From: Álvaro Fernández Rojas Date: Wed, 31 Jul 2019 16:23:26 +0000 (+0200) Subject: brcm2708: update to latest patches from the RPi foundation X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=19226502bf6393706defe7f049c587b32c9b4f33;p=openwrt%2Fstaging%2Faparcar.git brcm2708: update to latest patches from the RPi foundation Signed-off-by: Álvaro Fernández Rojas --- diff --git a/target/linux/brcm2708/bcm2708/config-4.19 b/target/linux/brcm2708/bcm2708/config-4.19 index 44a3019f4f..86d6b11b1e 100644 --- a/target/linux/brcm2708/bcm2708/config-4.19 +++ b/target/linux/brcm2708/bcm2708/config-4.19 @@ -71,7 +71,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_BLK_SCSI_REQUEST=y # CONFIG_BRCMSTB_THERMAL is not set CONFIG_BRCM_CHAR_DRIVERS=y -# CONFIG_BT_MTKUART is not set CONFIG_BUILD_BIN2C=y # CONFIG_CACHE_L2X0 is not set CONFIG_CC_HAS_ASM_GOTO=y @@ -246,7 +245,6 @@ CONFIG_HAVE_RSEQ=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_HAVE_UID16=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -# CONFIG_HID_BIGBEN_FF is not set CONFIG_HW_CONSOLE=y CONFIG_HZ_FIXED=0 CONFIG_I2C=y @@ -387,7 +385,6 @@ CONFIG_TIMER_OF=y CONFIG_TIMER_PROBE=y CONFIG_TINY_SRCU=y CONFIG_TMPFS_POSIX_ACL=y -# CONFIG_TOUCHSCREEN_RPI_FT5406 is not set CONFIG_UEVENT_HELPER_PATH="" # CONFIG_UID16 is not set CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" diff --git a/target/linux/brcm2708/bcm2709/config-4.19 b/target/linux/brcm2708/bcm2709/config-4.19 index e7a14a59b0..46fd680024 100644 --- a/target/linux/brcm2708/bcm2709/config-4.19 +++ b/target/linux/brcm2708/bcm2709/config-4.19 @@ -88,7 +88,6 @@ CONFIG_BOUNCE=y CONFIG_BRCMSTB_THERMAL=y CONFIG_BRCM_CHAR_DRIVERS=y CONFIG_BROADCOM_PHY=y -# CONFIG_BT_MTKUART is not set CONFIG_BUILD_BIN2C=y # CONFIG_CACHE_L2X0 is not set CONFIG_CC_HAS_ASM_GOTO=y @@ -177,7 +176,6 @@ CONFIG_DUMMY_CONSOLE=y CONFIG_EDAC_ATOMIC_SCRUB=y CONFIG_EDAC_SUPPORT=y CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_EXTCON_ARIZONA is not set CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y @@ -288,7 +286,6 @@ CONFIG_HAVE_SMP=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_HAVE_UID16=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -# CONFIG_HID_BIGBEN_FF is not set CONFIG_HIGHMEM=y CONFIG_HIGHPTE=y CONFIG_HOTPLUG_CPU=y @@ -312,8 +309,6 @@ CONFIG_IRQ_DOMAIN_HIERARCHY=y CONFIG_IRQ_FORCED_THREADING=y CONFIG_IRQ_WORK=y CONFIG_JBD2=y -CONFIG_KERNEL_GZIP=y -# CONFIG_KERNEL_XZ is not set # CONFIG_LCD_CLASS_DEVICE is not set CONFIG_LEDS_GPIO=y CONFIG_LEDS_TRIGGER_INPUT=y @@ -390,7 +385,10 @@ CONFIG_OLD_SIGSUSPEND3=y CONFIG_PADATA=y CONFIG_PAGE_OFFSET=0xC0000000 CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y CONFIG_PCIE_BRCMSTB=y +CONFIG_PCIE_PME=y CONFIG_PCI_DOMAINS=y CONFIG_PCI_DOMAINS_GENERIC=y CONFIG_PCI_MSI=y @@ -412,6 +410,7 @@ CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP_SMP=y CONFIG_POWER_SUPPLY=y CONFIG_PRINTK_TIME=y +CONFIG_RAS=y CONFIG_RASPBERRYPI_FIRMWARE=y CONFIG_RASPBERRYPI_POWER=y CONFIG_RATIONAL=y @@ -468,7 +467,6 @@ CONFIG_TICK_CPU_ACCOUNTING=y CONFIG_TIMER_OF=y CONFIG_TIMER_PROBE=y CONFIG_TMPFS_POSIX_ACL=y -# CONFIG_TOUCHSCREEN_RPI_FT5406 is not set CONFIG_TREE_RCU=y CONFIG_TREE_SRCU=y CONFIG_UEVENT_HELPER_PATH="" @@ -502,5 +500,5 @@ CONFIG_WATCHDOG_CORE=y CONFIG_XPS=y CONFIG_XZ_DEC_ARM=y CONFIG_XZ_DEC_BCJ=y -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_ZBOOT_ROM_TEXT=0 diff --git a/target/linux/brcm2708/bcm2710/config-4.19 b/target/linux/brcm2708/bcm2710/config-4.19 index 762a24df4b..6e77a73ac0 100644 --- a/target/linux/brcm2708/bcm2710/config-4.19 +++ b/target/linux/brcm2708/bcm2710/config-4.19 @@ -139,7 +139,6 @@ CONFIG_BLK_MQ_PCI=y CONFIG_BLK_SCSI_REQUEST=y CONFIG_BRCMSTB_THERMAL=y CONFIG_BRCM_CHAR_DRIVERS=y -# CONFIG_BT_MTKUART is not set CONFIG_BUILD_BIN2C=y CONFIG_CAVIUM_ERRATUM_22375=y CONFIG_CAVIUM_ERRATUM_23154=y @@ -207,13 +206,13 @@ CONFIG_DMA_CMA=y CONFIG_DMA_DIRECT_OPS=y CONFIG_DMA_ENGINE=y CONFIG_DMA_OF=y +CONFIG_DMA_SHARED_BUFFER=y CONFIG_DMA_VIRTUAL_CHANNELS=y CONFIG_DNOTIFY=y CONFIG_DTC=y CONFIG_DUMMY_CONSOLE=y CONFIG_EDAC_SUPPORT=y CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_EXTCON_ARIZONA is not set CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y @@ -329,7 +328,6 @@ CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y CONFIG_HAVE_RSEQ=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -# CONFIG_HID_BIGBEN_FF is not set CONFIG_HOLES_IN_ZONE=y CONFIG_HOTPLUG_CPU=y # CONFIG_HUGETLBFS is not set @@ -527,7 +525,6 @@ CONFIG_TICK_CPU_ACCOUNTING=y CONFIG_TIMER_OF=y CONFIG_TIMER_PROBE=y CONFIG_TMPFS_POSIX_ACL=y -# CONFIG_TOUCHSCREEN_RPI_FT5406 is not set CONFIG_TREE_RCU=y CONFIG_TREE_SRCU=y CONFIG_UEVENT_HELPER_PATH="" diff --git a/target/linux/brcm2708/modules/sound.mk b/target/linux/brcm2708/modules/sound.mk index 9f0a723948..92946bd9c7 100644 --- a/target/linux/brcm2708/modules/sound.mk +++ b/target/linux/brcm2708/modules/sound.mk @@ -512,6 +512,36 @@ endef $(eval $(call KernelPackage,sound-soc-hifiberry-dacplusadc)) +define KernelPackage/sound-soc-hifiberry-dacplusadc-pro + TITLE:=Support for HifiBerry DAC+ADC PRO + KCONFIG:= \ + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADCPRO \ + CONFIG_SND_SOC_PCM186X \ + CONFIG_SND_SOC_PCM186X_I2C \ + CONFIG_SND_SOC_PCM512x \ + CONFIG_SND_SOC_PCM512x_I2C + FILES:= \ + $(LINUX_DIR)/sound/soc/bcm/snd-soc-hifiberry-dacplusadcpro.ko \ + $(LINUX_DIR)/sound/soc/codecs/snd-soc-pcm186x.ko \ + $(LINUX_DIR)/sound/soc/codecs/snd-soc-pcm186x-i2c.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-pcm186x snd-soc-pcm186x-i2c \ + snd-soc-pcm512x snd-soc-pcm512x-i2c snd-soc-hifiberry-dacplusadcpro) + DEPENDS:= \ + kmod-sound-soc-bcm2835-i2s \ + +kmod-i2c-bcm2835 \ + +kmod-regmap-i2c + $(call AddDepends/sound) +endef + +define KernelPackage/sound-soc-hifiberry-dacplusadc-pro/description + This package contains support for HifiBerry DAC+ADC PRO +endef + +$(eval $(call KernelPackage,sound-soc-hifiberry-dacplusadc-pro)) + + define KernelPackage/sound-soc-hifiberry-digi TITLE:=Support for HifiBerry Digi / Digi+ / Digi+ Pro KCONFIG:= \ diff --git a/target/linux/brcm2708/patches-4.14/950-0132-mcp2515-Use-DT-supplied-interrupt-flags.patch b/target/linux/brcm2708/patches-4.14/950-0132-mcp2515-Use-DT-supplied-interrupt-flags.patch index bb87c97c6c..31942750c1 100644 --- a/target/linux/brcm2708/patches-4.14/950-0132-mcp2515-Use-DT-supplied-interrupt-flags.patch +++ b/target/linux/brcm2708/patches-4.14/950-0132-mcp2515-Use-DT-supplied-interrupt-flags.patch @@ -24,7 +24,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/can/spi/mcp251x.c +++ b/drivers/net/can/spi/mcp251x.c -@@ -951,6 +951,9 @@ static int mcp251x_open(struct net_devic +@@ -952,6 +952,9 @@ static int mcp251x_open(struct net_devic priv->tx_skb = NULL; priv->tx_len = 0; diff --git a/target/linux/brcm2708/patches-4.14/950-0315-usb-gadget-ethernet-Re-enable-Jumbo-frames.patch b/target/linux/brcm2708/patches-4.14/950-0315-usb-gadget-ethernet-Re-enable-Jumbo-frames.patch index 8875a8ac37..6442338a6c 100644 --- a/target/linux/brcm2708/patches-4.14/950-0315-usb-gadget-ethernet-Re-enable-Jumbo-frames.patch +++ b/target/linux/brcm2708/patches-4.14/950-0315-usb-gadget-ethernet-Re-enable-Jumbo-frames.patch @@ -18,7 +18,7 @@ Signed-off-by: Felipe Balbi --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c -@@ -850,6 +850,10 @@ struct net_device *gether_setup_name_def +@@ -848,6 +848,10 @@ struct net_device *gether_setup_name_def net->ethtool_ops = &ops; SET_NETDEV_DEVTYPE(net, &gadget_type); diff --git a/target/linux/brcm2708/patches-4.19/950-0001-arm-partially-revert-702b94bff3c50542a6e4ab9a4f4cef0.patch b/target/linux/brcm2708/patches-4.19/950-0001-arm-partially-revert-702b94bff3c50542a6e4ab9a4f4cef0.patch index 1f06450519..618330d1c0 100644 --- a/target/linux/brcm2708/patches-4.19/950-0001-arm-partially-revert-702b94bff3c50542a6e4ab9a4f4cef0.patch +++ b/target/linux/brcm2708/patches-4.19/950-0001-arm-partially-revert-702b94bff3c50542a6e4ab9a4f4cef0.patch @@ -1,7 +1,7 @@ -From d76972193fe88bb13028ba8277736a6aec4b8c8a Mon Sep 17 00:00:00 2001 +From 623cca7c1ef73b6b164d487d3bb3b2bddc60abab Mon Sep 17 00:00:00 2001 From: Dan Pasanen Date: Thu, 21 Sep 2017 09:55:42 -0500 -Subject: [PATCH 001/703] arm: partially revert +Subject: [PATCH 001/725] arm: partially revert 702b94bff3c50542a6e4ab9a4f4cef093262fe65 * Re-expose some dmi APIs for use in VCSM diff --git a/target/linux/brcm2708/patches-4.19/950-0002-smsx95xx-fix-crimes-against-truesize.patch b/target/linux/brcm2708/patches-4.19/950-0002-smsx95xx-fix-crimes-against-truesize.patch index 80071355a6..792fe03605 100644 --- a/target/linux/brcm2708/patches-4.19/950-0002-smsx95xx-fix-crimes-against-truesize.patch +++ b/target/linux/brcm2708/patches-4.19/950-0002-smsx95xx-fix-crimes-against-truesize.patch @@ -1,7 +1,7 @@ -From 8f4948a1503a76cbeb5823d8b17990bf3a3c57a6 Mon Sep 17 00:00:00 2001 +From b356c22b7c3cce97ba7c20af22f508510387a3f2 Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Thu, 19 Feb 2015 18:47:12 +0000 -Subject: [PATCH 002/703] smsx95xx: fix crimes against truesize +Subject: [PATCH 002/725] smsx95xx: fix crimes against truesize smsc95xx is adjusting truesize when it shouldn't, and following a recent patch from Eric this is now triggering warnings. diff --git a/target/linux/brcm2708/patches-4.19/950-0003-smsc95xx-Experimental-Enable-turbo_mode-and-packetsi.patch b/target/linux/brcm2708/patches-4.19/950-0003-smsc95xx-Experimental-Enable-turbo_mode-and-packetsi.patch index a4ef606a15..62c89ff4fc 100644 --- a/target/linux/brcm2708/patches-4.19/950-0003-smsc95xx-Experimental-Enable-turbo_mode-and-packetsi.patch +++ b/target/linux/brcm2708/patches-4.19/950-0003-smsc95xx-Experimental-Enable-turbo_mode-and-packetsi.patch @@ -1,7 +1,7 @@ -From 623b0f5e0a439af4beef58317b224d4d3d2a969c Mon Sep 17 00:00:00 2001 +From 440ed9d083956067ffbaaefd3e2411b746126593 Mon Sep 17 00:00:00 2001 From: Sam Nazarko Date: Fri, 1 Apr 2016 17:27:21 +0100 -Subject: [PATCH 003/703] smsc95xx: Experimental: Enable turbo_mode and +Subject: [PATCH 003/725] smsc95xx: Experimental: Enable turbo_mode and packetsize=2560 by default See: http://forum.kodi.tv/showthread.php?tid=285288 diff --git a/target/linux/brcm2708/patches-4.19/950-0004-Allow-mac-address-to-be-set-in-smsc95xx.patch b/target/linux/brcm2708/patches-4.19/950-0004-Allow-mac-address-to-be-set-in-smsc95xx.patch index 70d4a57d95..5ed138da21 100644 --- a/target/linux/brcm2708/patches-4.19/950-0004-Allow-mac-address-to-be-set-in-smsc95xx.patch +++ b/target/linux/brcm2708/patches-4.19/950-0004-Allow-mac-address-to-be-set-in-smsc95xx.patch @@ -1,7 +1,7 @@ -From 80592905099a4f0fa5d166d58785eacef968ba4e Mon Sep 17 00:00:00 2001 +From 3590eb29c3b4307a50daf24c1d58e188b1aaf65d Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 17:26:38 +0000 -Subject: [PATCH 004/703] Allow mac address to be set in smsc95xx +Subject: [PATCH 004/725] Allow mac address to be set in smsc95xx Signed-off-by: popcornmix --- diff --git a/target/linux/brcm2708/patches-4.19/950-0005-Protect-__release_resource-against-resources-without.patch b/target/linux/brcm2708/patches-4.19/950-0005-Protect-__release_resource-against-resources-without.patch index bf30cd913b..57b3618e77 100644 --- a/target/linux/brcm2708/patches-4.19/950-0005-Protect-__release_resource-against-resources-without.patch +++ b/target/linux/brcm2708/patches-4.19/950-0005-Protect-__release_resource-against-resources-without.patch @@ -1,7 +1,7 @@ -From b5e65f6a5a75c72d56d98c9543ff549710aa2d72 Mon Sep 17 00:00:00 2001 +From 42773929bcec27d195b93b11c10527be7fccd2d8 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 13 Mar 2015 12:43:36 +0000 -Subject: [PATCH 005/703] Protect __release_resource against resources without +Subject: [PATCH 005/725] Protect __release_resource against resources without parents Without this patch, removing a device tree overlay can crash here. diff --git a/target/linux/brcm2708/patches-4.19/950-0006-irq-bcm2836-Prevent-spurious-interrupts-and-trap-the.patch b/target/linux/brcm2708/patches-4.19/950-0006-irq-bcm2836-Prevent-spurious-interrupts-and-trap-the.patch index 3237b2a811..c993ee1e57 100644 --- a/target/linux/brcm2708/patches-4.19/950-0006-irq-bcm2836-Prevent-spurious-interrupts-and-trap-the.patch +++ b/target/linux/brcm2708/patches-4.19/950-0006-irq-bcm2836-Prevent-spurious-interrupts-and-trap-the.patch @@ -1,7 +1,7 @@ -From da00086d33452442af1009580f8e40164fc4e97f Mon Sep 17 00:00:00 2001 +From ca08ef4827614912c6f07fa734a2eede3420a9c6 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 4 Dec 2015 17:41:50 +0000 -Subject: [PATCH 006/703] irq-bcm2836: Prevent spurious interrupts, and trap +Subject: [PATCH 006/725] irq-bcm2836: Prevent spurious interrupts, and trap them early The old arch-specific IRQ macros included a dsb to ensure the diff --git a/target/linux/brcm2708/patches-4.19/950-0007-irq-bcm2836-Avoid-Invalid-trigger-warning.patch b/target/linux/brcm2708/patches-4.19/950-0007-irq-bcm2836-Avoid-Invalid-trigger-warning.patch index 54f4452341..112481e562 100644 --- a/target/linux/brcm2708/patches-4.19/950-0007-irq-bcm2836-Avoid-Invalid-trigger-warning.patch +++ b/target/linux/brcm2708/patches-4.19/950-0007-irq-bcm2836-Avoid-Invalid-trigger-warning.patch @@ -1,7 +1,7 @@ -From 23f28161eadbc84b976b1a6ff4c8e4fdfa38aa93 Mon Sep 17 00:00:00 2001 +From b3b97bc061e22d03569cd7eedaf7cc1b4fb403f3 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 9 Feb 2017 14:33:30 +0000 -Subject: [PATCH 007/703] irq-bcm2836: Avoid "Invalid trigger warning" +Subject: [PATCH 007/725] irq-bcm2836: Avoid "Invalid trigger warning" Initialise the level for each IRQ to avoid a warning from the arm arch timer code. diff --git a/target/linux/brcm2708/patches-4.19/950-0008-irqchip-bcm2835-Add-FIQ-support.patch b/target/linux/brcm2708/patches-4.19/950-0008-irqchip-bcm2835-Add-FIQ-support.patch index 77a9181539..0f39a78c4f 100644 --- a/target/linux/brcm2708/patches-4.19/950-0008-irqchip-bcm2835-Add-FIQ-support.patch +++ b/target/linux/brcm2708/patches-4.19/950-0008-irqchip-bcm2835-Add-FIQ-support.patch @@ -1,7 +1,7 @@ -From 06cc1d14e061ef7169947f09f1e356cec9e0a790 Mon Sep 17 00:00:00 2001 +From 9920e74cfd7571c36fce1caf84736f89e275fe22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Fri, 12 Jun 2015 19:01:05 +0200 -Subject: [PATCH 008/703] irqchip: bcm2835: Add FIQ support +Subject: [PATCH 008/725] irqchip: bcm2835: Add FIQ support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/target/linux/brcm2708/patches-4.19/950-0009-irqchip-irq-bcm2835-Add-2836-FIQ-support.patch b/target/linux/brcm2708/patches-4.19/950-0009-irqchip-irq-bcm2835-Add-2836-FIQ-support.patch index 1efa0b4d97..1227546832 100644 --- a/target/linux/brcm2708/patches-4.19/950-0009-irqchip-irq-bcm2835-Add-2836-FIQ-support.patch +++ b/target/linux/brcm2708/patches-4.19/950-0009-irqchip-irq-bcm2835-Add-2836-FIQ-support.patch @@ -1,7 +1,7 @@ -From 9c8894afe627b270aad44c64f4e70c659468d7ed Mon Sep 17 00:00:00 2001 +From b08bd87913c001b0f3d7f86d73abfc2074b0cab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Fri, 23 Oct 2015 16:26:55 +0200 -Subject: [PATCH 009/703] irqchip: irq-bcm2835: Add 2836 FIQ support +Subject: [PATCH 009/725] irqchip: irq-bcm2835: Add 2836 FIQ support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/target/linux/brcm2708/patches-4.19/950-0010-spidev-Add-spidev-compatible-string-to-silence-warni.patch b/target/linux/brcm2708/patches-4.19/950-0010-spidev-Add-spidev-compatible-string-to-silence-warni.patch index f0f6c1b9cd..0e89bef99c 100644 --- a/target/linux/brcm2708/patches-4.19/950-0010-spidev-Add-spidev-compatible-string-to-silence-warni.patch +++ b/target/linux/brcm2708/patches-4.19/950-0010-spidev-Add-spidev-compatible-string-to-silence-warni.patch @@ -1,7 +1,7 @@ -From 97e88641862862585d6ae8aaae034946ceab8ceb Mon Sep 17 00:00:00 2001 +From e73e4e6923289a3055d5fd10c7726fbe358505ad Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 14 Jul 2015 10:26:09 +0100 -Subject: [PATCH 010/703] spidev: Add "spidev" compatible string to silence +Subject: [PATCH 010/725] spidev: Add "spidev" compatible string to silence warning See: https://github.com/raspberrypi/linux/issues/1054 diff --git a/target/linux/brcm2708/patches-4.19/950-0011-spi-bcm2835-Support-pin-groups-other-than-7-11.patch b/target/linux/brcm2708/patches-4.19/950-0011-spi-bcm2835-Support-pin-groups-other-than-7-11.patch index 3955fb0cf3..2063d5a0be 100644 --- a/target/linux/brcm2708/patches-4.19/950-0011-spi-bcm2835-Support-pin-groups-other-than-7-11.patch +++ b/target/linux/brcm2708/patches-4.19/950-0011-spi-bcm2835-Support-pin-groups-other-than-7-11.patch @@ -1,7 +1,7 @@ -From 5d9d6d510a0e7d2e3eee1ed663f0157c719c90ec Mon Sep 17 00:00:00 2001 +From e1ebc1b8dcb6990e2541e3503cb2cdd3f5edfc1e Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 24 Jun 2015 14:10:44 +0100 -Subject: [PATCH 011/703] spi-bcm2835: Support pin groups other than 7-11 +Subject: [PATCH 011/725] spi-bcm2835: Support pin groups other than 7-11 The spi-bcm2835 driver automatically uses GPIO chip-selects due to some unreliability of the native ones. In doing so it chooses the diff --git a/target/linux/brcm2708/patches-4.19/950-0012-spi-bcm2835-Disable-forced-software-CS.patch b/target/linux/brcm2708/patches-4.19/950-0012-spi-bcm2835-Disable-forced-software-CS.patch index 091ede137d..ace41e47a3 100644 --- a/target/linux/brcm2708/patches-4.19/950-0012-spi-bcm2835-Disable-forced-software-CS.patch +++ b/target/linux/brcm2708/patches-4.19/950-0012-spi-bcm2835-Disable-forced-software-CS.patch @@ -1,7 +1,7 @@ -From 8d654c03c8e0730e67fc4e7d6435da05ddf4e284 Mon Sep 17 00:00:00 2001 +From e901e4ff32c1f3c10342b4607579a1d9613c3c66 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 1 Jul 2016 22:09:24 +0100 -Subject: [PATCH 012/703] spi-bcm2835: Disable forced software CS +Subject: [PATCH 012/725] spi-bcm2835: Disable forced software CS Select software CS in bcm2708_common.dtsi, and disable the automatic conversion in the driver to allow hardware CS to be re-enabled with an diff --git a/target/linux/brcm2708/patches-4.19/950-0013-spi-bcm2835-Remove-unused-code.patch b/target/linux/brcm2708/patches-4.19/950-0013-spi-bcm2835-Remove-unused-code.patch index de39a04455..72429e85e9 100644 --- a/target/linux/brcm2708/patches-4.19/950-0013-spi-bcm2835-Remove-unused-code.patch +++ b/target/linux/brcm2708/patches-4.19/950-0013-spi-bcm2835-Remove-unused-code.patch @@ -1,7 +1,7 @@ -From 5a6dcccb576167d1e50c922bfb7bf6cffbdaa671 Mon Sep 17 00:00:00 2001 +From f1b841cc75bcd8c655c9cd6c3dbed439a1f4d24a Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 8 Nov 2016 21:35:38 +0000 -Subject: [PATCH 013/703] spi-bcm2835: Remove unused code +Subject: [PATCH 013/725] spi-bcm2835: Remove unused code --- drivers/spi/spi-bcm2835.c | 61 --------------------------------------- diff --git a/target/linux/brcm2708/patches-4.19/950-0014-dmaengine-bcm2835-Load-driver-early-and-support-lega.patch b/target/linux/brcm2708/patches-4.19/950-0014-dmaengine-bcm2835-Load-driver-early-and-support-lega.patch index a865803f66..8db1d26147 100644 --- a/target/linux/brcm2708/patches-4.19/950-0014-dmaengine-bcm2835-Load-driver-early-and-support-lega.patch +++ b/target/linux/brcm2708/patches-4.19/950-0014-dmaengine-bcm2835-Load-driver-early-and-support-lega.patch @@ -1,7 +1,7 @@ -From abbc7f81bb68293439c0a325b5a590d28b91b819 Mon Sep 17 00:00:00 2001 +From 568609dad2f29b45931c2fc869f87d4abb6c7486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Sat, 3 Oct 2015 22:22:55 +0200 -Subject: [PATCH 014/703] dmaengine: bcm2835: Load driver early and support +Subject: [PATCH 014/725] dmaengine: bcm2835: Load driver early and support legacy API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 diff --git a/target/linux/brcm2708/patches-4.19/950-0015-firmware-Updated-mailbox-header.patch b/target/linux/brcm2708/patches-4.19/950-0015-firmware-Updated-mailbox-header.patch index be01e20c09..3d22d53f22 100644 --- a/target/linux/brcm2708/patches-4.19/950-0015-firmware-Updated-mailbox-header.patch +++ b/target/linux/brcm2708/patches-4.19/950-0015-firmware-Updated-mailbox-header.patch @@ -1,7 +1,7 @@ -From 8d00375a0645102bc58fc5c8e4c05efbcfbbbd71 Mon Sep 17 00:00:00 2001 +From 8151b76346ed89410b20db4fb4bc8f1784e0fd19 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 25 Jan 2016 17:25:12 +0000 -Subject: [PATCH 015/703] firmware: Updated mailbox header +Subject: [PATCH 015/725] firmware: Updated mailbox header --- include/soc/bcm2835/raspberrypi-firmware.h | 5 +++++ diff --git a/target/linux/brcm2708/patches-4.19/950-0016-rtc-Add-SPI-alias-for-pcf2123-driver.patch b/target/linux/brcm2708/patches-4.19/950-0016-rtc-Add-SPI-alias-for-pcf2123-driver.patch index 1cb84b17fd..6efbc80ce6 100644 --- a/target/linux/brcm2708/patches-4.19/950-0016-rtc-Add-SPI-alias-for-pcf2123-driver.patch +++ b/target/linux/brcm2708/patches-4.19/950-0016-rtc-Add-SPI-alias-for-pcf2123-driver.patch @@ -1,7 +1,7 @@ -From afbee813c2e801c74c1732eb4511e5fd32027245 Mon Sep 17 00:00:00 2001 +From 0af4ce25fc884c07db940d61e7677bba37a4130d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 15 Jun 2016 16:48:41 +0100 -Subject: [PATCH 016/703] rtc: Add SPI alias for pcf2123 driver +Subject: [PATCH 016/725] rtc: Add SPI alias for pcf2123 driver Without this alias, Device Tree won't cause the driver to be loaded. diff --git a/target/linux/brcm2708/patches-4.19/950-0017-watchdog-bcm2835-Support-setting-reboot-partition.patch b/target/linux/brcm2708/patches-4.19/950-0017-watchdog-bcm2835-Support-setting-reboot-partition.patch index 63b3c63e87..e20a1fc1fd 100644 --- a/target/linux/brcm2708/patches-4.19/950-0017-watchdog-bcm2835-Support-setting-reboot-partition.patch +++ b/target/linux/brcm2708/patches-4.19/950-0017-watchdog-bcm2835-Support-setting-reboot-partition.patch @@ -1,7 +1,7 @@ -From 3091f3a65590ab446e9c637377efa55dc3b8996f Mon Sep 17 00:00:00 2001 +From 726d38c5f2aee110f7e3b0f03fc17e5fc69aa8c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Fri, 7 Oct 2016 16:50:59 +0200 -Subject: [PATCH 017/703] watchdog: bcm2835: Support setting reboot partition +Subject: [PATCH 017/725] watchdog: bcm2835: Support setting reboot partition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/target/linux/brcm2708/patches-4.19/950-0018-reboot-Use-power-off-rather-than-busy-spinning-when-.patch b/target/linux/brcm2708/patches-4.19/950-0018-reboot-Use-power-off-rather-than-busy-spinning-when-.patch index 0223a4ac58..fb2805e4d8 100644 --- a/target/linux/brcm2708/patches-4.19/950-0018-reboot-Use-power-off-rather-than-busy-spinning-when-.patch +++ b/target/linux/brcm2708/patches-4.19/950-0018-reboot-Use-power-off-rather-than-busy-spinning-when-.patch @@ -1,7 +1,7 @@ -From 49dc030939b6332a4d1dca0c2b12ea9f559dcf2f Mon Sep 17 00:00:00 2001 +From a48963920cbab4a54fb8c1a12cab6f51249c8938 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 5 Apr 2016 19:40:12 +0100 -Subject: [PATCH 018/703] reboot: Use power off rather than busy spinning when +Subject: [PATCH 018/725] reboot: Use power off rather than busy spinning when halt is requested --- diff --git a/target/linux/brcm2708/patches-4.19/950-0019-bcm-Make-RASPBERRYPI_POWER-depend-on-PM.patch b/target/linux/brcm2708/patches-4.19/950-0019-bcm-Make-RASPBERRYPI_POWER-depend-on-PM.patch index 50193198fa..de317c31fa 100644 --- a/target/linux/brcm2708/patches-4.19/950-0019-bcm-Make-RASPBERRYPI_POWER-depend-on-PM.patch +++ b/target/linux/brcm2708/patches-4.19/950-0019-bcm-Make-RASPBERRYPI_POWER-depend-on-PM.patch @@ -1,7 +1,7 @@ -From 9fdc1aa7e5d82029afb4e14c3ef3613264f6eca0 Mon Sep 17 00:00:00 2001 +From 5b4c3e8bea1e40ae39e8e1d557f71c2262e41740 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 9 Nov 2016 13:02:52 +0000 -Subject: [PATCH 019/703] bcm: Make RASPBERRYPI_POWER depend on PM +Subject: [PATCH 019/725] bcm: Make RASPBERRYPI_POWER depend on PM --- drivers/soc/bcm/Kconfig | 1 + diff --git a/target/linux/brcm2708/patches-4.19/950-0020-Register-the-clocks-early-during-the-boot-process-so.patch b/target/linux/brcm2708/patches-4.19/950-0020-Register-the-clocks-early-during-the-boot-process-so.patch index 616a977ee9..1b090d7646 100644 --- a/target/linux/brcm2708/patches-4.19/950-0020-Register-the-clocks-early-during-the-boot-process-so.patch +++ b/target/linux/brcm2708/patches-4.19/950-0020-Register-the-clocks-early-during-the-boot-process-so.patch @@ -1,7 +1,7 @@ -From 4900c14f9c0f514162496e6a3f71c51a50e7b376 Mon Sep 17 00:00:00 2001 +From 2d35d5929c505731a490ea56a6a78f487c082e01 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Fri, 2 Sep 2016 16:45:27 +0100 -Subject: [PATCH 020/703] Register the clocks early during the boot process, so +Subject: [PATCH 020/725] Register the clocks early during the boot process, so that special/critical clocks can get enabled early on in the boot process avoiding the risk of disabling a clock, pll_divider or pll when a claiming driver fails to install propperly - maybe it needs to defer. diff --git a/target/linux/brcm2708/patches-4.19/950-0021-bcm2835-rng-Avoid-initialising-if-already-enabled.patch b/target/linux/brcm2708/patches-4.19/950-0021-bcm2835-rng-Avoid-initialising-if-already-enabled.patch index 5e197ba30c..33340a3801 100644 --- a/target/linux/brcm2708/patches-4.19/950-0021-bcm2835-rng-Avoid-initialising-if-already-enabled.patch +++ b/target/linux/brcm2708/patches-4.19/950-0021-bcm2835-rng-Avoid-initialising-if-already-enabled.patch @@ -1,7 +1,7 @@ -From bc5b619aa9eaa634e49483c95b3681171cb4d900 Mon Sep 17 00:00:00 2001 +From 241096d58e818f8f471eb141b1183e8b5e8ffea8 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 6 Dec 2016 17:05:39 +0000 -Subject: [PATCH 021/703] bcm2835-rng: Avoid initialising if already enabled +Subject: [PATCH 021/725] bcm2835-rng: Avoid initialising if already enabled Avoids the 0x40000 cycles of warmup again if firmware has already used it --- diff --git a/target/linux/brcm2708/patches-4.19/950-0022-kbuild-Ignore-dtco-targets-when-filtering-symbols.patch b/target/linux/brcm2708/patches-4.19/950-0022-kbuild-Ignore-dtco-targets-when-filtering-symbols.patch index eb216e40ac..41b8749042 100644 --- a/target/linux/brcm2708/patches-4.19/950-0022-kbuild-Ignore-dtco-targets-when-filtering-symbols.patch +++ b/target/linux/brcm2708/patches-4.19/950-0022-kbuild-Ignore-dtco-targets-when-filtering-symbols.patch @@ -1,7 +1,7 @@ -From 30a4c0ff154b3ce8fd0df9054d03cee55dacc8d0 Mon Sep 17 00:00:00 2001 +From 8bf56ee660bf07a25ba3a2081d9a498435d16a32 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 24 Aug 2016 16:28:44 +0100 -Subject: [PATCH 022/703] kbuild: Ignore dtco targets when filtering symbols +Subject: [PATCH 022/725] kbuild: Ignore dtco targets when filtering symbols --- scripts/Kbuild.include | 2 +- diff --git a/target/linux/brcm2708/patches-4.19/950-0023-clk-bcm2835-Mark-used-PLLs-and-dividers-CRITICAL.patch b/target/linux/brcm2708/patches-4.19/950-0023-clk-bcm2835-Mark-used-PLLs-and-dividers-CRITICAL.patch index 478d0c9987..234201dbc4 100644 --- a/target/linux/brcm2708/patches-4.19/950-0023-clk-bcm2835-Mark-used-PLLs-and-dividers-CRITICAL.patch +++ b/target/linux/brcm2708/patches-4.19/950-0023-clk-bcm2835-Mark-used-PLLs-and-dividers-CRITICAL.patch @@ -1,7 +1,7 @@ -From 06ad042c1d3b3471c478fee39a7539ac39b752ff Mon Sep 17 00:00:00 2001 +From a87e7ca656f8b80caf7db0056ba4b6191018359f Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 13 Feb 2017 17:20:08 +0000 -Subject: [PATCH 023/703] clk-bcm2835: Mark used PLLs and dividers CRITICAL +Subject: [PATCH 023/725] 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 diff --git a/target/linux/brcm2708/patches-4.19/950-0024-clk-bcm2835-Add-claim-clocks-property.patch b/target/linux/brcm2708/patches-4.19/950-0024-clk-bcm2835-Add-claim-clocks-property.patch index e80c99bcb0..45dba07ce1 100644 --- a/target/linux/brcm2708/patches-4.19/950-0024-clk-bcm2835-Add-claim-clocks-property.patch +++ b/target/linux/brcm2708/patches-4.19/950-0024-clk-bcm2835-Add-claim-clocks-property.patch @@ -1,7 +1,7 @@ -From 14e1d51f1737da7b2bf59df95db6f977179e0497 Mon Sep 17 00:00:00 2001 +From b0d7a3297087a0a78e12e9e8fc41e9c91a114304 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 13 Feb 2017 17:20:08 +0000 -Subject: [PATCH 024/703] clk-bcm2835: Add claim-clocks property +Subject: [PATCH 024/725] 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, diff --git a/target/linux/brcm2708/patches-4.19/950-0025-clk-bcm2835-Read-max-core-clock-from-firmware.patch b/target/linux/brcm2708/patches-4.19/950-0025-clk-bcm2835-Read-max-core-clock-from-firmware.patch index 66a0d2a429..8de5f1c785 100644 --- a/target/linux/brcm2708/patches-4.19/950-0025-clk-bcm2835-Read-max-core-clock-from-firmware.patch +++ b/target/linux/brcm2708/patches-4.19/950-0025-clk-bcm2835-Read-max-core-clock-from-firmware.patch @@ -1,7 +1,7 @@ -From 9e24627b07ac0553c9fc00a069fcc10c22a3cb6f Mon Sep 17 00:00:00 2001 +From 91e0734c2ca8c8629b0537329c7e6d538fa1c085 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 6 Mar 2017 09:06:18 +0000 -Subject: [PATCH 025/703] clk-bcm2835: Read max core clock from firmware +Subject: [PATCH 025/725] clk-bcm2835: Read max core clock from firmware The VPU is responsible for managing the core clock, usually under direction from the bcm2835-cpufreq driver but not via the clk-bcm2835 diff --git a/target/linux/brcm2708/patches-4.19/950-0026-clk-bcm2835-Mark-GPIO-clocks-enabled-at-boot-as-crit.patch b/target/linux/brcm2708/patches-4.19/950-0026-clk-bcm2835-Mark-GPIO-clocks-enabled-at-boot-as-crit.patch index ffbe31c8c5..ec4dafba1f 100644 --- a/target/linux/brcm2708/patches-4.19/950-0026-clk-bcm2835-Mark-GPIO-clocks-enabled-at-boot-as-crit.patch +++ b/target/linux/brcm2708/patches-4.19/950-0026-clk-bcm2835-Mark-GPIO-clocks-enabled-at-boot-as-crit.patch @@ -1,7 +1,7 @@ -From fabb3595bd356f058329ff94a3c5e31df5d84217 Mon Sep 17 00:00:00 2001 +From e61099f2c51b1583663e5868f87056d4c11b6e9d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 9 May 2016 17:28:18 -0700 -Subject: [PATCH 026/703] clk: bcm2835: Mark GPIO clocks enabled at boot as +Subject: [PATCH 026/725] clk: bcm2835: Mark GPIO clocks enabled at boot as critical. These divide off of PLLD_PER and are used for the ethernet and wifi diff --git a/target/linux/brcm2708/patches-4.19/950-0027-sound-Demote-deferral-errors-to-INFO-level.patch b/target/linux/brcm2708/patches-4.19/950-0027-sound-Demote-deferral-errors-to-INFO-level.patch index 3db0a75235..45fa26aa33 100644 --- a/target/linux/brcm2708/patches-4.19/950-0027-sound-Demote-deferral-errors-to-INFO-level.patch +++ b/target/linux/brcm2708/patches-4.19/950-0027-sound-Demote-deferral-errors-to-INFO-level.patch @@ -1,7 +1,7 @@ -From 34dfe2b3ea493bc57c2b85280c28dbe0b3c1d1dc Mon Sep 17 00:00:00 2001 +From 4d94da034003c8f8ba44ba4a8abdf5c9cf56d684 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 9 Feb 2017 14:36:44 +0000 -Subject: [PATCH 027/703] sound: Demote deferral errors to INFO level +Subject: [PATCH 027/725] 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. diff --git a/target/linux/brcm2708/patches-4.19/950-0028-Update-vfpmodule.c.patch b/target/linux/brcm2708/patches-4.19/950-0028-Update-vfpmodule.c.patch index afb0e3f78a..bb96515a8c 100644 --- a/target/linux/brcm2708/patches-4.19/950-0028-Update-vfpmodule.c.patch +++ b/target/linux/brcm2708/patches-4.19/950-0028-Update-vfpmodule.c.patch @@ -1,7 +1,7 @@ -From dae5f48d60cccc2214a09c11b84373988e57e2f5 Mon Sep 17 00:00:00 2001 +From be7a5d79d1f4d8f8db39f092e7f07d8cb05eebf7 Mon Sep 17 00:00:00 2001 From: Claggy3 Date: Sat, 11 Feb 2017 14:00:30 +0000 -Subject: [PATCH 028/703] Update vfpmodule.c +Subject: [PATCH 028/725] 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 diff --git a/target/linux/brcm2708/patches-4.19/950-0029-i2c-bcm2835-Add-debug-support.patch b/target/linux/brcm2708/patches-4.19/950-0029-i2c-bcm2835-Add-debug-support.patch index bf985e0f6a..2b95e79176 100644 --- a/target/linux/brcm2708/patches-4.19/950-0029-i2c-bcm2835-Add-debug-support.patch +++ b/target/linux/brcm2708/patches-4.19/950-0029-i2c-bcm2835-Add-debug-support.patch @@ -1,7 +1,7 @@ -From c7e79d0b9906e274e220f568ed49e5f00ee5187f Mon Sep 17 00:00:00 2001 +From 97549c7735e937cafdbeff241c9aac738fa560ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Tue, 1 Nov 2016 15:15:41 +0100 -Subject: [PATCH 029/703] i2c: bcm2835: Add debug support +Subject: [PATCH 029/725] i2c: bcm2835: Add debug support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/target/linux/brcm2708/patches-4.19/950-0030-mm-Remove-the-PFN-busy-warning.patch b/target/linux/brcm2708/patches-4.19/950-0030-mm-Remove-the-PFN-busy-warning.patch index 246b0281b5..553902f2ef 100644 --- a/target/linux/brcm2708/patches-4.19/950-0030-mm-Remove-the-PFN-busy-warning.patch +++ b/target/linux/brcm2708/patches-4.19/950-0030-mm-Remove-the-PFN-busy-warning.patch @@ -1,7 +1,7 @@ -From 72ed3b77a672a8a94dab5d08739fac5b4df488d2 Mon Sep 17 00:00:00 2001 +From 41dda0f0591a3b2e73439a3af562ac937927dd15 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Dec 2014 16:07:15 -0800 -Subject: [PATCH 030/703] mm: Remove the PFN busy warning +Subject: [PATCH 030/725] mm: Remove the PFN busy warning See commit dae803e165a11bc88ca8dbc07a11077caf97bbcb -- the warning is expected sometimes when using CMA. However, that commit still spams diff --git a/target/linux/brcm2708/patches-4.19/950-0031-ASoC-Add-prompt-for-ICS43432-codec.patch b/target/linux/brcm2708/patches-4.19/950-0031-ASoC-Add-prompt-for-ICS43432-codec.patch index a0070427e6..0bf91200ea 100644 --- a/target/linux/brcm2708/patches-4.19/950-0031-ASoC-Add-prompt-for-ICS43432-codec.patch +++ b/target/linux/brcm2708/patches-4.19/950-0031-ASoC-Add-prompt-for-ICS43432-codec.patch @@ -1,7 +1,7 @@ -From 14e894cf24f588a4066b171b846934ebe44afc5d Mon Sep 17 00:00:00 2001 +From 9d9d7ba0d4296bb2b0270a1e5dfbc8a3eb7cf192 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 23 Mar 2017 10:06:56 +0000 -Subject: [PATCH 031/703] ASoC: Add prompt for ICS43432 codec +Subject: [PATCH 031/725] ASoC: Add prompt for ICS43432 codec Without a prompt string, a config setting can't be included in a defconfig. Give CONFIG_SND_SOC_ICS43432 a prompt so that Pi soundcards diff --git a/target/linux/brcm2708/patches-4.19/950-0032-irqchip-irq-bcm2836-Remove-regmap-and-syscon-use.patch b/target/linux/brcm2708/patches-4.19/950-0032-irqchip-irq-bcm2836-Remove-regmap-and-syscon-use.patch index b55d9364ea..857e3f6613 100644 --- a/target/linux/brcm2708/patches-4.19/950-0032-irqchip-irq-bcm2836-Remove-regmap-and-syscon-use.patch +++ b/target/linux/brcm2708/patches-4.19/950-0032-irqchip-irq-bcm2836-Remove-regmap-and-syscon-use.patch @@ -1,7 +1,7 @@ -From a580882d64f92ec0b025f6ddcfcea985412eb430 Mon Sep 17 00:00:00 2001 +From 1c14a9ccc7c3b57c55374295a4a7a9a80090b095 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 23 Jan 2018 16:52:45 +0000 -Subject: [PATCH 032/703] irqchip: irq-bcm2836: Remove regmap and syscon use +Subject: [PATCH 032/725] irqchip: irq-bcm2836: Remove regmap and syscon use The syscon node defines a register range that duplicates that used by the local_intc node on bcm2836/7. Since irq-bcm2835 and irq-bcm2836 are diff --git a/target/linux/brcm2708/patches-4.19/950-0033-lan78xx-Enable-LEDs-and-auto-negotiation.patch b/target/linux/brcm2708/patches-4.19/950-0033-lan78xx-Enable-LEDs-and-auto-negotiation.patch index ace7600887..0d7769a3ea 100644 --- a/target/linux/brcm2708/patches-4.19/950-0033-lan78xx-Enable-LEDs-and-auto-negotiation.patch +++ b/target/linux/brcm2708/patches-4.19/950-0033-lan78xx-Enable-LEDs-and-auto-negotiation.patch @@ -1,7 +1,7 @@ -From a3d3dea9ca36f4f5adbf741f36b06ce05b70c2bb Mon Sep 17 00:00:00 2001 +From 37be14f62e3545c46cd86a11ba68cc036f34c638 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 17 Oct 2017 15:04:29 +0100 -Subject: [PATCH 033/703] lan78xx: Enable LEDs and auto-negotiation +Subject: [PATCH 033/725] lan78xx: Enable LEDs and auto-negotiation For applications of the LAN78xx that don't have valid programmed EEPROMs or OTPs, enabling both LEDs and auto-negotiation by default diff --git a/target/linux/brcm2708/patches-4.19/950-0034-amba_pl011-Don-t-use-DT-aliases-for-numbering.patch b/target/linux/brcm2708/patches-4.19/950-0034-amba_pl011-Don-t-use-DT-aliases-for-numbering.patch index 7b93c4cabe..ba5d77bade 100644 --- a/target/linux/brcm2708/patches-4.19/950-0034-amba_pl011-Don-t-use-DT-aliases-for-numbering.patch +++ b/target/linux/brcm2708/patches-4.19/950-0034-amba_pl011-Don-t-use-DT-aliases-for-numbering.patch @@ -1,7 +1,7 @@ -From 3ff31acbe9b371f1b9247cc50e7751eaf98b4cef Mon Sep 17 00:00:00 2001 +From 00a9f57a05b9f62c1c8b44479b6e700958ef1400 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 23 Feb 2016 17:26:48 +0000 -Subject: [PATCH 034/703] amba_pl011: Don't use DT aliases for numbering +Subject: [PATCH 034/725] amba_pl011: Don't use DT aliases for numbering The pl011 driver looks for DT aliases of the form "serial", and if found uses as the device ID. This can cause diff --git a/target/linux/brcm2708/patches-4.19/950-0035-amba_pl011-Round-input-clock-up.patch b/target/linux/brcm2708/patches-4.19/950-0035-amba_pl011-Round-input-clock-up.patch index db425ff8b8..946a3cbc65 100644 --- a/target/linux/brcm2708/patches-4.19/950-0035-amba_pl011-Round-input-clock-up.patch +++ b/target/linux/brcm2708/patches-4.19/950-0035-amba_pl011-Round-input-clock-up.patch @@ -1,7 +1,7 @@ -From 5f626b06eb9efa01ca364a60378b3998d12e2f99 Mon Sep 17 00:00:00 2001 +From f6c9045d3e326e9b3f6c5d93fe09f517443d9075 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 1 Mar 2017 16:07:39 +0000 -Subject: [PATCH 035/703] amba_pl011: Round input clock up +Subject: [PATCH 035/725] 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 diff --git a/target/linux/brcm2708/patches-4.19/950-0036-amba_pl011-Insert-mb-for-correct-FIFO-handling.patch b/target/linux/brcm2708/patches-4.19/950-0036-amba_pl011-Insert-mb-for-correct-FIFO-handling.patch index d98a85985d..9f14c138dc 100644 --- a/target/linux/brcm2708/patches-4.19/950-0036-amba_pl011-Insert-mb-for-correct-FIFO-handling.patch +++ b/target/linux/brcm2708/patches-4.19/950-0036-amba_pl011-Insert-mb-for-correct-FIFO-handling.patch @@ -1,7 +1,7 @@ -From 0ebd5e2c627c3c41a1081f6c1b7e7caa13e5b12e Mon Sep 17 00:00:00 2001 +From 95ea844e0a7addac38e0385f5ab4215921e1c86b Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 29 Sep 2017 10:32:19 +0100 -Subject: [PATCH 036/703] amba_pl011: Insert mb() for correct FIFO handling +Subject: [PATCH 036/725] amba_pl011: Insert mb() for correct FIFO handling The pl011 register accessor functions use the _relaxed versions of the standard readl() and writel() functions, meaning that there are no diff --git a/target/linux/brcm2708/patches-4.19/950-0037-amba_pl011-Add-cts-event-workaround-DT-property.patch b/target/linux/brcm2708/patches-4.19/950-0037-amba_pl011-Add-cts-event-workaround-DT-property.patch index 51f70b6e18..b178a162e2 100644 --- a/target/linux/brcm2708/patches-4.19/950-0037-amba_pl011-Add-cts-event-workaround-DT-property.patch +++ b/target/linux/brcm2708/patches-4.19/950-0037-amba_pl011-Add-cts-event-workaround-DT-property.patch @@ -1,7 +1,7 @@ -From 9106531665bc17788096fcbc00dac3dd8a4ba2e8 Mon Sep 17 00:00:00 2001 +From 92cd7f1608ffea6325748373f9464a035743c3c3 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 29 Sep 2017 10:32:19 +0100 -Subject: [PATCH 037/703] amba_pl011: Add cts-event-workaround DT property +Subject: [PATCH 037/725] amba_pl011: Add cts-event-workaround DT property The BCM2835 PL011 implementation seems to have a bug that can lead to a transmission lockup if CTS changes frequently. A workaround was added to diff --git a/target/linux/brcm2708/patches-4.19/950-0038-pinctrl-bcm2835-Set-base-to-0-give-expected-gpio-num.patch b/target/linux/brcm2708/patches-4.19/950-0038-pinctrl-bcm2835-Set-base-to-0-give-expected-gpio-num.patch index 65f0ea36fa..2698813af6 100644 --- a/target/linux/brcm2708/patches-4.19/950-0038-pinctrl-bcm2835-Set-base-to-0-give-expected-gpio-num.patch +++ b/target/linux/brcm2708/patches-4.19/950-0038-pinctrl-bcm2835-Set-base-to-0-give-expected-gpio-num.patch @@ -1,7 +1,7 @@ -From d52da4747de6ca008f86a73fbf153526c164c0ee Mon Sep 17 00:00:00 2001 +From af8d6777f0c606b8c6a472651e4d00c595db8cdf Mon Sep 17 00:00:00 2001 From: notro Date: Thu, 10 Jul 2014 13:59:47 +0200 -Subject: [PATCH 038/703] pinctrl-bcm2835: Set base to 0 give expected gpio +Subject: [PATCH 038/725] pinctrl-bcm2835: Set base to 0 give expected gpio numbering Signed-off-by: Noralf Tronnes diff --git a/target/linux/brcm2708/patches-4.19/950-0039-Main-bcm2708-bcm2709-linux-port.patch b/target/linux/brcm2708/patches-4.19/950-0039-Main-bcm2708-bcm2709-linux-port.patch index 0257095db9..6b1d745ba4 100644 --- a/target/linux/brcm2708/patches-4.19/950-0039-Main-bcm2708-bcm2709-linux-port.patch +++ b/target/linux/brcm2708/patches-4.19/950-0039-Main-bcm2708-bcm2709-linux-port.patch @@ -1,7 +1,7 @@ -From 712b8ef1f284c70fc5612894c1a793c7d6b96eae Mon Sep 17 00:00:00 2001 +From f395eddcb1dad5b6b2905efa3ccb3916f91cadb9 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 12 May 2013 12:24:19 +0100 -Subject: [PATCH 039/703] Main bcm2708/bcm2709 linux port +Subject: [PATCH 039/725] Main bcm2708/bcm2709 linux port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/target/linux/brcm2708/patches-4.19/950-0040-Add-dwc_otg-driver.patch b/target/linux/brcm2708/patches-4.19/950-0040-Add-dwc_otg-driver.patch index d32a187b8a..b481a12f80 100644 --- a/target/linux/brcm2708/patches-4.19/950-0040-Add-dwc_otg-driver.patch +++ b/target/linux/brcm2708/patches-4.19/950-0040-Add-dwc_otg-driver.patch @@ -1,7 +1,7 @@ -From 21ea0e6ad04f26557d5d707f2848c576534d2fa0 Mon Sep 17 00:00:00 2001 +From 7d7d160ca73faa35ab961ce201194ea6c419e9af Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:46:17 +0100 -Subject: [PATCH 040/703] Add dwc_otg driver +Subject: [PATCH 040/725] Add dwc_otg driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/target/linux/brcm2708/patches-4.19/950-0041-bcm2708-framebuffer-driver.patch b/target/linux/brcm2708/patches-4.19/950-0041-bcm2708-framebuffer-driver.patch index 8a157861a5..38bd6986e2 100644 --- a/target/linux/brcm2708/patches-4.19/950-0041-bcm2708-framebuffer-driver.patch +++ b/target/linux/brcm2708/patches-4.19/950-0041-bcm2708-framebuffer-driver.patch @@ -1,7 +1,7 @@ -From a79eeea4c9cecd4770ee03ba8444c01cea34b3c1 Mon Sep 17 00:00:00 2001 +From 051c5a36a676f82455f356ef42279814992fca50 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 17:06:34 +0100 -Subject: [PATCH 041/703] bcm2708 framebuffer driver +Subject: [PATCH 041/725] bcm2708 framebuffer driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/target/linux/brcm2708/patches-4.19/950-0042-Speed-up-console-framebuffer-imageblit-function.patch b/target/linux/brcm2708/patches-4.19/950-0042-Speed-up-console-framebuffer-imageblit-function.patch index f8214e24f7..fbb8c2f6a8 100644 --- a/target/linux/brcm2708/patches-4.19/950-0042-Speed-up-console-framebuffer-imageblit-function.patch +++ b/target/linux/brcm2708/patches-4.19/950-0042-Speed-up-console-framebuffer-imageblit-function.patch @@ -1,7 +1,7 @@ -From a1e59cb06aaa97771f2d39777017f8de6f237507 Mon Sep 17 00:00:00 2001 +From d73294bd1cceb3b51801d136b3ba8b38d3d23b59 Mon Sep 17 00:00:00 2001 From: Harm Hanemaaijer Date: Thu, 20 Jun 2013 20:21:39 +0200 -Subject: [PATCH 042/703] Speed up console framebuffer imageblit function +Subject: [PATCH 042/725] Speed up console framebuffer imageblit function Especially on platforms with a slower CPU but a relatively high framebuffer fill bandwidth, like current ARM devices, the existing diff --git a/target/linux/brcm2708/patches-4.19/950-0043-dmaengine-Add-support-for-BCM2708.patch b/target/linux/brcm2708/patches-4.19/950-0043-dmaengine-Add-support-for-BCM2708.patch index d2ded22af1..f2c0010d95 100644 --- a/target/linux/brcm2708/patches-4.19/950-0043-dmaengine-Add-support-for-BCM2708.patch +++ b/target/linux/brcm2708/patches-4.19/950-0043-dmaengine-Add-support-for-BCM2708.patch @@ -1,7 +1,7 @@ -From 3b7f7192307a3cc84215a42c42065758dd638986 Mon Sep 17 00:00:00 2001 +From 4a615d508ab20ee974c7f787739157ad86fcd410 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:22:53 +0100 -Subject: [PATCH 043/703] dmaengine: Add support for BCM2708 +Subject: [PATCH 043/725] dmaengine: Add support for BCM2708 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/target/linux/brcm2708/patches-4.19/950-0044-MMC-added-alternative-MMC-driver.patch b/target/linux/brcm2708/patches-4.19/950-0044-MMC-added-alternative-MMC-driver.patch index 3cd347da98..0d77cd7988 100644 --- a/target/linux/brcm2708/patches-4.19/950-0044-MMC-added-alternative-MMC-driver.patch +++ b/target/linux/brcm2708/patches-4.19/950-0044-MMC-added-alternative-MMC-driver.patch @@ -1,7 +1,7 @@ -From c34520567bf3dbca64cb871dacab7230c61726f6 Mon Sep 17 00:00:00 2001 +From b780980e2f381fd19c8d42af07d3d0b8aac3a8e2 Mon Sep 17 00:00:00 2001 From: gellert Date: Fri, 15 Aug 2014 16:35:06 +0100 -Subject: [PATCH 044/703] MMC: added alternative MMC driver +Subject: [PATCH 044/725] MMC: added alternative MMC driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/target/linux/brcm2708/patches-4.19/950-0045-Adding-bcm2835-sdhost-driver-and-an-overlay-to-enabl.patch b/target/linux/brcm2708/patches-4.19/950-0045-Adding-bcm2835-sdhost-driver-and-an-overlay-to-enabl.patch index cdd9656e74..f7e528aac6 100644 --- a/target/linux/brcm2708/patches-4.19/950-0045-Adding-bcm2835-sdhost-driver-and-an-overlay-to-enabl.patch +++ b/target/linux/brcm2708/patches-4.19/950-0045-Adding-bcm2835-sdhost-driver-and-an-overlay-to-enabl.patch @@ -1,7 +1,7 @@ -From 878b9058f3939881f570d84e8584f5ff9f79a847 Mon Sep 17 00:00:00 2001 +From d09bc280308712a775258a4ddf6198ba0d3bcfd5 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 25 Mar 2015 17:49:47 +0000 -Subject: [PATCH 045/703] Adding bcm2835-sdhost driver, and an overlay to +Subject: [PATCH 045/725] Adding bcm2835-sdhost driver, and an overlay to enable it BCM2835 has two SD card interfaces. This driver uses the other one. diff --git a/target/linux/brcm2708/patches-4.19/950-0046-vc_mem-Add-vc_mem-driver-for-querying-firmware-memor.patch b/target/linux/brcm2708/patches-4.19/950-0046-vc_mem-Add-vc_mem-driver-for-querying-firmware-memor.patch index 044b573f78..dfb5d2d8c9 100644 --- a/target/linux/brcm2708/patches-4.19/950-0046-vc_mem-Add-vc_mem-driver-for-querying-firmware-memor.patch +++ b/target/linux/brcm2708/patches-4.19/950-0046-vc_mem-Add-vc_mem-driver-for-querying-firmware-memor.patch @@ -1,7 +1,7 @@ -From 93e55dab09f9790d4cb547a9ac0a3c4803e682db Mon Sep 17 00:00:00 2001 +From 754aa63cbba18514970ea307d54fdfe4eb7072ea Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 28 Oct 2016 15:36:43 +0100 -Subject: [PATCH 046/703] vc_mem: Add vc_mem driver for querying firmware +Subject: [PATCH 046/725] vc_mem: Add vc_mem driver for querying firmware memory addresses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 diff --git a/target/linux/brcm2708/patches-4.19/950-0047-vcsm-VideoCore-shared-memory-service-for-BCM2835.patch b/target/linux/brcm2708/patches-4.19/950-0047-vcsm-VideoCore-shared-memory-service-for-BCM2835.patch index 72957fd78d..672ad4b096 100644 --- a/target/linux/brcm2708/patches-4.19/950-0047-vcsm-VideoCore-shared-memory-service-for-BCM2835.patch +++ b/target/linux/brcm2708/patches-4.19/950-0047-vcsm-VideoCore-shared-memory-service-for-BCM2835.patch @@ -1,7 +1,7 @@ -From 949b8ddbdd7d0865f71b93cc3774b738f229062a Mon Sep 17 00:00:00 2001 +From 42afc949534ce6402c3e2e13d7c939af45573376 Mon Sep 17 00:00:00 2001 From: Tim Gover Date: Tue, 22 Jul 2014 15:41:04 +0100 -Subject: [PATCH 047/703] vcsm: VideoCore shared memory service for BCM2835 +Subject: [PATCH 047/725] vcsm: VideoCore shared memory service for BCM2835 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/target/linux/brcm2708/patches-4.19/950-0048-Add-dev-gpiomem-device-for-rootless-user-GPIO-access.patch b/target/linux/brcm2708/patches-4.19/950-0048-Add-dev-gpiomem-device-for-rootless-user-GPIO-access.patch index e9a1227973..faf6921dad 100644 --- a/target/linux/brcm2708/patches-4.19/950-0048-Add-dev-gpiomem-device-for-rootless-user-GPIO-access.patch +++ b/target/linux/brcm2708/patches-4.19/950-0048-Add-dev-gpiomem-device-for-rootless-user-GPIO-access.patch @@ -1,7 +1,7 @@ -From 1a2c16ef68cbba94eee5d916e77269bca572830d Mon Sep 17 00:00:00 2001 +From 66a15ff847fb92d85deb19e694d999ad5d806401 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Fri, 21 Aug 2015 23:14:48 +0100 -Subject: [PATCH 048/703] Add /dev/gpiomem device for rootless user GPIO access +Subject: [PATCH 048/725] Add /dev/gpiomem device for rootless user GPIO access Signed-off-by: Luke Wren diff --git a/target/linux/brcm2708/patches-4.19/950-0049-Add-SMI-driver.patch b/target/linux/brcm2708/patches-4.19/950-0049-Add-SMI-driver.patch index fdb144d6a9..11265a5b73 100644 --- a/target/linux/brcm2708/patches-4.19/950-0049-Add-SMI-driver.patch +++ b/target/linux/brcm2708/patches-4.19/950-0049-Add-SMI-driver.patch @@ -1,7 +1,7 @@ -From edaa95330a802b1bcc26cfcd90404ebadd82965b Mon Sep 17 00:00:00 2001 +From dfb42085ee75db965bffe304287bea68b93b4b39 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Sat, 5 Sep 2015 01:14:45 +0100 -Subject: [PATCH 049/703] Add SMI driver +Subject: [PATCH 049/725] Add SMI driver Signed-off-by: Luke Wren --- diff --git a/target/linux/brcm2708/patches-4.19/950-0050-MISC-bcm2835-smi-use-clock-manager-and-fix-reload-is.patch b/target/linux/brcm2708/patches-4.19/950-0050-MISC-bcm2835-smi-use-clock-manager-and-fix-reload-is.patch index b68ccc7132..55b760ca40 100644 --- a/target/linux/brcm2708/patches-4.19/950-0050-MISC-bcm2835-smi-use-clock-manager-and-fix-reload-is.patch +++ b/target/linux/brcm2708/patches-4.19/950-0050-MISC-bcm2835-smi-use-clock-manager-and-fix-reload-is.patch @@ -1,7 +1,7 @@ -From 1216c1cccdd7e1eafd6859c9522cdef5c2e4ac8d Mon Sep 17 00:00:00 2001 +From f468b36a6b998cf9848bfcc24370cf13b2730b93 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Tue, 26 Apr 2016 14:59:21 +0000 -Subject: [PATCH 050/703] MISC: bcm2835: smi: use clock manager and fix reload +Subject: [PATCH 050/725] MISC: bcm2835: smi: use clock manager and fix reload issues Use clock manager instead of self-made clockmanager. diff --git a/target/linux/brcm2708/patches-4.19/950-0051-Add-SMI-NAND-driver.patch b/target/linux/brcm2708/patches-4.19/950-0051-Add-SMI-NAND-driver.patch index 04d9e46fdf..8f0eacb1bb 100644 --- a/target/linux/brcm2708/patches-4.19/950-0051-Add-SMI-NAND-driver.patch +++ b/target/linux/brcm2708/patches-4.19/950-0051-Add-SMI-NAND-driver.patch @@ -1,7 +1,7 @@ -From a3f0263e2d5deb675dfe7fb0c31167e86d762e27 Mon Sep 17 00:00:00 2001 +From 680df120e2054ce209e24415795a972bf76826b3 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Sat, 5 Sep 2015 01:16:10 +0100 -Subject: [PATCH 051/703] Add SMI NAND driver +Subject: [PATCH 051/725] Add SMI NAND driver Signed-off-by: Luke Wren --- diff --git a/target/linux/brcm2708/patches-4.19/950-0052-Add-cpufreq-driver.patch b/target/linux/brcm2708/patches-4.19/950-0052-Add-cpufreq-driver.patch index 3ef91c98b3..34eddd091e 100644 --- a/target/linux/brcm2708/patches-4.19/950-0052-Add-cpufreq-driver.patch +++ b/target/linux/brcm2708/patches-4.19/950-0052-Add-cpufreq-driver.patch @@ -1,7 +1,7 @@ -From 6ae7a56fdff2578805c6f17f03b5bc1b1f9d45a8 Mon Sep 17 00:00:00 2001 +From 7e52446393c3cc4200fa08dcfd1ea555d77c7068 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:49:20 +0100 -Subject: [PATCH 052/703] Add cpufreq driver +Subject: [PATCH 052/725] Add cpufreq driver Signed-off-by: popcornmix diff --git a/target/linux/brcm2708/patches-4.19/950-0053-Add-Chris-Boot-s-i2c-driver.patch b/target/linux/brcm2708/patches-4.19/950-0053-Add-Chris-Boot-s-i2c-driver.patch index 1869c9a27e..a7c82cb5ce 100644 --- a/target/linux/brcm2708/patches-4.19/950-0053-Add-Chris-Boot-s-i2c-driver.patch +++ b/target/linux/brcm2708/patches-4.19/950-0053-Add-Chris-Boot-s-i2c-driver.patch @@ -1,7 +1,7 @@ -From 3ae115e0812cdaaa3404c84354f40f1e1402fadf Mon Sep 17 00:00:00 2001 +From 92480253067c3534b16f4827f075f5590120b046 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 15:44:08 +0100 -Subject: [PATCH 053/703] Add Chris Boot's i2c driver +Subject: [PATCH 053/725] Add Chris Boot's i2c driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/target/linux/brcm2708/patches-4.19/950-0054-char-broadcom-Add-vcio-module.patch b/target/linux/brcm2708/patches-4.19/950-0054-char-broadcom-Add-vcio-module.patch index f268d1188f..9d20877088 100644 --- a/target/linux/brcm2708/patches-4.19/950-0054-char-broadcom-Add-vcio-module.patch +++ b/target/linux/brcm2708/patches-4.19/950-0054-char-broadcom-Add-vcio-module.patch @@ -1,7 +1,7 @@ -From 9fc71e9f5ee71c3f91b43c8c94a0db17349b938c Mon Sep 17 00:00:00 2001 +From a9c2c59a13c9138494b3adb1ce918def9825c376 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Fri, 26 Jun 2015 14:27:06 +0200 -Subject: [PATCH 054/703] char: broadcom: Add vcio module +Subject: [PATCH 054/725] char: broadcom: Add vcio module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/target/linux/brcm2708/patches-4.19/950-0055-firmware-bcm2835-Support-ARCH_BCM270x.patch b/target/linux/brcm2708/patches-4.19/950-0055-firmware-bcm2835-Support-ARCH_BCM270x.patch index 590a927356..6f23a5c0d4 100644 --- a/target/linux/brcm2708/patches-4.19/950-0055-firmware-bcm2835-Support-ARCH_BCM270x.patch +++ b/target/linux/brcm2708/patches-4.19/950-0055-firmware-bcm2835-Support-ARCH_BCM270x.patch @@ -1,7 +1,7 @@ -From 2df6434c1ff682a80f65bde7a9e026f4e0d20df1 Mon Sep 17 00:00:00 2001 +From c31f46a51f80fe435de05dc07859291d3540c096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Fri, 26 Jun 2015 14:25:01 +0200 -Subject: [PATCH 055/703] firmware: bcm2835: Support ARCH_BCM270x +Subject: [PATCH 055/725] firmware: bcm2835: Support ARCH_BCM270x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/target/linux/brcm2708/patches-4.19/950-0056-scripts-Add-mkknlimg-and-knlinfo-scripts-from-tools-.patch b/target/linux/brcm2708/patches-4.19/950-0056-scripts-Add-mkknlimg-and-knlinfo-scripts-from-tools-.patch index 098a2c62c4..570237f43a 100644 --- a/target/linux/brcm2708/patches-4.19/950-0056-scripts-Add-mkknlimg-and-knlinfo-scripts-from-tools-.patch +++ b/target/linux/brcm2708/patches-4.19/950-0056-scripts-Add-mkknlimg-and-knlinfo-scripts-from-tools-.patch @@ -1,7 +1,7 @@ -From bce7a71e1f399b6dcea8a145cc5fff4653450c50 Mon Sep 17 00:00:00 2001 +From 429e2d968172360c0b7a443229503158910abb92 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 11 May 2015 09:00:42 +0100 -Subject: [PATCH 056/703] scripts: Add mkknlimg and knlinfo scripts from tools +Subject: [PATCH 056/725] scripts: Add mkknlimg and knlinfo scripts from tools repo The Raspberry Pi firmware looks for a trailer on the kernel image to diff --git a/target/linux/brcm2708/patches-4.19/950-0057-BCM2708-Add-core-Device-Tree-support.patch b/target/linux/brcm2708/patches-4.19/950-0057-BCM2708-Add-core-Device-Tree-support.patch index 94501ef348..75d0a6d9ca 100644 --- a/target/linux/brcm2708/patches-4.19/950-0057-BCM2708-Add-core-Device-Tree-support.patch +++ b/target/linux/brcm2708/patches-4.19/950-0057-BCM2708-Add-core-Device-Tree-support.patch @@ -1,7 +1,7 @@ -From ef38e1a2b9c83fb10ac6fffdfa26da71776a3abb Mon Sep 17 00:00:00 2001 +From 2b8bc69a15a59b93330d37fb8629ae113231a0fb Mon Sep 17 00:00:00 2001 From: notro Date: Wed, 9 Jul 2014 14:46:08 +0200 -Subject: [PATCH 057/703] BCM2708: Add core Device Tree support +Subject: [PATCH 057/725] BCM2708: Add core Device Tree support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/target/linux/brcm2708/patches-4.19/950-0058-BCM270x_DT-Add-pwr_led-and-the-required-input-trigge.patch b/target/linux/brcm2708/patches-4.19/950-0058-BCM270x_DT-Add-pwr_led-and-the-required-input-trigge.patch index 7d43894881..1b991d11b1 100644 --- a/target/linux/brcm2708/patches-4.19/950-0058-BCM270x_DT-Add-pwr_led-and-the-required-input-trigge.patch +++ b/target/linux/brcm2708/patches-4.19/950-0058-BCM270x_DT-Add-pwr_led-and-the-required-input-trigge.patch @@ -1,7 +1,7 @@ -From 28644cb31e076ccc6645c692a7ff43414230f361 Mon Sep 17 00:00:00 2001 +From ed4300c1a1c2432efd902454146e2ca909b23192 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 6 Feb 2015 13:50:57 +0000 -Subject: [PATCH 058/703] BCM270x_DT: Add pwr_led, and the required "input" +Subject: [PATCH 058/725] BCM270x_DT: Add pwr_led, and the required "input" trigger The "input" trigger makes the associated GPIO an input. This is to support diff --git a/target/linux/brcm2708/patches-4.19/950-0059-fbdev-add-FBIOCOPYAREA-ioctl.patch b/target/linux/brcm2708/patches-4.19/950-0059-fbdev-add-FBIOCOPYAREA-ioctl.patch index c9e5a92d0f..da78f05388 100644 --- a/target/linux/brcm2708/patches-4.19/950-0059-fbdev-add-FBIOCOPYAREA-ioctl.patch +++ b/target/linux/brcm2708/patches-4.19/950-0059-fbdev-add-FBIOCOPYAREA-ioctl.patch @@ -1,7 +1,7 @@ -From cdec439b6dd76c5e1ccbe49636882067971abd0d Mon Sep 17 00:00:00 2001 +From 4f3938a0decb1d939978df44ac060deaa886b7c1 Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Mon, 17 Jun 2013 13:32:11 +0300 -Subject: [PATCH 059/703] fbdev: add FBIOCOPYAREA ioctl +Subject: [PATCH 059/725] fbdev: add FBIOCOPYAREA ioctl Based on the patch authored by Ali Gholami Rudi at https://lkml.org/lkml/2009/7/13/153 diff --git a/target/linux/brcm2708/patches-4.19/950-0060-Added-Device-IDs-for-August-DVB-T-205.patch b/target/linux/brcm2708/patches-4.19/950-0060-Added-Device-IDs-for-August-DVB-T-205.patch index bec94e1026..46332a7da5 100644 --- a/target/linux/brcm2708/patches-4.19/950-0060-Added-Device-IDs-for-August-DVB-T-205.patch +++ b/target/linux/brcm2708/patches-4.19/950-0060-Added-Device-IDs-for-August-DVB-T-205.patch @@ -1,7 +1,7 @@ -From 4052b5ba9b502747a6326b43e7f1437be36843b7 Mon Sep 17 00:00:00 2001 +From e408564fff425286f3acf9f625aa763d5cb8408b Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:54:08 +0100 -Subject: [PATCH 060/703] Added Device IDs for August DVB-T 205 +Subject: [PATCH 060/725] Added Device IDs for August DVB-T 205 --- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 4 ++++ diff --git a/target/linux/brcm2708/patches-4.19/950-0061-rpi-ft5406-Add-touchscreen-driver-for-pi-LCD-display.patch b/target/linux/brcm2708/patches-4.19/950-0061-rpi-ft5406-Add-touchscreen-driver-for-pi-LCD-display.patch index fa3feb6d86..a8cb9585c0 100644 --- a/target/linux/brcm2708/patches-4.19/950-0061-rpi-ft5406-Add-touchscreen-driver-for-pi-LCD-display.patch +++ b/target/linux/brcm2708/patches-4.19/950-0061-rpi-ft5406-Add-touchscreen-driver-for-pi-LCD-display.patch @@ -1,7 +1,7 @@ -From adc948965c7c2c52df7c93acffe5bd1d71dce462 Mon Sep 17 00:00:00 2001 +From e04d6501cf52bc69d75adef77482d6f6b027032d Mon Sep 17 00:00:00 2001 From: Gordon Hollingworth Date: Tue, 12 May 2015 14:47:56 +0100 -Subject: [PATCH 061/703] rpi-ft5406: Add touchscreen driver for pi LCD display +Subject: [PATCH 061/725] rpi-ft5406: Add touchscreen driver for pi LCD display Fix driver detection failure Check that the buffer response is non-zero meaning the touchscreen was detected diff --git a/target/linux/brcm2708/patches-4.19/950-0062-Improve-__copy_to_user-and-__copy_from_user-performa.patch b/target/linux/brcm2708/patches-4.19/950-0062-Improve-__copy_to_user-and-__copy_from_user-performa.patch index d022074b5f..e201ea6d47 100644 --- a/target/linux/brcm2708/patches-4.19/950-0062-Improve-__copy_to_user-and-__copy_from_user-performa.patch +++ b/target/linux/brcm2708/patches-4.19/950-0062-Improve-__copy_to_user-and-__copy_from_user-performa.patch @@ -1,7 +1,7 @@ -From e182f20d9faf1853dde2ab827a228011fa1dbc80 Mon Sep 17 00:00:00 2001 +From 4db2d4944e658ce809e6366a3a1338d0c2939231 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 28 Nov 2016 16:50:04 +0000 -Subject: [PATCH 062/703] Improve __copy_to_user and __copy_from_user +Subject: [PATCH 062/725] Improve __copy_to_user and __copy_from_user performance Provide a __copy_from_user that uses memcpy. On BCM2708, use diff --git a/target/linux/brcm2708/patches-4.19/950-0063-gpio-poweroff-Allow-it-to-work-on-Raspberry-Pi.patch b/target/linux/brcm2708/patches-4.19/950-0063-gpio-poweroff-Allow-it-to-work-on-Raspberry-Pi.patch index affb4c3fc8..73fbb420ee 100644 --- a/target/linux/brcm2708/patches-4.19/950-0063-gpio-poweroff-Allow-it-to-work-on-Raspberry-Pi.patch +++ b/target/linux/brcm2708/patches-4.19/950-0063-gpio-poweroff-Allow-it-to-work-on-Raspberry-Pi.patch @@ -1,7 +1,7 @@ -From 985bdee303c68ce16a6ad0b0e317c86b9669ab1a Mon Sep 17 00:00:00 2001 +From 799527e3596ebb96f5df8174818c193a8ca68781 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 25 Jun 2015 12:16:11 +0100 -Subject: [PATCH 063/703] gpio-poweroff: Allow it to work on Raspberry Pi +Subject: [PATCH 063/725] gpio-poweroff: Allow it to work on Raspberry Pi The Raspberry Pi firmware manages the power-down and reboot process. To do this it installs a pm_power_off handler, causing diff --git a/target/linux/brcm2708/patches-4.19/950-0064-mfd-Add-Raspberry-Pi-Sense-HAT-core-driver.patch b/target/linux/brcm2708/patches-4.19/950-0064-mfd-Add-Raspberry-Pi-Sense-HAT-core-driver.patch index cfe30fc10a..e00b458ff3 100644 --- a/target/linux/brcm2708/patches-4.19/950-0064-mfd-Add-Raspberry-Pi-Sense-HAT-core-driver.patch +++ b/target/linux/brcm2708/patches-4.19/950-0064-mfd-Add-Raspberry-Pi-Sense-HAT-core-driver.patch @@ -1,7 +1,7 @@ -From cc60f52641f8debefb1c37b59379ccdc84e1938f Mon Sep 17 00:00:00 2001 +From 8d80ce248d128b583244b0b00ce89ffa39598fe7 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 14 Jul 2015 14:32:47 +0100 -Subject: [PATCH 064/703] mfd: Add Raspberry Pi Sense HAT core driver +Subject: [PATCH 064/725] mfd: Add Raspberry Pi Sense HAT core driver --- drivers/input/joystick/Kconfig | 8 + diff --git a/target/linux/brcm2708/patches-4.19/950-0065-ASoC-pcm512x-implement-set_tdm_slot-interface.patch b/target/linux/brcm2708/patches-4.19/950-0065-ASoC-pcm512x-implement-set_tdm_slot-interface.patch index 1d0b76a3b9..f66d7e7f78 100644 --- a/target/linux/brcm2708/patches-4.19/950-0065-ASoC-pcm512x-implement-set_tdm_slot-interface.patch +++ b/target/linux/brcm2708/patches-4.19/950-0065-ASoC-pcm512x-implement-set_tdm_slot-interface.patch @@ -1,7 +1,7 @@ -From 099cc7ff40bca5c9203100aaca2ab69bc7b669ac Mon Sep 17 00:00:00 2001 +From b63482e725f4dd2c6adcda4878e5eadac238f05b Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Thu, 22 Feb 2018 11:55:06 +0100 -Subject: [PATCH 065/703] ASoC: pcm512x: implement set_tdm_slot interface +Subject: [PATCH 065/725] ASoC: pcm512x: implement set_tdm_slot interface PCM512x can accept data padded with additional BCLK cycles but the driver currently lacks an interface to configure this. diff --git a/target/linux/brcm2708/patches-4.19/950-0066-ASoC-Add-support-for-Rpi-DAC.patch b/target/linux/brcm2708/patches-4.19/950-0066-ASoC-Add-support-for-Rpi-DAC.patch index d4225de82b..2952d7e5b6 100644 --- a/target/linux/brcm2708/patches-4.19/950-0066-ASoC-Add-support-for-Rpi-DAC.patch +++ b/target/linux/brcm2708/patches-4.19/950-0066-ASoC-Add-support-for-Rpi-DAC.patch @@ -1,7 +1,7 @@ -From 2112d06f09c1ecd601de065351bc60b08fc53bca Mon Sep 17 00:00:00 2001 +From 5a5287ced8232a84e624c198b4595684134ff8f7 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Mon, 25 Jan 2016 15:48:59 +0000 -Subject: [PATCH 066/703] ASoC: Add support for Rpi-DAC +Subject: [PATCH 066/725] ASoC: Add support for Rpi-DAC --- sound/soc/codecs/Kconfig | 5 +++ diff --git a/target/linux/brcm2708/patches-4.19/950-0067-Add-IQaudIO-Sound-Card-support-for-Raspberry-Pi.patch b/target/linux/brcm2708/patches-4.19/950-0067-Add-IQaudIO-Sound-Card-support-for-Raspberry-Pi.patch index 2b4a1302a4..bd6cd68415 100644 --- a/target/linux/brcm2708/patches-4.19/950-0067-Add-IQaudIO-Sound-Card-support-for-Raspberry-Pi.patch +++ b/target/linux/brcm2708/patches-4.19/950-0067-Add-IQaudIO-Sound-Card-support-for-Raspberry-Pi.patch @@ -1,7 +1,7 @@ -From c8aa8a71618c103d09ae7fa05d5f65c111581194 Mon Sep 17 00:00:00 2001 +From 6cea04a434dfd4f3fbf02fdb5652d50a24586b18 Mon Sep 17 00:00:00 2001 From: Gordon Garrity Date: Sat, 8 Mar 2014 16:56:57 +0000 -Subject: [PATCH 067/703] Add IQaudIO Sound Card support for Raspberry Pi +Subject: [PATCH 067/725] Add IQaudIO Sound Card support for Raspberry Pi Set a limit of 0dB on Digital Volume Control diff --git a/target/linux/brcm2708/patches-4.19/950-0068-Added-support-for-HiFiBerry-DAC.patch b/target/linux/brcm2708/patches-4.19/950-0068-Added-support-for-HiFiBerry-DAC.patch index 4e37f19c64..a244cd205b 100644 --- a/target/linux/brcm2708/patches-4.19/950-0068-Added-support-for-HiFiBerry-DAC.patch +++ b/target/linux/brcm2708/patches-4.19/950-0068-Added-support-for-HiFiBerry-DAC.patch @@ -1,7 +1,7 @@ -From c383086fd519fcf61f3c5a35e937685f6f34832e Mon Sep 17 00:00:00 2001 +From 015277e926834c77787f4b6b15871f72e7b22d47 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Mon, 4 Aug 2014 10:06:56 +0200 -Subject: [PATCH 068/703] Added support for HiFiBerry DAC+ +Subject: [PATCH 068/725] Added support for HiFiBerry DAC+ The driver is based on the HiFiBerry DAC driver. However HiFiBerry DAC+ uses a different codec chip (PCM5122), therefore a new driver is necessary. diff --git a/target/linux/brcm2708/patches-4.19/950-0069-Added-driver-for-HiFiBerry-Amp-amplifier-add-on-boar.patch b/target/linux/brcm2708/patches-4.19/950-0069-Added-driver-for-HiFiBerry-Amp-amplifier-add-on-boar.patch index 17e80bb672..2fa239707c 100644 --- a/target/linux/brcm2708/patches-4.19/950-0069-Added-driver-for-HiFiBerry-Amp-amplifier-add-on-boar.patch +++ b/target/linux/brcm2708/patches-4.19/950-0069-Added-driver-for-HiFiBerry-Amp-amplifier-add-on-boar.patch @@ -1,7 +1,7 @@ -From 32df84e8c6f0f747c1182774fadbf4e9ef1794e2 Mon Sep 17 00:00:00 2001 +From 87a94fcef688251a514e9fa209a8c4ff63cdee73 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Mon, 4 Aug 2014 11:09:58 +0200 -Subject: [PATCH 069/703] Added driver for HiFiBerry Amp amplifier add-on board +Subject: [PATCH 069/725] Added driver for HiFiBerry Amp amplifier add-on board The driver contains a low-level hardware driver for the TAS5713 and the drivers for the Raspberry Pi I2S subsystem. diff --git a/target/linux/brcm2708/patches-4.19/950-0070-Add-driver-for-rpi-proto.patch b/target/linux/brcm2708/patches-4.19/950-0070-Add-driver-for-rpi-proto.patch index 098d5f4e65..8d1f34a4f4 100644 --- a/target/linux/brcm2708/patches-4.19/950-0070-Add-driver-for-rpi-proto.patch +++ b/target/linux/brcm2708/patches-4.19/950-0070-Add-driver-for-rpi-proto.patch @@ -1,7 +1,7 @@ -From 0a8842f908f015bd889e3c0cee5115db1c451990 Mon Sep 17 00:00:00 2001 +From 931b6e6c23f08ac08c5542ae2fae4ae6ab6eeec1 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 25 Mar 2015 09:26:17 +0100 -Subject: [PATCH 070/703] Add driver for rpi-proto +Subject: [PATCH 070/725] Add driver for rpi-proto Forward port of 3.10.x driver from https://github.com/koalo We are using a custom board and would like to use rpi 3.18.x diff --git a/target/linux/brcm2708/patches-4.19/950-0071-Add-Support-for-JustBoom-Audio-boards.patch b/target/linux/brcm2708/patches-4.19/950-0071-Add-Support-for-JustBoom-Audio-boards.patch index 731cee62e9..804a9fd77a 100644 --- a/target/linux/brcm2708/patches-4.19/950-0071-Add-Support-for-JustBoom-Audio-boards.patch +++ b/target/linux/brcm2708/patches-4.19/950-0071-Add-Support-for-JustBoom-Audio-boards.patch @@ -1,7 +1,7 @@ -From 71cd216db9c7c05f05c8dd7c7afdfb24f718be74 Mon Sep 17 00:00:00 2001 +From dc3e8f3e1d03f43d2af2709b6d5f09d72ef8d47e Mon Sep 17 00:00:00 2001 From: Aaron Shaw Date: Thu, 7 Apr 2016 21:26:21 +0100 -Subject: [PATCH 071/703] Add Support for JustBoom Audio boards +Subject: [PATCH 071/725] Add Support for JustBoom Audio boards justboom-dac: Adjust for ALSA API change diff --git a/target/linux/brcm2708/patches-4.19/950-0072-New-AudioInjector.net-Pi-soundcard-with-low-jitter-a.patch b/target/linux/brcm2708/patches-4.19/950-0072-New-AudioInjector.net-Pi-soundcard-with-low-jitter-a.patch index 369e18318a..0dd97168a7 100644 --- a/target/linux/brcm2708/patches-4.19/950-0072-New-AudioInjector.net-Pi-soundcard-with-low-jitter-a.patch +++ b/target/linux/brcm2708/patches-4.19/950-0072-New-AudioInjector.net-Pi-soundcard-with-low-jitter-a.patch @@ -1,7 +1,7 @@ -From 075e259919f36828473a97a231cdafcec073b63b Mon Sep 17 00:00:00 2001 +From 7a3906eb4db44354f2a3f7a330c1648964e51681 Mon Sep 17 00:00:00 2001 From: Matt Flax Date: Mon, 16 May 2016 21:36:31 +1000 -Subject: [PATCH 072/703] New AudioInjector.net Pi soundcard with low jitter +Subject: [PATCH 072/725] New AudioInjector.net Pi soundcard with low jitter audio in and out. Contains the sound/soc/bcm ALSA machine driver and necessary alterations to the Kconfig and Makefile. diff --git a/target/linux/brcm2708/patches-4.19/950-0073-New-driver-for-RRA-DigiDAC1-soundcard-using-WM8741-W.patch b/target/linux/brcm2708/patches-4.19/950-0073-New-driver-for-RRA-DigiDAC1-soundcard-using-WM8741-W.patch index 0a43d5e1ec..57825d9a6f 100644 --- a/target/linux/brcm2708/patches-4.19/950-0073-New-driver-for-RRA-DigiDAC1-soundcard-using-WM8741-W.patch +++ b/target/linux/brcm2708/patches-4.19/950-0073-New-driver-for-RRA-DigiDAC1-soundcard-using-WM8741-W.patch @@ -1,7 +1,7 @@ -From 3f5b5702b2245c639439607ab4e64d654edaa864 Mon Sep 17 00:00:00 2001 +From c2c45a480f012a6d939f39470e9d3a5e689b8b03 Mon Sep 17 00:00:00 2001 From: escalator2015 Date: Tue, 24 May 2016 16:20:09 +0100 -Subject: [PATCH 073/703] New driver for RRA DigiDAC1 soundcard using WM8741 + +Subject: [PATCH 073/725] New driver for RRA DigiDAC1 soundcard using WM8741 + WM8804 --- diff --git a/target/linux/brcm2708/patches-4.19/950-0074-Add-support-for-Dion-Audio-LOCO-DAC-AMP-HAT.patch b/target/linux/brcm2708/patches-4.19/950-0074-Add-support-for-Dion-Audio-LOCO-DAC-AMP-HAT.patch index 586e04d7f5..4a734640a6 100644 --- a/target/linux/brcm2708/patches-4.19/950-0074-Add-support-for-Dion-Audio-LOCO-DAC-AMP-HAT.patch +++ b/target/linux/brcm2708/patches-4.19/950-0074-Add-support-for-Dion-Audio-LOCO-DAC-AMP-HAT.patch @@ -1,7 +1,7 @@ -From 63f29d95488d5bbebc704f904e3f4d12ba90fe42 Mon Sep 17 00:00:00 2001 +From 54fc10a745ca32f55c504e6b08238da56ec3fa83 Mon Sep 17 00:00:00 2001 From: DigitalDreamtime Date: Sat, 2 Jul 2016 16:26:19 +0100 -Subject: [PATCH 074/703] Add support for Dion Audio LOCO DAC-AMP HAT +Subject: [PATCH 074/725] Add support for Dion Audio LOCO DAC-AMP HAT Using dedicated machine driver and pcm5102a codec driver. diff --git a/target/linux/brcm2708/patches-4.19/950-0075-Allo-Piano-DAC-boards-Initial-2-channel-stereo-suppo.patch b/target/linux/brcm2708/patches-4.19/950-0075-Allo-Piano-DAC-boards-Initial-2-channel-stereo-suppo.patch index 3f9b69faf3..292325b68a 100644 --- a/target/linux/brcm2708/patches-4.19/950-0075-Allo-Piano-DAC-boards-Initial-2-channel-stereo-suppo.patch +++ b/target/linux/brcm2708/patches-4.19/950-0075-Allo-Piano-DAC-boards-Initial-2-channel-stereo-suppo.patch @@ -1,7 +1,7 @@ -From befd64b81a740cba0ad23a6732dd56b2e67dda84 Mon Sep 17 00:00:00 2001 +From 45f28f47c5b4a3fabf33304c3660496da0b9dbcd Mon Sep 17 00:00:00 2001 From: Clive Messer Date: Mon, 19 Sep 2016 14:01:04 +0100 -Subject: [PATCH 075/703] Allo Piano DAC boards: Initial 2 channel (stereo) +Subject: [PATCH 075/725] Allo Piano DAC boards: Initial 2 channel (stereo) support (#1645) Add initial 2 channel (stereo) support for Allo Piano DAC (2.0/2.1) boards, diff --git a/target/linux/brcm2708/patches-4.19/950-0076-Add-support-for-Allo-Piano-DAC-2.1-plus-add-on-board.patch b/target/linux/brcm2708/patches-4.19/950-0076-Add-support-for-Allo-Piano-DAC-2.1-plus-add-on-board.patch index acc636068a..1bb980d41d 100644 --- a/target/linux/brcm2708/patches-4.19/950-0076-Add-support-for-Allo-Piano-DAC-2.1-plus-add-on-board.patch +++ b/target/linux/brcm2708/patches-4.19/950-0076-Add-support-for-Allo-Piano-DAC-2.1-plus-add-on-board.patch @@ -1,7 +1,7 @@ -From 9a43360b6f8d6073b0bd67077229fe1d63076733 Mon Sep 17 00:00:00 2001 +From 9659dfa0a5626b730b3b72431204ce541392e9f7 Mon Sep 17 00:00:00 2001 From: Raashid Muhammed Date: Mon, 27 Mar 2017 12:35:00 +0530 -Subject: [PATCH 076/703] Add support for Allo Piano DAC 2.1 plus add-on board +Subject: [PATCH 076/725] Add support for Allo Piano DAC 2.1 plus add-on board for Raspberry Pi. The Piano DAC 2.1 has support for 4 channels with subwoofer. diff --git a/target/linux/brcm2708/patches-4.19/950-0077-Add-support-for-Allo-Boss-DAC-add-on-board-for-Raspb.patch b/target/linux/brcm2708/patches-4.19/950-0077-Add-support-for-Allo-Boss-DAC-add-on-board-for-Raspb.patch index 4dd0fbef2e..ba914949b3 100644 --- a/target/linux/brcm2708/patches-4.19/950-0077-Add-support-for-Allo-Boss-DAC-add-on-board-for-Raspb.patch +++ b/target/linux/brcm2708/patches-4.19/950-0077-Add-support-for-Allo-Boss-DAC-add-on-board-for-Raspb.patch @@ -1,7 +1,7 @@ -From f9b56b66913621c3ecba0a5379381fd1e33e1914 Mon Sep 17 00:00:00 2001 +From 337c790ae688ad33941262b852a1ab88c3a9960b Mon Sep 17 00:00:00 2001 From: BabuSubashChandar Date: Tue, 28 Mar 2017 20:04:42 +0530 -Subject: [PATCH 077/703] Add support for Allo Boss DAC add-on board for +Subject: [PATCH 077/725] Add support for Allo Boss DAC add-on board for Raspberry Pi. (#1924) Signed-off-by: Baswaraj K diff --git a/target/linux/brcm2708/patches-4.19/950-0078-Support-for-Blokas-Labs-pisound-board.patch b/target/linux/brcm2708/patches-4.19/950-0078-Support-for-Blokas-Labs-pisound-board.patch index 011c0d64ee..df7f0f9a9e 100644 --- a/target/linux/brcm2708/patches-4.19/950-0078-Support-for-Blokas-Labs-pisound-board.patch +++ b/target/linux/brcm2708/patches-4.19/950-0078-Support-for-Blokas-Labs-pisound-board.patch @@ -1,7 +1,7 @@ -From 1b7248a956f0322a9b39d13cdddf83a7c0524ae9 Mon Sep 17 00:00:00 2001 +From 225c4a483b34eb88cab2d617a961fef9cb5a876e Mon Sep 17 00:00:00 2001 From: gtrainavicius Date: Sun, 23 Oct 2016 12:06:53 +0300 -Subject: [PATCH 078/703] Support for Blokas Labs pisound board +Subject: [PATCH 078/725] Support for Blokas Labs pisound board Pisound dynamic overlay (#1760) diff --git a/target/linux/brcm2708/patches-4.19/950-0079-ASoC-Add-driver-for-Cirrus-Logic-Audio-Card.patch b/target/linux/brcm2708/patches-4.19/950-0079-ASoC-Add-driver-for-Cirrus-Logic-Audio-Card.patch index 3acbca823e..5b0160434c 100644 --- a/target/linux/brcm2708/patches-4.19/950-0079-ASoC-Add-driver-for-Cirrus-Logic-Audio-Card.patch +++ b/target/linux/brcm2708/patches-4.19/950-0079-ASoC-Add-driver-for-Cirrus-Logic-Audio-Card.patch @@ -1,7 +1,7 @@ -From 9dea6c4e76e3bace9cbc62fd452de72ce0362034 Mon Sep 17 00:00:00 2001 +From 8341fbb96fa8a6802b316530d00799e2eeaf2962 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 22 Jan 2017 12:49:37 +0100 -Subject: [PATCH 079/703] ASoC: Add driver for Cirrus Logic Audio Card +Subject: [PATCH 079/725] ASoC: Add driver for Cirrus Logic Audio Card Note: due to problems with deferred probing of regulators the following softdep should be added to a modprobe.d file diff --git a/target/linux/brcm2708/patches-4.19/950-0080-sound-Support-for-Dion-Audio-LOCO-V2-DAC-AMP-HAT.patch b/target/linux/brcm2708/patches-4.19/950-0080-sound-Support-for-Dion-Audio-LOCO-V2-DAC-AMP-HAT.patch index fe3e52d2c0..418788959a 100644 --- a/target/linux/brcm2708/patches-4.19/950-0080-sound-Support-for-Dion-Audio-LOCO-V2-DAC-AMP-HAT.patch +++ b/target/linux/brcm2708/patches-4.19/950-0080-sound-Support-for-Dion-Audio-LOCO-V2-DAC-AMP-HAT.patch @@ -1,7 +1,7 @@ -From 3e2070202a0607fe572f565ed4c18aa964fc18e5 Mon Sep 17 00:00:00 2001 +From 261e3e2577768d848277489e26759f3f37b25aae Mon Sep 17 00:00:00 2001 From: Miquel Date: Fri, 24 Feb 2017 20:51:06 +0100 -Subject: [PATCH 080/703] sound: Support for Dion Audio LOCO-V2 DAC-AMP HAT +Subject: [PATCH 080/725] sound: Support for Dion Audio LOCO-V2 DAC-AMP HAT Signed-off-by: Miquel Blauw diff --git a/target/linux/brcm2708/patches-4.19/950-0081-Add-support-for-Fe-Pi-audio-sound-card.-1867.patch b/target/linux/brcm2708/patches-4.19/950-0081-Add-support-for-Fe-Pi-audio-sound-card.-1867.patch index cafc88f321..354ac60475 100644 --- a/target/linux/brcm2708/patches-4.19/950-0081-Add-support-for-Fe-Pi-audio-sound-card.-1867.patch +++ b/target/linux/brcm2708/patches-4.19/950-0081-Add-support-for-Fe-Pi-audio-sound-card.-1867.patch @@ -1,7 +1,7 @@ -From 0719be99171119689b89d117141b65e849a49239 Mon Sep 17 00:00:00 2001 +From 132ffc095977fbd3e3b4099deaba2b80ed4d13ed Mon Sep 17 00:00:00 2001 From: Fe-Pi Date: Wed, 1 Mar 2017 04:42:43 -0700 -Subject: [PATCH 081/703] Add support for Fe-Pi audio sound card. (#1867) +Subject: [PATCH 081/725] 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. diff --git a/target/linux/brcm2708/patches-4.19/950-0082-Add-support-for-the-AudioInjector.net-Octo-sound-car.patch b/target/linux/brcm2708/patches-4.19/950-0082-Add-support-for-the-AudioInjector.net-Octo-sound-car.patch index 856d4c2829..5891c8bb41 100644 --- a/target/linux/brcm2708/patches-4.19/950-0082-Add-support-for-the-AudioInjector.net-Octo-sound-car.patch +++ b/target/linux/brcm2708/patches-4.19/950-0082-Add-support-for-the-AudioInjector.net-Octo-sound-car.patch @@ -1,7 +1,7 @@ -From e95def09872db37a8e577da0882a113f68476af4 Mon Sep 17 00:00:00 2001 +From 3c3d9b8ffa1f47da2225262dc2bac5decc043f6d Mon Sep 17 00:00:00 2001 From: Matt Flax Date: Wed, 8 Mar 2017 20:04:13 +1100 -Subject: [PATCH 082/703] Add support for the AudioInjector.net Octo sound card +Subject: [PATCH 082/725] Add support for the AudioInjector.net Octo sound card AudioInjector Octo: sample rates, regulators, reset diff --git a/target/linux/brcm2708/patches-4.19/950-0083-Driver-support-for-Google-voiceHAT-soundcard.patch b/target/linux/brcm2708/patches-4.19/950-0083-Driver-support-for-Google-voiceHAT-soundcard.patch index e52f02b7c1..f82151a73c 100644 --- a/target/linux/brcm2708/patches-4.19/950-0083-Driver-support-for-Google-voiceHAT-soundcard.patch +++ b/target/linux/brcm2708/patches-4.19/950-0083-Driver-support-for-Google-voiceHAT-soundcard.patch @@ -1,7 +1,7 @@ -From 7a03cd841be6b35ae99b7a4a1b415786df98da88 Mon Sep 17 00:00:00 2001 +From 18914c73280bbb74c77f7d5fef622e26ea4e4ffc Mon Sep 17 00:00:00 2001 From: Peter Malkin Date: Mon, 27 Mar 2017 16:38:21 -0700 -Subject: [PATCH 083/703] Driver support for Google voiceHAT soundcard. +Subject: [PATCH 083/725] Driver support for Google voiceHAT soundcard. ASoC: googlevoicehat-codec: Use correct device when grabbing GPIO diff --git a/target/linux/brcm2708/patches-4.19/950-0084-Driver-and-overlay-for-Allo-Katana-DAC.patch b/target/linux/brcm2708/patches-4.19/950-0084-Driver-and-overlay-for-Allo-Katana-DAC.patch index e5960dff5a..c4d14a4dee 100644 --- a/target/linux/brcm2708/patches-4.19/950-0084-Driver-and-overlay-for-Allo-Katana-DAC.patch +++ b/target/linux/brcm2708/patches-4.19/950-0084-Driver-and-overlay-for-Allo-Katana-DAC.patch @@ -1,7 +1,7 @@ -From b64cde33b275ddda0e024a218cd31456a54cdd09 Mon Sep 17 00:00:00 2001 +From 414559d38e5fb6fe74e8a54a2b9de22f6d238a05 Mon Sep 17 00:00:00 2001 From: allocom Date: Thu, 19 Apr 2018 12:12:26 +0530 -Subject: [PATCH 084/703] Driver and overlay for Allo Katana DAC +Subject: [PATCH 084/725] Driver and overlay for Allo Katana DAC Allo Katana DAC: Updated default values diff --git a/target/linux/brcm2708/patches-4.19/950-0085-ASoC-wm8804-MCLK-configuration-options-32-bit.patch b/target/linux/brcm2708/patches-4.19/950-0085-ASoC-wm8804-MCLK-configuration-options-32-bit.patch index 6d42b24dfa..e404606983 100644 --- a/target/linux/brcm2708/patches-4.19/950-0085-ASoC-wm8804-MCLK-configuration-options-32-bit.patch +++ b/target/linux/brcm2708/patches-4.19/950-0085-ASoC-wm8804-MCLK-configuration-options-32-bit.patch @@ -1,7 +1,7 @@ -From 567ae821d7e3e4bcca95ac69847f23e9b4929570 Mon Sep 17 00:00:00 2001 +From 0d0387de52b82694b9df90476e21e6828025d1e9 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Wed, 15 Jan 2014 21:41:23 +0100 -Subject: [PATCH 085/703] ASoC: wm8804: MCLK configuration options, 32-bit +Subject: [PATCH 085/725] ASoC: wm8804: MCLK configuration options, 32-bit WM8804 can run with PLL frequencies of 256xfs and 128xfs for most sample rates. At 192kHz only 128xfs is supported. The existing driver selects diff --git a/target/linux/brcm2708/patches-4.19/950-0086-ASoC-Add-generic-RPI-driver-for-simple-soundcards.patch b/target/linux/brcm2708/patches-4.19/950-0086-ASoC-Add-generic-RPI-driver-for-simple-soundcards.patch index ca5cd3d8bf..8d313c1e84 100644 --- a/target/linux/brcm2708/patches-4.19/950-0086-ASoC-Add-generic-RPI-driver-for-simple-soundcards.patch +++ b/target/linux/brcm2708/patches-4.19/950-0086-ASoC-Add-generic-RPI-driver-for-simple-soundcards.patch @@ -1,7 +1,7 @@ -From fb0eaa75f3a486dd0a5cb126c198db047a768a5d Mon Sep 17 00:00:00 2001 +From 49d8b4eebd733c26bdd95f44352c0344af5b4472 Mon Sep 17 00:00:00 2001 From: Tim Gover Date: Wed, 27 Jun 2018 15:59:12 +0100 -Subject: [PATCH 086/703] ASoC: Add generic RPI driver for simple soundcards. +Subject: [PATCH 086/725] ASoC: Add generic RPI driver for simple soundcards. The RPI simple sound card driver provides a generic ALSA SOC card driver supporting a variety of Pi HAT soundcards. The intention is to avoid diff --git a/target/linux/brcm2708/patches-4.19/950-0087-ASoC-Add-Kconfig-and-Makefile-for-sound-soc-bcm.patch b/target/linux/brcm2708/patches-4.19/950-0087-ASoC-Add-Kconfig-and-Makefile-for-sound-soc-bcm.patch index 3a2c35c862..de2408b3c5 100644 --- a/target/linux/brcm2708/patches-4.19/950-0087-ASoC-Add-Kconfig-and-Makefile-for-sound-soc-bcm.patch +++ b/target/linux/brcm2708/patches-4.19/950-0087-ASoC-Add-Kconfig-and-Makefile-for-sound-soc-bcm.patch @@ -1,7 +1,7 @@ -From c95f1fca6bf35548cddf4909a505a6427f6f41ef Mon Sep 17 00:00:00 2001 +From 3f31d54804aebb748f200841dafdc8ff1f05b7a7 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 3 Sep 2018 17:00:36 +0100 -Subject: [PATCH 087/703] ASoC: Add Kconfig and Makefile for sound/soc/bcm +Subject: [PATCH 087/725] ASoC: Add Kconfig and Makefile for sound/soc/bcm Signed-off-by: popcornmix --- diff --git a/target/linux/brcm2708/patches-4.19/950-0088-ASoC-Create-a-generic-Pi-Hat-WM8804-driver.patch b/target/linux/brcm2708/patches-4.19/950-0088-ASoC-Create-a-generic-Pi-Hat-WM8804-driver.patch index d6d1aec81a..214ab01621 100644 --- a/target/linux/brcm2708/patches-4.19/950-0088-ASoC-Create-a-generic-Pi-Hat-WM8804-driver.patch +++ b/target/linux/brcm2708/patches-4.19/950-0088-ASoC-Create-a-generic-Pi-Hat-WM8804-driver.patch @@ -1,7 +1,7 @@ -From 1fb18379184ab1c039cc7b366901f3816f2ab768 Mon Sep 17 00:00:00 2001 +From 5b797e80e454e59af7381b579305cc25f70871d8 Mon Sep 17 00:00:00 2001 From: Tim Gover Date: Sat, 21 Jul 2018 20:07:46 +0100 -Subject: [PATCH 088/703] ASoC: Create a generic Pi Hat WM8804 driver +Subject: [PATCH 088/725] ASoC: Create a generic Pi Hat WM8804 driver Reduce the amount of duplicated code by creating a generic driver for Pi Hat digi cards using the WM8804 codec. diff --git a/target/linux/brcm2708/patches-4.19/950-0089-rpi_display-add-backlight-driver-and-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0089-rpi_display-add-backlight-driver-and-overlay.patch index 6be6b585a4..5010606d97 100644 --- a/target/linux/brcm2708/patches-4.19/950-0089-rpi_display-add-backlight-driver-and-overlay.patch +++ b/target/linux/brcm2708/patches-4.19/950-0089-rpi_display-add-backlight-driver-and-overlay.patch @@ -1,7 +1,7 @@ -From 7a0c9202a0bd363d49ba0b4a31d843f3a2cac66d Mon Sep 17 00:00:00 2001 +From a9adc2921cd7b460c25c4149374c7e94675d04fc Mon Sep 17 00:00:00 2001 From: P33M Date: Wed, 21 Oct 2015 14:55:21 +0100 -Subject: [PATCH 089/703] rpi_display: add backlight driver and overlay +Subject: [PATCH 089/725] rpi_display: add backlight driver and overlay Add a mailbox-driven backlight controller for the Raspberry Pi DSI touchscreen display. Requires updated GPU firmware to recognise the diff --git a/target/linux/brcm2708/patches-4.19/950-0090-bcm2835-virtgpio-Virtual-GPIO-driver.patch b/target/linux/brcm2708/patches-4.19/950-0090-bcm2835-virtgpio-Virtual-GPIO-driver.patch index 8aee6c7840..1f3ac16775 100644 --- a/target/linux/brcm2708/patches-4.19/950-0090-bcm2835-virtgpio-Virtual-GPIO-driver.patch +++ b/target/linux/brcm2708/patches-4.19/950-0090-bcm2835-virtgpio-Virtual-GPIO-driver.patch @@ -1,7 +1,7 @@ -From ae7c0b0955e96a7231ad4b6d909124fa7f7713e8 Mon Sep 17 00:00:00 2001 +From 2839c328b46a97314f6f9cfb5cd0c1be9bc174f3 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 23 Feb 2016 19:56:04 +0000 -Subject: [PATCH 090/703] bcm2835-virtgpio: Virtual GPIO driver +Subject: [PATCH 090/725] bcm2835-virtgpio: Virtual GPIO driver Add a virtual GPIO driver that uses the firmware mailbox interface to request that the VPU toggles LEDs. diff --git a/target/linux/brcm2708/patches-4.19/950-0091-net-Add-non-mainline-source-for-rtl8192cu-wlan.patch b/target/linux/brcm2708/patches-4.19/950-0091-net-Add-non-mainline-source-for-rtl8192cu-wlan.patch index 25703d6288..d5a3fb6c7a 100644 --- a/target/linux/brcm2708/patches-4.19/950-0091-net-Add-non-mainline-source-for-rtl8192cu-wlan.patch +++ b/target/linux/brcm2708/patches-4.19/950-0091-net-Add-non-mainline-source-for-rtl8192cu-wlan.patch @@ -1,7 +1,7 @@ -From 004fa06eecc1162dcb717bdce943a08c25c0922c Mon Sep 17 00:00:00 2001 +From de205caf53ef335d29f3d68f18f7bf996d1e0728 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 3 Sep 2012 17:10:23 +0100 -Subject: [PATCH 091/703] net: Add non-mainline source for rtl8192cu wlan +Subject: [PATCH 091/725] net: Add non-mainline source for rtl8192cu wlan We are now syncing with version from: https://github.com/pvaret/rtl8192cu-fixes diff --git a/target/linux/brcm2708/patches-4.19/950-0092-OF-DT-Overlay-configfs-interface.patch b/target/linux/brcm2708/patches-4.19/950-0092-OF-DT-Overlay-configfs-interface.patch index fcde0daa8c..34d44ecd8a 100644 --- a/target/linux/brcm2708/patches-4.19/950-0092-OF-DT-Overlay-configfs-interface.patch +++ b/target/linux/brcm2708/patches-4.19/950-0092-OF-DT-Overlay-configfs-interface.patch @@ -1,7 +1,7 @@ -From 1889a5e0d20a7f58b95cb41c682bf1a09a37d4f6 Mon Sep 17 00:00:00 2001 +From 40d6d85f902e7de4721db52394da172d3d5f2724 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Wed, 3 Dec 2014 13:23:28 +0200 -Subject: [PATCH 092/703] OF: DT-Overlay configfs interface +Subject: [PATCH 092/725] OF: DT-Overlay configfs interface This is a port of Pantelis Antoniou's v3 port that makes use of the new upstreamed configfs support for binary attributes. diff --git a/target/linux/brcm2708/patches-4.19/950-0093-brcm-adds-support-for-BCM43341-wifi.patch b/target/linux/brcm2708/patches-4.19/950-0093-brcm-adds-support-for-BCM43341-wifi.patch index 6efde5f1f8..783ddfd13e 100644 --- a/target/linux/brcm2708/patches-4.19/950-0093-brcm-adds-support-for-BCM43341-wifi.patch +++ b/target/linux/brcm2708/patches-4.19/950-0093-brcm-adds-support-for-BCM43341-wifi.patch @@ -1,7 +1,7 @@ -From fe1028f8aa31decab2a006c977598bd75eb42b40 Mon Sep 17 00:00:00 2001 +From 7f688c61d8a1f881e58ae32af51506141a64b1e2 Mon Sep 17 00:00:00 2001 From: Cheong2K Date: Fri, 26 Feb 2016 18:20:10 +0800 -Subject: [PATCH 093/703] brcm: adds support for BCM43341 wifi +Subject: [PATCH 093/725] brcm: adds support for BCM43341 wifi brcmfmac: Disable power management diff --git a/target/linux/brcm2708/patches-4.19/950-0094-brcmfmac-Mute-expected-startup-errors.patch b/target/linux/brcm2708/patches-4.19/950-0094-brcmfmac-Mute-expected-startup-errors.patch index f92381ef8e..41a795edaa 100644 --- a/target/linux/brcm2708/patches-4.19/950-0094-brcmfmac-Mute-expected-startup-errors.patch +++ b/target/linux/brcm2708/patches-4.19/950-0094-brcmfmac-Mute-expected-startup-errors.patch @@ -1,7 +1,7 @@ -From 06ec5a8827bec5fc4b7f2b322088c47963a782e4 Mon Sep 17 00:00:00 2001 +From 99150b44461c1b5a988297cab7f0188a291afec9 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 17 Feb 2017 15:26:13 +0000 -Subject: [PATCH 094/703] brcmfmac: Mute expected startup 'errors' +Subject: [PATCH 094/725] brcmfmac: Mute expected startup 'errors' The brcmfmac WiFi driver always complains about the '00' country code. Modify the driver to ignore '00' silently. diff --git a/target/linux/brcm2708/patches-4.19/950-0095-hci_h5-Don-t-send-conf_req-when-ACTIVE.patch b/target/linux/brcm2708/patches-4.19/950-0095-hci_h5-Don-t-send-conf_req-when-ACTIVE.patch index e222700bce..183b192d4c 100644 --- a/target/linux/brcm2708/patches-4.19/950-0095-hci_h5-Don-t-send-conf_req-when-ACTIVE.patch +++ b/target/linux/brcm2708/patches-4.19/950-0095-hci_h5-Don-t-send-conf_req-when-ACTIVE.patch @@ -1,7 +1,7 @@ -From 04398740be915fbbbc794b3b34aa36d11a85a0ab Mon Sep 17 00:00:00 2001 +From bddfcc074a6f46d2d107d5c6b06c5b6c906bbe19 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 17 Dec 2015 13:37:07 +0000 -Subject: [PATCH 095/703] hci_h5: Don't send conf_req when ACTIVE +Subject: [PATCH 095/725] hci_h5: Don't send conf_req when ACTIVE Without this patch, a modem and kernel can continuously bombard each other with conf_req and conf_rsp messages, in a demented game of tag. diff --git a/target/linux/brcm2708/patches-4.19/950-0096-config-Add-default-configs.patch b/target/linux/brcm2708/patches-4.19/950-0096-config-Add-default-configs.patch index 25f25ee7e7..b3f87abd27 100644 --- a/target/linux/brcm2708/patches-4.19/950-0096-config-Add-default-configs.patch +++ b/target/linux/brcm2708/patches-4.19/950-0096-config-Add-default-configs.patch @@ -1,7 +1,7 @@ -From 0c0a0d6d576db08b15281aa7263ebb4f26344d9f Mon Sep 17 00:00:00 2001 +From 97cc0418de0e851cf4a850a99878f8ddf31f8a64 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 13 Apr 2015 17:16:29 +0100 -Subject: [PATCH 096/703] config: Add default configs +Subject: [PATCH 096/725] config: Add default configs --- arch/arm/configs/bcm2709_defconfig | 1360 ++++++++++++++++++++++++++++ diff --git a/target/linux/brcm2708/patches-4.19/950-0097-Add-arm64-configuration-and-device-tree-differences..patch b/target/linux/brcm2708/patches-4.19/950-0097-Add-arm64-configuration-and-device-tree-differences..patch index 4ece04a21f..84ff6bf469 100644 --- a/target/linux/brcm2708/patches-4.19/950-0097-Add-arm64-configuration-and-device-tree-differences..patch +++ b/target/linux/brcm2708/patches-4.19/950-0097-Add-arm64-configuration-and-device-tree-differences..patch @@ -1,7 +1,7 @@ -From 8a3aa5b6a470f7c89025e51d5fc2f2827e8efc00 Mon Sep 17 00:00:00 2001 +From 974e489f199d585ebe57440969ab9661ce2156c9 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Wed, 24 Aug 2016 03:35:56 -0700 -Subject: [PATCH 097/703] Add arm64 configuration and device tree differences. +Subject: [PATCH 097/725] Add arm64 configuration and device tree differences. Disable MMC_BCM2835_SDHOST and MMC_BCM2835 since these drivers are crashing at the moment. diff --git a/target/linux/brcm2708/patches-4.19/950-0098-ARM64-DWC_OTG-Port-dwc_otg-driver-to-ARM64.patch b/target/linux/brcm2708/patches-4.19/950-0098-ARM64-DWC_OTG-Port-dwc_otg-driver-to-ARM64.patch index 054fa69306..aaf1172c15 100644 --- a/target/linux/brcm2708/patches-4.19/950-0098-ARM64-DWC_OTG-Port-dwc_otg-driver-to-ARM64.patch +++ b/target/linux/brcm2708/patches-4.19/950-0098-ARM64-DWC_OTG-Port-dwc_otg-driver-to-ARM64.patch @@ -1,7 +1,7 @@ -From 3d6c0c835d5e1b2983a0e4dec0dc779cd67db922 Mon Sep 17 00:00:00 2001 +From e65d132bca6b87ae1606ef156581f1de76b80962 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Sat, 14 Jan 2017 21:33:51 -0800 -Subject: [PATCH 098/703] ARM64/DWC_OTG: Port dwc_otg driver to ARM64 +Subject: [PATCH 098/725] ARM64/DWC_OTG: Port dwc_otg driver to ARM64 In ARM64, the FIQ mechanism used by this driver is not current implemented. As a workaround, reqular IRQ is used instead diff --git a/target/linux/brcm2708/patches-4.19/950-0099-ARM64-Round-Robin-dispatch-IRQs-between-CPUs.patch b/target/linux/brcm2708/patches-4.19/950-0099-ARM64-Round-Robin-dispatch-IRQs-between-CPUs.patch index 74e670c768..00fa90a003 100644 --- a/target/linux/brcm2708/patches-4.19/950-0099-ARM64-Round-Robin-dispatch-IRQs-between-CPUs.patch +++ b/target/linux/brcm2708/patches-4.19/950-0099-ARM64-Round-Robin-dispatch-IRQs-between-CPUs.patch @@ -1,7 +1,7 @@ -From 67ba0d1572d1ca3874cbe8ebd57f5141178eb55c Mon Sep 17 00:00:00 2001 +From 6b47138814b0e244c65c9d06d08fa9aca67b7904 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Sat, 14 Jan 2017 21:43:57 -0800 -Subject: [PATCH 099/703] ARM64: Round-Robin dispatch IRQs between CPUs. +Subject: [PATCH 099/725] ARM64: Round-Robin dispatch IRQs between CPUs. IRQ-CPU mapping is round robined on ARM64 to increase concurrency and allow multiple interrupts to be serviced diff --git a/target/linux/brcm2708/patches-4.19/950-0100-ARM64-Force-hardware-emulation-of-deprecated-instruc.patch b/target/linux/brcm2708/patches-4.19/950-0100-ARM64-Force-hardware-emulation-of-deprecated-instruc.patch index b8d7838853..53ed33b1e6 100644 --- a/target/linux/brcm2708/patches-4.19/950-0100-ARM64-Force-hardware-emulation-of-deprecated-instruc.patch +++ b/target/linux/brcm2708/patches-4.19/950-0100-ARM64-Force-hardware-emulation-of-deprecated-instruc.patch @@ -1,7 +1,7 @@ -From 303b20724f8691db1c6b575f127d47d5953359f2 Mon Sep 17 00:00:00 2001 +From 89c5a60b701b67a5bb3458fbe99a45da1d718e47 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Sat, 11 Feb 2017 01:18:31 -0800 -Subject: [PATCH 100/703] ARM64: Force hardware emulation of deprecated +Subject: [PATCH 100/725] ARM64: Force hardware emulation of deprecated instructions. --- diff --git a/target/linux/brcm2708/patches-4.19/950-0101-build-arm64-Add-rules-for-.dtbo-files-for-dts-overla.patch b/target/linux/brcm2708/patches-4.19/950-0101-build-arm64-Add-rules-for-.dtbo-files-for-dts-overla.patch index 12304c50c5..e9281288db 100644 --- a/target/linux/brcm2708/patches-4.19/950-0101-build-arm64-Add-rules-for-.dtbo-files-for-dts-overla.patch +++ b/target/linux/brcm2708/patches-4.19/950-0101-build-arm64-Add-rules-for-.dtbo-files-for-dts-overla.patch @@ -1,7 +1,7 @@ -From ab40577b4601c0eeeedb5c3688cf0719b2bc582e Mon Sep 17 00:00:00 2001 +From 0a1ea6126555abaf874f76c7d0c45f8d34b9c7a4 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Fri, 10 Feb 2017 17:57:08 -0800 -Subject: [PATCH 101/703] build/arm64: Add rules for .dtbo files for dts +Subject: [PATCH 101/725] build/arm64: Add rules for .dtbo files for dts overlays We now create overlays as .dtbo files. diff --git a/target/linux/brcm2708/patches-4.19/950-0102-cache-export-clean-and-invalidate.patch b/target/linux/brcm2708/patches-4.19/950-0102-cache-export-clean-and-invalidate.patch index 81d0d49093..cd6f745297 100644 --- a/target/linux/brcm2708/patches-4.19/950-0102-cache-export-clean-and-invalidate.patch +++ b/target/linux/brcm2708/patches-4.19/950-0102-cache-export-clean-and-invalidate.patch @@ -1,7 +1,7 @@ -From e8cf1886f2434ec0e5a672d9b94a96f7fea80789 Mon Sep 17 00:00:00 2001 +From 007008145da2e877e32090a4861440f56bc40080 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 25 Aug 2017 19:18:13 +0100 -Subject: [PATCH 102/703] cache: export clean and invalidate +Subject: [PATCH 102/725] cache: export clean and invalidate --- arch/arm/mm/cache-v6.S | 4 ++-- diff --git a/target/linux/brcm2708/patches-4.19/950-0103-AXI-performance-monitor-driver-2222.patch b/target/linux/brcm2708/patches-4.19/950-0103-AXI-performance-monitor-driver-2222.patch index 0fb4a67eda..f3822001a9 100644 --- a/target/linux/brcm2708/patches-4.19/950-0103-AXI-performance-monitor-driver-2222.patch +++ b/target/linux/brcm2708/patches-4.19/950-0103-AXI-performance-monitor-driver-2222.patch @@ -1,7 +1,7 @@ -From 93664cd3cee57e93c1d354c3263773a6b832db22 Mon Sep 17 00:00:00 2001 +From a7a7bff51039648f4d09d690bb037d02b26e593c Mon Sep 17 00:00:00 2001 From: James Hughes Date: Tue, 14 Nov 2017 15:13:15 +0000 -Subject: [PATCH 103/703] AXI performance monitor driver (#2222) +Subject: [PATCH 103/725] AXI performance monitor driver (#2222) Uses the debugfs I/F to provide access to the AXI bus performance monitors. diff --git a/target/linux/brcm2708/patches-4.19/950-0104-mcp2515-Use-DT-supplied-interrupt-flags.patch b/target/linux/brcm2708/patches-4.19/950-0104-mcp2515-Use-DT-supplied-interrupt-flags.patch index 51add31636..7b42b3f57c 100644 --- a/target/linux/brcm2708/patches-4.19/950-0104-mcp2515-Use-DT-supplied-interrupt-flags.patch +++ b/target/linux/brcm2708/patches-4.19/950-0104-mcp2515-Use-DT-supplied-interrupt-flags.patch @@ -1,7 +1,7 @@ -From a3ba7e3519d3dce17a0224b552fb88b7728f7061 Mon Sep 17 00:00:00 2001 +From 8ad27448ac0130fe78dbe1eaa1ce2d640669fb05 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 14 Nov 2017 11:03:22 +0000 -Subject: [PATCH 104/703] mcp2515: Use DT-supplied interrupt flags +Subject: [PATCH 104/725] mcp2515: Use DT-supplied interrupt flags The MCP2515 datasheet clearly describes a level-triggered interrupt pin. Therefore the receiving interrupt controller must also be diff --git a/target/linux/brcm2708/patches-4.19/950-0105-Tidy-up-of-the-ft5406-driver-to-use-DT-2189.patch b/target/linux/brcm2708/patches-4.19/950-0105-Tidy-up-of-the-ft5406-driver-to-use-DT-2189.patch index 45ed143c80..0908f0b7a1 100644 --- a/target/linux/brcm2708/patches-4.19/950-0105-Tidy-up-of-the-ft5406-driver-to-use-DT-2189.patch +++ b/target/linux/brcm2708/patches-4.19/950-0105-Tidy-up-of-the-ft5406-driver-to-use-DT-2189.patch @@ -1,7 +1,7 @@ -From c391ccaadd8928a79986e67ebc23cd6670b83d85 Mon Sep 17 00:00:00 2001 +From 4d326f3b4817e2a29d4ae69239c1ec2ef4a321a1 Mon Sep 17 00:00:00 2001 From: James Hughes Date: Thu, 16 Nov 2017 15:56:17 +0000 -Subject: [PATCH 105/703] Tidy up of the ft5406 driver to use DT (#2189) +Subject: [PATCH 105/725] Tidy up of the ft5406 driver to use DT (#2189) Driver was using a fixed resolution, this commit adds touchscreen size, and coordinate flip and swap diff --git a/target/linux/brcm2708/patches-4.19/950-0106-cgroup-Disable-cgroup-memory-by-default.patch b/target/linux/brcm2708/patches-4.19/950-0106-cgroup-Disable-cgroup-memory-by-default.patch index 6bb72a24f8..40d8ec044d 100644 --- a/target/linux/brcm2708/patches-4.19/950-0106-cgroup-Disable-cgroup-memory-by-default.patch +++ b/target/linux/brcm2708/patches-4.19/950-0106-cgroup-Disable-cgroup-memory-by-default.patch @@ -1,7 +1,7 @@ -From db9b15f3d930b045998c276c68f32645f7bade9f Mon Sep 17 00:00:00 2001 +From 15dc7e960b0de2d10a312e2be3ed6674f440cf61 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 27 Nov 2017 17:14:54 +0000 -Subject: [PATCH 106/703] cgroup: Disable cgroup "memory" by default +Subject: [PATCH 106/725] cgroup: Disable cgroup "memory" by default Some Raspberry Pis have limited RAM and most users won't use the cgroup memory support so it is disabled by default. Enable with: diff --git a/target/linux/brcm2708/patches-4.19/950-0107-ARM-bcm2835-Set-Serial-number-and-Revision.patch b/target/linux/brcm2708/patches-4.19/950-0107-ARM-bcm2835-Set-Serial-number-and-Revision.patch index 0593d7a9af..30a0ac0c21 100644 --- a/target/linux/brcm2708/patches-4.19/950-0107-ARM-bcm2835-Set-Serial-number-and-Revision.patch +++ b/target/linux/brcm2708/patches-4.19/950-0107-ARM-bcm2835-Set-Serial-number-and-Revision.patch @@ -1,7 +1,7 @@ -From 6ddffcf9c288513943680b958307b3bb267ea939 Mon Sep 17 00:00:00 2001 +From 5f4a7f6cabf2f7fdd75f8dba64394ed3f5c96d09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Wed, 3 Jun 2015 12:26:13 +0200 -Subject: [PATCH 107/703] ARM: bcm2835: Set Serial number and Revision +Subject: [PATCH 107/725] ARM: bcm2835: Set Serial number and Revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/target/linux/brcm2708/patches-4.19/950-0108-ARM-Activate-FIQs-to-avoid-__irq_startup-warnings.patch b/target/linux/brcm2708/patches-4.19/950-0108-ARM-Activate-FIQs-to-avoid-__irq_startup-warnings.patch index cedc6bdf35..11e5cbbff3 100644 --- a/target/linux/brcm2708/patches-4.19/950-0108-ARM-Activate-FIQs-to-avoid-__irq_startup-warnings.patch +++ b/target/linux/brcm2708/patches-4.19/950-0108-ARM-Activate-FIQs-to-avoid-__irq_startup-warnings.patch @@ -1,7 +1,7 @@ -From 84ae50c70c296998d39b819d1d5f3e2e4a355098 Mon Sep 17 00:00:00 2001 +From 83846923572c7b606ba85dfe613e38236e8bd695 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 11 Dec 2017 09:18:32 +0000 -Subject: [PATCH 108/703] ARM: Activate FIQs to avoid __irq_startup warnings +Subject: [PATCH 108/725] ARM: Activate FIQs to avoid __irq_startup warnings There is a new test in __irq_startup that the IRQ is activated, which hasn't been the case for FIQs since they bypass some of the usual setup. diff --git a/target/linux/brcm2708/patches-4.19/950-0109-serial-8250-bcm2835aux-suppress-EPROBE_DEFER.patch b/target/linux/brcm2708/patches-4.19/950-0109-serial-8250-bcm2835aux-suppress-EPROBE_DEFER.patch index b3102c2ff7..c75d68b976 100644 --- a/target/linux/brcm2708/patches-4.19/950-0109-serial-8250-bcm2835aux-suppress-EPROBE_DEFER.patch +++ b/target/linux/brcm2708/patches-4.19/950-0109-serial-8250-bcm2835aux-suppress-EPROBE_DEFER.patch @@ -1,7 +1,7 @@ -From 2f7074d8ae9b0867535fcfc56b4332073aee07f7 Mon Sep 17 00:00:00 2001 +From 3d00548e917e42a5d9da031c8dab8a52ff3cd1cc Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 22 Jan 2018 17:26:38 +0000 -Subject: [PATCH 109/703] serial: 8250: bcm2835aux - suppress EPROBE_DEFER +Subject: [PATCH 109/725] serial: 8250: bcm2835aux - suppress EPROBE_DEFER Signed-off-by: Phil Elwell --- diff --git a/target/linux/brcm2708/patches-4.19/950-0110-raspberrypi-firmware-Export-the-general-transaction-.patch b/target/linux/brcm2708/patches-4.19/950-0110-raspberrypi-firmware-Export-the-general-transaction-.patch index 70ec90da63..594d860c88 100644 --- a/target/linux/brcm2708/patches-4.19/950-0110-raspberrypi-firmware-Export-the-general-transaction-.patch +++ b/target/linux/brcm2708/patches-4.19/950-0110-raspberrypi-firmware-Export-the-general-transaction-.patch @@ -1,7 +1,7 @@ -From 48ce2d8a89c63f31a63b636b119a98c3ddbc66e1 Mon Sep 17 00:00:00 2001 +From 46828eb52e1d51dafb26f9073bd2b36dcf18596b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 14 Sep 2016 09:16:19 +0100 -Subject: [PATCH 110/703] raspberrypi-firmware: Export the general transaction +Subject: [PATCH 110/725] raspberrypi-firmware: Export the general transaction function. The vc4-firmware-kms module is going to be doing the MBOX FB call. diff --git a/target/linux/brcm2708/patches-4.19/950-0111-drm-vc4-Add-a-mode-for-using-the-closed-firmware-for.patch b/target/linux/brcm2708/patches-4.19/950-0111-drm-vc4-Add-a-mode-for-using-the-closed-firmware-for.patch index 270864f4d4..c439df5966 100644 --- a/target/linux/brcm2708/patches-4.19/950-0111-drm-vc4-Add-a-mode-for-using-the-closed-firmware-for.patch +++ b/target/linux/brcm2708/patches-4.19/950-0111-drm-vc4-Add-a-mode-for-using-the-closed-firmware-for.patch @@ -1,7 +1,7 @@ -From cf4d9b0e5f081408edf3340b3f46171f5b56dbff Mon Sep 17 00:00:00 2001 +From c8ae9b8e203f05c0a87f2576a58dbc6c747527c4 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 14 Sep 2016 08:39:33 +0100 -Subject: [PATCH 111/703] drm/vc4: Add a mode for using the closed firmware for +Subject: [PATCH 111/725] drm/vc4: Add a mode for using the closed firmware for display. Signed-off-by: Eric Anholt diff --git a/target/linux/brcm2708/patches-4.19/950-0112-drm-vc4-Name-the-primary-and-cursor-planes-in-fkms.patch b/target/linux/brcm2708/patches-4.19/950-0112-drm-vc4-Name-the-primary-and-cursor-planes-in-fkms.patch index ad596fc5ee..81fe0ad4d0 100644 --- a/target/linux/brcm2708/patches-4.19/950-0112-drm-vc4-Name-the-primary-and-cursor-planes-in-fkms.patch +++ b/target/linux/brcm2708/patches-4.19/950-0112-drm-vc4-Name-the-primary-and-cursor-planes-in-fkms.patch @@ -1,7 +1,7 @@ -From 9d538f69eca5ed335235fe89ba56966fdf07334d Mon Sep 17 00:00:00 2001 +From f42394aee8bcd3b7159029a4b9c66fcf35b16ba8 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 1 Feb 2017 17:09:18 -0800 -Subject: [PATCH 112/703] drm/vc4: Name the primary and cursor planes in fkms. +Subject: [PATCH 112/725] drm/vc4: Name the primary and cursor planes in fkms. This makes debugging nicer, compared to trying to remember what the IDs are. diff --git a/target/linux/brcm2708/patches-4.19/950-0113-drm-vc4-Add-DRM_DEBUG_ATOMIC-for-the-insides-of-fkms.patch b/target/linux/brcm2708/patches-4.19/950-0113-drm-vc4-Add-DRM_DEBUG_ATOMIC-for-the-insides-of-fkms.patch index c45a21a086..380414d034 100644 --- a/target/linux/brcm2708/patches-4.19/950-0113-drm-vc4-Add-DRM_DEBUG_ATOMIC-for-the-insides-of-fkms.patch +++ b/target/linux/brcm2708/patches-4.19/950-0113-drm-vc4-Add-DRM_DEBUG_ATOMIC-for-the-insides-of-fkms.patch @@ -1,7 +1,7 @@ -From 94f9a45df23146c709d7a08191e97ee31d6dd8e9 Mon Sep 17 00:00:00 2001 +From a54d059398df5799cc17789f11d40817f2cca3ed Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 1 Feb 2017 17:10:09 -0800 -Subject: [PATCH 113/703] drm/vc4: Add DRM_DEBUG_ATOMIC for the insides of +Subject: [PATCH 113/725] drm/vc4: Add DRM_DEBUG_ATOMIC for the insides of fkms. Trying to debug weston on fkms involved figuring out what calls I was diff --git a/target/linux/brcm2708/patches-4.19/950-0114-drm-vc4-Fix-sending-of-page-flip-completion-events-i.patch b/target/linux/brcm2708/patches-4.19/950-0114-drm-vc4-Fix-sending-of-page-flip-completion-events-i.patch index 50fcf11f08..7f9236974c 100644 --- a/target/linux/brcm2708/patches-4.19/950-0114-drm-vc4-Fix-sending-of-page-flip-completion-events-i.patch +++ b/target/linux/brcm2708/patches-4.19/950-0114-drm-vc4-Fix-sending-of-page-flip-completion-events-i.patch @@ -1,7 +1,7 @@ -From 96cfb9903f60e98d964c3547ac0cf5b920083c04 Mon Sep 17 00:00:00 2001 +From d36cddb19f380051aae81cc384fce9b49625798f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 2 Feb 2017 09:42:18 -0800 -Subject: [PATCH 114/703] drm/vc4: Fix sending of page flip completion events +Subject: [PATCH 114/725] 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 diff --git a/target/linux/brcm2708/patches-4.19/950-0115-drm-vc4-Add-support-for-setting-DPMS-in-firmwarekms.patch b/target/linux/brcm2708/patches-4.19/950-0115-drm-vc4-Add-support-for-setting-DPMS-in-firmwarekms.patch index b2e8a8d736..6dc1578836 100644 --- a/target/linux/brcm2708/patches-4.19/950-0115-drm-vc4-Add-support-for-setting-DPMS-in-firmwarekms.patch +++ b/target/linux/brcm2708/patches-4.19/950-0115-drm-vc4-Add-support-for-setting-DPMS-in-firmwarekms.patch @@ -1,7 +1,7 @@ -From 9f05f9c3a564cedbb3c5f3dd0d5b95f247b63c71 Mon Sep 17 00:00:00 2001 +From dbf8328dec97e1df1a61ca75e98b8b60e4e2e68e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 6 Jul 2017 11:45:48 -0700 -Subject: [PATCH 115/703] drm/vc4: Add support for setting DPMS in firmwarekms. +Subject: [PATCH 115/725] drm/vc4: Add support for setting DPMS in firmwarekms. This ensures that the screen goes blank during DPMS (screensaver), including the cursor. Planes don't necessarily get disabled during diff --git a/target/linux/brcm2708/patches-4.19/950-0116-drm-vc4-Add-FB-modifier-support-to-firmwarekms.patch b/target/linux/brcm2708/patches-4.19/950-0116-drm-vc4-Add-FB-modifier-support-to-firmwarekms.patch index 28845940ba..7a29e97111 100644 --- a/target/linux/brcm2708/patches-4.19/950-0116-drm-vc4-Add-FB-modifier-support-to-firmwarekms.patch +++ b/target/linux/brcm2708/patches-4.19/950-0116-drm-vc4-Add-FB-modifier-support-to-firmwarekms.patch @@ -1,7 +1,7 @@ -From ac5599d66654d69497945cb29e183824d9988e29 Mon Sep 17 00:00:00 2001 +From ba6bffb620f0f25868ed7d84add448f771201947 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 7 Jun 2017 14:39:49 -0700 -Subject: [PATCH 116/703] drm/vc4: Add FB modifier support to firmwarekms. +Subject: [PATCH 116/725] drm/vc4: Add FB modifier support to firmwarekms. Signed-off-by: Eric Anholt (cherry picked from commit 11752d73488e08aaeb65fe8289a9c016acde26c2) diff --git a/target/linux/brcm2708/patches-4.19/950-0117-drm-vc4-Add-missing-enable-disable-vblank-handlers-i.patch b/target/linux/brcm2708/patches-4.19/950-0117-drm-vc4-Add-missing-enable-disable-vblank-handlers-i.patch index a2bd180659..8d9ab4f648 100644 --- a/target/linux/brcm2708/patches-4.19/950-0117-drm-vc4-Add-missing-enable-disable-vblank-handlers-i.patch +++ b/target/linux/brcm2708/patches-4.19/950-0117-drm-vc4-Add-missing-enable-disable-vblank-handlers-i.patch @@ -1,7 +1,7 @@ -From 7815410d46ef8c5462eadbeff59d8c7e43639b03 Mon Sep 17 00:00:00 2001 +From 46652925942d2947afabc11abfdfb5d42d1559d5 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 30 Jan 2018 14:21:02 -0800 -Subject: [PATCH 117/703] drm/vc4: Add missing enable/disable vblank handlers +Subject: [PATCH 117/725] drm/vc4: Add missing enable/disable vblank handlers in fkms. Fixes hang at boot in 4.14. diff --git a/target/linux/brcm2708/patches-4.19/950-0118-vc4_fkms-Apply-firmware-overscan-offset-to-hardware-.patch b/target/linux/brcm2708/patches-4.19/950-0118-vc4_fkms-Apply-firmware-overscan-offset-to-hardware-.patch index 7907d026ec..9873a14163 100644 --- a/target/linux/brcm2708/patches-4.19/950-0118-vc4_fkms-Apply-firmware-overscan-offset-to-hardware-.patch +++ b/target/linux/brcm2708/patches-4.19/950-0118-vc4_fkms-Apply-firmware-overscan-offset-to-hardware-.patch @@ -1,7 +1,7 @@ -From 7c7cf2b1b7ea7189b18eb042e6a04ca90e07e658 Mon Sep 17 00:00:00 2001 +From e1ce159091e4bc8ce78ed9838d5935534dc40dbe Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 18 Apr 2017 21:43:46 +0100 -Subject: [PATCH 118/703] vc4_fkms: Apply firmware overscan offset to hardware +Subject: [PATCH 118/725] vc4_fkms: Apply firmware overscan offset to hardware cursor --- diff --git a/target/linux/brcm2708/patches-4.19/950-0119-drm-vc4-Fix-warning-about-vblank-interrupts-before-D.patch b/target/linux/brcm2708/patches-4.19/950-0119-drm-vc4-Fix-warning-about-vblank-interrupts-before-D.patch index ec50f3baea..6d09fa2313 100644 --- a/target/linux/brcm2708/patches-4.19/950-0119-drm-vc4-Fix-warning-about-vblank-interrupts-before-D.patch +++ b/target/linux/brcm2708/patches-4.19/950-0119-drm-vc4-Fix-warning-about-vblank-interrupts-before-D.patch @@ -1,7 +1,7 @@ -From b69ecf0b7259675e57be13836713946f1329f20c Mon Sep 17 00:00:00 2001 +From fd2b049cb8beed1b80e9f314e55116db2d960eef Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 5 Feb 2018 18:01:02 +0000 -Subject: [PATCH 119/703] drm/vc4: Fix warning about vblank interrupts before +Subject: [PATCH 119/725] drm/vc4: Fix warning about vblank interrupts before DRM core is ready. The SMICS interrupt fires continuously, but since it's 1/100 the rate diff --git a/target/linux/brcm2708/patches-4.19/950-0120-drm-vc4-Skip-SET_CURSOR_INFO-when-the-cursor-content.patch b/target/linux/brcm2708/patches-4.19/950-0120-drm-vc4-Skip-SET_CURSOR_INFO-when-the-cursor-content.patch index 3b734aa940..6bd85034f8 100644 --- a/target/linux/brcm2708/patches-4.19/950-0120-drm-vc4-Skip-SET_CURSOR_INFO-when-the-cursor-content.patch +++ b/target/linux/brcm2708/patches-4.19/950-0120-drm-vc4-Skip-SET_CURSOR_INFO-when-the-cursor-content.patch @@ -1,7 +1,7 @@ -From b77d51293dce1ff08da64c4bb95c13d2cb4c3ee7 Mon Sep 17 00:00:00 2001 +From 2d976e5035d98f5ada75f088a3e16079c8eee99a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 5 Feb 2018 18:02:30 +0000 -Subject: [PATCH 120/703] drm/vc4: Skip SET_CURSOR_INFO when the cursor +Subject: [PATCH 120/725] drm/vc4: Skip SET_CURSOR_INFO when the cursor contents didn't change. Signed-off-by: Eric Anholt diff --git a/target/linux/brcm2708/patches-4.19/950-0121-drm-vc4-Remove-duplicate-primary-cursor-fields-from-.patch b/target/linux/brcm2708/patches-4.19/950-0121-drm-vc4-Remove-duplicate-primary-cursor-fields-from-.patch index f84a42e4b1..591480e657 100644 --- a/target/linux/brcm2708/patches-4.19/950-0121-drm-vc4-Remove-duplicate-primary-cursor-fields-from-.patch +++ b/target/linux/brcm2708/patches-4.19/950-0121-drm-vc4-Remove-duplicate-primary-cursor-fields-from-.patch @@ -1,7 +1,7 @@ -From be3a851fe4c6f2e91a7d7b0738ad1873074eab43 Mon Sep 17 00:00:00 2001 +From 9c3d03b62cec67df4f3c989a2eceb38c1415fa71 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 5 Feb 2018 18:22:03 +0000 -Subject: [PATCH 121/703] drm/vc4: Remove duplicate primary/cursor fields from +Subject: [PATCH 121/725] drm/vc4: Remove duplicate primary/cursor fields from FKMS driver. The CRTC has those fields and we can just use them. diff --git a/target/linux/brcm2708/patches-4.19/950-0122-vc4_firmware_kms-fix-build.patch b/target/linux/brcm2708/patches-4.19/950-0122-vc4_firmware_kms-fix-build.patch index 3fe27d275a..556ad1e98f 100644 --- a/target/linux/brcm2708/patches-4.19/950-0122-vc4_firmware_kms-fix-build.patch +++ b/target/linux/brcm2708/patches-4.19/950-0122-vc4_firmware_kms-fix-build.patch @@ -1,7 +1,7 @@ -From 0f628b54b7f10997437a0e3f34eea2a0b2827250 Mon Sep 17 00:00:00 2001 +From 9c0ae7d4e7e70bd0b30073f66045a66bfabdb307 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 17 Jun 2018 13:22:07 +0100 -Subject: [PATCH 122/703] vc4_firmware_kms: fix build +Subject: [PATCH 122/725] vc4_firmware_kms: fix build --- drivers/gpu/drm/vc4/vc4_firmware_kms.c | 6 ++++-- diff --git a/target/linux/brcm2708/patches-4.19/950-0123-hack-cache-Fix-linker-error.patch b/target/linux/brcm2708/patches-4.19/950-0123-hack-cache-Fix-linker-error.patch index cd8731d5cf..42277c481b 100644 --- a/target/linux/brcm2708/patches-4.19/950-0123-hack-cache-Fix-linker-error.patch +++ b/target/linux/brcm2708/patches-4.19/950-0123-hack-cache-Fix-linker-error.patch @@ -1,7 +1,7 @@ -From 708821a5d04805bf61b036e869663d8650ca578c Mon Sep 17 00:00:00 2001 +From 48d20770b1aa96c6e3095316f493eab948e68c19 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 20 Feb 2018 20:53:46 +0000 -Subject: [PATCH 123/703] hack: cache: Fix linker error +Subject: [PATCH 123/725] hack: cache: Fix linker error --- arch/arm/mm/cache-v7.S | 2 ++ diff --git a/target/linux/brcm2708/patches-4.19/950-0124-i2c-gpio-Also-set-bus-numbers-from-reg-property.patch b/target/linux/brcm2708/patches-4.19/950-0124-i2c-gpio-Also-set-bus-numbers-from-reg-property.patch index 67dfd8fadf..7fde0ea0a3 100644 --- a/target/linux/brcm2708/patches-4.19/950-0124-i2c-gpio-Also-set-bus-numbers-from-reg-property.patch +++ b/target/linux/brcm2708/patches-4.19/950-0124-i2c-gpio-Also-set-bus-numbers-from-reg-property.patch @@ -1,7 +1,7 @@ -From ec510c1562ff8326e032a9f0d9ae26ff0e54dd1c Mon Sep 17 00:00:00 2001 +From b6109ee12acbda2c79f7a7a7b76806aebfcd9ed9 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 20 Feb 2018 10:07:27 +0000 -Subject: [PATCH 124/703] i2c-gpio: Also set bus numbers from reg property +Subject: [PATCH 124/725] i2c-gpio: Also set bus numbers from reg property I2C busses can be assigned specific bus numbers using aliases in Device Tree - string properties where the name is the alias and the diff --git a/target/linux/brcm2708/patches-4.19/950-0125-sound-bcm-Fix-memset-dereference-warning.patch b/target/linux/brcm2708/patches-4.19/950-0125-sound-bcm-Fix-memset-dereference-warning.patch index 3daea03bb4..56a5b1c0b7 100644 --- a/target/linux/brcm2708/patches-4.19/950-0125-sound-bcm-Fix-memset-dereference-warning.patch +++ b/target/linux/brcm2708/patches-4.19/950-0125-sound-bcm-Fix-memset-dereference-warning.patch @@ -1,7 +1,7 @@ -From 943530f05c0bb81679b1413c4a545e4600f61f71 Mon Sep 17 00:00:00 2001 +From 2b43c222f32b1a51a36a7511ea610adb9a51fb2b Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Sun, 4 Mar 2018 17:20:25 -0700 -Subject: [PATCH 125/703] sound: bcm: Fix memset dereference warning +Subject: [PATCH 125/725] sound: bcm: Fix memset dereference warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/target/linux/brcm2708/patches-4.19/950-0126-added-capture_clear-option-to-pps-gpio-via-dtoverlay.patch b/target/linux/brcm2708/patches-4.19/950-0126-added-capture_clear-option-to-pps-gpio-via-dtoverlay.patch index ba86578606..866b8382bf 100644 --- a/target/linux/brcm2708/patches-4.19/950-0126-added-capture_clear-option-to-pps-gpio-via-dtoverlay.patch +++ b/target/linux/brcm2708/patches-4.19/950-0126-added-capture_clear-option-to-pps-gpio-via-dtoverlay.patch @@ -1,7 +1,7 @@ -From ba23c2430362ba947a69c946b8b7bbe5c2eda914 Mon Sep 17 00:00:00 2001 +From 876356d4be81b4341cbc53a42c8a88dc49d7b56d Mon Sep 17 00:00:00 2001 From: hdoverobinson Date: Tue, 13 Mar 2018 06:58:39 -0400 -Subject: [PATCH 126/703] added capture_clear option to pps-gpio via dtoverlay +Subject: [PATCH 126/725] added capture_clear option to pps-gpio via dtoverlay (#2433) --- diff --git a/target/linux/brcm2708/patches-4.19/950-0127-lan78xx-Read-initial-EEE-status-from-DT.patch b/target/linux/brcm2708/patches-4.19/950-0127-lan78xx-Read-initial-EEE-status-from-DT.patch index 6102129b2f..b77d1c252c 100644 --- a/target/linux/brcm2708/patches-4.19/950-0127-lan78xx-Read-initial-EEE-status-from-DT.patch +++ b/target/linux/brcm2708/patches-4.19/950-0127-lan78xx-Read-initial-EEE-status-from-DT.patch @@ -1,7 +1,7 @@ -From 73b2c9d517072023cdc4e8331694b1e62234b09d Mon Sep 17 00:00:00 2001 +From c2da5c5af7a2d872d2b55c818cf9e67e34923a65 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 9 Mar 2018 12:01:00 +0000 -Subject: [PATCH 127/703] lan78xx: Read initial EEE status from DT +Subject: [PATCH 127/725] lan78xx: Read initial EEE status from DT Add two new DT properties: * microchip,eee-enabled - a boolean to enable EEE diff --git a/target/linux/brcm2708/patches-4.19/950-0128-hid-Reduce-default-mouse-polling-interval-to-60Hz.patch b/target/linux/brcm2708/patches-4.19/950-0128-hid-Reduce-default-mouse-polling-interval-to-60Hz.patch index be3c7b31cd..12e20ba757 100644 --- a/target/linux/brcm2708/patches-4.19/950-0128-hid-Reduce-default-mouse-polling-interval-to-60Hz.patch +++ b/target/linux/brcm2708/patches-4.19/950-0128-hid-Reduce-default-mouse-polling-interval-to-60Hz.patch @@ -1,7 +1,7 @@ -From e5af3fc88a539cabf03c3e676689282f662d1a08 Mon Sep 17 00:00:00 2001 +From 827f677549361a68c8bed46ae9bc3c6210273ace Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 14 Jul 2014 22:02:09 +0100 -Subject: [PATCH 128/703] hid: Reduce default mouse polling interval to 60Hz +Subject: [PATCH 128/725] hid: Reduce default mouse polling interval to 60Hz Reduces overhead when using X --- diff --git a/target/linux/brcm2708/patches-4.19/950-0129-gpiolib-Don-t-prevent-IRQ-usage-of-output-GPIOs.patch b/target/linux/brcm2708/patches-4.19/950-0129-gpiolib-Don-t-prevent-IRQ-usage-of-output-GPIOs.patch index 08c38d7430..d251129a2e 100644 --- a/target/linux/brcm2708/patches-4.19/950-0129-gpiolib-Don-t-prevent-IRQ-usage-of-output-GPIOs.patch +++ b/target/linux/brcm2708/patches-4.19/950-0129-gpiolib-Don-t-prevent-IRQ-usage-of-output-GPIOs.patch @@ -1,7 +1,7 @@ -From 4535e6abd37c89a7f21623497b9e656845aad4c0 Mon Sep 17 00:00:00 2001 +From 886c2877fcd6fdbff3c8cdec0e68bbb7570bc8ff Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 24 Apr 2018 14:42:27 +0100 -Subject: [PATCH 129/703] gpiolib: Don't prevent IRQ usage of output GPIOs +Subject: [PATCH 129/725] gpiolib: Don't prevent IRQ usage of output GPIOs Upstream Linux deems using output GPIOs to generate IRQs as a bogus use case, even though the BCM2835 GPIO controller is capable of doing diff --git a/target/linux/brcm2708/patches-4.19/950-0130-Add-ability-to-export-gpio-used-by-gpio-poweroff.patch b/target/linux/brcm2708/patches-4.19/950-0130-Add-ability-to-export-gpio-used-by-gpio-poweroff.patch index bcc104aaaa..5381c09268 100644 --- a/target/linux/brcm2708/patches-4.19/950-0130-Add-ability-to-export-gpio-used-by-gpio-poweroff.patch +++ b/target/linux/brcm2708/patches-4.19/950-0130-Add-ability-to-export-gpio-used-by-gpio-poweroff.patch @@ -1,7 +1,7 @@ -From cacdfc573c523a3e7e7e6ed708f459781228ccd1 Mon Sep 17 00:00:00 2001 +From 3e25c39320a501e57a5e232f6e98740357bd5bc6 Mon Sep 17 00:00:00 2001 From: Nick Bulleid Date: Thu, 10 May 2018 21:57:02 +0100 -Subject: [PATCH 130/703] Add ability to export gpio used by gpio-poweroff +Subject: [PATCH 130/725] Add ability to export gpio used by gpio-poweroff Signed-off-by: Nick Bulleid diff --git a/target/linux/brcm2708/patches-4.19/950-0131-firmware-raspberrypi-Notify-firmware-of-a-reboot.patch b/target/linux/brcm2708/patches-4.19/950-0131-firmware-raspberrypi-Notify-firmware-of-a-reboot.patch index 154aa1ecfe..0ff8de5182 100644 --- a/target/linux/brcm2708/patches-4.19/950-0131-firmware-raspberrypi-Notify-firmware-of-a-reboot.patch +++ b/target/linux/brcm2708/patches-4.19/950-0131-firmware-raspberrypi-Notify-firmware-of-a-reboot.patch @@ -1,7 +1,7 @@ -From 8e3109c37fc00a087aba08b92da9a416eb2cd37a Mon Sep 17 00:00:00 2001 +From ab5a0cc750eefdabd58b67c2558c46029ceb2a51 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Sat, 12 May 2018 21:35:43 +0100 -Subject: [PATCH 131/703] firmware/raspberrypi: Notify firmware of a reboot +Subject: [PATCH 131/725] firmware/raspberrypi: Notify firmware of a reboot Register for reboot notifications, sending RPI_FIRMWARE_NOTIFY_REBOOT over the mailbox interface on reception. diff --git a/target/linux/brcm2708/patches-4.19/950-0132-irqchip-irq-bcm2835-Calc.-FIQ_START-at-boot-time.patch b/target/linux/brcm2708/patches-4.19/950-0132-irqchip-irq-bcm2835-Calc.-FIQ_START-at-boot-time.patch index c269210a65..27b8192919 100644 --- a/target/linux/brcm2708/patches-4.19/950-0132-irqchip-irq-bcm2835-Calc.-FIQ_START-at-boot-time.patch +++ b/target/linux/brcm2708/patches-4.19/950-0132-irqchip-irq-bcm2835-Calc.-FIQ_START-at-boot-time.patch @@ -1,7 +1,7 @@ -From 73a2cd01254c251fe07c1a124b47105c1d1a7730 Mon Sep 17 00:00:00 2001 +From af6f3cf33a864c397f6ab43c0403b0a92797694e Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 14 Jun 2018 11:21:04 +0100 -Subject: [PATCH 132/703] irqchip: irq-bcm2835: Calc. FIQ_START at boot-time +Subject: [PATCH 132/725] irqchip: irq-bcm2835: Calc. FIQ_START at boot-time ad83c7cb2f37 ("irqchip/irq-bcm2836: Add support for DT interrupt polarity") changed the way that the BCM2836/7 local interrupts are mapped; instead diff --git a/target/linux/brcm2708/patches-4.19/950-0133-of-configfs-Use-of_overlay_fdt_apply-API-call.patch b/target/linux/brcm2708/patches-4.19/950-0133-of-configfs-Use-of_overlay_fdt_apply-API-call.patch index 78e2934bbb..09cc3997e0 100644 --- a/target/linux/brcm2708/patches-4.19/950-0133-of-configfs-Use-of_overlay_fdt_apply-API-call.patch +++ b/target/linux/brcm2708/patches-4.19/950-0133-of-configfs-Use-of_overlay_fdt_apply-API-call.patch @@ -1,7 +1,7 @@ -From 8d90ea3c51ab934802afe45eba16800f6c620cee Mon Sep 17 00:00:00 2001 +From 3a05e59e7c1866f46df63f0f11c46d3187d3adc9 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 14 Jun 2018 15:07:26 +0100 -Subject: [PATCH 133/703] of: configfs: Use of_overlay_fdt_apply API call +Subject: [PATCH 133/725] of: configfs: Use of_overlay_fdt_apply API call The published API to the dynamic overlay application mechanism now takes a Flattened Device Tree blob as input so that it can manage the diff --git a/target/linux/brcm2708/patches-4.19/950-0134-net-lan78xx-Disable-TCP-Segmentation-Offload-TSO.patch b/target/linux/brcm2708/patches-4.19/950-0134-net-lan78xx-Disable-TCP-Segmentation-Offload-TSO.patch index 6f31bd4f01..9f2d3ffde0 100644 --- a/target/linux/brcm2708/patches-4.19/950-0134-net-lan78xx-Disable-TCP-Segmentation-Offload-TSO.patch +++ b/target/linux/brcm2708/patches-4.19/950-0134-net-lan78xx-Disable-TCP-Segmentation-Offload-TSO.patch @@ -1,7 +1,7 @@ -From 48c17759c12fead4c4643e895582fb44b9b8ec15 Mon Sep 17 00:00:00 2001 +From aa624ea88f53750c15729e82c0ac380b2b0768ac Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 13 Jun 2018 15:21:10 +0100 -Subject: [PATCH 134/703] net: lan78xx: Disable TCP Segmentation Offload (TSO) +Subject: [PATCH 134/725] net: lan78xx: Disable TCP Segmentation Offload (TSO) TSO seems to be having issues when packets are dropped and the remote end uses Selective Acknowledge (SACK) to denote that diff --git a/target/linux/brcm2708/patches-4.19/950-0135-brcmfmac-Re-enable-firmware-roaming-support.patch b/target/linux/brcm2708/patches-4.19/950-0135-brcmfmac-Re-enable-firmware-roaming-support.patch index a907772566..f0e758465d 100644 --- a/target/linux/brcm2708/patches-4.19/950-0135-brcmfmac-Re-enable-firmware-roaming-support.patch +++ b/target/linux/brcm2708/patches-4.19/950-0135-brcmfmac-Re-enable-firmware-roaming-support.patch @@ -1,7 +1,7 @@ -From 8bb29ed53937d3608e68f75d269d648ca0b22dcf Mon Sep 17 00:00:00 2001 +From 5ef577082ea0d6fb498e5189bd55071aed9696e7 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 20 Jun 2018 12:20:01 +0100 -Subject: [PATCH 135/703] brcmfmac: Re-enable firmware roaming support +Subject: [PATCH 135/725] brcmfmac: Re-enable firmware roaming support As of 4.18, a firmware that implements the update_connect_params method but doesn't claim to support roaming causes an error. We diff --git a/target/linux/brcm2708/patches-4.19/950-0136-lan78xx-Move-enabling-of-EEE-into-PHY-init-code.patch b/target/linux/brcm2708/patches-4.19/950-0136-lan78xx-Move-enabling-of-EEE-into-PHY-init-code.patch index 642919b21e..37a280c14f 100644 --- a/target/linux/brcm2708/patches-4.19/950-0136-lan78xx-Move-enabling-of-EEE-into-PHY-init-code.patch +++ b/target/linux/brcm2708/patches-4.19/950-0136-lan78xx-Move-enabling-of-EEE-into-PHY-init-code.patch @@ -1,7 +1,7 @@ -From 16ca74df16214e51080a6102388fbbaaae713c5e Mon Sep 17 00:00:00 2001 +From 95e0c441040464722e1abb50a365224e7bf9058d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 5 Apr 2018 14:46:11 +0100 -Subject: [PATCH 136/703] lan78xx: Move enabling of EEE into PHY init code +Subject: [PATCH 136/725] lan78xx: Move enabling of EEE into PHY init code Enable EEE mode as soon as possible after connecting to the PHY, and before phy_start. This avoids a second link negotiation, which speeds diff --git a/target/linux/brcm2708/patches-4.19/950-0137-staging-vc04_services-Derive-g_cache_line_size.patch b/target/linux/brcm2708/patches-4.19/950-0137-staging-vc04_services-Derive-g_cache_line_size.patch index 5894aca1cd..1d94c2ac1d 100644 --- a/target/linux/brcm2708/patches-4.19/950-0137-staging-vc04_services-Derive-g_cache_line_size.patch +++ b/target/linux/brcm2708/patches-4.19/950-0137-staging-vc04_services-Derive-g_cache_line_size.patch @@ -1,7 +1,7 @@ -From 3e89900d7dd7c851400e0afeea326f94bba1cd84 Mon Sep 17 00:00:00 2001 +From 3e9ee1b0f8b5b8ad3fc688e785de479cbde00b5c Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 28 Aug 2018 10:40:40 +0100 -Subject: [PATCH 137/703] staging/vc04_services: Derive g_cache_line_size +Subject: [PATCH 137/725] staging/vc04_services: Derive g_cache_line_size The ARM coprocessor registers include dcache line size, but there is no function to expose this value. Rather than create a new one, use the diff --git a/target/linux/brcm2708/patches-4.19/950-0138-Add-rpi-poe-fan-driver.patch b/target/linux/brcm2708/patches-4.19/950-0138-Add-rpi-poe-fan-driver.patch index 659a2b4e06..97cc5f6968 100644 --- a/target/linux/brcm2708/patches-4.19/950-0138-Add-rpi-poe-fan-driver.patch +++ b/target/linux/brcm2708/patches-4.19/950-0138-Add-rpi-poe-fan-driver.patch @@ -1,7 +1,7 @@ -From ae762f7cc705c20c8320613425a7179c3e6f47f3 Mon Sep 17 00:00:00 2001 +From 1c1f26355604567bc11084cb3c4db204d7420941 Mon Sep 17 00:00:00 2001 From: Serge Schneider Date: Mon, 9 Jul 2018 12:54:25 +0100 -Subject: [PATCH 138/703] Add rpi-poe-fan driver +Subject: [PATCH 138/725] Add rpi-poe-fan driver Signed-off-by: Serge Schneider diff --git a/target/linux/brcm2708/patches-4.19/950-0139-cxd2880-CXD2880_SPI_DRV-should-select-DVB_CXD2880-wi.patch b/target/linux/brcm2708/patches-4.19/950-0139-cxd2880-CXD2880_SPI_DRV-should-select-DVB_CXD2880-wi.patch index ec97f6ffd8..0cd31a60c5 100644 --- a/target/linux/brcm2708/patches-4.19/950-0139-cxd2880-CXD2880_SPI_DRV-should-select-DVB_CXD2880-wi.patch +++ b/target/linux/brcm2708/patches-4.19/950-0139-cxd2880-CXD2880_SPI_DRV-should-select-DVB_CXD2880-wi.patch @@ -1,7 +1,7 @@ -From 6b7588fb541726ea05baf7f553deafa907263a6e Mon Sep 17 00:00:00 2001 +From f78d450f7ce53a644fae11f359c133fd015cda12 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 17 Sep 2018 17:31:18 +0100 -Subject: [PATCH 139/703] cxd2880: CXD2880_SPI_DRV should select DVB_CXD2880 +Subject: [PATCH 139/725] cxd2880: CXD2880_SPI_DRV should select DVB_CXD2880 with MEDIA_SUBDRV_AUTOSELECT --- diff --git a/target/linux/brcm2708/patches-4.19/950-0140-bcm2835-interpolate-audio-delay.patch b/target/linux/brcm2708/patches-4.19/950-0140-bcm2835-interpolate-audio-delay.patch index 61b4f50ca1..b3bb009099 100644 --- a/target/linux/brcm2708/patches-4.19/950-0140-bcm2835-interpolate-audio-delay.patch +++ b/target/linux/brcm2708/patches-4.19/950-0140-bcm2835-interpolate-audio-delay.patch @@ -1,7 +1,7 @@ -From 7de09525583f90004ba236345bae3ad3274d23da Mon Sep 17 00:00:00 2001 +From 572ba427304c769cdf4d19d8d93c3d413ad57f72 Mon Sep 17 00:00:00 2001 From: wm4 Date: Wed, 13 Jan 2016 19:44:47 +0100 -Subject: [PATCH 140/703] bcm2835: interpolate audio delay +Subject: [PATCH 140/725] bcm2835: interpolate audio delay It appears the GPU only sends us a message all 10ms to update the playback progress. Other than this, the playback position diff --git a/target/linux/brcm2708/patches-4.19/950-0141-vchiq_2835_arm-Implement-a-DMA-pool-for-small-bulk-t.patch b/target/linux/brcm2708/patches-4.19/950-0141-vchiq_2835_arm-Implement-a-DMA-pool-for-small-bulk-t.patch index b246b826ec..a1d1c2bf5c 100644 --- a/target/linux/brcm2708/patches-4.19/950-0141-vchiq_2835_arm-Implement-a-DMA-pool-for-small-bulk-t.patch +++ b/target/linux/brcm2708/patches-4.19/950-0141-vchiq_2835_arm-Implement-a-DMA-pool-for-small-bulk-t.patch @@ -1,7 +1,7 @@ -From 8a9e2054d3ecf11044136daa5644d803db486dd4 Mon Sep 17 00:00:00 2001 +From 77b81e05d19c1c25d8139eddc45c0a2da0585be2 Mon Sep 17 00:00:00 2001 From: detule Date: Tue, 2 Oct 2018 04:10:08 -0400 -Subject: [PATCH 141/703] vchiq_2835_arm: Implement a DMA pool for small bulk +Subject: [PATCH 141/725] vchiq_2835_arm: Implement a DMA pool for small bulk transfers (#2699) During a bulk transfer we request a DMA allocation to hold the diff --git a/target/linux/brcm2708/patches-4.19/950-0142-BCM2708_DT-Use-upstreamed-GPIO-expander-driver.patch b/target/linux/brcm2708/patches-4.19/950-0142-BCM2708_DT-Use-upstreamed-GPIO-expander-driver.patch index 4da560fa80..5a3d82197f 100644 --- a/target/linux/brcm2708/patches-4.19/950-0142-BCM2708_DT-Use-upstreamed-GPIO-expander-driver.patch +++ b/target/linux/brcm2708/patches-4.19/950-0142-BCM2708_DT-Use-upstreamed-GPIO-expander-driver.patch @@ -1,7 +1,7 @@ -From e40969b6e1a0818b016646c449d3fbc7e5c8b608 Mon Sep 17 00:00:00 2001 +From fdac3a95e9af79a125e41d7c16e4deac80742ac5 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 8 Oct 2018 12:20:36 +0100 -Subject: [PATCH 142/703] BCM2708_DT: Use upstreamed GPIO expander driver +Subject: [PATCH 142/725] BCM2708_DT: Use upstreamed GPIO expander driver The upstreamed driver for the GPIO expander has a different compatible string. Change the relevant Device Tree files to match. diff --git a/target/linux/brcm2708/patches-4.19/950-0143-overlays-Fix-a-few-dtc-warnings.patch b/target/linux/brcm2708/patches-4.19/950-0143-overlays-Fix-a-few-dtc-warnings.patch index 155ad28c51..38c60500cf 100644 --- a/target/linux/brcm2708/patches-4.19/950-0143-overlays-Fix-a-few-dtc-warnings.patch +++ b/target/linux/brcm2708/patches-4.19/950-0143-overlays-Fix-a-few-dtc-warnings.patch @@ -1,7 +1,7 @@ -From 17ded7b344a73b5a590ca8dc4599ac1ad3c1edb7 Mon Sep 17 00:00:00 2001 +From 920732ad22a1e352b757d854aec4814c95d061a9 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 8 Oct 2018 17:16:28 +0100 -Subject: [PATCH 143/703] overlays: Fix a few dtc warnings +Subject: [PATCH 143/725] overlays: Fix a few dtc warnings Signed-off-by: Phil Elwell --- diff --git a/target/linux/brcm2708/patches-4.19/950-0144-bcm2708-rpi-Disable-txp-interrupt-unless-using-vc4-k.patch b/target/linux/brcm2708/patches-4.19/950-0144-bcm2708-rpi-Disable-txp-interrupt-unless-using-vc4-k.patch index 562be8afd7..622c2ff69a 100644 --- a/target/linux/brcm2708/patches-4.19/950-0144-bcm2708-rpi-Disable-txp-interrupt-unless-using-vc4-k.patch +++ b/target/linux/brcm2708/patches-4.19/950-0144-bcm2708-rpi-Disable-txp-interrupt-unless-using-vc4-k.patch @@ -1,7 +1,7 @@ -From 158c6b75bd52edff52b9499313935c9d0f154eb2 Mon Sep 17 00:00:00 2001 +From d659979d89c1de698fa7c7e28951c4f09f9dfafd Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Oct 2018 16:32:52 +0100 -Subject: [PATCH 144/703] bcm2708-rpi: Disable txp interrupt unless using +Subject: [PATCH 144/725] bcm2708-rpi: Disable txp interrupt unless using vc4-kms-v3d overlay Signed-off-by: popcornmix diff --git a/target/linux/brcm2708/patches-4.19/950-0145-config-Enable-Raspberry-Pi-voltage-monitor.patch b/target/linux/brcm2708/patches-4.19/950-0145-config-Enable-Raspberry-Pi-voltage-monitor.patch index 2edec9381e..d98fb5d298 100644 --- a/target/linux/brcm2708/patches-4.19/950-0145-config-Enable-Raspberry-Pi-voltage-monitor.patch +++ b/target/linux/brcm2708/patches-4.19/950-0145-config-Enable-Raspberry-Pi-voltage-monitor.patch @@ -1,7 +1,7 @@ -From 3af123f416cbd52069f8479ece21e0564317cbb3 Mon Sep 17 00:00:00 2001 +From 0bb32ea31ade963bfe81c67dbb2a4dbb090895c2 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sat, 6 Oct 2018 16:45:41 +0200 -Subject: [PATCH 145/703] config: Enable Raspberry Pi voltage monitor +Subject: [PATCH 145/725] config: Enable Raspberry Pi voltage monitor This enables the Raspberry Pi voltage monitor as a replacement for the get_trottled sysfs approach in the firmware driver. diff --git a/target/linux/brcm2708/patches-4.19/950-0146-hwmon-raspberrypi-Prevent-voltage-low-warnings-from-.patch b/target/linux/brcm2708/patches-4.19/950-0146-hwmon-raspberrypi-Prevent-voltage-low-warnings-from-.patch index 992ef62c23..64816d8038 100644 --- a/target/linux/brcm2708/patches-4.19/950-0146-hwmon-raspberrypi-Prevent-voltage-low-warnings-from-.patch +++ b/target/linux/brcm2708/patches-4.19/950-0146-hwmon-raspberrypi-Prevent-voltage-low-warnings-from-.patch @@ -1,7 +1,7 @@ -From 639d584d74593084469286e33cbf8c6b2be9d1a5 Mon Sep 17 00:00:00 2001 +From af7c9bdc7c407c585fd3c6eac2ad42e78e1fb08c Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sat, 6 Oct 2018 16:46:18 +0200 -Subject: [PATCH 146/703] hwmon: raspberrypi: Prevent voltage low warnings from +Subject: [PATCH 146/725] hwmon: raspberrypi: Prevent voltage low warnings from filling log Although the correct fix for low voltage warnings is to diff --git a/target/linux/brcm2708/patches-4.19/950-0147-firmware-raspberrypi-Add-backward-compatible-get_thr.patch b/target/linux/brcm2708/patches-4.19/950-0147-firmware-raspberrypi-Add-backward-compatible-get_thr.patch index 7df7780b49..83065dd161 100644 --- a/target/linux/brcm2708/patches-4.19/950-0147-firmware-raspberrypi-Add-backward-compatible-get_thr.patch +++ b/target/linux/brcm2708/patches-4.19/950-0147-firmware-raspberrypi-Add-backward-compatible-get_thr.patch @@ -1,7 +1,7 @@ -From 2f40de9f47b7bcf5677a110d4207bbf65e02049c Mon Sep 17 00:00:00 2001 +From 53250b67aca386f2e01881623c192089226bbae3 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sat, 13 Oct 2018 13:31:21 +0200 -Subject: [PATCH 147/703] firmware: raspberrypi: Add backward compatible +Subject: [PATCH 147/725] firmware: raspberrypi: Add backward compatible get_throttled Avoid a hard userspace ABI change by adding a compatible get_throttled diff --git a/target/linux/brcm2708/patches-4.19/950-0148-Increase-firmware-call-buffer-size-to-48-bytes.patch b/target/linux/brcm2708/patches-4.19/950-0148-Increase-firmware-call-buffer-size-to-48-bytes.patch index 49c7864cf8..3d029a7dca 100644 --- a/target/linux/brcm2708/patches-4.19/950-0148-Increase-firmware-call-buffer-size-to-48-bytes.patch +++ b/target/linux/brcm2708/patches-4.19/950-0148-Increase-firmware-call-buffer-size-to-48-bytes.patch @@ -1,7 +1,7 @@ -From bee18e4688b1ac325f91dd4aee8672f6201d0a8d Mon Sep 17 00:00:00 2001 +From 5ff0d8351ea1bae67c1fd8d565bb4912cf201a71 Mon Sep 17 00:00:00 2001 From: James Hughes Date: Wed, 31 Oct 2018 13:00:46 +0000 -Subject: [PATCH 148/703] Increase firmware call buffer size to 48 bytes +Subject: [PATCH 148/725] Increase firmware call buffer size to 48 bytes An assumption was made in commit a1547e0bc that 32 bytes would be enough data buffer size for all firmware calls. However, diff --git a/target/linux/brcm2708/patches-4.19/950-0149-sc16is7xx-Don-t-spin-if-no-data-received.patch b/target/linux/brcm2708/patches-4.19/950-0149-sc16is7xx-Don-t-spin-if-no-data-received.patch index 7d6947ef9b..2a094cedac 100644 --- a/target/linux/brcm2708/patches-4.19/950-0149-sc16is7xx-Don-t-spin-if-no-data-received.patch +++ b/target/linux/brcm2708/patches-4.19/950-0149-sc16is7xx-Don-t-spin-if-no-data-received.patch @@ -1,7 +1,7 @@ -From 6a47065f2c10f857ec32786d0c4f2e1c46aed98b Mon Sep 17 00:00:00 2001 +From 692350cd48454616db5bde755b6d2ef29946ade7 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 6 Nov 2018 12:57:48 +0000 -Subject: [PATCH 149/703] sc16is7xx: Don't spin if no data received +Subject: [PATCH 149/725] sc16is7xx: Don't spin if no data received See: https://github.com/raspberrypi/linux/issues/2676 diff --git a/target/linux/brcm2708/patches-4.19/950-0150-configs-Rebuild-bcmrpi3_defconfig-to-fix-warnings.patch b/target/linux/brcm2708/patches-4.19/950-0150-configs-Rebuild-bcmrpi3_defconfig-to-fix-warnings.patch index bb45972cdb..d166787487 100644 --- a/target/linux/brcm2708/patches-4.19/950-0150-configs-Rebuild-bcmrpi3_defconfig-to-fix-warnings.patch +++ b/target/linux/brcm2708/patches-4.19/950-0150-configs-Rebuild-bcmrpi3_defconfig-to-fix-warnings.patch @@ -1,7 +1,7 @@ -From 00fd230b49fe86d0458b3fbd92b9c556c1433fe4 Mon Sep 17 00:00:00 2001 +From 049db5dc012f133a8838503426a0cfa1cf9367a6 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 12 Nov 2018 21:42:00 +0000 -Subject: [PATCH 150/703] configs: Rebuild bcmrpi3_defconfig to fix warnings +Subject: [PATCH 150/725] configs: Rebuild bcmrpi3_defconfig to fix warnings Also disable CONFIG_MMC_BCM2835 to avoid a runtime conflict. diff --git a/target/linux/brcm2708/patches-4.19/950-0151-brcmfmac-Disable-ARP-offloading-when-promiscuous.patch b/target/linux/brcm2708/patches-4.19/950-0151-brcmfmac-Disable-ARP-offloading-when-promiscuous.patch index 27f889482b..94843ea4f8 100644 --- a/target/linux/brcm2708/patches-4.19/950-0151-brcmfmac-Disable-ARP-offloading-when-promiscuous.patch +++ b/target/linux/brcm2708/patches-4.19/950-0151-brcmfmac-Disable-ARP-offloading-when-promiscuous.patch @@ -1,7 +1,7 @@ -From 80cebfc3a14a2645e99baa0a72587e25961e178f Mon Sep 17 00:00:00 2001 +From f54f72309a110bbb583335dd72d84908b1f56043 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 24 Aug 2017 16:16:16 +0100 -Subject: [PATCH 151/703] brcmfmac: Disable ARP offloading when promiscuous +Subject: [PATCH 151/725] brcmfmac: Disable ARP offloading when promiscuous This is a test patch for brcmfmac from Franky Lin at Broadcom to disable ARP offloading when in promiscuous mode, re-enabling the ability to diff --git a/target/linux/brcm2708/patches-4.19/950-0152-config-enable-Audio-Graph-Card-module.patch b/target/linux/brcm2708/patches-4.19/950-0152-config-enable-Audio-Graph-Card-module.patch index 9722e2aafe..e5ef26dbe4 100644 --- a/target/linux/brcm2708/patches-4.19/950-0152-config-enable-Audio-Graph-Card-module.patch +++ b/target/linux/brcm2708/patches-4.19/950-0152-config-enable-Audio-Graph-Card-module.patch @@ -1,7 +1,7 @@ -From 3267c6df89133ad70bd8bb1e55a5754be716df0e Mon Sep 17 00:00:00 2001 +From d96b4839eea5d6d0a776bed39d3fb6d8cc198662 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Tue, 6 Feb 2018 15:37:22 +0100 -Subject: [PATCH 152/703] config: enable Audio Graph Card module +Subject: [PATCH 152/725] config: enable Audio Graph Card module Signed-off-by: Matthias Reichl --- diff --git a/target/linux/brcm2708/patches-4.19/950-0153-config-Add-IPVLAN-module.patch b/target/linux/brcm2708/patches-4.19/950-0153-config-Add-IPVLAN-module.patch index 8bdd1cd370..45c63d0f39 100644 --- a/target/linux/brcm2708/patches-4.19/950-0153-config-Add-IPVLAN-module.patch +++ b/target/linux/brcm2708/patches-4.19/950-0153-config-Add-IPVLAN-module.patch @@ -1,7 +1,7 @@ -From 0de1fec9e76eabe6079fb9984a012cbdee9164a6 Mon Sep 17 00:00:00 2001 +From 52c06bef6f690f7fd5ab3fde9049a022344cb0bb Mon Sep 17 00:00:00 2001 From: popcornmix Date: Thu, 29 Mar 2018 16:05:28 +0100 -Subject: [PATCH 153/703] config: Add IPVLAN module +Subject: [PATCH 153/725] config: Add IPVLAN module --- arch/arm/configs/bcm2709_defconfig | 1 + diff --git a/target/linux/brcm2708/patches-4.19/950-0154-config-Add-I2C_TINY_USB-m.patch b/target/linux/brcm2708/patches-4.19/950-0154-config-Add-I2C_TINY_USB-m.patch index 1a88009d5c..a178f161f1 100644 --- a/target/linux/brcm2708/patches-4.19/950-0154-config-Add-I2C_TINY_USB-m.patch +++ b/target/linux/brcm2708/patches-4.19/950-0154-config-Add-I2C_TINY_USB-m.patch @@ -1,7 +1,7 @@ -From 61df97bfcb573b2361fdbbe0282ba1c5671988dc Mon Sep 17 00:00:00 2001 +From 511b2e25825ff53cb5dbb5d224c747c8dd37dc8b Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 27 Apr 2018 16:21:33 +0100 -Subject: [PATCH 154/703] config: Add I2C_TINY_USB=m +Subject: [PATCH 154/725] config: Add I2C_TINY_USB=m Enable the I2C Tiny USB module. diff --git a/target/linux/brcm2708/patches-4.19/950-0155-Add-device-tree-overlay-for-HD44780.patch b/target/linux/brcm2708/patches-4.19/950-0155-Add-device-tree-overlay-for-HD44780.patch index b6aa76b41e..4909ea2baf 100644 --- a/target/linux/brcm2708/patches-4.19/950-0155-Add-device-tree-overlay-for-HD44780.patch +++ b/target/linux/brcm2708/patches-4.19/950-0155-Add-device-tree-overlay-for-HD44780.patch @@ -1,7 +1,7 @@ -From 0950d997c40aa9428b886d7e1af46730b0366513 Mon Sep 17 00:00:00 2001 +From c02e400776f6cba9abef5bfec91765e694f35d3b Mon Sep 17 00:00:00 2001 From: Jasper Boomer Date: Sun, 24 Jun 2018 12:20:27 -0400 -Subject: [PATCH 155/703] Add device tree overlay for HD44780 +Subject: [PATCH 155/725] Add device tree overlay for HD44780 --- arch/arm/boot/dts/overlays/Makefile | 1 + diff --git a/target/linux/brcm2708/patches-4.19/950-0156-Add-hd44780-module-to-defconfig.patch b/target/linux/brcm2708/patches-4.19/950-0156-Add-hd44780-module-to-defconfig.patch index 5c5a2e0189..5d903c1c1a 100644 --- a/target/linux/brcm2708/patches-4.19/950-0156-Add-hd44780-module-to-defconfig.patch +++ b/target/linux/brcm2708/patches-4.19/950-0156-Add-hd44780-module-to-defconfig.patch @@ -1,7 +1,7 @@ -From 3b04201f52d7a717828ab10a92610edbb99abd23 Mon Sep 17 00:00:00 2001 +From a7523a743a928748b2961de56fe5345f653da15e Mon Sep 17 00:00:00 2001 From: Jasper Boomer Date: Mon, 2 Jul 2018 13:16:22 -0400 -Subject: [PATCH 156/703] Add hd44780 module to defconfig +Subject: [PATCH 156/725] Add hd44780 module to defconfig --- arch/arm/configs/bcm2709_defconfig | 2 ++ diff --git a/target/linux/brcm2708/patches-4.19/950-0157-overlays-Add-addr-parameter-to-i2c-rtc-gpio.patch b/target/linux/brcm2708/patches-4.19/950-0157-overlays-Add-addr-parameter-to-i2c-rtc-gpio.patch index e20f87c309..baedd1fe3e 100644 --- a/target/linux/brcm2708/patches-4.19/950-0157-overlays-Add-addr-parameter-to-i2c-rtc-gpio.patch +++ b/target/linux/brcm2708/patches-4.19/950-0157-overlays-Add-addr-parameter-to-i2c-rtc-gpio.patch @@ -1,7 +1,7 @@ -From ac46f67a7cd528da77a0483989ad41a71af1d9e5 Mon Sep 17 00:00:00 2001 +From 7eaf324bc93496bb2462da74aa575a4b5c6b39da Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 9 Jul 2018 21:11:32 +0100 -Subject: [PATCH 157/703] overlays: Add addr parameter to i2c-rtc (& -gpio) +Subject: [PATCH 157/725] overlays: Add addr parameter to i2c-rtc (& -gpio) See: https://github.com/raspberrypi/linux/issues/2611 diff --git a/target/linux/brcm2708/patches-4.19/950-0158-ARM-BCM270X-Add-the-18-bit-DPI-pinmux-to-the-RPI-DTs.patch b/target/linux/brcm2708/patches-4.19/950-0158-ARM-BCM270X-Add-the-18-bit-DPI-pinmux-to-the-RPI-DTs.patch index 77d52eadc8..f098ab9b7f 100644 --- a/target/linux/brcm2708/patches-4.19/950-0158-ARM-BCM270X-Add-the-18-bit-DPI-pinmux-to-the-RPI-DTs.patch +++ b/target/linux/brcm2708/patches-4.19/950-0158-ARM-BCM270X-Add-the-18-bit-DPI-pinmux-to-the-RPI-DTs.patch @@ -1,7 +1,7 @@ -From 74cbdede7a4a3eed31d508c02503ce06a1d0e7b2 Mon Sep 17 00:00:00 2001 +From c4620c94d1a5ec51908bb670968b68fd1aa692b1 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 9 Mar 2018 14:24:05 -0800 -Subject: [PATCH 158/703] ARM: BCM270X: Add the 18-bit DPI pinmux to the RPI +Subject: [PATCH 158/725] ARM: BCM270X: Add the 18-bit DPI pinmux to the RPI DTs. This doesn't do anything by default, but trying to put the node in an diff --git a/target/linux/brcm2708/patches-4.19/950-0159-overlays-Add-an-overlay-for-the-Adafruit-Kippah-with.patch b/target/linux/brcm2708/patches-4.19/950-0159-overlays-Add-an-overlay-for-the-Adafruit-Kippah-with.patch index 5b02eebab0..f38618d3ad 100644 --- a/target/linux/brcm2708/patches-4.19/950-0159-overlays-Add-an-overlay-for-the-Adafruit-Kippah-with.patch +++ b/target/linux/brcm2708/patches-4.19/950-0159-overlays-Add-an-overlay-for-the-Adafruit-Kippah-with.patch @@ -1,7 +1,7 @@ -From 7c8ccff2dfef1f42ac9e1592a4750b4d9b78ad62 Mon Sep 17 00:00:00 2001 +From 2fc67f0d898fb7be4e68bdb94959fdebe07b529d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 9 Mar 2018 13:20:21 -0800 -Subject: [PATCH 159/703] overlays: Add an overlay for the Adafruit Kippah with +Subject: [PATCH 159/725] overlays: Add an overlay for the Adafruit Kippah with their 7" panel Signed-off-by: Eric Anholt diff --git a/target/linux/brcm2708/patches-4.19/950-0160-overlays-Remove-stale-notes-about-vc4-s-CMA-alignmen.patch b/target/linux/brcm2708/patches-4.19/950-0160-overlays-Remove-stale-notes-about-vc4-s-CMA-alignmen.patch index cb95ac3268..64d466fac4 100644 --- a/target/linux/brcm2708/patches-4.19/950-0160-overlays-Remove-stale-notes-about-vc4-s-CMA-alignmen.patch +++ b/target/linux/brcm2708/patches-4.19/950-0160-overlays-Remove-stale-notes-about-vc4-s-CMA-alignmen.patch @@ -1,7 +1,7 @@ -From 27d6a0828bacfd0f1d3e0b64176be91a55d2f3ae Mon Sep 17 00:00:00 2001 +From e5d4483bb784c5602ba585692cbdde1d0fbbfff9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 9 Mar 2018 13:26:33 -0800 -Subject: [PATCH 160/703] overlays: Remove stale notes about vc4's CMA +Subject: [PATCH 160/725] overlays: Remove stale notes about vc4's CMA alignment in the README. We haven't needed alignment since diff --git a/target/linux/brcm2708/patches-4.19/950-0161-spi-Make-GPIO-CSs-honour-the-SPI_NO_CS-flag.patch b/target/linux/brcm2708/patches-4.19/950-0161-spi-Make-GPIO-CSs-honour-the-SPI_NO_CS-flag.patch index 85584d654b..2404cc1d64 100644 --- a/target/linux/brcm2708/patches-4.19/950-0161-spi-Make-GPIO-CSs-honour-the-SPI_NO_CS-flag.patch +++ b/target/linux/brcm2708/patches-4.19/950-0161-spi-Make-GPIO-CSs-honour-the-SPI_NO_CS-flag.patch @@ -1,7 +1,7 @@ -From ac1bfbc3e45d83d617ce9fbae7522bbd0be3a075 Mon Sep 17 00:00:00 2001 +From 2910d986df71ea75845706084fd257d2b9127e74 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 3 Jul 2018 14:23:47 +0100 -Subject: [PATCH 161/703] spi: Make GPIO CSs honour the SPI_NO_CS flag +Subject: [PATCH 161/725] spi: Make GPIO CSs honour the SPI_NO_CS flag The SPI configuration state includes an SPI_NO_CS flag that disables all CS line manipulation, for applications that want to manage their diff --git a/target/linux/brcm2708/patches-4.19/950-0162-devicetree-add-RPi-CM3-dts-to-arm64-mimic-the-RPi-3B.patch b/target/linux/brcm2708/patches-4.19/950-0162-devicetree-add-RPi-CM3-dts-to-arm64-mimic-the-RPi-3B.patch index 06a718ed48..4ca101ceec 100644 --- a/target/linux/brcm2708/patches-4.19/950-0162-devicetree-add-RPi-CM3-dts-to-arm64-mimic-the-RPi-3B.patch +++ b/target/linux/brcm2708/patches-4.19/950-0162-devicetree-add-RPi-CM3-dts-to-arm64-mimic-the-RPi-3B.patch @@ -1,7 +1,7 @@ -From 90e4534cb3d7b7f1810c160734b11adc79dd6422 Mon Sep 17 00:00:00 2001 +From bb5657317c40a44f4a550f7f7101edc6fe5f50af Mon Sep 17 00:00:00 2001 From: Steve Pavao Date: Fri, 10 Aug 2018 17:09:50 -0400 -Subject: [PATCH 162/703] devicetree: add RPi CM3 dts to arm64; mimic the RPi +Subject: [PATCH 162/725] devicetree: add RPi CM3 dts to arm64; mimic the RPi 3B arm64 dts implementation, by referring to the actual dts file in the arm directory diff --git a/target/linux/brcm2708/patches-4.19/950-0163-Add-support-for-audioinjector.net-ultra-soundcard.-2.patch b/target/linux/brcm2708/patches-4.19/950-0163-Add-support-for-audioinjector.net-ultra-soundcard.-2.patch index 63ae9b1815..f3ef36d03b 100644 --- a/target/linux/brcm2708/patches-4.19/950-0163-Add-support-for-audioinjector.net-ultra-soundcard.-2.patch +++ b/target/linux/brcm2708/patches-4.19/950-0163-Add-support-for-audioinjector.net-ultra-soundcard.-2.patch @@ -1,7 +1,7 @@ -From 5565106f860262bde33a49e866090bec4d2602e0 Mon Sep 17 00:00:00 2001 +From 4accaf8828da84a10053475c100a07ae91d75c8e Mon Sep 17 00:00:00 2001 From: Matt Flax Date: Tue, 28 Aug 2018 18:42:13 +1000 -Subject: [PATCH 163/703] Add support for audioinjector.net ultra soundcard. +Subject: [PATCH 163/725] Add support for audioinjector.net ultra soundcard. (#2664) Uses the simple-audio-card ALSA machine driver. Sets up the machine diff --git a/target/linux/brcm2708/patches-4.19/950-0164-ASoC-cs4265-Add-a-S-PDIF-enable-switch.patch b/target/linux/brcm2708/patches-4.19/950-0164-ASoC-cs4265-Add-a-S-PDIF-enable-switch.patch index 608ab2b5f3..4fabde4e4f 100644 --- a/target/linux/brcm2708/patches-4.19/950-0164-ASoC-cs4265-Add-a-S-PDIF-enable-switch.patch +++ b/target/linux/brcm2708/patches-4.19/950-0164-ASoC-cs4265-Add-a-S-PDIF-enable-switch.patch @@ -1,7 +1,7 @@ -From 42d8389b1b8b22be93aefd995f8a1b818bf1dac5 Mon Sep 17 00:00:00 2001 +From 84e563dc0f76f480dc00ec72c04621810cf2bcb1 Mon Sep 17 00:00:00 2001 From: Matt Flax Date: Thu, 30 Aug 2018 09:38:02 +1000 -Subject: [PATCH 164/703] ASoC: cs4265: Add a S/PDIF enable switch +Subject: [PATCH 164/725] ASoC: cs4265: Add a S/PDIF enable switch commit f853d6b3ba345297974d877d8ed0f4a91eaca739 upstream. diff --git a/target/linux/brcm2708/patches-4.19/950-0165-ASoC-cs4265-Add-native-32bit-I2S-transport.patch b/target/linux/brcm2708/patches-4.19/950-0165-ASoC-cs4265-Add-native-32bit-I2S-transport.patch index 619b759441..fb13aed6a6 100644 --- a/target/linux/brcm2708/patches-4.19/950-0165-ASoC-cs4265-Add-native-32bit-I2S-transport.patch +++ b/target/linux/brcm2708/patches-4.19/950-0165-ASoC-cs4265-Add-native-32bit-I2S-transport.patch @@ -1,7 +1,7 @@ -From acee6587af4d29f9c95fa79f2bbf9cab3a96842e Mon Sep 17 00:00:00 2001 +From 515db674b59d2d693b8a6dd8fc9bb2827a71335e Mon Sep 17 00:00:00 2001 From: Matt Flax Date: Thu, 30 Aug 2018 09:38:01 +1000 -Subject: [PATCH 165/703] ASoC: cs4265: Add native 32bit I2S transport +Subject: [PATCH 165/725] ASoC: cs4265: Add native 32bit I2S transport commit be47e75eb1419ffc1d9c26230963fd5fa3055097 upstream. diff --git a/target/linux/brcm2708/patches-4.19/950-0166-configs-Add-SENSOR_GPIO_FAN-m.patch b/target/linux/brcm2708/patches-4.19/950-0166-configs-Add-SENSOR_GPIO_FAN-m.patch index 4b1ab9ebfe..c2b0b52999 100644 --- a/target/linux/brcm2708/patches-4.19/950-0166-configs-Add-SENSOR_GPIO_FAN-m.patch +++ b/target/linux/brcm2708/patches-4.19/950-0166-configs-Add-SENSOR_GPIO_FAN-m.patch @@ -1,7 +1,7 @@ -From b505a24b00c20ca89877ed20599dd4846a7dea83 Mon Sep 17 00:00:00 2001 +From 160ed28c5e56e859e8e1c415e1012a9cab451af1 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 18 Sep 2018 11:03:20 +0100 -Subject: [PATCH 166/703] configs: Add SENSOR_GPIO_FAN=m +Subject: [PATCH 166/725] configs: Add SENSOR_GPIO_FAN=m Signed-off-by: Phil Elwell --- diff --git a/target/linux/brcm2708/patches-4.19/950-0167-BCM270X_DT-Add-gpio-fan-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0167-BCM270X_DT-Add-gpio-fan-overlay.patch index b4c93c0f78..a0e5076590 100644 --- a/target/linux/brcm2708/patches-4.19/950-0167-BCM270X_DT-Add-gpio-fan-overlay.patch +++ b/target/linux/brcm2708/patches-4.19/950-0167-BCM270X_DT-Add-gpio-fan-overlay.patch @@ -1,7 +1,7 @@ -From 0bcb443fca933a3b5e3c16065696a1949ea8f5eb Mon Sep 17 00:00:00 2001 +From 8b33ef9c1afe19c6d7e3f833e73a4bd3afa0225d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 18 Sep 2018 11:08:07 +0100 -Subject: [PATCH 167/703] BCM270X_DT: Add gpio-fan overlay +Subject: [PATCH 167/725] BCM270X_DT: Add gpio-fan overlay Signed-off-by: Phil Elwell --- diff --git a/target/linux/brcm2708/patches-4.19/950-0168-HID-hid-bigbenff-driver-for-BigBen-Interactive-PS3OF.patch b/target/linux/brcm2708/patches-4.19/950-0168-HID-hid-bigbenff-driver-for-BigBen-Interactive-PS3OF.patch index 840969667a..f529f46c9b 100644 --- a/target/linux/brcm2708/patches-4.19/950-0168-HID-hid-bigbenff-driver-for-BigBen-Interactive-PS3OF.patch +++ b/target/linux/brcm2708/patches-4.19/950-0168-HID-hid-bigbenff-driver-for-BigBen-Interactive-PS3OF.patch @@ -1,7 +1,7 @@ -From acb48e74935371e095b98d5d8d4c97a577e46b63 Mon Sep 17 00:00:00 2001 +From 2403affd9cfe04af6326ccc9ba7ee64832b1881d Mon Sep 17 00:00:00 2001 From: Hanno Zulla Date: Thu, 23 Aug 2018 17:03:38 +0200 -Subject: [PATCH 168/703] HID: hid-bigbenff: driver for BigBen Interactive +Subject: [PATCH 168/725] HID: hid-bigbenff: driver for BigBen Interactive PS3OFMINIPAD gamepad commit 256a90ed9e46b270bbc4e15ef05216ff049c3721 upstream. diff --git a/target/linux/brcm2708/patches-4.19/950-0169-configs-Add-CONFIG_HID_BIGBEN_FF-m.patch b/target/linux/brcm2708/patches-4.19/950-0169-configs-Add-CONFIG_HID_BIGBEN_FF-m.patch index ca53ab3a57..395cd4c656 100644 --- a/target/linux/brcm2708/patches-4.19/950-0169-configs-Add-CONFIG_HID_BIGBEN_FF-m.patch +++ b/target/linux/brcm2708/patches-4.19/950-0169-configs-Add-CONFIG_HID_BIGBEN_FF-m.patch @@ -1,7 +1,7 @@ -From 8bf8320c86fd8601dccb0ea6dc677a6d2256a50e Mon Sep 17 00:00:00 2001 +From f8ce06486d1946376160c956d1bc1784c9472fdb Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 24 Sep 2018 14:56:58 +0100 -Subject: [PATCH 169/703] configs: Add CONFIG_HID_BIGBEN_FF=m +Subject: [PATCH 169/725] configs: Add CONFIG_HID_BIGBEN_FF=m See: https://github.com/raspberrypi/linux/issues/2690 diff --git a/target/linux/brcm2708/patches-4.19/950-0170-ASoC-cs4265-Add-a-MIC-pre.-route-2696.patch b/target/linux/brcm2708/patches-4.19/950-0170-ASoC-cs4265-Add-a-MIC-pre.-route-2696.patch index 60824e8715..543b903434 100644 --- a/target/linux/brcm2708/patches-4.19/950-0170-ASoC-cs4265-Add-a-MIC-pre.-route-2696.patch +++ b/target/linux/brcm2708/patches-4.19/950-0170-ASoC-cs4265-Add-a-MIC-pre.-route-2696.patch @@ -1,7 +1,7 @@ -From 42808db6f458ddfca3367ed1167550241d2feb57 Mon Sep 17 00:00:00 2001 +From 8a868455243fec7abfe55d4f6af9eeb94755d4b7 Mon Sep 17 00:00:00 2001 From: Matt Flax Date: Fri, 28 Sep 2018 15:13:28 +1000 -Subject: [PATCH 170/703] ASoC: cs4265: Add a MIC pre. route (#2696) +Subject: [PATCH 170/725] ASoC: cs4265: Add a MIC pre. route (#2696) Commit b0ef5011b981ece1fde8063243a56d3038b87adb upstream. diff --git a/target/linux/brcm2708/patches-4.19/950-0171-Update-gpio-fan-overlay.dts-2711.patch b/target/linux/brcm2708/patches-4.19/950-0171-Update-gpio-fan-overlay.dts-2711.patch index 3aa967dc4f..42c4c10e9f 100644 --- a/target/linux/brcm2708/patches-4.19/950-0171-Update-gpio-fan-overlay.dts-2711.patch +++ b/target/linux/brcm2708/patches-4.19/950-0171-Update-gpio-fan-overlay.dts-2711.patch @@ -1,7 +1,7 @@ -From 45466299c8b39d5d37b3a84c2db74834539ddc4b Mon Sep 17 00:00:00 2001 +From e4c16c37899bacb3a1a10c5830459fc09f3135d9 Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 11 Oct 2018 12:17:20 +0300 -Subject: [PATCH 171/703] Update gpio-fan-overlay.dts (#2711) +Subject: [PATCH 171/725] Update gpio-fan-overlay.dts (#2711) Add references, links, clear details, some typo correction. --- diff --git a/target/linux/brcm2708/patches-4.19/950-0172-drivers-thermal-step_wise-add-support-for-hysteresis.patch b/target/linux/brcm2708/patches-4.19/950-0172-drivers-thermal-step_wise-add-support-for-hysteresis.patch index 77f0d96108..e7dd904a52 100644 --- a/target/linux/brcm2708/patches-4.19/950-0172-drivers-thermal-step_wise-add-support-for-hysteresis.patch +++ b/target/linux/brcm2708/patches-4.19/950-0172-drivers-thermal-step_wise-add-support-for-hysteresis.patch @@ -1,7 +1,7 @@ -From 5d58e2d4e99f2ad2107b3aaca93fda6e758dc1ba Mon Sep 17 00:00:00 2001 +From 158b0f9b48e2974cbe8b83ab0024a05ebcefbe99 Mon Sep 17 00:00:00 2001 From: Ram Chandrasekar Date: Mon, 7 May 2018 11:54:08 -0600 -Subject: [PATCH 172/703] drivers: thermal: step_wise: add support for +Subject: [PATCH 172/725] drivers: thermal: step_wise: add support for hysteresis From: Ram Chandrasekar diff --git a/target/linux/brcm2708/patches-4.19/950-0173-drivers-thermal-step_wise-avoid-throttling-at-hyster.patch b/target/linux/brcm2708/patches-4.19/950-0173-drivers-thermal-step_wise-avoid-throttling-at-hyster.patch index 55da2a0eee..82a02994aa 100644 --- a/target/linux/brcm2708/patches-4.19/950-0173-drivers-thermal-step_wise-avoid-throttling-at-hyster.patch +++ b/target/linux/brcm2708/patches-4.19/950-0173-drivers-thermal-step_wise-avoid-throttling-at-hyster.patch @@ -1,7 +1,7 @@ -From 71eb84af0905c95ae67e957f8af81e131e534ea9 Mon Sep 17 00:00:00 2001 +From e381db8721f2658d7c90183b4685bb62e96db6fe Mon Sep 17 00:00:00 2001 From: Serge Schneider Date: Tue, 2 Oct 2018 11:14:15 +0100 -Subject: [PATCH 173/703] drivers: thermal: step_wise: avoid throttling at +Subject: [PATCH 173/725] drivers: thermal: step_wise: avoid throttling at hysteresis temperature after dropping below it Signed-off-by: Serge Schneider diff --git a/target/linux/brcm2708/patches-4.19/950-0174-hwmon-adjust-rpi-poe-fan-overlay-trip-points.patch b/target/linux/brcm2708/patches-4.19/950-0174-hwmon-adjust-rpi-poe-fan-overlay-trip-points.patch index e26cff416b..0354f418a6 100644 --- a/target/linux/brcm2708/patches-4.19/950-0174-hwmon-adjust-rpi-poe-fan-overlay-trip-points.patch +++ b/target/linux/brcm2708/patches-4.19/950-0174-hwmon-adjust-rpi-poe-fan-overlay-trip-points.patch @@ -1,7 +1,7 @@ -From 981040d773878289ce9cd7bb15a78f4205317ab1 Mon Sep 17 00:00:00 2001 +From 6699b062f9bebb291c65f8402a62e99c71402ed0 Mon Sep 17 00:00:00 2001 From: Serge Schneider Date: Wed, 26 Sep 2018 19:44:59 +0100 -Subject: [PATCH 174/703] hwmon: adjust rpi-poe-fan overlay trip points +Subject: [PATCH 174/725] hwmon: adjust rpi-poe-fan overlay trip points Signed-off-by: Serge Schneider --- diff --git a/target/linux/brcm2708/patches-4.19/950-0175-overlays-add-overrides-for-PoE-HAT-fan-control.patch b/target/linux/brcm2708/patches-4.19/950-0175-overlays-add-overrides-for-PoE-HAT-fan-control.patch index d840ed7da3..19b8aa7ffb 100644 --- a/target/linux/brcm2708/patches-4.19/950-0175-overlays-add-overrides-for-PoE-HAT-fan-control.patch +++ b/target/linux/brcm2708/patches-4.19/950-0175-overlays-add-overrides-for-PoE-HAT-fan-control.patch @@ -1,7 +1,7 @@ -From ca2ef312a9bb95596a2f69186f4ca210a8160c1a Mon Sep 17 00:00:00 2001 +From db562e1eaed352231730eebcdc22b5c305e42338 Mon Sep 17 00:00:00 2001 From: Serge Schneider Date: Tue, 2 Oct 2018 17:13:48 +0100 -Subject: [PATCH 175/703] overlays: add overrides for PoE HAT fan control +Subject: [PATCH 175/725] overlays: add overrides for PoE HAT fan control Signed-off-by: Serge Schneider --- diff --git a/target/linux/brcm2708/patches-4.19/950-0176-overlays-Add-gpio-no-bank0-irq-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0176-overlays-Add-gpio-no-bank0-irq-overlay.patch index 0689e854a7..ea8581bf2f 100644 --- a/target/linux/brcm2708/patches-4.19/950-0176-overlays-Add-gpio-no-bank0-irq-overlay.patch +++ b/target/linux/brcm2708/patches-4.19/950-0176-overlays-Add-gpio-no-bank0-irq-overlay.patch @@ -1,7 +1,7 @@ -From deb8928a66ab048325b52a00c36bd8a69cd63bea Mon Sep 17 00:00:00 2001 +From dc7881193fbee4ac1235d5a87af7d3abef3bee14 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 18 Jul 2018 17:25:00 +0100 -Subject: [PATCH 176/703] overlays: Add gpio-no-bank0-irq overlay +Subject: [PATCH 176/725] overlays: Add gpio-no-bank0-irq overlay See: https://github.com/raspberrypi/linux/issues/2590 diff --git a/target/linux/brcm2708/patches-4.19/950-0177-Add-hy28b-2017-model-device-tree-overlay-2721.patch b/target/linux/brcm2708/patches-4.19/950-0177-Add-hy28b-2017-model-device-tree-overlay-2721.patch index 97d21c9f67..305517578c 100644 --- a/target/linux/brcm2708/patches-4.19/950-0177-Add-hy28b-2017-model-device-tree-overlay-2721.patch +++ b/target/linux/brcm2708/patches-4.19/950-0177-Add-hy28b-2017-model-device-tree-overlay-2721.patch @@ -1,7 +1,7 @@ -From e296ac154f037f09fd100150d8eb113942661f58 Mon Sep 17 00:00:00 2001 +From ea5d66b73d721b0a21d6b3eb677dd8f65cb8a3dd Mon Sep 17 00:00:00 2001 From: Hans-Wilhelm Warlo <5417271+hanswilw@users.noreply.github.com> Date: Tue, 16 Oct 2018 18:20:48 +0200 -Subject: [PATCH 177/703] Add hy28b 2017 model device tree overlay (#2721) +Subject: [PATCH 177/725] Add hy28b 2017 model device tree overlay (#2721) The 2017 version of the hy28b display requires a different initialisation sequence. diff --git a/target/linux/brcm2708/patches-4.19/950-0178-config-Add-CONFIG_USBIP_VUDC.patch b/target/linux/brcm2708/patches-4.19/950-0178-config-Add-CONFIG_USBIP_VUDC.patch index f5d6b7f920..f8ec94d6df 100644 --- a/target/linux/brcm2708/patches-4.19/950-0178-config-Add-CONFIG_USBIP_VUDC.patch +++ b/target/linux/brcm2708/patches-4.19/950-0178-config-Add-CONFIG_USBIP_VUDC.patch @@ -1,7 +1,7 @@ -From b457a3f171ce59b613250751775c56b390995c71 Mon Sep 17 00:00:00 2001 +From e7010b9f0497dd34e8b054b321d82e44925594dc Mon Sep 17 00:00:00 2001 From: popcornmix Date: Thu, 25 Oct 2018 14:08:43 +0100 -Subject: [PATCH 178/703] config: Add CONFIG_USBIP_VUDC +Subject: [PATCH 178/725] config: Add CONFIG_USBIP_VUDC See: https://github.com/raspberrypi/firmware/issues/353 --- diff --git a/target/linux/brcm2708/patches-4.19/950-0179-mmc-bcm2835-sdhost-Recover-from-MMC_SEND_EXT_CSD.patch b/target/linux/brcm2708/patches-4.19/950-0179-mmc-bcm2835-sdhost-Recover-from-MMC_SEND_EXT_CSD.patch index 1dd16f7a32..fd96888680 100644 --- a/target/linux/brcm2708/patches-4.19/950-0179-mmc-bcm2835-sdhost-Recover-from-MMC_SEND_EXT_CSD.patch +++ b/target/linux/brcm2708/patches-4.19/950-0179-mmc-bcm2835-sdhost-Recover-from-MMC_SEND_EXT_CSD.patch @@ -1,7 +1,7 @@ -From 999a38346e7d54c6d8323965e91e2218d0e6d716 Mon Sep 17 00:00:00 2001 +From d5188bb19c7c3a01091e0779a94c67c2b6314005 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 26 Oct 2018 17:29:51 +0100 -Subject: [PATCH 179/703] mmc/bcm2835-sdhost: Recover from MMC_SEND_EXT_CSD +Subject: [PATCH 179/725] mmc/bcm2835-sdhost: Recover from MMC_SEND_EXT_CSD If the user issues an "mmc extcsd read", the SD controller receives what it thinks is a SEND_IF_COND command with an unexpected data block. diff --git a/target/linux/brcm2708/patches-4.19/950-0180-overlays-pi3-disable-bt-Clear-out-bt_pins-node.patch b/target/linux/brcm2708/patches-4.19/950-0180-overlays-pi3-disable-bt-Clear-out-bt_pins-node.patch index f712da8f74..7bca34520b 100644 --- a/target/linux/brcm2708/patches-4.19/950-0180-overlays-pi3-disable-bt-Clear-out-bt_pins-node.patch +++ b/target/linux/brcm2708/patches-4.19/950-0180-overlays-pi3-disable-bt-Clear-out-bt_pins-node.patch @@ -1,7 +1,7 @@ -From 3bbbf9c1d2e2459c9a74adf0e7b771ac2b9f7451 Mon Sep 17 00:00:00 2001 +From 4f60a9f26c17f3722c6cc6b4af149ff8db4f6e47 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 29 Oct 2018 10:38:31 +0000 -Subject: [PATCH 180/703] overlays: pi3-disable-bt: Clear out bt_pins node +Subject: [PATCH 180/725] overlays: pi3-disable-bt: Clear out bt_pins node The pi3-disable-bt overlay does not (and cannot) delete the bt_pins node, but emptying its properties (including brcm,pins) is a way of diff --git a/target/linux/brcm2708/patches-4.19/950-0181-Revert-rtc-pcf8523-properly-handle-oscillator-stop-b.patch b/target/linux/brcm2708/patches-4.19/950-0181-Revert-rtc-pcf8523-properly-handle-oscillator-stop-b.patch index 2ecca9178a..c2fddc3b9a 100644 --- a/target/linux/brcm2708/patches-4.19/950-0181-Revert-rtc-pcf8523-properly-handle-oscillator-stop-b.patch +++ b/target/linux/brcm2708/patches-4.19/950-0181-Revert-rtc-pcf8523-properly-handle-oscillator-stop-b.patch @@ -1,7 +1,7 @@ -From 5e3cd6eeb1af7da0424290cb77e355755e17729c Mon Sep 17 00:00:00 2001 +From 759061b16cf853b38c8cce3688fb8566b3e8b413 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 29 Oct 2018 14:45:45 +0000 -Subject: [PATCH 181/703] Revert "rtc: pcf8523: properly handle oscillator stop +Subject: [PATCH 181/725] Revert "rtc: pcf8523: properly handle oscillator stop bit" This reverts commit ede44c908d44b166a5b6bd7caacd105c2ff5a70f. diff --git a/target/linux/brcm2708/patches-4.19/950-0182-Update-issue-templates-2736.patch b/target/linux/brcm2708/patches-4.19/950-0182-Update-issue-templates-2736.patch index 8d560acb3b..2fa4c6a25b 100644 --- a/target/linux/brcm2708/patches-4.19/950-0182-Update-issue-templates-2736.patch +++ b/target/linux/brcm2708/patches-4.19/950-0182-Update-issue-templates-2736.patch @@ -1,7 +1,7 @@ -From f77461fb11af8f37a15832032c58a256e21ff311 Mon Sep 17 00:00:00 2001 +From 70971c0ca8a15bca1ff755494bc83b161cf363f6 Mon Sep 17 00:00:00 2001 From: James Hughes Date: Fri, 2 Nov 2018 11:55:49 +0000 -Subject: [PATCH 182/703] Update issue templates (#2736) +Subject: [PATCH 182/725] Update issue templates (#2736) --- .github/ISSUE_TEMPLATE/bug_report.md | 34 ++++++++++++++++++++++++++++ diff --git a/target/linux/brcm2708/patches-4.19/950-0183-overlays-uart0-return-GPIOs-14-and-15-to-inputs.patch b/target/linux/brcm2708/patches-4.19/950-0183-overlays-uart0-return-GPIOs-14-and-15-to-inputs.patch index dd1f84547d..ffcc50d765 100644 --- a/target/linux/brcm2708/patches-4.19/950-0183-overlays-uart0-return-GPIOs-14-and-15-to-inputs.patch +++ b/target/linux/brcm2708/patches-4.19/950-0183-overlays-uart0-return-GPIOs-14-and-15-to-inputs.patch @@ -1,7 +1,7 @@ -From bd2af9087e825313f2c2d2cf4ff74c7421a705d2 Mon Sep 17 00:00:00 2001 +From 964ca9ac6a8e55a3563734d0e9c1219bc6e42813 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 7 Nov 2018 17:43:10 +0000 -Subject: [PATCH 183/703] overlays: uart0 - return GPIOs 14 and 15 to inputs +Subject: [PATCH 183/725] overlays: uart0 - return GPIOs 14 and 15 to inputs In the event that alternate pins are used (only useful on Compute Modules), return the standard pins to inputs to avoid double-mapping diff --git a/target/linux/brcm2708/patches-4.19/950-0184-mmc-bcm2835-sdhost-Fix-warnings-on-arm64.patch b/target/linux/brcm2708/patches-4.19/950-0184-mmc-bcm2835-sdhost-Fix-warnings-on-arm64.patch index 1e4e4a2208..e0d6f07da3 100644 --- a/target/linux/brcm2708/patches-4.19/950-0184-mmc-bcm2835-sdhost-Fix-warnings-on-arm64.patch +++ b/target/linux/brcm2708/patches-4.19/950-0184-mmc-bcm2835-sdhost-Fix-warnings-on-arm64.patch @@ -1,7 +1,7 @@ -From 59782472a3e41e591492ef219abb3f0fc082d08f Mon Sep 17 00:00:00 2001 +From cebac10c14079ce87b94a9e7caa77cdbf883f458 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 12 Nov 2018 22:54:40 +0000 -Subject: [PATCH 184/703] mmc: bcm2835-sdhost: Fix warnings on arm64 +Subject: [PATCH 184/725] mmc: bcm2835-sdhost: Fix warnings on arm64 Signed-off-by: Phil Elwell --- diff --git a/target/linux/brcm2708/patches-4.19/950-0185-Fix-warning-in-bcm2835-smi-nand.patch b/target/linux/brcm2708/patches-4.19/950-0185-Fix-warning-in-bcm2835-smi-nand.patch index 4382571f5f..a46a482874 100644 --- a/target/linux/brcm2708/patches-4.19/950-0185-Fix-warning-in-bcm2835-smi-nand.patch +++ b/target/linux/brcm2708/patches-4.19/950-0185-Fix-warning-in-bcm2835-smi-nand.patch @@ -1,7 +1,7 @@ -From bb7479c2adc27bd21e5fae14df21d4f9e89a8aac Mon Sep 17 00:00:00 2001 +From 2a1d1f77ccfc4e5f4b2b4df23504df77d5aceda1 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 12 Nov 2018 22:56:35 +0000 -Subject: [PATCH 185/703] Fix warning in bcm2835-smi-nand +Subject: [PATCH 185/725] Fix warning in bcm2835-smi-nand Signed-off-by: Phil Elwell --- diff --git a/target/linux/brcm2708/patches-4.19/950-0186-media-ov5647-Add-set_fmt-and-get_fmt-calls.patch b/target/linux/brcm2708/patches-4.19/950-0186-media-ov5647-Add-set_fmt-and-get_fmt-calls.patch index 4308d62bb1..9faa1a755c 100644 --- a/target/linux/brcm2708/patches-4.19/950-0186-media-ov5647-Add-set_fmt-and-get_fmt-calls.patch +++ b/target/linux/brcm2708/patches-4.19/950-0186-media-ov5647-Add-set_fmt-and-get_fmt-calls.patch @@ -1,7 +1,7 @@ -From 7ee204d064e56592409ea3ff7ba930a00fe51a0f Mon Sep 17 00:00:00 2001 +From 5d582dbe8344f87fb726b4e35620dc0ca554337f Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 14:55:37 +0000 -Subject: [PATCH 186/703] media: ov5647: Add set_fmt and get_fmt calls. +Subject: [PATCH 186/725] media: ov5647: Add set_fmt and get_fmt calls. There's no way to query the subdevice for the supported resolutions. diff --git a/target/linux/brcm2708/patches-4.19/950-0187-media-Documentation-DT-add-device-tree-for-PWDN-cont.patch b/target/linux/brcm2708/patches-4.19/950-0187-media-Documentation-DT-add-device-tree-for-PWDN-cont.patch index 83fcb1cc91..cb4839c010 100644 --- a/target/linux/brcm2708/patches-4.19/950-0187-media-Documentation-DT-add-device-tree-for-PWDN-cont.patch +++ b/target/linux/brcm2708/patches-4.19/950-0187-media-Documentation-DT-add-device-tree-for-PWDN-cont.patch @@ -1,7 +1,7 @@ -From 3a40a450f896c003be6b4fc7ce020f64716c2e2b Mon Sep 17 00:00:00 2001 +From 31f9d16b849bc50df1a0393a5b858fe3e56e7809 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 14:55:59 +0000 -Subject: [PATCH 187/703] [media] Documentation: DT: add device tree for PWDN +Subject: [PATCH 187/725] [media] Documentation: DT: add device tree for PWDN control Add optional GPIO pwdn to connect to the PWDN line on the sensor. diff --git a/target/linux/brcm2708/patches-4.19/950-0188-media-ov5647-Add-support-for-PWDN-GPIO.patch b/target/linux/brcm2708/patches-4.19/950-0188-media-ov5647-Add-support-for-PWDN-GPIO.patch index 0383fd444c..562d79ea2e 100644 --- a/target/linux/brcm2708/patches-4.19/950-0188-media-ov5647-Add-support-for-PWDN-GPIO.patch +++ b/target/linux/brcm2708/patches-4.19/950-0188-media-ov5647-Add-support-for-PWDN-GPIO.patch @@ -1,7 +1,7 @@ -From 7c6fef835e14a484f24a41f5095bbef492aa433c Mon Sep 17 00:00:00 2001 +From 7330f9a31cb271e4b148bf171cec1ce32c25338a Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 14:56:33 +0000 -Subject: [PATCH 188/703] media: ov5647: Add support for PWDN GPIO. +Subject: [PATCH 188/725] media: ov5647: Add support for PWDN GPIO. Add support for an optional GPIO connected to PWDN on the sensor. diff --git a/target/linux/brcm2708/patches-4.19/950-0189-media-ov5647-Add-support-for-non-continuous-clock-mo.patch b/target/linux/brcm2708/patches-4.19/950-0189-media-ov5647-Add-support-for-non-continuous-clock-mo.patch index e7c976b585..cd091c5b56 100644 --- a/target/linux/brcm2708/patches-4.19/950-0189-media-ov5647-Add-support-for-non-continuous-clock-mo.patch +++ b/target/linux/brcm2708/patches-4.19/950-0189-media-ov5647-Add-support-for-non-continuous-clock-mo.patch @@ -1,7 +1,7 @@ -From d8eb44c8aa81de883c154c46b3323895e6a70a35 Mon Sep 17 00:00:00 2001 +From 39de5418b771d8506e2836fec7d4296983fee954 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 14:56:47 +0000 -Subject: [PATCH 189/703] media: ov5647: Add support for non-continuous clock +Subject: [PATCH 189/725] media: ov5647: Add support for non-continuous clock mode The driver was only supporting continuous clock mode diff --git a/target/linux/brcm2708/patches-4.19/950-0190-media-tc358743-Increase-FIFO-level-to-374.patch b/target/linux/brcm2708/patches-4.19/950-0190-media-tc358743-Increase-FIFO-level-to-374.patch index 6dac072ff6..efae403633 100644 --- a/target/linux/brcm2708/patches-4.19/950-0190-media-tc358743-Increase-FIFO-level-to-374.patch +++ b/target/linux/brcm2708/patches-4.19/950-0190-media-tc358743-Increase-FIFO-level-to-374.patch @@ -1,7 +1,7 @@ -From 74cfa3689511a7befa86ab18ff4d4d9662472c08 Mon Sep 17 00:00:00 2001 +From 9774cb0c44ed8d6394b6cb7c742517a2c7989f09 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 14:56:59 +0000 -Subject: [PATCH 190/703] media: tc358743: Increase FIFO level to 374. +Subject: [PATCH 190/725] media: tc358743: Increase FIFO level to 374. The existing fixed value of 16 worked for UYVY 720P60 over 2 lanes at 594MHz, or UYVY 1080P60 over 4 lanes. (RGB888 diff --git a/target/linux/brcm2708/patches-4.19/950-0191-media-tc358743-fix-connected-active-CSI-2-lane-repor.patch b/target/linux/brcm2708/patches-4.19/950-0191-media-tc358743-fix-connected-active-CSI-2-lane-repor.patch index 48c0121094..fc6fb379b2 100644 --- a/target/linux/brcm2708/patches-4.19/950-0191-media-tc358743-fix-connected-active-CSI-2-lane-repor.patch +++ b/target/linux/brcm2708/patches-4.19/950-0191-media-tc358743-fix-connected-active-CSI-2-lane-repor.patch @@ -1,7 +1,7 @@ -From 5223be7b3a1ee9849730657ade5767bd3f6cf3bd Mon Sep 17 00:00:00 2001 +From 5edf7cf2cfe901e8df2d698eaf518f856308313f Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 21 Sep 2017 17:30:24 +0200 -Subject: [PATCH 191/703] media: tc358743: fix connected/active CSI-2 lane +Subject: [PATCH 191/725] media: tc358743: fix connected/active CSI-2 lane reporting g_mbus_config was supposed to indicate all supported lane numbers, not diff --git a/target/linux/brcm2708/patches-4.19/950-0192-media-tc358743-Add-support-for-972Mbit-s-link-freq.patch b/target/linux/brcm2708/patches-4.19/950-0192-media-tc358743-Add-support-for-972Mbit-s-link-freq.patch index 41e82c46a4..62aba6d887 100644 --- a/target/linux/brcm2708/patches-4.19/950-0192-media-tc358743-Add-support-for-972Mbit-s-link-freq.patch +++ b/target/linux/brcm2708/patches-4.19/950-0192-media-tc358743-Add-support-for-972Mbit-s-link-freq.patch @@ -1,7 +1,7 @@ -From 518faafd6f8b692a3448b6ca6e5e473f55d5360e Mon Sep 17 00:00:00 2001 +From f372eaac56da0592bef997c681b05525f1950745 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 14:57:21 +0000 -Subject: [PATCH 192/703] media: tc358743: Add support for 972Mbit/s link freq. +Subject: [PATCH 192/725] media: tc358743: Add support for 972Mbit/s link freq. Adds register setups for running the CSI lanes at 972Mbit/s, which allows 1080P50 UYVY down 2 lanes. diff --git a/target/linux/brcm2708/patches-4.19/950-0193-media-tc358743-Check-I2C-succeeded-during-probe.patch b/target/linux/brcm2708/patches-4.19/950-0193-media-tc358743-Check-I2C-succeeded-during-probe.patch index 96c55a1d82..8720e358cb 100644 --- a/target/linux/brcm2708/patches-4.19/950-0193-media-tc358743-Check-I2C-succeeded-during-probe.patch +++ b/target/linux/brcm2708/patches-4.19/950-0193-media-tc358743-Check-I2C-succeeded-during-probe.patch @@ -1,7 +1,7 @@ -From 0b01e856bf06b8cd40e0edd37b4f3d47935fe09c Mon Sep 17 00:00:00 2001 +From 02d715b6d479f2f67244056d731f37c5b1475f37 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 14:57:34 +0000 -Subject: [PATCH 193/703] media: tc358743: Check I2C succeeded during probe. +Subject: [PATCH 193/725] media: tc358743: Check I2C succeeded during probe. The probe for the TC358743 reads the CHIPID register from the device and compares it to the expected value of 0. diff --git a/target/linux/brcm2708/patches-4.19/950-0194-media-adv7180-Default-to-the-first-valid-input.patch b/target/linux/brcm2708/patches-4.19/950-0194-media-adv7180-Default-to-the-first-valid-input.patch index 0797cdc92d..c429e19484 100644 --- a/target/linux/brcm2708/patches-4.19/950-0194-media-adv7180-Default-to-the-first-valid-input.patch +++ b/target/linux/brcm2708/patches-4.19/950-0194-media-adv7180-Default-to-the-first-valid-input.patch @@ -1,7 +1,7 @@ -From cb7c2b320a18a8129092e6b452e72716fa083878 Mon Sep 17 00:00:00 2001 +From 156dcf0046229d377ab882094f7ea7b80c411eaa Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 14:57:46 +0000 -Subject: [PATCH 194/703] media: adv7180: Default to the first valid input +Subject: [PATCH 194/725] media: adv7180: Default to the first valid input The hardware default is differential CVBS on AIN1 & 2, which isn't very useful. diff --git a/target/linux/brcm2708/patches-4.19/950-0195-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch b/target/linux/brcm2708/patches-4.19/950-0195-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch index f4a7e6d29d..943d0090ff 100644 --- a/target/linux/brcm2708/patches-4.19/950-0195-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch +++ b/target/linux/brcm2708/patches-4.19/950-0195-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch @@ -1,7 +1,7 @@ -From 17310ae3261766d68d778d353b13970fb6c25810 Mon Sep 17 00:00:00 2001 +From 888202a50fd8f8eb16e57d2f35621bdcaff3c0c5 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 14:57:56 +0000 -Subject: [PATCH 195/703] media: adv7180: Add YPrPb support for ADV7282M +Subject: [PATCH 195/725] media: adv7180: Add YPrPb support for ADV7282M The ADV7282M can support YPbPr on AIN1-3, but this was not selectable from the driver. Add it to the list of diff --git a/target/linux/brcm2708/patches-4.19/950-0196-media-videodev2-Add-helper-defines-for-printing-FOUR.patch b/target/linux/brcm2708/patches-4.19/950-0196-media-videodev2-Add-helper-defines-for-printing-FOUR.patch index 00f394387b..c10a7ab68e 100644 --- a/target/linux/brcm2708/patches-4.19/950-0196-media-videodev2-Add-helper-defines-for-printing-FOUR.patch +++ b/target/linux/brcm2708/patches-4.19/950-0196-media-videodev2-Add-helper-defines-for-printing-FOUR.patch @@ -1,7 +1,7 @@ -From f776604fdd061358ccdc420ba8babcc6fbe76baa Mon Sep 17 00:00:00 2001 +From 37a1cdda51bc5989510ccfe28ccf149a1e5c3f76 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 14:58:08 +0000 -Subject: [PATCH 196/703] media: videodev2: Add helper defines for printing +Subject: [PATCH 196/725] media: videodev2: Add helper defines for printing FOURCCs New helper defines that allow printing of a FOURCC using diff --git a/target/linux/brcm2708/patches-4.19/950-0197-dt-bindings-Document-BCM283x-CSI2-CCP2-receiver.patch b/target/linux/brcm2708/patches-4.19/950-0197-dt-bindings-Document-BCM283x-CSI2-CCP2-receiver.patch index 0194d83ec8..82ead59807 100644 --- a/target/linux/brcm2708/patches-4.19/950-0197-dt-bindings-Document-BCM283x-CSI2-CCP2-receiver.patch +++ b/target/linux/brcm2708/patches-4.19/950-0197-dt-bindings-Document-BCM283x-CSI2-CCP2-receiver.patch @@ -1,7 +1,7 @@ -From 1adfe2e2d3e1cd6a13e32763e347284c08f6707b Mon Sep 17 00:00:00 2001 +From 1f7138cdbf10ca6225ba4b1df6ab4e3c7db996bc Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 14:59:06 +0000 -Subject: [PATCH 197/703] dt-bindings: Document BCM283x CSI2/CCP2 receiver +Subject: [PATCH 197/725] dt-bindings: Document BCM283x CSI2/CCP2 receiver Document the DT bindings for the CSI2/CCP2 receiver peripheral (known as Unicam) on BCM283x SoCs. diff --git a/target/linux/brcm2708/patches-4.19/950-0198-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch b/target/linux/brcm2708/patches-4.19/950-0198-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch index 74db12dc43..4d7fdd85d0 100644 --- a/target/linux/brcm2708/patches-4.19/950-0198-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch +++ b/target/linux/brcm2708/patches-4.19/950-0198-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch @@ -1,7 +1,7 @@ -From f37e8a66e3cd8eafc8b233ae250e2ac159b6870b Mon Sep 17 00:00:00 2001 +From c43d7b532dd2e502330fa1457e5e952ef307504e Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 14:59:22 +0000 -Subject: [PATCH 198/703] media: bcm2835-unicam: Driver for CCP2/CSI2 camera +Subject: [PATCH 198/725] media: bcm2835-unicam: Driver for CCP2/CSI2 camera interface Add driver for the Unicam camera receiver block on diff --git a/target/linux/brcm2708/patches-4.19/950-0199-MAINTAINERS-Add-entry-for-BCM2835-Unicam-driver.patch b/target/linux/brcm2708/patches-4.19/950-0199-MAINTAINERS-Add-entry-for-BCM2835-Unicam-driver.patch index 674f66190b..458079ffc1 100644 --- a/target/linux/brcm2708/patches-4.19/950-0199-MAINTAINERS-Add-entry-for-BCM2835-Unicam-driver.patch +++ b/target/linux/brcm2708/patches-4.19/950-0199-MAINTAINERS-Add-entry-for-BCM2835-Unicam-driver.patch @@ -1,7 +1,7 @@ -From 602457089d7a0ee10df402370a50e469b213da02 Mon Sep 17 00:00:00 2001 +From f363e576611799627bd2f5dbe3cf07c4792ccf84 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 14:59:40 +0000 -Subject: [PATCH 199/703] MAINTAINERS: Add entry for BCM2835 Unicam driver +Subject: [PATCH 199/725] MAINTAINERS: Add entry for BCM2835 Unicam driver Adds entry for the new BCM2835 Unicam (CSI-2 receiver) driver diff --git a/target/linux/brcm2708/patches-4.19/950-0200-defconfig-Enable-Unicam-driver-and-various-sources-o.patch b/target/linux/brcm2708/patches-4.19/950-0200-defconfig-Enable-Unicam-driver-and-various-sources-o.patch index 25113e701f..999efaaca1 100644 --- a/target/linux/brcm2708/patches-4.19/950-0200-defconfig-Enable-Unicam-driver-and-various-sources-o.patch +++ b/target/linux/brcm2708/patches-4.19/950-0200-defconfig-Enable-Unicam-driver-and-various-sources-o.patch @@ -1,7 +1,7 @@ -From 52fca9e13ca8fe69a2c181982bafe09688a42de4 Mon Sep 17 00:00:00 2001 +From ba8758df732d320e5647d23f245a8a134dde92e1 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 14:59:51 +0000 -Subject: [PATCH 200/703] defconfig: Enable Unicam driver and various sources +Subject: [PATCH 200/725] defconfig: Enable Unicam driver and various sources on Pi platforms. Enable: diff --git a/target/linux/brcm2708/patches-4.19/950-0201-media-adv7180-Nasty-hack-to-allow-input-selection.patch b/target/linux/brcm2708/patches-4.19/950-0201-media-adv7180-Nasty-hack-to-allow-input-selection.patch index 5121398048..ed8f6ba624 100644 --- a/target/linux/brcm2708/patches-4.19/950-0201-media-adv7180-Nasty-hack-to-allow-input-selection.patch +++ b/target/linux/brcm2708/patches-4.19/950-0201-media-adv7180-Nasty-hack-to-allow-input-selection.patch @@ -1,7 +1,7 @@ -From b14afe8c3c5c85e3114617eba49751e21b9cbe47 Mon Sep 17 00:00:00 2001 +From 63714d94e345ffeaf2042cfe552fa2a00ed8764c Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 15:00:04 +0000 -Subject: [PATCH 201/703] media: adv7180: Nasty hack to allow input selection. +Subject: [PATCH 201/725] media: adv7180: Nasty hack to allow input selection. Whilst the adv7180 driver support s_routing, nothing else does, and there is a missing lump of framework code to diff --git a/target/linux/brcm2708/patches-4.19/950-0202-BCM283x-DT-Add-CSI-nodes-to-the-device-tree.patch b/target/linux/brcm2708/patches-4.19/950-0202-BCM283x-DT-Add-CSI-nodes-to-the-device-tree.patch index 0741d89975..530d73c0df 100644 --- a/target/linux/brcm2708/patches-4.19/950-0202-BCM283x-DT-Add-CSI-nodes-to-the-device-tree.patch +++ b/target/linux/brcm2708/patches-4.19/950-0202-BCM283x-DT-Add-CSI-nodes-to-the-device-tree.patch @@ -1,7 +1,7 @@ -From e2bd21a4b01db45b8b3ecf5d1e0716c608266065 Mon Sep 17 00:00:00 2001 +From 5672dd9e874730f5a0db0b7697e5f66a7707e130 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 15:00:20 +0000 -Subject: [PATCH 202/703] BCM283x DT: Add CSI nodes to the device tree. +Subject: [PATCH 202/725] BCM283x DT: Add CSI nodes to the device tree. Adds CSI nodes to all the upstream device tree configs diff --git a/target/linux/brcm2708/patches-4.19/950-0203-BCM270X_DT-Add-CSI-defines-for-all-the-downstream-Pi.patch b/target/linux/brcm2708/patches-4.19/950-0203-BCM270X_DT-Add-CSI-defines-for-all-the-downstream-Pi.patch index 7d57872b88..13e8e706b3 100644 --- a/target/linux/brcm2708/patches-4.19/950-0203-BCM270X_DT-Add-CSI-defines-for-all-the-downstream-Pi.patch +++ b/target/linux/brcm2708/patches-4.19/950-0203-BCM270X_DT-Add-CSI-defines-for-all-the-downstream-Pi.patch @@ -1,7 +1,7 @@ -From 1778c46d5542576ba3335c00502c7ccf9035b42c Mon Sep 17 00:00:00 2001 +From 5da3b99c82d6a93af9490e759fa83caecc11550f Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 15:00:45 +0000 -Subject: [PATCH 203/703] BCM270X_DT: Add CSI defines for all the downstream Pi +Subject: [PATCH 203/725] BCM270X_DT: Add CSI defines for all the downstream Pi platforms Adds the CSI device includes for the bcm27xx platform DTS files diff --git a/target/linux/brcm2708/patches-4.19/950-0204-arm-dt-Add-DT-overlays-for-ADV7282M-OV5647-and-TC358.patch b/target/linux/brcm2708/patches-4.19/950-0204-arm-dt-Add-DT-overlays-for-ADV7282M-OV5647-and-TC358.patch index 389c12c25c..33a62936a9 100644 --- a/target/linux/brcm2708/patches-4.19/950-0204-arm-dt-Add-DT-overlays-for-ADV7282M-OV5647-and-TC358.patch +++ b/target/linux/brcm2708/patches-4.19/950-0204-arm-dt-Add-DT-overlays-for-ADV7282M-OV5647-and-TC358.patch @@ -1,7 +1,7 @@ -From db902a4ec646e0ab4dee6168c3d1ef2d121c5865 Mon Sep 17 00:00:00 2001 +From ba7e742c925b5a46ac63fe0c6e3d988eb6ea3e79 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 15:01:59 +0000 -Subject: [PATCH 204/703] arm: dt: Add DT overlays for ADV7282M, OV5647, and +Subject: [PATCH 204/725] arm: dt: Add DT overlays for ADV7282M, OV5647, and TC358743 DT overlays to setup the above devices via i2c_arm and csi1. diff --git a/target/linux/brcm2708/patches-4.19/950-0205-dtoverlays-Add-support-for-ADV7280-M-ADV7281-M-and-A.patch b/target/linux/brcm2708/patches-4.19/950-0205-dtoverlays-Add-support-for-ADV7280-M-ADV7281-M-and-A.patch index add524bfa7..8e7ee7ec18 100644 --- a/target/linux/brcm2708/patches-4.19/950-0205-dtoverlays-Add-support-for-ADV7280-M-ADV7281-M-and-A.patch +++ b/target/linux/brcm2708/patches-4.19/950-0205-dtoverlays-Add-support-for-ADV7280-M-ADV7281-M-and-A.patch @@ -1,7 +1,7 @@ -From 4f00a0c8bef152e0d2f3a382bbe02cc49bc8287e Mon Sep 17 00:00:00 2001 +From 9ab30d7658ba3c6ddf77661b6ca4440ef2d6e38d Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 31 Oct 2018 15:02:18 +0000 -Subject: [PATCH 205/703] dtoverlays: Add support for ADV7280-M, ADV7281-M and +Subject: [PATCH 205/725] dtoverlays: Add support for ADV7280-M, ADV7281-M and ADV7281-MA chips. The driver that supports the ADV7282-M also supports the ADV7280-M, diff --git a/target/linux/brcm2708/patches-4.19/950-0206-Mailbox-firmware-calls-now-use-kmalloc-2749.patch b/target/linux/brcm2708/patches-4.19/950-0206-Mailbox-firmware-calls-now-use-kmalloc-2749.patch index 84b1e77033..f1ca659610 100644 --- a/target/linux/brcm2708/patches-4.19/950-0206-Mailbox-firmware-calls-now-use-kmalloc-2749.patch +++ b/target/linux/brcm2708/patches-4.19/950-0206-Mailbox-firmware-calls-now-use-kmalloc-2749.patch @@ -1,7 +1,7 @@ -From 3090cdd55e3a36f545409814cbee08761b93640c Mon Sep 17 00:00:00 2001 +From 2491694e7b0b8c09b13130f9c165a812b773e57e Mon Sep 17 00:00:00 2001 From: James Hughes Date: Tue, 13 Nov 2018 17:27:00 +0000 -Subject: [PATCH 206/703] Mailbox firmware calls now use kmalloc (#2749) +Subject: [PATCH 206/725] Mailbox firmware calls now use kmalloc (#2749) A previous change moved away from variable stack allocation of a data buffer to a fixed maximum size. diff --git a/target/linux/brcm2708/patches-4.19/950-0207-vcsm-Fix-an-NULL-dereference-in-the-import_dmabuf-er.patch b/target/linux/brcm2708/patches-4.19/950-0207-vcsm-Fix-an-NULL-dereference-in-the-import_dmabuf-er.patch index 656d248467..38e751c845 100644 --- a/target/linux/brcm2708/patches-4.19/950-0207-vcsm-Fix-an-NULL-dereference-in-the-import_dmabuf-er.patch +++ b/target/linux/brcm2708/patches-4.19/950-0207-vcsm-Fix-an-NULL-dereference-in-the-import_dmabuf-er.patch @@ -1,7 +1,7 @@ -From fb5cef781e09bb78ca095f8f5780952f996115f1 Mon Sep 17 00:00:00 2001 +From c050abb666638d8f9eaa7b5557713e7d9335495f Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 14 Nov 2018 11:54:46 +0000 -Subject: [PATCH 207/703] vcsm: Fix an NULL dereference in the import_dmabuf +Subject: [PATCH 207/725] vcsm: Fix an NULL dereference in the import_dmabuf error path resource was dereferenced even though it was NULL. diff --git a/target/linux/brcm2708/patches-4.19/950-0208-Update-README-2750.patch b/target/linux/brcm2708/patches-4.19/950-0208-Update-README-2750.patch index 032d91ebad..44efc2ba1c 100644 --- a/target/linux/brcm2708/patches-4.19/950-0208-Update-README-2750.patch +++ b/target/linux/brcm2708/patches-4.19/950-0208-Update-README-2750.patch @@ -1,7 +1,7 @@ -From 150489867949c6059436b7f96f36b11c5e75692a Mon Sep 17 00:00:00 2001 +From 74e24f7ba3e0443ffc4d026e96848c9ec51e2dcf Mon Sep 17 00:00:00 2001 From: James Hughes Date: Tue, 13 Nov 2018 16:51:21 +0000 -Subject: [PATCH 208/703] Update README (#2750) +Subject: [PATCH 208/725] Update README (#2750) Small update to the DT blob docs to include the axiperf option. diff --git a/target/linux/brcm2708/patches-4.19/950-0209-overlays-Remove-superfluous-address-size-cells.patch b/target/linux/brcm2708/patches-4.19/950-0209-overlays-Remove-superfluous-address-size-cells.patch index 23c4b4afa6..6edbff4cb7 100644 --- a/target/linux/brcm2708/patches-4.19/950-0209-overlays-Remove-superfluous-address-size-cells.patch +++ b/target/linux/brcm2708/patches-4.19/950-0209-overlays-Remove-superfluous-address-size-cells.patch @@ -1,7 +1,7 @@ -From 18ac45909a08b7d4a67a4863a1a4c5e5ea7475dd Mon Sep 17 00:00:00 2001 +From 755f5c2690bd5c2b4db803600815cb1007057326 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 14 Nov 2018 09:53:25 +0000 -Subject: [PATCH 209/703] overlays: Remove superfluous #address/size-cells +Subject: [PATCH 209/725] overlays: Remove superfluous #address/size-cells Newer versions of dtc warn about unnecessary usage of #address-cells and #size-cells, so remove them. diff --git a/target/linux/brcm2708/patches-4.19/950-0210-Revert-ASoC-wm8804-MCLK-configuration-options-32-bit.patch b/target/linux/brcm2708/patches-4.19/950-0210-Revert-ASoC-wm8804-MCLK-configuration-options-32-bit.patch index 9c9085272e..4fe41c81cc 100644 --- a/target/linux/brcm2708/patches-4.19/950-0210-Revert-ASoC-wm8804-MCLK-configuration-options-32-bit.patch +++ b/target/linux/brcm2708/patches-4.19/950-0210-Revert-ASoC-wm8804-MCLK-configuration-options-32-bit.patch @@ -1,7 +1,7 @@ -From 636b64caee57e3afbe0c92c723ff266c9d4391b1 Mon Sep 17 00:00:00 2001 +From dbe949065c6b3de54cc172f6b2a906135392a4c1 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 18 Nov 2018 13:21:26 +0100 -Subject: [PATCH 210/703] Revert "ASoC: wm8804: MCLK configuration options, +Subject: [PATCH 210/725] Revert "ASoC: wm8804: MCLK configuration options, 32-bit" This reverts commit 3b12dcf797f5a4635aecd7f5c090dc507b124ffd. diff --git a/target/linux/brcm2708/patches-4.19/950-0211-rpi-wm8804-soundcard-drop-PWRDN-register-writes.patch b/target/linux/brcm2708/patches-4.19/950-0211-rpi-wm8804-soundcard-drop-PWRDN-register-writes.patch index c3eb817354..734cd686a8 100644 --- a/target/linux/brcm2708/patches-4.19/950-0211-rpi-wm8804-soundcard-drop-PWRDN-register-writes.patch +++ b/target/linux/brcm2708/patches-4.19/950-0211-rpi-wm8804-soundcard-drop-PWRDN-register-writes.patch @@ -1,7 +1,7 @@ -From 3ee2530bf8c00154ba00eb70bbb6c0276fbb0ca2 Mon Sep 17 00:00:00 2001 +From a93fcdaf72291fea4661690cc35e1a45834e3cb7 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 18 Nov 2018 15:24:16 +0100 -Subject: [PATCH 211/703] rpi-wm8804-soundcard: drop PWRDN register writes +Subject: [PATCH 211/725] rpi-wm8804-soundcard: drop PWRDN register writes Since kernel 4.0 the PWRDN register bits are under DAPM control from the wm8804 driver. diff --git a/target/linux/brcm2708/patches-4.19/950-0212-rpi-wm8804-soundcard-configure-wm8804-clocks-only-on.patch b/target/linux/brcm2708/patches-4.19/950-0212-rpi-wm8804-soundcard-configure-wm8804-clocks-only-on.patch index 2c38804c42..915631f8fc 100644 --- a/target/linux/brcm2708/patches-4.19/950-0212-rpi-wm8804-soundcard-configure-wm8804-clocks-only-on.patch +++ b/target/linux/brcm2708/patches-4.19/950-0212-rpi-wm8804-soundcard-configure-wm8804-clocks-only-on.patch @@ -1,7 +1,7 @@ -From c56c1c63927b4fafb51b45df92d6a58eeb08141a Mon Sep 17 00:00:00 2001 +From cf634513d2b238ae041d4fd836e48c63b94c0e6b Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 18 Nov 2018 15:32:28 +0100 -Subject: [PATCH 212/703] rpi-wm8804-soundcard: configure wm8804 clocks only on +Subject: [PATCH 212/725] rpi-wm8804-soundcard: configure wm8804 clocks only on rate change This should avoid clicks when stopping and immediately afterwards diff --git a/target/linux/brcm2708/patches-4.19/950-0213-dtoverlays-Add-i2c-on-0-1-option-to-TC358743-ADV7282.patch b/target/linux/brcm2708/patches-4.19/950-0213-dtoverlays-Add-i2c-on-0-1-option-to-TC358743-ADV7282.patch index da1d763d5e..824a2e9a97 100644 --- a/target/linux/brcm2708/patches-4.19/950-0213-dtoverlays-Add-i2c-on-0-1-option-to-TC358743-ADV7282.patch +++ b/target/linux/brcm2708/patches-4.19/950-0213-dtoverlays-Add-i2c-on-0-1-option-to-TC358743-ADV7282.patch @@ -1,7 +1,7 @@ -From 0676c7a6270df8f3bdc0cfee0025959e155c8c2a Mon Sep 17 00:00:00 2001 +From c305b2c14d9ec6f297062a0410010325d783eec6 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Mon, 26 Nov 2018 17:02:15 +0000 -Subject: [PATCH 213/703] dtoverlays: Add i2c on 0&1 option to TC358743, +Subject: [PATCH 213/725] dtoverlays: Add i2c on 0&1 option to TC358743, ADV7282 and OV5647 Adds the option of configuring i2c0 to be on GPIOs 0&1 as diff --git a/target/linux/brcm2708/patches-4.19/950-0214-overlays-Update-upstream-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0214-overlays-Update-upstream-overlay.patch index 00991ea720..2e6aa87d83 100644 --- a/target/linux/brcm2708/patches-4.19/950-0214-overlays-Update-upstream-overlay.patch +++ b/target/linux/brcm2708/patches-4.19/950-0214-overlays-Update-upstream-overlay.patch @@ -1,7 +1,7 @@ -From dcc96e7fc22e361aa7f242dd3ca6db1f04a4c364 Mon Sep 17 00:00:00 2001 +From be3c95b4f638fc037188705615fabe0d3f25e72c Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 26 Nov 2018 20:15:16 +0000 -Subject: [PATCH 214/703] overlays: Update upstream overlay +Subject: [PATCH 214/725] overlays: Update upstream overlay The vc4-kms-v3d overlay gained an extra fragment enabling the txp node, so rebuild the upstream overlay to match. diff --git a/target/linux/brcm2708/patches-4.19/950-0215-BCM2708_DT-update-firmware-node-binding.patch b/target/linux/brcm2708/patches-4.19/950-0215-BCM2708_DT-update-firmware-node-binding.patch index b77f0800f1..4a08726525 100644 --- a/target/linux/brcm2708/patches-4.19/950-0215-BCM2708_DT-update-firmware-node-binding.patch +++ b/target/linux/brcm2708/patches-4.19/950-0215-BCM2708_DT-update-firmware-node-binding.patch @@ -1,7 +1,7 @@ -From 2a98edd2e5a5477d9649f0682c9b195c8b6c7656 Mon Sep 17 00:00:00 2001 +From 16bf1291c3ffcdee88ee4838b2aa77f18bcfdd02 Mon Sep 17 00:00:00 2001 From: Nicolas Saenz Julienne Date: Wed, 28 Nov 2018 10:36:01 +0100 -Subject: [PATCH 215/703] BCM2708_DT: update firmware node binding +Subject: [PATCH 215/725] BCM2708_DT: update firmware node binding The upstreamed version of the firmware node has been updated to present it as a "simple-bus". We need to get this in order to accomodate other diff --git a/target/linux/brcm2708/patches-4.19/950-0216-BCM2710_DT-fix-gpio-expander-bindings.patch b/target/linux/brcm2708/patches-4.19/950-0216-BCM2710_DT-fix-gpio-expander-bindings.patch index 0524f980c0..2df216f066 100644 --- a/target/linux/brcm2708/patches-4.19/950-0216-BCM2710_DT-fix-gpio-expander-bindings.patch +++ b/target/linux/brcm2708/patches-4.19/950-0216-BCM2710_DT-fix-gpio-expander-bindings.patch @@ -1,7 +1,7 @@ -From 57fdcf2049630157495c84a1440632c476016687 Mon Sep 17 00:00:00 2001 +From d167329afba66f1c7ac58a60941f6ee716e303b2 Mon Sep 17 00:00:00 2001 From: Nicolas Saenz Julienne Date: Tue, 27 Nov 2018 16:59:10 +0100 -Subject: [PATCH 216/703] BCM2710_DT: fix gpio expander bindings +Subject: [PATCH 216/725] BCM2710_DT: fix gpio expander bindings The upstreamed driver for the GPIO expander expects to be a children of the "firmware" node. diff --git a/target/linux/brcm2708/patches-4.19/950-0217-ARM-dts-bcm283x-The-lan7515-PHY-node-has-moved.patch b/target/linux/brcm2708/patches-4.19/950-0217-ARM-dts-bcm283x-The-lan7515-PHY-node-has-moved.patch index 9f0077cd0f..9073a2e834 100644 --- a/target/linux/brcm2708/patches-4.19/950-0217-ARM-dts-bcm283x-The-lan7515-PHY-node-has-moved.patch +++ b/target/linux/brcm2708/patches-4.19/950-0217-ARM-dts-bcm283x-The-lan7515-PHY-node-has-moved.patch @@ -1,7 +1,7 @@ -From 1606baa0882db5b08b493b59eaa2377703e536d2 Mon Sep 17 00:00:00 2001 +From 3cb3a4cf65c1daf812e5b29447e3282e953f308b Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 27 Nov 2018 16:33:31 +0000 -Subject: [PATCH 217/703] ARM: dts: bcm283x: The lan7515 PHY node has moved +Subject: [PATCH 217/725] ARM: dts: bcm283x: The lan7515 PHY node has moved The DT node describing the LAN7800s PHY has now moved inside an "mdio" node. Update the DT declarations accordingly. diff --git a/target/linux/brcm2708/patches-4.19/950-0218-net-lan78xx-Support-auto-downshift-to-100Mb-s.patch b/target/linux/brcm2708/patches-4.19/950-0218-net-lan78xx-Support-auto-downshift-to-100Mb-s.patch index 516ccf6cd0..e4954e4f43 100644 --- a/target/linux/brcm2708/patches-4.19/950-0218-net-lan78xx-Support-auto-downshift-to-100Mb-s.patch +++ b/target/linux/brcm2708/patches-4.19/950-0218-net-lan78xx-Support-auto-downshift-to-100Mb-s.patch @@ -1,7 +1,7 @@ -From cfbb056c0c1445496f3434daf8324cad652d09be Mon Sep 17 00:00:00 2001 +From 0c5f8dac2daa64a5bc4793ec5c39004ae077b739 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 26 Nov 2018 19:46:58 +0000 -Subject: [PATCH 218/703] net: lan78xx: Support auto-downshift to 100Mb/s +Subject: [PATCH 218/725] net: lan78xx: Support auto-downshift to 100Mb/s Ethernet cables with faulty or missing pairs (specifically pairs C and D) allow auto-negotiation to 1000Mbs, but do not support the successful diff --git a/target/linux/brcm2708/patches-4.19/950-0219-dt-bindings-Document-microchip-downshift-after.patch b/target/linux/brcm2708/patches-4.19/950-0219-dt-bindings-Document-microchip-downshift-after.patch index 36fc3efcbb..bd2664a167 100644 --- a/target/linux/brcm2708/patches-4.19/950-0219-dt-bindings-Document-microchip-downshift-after.patch +++ b/target/linux/brcm2708/patches-4.19/950-0219-dt-bindings-Document-microchip-downshift-after.patch @@ -1,7 +1,7 @@ -From c8fee0e0a910f0286d6aa059b27c4d59109b978a Mon Sep 17 00:00:00 2001 +From 557a6998397903dd9416fdc717fa8016ef6b6d31 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 28 Nov 2018 15:51:41 +0000 -Subject: [PATCH 219/703] dt-bindings: Document microchip,downshift-after +Subject: [PATCH 219/725] dt-bindings: Document microchip,downshift-after Document the optional downshift-after property of the lan78xx's PHY. diff --git a/target/linux/brcm2708/patches-4.19/950-0220-ARM-dts-bcm283x-Set-downshift-after-for-Pi-3B.patch b/target/linux/brcm2708/patches-4.19/950-0220-ARM-dts-bcm283x-Set-downshift-after-for-Pi-3B.patch index 58be887ca2..92eeef42ef 100644 --- a/target/linux/brcm2708/patches-4.19/950-0220-ARM-dts-bcm283x-Set-downshift-after-for-Pi-3B.patch +++ b/target/linux/brcm2708/patches-4.19/950-0220-ARM-dts-bcm283x-Set-downshift-after-for-Pi-3B.patch @@ -1,7 +1,7 @@ -From 464f47a7c83ea253304b7fd43f56302db8071593 Mon Sep 17 00:00:00 2001 +From 1ee1b7cac821e90ac203c4274623fc03154be42d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 27 Nov 2018 16:55:14 +0000 -Subject: [PATCH 220/703] ARM: dts: bcm283x: Set downshift-after for Pi 3B+ +Subject: [PATCH 220/725] ARM: dts: bcm283x: Set downshift-after for Pi 3B+ Enable the auto-downshift feature on Raspberry Pi 3B+ so that a link can eventually be established using a cable with pairs C and/or D diff --git a/target/linux/brcm2708/patches-4.19/950-0221-BCM270X_DT-Add-new-Ethernet-DT-parameters.patch b/target/linux/brcm2708/patches-4.19/950-0221-BCM270X_DT-Add-new-Ethernet-DT-parameters.patch index 4b40e2f4d9..5f106d7963 100644 --- a/target/linux/brcm2708/patches-4.19/950-0221-BCM270X_DT-Add-new-Ethernet-DT-parameters.patch +++ b/target/linux/brcm2708/patches-4.19/950-0221-BCM270X_DT-Add-new-Ethernet-DT-parameters.patch @@ -1,7 +1,7 @@ -From 64c215470c985bd740e378cc3cd6963e15f0a927 Mon Sep 17 00:00:00 2001 +From 398295a34e3ee4b8817f868b4b81ae0462e6abe0 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 27 Nov 2018 16:56:50 +0000 -Subject: [PATCH 221/703] BCM270X_DT: Add new Ethernet DT parameters +Subject: [PATCH 221/725] BCM270X_DT: Add new Ethernet DT parameters Add "eth_downshift_after" DT parameter to allow the delay before the downshift to be specified. The default is 2 auto-negotiation cycles, diff --git a/target/linux/brcm2708/patches-4.19/950-0222-BCM270X_DT-Mark-eth_downshift_after-as-an-integer.patch b/target/linux/brcm2708/patches-4.19/950-0222-BCM270X_DT-Mark-eth_downshift_after-as-an-integer.patch index 265aee7e6d..ecde8625f9 100644 --- a/target/linux/brcm2708/patches-4.19/950-0222-BCM270X_DT-Mark-eth_downshift_after-as-an-integer.patch +++ b/target/linux/brcm2708/patches-4.19/950-0222-BCM270X_DT-Mark-eth_downshift_after-as-an-integer.patch @@ -1,7 +1,7 @@ -From 50086a7018911acdd58d627050127bfa7c5ec7de Mon Sep 17 00:00:00 2001 +From cb156dbcbd7fd138d0abb96855e2e472cb1ba3d3 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 29 Nov 2018 16:00:22 +0000 -Subject: [PATCH 222/703] BCM270X_DT: Mark eth_downshift_after as an integer +Subject: [PATCH 222/725] BCM270X_DT: Mark eth_downshift_after as an integer Signed-off-by: Phil Elwell --- diff --git a/target/linux/brcm2708/patches-4.19/950-0223-dwc-otg-FIQ-Fix-bad-mode-in-data-abort-handler.patch b/target/linux/brcm2708/patches-4.19/950-0223-dwc-otg-FIQ-Fix-bad-mode-in-data-abort-handler.patch index 1bf0b58c40..407c4af4ff 100644 --- a/target/linux/brcm2708/patches-4.19/950-0223-dwc-otg-FIQ-Fix-bad-mode-in-data-abort-handler.patch +++ b/target/linux/brcm2708/patches-4.19/950-0223-dwc-otg-FIQ-Fix-bad-mode-in-data-abort-handler.patch @@ -1,7 +1,7 @@ -From 71ffaebfc05366238b7b3777e572dc77ec6f78f6 Mon Sep 17 00:00:00 2001 +From e0cb60557d0127240de57893416068d60e90757a Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 16 Jul 2018 14:40:13 +0100 -Subject: [PATCH 223/703] dwc-otg: FIQ: Fix "bad mode in data abort handler" +Subject: [PATCH 223/725] dwc-otg: FIQ: Fix "bad mode in data abort handler" Create a semi-static mapping for the USB registers early in the boot process, before additional kernel threads are started, so all threads diff --git a/target/linux/brcm2708/patches-4.19/950-0224-lirc-rpi-Remove-in-favour-of-gpio-ir.patch b/target/linux/brcm2708/patches-4.19/950-0224-lirc-rpi-Remove-in-favour-of-gpio-ir.patch index 2aafb20c6e..472ffcad55 100644 --- a/target/linux/brcm2708/patches-4.19/950-0224-lirc-rpi-Remove-in-favour-of-gpio-ir.patch +++ b/target/linux/brcm2708/patches-4.19/950-0224-lirc-rpi-Remove-in-favour-of-gpio-ir.patch @@ -1,7 +1,7 @@ -From e2c77b86039e8f16d6dd75e06a50dc7290e95233 Mon Sep 17 00:00:00 2001 +From 06a217704d5b7acc8680b9ff4cb837f8dd7b4b5d Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 30 Nov 2018 18:55:23 +0000 -Subject: [PATCH 224/703] lirc-rpi: Remove in favour of gpio-ir +Subject: [PATCH 224/725] lirc-rpi: Remove in favour of gpio-ir --- arch/arm/boot/dts/overlays/Makefile | 1 - diff --git a/target/linux/brcm2708/patches-4.19/950-0225-media-bcm2835-unicam-Pass-through-the-colorspace-on-.patch b/target/linux/brcm2708/patches-4.19/950-0225-media-bcm2835-unicam-Pass-through-the-colorspace-on-.patch index dd4e3c79dd..33c9323e5f 100644 --- a/target/linux/brcm2708/patches-4.19/950-0225-media-bcm2835-unicam-Pass-through-the-colorspace-on-.patch +++ b/target/linux/brcm2708/patches-4.19/950-0225-media-bcm2835-unicam-Pass-through-the-colorspace-on-.patch @@ -1,7 +1,7 @@ -From b30282f720fddb3175a46726bd18ac691b172d32 Mon Sep 17 00:00:00 2001 +From 9e280b87eaf77735f0b9d1fd56a72ec11e7230cb Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 22 Nov 2018 17:28:02 +0000 -Subject: [PATCH 225/703] media: bcm2835-unicam: Pass through the colorspace on +Subject: [PATCH 225/725] media: bcm2835-unicam: Pass through the colorspace on try_fmt The current colorspace was always returned from try_fmt for no diff --git a/target/linux/brcm2708/patches-4.19/950-0226-media-tc358743-Return-an-appropriate-colorspace-from.patch b/target/linux/brcm2708/patches-4.19/950-0226-media-tc358743-Return-an-appropriate-colorspace-from.patch index 24a7d10e02..3e7512b749 100644 --- a/target/linux/brcm2708/patches-4.19/950-0226-media-tc358743-Return-an-appropriate-colorspace-from.patch +++ b/target/linux/brcm2708/patches-4.19/950-0226-media-tc358743-Return-an-appropriate-colorspace-from.patch @@ -1,7 +1,7 @@ -From 8f84df14dc88580bfdce95999ab0167d3871ff7c Mon Sep 17 00:00:00 2001 +From 88ebe04c5b8feff596e3d373eb3d779fa13ff8c9 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 22 Nov 2018 17:31:06 +0000 -Subject: [PATCH 226/703] media: tc358743: Return an appropriate colorspace +Subject: [PATCH 226/725] media: tc358743: Return an appropriate colorspace from tc358743_set_fmt When calling tc358743_set_fmt, the code was calling tc358743_get_fmt diff --git a/target/linux/brcm2708/patches-4.19/950-0227-staging-bcm2835-camera-fix-module-autoloading.patch b/target/linux/brcm2708/patches-4.19/950-0227-staging-bcm2835-camera-fix-module-autoloading.patch index 7c6052b36f..66b1a98541 100644 --- a/target/linux/brcm2708/patches-4.19/950-0227-staging-bcm2835-camera-fix-module-autoloading.patch +++ b/target/linux/brcm2708/patches-4.19/950-0227-staging-bcm2835-camera-fix-module-autoloading.patch @@ -1,7 +1,7 @@ -From 99b24dda7eb97f1c094abc942241ff1a7428b639 Mon Sep 17 00:00:00 2001 +From d248e54f2c13facdde31e13ab8c3acb26f63a8cd Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sat, 20 Oct 2018 19:26:18 +0200 -Subject: [PATCH 227/703] staging: bcm2835-camera: fix module autoloading +Subject: [PATCH 227/725] staging: bcm2835-camera: fix module autoloading In order to make the module bcm2835-camera load automatically, we need to add a module alias. diff --git a/target/linux/brcm2708/patches-4.19/950-0228-staging-bcm2835-camera-Move-module-info-to-the-end.patch b/target/linux/brcm2708/patches-4.19/950-0228-staging-bcm2835-camera-Move-module-info-to-the-end.patch index d3212a0067..e12e49fc28 100644 --- a/target/linux/brcm2708/patches-4.19/950-0228-staging-bcm2835-camera-Move-module-info-to-the-end.patch +++ b/target/linux/brcm2708/patches-4.19/950-0228-staging-bcm2835-camera-Move-module-info-to-the-end.patch @@ -1,7 +1,7 @@ -From 9aa76a475dad23bcec194a08d063c9b19e54187e Mon Sep 17 00:00:00 2001 +From 87c91dbd458eb312449a9b300e13d7ca43ba9105 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sat, 20 Oct 2018 19:31:00 +0200 -Subject: [PATCH 228/703] staging: bcm2835-camera: Move module info to the end +Subject: [PATCH 228/725] staging: bcm2835-camera: Move module info to the end In order to have this more consistent between the vc04 services move the module information to the end of the file. diff --git a/target/linux/brcm2708/patches-4.19/950-0229-staging-vchiq_arm-Fix-platform-device-unregistration.patch b/target/linux/brcm2708/patches-4.19/950-0229-staging-vchiq_arm-Fix-platform-device-unregistration.patch index 4c2a3482a1..bdf3f274cb 100644 --- a/target/linux/brcm2708/patches-4.19/950-0229-staging-vchiq_arm-Fix-platform-device-unregistration.patch +++ b/target/linux/brcm2708/patches-4.19/950-0229-staging-vchiq_arm-Fix-platform-device-unregistration.patch @@ -1,7 +1,7 @@ -From e70e5563e9db4cb2cf081f40373b0b0df40b1c5c Mon Sep 17 00:00:00 2001 +From f5072609c720b1f50098d69e208113735f6b31fa Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sat, 13 Oct 2018 20:51:23 +0200 -Subject: [PATCH 229/703] staging: vchiq_arm: Fix platform device +Subject: [PATCH 229/725] staging: vchiq_arm: Fix platform device unregistration In error case platform_device_register_data would return an ERR_PTR diff --git a/target/linux/brcm2708/patches-4.19/950-0230-staging-vchiq_arm-Fix-camera-device-registration.patch b/target/linux/brcm2708/patches-4.19/950-0230-staging-vchiq_arm-Fix-camera-device-registration.patch index 181e339b4f..4d37bc0774 100644 --- a/target/linux/brcm2708/patches-4.19/950-0230-staging-vchiq_arm-Fix-camera-device-registration.patch +++ b/target/linux/brcm2708/patches-4.19/950-0230-staging-vchiq_arm-Fix-camera-device-registration.patch @@ -1,7 +1,7 @@ -From 1134ea85e8c3870ee3d31bb6acb4326d0f674d6a Mon Sep 17 00:00:00 2001 +From c9adbf27cebcbd0bd144eb3c282f9d9115121526 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Mon, 22 Oct 2018 15:16:51 +0200 -Subject: [PATCH 230/703] staging: vchiq_arm: Fix camera device registration +Subject: [PATCH 230/725] staging: vchiq_arm: Fix camera device registration Since the camera driver isn't probed via DT, we need to properly setup DMA. diff --git a/target/linux/brcm2708/patches-4.19/950-0231-staging-vchiq_arm-Register-a-platform-device-for-the.patch b/target/linux/brcm2708/patches-4.19/950-0231-staging-vchiq_arm-Register-a-platform-device-for-the.patch index 30bea2f204..ff17bf85ea 100644 --- a/target/linux/brcm2708/patches-4.19/950-0231-staging-vchiq_arm-Register-a-platform-device-for-the.patch +++ b/target/linux/brcm2708/patches-4.19/950-0231-staging-vchiq_arm-Register-a-platform-device-for-the.patch @@ -1,7 +1,7 @@ -From 1f7a4bfbb20d1775eac5b7db7545c0ab35b7642d Mon Sep 17 00:00:00 2001 +From 9a52240005032514c0df20bbcbac6a2efdc1ba04 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sat, 20 Oct 2018 20:25:41 +0200 -Subject: [PATCH 231/703] staging: vchiq_arm: Register a platform device for +Subject: [PATCH 231/725] staging: vchiq_arm: Register a platform device for the audio driver Signed-off-by: Stefan Wahren diff --git a/target/linux/brcm2708/patches-4.19/950-0232-staging-bcm2835-audio-Enable-compile-test.patch b/target/linux/brcm2708/patches-4.19/950-0232-staging-bcm2835-audio-Enable-compile-test.patch index d04e18b8a9..3ed2a933fe 100644 --- a/target/linux/brcm2708/patches-4.19/950-0232-staging-bcm2835-audio-Enable-compile-test.patch +++ b/target/linux/brcm2708/patches-4.19/950-0232-staging-bcm2835-audio-Enable-compile-test.patch @@ -1,7 +1,7 @@ -From 4055954ff0be5159876c33f4841be686b4f730ab Mon Sep 17 00:00:00 2001 +From fb56caeb8f51fd08ff898bb679ac53bb5d9eb04e Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sat, 13 Oct 2018 20:19:13 +0200 -Subject: [PATCH 232/703] staging: bcm2835-audio: Enable compile test +Subject: [PATCH 232/725] staging: bcm2835-audio: Enable compile test Enable the compilation test for bcm2835-audio. diff --git a/target/linux/brcm2708/patches-4.19/950-0233-staging-bcm2835-audio-use-module_platform_driver-mac.patch b/target/linux/brcm2708/patches-4.19/950-0233-staging-bcm2835-audio-use-module_platform_driver-mac.patch index 27537ec5a3..2c7fe6842e 100644 --- a/target/linux/brcm2708/patches-4.19/950-0233-staging-bcm2835-audio-use-module_platform_driver-mac.patch +++ b/target/linux/brcm2708/patches-4.19/950-0233-staging-bcm2835-audio-use-module_platform_driver-mac.patch @@ -1,7 +1,7 @@ -From ff285113caa9279101db3b6eb31dfc3d94e57d3d Mon Sep 17 00:00:00 2001 +From 57d6f481243f83f9ee1d62e0581d20d54005fb90 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Thu, 18 Oct 2018 19:47:29 +0200 -Subject: [PATCH 233/703] staging: bcm2835-audio: use module_platform_driver() +Subject: [PATCH 233/725] staging: bcm2835-audio: use module_platform_driver() macro There is not much value behind this boilerplate, so use diff --git a/target/linux/brcm2708/patches-4.19/950-0234-staging-bcm2835-audio-Drop-DT-dependency.patch b/target/linux/brcm2708/patches-4.19/950-0234-staging-bcm2835-audio-Drop-DT-dependency.patch index 29cd60732e..e0ee2e4b57 100644 --- a/target/linux/brcm2708/patches-4.19/950-0234-staging-bcm2835-audio-Drop-DT-dependency.patch +++ b/target/linux/brcm2708/patches-4.19/950-0234-staging-bcm2835-audio-Drop-DT-dependency.patch @@ -1,7 +1,7 @@ -From 4f0fb18ee7b5479b673257d15fe7bec3b3d90aac Mon Sep 17 00:00:00 2001 +From c396f36045c306f7d928c487455d0450585bbf4e Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Thu, 18 Oct 2018 19:54:01 +0200 -Subject: [PATCH 234/703] staging: bcm2835-audio: Drop DT dependency +Subject: [PATCH 234/725] staging: bcm2835-audio: Drop DT dependency Just like the bcm2835-video make this a platform driver which is probed by vchiq. In order to change the number of channels use a module diff --git a/target/linux/brcm2708/patches-4.19/950-0235-staging-bcm2835-camera-Provide-more-specific-probe-e.patch b/target/linux/brcm2708/patches-4.19/950-0235-staging-bcm2835-camera-Provide-more-specific-probe-e.patch index c346816db5..113be4d892 100644 --- a/target/linux/brcm2708/patches-4.19/950-0235-staging-bcm2835-camera-Provide-more-specific-probe-e.patch +++ b/target/linux/brcm2708/patches-4.19/950-0235-staging-bcm2835-camera-Provide-more-specific-probe-e.patch @@ -1,7 +1,7 @@ -From a6646e496feed4fd7affe3fc5d4fc3e2591046d6 Mon Sep 17 00:00:00 2001 +From acf4b3ea7ec32069d8f3bd2b541ccb56ed1d0db5 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sun, 21 Oct 2018 18:40:07 +0200 -Subject: [PATCH 235/703] staging: bcm2835-camera: Provide more specific probe +Subject: [PATCH 235/725] staging: bcm2835-camera: Provide more specific probe error messages Currently there is only a catch-all info message which print the diff --git a/target/linux/brcm2708/patches-4.19/950-0236-staging-bcm2835-camera-Add-hint-about-possible-fault.patch b/target/linux/brcm2708/patches-4.19/950-0236-staging-bcm2835-camera-Add-hint-about-possible-fault.patch index 4cf38bcf2d..c79f17074f 100644 --- a/target/linux/brcm2708/patches-4.19/950-0236-staging-bcm2835-camera-Add-hint-about-possible-fault.patch +++ b/target/linux/brcm2708/patches-4.19/950-0236-staging-bcm2835-camera-Add-hint-about-possible-fault.patch @@ -1,7 +1,7 @@ -From 477275011a3c1720683e3f9e6014ed2e76d921b7 Mon Sep 17 00:00:00 2001 +From 362ea23e6c338b589e9fcc5e91e942b00c37a93b Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sun, 21 Oct 2018 19:08:29 +0200 -Subject: [PATCH 236/703] staging: bcm2835-camera: Add hint about possible +Subject: [PATCH 236/725] staging: bcm2835-camera: Add hint about possible faulty GPU mem config As per default the GPU memory config of the Raspberry Pi isn't sufficient diff --git a/target/linux/brcm2708/patches-4.19/950-0237-staging-bcm2835-Don-t-probe-if-no-camera-is-detected.patch b/target/linux/brcm2708/patches-4.19/950-0237-staging-bcm2835-Don-t-probe-if-no-camera-is-detected.patch index 4e13404f59..5aee2ea6e5 100644 --- a/target/linux/brcm2708/patches-4.19/950-0237-staging-bcm2835-Don-t-probe-if-no-camera-is-detected.patch +++ b/target/linux/brcm2708/patches-4.19/950-0237-staging-bcm2835-Don-t-probe-if-no-camera-is-detected.patch @@ -1,7 +1,7 @@ -From 55c9d1a762b9cbb5a4c574918fb41a9cde6bb491 Mon Sep 17 00:00:00 2001 +From eb3b747986fbc23defe3942b91e24d3b0e007e3e Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Mon, 22 Oct 2018 11:09:18 +0200 -Subject: [PATCH 237/703] staging: bcm2835: Don't probe if no camera is +Subject: [PATCH 237/725] staging: bcm2835: Don't probe if no camera is detected It is a waste of resources to load the camera driver in case there isn't diff --git a/target/linux/brcm2708/patches-4.19/950-0238-staging-vchiq_arm-Improve-error-handling-on-loading-.patch b/target/linux/brcm2708/patches-4.19/950-0238-staging-vchiq_arm-Improve-error-handling-on-loading-.patch index c32757c245..f62004b01f 100644 --- a/target/linux/brcm2708/patches-4.19/950-0238-staging-vchiq_arm-Improve-error-handling-on-loading-.patch +++ b/target/linux/brcm2708/patches-4.19/950-0238-staging-vchiq_arm-Improve-error-handling-on-loading-.patch @@ -1,7 +1,7 @@ -From f83ac752b3898e65614d8b643ac57e828e1c5668 Mon Sep 17 00:00:00 2001 +From 8c25a73d376b538692aa0128d57ff95c71479561 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Mon, 3 Dec 2018 12:50:38 +0000 -Subject: [PATCH 238/703] staging: vchiq_arm: Improve error handling on loading +Subject: [PATCH 238/725] staging: vchiq_arm: Improve error handling on loading drivers The handling of loading platform drivers requires checking IS_ERR diff --git a/target/linux/brcm2708/patches-4.19/950-0239-staging-bcm2835-camera-Do-not-bulk-receive-from-serv.patch b/target/linux/brcm2708/patches-4.19/950-0239-staging-bcm2835-camera-Do-not-bulk-receive-from-serv.patch index 0df004ca9a..03b48a5f0e 100644 --- a/target/linux/brcm2708/patches-4.19/950-0239-staging-bcm2835-camera-Do-not-bulk-receive-from-serv.patch +++ b/target/linux/brcm2708/patches-4.19/950-0239-staging-bcm2835-camera-Do-not-bulk-receive-from-serv.patch @@ -1,7 +1,7 @@ -From 7cd2d38371edd4a04401c02c098a0e436816f3af Mon Sep 17 00:00:00 2001 +From c668ed917ce492f9448245078e0a2e9f9f4eef3a Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 14 Feb 2018 17:04:26 +0000 -Subject: [PATCH 239/703] staging: bcm2835-camera: Do not bulk receive from +Subject: [PATCH 239/725] staging: bcm2835-camera: Do not bulk receive from service thread vchi_bulk_queue_receive will queue up to a default of 4 diff --git a/target/linux/brcm2708/patches-4.19/950-0240-staging-bcm2835-camera-Ensure-H264-header-bytes-get-.patch b/target/linux/brcm2708/patches-4.19/950-0240-staging-bcm2835-camera-Ensure-H264-header-bytes-get-.patch index 3322a7ba52..638f0cf00a 100644 --- a/target/linux/brcm2708/patches-4.19/950-0240-staging-bcm2835-camera-Ensure-H264-header-bytes-get-.patch +++ b/target/linux/brcm2708/patches-4.19/950-0240-staging-bcm2835-camera-Ensure-H264-header-bytes-get-.patch @@ -1,7 +1,7 @@ -From 1e07591a39c73d5aec191a5d4065f33167483dd2 Mon Sep 17 00:00:00 2001 +From 873220449e4532c76d9ff86a75a482d1f78887db Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Mon, 29 Oct 2018 14:21:04 +0000 -Subject: [PATCH 240/703] staging: bcm2835-camera: Ensure H264 header bytes get +Subject: [PATCH 240/725] staging: bcm2835-camera: Ensure H264 header bytes get a sensible timestamp H264 header come from VC with 0 timestamps, which means they get a diff --git a/target/linux/brcm2708/patches-4.19/950-0241-staging-bcm2835-camera-Correctly-denote-key-frames-i.patch b/target/linux/brcm2708/patches-4.19/950-0241-staging-bcm2835-camera-Correctly-denote-key-frames-i.patch index df19dd3f8c..eeeafe352f 100644 --- a/target/linux/brcm2708/patches-4.19/950-0241-staging-bcm2835-camera-Correctly-denote-key-frames-i.patch +++ b/target/linux/brcm2708/patches-4.19/950-0241-staging-bcm2835-camera-Correctly-denote-key-frames-i.patch @@ -1,7 +1,7 @@ -From e66266218dca0b30e730f7b97240119cd140b92f Mon Sep 17 00:00:00 2001 +From 4bbbd45f2e47c52b89cd77c6b7cd7b5075836f86 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Mon, 13 Feb 2017 13:11:41 +0000 -Subject: [PATCH 241/703] staging: bcm2835-camera: Correctly denote key frames +Subject: [PATCH 241/725] staging: bcm2835-camera: Correctly denote key frames in encoded data Forward MMAL key frame flags to the V4L2 buffers. diff --git a/target/linux/brcm2708/patches-4.19/950-0242-staging-bcm2835-camera-Return-early-on-errors.patch b/target/linux/brcm2708/patches-4.19/950-0242-staging-bcm2835-camera-Return-early-on-errors.patch index 5ccb2850d5..5405a2a338 100644 --- a/target/linux/brcm2708/patches-4.19/950-0242-staging-bcm2835-camera-Return-early-on-errors.patch +++ b/target/linux/brcm2708/patches-4.19/950-0242-staging-bcm2835-camera-Return-early-on-errors.patch @@ -1,7 +1,7 @@ -From 83ba21bb6043c5afc3d497e9be4e128b3e1adf93 Mon Sep 17 00:00:00 2001 +From 7270f7555eb3d8144844c110e10f20558e563de6 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Fri, 10 Mar 2017 17:27:56 +0000 -Subject: [PATCH 242/703] staging: bcm2835-camera: Return early on errors +Subject: [PATCH 242/725] staging: bcm2835-camera: Return early on errors Fix several instances where it is easier to return early on error conditions than handle it as an else diff --git a/target/linux/brcm2708/patches-4.19/950-0243-staging-bcm2835-camera-Remove-dead-email-addresses.patch b/target/linux/brcm2708/patches-4.19/950-0243-staging-bcm2835-camera-Remove-dead-email-addresses.patch index d3bc0d8222..812eb92412 100644 --- a/target/linux/brcm2708/patches-4.19/950-0243-staging-bcm2835-camera-Remove-dead-email-addresses.patch +++ b/target/linux/brcm2708/patches-4.19/950-0243-staging-bcm2835-camera-Remove-dead-email-addresses.patch @@ -1,7 +1,7 @@ -From b7c48c78192d20fadb46b41a4628cb2a239017c1 Mon Sep 17 00:00:00 2001 +From fbea466b9b1178cf7b20607a3aa4ba7e98090e72 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Fri, 10 Mar 2017 17:35:38 +0000 -Subject: [PATCH 243/703] staging: bcm2835-camera: Remove dead email addresses +Subject: [PATCH 243/725] staging: bcm2835-camera: Remove dead email addresses None of the listed author email addresses were valid. Keep list of authors and the companies they represented. diff --git a/target/linux/brcm2708/patches-4.19/950-0244-staging-bcm2835-camera-Fix-comment-style-violations.patch b/target/linux/brcm2708/patches-4.19/950-0244-staging-bcm2835-camera-Fix-comment-style-violations.patch index 3659e33fc4..d721f1ede6 100644 --- a/target/linux/brcm2708/patches-4.19/950-0244-staging-bcm2835-camera-Fix-comment-style-violations.patch +++ b/target/linux/brcm2708/patches-4.19/950-0244-staging-bcm2835-camera-Fix-comment-style-violations.patch @@ -1,7 +1,7 @@ -From d1f1713c45091e779b29ee64e8900c9fac9e6339 Mon Sep 17 00:00:00 2001 +From d6c47fa1f829bfd7d85829bf5b507ac5aafe1172 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 21 Feb 2018 13:49:32 +0000 -Subject: [PATCH 244/703] staging: bcm2835-camera: Fix comment style +Subject: [PATCH 244/725] staging: bcm2835-camera: Fix comment style violations. Fix comment style violations in the header files. diff --git a/target/linux/brcm2708/patches-4.19/950-0245-staging-bcm2835-camera-Fix-spacing-around-operators.patch b/target/linux/brcm2708/patches-4.19/950-0245-staging-bcm2835-camera-Fix-spacing-around-operators.patch index 4d9f296552..89a9c04e55 100644 --- a/target/linux/brcm2708/patches-4.19/950-0245-staging-bcm2835-camera-Fix-spacing-around-operators.patch +++ b/target/linux/brcm2708/patches-4.19/950-0245-staging-bcm2835-camera-Fix-spacing-around-operators.patch @@ -1,7 +1,7 @@ -From 587b76ecb097da6d7d386a0c228230d9175bc1e4 Mon Sep 17 00:00:00 2001 +From 9b4f48ebb4bad6ed87d15874967d446327b0e65f Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 21 Feb 2018 14:13:03 +0000 -Subject: [PATCH 245/703] staging: bcm2835-camera: Fix spacing around operators +Subject: [PATCH 245/725] staging: bcm2835-camera: Fix spacing around operators Fix checkpatch warnings over spaces around operators. Many were around operations that can be replaced with the diff --git a/target/linux/brcm2708/patches-4.19/950-0246-staging-bcm2835-camera-Reduce-length-of-enum-names.patch b/target/linux/brcm2708/patches-4.19/950-0246-staging-bcm2835-camera-Reduce-length-of-enum-names.patch index b480aa442e..512aadf2d8 100644 --- a/target/linux/brcm2708/patches-4.19/950-0246-staging-bcm2835-camera-Reduce-length-of-enum-names.patch +++ b/target/linux/brcm2708/patches-4.19/950-0246-staging-bcm2835-camera-Reduce-length-of-enum-names.patch @@ -1,7 +1,7 @@ -From 12692997f0508b8c3c31c23f8ab6983380888f5e Mon Sep 17 00:00:00 2001 +From 562d78a33091aaeb7c2f2a975a262438d4b6ff30 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 21 Feb 2018 15:23:35 +0000 -Subject: [PATCH 246/703] staging: bcm2835-camera: Reduce length of enum names +Subject: [PATCH 246/725] staging: bcm2835-camera: Reduce length of enum names We have numerous lines over 80 chars, or oddly split. Many of these are due to using long enum names such as diff --git a/target/linux/brcm2708/patches-4.19/950-0247-staging-bcm2835-camera-Fix-multiple-line-dereference.patch b/target/linux/brcm2708/patches-4.19/950-0247-staging-bcm2835-camera-Fix-multiple-line-dereference.patch index 8a34daa0b8..08ccf1d0ba 100644 --- a/target/linux/brcm2708/patches-4.19/950-0247-staging-bcm2835-camera-Fix-multiple-line-dereference.patch +++ b/target/linux/brcm2708/patches-4.19/950-0247-staging-bcm2835-camera-Fix-multiple-line-dereference.patch @@ -1,7 +1,7 @@ -From 169d3b165889c1531227e2bb1e5df0f10ca9c83a Mon Sep 17 00:00:00 2001 +From bec59483afd1d335649fd26c83e448aae6602e4a Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 21 Feb 2018 15:28:07 +0000 -Subject: [PATCH 247/703] staging: bcm2835-camera: Fix multiple line +Subject: [PATCH 247/725] staging: bcm2835-camera: Fix multiple line dereference errors Fix checkpatch errors "Avoid multiple line dereference" diff --git a/target/linux/brcm2708/patches-4.19/950-0248-staging-bcm2835-camera-Fix-brace-style-issues.patch b/target/linux/brcm2708/patches-4.19/950-0248-staging-bcm2835-camera-Fix-brace-style-issues.patch index 748e2a6a67..1dffc8071e 100644 --- a/target/linux/brcm2708/patches-4.19/950-0248-staging-bcm2835-camera-Fix-brace-style-issues.patch +++ b/target/linux/brcm2708/patches-4.19/950-0248-staging-bcm2835-camera-Fix-brace-style-issues.patch @@ -1,7 +1,7 @@ -From b9702c9018656a2145bf18ad997d59f03f606bee Mon Sep 17 00:00:00 2001 +From c6fd809a48f06d2319c2391bafef0cf912fd9aa9 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 21 Feb 2018 15:37:11 +0000 -Subject: [PATCH 248/703] staging: bcm2835-camera: Fix brace style issues. +Subject: [PATCH 248/725] staging: bcm2835-camera: Fix brace style issues. Fix mismatched or missing brace issues flagged by checkpatch. diff --git a/target/linux/brcm2708/patches-4.19/950-0249-staging-bcm2835-camera-Fix-missing-lines-between-ite.patch b/target/linux/brcm2708/patches-4.19/950-0249-staging-bcm2835-camera-Fix-missing-lines-between-ite.patch index 9314b2d3a9..d0b2e9329f 100644 --- a/target/linux/brcm2708/patches-4.19/950-0249-staging-bcm2835-camera-Fix-missing-lines-between-ite.patch +++ b/target/linux/brcm2708/patches-4.19/950-0249-staging-bcm2835-camera-Fix-missing-lines-between-ite.patch @@ -1,7 +1,7 @@ -From 153f1bd423b29c9c5ea0ab23ca4c1beb272dab31 Mon Sep 17 00:00:00 2001 +From cd004c183f3080cd6ec13337e63dded7a625bee4 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 21 Feb 2018 15:39:26 +0000 -Subject: [PATCH 249/703] staging: bcm2835-camera: Fix missing lines between +Subject: [PATCH 249/725] staging: bcm2835-camera: Fix missing lines between items Fix checkpatch errors for missing blank lines after variable diff --git a/target/linux/brcm2708/patches-4.19/950-0250-staging-bcm2835-camera-Fix-logical-continuation-spli.patch b/target/linux/brcm2708/patches-4.19/950-0250-staging-bcm2835-camera-Fix-logical-continuation-spli.patch index 6d4526d1bb..be3de663bc 100644 --- a/target/linux/brcm2708/patches-4.19/950-0250-staging-bcm2835-camera-Fix-logical-continuation-spli.patch +++ b/target/linux/brcm2708/patches-4.19/950-0250-staging-bcm2835-camera-Fix-logical-continuation-spli.patch @@ -1,7 +1,7 @@ -From b628d79fb130da3cbae59b4aaa14fbaf599a5e7c Mon Sep 17 00:00:00 2001 +From 1a1fb6d6e25aa33db217c5109aa6b440fedee415 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 21 Feb 2018 15:48:54 +0000 -Subject: [PATCH 250/703] staging: bcm2835-camera: Fix logical continuation +Subject: [PATCH 250/725] staging: bcm2835-camera: Fix logical continuation splits Fix checkpatch errors for "Logical continuations should be diff --git a/target/linux/brcm2708/patches-4.19/950-0251-staging-bcm2835-camera-Fix-open-parenthesis-alignmen.patch b/target/linux/brcm2708/patches-4.19/950-0251-staging-bcm2835-camera-Fix-open-parenthesis-alignmen.patch index 1331849457..721187cdcd 100644 --- a/target/linux/brcm2708/patches-4.19/950-0251-staging-bcm2835-camera-Fix-open-parenthesis-alignmen.patch +++ b/target/linux/brcm2708/patches-4.19/950-0251-staging-bcm2835-camera-Fix-open-parenthesis-alignmen.patch @@ -1,7 +1,7 @@ -From 1e5564239201bed6be0b57d50c6f95e8f3907512 Mon Sep 17 00:00:00 2001 +From 636f4fad6c786c006e32c86b2f0d769c19177414 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 21 Feb 2018 15:53:59 +0000 -Subject: [PATCH 251/703] staging: bcm2835-camera: Fix open parenthesis +Subject: [PATCH 251/725] staging: bcm2835-camera: Fix open parenthesis alignment Fix checkpatch "Alignment should match open parenthesis" diff --git a/target/linux/brcm2708/patches-4.19/950-0252-staging-bcm2835-camera-Set-sequence-number-correctly.patch b/target/linux/brcm2708/patches-4.19/950-0252-staging-bcm2835-camera-Set-sequence-number-correctly.patch new file mode 100644 index 0000000000..4696716b95 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0252-staging-bcm2835-camera-Set-sequence-number-correctly.patch @@ -0,0 +1,46 @@ +From 12f0df5a07a37ebc3669784fe234e7a24d5867c3 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 21 Jun 2018 17:02:14 +0100 +Subject: [PATCH 252/725] staging: bcm2835-camera: Set sequence number + correctly + +Set the sequence number in vb2_v4l2_buffer mainly so the +latest v4l2-ctl reports the frame rate correctly. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 4 ++++ + drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h | 2 ++ + 2 files changed, 6 insertions(+) + +--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c ++++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +@@ -409,6 +409,7 @@ static void buffer_cb(struct vchiq_mmal_ + } + } + dev->capture.last_timestamp = buf->vb.vb2_buf.timestamp; ++ buf->vb.sequence = dev->capture.sequence++; + + vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length); + if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) +@@ -537,6 +538,9 @@ static int start_streaming(struct vb2_qu + /* enable frame capture */ + dev->capture.frame_count = 1; + ++ /* reset sequence number */ ++ dev->capture.sequence = 0; ++ + /* if the preview is not already running, wait for a few frames for AGC + * to settle down. + */ +--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h ++++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h +@@ -93,6 +93,8 @@ struct bm2835_mmal_dev { + ktime_t kernel_start_ts; + /* Timestamp of last frame */ + u64 last_timestamp; ++ /* Sequence number of last buffer */ ++ u32 sequence; + + struct vchiq_mmal_port *port; /* port being used for capture */ + /* camera port being used for capture */ diff --git a/target/linux/brcm2708/patches-4.19/950-0253-staging-bcm2835-camera-Ensure-timestamps-never-go-ba.patch b/target/linux/brcm2708/patches-4.19/950-0253-staging-bcm2835-camera-Ensure-timestamps-never-go-ba.patch new file mode 100644 index 0000000000..188bf23b21 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0253-staging-bcm2835-camera-Ensure-timestamps-never-go-ba.patch @@ -0,0 +1,38 @@ +From b29685ae7838b052cab7c7e26ff16e249edea294 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 24 Jul 2018 12:08:29 +0100 +Subject: [PATCH 253/725] staging: bcm2835-camera: Ensure timestamps never go + backwards. + +There is an awkward situation with H264 header bytes. Currently +they are returned with a PTS of 0 because they aren't associated +with a timestamped frame to encode. These are handled by either +returning the timestamp of the last buffer to have been received, +or in the case of the first buffer the timestamp taken at +start_streaming. +This results in a race where the current frame may have started +before we take the start time, which results in the first encoded +frame having an earlier timestamp than the header bytes. + +Ensure that we never return a negative delta to the user by checking +against the previous timestamp. + +Signed-off-by: Dave Stevenson +--- + .../staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c ++++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +@@ -393,6 +393,11 @@ static void buffer_cb(struct vchiq_mmal_ + ktime_to_ns(dev->capture.kernel_start_ts), + dev->capture.vc_start_timestamp, pts, + ktime_to_ns(timestamp)); ++ if (timestamp < dev->capture.last_timestamp) { ++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, ++ "Negative delta - using last time\n"); ++ timestamp = dev->capture.last_timestamp; ++ } + buf->vb.vb2_buf.timestamp = ktime_to_ns(timestamp); + } else { + if (dev->capture.last_timestamp) { diff --git a/target/linux/brcm2708/patches-4.19/950-0254-staging-bcm2835-camera-Avoid-unneeded-internal-decla.patch b/target/linux/brcm2708/patches-4.19/950-0254-staging-bcm2835-camera-Avoid-unneeded-internal-decla.patch new file mode 100644 index 0000000000..770855756a --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0254-staging-bcm2835-camera-Avoid-unneeded-internal-decla.patch @@ -0,0 +1,41 @@ +From 4ae496b855e158789383247cde55591fe9ce4ceb Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Thu, 27 Sep 2018 17:50:39 -0700 +Subject: [PATCH 254/725] staging: bcm2835-camera: Avoid unneeded internal + declaration warning + +Clang warns: + +drivers/staging/vc04_services/bcm2835-camera/controls.c:59:18: warning: +variable 'mains_freq_qmenu' is not needed and will not be emitted +[-Wunneeded-internal-declaration] +static const s64 mains_freq_qmenu[] = { + ^ +1 warning generated. + +This is because mains_freq_qmenu is currently only used in an ARRAY_SIZE +macro, which is a compile time evaluation in this case. Avoid this by +adding mains_freq_qmenu as the imenu member of this structure, which +matches all other controls that uses the ARRAY_SIZE macro in v4l2_ctrls. +This turns out to be a no-op because V4L2_CID_MPEG_VIDEO_BITRATE_MODE is +defined as a MMAL_CONTROL_TYPE_STD_MENU, which does not pass the imenu +definition along to v4l2_ctrl_new in bm2835_mmal_init_controls. + +Link: https://github.com/ClangBuiltLinux/linux/issues/122 +Signed-off-by: Nathan Chancellor +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/vc04_services/bcm2835-camera/controls.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/bcm2835-camera/controls.c ++++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c +@@ -1109,7 +1109,7 @@ static const struct bm2835_mmal_v4l2_ctr + { + V4L2_CID_POWER_LINE_FREQUENCY, MMAL_CONTROL_TYPE_STD_MENU, + 0, ARRAY_SIZE(mains_freq_qmenu) - 1, +- 1, 1, NULL, ++ 1, 1, mains_freq_qmenu, + MMAL_PARAMETER_FLICKER_AVOID, + &ctrl_set_flicker_avoidance, + false diff --git a/target/linux/brcm2708/patches-4.19/950-0255-staging-bcm2835-camera-Add-multiple-inclusion-protec.patch b/target/linux/brcm2708/patches-4.19/950-0255-staging-bcm2835-camera-Add-multiple-inclusion-protec.patch new file mode 100644 index 0000000000..effe47f814 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0255-staging-bcm2835-camera-Add-multiple-inclusion-protec.patch @@ -0,0 +1,48 @@ +From 66becb1e25c43817c0f46e401557955d2f763d07 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 24 Sep 2018 16:21:06 +0100 +Subject: [PATCH 255/725] staging: bcm2835-camera: Add multiple inclusion + protection to headers + +mmal-common.h and mmal-msg.h didn't have the normal +ifndef FOO / define FOO / endif protection to stop it being +included multiple times. Add it. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/bcm2835-camera/mmal-common.h | 3 +++ + drivers/staging/vc04_services/bcm2835-camera/mmal-msg.h | 3 +++ + 2 files changed, 6 insertions(+) + +--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h ++++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h +@@ -13,6 +13,8 @@ + * MMAL structures + * + */ ++#ifndef MMAL_COMMON_H ++#define MMAL_COMMON_H + + #define MMAL_FOURCC(a, b, c, d) ((a) | (b << 8) | (c << 16) | (d << 24)) + #define MMAL_MAGIC MMAL_FOURCC('m', 'm', 'a', 'l') +@@ -56,3 +58,4 @@ struct mmal_colourfx { + u32 u; + u32 v; + }; ++#endif +--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg.h ++++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-msg.h +@@ -23,6 +23,8 @@ + * implementation uses fixed size types and not the enums (though the + * comments have the actual enum type + */ ++#ifndef MMAL_MSG_H ++#define MMAL_MSG_H + + #define VC_MMAL_VER 15 + #define VC_MMAL_MIN_VER 10 +@@ -401,3 +403,4 @@ struct mmal_msg { + u8 payload[MMAL_MSG_MAX_PAYLOAD]; + } u; + }; ++#endif diff --git a/target/linux/brcm2708/patches-4.19/950-0255-staging-bcm2835-camera-Set-sequence-number-correctly.patch b/target/linux/brcm2708/patches-4.19/950-0255-staging-bcm2835-camera-Set-sequence-number-correctly.patch deleted file mode 100644 index c479a0eed8..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0255-staging-bcm2835-camera-Set-sequence-number-correctly.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 06ef8c73a0898576b90db697007bca999acad2fe Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 21 Jun 2018 17:02:14 +0100 -Subject: [PATCH 255/703] staging: bcm2835-camera: Set sequence number - correctly - -Set the sequence number in vb2_v4l2_buffer mainly so the -latest v4l2-ctl reports the frame rate correctly. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 4 ++++ - drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h | 2 ++ - 2 files changed, 6 insertions(+) - ---- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c -+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c -@@ -409,6 +409,7 @@ static void buffer_cb(struct vchiq_mmal_ - } - } - dev->capture.last_timestamp = buf->vb.vb2_buf.timestamp; -+ buf->vb.sequence = dev->capture.sequence++; - - vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length); - if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) -@@ -537,6 +538,9 @@ static int start_streaming(struct vb2_qu - /* enable frame capture */ - dev->capture.frame_count = 1; - -+ /* reset sequence number */ -+ dev->capture.sequence = 0; -+ - /* if the preview is not already running, wait for a few frames for AGC - * to settle down. - */ ---- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h -+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h -@@ -93,6 +93,8 @@ struct bm2835_mmal_dev { - ktime_t kernel_start_ts; - /* Timestamp of last frame */ - u64 last_timestamp; -+ /* Sequence number of last buffer */ -+ u32 sequence; - - struct vchiq_mmal_port *port; /* port being used for capture */ - /* camera port being used for capture */ diff --git a/target/linux/brcm2708/patches-4.19/950-0256-staging-bcm2835-camera-Ensure-timestamps-never-go-ba.patch b/target/linux/brcm2708/patches-4.19/950-0256-staging-bcm2835-camera-Ensure-timestamps-never-go-ba.patch deleted file mode 100644 index f4de0dab5f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0256-staging-bcm2835-camera-Ensure-timestamps-never-go-ba.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 04224f83b7285caf63afbbc4dab2917118ce6667 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 24 Jul 2018 12:08:29 +0100 -Subject: [PATCH 256/703] staging: bcm2835-camera: Ensure timestamps never go - backwards. - -There is an awkward situation with H264 header bytes. Currently -they are returned with a PTS of 0 because they aren't associated -with a timestamped frame to encode. These are handled by either -returning the timestamp of the last buffer to have been received, -or in the case of the first buffer the timestamp taken at -start_streaming. -This results in a race where the current frame may have started -before we take the start time, which results in the first encoded -frame having an earlier timestamp than the header bytes. - -Ensure that we never return a negative delta to the user by checking -against the previous timestamp. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c -+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c -@@ -393,6 +393,11 @@ static void buffer_cb(struct vchiq_mmal_ - ktime_to_ns(dev->capture.kernel_start_ts), - dev->capture.vc_start_timestamp, pts, - ktime_to_ns(timestamp)); -+ if (timestamp < dev->capture.last_timestamp) { -+ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, -+ "Negative delta - using last time\n"); -+ timestamp = dev->capture.last_timestamp; -+ } - buf->vb.vb2_buf.timestamp = ktime_to_ns(timestamp); - } else { - if (dev->capture.last_timestamp) { diff --git a/target/linux/brcm2708/patches-4.19/950-0256-staging-bcm2835-camera-Unify-header-inclusion-define.patch b/target/linux/brcm2708/patches-4.19/950-0256-staging-bcm2835-camera-Unify-header-inclusion-define.patch new file mode 100644 index 0000000000..16f4f56b4b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0256-staging-bcm2835-camera-Unify-header-inclusion-define.patch @@ -0,0 +1,30 @@ +From dc86a3318afa6e113b3094380fdab904d900c90b Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 3 Dec 2018 13:15:20 +0000 +Subject: [PATCH 256/725] staging: bcm2835-camera: Unify header inclusion + defines + +Most of the headers use ifndef FOO_H, whilst mmal-parameters.h +used ifndef __FOO_H. + +Revise mmal-parameters.h to drop the underscores and make the +headers all consistent. + +Signed-off-by: Dave Stevenson +--- + .../staging/vc04_services/bcm2835-camera/mmal-parameters.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h ++++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h +@@ -19,8 +19,8 @@ + * @{ + */ + +-#ifndef __MMAL_PARAMETERS_H +-#define __MMAL_PARAMETERS_H ++#ifndef MMAL_PARAMETERS_H ++#define MMAL_PARAMETERS_H + + /** Common parameter ID group, used with many types of component. */ + #define MMAL_PARAMETER_GROUP_COMMON (0 << 16) diff --git a/target/linux/brcm2708/patches-4.19/950-0257-ARM-bcm2835_defconfig-Enable-bcm2835-camera.patch b/target/linux/brcm2708/patches-4.19/950-0257-ARM-bcm2835_defconfig-Enable-bcm2835-camera.patch new file mode 100644 index 0000000000..47e7eeeb10 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0257-ARM-bcm2835_defconfig-Enable-bcm2835-camera.patch @@ -0,0 +1,33 @@ +From 8f2e8949f937462d749e19b28a8208e286caf605 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 29 Oct 2018 15:50:50 +0000 +Subject: [PATCH 257/725] ARM: bcm2835_defconfig: Enable bcm2835-camera + +Enables the V4L2 camera driver as a module. + +Signed-off-by: Dave Stevenson +--- + arch/arm/configs/bcm2835_defconfig | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/arch/arm/configs/bcm2835_defconfig ++++ b/arch/arm/configs/bcm2835_defconfig +@@ -91,6 +91,8 @@ CONFIG_THERMAL=y + CONFIG_BCM2835_THERMAL=y + CONFIG_WATCHDOG=y + CONFIG_BCM2835_WDT=y ++CONFIG_MEDIA_SUPPORT=m ++CONFIG_MEDIA_CAMERA_SUPPORT=y + CONFIG_DRM=y + CONFIG_DRM_VC4=y + CONFIG_FB_SIMPLE=y +@@ -128,7 +130,8 @@ CONFIG_LEDS_TRIGGER_CAMERA=y + CONFIG_DMADEVICES=y + CONFIG_DMA_BCM2835=y + CONFIG_STAGING=y +-CONFIG_BCM2835_VCHIQ=m ++CONFIG_SND_BCM2835=m ++CONFIG_VIDEO_BCM2835=m + CONFIG_MAILBOX=y + CONFIG_BCM2835_MBOX=y + # CONFIG_IOMMU_SUPPORT is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0257-staging-bcm2835-camera-Avoid-unneeded-internal-decla.patch b/target/linux/brcm2708/patches-4.19/950-0257-staging-bcm2835-camera-Avoid-unneeded-internal-decla.patch deleted file mode 100644 index 0cf30d9bb1..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0257-staging-bcm2835-camera-Avoid-unneeded-internal-decla.patch +++ /dev/null @@ -1,41 +0,0 @@ -From bb6d0d223ef1579a13eae3cffc66db9ede83bbd1 Mon Sep 17 00:00:00 2001 -From: Nathan Chancellor -Date: Thu, 27 Sep 2018 17:50:39 -0700 -Subject: [PATCH 257/703] staging: bcm2835-camera: Avoid unneeded internal - declaration warning - -Clang warns: - -drivers/staging/vc04_services/bcm2835-camera/controls.c:59:18: warning: -variable 'mains_freq_qmenu' is not needed and will not be emitted -[-Wunneeded-internal-declaration] -static const s64 mains_freq_qmenu[] = { - ^ -1 warning generated. - -This is because mains_freq_qmenu is currently only used in an ARRAY_SIZE -macro, which is a compile time evaluation in this case. Avoid this by -adding mains_freq_qmenu as the imenu member of this structure, which -matches all other controls that uses the ARRAY_SIZE macro in v4l2_ctrls. -This turns out to be a no-op because V4L2_CID_MPEG_VIDEO_BITRATE_MODE is -defined as a MMAL_CONTROL_TYPE_STD_MENU, which does not pass the imenu -definition along to v4l2_ctrl_new in bm2835_mmal_init_controls. - -Link: https://github.com/ClangBuiltLinux/linux/issues/122 -Signed-off-by: Nathan Chancellor -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/vc04_services/bcm2835-camera/controls.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/bcm2835-camera/controls.c -+++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c -@@ -1109,7 +1109,7 @@ static const struct bm2835_mmal_v4l2_ctr - { - V4L2_CID_POWER_LINE_FREQUENCY, MMAL_CONTROL_TYPE_STD_MENU, - 0, ARRAY_SIZE(mains_freq_qmenu) - 1, -- 1, 1, NULL, -+ 1, 1, mains_freq_qmenu, - MMAL_PARAMETER_FLICKER_AVOID, - &ctrl_set_flicker_avoidance, - false diff --git a/target/linux/brcm2708/patches-4.19/950-0258-staging-bcm2835-camera-Add-multiple-inclusion-protec.patch b/target/linux/brcm2708/patches-4.19/950-0258-staging-bcm2835-camera-Add-multiple-inclusion-protec.patch deleted file mode 100644 index fbbb2f5de4..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0258-staging-bcm2835-camera-Add-multiple-inclusion-protec.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 74a68a4cabb8dc516c6d1a9860043b9285d4f661 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 24 Sep 2018 16:21:06 +0100 -Subject: [PATCH 258/703] staging: bcm2835-camera: Add multiple inclusion - protection to headers - -mmal-common.h and mmal-msg.h didn't have the normal -ifndef FOO / define FOO / endif protection to stop it being -included multiple times. Add it. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/bcm2835-camera/mmal-common.h | 3 +++ - drivers/staging/vc04_services/bcm2835-camera/mmal-msg.h | 3 +++ - 2 files changed, 6 insertions(+) - ---- a/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h -+++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h -@@ -13,6 +13,8 @@ - * MMAL structures - * - */ -+#ifndef MMAL_COMMON_H -+#define MMAL_COMMON_H - - #define MMAL_FOURCC(a, b, c, d) ((a) | (b << 8) | (c << 16) | (d << 24)) - #define MMAL_MAGIC MMAL_FOURCC('m', 'm', 'a', 'l') -@@ -56,3 +58,4 @@ struct mmal_colourfx { - u32 u; - u32 v; - }; -+#endif ---- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg.h -+++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-msg.h -@@ -23,6 +23,8 @@ - * implementation uses fixed size types and not the enums (though the - * comments have the actual enum type - */ -+#ifndef MMAL_MSG_H -+#define MMAL_MSG_H - - #define VC_MMAL_VER 15 - #define VC_MMAL_MIN_VER 10 -@@ -401,3 +403,4 @@ struct mmal_msg { - u8 payload[MMAL_MSG_MAX_PAYLOAD]; - } u; - }; -+#endif diff --git a/target/linux/brcm2708/patches-4.19/950-0258-staging-bcm2835-camera-Fix-alignment-should-match-op.patch b/target/linux/brcm2708/patches-4.19/950-0258-staging-bcm2835-camera-Fix-alignment-should-match-op.patch new file mode 100644 index 0000000000..d1ae533bb5 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0258-staging-bcm2835-camera-Fix-alignment-should-match-op.patch @@ -0,0 +1,51 @@ +From d8c77a920cd800c375e1040f61ed15ec53219c1c Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 29 Oct 2018 15:55:42 +0000 +Subject: [PATCH 258/725] staging: bcm2835-camera: Fix alignment should match + open parenthesis + +Fix up checkpatch "Alignment should match open parenthesis" errors + +Signed-off-by: Dave Stevenson +--- + .../staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c ++++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +@@ -1934,7 +1934,7 @@ static int bcm2835_mmal_probe(struct pla + ret = bm2835_mmal_init_controls(dev, &dev->ctrl_handler); + if (ret < 0) { + v4l2_err(&dev->v4l2_dev, "%s: could not init controls: %d\n", +- __func__, ret); ++ __func__, ret); + goto unreg_dev; + } + dev->v4l2_dev.ctrl_handler = &dev->ctrl_handler; +@@ -1944,7 +1944,7 @@ static int bcm2835_mmal_probe(struct pla + ret = mmal_init(dev); + if (ret < 0) { + v4l2_err(&dev->v4l2_dev, "%s: mmal init failed: %d\n", +- __func__, ret); ++ __func__, ret); + goto unreg_dev; + } + /* initialize queue */ +@@ -1966,7 +1966,7 @@ static int bcm2835_mmal_probe(struct pla + ret = bm2835_mmal_init_device(dev, &dev->vdev); + if (ret < 0) { + v4l2_err(&dev->v4l2_dev, "%s: could not init device: %d\n", +- __func__, ret); ++ __func__, ret); + goto unreg_dev; + } + +@@ -1976,7 +1976,7 @@ static int bcm2835_mmal_probe(struct pla + ret = mmal_setup_components(dev, &default_v4l2_format); + if (ret < 0) { + v4l2_err(&dev->v4l2_dev, "%s: could not setup components: %d\n", +- __func__, ret); ++ __func__, ret); + goto unreg_dev; + } + diff --git a/target/linux/brcm2708/patches-4.19/950-0259-staging-bcm2835-camera-Fix-multiple-assignments-shou.patch b/target/linux/brcm2708/patches-4.19/950-0259-staging-bcm2835-camera-Fix-multiple-assignments-shou.patch new file mode 100644 index 0000000000..5001128806 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0259-staging-bcm2835-camera-Fix-multiple-assignments-shou.patch @@ -0,0 +1,30 @@ +From 816336e4081a5180c5b8524b2839e31f43a5ddf8 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 29 Oct 2018 15:58:14 +0000 +Subject: [PATCH 259/725] staging: bcm2835-camera: Fix multiple assignments + should be avoided + +Clear checkpatch complaints of "multiple assignments should be avoided" + +Signed-off-by: Dave Stevenson +--- + .../staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c ++++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +@@ -1065,11 +1065,12 @@ static int mmal_setup_components(struct + /* Make a further decision on port based on resolution */ + if (f->fmt.pix.width <= max_video_width && + f->fmt.pix.height <= max_video_height) +- camera_port = port = ++ camera_port = + &dev->component[COMP_CAMERA]->output[CAM_PORT_VIDEO]; + else +- camera_port = port = ++ camera_port = + &dev->component[COMP_CAMERA]->output[CAM_PORT_CAPTURE]; ++ port = camera_port; + break; + case COMP_IMAGE_ENCODE: + encode_component = dev->component[COMP_IMAGE_ENCODE]; diff --git a/target/linux/brcm2708/patches-4.19/950-0259-staging-bcm2835-camera-Unify-header-inclusion-define.patch b/target/linux/brcm2708/patches-4.19/950-0259-staging-bcm2835-camera-Unify-header-inclusion-define.patch deleted file mode 100644 index 55e0c534c7..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0259-staging-bcm2835-camera-Unify-header-inclusion-define.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 8e7b28ae807a4f727ea9a1232705b2bdb6752c1f Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 3 Dec 2018 13:15:20 +0000 -Subject: [PATCH 259/703] staging: bcm2835-camera: Unify header inclusion - defines - -Most of the headers use ifndef FOO_H, whilst mmal-parameters.h -used ifndef __FOO_H. - -Revise mmal-parameters.h to drop the underscores and make the -headers all consistent. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/bcm2835-camera/mmal-parameters.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h -+++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h -@@ -19,8 +19,8 @@ - * @{ - */ - --#ifndef __MMAL_PARAMETERS_H --#define __MMAL_PARAMETERS_H -+#ifndef MMAL_PARAMETERS_H -+#define MMAL_PARAMETERS_H - - /** Common parameter ID group, used with many types of component. */ - #define MMAL_PARAMETER_GROUP_COMMON (0 << 16) diff --git a/target/linux/brcm2708/patches-4.19/950-0260-ARM-bcm2835_defconfig-Enable-bcm2835-camera.patch b/target/linux/brcm2708/patches-4.19/950-0260-ARM-bcm2835_defconfig-Enable-bcm2835-camera.patch deleted file mode 100644 index f61d50317a..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0260-ARM-bcm2835_defconfig-Enable-bcm2835-camera.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 62b19c662d048c575fc9aef23560f31f4d72767b Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 29 Oct 2018 15:50:50 +0000 -Subject: [PATCH 260/703] ARM: bcm2835_defconfig: Enable bcm2835-camera - -Enables the V4L2 camera driver as a module. - -Signed-off-by: Dave Stevenson ---- - arch/arm/configs/bcm2835_defconfig | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -91,6 +91,8 @@ CONFIG_THERMAL=y - CONFIG_BCM2835_THERMAL=y - CONFIG_WATCHDOG=y - CONFIG_BCM2835_WDT=y -+CONFIG_MEDIA_SUPPORT=m -+CONFIG_MEDIA_CAMERA_SUPPORT=y - CONFIG_DRM=y - CONFIG_DRM_VC4=y - CONFIG_FB_SIMPLE=y -@@ -128,7 +130,8 @@ CONFIG_LEDS_TRIGGER_CAMERA=y - CONFIG_DMADEVICES=y - CONFIG_DMA_BCM2835=y - CONFIG_STAGING=y --CONFIG_BCM2835_VCHIQ=m -+CONFIG_SND_BCM2835=m -+CONFIG_VIDEO_BCM2835=m - CONFIG_MAILBOX=y - CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0260-staging-bcm2835-camera-Fix-up-all-formatting-in-mmal.patch b/target/linux/brcm2708/patches-4.19/950-0260-staging-bcm2835-camera-Fix-up-all-formatting-in-mmal.patch new file mode 100644 index 0000000000..602cf6caed --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0260-staging-bcm2835-camera-Fix-up-all-formatting-in-mmal.patch @@ -0,0 +1,336 @@ +From 2af5efec3dd9186edee08f14dffcee638955c909 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 29 Oct 2018 16:08:41 +0000 +Subject: [PATCH 260/725] staging: bcm2835-camera: Fix up all formatting in + mmal-paramters.h + +Fixes up all checkpatch errors in mmal-parameters.h + +Signed-off-by: Dave Stevenson +--- + .../bcm2835-camera/mmal-parameters.h | 273 +++++++++++------- + 1 file changed, 165 insertions(+), 108 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h ++++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h +@@ -23,148 +23,204 @@ + #define MMAL_PARAMETERS_H + + /** Common parameter ID group, used with many types of component. */ +-#define MMAL_PARAMETER_GROUP_COMMON (0 << 16) ++#define MMAL_PARAMETER_GROUP_COMMON (0 << 16) + /** Camera-specific parameter ID group. */ +-#define MMAL_PARAMETER_GROUP_CAMERA (1 << 16) ++#define MMAL_PARAMETER_GROUP_CAMERA (1 << 16) + /** Video-specific parameter ID group. */ +-#define MMAL_PARAMETER_GROUP_VIDEO (2 << 16) ++#define MMAL_PARAMETER_GROUP_VIDEO (2 << 16) + /** Audio-specific parameter ID group. */ +-#define MMAL_PARAMETER_GROUP_AUDIO (3 << 16) ++#define MMAL_PARAMETER_GROUP_AUDIO (3 << 16) + /** Clock-specific parameter ID group. */ +-#define MMAL_PARAMETER_GROUP_CLOCK (4 << 16) ++#define MMAL_PARAMETER_GROUP_CLOCK (4 << 16) + /** Miracast-specific parameter ID group. */ +-#define MMAL_PARAMETER_GROUP_MIRACAST (5 << 16) ++#define MMAL_PARAMETER_GROUP_MIRACAST (5 << 16) + + /* Common parameters */ + enum mmal_parameter_common_type { +- MMAL_PARAMETER_UNUSED /**< Never a valid parameter ID */ +- = MMAL_PARAMETER_GROUP_COMMON, +- MMAL_PARAMETER_SUPPORTED_ENCODINGS, /**< MMAL_PARAMETER_ENCODING_T */ +- MMAL_PARAMETER_URI, /**< MMAL_PARAMETER_URI_T */ ++ /**< Never a valid parameter ID */ ++ MMAL_PARAMETER_UNUSED = MMAL_PARAMETER_GROUP_COMMON, + +- /** MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T */ ++ /**< MMAL_PARAMETER_ENCODING_T */ ++ MMAL_PARAMETER_SUPPORTED_ENCODINGS, ++ /**< MMAL_PARAMETER_URI_T */ ++ MMAL_PARAMETER_URI, ++ /** MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T */ + MMAL_PARAMETER_CHANGE_EVENT_REQUEST, +- +- /** MMAL_PARAMETER_BOOLEAN_T */ ++ /** MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_ZERO_COPY, +- +- /**< MMAL_PARAMETER_BUFFER_REQUIREMENTS_T */ ++ /**< MMAL_PARAMETER_BUFFER_REQUIREMENTS_T */ + MMAL_PARAMETER_BUFFER_REQUIREMENTS, +- +- MMAL_PARAMETER_STATISTICS, /**< MMAL_PARAMETER_STATISTICS_T */ +- MMAL_PARAMETER_CORE_STATISTICS, /**< MMAL_PARAMETER_CORE_STATISTICS_T */ +- MMAL_PARAMETER_MEM_USAGE, /**< MMAL_PARAMETER_MEM_USAGE_T */ +- MMAL_PARAMETER_BUFFER_FLAG_FILTER, /**< MMAL_PARAMETER_UINT32_T */ +- MMAL_PARAMETER_SEEK, /**< MMAL_PARAMETER_SEEK_T */ +- MMAL_PARAMETER_POWERMON_ENABLE, /**< MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_LOGGING, /**< MMAL_PARAMETER_LOGGING_T */ +- MMAL_PARAMETER_SYSTEM_TIME, /**< MMAL_PARAMETER_UINT64_T */ +- MMAL_PARAMETER_NO_IMAGE_PADDING /**< MMAL_PARAMETER_BOOLEAN_T */ ++ /**< MMAL_PARAMETER_STATISTICS_T */ ++ MMAL_PARAMETER_STATISTICS, ++ /**< MMAL_PARAMETER_CORE_STATISTICS_T */ ++ MMAL_PARAMETER_CORE_STATISTICS, ++ /**< MMAL_PARAMETER_MEM_USAGE_T */ ++ MMAL_PARAMETER_MEM_USAGE, ++ /**< MMAL_PARAMETER_UINT32_T */ ++ MMAL_PARAMETER_BUFFER_FLAG_FILTER, ++ /**< MMAL_PARAMETER_SEEK_T */ ++ MMAL_PARAMETER_SEEK, ++ /**< MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_POWERMON_ENABLE, ++ /**< MMAL_PARAMETER_LOGGING_T */ ++ MMAL_PARAMETER_LOGGING, ++ /**< MMAL_PARAMETER_UINT64_T */ ++ MMAL_PARAMETER_SYSTEM_TIME, ++ /**< MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_NO_IMAGE_PADDING, + }; + + /* camera parameters */ + + enum mmal_parameter_camera_type { + /* 0 */ +- /** @ref MMAL_PARAMETER_THUMBNAIL_CONFIG_T */ +- MMAL_PARAMETER_THUMBNAIL_CONFIGURATION +- = MMAL_PARAMETER_GROUP_CAMERA, +- MMAL_PARAMETER_CAPTURE_QUALITY, /**< Unused? */ +- MMAL_PARAMETER_ROTATION, /**< @ref MMAL_PARAMETER_INT32_T */ +- MMAL_PARAMETER_EXIF_DISABLE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_EXIF, /**< @ref MMAL_PARAMETER_EXIF_T */ +- MMAL_PARAMETER_AWB_MODE, /**< @ref MMAL_PARAM_AWBMODE_T */ +- MMAL_PARAMETER_IMAGE_EFFECT, /**< @ref MMAL_PARAMETER_IMAGEFX_T */ +- MMAL_PARAMETER_COLOUR_EFFECT, /**< @ref MMAL_PARAMETER_COLOURFX_T */ +- MMAL_PARAMETER_FLICKER_AVOID, /**< @ref MMAL_PARAMETER_FLICKERAVOID_T */ +- MMAL_PARAMETER_FLASH, /**< @ref MMAL_PARAMETER_FLASH_T */ +- MMAL_PARAMETER_REDEYE, /**< @ref MMAL_PARAMETER_REDEYE_T */ +- MMAL_PARAMETER_FOCUS, /**< @ref MMAL_PARAMETER_FOCUS_T */ +- MMAL_PARAMETER_FOCAL_LENGTHS, /**< Unused? */ +- MMAL_PARAMETER_EXPOSURE_COMP, /**< @ref MMAL_PARAMETER_INT32_T */ +- MMAL_PARAMETER_ZOOM, /**< @ref MMAL_PARAMETER_SCALEFACTOR_T */ +- MMAL_PARAMETER_MIRROR, /**< @ref MMAL_PARAMETER_MIRROR_T */ ++ /** @ref MMAL_PARAMETER_THUMBNAIL_CONFIG_T */ ++ MMAL_PARAMETER_THUMBNAIL_CONFIGURATION = ++ MMAL_PARAMETER_GROUP_CAMERA, ++ /**< Unused? */ ++ MMAL_PARAMETER_CAPTURE_QUALITY, ++ /**< @ref MMAL_PARAMETER_INT32_T */ ++ MMAL_PARAMETER_ROTATION, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_EXIF_DISABLE, ++ /**< @ref MMAL_PARAMETER_EXIF_T */ ++ MMAL_PARAMETER_EXIF, ++ /**< @ref MMAL_PARAM_AWBMODE_T */ ++ MMAL_PARAMETER_AWB_MODE, ++ /**< @ref MMAL_PARAMETER_IMAGEFX_T */ ++ MMAL_PARAMETER_IMAGE_EFFECT, ++ /**< @ref MMAL_PARAMETER_COLOURFX_T */ ++ MMAL_PARAMETER_COLOUR_EFFECT, ++ /**< @ref MMAL_PARAMETER_FLICKERAVOID_T */ ++ MMAL_PARAMETER_FLICKER_AVOID, ++ /**< @ref MMAL_PARAMETER_FLASH_T */ ++ MMAL_PARAMETER_FLASH, ++ /**< @ref MMAL_PARAMETER_REDEYE_T */ ++ MMAL_PARAMETER_REDEYE, ++ /**< @ref MMAL_PARAMETER_FOCUS_T */ ++ MMAL_PARAMETER_FOCUS, ++ /**< Unused? */ ++ MMAL_PARAMETER_FOCAL_LENGTHS, ++ /**< @ref MMAL_PARAMETER_INT32_T */ ++ MMAL_PARAMETER_EXPOSURE_COMP, ++ /**< @ref MMAL_PARAMETER_SCALEFACTOR_T */ ++ MMAL_PARAMETER_ZOOM, ++ /**< @ref MMAL_PARAMETER_MIRROR_T */ ++ MMAL_PARAMETER_MIRROR, + + /* 0x10 */ +- MMAL_PARAMETER_CAMERA_NUM, /**< @ref MMAL_PARAMETER_UINT32_T */ +- MMAL_PARAMETER_CAPTURE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_EXPOSURE_MODE, /**< @ref MMAL_PARAMETER_EXPOSUREMODE_T */ +- MMAL_PARAMETER_EXP_METERING_MODE, /**< @ref MMAL_PARAMETER_EXPOSUREMETERINGMODE_T */ +- MMAL_PARAMETER_FOCUS_STATUS, /**< @ref MMAL_PARAMETER_FOCUS_STATUS_T */ +- MMAL_PARAMETER_CAMERA_CONFIG, /**< @ref MMAL_PARAMETER_CAMERA_CONFIG_T */ +- MMAL_PARAMETER_CAPTURE_STATUS, /**< @ref MMAL_PARAMETER_CAPTURE_STATUS_T */ +- MMAL_PARAMETER_FACE_TRACK, /**< @ref MMAL_PARAMETER_FACE_TRACK_T */ +- MMAL_PARAMETER_DRAW_BOX_FACES_AND_FOCUS, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_JPEG_Q_FACTOR, /**< @ref MMAL_PARAMETER_UINT32_T */ +- MMAL_PARAMETER_FRAME_RATE, /**< @ref MMAL_PARAMETER_FRAME_RATE_T */ +- MMAL_PARAMETER_USE_STC, /**< @ref MMAL_PARAMETER_CAMERA_STC_MODE_T */ +- MMAL_PARAMETER_CAMERA_INFO, /**< @ref MMAL_PARAMETER_CAMERA_INFO_T */ +- MMAL_PARAMETER_VIDEO_STABILISATION, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_FACE_TRACK_RESULTS, /**< @ref MMAL_PARAMETER_FACE_TRACK_RESULTS_T */ +- MMAL_PARAMETER_ENABLE_RAW_CAPTURE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ /**< @ref MMAL_PARAMETER_UINT32_T */ ++ MMAL_PARAMETER_CAMERA_NUM, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_CAPTURE, ++ /**< @ref MMAL_PARAMETER_EXPOSUREMODE_T */ ++ MMAL_PARAMETER_EXPOSURE_MODE, ++ /**< @ref MMAL_PARAMETER_EXPOSUREMETERINGMODE_T */ ++ MMAL_PARAMETER_EXP_METERING_MODE, ++ /**< @ref MMAL_PARAMETER_FOCUS_STATUS_T */ ++ MMAL_PARAMETER_FOCUS_STATUS, ++ /**< @ref MMAL_PARAMETER_CAMERA_CONFIG_T */ ++ MMAL_PARAMETER_CAMERA_CONFIG, ++ /**< @ref MMAL_PARAMETER_CAPTURE_STATUS_T */ ++ MMAL_PARAMETER_CAPTURE_STATUS, ++ /**< @ref MMAL_PARAMETER_FACE_TRACK_T */ ++ MMAL_PARAMETER_FACE_TRACK, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_DRAW_BOX_FACES_AND_FOCUS, ++ /**< @ref MMAL_PARAMETER_UINT32_T */ ++ MMAL_PARAMETER_JPEG_Q_FACTOR, ++ /**< @ref MMAL_PARAMETER_FRAME_RATE_T */ ++ MMAL_PARAMETER_FRAME_RATE, ++ /**< @ref MMAL_PARAMETER_CAMERA_STC_MODE_T */ ++ MMAL_PARAMETER_USE_STC, ++ /**< @ref MMAL_PARAMETER_CAMERA_INFO_T */ ++ MMAL_PARAMETER_CAMERA_INFO, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_VIDEO_STABILISATION, ++ /**< @ref MMAL_PARAMETER_FACE_TRACK_RESULTS_T */ ++ MMAL_PARAMETER_FACE_TRACK_RESULTS, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_ENABLE_RAW_CAPTURE, + + /* 0x20 */ +- MMAL_PARAMETER_DPF_FILE, /**< @ref MMAL_PARAMETER_URI_T */ +- MMAL_PARAMETER_ENABLE_DPF_FILE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_DPF_FAIL_IS_FATAL, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_CAPTURE_MODE, /**< @ref MMAL_PARAMETER_CAPTUREMODE_T */ +- MMAL_PARAMETER_FOCUS_REGIONS, /**< @ref MMAL_PARAMETER_FOCUS_REGIONS_T */ +- MMAL_PARAMETER_INPUT_CROP, /**< @ref MMAL_PARAMETER_INPUT_CROP_T */ +- MMAL_PARAMETER_SENSOR_INFORMATION, /**< @ref MMAL_PARAMETER_SENSOR_INFORMATION_T */ +- MMAL_PARAMETER_FLASH_SELECT, /**< @ref MMAL_PARAMETER_FLASH_SELECT_T */ +- MMAL_PARAMETER_FIELD_OF_VIEW, /**< @ref MMAL_PARAMETER_FIELD_OF_VIEW_T */ +- MMAL_PARAMETER_HIGH_DYNAMIC_RANGE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_DYNAMIC_RANGE_COMPRESSION, /**< @ref MMAL_PARAMETER_DRC_T */ +- MMAL_PARAMETER_ALGORITHM_CONTROL, /**< @ref MMAL_PARAMETER_ALGORITHM_CONTROL_T */ +- MMAL_PARAMETER_SHARPNESS, /**< @ref MMAL_PARAMETER_RATIONAL_T */ +- MMAL_PARAMETER_CONTRAST, /**< @ref MMAL_PARAMETER_RATIONAL_T */ +- MMAL_PARAMETER_BRIGHTNESS, /**< @ref MMAL_PARAMETER_RATIONAL_T */ +- MMAL_PARAMETER_SATURATION, /**< @ref MMAL_PARAMETER_RATIONAL_T */ ++ /**< @ref MMAL_PARAMETER_URI_T */ ++ MMAL_PARAMETER_DPF_FILE, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_ENABLE_DPF_FILE, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_DPF_FAIL_IS_FATAL, ++ /**< @ref MMAL_PARAMETER_CAPTUREMODE_T */ ++ MMAL_PARAMETER_CAPTURE_MODE, ++ /**< @ref MMAL_PARAMETER_FOCUS_REGIONS_T */ ++ MMAL_PARAMETER_FOCUS_REGIONS, ++ /**< @ref MMAL_PARAMETER_INPUT_CROP_T */ ++ MMAL_PARAMETER_INPUT_CROP, ++ /**< @ref MMAL_PARAMETER_SENSOR_INFORMATION_T */ ++ MMAL_PARAMETER_SENSOR_INFORMATION, ++ /**< @ref MMAL_PARAMETER_FLASH_SELECT_T */ ++ MMAL_PARAMETER_FLASH_SELECT, ++ /**< @ref MMAL_PARAMETER_FIELD_OF_VIEW_T */ ++ MMAL_PARAMETER_FIELD_OF_VIEW, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_HIGH_DYNAMIC_RANGE, ++ /**< @ref MMAL_PARAMETER_DRC_T */ ++ MMAL_PARAMETER_DYNAMIC_RANGE_COMPRESSION, ++ /**< @ref MMAL_PARAMETER_ALGORITHM_CONTROL_T */ ++ MMAL_PARAMETER_ALGORITHM_CONTROL, ++ /**< @ref MMAL_PARAMETER_RATIONAL_T */ ++ MMAL_PARAMETER_SHARPNESS, ++ /**< @ref MMAL_PARAMETER_RATIONAL_T */ ++ MMAL_PARAMETER_CONTRAST, ++ /**< @ref MMAL_PARAMETER_RATIONAL_T */ ++ MMAL_PARAMETER_BRIGHTNESS, ++ /**< @ref MMAL_PARAMETER_RATIONAL_T */ ++ MMAL_PARAMETER_SATURATION, + + /* 0x30 */ +- MMAL_PARAMETER_ISO, /**< @ref MMAL_PARAMETER_UINT32_T */ +- MMAL_PARAMETER_ANTISHAKE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- +- /** @ref MMAL_PARAMETER_IMAGEFX_PARAMETERS_T */ ++ /**< @ref MMAL_PARAMETER_UINT32_T */ ++ MMAL_PARAMETER_ISO, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_ANTISHAKE, ++ /** @ref MMAL_PARAMETER_IMAGEFX_PARAMETERS_T */ + MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, +- +- /** @ref MMAL_PARAMETER_BOOLEAN_T */ ++ /** @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_CAMERA_BURST_CAPTURE, +- +- /** @ref MMAL_PARAMETER_UINT32_T */ ++ /** @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_CAMERA_MIN_ISO, +- +- /** @ref MMAL_PARAMETER_CAMERA_USE_CASE_T */ ++ /** @ref MMAL_PARAMETER_CAMERA_USE_CASE_T */ + MMAL_PARAMETER_CAMERA_USE_CASE, +- +- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_CAPTURE_STATS_PASS, +- +- /** @ref MMAL_PARAMETER_UINT32_T */ ++ /** @ref MMAL_PARAMETER_UINT32_T */ + MMAL_PARAMETER_CAMERA_CUSTOM_SENSOR_CONFIG, +- +- /** @ref MMAL_PARAMETER_BOOLEAN_T */ ++ /** @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_ENABLE_REGISTER_FILE, +- +- /** @ref MMAL_PARAMETER_BOOLEAN_T */ ++ /** @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_REGISTER_FAIL_IS_FATAL, +- +- /** @ref MMAL_PARAMETER_CONFIGFILE_T */ ++ /** @ref MMAL_PARAMETER_CONFIGFILE_T */ + MMAL_PARAMETER_CONFIGFILE_REGISTERS, +- +- /** @ref MMAL_PARAMETER_CONFIGFILE_CHUNK_T */ ++ /** @ref MMAL_PARAMETER_CONFIGFILE_CHUNK_T */ + MMAL_PARAMETER_CONFIGFILE_CHUNK_REGISTERS, +- MMAL_PARAMETER_JPEG_ATTACH_LOG, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_ZERO_SHUTTER_LAG, /**< @ref MMAL_PARAMETER_ZEROSHUTTERLAG_T */ +- MMAL_PARAMETER_FPS_RANGE, /**< @ref MMAL_PARAMETER_FPS_RANGE_T */ +- MMAL_PARAMETER_CAPTURE_EXPOSURE_COMP, /**< @ref MMAL_PARAMETER_INT32_T */ ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_JPEG_ATTACH_LOG, ++ /**< @ref MMAL_PARAMETER_ZEROSHUTTERLAG_T */ ++ MMAL_PARAMETER_ZERO_SHUTTER_LAG, ++ /**< @ref MMAL_PARAMETER_FPS_RANGE_T */ ++ MMAL_PARAMETER_FPS_RANGE, ++ /**< @ref MMAL_PARAMETER_INT32_T */ ++ MMAL_PARAMETER_CAPTURE_EXPOSURE_COMP, + + /* 0x40 */ +- MMAL_PARAMETER_SW_SHARPEN_DISABLE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_FLASH_REQUIRED, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_SW_SATURATION_DISABLE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_SHUTTER_SPEED, /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ +- MMAL_PARAMETER_CUSTOM_AWB_GAINS, /**< Takes a @ref MMAL_PARAMETER_AWB_GAINS_T */ ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_SW_SHARPEN_DISABLE, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_FLASH_REQUIRED, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_SW_SATURATION_DISABLE, ++ /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ ++ MMAL_PARAMETER_SHUTTER_SPEED, ++ /**< Takes a @ref MMAL_PARAMETER_AWB_GAINS_T */ ++ MMAL_PARAMETER_CUSTOM_AWB_GAINS, + }; + + struct mmal_parameter_rational { +@@ -411,7 +467,8 @@ enum mmal_parameter_video_type { + MMAL_PARAMETER_MINIMISE_FRAGMENTATION, + + /** @ref MMAL_PARAMETER_UINT32_T. +- * Setting the value to zero resets to the default (one slice per frame). ++ * Setting the value to zero resets to the default (one slice per ++ * frame). + */ + MMAL_PARAMETER_MB_ROWS_PER_SLICE, + diff --git a/target/linux/brcm2708/patches-4.19/950-0261-staging-bcm2835-camera-Fix-alignment-should-match-op.patch b/target/linux/brcm2708/patches-4.19/950-0261-staging-bcm2835-camera-Fix-alignment-should-match-op.patch deleted file mode 100644 index cf22f62590..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0261-staging-bcm2835-camera-Fix-alignment-should-match-op.patch +++ /dev/null @@ -1,51 +0,0 @@ -From eef1625f7bbf1d7073860159fb9317725cd680dc Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 29 Oct 2018 15:55:42 +0000 -Subject: [PATCH 261/703] staging: bcm2835-camera: Fix alignment should match - open parenthesis - -Fix up checkpatch "Alignment should match open parenthesis" errors - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c -+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c -@@ -1934,7 +1934,7 @@ static int bcm2835_mmal_probe(struct pla - ret = bm2835_mmal_init_controls(dev, &dev->ctrl_handler); - if (ret < 0) { - v4l2_err(&dev->v4l2_dev, "%s: could not init controls: %d\n", -- __func__, ret); -+ __func__, ret); - goto unreg_dev; - } - dev->v4l2_dev.ctrl_handler = &dev->ctrl_handler; -@@ -1944,7 +1944,7 @@ static int bcm2835_mmal_probe(struct pla - ret = mmal_init(dev); - if (ret < 0) { - v4l2_err(&dev->v4l2_dev, "%s: mmal init failed: %d\n", -- __func__, ret); -+ __func__, ret); - goto unreg_dev; - } - /* initialize queue */ -@@ -1966,7 +1966,7 @@ static int bcm2835_mmal_probe(struct pla - ret = bm2835_mmal_init_device(dev, &dev->vdev); - if (ret < 0) { - v4l2_err(&dev->v4l2_dev, "%s: could not init device: %d\n", -- __func__, ret); -+ __func__, ret); - goto unreg_dev; - } - -@@ -1976,7 +1976,7 @@ static int bcm2835_mmal_probe(struct pla - ret = mmal_setup_components(dev, &default_v4l2_format); - if (ret < 0) { - v4l2_err(&dev->v4l2_dev, "%s: could not setup components: %d\n", -- __func__, ret); -+ __func__, ret); - goto unreg_dev; - } - diff --git a/target/linux/brcm2708/patches-4.19/950-0261-staging-bcm2835-camera-Use-enums-for-max-value-in-co.patch b/target/linux/brcm2708/patches-4.19/950-0261-staging-bcm2835-camera-Use-enums-for-max-value-in-co.patch new file mode 100644 index 0000000000..6a8fa5e0d0 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0261-staging-bcm2835-camera-Use-enums-for-max-value-in-co.patch @@ -0,0 +1,112 @@ +From 8d81b25c2bdc73f4d5d0985c0ec8e2d19f181768 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 28 Sep 2018 10:17:11 +0100 +Subject: [PATCH 261/725] staging: bcm2835-camera: Use enums for max value in + controls + +Controls of type MMAL_CONTROL_TYPE_STD_MENU call v4l2_ctrl_new_std_menu +with a max value and a mask. The max value is one of the defined +values for the control, however in the config array there are several +entries where raw numbers have been used instead. Replace these +with the appropriate enum. + +Signed-off-by: Dave Stevenson +--- + .../vc04_services/bcm2835-camera/controls.c | 37 +++++++------------ + 1 file changed, 13 insertions(+), 24 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-camera/controls.c ++++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c +@@ -58,19 +58,6 @@ static const uint32_t iso_values[] = { + 0, 100, 200, 400, 800, + }; + +-static const s64 mains_freq_qmenu[] = { +- V4L2_CID_POWER_LINE_FREQUENCY_DISABLED, +- V4L2_CID_POWER_LINE_FREQUENCY_50HZ, +- V4L2_CID_POWER_LINE_FREQUENCY_60HZ, +- V4L2_CID_POWER_LINE_FREQUENCY_AUTO +-}; +- +-/* Supported video encode modes */ +-static const s64 bitrate_mode_qmenu[] = { +- (s64)V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, +- (s64)V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, +-}; +- + enum bm2835_mmal_ctrl_type { + MMAL_CONTROL_TYPE_STD, + MMAL_CONTROL_TYPE_STD_MENU, +@@ -966,8 +953,8 @@ static const struct bm2835_mmal_v4l2_ctr + }, + { + V4L2_CID_ISO_SENSITIVITY_AUTO, MMAL_CONTROL_TYPE_STD_MENU, +- 0, 1, V4L2_ISO_SENSITIVITY_AUTO, 1, NULL, +- MMAL_PARAMETER_ISO, ++ 0, V4L2_ISO_SENSITIVITY_AUTO, V4L2_ISO_SENSITIVITY_AUTO, 1, ++ NULL, MMAL_PARAMETER_ISO, + &ctrl_set_iso, + false + }, +@@ -984,8 +971,8 @@ static const struct bm2835_mmal_v4l2_ctr + */ + { + V4L2_CID_EXPOSURE_AUTO, MMAL_CONTROL_TYPE_STD_MENU, +- ~0x03, 3, V4L2_EXPOSURE_AUTO, 0, NULL, +- MMAL_PARAMETER_EXPOSURE_MODE, ++ ~0x03, V4L2_EXPOSURE_APERTURE_PRIORITY, V4L2_EXPOSURE_AUTO, 0, ++ NULL, MMAL_PARAMETER_EXPOSURE_MODE, + &ctrl_set_exposure, + false + }, +@@ -1021,7 +1008,8 @@ static const struct bm2835_mmal_v4l2_ctr + { + V4L2_CID_EXPOSURE_METERING, + MMAL_CONTROL_TYPE_STD_MENU, +- ~0x7, 2, V4L2_EXPOSURE_METERING_AVERAGE, 0, NULL, ++ ~0x7, V4L2_EXPOSURE_METERING_SPOT, ++ V4L2_EXPOSURE_METERING_AVERAGE, 0, NULL, + MMAL_PARAMETER_EXP_METERING_MODE, + &ctrl_set_metering_mode, + false +@@ -1029,7 +1017,8 @@ static const struct bm2835_mmal_v4l2_ctr + { + V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE, + MMAL_CONTROL_TYPE_STD_MENU, +- ~0x3ff, 9, V4L2_WHITE_BALANCE_AUTO, 0, NULL, ++ ~0x3ff, V4L2_WHITE_BALANCE_SHADE, V4L2_WHITE_BALANCE_AUTO, 0, ++ NULL, + MMAL_PARAMETER_AWB_MODE, + &ctrl_set_awb_mode, + false +@@ -1050,7 +1039,7 @@ static const struct bm2835_mmal_v4l2_ctr + }, + { + V4L2_CID_COLORFX, MMAL_CONTROL_TYPE_STD_MENU, +- 0, 15, V4L2_COLORFX_NONE, 0, NULL, ++ 0, V4L2_COLORFX_SET_CBCR, V4L2_COLORFX_NONE, 0, NULL, + MMAL_PARAMETER_IMAGE_EFFECT, + &ctrl_set_image_effect, + false +@@ -1085,8 +1074,8 @@ static const struct bm2835_mmal_v4l2_ctr + }, + { + V4L2_CID_MPEG_VIDEO_BITRATE_MODE, MMAL_CONTROL_TYPE_STD_MENU, +- 0, ARRAY_SIZE(bitrate_mode_qmenu) - 1, +- 0, 0, bitrate_mode_qmenu, ++ 0, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, ++ 0, 0, NULL, + MMAL_PARAMETER_RATECONTROL, + &ctrl_set_bitrate_mode, + false +@@ -1108,8 +1097,8 @@ static const struct bm2835_mmal_v4l2_ctr + }, + { + V4L2_CID_POWER_LINE_FREQUENCY, MMAL_CONTROL_TYPE_STD_MENU, +- 0, ARRAY_SIZE(mains_freq_qmenu) - 1, +- 1, 1, mains_freq_qmenu, ++ 0, V4L2_CID_POWER_LINE_FREQUENCY_AUTO, ++ 1, 1, NULL, + MMAL_PARAMETER_FLICKER_AVOID, + &ctrl_set_flicker_avoidance, + false diff --git a/target/linux/brcm2708/patches-4.19/950-0262-staging-bcm2835-camera-Correct-V4L2_CID_COLORFX_CBCR.patch b/target/linux/brcm2708/patches-4.19/950-0262-staging-bcm2835-camera-Correct-V4L2_CID_COLORFX_CBCR.patch new file mode 100644 index 0000000000..2efd437f3b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0262-staging-bcm2835-camera-Correct-V4L2_CID_COLORFX_CBCR.patch @@ -0,0 +1,34 @@ +From d0b848e7dde7eb67abd7cd14a2746ee09ffcfacb Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 8 Oct 2018 18:26:15 +0100 +Subject: [PATCH 262/725] staging: bcm2835-camera: Correct + V4L2_CID_COLORFX_CBCR behaviour + +With V4L2_CID_COLORFX_CBCR calling ctrl_set_colfx it was incorrectly +assigning the colour values to the enable field of dev->colourfx +instead of the u and v fields. + +Correct the assignments. + +Reported as a Coverity issue +Detected by CoverityScan CID#1419711 ("Unused value") + +Reported-by: Colin Ian King +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/bcm2835-camera/controls.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-camera/controls.c ++++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c +@@ -578,8 +578,8 @@ static int ctrl_set_colfx(struct bm2835_ + + control = &dev->component[COMP_CAMERA]->control; + +- dev->colourfx.enable = (ctrl->val & 0xff00) >> 8; +- dev->colourfx.enable = ctrl->val & 0xff; ++ dev->colourfx.u = (ctrl->val & 0xff00) >> 8; ++ dev->colourfx.v = ctrl->val & 0xff; + + ret = vchiq_mmal_port_parameter_set(dev->instance, control, + MMAL_PARAMETER_COLOUR_EFFECT, diff --git a/target/linux/brcm2708/patches-4.19/950-0262-staging-bcm2835-camera-Fix-multiple-assignments-shou.patch b/target/linux/brcm2708/patches-4.19/950-0262-staging-bcm2835-camera-Fix-multiple-assignments-shou.patch deleted file mode 100644 index d257efa70e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0262-staging-bcm2835-camera-Fix-multiple-assignments-shou.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 39d27efce4fe6c36ae65c34b73ff1024ec4fbf0e Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 29 Oct 2018 15:58:14 +0000 -Subject: [PATCH 262/703] staging: bcm2835-camera: Fix multiple assignments - should be avoided - -Clear checkpatch complaints of "multiple assignments should be avoided" - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c -+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c -@@ -1065,11 +1065,12 @@ static int mmal_setup_components(struct - /* Make a further decision on port based on resolution */ - if (f->fmt.pix.width <= max_video_width && - f->fmt.pix.height <= max_video_height) -- camera_port = port = -+ camera_port = - &dev->component[COMP_CAMERA]->output[CAM_PORT_VIDEO]; - else -- camera_port = port = -+ camera_port = - &dev->component[COMP_CAMERA]->output[CAM_PORT_CAPTURE]; -+ port = camera_port; - break; - case COMP_IMAGE_ENCODE: - encode_component = dev->component[COMP_IMAGE_ENCODE]; diff --git a/target/linux/brcm2708/patches-4.19/950-0263-staging-bcm2835-camera-Fix-up-all-formatting-in-mmal.patch b/target/linux/brcm2708/patches-4.19/950-0263-staging-bcm2835-camera-Fix-up-all-formatting-in-mmal.patch deleted file mode 100644 index 44ac11e075..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0263-staging-bcm2835-camera-Fix-up-all-formatting-in-mmal.patch +++ /dev/null @@ -1,336 +0,0 @@ -From 9ae2700167c495dba01b1625ab62e407b660c86c Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 29 Oct 2018 16:08:41 +0000 -Subject: [PATCH 263/703] staging: bcm2835-camera: Fix up all formatting in - mmal-paramters.h - -Fixes up all checkpatch errors in mmal-parameters.h - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-camera/mmal-parameters.h | 273 +++++++++++------- - 1 file changed, 165 insertions(+), 108 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h -+++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h -@@ -23,148 +23,204 @@ - #define MMAL_PARAMETERS_H - - /** Common parameter ID group, used with many types of component. */ --#define MMAL_PARAMETER_GROUP_COMMON (0 << 16) -+#define MMAL_PARAMETER_GROUP_COMMON (0 << 16) - /** Camera-specific parameter ID group. */ --#define MMAL_PARAMETER_GROUP_CAMERA (1 << 16) -+#define MMAL_PARAMETER_GROUP_CAMERA (1 << 16) - /** Video-specific parameter ID group. */ --#define MMAL_PARAMETER_GROUP_VIDEO (2 << 16) -+#define MMAL_PARAMETER_GROUP_VIDEO (2 << 16) - /** Audio-specific parameter ID group. */ --#define MMAL_PARAMETER_GROUP_AUDIO (3 << 16) -+#define MMAL_PARAMETER_GROUP_AUDIO (3 << 16) - /** Clock-specific parameter ID group. */ --#define MMAL_PARAMETER_GROUP_CLOCK (4 << 16) -+#define MMAL_PARAMETER_GROUP_CLOCK (4 << 16) - /** Miracast-specific parameter ID group. */ --#define MMAL_PARAMETER_GROUP_MIRACAST (5 << 16) -+#define MMAL_PARAMETER_GROUP_MIRACAST (5 << 16) - - /* Common parameters */ - enum mmal_parameter_common_type { -- MMAL_PARAMETER_UNUSED /**< Never a valid parameter ID */ -- = MMAL_PARAMETER_GROUP_COMMON, -- MMAL_PARAMETER_SUPPORTED_ENCODINGS, /**< MMAL_PARAMETER_ENCODING_T */ -- MMAL_PARAMETER_URI, /**< MMAL_PARAMETER_URI_T */ -+ /**< Never a valid parameter ID */ -+ MMAL_PARAMETER_UNUSED = MMAL_PARAMETER_GROUP_COMMON, - -- /** MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T */ -+ /**< MMAL_PARAMETER_ENCODING_T */ -+ MMAL_PARAMETER_SUPPORTED_ENCODINGS, -+ /**< MMAL_PARAMETER_URI_T */ -+ MMAL_PARAMETER_URI, -+ /** MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T */ - MMAL_PARAMETER_CHANGE_EVENT_REQUEST, -- -- /** MMAL_PARAMETER_BOOLEAN_T */ -+ /** MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_ZERO_COPY, -- -- /**< MMAL_PARAMETER_BUFFER_REQUIREMENTS_T */ -+ /**< MMAL_PARAMETER_BUFFER_REQUIREMENTS_T */ - MMAL_PARAMETER_BUFFER_REQUIREMENTS, -- -- MMAL_PARAMETER_STATISTICS, /**< MMAL_PARAMETER_STATISTICS_T */ -- MMAL_PARAMETER_CORE_STATISTICS, /**< MMAL_PARAMETER_CORE_STATISTICS_T */ -- MMAL_PARAMETER_MEM_USAGE, /**< MMAL_PARAMETER_MEM_USAGE_T */ -- MMAL_PARAMETER_BUFFER_FLAG_FILTER, /**< MMAL_PARAMETER_UINT32_T */ -- MMAL_PARAMETER_SEEK, /**< MMAL_PARAMETER_SEEK_T */ -- MMAL_PARAMETER_POWERMON_ENABLE, /**< MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_LOGGING, /**< MMAL_PARAMETER_LOGGING_T */ -- MMAL_PARAMETER_SYSTEM_TIME, /**< MMAL_PARAMETER_UINT64_T */ -- MMAL_PARAMETER_NO_IMAGE_PADDING /**< MMAL_PARAMETER_BOOLEAN_T */ -+ /**< MMAL_PARAMETER_STATISTICS_T */ -+ MMAL_PARAMETER_STATISTICS, -+ /**< MMAL_PARAMETER_CORE_STATISTICS_T */ -+ MMAL_PARAMETER_CORE_STATISTICS, -+ /**< MMAL_PARAMETER_MEM_USAGE_T */ -+ MMAL_PARAMETER_MEM_USAGE, -+ /**< MMAL_PARAMETER_UINT32_T */ -+ MMAL_PARAMETER_BUFFER_FLAG_FILTER, -+ /**< MMAL_PARAMETER_SEEK_T */ -+ MMAL_PARAMETER_SEEK, -+ /**< MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_POWERMON_ENABLE, -+ /**< MMAL_PARAMETER_LOGGING_T */ -+ MMAL_PARAMETER_LOGGING, -+ /**< MMAL_PARAMETER_UINT64_T */ -+ MMAL_PARAMETER_SYSTEM_TIME, -+ /**< MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_NO_IMAGE_PADDING, - }; - - /* camera parameters */ - - enum mmal_parameter_camera_type { - /* 0 */ -- /** @ref MMAL_PARAMETER_THUMBNAIL_CONFIG_T */ -- MMAL_PARAMETER_THUMBNAIL_CONFIGURATION -- = MMAL_PARAMETER_GROUP_CAMERA, -- MMAL_PARAMETER_CAPTURE_QUALITY, /**< Unused? */ -- MMAL_PARAMETER_ROTATION, /**< @ref MMAL_PARAMETER_INT32_T */ -- MMAL_PARAMETER_EXIF_DISABLE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_EXIF, /**< @ref MMAL_PARAMETER_EXIF_T */ -- MMAL_PARAMETER_AWB_MODE, /**< @ref MMAL_PARAM_AWBMODE_T */ -- MMAL_PARAMETER_IMAGE_EFFECT, /**< @ref MMAL_PARAMETER_IMAGEFX_T */ -- MMAL_PARAMETER_COLOUR_EFFECT, /**< @ref MMAL_PARAMETER_COLOURFX_T */ -- MMAL_PARAMETER_FLICKER_AVOID, /**< @ref MMAL_PARAMETER_FLICKERAVOID_T */ -- MMAL_PARAMETER_FLASH, /**< @ref MMAL_PARAMETER_FLASH_T */ -- MMAL_PARAMETER_REDEYE, /**< @ref MMAL_PARAMETER_REDEYE_T */ -- MMAL_PARAMETER_FOCUS, /**< @ref MMAL_PARAMETER_FOCUS_T */ -- MMAL_PARAMETER_FOCAL_LENGTHS, /**< Unused? */ -- MMAL_PARAMETER_EXPOSURE_COMP, /**< @ref MMAL_PARAMETER_INT32_T */ -- MMAL_PARAMETER_ZOOM, /**< @ref MMAL_PARAMETER_SCALEFACTOR_T */ -- MMAL_PARAMETER_MIRROR, /**< @ref MMAL_PARAMETER_MIRROR_T */ -+ /** @ref MMAL_PARAMETER_THUMBNAIL_CONFIG_T */ -+ MMAL_PARAMETER_THUMBNAIL_CONFIGURATION = -+ MMAL_PARAMETER_GROUP_CAMERA, -+ /**< Unused? */ -+ MMAL_PARAMETER_CAPTURE_QUALITY, -+ /**< @ref MMAL_PARAMETER_INT32_T */ -+ MMAL_PARAMETER_ROTATION, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_EXIF_DISABLE, -+ /**< @ref MMAL_PARAMETER_EXIF_T */ -+ MMAL_PARAMETER_EXIF, -+ /**< @ref MMAL_PARAM_AWBMODE_T */ -+ MMAL_PARAMETER_AWB_MODE, -+ /**< @ref MMAL_PARAMETER_IMAGEFX_T */ -+ MMAL_PARAMETER_IMAGE_EFFECT, -+ /**< @ref MMAL_PARAMETER_COLOURFX_T */ -+ MMAL_PARAMETER_COLOUR_EFFECT, -+ /**< @ref MMAL_PARAMETER_FLICKERAVOID_T */ -+ MMAL_PARAMETER_FLICKER_AVOID, -+ /**< @ref MMAL_PARAMETER_FLASH_T */ -+ MMAL_PARAMETER_FLASH, -+ /**< @ref MMAL_PARAMETER_REDEYE_T */ -+ MMAL_PARAMETER_REDEYE, -+ /**< @ref MMAL_PARAMETER_FOCUS_T */ -+ MMAL_PARAMETER_FOCUS, -+ /**< Unused? */ -+ MMAL_PARAMETER_FOCAL_LENGTHS, -+ /**< @ref MMAL_PARAMETER_INT32_T */ -+ MMAL_PARAMETER_EXPOSURE_COMP, -+ /**< @ref MMAL_PARAMETER_SCALEFACTOR_T */ -+ MMAL_PARAMETER_ZOOM, -+ /**< @ref MMAL_PARAMETER_MIRROR_T */ -+ MMAL_PARAMETER_MIRROR, - - /* 0x10 */ -- MMAL_PARAMETER_CAMERA_NUM, /**< @ref MMAL_PARAMETER_UINT32_T */ -- MMAL_PARAMETER_CAPTURE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_EXPOSURE_MODE, /**< @ref MMAL_PARAMETER_EXPOSUREMODE_T */ -- MMAL_PARAMETER_EXP_METERING_MODE, /**< @ref MMAL_PARAMETER_EXPOSUREMETERINGMODE_T */ -- MMAL_PARAMETER_FOCUS_STATUS, /**< @ref MMAL_PARAMETER_FOCUS_STATUS_T */ -- MMAL_PARAMETER_CAMERA_CONFIG, /**< @ref MMAL_PARAMETER_CAMERA_CONFIG_T */ -- MMAL_PARAMETER_CAPTURE_STATUS, /**< @ref MMAL_PARAMETER_CAPTURE_STATUS_T */ -- MMAL_PARAMETER_FACE_TRACK, /**< @ref MMAL_PARAMETER_FACE_TRACK_T */ -- MMAL_PARAMETER_DRAW_BOX_FACES_AND_FOCUS, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_JPEG_Q_FACTOR, /**< @ref MMAL_PARAMETER_UINT32_T */ -- MMAL_PARAMETER_FRAME_RATE, /**< @ref MMAL_PARAMETER_FRAME_RATE_T */ -- MMAL_PARAMETER_USE_STC, /**< @ref MMAL_PARAMETER_CAMERA_STC_MODE_T */ -- MMAL_PARAMETER_CAMERA_INFO, /**< @ref MMAL_PARAMETER_CAMERA_INFO_T */ -- MMAL_PARAMETER_VIDEO_STABILISATION, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_FACE_TRACK_RESULTS, /**< @ref MMAL_PARAMETER_FACE_TRACK_RESULTS_T */ -- MMAL_PARAMETER_ENABLE_RAW_CAPTURE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ /**< @ref MMAL_PARAMETER_UINT32_T */ -+ MMAL_PARAMETER_CAMERA_NUM, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_CAPTURE, -+ /**< @ref MMAL_PARAMETER_EXPOSUREMODE_T */ -+ MMAL_PARAMETER_EXPOSURE_MODE, -+ /**< @ref MMAL_PARAMETER_EXPOSUREMETERINGMODE_T */ -+ MMAL_PARAMETER_EXP_METERING_MODE, -+ /**< @ref MMAL_PARAMETER_FOCUS_STATUS_T */ -+ MMAL_PARAMETER_FOCUS_STATUS, -+ /**< @ref MMAL_PARAMETER_CAMERA_CONFIG_T */ -+ MMAL_PARAMETER_CAMERA_CONFIG, -+ /**< @ref MMAL_PARAMETER_CAPTURE_STATUS_T */ -+ MMAL_PARAMETER_CAPTURE_STATUS, -+ /**< @ref MMAL_PARAMETER_FACE_TRACK_T */ -+ MMAL_PARAMETER_FACE_TRACK, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_DRAW_BOX_FACES_AND_FOCUS, -+ /**< @ref MMAL_PARAMETER_UINT32_T */ -+ MMAL_PARAMETER_JPEG_Q_FACTOR, -+ /**< @ref MMAL_PARAMETER_FRAME_RATE_T */ -+ MMAL_PARAMETER_FRAME_RATE, -+ /**< @ref MMAL_PARAMETER_CAMERA_STC_MODE_T */ -+ MMAL_PARAMETER_USE_STC, -+ /**< @ref MMAL_PARAMETER_CAMERA_INFO_T */ -+ MMAL_PARAMETER_CAMERA_INFO, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_VIDEO_STABILISATION, -+ /**< @ref MMAL_PARAMETER_FACE_TRACK_RESULTS_T */ -+ MMAL_PARAMETER_FACE_TRACK_RESULTS, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_ENABLE_RAW_CAPTURE, - - /* 0x20 */ -- MMAL_PARAMETER_DPF_FILE, /**< @ref MMAL_PARAMETER_URI_T */ -- MMAL_PARAMETER_ENABLE_DPF_FILE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_DPF_FAIL_IS_FATAL, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_CAPTURE_MODE, /**< @ref MMAL_PARAMETER_CAPTUREMODE_T */ -- MMAL_PARAMETER_FOCUS_REGIONS, /**< @ref MMAL_PARAMETER_FOCUS_REGIONS_T */ -- MMAL_PARAMETER_INPUT_CROP, /**< @ref MMAL_PARAMETER_INPUT_CROP_T */ -- MMAL_PARAMETER_SENSOR_INFORMATION, /**< @ref MMAL_PARAMETER_SENSOR_INFORMATION_T */ -- MMAL_PARAMETER_FLASH_SELECT, /**< @ref MMAL_PARAMETER_FLASH_SELECT_T */ -- MMAL_PARAMETER_FIELD_OF_VIEW, /**< @ref MMAL_PARAMETER_FIELD_OF_VIEW_T */ -- MMAL_PARAMETER_HIGH_DYNAMIC_RANGE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_DYNAMIC_RANGE_COMPRESSION, /**< @ref MMAL_PARAMETER_DRC_T */ -- MMAL_PARAMETER_ALGORITHM_CONTROL, /**< @ref MMAL_PARAMETER_ALGORITHM_CONTROL_T */ -- MMAL_PARAMETER_SHARPNESS, /**< @ref MMAL_PARAMETER_RATIONAL_T */ -- MMAL_PARAMETER_CONTRAST, /**< @ref MMAL_PARAMETER_RATIONAL_T */ -- MMAL_PARAMETER_BRIGHTNESS, /**< @ref MMAL_PARAMETER_RATIONAL_T */ -- MMAL_PARAMETER_SATURATION, /**< @ref MMAL_PARAMETER_RATIONAL_T */ -+ /**< @ref MMAL_PARAMETER_URI_T */ -+ MMAL_PARAMETER_DPF_FILE, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_ENABLE_DPF_FILE, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_DPF_FAIL_IS_FATAL, -+ /**< @ref MMAL_PARAMETER_CAPTUREMODE_T */ -+ MMAL_PARAMETER_CAPTURE_MODE, -+ /**< @ref MMAL_PARAMETER_FOCUS_REGIONS_T */ -+ MMAL_PARAMETER_FOCUS_REGIONS, -+ /**< @ref MMAL_PARAMETER_INPUT_CROP_T */ -+ MMAL_PARAMETER_INPUT_CROP, -+ /**< @ref MMAL_PARAMETER_SENSOR_INFORMATION_T */ -+ MMAL_PARAMETER_SENSOR_INFORMATION, -+ /**< @ref MMAL_PARAMETER_FLASH_SELECT_T */ -+ MMAL_PARAMETER_FLASH_SELECT, -+ /**< @ref MMAL_PARAMETER_FIELD_OF_VIEW_T */ -+ MMAL_PARAMETER_FIELD_OF_VIEW, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_HIGH_DYNAMIC_RANGE, -+ /**< @ref MMAL_PARAMETER_DRC_T */ -+ MMAL_PARAMETER_DYNAMIC_RANGE_COMPRESSION, -+ /**< @ref MMAL_PARAMETER_ALGORITHM_CONTROL_T */ -+ MMAL_PARAMETER_ALGORITHM_CONTROL, -+ /**< @ref MMAL_PARAMETER_RATIONAL_T */ -+ MMAL_PARAMETER_SHARPNESS, -+ /**< @ref MMAL_PARAMETER_RATIONAL_T */ -+ MMAL_PARAMETER_CONTRAST, -+ /**< @ref MMAL_PARAMETER_RATIONAL_T */ -+ MMAL_PARAMETER_BRIGHTNESS, -+ /**< @ref MMAL_PARAMETER_RATIONAL_T */ -+ MMAL_PARAMETER_SATURATION, - - /* 0x30 */ -- MMAL_PARAMETER_ISO, /**< @ref MMAL_PARAMETER_UINT32_T */ -- MMAL_PARAMETER_ANTISHAKE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- -- /** @ref MMAL_PARAMETER_IMAGEFX_PARAMETERS_T */ -+ /**< @ref MMAL_PARAMETER_UINT32_T */ -+ MMAL_PARAMETER_ISO, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_ANTISHAKE, -+ /** @ref MMAL_PARAMETER_IMAGEFX_PARAMETERS_T */ - MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, -- -- /** @ref MMAL_PARAMETER_BOOLEAN_T */ -+ /** @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_CAMERA_BURST_CAPTURE, -- -- /** @ref MMAL_PARAMETER_UINT32_T */ -+ /** @ref MMAL_PARAMETER_UINT32_T */ - MMAL_PARAMETER_CAMERA_MIN_ISO, -- -- /** @ref MMAL_PARAMETER_CAMERA_USE_CASE_T */ -+ /** @ref MMAL_PARAMETER_CAMERA_USE_CASE_T */ - MMAL_PARAMETER_CAMERA_USE_CASE, -- -- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_CAPTURE_STATS_PASS, -- -- /** @ref MMAL_PARAMETER_UINT32_T */ -+ /** @ref MMAL_PARAMETER_UINT32_T */ - MMAL_PARAMETER_CAMERA_CUSTOM_SENSOR_CONFIG, -- -- /** @ref MMAL_PARAMETER_BOOLEAN_T */ -+ /** @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_ENABLE_REGISTER_FILE, -- -- /** @ref MMAL_PARAMETER_BOOLEAN_T */ -+ /** @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_REGISTER_FAIL_IS_FATAL, -- -- /** @ref MMAL_PARAMETER_CONFIGFILE_T */ -+ /** @ref MMAL_PARAMETER_CONFIGFILE_T */ - MMAL_PARAMETER_CONFIGFILE_REGISTERS, -- -- /** @ref MMAL_PARAMETER_CONFIGFILE_CHUNK_T */ -+ /** @ref MMAL_PARAMETER_CONFIGFILE_CHUNK_T */ - MMAL_PARAMETER_CONFIGFILE_CHUNK_REGISTERS, -- MMAL_PARAMETER_JPEG_ATTACH_LOG, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_ZERO_SHUTTER_LAG, /**< @ref MMAL_PARAMETER_ZEROSHUTTERLAG_T */ -- MMAL_PARAMETER_FPS_RANGE, /**< @ref MMAL_PARAMETER_FPS_RANGE_T */ -- MMAL_PARAMETER_CAPTURE_EXPOSURE_COMP, /**< @ref MMAL_PARAMETER_INT32_T */ -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_JPEG_ATTACH_LOG, -+ /**< @ref MMAL_PARAMETER_ZEROSHUTTERLAG_T */ -+ MMAL_PARAMETER_ZERO_SHUTTER_LAG, -+ /**< @ref MMAL_PARAMETER_FPS_RANGE_T */ -+ MMAL_PARAMETER_FPS_RANGE, -+ /**< @ref MMAL_PARAMETER_INT32_T */ -+ MMAL_PARAMETER_CAPTURE_EXPOSURE_COMP, - - /* 0x40 */ -- MMAL_PARAMETER_SW_SHARPEN_DISABLE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_FLASH_REQUIRED, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_SW_SATURATION_DISABLE, /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_SHUTTER_SPEED, /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ -- MMAL_PARAMETER_CUSTOM_AWB_GAINS, /**< Takes a @ref MMAL_PARAMETER_AWB_GAINS_T */ -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_SW_SHARPEN_DISABLE, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_FLASH_REQUIRED, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_SW_SATURATION_DISABLE, -+ /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ -+ MMAL_PARAMETER_SHUTTER_SPEED, -+ /**< Takes a @ref MMAL_PARAMETER_AWB_GAINS_T */ -+ MMAL_PARAMETER_CUSTOM_AWB_GAINS, - }; - - struct mmal_parameter_rational { -@@ -411,7 +467,8 @@ enum mmal_parameter_video_type { - MMAL_PARAMETER_MINIMISE_FRAGMENTATION, - - /** @ref MMAL_PARAMETER_UINT32_T. -- * Setting the value to zero resets to the default (one slice per frame). -+ * Setting the value to zero resets to the default (one slice per -+ * frame). - */ - MMAL_PARAMETER_MB_ROWS_PER_SLICE, - diff --git a/target/linux/brcm2708/patches-4.19/950-0263-staging-bcm2835-camera-Remove-amend-some-obsolete-co.patch b/target/linux/brcm2708/patches-4.19/950-0263-staging-bcm2835-camera-Remove-amend-some-obsolete-co.patch new file mode 100644 index 0000000000..5917505f44 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0263-staging-bcm2835-camera-Remove-amend-some-obsolete-co.patch @@ -0,0 +1,49 @@ +From f214d9ca66942c23a839e5ba54524fa39a8e08b1 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 28 Sep 2018 10:22:26 +0100 +Subject: [PATCH 263/725] staging: bcm2835-camera: Remove/amend some obsolete + comments + +Remove a todo which has been done. +Remove a template line that was redundant. +Make a comment clearer as to the non-obvious meaning of a field. + +Signed-off-by: Dave Stevenson +--- + .../staging/vc04_services/bcm2835-camera/controls.c | 11 +---------- + 1 file changed, 1 insertion(+), 10 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-camera/controls.c ++++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c +@@ -965,10 +965,6 @@ static const struct bm2835_mmal_v4l2_ctr + &ctrl_set_value, + false + }, +-/* { +- * 0, MMAL_CONTROL_TYPE_CLUSTER, 3, 1, 0, NULL, 0, NULL +- * }, +- */ + { + V4L2_CID_EXPOSURE_AUTO, MMAL_CONTROL_TYPE_STD_MENU, + ~0x03, V4L2_EXPOSURE_APERTURE_PRIORITY, V4L2_EXPOSURE_AUTO, 0, +@@ -976,11 +972,6 @@ static const struct bm2835_mmal_v4l2_ctr + &ctrl_set_exposure, + false + }, +-/* todo this needs mixing in with set exposure +- * { +- * V4L2_CID_SCENE_MODE, MMAL_CONTROL_TYPE_STD_MENU, +- * }, +- */ + { + V4L2_CID_EXPOSURE_ABSOLUTE, MMAL_CONTROL_TYPE_STD, + /* Units of 100usecs */ +@@ -1146,7 +1137,7 @@ static const struct bm2835_mmal_v4l2_ctr + }, + { + V4L2_CID_SCENE_MODE, MMAL_CONTROL_TYPE_STD_MENU, +- -1, /* Min is computed at runtime */ ++ -1, /* Min (mask) is computed at runtime */ + V4L2_SCENE_MODE_TEXT, + V4L2_SCENE_MODE_NONE, 1, NULL, + MMAL_PARAMETER_PROFILE, diff --git a/target/linux/brcm2708/patches-4.19/950-0264-staging-bcm2835-camera-Use-enums-for-max-value-in-co.patch b/target/linux/brcm2708/patches-4.19/950-0264-staging-bcm2835-camera-Use-enums-for-max-value-in-co.patch deleted file mode 100644 index 24a4205549..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0264-staging-bcm2835-camera-Use-enums-for-max-value-in-co.patch +++ /dev/null @@ -1,112 +0,0 @@ -From cbfd21871e5882f8ffa73a7b5c96018409b683ea Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 28 Sep 2018 10:17:11 +0100 -Subject: [PATCH 264/703] staging: bcm2835-camera: Use enums for max value in - controls - -Controls of type MMAL_CONTROL_TYPE_STD_MENU call v4l2_ctrl_new_std_menu -with a max value and a mask. The max value is one of the defined -values for the control, however in the config array there are several -entries where raw numbers have been used instead. Replace these -with the appropriate enum. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/bcm2835-camera/controls.c | 37 +++++++------------ - 1 file changed, 13 insertions(+), 24 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-camera/controls.c -+++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c -@@ -58,19 +58,6 @@ static const uint32_t iso_values[] = { - 0, 100, 200, 400, 800, - }; - --static const s64 mains_freq_qmenu[] = { -- V4L2_CID_POWER_LINE_FREQUENCY_DISABLED, -- V4L2_CID_POWER_LINE_FREQUENCY_50HZ, -- V4L2_CID_POWER_LINE_FREQUENCY_60HZ, -- V4L2_CID_POWER_LINE_FREQUENCY_AUTO --}; -- --/* Supported video encode modes */ --static const s64 bitrate_mode_qmenu[] = { -- (s64)V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, -- (s64)V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, --}; -- - enum bm2835_mmal_ctrl_type { - MMAL_CONTROL_TYPE_STD, - MMAL_CONTROL_TYPE_STD_MENU, -@@ -966,8 +953,8 @@ static const struct bm2835_mmal_v4l2_ctr - }, - { - V4L2_CID_ISO_SENSITIVITY_AUTO, MMAL_CONTROL_TYPE_STD_MENU, -- 0, 1, V4L2_ISO_SENSITIVITY_AUTO, 1, NULL, -- MMAL_PARAMETER_ISO, -+ 0, V4L2_ISO_SENSITIVITY_AUTO, V4L2_ISO_SENSITIVITY_AUTO, 1, -+ NULL, MMAL_PARAMETER_ISO, - &ctrl_set_iso, - false - }, -@@ -984,8 +971,8 @@ static const struct bm2835_mmal_v4l2_ctr - */ - { - V4L2_CID_EXPOSURE_AUTO, MMAL_CONTROL_TYPE_STD_MENU, -- ~0x03, 3, V4L2_EXPOSURE_AUTO, 0, NULL, -- MMAL_PARAMETER_EXPOSURE_MODE, -+ ~0x03, V4L2_EXPOSURE_APERTURE_PRIORITY, V4L2_EXPOSURE_AUTO, 0, -+ NULL, MMAL_PARAMETER_EXPOSURE_MODE, - &ctrl_set_exposure, - false - }, -@@ -1021,7 +1008,8 @@ static const struct bm2835_mmal_v4l2_ctr - { - V4L2_CID_EXPOSURE_METERING, - MMAL_CONTROL_TYPE_STD_MENU, -- ~0x7, 2, V4L2_EXPOSURE_METERING_AVERAGE, 0, NULL, -+ ~0x7, V4L2_EXPOSURE_METERING_SPOT, -+ V4L2_EXPOSURE_METERING_AVERAGE, 0, NULL, - MMAL_PARAMETER_EXP_METERING_MODE, - &ctrl_set_metering_mode, - false -@@ -1029,7 +1017,8 @@ static const struct bm2835_mmal_v4l2_ctr - { - V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE, - MMAL_CONTROL_TYPE_STD_MENU, -- ~0x3ff, 9, V4L2_WHITE_BALANCE_AUTO, 0, NULL, -+ ~0x3ff, V4L2_WHITE_BALANCE_SHADE, V4L2_WHITE_BALANCE_AUTO, 0, -+ NULL, - MMAL_PARAMETER_AWB_MODE, - &ctrl_set_awb_mode, - false -@@ -1050,7 +1039,7 @@ static const struct bm2835_mmal_v4l2_ctr - }, - { - V4L2_CID_COLORFX, MMAL_CONTROL_TYPE_STD_MENU, -- 0, 15, V4L2_COLORFX_NONE, 0, NULL, -+ 0, V4L2_COLORFX_SET_CBCR, V4L2_COLORFX_NONE, 0, NULL, - MMAL_PARAMETER_IMAGE_EFFECT, - &ctrl_set_image_effect, - false -@@ -1085,8 +1074,8 @@ static const struct bm2835_mmal_v4l2_ctr - }, - { - V4L2_CID_MPEG_VIDEO_BITRATE_MODE, MMAL_CONTROL_TYPE_STD_MENU, -- 0, ARRAY_SIZE(bitrate_mode_qmenu) - 1, -- 0, 0, bitrate_mode_qmenu, -+ 0, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, -+ 0, 0, NULL, - MMAL_PARAMETER_RATECONTROL, - &ctrl_set_bitrate_mode, - false -@@ -1108,8 +1097,8 @@ static const struct bm2835_mmal_v4l2_ctr - }, - { - V4L2_CID_POWER_LINE_FREQUENCY, MMAL_CONTROL_TYPE_STD_MENU, -- 0, ARRAY_SIZE(mains_freq_qmenu) - 1, -- 1, 1, mains_freq_qmenu, -+ 0, V4L2_CID_POWER_LINE_FREQUENCY_AUTO, -+ 1, 1, NULL, - MMAL_PARAMETER_FLICKER_AVOID, - &ctrl_set_flicker_avoidance, - false diff --git a/target/linux/brcm2708/patches-4.19/950-0264-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch b/target/linux/brcm2708/patches-4.19/950-0264-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch new file mode 100644 index 0000000000..6445d776da --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0264-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch @@ -0,0 +1,7535 @@ +From 5ba9f10bdb359e285f9052484814ef61a7bcb276 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 24 Sep 2018 16:30:37 +0100 +Subject: [PATCH 264/725] staging: vc04_services: Split vchiq-mmal into a + module + +In preparation for adding a video codec V4L2 module which also +wants to use vchiq-mmal functions, split it out into an +independent module. +The minimum number of changes have been made to achieve this +(eg straight moves where possible) so existing checkpatch +errors will still be present. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/Kconfig | 1 + + drivers/staging/vc04_services/Makefile | 1 + + .../vc04_services/bcm2835-camera/Kconfig | 2 +- + .../vc04_services/bcm2835-camera/Makefile | 4 ++-- + .../staging/vc04_services/vchiq-mmal/Kconfig | 7 ++++++ + .../staging/vc04_services/vchiq-mmal/Makefile | 8 +++++++ + .../mmal-common.h | 0 + .../mmal-encodings.h | 0 + .../mmal-msg-common.h | 0 + .../mmal-msg-format.h | 0 + .../mmal-msg-port.h | 0 + .../{bcm2835-camera => vchiq-mmal}/mmal-msg.h | 0 + .../mmal-parameters.h | 0 + .../mmal-vchiq.c | 22 +++++++++++++++++++ + .../mmal-vchiq.h | 0 + 15 files changed, 42 insertions(+), 3 deletions(-) + create mode 100644 drivers/staging/vc04_services/vchiq-mmal/Kconfig + create mode 100644 drivers/staging/vc04_services/vchiq-mmal/Makefile + rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-common.h (100%) + rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-encodings.h (100%) + rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-msg-common.h (100%) + rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-msg-format.h (100%) + rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-msg-port.h (100%) + rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-msg.h (100%) + rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-parameters.h (100%) + rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-vchiq.c (98%) + rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-vchiq.h (100%) + +--- a/drivers/staging/vc04_services/Kconfig ++++ b/drivers/staging/vc04_services/Kconfig +@@ -21,6 +21,7 @@ config BCM2835_VCHIQ + source "drivers/staging/vc04_services/bcm2835-audio/Kconfig" + + source "drivers/staging/vc04_services/bcm2835-camera/Kconfig" ++source "drivers/staging/vc04_services/vchiq-mmal/Kconfig" + + endif + +--- a/drivers/staging/vc04_services/Makefile ++++ b/drivers/staging/vc04_services/Makefile +@@ -12,6 +12,7 @@ vchiq-objs := \ + + obj-$(CONFIG_SND_BCM2835) += bcm2835-audio/ + obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-camera/ ++obj-$(CONFIG_BCM2835_VCHIQ_MMAL) += vchiq-mmal/ + + ccflags-y += -Idrivers/staging/vc04_services -D__VCCOREVER__=0x04000000 + +--- a/drivers/staging/vc04_services/bcm2835-camera/Kconfig ++++ b/drivers/staging/vc04_services/bcm2835-camera/Kconfig +@@ -2,7 +2,7 @@ config VIDEO_BCM2835 + tristate "BCM2835 Camera" + depends on MEDIA_SUPPORT + depends on VIDEO_V4L2 && (ARCH_BCM2835 || COMPILE_TEST) +- select BCM2835_VCHIQ ++ select BCM2835_VCHIQ_MMAL + select VIDEOBUF2_VMALLOC + select BTREE + help +--- a/drivers/staging/vc04_services/bcm2835-camera/Makefile ++++ b/drivers/staging/vc04_services/bcm2835-camera/Makefile +@@ -1,11 +1,11 @@ + # SPDX-License-Identifier: GPL-2.0 + bcm2835-v4l2-$(CONFIG_VIDEO_BCM2835) := \ + bcm2835-camera.o \ +- controls.o \ +- mmal-vchiq.o ++ controls.o + + obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-v4l2.o + + ccflags-y += \ + -Idrivers/staging/vc04_services \ ++ -Idrivers/staging/vc04_services/vchiq-mmal \ + -D__VCCOREVER__=0x04000000 +--- /dev/null ++++ b/drivers/staging/vc04_services/vchiq-mmal/Kconfig +@@ -0,0 +1,7 @@ ++config BCM2835_VCHIQ_MMAL ++ tristate "BCM2835 MMAL VCHIQ service" ++ depends on (ARCH_BCM2835 || COMPILE_TEST) ++ select BCM2835_VCHIQ ++ help ++ Enables the MMAL API over VCHIQ as used for the ++ majority of the multimedia services on VideoCore. +--- /dev/null ++++ b/drivers/staging/vc04_services/vchiq-mmal/Makefile +@@ -0,0 +1,8 @@ ++# SPDX-License-Identifier: GPL-2.0 ++bcm2835-mmal-vchiq-objs := mmal-vchiq.o ++ ++obj-$(CONFIG_BCM2835_VCHIQ_MMAL) += bcm2835-mmal-vchiq.o ++ ++ccflags-y += \ ++ -Idrivers/staging/vc04_services \ ++ -D__VCCOREVER__=0x04000000 +--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c ++++ /dev/null +@@ -1,1899 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +-/* +- * Broadcom BM2835 V4L2 driver +- * +- * Copyright © 2013 Raspberry Pi (Trading) Ltd. +- * +- * Authors: Vincent Sanders @ Collabora +- * Dave Stevenson @ Broadcom +- * (now dave.stevenson@raspberrypi.org) +- * Simon Mellor @ Broadcom +- * Luke Diamand @ Broadcom +- * +- * V4L2 driver MMAL vchiq interface code +- */ +- +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "mmal-common.h" +-#include "mmal-vchiq.h" +-#include "mmal-msg.h" +- +-#define USE_VCHIQ_ARM +-#include "interface/vchi/vchi.h" +- +-/* maximum number of components supported */ +-#define VCHIQ_MMAL_MAX_COMPONENTS 4 +- +-/*#define FULL_MSG_DUMP 1*/ +- +-#ifdef DEBUG +-static const char *const msg_type_names[] = { +- "UNKNOWN", +- "QUIT", +- "SERVICE_CLOSED", +- "GET_VERSION", +- "COMPONENT_CREATE", +- "COMPONENT_DESTROY", +- "COMPONENT_ENABLE", +- "COMPONENT_DISABLE", +- "PORT_INFO_GET", +- "PORT_INFO_SET", +- "PORT_ACTION", +- "BUFFER_FROM_HOST", +- "BUFFER_TO_HOST", +- "GET_STATS", +- "PORT_PARAMETER_SET", +- "PORT_PARAMETER_GET", +- "EVENT_TO_HOST", +- "GET_CORE_STATS_FOR_PORT", +- "OPAQUE_ALLOCATOR", +- "CONSUME_MEM", +- "LMK", +- "OPAQUE_ALLOCATOR_DESC", +- "DRM_GET_LHS32", +- "DRM_GET_TIME", +- "BUFFER_FROM_HOST_ZEROLEN", +- "PORT_FLUSH", +- "HOST_LOG", +-}; +-#endif +- +-static const char *const port_action_type_names[] = { +- "UNKNOWN", +- "ENABLE", +- "DISABLE", +- "FLUSH", +- "CONNECT", +- "DISCONNECT", +- "SET_REQUIREMENTS", +-}; +- +-#if defined(DEBUG) +-#if defined(FULL_MSG_DUMP) +-#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE) \ +- do { \ +- pr_debug(TITLE" type:%s(%d) length:%d\n", \ +- msg_type_names[(MSG)->h.type], \ +- (MSG)->h.type, (MSG_LEN)); \ +- print_hex_dump(KERN_DEBUG, "<h.type], \ +- (MSG)->h.type, (MSG_LEN)); \ +- } +-#endif +-#else +-#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE) +-#endif +- +-struct vchiq_mmal_instance; +- +-/* normal message context */ +-struct mmal_msg_context { +- struct vchiq_mmal_instance *instance; +- +- /* Index in the context_map idr so that we can find the +- * mmal_msg_context again when servicing the VCHI reply. +- */ +- int handle; +- +- union { +- struct { +- /* work struct for buffer_cb callback */ +- struct work_struct work; +- /* work struct for deferred callback */ +- struct work_struct buffer_to_host_work; +- /* mmal instance */ +- struct vchiq_mmal_instance *instance; +- /* mmal port */ +- struct vchiq_mmal_port *port; +- /* actual buffer used to store bulk reply */ +- struct mmal_buffer *buffer; +- /* amount of buffer used */ +- unsigned long buffer_used; +- /* MMAL buffer flags */ +- u32 mmal_flags; +- /* Presentation and Decode timestamps */ +- s64 pts; +- s64 dts; +- +- int status; /* context status */ +- +- } bulk; /* bulk data */ +- +- struct { +- /* message handle to release */ +- VCHI_HELD_MSG_T msg_handle; +- /* pointer to received message */ +- struct mmal_msg *msg; +- /* received message length */ +- u32 msg_len; +- /* completion upon reply */ +- struct completion cmplt; +- } sync; /* synchronous response */ +- } u; +- +-}; +- +-struct vchiq_mmal_instance { +- VCHI_SERVICE_HANDLE_T handle; +- +- /* ensure serialised access to service */ +- struct mutex vchiq_mutex; +- +- /* vmalloc page to receive scratch bulk xfers into */ +- void *bulk_scratch; +- +- struct idr context_map; +- /* protect accesses to context_map */ +- struct mutex context_map_lock; +- +- /* component to use next */ +- int component_idx; +- struct vchiq_mmal_component component[VCHIQ_MMAL_MAX_COMPONENTS]; +- +- /* ordered workqueue to process all bulk operations */ +- struct workqueue_struct *bulk_wq; +-}; +- +-static struct mmal_msg_context * +-get_msg_context(struct vchiq_mmal_instance *instance) +-{ +- struct mmal_msg_context *msg_context; +- int handle; +- +- /* todo: should this be allocated from a pool to avoid kzalloc */ +- msg_context = kzalloc(sizeof(*msg_context), GFP_KERNEL); +- +- if (!msg_context) +- return ERR_PTR(-ENOMEM); +- +- /* Create an ID that will be passed along with our message so +- * that when we service the VCHI reply, we can look up what +- * message is being replied to. +- */ +- mutex_lock(&instance->context_map_lock); +- handle = idr_alloc(&instance->context_map, msg_context, +- 0, 0, GFP_KERNEL); +- mutex_unlock(&instance->context_map_lock); +- +- if (handle < 0) { +- kfree(msg_context); +- return ERR_PTR(handle); +- } +- +- msg_context->instance = instance; +- msg_context->handle = handle; +- +- return msg_context; +-} +- +-static struct mmal_msg_context * +-lookup_msg_context(struct vchiq_mmal_instance *instance, int handle) +-{ +- return idr_find(&instance->context_map, handle); +-} +- +-static void +-release_msg_context(struct mmal_msg_context *msg_context) +-{ +- struct vchiq_mmal_instance *instance = msg_context->instance; +- +- mutex_lock(&instance->context_map_lock); +- idr_remove(&instance->context_map, msg_context->handle); +- mutex_unlock(&instance->context_map_lock); +- kfree(msg_context); +-} +- +-/* deals with receipt of event to host message */ +-static void event_to_host_cb(struct vchiq_mmal_instance *instance, +- struct mmal_msg *msg, u32 msg_len) +-{ +- pr_debug("unhandled event\n"); +- pr_debug("component:%u port type:%d num:%d cmd:0x%x length:%d\n", +- msg->u.event_to_host.client_component, +- msg->u.event_to_host.port_type, +- msg->u.event_to_host.port_num, +- msg->u.event_to_host.cmd, msg->u.event_to_host.length); +-} +- +-/* workqueue scheduled callback +- * +- * we do this because it is important we do not call any other vchiq +- * sync calls from witin the message delivery thread +- */ +-static void buffer_work_cb(struct work_struct *work) +-{ +- struct mmal_msg_context *msg_context = +- container_of(work, struct mmal_msg_context, u.bulk.work); +- +- atomic_dec(&msg_context->u.bulk.port->buffers_with_vpu); +- +- msg_context->u.bulk.port->buffer_cb(msg_context->u.bulk.instance, +- msg_context->u.bulk.port, +- msg_context->u.bulk.status, +- msg_context->u.bulk.buffer, +- msg_context->u.bulk.buffer_used, +- msg_context->u.bulk.mmal_flags, +- msg_context->u.bulk.dts, +- msg_context->u.bulk.pts); +-} +- +-/* workqueue scheduled callback to handle receiving buffers +- * +- * VCHI will allow up to 4 bulk receives to be scheduled before blocking. +- * If we block in the service_callback context then we can't process the +- * VCHI_CALLBACK_BULK_RECEIVED message that would otherwise allow the blocked +- * vchi_bulk_queue_receive() call to complete. +- */ +-static void buffer_to_host_work_cb(struct work_struct *work) +-{ +- struct mmal_msg_context *msg_context = +- container_of(work, struct mmal_msg_context, +- u.bulk.buffer_to_host_work); +- struct vchiq_mmal_instance *instance = msg_context->instance; +- unsigned long len = msg_context->u.bulk.buffer_used; +- int ret; +- +- if (!len) +- /* Dummy receive to ensure the buffers remain in order */ +- len = 8; +- /* queue the bulk submission */ +- vchi_service_use(instance->handle); +- ret = vchi_bulk_queue_receive(instance->handle, +- msg_context->u.bulk.buffer->buffer, +- /* Actual receive needs to be a multiple +- * of 4 bytes +- */ +- (len + 3) & ~3, +- VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE | +- VCHI_FLAGS_BLOCK_UNTIL_QUEUED, +- msg_context); +- +- vchi_service_release(instance->handle); +- +- if (ret != 0) +- pr_err("%s: ctx: %p, vchi_bulk_queue_receive failed %d\n", +- __func__, msg_context, ret); +-} +- +-/* enqueue a bulk receive for a given message context */ +-static int bulk_receive(struct vchiq_mmal_instance *instance, +- struct mmal_msg *msg, +- struct mmal_msg_context *msg_context) +-{ +- unsigned long rd_len; +- +- rd_len = msg->u.buffer_from_host.buffer_header.length; +- +- if (!msg_context->u.bulk.buffer) { +- pr_err("bulk.buffer not configured - error in buffer_from_host\n"); +- +- /* todo: this is a serious error, we should never have +- * committed a buffer_to_host operation to the mmal +- * port without the buffer to back it up (underflow +- * handling) and there is no obvious way to deal with +- * this - how is the mmal servie going to react when +- * we fail to do the xfer and reschedule a buffer when +- * it arrives? perhaps a starved flag to indicate a +- * waiting bulk receive? +- */ +- +- return -EINVAL; +- } +- +- /* ensure we do not overrun the available buffer */ +- if (rd_len > msg_context->u.bulk.buffer->buffer_size) { +- rd_len = msg_context->u.bulk.buffer->buffer_size; +- pr_warn("short read as not enough receive buffer space\n"); +- /* todo: is this the correct response, what happens to +- * the rest of the message data? +- */ +- } +- +- /* store length */ +- msg_context->u.bulk.buffer_used = rd_len; +- msg_context->u.bulk.dts = msg->u.buffer_from_host.buffer_header.dts; +- msg_context->u.bulk.pts = msg->u.buffer_from_host.buffer_header.pts; +- +- queue_work(msg_context->instance->bulk_wq, +- &msg_context->u.bulk.buffer_to_host_work); +- +- return 0; +-} +- +-/* data in message, memcpy from packet into output buffer */ +-static int inline_receive(struct vchiq_mmal_instance *instance, +- struct mmal_msg *msg, +- struct mmal_msg_context *msg_context) +-{ +- memcpy(msg_context->u.bulk.buffer->buffer, +- msg->u.buffer_from_host.short_data, +- msg->u.buffer_from_host.payload_in_message); +- +- msg_context->u.bulk.buffer_used = +- msg->u.buffer_from_host.payload_in_message; +- +- return 0; +-} +- +-/* queue the buffer availability with MMAL_MSG_TYPE_BUFFER_FROM_HOST */ +-static int +-buffer_from_host(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port, struct mmal_buffer *buf) +-{ +- struct mmal_msg_context *msg_context; +- struct mmal_msg m; +- int ret; +- +- if (!port->enabled) +- return -EINVAL; +- +- pr_debug("instance:%p buffer:%p\n", instance->handle, buf); +- +- /* get context */ +- if (!buf->msg_context) { +- pr_err("%s: msg_context not allocated, buf %p\n", __func__, +- buf); +- return -EINVAL; +- } +- msg_context = buf->msg_context; +- +- /* store bulk message context for when data arrives */ +- msg_context->u.bulk.instance = instance; +- msg_context->u.bulk.port = port; +- msg_context->u.bulk.buffer = buf; +- msg_context->u.bulk.buffer_used = 0; +- +- /* initialise work structure ready to schedule callback */ +- INIT_WORK(&msg_context->u.bulk.work, buffer_work_cb); +- INIT_WORK(&msg_context->u.bulk.buffer_to_host_work, +- buffer_to_host_work_cb); +- +- atomic_inc(&port->buffers_with_vpu); +- +- /* prep the buffer from host message */ +- memset(&m, 0xbc, sizeof(m)); /* just to make debug clearer */ +- +- m.h.type = MMAL_MSG_TYPE_BUFFER_FROM_HOST; +- m.h.magic = MMAL_MAGIC; +- m.h.context = msg_context->handle; +- m.h.status = 0; +- +- /* drvbuf is our private data passed back */ +- m.u.buffer_from_host.drvbuf.magic = MMAL_MAGIC; +- m.u.buffer_from_host.drvbuf.component_handle = port->component->handle; +- m.u.buffer_from_host.drvbuf.port_handle = port->handle; +- m.u.buffer_from_host.drvbuf.client_context = msg_context->handle; +- +- /* buffer header */ +- m.u.buffer_from_host.buffer_header.cmd = 0; +- m.u.buffer_from_host.buffer_header.data = +- (u32)(unsigned long)buf->buffer; +- m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size; +- m.u.buffer_from_host.buffer_header.length = 0; /* nothing used yet */ +- m.u.buffer_from_host.buffer_header.offset = 0; /* no offset */ +- m.u.buffer_from_host.buffer_header.flags = 0; /* no flags */ +- m.u.buffer_from_host.buffer_header.pts = MMAL_TIME_UNKNOWN; +- m.u.buffer_from_host.buffer_header.dts = MMAL_TIME_UNKNOWN; +- +- /* clear buffer type sepecific data */ +- memset(&m.u.buffer_from_host.buffer_header_type_specific, 0, +- sizeof(m.u.buffer_from_host.buffer_header_type_specific)); +- +- /* no payload in message */ +- m.u.buffer_from_host.payload_in_message = 0; +- +- vchi_service_use(instance->handle); +- +- ret = vchi_queue_kernel_message(instance->handle, +- &m, +- sizeof(struct mmal_msg_header) + +- sizeof(m.u.buffer_from_host)); +- +- vchi_service_release(instance->handle); +- +- return ret; +-} +- +-/* deals with receipt of buffer to host message */ +-static void buffer_to_host_cb(struct vchiq_mmal_instance *instance, +- struct mmal_msg *msg, u32 msg_len) +-{ +- struct mmal_msg_context *msg_context; +- u32 handle; +- +- pr_debug("%s: instance:%p msg:%p msg_len:%d\n", +- __func__, instance, msg, msg_len); +- +- if (msg->u.buffer_from_host.drvbuf.magic == MMAL_MAGIC) { +- handle = msg->u.buffer_from_host.drvbuf.client_context; +- msg_context = lookup_msg_context(instance, handle); +- +- if (!msg_context) { +- pr_err("drvbuf.client_context(%u) is invalid\n", +- handle); +- return; +- } +- } else { +- pr_err("MMAL_MSG_TYPE_BUFFER_TO_HOST with bad magic\n"); +- return; +- } +- +- msg_context->u.bulk.mmal_flags = +- msg->u.buffer_from_host.buffer_header.flags; +- +- if (msg->h.status != MMAL_MSG_STATUS_SUCCESS) { +- /* message reception had an error */ +- pr_warn("error %d in reply\n", msg->h.status); +- +- msg_context->u.bulk.status = msg->h.status; +- +- } else if (msg->u.buffer_from_host.buffer_header.length == 0) { +- /* empty buffer */ +- if (msg->u.buffer_from_host.buffer_header.flags & +- MMAL_BUFFER_HEADER_FLAG_EOS) { +- msg_context->u.bulk.status = +- bulk_receive(instance, msg, msg_context); +- if (msg_context->u.bulk.status == 0) +- return; /* successful bulk submission, bulk +- * completion will trigger callback +- */ +- } else { +- /* do callback with empty buffer - not EOS though */ +- msg_context->u.bulk.status = 0; +- msg_context->u.bulk.buffer_used = 0; +- } +- } else if (msg->u.buffer_from_host.payload_in_message == 0) { +- /* data is not in message, queue a bulk receive */ +- msg_context->u.bulk.status = +- bulk_receive(instance, msg, msg_context); +- if (msg_context->u.bulk.status == 0) +- return; /* successful bulk submission, bulk +- * completion will trigger callback +- */ +- +- /* failed to submit buffer, this will end badly */ +- pr_err("error %d on bulk submission\n", +- msg_context->u.bulk.status); +- +- } else if (msg->u.buffer_from_host.payload_in_message <= +- MMAL_VC_SHORT_DATA) { +- /* data payload within message */ +- msg_context->u.bulk.status = inline_receive(instance, msg, +- msg_context); +- } else { +- pr_err("message with invalid short payload\n"); +- +- /* signal error */ +- msg_context->u.bulk.status = -EINVAL; +- msg_context->u.bulk.buffer_used = +- msg->u.buffer_from_host.payload_in_message; +- } +- +- /* schedule the port callback */ +- schedule_work(&msg_context->u.bulk.work); +-} +- +-static void bulk_receive_cb(struct vchiq_mmal_instance *instance, +- struct mmal_msg_context *msg_context) +-{ +- msg_context->u.bulk.status = 0; +- +- /* schedule the port callback */ +- schedule_work(&msg_context->u.bulk.work); +-} +- +-static void bulk_abort_cb(struct vchiq_mmal_instance *instance, +- struct mmal_msg_context *msg_context) +-{ +- pr_err("%s: bulk ABORTED msg_context:%p\n", __func__, msg_context); +- +- msg_context->u.bulk.status = -EINTR; +- +- schedule_work(&msg_context->u.bulk.work); +-} +- +-/* incoming event service callback */ +-static void service_callback(void *param, +- const VCHI_CALLBACK_REASON_T reason, +- void *bulk_ctx) +-{ +- struct vchiq_mmal_instance *instance = param; +- int status; +- u32 msg_len; +- struct mmal_msg *msg; +- VCHI_HELD_MSG_T msg_handle; +- struct mmal_msg_context *msg_context; +- +- if (!instance) { +- pr_err("Message callback passed NULL instance\n"); +- return; +- } +- +- switch (reason) { +- case VCHI_CALLBACK_MSG_AVAILABLE: +- status = vchi_msg_hold(instance->handle, (void **)&msg, +- &msg_len, VCHI_FLAGS_NONE, &msg_handle); +- if (status) { +- pr_err("Unable to dequeue a message (%d)\n", status); +- break; +- } +- +- DBG_DUMP_MSG(msg, msg_len, "<<< reply message"); +- +- /* handling is different for buffer messages */ +- switch (msg->h.type) { +- case MMAL_MSG_TYPE_BUFFER_FROM_HOST: +- vchi_held_msg_release(&msg_handle); +- break; +- +- case MMAL_MSG_TYPE_EVENT_TO_HOST: +- event_to_host_cb(instance, msg, msg_len); +- vchi_held_msg_release(&msg_handle); +- +- break; +- +- case MMAL_MSG_TYPE_BUFFER_TO_HOST: +- buffer_to_host_cb(instance, msg, msg_len); +- vchi_held_msg_release(&msg_handle); +- break; +- +- default: +- /* messages dependent on header context to complete */ +- if (!msg->h.context) { +- pr_err("received message context was null!\n"); +- vchi_held_msg_release(&msg_handle); +- break; +- } +- +- msg_context = lookup_msg_context(instance, +- msg->h.context); +- if (!msg_context) { +- pr_err("received invalid message context %u!\n", +- msg->h.context); +- vchi_held_msg_release(&msg_handle); +- break; +- } +- +- /* fill in context values */ +- msg_context->u.sync.msg_handle = msg_handle; +- msg_context->u.sync.msg = msg; +- msg_context->u.sync.msg_len = msg_len; +- +- /* todo: should this check (completion_done() +- * == 1) for no one waiting? or do we need a +- * flag to tell us the completion has been +- * interrupted so we can free the message and +- * its context. This probably also solves the +- * message arriving after interruption todo +- * below +- */ +- +- /* complete message so caller knows it happened */ +- complete(&msg_context->u.sync.cmplt); +- break; +- } +- +- break; +- +- case VCHI_CALLBACK_BULK_RECEIVED: +- bulk_receive_cb(instance, bulk_ctx); +- break; +- +- case VCHI_CALLBACK_BULK_RECEIVE_ABORTED: +- bulk_abort_cb(instance, bulk_ctx); +- break; +- +- case VCHI_CALLBACK_SERVICE_CLOSED: +- /* TODO: consider if this requires action if received when +- * driver is not explicitly closing the service +- */ +- break; +- +- default: +- pr_err("Received unhandled message reason %d\n", reason); +- break; +- } +-} +- +-static int send_synchronous_mmal_msg(struct vchiq_mmal_instance *instance, +- struct mmal_msg *msg, +- unsigned int payload_len, +- struct mmal_msg **msg_out, +- VCHI_HELD_MSG_T *msg_handle_out) +-{ +- struct mmal_msg_context *msg_context; +- int ret; +- unsigned long timeout; +- +- /* payload size must not cause message to exceed max size */ +- if (payload_len > +- (MMAL_MSG_MAX_SIZE - sizeof(struct mmal_msg_header))) { +- pr_err("payload length %d exceeds max:%d\n", payload_len, +- (int)(MMAL_MSG_MAX_SIZE - +- sizeof(struct mmal_msg_header))); +- return -EINVAL; +- } +- +- msg_context = get_msg_context(instance); +- if (IS_ERR(msg_context)) +- return PTR_ERR(msg_context); +- +- init_completion(&msg_context->u.sync.cmplt); +- +- msg->h.magic = MMAL_MAGIC; +- msg->h.context = msg_context->handle; +- msg->h.status = 0; +- +- DBG_DUMP_MSG(msg, (sizeof(struct mmal_msg_header) + payload_len), +- ">>> sync message"); +- +- vchi_service_use(instance->handle); +- +- ret = vchi_queue_kernel_message(instance->handle, +- msg, +- sizeof(struct mmal_msg_header) + +- payload_len); +- +- vchi_service_release(instance->handle); +- +- if (ret) { +- pr_err("error %d queuing message\n", ret); +- release_msg_context(msg_context); +- return ret; +- } +- +- timeout = wait_for_completion_timeout(&msg_context->u.sync.cmplt, +- 3 * HZ); +- if (timeout == 0) { +- pr_err("timed out waiting for sync completion\n"); +- ret = -ETIME; +- /* todo: what happens if the message arrives after aborting */ +- release_msg_context(msg_context); +- return ret; +- } +- +- *msg_out = msg_context->u.sync.msg; +- *msg_handle_out = msg_context->u.sync.msg_handle; +- release_msg_context(msg_context); +- +- return 0; +-} +- +-static void dump_port_info(struct vchiq_mmal_port *port) +-{ +- pr_debug("port handle:0x%x enabled:%d\n", port->handle, port->enabled); +- +- pr_debug("buffer minimum num:%d size:%d align:%d\n", +- port->minimum_buffer.num, +- port->minimum_buffer.size, port->minimum_buffer.alignment); +- +- pr_debug("buffer recommended num:%d size:%d align:%d\n", +- port->recommended_buffer.num, +- port->recommended_buffer.size, +- port->recommended_buffer.alignment); +- +- pr_debug("buffer current values num:%d size:%d align:%d\n", +- port->current_buffer.num, +- port->current_buffer.size, port->current_buffer.alignment); +- +- pr_debug("elementary stream: type:%d encoding:0x%x variant:0x%x\n", +- port->format.type, +- port->format.encoding, port->format.encoding_variant); +- +- pr_debug(" bitrate:%d flags:0x%x\n", +- port->format.bitrate, port->format.flags); +- +- if (port->format.type == MMAL_ES_TYPE_VIDEO) { +- pr_debug +- ("es video format: width:%d height:%d colourspace:0x%x\n", +- port->es.video.width, port->es.video.height, +- port->es.video.color_space); +- +- pr_debug(" : crop xywh %d,%d,%d,%d\n", +- port->es.video.crop.x, +- port->es.video.crop.y, +- port->es.video.crop.width, port->es.video.crop.height); +- pr_debug(" : framerate %d/%d aspect %d/%d\n", +- port->es.video.frame_rate.num, +- port->es.video.frame_rate.den, +- port->es.video.par.num, port->es.video.par.den); +- } +-} +- +-static void port_to_mmal_msg(struct vchiq_mmal_port *port, struct mmal_port *p) +-{ +- /* todo do readonly fields need setting at all? */ +- p->type = port->type; +- p->index = port->index; +- p->index_all = 0; +- p->is_enabled = port->enabled; +- p->buffer_num_min = port->minimum_buffer.num; +- p->buffer_size_min = port->minimum_buffer.size; +- p->buffer_alignment_min = port->minimum_buffer.alignment; +- p->buffer_num_recommended = port->recommended_buffer.num; +- p->buffer_size_recommended = port->recommended_buffer.size; +- +- /* only three writable fields in a port */ +- p->buffer_num = port->current_buffer.num; +- p->buffer_size = port->current_buffer.size; +- p->userdata = (u32)(unsigned long)port; +-} +- +-static int port_info_set(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port) +-{ +- int ret; +- struct mmal_msg m; +- struct mmal_msg *rmsg; +- VCHI_HELD_MSG_T rmsg_handle; +- +- pr_debug("setting port info port %p\n", port); +- if (!port) +- return -1; +- dump_port_info(port); +- +- m.h.type = MMAL_MSG_TYPE_PORT_INFO_SET; +- +- m.u.port_info_set.component_handle = port->component->handle; +- m.u.port_info_set.port_type = port->type; +- m.u.port_info_set.port_index = port->index; +- +- port_to_mmal_msg(port, &m.u.port_info_set.port); +- +- /* elementary stream format setup */ +- m.u.port_info_set.format.type = port->format.type; +- m.u.port_info_set.format.encoding = port->format.encoding; +- m.u.port_info_set.format.encoding_variant = +- port->format.encoding_variant; +- m.u.port_info_set.format.bitrate = port->format.bitrate; +- m.u.port_info_set.format.flags = port->format.flags; +- +- memcpy(&m.u.port_info_set.es, &port->es, +- sizeof(union mmal_es_specific_format)); +- +- m.u.port_info_set.format.extradata_size = port->format.extradata_size; +- memcpy(&m.u.port_info_set.extradata, port->format.extradata, +- port->format.extradata_size); +- +- ret = send_synchronous_mmal_msg(instance, &m, +- sizeof(m.u.port_info_set), +- &rmsg, &rmsg_handle); +- if (ret) +- return ret; +- +- if (rmsg->h.type != MMAL_MSG_TYPE_PORT_INFO_SET) { +- /* got an unexpected message type in reply */ +- ret = -EINVAL; +- goto release_msg; +- } +- +- /* return operation status */ +- ret = -rmsg->u.port_info_get_reply.status; +- +- pr_debug("%s:result:%d component:0x%x port:%d\n", __func__, ret, +- port->component->handle, port->handle); +- +-release_msg: +- vchi_held_msg_release(&rmsg_handle); +- +- return ret; +-} +- +-/* use port info get message to retrieve port information */ +-static int port_info_get(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port) +-{ +- int ret; +- struct mmal_msg m; +- struct mmal_msg *rmsg; +- VCHI_HELD_MSG_T rmsg_handle; +- +- /* port info time */ +- m.h.type = MMAL_MSG_TYPE_PORT_INFO_GET; +- m.u.port_info_get.component_handle = port->component->handle; +- m.u.port_info_get.port_type = port->type; +- m.u.port_info_get.index = port->index; +- +- ret = send_synchronous_mmal_msg(instance, &m, +- sizeof(m.u.port_info_get), +- &rmsg, &rmsg_handle); +- if (ret) +- return ret; +- +- if (rmsg->h.type != MMAL_MSG_TYPE_PORT_INFO_GET) { +- /* got an unexpected message type in reply */ +- ret = -EINVAL; +- goto release_msg; +- } +- +- /* return operation status */ +- ret = -rmsg->u.port_info_get_reply.status; +- if (ret != MMAL_MSG_STATUS_SUCCESS) +- goto release_msg; +- +- if (rmsg->u.port_info_get_reply.port.is_enabled == 0) +- port->enabled = false; +- else +- port->enabled = true; +- +- /* copy the values out of the message */ +- port->handle = rmsg->u.port_info_get_reply.port_handle; +- +- /* port type and index cached to use on port info set because +- * it does not use a port handle +- */ +- port->type = rmsg->u.port_info_get_reply.port_type; +- port->index = rmsg->u.port_info_get_reply.port_index; +- +- port->minimum_buffer.num = +- rmsg->u.port_info_get_reply.port.buffer_num_min; +- port->minimum_buffer.size = +- rmsg->u.port_info_get_reply.port.buffer_size_min; +- port->minimum_buffer.alignment = +- rmsg->u.port_info_get_reply.port.buffer_alignment_min; +- +- port->recommended_buffer.alignment = +- rmsg->u.port_info_get_reply.port.buffer_alignment_min; +- port->recommended_buffer.num = +- rmsg->u.port_info_get_reply.port.buffer_num_recommended; +- +- port->current_buffer.num = rmsg->u.port_info_get_reply.port.buffer_num; +- port->current_buffer.size = +- rmsg->u.port_info_get_reply.port.buffer_size; +- +- /* stream format */ +- port->format.type = rmsg->u.port_info_get_reply.format.type; +- port->format.encoding = rmsg->u.port_info_get_reply.format.encoding; +- port->format.encoding_variant = +- rmsg->u.port_info_get_reply.format.encoding_variant; +- port->format.bitrate = rmsg->u.port_info_get_reply.format.bitrate; +- port->format.flags = rmsg->u.port_info_get_reply.format.flags; +- +- /* elementary stream format */ +- memcpy(&port->es, +- &rmsg->u.port_info_get_reply.es, +- sizeof(union mmal_es_specific_format)); +- port->format.es = &port->es; +- +- port->format.extradata_size = +- rmsg->u.port_info_get_reply.format.extradata_size; +- memcpy(port->format.extradata, +- rmsg->u.port_info_get_reply.extradata, +- port->format.extradata_size); +- +- pr_debug("received port info\n"); +- dump_port_info(port); +- +-release_msg: +- +- pr_debug("%s:result:%d component:0x%x port:%d\n", +- __func__, ret, port->component->handle, port->handle); +- +- vchi_held_msg_release(&rmsg_handle); +- +- return ret; +-} +- +-/* create comonent on vc */ +-static int create_component(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_component *component, +- const char *name) +-{ +- int ret; +- struct mmal_msg m; +- struct mmal_msg *rmsg; +- VCHI_HELD_MSG_T rmsg_handle; +- +- /* build component create message */ +- m.h.type = MMAL_MSG_TYPE_COMPONENT_CREATE; +- m.u.component_create.client_component = (u32)(unsigned long)component; +- strncpy(m.u.component_create.name, name, +- sizeof(m.u.component_create.name)); +- +- ret = send_synchronous_mmal_msg(instance, &m, +- sizeof(m.u.component_create), +- &rmsg, &rmsg_handle); +- if (ret) +- return ret; +- +- if (rmsg->h.type != m.h.type) { +- /* got an unexpected message type in reply */ +- ret = -EINVAL; +- goto release_msg; +- } +- +- ret = -rmsg->u.component_create_reply.status; +- if (ret != MMAL_MSG_STATUS_SUCCESS) +- goto release_msg; +- +- /* a valid component response received */ +- component->handle = rmsg->u.component_create_reply.component_handle; +- component->inputs = rmsg->u.component_create_reply.input_num; +- component->outputs = rmsg->u.component_create_reply.output_num; +- component->clocks = rmsg->u.component_create_reply.clock_num; +- +- pr_debug("Component handle:0x%x in:%d out:%d clock:%d\n", +- component->handle, +- component->inputs, component->outputs, component->clocks); +- +-release_msg: +- vchi_held_msg_release(&rmsg_handle); +- +- return ret; +-} +- +-/* destroys a component on vc */ +-static int destroy_component(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_component *component) +-{ +- int ret; +- struct mmal_msg m; +- struct mmal_msg *rmsg; +- VCHI_HELD_MSG_T rmsg_handle; +- +- m.h.type = MMAL_MSG_TYPE_COMPONENT_DESTROY; +- m.u.component_destroy.component_handle = component->handle; +- +- ret = send_synchronous_mmal_msg(instance, &m, +- sizeof(m.u.component_destroy), +- &rmsg, &rmsg_handle); +- if (ret) +- return ret; +- +- if (rmsg->h.type != m.h.type) { +- /* got an unexpected message type in reply */ +- ret = -EINVAL; +- goto release_msg; +- } +- +- ret = -rmsg->u.component_destroy_reply.status; +- +-release_msg: +- +- vchi_held_msg_release(&rmsg_handle); +- +- return ret; +-} +- +-/* enable a component on vc */ +-static int enable_component(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_component *component) +-{ +- int ret; +- struct mmal_msg m; +- struct mmal_msg *rmsg; +- VCHI_HELD_MSG_T rmsg_handle; +- +- m.h.type = MMAL_MSG_TYPE_COMPONENT_ENABLE; +- m.u.component_enable.component_handle = component->handle; +- +- ret = send_synchronous_mmal_msg(instance, &m, +- sizeof(m.u.component_enable), +- &rmsg, &rmsg_handle); +- if (ret) +- return ret; +- +- if (rmsg->h.type != m.h.type) { +- /* got an unexpected message type in reply */ +- ret = -EINVAL; +- goto release_msg; +- } +- +- ret = -rmsg->u.component_enable_reply.status; +- +-release_msg: +- vchi_held_msg_release(&rmsg_handle); +- +- return ret; +-} +- +-/* disable a component on vc */ +-static int disable_component(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_component *component) +-{ +- int ret; +- struct mmal_msg m; +- struct mmal_msg *rmsg; +- VCHI_HELD_MSG_T rmsg_handle; +- +- m.h.type = MMAL_MSG_TYPE_COMPONENT_DISABLE; +- m.u.component_disable.component_handle = component->handle; +- +- ret = send_synchronous_mmal_msg(instance, &m, +- sizeof(m.u.component_disable), +- &rmsg, &rmsg_handle); +- if (ret) +- return ret; +- +- if (rmsg->h.type != m.h.type) { +- /* got an unexpected message type in reply */ +- ret = -EINVAL; +- goto release_msg; +- } +- +- ret = -rmsg->u.component_disable_reply.status; +- +-release_msg: +- +- vchi_held_msg_release(&rmsg_handle); +- +- return ret; +-} +- +-/* get version of mmal implementation */ +-static int get_version(struct vchiq_mmal_instance *instance, +- u32 *major_out, u32 *minor_out) +-{ +- int ret; +- struct mmal_msg m; +- struct mmal_msg *rmsg; +- VCHI_HELD_MSG_T rmsg_handle; +- +- m.h.type = MMAL_MSG_TYPE_GET_VERSION; +- +- ret = send_synchronous_mmal_msg(instance, &m, +- sizeof(m.u.version), +- &rmsg, &rmsg_handle); +- if (ret) +- return ret; +- +- if (rmsg->h.type != m.h.type) { +- /* got an unexpected message type in reply */ +- ret = -EINVAL; +- goto release_msg; +- } +- +- *major_out = rmsg->u.version.major; +- *minor_out = rmsg->u.version.minor; +- +-release_msg: +- vchi_held_msg_release(&rmsg_handle); +- +- return ret; +-} +- +-/* do a port action with a port as a parameter */ +-static int port_action_port(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port, +- enum mmal_msg_port_action_type action_type) +-{ +- int ret; +- struct mmal_msg m; +- struct mmal_msg *rmsg; +- VCHI_HELD_MSG_T rmsg_handle; +- +- m.h.type = MMAL_MSG_TYPE_PORT_ACTION; +- m.u.port_action_port.component_handle = port->component->handle; +- m.u.port_action_port.port_handle = port->handle; +- m.u.port_action_port.action = action_type; +- +- port_to_mmal_msg(port, &m.u.port_action_port.port); +- +- ret = send_synchronous_mmal_msg(instance, &m, +- sizeof(m.u.port_action_port), +- &rmsg, &rmsg_handle); +- if (ret) +- return ret; +- +- if (rmsg->h.type != MMAL_MSG_TYPE_PORT_ACTION) { +- /* got an unexpected message type in reply */ +- ret = -EINVAL; +- goto release_msg; +- } +- +- ret = -rmsg->u.port_action_reply.status; +- +- pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d)\n", +- __func__, +- ret, port->component->handle, port->handle, +- port_action_type_names[action_type], action_type); +- +-release_msg: +- vchi_held_msg_release(&rmsg_handle); +- +- return ret; +-} +- +-/* do a port action with handles as parameters */ +-static int port_action_handle(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port, +- enum mmal_msg_port_action_type action_type, +- u32 connect_component_handle, +- u32 connect_port_handle) +-{ +- int ret; +- struct mmal_msg m; +- struct mmal_msg *rmsg; +- VCHI_HELD_MSG_T rmsg_handle; +- +- m.h.type = MMAL_MSG_TYPE_PORT_ACTION; +- +- m.u.port_action_handle.component_handle = port->component->handle; +- m.u.port_action_handle.port_handle = port->handle; +- m.u.port_action_handle.action = action_type; +- +- m.u.port_action_handle.connect_component_handle = +- connect_component_handle; +- m.u.port_action_handle.connect_port_handle = connect_port_handle; +- +- ret = send_synchronous_mmal_msg(instance, &m, +- sizeof(m.u.port_action_handle), +- &rmsg, &rmsg_handle); +- if (ret) +- return ret; +- +- if (rmsg->h.type != MMAL_MSG_TYPE_PORT_ACTION) { +- /* got an unexpected message type in reply */ +- ret = -EINVAL; +- goto release_msg; +- } +- +- ret = -rmsg->u.port_action_reply.status; +- +- pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d) connect component:0x%x connect port:%d\n", +- __func__, +- ret, port->component->handle, port->handle, +- port_action_type_names[action_type], +- action_type, connect_component_handle, connect_port_handle); +- +-release_msg: +- vchi_held_msg_release(&rmsg_handle); +- +- return ret; +-} +- +-static int port_parameter_set(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port, +- u32 parameter_id, void *value, u32 value_size) +-{ +- int ret; +- struct mmal_msg m; +- struct mmal_msg *rmsg; +- VCHI_HELD_MSG_T rmsg_handle; +- +- m.h.type = MMAL_MSG_TYPE_PORT_PARAMETER_SET; +- +- m.u.port_parameter_set.component_handle = port->component->handle; +- m.u.port_parameter_set.port_handle = port->handle; +- m.u.port_parameter_set.id = parameter_id; +- m.u.port_parameter_set.size = (2 * sizeof(u32)) + value_size; +- memcpy(&m.u.port_parameter_set.value, value, value_size); +- +- ret = send_synchronous_mmal_msg(instance, &m, +- (4 * sizeof(u32)) + value_size, +- &rmsg, &rmsg_handle); +- if (ret) +- return ret; +- +- if (rmsg->h.type != MMAL_MSG_TYPE_PORT_PARAMETER_SET) { +- /* got an unexpected message type in reply */ +- ret = -EINVAL; +- goto release_msg; +- } +- +- ret = -rmsg->u.port_parameter_set_reply.status; +- +- pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n", +- __func__, +- ret, port->component->handle, port->handle, parameter_id); +- +-release_msg: +- vchi_held_msg_release(&rmsg_handle); +- +- return ret; +-} +- +-static int port_parameter_get(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port, +- u32 parameter_id, void *value, u32 *value_size) +-{ +- int ret; +- struct mmal_msg m; +- struct mmal_msg *rmsg; +- VCHI_HELD_MSG_T rmsg_handle; +- +- m.h.type = MMAL_MSG_TYPE_PORT_PARAMETER_GET; +- +- m.u.port_parameter_get.component_handle = port->component->handle; +- m.u.port_parameter_get.port_handle = port->handle; +- m.u.port_parameter_get.id = parameter_id; +- m.u.port_parameter_get.size = (2 * sizeof(u32)) + *value_size; +- +- ret = send_synchronous_mmal_msg(instance, &m, +- sizeof(struct +- mmal_msg_port_parameter_get), +- &rmsg, &rmsg_handle); +- if (ret) +- return ret; +- +- if (rmsg->h.type != MMAL_MSG_TYPE_PORT_PARAMETER_GET) { +- /* got an unexpected message type in reply */ +- pr_err("Incorrect reply type %d\n", rmsg->h.type); +- ret = -EINVAL; +- goto release_msg; +- } +- +- ret = -rmsg->u.port_parameter_get_reply.status; +- /* port_parameter_get_reply.size includes the header, +- * whilst *value_size doesn't. +- */ +- rmsg->u.port_parameter_get_reply.size -= (2 * sizeof(u32)); +- +- if (ret || rmsg->u.port_parameter_get_reply.size > *value_size) { +- /* Copy only as much as we have space for +- * but report true size of parameter +- */ +- memcpy(value, &rmsg->u.port_parameter_get_reply.value, +- *value_size); +- *value_size = rmsg->u.port_parameter_get_reply.size; +- } else { +- memcpy(value, &rmsg->u.port_parameter_get_reply.value, +- rmsg->u.port_parameter_get_reply.size); +- } +- +- pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n", __func__, +- ret, port->component->handle, port->handle, parameter_id); +- +-release_msg: +- vchi_held_msg_release(&rmsg_handle); +- +- return ret; +-} +- +-/* disables a port and drains buffers from it */ +-static int port_disable(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port) +-{ +- int ret; +- struct list_head *q, *buf_head; +- unsigned long flags = 0; +- +- if (!port->enabled) +- return 0; +- +- port->enabled = false; +- +- ret = port_action_port(instance, port, +- MMAL_MSG_PORT_ACTION_TYPE_DISABLE); +- if (ret == 0) { +- /* +- * Drain all queued buffers on port. This should only +- * apply to buffers that have been queued before the port +- * has been enabled. If the port has been enabled and buffers +- * passed, then the buffers should have been removed from this +- * list, and we should get the relevant callbacks via VCHIQ +- * to release the buffers. +- */ +- spin_lock_irqsave(&port->slock, flags); +- +- list_for_each_safe(buf_head, q, &port->buffers) { +- struct mmal_buffer *mmalbuf; +- +- mmalbuf = list_entry(buf_head, struct mmal_buffer, +- list); +- list_del(buf_head); +- if (port->buffer_cb) +- port->buffer_cb(instance, +- port, 0, mmalbuf, 0, 0, +- MMAL_TIME_UNKNOWN, +- MMAL_TIME_UNKNOWN); +- } +- +- spin_unlock_irqrestore(&port->slock, flags); +- +- ret = port_info_get(instance, port); +- } +- +- return ret; +-} +- +-/* enable a port */ +-static int port_enable(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port) +-{ +- unsigned int hdr_count; +- struct list_head *q, *buf_head; +- int ret; +- +- if (port->enabled) +- return 0; +- +- ret = port_action_port(instance, port, +- MMAL_MSG_PORT_ACTION_TYPE_ENABLE); +- if (ret) +- goto done; +- +- port->enabled = true; +- +- if (port->buffer_cb) { +- /* send buffer headers to videocore */ +- hdr_count = 1; +- list_for_each_safe(buf_head, q, &port->buffers) { +- struct mmal_buffer *mmalbuf; +- +- mmalbuf = list_entry(buf_head, struct mmal_buffer, +- list); +- ret = buffer_from_host(instance, port, mmalbuf); +- if (ret) +- goto done; +- +- list_del(buf_head); +- hdr_count++; +- if (hdr_count > port->current_buffer.num) +- break; +- } +- } +- +- ret = port_info_get(instance, port); +- +-done: +- return ret; +-} +- +-/* ------------------------------------------------------------------ +- * Exported API +- *------------------------------------------------------------------ +- */ +- +-int vchiq_mmal_port_set_format(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port) +-{ +- int ret; +- +- if (mutex_lock_interruptible(&instance->vchiq_mutex)) +- return -EINTR; +- +- ret = port_info_set(instance, port); +- if (ret) +- goto release_unlock; +- +- /* read what has actually been set */ +- ret = port_info_get(instance, port); +- +-release_unlock: +- mutex_unlock(&instance->vchiq_mutex); +- +- return ret; +-} +- +-int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port, +- u32 parameter, void *value, u32 value_size) +-{ +- int ret; +- +- if (mutex_lock_interruptible(&instance->vchiq_mutex)) +- return -EINTR; +- +- ret = port_parameter_set(instance, port, parameter, value, value_size); +- +- mutex_unlock(&instance->vchiq_mutex); +- +- return ret; +-} +- +-int vchiq_mmal_port_parameter_get(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port, +- u32 parameter, void *value, u32 *value_size) +-{ +- int ret; +- +- if (mutex_lock_interruptible(&instance->vchiq_mutex)) +- return -EINTR; +- +- ret = port_parameter_get(instance, port, parameter, value, value_size); +- +- mutex_unlock(&instance->vchiq_mutex); +- +- return ret; +-} +- +-/* enable a port +- * +- * enables a port and queues buffers for satisfying callbacks if we +- * provide a callback handler +- */ +-int vchiq_mmal_port_enable(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port, +- vchiq_mmal_buffer_cb buffer_cb) +-{ +- int ret; +- +- if (mutex_lock_interruptible(&instance->vchiq_mutex)) +- return -EINTR; +- +- /* already enabled - noop */ +- if (port->enabled) { +- ret = 0; +- goto unlock; +- } +- +- port->buffer_cb = buffer_cb; +- +- ret = port_enable(instance, port); +- +-unlock: +- mutex_unlock(&instance->vchiq_mutex); +- +- return ret; +-} +- +-int vchiq_mmal_port_disable(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port) +-{ +- int ret; +- +- if (mutex_lock_interruptible(&instance->vchiq_mutex)) +- return -EINTR; +- +- if (!port->enabled) { +- mutex_unlock(&instance->vchiq_mutex); +- return 0; +- } +- +- ret = port_disable(instance, port); +- +- mutex_unlock(&instance->vchiq_mutex); +- +- return ret; +-} +- +-/* ports will be connected in a tunneled manner so data buffers +- * are not handled by client. +- */ +-int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *src, +- struct vchiq_mmal_port *dst) +-{ +- int ret; +- +- if (mutex_lock_interruptible(&instance->vchiq_mutex)) +- return -EINTR; +- +- /* disconnect ports if connected */ +- if (src->connected) { +- ret = port_disable(instance, src); +- if (ret) { +- pr_err("failed disabling src port(%d)\n", ret); +- goto release_unlock; +- } +- +- /* do not need to disable the destination port as they +- * are connected and it is done automatically +- */ +- +- ret = port_action_handle(instance, src, +- MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT, +- src->connected->component->handle, +- src->connected->handle); +- if (ret < 0) { +- pr_err("failed disconnecting src port\n"); +- goto release_unlock; +- } +- src->connected->enabled = false; +- src->connected = NULL; +- } +- +- if (!dst) { +- /* do not make new connection */ +- ret = 0; +- pr_debug("not making new connection\n"); +- goto release_unlock; +- } +- +- /* copy src port format to dst */ +- dst->format.encoding = src->format.encoding; +- dst->es.video.width = src->es.video.width; +- dst->es.video.height = src->es.video.height; +- dst->es.video.crop.x = src->es.video.crop.x; +- dst->es.video.crop.y = src->es.video.crop.y; +- dst->es.video.crop.width = src->es.video.crop.width; +- dst->es.video.crop.height = src->es.video.crop.height; +- dst->es.video.frame_rate.num = src->es.video.frame_rate.num; +- dst->es.video.frame_rate.den = src->es.video.frame_rate.den; +- +- /* set new format */ +- ret = port_info_set(instance, dst); +- if (ret) { +- pr_debug("setting port info failed\n"); +- goto release_unlock; +- } +- +- /* read what has actually been set */ +- ret = port_info_get(instance, dst); +- if (ret) { +- pr_debug("read back port info failed\n"); +- goto release_unlock; +- } +- +- /* connect two ports together */ +- ret = port_action_handle(instance, src, +- MMAL_MSG_PORT_ACTION_TYPE_CONNECT, +- dst->component->handle, dst->handle); +- if (ret < 0) { +- pr_debug("connecting port %d:%d to %d:%d failed\n", +- src->component->handle, src->handle, +- dst->component->handle, dst->handle); +- goto release_unlock; +- } +- src->connected = dst; +- +-release_unlock: +- +- mutex_unlock(&instance->vchiq_mutex); +- +- return ret; +-} +- +-int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port, +- struct mmal_buffer *buffer) +-{ +- unsigned long flags = 0; +- int ret; +- +- ret = buffer_from_host(instance, port, buffer); +- if (ret == -EINVAL) { +- /* Port is disabled. Queue for when it is enabled. */ +- spin_lock_irqsave(&port->slock, flags); +- list_add_tail(&buffer->list, &port->buffers); +- spin_unlock_irqrestore(&port->slock, flags); +- } +- +- return 0; +-} +- +-int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance, +- struct mmal_buffer *buf) +-{ +- struct mmal_msg_context *msg_context = get_msg_context(instance); +- +- if (IS_ERR(msg_context)) +- return (PTR_ERR(msg_context)); +- +- buf->msg_context = msg_context; +- return 0; +-} +- +-int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf) +-{ +- struct mmal_msg_context *msg_context = buf->msg_context; +- +- if (msg_context) +- release_msg_context(msg_context); +- buf->msg_context = NULL; +- +- return 0; +-} +- +-/* Initialise a mmal component and its ports +- * +- */ +-int vchiq_mmal_component_init(struct vchiq_mmal_instance *instance, +- const char *name, +- struct vchiq_mmal_component **component_out) +-{ +- int ret; +- int idx; /* port index */ +- struct vchiq_mmal_component *component; +- +- if (mutex_lock_interruptible(&instance->vchiq_mutex)) +- return -EINTR; +- +- if (instance->component_idx == VCHIQ_MMAL_MAX_COMPONENTS) { +- ret = -EINVAL; /* todo is this correct error? */ +- goto unlock; +- } +- +- component = &instance->component[instance->component_idx]; +- +- ret = create_component(instance, component, name); +- if (ret < 0) { +- pr_err("%s: failed to create component %d (Not enough GPU mem?)\n", +- __func__, ret); +- goto unlock; +- } +- +- /* ports info needs gathering */ +- component->control.type = MMAL_PORT_TYPE_CONTROL; +- component->control.index = 0; +- component->control.component = component; +- spin_lock_init(&component->control.slock); +- INIT_LIST_HEAD(&component->control.buffers); +- ret = port_info_get(instance, &component->control); +- if (ret < 0) +- goto release_component; +- +- for (idx = 0; idx < component->inputs; idx++) { +- component->input[idx].type = MMAL_PORT_TYPE_INPUT; +- component->input[idx].index = idx; +- component->input[idx].component = component; +- spin_lock_init(&component->input[idx].slock); +- INIT_LIST_HEAD(&component->input[idx].buffers); +- ret = port_info_get(instance, &component->input[idx]); +- if (ret < 0) +- goto release_component; +- } +- +- for (idx = 0; idx < component->outputs; idx++) { +- component->output[idx].type = MMAL_PORT_TYPE_OUTPUT; +- component->output[idx].index = idx; +- component->output[idx].component = component; +- spin_lock_init(&component->output[idx].slock); +- INIT_LIST_HEAD(&component->output[idx].buffers); +- ret = port_info_get(instance, &component->output[idx]); +- if (ret < 0) +- goto release_component; +- } +- +- for (idx = 0; idx < component->clocks; idx++) { +- component->clock[idx].type = MMAL_PORT_TYPE_CLOCK; +- component->clock[idx].index = idx; +- component->clock[idx].component = component; +- spin_lock_init(&component->clock[idx].slock); +- INIT_LIST_HEAD(&component->clock[idx].buffers); +- ret = port_info_get(instance, &component->clock[idx]); +- if (ret < 0) +- goto release_component; +- } +- +- instance->component_idx++; +- +- *component_out = component; +- +- mutex_unlock(&instance->vchiq_mutex); +- +- return 0; +- +-release_component: +- destroy_component(instance, component); +-unlock: +- mutex_unlock(&instance->vchiq_mutex); +- +- return ret; +-} +- +-/* +- * cause a mmal component to be destroyed +- */ +-int vchiq_mmal_component_finalise(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_component *component) +-{ +- int ret; +- +- if (mutex_lock_interruptible(&instance->vchiq_mutex)) +- return -EINTR; +- +- if (component->enabled) +- ret = disable_component(instance, component); +- +- ret = destroy_component(instance, component); +- +- mutex_unlock(&instance->vchiq_mutex); +- +- return ret; +-} +- +-/* +- * cause a mmal component to be enabled +- */ +-int vchiq_mmal_component_enable(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_component *component) +-{ +- int ret; +- +- if (mutex_lock_interruptible(&instance->vchiq_mutex)) +- return -EINTR; +- +- if (component->enabled) { +- mutex_unlock(&instance->vchiq_mutex); +- return 0; +- } +- +- ret = enable_component(instance, component); +- if (ret == 0) +- component->enabled = true; +- +- mutex_unlock(&instance->vchiq_mutex); +- +- return ret; +-} +- +-/* +- * cause a mmal component to be enabled +- */ +-int vchiq_mmal_component_disable(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_component *component) +-{ +- int ret; +- +- if (mutex_lock_interruptible(&instance->vchiq_mutex)) +- return -EINTR; +- +- if (!component->enabled) { +- mutex_unlock(&instance->vchiq_mutex); +- return 0; +- } +- +- ret = disable_component(instance, component); +- if (ret == 0) +- component->enabled = false; +- +- mutex_unlock(&instance->vchiq_mutex); +- +- return ret; +-} +- +-int vchiq_mmal_version(struct vchiq_mmal_instance *instance, +- u32 *major_out, u32 *minor_out) +-{ +- int ret; +- +- if (mutex_lock_interruptible(&instance->vchiq_mutex)) +- return -EINTR; +- +- ret = get_version(instance, major_out, minor_out); +- +- mutex_unlock(&instance->vchiq_mutex); +- +- return ret; +-} +- +-int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance) +-{ +- int status = 0; +- +- if (!instance) +- return -EINVAL; +- +- if (mutex_lock_interruptible(&instance->vchiq_mutex)) +- return -EINTR; +- +- vchi_service_use(instance->handle); +- +- status = vchi_service_close(instance->handle); +- if (status != 0) +- pr_err("mmal-vchiq: VCHIQ close failed\n"); +- +- mutex_unlock(&instance->vchiq_mutex); +- +- flush_workqueue(instance->bulk_wq); +- destroy_workqueue(instance->bulk_wq); +- +- vfree(instance->bulk_scratch); +- +- idr_destroy(&instance->context_map); +- +- kfree(instance); +- +- return status; +-} +- +-int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance) +-{ +- int status; +- struct vchiq_mmal_instance *instance; +- static VCHI_CONNECTION_T *vchi_connection; +- static VCHI_INSTANCE_T vchi_instance; +- SERVICE_CREATION_T params = { +- .version = VCHI_VERSION_EX(VC_MMAL_VER, VC_MMAL_MIN_VER), +- .service_id = VC_MMAL_SERVER_NAME, +- .connection = vchi_connection, +- .rx_fifo_size = 0, +- .tx_fifo_size = 0, +- .callback = service_callback, +- .callback_param = NULL, +- .want_unaligned_bulk_rx = 1, +- .want_unaligned_bulk_tx = 1, +- .want_crc = 0 +- }; +- +- /* compile time checks to ensure structure size as they are +- * directly (de)serialised from memory. +- */ +- +- /* ensure the header structure has packed to the correct size */ +- BUILD_BUG_ON(sizeof(struct mmal_msg_header) != 24); +- +- /* ensure message structure does not exceed maximum length */ +- BUILD_BUG_ON(sizeof(struct mmal_msg) > MMAL_MSG_MAX_SIZE); +- +- /* mmal port struct is correct size */ +- BUILD_BUG_ON(sizeof(struct mmal_port) != 64); +- +- /* create a vchi instance */ +- status = vchi_initialise(&vchi_instance); +- if (status) { +- pr_err("Failed to initialise VCHI instance (status=%d)\n", +- status); +- return -EIO; +- } +- +- status = vchi_connect(NULL, 0, vchi_instance); +- if (status) { +- pr_err("Failed to connect VCHI instance (status=%d)\n", status); +- return -EIO; +- } +- +- instance = kzalloc(sizeof(*instance), GFP_KERNEL); +- +- if (!instance) +- return -ENOMEM; +- +- mutex_init(&instance->vchiq_mutex); +- +- instance->bulk_scratch = vmalloc(PAGE_SIZE); +- +- mutex_init(&instance->context_map_lock); +- idr_init_base(&instance->context_map, 1); +- +- params.callback_param = instance; +- +- instance->bulk_wq = alloc_ordered_workqueue("mmal-vchiq", +- WQ_MEM_RECLAIM); +- if (!instance->bulk_wq) +- goto err_free; +- +- status = vchi_service_open(vchi_instance, ¶ms, &instance->handle); +- if (status) { +- pr_err("Failed to open VCHI service connection (status=%d)\n", +- status); +- goto err_close_services; +- } +- +- vchi_service_release(instance->handle); +- +- *out_instance = instance; +- +- return 0; +- +-err_close_services: +- vchi_service_close(instance->handle); +- destroy_workqueue(instance->bulk_wq); +-err_free: +- vfree(instance->bulk_scratch); +- kfree(instance); +- return -ENODEV; +-} +--- /dev/null ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +@@ -0,0 +1,1921 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Broadcom BM2835 V4L2 driver ++ * ++ * Copyright © 2013 Raspberry Pi (Trading) Ltd. ++ * ++ * Authors: Vincent Sanders @ Collabora ++ * Dave Stevenson @ Broadcom ++ * (now dave.stevenson@raspberrypi.org) ++ * Simon Mellor @ Broadcom ++ * Luke Diamand @ Broadcom ++ * ++ * V4L2 driver MMAL vchiq interface code ++ */ ++ ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "mmal-common.h" ++#include "mmal-vchiq.h" ++#include "mmal-msg.h" ++ ++#define USE_VCHIQ_ARM ++#include "interface/vchi/vchi.h" ++ ++MODULE_DESCRIPTION("BCM2835 MMAL VCHIQ interface"); ++MODULE_AUTHOR("Dave Stevenson, "); ++MODULE_LICENSE("GPL"); ++MODULE_VERSION("0.0.1"); ++ ++/* maximum number of components supported */ ++#define VCHIQ_MMAL_MAX_COMPONENTS 4 ++ ++/*#define FULL_MSG_DUMP 1*/ ++ ++#ifdef DEBUG ++static const char *const msg_type_names[] = { ++ "UNKNOWN", ++ "QUIT", ++ "SERVICE_CLOSED", ++ "GET_VERSION", ++ "COMPONENT_CREATE", ++ "COMPONENT_DESTROY", ++ "COMPONENT_ENABLE", ++ "COMPONENT_DISABLE", ++ "PORT_INFO_GET", ++ "PORT_INFO_SET", ++ "PORT_ACTION", ++ "BUFFER_FROM_HOST", ++ "BUFFER_TO_HOST", ++ "GET_STATS", ++ "PORT_PARAMETER_SET", ++ "PORT_PARAMETER_GET", ++ "EVENT_TO_HOST", ++ "GET_CORE_STATS_FOR_PORT", ++ "OPAQUE_ALLOCATOR", ++ "CONSUME_MEM", ++ "LMK", ++ "OPAQUE_ALLOCATOR_DESC", ++ "DRM_GET_LHS32", ++ "DRM_GET_TIME", ++ "BUFFER_FROM_HOST_ZEROLEN", ++ "PORT_FLUSH", ++ "HOST_LOG", ++}; ++#endif ++ ++static const char *const port_action_type_names[] = { ++ "UNKNOWN", ++ "ENABLE", ++ "DISABLE", ++ "FLUSH", ++ "CONNECT", ++ "DISCONNECT", ++ "SET_REQUIREMENTS", ++}; ++ ++#if defined(DEBUG) ++#if defined(FULL_MSG_DUMP) ++#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE) \ ++ do { \ ++ pr_debug(TITLE" type:%s(%d) length:%d\n", \ ++ msg_type_names[(MSG)->h.type], \ ++ (MSG)->h.type, (MSG_LEN)); \ ++ print_hex_dump(KERN_DEBUG, "<h.type], \ ++ (MSG)->h.type, (MSG_LEN)); \ ++ } ++#endif ++#else ++#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE) ++#endif ++ ++struct vchiq_mmal_instance; ++ ++/* normal message context */ ++struct mmal_msg_context { ++ struct vchiq_mmal_instance *instance; ++ ++ /* Index in the context_map idr so that we can find the ++ * mmal_msg_context again when servicing the VCHI reply. ++ */ ++ int handle; ++ ++ union { ++ struct { ++ /* work struct for buffer_cb callback */ ++ struct work_struct work; ++ /* work struct for deferred callback */ ++ struct work_struct buffer_to_host_work; ++ /* mmal instance */ ++ struct vchiq_mmal_instance *instance; ++ /* mmal port */ ++ struct vchiq_mmal_port *port; ++ /* actual buffer used to store bulk reply */ ++ struct mmal_buffer *buffer; ++ /* amount of buffer used */ ++ unsigned long buffer_used; ++ /* MMAL buffer flags */ ++ u32 mmal_flags; ++ /* Presentation and Decode timestamps */ ++ s64 pts; ++ s64 dts; ++ ++ int status; /* context status */ ++ ++ } bulk; /* bulk data */ ++ ++ struct { ++ /* message handle to release */ ++ VCHI_HELD_MSG_T msg_handle; ++ /* pointer to received message */ ++ struct mmal_msg *msg; ++ /* received message length */ ++ u32 msg_len; ++ /* completion upon reply */ ++ struct completion cmplt; ++ } sync; /* synchronous response */ ++ } u; ++ ++}; ++ ++struct vchiq_mmal_instance { ++ VCHI_SERVICE_HANDLE_T handle; ++ ++ /* ensure serialised access to service */ ++ struct mutex vchiq_mutex; ++ ++ /* vmalloc page to receive scratch bulk xfers into */ ++ void *bulk_scratch; ++ ++ struct idr context_map; ++ /* protect accesses to context_map */ ++ struct mutex context_map_lock; ++ ++ /* component to use next */ ++ int component_idx; ++ struct vchiq_mmal_component component[VCHIQ_MMAL_MAX_COMPONENTS]; ++ ++ /* ordered workqueue to process all bulk operations */ ++ struct workqueue_struct *bulk_wq; ++}; ++ ++static struct mmal_msg_context * ++get_msg_context(struct vchiq_mmal_instance *instance) ++{ ++ struct mmal_msg_context *msg_context; ++ int handle; ++ ++ /* todo: should this be allocated from a pool to avoid kzalloc */ ++ msg_context = kzalloc(sizeof(*msg_context), GFP_KERNEL); ++ ++ if (!msg_context) ++ return ERR_PTR(-ENOMEM); ++ ++ /* Create an ID that will be passed along with our message so ++ * that when we service the VCHI reply, we can look up what ++ * message is being replied to. ++ */ ++ mutex_lock(&instance->context_map_lock); ++ handle = idr_alloc(&instance->context_map, msg_context, ++ 0, 0, GFP_KERNEL); ++ mutex_unlock(&instance->context_map_lock); ++ ++ if (handle < 0) { ++ kfree(msg_context); ++ return ERR_PTR(handle); ++ } ++ ++ msg_context->instance = instance; ++ msg_context->handle = handle; ++ ++ return msg_context; ++} ++ ++static struct mmal_msg_context * ++lookup_msg_context(struct vchiq_mmal_instance *instance, int handle) ++{ ++ return idr_find(&instance->context_map, handle); ++} ++ ++static void ++release_msg_context(struct mmal_msg_context *msg_context) ++{ ++ struct vchiq_mmal_instance *instance = msg_context->instance; ++ ++ mutex_lock(&instance->context_map_lock); ++ idr_remove(&instance->context_map, msg_context->handle); ++ mutex_unlock(&instance->context_map_lock); ++ kfree(msg_context); ++} ++ ++/* deals with receipt of event to host message */ ++static void event_to_host_cb(struct vchiq_mmal_instance *instance, ++ struct mmal_msg *msg, u32 msg_len) ++{ ++ pr_debug("unhandled event\n"); ++ pr_debug("component:%u port type:%d num:%d cmd:0x%x length:%d\n", ++ msg->u.event_to_host.client_component, ++ msg->u.event_to_host.port_type, ++ msg->u.event_to_host.port_num, ++ msg->u.event_to_host.cmd, msg->u.event_to_host.length); ++} ++ ++/* workqueue scheduled callback ++ * ++ * we do this because it is important we do not call any other vchiq ++ * sync calls from witin the message delivery thread ++ */ ++static void buffer_work_cb(struct work_struct *work) ++{ ++ struct mmal_msg_context *msg_context = ++ container_of(work, struct mmal_msg_context, u.bulk.work); ++ ++ atomic_dec(&msg_context->u.bulk.port->buffers_with_vpu); ++ ++ msg_context->u.bulk.port->buffer_cb(msg_context->u.bulk.instance, ++ msg_context->u.bulk.port, ++ msg_context->u.bulk.status, ++ msg_context->u.bulk.buffer, ++ msg_context->u.bulk.buffer_used, ++ msg_context->u.bulk.mmal_flags, ++ msg_context->u.bulk.dts, ++ msg_context->u.bulk.pts); ++} ++ ++/* workqueue scheduled callback to handle receiving buffers ++ * ++ * VCHI will allow up to 4 bulk receives to be scheduled before blocking. ++ * If we block in the service_callback context then we can't process the ++ * VCHI_CALLBACK_BULK_RECEIVED message that would otherwise allow the blocked ++ * vchi_bulk_queue_receive() call to complete. ++ */ ++static void buffer_to_host_work_cb(struct work_struct *work) ++{ ++ struct mmal_msg_context *msg_context = ++ container_of(work, struct mmal_msg_context, ++ u.bulk.buffer_to_host_work); ++ struct vchiq_mmal_instance *instance = msg_context->instance; ++ unsigned long len = msg_context->u.bulk.buffer_used; ++ int ret; ++ ++ if (!len) ++ /* Dummy receive to ensure the buffers remain in order */ ++ len = 8; ++ /* queue the bulk submission */ ++ vchi_service_use(instance->handle); ++ ret = vchi_bulk_queue_receive(instance->handle, ++ msg_context->u.bulk.buffer->buffer, ++ /* Actual receive needs to be a multiple ++ * of 4 bytes ++ */ ++ (len + 3) & ~3, ++ VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE | ++ VCHI_FLAGS_BLOCK_UNTIL_QUEUED, ++ msg_context); ++ ++ vchi_service_release(instance->handle); ++ ++ if (ret != 0) ++ pr_err("%s: ctx: %p, vchi_bulk_queue_receive failed %d\n", ++ __func__, msg_context, ret); ++} ++ ++/* enqueue a bulk receive for a given message context */ ++static int bulk_receive(struct vchiq_mmal_instance *instance, ++ struct mmal_msg *msg, ++ struct mmal_msg_context *msg_context) ++{ ++ unsigned long rd_len; ++ ++ rd_len = msg->u.buffer_from_host.buffer_header.length; ++ ++ if (!msg_context->u.bulk.buffer) { ++ pr_err("bulk.buffer not configured - error in buffer_from_host\n"); ++ ++ /* todo: this is a serious error, we should never have ++ * committed a buffer_to_host operation to the mmal ++ * port without the buffer to back it up (underflow ++ * handling) and there is no obvious way to deal with ++ * this - how is the mmal servie going to react when ++ * we fail to do the xfer and reschedule a buffer when ++ * it arrives? perhaps a starved flag to indicate a ++ * waiting bulk receive? ++ */ ++ ++ return -EINVAL; ++ } ++ ++ /* ensure we do not overrun the available buffer */ ++ if (rd_len > msg_context->u.bulk.buffer->buffer_size) { ++ rd_len = msg_context->u.bulk.buffer->buffer_size; ++ pr_warn("short read as not enough receive buffer space\n"); ++ /* todo: is this the correct response, what happens to ++ * the rest of the message data? ++ */ ++ } ++ ++ /* store length */ ++ msg_context->u.bulk.buffer_used = rd_len; ++ msg_context->u.bulk.dts = msg->u.buffer_from_host.buffer_header.dts; ++ msg_context->u.bulk.pts = msg->u.buffer_from_host.buffer_header.pts; ++ ++ queue_work(msg_context->instance->bulk_wq, ++ &msg_context->u.bulk.buffer_to_host_work); ++ ++ return 0; ++} ++ ++/* data in message, memcpy from packet into output buffer */ ++static int inline_receive(struct vchiq_mmal_instance *instance, ++ struct mmal_msg *msg, ++ struct mmal_msg_context *msg_context) ++{ ++ memcpy(msg_context->u.bulk.buffer->buffer, ++ msg->u.buffer_from_host.short_data, ++ msg->u.buffer_from_host.payload_in_message); ++ ++ msg_context->u.bulk.buffer_used = ++ msg->u.buffer_from_host.payload_in_message; ++ ++ return 0; ++} ++ ++/* queue the buffer availability with MMAL_MSG_TYPE_BUFFER_FROM_HOST */ ++static int ++buffer_from_host(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port, struct mmal_buffer *buf) ++{ ++ struct mmal_msg_context *msg_context; ++ struct mmal_msg m; ++ int ret; ++ ++ if (!port->enabled) ++ return -EINVAL; ++ ++ pr_debug("instance:%p buffer:%p\n", instance->handle, buf); ++ ++ /* get context */ ++ if (!buf->msg_context) { ++ pr_err("%s: msg_context not allocated, buf %p\n", __func__, ++ buf); ++ return -EINVAL; ++ } ++ msg_context = buf->msg_context; ++ ++ /* store bulk message context for when data arrives */ ++ msg_context->u.bulk.instance = instance; ++ msg_context->u.bulk.port = port; ++ msg_context->u.bulk.buffer = buf; ++ msg_context->u.bulk.buffer_used = 0; ++ ++ /* initialise work structure ready to schedule callback */ ++ INIT_WORK(&msg_context->u.bulk.work, buffer_work_cb); ++ INIT_WORK(&msg_context->u.bulk.buffer_to_host_work, ++ buffer_to_host_work_cb); ++ ++ atomic_inc(&port->buffers_with_vpu); ++ ++ /* prep the buffer from host message */ ++ memset(&m, 0xbc, sizeof(m)); /* just to make debug clearer */ ++ ++ m.h.type = MMAL_MSG_TYPE_BUFFER_FROM_HOST; ++ m.h.magic = MMAL_MAGIC; ++ m.h.context = msg_context->handle; ++ m.h.status = 0; ++ ++ /* drvbuf is our private data passed back */ ++ m.u.buffer_from_host.drvbuf.magic = MMAL_MAGIC; ++ m.u.buffer_from_host.drvbuf.component_handle = port->component->handle; ++ m.u.buffer_from_host.drvbuf.port_handle = port->handle; ++ m.u.buffer_from_host.drvbuf.client_context = msg_context->handle; ++ ++ /* buffer header */ ++ m.u.buffer_from_host.buffer_header.cmd = 0; ++ m.u.buffer_from_host.buffer_header.data = ++ (u32)(unsigned long)buf->buffer; ++ m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size; ++ m.u.buffer_from_host.buffer_header.length = 0; /* nothing used yet */ ++ m.u.buffer_from_host.buffer_header.offset = 0; /* no offset */ ++ m.u.buffer_from_host.buffer_header.flags = 0; /* no flags */ ++ m.u.buffer_from_host.buffer_header.pts = MMAL_TIME_UNKNOWN; ++ m.u.buffer_from_host.buffer_header.dts = MMAL_TIME_UNKNOWN; ++ ++ /* clear buffer type sepecific data */ ++ memset(&m.u.buffer_from_host.buffer_header_type_specific, 0, ++ sizeof(m.u.buffer_from_host.buffer_header_type_specific)); ++ ++ /* no payload in message */ ++ m.u.buffer_from_host.payload_in_message = 0; ++ ++ vchi_service_use(instance->handle); ++ ++ ret = vchi_queue_kernel_message(instance->handle, ++ &m, ++ sizeof(struct mmal_msg_header) + ++ sizeof(m.u.buffer_from_host)); ++ ++ vchi_service_release(instance->handle); ++ ++ return ret; ++} ++ ++/* deals with receipt of buffer to host message */ ++static void buffer_to_host_cb(struct vchiq_mmal_instance *instance, ++ struct mmal_msg *msg, u32 msg_len) ++{ ++ struct mmal_msg_context *msg_context; ++ u32 handle; ++ ++ pr_debug("%s: instance:%p msg:%p msg_len:%d\n", ++ __func__, instance, msg, msg_len); ++ ++ if (msg->u.buffer_from_host.drvbuf.magic == MMAL_MAGIC) { ++ handle = msg->u.buffer_from_host.drvbuf.client_context; ++ msg_context = lookup_msg_context(instance, handle); ++ ++ if (!msg_context) { ++ pr_err("drvbuf.client_context(%u) is invalid\n", ++ handle); ++ return; ++ } ++ } else { ++ pr_err("MMAL_MSG_TYPE_BUFFER_TO_HOST with bad magic\n"); ++ return; ++ } ++ ++ msg_context->u.bulk.mmal_flags = ++ msg->u.buffer_from_host.buffer_header.flags; ++ ++ if (msg->h.status != MMAL_MSG_STATUS_SUCCESS) { ++ /* message reception had an error */ ++ pr_warn("error %d in reply\n", msg->h.status); ++ ++ msg_context->u.bulk.status = msg->h.status; ++ ++ } else if (msg->u.buffer_from_host.buffer_header.length == 0) { ++ /* empty buffer */ ++ if (msg->u.buffer_from_host.buffer_header.flags & ++ MMAL_BUFFER_HEADER_FLAG_EOS) { ++ msg_context->u.bulk.status = ++ bulk_receive(instance, msg, msg_context); ++ if (msg_context->u.bulk.status == 0) ++ return; /* successful bulk submission, bulk ++ * completion will trigger callback ++ */ ++ } else { ++ /* do callback with empty buffer - not EOS though */ ++ msg_context->u.bulk.status = 0; ++ msg_context->u.bulk.buffer_used = 0; ++ } ++ } else if (msg->u.buffer_from_host.payload_in_message == 0) { ++ /* data is not in message, queue a bulk receive */ ++ msg_context->u.bulk.status = ++ bulk_receive(instance, msg, msg_context); ++ if (msg_context->u.bulk.status == 0) ++ return; /* successful bulk submission, bulk ++ * completion will trigger callback ++ */ ++ ++ /* failed to submit buffer, this will end badly */ ++ pr_err("error %d on bulk submission\n", ++ msg_context->u.bulk.status); ++ ++ } else if (msg->u.buffer_from_host.payload_in_message <= ++ MMAL_VC_SHORT_DATA) { ++ /* data payload within message */ ++ msg_context->u.bulk.status = inline_receive(instance, msg, ++ msg_context); ++ } else { ++ pr_err("message with invalid short payload\n"); ++ ++ /* signal error */ ++ msg_context->u.bulk.status = -EINVAL; ++ msg_context->u.bulk.buffer_used = ++ msg->u.buffer_from_host.payload_in_message; ++ } ++ ++ /* schedule the port callback */ ++ schedule_work(&msg_context->u.bulk.work); ++} ++ ++static void bulk_receive_cb(struct vchiq_mmal_instance *instance, ++ struct mmal_msg_context *msg_context) ++{ ++ msg_context->u.bulk.status = 0; ++ ++ /* schedule the port callback */ ++ schedule_work(&msg_context->u.bulk.work); ++} ++ ++static void bulk_abort_cb(struct vchiq_mmal_instance *instance, ++ struct mmal_msg_context *msg_context) ++{ ++ pr_err("%s: bulk ABORTED msg_context:%p\n", __func__, msg_context); ++ ++ msg_context->u.bulk.status = -EINTR; ++ ++ schedule_work(&msg_context->u.bulk.work); ++} ++ ++/* incoming event service callback */ ++static void service_callback(void *param, ++ const VCHI_CALLBACK_REASON_T reason, ++ void *bulk_ctx) ++{ ++ struct vchiq_mmal_instance *instance = param; ++ int status; ++ u32 msg_len; ++ struct mmal_msg *msg; ++ VCHI_HELD_MSG_T msg_handle; ++ struct mmal_msg_context *msg_context; ++ ++ if (!instance) { ++ pr_err("Message callback passed NULL instance\n"); ++ return; ++ } ++ ++ switch (reason) { ++ case VCHI_CALLBACK_MSG_AVAILABLE: ++ status = vchi_msg_hold(instance->handle, (void **)&msg, ++ &msg_len, VCHI_FLAGS_NONE, &msg_handle); ++ if (status) { ++ pr_err("Unable to dequeue a message (%d)\n", status); ++ break; ++ } ++ ++ DBG_DUMP_MSG(msg, msg_len, "<<< reply message"); ++ ++ /* handling is different for buffer messages */ ++ switch (msg->h.type) { ++ case MMAL_MSG_TYPE_BUFFER_FROM_HOST: ++ vchi_held_msg_release(&msg_handle); ++ break; ++ ++ case MMAL_MSG_TYPE_EVENT_TO_HOST: ++ event_to_host_cb(instance, msg, msg_len); ++ vchi_held_msg_release(&msg_handle); ++ ++ break; ++ ++ case MMAL_MSG_TYPE_BUFFER_TO_HOST: ++ buffer_to_host_cb(instance, msg, msg_len); ++ vchi_held_msg_release(&msg_handle); ++ break; ++ ++ default: ++ /* messages dependent on header context to complete */ ++ if (!msg->h.context) { ++ pr_err("received message context was null!\n"); ++ vchi_held_msg_release(&msg_handle); ++ break; ++ } ++ ++ msg_context = lookup_msg_context(instance, ++ msg->h.context); ++ if (!msg_context) { ++ pr_err("received invalid message context %u!\n", ++ msg->h.context); ++ vchi_held_msg_release(&msg_handle); ++ break; ++ } ++ ++ /* fill in context values */ ++ msg_context->u.sync.msg_handle = msg_handle; ++ msg_context->u.sync.msg = msg; ++ msg_context->u.sync.msg_len = msg_len; ++ ++ /* todo: should this check (completion_done() ++ * == 1) for no one waiting? or do we need a ++ * flag to tell us the completion has been ++ * interrupted so we can free the message and ++ * its context. This probably also solves the ++ * message arriving after interruption todo ++ * below ++ */ ++ ++ /* complete message so caller knows it happened */ ++ complete(&msg_context->u.sync.cmplt); ++ break; ++ } ++ ++ break; ++ ++ case VCHI_CALLBACK_BULK_RECEIVED: ++ bulk_receive_cb(instance, bulk_ctx); ++ break; ++ ++ case VCHI_CALLBACK_BULK_RECEIVE_ABORTED: ++ bulk_abort_cb(instance, bulk_ctx); ++ break; ++ ++ case VCHI_CALLBACK_SERVICE_CLOSED: ++ /* TODO: consider if this requires action if received when ++ * driver is not explicitly closing the service ++ */ ++ break; ++ ++ default: ++ pr_err("Received unhandled message reason %d\n", reason); ++ break; ++ } ++} ++ ++static int send_synchronous_mmal_msg(struct vchiq_mmal_instance *instance, ++ struct mmal_msg *msg, ++ unsigned int payload_len, ++ struct mmal_msg **msg_out, ++ VCHI_HELD_MSG_T *msg_handle_out) ++{ ++ struct mmal_msg_context *msg_context; ++ int ret; ++ unsigned long timeout; ++ ++ /* payload size must not cause message to exceed max size */ ++ if (payload_len > ++ (MMAL_MSG_MAX_SIZE - sizeof(struct mmal_msg_header))) { ++ pr_err("payload length %d exceeds max:%d\n", payload_len, ++ (int)(MMAL_MSG_MAX_SIZE - ++ sizeof(struct mmal_msg_header))); ++ return -EINVAL; ++ } ++ ++ msg_context = get_msg_context(instance); ++ if (IS_ERR(msg_context)) ++ return PTR_ERR(msg_context); ++ ++ init_completion(&msg_context->u.sync.cmplt); ++ ++ msg->h.magic = MMAL_MAGIC; ++ msg->h.context = msg_context->handle; ++ msg->h.status = 0; ++ ++ DBG_DUMP_MSG(msg, (sizeof(struct mmal_msg_header) + payload_len), ++ ">>> sync message"); ++ ++ vchi_service_use(instance->handle); ++ ++ ret = vchi_queue_kernel_message(instance->handle, ++ msg, ++ sizeof(struct mmal_msg_header) + ++ payload_len); ++ ++ vchi_service_release(instance->handle); ++ ++ if (ret) { ++ pr_err("error %d queuing message\n", ret); ++ release_msg_context(msg_context); ++ return ret; ++ } ++ ++ timeout = wait_for_completion_timeout(&msg_context->u.sync.cmplt, ++ 3 * HZ); ++ if (timeout == 0) { ++ pr_err("timed out waiting for sync completion\n"); ++ ret = -ETIME; ++ /* todo: what happens if the message arrives after aborting */ ++ release_msg_context(msg_context); ++ return ret; ++ } ++ ++ *msg_out = msg_context->u.sync.msg; ++ *msg_handle_out = msg_context->u.sync.msg_handle; ++ release_msg_context(msg_context); ++ ++ return 0; ++} ++ ++static void dump_port_info(struct vchiq_mmal_port *port) ++{ ++ pr_debug("port handle:0x%x enabled:%d\n", port->handle, port->enabled); ++ ++ pr_debug("buffer minimum num:%d size:%d align:%d\n", ++ port->minimum_buffer.num, ++ port->minimum_buffer.size, port->minimum_buffer.alignment); ++ ++ pr_debug("buffer recommended num:%d size:%d align:%d\n", ++ port->recommended_buffer.num, ++ port->recommended_buffer.size, ++ port->recommended_buffer.alignment); ++ ++ pr_debug("buffer current values num:%d size:%d align:%d\n", ++ port->current_buffer.num, ++ port->current_buffer.size, port->current_buffer.alignment); ++ ++ pr_debug("elementary stream: type:%d encoding:0x%x variant:0x%x\n", ++ port->format.type, ++ port->format.encoding, port->format.encoding_variant); ++ ++ pr_debug(" bitrate:%d flags:0x%x\n", ++ port->format.bitrate, port->format.flags); ++ ++ if (port->format.type == MMAL_ES_TYPE_VIDEO) { ++ pr_debug ++ ("es video format: width:%d height:%d colourspace:0x%x\n", ++ port->es.video.width, port->es.video.height, ++ port->es.video.color_space); ++ ++ pr_debug(" : crop xywh %d,%d,%d,%d\n", ++ port->es.video.crop.x, ++ port->es.video.crop.y, ++ port->es.video.crop.width, port->es.video.crop.height); ++ pr_debug(" : framerate %d/%d aspect %d/%d\n", ++ port->es.video.frame_rate.num, ++ port->es.video.frame_rate.den, ++ port->es.video.par.num, port->es.video.par.den); ++ } ++} ++ ++static void port_to_mmal_msg(struct vchiq_mmal_port *port, struct mmal_port *p) ++{ ++ /* todo do readonly fields need setting at all? */ ++ p->type = port->type; ++ p->index = port->index; ++ p->index_all = 0; ++ p->is_enabled = port->enabled; ++ p->buffer_num_min = port->minimum_buffer.num; ++ p->buffer_size_min = port->minimum_buffer.size; ++ p->buffer_alignment_min = port->minimum_buffer.alignment; ++ p->buffer_num_recommended = port->recommended_buffer.num; ++ p->buffer_size_recommended = port->recommended_buffer.size; ++ ++ /* only three writable fields in a port */ ++ p->buffer_num = port->current_buffer.num; ++ p->buffer_size = port->current_buffer.size; ++ p->userdata = (u32)(unsigned long)port; ++} ++ ++static int port_info_set(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port) ++{ ++ int ret; ++ struct mmal_msg m; ++ struct mmal_msg *rmsg; ++ VCHI_HELD_MSG_T rmsg_handle; ++ ++ pr_debug("setting port info port %p\n", port); ++ if (!port) ++ return -1; ++ dump_port_info(port); ++ ++ m.h.type = MMAL_MSG_TYPE_PORT_INFO_SET; ++ ++ m.u.port_info_set.component_handle = port->component->handle; ++ m.u.port_info_set.port_type = port->type; ++ m.u.port_info_set.port_index = port->index; ++ ++ port_to_mmal_msg(port, &m.u.port_info_set.port); ++ ++ /* elementary stream format setup */ ++ m.u.port_info_set.format.type = port->format.type; ++ m.u.port_info_set.format.encoding = port->format.encoding; ++ m.u.port_info_set.format.encoding_variant = ++ port->format.encoding_variant; ++ m.u.port_info_set.format.bitrate = port->format.bitrate; ++ m.u.port_info_set.format.flags = port->format.flags; ++ ++ memcpy(&m.u.port_info_set.es, &port->es, ++ sizeof(union mmal_es_specific_format)); ++ ++ m.u.port_info_set.format.extradata_size = port->format.extradata_size; ++ memcpy(&m.u.port_info_set.extradata, port->format.extradata, ++ port->format.extradata_size); ++ ++ ret = send_synchronous_mmal_msg(instance, &m, ++ sizeof(m.u.port_info_set), ++ &rmsg, &rmsg_handle); ++ if (ret) ++ return ret; ++ ++ if (rmsg->h.type != MMAL_MSG_TYPE_PORT_INFO_SET) { ++ /* got an unexpected message type in reply */ ++ ret = -EINVAL; ++ goto release_msg; ++ } ++ ++ /* return operation status */ ++ ret = -rmsg->u.port_info_get_reply.status; ++ ++ pr_debug("%s:result:%d component:0x%x port:%d\n", __func__, ret, ++ port->component->handle, port->handle); ++ ++release_msg: ++ vchi_held_msg_release(&rmsg_handle); ++ ++ return ret; ++} ++ ++/* use port info get message to retrieve port information */ ++static int port_info_get(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port) ++{ ++ int ret; ++ struct mmal_msg m; ++ struct mmal_msg *rmsg; ++ VCHI_HELD_MSG_T rmsg_handle; ++ ++ /* port info time */ ++ m.h.type = MMAL_MSG_TYPE_PORT_INFO_GET; ++ m.u.port_info_get.component_handle = port->component->handle; ++ m.u.port_info_get.port_type = port->type; ++ m.u.port_info_get.index = port->index; ++ ++ ret = send_synchronous_mmal_msg(instance, &m, ++ sizeof(m.u.port_info_get), ++ &rmsg, &rmsg_handle); ++ if (ret) ++ return ret; ++ ++ if (rmsg->h.type != MMAL_MSG_TYPE_PORT_INFO_GET) { ++ /* got an unexpected message type in reply */ ++ ret = -EINVAL; ++ goto release_msg; ++ } ++ ++ /* return operation status */ ++ ret = -rmsg->u.port_info_get_reply.status; ++ if (ret != MMAL_MSG_STATUS_SUCCESS) ++ goto release_msg; ++ ++ if (rmsg->u.port_info_get_reply.port.is_enabled == 0) ++ port->enabled = false; ++ else ++ port->enabled = true; ++ ++ /* copy the values out of the message */ ++ port->handle = rmsg->u.port_info_get_reply.port_handle; ++ ++ /* port type and index cached to use on port info set because ++ * it does not use a port handle ++ */ ++ port->type = rmsg->u.port_info_get_reply.port_type; ++ port->index = rmsg->u.port_info_get_reply.port_index; ++ ++ port->minimum_buffer.num = ++ rmsg->u.port_info_get_reply.port.buffer_num_min; ++ port->minimum_buffer.size = ++ rmsg->u.port_info_get_reply.port.buffer_size_min; ++ port->minimum_buffer.alignment = ++ rmsg->u.port_info_get_reply.port.buffer_alignment_min; ++ ++ port->recommended_buffer.alignment = ++ rmsg->u.port_info_get_reply.port.buffer_alignment_min; ++ port->recommended_buffer.num = ++ rmsg->u.port_info_get_reply.port.buffer_num_recommended; ++ ++ port->current_buffer.num = rmsg->u.port_info_get_reply.port.buffer_num; ++ port->current_buffer.size = ++ rmsg->u.port_info_get_reply.port.buffer_size; ++ ++ /* stream format */ ++ port->format.type = rmsg->u.port_info_get_reply.format.type; ++ port->format.encoding = rmsg->u.port_info_get_reply.format.encoding; ++ port->format.encoding_variant = ++ rmsg->u.port_info_get_reply.format.encoding_variant; ++ port->format.bitrate = rmsg->u.port_info_get_reply.format.bitrate; ++ port->format.flags = rmsg->u.port_info_get_reply.format.flags; ++ ++ /* elementary stream format */ ++ memcpy(&port->es, ++ &rmsg->u.port_info_get_reply.es, ++ sizeof(union mmal_es_specific_format)); ++ port->format.es = &port->es; ++ ++ port->format.extradata_size = ++ rmsg->u.port_info_get_reply.format.extradata_size; ++ memcpy(port->format.extradata, ++ rmsg->u.port_info_get_reply.extradata, ++ port->format.extradata_size); ++ ++ pr_debug("received port info\n"); ++ dump_port_info(port); ++ ++release_msg: ++ ++ pr_debug("%s:result:%d component:0x%x port:%d\n", ++ __func__, ret, port->component->handle, port->handle); ++ ++ vchi_held_msg_release(&rmsg_handle); ++ ++ return ret; ++} ++ ++/* create comonent on vc */ ++static int create_component(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_component *component, ++ const char *name) ++{ ++ int ret; ++ struct mmal_msg m; ++ struct mmal_msg *rmsg; ++ VCHI_HELD_MSG_T rmsg_handle; ++ ++ /* build component create message */ ++ m.h.type = MMAL_MSG_TYPE_COMPONENT_CREATE; ++ m.u.component_create.client_component = (u32)(unsigned long)component; ++ strncpy(m.u.component_create.name, name, ++ sizeof(m.u.component_create.name)); ++ ++ ret = send_synchronous_mmal_msg(instance, &m, ++ sizeof(m.u.component_create), ++ &rmsg, &rmsg_handle); ++ if (ret) ++ return ret; ++ ++ if (rmsg->h.type != m.h.type) { ++ /* got an unexpected message type in reply */ ++ ret = -EINVAL; ++ goto release_msg; ++ } ++ ++ ret = -rmsg->u.component_create_reply.status; ++ if (ret != MMAL_MSG_STATUS_SUCCESS) ++ goto release_msg; ++ ++ /* a valid component response received */ ++ component->handle = rmsg->u.component_create_reply.component_handle; ++ component->inputs = rmsg->u.component_create_reply.input_num; ++ component->outputs = rmsg->u.component_create_reply.output_num; ++ component->clocks = rmsg->u.component_create_reply.clock_num; ++ ++ pr_debug("Component handle:0x%x in:%d out:%d clock:%d\n", ++ component->handle, ++ component->inputs, component->outputs, component->clocks); ++ ++release_msg: ++ vchi_held_msg_release(&rmsg_handle); ++ ++ return ret; ++} ++ ++/* destroys a component on vc */ ++static int destroy_component(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_component *component) ++{ ++ int ret; ++ struct mmal_msg m; ++ struct mmal_msg *rmsg; ++ VCHI_HELD_MSG_T rmsg_handle; ++ ++ m.h.type = MMAL_MSG_TYPE_COMPONENT_DESTROY; ++ m.u.component_destroy.component_handle = component->handle; ++ ++ ret = send_synchronous_mmal_msg(instance, &m, ++ sizeof(m.u.component_destroy), ++ &rmsg, &rmsg_handle); ++ if (ret) ++ return ret; ++ ++ if (rmsg->h.type != m.h.type) { ++ /* got an unexpected message type in reply */ ++ ret = -EINVAL; ++ goto release_msg; ++ } ++ ++ ret = -rmsg->u.component_destroy_reply.status; ++ ++release_msg: ++ ++ vchi_held_msg_release(&rmsg_handle); ++ ++ return ret; ++} ++ ++/* enable a component on vc */ ++static int enable_component(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_component *component) ++{ ++ int ret; ++ struct mmal_msg m; ++ struct mmal_msg *rmsg; ++ VCHI_HELD_MSG_T rmsg_handle; ++ ++ m.h.type = MMAL_MSG_TYPE_COMPONENT_ENABLE; ++ m.u.component_enable.component_handle = component->handle; ++ ++ ret = send_synchronous_mmal_msg(instance, &m, ++ sizeof(m.u.component_enable), ++ &rmsg, &rmsg_handle); ++ if (ret) ++ return ret; ++ ++ if (rmsg->h.type != m.h.type) { ++ /* got an unexpected message type in reply */ ++ ret = -EINVAL; ++ goto release_msg; ++ } ++ ++ ret = -rmsg->u.component_enable_reply.status; ++ ++release_msg: ++ vchi_held_msg_release(&rmsg_handle); ++ ++ return ret; ++} ++ ++/* disable a component on vc */ ++static int disable_component(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_component *component) ++{ ++ int ret; ++ struct mmal_msg m; ++ struct mmal_msg *rmsg; ++ VCHI_HELD_MSG_T rmsg_handle; ++ ++ m.h.type = MMAL_MSG_TYPE_COMPONENT_DISABLE; ++ m.u.component_disable.component_handle = component->handle; ++ ++ ret = send_synchronous_mmal_msg(instance, &m, ++ sizeof(m.u.component_disable), ++ &rmsg, &rmsg_handle); ++ if (ret) ++ return ret; ++ ++ if (rmsg->h.type != m.h.type) { ++ /* got an unexpected message type in reply */ ++ ret = -EINVAL; ++ goto release_msg; ++ } ++ ++ ret = -rmsg->u.component_disable_reply.status; ++ ++release_msg: ++ ++ vchi_held_msg_release(&rmsg_handle); ++ ++ return ret; ++} ++ ++/* get version of mmal implementation */ ++static int get_version(struct vchiq_mmal_instance *instance, ++ u32 *major_out, u32 *minor_out) ++{ ++ int ret; ++ struct mmal_msg m; ++ struct mmal_msg *rmsg; ++ VCHI_HELD_MSG_T rmsg_handle; ++ ++ m.h.type = MMAL_MSG_TYPE_GET_VERSION; ++ ++ ret = send_synchronous_mmal_msg(instance, &m, ++ sizeof(m.u.version), ++ &rmsg, &rmsg_handle); ++ if (ret) ++ return ret; ++ ++ if (rmsg->h.type != m.h.type) { ++ /* got an unexpected message type in reply */ ++ ret = -EINVAL; ++ goto release_msg; ++ } ++ ++ *major_out = rmsg->u.version.major; ++ *minor_out = rmsg->u.version.minor; ++ ++release_msg: ++ vchi_held_msg_release(&rmsg_handle); ++ ++ return ret; ++} ++ ++/* do a port action with a port as a parameter */ ++static int port_action_port(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port, ++ enum mmal_msg_port_action_type action_type) ++{ ++ int ret; ++ struct mmal_msg m; ++ struct mmal_msg *rmsg; ++ VCHI_HELD_MSG_T rmsg_handle; ++ ++ m.h.type = MMAL_MSG_TYPE_PORT_ACTION; ++ m.u.port_action_port.component_handle = port->component->handle; ++ m.u.port_action_port.port_handle = port->handle; ++ m.u.port_action_port.action = action_type; ++ ++ port_to_mmal_msg(port, &m.u.port_action_port.port); ++ ++ ret = send_synchronous_mmal_msg(instance, &m, ++ sizeof(m.u.port_action_port), ++ &rmsg, &rmsg_handle); ++ if (ret) ++ return ret; ++ ++ if (rmsg->h.type != MMAL_MSG_TYPE_PORT_ACTION) { ++ /* got an unexpected message type in reply */ ++ ret = -EINVAL; ++ goto release_msg; ++ } ++ ++ ret = -rmsg->u.port_action_reply.status; ++ ++ pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d)\n", ++ __func__, ++ ret, port->component->handle, port->handle, ++ port_action_type_names[action_type], action_type); ++ ++release_msg: ++ vchi_held_msg_release(&rmsg_handle); ++ ++ return ret; ++} ++ ++/* do a port action with handles as parameters */ ++static int port_action_handle(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port, ++ enum mmal_msg_port_action_type action_type, ++ u32 connect_component_handle, ++ u32 connect_port_handle) ++{ ++ int ret; ++ struct mmal_msg m; ++ struct mmal_msg *rmsg; ++ VCHI_HELD_MSG_T rmsg_handle; ++ ++ m.h.type = MMAL_MSG_TYPE_PORT_ACTION; ++ ++ m.u.port_action_handle.component_handle = port->component->handle; ++ m.u.port_action_handle.port_handle = port->handle; ++ m.u.port_action_handle.action = action_type; ++ ++ m.u.port_action_handle.connect_component_handle = ++ connect_component_handle; ++ m.u.port_action_handle.connect_port_handle = connect_port_handle; ++ ++ ret = send_synchronous_mmal_msg(instance, &m, ++ sizeof(m.u.port_action_handle), ++ &rmsg, &rmsg_handle); ++ if (ret) ++ return ret; ++ ++ if (rmsg->h.type != MMAL_MSG_TYPE_PORT_ACTION) { ++ /* got an unexpected message type in reply */ ++ ret = -EINVAL; ++ goto release_msg; ++ } ++ ++ ret = -rmsg->u.port_action_reply.status; ++ ++ pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d) connect component:0x%x connect port:%d\n", ++ __func__, ++ ret, port->component->handle, port->handle, ++ port_action_type_names[action_type], ++ action_type, connect_component_handle, connect_port_handle); ++ ++release_msg: ++ vchi_held_msg_release(&rmsg_handle); ++ ++ return ret; ++} ++ ++static int port_parameter_set(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port, ++ u32 parameter_id, void *value, u32 value_size) ++{ ++ int ret; ++ struct mmal_msg m; ++ struct mmal_msg *rmsg; ++ VCHI_HELD_MSG_T rmsg_handle; ++ ++ m.h.type = MMAL_MSG_TYPE_PORT_PARAMETER_SET; ++ ++ m.u.port_parameter_set.component_handle = port->component->handle; ++ m.u.port_parameter_set.port_handle = port->handle; ++ m.u.port_parameter_set.id = parameter_id; ++ m.u.port_parameter_set.size = (2 * sizeof(u32)) + value_size; ++ memcpy(&m.u.port_parameter_set.value, value, value_size); ++ ++ ret = send_synchronous_mmal_msg(instance, &m, ++ (4 * sizeof(u32)) + value_size, ++ &rmsg, &rmsg_handle); ++ if (ret) ++ return ret; ++ ++ if (rmsg->h.type != MMAL_MSG_TYPE_PORT_PARAMETER_SET) { ++ /* got an unexpected message type in reply */ ++ ret = -EINVAL; ++ goto release_msg; ++ } ++ ++ ret = -rmsg->u.port_parameter_set_reply.status; ++ ++ pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n", ++ __func__, ++ ret, port->component->handle, port->handle, parameter_id); ++ ++release_msg: ++ vchi_held_msg_release(&rmsg_handle); ++ ++ return ret; ++} ++ ++static int port_parameter_get(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port, ++ u32 parameter_id, void *value, u32 *value_size) ++{ ++ int ret; ++ struct mmal_msg m; ++ struct mmal_msg *rmsg; ++ VCHI_HELD_MSG_T rmsg_handle; ++ ++ m.h.type = MMAL_MSG_TYPE_PORT_PARAMETER_GET; ++ ++ m.u.port_parameter_get.component_handle = port->component->handle; ++ m.u.port_parameter_get.port_handle = port->handle; ++ m.u.port_parameter_get.id = parameter_id; ++ m.u.port_parameter_get.size = (2 * sizeof(u32)) + *value_size; ++ ++ ret = send_synchronous_mmal_msg(instance, &m, ++ sizeof(struct ++ mmal_msg_port_parameter_get), ++ &rmsg, &rmsg_handle); ++ if (ret) ++ return ret; ++ ++ if (rmsg->h.type != MMAL_MSG_TYPE_PORT_PARAMETER_GET) { ++ /* got an unexpected message type in reply */ ++ pr_err("Incorrect reply type %d\n", rmsg->h.type); ++ ret = -EINVAL; ++ goto release_msg; ++ } ++ ++ ret = -rmsg->u.port_parameter_get_reply.status; ++ /* port_parameter_get_reply.size includes the header, ++ * whilst *value_size doesn't. ++ */ ++ rmsg->u.port_parameter_get_reply.size -= (2 * sizeof(u32)); ++ ++ if (ret || rmsg->u.port_parameter_get_reply.size > *value_size) { ++ /* Copy only as much as we have space for ++ * but report true size of parameter ++ */ ++ memcpy(value, &rmsg->u.port_parameter_get_reply.value, ++ *value_size); ++ *value_size = rmsg->u.port_parameter_get_reply.size; ++ } else { ++ memcpy(value, &rmsg->u.port_parameter_get_reply.value, ++ rmsg->u.port_parameter_get_reply.size); ++ } ++ ++ pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n", __func__, ++ ret, port->component->handle, port->handle, parameter_id); ++ ++release_msg: ++ vchi_held_msg_release(&rmsg_handle); ++ ++ return ret; ++} ++ ++/* disables a port and drains buffers from it */ ++static int port_disable(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port) ++{ ++ int ret; ++ struct list_head *q, *buf_head; ++ unsigned long flags = 0; ++ ++ if (!port->enabled) ++ return 0; ++ ++ port->enabled = false; ++ ++ ret = port_action_port(instance, port, ++ MMAL_MSG_PORT_ACTION_TYPE_DISABLE); ++ if (ret == 0) { ++ /* ++ * Drain all queued buffers on port. This should only ++ * apply to buffers that have been queued before the port ++ * has been enabled. If the port has been enabled and buffers ++ * passed, then the buffers should have been removed from this ++ * list, and we should get the relevant callbacks via VCHIQ ++ * to release the buffers. ++ */ ++ spin_lock_irqsave(&port->slock, flags); ++ ++ list_for_each_safe(buf_head, q, &port->buffers) { ++ struct mmal_buffer *mmalbuf; ++ ++ mmalbuf = list_entry(buf_head, struct mmal_buffer, ++ list); ++ list_del(buf_head); ++ if (port->buffer_cb) ++ port->buffer_cb(instance, ++ port, 0, mmalbuf, 0, 0, ++ MMAL_TIME_UNKNOWN, ++ MMAL_TIME_UNKNOWN); ++ } ++ ++ spin_unlock_irqrestore(&port->slock, flags); ++ ++ ret = port_info_get(instance, port); ++ } ++ ++ return ret; ++} ++ ++/* enable a port */ ++static int port_enable(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port) ++{ ++ unsigned int hdr_count; ++ struct list_head *q, *buf_head; ++ int ret; ++ ++ if (port->enabled) ++ return 0; ++ ++ ret = port_action_port(instance, port, ++ MMAL_MSG_PORT_ACTION_TYPE_ENABLE); ++ if (ret) ++ goto done; ++ ++ port->enabled = true; ++ ++ if (port->buffer_cb) { ++ /* send buffer headers to videocore */ ++ hdr_count = 1; ++ list_for_each_safe(buf_head, q, &port->buffers) { ++ struct mmal_buffer *mmalbuf; ++ ++ mmalbuf = list_entry(buf_head, struct mmal_buffer, ++ list); ++ ret = buffer_from_host(instance, port, mmalbuf); ++ if (ret) ++ goto done; ++ ++ list_del(buf_head); ++ hdr_count++; ++ if (hdr_count > port->current_buffer.num) ++ break; ++ } ++ } ++ ++ ret = port_info_get(instance, port); ++ ++done: ++ return ret; ++} ++ ++/* ------------------------------------------------------------------ ++ * Exported API ++ *------------------------------------------------------------------ ++ */ ++ ++int vchiq_mmal_port_set_format(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port) ++{ ++ int ret; ++ ++ if (mutex_lock_interruptible(&instance->vchiq_mutex)) ++ return -EINTR; ++ ++ ret = port_info_set(instance, port); ++ if (ret) ++ goto release_unlock; ++ ++ /* read what has actually been set */ ++ ret = port_info_get(instance, port); ++ ++release_unlock: ++ mutex_unlock(&instance->vchiq_mutex); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(vchiq_mmal_port_set_format); ++ ++int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port, ++ u32 parameter, void *value, u32 value_size) ++{ ++ int ret; ++ ++ if (mutex_lock_interruptible(&instance->vchiq_mutex)) ++ return -EINTR; ++ ++ ret = port_parameter_set(instance, port, parameter, value, value_size); ++ ++ mutex_unlock(&instance->vchiq_mutex); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_set); ++ ++int vchiq_mmal_port_parameter_get(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port, ++ u32 parameter, void *value, u32 *value_size) ++{ ++ int ret; ++ ++ if (mutex_lock_interruptible(&instance->vchiq_mutex)) ++ return -EINTR; ++ ++ ret = port_parameter_get(instance, port, parameter, value, value_size); ++ ++ mutex_unlock(&instance->vchiq_mutex); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_get); ++ ++/* enable a port ++ * ++ * enables a port and queues buffers for satisfying callbacks if we ++ * provide a callback handler ++ */ ++int vchiq_mmal_port_enable(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port, ++ vchiq_mmal_buffer_cb buffer_cb) ++{ ++ int ret; ++ ++ if (mutex_lock_interruptible(&instance->vchiq_mutex)) ++ return -EINTR; ++ ++ /* already enabled - noop */ ++ if (port->enabled) { ++ ret = 0; ++ goto unlock; ++ } ++ ++ port->buffer_cb = buffer_cb; ++ ++ ret = port_enable(instance, port); ++ ++unlock: ++ mutex_unlock(&instance->vchiq_mutex); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(vchiq_mmal_port_enable); ++ ++int vchiq_mmal_port_disable(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port) ++{ ++ int ret; ++ ++ if (mutex_lock_interruptible(&instance->vchiq_mutex)) ++ return -EINTR; ++ ++ if (!port->enabled) { ++ mutex_unlock(&instance->vchiq_mutex); ++ return 0; ++ } ++ ++ ret = port_disable(instance, port); ++ ++ mutex_unlock(&instance->vchiq_mutex); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(vchiq_mmal_port_disable); ++ ++/* ports will be connected in a tunneled manner so data buffers ++ * are not handled by client. ++ */ ++int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *src, ++ struct vchiq_mmal_port *dst) ++{ ++ int ret; ++ ++ if (mutex_lock_interruptible(&instance->vchiq_mutex)) ++ return -EINTR; ++ ++ /* disconnect ports if connected */ ++ if (src->connected) { ++ ret = port_disable(instance, src); ++ if (ret) { ++ pr_err("failed disabling src port(%d)\n", ret); ++ goto release_unlock; ++ } ++ ++ /* do not need to disable the destination port as they ++ * are connected and it is done automatically ++ */ ++ ++ ret = port_action_handle(instance, src, ++ MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT, ++ src->connected->component->handle, ++ src->connected->handle); ++ if (ret < 0) { ++ pr_err("failed disconnecting src port\n"); ++ goto release_unlock; ++ } ++ src->connected->enabled = false; ++ src->connected = NULL; ++ } ++ ++ if (!dst) { ++ /* do not make new connection */ ++ ret = 0; ++ pr_debug("not making new connection\n"); ++ goto release_unlock; ++ } ++ ++ /* copy src port format to dst */ ++ dst->format.encoding = src->format.encoding; ++ dst->es.video.width = src->es.video.width; ++ dst->es.video.height = src->es.video.height; ++ dst->es.video.crop.x = src->es.video.crop.x; ++ dst->es.video.crop.y = src->es.video.crop.y; ++ dst->es.video.crop.width = src->es.video.crop.width; ++ dst->es.video.crop.height = src->es.video.crop.height; ++ dst->es.video.frame_rate.num = src->es.video.frame_rate.num; ++ dst->es.video.frame_rate.den = src->es.video.frame_rate.den; ++ ++ /* set new format */ ++ ret = port_info_set(instance, dst); ++ if (ret) { ++ pr_debug("setting port info failed\n"); ++ goto release_unlock; ++ } ++ ++ /* read what has actually been set */ ++ ret = port_info_get(instance, dst); ++ if (ret) { ++ pr_debug("read back port info failed\n"); ++ goto release_unlock; ++ } ++ ++ /* connect two ports together */ ++ ret = port_action_handle(instance, src, ++ MMAL_MSG_PORT_ACTION_TYPE_CONNECT, ++ dst->component->handle, dst->handle); ++ if (ret < 0) { ++ pr_debug("connecting port %d:%d to %d:%d failed\n", ++ src->component->handle, src->handle, ++ dst->component->handle, dst->handle); ++ goto release_unlock; ++ } ++ src->connected = dst; ++ ++release_unlock: ++ ++ mutex_unlock(&instance->vchiq_mutex); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(vchiq_mmal_port_connect_tunnel); ++ ++int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port, ++ struct mmal_buffer *buffer) ++{ ++ unsigned long flags = 0; ++ int ret; ++ ++ ret = buffer_from_host(instance, port, buffer); ++ if (ret == -EINVAL) { ++ /* Port is disabled. Queue for when it is enabled. */ ++ spin_lock_irqsave(&port->slock, flags); ++ list_add_tail(&buffer->list, &port->buffers); ++ spin_unlock_irqrestore(&port->slock, flags); ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(vchiq_mmal_submit_buffer); ++ ++int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance, ++ struct mmal_buffer *buf) ++{ ++ struct mmal_msg_context *msg_context = get_msg_context(instance); ++ ++ if (IS_ERR(msg_context)) ++ return (PTR_ERR(msg_context)); ++ ++ buf->msg_context = msg_context; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(mmal_vchi_buffer_init); ++ ++int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf) ++{ ++ struct mmal_msg_context *msg_context = buf->msg_context; ++ ++ if (msg_context) ++ release_msg_context(msg_context); ++ buf->msg_context = NULL; ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup); ++ ++/* Initialise a mmal component and its ports ++ * ++ */ ++int vchiq_mmal_component_init(struct vchiq_mmal_instance *instance, ++ const char *name, ++ struct vchiq_mmal_component **component_out) ++{ ++ int ret; ++ int idx; /* port index */ ++ struct vchiq_mmal_component *component; ++ ++ if (mutex_lock_interruptible(&instance->vchiq_mutex)) ++ return -EINTR; ++ ++ if (instance->component_idx == VCHIQ_MMAL_MAX_COMPONENTS) { ++ ret = -EINVAL; /* todo is this correct error? */ ++ goto unlock; ++ } ++ ++ component = &instance->component[instance->component_idx]; ++ ++ ret = create_component(instance, component, name); ++ if (ret < 0) { ++ pr_err("%s: failed to create component %d (Not enough GPU mem?)\n", ++ __func__, ret); ++ goto unlock; ++ } ++ ++ /* ports info needs gathering */ ++ component->control.type = MMAL_PORT_TYPE_CONTROL; ++ component->control.index = 0; ++ component->control.component = component; ++ spin_lock_init(&component->control.slock); ++ INIT_LIST_HEAD(&component->control.buffers); ++ ret = port_info_get(instance, &component->control); ++ if (ret < 0) ++ goto release_component; ++ ++ for (idx = 0; idx < component->inputs; idx++) { ++ component->input[idx].type = MMAL_PORT_TYPE_INPUT; ++ component->input[idx].index = idx; ++ component->input[idx].component = component; ++ spin_lock_init(&component->input[idx].slock); ++ INIT_LIST_HEAD(&component->input[idx].buffers); ++ ret = port_info_get(instance, &component->input[idx]); ++ if (ret < 0) ++ goto release_component; ++ } ++ ++ for (idx = 0; idx < component->outputs; idx++) { ++ component->output[idx].type = MMAL_PORT_TYPE_OUTPUT; ++ component->output[idx].index = idx; ++ component->output[idx].component = component; ++ spin_lock_init(&component->output[idx].slock); ++ INIT_LIST_HEAD(&component->output[idx].buffers); ++ ret = port_info_get(instance, &component->output[idx]); ++ if (ret < 0) ++ goto release_component; ++ } ++ ++ for (idx = 0; idx < component->clocks; idx++) { ++ component->clock[idx].type = MMAL_PORT_TYPE_CLOCK; ++ component->clock[idx].index = idx; ++ component->clock[idx].component = component; ++ spin_lock_init(&component->clock[idx].slock); ++ INIT_LIST_HEAD(&component->clock[idx].buffers); ++ ret = port_info_get(instance, &component->clock[idx]); ++ if (ret < 0) ++ goto release_component; ++ } ++ ++ instance->component_idx++; ++ ++ *component_out = component; ++ ++ mutex_unlock(&instance->vchiq_mutex); ++ ++ return 0; ++ ++release_component: ++ destroy_component(instance, component); ++unlock: ++ mutex_unlock(&instance->vchiq_mutex); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(vchiq_mmal_component_init); ++ ++/* ++ * cause a mmal component to be destroyed ++ */ ++int vchiq_mmal_component_finalise(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_component *component) ++{ ++ int ret; ++ ++ if (mutex_lock_interruptible(&instance->vchiq_mutex)) ++ return -EINTR; ++ ++ if (component->enabled) ++ ret = disable_component(instance, component); ++ ++ ret = destroy_component(instance, component); ++ ++ mutex_unlock(&instance->vchiq_mutex); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(vchiq_mmal_component_finalise); ++ ++/* ++ * cause a mmal component to be enabled ++ */ ++int vchiq_mmal_component_enable(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_component *component) ++{ ++ int ret; ++ ++ if (mutex_lock_interruptible(&instance->vchiq_mutex)) ++ return -EINTR; ++ ++ if (component->enabled) { ++ mutex_unlock(&instance->vchiq_mutex); ++ return 0; ++ } ++ ++ ret = enable_component(instance, component); ++ if (ret == 0) ++ component->enabled = true; ++ ++ mutex_unlock(&instance->vchiq_mutex); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(vchiq_mmal_component_enable); ++ ++/* ++ * cause a mmal component to be enabled ++ */ ++int vchiq_mmal_component_disable(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_component *component) ++{ ++ int ret; ++ ++ if (mutex_lock_interruptible(&instance->vchiq_mutex)) ++ return -EINTR; ++ ++ if (!component->enabled) { ++ mutex_unlock(&instance->vchiq_mutex); ++ return 0; ++ } ++ ++ ret = disable_component(instance, component); ++ if (ret == 0) ++ component->enabled = false; ++ ++ mutex_unlock(&instance->vchiq_mutex); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(vchiq_mmal_component_disable); ++ ++int vchiq_mmal_version(struct vchiq_mmal_instance *instance, ++ u32 *major_out, u32 *minor_out) ++{ ++ int ret; ++ ++ if (mutex_lock_interruptible(&instance->vchiq_mutex)) ++ return -EINTR; ++ ++ ret = get_version(instance, major_out, minor_out); ++ ++ mutex_unlock(&instance->vchiq_mutex); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(vchiq_mmal_version); ++ ++int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance) ++{ ++ int status = 0; ++ ++ if (!instance) ++ return -EINVAL; ++ ++ if (mutex_lock_interruptible(&instance->vchiq_mutex)) ++ return -EINTR; ++ ++ vchi_service_use(instance->handle); ++ ++ status = vchi_service_close(instance->handle); ++ if (status != 0) ++ pr_err("mmal-vchiq: VCHIQ close failed\n"); ++ ++ mutex_unlock(&instance->vchiq_mutex); ++ ++ flush_workqueue(instance->bulk_wq); ++ destroy_workqueue(instance->bulk_wq); ++ ++ vfree(instance->bulk_scratch); ++ ++ idr_destroy(&instance->context_map); ++ ++ kfree(instance); ++ ++ return status; ++} ++EXPORT_SYMBOL_GPL(vchiq_mmal_finalise); ++ ++int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance) ++{ ++ int status; ++ struct vchiq_mmal_instance *instance; ++ static VCHI_CONNECTION_T *vchi_connection; ++ static VCHI_INSTANCE_T vchi_instance; ++ SERVICE_CREATION_T params = { ++ .version = VCHI_VERSION_EX(VC_MMAL_VER, VC_MMAL_MIN_VER), ++ .service_id = VC_MMAL_SERVER_NAME, ++ .connection = vchi_connection, ++ .rx_fifo_size = 0, ++ .tx_fifo_size = 0, ++ .callback = service_callback, ++ .callback_param = NULL, ++ .want_unaligned_bulk_rx = 1, ++ .want_unaligned_bulk_tx = 1, ++ .want_crc = 0 ++ }; ++ ++ /* compile time checks to ensure structure size as they are ++ * directly (de)serialised from memory. ++ */ ++ ++ /* ensure the header structure has packed to the correct size */ ++ BUILD_BUG_ON(sizeof(struct mmal_msg_header) != 24); ++ ++ /* ensure message structure does not exceed maximum length */ ++ BUILD_BUG_ON(sizeof(struct mmal_msg) > MMAL_MSG_MAX_SIZE); ++ ++ /* mmal port struct is correct size */ ++ BUILD_BUG_ON(sizeof(struct mmal_port) != 64); ++ ++ /* create a vchi instance */ ++ status = vchi_initialise(&vchi_instance); ++ if (status) { ++ pr_err("Failed to initialise VCHI instance (status=%d)\n", ++ status); ++ return -EIO; ++ } ++ ++ status = vchi_connect(NULL, 0, vchi_instance); ++ if (status) { ++ pr_err("Failed to connect VCHI instance (status=%d)\n", status); ++ return -EIO; ++ } ++ ++ instance = kzalloc(sizeof(*instance), GFP_KERNEL); ++ ++ if (!instance) ++ return -ENOMEM; ++ ++ mutex_init(&instance->vchiq_mutex); ++ ++ instance->bulk_scratch = vmalloc(PAGE_SIZE); ++ ++ mutex_init(&instance->context_map_lock); ++ idr_init_base(&instance->context_map, 1); ++ ++ params.callback_param = instance; ++ ++ instance->bulk_wq = alloc_ordered_workqueue("mmal-vchiq", ++ WQ_MEM_RECLAIM); ++ if (!instance->bulk_wq) ++ goto err_free; ++ ++ status = vchi_service_open(vchi_instance, ¶ms, &instance->handle); ++ if (status) { ++ pr_err("Failed to open VCHI service connection (status=%d)\n", ++ status); ++ goto err_close_services; ++ } ++ ++ vchi_service_release(instance->handle); ++ ++ *out_instance = instance; ++ ++ return 0; ++ ++err_close_services: ++ vchi_service_close(instance->handle); ++ destroy_workqueue(instance->bulk_wq); ++err_free: ++ vfree(instance->bulk_scratch); ++ kfree(instance); ++ return -ENODEV; ++} ++EXPORT_SYMBOL_GPL(vchiq_mmal_init); +--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h ++++ /dev/null +@@ -1,61 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * Broadcom BM2835 V4L2 driver +- * +- * Copyright © 2013 Raspberry Pi (Trading) Ltd. +- * +- * Authors: Vincent Sanders @ Collabora +- * Dave Stevenson @ Broadcom +- * (now dave.stevenson@raspberrypi.org) +- * Simon Mellor @ Broadcom +- * Luke Diamand @ Broadcom +- * +- * MMAL structures +- * +- */ +-#ifndef MMAL_COMMON_H +-#define MMAL_COMMON_H +- +-#define MMAL_FOURCC(a, b, c, d) ((a) | (b << 8) | (c << 16) | (d << 24)) +-#define MMAL_MAGIC MMAL_FOURCC('m', 'm', 'a', 'l') +- +-/** Special value signalling that time is not known */ +-#define MMAL_TIME_UNKNOWN BIT_ULL(63) +- +-struct mmal_msg_context; +- +-/* mapping between v4l and mmal video modes */ +-struct mmal_fmt { +- char *name; +- u32 fourcc; /* v4l2 format id */ +- int flags; /* v4l2 flags field */ +- u32 mmal; +- int depth; +- u32 mmal_component; /* MMAL component index to be used to encode */ +- u32 ybbp; /* depth of first Y plane for planar formats */ +- bool remove_padding; /* Does the GPU have to remove padding, +- * or can we do hide padding via bytesperline. +- */ +-}; +- +-/* buffer for one video frame */ +-struct mmal_buffer { +- /* v4l buffer data -- must be first */ +- struct vb2_v4l2_buffer vb; +- +- /* list of buffers available */ +- struct list_head list; +- +- void *buffer; /* buffer pointer */ +- unsigned long buffer_size; /* size of allocated buffer */ +- +- struct mmal_msg_context *msg_context; +-}; +- +-/* */ +-struct mmal_colourfx { +- s32 enable; +- u32 u; +- u32 v; +-}; +-#endif +--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-encodings.h ++++ /dev/null +@@ -1,124 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * Broadcom BM2835 V4L2 driver +- * +- * Copyright © 2013 Raspberry Pi (Trading) Ltd. +- * +- * Authors: Vincent Sanders @ Collabora +- * Dave Stevenson @ Broadcom +- * (now dave.stevenson@raspberrypi.org) +- * Simon Mellor @ Broadcom +- * Luke Diamand @ Broadcom +- */ +-#ifndef MMAL_ENCODINGS_H +-#define MMAL_ENCODINGS_H +- +-#define MMAL_ENCODING_H264 MMAL_FOURCC('H', '2', '6', '4') +-#define MMAL_ENCODING_H263 MMAL_FOURCC('H', '2', '6', '3') +-#define MMAL_ENCODING_MP4V MMAL_FOURCC('M', 'P', '4', 'V') +-#define MMAL_ENCODING_MP2V MMAL_FOURCC('M', 'P', '2', 'V') +-#define MMAL_ENCODING_MP1V MMAL_FOURCC('M', 'P', '1', 'V') +-#define MMAL_ENCODING_WMV3 MMAL_FOURCC('W', 'M', 'V', '3') +-#define MMAL_ENCODING_WMV2 MMAL_FOURCC('W', 'M', 'V', '2') +-#define MMAL_ENCODING_WMV1 MMAL_FOURCC('W', 'M', 'V', '1') +-#define MMAL_ENCODING_WVC1 MMAL_FOURCC('W', 'V', 'C', '1') +-#define MMAL_ENCODING_VP8 MMAL_FOURCC('V', 'P', '8', ' ') +-#define MMAL_ENCODING_VP7 MMAL_FOURCC('V', 'P', '7', ' ') +-#define MMAL_ENCODING_VP6 MMAL_FOURCC('V', 'P', '6', ' ') +-#define MMAL_ENCODING_THEORA MMAL_FOURCC('T', 'H', 'E', 'O') +-#define MMAL_ENCODING_SPARK MMAL_FOURCC('S', 'P', 'R', 'K') +-#define MMAL_ENCODING_MJPEG MMAL_FOURCC('M', 'J', 'P', 'G') +- +-#define MMAL_ENCODING_JPEG MMAL_FOURCC('J', 'P', 'E', 'G') +-#define MMAL_ENCODING_GIF MMAL_FOURCC('G', 'I', 'F', ' ') +-#define MMAL_ENCODING_PNG MMAL_FOURCC('P', 'N', 'G', ' ') +-#define MMAL_ENCODING_PPM MMAL_FOURCC('P', 'P', 'M', ' ') +-#define MMAL_ENCODING_TGA MMAL_FOURCC('T', 'G', 'A', ' ') +-#define MMAL_ENCODING_BMP MMAL_FOURCC('B', 'M', 'P', ' ') +- +-#define MMAL_ENCODING_I420 MMAL_FOURCC('I', '4', '2', '0') +-#define MMAL_ENCODING_I420_SLICE MMAL_FOURCC('S', '4', '2', '0') +-#define MMAL_ENCODING_YV12 MMAL_FOURCC('Y', 'V', '1', '2') +-#define MMAL_ENCODING_I422 MMAL_FOURCC('I', '4', '2', '2') +-#define MMAL_ENCODING_I422_SLICE MMAL_FOURCC('S', '4', '2', '2') +-#define MMAL_ENCODING_YUYV MMAL_FOURCC('Y', 'U', 'Y', 'V') +-#define MMAL_ENCODING_YVYU MMAL_FOURCC('Y', 'V', 'Y', 'U') +-#define MMAL_ENCODING_UYVY MMAL_FOURCC('U', 'Y', 'V', 'Y') +-#define MMAL_ENCODING_VYUY MMAL_FOURCC('V', 'Y', 'U', 'Y') +-#define MMAL_ENCODING_NV12 MMAL_FOURCC('N', 'V', '1', '2') +-#define MMAL_ENCODING_NV21 MMAL_FOURCC('N', 'V', '2', '1') +-#define MMAL_ENCODING_ARGB MMAL_FOURCC('A', 'R', 'G', 'B') +-#define MMAL_ENCODING_RGBA MMAL_FOURCC('R', 'G', 'B', 'A') +-#define MMAL_ENCODING_ABGR MMAL_FOURCC('A', 'B', 'G', 'R') +-#define MMAL_ENCODING_BGRA MMAL_FOURCC('B', 'G', 'R', 'A') +-#define MMAL_ENCODING_RGB16 MMAL_FOURCC('R', 'G', 'B', '2') +-#define MMAL_ENCODING_RGB24 MMAL_FOURCC('R', 'G', 'B', '3') +-#define MMAL_ENCODING_RGB32 MMAL_FOURCC('R', 'G', 'B', '4') +-#define MMAL_ENCODING_BGR16 MMAL_FOURCC('B', 'G', 'R', '2') +-#define MMAL_ENCODING_BGR24 MMAL_FOURCC('B', 'G', 'R', '3') +-#define MMAL_ENCODING_BGR32 MMAL_FOURCC('B', 'G', 'R', '4') +- +-/** SAND Video (YUVUV128) format, native format understood by VideoCore. +- * This format is *not* opaque - if requested you will receive full frames +- * of YUV_UV video. +- */ +-#define MMAL_ENCODING_YUVUV128 MMAL_FOURCC('S', 'A', 'N', 'D') +- +-/** VideoCore opaque image format, image handles are returned to +- * the host but not the actual image data. +- */ +-#define MMAL_ENCODING_OPAQUE MMAL_FOURCC('O', 'P', 'Q', 'V') +- +-/** An EGL image handle +- */ +-#define MMAL_ENCODING_EGL_IMAGE MMAL_FOURCC('E', 'G', 'L', 'I') +- +-/* }@ */ +- +-/** \name Pre-defined audio encodings */ +-/* @{ */ +-#define MMAL_ENCODING_PCM_UNSIGNED_BE MMAL_FOURCC('P', 'C', 'M', 'U') +-#define MMAL_ENCODING_PCM_UNSIGNED_LE MMAL_FOURCC('p', 'c', 'm', 'u') +-#define MMAL_ENCODING_PCM_SIGNED_BE MMAL_FOURCC('P', 'C', 'M', 'S') +-#define MMAL_ENCODING_PCM_SIGNED_LE MMAL_FOURCC('p', 'c', 'm', 's') +-#define MMAL_ENCODING_PCM_FLOAT_BE MMAL_FOURCC('P', 'C', 'M', 'F') +-#define MMAL_ENCODING_PCM_FLOAT_LE MMAL_FOURCC('p', 'c', 'm', 'f') +- +-/* Pre-defined H264 encoding variants */ +- +-/** ISO 14496-10 Annex B byte stream format */ +-#define MMAL_ENCODING_VARIANT_H264_DEFAULT 0 +-/** ISO 14496-15 AVC stream format */ +-#define MMAL_ENCODING_VARIANT_H264_AVC1 MMAL_FOURCC('A', 'V', 'C', '1') +-/** Implicitly delineated NAL units without emulation prevention */ +-#define MMAL_ENCODING_VARIANT_H264_RAW MMAL_FOURCC('R', 'A', 'W', ' ') +- +-/** \defgroup MmalColorSpace List of pre-defined video color spaces +- * This defines a list of common color spaces. This list isn't exhaustive and +- * is only provided as a convenience to avoid clients having to use FourCC +- * codes directly. However components are allowed to define and use their own +- * FourCC codes. +- */ +-/* @{ */ +- +-/** Unknown color space */ +-#define MMAL_COLOR_SPACE_UNKNOWN 0 +-/** ITU-R BT.601-5 [SDTV] */ +-#define MMAL_COLOR_SPACE_ITUR_BT601 MMAL_FOURCC('Y', '6', '0', '1') +-/** ITU-R BT.709-3 [HDTV] */ +-#define MMAL_COLOR_SPACE_ITUR_BT709 MMAL_FOURCC('Y', '7', '0', '9') +-/** JPEG JFIF */ +-#define MMAL_COLOR_SPACE_JPEG_JFIF MMAL_FOURCC('Y', 'J', 'F', 'I') +-/** Title 47 Code of Federal Regulations (2003) 73.682 (a) (20) */ +-#define MMAL_COLOR_SPACE_FCC MMAL_FOURCC('Y', 'F', 'C', 'C') +-/** Society of Motion Picture and Television Engineers 240M (1999) */ +-#define MMAL_COLOR_SPACE_SMPTE240M MMAL_FOURCC('Y', '2', '4', '0') +-/** ITU-R BT.470-2 System M */ +-#define MMAL_COLOR_SPACE_BT470_2_M MMAL_FOURCC('Y', '_', '_', 'M') +-/** ITU-R BT.470-2 System BG */ +-#define MMAL_COLOR_SPACE_BT470_2_BG MMAL_FOURCC('Y', '_', 'B', 'G') +-/** JPEG JFIF, but with 16..255 luma */ +-#define MMAL_COLOR_SPACE_JFIF_Y16_255 MMAL_FOURCC('Y', 'Y', '1', '6') +-/* @} MmalColorSpace List */ +- +-#endif /* MMAL_ENCODINGS_H */ +--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-common.h ++++ /dev/null +@@ -1,48 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * Broadcom BM2835 V4L2 driver +- * +- * Copyright © 2013 Raspberry Pi (Trading) Ltd. +- * +- * Authors: Vincent Sanders @ Collabora +- * Dave Stevenson @ Broadcom +- * (now dave.stevenson@raspberrypi.org) +- * Simon Mellor @ Broadcom +- * Luke Diamand @ Broadcom +- */ +- +-#ifndef MMAL_MSG_COMMON_H +-#define MMAL_MSG_COMMON_H +- +-enum mmal_msg_status { +- MMAL_MSG_STATUS_SUCCESS = 0, /**< Success */ +- MMAL_MSG_STATUS_ENOMEM, /**< Out of memory */ +- MMAL_MSG_STATUS_ENOSPC, /**< Out of resources other than memory */ +- MMAL_MSG_STATUS_EINVAL, /**< Argument is invalid */ +- MMAL_MSG_STATUS_ENOSYS, /**< Function not implemented */ +- MMAL_MSG_STATUS_ENOENT, /**< No such file or directory */ +- MMAL_MSG_STATUS_ENXIO, /**< No such device or address */ +- MMAL_MSG_STATUS_EIO, /**< I/O error */ +- MMAL_MSG_STATUS_ESPIPE, /**< Illegal seek */ +- MMAL_MSG_STATUS_ECORRUPT, /**< Data is corrupt \attention */ +- MMAL_MSG_STATUS_ENOTREADY, /**< Component is not ready */ +- MMAL_MSG_STATUS_ECONFIG, /**< Component is not configured */ +- MMAL_MSG_STATUS_EISCONN, /**< Port is already connected */ +- MMAL_MSG_STATUS_ENOTCONN, /**< Port is disconnected */ +- MMAL_MSG_STATUS_EAGAIN, /**< Resource temporarily unavailable. */ +- MMAL_MSG_STATUS_EFAULT, /**< Bad address */ +-}; +- +-struct mmal_rect { +- s32 x; /**< x coordinate (from left) */ +- s32 y; /**< y coordinate (from top) */ +- s32 width; /**< width */ +- s32 height; /**< height */ +-}; +- +-struct mmal_rational { +- s32 num; /**< Numerator */ +- s32 den; /**< Denominator */ +-}; +- +-#endif /* MMAL_MSG_COMMON_H */ +--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-format.h ++++ /dev/null +@@ -1,106 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * Broadcom BM2835 V4L2 driver +- * +- * Copyright © 2013 Raspberry Pi (Trading) Ltd. +- * +- * Authors: Vincent Sanders @ Collabora +- * Dave Stevenson @ Broadcom +- * (now dave.stevenson@raspberrypi.org) +- * Simon Mellor @ Broadcom +- * Luke Diamand @ Broadcom +- */ +- +-#ifndef MMAL_MSG_FORMAT_H +-#define MMAL_MSG_FORMAT_H +- +-#include "mmal-msg-common.h" +- +-/* MMAL_ES_FORMAT_T */ +- +-struct mmal_audio_format { +- u32 channels; /* Number of audio channels */ +- u32 sample_rate; /* Sample rate */ +- +- u32 bits_per_sample; /* Bits per sample */ +- u32 block_align; /* Size of a block of data */ +-}; +- +-struct mmal_video_format { +- u32 width; /* Width of frame in pixels */ +- u32 height; /* Height of frame in rows of pixels */ +- struct mmal_rect crop; /* Visible region of the frame */ +- struct mmal_rational frame_rate; /* Frame rate */ +- struct mmal_rational par; /* Pixel aspect ratio */ +- +- /* +- * FourCC specifying the color space of the video stream. See the +- * MmalColorSpace "pre-defined color spaces" for some examples. +- */ +- u32 color_space; +-}; +- +-struct mmal_subpicture_format { +- u32 x_offset; +- u32 y_offset; +-}; +- +-union mmal_es_specific_format { +- struct mmal_audio_format audio; +- struct mmal_video_format video; +- struct mmal_subpicture_format subpicture; +-}; +- +-/* Definition of an elementary stream format (MMAL_ES_FORMAT_T) */ +-struct mmal_es_format_local { +- u32 type; /* enum mmal_es_type */ +- +- u32 encoding; /* FourCC specifying encoding of the elementary +- * stream. +- */ +- u32 encoding_variant; /* FourCC specifying the specific +- * encoding variant of the elementary +- * stream. +- */ +- +- union mmal_es_specific_format *es; /* Type specific +- * information for the +- * elementary stream +- */ +- +- u32 bitrate; /* Bitrate in bits per second */ +- u32 flags; /* Flags describing properties of the elementary +- * stream. +- */ +- +- u32 extradata_size; /* Size of the codec specific data */ +- u8 *extradata; /* Codec specific data */ +-}; +- +-/* Remote definition of an elementary stream format (MMAL_ES_FORMAT_T) */ +-struct mmal_es_format { +- u32 type; /* enum mmal_es_type */ +- +- u32 encoding; /* FourCC specifying encoding of the elementary +- * stream. +- */ +- u32 encoding_variant; /* FourCC specifying the specific +- * encoding variant of the elementary +- * stream. +- */ +- +- u32 es; /* Type specific +- * information for the +- * elementary stream +- */ +- +- u32 bitrate; /* Bitrate in bits per second */ +- u32 flags; /* Flags describing properties of the elementary +- * stream. +- */ +- +- u32 extradata_size; /* Size of the codec specific data */ +- u32 extradata; /* Codec specific data */ +-}; +- +-#endif /* MMAL_MSG_FORMAT_H */ +--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-port.h ++++ /dev/null +@@ -1,109 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * Broadcom BM2835 V4L2 driver +- * +- * Copyright © 2013 Raspberry Pi (Trading) Ltd. +- * +- * Authors: Vincent Sanders @ Collabora +- * Dave Stevenson @ Broadcom +- * (now dave.stevenson@raspberrypi.org) +- * Simon Mellor @ Broadcom +- * Luke Diamand @ Broadcom +- */ +- +-/* MMAL_PORT_TYPE_T */ +-enum mmal_port_type { +- MMAL_PORT_TYPE_UNKNOWN = 0, /* Unknown port type */ +- MMAL_PORT_TYPE_CONTROL, /* Control port */ +- MMAL_PORT_TYPE_INPUT, /* Input port */ +- MMAL_PORT_TYPE_OUTPUT, /* Output port */ +- MMAL_PORT_TYPE_CLOCK, /* Clock port */ +-}; +- +-/* The port is pass-through and doesn't need buffer headers allocated */ +-#define MMAL_PORT_CAPABILITY_PASSTHROUGH 0x01 +-/* +- *The port wants to allocate the buffer payloads. +- * This signals a preference that payload allocation should be done +- * on this port for efficiency reasons. +- */ +-#define MMAL_PORT_CAPABILITY_ALLOCATION 0x02 +-/* +- * The port supports format change events. +- * This applies to input ports and is used to let the client know +- * whether the port supports being reconfigured via a format +- * change event (i.e. without having to disable the port). +- */ +-#define MMAL_PORT_CAPABILITY_SUPPORTS_EVENT_FORMAT_CHANGE 0x04 +- +-/* +- * mmal port structure (MMAL_PORT_T) +- * +- * most elements are informational only, the pointer values for +- * interogation messages are generally provided as additional +- * structures within the message. When used to set values only the +- * buffer_num, buffer_size and userdata parameters are writable. +- */ +-struct mmal_port { +- u32 priv; /* Private member used by the framework */ +- u32 name; /* Port name. Used for debugging purposes (RO) */ +- +- u32 type; /* Type of the port (RO) enum mmal_port_type */ +- u16 index; /* Index of the port in its type list (RO) */ +- u16 index_all; /* Index of the port in the list of all ports (RO) */ +- +- u32 is_enabled; /* Indicates whether the port is enabled or not (RO) */ +- u32 format; /* Format of the elementary stream */ +- +- u32 buffer_num_min; /* Minimum number of buffers the port +- * requires (RO). This is set by the +- * component. +- */ +- +- u32 buffer_size_min; /* Minimum size of buffers the port +- * requires (RO). This is set by the +- * component. +- */ +- +- u32 buffer_alignment_min;/* Minimum alignment requirement for +- * the buffers (RO). A value of +- * zero means no special alignment +- * requirements. This is set by the +- * component. +- */ +- +- u32 buffer_num_recommended; /* Number of buffers the port +- * recommends for optimal +- * performance (RO). A value of +- * zero means no special +- * recommendation. This is set +- * by the component. +- */ +- +- u32 buffer_size_recommended; /* Size of buffers the port +- * recommends for optimal +- * performance (RO). A value of +- * zero means no special +- * recommendation. This is set +- * by the component. +- */ +- +- u32 buffer_num; /* Actual number of buffers the port will use. +- * This is set by the client. +- */ +- +- u32 buffer_size; /* Actual maximum size of the buffers that +- * will be sent to the port. This is set by +- * the client. +- */ +- +- u32 component; /* Component this port belongs to (Read Only) */ +- +- u32 userdata; /* Field reserved for use by the client */ +- +- u32 capabilities; /* Flags describing the capabilities of a +- * port (RO). Bitwise combination of \ref +- * portcapabilities "Port capabilities" +- * values. +- */ +-}; +--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg.h ++++ /dev/null +@@ -1,406 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * Broadcom BM2835 V4L2 driver +- * +- * Copyright © 2013 Raspberry Pi (Trading) Ltd. +- * +- * Authors: Vincent Sanders @ Collabora +- * Dave Stevenson @ Broadcom +- * (now dave.stevenson@raspberrypi.org) +- * Simon Mellor @ Broadcom +- * Luke Diamand @ Broadcom +- */ +- +-/* +- * all the data structures which serialise the MMAL protocol. note +- * these are directly mapped onto the recived message data. +- * +- * BEWARE: They seem to *assume* pointers are u32 and that there is no +- * structure padding! +- * +- * NOTE: this implementation uses kernel types to ensure sizes. Rather +- * than assigning values to enums to force their size the +- * implementation uses fixed size types and not the enums (though the +- * comments have the actual enum type +- */ +-#ifndef MMAL_MSG_H +-#define MMAL_MSG_H +- +-#define VC_MMAL_VER 15 +-#define VC_MMAL_MIN_VER 10 +-#define VC_MMAL_SERVER_NAME MAKE_FOURCC("mmal") +- +-/* max total message size is 512 bytes */ +-#define MMAL_MSG_MAX_SIZE 512 +-/* with six 32bit header elements max payload is therefore 488 bytes */ +-#define MMAL_MSG_MAX_PAYLOAD 488 +- +-#include "mmal-msg-common.h" +-#include "mmal-msg-format.h" +-#include "mmal-msg-port.h" +- +-enum mmal_msg_type { +- MMAL_MSG_TYPE_QUIT = 1, +- MMAL_MSG_TYPE_SERVICE_CLOSED, +- MMAL_MSG_TYPE_GET_VERSION, +- MMAL_MSG_TYPE_COMPONENT_CREATE, +- MMAL_MSG_TYPE_COMPONENT_DESTROY, /* 5 */ +- MMAL_MSG_TYPE_COMPONENT_ENABLE, +- MMAL_MSG_TYPE_COMPONENT_DISABLE, +- MMAL_MSG_TYPE_PORT_INFO_GET, +- MMAL_MSG_TYPE_PORT_INFO_SET, +- MMAL_MSG_TYPE_PORT_ACTION, /* 10 */ +- MMAL_MSG_TYPE_BUFFER_FROM_HOST, +- MMAL_MSG_TYPE_BUFFER_TO_HOST, +- MMAL_MSG_TYPE_GET_STATS, +- MMAL_MSG_TYPE_PORT_PARAMETER_SET, +- MMAL_MSG_TYPE_PORT_PARAMETER_GET, /* 15 */ +- MMAL_MSG_TYPE_EVENT_TO_HOST, +- MMAL_MSG_TYPE_GET_CORE_STATS_FOR_PORT, +- MMAL_MSG_TYPE_OPAQUE_ALLOCATOR, +- MMAL_MSG_TYPE_CONSUME_MEM, +- MMAL_MSG_TYPE_LMK, /* 20 */ +- MMAL_MSG_TYPE_OPAQUE_ALLOCATOR_DESC, +- MMAL_MSG_TYPE_DRM_GET_LHS32, +- MMAL_MSG_TYPE_DRM_GET_TIME, +- MMAL_MSG_TYPE_BUFFER_FROM_HOST_ZEROLEN, +- MMAL_MSG_TYPE_PORT_FLUSH, /* 25 */ +- MMAL_MSG_TYPE_HOST_LOG, +- MMAL_MSG_TYPE_MSG_LAST +-}; +- +-/* port action request messages differ depending on the action type */ +-enum mmal_msg_port_action_type { +- MMAL_MSG_PORT_ACTION_TYPE_UNKNOWN = 0, /* Unknown action */ +- MMAL_MSG_PORT_ACTION_TYPE_ENABLE, /* Enable a port */ +- MMAL_MSG_PORT_ACTION_TYPE_DISABLE, /* Disable a port */ +- MMAL_MSG_PORT_ACTION_TYPE_FLUSH, /* Flush a port */ +- MMAL_MSG_PORT_ACTION_TYPE_CONNECT, /* Connect ports */ +- MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT, /* Disconnect ports */ +- MMAL_MSG_PORT_ACTION_TYPE_SET_REQUIREMENTS, /* Set buffer requirements*/ +-}; +- +-struct mmal_msg_header { +- u32 magic; +- u32 type; /* enum mmal_msg_type */ +- +- /* Opaque handle to the control service */ +- u32 control_service; +- +- u32 context; /* a u32 per message context */ +- u32 status; /* The status of the vchiq operation */ +- u32 padding; +-}; +- +-/* Send from VC to host to report version */ +-struct mmal_msg_version { +- u32 flags; +- u32 major; +- u32 minor; +- u32 minimum; +-}; +- +-/* request to VC to create component */ +-struct mmal_msg_component_create { +- u32 client_component; /* component context */ +- char name[128]; +- u32 pid; /* For debug */ +-}; +- +-/* reply from VC to component creation request */ +-struct mmal_msg_component_create_reply { +- u32 status; /* enum mmal_msg_status - how does this differ to +- * the one in the header? +- */ +- u32 component_handle; /* VideoCore handle for component */ +- u32 input_num; /* Number of input ports */ +- u32 output_num; /* Number of output ports */ +- u32 clock_num; /* Number of clock ports */ +-}; +- +-/* request to VC to destroy a component */ +-struct mmal_msg_component_destroy { +- u32 component_handle; +-}; +- +-struct mmal_msg_component_destroy_reply { +- u32 status; /* The component destruction status */ +-}; +- +-/* request and reply to VC to enable a component */ +-struct mmal_msg_component_enable { +- u32 component_handle; +-}; +- +-struct mmal_msg_component_enable_reply { +- u32 status; /* The component enable status */ +-}; +- +-/* request and reply to VC to disable a component */ +-struct mmal_msg_component_disable { +- u32 component_handle; +-}; +- +-struct mmal_msg_component_disable_reply { +- u32 status; /* The component disable status */ +-}; +- +-/* request to VC to get port information */ +-struct mmal_msg_port_info_get { +- u32 component_handle; /* component handle port is associated with */ +- u32 port_type; /* enum mmal_msg_port_type */ +- u32 index; /* port index to query */ +-}; +- +-/* reply from VC to get port info request */ +-struct mmal_msg_port_info_get_reply { +- u32 status; /* enum mmal_msg_status */ +- u32 component_handle; /* component handle port is associated with */ +- u32 port_type; /* enum mmal_msg_port_type */ +- u32 port_index; /* port indexed in query */ +- s32 found; /* unused */ +- u32 port_handle; /* Handle to use for this port */ +- struct mmal_port port; +- struct mmal_es_format format; /* elementary stream format */ +- union mmal_es_specific_format es; /* es type specific data */ +- u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; /* es extra data */ +-}; +- +-/* request to VC to set port information */ +-struct mmal_msg_port_info_set { +- u32 component_handle; +- u32 port_type; /* enum mmal_msg_port_type */ +- u32 port_index; /* port indexed in query */ +- struct mmal_port port; +- struct mmal_es_format format; +- union mmal_es_specific_format es; +- u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; +-}; +- +-/* reply from VC to port info set request */ +-struct mmal_msg_port_info_set_reply { +- u32 status; +- u32 component_handle; /* component handle port is associated with */ +- u32 port_type; /* enum mmal_msg_port_type */ +- u32 index; /* port indexed in query */ +- s32 found; /* unused */ +- u32 port_handle; /* Handle to use for this port */ +- struct mmal_port port; +- struct mmal_es_format format; +- union mmal_es_specific_format es; +- u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; +-}; +- +-/* port action requests that take a mmal_port as a parameter */ +-struct mmal_msg_port_action_port { +- u32 component_handle; +- u32 port_handle; +- u32 action; /* enum mmal_msg_port_action_type */ +- struct mmal_port port; +-}; +- +-/* port action requests that take handles as a parameter */ +-struct mmal_msg_port_action_handle { +- u32 component_handle; +- u32 port_handle; +- u32 action; /* enum mmal_msg_port_action_type */ +- u32 connect_component_handle; +- u32 connect_port_handle; +-}; +- +-struct mmal_msg_port_action_reply { +- u32 status; /* The port action operation status */ +-}; +- +-/* MMAL buffer transfer */ +- +-/* Size of space reserved in a buffer message for short messages. */ +-#define MMAL_VC_SHORT_DATA 128 +- +-/* Signals that the current payload is the end of the stream of data */ +-#define MMAL_BUFFER_HEADER_FLAG_EOS BIT(0) +-/* Signals that the start of the current payload starts a frame */ +-#define MMAL_BUFFER_HEADER_FLAG_FRAME_START BIT(1) +-/* Signals that the end of the current payload ends a frame */ +-#define MMAL_BUFFER_HEADER_FLAG_FRAME_END BIT(2) +-/* Signals that the current payload contains only complete frames (>1) */ +-#define MMAL_BUFFER_HEADER_FLAG_FRAME \ +- (MMAL_BUFFER_HEADER_FLAG_FRAME_START | \ +- MMAL_BUFFER_HEADER_FLAG_FRAME_END) +-/* Signals that the current payload is a keyframe (i.e. self decodable) */ +-#define MMAL_BUFFER_HEADER_FLAG_KEYFRAME BIT(3) +-/* +- * Signals a discontinuity in the stream of data (e.g. after a seek). +- * Can be used for instance by a decoder to reset its state +- */ +-#define MMAL_BUFFER_HEADER_FLAG_DISCONTINUITY BIT(4) +-/* +- * Signals a buffer containing some kind of config data for the component +- * (e.g. codec config data) +- */ +-#define MMAL_BUFFER_HEADER_FLAG_CONFIG BIT(5) +-/* Signals an encrypted payload */ +-#define MMAL_BUFFER_HEADER_FLAG_ENCRYPTED BIT(6) +-/* Signals a buffer containing side information */ +-#define MMAL_BUFFER_HEADER_FLAG_CODECSIDEINFO BIT(7) +-/* +- * Signals a buffer which is the snapshot/postview image from a stills +- * capture +- */ +-#define MMAL_BUFFER_HEADER_FLAGS_SNAPSHOT BIT(8) +-/* Signals a buffer which contains data known to be corrupted */ +-#define MMAL_BUFFER_HEADER_FLAG_CORRUPTED BIT(9) +-/* Signals that a buffer failed to be transmitted */ +-#define MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED BIT(10) +- +-struct mmal_driver_buffer { +- u32 magic; +- u32 component_handle; +- u32 port_handle; +- u32 client_context; +-}; +- +-/* buffer header */ +-struct mmal_buffer_header { +- u32 next; /* next header */ +- u32 priv; /* framework private data */ +- u32 cmd; +- u32 data; +- u32 alloc_size; +- u32 length; +- u32 offset; +- u32 flags; +- s64 pts; +- s64 dts; +- u32 type; +- u32 user_data; +-}; +- +-struct mmal_buffer_header_type_specific { +- union { +- struct { +- u32 planes; +- u32 offset[4]; +- u32 pitch[4]; +- u32 flags; +- } video; +- } u; +-}; +- +-struct mmal_msg_buffer_from_host { +- /* +- *The front 32 bytes of the buffer header are copied +- * back to us in the reply to allow for context. This +- * area is used to store two mmal_driver_buffer structures to +- * allow for multiple concurrent service users. +- */ +- /* control data */ +- struct mmal_driver_buffer drvbuf; +- +- /* referenced control data for passthrough buffer management */ +- struct mmal_driver_buffer drvbuf_ref; +- struct mmal_buffer_header buffer_header; /* buffer header itself */ +- struct mmal_buffer_header_type_specific buffer_header_type_specific; +- s32 is_zero_copy; +- s32 has_reference; +- +- /* allows short data to be xfered in control message */ +- u32 payload_in_message; +- u8 short_data[MMAL_VC_SHORT_DATA]; +-}; +- +-/* port parameter setting */ +- +-#define MMAL_WORKER_PORT_PARAMETER_SPACE 96 +- +-struct mmal_msg_port_parameter_set { +- u32 component_handle; /* component */ +- u32 port_handle; /* port */ +- u32 id; /* Parameter ID */ +- u32 size; /* Parameter size */ +- uint32_t value[MMAL_WORKER_PORT_PARAMETER_SPACE]; +-}; +- +-struct mmal_msg_port_parameter_set_reply { +- u32 status; /* enum mmal_msg_status todo: how does this +- * differ to the one in the header? +- */ +-}; +- +-/* port parameter getting */ +- +-struct mmal_msg_port_parameter_get { +- u32 component_handle; /* component */ +- u32 port_handle; /* port */ +- u32 id; /* Parameter ID */ +- u32 size; /* Parameter size */ +-}; +- +-struct mmal_msg_port_parameter_get_reply { +- u32 status; /* Status of mmal_port_parameter_get call */ +- u32 id; /* Parameter ID */ +- u32 size; /* Parameter size */ +- uint32_t value[MMAL_WORKER_PORT_PARAMETER_SPACE]; +-}; +- +-/* event messages */ +-#define MMAL_WORKER_EVENT_SPACE 256 +- +-struct mmal_msg_event_to_host { +- u32 client_component; /* component context */ +- +- u32 port_type; +- u32 port_num; +- +- u32 cmd; +- u32 length; +- u8 data[MMAL_WORKER_EVENT_SPACE]; +- u32 delayed_buffer; +-}; +- +-/* all mmal messages are serialised through this structure */ +-struct mmal_msg { +- /* header */ +- struct mmal_msg_header h; +- /* payload */ +- union { +- struct mmal_msg_version version; +- +- struct mmal_msg_component_create component_create; +- struct mmal_msg_component_create_reply component_create_reply; +- +- struct mmal_msg_component_destroy component_destroy; +- struct mmal_msg_component_destroy_reply component_destroy_reply; +- +- struct mmal_msg_component_enable component_enable; +- struct mmal_msg_component_enable_reply component_enable_reply; +- +- struct mmal_msg_component_disable component_disable; +- struct mmal_msg_component_disable_reply component_disable_reply; +- +- struct mmal_msg_port_info_get port_info_get; +- struct mmal_msg_port_info_get_reply port_info_get_reply; +- +- struct mmal_msg_port_info_set port_info_set; +- struct mmal_msg_port_info_set_reply port_info_set_reply; +- +- struct mmal_msg_port_action_port port_action_port; +- struct mmal_msg_port_action_handle port_action_handle; +- struct mmal_msg_port_action_reply port_action_reply; +- +- struct mmal_msg_buffer_from_host buffer_from_host; +- +- struct mmal_msg_port_parameter_set port_parameter_set; +- struct mmal_msg_port_parameter_set_reply +- port_parameter_set_reply; +- struct mmal_msg_port_parameter_get +- port_parameter_get; +- struct mmal_msg_port_parameter_get_reply +- port_parameter_get_reply; +- +- struct mmal_msg_event_to_host event_to_host; +- +- u8 payload[MMAL_MSG_MAX_PAYLOAD]; +- } u; +-}; +-#endif +--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h ++++ /dev/null +@@ -1,755 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * Broadcom BM2835 V4L2 driver +- * +- * Copyright © 2013 Raspberry Pi (Trading) Ltd. +- * +- * Authors: Vincent Sanders @ Collabora +- * Dave Stevenson @ Broadcom +- * (now dave.stevenson@raspberrypi.org) +- * Simon Mellor @ Broadcom +- * Luke Diamand @ Broadcom +- */ +- +-/* common parameters */ +- +-/** @name Parameter groups +- * Parameters are divided into groups, and then allocated sequentially within +- * a group using an enum. +- * @{ +- */ +- +-#ifndef MMAL_PARAMETERS_H +-#define MMAL_PARAMETERS_H +- +-/** Common parameter ID group, used with many types of component. */ +-#define MMAL_PARAMETER_GROUP_COMMON (0 << 16) +-/** Camera-specific parameter ID group. */ +-#define MMAL_PARAMETER_GROUP_CAMERA (1 << 16) +-/** Video-specific parameter ID group. */ +-#define MMAL_PARAMETER_GROUP_VIDEO (2 << 16) +-/** Audio-specific parameter ID group. */ +-#define MMAL_PARAMETER_GROUP_AUDIO (3 << 16) +-/** Clock-specific parameter ID group. */ +-#define MMAL_PARAMETER_GROUP_CLOCK (4 << 16) +-/** Miracast-specific parameter ID group. */ +-#define MMAL_PARAMETER_GROUP_MIRACAST (5 << 16) +- +-/* Common parameters */ +-enum mmal_parameter_common_type { +- /**< Never a valid parameter ID */ +- MMAL_PARAMETER_UNUSED = MMAL_PARAMETER_GROUP_COMMON, +- +- /**< MMAL_PARAMETER_ENCODING_T */ +- MMAL_PARAMETER_SUPPORTED_ENCODINGS, +- /**< MMAL_PARAMETER_URI_T */ +- MMAL_PARAMETER_URI, +- /** MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T */ +- MMAL_PARAMETER_CHANGE_EVENT_REQUEST, +- /** MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_ZERO_COPY, +- /**< MMAL_PARAMETER_BUFFER_REQUIREMENTS_T */ +- MMAL_PARAMETER_BUFFER_REQUIREMENTS, +- /**< MMAL_PARAMETER_STATISTICS_T */ +- MMAL_PARAMETER_STATISTICS, +- /**< MMAL_PARAMETER_CORE_STATISTICS_T */ +- MMAL_PARAMETER_CORE_STATISTICS, +- /**< MMAL_PARAMETER_MEM_USAGE_T */ +- MMAL_PARAMETER_MEM_USAGE, +- /**< MMAL_PARAMETER_UINT32_T */ +- MMAL_PARAMETER_BUFFER_FLAG_FILTER, +- /**< MMAL_PARAMETER_SEEK_T */ +- MMAL_PARAMETER_SEEK, +- /**< MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_POWERMON_ENABLE, +- /**< MMAL_PARAMETER_LOGGING_T */ +- MMAL_PARAMETER_LOGGING, +- /**< MMAL_PARAMETER_UINT64_T */ +- MMAL_PARAMETER_SYSTEM_TIME, +- /**< MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_NO_IMAGE_PADDING, +-}; +- +-/* camera parameters */ +- +-enum mmal_parameter_camera_type { +- /* 0 */ +- /** @ref MMAL_PARAMETER_THUMBNAIL_CONFIG_T */ +- MMAL_PARAMETER_THUMBNAIL_CONFIGURATION = +- MMAL_PARAMETER_GROUP_CAMERA, +- /**< Unused? */ +- MMAL_PARAMETER_CAPTURE_QUALITY, +- /**< @ref MMAL_PARAMETER_INT32_T */ +- MMAL_PARAMETER_ROTATION, +- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_EXIF_DISABLE, +- /**< @ref MMAL_PARAMETER_EXIF_T */ +- MMAL_PARAMETER_EXIF, +- /**< @ref MMAL_PARAM_AWBMODE_T */ +- MMAL_PARAMETER_AWB_MODE, +- /**< @ref MMAL_PARAMETER_IMAGEFX_T */ +- MMAL_PARAMETER_IMAGE_EFFECT, +- /**< @ref MMAL_PARAMETER_COLOURFX_T */ +- MMAL_PARAMETER_COLOUR_EFFECT, +- /**< @ref MMAL_PARAMETER_FLICKERAVOID_T */ +- MMAL_PARAMETER_FLICKER_AVOID, +- /**< @ref MMAL_PARAMETER_FLASH_T */ +- MMAL_PARAMETER_FLASH, +- /**< @ref MMAL_PARAMETER_REDEYE_T */ +- MMAL_PARAMETER_REDEYE, +- /**< @ref MMAL_PARAMETER_FOCUS_T */ +- MMAL_PARAMETER_FOCUS, +- /**< Unused? */ +- MMAL_PARAMETER_FOCAL_LENGTHS, +- /**< @ref MMAL_PARAMETER_INT32_T */ +- MMAL_PARAMETER_EXPOSURE_COMP, +- /**< @ref MMAL_PARAMETER_SCALEFACTOR_T */ +- MMAL_PARAMETER_ZOOM, +- /**< @ref MMAL_PARAMETER_MIRROR_T */ +- MMAL_PARAMETER_MIRROR, +- +- /* 0x10 */ +- /**< @ref MMAL_PARAMETER_UINT32_T */ +- MMAL_PARAMETER_CAMERA_NUM, +- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_CAPTURE, +- /**< @ref MMAL_PARAMETER_EXPOSUREMODE_T */ +- MMAL_PARAMETER_EXPOSURE_MODE, +- /**< @ref MMAL_PARAMETER_EXPOSUREMETERINGMODE_T */ +- MMAL_PARAMETER_EXP_METERING_MODE, +- /**< @ref MMAL_PARAMETER_FOCUS_STATUS_T */ +- MMAL_PARAMETER_FOCUS_STATUS, +- /**< @ref MMAL_PARAMETER_CAMERA_CONFIG_T */ +- MMAL_PARAMETER_CAMERA_CONFIG, +- /**< @ref MMAL_PARAMETER_CAPTURE_STATUS_T */ +- MMAL_PARAMETER_CAPTURE_STATUS, +- /**< @ref MMAL_PARAMETER_FACE_TRACK_T */ +- MMAL_PARAMETER_FACE_TRACK, +- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_DRAW_BOX_FACES_AND_FOCUS, +- /**< @ref MMAL_PARAMETER_UINT32_T */ +- MMAL_PARAMETER_JPEG_Q_FACTOR, +- /**< @ref MMAL_PARAMETER_FRAME_RATE_T */ +- MMAL_PARAMETER_FRAME_RATE, +- /**< @ref MMAL_PARAMETER_CAMERA_STC_MODE_T */ +- MMAL_PARAMETER_USE_STC, +- /**< @ref MMAL_PARAMETER_CAMERA_INFO_T */ +- MMAL_PARAMETER_CAMERA_INFO, +- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_VIDEO_STABILISATION, +- /**< @ref MMAL_PARAMETER_FACE_TRACK_RESULTS_T */ +- MMAL_PARAMETER_FACE_TRACK_RESULTS, +- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_ENABLE_RAW_CAPTURE, +- +- /* 0x20 */ +- /**< @ref MMAL_PARAMETER_URI_T */ +- MMAL_PARAMETER_DPF_FILE, +- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_ENABLE_DPF_FILE, +- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_DPF_FAIL_IS_FATAL, +- /**< @ref MMAL_PARAMETER_CAPTUREMODE_T */ +- MMAL_PARAMETER_CAPTURE_MODE, +- /**< @ref MMAL_PARAMETER_FOCUS_REGIONS_T */ +- MMAL_PARAMETER_FOCUS_REGIONS, +- /**< @ref MMAL_PARAMETER_INPUT_CROP_T */ +- MMAL_PARAMETER_INPUT_CROP, +- /**< @ref MMAL_PARAMETER_SENSOR_INFORMATION_T */ +- MMAL_PARAMETER_SENSOR_INFORMATION, +- /**< @ref MMAL_PARAMETER_FLASH_SELECT_T */ +- MMAL_PARAMETER_FLASH_SELECT, +- /**< @ref MMAL_PARAMETER_FIELD_OF_VIEW_T */ +- MMAL_PARAMETER_FIELD_OF_VIEW, +- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_HIGH_DYNAMIC_RANGE, +- /**< @ref MMAL_PARAMETER_DRC_T */ +- MMAL_PARAMETER_DYNAMIC_RANGE_COMPRESSION, +- /**< @ref MMAL_PARAMETER_ALGORITHM_CONTROL_T */ +- MMAL_PARAMETER_ALGORITHM_CONTROL, +- /**< @ref MMAL_PARAMETER_RATIONAL_T */ +- MMAL_PARAMETER_SHARPNESS, +- /**< @ref MMAL_PARAMETER_RATIONAL_T */ +- MMAL_PARAMETER_CONTRAST, +- /**< @ref MMAL_PARAMETER_RATIONAL_T */ +- MMAL_PARAMETER_BRIGHTNESS, +- /**< @ref MMAL_PARAMETER_RATIONAL_T */ +- MMAL_PARAMETER_SATURATION, +- +- /* 0x30 */ +- /**< @ref MMAL_PARAMETER_UINT32_T */ +- MMAL_PARAMETER_ISO, +- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_ANTISHAKE, +- /** @ref MMAL_PARAMETER_IMAGEFX_PARAMETERS_T */ +- MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, +- /** @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_CAMERA_BURST_CAPTURE, +- /** @ref MMAL_PARAMETER_UINT32_T */ +- MMAL_PARAMETER_CAMERA_MIN_ISO, +- /** @ref MMAL_PARAMETER_CAMERA_USE_CASE_T */ +- MMAL_PARAMETER_CAMERA_USE_CASE, +- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_CAPTURE_STATS_PASS, +- /** @ref MMAL_PARAMETER_UINT32_T */ +- MMAL_PARAMETER_CAMERA_CUSTOM_SENSOR_CONFIG, +- /** @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_ENABLE_REGISTER_FILE, +- /** @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_REGISTER_FAIL_IS_FATAL, +- /** @ref MMAL_PARAMETER_CONFIGFILE_T */ +- MMAL_PARAMETER_CONFIGFILE_REGISTERS, +- /** @ref MMAL_PARAMETER_CONFIGFILE_CHUNK_T */ +- MMAL_PARAMETER_CONFIGFILE_CHUNK_REGISTERS, +- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_JPEG_ATTACH_LOG, +- /**< @ref MMAL_PARAMETER_ZEROSHUTTERLAG_T */ +- MMAL_PARAMETER_ZERO_SHUTTER_LAG, +- /**< @ref MMAL_PARAMETER_FPS_RANGE_T */ +- MMAL_PARAMETER_FPS_RANGE, +- /**< @ref MMAL_PARAMETER_INT32_T */ +- MMAL_PARAMETER_CAPTURE_EXPOSURE_COMP, +- +- /* 0x40 */ +- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_SW_SHARPEN_DISABLE, +- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_FLASH_REQUIRED, +- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_SW_SATURATION_DISABLE, +- /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ +- MMAL_PARAMETER_SHUTTER_SPEED, +- /**< Takes a @ref MMAL_PARAMETER_AWB_GAINS_T */ +- MMAL_PARAMETER_CUSTOM_AWB_GAINS, +-}; +- +-struct mmal_parameter_rational { +- s32 num; /**< Numerator */ +- s32 den; /**< Denominator */ +-}; +- +-enum mmal_parameter_camera_config_timestamp_mode { +- MMAL_PARAM_TIMESTAMP_MODE_ZERO = 0, /* Always timestamp frames as 0 */ +- MMAL_PARAM_TIMESTAMP_MODE_RAW_STC, /* Use the raw STC value +- * for the frame timestamp +- */ +- MMAL_PARAM_TIMESTAMP_MODE_RESET_STC, /* Use the STC timestamp +- * but subtract the +- * timestamp of the first +- * frame sent to give a +- * zero based timestamp. +- */ +-}; +- +-struct mmal_parameter_fps_range { +- /**< Low end of the permitted framerate range */ +- struct mmal_parameter_rational fps_low; +- /**< High end of the permitted framerate range */ +- struct mmal_parameter_rational fps_high; +-}; +- +-/* camera configuration parameter */ +-struct mmal_parameter_camera_config { +- /* Parameters for setting up the image pools */ +- u32 max_stills_w; /* Max size of stills capture */ +- u32 max_stills_h; +- u32 stills_yuv422; /* Allow YUV422 stills capture */ +- u32 one_shot_stills; /* Continuous or one shot stills captures. */ +- +- u32 max_preview_video_w; /* Max size of the preview or video +- * capture frames +- */ +- u32 max_preview_video_h; +- u32 num_preview_video_frames; +- +- /** Sets the height of the circular buffer for stills capture. */ +- u32 stills_capture_circular_buffer_height; +- +- /** Allows preview/encode to resume as fast as possible after the stills +- * input frame has been received, and then processes the still frame in +- * the background whilst preview/encode has resumed. +- * Actual mode is controlled by MMAL_PARAMETER_CAPTURE_MODE. +- */ +- u32 fast_preview_resume; +- +- /** Selects algorithm for timestamping frames if +- * there is no clock component connected. +- * enum mmal_parameter_camera_config_timestamp_mode +- */ +- s32 use_stc_timestamp; +-}; +- +-enum mmal_parameter_exposuremode { +- MMAL_PARAM_EXPOSUREMODE_OFF, +- MMAL_PARAM_EXPOSUREMODE_AUTO, +- MMAL_PARAM_EXPOSUREMODE_NIGHT, +- MMAL_PARAM_EXPOSUREMODE_NIGHTPREVIEW, +- MMAL_PARAM_EXPOSUREMODE_BACKLIGHT, +- MMAL_PARAM_EXPOSUREMODE_SPOTLIGHT, +- MMAL_PARAM_EXPOSUREMODE_SPORTS, +- MMAL_PARAM_EXPOSUREMODE_SNOW, +- MMAL_PARAM_EXPOSUREMODE_BEACH, +- MMAL_PARAM_EXPOSUREMODE_VERYLONG, +- MMAL_PARAM_EXPOSUREMODE_FIXEDFPS, +- MMAL_PARAM_EXPOSUREMODE_ANTISHAKE, +- MMAL_PARAM_EXPOSUREMODE_FIREWORKS, +-}; +- +-enum mmal_parameter_exposuremeteringmode { +- MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE, +- MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT, +- MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT, +- MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX, +-}; +- +-enum mmal_parameter_awbmode { +- MMAL_PARAM_AWBMODE_OFF, +- MMAL_PARAM_AWBMODE_AUTO, +- MMAL_PARAM_AWBMODE_SUNLIGHT, +- MMAL_PARAM_AWBMODE_CLOUDY, +- MMAL_PARAM_AWBMODE_SHADE, +- MMAL_PARAM_AWBMODE_TUNGSTEN, +- MMAL_PARAM_AWBMODE_FLUORESCENT, +- MMAL_PARAM_AWBMODE_INCANDESCENT, +- MMAL_PARAM_AWBMODE_FLASH, +- MMAL_PARAM_AWBMODE_HORIZON, +-}; +- +-enum mmal_parameter_imagefx { +- MMAL_PARAM_IMAGEFX_NONE, +- MMAL_PARAM_IMAGEFX_NEGATIVE, +- MMAL_PARAM_IMAGEFX_SOLARIZE, +- MMAL_PARAM_IMAGEFX_POSTERIZE, +- MMAL_PARAM_IMAGEFX_WHITEBOARD, +- MMAL_PARAM_IMAGEFX_BLACKBOARD, +- MMAL_PARAM_IMAGEFX_SKETCH, +- MMAL_PARAM_IMAGEFX_DENOISE, +- MMAL_PARAM_IMAGEFX_EMBOSS, +- MMAL_PARAM_IMAGEFX_OILPAINT, +- MMAL_PARAM_IMAGEFX_HATCH, +- MMAL_PARAM_IMAGEFX_GPEN, +- MMAL_PARAM_IMAGEFX_PASTEL, +- MMAL_PARAM_IMAGEFX_WATERCOLOUR, +- MMAL_PARAM_IMAGEFX_FILM, +- MMAL_PARAM_IMAGEFX_BLUR, +- MMAL_PARAM_IMAGEFX_SATURATION, +- MMAL_PARAM_IMAGEFX_COLOURSWAP, +- MMAL_PARAM_IMAGEFX_WASHEDOUT, +- MMAL_PARAM_IMAGEFX_POSTERISE, +- MMAL_PARAM_IMAGEFX_COLOURPOINT, +- MMAL_PARAM_IMAGEFX_COLOURBALANCE, +- MMAL_PARAM_IMAGEFX_CARTOON, +-}; +- +-enum MMAL_PARAM_FLICKERAVOID_T { +- MMAL_PARAM_FLICKERAVOID_OFF, +- MMAL_PARAM_FLICKERAVOID_AUTO, +- MMAL_PARAM_FLICKERAVOID_50HZ, +- MMAL_PARAM_FLICKERAVOID_60HZ, +- MMAL_PARAM_FLICKERAVOID_MAX = 0x7FFFFFFF +-}; +- +-struct mmal_parameter_awbgains { +- struct mmal_parameter_rational r_gain; /**< Red gain */ +- struct mmal_parameter_rational b_gain; /**< Blue gain */ +-}; +- +-/** Manner of video rate control */ +-enum mmal_parameter_rate_control_mode { +- MMAL_VIDEO_RATECONTROL_DEFAULT, +- MMAL_VIDEO_RATECONTROL_VARIABLE, +- MMAL_VIDEO_RATECONTROL_CONSTANT, +- MMAL_VIDEO_RATECONTROL_VARIABLE_SKIP_FRAMES, +- MMAL_VIDEO_RATECONTROL_CONSTANT_SKIP_FRAMES +-}; +- +-enum mmal_video_profile { +- MMAL_VIDEO_PROFILE_H263_BASELINE, +- MMAL_VIDEO_PROFILE_H263_H320CODING, +- MMAL_VIDEO_PROFILE_H263_BACKWARDCOMPATIBLE, +- MMAL_VIDEO_PROFILE_H263_ISWV2, +- MMAL_VIDEO_PROFILE_H263_ISWV3, +- MMAL_VIDEO_PROFILE_H263_HIGHCOMPRESSION, +- MMAL_VIDEO_PROFILE_H263_INTERNET, +- MMAL_VIDEO_PROFILE_H263_INTERLACE, +- MMAL_VIDEO_PROFILE_H263_HIGHLATENCY, +- MMAL_VIDEO_PROFILE_MP4V_SIMPLE, +- MMAL_VIDEO_PROFILE_MP4V_SIMPLESCALABLE, +- MMAL_VIDEO_PROFILE_MP4V_CORE, +- MMAL_VIDEO_PROFILE_MP4V_MAIN, +- MMAL_VIDEO_PROFILE_MP4V_NBIT, +- MMAL_VIDEO_PROFILE_MP4V_SCALABLETEXTURE, +- MMAL_VIDEO_PROFILE_MP4V_SIMPLEFACE, +- MMAL_VIDEO_PROFILE_MP4V_SIMPLEFBA, +- MMAL_VIDEO_PROFILE_MP4V_BASICANIMATED, +- MMAL_VIDEO_PROFILE_MP4V_HYBRID, +- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDREALTIME, +- MMAL_VIDEO_PROFILE_MP4V_CORESCALABLE, +- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCODING, +- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCORE, +- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSCALABLE, +- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSIMPLE, +- MMAL_VIDEO_PROFILE_H264_BASELINE, +- MMAL_VIDEO_PROFILE_H264_MAIN, +- MMAL_VIDEO_PROFILE_H264_EXTENDED, +- MMAL_VIDEO_PROFILE_H264_HIGH, +- MMAL_VIDEO_PROFILE_H264_HIGH10, +- MMAL_VIDEO_PROFILE_H264_HIGH422, +- MMAL_VIDEO_PROFILE_H264_HIGH444, +- MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE, +- MMAL_VIDEO_PROFILE_DUMMY = 0x7FFFFFFF +-}; +- +-enum mmal_video_level { +- MMAL_VIDEO_LEVEL_H263_10, +- MMAL_VIDEO_LEVEL_H263_20, +- MMAL_VIDEO_LEVEL_H263_30, +- MMAL_VIDEO_LEVEL_H263_40, +- MMAL_VIDEO_LEVEL_H263_45, +- MMAL_VIDEO_LEVEL_H263_50, +- MMAL_VIDEO_LEVEL_H263_60, +- MMAL_VIDEO_LEVEL_H263_70, +- MMAL_VIDEO_LEVEL_MP4V_0, +- MMAL_VIDEO_LEVEL_MP4V_0b, +- MMAL_VIDEO_LEVEL_MP4V_1, +- MMAL_VIDEO_LEVEL_MP4V_2, +- MMAL_VIDEO_LEVEL_MP4V_3, +- MMAL_VIDEO_LEVEL_MP4V_4, +- MMAL_VIDEO_LEVEL_MP4V_4a, +- MMAL_VIDEO_LEVEL_MP4V_5, +- MMAL_VIDEO_LEVEL_MP4V_6, +- MMAL_VIDEO_LEVEL_H264_1, +- MMAL_VIDEO_LEVEL_H264_1b, +- MMAL_VIDEO_LEVEL_H264_11, +- MMAL_VIDEO_LEVEL_H264_12, +- MMAL_VIDEO_LEVEL_H264_13, +- MMAL_VIDEO_LEVEL_H264_2, +- MMAL_VIDEO_LEVEL_H264_21, +- MMAL_VIDEO_LEVEL_H264_22, +- MMAL_VIDEO_LEVEL_H264_3, +- MMAL_VIDEO_LEVEL_H264_31, +- MMAL_VIDEO_LEVEL_H264_32, +- MMAL_VIDEO_LEVEL_H264_4, +- MMAL_VIDEO_LEVEL_H264_41, +- MMAL_VIDEO_LEVEL_H264_42, +- MMAL_VIDEO_LEVEL_H264_5, +- MMAL_VIDEO_LEVEL_H264_51, +- MMAL_VIDEO_LEVEL_DUMMY = 0x7FFFFFFF +-}; +- +-struct mmal_parameter_video_profile { +- enum mmal_video_profile profile; +- enum mmal_video_level level; +-}; +- +-/* video parameters */ +- +-enum mmal_parameter_video_type { +- /** @ref MMAL_DISPLAYREGION_T */ +- MMAL_PARAMETER_DISPLAYREGION = MMAL_PARAMETER_GROUP_VIDEO, +- +- /** @ref MMAL_PARAMETER_VIDEO_PROFILE_T */ +- MMAL_PARAMETER_SUPPORTED_PROFILES, +- +- /** @ref MMAL_PARAMETER_VIDEO_PROFILE_T */ +- MMAL_PARAMETER_PROFILE, +- +- /** @ref MMAL_PARAMETER_UINT32_T */ +- MMAL_PARAMETER_INTRAPERIOD, +- +- /** @ref MMAL_PARAMETER_VIDEO_RATECONTROL_T */ +- MMAL_PARAMETER_RATECONTROL, +- +- /** @ref MMAL_PARAMETER_VIDEO_NALUNITFORMAT_T */ +- MMAL_PARAMETER_NALUNITFORMAT, +- +- /** @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_MINIMISE_FRAGMENTATION, +- +- /** @ref MMAL_PARAMETER_UINT32_T. +- * Setting the value to zero resets to the default (one slice per +- * frame). +- */ +- MMAL_PARAMETER_MB_ROWS_PER_SLICE, +- +- /** @ref MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION_T */ +- MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION, +- +- /** @ref MMAL_PARAMETER_VIDEO_EEDE_ENABLE_T */ +- MMAL_PARAMETER_VIDEO_EEDE_ENABLE, +- +- /** @ref MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE_T */ +- MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE, +- +- /** @ref MMAL_PARAMETER_BOOLEAN_T. Request an I-frame. */ +- MMAL_PARAMETER_VIDEO_REQUEST_I_FRAME, +- /** @ref MMAL_PARAMETER_VIDEO_INTRA_REFRESH_T */ +- MMAL_PARAMETER_VIDEO_INTRA_REFRESH, +- +- /** @ref MMAL_PARAMETER_BOOLEAN_T. */ +- MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, +- +- /** @ref MMAL_PARAMETER_UINT32_T. Run-time bit rate control */ +- MMAL_PARAMETER_VIDEO_BIT_RATE, +- +- /** @ref MMAL_PARAMETER_FRAME_RATE_T */ +- MMAL_PARAMETER_VIDEO_FRAME_RATE, +- +- /** @ref MMAL_PARAMETER_UINT32_T. */ +- MMAL_PARAMETER_VIDEO_ENCODE_MIN_QUANT, +- +- /** @ref MMAL_PARAMETER_UINT32_T. */ +- MMAL_PARAMETER_VIDEO_ENCODE_MAX_QUANT, +- +- /** @ref MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL_T. */ +- MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL, +- +- MMAL_PARAMETER_EXTRA_BUFFERS, /**< @ref MMAL_PARAMETER_UINT32_T. */ +- /** @ref MMAL_PARAMETER_UINT32_T. +- * Changing this parameter from the default can reduce frame rate +- * because image buffers need to be re-pitched. +- */ +- MMAL_PARAMETER_VIDEO_ALIGN_HORIZ, +- +- /** @ref MMAL_PARAMETER_UINT32_T. +- * Changing this parameter from the default can reduce frame rate +- * because image buffers need to be re-pitched. +- */ +- MMAL_PARAMETER_VIDEO_ALIGN_VERT, +- +- /** @ref MMAL_PARAMETER_BOOLEAN_T. */ +- MMAL_PARAMETER_VIDEO_DROPPABLE_PFRAMES, +- +- /** @ref MMAL_PARAMETER_UINT32_T. */ +- MMAL_PARAMETER_VIDEO_ENCODE_INITIAL_QUANT, +- +- /**< @ref MMAL_PARAMETER_UINT32_T. */ +- MMAL_PARAMETER_VIDEO_ENCODE_QP_P, +- +- /**< @ref MMAL_PARAMETER_UINT32_T. */ +- MMAL_PARAMETER_VIDEO_ENCODE_RC_SLICE_DQUANT, +- +- /** @ref MMAL_PARAMETER_UINT32_T */ +- MMAL_PARAMETER_VIDEO_ENCODE_FRAME_LIMIT_BITS, +- +- /** @ref MMAL_PARAMETER_UINT32_T. */ +- MMAL_PARAMETER_VIDEO_ENCODE_PEAK_RATE, +- +- /* H264 specific parameters */ +- +- /** @ref MMAL_PARAMETER_BOOLEAN_T. */ +- MMAL_PARAMETER_VIDEO_ENCODE_H264_DISABLE_CABAC, +- +- /** @ref MMAL_PARAMETER_BOOLEAN_T. */ +- MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_LATENCY, +- +- /** @ref MMAL_PARAMETER_BOOLEAN_T. */ +- MMAL_PARAMETER_VIDEO_ENCODE_H264_AU_DELIMITERS, +- +- /** @ref MMAL_PARAMETER_UINT32_T. */ +- MMAL_PARAMETER_VIDEO_ENCODE_H264_DEBLOCK_IDC, +- +- /** @ref MMAL_PARAMETER_VIDEO_ENCODER_H264_MB_INTRA_MODES_T. */ +- MMAL_PARAMETER_VIDEO_ENCODE_H264_MB_INTRA_MODE, +- +- /** @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_VIDEO_ENCODE_HEADER_ON_OPEN, +- +- /** @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_VIDEO_ENCODE_PRECODE_FOR_QP, +- +- /** @ref MMAL_PARAMETER_VIDEO_DRM_INIT_INFO_T. */ +- MMAL_PARAMETER_VIDEO_DRM_INIT_INFO, +- +- /** @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_VIDEO_TIMESTAMP_FIFO, +- +- /** @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_VIDEO_DECODE_ERROR_CONCEALMENT, +- +- /** @ref MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER_T. */ +- MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER, +- +- /** @ref MMAL_PARAMETER_BYTES_T */ +- MMAL_PARAMETER_VIDEO_DECODE_CONFIG_VD3, +- +- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_VIDEO_ENCODE_H264_VCL_HRD_PARAMETERS, +- +- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_DELAY_HRD_FLAG, +- +- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER +-}; +- +-/** Valid mirror modes */ +-enum mmal_parameter_mirror { +- MMAL_PARAM_MIRROR_NONE, +- MMAL_PARAM_MIRROR_VERTICAL, +- MMAL_PARAM_MIRROR_HORIZONTAL, +- MMAL_PARAM_MIRROR_BOTH, +-}; +- +-enum mmal_parameter_displaytransform { +- MMAL_DISPLAY_ROT0 = 0, +- MMAL_DISPLAY_MIRROR_ROT0 = 1, +- MMAL_DISPLAY_MIRROR_ROT180 = 2, +- MMAL_DISPLAY_ROT180 = 3, +- MMAL_DISPLAY_MIRROR_ROT90 = 4, +- MMAL_DISPLAY_ROT270 = 5, +- MMAL_DISPLAY_ROT90 = 6, +- MMAL_DISPLAY_MIRROR_ROT270 = 7, +-}; +- +-enum mmal_parameter_displaymode { +- MMAL_DISPLAY_MODE_FILL = 0, +- MMAL_DISPLAY_MODE_LETTERBOX = 1, +-}; +- +-enum mmal_parameter_displayset { +- MMAL_DISPLAY_SET_NONE = 0, +- MMAL_DISPLAY_SET_NUM = 1, +- MMAL_DISPLAY_SET_FULLSCREEN = 2, +- MMAL_DISPLAY_SET_TRANSFORM = 4, +- MMAL_DISPLAY_SET_DEST_RECT = 8, +- MMAL_DISPLAY_SET_SRC_RECT = 0x10, +- MMAL_DISPLAY_SET_MODE = 0x20, +- MMAL_DISPLAY_SET_PIXEL = 0x40, +- MMAL_DISPLAY_SET_NOASPECT = 0x80, +- MMAL_DISPLAY_SET_LAYER = 0x100, +- MMAL_DISPLAY_SET_COPYPROTECT = 0x200, +- MMAL_DISPLAY_SET_ALPHA = 0x400, +-}; +- +-/* rectangle, used lots so it gets its own struct */ +-struct vchiq_mmal_rect { +- s32 x; +- s32 y; +- s32 width; +- s32 height; +-}; +- +-struct mmal_parameter_displayregion { +- /** Bitfield that indicates which fields are set and should be +- * used. All other fields will maintain their current value. +- * \ref MMAL_DISPLAYSET_T defines the bits that can be +- * combined. +- */ +- u32 set; +- +- /** Describes the display output device, with 0 typically +- * being a directly connected LCD display. The actual values +- * will depend on the hardware. Code using hard-wired numbers +- * (e.g. 2) is certain to fail. +- */ +- +- u32 display_num; +- /** Indicates that we are using the full device screen area, +- * rather than a window of the display. If zero, then +- * dest_rect is used to specify a region of the display to +- * use. +- */ +- +- s32 fullscreen; +- /** Indicates any rotation or flipping used to map frames onto +- * the natural display orientation. +- */ +- u32 transform; /* enum mmal_parameter_displaytransform */ +- +- /** Where to display the frame within the screen, if +- * fullscreen is zero. +- */ +- struct vchiq_mmal_rect dest_rect; +- +- /** Indicates which area of the frame to display. If all +- * values are zero, the whole frame will be used. +- */ +- struct vchiq_mmal_rect src_rect; +- +- /** If set to non-zero, indicates that any display scaling +- * should disregard the aspect ratio of the frame region being +- * displayed. +- */ +- s32 noaspect; +- +- /** Indicates how the image should be scaled to fit the +- * display. \code MMAL_DISPLAY_MODE_FILL \endcode indicates +- * that the image should fill the screen by potentially +- * cropping the frames. Setting \code mode \endcode to \code +- * MMAL_DISPLAY_MODE_LETTERBOX \endcode indicates that all the +- * source region should be displayed and black bars added if +- * necessary. +- */ +- u32 mode; /* enum mmal_parameter_displaymode */ +- +- /** If non-zero, defines the width of a source pixel relative +- * to \code pixel_y \endcode. If zero, then pixels default to +- * being square. +- */ +- u32 pixel_x; +- +- /** If non-zero, defines the height of a source pixel relative +- * to \code pixel_x \endcode. If zero, then pixels default to +- * being square. +- */ +- u32 pixel_y; +- +- /** Sets the relative depth of the images, with greater values +- * being in front of smaller values. +- */ +- u32 layer; +- +- /** Set to non-zero to ensure copy protection is used on +- * output. +- */ +- s32 copyprotect_required; +- +- /** Level of opacity of the layer, where zero is fully +- * transparent and 255 is fully opaque. +- */ +- u32 alpha; +-}; +- +-#define MMAL_MAX_IMAGEFX_PARAMETERS 5 +- +-struct mmal_parameter_imagefx_parameters { +- enum mmal_parameter_imagefx effect; +- u32 num_effect_params; +- u32 effect_parameter[MMAL_MAX_IMAGEFX_PARAMETERS]; +-}; +- +-#define MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS 4 +-#define MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES 2 +-#define MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN 16 +- +-struct mmal_parameter_camera_info_camera_t { +- u32 port_id; +- u32 max_width; +- u32 max_height; +- u32 lens_present; +- u8 camera_name[MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN]; +-}; +- +-enum mmal_parameter_camera_info_flash_type_t { +- /* Make values explicit to ensure they match values in config ini */ +- MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_XENON = 0, +- MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_LED = 1, +- MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_OTHER = 2, +- MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_MAX = 0x7FFFFFFF +-}; +- +-struct mmal_parameter_camera_info_flash_t { +- enum mmal_parameter_camera_info_flash_type_t flash_type; +-}; +- +-struct mmal_parameter_camera_info_t { +- u32 num_cameras; +- u32 num_flashes; +- struct mmal_parameter_camera_info_camera_t +- cameras[MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS]; +- struct mmal_parameter_camera_info_flash_t +- flashes[MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES]; +-}; +- +-#endif +--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h ++++ /dev/null +@@ -1,166 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +-/* +- * Broadcom BM2835 V4L2 driver +- * +- * Copyright © 2013 Raspberry Pi (Trading) Ltd. +- * +- * Authors: Vincent Sanders @ Collabora +- * Dave Stevenson @ Broadcom +- * (now dave.stevenson@raspberrypi.org) +- * Simon Mellor @ Broadcom +- * Luke Diamand @ Broadcom +- * +- * MMAL interface to VCHIQ message passing +- */ +- +-#ifndef MMAL_VCHIQ_H +-#define MMAL_VCHIQ_H +- +-#include "mmal-msg-format.h" +- +-#define MAX_PORT_COUNT 4 +- +-/* Maximum size of the format extradata. */ +-#define MMAL_FORMAT_EXTRADATA_MAX_SIZE 128 +- +-struct vchiq_mmal_instance; +- +-enum vchiq_mmal_es_type { +- MMAL_ES_TYPE_UNKNOWN, /**< Unknown elementary stream type */ +- MMAL_ES_TYPE_CONTROL, /**< Elementary stream of control commands */ +- MMAL_ES_TYPE_AUDIO, /**< Audio elementary stream */ +- MMAL_ES_TYPE_VIDEO, /**< Video elementary stream */ +- MMAL_ES_TYPE_SUBPICTURE /**< Sub-picture elementary stream */ +-}; +- +-struct vchiq_mmal_port_buffer { +- unsigned int num; /* number of buffers */ +- u32 size; /* size of buffers */ +- u32 alignment; /* alignment of buffers */ +-}; +- +-struct vchiq_mmal_port; +- +-typedef void (*vchiq_mmal_buffer_cb)( +- struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port, +- int status, struct mmal_buffer *buffer, +- unsigned long length, u32 mmal_flags, s64 dts, s64 pts); +- +-struct vchiq_mmal_port { +- bool enabled; +- u32 handle; +- u32 type; /* port type, cached to use on port info set */ +- u32 index; /* port index, cached to use on port info set */ +- +- /* component port belongs to, allows simple deref */ +- struct vchiq_mmal_component *component; +- +- struct vchiq_mmal_port *connected; /* port conencted to */ +- +- /* buffer info */ +- struct vchiq_mmal_port_buffer minimum_buffer; +- struct vchiq_mmal_port_buffer recommended_buffer; +- struct vchiq_mmal_port_buffer current_buffer; +- +- /* stream format */ +- struct mmal_es_format_local format; +- /* elementary stream format */ +- union mmal_es_specific_format es; +- +- /* data buffers to fill */ +- struct list_head buffers; +- /* lock to serialise adding and removing buffers from list */ +- spinlock_t slock; +- +- /* Count of buffers the VPU has yet to return */ +- atomic_t buffers_with_vpu; +- /* callback on buffer completion */ +- vchiq_mmal_buffer_cb buffer_cb; +- /* callback context */ +- void *cb_ctx; +-}; +- +-struct vchiq_mmal_component { +- bool enabled; +- u32 handle; /* VideoCore handle for component */ +- u32 inputs; /* Number of input ports */ +- u32 outputs; /* Number of output ports */ +- u32 clocks; /* Number of clock ports */ +- struct vchiq_mmal_port control; /* control port */ +- struct vchiq_mmal_port input[MAX_PORT_COUNT]; /* input ports */ +- struct vchiq_mmal_port output[MAX_PORT_COUNT]; /* output ports */ +- struct vchiq_mmal_port clock[MAX_PORT_COUNT]; /* clock ports */ +-}; +- +-int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance); +-int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance); +- +-/* Initialise a mmal component and its ports +- * +- */ +-int vchiq_mmal_component_init( +- struct vchiq_mmal_instance *instance, +- const char *name, +- struct vchiq_mmal_component **component_out); +- +-int vchiq_mmal_component_finalise( +- struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_component *component); +- +-int vchiq_mmal_component_enable( +- struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_component *component); +- +-int vchiq_mmal_component_disable( +- struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_component *component); +- +-/* enable a mmal port +- * +- * enables a port and if a buffer callback provided enque buffer +- * headers as appropriate for the port. +- */ +-int vchiq_mmal_port_enable( +- struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port, +- vchiq_mmal_buffer_cb buffer_cb); +- +-/* disable a port +- * +- * disable a port will dequeue any pending buffers +- */ +-int vchiq_mmal_port_disable(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port); +- +-int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port, +- u32 parameter, +- void *value, +- u32 value_size); +- +-int vchiq_mmal_port_parameter_get(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port, +- u32 parameter, +- void *value, +- u32 *value_size); +- +-int vchiq_mmal_port_set_format(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port); +- +-int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *src, +- struct vchiq_mmal_port *dst); +- +-int vchiq_mmal_version(struct vchiq_mmal_instance *instance, +- u32 *major_out, +- u32 *minor_out); +- +-int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance, +- struct vchiq_mmal_port *port, +- struct mmal_buffer *buf); +- +-int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance, +- struct mmal_buffer *buf); +-int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf); +-#endif /* MMAL_VCHIQ_H */ +--- /dev/null ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h +@@ -0,0 +1,61 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Broadcom BM2835 V4L2 driver ++ * ++ * Copyright © 2013 Raspberry Pi (Trading) Ltd. ++ * ++ * Authors: Vincent Sanders @ Collabora ++ * Dave Stevenson @ Broadcom ++ * (now dave.stevenson@raspberrypi.org) ++ * Simon Mellor @ Broadcom ++ * Luke Diamand @ Broadcom ++ * ++ * MMAL structures ++ * ++ */ ++#ifndef MMAL_COMMON_H ++#define MMAL_COMMON_H ++ ++#define MMAL_FOURCC(a, b, c, d) ((a) | (b << 8) | (c << 16) | (d << 24)) ++#define MMAL_MAGIC MMAL_FOURCC('m', 'm', 'a', 'l') ++ ++/** Special value signalling that time is not known */ ++#define MMAL_TIME_UNKNOWN BIT_ULL(63) ++ ++struct mmal_msg_context; ++ ++/* mapping between v4l and mmal video modes */ ++struct mmal_fmt { ++ char *name; ++ u32 fourcc; /* v4l2 format id */ ++ int flags; /* v4l2 flags field */ ++ u32 mmal; ++ int depth; ++ u32 mmal_component; /* MMAL component index to be used to encode */ ++ u32 ybbp; /* depth of first Y plane for planar formats */ ++ bool remove_padding; /* Does the GPU have to remove padding, ++ * or can we do hide padding via bytesperline. ++ */ ++}; ++ ++/* buffer for one video frame */ ++struct mmal_buffer { ++ /* v4l buffer data -- must be first */ ++ struct vb2_v4l2_buffer vb; ++ ++ /* list of buffers available */ ++ struct list_head list; ++ ++ void *buffer; /* buffer pointer */ ++ unsigned long buffer_size; /* size of allocated buffer */ ++ ++ struct mmal_msg_context *msg_context; ++}; ++ ++/* */ ++struct mmal_colourfx { ++ s32 enable; ++ u32 u; ++ u32 v; ++}; ++#endif +--- /dev/null ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h +@@ -0,0 +1,124 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Broadcom BM2835 V4L2 driver ++ * ++ * Copyright © 2013 Raspberry Pi (Trading) Ltd. ++ * ++ * Authors: Vincent Sanders @ Collabora ++ * Dave Stevenson @ Broadcom ++ * (now dave.stevenson@raspberrypi.org) ++ * Simon Mellor @ Broadcom ++ * Luke Diamand @ Broadcom ++ */ ++#ifndef MMAL_ENCODINGS_H ++#define MMAL_ENCODINGS_H ++ ++#define MMAL_ENCODING_H264 MMAL_FOURCC('H', '2', '6', '4') ++#define MMAL_ENCODING_H263 MMAL_FOURCC('H', '2', '6', '3') ++#define MMAL_ENCODING_MP4V MMAL_FOURCC('M', 'P', '4', 'V') ++#define MMAL_ENCODING_MP2V MMAL_FOURCC('M', 'P', '2', 'V') ++#define MMAL_ENCODING_MP1V MMAL_FOURCC('M', 'P', '1', 'V') ++#define MMAL_ENCODING_WMV3 MMAL_FOURCC('W', 'M', 'V', '3') ++#define MMAL_ENCODING_WMV2 MMAL_FOURCC('W', 'M', 'V', '2') ++#define MMAL_ENCODING_WMV1 MMAL_FOURCC('W', 'M', 'V', '1') ++#define MMAL_ENCODING_WVC1 MMAL_FOURCC('W', 'V', 'C', '1') ++#define MMAL_ENCODING_VP8 MMAL_FOURCC('V', 'P', '8', ' ') ++#define MMAL_ENCODING_VP7 MMAL_FOURCC('V', 'P', '7', ' ') ++#define MMAL_ENCODING_VP6 MMAL_FOURCC('V', 'P', '6', ' ') ++#define MMAL_ENCODING_THEORA MMAL_FOURCC('T', 'H', 'E', 'O') ++#define MMAL_ENCODING_SPARK MMAL_FOURCC('S', 'P', 'R', 'K') ++#define MMAL_ENCODING_MJPEG MMAL_FOURCC('M', 'J', 'P', 'G') ++ ++#define MMAL_ENCODING_JPEG MMAL_FOURCC('J', 'P', 'E', 'G') ++#define MMAL_ENCODING_GIF MMAL_FOURCC('G', 'I', 'F', ' ') ++#define MMAL_ENCODING_PNG MMAL_FOURCC('P', 'N', 'G', ' ') ++#define MMAL_ENCODING_PPM MMAL_FOURCC('P', 'P', 'M', ' ') ++#define MMAL_ENCODING_TGA MMAL_FOURCC('T', 'G', 'A', ' ') ++#define MMAL_ENCODING_BMP MMAL_FOURCC('B', 'M', 'P', ' ') ++ ++#define MMAL_ENCODING_I420 MMAL_FOURCC('I', '4', '2', '0') ++#define MMAL_ENCODING_I420_SLICE MMAL_FOURCC('S', '4', '2', '0') ++#define MMAL_ENCODING_YV12 MMAL_FOURCC('Y', 'V', '1', '2') ++#define MMAL_ENCODING_I422 MMAL_FOURCC('I', '4', '2', '2') ++#define MMAL_ENCODING_I422_SLICE MMAL_FOURCC('S', '4', '2', '2') ++#define MMAL_ENCODING_YUYV MMAL_FOURCC('Y', 'U', 'Y', 'V') ++#define MMAL_ENCODING_YVYU MMAL_FOURCC('Y', 'V', 'Y', 'U') ++#define MMAL_ENCODING_UYVY MMAL_FOURCC('U', 'Y', 'V', 'Y') ++#define MMAL_ENCODING_VYUY MMAL_FOURCC('V', 'Y', 'U', 'Y') ++#define MMAL_ENCODING_NV12 MMAL_FOURCC('N', 'V', '1', '2') ++#define MMAL_ENCODING_NV21 MMAL_FOURCC('N', 'V', '2', '1') ++#define MMAL_ENCODING_ARGB MMAL_FOURCC('A', 'R', 'G', 'B') ++#define MMAL_ENCODING_RGBA MMAL_FOURCC('R', 'G', 'B', 'A') ++#define MMAL_ENCODING_ABGR MMAL_FOURCC('A', 'B', 'G', 'R') ++#define MMAL_ENCODING_BGRA MMAL_FOURCC('B', 'G', 'R', 'A') ++#define MMAL_ENCODING_RGB16 MMAL_FOURCC('R', 'G', 'B', '2') ++#define MMAL_ENCODING_RGB24 MMAL_FOURCC('R', 'G', 'B', '3') ++#define MMAL_ENCODING_RGB32 MMAL_FOURCC('R', 'G', 'B', '4') ++#define MMAL_ENCODING_BGR16 MMAL_FOURCC('B', 'G', 'R', '2') ++#define MMAL_ENCODING_BGR24 MMAL_FOURCC('B', 'G', 'R', '3') ++#define MMAL_ENCODING_BGR32 MMAL_FOURCC('B', 'G', 'R', '4') ++ ++/** SAND Video (YUVUV128) format, native format understood by VideoCore. ++ * This format is *not* opaque - if requested you will receive full frames ++ * of YUV_UV video. ++ */ ++#define MMAL_ENCODING_YUVUV128 MMAL_FOURCC('S', 'A', 'N', 'D') ++ ++/** VideoCore opaque image format, image handles are returned to ++ * the host but not the actual image data. ++ */ ++#define MMAL_ENCODING_OPAQUE MMAL_FOURCC('O', 'P', 'Q', 'V') ++ ++/** An EGL image handle ++ */ ++#define MMAL_ENCODING_EGL_IMAGE MMAL_FOURCC('E', 'G', 'L', 'I') ++ ++/* }@ */ ++ ++/** \name Pre-defined audio encodings */ ++/* @{ */ ++#define MMAL_ENCODING_PCM_UNSIGNED_BE MMAL_FOURCC('P', 'C', 'M', 'U') ++#define MMAL_ENCODING_PCM_UNSIGNED_LE MMAL_FOURCC('p', 'c', 'm', 'u') ++#define MMAL_ENCODING_PCM_SIGNED_BE MMAL_FOURCC('P', 'C', 'M', 'S') ++#define MMAL_ENCODING_PCM_SIGNED_LE MMAL_FOURCC('p', 'c', 'm', 's') ++#define MMAL_ENCODING_PCM_FLOAT_BE MMAL_FOURCC('P', 'C', 'M', 'F') ++#define MMAL_ENCODING_PCM_FLOAT_LE MMAL_FOURCC('p', 'c', 'm', 'f') ++ ++/* Pre-defined H264 encoding variants */ ++ ++/** ISO 14496-10 Annex B byte stream format */ ++#define MMAL_ENCODING_VARIANT_H264_DEFAULT 0 ++/** ISO 14496-15 AVC stream format */ ++#define MMAL_ENCODING_VARIANT_H264_AVC1 MMAL_FOURCC('A', 'V', 'C', '1') ++/** Implicitly delineated NAL units without emulation prevention */ ++#define MMAL_ENCODING_VARIANT_H264_RAW MMAL_FOURCC('R', 'A', 'W', ' ') ++ ++/** \defgroup MmalColorSpace List of pre-defined video color spaces ++ * This defines a list of common color spaces. This list isn't exhaustive and ++ * is only provided as a convenience to avoid clients having to use FourCC ++ * codes directly. However components are allowed to define and use their own ++ * FourCC codes. ++ */ ++/* @{ */ ++ ++/** Unknown color space */ ++#define MMAL_COLOR_SPACE_UNKNOWN 0 ++/** ITU-R BT.601-5 [SDTV] */ ++#define MMAL_COLOR_SPACE_ITUR_BT601 MMAL_FOURCC('Y', '6', '0', '1') ++/** ITU-R BT.709-3 [HDTV] */ ++#define MMAL_COLOR_SPACE_ITUR_BT709 MMAL_FOURCC('Y', '7', '0', '9') ++/** JPEG JFIF */ ++#define MMAL_COLOR_SPACE_JPEG_JFIF MMAL_FOURCC('Y', 'J', 'F', 'I') ++/** Title 47 Code of Federal Regulations (2003) 73.682 (a) (20) */ ++#define MMAL_COLOR_SPACE_FCC MMAL_FOURCC('Y', 'F', 'C', 'C') ++/** Society of Motion Picture and Television Engineers 240M (1999) */ ++#define MMAL_COLOR_SPACE_SMPTE240M MMAL_FOURCC('Y', '2', '4', '0') ++/** ITU-R BT.470-2 System M */ ++#define MMAL_COLOR_SPACE_BT470_2_M MMAL_FOURCC('Y', '_', '_', 'M') ++/** ITU-R BT.470-2 System BG */ ++#define MMAL_COLOR_SPACE_BT470_2_BG MMAL_FOURCC('Y', '_', 'B', 'G') ++/** JPEG JFIF, but with 16..255 luma */ ++#define MMAL_COLOR_SPACE_JFIF_Y16_255 MMAL_FOURCC('Y', 'Y', '1', '6') ++/* @} MmalColorSpace List */ ++ ++#endif /* MMAL_ENCODINGS_H */ +--- /dev/null ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-common.h +@@ -0,0 +1,48 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Broadcom BM2835 V4L2 driver ++ * ++ * Copyright © 2013 Raspberry Pi (Trading) Ltd. ++ * ++ * Authors: Vincent Sanders @ Collabora ++ * Dave Stevenson @ Broadcom ++ * (now dave.stevenson@raspberrypi.org) ++ * Simon Mellor @ Broadcom ++ * Luke Diamand @ Broadcom ++ */ ++ ++#ifndef MMAL_MSG_COMMON_H ++#define MMAL_MSG_COMMON_H ++ ++enum mmal_msg_status { ++ MMAL_MSG_STATUS_SUCCESS = 0, /**< Success */ ++ MMAL_MSG_STATUS_ENOMEM, /**< Out of memory */ ++ MMAL_MSG_STATUS_ENOSPC, /**< Out of resources other than memory */ ++ MMAL_MSG_STATUS_EINVAL, /**< Argument is invalid */ ++ MMAL_MSG_STATUS_ENOSYS, /**< Function not implemented */ ++ MMAL_MSG_STATUS_ENOENT, /**< No such file or directory */ ++ MMAL_MSG_STATUS_ENXIO, /**< No such device or address */ ++ MMAL_MSG_STATUS_EIO, /**< I/O error */ ++ MMAL_MSG_STATUS_ESPIPE, /**< Illegal seek */ ++ MMAL_MSG_STATUS_ECORRUPT, /**< Data is corrupt \attention */ ++ MMAL_MSG_STATUS_ENOTREADY, /**< Component is not ready */ ++ MMAL_MSG_STATUS_ECONFIG, /**< Component is not configured */ ++ MMAL_MSG_STATUS_EISCONN, /**< Port is already connected */ ++ MMAL_MSG_STATUS_ENOTCONN, /**< Port is disconnected */ ++ MMAL_MSG_STATUS_EAGAIN, /**< Resource temporarily unavailable. */ ++ MMAL_MSG_STATUS_EFAULT, /**< Bad address */ ++}; ++ ++struct mmal_rect { ++ s32 x; /**< x coordinate (from left) */ ++ s32 y; /**< y coordinate (from top) */ ++ s32 width; /**< width */ ++ s32 height; /**< height */ ++}; ++ ++struct mmal_rational { ++ s32 num; /**< Numerator */ ++ s32 den; /**< Denominator */ ++}; ++ ++#endif /* MMAL_MSG_COMMON_H */ +--- /dev/null ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-format.h +@@ -0,0 +1,106 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Broadcom BM2835 V4L2 driver ++ * ++ * Copyright © 2013 Raspberry Pi (Trading) Ltd. ++ * ++ * Authors: Vincent Sanders @ Collabora ++ * Dave Stevenson @ Broadcom ++ * (now dave.stevenson@raspberrypi.org) ++ * Simon Mellor @ Broadcom ++ * Luke Diamand @ Broadcom ++ */ ++ ++#ifndef MMAL_MSG_FORMAT_H ++#define MMAL_MSG_FORMAT_H ++ ++#include "mmal-msg-common.h" ++ ++/* MMAL_ES_FORMAT_T */ ++ ++struct mmal_audio_format { ++ u32 channels; /* Number of audio channels */ ++ u32 sample_rate; /* Sample rate */ ++ ++ u32 bits_per_sample; /* Bits per sample */ ++ u32 block_align; /* Size of a block of data */ ++}; ++ ++struct mmal_video_format { ++ u32 width; /* Width of frame in pixels */ ++ u32 height; /* Height of frame in rows of pixels */ ++ struct mmal_rect crop; /* Visible region of the frame */ ++ struct mmal_rational frame_rate; /* Frame rate */ ++ struct mmal_rational par; /* Pixel aspect ratio */ ++ ++ /* ++ * FourCC specifying the color space of the video stream. See the ++ * MmalColorSpace "pre-defined color spaces" for some examples. ++ */ ++ u32 color_space; ++}; ++ ++struct mmal_subpicture_format { ++ u32 x_offset; ++ u32 y_offset; ++}; ++ ++union mmal_es_specific_format { ++ struct mmal_audio_format audio; ++ struct mmal_video_format video; ++ struct mmal_subpicture_format subpicture; ++}; ++ ++/* Definition of an elementary stream format (MMAL_ES_FORMAT_T) */ ++struct mmal_es_format_local { ++ u32 type; /* enum mmal_es_type */ ++ ++ u32 encoding; /* FourCC specifying encoding of the elementary ++ * stream. ++ */ ++ u32 encoding_variant; /* FourCC specifying the specific ++ * encoding variant of the elementary ++ * stream. ++ */ ++ ++ union mmal_es_specific_format *es; /* Type specific ++ * information for the ++ * elementary stream ++ */ ++ ++ u32 bitrate; /* Bitrate in bits per second */ ++ u32 flags; /* Flags describing properties of the elementary ++ * stream. ++ */ ++ ++ u32 extradata_size; /* Size of the codec specific data */ ++ u8 *extradata; /* Codec specific data */ ++}; ++ ++/* Remote definition of an elementary stream format (MMAL_ES_FORMAT_T) */ ++struct mmal_es_format { ++ u32 type; /* enum mmal_es_type */ ++ ++ u32 encoding; /* FourCC specifying encoding of the elementary ++ * stream. ++ */ ++ u32 encoding_variant; /* FourCC specifying the specific ++ * encoding variant of the elementary ++ * stream. ++ */ ++ ++ u32 es; /* Type specific ++ * information for the ++ * elementary stream ++ */ ++ ++ u32 bitrate; /* Bitrate in bits per second */ ++ u32 flags; /* Flags describing properties of the elementary ++ * stream. ++ */ ++ ++ u32 extradata_size; /* Size of the codec specific data */ ++ u32 extradata; /* Codec specific data */ ++}; ++ ++#endif /* MMAL_MSG_FORMAT_H */ +--- /dev/null ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-port.h +@@ -0,0 +1,109 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Broadcom BM2835 V4L2 driver ++ * ++ * Copyright © 2013 Raspberry Pi (Trading) Ltd. ++ * ++ * Authors: Vincent Sanders @ Collabora ++ * Dave Stevenson @ Broadcom ++ * (now dave.stevenson@raspberrypi.org) ++ * Simon Mellor @ Broadcom ++ * Luke Diamand @ Broadcom ++ */ ++ ++/* MMAL_PORT_TYPE_T */ ++enum mmal_port_type { ++ MMAL_PORT_TYPE_UNKNOWN = 0, /* Unknown port type */ ++ MMAL_PORT_TYPE_CONTROL, /* Control port */ ++ MMAL_PORT_TYPE_INPUT, /* Input port */ ++ MMAL_PORT_TYPE_OUTPUT, /* Output port */ ++ MMAL_PORT_TYPE_CLOCK, /* Clock port */ ++}; ++ ++/* The port is pass-through and doesn't need buffer headers allocated */ ++#define MMAL_PORT_CAPABILITY_PASSTHROUGH 0x01 ++/* ++ *The port wants to allocate the buffer payloads. ++ * This signals a preference that payload allocation should be done ++ * on this port for efficiency reasons. ++ */ ++#define MMAL_PORT_CAPABILITY_ALLOCATION 0x02 ++/* ++ * The port supports format change events. ++ * This applies to input ports and is used to let the client know ++ * whether the port supports being reconfigured via a format ++ * change event (i.e. without having to disable the port). ++ */ ++#define MMAL_PORT_CAPABILITY_SUPPORTS_EVENT_FORMAT_CHANGE 0x04 ++ ++/* ++ * mmal port structure (MMAL_PORT_T) ++ * ++ * most elements are informational only, the pointer values for ++ * interogation messages are generally provided as additional ++ * structures within the message. When used to set values only the ++ * buffer_num, buffer_size and userdata parameters are writable. ++ */ ++struct mmal_port { ++ u32 priv; /* Private member used by the framework */ ++ u32 name; /* Port name. Used for debugging purposes (RO) */ ++ ++ u32 type; /* Type of the port (RO) enum mmal_port_type */ ++ u16 index; /* Index of the port in its type list (RO) */ ++ u16 index_all; /* Index of the port in the list of all ports (RO) */ ++ ++ u32 is_enabled; /* Indicates whether the port is enabled or not (RO) */ ++ u32 format; /* Format of the elementary stream */ ++ ++ u32 buffer_num_min; /* Minimum number of buffers the port ++ * requires (RO). This is set by the ++ * component. ++ */ ++ ++ u32 buffer_size_min; /* Minimum size of buffers the port ++ * requires (RO). This is set by the ++ * component. ++ */ ++ ++ u32 buffer_alignment_min;/* Minimum alignment requirement for ++ * the buffers (RO). A value of ++ * zero means no special alignment ++ * requirements. This is set by the ++ * component. ++ */ ++ ++ u32 buffer_num_recommended; /* Number of buffers the port ++ * recommends for optimal ++ * performance (RO). A value of ++ * zero means no special ++ * recommendation. This is set ++ * by the component. ++ */ ++ ++ u32 buffer_size_recommended; /* Size of buffers the port ++ * recommends for optimal ++ * performance (RO). A value of ++ * zero means no special ++ * recommendation. This is set ++ * by the component. ++ */ ++ ++ u32 buffer_num; /* Actual number of buffers the port will use. ++ * This is set by the client. ++ */ ++ ++ u32 buffer_size; /* Actual maximum size of the buffers that ++ * will be sent to the port. This is set by ++ * the client. ++ */ ++ ++ u32 component; /* Component this port belongs to (Read Only) */ ++ ++ u32 userdata; /* Field reserved for use by the client */ ++ ++ u32 capabilities; /* Flags describing the capabilities of a ++ * port (RO). Bitwise combination of \ref ++ * portcapabilities "Port capabilities" ++ * values. ++ */ ++}; +--- /dev/null ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h +@@ -0,0 +1,406 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Broadcom BM2835 V4L2 driver ++ * ++ * Copyright © 2013 Raspberry Pi (Trading) Ltd. ++ * ++ * Authors: Vincent Sanders @ Collabora ++ * Dave Stevenson @ Broadcom ++ * (now dave.stevenson@raspberrypi.org) ++ * Simon Mellor @ Broadcom ++ * Luke Diamand @ Broadcom ++ */ ++ ++/* ++ * all the data structures which serialise the MMAL protocol. note ++ * these are directly mapped onto the recived message data. ++ * ++ * BEWARE: They seem to *assume* pointers are u32 and that there is no ++ * structure padding! ++ * ++ * NOTE: this implementation uses kernel types to ensure sizes. Rather ++ * than assigning values to enums to force their size the ++ * implementation uses fixed size types and not the enums (though the ++ * comments have the actual enum type ++ */ ++#ifndef MMAL_MSG_H ++#define MMAL_MSG_H ++ ++#define VC_MMAL_VER 15 ++#define VC_MMAL_MIN_VER 10 ++#define VC_MMAL_SERVER_NAME MAKE_FOURCC("mmal") ++ ++/* max total message size is 512 bytes */ ++#define MMAL_MSG_MAX_SIZE 512 ++/* with six 32bit header elements max payload is therefore 488 bytes */ ++#define MMAL_MSG_MAX_PAYLOAD 488 ++ ++#include "mmal-msg-common.h" ++#include "mmal-msg-format.h" ++#include "mmal-msg-port.h" ++ ++enum mmal_msg_type { ++ MMAL_MSG_TYPE_QUIT = 1, ++ MMAL_MSG_TYPE_SERVICE_CLOSED, ++ MMAL_MSG_TYPE_GET_VERSION, ++ MMAL_MSG_TYPE_COMPONENT_CREATE, ++ MMAL_MSG_TYPE_COMPONENT_DESTROY, /* 5 */ ++ MMAL_MSG_TYPE_COMPONENT_ENABLE, ++ MMAL_MSG_TYPE_COMPONENT_DISABLE, ++ MMAL_MSG_TYPE_PORT_INFO_GET, ++ MMAL_MSG_TYPE_PORT_INFO_SET, ++ MMAL_MSG_TYPE_PORT_ACTION, /* 10 */ ++ MMAL_MSG_TYPE_BUFFER_FROM_HOST, ++ MMAL_MSG_TYPE_BUFFER_TO_HOST, ++ MMAL_MSG_TYPE_GET_STATS, ++ MMAL_MSG_TYPE_PORT_PARAMETER_SET, ++ MMAL_MSG_TYPE_PORT_PARAMETER_GET, /* 15 */ ++ MMAL_MSG_TYPE_EVENT_TO_HOST, ++ MMAL_MSG_TYPE_GET_CORE_STATS_FOR_PORT, ++ MMAL_MSG_TYPE_OPAQUE_ALLOCATOR, ++ MMAL_MSG_TYPE_CONSUME_MEM, ++ MMAL_MSG_TYPE_LMK, /* 20 */ ++ MMAL_MSG_TYPE_OPAQUE_ALLOCATOR_DESC, ++ MMAL_MSG_TYPE_DRM_GET_LHS32, ++ MMAL_MSG_TYPE_DRM_GET_TIME, ++ MMAL_MSG_TYPE_BUFFER_FROM_HOST_ZEROLEN, ++ MMAL_MSG_TYPE_PORT_FLUSH, /* 25 */ ++ MMAL_MSG_TYPE_HOST_LOG, ++ MMAL_MSG_TYPE_MSG_LAST ++}; ++ ++/* port action request messages differ depending on the action type */ ++enum mmal_msg_port_action_type { ++ MMAL_MSG_PORT_ACTION_TYPE_UNKNOWN = 0, /* Unknown action */ ++ MMAL_MSG_PORT_ACTION_TYPE_ENABLE, /* Enable a port */ ++ MMAL_MSG_PORT_ACTION_TYPE_DISABLE, /* Disable a port */ ++ MMAL_MSG_PORT_ACTION_TYPE_FLUSH, /* Flush a port */ ++ MMAL_MSG_PORT_ACTION_TYPE_CONNECT, /* Connect ports */ ++ MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT, /* Disconnect ports */ ++ MMAL_MSG_PORT_ACTION_TYPE_SET_REQUIREMENTS, /* Set buffer requirements*/ ++}; ++ ++struct mmal_msg_header { ++ u32 magic; ++ u32 type; /* enum mmal_msg_type */ ++ ++ /* Opaque handle to the control service */ ++ u32 control_service; ++ ++ u32 context; /* a u32 per message context */ ++ u32 status; /* The status of the vchiq operation */ ++ u32 padding; ++}; ++ ++/* Send from VC to host to report version */ ++struct mmal_msg_version { ++ u32 flags; ++ u32 major; ++ u32 minor; ++ u32 minimum; ++}; ++ ++/* request to VC to create component */ ++struct mmal_msg_component_create { ++ u32 client_component; /* component context */ ++ char name[128]; ++ u32 pid; /* For debug */ ++}; ++ ++/* reply from VC to component creation request */ ++struct mmal_msg_component_create_reply { ++ u32 status; /* enum mmal_msg_status - how does this differ to ++ * the one in the header? ++ */ ++ u32 component_handle; /* VideoCore handle for component */ ++ u32 input_num; /* Number of input ports */ ++ u32 output_num; /* Number of output ports */ ++ u32 clock_num; /* Number of clock ports */ ++}; ++ ++/* request to VC to destroy a component */ ++struct mmal_msg_component_destroy { ++ u32 component_handle; ++}; ++ ++struct mmal_msg_component_destroy_reply { ++ u32 status; /* The component destruction status */ ++}; ++ ++/* request and reply to VC to enable a component */ ++struct mmal_msg_component_enable { ++ u32 component_handle; ++}; ++ ++struct mmal_msg_component_enable_reply { ++ u32 status; /* The component enable status */ ++}; ++ ++/* request and reply to VC to disable a component */ ++struct mmal_msg_component_disable { ++ u32 component_handle; ++}; ++ ++struct mmal_msg_component_disable_reply { ++ u32 status; /* The component disable status */ ++}; ++ ++/* request to VC to get port information */ ++struct mmal_msg_port_info_get { ++ u32 component_handle; /* component handle port is associated with */ ++ u32 port_type; /* enum mmal_msg_port_type */ ++ u32 index; /* port index to query */ ++}; ++ ++/* reply from VC to get port info request */ ++struct mmal_msg_port_info_get_reply { ++ u32 status; /* enum mmal_msg_status */ ++ u32 component_handle; /* component handle port is associated with */ ++ u32 port_type; /* enum mmal_msg_port_type */ ++ u32 port_index; /* port indexed in query */ ++ s32 found; /* unused */ ++ u32 port_handle; /* Handle to use for this port */ ++ struct mmal_port port; ++ struct mmal_es_format format; /* elementary stream format */ ++ union mmal_es_specific_format es; /* es type specific data */ ++ u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; /* es extra data */ ++}; ++ ++/* request to VC to set port information */ ++struct mmal_msg_port_info_set { ++ u32 component_handle; ++ u32 port_type; /* enum mmal_msg_port_type */ ++ u32 port_index; /* port indexed in query */ ++ struct mmal_port port; ++ struct mmal_es_format format; ++ union mmal_es_specific_format es; ++ u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; ++}; ++ ++/* reply from VC to port info set request */ ++struct mmal_msg_port_info_set_reply { ++ u32 status; ++ u32 component_handle; /* component handle port is associated with */ ++ u32 port_type; /* enum mmal_msg_port_type */ ++ u32 index; /* port indexed in query */ ++ s32 found; /* unused */ ++ u32 port_handle; /* Handle to use for this port */ ++ struct mmal_port port; ++ struct mmal_es_format format; ++ union mmal_es_specific_format es; ++ u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; ++}; ++ ++/* port action requests that take a mmal_port as a parameter */ ++struct mmal_msg_port_action_port { ++ u32 component_handle; ++ u32 port_handle; ++ u32 action; /* enum mmal_msg_port_action_type */ ++ struct mmal_port port; ++}; ++ ++/* port action requests that take handles as a parameter */ ++struct mmal_msg_port_action_handle { ++ u32 component_handle; ++ u32 port_handle; ++ u32 action; /* enum mmal_msg_port_action_type */ ++ u32 connect_component_handle; ++ u32 connect_port_handle; ++}; ++ ++struct mmal_msg_port_action_reply { ++ u32 status; /* The port action operation status */ ++}; ++ ++/* MMAL buffer transfer */ ++ ++/* Size of space reserved in a buffer message for short messages. */ ++#define MMAL_VC_SHORT_DATA 128 ++ ++/* Signals that the current payload is the end of the stream of data */ ++#define MMAL_BUFFER_HEADER_FLAG_EOS BIT(0) ++/* Signals that the start of the current payload starts a frame */ ++#define MMAL_BUFFER_HEADER_FLAG_FRAME_START BIT(1) ++/* Signals that the end of the current payload ends a frame */ ++#define MMAL_BUFFER_HEADER_FLAG_FRAME_END BIT(2) ++/* Signals that the current payload contains only complete frames (>1) */ ++#define MMAL_BUFFER_HEADER_FLAG_FRAME \ ++ (MMAL_BUFFER_HEADER_FLAG_FRAME_START | \ ++ MMAL_BUFFER_HEADER_FLAG_FRAME_END) ++/* Signals that the current payload is a keyframe (i.e. self decodable) */ ++#define MMAL_BUFFER_HEADER_FLAG_KEYFRAME BIT(3) ++/* ++ * Signals a discontinuity in the stream of data (e.g. after a seek). ++ * Can be used for instance by a decoder to reset its state ++ */ ++#define MMAL_BUFFER_HEADER_FLAG_DISCONTINUITY BIT(4) ++/* ++ * Signals a buffer containing some kind of config data for the component ++ * (e.g. codec config data) ++ */ ++#define MMAL_BUFFER_HEADER_FLAG_CONFIG BIT(5) ++/* Signals an encrypted payload */ ++#define MMAL_BUFFER_HEADER_FLAG_ENCRYPTED BIT(6) ++/* Signals a buffer containing side information */ ++#define MMAL_BUFFER_HEADER_FLAG_CODECSIDEINFO BIT(7) ++/* ++ * Signals a buffer which is the snapshot/postview image from a stills ++ * capture ++ */ ++#define MMAL_BUFFER_HEADER_FLAGS_SNAPSHOT BIT(8) ++/* Signals a buffer which contains data known to be corrupted */ ++#define MMAL_BUFFER_HEADER_FLAG_CORRUPTED BIT(9) ++/* Signals that a buffer failed to be transmitted */ ++#define MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED BIT(10) ++ ++struct mmal_driver_buffer { ++ u32 magic; ++ u32 component_handle; ++ u32 port_handle; ++ u32 client_context; ++}; ++ ++/* buffer header */ ++struct mmal_buffer_header { ++ u32 next; /* next header */ ++ u32 priv; /* framework private data */ ++ u32 cmd; ++ u32 data; ++ u32 alloc_size; ++ u32 length; ++ u32 offset; ++ u32 flags; ++ s64 pts; ++ s64 dts; ++ u32 type; ++ u32 user_data; ++}; ++ ++struct mmal_buffer_header_type_specific { ++ union { ++ struct { ++ u32 planes; ++ u32 offset[4]; ++ u32 pitch[4]; ++ u32 flags; ++ } video; ++ } u; ++}; ++ ++struct mmal_msg_buffer_from_host { ++ /* ++ *The front 32 bytes of the buffer header are copied ++ * back to us in the reply to allow for context. This ++ * area is used to store two mmal_driver_buffer structures to ++ * allow for multiple concurrent service users. ++ */ ++ /* control data */ ++ struct mmal_driver_buffer drvbuf; ++ ++ /* referenced control data for passthrough buffer management */ ++ struct mmal_driver_buffer drvbuf_ref; ++ struct mmal_buffer_header buffer_header; /* buffer header itself */ ++ struct mmal_buffer_header_type_specific buffer_header_type_specific; ++ s32 is_zero_copy; ++ s32 has_reference; ++ ++ /* allows short data to be xfered in control message */ ++ u32 payload_in_message; ++ u8 short_data[MMAL_VC_SHORT_DATA]; ++}; ++ ++/* port parameter setting */ ++ ++#define MMAL_WORKER_PORT_PARAMETER_SPACE 96 ++ ++struct mmal_msg_port_parameter_set { ++ u32 component_handle; /* component */ ++ u32 port_handle; /* port */ ++ u32 id; /* Parameter ID */ ++ u32 size; /* Parameter size */ ++ uint32_t value[MMAL_WORKER_PORT_PARAMETER_SPACE]; ++}; ++ ++struct mmal_msg_port_parameter_set_reply { ++ u32 status; /* enum mmal_msg_status todo: how does this ++ * differ to the one in the header? ++ */ ++}; ++ ++/* port parameter getting */ ++ ++struct mmal_msg_port_parameter_get { ++ u32 component_handle; /* component */ ++ u32 port_handle; /* port */ ++ u32 id; /* Parameter ID */ ++ u32 size; /* Parameter size */ ++}; ++ ++struct mmal_msg_port_parameter_get_reply { ++ u32 status; /* Status of mmal_port_parameter_get call */ ++ u32 id; /* Parameter ID */ ++ u32 size; /* Parameter size */ ++ uint32_t value[MMAL_WORKER_PORT_PARAMETER_SPACE]; ++}; ++ ++/* event messages */ ++#define MMAL_WORKER_EVENT_SPACE 256 ++ ++struct mmal_msg_event_to_host { ++ u32 client_component; /* component context */ ++ ++ u32 port_type; ++ u32 port_num; ++ ++ u32 cmd; ++ u32 length; ++ u8 data[MMAL_WORKER_EVENT_SPACE]; ++ u32 delayed_buffer; ++}; ++ ++/* all mmal messages are serialised through this structure */ ++struct mmal_msg { ++ /* header */ ++ struct mmal_msg_header h; ++ /* payload */ ++ union { ++ struct mmal_msg_version version; ++ ++ struct mmal_msg_component_create component_create; ++ struct mmal_msg_component_create_reply component_create_reply; ++ ++ struct mmal_msg_component_destroy component_destroy; ++ struct mmal_msg_component_destroy_reply component_destroy_reply; ++ ++ struct mmal_msg_component_enable component_enable; ++ struct mmal_msg_component_enable_reply component_enable_reply; ++ ++ struct mmal_msg_component_disable component_disable; ++ struct mmal_msg_component_disable_reply component_disable_reply; ++ ++ struct mmal_msg_port_info_get port_info_get; ++ struct mmal_msg_port_info_get_reply port_info_get_reply; ++ ++ struct mmal_msg_port_info_set port_info_set; ++ struct mmal_msg_port_info_set_reply port_info_set_reply; ++ ++ struct mmal_msg_port_action_port port_action_port; ++ struct mmal_msg_port_action_handle port_action_handle; ++ struct mmal_msg_port_action_reply port_action_reply; ++ ++ struct mmal_msg_buffer_from_host buffer_from_host; ++ ++ struct mmal_msg_port_parameter_set port_parameter_set; ++ struct mmal_msg_port_parameter_set_reply ++ port_parameter_set_reply; ++ struct mmal_msg_port_parameter_get ++ port_parameter_get; ++ struct mmal_msg_port_parameter_get_reply ++ port_parameter_get_reply; ++ ++ struct mmal_msg_event_to_host event_to_host; ++ ++ u8 payload[MMAL_MSG_MAX_PAYLOAD]; ++ } u; ++}; ++#endif +--- /dev/null ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h +@@ -0,0 +1,755 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Broadcom BM2835 V4L2 driver ++ * ++ * Copyright © 2013 Raspberry Pi (Trading) Ltd. ++ * ++ * Authors: Vincent Sanders @ Collabora ++ * Dave Stevenson @ Broadcom ++ * (now dave.stevenson@raspberrypi.org) ++ * Simon Mellor @ Broadcom ++ * Luke Diamand @ Broadcom ++ */ ++ ++/* common parameters */ ++ ++/** @name Parameter groups ++ * Parameters are divided into groups, and then allocated sequentially within ++ * a group using an enum. ++ * @{ ++ */ ++ ++#ifndef MMAL_PARAMETERS_H ++#define MMAL_PARAMETERS_H ++ ++/** Common parameter ID group, used with many types of component. */ ++#define MMAL_PARAMETER_GROUP_COMMON (0 << 16) ++/** Camera-specific parameter ID group. */ ++#define MMAL_PARAMETER_GROUP_CAMERA (1 << 16) ++/** Video-specific parameter ID group. */ ++#define MMAL_PARAMETER_GROUP_VIDEO (2 << 16) ++/** Audio-specific parameter ID group. */ ++#define MMAL_PARAMETER_GROUP_AUDIO (3 << 16) ++/** Clock-specific parameter ID group. */ ++#define MMAL_PARAMETER_GROUP_CLOCK (4 << 16) ++/** Miracast-specific parameter ID group. */ ++#define MMAL_PARAMETER_GROUP_MIRACAST (5 << 16) ++ ++/* Common parameters */ ++enum mmal_parameter_common_type { ++ /**< Never a valid parameter ID */ ++ MMAL_PARAMETER_UNUSED = MMAL_PARAMETER_GROUP_COMMON, ++ ++ /**< MMAL_PARAMETER_ENCODING_T */ ++ MMAL_PARAMETER_SUPPORTED_ENCODINGS, ++ /**< MMAL_PARAMETER_URI_T */ ++ MMAL_PARAMETER_URI, ++ /** MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T */ ++ MMAL_PARAMETER_CHANGE_EVENT_REQUEST, ++ /** MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_ZERO_COPY, ++ /**< MMAL_PARAMETER_BUFFER_REQUIREMENTS_T */ ++ MMAL_PARAMETER_BUFFER_REQUIREMENTS, ++ /**< MMAL_PARAMETER_STATISTICS_T */ ++ MMAL_PARAMETER_STATISTICS, ++ /**< MMAL_PARAMETER_CORE_STATISTICS_T */ ++ MMAL_PARAMETER_CORE_STATISTICS, ++ /**< MMAL_PARAMETER_MEM_USAGE_T */ ++ MMAL_PARAMETER_MEM_USAGE, ++ /**< MMAL_PARAMETER_UINT32_T */ ++ MMAL_PARAMETER_BUFFER_FLAG_FILTER, ++ /**< MMAL_PARAMETER_SEEK_T */ ++ MMAL_PARAMETER_SEEK, ++ /**< MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_POWERMON_ENABLE, ++ /**< MMAL_PARAMETER_LOGGING_T */ ++ MMAL_PARAMETER_LOGGING, ++ /**< MMAL_PARAMETER_UINT64_T */ ++ MMAL_PARAMETER_SYSTEM_TIME, ++ /**< MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_NO_IMAGE_PADDING, ++}; ++ ++/* camera parameters */ ++ ++enum mmal_parameter_camera_type { ++ /* 0 */ ++ /** @ref MMAL_PARAMETER_THUMBNAIL_CONFIG_T */ ++ MMAL_PARAMETER_THUMBNAIL_CONFIGURATION = ++ MMAL_PARAMETER_GROUP_CAMERA, ++ /**< Unused? */ ++ MMAL_PARAMETER_CAPTURE_QUALITY, ++ /**< @ref MMAL_PARAMETER_INT32_T */ ++ MMAL_PARAMETER_ROTATION, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_EXIF_DISABLE, ++ /**< @ref MMAL_PARAMETER_EXIF_T */ ++ MMAL_PARAMETER_EXIF, ++ /**< @ref MMAL_PARAM_AWBMODE_T */ ++ MMAL_PARAMETER_AWB_MODE, ++ /**< @ref MMAL_PARAMETER_IMAGEFX_T */ ++ MMAL_PARAMETER_IMAGE_EFFECT, ++ /**< @ref MMAL_PARAMETER_COLOURFX_T */ ++ MMAL_PARAMETER_COLOUR_EFFECT, ++ /**< @ref MMAL_PARAMETER_FLICKERAVOID_T */ ++ MMAL_PARAMETER_FLICKER_AVOID, ++ /**< @ref MMAL_PARAMETER_FLASH_T */ ++ MMAL_PARAMETER_FLASH, ++ /**< @ref MMAL_PARAMETER_REDEYE_T */ ++ MMAL_PARAMETER_REDEYE, ++ /**< @ref MMAL_PARAMETER_FOCUS_T */ ++ MMAL_PARAMETER_FOCUS, ++ /**< Unused? */ ++ MMAL_PARAMETER_FOCAL_LENGTHS, ++ /**< @ref MMAL_PARAMETER_INT32_T */ ++ MMAL_PARAMETER_EXPOSURE_COMP, ++ /**< @ref MMAL_PARAMETER_SCALEFACTOR_T */ ++ MMAL_PARAMETER_ZOOM, ++ /**< @ref MMAL_PARAMETER_MIRROR_T */ ++ MMAL_PARAMETER_MIRROR, ++ ++ /* 0x10 */ ++ /**< @ref MMAL_PARAMETER_UINT32_T */ ++ MMAL_PARAMETER_CAMERA_NUM, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_CAPTURE, ++ /**< @ref MMAL_PARAMETER_EXPOSUREMODE_T */ ++ MMAL_PARAMETER_EXPOSURE_MODE, ++ /**< @ref MMAL_PARAMETER_EXPOSUREMETERINGMODE_T */ ++ MMAL_PARAMETER_EXP_METERING_MODE, ++ /**< @ref MMAL_PARAMETER_FOCUS_STATUS_T */ ++ MMAL_PARAMETER_FOCUS_STATUS, ++ /**< @ref MMAL_PARAMETER_CAMERA_CONFIG_T */ ++ MMAL_PARAMETER_CAMERA_CONFIG, ++ /**< @ref MMAL_PARAMETER_CAPTURE_STATUS_T */ ++ MMAL_PARAMETER_CAPTURE_STATUS, ++ /**< @ref MMAL_PARAMETER_FACE_TRACK_T */ ++ MMAL_PARAMETER_FACE_TRACK, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_DRAW_BOX_FACES_AND_FOCUS, ++ /**< @ref MMAL_PARAMETER_UINT32_T */ ++ MMAL_PARAMETER_JPEG_Q_FACTOR, ++ /**< @ref MMAL_PARAMETER_FRAME_RATE_T */ ++ MMAL_PARAMETER_FRAME_RATE, ++ /**< @ref MMAL_PARAMETER_CAMERA_STC_MODE_T */ ++ MMAL_PARAMETER_USE_STC, ++ /**< @ref MMAL_PARAMETER_CAMERA_INFO_T */ ++ MMAL_PARAMETER_CAMERA_INFO, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_VIDEO_STABILISATION, ++ /**< @ref MMAL_PARAMETER_FACE_TRACK_RESULTS_T */ ++ MMAL_PARAMETER_FACE_TRACK_RESULTS, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_ENABLE_RAW_CAPTURE, ++ ++ /* 0x20 */ ++ /**< @ref MMAL_PARAMETER_URI_T */ ++ MMAL_PARAMETER_DPF_FILE, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_ENABLE_DPF_FILE, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_DPF_FAIL_IS_FATAL, ++ /**< @ref MMAL_PARAMETER_CAPTUREMODE_T */ ++ MMAL_PARAMETER_CAPTURE_MODE, ++ /**< @ref MMAL_PARAMETER_FOCUS_REGIONS_T */ ++ MMAL_PARAMETER_FOCUS_REGIONS, ++ /**< @ref MMAL_PARAMETER_INPUT_CROP_T */ ++ MMAL_PARAMETER_INPUT_CROP, ++ /**< @ref MMAL_PARAMETER_SENSOR_INFORMATION_T */ ++ MMAL_PARAMETER_SENSOR_INFORMATION, ++ /**< @ref MMAL_PARAMETER_FLASH_SELECT_T */ ++ MMAL_PARAMETER_FLASH_SELECT, ++ /**< @ref MMAL_PARAMETER_FIELD_OF_VIEW_T */ ++ MMAL_PARAMETER_FIELD_OF_VIEW, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_HIGH_DYNAMIC_RANGE, ++ /**< @ref MMAL_PARAMETER_DRC_T */ ++ MMAL_PARAMETER_DYNAMIC_RANGE_COMPRESSION, ++ /**< @ref MMAL_PARAMETER_ALGORITHM_CONTROL_T */ ++ MMAL_PARAMETER_ALGORITHM_CONTROL, ++ /**< @ref MMAL_PARAMETER_RATIONAL_T */ ++ MMAL_PARAMETER_SHARPNESS, ++ /**< @ref MMAL_PARAMETER_RATIONAL_T */ ++ MMAL_PARAMETER_CONTRAST, ++ /**< @ref MMAL_PARAMETER_RATIONAL_T */ ++ MMAL_PARAMETER_BRIGHTNESS, ++ /**< @ref MMAL_PARAMETER_RATIONAL_T */ ++ MMAL_PARAMETER_SATURATION, ++ ++ /* 0x30 */ ++ /**< @ref MMAL_PARAMETER_UINT32_T */ ++ MMAL_PARAMETER_ISO, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_ANTISHAKE, ++ /** @ref MMAL_PARAMETER_IMAGEFX_PARAMETERS_T */ ++ MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, ++ /** @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_CAMERA_BURST_CAPTURE, ++ /** @ref MMAL_PARAMETER_UINT32_T */ ++ MMAL_PARAMETER_CAMERA_MIN_ISO, ++ /** @ref MMAL_PARAMETER_CAMERA_USE_CASE_T */ ++ MMAL_PARAMETER_CAMERA_USE_CASE, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_CAPTURE_STATS_PASS, ++ /** @ref MMAL_PARAMETER_UINT32_T */ ++ MMAL_PARAMETER_CAMERA_CUSTOM_SENSOR_CONFIG, ++ /** @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_ENABLE_REGISTER_FILE, ++ /** @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_REGISTER_FAIL_IS_FATAL, ++ /** @ref MMAL_PARAMETER_CONFIGFILE_T */ ++ MMAL_PARAMETER_CONFIGFILE_REGISTERS, ++ /** @ref MMAL_PARAMETER_CONFIGFILE_CHUNK_T */ ++ MMAL_PARAMETER_CONFIGFILE_CHUNK_REGISTERS, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_JPEG_ATTACH_LOG, ++ /**< @ref MMAL_PARAMETER_ZEROSHUTTERLAG_T */ ++ MMAL_PARAMETER_ZERO_SHUTTER_LAG, ++ /**< @ref MMAL_PARAMETER_FPS_RANGE_T */ ++ MMAL_PARAMETER_FPS_RANGE, ++ /**< @ref MMAL_PARAMETER_INT32_T */ ++ MMAL_PARAMETER_CAPTURE_EXPOSURE_COMP, ++ ++ /* 0x40 */ ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_SW_SHARPEN_DISABLE, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_FLASH_REQUIRED, ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_SW_SATURATION_DISABLE, ++ /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ ++ MMAL_PARAMETER_SHUTTER_SPEED, ++ /**< Takes a @ref MMAL_PARAMETER_AWB_GAINS_T */ ++ MMAL_PARAMETER_CUSTOM_AWB_GAINS, ++}; ++ ++struct mmal_parameter_rational { ++ s32 num; /**< Numerator */ ++ s32 den; /**< Denominator */ ++}; ++ ++enum mmal_parameter_camera_config_timestamp_mode { ++ MMAL_PARAM_TIMESTAMP_MODE_ZERO = 0, /* Always timestamp frames as 0 */ ++ MMAL_PARAM_TIMESTAMP_MODE_RAW_STC, /* Use the raw STC value ++ * for the frame timestamp ++ */ ++ MMAL_PARAM_TIMESTAMP_MODE_RESET_STC, /* Use the STC timestamp ++ * but subtract the ++ * timestamp of the first ++ * frame sent to give a ++ * zero based timestamp. ++ */ ++}; ++ ++struct mmal_parameter_fps_range { ++ /**< Low end of the permitted framerate range */ ++ struct mmal_parameter_rational fps_low; ++ /**< High end of the permitted framerate range */ ++ struct mmal_parameter_rational fps_high; ++}; ++ ++/* camera configuration parameter */ ++struct mmal_parameter_camera_config { ++ /* Parameters for setting up the image pools */ ++ u32 max_stills_w; /* Max size of stills capture */ ++ u32 max_stills_h; ++ u32 stills_yuv422; /* Allow YUV422 stills capture */ ++ u32 one_shot_stills; /* Continuous or one shot stills captures. */ ++ ++ u32 max_preview_video_w; /* Max size of the preview or video ++ * capture frames ++ */ ++ u32 max_preview_video_h; ++ u32 num_preview_video_frames; ++ ++ /** Sets the height of the circular buffer for stills capture. */ ++ u32 stills_capture_circular_buffer_height; ++ ++ /** Allows preview/encode to resume as fast as possible after the stills ++ * input frame has been received, and then processes the still frame in ++ * the background whilst preview/encode has resumed. ++ * Actual mode is controlled by MMAL_PARAMETER_CAPTURE_MODE. ++ */ ++ u32 fast_preview_resume; ++ ++ /** Selects algorithm for timestamping frames if ++ * there is no clock component connected. ++ * enum mmal_parameter_camera_config_timestamp_mode ++ */ ++ s32 use_stc_timestamp; ++}; ++ ++enum mmal_parameter_exposuremode { ++ MMAL_PARAM_EXPOSUREMODE_OFF, ++ MMAL_PARAM_EXPOSUREMODE_AUTO, ++ MMAL_PARAM_EXPOSUREMODE_NIGHT, ++ MMAL_PARAM_EXPOSUREMODE_NIGHTPREVIEW, ++ MMAL_PARAM_EXPOSUREMODE_BACKLIGHT, ++ MMAL_PARAM_EXPOSUREMODE_SPOTLIGHT, ++ MMAL_PARAM_EXPOSUREMODE_SPORTS, ++ MMAL_PARAM_EXPOSUREMODE_SNOW, ++ MMAL_PARAM_EXPOSUREMODE_BEACH, ++ MMAL_PARAM_EXPOSUREMODE_VERYLONG, ++ MMAL_PARAM_EXPOSUREMODE_FIXEDFPS, ++ MMAL_PARAM_EXPOSUREMODE_ANTISHAKE, ++ MMAL_PARAM_EXPOSUREMODE_FIREWORKS, ++}; ++ ++enum mmal_parameter_exposuremeteringmode { ++ MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE, ++ MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT, ++ MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT, ++ MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX, ++}; ++ ++enum mmal_parameter_awbmode { ++ MMAL_PARAM_AWBMODE_OFF, ++ MMAL_PARAM_AWBMODE_AUTO, ++ MMAL_PARAM_AWBMODE_SUNLIGHT, ++ MMAL_PARAM_AWBMODE_CLOUDY, ++ MMAL_PARAM_AWBMODE_SHADE, ++ MMAL_PARAM_AWBMODE_TUNGSTEN, ++ MMAL_PARAM_AWBMODE_FLUORESCENT, ++ MMAL_PARAM_AWBMODE_INCANDESCENT, ++ MMAL_PARAM_AWBMODE_FLASH, ++ MMAL_PARAM_AWBMODE_HORIZON, ++}; ++ ++enum mmal_parameter_imagefx { ++ MMAL_PARAM_IMAGEFX_NONE, ++ MMAL_PARAM_IMAGEFX_NEGATIVE, ++ MMAL_PARAM_IMAGEFX_SOLARIZE, ++ MMAL_PARAM_IMAGEFX_POSTERIZE, ++ MMAL_PARAM_IMAGEFX_WHITEBOARD, ++ MMAL_PARAM_IMAGEFX_BLACKBOARD, ++ MMAL_PARAM_IMAGEFX_SKETCH, ++ MMAL_PARAM_IMAGEFX_DENOISE, ++ MMAL_PARAM_IMAGEFX_EMBOSS, ++ MMAL_PARAM_IMAGEFX_OILPAINT, ++ MMAL_PARAM_IMAGEFX_HATCH, ++ MMAL_PARAM_IMAGEFX_GPEN, ++ MMAL_PARAM_IMAGEFX_PASTEL, ++ MMAL_PARAM_IMAGEFX_WATERCOLOUR, ++ MMAL_PARAM_IMAGEFX_FILM, ++ MMAL_PARAM_IMAGEFX_BLUR, ++ MMAL_PARAM_IMAGEFX_SATURATION, ++ MMAL_PARAM_IMAGEFX_COLOURSWAP, ++ MMAL_PARAM_IMAGEFX_WASHEDOUT, ++ MMAL_PARAM_IMAGEFX_POSTERISE, ++ MMAL_PARAM_IMAGEFX_COLOURPOINT, ++ MMAL_PARAM_IMAGEFX_COLOURBALANCE, ++ MMAL_PARAM_IMAGEFX_CARTOON, ++}; ++ ++enum MMAL_PARAM_FLICKERAVOID_T { ++ MMAL_PARAM_FLICKERAVOID_OFF, ++ MMAL_PARAM_FLICKERAVOID_AUTO, ++ MMAL_PARAM_FLICKERAVOID_50HZ, ++ MMAL_PARAM_FLICKERAVOID_60HZ, ++ MMAL_PARAM_FLICKERAVOID_MAX = 0x7FFFFFFF ++}; ++ ++struct mmal_parameter_awbgains { ++ struct mmal_parameter_rational r_gain; /**< Red gain */ ++ struct mmal_parameter_rational b_gain; /**< Blue gain */ ++}; ++ ++/** Manner of video rate control */ ++enum mmal_parameter_rate_control_mode { ++ MMAL_VIDEO_RATECONTROL_DEFAULT, ++ MMAL_VIDEO_RATECONTROL_VARIABLE, ++ MMAL_VIDEO_RATECONTROL_CONSTANT, ++ MMAL_VIDEO_RATECONTROL_VARIABLE_SKIP_FRAMES, ++ MMAL_VIDEO_RATECONTROL_CONSTANT_SKIP_FRAMES ++}; ++ ++enum mmal_video_profile { ++ MMAL_VIDEO_PROFILE_H263_BASELINE, ++ MMAL_VIDEO_PROFILE_H263_H320CODING, ++ MMAL_VIDEO_PROFILE_H263_BACKWARDCOMPATIBLE, ++ MMAL_VIDEO_PROFILE_H263_ISWV2, ++ MMAL_VIDEO_PROFILE_H263_ISWV3, ++ MMAL_VIDEO_PROFILE_H263_HIGHCOMPRESSION, ++ MMAL_VIDEO_PROFILE_H263_INTERNET, ++ MMAL_VIDEO_PROFILE_H263_INTERLACE, ++ MMAL_VIDEO_PROFILE_H263_HIGHLATENCY, ++ MMAL_VIDEO_PROFILE_MP4V_SIMPLE, ++ MMAL_VIDEO_PROFILE_MP4V_SIMPLESCALABLE, ++ MMAL_VIDEO_PROFILE_MP4V_CORE, ++ MMAL_VIDEO_PROFILE_MP4V_MAIN, ++ MMAL_VIDEO_PROFILE_MP4V_NBIT, ++ MMAL_VIDEO_PROFILE_MP4V_SCALABLETEXTURE, ++ MMAL_VIDEO_PROFILE_MP4V_SIMPLEFACE, ++ MMAL_VIDEO_PROFILE_MP4V_SIMPLEFBA, ++ MMAL_VIDEO_PROFILE_MP4V_BASICANIMATED, ++ MMAL_VIDEO_PROFILE_MP4V_HYBRID, ++ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDREALTIME, ++ MMAL_VIDEO_PROFILE_MP4V_CORESCALABLE, ++ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCODING, ++ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCORE, ++ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSCALABLE, ++ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSIMPLE, ++ MMAL_VIDEO_PROFILE_H264_BASELINE, ++ MMAL_VIDEO_PROFILE_H264_MAIN, ++ MMAL_VIDEO_PROFILE_H264_EXTENDED, ++ MMAL_VIDEO_PROFILE_H264_HIGH, ++ MMAL_VIDEO_PROFILE_H264_HIGH10, ++ MMAL_VIDEO_PROFILE_H264_HIGH422, ++ MMAL_VIDEO_PROFILE_H264_HIGH444, ++ MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE, ++ MMAL_VIDEO_PROFILE_DUMMY = 0x7FFFFFFF ++}; ++ ++enum mmal_video_level { ++ MMAL_VIDEO_LEVEL_H263_10, ++ MMAL_VIDEO_LEVEL_H263_20, ++ MMAL_VIDEO_LEVEL_H263_30, ++ MMAL_VIDEO_LEVEL_H263_40, ++ MMAL_VIDEO_LEVEL_H263_45, ++ MMAL_VIDEO_LEVEL_H263_50, ++ MMAL_VIDEO_LEVEL_H263_60, ++ MMAL_VIDEO_LEVEL_H263_70, ++ MMAL_VIDEO_LEVEL_MP4V_0, ++ MMAL_VIDEO_LEVEL_MP4V_0b, ++ MMAL_VIDEO_LEVEL_MP4V_1, ++ MMAL_VIDEO_LEVEL_MP4V_2, ++ MMAL_VIDEO_LEVEL_MP4V_3, ++ MMAL_VIDEO_LEVEL_MP4V_4, ++ MMAL_VIDEO_LEVEL_MP4V_4a, ++ MMAL_VIDEO_LEVEL_MP4V_5, ++ MMAL_VIDEO_LEVEL_MP4V_6, ++ MMAL_VIDEO_LEVEL_H264_1, ++ MMAL_VIDEO_LEVEL_H264_1b, ++ MMAL_VIDEO_LEVEL_H264_11, ++ MMAL_VIDEO_LEVEL_H264_12, ++ MMAL_VIDEO_LEVEL_H264_13, ++ MMAL_VIDEO_LEVEL_H264_2, ++ MMAL_VIDEO_LEVEL_H264_21, ++ MMAL_VIDEO_LEVEL_H264_22, ++ MMAL_VIDEO_LEVEL_H264_3, ++ MMAL_VIDEO_LEVEL_H264_31, ++ MMAL_VIDEO_LEVEL_H264_32, ++ MMAL_VIDEO_LEVEL_H264_4, ++ MMAL_VIDEO_LEVEL_H264_41, ++ MMAL_VIDEO_LEVEL_H264_42, ++ MMAL_VIDEO_LEVEL_H264_5, ++ MMAL_VIDEO_LEVEL_H264_51, ++ MMAL_VIDEO_LEVEL_DUMMY = 0x7FFFFFFF ++}; ++ ++struct mmal_parameter_video_profile { ++ enum mmal_video_profile profile; ++ enum mmal_video_level level; ++}; ++ ++/* video parameters */ ++ ++enum mmal_parameter_video_type { ++ /** @ref MMAL_DISPLAYREGION_T */ ++ MMAL_PARAMETER_DISPLAYREGION = MMAL_PARAMETER_GROUP_VIDEO, ++ ++ /** @ref MMAL_PARAMETER_VIDEO_PROFILE_T */ ++ MMAL_PARAMETER_SUPPORTED_PROFILES, ++ ++ /** @ref MMAL_PARAMETER_VIDEO_PROFILE_T */ ++ MMAL_PARAMETER_PROFILE, ++ ++ /** @ref MMAL_PARAMETER_UINT32_T */ ++ MMAL_PARAMETER_INTRAPERIOD, ++ ++ /** @ref MMAL_PARAMETER_VIDEO_RATECONTROL_T */ ++ MMAL_PARAMETER_RATECONTROL, ++ ++ /** @ref MMAL_PARAMETER_VIDEO_NALUNITFORMAT_T */ ++ MMAL_PARAMETER_NALUNITFORMAT, ++ ++ /** @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_MINIMISE_FRAGMENTATION, ++ ++ /** @ref MMAL_PARAMETER_UINT32_T. ++ * Setting the value to zero resets to the default (one slice per ++ * frame). ++ */ ++ MMAL_PARAMETER_MB_ROWS_PER_SLICE, ++ ++ /** @ref MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION_T */ ++ MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION, ++ ++ /** @ref MMAL_PARAMETER_VIDEO_EEDE_ENABLE_T */ ++ MMAL_PARAMETER_VIDEO_EEDE_ENABLE, ++ ++ /** @ref MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE_T */ ++ MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE, ++ ++ /** @ref MMAL_PARAMETER_BOOLEAN_T. Request an I-frame. */ ++ MMAL_PARAMETER_VIDEO_REQUEST_I_FRAME, ++ /** @ref MMAL_PARAMETER_VIDEO_INTRA_REFRESH_T */ ++ MMAL_PARAMETER_VIDEO_INTRA_REFRESH, ++ ++ /** @ref MMAL_PARAMETER_BOOLEAN_T. */ ++ MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, ++ ++ /** @ref MMAL_PARAMETER_UINT32_T. Run-time bit rate control */ ++ MMAL_PARAMETER_VIDEO_BIT_RATE, ++ ++ /** @ref MMAL_PARAMETER_FRAME_RATE_T */ ++ MMAL_PARAMETER_VIDEO_FRAME_RATE, ++ ++ /** @ref MMAL_PARAMETER_UINT32_T. */ ++ MMAL_PARAMETER_VIDEO_ENCODE_MIN_QUANT, ++ ++ /** @ref MMAL_PARAMETER_UINT32_T. */ ++ MMAL_PARAMETER_VIDEO_ENCODE_MAX_QUANT, ++ ++ /** @ref MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL_T. */ ++ MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL, ++ ++ MMAL_PARAMETER_EXTRA_BUFFERS, /**< @ref MMAL_PARAMETER_UINT32_T. */ ++ /** @ref MMAL_PARAMETER_UINT32_T. ++ * Changing this parameter from the default can reduce frame rate ++ * because image buffers need to be re-pitched. ++ */ ++ MMAL_PARAMETER_VIDEO_ALIGN_HORIZ, ++ ++ /** @ref MMAL_PARAMETER_UINT32_T. ++ * Changing this parameter from the default can reduce frame rate ++ * because image buffers need to be re-pitched. ++ */ ++ MMAL_PARAMETER_VIDEO_ALIGN_VERT, ++ ++ /** @ref MMAL_PARAMETER_BOOLEAN_T. */ ++ MMAL_PARAMETER_VIDEO_DROPPABLE_PFRAMES, ++ ++ /** @ref MMAL_PARAMETER_UINT32_T. */ ++ MMAL_PARAMETER_VIDEO_ENCODE_INITIAL_QUANT, ++ ++ /**< @ref MMAL_PARAMETER_UINT32_T. */ ++ MMAL_PARAMETER_VIDEO_ENCODE_QP_P, ++ ++ /**< @ref MMAL_PARAMETER_UINT32_T. */ ++ MMAL_PARAMETER_VIDEO_ENCODE_RC_SLICE_DQUANT, ++ ++ /** @ref MMAL_PARAMETER_UINT32_T */ ++ MMAL_PARAMETER_VIDEO_ENCODE_FRAME_LIMIT_BITS, ++ ++ /** @ref MMAL_PARAMETER_UINT32_T. */ ++ MMAL_PARAMETER_VIDEO_ENCODE_PEAK_RATE, ++ ++ /* H264 specific parameters */ ++ ++ /** @ref MMAL_PARAMETER_BOOLEAN_T. */ ++ MMAL_PARAMETER_VIDEO_ENCODE_H264_DISABLE_CABAC, ++ ++ /** @ref MMAL_PARAMETER_BOOLEAN_T. */ ++ MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_LATENCY, ++ ++ /** @ref MMAL_PARAMETER_BOOLEAN_T. */ ++ MMAL_PARAMETER_VIDEO_ENCODE_H264_AU_DELIMITERS, ++ ++ /** @ref MMAL_PARAMETER_UINT32_T. */ ++ MMAL_PARAMETER_VIDEO_ENCODE_H264_DEBLOCK_IDC, ++ ++ /** @ref MMAL_PARAMETER_VIDEO_ENCODER_H264_MB_INTRA_MODES_T. */ ++ MMAL_PARAMETER_VIDEO_ENCODE_H264_MB_INTRA_MODE, ++ ++ /** @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_VIDEO_ENCODE_HEADER_ON_OPEN, ++ ++ /** @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_VIDEO_ENCODE_PRECODE_FOR_QP, ++ ++ /** @ref MMAL_PARAMETER_VIDEO_DRM_INIT_INFO_T. */ ++ MMAL_PARAMETER_VIDEO_DRM_INIT_INFO, ++ ++ /** @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_VIDEO_TIMESTAMP_FIFO, ++ ++ /** @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_VIDEO_DECODE_ERROR_CONCEALMENT, ++ ++ /** @ref MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER_T. */ ++ MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER, ++ ++ /** @ref MMAL_PARAMETER_BYTES_T */ ++ MMAL_PARAMETER_VIDEO_DECODE_CONFIG_VD3, ++ ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_VIDEO_ENCODE_H264_VCL_HRD_PARAMETERS, ++ ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_DELAY_HRD_FLAG, ++ ++ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER ++}; ++ ++/** Valid mirror modes */ ++enum mmal_parameter_mirror { ++ MMAL_PARAM_MIRROR_NONE, ++ MMAL_PARAM_MIRROR_VERTICAL, ++ MMAL_PARAM_MIRROR_HORIZONTAL, ++ MMAL_PARAM_MIRROR_BOTH, ++}; ++ ++enum mmal_parameter_displaytransform { ++ MMAL_DISPLAY_ROT0 = 0, ++ MMAL_DISPLAY_MIRROR_ROT0 = 1, ++ MMAL_DISPLAY_MIRROR_ROT180 = 2, ++ MMAL_DISPLAY_ROT180 = 3, ++ MMAL_DISPLAY_MIRROR_ROT90 = 4, ++ MMAL_DISPLAY_ROT270 = 5, ++ MMAL_DISPLAY_ROT90 = 6, ++ MMAL_DISPLAY_MIRROR_ROT270 = 7, ++}; ++ ++enum mmal_parameter_displaymode { ++ MMAL_DISPLAY_MODE_FILL = 0, ++ MMAL_DISPLAY_MODE_LETTERBOX = 1, ++}; ++ ++enum mmal_parameter_displayset { ++ MMAL_DISPLAY_SET_NONE = 0, ++ MMAL_DISPLAY_SET_NUM = 1, ++ MMAL_DISPLAY_SET_FULLSCREEN = 2, ++ MMAL_DISPLAY_SET_TRANSFORM = 4, ++ MMAL_DISPLAY_SET_DEST_RECT = 8, ++ MMAL_DISPLAY_SET_SRC_RECT = 0x10, ++ MMAL_DISPLAY_SET_MODE = 0x20, ++ MMAL_DISPLAY_SET_PIXEL = 0x40, ++ MMAL_DISPLAY_SET_NOASPECT = 0x80, ++ MMAL_DISPLAY_SET_LAYER = 0x100, ++ MMAL_DISPLAY_SET_COPYPROTECT = 0x200, ++ MMAL_DISPLAY_SET_ALPHA = 0x400, ++}; ++ ++/* rectangle, used lots so it gets its own struct */ ++struct vchiq_mmal_rect { ++ s32 x; ++ s32 y; ++ s32 width; ++ s32 height; ++}; ++ ++struct mmal_parameter_displayregion { ++ /** Bitfield that indicates which fields are set and should be ++ * used. All other fields will maintain their current value. ++ * \ref MMAL_DISPLAYSET_T defines the bits that can be ++ * combined. ++ */ ++ u32 set; ++ ++ /** Describes the display output device, with 0 typically ++ * being a directly connected LCD display. The actual values ++ * will depend on the hardware. Code using hard-wired numbers ++ * (e.g. 2) is certain to fail. ++ */ ++ ++ u32 display_num; ++ /** Indicates that we are using the full device screen area, ++ * rather than a window of the display. If zero, then ++ * dest_rect is used to specify a region of the display to ++ * use. ++ */ ++ ++ s32 fullscreen; ++ /** Indicates any rotation or flipping used to map frames onto ++ * the natural display orientation. ++ */ ++ u32 transform; /* enum mmal_parameter_displaytransform */ ++ ++ /** Where to display the frame within the screen, if ++ * fullscreen is zero. ++ */ ++ struct vchiq_mmal_rect dest_rect; ++ ++ /** Indicates which area of the frame to display. If all ++ * values are zero, the whole frame will be used. ++ */ ++ struct vchiq_mmal_rect src_rect; ++ ++ /** If set to non-zero, indicates that any display scaling ++ * should disregard the aspect ratio of the frame region being ++ * displayed. ++ */ ++ s32 noaspect; ++ ++ /** Indicates how the image should be scaled to fit the ++ * display. \code MMAL_DISPLAY_MODE_FILL \endcode indicates ++ * that the image should fill the screen by potentially ++ * cropping the frames. Setting \code mode \endcode to \code ++ * MMAL_DISPLAY_MODE_LETTERBOX \endcode indicates that all the ++ * source region should be displayed and black bars added if ++ * necessary. ++ */ ++ u32 mode; /* enum mmal_parameter_displaymode */ ++ ++ /** If non-zero, defines the width of a source pixel relative ++ * to \code pixel_y \endcode. If zero, then pixels default to ++ * being square. ++ */ ++ u32 pixel_x; ++ ++ /** If non-zero, defines the height of a source pixel relative ++ * to \code pixel_x \endcode. If zero, then pixels default to ++ * being square. ++ */ ++ u32 pixel_y; ++ ++ /** Sets the relative depth of the images, with greater values ++ * being in front of smaller values. ++ */ ++ u32 layer; ++ ++ /** Set to non-zero to ensure copy protection is used on ++ * output. ++ */ ++ s32 copyprotect_required; ++ ++ /** Level of opacity of the layer, where zero is fully ++ * transparent and 255 is fully opaque. ++ */ ++ u32 alpha; ++}; ++ ++#define MMAL_MAX_IMAGEFX_PARAMETERS 5 ++ ++struct mmal_parameter_imagefx_parameters { ++ enum mmal_parameter_imagefx effect; ++ u32 num_effect_params; ++ u32 effect_parameter[MMAL_MAX_IMAGEFX_PARAMETERS]; ++}; ++ ++#define MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS 4 ++#define MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES 2 ++#define MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN 16 ++ ++struct mmal_parameter_camera_info_camera_t { ++ u32 port_id; ++ u32 max_width; ++ u32 max_height; ++ u32 lens_present; ++ u8 camera_name[MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN]; ++}; ++ ++enum mmal_parameter_camera_info_flash_type_t { ++ /* Make values explicit to ensure they match values in config ini */ ++ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_XENON = 0, ++ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_LED = 1, ++ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_OTHER = 2, ++ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_MAX = 0x7FFFFFFF ++}; ++ ++struct mmal_parameter_camera_info_flash_t { ++ enum mmal_parameter_camera_info_flash_type_t flash_type; ++}; ++ ++struct mmal_parameter_camera_info_t { ++ u32 num_cameras; ++ u32 num_flashes; ++ struct mmal_parameter_camera_info_camera_t ++ cameras[MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS]; ++ struct mmal_parameter_camera_info_flash_t ++ flashes[MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES]; ++}; ++ ++#endif +--- /dev/null ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h +@@ -0,0 +1,166 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Broadcom BM2835 V4L2 driver ++ * ++ * Copyright © 2013 Raspberry Pi (Trading) Ltd. ++ * ++ * Authors: Vincent Sanders @ Collabora ++ * Dave Stevenson @ Broadcom ++ * (now dave.stevenson@raspberrypi.org) ++ * Simon Mellor @ Broadcom ++ * Luke Diamand @ Broadcom ++ * ++ * MMAL interface to VCHIQ message passing ++ */ ++ ++#ifndef MMAL_VCHIQ_H ++#define MMAL_VCHIQ_H ++ ++#include "mmal-msg-format.h" ++ ++#define MAX_PORT_COUNT 4 ++ ++/* Maximum size of the format extradata. */ ++#define MMAL_FORMAT_EXTRADATA_MAX_SIZE 128 ++ ++struct vchiq_mmal_instance; ++ ++enum vchiq_mmal_es_type { ++ MMAL_ES_TYPE_UNKNOWN, /**< Unknown elementary stream type */ ++ MMAL_ES_TYPE_CONTROL, /**< Elementary stream of control commands */ ++ MMAL_ES_TYPE_AUDIO, /**< Audio elementary stream */ ++ MMAL_ES_TYPE_VIDEO, /**< Video elementary stream */ ++ MMAL_ES_TYPE_SUBPICTURE /**< Sub-picture elementary stream */ ++}; ++ ++struct vchiq_mmal_port_buffer { ++ unsigned int num; /* number of buffers */ ++ u32 size; /* size of buffers */ ++ u32 alignment; /* alignment of buffers */ ++}; ++ ++struct vchiq_mmal_port; ++ ++typedef void (*vchiq_mmal_buffer_cb)( ++ struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port, ++ int status, struct mmal_buffer *buffer, ++ unsigned long length, u32 mmal_flags, s64 dts, s64 pts); ++ ++struct vchiq_mmal_port { ++ bool enabled; ++ u32 handle; ++ u32 type; /* port type, cached to use on port info set */ ++ u32 index; /* port index, cached to use on port info set */ ++ ++ /* component port belongs to, allows simple deref */ ++ struct vchiq_mmal_component *component; ++ ++ struct vchiq_mmal_port *connected; /* port conencted to */ ++ ++ /* buffer info */ ++ struct vchiq_mmal_port_buffer minimum_buffer; ++ struct vchiq_mmal_port_buffer recommended_buffer; ++ struct vchiq_mmal_port_buffer current_buffer; ++ ++ /* stream format */ ++ struct mmal_es_format_local format; ++ /* elementary stream format */ ++ union mmal_es_specific_format es; ++ ++ /* data buffers to fill */ ++ struct list_head buffers; ++ /* lock to serialise adding and removing buffers from list */ ++ spinlock_t slock; ++ ++ /* Count of buffers the VPU has yet to return */ ++ atomic_t buffers_with_vpu; ++ /* callback on buffer completion */ ++ vchiq_mmal_buffer_cb buffer_cb; ++ /* callback context */ ++ void *cb_ctx; ++}; ++ ++struct vchiq_mmal_component { ++ bool enabled; ++ u32 handle; /* VideoCore handle for component */ ++ u32 inputs; /* Number of input ports */ ++ u32 outputs; /* Number of output ports */ ++ u32 clocks; /* Number of clock ports */ ++ struct vchiq_mmal_port control; /* control port */ ++ struct vchiq_mmal_port input[MAX_PORT_COUNT]; /* input ports */ ++ struct vchiq_mmal_port output[MAX_PORT_COUNT]; /* output ports */ ++ struct vchiq_mmal_port clock[MAX_PORT_COUNT]; /* clock ports */ ++}; ++ ++int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance); ++int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance); ++ ++/* Initialise a mmal component and its ports ++ * ++ */ ++int vchiq_mmal_component_init( ++ struct vchiq_mmal_instance *instance, ++ const char *name, ++ struct vchiq_mmal_component **component_out); ++ ++int vchiq_mmal_component_finalise( ++ struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_component *component); ++ ++int vchiq_mmal_component_enable( ++ struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_component *component); ++ ++int vchiq_mmal_component_disable( ++ struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_component *component); ++ ++/* enable a mmal port ++ * ++ * enables a port and if a buffer callback provided enque buffer ++ * headers as appropriate for the port. ++ */ ++int vchiq_mmal_port_enable( ++ struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port, ++ vchiq_mmal_buffer_cb buffer_cb); ++ ++/* disable a port ++ * ++ * disable a port will dequeue any pending buffers ++ */ ++int vchiq_mmal_port_disable(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port); ++ ++int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port, ++ u32 parameter, ++ void *value, ++ u32 value_size); ++ ++int vchiq_mmal_port_parameter_get(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port, ++ u32 parameter, ++ void *value, ++ u32 *value_size); ++ ++int vchiq_mmal_port_set_format(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port); ++ ++int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *src, ++ struct vchiq_mmal_port *dst); ++ ++int vchiq_mmal_version(struct vchiq_mmal_instance *instance, ++ u32 *major_out, ++ u32 *minor_out); ++ ++int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port, ++ struct mmal_buffer *buf); ++ ++int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance, ++ struct mmal_buffer *buf); ++int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf); ++#endif /* MMAL_VCHIQ_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0265-staging-bcm2835-camera-Correct-V4L2_CID_COLORFX_CBCR.patch b/target/linux/brcm2708/patches-4.19/950-0265-staging-bcm2835-camera-Correct-V4L2_CID_COLORFX_CBCR.patch deleted file mode 100644 index 1b81d5d336..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0265-staging-bcm2835-camera-Correct-V4L2_CID_COLORFX_CBCR.patch +++ /dev/null @@ -1,34 +0,0 @@ -From d62b10483e89fbd3adc2cde272234ad5300d9a42 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 8 Oct 2018 18:26:15 +0100 -Subject: [PATCH 265/703] staging: bcm2835-camera: Correct - V4L2_CID_COLORFX_CBCR behaviour - -With V4L2_CID_COLORFX_CBCR calling ctrl_set_colfx it was incorrectly -assigning the colour values to the enable field of dev->colourfx -instead of the u and v fields. - -Correct the assignments. - -Reported as a Coverity issue -Detected by CoverityScan CID#1419711 ("Unused value") - -Reported-by: Colin Ian King -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/bcm2835-camera/controls.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-camera/controls.c -+++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c -@@ -578,8 +578,8 @@ static int ctrl_set_colfx(struct bm2835_ - - control = &dev->component[COMP_CAMERA]->control; - -- dev->colourfx.enable = (ctrl->val & 0xff00) >> 8; -- dev->colourfx.enable = ctrl->val & 0xff; -+ dev->colourfx.u = (ctrl->val & 0xff00) >> 8; -+ dev->colourfx.v = ctrl->val & 0xff; - - ret = vchiq_mmal_port_parameter_set(dev->instance, control, - MMAL_PARAMETER_COLOUR_EFFECT, diff --git a/target/linux/brcm2708/patches-4.19/950-0265-staging-mmal-vchiq-Allocate-and-free-components-as-r.patch b/target/linux/brcm2708/patches-4.19/950-0265-staging-mmal-vchiq-Allocate-and-free-components-as-r.patch new file mode 100644 index 0000000000..c15273a547 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0265-staging-mmal-vchiq-Allocate-and-free-components-as-r.patch @@ -0,0 +1,107 @@ +From 0be8a2fb0d0986f48ba31375f9c5a8620aa82edd Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 24 Sep 2018 16:51:13 +0100 +Subject: [PATCH 265/725] staging: mmal-vchiq: Allocate and free components as + required + +The existing code assumed that there would only ever be 4 components, +and never freed the entries once used. +Allow arbitrary creation and destruction of components. + +Signed-off-by: Dave Stevenson +--- + .../vc04_services/vchiq-mmal/mmal-vchiq.c | 29 ++++++++++++------- + .../vc04_services/vchiq-mmal/mmal-vchiq.h | 1 + + 2 files changed, 20 insertions(+), 10 deletions(-) + +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +@@ -38,8 +38,11 @@ MODULE_AUTHOR("Dave Stevenson, vchiq_mutex)) + return -EINTR; + +- if (instance->component_idx == VCHIQ_MMAL_MAX_COMPONENTS) { ++ for (idx = 0; idx < VCHIQ_MMAL_MAX_COMPONENTS; idx++) { ++ if (!instance->component[idx].in_use) { ++ component = &instance->component[idx]; ++ component->in_use = 1; ++ break; ++ } ++ } ++ ++ if (!component) { + ret = -EINVAL; /* todo is this correct error? */ + goto unlock; + } + +- component = &instance->component[instance->component_idx]; +- + ret = create_component(instance, component, name); + if (ret < 0) { + pr_err("%s: failed to create component %d (Not enough GPU mem?)\n", +@@ -1694,8 +1701,6 @@ int vchiq_mmal_component_init(struct vch + goto release_component; + } + +- instance->component_idx++; +- + *component_out = component; + + mutex_unlock(&instance->vchiq_mutex); +@@ -1705,6 +1710,8 @@ int vchiq_mmal_component_init(struct vch + release_component: + destroy_component(instance, component); + unlock: ++ if (component) ++ component->in_use = 0; + mutex_unlock(&instance->vchiq_mutex); + + return ret; +@@ -1727,6 +1734,8 @@ int vchiq_mmal_component_finalise(struct + + ret = destroy_component(instance, component); + ++ component->in_use = 0; ++ + mutex_unlock(&instance->vchiq_mutex); + + return ret; +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h +@@ -82,6 +82,7 @@ struct vchiq_mmal_port { + }; + + struct vchiq_mmal_component { ++ u32 in_use:1; + bool enabled; + u32 handle; /* VideoCore handle for component */ + u32 inputs; /* Number of input ports */ diff --git a/target/linux/brcm2708/patches-4.19/950-0266-staging-bcm2835-camera-Remove-amend-some-obsolete-co.patch b/target/linux/brcm2708/patches-4.19/950-0266-staging-bcm2835-camera-Remove-amend-some-obsolete-co.patch deleted file mode 100644 index c7f6f28d8f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0266-staging-bcm2835-camera-Remove-amend-some-obsolete-co.patch +++ /dev/null @@ -1,49 +0,0 @@ -From dac082334ccbfa6a051fdc48700f64e8412169d5 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 28 Sep 2018 10:22:26 +0100 -Subject: [PATCH 266/703] staging: bcm2835-camera: Remove/amend some obsolete - comments - -Remove a todo which has been done. -Remove a template line that was redundant. -Make a comment clearer as to the non-obvious meaning of a field. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/bcm2835-camera/controls.c | 11 +---------- - 1 file changed, 1 insertion(+), 10 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-camera/controls.c -+++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c -@@ -965,10 +965,6 @@ static const struct bm2835_mmal_v4l2_ctr - &ctrl_set_value, - false - }, --/* { -- * 0, MMAL_CONTROL_TYPE_CLUSTER, 3, 1, 0, NULL, 0, NULL -- * }, -- */ - { - V4L2_CID_EXPOSURE_AUTO, MMAL_CONTROL_TYPE_STD_MENU, - ~0x03, V4L2_EXPOSURE_APERTURE_PRIORITY, V4L2_EXPOSURE_AUTO, 0, -@@ -976,11 +972,6 @@ static const struct bm2835_mmal_v4l2_ctr - &ctrl_set_exposure, - false - }, --/* todo this needs mixing in with set exposure -- * { -- * V4L2_CID_SCENE_MODE, MMAL_CONTROL_TYPE_STD_MENU, -- * }, -- */ - { - V4L2_CID_EXPOSURE_ABSOLUTE, MMAL_CONTROL_TYPE_STD, - /* Units of 100usecs */ -@@ -1146,7 +1137,7 @@ static const struct bm2835_mmal_v4l2_ctr - }, - { - V4L2_CID_SCENE_MODE, MMAL_CONTROL_TYPE_STD_MENU, -- -1, /* Min is computed at runtime */ -+ -1, /* Min (mask) is computed at runtime */ - V4L2_SCENE_MODE_TEXT, - V4L2_SCENE_MODE_NONE, 1, NULL, - MMAL_PARAMETER_PROFILE, diff --git a/target/linux/brcm2708/patches-4.19/950-0266-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch b/target/linux/brcm2708/patches-4.19/950-0266-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch new file mode 100644 index 0000000000..846c896b82 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0266-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch @@ -0,0 +1,93 @@ +From 4938924a490f11659b8661bbe9a7f250c2a62237 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 29 Oct 2018 16:20:46 +0000 +Subject: [PATCH 266/725] staging: mmal-vchiq: Avoid use of bool in structures + +Fixes up a checkpatch error "Avoid using bool structure members +because of possible alignment issues". + +Signed-off-by: Dave Stevenson +--- + .../staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 14 +++++++------- + .../staging/vc04_services/vchiq-mmal/mmal-vchiq.h | 4 ++-- + 2 files changed, 9 insertions(+), 9 deletions(-) + +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +@@ -861,9 +861,9 @@ static int port_info_get(struct vchiq_mm + goto release_msg; + + if (rmsg->u.port_info_get_reply.port.is_enabled == 0) +- port->enabled = false; ++ port->enabled = 0; + else +- port->enabled = true; ++ port->enabled = 1; + + /* copy the values out of the message */ + port->handle = rmsg->u.port_info_get_reply.port_handle; +@@ -1300,7 +1300,7 @@ static int port_disable(struct vchiq_mma + if (!port->enabled) + return 0; + +- port->enabled = false; ++ port->enabled = 0; + + ret = port_action_port(instance, port, + MMAL_MSG_PORT_ACTION_TYPE_DISABLE); +@@ -1352,7 +1352,7 @@ static int port_enable(struct vchiq_mmal + if (ret) + goto done; + +- port->enabled = true; ++ port->enabled = 1; + + if (port->buffer_cb) { + /* send buffer headers to videocore */ +@@ -1524,7 +1524,7 @@ int vchiq_mmal_port_connect_tunnel(struc + pr_err("failed disconnecting src port\n"); + goto release_unlock; + } +- src->connected->enabled = false; ++ src->connected->enabled = 0; + src->connected = NULL; + } + +@@ -1760,7 +1760,7 @@ int vchiq_mmal_component_enable(struct v + + ret = enable_component(instance, component); + if (ret == 0) +- component->enabled = true; ++ component->enabled = 1; + + mutex_unlock(&instance->vchiq_mutex); + +@@ -1786,7 +1786,7 @@ int vchiq_mmal_component_disable(struct + + ret = disable_component(instance, component); + if (ret == 0) +- component->enabled = false; ++ component->enabled = 0; + + mutex_unlock(&instance->vchiq_mutex); + +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h +@@ -48,7 +48,7 @@ typedef void (*vchiq_mmal_buffer_cb)( + unsigned long length, u32 mmal_flags, s64 dts, s64 pts); + + struct vchiq_mmal_port { +- bool enabled; ++ u32 enabled:1; + u32 handle; + u32 type; /* port type, cached to use on port info set */ + u32 index; /* port index, cached to use on port info set */ +@@ -83,7 +83,7 @@ struct vchiq_mmal_port { + + struct vchiq_mmal_component { + u32 in_use:1; +- bool enabled; ++ u32 enabled:1; + u32 handle; /* VideoCore handle for component */ + u32 inputs; /* Number of input ports */ + u32 outputs; /* Number of output ports */ diff --git a/target/linux/brcm2708/patches-4.19/950-0267-staging-mmal-vchiq-Make-timeout-a-defined-parameter.patch b/target/linux/brcm2708/patches-4.19/950-0267-staging-mmal-vchiq-Make-timeout-a-defined-parameter.patch new file mode 100644 index 0000000000..d9bda52107 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0267-staging-mmal-vchiq-Make-timeout-a-defined-parameter.patch @@ -0,0 +1,38 @@ +From 609bd5dbe6c1f9cbe2fc50124e4e8a99e4a5042a Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 24 Sep 2018 16:57:09 +0100 +Subject: [PATCH 267/725] staging: mmal-vchiq: Make timeout a defined parameter + +The timeout period for VPU communications is a useful thing +to extend when debugging. +Set it via a define, rather than a magic number buried in the code. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +@@ -44,6 +44,12 @@ MODULE_VERSION("0.0.1"); + */ + #define VCHIQ_MMAL_MAX_COMPONENTS 64 + ++/* ++ * Timeout for synchronous msg responses in seconds. ++ * Helpful to increase this if stopping in the VPU debugger. ++ */ ++#define SYNC_MSG_TIMEOUT 3 ++ + /*#define FULL_MSG_DUMP 1*/ + + #ifdef DEBUG +@@ -692,7 +698,7 @@ static int send_synchronous_mmal_msg(str + } + + timeout = wait_for_completion_timeout(&msg_context->u.sync.cmplt, +- 3 * HZ); ++ SYNC_MSG_TIMEOUT * HZ); + if (timeout == 0) { + pr_err("timed out waiting for sync completion\n"); + ret = -ETIME; diff --git a/target/linux/brcm2708/patches-4.19/950-0267-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch b/target/linux/brcm2708/patches-4.19/950-0267-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch deleted file mode 100644 index 13ee7ba190..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0267-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch +++ /dev/null @@ -1,5633 +0,0 @@ -From abd417b71f4b157cb183cab26620d08c303ce805 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 24 Sep 2018 16:30:37 +0100 -Subject: [PATCH 267/703] staging: vc04_services: Split vchiq-mmal into a - module - -In preparation for adding a video codec V4L2 module which also -wants to use vchiq-mmal functions, split it out into an -independent module. -The minimum number of changes have been made to achieve this -(eg straight moves where possible) so existing checkpatch -errors will still be present. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/Kconfig | 1 + - drivers/staging/vc04_services/Makefile | 1 + - .../vc04_services/bcm2835-camera/Kconfig | 2 +- - .../vc04_services/bcm2835-camera/Makefile | 4 ++-- - .../staging/vc04_services/vchiq-mmal/Kconfig | 7 ++++++ - .../staging/vc04_services/vchiq-mmal/Makefile | 8 +++++++ - .../mmal-common.h | 0 - .../mmal-encodings.h | 0 - .../mmal-msg-common.h | 0 - .../mmal-msg-format.h | 0 - .../mmal-msg-port.h | 0 - .../{bcm2835-camera => vchiq-mmal}/mmal-msg.h | 0 - .../mmal-parameters.h | 0 - .../mmal-vchiq.c | 22 +++++++++++++++++++ - .../mmal-vchiq.h | 0 - 15 files changed, 42 insertions(+), 3 deletions(-) - create mode 100644 drivers/staging/vc04_services/vchiq-mmal/Kconfig - create mode 100644 drivers/staging/vc04_services/vchiq-mmal/Makefile - rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-common.h (100%) - rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-encodings.h (100%) - rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-msg-common.h (100%) - rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-msg-format.h (100%) - rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-msg-port.h (100%) - rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-msg.h (100%) - rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-parameters.h (100%) - rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-vchiq.c (98%) - rename drivers/staging/vc04_services/{bcm2835-camera => vchiq-mmal}/mmal-vchiq.h (100%) - ---- a/drivers/staging/vc04_services/Kconfig -+++ b/drivers/staging/vc04_services/Kconfig -@@ -21,6 +21,7 @@ config BCM2835_VCHIQ - source "drivers/staging/vc04_services/bcm2835-audio/Kconfig" - - source "drivers/staging/vc04_services/bcm2835-camera/Kconfig" -+source "drivers/staging/vc04_services/vchiq-mmal/Kconfig" - - endif - ---- a/drivers/staging/vc04_services/Makefile -+++ b/drivers/staging/vc04_services/Makefile -@@ -12,6 +12,7 @@ vchiq-objs := \ - - obj-$(CONFIG_SND_BCM2835) += bcm2835-audio/ - obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-camera/ -+obj-$(CONFIG_BCM2835_VCHIQ_MMAL) += vchiq-mmal/ - - ccflags-y += -Idrivers/staging/vc04_services -D__VCCOREVER__=0x04000000 - ---- a/drivers/staging/vc04_services/bcm2835-camera/Kconfig -+++ b/drivers/staging/vc04_services/bcm2835-camera/Kconfig -@@ -2,7 +2,7 @@ config VIDEO_BCM2835 - tristate "BCM2835 Camera" - depends on MEDIA_SUPPORT - depends on VIDEO_V4L2 && (ARCH_BCM2835 || COMPILE_TEST) -- select BCM2835_VCHIQ -+ select BCM2835_VCHIQ_MMAL - select VIDEOBUF2_VMALLOC - select BTREE - help ---- a/drivers/staging/vc04_services/bcm2835-camera/Makefile -+++ b/drivers/staging/vc04_services/bcm2835-camera/Makefile -@@ -1,11 +1,11 @@ - # SPDX-License-Identifier: GPL-2.0 - bcm2835-v4l2-$(CONFIG_VIDEO_BCM2835) := \ - bcm2835-camera.o \ -- controls.o \ -- mmal-vchiq.o -+ controls.o - - obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-v4l2.o - - ccflags-y += \ - -Idrivers/staging/vc04_services \ -+ -Idrivers/staging/vc04_services/vchiq-mmal \ - -D__VCCOREVER__=0x04000000 ---- /dev/null -+++ b/drivers/staging/vc04_services/vchiq-mmal/Kconfig -@@ -0,0 +1,7 @@ -+config BCM2835_VCHIQ_MMAL -+ tristate "BCM2835 MMAL VCHIQ service" -+ depends on (ARCH_BCM2835 || COMPILE_TEST) -+ select BCM2835_VCHIQ -+ help -+ Enables the MMAL API over VCHIQ as used for the -+ majority of the multimedia services on VideoCore. ---- /dev/null -+++ b/drivers/staging/vc04_services/vchiq-mmal/Makefile -@@ -0,0 +1,8 @@ -+# SPDX-License-Identifier: GPL-2.0 -+bcm2835-mmal-vchiq-objs := mmal-vchiq.o -+ -+obj-$(CONFIG_BCM2835_VCHIQ_MMAL) += bcm2835-mmal-vchiq.o -+ -+ccflags-y += \ -+ -Idrivers/staging/vc04_services \ -+ -D__VCCOREVER__=0x04000000 ---- /dev/null -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -0,0 +1,1921 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Broadcom BM2835 V4L2 driver -+ * -+ * Copyright © 2013 Raspberry Pi (Trading) Ltd. -+ * -+ * Authors: Vincent Sanders @ Collabora -+ * Dave Stevenson @ Broadcom -+ * (now dave.stevenson@raspberrypi.org) -+ * Simon Mellor @ Broadcom -+ * Luke Diamand @ Broadcom -+ * -+ * V4L2 driver MMAL vchiq interface code -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mmal-common.h" -+#include "mmal-vchiq.h" -+#include "mmal-msg.h" -+ -+#define USE_VCHIQ_ARM -+#include "interface/vchi/vchi.h" -+ -+MODULE_DESCRIPTION("BCM2835 MMAL VCHIQ interface"); -+MODULE_AUTHOR("Dave Stevenson, "); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION("0.0.1"); -+ -+/* maximum number of components supported */ -+#define VCHIQ_MMAL_MAX_COMPONENTS 4 -+ -+/*#define FULL_MSG_DUMP 1*/ -+ -+#ifdef DEBUG -+static const char *const msg_type_names[] = { -+ "UNKNOWN", -+ "QUIT", -+ "SERVICE_CLOSED", -+ "GET_VERSION", -+ "COMPONENT_CREATE", -+ "COMPONENT_DESTROY", -+ "COMPONENT_ENABLE", -+ "COMPONENT_DISABLE", -+ "PORT_INFO_GET", -+ "PORT_INFO_SET", -+ "PORT_ACTION", -+ "BUFFER_FROM_HOST", -+ "BUFFER_TO_HOST", -+ "GET_STATS", -+ "PORT_PARAMETER_SET", -+ "PORT_PARAMETER_GET", -+ "EVENT_TO_HOST", -+ "GET_CORE_STATS_FOR_PORT", -+ "OPAQUE_ALLOCATOR", -+ "CONSUME_MEM", -+ "LMK", -+ "OPAQUE_ALLOCATOR_DESC", -+ "DRM_GET_LHS32", -+ "DRM_GET_TIME", -+ "BUFFER_FROM_HOST_ZEROLEN", -+ "PORT_FLUSH", -+ "HOST_LOG", -+}; -+#endif -+ -+static const char *const port_action_type_names[] = { -+ "UNKNOWN", -+ "ENABLE", -+ "DISABLE", -+ "FLUSH", -+ "CONNECT", -+ "DISCONNECT", -+ "SET_REQUIREMENTS", -+}; -+ -+#if defined(DEBUG) -+#if defined(FULL_MSG_DUMP) -+#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE) \ -+ do { \ -+ pr_debug(TITLE" type:%s(%d) length:%d\n", \ -+ msg_type_names[(MSG)->h.type], \ -+ (MSG)->h.type, (MSG_LEN)); \ -+ print_hex_dump(KERN_DEBUG, "<h.type], \ -+ (MSG)->h.type, (MSG_LEN)); \ -+ } -+#endif -+#else -+#define DBG_DUMP_MSG(MSG, MSG_LEN, TITLE) -+#endif -+ -+struct vchiq_mmal_instance; -+ -+/* normal message context */ -+struct mmal_msg_context { -+ struct vchiq_mmal_instance *instance; -+ -+ /* Index in the context_map idr so that we can find the -+ * mmal_msg_context again when servicing the VCHI reply. -+ */ -+ int handle; -+ -+ union { -+ struct { -+ /* work struct for buffer_cb callback */ -+ struct work_struct work; -+ /* work struct for deferred callback */ -+ struct work_struct buffer_to_host_work; -+ /* mmal instance */ -+ struct vchiq_mmal_instance *instance; -+ /* mmal port */ -+ struct vchiq_mmal_port *port; -+ /* actual buffer used to store bulk reply */ -+ struct mmal_buffer *buffer; -+ /* amount of buffer used */ -+ unsigned long buffer_used; -+ /* MMAL buffer flags */ -+ u32 mmal_flags; -+ /* Presentation and Decode timestamps */ -+ s64 pts; -+ s64 dts; -+ -+ int status; /* context status */ -+ -+ } bulk; /* bulk data */ -+ -+ struct { -+ /* message handle to release */ -+ VCHI_HELD_MSG_T msg_handle; -+ /* pointer to received message */ -+ struct mmal_msg *msg; -+ /* received message length */ -+ u32 msg_len; -+ /* completion upon reply */ -+ struct completion cmplt; -+ } sync; /* synchronous response */ -+ } u; -+ -+}; -+ -+struct vchiq_mmal_instance { -+ VCHI_SERVICE_HANDLE_T handle; -+ -+ /* ensure serialised access to service */ -+ struct mutex vchiq_mutex; -+ -+ /* vmalloc page to receive scratch bulk xfers into */ -+ void *bulk_scratch; -+ -+ struct idr context_map; -+ /* protect accesses to context_map */ -+ struct mutex context_map_lock; -+ -+ /* component to use next */ -+ int component_idx; -+ struct vchiq_mmal_component component[VCHIQ_MMAL_MAX_COMPONENTS]; -+ -+ /* ordered workqueue to process all bulk operations */ -+ struct workqueue_struct *bulk_wq; -+}; -+ -+static struct mmal_msg_context * -+get_msg_context(struct vchiq_mmal_instance *instance) -+{ -+ struct mmal_msg_context *msg_context; -+ int handle; -+ -+ /* todo: should this be allocated from a pool to avoid kzalloc */ -+ msg_context = kzalloc(sizeof(*msg_context), GFP_KERNEL); -+ -+ if (!msg_context) -+ return ERR_PTR(-ENOMEM); -+ -+ /* Create an ID that will be passed along with our message so -+ * that when we service the VCHI reply, we can look up what -+ * message is being replied to. -+ */ -+ mutex_lock(&instance->context_map_lock); -+ handle = idr_alloc(&instance->context_map, msg_context, -+ 0, 0, GFP_KERNEL); -+ mutex_unlock(&instance->context_map_lock); -+ -+ if (handle < 0) { -+ kfree(msg_context); -+ return ERR_PTR(handle); -+ } -+ -+ msg_context->instance = instance; -+ msg_context->handle = handle; -+ -+ return msg_context; -+} -+ -+static struct mmal_msg_context * -+lookup_msg_context(struct vchiq_mmal_instance *instance, int handle) -+{ -+ return idr_find(&instance->context_map, handle); -+} -+ -+static void -+release_msg_context(struct mmal_msg_context *msg_context) -+{ -+ struct vchiq_mmal_instance *instance = msg_context->instance; -+ -+ mutex_lock(&instance->context_map_lock); -+ idr_remove(&instance->context_map, msg_context->handle); -+ mutex_unlock(&instance->context_map_lock); -+ kfree(msg_context); -+} -+ -+/* deals with receipt of event to host message */ -+static void event_to_host_cb(struct vchiq_mmal_instance *instance, -+ struct mmal_msg *msg, u32 msg_len) -+{ -+ pr_debug("unhandled event\n"); -+ pr_debug("component:%u port type:%d num:%d cmd:0x%x length:%d\n", -+ msg->u.event_to_host.client_component, -+ msg->u.event_to_host.port_type, -+ msg->u.event_to_host.port_num, -+ msg->u.event_to_host.cmd, msg->u.event_to_host.length); -+} -+ -+/* workqueue scheduled callback -+ * -+ * we do this because it is important we do not call any other vchiq -+ * sync calls from witin the message delivery thread -+ */ -+static void buffer_work_cb(struct work_struct *work) -+{ -+ struct mmal_msg_context *msg_context = -+ container_of(work, struct mmal_msg_context, u.bulk.work); -+ -+ atomic_dec(&msg_context->u.bulk.port->buffers_with_vpu); -+ -+ msg_context->u.bulk.port->buffer_cb(msg_context->u.bulk.instance, -+ msg_context->u.bulk.port, -+ msg_context->u.bulk.status, -+ msg_context->u.bulk.buffer, -+ msg_context->u.bulk.buffer_used, -+ msg_context->u.bulk.mmal_flags, -+ msg_context->u.bulk.dts, -+ msg_context->u.bulk.pts); -+} -+ -+/* workqueue scheduled callback to handle receiving buffers -+ * -+ * VCHI will allow up to 4 bulk receives to be scheduled before blocking. -+ * If we block in the service_callback context then we can't process the -+ * VCHI_CALLBACK_BULK_RECEIVED message that would otherwise allow the blocked -+ * vchi_bulk_queue_receive() call to complete. -+ */ -+static void buffer_to_host_work_cb(struct work_struct *work) -+{ -+ struct mmal_msg_context *msg_context = -+ container_of(work, struct mmal_msg_context, -+ u.bulk.buffer_to_host_work); -+ struct vchiq_mmal_instance *instance = msg_context->instance; -+ unsigned long len = msg_context->u.bulk.buffer_used; -+ int ret; -+ -+ if (!len) -+ /* Dummy receive to ensure the buffers remain in order */ -+ len = 8; -+ /* queue the bulk submission */ -+ vchi_service_use(instance->handle); -+ ret = vchi_bulk_queue_receive(instance->handle, -+ msg_context->u.bulk.buffer->buffer, -+ /* Actual receive needs to be a multiple -+ * of 4 bytes -+ */ -+ (len + 3) & ~3, -+ VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE | -+ VCHI_FLAGS_BLOCK_UNTIL_QUEUED, -+ msg_context); -+ -+ vchi_service_release(instance->handle); -+ -+ if (ret != 0) -+ pr_err("%s: ctx: %p, vchi_bulk_queue_receive failed %d\n", -+ __func__, msg_context, ret); -+} -+ -+/* enqueue a bulk receive for a given message context */ -+static int bulk_receive(struct vchiq_mmal_instance *instance, -+ struct mmal_msg *msg, -+ struct mmal_msg_context *msg_context) -+{ -+ unsigned long rd_len; -+ -+ rd_len = msg->u.buffer_from_host.buffer_header.length; -+ -+ if (!msg_context->u.bulk.buffer) { -+ pr_err("bulk.buffer not configured - error in buffer_from_host\n"); -+ -+ /* todo: this is a serious error, we should never have -+ * committed a buffer_to_host operation to the mmal -+ * port without the buffer to back it up (underflow -+ * handling) and there is no obvious way to deal with -+ * this - how is the mmal servie going to react when -+ * we fail to do the xfer and reschedule a buffer when -+ * it arrives? perhaps a starved flag to indicate a -+ * waiting bulk receive? -+ */ -+ -+ return -EINVAL; -+ } -+ -+ /* ensure we do not overrun the available buffer */ -+ if (rd_len > msg_context->u.bulk.buffer->buffer_size) { -+ rd_len = msg_context->u.bulk.buffer->buffer_size; -+ pr_warn("short read as not enough receive buffer space\n"); -+ /* todo: is this the correct response, what happens to -+ * the rest of the message data? -+ */ -+ } -+ -+ /* store length */ -+ msg_context->u.bulk.buffer_used = rd_len; -+ msg_context->u.bulk.dts = msg->u.buffer_from_host.buffer_header.dts; -+ msg_context->u.bulk.pts = msg->u.buffer_from_host.buffer_header.pts; -+ -+ queue_work(msg_context->instance->bulk_wq, -+ &msg_context->u.bulk.buffer_to_host_work); -+ -+ return 0; -+} -+ -+/* data in message, memcpy from packet into output buffer */ -+static int inline_receive(struct vchiq_mmal_instance *instance, -+ struct mmal_msg *msg, -+ struct mmal_msg_context *msg_context) -+{ -+ memcpy(msg_context->u.bulk.buffer->buffer, -+ msg->u.buffer_from_host.short_data, -+ msg->u.buffer_from_host.payload_in_message); -+ -+ msg_context->u.bulk.buffer_used = -+ msg->u.buffer_from_host.payload_in_message; -+ -+ return 0; -+} -+ -+/* queue the buffer availability with MMAL_MSG_TYPE_BUFFER_FROM_HOST */ -+static int -+buffer_from_host(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port, struct mmal_buffer *buf) -+{ -+ struct mmal_msg_context *msg_context; -+ struct mmal_msg m; -+ int ret; -+ -+ if (!port->enabled) -+ return -EINVAL; -+ -+ pr_debug("instance:%p buffer:%p\n", instance->handle, buf); -+ -+ /* get context */ -+ if (!buf->msg_context) { -+ pr_err("%s: msg_context not allocated, buf %p\n", __func__, -+ buf); -+ return -EINVAL; -+ } -+ msg_context = buf->msg_context; -+ -+ /* store bulk message context for when data arrives */ -+ msg_context->u.bulk.instance = instance; -+ msg_context->u.bulk.port = port; -+ msg_context->u.bulk.buffer = buf; -+ msg_context->u.bulk.buffer_used = 0; -+ -+ /* initialise work structure ready to schedule callback */ -+ INIT_WORK(&msg_context->u.bulk.work, buffer_work_cb); -+ INIT_WORK(&msg_context->u.bulk.buffer_to_host_work, -+ buffer_to_host_work_cb); -+ -+ atomic_inc(&port->buffers_with_vpu); -+ -+ /* prep the buffer from host message */ -+ memset(&m, 0xbc, sizeof(m)); /* just to make debug clearer */ -+ -+ m.h.type = MMAL_MSG_TYPE_BUFFER_FROM_HOST; -+ m.h.magic = MMAL_MAGIC; -+ m.h.context = msg_context->handle; -+ m.h.status = 0; -+ -+ /* drvbuf is our private data passed back */ -+ m.u.buffer_from_host.drvbuf.magic = MMAL_MAGIC; -+ m.u.buffer_from_host.drvbuf.component_handle = port->component->handle; -+ m.u.buffer_from_host.drvbuf.port_handle = port->handle; -+ m.u.buffer_from_host.drvbuf.client_context = msg_context->handle; -+ -+ /* buffer header */ -+ m.u.buffer_from_host.buffer_header.cmd = 0; -+ m.u.buffer_from_host.buffer_header.data = -+ (u32)(unsigned long)buf->buffer; -+ m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size; -+ m.u.buffer_from_host.buffer_header.length = 0; /* nothing used yet */ -+ m.u.buffer_from_host.buffer_header.offset = 0; /* no offset */ -+ m.u.buffer_from_host.buffer_header.flags = 0; /* no flags */ -+ m.u.buffer_from_host.buffer_header.pts = MMAL_TIME_UNKNOWN; -+ m.u.buffer_from_host.buffer_header.dts = MMAL_TIME_UNKNOWN; -+ -+ /* clear buffer type sepecific data */ -+ memset(&m.u.buffer_from_host.buffer_header_type_specific, 0, -+ sizeof(m.u.buffer_from_host.buffer_header_type_specific)); -+ -+ /* no payload in message */ -+ m.u.buffer_from_host.payload_in_message = 0; -+ -+ vchi_service_use(instance->handle); -+ -+ ret = vchi_queue_kernel_message(instance->handle, -+ &m, -+ sizeof(struct mmal_msg_header) + -+ sizeof(m.u.buffer_from_host)); -+ -+ vchi_service_release(instance->handle); -+ -+ return ret; -+} -+ -+/* deals with receipt of buffer to host message */ -+static void buffer_to_host_cb(struct vchiq_mmal_instance *instance, -+ struct mmal_msg *msg, u32 msg_len) -+{ -+ struct mmal_msg_context *msg_context; -+ u32 handle; -+ -+ pr_debug("%s: instance:%p msg:%p msg_len:%d\n", -+ __func__, instance, msg, msg_len); -+ -+ if (msg->u.buffer_from_host.drvbuf.magic == MMAL_MAGIC) { -+ handle = msg->u.buffer_from_host.drvbuf.client_context; -+ msg_context = lookup_msg_context(instance, handle); -+ -+ if (!msg_context) { -+ pr_err("drvbuf.client_context(%u) is invalid\n", -+ handle); -+ return; -+ } -+ } else { -+ pr_err("MMAL_MSG_TYPE_BUFFER_TO_HOST with bad magic\n"); -+ return; -+ } -+ -+ msg_context->u.bulk.mmal_flags = -+ msg->u.buffer_from_host.buffer_header.flags; -+ -+ if (msg->h.status != MMAL_MSG_STATUS_SUCCESS) { -+ /* message reception had an error */ -+ pr_warn("error %d in reply\n", msg->h.status); -+ -+ msg_context->u.bulk.status = msg->h.status; -+ -+ } else if (msg->u.buffer_from_host.buffer_header.length == 0) { -+ /* empty buffer */ -+ if (msg->u.buffer_from_host.buffer_header.flags & -+ MMAL_BUFFER_HEADER_FLAG_EOS) { -+ msg_context->u.bulk.status = -+ bulk_receive(instance, msg, msg_context); -+ if (msg_context->u.bulk.status == 0) -+ return; /* successful bulk submission, bulk -+ * completion will trigger callback -+ */ -+ } else { -+ /* do callback with empty buffer - not EOS though */ -+ msg_context->u.bulk.status = 0; -+ msg_context->u.bulk.buffer_used = 0; -+ } -+ } else if (msg->u.buffer_from_host.payload_in_message == 0) { -+ /* data is not in message, queue a bulk receive */ -+ msg_context->u.bulk.status = -+ bulk_receive(instance, msg, msg_context); -+ if (msg_context->u.bulk.status == 0) -+ return; /* successful bulk submission, bulk -+ * completion will trigger callback -+ */ -+ -+ /* failed to submit buffer, this will end badly */ -+ pr_err("error %d on bulk submission\n", -+ msg_context->u.bulk.status); -+ -+ } else if (msg->u.buffer_from_host.payload_in_message <= -+ MMAL_VC_SHORT_DATA) { -+ /* data payload within message */ -+ msg_context->u.bulk.status = inline_receive(instance, msg, -+ msg_context); -+ } else { -+ pr_err("message with invalid short payload\n"); -+ -+ /* signal error */ -+ msg_context->u.bulk.status = -EINVAL; -+ msg_context->u.bulk.buffer_used = -+ msg->u.buffer_from_host.payload_in_message; -+ } -+ -+ /* schedule the port callback */ -+ schedule_work(&msg_context->u.bulk.work); -+} -+ -+static void bulk_receive_cb(struct vchiq_mmal_instance *instance, -+ struct mmal_msg_context *msg_context) -+{ -+ msg_context->u.bulk.status = 0; -+ -+ /* schedule the port callback */ -+ schedule_work(&msg_context->u.bulk.work); -+} -+ -+static void bulk_abort_cb(struct vchiq_mmal_instance *instance, -+ struct mmal_msg_context *msg_context) -+{ -+ pr_err("%s: bulk ABORTED msg_context:%p\n", __func__, msg_context); -+ -+ msg_context->u.bulk.status = -EINTR; -+ -+ schedule_work(&msg_context->u.bulk.work); -+} -+ -+/* incoming event service callback */ -+static void service_callback(void *param, -+ const VCHI_CALLBACK_REASON_T reason, -+ void *bulk_ctx) -+{ -+ struct vchiq_mmal_instance *instance = param; -+ int status; -+ u32 msg_len; -+ struct mmal_msg *msg; -+ VCHI_HELD_MSG_T msg_handle; -+ struct mmal_msg_context *msg_context; -+ -+ if (!instance) { -+ pr_err("Message callback passed NULL instance\n"); -+ return; -+ } -+ -+ switch (reason) { -+ case VCHI_CALLBACK_MSG_AVAILABLE: -+ status = vchi_msg_hold(instance->handle, (void **)&msg, -+ &msg_len, VCHI_FLAGS_NONE, &msg_handle); -+ if (status) { -+ pr_err("Unable to dequeue a message (%d)\n", status); -+ break; -+ } -+ -+ DBG_DUMP_MSG(msg, msg_len, "<<< reply message"); -+ -+ /* handling is different for buffer messages */ -+ switch (msg->h.type) { -+ case MMAL_MSG_TYPE_BUFFER_FROM_HOST: -+ vchi_held_msg_release(&msg_handle); -+ break; -+ -+ case MMAL_MSG_TYPE_EVENT_TO_HOST: -+ event_to_host_cb(instance, msg, msg_len); -+ vchi_held_msg_release(&msg_handle); -+ -+ break; -+ -+ case MMAL_MSG_TYPE_BUFFER_TO_HOST: -+ buffer_to_host_cb(instance, msg, msg_len); -+ vchi_held_msg_release(&msg_handle); -+ break; -+ -+ default: -+ /* messages dependent on header context to complete */ -+ if (!msg->h.context) { -+ pr_err("received message context was null!\n"); -+ vchi_held_msg_release(&msg_handle); -+ break; -+ } -+ -+ msg_context = lookup_msg_context(instance, -+ msg->h.context); -+ if (!msg_context) { -+ pr_err("received invalid message context %u!\n", -+ msg->h.context); -+ vchi_held_msg_release(&msg_handle); -+ break; -+ } -+ -+ /* fill in context values */ -+ msg_context->u.sync.msg_handle = msg_handle; -+ msg_context->u.sync.msg = msg; -+ msg_context->u.sync.msg_len = msg_len; -+ -+ /* todo: should this check (completion_done() -+ * == 1) for no one waiting? or do we need a -+ * flag to tell us the completion has been -+ * interrupted so we can free the message and -+ * its context. This probably also solves the -+ * message arriving after interruption todo -+ * below -+ */ -+ -+ /* complete message so caller knows it happened */ -+ complete(&msg_context->u.sync.cmplt); -+ break; -+ } -+ -+ break; -+ -+ case VCHI_CALLBACK_BULK_RECEIVED: -+ bulk_receive_cb(instance, bulk_ctx); -+ break; -+ -+ case VCHI_CALLBACK_BULK_RECEIVE_ABORTED: -+ bulk_abort_cb(instance, bulk_ctx); -+ break; -+ -+ case VCHI_CALLBACK_SERVICE_CLOSED: -+ /* TODO: consider if this requires action if received when -+ * driver is not explicitly closing the service -+ */ -+ break; -+ -+ default: -+ pr_err("Received unhandled message reason %d\n", reason); -+ break; -+ } -+} -+ -+static int send_synchronous_mmal_msg(struct vchiq_mmal_instance *instance, -+ struct mmal_msg *msg, -+ unsigned int payload_len, -+ struct mmal_msg **msg_out, -+ VCHI_HELD_MSG_T *msg_handle_out) -+{ -+ struct mmal_msg_context *msg_context; -+ int ret; -+ unsigned long timeout; -+ -+ /* payload size must not cause message to exceed max size */ -+ if (payload_len > -+ (MMAL_MSG_MAX_SIZE - sizeof(struct mmal_msg_header))) { -+ pr_err("payload length %d exceeds max:%d\n", payload_len, -+ (int)(MMAL_MSG_MAX_SIZE - -+ sizeof(struct mmal_msg_header))); -+ return -EINVAL; -+ } -+ -+ msg_context = get_msg_context(instance); -+ if (IS_ERR(msg_context)) -+ return PTR_ERR(msg_context); -+ -+ init_completion(&msg_context->u.sync.cmplt); -+ -+ msg->h.magic = MMAL_MAGIC; -+ msg->h.context = msg_context->handle; -+ msg->h.status = 0; -+ -+ DBG_DUMP_MSG(msg, (sizeof(struct mmal_msg_header) + payload_len), -+ ">>> sync message"); -+ -+ vchi_service_use(instance->handle); -+ -+ ret = vchi_queue_kernel_message(instance->handle, -+ msg, -+ sizeof(struct mmal_msg_header) + -+ payload_len); -+ -+ vchi_service_release(instance->handle); -+ -+ if (ret) { -+ pr_err("error %d queuing message\n", ret); -+ release_msg_context(msg_context); -+ return ret; -+ } -+ -+ timeout = wait_for_completion_timeout(&msg_context->u.sync.cmplt, -+ 3 * HZ); -+ if (timeout == 0) { -+ pr_err("timed out waiting for sync completion\n"); -+ ret = -ETIME; -+ /* todo: what happens if the message arrives after aborting */ -+ release_msg_context(msg_context); -+ return ret; -+ } -+ -+ *msg_out = msg_context->u.sync.msg; -+ *msg_handle_out = msg_context->u.sync.msg_handle; -+ release_msg_context(msg_context); -+ -+ return 0; -+} -+ -+static void dump_port_info(struct vchiq_mmal_port *port) -+{ -+ pr_debug("port handle:0x%x enabled:%d\n", port->handle, port->enabled); -+ -+ pr_debug("buffer minimum num:%d size:%d align:%d\n", -+ port->minimum_buffer.num, -+ port->minimum_buffer.size, port->minimum_buffer.alignment); -+ -+ pr_debug("buffer recommended num:%d size:%d align:%d\n", -+ port->recommended_buffer.num, -+ port->recommended_buffer.size, -+ port->recommended_buffer.alignment); -+ -+ pr_debug("buffer current values num:%d size:%d align:%d\n", -+ port->current_buffer.num, -+ port->current_buffer.size, port->current_buffer.alignment); -+ -+ pr_debug("elementary stream: type:%d encoding:0x%x variant:0x%x\n", -+ port->format.type, -+ port->format.encoding, port->format.encoding_variant); -+ -+ pr_debug(" bitrate:%d flags:0x%x\n", -+ port->format.bitrate, port->format.flags); -+ -+ if (port->format.type == MMAL_ES_TYPE_VIDEO) { -+ pr_debug -+ ("es video format: width:%d height:%d colourspace:0x%x\n", -+ port->es.video.width, port->es.video.height, -+ port->es.video.color_space); -+ -+ pr_debug(" : crop xywh %d,%d,%d,%d\n", -+ port->es.video.crop.x, -+ port->es.video.crop.y, -+ port->es.video.crop.width, port->es.video.crop.height); -+ pr_debug(" : framerate %d/%d aspect %d/%d\n", -+ port->es.video.frame_rate.num, -+ port->es.video.frame_rate.den, -+ port->es.video.par.num, port->es.video.par.den); -+ } -+} -+ -+static void port_to_mmal_msg(struct vchiq_mmal_port *port, struct mmal_port *p) -+{ -+ /* todo do readonly fields need setting at all? */ -+ p->type = port->type; -+ p->index = port->index; -+ p->index_all = 0; -+ p->is_enabled = port->enabled; -+ p->buffer_num_min = port->minimum_buffer.num; -+ p->buffer_size_min = port->minimum_buffer.size; -+ p->buffer_alignment_min = port->minimum_buffer.alignment; -+ p->buffer_num_recommended = port->recommended_buffer.num; -+ p->buffer_size_recommended = port->recommended_buffer.size; -+ -+ /* only three writable fields in a port */ -+ p->buffer_num = port->current_buffer.num; -+ p->buffer_size = port->current_buffer.size; -+ p->userdata = (u32)(unsigned long)port; -+} -+ -+static int port_info_set(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port) -+{ -+ int ret; -+ struct mmal_msg m; -+ struct mmal_msg *rmsg; -+ VCHI_HELD_MSG_T rmsg_handle; -+ -+ pr_debug("setting port info port %p\n", port); -+ if (!port) -+ return -1; -+ dump_port_info(port); -+ -+ m.h.type = MMAL_MSG_TYPE_PORT_INFO_SET; -+ -+ m.u.port_info_set.component_handle = port->component->handle; -+ m.u.port_info_set.port_type = port->type; -+ m.u.port_info_set.port_index = port->index; -+ -+ port_to_mmal_msg(port, &m.u.port_info_set.port); -+ -+ /* elementary stream format setup */ -+ m.u.port_info_set.format.type = port->format.type; -+ m.u.port_info_set.format.encoding = port->format.encoding; -+ m.u.port_info_set.format.encoding_variant = -+ port->format.encoding_variant; -+ m.u.port_info_set.format.bitrate = port->format.bitrate; -+ m.u.port_info_set.format.flags = port->format.flags; -+ -+ memcpy(&m.u.port_info_set.es, &port->es, -+ sizeof(union mmal_es_specific_format)); -+ -+ m.u.port_info_set.format.extradata_size = port->format.extradata_size; -+ memcpy(&m.u.port_info_set.extradata, port->format.extradata, -+ port->format.extradata_size); -+ -+ ret = send_synchronous_mmal_msg(instance, &m, -+ sizeof(m.u.port_info_set), -+ &rmsg, &rmsg_handle); -+ if (ret) -+ return ret; -+ -+ if (rmsg->h.type != MMAL_MSG_TYPE_PORT_INFO_SET) { -+ /* got an unexpected message type in reply */ -+ ret = -EINVAL; -+ goto release_msg; -+ } -+ -+ /* return operation status */ -+ ret = -rmsg->u.port_info_get_reply.status; -+ -+ pr_debug("%s:result:%d component:0x%x port:%d\n", __func__, ret, -+ port->component->handle, port->handle); -+ -+release_msg: -+ vchi_held_msg_release(&rmsg_handle); -+ -+ return ret; -+} -+ -+/* use port info get message to retrieve port information */ -+static int port_info_get(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port) -+{ -+ int ret; -+ struct mmal_msg m; -+ struct mmal_msg *rmsg; -+ VCHI_HELD_MSG_T rmsg_handle; -+ -+ /* port info time */ -+ m.h.type = MMAL_MSG_TYPE_PORT_INFO_GET; -+ m.u.port_info_get.component_handle = port->component->handle; -+ m.u.port_info_get.port_type = port->type; -+ m.u.port_info_get.index = port->index; -+ -+ ret = send_synchronous_mmal_msg(instance, &m, -+ sizeof(m.u.port_info_get), -+ &rmsg, &rmsg_handle); -+ if (ret) -+ return ret; -+ -+ if (rmsg->h.type != MMAL_MSG_TYPE_PORT_INFO_GET) { -+ /* got an unexpected message type in reply */ -+ ret = -EINVAL; -+ goto release_msg; -+ } -+ -+ /* return operation status */ -+ ret = -rmsg->u.port_info_get_reply.status; -+ if (ret != MMAL_MSG_STATUS_SUCCESS) -+ goto release_msg; -+ -+ if (rmsg->u.port_info_get_reply.port.is_enabled == 0) -+ port->enabled = false; -+ else -+ port->enabled = true; -+ -+ /* copy the values out of the message */ -+ port->handle = rmsg->u.port_info_get_reply.port_handle; -+ -+ /* port type and index cached to use on port info set because -+ * it does not use a port handle -+ */ -+ port->type = rmsg->u.port_info_get_reply.port_type; -+ port->index = rmsg->u.port_info_get_reply.port_index; -+ -+ port->minimum_buffer.num = -+ rmsg->u.port_info_get_reply.port.buffer_num_min; -+ port->minimum_buffer.size = -+ rmsg->u.port_info_get_reply.port.buffer_size_min; -+ port->minimum_buffer.alignment = -+ rmsg->u.port_info_get_reply.port.buffer_alignment_min; -+ -+ port->recommended_buffer.alignment = -+ rmsg->u.port_info_get_reply.port.buffer_alignment_min; -+ port->recommended_buffer.num = -+ rmsg->u.port_info_get_reply.port.buffer_num_recommended; -+ -+ port->current_buffer.num = rmsg->u.port_info_get_reply.port.buffer_num; -+ port->current_buffer.size = -+ rmsg->u.port_info_get_reply.port.buffer_size; -+ -+ /* stream format */ -+ port->format.type = rmsg->u.port_info_get_reply.format.type; -+ port->format.encoding = rmsg->u.port_info_get_reply.format.encoding; -+ port->format.encoding_variant = -+ rmsg->u.port_info_get_reply.format.encoding_variant; -+ port->format.bitrate = rmsg->u.port_info_get_reply.format.bitrate; -+ port->format.flags = rmsg->u.port_info_get_reply.format.flags; -+ -+ /* elementary stream format */ -+ memcpy(&port->es, -+ &rmsg->u.port_info_get_reply.es, -+ sizeof(union mmal_es_specific_format)); -+ port->format.es = &port->es; -+ -+ port->format.extradata_size = -+ rmsg->u.port_info_get_reply.format.extradata_size; -+ memcpy(port->format.extradata, -+ rmsg->u.port_info_get_reply.extradata, -+ port->format.extradata_size); -+ -+ pr_debug("received port info\n"); -+ dump_port_info(port); -+ -+release_msg: -+ -+ pr_debug("%s:result:%d component:0x%x port:%d\n", -+ __func__, ret, port->component->handle, port->handle); -+ -+ vchi_held_msg_release(&rmsg_handle); -+ -+ return ret; -+} -+ -+/* create comonent on vc */ -+static int create_component(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_component *component, -+ const char *name) -+{ -+ int ret; -+ struct mmal_msg m; -+ struct mmal_msg *rmsg; -+ VCHI_HELD_MSG_T rmsg_handle; -+ -+ /* build component create message */ -+ m.h.type = MMAL_MSG_TYPE_COMPONENT_CREATE; -+ m.u.component_create.client_component = (u32)(unsigned long)component; -+ strncpy(m.u.component_create.name, name, -+ sizeof(m.u.component_create.name)); -+ -+ ret = send_synchronous_mmal_msg(instance, &m, -+ sizeof(m.u.component_create), -+ &rmsg, &rmsg_handle); -+ if (ret) -+ return ret; -+ -+ if (rmsg->h.type != m.h.type) { -+ /* got an unexpected message type in reply */ -+ ret = -EINVAL; -+ goto release_msg; -+ } -+ -+ ret = -rmsg->u.component_create_reply.status; -+ if (ret != MMAL_MSG_STATUS_SUCCESS) -+ goto release_msg; -+ -+ /* a valid component response received */ -+ component->handle = rmsg->u.component_create_reply.component_handle; -+ component->inputs = rmsg->u.component_create_reply.input_num; -+ component->outputs = rmsg->u.component_create_reply.output_num; -+ component->clocks = rmsg->u.component_create_reply.clock_num; -+ -+ pr_debug("Component handle:0x%x in:%d out:%d clock:%d\n", -+ component->handle, -+ component->inputs, component->outputs, component->clocks); -+ -+release_msg: -+ vchi_held_msg_release(&rmsg_handle); -+ -+ return ret; -+} -+ -+/* destroys a component on vc */ -+static int destroy_component(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_component *component) -+{ -+ int ret; -+ struct mmal_msg m; -+ struct mmal_msg *rmsg; -+ VCHI_HELD_MSG_T rmsg_handle; -+ -+ m.h.type = MMAL_MSG_TYPE_COMPONENT_DESTROY; -+ m.u.component_destroy.component_handle = component->handle; -+ -+ ret = send_synchronous_mmal_msg(instance, &m, -+ sizeof(m.u.component_destroy), -+ &rmsg, &rmsg_handle); -+ if (ret) -+ return ret; -+ -+ if (rmsg->h.type != m.h.type) { -+ /* got an unexpected message type in reply */ -+ ret = -EINVAL; -+ goto release_msg; -+ } -+ -+ ret = -rmsg->u.component_destroy_reply.status; -+ -+release_msg: -+ -+ vchi_held_msg_release(&rmsg_handle); -+ -+ return ret; -+} -+ -+/* enable a component on vc */ -+static int enable_component(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_component *component) -+{ -+ int ret; -+ struct mmal_msg m; -+ struct mmal_msg *rmsg; -+ VCHI_HELD_MSG_T rmsg_handle; -+ -+ m.h.type = MMAL_MSG_TYPE_COMPONENT_ENABLE; -+ m.u.component_enable.component_handle = component->handle; -+ -+ ret = send_synchronous_mmal_msg(instance, &m, -+ sizeof(m.u.component_enable), -+ &rmsg, &rmsg_handle); -+ if (ret) -+ return ret; -+ -+ if (rmsg->h.type != m.h.type) { -+ /* got an unexpected message type in reply */ -+ ret = -EINVAL; -+ goto release_msg; -+ } -+ -+ ret = -rmsg->u.component_enable_reply.status; -+ -+release_msg: -+ vchi_held_msg_release(&rmsg_handle); -+ -+ return ret; -+} -+ -+/* disable a component on vc */ -+static int disable_component(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_component *component) -+{ -+ int ret; -+ struct mmal_msg m; -+ struct mmal_msg *rmsg; -+ VCHI_HELD_MSG_T rmsg_handle; -+ -+ m.h.type = MMAL_MSG_TYPE_COMPONENT_DISABLE; -+ m.u.component_disable.component_handle = component->handle; -+ -+ ret = send_synchronous_mmal_msg(instance, &m, -+ sizeof(m.u.component_disable), -+ &rmsg, &rmsg_handle); -+ if (ret) -+ return ret; -+ -+ if (rmsg->h.type != m.h.type) { -+ /* got an unexpected message type in reply */ -+ ret = -EINVAL; -+ goto release_msg; -+ } -+ -+ ret = -rmsg->u.component_disable_reply.status; -+ -+release_msg: -+ -+ vchi_held_msg_release(&rmsg_handle); -+ -+ return ret; -+} -+ -+/* get version of mmal implementation */ -+static int get_version(struct vchiq_mmal_instance *instance, -+ u32 *major_out, u32 *minor_out) -+{ -+ int ret; -+ struct mmal_msg m; -+ struct mmal_msg *rmsg; -+ VCHI_HELD_MSG_T rmsg_handle; -+ -+ m.h.type = MMAL_MSG_TYPE_GET_VERSION; -+ -+ ret = send_synchronous_mmal_msg(instance, &m, -+ sizeof(m.u.version), -+ &rmsg, &rmsg_handle); -+ if (ret) -+ return ret; -+ -+ if (rmsg->h.type != m.h.type) { -+ /* got an unexpected message type in reply */ -+ ret = -EINVAL; -+ goto release_msg; -+ } -+ -+ *major_out = rmsg->u.version.major; -+ *minor_out = rmsg->u.version.minor; -+ -+release_msg: -+ vchi_held_msg_release(&rmsg_handle); -+ -+ return ret; -+} -+ -+/* do a port action with a port as a parameter */ -+static int port_action_port(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port, -+ enum mmal_msg_port_action_type action_type) -+{ -+ int ret; -+ struct mmal_msg m; -+ struct mmal_msg *rmsg; -+ VCHI_HELD_MSG_T rmsg_handle; -+ -+ m.h.type = MMAL_MSG_TYPE_PORT_ACTION; -+ m.u.port_action_port.component_handle = port->component->handle; -+ m.u.port_action_port.port_handle = port->handle; -+ m.u.port_action_port.action = action_type; -+ -+ port_to_mmal_msg(port, &m.u.port_action_port.port); -+ -+ ret = send_synchronous_mmal_msg(instance, &m, -+ sizeof(m.u.port_action_port), -+ &rmsg, &rmsg_handle); -+ if (ret) -+ return ret; -+ -+ if (rmsg->h.type != MMAL_MSG_TYPE_PORT_ACTION) { -+ /* got an unexpected message type in reply */ -+ ret = -EINVAL; -+ goto release_msg; -+ } -+ -+ ret = -rmsg->u.port_action_reply.status; -+ -+ pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d)\n", -+ __func__, -+ ret, port->component->handle, port->handle, -+ port_action_type_names[action_type], action_type); -+ -+release_msg: -+ vchi_held_msg_release(&rmsg_handle); -+ -+ return ret; -+} -+ -+/* do a port action with handles as parameters */ -+static int port_action_handle(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port, -+ enum mmal_msg_port_action_type action_type, -+ u32 connect_component_handle, -+ u32 connect_port_handle) -+{ -+ int ret; -+ struct mmal_msg m; -+ struct mmal_msg *rmsg; -+ VCHI_HELD_MSG_T rmsg_handle; -+ -+ m.h.type = MMAL_MSG_TYPE_PORT_ACTION; -+ -+ m.u.port_action_handle.component_handle = port->component->handle; -+ m.u.port_action_handle.port_handle = port->handle; -+ m.u.port_action_handle.action = action_type; -+ -+ m.u.port_action_handle.connect_component_handle = -+ connect_component_handle; -+ m.u.port_action_handle.connect_port_handle = connect_port_handle; -+ -+ ret = send_synchronous_mmal_msg(instance, &m, -+ sizeof(m.u.port_action_handle), -+ &rmsg, &rmsg_handle); -+ if (ret) -+ return ret; -+ -+ if (rmsg->h.type != MMAL_MSG_TYPE_PORT_ACTION) { -+ /* got an unexpected message type in reply */ -+ ret = -EINVAL; -+ goto release_msg; -+ } -+ -+ ret = -rmsg->u.port_action_reply.status; -+ -+ pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d) connect component:0x%x connect port:%d\n", -+ __func__, -+ ret, port->component->handle, port->handle, -+ port_action_type_names[action_type], -+ action_type, connect_component_handle, connect_port_handle); -+ -+release_msg: -+ vchi_held_msg_release(&rmsg_handle); -+ -+ return ret; -+} -+ -+static int port_parameter_set(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port, -+ u32 parameter_id, void *value, u32 value_size) -+{ -+ int ret; -+ struct mmal_msg m; -+ struct mmal_msg *rmsg; -+ VCHI_HELD_MSG_T rmsg_handle; -+ -+ m.h.type = MMAL_MSG_TYPE_PORT_PARAMETER_SET; -+ -+ m.u.port_parameter_set.component_handle = port->component->handle; -+ m.u.port_parameter_set.port_handle = port->handle; -+ m.u.port_parameter_set.id = parameter_id; -+ m.u.port_parameter_set.size = (2 * sizeof(u32)) + value_size; -+ memcpy(&m.u.port_parameter_set.value, value, value_size); -+ -+ ret = send_synchronous_mmal_msg(instance, &m, -+ (4 * sizeof(u32)) + value_size, -+ &rmsg, &rmsg_handle); -+ if (ret) -+ return ret; -+ -+ if (rmsg->h.type != MMAL_MSG_TYPE_PORT_PARAMETER_SET) { -+ /* got an unexpected message type in reply */ -+ ret = -EINVAL; -+ goto release_msg; -+ } -+ -+ ret = -rmsg->u.port_parameter_set_reply.status; -+ -+ pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n", -+ __func__, -+ ret, port->component->handle, port->handle, parameter_id); -+ -+release_msg: -+ vchi_held_msg_release(&rmsg_handle); -+ -+ return ret; -+} -+ -+static int port_parameter_get(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port, -+ u32 parameter_id, void *value, u32 *value_size) -+{ -+ int ret; -+ struct mmal_msg m; -+ struct mmal_msg *rmsg; -+ VCHI_HELD_MSG_T rmsg_handle; -+ -+ m.h.type = MMAL_MSG_TYPE_PORT_PARAMETER_GET; -+ -+ m.u.port_parameter_get.component_handle = port->component->handle; -+ m.u.port_parameter_get.port_handle = port->handle; -+ m.u.port_parameter_get.id = parameter_id; -+ m.u.port_parameter_get.size = (2 * sizeof(u32)) + *value_size; -+ -+ ret = send_synchronous_mmal_msg(instance, &m, -+ sizeof(struct -+ mmal_msg_port_parameter_get), -+ &rmsg, &rmsg_handle); -+ if (ret) -+ return ret; -+ -+ if (rmsg->h.type != MMAL_MSG_TYPE_PORT_PARAMETER_GET) { -+ /* got an unexpected message type in reply */ -+ pr_err("Incorrect reply type %d\n", rmsg->h.type); -+ ret = -EINVAL; -+ goto release_msg; -+ } -+ -+ ret = -rmsg->u.port_parameter_get_reply.status; -+ /* port_parameter_get_reply.size includes the header, -+ * whilst *value_size doesn't. -+ */ -+ rmsg->u.port_parameter_get_reply.size -= (2 * sizeof(u32)); -+ -+ if (ret || rmsg->u.port_parameter_get_reply.size > *value_size) { -+ /* Copy only as much as we have space for -+ * but report true size of parameter -+ */ -+ memcpy(value, &rmsg->u.port_parameter_get_reply.value, -+ *value_size); -+ *value_size = rmsg->u.port_parameter_get_reply.size; -+ } else { -+ memcpy(value, &rmsg->u.port_parameter_get_reply.value, -+ rmsg->u.port_parameter_get_reply.size); -+ } -+ -+ pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n", __func__, -+ ret, port->component->handle, port->handle, parameter_id); -+ -+release_msg: -+ vchi_held_msg_release(&rmsg_handle); -+ -+ return ret; -+} -+ -+/* disables a port and drains buffers from it */ -+static int port_disable(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port) -+{ -+ int ret; -+ struct list_head *q, *buf_head; -+ unsigned long flags = 0; -+ -+ if (!port->enabled) -+ return 0; -+ -+ port->enabled = false; -+ -+ ret = port_action_port(instance, port, -+ MMAL_MSG_PORT_ACTION_TYPE_DISABLE); -+ if (ret == 0) { -+ /* -+ * Drain all queued buffers on port. This should only -+ * apply to buffers that have been queued before the port -+ * has been enabled. If the port has been enabled and buffers -+ * passed, then the buffers should have been removed from this -+ * list, and we should get the relevant callbacks via VCHIQ -+ * to release the buffers. -+ */ -+ spin_lock_irqsave(&port->slock, flags); -+ -+ list_for_each_safe(buf_head, q, &port->buffers) { -+ struct mmal_buffer *mmalbuf; -+ -+ mmalbuf = list_entry(buf_head, struct mmal_buffer, -+ list); -+ list_del(buf_head); -+ if (port->buffer_cb) -+ port->buffer_cb(instance, -+ port, 0, mmalbuf, 0, 0, -+ MMAL_TIME_UNKNOWN, -+ MMAL_TIME_UNKNOWN); -+ } -+ -+ spin_unlock_irqrestore(&port->slock, flags); -+ -+ ret = port_info_get(instance, port); -+ } -+ -+ return ret; -+} -+ -+/* enable a port */ -+static int port_enable(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port) -+{ -+ unsigned int hdr_count; -+ struct list_head *q, *buf_head; -+ int ret; -+ -+ if (port->enabled) -+ return 0; -+ -+ ret = port_action_port(instance, port, -+ MMAL_MSG_PORT_ACTION_TYPE_ENABLE); -+ if (ret) -+ goto done; -+ -+ port->enabled = true; -+ -+ if (port->buffer_cb) { -+ /* send buffer headers to videocore */ -+ hdr_count = 1; -+ list_for_each_safe(buf_head, q, &port->buffers) { -+ struct mmal_buffer *mmalbuf; -+ -+ mmalbuf = list_entry(buf_head, struct mmal_buffer, -+ list); -+ ret = buffer_from_host(instance, port, mmalbuf); -+ if (ret) -+ goto done; -+ -+ list_del(buf_head); -+ hdr_count++; -+ if (hdr_count > port->current_buffer.num) -+ break; -+ } -+ } -+ -+ ret = port_info_get(instance, port); -+ -+done: -+ return ret; -+} -+ -+/* ------------------------------------------------------------------ -+ * Exported API -+ *------------------------------------------------------------------ -+ */ -+ -+int vchiq_mmal_port_set_format(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port) -+{ -+ int ret; -+ -+ if (mutex_lock_interruptible(&instance->vchiq_mutex)) -+ return -EINTR; -+ -+ ret = port_info_set(instance, port); -+ if (ret) -+ goto release_unlock; -+ -+ /* read what has actually been set */ -+ ret = port_info_get(instance, port); -+ -+release_unlock: -+ mutex_unlock(&instance->vchiq_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(vchiq_mmal_port_set_format); -+ -+int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port, -+ u32 parameter, void *value, u32 value_size) -+{ -+ int ret; -+ -+ if (mutex_lock_interruptible(&instance->vchiq_mutex)) -+ return -EINTR; -+ -+ ret = port_parameter_set(instance, port, parameter, value, value_size); -+ -+ mutex_unlock(&instance->vchiq_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_set); -+ -+int vchiq_mmal_port_parameter_get(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port, -+ u32 parameter, void *value, u32 *value_size) -+{ -+ int ret; -+ -+ if (mutex_lock_interruptible(&instance->vchiq_mutex)) -+ return -EINTR; -+ -+ ret = port_parameter_get(instance, port, parameter, value, value_size); -+ -+ mutex_unlock(&instance->vchiq_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_get); -+ -+/* enable a port -+ * -+ * enables a port and queues buffers for satisfying callbacks if we -+ * provide a callback handler -+ */ -+int vchiq_mmal_port_enable(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port, -+ vchiq_mmal_buffer_cb buffer_cb) -+{ -+ int ret; -+ -+ if (mutex_lock_interruptible(&instance->vchiq_mutex)) -+ return -EINTR; -+ -+ /* already enabled - noop */ -+ if (port->enabled) { -+ ret = 0; -+ goto unlock; -+ } -+ -+ port->buffer_cb = buffer_cb; -+ -+ ret = port_enable(instance, port); -+ -+unlock: -+ mutex_unlock(&instance->vchiq_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(vchiq_mmal_port_enable); -+ -+int vchiq_mmal_port_disable(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port) -+{ -+ int ret; -+ -+ if (mutex_lock_interruptible(&instance->vchiq_mutex)) -+ return -EINTR; -+ -+ if (!port->enabled) { -+ mutex_unlock(&instance->vchiq_mutex); -+ return 0; -+ } -+ -+ ret = port_disable(instance, port); -+ -+ mutex_unlock(&instance->vchiq_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(vchiq_mmal_port_disable); -+ -+/* ports will be connected in a tunneled manner so data buffers -+ * are not handled by client. -+ */ -+int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *src, -+ struct vchiq_mmal_port *dst) -+{ -+ int ret; -+ -+ if (mutex_lock_interruptible(&instance->vchiq_mutex)) -+ return -EINTR; -+ -+ /* disconnect ports if connected */ -+ if (src->connected) { -+ ret = port_disable(instance, src); -+ if (ret) { -+ pr_err("failed disabling src port(%d)\n", ret); -+ goto release_unlock; -+ } -+ -+ /* do not need to disable the destination port as they -+ * are connected and it is done automatically -+ */ -+ -+ ret = port_action_handle(instance, src, -+ MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT, -+ src->connected->component->handle, -+ src->connected->handle); -+ if (ret < 0) { -+ pr_err("failed disconnecting src port\n"); -+ goto release_unlock; -+ } -+ src->connected->enabled = false; -+ src->connected = NULL; -+ } -+ -+ if (!dst) { -+ /* do not make new connection */ -+ ret = 0; -+ pr_debug("not making new connection\n"); -+ goto release_unlock; -+ } -+ -+ /* copy src port format to dst */ -+ dst->format.encoding = src->format.encoding; -+ dst->es.video.width = src->es.video.width; -+ dst->es.video.height = src->es.video.height; -+ dst->es.video.crop.x = src->es.video.crop.x; -+ dst->es.video.crop.y = src->es.video.crop.y; -+ dst->es.video.crop.width = src->es.video.crop.width; -+ dst->es.video.crop.height = src->es.video.crop.height; -+ dst->es.video.frame_rate.num = src->es.video.frame_rate.num; -+ dst->es.video.frame_rate.den = src->es.video.frame_rate.den; -+ -+ /* set new format */ -+ ret = port_info_set(instance, dst); -+ if (ret) { -+ pr_debug("setting port info failed\n"); -+ goto release_unlock; -+ } -+ -+ /* read what has actually been set */ -+ ret = port_info_get(instance, dst); -+ if (ret) { -+ pr_debug("read back port info failed\n"); -+ goto release_unlock; -+ } -+ -+ /* connect two ports together */ -+ ret = port_action_handle(instance, src, -+ MMAL_MSG_PORT_ACTION_TYPE_CONNECT, -+ dst->component->handle, dst->handle); -+ if (ret < 0) { -+ pr_debug("connecting port %d:%d to %d:%d failed\n", -+ src->component->handle, src->handle, -+ dst->component->handle, dst->handle); -+ goto release_unlock; -+ } -+ src->connected = dst; -+ -+release_unlock: -+ -+ mutex_unlock(&instance->vchiq_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(vchiq_mmal_port_connect_tunnel); -+ -+int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port, -+ struct mmal_buffer *buffer) -+{ -+ unsigned long flags = 0; -+ int ret; -+ -+ ret = buffer_from_host(instance, port, buffer); -+ if (ret == -EINVAL) { -+ /* Port is disabled. Queue for when it is enabled. */ -+ spin_lock_irqsave(&port->slock, flags); -+ list_add_tail(&buffer->list, &port->buffers); -+ spin_unlock_irqrestore(&port->slock, flags); -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(vchiq_mmal_submit_buffer); -+ -+int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance, -+ struct mmal_buffer *buf) -+{ -+ struct mmal_msg_context *msg_context = get_msg_context(instance); -+ -+ if (IS_ERR(msg_context)) -+ return (PTR_ERR(msg_context)); -+ -+ buf->msg_context = msg_context; -+ return 0; -+} -+EXPORT_SYMBOL_GPL(mmal_vchi_buffer_init); -+ -+int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf) -+{ -+ struct mmal_msg_context *msg_context = buf->msg_context; -+ -+ if (msg_context) -+ release_msg_context(msg_context); -+ buf->msg_context = NULL; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup); -+ -+/* Initialise a mmal component and its ports -+ * -+ */ -+int vchiq_mmal_component_init(struct vchiq_mmal_instance *instance, -+ const char *name, -+ struct vchiq_mmal_component **component_out) -+{ -+ int ret; -+ int idx; /* port index */ -+ struct vchiq_mmal_component *component; -+ -+ if (mutex_lock_interruptible(&instance->vchiq_mutex)) -+ return -EINTR; -+ -+ if (instance->component_idx == VCHIQ_MMAL_MAX_COMPONENTS) { -+ ret = -EINVAL; /* todo is this correct error? */ -+ goto unlock; -+ } -+ -+ component = &instance->component[instance->component_idx]; -+ -+ ret = create_component(instance, component, name); -+ if (ret < 0) { -+ pr_err("%s: failed to create component %d (Not enough GPU mem?)\n", -+ __func__, ret); -+ goto unlock; -+ } -+ -+ /* ports info needs gathering */ -+ component->control.type = MMAL_PORT_TYPE_CONTROL; -+ component->control.index = 0; -+ component->control.component = component; -+ spin_lock_init(&component->control.slock); -+ INIT_LIST_HEAD(&component->control.buffers); -+ ret = port_info_get(instance, &component->control); -+ if (ret < 0) -+ goto release_component; -+ -+ for (idx = 0; idx < component->inputs; idx++) { -+ component->input[idx].type = MMAL_PORT_TYPE_INPUT; -+ component->input[idx].index = idx; -+ component->input[idx].component = component; -+ spin_lock_init(&component->input[idx].slock); -+ INIT_LIST_HEAD(&component->input[idx].buffers); -+ ret = port_info_get(instance, &component->input[idx]); -+ if (ret < 0) -+ goto release_component; -+ } -+ -+ for (idx = 0; idx < component->outputs; idx++) { -+ component->output[idx].type = MMAL_PORT_TYPE_OUTPUT; -+ component->output[idx].index = idx; -+ component->output[idx].component = component; -+ spin_lock_init(&component->output[idx].slock); -+ INIT_LIST_HEAD(&component->output[idx].buffers); -+ ret = port_info_get(instance, &component->output[idx]); -+ if (ret < 0) -+ goto release_component; -+ } -+ -+ for (idx = 0; idx < component->clocks; idx++) { -+ component->clock[idx].type = MMAL_PORT_TYPE_CLOCK; -+ component->clock[idx].index = idx; -+ component->clock[idx].component = component; -+ spin_lock_init(&component->clock[idx].slock); -+ INIT_LIST_HEAD(&component->clock[idx].buffers); -+ ret = port_info_get(instance, &component->clock[idx]); -+ if (ret < 0) -+ goto release_component; -+ } -+ -+ instance->component_idx++; -+ -+ *component_out = component; -+ -+ mutex_unlock(&instance->vchiq_mutex); -+ -+ return 0; -+ -+release_component: -+ destroy_component(instance, component); -+unlock: -+ mutex_unlock(&instance->vchiq_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(vchiq_mmal_component_init); -+ -+/* -+ * cause a mmal component to be destroyed -+ */ -+int vchiq_mmal_component_finalise(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_component *component) -+{ -+ int ret; -+ -+ if (mutex_lock_interruptible(&instance->vchiq_mutex)) -+ return -EINTR; -+ -+ if (component->enabled) -+ ret = disable_component(instance, component); -+ -+ ret = destroy_component(instance, component); -+ -+ mutex_unlock(&instance->vchiq_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(vchiq_mmal_component_finalise); -+ -+/* -+ * cause a mmal component to be enabled -+ */ -+int vchiq_mmal_component_enable(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_component *component) -+{ -+ int ret; -+ -+ if (mutex_lock_interruptible(&instance->vchiq_mutex)) -+ return -EINTR; -+ -+ if (component->enabled) { -+ mutex_unlock(&instance->vchiq_mutex); -+ return 0; -+ } -+ -+ ret = enable_component(instance, component); -+ if (ret == 0) -+ component->enabled = true; -+ -+ mutex_unlock(&instance->vchiq_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(vchiq_mmal_component_enable); -+ -+/* -+ * cause a mmal component to be enabled -+ */ -+int vchiq_mmal_component_disable(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_component *component) -+{ -+ int ret; -+ -+ if (mutex_lock_interruptible(&instance->vchiq_mutex)) -+ return -EINTR; -+ -+ if (!component->enabled) { -+ mutex_unlock(&instance->vchiq_mutex); -+ return 0; -+ } -+ -+ ret = disable_component(instance, component); -+ if (ret == 0) -+ component->enabled = false; -+ -+ mutex_unlock(&instance->vchiq_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(vchiq_mmal_component_disable); -+ -+int vchiq_mmal_version(struct vchiq_mmal_instance *instance, -+ u32 *major_out, u32 *minor_out) -+{ -+ int ret; -+ -+ if (mutex_lock_interruptible(&instance->vchiq_mutex)) -+ return -EINTR; -+ -+ ret = get_version(instance, major_out, minor_out); -+ -+ mutex_unlock(&instance->vchiq_mutex); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(vchiq_mmal_version); -+ -+int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance) -+{ -+ int status = 0; -+ -+ if (!instance) -+ return -EINVAL; -+ -+ if (mutex_lock_interruptible(&instance->vchiq_mutex)) -+ return -EINTR; -+ -+ vchi_service_use(instance->handle); -+ -+ status = vchi_service_close(instance->handle); -+ if (status != 0) -+ pr_err("mmal-vchiq: VCHIQ close failed\n"); -+ -+ mutex_unlock(&instance->vchiq_mutex); -+ -+ flush_workqueue(instance->bulk_wq); -+ destroy_workqueue(instance->bulk_wq); -+ -+ vfree(instance->bulk_scratch); -+ -+ idr_destroy(&instance->context_map); -+ -+ kfree(instance); -+ -+ return status; -+} -+EXPORT_SYMBOL_GPL(vchiq_mmal_finalise); -+ -+int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance) -+{ -+ int status; -+ struct vchiq_mmal_instance *instance; -+ static VCHI_CONNECTION_T *vchi_connection; -+ static VCHI_INSTANCE_T vchi_instance; -+ SERVICE_CREATION_T params = { -+ .version = VCHI_VERSION_EX(VC_MMAL_VER, VC_MMAL_MIN_VER), -+ .service_id = VC_MMAL_SERVER_NAME, -+ .connection = vchi_connection, -+ .rx_fifo_size = 0, -+ .tx_fifo_size = 0, -+ .callback = service_callback, -+ .callback_param = NULL, -+ .want_unaligned_bulk_rx = 1, -+ .want_unaligned_bulk_tx = 1, -+ .want_crc = 0 -+ }; -+ -+ /* compile time checks to ensure structure size as they are -+ * directly (de)serialised from memory. -+ */ -+ -+ /* ensure the header structure has packed to the correct size */ -+ BUILD_BUG_ON(sizeof(struct mmal_msg_header) != 24); -+ -+ /* ensure message structure does not exceed maximum length */ -+ BUILD_BUG_ON(sizeof(struct mmal_msg) > MMAL_MSG_MAX_SIZE); -+ -+ /* mmal port struct is correct size */ -+ BUILD_BUG_ON(sizeof(struct mmal_port) != 64); -+ -+ /* create a vchi instance */ -+ status = vchi_initialise(&vchi_instance); -+ if (status) { -+ pr_err("Failed to initialise VCHI instance (status=%d)\n", -+ status); -+ return -EIO; -+ } -+ -+ status = vchi_connect(NULL, 0, vchi_instance); -+ if (status) { -+ pr_err("Failed to connect VCHI instance (status=%d)\n", status); -+ return -EIO; -+ } -+ -+ instance = kzalloc(sizeof(*instance), GFP_KERNEL); -+ -+ if (!instance) -+ return -ENOMEM; -+ -+ mutex_init(&instance->vchiq_mutex); -+ -+ instance->bulk_scratch = vmalloc(PAGE_SIZE); -+ -+ mutex_init(&instance->context_map_lock); -+ idr_init_base(&instance->context_map, 1); -+ -+ params.callback_param = instance; -+ -+ instance->bulk_wq = alloc_ordered_workqueue("mmal-vchiq", -+ WQ_MEM_RECLAIM); -+ if (!instance->bulk_wq) -+ goto err_free; -+ -+ status = vchi_service_open(vchi_instance, ¶ms, &instance->handle); -+ if (status) { -+ pr_err("Failed to open VCHI service connection (status=%d)\n", -+ status); -+ goto err_close_services; -+ } -+ -+ vchi_service_release(instance->handle); -+ -+ *out_instance = instance; -+ -+ return 0; -+ -+err_close_services: -+ vchi_service_close(instance->handle); -+ destroy_workqueue(instance->bulk_wq); -+err_free: -+ vfree(instance->bulk_scratch); -+ kfree(instance); -+ return -ENODEV; -+} -+EXPORT_SYMBOL_GPL(vchiq_mmal_init); ---- a/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h -+++ /dev/null -@@ -1,61 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Broadcom BM2835 V4L2 driver -- * -- * Copyright © 2013 Raspberry Pi (Trading) Ltd. -- * -- * Authors: Vincent Sanders @ Collabora -- * Dave Stevenson @ Broadcom -- * (now dave.stevenson@raspberrypi.org) -- * Simon Mellor @ Broadcom -- * Luke Diamand @ Broadcom -- * -- * MMAL structures -- * -- */ --#ifndef MMAL_COMMON_H --#define MMAL_COMMON_H -- --#define MMAL_FOURCC(a, b, c, d) ((a) | (b << 8) | (c << 16) | (d << 24)) --#define MMAL_MAGIC MMAL_FOURCC('m', 'm', 'a', 'l') -- --/** Special value signalling that time is not known */ --#define MMAL_TIME_UNKNOWN BIT_ULL(63) -- --struct mmal_msg_context; -- --/* mapping between v4l and mmal video modes */ --struct mmal_fmt { -- char *name; -- u32 fourcc; /* v4l2 format id */ -- int flags; /* v4l2 flags field */ -- u32 mmal; -- int depth; -- u32 mmal_component; /* MMAL component index to be used to encode */ -- u32 ybbp; /* depth of first Y plane for planar formats */ -- bool remove_padding; /* Does the GPU have to remove padding, -- * or can we do hide padding via bytesperline. -- */ --}; -- --/* buffer for one video frame */ --struct mmal_buffer { -- /* v4l buffer data -- must be first */ -- struct vb2_v4l2_buffer vb; -- -- /* list of buffers available */ -- struct list_head list; -- -- void *buffer; /* buffer pointer */ -- unsigned long buffer_size; /* size of allocated buffer */ -- -- struct mmal_msg_context *msg_context; --}; -- --/* */ --struct mmal_colourfx { -- s32 enable; -- u32 u; -- u32 v; --}; --#endif ---- a/drivers/staging/vc04_services/bcm2835-camera/mmal-encodings.h -+++ /dev/null -@@ -1,124 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Broadcom BM2835 V4L2 driver -- * -- * Copyright © 2013 Raspberry Pi (Trading) Ltd. -- * -- * Authors: Vincent Sanders @ Collabora -- * Dave Stevenson @ Broadcom -- * (now dave.stevenson@raspberrypi.org) -- * Simon Mellor @ Broadcom -- * Luke Diamand @ Broadcom -- */ --#ifndef MMAL_ENCODINGS_H --#define MMAL_ENCODINGS_H -- --#define MMAL_ENCODING_H264 MMAL_FOURCC('H', '2', '6', '4') --#define MMAL_ENCODING_H263 MMAL_FOURCC('H', '2', '6', '3') --#define MMAL_ENCODING_MP4V MMAL_FOURCC('M', 'P', '4', 'V') --#define MMAL_ENCODING_MP2V MMAL_FOURCC('M', 'P', '2', 'V') --#define MMAL_ENCODING_MP1V MMAL_FOURCC('M', 'P', '1', 'V') --#define MMAL_ENCODING_WMV3 MMAL_FOURCC('W', 'M', 'V', '3') --#define MMAL_ENCODING_WMV2 MMAL_FOURCC('W', 'M', 'V', '2') --#define MMAL_ENCODING_WMV1 MMAL_FOURCC('W', 'M', 'V', '1') --#define MMAL_ENCODING_WVC1 MMAL_FOURCC('W', 'V', 'C', '1') --#define MMAL_ENCODING_VP8 MMAL_FOURCC('V', 'P', '8', ' ') --#define MMAL_ENCODING_VP7 MMAL_FOURCC('V', 'P', '7', ' ') --#define MMAL_ENCODING_VP6 MMAL_FOURCC('V', 'P', '6', ' ') --#define MMAL_ENCODING_THEORA MMAL_FOURCC('T', 'H', 'E', 'O') --#define MMAL_ENCODING_SPARK MMAL_FOURCC('S', 'P', 'R', 'K') --#define MMAL_ENCODING_MJPEG MMAL_FOURCC('M', 'J', 'P', 'G') -- --#define MMAL_ENCODING_JPEG MMAL_FOURCC('J', 'P', 'E', 'G') --#define MMAL_ENCODING_GIF MMAL_FOURCC('G', 'I', 'F', ' ') --#define MMAL_ENCODING_PNG MMAL_FOURCC('P', 'N', 'G', ' ') --#define MMAL_ENCODING_PPM MMAL_FOURCC('P', 'P', 'M', ' ') --#define MMAL_ENCODING_TGA MMAL_FOURCC('T', 'G', 'A', ' ') --#define MMAL_ENCODING_BMP MMAL_FOURCC('B', 'M', 'P', ' ') -- --#define MMAL_ENCODING_I420 MMAL_FOURCC('I', '4', '2', '0') --#define MMAL_ENCODING_I420_SLICE MMAL_FOURCC('S', '4', '2', '0') --#define MMAL_ENCODING_YV12 MMAL_FOURCC('Y', 'V', '1', '2') --#define MMAL_ENCODING_I422 MMAL_FOURCC('I', '4', '2', '2') --#define MMAL_ENCODING_I422_SLICE MMAL_FOURCC('S', '4', '2', '2') --#define MMAL_ENCODING_YUYV MMAL_FOURCC('Y', 'U', 'Y', 'V') --#define MMAL_ENCODING_YVYU MMAL_FOURCC('Y', 'V', 'Y', 'U') --#define MMAL_ENCODING_UYVY MMAL_FOURCC('U', 'Y', 'V', 'Y') --#define MMAL_ENCODING_VYUY MMAL_FOURCC('V', 'Y', 'U', 'Y') --#define MMAL_ENCODING_NV12 MMAL_FOURCC('N', 'V', '1', '2') --#define MMAL_ENCODING_NV21 MMAL_FOURCC('N', 'V', '2', '1') --#define MMAL_ENCODING_ARGB MMAL_FOURCC('A', 'R', 'G', 'B') --#define MMAL_ENCODING_RGBA MMAL_FOURCC('R', 'G', 'B', 'A') --#define MMAL_ENCODING_ABGR MMAL_FOURCC('A', 'B', 'G', 'R') --#define MMAL_ENCODING_BGRA MMAL_FOURCC('B', 'G', 'R', 'A') --#define MMAL_ENCODING_RGB16 MMAL_FOURCC('R', 'G', 'B', '2') --#define MMAL_ENCODING_RGB24 MMAL_FOURCC('R', 'G', 'B', '3') --#define MMAL_ENCODING_RGB32 MMAL_FOURCC('R', 'G', 'B', '4') --#define MMAL_ENCODING_BGR16 MMAL_FOURCC('B', 'G', 'R', '2') --#define MMAL_ENCODING_BGR24 MMAL_FOURCC('B', 'G', 'R', '3') --#define MMAL_ENCODING_BGR32 MMAL_FOURCC('B', 'G', 'R', '4') -- --/** SAND Video (YUVUV128) format, native format understood by VideoCore. -- * This format is *not* opaque - if requested you will receive full frames -- * of YUV_UV video. -- */ --#define MMAL_ENCODING_YUVUV128 MMAL_FOURCC('S', 'A', 'N', 'D') -- --/** VideoCore opaque image format, image handles are returned to -- * the host but not the actual image data. -- */ --#define MMAL_ENCODING_OPAQUE MMAL_FOURCC('O', 'P', 'Q', 'V') -- --/** An EGL image handle -- */ --#define MMAL_ENCODING_EGL_IMAGE MMAL_FOURCC('E', 'G', 'L', 'I') -- --/* }@ */ -- --/** \name Pre-defined audio encodings */ --/* @{ */ --#define MMAL_ENCODING_PCM_UNSIGNED_BE MMAL_FOURCC('P', 'C', 'M', 'U') --#define MMAL_ENCODING_PCM_UNSIGNED_LE MMAL_FOURCC('p', 'c', 'm', 'u') --#define MMAL_ENCODING_PCM_SIGNED_BE MMAL_FOURCC('P', 'C', 'M', 'S') --#define MMAL_ENCODING_PCM_SIGNED_LE MMAL_FOURCC('p', 'c', 'm', 's') --#define MMAL_ENCODING_PCM_FLOAT_BE MMAL_FOURCC('P', 'C', 'M', 'F') --#define MMAL_ENCODING_PCM_FLOAT_LE MMAL_FOURCC('p', 'c', 'm', 'f') -- --/* Pre-defined H264 encoding variants */ -- --/** ISO 14496-10 Annex B byte stream format */ --#define MMAL_ENCODING_VARIANT_H264_DEFAULT 0 --/** ISO 14496-15 AVC stream format */ --#define MMAL_ENCODING_VARIANT_H264_AVC1 MMAL_FOURCC('A', 'V', 'C', '1') --/** Implicitly delineated NAL units without emulation prevention */ --#define MMAL_ENCODING_VARIANT_H264_RAW MMAL_FOURCC('R', 'A', 'W', ' ') -- --/** \defgroup MmalColorSpace List of pre-defined video color spaces -- * This defines a list of common color spaces. This list isn't exhaustive and -- * is only provided as a convenience to avoid clients having to use FourCC -- * codes directly. However components are allowed to define and use their own -- * FourCC codes. -- */ --/* @{ */ -- --/** Unknown color space */ --#define MMAL_COLOR_SPACE_UNKNOWN 0 --/** ITU-R BT.601-5 [SDTV] */ --#define MMAL_COLOR_SPACE_ITUR_BT601 MMAL_FOURCC('Y', '6', '0', '1') --/** ITU-R BT.709-3 [HDTV] */ --#define MMAL_COLOR_SPACE_ITUR_BT709 MMAL_FOURCC('Y', '7', '0', '9') --/** JPEG JFIF */ --#define MMAL_COLOR_SPACE_JPEG_JFIF MMAL_FOURCC('Y', 'J', 'F', 'I') --/** Title 47 Code of Federal Regulations (2003) 73.682 (a) (20) */ --#define MMAL_COLOR_SPACE_FCC MMAL_FOURCC('Y', 'F', 'C', 'C') --/** Society of Motion Picture and Television Engineers 240M (1999) */ --#define MMAL_COLOR_SPACE_SMPTE240M MMAL_FOURCC('Y', '2', '4', '0') --/** ITU-R BT.470-2 System M */ --#define MMAL_COLOR_SPACE_BT470_2_M MMAL_FOURCC('Y', '_', '_', 'M') --/** ITU-R BT.470-2 System BG */ --#define MMAL_COLOR_SPACE_BT470_2_BG MMAL_FOURCC('Y', '_', 'B', 'G') --/** JPEG JFIF, but with 16..255 luma */ --#define MMAL_COLOR_SPACE_JFIF_Y16_255 MMAL_FOURCC('Y', 'Y', '1', '6') --/* @} MmalColorSpace List */ -- --#endif /* MMAL_ENCODINGS_H */ ---- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-common.h -+++ /dev/null -@@ -1,48 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Broadcom BM2835 V4L2 driver -- * -- * Copyright © 2013 Raspberry Pi (Trading) Ltd. -- * -- * Authors: Vincent Sanders @ Collabora -- * Dave Stevenson @ Broadcom -- * (now dave.stevenson@raspberrypi.org) -- * Simon Mellor @ Broadcom -- * Luke Diamand @ Broadcom -- */ -- --#ifndef MMAL_MSG_COMMON_H --#define MMAL_MSG_COMMON_H -- --enum mmal_msg_status { -- MMAL_MSG_STATUS_SUCCESS = 0, /**< Success */ -- MMAL_MSG_STATUS_ENOMEM, /**< Out of memory */ -- MMAL_MSG_STATUS_ENOSPC, /**< Out of resources other than memory */ -- MMAL_MSG_STATUS_EINVAL, /**< Argument is invalid */ -- MMAL_MSG_STATUS_ENOSYS, /**< Function not implemented */ -- MMAL_MSG_STATUS_ENOENT, /**< No such file or directory */ -- MMAL_MSG_STATUS_ENXIO, /**< No such device or address */ -- MMAL_MSG_STATUS_EIO, /**< I/O error */ -- MMAL_MSG_STATUS_ESPIPE, /**< Illegal seek */ -- MMAL_MSG_STATUS_ECORRUPT, /**< Data is corrupt \attention */ -- MMAL_MSG_STATUS_ENOTREADY, /**< Component is not ready */ -- MMAL_MSG_STATUS_ECONFIG, /**< Component is not configured */ -- MMAL_MSG_STATUS_EISCONN, /**< Port is already connected */ -- MMAL_MSG_STATUS_ENOTCONN, /**< Port is disconnected */ -- MMAL_MSG_STATUS_EAGAIN, /**< Resource temporarily unavailable. */ -- MMAL_MSG_STATUS_EFAULT, /**< Bad address */ --}; -- --struct mmal_rect { -- s32 x; /**< x coordinate (from left) */ -- s32 y; /**< y coordinate (from top) */ -- s32 width; /**< width */ -- s32 height; /**< height */ --}; -- --struct mmal_rational { -- s32 num; /**< Numerator */ -- s32 den; /**< Denominator */ --}; -- --#endif /* MMAL_MSG_COMMON_H */ ---- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-format.h -+++ /dev/null -@@ -1,106 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Broadcom BM2835 V4L2 driver -- * -- * Copyright © 2013 Raspberry Pi (Trading) Ltd. -- * -- * Authors: Vincent Sanders @ Collabora -- * Dave Stevenson @ Broadcom -- * (now dave.stevenson@raspberrypi.org) -- * Simon Mellor @ Broadcom -- * Luke Diamand @ Broadcom -- */ -- --#ifndef MMAL_MSG_FORMAT_H --#define MMAL_MSG_FORMAT_H -- --#include "mmal-msg-common.h" -- --/* MMAL_ES_FORMAT_T */ -- --struct mmal_audio_format { -- u32 channels; /* Number of audio channels */ -- u32 sample_rate; /* Sample rate */ -- -- u32 bits_per_sample; /* Bits per sample */ -- u32 block_align; /* Size of a block of data */ --}; -- --struct mmal_video_format { -- u32 width; /* Width of frame in pixels */ -- u32 height; /* Height of frame in rows of pixels */ -- struct mmal_rect crop; /* Visible region of the frame */ -- struct mmal_rational frame_rate; /* Frame rate */ -- struct mmal_rational par; /* Pixel aspect ratio */ -- -- /* -- * FourCC specifying the color space of the video stream. See the -- * MmalColorSpace "pre-defined color spaces" for some examples. -- */ -- u32 color_space; --}; -- --struct mmal_subpicture_format { -- u32 x_offset; -- u32 y_offset; --}; -- --union mmal_es_specific_format { -- struct mmal_audio_format audio; -- struct mmal_video_format video; -- struct mmal_subpicture_format subpicture; --}; -- --/* Definition of an elementary stream format (MMAL_ES_FORMAT_T) */ --struct mmal_es_format_local { -- u32 type; /* enum mmal_es_type */ -- -- u32 encoding; /* FourCC specifying encoding of the elementary -- * stream. -- */ -- u32 encoding_variant; /* FourCC specifying the specific -- * encoding variant of the elementary -- * stream. -- */ -- -- union mmal_es_specific_format *es; /* Type specific -- * information for the -- * elementary stream -- */ -- -- u32 bitrate; /* Bitrate in bits per second */ -- u32 flags; /* Flags describing properties of the elementary -- * stream. -- */ -- -- u32 extradata_size; /* Size of the codec specific data */ -- u8 *extradata; /* Codec specific data */ --}; -- --/* Remote definition of an elementary stream format (MMAL_ES_FORMAT_T) */ --struct mmal_es_format { -- u32 type; /* enum mmal_es_type */ -- -- u32 encoding; /* FourCC specifying encoding of the elementary -- * stream. -- */ -- u32 encoding_variant; /* FourCC specifying the specific -- * encoding variant of the elementary -- * stream. -- */ -- -- u32 es; /* Type specific -- * information for the -- * elementary stream -- */ -- -- u32 bitrate; /* Bitrate in bits per second */ -- u32 flags; /* Flags describing properties of the elementary -- * stream. -- */ -- -- u32 extradata_size; /* Size of the codec specific data */ -- u32 extradata; /* Codec specific data */ --}; -- --#endif /* MMAL_MSG_FORMAT_H */ ---- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-port.h -+++ /dev/null -@@ -1,109 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Broadcom BM2835 V4L2 driver -- * -- * Copyright © 2013 Raspberry Pi (Trading) Ltd. -- * -- * Authors: Vincent Sanders @ Collabora -- * Dave Stevenson @ Broadcom -- * (now dave.stevenson@raspberrypi.org) -- * Simon Mellor @ Broadcom -- * Luke Diamand @ Broadcom -- */ -- --/* MMAL_PORT_TYPE_T */ --enum mmal_port_type { -- MMAL_PORT_TYPE_UNKNOWN = 0, /* Unknown port type */ -- MMAL_PORT_TYPE_CONTROL, /* Control port */ -- MMAL_PORT_TYPE_INPUT, /* Input port */ -- MMAL_PORT_TYPE_OUTPUT, /* Output port */ -- MMAL_PORT_TYPE_CLOCK, /* Clock port */ --}; -- --/* The port is pass-through and doesn't need buffer headers allocated */ --#define MMAL_PORT_CAPABILITY_PASSTHROUGH 0x01 --/* -- *The port wants to allocate the buffer payloads. -- * This signals a preference that payload allocation should be done -- * on this port for efficiency reasons. -- */ --#define MMAL_PORT_CAPABILITY_ALLOCATION 0x02 --/* -- * The port supports format change events. -- * This applies to input ports and is used to let the client know -- * whether the port supports being reconfigured via a format -- * change event (i.e. without having to disable the port). -- */ --#define MMAL_PORT_CAPABILITY_SUPPORTS_EVENT_FORMAT_CHANGE 0x04 -- --/* -- * mmal port structure (MMAL_PORT_T) -- * -- * most elements are informational only, the pointer values for -- * interogation messages are generally provided as additional -- * structures within the message. When used to set values only the -- * buffer_num, buffer_size and userdata parameters are writable. -- */ --struct mmal_port { -- u32 priv; /* Private member used by the framework */ -- u32 name; /* Port name. Used for debugging purposes (RO) */ -- -- u32 type; /* Type of the port (RO) enum mmal_port_type */ -- u16 index; /* Index of the port in its type list (RO) */ -- u16 index_all; /* Index of the port in the list of all ports (RO) */ -- -- u32 is_enabled; /* Indicates whether the port is enabled or not (RO) */ -- u32 format; /* Format of the elementary stream */ -- -- u32 buffer_num_min; /* Minimum number of buffers the port -- * requires (RO). This is set by the -- * component. -- */ -- -- u32 buffer_size_min; /* Minimum size of buffers the port -- * requires (RO). This is set by the -- * component. -- */ -- -- u32 buffer_alignment_min;/* Minimum alignment requirement for -- * the buffers (RO). A value of -- * zero means no special alignment -- * requirements. This is set by the -- * component. -- */ -- -- u32 buffer_num_recommended; /* Number of buffers the port -- * recommends for optimal -- * performance (RO). A value of -- * zero means no special -- * recommendation. This is set -- * by the component. -- */ -- -- u32 buffer_size_recommended; /* Size of buffers the port -- * recommends for optimal -- * performance (RO). A value of -- * zero means no special -- * recommendation. This is set -- * by the component. -- */ -- -- u32 buffer_num; /* Actual number of buffers the port will use. -- * This is set by the client. -- */ -- -- u32 buffer_size; /* Actual maximum size of the buffers that -- * will be sent to the port. This is set by -- * the client. -- */ -- -- u32 component; /* Component this port belongs to (Read Only) */ -- -- u32 userdata; /* Field reserved for use by the client */ -- -- u32 capabilities; /* Flags describing the capabilities of a -- * port (RO). Bitwise combination of \ref -- * portcapabilities "Port capabilities" -- * values. -- */ --}; ---- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg.h -+++ /dev/null -@@ -1,406 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Broadcom BM2835 V4L2 driver -- * -- * Copyright © 2013 Raspberry Pi (Trading) Ltd. -- * -- * Authors: Vincent Sanders @ Collabora -- * Dave Stevenson @ Broadcom -- * (now dave.stevenson@raspberrypi.org) -- * Simon Mellor @ Broadcom -- * Luke Diamand @ Broadcom -- */ -- --/* -- * all the data structures which serialise the MMAL protocol. note -- * these are directly mapped onto the recived message data. -- * -- * BEWARE: They seem to *assume* pointers are u32 and that there is no -- * structure padding! -- * -- * NOTE: this implementation uses kernel types to ensure sizes. Rather -- * than assigning values to enums to force their size the -- * implementation uses fixed size types and not the enums (though the -- * comments have the actual enum type -- */ --#ifndef MMAL_MSG_H --#define MMAL_MSG_H -- --#define VC_MMAL_VER 15 --#define VC_MMAL_MIN_VER 10 --#define VC_MMAL_SERVER_NAME MAKE_FOURCC("mmal") -- --/* max total message size is 512 bytes */ --#define MMAL_MSG_MAX_SIZE 512 --/* with six 32bit header elements max payload is therefore 488 bytes */ --#define MMAL_MSG_MAX_PAYLOAD 488 -- --#include "mmal-msg-common.h" --#include "mmal-msg-format.h" --#include "mmal-msg-port.h" -- --enum mmal_msg_type { -- MMAL_MSG_TYPE_QUIT = 1, -- MMAL_MSG_TYPE_SERVICE_CLOSED, -- MMAL_MSG_TYPE_GET_VERSION, -- MMAL_MSG_TYPE_COMPONENT_CREATE, -- MMAL_MSG_TYPE_COMPONENT_DESTROY, /* 5 */ -- MMAL_MSG_TYPE_COMPONENT_ENABLE, -- MMAL_MSG_TYPE_COMPONENT_DISABLE, -- MMAL_MSG_TYPE_PORT_INFO_GET, -- MMAL_MSG_TYPE_PORT_INFO_SET, -- MMAL_MSG_TYPE_PORT_ACTION, /* 10 */ -- MMAL_MSG_TYPE_BUFFER_FROM_HOST, -- MMAL_MSG_TYPE_BUFFER_TO_HOST, -- MMAL_MSG_TYPE_GET_STATS, -- MMAL_MSG_TYPE_PORT_PARAMETER_SET, -- MMAL_MSG_TYPE_PORT_PARAMETER_GET, /* 15 */ -- MMAL_MSG_TYPE_EVENT_TO_HOST, -- MMAL_MSG_TYPE_GET_CORE_STATS_FOR_PORT, -- MMAL_MSG_TYPE_OPAQUE_ALLOCATOR, -- MMAL_MSG_TYPE_CONSUME_MEM, -- MMAL_MSG_TYPE_LMK, /* 20 */ -- MMAL_MSG_TYPE_OPAQUE_ALLOCATOR_DESC, -- MMAL_MSG_TYPE_DRM_GET_LHS32, -- MMAL_MSG_TYPE_DRM_GET_TIME, -- MMAL_MSG_TYPE_BUFFER_FROM_HOST_ZEROLEN, -- MMAL_MSG_TYPE_PORT_FLUSH, /* 25 */ -- MMAL_MSG_TYPE_HOST_LOG, -- MMAL_MSG_TYPE_MSG_LAST --}; -- --/* port action request messages differ depending on the action type */ --enum mmal_msg_port_action_type { -- MMAL_MSG_PORT_ACTION_TYPE_UNKNOWN = 0, /* Unknown action */ -- MMAL_MSG_PORT_ACTION_TYPE_ENABLE, /* Enable a port */ -- MMAL_MSG_PORT_ACTION_TYPE_DISABLE, /* Disable a port */ -- MMAL_MSG_PORT_ACTION_TYPE_FLUSH, /* Flush a port */ -- MMAL_MSG_PORT_ACTION_TYPE_CONNECT, /* Connect ports */ -- MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT, /* Disconnect ports */ -- MMAL_MSG_PORT_ACTION_TYPE_SET_REQUIREMENTS, /* Set buffer requirements*/ --}; -- --struct mmal_msg_header { -- u32 magic; -- u32 type; /* enum mmal_msg_type */ -- -- /* Opaque handle to the control service */ -- u32 control_service; -- -- u32 context; /* a u32 per message context */ -- u32 status; /* The status of the vchiq operation */ -- u32 padding; --}; -- --/* Send from VC to host to report version */ --struct mmal_msg_version { -- u32 flags; -- u32 major; -- u32 minor; -- u32 minimum; --}; -- --/* request to VC to create component */ --struct mmal_msg_component_create { -- u32 client_component; /* component context */ -- char name[128]; -- u32 pid; /* For debug */ --}; -- --/* reply from VC to component creation request */ --struct mmal_msg_component_create_reply { -- u32 status; /* enum mmal_msg_status - how does this differ to -- * the one in the header? -- */ -- u32 component_handle; /* VideoCore handle for component */ -- u32 input_num; /* Number of input ports */ -- u32 output_num; /* Number of output ports */ -- u32 clock_num; /* Number of clock ports */ --}; -- --/* request to VC to destroy a component */ --struct mmal_msg_component_destroy { -- u32 component_handle; --}; -- --struct mmal_msg_component_destroy_reply { -- u32 status; /* The component destruction status */ --}; -- --/* request and reply to VC to enable a component */ --struct mmal_msg_component_enable { -- u32 component_handle; --}; -- --struct mmal_msg_component_enable_reply { -- u32 status; /* The component enable status */ --}; -- --/* request and reply to VC to disable a component */ --struct mmal_msg_component_disable { -- u32 component_handle; --}; -- --struct mmal_msg_component_disable_reply { -- u32 status; /* The component disable status */ --}; -- --/* request to VC to get port information */ --struct mmal_msg_port_info_get { -- u32 component_handle; /* component handle port is associated with */ -- u32 port_type; /* enum mmal_msg_port_type */ -- u32 index; /* port index to query */ --}; -- --/* reply from VC to get port info request */ --struct mmal_msg_port_info_get_reply { -- u32 status; /* enum mmal_msg_status */ -- u32 component_handle; /* component handle port is associated with */ -- u32 port_type; /* enum mmal_msg_port_type */ -- u32 port_index; /* port indexed in query */ -- s32 found; /* unused */ -- u32 port_handle; /* Handle to use for this port */ -- struct mmal_port port; -- struct mmal_es_format format; /* elementary stream format */ -- union mmal_es_specific_format es; /* es type specific data */ -- u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; /* es extra data */ --}; -- --/* request to VC to set port information */ --struct mmal_msg_port_info_set { -- u32 component_handle; -- u32 port_type; /* enum mmal_msg_port_type */ -- u32 port_index; /* port indexed in query */ -- struct mmal_port port; -- struct mmal_es_format format; -- union mmal_es_specific_format es; -- u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; --}; -- --/* reply from VC to port info set request */ --struct mmal_msg_port_info_set_reply { -- u32 status; -- u32 component_handle; /* component handle port is associated with */ -- u32 port_type; /* enum mmal_msg_port_type */ -- u32 index; /* port indexed in query */ -- s32 found; /* unused */ -- u32 port_handle; /* Handle to use for this port */ -- struct mmal_port port; -- struct mmal_es_format format; -- union mmal_es_specific_format es; -- u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; --}; -- --/* port action requests that take a mmal_port as a parameter */ --struct mmal_msg_port_action_port { -- u32 component_handle; -- u32 port_handle; -- u32 action; /* enum mmal_msg_port_action_type */ -- struct mmal_port port; --}; -- --/* port action requests that take handles as a parameter */ --struct mmal_msg_port_action_handle { -- u32 component_handle; -- u32 port_handle; -- u32 action; /* enum mmal_msg_port_action_type */ -- u32 connect_component_handle; -- u32 connect_port_handle; --}; -- --struct mmal_msg_port_action_reply { -- u32 status; /* The port action operation status */ --}; -- --/* MMAL buffer transfer */ -- --/* Size of space reserved in a buffer message for short messages. */ --#define MMAL_VC_SHORT_DATA 128 -- --/* Signals that the current payload is the end of the stream of data */ --#define MMAL_BUFFER_HEADER_FLAG_EOS BIT(0) --/* Signals that the start of the current payload starts a frame */ --#define MMAL_BUFFER_HEADER_FLAG_FRAME_START BIT(1) --/* Signals that the end of the current payload ends a frame */ --#define MMAL_BUFFER_HEADER_FLAG_FRAME_END BIT(2) --/* Signals that the current payload contains only complete frames (>1) */ --#define MMAL_BUFFER_HEADER_FLAG_FRAME \ -- (MMAL_BUFFER_HEADER_FLAG_FRAME_START | \ -- MMAL_BUFFER_HEADER_FLAG_FRAME_END) --/* Signals that the current payload is a keyframe (i.e. self decodable) */ --#define MMAL_BUFFER_HEADER_FLAG_KEYFRAME BIT(3) --/* -- * Signals a discontinuity in the stream of data (e.g. after a seek). -- * Can be used for instance by a decoder to reset its state -- */ --#define MMAL_BUFFER_HEADER_FLAG_DISCONTINUITY BIT(4) --/* -- * Signals a buffer containing some kind of config data for the component -- * (e.g. codec config data) -- */ --#define MMAL_BUFFER_HEADER_FLAG_CONFIG BIT(5) --/* Signals an encrypted payload */ --#define MMAL_BUFFER_HEADER_FLAG_ENCRYPTED BIT(6) --/* Signals a buffer containing side information */ --#define MMAL_BUFFER_HEADER_FLAG_CODECSIDEINFO BIT(7) --/* -- * Signals a buffer which is the snapshot/postview image from a stills -- * capture -- */ --#define MMAL_BUFFER_HEADER_FLAGS_SNAPSHOT BIT(8) --/* Signals a buffer which contains data known to be corrupted */ --#define MMAL_BUFFER_HEADER_FLAG_CORRUPTED BIT(9) --/* Signals that a buffer failed to be transmitted */ --#define MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED BIT(10) -- --struct mmal_driver_buffer { -- u32 magic; -- u32 component_handle; -- u32 port_handle; -- u32 client_context; --}; -- --/* buffer header */ --struct mmal_buffer_header { -- u32 next; /* next header */ -- u32 priv; /* framework private data */ -- u32 cmd; -- u32 data; -- u32 alloc_size; -- u32 length; -- u32 offset; -- u32 flags; -- s64 pts; -- s64 dts; -- u32 type; -- u32 user_data; --}; -- --struct mmal_buffer_header_type_specific { -- union { -- struct { -- u32 planes; -- u32 offset[4]; -- u32 pitch[4]; -- u32 flags; -- } video; -- } u; --}; -- --struct mmal_msg_buffer_from_host { -- /* -- *The front 32 bytes of the buffer header are copied -- * back to us in the reply to allow for context. This -- * area is used to store two mmal_driver_buffer structures to -- * allow for multiple concurrent service users. -- */ -- /* control data */ -- struct mmal_driver_buffer drvbuf; -- -- /* referenced control data for passthrough buffer management */ -- struct mmal_driver_buffer drvbuf_ref; -- struct mmal_buffer_header buffer_header; /* buffer header itself */ -- struct mmal_buffer_header_type_specific buffer_header_type_specific; -- s32 is_zero_copy; -- s32 has_reference; -- -- /* allows short data to be xfered in control message */ -- u32 payload_in_message; -- u8 short_data[MMAL_VC_SHORT_DATA]; --}; -- --/* port parameter setting */ -- --#define MMAL_WORKER_PORT_PARAMETER_SPACE 96 -- --struct mmal_msg_port_parameter_set { -- u32 component_handle; /* component */ -- u32 port_handle; /* port */ -- u32 id; /* Parameter ID */ -- u32 size; /* Parameter size */ -- uint32_t value[MMAL_WORKER_PORT_PARAMETER_SPACE]; --}; -- --struct mmal_msg_port_parameter_set_reply { -- u32 status; /* enum mmal_msg_status todo: how does this -- * differ to the one in the header? -- */ --}; -- --/* port parameter getting */ -- --struct mmal_msg_port_parameter_get { -- u32 component_handle; /* component */ -- u32 port_handle; /* port */ -- u32 id; /* Parameter ID */ -- u32 size; /* Parameter size */ --}; -- --struct mmal_msg_port_parameter_get_reply { -- u32 status; /* Status of mmal_port_parameter_get call */ -- u32 id; /* Parameter ID */ -- u32 size; /* Parameter size */ -- uint32_t value[MMAL_WORKER_PORT_PARAMETER_SPACE]; --}; -- --/* event messages */ --#define MMAL_WORKER_EVENT_SPACE 256 -- --struct mmal_msg_event_to_host { -- u32 client_component; /* component context */ -- -- u32 port_type; -- u32 port_num; -- -- u32 cmd; -- u32 length; -- u8 data[MMAL_WORKER_EVENT_SPACE]; -- u32 delayed_buffer; --}; -- --/* all mmal messages are serialised through this structure */ --struct mmal_msg { -- /* header */ -- struct mmal_msg_header h; -- /* payload */ -- union { -- struct mmal_msg_version version; -- -- struct mmal_msg_component_create component_create; -- struct mmal_msg_component_create_reply component_create_reply; -- -- struct mmal_msg_component_destroy component_destroy; -- struct mmal_msg_component_destroy_reply component_destroy_reply; -- -- struct mmal_msg_component_enable component_enable; -- struct mmal_msg_component_enable_reply component_enable_reply; -- -- struct mmal_msg_component_disable component_disable; -- struct mmal_msg_component_disable_reply component_disable_reply; -- -- struct mmal_msg_port_info_get port_info_get; -- struct mmal_msg_port_info_get_reply port_info_get_reply; -- -- struct mmal_msg_port_info_set port_info_set; -- struct mmal_msg_port_info_set_reply port_info_set_reply; -- -- struct mmal_msg_port_action_port port_action_port; -- struct mmal_msg_port_action_handle port_action_handle; -- struct mmal_msg_port_action_reply port_action_reply; -- -- struct mmal_msg_buffer_from_host buffer_from_host; -- -- struct mmal_msg_port_parameter_set port_parameter_set; -- struct mmal_msg_port_parameter_set_reply -- port_parameter_set_reply; -- struct mmal_msg_port_parameter_get -- port_parameter_get; -- struct mmal_msg_port_parameter_get_reply -- port_parameter_get_reply; -- -- struct mmal_msg_event_to_host event_to_host; -- -- u8 payload[MMAL_MSG_MAX_PAYLOAD]; -- } u; --}; --#endif ---- a/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h -+++ /dev/null -@@ -1,755 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Broadcom BM2835 V4L2 driver -- * -- * Copyright © 2013 Raspberry Pi (Trading) Ltd. -- * -- * Authors: Vincent Sanders @ Collabora -- * Dave Stevenson @ Broadcom -- * (now dave.stevenson@raspberrypi.org) -- * Simon Mellor @ Broadcom -- * Luke Diamand @ Broadcom -- */ -- --/* common parameters */ -- --/** @name Parameter groups -- * Parameters are divided into groups, and then allocated sequentially within -- * a group using an enum. -- * @{ -- */ -- --#ifndef MMAL_PARAMETERS_H --#define MMAL_PARAMETERS_H -- --/** Common parameter ID group, used with many types of component. */ --#define MMAL_PARAMETER_GROUP_COMMON (0 << 16) --/** Camera-specific parameter ID group. */ --#define MMAL_PARAMETER_GROUP_CAMERA (1 << 16) --/** Video-specific parameter ID group. */ --#define MMAL_PARAMETER_GROUP_VIDEO (2 << 16) --/** Audio-specific parameter ID group. */ --#define MMAL_PARAMETER_GROUP_AUDIO (3 << 16) --/** Clock-specific parameter ID group. */ --#define MMAL_PARAMETER_GROUP_CLOCK (4 << 16) --/** Miracast-specific parameter ID group. */ --#define MMAL_PARAMETER_GROUP_MIRACAST (5 << 16) -- --/* Common parameters */ --enum mmal_parameter_common_type { -- /**< Never a valid parameter ID */ -- MMAL_PARAMETER_UNUSED = MMAL_PARAMETER_GROUP_COMMON, -- -- /**< MMAL_PARAMETER_ENCODING_T */ -- MMAL_PARAMETER_SUPPORTED_ENCODINGS, -- /**< MMAL_PARAMETER_URI_T */ -- MMAL_PARAMETER_URI, -- /** MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T */ -- MMAL_PARAMETER_CHANGE_EVENT_REQUEST, -- /** MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_ZERO_COPY, -- /**< MMAL_PARAMETER_BUFFER_REQUIREMENTS_T */ -- MMAL_PARAMETER_BUFFER_REQUIREMENTS, -- /**< MMAL_PARAMETER_STATISTICS_T */ -- MMAL_PARAMETER_STATISTICS, -- /**< MMAL_PARAMETER_CORE_STATISTICS_T */ -- MMAL_PARAMETER_CORE_STATISTICS, -- /**< MMAL_PARAMETER_MEM_USAGE_T */ -- MMAL_PARAMETER_MEM_USAGE, -- /**< MMAL_PARAMETER_UINT32_T */ -- MMAL_PARAMETER_BUFFER_FLAG_FILTER, -- /**< MMAL_PARAMETER_SEEK_T */ -- MMAL_PARAMETER_SEEK, -- /**< MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_POWERMON_ENABLE, -- /**< MMAL_PARAMETER_LOGGING_T */ -- MMAL_PARAMETER_LOGGING, -- /**< MMAL_PARAMETER_UINT64_T */ -- MMAL_PARAMETER_SYSTEM_TIME, -- /**< MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_NO_IMAGE_PADDING, --}; -- --/* camera parameters */ -- --enum mmal_parameter_camera_type { -- /* 0 */ -- /** @ref MMAL_PARAMETER_THUMBNAIL_CONFIG_T */ -- MMAL_PARAMETER_THUMBNAIL_CONFIGURATION = -- MMAL_PARAMETER_GROUP_CAMERA, -- /**< Unused? */ -- MMAL_PARAMETER_CAPTURE_QUALITY, -- /**< @ref MMAL_PARAMETER_INT32_T */ -- MMAL_PARAMETER_ROTATION, -- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_EXIF_DISABLE, -- /**< @ref MMAL_PARAMETER_EXIF_T */ -- MMAL_PARAMETER_EXIF, -- /**< @ref MMAL_PARAM_AWBMODE_T */ -- MMAL_PARAMETER_AWB_MODE, -- /**< @ref MMAL_PARAMETER_IMAGEFX_T */ -- MMAL_PARAMETER_IMAGE_EFFECT, -- /**< @ref MMAL_PARAMETER_COLOURFX_T */ -- MMAL_PARAMETER_COLOUR_EFFECT, -- /**< @ref MMAL_PARAMETER_FLICKERAVOID_T */ -- MMAL_PARAMETER_FLICKER_AVOID, -- /**< @ref MMAL_PARAMETER_FLASH_T */ -- MMAL_PARAMETER_FLASH, -- /**< @ref MMAL_PARAMETER_REDEYE_T */ -- MMAL_PARAMETER_REDEYE, -- /**< @ref MMAL_PARAMETER_FOCUS_T */ -- MMAL_PARAMETER_FOCUS, -- /**< Unused? */ -- MMAL_PARAMETER_FOCAL_LENGTHS, -- /**< @ref MMAL_PARAMETER_INT32_T */ -- MMAL_PARAMETER_EXPOSURE_COMP, -- /**< @ref MMAL_PARAMETER_SCALEFACTOR_T */ -- MMAL_PARAMETER_ZOOM, -- /**< @ref MMAL_PARAMETER_MIRROR_T */ -- MMAL_PARAMETER_MIRROR, -- -- /* 0x10 */ -- /**< @ref MMAL_PARAMETER_UINT32_T */ -- MMAL_PARAMETER_CAMERA_NUM, -- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_CAPTURE, -- /**< @ref MMAL_PARAMETER_EXPOSUREMODE_T */ -- MMAL_PARAMETER_EXPOSURE_MODE, -- /**< @ref MMAL_PARAMETER_EXPOSUREMETERINGMODE_T */ -- MMAL_PARAMETER_EXP_METERING_MODE, -- /**< @ref MMAL_PARAMETER_FOCUS_STATUS_T */ -- MMAL_PARAMETER_FOCUS_STATUS, -- /**< @ref MMAL_PARAMETER_CAMERA_CONFIG_T */ -- MMAL_PARAMETER_CAMERA_CONFIG, -- /**< @ref MMAL_PARAMETER_CAPTURE_STATUS_T */ -- MMAL_PARAMETER_CAPTURE_STATUS, -- /**< @ref MMAL_PARAMETER_FACE_TRACK_T */ -- MMAL_PARAMETER_FACE_TRACK, -- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_DRAW_BOX_FACES_AND_FOCUS, -- /**< @ref MMAL_PARAMETER_UINT32_T */ -- MMAL_PARAMETER_JPEG_Q_FACTOR, -- /**< @ref MMAL_PARAMETER_FRAME_RATE_T */ -- MMAL_PARAMETER_FRAME_RATE, -- /**< @ref MMAL_PARAMETER_CAMERA_STC_MODE_T */ -- MMAL_PARAMETER_USE_STC, -- /**< @ref MMAL_PARAMETER_CAMERA_INFO_T */ -- MMAL_PARAMETER_CAMERA_INFO, -- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_VIDEO_STABILISATION, -- /**< @ref MMAL_PARAMETER_FACE_TRACK_RESULTS_T */ -- MMAL_PARAMETER_FACE_TRACK_RESULTS, -- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_ENABLE_RAW_CAPTURE, -- -- /* 0x20 */ -- /**< @ref MMAL_PARAMETER_URI_T */ -- MMAL_PARAMETER_DPF_FILE, -- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_ENABLE_DPF_FILE, -- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_DPF_FAIL_IS_FATAL, -- /**< @ref MMAL_PARAMETER_CAPTUREMODE_T */ -- MMAL_PARAMETER_CAPTURE_MODE, -- /**< @ref MMAL_PARAMETER_FOCUS_REGIONS_T */ -- MMAL_PARAMETER_FOCUS_REGIONS, -- /**< @ref MMAL_PARAMETER_INPUT_CROP_T */ -- MMAL_PARAMETER_INPUT_CROP, -- /**< @ref MMAL_PARAMETER_SENSOR_INFORMATION_T */ -- MMAL_PARAMETER_SENSOR_INFORMATION, -- /**< @ref MMAL_PARAMETER_FLASH_SELECT_T */ -- MMAL_PARAMETER_FLASH_SELECT, -- /**< @ref MMAL_PARAMETER_FIELD_OF_VIEW_T */ -- MMAL_PARAMETER_FIELD_OF_VIEW, -- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_HIGH_DYNAMIC_RANGE, -- /**< @ref MMAL_PARAMETER_DRC_T */ -- MMAL_PARAMETER_DYNAMIC_RANGE_COMPRESSION, -- /**< @ref MMAL_PARAMETER_ALGORITHM_CONTROL_T */ -- MMAL_PARAMETER_ALGORITHM_CONTROL, -- /**< @ref MMAL_PARAMETER_RATIONAL_T */ -- MMAL_PARAMETER_SHARPNESS, -- /**< @ref MMAL_PARAMETER_RATIONAL_T */ -- MMAL_PARAMETER_CONTRAST, -- /**< @ref MMAL_PARAMETER_RATIONAL_T */ -- MMAL_PARAMETER_BRIGHTNESS, -- /**< @ref MMAL_PARAMETER_RATIONAL_T */ -- MMAL_PARAMETER_SATURATION, -- -- /* 0x30 */ -- /**< @ref MMAL_PARAMETER_UINT32_T */ -- MMAL_PARAMETER_ISO, -- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_ANTISHAKE, -- /** @ref MMAL_PARAMETER_IMAGEFX_PARAMETERS_T */ -- MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, -- /** @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_CAMERA_BURST_CAPTURE, -- /** @ref MMAL_PARAMETER_UINT32_T */ -- MMAL_PARAMETER_CAMERA_MIN_ISO, -- /** @ref MMAL_PARAMETER_CAMERA_USE_CASE_T */ -- MMAL_PARAMETER_CAMERA_USE_CASE, -- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_CAPTURE_STATS_PASS, -- /** @ref MMAL_PARAMETER_UINT32_T */ -- MMAL_PARAMETER_CAMERA_CUSTOM_SENSOR_CONFIG, -- /** @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_ENABLE_REGISTER_FILE, -- /** @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_REGISTER_FAIL_IS_FATAL, -- /** @ref MMAL_PARAMETER_CONFIGFILE_T */ -- MMAL_PARAMETER_CONFIGFILE_REGISTERS, -- /** @ref MMAL_PARAMETER_CONFIGFILE_CHUNK_T */ -- MMAL_PARAMETER_CONFIGFILE_CHUNK_REGISTERS, -- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_JPEG_ATTACH_LOG, -- /**< @ref MMAL_PARAMETER_ZEROSHUTTERLAG_T */ -- MMAL_PARAMETER_ZERO_SHUTTER_LAG, -- /**< @ref MMAL_PARAMETER_FPS_RANGE_T */ -- MMAL_PARAMETER_FPS_RANGE, -- /**< @ref MMAL_PARAMETER_INT32_T */ -- MMAL_PARAMETER_CAPTURE_EXPOSURE_COMP, -- -- /* 0x40 */ -- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_SW_SHARPEN_DISABLE, -- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_FLASH_REQUIRED, -- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_SW_SATURATION_DISABLE, -- /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ -- MMAL_PARAMETER_SHUTTER_SPEED, -- /**< Takes a @ref MMAL_PARAMETER_AWB_GAINS_T */ -- MMAL_PARAMETER_CUSTOM_AWB_GAINS, --}; -- --struct mmal_parameter_rational { -- s32 num; /**< Numerator */ -- s32 den; /**< Denominator */ --}; -- --enum mmal_parameter_camera_config_timestamp_mode { -- MMAL_PARAM_TIMESTAMP_MODE_ZERO = 0, /* Always timestamp frames as 0 */ -- MMAL_PARAM_TIMESTAMP_MODE_RAW_STC, /* Use the raw STC value -- * for the frame timestamp -- */ -- MMAL_PARAM_TIMESTAMP_MODE_RESET_STC, /* Use the STC timestamp -- * but subtract the -- * timestamp of the first -- * frame sent to give a -- * zero based timestamp. -- */ --}; -- --struct mmal_parameter_fps_range { -- /**< Low end of the permitted framerate range */ -- struct mmal_parameter_rational fps_low; -- /**< High end of the permitted framerate range */ -- struct mmal_parameter_rational fps_high; --}; -- --/* camera configuration parameter */ --struct mmal_parameter_camera_config { -- /* Parameters for setting up the image pools */ -- u32 max_stills_w; /* Max size of stills capture */ -- u32 max_stills_h; -- u32 stills_yuv422; /* Allow YUV422 stills capture */ -- u32 one_shot_stills; /* Continuous or one shot stills captures. */ -- -- u32 max_preview_video_w; /* Max size of the preview or video -- * capture frames -- */ -- u32 max_preview_video_h; -- u32 num_preview_video_frames; -- -- /** Sets the height of the circular buffer for stills capture. */ -- u32 stills_capture_circular_buffer_height; -- -- /** Allows preview/encode to resume as fast as possible after the stills -- * input frame has been received, and then processes the still frame in -- * the background whilst preview/encode has resumed. -- * Actual mode is controlled by MMAL_PARAMETER_CAPTURE_MODE. -- */ -- u32 fast_preview_resume; -- -- /** Selects algorithm for timestamping frames if -- * there is no clock component connected. -- * enum mmal_parameter_camera_config_timestamp_mode -- */ -- s32 use_stc_timestamp; --}; -- --enum mmal_parameter_exposuremode { -- MMAL_PARAM_EXPOSUREMODE_OFF, -- MMAL_PARAM_EXPOSUREMODE_AUTO, -- MMAL_PARAM_EXPOSUREMODE_NIGHT, -- MMAL_PARAM_EXPOSUREMODE_NIGHTPREVIEW, -- MMAL_PARAM_EXPOSUREMODE_BACKLIGHT, -- MMAL_PARAM_EXPOSUREMODE_SPOTLIGHT, -- MMAL_PARAM_EXPOSUREMODE_SPORTS, -- MMAL_PARAM_EXPOSUREMODE_SNOW, -- MMAL_PARAM_EXPOSUREMODE_BEACH, -- MMAL_PARAM_EXPOSUREMODE_VERYLONG, -- MMAL_PARAM_EXPOSUREMODE_FIXEDFPS, -- MMAL_PARAM_EXPOSUREMODE_ANTISHAKE, -- MMAL_PARAM_EXPOSUREMODE_FIREWORKS, --}; -- --enum mmal_parameter_exposuremeteringmode { -- MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE, -- MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT, -- MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT, -- MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX, --}; -- --enum mmal_parameter_awbmode { -- MMAL_PARAM_AWBMODE_OFF, -- MMAL_PARAM_AWBMODE_AUTO, -- MMAL_PARAM_AWBMODE_SUNLIGHT, -- MMAL_PARAM_AWBMODE_CLOUDY, -- MMAL_PARAM_AWBMODE_SHADE, -- MMAL_PARAM_AWBMODE_TUNGSTEN, -- MMAL_PARAM_AWBMODE_FLUORESCENT, -- MMAL_PARAM_AWBMODE_INCANDESCENT, -- MMAL_PARAM_AWBMODE_FLASH, -- MMAL_PARAM_AWBMODE_HORIZON, --}; -- --enum mmal_parameter_imagefx { -- MMAL_PARAM_IMAGEFX_NONE, -- MMAL_PARAM_IMAGEFX_NEGATIVE, -- MMAL_PARAM_IMAGEFX_SOLARIZE, -- MMAL_PARAM_IMAGEFX_POSTERIZE, -- MMAL_PARAM_IMAGEFX_WHITEBOARD, -- MMAL_PARAM_IMAGEFX_BLACKBOARD, -- MMAL_PARAM_IMAGEFX_SKETCH, -- MMAL_PARAM_IMAGEFX_DENOISE, -- MMAL_PARAM_IMAGEFX_EMBOSS, -- MMAL_PARAM_IMAGEFX_OILPAINT, -- MMAL_PARAM_IMAGEFX_HATCH, -- MMAL_PARAM_IMAGEFX_GPEN, -- MMAL_PARAM_IMAGEFX_PASTEL, -- MMAL_PARAM_IMAGEFX_WATERCOLOUR, -- MMAL_PARAM_IMAGEFX_FILM, -- MMAL_PARAM_IMAGEFX_BLUR, -- MMAL_PARAM_IMAGEFX_SATURATION, -- MMAL_PARAM_IMAGEFX_COLOURSWAP, -- MMAL_PARAM_IMAGEFX_WASHEDOUT, -- MMAL_PARAM_IMAGEFX_POSTERISE, -- MMAL_PARAM_IMAGEFX_COLOURPOINT, -- MMAL_PARAM_IMAGEFX_COLOURBALANCE, -- MMAL_PARAM_IMAGEFX_CARTOON, --}; -- --enum MMAL_PARAM_FLICKERAVOID_T { -- MMAL_PARAM_FLICKERAVOID_OFF, -- MMAL_PARAM_FLICKERAVOID_AUTO, -- MMAL_PARAM_FLICKERAVOID_50HZ, -- MMAL_PARAM_FLICKERAVOID_60HZ, -- MMAL_PARAM_FLICKERAVOID_MAX = 0x7FFFFFFF --}; -- --struct mmal_parameter_awbgains { -- struct mmal_parameter_rational r_gain; /**< Red gain */ -- struct mmal_parameter_rational b_gain; /**< Blue gain */ --}; -- --/** Manner of video rate control */ --enum mmal_parameter_rate_control_mode { -- MMAL_VIDEO_RATECONTROL_DEFAULT, -- MMAL_VIDEO_RATECONTROL_VARIABLE, -- MMAL_VIDEO_RATECONTROL_CONSTANT, -- MMAL_VIDEO_RATECONTROL_VARIABLE_SKIP_FRAMES, -- MMAL_VIDEO_RATECONTROL_CONSTANT_SKIP_FRAMES --}; -- --enum mmal_video_profile { -- MMAL_VIDEO_PROFILE_H263_BASELINE, -- MMAL_VIDEO_PROFILE_H263_H320CODING, -- MMAL_VIDEO_PROFILE_H263_BACKWARDCOMPATIBLE, -- MMAL_VIDEO_PROFILE_H263_ISWV2, -- MMAL_VIDEO_PROFILE_H263_ISWV3, -- MMAL_VIDEO_PROFILE_H263_HIGHCOMPRESSION, -- MMAL_VIDEO_PROFILE_H263_INTERNET, -- MMAL_VIDEO_PROFILE_H263_INTERLACE, -- MMAL_VIDEO_PROFILE_H263_HIGHLATENCY, -- MMAL_VIDEO_PROFILE_MP4V_SIMPLE, -- MMAL_VIDEO_PROFILE_MP4V_SIMPLESCALABLE, -- MMAL_VIDEO_PROFILE_MP4V_CORE, -- MMAL_VIDEO_PROFILE_MP4V_MAIN, -- MMAL_VIDEO_PROFILE_MP4V_NBIT, -- MMAL_VIDEO_PROFILE_MP4V_SCALABLETEXTURE, -- MMAL_VIDEO_PROFILE_MP4V_SIMPLEFACE, -- MMAL_VIDEO_PROFILE_MP4V_SIMPLEFBA, -- MMAL_VIDEO_PROFILE_MP4V_BASICANIMATED, -- MMAL_VIDEO_PROFILE_MP4V_HYBRID, -- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDREALTIME, -- MMAL_VIDEO_PROFILE_MP4V_CORESCALABLE, -- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCODING, -- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCORE, -- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSCALABLE, -- MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSIMPLE, -- MMAL_VIDEO_PROFILE_H264_BASELINE, -- MMAL_VIDEO_PROFILE_H264_MAIN, -- MMAL_VIDEO_PROFILE_H264_EXTENDED, -- MMAL_VIDEO_PROFILE_H264_HIGH, -- MMAL_VIDEO_PROFILE_H264_HIGH10, -- MMAL_VIDEO_PROFILE_H264_HIGH422, -- MMAL_VIDEO_PROFILE_H264_HIGH444, -- MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE, -- MMAL_VIDEO_PROFILE_DUMMY = 0x7FFFFFFF --}; -- --enum mmal_video_level { -- MMAL_VIDEO_LEVEL_H263_10, -- MMAL_VIDEO_LEVEL_H263_20, -- MMAL_VIDEO_LEVEL_H263_30, -- MMAL_VIDEO_LEVEL_H263_40, -- MMAL_VIDEO_LEVEL_H263_45, -- MMAL_VIDEO_LEVEL_H263_50, -- MMAL_VIDEO_LEVEL_H263_60, -- MMAL_VIDEO_LEVEL_H263_70, -- MMAL_VIDEO_LEVEL_MP4V_0, -- MMAL_VIDEO_LEVEL_MP4V_0b, -- MMAL_VIDEO_LEVEL_MP4V_1, -- MMAL_VIDEO_LEVEL_MP4V_2, -- MMAL_VIDEO_LEVEL_MP4V_3, -- MMAL_VIDEO_LEVEL_MP4V_4, -- MMAL_VIDEO_LEVEL_MP4V_4a, -- MMAL_VIDEO_LEVEL_MP4V_5, -- MMAL_VIDEO_LEVEL_MP4V_6, -- MMAL_VIDEO_LEVEL_H264_1, -- MMAL_VIDEO_LEVEL_H264_1b, -- MMAL_VIDEO_LEVEL_H264_11, -- MMAL_VIDEO_LEVEL_H264_12, -- MMAL_VIDEO_LEVEL_H264_13, -- MMAL_VIDEO_LEVEL_H264_2, -- MMAL_VIDEO_LEVEL_H264_21, -- MMAL_VIDEO_LEVEL_H264_22, -- MMAL_VIDEO_LEVEL_H264_3, -- MMAL_VIDEO_LEVEL_H264_31, -- MMAL_VIDEO_LEVEL_H264_32, -- MMAL_VIDEO_LEVEL_H264_4, -- MMAL_VIDEO_LEVEL_H264_41, -- MMAL_VIDEO_LEVEL_H264_42, -- MMAL_VIDEO_LEVEL_H264_5, -- MMAL_VIDEO_LEVEL_H264_51, -- MMAL_VIDEO_LEVEL_DUMMY = 0x7FFFFFFF --}; -- --struct mmal_parameter_video_profile { -- enum mmal_video_profile profile; -- enum mmal_video_level level; --}; -- --/* video parameters */ -- --enum mmal_parameter_video_type { -- /** @ref MMAL_DISPLAYREGION_T */ -- MMAL_PARAMETER_DISPLAYREGION = MMAL_PARAMETER_GROUP_VIDEO, -- -- /** @ref MMAL_PARAMETER_VIDEO_PROFILE_T */ -- MMAL_PARAMETER_SUPPORTED_PROFILES, -- -- /** @ref MMAL_PARAMETER_VIDEO_PROFILE_T */ -- MMAL_PARAMETER_PROFILE, -- -- /** @ref MMAL_PARAMETER_UINT32_T */ -- MMAL_PARAMETER_INTRAPERIOD, -- -- /** @ref MMAL_PARAMETER_VIDEO_RATECONTROL_T */ -- MMAL_PARAMETER_RATECONTROL, -- -- /** @ref MMAL_PARAMETER_VIDEO_NALUNITFORMAT_T */ -- MMAL_PARAMETER_NALUNITFORMAT, -- -- /** @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_MINIMISE_FRAGMENTATION, -- -- /** @ref MMAL_PARAMETER_UINT32_T. -- * Setting the value to zero resets to the default (one slice per -- * frame). -- */ -- MMAL_PARAMETER_MB_ROWS_PER_SLICE, -- -- /** @ref MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION_T */ -- MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION, -- -- /** @ref MMAL_PARAMETER_VIDEO_EEDE_ENABLE_T */ -- MMAL_PARAMETER_VIDEO_EEDE_ENABLE, -- -- /** @ref MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE_T */ -- MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE, -- -- /** @ref MMAL_PARAMETER_BOOLEAN_T. Request an I-frame. */ -- MMAL_PARAMETER_VIDEO_REQUEST_I_FRAME, -- /** @ref MMAL_PARAMETER_VIDEO_INTRA_REFRESH_T */ -- MMAL_PARAMETER_VIDEO_INTRA_REFRESH, -- -- /** @ref MMAL_PARAMETER_BOOLEAN_T. */ -- MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, -- -- /** @ref MMAL_PARAMETER_UINT32_T. Run-time bit rate control */ -- MMAL_PARAMETER_VIDEO_BIT_RATE, -- -- /** @ref MMAL_PARAMETER_FRAME_RATE_T */ -- MMAL_PARAMETER_VIDEO_FRAME_RATE, -- -- /** @ref MMAL_PARAMETER_UINT32_T. */ -- MMAL_PARAMETER_VIDEO_ENCODE_MIN_QUANT, -- -- /** @ref MMAL_PARAMETER_UINT32_T. */ -- MMAL_PARAMETER_VIDEO_ENCODE_MAX_QUANT, -- -- /** @ref MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL_T. */ -- MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL, -- -- MMAL_PARAMETER_EXTRA_BUFFERS, /**< @ref MMAL_PARAMETER_UINT32_T. */ -- /** @ref MMAL_PARAMETER_UINT32_T. -- * Changing this parameter from the default can reduce frame rate -- * because image buffers need to be re-pitched. -- */ -- MMAL_PARAMETER_VIDEO_ALIGN_HORIZ, -- -- /** @ref MMAL_PARAMETER_UINT32_T. -- * Changing this parameter from the default can reduce frame rate -- * because image buffers need to be re-pitched. -- */ -- MMAL_PARAMETER_VIDEO_ALIGN_VERT, -- -- /** @ref MMAL_PARAMETER_BOOLEAN_T. */ -- MMAL_PARAMETER_VIDEO_DROPPABLE_PFRAMES, -- -- /** @ref MMAL_PARAMETER_UINT32_T. */ -- MMAL_PARAMETER_VIDEO_ENCODE_INITIAL_QUANT, -- -- /**< @ref MMAL_PARAMETER_UINT32_T. */ -- MMAL_PARAMETER_VIDEO_ENCODE_QP_P, -- -- /**< @ref MMAL_PARAMETER_UINT32_T. */ -- MMAL_PARAMETER_VIDEO_ENCODE_RC_SLICE_DQUANT, -- -- /** @ref MMAL_PARAMETER_UINT32_T */ -- MMAL_PARAMETER_VIDEO_ENCODE_FRAME_LIMIT_BITS, -- -- /** @ref MMAL_PARAMETER_UINT32_T. */ -- MMAL_PARAMETER_VIDEO_ENCODE_PEAK_RATE, -- -- /* H264 specific parameters */ -- -- /** @ref MMAL_PARAMETER_BOOLEAN_T. */ -- MMAL_PARAMETER_VIDEO_ENCODE_H264_DISABLE_CABAC, -- -- /** @ref MMAL_PARAMETER_BOOLEAN_T. */ -- MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_LATENCY, -- -- /** @ref MMAL_PARAMETER_BOOLEAN_T. */ -- MMAL_PARAMETER_VIDEO_ENCODE_H264_AU_DELIMITERS, -- -- /** @ref MMAL_PARAMETER_UINT32_T. */ -- MMAL_PARAMETER_VIDEO_ENCODE_H264_DEBLOCK_IDC, -- -- /** @ref MMAL_PARAMETER_VIDEO_ENCODER_H264_MB_INTRA_MODES_T. */ -- MMAL_PARAMETER_VIDEO_ENCODE_H264_MB_INTRA_MODE, -- -- /** @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_VIDEO_ENCODE_HEADER_ON_OPEN, -- -- /** @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_VIDEO_ENCODE_PRECODE_FOR_QP, -- -- /** @ref MMAL_PARAMETER_VIDEO_DRM_INIT_INFO_T. */ -- MMAL_PARAMETER_VIDEO_DRM_INIT_INFO, -- -- /** @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_VIDEO_TIMESTAMP_FIFO, -- -- /** @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_VIDEO_DECODE_ERROR_CONCEALMENT, -- -- /** @ref MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER_T. */ -- MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER, -- -- /** @ref MMAL_PARAMETER_BYTES_T */ -- MMAL_PARAMETER_VIDEO_DECODE_CONFIG_VD3, -- -- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_VIDEO_ENCODE_H264_VCL_HRD_PARAMETERS, -- -- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_DELAY_HRD_FLAG, -- -- /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER --}; -- --/** Valid mirror modes */ --enum mmal_parameter_mirror { -- MMAL_PARAM_MIRROR_NONE, -- MMAL_PARAM_MIRROR_VERTICAL, -- MMAL_PARAM_MIRROR_HORIZONTAL, -- MMAL_PARAM_MIRROR_BOTH, --}; -- --enum mmal_parameter_displaytransform { -- MMAL_DISPLAY_ROT0 = 0, -- MMAL_DISPLAY_MIRROR_ROT0 = 1, -- MMAL_DISPLAY_MIRROR_ROT180 = 2, -- MMAL_DISPLAY_ROT180 = 3, -- MMAL_DISPLAY_MIRROR_ROT90 = 4, -- MMAL_DISPLAY_ROT270 = 5, -- MMAL_DISPLAY_ROT90 = 6, -- MMAL_DISPLAY_MIRROR_ROT270 = 7, --}; -- --enum mmal_parameter_displaymode { -- MMAL_DISPLAY_MODE_FILL = 0, -- MMAL_DISPLAY_MODE_LETTERBOX = 1, --}; -- --enum mmal_parameter_displayset { -- MMAL_DISPLAY_SET_NONE = 0, -- MMAL_DISPLAY_SET_NUM = 1, -- MMAL_DISPLAY_SET_FULLSCREEN = 2, -- MMAL_DISPLAY_SET_TRANSFORM = 4, -- MMAL_DISPLAY_SET_DEST_RECT = 8, -- MMAL_DISPLAY_SET_SRC_RECT = 0x10, -- MMAL_DISPLAY_SET_MODE = 0x20, -- MMAL_DISPLAY_SET_PIXEL = 0x40, -- MMAL_DISPLAY_SET_NOASPECT = 0x80, -- MMAL_DISPLAY_SET_LAYER = 0x100, -- MMAL_DISPLAY_SET_COPYPROTECT = 0x200, -- MMAL_DISPLAY_SET_ALPHA = 0x400, --}; -- --/* rectangle, used lots so it gets its own struct */ --struct vchiq_mmal_rect { -- s32 x; -- s32 y; -- s32 width; -- s32 height; --}; -- --struct mmal_parameter_displayregion { -- /** Bitfield that indicates which fields are set and should be -- * used. All other fields will maintain their current value. -- * \ref MMAL_DISPLAYSET_T defines the bits that can be -- * combined. -- */ -- u32 set; -- -- /** Describes the display output device, with 0 typically -- * being a directly connected LCD display. The actual values -- * will depend on the hardware. Code using hard-wired numbers -- * (e.g. 2) is certain to fail. -- */ -- -- u32 display_num; -- /** Indicates that we are using the full device screen area, -- * rather than a window of the display. If zero, then -- * dest_rect is used to specify a region of the display to -- * use. -- */ -- -- s32 fullscreen; -- /** Indicates any rotation or flipping used to map frames onto -- * the natural display orientation. -- */ -- u32 transform; /* enum mmal_parameter_displaytransform */ -- -- /** Where to display the frame within the screen, if -- * fullscreen is zero. -- */ -- struct vchiq_mmal_rect dest_rect; -- -- /** Indicates which area of the frame to display. If all -- * values are zero, the whole frame will be used. -- */ -- struct vchiq_mmal_rect src_rect; -- -- /** If set to non-zero, indicates that any display scaling -- * should disregard the aspect ratio of the frame region being -- * displayed. -- */ -- s32 noaspect; -- -- /** Indicates how the image should be scaled to fit the -- * display. \code MMAL_DISPLAY_MODE_FILL \endcode indicates -- * that the image should fill the screen by potentially -- * cropping the frames. Setting \code mode \endcode to \code -- * MMAL_DISPLAY_MODE_LETTERBOX \endcode indicates that all the -- * source region should be displayed and black bars added if -- * necessary. -- */ -- u32 mode; /* enum mmal_parameter_displaymode */ -- -- /** If non-zero, defines the width of a source pixel relative -- * to \code pixel_y \endcode. If zero, then pixels default to -- * being square. -- */ -- u32 pixel_x; -- -- /** If non-zero, defines the height of a source pixel relative -- * to \code pixel_x \endcode. If zero, then pixels default to -- * being square. -- */ -- u32 pixel_y; -- -- /** Sets the relative depth of the images, with greater values -- * being in front of smaller values. -- */ -- u32 layer; -- -- /** Set to non-zero to ensure copy protection is used on -- * output. -- */ -- s32 copyprotect_required; -- -- /** Level of opacity of the layer, where zero is fully -- * transparent and 255 is fully opaque. -- */ -- u32 alpha; --}; -- --#define MMAL_MAX_IMAGEFX_PARAMETERS 5 -- --struct mmal_parameter_imagefx_parameters { -- enum mmal_parameter_imagefx effect; -- u32 num_effect_params; -- u32 effect_parameter[MMAL_MAX_IMAGEFX_PARAMETERS]; --}; -- --#define MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS 4 --#define MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES 2 --#define MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN 16 -- --struct mmal_parameter_camera_info_camera_t { -- u32 port_id; -- u32 max_width; -- u32 max_height; -- u32 lens_present; -- u8 camera_name[MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN]; --}; -- --enum mmal_parameter_camera_info_flash_type_t { -- /* Make values explicit to ensure they match values in config ini */ -- MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_XENON = 0, -- MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_LED = 1, -- MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_OTHER = 2, -- MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_MAX = 0x7FFFFFFF --}; -- --struct mmal_parameter_camera_info_flash_t { -- enum mmal_parameter_camera_info_flash_type_t flash_type; --}; -- --struct mmal_parameter_camera_info_t { -- u32 num_cameras; -- u32 num_flashes; -- struct mmal_parameter_camera_info_camera_t -- cameras[MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS]; -- struct mmal_parameter_camera_info_flash_t -- flashes[MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES]; --}; -- --#endif ---- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h -+++ /dev/null -@@ -1,166 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * Broadcom BM2835 V4L2 driver -- * -- * Copyright © 2013 Raspberry Pi (Trading) Ltd. -- * -- * Authors: Vincent Sanders @ Collabora -- * Dave Stevenson @ Broadcom -- * (now dave.stevenson@raspberrypi.org) -- * Simon Mellor @ Broadcom -- * Luke Diamand @ Broadcom -- * -- * MMAL interface to VCHIQ message passing -- */ -- --#ifndef MMAL_VCHIQ_H --#define MMAL_VCHIQ_H -- --#include "mmal-msg-format.h" -- --#define MAX_PORT_COUNT 4 -- --/* Maximum size of the format extradata. */ --#define MMAL_FORMAT_EXTRADATA_MAX_SIZE 128 -- --struct vchiq_mmal_instance; -- --enum vchiq_mmal_es_type { -- MMAL_ES_TYPE_UNKNOWN, /**< Unknown elementary stream type */ -- MMAL_ES_TYPE_CONTROL, /**< Elementary stream of control commands */ -- MMAL_ES_TYPE_AUDIO, /**< Audio elementary stream */ -- MMAL_ES_TYPE_VIDEO, /**< Video elementary stream */ -- MMAL_ES_TYPE_SUBPICTURE /**< Sub-picture elementary stream */ --}; -- --struct vchiq_mmal_port_buffer { -- unsigned int num; /* number of buffers */ -- u32 size; /* size of buffers */ -- u32 alignment; /* alignment of buffers */ --}; -- --struct vchiq_mmal_port; -- --typedef void (*vchiq_mmal_buffer_cb)( -- struct vchiq_mmal_instance *instance, -- struct vchiq_mmal_port *port, -- int status, struct mmal_buffer *buffer, -- unsigned long length, u32 mmal_flags, s64 dts, s64 pts); -- --struct vchiq_mmal_port { -- bool enabled; -- u32 handle; -- u32 type; /* port type, cached to use on port info set */ -- u32 index; /* port index, cached to use on port info set */ -- -- /* component port belongs to, allows simple deref */ -- struct vchiq_mmal_component *component; -- -- struct vchiq_mmal_port *connected; /* port conencted to */ -- -- /* buffer info */ -- struct vchiq_mmal_port_buffer minimum_buffer; -- struct vchiq_mmal_port_buffer recommended_buffer; -- struct vchiq_mmal_port_buffer current_buffer; -- -- /* stream format */ -- struct mmal_es_format_local format; -- /* elementary stream format */ -- union mmal_es_specific_format es; -- -- /* data buffers to fill */ -- struct list_head buffers; -- /* lock to serialise adding and removing buffers from list */ -- spinlock_t slock; -- -- /* Count of buffers the VPU has yet to return */ -- atomic_t buffers_with_vpu; -- /* callback on buffer completion */ -- vchiq_mmal_buffer_cb buffer_cb; -- /* callback context */ -- void *cb_ctx; --}; -- --struct vchiq_mmal_component { -- bool enabled; -- u32 handle; /* VideoCore handle for component */ -- u32 inputs; /* Number of input ports */ -- u32 outputs; /* Number of output ports */ -- u32 clocks; /* Number of clock ports */ -- struct vchiq_mmal_port control; /* control port */ -- struct vchiq_mmal_port input[MAX_PORT_COUNT]; /* input ports */ -- struct vchiq_mmal_port output[MAX_PORT_COUNT]; /* output ports */ -- struct vchiq_mmal_port clock[MAX_PORT_COUNT]; /* clock ports */ --}; -- --int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance); --int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance); -- --/* Initialise a mmal component and its ports -- * -- */ --int vchiq_mmal_component_init( -- struct vchiq_mmal_instance *instance, -- const char *name, -- struct vchiq_mmal_component **component_out); -- --int vchiq_mmal_component_finalise( -- struct vchiq_mmal_instance *instance, -- struct vchiq_mmal_component *component); -- --int vchiq_mmal_component_enable( -- struct vchiq_mmal_instance *instance, -- struct vchiq_mmal_component *component); -- --int vchiq_mmal_component_disable( -- struct vchiq_mmal_instance *instance, -- struct vchiq_mmal_component *component); -- --/* enable a mmal port -- * -- * enables a port and if a buffer callback provided enque buffer -- * headers as appropriate for the port. -- */ --int vchiq_mmal_port_enable( -- struct vchiq_mmal_instance *instance, -- struct vchiq_mmal_port *port, -- vchiq_mmal_buffer_cb buffer_cb); -- --/* disable a port -- * -- * disable a port will dequeue any pending buffers -- */ --int vchiq_mmal_port_disable(struct vchiq_mmal_instance *instance, -- struct vchiq_mmal_port *port); -- --int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance, -- struct vchiq_mmal_port *port, -- u32 parameter, -- void *value, -- u32 value_size); -- --int vchiq_mmal_port_parameter_get(struct vchiq_mmal_instance *instance, -- struct vchiq_mmal_port *port, -- u32 parameter, -- void *value, -- u32 *value_size); -- --int vchiq_mmal_port_set_format(struct vchiq_mmal_instance *instance, -- struct vchiq_mmal_port *port); -- --int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance, -- struct vchiq_mmal_port *src, -- struct vchiq_mmal_port *dst); -- --int vchiq_mmal_version(struct vchiq_mmal_instance *instance, -- u32 *major_out, -- u32 *minor_out); -- --int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance, -- struct vchiq_mmal_port *port, -- struct mmal_buffer *buf); -- --int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance, -- struct mmal_buffer *buf); --int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf); --#endif /* MMAL_VCHIQ_H */ ---- /dev/null -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h -@@ -0,0 +1,61 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Broadcom BM2835 V4L2 driver -+ * -+ * Copyright © 2013 Raspberry Pi (Trading) Ltd. -+ * -+ * Authors: Vincent Sanders @ Collabora -+ * Dave Stevenson @ Broadcom -+ * (now dave.stevenson@raspberrypi.org) -+ * Simon Mellor @ Broadcom -+ * Luke Diamand @ Broadcom -+ * -+ * MMAL structures -+ * -+ */ -+#ifndef MMAL_COMMON_H -+#define MMAL_COMMON_H -+ -+#define MMAL_FOURCC(a, b, c, d) ((a) | (b << 8) | (c << 16) | (d << 24)) -+#define MMAL_MAGIC MMAL_FOURCC('m', 'm', 'a', 'l') -+ -+/** Special value signalling that time is not known */ -+#define MMAL_TIME_UNKNOWN BIT_ULL(63) -+ -+struct mmal_msg_context; -+ -+/* mapping between v4l and mmal video modes */ -+struct mmal_fmt { -+ char *name; -+ u32 fourcc; /* v4l2 format id */ -+ int flags; /* v4l2 flags field */ -+ u32 mmal; -+ int depth; -+ u32 mmal_component; /* MMAL component index to be used to encode */ -+ u32 ybbp; /* depth of first Y plane for planar formats */ -+ bool remove_padding; /* Does the GPU have to remove padding, -+ * or can we do hide padding via bytesperline. -+ */ -+}; -+ -+/* buffer for one video frame */ -+struct mmal_buffer { -+ /* v4l buffer data -- must be first */ -+ struct vb2_v4l2_buffer vb; -+ -+ /* list of buffers available */ -+ struct list_head list; -+ -+ void *buffer; /* buffer pointer */ -+ unsigned long buffer_size; /* size of allocated buffer */ -+ -+ struct mmal_msg_context *msg_context; -+}; -+ -+/* */ -+struct mmal_colourfx { -+ s32 enable; -+ u32 u; -+ u32 v; -+}; -+#endif ---- /dev/null -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h -@@ -0,0 +1,124 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Broadcom BM2835 V4L2 driver -+ * -+ * Copyright © 2013 Raspberry Pi (Trading) Ltd. -+ * -+ * Authors: Vincent Sanders @ Collabora -+ * Dave Stevenson @ Broadcom -+ * (now dave.stevenson@raspberrypi.org) -+ * Simon Mellor @ Broadcom -+ * Luke Diamand @ Broadcom -+ */ -+#ifndef MMAL_ENCODINGS_H -+#define MMAL_ENCODINGS_H -+ -+#define MMAL_ENCODING_H264 MMAL_FOURCC('H', '2', '6', '4') -+#define MMAL_ENCODING_H263 MMAL_FOURCC('H', '2', '6', '3') -+#define MMAL_ENCODING_MP4V MMAL_FOURCC('M', 'P', '4', 'V') -+#define MMAL_ENCODING_MP2V MMAL_FOURCC('M', 'P', '2', 'V') -+#define MMAL_ENCODING_MP1V MMAL_FOURCC('M', 'P', '1', 'V') -+#define MMAL_ENCODING_WMV3 MMAL_FOURCC('W', 'M', 'V', '3') -+#define MMAL_ENCODING_WMV2 MMAL_FOURCC('W', 'M', 'V', '2') -+#define MMAL_ENCODING_WMV1 MMAL_FOURCC('W', 'M', 'V', '1') -+#define MMAL_ENCODING_WVC1 MMAL_FOURCC('W', 'V', 'C', '1') -+#define MMAL_ENCODING_VP8 MMAL_FOURCC('V', 'P', '8', ' ') -+#define MMAL_ENCODING_VP7 MMAL_FOURCC('V', 'P', '7', ' ') -+#define MMAL_ENCODING_VP6 MMAL_FOURCC('V', 'P', '6', ' ') -+#define MMAL_ENCODING_THEORA MMAL_FOURCC('T', 'H', 'E', 'O') -+#define MMAL_ENCODING_SPARK MMAL_FOURCC('S', 'P', 'R', 'K') -+#define MMAL_ENCODING_MJPEG MMAL_FOURCC('M', 'J', 'P', 'G') -+ -+#define MMAL_ENCODING_JPEG MMAL_FOURCC('J', 'P', 'E', 'G') -+#define MMAL_ENCODING_GIF MMAL_FOURCC('G', 'I', 'F', ' ') -+#define MMAL_ENCODING_PNG MMAL_FOURCC('P', 'N', 'G', ' ') -+#define MMAL_ENCODING_PPM MMAL_FOURCC('P', 'P', 'M', ' ') -+#define MMAL_ENCODING_TGA MMAL_FOURCC('T', 'G', 'A', ' ') -+#define MMAL_ENCODING_BMP MMAL_FOURCC('B', 'M', 'P', ' ') -+ -+#define MMAL_ENCODING_I420 MMAL_FOURCC('I', '4', '2', '0') -+#define MMAL_ENCODING_I420_SLICE MMAL_FOURCC('S', '4', '2', '0') -+#define MMAL_ENCODING_YV12 MMAL_FOURCC('Y', 'V', '1', '2') -+#define MMAL_ENCODING_I422 MMAL_FOURCC('I', '4', '2', '2') -+#define MMAL_ENCODING_I422_SLICE MMAL_FOURCC('S', '4', '2', '2') -+#define MMAL_ENCODING_YUYV MMAL_FOURCC('Y', 'U', 'Y', 'V') -+#define MMAL_ENCODING_YVYU MMAL_FOURCC('Y', 'V', 'Y', 'U') -+#define MMAL_ENCODING_UYVY MMAL_FOURCC('U', 'Y', 'V', 'Y') -+#define MMAL_ENCODING_VYUY MMAL_FOURCC('V', 'Y', 'U', 'Y') -+#define MMAL_ENCODING_NV12 MMAL_FOURCC('N', 'V', '1', '2') -+#define MMAL_ENCODING_NV21 MMAL_FOURCC('N', 'V', '2', '1') -+#define MMAL_ENCODING_ARGB MMAL_FOURCC('A', 'R', 'G', 'B') -+#define MMAL_ENCODING_RGBA MMAL_FOURCC('R', 'G', 'B', 'A') -+#define MMAL_ENCODING_ABGR MMAL_FOURCC('A', 'B', 'G', 'R') -+#define MMAL_ENCODING_BGRA MMAL_FOURCC('B', 'G', 'R', 'A') -+#define MMAL_ENCODING_RGB16 MMAL_FOURCC('R', 'G', 'B', '2') -+#define MMAL_ENCODING_RGB24 MMAL_FOURCC('R', 'G', 'B', '3') -+#define MMAL_ENCODING_RGB32 MMAL_FOURCC('R', 'G', 'B', '4') -+#define MMAL_ENCODING_BGR16 MMAL_FOURCC('B', 'G', 'R', '2') -+#define MMAL_ENCODING_BGR24 MMAL_FOURCC('B', 'G', 'R', '3') -+#define MMAL_ENCODING_BGR32 MMAL_FOURCC('B', 'G', 'R', '4') -+ -+/** SAND Video (YUVUV128) format, native format understood by VideoCore. -+ * This format is *not* opaque - if requested you will receive full frames -+ * of YUV_UV video. -+ */ -+#define MMAL_ENCODING_YUVUV128 MMAL_FOURCC('S', 'A', 'N', 'D') -+ -+/** VideoCore opaque image format, image handles are returned to -+ * the host but not the actual image data. -+ */ -+#define MMAL_ENCODING_OPAQUE MMAL_FOURCC('O', 'P', 'Q', 'V') -+ -+/** An EGL image handle -+ */ -+#define MMAL_ENCODING_EGL_IMAGE MMAL_FOURCC('E', 'G', 'L', 'I') -+ -+/* }@ */ -+ -+/** \name Pre-defined audio encodings */ -+/* @{ */ -+#define MMAL_ENCODING_PCM_UNSIGNED_BE MMAL_FOURCC('P', 'C', 'M', 'U') -+#define MMAL_ENCODING_PCM_UNSIGNED_LE MMAL_FOURCC('p', 'c', 'm', 'u') -+#define MMAL_ENCODING_PCM_SIGNED_BE MMAL_FOURCC('P', 'C', 'M', 'S') -+#define MMAL_ENCODING_PCM_SIGNED_LE MMAL_FOURCC('p', 'c', 'm', 's') -+#define MMAL_ENCODING_PCM_FLOAT_BE MMAL_FOURCC('P', 'C', 'M', 'F') -+#define MMAL_ENCODING_PCM_FLOAT_LE MMAL_FOURCC('p', 'c', 'm', 'f') -+ -+/* Pre-defined H264 encoding variants */ -+ -+/** ISO 14496-10 Annex B byte stream format */ -+#define MMAL_ENCODING_VARIANT_H264_DEFAULT 0 -+/** ISO 14496-15 AVC stream format */ -+#define MMAL_ENCODING_VARIANT_H264_AVC1 MMAL_FOURCC('A', 'V', 'C', '1') -+/** Implicitly delineated NAL units without emulation prevention */ -+#define MMAL_ENCODING_VARIANT_H264_RAW MMAL_FOURCC('R', 'A', 'W', ' ') -+ -+/** \defgroup MmalColorSpace List of pre-defined video color spaces -+ * This defines a list of common color spaces. This list isn't exhaustive and -+ * is only provided as a convenience to avoid clients having to use FourCC -+ * codes directly. However components are allowed to define and use their own -+ * FourCC codes. -+ */ -+/* @{ */ -+ -+/** Unknown color space */ -+#define MMAL_COLOR_SPACE_UNKNOWN 0 -+/** ITU-R BT.601-5 [SDTV] */ -+#define MMAL_COLOR_SPACE_ITUR_BT601 MMAL_FOURCC('Y', '6', '0', '1') -+/** ITU-R BT.709-3 [HDTV] */ -+#define MMAL_COLOR_SPACE_ITUR_BT709 MMAL_FOURCC('Y', '7', '0', '9') -+/** JPEG JFIF */ -+#define MMAL_COLOR_SPACE_JPEG_JFIF MMAL_FOURCC('Y', 'J', 'F', 'I') -+/** Title 47 Code of Federal Regulations (2003) 73.682 (a) (20) */ -+#define MMAL_COLOR_SPACE_FCC MMAL_FOURCC('Y', 'F', 'C', 'C') -+/** Society of Motion Picture and Television Engineers 240M (1999) */ -+#define MMAL_COLOR_SPACE_SMPTE240M MMAL_FOURCC('Y', '2', '4', '0') -+/** ITU-R BT.470-2 System M */ -+#define MMAL_COLOR_SPACE_BT470_2_M MMAL_FOURCC('Y', '_', '_', 'M') -+/** ITU-R BT.470-2 System BG */ -+#define MMAL_COLOR_SPACE_BT470_2_BG MMAL_FOURCC('Y', '_', 'B', 'G') -+/** JPEG JFIF, but with 16..255 luma */ -+#define MMAL_COLOR_SPACE_JFIF_Y16_255 MMAL_FOURCC('Y', 'Y', '1', '6') -+/* @} MmalColorSpace List */ -+ -+#endif /* MMAL_ENCODINGS_H */ ---- /dev/null -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-common.h -@@ -0,0 +1,48 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Broadcom BM2835 V4L2 driver -+ * -+ * Copyright © 2013 Raspberry Pi (Trading) Ltd. -+ * -+ * Authors: Vincent Sanders @ Collabora -+ * Dave Stevenson @ Broadcom -+ * (now dave.stevenson@raspberrypi.org) -+ * Simon Mellor @ Broadcom -+ * Luke Diamand @ Broadcom -+ */ -+ -+#ifndef MMAL_MSG_COMMON_H -+#define MMAL_MSG_COMMON_H -+ -+enum mmal_msg_status { -+ MMAL_MSG_STATUS_SUCCESS = 0, /**< Success */ -+ MMAL_MSG_STATUS_ENOMEM, /**< Out of memory */ -+ MMAL_MSG_STATUS_ENOSPC, /**< Out of resources other than memory */ -+ MMAL_MSG_STATUS_EINVAL, /**< Argument is invalid */ -+ MMAL_MSG_STATUS_ENOSYS, /**< Function not implemented */ -+ MMAL_MSG_STATUS_ENOENT, /**< No such file or directory */ -+ MMAL_MSG_STATUS_ENXIO, /**< No such device or address */ -+ MMAL_MSG_STATUS_EIO, /**< I/O error */ -+ MMAL_MSG_STATUS_ESPIPE, /**< Illegal seek */ -+ MMAL_MSG_STATUS_ECORRUPT, /**< Data is corrupt \attention */ -+ MMAL_MSG_STATUS_ENOTREADY, /**< Component is not ready */ -+ MMAL_MSG_STATUS_ECONFIG, /**< Component is not configured */ -+ MMAL_MSG_STATUS_EISCONN, /**< Port is already connected */ -+ MMAL_MSG_STATUS_ENOTCONN, /**< Port is disconnected */ -+ MMAL_MSG_STATUS_EAGAIN, /**< Resource temporarily unavailable. */ -+ MMAL_MSG_STATUS_EFAULT, /**< Bad address */ -+}; -+ -+struct mmal_rect { -+ s32 x; /**< x coordinate (from left) */ -+ s32 y; /**< y coordinate (from top) */ -+ s32 width; /**< width */ -+ s32 height; /**< height */ -+}; -+ -+struct mmal_rational { -+ s32 num; /**< Numerator */ -+ s32 den; /**< Denominator */ -+}; -+ -+#endif /* MMAL_MSG_COMMON_H */ ---- /dev/null -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-format.h -@@ -0,0 +1,106 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Broadcom BM2835 V4L2 driver -+ * -+ * Copyright © 2013 Raspberry Pi (Trading) Ltd. -+ * -+ * Authors: Vincent Sanders @ Collabora -+ * Dave Stevenson @ Broadcom -+ * (now dave.stevenson@raspberrypi.org) -+ * Simon Mellor @ Broadcom -+ * Luke Diamand @ Broadcom -+ */ -+ -+#ifndef MMAL_MSG_FORMAT_H -+#define MMAL_MSG_FORMAT_H -+ -+#include "mmal-msg-common.h" -+ -+/* MMAL_ES_FORMAT_T */ -+ -+struct mmal_audio_format { -+ u32 channels; /* Number of audio channels */ -+ u32 sample_rate; /* Sample rate */ -+ -+ u32 bits_per_sample; /* Bits per sample */ -+ u32 block_align; /* Size of a block of data */ -+}; -+ -+struct mmal_video_format { -+ u32 width; /* Width of frame in pixels */ -+ u32 height; /* Height of frame in rows of pixels */ -+ struct mmal_rect crop; /* Visible region of the frame */ -+ struct mmal_rational frame_rate; /* Frame rate */ -+ struct mmal_rational par; /* Pixel aspect ratio */ -+ -+ /* -+ * FourCC specifying the color space of the video stream. See the -+ * MmalColorSpace "pre-defined color spaces" for some examples. -+ */ -+ u32 color_space; -+}; -+ -+struct mmal_subpicture_format { -+ u32 x_offset; -+ u32 y_offset; -+}; -+ -+union mmal_es_specific_format { -+ struct mmal_audio_format audio; -+ struct mmal_video_format video; -+ struct mmal_subpicture_format subpicture; -+}; -+ -+/* Definition of an elementary stream format (MMAL_ES_FORMAT_T) */ -+struct mmal_es_format_local { -+ u32 type; /* enum mmal_es_type */ -+ -+ u32 encoding; /* FourCC specifying encoding of the elementary -+ * stream. -+ */ -+ u32 encoding_variant; /* FourCC specifying the specific -+ * encoding variant of the elementary -+ * stream. -+ */ -+ -+ union mmal_es_specific_format *es; /* Type specific -+ * information for the -+ * elementary stream -+ */ -+ -+ u32 bitrate; /* Bitrate in bits per second */ -+ u32 flags; /* Flags describing properties of the elementary -+ * stream. -+ */ -+ -+ u32 extradata_size; /* Size of the codec specific data */ -+ u8 *extradata; /* Codec specific data */ -+}; -+ -+/* Remote definition of an elementary stream format (MMAL_ES_FORMAT_T) */ -+struct mmal_es_format { -+ u32 type; /* enum mmal_es_type */ -+ -+ u32 encoding; /* FourCC specifying encoding of the elementary -+ * stream. -+ */ -+ u32 encoding_variant; /* FourCC specifying the specific -+ * encoding variant of the elementary -+ * stream. -+ */ -+ -+ u32 es; /* Type specific -+ * information for the -+ * elementary stream -+ */ -+ -+ u32 bitrate; /* Bitrate in bits per second */ -+ u32 flags; /* Flags describing properties of the elementary -+ * stream. -+ */ -+ -+ u32 extradata_size; /* Size of the codec specific data */ -+ u32 extradata; /* Codec specific data */ -+}; -+ -+#endif /* MMAL_MSG_FORMAT_H */ ---- /dev/null -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-port.h -@@ -0,0 +1,109 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Broadcom BM2835 V4L2 driver -+ * -+ * Copyright © 2013 Raspberry Pi (Trading) Ltd. -+ * -+ * Authors: Vincent Sanders @ Collabora -+ * Dave Stevenson @ Broadcom -+ * (now dave.stevenson@raspberrypi.org) -+ * Simon Mellor @ Broadcom -+ * Luke Diamand @ Broadcom -+ */ -+ -+/* MMAL_PORT_TYPE_T */ -+enum mmal_port_type { -+ MMAL_PORT_TYPE_UNKNOWN = 0, /* Unknown port type */ -+ MMAL_PORT_TYPE_CONTROL, /* Control port */ -+ MMAL_PORT_TYPE_INPUT, /* Input port */ -+ MMAL_PORT_TYPE_OUTPUT, /* Output port */ -+ MMAL_PORT_TYPE_CLOCK, /* Clock port */ -+}; -+ -+/* The port is pass-through and doesn't need buffer headers allocated */ -+#define MMAL_PORT_CAPABILITY_PASSTHROUGH 0x01 -+/* -+ *The port wants to allocate the buffer payloads. -+ * This signals a preference that payload allocation should be done -+ * on this port for efficiency reasons. -+ */ -+#define MMAL_PORT_CAPABILITY_ALLOCATION 0x02 -+/* -+ * The port supports format change events. -+ * This applies to input ports and is used to let the client know -+ * whether the port supports being reconfigured via a format -+ * change event (i.e. without having to disable the port). -+ */ -+#define MMAL_PORT_CAPABILITY_SUPPORTS_EVENT_FORMAT_CHANGE 0x04 -+ -+/* -+ * mmal port structure (MMAL_PORT_T) -+ * -+ * most elements are informational only, the pointer values for -+ * interogation messages are generally provided as additional -+ * structures within the message. When used to set values only the -+ * buffer_num, buffer_size and userdata parameters are writable. -+ */ -+struct mmal_port { -+ u32 priv; /* Private member used by the framework */ -+ u32 name; /* Port name. Used for debugging purposes (RO) */ -+ -+ u32 type; /* Type of the port (RO) enum mmal_port_type */ -+ u16 index; /* Index of the port in its type list (RO) */ -+ u16 index_all; /* Index of the port in the list of all ports (RO) */ -+ -+ u32 is_enabled; /* Indicates whether the port is enabled or not (RO) */ -+ u32 format; /* Format of the elementary stream */ -+ -+ u32 buffer_num_min; /* Minimum number of buffers the port -+ * requires (RO). This is set by the -+ * component. -+ */ -+ -+ u32 buffer_size_min; /* Minimum size of buffers the port -+ * requires (RO). This is set by the -+ * component. -+ */ -+ -+ u32 buffer_alignment_min;/* Minimum alignment requirement for -+ * the buffers (RO). A value of -+ * zero means no special alignment -+ * requirements. This is set by the -+ * component. -+ */ -+ -+ u32 buffer_num_recommended; /* Number of buffers the port -+ * recommends for optimal -+ * performance (RO). A value of -+ * zero means no special -+ * recommendation. This is set -+ * by the component. -+ */ -+ -+ u32 buffer_size_recommended; /* Size of buffers the port -+ * recommends for optimal -+ * performance (RO). A value of -+ * zero means no special -+ * recommendation. This is set -+ * by the component. -+ */ -+ -+ u32 buffer_num; /* Actual number of buffers the port will use. -+ * This is set by the client. -+ */ -+ -+ u32 buffer_size; /* Actual maximum size of the buffers that -+ * will be sent to the port. This is set by -+ * the client. -+ */ -+ -+ u32 component; /* Component this port belongs to (Read Only) */ -+ -+ u32 userdata; /* Field reserved for use by the client */ -+ -+ u32 capabilities; /* Flags describing the capabilities of a -+ * port (RO). Bitwise combination of \ref -+ * portcapabilities "Port capabilities" -+ * values. -+ */ -+}; ---- /dev/null -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h -@@ -0,0 +1,406 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Broadcom BM2835 V4L2 driver -+ * -+ * Copyright © 2013 Raspberry Pi (Trading) Ltd. -+ * -+ * Authors: Vincent Sanders @ Collabora -+ * Dave Stevenson @ Broadcom -+ * (now dave.stevenson@raspberrypi.org) -+ * Simon Mellor @ Broadcom -+ * Luke Diamand @ Broadcom -+ */ -+ -+/* -+ * all the data structures which serialise the MMAL protocol. note -+ * these are directly mapped onto the recived message data. -+ * -+ * BEWARE: They seem to *assume* pointers are u32 and that there is no -+ * structure padding! -+ * -+ * NOTE: this implementation uses kernel types to ensure sizes. Rather -+ * than assigning values to enums to force their size the -+ * implementation uses fixed size types and not the enums (though the -+ * comments have the actual enum type -+ */ -+#ifndef MMAL_MSG_H -+#define MMAL_MSG_H -+ -+#define VC_MMAL_VER 15 -+#define VC_MMAL_MIN_VER 10 -+#define VC_MMAL_SERVER_NAME MAKE_FOURCC("mmal") -+ -+/* max total message size is 512 bytes */ -+#define MMAL_MSG_MAX_SIZE 512 -+/* with six 32bit header elements max payload is therefore 488 bytes */ -+#define MMAL_MSG_MAX_PAYLOAD 488 -+ -+#include "mmal-msg-common.h" -+#include "mmal-msg-format.h" -+#include "mmal-msg-port.h" -+ -+enum mmal_msg_type { -+ MMAL_MSG_TYPE_QUIT = 1, -+ MMAL_MSG_TYPE_SERVICE_CLOSED, -+ MMAL_MSG_TYPE_GET_VERSION, -+ MMAL_MSG_TYPE_COMPONENT_CREATE, -+ MMAL_MSG_TYPE_COMPONENT_DESTROY, /* 5 */ -+ MMAL_MSG_TYPE_COMPONENT_ENABLE, -+ MMAL_MSG_TYPE_COMPONENT_DISABLE, -+ MMAL_MSG_TYPE_PORT_INFO_GET, -+ MMAL_MSG_TYPE_PORT_INFO_SET, -+ MMAL_MSG_TYPE_PORT_ACTION, /* 10 */ -+ MMAL_MSG_TYPE_BUFFER_FROM_HOST, -+ MMAL_MSG_TYPE_BUFFER_TO_HOST, -+ MMAL_MSG_TYPE_GET_STATS, -+ MMAL_MSG_TYPE_PORT_PARAMETER_SET, -+ MMAL_MSG_TYPE_PORT_PARAMETER_GET, /* 15 */ -+ MMAL_MSG_TYPE_EVENT_TO_HOST, -+ MMAL_MSG_TYPE_GET_CORE_STATS_FOR_PORT, -+ MMAL_MSG_TYPE_OPAQUE_ALLOCATOR, -+ MMAL_MSG_TYPE_CONSUME_MEM, -+ MMAL_MSG_TYPE_LMK, /* 20 */ -+ MMAL_MSG_TYPE_OPAQUE_ALLOCATOR_DESC, -+ MMAL_MSG_TYPE_DRM_GET_LHS32, -+ MMAL_MSG_TYPE_DRM_GET_TIME, -+ MMAL_MSG_TYPE_BUFFER_FROM_HOST_ZEROLEN, -+ MMAL_MSG_TYPE_PORT_FLUSH, /* 25 */ -+ MMAL_MSG_TYPE_HOST_LOG, -+ MMAL_MSG_TYPE_MSG_LAST -+}; -+ -+/* port action request messages differ depending on the action type */ -+enum mmal_msg_port_action_type { -+ MMAL_MSG_PORT_ACTION_TYPE_UNKNOWN = 0, /* Unknown action */ -+ MMAL_MSG_PORT_ACTION_TYPE_ENABLE, /* Enable a port */ -+ MMAL_MSG_PORT_ACTION_TYPE_DISABLE, /* Disable a port */ -+ MMAL_MSG_PORT_ACTION_TYPE_FLUSH, /* Flush a port */ -+ MMAL_MSG_PORT_ACTION_TYPE_CONNECT, /* Connect ports */ -+ MMAL_MSG_PORT_ACTION_TYPE_DISCONNECT, /* Disconnect ports */ -+ MMAL_MSG_PORT_ACTION_TYPE_SET_REQUIREMENTS, /* Set buffer requirements*/ -+}; -+ -+struct mmal_msg_header { -+ u32 magic; -+ u32 type; /* enum mmal_msg_type */ -+ -+ /* Opaque handle to the control service */ -+ u32 control_service; -+ -+ u32 context; /* a u32 per message context */ -+ u32 status; /* The status of the vchiq operation */ -+ u32 padding; -+}; -+ -+/* Send from VC to host to report version */ -+struct mmal_msg_version { -+ u32 flags; -+ u32 major; -+ u32 minor; -+ u32 minimum; -+}; -+ -+/* request to VC to create component */ -+struct mmal_msg_component_create { -+ u32 client_component; /* component context */ -+ char name[128]; -+ u32 pid; /* For debug */ -+}; -+ -+/* reply from VC to component creation request */ -+struct mmal_msg_component_create_reply { -+ u32 status; /* enum mmal_msg_status - how does this differ to -+ * the one in the header? -+ */ -+ u32 component_handle; /* VideoCore handle for component */ -+ u32 input_num; /* Number of input ports */ -+ u32 output_num; /* Number of output ports */ -+ u32 clock_num; /* Number of clock ports */ -+}; -+ -+/* request to VC to destroy a component */ -+struct mmal_msg_component_destroy { -+ u32 component_handle; -+}; -+ -+struct mmal_msg_component_destroy_reply { -+ u32 status; /* The component destruction status */ -+}; -+ -+/* request and reply to VC to enable a component */ -+struct mmal_msg_component_enable { -+ u32 component_handle; -+}; -+ -+struct mmal_msg_component_enable_reply { -+ u32 status; /* The component enable status */ -+}; -+ -+/* request and reply to VC to disable a component */ -+struct mmal_msg_component_disable { -+ u32 component_handle; -+}; -+ -+struct mmal_msg_component_disable_reply { -+ u32 status; /* The component disable status */ -+}; -+ -+/* request to VC to get port information */ -+struct mmal_msg_port_info_get { -+ u32 component_handle; /* component handle port is associated with */ -+ u32 port_type; /* enum mmal_msg_port_type */ -+ u32 index; /* port index to query */ -+}; -+ -+/* reply from VC to get port info request */ -+struct mmal_msg_port_info_get_reply { -+ u32 status; /* enum mmal_msg_status */ -+ u32 component_handle; /* component handle port is associated with */ -+ u32 port_type; /* enum mmal_msg_port_type */ -+ u32 port_index; /* port indexed in query */ -+ s32 found; /* unused */ -+ u32 port_handle; /* Handle to use for this port */ -+ struct mmal_port port; -+ struct mmal_es_format format; /* elementary stream format */ -+ union mmal_es_specific_format es; /* es type specific data */ -+ u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; /* es extra data */ -+}; -+ -+/* request to VC to set port information */ -+struct mmal_msg_port_info_set { -+ u32 component_handle; -+ u32 port_type; /* enum mmal_msg_port_type */ -+ u32 port_index; /* port indexed in query */ -+ struct mmal_port port; -+ struct mmal_es_format format; -+ union mmal_es_specific_format es; -+ u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; -+}; -+ -+/* reply from VC to port info set request */ -+struct mmal_msg_port_info_set_reply { -+ u32 status; -+ u32 component_handle; /* component handle port is associated with */ -+ u32 port_type; /* enum mmal_msg_port_type */ -+ u32 index; /* port indexed in query */ -+ s32 found; /* unused */ -+ u32 port_handle; /* Handle to use for this port */ -+ struct mmal_port port; -+ struct mmal_es_format format; -+ union mmal_es_specific_format es; -+ u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; -+}; -+ -+/* port action requests that take a mmal_port as a parameter */ -+struct mmal_msg_port_action_port { -+ u32 component_handle; -+ u32 port_handle; -+ u32 action; /* enum mmal_msg_port_action_type */ -+ struct mmal_port port; -+}; -+ -+/* port action requests that take handles as a parameter */ -+struct mmal_msg_port_action_handle { -+ u32 component_handle; -+ u32 port_handle; -+ u32 action; /* enum mmal_msg_port_action_type */ -+ u32 connect_component_handle; -+ u32 connect_port_handle; -+}; -+ -+struct mmal_msg_port_action_reply { -+ u32 status; /* The port action operation status */ -+}; -+ -+/* MMAL buffer transfer */ -+ -+/* Size of space reserved in a buffer message for short messages. */ -+#define MMAL_VC_SHORT_DATA 128 -+ -+/* Signals that the current payload is the end of the stream of data */ -+#define MMAL_BUFFER_HEADER_FLAG_EOS BIT(0) -+/* Signals that the start of the current payload starts a frame */ -+#define MMAL_BUFFER_HEADER_FLAG_FRAME_START BIT(1) -+/* Signals that the end of the current payload ends a frame */ -+#define MMAL_BUFFER_HEADER_FLAG_FRAME_END BIT(2) -+/* Signals that the current payload contains only complete frames (>1) */ -+#define MMAL_BUFFER_HEADER_FLAG_FRAME \ -+ (MMAL_BUFFER_HEADER_FLAG_FRAME_START | \ -+ MMAL_BUFFER_HEADER_FLAG_FRAME_END) -+/* Signals that the current payload is a keyframe (i.e. self decodable) */ -+#define MMAL_BUFFER_HEADER_FLAG_KEYFRAME BIT(3) -+/* -+ * Signals a discontinuity in the stream of data (e.g. after a seek). -+ * Can be used for instance by a decoder to reset its state -+ */ -+#define MMAL_BUFFER_HEADER_FLAG_DISCONTINUITY BIT(4) -+/* -+ * Signals a buffer containing some kind of config data for the component -+ * (e.g. codec config data) -+ */ -+#define MMAL_BUFFER_HEADER_FLAG_CONFIG BIT(5) -+/* Signals an encrypted payload */ -+#define MMAL_BUFFER_HEADER_FLAG_ENCRYPTED BIT(6) -+/* Signals a buffer containing side information */ -+#define MMAL_BUFFER_HEADER_FLAG_CODECSIDEINFO BIT(7) -+/* -+ * Signals a buffer which is the snapshot/postview image from a stills -+ * capture -+ */ -+#define MMAL_BUFFER_HEADER_FLAGS_SNAPSHOT BIT(8) -+/* Signals a buffer which contains data known to be corrupted */ -+#define MMAL_BUFFER_HEADER_FLAG_CORRUPTED BIT(9) -+/* Signals that a buffer failed to be transmitted */ -+#define MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED BIT(10) -+ -+struct mmal_driver_buffer { -+ u32 magic; -+ u32 component_handle; -+ u32 port_handle; -+ u32 client_context; -+}; -+ -+/* buffer header */ -+struct mmal_buffer_header { -+ u32 next; /* next header */ -+ u32 priv; /* framework private data */ -+ u32 cmd; -+ u32 data; -+ u32 alloc_size; -+ u32 length; -+ u32 offset; -+ u32 flags; -+ s64 pts; -+ s64 dts; -+ u32 type; -+ u32 user_data; -+}; -+ -+struct mmal_buffer_header_type_specific { -+ union { -+ struct { -+ u32 planes; -+ u32 offset[4]; -+ u32 pitch[4]; -+ u32 flags; -+ } video; -+ } u; -+}; -+ -+struct mmal_msg_buffer_from_host { -+ /* -+ *The front 32 bytes of the buffer header are copied -+ * back to us in the reply to allow for context. This -+ * area is used to store two mmal_driver_buffer structures to -+ * allow for multiple concurrent service users. -+ */ -+ /* control data */ -+ struct mmal_driver_buffer drvbuf; -+ -+ /* referenced control data for passthrough buffer management */ -+ struct mmal_driver_buffer drvbuf_ref; -+ struct mmal_buffer_header buffer_header; /* buffer header itself */ -+ struct mmal_buffer_header_type_specific buffer_header_type_specific; -+ s32 is_zero_copy; -+ s32 has_reference; -+ -+ /* allows short data to be xfered in control message */ -+ u32 payload_in_message; -+ u8 short_data[MMAL_VC_SHORT_DATA]; -+}; -+ -+/* port parameter setting */ -+ -+#define MMAL_WORKER_PORT_PARAMETER_SPACE 96 -+ -+struct mmal_msg_port_parameter_set { -+ u32 component_handle; /* component */ -+ u32 port_handle; /* port */ -+ u32 id; /* Parameter ID */ -+ u32 size; /* Parameter size */ -+ uint32_t value[MMAL_WORKER_PORT_PARAMETER_SPACE]; -+}; -+ -+struct mmal_msg_port_parameter_set_reply { -+ u32 status; /* enum mmal_msg_status todo: how does this -+ * differ to the one in the header? -+ */ -+}; -+ -+/* port parameter getting */ -+ -+struct mmal_msg_port_parameter_get { -+ u32 component_handle; /* component */ -+ u32 port_handle; /* port */ -+ u32 id; /* Parameter ID */ -+ u32 size; /* Parameter size */ -+}; -+ -+struct mmal_msg_port_parameter_get_reply { -+ u32 status; /* Status of mmal_port_parameter_get call */ -+ u32 id; /* Parameter ID */ -+ u32 size; /* Parameter size */ -+ uint32_t value[MMAL_WORKER_PORT_PARAMETER_SPACE]; -+}; -+ -+/* event messages */ -+#define MMAL_WORKER_EVENT_SPACE 256 -+ -+struct mmal_msg_event_to_host { -+ u32 client_component; /* component context */ -+ -+ u32 port_type; -+ u32 port_num; -+ -+ u32 cmd; -+ u32 length; -+ u8 data[MMAL_WORKER_EVENT_SPACE]; -+ u32 delayed_buffer; -+}; -+ -+/* all mmal messages are serialised through this structure */ -+struct mmal_msg { -+ /* header */ -+ struct mmal_msg_header h; -+ /* payload */ -+ union { -+ struct mmal_msg_version version; -+ -+ struct mmal_msg_component_create component_create; -+ struct mmal_msg_component_create_reply component_create_reply; -+ -+ struct mmal_msg_component_destroy component_destroy; -+ struct mmal_msg_component_destroy_reply component_destroy_reply; -+ -+ struct mmal_msg_component_enable component_enable; -+ struct mmal_msg_component_enable_reply component_enable_reply; -+ -+ struct mmal_msg_component_disable component_disable; -+ struct mmal_msg_component_disable_reply component_disable_reply; -+ -+ struct mmal_msg_port_info_get port_info_get; -+ struct mmal_msg_port_info_get_reply port_info_get_reply; -+ -+ struct mmal_msg_port_info_set port_info_set; -+ struct mmal_msg_port_info_set_reply port_info_set_reply; -+ -+ struct mmal_msg_port_action_port port_action_port; -+ struct mmal_msg_port_action_handle port_action_handle; -+ struct mmal_msg_port_action_reply port_action_reply; -+ -+ struct mmal_msg_buffer_from_host buffer_from_host; -+ -+ struct mmal_msg_port_parameter_set port_parameter_set; -+ struct mmal_msg_port_parameter_set_reply -+ port_parameter_set_reply; -+ struct mmal_msg_port_parameter_get -+ port_parameter_get; -+ struct mmal_msg_port_parameter_get_reply -+ port_parameter_get_reply; -+ -+ struct mmal_msg_event_to_host event_to_host; -+ -+ u8 payload[MMAL_MSG_MAX_PAYLOAD]; -+ } u; -+}; -+#endif ---- /dev/null -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h -@@ -0,0 +1,755 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Broadcom BM2835 V4L2 driver -+ * -+ * Copyright © 2013 Raspberry Pi (Trading) Ltd. -+ * -+ * Authors: Vincent Sanders @ Collabora -+ * Dave Stevenson @ Broadcom -+ * (now dave.stevenson@raspberrypi.org) -+ * Simon Mellor @ Broadcom -+ * Luke Diamand @ Broadcom -+ */ -+ -+/* common parameters */ -+ -+/** @name Parameter groups -+ * Parameters are divided into groups, and then allocated sequentially within -+ * a group using an enum. -+ * @{ -+ */ -+ -+#ifndef MMAL_PARAMETERS_H -+#define MMAL_PARAMETERS_H -+ -+/** Common parameter ID group, used with many types of component. */ -+#define MMAL_PARAMETER_GROUP_COMMON (0 << 16) -+/** Camera-specific parameter ID group. */ -+#define MMAL_PARAMETER_GROUP_CAMERA (1 << 16) -+/** Video-specific parameter ID group. */ -+#define MMAL_PARAMETER_GROUP_VIDEO (2 << 16) -+/** Audio-specific parameter ID group. */ -+#define MMAL_PARAMETER_GROUP_AUDIO (3 << 16) -+/** Clock-specific parameter ID group. */ -+#define MMAL_PARAMETER_GROUP_CLOCK (4 << 16) -+/** Miracast-specific parameter ID group. */ -+#define MMAL_PARAMETER_GROUP_MIRACAST (5 << 16) -+ -+/* Common parameters */ -+enum mmal_parameter_common_type { -+ /**< Never a valid parameter ID */ -+ MMAL_PARAMETER_UNUSED = MMAL_PARAMETER_GROUP_COMMON, -+ -+ /**< MMAL_PARAMETER_ENCODING_T */ -+ MMAL_PARAMETER_SUPPORTED_ENCODINGS, -+ /**< MMAL_PARAMETER_URI_T */ -+ MMAL_PARAMETER_URI, -+ /** MMAL_PARAMETER_CHANGE_EVENT_REQUEST_T */ -+ MMAL_PARAMETER_CHANGE_EVENT_REQUEST, -+ /** MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_ZERO_COPY, -+ /**< MMAL_PARAMETER_BUFFER_REQUIREMENTS_T */ -+ MMAL_PARAMETER_BUFFER_REQUIREMENTS, -+ /**< MMAL_PARAMETER_STATISTICS_T */ -+ MMAL_PARAMETER_STATISTICS, -+ /**< MMAL_PARAMETER_CORE_STATISTICS_T */ -+ MMAL_PARAMETER_CORE_STATISTICS, -+ /**< MMAL_PARAMETER_MEM_USAGE_T */ -+ MMAL_PARAMETER_MEM_USAGE, -+ /**< MMAL_PARAMETER_UINT32_T */ -+ MMAL_PARAMETER_BUFFER_FLAG_FILTER, -+ /**< MMAL_PARAMETER_SEEK_T */ -+ MMAL_PARAMETER_SEEK, -+ /**< MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_POWERMON_ENABLE, -+ /**< MMAL_PARAMETER_LOGGING_T */ -+ MMAL_PARAMETER_LOGGING, -+ /**< MMAL_PARAMETER_UINT64_T */ -+ MMAL_PARAMETER_SYSTEM_TIME, -+ /**< MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_NO_IMAGE_PADDING, -+}; -+ -+/* camera parameters */ -+ -+enum mmal_parameter_camera_type { -+ /* 0 */ -+ /** @ref MMAL_PARAMETER_THUMBNAIL_CONFIG_T */ -+ MMAL_PARAMETER_THUMBNAIL_CONFIGURATION = -+ MMAL_PARAMETER_GROUP_CAMERA, -+ /**< Unused? */ -+ MMAL_PARAMETER_CAPTURE_QUALITY, -+ /**< @ref MMAL_PARAMETER_INT32_T */ -+ MMAL_PARAMETER_ROTATION, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_EXIF_DISABLE, -+ /**< @ref MMAL_PARAMETER_EXIF_T */ -+ MMAL_PARAMETER_EXIF, -+ /**< @ref MMAL_PARAM_AWBMODE_T */ -+ MMAL_PARAMETER_AWB_MODE, -+ /**< @ref MMAL_PARAMETER_IMAGEFX_T */ -+ MMAL_PARAMETER_IMAGE_EFFECT, -+ /**< @ref MMAL_PARAMETER_COLOURFX_T */ -+ MMAL_PARAMETER_COLOUR_EFFECT, -+ /**< @ref MMAL_PARAMETER_FLICKERAVOID_T */ -+ MMAL_PARAMETER_FLICKER_AVOID, -+ /**< @ref MMAL_PARAMETER_FLASH_T */ -+ MMAL_PARAMETER_FLASH, -+ /**< @ref MMAL_PARAMETER_REDEYE_T */ -+ MMAL_PARAMETER_REDEYE, -+ /**< @ref MMAL_PARAMETER_FOCUS_T */ -+ MMAL_PARAMETER_FOCUS, -+ /**< Unused? */ -+ MMAL_PARAMETER_FOCAL_LENGTHS, -+ /**< @ref MMAL_PARAMETER_INT32_T */ -+ MMAL_PARAMETER_EXPOSURE_COMP, -+ /**< @ref MMAL_PARAMETER_SCALEFACTOR_T */ -+ MMAL_PARAMETER_ZOOM, -+ /**< @ref MMAL_PARAMETER_MIRROR_T */ -+ MMAL_PARAMETER_MIRROR, -+ -+ /* 0x10 */ -+ /**< @ref MMAL_PARAMETER_UINT32_T */ -+ MMAL_PARAMETER_CAMERA_NUM, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_CAPTURE, -+ /**< @ref MMAL_PARAMETER_EXPOSUREMODE_T */ -+ MMAL_PARAMETER_EXPOSURE_MODE, -+ /**< @ref MMAL_PARAMETER_EXPOSUREMETERINGMODE_T */ -+ MMAL_PARAMETER_EXP_METERING_MODE, -+ /**< @ref MMAL_PARAMETER_FOCUS_STATUS_T */ -+ MMAL_PARAMETER_FOCUS_STATUS, -+ /**< @ref MMAL_PARAMETER_CAMERA_CONFIG_T */ -+ MMAL_PARAMETER_CAMERA_CONFIG, -+ /**< @ref MMAL_PARAMETER_CAPTURE_STATUS_T */ -+ MMAL_PARAMETER_CAPTURE_STATUS, -+ /**< @ref MMAL_PARAMETER_FACE_TRACK_T */ -+ MMAL_PARAMETER_FACE_TRACK, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_DRAW_BOX_FACES_AND_FOCUS, -+ /**< @ref MMAL_PARAMETER_UINT32_T */ -+ MMAL_PARAMETER_JPEG_Q_FACTOR, -+ /**< @ref MMAL_PARAMETER_FRAME_RATE_T */ -+ MMAL_PARAMETER_FRAME_RATE, -+ /**< @ref MMAL_PARAMETER_CAMERA_STC_MODE_T */ -+ MMAL_PARAMETER_USE_STC, -+ /**< @ref MMAL_PARAMETER_CAMERA_INFO_T */ -+ MMAL_PARAMETER_CAMERA_INFO, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_VIDEO_STABILISATION, -+ /**< @ref MMAL_PARAMETER_FACE_TRACK_RESULTS_T */ -+ MMAL_PARAMETER_FACE_TRACK_RESULTS, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_ENABLE_RAW_CAPTURE, -+ -+ /* 0x20 */ -+ /**< @ref MMAL_PARAMETER_URI_T */ -+ MMAL_PARAMETER_DPF_FILE, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_ENABLE_DPF_FILE, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_DPF_FAIL_IS_FATAL, -+ /**< @ref MMAL_PARAMETER_CAPTUREMODE_T */ -+ MMAL_PARAMETER_CAPTURE_MODE, -+ /**< @ref MMAL_PARAMETER_FOCUS_REGIONS_T */ -+ MMAL_PARAMETER_FOCUS_REGIONS, -+ /**< @ref MMAL_PARAMETER_INPUT_CROP_T */ -+ MMAL_PARAMETER_INPUT_CROP, -+ /**< @ref MMAL_PARAMETER_SENSOR_INFORMATION_T */ -+ MMAL_PARAMETER_SENSOR_INFORMATION, -+ /**< @ref MMAL_PARAMETER_FLASH_SELECT_T */ -+ MMAL_PARAMETER_FLASH_SELECT, -+ /**< @ref MMAL_PARAMETER_FIELD_OF_VIEW_T */ -+ MMAL_PARAMETER_FIELD_OF_VIEW, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_HIGH_DYNAMIC_RANGE, -+ /**< @ref MMAL_PARAMETER_DRC_T */ -+ MMAL_PARAMETER_DYNAMIC_RANGE_COMPRESSION, -+ /**< @ref MMAL_PARAMETER_ALGORITHM_CONTROL_T */ -+ MMAL_PARAMETER_ALGORITHM_CONTROL, -+ /**< @ref MMAL_PARAMETER_RATIONAL_T */ -+ MMAL_PARAMETER_SHARPNESS, -+ /**< @ref MMAL_PARAMETER_RATIONAL_T */ -+ MMAL_PARAMETER_CONTRAST, -+ /**< @ref MMAL_PARAMETER_RATIONAL_T */ -+ MMAL_PARAMETER_BRIGHTNESS, -+ /**< @ref MMAL_PARAMETER_RATIONAL_T */ -+ MMAL_PARAMETER_SATURATION, -+ -+ /* 0x30 */ -+ /**< @ref MMAL_PARAMETER_UINT32_T */ -+ MMAL_PARAMETER_ISO, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_ANTISHAKE, -+ /** @ref MMAL_PARAMETER_IMAGEFX_PARAMETERS_T */ -+ MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, -+ /** @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_CAMERA_BURST_CAPTURE, -+ /** @ref MMAL_PARAMETER_UINT32_T */ -+ MMAL_PARAMETER_CAMERA_MIN_ISO, -+ /** @ref MMAL_PARAMETER_CAMERA_USE_CASE_T */ -+ MMAL_PARAMETER_CAMERA_USE_CASE, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_CAPTURE_STATS_PASS, -+ /** @ref MMAL_PARAMETER_UINT32_T */ -+ MMAL_PARAMETER_CAMERA_CUSTOM_SENSOR_CONFIG, -+ /** @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_ENABLE_REGISTER_FILE, -+ /** @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_REGISTER_FAIL_IS_FATAL, -+ /** @ref MMAL_PARAMETER_CONFIGFILE_T */ -+ MMAL_PARAMETER_CONFIGFILE_REGISTERS, -+ /** @ref MMAL_PARAMETER_CONFIGFILE_CHUNK_T */ -+ MMAL_PARAMETER_CONFIGFILE_CHUNK_REGISTERS, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_JPEG_ATTACH_LOG, -+ /**< @ref MMAL_PARAMETER_ZEROSHUTTERLAG_T */ -+ MMAL_PARAMETER_ZERO_SHUTTER_LAG, -+ /**< @ref MMAL_PARAMETER_FPS_RANGE_T */ -+ MMAL_PARAMETER_FPS_RANGE, -+ /**< @ref MMAL_PARAMETER_INT32_T */ -+ MMAL_PARAMETER_CAPTURE_EXPOSURE_COMP, -+ -+ /* 0x40 */ -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_SW_SHARPEN_DISABLE, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_FLASH_REQUIRED, -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_SW_SATURATION_DISABLE, -+ /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ -+ MMAL_PARAMETER_SHUTTER_SPEED, -+ /**< Takes a @ref MMAL_PARAMETER_AWB_GAINS_T */ -+ MMAL_PARAMETER_CUSTOM_AWB_GAINS, -+}; -+ -+struct mmal_parameter_rational { -+ s32 num; /**< Numerator */ -+ s32 den; /**< Denominator */ -+}; -+ -+enum mmal_parameter_camera_config_timestamp_mode { -+ MMAL_PARAM_TIMESTAMP_MODE_ZERO = 0, /* Always timestamp frames as 0 */ -+ MMAL_PARAM_TIMESTAMP_MODE_RAW_STC, /* Use the raw STC value -+ * for the frame timestamp -+ */ -+ MMAL_PARAM_TIMESTAMP_MODE_RESET_STC, /* Use the STC timestamp -+ * but subtract the -+ * timestamp of the first -+ * frame sent to give a -+ * zero based timestamp. -+ */ -+}; -+ -+struct mmal_parameter_fps_range { -+ /**< Low end of the permitted framerate range */ -+ struct mmal_parameter_rational fps_low; -+ /**< High end of the permitted framerate range */ -+ struct mmal_parameter_rational fps_high; -+}; -+ -+/* camera configuration parameter */ -+struct mmal_parameter_camera_config { -+ /* Parameters for setting up the image pools */ -+ u32 max_stills_w; /* Max size of stills capture */ -+ u32 max_stills_h; -+ u32 stills_yuv422; /* Allow YUV422 stills capture */ -+ u32 one_shot_stills; /* Continuous or one shot stills captures. */ -+ -+ u32 max_preview_video_w; /* Max size of the preview or video -+ * capture frames -+ */ -+ u32 max_preview_video_h; -+ u32 num_preview_video_frames; -+ -+ /** Sets the height of the circular buffer for stills capture. */ -+ u32 stills_capture_circular_buffer_height; -+ -+ /** Allows preview/encode to resume as fast as possible after the stills -+ * input frame has been received, and then processes the still frame in -+ * the background whilst preview/encode has resumed. -+ * Actual mode is controlled by MMAL_PARAMETER_CAPTURE_MODE. -+ */ -+ u32 fast_preview_resume; -+ -+ /** Selects algorithm for timestamping frames if -+ * there is no clock component connected. -+ * enum mmal_parameter_camera_config_timestamp_mode -+ */ -+ s32 use_stc_timestamp; -+}; -+ -+enum mmal_parameter_exposuremode { -+ MMAL_PARAM_EXPOSUREMODE_OFF, -+ MMAL_PARAM_EXPOSUREMODE_AUTO, -+ MMAL_PARAM_EXPOSUREMODE_NIGHT, -+ MMAL_PARAM_EXPOSUREMODE_NIGHTPREVIEW, -+ MMAL_PARAM_EXPOSUREMODE_BACKLIGHT, -+ MMAL_PARAM_EXPOSUREMODE_SPOTLIGHT, -+ MMAL_PARAM_EXPOSUREMODE_SPORTS, -+ MMAL_PARAM_EXPOSUREMODE_SNOW, -+ MMAL_PARAM_EXPOSUREMODE_BEACH, -+ MMAL_PARAM_EXPOSUREMODE_VERYLONG, -+ MMAL_PARAM_EXPOSUREMODE_FIXEDFPS, -+ MMAL_PARAM_EXPOSUREMODE_ANTISHAKE, -+ MMAL_PARAM_EXPOSUREMODE_FIREWORKS, -+}; -+ -+enum mmal_parameter_exposuremeteringmode { -+ MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE, -+ MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT, -+ MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT, -+ MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX, -+}; -+ -+enum mmal_parameter_awbmode { -+ MMAL_PARAM_AWBMODE_OFF, -+ MMAL_PARAM_AWBMODE_AUTO, -+ MMAL_PARAM_AWBMODE_SUNLIGHT, -+ MMAL_PARAM_AWBMODE_CLOUDY, -+ MMAL_PARAM_AWBMODE_SHADE, -+ MMAL_PARAM_AWBMODE_TUNGSTEN, -+ MMAL_PARAM_AWBMODE_FLUORESCENT, -+ MMAL_PARAM_AWBMODE_INCANDESCENT, -+ MMAL_PARAM_AWBMODE_FLASH, -+ MMAL_PARAM_AWBMODE_HORIZON, -+}; -+ -+enum mmal_parameter_imagefx { -+ MMAL_PARAM_IMAGEFX_NONE, -+ MMAL_PARAM_IMAGEFX_NEGATIVE, -+ MMAL_PARAM_IMAGEFX_SOLARIZE, -+ MMAL_PARAM_IMAGEFX_POSTERIZE, -+ MMAL_PARAM_IMAGEFX_WHITEBOARD, -+ MMAL_PARAM_IMAGEFX_BLACKBOARD, -+ MMAL_PARAM_IMAGEFX_SKETCH, -+ MMAL_PARAM_IMAGEFX_DENOISE, -+ MMAL_PARAM_IMAGEFX_EMBOSS, -+ MMAL_PARAM_IMAGEFX_OILPAINT, -+ MMAL_PARAM_IMAGEFX_HATCH, -+ MMAL_PARAM_IMAGEFX_GPEN, -+ MMAL_PARAM_IMAGEFX_PASTEL, -+ MMAL_PARAM_IMAGEFX_WATERCOLOUR, -+ MMAL_PARAM_IMAGEFX_FILM, -+ MMAL_PARAM_IMAGEFX_BLUR, -+ MMAL_PARAM_IMAGEFX_SATURATION, -+ MMAL_PARAM_IMAGEFX_COLOURSWAP, -+ MMAL_PARAM_IMAGEFX_WASHEDOUT, -+ MMAL_PARAM_IMAGEFX_POSTERISE, -+ MMAL_PARAM_IMAGEFX_COLOURPOINT, -+ MMAL_PARAM_IMAGEFX_COLOURBALANCE, -+ MMAL_PARAM_IMAGEFX_CARTOON, -+}; -+ -+enum MMAL_PARAM_FLICKERAVOID_T { -+ MMAL_PARAM_FLICKERAVOID_OFF, -+ MMAL_PARAM_FLICKERAVOID_AUTO, -+ MMAL_PARAM_FLICKERAVOID_50HZ, -+ MMAL_PARAM_FLICKERAVOID_60HZ, -+ MMAL_PARAM_FLICKERAVOID_MAX = 0x7FFFFFFF -+}; -+ -+struct mmal_parameter_awbgains { -+ struct mmal_parameter_rational r_gain; /**< Red gain */ -+ struct mmal_parameter_rational b_gain; /**< Blue gain */ -+}; -+ -+/** Manner of video rate control */ -+enum mmal_parameter_rate_control_mode { -+ MMAL_VIDEO_RATECONTROL_DEFAULT, -+ MMAL_VIDEO_RATECONTROL_VARIABLE, -+ MMAL_VIDEO_RATECONTROL_CONSTANT, -+ MMAL_VIDEO_RATECONTROL_VARIABLE_SKIP_FRAMES, -+ MMAL_VIDEO_RATECONTROL_CONSTANT_SKIP_FRAMES -+}; -+ -+enum mmal_video_profile { -+ MMAL_VIDEO_PROFILE_H263_BASELINE, -+ MMAL_VIDEO_PROFILE_H263_H320CODING, -+ MMAL_VIDEO_PROFILE_H263_BACKWARDCOMPATIBLE, -+ MMAL_VIDEO_PROFILE_H263_ISWV2, -+ MMAL_VIDEO_PROFILE_H263_ISWV3, -+ MMAL_VIDEO_PROFILE_H263_HIGHCOMPRESSION, -+ MMAL_VIDEO_PROFILE_H263_INTERNET, -+ MMAL_VIDEO_PROFILE_H263_INTERLACE, -+ MMAL_VIDEO_PROFILE_H263_HIGHLATENCY, -+ MMAL_VIDEO_PROFILE_MP4V_SIMPLE, -+ MMAL_VIDEO_PROFILE_MP4V_SIMPLESCALABLE, -+ MMAL_VIDEO_PROFILE_MP4V_CORE, -+ MMAL_VIDEO_PROFILE_MP4V_MAIN, -+ MMAL_VIDEO_PROFILE_MP4V_NBIT, -+ MMAL_VIDEO_PROFILE_MP4V_SCALABLETEXTURE, -+ MMAL_VIDEO_PROFILE_MP4V_SIMPLEFACE, -+ MMAL_VIDEO_PROFILE_MP4V_SIMPLEFBA, -+ MMAL_VIDEO_PROFILE_MP4V_BASICANIMATED, -+ MMAL_VIDEO_PROFILE_MP4V_HYBRID, -+ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDREALTIME, -+ MMAL_VIDEO_PROFILE_MP4V_CORESCALABLE, -+ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCODING, -+ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCORE, -+ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSCALABLE, -+ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSIMPLE, -+ MMAL_VIDEO_PROFILE_H264_BASELINE, -+ MMAL_VIDEO_PROFILE_H264_MAIN, -+ MMAL_VIDEO_PROFILE_H264_EXTENDED, -+ MMAL_VIDEO_PROFILE_H264_HIGH, -+ MMAL_VIDEO_PROFILE_H264_HIGH10, -+ MMAL_VIDEO_PROFILE_H264_HIGH422, -+ MMAL_VIDEO_PROFILE_H264_HIGH444, -+ MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE, -+ MMAL_VIDEO_PROFILE_DUMMY = 0x7FFFFFFF -+}; -+ -+enum mmal_video_level { -+ MMAL_VIDEO_LEVEL_H263_10, -+ MMAL_VIDEO_LEVEL_H263_20, -+ MMAL_VIDEO_LEVEL_H263_30, -+ MMAL_VIDEO_LEVEL_H263_40, -+ MMAL_VIDEO_LEVEL_H263_45, -+ MMAL_VIDEO_LEVEL_H263_50, -+ MMAL_VIDEO_LEVEL_H263_60, -+ MMAL_VIDEO_LEVEL_H263_70, -+ MMAL_VIDEO_LEVEL_MP4V_0, -+ MMAL_VIDEO_LEVEL_MP4V_0b, -+ MMAL_VIDEO_LEVEL_MP4V_1, -+ MMAL_VIDEO_LEVEL_MP4V_2, -+ MMAL_VIDEO_LEVEL_MP4V_3, -+ MMAL_VIDEO_LEVEL_MP4V_4, -+ MMAL_VIDEO_LEVEL_MP4V_4a, -+ MMAL_VIDEO_LEVEL_MP4V_5, -+ MMAL_VIDEO_LEVEL_MP4V_6, -+ MMAL_VIDEO_LEVEL_H264_1, -+ MMAL_VIDEO_LEVEL_H264_1b, -+ MMAL_VIDEO_LEVEL_H264_11, -+ MMAL_VIDEO_LEVEL_H264_12, -+ MMAL_VIDEO_LEVEL_H264_13, -+ MMAL_VIDEO_LEVEL_H264_2, -+ MMAL_VIDEO_LEVEL_H264_21, -+ MMAL_VIDEO_LEVEL_H264_22, -+ MMAL_VIDEO_LEVEL_H264_3, -+ MMAL_VIDEO_LEVEL_H264_31, -+ MMAL_VIDEO_LEVEL_H264_32, -+ MMAL_VIDEO_LEVEL_H264_4, -+ MMAL_VIDEO_LEVEL_H264_41, -+ MMAL_VIDEO_LEVEL_H264_42, -+ MMAL_VIDEO_LEVEL_H264_5, -+ MMAL_VIDEO_LEVEL_H264_51, -+ MMAL_VIDEO_LEVEL_DUMMY = 0x7FFFFFFF -+}; -+ -+struct mmal_parameter_video_profile { -+ enum mmal_video_profile profile; -+ enum mmal_video_level level; -+}; -+ -+/* video parameters */ -+ -+enum mmal_parameter_video_type { -+ /** @ref MMAL_DISPLAYREGION_T */ -+ MMAL_PARAMETER_DISPLAYREGION = MMAL_PARAMETER_GROUP_VIDEO, -+ -+ /** @ref MMAL_PARAMETER_VIDEO_PROFILE_T */ -+ MMAL_PARAMETER_SUPPORTED_PROFILES, -+ -+ /** @ref MMAL_PARAMETER_VIDEO_PROFILE_T */ -+ MMAL_PARAMETER_PROFILE, -+ -+ /** @ref MMAL_PARAMETER_UINT32_T */ -+ MMAL_PARAMETER_INTRAPERIOD, -+ -+ /** @ref MMAL_PARAMETER_VIDEO_RATECONTROL_T */ -+ MMAL_PARAMETER_RATECONTROL, -+ -+ /** @ref MMAL_PARAMETER_VIDEO_NALUNITFORMAT_T */ -+ MMAL_PARAMETER_NALUNITFORMAT, -+ -+ /** @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_MINIMISE_FRAGMENTATION, -+ -+ /** @ref MMAL_PARAMETER_UINT32_T. -+ * Setting the value to zero resets to the default (one slice per -+ * frame). -+ */ -+ MMAL_PARAMETER_MB_ROWS_PER_SLICE, -+ -+ /** @ref MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION_T */ -+ MMAL_PARAMETER_VIDEO_LEVEL_EXTENSION, -+ -+ /** @ref MMAL_PARAMETER_VIDEO_EEDE_ENABLE_T */ -+ MMAL_PARAMETER_VIDEO_EEDE_ENABLE, -+ -+ /** @ref MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE_T */ -+ MMAL_PARAMETER_VIDEO_EEDE_LOSSRATE, -+ -+ /** @ref MMAL_PARAMETER_BOOLEAN_T. Request an I-frame. */ -+ MMAL_PARAMETER_VIDEO_REQUEST_I_FRAME, -+ /** @ref MMAL_PARAMETER_VIDEO_INTRA_REFRESH_T */ -+ MMAL_PARAMETER_VIDEO_INTRA_REFRESH, -+ -+ /** @ref MMAL_PARAMETER_BOOLEAN_T. */ -+ MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, -+ -+ /** @ref MMAL_PARAMETER_UINT32_T. Run-time bit rate control */ -+ MMAL_PARAMETER_VIDEO_BIT_RATE, -+ -+ /** @ref MMAL_PARAMETER_FRAME_RATE_T */ -+ MMAL_PARAMETER_VIDEO_FRAME_RATE, -+ -+ /** @ref MMAL_PARAMETER_UINT32_T. */ -+ MMAL_PARAMETER_VIDEO_ENCODE_MIN_QUANT, -+ -+ /** @ref MMAL_PARAMETER_UINT32_T. */ -+ MMAL_PARAMETER_VIDEO_ENCODE_MAX_QUANT, -+ -+ /** @ref MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL_T. */ -+ MMAL_PARAMETER_VIDEO_ENCODE_RC_MODEL, -+ -+ MMAL_PARAMETER_EXTRA_BUFFERS, /**< @ref MMAL_PARAMETER_UINT32_T. */ -+ /** @ref MMAL_PARAMETER_UINT32_T. -+ * Changing this parameter from the default can reduce frame rate -+ * because image buffers need to be re-pitched. -+ */ -+ MMAL_PARAMETER_VIDEO_ALIGN_HORIZ, -+ -+ /** @ref MMAL_PARAMETER_UINT32_T. -+ * Changing this parameter from the default can reduce frame rate -+ * because image buffers need to be re-pitched. -+ */ -+ MMAL_PARAMETER_VIDEO_ALIGN_VERT, -+ -+ /** @ref MMAL_PARAMETER_BOOLEAN_T. */ -+ MMAL_PARAMETER_VIDEO_DROPPABLE_PFRAMES, -+ -+ /** @ref MMAL_PARAMETER_UINT32_T. */ -+ MMAL_PARAMETER_VIDEO_ENCODE_INITIAL_QUANT, -+ -+ /**< @ref MMAL_PARAMETER_UINT32_T. */ -+ MMAL_PARAMETER_VIDEO_ENCODE_QP_P, -+ -+ /**< @ref MMAL_PARAMETER_UINT32_T. */ -+ MMAL_PARAMETER_VIDEO_ENCODE_RC_SLICE_DQUANT, -+ -+ /** @ref MMAL_PARAMETER_UINT32_T */ -+ MMAL_PARAMETER_VIDEO_ENCODE_FRAME_LIMIT_BITS, -+ -+ /** @ref MMAL_PARAMETER_UINT32_T. */ -+ MMAL_PARAMETER_VIDEO_ENCODE_PEAK_RATE, -+ -+ /* H264 specific parameters */ -+ -+ /** @ref MMAL_PARAMETER_BOOLEAN_T. */ -+ MMAL_PARAMETER_VIDEO_ENCODE_H264_DISABLE_CABAC, -+ -+ /** @ref MMAL_PARAMETER_BOOLEAN_T. */ -+ MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_LATENCY, -+ -+ /** @ref MMAL_PARAMETER_BOOLEAN_T. */ -+ MMAL_PARAMETER_VIDEO_ENCODE_H264_AU_DELIMITERS, -+ -+ /** @ref MMAL_PARAMETER_UINT32_T. */ -+ MMAL_PARAMETER_VIDEO_ENCODE_H264_DEBLOCK_IDC, -+ -+ /** @ref MMAL_PARAMETER_VIDEO_ENCODER_H264_MB_INTRA_MODES_T. */ -+ MMAL_PARAMETER_VIDEO_ENCODE_H264_MB_INTRA_MODE, -+ -+ /** @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_VIDEO_ENCODE_HEADER_ON_OPEN, -+ -+ /** @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_VIDEO_ENCODE_PRECODE_FOR_QP, -+ -+ /** @ref MMAL_PARAMETER_VIDEO_DRM_INIT_INFO_T. */ -+ MMAL_PARAMETER_VIDEO_DRM_INIT_INFO, -+ -+ /** @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_VIDEO_TIMESTAMP_FIFO, -+ -+ /** @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_VIDEO_DECODE_ERROR_CONCEALMENT, -+ -+ /** @ref MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER_T. */ -+ MMAL_PARAMETER_VIDEO_DRM_PROTECT_BUFFER, -+ -+ /** @ref MMAL_PARAMETER_BYTES_T */ -+ MMAL_PARAMETER_VIDEO_DECODE_CONFIG_VD3, -+ -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_VIDEO_ENCODE_H264_VCL_HRD_PARAMETERS, -+ -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_DELAY_HRD_FLAG, -+ -+ /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER -+}; -+ -+/** Valid mirror modes */ -+enum mmal_parameter_mirror { -+ MMAL_PARAM_MIRROR_NONE, -+ MMAL_PARAM_MIRROR_VERTICAL, -+ MMAL_PARAM_MIRROR_HORIZONTAL, -+ MMAL_PARAM_MIRROR_BOTH, -+}; -+ -+enum mmal_parameter_displaytransform { -+ MMAL_DISPLAY_ROT0 = 0, -+ MMAL_DISPLAY_MIRROR_ROT0 = 1, -+ MMAL_DISPLAY_MIRROR_ROT180 = 2, -+ MMAL_DISPLAY_ROT180 = 3, -+ MMAL_DISPLAY_MIRROR_ROT90 = 4, -+ MMAL_DISPLAY_ROT270 = 5, -+ MMAL_DISPLAY_ROT90 = 6, -+ MMAL_DISPLAY_MIRROR_ROT270 = 7, -+}; -+ -+enum mmal_parameter_displaymode { -+ MMAL_DISPLAY_MODE_FILL = 0, -+ MMAL_DISPLAY_MODE_LETTERBOX = 1, -+}; -+ -+enum mmal_parameter_displayset { -+ MMAL_DISPLAY_SET_NONE = 0, -+ MMAL_DISPLAY_SET_NUM = 1, -+ MMAL_DISPLAY_SET_FULLSCREEN = 2, -+ MMAL_DISPLAY_SET_TRANSFORM = 4, -+ MMAL_DISPLAY_SET_DEST_RECT = 8, -+ MMAL_DISPLAY_SET_SRC_RECT = 0x10, -+ MMAL_DISPLAY_SET_MODE = 0x20, -+ MMAL_DISPLAY_SET_PIXEL = 0x40, -+ MMAL_DISPLAY_SET_NOASPECT = 0x80, -+ MMAL_DISPLAY_SET_LAYER = 0x100, -+ MMAL_DISPLAY_SET_COPYPROTECT = 0x200, -+ MMAL_DISPLAY_SET_ALPHA = 0x400, -+}; -+ -+/* rectangle, used lots so it gets its own struct */ -+struct vchiq_mmal_rect { -+ s32 x; -+ s32 y; -+ s32 width; -+ s32 height; -+}; -+ -+struct mmal_parameter_displayregion { -+ /** Bitfield that indicates which fields are set and should be -+ * used. All other fields will maintain their current value. -+ * \ref MMAL_DISPLAYSET_T defines the bits that can be -+ * combined. -+ */ -+ u32 set; -+ -+ /** Describes the display output device, with 0 typically -+ * being a directly connected LCD display. The actual values -+ * will depend on the hardware. Code using hard-wired numbers -+ * (e.g. 2) is certain to fail. -+ */ -+ -+ u32 display_num; -+ /** Indicates that we are using the full device screen area, -+ * rather than a window of the display. If zero, then -+ * dest_rect is used to specify a region of the display to -+ * use. -+ */ -+ -+ s32 fullscreen; -+ /** Indicates any rotation or flipping used to map frames onto -+ * the natural display orientation. -+ */ -+ u32 transform; /* enum mmal_parameter_displaytransform */ -+ -+ /** Where to display the frame within the screen, if -+ * fullscreen is zero. -+ */ -+ struct vchiq_mmal_rect dest_rect; -+ -+ /** Indicates which area of the frame to display. If all -+ * values are zero, the whole frame will be used. -+ */ -+ struct vchiq_mmal_rect src_rect; -+ -+ /** If set to non-zero, indicates that any display scaling -+ * should disregard the aspect ratio of the frame region being -+ * displayed. -+ */ -+ s32 noaspect; -+ -+ /** Indicates how the image should be scaled to fit the -+ * display. \code MMAL_DISPLAY_MODE_FILL \endcode indicates -+ * that the image should fill the screen by potentially -+ * cropping the frames. Setting \code mode \endcode to \code -+ * MMAL_DISPLAY_MODE_LETTERBOX \endcode indicates that all the -+ * source region should be displayed and black bars added if -+ * necessary. -+ */ -+ u32 mode; /* enum mmal_parameter_displaymode */ -+ -+ /** If non-zero, defines the width of a source pixel relative -+ * to \code pixel_y \endcode. If zero, then pixels default to -+ * being square. -+ */ -+ u32 pixel_x; -+ -+ /** If non-zero, defines the height of a source pixel relative -+ * to \code pixel_x \endcode. If zero, then pixels default to -+ * being square. -+ */ -+ u32 pixel_y; -+ -+ /** Sets the relative depth of the images, with greater values -+ * being in front of smaller values. -+ */ -+ u32 layer; -+ -+ /** Set to non-zero to ensure copy protection is used on -+ * output. -+ */ -+ s32 copyprotect_required; -+ -+ /** Level of opacity of the layer, where zero is fully -+ * transparent and 255 is fully opaque. -+ */ -+ u32 alpha; -+}; -+ -+#define MMAL_MAX_IMAGEFX_PARAMETERS 5 -+ -+struct mmal_parameter_imagefx_parameters { -+ enum mmal_parameter_imagefx effect; -+ u32 num_effect_params; -+ u32 effect_parameter[MMAL_MAX_IMAGEFX_PARAMETERS]; -+}; -+ -+#define MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS 4 -+#define MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES 2 -+#define MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN 16 -+ -+struct mmal_parameter_camera_info_camera_t { -+ u32 port_id; -+ u32 max_width; -+ u32 max_height; -+ u32 lens_present; -+ u8 camera_name[MMAL_PARAMETER_CAMERA_INFO_MAX_STR_LEN]; -+}; -+ -+enum mmal_parameter_camera_info_flash_type_t { -+ /* Make values explicit to ensure they match values in config ini */ -+ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_XENON = 0, -+ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_LED = 1, -+ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_OTHER = 2, -+ MMAL_PARAMETER_CAMERA_INFO_FLASH_TYPE_MAX = 0x7FFFFFFF -+}; -+ -+struct mmal_parameter_camera_info_flash_t { -+ enum mmal_parameter_camera_info_flash_type_t flash_type; -+}; -+ -+struct mmal_parameter_camera_info_t { -+ u32 num_cameras; -+ u32 num_flashes; -+ struct mmal_parameter_camera_info_camera_t -+ cameras[MMAL_PARAMETER_CAMERA_INFO_MAX_CAMERAS]; -+ struct mmal_parameter_camera_info_flash_t -+ flashes[MMAL_PARAMETER_CAMERA_INFO_MAX_FLASHES]; -+}; -+ -+#endif ---- /dev/null -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h -@@ -0,0 +1,166 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Broadcom BM2835 V4L2 driver -+ * -+ * Copyright © 2013 Raspberry Pi (Trading) Ltd. -+ * -+ * Authors: Vincent Sanders @ Collabora -+ * Dave Stevenson @ Broadcom -+ * (now dave.stevenson@raspberrypi.org) -+ * Simon Mellor @ Broadcom -+ * Luke Diamand @ Broadcom -+ * -+ * MMAL interface to VCHIQ message passing -+ */ -+ -+#ifndef MMAL_VCHIQ_H -+#define MMAL_VCHIQ_H -+ -+#include "mmal-msg-format.h" -+ -+#define MAX_PORT_COUNT 4 -+ -+/* Maximum size of the format extradata. */ -+#define MMAL_FORMAT_EXTRADATA_MAX_SIZE 128 -+ -+struct vchiq_mmal_instance; -+ -+enum vchiq_mmal_es_type { -+ MMAL_ES_TYPE_UNKNOWN, /**< Unknown elementary stream type */ -+ MMAL_ES_TYPE_CONTROL, /**< Elementary stream of control commands */ -+ MMAL_ES_TYPE_AUDIO, /**< Audio elementary stream */ -+ MMAL_ES_TYPE_VIDEO, /**< Video elementary stream */ -+ MMAL_ES_TYPE_SUBPICTURE /**< Sub-picture elementary stream */ -+}; -+ -+struct vchiq_mmal_port_buffer { -+ unsigned int num; /* number of buffers */ -+ u32 size; /* size of buffers */ -+ u32 alignment; /* alignment of buffers */ -+}; -+ -+struct vchiq_mmal_port; -+ -+typedef void (*vchiq_mmal_buffer_cb)( -+ struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port, -+ int status, struct mmal_buffer *buffer, -+ unsigned long length, u32 mmal_flags, s64 dts, s64 pts); -+ -+struct vchiq_mmal_port { -+ bool enabled; -+ u32 handle; -+ u32 type; /* port type, cached to use on port info set */ -+ u32 index; /* port index, cached to use on port info set */ -+ -+ /* component port belongs to, allows simple deref */ -+ struct vchiq_mmal_component *component; -+ -+ struct vchiq_mmal_port *connected; /* port conencted to */ -+ -+ /* buffer info */ -+ struct vchiq_mmal_port_buffer minimum_buffer; -+ struct vchiq_mmal_port_buffer recommended_buffer; -+ struct vchiq_mmal_port_buffer current_buffer; -+ -+ /* stream format */ -+ struct mmal_es_format_local format; -+ /* elementary stream format */ -+ union mmal_es_specific_format es; -+ -+ /* data buffers to fill */ -+ struct list_head buffers; -+ /* lock to serialise adding and removing buffers from list */ -+ spinlock_t slock; -+ -+ /* Count of buffers the VPU has yet to return */ -+ atomic_t buffers_with_vpu; -+ /* callback on buffer completion */ -+ vchiq_mmal_buffer_cb buffer_cb; -+ /* callback context */ -+ void *cb_ctx; -+}; -+ -+struct vchiq_mmal_component { -+ bool enabled; -+ u32 handle; /* VideoCore handle for component */ -+ u32 inputs; /* Number of input ports */ -+ u32 outputs; /* Number of output ports */ -+ u32 clocks; /* Number of clock ports */ -+ struct vchiq_mmal_port control; /* control port */ -+ struct vchiq_mmal_port input[MAX_PORT_COUNT]; /* input ports */ -+ struct vchiq_mmal_port output[MAX_PORT_COUNT]; /* output ports */ -+ struct vchiq_mmal_port clock[MAX_PORT_COUNT]; /* clock ports */ -+}; -+ -+int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance); -+int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance); -+ -+/* Initialise a mmal component and its ports -+ * -+ */ -+int vchiq_mmal_component_init( -+ struct vchiq_mmal_instance *instance, -+ const char *name, -+ struct vchiq_mmal_component **component_out); -+ -+int vchiq_mmal_component_finalise( -+ struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_component *component); -+ -+int vchiq_mmal_component_enable( -+ struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_component *component); -+ -+int vchiq_mmal_component_disable( -+ struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_component *component); -+ -+/* enable a mmal port -+ * -+ * enables a port and if a buffer callback provided enque buffer -+ * headers as appropriate for the port. -+ */ -+int vchiq_mmal_port_enable( -+ struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port, -+ vchiq_mmal_buffer_cb buffer_cb); -+ -+/* disable a port -+ * -+ * disable a port will dequeue any pending buffers -+ */ -+int vchiq_mmal_port_disable(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port); -+ -+int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port, -+ u32 parameter, -+ void *value, -+ u32 value_size); -+ -+int vchiq_mmal_port_parameter_get(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port, -+ u32 parameter, -+ void *value, -+ u32 *value_size); -+ -+int vchiq_mmal_port_set_format(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port); -+ -+int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *src, -+ struct vchiq_mmal_port *dst); -+ -+int vchiq_mmal_version(struct vchiq_mmal_instance *instance, -+ u32 *major_out, -+ u32 *minor_out); -+ -+int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port, -+ struct mmal_buffer *buf); -+ -+int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance, -+ struct mmal_buffer *buf); -+int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf); -+#endif /* MMAL_VCHIQ_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0268-staging-mmal-vchiq-Allocate-and-free-components-as-r.patch b/target/linux/brcm2708/patches-4.19/950-0268-staging-mmal-vchiq-Allocate-and-free-components-as-r.patch deleted file mode 100644 index 4764ae297e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0268-staging-mmal-vchiq-Allocate-and-free-components-as-r.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 9daa20076f689c9d3f32446b5a73a0f0e20651ca Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 24 Sep 2018 16:51:13 +0100 -Subject: [PATCH 268/703] staging: mmal-vchiq: Allocate and free components as - required - -The existing code assumed that there would only ever be 4 components, -and never freed the entries once used. -Allow arbitrary creation and destruction of components. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/vchiq-mmal/mmal-vchiq.c | 29 ++++++++++++------- - .../vc04_services/vchiq-mmal/mmal-vchiq.h | 1 + - 2 files changed, 20 insertions(+), 10 deletions(-) - ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -38,8 +38,11 @@ MODULE_AUTHOR("Dave Stevenson, vchiq_mutex)) - return -EINTR; - -- if (instance->component_idx == VCHIQ_MMAL_MAX_COMPONENTS) { -+ for (idx = 0; idx < VCHIQ_MMAL_MAX_COMPONENTS; idx++) { -+ if (!instance->component[idx].in_use) { -+ component = &instance->component[idx]; -+ component->in_use = 1; -+ break; -+ } -+ } -+ -+ if (!component) { - ret = -EINVAL; /* todo is this correct error? */ - goto unlock; - } - -- component = &instance->component[instance->component_idx]; -- - ret = create_component(instance, component, name); - if (ret < 0) { - pr_err("%s: failed to create component %d (Not enough GPU mem?)\n", -@@ -1694,8 +1701,6 @@ int vchiq_mmal_component_init(struct vch - goto release_component; - } - -- instance->component_idx++; -- - *component_out = component; - - mutex_unlock(&instance->vchiq_mutex); -@@ -1705,6 +1710,8 @@ int vchiq_mmal_component_init(struct vch - release_component: - destroy_component(instance, component); - unlock: -+ if (component) -+ component->in_use = 0; - mutex_unlock(&instance->vchiq_mutex); - - return ret; -@@ -1727,6 +1734,8 @@ int vchiq_mmal_component_finalise(struct - - ret = destroy_component(instance, component); - -+ component->in_use = 0; -+ - mutex_unlock(&instance->vchiq_mutex); - - return ret; ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h -@@ -82,6 +82,7 @@ struct vchiq_mmal_port { - }; - - struct vchiq_mmal_component { -+ u32 in_use:1; - bool enabled; - u32 handle; /* VideoCore handle for component */ - u32 inputs; /* Number of input ports */ diff --git a/target/linux/brcm2708/patches-4.19/950-0268-staging-mmal-vchiq-Make-a-mmal_buf-struct-for-passin.patch b/target/linux/brcm2708/patches-4.19/950-0268-staging-mmal-vchiq-Make-a-mmal_buf-struct-for-passin.patch new file mode 100644 index 0000000000..9c50e78b6c --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0268-staging-mmal-vchiq-Make-a-mmal_buf-struct-for-passin.patch @@ -0,0 +1,280 @@ +From 2fba609cb0baec25ef32de6ca340951e55aea464 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 24 Sep 2018 17:33:37 +0100 +Subject: [PATCH 268/725] staging: mmal-vchiq: Make a mmal_buf struct for + passing parameters + +The callback from vchi_mmal to the client was growing lots of extra +parameters. Consolidate them into a single struct instead of +growing the list further. +The struct is associated with the client buffer, therefore there +are various changes to setup various containers for the struct, +and pass the appropriate members. + +Signed-off-by: Dave Stevenson +--- + .../bcm2835-camera/bcm2835-camera.c | 62 ++++++++++++------- + .../vc04_services/vchiq-mmal/mmal-common.h | 5 ++ + .../vc04_services/vchiq-mmal/mmal-vchiq.c | 29 ++++++--- + .../vc04_services/vchiq-mmal/mmal-vchiq.h | 3 +- + 4 files changed, 64 insertions(+), 35 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c ++++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +@@ -72,6 +72,12 @@ static const struct v4l2_fract + tpf_max = {.numerator = 1, .denominator = FPS_MIN}, + tpf_default = {.numerator = 1000, .denominator = 30000}; + ++/* Container for MMAL and VB2 buffers*/ ++struct vb2_mmal_buffer { ++ struct vb2_v4l2_buffer vb; ++ struct mmal_buffer mmal; ++}; ++ + /* video formats */ + static struct mmal_fmt formats[] = { + { +@@ -267,14 +273,15 @@ static int buffer_init(struct vb2_buffer + { + struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue); + struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb); +- struct mmal_buffer *buf = container_of(vb2, struct mmal_buffer, vb); ++ struct vb2_mmal_buffer *buf = ++ container_of(vb2, struct vb2_mmal_buffer, vb); + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p, vb %p\n", + __func__, dev, vb); +- buf->buffer = vb2_plane_vaddr(&buf->vb.vb2_buf, 0); +- buf->buffer_size = vb2_plane_size(&buf->vb.vb2_buf, 0); ++ buf->mmal.buffer = vb2_plane_vaddr(&buf->vb.vb2_buf, 0); ++ buf->mmal.buffer_size = vb2_plane_size(&buf->vb.vb2_buf, 0); + +- return mmal_vchi_buffer_init(dev->instance, buf); ++ return mmal_vchi_buffer_init(dev->instance, &buf->mmal); + } + + static int buffer_prepare(struct vb2_buffer *vb) +@@ -303,11 +310,13 @@ static void buffer_cleanup(struct vb2_bu + { + struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue); + struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb); +- struct mmal_buffer *buf = container_of(vb2, struct mmal_buffer, vb); ++ struct vb2_mmal_buffer *buf = ++ container_of(vb2, struct vb2_mmal_buffer, vb); + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p, vb %p\n", + __func__, dev, vb); +- mmal_vchi_buffer_cleanup(buf); ++ ++ mmal_vchi_buffer_cleanup(&buf->mmal); + } + + static inline bool is_capturing(struct bm2835_mmal_dev *dev) +@@ -319,14 +328,16 @@ static inline bool is_capturing(struct b + static void buffer_cb(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port, + int status, +- struct mmal_buffer *buf, +- unsigned long length, u32 mmal_flags, s64 dts, s64 pts) ++ struct mmal_buffer *mmal_buf) + { + struct bm2835_mmal_dev *dev = port->cb_ctx; ++ struct vb2_mmal_buffer *buf = ++ container_of(mmal_buf, struct vb2_mmal_buffer, mmal); + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "%s: status:%d, buf:%p, length:%lu, flags %u, pts %lld\n", +- __func__, status, buf, length, mmal_flags, pts); ++ __func__, status, buf, mmal_buf->length, mmal_buf->mmal_flags, ++ mmal_buf->pts); + + if (status != 0) { + /* error in transfer */ +@@ -337,7 +348,7 @@ static void buffer_cb(struct vchiq_mmal_ + return; + } + +- if (length == 0) { ++ if (mmal_buf->length == 0) { + /* stream ended */ + if (dev->capture.frame_count) { + /* empty buffer whilst capturing - expected to be an +@@ -353,7 +364,8 @@ static void buffer_cb(struct vchiq_mmal_ + &dev->capture.frame_count, + sizeof(dev->capture.frame_count)); + } +- if (vchiq_mmal_submit_buffer(instance, port, buf)) ++ if (vchiq_mmal_submit_buffer(instance, port, ++ &buf->mmal)) + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Failed to return EOS buffer"); + } else { +@@ -382,16 +394,16 @@ static void buffer_cb(struct vchiq_mmal_ + 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) { ++ } else if (mmal_buf->pts != 0) { + ktime_t timestamp; +- s64 runtime_us = pts - ++ s64 runtime_us = mmal_buf->pts - + dev->capture.vc_start_timestamp; + timestamp = ktime_add_us(dev->capture.kernel_start_ts, + runtime_us); + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Convert start time %llu and %llu with offset %llu to %llu\n", + ktime_to_ns(dev->capture.kernel_start_ts), +- dev->capture.vc_start_timestamp, pts, ++ dev->capture.vc_start_timestamp, mmal_buf->pts, + ktime_to_ns(timestamp)); + if (timestamp < dev->capture.last_timestamp) { + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, +@@ -416,15 +428,15 @@ static void buffer_cb(struct vchiq_mmal_ + dev->capture.last_timestamp = buf->vb.vb2_buf.timestamp; + buf->vb.sequence = dev->capture.sequence++; + +- vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length); +- if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) ++ vb2_set_plane_payload(&buf->vb.vb2_buf, 0, mmal_buf->length); ++ if (mmal_buf->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); + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + +- if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS && ++ if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS && + is_capturing(dev)) { + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Grab another frame as buffer has EOS"); +@@ -507,14 +519,16 @@ static void buffer_queue(struct vb2_buff + { + struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue); + struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb); +- struct mmal_buffer *buf = container_of(vb2, struct mmal_buffer, vb); ++ struct vb2_mmal_buffer *buf = ++ container_of(vb2, struct vb2_mmal_buffer, vb); + int ret; + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "%s: dev:%p buf:%p, idx %u\n", + __func__, dev, buf, vb2->vb2_buf.index); + +- ret = vchiq_mmal_submit_buffer(dev->instance, dev->capture.port, buf); ++ ret = vchiq_mmal_submit_buffer(dev->instance, dev->capture.port, ++ &buf->mmal); + if (ret < 0) + v4l2_err(&dev->v4l2_dev, "%s: error submitting buffer\n", + __func__); +@@ -628,7 +642,7 @@ static void stop_streaming(struct vb2_qu + dev->capture.frame_count = 0; + + /* ensure a format has actually been set */ +- if (!dev->capture.port) { ++ if (!port) { + v4l2_err(&dev->v4l2_dev, + "no capture port - stream not started?\n"); + return; +@@ -648,11 +662,11 @@ static void stop_streaming(struct vb2_qu + + /* disable the connection from camera to encoder */ + ret = vchiq_mmal_port_disable(dev->instance, dev->capture.camera_port); +- if (!ret && dev->capture.camera_port != dev->capture.port) { ++ if (!ret && dev->capture.camera_port != port) { + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "disabling port\n"); +- ret = vchiq_mmal_port_disable(dev->instance, dev->capture.port); +- } else if (dev->capture.camera_port != dev->capture.port) { ++ ret = vchiq_mmal_port_disable(dev->instance, port); ++ } else if (dev->capture.camera_port != port) { + v4l2_err(&dev->v4l2_dev, "port_disable failed, error %d\n", + ret); + } +@@ -1954,7 +1968,7 @@ static int bcm2835_mmal_probe(struct pla + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; + q->drv_priv = dev; +- q->buf_struct_size = sizeof(struct mmal_buffer); ++ q->buf_struct_size = sizeof(struct vb2_mmal_buffer); + q->ops = &bm2835_mmal_video_qops; + q->mem_ops = &vb2_vmalloc_memops; + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h +@@ -50,6 +50,11 @@ struct mmal_buffer { + unsigned long buffer_size; /* size of allocated buffer */ + + struct mmal_msg_context *msg_context; ++ ++ unsigned long length; ++ u32 mmal_flags; ++ s64 dts; ++ s64 pts; + }; + + /* */ +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +@@ -259,17 +259,25 @@ static void buffer_work_cb(struct work_s + { + struct mmal_msg_context *msg_context = + container_of(work, struct mmal_msg_context, u.bulk.work); ++ struct mmal_buffer *buffer = msg_context->u.bulk.buffer; ++ ++ if (!buffer) { ++ pr_err("%s: ctx: %p, No mmal buffer to pass details\n", ++ __func__, msg_context); ++ return; ++ } ++ ++ buffer->length = msg_context->u.bulk.buffer_used; ++ buffer->mmal_flags = msg_context->u.bulk.mmal_flags; ++ buffer->dts = msg_context->u.bulk.dts; ++ buffer->pts = msg_context->u.bulk.pts; + + atomic_dec(&msg_context->u.bulk.port->buffers_with_vpu); + + msg_context->u.bulk.port->buffer_cb(msg_context->u.bulk.instance, + msg_context->u.bulk.port, + msg_context->u.bulk.status, +- msg_context->u.bulk.buffer, +- msg_context->u.bulk.buffer_used, +- msg_context->u.bulk.mmal_flags, +- msg_context->u.bulk.dts, +- msg_context->u.bulk.pts); ++ msg_context->u.bulk.buffer); + } + + /* workqueue scheduled callback to handle receiving buffers +@@ -1327,11 +1335,14 @@ static int port_disable(struct vchiq_mma + mmalbuf = list_entry(buf_head, struct mmal_buffer, + list); + list_del(buf_head); +- if (port->buffer_cb) ++ if (port->buffer_cb) { ++ mmalbuf->length = 0; ++ mmalbuf->mmal_flags = 0; ++ mmalbuf->dts = MMAL_TIME_UNKNOWN; ++ mmalbuf->pts = MMAL_TIME_UNKNOWN; + port->buffer_cb(instance, +- port, 0, mmalbuf, 0, 0, +- MMAL_TIME_UNKNOWN, +- MMAL_TIME_UNKNOWN); ++ port, 0, mmalbuf); ++ } + } + + spin_unlock_irqrestore(&port->slock, flags); +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h +@@ -44,8 +44,7 @@ struct vchiq_mmal_port; + typedef void (*vchiq_mmal_buffer_cb)( + struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port, +- int status, struct mmal_buffer *buffer, +- unsigned long length, u32 mmal_flags, s64 dts, s64 pts); ++ int status, struct mmal_buffer *buffer); + + struct vchiq_mmal_port { + u32 enabled:1; diff --git a/target/linux/brcm2708/patches-4.19/950-0269-staging-mmal-vchiq-Add-support-for-event-callbacks.patch b/target/linux/brcm2708/patches-4.19/950-0269-staging-mmal-vchiq-Add-support-for-event-callbacks.patch new file mode 100644 index 0000000000..116ce4d0a8 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0269-staging-mmal-vchiq-Add-support-for-event-callbacks.patch @@ -0,0 +1,356 @@ +From 4b5f21b730dae52710a930a295c405044557e319 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 24 Sep 2018 18:15:38 +0100 +Subject: [PATCH 269/725] staging: mmal-vchiq: Add support for event callbacks. + +(Preparation for the codec driver). +The codec uses the event mechanism to report things such as +resolution changes. It is signalled by the cmd field of the buffer +being non-zero. + +Add support for passing this information out to the client. + +Signed-off-by: Dave Stevenson +--- + .../vc04_services/vchiq-mmal/mmal-common.h | 1 + + .../vc04_services/vchiq-mmal/mmal-msg.h | 35 ++++ + .../vc04_services/vchiq-mmal/mmal-vchiq.c | 170 ++++++++++++++++-- + .../vc04_services/vchiq-mmal/mmal-vchiq.h | 4 + + 4 files changed, 196 insertions(+), 14 deletions(-) + +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h +@@ -51,6 +51,7 @@ struct mmal_buffer { + + struct mmal_msg_context *msg_context; + ++ u32 cmd; /* MMAL command. 0=data. */ + unsigned long length; + u32 mmal_flags; + s64 dts; +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h +@@ -346,6 +346,41 @@ struct mmal_msg_port_parameter_get_reply + /* event messages */ + #define MMAL_WORKER_EVENT_SPACE 256 + ++/* Four CC's for events */ ++#define MMAL_FOURCC(a, b, c, d) ((a) | (b << 8) | (c << 16) | (d << 24)) ++ ++#define MMAL_EVENT_ERROR MMAL_FOURCC('E', 'R', 'R', 'O') ++#define MMAL_EVENT_EOS MMAL_FOURCC('E', 'E', 'O', 'S') ++#define MMAL_EVENT_FORMAT_CHANGED MMAL_FOURCC('E', 'F', 'C', 'H') ++#define MMAL_EVENT_PARAMETER_CHANGED MMAL_FOURCC('E', 'P', 'C', 'H') ++ ++/* Structs for each of the event message payloads */ ++struct mmal_msg_event_eos { ++ u32 port_type; /**< Type of port that received the end of stream */ ++ u32 port_index; /**< Index of port that received the end of stream */ ++}; ++ ++/** Format changed event data. */ ++struct mmal_msg_event_format_changed { ++ /* Minimum size of buffers the port requires */ ++ u32 buffer_size_min; ++ /* Minimum number of buffers the port requires */ ++ u32 buffer_num_min; ++ /* Size of buffers the port recommends for optimal performance. ++ * A value of zero means no special recommendation. ++ */ ++ u32 buffer_size_recommended; ++ /* Number of buffers the port recommends for optimal ++ * performance. A value of zero means no special recommendation. ++ */ ++ u32 buffer_num_recommended; ++ ++ u32 es_ptr; ++ struct mmal_es_format format; ++ union mmal_es_specific_format es; ++ u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; ++}; ++ + struct mmal_msg_event_to_host { + u32 client_component; /* component context */ + +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +@@ -151,6 +151,8 @@ struct mmal_msg_context { + /* Presentation and Decode timestamps */ + s64 pts; + s64 dts; ++ /* MMAL buffer command flag */ ++ u32 cmd; + + int status; /* context status */ + +@@ -238,18 +240,6 @@ release_msg_context(struct mmal_msg_cont + kfree(msg_context); + } + +-/* deals with receipt of event to host message */ +-static void event_to_host_cb(struct vchiq_mmal_instance *instance, +- struct mmal_msg *msg, u32 msg_len) +-{ +- pr_debug("unhandled event\n"); +- pr_debug("component:%u port type:%d num:%d cmd:0x%x length:%d\n", +- msg->u.event_to_host.client_component, +- msg->u.event_to_host.port_type, +- msg->u.event_to_host.port_num, +- msg->u.event_to_host.cmd, msg->u.event_to_host.length); +-} +- + /* workqueue scheduled callback + * + * we do this because it is important we do not call any other vchiq +@@ -271,13 +261,18 @@ static void buffer_work_cb(struct work_s + buffer->mmal_flags = msg_context->u.bulk.mmal_flags; + buffer->dts = msg_context->u.bulk.dts; + buffer->pts = msg_context->u.bulk.pts; ++ buffer->cmd = msg_context->u.bulk.cmd; + +- atomic_dec(&msg_context->u.bulk.port->buffers_with_vpu); ++ if (!buffer->cmd) ++ atomic_dec(&msg_context->u.bulk.port->buffers_with_vpu); + + msg_context->u.bulk.port->buffer_cb(msg_context->u.bulk.instance, + msg_context->u.bulk.port, + msg_context->u.bulk.status, + msg_context->u.bulk.buffer); ++ ++ if (buffer->cmd) ++ mutex_unlock(&msg_context->u.bulk.port->event_context_mutex); + } + + /* workqueue scheduled callback to handle receiving buffers +@@ -356,6 +351,7 @@ static int bulk_receive(struct vchiq_mma + msg_context->u.bulk.buffer_used = rd_len; + msg_context->u.bulk.dts = msg->u.buffer_from_host.buffer_header.dts; + msg_context->u.bulk.pts = msg->u.buffer_from_host.buffer_header.pts; ++ msg_context->u.bulk.cmd = msg->u.buffer_from_host.buffer_header.cmd; + + queue_work(msg_context->instance->bulk_wq, + &msg_context->u.bulk.buffer_to_host_work); +@@ -457,6 +453,103 @@ buffer_from_host(struct vchiq_mmal_insta + return ret; + } + ++/* deals with receipt of event to host message */ ++static void event_to_host_cb(struct vchiq_mmal_instance *instance, ++ struct mmal_msg *msg, u32 msg_len) ++{ ++ /* FIXME: Not going to work on 64 bit */ ++ struct vchiq_mmal_component *component = ++ (struct vchiq_mmal_component *)msg->u.event_to_host.client_component; ++ struct vchiq_mmal_port *port = NULL; ++ struct mmal_msg_context *msg_context; ++ u32 port_num = msg->u.event_to_host.port_num; ++ ++ if (msg->u.buffer_from_host.drvbuf.magic == MMAL_MAGIC) { ++ pr_err("%s: MMAL_MSG_TYPE_BUFFER_TO_HOST with bad magic\n", ++ __func__); ++ return; ++ } ++ ++ switch (msg->u.event_to_host.port_type) { ++ case MMAL_PORT_TYPE_CONTROL: ++ if (port_num) { ++ pr_err("%s: port_num of %u >= number of ports 1", ++ __func__, port_num); ++ return; ++ } ++ port = &component->control; ++ break; ++ case MMAL_PORT_TYPE_INPUT: ++ if (port_num >= component->inputs) { ++ pr_err("%s: port_num of %u >= number of ports %u", ++ __func__, port_num, ++ port_num >= component->inputs); ++ return; ++ } ++ port = &component->input[port_num]; ++ break; ++ case MMAL_PORT_TYPE_OUTPUT: ++ if (port_num >= component->outputs) { ++ pr_err("%s: port_num of %u >= number of ports %u", ++ __func__, port_num, ++ port_num >= component->outputs); ++ return; ++ } ++ port = &component->output[port_num]; ++ break; ++ case MMAL_PORT_TYPE_CLOCK: ++ if (port_num >= component->clocks) { ++ pr_err("%s: port_num of %u >= number of ports %u", ++ __func__, port_num, ++ port_num >= component->clocks); ++ return; ++ } ++ port = &component->clock[port_num]; ++ break; ++ default: ++ break; ++ } ++ ++ if (!mutex_trylock(&port->event_context_mutex)) { ++ pr_err("dropping event 0x%x\n", msg->u.event_to_host.cmd); ++ return; ++ } ++ msg_context = port->event_context; ++ ++ if (msg->h.status != MMAL_MSG_STATUS_SUCCESS) { ++ /* message reception had an error */ ++ //pr_warn ++ pr_err("%s: error %d in reply\n", __func__, msg->h.status); ++ ++ msg_context->u.bulk.status = msg->h.status; ++ } else if (msg->u.event_to_host.length > MMAL_WORKER_EVENT_SPACE) { ++ /* data is not in message, queue a bulk receive */ ++ pr_err("%s: payload not in message - bulk receive??! NOT SUPPORTED\n", ++ __func__); ++ msg_context->u.bulk.status = -1; ++ } else { ++ memcpy(msg_context->u.bulk.buffer->buffer, ++ msg->u.event_to_host.data, ++ msg->u.event_to_host.length); ++ ++ msg_context->u.bulk.buffer_used = ++ msg->u.event_to_host.length; ++ ++ msg_context->u.bulk.mmal_flags = 0; ++ msg_context->u.bulk.dts = MMAL_TIME_UNKNOWN; ++ msg_context->u.bulk.pts = MMAL_TIME_UNKNOWN; ++ msg_context->u.bulk.cmd = msg->u.event_to_host.cmd; ++ ++ pr_debug("event component:%u port type:%d num:%d cmd:0x%x length:%d\n", ++ msg->u.event_to_host.client_component, ++ msg->u.event_to_host.port_type, ++ msg->u.event_to_host.port_num, ++ msg->u.event_to_host.cmd, msg->u.event_to_host.length); ++ } ++ ++ schedule_work(&msg_context->u.bulk.work); ++} ++ + /* deals with receipt of buffer to host message */ + static void buffer_to_host_cb(struct vchiq_mmal_instance *instance, + struct mmal_msg *msg, u32 msg_len) +@@ -1340,6 +1433,7 @@ static int port_disable(struct vchiq_mma + mmalbuf->mmal_flags = 0; + mmalbuf->dts = MMAL_TIME_UNKNOWN; + mmalbuf->pts = MMAL_TIME_UNKNOWN; ++ mmalbuf->cmd = 0; + port->buffer_cb(instance, + port, 0, mmalbuf); + } +@@ -1641,6 +1735,43 @@ int mmal_vchi_buffer_cleanup(struct mmal + } + EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup); + ++static void init_event_context(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port) ++{ ++ struct mmal_msg_context *ctx = get_msg_context(instance); ++ ++ mutex_init(&port->event_context_mutex); ++ ++ port->event_context = ctx; ++ ctx->u.bulk.instance = instance; ++ ctx->u.bulk.port = port; ++ ctx->u.bulk.buffer = ++ kzalloc(sizeof(*ctx->u.bulk.buffer), GFP_KERNEL); ++ if (!ctx->u.bulk.buffer) ++ goto release_msg_context; ++ ctx->u.bulk.buffer->buffer = kzalloc(MMAL_WORKER_EVENT_SPACE, ++ GFP_KERNEL); ++ if (!ctx->u.bulk.buffer->buffer) ++ goto release_buffer; ++ ++ INIT_WORK(&ctx->u.bulk.work, buffer_work_cb); ++ return; ++ ++release_buffer: ++ kfree(ctx->u.bulk.buffer); ++release_msg_context: ++ release_msg_context(ctx); ++} ++ ++static void free_event_context(struct vchiq_mmal_port *port) ++{ ++ struct mmal_msg_context *ctx = port->event_context; ++ ++ kfree(ctx->u.bulk.buffer->buffer); ++ kfree(ctx->u.bulk.buffer); ++ release_msg_context(ctx); ++} ++ + /* Initialise a mmal component and its ports + * + */ +@@ -1684,6 +1815,7 @@ int vchiq_mmal_component_init(struct vch + ret = port_info_get(instance, &component->control); + if (ret < 0) + goto release_component; ++ init_event_context(instance, &component->control); + + for (idx = 0; idx < component->inputs; idx++) { + component->input[idx].type = MMAL_PORT_TYPE_INPUT; +@@ -1694,6 +1826,7 @@ int vchiq_mmal_component_init(struct vch + ret = port_info_get(instance, &component->input[idx]); + if (ret < 0) + goto release_component; ++ init_event_context(instance, &component->input[idx]); + } + + for (idx = 0; idx < component->outputs; idx++) { +@@ -1705,6 +1838,7 @@ int vchiq_mmal_component_init(struct vch + ret = port_info_get(instance, &component->output[idx]); + if (ret < 0) + goto release_component; ++ init_event_context(instance, &component->output[idx]); + } + + for (idx = 0; idx < component->clocks; idx++) { +@@ -1716,6 +1850,7 @@ int vchiq_mmal_component_init(struct vch + ret = port_info_get(instance, &component->clock[idx]); + if (ret < 0) + goto release_component; ++ init_event_context(instance, &component->clock[idx]); + } + + *component_out = component; +@@ -1741,7 +1876,7 @@ EXPORT_SYMBOL_GPL(vchiq_mmal_component_i + int vchiq_mmal_component_finalise(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_component *component) + { +- int ret; ++ int ret, idx; + + if (mutex_lock_interruptible(&instance->vchiq_mutex)) + return -EINTR; +@@ -1753,6 +1888,13 @@ int vchiq_mmal_component_finalise(struct + + component->in_use = 0; + ++ for (idx = 0; idx < component->inputs; idx++) ++ free_event_context(&component->input[idx]); ++ for (idx = 0; idx < component->outputs; idx++) ++ free_event_context(&component->output[idx]); ++ for (idx = 0; idx < component->clocks; idx++) ++ free_event_context(&component->clock[idx]); ++ + mutex_unlock(&instance->vchiq_mutex); + + return ret; +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h +@@ -78,6 +78,10 @@ struct vchiq_mmal_port { + vchiq_mmal_buffer_cb buffer_cb; + /* callback context */ + void *cb_ctx; ++ ++ /* ensure serialised use of the one event context structure */ ++ struct mutex event_context_mutex; ++ struct mmal_msg_context *event_context; + }; + + struct vchiq_mmal_component { diff --git a/target/linux/brcm2708/patches-4.19/950-0269-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch b/target/linux/brcm2708/patches-4.19/950-0269-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch deleted file mode 100644 index 48cc89eec9..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0269-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 504d899794febbec7f371a2ef3d1b18e991d18e5 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 29 Oct 2018 16:20:46 +0000 -Subject: [PATCH 269/703] staging: mmal-vchiq: Avoid use of bool in structures - -Fixes up a checkpatch error "Avoid using bool structure members -because of possible alignment issues". - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 14 +++++++------- - .../staging/vc04_services/vchiq-mmal/mmal-vchiq.h | 4 ++-- - 2 files changed, 9 insertions(+), 9 deletions(-) - ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -861,9 +861,9 @@ static int port_info_get(struct vchiq_mm - goto release_msg; - - if (rmsg->u.port_info_get_reply.port.is_enabled == 0) -- port->enabled = false; -+ port->enabled = 0; - else -- port->enabled = true; -+ port->enabled = 1; - - /* copy the values out of the message */ - port->handle = rmsg->u.port_info_get_reply.port_handle; -@@ -1300,7 +1300,7 @@ static int port_disable(struct vchiq_mma - if (!port->enabled) - return 0; - -- port->enabled = false; -+ port->enabled = 0; - - ret = port_action_port(instance, port, - MMAL_MSG_PORT_ACTION_TYPE_DISABLE); -@@ -1352,7 +1352,7 @@ static int port_enable(struct vchiq_mmal - if (ret) - goto done; - -- port->enabled = true; -+ port->enabled = 1; - - if (port->buffer_cb) { - /* send buffer headers to videocore */ -@@ -1524,7 +1524,7 @@ int vchiq_mmal_port_connect_tunnel(struc - pr_err("failed disconnecting src port\n"); - goto release_unlock; - } -- src->connected->enabled = false; -+ src->connected->enabled = 0; - src->connected = NULL; - } - -@@ -1760,7 +1760,7 @@ int vchiq_mmal_component_enable(struct v - - ret = enable_component(instance, component); - if (ret == 0) -- component->enabled = true; -+ component->enabled = 1; - - mutex_unlock(&instance->vchiq_mutex); - -@@ -1786,7 +1786,7 @@ int vchiq_mmal_component_disable(struct - - ret = disable_component(instance, component); - if (ret == 0) -- component->enabled = false; -+ component->enabled = 0; - - mutex_unlock(&instance->vchiq_mutex); - ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h -@@ -48,7 +48,7 @@ typedef void (*vchiq_mmal_buffer_cb)( - unsigned long length, u32 mmal_flags, s64 dts, s64 pts); - - struct vchiq_mmal_port { -- bool enabled; -+ u32 enabled:1; - u32 handle; - u32 type; /* port type, cached to use on port info set */ - u32 index; /* port index, cached to use on port info set */ -@@ -83,7 +83,7 @@ struct vchiq_mmal_port { - - struct vchiq_mmal_component { - u32 in_use:1; -- bool enabled; -+ u32 enabled:1; - u32 handle; /* VideoCore handle for component */ - u32 inputs; /* Number of input ports */ - u32 outputs; /* Number of output ports */ diff --git a/target/linux/brcm2708/patches-4.19/950-0270-staging-mmal-vchiq-Make-timeout-a-defined-parameter.patch b/target/linux/brcm2708/patches-4.19/950-0270-staging-mmal-vchiq-Make-timeout-a-defined-parameter.patch deleted file mode 100644 index bcccde74de..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0270-staging-mmal-vchiq-Make-timeout-a-defined-parameter.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 11937ca9b223ffa394f04940b245b3689172537f Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 24 Sep 2018 16:57:09 +0100 -Subject: [PATCH 270/703] staging: mmal-vchiq: Make timeout a defined parameter - -The timeout period for VPU communications is a useful thing -to extend when debugging. -Set it via a define, rather than a magic number buried in the code. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -44,6 +44,12 @@ MODULE_VERSION("0.0.1"); - */ - #define VCHIQ_MMAL_MAX_COMPONENTS 64 - -+/* -+ * Timeout for synchronous msg responses in seconds. -+ * Helpful to increase this if stopping in the VPU debugger. -+ */ -+#define SYNC_MSG_TIMEOUT 3 -+ - /*#define FULL_MSG_DUMP 1*/ - - #ifdef DEBUG -@@ -692,7 +698,7 @@ static int send_synchronous_mmal_msg(str - } - - timeout = wait_for_completion_timeout(&msg_context->u.sync.cmplt, -- 3 * HZ); -+ SYNC_MSG_TIMEOUT * HZ); - if (timeout == 0) { - pr_err("timed out waiting for sync completion\n"); - ret = -ETIME; diff --git a/target/linux/brcm2708/patches-4.19/950-0270-staging-vc04_services-Support-sending-data-to-MMAL-p.patch b/target/linux/brcm2708/patches-4.19/950-0270-staging-vc04_services-Support-sending-data-to-MMAL-p.patch new file mode 100644 index 0000000000..c1e5dd3792 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0270-staging-vc04_services-Support-sending-data-to-MMAL-p.patch @@ -0,0 +1,42 @@ +From c117bd7886d4d4079f33fb27b07ddd9add7310ee Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 24 Sep 2018 18:26:02 +0100 +Subject: [PATCH 270/725] staging: vc04_services: Support sending data to MMAL + ports + +Add the ability to send data to ports. This only supports +zero copy mode as the required bulk transfer setup calls +are not done. + +Signed-off-by: Dave Stevenson +--- + .../vc04_services/vchiq-mmal/mmal-vchiq.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +@@ -428,11 +428,19 @@ buffer_from_host(struct vchiq_mmal_insta + m.u.buffer_from_host.buffer_header.data = + (u32)(unsigned long)buf->buffer; + m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size; +- m.u.buffer_from_host.buffer_header.length = 0; /* nothing used yet */ +- m.u.buffer_from_host.buffer_header.offset = 0; /* no offset */ +- m.u.buffer_from_host.buffer_header.flags = 0; /* no flags */ +- m.u.buffer_from_host.buffer_header.pts = MMAL_TIME_UNKNOWN; +- m.u.buffer_from_host.buffer_header.dts = MMAL_TIME_UNKNOWN; ++ if (port->type == MMAL_PORT_TYPE_OUTPUT) { ++ m.u.buffer_from_host.buffer_header.length = 0; ++ m.u.buffer_from_host.buffer_header.offset = 0; ++ m.u.buffer_from_host.buffer_header.flags = 0; ++ m.u.buffer_from_host.buffer_header.pts = MMAL_TIME_UNKNOWN; ++ m.u.buffer_from_host.buffer_header.dts = MMAL_TIME_UNKNOWN; ++ } else { ++ m.u.buffer_from_host.buffer_header.length = buf->length; ++ m.u.buffer_from_host.buffer_header.offset = 0; ++ m.u.buffer_from_host.buffer_header.flags = buf->mmal_flags; ++ m.u.buffer_from_host.buffer_header.pts = buf->pts; ++ m.u.buffer_from_host.buffer_header.dts = buf->dts; ++ } + + /* clear buffer type sepecific data */ + memset(&m.u.buffer_from_host.buffer_header_type_specific, 0, diff --git a/target/linux/brcm2708/patches-4.19/950-0271-staging-mmal-vchiq-Make-a-mmal_buf-struct-for-passin.patch b/target/linux/brcm2708/patches-4.19/950-0271-staging-mmal-vchiq-Make-a-mmal_buf-struct-for-passin.patch deleted file mode 100644 index d32aa85445..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0271-staging-mmal-vchiq-Make-a-mmal_buf-struct-for-passin.patch +++ /dev/null @@ -1,280 +0,0 @@ -From 32d3fb2930b7e6f47959f0765c13f7cfda2baa7e Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 24 Sep 2018 17:33:37 +0100 -Subject: [PATCH 271/703] staging: mmal-vchiq: Make a mmal_buf struct for - passing parameters - -The callback from vchi_mmal to the client was growing lots of extra -parameters. Consolidate them into a single struct instead of -growing the list further. -The struct is associated with the client buffer, therefore there -are various changes to setup various containers for the struct, -and pass the appropriate members. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-camera/bcm2835-camera.c | 62 ++++++++++++------- - .../vc04_services/vchiq-mmal/mmal-common.h | 5 ++ - .../vc04_services/vchiq-mmal/mmal-vchiq.c | 29 ++++++--- - .../vc04_services/vchiq-mmal/mmal-vchiq.h | 3 +- - 4 files changed, 64 insertions(+), 35 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c -+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c -@@ -72,6 +72,12 @@ static const struct v4l2_fract - tpf_max = {.numerator = 1, .denominator = FPS_MIN}, - tpf_default = {.numerator = 1000, .denominator = 30000}; - -+/* Container for MMAL and VB2 buffers*/ -+struct vb2_mmal_buffer { -+ struct vb2_v4l2_buffer vb; -+ struct mmal_buffer mmal; -+}; -+ - /* video formats */ - static struct mmal_fmt formats[] = { - { -@@ -267,14 +273,15 @@ static int buffer_init(struct vb2_buffer - { - struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue); - struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb); -- struct mmal_buffer *buf = container_of(vb2, struct mmal_buffer, vb); -+ struct vb2_mmal_buffer *buf = -+ container_of(vb2, struct vb2_mmal_buffer, vb); - - v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p, vb %p\n", - __func__, dev, vb); -- buf->buffer = vb2_plane_vaddr(&buf->vb.vb2_buf, 0); -- buf->buffer_size = vb2_plane_size(&buf->vb.vb2_buf, 0); -+ buf->mmal.buffer = vb2_plane_vaddr(&buf->vb.vb2_buf, 0); -+ buf->mmal.buffer_size = vb2_plane_size(&buf->vb.vb2_buf, 0); - -- return mmal_vchi_buffer_init(dev->instance, buf); -+ return mmal_vchi_buffer_init(dev->instance, &buf->mmal); - } - - static int buffer_prepare(struct vb2_buffer *vb) -@@ -303,11 +310,13 @@ static void buffer_cleanup(struct vb2_bu - { - struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue); - struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb); -- struct mmal_buffer *buf = container_of(vb2, struct mmal_buffer, vb); -+ struct vb2_mmal_buffer *buf = -+ container_of(vb2, struct vb2_mmal_buffer, vb); - - v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p, vb %p\n", - __func__, dev, vb); -- mmal_vchi_buffer_cleanup(buf); -+ -+ mmal_vchi_buffer_cleanup(&buf->mmal); - } - - static inline bool is_capturing(struct bm2835_mmal_dev *dev) -@@ -319,14 +328,16 @@ static inline bool is_capturing(struct b - static void buffer_cb(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port, - int status, -- struct mmal_buffer *buf, -- unsigned long length, u32 mmal_flags, s64 dts, s64 pts) -+ struct mmal_buffer *mmal_buf) - { - struct bm2835_mmal_dev *dev = port->cb_ctx; -+ struct vb2_mmal_buffer *buf = -+ container_of(mmal_buf, struct vb2_mmal_buffer, mmal); - - v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, - "%s: status:%d, buf:%p, length:%lu, flags %u, pts %lld\n", -- __func__, status, buf, length, mmal_flags, pts); -+ __func__, status, buf, mmal_buf->length, mmal_buf->mmal_flags, -+ mmal_buf->pts); - - if (status != 0) { - /* error in transfer */ -@@ -337,7 +348,7 @@ static void buffer_cb(struct vchiq_mmal_ - return; - } - -- if (length == 0) { -+ if (mmal_buf->length == 0) { - /* stream ended */ - if (dev->capture.frame_count) { - /* empty buffer whilst capturing - expected to be an -@@ -353,7 +364,8 @@ static void buffer_cb(struct vchiq_mmal_ - &dev->capture.frame_count, - sizeof(dev->capture.frame_count)); - } -- if (vchiq_mmal_submit_buffer(instance, port, buf)) -+ if (vchiq_mmal_submit_buffer(instance, port, -+ &buf->mmal)) - v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, - "Failed to return EOS buffer"); - } else { -@@ -382,16 +394,16 @@ static void buffer_cb(struct vchiq_mmal_ - 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) { -+ } else if (mmal_buf->pts != 0) { - ktime_t timestamp; -- s64 runtime_us = pts - -+ s64 runtime_us = mmal_buf->pts - - dev->capture.vc_start_timestamp; - timestamp = ktime_add_us(dev->capture.kernel_start_ts, - runtime_us); - v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, - "Convert start time %llu and %llu with offset %llu to %llu\n", - ktime_to_ns(dev->capture.kernel_start_ts), -- dev->capture.vc_start_timestamp, pts, -+ dev->capture.vc_start_timestamp, mmal_buf->pts, - ktime_to_ns(timestamp)); - if (timestamp < dev->capture.last_timestamp) { - v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, -@@ -416,15 +428,15 @@ static void buffer_cb(struct vchiq_mmal_ - dev->capture.last_timestamp = buf->vb.vb2_buf.timestamp; - buf->vb.sequence = dev->capture.sequence++; - -- vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length); -- if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) -+ vb2_set_plane_payload(&buf->vb.vb2_buf, 0, mmal_buf->length); -+ if (mmal_buf->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); - vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); - -- if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS && -+ if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS && - is_capturing(dev)) { - v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, - "Grab another frame as buffer has EOS"); -@@ -507,14 +519,16 @@ static void buffer_queue(struct vb2_buff - { - struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue); - struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb); -- struct mmal_buffer *buf = container_of(vb2, struct mmal_buffer, vb); -+ struct vb2_mmal_buffer *buf = -+ container_of(vb2, struct vb2_mmal_buffer, vb); - int ret; - - v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, - "%s: dev:%p buf:%p, idx %u\n", - __func__, dev, buf, vb2->vb2_buf.index); - -- ret = vchiq_mmal_submit_buffer(dev->instance, dev->capture.port, buf); -+ ret = vchiq_mmal_submit_buffer(dev->instance, dev->capture.port, -+ &buf->mmal); - if (ret < 0) - v4l2_err(&dev->v4l2_dev, "%s: error submitting buffer\n", - __func__); -@@ -628,7 +642,7 @@ static void stop_streaming(struct vb2_qu - dev->capture.frame_count = 0; - - /* ensure a format has actually been set */ -- if (!dev->capture.port) { -+ if (!port) { - v4l2_err(&dev->v4l2_dev, - "no capture port - stream not started?\n"); - return; -@@ -648,11 +662,11 @@ static void stop_streaming(struct vb2_qu - - /* disable the connection from camera to encoder */ - ret = vchiq_mmal_port_disable(dev->instance, dev->capture.camera_port); -- if (!ret && dev->capture.camera_port != dev->capture.port) { -+ if (!ret && dev->capture.camera_port != port) { - v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, - "disabling port\n"); -- ret = vchiq_mmal_port_disable(dev->instance, dev->capture.port); -- } else if (dev->capture.camera_port != dev->capture.port) { -+ ret = vchiq_mmal_port_disable(dev->instance, port); -+ } else if (dev->capture.camera_port != port) { - v4l2_err(&dev->v4l2_dev, "port_disable failed, error %d\n", - ret); - } -@@ -1954,7 +1968,7 @@ static int bcm2835_mmal_probe(struct pla - q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; - q->drv_priv = dev; -- q->buf_struct_size = sizeof(struct mmal_buffer); -+ q->buf_struct_size = sizeof(struct vb2_mmal_buffer); - q->ops = &bm2835_mmal_video_qops; - q->mem_ops = &vb2_vmalloc_memops; - q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h -@@ -50,6 +50,11 @@ struct mmal_buffer { - unsigned long buffer_size; /* size of allocated buffer */ - - struct mmal_msg_context *msg_context; -+ -+ unsigned long length; -+ u32 mmal_flags; -+ s64 dts; -+ s64 pts; - }; - - /* */ ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -259,17 +259,25 @@ static void buffer_work_cb(struct work_s - { - struct mmal_msg_context *msg_context = - container_of(work, struct mmal_msg_context, u.bulk.work); -+ struct mmal_buffer *buffer = msg_context->u.bulk.buffer; -+ -+ if (!buffer) { -+ pr_err("%s: ctx: %p, No mmal buffer to pass details\n", -+ __func__, msg_context); -+ return; -+ } -+ -+ buffer->length = msg_context->u.bulk.buffer_used; -+ buffer->mmal_flags = msg_context->u.bulk.mmal_flags; -+ buffer->dts = msg_context->u.bulk.dts; -+ buffer->pts = msg_context->u.bulk.pts; - - atomic_dec(&msg_context->u.bulk.port->buffers_with_vpu); - - msg_context->u.bulk.port->buffer_cb(msg_context->u.bulk.instance, - msg_context->u.bulk.port, - msg_context->u.bulk.status, -- msg_context->u.bulk.buffer, -- msg_context->u.bulk.buffer_used, -- msg_context->u.bulk.mmal_flags, -- msg_context->u.bulk.dts, -- msg_context->u.bulk.pts); -+ msg_context->u.bulk.buffer); - } - - /* workqueue scheduled callback to handle receiving buffers -@@ -1327,11 +1335,14 @@ static int port_disable(struct vchiq_mma - mmalbuf = list_entry(buf_head, struct mmal_buffer, - list); - list_del(buf_head); -- if (port->buffer_cb) -+ if (port->buffer_cb) { -+ mmalbuf->length = 0; -+ mmalbuf->mmal_flags = 0; -+ mmalbuf->dts = MMAL_TIME_UNKNOWN; -+ mmalbuf->pts = MMAL_TIME_UNKNOWN; - port->buffer_cb(instance, -- port, 0, mmalbuf, 0, 0, -- MMAL_TIME_UNKNOWN, -- MMAL_TIME_UNKNOWN); -+ port, 0, mmalbuf); -+ } - } - - spin_unlock_irqrestore(&port->slock, flags); ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h -@@ -44,8 +44,7 @@ struct vchiq_mmal_port; - typedef void (*vchiq_mmal_buffer_cb)( - struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port, -- int status, struct mmal_buffer *buffer, -- unsigned long length, u32 mmal_flags, s64 dts, s64 pts); -+ int status, struct mmal_buffer *buffer); - - struct vchiq_mmal_port { - u32 enabled:1; diff --git a/target/linux/brcm2708/patches-4.19/950-0271-staging-vc04_services-Fixup-vchiq-mmal-include-order.patch b/target/linux/brcm2708/patches-4.19/950-0271-staging-vc04_services-Fixup-vchiq-mmal-include-order.patch new file mode 100644 index 0000000000..b1cfe54ba6 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0271-staging-vc04_services-Fixup-vchiq-mmal-include-order.patch @@ -0,0 +1,36 @@ +From e28f85053dc8de18935993bee4c9e5d9483787bd Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 25 Sep 2018 16:57:40 +0100 +Subject: [PATCH 271/725] staging: vc04_services: Fixup vchiq-mmal include + ordering + +There were dependencies on including the headers in the correct +order. Fix up the headers so that they include the other +headers that they depend on themselves. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h | 1 + + drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h | 1 + + 2 files changed, 2 insertions(+) + +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h +@@ -38,6 +38,7 @@ + #include "mmal-msg-common.h" + #include "mmal-msg-format.h" + #include "mmal-msg-port.h" ++#include "mmal-vchiq.h" + + enum mmal_msg_type { + MMAL_MSG_TYPE_QUIT = 1, +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h +@@ -16,6 +16,7 @@ + #ifndef MMAL_VCHIQ_H + #define MMAL_VCHIQ_H + ++#include "mmal-common.h" + #include "mmal-msg-format.h" + + #define MAX_PORT_COUNT 4 diff --git a/target/linux/brcm2708/patches-4.19/950-0272-staging-mmal-vchiq-Add-support-for-event-callbacks.patch b/target/linux/brcm2708/patches-4.19/950-0272-staging-mmal-vchiq-Add-support-for-event-callbacks.patch deleted file mode 100644 index 34006c5377..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0272-staging-mmal-vchiq-Add-support-for-event-callbacks.patch +++ /dev/null @@ -1,356 +0,0 @@ -From 903a6c2047aef7eba69ca04e6e3488ba3de0d9f9 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 24 Sep 2018 18:15:38 +0100 -Subject: [PATCH 272/703] staging: mmal-vchiq: Add support for event callbacks. - -(Preparation for the codec driver). -The codec uses the event mechanism to report things such as -resolution changes. It is signalled by the cmd field of the buffer -being non-zero. - -Add support for passing this information out to the client. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/vchiq-mmal/mmal-common.h | 1 + - .../vc04_services/vchiq-mmal/mmal-msg.h | 35 ++++ - .../vc04_services/vchiq-mmal/mmal-vchiq.c | 170 ++++++++++++++++-- - .../vc04_services/vchiq-mmal/mmal-vchiq.h | 4 + - 4 files changed, 196 insertions(+), 14 deletions(-) - ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h -@@ -51,6 +51,7 @@ struct mmal_buffer { - - struct mmal_msg_context *msg_context; - -+ u32 cmd; /* MMAL command. 0=data. */ - unsigned long length; - u32 mmal_flags; - s64 dts; ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h -@@ -346,6 +346,41 @@ struct mmal_msg_port_parameter_get_reply - /* event messages */ - #define MMAL_WORKER_EVENT_SPACE 256 - -+/* Four CC's for events */ -+#define MMAL_FOURCC(a, b, c, d) ((a) | (b << 8) | (c << 16) | (d << 24)) -+ -+#define MMAL_EVENT_ERROR MMAL_FOURCC('E', 'R', 'R', 'O') -+#define MMAL_EVENT_EOS MMAL_FOURCC('E', 'E', 'O', 'S') -+#define MMAL_EVENT_FORMAT_CHANGED MMAL_FOURCC('E', 'F', 'C', 'H') -+#define MMAL_EVENT_PARAMETER_CHANGED MMAL_FOURCC('E', 'P', 'C', 'H') -+ -+/* Structs for each of the event message payloads */ -+struct mmal_msg_event_eos { -+ u32 port_type; /**< Type of port that received the end of stream */ -+ u32 port_index; /**< Index of port that received the end of stream */ -+}; -+ -+/** Format changed event data. */ -+struct mmal_msg_event_format_changed { -+ /* Minimum size of buffers the port requires */ -+ u32 buffer_size_min; -+ /* Minimum number of buffers the port requires */ -+ u32 buffer_num_min; -+ /* Size of buffers the port recommends for optimal performance. -+ * A value of zero means no special recommendation. -+ */ -+ u32 buffer_size_recommended; -+ /* Number of buffers the port recommends for optimal -+ * performance. A value of zero means no special recommendation. -+ */ -+ u32 buffer_num_recommended; -+ -+ u32 es_ptr; -+ struct mmal_es_format format; -+ union mmal_es_specific_format es; -+ u8 extradata[MMAL_FORMAT_EXTRADATA_MAX_SIZE]; -+}; -+ - struct mmal_msg_event_to_host { - u32 client_component; /* component context */ - ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -151,6 +151,8 @@ struct mmal_msg_context { - /* Presentation and Decode timestamps */ - s64 pts; - s64 dts; -+ /* MMAL buffer command flag */ -+ u32 cmd; - - int status; /* context status */ - -@@ -238,18 +240,6 @@ release_msg_context(struct mmal_msg_cont - kfree(msg_context); - } - --/* deals with receipt of event to host message */ --static void event_to_host_cb(struct vchiq_mmal_instance *instance, -- struct mmal_msg *msg, u32 msg_len) --{ -- pr_debug("unhandled event\n"); -- pr_debug("component:%u port type:%d num:%d cmd:0x%x length:%d\n", -- msg->u.event_to_host.client_component, -- msg->u.event_to_host.port_type, -- msg->u.event_to_host.port_num, -- msg->u.event_to_host.cmd, msg->u.event_to_host.length); --} -- - /* workqueue scheduled callback - * - * we do this because it is important we do not call any other vchiq -@@ -271,13 +261,18 @@ static void buffer_work_cb(struct work_s - buffer->mmal_flags = msg_context->u.bulk.mmal_flags; - buffer->dts = msg_context->u.bulk.dts; - buffer->pts = msg_context->u.bulk.pts; -+ buffer->cmd = msg_context->u.bulk.cmd; - -- atomic_dec(&msg_context->u.bulk.port->buffers_with_vpu); -+ if (!buffer->cmd) -+ atomic_dec(&msg_context->u.bulk.port->buffers_with_vpu); - - msg_context->u.bulk.port->buffer_cb(msg_context->u.bulk.instance, - msg_context->u.bulk.port, - msg_context->u.bulk.status, - msg_context->u.bulk.buffer); -+ -+ if (buffer->cmd) -+ mutex_unlock(&msg_context->u.bulk.port->event_context_mutex); - } - - /* workqueue scheduled callback to handle receiving buffers -@@ -356,6 +351,7 @@ static int bulk_receive(struct vchiq_mma - msg_context->u.bulk.buffer_used = rd_len; - msg_context->u.bulk.dts = msg->u.buffer_from_host.buffer_header.dts; - msg_context->u.bulk.pts = msg->u.buffer_from_host.buffer_header.pts; -+ msg_context->u.bulk.cmd = msg->u.buffer_from_host.buffer_header.cmd; - - queue_work(msg_context->instance->bulk_wq, - &msg_context->u.bulk.buffer_to_host_work); -@@ -457,6 +453,103 @@ buffer_from_host(struct vchiq_mmal_insta - return ret; - } - -+/* deals with receipt of event to host message */ -+static void event_to_host_cb(struct vchiq_mmal_instance *instance, -+ struct mmal_msg *msg, u32 msg_len) -+{ -+ /* FIXME: Not going to work on 64 bit */ -+ struct vchiq_mmal_component *component = -+ (struct vchiq_mmal_component *)msg->u.event_to_host.client_component; -+ struct vchiq_mmal_port *port = NULL; -+ struct mmal_msg_context *msg_context; -+ u32 port_num = msg->u.event_to_host.port_num; -+ -+ if (msg->u.buffer_from_host.drvbuf.magic == MMAL_MAGIC) { -+ pr_err("%s: MMAL_MSG_TYPE_BUFFER_TO_HOST with bad magic\n", -+ __func__); -+ return; -+ } -+ -+ switch (msg->u.event_to_host.port_type) { -+ case MMAL_PORT_TYPE_CONTROL: -+ if (port_num) { -+ pr_err("%s: port_num of %u >= number of ports 1", -+ __func__, port_num); -+ return; -+ } -+ port = &component->control; -+ break; -+ case MMAL_PORT_TYPE_INPUT: -+ if (port_num >= component->inputs) { -+ pr_err("%s: port_num of %u >= number of ports %u", -+ __func__, port_num, -+ port_num >= component->inputs); -+ return; -+ } -+ port = &component->input[port_num]; -+ break; -+ case MMAL_PORT_TYPE_OUTPUT: -+ if (port_num >= component->outputs) { -+ pr_err("%s: port_num of %u >= number of ports %u", -+ __func__, port_num, -+ port_num >= component->outputs); -+ return; -+ } -+ port = &component->output[port_num]; -+ break; -+ case MMAL_PORT_TYPE_CLOCK: -+ if (port_num >= component->clocks) { -+ pr_err("%s: port_num of %u >= number of ports %u", -+ __func__, port_num, -+ port_num >= component->clocks); -+ return; -+ } -+ port = &component->clock[port_num]; -+ break; -+ default: -+ break; -+ } -+ -+ if (!mutex_trylock(&port->event_context_mutex)) { -+ pr_err("dropping event 0x%x\n", msg->u.event_to_host.cmd); -+ return; -+ } -+ msg_context = port->event_context; -+ -+ if (msg->h.status != MMAL_MSG_STATUS_SUCCESS) { -+ /* message reception had an error */ -+ //pr_warn -+ pr_err("%s: error %d in reply\n", __func__, msg->h.status); -+ -+ msg_context->u.bulk.status = msg->h.status; -+ } else if (msg->u.event_to_host.length > MMAL_WORKER_EVENT_SPACE) { -+ /* data is not in message, queue a bulk receive */ -+ pr_err("%s: payload not in message - bulk receive??! NOT SUPPORTED\n", -+ __func__); -+ msg_context->u.bulk.status = -1; -+ } else { -+ memcpy(msg_context->u.bulk.buffer->buffer, -+ msg->u.event_to_host.data, -+ msg->u.event_to_host.length); -+ -+ msg_context->u.bulk.buffer_used = -+ msg->u.event_to_host.length; -+ -+ msg_context->u.bulk.mmal_flags = 0; -+ msg_context->u.bulk.dts = MMAL_TIME_UNKNOWN; -+ msg_context->u.bulk.pts = MMAL_TIME_UNKNOWN; -+ msg_context->u.bulk.cmd = msg->u.event_to_host.cmd; -+ -+ pr_debug("event component:%u port type:%d num:%d cmd:0x%x length:%d\n", -+ msg->u.event_to_host.client_component, -+ msg->u.event_to_host.port_type, -+ msg->u.event_to_host.port_num, -+ msg->u.event_to_host.cmd, msg->u.event_to_host.length); -+ } -+ -+ schedule_work(&msg_context->u.bulk.work); -+} -+ - /* deals with receipt of buffer to host message */ - static void buffer_to_host_cb(struct vchiq_mmal_instance *instance, - struct mmal_msg *msg, u32 msg_len) -@@ -1340,6 +1433,7 @@ static int port_disable(struct vchiq_mma - mmalbuf->mmal_flags = 0; - mmalbuf->dts = MMAL_TIME_UNKNOWN; - mmalbuf->pts = MMAL_TIME_UNKNOWN; -+ mmalbuf->cmd = 0; - port->buffer_cb(instance, - port, 0, mmalbuf); - } -@@ -1641,6 +1735,43 @@ int mmal_vchi_buffer_cleanup(struct mmal - } - EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup); - -+static void init_event_context(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port) -+{ -+ struct mmal_msg_context *ctx = get_msg_context(instance); -+ -+ mutex_init(&port->event_context_mutex); -+ -+ port->event_context = ctx; -+ ctx->u.bulk.instance = instance; -+ ctx->u.bulk.port = port; -+ ctx->u.bulk.buffer = -+ kzalloc(sizeof(*ctx->u.bulk.buffer), GFP_KERNEL); -+ if (!ctx->u.bulk.buffer) -+ goto release_msg_context; -+ ctx->u.bulk.buffer->buffer = kzalloc(MMAL_WORKER_EVENT_SPACE, -+ GFP_KERNEL); -+ if (!ctx->u.bulk.buffer->buffer) -+ goto release_buffer; -+ -+ INIT_WORK(&ctx->u.bulk.work, buffer_work_cb); -+ return; -+ -+release_buffer: -+ kfree(ctx->u.bulk.buffer); -+release_msg_context: -+ release_msg_context(ctx); -+} -+ -+static void free_event_context(struct vchiq_mmal_port *port) -+{ -+ struct mmal_msg_context *ctx = port->event_context; -+ -+ kfree(ctx->u.bulk.buffer->buffer); -+ kfree(ctx->u.bulk.buffer); -+ release_msg_context(ctx); -+} -+ - /* Initialise a mmal component and its ports - * - */ -@@ -1684,6 +1815,7 @@ int vchiq_mmal_component_init(struct vch - ret = port_info_get(instance, &component->control); - if (ret < 0) - goto release_component; -+ init_event_context(instance, &component->control); - - for (idx = 0; idx < component->inputs; idx++) { - component->input[idx].type = MMAL_PORT_TYPE_INPUT; -@@ -1694,6 +1826,7 @@ int vchiq_mmal_component_init(struct vch - ret = port_info_get(instance, &component->input[idx]); - if (ret < 0) - goto release_component; -+ init_event_context(instance, &component->input[idx]); - } - - for (idx = 0; idx < component->outputs; idx++) { -@@ -1705,6 +1838,7 @@ int vchiq_mmal_component_init(struct vch - ret = port_info_get(instance, &component->output[idx]); - if (ret < 0) - goto release_component; -+ init_event_context(instance, &component->output[idx]); - } - - for (idx = 0; idx < component->clocks; idx++) { -@@ -1716,6 +1850,7 @@ int vchiq_mmal_component_init(struct vch - ret = port_info_get(instance, &component->clock[idx]); - if (ret < 0) - goto release_component; -+ init_event_context(instance, &component->clock[idx]); - } - - *component_out = component; -@@ -1741,7 +1876,7 @@ EXPORT_SYMBOL_GPL(vchiq_mmal_component_i - int vchiq_mmal_component_finalise(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_component *component) - { -- int ret; -+ int ret, idx; - - if (mutex_lock_interruptible(&instance->vchiq_mutex)) - return -EINTR; -@@ -1753,6 +1888,13 @@ int vchiq_mmal_component_finalise(struct - - component->in_use = 0; - -+ for (idx = 0; idx < component->inputs; idx++) -+ free_event_context(&component->input[idx]); -+ for (idx = 0; idx < component->outputs; idx++) -+ free_event_context(&component->output[idx]); -+ for (idx = 0; idx < component->clocks; idx++) -+ free_event_context(&component->clock[idx]); -+ - mutex_unlock(&instance->vchiq_mutex); - - return ret; ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h -@@ -78,6 +78,10 @@ struct vchiq_mmal_port { - vchiq_mmal_buffer_cb buffer_cb; - /* callback context */ - void *cb_ctx; -+ -+ /* ensure serialised use of the one event context structure */ -+ struct mutex event_context_mutex; -+ struct mmal_msg_context *event_context; - }; - - struct vchiq_mmal_component { diff --git a/target/linux/brcm2708/patches-4.19/950-0272-staging-vc04_services-Add-new-vc-sm-cma-driver.patch b/target/linux/brcm2708/patches-4.19/950-0272-staging-vc04_services-Add-new-vc-sm-cma-driver.patch new file mode 100644 index 0000000000..c476d6321a --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0272-staging-vc04_services-Add-new-vc-sm-cma-driver.patch @@ -0,0 +1,1881 @@ +From 3b89c864ffec186fc4b3d31ddb575533e97225eb Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 25 Sep 2018 10:27:11 +0100 +Subject: [PATCH 272/725] staging: vc04_services: Add new vc-sm-cma driver + +This new driver allows contiguous memory blocks to be imported +into the VideoCore VPU memory map, and manages the lifetime of +those objects, only releasing the source dmabuf once the VPU has +confirmed it has finished with it. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/Kconfig | 1 + + drivers/staging/vc04_services/Makefile | 1 + + .../staging/vc04_services/vc-sm-cma/Kconfig | 10 + + .../staging/vc04_services/vc-sm-cma/Makefile | 8 + + drivers/staging/vc04_services/vc-sm-cma/TODO | 2 + + .../staging/vc04_services/vc-sm-cma/vc_sm.c | 838 ++++++++++++++++++ + .../staging/vc04_services/vc-sm-cma/vc_sm.h | 59 ++ + .../vc04_services/vc-sm-cma/vc_sm_cma_vchi.c | 498 +++++++++++ + .../vc04_services/vc-sm-cma/vc_sm_cma_vchi.h | 59 ++ + .../vc04_services/vc-sm-cma/vc_sm_defs.h | 298 +++++++ + .../vc04_services/vc-sm-cma/vc_sm_knl.h | 28 + + 11 files changed, 1802 insertions(+) + create mode 100644 drivers/staging/vc04_services/vc-sm-cma/Kconfig + create mode 100644 drivers/staging/vc04_services/vc-sm-cma/Makefile + create mode 100644 drivers/staging/vc04_services/vc-sm-cma/TODO + create mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm.c + create mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm.h + create mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c + create mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.h + create mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm_defs.h + create mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm_knl.h + +--- a/drivers/staging/vc04_services/Kconfig ++++ b/drivers/staging/vc04_services/Kconfig +@@ -22,6 +22,7 @@ source "drivers/staging/vc04_services/bc + + source "drivers/staging/vc04_services/bcm2835-camera/Kconfig" + source "drivers/staging/vc04_services/vchiq-mmal/Kconfig" ++source "drivers/staging/vc04_services/vc-sm-cma/Kconfig" + + endif + +--- a/drivers/staging/vc04_services/Makefile ++++ b/drivers/staging/vc04_services/Makefile +@@ -13,6 +13,7 @@ vchiq-objs := \ + obj-$(CONFIG_SND_BCM2835) += bcm2835-audio/ + obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-camera/ + obj-$(CONFIG_BCM2835_VCHIQ_MMAL) += vchiq-mmal/ ++obj-$(CONFIG_BCM_VC_SM_CMA) += vc-sm-cma/ + + ccflags-y += -Idrivers/staging/vc04_services -D__VCCOREVER__=0x04000000 + +--- /dev/null ++++ b/drivers/staging/vc04_services/vc-sm-cma/Kconfig +@@ -0,0 +1,10 @@ ++config BCM_VC_SM_CMA ++ tristate "VideoCore Shared Memory (CMA) driver" ++ depends on BCM2835_VCHIQ ++ select RBTREE ++ select DMA_SHARED_BUFFER ++ help ++ Say Y here to enable the shared memory interface that ++ supports sharing dmabufs with VideoCore. ++ This operates over the VCHIQ interface to a service ++ running on VideoCore. +--- /dev/null ++++ b/drivers/staging/vc04_services/vc-sm-cma/Makefile +@@ -0,0 +1,8 @@ ++ccflags-y += -Idrivers/staging/vc04_services -Idrivers/staging/vc04_services/interface/vchi -Idrivers/staging/vc04_services/interface/vchiq_arm ++# -I"drivers/staging/android/ion/" -I"$(srctree)/fs/" ++ccflags-y += -D__VCCOREVER__=0 ++ ++vc-sm-cma-$(CONFIG_BCM_VC_SM_CMA) := \ ++ vc_sm.o vc_sm_cma_vchi.o ++ ++obj-$(CONFIG_BCM_VC_SM_CMA) += vc-sm-cma.o +--- /dev/null ++++ b/drivers/staging/vc04_services/vc-sm-cma/TODO +@@ -0,0 +1,2 @@ ++1) Convert to a platform driver. ++ +--- /dev/null ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -0,0 +1,838 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * VideoCore Shared Memory driver using CMA. ++ * ++ * Copyright: 2018, Raspberry Pi (Trading) Ltd ++ * Dave Stevenson ++ * ++ * Based on vmcs_sm driver from Broadcom Corporation for some API, ++ * and taking some code for CMA/dmabuf handling from the Android Ion ++ * driver (Google/Linaro). ++ * ++ * This is cut down version to only support import of dma_bufs from ++ * other kernel drivers. A more complete implementation of the old ++ * vmcs_sm functionality can follow later. ++ * ++ */ ++ ++/* ---- Include Files ----------------------------------------------------- */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "vchiq_connected.h" ++#include "vc_sm_cma_vchi.h" ++ ++#include "vc_sm.h" ++#include "vc_sm_knl.h" ++ ++/* ---- Private Constants and Types --------------------------------------- */ ++ ++#define DEVICE_NAME "vcsm-cma" ++#define DEVICE_MINOR 0 ++ ++#define VC_SM_RESOURCE_NAME_DEFAULT "sm-host-resource" ++ ++#define VC_SM_DIR_ROOT_NAME "vcsm-cma" ++#define VC_SM_STATE "state" ++ ++/* Private file data associated with each opened device. */ ++struct vc_sm_privdata_t { ++ pid_t pid; /* PID of creator. */ ++ ++ int restart_sys; /* Tracks restart on interrupt. */ ++ enum vc_sm_msg_type int_action; /* Interrupted action. */ ++ u32 int_trans_id; /* Interrupted transaction. */ ++}; ++ ++typedef int (*VC_SM_SHOW) (struct seq_file *s, void *v); ++struct sm_pde_t { ++ VC_SM_SHOW show; /* Debug fs function hookup. */ ++ struct dentry *dir_entry; /* Debug fs directory entry. */ ++ void *priv_data; /* Private data */ ++}; ++ ++/* Global state information. */ ++struct sm_state_t { ++ struct platform_device *pdev; ++ ++ struct miscdevice dev; ++ struct sm_instance *sm_handle; /* Handle for videocore service. */ ++ ++ struct mutex map_lock; /* Global map lock. */ ++ struct list_head buffer_list; /* List of buffer. */ ++ ++ struct vc_sm_privdata_t *data_knl; /* Kernel internal data tracking. */ ++ struct dentry *dir_root; /* Debug fs entries root. */ ++ struct sm_pde_t dir_state; /* Debug fs entries state sub-tree. */ ++ ++ bool require_released_callback; /* VPU will send a released msg when it ++ * has finished with a resource. ++ */ ++ u32 int_trans_id; /* Interrupted transaction. */ ++}; ++ ++/* ---- Private Variables ----------------------------------------------- */ ++ ++static struct sm_state_t *sm_state; ++static int sm_inited; ++ ++/* ---- Private Function Prototypes -------------------------------------- */ ++ ++/* ---- Private Functions ------------------------------------------------ */ ++ ++static int vc_sm_cma_seq_file_show(struct seq_file *s, void *v) ++{ ++ struct sm_pde_t *sm_pde; ++ ++ sm_pde = (struct sm_pde_t *)(s->private); ++ ++ if (sm_pde && sm_pde->show) ++ sm_pde->show(s, v); ++ ++ return 0; ++} ++ ++static int vc_sm_cma_single_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, vc_sm_cma_seq_file_show, inode->i_private); ++} ++ ++static const struct file_operations vc_sm_cma_debug_fs_fops = { ++ .open = vc_sm_cma_single_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static int vc_sm_cma_global_state_show(struct seq_file *s, void *v) ++{ ++ struct vc_sm_buffer *resource = NULL; ++ int resource_count = 0; ++ ++ if (!sm_state) ++ return 0; ++ ++ seq_printf(s, "\nVC-ServiceHandle 0x%x\n", ++ (unsigned int)sm_state->sm_handle); ++ ++ /* Log all applicable mapping(s). */ ++ ++ mutex_lock(&sm_state->map_lock); ++ seq_puts(s, "\nResources\n"); ++ if (!list_empty(&sm_state->buffer_list)) { ++ list_for_each_entry(resource, &sm_state->buffer_list, ++ global_buffer_list) { ++ resource_count++; ++ ++ seq_printf(s, "\nResource %p\n", ++ resource); ++ seq_printf(s, " NAME %s\n", ++ resource->name); ++ seq_printf(s, " SIZE %d\n", ++ resource->size); ++ seq_printf(s, " DMABUF %p\n", ++ resource->dma_buf); ++ seq_printf(s, " ATTACH %p\n", ++ resource->attach); ++ seq_printf(s, " SG_TABLE %p\n", ++ resource->sg_table); ++ seq_printf(s, " SGT %p\n", ++ resource->sgt); ++ seq_printf(s, " DMA_ADDR %pad\n", ++ &resource->dma_addr); ++ seq_printf(s, " VC_HANDLE %08x\n", ++ resource->vc_handle); ++ seq_printf(s, " VC_MAPPING %d\n", ++ resource->vpu_state); ++ } ++ } ++ seq_printf(s, "\n\nTotal resource count: %d\n\n", resource_count); ++ ++ mutex_unlock(&sm_state->map_lock); ++ ++ return 0; ++} ++ ++/* ++ * Adds a buffer to the private data list which tracks all the allocated ++ * data. ++ */ ++static void vc_sm_add_resource(struct vc_sm_privdata_t *privdata, ++ struct vc_sm_buffer *buffer) ++{ ++ mutex_lock(&sm_state->map_lock); ++ list_add(&buffer->global_buffer_list, &sm_state->buffer_list); ++ mutex_unlock(&sm_state->map_lock); ++ ++ pr_debug("[%s]: added buffer %p (name %s, size %d)\n", ++ __func__, buffer, buffer->name, buffer->size); ++} ++ ++/* ++ * Release an allocation. ++ * All refcounting is done via the dma buf object. ++ */ ++static void vc_sm_release_resource(struct vc_sm_buffer *buffer, int force) ++{ ++ mutex_lock(&sm_state->map_lock); ++ mutex_lock(&buffer->lock); ++ ++ pr_debug("[%s]: buffer %p (name %s, size %d)\n", ++ __func__, buffer, buffer->name, buffer->size); ++ ++ if (buffer->vc_handle && buffer->vpu_state == VPU_MAPPED) { ++ struct vc_sm_free_t free = { buffer->vc_handle, 0 }; ++ int status = vc_sm_cma_vchi_free(sm_state->sm_handle, &free, ++ &sm_state->int_trans_id); ++ if (status != 0 && status != -EINTR) { ++ pr_err("[%s]: failed to free memory on videocore (status: %u, trans_id: %u)\n", ++ __func__, status, sm_state->int_trans_id); ++ } ++ ++ if (sm_state->require_released_callback) { ++ /* Need to wait for the VPU to confirm the free */ ++ ++ /* Retain a reference on this until the VPU has ++ * released it ++ */ ++ buffer->vpu_state = VPU_UNMAPPING; ++ goto defer; ++ } ++ buffer->vpu_state = VPU_NOT_MAPPED; ++ buffer->vc_handle = 0; ++ } ++ if (buffer->vc_handle) { ++ /* We've sent the unmap request but not had the response. */ ++ pr_err("[%s]: Waiting for VPU unmap response on %p\n", ++ __func__, buffer); ++ goto defer; ++ } ++ if (buffer->in_use) { ++ /* Don't release dmabuf here - we await the release */ ++ pr_err("[%s]: buffer %p is still in use\n", ++ __func__, buffer); ++ goto defer; ++ } ++ ++ /* Handle cleaning up imported dmabufs */ ++ if (buffer->sgt) { ++ dma_buf_unmap_attachment(buffer->attach, buffer->sgt, ++ DMA_BIDIRECTIONAL); ++ buffer->sgt = NULL; ++ } ++ if (buffer->attach) { ++ dma_buf_detach(buffer->dma_buf, buffer->attach); ++ buffer->attach = NULL; ++ } ++ ++ /* Release the dma_buf (whether ours or imported) */ ++ if (buffer->import_dma_buf) { ++ dma_buf_put(buffer->import_dma_buf); ++ buffer->import_dma_buf = NULL; ++ buffer->dma_buf = NULL; ++ } else if (buffer->dma_buf) { ++ dma_buf_put(buffer->dma_buf); ++ buffer->dma_buf = NULL; ++ } ++ ++ if (buffer->sg_table && !buffer->import_dma_buf) { ++ /* Our own allocation that we need to dma_unmap_sg */ ++ dma_unmap_sg(&sm_state->pdev->dev, buffer->sg_table->sgl, ++ buffer->sg_table->nents, DMA_BIDIRECTIONAL); ++ } ++ ++ /* Free the local resource. Start by removing it from the list */ ++ buffer->private = NULL; ++ list_del(&buffer->global_buffer_list); ++ ++ mutex_unlock(&buffer->lock); ++ mutex_unlock(&sm_state->map_lock); ++ ++ mutex_destroy(&buffer->lock); ++ ++ kfree(buffer); ++ return; ++ ++defer: ++ mutex_unlock(&buffer->lock); ++ mutex_unlock(&sm_state->map_lock); ++} ++ ++/* Create support for private data tracking. */ ++static struct vc_sm_privdata_t *vc_sm_cma_create_priv_data(pid_t id) ++{ ++ char alloc_name[32]; ++ struct vc_sm_privdata_t *file_data = NULL; ++ ++ /* Allocate private structure. */ ++ file_data = kzalloc(sizeof(*file_data), GFP_KERNEL); ++ ++ if (!file_data) ++ return NULL; ++ ++ snprintf(alloc_name, sizeof(alloc_name), "%d", id); ++ ++ file_data->pid = id; ++ ++ return file_data; ++} ++ ++/* Dma_buf operations for chaining through to an imported dma_buf */ ++static ++int vc_sm_import_dma_buf_attach(struct dma_buf *dmabuf, ++ struct dma_buf_attachment *attachment) ++{ ++ struct vc_sm_buffer *res = dmabuf->priv; ++ ++ if (!res->import_dma_buf) ++ return -EINVAL; ++ return res->import_dma_buf->ops->attach(res->import_dma_buf, ++ attachment); ++} ++ ++static ++void vc_sm_import_dma_buf_detatch(struct dma_buf *dmabuf, ++ struct dma_buf_attachment *attachment) ++{ ++ struct vc_sm_buffer *res = dmabuf->priv; ++ ++ if (!res->import_dma_buf) ++ return; ++ res->import_dma_buf->ops->detach(res->import_dma_buf, attachment); ++} ++ ++static ++struct sg_table *vc_sm_import_map_dma_buf(struct dma_buf_attachment *attachment, ++ enum dma_data_direction direction) ++{ ++ struct vc_sm_buffer *res = attachment->dmabuf->priv; ++ ++ if (!res->import_dma_buf) ++ return NULL; ++ return res->import_dma_buf->ops->map_dma_buf(attachment, direction); ++} ++ ++static ++void vc_sm_import_unmap_dma_buf(struct dma_buf_attachment *attachment, ++ struct sg_table *table, ++ enum dma_data_direction direction) ++{ ++ struct vc_sm_buffer *res = attachment->dmabuf->priv; ++ ++ if (!res->import_dma_buf) ++ return; ++ res->import_dma_buf->ops->unmap_dma_buf(attachment, table, direction); ++} ++ ++static ++int vc_sm_import_dmabuf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) ++{ ++ struct vc_sm_buffer *res = dmabuf->priv; ++ ++ pr_debug("%s: mmap dma_buf %p, res %p, imported db %p\n", __func__, ++ dmabuf, res, res->import_dma_buf); ++ if (!res->import_dma_buf) { ++ pr_err("%s: mmap dma_buf %p- not an imported buffer\n", ++ __func__, dmabuf); ++ return -EINVAL; ++ } ++ return res->import_dma_buf->ops->mmap(res->import_dma_buf, vma); ++} ++ ++static ++void vc_sm_import_dma_buf_release(struct dma_buf *dmabuf) ++{ ++ struct vc_sm_buffer *res = dmabuf->priv; ++ ++ pr_debug("%s: Relasing dma_buf %p\n", __func__, dmabuf); ++ if (!res->import_dma_buf) ++ return; ++ ++ res->in_use = 0; ++ ++ vc_sm_release_resource(res, 0); ++} ++ ++static ++void *vc_sm_import_dma_buf_kmap(struct dma_buf *dmabuf, ++ unsigned long offset) ++{ ++ struct vc_sm_buffer *res = dmabuf->priv; ++ ++ if (!res->import_dma_buf) ++ return NULL; ++ return res->import_dma_buf->ops->map(res->import_dma_buf, ++ offset); ++} ++ ++static ++void vc_sm_import_dma_buf_kunmap(struct dma_buf *dmabuf, ++ unsigned long offset, void *ptr) ++{ ++ struct vc_sm_buffer *res = dmabuf->priv; ++ ++ if (!res->import_dma_buf) ++ return; ++ res->import_dma_buf->ops->unmap(res->import_dma_buf, ++ offset, ptr); ++} ++ ++static ++int vc_sm_import_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, ++ enum dma_data_direction direction) ++{ ++ struct vc_sm_buffer *res = dmabuf->priv; ++ ++ if (!res->import_dma_buf) ++ return -EINVAL; ++ return res->import_dma_buf->ops->begin_cpu_access(res->import_dma_buf, ++ direction); ++} ++ ++static ++int vc_sm_import_dma_buf_end_cpu_access(struct dma_buf *dmabuf, ++ enum dma_data_direction direction) ++{ ++ struct vc_sm_buffer *res = dmabuf->priv; ++ ++ if (!res->import_dma_buf) ++ return -EINVAL; ++ return res->import_dma_buf->ops->end_cpu_access(res->import_dma_buf, ++ direction); ++} ++ ++static const struct dma_buf_ops dma_buf_import_ops = { ++ .map_dma_buf = vc_sm_import_map_dma_buf, ++ .unmap_dma_buf = vc_sm_import_unmap_dma_buf, ++ .mmap = vc_sm_import_dmabuf_mmap, ++ .release = vc_sm_import_dma_buf_release, ++ .attach = vc_sm_import_dma_buf_attach, ++ .detach = vc_sm_import_dma_buf_detatch, ++ .begin_cpu_access = vc_sm_import_dma_buf_begin_cpu_access, ++ .end_cpu_access = vc_sm_import_dma_buf_end_cpu_access, ++ .map = vc_sm_import_dma_buf_kmap, ++ .unmap = vc_sm_import_dma_buf_kunmap, ++}; ++ ++/* Import a dma_buf to be shared with VC. */ ++int ++vc_sm_cma_import_dmabuf_internal(struct vc_sm_privdata_t *private, ++ struct dma_buf *dma_buf, ++ struct dma_buf **imported_buf) ++{ ++ DEFINE_DMA_BUF_EXPORT_INFO(exp_info); ++ struct vc_sm_buffer *buffer = NULL; ++ struct vc_sm_import import = { }; ++ struct vc_sm_import_result result = { }; ++ struct dma_buf_attachment *attach = NULL; ++ struct sg_table *sgt = NULL; ++ int ret = 0; ++ int status; ++ ++ /* Setup our allocation parameters */ ++ pr_debug("%s: importing dma_buf %p\n", __func__, dma_buf); ++ ++ get_dma_buf(dma_buf); ++ dma_buf = dma_buf; ++ ++ attach = dma_buf_attach(dma_buf, &sm_state->pdev->dev); ++ if (IS_ERR(attach)) { ++ ret = PTR_ERR(attach); ++ goto error; ++ } ++ ++ sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); ++ if (IS_ERR(sgt)) { ++ ret = PTR_ERR(sgt); ++ goto error; ++ } ++ ++ /* Verify that the address block is contiguous */ ++ if (sgt->nents != 1) { ++ ret = -ENOMEM; ++ goto error; ++ } ++ ++ /* Allocate local buffer to track this allocation. */ ++ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); ++ if (!buffer) { ++ ret = -ENOMEM; ++ goto error; ++ } ++ ++ import.type = VC_SM_ALLOC_NON_CACHED; ++ import.addr = (uint32_t)sg_dma_address(sgt->sgl); ++ if ((import.addr & 0xC0000000) != 0xC0000000) { ++ pr_err("%s: Expecting an uncached alias for dma_addr %08x\n", ++ __func__, import.addr); ++ import.addr |= 0xC0000000; ++ } ++ import.size = sg_dma_len(sgt->sgl); ++ import.allocator = current->tgid; ++ import.kernel_id = (uint32_t)buffer; //FIXME: 64 bit support needed. ++ ++ memcpy(import.name, VC_SM_RESOURCE_NAME_DEFAULT, ++ sizeof(VC_SM_RESOURCE_NAME_DEFAULT)); ++ ++ pr_debug("[%s]: attempt to import \"%s\" data - type %u, addr %p, size %u\n", ++ __func__, import.name, import.type, (void *)import.addr, ++ import.size); ++ ++ /* Allocate the videocore buffer. */ ++ status = vc_sm_cma_vchi_import(sm_state->sm_handle, &import, &result, ++ &sm_state->int_trans_id); ++ if (status == -EINTR) { ++ pr_debug("[%s]: requesting import memory action restart (trans_id: %u)\n", ++ __func__, sm_state->int_trans_id); ++ ret = -ERESTARTSYS; ++ private->restart_sys = -EINTR; ++ private->int_action = VC_SM_MSG_TYPE_IMPORT; ++ goto error; ++ } else if (status || !result.res_handle) { ++ pr_debug("[%s]: failed to import memory on videocore (status: %u, trans_id: %u)\n", ++ __func__, status, sm_state->int_trans_id); ++ ret = -ENOMEM; ++ goto error; ++ } ++ ++ mutex_init(&buffer->lock); ++ INIT_LIST_HEAD(&buffer->attachments); ++ memcpy(buffer->name, import.name, ++ min(sizeof(buffer->name), sizeof(import.name) - 1)); ++ ++ /* Keep track of the buffer we created. */ ++ buffer->private = private; ++ buffer->vc_handle = result.res_handle; ++ buffer->size = import.size; ++ buffer->vpu_state = VPU_MAPPED; ++ ++ buffer->import_dma_buf = dma_buf; ++ ++ buffer->attach = attach; ++ buffer->sgt = sgt; ++ buffer->dma_addr = sg_dma_address(sgt->sgl); ++ buffer->in_use = 1; ++ ++ /* ++ * We're done - we need to export a new dmabuf chaining through most ++ * functions, but enabling us to release our own internal references ++ * here. ++ */ ++ exp_info.ops = &dma_buf_import_ops; ++ exp_info.size = import.size; ++ exp_info.flags = O_RDWR; ++ exp_info.priv = buffer; ++ ++ buffer->dma_buf = dma_buf_export(&exp_info); ++ if (IS_ERR(buffer->dma_buf)) { ++ ret = PTR_ERR(buffer->dma_buf); ++ goto error; ++ } ++ ++ vc_sm_add_resource(private, buffer); ++ ++ *imported_buf = buffer->dma_buf; ++ ++ return 0; ++ ++error: ++ if (result.res_handle) { ++ struct vc_sm_free_t free = { result.res_handle, 0 }; ++ ++ vc_sm_cma_vchi_free(sm_state->sm_handle, &free, ++ &sm_state->int_trans_id); ++ } ++ kfree(buffer); ++ if (sgt) ++ dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); ++ if (attach) ++ dma_buf_detach(dma_buf, attach); ++ dma_buf_put(dma_buf); ++ return ret; ++} ++ ++/* FIXME: Pass a function pointer to this into vc_vchi_sm.c */ ++void ++vc_sm_vpu_event(struct sm_instance *instance, struct vc_sm_result_t *reply, ++ int reply_len) ++{ ++ switch (reply->trans_id & ~0x80000000) { ++ case VC_SM_MSG_TYPE_CLIENT_VERSION: ++ { ++ /* Acknowledge that the firmware supports the version command */ ++ pr_debug("%s: firmware acked version msg. Require release cb\n", ++ __func__); ++ sm_state->require_released_callback = true; ++ } ++ break; ++ case VC_SM_MSG_TYPE_RELEASED: ++ { ++ struct vc_sm_released *release = (struct vc_sm_released *)reply; ++ struct vc_sm_buffer *buffer = ++ (struct vc_sm_buffer *)release->kernel_id; ++ ++ /* ++ * FIXME: Need to check buffer is still valid and allocated ++ * before continuing ++ */ ++ pr_debug("%s: Released addr %08x, size %u, id %08x, mem_handle %08x\n", ++ __func__, release->addr, release->size, ++ release->kernel_id, release->vc_handle); ++ mutex_lock(&buffer->lock); ++ buffer->vc_handle = 0; ++ buffer->vpu_state = VPU_NOT_MAPPED; ++ mutex_unlock(&buffer->lock); ++ ++ vc_sm_release_resource(buffer, 0); ++ } ++ break; ++ default: ++ pr_err("%s: Unknown vpu cmd %x\n", __func__, reply->trans_id); ++ break; ++ } ++} ++ ++/* Videocore connected. */ ++static void vc_sm_connected_init(void) ++{ ++ int ret; ++ VCHI_INSTANCE_T vchi_instance; ++ struct vc_sm_version version; ++ struct vc_sm_result_t version_result; ++ ++ pr_info("[%s]: start\n", __func__); ++ ++ /* ++ * Initialize and create a VCHI connection for the shared memory service ++ * running on videocore. ++ */ ++ ret = vchi_initialise(&vchi_instance); ++ if (ret) { ++ pr_err("[%s]: failed to initialise VCHI instance (ret=%d)\n", ++ __func__, ret); ++ ++ ret = -EIO; ++ goto err_free_mem; ++ } ++ ++ ret = vchi_connect(vchi_instance); ++ if (ret) { ++ pr_err("[%s]: failed to connect VCHI instance (ret=%d)\n", ++ __func__, ret); ++ ++ ret = -EIO; ++ goto err_free_mem; ++ } ++ ++ /* Initialize an instance of the shared memory service. */ ++ sm_state->sm_handle = vc_sm_cma_vchi_init(vchi_instance, 1, ++ vc_sm_vpu_event); ++ if (!sm_state->sm_handle) { ++ pr_err("[%s]: failed to initialize shared memory service\n", ++ __func__); ++ ++ ret = -EPERM; ++ goto err_free_mem; ++ } ++ ++ /* Create a debug fs directory entry (root). */ ++ sm_state->dir_root = debugfs_create_dir(VC_SM_DIR_ROOT_NAME, NULL); ++ if (!sm_state->dir_root) { ++ pr_err("[%s]: failed to create \'%s\' directory entry\n", ++ __func__, VC_SM_DIR_ROOT_NAME); ++ ++ ret = -EPERM; ++ goto err_stop_sm_service; ++ } ++ ++ sm_state->dir_state.show = &vc_sm_cma_global_state_show; ++ sm_state->dir_state.dir_entry = ++ debugfs_create_file(VC_SM_STATE, 0444, sm_state->dir_root, ++ &sm_state->dir_state, ++ &vc_sm_cma_debug_fs_fops); ++ ++ INIT_LIST_HEAD(&sm_state->buffer_list); ++ ++ sm_state->data_knl = vc_sm_cma_create_priv_data(0); ++ if (!sm_state->data_knl) { ++ pr_err("[%s]: failed to create kernel private data tracker\n", ++ __func__); ++ goto err_remove_shared_memory; ++ } ++ ++ version.version = 1; ++ ret = vc_sm_cma_vchi_client_version(sm_state->sm_handle, &version, ++ &version_result, ++ &sm_state->int_trans_id); ++ if (ret) { ++ pr_err("[%s]: Failed to send version request %d\n", __func__, ++ ret); ++ } ++ ++ /* Done! */ ++ sm_inited = 1; ++ pr_info("[%s]: installed successfully\n", __func__); ++ return; ++ ++err_remove_shared_memory: ++ debugfs_remove_recursive(sm_state->dir_root); ++err_stop_sm_service: ++ vc_sm_cma_vchi_stop(&sm_state->sm_handle); ++err_free_mem: ++ kfree(sm_state); ++ pr_info("[%s]: failed, ret %d\n", __func__, ret); ++} ++ ++/* Driver loading. */ ++static int bcm2835_vc_sm_cma_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ int err; ++ ++ pr_info("%s: Videocore shared memory driver\n", __func__); ++ ++ sm_state = kzalloc(sizeof(*sm_state), GFP_KERNEL); ++ if (!sm_state) ++ return -ENOMEM; ++ sm_state->pdev = pdev; ++ mutex_init(&sm_state->map_lock); ++ ++ dev->coherent_dma_mask = DMA_BIT_MASK(32); ++ dev->dma_mask = &dev->coherent_dma_mask; ++ err = of_dma_configure(dev, NULL, true); ++ if (err) { ++ dev_err(dev, "Unable to setup DMA: %d\n", err); ++ return err; ++ } ++ ++ vchiq_add_connected_callback(vc_sm_connected_init); ++ return 0; ++} ++ ++/* Driver unloading. */ ++static int bcm2835_vc_sm_cma_remove(struct platform_device *pdev) ++{ ++ pr_debug("[%s]: start\n", __func__); ++ if (sm_inited) { ++ /* Remove shared memory device. */ ++ misc_deregister(&sm_state->dev); ++ ++ /* Remove all proc entries. */ ++ //debugfs_remove_recursive(sm_state->dir_root); ++ ++ /* Stop the videocore shared memory service. */ ++ vc_sm_cma_vchi_stop(&sm_state->sm_handle); ++ ++ /* Free the memory for the state structure. */ ++ mutex_destroy(&sm_state->map_lock); ++ kfree(sm_state); ++ } ++ ++ pr_debug("[%s]: end\n", __func__); ++ return 0; ++} ++ ++/* Get an internal resource handle mapped from the external one. */ ++int vc_sm_cma_int_handle(int handle) ++{ ++ struct dma_buf *dma_buf = (struct dma_buf *)handle; ++ struct vc_sm_buffer *res; ++ ++ /* Validate we can work with this device. */ ++ if (!sm_state || !handle) { ++ pr_err("[%s]: invalid input\n", __func__); ++ return 0; ++ } ++ ++ res = (struct vc_sm_buffer *)dma_buf->priv; ++ return res->vc_handle; ++} ++EXPORT_SYMBOL_GPL(vc_sm_cma_int_handle); ++ ++/* Free a previously allocated shared memory handle and block. */ ++int vc_sm_cma_free(int handle) ++{ ++ struct dma_buf *dma_buf = (struct dma_buf *)handle; ++ ++ /* Validate we can work with this device. */ ++ if (!sm_state || !handle) { ++ pr_err("[%s]: invalid input\n", __func__); ++ return -EPERM; ++ } ++ ++ pr_debug("%s: handle %08x/dmabuf %p\n", __func__, handle, dma_buf); ++ ++ dma_buf_put(dma_buf); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(vc_sm_cma_free); ++ ++/* Import a dmabuf to be shared with VC. */ ++int vc_sm_cma_import_dmabuf(struct dma_buf *src_dmabuf, int *handle) ++{ ++ struct dma_buf *new_dma_buf; ++ struct vc_sm_buffer *res; ++ int ret; ++ ++ /* Validate we can work with this device. */ ++ if (!sm_state || !src_dmabuf || !handle) { ++ pr_err("[%s]: invalid input\n", __func__); ++ return -EPERM; ++ } ++ ++ ret = vc_sm_cma_import_dmabuf_internal(sm_state->data_knl, src_dmabuf, ++ &new_dma_buf); ++ ++ if (!ret) { ++ pr_debug("%s: imported to ptr %p\n", __func__, new_dma_buf); ++ res = (struct vc_sm_buffer *)new_dma_buf->priv; ++ ++ /* Assign valid handle at this time.*/ ++ *handle = (int)new_dma_buf; ++ } else { ++ /* ++ * succeeded in importing the dma_buf, but then ++ * failed to look it up again. How? ++ * Release the fd again. ++ */ ++ pr_err("%s: imported vc_sm_cma_get_buffer failed %d\n", ++ __func__, ret); ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(vc_sm_cma_import_dmabuf); ++ ++static struct platform_driver bcm2835_vcsm_cma_driver = { ++ .probe = bcm2835_vc_sm_cma_probe, ++ .remove = bcm2835_vc_sm_cma_remove, ++ .driver = { ++ .name = DEVICE_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++module_platform_driver(bcm2835_vcsm_cma_driver); ++ ++MODULE_AUTHOR("Dave Stevenson"); ++MODULE_DESCRIPTION("VideoCore CMA Shared Memory Driver"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:vcsm-cma"); +--- /dev/null ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.h +@@ -0,0 +1,59 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++ ++/* ++ * VideoCore Shared Memory driver using CMA. ++ * ++ * Copyright: 2018, Raspberry Pi (Trading) Ltd ++ * ++ */ ++ ++#ifndef VC_SM_H ++#define VC_SM_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define VC_SM_MAX_NAME_LEN 32 ++ ++enum vc_sm_vpu_mapping_state { ++ VPU_NOT_MAPPED, ++ VPU_MAPPED, ++ VPU_UNMAPPING ++}; ++ ++struct vc_sm_buffer { ++ struct list_head global_buffer_list; /* Global list of buffers. */ ++ ++ size_t size; ++ ++ /* Lock over all the following state for this buffer */ ++ struct mutex lock; ++ struct sg_table *sg_table; ++ struct list_head attachments; ++ ++ char name[VC_SM_MAX_NAME_LEN]; ++ ++ int in_use:1; /* Kernel is still using this resource */ ++ ++ enum vc_sm_vpu_mapping_state vpu_state; ++ u32 vc_handle; /* VideoCore handle for this buffer */ ++ ++ /* DMABUF related fields */ ++ struct dma_buf *import_dma_buf; ++ struct dma_buf *dma_buf; ++ struct dma_buf_attachment *attach; ++ struct sg_table *sgt; ++ dma_addr_t dma_addr; ++ ++ struct vc_sm_privdata_t *private; ++}; ++ ++#endif +--- /dev/null ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c +@@ -0,0 +1,498 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * VideoCore Shared Memory CMA allocator ++ * ++ * Copyright: 2018, Raspberry Pi (Trading) Ltd ++ * Copyright 2011-2012 Broadcom Corporation. All rights reserved. ++ * ++ * Based on vmcs_sm driver from Broadcom Corporation. ++ * ++ */ ++ ++/* ---- Include Files ----------------------------------------------------- */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "vc_sm_cma_vchi.h" ++ ++#define VC_SM_VER 1 ++#define VC_SM_MIN_VER 0 ++ ++/* ---- Private Constants and Types -------------------------------------- */ ++ ++/* Command blocks come from a pool */ ++#define SM_MAX_NUM_CMD_RSP_BLKS 32 ++ ++struct sm_cmd_rsp_blk { ++ struct list_head head; /* To create lists */ ++ /* To be signaled when the response is there */ ++ struct completion cmplt; ++ ++ u16 id; ++ u16 length; ++ ++ u8 msg[VC_SM_MAX_MSG_LEN]; ++ ++ uint32_t wait:1; ++ uint32_t sent:1; ++ uint32_t alloc:1; ++ ++}; ++ ++struct sm_instance { ++ u32 num_connections; ++ VCHI_SERVICE_HANDLE_T vchi_handle[VCHI_MAX_NUM_CONNECTIONS]; ++ struct task_struct *io_thread; ++ struct completion io_cmplt; ++ ++ vpu_event_cb vpu_event; ++ ++ /* Mutex over the following lists */ ++ struct mutex lock; ++ u32 trans_id; ++ struct list_head cmd_list; ++ struct list_head rsp_list; ++ struct list_head dead_list; ++ ++ struct sm_cmd_rsp_blk free_blk[SM_MAX_NUM_CMD_RSP_BLKS]; ++ ++ /* Mutex over the free_list */ ++ struct mutex free_lock; ++ struct list_head free_list; ++ ++ struct semaphore free_sema; ++ ++}; ++ ++/* ---- Private Variables ------------------------------------------------ */ ++ ++/* ---- Private Function Prototypes -------------------------------------- */ ++ ++/* ---- Private Functions ------------------------------------------------ */ ++static int ++bcm2835_vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle, ++ void *data, ++ unsigned int size) ++{ ++ return vchi_queue_kernel_message(handle, ++ data, ++ size); ++} ++ ++static struct ++sm_cmd_rsp_blk *vc_vchi_cmd_create(struct sm_instance *instance, ++ enum vc_sm_msg_type id, void *msg, ++ u32 size, int wait) ++{ ++ struct sm_cmd_rsp_blk *blk; ++ struct vc_sm_msg_hdr_t *hdr; ++ ++ if (down_interruptible(&instance->free_sema)) { ++ blk = kmalloc(sizeof(*blk), GFP_KERNEL); ++ if (!blk) ++ return NULL; ++ ++ blk->alloc = 1; ++ init_completion(&blk->cmplt); ++ } else { ++ mutex_lock(&instance->free_lock); ++ blk = ++ list_first_entry(&instance->free_list, ++ struct sm_cmd_rsp_blk, head); ++ list_del(&blk->head); ++ mutex_unlock(&instance->free_lock); ++ } ++ ++ blk->sent = 0; ++ blk->wait = wait; ++ blk->length = sizeof(*hdr) + size; ++ ++ hdr = (struct vc_sm_msg_hdr_t *)blk->msg; ++ hdr->type = id; ++ mutex_lock(&instance->lock); ++ instance->trans_id++; ++ /* ++ * Retain the top bit for identifying asynchronous events, or VPU cmds. ++ */ ++ instance->trans_id &= ~0x80000000; ++ hdr->trans_id = instance->trans_id; ++ blk->id = instance->trans_id; ++ mutex_unlock(&instance->lock); ++ ++ if (size) ++ memcpy(hdr->body, msg, size); ++ ++ return blk; ++} ++ ++static void ++vc_vchi_cmd_delete(struct sm_instance *instance, struct sm_cmd_rsp_blk *blk) ++{ ++ if (blk->alloc) { ++ kfree(blk); ++ return; ++ } ++ ++ mutex_lock(&instance->free_lock); ++ list_add(&blk->head, &instance->free_list); ++ mutex_unlock(&instance->free_lock); ++ up(&instance->free_sema); ++} ++ ++static void vc_sm_cma_vchi_rx_ack(struct sm_instance *instance, ++ struct sm_cmd_rsp_blk *cmd, ++ struct vc_sm_result_t *reply, ++ u32 reply_len) ++{ ++ mutex_lock(&instance->lock); ++ list_for_each_entry(cmd, ++ &instance->rsp_list, ++ head) { ++ if (cmd->id == reply->trans_id) ++ break; ++ } ++ mutex_unlock(&instance->lock); ++ ++ if (&cmd->head == &instance->rsp_list) { ++ //pr_debug("%s: received response %u, throw away...", ++ pr_err("%s: received response %u, throw away...", ++ __func__, ++ reply->trans_id); ++ } else if (reply_len > sizeof(cmd->msg)) { ++ pr_err("%s: reply too big (%u) %u, throw away...", ++ __func__, reply_len, ++ reply->trans_id); ++ } else { ++ memcpy(cmd->msg, reply, ++ reply_len); ++ complete(&cmd->cmplt); ++ } ++} ++ ++static int vc_sm_cma_vchi_videocore_io(void *arg) ++{ ++ struct sm_instance *instance = arg; ++ struct sm_cmd_rsp_blk *cmd = NULL, *cmd_tmp; ++ struct vc_sm_result_t *reply; ++ u32 reply_len; ++ s32 status; ++ int svc_use = 1; ++ ++ while (1) { ++ if (svc_use) ++ vchi_service_release(instance->vchi_handle[0]); ++ svc_use = 0; ++ if (!wait_for_completion_interruptible(&instance->io_cmplt)) { ++ vchi_service_use(instance->vchi_handle[0]); ++ svc_use = 1; ++ ++ do { ++ /* ++ * Get new command and move it to response list ++ */ ++ mutex_lock(&instance->lock); ++ if (list_empty(&instance->cmd_list)) { ++ /* no more commands to process */ ++ mutex_unlock(&instance->lock); ++ break; ++ } ++ cmd = ++ list_first_entry(&instance->cmd_list, ++ struct sm_cmd_rsp_blk, ++ head); ++ list_move(&cmd->head, &instance->rsp_list); ++ cmd->sent = 1; ++ mutex_unlock(&instance->lock); ++ ++ /* Send the command */ ++ status = bcm2835_vchi_msg_queue( ++ instance->vchi_handle[0], ++ cmd->msg, cmd->length); ++ if (status) { ++ pr_err("%s: failed to queue message (%d)", ++ __func__, status); ++ } ++ ++ /* If no reply is needed then we're done */ ++ if (!cmd->wait) { ++ mutex_lock(&instance->lock); ++ list_del(&cmd->head); ++ mutex_unlock(&instance->lock); ++ vc_vchi_cmd_delete(instance, cmd); ++ continue; ++ } ++ ++ if (status) { ++ complete(&cmd->cmplt); ++ continue; ++ } ++ ++ } while (1); ++ ++ while (!vchi_msg_peek(instance->vchi_handle[0], ++ (void **)&reply, &reply_len, ++ VCHI_FLAGS_NONE)) { ++ if (reply->trans_id & 0x80000000) { ++ /* Async event or cmd from the VPU */ ++ if (instance->vpu_event) ++ instance->vpu_event( ++ instance, reply, ++ reply_len); ++ } else { ++ vc_sm_cma_vchi_rx_ack(instance, cmd, ++ reply, reply_len); ++ } ++ ++ vchi_msg_remove(instance->vchi_handle[0]); ++ } ++ ++ /* Go through the dead list and free them */ ++ mutex_lock(&instance->lock); ++ list_for_each_entry_safe(cmd, cmd_tmp, ++ &instance->dead_list, head) { ++ list_del(&cmd->head); ++ vc_vchi_cmd_delete(instance, cmd); ++ } ++ mutex_unlock(&instance->lock); ++ } ++ } ++ ++ return 0; ++} ++ ++static void vc_sm_cma_vchi_callback(void *param, ++ const VCHI_CALLBACK_REASON_T reason, ++ void *msg_handle) ++{ ++ struct sm_instance *instance = param; ++ ++ (void)msg_handle; ++ ++ switch (reason) { ++ case VCHI_CALLBACK_MSG_AVAILABLE: ++ complete(&instance->io_cmplt); ++ break; ++ ++ case VCHI_CALLBACK_SERVICE_CLOSED: ++ pr_info("%s: service CLOSED!!", __func__); ++ default: ++ break; ++ } ++} ++ ++struct sm_instance *vc_sm_cma_vchi_init(VCHI_INSTANCE_T vchi_instance, ++ unsigned int num_connections, ++ vpu_event_cb vpu_event) ++{ ++ u32 i; ++ struct sm_instance *instance; ++ int status; ++ ++ pr_debug("%s: start", __func__); ++ ++ if (num_connections > VCHI_MAX_NUM_CONNECTIONS) { ++ pr_err("%s: unsupported number of connections %u (max=%u)", ++ __func__, num_connections, VCHI_MAX_NUM_CONNECTIONS); ++ ++ goto err_null; ++ } ++ /* Allocate memory for this instance */ ++ instance = kzalloc(sizeof(*instance), GFP_KERNEL); ++ ++ /* Misc initialisations */ ++ mutex_init(&instance->lock); ++ init_completion(&instance->io_cmplt); ++ INIT_LIST_HEAD(&instance->cmd_list); ++ INIT_LIST_HEAD(&instance->rsp_list); ++ INIT_LIST_HEAD(&instance->dead_list); ++ INIT_LIST_HEAD(&instance->free_list); ++ sema_init(&instance->free_sema, SM_MAX_NUM_CMD_RSP_BLKS); ++ mutex_init(&instance->free_lock); ++ for (i = 0; i < SM_MAX_NUM_CMD_RSP_BLKS; i++) { ++ init_completion(&instance->free_blk[i].cmplt); ++ list_add(&instance->free_blk[i].head, &instance->free_list); ++ } ++ ++ /* Open the VCHI service connections */ ++ instance->num_connections = num_connections; ++ for (i = 0; i < num_connections; i++) { ++ SERVICE_CREATION_T params = { ++ .version = VCHI_VERSION_EX(VC_SM_VER, VC_SM_MIN_VER), ++ .service_id = VC_SM_SERVER_NAME, ++ .callback = vc_sm_cma_vchi_callback, ++ .callback_param = instance, ++ }; ++ ++ status = vchi_service_open(vchi_instance, ++ ¶ms, &instance->vchi_handle[i]); ++ if (status) { ++ pr_err("%s: failed to open VCHI service (%d)", ++ __func__, status); ++ ++ goto err_close_services; ++ } ++ } ++ ++ /* Create the thread which takes care of all io to/from videoocore. */ ++ instance->io_thread = kthread_create(&vc_sm_cma_vchi_videocore_io, ++ (void *)instance, "SMIO"); ++ if (!instance->io_thread) { ++ pr_err("%s: failed to create SMIO thread", __func__); ++ ++ goto err_close_services; ++ } ++ instance->vpu_event = vpu_event; ++ set_user_nice(instance->io_thread, -10); ++ wake_up_process(instance->io_thread); ++ ++ pr_debug("%s: success - instance 0x%x", __func__, ++ (unsigned int)instance); ++ return instance; ++ ++err_close_services: ++ for (i = 0; i < instance->num_connections; i++) { ++ if (instance->vchi_handle[i]) ++ vchi_service_close(instance->vchi_handle[i]); ++ } ++ kfree(instance); ++err_null: ++ pr_debug("%s: FAILED", __func__); ++ return NULL; ++} ++ ++int vc_sm_cma_vchi_stop(struct sm_instance **handle) ++{ ++ struct sm_instance *instance; ++ u32 i; ++ ++ if (!handle) { ++ pr_err("%s: invalid pointer to handle %p", __func__, handle); ++ goto lock; ++ } ++ ++ if (!*handle) { ++ pr_err("%s: invalid handle %p", __func__, *handle); ++ goto lock; ++ } ++ ++ instance = *handle; ++ ++ /* Close all VCHI service connections */ ++ for (i = 0; i < instance->num_connections; i++) { ++ s32 success; ++ ++ vchi_service_use(instance->vchi_handle[i]); ++ ++ success = vchi_service_close(instance->vchi_handle[i]); ++ } ++ ++ kfree(instance); ++ ++ *handle = NULL; ++ return 0; ++ ++lock: ++ return -EINVAL; ++} ++ ++static int vc_sm_cma_vchi_send_msg(struct sm_instance *handle, ++ enum vc_sm_msg_type msg_id, void *msg, ++ u32 msg_size, void *result, u32 result_size, ++ u32 *cur_trans_id, u8 wait_reply) ++{ ++ int status = 0; ++ struct sm_instance *instance = handle; ++ struct sm_cmd_rsp_blk *cmd_blk; ++ ++ if (!handle) { ++ pr_err("%s: invalid handle", __func__); ++ return -EINVAL; ++ } ++ if (!msg) { ++ pr_err("%s: invalid msg pointer", __func__); ++ return -EINVAL; ++ } ++ ++ cmd_blk = ++ vc_vchi_cmd_create(instance, msg_id, msg, msg_size, wait_reply); ++ if (!cmd_blk) { ++ pr_err("[%s]: failed to allocate global tracking resource", ++ __func__); ++ return -ENOMEM; ++ } ++ ++ if (cur_trans_id) ++ *cur_trans_id = cmd_blk->id; ++ ++ mutex_lock(&instance->lock); ++ list_add_tail(&cmd_blk->head, &instance->cmd_list); ++ mutex_unlock(&instance->lock); ++ complete(&instance->io_cmplt); ++ ++ if (!wait_reply) ++ /* We're done */ ++ return 0; ++ ++ /* Wait for the response */ ++ if (wait_for_completion_interruptible(&cmd_blk->cmplt)) { ++ mutex_lock(&instance->lock); ++ if (!cmd_blk->sent) { ++ list_del(&cmd_blk->head); ++ mutex_unlock(&instance->lock); ++ vc_vchi_cmd_delete(instance, cmd_blk); ++ return -ENXIO; ++ } ++ ++ list_move(&cmd_blk->head, &instance->dead_list); ++ mutex_unlock(&instance->lock); ++ complete(&instance->io_cmplt); ++ return -EINTR; /* We're done */ ++ } ++ ++ if (result && result_size) { ++ memcpy(result, cmd_blk->msg, result_size); ++ } else { ++ struct vc_sm_result_t *res = ++ (struct vc_sm_result_t *)cmd_blk->msg; ++ status = (res->success == 0) ? 0 : -ENXIO; ++ } ++ ++ mutex_lock(&instance->lock); ++ list_del(&cmd_blk->head); ++ mutex_unlock(&instance->lock); ++ vc_vchi_cmd_delete(instance, cmd_blk); ++ return status; ++} ++ ++int vc_sm_cma_vchi_free(struct sm_instance *handle, struct vc_sm_free_t *msg, ++ u32 *cur_trans_id) ++{ ++ return vc_sm_cma_vchi_send_msg(handle, VC_SM_MSG_TYPE_FREE, ++ msg, sizeof(*msg), 0, 0, cur_trans_id, 0); ++} ++ ++int vc_sm_cma_vchi_import(struct sm_instance *handle, struct vc_sm_import *msg, ++ struct vc_sm_import_result *result, u32 *cur_trans_id) ++{ ++ return vc_sm_cma_vchi_send_msg(handle, VC_SM_MSG_TYPE_IMPORT, ++ msg, sizeof(*msg), result, sizeof(*result), ++ cur_trans_id, 1); ++} ++ ++int vc_sm_cma_vchi_client_version(struct sm_instance *handle, ++ struct vc_sm_version *msg, ++ struct vc_sm_result_t *result, ++ u32 *cur_trans_id) ++{ ++ return vc_sm_cma_vchi_send_msg(handle, VC_SM_MSG_TYPE_CLIENT_VERSION, ++ //msg, sizeof(*msg), result, sizeof(*result), ++ //cur_trans_id, 1); ++ msg, sizeof(*msg), NULL, 0, ++ cur_trans_id, 0); ++} +--- /dev/null ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.h +@@ -0,0 +1,59 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++ ++/* ++ * VideoCore Shared Memory CMA allocator ++ * ++ * Copyright: 2018, Raspberry Pi (Trading) Ltd ++ * Copyright 2011-2012 Broadcom Corporation. All rights reserved. ++ * ++ * Based on vmcs_sm driver from Broadcom Corporation. ++ * ++ */ ++ ++#ifndef __VC_SM_CMA_VCHI_H__INCLUDED__ ++#define __VC_SM_CMA_VCHI_H__INCLUDED__ ++ ++#include "interface/vchi/vchi.h" ++ ++#include "vc_sm_defs.h" ++ ++/* ++ * Forward declare. ++ */ ++struct sm_instance; ++ ++typedef void (*vpu_event_cb)(struct sm_instance *instance, ++ struct vc_sm_result_t *reply, int reply_len); ++ ++/* ++ * Initialize the shared memory service, opens up vchi connection to talk to it. ++ */ ++struct sm_instance *vc_sm_cma_vchi_init(VCHI_INSTANCE_T vchi_instance, ++ unsigned int num_connections, ++ vpu_event_cb vpu_event); ++ ++/* ++ * Terminates the shared memory service. ++ */ ++int vc_sm_cma_vchi_stop(struct sm_instance **handle); ++ ++/* ++ * Ask the shared memory service to free up some memory that was previously ++ * allocated by the vc_sm_cma_vchi_alloc function call. ++ */ ++int vc_sm_cma_vchi_free(struct sm_instance *handle, struct vc_sm_free_t *msg, ++ u32 *cur_trans_id); ++ ++/* ++ * Import a contiguous block of memory and wrap it in a GPU MEM_HANDLE_T. ++ */ ++int vc_sm_cma_vchi_import(struct sm_instance *handle, struct vc_sm_import *msg, ++ struct vc_sm_import_result *result, ++ u32 *cur_trans_id); ++ ++int vc_sm_cma_vchi_client_version(struct sm_instance *handle, ++ struct vc_sm_version *msg, ++ struct vc_sm_result_t *result, ++ u32 *cur_trans_id); ++ ++#endif /* __VC_SM_CMA_VCHI_H__INCLUDED__ */ +--- /dev/null ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_defs.h +@@ -0,0 +1,298 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++ ++/* ++ * VideoCore Shared Memory CMA allocator ++ * ++ * Copyright: 2018, Raspberry Pi (Trading) Ltd ++ * ++ * Based on vc_sm_defs.h from the vmcs_sm driver Copyright Broadcom Corporation. ++ * All IPC messages are copied across to this file, even if the vc-sm-cma ++ * driver is not currently using them. ++ * ++ **************************************************************************** ++ */ ++ ++#ifndef __VC_SM_DEFS_H__INCLUDED__ ++#define __VC_SM_DEFS_H__INCLUDED__ ++ ++/* FourCC code used for VCHI connection */ ++#define VC_SM_SERVER_NAME MAKE_FOURCC("SMEM") ++ ++/* Maximum message length */ ++#define VC_SM_MAX_MSG_LEN (sizeof(union vc_sm_msg_union_t) + \ ++ sizeof(struct vc_sm_msg_hdr_t)) ++#define VC_SM_MAX_RSP_LEN (sizeof(union vc_sm_msg_union_t)) ++ ++/* Resource name maximum size */ ++#define VC_SM_RESOURCE_NAME 32 ++ ++/* ++ * Version to be reported to the VPU ++ * VPU assumes 0 (aka 1) which does not require the released callback, nor ++ * expect the client to handle VC_MEM_REQUESTS. ++ * Version 2 requires the released callback, and must support VC_MEM_REQUESTS. ++ */ ++#define VC_SM_PROTOCOL_VERSION 2 ++ ++enum vc_sm_msg_type { ++ /* Message types supported for HOST->VC direction */ ++ ++ /* Allocate shared memory block */ ++ VC_SM_MSG_TYPE_ALLOC, ++ /* Lock allocated shared memory block */ ++ VC_SM_MSG_TYPE_LOCK, ++ /* Unlock allocated shared memory block */ ++ VC_SM_MSG_TYPE_UNLOCK, ++ /* Unlock allocated shared memory block, do not answer command */ ++ VC_SM_MSG_TYPE_UNLOCK_NOANS, ++ /* Free shared memory block */ ++ VC_SM_MSG_TYPE_FREE, ++ /* Resize a shared memory block */ ++ VC_SM_MSG_TYPE_RESIZE, ++ /* Walk the allocated shared memory block(s) */ ++ VC_SM_MSG_TYPE_WALK_ALLOC, ++ ++ /* A previously applied action will need to be reverted */ ++ VC_SM_MSG_TYPE_ACTION_CLEAN, ++ ++ /* ++ * Import a physical address and wrap into a MEM_HANDLE_T. ++ * Release with VC_SM_MSG_TYPE_FREE. ++ */ ++ VC_SM_MSG_TYPE_IMPORT, ++ /* ++ *Tells VC the protocol version supported by this client. ++ * 2 supports the async/cmd messages from the VPU for final release ++ * of memory, and for VC allocations. ++ */ ++ VC_SM_MSG_TYPE_CLIENT_VERSION, ++ /* Response to VC request for memory */ ++ VC_SM_MSG_TYPE_VC_MEM_REQUEST_REPLY, ++ ++ /* ++ * Asynchronous/cmd messages supported for VC->HOST direction. ++ * Signalled by setting the top bit in vc_sm_result_t trans_id. ++ */ ++ ++ /* ++ * VC has finished with an imported memory allocation. ++ * Release any Linux reference counts on the underlying block. ++ */ ++ VC_SM_MSG_TYPE_RELEASED, ++ /* VC request for memory */ ++ VC_SM_MSG_TYPE_VC_MEM_REQUEST, ++ ++ VC_SM_MSG_TYPE_MAX ++}; ++ ++/* Type of memory to be allocated */ ++enum vc_sm_alloc_type_t { ++ VC_SM_ALLOC_CACHED, ++ VC_SM_ALLOC_NON_CACHED, ++}; ++ ++/* Message header for all messages in HOST->VC direction */ ++struct vc_sm_msg_hdr_t { ++ u32 type; ++ u32 trans_id; ++ u8 body[0]; ++ ++}; ++ ++/* Request to allocate memory (HOST->VC) */ ++struct vc_sm_alloc_t { ++ /* type of memory to allocate */ ++ enum vc_sm_alloc_type_t type; ++ /* byte amount of data to allocate per unit */ ++ u32 base_unit; ++ /* number of unit to allocate */ ++ u32 num_unit; ++ /* alignment to be applied on allocation */ ++ u32 alignment; ++ /* identity of who allocated this block */ ++ u32 allocator; ++ /* resource name (for easier tracking on vc side) */ ++ char name[VC_SM_RESOURCE_NAME]; ++ ++}; ++ ++/* Result of a requested memory allocation (VC->HOST) */ ++struct vc_sm_alloc_result_t { ++ /* Transaction identifier */ ++ u32 trans_id; ++ ++ /* Resource handle */ ++ u32 res_handle; ++ /* Pointer to resource buffer */ ++ u32 res_mem; ++ /* Resource base size (bytes) */ ++ u32 res_base_size; ++ /* Resource number */ ++ u32 res_num; ++ ++}; ++ ++/* Request to free a previously allocated memory (HOST->VC) */ ++struct vc_sm_free_t { ++ /* Resource handle (returned from alloc) */ ++ u32 res_handle; ++ /* Resource buffer (returned from alloc) */ ++ u32 res_mem; ++ ++}; ++ ++/* Request to lock a previously allocated memory (HOST->VC) */ ++struct vc_sm_lock_unlock_t { ++ /* Resource handle (returned from alloc) */ ++ u32 res_handle; ++ /* Resource buffer (returned from alloc) */ ++ u32 res_mem; ++ ++}; ++ ++/* Request to resize a previously allocated memory (HOST->VC) */ ++struct vc_sm_resize_t { ++ /* Resource handle (returned from alloc) */ ++ u32 res_handle; ++ /* Resource buffer (returned from alloc) */ ++ u32 res_mem; ++ /* Resource *new* size requested (bytes) */ ++ u32 res_new_size; ++ ++}; ++ ++/* Result of a requested memory lock (VC->HOST) */ ++struct vc_sm_lock_result_t { ++ /* Transaction identifier */ ++ u32 trans_id; ++ ++ /* Resource handle */ ++ u32 res_handle; ++ /* Pointer to resource buffer */ ++ u32 res_mem; ++ /* ++ * Pointer to former resource buffer if the memory ++ * was reallocated ++ */ ++ u32 res_old_mem; ++ ++}; ++ ++/* Generic result for a request (VC->HOST) */ ++struct vc_sm_result_t { ++ /* Transaction identifier */ ++ u32 trans_id; ++ ++ s32 success; ++ ++}; ++ ++/* Request to revert a previously applied action (HOST->VC) */ ++struct vc_sm_action_clean_t { ++ /* Action of interest */ ++ enum vc_sm_msg_type res_action; ++ /* Transaction identifier for the action of interest */ ++ u32 action_trans_id; ++ ++}; ++ ++/* Request to remove all data associated with a given allocator (HOST->VC) */ ++struct vc_sm_free_all_t { ++ /* Allocator identifier */ ++ u32 allocator; ++}; ++ ++/* Request to import memory (HOST->VC) */ ++struct vc_sm_import { ++ /* type of memory to allocate */ ++ enum vc_sm_alloc_type_t type; ++ /* pointer to the VC (ie physical) address of the allocated memory */ ++ u32 addr; ++ /* size of buffer */ ++ u32 size; ++ /* opaque handle returned in RELEASED messages */ ++ u32 kernel_id; ++ /* Allocator identifier */ ++ u32 allocator; ++ /* resource name (for easier tracking on vc side) */ ++ char name[VC_SM_RESOURCE_NAME]; ++}; ++ ++/* Result of a requested memory import (VC->HOST) */ ++struct vc_sm_import_result { ++ /* Transaction identifier */ ++ u32 trans_id; ++ ++ /* Resource handle */ ++ u32 res_handle; ++}; ++ ++/* Notification that VC has finished with an allocation (VC->HOST) */ ++struct vc_sm_released { ++ /* cmd type / trans_id */ ++ u32 cmd; ++ ++ /* pointer to the VC (ie physical) address of the allocated memory */ ++ u32 addr; ++ /* size of buffer */ ++ u32 size; ++ /* opaque handle returned in RELEASED messages */ ++ u32 kernel_id; ++ u32 vc_handle; ++}; ++ ++/* ++ * Client informing VC as to the protocol version it supports. ++ * >=2 requires the released callback, and supports VC asking for memory. ++ * Failure means that the firmware doesn't support this call, and therefore the ++ * client should either fail, or NOT rely on getting the released callback. ++ */ ++struct vc_sm_version { ++ u32 version; ++}; ++ ++/* Request FROM VideoCore for some memory */ ++struct vc_sm_vc_mem_request { ++ /* cmd type */ ++ u32 cmd; ++ ++ /* trans_id (from VPU) */ ++ u32 trans_id; ++ /* size of buffer */ ++ u32 size; ++ /* alignment of buffer */ ++ u32 align; ++ /* resource name (for easier tracking) */ ++ char name[VC_SM_RESOURCE_NAME]; ++}; ++ ++/* Response from the kernel to provide the VPU with some memory */ ++struct vc_sm_vc_mem_request_result { ++ /* Transaction identifier for the VPU */ ++ u32 trans_id; ++ /* pointer to the physical address of the allocated memory */ ++ u32 addr; ++ /* opaque handle returned in RELEASED messages */ ++ u32 kernel_id; ++}; ++ ++/* Union of ALL messages */ ++union vc_sm_msg_union_t { ++ struct vc_sm_alloc_t alloc; ++ struct vc_sm_alloc_result_t alloc_result; ++ struct vc_sm_free_t free; ++ struct vc_sm_lock_unlock_t lock_unlock; ++ struct vc_sm_action_clean_t action_clean; ++ struct vc_sm_resize_t resize; ++ struct vc_sm_lock_result_t lock_result; ++ struct vc_sm_result_t result; ++ struct vc_sm_free_all_t free_all; ++ struct vc_sm_import import; ++ struct vc_sm_import_result import_result; ++ struct vc_sm_version version; ++ struct vc_sm_released released; ++ struct vc_sm_vc_mem_request vc_request; ++ struct vc_sm_vc_mem_request_result vc_request_result; ++}; ++ ++#endif /* __VC_SM_DEFS_H__INCLUDED__ */ +--- /dev/null ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_knl.h +@@ -0,0 +1,28 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++ ++/* ++ * VideoCore Shared Memory CMA allocator ++ * ++ * Copyright: 2018, Raspberry Pi (Trading) Ltd ++ * ++ * Based on vc_sm_defs.h from the vmcs_sm driver Copyright Broadcom Corporation. ++ * ++ */ ++ ++#ifndef __VC_SM_KNL_H__INCLUDED__ ++#define __VC_SM_KNL_H__INCLUDED__ ++ ++#if !defined(__KERNEL__) ++#error "This interface is for kernel use only..." ++#endif ++ ++/* Free a previously allocated or imported shared memory handle and block. */ ++int vc_sm_cma_free(int handle); ++ ++/* Get an internal resource handle mapped from the external one. */ ++int vc_sm_cma_int_handle(int handle); ++ ++/* Import a block of memory into the GPU space. */ ++int vc_sm_cma_import_dmabuf(struct dma_buf *dmabuf, int *handle); ++ ++#endif /* __VC_SM_KNL_H__INCLUDED__ */ diff --git a/target/linux/brcm2708/patches-4.19/950-0273-staging-vc-sm-cma-Fixup-driver-for-older-VCHI-APIs.patch b/target/linux/brcm2708/patches-4.19/950-0273-staging-vc-sm-cma-Fixup-driver-for-older-VCHI-APIs.patch new file mode 100644 index 0000000000..6def1802fe --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0273-staging-vc-sm-cma-Fixup-driver-for-older-VCHI-APIs.patch @@ -0,0 +1,42 @@ +From 0a36165c509c40a0551831efdbd2e957cba12f80 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 30 Oct 2018 11:42:48 +0000 +Subject: [PATCH 273/725] staging: vc-sm-cma: Fixup driver for older VCHI APIs + +Original patch was based off staging which included some cleanups +of the VCHI APIs. Those aren't present here, so switch back to +the older API. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 2 +- + drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c | 5 +++++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -632,7 +632,7 @@ static void vc_sm_connected_init(void) + goto err_free_mem; + } + +- ret = vchi_connect(vchi_instance); ++ ret = vchi_connect(NULL, 0, vchi_instance); + if (ret) { + pr_err("[%s]: failed to connect VCHI instance (ret=%d)\n", + __func__, ret); +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c +@@ -325,8 +325,13 @@ struct sm_instance *vc_sm_cma_vchi_init( + SERVICE_CREATION_T params = { + .version = VCHI_VERSION_EX(VC_SM_VER, VC_SM_MIN_VER), + .service_id = VC_SM_SERVER_NAME, ++ .rx_fifo_size = 0, ++ .tx_fifo_size = 0, + .callback = vc_sm_cma_vchi_callback, + .callback_param = instance, ++ .want_unaligned_bulk_rx = 0, ++ .want_unaligned_bulk_tx = 0, ++ .want_crc = 0 + }; + + status = vchi_service_open(vchi_instance, diff --git a/target/linux/brcm2708/patches-4.19/950-0273-staging-vc04_services-Support-sending-data-to-MMAL-p.patch b/target/linux/brcm2708/patches-4.19/950-0273-staging-vc04_services-Support-sending-data-to-MMAL-p.patch deleted file mode 100644 index 4d2a20fa5f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0273-staging-vc04_services-Support-sending-data-to-MMAL-p.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 6a64ea8c2097cbe835fae209906a26c9a1896742 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 24 Sep 2018 18:26:02 +0100 -Subject: [PATCH 273/703] staging: vc04_services: Support sending data to MMAL - ports - -Add the ability to send data to ports. This only supports -zero copy mode as the required bulk transfer setup calls -are not done. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/vchiq-mmal/mmal-vchiq.c | 18 +++++++++++++----- - 1 file changed, 13 insertions(+), 5 deletions(-) - ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -428,11 +428,19 @@ buffer_from_host(struct vchiq_mmal_insta - m.u.buffer_from_host.buffer_header.data = - (u32)(unsigned long)buf->buffer; - m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size; -- m.u.buffer_from_host.buffer_header.length = 0; /* nothing used yet */ -- m.u.buffer_from_host.buffer_header.offset = 0; /* no offset */ -- m.u.buffer_from_host.buffer_header.flags = 0; /* no flags */ -- m.u.buffer_from_host.buffer_header.pts = MMAL_TIME_UNKNOWN; -- m.u.buffer_from_host.buffer_header.dts = MMAL_TIME_UNKNOWN; -+ if (port->type == MMAL_PORT_TYPE_OUTPUT) { -+ m.u.buffer_from_host.buffer_header.length = 0; -+ m.u.buffer_from_host.buffer_header.offset = 0; -+ m.u.buffer_from_host.buffer_header.flags = 0; -+ m.u.buffer_from_host.buffer_header.pts = MMAL_TIME_UNKNOWN; -+ m.u.buffer_from_host.buffer_header.dts = MMAL_TIME_UNKNOWN; -+ } else { -+ m.u.buffer_from_host.buffer_header.length = buf->length; -+ m.u.buffer_from_host.buffer_header.offset = 0; -+ m.u.buffer_from_host.buffer_header.flags = buf->mmal_flags; -+ m.u.buffer_from_host.buffer_header.pts = buf->pts; -+ m.u.buffer_from_host.buffer_header.dts = buf->dts; -+ } - - /* clear buffer type sepecific data */ - memset(&m.u.buffer_from_host.buffer_header_type_specific, 0, diff --git a/target/linux/brcm2708/patches-4.19/950-0274-staging-vc04_services-Fixup-vchiq-mmal-include-order.patch b/target/linux/brcm2708/patches-4.19/950-0274-staging-vc04_services-Fixup-vchiq-mmal-include-order.patch deleted file mode 100644 index 4a591eb42f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0274-staging-vc04_services-Fixup-vchiq-mmal-include-order.patch +++ /dev/null @@ -1,36 +0,0 @@ -From e84380e8791d0a7a6cc4057269f2a2885a4ae8c1 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 25 Sep 2018 16:57:40 +0100 -Subject: [PATCH 274/703] staging: vc04_services: Fixup vchiq-mmal include - ordering - -There were dependencies on including the headers in the correct -order. Fix up the headers so that they include the other -headers that they depend on themselves. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h | 1 + - drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h | 1 + - 2 files changed, 2 insertions(+) - ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h -@@ -38,6 +38,7 @@ - #include "mmal-msg-common.h" - #include "mmal-msg-format.h" - #include "mmal-msg-port.h" -+#include "mmal-vchiq.h" - - enum mmal_msg_type { - MMAL_MSG_TYPE_QUIT = 1, ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h -@@ -16,6 +16,7 @@ - #ifndef MMAL_VCHIQ_H - #define MMAL_VCHIQ_H - -+#include "mmal-common.h" - #include "mmal-msg-format.h" - - #define MAX_PORT_COUNT 4 diff --git a/target/linux/brcm2708/patches-4.19/950-0274-staging-vc04_services-Use-vc-sm-cma-to-support-zero-.patch b/target/linux/brcm2708/patches-4.19/950-0274-staging-vc04_services-Use-vc-sm-cma-to-support-zero-.patch new file mode 100644 index 0000000000..cfc6ebee4e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0274-staging-vc04_services-Use-vc-sm-cma-to-support-zero-.patch @@ -0,0 +1,163 @@ +From b821e47df883a3325062a68cbe1504bf62129fd6 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 25 Sep 2018 16:07:55 +0100 +Subject: [PATCH 274/725] staging: vc04_services: Use vc-sm-cma to support zero + copy + +With the vc-sm-cma driver we can support zero copy of buffers between +the kernel and VPU. Add this support to vchiq-mmal. + +Signed-off-by: Dave Stevenson +--- + .../staging/vc04_services/vchiq-mmal/Kconfig | 1 + + .../vc04_services/vchiq-mmal/mmal-common.h | 4 ++ + .../vc04_services/vchiq-mmal/mmal-vchiq.c | 66 ++++++++++++++++++- + .../vc04_services/vchiq-mmal/mmal-vchiq.h | 1 + + 4 files changed, 70 insertions(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/vchiq-mmal/Kconfig ++++ b/drivers/staging/vc04_services/vchiq-mmal/Kconfig +@@ -2,6 +2,7 @@ config BCM2835_VCHIQ_MMAL + tristate "BCM2835 MMAL VCHIQ service" + depends on (ARCH_BCM2835 || COMPILE_TEST) + select BCM2835_VCHIQ ++ select BCM_VC_SM_CMA + help + Enables the MMAL API over VCHIQ as used for the + majority of the multimedia services on VideoCore. +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h +@@ -51,6 +51,10 @@ struct mmal_buffer { + + struct mmal_msg_context *msg_context; + ++ struct dma_buf *dma_buf;/* Exported dmabuf fd from videobuf2 */ ++ int vcsm_handle; /* VCSM handle having imported the dmabuf */ ++ u32 vc_handle; /* VC handle to that dmabuf */ ++ + u32 cmd; /* MMAL command. 0=data. */ + unsigned long length; + u32 mmal_flags; +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +@@ -27,9 +27,12 @@ + #include + + #include "mmal-common.h" ++#include "mmal-parameters.h" + #include "mmal-vchiq.h" + #include "mmal-msg.h" + ++#include "vc-sm-cma/vc_sm_knl.h" ++ + #define USE_VCHIQ_ARM + #include "interface/vchi/vchi.h" + +@@ -425,8 +428,13 @@ buffer_from_host(struct vchiq_mmal_insta + + /* buffer header */ + m.u.buffer_from_host.buffer_header.cmd = 0; +- m.u.buffer_from_host.buffer_header.data = +- (u32)(unsigned long)buf->buffer; ++ if (port->zero_copy) { ++ m.u.buffer_from_host.buffer_header.data = buf->vc_handle; ++ } else { ++ m.u.buffer_from_host.buffer_header.data = ++ (u32)(unsigned long)buf->buffer; ++ } ++ + m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size; + if (port->type == MMAL_PORT_TYPE_OUTPUT) { + m.u.buffer_from_host.buffer_header.length = 0; +@@ -591,6 +599,22 @@ static void buffer_to_host_cb(struct vch + + msg_context->u.bulk.status = msg->h.status; + ++ } else if (msg->u.buffer_from_host.is_zero_copy) { ++ /* ++ * Zero copy buffer, so nothing to do. ++ * Copy buffer info and make callback. ++ */ ++ msg_context->u.bulk.buffer_used = ++ msg->u.buffer_from_host.buffer_header.length; ++ msg_context->u.bulk.mmal_flags = ++ msg->u.buffer_from_host.buffer_header.flags; ++ msg_context->u.bulk.dts = ++ msg->u.buffer_from_host.buffer_header.dts; ++ msg_context->u.bulk.pts = ++ msg->u.buffer_from_host.buffer_header.pts; ++ msg_context->u.bulk.cmd = ++ msg->u.buffer_from_host.buffer_header.cmd; ++ + } else if (msg->u.buffer_from_host.buffer_header.length == 0) { + /* empty buffer */ + if (msg->u.buffer_from_host.buffer_header.flags & +@@ -1538,6 +1562,9 @@ int vchiq_mmal_port_parameter_set(struct + + mutex_unlock(&instance->vchiq_mutex); + ++ if (parameter == MMAL_PARAMETER_ZERO_COPY && !ret) ++ port->zero_copy = !!(*(bool *)value); ++ + return ret; + } + EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_set); +@@ -1706,6 +1733,31 @@ int vchiq_mmal_submit_buffer(struct vchi + unsigned long flags = 0; + int ret; + ++ /* ++ * We really want to do this in mmal_vchi_buffer_init but can't as ++ * videobuf2 won't let us have the dmabuf there. ++ */ ++ if (port->zero_copy && buffer->dma_buf && !buffer->vcsm_handle) { ++ pr_debug("%s: import dmabuf %p\n", __func__, buffer->dma_buf); ++ ret = vc_sm_cma_import_dmabuf(buffer->dma_buf, ++ &buffer->vcsm_handle); ++ if (ret) { ++ pr_err("%s: vc_sm_import_dmabuf_fd failed, ret %d\n", ++ __func__, ret); ++ return ret; ++ } ++ ++ buffer->vc_handle = vc_sm_cma_int_handle(buffer->vcsm_handle); ++ if (!buffer->vc_handle) { ++ pr_err("%s: vc_sm_int_handle failed %d\n", ++ __func__, ret); ++ vc_sm_cma_free(buffer->vcsm_handle); ++ return ret; ++ } ++ pr_debug("%s: import dmabuf %p - got vc handle %08X\n", ++ __func__, buffer->dma_buf, buffer->vc_handle); ++ } ++ + ret = buffer_from_host(instance, port, buffer); + if (ret == -EINVAL) { + /* Port is disabled. Queue for when it is enabled. */ +@@ -1739,6 +1791,16 @@ int mmal_vchi_buffer_cleanup(struct mmal + release_msg_context(msg_context); + buf->msg_context = NULL; + ++ if (buf->vcsm_handle) { ++ int ret; ++ ++ pr_debug("%s: vc_sm_cma_free on handle %08X\n", __func__, ++ buf->vcsm_handle); ++ ret = vc_sm_cma_free(buf->vcsm_handle); ++ if (ret) ++ pr_err("%s: vcsm_free failed, ret %d\n", __func__, ret); ++ buf->vcsm_handle = 0; ++ } + return 0; + } + EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup); +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h +@@ -49,6 +49,7 @@ typedef void (*vchiq_mmal_buffer_cb)( + + struct vchiq_mmal_port { + u32 enabled:1; ++ u32 zero_copy:1; + u32 handle; + u32 type; /* port type, cached to use on port info set */ + u32 index; /* port index, cached to use on port info set */ diff --git a/target/linux/brcm2708/patches-4.19/950-0275-media-videobuf2-Allow-exporting-of-a-struct-dmabuf.patch b/target/linux/brcm2708/patches-4.19/950-0275-media-videobuf2-Allow-exporting-of-a-struct-dmabuf.patch new file mode 100644 index 0000000000..b444ace063 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0275-media-videobuf2-Allow-exporting-of-a-struct-dmabuf.patch @@ -0,0 +1,83 @@ +From 46f9f09f99867b8211974aa2426bd68fe5ddb2d6 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 29 Oct 2018 17:57:45 +0000 +Subject: [PATCH 275/725] media: videobuf2: Allow exporting of a struct dmabuf + +videobuf2 only allowed exporting a dmabuf as a file descriptor, +but there are instances where having the struct dma_buf is +useful within the kernel. + +Split the current implementation into two, one step which +exports a struct dma_buf, and the second which converts that +into an fd. + +Signed-off-by: Dave Stevenson +--- + .../media/common/videobuf2/videobuf2-core.c | 21 ++++++++++++++++--- + include/media/videobuf2-core.h | 15 +++++++++++++ + 2 files changed, 33 insertions(+), 3 deletions(-) + +--- a/drivers/media/common/videobuf2/videobuf2-core.c ++++ b/drivers/media/common/videobuf2/videobuf2-core.c +@@ -1851,12 +1851,12 @@ static int __find_plane_by_offset(struct + return -EINVAL; + } + +-int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, +- unsigned int index, unsigned int plane, unsigned int flags) ++int vb2_core_expbuf_dmabuf(struct vb2_queue *q, unsigned int type, ++ unsigned int index, unsigned int plane, ++ unsigned int flags, struct dma_buf **dmabuf) + { + struct vb2_buffer *vb = NULL; + struct vb2_plane *vb_plane; +- int ret; + struct dma_buf *dbuf; + + if (q->memory != VB2_MEMORY_MMAP) { +@@ -1906,6 +1906,21 @@ int vb2_core_expbuf(struct vb2_queue *q, + return -EINVAL; + } + ++ *dmabuf = dbuf; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(vb2_core_expbuf_dmabuf); ++ ++int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, ++ unsigned int index, unsigned int plane, unsigned int flags) ++{ ++ struct dma_buf *dbuf; ++ int ret; ++ ++ ret = vb2_core_expbuf_dmabuf(q, type, index, plane, flags, &dbuf); ++ if (ret) ++ return ret; ++ + ret = dma_buf_fd(dbuf, flags & ~O_ACCMODE); + if (ret < 0) { + dprintk(3, "buffer %d, plane %d failed to export (%d)\n", +--- a/include/media/videobuf2-core.h ++++ b/include/media/videobuf2-core.h +@@ -825,6 +825,21 @@ int vb2_core_streamon(struct vb2_queue * + int vb2_core_streamoff(struct vb2_queue *q, unsigned int type); + + /** ++ * vb2_core_expbuf_dmabuf() - Export a buffer as a dma_buf structure ++ * @q: videobuf2 queue ++ * @type: buffer type ++ * @index: id number of the buffer ++ * @plane: index of the plane to be exported, 0 for single plane queues ++ * @flags: flags for newly created file, currently only O_CLOEXEC is ++ * supported, refer to manual of open syscall for more details ++ * @dmabuf: Returns the dmabuf pointer ++ * ++ */ ++int vb2_core_expbuf_dmabuf(struct vb2_queue *q, unsigned int type, ++ unsigned int index, unsigned int plane, ++ unsigned int flags, struct dma_buf **dmabuf); ++ ++/** + * vb2_core_expbuf() - Export a buffer as a file descriptor. + * @q: pointer to &struct vb2_queue with videobuf2 queue. + * @fd: pointer to the file descriptor associated with DMABUF diff --git a/target/linux/brcm2708/patches-4.19/950-0275-staging-vc04_services-Add-new-vc-sm-cma-driver.patch b/target/linux/brcm2708/patches-4.19/950-0275-staging-vc04_services-Add-new-vc-sm-cma-driver.patch deleted file mode 100644 index 8437fb2fd2..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0275-staging-vc04_services-Add-new-vc-sm-cma-driver.patch +++ /dev/null @@ -1,1881 +0,0 @@ -From b9607d33b3efa9a85268961cadc6df5b5c9b042b Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 25 Sep 2018 10:27:11 +0100 -Subject: [PATCH 275/703] staging: vc04_services: Add new vc-sm-cma driver - -This new driver allows contiguous memory blocks to be imported -into the VideoCore VPU memory map, and manages the lifetime of -those objects, only releasing the source dmabuf once the VPU has -confirmed it has finished with it. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/Kconfig | 1 + - drivers/staging/vc04_services/Makefile | 1 + - .../staging/vc04_services/vc-sm-cma/Kconfig | 10 + - .../staging/vc04_services/vc-sm-cma/Makefile | 8 + - drivers/staging/vc04_services/vc-sm-cma/TODO | 2 + - .../staging/vc04_services/vc-sm-cma/vc_sm.c | 838 ++++++++++++++++++ - .../staging/vc04_services/vc-sm-cma/vc_sm.h | 59 ++ - .../vc04_services/vc-sm-cma/vc_sm_cma_vchi.c | 498 +++++++++++ - .../vc04_services/vc-sm-cma/vc_sm_cma_vchi.h | 59 ++ - .../vc04_services/vc-sm-cma/vc_sm_defs.h | 298 +++++++ - .../vc04_services/vc-sm-cma/vc_sm_knl.h | 28 + - 11 files changed, 1802 insertions(+) - create mode 100644 drivers/staging/vc04_services/vc-sm-cma/Kconfig - create mode 100644 drivers/staging/vc04_services/vc-sm-cma/Makefile - create mode 100644 drivers/staging/vc04_services/vc-sm-cma/TODO - create mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm.c - create mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm.h - create mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c - create mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.h - create mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm_defs.h - create mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm_knl.h - ---- a/drivers/staging/vc04_services/Kconfig -+++ b/drivers/staging/vc04_services/Kconfig -@@ -22,6 +22,7 @@ source "drivers/staging/vc04_services/bc - - source "drivers/staging/vc04_services/bcm2835-camera/Kconfig" - source "drivers/staging/vc04_services/vchiq-mmal/Kconfig" -+source "drivers/staging/vc04_services/vc-sm-cma/Kconfig" - - endif - ---- a/drivers/staging/vc04_services/Makefile -+++ b/drivers/staging/vc04_services/Makefile -@@ -13,6 +13,7 @@ vchiq-objs := \ - obj-$(CONFIG_SND_BCM2835) += bcm2835-audio/ - obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-camera/ - obj-$(CONFIG_BCM2835_VCHIQ_MMAL) += vchiq-mmal/ -+obj-$(CONFIG_BCM_VC_SM_CMA) += vc-sm-cma/ - - ccflags-y += -Idrivers/staging/vc04_services -D__VCCOREVER__=0x04000000 - ---- /dev/null -+++ b/drivers/staging/vc04_services/vc-sm-cma/Kconfig -@@ -0,0 +1,10 @@ -+config BCM_VC_SM_CMA -+ tristate "VideoCore Shared Memory (CMA) driver" -+ depends on BCM2835_VCHIQ -+ select RBTREE -+ select DMA_SHARED_BUFFER -+ help -+ Say Y here to enable the shared memory interface that -+ supports sharing dmabufs with VideoCore. -+ This operates over the VCHIQ interface to a service -+ running on VideoCore. ---- /dev/null -+++ b/drivers/staging/vc04_services/vc-sm-cma/Makefile -@@ -0,0 +1,8 @@ -+ccflags-y += -Idrivers/staging/vc04_services -Idrivers/staging/vc04_services/interface/vchi -Idrivers/staging/vc04_services/interface/vchiq_arm -+# -I"drivers/staging/android/ion/" -I"$(srctree)/fs/" -+ccflags-y += -D__VCCOREVER__=0 -+ -+vc-sm-cma-$(CONFIG_BCM_VC_SM_CMA) := \ -+ vc_sm.o vc_sm_cma_vchi.o -+ -+obj-$(CONFIG_BCM_VC_SM_CMA) += vc-sm-cma.o ---- /dev/null -+++ b/drivers/staging/vc04_services/vc-sm-cma/TODO -@@ -0,0 +1,2 @@ -+1) Convert to a platform driver. -+ ---- /dev/null -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -0,0 +1,838 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * VideoCore Shared Memory driver using CMA. -+ * -+ * Copyright: 2018, Raspberry Pi (Trading) Ltd -+ * Dave Stevenson -+ * -+ * Based on vmcs_sm driver from Broadcom Corporation for some API, -+ * and taking some code for CMA/dmabuf handling from the Android Ion -+ * driver (Google/Linaro). -+ * -+ * This is cut down version to only support import of dma_bufs from -+ * other kernel drivers. A more complete implementation of the old -+ * vmcs_sm functionality can follow later. -+ * -+ */ -+ -+/* ---- Include Files ----------------------------------------------------- */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "vchiq_connected.h" -+#include "vc_sm_cma_vchi.h" -+ -+#include "vc_sm.h" -+#include "vc_sm_knl.h" -+ -+/* ---- Private Constants and Types --------------------------------------- */ -+ -+#define DEVICE_NAME "vcsm-cma" -+#define DEVICE_MINOR 0 -+ -+#define VC_SM_RESOURCE_NAME_DEFAULT "sm-host-resource" -+ -+#define VC_SM_DIR_ROOT_NAME "vcsm-cma" -+#define VC_SM_STATE "state" -+ -+/* Private file data associated with each opened device. */ -+struct vc_sm_privdata_t { -+ pid_t pid; /* PID of creator. */ -+ -+ int restart_sys; /* Tracks restart on interrupt. */ -+ enum vc_sm_msg_type int_action; /* Interrupted action. */ -+ u32 int_trans_id; /* Interrupted transaction. */ -+}; -+ -+typedef int (*VC_SM_SHOW) (struct seq_file *s, void *v); -+struct sm_pde_t { -+ VC_SM_SHOW show; /* Debug fs function hookup. */ -+ struct dentry *dir_entry; /* Debug fs directory entry. */ -+ void *priv_data; /* Private data */ -+}; -+ -+/* Global state information. */ -+struct sm_state_t { -+ struct platform_device *pdev; -+ -+ struct miscdevice dev; -+ struct sm_instance *sm_handle; /* Handle for videocore service. */ -+ -+ struct mutex map_lock; /* Global map lock. */ -+ struct list_head buffer_list; /* List of buffer. */ -+ -+ struct vc_sm_privdata_t *data_knl; /* Kernel internal data tracking. */ -+ struct dentry *dir_root; /* Debug fs entries root. */ -+ struct sm_pde_t dir_state; /* Debug fs entries state sub-tree. */ -+ -+ bool require_released_callback; /* VPU will send a released msg when it -+ * has finished with a resource. -+ */ -+ u32 int_trans_id; /* Interrupted transaction. */ -+}; -+ -+/* ---- Private Variables ----------------------------------------------- */ -+ -+static struct sm_state_t *sm_state; -+static int sm_inited; -+ -+/* ---- Private Function Prototypes -------------------------------------- */ -+ -+/* ---- Private Functions ------------------------------------------------ */ -+ -+static int vc_sm_cma_seq_file_show(struct seq_file *s, void *v) -+{ -+ struct sm_pde_t *sm_pde; -+ -+ sm_pde = (struct sm_pde_t *)(s->private); -+ -+ if (sm_pde && sm_pde->show) -+ sm_pde->show(s, v); -+ -+ return 0; -+} -+ -+static int vc_sm_cma_single_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, vc_sm_cma_seq_file_show, inode->i_private); -+} -+ -+static const struct file_operations vc_sm_cma_debug_fs_fops = { -+ .open = vc_sm_cma_single_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+static int vc_sm_cma_global_state_show(struct seq_file *s, void *v) -+{ -+ struct vc_sm_buffer *resource = NULL; -+ int resource_count = 0; -+ -+ if (!sm_state) -+ return 0; -+ -+ seq_printf(s, "\nVC-ServiceHandle 0x%x\n", -+ (unsigned int)sm_state->sm_handle); -+ -+ /* Log all applicable mapping(s). */ -+ -+ mutex_lock(&sm_state->map_lock); -+ seq_puts(s, "\nResources\n"); -+ if (!list_empty(&sm_state->buffer_list)) { -+ list_for_each_entry(resource, &sm_state->buffer_list, -+ global_buffer_list) { -+ resource_count++; -+ -+ seq_printf(s, "\nResource %p\n", -+ resource); -+ seq_printf(s, " NAME %s\n", -+ resource->name); -+ seq_printf(s, " SIZE %d\n", -+ resource->size); -+ seq_printf(s, " DMABUF %p\n", -+ resource->dma_buf); -+ seq_printf(s, " ATTACH %p\n", -+ resource->attach); -+ seq_printf(s, " SG_TABLE %p\n", -+ resource->sg_table); -+ seq_printf(s, " SGT %p\n", -+ resource->sgt); -+ seq_printf(s, " DMA_ADDR %pad\n", -+ &resource->dma_addr); -+ seq_printf(s, " VC_HANDLE %08x\n", -+ resource->vc_handle); -+ seq_printf(s, " VC_MAPPING %d\n", -+ resource->vpu_state); -+ } -+ } -+ seq_printf(s, "\n\nTotal resource count: %d\n\n", resource_count); -+ -+ mutex_unlock(&sm_state->map_lock); -+ -+ return 0; -+} -+ -+/* -+ * Adds a buffer to the private data list which tracks all the allocated -+ * data. -+ */ -+static void vc_sm_add_resource(struct vc_sm_privdata_t *privdata, -+ struct vc_sm_buffer *buffer) -+{ -+ mutex_lock(&sm_state->map_lock); -+ list_add(&buffer->global_buffer_list, &sm_state->buffer_list); -+ mutex_unlock(&sm_state->map_lock); -+ -+ pr_debug("[%s]: added buffer %p (name %s, size %d)\n", -+ __func__, buffer, buffer->name, buffer->size); -+} -+ -+/* -+ * Release an allocation. -+ * All refcounting is done via the dma buf object. -+ */ -+static void vc_sm_release_resource(struct vc_sm_buffer *buffer, int force) -+{ -+ mutex_lock(&sm_state->map_lock); -+ mutex_lock(&buffer->lock); -+ -+ pr_debug("[%s]: buffer %p (name %s, size %d)\n", -+ __func__, buffer, buffer->name, buffer->size); -+ -+ if (buffer->vc_handle && buffer->vpu_state == VPU_MAPPED) { -+ struct vc_sm_free_t free = { buffer->vc_handle, 0 }; -+ int status = vc_sm_cma_vchi_free(sm_state->sm_handle, &free, -+ &sm_state->int_trans_id); -+ if (status != 0 && status != -EINTR) { -+ pr_err("[%s]: failed to free memory on videocore (status: %u, trans_id: %u)\n", -+ __func__, status, sm_state->int_trans_id); -+ } -+ -+ if (sm_state->require_released_callback) { -+ /* Need to wait for the VPU to confirm the free */ -+ -+ /* Retain a reference on this until the VPU has -+ * released it -+ */ -+ buffer->vpu_state = VPU_UNMAPPING; -+ goto defer; -+ } -+ buffer->vpu_state = VPU_NOT_MAPPED; -+ buffer->vc_handle = 0; -+ } -+ if (buffer->vc_handle) { -+ /* We've sent the unmap request but not had the response. */ -+ pr_err("[%s]: Waiting for VPU unmap response on %p\n", -+ __func__, buffer); -+ goto defer; -+ } -+ if (buffer->in_use) { -+ /* Don't release dmabuf here - we await the release */ -+ pr_err("[%s]: buffer %p is still in use\n", -+ __func__, buffer); -+ goto defer; -+ } -+ -+ /* Handle cleaning up imported dmabufs */ -+ if (buffer->sgt) { -+ dma_buf_unmap_attachment(buffer->attach, buffer->sgt, -+ DMA_BIDIRECTIONAL); -+ buffer->sgt = NULL; -+ } -+ if (buffer->attach) { -+ dma_buf_detach(buffer->dma_buf, buffer->attach); -+ buffer->attach = NULL; -+ } -+ -+ /* Release the dma_buf (whether ours or imported) */ -+ if (buffer->import_dma_buf) { -+ dma_buf_put(buffer->import_dma_buf); -+ buffer->import_dma_buf = NULL; -+ buffer->dma_buf = NULL; -+ } else if (buffer->dma_buf) { -+ dma_buf_put(buffer->dma_buf); -+ buffer->dma_buf = NULL; -+ } -+ -+ if (buffer->sg_table && !buffer->import_dma_buf) { -+ /* Our own allocation that we need to dma_unmap_sg */ -+ dma_unmap_sg(&sm_state->pdev->dev, buffer->sg_table->sgl, -+ buffer->sg_table->nents, DMA_BIDIRECTIONAL); -+ } -+ -+ /* Free the local resource. Start by removing it from the list */ -+ buffer->private = NULL; -+ list_del(&buffer->global_buffer_list); -+ -+ mutex_unlock(&buffer->lock); -+ mutex_unlock(&sm_state->map_lock); -+ -+ mutex_destroy(&buffer->lock); -+ -+ kfree(buffer); -+ return; -+ -+defer: -+ mutex_unlock(&buffer->lock); -+ mutex_unlock(&sm_state->map_lock); -+} -+ -+/* Create support for private data tracking. */ -+static struct vc_sm_privdata_t *vc_sm_cma_create_priv_data(pid_t id) -+{ -+ char alloc_name[32]; -+ struct vc_sm_privdata_t *file_data = NULL; -+ -+ /* Allocate private structure. */ -+ file_data = kzalloc(sizeof(*file_data), GFP_KERNEL); -+ -+ if (!file_data) -+ return NULL; -+ -+ snprintf(alloc_name, sizeof(alloc_name), "%d", id); -+ -+ file_data->pid = id; -+ -+ return file_data; -+} -+ -+/* Dma_buf operations for chaining through to an imported dma_buf */ -+static -+int vc_sm_import_dma_buf_attach(struct dma_buf *dmabuf, -+ struct dma_buf_attachment *attachment) -+{ -+ struct vc_sm_buffer *res = dmabuf->priv; -+ -+ if (!res->import_dma_buf) -+ return -EINVAL; -+ return res->import_dma_buf->ops->attach(res->import_dma_buf, -+ attachment); -+} -+ -+static -+void vc_sm_import_dma_buf_detatch(struct dma_buf *dmabuf, -+ struct dma_buf_attachment *attachment) -+{ -+ struct vc_sm_buffer *res = dmabuf->priv; -+ -+ if (!res->import_dma_buf) -+ return; -+ res->import_dma_buf->ops->detach(res->import_dma_buf, attachment); -+} -+ -+static -+struct sg_table *vc_sm_import_map_dma_buf(struct dma_buf_attachment *attachment, -+ enum dma_data_direction direction) -+{ -+ struct vc_sm_buffer *res = attachment->dmabuf->priv; -+ -+ if (!res->import_dma_buf) -+ return NULL; -+ return res->import_dma_buf->ops->map_dma_buf(attachment, direction); -+} -+ -+static -+void vc_sm_import_unmap_dma_buf(struct dma_buf_attachment *attachment, -+ struct sg_table *table, -+ enum dma_data_direction direction) -+{ -+ struct vc_sm_buffer *res = attachment->dmabuf->priv; -+ -+ if (!res->import_dma_buf) -+ return; -+ res->import_dma_buf->ops->unmap_dma_buf(attachment, table, direction); -+} -+ -+static -+int vc_sm_import_dmabuf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) -+{ -+ struct vc_sm_buffer *res = dmabuf->priv; -+ -+ pr_debug("%s: mmap dma_buf %p, res %p, imported db %p\n", __func__, -+ dmabuf, res, res->import_dma_buf); -+ if (!res->import_dma_buf) { -+ pr_err("%s: mmap dma_buf %p- not an imported buffer\n", -+ __func__, dmabuf); -+ return -EINVAL; -+ } -+ return res->import_dma_buf->ops->mmap(res->import_dma_buf, vma); -+} -+ -+static -+void vc_sm_import_dma_buf_release(struct dma_buf *dmabuf) -+{ -+ struct vc_sm_buffer *res = dmabuf->priv; -+ -+ pr_debug("%s: Relasing dma_buf %p\n", __func__, dmabuf); -+ if (!res->import_dma_buf) -+ return; -+ -+ res->in_use = 0; -+ -+ vc_sm_release_resource(res, 0); -+} -+ -+static -+void *vc_sm_import_dma_buf_kmap(struct dma_buf *dmabuf, -+ unsigned long offset) -+{ -+ struct vc_sm_buffer *res = dmabuf->priv; -+ -+ if (!res->import_dma_buf) -+ return NULL; -+ return res->import_dma_buf->ops->map(res->import_dma_buf, -+ offset); -+} -+ -+static -+void vc_sm_import_dma_buf_kunmap(struct dma_buf *dmabuf, -+ unsigned long offset, void *ptr) -+{ -+ struct vc_sm_buffer *res = dmabuf->priv; -+ -+ if (!res->import_dma_buf) -+ return; -+ res->import_dma_buf->ops->unmap(res->import_dma_buf, -+ offset, ptr); -+} -+ -+static -+int vc_sm_import_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, -+ enum dma_data_direction direction) -+{ -+ struct vc_sm_buffer *res = dmabuf->priv; -+ -+ if (!res->import_dma_buf) -+ return -EINVAL; -+ return res->import_dma_buf->ops->begin_cpu_access(res->import_dma_buf, -+ direction); -+} -+ -+static -+int vc_sm_import_dma_buf_end_cpu_access(struct dma_buf *dmabuf, -+ enum dma_data_direction direction) -+{ -+ struct vc_sm_buffer *res = dmabuf->priv; -+ -+ if (!res->import_dma_buf) -+ return -EINVAL; -+ return res->import_dma_buf->ops->end_cpu_access(res->import_dma_buf, -+ direction); -+} -+ -+static const struct dma_buf_ops dma_buf_import_ops = { -+ .map_dma_buf = vc_sm_import_map_dma_buf, -+ .unmap_dma_buf = vc_sm_import_unmap_dma_buf, -+ .mmap = vc_sm_import_dmabuf_mmap, -+ .release = vc_sm_import_dma_buf_release, -+ .attach = vc_sm_import_dma_buf_attach, -+ .detach = vc_sm_import_dma_buf_detatch, -+ .begin_cpu_access = vc_sm_import_dma_buf_begin_cpu_access, -+ .end_cpu_access = vc_sm_import_dma_buf_end_cpu_access, -+ .map = vc_sm_import_dma_buf_kmap, -+ .unmap = vc_sm_import_dma_buf_kunmap, -+}; -+ -+/* Import a dma_buf to be shared with VC. */ -+int -+vc_sm_cma_import_dmabuf_internal(struct vc_sm_privdata_t *private, -+ struct dma_buf *dma_buf, -+ struct dma_buf **imported_buf) -+{ -+ DEFINE_DMA_BUF_EXPORT_INFO(exp_info); -+ struct vc_sm_buffer *buffer = NULL; -+ struct vc_sm_import import = { }; -+ struct vc_sm_import_result result = { }; -+ struct dma_buf_attachment *attach = NULL; -+ struct sg_table *sgt = NULL; -+ int ret = 0; -+ int status; -+ -+ /* Setup our allocation parameters */ -+ pr_debug("%s: importing dma_buf %p\n", __func__, dma_buf); -+ -+ get_dma_buf(dma_buf); -+ dma_buf = dma_buf; -+ -+ attach = dma_buf_attach(dma_buf, &sm_state->pdev->dev); -+ if (IS_ERR(attach)) { -+ ret = PTR_ERR(attach); -+ goto error; -+ } -+ -+ sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); -+ if (IS_ERR(sgt)) { -+ ret = PTR_ERR(sgt); -+ goto error; -+ } -+ -+ /* Verify that the address block is contiguous */ -+ if (sgt->nents != 1) { -+ ret = -ENOMEM; -+ goto error; -+ } -+ -+ /* Allocate local buffer to track this allocation. */ -+ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); -+ if (!buffer) { -+ ret = -ENOMEM; -+ goto error; -+ } -+ -+ import.type = VC_SM_ALLOC_NON_CACHED; -+ import.addr = (uint32_t)sg_dma_address(sgt->sgl); -+ if ((import.addr & 0xC0000000) != 0xC0000000) { -+ pr_err("%s: Expecting an uncached alias for dma_addr %08x\n", -+ __func__, import.addr); -+ import.addr |= 0xC0000000; -+ } -+ import.size = sg_dma_len(sgt->sgl); -+ import.allocator = current->tgid; -+ import.kernel_id = (uint32_t)buffer; //FIXME: 64 bit support needed. -+ -+ memcpy(import.name, VC_SM_RESOURCE_NAME_DEFAULT, -+ sizeof(VC_SM_RESOURCE_NAME_DEFAULT)); -+ -+ pr_debug("[%s]: attempt to import \"%s\" data - type %u, addr %p, size %u\n", -+ __func__, import.name, import.type, (void *)import.addr, -+ import.size); -+ -+ /* Allocate the videocore buffer. */ -+ status = vc_sm_cma_vchi_import(sm_state->sm_handle, &import, &result, -+ &sm_state->int_trans_id); -+ if (status == -EINTR) { -+ pr_debug("[%s]: requesting import memory action restart (trans_id: %u)\n", -+ __func__, sm_state->int_trans_id); -+ ret = -ERESTARTSYS; -+ private->restart_sys = -EINTR; -+ private->int_action = VC_SM_MSG_TYPE_IMPORT; -+ goto error; -+ } else if (status || !result.res_handle) { -+ pr_debug("[%s]: failed to import memory on videocore (status: %u, trans_id: %u)\n", -+ __func__, status, sm_state->int_trans_id); -+ ret = -ENOMEM; -+ goto error; -+ } -+ -+ mutex_init(&buffer->lock); -+ INIT_LIST_HEAD(&buffer->attachments); -+ memcpy(buffer->name, import.name, -+ min(sizeof(buffer->name), sizeof(import.name) - 1)); -+ -+ /* Keep track of the buffer we created. */ -+ buffer->private = private; -+ buffer->vc_handle = result.res_handle; -+ buffer->size = import.size; -+ buffer->vpu_state = VPU_MAPPED; -+ -+ buffer->import_dma_buf = dma_buf; -+ -+ buffer->attach = attach; -+ buffer->sgt = sgt; -+ buffer->dma_addr = sg_dma_address(sgt->sgl); -+ buffer->in_use = 1; -+ -+ /* -+ * We're done - we need to export a new dmabuf chaining through most -+ * functions, but enabling us to release our own internal references -+ * here. -+ */ -+ exp_info.ops = &dma_buf_import_ops; -+ exp_info.size = import.size; -+ exp_info.flags = O_RDWR; -+ exp_info.priv = buffer; -+ -+ buffer->dma_buf = dma_buf_export(&exp_info); -+ if (IS_ERR(buffer->dma_buf)) { -+ ret = PTR_ERR(buffer->dma_buf); -+ goto error; -+ } -+ -+ vc_sm_add_resource(private, buffer); -+ -+ *imported_buf = buffer->dma_buf; -+ -+ return 0; -+ -+error: -+ if (result.res_handle) { -+ struct vc_sm_free_t free = { result.res_handle, 0 }; -+ -+ vc_sm_cma_vchi_free(sm_state->sm_handle, &free, -+ &sm_state->int_trans_id); -+ } -+ kfree(buffer); -+ if (sgt) -+ dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); -+ if (attach) -+ dma_buf_detach(dma_buf, attach); -+ dma_buf_put(dma_buf); -+ return ret; -+} -+ -+/* FIXME: Pass a function pointer to this into vc_vchi_sm.c */ -+void -+vc_sm_vpu_event(struct sm_instance *instance, struct vc_sm_result_t *reply, -+ int reply_len) -+{ -+ switch (reply->trans_id & ~0x80000000) { -+ case VC_SM_MSG_TYPE_CLIENT_VERSION: -+ { -+ /* Acknowledge that the firmware supports the version command */ -+ pr_debug("%s: firmware acked version msg. Require release cb\n", -+ __func__); -+ sm_state->require_released_callback = true; -+ } -+ break; -+ case VC_SM_MSG_TYPE_RELEASED: -+ { -+ struct vc_sm_released *release = (struct vc_sm_released *)reply; -+ struct vc_sm_buffer *buffer = -+ (struct vc_sm_buffer *)release->kernel_id; -+ -+ /* -+ * FIXME: Need to check buffer is still valid and allocated -+ * before continuing -+ */ -+ pr_debug("%s: Released addr %08x, size %u, id %08x, mem_handle %08x\n", -+ __func__, release->addr, release->size, -+ release->kernel_id, release->vc_handle); -+ mutex_lock(&buffer->lock); -+ buffer->vc_handle = 0; -+ buffer->vpu_state = VPU_NOT_MAPPED; -+ mutex_unlock(&buffer->lock); -+ -+ vc_sm_release_resource(buffer, 0); -+ } -+ break; -+ default: -+ pr_err("%s: Unknown vpu cmd %x\n", __func__, reply->trans_id); -+ break; -+ } -+} -+ -+/* Videocore connected. */ -+static void vc_sm_connected_init(void) -+{ -+ int ret; -+ VCHI_INSTANCE_T vchi_instance; -+ struct vc_sm_version version; -+ struct vc_sm_result_t version_result; -+ -+ pr_info("[%s]: start\n", __func__); -+ -+ /* -+ * Initialize and create a VCHI connection for the shared memory service -+ * running on videocore. -+ */ -+ ret = vchi_initialise(&vchi_instance); -+ if (ret) { -+ pr_err("[%s]: failed to initialise VCHI instance (ret=%d)\n", -+ __func__, ret); -+ -+ ret = -EIO; -+ goto err_free_mem; -+ } -+ -+ ret = vchi_connect(vchi_instance); -+ if (ret) { -+ pr_err("[%s]: failed to connect VCHI instance (ret=%d)\n", -+ __func__, ret); -+ -+ ret = -EIO; -+ goto err_free_mem; -+ } -+ -+ /* Initialize an instance of the shared memory service. */ -+ sm_state->sm_handle = vc_sm_cma_vchi_init(vchi_instance, 1, -+ vc_sm_vpu_event); -+ if (!sm_state->sm_handle) { -+ pr_err("[%s]: failed to initialize shared memory service\n", -+ __func__); -+ -+ ret = -EPERM; -+ goto err_free_mem; -+ } -+ -+ /* Create a debug fs directory entry (root). */ -+ sm_state->dir_root = debugfs_create_dir(VC_SM_DIR_ROOT_NAME, NULL); -+ if (!sm_state->dir_root) { -+ pr_err("[%s]: failed to create \'%s\' directory entry\n", -+ __func__, VC_SM_DIR_ROOT_NAME); -+ -+ ret = -EPERM; -+ goto err_stop_sm_service; -+ } -+ -+ sm_state->dir_state.show = &vc_sm_cma_global_state_show; -+ sm_state->dir_state.dir_entry = -+ debugfs_create_file(VC_SM_STATE, 0444, sm_state->dir_root, -+ &sm_state->dir_state, -+ &vc_sm_cma_debug_fs_fops); -+ -+ INIT_LIST_HEAD(&sm_state->buffer_list); -+ -+ sm_state->data_knl = vc_sm_cma_create_priv_data(0); -+ if (!sm_state->data_knl) { -+ pr_err("[%s]: failed to create kernel private data tracker\n", -+ __func__); -+ goto err_remove_shared_memory; -+ } -+ -+ version.version = 1; -+ ret = vc_sm_cma_vchi_client_version(sm_state->sm_handle, &version, -+ &version_result, -+ &sm_state->int_trans_id); -+ if (ret) { -+ pr_err("[%s]: Failed to send version request %d\n", __func__, -+ ret); -+ } -+ -+ /* Done! */ -+ sm_inited = 1; -+ pr_info("[%s]: installed successfully\n", __func__); -+ return; -+ -+err_remove_shared_memory: -+ debugfs_remove_recursive(sm_state->dir_root); -+err_stop_sm_service: -+ vc_sm_cma_vchi_stop(&sm_state->sm_handle); -+err_free_mem: -+ kfree(sm_state); -+ pr_info("[%s]: failed, ret %d\n", __func__, ret); -+} -+ -+/* Driver loading. */ -+static int bcm2835_vc_sm_cma_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ int err; -+ -+ pr_info("%s: Videocore shared memory driver\n", __func__); -+ -+ sm_state = kzalloc(sizeof(*sm_state), GFP_KERNEL); -+ if (!sm_state) -+ return -ENOMEM; -+ sm_state->pdev = pdev; -+ mutex_init(&sm_state->map_lock); -+ -+ dev->coherent_dma_mask = DMA_BIT_MASK(32); -+ dev->dma_mask = &dev->coherent_dma_mask; -+ err = of_dma_configure(dev, NULL, true); -+ if (err) { -+ dev_err(dev, "Unable to setup DMA: %d\n", err); -+ return err; -+ } -+ -+ vchiq_add_connected_callback(vc_sm_connected_init); -+ return 0; -+} -+ -+/* Driver unloading. */ -+static int bcm2835_vc_sm_cma_remove(struct platform_device *pdev) -+{ -+ pr_debug("[%s]: start\n", __func__); -+ if (sm_inited) { -+ /* Remove shared memory device. */ -+ misc_deregister(&sm_state->dev); -+ -+ /* Remove all proc entries. */ -+ //debugfs_remove_recursive(sm_state->dir_root); -+ -+ /* Stop the videocore shared memory service. */ -+ vc_sm_cma_vchi_stop(&sm_state->sm_handle); -+ -+ /* Free the memory for the state structure. */ -+ mutex_destroy(&sm_state->map_lock); -+ kfree(sm_state); -+ } -+ -+ pr_debug("[%s]: end\n", __func__); -+ return 0; -+} -+ -+/* Get an internal resource handle mapped from the external one. */ -+int vc_sm_cma_int_handle(int handle) -+{ -+ struct dma_buf *dma_buf = (struct dma_buf *)handle; -+ struct vc_sm_buffer *res; -+ -+ /* Validate we can work with this device. */ -+ if (!sm_state || !handle) { -+ pr_err("[%s]: invalid input\n", __func__); -+ return 0; -+ } -+ -+ res = (struct vc_sm_buffer *)dma_buf->priv; -+ return res->vc_handle; -+} -+EXPORT_SYMBOL_GPL(vc_sm_cma_int_handle); -+ -+/* Free a previously allocated shared memory handle and block. */ -+int vc_sm_cma_free(int handle) -+{ -+ struct dma_buf *dma_buf = (struct dma_buf *)handle; -+ -+ /* Validate we can work with this device. */ -+ if (!sm_state || !handle) { -+ pr_err("[%s]: invalid input\n", __func__); -+ return -EPERM; -+ } -+ -+ pr_debug("%s: handle %08x/dmabuf %p\n", __func__, handle, dma_buf); -+ -+ dma_buf_put(dma_buf); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(vc_sm_cma_free); -+ -+/* Import a dmabuf to be shared with VC. */ -+int vc_sm_cma_import_dmabuf(struct dma_buf *src_dmabuf, int *handle) -+{ -+ struct dma_buf *new_dma_buf; -+ struct vc_sm_buffer *res; -+ int ret; -+ -+ /* Validate we can work with this device. */ -+ if (!sm_state || !src_dmabuf || !handle) { -+ pr_err("[%s]: invalid input\n", __func__); -+ return -EPERM; -+ } -+ -+ ret = vc_sm_cma_import_dmabuf_internal(sm_state->data_knl, src_dmabuf, -+ &new_dma_buf); -+ -+ if (!ret) { -+ pr_debug("%s: imported to ptr %p\n", __func__, new_dma_buf); -+ res = (struct vc_sm_buffer *)new_dma_buf->priv; -+ -+ /* Assign valid handle at this time.*/ -+ *handle = (int)new_dma_buf; -+ } else { -+ /* -+ * succeeded in importing the dma_buf, but then -+ * failed to look it up again. How? -+ * Release the fd again. -+ */ -+ pr_err("%s: imported vc_sm_cma_get_buffer failed %d\n", -+ __func__, ret); -+ } -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(vc_sm_cma_import_dmabuf); -+ -+static struct platform_driver bcm2835_vcsm_cma_driver = { -+ .probe = bcm2835_vc_sm_cma_probe, -+ .remove = bcm2835_vc_sm_cma_remove, -+ .driver = { -+ .name = DEVICE_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+module_platform_driver(bcm2835_vcsm_cma_driver); -+ -+MODULE_AUTHOR("Dave Stevenson"); -+MODULE_DESCRIPTION("VideoCore CMA Shared Memory Driver"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:vcsm-cma"); ---- /dev/null -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.h -@@ -0,0 +1,59 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+ -+/* -+ * VideoCore Shared Memory driver using CMA. -+ * -+ * Copyright: 2018, Raspberry Pi (Trading) Ltd -+ * -+ */ -+ -+#ifndef VC_SM_H -+#define VC_SM_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define VC_SM_MAX_NAME_LEN 32 -+ -+enum vc_sm_vpu_mapping_state { -+ VPU_NOT_MAPPED, -+ VPU_MAPPED, -+ VPU_UNMAPPING -+}; -+ -+struct vc_sm_buffer { -+ struct list_head global_buffer_list; /* Global list of buffers. */ -+ -+ size_t size; -+ -+ /* Lock over all the following state for this buffer */ -+ struct mutex lock; -+ struct sg_table *sg_table; -+ struct list_head attachments; -+ -+ char name[VC_SM_MAX_NAME_LEN]; -+ -+ int in_use:1; /* Kernel is still using this resource */ -+ -+ enum vc_sm_vpu_mapping_state vpu_state; -+ u32 vc_handle; /* VideoCore handle for this buffer */ -+ -+ /* DMABUF related fields */ -+ struct dma_buf *import_dma_buf; -+ struct dma_buf *dma_buf; -+ struct dma_buf_attachment *attach; -+ struct sg_table *sgt; -+ dma_addr_t dma_addr; -+ -+ struct vc_sm_privdata_t *private; -+}; -+ -+#endif ---- /dev/null -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c -@@ -0,0 +1,498 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * VideoCore Shared Memory CMA allocator -+ * -+ * Copyright: 2018, Raspberry Pi (Trading) Ltd -+ * Copyright 2011-2012 Broadcom Corporation. All rights reserved. -+ * -+ * Based on vmcs_sm driver from Broadcom Corporation. -+ * -+ */ -+ -+/* ---- Include Files ----------------------------------------------------- */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "vc_sm_cma_vchi.h" -+ -+#define VC_SM_VER 1 -+#define VC_SM_MIN_VER 0 -+ -+/* ---- Private Constants and Types -------------------------------------- */ -+ -+/* Command blocks come from a pool */ -+#define SM_MAX_NUM_CMD_RSP_BLKS 32 -+ -+struct sm_cmd_rsp_blk { -+ struct list_head head; /* To create lists */ -+ /* To be signaled when the response is there */ -+ struct completion cmplt; -+ -+ u16 id; -+ u16 length; -+ -+ u8 msg[VC_SM_MAX_MSG_LEN]; -+ -+ uint32_t wait:1; -+ uint32_t sent:1; -+ uint32_t alloc:1; -+ -+}; -+ -+struct sm_instance { -+ u32 num_connections; -+ VCHI_SERVICE_HANDLE_T vchi_handle[VCHI_MAX_NUM_CONNECTIONS]; -+ struct task_struct *io_thread; -+ struct completion io_cmplt; -+ -+ vpu_event_cb vpu_event; -+ -+ /* Mutex over the following lists */ -+ struct mutex lock; -+ u32 trans_id; -+ struct list_head cmd_list; -+ struct list_head rsp_list; -+ struct list_head dead_list; -+ -+ struct sm_cmd_rsp_blk free_blk[SM_MAX_NUM_CMD_RSP_BLKS]; -+ -+ /* Mutex over the free_list */ -+ struct mutex free_lock; -+ struct list_head free_list; -+ -+ struct semaphore free_sema; -+ -+}; -+ -+/* ---- Private Variables ------------------------------------------------ */ -+ -+/* ---- Private Function Prototypes -------------------------------------- */ -+ -+/* ---- Private Functions ------------------------------------------------ */ -+static int -+bcm2835_vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle, -+ void *data, -+ unsigned int size) -+{ -+ return vchi_queue_kernel_message(handle, -+ data, -+ size); -+} -+ -+static struct -+sm_cmd_rsp_blk *vc_vchi_cmd_create(struct sm_instance *instance, -+ enum vc_sm_msg_type id, void *msg, -+ u32 size, int wait) -+{ -+ struct sm_cmd_rsp_blk *blk; -+ struct vc_sm_msg_hdr_t *hdr; -+ -+ if (down_interruptible(&instance->free_sema)) { -+ blk = kmalloc(sizeof(*blk), GFP_KERNEL); -+ if (!blk) -+ return NULL; -+ -+ blk->alloc = 1; -+ init_completion(&blk->cmplt); -+ } else { -+ mutex_lock(&instance->free_lock); -+ blk = -+ list_first_entry(&instance->free_list, -+ struct sm_cmd_rsp_blk, head); -+ list_del(&blk->head); -+ mutex_unlock(&instance->free_lock); -+ } -+ -+ blk->sent = 0; -+ blk->wait = wait; -+ blk->length = sizeof(*hdr) + size; -+ -+ hdr = (struct vc_sm_msg_hdr_t *)blk->msg; -+ hdr->type = id; -+ mutex_lock(&instance->lock); -+ instance->trans_id++; -+ /* -+ * Retain the top bit for identifying asynchronous events, or VPU cmds. -+ */ -+ instance->trans_id &= ~0x80000000; -+ hdr->trans_id = instance->trans_id; -+ blk->id = instance->trans_id; -+ mutex_unlock(&instance->lock); -+ -+ if (size) -+ memcpy(hdr->body, msg, size); -+ -+ return blk; -+} -+ -+static void -+vc_vchi_cmd_delete(struct sm_instance *instance, struct sm_cmd_rsp_blk *blk) -+{ -+ if (blk->alloc) { -+ kfree(blk); -+ return; -+ } -+ -+ mutex_lock(&instance->free_lock); -+ list_add(&blk->head, &instance->free_list); -+ mutex_unlock(&instance->free_lock); -+ up(&instance->free_sema); -+} -+ -+static void vc_sm_cma_vchi_rx_ack(struct sm_instance *instance, -+ struct sm_cmd_rsp_blk *cmd, -+ struct vc_sm_result_t *reply, -+ u32 reply_len) -+{ -+ mutex_lock(&instance->lock); -+ list_for_each_entry(cmd, -+ &instance->rsp_list, -+ head) { -+ if (cmd->id == reply->trans_id) -+ break; -+ } -+ mutex_unlock(&instance->lock); -+ -+ if (&cmd->head == &instance->rsp_list) { -+ //pr_debug("%s: received response %u, throw away...", -+ pr_err("%s: received response %u, throw away...", -+ __func__, -+ reply->trans_id); -+ } else if (reply_len > sizeof(cmd->msg)) { -+ pr_err("%s: reply too big (%u) %u, throw away...", -+ __func__, reply_len, -+ reply->trans_id); -+ } else { -+ memcpy(cmd->msg, reply, -+ reply_len); -+ complete(&cmd->cmplt); -+ } -+} -+ -+static int vc_sm_cma_vchi_videocore_io(void *arg) -+{ -+ struct sm_instance *instance = arg; -+ struct sm_cmd_rsp_blk *cmd = NULL, *cmd_tmp; -+ struct vc_sm_result_t *reply; -+ u32 reply_len; -+ s32 status; -+ int svc_use = 1; -+ -+ while (1) { -+ if (svc_use) -+ vchi_service_release(instance->vchi_handle[0]); -+ svc_use = 0; -+ if (!wait_for_completion_interruptible(&instance->io_cmplt)) { -+ vchi_service_use(instance->vchi_handle[0]); -+ svc_use = 1; -+ -+ do { -+ /* -+ * Get new command and move it to response list -+ */ -+ mutex_lock(&instance->lock); -+ if (list_empty(&instance->cmd_list)) { -+ /* no more commands to process */ -+ mutex_unlock(&instance->lock); -+ break; -+ } -+ cmd = -+ list_first_entry(&instance->cmd_list, -+ struct sm_cmd_rsp_blk, -+ head); -+ list_move(&cmd->head, &instance->rsp_list); -+ cmd->sent = 1; -+ mutex_unlock(&instance->lock); -+ -+ /* Send the command */ -+ status = bcm2835_vchi_msg_queue( -+ instance->vchi_handle[0], -+ cmd->msg, cmd->length); -+ if (status) { -+ pr_err("%s: failed to queue message (%d)", -+ __func__, status); -+ } -+ -+ /* If no reply is needed then we're done */ -+ if (!cmd->wait) { -+ mutex_lock(&instance->lock); -+ list_del(&cmd->head); -+ mutex_unlock(&instance->lock); -+ vc_vchi_cmd_delete(instance, cmd); -+ continue; -+ } -+ -+ if (status) { -+ complete(&cmd->cmplt); -+ continue; -+ } -+ -+ } while (1); -+ -+ while (!vchi_msg_peek(instance->vchi_handle[0], -+ (void **)&reply, &reply_len, -+ VCHI_FLAGS_NONE)) { -+ if (reply->trans_id & 0x80000000) { -+ /* Async event or cmd from the VPU */ -+ if (instance->vpu_event) -+ instance->vpu_event( -+ instance, reply, -+ reply_len); -+ } else { -+ vc_sm_cma_vchi_rx_ack(instance, cmd, -+ reply, reply_len); -+ } -+ -+ vchi_msg_remove(instance->vchi_handle[0]); -+ } -+ -+ /* Go through the dead list and free them */ -+ mutex_lock(&instance->lock); -+ list_for_each_entry_safe(cmd, cmd_tmp, -+ &instance->dead_list, head) { -+ list_del(&cmd->head); -+ vc_vchi_cmd_delete(instance, cmd); -+ } -+ mutex_unlock(&instance->lock); -+ } -+ } -+ -+ return 0; -+} -+ -+static void vc_sm_cma_vchi_callback(void *param, -+ const VCHI_CALLBACK_REASON_T reason, -+ void *msg_handle) -+{ -+ struct sm_instance *instance = param; -+ -+ (void)msg_handle; -+ -+ switch (reason) { -+ case VCHI_CALLBACK_MSG_AVAILABLE: -+ complete(&instance->io_cmplt); -+ break; -+ -+ case VCHI_CALLBACK_SERVICE_CLOSED: -+ pr_info("%s: service CLOSED!!", __func__); -+ default: -+ break; -+ } -+} -+ -+struct sm_instance *vc_sm_cma_vchi_init(VCHI_INSTANCE_T vchi_instance, -+ unsigned int num_connections, -+ vpu_event_cb vpu_event) -+{ -+ u32 i; -+ struct sm_instance *instance; -+ int status; -+ -+ pr_debug("%s: start", __func__); -+ -+ if (num_connections > VCHI_MAX_NUM_CONNECTIONS) { -+ pr_err("%s: unsupported number of connections %u (max=%u)", -+ __func__, num_connections, VCHI_MAX_NUM_CONNECTIONS); -+ -+ goto err_null; -+ } -+ /* Allocate memory for this instance */ -+ instance = kzalloc(sizeof(*instance), GFP_KERNEL); -+ -+ /* Misc initialisations */ -+ mutex_init(&instance->lock); -+ init_completion(&instance->io_cmplt); -+ INIT_LIST_HEAD(&instance->cmd_list); -+ INIT_LIST_HEAD(&instance->rsp_list); -+ INIT_LIST_HEAD(&instance->dead_list); -+ INIT_LIST_HEAD(&instance->free_list); -+ sema_init(&instance->free_sema, SM_MAX_NUM_CMD_RSP_BLKS); -+ mutex_init(&instance->free_lock); -+ for (i = 0; i < SM_MAX_NUM_CMD_RSP_BLKS; i++) { -+ init_completion(&instance->free_blk[i].cmplt); -+ list_add(&instance->free_blk[i].head, &instance->free_list); -+ } -+ -+ /* Open the VCHI service connections */ -+ instance->num_connections = num_connections; -+ for (i = 0; i < num_connections; i++) { -+ SERVICE_CREATION_T params = { -+ .version = VCHI_VERSION_EX(VC_SM_VER, VC_SM_MIN_VER), -+ .service_id = VC_SM_SERVER_NAME, -+ .callback = vc_sm_cma_vchi_callback, -+ .callback_param = instance, -+ }; -+ -+ status = vchi_service_open(vchi_instance, -+ ¶ms, &instance->vchi_handle[i]); -+ if (status) { -+ pr_err("%s: failed to open VCHI service (%d)", -+ __func__, status); -+ -+ goto err_close_services; -+ } -+ } -+ -+ /* Create the thread which takes care of all io to/from videoocore. */ -+ instance->io_thread = kthread_create(&vc_sm_cma_vchi_videocore_io, -+ (void *)instance, "SMIO"); -+ if (!instance->io_thread) { -+ pr_err("%s: failed to create SMIO thread", __func__); -+ -+ goto err_close_services; -+ } -+ instance->vpu_event = vpu_event; -+ set_user_nice(instance->io_thread, -10); -+ wake_up_process(instance->io_thread); -+ -+ pr_debug("%s: success - instance 0x%x", __func__, -+ (unsigned int)instance); -+ return instance; -+ -+err_close_services: -+ for (i = 0; i < instance->num_connections; i++) { -+ if (instance->vchi_handle[i]) -+ vchi_service_close(instance->vchi_handle[i]); -+ } -+ kfree(instance); -+err_null: -+ pr_debug("%s: FAILED", __func__); -+ return NULL; -+} -+ -+int vc_sm_cma_vchi_stop(struct sm_instance **handle) -+{ -+ struct sm_instance *instance; -+ u32 i; -+ -+ if (!handle) { -+ pr_err("%s: invalid pointer to handle %p", __func__, handle); -+ goto lock; -+ } -+ -+ if (!*handle) { -+ pr_err("%s: invalid handle %p", __func__, *handle); -+ goto lock; -+ } -+ -+ instance = *handle; -+ -+ /* Close all VCHI service connections */ -+ for (i = 0; i < instance->num_connections; i++) { -+ s32 success; -+ -+ vchi_service_use(instance->vchi_handle[i]); -+ -+ success = vchi_service_close(instance->vchi_handle[i]); -+ } -+ -+ kfree(instance); -+ -+ *handle = NULL; -+ return 0; -+ -+lock: -+ return -EINVAL; -+} -+ -+static int vc_sm_cma_vchi_send_msg(struct sm_instance *handle, -+ enum vc_sm_msg_type msg_id, void *msg, -+ u32 msg_size, void *result, u32 result_size, -+ u32 *cur_trans_id, u8 wait_reply) -+{ -+ int status = 0; -+ struct sm_instance *instance = handle; -+ struct sm_cmd_rsp_blk *cmd_blk; -+ -+ if (!handle) { -+ pr_err("%s: invalid handle", __func__); -+ return -EINVAL; -+ } -+ if (!msg) { -+ pr_err("%s: invalid msg pointer", __func__); -+ return -EINVAL; -+ } -+ -+ cmd_blk = -+ vc_vchi_cmd_create(instance, msg_id, msg, msg_size, wait_reply); -+ if (!cmd_blk) { -+ pr_err("[%s]: failed to allocate global tracking resource", -+ __func__); -+ return -ENOMEM; -+ } -+ -+ if (cur_trans_id) -+ *cur_trans_id = cmd_blk->id; -+ -+ mutex_lock(&instance->lock); -+ list_add_tail(&cmd_blk->head, &instance->cmd_list); -+ mutex_unlock(&instance->lock); -+ complete(&instance->io_cmplt); -+ -+ if (!wait_reply) -+ /* We're done */ -+ return 0; -+ -+ /* Wait for the response */ -+ if (wait_for_completion_interruptible(&cmd_blk->cmplt)) { -+ mutex_lock(&instance->lock); -+ if (!cmd_blk->sent) { -+ list_del(&cmd_blk->head); -+ mutex_unlock(&instance->lock); -+ vc_vchi_cmd_delete(instance, cmd_blk); -+ return -ENXIO; -+ } -+ -+ list_move(&cmd_blk->head, &instance->dead_list); -+ mutex_unlock(&instance->lock); -+ complete(&instance->io_cmplt); -+ return -EINTR; /* We're done */ -+ } -+ -+ if (result && result_size) { -+ memcpy(result, cmd_blk->msg, result_size); -+ } else { -+ struct vc_sm_result_t *res = -+ (struct vc_sm_result_t *)cmd_blk->msg; -+ status = (res->success == 0) ? 0 : -ENXIO; -+ } -+ -+ mutex_lock(&instance->lock); -+ list_del(&cmd_blk->head); -+ mutex_unlock(&instance->lock); -+ vc_vchi_cmd_delete(instance, cmd_blk); -+ return status; -+} -+ -+int vc_sm_cma_vchi_free(struct sm_instance *handle, struct vc_sm_free_t *msg, -+ u32 *cur_trans_id) -+{ -+ return vc_sm_cma_vchi_send_msg(handle, VC_SM_MSG_TYPE_FREE, -+ msg, sizeof(*msg), 0, 0, cur_trans_id, 0); -+} -+ -+int vc_sm_cma_vchi_import(struct sm_instance *handle, struct vc_sm_import *msg, -+ struct vc_sm_import_result *result, u32 *cur_trans_id) -+{ -+ return vc_sm_cma_vchi_send_msg(handle, VC_SM_MSG_TYPE_IMPORT, -+ msg, sizeof(*msg), result, sizeof(*result), -+ cur_trans_id, 1); -+} -+ -+int vc_sm_cma_vchi_client_version(struct sm_instance *handle, -+ struct vc_sm_version *msg, -+ struct vc_sm_result_t *result, -+ u32 *cur_trans_id) -+{ -+ return vc_sm_cma_vchi_send_msg(handle, VC_SM_MSG_TYPE_CLIENT_VERSION, -+ //msg, sizeof(*msg), result, sizeof(*result), -+ //cur_trans_id, 1); -+ msg, sizeof(*msg), NULL, 0, -+ cur_trans_id, 0); -+} ---- /dev/null -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.h -@@ -0,0 +1,59 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+ -+/* -+ * VideoCore Shared Memory CMA allocator -+ * -+ * Copyright: 2018, Raspberry Pi (Trading) Ltd -+ * Copyright 2011-2012 Broadcom Corporation. All rights reserved. -+ * -+ * Based on vmcs_sm driver from Broadcom Corporation. -+ * -+ */ -+ -+#ifndef __VC_SM_CMA_VCHI_H__INCLUDED__ -+#define __VC_SM_CMA_VCHI_H__INCLUDED__ -+ -+#include "interface/vchi/vchi.h" -+ -+#include "vc_sm_defs.h" -+ -+/* -+ * Forward declare. -+ */ -+struct sm_instance; -+ -+typedef void (*vpu_event_cb)(struct sm_instance *instance, -+ struct vc_sm_result_t *reply, int reply_len); -+ -+/* -+ * Initialize the shared memory service, opens up vchi connection to talk to it. -+ */ -+struct sm_instance *vc_sm_cma_vchi_init(VCHI_INSTANCE_T vchi_instance, -+ unsigned int num_connections, -+ vpu_event_cb vpu_event); -+ -+/* -+ * Terminates the shared memory service. -+ */ -+int vc_sm_cma_vchi_stop(struct sm_instance **handle); -+ -+/* -+ * Ask the shared memory service to free up some memory that was previously -+ * allocated by the vc_sm_cma_vchi_alloc function call. -+ */ -+int vc_sm_cma_vchi_free(struct sm_instance *handle, struct vc_sm_free_t *msg, -+ u32 *cur_trans_id); -+ -+/* -+ * Import a contiguous block of memory and wrap it in a GPU MEM_HANDLE_T. -+ */ -+int vc_sm_cma_vchi_import(struct sm_instance *handle, struct vc_sm_import *msg, -+ struct vc_sm_import_result *result, -+ u32 *cur_trans_id); -+ -+int vc_sm_cma_vchi_client_version(struct sm_instance *handle, -+ struct vc_sm_version *msg, -+ struct vc_sm_result_t *result, -+ u32 *cur_trans_id); -+ -+#endif /* __VC_SM_CMA_VCHI_H__INCLUDED__ */ ---- /dev/null -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_defs.h -@@ -0,0 +1,298 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+ -+/* -+ * VideoCore Shared Memory CMA allocator -+ * -+ * Copyright: 2018, Raspberry Pi (Trading) Ltd -+ * -+ * Based on vc_sm_defs.h from the vmcs_sm driver Copyright Broadcom Corporation. -+ * All IPC messages are copied across to this file, even if the vc-sm-cma -+ * driver is not currently using them. -+ * -+ **************************************************************************** -+ */ -+ -+#ifndef __VC_SM_DEFS_H__INCLUDED__ -+#define __VC_SM_DEFS_H__INCLUDED__ -+ -+/* FourCC code used for VCHI connection */ -+#define VC_SM_SERVER_NAME MAKE_FOURCC("SMEM") -+ -+/* Maximum message length */ -+#define VC_SM_MAX_MSG_LEN (sizeof(union vc_sm_msg_union_t) + \ -+ sizeof(struct vc_sm_msg_hdr_t)) -+#define VC_SM_MAX_RSP_LEN (sizeof(union vc_sm_msg_union_t)) -+ -+/* Resource name maximum size */ -+#define VC_SM_RESOURCE_NAME 32 -+ -+/* -+ * Version to be reported to the VPU -+ * VPU assumes 0 (aka 1) which does not require the released callback, nor -+ * expect the client to handle VC_MEM_REQUESTS. -+ * Version 2 requires the released callback, and must support VC_MEM_REQUESTS. -+ */ -+#define VC_SM_PROTOCOL_VERSION 2 -+ -+enum vc_sm_msg_type { -+ /* Message types supported for HOST->VC direction */ -+ -+ /* Allocate shared memory block */ -+ VC_SM_MSG_TYPE_ALLOC, -+ /* Lock allocated shared memory block */ -+ VC_SM_MSG_TYPE_LOCK, -+ /* Unlock allocated shared memory block */ -+ VC_SM_MSG_TYPE_UNLOCK, -+ /* Unlock allocated shared memory block, do not answer command */ -+ VC_SM_MSG_TYPE_UNLOCK_NOANS, -+ /* Free shared memory block */ -+ VC_SM_MSG_TYPE_FREE, -+ /* Resize a shared memory block */ -+ VC_SM_MSG_TYPE_RESIZE, -+ /* Walk the allocated shared memory block(s) */ -+ VC_SM_MSG_TYPE_WALK_ALLOC, -+ -+ /* A previously applied action will need to be reverted */ -+ VC_SM_MSG_TYPE_ACTION_CLEAN, -+ -+ /* -+ * Import a physical address and wrap into a MEM_HANDLE_T. -+ * Release with VC_SM_MSG_TYPE_FREE. -+ */ -+ VC_SM_MSG_TYPE_IMPORT, -+ /* -+ *Tells VC the protocol version supported by this client. -+ * 2 supports the async/cmd messages from the VPU for final release -+ * of memory, and for VC allocations. -+ */ -+ VC_SM_MSG_TYPE_CLIENT_VERSION, -+ /* Response to VC request for memory */ -+ VC_SM_MSG_TYPE_VC_MEM_REQUEST_REPLY, -+ -+ /* -+ * Asynchronous/cmd messages supported for VC->HOST direction. -+ * Signalled by setting the top bit in vc_sm_result_t trans_id. -+ */ -+ -+ /* -+ * VC has finished with an imported memory allocation. -+ * Release any Linux reference counts on the underlying block. -+ */ -+ VC_SM_MSG_TYPE_RELEASED, -+ /* VC request for memory */ -+ VC_SM_MSG_TYPE_VC_MEM_REQUEST, -+ -+ VC_SM_MSG_TYPE_MAX -+}; -+ -+/* Type of memory to be allocated */ -+enum vc_sm_alloc_type_t { -+ VC_SM_ALLOC_CACHED, -+ VC_SM_ALLOC_NON_CACHED, -+}; -+ -+/* Message header for all messages in HOST->VC direction */ -+struct vc_sm_msg_hdr_t { -+ u32 type; -+ u32 trans_id; -+ u8 body[0]; -+ -+}; -+ -+/* Request to allocate memory (HOST->VC) */ -+struct vc_sm_alloc_t { -+ /* type of memory to allocate */ -+ enum vc_sm_alloc_type_t type; -+ /* byte amount of data to allocate per unit */ -+ u32 base_unit; -+ /* number of unit to allocate */ -+ u32 num_unit; -+ /* alignment to be applied on allocation */ -+ u32 alignment; -+ /* identity of who allocated this block */ -+ u32 allocator; -+ /* resource name (for easier tracking on vc side) */ -+ char name[VC_SM_RESOURCE_NAME]; -+ -+}; -+ -+/* Result of a requested memory allocation (VC->HOST) */ -+struct vc_sm_alloc_result_t { -+ /* Transaction identifier */ -+ u32 trans_id; -+ -+ /* Resource handle */ -+ u32 res_handle; -+ /* Pointer to resource buffer */ -+ u32 res_mem; -+ /* Resource base size (bytes) */ -+ u32 res_base_size; -+ /* Resource number */ -+ u32 res_num; -+ -+}; -+ -+/* Request to free a previously allocated memory (HOST->VC) */ -+struct vc_sm_free_t { -+ /* Resource handle (returned from alloc) */ -+ u32 res_handle; -+ /* Resource buffer (returned from alloc) */ -+ u32 res_mem; -+ -+}; -+ -+/* Request to lock a previously allocated memory (HOST->VC) */ -+struct vc_sm_lock_unlock_t { -+ /* Resource handle (returned from alloc) */ -+ u32 res_handle; -+ /* Resource buffer (returned from alloc) */ -+ u32 res_mem; -+ -+}; -+ -+/* Request to resize a previously allocated memory (HOST->VC) */ -+struct vc_sm_resize_t { -+ /* Resource handle (returned from alloc) */ -+ u32 res_handle; -+ /* Resource buffer (returned from alloc) */ -+ u32 res_mem; -+ /* Resource *new* size requested (bytes) */ -+ u32 res_new_size; -+ -+}; -+ -+/* Result of a requested memory lock (VC->HOST) */ -+struct vc_sm_lock_result_t { -+ /* Transaction identifier */ -+ u32 trans_id; -+ -+ /* Resource handle */ -+ u32 res_handle; -+ /* Pointer to resource buffer */ -+ u32 res_mem; -+ /* -+ * Pointer to former resource buffer if the memory -+ * was reallocated -+ */ -+ u32 res_old_mem; -+ -+}; -+ -+/* Generic result for a request (VC->HOST) */ -+struct vc_sm_result_t { -+ /* Transaction identifier */ -+ u32 trans_id; -+ -+ s32 success; -+ -+}; -+ -+/* Request to revert a previously applied action (HOST->VC) */ -+struct vc_sm_action_clean_t { -+ /* Action of interest */ -+ enum vc_sm_msg_type res_action; -+ /* Transaction identifier for the action of interest */ -+ u32 action_trans_id; -+ -+}; -+ -+/* Request to remove all data associated with a given allocator (HOST->VC) */ -+struct vc_sm_free_all_t { -+ /* Allocator identifier */ -+ u32 allocator; -+}; -+ -+/* Request to import memory (HOST->VC) */ -+struct vc_sm_import { -+ /* type of memory to allocate */ -+ enum vc_sm_alloc_type_t type; -+ /* pointer to the VC (ie physical) address of the allocated memory */ -+ u32 addr; -+ /* size of buffer */ -+ u32 size; -+ /* opaque handle returned in RELEASED messages */ -+ u32 kernel_id; -+ /* Allocator identifier */ -+ u32 allocator; -+ /* resource name (for easier tracking on vc side) */ -+ char name[VC_SM_RESOURCE_NAME]; -+}; -+ -+/* Result of a requested memory import (VC->HOST) */ -+struct vc_sm_import_result { -+ /* Transaction identifier */ -+ u32 trans_id; -+ -+ /* Resource handle */ -+ u32 res_handle; -+}; -+ -+/* Notification that VC has finished with an allocation (VC->HOST) */ -+struct vc_sm_released { -+ /* cmd type / trans_id */ -+ u32 cmd; -+ -+ /* pointer to the VC (ie physical) address of the allocated memory */ -+ u32 addr; -+ /* size of buffer */ -+ u32 size; -+ /* opaque handle returned in RELEASED messages */ -+ u32 kernel_id; -+ u32 vc_handle; -+}; -+ -+/* -+ * Client informing VC as to the protocol version it supports. -+ * >=2 requires the released callback, and supports VC asking for memory. -+ * Failure means that the firmware doesn't support this call, and therefore the -+ * client should either fail, or NOT rely on getting the released callback. -+ */ -+struct vc_sm_version { -+ u32 version; -+}; -+ -+/* Request FROM VideoCore for some memory */ -+struct vc_sm_vc_mem_request { -+ /* cmd type */ -+ u32 cmd; -+ -+ /* trans_id (from VPU) */ -+ u32 trans_id; -+ /* size of buffer */ -+ u32 size; -+ /* alignment of buffer */ -+ u32 align; -+ /* resource name (for easier tracking) */ -+ char name[VC_SM_RESOURCE_NAME]; -+}; -+ -+/* Response from the kernel to provide the VPU with some memory */ -+struct vc_sm_vc_mem_request_result { -+ /* Transaction identifier for the VPU */ -+ u32 trans_id; -+ /* pointer to the physical address of the allocated memory */ -+ u32 addr; -+ /* opaque handle returned in RELEASED messages */ -+ u32 kernel_id; -+}; -+ -+/* Union of ALL messages */ -+union vc_sm_msg_union_t { -+ struct vc_sm_alloc_t alloc; -+ struct vc_sm_alloc_result_t alloc_result; -+ struct vc_sm_free_t free; -+ struct vc_sm_lock_unlock_t lock_unlock; -+ struct vc_sm_action_clean_t action_clean; -+ struct vc_sm_resize_t resize; -+ struct vc_sm_lock_result_t lock_result; -+ struct vc_sm_result_t result; -+ struct vc_sm_free_all_t free_all; -+ struct vc_sm_import import; -+ struct vc_sm_import_result import_result; -+ struct vc_sm_version version; -+ struct vc_sm_released released; -+ struct vc_sm_vc_mem_request vc_request; -+ struct vc_sm_vc_mem_request_result vc_request_result; -+}; -+ -+#endif /* __VC_SM_DEFS_H__INCLUDED__ */ ---- /dev/null -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_knl.h -@@ -0,0 +1,28 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+ -+/* -+ * VideoCore Shared Memory CMA allocator -+ * -+ * Copyright: 2018, Raspberry Pi (Trading) Ltd -+ * -+ * Based on vc_sm_defs.h from the vmcs_sm driver Copyright Broadcom Corporation. -+ * -+ */ -+ -+#ifndef __VC_SM_KNL_H__INCLUDED__ -+#define __VC_SM_KNL_H__INCLUDED__ -+ -+#if !defined(__KERNEL__) -+#error "This interface is for kernel use only..." -+#endif -+ -+/* Free a previously allocated or imported shared memory handle and block. */ -+int vc_sm_cma_free(int handle); -+ -+/* Get an internal resource handle mapped from the external one. */ -+int vc_sm_cma_int_handle(int handle); -+ -+/* Import a block of memory into the GPU space. */ -+int vc_sm_cma_import_dmabuf(struct dma_buf *dmabuf, int *handle); -+ -+#endif /* __VC_SM_KNL_H__INCLUDED__ */ diff --git a/target/linux/brcm2708/patches-4.19/950-0276-staging-vc-sm-cma-Fixup-driver-for-older-VCHI-APIs.patch b/target/linux/brcm2708/patches-4.19/950-0276-staging-vc-sm-cma-Fixup-driver-for-older-VCHI-APIs.patch deleted file mode 100644 index 1ab6bdd5a8..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0276-staging-vc-sm-cma-Fixup-driver-for-older-VCHI-APIs.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 474a6207d432c230ffa4f9b1a8ff0d9673bd89bb Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 30 Oct 2018 11:42:48 +0000 -Subject: [PATCH 276/703] staging: vc-sm-cma: Fixup driver for older VCHI APIs - -Original patch was based off staging which included some cleanups -of the VCHI APIs. Those aren't present here, so switch back to -the older API. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 2 +- - drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c | 5 +++++ - 2 files changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -632,7 +632,7 @@ static void vc_sm_connected_init(void) - goto err_free_mem; - } - -- ret = vchi_connect(vchi_instance); -+ ret = vchi_connect(NULL, 0, vchi_instance); - if (ret) { - pr_err("[%s]: failed to connect VCHI instance (ret=%d)\n", - __func__, ret); ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c -@@ -325,8 +325,13 @@ struct sm_instance *vc_sm_cma_vchi_init( - SERVICE_CREATION_T params = { - .version = VCHI_VERSION_EX(VC_SM_VER, VC_SM_MIN_VER), - .service_id = VC_SM_SERVER_NAME, -+ .rx_fifo_size = 0, -+ .tx_fifo_size = 0, - .callback = vc_sm_cma_vchi_callback, - .callback_param = instance, -+ .want_unaligned_bulk_rx = 0, -+ .want_unaligned_bulk_tx = 0, -+ .want_crc = 0 - }; - - status = vchi_service_open(vchi_instance, diff --git a/target/linux/brcm2708/patches-4.19/950-0276-staging-vc04_services-Add-a-V4L2-M2M-codec-driver.patch b/target/linux/brcm2708/patches-4.19/950-0276-staging-vc04_services-Add-a-V4L2-M2M-codec-driver.patch new file mode 100644 index 0000000000..c7816f7333 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0276-staging-vc04_services-Add-a-V4L2-M2M-codec-driver.patch @@ -0,0 +1,2467 @@ +From e99f0a65a7159b35cd8dbf753d7e12b3331b0ca4 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 25 Sep 2018 14:53:49 +0100 +Subject: [PATCH 276/725] staging: vc04_services: Add a V4L2 M2M codec driver + +This adds a V4L2 memory to memory device that wraps the MMAL +video decode and video_encode components for H264 and MJPEG encode +and decode, MPEG4, H263, and VP8 decode (and MPEG2 decode +if the appropriate licence has been purchased). + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/Kconfig | 1 + + drivers/staging/vc04_services/Makefile | 9 +- + .../vc04_services/bcm2835-codec/Kconfig | 11 + + .../vc04_services/bcm2835-codec/Makefile | 8 + + .../staging/vc04_services/bcm2835-codec/TODO | 24 + + .../bcm2835-codec/bcm2835-v4l2-codec.c | 2359 +++++++++++++++++ + 6 files changed, 2408 insertions(+), 4 deletions(-) + create mode 100644 drivers/staging/vc04_services/bcm2835-codec/Kconfig + create mode 100644 drivers/staging/vc04_services/bcm2835-codec/Makefile + create mode 100644 drivers/staging/vc04_services/bcm2835-codec/TODO + create mode 100644 drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c + +--- a/drivers/staging/vc04_services/Kconfig ++++ b/drivers/staging/vc04_services/Kconfig +@@ -23,6 +23,7 @@ source "drivers/staging/vc04_services/bc + source "drivers/staging/vc04_services/bcm2835-camera/Kconfig" + source "drivers/staging/vc04_services/vchiq-mmal/Kconfig" + source "drivers/staging/vc04_services/vc-sm-cma/Kconfig" ++source "drivers/staging/vc04_services/bcm2835-codec/Kconfig" + + endif + +--- a/drivers/staging/vc04_services/Makefile ++++ b/drivers/staging/vc04_services/Makefile +@@ -10,10 +10,11 @@ vchiq-objs := \ + interface/vchiq_arm/vchiq_util.o \ + interface/vchiq_arm/vchiq_connected.o \ + +-obj-$(CONFIG_SND_BCM2835) += bcm2835-audio/ +-obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-camera/ +-obj-$(CONFIG_BCM2835_VCHIQ_MMAL) += vchiq-mmal/ +-obj-$(CONFIG_BCM_VC_SM_CMA) += vc-sm-cma/ ++obj-$(CONFIG_SND_BCM2835) += bcm2835-audio/ ++obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-camera/ ++obj-$(CONFIG_BCM2835_VCHIQ_MMAL) += vchiq-mmal/ ++obj-$(CONFIG_BCM_VC_SM_CMA) += vc-sm-cma/ ++obj-$(CONFIG_VIDEO_CODEC_BCM2835) += bcm2835-codec/ + + ccflags-y += -Idrivers/staging/vc04_services -D__VCCOREVER__=0x04000000 + +--- /dev/null ++++ b/drivers/staging/vc04_services/bcm2835-codec/Kconfig +@@ -0,0 +1,11 @@ ++config VIDEO_CODEC_BCM2835 ++ tristate "BCM2835 Video codec support" ++ depends on MEDIA_SUPPORT ++ depends on VIDEO_V4L2 && (ARCH_BCM2835 || COMPILE_TEST) ++ select BCM2835_VCHIQ_MMAL ++ select VIDEOBUF2_DMA_CONTIG ++ select V4L2_MEM2MEM_DEV ++ help ++ Say Y here to enable the V4L2 video codecs for ++ Broadcom BCM2835 SoC. This operates over the VCHIQ interface ++ to a service running on VideoCore. +--- /dev/null ++++ b/drivers/staging/vc04_services/bcm2835-codec/Makefile +@@ -0,0 +1,8 @@ ++# SPDX-License-Identifier: GPL-2.0 ++bcm2835-codec-objs := bcm2835-v4l2-codec.o ++ ++obj-$(CONFIG_VIDEO_CODEC_BCM2835) += bcm2835-codec.o ++ ++ccflags-y += \ ++ -Idrivers/staging/vc04_services \ ++ -D__VCCOREVER__=0x04000000 +--- /dev/null ++++ b/drivers/staging/vc04_services/bcm2835-codec/TODO +@@ -0,0 +1,24 @@ ++1) Convert to be a platform driver. ++ ++Right now when the module probes, it tries to initialize VCHI and ++errors out if it wasn't ready yet. If bcm2835-v4l2 was built in, then ++VCHI generally isn't ready because it depends on both the firmware and ++mailbox drivers having already loaded. ++ ++We should have VCHI create a platform device once it's initialized, ++and have this driver bind to it, so that we automatically load the ++v4l2 module after VCHI loads. ++ ++2) Support SELECTION API to define crop region on the image for encode. ++ ++Particularly for resolutions that aren't a multiple of the macroblock ++size, the codec will report a resolution that is a multiple of the macroblock ++size (it has to have the memory to decode into), and then a different crop ++region within that buffer. ++The most common example is 1080P, where the buffer will be 1920x1088 with a ++crop region of 1920x1080. ++ ++3) Refactor so that the component creation is only on queue_setup, not open. ++ ++Fixes v4l2-compliance failure on trying to open 100 instances of the ++device. +\ No newline at end of file +--- /dev/null ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -0,0 +1,2359 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++/* ++ * A v4l2-mem2mem device that wraps the video codec MMAL component. ++ * ++ * Copyright 2018 Raspberry Pi (Trading) Ltd. ++ * Author: Dave Stevenson (dave.stevenson@raspberrypi.org) ++ * ++ * Loosely based on the vim2m virtual driver by Pawel Osciak ++ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. ++ * Pawel Osciak, ++ * Marek Szyprowski, ++ * ++ * Whilst this driver uses the v4l2_mem2mem framework, it does not need the ++ * scheduling aspects, so will always take the buffers, pass them to the VPU, ++ * and then signal the job as complete. ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "vchiq-mmal/mmal-encodings.h" ++#include "vchiq-mmal/mmal-msg.h" ++#include "vchiq-mmal/mmal-parameters.h" ++#include "vchiq-mmal/mmal-vchiq.h" ++ ++/* ++ * Default /dev/videoN node numbers for decode and encode. ++ * Deliberately avoid the very low numbers as these are often taken by webcams ++ * etc, and simple apps tend to only go for /dev/video0. ++ */ ++static int decode_video_nr = 10; ++module_param(decode_video_nr, int, 0644); ++MODULE_PARM_DESC(decode_video_nr, "decoder video device number"); ++ ++static int encode_video_nr = 11; ++module_param(encode_video_nr, int, 0644); ++MODULE_PARM_DESC(encode_video_nr, "encoder video device number"); ++ ++static unsigned int debug; ++module_param(debug, uint, 0644); ++MODULE_PARM_DESC(debug, "activates debug info (0-3)"); ++ ++#define MIN_W 32 ++#define MIN_H 32 ++#define MAX_W 1920 ++#define MAX_H 1088 ++#define BPL_ALIGN 32 ++#define DEFAULT_WIDTH 640 ++#define DEFAULT_HEIGHT 480 ++/* ++ * The unanswered question - what is the maximum size of a compressed frame? ++ * V4L2 mandates that the encoded frame must fit in a single buffer. Sizing ++ * that buffer is a compromise between wasting memory and risking not fitting. ++ * The 1080P version of Big Buck Bunny has some frames that exceed 512kB. ++ * Adopt a moderately arbitrary split at 720P for switching between 512 and ++ * 768kB buffers. ++ */ ++#define DEF_COMP_BUF_SIZE_GREATER_720P (768 << 10) ++#define DEF_COMP_BUF_SIZE_720P_OR_LESS (512 << 10) ++ ++/* Flags that indicate a format can be used for capture/output */ ++#define MEM2MEM_CAPTURE BIT(0) ++#define MEM2MEM_OUTPUT BIT(1) ++ ++#define MEM2MEM_NAME "bcm2835-codec" ++ ++struct bcm2835_codec_fmt { ++ u32 fourcc; ++ int depth; ++ int bytesperline_align; ++ u32 flags; ++ u32 mmal_fmt; ++ bool decode_only; ++ bool encode_only; ++ int size_multiplier_x2; ++}; ++ ++/* Supported raw pixel formats. Those supported for both encode and decode ++ * must come first, with those only supported for decode coming after (there ++ * are no formats supported for encode only). ++ */ ++static struct bcm2835_codec_fmt raw_formats[] = { ++ { ++ .fourcc = V4L2_PIX_FMT_YUV420, ++ .depth = 8, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_I420, ++ .size_multiplier_x2 = 3, ++ }, { ++ .fourcc = V4L2_PIX_FMT_YVU420, ++ .depth = 8, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_YV12, ++ .size_multiplier_x2 = 3, ++ }, { ++ .fourcc = V4L2_PIX_FMT_NV12, ++ .depth = 8, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_NV12, ++ .size_multiplier_x2 = 3, ++ }, { ++ .fourcc = V4L2_PIX_FMT_NV21, ++ .depth = 8, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_NV21, ++ .size_multiplier_x2 = 3, ++ }, { ++ .fourcc = V4L2_PIX_FMT_RGB565, ++ .depth = 16, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_RGB16, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_YUYV, ++ .depth = 16, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_YUYV, ++ .encode_only = true, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_UYVY, ++ .depth = 16, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_UYVY, ++ .encode_only = true, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_YVYU, ++ .depth = 16, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_YVYU, ++ .encode_only = true, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_VYUY, ++ .depth = 16, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_VYUY, ++ .encode_only = true, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_RGB24, ++ .depth = 24, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_RGB24, ++ .encode_only = true, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_BGR24, ++ .depth = 24, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BGR24, ++ .encode_only = true, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_BGR32, ++ .depth = 32, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BGRA, ++ .encode_only = true, ++ .size_multiplier_x2 = 2, ++ }, ++}; ++ ++/* Supported encoded formats. Those supported for both encode and decode ++ * must come first, with those only supported for decode coming after (there ++ * are no formats supported for encode only). ++ */ ++static struct bcm2835_codec_fmt encoded_formats[] = { ++ { ++ .fourcc = V4L2_PIX_FMT_H264, ++ .depth = 0, ++ .flags = V4L2_FMT_FLAG_COMPRESSED, ++ .mmal_fmt = MMAL_ENCODING_H264, ++ }, { ++ .fourcc = V4L2_PIX_FMT_MJPEG, ++ .depth = 0, ++ .flags = V4L2_FMT_FLAG_COMPRESSED, ++ .mmal_fmt = MMAL_ENCODING_MJPEG, ++ }, { ++ .fourcc = V4L2_PIX_FMT_MPEG4, ++ .depth = 0, ++ .flags = V4L2_FMT_FLAG_COMPRESSED, ++ .mmal_fmt = MMAL_ENCODING_MP4V, ++ .decode_only = true, ++ }, { ++ .fourcc = V4L2_PIX_FMT_H263, ++ .depth = 0, ++ .flags = V4L2_FMT_FLAG_COMPRESSED, ++ .mmal_fmt = MMAL_ENCODING_H263, ++ .decode_only = true, ++ }, { ++ .fourcc = V4L2_PIX_FMT_MPEG2, ++ .depth = 0, ++ .flags = V4L2_FMT_FLAG_COMPRESSED, ++ .mmal_fmt = MMAL_ENCODING_MP2V, ++ .decode_only = true, ++ }, { ++ .fourcc = V4L2_PIX_FMT_VP8, ++ .depth = 0, ++ .flags = V4L2_FMT_FLAG_COMPRESSED, ++ .mmal_fmt = MMAL_ENCODING_VP8, ++ .decode_only = true, ++ }, ++ /* ++ * This list couold include VP6 and Theorafor decode, but V4L2 doesn't ++ * support them. ++ */ ++}; ++ ++struct bcm2835_codec_fmt_list { ++ struct bcm2835_codec_fmt *list; ++ unsigned int num_entries; ++}; ++ ++#define RAW_LIST 0 ++#define ENCODED_LIST 1 ++ ++struct bcm2835_codec_fmt_list formats[] = { ++ { ++ .list = raw_formats, ++ .num_entries = ARRAY_SIZE(raw_formats), ++ }, { ++ .list = encoded_formats, ++ .num_entries = ARRAY_SIZE(encoded_formats), ++ }, ++}; ++ ++struct m2m_mmal_buffer { ++ struct v4l2_m2m_buffer m2m; ++ struct mmal_buffer mmal; ++}; ++ ++/* Per-queue, driver-specific private data */ ++struct bcm2835_codec_q_data { ++ /* ++ * These parameters should be treated as gospel, with everything else ++ * being determined from them. ++ */ ++ /* Buffer width/height */ ++ unsigned int bytesperline; ++ unsigned int height; ++ /* Crop size used for selection handling */ ++ unsigned int crop_width; ++ unsigned int crop_height; ++ bool selection_set; ++ ++ unsigned int sizeimage; ++ unsigned int sequence; ++ struct bcm2835_codec_fmt *fmt; ++ ++ /* One extra buffer header so we can send an EOS. */ ++ struct m2m_mmal_buffer eos_buffer; ++ bool eos_buffer_in_use; /* debug only */ ++}; ++ ++enum { ++ V4L2_M2M_SRC = 0, ++ V4L2_M2M_DST = 1, ++}; ++ ++static inline struct bcm2835_codec_fmt_list *get_format_list(bool decode, ++ bool capture) ++{ ++ return decode ^ capture ? &formats[ENCODED_LIST] : &formats[RAW_LIST]; ++} ++ ++static struct bcm2835_codec_fmt *get_default_format(bool decode, bool capture) ++{ ++ return &get_format_list(decode, capture)->list[0]; ++} ++ ++static struct bcm2835_codec_fmt *find_format(struct v4l2_format *f, bool decode, ++ bool capture) ++{ ++ struct bcm2835_codec_fmt *fmt; ++ unsigned int k; ++ struct bcm2835_codec_fmt_list *fmts = get_format_list(decode, capture); ++ ++ for (k = 0; k < fmts->num_entries; k++) { ++ fmt = &fmts->list[k]; ++ if (fmt->fourcc == f->fmt.pix.pixelformat) ++ break; ++ } ++ ++ /* ++ * Some compressed formats are only supported for decoding, not ++ * encoding. ++ */ ++ if (!decode && fmts->list[k].decode_only) ++ return NULL; ++ ++ /* Some pixel formats are only supported for encoding, not decoding. */ ++ if (decode && fmts->list[k].encode_only) ++ return NULL; ++ ++ if (k == fmts->num_entries) ++ return NULL; ++ ++ return &fmts->list[k]; ++} ++ ++struct bcm2835_codec_dev { ++ struct platform_device *pdev; ++ ++ /* v4l2 devices */ ++ struct v4l2_device v4l2_dev; ++ struct video_device vfd; ++ /* mutex for the v4l2 device */ ++ struct mutex dev_mutex; ++ atomic_t num_inst; ++ ++ /* allocated mmal instance and components */ ++ bool decode; /* Is this instance a decoder? */ ++ struct vchiq_mmal_instance *instance; ++ ++ struct v4l2_m2m_dev *m2m_dev; ++}; ++ ++struct bcm2835_codec_ctx { ++ struct v4l2_fh fh; ++ struct bcm2835_codec_dev *dev; ++ ++ struct v4l2_ctrl_handler hdl; ++ ++ struct vchiq_mmal_component *component; ++ bool component_enabled; ++ ++ enum v4l2_colorspace colorspace; ++ enum v4l2_ycbcr_encoding ycbcr_enc; ++ enum v4l2_xfer_func xfer_func; ++ enum v4l2_quantization quant; ++ ++ /* Source and destination queue data */ ++ struct bcm2835_codec_q_data q_data[2]; ++ s32 bitrate; ++ ++ bool aborting; ++ int num_ip_buffers; ++ int num_op_buffers; ++ struct completion frame_cmplt; ++}; ++ ++struct bcm2835_codec_driver { ++ struct bcm2835_codec_dev *encode; ++ struct bcm2835_codec_dev *decode; ++}; ++ ++static inline struct bcm2835_codec_ctx *file2ctx(struct file *file) ++{ ++ return container_of(file->private_data, struct bcm2835_codec_ctx, fh); ++} ++ ++static struct bcm2835_codec_q_data *get_q_data(struct bcm2835_codec_ctx *ctx, ++ enum v4l2_buf_type type) ++{ ++ switch (type) { ++ case V4L2_BUF_TYPE_VIDEO_OUTPUT: ++ return &ctx->q_data[V4L2_M2M_SRC]; ++ case V4L2_BUF_TYPE_VIDEO_CAPTURE: ++ return &ctx->q_data[V4L2_M2M_DST]; ++ default: ++ v4l2_err(&ctx->dev->v4l2_dev, "%s: Invalid queue type %u\n", ++ __func__, type); ++ break; ++ } ++ return NULL; ++} ++ ++static struct vchiq_mmal_port *get_port_data(struct bcm2835_codec_ctx *ctx, ++ enum v4l2_buf_type type) ++{ ++ if (!ctx->component) ++ return NULL; ++ ++ switch (type) { ++ case V4L2_BUF_TYPE_VIDEO_OUTPUT: ++ return &ctx->component->input[0]; ++ case V4L2_BUF_TYPE_VIDEO_CAPTURE: ++ return &ctx->component->output[0]; ++ default: ++ v4l2_err(&ctx->dev->v4l2_dev, "%s: Invalid queue type %u\n", ++ __func__, type); ++ break; ++ } ++ return NULL; ++} ++ ++/* ++ * mem2mem callbacks ++ */ ++ ++/** ++ * job_ready() - check whether an instance is ready to be scheduled to run ++ */ ++static int job_ready(void *priv) ++{ ++ struct bcm2835_codec_ctx *ctx = priv; ++ ++ if (!v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) && ++ !v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx)) ++ return 0; ++ ++ return 1; ++} ++ ++static void job_abort(void *priv) ++{ ++ struct bcm2835_codec_ctx *ctx = priv; ++ ++ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s\n", __func__); ++ /* Will cancel the transaction in the next interrupt handler */ ++ ctx->aborting = 1; ++} ++ ++static inline unsigned int get_sizeimage(int bpl, int height, ++ struct bcm2835_codec_fmt *fmt) ++{ ++ return (bpl * height * fmt->size_multiplier_x2) >> 1; ++} ++ ++static inline unsigned int get_bytesperline(int width, ++ struct bcm2835_codec_fmt *fmt) ++{ ++ return ALIGN((width * fmt->depth) >> 3, fmt->bytesperline_align); ++} ++ ++static void setup_mmal_port_format(struct bcm2835_codec_ctx *ctx, ++ bool decode, ++ struct bcm2835_codec_q_data *q_data, ++ struct vchiq_mmal_port *port) ++{ ++ port->format.encoding = q_data->fmt->mmal_fmt; ++ ++ if (!(q_data->fmt->flags & V4L2_FMT_FLAG_COMPRESSED)) { ++ /* Raw image format - set width/height */ ++ port->es.video.width = q_data->bytesperline / ++ (q_data->fmt->depth >> 3); ++ port->es.video.height = q_data->height; ++ port->es.video.crop.width = q_data->crop_width; ++ port->es.video.crop.height = q_data->crop_height; ++ port->es.video.frame_rate.num = 0; ++ port->es.video.frame_rate.den = 1; ++ } else { ++ /* Compressed format - leave resolution as 0 for decode */ ++ if (decode) { ++ port->es.video.width = 0; ++ port->es.video.height = 0; ++ port->es.video.crop.width = 0; ++ port->es.video.crop.height = 0; ++ } else { ++ port->es.video.width = q_data->crop_width; ++ port->es.video.height = q_data->height; ++ port->es.video.crop.width = q_data->crop_width; ++ port->es.video.crop.height = q_data->crop_height; ++ port->format.bitrate = ctx->bitrate; ++ } ++ port->es.video.frame_rate.num = 0; ++ port->es.video.frame_rate.den = 1; ++ } ++ port->es.video.crop.x = 0; ++ port->es.video.crop.y = 0; ++ ++ port->current_buffer.size = q_data->sizeimage; ++}; ++ ++static void ip_buffer_cb(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port, int status, ++ struct mmal_buffer *mmal_buf) ++{ ++ struct bcm2835_codec_ctx *ctx = port->cb_ctx/*, *curr_ctx*/; ++ struct m2m_mmal_buffer *buf = ++ container_of(mmal_buf, struct m2m_mmal_buffer, mmal); ++ ++ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: port %p buf %p length %lu, flags %x\n", ++ __func__, port, mmal_buf, mmal_buf->length, ++ mmal_buf->mmal_flags); ++ ++ if (buf == &ctx->q_data[V4L2_M2M_SRC].eos_buffer) { ++ /* Do we need to add lcoking to prevent multiple submission of ++ * the EOS, and therefore handle mutliple return here? ++ */ ++ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: eos buffer returned.\n", ++ __func__); ++ ctx->q_data[V4L2_M2M_SRC].eos_buffer_in_use = false; ++ return; ++ } ++ ++ if (status) { ++ /* error in transfer */ ++ if (buf) ++ /* there was a buffer with the error so return it */ ++ vb2_buffer_done(&buf->m2m.vb.vb2_buf, ++ VB2_BUF_STATE_ERROR); ++ return; ++ } ++ if (mmal_buf->cmd) { ++ v4l2_err(&ctx->dev->v4l2_dev, "%s: Not expecting cmd msgs on ip callback - %08x\n", ++ __func__, mmal_buf->cmd); ++ /* ++ * CHECKME: Should we return here. The buffer shouldn't have a ++ * message context or vb2 buf associated. ++ */ ++ } ++ ++ v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: no error. Return buffer %p\n", ++ __func__, &buf->m2m.vb.vb2_buf); ++ vb2_buffer_done(&buf->m2m.vb.vb2_buf, VB2_BUF_STATE_DONE); ++ ++ ctx->num_ip_buffers++; ++ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: done %d input buffers\n", ++ __func__, ctx->num_ip_buffers); ++ ++ if (!port->enabled) ++ complete(&ctx->frame_cmplt); ++} ++ ++static void queue_res_chg_event(struct bcm2835_codec_ctx *ctx) ++{ ++ static const struct v4l2_event ev_src_ch = { ++ .type = V4L2_EVENT_SOURCE_CHANGE, ++ .u.src_change.changes = ++ V4L2_EVENT_SRC_CH_RESOLUTION, ++ }; ++ ++ v4l2_event_queue_fh(&ctx->fh, &ev_src_ch); ++} ++ ++static void send_eos_event(struct bcm2835_codec_ctx *ctx) ++{ ++ static const struct v4l2_event ev = { ++ .type = V4L2_EVENT_EOS, ++ }; ++ ++ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Sending EOS event\n"); ++ ++ v4l2_event_queue_fh(&ctx->fh, &ev); ++} ++ ++static void color_mmal2v4l(struct bcm2835_codec_ctx *ctx, u32 mmal_color_space) ++{ ++ switch (mmal_color_space) { ++ case MMAL_COLOR_SPACE_ITUR_BT601: ++ ctx->colorspace = V4L2_COLORSPACE_REC709; ++ ctx->xfer_func = V4L2_XFER_FUNC_709; ++ ctx->ycbcr_enc = V4L2_YCBCR_ENC_601; ++ ctx->quant = V4L2_QUANTIZATION_LIM_RANGE; ++ break; ++ ++ case MMAL_COLOR_SPACE_ITUR_BT709: ++ ctx->colorspace = V4L2_COLORSPACE_REC709; ++ ctx->xfer_func = V4L2_XFER_FUNC_709; ++ ctx->ycbcr_enc = V4L2_YCBCR_ENC_709; ++ ctx->quant = V4L2_QUANTIZATION_LIM_RANGE; ++ break; ++ } ++} ++ ++static void handle_fmt_changed(struct bcm2835_codec_ctx *ctx, ++ struct mmal_buffer *mmal_buf) ++{ ++ struct bcm2835_codec_q_data *q_data; ++ struct mmal_msg_event_format_changed *format = ++ (struct mmal_msg_event_format_changed *)mmal_buf->buffer; ++ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Format changed: buff size min %u, rec %u, buff num min %u, rec %u\n", ++ __func__, ++ format->buffer_size_min, ++ format->buffer_size_recommended, ++ format->buffer_num_min, ++ format->buffer_num_recommended ++ ); ++ if (format->format.type != MMAL_ES_TYPE_VIDEO) { ++ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Format changed but not video %u\n", ++ __func__, format->format.type); ++ return; ++ } ++ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Format changed to %ux%u, crop %ux%u, colourspace %08X\n", ++ __func__, format->es.video.width, format->es.video.height, ++ format->es.video.crop.width, format->es.video.crop.height, ++ format->es.video.color_space); ++ ++ q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); ++ q_data->crop_width = format->es.video.crop.width; ++ q_data->crop_height = format->es.video.crop.height; ++ q_data->bytesperline = format->es.video.crop.width; ++ q_data->height = format->es.video.height; ++ q_data->sizeimage = format->buffer_size_min; ++ if (format->es.video.color_space) ++ color_mmal2v4l(ctx, format->es.video.color_space); ++ ++ queue_res_chg_event(ctx); ++} ++ ++static void op_buffer_cb(struct vchiq_mmal_instance *instance, ++ struct vchiq_mmal_port *port, int status, ++ struct mmal_buffer *mmal_buf) ++{ ++ struct bcm2835_codec_ctx *ctx = port->cb_ctx; ++ struct m2m_mmal_buffer *buf; ++ struct vb2_v4l2_buffer *vb2; ++ ++ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, ++ "%s: status:%d, buf:%p, length:%lu, flags %u, pts %lld\n", ++ __func__, status, mmal_buf, mmal_buf->length, ++ mmal_buf->mmal_flags, mmal_buf->pts); ++ ++ if (status) { ++ /* error in transfer */ ++ if (vb2) { ++ /* there was a buffer with the error so return it */ ++ vb2_buffer_done(&vb2->vb2_buf, VB2_BUF_STATE_ERROR); ++ } ++ return; ++ } ++ ++ if (mmal_buf->cmd) { ++ switch (mmal_buf->cmd) { ++ case MMAL_EVENT_FORMAT_CHANGED: ++ { ++ handle_fmt_changed(ctx, mmal_buf); ++ break; ++ } ++ default: ++ v4l2_err(&ctx->dev->v4l2_dev, "%s: Unexpected event on output callback - %08x\n", ++ __func__, mmal_buf->cmd); ++ break; ++ } ++ return; ++ } ++ ++ buf = container_of(mmal_buf, struct m2m_mmal_buffer, mmal); ++ vb2 = &buf->m2m.vb; ++ ++ v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: length %lu, flags %x, idx %u\n", ++ __func__, mmal_buf->length, mmal_buf->mmal_flags, ++ vb2->vb2_buf.index); ++ ++ if (mmal_buf->length == 0) { ++ /* stream ended, or buffer being returned during disable. */ ++ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: Empty buffer - flags %04x", ++ __func__, mmal_buf->mmal_flags); ++ if (!mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS) { ++ vb2_buffer_done(&vb2->vb2_buf, VB2_BUF_STATE_ERROR); ++ if (!port->enabled) ++ complete(&ctx->frame_cmplt); ++ return; ++ } ++ } ++ if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS) { ++ /* EOS packet from the VPU */ ++ send_eos_event(ctx); ++ vb2->flags |= V4L2_BUF_FLAG_LAST; ++ } ++ ++ vb2->vb2_buf.timestamp = mmal_buf->pts; ++ ++ vb2_set_plane_payload(&vb2->vb2_buf, 0, mmal_buf->length); ++ if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) ++ vb2->flags |= V4L2_BUF_FLAG_KEYFRAME; ++ ++ vb2_buffer_done(&vb2->vb2_buf, VB2_BUF_STATE_DONE); ++ ctx->num_op_buffers++; ++ ++ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: done %d output buffers\n", ++ __func__, ctx->num_op_buffers); ++ ++ if (!port->enabled) ++ complete(&ctx->frame_cmplt); ++} ++ ++/* vb2_to_mmal_buffer() - converts vb2 buffer header to MMAL ++ * ++ * Copies all the required fields from a VB2 buffer to the MMAL buffer header, ++ * ready for sending to the VPU. ++ */ ++static void vb2_to_mmal_buffer(struct m2m_mmal_buffer *buf, ++ struct vb2_v4l2_buffer *vb2) ++{ ++ buf->mmal.mmal_flags = 0; ++ if (vb2->flags & V4L2_BUF_FLAG_KEYFRAME) ++ buf->mmal.mmal_flags |= MMAL_BUFFER_HEADER_FLAG_KEYFRAME; ++ ++ /* ++ * Adding this means that the data must be framed correctly as one frame ++ * per buffer. The underlying decoder has no such requirement, but it ++ * will reduce latency as the bistream parser will be kicked immediately ++ * to parse the frame, rather than relying on its own heuristics for ++ * when to wake up. ++ */ ++ buf->mmal.mmal_flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END; ++ ++ buf->mmal.length = vb2->vb2_buf.planes[0].bytesused; ++ /* ++ * Minor ambiguity in the V4L2 spec as to whether passing in a 0 length ++ * buffer, or one with V4L2_BUF_FLAG_LAST set denotes end of stream. ++ * Handle either. ++ */ ++ if (!buf->mmal.length || vb2->flags & V4L2_BUF_FLAG_LAST) ++ buf->mmal.mmal_flags |= MMAL_BUFFER_HEADER_FLAG_EOS; ++ ++ buf->mmal.pts = vb2->vb2_buf.timestamp; ++ buf->mmal.dts = MMAL_TIME_UNKNOWN; ++} ++ ++/* device_run() - prepares and starts the device ++ * ++ * This simulates all the immediate preparations required before starting ++ * a device. This will be called by the framework when it decides to schedule ++ * a particular instance. ++ */ ++static void device_run(void *priv) ++{ ++ struct bcm2835_codec_ctx *ctx = priv; ++ struct bcm2835_codec_dev *dev = ctx->dev; ++ struct vb2_v4l2_buffer *src_buf, *dst_buf; ++ struct m2m_mmal_buffer *src_m2m_buf, *dst_m2m_buf; ++ struct v4l2_m2m_buffer *m2m; ++ int ret; ++ ++ v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: off we go\n", __func__); ++ ++ src_buf = v4l2_m2m_buf_remove(&ctx->fh.m2m_ctx->out_q_ctx); ++ if (src_buf) { ++ m2m = container_of(src_buf, struct v4l2_m2m_buffer, vb); ++ src_m2m_buf = container_of(m2m, struct m2m_mmal_buffer, m2m); ++ vb2_to_mmal_buffer(src_m2m_buf, src_buf); ++ ++ ret = vchiq_mmal_submit_buffer(dev->instance, ++ &ctx->component->input[0], ++ &src_m2m_buf->mmal); ++ v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: Submitted ip buffer len %lu, pts %llu, flags %04x\n", ++ __func__, src_m2m_buf->mmal.length, ++ src_m2m_buf->mmal.pts, src_m2m_buf->mmal.mmal_flags); ++ if (ret) ++ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed submitting ip buffer\n", ++ __func__); ++ } ++ ++ dst_buf = v4l2_m2m_buf_remove(&ctx->fh.m2m_ctx->cap_q_ctx); ++ if (dst_buf) { ++ m2m = container_of(dst_buf, struct v4l2_m2m_buffer, vb); ++ dst_m2m_buf = container_of(m2m, struct m2m_mmal_buffer, m2m); ++ vb2_to_mmal_buffer(dst_m2m_buf, dst_buf); ++ ++ ret = vchiq_mmal_submit_buffer(dev->instance, ++ &ctx->component->output[0], ++ &dst_m2m_buf->mmal); ++ if (ret) ++ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed submitting op buffer\n", ++ __func__); ++ } ++ ++ v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: Submitted src %p, dst %p\n", ++ __func__, src_m2m_buf, dst_m2m_buf); ++ ++ /* Complete the job here. */ ++ v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx); ++} ++ ++/* ++ * video ioctls ++ */ ++static int vidioc_querycap(struct file *file, void *priv, ++ struct v4l2_capability *cap) ++{ ++ strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1); ++ strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1); ++ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", ++ MEM2MEM_NAME); ++ cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; ++ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; ++ return 0; ++} ++ ++static int enum_fmt(struct v4l2_fmtdesc *f, bool decode, bool capture) ++{ ++ struct bcm2835_codec_fmt *fmt; ++ struct bcm2835_codec_fmt_list *fmts = get_format_list(decode, capture); ++ ++ if (f->index < fmts->num_entries) { ++ /* Format found */ ++ /* Check format isn't a decode only format when encoding */ ++ if (!decode && ++ fmts->list[f->index].decode_only) ++ return -EINVAL; ++ /* Check format isn't a decode only format when encoding */ ++ if (decode && ++ fmts->list[f->index].encode_only) ++ return -EINVAL; ++ ++ fmt = &fmts->list[f->index]; ++ f->pixelformat = fmt->fourcc; ++ f->flags = fmt->flags; ++ return 0; ++ } ++ ++ /* Format not found */ ++ return -EINVAL; ++} ++ ++static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, ++ struct v4l2_fmtdesc *f) ++{ ++ struct bcm2835_codec_ctx *ctx = file2ctx(file); ++ ++ return enum_fmt(f, ctx->dev->decode, true); ++} ++ ++static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, ++ struct v4l2_fmtdesc *f) ++{ ++ struct bcm2835_codec_ctx *ctx = file2ctx(file); ++ ++ return enum_fmt(f, ctx->dev->decode, false); ++} ++ ++static int vidioc_g_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f) ++{ ++ struct vb2_queue *vq; ++ struct bcm2835_codec_q_data *q_data; ++ ++ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); ++ if (!vq) ++ return -EINVAL; ++ ++ q_data = get_q_data(ctx, f->type); ++ ++ f->fmt.pix.width = q_data->crop_width; ++ f->fmt.pix.height = q_data->height; ++ f->fmt.pix.field = V4L2_FIELD_NONE; ++ f->fmt.pix.pixelformat = q_data->fmt->fourcc; ++ f->fmt.pix.bytesperline = q_data->bytesperline; ++ f->fmt.pix.sizeimage = q_data->sizeimage; ++ f->fmt.pix.colorspace = ctx->colorspace; ++ f->fmt.pix.xfer_func = ctx->xfer_func; ++ f->fmt.pix.ycbcr_enc = ctx->ycbcr_enc; ++ f->fmt.pix.quantization = ctx->quant; ++ ++ return 0; ++} ++ ++static int vidioc_g_fmt_vid_out(struct file *file, void *priv, ++ struct v4l2_format *f) ++{ ++ return vidioc_g_fmt(file2ctx(file), f); ++} ++ ++static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, ++ struct v4l2_format *f) ++{ ++ return vidioc_g_fmt(file2ctx(file), f); ++} ++ ++static int vidioc_try_fmt(struct v4l2_format *f, struct bcm2835_codec_fmt *fmt) ++{ ++ /* ++ * The V4L2 specification requires the driver to correct the format ++ * struct if any of the dimensions is unsupported ++ */ ++ if (f->fmt.pix.width > MAX_W) ++ f->fmt.pix.width = MAX_W; ++ if (f->fmt.pix.height > MAX_H) ++ f->fmt.pix.height = MAX_H; ++ ++ if (!fmt->flags & V4L2_FMT_FLAG_COMPRESSED) { ++ /* Only clip min w/h on capture. Treat 0x0 as unknown. */ ++ if (f->fmt.pix.width < MIN_W) ++ f->fmt.pix.width = MIN_W; ++ if (f->fmt.pix.height < MIN_H) ++ f->fmt.pix.height = MIN_H; ++ ++ /* ++ * Buffer must have a vertical alignment of 16 lines. ++ * The selection will reflect any cropping rectangle when only ++ * some of the pixels are active. ++ */ ++ f->fmt.pix.height = ALIGN(f->fmt.pix.height, 16); ++ ++ f->fmt.pix.bytesperline = get_bytesperline(f->fmt.pix.width, ++ fmt); ++ f->fmt.pix.sizeimage = get_sizeimage(f->fmt.pix.bytesperline, ++ f->fmt.pix.height, ++ fmt); ++ } else { ++ u32 min_size = f->fmt.pix.width > 1280 || ++ f->fmt.pix.height > 720 ? ++ DEF_COMP_BUF_SIZE_GREATER_720P : ++ DEF_COMP_BUF_SIZE_720P_OR_LESS; ++ ++ f->fmt.pix.bytesperline = 0; ++ if (f->fmt.pix.sizeimage < min_size) ++ f->fmt.pix.sizeimage = min_size; ++ } ++ ++ f->fmt.pix.field = V4L2_FIELD_NONE; ++ ++ return 0; ++} ++ ++static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, ++ struct v4l2_format *f) ++{ ++ struct bcm2835_codec_fmt *fmt; ++ struct bcm2835_codec_ctx *ctx = file2ctx(file); ++ ++ fmt = find_format(f, ctx->dev->decode, true); ++ if (!fmt) { ++ f->fmt.pix.pixelformat = get_default_format(ctx->dev->decode, ++ true)->fourcc; ++ fmt = find_format(f, ctx->dev->decode, true); ++ } ++ ++ return vidioc_try_fmt(f, fmt); ++} ++ ++static int vidioc_try_fmt_vid_out(struct file *file, void *priv, ++ struct v4l2_format *f) ++{ ++ struct bcm2835_codec_fmt *fmt; ++ struct bcm2835_codec_ctx *ctx = file2ctx(file); ++ ++ fmt = find_format(f, ctx->dev->decode, false); ++ if (!fmt) { ++ f->fmt.pix.pixelformat = get_default_format(ctx->dev->decode, ++ false)->fourcc; ++ fmt = find_format(f, ctx->dev->decode, false); ++ } ++ ++ if (!f->fmt.pix.colorspace) ++ f->fmt.pix.colorspace = ctx->colorspace; ++ ++ return vidioc_try_fmt(f, fmt); ++} ++ ++static int vidioc_s_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f, ++ unsigned int requested_height) ++{ ++ struct bcm2835_codec_q_data *q_data; ++ struct vb2_queue *vq; ++ struct vchiq_mmal_port *port; ++ bool update_capture_port = false; ++ int ret; ++ ++ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Setting format for type %d, wxh: %dx%d, fmt: %08x, size %u\n", ++ f->type, f->fmt.pix.width, f->fmt.pix.height, ++ f->fmt.pix.pixelformat, f->fmt.pix.sizeimage); ++ ++ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); ++ if (!vq) ++ return -EINVAL; ++ ++ q_data = get_q_data(ctx, f->type); ++ if (!q_data) ++ return -EINVAL; ++ ++ if (vb2_is_busy(vq)) { ++ v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__); ++ return -EBUSY; ++ } ++ ++ q_data->fmt = find_format(f, ctx->dev->decode, ++ f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE); ++ q_data->crop_width = f->fmt.pix.width; ++ q_data->height = f->fmt.pix.height; ++ if (!q_data->selection_set) ++ q_data->crop_height = requested_height; ++ ++ /* ++ * Copying the behaviour of vicodec which retains a single set of ++ * colorspace parameters for both input and output. ++ */ ++ ctx->colorspace = f->fmt.pix.colorspace; ++ ctx->xfer_func = f->fmt.pix.xfer_func; ++ ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc; ++ ctx->quant = f->fmt.pix.quantization; ++ ++ /* All parameters should have been set correctly by try_fmt */ ++ q_data->bytesperline = f->fmt.pix.bytesperline; ++ q_data->sizeimage = f->fmt.pix.sizeimage; ++ ++ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Calulated bpl as %u, size %u\n", ++ q_data->bytesperline, q_data->sizeimage); ++ ++ if (ctx->dev->decode && q_data->fmt->flags & V4L2_FMT_FLAG_COMPRESSED && ++ f->fmt.pix.width && f->fmt.pix.height) { ++ /* ++ * On the decoder, if provided with a resolution on the input ++ * side, then replicate that to the output side. ++ * GStreamer appears not to support V4L2_EVENT_SOURCE_CHANGE, ++ * nor set up a resolution on the output side, therefore ++ * we can't decode anything at a resolution other than the ++ * default one. ++ */ ++ struct bcm2835_codec_q_data *q_data_dst = ++ &ctx->q_data[V4L2_M2M_DST]; ++ ++ q_data_dst->crop_width = q_data->crop_width; ++ q_data_dst->crop_height = q_data->crop_height; ++ q_data_dst->height = ALIGN(q_data->crop_height, 16); ++ ++ q_data_dst->bytesperline = ++ get_bytesperline(f->fmt.pix.width, q_data_dst->fmt); ++ q_data_dst->sizeimage = get_sizeimage(q_data_dst->bytesperline, ++ q_data_dst->height, ++ q_data_dst->fmt); ++ update_capture_port = true; ++ } ++ ++ /* If we have a component then setup the port as well */ ++ port = get_port_data(ctx, vq->type); ++ if (!port) ++ return 0; ++ ++ setup_mmal_port_format(ctx, ctx->dev->decode, q_data, port); ++ ret = vchiq_mmal_port_set_format(ctx->dev->instance, port); ++ if (ret) { ++ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed vchiq_mmal_port_set_format on port, ret %d\n", ++ __func__, ret); ++ ret = -EINVAL; ++ } ++ ++ if (q_data->sizeimage < port->minimum_buffer.size) { ++ v4l2_err(&ctx->dev->v4l2_dev, "%s: Current buffer size of %u < min buf size %u - driver mismatch to MMAL\n", ++ __func__, q_data->sizeimage, ++ port->minimum_buffer.size); ++ } ++ ++ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Set format for type %d, wxh: %dx%d, fmt: %08x, size %u\n", ++ f->type, q_data->crop_width, q_data->height, ++ q_data->fmt->fourcc, q_data->sizeimage); ++ ++ if (update_capture_port) { ++ struct vchiq_mmal_port *port_dst = &ctx->component->output[0]; ++ struct bcm2835_codec_q_data *q_data_dst = ++ &ctx->q_data[V4L2_M2M_DST]; ++ ++ setup_mmal_port_format(ctx, ctx->dev->decode, q_data_dst, ++ port_dst); ++ ret = vchiq_mmal_port_set_format(ctx->dev->instance, port_dst); ++ if (ret) { ++ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed vchiq_mmal_port_set_format on output port, ret %d\n", ++ __func__, ret); ++ ret = -EINVAL; ++ } ++ } ++ return ret; ++} ++ ++static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, ++ struct v4l2_format *f) ++{ ++ unsigned int height = f->fmt.pix.height; ++ int ret; ++ ++ ret = vidioc_try_fmt_vid_cap(file, priv, f); ++ if (ret) ++ return ret; ++ ++ return vidioc_s_fmt(file2ctx(file), f, height); ++} ++ ++static int vidioc_s_fmt_vid_out(struct file *file, void *priv, ++ struct v4l2_format *f) ++{ ++ unsigned int height = f->fmt.pix.height; ++ int ret; ++ ++ ret = vidioc_try_fmt_vid_out(file, priv, f); ++ if (ret) ++ return ret; ++ ++ ret = vidioc_s_fmt(file2ctx(file), f, height); ++ return ret; ++} ++ ++static int vidioc_g_selection(struct file *file, void *priv, ++ struct v4l2_selection *s) ++{ ++ struct bcm2835_codec_ctx *ctx = file2ctx(file); ++ struct bcm2835_codec_q_data *q_data; ++ bool capture_queue = s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? ++ true : false; ++ ++ if (capture_queue ^ ctx->dev->decode) ++ /* OUTPUT on decoder and CAPTURE on encoder are not valid. */ ++ return -EINVAL; ++ ++ q_data = get_q_data(ctx, s->type); ++ if (!q_data) ++ return -EINVAL; ++ ++ if (ctx->dev->decode) { ++ switch (s->target) { ++ case V4L2_SEL_TGT_COMPOSE_DEFAULT: ++ case V4L2_SEL_TGT_COMPOSE: ++ s->r.left = 0; ++ s->r.top = 0; ++ s->r.width = q_data->crop_width; ++ s->r.height = q_data->crop_height; ++ break; ++ case V4L2_SEL_TGT_COMPOSE_BOUNDS: ++ s->r.left = 0; ++ s->r.top = 0; ++ s->r.width = q_data->crop_width; ++ s->r.height = q_data->crop_height; ++ break; ++ default: ++ return -EINVAL; ++ } ++ } else { ++ switch (s->target) { ++ case V4L2_SEL_TGT_CROP_DEFAULT: ++ case V4L2_SEL_TGT_CROP_BOUNDS: ++ s->r.top = 0; ++ s->r.left = 0; ++ s->r.width = q_data->bytesperline; ++ s->r.height = q_data->height; ++ break; ++ case V4L2_SEL_TGT_CROP: ++ s->r.top = 0; ++ s->r.left = 0; ++ s->r.width = q_data->crop_width; ++ s->r.height = q_data->crop_height; ++ break; ++ default: ++ return -EINVAL; ++ } ++ } ++ ++ return 0; ++} ++ ++static int vidioc_s_selection(struct file *file, void *priv, ++ struct v4l2_selection *s) ++{ ++ struct bcm2835_codec_ctx *ctx = file2ctx(file); ++ struct bcm2835_codec_q_data *q_data = NULL; ++ bool capture_queue = s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? ++ true : false; ++ ++ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: ctx %p, type %d, q_data %p, target %d, rect x/y %d/%d, w/h %ux%u\n", ++ __func__, ctx, s->type, q_data, s->target, s->r.left, s->r.top, ++ s->r.width, s->r.height); ++ ++ if (capture_queue ^ ctx->dev->decode) ++ /* OUTPUT on decoder and CAPTURE on encoder are not valid. */ ++ return -EINVAL; ++ ++ q_data = get_q_data(ctx, s->type); ++ if (!q_data) ++ return -EINVAL; ++ ++ if (ctx->dev->decode) { ++ switch (s->target) { ++ case V4L2_SEL_TGT_COMPOSE: ++ /* Accept cropped image */ ++ s->r.left = 0; ++ s->r.top = 0; ++ s->r.width = min(s->r.width, q_data->crop_width); ++ s->r.height = min(s->r.height, q_data->height); ++ q_data->crop_width = s->r.width; ++ q_data->crop_height = s->r.height; ++ q_data->selection_set = true; ++ break; ++ default: ++ return -EINVAL; ++ } ++ } else { ++ switch (s->target) { ++ case V4L2_SEL_TGT_CROP: ++ /* Only support crop from (0,0) */ ++ s->r.top = 0; ++ s->r.left = 0; ++ s->r.width = min(s->r.width, q_data->crop_width); ++ s->r.height = min(s->r.height, q_data->crop_height); ++ q_data->crop_width = s->r.width; ++ q_data->crop_height = s->r.height; ++ q_data->selection_set = true; ++ break; ++ default: ++ return -EINVAL; ++ } ++ } ++ ++ return 0; ++} ++ ++static int vidioc_subscribe_evt(struct v4l2_fh *fh, ++ const struct v4l2_event_subscription *sub) ++{ ++ switch (sub->type) { ++ case V4L2_EVENT_EOS: ++ return v4l2_event_subscribe(fh, sub, 2, NULL); ++ case V4L2_EVENT_SOURCE_CHANGE: ++ return v4l2_src_change_event_subscribe(fh, sub); ++ default: ++ return v4l2_ctrl_subscribe_event(fh, sub); ++ } ++} ++ ++static int bcm2835_codec_set_level_profile(struct bcm2835_codec_ctx *ctx, ++ struct v4l2_ctrl *ctrl) ++{ ++ struct mmal_parameter_video_profile param; ++ int param_size = sizeof(param); ++ int ret; ++ ++ /* ++ * Level and Profile are set via the same MMAL parameter. ++ * Retrieve the current settings and amend the one that has changed. ++ */ ++ ret = vchiq_mmal_port_parameter_get(ctx->dev->instance, ++ &ctx->component->output[0], ++ MMAL_PARAMETER_PROFILE, ++ ¶m, ++ ¶m_size); ++ if (ret) ++ return ret; ++ ++ switch (ctrl->id) { ++ case V4L2_CID_MPEG_VIDEO_H264_PROFILE: ++ switch (ctrl->val) { ++ case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: ++ param.profile = MMAL_VIDEO_PROFILE_H264_BASELINE; ++ break; ++ case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: ++ param.profile = ++ MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE; ++ break; ++ case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: ++ param.profile = MMAL_VIDEO_PROFILE_H264_MAIN; ++ break; ++ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: ++ param.profile = MMAL_VIDEO_PROFILE_H264_HIGH; ++ break; ++ default: ++ /* Should never get here */ ++ break; ++ } ++ break; ++ ++ case V4L2_CID_MPEG_VIDEO_H264_LEVEL: ++ switch (ctrl->val) { ++ case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: ++ param.level = MMAL_VIDEO_LEVEL_H264_1; ++ break; ++ case V4L2_MPEG_VIDEO_H264_LEVEL_1B: ++ param.level = MMAL_VIDEO_LEVEL_H264_1b; ++ break; ++ case V4L2_MPEG_VIDEO_H264_LEVEL_1_1: ++ param.level = MMAL_VIDEO_LEVEL_H264_11; ++ break; ++ case V4L2_MPEG_VIDEO_H264_LEVEL_1_2: ++ param.level = MMAL_VIDEO_LEVEL_H264_12; ++ break; ++ case V4L2_MPEG_VIDEO_H264_LEVEL_1_3: ++ param.level = MMAL_VIDEO_LEVEL_H264_13; ++ break; ++ case V4L2_MPEG_VIDEO_H264_LEVEL_2_0: ++ param.level = MMAL_VIDEO_LEVEL_H264_2; ++ break; ++ case V4L2_MPEG_VIDEO_H264_LEVEL_2_1: ++ param.level = MMAL_VIDEO_LEVEL_H264_21; ++ break; ++ case V4L2_MPEG_VIDEO_H264_LEVEL_2_2: ++ param.level = MMAL_VIDEO_LEVEL_H264_22; ++ break; ++ case V4L2_MPEG_VIDEO_H264_LEVEL_3_0: ++ param.level = MMAL_VIDEO_LEVEL_H264_3; ++ break; ++ case V4L2_MPEG_VIDEO_H264_LEVEL_3_1: ++ param.level = MMAL_VIDEO_LEVEL_H264_31; ++ break; ++ case V4L2_MPEG_VIDEO_H264_LEVEL_3_2: ++ param.level = MMAL_VIDEO_LEVEL_H264_32; ++ break; ++ case V4L2_MPEG_VIDEO_H264_LEVEL_4_0: ++ param.level = MMAL_VIDEO_LEVEL_H264_4; ++ break; ++ default: ++ /* Should never get here */ ++ break; ++ } ++ } ++ ret = vchiq_mmal_port_parameter_set(ctx->dev->instance, ++ &ctx->component->output[0], ++ MMAL_PARAMETER_PROFILE, ++ ¶m, ++ param_size); ++ ++ return ret; ++} ++ ++static int bcm2835_codec_s_ctrl(struct v4l2_ctrl *ctrl) ++{ ++ struct bcm2835_codec_ctx *ctx = ++ container_of(ctrl->handler, struct bcm2835_codec_ctx, hdl); ++ int ret = 0; ++ ++ switch (ctrl->id) { ++ case V4L2_CID_MPEG_VIDEO_BITRATE: ++ ctx->bitrate = ctrl->val; ++ if (!ctx->component) ++ break; ++ ++ ret = vchiq_mmal_port_parameter_set(ctx->dev->instance, ++ &ctx->component->output[0], ++ MMAL_PARAMETER_VIDEO_BIT_RATE, ++ &ctrl->val, ++ sizeof(ctrl->val)); ++ break; ++ ++ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: { ++ u32 bitrate_mode; ++ ++ if (!ctx->component) ++ break; ++ ++ switch (ctrl->val) { ++ default: ++ case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR: ++ bitrate_mode = MMAL_VIDEO_RATECONTROL_VARIABLE; ++ break; ++ case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR: ++ bitrate_mode = MMAL_VIDEO_RATECONTROL_CONSTANT; ++ break; ++ } ++ ++ ret = vchiq_mmal_port_parameter_set(ctx->dev->instance, ++ &ctx->component->output[0], ++ MMAL_PARAMETER_RATECONTROL, ++ &bitrate_mode, ++ sizeof(bitrate_mode)); ++ break; ++ } ++ case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER: ++ if (!ctx->component) ++ break; ++ ++ ret = vchiq_mmal_port_parameter_set(ctx->dev->instance, ++ &ctx->component->output[0], ++ MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER, ++ &ctrl->val, ++ sizeof(ctrl->val)); ++ break; ++ ++ case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: ++ if (!ctx->component) ++ break; ++ ++ ret = vchiq_mmal_port_parameter_set(ctx->dev->instance, ++ &ctx->component->output[0], ++ MMAL_PARAMETER_INTRAPERIOD, ++ &ctrl->val, ++ sizeof(ctrl->val)); ++ break; ++ ++ case V4L2_CID_MPEG_VIDEO_H264_PROFILE: ++ case V4L2_CID_MPEG_VIDEO_H264_LEVEL: ++ if (!ctx->component) ++ break; ++ ++ ret = bcm2835_codec_set_level_profile(ctx, ctrl); ++ break; ++ ++ default: ++ v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n"); ++ return -EINVAL; ++ } ++ ++ if (ret) ++ v4l2_err(&ctx->dev->v4l2_dev, "Failed setting ctrl %08x, ret %d\n", ++ ctrl->id, ret); ++ return ret ? -EINVAL : 0; ++} ++ ++static const struct v4l2_ctrl_ops bcm2835_codec_ctrl_ops = { ++ .s_ctrl = bcm2835_codec_s_ctrl, ++}; ++ ++static int vidioc_try_decoder_cmd(struct file *file, void *priv, ++ struct v4l2_decoder_cmd *cmd) ++{ ++ struct bcm2835_codec_ctx *ctx = file2ctx(file); ++ ++ if (!ctx->dev->decode) ++ return -EINVAL; ++ ++ switch (cmd->cmd) { ++ case V4L2_DEC_CMD_STOP: ++ if (cmd->flags & V4L2_DEC_CMD_STOP_TO_BLACK) { ++ v4l2_err(&ctx->dev->v4l2_dev, "%s: DEC cmd->flags=%u stop to black not supported", ++ __func__, cmd->flags); ++ return -EINVAL; ++ } ++ break; ++ case V4L2_DEC_CMD_START: ++ break; ++ default: ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static int vidioc_decoder_cmd(struct file *file, void *priv, ++ struct v4l2_decoder_cmd *cmd) ++{ ++ struct bcm2835_codec_ctx *ctx = file2ctx(file); ++ struct bcm2835_codec_q_data *q_data = &ctx->q_data[V4L2_M2M_SRC]; ++ int ret; ++ ++ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s, cmd %u", __func__, ++ cmd->cmd); ++ ret = vidioc_try_decoder_cmd(file, priv, cmd); ++ if (ret) ++ return ret; ++ ++ switch (cmd->cmd) { ++ case V4L2_DEC_CMD_STOP: ++ if (q_data->eos_buffer_in_use) ++ v4l2_err(&ctx->dev->v4l2_dev, "EOS buffers already in use\n"); ++ q_data->eos_buffer_in_use = true; ++ ++ q_data->eos_buffer.mmal.buffer_size = 0; ++ q_data->eos_buffer.mmal.length = 0; ++ q_data->eos_buffer.mmal.mmal_flags = ++ MMAL_BUFFER_HEADER_FLAG_EOS; ++ q_data->eos_buffer.mmal.pts = 0; ++ q_data->eos_buffer.mmal.dts = 0; ++ ++ if (!ctx->component) ++ break; ++ ++ ret = vchiq_mmal_submit_buffer(ctx->dev->instance, ++ &ctx->component->input[0], ++ &q_data->eos_buffer.mmal); ++ if (ret) ++ v4l2_err(&ctx->dev->v4l2_dev, ++ "%s: EOS buffer submit failed %d\n", ++ __func__, ret); ++ ++ break; ++ ++ case V4L2_DEC_CMD_START: ++ /* Do we need to do anything here? */ ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int vidioc_try_encoder_cmd(struct file *file, void *priv, ++ struct v4l2_encoder_cmd *cmd) ++{ ++ struct bcm2835_codec_ctx *ctx = file2ctx(file); ++ ++ if (ctx->dev->decode) ++ return -EINVAL; ++ ++ switch (cmd->cmd) { ++ case V4L2_ENC_CMD_STOP: ++ break; ++ ++ case V4L2_ENC_CMD_START: ++ /* Do we need to do anything here? */ ++ break; ++ default: ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static int vidioc_encoder_cmd(struct file *file, void *priv, ++ struct v4l2_encoder_cmd *cmd) ++{ ++ struct bcm2835_codec_ctx *ctx = file2ctx(file); ++ struct bcm2835_codec_q_data *q_data = &ctx->q_data[V4L2_M2M_SRC]; ++ int ret; ++ ++ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s, cmd %u", __func__, ++ cmd->cmd); ++ ret = vidioc_try_encoder_cmd(file, priv, cmd); ++ if (ret) ++ return ret; ++ ++ switch (cmd->cmd) { ++ case V4L2_ENC_CMD_STOP: ++ if (q_data->eos_buffer_in_use) ++ v4l2_err(&ctx->dev->v4l2_dev, "EOS buffers already in use\n"); ++ q_data->eos_buffer_in_use = true; ++ ++ q_data->eos_buffer.mmal.buffer_size = 0; ++ q_data->eos_buffer.mmal.length = 0; ++ q_data->eos_buffer.mmal.mmal_flags = ++ MMAL_BUFFER_HEADER_FLAG_EOS; ++ q_data->eos_buffer.mmal.pts = 0; ++ q_data->eos_buffer.mmal.dts = 0; ++ ++ if (!ctx->component) ++ break; ++ ++ ret = vchiq_mmal_submit_buffer(ctx->dev->instance, ++ &ctx->component->input[0], ++ &q_data->eos_buffer.mmal); ++ if (ret) ++ v4l2_err(&ctx->dev->v4l2_dev, ++ "%s: EOS buffer submit failed %d\n", ++ __func__, ret); ++ ++ break; ++ case V4L2_ENC_CMD_START: ++ /* Do we need to do anything here? */ ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static const struct v4l2_ioctl_ops bcm2835_codec_ioctl_ops = { ++ .vidioc_querycap = vidioc_querycap, ++ ++ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, ++ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, ++ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, ++ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, ++ ++ .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out, ++ .vidioc_g_fmt_vid_out = vidioc_g_fmt_vid_out, ++ .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out, ++ .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out, ++ ++ .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, ++ .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, ++ .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, ++ .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, ++ .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, ++ .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, ++ .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, ++ ++ .vidioc_streamon = v4l2_m2m_ioctl_streamon, ++ .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, ++ ++ .vidioc_g_selection = vidioc_g_selection, ++ .vidioc_s_selection = vidioc_s_selection, ++ ++ .vidioc_subscribe_event = vidioc_subscribe_evt, ++ .vidioc_unsubscribe_event = v4l2_event_unsubscribe, ++ ++ .vidioc_decoder_cmd = vidioc_decoder_cmd, ++ .vidioc_try_decoder_cmd = vidioc_try_decoder_cmd, ++ .vidioc_encoder_cmd = vidioc_encoder_cmd, ++ .vidioc_try_encoder_cmd = vidioc_try_encoder_cmd, ++}; ++ ++static int bcm2835_codec_set_ctrls(struct bcm2835_codec_ctx *ctx) ++{ ++ /* ++ * Query the control handler for the value of the various controls and ++ * set them. ++ */ ++ const u32 control_ids[] = { ++ V4L2_CID_MPEG_VIDEO_BITRATE_MODE, ++ V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, ++ V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, ++ V4L2_CID_MPEG_VIDEO_H264_LEVEL, ++ V4L2_CID_MPEG_VIDEO_H264_PROFILE, ++ }; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(control_ids); i++) { ++ struct v4l2_ctrl *ctrl; ++ ++ ctrl = v4l2_ctrl_find(&ctx->hdl, control_ids[i]); ++ if (ctrl) ++ bcm2835_codec_s_ctrl(ctrl); ++ } ++ ++ return 0; ++} ++ ++static int bcm2835_codec_create_component(struct bcm2835_codec_ctx *ctx) ++{ ++ struct bcm2835_codec_dev *dev = ctx->dev; ++ unsigned int enable = 1; ++ int ret; ++ ++ ret = vchiq_mmal_component_init(dev->instance, dev->decode ? ++ "ril.video_decode" : "ril.video_encode", ++ &ctx->component); ++ if (ret < 0) { ++ v4l2_err(&dev->v4l2_dev, "%s: failed to create component for %s\n", ++ __func__, dev->decode ? "decode" : "encode"); ++ return -ENOMEM; ++ } ++ ++ vchiq_mmal_port_parameter_set(dev->instance, &ctx->component->input[0], ++ MMAL_PARAMETER_ZERO_COPY, &enable, ++ sizeof(enable)); ++ vchiq_mmal_port_parameter_set(dev->instance, &ctx->component->output[0], ++ MMAL_PARAMETER_ZERO_COPY, &enable, ++ sizeof(enable)); ++ ++ setup_mmal_port_format(ctx, dev->decode, &ctx->q_data[V4L2_M2M_SRC], ++ &ctx->component->input[0]); ++ ++ setup_mmal_port_format(ctx, dev->decode, &ctx->q_data[V4L2_M2M_DST], ++ &ctx->component->output[0]); ++ ++ ret = vchiq_mmal_port_set_format(dev->instance, ++ &ctx->component->input[0]); ++ if (ret < 0) ++ goto destroy_component; ++ ++ ret = vchiq_mmal_port_set_format(dev->instance, ++ &ctx->component->output[0]); ++ if (ret < 0) ++ goto destroy_component; ++ ++ if (dev->decode) { ++ if (ctx->q_data[V4L2_M2M_DST].sizeimage < ++ ctx->component->output[0].minimum_buffer.size) ++ v4l2_err(&dev->v4l2_dev, "buffer size mismatch sizeimage %u < min size %u\n", ++ ctx->q_data[V4L2_M2M_DST].sizeimage, ++ ctx->component->output[0].minimum_buffer.size); ++ } else { ++ if (ctx->q_data[V4L2_M2M_SRC].sizeimage < ++ ctx->component->output[0].minimum_buffer.size) ++ v4l2_err(&dev->v4l2_dev, "buffer size mismatch sizeimage %u < min size %u\n", ++ ctx->q_data[V4L2_M2M_SRC].sizeimage, ++ ctx->component->output[0].minimum_buffer.size); ++ ++ /* Now we have a component we can set all the ctrls */ ++ bcm2835_codec_set_ctrls(ctx); ++ } ++ ++ return 0; ++ ++destroy_component: ++ vchiq_mmal_component_finalise(ctx->dev->instance, ctx->component); ++ ++ return ret; ++} ++ ++/* ++ * Queue operations ++ */ ++ ++static int bcm2835_codec_queue_setup(struct vb2_queue *vq, ++ unsigned int *nbuffers, ++ unsigned int *nplanes, ++ unsigned int sizes[], ++ struct device *alloc_devs[]) ++{ ++ struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vq); ++ struct bcm2835_codec_q_data *q_data; ++ struct vchiq_mmal_port *port; ++ unsigned int size; ++ ++ q_data = get_q_data(ctx, vq->type); ++ if (!q_data) ++ return -EINVAL; ++ ++ if (!ctx->component) ++ if (bcm2835_codec_create_component(ctx)) ++ return -EINVAL; ++ ++ port = get_port_data(ctx, vq->type); ++ ++ size = q_data->sizeimage; ++ ++ if (*nplanes) ++ return sizes[0] < size ? -EINVAL : 0; ++ ++ *nplanes = 1; ++ ++ sizes[0] = size; ++ port->current_buffer.size = size; ++ ++ if (*nbuffers < port->minimum_buffer.num) ++ *nbuffers = port->minimum_buffer.num; ++ /* Add one buffer to take an EOS */ ++ port->current_buffer.num = *nbuffers + 1; ++ ++ return 0; ++} ++ ++static int bcm2835_codec_buf_init(struct vb2_buffer *vb) ++{ ++ struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); ++ struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb); ++ struct v4l2_m2m_buffer *m2m = container_of(vb2, struct v4l2_m2m_buffer, ++ vb); ++ struct m2m_mmal_buffer *buf = container_of(m2m, struct m2m_mmal_buffer, ++ m2m); ++ ++ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: ctx:%p, vb %p\n", ++ __func__, ctx, vb); ++ buf->mmal.buffer = vb2_plane_vaddr(&buf->m2m.vb.vb2_buf, 0); ++ buf->mmal.buffer_size = vb2_plane_size(&buf->m2m.vb.vb2_buf, 0); ++ ++ mmal_vchi_buffer_init(ctx->dev->instance, &buf->mmal); ++ ++ return 0; ++} ++ ++static int bcm2835_codec_buf_prepare(struct vb2_buffer *vb) ++{ ++ struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); ++ struct bcm2835_codec_q_data *q_data; ++ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); ++ struct v4l2_m2m_buffer *m2m = container_of(vbuf, struct v4l2_m2m_buffer, ++ vb); ++ struct m2m_mmal_buffer *buf = container_of(m2m, struct m2m_mmal_buffer, ++ m2m); ++ int ret; ++ ++ v4l2_dbg(4, debug, &ctx->dev->v4l2_dev, "%s: type: %d ptr %p\n", ++ __func__, vb->vb2_queue->type, vb); ++ ++ q_data = get_q_data(ctx, vb->vb2_queue->type); ++ if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { ++ if (vbuf->field == V4L2_FIELD_ANY) ++ vbuf->field = V4L2_FIELD_NONE; ++ if (vbuf->field != V4L2_FIELD_NONE) { ++ v4l2_err(&ctx->dev->v4l2_dev, "%s field isn't supported\n", ++ __func__); ++ return -EINVAL; ++ } ++ } ++ ++ if (vb2_plane_size(vb, 0) < q_data->sizeimage) { ++ v4l2_err(&ctx->dev->v4l2_dev, "%s data will not fit into plane (%lu < %lu)\n", ++ __func__, vb2_plane_size(vb, 0), ++ (long)q_data->sizeimage); ++ return -EINVAL; ++ } ++ ++ if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) ++ vb2_set_plane_payload(vb, 0, q_data->sizeimage); ++ ++ /* ++ * We want to do this at init, but vb2_core_expbuf checks that the ++ * index < q->num_buffers, and q->num_buffers only gets updated once ++ * all the buffers are allocated. ++ */ ++ if (!buf->mmal.dma_buf) { ++ ret = vb2_core_expbuf_dmabuf(vb->vb2_queue, ++ vb->vb2_queue->type, vb->index, 0, ++ O_CLOEXEC, &buf->mmal.dma_buf); ++ if (ret) ++ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed to expbuf idx %d, ret %d\n", ++ __func__, vb->index, ret); ++ } else { ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++static void bcm2835_codec_buf_queue(struct vb2_buffer *vb) ++{ ++ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); ++ struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); ++ ++ v4l2_dbg(4, debug, &ctx->dev->v4l2_dev, "%s: type: %d ptr %p vbuf->flags %u, seq %u, bytesused %u\n", ++ __func__, vb->vb2_queue->type, vb, vbuf->flags, vbuf->sequence, ++ vb->planes[0].bytesused); ++ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); ++} ++ ++static void bcm2835_codec_buffer_cleanup(struct vb2_buffer *vb) ++{ ++ struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); ++ struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb); ++ struct v4l2_m2m_buffer *m2m = container_of(vb2, struct v4l2_m2m_buffer, ++ vb); ++ struct m2m_mmal_buffer *buf = container_of(m2m, struct m2m_mmal_buffer, ++ m2m); ++ ++ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: ctx:%p, vb %p\n", ++ __func__, ctx, vb); ++ ++ mmal_vchi_buffer_cleanup(&buf->mmal); ++ ++ if (buf->mmal.dma_buf) { ++ dma_buf_put(buf->mmal.dma_buf); ++ buf->mmal.dma_buf = NULL; ++ } ++} ++ ++static int bcm2835_codec_start_streaming(struct vb2_queue *q, ++ unsigned int count) ++{ ++ struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(q); ++ struct bcm2835_codec_dev *dev = ctx->dev; ++ struct bcm2835_codec_q_data *q_data = get_q_data(ctx, q->type); ++ int ret; ++ ++ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: type: %d count %d\n", ++ __func__, q->type, count); ++ q_data->sequence = 0; ++ ++ if (!ctx->component_enabled) { ++ ret = vchiq_mmal_component_enable(dev->instance, ++ ctx->component); ++ if (ret) ++ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling component, ret %d\n", ++ __func__, ret); ++ ctx->component_enabled = true; ++ } ++ ++ if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { ++ /* ++ * Create the EOS buffer. ++ * We only need the MMAL part, and want to NOT attach a memory ++ * buffer to it as it should only take flags. ++ */ ++ memset(&q_data->eos_buffer, 0, sizeof(q_data->eos_buffer)); ++ mmal_vchi_buffer_init(dev->instance, ++ &q_data->eos_buffer.mmal); ++ q_data->eos_buffer_in_use = false; ++ ++ ctx->component->input[0].cb_ctx = ctx; ++ ret = vchiq_mmal_port_enable(dev->instance, ++ &ctx->component->input[0], ++ ip_buffer_cb); ++ if (ret) ++ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling i/p port, ret %d\n", ++ __func__, ret); ++ } else { ++ ctx->component->output[0].cb_ctx = ctx; ++ ret = vchiq_mmal_port_enable(dev->instance, ++ &ctx->component->output[0], ++ op_buffer_cb); ++ if (ret) ++ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling o/p port, ret %d\n", ++ __func__, ret); ++ } ++ return ret; ++} ++ ++static void bcm2835_codec_stop_streaming(struct vb2_queue *q) ++{ ++ struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(q); ++ struct bcm2835_codec_dev *dev = ctx->dev; ++ struct bcm2835_codec_q_data *q_data = get_q_data(ctx, q->type); ++ struct vchiq_mmal_port *port = get_port_data(ctx, q->type); ++ struct vb2_v4l2_buffer *vbuf; ++ struct vb2_v4l2_buffer *vb2; ++ struct v4l2_m2m_buffer *m2m; ++ struct m2m_mmal_buffer *buf; ++ int ret, i; ++ ++ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: type: %d - return buffers\n", ++ __func__, q->type); ++ ++ init_completion(&ctx->frame_cmplt); ++ ++ /* Clear out all buffers held by m2m framework */ ++ for (;;) { ++ if (V4L2_TYPE_IS_OUTPUT(q->type)) ++ vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); ++ else ++ vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); ++ if (!vbuf) ++ break; ++ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: return buffer %p\n", ++ __func__, vbuf); ++ ++ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); ++ } ++ ++ /* Disable MMAL port - this will flush buffers back */ ++ ret = vchiq_mmal_port_disable(dev->instance, port); ++ if (ret) ++ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed disabling %s port, ret %d\n", ++ __func__, V4L2_TYPE_IS_OUTPUT(q->type) ? "i/p" : "o/p", ++ ret); ++ ++ while (atomic_read(&port->buffers_with_vpu)) { ++ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Waiting for buffers to be returned - %d outstanding\n", ++ __func__, atomic_read(&port->buffers_with_vpu)); ++ ret = wait_for_completion_timeout(&ctx->frame_cmplt, HZ); ++ if (ret <= 0) { ++ v4l2_err(&ctx->dev->v4l2_dev, "%s: Timeout waiting for buffers to be returned - %d outstanding\n", ++ __func__, ++ atomic_read(&port->buffers_with_vpu)); ++ break; ++ } ++ } ++ ++ /* ++ * Release the VCSM handle here as otherwise REQBUFS(0) aborts because ++ * someone is using the dmabuf before giving the driver a chance to do ++ * anything about it. ++ */ ++ for (i = 0; i < q->num_buffers; i++) { ++ vb2 = to_vb2_v4l2_buffer(q->bufs[i]); ++ m2m = container_of(vb2, struct v4l2_m2m_buffer, vb); ++ buf = container_of(m2m, struct m2m_mmal_buffer, m2m); ++ ++ mmal_vchi_buffer_cleanup(&buf->mmal); ++ if (buf->mmal.dma_buf) { ++ dma_buf_put(buf->mmal.dma_buf); ++ buf->mmal.dma_buf = NULL; ++ } ++ } ++ ++ /* If both ports disabled, then disable the component */ ++ if (!ctx->component->input[0].enabled && ++ !ctx->component->output[0].enabled) { ++ ret = vchiq_mmal_component_disable(dev->instance, ++ ctx->component); ++ if (ret) ++ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling component, ret %d\n", ++ __func__, ret); ++ } ++ ++ if (V4L2_TYPE_IS_OUTPUT(q->type)) ++ mmal_vchi_buffer_cleanup(&q_data->eos_buffer.mmal); ++ ++ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: done\n", __func__); ++} ++ ++static const struct vb2_ops bcm2835_codec_qops = { ++ .queue_setup = bcm2835_codec_queue_setup, ++ .buf_init = bcm2835_codec_buf_init, ++ .buf_prepare = bcm2835_codec_buf_prepare, ++ .buf_queue = bcm2835_codec_buf_queue, ++ .buf_cleanup = bcm2835_codec_buffer_cleanup, ++ .start_streaming = bcm2835_codec_start_streaming, ++ .stop_streaming = bcm2835_codec_stop_streaming, ++ .wait_prepare = vb2_ops_wait_prepare, ++ .wait_finish = vb2_ops_wait_finish, ++}; ++ ++static int queue_init(void *priv, struct vb2_queue *src_vq, ++ struct vb2_queue *dst_vq) ++{ ++ struct bcm2835_codec_ctx *ctx = priv; ++ int ret; ++ ++ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; ++ src_vq->io_modes = VB2_MMAP | VB2_DMABUF; ++ src_vq->drv_priv = ctx; ++ src_vq->buf_struct_size = sizeof(struct m2m_mmal_buffer); ++ src_vq->ops = &bcm2835_codec_qops; ++ src_vq->mem_ops = &vb2_dma_contig_memops; ++ src_vq->dev = &ctx->dev->pdev->dev; ++ src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; ++ src_vq->lock = &ctx->dev->dev_mutex; ++ ++ ret = vb2_queue_init(src_vq); ++ if (ret) ++ return ret; ++ ++ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ++ dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; ++ dst_vq->drv_priv = ctx; ++ dst_vq->buf_struct_size = sizeof(struct m2m_mmal_buffer); ++ dst_vq->ops = &bcm2835_codec_qops; ++ dst_vq->mem_ops = &vb2_dma_contig_memops; ++ dst_vq->dev = &ctx->dev->pdev->dev; ++ dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; ++ dst_vq->lock = &ctx->dev->dev_mutex; ++ ++ return vb2_queue_init(dst_vq); ++} ++ ++/* ++ * File operations ++ */ ++static int bcm2835_codec_open(struct file *file) ++{ ++ struct bcm2835_codec_dev *dev = video_drvdata(file); ++ struct bcm2835_codec_ctx *ctx = NULL; ++ struct v4l2_ctrl_handler *hdl; ++ int rc = 0; ++ ++ v4l2_dbg(1, debug, &dev->v4l2_dev, "Creating instance for %s\n", ++ dev->decode ? "decode" : "encode"); ++ if (mutex_lock_interruptible(&dev->dev_mutex)) { ++ v4l2_err(&dev->v4l2_dev, "Mutex fail\n"); ++ return -ERESTARTSYS; ++ } ++ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); ++ if (!ctx) { ++ rc = -ENOMEM; ++ goto open_unlock; ++ } ++ ++ ctx->q_data[V4L2_M2M_SRC].fmt = get_default_format(dev->decode, false); ++ ctx->q_data[V4L2_M2M_DST].fmt = get_default_format(dev->decode, true); ++ if (dev->decode) { ++ /* ++ * Input width and height are irrelevant as they will be defined ++ * by the bitstream not the format. Required by V4L2 though. ++ */ ++ ctx->q_data[V4L2_M2M_SRC].crop_width = DEFAULT_WIDTH; ++ ctx->q_data[V4L2_M2M_SRC].crop_height = DEFAULT_HEIGHT; ++ ctx->q_data[V4L2_M2M_SRC].height = DEFAULT_HEIGHT; ++ ctx->q_data[V4L2_M2M_SRC].bytesperline = 0; ++ ctx->q_data[V4L2_M2M_SRC].sizeimage = ++ DEF_COMP_BUF_SIZE_720P_OR_LESS; ++ ++ ctx->q_data[V4L2_M2M_DST].crop_width = DEFAULT_WIDTH; ++ ctx->q_data[V4L2_M2M_DST].crop_height = DEFAULT_HEIGHT; ++ ctx->q_data[V4L2_M2M_DST].height = DEFAULT_HEIGHT; ++ ctx->q_data[V4L2_M2M_DST].bytesperline = ++ get_bytesperline(DEFAULT_WIDTH, ++ ctx->q_data[V4L2_M2M_DST].fmt); ++ ctx->q_data[V4L2_M2M_DST].sizeimage = ++ get_sizeimage(ctx->q_data[V4L2_M2M_DST].bytesperline, ++ ctx->q_data[V4L2_M2M_DST].height, ++ ctx->q_data[V4L2_M2M_DST].fmt); ++ } else { ++ ctx->q_data[V4L2_M2M_SRC].crop_width = DEFAULT_WIDTH; ++ ctx->q_data[V4L2_M2M_SRC].crop_height = DEFAULT_HEIGHT; ++ ctx->q_data[V4L2_M2M_SRC].height = DEFAULT_HEIGHT; ++ ctx->q_data[V4L2_M2M_SRC].bytesperline = ++ get_bytesperline(DEFAULT_WIDTH, ++ ctx->q_data[V4L2_M2M_SRC].fmt); ++ ctx->q_data[V4L2_M2M_SRC].sizeimage = ++ get_sizeimage(ctx->q_data[V4L2_M2M_SRC].bytesperline, ++ ctx->q_data[V4L2_M2M_SRC].height, ++ ctx->q_data[V4L2_M2M_SRC].fmt); ++ ++ ctx->q_data[V4L2_M2M_DST].crop_width = DEFAULT_WIDTH; ++ ctx->q_data[V4L2_M2M_DST].crop_height = DEFAULT_HEIGHT; ++ ctx->q_data[V4L2_M2M_DST].bytesperline = 0; ++ ctx->q_data[V4L2_M2M_DST].height = DEFAULT_HEIGHT; ++ ctx->q_data[V4L2_M2M_DST].sizeimage = ++ DEF_COMP_BUF_SIZE_720P_OR_LESS; ++ } ++ ++ ctx->colorspace = V4L2_COLORSPACE_REC709; ++ ctx->bitrate = 10 * 1000 * 1000; ++ ++ /* Initialise V4L2 contexts */ ++ v4l2_fh_init(&ctx->fh, video_devdata(file)); ++ file->private_data = &ctx->fh; ++ ctx->dev = dev; ++ hdl = &ctx->hdl; ++ if (!dev->decode) { ++ /* Encode controls */ ++ v4l2_ctrl_handler_init(hdl, 6); ++ ++ v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, ++ V4L2_CID_MPEG_VIDEO_BITRATE_MODE, ++ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0, ++ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); ++ v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops, ++ V4L2_CID_MPEG_VIDEO_BITRATE, ++ 25 * 1000, 25 * 1000 * 1000, ++ 25 * 1000, 10 * 1000 * 1000); ++ v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops, ++ V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, ++ 0, 1, ++ 1, 0); ++ v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops, ++ V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, ++ 0, 0x7FFFFFFF, ++ 1, 60); ++ v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, ++ V4L2_CID_MPEG_VIDEO_H264_LEVEL, ++ V4L2_MPEG_VIDEO_H264_LEVEL_4_2, ++ ~(BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) | ++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) | ++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) | ++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) | ++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) | ++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | ++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) | ++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) | ++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | ++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | ++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | ++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) | ++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) | ++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2)), ++ V4L2_MPEG_VIDEO_H264_LEVEL_4_0); ++ v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, ++ V4L2_CID_MPEG_VIDEO_H264_PROFILE, ++ V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, ++ ~(BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | ++ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | ++ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | ++ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)), ++ V4L2_MPEG_VIDEO_H264_PROFILE_HIGH); ++ if (hdl->error) { ++ rc = hdl->error; ++ goto free_ctrl_handler; ++ } ++ ctx->fh.ctrl_handler = hdl; ++ v4l2_ctrl_handler_setup(hdl); ++ } ++ ++ ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init); ++ ++ if (IS_ERR(ctx->fh.m2m_ctx)) { ++ rc = PTR_ERR(ctx->fh.m2m_ctx); ++ ++ goto free_ctrl_handler; ++ } ++ ++ /* Set both queues as buffered as we have buffering in the VPU. That ++ * means that we will be scheduled whenever either an input or output ++ * buffer is available (otherwise one of each are required). ++ */ ++ v4l2_m2m_set_src_buffered(ctx->fh.m2m_ctx, true); ++ v4l2_m2m_set_dst_buffered(ctx->fh.m2m_ctx, true); ++ ++ v4l2_fh_add(&ctx->fh); ++ atomic_inc(&dev->num_inst); ++ ++ mutex_unlock(&dev->dev_mutex); ++ return 0; ++ ++free_ctrl_handler: ++ v4l2_ctrl_handler_free(hdl); ++ kfree(ctx); ++open_unlock: ++ mutex_unlock(&dev->dev_mutex); ++ return rc; ++} ++ ++static int bcm2835_codec_release(struct file *file) ++{ ++ struct bcm2835_codec_dev *dev = video_drvdata(file); ++ struct bcm2835_codec_ctx *ctx = file2ctx(file); ++ ++ v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: Releasing instance %p\n", ++ __func__, ctx); ++ ++ v4l2_fh_del(&ctx->fh); ++ v4l2_fh_exit(&ctx->fh); ++ v4l2_ctrl_handler_free(&ctx->hdl); ++ mutex_lock(&dev->dev_mutex); ++ v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); ++ ++ if (ctx->component) ++ vchiq_mmal_component_finalise(dev->instance, ctx->component); ++ ++ mutex_unlock(&dev->dev_mutex); ++ kfree(ctx); ++ ++ atomic_dec(&dev->num_inst); ++ ++ return 0; ++} ++ ++static const struct v4l2_file_operations bcm2835_codec_fops = { ++ .owner = THIS_MODULE, ++ .open = bcm2835_codec_open, ++ .release = bcm2835_codec_release, ++ .poll = v4l2_m2m_fop_poll, ++ .unlocked_ioctl = video_ioctl2, ++ .mmap = v4l2_m2m_fop_mmap, ++}; ++ ++static const struct video_device bcm2835_codec_videodev = { ++ .name = MEM2MEM_NAME, ++ .vfl_dir = VFL_DIR_M2M, ++ .fops = &bcm2835_codec_fops, ++ .ioctl_ops = &bcm2835_codec_ioctl_ops, ++ .minor = -1, ++ .release = video_device_release_empty, ++}; ++ ++static const struct v4l2_m2m_ops m2m_ops = { ++ .device_run = device_run, ++ .job_ready = job_ready, ++ .job_abort = job_abort, ++}; ++ ++static int bcm2835_codec_create(struct platform_device *pdev, ++ struct bcm2835_codec_dev **new_dev, ++ bool decode) ++{ ++ struct bcm2835_codec_dev *dev; ++ struct video_device *vfd; ++ struct vchiq_mmal_instance *instance = NULL; ++ int video_nr; ++ int ret; ++ ++ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); ++ if (!dev) ++ return -ENOMEM; ++ ++ dev->pdev = pdev; ++ ++ dev->decode = decode; ++ ++ ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); ++ if (ret) ++ return ret; ++ ++ atomic_set(&dev->num_inst, 0); ++ mutex_init(&dev->dev_mutex); ++ ++ dev->vfd = bcm2835_codec_videodev; ++ vfd = &dev->vfd; ++ vfd->lock = &dev->dev_mutex; ++ vfd->v4l2_dev = &dev->v4l2_dev; ++ ++ if (dev->decode) { ++ v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD); ++ v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); ++ video_nr = decode_video_nr; ++ } else { ++ v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD); ++ v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD); ++ video_nr = encode_video_nr; ++ } ++ ++ ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); ++ if (ret) { ++ v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); ++ goto unreg_dev; ++ } ++ ++ video_set_drvdata(vfd, dev); ++ snprintf(vfd->name, sizeof(vfd->name), "%s", ++ bcm2835_codec_videodev.name); ++ v4l2_info(&dev->v4l2_dev, "Device registered as /dev/video%d\n", ++ vfd->num); ++ ++ *new_dev = dev; ++ ++ dev->m2m_dev = v4l2_m2m_init(&m2m_ops); ++ if (IS_ERR(dev->m2m_dev)) { ++ v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n"); ++ ret = PTR_ERR(dev->m2m_dev); ++ goto err_m2m; ++ } ++ ++ ret = vchiq_mmal_init(&instance); ++ if (ret < 0) ++ goto err_m2m; ++ dev->instance = instance; ++ ++ v4l2_info(&dev->v4l2_dev, "Loaded V4L2 %s codec\n", ++ dev->decode ? "decode" : "encode"); ++ return 0; ++ ++err_m2m: ++ v4l2_m2m_release(dev->m2m_dev); ++ video_unregister_device(&dev->vfd); ++unreg_dev: ++ v4l2_device_unregister(&dev->v4l2_dev); ++ ++ return ret; ++} ++ ++static int bcm2835_codec_destroy(struct bcm2835_codec_dev *dev) ++{ ++ if (!dev) ++ return -ENODEV; ++ ++ v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME); ++ v4l2_m2m_release(dev->m2m_dev); ++ video_unregister_device(&dev->vfd); ++ v4l2_device_unregister(&dev->v4l2_dev); ++ ++ return 0; ++} ++ ++static int bcm2835_codec_probe(struct platform_device *pdev) ++{ ++ struct bcm2835_codec_driver *drv; ++ int ret = 0; ++ ++ drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); ++ if (!drv) ++ return -ENOMEM; ++ ++ ret = bcm2835_codec_create(pdev, &drv->encode, false); ++ if (ret) ++ goto out; ++ ++ ret = bcm2835_codec_create(pdev, &drv->decode, true); ++ if (ret) ++ goto out; ++ ++ platform_set_drvdata(pdev, drv); ++ ++ return 0; ++ ++out: ++ if (drv->encode) { ++ bcm2835_codec_destroy(drv->encode); ++ drv->encode = NULL; ++ } ++ return ret; ++} ++ ++static int bcm2835_codec_remove(struct platform_device *pdev) ++{ ++ struct bcm2835_codec_driver *drv = platform_get_drvdata(pdev); ++ ++ bcm2835_codec_destroy(drv->encode); ++ ++ bcm2835_codec_destroy(drv->decode); ++ ++ return 0; ++} ++ ++static struct platform_driver bcm2835_v4l2_codec_driver = { ++ .probe = bcm2835_codec_probe, ++ .remove = bcm2835_codec_remove, ++ .driver = { ++ .name = "bcm2835-codec", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++module_platform_driver(bcm2835_v4l2_codec_driver); ++ ++MODULE_DESCRIPTION("BCM2835 codec V4L2 driver"); ++MODULE_AUTHOR("Dave Stevenson, "); ++MODULE_LICENSE("GPL"); ++MODULE_VERSION("0.0.1"); ++MODULE_ALIAS("platform:bcm2835-codec"); diff --git a/target/linux/brcm2708/patches-4.19/950-0277-staging-vc04_services-Use-vc-sm-cma-to-support-zero-.patch b/target/linux/brcm2708/patches-4.19/950-0277-staging-vc04_services-Use-vc-sm-cma-to-support-zero-.patch deleted file mode 100644 index 5d4c7a53c3..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0277-staging-vc04_services-Use-vc-sm-cma-to-support-zero-.patch +++ /dev/null @@ -1,163 +0,0 @@ -From d3c99e301ac57e6c1a5e13b341baacd7182a5763 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 25 Sep 2018 16:07:55 +0100 -Subject: [PATCH 277/703] staging: vc04_services: Use vc-sm-cma to support zero - copy - -With the vc-sm-cma driver we can support zero copy of buffers between -the kernel and VPU. Add this support to vchiq-mmal. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/vchiq-mmal/Kconfig | 1 + - .../vc04_services/vchiq-mmal/mmal-common.h | 4 ++ - .../vc04_services/vchiq-mmal/mmal-vchiq.c | 66 ++++++++++++++++++- - .../vc04_services/vchiq-mmal/mmal-vchiq.h | 1 + - 4 files changed, 70 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/vchiq-mmal/Kconfig -+++ b/drivers/staging/vc04_services/vchiq-mmal/Kconfig -@@ -2,6 +2,7 @@ config BCM2835_VCHIQ_MMAL - tristate "BCM2835 MMAL VCHIQ service" - depends on (ARCH_BCM2835 || COMPILE_TEST) - select BCM2835_VCHIQ -+ select BCM_VC_SM_CMA - help - Enables the MMAL API over VCHIQ as used for the - majority of the multimedia services on VideoCore. ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h -@@ -51,6 +51,10 @@ struct mmal_buffer { - - struct mmal_msg_context *msg_context; - -+ struct dma_buf *dma_buf;/* Exported dmabuf fd from videobuf2 */ -+ int vcsm_handle; /* VCSM handle having imported the dmabuf */ -+ u32 vc_handle; /* VC handle to that dmabuf */ -+ - u32 cmd; /* MMAL command. 0=data. */ - unsigned long length; - u32 mmal_flags; ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -27,9 +27,12 @@ - #include - - #include "mmal-common.h" -+#include "mmal-parameters.h" - #include "mmal-vchiq.h" - #include "mmal-msg.h" - -+#include "vc-sm-cma/vc_sm_knl.h" -+ - #define USE_VCHIQ_ARM - #include "interface/vchi/vchi.h" - -@@ -425,8 +428,13 @@ buffer_from_host(struct vchiq_mmal_insta - - /* buffer header */ - m.u.buffer_from_host.buffer_header.cmd = 0; -- m.u.buffer_from_host.buffer_header.data = -- (u32)(unsigned long)buf->buffer; -+ if (port->zero_copy) { -+ m.u.buffer_from_host.buffer_header.data = buf->vc_handle; -+ } else { -+ m.u.buffer_from_host.buffer_header.data = -+ (u32)(unsigned long)buf->buffer; -+ } -+ - m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size; - if (port->type == MMAL_PORT_TYPE_OUTPUT) { - m.u.buffer_from_host.buffer_header.length = 0; -@@ -591,6 +599,22 @@ static void buffer_to_host_cb(struct vch - - msg_context->u.bulk.status = msg->h.status; - -+ } else if (msg->u.buffer_from_host.is_zero_copy) { -+ /* -+ * Zero copy buffer, so nothing to do. -+ * Copy buffer info and make callback. -+ */ -+ msg_context->u.bulk.buffer_used = -+ msg->u.buffer_from_host.buffer_header.length; -+ msg_context->u.bulk.mmal_flags = -+ msg->u.buffer_from_host.buffer_header.flags; -+ msg_context->u.bulk.dts = -+ msg->u.buffer_from_host.buffer_header.dts; -+ msg_context->u.bulk.pts = -+ msg->u.buffer_from_host.buffer_header.pts; -+ msg_context->u.bulk.cmd = -+ msg->u.buffer_from_host.buffer_header.cmd; -+ - } else if (msg->u.buffer_from_host.buffer_header.length == 0) { - /* empty buffer */ - if (msg->u.buffer_from_host.buffer_header.flags & -@@ -1538,6 +1562,9 @@ int vchiq_mmal_port_parameter_set(struct - - mutex_unlock(&instance->vchiq_mutex); - -+ if (parameter == MMAL_PARAMETER_ZERO_COPY && !ret) -+ port->zero_copy = !!(*(bool *)value); -+ - return ret; - } - EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_set); -@@ -1706,6 +1733,31 @@ int vchiq_mmal_submit_buffer(struct vchi - unsigned long flags = 0; - int ret; - -+ /* -+ * We really want to do this in mmal_vchi_buffer_init but can't as -+ * videobuf2 won't let us have the dmabuf there. -+ */ -+ if (port->zero_copy && buffer->dma_buf && !buffer->vcsm_handle) { -+ pr_debug("%s: import dmabuf %p\n", __func__, buffer->dma_buf); -+ ret = vc_sm_cma_import_dmabuf(buffer->dma_buf, -+ &buffer->vcsm_handle); -+ if (ret) { -+ pr_err("%s: vc_sm_import_dmabuf_fd failed, ret %d\n", -+ __func__, ret); -+ return ret; -+ } -+ -+ buffer->vc_handle = vc_sm_cma_int_handle(buffer->vcsm_handle); -+ if (!buffer->vc_handle) { -+ pr_err("%s: vc_sm_int_handle failed %d\n", -+ __func__, ret); -+ vc_sm_cma_free(buffer->vcsm_handle); -+ return ret; -+ } -+ pr_debug("%s: import dmabuf %p - got vc handle %08X\n", -+ __func__, buffer->dma_buf, buffer->vc_handle); -+ } -+ - ret = buffer_from_host(instance, port, buffer); - if (ret == -EINVAL) { - /* Port is disabled. Queue for when it is enabled. */ -@@ -1739,6 +1791,16 @@ int mmal_vchi_buffer_cleanup(struct mmal - release_msg_context(msg_context); - buf->msg_context = NULL; - -+ if (buf->vcsm_handle) { -+ int ret; -+ -+ pr_debug("%s: vc_sm_cma_free on handle %08X\n", __func__, -+ buf->vcsm_handle); -+ ret = vc_sm_cma_free(buf->vcsm_handle); -+ if (ret) -+ pr_err("%s: vcsm_free failed, ret %d\n", __func__, ret); -+ buf->vcsm_handle = 0; -+ } - return 0; - } - EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup); ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h -@@ -49,6 +49,7 @@ typedef void (*vchiq_mmal_buffer_cb)( - - struct vchiq_mmal_port { - u32 enabled:1; -+ u32 zero_copy:1; - u32 handle; - u32 type; /* port type, cached to use on port info set */ - u32 index; /* port index, cached to use on port info set */ diff --git a/target/linux/brcm2708/patches-4.19/950-0277-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch b/target/linux/brcm2708/patches-4.19/950-0277-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch new file mode 100644 index 0000000000..5618b97716 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0277-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch @@ -0,0 +1,34 @@ +From d5e800f52f43d8be95d78d4f95b0e5825bc5c4fb Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 26 Oct 2018 15:14:16 +0100 +Subject: [PATCH 277/725] staging: vchiq_arm: Register bcm2835-codec as a + platform driver + +Following the same pattern as bcm2835-camera and bcm2835-audio, +register the V4L2 codec driver as a platform driver + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +@@ -171,6 +171,7 @@ static struct device *vchiq_dev; + static DEFINE_SPINLOCK(msg_queue_spinlock); + static struct platform_device *bcm2835_camera; + static struct platform_device *bcm2835_audio; ++static struct platform_device *bcm2835_codec; + + static const char *const ioctl_names[] = { + "CONNECT", +@@ -3660,6 +3661,9 @@ static int vchiq_probe(struct platform_d + bcm2835_audio = vchiq_register_child(pdev, "bcm2835_audio"); + if (IS_ERR(bcm2835_audio)) + bcm2835_audio = NULL; ++ bcm2835_codec = vchiq_register_child(pdev, "bcm2835-codec"); ++ if (IS_ERR(bcm2835_codec)) ++ bcm2835_codec = NULL; + + return 0; + diff --git a/target/linux/brcm2708/patches-4.19/950-0278-media-videobuf2-Allow-exporting-of-a-struct-dmabuf.patch b/target/linux/brcm2708/patches-4.19/950-0278-media-videobuf2-Allow-exporting-of-a-struct-dmabuf.patch deleted file mode 100644 index 743faa2c3f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0278-media-videobuf2-Allow-exporting-of-a-struct-dmabuf.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 2fada970d893db4a8800bae31d6ed8c01b4c4173 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 29 Oct 2018 17:57:45 +0000 -Subject: [PATCH 278/703] media: videobuf2: Allow exporting of a struct dmabuf - -videobuf2 only allowed exporting a dmabuf as a file descriptor, -but there are instances where having the struct dma_buf is -useful within the kernel. - -Split the current implementation into two, one step which -exports a struct dma_buf, and the second which converts that -into an fd. - -Signed-off-by: Dave Stevenson ---- - .../media/common/videobuf2/videobuf2-core.c | 21 ++++++++++++++++--- - include/media/videobuf2-core.h | 15 +++++++++++++ - 2 files changed, 33 insertions(+), 3 deletions(-) - ---- a/drivers/media/common/videobuf2/videobuf2-core.c -+++ b/drivers/media/common/videobuf2/videobuf2-core.c -@@ -1851,12 +1851,12 @@ static int __find_plane_by_offset(struct - return -EINVAL; - } - --int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, -- unsigned int index, unsigned int plane, unsigned int flags) -+int vb2_core_expbuf_dmabuf(struct vb2_queue *q, unsigned int type, -+ unsigned int index, unsigned int plane, -+ unsigned int flags, struct dma_buf **dmabuf) - { - struct vb2_buffer *vb = NULL; - struct vb2_plane *vb_plane; -- int ret; - struct dma_buf *dbuf; - - if (q->memory != VB2_MEMORY_MMAP) { -@@ -1906,6 +1906,21 @@ int vb2_core_expbuf(struct vb2_queue *q, - return -EINVAL; - } - -+ *dmabuf = dbuf; -+ return 0; -+} -+EXPORT_SYMBOL_GPL(vb2_core_expbuf_dmabuf); -+ -+int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, -+ unsigned int index, unsigned int plane, unsigned int flags) -+{ -+ struct dma_buf *dbuf; -+ int ret; -+ -+ ret = vb2_core_expbuf_dmabuf(q, type, index, plane, flags, &dbuf); -+ if (ret) -+ return ret; -+ - ret = dma_buf_fd(dbuf, flags & ~O_ACCMODE); - if (ret < 0) { - dprintk(3, "buffer %d, plane %d failed to export (%d)\n", ---- a/include/media/videobuf2-core.h -+++ b/include/media/videobuf2-core.h -@@ -825,6 +825,21 @@ int vb2_core_streamon(struct vb2_queue * - int vb2_core_streamoff(struct vb2_queue *q, unsigned int type); - - /** -+ * vb2_core_expbuf_dmabuf() - Export a buffer as a dma_buf structure -+ * @q: videobuf2 queue -+ * @type: buffer type -+ * @index: id number of the buffer -+ * @plane: index of the plane to be exported, 0 for single plane queues -+ * @flags: flags for newly created file, currently only O_CLOEXEC is -+ * supported, refer to manual of open syscall for more details -+ * @dmabuf: Returns the dmabuf pointer -+ * -+ */ -+int vb2_core_expbuf_dmabuf(struct vb2_queue *q, unsigned int type, -+ unsigned int index, unsigned int plane, -+ unsigned int flags, struct dma_buf **dmabuf); -+ -+/** - * vb2_core_expbuf() - Export a buffer as a file descriptor. - * @q: pointer to &struct vb2_queue with videobuf2 queue. - * @fd: pointer to the file descriptor associated with DMABUF diff --git a/target/linux/brcm2708/patches-4.19/950-0278-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch b/target/linux/brcm2708/patches-4.19/950-0278-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch new file mode 100644 index 0000000000..16f7d4953b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0278-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch @@ -0,0 +1,34 @@ +From 37dfe69edd33c0ed92770207f55f97ae3fa77607 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 26 Oct 2018 15:19:40 +0100 +Subject: [PATCH 278/725] staging: vchiq_arm: Register vcsm-cma as a platform + driver + +Following the same pattern as bcm2835-camera and bcm2835-audio, +register the vcsm-cma driver as a platform driver + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +@@ -172,6 +172,7 @@ static DEFINE_SPINLOCK(msg_queue_spinloc + static struct platform_device *bcm2835_camera; + static struct platform_device *bcm2835_audio; + static struct platform_device *bcm2835_codec; ++static struct platform_device *vcsm_cma; + + static const char *const ioctl_names[] = { + "CONNECT", +@@ -3655,6 +3656,9 @@ static int vchiq_probe(struct platform_d + VCHIQ_VERSION, VCHIQ_VERSION_MIN, + MAJOR(vchiq_devid), MINOR(vchiq_devid)); + ++ vcsm_cma = vchiq_register_child(pdev, "vcsm-cma"); ++ if (IS_ERR(vcsm_cma)) ++ vcsm_cma = NULL; + bcm2835_camera = vchiq_register_child(pdev, "bcm2835-camera"); + if (IS_ERR(bcm2835_camera)) + bcm2835_camera = NULL; diff --git a/target/linux/brcm2708/patches-4.19/950-0279-ARM-bcm2835_defconfig-Enable-bcm2835-codec.patch b/target/linux/brcm2708/patches-4.19/950-0279-ARM-bcm2835_defconfig-Enable-bcm2835-codec.patch new file mode 100644 index 0000000000..9ac7974452 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0279-ARM-bcm2835_defconfig-Enable-bcm2835-codec.patch @@ -0,0 +1,22 @@ +From 73ba32bae3b1afd20a8b9c116c620d47020f1720 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 29 Oct 2018 17:49:04 +0000 +Subject: [PATCH 279/725] ARM: bcm2835_defconfig: Enable bcm2835-codec + +Enables the V4L2 M2M codec driver as a module. + +Signed-off-by: Dave Stevenson +--- + arch/arm/configs/bcm2835_defconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm/configs/bcm2835_defconfig ++++ b/arch/arm/configs/bcm2835_defconfig +@@ -132,6 +132,7 @@ CONFIG_DMA_BCM2835=y + CONFIG_STAGING=y + CONFIG_SND_BCM2835=m + CONFIG_VIDEO_BCM2835=m ++CONFIG_VIDEO_CODEC_BCM2835=m + CONFIG_MAILBOX=y + CONFIG_BCM2835_MBOX=y + # CONFIG_IOMMU_SUPPORT is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0279-staging-vc04_services-Add-a-V4L2-M2M-codec-driver.patch b/target/linux/brcm2708/patches-4.19/950-0279-staging-vc04_services-Add-a-V4L2-M2M-codec-driver.patch deleted file mode 100644 index b1d53c61ef..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0279-staging-vc04_services-Add-a-V4L2-M2M-codec-driver.patch +++ /dev/null @@ -1,2467 +0,0 @@ -From ce40b5f18f770684fcfe2b02e5bd9a73f7716a8f Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 25 Sep 2018 14:53:49 +0100 -Subject: [PATCH 279/703] staging: vc04_services: Add a V4L2 M2M codec driver - -This adds a V4L2 memory to memory device that wraps the MMAL -video decode and video_encode components for H264 and MJPEG encode -and decode, MPEG4, H263, and VP8 decode (and MPEG2 decode -if the appropriate licence has been purchased). - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/Kconfig | 1 + - drivers/staging/vc04_services/Makefile | 9 +- - .../vc04_services/bcm2835-codec/Kconfig | 11 + - .../vc04_services/bcm2835-codec/Makefile | 8 + - .../staging/vc04_services/bcm2835-codec/TODO | 24 + - .../bcm2835-codec/bcm2835-v4l2-codec.c | 2359 +++++++++++++++++ - 6 files changed, 2408 insertions(+), 4 deletions(-) - create mode 100644 drivers/staging/vc04_services/bcm2835-codec/Kconfig - create mode 100644 drivers/staging/vc04_services/bcm2835-codec/Makefile - create mode 100644 drivers/staging/vc04_services/bcm2835-codec/TODO - create mode 100644 drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c - ---- a/drivers/staging/vc04_services/Kconfig -+++ b/drivers/staging/vc04_services/Kconfig -@@ -23,6 +23,7 @@ source "drivers/staging/vc04_services/bc - source "drivers/staging/vc04_services/bcm2835-camera/Kconfig" - source "drivers/staging/vc04_services/vchiq-mmal/Kconfig" - source "drivers/staging/vc04_services/vc-sm-cma/Kconfig" -+source "drivers/staging/vc04_services/bcm2835-codec/Kconfig" - - endif - ---- a/drivers/staging/vc04_services/Makefile -+++ b/drivers/staging/vc04_services/Makefile -@@ -10,10 +10,11 @@ vchiq-objs := \ - interface/vchiq_arm/vchiq_util.o \ - interface/vchiq_arm/vchiq_connected.o \ - --obj-$(CONFIG_SND_BCM2835) += bcm2835-audio/ --obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-camera/ --obj-$(CONFIG_BCM2835_VCHIQ_MMAL) += vchiq-mmal/ --obj-$(CONFIG_BCM_VC_SM_CMA) += vc-sm-cma/ -+obj-$(CONFIG_SND_BCM2835) += bcm2835-audio/ -+obj-$(CONFIG_VIDEO_BCM2835) += bcm2835-camera/ -+obj-$(CONFIG_BCM2835_VCHIQ_MMAL) += vchiq-mmal/ -+obj-$(CONFIG_BCM_VC_SM_CMA) += vc-sm-cma/ -+obj-$(CONFIG_VIDEO_CODEC_BCM2835) += bcm2835-codec/ - - ccflags-y += -Idrivers/staging/vc04_services -D__VCCOREVER__=0x04000000 - ---- /dev/null -+++ b/drivers/staging/vc04_services/bcm2835-codec/Kconfig -@@ -0,0 +1,11 @@ -+config VIDEO_CODEC_BCM2835 -+ tristate "BCM2835 Video codec support" -+ depends on MEDIA_SUPPORT -+ depends on VIDEO_V4L2 && (ARCH_BCM2835 || COMPILE_TEST) -+ select BCM2835_VCHIQ_MMAL -+ select VIDEOBUF2_DMA_CONTIG -+ select V4L2_MEM2MEM_DEV -+ help -+ Say Y here to enable the V4L2 video codecs for -+ Broadcom BCM2835 SoC. This operates over the VCHIQ interface -+ to a service running on VideoCore. ---- /dev/null -+++ b/drivers/staging/vc04_services/bcm2835-codec/Makefile -@@ -0,0 +1,8 @@ -+# SPDX-License-Identifier: GPL-2.0 -+bcm2835-codec-objs := bcm2835-v4l2-codec.o -+ -+obj-$(CONFIG_VIDEO_CODEC_BCM2835) += bcm2835-codec.o -+ -+ccflags-y += \ -+ -Idrivers/staging/vc04_services \ -+ -D__VCCOREVER__=0x04000000 ---- /dev/null -+++ b/drivers/staging/vc04_services/bcm2835-codec/TODO -@@ -0,0 +1,24 @@ -+1) Convert to be a platform driver. -+ -+Right now when the module probes, it tries to initialize VCHI and -+errors out if it wasn't ready yet. If bcm2835-v4l2 was built in, then -+VCHI generally isn't ready because it depends on both the firmware and -+mailbox drivers having already loaded. -+ -+We should have VCHI create a platform device once it's initialized, -+and have this driver bind to it, so that we automatically load the -+v4l2 module after VCHI loads. -+ -+2) Support SELECTION API to define crop region on the image for encode. -+ -+Particularly for resolutions that aren't a multiple of the macroblock -+size, the codec will report a resolution that is a multiple of the macroblock -+size (it has to have the memory to decode into), and then a different crop -+region within that buffer. -+The most common example is 1080P, where the buffer will be 1920x1088 with a -+crop region of 1920x1080. -+ -+3) Refactor so that the component creation is only on queue_setup, not open. -+ -+Fixes v4l2-compliance failure on trying to open 100 instances of the -+device. -\ No newline at end of file ---- /dev/null -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -0,0 +1,2359 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+/* -+ * A v4l2-mem2mem device that wraps the video codec MMAL component. -+ * -+ * Copyright 2018 Raspberry Pi (Trading) Ltd. -+ * Author: Dave Stevenson (dave.stevenson@raspberrypi.org) -+ * -+ * Loosely based on the vim2m virtual driver by Pawel Osciak -+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. -+ * Pawel Osciak, -+ * Marek Szyprowski, -+ * -+ * Whilst this driver uses the v4l2_mem2mem framework, it does not need the -+ * scheduling aspects, so will always take the buffers, pass them to the VPU, -+ * and then signal the job as complete. -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "vchiq-mmal/mmal-encodings.h" -+#include "vchiq-mmal/mmal-msg.h" -+#include "vchiq-mmal/mmal-parameters.h" -+#include "vchiq-mmal/mmal-vchiq.h" -+ -+/* -+ * Default /dev/videoN node numbers for decode and encode. -+ * Deliberately avoid the very low numbers as these are often taken by webcams -+ * etc, and simple apps tend to only go for /dev/video0. -+ */ -+static int decode_video_nr = 10; -+module_param(decode_video_nr, int, 0644); -+MODULE_PARM_DESC(decode_video_nr, "decoder video device number"); -+ -+static int encode_video_nr = 11; -+module_param(encode_video_nr, int, 0644); -+MODULE_PARM_DESC(encode_video_nr, "encoder video device number"); -+ -+static unsigned int debug; -+module_param(debug, uint, 0644); -+MODULE_PARM_DESC(debug, "activates debug info (0-3)"); -+ -+#define MIN_W 32 -+#define MIN_H 32 -+#define MAX_W 1920 -+#define MAX_H 1088 -+#define BPL_ALIGN 32 -+#define DEFAULT_WIDTH 640 -+#define DEFAULT_HEIGHT 480 -+/* -+ * The unanswered question - what is the maximum size of a compressed frame? -+ * V4L2 mandates that the encoded frame must fit in a single buffer. Sizing -+ * that buffer is a compromise between wasting memory and risking not fitting. -+ * The 1080P version of Big Buck Bunny has some frames that exceed 512kB. -+ * Adopt a moderately arbitrary split at 720P for switching between 512 and -+ * 768kB buffers. -+ */ -+#define DEF_COMP_BUF_SIZE_GREATER_720P (768 << 10) -+#define DEF_COMP_BUF_SIZE_720P_OR_LESS (512 << 10) -+ -+/* Flags that indicate a format can be used for capture/output */ -+#define MEM2MEM_CAPTURE BIT(0) -+#define MEM2MEM_OUTPUT BIT(1) -+ -+#define MEM2MEM_NAME "bcm2835-codec" -+ -+struct bcm2835_codec_fmt { -+ u32 fourcc; -+ int depth; -+ int bytesperline_align; -+ u32 flags; -+ u32 mmal_fmt; -+ bool decode_only; -+ bool encode_only; -+ int size_multiplier_x2; -+}; -+ -+/* Supported raw pixel formats. Those supported for both encode and decode -+ * must come first, with those only supported for decode coming after (there -+ * are no formats supported for encode only). -+ */ -+static struct bcm2835_codec_fmt raw_formats[] = { -+ { -+ .fourcc = V4L2_PIX_FMT_YUV420, -+ .depth = 8, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_I420, -+ .size_multiplier_x2 = 3, -+ }, { -+ .fourcc = V4L2_PIX_FMT_YVU420, -+ .depth = 8, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_YV12, -+ .size_multiplier_x2 = 3, -+ }, { -+ .fourcc = V4L2_PIX_FMT_NV12, -+ .depth = 8, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_NV12, -+ .size_multiplier_x2 = 3, -+ }, { -+ .fourcc = V4L2_PIX_FMT_NV21, -+ .depth = 8, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_NV21, -+ .size_multiplier_x2 = 3, -+ }, { -+ .fourcc = V4L2_PIX_FMT_RGB565, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_RGB16, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_YUYV, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_YUYV, -+ .encode_only = true, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_UYVY, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_UYVY, -+ .encode_only = true, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_YVYU, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_YVYU, -+ .encode_only = true, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_VYUY, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_VYUY, -+ .encode_only = true, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_RGB24, -+ .depth = 24, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_RGB24, -+ .encode_only = true, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_BGR24, -+ .depth = 24, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BGR24, -+ .encode_only = true, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_BGR32, -+ .depth = 32, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BGRA, -+ .encode_only = true, -+ .size_multiplier_x2 = 2, -+ }, -+}; -+ -+/* Supported encoded formats. Those supported for both encode and decode -+ * must come first, with those only supported for decode coming after (there -+ * are no formats supported for encode only). -+ */ -+static struct bcm2835_codec_fmt encoded_formats[] = { -+ { -+ .fourcc = V4L2_PIX_FMT_H264, -+ .depth = 0, -+ .flags = V4L2_FMT_FLAG_COMPRESSED, -+ .mmal_fmt = MMAL_ENCODING_H264, -+ }, { -+ .fourcc = V4L2_PIX_FMT_MJPEG, -+ .depth = 0, -+ .flags = V4L2_FMT_FLAG_COMPRESSED, -+ .mmal_fmt = MMAL_ENCODING_MJPEG, -+ }, { -+ .fourcc = V4L2_PIX_FMT_MPEG4, -+ .depth = 0, -+ .flags = V4L2_FMT_FLAG_COMPRESSED, -+ .mmal_fmt = MMAL_ENCODING_MP4V, -+ .decode_only = true, -+ }, { -+ .fourcc = V4L2_PIX_FMT_H263, -+ .depth = 0, -+ .flags = V4L2_FMT_FLAG_COMPRESSED, -+ .mmal_fmt = MMAL_ENCODING_H263, -+ .decode_only = true, -+ }, { -+ .fourcc = V4L2_PIX_FMT_MPEG2, -+ .depth = 0, -+ .flags = V4L2_FMT_FLAG_COMPRESSED, -+ .mmal_fmt = MMAL_ENCODING_MP2V, -+ .decode_only = true, -+ }, { -+ .fourcc = V4L2_PIX_FMT_VP8, -+ .depth = 0, -+ .flags = V4L2_FMT_FLAG_COMPRESSED, -+ .mmal_fmt = MMAL_ENCODING_VP8, -+ .decode_only = true, -+ }, -+ /* -+ * This list couold include VP6 and Theorafor decode, but V4L2 doesn't -+ * support them. -+ */ -+}; -+ -+struct bcm2835_codec_fmt_list { -+ struct bcm2835_codec_fmt *list; -+ unsigned int num_entries; -+}; -+ -+#define RAW_LIST 0 -+#define ENCODED_LIST 1 -+ -+struct bcm2835_codec_fmt_list formats[] = { -+ { -+ .list = raw_formats, -+ .num_entries = ARRAY_SIZE(raw_formats), -+ }, { -+ .list = encoded_formats, -+ .num_entries = ARRAY_SIZE(encoded_formats), -+ }, -+}; -+ -+struct m2m_mmal_buffer { -+ struct v4l2_m2m_buffer m2m; -+ struct mmal_buffer mmal; -+}; -+ -+/* Per-queue, driver-specific private data */ -+struct bcm2835_codec_q_data { -+ /* -+ * These parameters should be treated as gospel, with everything else -+ * being determined from them. -+ */ -+ /* Buffer width/height */ -+ unsigned int bytesperline; -+ unsigned int height; -+ /* Crop size used for selection handling */ -+ unsigned int crop_width; -+ unsigned int crop_height; -+ bool selection_set; -+ -+ unsigned int sizeimage; -+ unsigned int sequence; -+ struct bcm2835_codec_fmt *fmt; -+ -+ /* One extra buffer header so we can send an EOS. */ -+ struct m2m_mmal_buffer eos_buffer; -+ bool eos_buffer_in_use; /* debug only */ -+}; -+ -+enum { -+ V4L2_M2M_SRC = 0, -+ V4L2_M2M_DST = 1, -+}; -+ -+static inline struct bcm2835_codec_fmt_list *get_format_list(bool decode, -+ bool capture) -+{ -+ return decode ^ capture ? &formats[ENCODED_LIST] : &formats[RAW_LIST]; -+} -+ -+static struct bcm2835_codec_fmt *get_default_format(bool decode, bool capture) -+{ -+ return &get_format_list(decode, capture)->list[0]; -+} -+ -+static struct bcm2835_codec_fmt *find_format(struct v4l2_format *f, bool decode, -+ bool capture) -+{ -+ struct bcm2835_codec_fmt *fmt; -+ unsigned int k; -+ struct bcm2835_codec_fmt_list *fmts = get_format_list(decode, capture); -+ -+ for (k = 0; k < fmts->num_entries; k++) { -+ fmt = &fmts->list[k]; -+ if (fmt->fourcc == f->fmt.pix.pixelformat) -+ break; -+ } -+ -+ /* -+ * Some compressed formats are only supported for decoding, not -+ * encoding. -+ */ -+ if (!decode && fmts->list[k].decode_only) -+ return NULL; -+ -+ /* Some pixel formats are only supported for encoding, not decoding. */ -+ if (decode && fmts->list[k].encode_only) -+ return NULL; -+ -+ if (k == fmts->num_entries) -+ return NULL; -+ -+ return &fmts->list[k]; -+} -+ -+struct bcm2835_codec_dev { -+ struct platform_device *pdev; -+ -+ /* v4l2 devices */ -+ struct v4l2_device v4l2_dev; -+ struct video_device vfd; -+ /* mutex for the v4l2 device */ -+ struct mutex dev_mutex; -+ atomic_t num_inst; -+ -+ /* allocated mmal instance and components */ -+ bool decode; /* Is this instance a decoder? */ -+ struct vchiq_mmal_instance *instance; -+ -+ struct v4l2_m2m_dev *m2m_dev; -+}; -+ -+struct bcm2835_codec_ctx { -+ struct v4l2_fh fh; -+ struct bcm2835_codec_dev *dev; -+ -+ struct v4l2_ctrl_handler hdl; -+ -+ struct vchiq_mmal_component *component; -+ bool component_enabled; -+ -+ enum v4l2_colorspace colorspace; -+ enum v4l2_ycbcr_encoding ycbcr_enc; -+ enum v4l2_xfer_func xfer_func; -+ enum v4l2_quantization quant; -+ -+ /* Source and destination queue data */ -+ struct bcm2835_codec_q_data q_data[2]; -+ s32 bitrate; -+ -+ bool aborting; -+ int num_ip_buffers; -+ int num_op_buffers; -+ struct completion frame_cmplt; -+}; -+ -+struct bcm2835_codec_driver { -+ struct bcm2835_codec_dev *encode; -+ struct bcm2835_codec_dev *decode; -+}; -+ -+static inline struct bcm2835_codec_ctx *file2ctx(struct file *file) -+{ -+ return container_of(file->private_data, struct bcm2835_codec_ctx, fh); -+} -+ -+static struct bcm2835_codec_q_data *get_q_data(struct bcm2835_codec_ctx *ctx, -+ enum v4l2_buf_type type) -+{ -+ switch (type) { -+ case V4L2_BUF_TYPE_VIDEO_OUTPUT: -+ return &ctx->q_data[V4L2_M2M_SRC]; -+ case V4L2_BUF_TYPE_VIDEO_CAPTURE: -+ return &ctx->q_data[V4L2_M2M_DST]; -+ default: -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Invalid queue type %u\n", -+ __func__, type); -+ break; -+ } -+ return NULL; -+} -+ -+static struct vchiq_mmal_port *get_port_data(struct bcm2835_codec_ctx *ctx, -+ enum v4l2_buf_type type) -+{ -+ if (!ctx->component) -+ return NULL; -+ -+ switch (type) { -+ case V4L2_BUF_TYPE_VIDEO_OUTPUT: -+ return &ctx->component->input[0]; -+ case V4L2_BUF_TYPE_VIDEO_CAPTURE: -+ return &ctx->component->output[0]; -+ default: -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Invalid queue type %u\n", -+ __func__, type); -+ break; -+ } -+ return NULL; -+} -+ -+/* -+ * mem2mem callbacks -+ */ -+ -+/** -+ * job_ready() - check whether an instance is ready to be scheduled to run -+ */ -+static int job_ready(void *priv) -+{ -+ struct bcm2835_codec_ctx *ctx = priv; -+ -+ if (!v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) && -+ !v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx)) -+ return 0; -+ -+ return 1; -+} -+ -+static void job_abort(void *priv) -+{ -+ struct bcm2835_codec_ctx *ctx = priv; -+ -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s\n", __func__); -+ /* Will cancel the transaction in the next interrupt handler */ -+ ctx->aborting = 1; -+} -+ -+static inline unsigned int get_sizeimage(int bpl, int height, -+ struct bcm2835_codec_fmt *fmt) -+{ -+ return (bpl * height * fmt->size_multiplier_x2) >> 1; -+} -+ -+static inline unsigned int get_bytesperline(int width, -+ struct bcm2835_codec_fmt *fmt) -+{ -+ return ALIGN((width * fmt->depth) >> 3, fmt->bytesperline_align); -+} -+ -+static void setup_mmal_port_format(struct bcm2835_codec_ctx *ctx, -+ bool decode, -+ struct bcm2835_codec_q_data *q_data, -+ struct vchiq_mmal_port *port) -+{ -+ port->format.encoding = q_data->fmt->mmal_fmt; -+ -+ if (!(q_data->fmt->flags & V4L2_FMT_FLAG_COMPRESSED)) { -+ /* Raw image format - set width/height */ -+ port->es.video.width = q_data->bytesperline / -+ (q_data->fmt->depth >> 3); -+ port->es.video.height = q_data->height; -+ port->es.video.crop.width = q_data->crop_width; -+ port->es.video.crop.height = q_data->crop_height; -+ port->es.video.frame_rate.num = 0; -+ port->es.video.frame_rate.den = 1; -+ } else { -+ /* Compressed format - leave resolution as 0 for decode */ -+ if (decode) { -+ port->es.video.width = 0; -+ port->es.video.height = 0; -+ port->es.video.crop.width = 0; -+ port->es.video.crop.height = 0; -+ } else { -+ port->es.video.width = q_data->crop_width; -+ port->es.video.height = q_data->height; -+ port->es.video.crop.width = q_data->crop_width; -+ port->es.video.crop.height = q_data->crop_height; -+ port->format.bitrate = ctx->bitrate; -+ } -+ port->es.video.frame_rate.num = 0; -+ port->es.video.frame_rate.den = 1; -+ } -+ port->es.video.crop.x = 0; -+ port->es.video.crop.y = 0; -+ -+ port->current_buffer.size = q_data->sizeimage; -+}; -+ -+static void ip_buffer_cb(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port, int status, -+ struct mmal_buffer *mmal_buf) -+{ -+ struct bcm2835_codec_ctx *ctx = port->cb_ctx/*, *curr_ctx*/; -+ struct m2m_mmal_buffer *buf = -+ container_of(mmal_buf, struct m2m_mmal_buffer, mmal); -+ -+ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: port %p buf %p length %lu, flags %x\n", -+ __func__, port, mmal_buf, mmal_buf->length, -+ mmal_buf->mmal_flags); -+ -+ if (buf == &ctx->q_data[V4L2_M2M_SRC].eos_buffer) { -+ /* Do we need to add lcoking to prevent multiple submission of -+ * the EOS, and therefore handle mutliple return here? -+ */ -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: eos buffer returned.\n", -+ __func__); -+ ctx->q_data[V4L2_M2M_SRC].eos_buffer_in_use = false; -+ return; -+ } -+ -+ if (status) { -+ /* error in transfer */ -+ if (buf) -+ /* there was a buffer with the error so return it */ -+ vb2_buffer_done(&buf->m2m.vb.vb2_buf, -+ VB2_BUF_STATE_ERROR); -+ return; -+ } -+ if (mmal_buf->cmd) { -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Not expecting cmd msgs on ip callback - %08x\n", -+ __func__, mmal_buf->cmd); -+ /* -+ * CHECKME: Should we return here. The buffer shouldn't have a -+ * message context or vb2 buf associated. -+ */ -+ } -+ -+ v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: no error. Return buffer %p\n", -+ __func__, &buf->m2m.vb.vb2_buf); -+ vb2_buffer_done(&buf->m2m.vb.vb2_buf, VB2_BUF_STATE_DONE); -+ -+ ctx->num_ip_buffers++; -+ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: done %d input buffers\n", -+ __func__, ctx->num_ip_buffers); -+ -+ if (!port->enabled) -+ complete(&ctx->frame_cmplt); -+} -+ -+static void queue_res_chg_event(struct bcm2835_codec_ctx *ctx) -+{ -+ static const struct v4l2_event ev_src_ch = { -+ .type = V4L2_EVENT_SOURCE_CHANGE, -+ .u.src_change.changes = -+ V4L2_EVENT_SRC_CH_RESOLUTION, -+ }; -+ -+ v4l2_event_queue_fh(&ctx->fh, &ev_src_ch); -+} -+ -+static void send_eos_event(struct bcm2835_codec_ctx *ctx) -+{ -+ static const struct v4l2_event ev = { -+ .type = V4L2_EVENT_EOS, -+ }; -+ -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Sending EOS event\n"); -+ -+ v4l2_event_queue_fh(&ctx->fh, &ev); -+} -+ -+static void color_mmal2v4l(struct bcm2835_codec_ctx *ctx, u32 mmal_color_space) -+{ -+ switch (mmal_color_space) { -+ case MMAL_COLOR_SPACE_ITUR_BT601: -+ ctx->colorspace = V4L2_COLORSPACE_REC709; -+ ctx->xfer_func = V4L2_XFER_FUNC_709; -+ ctx->ycbcr_enc = V4L2_YCBCR_ENC_601; -+ ctx->quant = V4L2_QUANTIZATION_LIM_RANGE; -+ break; -+ -+ case MMAL_COLOR_SPACE_ITUR_BT709: -+ ctx->colorspace = V4L2_COLORSPACE_REC709; -+ ctx->xfer_func = V4L2_XFER_FUNC_709; -+ ctx->ycbcr_enc = V4L2_YCBCR_ENC_709; -+ ctx->quant = V4L2_QUANTIZATION_LIM_RANGE; -+ break; -+ } -+} -+ -+static void handle_fmt_changed(struct bcm2835_codec_ctx *ctx, -+ struct mmal_buffer *mmal_buf) -+{ -+ struct bcm2835_codec_q_data *q_data; -+ struct mmal_msg_event_format_changed *format = -+ (struct mmal_msg_event_format_changed *)mmal_buf->buffer; -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Format changed: buff size min %u, rec %u, buff num min %u, rec %u\n", -+ __func__, -+ format->buffer_size_min, -+ format->buffer_size_recommended, -+ format->buffer_num_min, -+ format->buffer_num_recommended -+ ); -+ if (format->format.type != MMAL_ES_TYPE_VIDEO) { -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Format changed but not video %u\n", -+ __func__, format->format.type); -+ return; -+ } -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Format changed to %ux%u, crop %ux%u, colourspace %08X\n", -+ __func__, format->es.video.width, format->es.video.height, -+ format->es.video.crop.width, format->es.video.crop.height, -+ format->es.video.color_space); -+ -+ q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); -+ q_data->crop_width = format->es.video.crop.width; -+ q_data->crop_height = format->es.video.crop.height; -+ q_data->bytesperline = format->es.video.crop.width; -+ q_data->height = format->es.video.height; -+ q_data->sizeimage = format->buffer_size_min; -+ if (format->es.video.color_space) -+ color_mmal2v4l(ctx, format->es.video.color_space); -+ -+ queue_res_chg_event(ctx); -+} -+ -+static void op_buffer_cb(struct vchiq_mmal_instance *instance, -+ struct vchiq_mmal_port *port, int status, -+ struct mmal_buffer *mmal_buf) -+{ -+ struct bcm2835_codec_ctx *ctx = port->cb_ctx; -+ struct m2m_mmal_buffer *buf; -+ struct vb2_v4l2_buffer *vb2; -+ -+ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, -+ "%s: status:%d, buf:%p, length:%lu, flags %u, pts %lld\n", -+ __func__, status, mmal_buf, mmal_buf->length, -+ mmal_buf->mmal_flags, mmal_buf->pts); -+ -+ if (status) { -+ /* error in transfer */ -+ if (vb2) { -+ /* there was a buffer with the error so return it */ -+ vb2_buffer_done(&vb2->vb2_buf, VB2_BUF_STATE_ERROR); -+ } -+ return; -+ } -+ -+ if (mmal_buf->cmd) { -+ switch (mmal_buf->cmd) { -+ case MMAL_EVENT_FORMAT_CHANGED: -+ { -+ handle_fmt_changed(ctx, mmal_buf); -+ break; -+ } -+ default: -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Unexpected event on output callback - %08x\n", -+ __func__, mmal_buf->cmd); -+ break; -+ } -+ return; -+ } -+ -+ buf = container_of(mmal_buf, struct m2m_mmal_buffer, mmal); -+ vb2 = &buf->m2m.vb; -+ -+ v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: length %lu, flags %x, idx %u\n", -+ __func__, mmal_buf->length, mmal_buf->mmal_flags, -+ vb2->vb2_buf.index); -+ -+ if (mmal_buf->length == 0) { -+ /* stream ended, or buffer being returned during disable. */ -+ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: Empty buffer - flags %04x", -+ __func__, mmal_buf->mmal_flags); -+ if (!mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS) { -+ vb2_buffer_done(&vb2->vb2_buf, VB2_BUF_STATE_ERROR); -+ if (!port->enabled) -+ complete(&ctx->frame_cmplt); -+ return; -+ } -+ } -+ if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS) { -+ /* EOS packet from the VPU */ -+ send_eos_event(ctx); -+ vb2->flags |= V4L2_BUF_FLAG_LAST; -+ } -+ -+ vb2->vb2_buf.timestamp = mmal_buf->pts; -+ -+ vb2_set_plane_payload(&vb2->vb2_buf, 0, mmal_buf->length); -+ if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) -+ vb2->flags |= V4L2_BUF_FLAG_KEYFRAME; -+ -+ vb2_buffer_done(&vb2->vb2_buf, VB2_BUF_STATE_DONE); -+ ctx->num_op_buffers++; -+ -+ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: done %d output buffers\n", -+ __func__, ctx->num_op_buffers); -+ -+ if (!port->enabled) -+ complete(&ctx->frame_cmplt); -+} -+ -+/* vb2_to_mmal_buffer() - converts vb2 buffer header to MMAL -+ * -+ * Copies all the required fields from a VB2 buffer to the MMAL buffer header, -+ * ready for sending to the VPU. -+ */ -+static void vb2_to_mmal_buffer(struct m2m_mmal_buffer *buf, -+ struct vb2_v4l2_buffer *vb2) -+{ -+ buf->mmal.mmal_flags = 0; -+ if (vb2->flags & V4L2_BUF_FLAG_KEYFRAME) -+ buf->mmal.mmal_flags |= MMAL_BUFFER_HEADER_FLAG_KEYFRAME; -+ -+ /* -+ * Adding this means that the data must be framed correctly as one frame -+ * per buffer. The underlying decoder has no such requirement, but it -+ * will reduce latency as the bistream parser will be kicked immediately -+ * to parse the frame, rather than relying on its own heuristics for -+ * when to wake up. -+ */ -+ buf->mmal.mmal_flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END; -+ -+ buf->mmal.length = vb2->vb2_buf.planes[0].bytesused; -+ /* -+ * Minor ambiguity in the V4L2 spec as to whether passing in a 0 length -+ * buffer, or one with V4L2_BUF_FLAG_LAST set denotes end of stream. -+ * Handle either. -+ */ -+ if (!buf->mmal.length || vb2->flags & V4L2_BUF_FLAG_LAST) -+ buf->mmal.mmal_flags |= MMAL_BUFFER_HEADER_FLAG_EOS; -+ -+ buf->mmal.pts = vb2->vb2_buf.timestamp; -+ buf->mmal.dts = MMAL_TIME_UNKNOWN; -+} -+ -+/* device_run() - prepares and starts the device -+ * -+ * This simulates all the immediate preparations required before starting -+ * a device. This will be called by the framework when it decides to schedule -+ * a particular instance. -+ */ -+static void device_run(void *priv) -+{ -+ struct bcm2835_codec_ctx *ctx = priv; -+ struct bcm2835_codec_dev *dev = ctx->dev; -+ struct vb2_v4l2_buffer *src_buf, *dst_buf; -+ struct m2m_mmal_buffer *src_m2m_buf, *dst_m2m_buf; -+ struct v4l2_m2m_buffer *m2m; -+ int ret; -+ -+ v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: off we go\n", __func__); -+ -+ src_buf = v4l2_m2m_buf_remove(&ctx->fh.m2m_ctx->out_q_ctx); -+ if (src_buf) { -+ m2m = container_of(src_buf, struct v4l2_m2m_buffer, vb); -+ src_m2m_buf = container_of(m2m, struct m2m_mmal_buffer, m2m); -+ vb2_to_mmal_buffer(src_m2m_buf, src_buf); -+ -+ ret = vchiq_mmal_submit_buffer(dev->instance, -+ &ctx->component->input[0], -+ &src_m2m_buf->mmal); -+ v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: Submitted ip buffer len %lu, pts %llu, flags %04x\n", -+ __func__, src_m2m_buf->mmal.length, -+ src_m2m_buf->mmal.pts, src_m2m_buf->mmal.mmal_flags); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed submitting ip buffer\n", -+ __func__); -+ } -+ -+ dst_buf = v4l2_m2m_buf_remove(&ctx->fh.m2m_ctx->cap_q_ctx); -+ if (dst_buf) { -+ m2m = container_of(dst_buf, struct v4l2_m2m_buffer, vb); -+ dst_m2m_buf = container_of(m2m, struct m2m_mmal_buffer, m2m); -+ vb2_to_mmal_buffer(dst_m2m_buf, dst_buf); -+ -+ ret = vchiq_mmal_submit_buffer(dev->instance, -+ &ctx->component->output[0], -+ &dst_m2m_buf->mmal); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed submitting op buffer\n", -+ __func__); -+ } -+ -+ v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: Submitted src %p, dst %p\n", -+ __func__, src_m2m_buf, dst_m2m_buf); -+ -+ /* Complete the job here. */ -+ v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx); -+} -+ -+/* -+ * video ioctls -+ */ -+static int vidioc_querycap(struct file *file, void *priv, -+ struct v4l2_capability *cap) -+{ -+ strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1); -+ strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1); -+ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", -+ MEM2MEM_NAME); -+ cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; -+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; -+ return 0; -+} -+ -+static int enum_fmt(struct v4l2_fmtdesc *f, bool decode, bool capture) -+{ -+ struct bcm2835_codec_fmt *fmt; -+ struct bcm2835_codec_fmt_list *fmts = get_format_list(decode, capture); -+ -+ if (f->index < fmts->num_entries) { -+ /* Format found */ -+ /* Check format isn't a decode only format when encoding */ -+ if (!decode && -+ fmts->list[f->index].decode_only) -+ return -EINVAL; -+ /* Check format isn't a decode only format when encoding */ -+ if (decode && -+ fmts->list[f->index].encode_only) -+ return -EINVAL; -+ -+ fmt = &fmts->list[f->index]; -+ f->pixelformat = fmt->fourcc; -+ f->flags = fmt->flags; -+ return 0; -+ } -+ -+ /* Format not found */ -+ return -EINVAL; -+} -+ -+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, -+ struct v4l2_fmtdesc *f) -+{ -+ struct bcm2835_codec_ctx *ctx = file2ctx(file); -+ -+ return enum_fmt(f, ctx->dev->decode, true); -+} -+ -+static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, -+ struct v4l2_fmtdesc *f) -+{ -+ struct bcm2835_codec_ctx *ctx = file2ctx(file); -+ -+ return enum_fmt(f, ctx->dev->decode, false); -+} -+ -+static int vidioc_g_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f) -+{ -+ struct vb2_queue *vq; -+ struct bcm2835_codec_q_data *q_data; -+ -+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); -+ if (!vq) -+ return -EINVAL; -+ -+ q_data = get_q_data(ctx, f->type); -+ -+ f->fmt.pix.width = q_data->crop_width; -+ f->fmt.pix.height = q_data->height; -+ f->fmt.pix.field = V4L2_FIELD_NONE; -+ f->fmt.pix.pixelformat = q_data->fmt->fourcc; -+ f->fmt.pix.bytesperline = q_data->bytesperline; -+ f->fmt.pix.sizeimage = q_data->sizeimage; -+ f->fmt.pix.colorspace = ctx->colorspace; -+ f->fmt.pix.xfer_func = ctx->xfer_func; -+ f->fmt.pix.ycbcr_enc = ctx->ycbcr_enc; -+ f->fmt.pix.quantization = ctx->quant; -+ -+ return 0; -+} -+ -+static int vidioc_g_fmt_vid_out(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ return vidioc_g_fmt(file2ctx(file), f); -+} -+ -+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ return vidioc_g_fmt(file2ctx(file), f); -+} -+ -+static int vidioc_try_fmt(struct v4l2_format *f, struct bcm2835_codec_fmt *fmt) -+{ -+ /* -+ * The V4L2 specification requires the driver to correct the format -+ * struct if any of the dimensions is unsupported -+ */ -+ if (f->fmt.pix.width > MAX_W) -+ f->fmt.pix.width = MAX_W; -+ if (f->fmt.pix.height > MAX_H) -+ f->fmt.pix.height = MAX_H; -+ -+ if (!fmt->flags & V4L2_FMT_FLAG_COMPRESSED) { -+ /* Only clip min w/h on capture. Treat 0x0 as unknown. */ -+ if (f->fmt.pix.width < MIN_W) -+ f->fmt.pix.width = MIN_W; -+ if (f->fmt.pix.height < MIN_H) -+ f->fmt.pix.height = MIN_H; -+ -+ /* -+ * Buffer must have a vertical alignment of 16 lines. -+ * The selection will reflect any cropping rectangle when only -+ * some of the pixels are active. -+ */ -+ f->fmt.pix.height = ALIGN(f->fmt.pix.height, 16); -+ -+ f->fmt.pix.bytesperline = get_bytesperline(f->fmt.pix.width, -+ fmt); -+ f->fmt.pix.sizeimage = get_sizeimage(f->fmt.pix.bytesperline, -+ f->fmt.pix.height, -+ fmt); -+ } else { -+ u32 min_size = f->fmt.pix.width > 1280 || -+ f->fmt.pix.height > 720 ? -+ DEF_COMP_BUF_SIZE_GREATER_720P : -+ DEF_COMP_BUF_SIZE_720P_OR_LESS; -+ -+ f->fmt.pix.bytesperline = 0; -+ if (f->fmt.pix.sizeimage < min_size) -+ f->fmt.pix.sizeimage = min_size; -+ } -+ -+ f->fmt.pix.field = V4L2_FIELD_NONE; -+ -+ return 0; -+} -+ -+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct bcm2835_codec_fmt *fmt; -+ struct bcm2835_codec_ctx *ctx = file2ctx(file); -+ -+ fmt = find_format(f, ctx->dev->decode, true); -+ if (!fmt) { -+ f->fmt.pix.pixelformat = get_default_format(ctx->dev->decode, -+ true)->fourcc; -+ fmt = find_format(f, ctx->dev->decode, true); -+ } -+ -+ return vidioc_try_fmt(f, fmt); -+} -+ -+static int vidioc_try_fmt_vid_out(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct bcm2835_codec_fmt *fmt; -+ struct bcm2835_codec_ctx *ctx = file2ctx(file); -+ -+ fmt = find_format(f, ctx->dev->decode, false); -+ if (!fmt) { -+ f->fmt.pix.pixelformat = get_default_format(ctx->dev->decode, -+ false)->fourcc; -+ fmt = find_format(f, ctx->dev->decode, false); -+ } -+ -+ if (!f->fmt.pix.colorspace) -+ f->fmt.pix.colorspace = ctx->colorspace; -+ -+ return vidioc_try_fmt(f, fmt); -+} -+ -+static int vidioc_s_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f, -+ unsigned int requested_height) -+{ -+ struct bcm2835_codec_q_data *q_data; -+ struct vb2_queue *vq; -+ struct vchiq_mmal_port *port; -+ bool update_capture_port = false; -+ int ret; -+ -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Setting format for type %d, wxh: %dx%d, fmt: %08x, size %u\n", -+ f->type, f->fmt.pix.width, f->fmt.pix.height, -+ f->fmt.pix.pixelformat, f->fmt.pix.sizeimage); -+ -+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); -+ if (!vq) -+ return -EINVAL; -+ -+ q_data = get_q_data(ctx, f->type); -+ if (!q_data) -+ return -EINVAL; -+ -+ if (vb2_is_busy(vq)) { -+ v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__); -+ return -EBUSY; -+ } -+ -+ q_data->fmt = find_format(f, ctx->dev->decode, -+ f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE); -+ q_data->crop_width = f->fmt.pix.width; -+ q_data->height = f->fmt.pix.height; -+ if (!q_data->selection_set) -+ q_data->crop_height = requested_height; -+ -+ /* -+ * Copying the behaviour of vicodec which retains a single set of -+ * colorspace parameters for both input and output. -+ */ -+ ctx->colorspace = f->fmt.pix.colorspace; -+ ctx->xfer_func = f->fmt.pix.xfer_func; -+ ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc; -+ ctx->quant = f->fmt.pix.quantization; -+ -+ /* All parameters should have been set correctly by try_fmt */ -+ q_data->bytesperline = f->fmt.pix.bytesperline; -+ q_data->sizeimage = f->fmt.pix.sizeimage; -+ -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Calulated bpl as %u, size %u\n", -+ q_data->bytesperline, q_data->sizeimage); -+ -+ if (ctx->dev->decode && q_data->fmt->flags & V4L2_FMT_FLAG_COMPRESSED && -+ f->fmt.pix.width && f->fmt.pix.height) { -+ /* -+ * On the decoder, if provided with a resolution on the input -+ * side, then replicate that to the output side. -+ * GStreamer appears not to support V4L2_EVENT_SOURCE_CHANGE, -+ * nor set up a resolution on the output side, therefore -+ * we can't decode anything at a resolution other than the -+ * default one. -+ */ -+ struct bcm2835_codec_q_data *q_data_dst = -+ &ctx->q_data[V4L2_M2M_DST]; -+ -+ q_data_dst->crop_width = q_data->crop_width; -+ q_data_dst->crop_height = q_data->crop_height; -+ q_data_dst->height = ALIGN(q_data->crop_height, 16); -+ -+ q_data_dst->bytesperline = -+ get_bytesperline(f->fmt.pix.width, q_data_dst->fmt); -+ q_data_dst->sizeimage = get_sizeimage(q_data_dst->bytesperline, -+ q_data_dst->height, -+ q_data_dst->fmt); -+ update_capture_port = true; -+ } -+ -+ /* If we have a component then setup the port as well */ -+ port = get_port_data(ctx, vq->type); -+ if (!port) -+ return 0; -+ -+ setup_mmal_port_format(ctx, ctx->dev->decode, q_data, port); -+ ret = vchiq_mmal_port_set_format(ctx->dev->instance, port); -+ if (ret) { -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed vchiq_mmal_port_set_format on port, ret %d\n", -+ __func__, ret); -+ ret = -EINVAL; -+ } -+ -+ if (q_data->sizeimage < port->minimum_buffer.size) { -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Current buffer size of %u < min buf size %u - driver mismatch to MMAL\n", -+ __func__, q_data->sizeimage, -+ port->minimum_buffer.size); -+ } -+ -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Set format for type %d, wxh: %dx%d, fmt: %08x, size %u\n", -+ f->type, q_data->crop_width, q_data->height, -+ q_data->fmt->fourcc, q_data->sizeimage); -+ -+ if (update_capture_port) { -+ struct vchiq_mmal_port *port_dst = &ctx->component->output[0]; -+ struct bcm2835_codec_q_data *q_data_dst = -+ &ctx->q_data[V4L2_M2M_DST]; -+ -+ setup_mmal_port_format(ctx, ctx->dev->decode, q_data_dst, -+ port_dst); -+ ret = vchiq_mmal_port_set_format(ctx->dev->instance, port_dst); -+ if (ret) { -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed vchiq_mmal_port_set_format on output port, ret %d\n", -+ __func__, ret); -+ ret = -EINVAL; -+ } -+ } -+ return ret; -+} -+ -+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ unsigned int height = f->fmt.pix.height; -+ int ret; -+ -+ ret = vidioc_try_fmt_vid_cap(file, priv, f); -+ if (ret) -+ return ret; -+ -+ return vidioc_s_fmt(file2ctx(file), f, height); -+} -+ -+static int vidioc_s_fmt_vid_out(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ unsigned int height = f->fmt.pix.height; -+ int ret; -+ -+ ret = vidioc_try_fmt_vid_out(file, priv, f); -+ if (ret) -+ return ret; -+ -+ ret = vidioc_s_fmt(file2ctx(file), f, height); -+ return ret; -+} -+ -+static int vidioc_g_selection(struct file *file, void *priv, -+ struct v4l2_selection *s) -+{ -+ struct bcm2835_codec_ctx *ctx = file2ctx(file); -+ struct bcm2835_codec_q_data *q_data; -+ bool capture_queue = s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? -+ true : false; -+ -+ if (capture_queue ^ ctx->dev->decode) -+ /* OUTPUT on decoder and CAPTURE on encoder are not valid. */ -+ return -EINVAL; -+ -+ q_data = get_q_data(ctx, s->type); -+ if (!q_data) -+ return -EINVAL; -+ -+ if (ctx->dev->decode) { -+ switch (s->target) { -+ case V4L2_SEL_TGT_COMPOSE_DEFAULT: -+ case V4L2_SEL_TGT_COMPOSE: -+ s->r.left = 0; -+ s->r.top = 0; -+ s->r.width = q_data->crop_width; -+ s->r.height = q_data->crop_height; -+ break; -+ case V4L2_SEL_TGT_COMPOSE_BOUNDS: -+ s->r.left = 0; -+ s->r.top = 0; -+ s->r.width = q_data->crop_width; -+ s->r.height = q_data->crop_height; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } else { -+ switch (s->target) { -+ case V4L2_SEL_TGT_CROP_DEFAULT: -+ case V4L2_SEL_TGT_CROP_BOUNDS: -+ s->r.top = 0; -+ s->r.left = 0; -+ s->r.width = q_data->bytesperline; -+ s->r.height = q_data->height; -+ break; -+ case V4L2_SEL_TGT_CROP: -+ s->r.top = 0; -+ s->r.left = 0; -+ s->r.width = q_data->crop_width; -+ s->r.height = q_data->crop_height; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ -+ return 0; -+} -+ -+static int vidioc_s_selection(struct file *file, void *priv, -+ struct v4l2_selection *s) -+{ -+ struct bcm2835_codec_ctx *ctx = file2ctx(file); -+ struct bcm2835_codec_q_data *q_data = NULL; -+ bool capture_queue = s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? -+ true : false; -+ -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: ctx %p, type %d, q_data %p, target %d, rect x/y %d/%d, w/h %ux%u\n", -+ __func__, ctx, s->type, q_data, s->target, s->r.left, s->r.top, -+ s->r.width, s->r.height); -+ -+ if (capture_queue ^ ctx->dev->decode) -+ /* OUTPUT on decoder and CAPTURE on encoder are not valid. */ -+ return -EINVAL; -+ -+ q_data = get_q_data(ctx, s->type); -+ if (!q_data) -+ return -EINVAL; -+ -+ if (ctx->dev->decode) { -+ switch (s->target) { -+ case V4L2_SEL_TGT_COMPOSE: -+ /* Accept cropped image */ -+ s->r.left = 0; -+ s->r.top = 0; -+ s->r.width = min(s->r.width, q_data->crop_width); -+ s->r.height = min(s->r.height, q_data->height); -+ q_data->crop_width = s->r.width; -+ q_data->crop_height = s->r.height; -+ q_data->selection_set = true; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } else { -+ switch (s->target) { -+ case V4L2_SEL_TGT_CROP: -+ /* Only support crop from (0,0) */ -+ s->r.top = 0; -+ s->r.left = 0; -+ s->r.width = min(s->r.width, q_data->crop_width); -+ s->r.height = min(s->r.height, q_data->crop_height); -+ q_data->crop_width = s->r.width; -+ q_data->crop_height = s->r.height; -+ q_data->selection_set = true; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ -+ return 0; -+} -+ -+static int vidioc_subscribe_evt(struct v4l2_fh *fh, -+ const struct v4l2_event_subscription *sub) -+{ -+ switch (sub->type) { -+ case V4L2_EVENT_EOS: -+ return v4l2_event_subscribe(fh, sub, 2, NULL); -+ case V4L2_EVENT_SOURCE_CHANGE: -+ return v4l2_src_change_event_subscribe(fh, sub); -+ default: -+ return v4l2_ctrl_subscribe_event(fh, sub); -+ } -+} -+ -+static int bcm2835_codec_set_level_profile(struct bcm2835_codec_ctx *ctx, -+ struct v4l2_ctrl *ctrl) -+{ -+ struct mmal_parameter_video_profile param; -+ int param_size = sizeof(param); -+ int ret; -+ -+ /* -+ * Level and Profile are set via the same MMAL parameter. -+ * Retrieve the current settings and amend the one that has changed. -+ */ -+ ret = vchiq_mmal_port_parameter_get(ctx->dev->instance, -+ &ctx->component->output[0], -+ MMAL_PARAMETER_PROFILE, -+ ¶m, -+ ¶m_size); -+ if (ret) -+ return ret; -+ -+ switch (ctrl->id) { -+ case V4L2_CID_MPEG_VIDEO_H264_PROFILE: -+ switch (ctrl->val) { -+ case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: -+ param.profile = MMAL_VIDEO_PROFILE_H264_BASELINE; -+ break; -+ case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: -+ param.profile = -+ MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE; -+ break; -+ case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: -+ param.profile = MMAL_VIDEO_PROFILE_H264_MAIN; -+ break; -+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: -+ param.profile = MMAL_VIDEO_PROFILE_H264_HIGH; -+ break; -+ default: -+ /* Should never get here */ -+ break; -+ } -+ break; -+ -+ case V4L2_CID_MPEG_VIDEO_H264_LEVEL: -+ switch (ctrl->val) { -+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: -+ param.level = MMAL_VIDEO_LEVEL_H264_1; -+ break; -+ case V4L2_MPEG_VIDEO_H264_LEVEL_1B: -+ param.level = MMAL_VIDEO_LEVEL_H264_1b; -+ break; -+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_1: -+ param.level = MMAL_VIDEO_LEVEL_H264_11; -+ break; -+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_2: -+ param.level = MMAL_VIDEO_LEVEL_H264_12; -+ break; -+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_3: -+ param.level = MMAL_VIDEO_LEVEL_H264_13; -+ break; -+ case V4L2_MPEG_VIDEO_H264_LEVEL_2_0: -+ param.level = MMAL_VIDEO_LEVEL_H264_2; -+ break; -+ case V4L2_MPEG_VIDEO_H264_LEVEL_2_1: -+ param.level = MMAL_VIDEO_LEVEL_H264_21; -+ break; -+ case V4L2_MPEG_VIDEO_H264_LEVEL_2_2: -+ param.level = MMAL_VIDEO_LEVEL_H264_22; -+ break; -+ case V4L2_MPEG_VIDEO_H264_LEVEL_3_0: -+ param.level = MMAL_VIDEO_LEVEL_H264_3; -+ break; -+ case V4L2_MPEG_VIDEO_H264_LEVEL_3_1: -+ param.level = MMAL_VIDEO_LEVEL_H264_31; -+ break; -+ case V4L2_MPEG_VIDEO_H264_LEVEL_3_2: -+ param.level = MMAL_VIDEO_LEVEL_H264_32; -+ break; -+ case V4L2_MPEG_VIDEO_H264_LEVEL_4_0: -+ param.level = MMAL_VIDEO_LEVEL_H264_4; -+ break; -+ default: -+ /* Should never get here */ -+ break; -+ } -+ } -+ ret = vchiq_mmal_port_parameter_set(ctx->dev->instance, -+ &ctx->component->output[0], -+ MMAL_PARAMETER_PROFILE, -+ ¶m, -+ param_size); -+ -+ return ret; -+} -+ -+static int bcm2835_codec_s_ctrl(struct v4l2_ctrl *ctrl) -+{ -+ struct bcm2835_codec_ctx *ctx = -+ container_of(ctrl->handler, struct bcm2835_codec_ctx, hdl); -+ int ret = 0; -+ -+ switch (ctrl->id) { -+ case V4L2_CID_MPEG_VIDEO_BITRATE: -+ ctx->bitrate = ctrl->val; -+ if (!ctx->component) -+ break; -+ -+ ret = vchiq_mmal_port_parameter_set(ctx->dev->instance, -+ &ctx->component->output[0], -+ MMAL_PARAMETER_VIDEO_BIT_RATE, -+ &ctrl->val, -+ sizeof(ctrl->val)); -+ break; -+ -+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: { -+ u32 bitrate_mode; -+ -+ if (!ctx->component) -+ break; -+ -+ switch (ctrl->val) { -+ default: -+ case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR: -+ bitrate_mode = MMAL_VIDEO_RATECONTROL_VARIABLE; -+ break; -+ case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR: -+ bitrate_mode = MMAL_VIDEO_RATECONTROL_CONSTANT; -+ break; -+ } -+ -+ ret = vchiq_mmal_port_parameter_set(ctx->dev->instance, -+ &ctx->component->output[0], -+ MMAL_PARAMETER_RATECONTROL, -+ &bitrate_mode, -+ sizeof(bitrate_mode)); -+ break; -+ } -+ case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER: -+ if (!ctx->component) -+ break; -+ -+ ret = vchiq_mmal_port_parameter_set(ctx->dev->instance, -+ &ctx->component->output[0], -+ MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER, -+ &ctrl->val, -+ sizeof(ctrl->val)); -+ break; -+ -+ case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: -+ if (!ctx->component) -+ break; -+ -+ ret = vchiq_mmal_port_parameter_set(ctx->dev->instance, -+ &ctx->component->output[0], -+ MMAL_PARAMETER_INTRAPERIOD, -+ &ctrl->val, -+ sizeof(ctrl->val)); -+ break; -+ -+ case V4L2_CID_MPEG_VIDEO_H264_PROFILE: -+ case V4L2_CID_MPEG_VIDEO_H264_LEVEL: -+ if (!ctx->component) -+ break; -+ -+ ret = bcm2835_codec_set_level_profile(ctx, ctrl); -+ break; -+ -+ default: -+ v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n"); -+ return -EINVAL; -+ } -+ -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, "Failed setting ctrl %08x, ret %d\n", -+ ctrl->id, ret); -+ return ret ? -EINVAL : 0; -+} -+ -+static const struct v4l2_ctrl_ops bcm2835_codec_ctrl_ops = { -+ .s_ctrl = bcm2835_codec_s_ctrl, -+}; -+ -+static int vidioc_try_decoder_cmd(struct file *file, void *priv, -+ struct v4l2_decoder_cmd *cmd) -+{ -+ struct bcm2835_codec_ctx *ctx = file2ctx(file); -+ -+ if (!ctx->dev->decode) -+ return -EINVAL; -+ -+ switch (cmd->cmd) { -+ case V4L2_DEC_CMD_STOP: -+ if (cmd->flags & V4L2_DEC_CMD_STOP_TO_BLACK) { -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: DEC cmd->flags=%u stop to black not supported", -+ __func__, cmd->flags); -+ return -EINVAL; -+ } -+ break; -+ case V4L2_DEC_CMD_START: -+ break; -+ default: -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static int vidioc_decoder_cmd(struct file *file, void *priv, -+ struct v4l2_decoder_cmd *cmd) -+{ -+ struct bcm2835_codec_ctx *ctx = file2ctx(file); -+ struct bcm2835_codec_q_data *q_data = &ctx->q_data[V4L2_M2M_SRC]; -+ int ret; -+ -+ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s, cmd %u", __func__, -+ cmd->cmd); -+ ret = vidioc_try_decoder_cmd(file, priv, cmd); -+ if (ret) -+ return ret; -+ -+ switch (cmd->cmd) { -+ case V4L2_DEC_CMD_STOP: -+ if (q_data->eos_buffer_in_use) -+ v4l2_err(&ctx->dev->v4l2_dev, "EOS buffers already in use\n"); -+ q_data->eos_buffer_in_use = true; -+ -+ q_data->eos_buffer.mmal.buffer_size = 0; -+ q_data->eos_buffer.mmal.length = 0; -+ q_data->eos_buffer.mmal.mmal_flags = -+ MMAL_BUFFER_HEADER_FLAG_EOS; -+ q_data->eos_buffer.mmal.pts = 0; -+ q_data->eos_buffer.mmal.dts = 0; -+ -+ if (!ctx->component) -+ break; -+ -+ ret = vchiq_mmal_submit_buffer(ctx->dev->instance, -+ &ctx->component->input[0], -+ &q_data->eos_buffer.mmal); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, -+ "%s: EOS buffer submit failed %d\n", -+ __func__, ret); -+ -+ break; -+ -+ case V4L2_DEC_CMD_START: -+ /* Do we need to do anything here? */ -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int vidioc_try_encoder_cmd(struct file *file, void *priv, -+ struct v4l2_encoder_cmd *cmd) -+{ -+ struct bcm2835_codec_ctx *ctx = file2ctx(file); -+ -+ if (ctx->dev->decode) -+ return -EINVAL; -+ -+ switch (cmd->cmd) { -+ case V4L2_ENC_CMD_STOP: -+ break; -+ -+ case V4L2_ENC_CMD_START: -+ /* Do we need to do anything here? */ -+ break; -+ default: -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static int vidioc_encoder_cmd(struct file *file, void *priv, -+ struct v4l2_encoder_cmd *cmd) -+{ -+ struct bcm2835_codec_ctx *ctx = file2ctx(file); -+ struct bcm2835_codec_q_data *q_data = &ctx->q_data[V4L2_M2M_SRC]; -+ int ret; -+ -+ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s, cmd %u", __func__, -+ cmd->cmd); -+ ret = vidioc_try_encoder_cmd(file, priv, cmd); -+ if (ret) -+ return ret; -+ -+ switch (cmd->cmd) { -+ case V4L2_ENC_CMD_STOP: -+ if (q_data->eos_buffer_in_use) -+ v4l2_err(&ctx->dev->v4l2_dev, "EOS buffers already in use\n"); -+ q_data->eos_buffer_in_use = true; -+ -+ q_data->eos_buffer.mmal.buffer_size = 0; -+ q_data->eos_buffer.mmal.length = 0; -+ q_data->eos_buffer.mmal.mmal_flags = -+ MMAL_BUFFER_HEADER_FLAG_EOS; -+ q_data->eos_buffer.mmal.pts = 0; -+ q_data->eos_buffer.mmal.dts = 0; -+ -+ if (!ctx->component) -+ break; -+ -+ ret = vchiq_mmal_submit_buffer(ctx->dev->instance, -+ &ctx->component->input[0], -+ &q_data->eos_buffer.mmal); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, -+ "%s: EOS buffer submit failed %d\n", -+ __func__, ret); -+ -+ break; -+ case V4L2_ENC_CMD_START: -+ /* Do we need to do anything here? */ -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static const struct v4l2_ioctl_ops bcm2835_codec_ioctl_ops = { -+ .vidioc_querycap = vidioc_querycap, -+ -+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, -+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, -+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, -+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, -+ -+ .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out, -+ .vidioc_g_fmt_vid_out = vidioc_g_fmt_vid_out, -+ .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out, -+ .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out, -+ -+ .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, -+ .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, -+ .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, -+ .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, -+ .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, -+ .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, -+ .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, -+ -+ .vidioc_streamon = v4l2_m2m_ioctl_streamon, -+ .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, -+ -+ .vidioc_g_selection = vidioc_g_selection, -+ .vidioc_s_selection = vidioc_s_selection, -+ -+ .vidioc_subscribe_event = vidioc_subscribe_evt, -+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe, -+ -+ .vidioc_decoder_cmd = vidioc_decoder_cmd, -+ .vidioc_try_decoder_cmd = vidioc_try_decoder_cmd, -+ .vidioc_encoder_cmd = vidioc_encoder_cmd, -+ .vidioc_try_encoder_cmd = vidioc_try_encoder_cmd, -+}; -+ -+static int bcm2835_codec_set_ctrls(struct bcm2835_codec_ctx *ctx) -+{ -+ /* -+ * Query the control handler for the value of the various controls and -+ * set them. -+ */ -+ const u32 control_ids[] = { -+ V4L2_CID_MPEG_VIDEO_BITRATE_MODE, -+ V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, -+ V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, -+ V4L2_CID_MPEG_VIDEO_H264_LEVEL, -+ V4L2_CID_MPEG_VIDEO_H264_PROFILE, -+ }; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(control_ids); i++) { -+ struct v4l2_ctrl *ctrl; -+ -+ ctrl = v4l2_ctrl_find(&ctx->hdl, control_ids[i]); -+ if (ctrl) -+ bcm2835_codec_s_ctrl(ctrl); -+ } -+ -+ return 0; -+} -+ -+static int bcm2835_codec_create_component(struct bcm2835_codec_ctx *ctx) -+{ -+ struct bcm2835_codec_dev *dev = ctx->dev; -+ unsigned int enable = 1; -+ int ret; -+ -+ ret = vchiq_mmal_component_init(dev->instance, dev->decode ? -+ "ril.video_decode" : "ril.video_encode", -+ &ctx->component); -+ if (ret < 0) { -+ v4l2_err(&dev->v4l2_dev, "%s: failed to create component for %s\n", -+ __func__, dev->decode ? "decode" : "encode"); -+ return -ENOMEM; -+ } -+ -+ vchiq_mmal_port_parameter_set(dev->instance, &ctx->component->input[0], -+ MMAL_PARAMETER_ZERO_COPY, &enable, -+ sizeof(enable)); -+ vchiq_mmal_port_parameter_set(dev->instance, &ctx->component->output[0], -+ MMAL_PARAMETER_ZERO_COPY, &enable, -+ sizeof(enable)); -+ -+ setup_mmal_port_format(ctx, dev->decode, &ctx->q_data[V4L2_M2M_SRC], -+ &ctx->component->input[0]); -+ -+ setup_mmal_port_format(ctx, dev->decode, &ctx->q_data[V4L2_M2M_DST], -+ &ctx->component->output[0]); -+ -+ ret = vchiq_mmal_port_set_format(dev->instance, -+ &ctx->component->input[0]); -+ if (ret < 0) -+ goto destroy_component; -+ -+ ret = vchiq_mmal_port_set_format(dev->instance, -+ &ctx->component->output[0]); -+ if (ret < 0) -+ goto destroy_component; -+ -+ if (dev->decode) { -+ if (ctx->q_data[V4L2_M2M_DST].sizeimage < -+ ctx->component->output[0].minimum_buffer.size) -+ v4l2_err(&dev->v4l2_dev, "buffer size mismatch sizeimage %u < min size %u\n", -+ ctx->q_data[V4L2_M2M_DST].sizeimage, -+ ctx->component->output[0].minimum_buffer.size); -+ } else { -+ if (ctx->q_data[V4L2_M2M_SRC].sizeimage < -+ ctx->component->output[0].minimum_buffer.size) -+ v4l2_err(&dev->v4l2_dev, "buffer size mismatch sizeimage %u < min size %u\n", -+ ctx->q_data[V4L2_M2M_SRC].sizeimage, -+ ctx->component->output[0].minimum_buffer.size); -+ -+ /* Now we have a component we can set all the ctrls */ -+ bcm2835_codec_set_ctrls(ctx); -+ } -+ -+ return 0; -+ -+destroy_component: -+ vchiq_mmal_component_finalise(ctx->dev->instance, ctx->component); -+ -+ return ret; -+} -+ -+/* -+ * Queue operations -+ */ -+ -+static int bcm2835_codec_queue_setup(struct vb2_queue *vq, -+ unsigned int *nbuffers, -+ unsigned int *nplanes, -+ unsigned int sizes[], -+ struct device *alloc_devs[]) -+{ -+ struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vq); -+ struct bcm2835_codec_q_data *q_data; -+ struct vchiq_mmal_port *port; -+ unsigned int size; -+ -+ q_data = get_q_data(ctx, vq->type); -+ if (!q_data) -+ return -EINVAL; -+ -+ if (!ctx->component) -+ if (bcm2835_codec_create_component(ctx)) -+ return -EINVAL; -+ -+ port = get_port_data(ctx, vq->type); -+ -+ size = q_data->sizeimage; -+ -+ if (*nplanes) -+ return sizes[0] < size ? -EINVAL : 0; -+ -+ *nplanes = 1; -+ -+ sizes[0] = size; -+ port->current_buffer.size = size; -+ -+ if (*nbuffers < port->minimum_buffer.num) -+ *nbuffers = port->minimum_buffer.num; -+ /* Add one buffer to take an EOS */ -+ port->current_buffer.num = *nbuffers + 1; -+ -+ return 0; -+} -+ -+static int bcm2835_codec_buf_init(struct vb2_buffer *vb) -+{ -+ struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); -+ struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb); -+ struct v4l2_m2m_buffer *m2m = container_of(vb2, struct v4l2_m2m_buffer, -+ vb); -+ struct m2m_mmal_buffer *buf = container_of(m2m, struct m2m_mmal_buffer, -+ m2m); -+ -+ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: ctx:%p, vb %p\n", -+ __func__, ctx, vb); -+ buf->mmal.buffer = vb2_plane_vaddr(&buf->m2m.vb.vb2_buf, 0); -+ buf->mmal.buffer_size = vb2_plane_size(&buf->m2m.vb.vb2_buf, 0); -+ -+ mmal_vchi_buffer_init(ctx->dev->instance, &buf->mmal); -+ -+ return 0; -+} -+ -+static int bcm2835_codec_buf_prepare(struct vb2_buffer *vb) -+{ -+ struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); -+ struct bcm2835_codec_q_data *q_data; -+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); -+ struct v4l2_m2m_buffer *m2m = container_of(vbuf, struct v4l2_m2m_buffer, -+ vb); -+ struct m2m_mmal_buffer *buf = container_of(m2m, struct m2m_mmal_buffer, -+ m2m); -+ int ret; -+ -+ v4l2_dbg(4, debug, &ctx->dev->v4l2_dev, "%s: type: %d ptr %p\n", -+ __func__, vb->vb2_queue->type, vb); -+ -+ q_data = get_q_data(ctx, vb->vb2_queue->type); -+ if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { -+ if (vbuf->field == V4L2_FIELD_ANY) -+ vbuf->field = V4L2_FIELD_NONE; -+ if (vbuf->field != V4L2_FIELD_NONE) { -+ v4l2_err(&ctx->dev->v4l2_dev, "%s field isn't supported\n", -+ __func__); -+ return -EINVAL; -+ } -+ } -+ -+ if (vb2_plane_size(vb, 0) < q_data->sizeimage) { -+ v4l2_err(&ctx->dev->v4l2_dev, "%s data will not fit into plane (%lu < %lu)\n", -+ __func__, vb2_plane_size(vb, 0), -+ (long)q_data->sizeimage); -+ return -EINVAL; -+ } -+ -+ if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) -+ vb2_set_plane_payload(vb, 0, q_data->sizeimage); -+ -+ /* -+ * We want to do this at init, but vb2_core_expbuf checks that the -+ * index < q->num_buffers, and q->num_buffers only gets updated once -+ * all the buffers are allocated. -+ */ -+ if (!buf->mmal.dma_buf) { -+ ret = vb2_core_expbuf_dmabuf(vb->vb2_queue, -+ vb->vb2_queue->type, vb->index, 0, -+ O_CLOEXEC, &buf->mmal.dma_buf); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed to expbuf idx %d, ret %d\n", -+ __func__, vb->index, ret); -+ } else { -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+static void bcm2835_codec_buf_queue(struct vb2_buffer *vb) -+{ -+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); -+ struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); -+ -+ v4l2_dbg(4, debug, &ctx->dev->v4l2_dev, "%s: type: %d ptr %p vbuf->flags %u, seq %u, bytesused %u\n", -+ __func__, vb->vb2_queue->type, vb, vbuf->flags, vbuf->sequence, -+ vb->planes[0].bytesused); -+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); -+} -+ -+static void bcm2835_codec_buffer_cleanup(struct vb2_buffer *vb) -+{ -+ struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); -+ struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb); -+ struct v4l2_m2m_buffer *m2m = container_of(vb2, struct v4l2_m2m_buffer, -+ vb); -+ struct m2m_mmal_buffer *buf = container_of(m2m, struct m2m_mmal_buffer, -+ m2m); -+ -+ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: ctx:%p, vb %p\n", -+ __func__, ctx, vb); -+ -+ mmal_vchi_buffer_cleanup(&buf->mmal); -+ -+ if (buf->mmal.dma_buf) { -+ dma_buf_put(buf->mmal.dma_buf); -+ buf->mmal.dma_buf = NULL; -+ } -+} -+ -+static int bcm2835_codec_start_streaming(struct vb2_queue *q, -+ unsigned int count) -+{ -+ struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(q); -+ struct bcm2835_codec_dev *dev = ctx->dev; -+ struct bcm2835_codec_q_data *q_data = get_q_data(ctx, q->type); -+ int ret; -+ -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: type: %d count %d\n", -+ __func__, q->type, count); -+ q_data->sequence = 0; -+ -+ if (!ctx->component_enabled) { -+ ret = vchiq_mmal_component_enable(dev->instance, -+ ctx->component); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling component, ret %d\n", -+ __func__, ret); -+ ctx->component_enabled = true; -+ } -+ -+ if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { -+ /* -+ * Create the EOS buffer. -+ * We only need the MMAL part, and want to NOT attach a memory -+ * buffer to it as it should only take flags. -+ */ -+ memset(&q_data->eos_buffer, 0, sizeof(q_data->eos_buffer)); -+ mmal_vchi_buffer_init(dev->instance, -+ &q_data->eos_buffer.mmal); -+ q_data->eos_buffer_in_use = false; -+ -+ ctx->component->input[0].cb_ctx = ctx; -+ ret = vchiq_mmal_port_enable(dev->instance, -+ &ctx->component->input[0], -+ ip_buffer_cb); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling i/p port, ret %d\n", -+ __func__, ret); -+ } else { -+ ctx->component->output[0].cb_ctx = ctx; -+ ret = vchiq_mmal_port_enable(dev->instance, -+ &ctx->component->output[0], -+ op_buffer_cb); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling o/p port, ret %d\n", -+ __func__, ret); -+ } -+ return ret; -+} -+ -+static void bcm2835_codec_stop_streaming(struct vb2_queue *q) -+{ -+ struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(q); -+ struct bcm2835_codec_dev *dev = ctx->dev; -+ struct bcm2835_codec_q_data *q_data = get_q_data(ctx, q->type); -+ struct vchiq_mmal_port *port = get_port_data(ctx, q->type); -+ struct vb2_v4l2_buffer *vbuf; -+ struct vb2_v4l2_buffer *vb2; -+ struct v4l2_m2m_buffer *m2m; -+ struct m2m_mmal_buffer *buf; -+ int ret, i; -+ -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: type: %d - return buffers\n", -+ __func__, q->type); -+ -+ init_completion(&ctx->frame_cmplt); -+ -+ /* Clear out all buffers held by m2m framework */ -+ for (;;) { -+ if (V4L2_TYPE_IS_OUTPUT(q->type)) -+ vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); -+ else -+ vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); -+ if (!vbuf) -+ break; -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: return buffer %p\n", -+ __func__, vbuf); -+ -+ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); -+ } -+ -+ /* Disable MMAL port - this will flush buffers back */ -+ ret = vchiq_mmal_port_disable(dev->instance, port); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed disabling %s port, ret %d\n", -+ __func__, V4L2_TYPE_IS_OUTPUT(q->type) ? "i/p" : "o/p", -+ ret); -+ -+ while (atomic_read(&port->buffers_with_vpu)) { -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Waiting for buffers to be returned - %d outstanding\n", -+ __func__, atomic_read(&port->buffers_with_vpu)); -+ ret = wait_for_completion_timeout(&ctx->frame_cmplt, HZ); -+ if (ret <= 0) { -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Timeout waiting for buffers to be returned - %d outstanding\n", -+ __func__, -+ atomic_read(&port->buffers_with_vpu)); -+ break; -+ } -+ } -+ -+ /* -+ * Release the VCSM handle here as otherwise REQBUFS(0) aborts because -+ * someone is using the dmabuf before giving the driver a chance to do -+ * anything about it. -+ */ -+ for (i = 0; i < q->num_buffers; i++) { -+ vb2 = to_vb2_v4l2_buffer(q->bufs[i]); -+ m2m = container_of(vb2, struct v4l2_m2m_buffer, vb); -+ buf = container_of(m2m, struct m2m_mmal_buffer, m2m); -+ -+ mmal_vchi_buffer_cleanup(&buf->mmal); -+ if (buf->mmal.dma_buf) { -+ dma_buf_put(buf->mmal.dma_buf); -+ buf->mmal.dma_buf = NULL; -+ } -+ } -+ -+ /* If both ports disabled, then disable the component */ -+ if (!ctx->component->input[0].enabled && -+ !ctx->component->output[0].enabled) { -+ ret = vchiq_mmal_component_disable(dev->instance, -+ ctx->component); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling component, ret %d\n", -+ __func__, ret); -+ } -+ -+ if (V4L2_TYPE_IS_OUTPUT(q->type)) -+ mmal_vchi_buffer_cleanup(&q_data->eos_buffer.mmal); -+ -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: done\n", __func__); -+} -+ -+static const struct vb2_ops bcm2835_codec_qops = { -+ .queue_setup = bcm2835_codec_queue_setup, -+ .buf_init = bcm2835_codec_buf_init, -+ .buf_prepare = bcm2835_codec_buf_prepare, -+ .buf_queue = bcm2835_codec_buf_queue, -+ .buf_cleanup = bcm2835_codec_buffer_cleanup, -+ .start_streaming = bcm2835_codec_start_streaming, -+ .stop_streaming = bcm2835_codec_stop_streaming, -+ .wait_prepare = vb2_ops_wait_prepare, -+ .wait_finish = vb2_ops_wait_finish, -+}; -+ -+static int queue_init(void *priv, struct vb2_queue *src_vq, -+ struct vb2_queue *dst_vq) -+{ -+ struct bcm2835_codec_ctx *ctx = priv; -+ int ret; -+ -+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; -+ src_vq->io_modes = VB2_MMAP | VB2_DMABUF; -+ src_vq->drv_priv = ctx; -+ src_vq->buf_struct_size = sizeof(struct m2m_mmal_buffer); -+ src_vq->ops = &bcm2835_codec_qops; -+ src_vq->mem_ops = &vb2_dma_contig_memops; -+ src_vq->dev = &ctx->dev->pdev->dev; -+ src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; -+ src_vq->lock = &ctx->dev->dev_mutex; -+ -+ ret = vb2_queue_init(src_vq); -+ if (ret) -+ return ret; -+ -+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -+ dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; -+ dst_vq->drv_priv = ctx; -+ dst_vq->buf_struct_size = sizeof(struct m2m_mmal_buffer); -+ dst_vq->ops = &bcm2835_codec_qops; -+ dst_vq->mem_ops = &vb2_dma_contig_memops; -+ dst_vq->dev = &ctx->dev->pdev->dev; -+ dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; -+ dst_vq->lock = &ctx->dev->dev_mutex; -+ -+ return vb2_queue_init(dst_vq); -+} -+ -+/* -+ * File operations -+ */ -+static int bcm2835_codec_open(struct file *file) -+{ -+ struct bcm2835_codec_dev *dev = video_drvdata(file); -+ struct bcm2835_codec_ctx *ctx = NULL; -+ struct v4l2_ctrl_handler *hdl; -+ int rc = 0; -+ -+ v4l2_dbg(1, debug, &dev->v4l2_dev, "Creating instance for %s\n", -+ dev->decode ? "decode" : "encode"); -+ if (mutex_lock_interruptible(&dev->dev_mutex)) { -+ v4l2_err(&dev->v4l2_dev, "Mutex fail\n"); -+ return -ERESTARTSYS; -+ } -+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); -+ if (!ctx) { -+ rc = -ENOMEM; -+ goto open_unlock; -+ } -+ -+ ctx->q_data[V4L2_M2M_SRC].fmt = get_default_format(dev->decode, false); -+ ctx->q_data[V4L2_M2M_DST].fmt = get_default_format(dev->decode, true); -+ if (dev->decode) { -+ /* -+ * Input width and height are irrelevant as they will be defined -+ * by the bitstream not the format. Required by V4L2 though. -+ */ -+ ctx->q_data[V4L2_M2M_SRC].crop_width = DEFAULT_WIDTH; -+ ctx->q_data[V4L2_M2M_SRC].crop_height = DEFAULT_HEIGHT; -+ ctx->q_data[V4L2_M2M_SRC].height = DEFAULT_HEIGHT; -+ ctx->q_data[V4L2_M2M_SRC].bytesperline = 0; -+ ctx->q_data[V4L2_M2M_SRC].sizeimage = -+ DEF_COMP_BUF_SIZE_720P_OR_LESS; -+ -+ ctx->q_data[V4L2_M2M_DST].crop_width = DEFAULT_WIDTH; -+ ctx->q_data[V4L2_M2M_DST].crop_height = DEFAULT_HEIGHT; -+ ctx->q_data[V4L2_M2M_DST].height = DEFAULT_HEIGHT; -+ ctx->q_data[V4L2_M2M_DST].bytesperline = -+ get_bytesperline(DEFAULT_WIDTH, -+ ctx->q_data[V4L2_M2M_DST].fmt); -+ ctx->q_data[V4L2_M2M_DST].sizeimage = -+ get_sizeimage(ctx->q_data[V4L2_M2M_DST].bytesperline, -+ ctx->q_data[V4L2_M2M_DST].height, -+ ctx->q_data[V4L2_M2M_DST].fmt); -+ } else { -+ ctx->q_data[V4L2_M2M_SRC].crop_width = DEFAULT_WIDTH; -+ ctx->q_data[V4L2_M2M_SRC].crop_height = DEFAULT_HEIGHT; -+ ctx->q_data[V4L2_M2M_SRC].height = DEFAULT_HEIGHT; -+ ctx->q_data[V4L2_M2M_SRC].bytesperline = -+ get_bytesperline(DEFAULT_WIDTH, -+ ctx->q_data[V4L2_M2M_SRC].fmt); -+ ctx->q_data[V4L2_M2M_SRC].sizeimage = -+ get_sizeimage(ctx->q_data[V4L2_M2M_SRC].bytesperline, -+ ctx->q_data[V4L2_M2M_SRC].height, -+ ctx->q_data[V4L2_M2M_SRC].fmt); -+ -+ ctx->q_data[V4L2_M2M_DST].crop_width = DEFAULT_WIDTH; -+ ctx->q_data[V4L2_M2M_DST].crop_height = DEFAULT_HEIGHT; -+ ctx->q_data[V4L2_M2M_DST].bytesperline = 0; -+ ctx->q_data[V4L2_M2M_DST].height = DEFAULT_HEIGHT; -+ ctx->q_data[V4L2_M2M_DST].sizeimage = -+ DEF_COMP_BUF_SIZE_720P_OR_LESS; -+ } -+ -+ ctx->colorspace = V4L2_COLORSPACE_REC709; -+ ctx->bitrate = 10 * 1000 * 1000; -+ -+ /* Initialise V4L2 contexts */ -+ v4l2_fh_init(&ctx->fh, video_devdata(file)); -+ file->private_data = &ctx->fh; -+ ctx->dev = dev; -+ hdl = &ctx->hdl; -+ if (!dev->decode) { -+ /* Encode controls */ -+ v4l2_ctrl_handler_init(hdl, 6); -+ -+ v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, -+ V4L2_CID_MPEG_VIDEO_BITRATE_MODE, -+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0, -+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); -+ v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops, -+ V4L2_CID_MPEG_VIDEO_BITRATE, -+ 25 * 1000, 25 * 1000 * 1000, -+ 25 * 1000, 10 * 1000 * 1000); -+ v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops, -+ V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, -+ 0, 1, -+ 1, 0); -+ v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops, -+ V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, -+ 0, 0x7FFFFFFF, -+ 1, 60); -+ v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, -+ V4L2_CID_MPEG_VIDEO_H264_LEVEL, -+ V4L2_MPEG_VIDEO_H264_LEVEL_4_2, -+ ~(BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2)), -+ V4L2_MPEG_VIDEO_H264_LEVEL_4_0); -+ v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, -+ V4L2_CID_MPEG_VIDEO_H264_PROFILE, -+ V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, -+ ~(BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | -+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | -+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | -+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)), -+ V4L2_MPEG_VIDEO_H264_PROFILE_HIGH); -+ if (hdl->error) { -+ rc = hdl->error; -+ goto free_ctrl_handler; -+ } -+ ctx->fh.ctrl_handler = hdl; -+ v4l2_ctrl_handler_setup(hdl); -+ } -+ -+ ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init); -+ -+ if (IS_ERR(ctx->fh.m2m_ctx)) { -+ rc = PTR_ERR(ctx->fh.m2m_ctx); -+ -+ goto free_ctrl_handler; -+ } -+ -+ /* Set both queues as buffered as we have buffering in the VPU. That -+ * means that we will be scheduled whenever either an input or output -+ * buffer is available (otherwise one of each are required). -+ */ -+ v4l2_m2m_set_src_buffered(ctx->fh.m2m_ctx, true); -+ v4l2_m2m_set_dst_buffered(ctx->fh.m2m_ctx, true); -+ -+ v4l2_fh_add(&ctx->fh); -+ atomic_inc(&dev->num_inst); -+ -+ mutex_unlock(&dev->dev_mutex); -+ return 0; -+ -+free_ctrl_handler: -+ v4l2_ctrl_handler_free(hdl); -+ kfree(ctx); -+open_unlock: -+ mutex_unlock(&dev->dev_mutex); -+ return rc; -+} -+ -+static int bcm2835_codec_release(struct file *file) -+{ -+ struct bcm2835_codec_dev *dev = video_drvdata(file); -+ struct bcm2835_codec_ctx *ctx = file2ctx(file); -+ -+ v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: Releasing instance %p\n", -+ __func__, ctx); -+ -+ v4l2_fh_del(&ctx->fh); -+ v4l2_fh_exit(&ctx->fh); -+ v4l2_ctrl_handler_free(&ctx->hdl); -+ mutex_lock(&dev->dev_mutex); -+ v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); -+ -+ if (ctx->component) -+ vchiq_mmal_component_finalise(dev->instance, ctx->component); -+ -+ mutex_unlock(&dev->dev_mutex); -+ kfree(ctx); -+ -+ atomic_dec(&dev->num_inst); -+ -+ return 0; -+} -+ -+static const struct v4l2_file_operations bcm2835_codec_fops = { -+ .owner = THIS_MODULE, -+ .open = bcm2835_codec_open, -+ .release = bcm2835_codec_release, -+ .poll = v4l2_m2m_fop_poll, -+ .unlocked_ioctl = video_ioctl2, -+ .mmap = v4l2_m2m_fop_mmap, -+}; -+ -+static const struct video_device bcm2835_codec_videodev = { -+ .name = MEM2MEM_NAME, -+ .vfl_dir = VFL_DIR_M2M, -+ .fops = &bcm2835_codec_fops, -+ .ioctl_ops = &bcm2835_codec_ioctl_ops, -+ .minor = -1, -+ .release = video_device_release_empty, -+}; -+ -+static const struct v4l2_m2m_ops m2m_ops = { -+ .device_run = device_run, -+ .job_ready = job_ready, -+ .job_abort = job_abort, -+}; -+ -+static int bcm2835_codec_create(struct platform_device *pdev, -+ struct bcm2835_codec_dev **new_dev, -+ bool decode) -+{ -+ struct bcm2835_codec_dev *dev; -+ struct video_device *vfd; -+ struct vchiq_mmal_instance *instance = NULL; -+ int video_nr; -+ int ret; -+ -+ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); -+ if (!dev) -+ return -ENOMEM; -+ -+ dev->pdev = pdev; -+ -+ dev->decode = decode; -+ -+ ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); -+ if (ret) -+ return ret; -+ -+ atomic_set(&dev->num_inst, 0); -+ mutex_init(&dev->dev_mutex); -+ -+ dev->vfd = bcm2835_codec_videodev; -+ vfd = &dev->vfd; -+ vfd->lock = &dev->dev_mutex; -+ vfd->v4l2_dev = &dev->v4l2_dev; -+ -+ if (dev->decode) { -+ v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD); -+ v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); -+ video_nr = decode_video_nr; -+ } else { -+ v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD); -+ v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD); -+ video_nr = encode_video_nr; -+ } -+ -+ ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); -+ if (ret) { -+ v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); -+ goto unreg_dev; -+ } -+ -+ video_set_drvdata(vfd, dev); -+ snprintf(vfd->name, sizeof(vfd->name), "%s", -+ bcm2835_codec_videodev.name); -+ v4l2_info(&dev->v4l2_dev, "Device registered as /dev/video%d\n", -+ vfd->num); -+ -+ *new_dev = dev; -+ -+ dev->m2m_dev = v4l2_m2m_init(&m2m_ops); -+ if (IS_ERR(dev->m2m_dev)) { -+ v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n"); -+ ret = PTR_ERR(dev->m2m_dev); -+ goto err_m2m; -+ } -+ -+ ret = vchiq_mmal_init(&instance); -+ if (ret < 0) -+ goto err_m2m; -+ dev->instance = instance; -+ -+ v4l2_info(&dev->v4l2_dev, "Loaded V4L2 %s codec\n", -+ dev->decode ? "decode" : "encode"); -+ return 0; -+ -+err_m2m: -+ v4l2_m2m_release(dev->m2m_dev); -+ video_unregister_device(&dev->vfd); -+unreg_dev: -+ v4l2_device_unregister(&dev->v4l2_dev); -+ -+ return ret; -+} -+ -+static int bcm2835_codec_destroy(struct bcm2835_codec_dev *dev) -+{ -+ if (!dev) -+ return -ENODEV; -+ -+ v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME); -+ v4l2_m2m_release(dev->m2m_dev); -+ video_unregister_device(&dev->vfd); -+ v4l2_device_unregister(&dev->v4l2_dev); -+ -+ return 0; -+} -+ -+static int bcm2835_codec_probe(struct platform_device *pdev) -+{ -+ struct bcm2835_codec_driver *drv; -+ int ret = 0; -+ -+ drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); -+ if (!drv) -+ return -ENOMEM; -+ -+ ret = bcm2835_codec_create(pdev, &drv->encode, false); -+ if (ret) -+ goto out; -+ -+ ret = bcm2835_codec_create(pdev, &drv->decode, true); -+ if (ret) -+ goto out; -+ -+ platform_set_drvdata(pdev, drv); -+ -+ return 0; -+ -+out: -+ if (drv->encode) { -+ bcm2835_codec_destroy(drv->encode); -+ drv->encode = NULL; -+ } -+ return ret; -+} -+ -+static int bcm2835_codec_remove(struct platform_device *pdev) -+{ -+ struct bcm2835_codec_driver *drv = platform_get_drvdata(pdev); -+ -+ bcm2835_codec_destroy(drv->encode); -+ -+ bcm2835_codec_destroy(drv->decode); -+ -+ return 0; -+} -+ -+static struct platform_driver bcm2835_v4l2_codec_driver = { -+ .probe = bcm2835_codec_probe, -+ .remove = bcm2835_codec_remove, -+ .driver = { -+ .name = "bcm2835-codec", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+module_platform_driver(bcm2835_v4l2_codec_driver); -+ -+MODULE_DESCRIPTION("BCM2835 codec V4L2 driver"); -+MODULE_AUTHOR("Dave Stevenson, "); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION("0.0.1"); -+MODULE_ALIAS("platform:bcm2835-codec"); diff --git a/target/linux/brcm2708/patches-4.19/950-0280-config-Add-bcm2835-codec-to-Pi-defconfigs.patch b/target/linux/brcm2708/patches-4.19/950-0280-config-Add-bcm2835-codec-to-Pi-defconfigs.patch new file mode 100644 index 0000000000..f664a70247 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0280-config-Add-bcm2835-codec-to-Pi-defconfigs.patch @@ -0,0 +1,33 @@ +From 1e3afe8e33c7ea7d2d64298d7800291766e17a15 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 30 Oct 2018 12:23:26 +0000 +Subject: [PATCH 280/725] config: Add bcm2835-codec to Pi defconfigs. + +Adds the V4L2 M2M codec driver to the config. + +Signed-off-by: Dave Stevenson +--- + 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 +@@ -1210,6 +1210,7 @@ CONFIG_FB_TFT_FBTFT_DEVICE=m + CONFIG_BCM2835_VCHIQ=y + CONFIG_SND_BCM2835=m + CONFIG_VIDEO_BCM2835=m ++CONFIG_VIDEO_CODEC_BCM2835=m + CONFIG_MAILBOX=y + CONFIG_BCM2835_MBOX=y + # CONFIG_IOMMU_SUPPORT is not set +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -1203,6 +1203,7 @@ CONFIG_FB_TFT_FBTFT_DEVICE=m + CONFIG_BCM2835_VCHIQ=y + CONFIG_SND_BCM2835=m + CONFIG_VIDEO_BCM2835=m ++CONFIG_VIDEO_CODEC_BCM2835=m + CONFIG_MAILBOX=y + CONFIG_BCM2835_MBOX=y + # CONFIG_IOMMU_SUPPORT is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0280-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch b/target/linux/brcm2708/patches-4.19/950-0280-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch deleted file mode 100644 index abfd828176..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0280-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 7dc3f0727d394ae8eaef363808b7525e9f760310 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 26 Oct 2018 15:14:16 +0100 -Subject: [PATCH 280/703] staging: vchiq_arm: Register bcm2835-codec as a - platform driver - -Following the same pattern as bcm2835-camera and bcm2835-audio, -register the V4L2 codec driver as a platform driver - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -171,6 +171,7 @@ static struct device *vchiq_dev; - static DEFINE_SPINLOCK(msg_queue_spinlock); - static struct platform_device *bcm2835_camera; - static struct platform_device *bcm2835_audio; -+static struct platform_device *bcm2835_codec; - - static const char *const ioctl_names[] = { - "CONNECT", -@@ -3660,6 +3661,9 @@ static int vchiq_probe(struct platform_d - bcm2835_audio = vchiq_register_child(pdev, "bcm2835_audio"); - if (IS_ERR(bcm2835_audio)) - bcm2835_audio = NULL; -+ bcm2835_codec = vchiq_register_child(pdev, "bcm2835-codec"); -+ if (IS_ERR(bcm2835_codec)) -+ bcm2835_codec = NULL; - - return 0; - diff --git a/target/linux/brcm2708/patches-4.19/950-0281-staging-bcm2835-camera-Fix-stride-on-RGB3-BGR3-forma.patch b/target/linux/brcm2708/patches-4.19/950-0281-staging-bcm2835-camera-Fix-stride-on-RGB3-BGR3-forma.patch new file mode 100644 index 0000000000..b8c3f2789d --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0281-staging-bcm2835-camera-Fix-stride-on-RGB3-BGR3-forma.patch @@ -0,0 +1,53 @@ +From f82bc2707af229ea9b55c5b9ec7b489aad928232 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 30 Nov 2018 16:00:54 +0000 +Subject: [PATCH 281/725] staging: bcm2835-camera: Fix stride on RGB3/BGR3 + formats + +RGB3/BGR3 end up being 3 bytes per pixel, which meant that +the alignment code ended up trying to align using bitmasking +with a mask of 96. +That doesn't work, so switch to an arithmetic alignment for +those formats. + +Signed-off-by: Dave Stevenson +--- + .../bcm2835-camera/bcm2835-camera.c | 26 ++++++++++++++----- + 1 file changed, 20 insertions(+), 6 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c ++++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +@@ -1008,13 +1008,27 @@ static int vidioc_try_fmt_vid_cap(struct + 1, 0); + f->fmt.pix.bytesperline = f->fmt.pix.width * mfmt->ybbp; + if (!mfmt->remove_padding) { +- int align_mask = ((32 * mfmt->depth) >> 3) - 1; +- /* GPU isn't removing padding, so stride is aligned to 32 */ +- f->fmt.pix.bytesperline = +- (f->fmt.pix.bytesperline + align_mask) & ~align_mask; ++ if (mfmt->depth == 24) { ++ /* ++ * 24bpp is a pain as we can't use simple masking. ++ * Min stride is width aligned to 16, times 24bpp. ++ */ ++ f->fmt.pix.bytesperline = ++ ((f->fmt.pix.width + 15) & ~15) * 3; ++ } else { ++ /* ++ * GPU isn't removing padding, so stride is aligned to ++ * 32 ++ */ ++ int align_mask = ((32 * mfmt->depth) >> 3) - 1; ++ ++ f->fmt.pix.bytesperline = ++ (f->fmt.pix.bytesperline + align_mask) & ++ ~align_mask; ++ } + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, +- "Not removing padding, so bytes/line = %d, (align_mask %d)\n", +- f->fmt.pix.bytesperline, align_mask); ++ "Not removing padding, so bytes/line = %d\n", ++ f->fmt.pix.bytesperline); + } + + /* Image buffer has to be padded to allow for alignment, even though diff --git a/target/linux/brcm2708/patches-4.19/950-0281-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch b/target/linux/brcm2708/patches-4.19/950-0281-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch deleted file mode 100644 index 7c4a096ce9..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0281-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch +++ /dev/null @@ -1,34 +0,0 @@ -From e0f22704bdcaa4b0033e65ce00f585e8b07b26af Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 26 Oct 2018 15:19:40 +0100 -Subject: [PATCH 281/703] staging: vchiq_arm: Register vcsm-cma as a platform - driver - -Following the same pattern as bcm2835-camera and bcm2835-audio, -register the vcsm-cma driver as a platform driver - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -172,6 +172,7 @@ static DEFINE_SPINLOCK(msg_queue_spinloc - static struct platform_device *bcm2835_camera; - static struct platform_device *bcm2835_audio; - static struct platform_device *bcm2835_codec; -+static struct platform_device *vcsm_cma; - - static const char *const ioctl_names[] = { - "CONNECT", -@@ -3655,6 +3656,9 @@ static int vchiq_probe(struct platform_d - VCHIQ_VERSION, VCHIQ_VERSION_MIN, - MAJOR(vchiq_devid), MINOR(vchiq_devid)); - -+ vcsm_cma = vchiq_register_child(pdev, "vcsm-cma"); -+ if (IS_ERR(vcsm_cma)) -+ vcsm_cma = NULL; - bcm2835_camera = vchiq_register_child(pdev, "bcm2835-camera"); - if (IS_ERR(bcm2835_camera)) - bcm2835_camera = NULL; diff --git a/target/linux/brcm2708/patches-4.19/950-0282-ARM-bcm2835_defconfig-Enable-bcm2835-codec.patch b/target/linux/brcm2708/patches-4.19/950-0282-ARM-bcm2835_defconfig-Enable-bcm2835-codec.patch deleted file mode 100644 index 1bdba512ea..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0282-ARM-bcm2835_defconfig-Enable-bcm2835-codec.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 940f1ba9a06ccff70f10459803efe140baa7896d Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 29 Oct 2018 17:49:04 +0000 -Subject: [PATCH 282/703] ARM: bcm2835_defconfig: Enable bcm2835-codec - -Enables the V4L2 M2M codec driver as a module. - -Signed-off-by: Dave Stevenson ---- - arch/arm/configs/bcm2835_defconfig | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -132,6 +132,7 @@ CONFIG_DMA_BCM2835=y - CONFIG_STAGING=y - CONFIG_SND_BCM2835=m - CONFIG_VIDEO_BCM2835=m -+CONFIG_VIDEO_CODEC_BCM2835=m - CONFIG_MAILBOX=y - CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0282-media-vb2-Allow-reqbufs-0-with-in-use-MMAP-buffers.patch b/target/linux/brcm2708/patches-4.19/950-0282-media-vb2-Allow-reqbufs-0-with-in-use-MMAP-buffers.patch new file mode 100644 index 0000000000..de40adf6f3 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0282-media-vb2-Allow-reqbufs-0-with-in-use-MMAP-buffers.patch @@ -0,0 +1,76 @@ +From b326f198daeac021ba83802b5e4502f8b22c1604 Mon Sep 17 00:00:00 2001 +From: John Sheu +Date: Thu, 15 Oct 2015 18:05:25 +0900 +Subject: [PATCH 282/725] media: vb2: Allow reqbufs(0) with "in use" MMAP + buffers + +Videobuf2 presently does not allow VIDIOC_REQBUFS to destroy outstanding +buffers if the queue is of type V4L2_MEMORY_MMAP, and if the buffers are +considered "in use". This is different behavior than for other memory +types and prevents us from deallocating buffers in following two cases: + +1) There are outstanding mmap()ed views on the buffer. However even if + we put the buffer in reqbufs(0), there will be remaining references, + due to vma .open/close() adjusting vb2 buffer refcount appropriately. + This means that the buffer will be in fact freed only when the last + mmap()ed view is unmapped. + +2) Buffer has been exported as a DMABUF. Refcount of the vb2 buffer + is managed properly by VB2 DMABUF ops, i.e. incremented on DMABUF + get and decremented on DMABUF release. This means that the buffer + will be alive until all importers release it. + +Considering both cases above, there does not seem to be any need to +prevent reqbufs(0) operation, because buffer lifetime is already +properly managed by both mmap() and DMABUF code paths. Let's remove it +and allow userspace freeing the queue (and potentially allocating a new +one) even though old buffers might be still in processing. + +Signed-off-by: John Sheu +Reviewed-by: Pawel Osciak +Reviewed-by: Tomasz Figa +Signed-off-by: Tomasz Figa +--- + .../media/common/videobuf2/videobuf2-core.c | 23 ------------------- + 1 file changed, 23 deletions(-) + +--- a/drivers/media/common/videobuf2/videobuf2-core.c ++++ b/drivers/media/common/videobuf2/videobuf2-core.c +@@ -554,20 +554,6 @@ bool vb2_buffer_in_use(struct vb2_queue + } + EXPORT_SYMBOL(vb2_buffer_in_use); + +-/* +- * __buffers_in_use() - return true if any buffers on the queue are in use and +- * the queue cannot be freed (by the means of REQBUFS(0)) call +- */ +-static bool __buffers_in_use(struct vb2_queue *q) +-{ +- unsigned int buffer; +- for (buffer = 0; buffer < q->num_buffers; ++buffer) { +- if (vb2_buffer_in_use(q, q->bufs[buffer])) +- return true; +- } +- return false; +-} +- + void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb) + { + call_void_bufop(q, fill_user_buffer, q->bufs[index], pb); +@@ -679,16 +665,7 @@ int vb2_core_reqbufs(struct vb2_queue *q + + if (*count == 0 || q->num_buffers != 0 || + (q->memory != VB2_MEMORY_UNKNOWN && q->memory != memory)) { +- /* +- * We already have buffers allocated, so first check if they +- * are not in use and can be freed. +- */ + mutex_lock(&q->mmap_lock); +- if (q->memory == VB2_MEMORY_MMAP && __buffers_in_use(q)) { +- mutex_unlock(&q->mmap_lock); +- dprintk(1, "memory in use, cannot free\n"); +- return -EBUSY; +- } + + /* + * Call queue_cancel to clean up any buffers in the PREPARED or diff --git a/target/linux/brcm2708/patches-4.19/950-0283-config-Add-bcm2835-codec-to-Pi-defconfigs.patch b/target/linux/brcm2708/patches-4.19/950-0283-config-Add-bcm2835-codec-to-Pi-defconfigs.patch deleted file mode 100644 index 3551a7051d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0283-config-Add-bcm2835-codec-to-Pi-defconfigs.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 7047db2bf3ea962ccd4b3e197b1a812aab491a79 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 30 Oct 2018 12:23:26 +0000 -Subject: [PATCH 283/703] config: Add bcm2835-codec to Pi defconfigs. - -Adds the V4L2 M2M codec driver to the config. - -Signed-off-by: Dave Stevenson ---- - 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 -@@ -1210,6 +1210,7 @@ CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_BCM2835_VCHIQ=y - CONFIG_SND_BCM2835=m - CONFIG_VIDEO_BCM2835=m -+CONFIG_VIDEO_CODEC_BCM2835=m - CONFIG_MAILBOX=y - CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1203,6 +1203,7 @@ CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_BCM2835_VCHIQ=y - CONFIG_SND_BCM2835=m - CONFIG_VIDEO_BCM2835=m -+CONFIG_VIDEO_CODEC_BCM2835=m - CONFIG_MAILBOX=y - CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0283-tpm-Make-SECURITYFS-a-weak-dependency.patch b/target/linux/brcm2708/patches-4.19/950-0283-tpm-Make-SECURITYFS-a-weak-dependency.patch new file mode 100644 index 0000000000..f7179a05be --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0283-tpm-Make-SECURITYFS-a-weak-dependency.patch @@ -0,0 +1,35 @@ +From 710a31a64daa6929cf1940a7664609be39f442bc Mon Sep 17 00:00:00 2001 +From: Peter Huewe +Date: Mon, 3 Sep 2018 21:51:51 +0200 +Subject: [PATCH 283/725] tpm: Make SECURITYFS a weak dependency + +commit 2f7d8dbb11287cbe9da6380ca14ed5d38c9ed91f upstream. + +While having SECURITYFS enabled for the tpm subsystem is beneficial in +most cases, it is not strictly necessary to have it enabled at all. +Especially on platforms without any boot firmware integration of the TPM +(e.g. raspberry pi) it does not add any value for the tpm subsystem, +as there is no eventlog present. + +By turning it from 'select' to 'imply' it still gets selected per +default, but enables users who want to save some kb of ram by turning +SECURITYFS off. + +Signed-off-by: Peter Huewe +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +--- + drivers/char/tpm/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/char/tpm/Kconfig ++++ b/drivers/char/tpm/Kconfig +@@ -5,7 +5,7 @@ + menuconfig TCG_TPM + tristate "TPM Hardware Support" + depends on HAS_IOMEM +- select SECURITYFS ++ imply SECURITYFS + select CRYPTO + select CRYPTO_HASH_INFO + ---help--- diff --git a/target/linux/brcm2708/patches-4.19/950-0284-Enable-TPM-TIS-SPI-support-for-TPM1.2-and-TPM2.0-chi.patch b/target/linux/brcm2708/patches-4.19/950-0284-Enable-TPM-TIS-SPI-support-for-TPM1.2-and-TPM2.0-chi.patch new file mode 100644 index 0000000000..98f1011c55 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0284-Enable-TPM-TIS-SPI-support-for-TPM1.2-and-TPM2.0-chi.patch @@ -0,0 +1,104 @@ +From 63015baea6a1b3c2cb4c84d18efdbb43ff838028 Mon Sep 17 00:00:00 2001 +From: Peter Huewe +Date: Thu, 14 Jun 2018 22:42:18 +0200 +Subject: [PATCH 284/725] Enable TPM TIS SPI support for TPM1.2 and TPM2.0 + chips + +This patch enables the support for SPI TPMs which follow the TCG TIS +FIFO/PTP specification like the SLB9670. +In order to decrease ram usage the weak dependency on CONFIG_SECURITFS +is explictly set to 'n'. + +Signed-off-by: Peter Huewe +--- + arch/arm/configs/bcm2709_defconfig | 5 +++-- + arch/arm/configs/bcmrpi_defconfig | 5 +++-- + arch/arm64/configs/bcmrpi3_defconfig | 3 +++ + 3 files changed, 9 insertions(+), 4 deletions(-) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -350,7 +350,6 @@ CONFIG_NET_ACT_SKBEDIT=m + CONFIG_NET_ACT_CSUM=m + CONFIG_BATMAN_ADV=m + CONFIG_OPENVSWITCH=m +-CONFIG_NET_L3_MASTER_DEV=y + CONFIG_NET_PKTGEN=m + CONFIG_HAMRADIO=y + CONFIG_AX25=m +@@ -610,6 +609,8 @@ CONFIG_SERIAL_DEV_BUS=m + CONFIG_TTY_PRINTK=y + CONFIG_HW_RANDOM=y + CONFIG_RAW_DRIVER=y ++CONFIG_TCG_TPM=m ++CONFIG_TCG_TIS_SPI=m + CONFIG_I2C=y + CONFIG_I2C_CHARDEV=m + CONFIG_I2C_MUX=m +@@ -1343,12 +1344,12 @@ CONFIG_NLS_ISO8859_15=m + CONFIG_NLS_KOI8_R=m + CONFIG_NLS_KOI8_U=m + CONFIG_DLM=m ++# CONFIG_SECURITYFS is not set + CONFIG_CRYPTO_USER=m + CONFIG_CRYPTO_CBC=y + CONFIG_CRYPTO_CTS=m + CONFIG_CRYPTO_XTS=m + CONFIG_CRYPTO_XCBC=m +-CONFIG_CRYPTO_SHA512=m + CONFIG_CRYPTO_TGR192=m + CONFIG_CRYPTO_WP512=m + CONFIG_CRYPTO_CAST5=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -344,7 +344,6 @@ CONFIG_NET_ACT_SKBEDIT=m + CONFIG_NET_ACT_CSUM=m + CONFIG_BATMAN_ADV=m + CONFIG_OPENVSWITCH=m +-CONFIG_NET_L3_MASTER_DEV=y + CONFIG_NET_PKTGEN=m + CONFIG_HAMRADIO=y + CONFIG_AX25=m +@@ -604,6 +603,8 @@ CONFIG_SERIAL_DEV_BUS=m + CONFIG_TTY_PRINTK=y + CONFIG_HW_RANDOM=y + CONFIG_RAW_DRIVER=y ++CONFIG_TCG_TPM=m ++CONFIG_TCG_TIS_SPI=m + CONFIG_I2C=y + CONFIG_I2C_CHARDEV=m + CONFIG_I2C_MUX=m +@@ -1336,13 +1337,13 @@ CONFIG_NLS_ISO8859_15=m + CONFIG_NLS_KOI8_R=m + CONFIG_NLS_KOI8_U=m + CONFIG_DLM=m ++# CONFIG_SECURITYFS is not set + CONFIG_CRYPTO_USER=m + CONFIG_CRYPTO_CRYPTD=m + CONFIG_CRYPTO_CBC=y + CONFIG_CRYPTO_CTS=m + CONFIG_CRYPTO_XTS=m + CONFIG_CRYPTO_XCBC=m +-CONFIG_CRYPTO_SHA512=m + CONFIG_CRYPTO_TGR192=m + CONFIG_CRYPTO_WP512=m + CONFIG_CRYPTO_CAST5=m +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -589,6 +589,8 @@ CONFIG_SERIAL_DEV_BUS=m + CONFIG_TTY_PRINTK=y + CONFIG_HW_RANDOM=y + CONFIG_RAW_DRIVER=y ++CONFIG_TCG_TPM=m ++CONFIG_TCG_TIS_SPI=m + CONFIG_I2C=y + CONFIG_I2C_CHARDEV=m + CONFIG_I2C_BCM2708=m +@@ -1187,6 +1189,7 @@ CONFIG_NLS_ISO8859_15=m + CONFIG_NLS_KOI8_R=m + CONFIG_NLS_KOI8_U=m + CONFIG_DLM=m ++# CONFIG_SECURITYFS is not set + CONFIG_CRYPTO_USER=m + CONFIG_CRYPTO_CBC=y + CONFIG_CRYPTO_CTS=m diff --git a/target/linux/brcm2708/patches-4.19/950-0284-staging-bcm2835-camera-Fix-stride-on-RGB3-BGR3-forma.patch b/target/linux/brcm2708/patches-4.19/950-0284-staging-bcm2835-camera-Fix-stride-on-RGB3-BGR3-forma.patch deleted file mode 100644 index 600f1b220b..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0284-staging-bcm2835-camera-Fix-stride-on-RGB3-BGR3-forma.patch +++ /dev/null @@ -1,53 +0,0 @@ -From a81fd46f130118ac4e18588eec81a630623145f6 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 30 Nov 2018 16:00:54 +0000 -Subject: [PATCH 284/703] staging: bcm2835-camera: Fix stride on RGB3/BGR3 - formats - -RGB3/BGR3 end up being 3 bytes per pixel, which meant that -the alignment code ended up trying to align using bitmasking -with a mask of 96. -That doesn't work, so switch to an arithmetic alignment for -those formats. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-camera/bcm2835-camera.c | 26 ++++++++++++++----- - 1 file changed, 20 insertions(+), 6 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c -+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c -@@ -1008,13 +1008,27 @@ static int vidioc_try_fmt_vid_cap(struct - 1, 0); - f->fmt.pix.bytesperline = f->fmt.pix.width * mfmt->ybbp; - if (!mfmt->remove_padding) { -- int align_mask = ((32 * mfmt->depth) >> 3) - 1; -- /* GPU isn't removing padding, so stride is aligned to 32 */ -- f->fmt.pix.bytesperline = -- (f->fmt.pix.bytesperline + align_mask) & ~align_mask; -+ if (mfmt->depth == 24) { -+ /* -+ * 24bpp is a pain as we can't use simple masking. -+ * Min stride is width aligned to 16, times 24bpp. -+ */ -+ f->fmt.pix.bytesperline = -+ ((f->fmt.pix.width + 15) & ~15) * 3; -+ } else { -+ /* -+ * GPU isn't removing padding, so stride is aligned to -+ * 32 -+ */ -+ int align_mask = ((32 * mfmt->depth) >> 3) - 1; -+ -+ f->fmt.pix.bytesperline = -+ (f->fmt.pix.bytesperline + align_mask) & -+ ~align_mask; -+ } - v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, -- "Not removing padding, so bytes/line = %d, (align_mask %d)\n", -- f->fmt.pix.bytesperline, align_mask); -+ "Not removing padding, so bytes/line = %d\n", -+ f->fmt.pix.bytesperline); - } - - /* Image buffer has to be padded to allow for alignment, even though diff --git a/target/linux/brcm2708/patches-4.19/950-0285-Add-overlay-for-SLB9760-Iridium-LetsTrust-TPM.patch b/target/linux/brcm2708/patches-4.19/950-0285-Add-overlay-for-SLB9760-Iridium-LetsTrust-TPM.patch new file mode 100644 index 0000000000..238993068e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0285-Add-overlay-for-SLB9760-Iridium-LetsTrust-TPM.patch @@ -0,0 +1,92 @@ +From d3bff43fb2a1a1ba28c7770daa28565cfc2abd5e Mon Sep 17 00:00:00 2001 +From: Peter Huewe +Date: Thu, 14 Jun 2018 22:51:24 +0200 +Subject: [PATCH 285/725] Add overlay for SLB9760 Iridium /LetsTrust TPM + +Device Tree overlay for the Infineon SLB9670 Trusted Platform Module add-on +boards, which can be used as a secure key storage and hwrng. +available as "Iridium SLB9670" by Infineon and "LetsTrust TPM" by +pi3g. + +Signed-off-by: Peter Huewe +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 8 ++++ + .../boot/dts/overlays/tpm-slb9670-overlay.dts | 44 +++++++++++++++++++ + 3 files changed, 53 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/tpm-slb9670-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -137,6 +137,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + tc358743.dtbo \ + tc358743-audio.dtbo \ + tinylcd35.dtbo \ ++ tpm-slb9670.dtbo \ + uart0.dtbo \ + uart1.dtbo \ + upstream.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -2012,6 +2012,14 @@ Params: speed Display + dtoverlay=tinylcd35,touch,touchgpio=3 + + ++Name: tpm-slb9670 ++Info: Enables support for Infineon SLB9670 Trusted Platform Module add-on ++ boards, which can be used as a secure key storage and hwrng, ++ available as "Iridium SLB9670" by Infineon and "LetsTrust TPM" by pi3g. ++Load: dtoverlay=tpm-slb9670 ++Params: ++ ++ + Name: uart0 + Info: Change the pin usage of uart0 + Load: dtoverlay=uart0,= +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/tpm-slb9670-overlay.dts +@@ -0,0 +1,44 @@ ++/* ++ * Device Tree overlay for the Infineon SLB9670 Trusted Platform Module add-on ++ * boards, which can be used as a secure key storage and hwrng. ++ * available as "Iridium SLB9670" by Infineon and "LetsTrust TPM" by pi3g. ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ slb9670: slb9670@1 { ++ compatible = "infineon,slb9670"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <32000000>; ++ status = "okay"; ++ }; ++ ++ }; ++ }; ++}; diff --git a/target/linux/brcm2708/patches-4.19/950-0285-media-vb2-Allow-reqbufs-0-with-in-use-MMAP-buffers.patch b/target/linux/brcm2708/patches-4.19/950-0285-media-vb2-Allow-reqbufs-0-with-in-use-MMAP-buffers.patch deleted file mode 100644 index 33c3242c92..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0285-media-vb2-Allow-reqbufs-0-with-in-use-MMAP-buffers.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 0f4f3fca8bb1e8283d5342d63e6758f6ac16d68d Mon Sep 17 00:00:00 2001 -From: John Sheu -Date: Thu, 15 Oct 2015 18:05:25 +0900 -Subject: [PATCH 285/703] media: vb2: Allow reqbufs(0) with "in use" MMAP - buffers - -Videobuf2 presently does not allow VIDIOC_REQBUFS to destroy outstanding -buffers if the queue is of type V4L2_MEMORY_MMAP, and if the buffers are -considered "in use". This is different behavior than for other memory -types and prevents us from deallocating buffers in following two cases: - -1) There are outstanding mmap()ed views on the buffer. However even if - we put the buffer in reqbufs(0), there will be remaining references, - due to vma .open/close() adjusting vb2 buffer refcount appropriately. - This means that the buffer will be in fact freed only when the last - mmap()ed view is unmapped. - -2) Buffer has been exported as a DMABUF. Refcount of the vb2 buffer - is managed properly by VB2 DMABUF ops, i.e. incremented on DMABUF - get and decremented on DMABUF release. This means that the buffer - will be alive until all importers release it. - -Considering both cases above, there does not seem to be any need to -prevent reqbufs(0) operation, because buffer lifetime is already -properly managed by both mmap() and DMABUF code paths. Let's remove it -and allow userspace freeing the queue (and potentially allocating a new -one) even though old buffers might be still in processing. - -Signed-off-by: John Sheu -Reviewed-by: Pawel Osciak -Reviewed-by: Tomasz Figa -Signed-off-by: Tomasz Figa ---- - .../media/common/videobuf2/videobuf2-core.c | 23 ------------------- - 1 file changed, 23 deletions(-) - ---- a/drivers/media/common/videobuf2/videobuf2-core.c -+++ b/drivers/media/common/videobuf2/videobuf2-core.c -@@ -554,20 +554,6 @@ bool vb2_buffer_in_use(struct vb2_queue - } - EXPORT_SYMBOL(vb2_buffer_in_use); - --/* -- * __buffers_in_use() - return true if any buffers on the queue are in use and -- * the queue cannot be freed (by the means of REQBUFS(0)) call -- */ --static bool __buffers_in_use(struct vb2_queue *q) --{ -- unsigned int buffer; -- for (buffer = 0; buffer < q->num_buffers; ++buffer) { -- if (vb2_buffer_in_use(q, q->bufs[buffer])) -- return true; -- } -- return false; --} -- - void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb) - { - call_void_bufop(q, fill_user_buffer, q->bufs[index], pb); -@@ -679,16 +665,7 @@ int vb2_core_reqbufs(struct vb2_queue *q - - if (*count == 0 || q->num_buffers != 0 || - (q->memory != VB2_MEMORY_UNKNOWN && q->memory != memory)) { -- /* -- * We already have buffers allocated, so first check if they -- * are not in use and can be freed. -- */ - mutex_lock(&q->mmap_lock); -- if (q->memory == VB2_MEMORY_MMAP && __buffers_in_use(q)) { -- mutex_unlock(&q->mmap_lock); -- dprintk(1, "memory in use, cannot free\n"); -- return -EBUSY; -- } - - /* - * Call queue_cancel to clean up any buffers in the PREPARED or diff --git a/target/linux/brcm2708/patches-4.19/950-0286-Revert-staging-vchiq_arm-Register-a-platform-device-.patch b/target/linux/brcm2708/patches-4.19/950-0286-Revert-staging-vchiq_arm-Register-a-platform-device-.patch new file mode 100644 index 0000000000..52548e3fec --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0286-Revert-staging-vchiq_arm-Register-a-platform-device-.patch @@ -0,0 +1,48 @@ +From d77f611dd04cab8310455d93106c503cde89175e Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 4 Dec 2018 19:40:12 +0000 +Subject: [PATCH 286/725] Revert "staging: vchiq_arm: Register a platform + device for the audio driver" + +This reverts commit ab59590ed562b89db51fe46cee5db96b9bc5abd8. + +Issues have been observed in LibreElec as this was unconditionally +loading the audio driver instead of having the DT parameter to +enable it. + +Includes a partial revert of 2147700eb7a1b9e55e0684f0749114ce35d61571 +which fixed up the error handling. + +Signed-off-by: Dave Stevenson +--- + .../staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 5 ----- + 1 file changed, 5 deletions(-) + +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +@@ -170,7 +170,6 @@ static struct class *vchiq_class; + static struct device *vchiq_dev; + static DEFINE_SPINLOCK(msg_queue_spinlock); + static struct platform_device *bcm2835_camera; +-static struct platform_device *bcm2835_audio; + static struct platform_device *bcm2835_codec; + static struct platform_device *vcsm_cma; + +@@ -3662,9 +3661,6 @@ static int vchiq_probe(struct platform_d + bcm2835_camera = vchiq_register_child(pdev, "bcm2835-camera"); + if (IS_ERR(bcm2835_camera)) + bcm2835_camera = NULL; +- bcm2835_audio = vchiq_register_child(pdev, "bcm2835_audio"); +- if (IS_ERR(bcm2835_audio)) +- bcm2835_audio = NULL; + bcm2835_codec = vchiq_register_child(pdev, "bcm2835-codec"); + if (IS_ERR(bcm2835_codec)) + bcm2835_codec = NULL; +@@ -3685,7 +3681,6 @@ failed_platform_init: + static int vchiq_remove(struct platform_device *pdev) + { + platform_device_unregister(bcm2835_codec); +- platform_device_unregister(bcm2835_audio); + platform_device_unregister(bcm2835_camera); + platform_device_unregister(vcsm_cma); + vchiq_debugfs_deinit(); diff --git a/target/linux/brcm2708/patches-4.19/950-0286-tpm-Make-SECURITYFS-a-weak-dependency.patch b/target/linux/brcm2708/patches-4.19/950-0286-tpm-Make-SECURITYFS-a-weak-dependency.patch deleted file mode 100644 index fa1f2b4ee6..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0286-tpm-Make-SECURITYFS-a-weak-dependency.patch +++ /dev/null @@ -1,35 +0,0 @@ -From bcff673c2438f78cb41ab282ce969e4151e00f69 Mon Sep 17 00:00:00 2001 -From: Peter Huewe -Date: Mon, 3 Sep 2018 21:51:51 +0200 -Subject: [PATCH 286/703] tpm: Make SECURITYFS a weak dependency - -commit 2f7d8dbb11287cbe9da6380ca14ed5d38c9ed91f upstream. - -While having SECURITYFS enabled for the tpm subsystem is beneficial in -most cases, it is not strictly necessary to have it enabled at all. -Especially on platforms without any boot firmware integration of the TPM -(e.g. raspberry pi) it does not add any value for the tpm subsystem, -as there is no eventlog present. - -By turning it from 'select' to 'imply' it still gets selected per -default, but enables users who want to save some kb of ram by turning -SECURITYFS off. - -Signed-off-by: Peter Huewe -Reviewed-by: Jarkko Sakkinen -Signed-off-by: Jarkko Sakkinen ---- - drivers/char/tpm/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/char/tpm/Kconfig -+++ b/drivers/char/tpm/Kconfig -@@ -5,7 +5,7 @@ - menuconfig TCG_TPM - tristate "TPM Hardware Support" - depends on HAS_IOMEM -- select SECURITYFS -+ imply SECURITYFS - select CRYPTO - select CRYPTO_HASH_INFO - ---help--- diff --git a/target/linux/brcm2708/patches-4.19/950-0287-Enable-TPM-TIS-SPI-support-for-TPM1.2-and-TPM2.0-chi.patch b/target/linux/brcm2708/patches-4.19/950-0287-Enable-TPM-TIS-SPI-support-for-TPM1.2-and-TPM2.0-chi.patch deleted file mode 100644 index 37481a0af5..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0287-Enable-TPM-TIS-SPI-support-for-TPM1.2-and-TPM2.0-chi.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 6fd45140dfb490a231a71994d92d0f0f86703b56 Mon Sep 17 00:00:00 2001 -From: Peter Huewe -Date: Thu, 14 Jun 2018 22:42:18 +0200 -Subject: [PATCH 287/703] Enable TPM TIS SPI support for TPM1.2 and TPM2.0 - chips - -This patch enables the support for SPI TPMs which follow the TCG TIS -FIFO/PTP specification like the SLB9670. -In order to decrease ram usage the weak dependency on CONFIG_SECURITFS -is explictly set to 'n'. - -Signed-off-by: Peter Huewe ---- - arch/arm/configs/bcm2709_defconfig | 5 +++-- - arch/arm/configs/bcmrpi_defconfig | 5 +++-- - arch/arm64/configs/bcmrpi3_defconfig | 3 +++ - 3 files changed, 9 insertions(+), 4 deletions(-) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -350,7 +350,6 @@ CONFIG_NET_ACT_SKBEDIT=m - CONFIG_NET_ACT_CSUM=m - CONFIG_BATMAN_ADV=m - CONFIG_OPENVSWITCH=m --CONFIG_NET_L3_MASTER_DEV=y - CONFIG_NET_PKTGEN=m - CONFIG_HAMRADIO=y - CONFIG_AX25=m -@@ -610,6 +609,8 @@ CONFIG_SERIAL_DEV_BUS=m - CONFIG_TTY_PRINTK=y - CONFIG_HW_RANDOM=y - CONFIG_RAW_DRIVER=y -+CONFIG_TCG_TPM=m -+CONFIG_TCG_TIS_SPI=m - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m - CONFIG_I2C_MUX=m -@@ -1343,12 +1344,12 @@ CONFIG_NLS_ISO8859_15=m - CONFIG_NLS_KOI8_R=m - CONFIG_NLS_KOI8_U=m - CONFIG_DLM=m -+# CONFIG_SECURITYFS is not set - CONFIG_CRYPTO_USER=m - CONFIG_CRYPTO_CBC=y - CONFIG_CRYPTO_CTS=m - CONFIG_CRYPTO_XTS=m - CONFIG_CRYPTO_XCBC=m --CONFIG_CRYPTO_SHA512=m - CONFIG_CRYPTO_TGR192=m - CONFIG_CRYPTO_WP512=m - CONFIG_CRYPTO_CAST5=m ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -344,7 +344,6 @@ CONFIG_NET_ACT_SKBEDIT=m - CONFIG_NET_ACT_CSUM=m - CONFIG_BATMAN_ADV=m - CONFIG_OPENVSWITCH=m --CONFIG_NET_L3_MASTER_DEV=y - CONFIG_NET_PKTGEN=m - CONFIG_HAMRADIO=y - CONFIG_AX25=m -@@ -604,6 +603,8 @@ CONFIG_SERIAL_DEV_BUS=m - CONFIG_TTY_PRINTK=y - CONFIG_HW_RANDOM=y - CONFIG_RAW_DRIVER=y -+CONFIG_TCG_TPM=m -+CONFIG_TCG_TIS_SPI=m - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m - CONFIG_I2C_MUX=m -@@ -1336,13 +1337,13 @@ CONFIG_NLS_ISO8859_15=m - CONFIG_NLS_KOI8_R=m - CONFIG_NLS_KOI8_U=m - CONFIG_DLM=m -+# CONFIG_SECURITYFS is not set - CONFIG_CRYPTO_USER=m - CONFIG_CRYPTO_CRYPTD=m - CONFIG_CRYPTO_CBC=y - CONFIG_CRYPTO_CTS=m - CONFIG_CRYPTO_XTS=m - CONFIG_CRYPTO_XCBC=m --CONFIG_CRYPTO_SHA512=m - CONFIG_CRYPTO_TGR192=m - CONFIG_CRYPTO_WP512=m - CONFIG_CRYPTO_CAST5=m ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -589,6 +589,8 @@ CONFIG_SERIAL_DEV_BUS=m - CONFIG_TTY_PRINTK=y - CONFIG_HW_RANDOM=y - CONFIG_RAW_DRIVER=y -+CONFIG_TCG_TPM=m -+CONFIG_TCG_TIS_SPI=m - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m - CONFIG_I2C_BCM2708=m -@@ -1187,6 +1189,7 @@ CONFIG_NLS_ISO8859_15=m - CONFIG_NLS_KOI8_R=m - CONFIG_NLS_KOI8_U=m - CONFIG_DLM=m -+# CONFIG_SECURITYFS is not set - CONFIG_CRYPTO_USER=m - CONFIG_CRYPTO_CBC=y - CONFIG_CRYPTO_CTS=m diff --git a/target/linux/brcm2708/patches-4.19/950-0287-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch b/target/linux/brcm2708/patches-4.19/950-0287-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch new file mode 100644 index 0000000000..aa7a8d1429 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0287-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch @@ -0,0 +1,114 @@ +From 3005ff34fcaea926cfc0c062c44f875568828ca7 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 4 Dec 2018 20:41:19 +0000 +Subject: [PATCH 287/725] Revert "staging: bcm2835-audio: Drop DT dependency" + +This reverts commit 933bc853bb764e476b0b0f633588f46d20f1f76a. + +Signed-off-by: Dave Stevenson +--- + .../vc04_services/bcm2835-audio/bcm2835.c | 41 ++++++++++--------- + 1 file changed, 22 insertions(+), 19 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +@@ -4,17 +4,15 @@ + #include + + #include +-#include +-#include + #include + #include ++#include + + #include "bcm2835.h" + + static bool enable_hdmi; + static bool enable_headphones; + static bool enable_compat_alsa = true; +-static int num_channels = MAX_SUBSTREAMS; + + module_param(enable_hdmi, bool, 0444); + MODULE_PARM_DESC(enable_hdmi, "Enables HDMI virtual audio device"); +@@ -23,8 +21,6 @@ MODULE_PARM_DESC(enable_headphones, "Ena + module_param(enable_compat_alsa, bool, 0444); + MODULE_PARM_DESC(enable_compat_alsa, + "Enables ALSA compatibility virtual audio device"); +-module_param(num_channels, int, 0644); +-MODULE_PARM_DESC(num_channels, "Number of audio channels (default: 8)"); + + static void snd_devm_unregister_child(struct device *dev, void *res) + { +@@ -411,30 +407,31 @@ static int snd_add_child_devices(struct + return 0; + } + +-static int snd_bcm2835_alsa_probe(struct platform_device *pdev) ++static int snd_bcm2835_alsa_probe_dt(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; ++ u32 numchans; + int err; + +- if (num_channels <= 0 || num_channels > MAX_SUBSTREAMS) { +- num_channels = MAX_SUBSTREAMS; +- dev_warn(dev, "Illegal num_channels value, will use %u\n", +- num_channels); +- } +- +- dev->coherent_dma_mask = DMA_BIT_MASK(32); +- dev->dma_mask = &dev->coherent_dma_mask; +- err = of_dma_configure(dev, NULL, true); ++ err = of_property_read_u32(dev->of_node, "brcm,pwm-channels", ++ &numchans); + if (err) { +- dev_err(dev, "Unable to setup DMA: %d\n", err); ++ dev_err(dev, "Failed to get DT property 'brcm,pwm-channels'"); + return err; + } + ++ if (numchans == 0 || numchans > MAX_SUBSTREAMS) { ++ numchans = MAX_SUBSTREAMS; ++ dev_warn(dev, ++ "Illegal 'brcm,pwm-channels' value, will use %u\n", ++ numchans); ++ } ++ + err = bcm2835_devm_add_vchi_ctx(dev); + if (err) + return err; + +- err = snd_add_child_devices(dev, num_channels); ++ err = snd_add_child_devices(dev, numchans); + if (err) + return err; + +@@ -456,14 +453,21 @@ static int snd_bcm2835_alsa_resume(struc + + #endif + ++static const struct of_device_id snd_bcm2835_of_match_table[] = { ++ { .compatible = "brcm,bcm2835-audio",}, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); ++ + static struct platform_driver bcm2835_alsa0_driver = { +- .probe = snd_bcm2835_alsa_probe, ++ .probe = snd_bcm2835_alsa_probe_dt, + #ifdef CONFIG_PM + .suspend = snd_bcm2835_alsa_suspend, + .resume = snd_bcm2835_alsa_resume, + #endif + .driver = { + .name = "bcm2835_audio", ++ .of_match_table = snd_bcm2835_of_match_table, + }, + }; + module_platform_driver(bcm2835_alsa0_driver); +@@ -471,4 +475,3 @@ module_platform_driver(bcm2835_alsa0_dri + MODULE_AUTHOR("Dom Cobley"); + MODULE_DESCRIPTION("Alsa driver for BCM2835 chip"); + MODULE_LICENSE("GPL"); +-MODULE_ALIAS("platform:bcm2835_audio"); diff --git a/target/linux/brcm2708/patches-4.19/950-0288-ASoC-add-driver-for-3Dlab-Nano-soundcard-2758.patch b/target/linux/brcm2708/patches-4.19/950-0288-ASoC-add-driver-for-3Dlab-Nano-soundcard-2758.patch new file mode 100644 index 0000000000..77113179bf --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0288-ASoC-add-driver-for-3Dlab-Nano-soundcard-2758.patch @@ -0,0 +1,505 @@ +From d3a8ba2147f62a30eba236976ce9ff6291ed9636 Mon Sep 17 00:00:00 2001 +From: dev-3Dlab <45081440+dev-3Dlab@users.noreply.github.com> +Date: Wed, 5 Dec 2018 10:59:11 +0100 +Subject: [PATCH 288/725] ASoC: add driver for 3Dlab Nano soundcard (#2758) + +Signed-off-by: GT +--- + .../overlays/3dlab-nano-player-overlay.dts | 32 ++ + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 6 + + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + sound/soc/bcm/3dlab-nano-player.c | 370 ++++++++++++++++++ + sound/soc/bcm/Kconfig | 6 + + sound/soc/bcm/Makefile | 2 + + 8 files changed, 419 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/3dlab-nano-player-overlay.dts + create mode 100644 sound/soc/bcm/3dlab-nano-player.c + +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/3dlab-nano-player-overlay.dts +@@ -0,0 +1,32 @@ ++// Definitions for 3Dlab Nano Player ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ nano-player@41 { ++ compatible = "3dlab,nano-player"; ++ reg = <0x41>; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; ++ ++// EOF +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -1,6 +1,7 @@ + # Overlays for the Raspberry Pi platform + + dtbo-$(CONFIG_ARCH_BCM2835) += \ ++ 3dlab-nano-player.dtbo \ + adau1977-adc.dtbo \ + adau7002-simple.dtbo \ + ads1015.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -199,6 +199,12 @@ Params: + and the other i2c baudrate parameters. + + ++Name: 3dlab-nano-player ++Info: Configures the 3Dlab Nano Player ++Load: dtoverlay=3dlab-nano-player ++Params: ++ ++ + Name: adau1977-adc + Info: Overlay for activation of ADAU1977 ADC codec over I2C for control + and I2S for data. +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -902,6 +902,7 @@ CONFIG_SND_USB_6FIRE=m + CONFIG_SND_USB_HIFACE=m + CONFIG_SND_SOC=m + CONFIG_SND_BCM2835_SOC_I2S=m ++CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER=m + CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -895,6 +895,7 @@ CONFIG_SND_USB_6FIRE=m + CONFIG_SND_USB_HIFACE=m + CONFIG_SND_SOC=m + CONFIG_SND_BCM2835_SOC_I2S=m ++CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER=m + CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m +--- /dev/null ++++ b/sound/soc/bcm/3dlab-nano-player.c +@@ -0,0 +1,370 @@ ++/* ++ * 3Dlab Nano Player ALSA SoC Audio driver. ++ * ++ * Copyright (C) 2018 3Dlab. ++ * ++ * Author: GT ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++ ++#define NANO_ID 0x00 ++#define NANO_VER 0x01 ++#define NANO_CFG 0x02 ++#define NANO_STATUS 0x03 ++#define NANO_SPI_ADDR 0x04 ++#define NANO_SPI_DATA 0x05 ++ ++#define NANO_ID_VAL 0x3D ++#define NANO_CFG_OFF 0x00 ++#define NANO_CFG_MULT1 0 ++#define NANO_CFG_MULT2 1 ++#define NANO_CFG_MULT4 2 ++#define NANO_CFG_MULT8 3 ++#define NANO_CFG_MULT16 4 ++#define NANO_CFG_CLK22 0 ++#define NANO_CFG_CLK24 BIT(3) ++#define NANO_CFG_DSD BIT(4) ++#define NANO_CFG_ENA BIT(5) ++#define NANO_CFG_BLINK BIT(6) ++#define NANO_STATUS_P1 BIT(0) ++#define NANO_STATUS_P2 BIT(1) ++#define NANO_STATUS_FLG BIT(2) ++#define NANO_STATUS_CLK BIT(3) ++#define NANO_SPI_READ 0 ++#define NANO_SPI_WRITE BIT(5) ++ ++#define NANO_DAC_CTRL1 0x00 ++#define NANO_DAC_CTRL2 0x01 ++#define NANO_DAC_CTRL3 0x02 ++#define NANO_DAC_LATT 0x03 ++#define NANO_DAC_RATT 0x04 ++ ++#define NANO_CTRL2_VAL 0x22 ++ ++static int nano_player_spi_write(struct regmap *map, ++ unsigned int reg, unsigned int val) ++{ ++ /* indirect register access */ ++ regmap_write(map, NANO_SPI_DATA, val); ++ regmap_write(map, NANO_SPI_ADDR, reg | NANO_SPI_WRITE); ++ return 0; ++} ++ ++static int nano_player_ctrl_info(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ /* describe control element */ ++ if (strstr(kcontrol->id.name, "Volume")) { ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 100; ++ } else { ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 1; ++ } ++ ++ return 0; ++} ++ ++static int nano_player_ctrl_put(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ /* program control value to hardware */ ++ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); ++ struct regmap *regmap = snd_soc_card_get_drvdata(card); ++ ++ if (strstr(kcontrol->id.name, "Volume")) { ++ unsigned int vol = ucontrol->value.integer.value[0]; ++ unsigned int att = 255 - (2 * (100 - vol)); ++ ++ nano_player_spi_write(regmap, NANO_DAC_LATT, att); ++ nano_player_spi_write(regmap, NANO_DAC_RATT, att); ++ kcontrol->private_value = vol; ++ } else { ++ unsigned int mute = ucontrol->value.integer.value[0]; ++ unsigned int reg = NANO_CTRL2_VAL | mute; ++ ++ nano_player_spi_write(regmap, NANO_DAC_CTRL2, reg); ++ kcontrol->private_value = mute; ++ } ++ return 0; ++} ++ ++static int nano_player_ctrl_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ /* return last programmed value */ ++ ucontrol->value.integer.value[0] = kcontrol->private_value; ++ return 0; ++} ++ ++#define SOC_NANO_PLAYER_CTRL(xname) \ ++{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ ++ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ ++ .info = nano_player_ctrl_info, \ ++ .put = nano_player_ctrl_put, \ ++ .get = nano_player_ctrl_get } ++ ++static const struct snd_kcontrol_new nano_player_controls[] = { ++ SOC_NANO_PLAYER_CTRL("Master Playback Volume"), ++ SOC_NANO_PLAYER_CTRL("Master Playback Switch"), ++}; ++ ++static const unsigned int nano_player_rates[] = { ++ 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, ++ 705600, 768000 /* only possible with fast clocks */ ++}; ++ ++static struct snd_pcm_hw_constraint_list nano_player_constraint_rates = { ++ .list = nano_player_rates, ++ .count = ARRAY_SIZE(nano_player_rates), ++}; ++ ++static int nano_player_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ struct snd_soc_card *card = rtd->card; ++ struct regmap *regmap = snd_soc_card_get_drvdata(card); ++ struct snd_soc_pcm_stream *cpu = &rtd->cpu_dai->driver->playback; ++ struct snd_soc_pcm_stream *codec = &rtd->codec_dai->driver->playback; ++ unsigned int sample_bits = 32; ++ unsigned int val; ++ ++ /* configure cpu dai */ ++ cpu->formats |= SNDRV_PCM_FMTBIT_DSD_U32_LE; ++ cpu->rate_max = 768000; ++ ++ /* configure dummy codec dai */ ++ codec->rate_min = 44100; ++ codec->rates = SNDRV_PCM_RATE_KNOT; ++ codec->formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_DSD_U32_LE; ++ ++ /* configure max supported rate */ ++ regmap_read(regmap, NANO_STATUS, &val); ++ if (val & NANO_STATUS_CLK) { ++ dev_notice(card->dev, "Board with fast clocks installed\n"); ++ codec->rate_max = 768000; ++ } else { ++ dev_notice(card->dev, "Board with normal clocks installed\n"); ++ codec->rate_max = 384000; ++ } ++ ++ /* frame length enforced by hardware */ ++ return snd_soc_dai_set_bclk_ratio(rtd->cpu_dai, sample_bits * 2); ++} ++ ++static int nano_player_startup(struct snd_pcm_substream *substream) ++{ ++ return snd_pcm_hw_constraint_list(substream->runtime, 0, ++ SNDRV_PCM_HW_PARAM_RATE, ++ &nano_player_constraint_rates); ++} ++ ++static int nano_player_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_card *card = rtd->card; ++ struct regmap *regmap = snd_soc_card_get_drvdata(card); ++ unsigned int config = NANO_CFG_ENA; ++ struct snd_mask *fmt; ++ ++ /* configure PCM or DSD */ ++ fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); ++ if (snd_mask_test(fmt, SNDRV_PCM_FORMAT_DSD_U32_LE)) { ++ /* embed DSD in PCM data */ ++ snd_mask_none(fmt); ++ snd_mask_set(fmt, SNDRV_PCM_FORMAT_S32_LE); ++ /* enable DSD mode */ ++ config |= NANO_CFG_DSD; ++ } ++ ++ /* configure clocks */ ++ switch (params_rate(params)) { ++ case 44100: ++ config |= NANO_CFG_MULT1 | NANO_CFG_CLK22; ++ break; ++ case 88200: ++ config |= NANO_CFG_MULT2 | NANO_CFG_CLK22; ++ break; ++ case 176400: ++ config |= NANO_CFG_MULT4 | NANO_CFG_CLK22; ++ break; ++ case 352800: ++ config |= NANO_CFG_MULT8 | NANO_CFG_CLK22; ++ break; ++ case 705600: ++ config |= NANO_CFG_MULT16 | NANO_CFG_CLK22; ++ break; ++ case 48000: ++ config |= NANO_CFG_MULT1 | NANO_CFG_CLK24; ++ break; ++ case 96000: ++ config |= NANO_CFG_MULT2 | NANO_CFG_CLK24; ++ break; ++ case 192000: ++ config |= NANO_CFG_MULT4 | NANO_CFG_CLK24; ++ break; ++ case 384000: ++ config |= NANO_CFG_MULT8 | NANO_CFG_CLK24; ++ break; ++ case 768000: ++ config |= NANO_CFG_MULT16 | NANO_CFG_CLK24; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ dev_dbg(card->dev, "Send CFG register 0x%02X\n", config); ++ return regmap_write(regmap, NANO_CFG, config); ++} ++ ++static struct snd_soc_ops nano_player_ops = { ++ .startup = nano_player_startup, ++ .hw_params = nano_player_hw_params, ++}; ++ ++static struct snd_soc_dai_link nano_player_link = { ++ .name = "3Dlab Nano Player", ++ .stream_name = "3Dlab Nano Player HiFi", ++ .platform_name = "bcm2708-i2s.0", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_name = "snd-soc-dummy", ++ .codec_dai_name = "snd-soc-dummy-dai", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | ++ SND_SOC_DAIFMT_CONT | ++ SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBM_CFM, ++ .init = nano_player_init, ++ .ops = &nano_player_ops, ++}; ++ ++static const struct regmap_config nano_player_regmap = { ++ .reg_bits = 8, ++ .val_bits = 8, ++ .max_register = 128, ++ .cache_type = REGCACHE_RBTREE, ++}; ++ ++static int nano_player_card_probe(struct snd_soc_card *card) ++{ ++ struct regmap *regmap = snd_soc_card_get_drvdata(card); ++ unsigned int val; ++ ++ /* check hardware integrity */ ++ regmap_read(regmap, NANO_ID, &val); ++ if (val != NANO_ID_VAL) { ++ dev_err(card->dev, "Invalid ID register 0x%02X\n", val); ++ return -ENODEV; ++ } ++ ++ /* report version to the user */ ++ regmap_read(regmap, NANO_VER, &val); ++ dev_notice(card->dev, "Started 3Dlab Nano Player driver (v%d)\n", val); ++ ++ /* enable internal audio bus and blink status LED */ ++ return regmap_write(regmap, NANO_CFG, NANO_CFG_ENA | NANO_CFG_BLINK); ++} ++ ++static int nano_player_card_remove(struct snd_soc_card *card) ++{ ++ /* disable internal audio bus */ ++ struct regmap *regmap = snd_soc_card_get_drvdata(card); ++ ++ return regmap_write(regmap, NANO_CFG, NANO_CFG_OFF); ++} ++ ++static struct snd_soc_card nano_player_card = { ++ .name = "3Dlab_Nano_Player", ++ .owner = THIS_MODULE, ++ .dai_link = &nano_player_link, ++ .num_links = 1, ++ .controls = nano_player_controls, ++ .num_controls = ARRAY_SIZE(nano_player_controls), ++ .probe = nano_player_card_probe, ++ .remove = nano_player_card_remove, ++}; ++ ++static int nano_player_i2c_probe(struct i2c_client *i2c, ++ const struct i2c_device_id *id) ++{ ++ struct regmap *regmap; ++ int ret; ++ ++ regmap = devm_regmap_init_i2c(i2c, &nano_player_regmap); ++ if (IS_ERR(regmap)) { ++ ret = PTR_ERR(regmap); ++ dev_err(&i2c->dev, "Failed to init regmap %d\n", ret); ++ return ret; ++ } ++ ++ if (i2c->dev.of_node) { ++ struct snd_soc_dai_link *dai = &nano_player_link; ++ struct device_node *node; ++ ++ /* cpu handle configured by device tree */ ++ node = of_parse_phandle(i2c->dev.of_node, "i2s-controller", 0); ++ if (node) { ++ dai->platform_name = NULL; ++ dai->platform_of_node = node; ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = node; ++ } ++ } ++ ++ nano_player_card.dev = &i2c->dev; ++ snd_soc_card_set_drvdata(&nano_player_card, regmap); ++ ret = devm_snd_soc_register_card(&i2c->dev, &nano_player_card); ++ ++ if (ret && ret != -EPROBE_DEFER) ++ dev_err(&i2c->dev, "Failed to register card %d\n", ret); ++ ++ return ret; ++} ++ ++static const struct of_device_id nano_player_of_match[] = { ++ { .compatible = "3dlab,nano-player", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, nano_player_of_match); ++ ++static const struct i2c_device_id nano_player_i2c_id[] = { ++ { "nano-player", 0 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(i2c, nano_player_i2c_id); ++ ++static struct i2c_driver nano_player_i2c_driver = { ++ .probe = nano_player_i2c_probe, ++ .id_table = nano_player_i2c_id, ++ .driver = { ++ .name = "nano-player", ++ .owner = THIS_MODULE, ++ .of_match_table = nano_player_of_match, ++ }, ++}; ++ ++module_i2c_driver(nano_player_i2c_driver); ++ ++MODULE_DESCRIPTION("ASoC 3Dlab Nano Player driver"); ++MODULE_AUTHOR("GT "); ++MODULE_LICENSE("GPL v2"); ++ ++/* EOF */ +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -17,6 +17,12 @@ config SND_SOC_CYGNUS + + If you don't know what to do here, say N. + ++config SND_BCM2708_SOC_3DLAB_NANO_PLAYER ++ tristate "Support for 3Dlab Nano Player" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ help ++ Say Y or M if you want to add support for 3Dlab Nano Player. ++ + config SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD + tristate "Support for Google voiceHAT soundcard" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -12,6 +12,7 @@ obj-$(CONFIG_SND_SOC_CYGNUS) += snd-soc- + snd-soc-googlevoicehat-codec-objs := googlevoicehat-codec.o + + # BCM2708 Machine Support ++snd-soc-3dlab-nano-player-objs := 3dlab-nano-player.o + snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o + snd-soc-justboom-dac-objs := justboom-dac.o + snd-soc-rpi-cirrus-objs := rpi-cirrus.o +@@ -31,6 +32,7 @@ snd-soc-fe-pi-audio-objs := fe-pi-audio. + snd-soc-rpi-simple-soundcard-objs := rpi-simple-soundcard.o + snd-soc-rpi-wm8804-soundcard-objs := rpi-wm8804-soundcard.o + ++obj-$(CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER) += snd-soc-3dlab-nano-player.o + obj-$(CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD) += snd-soc-googlevoicehat-codec.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o + obj-$(CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC) += snd-soc-justboom-dac.o diff --git a/target/linux/brcm2708/patches-4.19/950-0288-Add-overlay-for-SLB9760-Iridium-LetsTrust-TPM.patch b/target/linux/brcm2708/patches-4.19/950-0288-Add-overlay-for-SLB9760-Iridium-LetsTrust-TPM.patch deleted file mode 100644 index de7903d86c..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0288-Add-overlay-for-SLB9760-Iridium-LetsTrust-TPM.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 0ca744a930b9aed72b2f291796140339eaf6ea33 Mon Sep 17 00:00:00 2001 -From: Peter Huewe -Date: Thu, 14 Jun 2018 22:51:24 +0200 -Subject: [PATCH 288/703] Add overlay for SLB9760 Iridium /LetsTrust TPM - -Device Tree overlay for the Infineon SLB9670 Trusted Platform Module add-on -boards, which can be used as a secure key storage and hwrng. -available as "Iridium SLB9670" by Infineon and "LetsTrust TPM" by -pi3g. - -Signed-off-by: Peter Huewe ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 8 ++++ - .../boot/dts/overlays/tpm-slb9670-overlay.dts | 44 +++++++++++++++++++ - 3 files changed, 53 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/tpm-slb9670-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -137,6 +137,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - tc358743.dtbo \ - tc358743-audio.dtbo \ - tinylcd35.dtbo \ -+ tpm-slb9670.dtbo \ - uart0.dtbo \ - uart1.dtbo \ - upstream.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -2012,6 +2012,14 @@ Params: speed Display - dtoverlay=tinylcd35,touch,touchgpio=3 - - -+Name: tpm-slb9670 -+Info: Enables support for Infineon SLB9670 Trusted Platform Module add-on -+ boards, which can be used as a secure key storage and hwrng, -+ available as "Iridium SLB9670" by Infineon and "LetsTrust TPM" by pi3g. -+Load: dtoverlay=tpm-slb9670 -+Params: -+ -+ - Name: uart0 - Info: Change the pin usage of uart0 - Load: dtoverlay=uart0,= ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/tpm-slb9670-overlay.dts -@@ -0,0 +1,44 @@ -+/* -+ * Device Tree overlay for the Infineon SLB9670 Trusted Platform Module add-on -+ * boards, which can be used as a secure key storage and hwrng. -+ * available as "Iridium SLB9670" by Infineon and "LetsTrust TPM" by pi3g. -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ slb9670: slb9670@1 { -+ compatible = "infineon,slb9670"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <32000000>; -+ status = "okay"; -+ }; -+ -+ }; -+ }; -+}; diff --git a/target/linux/brcm2708/patches-4.19/950-0289-Revert-staging-vchiq_arm-Register-a-platform-device-.patch b/target/linux/brcm2708/patches-4.19/950-0289-Revert-staging-vchiq_arm-Register-a-platform-device-.patch deleted file mode 100644 index d428773a1b..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0289-Revert-staging-vchiq_arm-Register-a-platform-device-.patch +++ /dev/null @@ -1,48 +0,0 @@ -From f70b874a07779f015befed503790417c6bc1cfd2 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 4 Dec 2018 19:40:12 +0000 -Subject: [PATCH 289/703] Revert "staging: vchiq_arm: Register a platform - device for the audio driver" - -This reverts commit ab59590ed562b89db51fe46cee5db96b9bc5abd8. - -Issues have been observed in LibreElec as this was unconditionally -loading the audio driver instead of having the DT parameter to -enable it. - -Includes a partial revert of 2147700eb7a1b9e55e0684f0749114ce35d61571 -which fixed up the error handling. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 5 ----- - 1 file changed, 5 deletions(-) - ---- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -170,7 +170,6 @@ static struct class *vchiq_class; - static struct device *vchiq_dev; - static DEFINE_SPINLOCK(msg_queue_spinlock); - static struct platform_device *bcm2835_camera; --static struct platform_device *bcm2835_audio; - static struct platform_device *bcm2835_codec; - static struct platform_device *vcsm_cma; - -@@ -3662,9 +3661,6 @@ static int vchiq_probe(struct platform_d - bcm2835_camera = vchiq_register_child(pdev, "bcm2835-camera"); - if (IS_ERR(bcm2835_camera)) - bcm2835_camera = NULL; -- bcm2835_audio = vchiq_register_child(pdev, "bcm2835_audio"); -- if (IS_ERR(bcm2835_audio)) -- bcm2835_audio = NULL; - bcm2835_codec = vchiq_register_child(pdev, "bcm2835-codec"); - if (IS_ERR(bcm2835_codec)) - bcm2835_codec = NULL; -@@ -3685,7 +3681,6 @@ failed_platform_init: - static int vchiq_remove(struct platform_device *pdev) - { - platform_device_unregister(bcm2835_codec); -- platform_device_unregister(bcm2835_audio); - platform_device_unregister(bcm2835_camera); - platform_device_unregister(vcsm_cma); - vchiq_debugfs_deinit(); diff --git a/target/linux/brcm2708/patches-4.19/950-0289-overlays-Update-README-with-removal-of-lirc-rpi.patch b/target/linux/brcm2708/patches-4.19/950-0289-overlays-Update-README-with-removal-of-lirc-rpi.patch new file mode 100644 index 0000000000..2ef67c8038 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0289-overlays-Update-README-with-removal-of-lirc-rpi.patch @@ -0,0 +1,91 @@ +From 2a7770becf1b2bf289836ea19dcc2f6744d7e413 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 5 Dec 2018 11:56:40 +0000 +Subject: [PATCH 289/725] overlays: Update README with removal of lirc-rpi + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/README | 57 ++++++++++++------------------- + 1 file changed, 21 insertions(+), 36 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -56,23 +56,29 @@ have its contents deleted (or commented + Using Overlays + ============== + +-Overlays are loaded using the "dtoverlay" directive. As an example, consider +-the popular lirc-rpi module, the Linux Infrared Remote Control driver. In the +-pre-DT world this would be loaded from /etc/modules, with an explicit +-"modprobe lirc-rpi" command, or programmatically by lircd. With DT enabled, +-this becomes a line in config.txt: +- +- dtoverlay=lirc-rpi +- +-This causes the file /boot/overlays/lirc-rpi.dtbo to be loaded. By +-default it will use GPIOs 17 (out) and 18 (in), but this can be modified using +-DT parameters: +- +- dtoverlay=lirc-rpi,gpio_out_pin=17,gpio_in_pin=13 +- +-Parameters always have default values, although in some cases (e.g. "w1-gpio") +-it is necessary to provided multiple overlays in order to get the desired +-behaviour. See the list of overlays below for a description of the parameters ++Overlays are loaded using the "dtoverlay" config.txt setting. As an example, ++consider I2C Real Time Clock drivers. In the pre-DT world these would be loaded ++by writing a magic string comprising a device identifier and an I2C address to ++a special file in /sys/class/i2c-adapter, having first loaded the driver for ++the I2C interface and the RTC device - something like this: ++ ++ modprobe i2c-bcm2835 ++ modprobe rtc-ds1307 ++ echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device ++ ++With DT enabled, this becomes a line in config.txt: ++ ++ dtoverlay=i2c-rtc,ds1307 ++ ++This causes the file /boot/overlays/i2c-rtc.dtbo to be loaded and a "node" ++describing the DS1307 I2C device to be added to the Device Tree for the Pi. By ++default it usees address 0x68, but this can be modified with an additional DT ++parameter: ++ ++ dtoverlay=i2c-rtc,ds1307,addr=0x68 ++ ++Parameters usually have default values, although certain parameters are ++mandatory. See the list of overlays below for a description of the parameters + and their defaults. + + The Overlay and Parameter Reference +@@ -1135,29 +1141,8 @@ Params: + + + Name: lirc-rpi +-Info: Configures lirc-rpi (Linux Infrared Remote Control for Raspberry Pi) +- Consult the module documentation for more details. +-Load: dtoverlay=lirc-rpi,= +-Params: gpio_out_pin GPIO for output (default "17") +- +- gpio_in_pin GPIO for input (default "18") +- +- gpio_in_pull Pull up/down/off on the input pin +- (default "down") +- +- sense Override the IR receive auto-detection logic: +- "0" = force active-high +- "1" = force active-low +- "-1" = use auto-detection +- (default "-1") +- +- softcarrier Turn the software carrier "on" or "off" +- (default "on") +- +- invert "on" = invert the output pin (default "off") +- +- debug "on" = enable additional debug messages +- (default "off") ++Info: This overlay has been deprecated and removed - see gpio-ir ++Load: + + + Name: ltc294x diff --git a/target/linux/brcm2708/patches-4.19/950-0290-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch b/target/linux/brcm2708/patches-4.19/950-0290-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch deleted file mode 100644 index b259f27e10..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0290-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 4a208b7269c8713ac3e9cb9348af76b2bb03e919 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 4 Dec 2018 20:41:19 +0000 -Subject: [PATCH 290/703] Revert "staging: bcm2835-audio: Drop DT dependency" - -This reverts commit 933bc853bb764e476b0b0f633588f46d20f1f76a. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/bcm2835-audio/bcm2835.c | 41 ++++++++++--------- - 1 file changed, 22 insertions(+), 19 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -4,17 +4,15 @@ - #include - - #include --#include --#include - #include - #include -+#include - - #include "bcm2835.h" - - static bool enable_hdmi; - static bool enable_headphones; - static bool enable_compat_alsa = true; --static int num_channels = MAX_SUBSTREAMS; - - module_param(enable_hdmi, bool, 0444); - MODULE_PARM_DESC(enable_hdmi, "Enables HDMI virtual audio device"); -@@ -23,8 +21,6 @@ MODULE_PARM_DESC(enable_headphones, "Ena - module_param(enable_compat_alsa, bool, 0444); - MODULE_PARM_DESC(enable_compat_alsa, - "Enables ALSA compatibility virtual audio device"); --module_param(num_channels, int, 0644); --MODULE_PARM_DESC(num_channels, "Number of audio channels (default: 8)"); - - static void snd_devm_unregister_child(struct device *dev, void *res) - { -@@ -411,30 +407,31 @@ static int snd_add_child_devices(struct - return 0; - } - --static int snd_bcm2835_alsa_probe(struct platform_device *pdev) -+static int snd_bcm2835_alsa_probe_dt(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -+ u32 numchans; - int err; - -- if (num_channels <= 0 || num_channels > MAX_SUBSTREAMS) { -- num_channels = MAX_SUBSTREAMS; -- dev_warn(dev, "Illegal num_channels value, will use %u\n", -- num_channels); -- } -- -- dev->coherent_dma_mask = DMA_BIT_MASK(32); -- dev->dma_mask = &dev->coherent_dma_mask; -- err = of_dma_configure(dev, NULL, true); -+ err = of_property_read_u32(dev->of_node, "brcm,pwm-channels", -+ &numchans); - if (err) { -- dev_err(dev, "Unable to setup DMA: %d\n", err); -+ dev_err(dev, "Failed to get DT property 'brcm,pwm-channels'"); - return err; - } - -+ if (numchans == 0 || numchans > MAX_SUBSTREAMS) { -+ numchans = MAX_SUBSTREAMS; -+ dev_warn(dev, -+ "Illegal 'brcm,pwm-channels' value, will use %u\n", -+ numchans); -+ } -+ - err = bcm2835_devm_add_vchi_ctx(dev); - if (err) - return err; - -- err = snd_add_child_devices(dev, num_channels); -+ err = snd_add_child_devices(dev, numchans); - if (err) - return err; - -@@ -456,14 +453,21 @@ static int snd_bcm2835_alsa_resume(struc - - #endif - -+static const struct of_device_id snd_bcm2835_of_match_table[] = { -+ { .compatible = "brcm,bcm2835-audio",}, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); -+ - static struct platform_driver bcm2835_alsa0_driver = { -- .probe = snd_bcm2835_alsa_probe, -+ .probe = snd_bcm2835_alsa_probe_dt, - #ifdef CONFIG_PM - .suspend = snd_bcm2835_alsa_suspend, - .resume = snd_bcm2835_alsa_resume, - #endif - .driver = { - .name = "bcm2835_audio", -+ .of_match_table = snd_bcm2835_of_match_table, - }, - }; - module_platform_driver(bcm2835_alsa0_driver); -@@ -471,4 +475,3 @@ module_platform_driver(bcm2835_alsa0_dri - MODULE_AUTHOR("Dom Cobley"); - MODULE_DESCRIPTION("Alsa driver for BCM2835 chip"); - MODULE_LICENSE("GPL"); --MODULE_ALIAS("platform:bcm2835_audio"); diff --git a/target/linux/brcm2708/patches-4.19/950-0290-staging-bcm2835-camera-Check-the-error-for-REPEAT_SE.patch b/target/linux/brcm2708/patches-4.19/950-0290-staging-bcm2835-camera-Check-the-error-for-REPEAT_SE.patch new file mode 100644 index 0000000000..6cd756ad0f --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0290-staging-bcm2835-camera-Check-the-error-for-REPEAT_SE.patch @@ -0,0 +1,31 @@ +From c38a34a4f9465df9bfeff355772555efa0cd574b Mon Sep 17 00:00:00 2001 +From: 6by9 <6by9@users.noreply.github.com> +Date: Tue, 11 Dec 2018 15:18:02 +0000 +Subject: [PATCH 290/725] staging: bcm2835-camera: Check the error for + REPEAT_SEQ_HEADER (#2782) + +When handling for V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER was added +the firmware would reject the setting if H264 hadn't already been +selected. This was fixed in the firmware at that point, but to +enable backwards compatibility the returned error was ignored. + +That was Dec 2013, so the chances of having a firmware that still +has that issue is so close to zero that the workaround can be +removed. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/bcm2835-camera/controls.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/bcm2835-camera/controls.c ++++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c +@@ -1100,7 +1100,7 @@ static const struct bm2835_mmal_v4l2_ctr + 0, 1, NULL, + MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER, + &ctrl_set_video_encode_param_output, +- true /* Errors ignored as requires latest firmware to work */ ++ false + }, + { + V4L2_CID_MPEG_VIDEO_H264_PROFILE, diff --git a/target/linux/brcm2708/patches-4.19/950-0291-ASoC-add-driver-for-3Dlab-Nano-soundcard-2758.patch b/target/linux/brcm2708/patches-4.19/950-0291-ASoC-add-driver-for-3Dlab-Nano-soundcard-2758.patch deleted file mode 100644 index bca2e13150..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0291-ASoC-add-driver-for-3Dlab-Nano-soundcard-2758.patch +++ /dev/null @@ -1,505 +0,0 @@ -From b459fc35cd584d7f1c02da9f83f9238caa742c97 Mon Sep 17 00:00:00 2001 -From: dev-3Dlab <45081440+dev-3Dlab@users.noreply.github.com> -Date: Wed, 5 Dec 2018 10:59:11 +0100 -Subject: [PATCH 291/703] ASoC: add driver for 3Dlab Nano soundcard (#2758) - -Signed-off-by: GT ---- - .../overlays/3dlab-nano-player-overlay.dts | 32 ++ - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 6 + - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - sound/soc/bcm/3dlab-nano-player.c | 370 ++++++++++++++++++ - sound/soc/bcm/Kconfig | 6 + - sound/soc/bcm/Makefile | 2 + - 8 files changed, 419 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/3dlab-nano-player-overlay.dts - create mode 100644 sound/soc/bcm/3dlab-nano-player.c - ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/3dlab-nano-player-overlay.dts -@@ -0,0 +1,32 @@ -+// Definitions for 3Dlab Nano Player -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2c>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ nano-player@41 { -+ compatible = "3dlab,nano-player"; -+ reg = <0x41>; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -+ -+// EOF ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -1,6 +1,7 @@ - # Overlays for the Raspberry Pi platform - - dtbo-$(CONFIG_ARCH_BCM2835) += \ -+ 3dlab-nano-player.dtbo \ - adau1977-adc.dtbo \ - adau7002-simple.dtbo \ - ads1015.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -199,6 +199,12 @@ Params: - and the other i2c baudrate parameters. - - -+Name: 3dlab-nano-player -+Info: Configures the 3Dlab Nano Player -+Load: dtoverlay=3dlab-nano-player -+Params: -+ -+ - Name: adau1977-adc - Info: Overlay for activation of ADAU1977 ADC codec over I2C for control - and I2S for data. ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -902,6 +902,7 @@ CONFIG_SND_USB_6FIRE=m - CONFIG_SND_USB_HIFACE=m - CONFIG_SND_SOC=m - CONFIG_SND_BCM2835_SOC_I2S=m -+CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER=m - CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -895,6 +895,7 @@ CONFIG_SND_USB_6FIRE=m - CONFIG_SND_USB_HIFACE=m - CONFIG_SND_SOC=m - CONFIG_SND_BCM2835_SOC_I2S=m -+CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER=m - CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m ---- /dev/null -+++ b/sound/soc/bcm/3dlab-nano-player.c -@@ -0,0 +1,370 @@ -+/* -+ * 3Dlab Nano Player ALSA SoC Audio driver. -+ * -+ * Copyright (C) 2018 3Dlab. -+ * -+ * Author: GT -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+ -+#define NANO_ID 0x00 -+#define NANO_VER 0x01 -+#define NANO_CFG 0x02 -+#define NANO_STATUS 0x03 -+#define NANO_SPI_ADDR 0x04 -+#define NANO_SPI_DATA 0x05 -+ -+#define NANO_ID_VAL 0x3D -+#define NANO_CFG_OFF 0x00 -+#define NANO_CFG_MULT1 0 -+#define NANO_CFG_MULT2 1 -+#define NANO_CFG_MULT4 2 -+#define NANO_CFG_MULT8 3 -+#define NANO_CFG_MULT16 4 -+#define NANO_CFG_CLK22 0 -+#define NANO_CFG_CLK24 BIT(3) -+#define NANO_CFG_DSD BIT(4) -+#define NANO_CFG_ENA BIT(5) -+#define NANO_CFG_BLINK BIT(6) -+#define NANO_STATUS_P1 BIT(0) -+#define NANO_STATUS_P2 BIT(1) -+#define NANO_STATUS_FLG BIT(2) -+#define NANO_STATUS_CLK BIT(3) -+#define NANO_SPI_READ 0 -+#define NANO_SPI_WRITE BIT(5) -+ -+#define NANO_DAC_CTRL1 0x00 -+#define NANO_DAC_CTRL2 0x01 -+#define NANO_DAC_CTRL3 0x02 -+#define NANO_DAC_LATT 0x03 -+#define NANO_DAC_RATT 0x04 -+ -+#define NANO_CTRL2_VAL 0x22 -+ -+static int nano_player_spi_write(struct regmap *map, -+ unsigned int reg, unsigned int val) -+{ -+ /* indirect register access */ -+ regmap_write(map, NANO_SPI_DATA, val); -+ regmap_write(map, NANO_SPI_ADDR, reg | NANO_SPI_WRITE); -+ return 0; -+} -+ -+static int nano_player_ctrl_info(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_info *uinfo) -+{ -+ /* describe control element */ -+ if (strstr(kcontrol->id.name, "Volume")) { -+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; -+ uinfo->count = 1; -+ uinfo->value.integer.min = 0; -+ uinfo->value.integer.max = 100; -+ } else { -+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; -+ uinfo->count = 1; -+ uinfo->value.integer.min = 0; -+ uinfo->value.integer.max = 1; -+ } -+ -+ return 0; -+} -+ -+static int nano_player_ctrl_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ /* program control value to hardware */ -+ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); -+ struct regmap *regmap = snd_soc_card_get_drvdata(card); -+ -+ if (strstr(kcontrol->id.name, "Volume")) { -+ unsigned int vol = ucontrol->value.integer.value[0]; -+ unsigned int att = 255 - (2 * (100 - vol)); -+ -+ nano_player_spi_write(regmap, NANO_DAC_LATT, att); -+ nano_player_spi_write(regmap, NANO_DAC_RATT, att); -+ kcontrol->private_value = vol; -+ } else { -+ unsigned int mute = ucontrol->value.integer.value[0]; -+ unsigned int reg = NANO_CTRL2_VAL | mute; -+ -+ nano_player_spi_write(regmap, NANO_DAC_CTRL2, reg); -+ kcontrol->private_value = mute; -+ } -+ return 0; -+} -+ -+static int nano_player_ctrl_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ /* return last programmed value */ -+ ucontrol->value.integer.value[0] = kcontrol->private_value; -+ return 0; -+} -+ -+#define SOC_NANO_PLAYER_CTRL(xname) \ -+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ -+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ -+ .info = nano_player_ctrl_info, \ -+ .put = nano_player_ctrl_put, \ -+ .get = nano_player_ctrl_get } -+ -+static const struct snd_kcontrol_new nano_player_controls[] = { -+ SOC_NANO_PLAYER_CTRL("Master Playback Volume"), -+ SOC_NANO_PLAYER_CTRL("Master Playback Switch"), -+}; -+ -+static const unsigned int nano_player_rates[] = { -+ 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, -+ 705600, 768000 /* only possible with fast clocks */ -+}; -+ -+static struct snd_pcm_hw_constraint_list nano_player_constraint_rates = { -+ .list = nano_player_rates, -+ .count = ARRAY_SIZE(nano_player_rates), -+}; -+ -+static int nano_player_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ struct snd_soc_card *card = rtd->card; -+ struct regmap *regmap = snd_soc_card_get_drvdata(card); -+ struct snd_soc_pcm_stream *cpu = &rtd->cpu_dai->driver->playback; -+ struct snd_soc_pcm_stream *codec = &rtd->codec_dai->driver->playback; -+ unsigned int sample_bits = 32; -+ unsigned int val; -+ -+ /* configure cpu dai */ -+ cpu->formats |= SNDRV_PCM_FMTBIT_DSD_U32_LE; -+ cpu->rate_max = 768000; -+ -+ /* configure dummy codec dai */ -+ codec->rate_min = 44100; -+ codec->rates = SNDRV_PCM_RATE_KNOT; -+ codec->formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_DSD_U32_LE; -+ -+ /* configure max supported rate */ -+ regmap_read(regmap, NANO_STATUS, &val); -+ if (val & NANO_STATUS_CLK) { -+ dev_notice(card->dev, "Board with fast clocks installed\n"); -+ codec->rate_max = 768000; -+ } else { -+ dev_notice(card->dev, "Board with normal clocks installed\n"); -+ codec->rate_max = 384000; -+ } -+ -+ /* frame length enforced by hardware */ -+ return snd_soc_dai_set_bclk_ratio(rtd->cpu_dai, sample_bits * 2); -+} -+ -+static int nano_player_startup(struct snd_pcm_substream *substream) -+{ -+ return snd_pcm_hw_constraint_list(substream->runtime, 0, -+ SNDRV_PCM_HW_PARAM_RATE, -+ &nano_player_constraint_rates); -+} -+ -+static int nano_player_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_card *card = rtd->card; -+ struct regmap *regmap = snd_soc_card_get_drvdata(card); -+ unsigned int config = NANO_CFG_ENA; -+ struct snd_mask *fmt; -+ -+ /* configure PCM or DSD */ -+ fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); -+ if (snd_mask_test(fmt, SNDRV_PCM_FORMAT_DSD_U32_LE)) { -+ /* embed DSD in PCM data */ -+ snd_mask_none(fmt); -+ snd_mask_set(fmt, SNDRV_PCM_FORMAT_S32_LE); -+ /* enable DSD mode */ -+ config |= NANO_CFG_DSD; -+ } -+ -+ /* configure clocks */ -+ switch (params_rate(params)) { -+ case 44100: -+ config |= NANO_CFG_MULT1 | NANO_CFG_CLK22; -+ break; -+ case 88200: -+ config |= NANO_CFG_MULT2 | NANO_CFG_CLK22; -+ break; -+ case 176400: -+ config |= NANO_CFG_MULT4 | NANO_CFG_CLK22; -+ break; -+ case 352800: -+ config |= NANO_CFG_MULT8 | NANO_CFG_CLK22; -+ break; -+ case 705600: -+ config |= NANO_CFG_MULT16 | NANO_CFG_CLK22; -+ break; -+ case 48000: -+ config |= NANO_CFG_MULT1 | NANO_CFG_CLK24; -+ break; -+ case 96000: -+ config |= NANO_CFG_MULT2 | NANO_CFG_CLK24; -+ break; -+ case 192000: -+ config |= NANO_CFG_MULT4 | NANO_CFG_CLK24; -+ break; -+ case 384000: -+ config |= NANO_CFG_MULT8 | NANO_CFG_CLK24; -+ break; -+ case 768000: -+ config |= NANO_CFG_MULT16 | NANO_CFG_CLK24; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ dev_dbg(card->dev, "Send CFG register 0x%02X\n", config); -+ return regmap_write(regmap, NANO_CFG, config); -+} -+ -+static struct snd_soc_ops nano_player_ops = { -+ .startup = nano_player_startup, -+ .hw_params = nano_player_hw_params, -+}; -+ -+static struct snd_soc_dai_link nano_player_link = { -+ .name = "3Dlab Nano Player", -+ .stream_name = "3Dlab Nano Player HiFi", -+ .platform_name = "bcm2708-i2s.0", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_name = "snd-soc-dummy", -+ .codec_dai_name = "snd-soc-dummy-dai", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | -+ SND_SOC_DAIFMT_CONT | -+ SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBM_CFM, -+ .init = nano_player_init, -+ .ops = &nano_player_ops, -+}; -+ -+static const struct regmap_config nano_player_regmap = { -+ .reg_bits = 8, -+ .val_bits = 8, -+ .max_register = 128, -+ .cache_type = REGCACHE_RBTREE, -+}; -+ -+static int nano_player_card_probe(struct snd_soc_card *card) -+{ -+ struct regmap *regmap = snd_soc_card_get_drvdata(card); -+ unsigned int val; -+ -+ /* check hardware integrity */ -+ regmap_read(regmap, NANO_ID, &val); -+ if (val != NANO_ID_VAL) { -+ dev_err(card->dev, "Invalid ID register 0x%02X\n", val); -+ return -ENODEV; -+ } -+ -+ /* report version to the user */ -+ regmap_read(regmap, NANO_VER, &val); -+ dev_notice(card->dev, "Started 3Dlab Nano Player driver (v%d)\n", val); -+ -+ /* enable internal audio bus and blink status LED */ -+ return regmap_write(regmap, NANO_CFG, NANO_CFG_ENA | NANO_CFG_BLINK); -+} -+ -+static int nano_player_card_remove(struct snd_soc_card *card) -+{ -+ /* disable internal audio bus */ -+ struct regmap *regmap = snd_soc_card_get_drvdata(card); -+ -+ return regmap_write(regmap, NANO_CFG, NANO_CFG_OFF); -+} -+ -+static struct snd_soc_card nano_player_card = { -+ .name = "3Dlab_Nano_Player", -+ .owner = THIS_MODULE, -+ .dai_link = &nano_player_link, -+ .num_links = 1, -+ .controls = nano_player_controls, -+ .num_controls = ARRAY_SIZE(nano_player_controls), -+ .probe = nano_player_card_probe, -+ .remove = nano_player_card_remove, -+}; -+ -+static int nano_player_i2c_probe(struct i2c_client *i2c, -+ const struct i2c_device_id *id) -+{ -+ struct regmap *regmap; -+ int ret; -+ -+ regmap = devm_regmap_init_i2c(i2c, &nano_player_regmap); -+ if (IS_ERR(regmap)) { -+ ret = PTR_ERR(regmap); -+ dev_err(&i2c->dev, "Failed to init regmap %d\n", ret); -+ return ret; -+ } -+ -+ if (i2c->dev.of_node) { -+ struct snd_soc_dai_link *dai = &nano_player_link; -+ struct device_node *node; -+ -+ /* cpu handle configured by device tree */ -+ node = of_parse_phandle(i2c->dev.of_node, "i2s-controller", 0); -+ if (node) { -+ dai->platform_name = NULL; -+ dai->platform_of_node = node; -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = node; -+ } -+ } -+ -+ nano_player_card.dev = &i2c->dev; -+ snd_soc_card_set_drvdata(&nano_player_card, regmap); -+ ret = devm_snd_soc_register_card(&i2c->dev, &nano_player_card); -+ -+ if (ret && ret != -EPROBE_DEFER) -+ dev_err(&i2c->dev, "Failed to register card %d\n", ret); -+ -+ return ret; -+} -+ -+static const struct of_device_id nano_player_of_match[] = { -+ { .compatible = "3dlab,nano-player", }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, nano_player_of_match); -+ -+static const struct i2c_device_id nano_player_i2c_id[] = { -+ { "nano-player", 0 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, nano_player_i2c_id); -+ -+static struct i2c_driver nano_player_i2c_driver = { -+ .probe = nano_player_i2c_probe, -+ .id_table = nano_player_i2c_id, -+ .driver = { -+ .name = "nano-player", -+ .owner = THIS_MODULE, -+ .of_match_table = nano_player_of_match, -+ }, -+}; -+ -+module_i2c_driver(nano_player_i2c_driver); -+ -+MODULE_DESCRIPTION("ASoC 3Dlab Nano Player driver"); -+MODULE_AUTHOR("GT "); -+MODULE_LICENSE("GPL v2"); -+ -+/* EOF */ ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -17,6 +17,12 @@ config SND_SOC_CYGNUS - - If you don't know what to do here, say N. - -+config SND_BCM2708_SOC_3DLAB_NANO_PLAYER -+ tristate "Support for 3Dlab Nano Player" -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S -+ help -+ Say Y or M if you want to add support for 3Dlab Nano Player. -+ - config SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD - tristate "Support for Google voiceHAT soundcard" - depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -12,6 +12,7 @@ obj-$(CONFIG_SND_SOC_CYGNUS) += snd-soc- - snd-soc-googlevoicehat-codec-objs := googlevoicehat-codec.o - - # BCM2708 Machine Support -+snd-soc-3dlab-nano-player-objs := 3dlab-nano-player.o - snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o - snd-soc-justboom-dac-objs := justboom-dac.o - snd-soc-rpi-cirrus-objs := rpi-cirrus.o -@@ -31,6 +32,7 @@ snd-soc-fe-pi-audio-objs := fe-pi-audio. - snd-soc-rpi-simple-soundcard-objs := rpi-simple-soundcard.o - snd-soc-rpi-wm8804-soundcard-objs := rpi-wm8804-soundcard.o - -+obj-$(CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER) += snd-soc-3dlab-nano-player.o - obj-$(CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD) += snd-soc-googlevoicehat-codec.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o - obj-$(CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC) += snd-soc-justboom-dac.o diff --git a/target/linux/brcm2708/patches-4.19/950-0291-gpio-ir-change-default-pull-configuration-to-up.patch b/target/linux/brcm2708/patches-4.19/950-0291-gpio-ir-change-default-pull-configuration-to-up.patch new file mode 100644 index 0000000000..08316b78d4 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0291-gpio-ir-change-default-pull-configuration-to-up.patch @@ -0,0 +1,47 @@ +From 92ac07c588df68c6cbc6c7965b679ba02d3c994b Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Wed, 9 Jan 2019 14:51:01 +0100 +Subject: [PATCH 291/725] gpio-ir: change default pull configuration to up + +IR receivers like the TSOP series from Vishay and compatible ones +have active-low open collector outputs with an internal pull up of +about 30k (according to the TSOP datasheets). + +Activating a pull-down resistor on the GPIO will make it work against +the pull-up in the IR receiver and brings the idle input voltage down +to about 1.9V (measured on a RPi3B+ with a TSOP4438). While that's +usually enough to make the RPi see a high signal it's certainly not +optimal and may even fail when using an IR receiver with a weaker pull-up. + +Switching the default GPIO pull to "up" results in an input voltage +level of about 3.3V and ensures that an idle state (high signal) will +be detected if no IR receiver is attached. + +Signed-off-by: Matthias Reichl +--- + arch/arm/boot/dts/overlays/README | 2 +- + arch/arm/boot/dts/overlays/gpio-ir-overlay.dts | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -611,7 +611,7 @@ Load: dtoverlay=gpio-ir,= + Params: gpio_pin Input pin number. Default is 18. + + gpio_pull Desired pull-up/down state (off, down, up) +- Default is "down". ++ Default is "up". + + rc-map-name Default rc keymap (can also be changed by + ir-keytable), defaults to "rc-rc6-mce" +--- a/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts ++++ b/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts +@@ -30,7 +30,7 @@ + gpio_ir_pins: gpio_ir_pins@12 { + brcm,pins = <18>; // pin 18 + brcm,function = <0>; // in +- brcm,pull = <1>; // down ++ brcm,pull = <2>; // up + }; + }; + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0292-firmware-raspberrypi-Report-the-fw-variant-during-pr.patch b/target/linux/brcm2708/patches-4.19/950-0292-firmware-raspberrypi-Report-the-fw-variant-during-pr.patch new file mode 100644 index 0000000000..ccb4979d98 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0292-firmware-raspberrypi-Report-the-fw-variant-during-pr.patch @@ -0,0 +1,79 @@ +From bf6b1c361f3e01a5d7ce6ac2c6cb29ece28bf41a Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 10 Jan 2019 17:58:06 +0000 +Subject: [PATCH 292/725] firmware: raspberrypi: Report the fw variant during + probe + +The driver already reported the firmware build date during probe. +The mailbox calls have been extended to also report the variant + 1 = standard start.elf + 2 = start_x.elf (includes camera stack) + 3 = start_db.elf (includes assert logging) + 4 = start_cd.elf (cutdown version for smallest memory footprint). +Log the variant during probe. + +Signed-off-by: Dave Stevenson +--- + drivers/firmware/raspberrypi.c | 32 +++++++++++++++++----- + include/soc/bcm2835/raspberrypi-firmware.h | 1 + + 2 files changed, 26 insertions(+), 7 deletions(-) + +--- a/drivers/firmware/raspberrypi.c ++++ b/drivers/firmware/raspberrypi.c +@@ -227,21 +227,39 @@ static const struct attribute_group rpi_ + static void + rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) + { ++ static const char * const variant_strs[] = { ++ "unknown", ++ "start", ++ "start_x", ++ "start_db", ++ "start_cd", ++ }; ++ const char *variant_str = "cmd unsupported"; + u32 packet; ++ u32 variant; ++ struct tm tm; + int ret = rpi_firmware_property(fw, + RPI_FIRMWARE_GET_FIRMWARE_REVISION, + &packet, sizeof(packet)); + +- if (ret == 0) { +- struct tm tm; ++ if (ret) ++ return; + +- time64_to_tm(packet, 0, &tm); ++ ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_FIRMWARE_VARIANT, ++ &variant, sizeof(variant)); + +- dev_info(fw->cl.dev, +- "Attached to firmware from %04ld-%02d-%02d %02d:%02d\n", +- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, +- tm.tm_hour, tm.tm_min); ++ if (!ret) { ++ if (variant >= ARRAY_SIZE(variant_strs)) ++ variant = 0; ++ variant_str = variant_strs[variant]; + } ++ ++ time64_to_tm(packet, 0, &tm); ++ ++ dev_info(fw->cl.dev, ++ "Attached to firmware from %04ld-%02d-%02d %02d:%02d, variant %s\n", ++ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, ++ tm.tm_min, variant_str); + } + + static void +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -41,6 +41,7 @@ struct rpi_firmware_property_tag_header + enum rpi_firmware_property_tag { + RPI_FIRMWARE_PROPERTY_END = 0, + RPI_FIRMWARE_GET_FIRMWARE_REVISION = 0x00000001, ++ RPI_FIRMWARE_GET_FIRMWARE_VARIANT = 0x00000002, + + RPI_FIRMWARE_SET_CURSOR_INFO = 0x00008010, + RPI_FIRMWARE_SET_CURSOR_STATE = 0x00008011, diff --git a/target/linux/brcm2708/patches-4.19/950-0292-overlays-Update-README-with-removal-of-lirc-rpi.patch b/target/linux/brcm2708/patches-4.19/950-0292-overlays-Update-README-with-removal-of-lirc-rpi.patch deleted file mode 100644 index 9adabcc8b8..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0292-overlays-Update-README-with-removal-of-lirc-rpi.patch +++ /dev/null @@ -1,91 +0,0 @@ -From a7544b1d73143b69134dd9ec665d0013775aca50 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 5 Dec 2018 11:56:40 +0000 -Subject: [PATCH 292/703] overlays: Update README with removal of lirc-rpi - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/README | 57 ++++++++++++------------------- - 1 file changed, 21 insertions(+), 36 deletions(-) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -56,23 +56,29 @@ have its contents deleted (or commented - Using Overlays - ============== - --Overlays are loaded using the "dtoverlay" directive. As an example, consider --the popular lirc-rpi module, the Linux Infrared Remote Control driver. In the --pre-DT world this would be loaded from /etc/modules, with an explicit --"modprobe lirc-rpi" command, or programmatically by lircd. With DT enabled, --this becomes a line in config.txt: -- -- dtoverlay=lirc-rpi -- --This causes the file /boot/overlays/lirc-rpi.dtbo to be loaded. By --default it will use GPIOs 17 (out) and 18 (in), but this can be modified using --DT parameters: -- -- dtoverlay=lirc-rpi,gpio_out_pin=17,gpio_in_pin=13 -- --Parameters always have default values, although in some cases (e.g. "w1-gpio") --it is necessary to provided multiple overlays in order to get the desired --behaviour. See the list of overlays below for a description of the parameters -+Overlays are loaded using the "dtoverlay" config.txt setting. As an example, -+consider I2C Real Time Clock drivers. In the pre-DT world these would be loaded -+by writing a magic string comprising a device identifier and an I2C address to -+a special file in /sys/class/i2c-adapter, having first loaded the driver for -+the I2C interface and the RTC device - something like this: -+ -+ modprobe i2c-bcm2835 -+ modprobe rtc-ds1307 -+ echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device -+ -+With DT enabled, this becomes a line in config.txt: -+ -+ dtoverlay=i2c-rtc,ds1307 -+ -+This causes the file /boot/overlays/i2c-rtc.dtbo to be loaded and a "node" -+describing the DS1307 I2C device to be added to the Device Tree for the Pi. By -+default it usees address 0x68, but this can be modified with an additional DT -+parameter: -+ -+ dtoverlay=i2c-rtc,ds1307,addr=0x68 -+ -+Parameters usually have default values, although certain parameters are -+mandatory. See the list of overlays below for a description of the parameters - and their defaults. - - The Overlay and Parameter Reference -@@ -1135,29 +1141,8 @@ Params: - - - Name: lirc-rpi --Info: Configures lirc-rpi (Linux Infrared Remote Control for Raspberry Pi) -- Consult the module documentation for more details. --Load: dtoverlay=lirc-rpi,= --Params: gpio_out_pin GPIO for output (default "17") -- -- gpio_in_pin GPIO for input (default "18") -- -- gpio_in_pull Pull up/down/off on the input pin -- (default "down") -- -- sense Override the IR receive auto-detection logic: -- "0" = force active-high -- "1" = force active-low -- "-1" = use auto-detection -- (default "-1") -- -- softcarrier Turn the software carrier "on" or "off" -- (default "on") -- -- invert "on" = invert the output pin (default "off") -- -- debug "on" = enable additional debug messages -- (default "off") -+Info: This overlay has been deprecated and removed - see gpio-ir -+Load: - - - Name: ltc294x diff --git a/target/linux/brcm2708/patches-4.19/950-0293-firmware-raspberrypi-Report-the-fw-git-hash-during-p.patch b/target/linux/brcm2708/patches-4.19/950-0293-firmware-raspberrypi-Report-the-fw-git-hash-during-p.patch new file mode 100644 index 0000000000..d73d293927 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0293-firmware-raspberrypi-Report-the-fw-git-hash-during-p.patch @@ -0,0 +1,58 @@ +From 6a9b19e48f8503ca3ac0c4ef29f34d6b6a96dfac Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 10 Jan 2019 18:48:54 +0000 +Subject: [PATCH 293/725] firmware: raspberrypi: Report the fw git hash during + probe + +The firmware can now report the git hash from which it was built +via the mailbox, so report it during probe. + +Signed-off-by: Dave Stevenson +--- + drivers/firmware/raspberrypi.c | 17 +++++++++++++++++ + include/soc/bcm2835/raspberrypi-firmware.h | 1 + + 2 files changed, 18 insertions(+) + +--- a/drivers/firmware/raspberrypi.c ++++ b/drivers/firmware/raspberrypi.c +@@ -263,6 +263,22 @@ rpi_firmware_print_firmware_revision(str + } + + static void ++rpi_firmware_print_firmware_hash(struct rpi_firmware *fw) ++{ ++ u32 hash[5]; ++ int ret = rpi_firmware_property(fw, ++ RPI_FIRMWARE_GET_FIRMWARE_HASH, ++ hash, sizeof(hash)); ++ ++ if (ret) ++ return; ++ ++ dev_info(fw->cl.dev, ++ "Firmware hash is %08x%08x%08x%08x%08x\n", ++ hash[0], hash[1], hash[2], hash[3], hash[4]); ++} ++ ++static void + rpi_register_hwmon_driver(struct device *dev, struct rpi_firmware *fw) + { + u32 packet; +@@ -308,6 +324,7 @@ static int rpi_firmware_probe(struct pla + g_pdev = pdev; + + rpi_firmware_print_firmware_revision(fw); ++ rpi_firmware_print_firmware_hash(fw); + rpi_register_hwmon_driver(dev, fw); + + return 0; +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -42,6 +42,7 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_PROPERTY_END = 0, + RPI_FIRMWARE_GET_FIRMWARE_REVISION = 0x00000001, + RPI_FIRMWARE_GET_FIRMWARE_VARIANT = 0x00000002, ++ RPI_FIRMWARE_GET_FIRMWARE_HASH = 0x00000003, + + RPI_FIRMWARE_SET_CURSOR_INFO = 0x00008010, + RPI_FIRMWARE_SET_CURSOR_STATE = 0x00008011, diff --git a/target/linux/brcm2708/patches-4.19/950-0293-staging-bcm2835-camera-Check-the-error-for-REPEAT_SE.patch b/target/linux/brcm2708/patches-4.19/950-0293-staging-bcm2835-camera-Check-the-error-for-REPEAT_SE.patch deleted file mode 100644 index 1216424e1e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0293-staging-bcm2835-camera-Check-the-error-for-REPEAT_SE.patch +++ /dev/null @@ -1,31 +0,0 @@ -From c2423f2fef7098dac416a1b49b3f9efbbbbd3293 Mon Sep 17 00:00:00 2001 -From: 6by9 <6by9@users.noreply.github.com> -Date: Tue, 11 Dec 2018 15:18:02 +0000 -Subject: [PATCH 293/703] staging: bcm2835-camera: Check the error for - REPEAT_SEQ_HEADER (#2782) - -When handling for V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER was added -the firmware would reject the setting if H264 hadn't already been -selected. This was fixed in the firmware at that point, but to -enable backwards compatibility the returned error was ignored. - -That was Dec 2013, so the chances of having a firmware that still -has that issue is so close to zero that the workaround can be -removed. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/bcm2835-camera/controls.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/bcm2835-camera/controls.c -+++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c -@@ -1100,7 +1100,7 @@ static const struct bm2835_mmal_v4l2_ctr - 0, 1, NULL, - MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER, - &ctrl_set_video_encode_param_output, -- true /* Errors ignored as requires latest firmware to work */ -+ false - }, - { - V4L2_CID_MPEG_VIDEO_H264_PROFILE, diff --git a/target/linux/brcm2708/patches-4.19/950-0294-arm64-dts-broadcom-Enable-fixups-for-overlays.patch b/target/linux/brcm2708/patches-4.19/950-0294-arm64-dts-broadcom-Enable-fixups-for-overlays.patch new file mode 100644 index 0000000000..b870e938ca --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0294-arm64-dts-broadcom-Enable-fixups-for-overlays.patch @@ -0,0 +1,23 @@ +From 848168d31f850623d2837c2cc154587189a5fd47 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 15 Jan 2019 09:56:41 +0000 +Subject: [PATCH 294/725] arm64: dts: broadcom: Enable fixups for overlays + +See: https://github.com/raspberrypi/linux/pull/2733 + +Signed-off-by: Phil Elwell +--- + arch/arm64/boot/dts/broadcom/Makefile | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/arch/arm64/boot/dts/broadcom/Makefile ++++ b/arch/arm64/boot/dts/broadcom/Makefile +@@ -9,3 +9,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rp + + subdir-y += northstar2 + subdir-y += stingray ++ ++# Enable fixups to support overlays on BCM2835 platforms ++ifeq ($(CONFIG_ARCH_BCM2835),y) ++ DTC_FLAGS ?= -@ ++endif diff --git a/target/linux/brcm2708/patches-4.19/950-0294-gpio-ir-change-default-pull-configuration-to-up.patch b/target/linux/brcm2708/patches-4.19/950-0294-gpio-ir-change-default-pull-configuration-to-up.patch deleted file mode 100644 index 8cc791d637..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0294-gpio-ir-change-default-pull-configuration-to-up.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 550dce51930fca1d5dc2a00a7a6f172fbb4e5b56 Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Wed, 9 Jan 2019 14:51:01 +0100 -Subject: [PATCH 294/703] gpio-ir: change default pull configuration to up - -IR receivers like the TSOP series from Vishay and compatible ones -have active-low open collector outputs with an internal pull up of -about 30k (according to the TSOP datasheets). - -Activating a pull-down resistor on the GPIO will make it work against -the pull-up in the IR receiver and brings the idle input voltage down -to about 1.9V (measured on a RPi3B+ with a TSOP4438). While that's -usually enough to make the RPi see a high signal it's certainly not -optimal and may even fail when using an IR receiver with a weaker pull-up. - -Switching the default GPIO pull to "up" results in an input voltage -level of about 3.3V and ensures that an idle state (high signal) will -be detected if no IR receiver is attached. - -Signed-off-by: Matthias Reichl ---- - arch/arm/boot/dts/overlays/README | 2 +- - arch/arm/boot/dts/overlays/gpio-ir-overlay.dts | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -611,7 +611,7 @@ Load: dtoverlay=gpio-ir,= - Params: gpio_pin Input pin number. Default is 18. - - gpio_pull Desired pull-up/down state (off, down, up) -- Default is "down". -+ Default is "up". - - rc-map-name Default rc keymap (can also be changed by - ir-keytable), defaults to "rc-rc6-mce" ---- a/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts -+++ b/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts -@@ -30,7 +30,7 @@ - gpio_ir_pins: gpio_ir_pins@12 { - brcm,pins = <18>; // pin 18 - brcm,function = <0>; // in -- brcm,pull = <1>; // down -+ brcm,pull = <2>; // up - }; - }; - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0295-firmware-raspberrypi-Report-the-fw-variant-during-pr.patch b/target/linux/brcm2708/patches-4.19/950-0295-firmware-raspberrypi-Report-the-fw-variant-during-pr.patch deleted file mode 100644 index 0e4a224097..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0295-firmware-raspberrypi-Report-the-fw-variant-during-pr.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 127e0899869365f5dc078e1ed84429ce81df90dc Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 10 Jan 2019 17:58:06 +0000 -Subject: [PATCH 295/703] firmware: raspberrypi: Report the fw variant during - probe - -The driver already reported the firmware build date during probe. -The mailbox calls have been extended to also report the variant - 1 = standard start.elf - 2 = start_x.elf (includes camera stack) - 3 = start_db.elf (includes assert logging) - 4 = start_cd.elf (cutdown version for smallest memory footprint). -Log the variant during probe. - -Signed-off-by: Dave Stevenson ---- - drivers/firmware/raspberrypi.c | 32 +++++++++++++++++----- - include/soc/bcm2835/raspberrypi-firmware.h | 1 + - 2 files changed, 26 insertions(+), 7 deletions(-) - ---- a/drivers/firmware/raspberrypi.c -+++ b/drivers/firmware/raspberrypi.c -@@ -227,21 +227,39 @@ static const struct attribute_group rpi_ - static void - rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) - { -+ static const char * const variant_strs[] = { -+ "unknown", -+ "start", -+ "start_x", -+ "start_db", -+ "start_cd", -+ }; -+ const char *variant_str = "cmd unsupported"; - u32 packet; -+ u32 variant; -+ struct tm tm; - int ret = rpi_firmware_property(fw, - RPI_FIRMWARE_GET_FIRMWARE_REVISION, - &packet, sizeof(packet)); - -- if (ret == 0) { -- struct tm tm; -+ if (ret) -+ return; - -- time64_to_tm(packet, 0, &tm); -+ ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_FIRMWARE_VARIANT, -+ &variant, sizeof(variant)); - -- dev_info(fw->cl.dev, -- "Attached to firmware from %04ld-%02d-%02d %02d:%02d\n", -- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, -- tm.tm_hour, tm.tm_min); -+ if (!ret) { -+ if (variant >= ARRAY_SIZE(variant_strs)) -+ variant = 0; -+ variant_str = variant_strs[variant]; - } -+ -+ time64_to_tm(packet, 0, &tm); -+ -+ dev_info(fw->cl.dev, -+ "Attached to firmware from %04ld-%02d-%02d %02d:%02d, variant %s\n", -+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, -+ tm.tm_min, variant_str); - } - - static void ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -41,6 +41,7 @@ struct rpi_firmware_property_tag_header - enum rpi_firmware_property_tag { - RPI_FIRMWARE_PROPERTY_END = 0, - RPI_FIRMWARE_GET_FIRMWARE_REVISION = 0x00000001, -+ RPI_FIRMWARE_GET_FIRMWARE_VARIANT = 0x00000002, - - RPI_FIRMWARE_SET_CURSOR_INFO = 0x00008010, - RPI_FIRMWARE_SET_CURSOR_STATE = 0x00008011, diff --git a/target/linux/brcm2708/patches-4.19/950-0295-sc16is7xx-Fix-for-Unexpected-interrupt-8.patch b/target/linux/brcm2708/patches-4.19/950-0295-sc16is7xx-Fix-for-Unexpected-interrupt-8.patch new file mode 100644 index 0000000000..3137a01123 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0295-sc16is7xx-Fix-for-Unexpected-interrupt-8.patch @@ -0,0 +1,110 @@ +From 699bca131fe01413d547e40a9e0d1db57b56e697 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 18 May 2018 10:26:59 +0100 +Subject: [PATCH 295/725] sc16is7xx: Fix for "Unexpected interrupt: 8" + +The SC16IS752 has an Enhanced Feature Register which is aliased at the +same address as the Interrupt Identification Register; accessing it +requires that a magic value is written to the Line Configuration +Register. If an interrupt is raised while the EFR is mapped in then +the ISR won't be able to access the IIR, leading to the "Unexpected +interrupt" error messages. + +Avoid the problem by claiming a mutex around accesses to the EFR +register, also claiming the mutex in the interrupt handler work +item (this is equivalent to disabling interrupts to interlock against +a non-threaded interrupt handler). + +See: https://github.com/raspberrypi/linux/issues/2529 + +Signed-off-by: Phil Elwell +--- + drivers/tty/serial/sc16is7xx.c | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +--- a/drivers/tty/serial/sc16is7xx.c ++++ b/drivers/tty/serial/sc16is7xx.c +@@ -328,6 +328,7 @@ struct sc16is7xx_port { + struct kthread_worker kworker; + struct task_struct *kworker_task; + struct kthread_work irq_work; ++ struct mutex efr_lock; + struct sc16is7xx_one p[0]; + }; + +@@ -499,6 +500,21 @@ static int sc16is7xx_set_baud(struct uar + div /= 4; + } + ++ /* In an amazing feat of design, the Enhanced Features Register shares ++ * the address of the Interrupt Identification Register, and is ++ * switched in by writing a magic value (0xbf) to the Line Control ++ * Register. Any interrupt firing during this time will see the EFR ++ * where it expects the IIR to be, leading to "Unexpected interrupt" ++ * messages. ++ * ++ * Prevent this possibility by claiming a mutex while accessing the ++ * EFR, and claiming the same mutex from within the interrupt handler. ++ * This is similar to disabling the interrupt, but that doesn't work ++ * because the bulk of the interrupt processing is run as a workqueue ++ * job in thread context. ++ */ ++ mutex_lock(&s->efr_lock); ++ + lcr = sc16is7xx_port_read(port, SC16IS7XX_LCR_REG); + + /* Open the LCR divisors for configuration */ +@@ -514,6 +530,8 @@ static int sc16is7xx_set_baud(struct uar + /* Put LCR back to the normal mode */ + sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr); + ++ mutex_unlock(&s->efr_lock); ++ + sc16is7xx_port_update(port, SC16IS7XX_MCR_REG, + SC16IS7XX_MCR_CLKSEL_BIT, + prescaler); +@@ -698,6 +716,8 @@ static void sc16is7xx_ist(struct kthread + { + struct sc16is7xx_port *s = to_sc16is7xx_port(ws, irq_work); + ++ mutex_lock(&s->efr_lock); ++ + while (1) { + bool keep_polling = false; + int i; +@@ -707,6 +727,8 @@ static void sc16is7xx_ist(struct kthread + if (!keep_polling) + break; + } ++ ++ mutex_unlock(&s->efr_lock); + } + + static irqreturn_t sc16is7xx_irq(int irq, void *dev_id) +@@ -901,6 +923,9 @@ static void sc16is7xx_set_termios(struct + if (!(termios->c_cflag & CREAD)) + port->ignore_status_mask |= SC16IS7XX_LSR_BRK_ERROR_MASK; + ++ /* As above, claim the mutex while accessing the EFR. */ ++ mutex_lock(&s->efr_lock); ++ + sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, + SC16IS7XX_LCR_CONF_MODE_B); + +@@ -922,6 +947,8 @@ static void sc16is7xx_set_termios(struct + /* Update LCR register */ + sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr); + ++ mutex_unlock(&s->efr_lock); ++ + /* Get baud rate generator configuration */ + baud = uart_get_baud_rate(port, termios, old, + port->uartclk / 16 / 4 / 0xffff, +@@ -1187,6 +1214,7 @@ static int sc16is7xx_probe(struct device + s->regmap = regmap; + s->devtype = devtype; + dev_set_drvdata(dev, s); ++ mutex_init(&s->efr_lock); + + kthread_init_worker(&s->kworker); + kthread_init_work(&s->irq_work, sc16is7xx_ist); diff --git a/target/linux/brcm2708/patches-4.19/950-0296-dtoverlays-fe-pi-audio-fix-sgtl5000-compatible-strin.patch b/target/linux/brcm2708/patches-4.19/950-0296-dtoverlays-fe-pi-audio-fix-sgtl5000-compatible-strin.patch new file mode 100644 index 0000000000..8ed9711e71 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0296-dtoverlays-fe-pi-audio-fix-sgtl5000-compatible-strin.patch @@ -0,0 +1,27 @@ +From 4db271be1ee58a646878a17aa1007533897c095b Mon Sep 17 00:00:00 2001 +From: Ben Wolsieffer +Date: Sun, 9 Dec 2018 16:46:00 -0500 +Subject: [PATCH 296/725] dtoverlays: fe-pi-audio: fix sgtl5000 compatible + string + +The compatible string was set to "fepi,sgtl5000", which worked for some +reason in 4.14, but does not work in 4.19, presumably due to some +change in the kernel matching logic. The correct string is +"fsl,sgtl5000". + +Signed-off-by: Ben Wolsieffer +--- + arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts +@@ -39,7 +39,7 @@ + + sgtl5000@0a { + #sound-dai-cells = <0>; +- compatible = "fepi,sgtl5000"; ++ compatible = "fsl,sgtl5000"; + reg = <0x0a>; + clocks = <&sgtl5000_mclk>; + micbias-resistor-k-ohms = <2>; diff --git a/target/linux/brcm2708/patches-4.19/950-0296-firmware-raspberrypi-Report-the-fw-git-hash-during-p.patch b/target/linux/brcm2708/patches-4.19/950-0296-firmware-raspberrypi-Report-the-fw-git-hash-during-p.patch deleted file mode 100644 index 8194883bd2..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0296-firmware-raspberrypi-Report-the-fw-git-hash-during-p.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 66d4a3ecb20bca91bc9e209cc8dc7730dffb0b57 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 10 Jan 2019 18:48:54 +0000 -Subject: [PATCH 296/703] firmware: raspberrypi: Report the fw git hash during - probe - -The firmware can now report the git hash from which it was built -via the mailbox, so report it during probe. - -Signed-off-by: Dave Stevenson ---- - drivers/firmware/raspberrypi.c | 17 +++++++++++++++++ - include/soc/bcm2835/raspberrypi-firmware.h | 1 + - 2 files changed, 18 insertions(+) - ---- a/drivers/firmware/raspberrypi.c -+++ b/drivers/firmware/raspberrypi.c -@@ -263,6 +263,22 @@ rpi_firmware_print_firmware_revision(str - } - - static void -+rpi_firmware_print_firmware_hash(struct rpi_firmware *fw) -+{ -+ u32 hash[5]; -+ int ret = rpi_firmware_property(fw, -+ RPI_FIRMWARE_GET_FIRMWARE_HASH, -+ hash, sizeof(hash)); -+ -+ if (ret) -+ return; -+ -+ dev_info(fw->cl.dev, -+ "Firmware hash is %08x%08x%08x%08x%08x\n", -+ hash[0], hash[1], hash[2], hash[3], hash[4]); -+} -+ -+static void - rpi_register_hwmon_driver(struct device *dev, struct rpi_firmware *fw) - { - u32 packet; -@@ -308,6 +324,7 @@ static int rpi_firmware_probe(struct pla - g_pdev = pdev; - - rpi_firmware_print_firmware_revision(fw); -+ rpi_firmware_print_firmware_hash(fw); - rpi_register_hwmon_driver(dev, fw); - - return 0; ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -42,6 +42,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_PROPERTY_END = 0, - RPI_FIRMWARE_GET_FIRMWARE_REVISION = 0x00000001, - RPI_FIRMWARE_GET_FIRMWARE_VARIANT = 0x00000002, -+ RPI_FIRMWARE_GET_FIRMWARE_HASH = 0x00000003, - - RPI_FIRMWARE_SET_CURSOR_INFO = 0x00008010, - RPI_FIRMWARE_SET_CURSOR_STATE = 0x00008011, diff --git a/target/linux/brcm2708/patches-4.19/950-0297-arm64-dts-broadcom-Enable-fixups-for-overlays.patch b/target/linux/brcm2708/patches-4.19/950-0297-arm64-dts-broadcom-Enable-fixups-for-overlays.patch deleted file mode 100644 index 69e1d65926..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0297-arm64-dts-broadcom-Enable-fixups-for-overlays.patch +++ /dev/null @@ -1,23 +0,0 @@ -From e09f9e3d46d8a393d54e414a718d232d13169a29 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 15 Jan 2019 09:56:41 +0000 -Subject: [PATCH 297/703] arm64: dts: broadcom: Enable fixups for overlays - -See: https://github.com/raspberrypi/linux/pull/2733 - -Signed-off-by: Phil Elwell ---- - arch/arm64/boot/dts/broadcom/Makefile | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/arch/arm64/boot/dts/broadcom/Makefile -+++ b/arch/arm64/boot/dts/broadcom/Makefile -@@ -9,3 +9,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rp - - subdir-y += northstar2 - subdir-y += stingray -+ -+# Enable fixups to support overlays on BCM2835 platforms -+ifeq ($(CONFIG_ARCH_BCM2835),y) -+ DTC_FLAGS ?= -@ -+endif diff --git a/target/linux/brcm2708/patches-4.19/950-0297-bcm2835_smi-re-add-dereference-to-fix-DMA-transfers.patch b/target/linux/brcm2708/patches-4.19/950-0297-bcm2835_smi-re-add-dereference-to-fix-DMA-transfers.patch new file mode 100644 index 0000000000..445474db8f --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0297-bcm2835_smi-re-add-dereference-to-fix-DMA-transfers.patch @@ -0,0 +1,20 @@ +From 4e11b14186707dfb88be344f227737eaf8adc608 Mon Sep 17 00:00:00 2001 +From: Ezekiel Bethel +Date: Wed, 12 Dec 2018 19:11:13 +0000 +Subject: [PATCH 297/725] bcm2835_smi: re-add dereference to fix DMA transfers + +--- + drivers/misc/bcm2835_smi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/misc/bcm2835_smi.c ++++ b/drivers/misc/bcm2835_smi.c +@@ -879,7 +879,7 @@ static int bcm2835_smi_probe(struct plat + goto err; + } + addr = of_get_address(node, 0, NULL, NULL); +- inst->smi_regs_busaddr = be32_to_cpu(addr); ++ inst->smi_regs_busaddr = be32_to_cpu(*addr); + + err = bcm2835_smi_dma_setup(inst); + if (err) diff --git a/target/linux/brcm2708/patches-4.19/950-0298-lan78xx-Debounce-link-events-to-minimize-poll-storm.patch b/target/linux/brcm2708/patches-4.19/950-0298-lan78xx-Debounce-link-events-to-minimize-poll-storm.patch new file mode 100644 index 0000000000..b855a77ed7 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0298-lan78xx-Debounce-link-events-to-minimize-poll-storm.patch @@ -0,0 +1,44 @@ +From a1bcab7b0deee8cf7d7bec2707cb50c269070d41 Mon Sep 17 00:00:00 2001 +From: Joshua Emele +Date: Wed, 7 Nov 2018 16:07:40 -0800 +Subject: [PATCH 298/725] lan78xx: Debounce link events to minimize poll storm + +The bInterval is set to 4 (i.e. 8 microframes => 1ms) and the only bit +that the driver pays attention to is "link was reset". If there's a +flapping status bit in that endpoint data, (such as if PHY negotiation +needs a few tries to get a stable link) then polling at a slower rate +would act as a de-bounce. + +See: https://github.com/raspberrypi/linux/issues/2447 +--- + drivers/net/usb/lan78xx.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -448,6 +448,11 @@ static bool enable_tso; + module_param(enable_tso, bool, 0644); + MODULE_PARM_DESC(enable_tso, "Enables TCP segmentation offload"); + ++#define INT_URB_MICROFRAMES_PER_MS 8 ++static int int_urb_interval_ms = 8; ++module_param(int_urb_interval_ms, int, 0); ++MODULE_PARM_DESC(int_urb_interval_ms, "Override usb interrupt urb interval"); ++ + static int lan78xx_read_reg(struct lan78xx_net *dev, u32 index, u32 *data) + { + u32 *buf = kmalloc(sizeof(u32), GFP_KERNEL); +@@ -3816,7 +3821,12 @@ static int lan78xx_probe(struct usb_inte + dev->pipe_intr = usb_rcvintpipe(dev->udev, + dev->ep_intr->desc.bEndpointAddress & + USB_ENDPOINT_NUMBER_MASK); +- period = dev->ep_intr->desc.bInterval; ++ if (int_urb_interval_ms <= 0) ++ period = dev->ep_intr->desc.bInterval; ++ else ++ period = int_urb_interval_ms * INT_URB_MICROFRAMES_PER_MS; ++ ++ netif_notice(dev, probe, netdev, "int urb period %d\n", period); + + maxp = usb_maxpacket(dev->udev, dev->pipe_intr, 0); + buf = kmalloc(maxp, GFP_KERNEL); diff --git a/target/linux/brcm2708/patches-4.19/950-0298-sc16is7xx-Fix-for-Unexpected-interrupt-8.patch b/target/linux/brcm2708/patches-4.19/950-0298-sc16is7xx-Fix-for-Unexpected-interrupt-8.patch deleted file mode 100644 index 8c980ce43c..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0298-sc16is7xx-Fix-for-Unexpected-interrupt-8.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 2328af8468b09a20258488b2126449aa8539ee5a Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 18 May 2018 10:26:59 +0100 -Subject: [PATCH 298/703] sc16is7xx: Fix for "Unexpected interrupt: 8" - -The SC16IS752 has an Enhanced Feature Register which is aliased at the -same address as the Interrupt Identification Register; accessing it -requires that a magic value is written to the Line Configuration -Register. If an interrupt is raised while the EFR is mapped in then -the ISR won't be able to access the IIR, leading to the "Unexpected -interrupt" error messages. - -Avoid the problem by claiming a mutex around accesses to the EFR -register, also claiming the mutex in the interrupt handler work -item (this is equivalent to disabling interrupts to interlock against -a non-threaded interrupt handler). - -See: https://github.com/raspberrypi/linux/issues/2529 - -Signed-off-by: Phil Elwell ---- - drivers/tty/serial/sc16is7xx.c | 28 ++++++++++++++++++++++++++++ - 1 file changed, 28 insertions(+) - ---- a/drivers/tty/serial/sc16is7xx.c -+++ b/drivers/tty/serial/sc16is7xx.c -@@ -328,6 +328,7 @@ struct sc16is7xx_port { - struct kthread_worker kworker; - struct task_struct *kworker_task; - struct kthread_work irq_work; -+ struct mutex efr_lock; - struct sc16is7xx_one p[0]; - }; - -@@ -499,6 +500,21 @@ static int sc16is7xx_set_baud(struct uar - div /= 4; - } - -+ /* In an amazing feat of design, the Enhanced Features Register shares -+ * the address of the Interrupt Identification Register, and is -+ * switched in by writing a magic value (0xbf) to the Line Control -+ * Register. Any interrupt firing during this time will see the EFR -+ * where it expects the IIR to be, leading to "Unexpected interrupt" -+ * messages. -+ * -+ * Prevent this possibility by claiming a mutex while accessing the -+ * EFR, and claiming the same mutex from within the interrupt handler. -+ * This is similar to disabling the interrupt, but that doesn't work -+ * because the bulk of the interrupt processing is run as a workqueue -+ * job in thread context. -+ */ -+ mutex_lock(&s->efr_lock); -+ - lcr = sc16is7xx_port_read(port, SC16IS7XX_LCR_REG); - - /* Open the LCR divisors for configuration */ -@@ -514,6 +530,8 @@ static int sc16is7xx_set_baud(struct uar - /* Put LCR back to the normal mode */ - sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr); - -+ mutex_unlock(&s->efr_lock); -+ - sc16is7xx_port_update(port, SC16IS7XX_MCR_REG, - SC16IS7XX_MCR_CLKSEL_BIT, - prescaler); -@@ -698,6 +716,8 @@ static void sc16is7xx_ist(struct kthread - { - struct sc16is7xx_port *s = to_sc16is7xx_port(ws, irq_work); - -+ mutex_lock(&s->efr_lock); -+ - while (1) { - bool keep_polling = false; - int i; -@@ -707,6 +727,8 @@ static void sc16is7xx_ist(struct kthread - if (!keep_polling) - break; - } -+ -+ mutex_unlock(&s->efr_lock); - } - - static irqreturn_t sc16is7xx_irq(int irq, void *dev_id) -@@ -901,6 +923,9 @@ static void sc16is7xx_set_termios(struct - if (!(termios->c_cflag & CREAD)) - port->ignore_status_mask |= SC16IS7XX_LSR_BRK_ERROR_MASK; - -+ /* As above, claim the mutex while accessing the EFR. */ -+ mutex_lock(&s->efr_lock); -+ - sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, - SC16IS7XX_LCR_CONF_MODE_B); - -@@ -922,6 +947,8 @@ static void sc16is7xx_set_termios(struct - /* Update LCR register */ - sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr); - -+ mutex_unlock(&s->efr_lock); -+ - /* Get baud rate generator configuration */ - baud = uart_get_baud_rate(port, termios, old, - port->uartclk / 16 / 4 / 0xffff, -@@ -1187,6 +1214,7 @@ static int sc16is7xx_probe(struct device - s->regmap = regmap; - s->devtype = devtype; - dev_set_drvdata(dev, s); -+ mutex_init(&s->efr_lock); - - kthread_init_worker(&s->kworker); - kthread_init_work(&s->irq_work, sc16is7xx_ist); diff --git a/target/linux/brcm2708/patches-4.19/950-0299-ASoC-Add-support-for-AudioSense-Pi-add-on-soundcard.patch b/target/linux/brcm2708/patches-4.19/950-0299-ASoC-Add-support-for-AudioSense-Pi-add-on-soundcard.patch new file mode 100644 index 0000000000..5f482d0bc7 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0299-ASoC-Add-support-for-AudioSense-Pi-add-on-soundcard.patch @@ -0,0 +1,320 @@ +From 93952495f34e255ab4a3ce4631edd1520200f586 Mon Sep 17 00:00:00 2001 +From: b-ak +Date: Thu, 3 Jan 2019 00:01:08 +0530 +Subject: [PATCH 299/725] ASoC: Add support for AudioSense-Pi add-on soundcard + +AudioSense-Pi is a RPi HAT based on a TI's TLV320AIC32x4 stereo codec + +This hardware provides multiple audio I/O capabilities to the RPi. +The codec connects to the RPi's SoC through the I2S Bus. + +The following devices can be connected through a 3.5mm jack + 1. Line-In: Plain old audio in from mobile phones, PCs, etc., + 2. Mic-In: Connect a microphone + 3. Line-Out: Connect the output to a speaker + 4. Headphones: Connect a Headphone w or w/o microphones + +Multiple Inputs: + It supports the following combinations + 1. Two stereo Line-Inputs and a microphone + 2. One stereo Line-Input and two microphones + 3. Two stereo Line-Inputs, a microphone and + one mono line-input (with h/w hack) + 4. One stereo Line-Input, two microphones and + one mono line-input (with h/w hack) + +Multiple Outputs: + Audio output can be routed to the headphones or + speakers (with additional hardware) + +Signed-off-by: b-ak +--- + sound/soc/bcm/Kconfig | 7 + + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/audiosense-pi.c | 246 ++++++++++++++++++++++++++++++++++ + 3 files changed, 255 insertions(+) + create mode 100644 sound/soc/bcm/audiosense-pi.c + +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -137,6 +137,13 @@ config SND_AUDIOINJECTOR_OCTO_SOUNDCARD + help + Say Y or M if you want to add support for audioinjector.net octo add on + ++config SND_AUDIOSENSE_PI ++ tristate "Support for AudioSense Add-On Soundcard" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_TLV320AIC32X4_I2C ++ help ++ Say Y or M if you want to add support for tlv320aic32x4 add-on ++ + config SND_DIGIDAC1_SOUNDCARD + tristate "Support for Red Rocks Audio DigiDAC1" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -20,6 +20,7 @@ snd-soc-rpi-proto-objs := rpi-proto.o + snd-soc-iqaudio-dac-objs := iqaudio-dac.o + snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o + snd-soc-audioinjector-octo-soundcard-objs := audioinjector-octo-soundcard.o ++snd-soc-audiosense-pi-objs := audiosense-pi.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 +@@ -41,6 +42,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) + obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o + obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o + obj-$(CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD) += snd-soc-audioinjector-octo-soundcard.o ++obj-$(CONFIG_SND_AUDIOSENSE_PI) += snd-soc-audiosense-pi.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 +--- /dev/null ++++ b/sound/soc/bcm/audiosense-pi.c +@@ -0,0 +1,246 @@ ++/* ++ * ASoC Driver for AudioSense add on soundcard ++ * Author: ++ * Bhargav A K ++ * Copyright 2017 ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include "../codecs/tlv320aic32x4.h" ++ ++#define AIC32X4_SYSCLK_XTAL 0x00 ++ ++/* ++ * Setup Codec Sample Rates and Channels ++ * Supported Rates: ++ * 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200, 96000, ++ */ ++static const unsigned int audiosense_pi_rate[] = { ++ 48000, ++}; ++ ++static struct snd_pcm_hw_constraint_list audiosense_constraints_rates = { ++ .list = audiosense_pi_rate, ++ .count = ARRAY_SIZE(audiosense_pi_rate), ++}; ++ ++static const unsigned int audiosense_pi_channels[] = { ++ 2, ++}; ++ ++static struct snd_pcm_hw_constraint_list audiosense_constraints_ch = { ++ .count = ARRAY_SIZE(audiosense_pi_channels), ++ .list = audiosense_pi_channels, ++ .mask = 0, ++}; ++ ++/* Setup DAPM widgets and paths */ ++static const struct snd_soc_dapm_widget audiosense_pi_dapm_widgets[] = { ++ SND_SOC_DAPM_HP("Headphone Jack", NULL), ++ SND_SOC_DAPM_LINE("Line Out", NULL), ++ SND_SOC_DAPM_LINE("Line In", NULL), ++ SND_SOC_DAPM_INPUT("CM_L"), ++ SND_SOC_DAPM_INPUT("CM_R"), ++}; ++ ++static const struct snd_soc_dapm_route audiosense_pi_audio_map[] = { ++ /* Line Inputs are connected to ++ * (IN1_L | IN1_R) ++ * (IN2_L | IN2_R) ++ * (IN3_L | IN3_R) ++ */ ++ {"IN1_L", NULL, "Line In"}, ++ {"IN1_R", NULL, "Line In"}, ++ {"IN2_L", NULL, "Line In"}, ++ {"IN2_R", NULL, "Line In"}, ++ {"IN3_L", NULL, "Line In"}, ++ {"IN3_R", NULL, "Line In"}, ++ ++ /* Mic is connected to IN2_L and IN2_R */ ++ {"Left ADC", NULL, "Mic Bias"}, ++ {"Right ADC", NULL, "Mic Bias"}, ++ ++ /* Headphone connected to HPL, HPR */ ++ {"Headphone Jack", NULL, "HPL"}, ++ {"Headphone Jack", NULL, "HPR"}, ++ ++ /* Speakers connected to LOL and LOR */ ++ {"Line Out", NULL, "LOL"}, ++ {"Line Out", NULL, "LOR"}, ++}; ++ ++static int audiosense_pi_card_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ /* TODO: init of the codec specific dapm data, ignore suspend/resume */ ++ struct snd_soc_component *component = rtd->codec_dai->component; ++ ++ snd_soc_component_update_bits(component, AIC32X4_MICBIAS, 0x78, ++ AIC32X4_MICBIAS_LDOIN | ++ AIC32X4_MICBIAS_2075V); ++ snd_soc_component_update_bits(component, AIC32X4_PWRCFG, 0x08, ++ AIC32X4_AVDDWEAKDISABLE); ++ snd_soc_component_update_bits(component, AIC32X4_LDOCTL, 0x01, ++ AIC32X4_LDOCTLEN); ++ ++ return 0; ++} ++ ++static int audiosense_pi_card_hw_params( ++ struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ int ret = 0; ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *codec_dai = rtd->codec_dai; ++ ++ /* Set the codec system clock, there is a 12 MHz XTAL on the board */ ++ ret = snd_soc_dai_set_sysclk(codec_dai, AIC32X4_SYSCLK_XTAL, ++ 12000000, SND_SOC_CLOCK_IN); ++ if (ret) { ++ dev_err(rtd->card->dev, ++ "could not set codec driver clock params\n"); ++ return ret; ++ } ++ return 0; ++} ++ ++static int audiosense_pi_card_startup(struct snd_pcm_substream *substream) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ ++ /* ++ * Set codec to 48Khz Sampling, Stereo I/O and 16 bit audio ++ */ ++ runtime->hw.channels_max = 2; ++ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, ++ &audiosense_constraints_ch); ++ ++ runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; ++ snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); ++ ++ ++ snd_pcm_hw_constraint_list(substream->runtime, 0, ++ SNDRV_PCM_HW_PARAM_RATE, ++ &audiosense_constraints_rates); ++ return 0; ++} ++ ++static struct snd_soc_ops audiosense_pi_card_ops = { ++ .startup = audiosense_pi_card_startup, ++ .hw_params = audiosense_pi_card_hw_params, ++}; ++ ++static struct snd_soc_dai_link audiosense_pi_card_dai[] = { ++ { ++ .name = "TLV320AIC3204 Audio", ++ .stream_name = "TLV320AIC3204 Hifi Audio", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "tlv320aic32x4-hifi", ++ .platform_name = "bcm2708-i2s.0", ++ .codec_name = "tlv320aic32x4.1-0018", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBM_CFM, ++ .ops = &audiosense_pi_card_ops, ++ .init = audiosense_pi_card_init, ++ }, ++}; ++ ++static struct snd_soc_card audiosense_pi_card = { ++ .name = "audiosense-pi", ++ .driver_name = "audiosense-pi", ++ .dai_link = audiosense_pi_card_dai, ++ .owner = THIS_MODULE, ++ .num_links = ARRAY_SIZE(audiosense_pi_card_dai), ++ .dapm_widgets = audiosense_pi_dapm_widgets, ++ .num_dapm_widgets = ARRAY_SIZE(audiosense_pi_dapm_widgets), ++ .dapm_routes = audiosense_pi_audio_map, ++ .num_dapm_routes = ARRAY_SIZE(audiosense_pi_audio_map), ++}; ++ ++static int audiosense_pi_card_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ struct snd_soc_card *card = &audiosense_pi_card; ++ struct snd_soc_dai_link *dai = &audiosense_pi_card_dai[0]; ++ struct device_node *i2s_node = pdev->dev.of_node; ++ ++ card->dev = &pdev->dev; ++ ++ if (!dai) { ++ dev_err(&pdev->dev, "DAI not found. Missing or Invalid\n"); ++ return -EINVAL; ++ } ++ ++ i2s_node = of_parse_phandle(pdev->dev.of_node, "i2s-controller", 0); ++ if (!i2s_node) { ++ dev_err(&pdev->dev, ++ "Property 'i2s-controller' 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); ++ ++ 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 audiosense_pi_card_remove(struct platform_device *pdev) ++{ ++ struct snd_soc_card *card = platform_get_drvdata(pdev); ++ ++ return snd_soc_unregister_card(card); ++ ++} ++ ++static const struct of_device_id audiosense_pi_card_of_match[] = { ++ { .compatible = "as,audiosense-pi", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, audiosense_pi_card_of_match); ++ ++static struct platform_driver audiosense_pi_card_driver = { ++ .driver = { ++ .name = "audiosense-snd-card", ++ .owner = THIS_MODULE, ++ .of_match_table = audiosense_pi_card_of_match, ++ }, ++ .probe = audiosense_pi_card_probe, ++ .remove = audiosense_pi_card_remove, ++}; ++ ++module_platform_driver(audiosense_pi_card_driver); ++ ++MODULE_AUTHOR("Bhargav AK "); ++MODULE_DESCRIPTION("ASoC Driver for TLV320AIC3204 Audio"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:audiosense-pi"); ++ diff --git a/target/linux/brcm2708/patches-4.19/950-0299-dtoverlays-fe-pi-audio-fix-sgtl5000-compatible-strin.patch b/target/linux/brcm2708/patches-4.19/950-0299-dtoverlays-fe-pi-audio-fix-sgtl5000-compatible-strin.patch deleted file mode 100644 index 21237ed4b7..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0299-dtoverlays-fe-pi-audio-fix-sgtl5000-compatible-strin.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 4e7767bc63406cf8a4cb2cdcf86c2592c07440f6 Mon Sep 17 00:00:00 2001 -From: Ben Wolsieffer -Date: Sun, 9 Dec 2018 16:46:00 -0500 -Subject: [PATCH 299/703] dtoverlays: fe-pi-audio: fix sgtl5000 compatible - string - -The compatible string was set to "fepi,sgtl5000", which worked for some -reason in 4.14, but does not work in 4.19, presumably due to some -change in the kernel matching logic. The correct string is -"fsl,sgtl5000". - -Signed-off-by: Ben Wolsieffer ---- - arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts -@@ -39,7 +39,7 @@ - - sgtl5000@0a { - #sound-dai-cells = <0>; -- compatible = "fepi,sgtl5000"; -+ compatible = "fsl,sgtl5000"; - reg = <0x0a>; - clocks = <&sgtl5000_mclk>; - micbias-resistor-k-ohms = <2>; diff --git a/target/linux/brcm2708/patches-4.19/950-0300-BCM270X-Adding-device-tree-support-for-AudioSense-Pi.patch b/target/linux/brcm2708/patches-4.19/950-0300-BCM270X-Adding-device-tree-support-for-AudioSense-Pi.patch new file mode 100644 index 0000000000..5588d605d4 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0300-BCM270X-Adding-device-tree-support-for-AudioSense-Pi.patch @@ -0,0 +1,135 @@ +From 92192e0410d1c38596ca387c1680ff37847dcdc3 Mon Sep 17 00:00:00 2001 +From: b-ak +Date: Thu, 3 Jan 2019 00:29:14 +0530 +Subject: [PATCH 300/725] BCM270X: Adding device tree support for AudioSense-Pi + add-on soundcard + +Device tree overlay for AudioSense-Pi card. + +To enable support for the hardware add the following +line to the RPi /boot/config.txt: + + dtoverlay=audiosense-pi + +More documentation @ arch/arm/boot/dts/overlays/README + +Signed-off-by: b-ak +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 8 ++ + .../dts/overlays/audiosense-pi-overlay.dts | 82 +++++++++++++++++++ + 3 files changed, 91 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/audiosense-pi-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -20,6 +20,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + audioinjector-addons.dtbo \ + audioinjector-ultra.dtbo \ + audioinjector-wm8731-audio.dtbo \ ++ audiosense-pi.dtbo \ + audremap.dtbo \ + balena-fin.dtbo \ + bmp085_i2c-sensor.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -453,6 +453,14 @@ Load: dtoverlay=audioinjector-wm8731-a + Params: + + ++Name: audiosense-pi ++Info: Configures the audiosense-pi add on soundcard ++ For more information refer to ++ https://gitlab.com/kakar0t/audiosense-pi ++Load: dtoverlay=audiosense-pi ++Params: ++ ++ + Name: audremap + Info: Switches PWM sound output to pins 12 (Right) & 13 (Left) + Load: dtoverlay=audremap,= +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/audiosense-pi-overlay.dts +@@ -0,0 +1,82 @@ ++// Definitions for audiosense add on soundcard ++/dts-v1/; ++/plugin/; ++#include ++#include ++ ++/ { ++ compatible = "brcm,bcm2837", "brcm,bcm2836", "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ codec_reg_1v8: codec-reg-1v8 { ++ compatible = "regulator-fixed"; ++ regulator-name = "tlv320aic3204_1v8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&gpio>; ++ __overlay__ { ++ codec_rst: codec-rst { ++ brcm,pins = <26>; ++ brcm,function = ; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ /* audio external oscillator */ ++ codec_osc: codec_osc { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <12000000>; /* 12 MHz */ ++ }; ++ ++ codec: tlv320aic32x4@18 { ++ #sound-dai-cells = <0>; ++ compatible = "ti,tlv320aic32x4"; ++ reg = <0x18>; ++ ++ clocks = <&codec_osc>; ++ clock-names = "mclk"; ++ ++ iov-supply = <&vdd_3v3_reg>; ++ ldoin-supply = <&vdd_3v3_reg>; ++ ++ gpio-controller; ++ #gpio-cells = <2>; ++ reset-gpios = <&gpio 26 GPIO_ACTIVE_HIGH>; ++ ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "as,audiosense-pi"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++}; diff --git a/target/linux/brcm2708/patches-4.19/950-0300-bcm2835_smi-re-add-dereference-to-fix-DMA-transfers.patch b/target/linux/brcm2708/patches-4.19/950-0300-bcm2835_smi-re-add-dereference-to-fix-DMA-transfers.patch deleted file mode 100644 index 9512c1291d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0300-bcm2835_smi-re-add-dereference-to-fix-DMA-transfers.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 6edc58ab2e73fc38ba380de57e8a416cfaaba512 Mon Sep 17 00:00:00 2001 -From: Ezekiel Bethel -Date: Wed, 12 Dec 2018 19:11:13 +0000 -Subject: [PATCH 300/703] bcm2835_smi: re-add dereference to fix DMA transfers - ---- - drivers/misc/bcm2835_smi.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/misc/bcm2835_smi.c -+++ b/drivers/misc/bcm2835_smi.c -@@ -879,7 +879,7 @@ static int bcm2835_smi_probe(struct plat - goto err; - } - addr = of_get_address(node, 0, NULL, NULL); -- inst->smi_regs_busaddr = be32_to_cpu(addr); -+ inst->smi_regs_busaddr = be32_to_cpu(*addr); - - err = bcm2835_smi_dma_setup(inst); - if (err) diff --git a/target/linux/brcm2708/patches-4.19/950-0301-configs-Add-CONFIG_SND_AUDIOSENSE_PI-m.patch b/target/linux/brcm2708/patches-4.19/950-0301-configs-Add-CONFIG_SND_AUDIOSENSE_PI-m.patch new file mode 100644 index 0000000000..365ad46fdb --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0301-configs-Add-CONFIG_SND_AUDIOSENSE_PI-m.patch @@ -0,0 +1,44 @@ +From f737d88ed6add8f6197bf1a26ace908b13a19d96 Mon Sep 17 00:00:00 2001 +From: b-ak +Date: Fri, 4 Jan 2019 00:12:51 +0530 +Subject: [PATCH 301/725] configs: Add CONFIG_SND_AUDIOSENSE_PI=m + +AudioSense-Pi add on soundcard configuration definitions + +Signed-off-by: b-ak +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + arch/arm64/configs/bcmrpi3_defconfig | 1 + + 3 files changed, 3 insertions(+) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -918,6 +918,7 @@ CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m + CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m + CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m + CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m ++CONFIG_SND_AUDIOSENSE_PI=m + CONFIG_SND_DIGIDAC1_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -911,6 +911,7 @@ CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m + CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m + CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m + CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m ++CONFIG_SND_AUDIOSENSE_PI=m + CONFIG_SND_DIGIDAC1_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -800,6 +800,7 @@ CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m + CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m + CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m + CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m ++CONFIG_SND_AUDIOSENSE_PI=m + CONFIG_SND_DIGIDAC1_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m + CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m diff --git a/target/linux/brcm2708/patches-4.19/950-0301-lan78xx-Debounce-link-events-to-minimize-poll-storm.patch b/target/linux/brcm2708/patches-4.19/950-0301-lan78xx-Debounce-link-events-to-minimize-poll-storm.patch deleted file mode 100644 index f5ca286e73..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0301-lan78xx-Debounce-link-events-to-minimize-poll-storm.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 643d2b5c276c5d2967b857256a983ae7860607a1 Mon Sep 17 00:00:00 2001 -From: Joshua Emele -Date: Wed, 7 Nov 2018 16:07:40 -0800 -Subject: [PATCH 301/703] lan78xx: Debounce link events to minimize poll storm - -The bInterval is set to 4 (i.e. 8 microframes => 1ms) and the only bit -that the driver pays attention to is "link was reset". If there's a -flapping status bit in that endpoint data, (such as if PHY negotiation -needs a few tries to get a stable link) then polling at a slower rate -would act as a de-bounce. - -See: https://github.com/raspberrypi/linux/issues/2447 ---- - drivers/net/usb/lan78xx.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - ---- a/drivers/net/usb/lan78xx.c -+++ b/drivers/net/usb/lan78xx.c -@@ -448,6 +448,11 @@ static bool enable_tso; - module_param(enable_tso, bool, 0644); - MODULE_PARM_DESC(enable_tso, "Enables TCP segmentation offload"); - -+#define INT_URB_MICROFRAMES_PER_MS 8 -+static int int_urb_interval_ms = 8; -+module_param(int_urb_interval_ms, int, 0); -+MODULE_PARM_DESC(int_urb_interval_ms, "Override usb interrupt urb interval"); -+ - static int lan78xx_read_reg(struct lan78xx_net *dev, u32 index, u32 *data) - { - u32 *buf = kmalloc(sizeof(u32), GFP_KERNEL); -@@ -3816,7 +3821,12 @@ static int lan78xx_probe(struct usb_inte - dev->pipe_intr = usb_rcvintpipe(dev->udev, - dev->ep_intr->desc.bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK); -- period = dev->ep_intr->desc.bInterval; -+ if (int_urb_interval_ms <= 0) -+ period = dev->ep_intr->desc.bInterval; -+ else -+ period = int_urb_interval_ms * INT_URB_MICROFRAMES_PER_MS; -+ -+ netif_notice(dev, probe, netdev, "int urb period %d\n", period); - - maxp = usb_maxpacket(dev->udev, dev->pipe_intr, 0); - buf = kmalloc(maxp, GFP_KERNEL); diff --git a/target/linux/brcm2708/patches-4.19/950-0302-ASoC-Add-support-for-AudioSense-Pi-add-on-soundcard.patch b/target/linux/brcm2708/patches-4.19/950-0302-ASoC-Add-support-for-AudioSense-Pi-add-on-soundcard.patch deleted file mode 100644 index f2cd3aa159..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0302-ASoC-Add-support-for-AudioSense-Pi-add-on-soundcard.patch +++ /dev/null @@ -1,320 +0,0 @@ -From 99324d4b613b3ee56683446abbd96623c6a64887 Mon Sep 17 00:00:00 2001 -From: b-ak -Date: Thu, 3 Jan 2019 00:01:08 +0530 -Subject: [PATCH 302/703] ASoC: Add support for AudioSense-Pi add-on soundcard - -AudioSense-Pi is a RPi HAT based on a TI's TLV320AIC32x4 stereo codec - -This hardware provides multiple audio I/O capabilities to the RPi. -The codec connects to the RPi's SoC through the I2S Bus. - -The following devices can be connected through a 3.5mm jack - 1. Line-In: Plain old audio in from mobile phones, PCs, etc., - 2. Mic-In: Connect a microphone - 3. Line-Out: Connect the output to a speaker - 4. Headphones: Connect a Headphone w or w/o microphones - -Multiple Inputs: - It supports the following combinations - 1. Two stereo Line-Inputs and a microphone - 2. One stereo Line-Input and two microphones - 3. Two stereo Line-Inputs, a microphone and - one mono line-input (with h/w hack) - 4. One stereo Line-Input, two microphones and - one mono line-input (with h/w hack) - -Multiple Outputs: - Audio output can be routed to the headphones or - speakers (with additional hardware) - -Signed-off-by: b-ak ---- - sound/soc/bcm/Kconfig | 7 + - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/audiosense-pi.c | 246 ++++++++++++++++++++++++++++++++++ - 3 files changed, 255 insertions(+) - create mode 100644 sound/soc/bcm/audiosense-pi.c - ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -137,6 +137,13 @@ config SND_AUDIOINJECTOR_OCTO_SOUNDCARD - help - Say Y or M if you want to add support for audioinjector.net octo add on - -+config SND_AUDIOSENSE_PI -+ tristate "Support for AudioSense Add-On Soundcard" -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S -+ select SND_SOC_TLV320AIC32X4_I2C -+ help -+ Say Y or M if you want to add support for tlv320aic32x4 add-on -+ - config SND_DIGIDAC1_SOUNDCARD - tristate "Support for Red Rocks Audio DigiDAC1" - depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -20,6 +20,7 @@ snd-soc-rpi-proto-objs := rpi-proto.o - snd-soc-iqaudio-dac-objs := iqaudio-dac.o - snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o - snd-soc-audioinjector-octo-soundcard-objs := audioinjector-octo-soundcard.o -+snd-soc-audiosense-pi-objs := audiosense-pi.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 -@@ -41,6 +42,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) - obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o - obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o - obj-$(CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD) += snd-soc-audioinjector-octo-soundcard.o -+obj-$(CONFIG_SND_AUDIOSENSE_PI) += snd-soc-audiosense-pi.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 ---- /dev/null -+++ b/sound/soc/bcm/audiosense-pi.c -@@ -0,0 +1,246 @@ -+/* -+ * ASoC Driver for AudioSense add on soundcard -+ * Author: -+ * Bhargav A K -+ * Copyright 2017 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include "../codecs/tlv320aic32x4.h" -+ -+#define AIC32X4_SYSCLK_XTAL 0x00 -+ -+/* -+ * Setup Codec Sample Rates and Channels -+ * Supported Rates: -+ * 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200, 96000, -+ */ -+static const unsigned int audiosense_pi_rate[] = { -+ 48000, -+}; -+ -+static struct snd_pcm_hw_constraint_list audiosense_constraints_rates = { -+ .list = audiosense_pi_rate, -+ .count = ARRAY_SIZE(audiosense_pi_rate), -+}; -+ -+static const unsigned int audiosense_pi_channels[] = { -+ 2, -+}; -+ -+static struct snd_pcm_hw_constraint_list audiosense_constraints_ch = { -+ .count = ARRAY_SIZE(audiosense_pi_channels), -+ .list = audiosense_pi_channels, -+ .mask = 0, -+}; -+ -+/* Setup DAPM widgets and paths */ -+static const struct snd_soc_dapm_widget audiosense_pi_dapm_widgets[] = { -+ SND_SOC_DAPM_HP("Headphone Jack", NULL), -+ SND_SOC_DAPM_LINE("Line Out", NULL), -+ SND_SOC_DAPM_LINE("Line In", NULL), -+ SND_SOC_DAPM_INPUT("CM_L"), -+ SND_SOC_DAPM_INPUT("CM_R"), -+}; -+ -+static const struct snd_soc_dapm_route audiosense_pi_audio_map[] = { -+ /* Line Inputs are connected to -+ * (IN1_L | IN1_R) -+ * (IN2_L | IN2_R) -+ * (IN3_L | IN3_R) -+ */ -+ {"IN1_L", NULL, "Line In"}, -+ {"IN1_R", NULL, "Line In"}, -+ {"IN2_L", NULL, "Line In"}, -+ {"IN2_R", NULL, "Line In"}, -+ {"IN3_L", NULL, "Line In"}, -+ {"IN3_R", NULL, "Line In"}, -+ -+ /* Mic is connected to IN2_L and IN2_R */ -+ {"Left ADC", NULL, "Mic Bias"}, -+ {"Right ADC", NULL, "Mic Bias"}, -+ -+ /* Headphone connected to HPL, HPR */ -+ {"Headphone Jack", NULL, "HPL"}, -+ {"Headphone Jack", NULL, "HPR"}, -+ -+ /* Speakers connected to LOL and LOR */ -+ {"Line Out", NULL, "LOL"}, -+ {"Line Out", NULL, "LOR"}, -+}; -+ -+static int audiosense_pi_card_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ /* TODO: init of the codec specific dapm data, ignore suspend/resume */ -+ struct snd_soc_component *component = rtd->codec_dai->component; -+ -+ snd_soc_component_update_bits(component, AIC32X4_MICBIAS, 0x78, -+ AIC32X4_MICBIAS_LDOIN | -+ AIC32X4_MICBIAS_2075V); -+ snd_soc_component_update_bits(component, AIC32X4_PWRCFG, 0x08, -+ AIC32X4_AVDDWEAKDISABLE); -+ snd_soc_component_update_bits(component, AIC32X4_LDOCTL, 0x01, -+ AIC32X4_LDOCTLEN); -+ -+ return 0; -+} -+ -+static int audiosense_pi_card_hw_params( -+ struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ int ret = 0; -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_dai *codec_dai = rtd->codec_dai; -+ -+ /* Set the codec system clock, there is a 12 MHz XTAL on the board */ -+ ret = snd_soc_dai_set_sysclk(codec_dai, AIC32X4_SYSCLK_XTAL, -+ 12000000, SND_SOC_CLOCK_IN); -+ if (ret) { -+ dev_err(rtd->card->dev, -+ "could not set codec driver clock params\n"); -+ return ret; -+ } -+ return 0; -+} -+ -+static int audiosense_pi_card_startup(struct snd_pcm_substream *substream) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ -+ /* -+ * Set codec to 48Khz Sampling, Stereo I/O and 16 bit audio -+ */ -+ runtime->hw.channels_max = 2; -+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, -+ &audiosense_constraints_ch); -+ -+ runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; -+ snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); -+ -+ -+ snd_pcm_hw_constraint_list(substream->runtime, 0, -+ SNDRV_PCM_HW_PARAM_RATE, -+ &audiosense_constraints_rates); -+ return 0; -+} -+ -+static struct snd_soc_ops audiosense_pi_card_ops = { -+ .startup = audiosense_pi_card_startup, -+ .hw_params = audiosense_pi_card_hw_params, -+}; -+ -+static struct snd_soc_dai_link audiosense_pi_card_dai[] = { -+ { -+ .name = "TLV320AIC3204 Audio", -+ .stream_name = "TLV320AIC3204 Hifi Audio", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "tlv320aic32x4-hifi", -+ .platform_name = "bcm2708-i2s.0", -+ .codec_name = "tlv320aic32x4.1-0018", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBM_CFM, -+ .ops = &audiosense_pi_card_ops, -+ .init = audiosense_pi_card_init, -+ }, -+}; -+ -+static struct snd_soc_card audiosense_pi_card = { -+ .name = "audiosense-pi", -+ .driver_name = "audiosense-pi", -+ .dai_link = audiosense_pi_card_dai, -+ .owner = THIS_MODULE, -+ .num_links = ARRAY_SIZE(audiosense_pi_card_dai), -+ .dapm_widgets = audiosense_pi_dapm_widgets, -+ .num_dapm_widgets = ARRAY_SIZE(audiosense_pi_dapm_widgets), -+ .dapm_routes = audiosense_pi_audio_map, -+ .num_dapm_routes = ARRAY_SIZE(audiosense_pi_audio_map), -+}; -+ -+static int audiosense_pi_card_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ struct snd_soc_card *card = &audiosense_pi_card; -+ struct snd_soc_dai_link *dai = &audiosense_pi_card_dai[0]; -+ struct device_node *i2s_node = pdev->dev.of_node; -+ -+ card->dev = &pdev->dev; -+ -+ if (!dai) { -+ dev_err(&pdev->dev, "DAI not found. Missing or Invalid\n"); -+ return -EINVAL; -+ } -+ -+ i2s_node = of_parse_phandle(pdev->dev.of_node, "i2s-controller", 0); -+ if (!i2s_node) { -+ dev_err(&pdev->dev, -+ "Property 'i2s-controller' 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); -+ -+ 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 audiosense_pi_card_remove(struct platform_device *pdev) -+{ -+ struct snd_soc_card *card = platform_get_drvdata(pdev); -+ -+ return snd_soc_unregister_card(card); -+ -+} -+ -+static const struct of_device_id audiosense_pi_card_of_match[] = { -+ { .compatible = "as,audiosense-pi", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, audiosense_pi_card_of_match); -+ -+static struct platform_driver audiosense_pi_card_driver = { -+ .driver = { -+ .name = "audiosense-snd-card", -+ .owner = THIS_MODULE, -+ .of_match_table = audiosense_pi_card_of_match, -+ }, -+ .probe = audiosense_pi_card_probe, -+ .remove = audiosense_pi_card_remove, -+}; -+ -+module_platform_driver(audiosense_pi_card_driver); -+ -+MODULE_AUTHOR("Bhargav AK "); -+MODULE_DESCRIPTION("ASoC Driver for TLV320AIC3204 Audio"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:audiosense-pi"); -+ diff --git a/target/linux/brcm2708/patches-4.19/950-0302-configs-Add-CONFIG_USB_TMC-m.patch b/target/linux/brcm2708/patches-4.19/950-0302-configs-Add-CONFIG_USB_TMC-m.patch new file mode 100644 index 0000000000..0b3842206b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0302-configs-Add-CONFIG_USB_TMC-m.patch @@ -0,0 +1,70 @@ +From 3e9204fb393ff539359a1dd1da228d2817116f3a Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 14 Jan 2019 08:50:55 +0000 +Subject: [PATCH 302/725] configs: Add CONFIG_USB_TMC=m + +Enable the Test & Measurement Class USB driver module. + +See: https://github.com/raspberrypi/linux/firmware/issues/929 + +Signed-off-by: Phil Elwell +--- + arch/arm/configs/bcm2709_defconfig | 2 +- + arch/arm/configs/bcmrpi_defconfig | 2 +- + arch/arm64/configs/bcmrpi3_defconfig | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -1002,6 +1002,7 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + CONFIG_USB_MON=m + CONFIG_USB_DWCOTG=y + CONFIG_USB_PRINTER=m ++CONFIG_USB_TMC=m + CONFIG_USB_STORAGE=y + CONFIG_USB_STORAGE_REALTEK=m + CONFIG_USB_STORAGE_DATAFAB=m +@@ -1301,7 +1302,6 @@ CONFIG_CIFS=m + CONFIG_CIFS_WEAK_PW_HASH=y + CONFIG_CIFS_UPCALL=y + CONFIG_CIFS_XATTR=y +-CONFIG_CIFS_POSIX=y + CONFIG_CIFS_ACL=y + CONFIG_CIFS_DFS_UPCALL=y + CONFIG_CIFS_FSCACHE=y +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -995,6 +995,7 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + CONFIG_USB_MON=m + CONFIG_USB_DWCOTG=y + CONFIG_USB_PRINTER=m ++CONFIG_USB_TMC=m + CONFIG_USB_STORAGE=y + CONFIG_USB_STORAGE_REALTEK=m + CONFIG_USB_STORAGE_DATAFAB=m +@@ -1294,7 +1295,6 @@ CONFIG_CIFS=m + CONFIG_CIFS_WEAK_PW_HASH=y + CONFIG_CIFS_UPCALL=y + CONFIG_CIFS_XATTR=y +-CONFIG_CIFS_POSIX=y + CONFIG_CIFS_ACL=y + CONFIG_CIFS_DFS_UPCALL=y + CONFIG_CIFS_FSCACHE=y +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -871,6 +871,7 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + CONFIG_USB_MON=m + CONFIG_USB_DWCOTG=y + CONFIG_USB_PRINTER=m ++CONFIG_USB_TMC=m + CONFIG_USB_STORAGE=y + CONFIG_USB_STORAGE_REALTEK=m + CONFIG_USB_STORAGE_DATAFAB=m +@@ -1145,7 +1146,6 @@ CONFIG_CIFS=m + CONFIG_CIFS_WEAK_PW_HASH=y + CONFIG_CIFS_UPCALL=y + CONFIG_CIFS_XATTR=y +-CONFIG_CIFS_POSIX=y + CONFIG_CIFS_ACL=y + CONFIG_CIFS_DFS_UPCALL=y + CONFIG_CIFS_FSCACHE=y diff --git a/target/linux/brcm2708/patches-4.19/950-0303-BCM270X-Adding-device-tree-support-for-AudioSense-Pi.patch b/target/linux/brcm2708/patches-4.19/950-0303-BCM270X-Adding-device-tree-support-for-AudioSense-Pi.patch deleted file mode 100644 index 666da86998..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0303-BCM270X-Adding-device-tree-support-for-AudioSense-Pi.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 43f0013d9050a0011c05370c9b6123eb059f235b Mon Sep 17 00:00:00 2001 -From: b-ak -Date: Thu, 3 Jan 2019 00:29:14 +0530 -Subject: [PATCH 303/703] BCM270X: Adding device tree support for AudioSense-Pi - add-on soundcard - -Device tree overlay for AudioSense-Pi card. - -To enable support for the hardware add the following -line to the RPi /boot/config.txt: - - dtoverlay=audiosense-pi - -More documentation @ arch/arm/boot/dts/overlays/README - -Signed-off-by: b-ak ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 8 ++ - .../dts/overlays/audiosense-pi-overlay.dts | 82 +++++++++++++++++++ - 3 files changed, 91 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/audiosense-pi-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -20,6 +20,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - audioinjector-addons.dtbo \ - audioinjector-ultra.dtbo \ - audioinjector-wm8731-audio.dtbo \ -+ audiosense-pi.dtbo \ - audremap.dtbo \ - balena-fin.dtbo \ - bmp085_i2c-sensor.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -453,6 +453,14 @@ Load: dtoverlay=audioinjector-wm8731-a - Params: - - -+Name: audiosense-pi -+Info: Configures the audiosense-pi add on soundcard -+ For more information refer to -+ https://gitlab.com/kakar0t/audiosense-pi -+Load: dtoverlay=audiosense-pi -+Params: -+ -+ - Name: audremap - Info: Switches PWM sound output to pins 12 (Right) & 13 (Left) - Load: dtoverlay=audremap,= ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/audiosense-pi-overlay.dts -@@ -0,0 +1,82 @@ -+// Definitions for audiosense add on soundcard -+/dts-v1/; -+/plugin/; -+#include -+#include -+ -+/ { -+ compatible = "brcm,bcm2837", "brcm,bcm2836", "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target-path = "/"; -+ __overlay__ { -+ codec_reg_1v8: codec-reg-1v8 { -+ compatible = "regulator-fixed"; -+ regulator-name = "tlv320aic3204_1v8"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&gpio>; -+ __overlay__ { -+ codec_rst: codec-rst { -+ brcm,pins = <26>; -+ brcm,function = ; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ /* audio external oscillator */ -+ codec_osc: codec_osc { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <12000000>; /* 12 MHz */ -+ }; -+ -+ codec: tlv320aic32x4@18 { -+ #sound-dai-cells = <0>; -+ compatible = "ti,tlv320aic32x4"; -+ reg = <0x18>; -+ -+ clocks = <&codec_osc>; -+ clock-names = "mclk"; -+ -+ iov-supply = <&vdd_3v3_reg>; -+ ldoin-supply = <&vdd_3v3_reg>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ reset-gpios = <&gpio 26 GPIO_ACTIVE_HIGH>; -+ -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "as,audiosense-pi"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+}; diff --git a/target/linux/brcm2708/patches-4.19/950-0303-overlays-sdio-Add-enhanced-1-bit-support.patch b/target/linux/brcm2708/patches-4.19/950-0303-overlays-sdio-Add-enhanced-1-bit-support.patch new file mode 100644 index 0000000000..6edbed1b57 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0303-overlays-sdio-Add-enhanced-1-bit-support.patch @@ -0,0 +1,107 @@ +From d92f631ece6e1fca95462d8b0ffd3fee97be257a Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 10 Jan 2019 15:27:56 +0000 +Subject: [PATCH 303/725] overlays: sdio: Add enhanced 1-bit support + +"dtoverlay=sdio,bus_width=1,gpios_22_25" is equivalent to the sdio-1bit +overlay, which is now deprecated. + +"dtoverlay=sdio,bus_width=1,gpios_34_37" enables 1-bit mode on GPIOs 34-37. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/README | 24 +++++++++++---------- + arch/arm/boot/dts/overlays/sdio-overlay.dts | 20 ++++++++++++++++- + 2 files changed, 32 insertions(+), 12 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -479,8 +479,7 @@ Params: + + Name: bmp085_i2c-sensor + Info: This overlay is now deprecated - see i2c-sensor +-Load: dtoverlay=bmp085_i2c-sensor +-Params: ++Load: + + + Name: dht11 +@@ -1737,7 +1736,8 @@ Params: overclock_50 Clock (i + + Name: sdio + Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, +- and enables SDIO via GPIOs 22-27. ++ and enables SDIO via GPIOs 22-27. An example of use in 1-bit mode is ++ "dtoverlay=sdio,bus_width=1,gpios_22_25" + Load: dtoverlay=sdio,= + Params: sdio_overclock SDIO Clock (in MHz) to use when the MMC + framework requests 50MHz +@@ -1747,16 +1747,18 @@ Params: sdio_overclock SDIO Clo + + bus_width Set the SDIO host bus width (default 4 bits) + ++ gpios_22_25 Select GPIOs 22-25 for 1-bit mode. Must be used ++ with bus_width=1. This replaces the sdio-1bit ++ overlay, which is now deprecated. + +-Name: sdio-1bit +-Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, +- and enables 1-bit SDIO via GPIOs 22-25. +-Load: dtoverlay=sdio-1bit,= +-Params: sdio_overclock SDIO Clock (in MHz) to use when the MMC +- framework requests 50MHz ++ gpios_34_37 Select GPIOs 34-37 for 1-bit mode. Must be used ++ with bus_width=1. + +- poll_once Disable SDIO-device polling every second +- (default on: polling once at boot-time) ++ ++Name: sdio-1bit ++Info: This overlay is now deprecated. Use ++ "dtoverlay=sdio,bus_width=1,gpios_22_25" instead. ++Load: + + + Name: sdtweak +--- a/arch/arm/boot/dts/overlays/sdio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts +@@ -32,7 +32,7 @@ + pinctrl-names = "default"; + pinctrl-0 = <&sdio_ovl_pins>; + non-removable; +- bus-width = <1>; ++ bus-width = <4>; + }; + }; + }; +@@ -49,6 +49,22 @@ + }; + + fragment@3 { ++ target = <&sdio_ovl_pins>; ++ __dormant__ { ++ brcm,pins = <22 23 24 25>; ++ brcm,pull = <0 2 2 2>; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&sdio_ovl_pins>; ++ __dormant__ { ++ brcm,pins = <34 35 36 37>; ++ brcm,pull = <0 2 2 2>; ++ }; ++ }; ++ ++ fragment@6 { + target-path = "/aliases"; + __overlay__ { + mmc1 = "/soc/sdio@7e300000"; +@@ -59,5 +75,7 @@ + poll_once = <&sdio_ovl>,"non-removable?"; + bus_width = <&sdio_ovl>,"bus-width:0"; + sdio_overclock = <&sdio_ovl>,"brcm,overclock-50:0"; ++ gpios_22_25 = <0>,"=3"; ++ gpios_34_37 = <0>,"=4"; + }; + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0304-configs-Add-CONFIG_SND_AUDIOSENSE_PI-m.patch b/target/linux/brcm2708/patches-4.19/950-0304-configs-Add-CONFIG_SND_AUDIOSENSE_PI-m.patch deleted file mode 100644 index 16174c7d37..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0304-configs-Add-CONFIG_SND_AUDIOSENSE_PI-m.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 3e7e88225ea313a8a79773383b4004b714b07bc2 Mon Sep 17 00:00:00 2001 -From: b-ak -Date: Fri, 4 Jan 2019 00:12:51 +0530 -Subject: [PATCH 304/703] configs: Add CONFIG_SND_AUDIOSENSE_PI=m - -AudioSense-Pi add on soundcard configuration definitions - -Signed-off-by: b-ak ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - arch/arm64/configs/bcmrpi3_defconfig | 1 + - 3 files changed, 3 insertions(+) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -918,6 +918,7 @@ CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m - CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m - CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m - CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m -+CONFIG_SND_AUDIOSENSE_PI=m - CONFIG_SND_DIGIDAC1_SOUNDCARD=m - CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m - CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -911,6 +911,7 @@ CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m - CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m - CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m - CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m -+CONFIG_SND_AUDIOSENSE_PI=m - CONFIG_SND_DIGIDAC1_SOUNDCARD=m - CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m - CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -800,6 +800,7 @@ CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m - CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m - CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m -+CONFIG_SND_AUDIOSENSE_PI=m - CONFIG_SND_DIGIDAC1_SOUNDCARD=m - CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m - CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m diff --git a/target/linux/brcm2708/patches-4.19/950-0304-dwc_otg-fix-bug-with-port_addr-assignment-for-single.patch b/target/linux/brcm2708/patches-4.19/950-0304-dwc_otg-fix-bug-with-port_addr-assignment-for-single.patch new file mode 100644 index 0000000000..47e49c85b4 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0304-dwc_otg-fix-bug-with-port_addr-assignment-for-single.patch @@ -0,0 +1,28 @@ +From 0384e9ec7b5a3d8e6e2162ce8adf019d0f5c94cf Mon Sep 17 00:00:00 2001 +From: P33M +Date: Wed, 16 Jan 2019 10:17:52 +0000 +Subject: [PATCH 304/725] dwc_otg: fix bug with port_addr assignment for + single-TT hubs + +See https://github.com/raspberrypi/linux/issues/2734 + +The "Hub Port" field in the split transaction packet was always set +to 1 for single-TT hubs. The majority of single-TT hub products +apparently ignore this field and broadcast to all downstream enabled +ports, which masked the issue. A subset of hub devices apparently +need the port number to be exact or split transactions will fail. +--- + drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c +@@ -232,7 +232,7 @@ static int _hub_info(dwc_otg_hcd_t * hcd + else + *hub_addr = urb->dev->tt->hub->devnum; + } +- *port_addr = urb->dev->tt->multi ? urb->dev->ttport : 1; ++ *port_addr = urb->dev->ttport; + } else { + *hub_addr = 0; + *port_addr = urb->dev->ttport; diff --git a/target/linux/brcm2708/patches-4.19/950-0305-configs-Add-CONFIG_USB_TMC-m.patch b/target/linux/brcm2708/patches-4.19/950-0305-configs-Add-CONFIG_USB_TMC-m.patch deleted file mode 100644 index 48ea4c6426..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0305-configs-Add-CONFIG_USB_TMC-m.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 5822a95be9ca76e9f467392f9010fd10635f86cd Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 14 Jan 2019 08:50:55 +0000 -Subject: [PATCH 305/703] configs: Add CONFIG_USB_TMC=m - -Enable the Test & Measurement Class USB driver module. - -See: https://github.com/raspberrypi/linux/firmware/issues/929 - -Signed-off-by: Phil Elwell ---- - arch/arm/configs/bcm2709_defconfig | 2 +- - arch/arm/configs/bcmrpi_defconfig | 2 +- - arch/arm64/configs/bcmrpi3_defconfig | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1002,6 +1002,7 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y - CONFIG_USB_MON=m - CONFIG_USB_DWCOTG=y - CONFIG_USB_PRINTER=m -+CONFIG_USB_TMC=m - CONFIG_USB_STORAGE=y - CONFIG_USB_STORAGE_REALTEK=m - CONFIG_USB_STORAGE_DATAFAB=m -@@ -1301,7 +1302,6 @@ CONFIG_CIFS=m - CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_CIFS_UPCALL=y - CONFIG_CIFS_XATTR=y --CONFIG_CIFS_POSIX=y - CONFIG_CIFS_ACL=y - CONFIG_CIFS_DFS_UPCALL=y - CONFIG_CIFS_FSCACHE=y ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -995,6 +995,7 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y - CONFIG_USB_MON=m - CONFIG_USB_DWCOTG=y - CONFIG_USB_PRINTER=m -+CONFIG_USB_TMC=m - CONFIG_USB_STORAGE=y - CONFIG_USB_STORAGE_REALTEK=m - CONFIG_USB_STORAGE_DATAFAB=m -@@ -1294,7 +1295,6 @@ CONFIG_CIFS=m - CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_CIFS_UPCALL=y - CONFIG_CIFS_XATTR=y --CONFIG_CIFS_POSIX=y - CONFIG_CIFS_ACL=y - CONFIG_CIFS_DFS_UPCALL=y - CONFIG_CIFS_FSCACHE=y ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -871,6 +871,7 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y - CONFIG_USB_MON=m - CONFIG_USB_DWCOTG=y - CONFIG_USB_PRINTER=m -+CONFIG_USB_TMC=m - CONFIG_USB_STORAGE=y - CONFIG_USB_STORAGE_REALTEK=m - CONFIG_USB_STORAGE_DATAFAB=m -@@ -1145,7 +1146,6 @@ CONFIG_CIFS=m - CONFIG_CIFS_WEAK_PW_HASH=y - CONFIG_CIFS_UPCALL=y - CONFIG_CIFS_XATTR=y --CONFIG_CIFS_POSIX=y - CONFIG_CIFS_ACL=y - CONFIG_CIFS_DFS_UPCALL=y - CONFIG_CIFS_FSCACHE=y diff --git a/target/linux/brcm2708/patches-4.19/950-0305-configs-Add-CONFIG_USB_UAS-m.patch b/target/linux/brcm2708/patches-4.19/950-0305-configs-Add-CONFIG_USB_UAS-m.patch new file mode 100644 index 0000000000..e16a8ab607 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0305-configs-Add-CONFIG_USB_UAS-m.patch @@ -0,0 +1,46 @@ +From e775807c64a610be5f2fcb82e152109d9b9d30f8 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 16 Jan 2019 21:26:13 +0000 +Subject: [PATCH 305/725] configs: Add CONFIG_USB_UAS=m + +Enable support for USB-attached-SCSI devicess. + +See: https://github.com/raspberrypi/linux/issues/2813 + +Signed-off-by: Phil Elwell +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + arch/arm64/configs/bcmrpi3_defconfig | 1 + + 3 files changed, 3 insertions(+) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -1017,6 +1017,7 @@ CONFIG_USB_STORAGE_ONETOUCH=m + CONFIG_USB_STORAGE_KARMA=m + CONFIG_USB_STORAGE_CYPRESS_ATACB=m + CONFIG_USB_STORAGE_ENE_UB6250=m ++CONFIG_USB_UAS=m + CONFIG_USB_MDC800=m + CONFIG_USB_MICROTEK=m + CONFIG_USBIP_CORE=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -1010,6 +1010,7 @@ CONFIG_USB_STORAGE_ONETOUCH=m + CONFIG_USB_STORAGE_KARMA=m + CONFIG_USB_STORAGE_CYPRESS_ATACB=m + CONFIG_USB_STORAGE_ENE_UB6250=m ++CONFIG_USB_UAS=m + CONFIG_USB_MDC800=m + CONFIG_USB_MICROTEK=m + CONFIG_USBIP_CORE=m +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -886,6 +886,7 @@ CONFIG_USB_STORAGE_ONETOUCH=m + CONFIG_USB_STORAGE_KARMA=m + CONFIG_USB_STORAGE_CYPRESS_ATACB=m + CONFIG_USB_STORAGE_ENE_UB6250=m ++CONFIG_USB_UAS=m + CONFIG_USB_MDC800=m + CONFIG_USB_MICROTEK=m + CONFIG_USBIP_CORE=m diff --git a/target/linux/brcm2708/patches-4.19/950-0306-Added-driver-for-the-HiFiBerry-DAC-ADC-2694.patch b/target/linux/brcm2708/patches-4.19/950-0306-Added-driver-for-the-HiFiBerry-DAC-ADC-2694.patch new file mode 100644 index 0000000000..84fed7fadc --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0306-Added-driver-for-the-HiFiBerry-DAC-ADC-2694.patch @@ -0,0 +1,598 @@ +From a4bda3453c292c7b75ca0e3163daa7879d5fa952 Mon Sep 17 00:00:00 2001 +From: HiFiBerry +Date: Mon, 8 Oct 2018 18:10:12 +0200 +Subject: [PATCH 306/725] Added driver for the HiFiBerry DAC+ ADC (#2694) + +Signed-off-by: Daniel Matuschek +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 21 + + .../overlays/hifiberry-dacplusadc-overlay.dts | 71 +++ + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + sound/soc/bcm/Kconfig | 8 + + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/hifiberry_dacplusadc.c | 407 ++++++++++++++++++ + 8 files changed, 512 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dacplusadc-overlay.dts + create mode 100644 sound/soc/bcm/hifiberry_dacplusadc.c + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -49,6 +49,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + hifiberry-amp.dtbo \ + hifiberry-dac.dtbo \ + hifiberry-dacplus.dtbo \ ++ hifiberry-dacplusadc.dtbo \ + hifiberry-digi.dtbo \ + hifiberry-digi-pro.dtbo \ + hy28a.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -779,6 +779,27 @@ Params: 24db_digital_gain Allow ga + master for bit clock and frame clock. + + ++Name: hifiberry-dacplusadc ++Info: Configures the HifiBerry DAC+ADC audio card ++Load: dtoverlay=hifiberry-dacplusadc,= ++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!) ++ slave Force DAC+ Pro into slave mode, using Pi as ++ master for bit clock and frame clock. ++ ++ + Name: hifiberry-digi + Info: Configures the HifiBerry Digi and Digi+ audio card + Load: dtoverlay=hifiberry-digi +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/hifiberry-dacplusadc-overlay.dts +@@ -0,0 +1,71 @@ ++// Definitions for HiFiBerry DAC+ADC ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/clocks"; ++ __overlay__ { ++ dacpro_osc: dacpro_osc { ++ compatible = "hifiberry,dacpro-clk"; ++ #clock-cells = <0>; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pcm_codec: pcm5122@4d { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm5122"; ++ reg = <0x4d>; ++ clocks = <&dacpro_osc>; ++ AVDD-supply = <&vdd_3v3_reg>; ++ DVDD-supply = <&vdd_3v3_reg>; ++ CPVDD-supply = <&vdd_3v3_reg>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target-path = "/"; ++ __overlay__ { ++ dmic { ++ #sound-dai-cells = <0>; ++ compatible = "dmic-codec"; ++ num-channels = <2>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&sound>; ++ hifiberry_dacplusadc: __overlay__ { ++ compatible = "hifiberry,hifiberry-dacplusadc"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ 24db_digital_gain = ++ <&hifiberry_dacplusadc>,"hifiberry,24db_digital_gain?"; ++ slave = <&hifiberry_dacplusadc>,"hifiberry-dacplusadc,slave?"; ++ }; ++}; +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -905,6 +905,7 @@ CONFIG_SND_BCM2835_SOC_I2S=m + CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER=m + CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -898,6 +898,7 @@ CONFIG_SND_BCM2835_SOC_I2S=m + CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER=m + CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -46,6 +46,14 @@ config SND_BCM2708_SOC_HIFIBERRY_DACPLUS + help + Say Y or M if you want to add support for HifiBerry DAC+. + ++config SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC ++ tristate "Support for HifiBerry DAC+ADC" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_PCM512x_I2C ++ select SND_SOC_DMIC ++ help ++ Say Y or M if you want to add support for HifiBerry DAC+ADC. ++ + config SND_BCM2708_SOC_HIFIBERRY_DIGI + tristate "Support for HifiBerry Digi" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -14,6 +14,7 @@ snd-soc-googlevoicehat-codec-objs := goo + # BCM2708 Machine Support + snd-soc-3dlab-nano-player-objs := 3dlab-nano-player.o + snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o ++snd-soc-hifiberry-dacplusadc-objs := hifiberry_dacplusadc.o + snd-soc-justboom-dac-objs := justboom-dac.o + snd-soc-rpi-cirrus-objs := rpi-cirrus.o + snd-soc-rpi-proto-objs := rpi-proto.o +@@ -36,6 +37,7 @@ snd-soc-rpi-wm8804-soundcard-objs := rpi + obj-$(CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER) += snd-soc-3dlab-nano-player.o + obj-$(CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD) += snd-soc-googlevoicehat-codec.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o ++obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC) += snd-soc-hifiberry-dacplusadc.o + obj-$(CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC) += snd-soc-justboom-dac.o + obj-$(CONFIG_SND_BCM2708_SOC_RPI_CIRRUS) += snd-soc-rpi-cirrus.o + obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o +--- /dev/null ++++ b/sound/soc/bcm/hifiberry_dacplusadc.c +@@ -0,0 +1,407 @@ ++/* ++ * ASoC Driver for HiFiBerry DAC+ / DAC Pro with ADC ++ * ++ * Author: Daniel Matuschek, Stuart MacLean ++ * Copyright 2014-2015 ++ * based on code by Florian Meier ++ * ADC added by Joerg Schambacher ++ * Copyright 2018 ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "../codecs/pcm512x.h" ++ ++#define HIFIBERRY_DACPRO_NOCLOCK 0 ++#define HIFIBERRY_DACPRO_CLK44EN 1 ++#define HIFIBERRY_DACPRO_CLK48EN 2 ++ ++struct platform_device *dmic_codec_dev; ++ ++struct pcm512x_priv { ++ struct regmap *regmap; ++ struct clk *sclk; ++}; ++ ++/* Clock rate of CLK44EN attached to GPIO6 pin */ ++#define CLK_44EN_RATE 22579200UL ++/* Clock rate of CLK48EN attached to GPIO3 pin */ ++#define CLK_48EN_RATE 24576000UL ++ ++static bool slave; ++static bool snd_rpi_hifiberry_is_dacpro; ++static bool digital_gain_0db_limit = true; ++ ++static void snd_rpi_hifiberry_dacplusadc_select_clk(struct snd_soc_component *component, ++ int clk_id) ++{ ++ switch (clk_id) { ++ case HIFIBERRY_DACPRO_NOCLOCK: ++ snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x24, 0x00); ++ break; ++ case HIFIBERRY_DACPRO_CLK44EN: ++ snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x24, 0x20); ++ break; ++ case HIFIBERRY_DACPRO_CLK48EN: ++ snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x24, 0x04); ++ break; ++ } ++} ++ ++static void snd_rpi_hifiberry_dacplusadc_clk_gpio(struct snd_soc_component *component) ++{ ++ snd_soc_component_update_bits(component, PCM512x_GPIO_EN, 0x24, 0x24); ++ snd_soc_component_update_bits(component, PCM512x_GPIO_OUTPUT_3, 0x0f, 0x02); ++ snd_soc_component_update_bits(component, PCM512x_GPIO_OUTPUT_6, 0x0f, 0x02); ++} ++ ++static bool snd_rpi_hifiberry_dacplusadc_is_sclk(struct snd_soc_component *component) ++{ ++ unsigned int sck; ++ ++ snd_soc_component_read(component, PCM512x_RATE_DET_4, &sck); ++ return (!(sck & 0x40)); ++} ++ ++static bool snd_rpi_hifiberry_dacplusadc_is_sclk_sleep( ++ struct snd_soc_component *component) ++{ ++ msleep(2); ++ return snd_rpi_hifiberry_dacplusadc_is_sclk(component); ++} ++ ++static bool snd_rpi_hifiberry_dacplusadc_is_pro_card(struct snd_soc_component *component) ++{ ++ bool isClk44EN, isClk48En, isNoClk; ++ ++ snd_rpi_hifiberry_dacplusadc_clk_gpio(component); ++ ++ snd_rpi_hifiberry_dacplusadc_select_clk(component, HIFIBERRY_DACPRO_CLK44EN); ++ isClk44EN = snd_rpi_hifiberry_dacplusadc_is_sclk_sleep(component); ++ ++ snd_rpi_hifiberry_dacplusadc_select_clk(component, HIFIBERRY_DACPRO_NOCLOCK); ++ isNoClk = snd_rpi_hifiberry_dacplusadc_is_sclk_sleep(component); ++ ++ snd_rpi_hifiberry_dacplusadc_select_clk(component, HIFIBERRY_DACPRO_CLK48EN); ++ isClk48En = snd_rpi_hifiberry_dacplusadc_is_sclk_sleep(component); ++ ++ return (isClk44EN && isClk48En && !isNoClk); ++} ++ ++static int snd_rpi_hifiberry_dacplusadc_clk_for_rate(int sample_rate) ++{ ++ int type; ++ ++ switch (sample_rate) { ++ case 11025: ++ case 22050: ++ case 44100: ++ case 88200: ++ case 176400: ++ case 352800: ++ type = HIFIBERRY_DACPRO_CLK44EN; ++ break; ++ default: ++ type = HIFIBERRY_DACPRO_CLK48EN; ++ break; ++ } ++ return type; ++} ++ ++static void snd_rpi_hifiberry_dacplusadc_set_sclk(struct snd_soc_component *component, ++ int sample_rate) ++{ ++ struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component); ++ ++ if (!IS_ERR(pcm512x->sclk)) { ++ int ctype; ++ ++ ctype = snd_rpi_hifiberry_dacplusadc_clk_for_rate(sample_rate); ++ clk_set_rate(pcm512x->sclk, (ctype == HIFIBERRY_DACPRO_CLK44EN) ++ ? CLK_44EN_RATE : CLK_48EN_RATE); ++ snd_rpi_hifiberry_dacplusadc_select_clk(component, ctype); ++ } ++} ++ ++static int snd_rpi_hifiberry_dacplusadc_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ struct snd_soc_component *component = rtd->codec_dai->component; ++ struct pcm512x_priv *priv; ++ ++ if (slave) ++ snd_rpi_hifiberry_is_dacpro = false; ++ else ++ snd_rpi_hifiberry_is_dacpro = ++ snd_rpi_hifiberry_dacplusadc_is_pro_card(component); ++ ++ if (snd_rpi_hifiberry_is_dacpro) { ++ struct snd_soc_dai_link *dai = rtd->dai_link; ++ ++ dai->name = "HiFiBerry ADCDAC+ Pro"; ++ dai->stream_name = "HiFiBerry ADCDAC+ Pro HiFi"; ++ dai->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF ++ | SND_SOC_DAIFMT_CBM_CFM; ++ ++ snd_soc_component_update_bits(component, PCM512x_BCLK_LRCLK_CFG, 0x31, 0x11); ++ snd_soc_component_update_bits(component, PCM512x_MASTER_MODE, 0x03, 0x03); ++ snd_soc_component_update_bits(component, PCM512x_MASTER_CLKDIV_2, 0x7f, 63); ++ } else { ++ priv = snd_soc_component_get_drvdata(component); ++ priv->sclk = ERR_PTR(-ENOENT); ++ } ++ ++ snd_soc_component_update_bits(component, PCM512x_GPIO_EN, 0x08, 0x08); ++ snd_soc_component_update_bits(component, PCM512x_GPIO_OUTPUT_4, 0x0f, 0x02); ++ snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); ++ ++ 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_hifiberry_dacplusadc_update_rate_den( ++ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_component *component = rtd->codec_dai->component; ++ struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component); ++ struct snd_ratnum *rats_no_pll; ++ unsigned int num = 0, den = 0; ++ int err; ++ ++ rats_no_pll = devm_kzalloc(rtd->dev, sizeof(*rats_no_pll), GFP_KERNEL); ++ if (!rats_no_pll) ++ return -ENOMEM; ++ ++ rats_no_pll->num = clk_get_rate(pcm512x->sclk) / 64; ++ rats_no_pll->den_min = 1; ++ rats_no_pll->den_max = 128; ++ rats_no_pll->den_step = 1; ++ ++ err = snd_interval_ratnum(hw_param_interval(params, ++ SNDRV_PCM_HW_PARAM_RATE), 1, rats_no_pll, &num, &den); ++ if (err >= 0 && den) { ++ params->rate_num = num; ++ params->rate_den = den; ++ } ++ ++ devm_kfree(rtd->dev, rats_no_pll); ++ return 0; ++} ++ ++static int snd_rpi_hifiberry_dacplusadc_hw_params( ++ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) ++{ ++ int ret = 0; ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ int channels = params_channels(params); ++ int width = 32; ++ ++ if (snd_rpi_hifiberry_is_dacpro) { ++ struct snd_soc_component *component = rtd->codec_dai->component; ++ ++ width = snd_pcm_format_physical_width(params_format(params)); ++ ++ snd_rpi_hifiberry_dacplusadc_set_sclk(component, ++ params_rate(params)); ++ ++ ret = snd_rpi_hifiberry_dacplusadc_update_rate_den( ++ substream, params); ++ } ++ ++ ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x03, 0x03, ++ channels, width); ++ if (ret) ++ return ret; ++ ret = snd_soc_dai_set_tdm_slot(rtd->codec_dai, 0x03, 0x03, ++ channels, width); ++ return ret; ++} ++ ++static int hifiberry_dacplusadc_LED_cnt; ++ ++static int snd_rpi_hifiberry_dacplusadc_startup( ++ struct snd_pcm_substream *substream) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_component *component = rtd->codec_dai->component; ++ ++ snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, ++ 0x08, 0x08); ++ hifiberry_dacplusadc_LED_cnt++; ++ return 0; ++} ++ ++static void snd_rpi_hifiberry_dacplusadc_shutdown( ++ struct snd_pcm_substream *substream) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_component *component = rtd->codec_dai->component; ++ ++ hifiberry_dacplusadc_LED_cnt--; ++ if (!hifiberry_dacplusadc_LED_cnt) ++ snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, ++ 0x08, 0x00); ++} ++ ++/* machine stream operations */ ++static struct snd_soc_ops snd_rpi_hifiberry_dacplusadc_ops = { ++ .hw_params = snd_rpi_hifiberry_dacplusadc_hw_params, ++ .startup = snd_rpi_hifiberry_dacplusadc_startup, ++ .shutdown = snd_rpi_hifiberry_dacplusadc_shutdown, ++}; ++ ++static struct snd_soc_dai_link_component snd_rpi_hifiberry_dacplusadc_codecs[] = { ++ { ++ .name = "pcm512x.1-004d", ++ .dai_name = "pcm512x-hifi", ++ }, ++ { ++ .name = "dmic-codec", ++ .dai_name = "dmic-hifi", ++ }, ++}; ++ ++static struct snd_soc_dai_link snd_rpi_hifiberry_dacplusadc_dai[] = { ++{ ++ .name = "HiFiBerry DAC+ADC", ++ .stream_name = "HiFiBerry DAC+ADC HiFi", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .platform_name = "bcm2708-i2s.0", ++ .codecs = snd_rpi_hifiberry_dacplusadc_codecs, ++ .num_codecs = 2, ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS, ++ .ops = &snd_rpi_hifiberry_dacplusadc_ops, ++ .init = snd_rpi_hifiberry_dacplusadc_init, ++}, ++}; ++ ++/* audio machine driver */ ++static struct snd_soc_card snd_rpi_hifiberry_dacplusadc = { ++ .name = "snd_rpi_hifiberry_dacplusadc", ++ .driver_name = "HifiberryDacpAdc", ++ .owner = THIS_MODULE, ++ .dai_link = snd_rpi_hifiberry_dacplusadc_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dacplusadc_dai), ++}; ++ ++ ++static int snd_rpi_hifiberry_dacplusadc_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ snd_rpi_hifiberry_dacplusadc.dev = &pdev->dev; ++ if (pdev->dev.of_node) { ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai; ++ ++ dai = &snd_rpi_hifiberry_dacplusadc_dai[0]; ++ i2s_node = of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ if (i2s_node) { ++ dai->cpu_of_node = i2s_node; ++ dai->platform_of_node = i2s_node; ++ dai->cpu_dai_name = NULL; ++ dai->platform_name = NULL; ++ } ++ dai = &snd_rpi_hifiberry_dacplusadc_dai[1]; ++ i2s_node = of_parse_phandle(pdev->dev.of_node, "dmic", 0); ++ if (i2s_node) { ++ dai->cpu_of_node = i2s_node; ++ dai->platform_of_node = i2s_node; ++ } ++ ++ } ++ digital_gain_0db_limit = !of_property_read_bool( ++ pdev->dev.of_node, "hifiberry,24db_digital_gain"); ++ slave = of_property_read_bool(pdev->dev.of_node, ++ "hifiberry-dacplusadc,slave"); ++ ++ ret = devm_snd_soc_register_card(&pdev->dev, ++ &snd_rpi_hifiberry_dacplusadc); ++ if (ret && ret != -EPROBE_DEFER) ++ dev_err(&pdev->dev, ++ "snd_soc_register_card() failed: %d\n", ret); ++ ++ return ret; ++} ++ ++static const struct of_device_id snd_rpi_hifiberry_dacplusadc_of_match[] = { ++ { .compatible = "hifiberry,hifiberry-dacplusadc", }, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_dacplusadc_of_match); ++ ++static struct platform_driver snd_rpi_hifiberry_dacplusadc_driver = { ++ .driver = { ++ .name = "snd-rpi-hifiberry-dacplusadc", ++ .owner = THIS_MODULE, ++ .of_match_table = snd_rpi_hifiberry_dacplusadc_of_match, ++ }, ++ .probe = snd_rpi_hifiberry_dacplusadc_probe, ++}; ++ ++static int __init hifiberry_dacplusadc_init(void) ++{ ++ int ret; ++ ++ dmic_codec_dev = platform_device_register_simple("dmic-codec", -1, NULL, ++ 0); ++ if (IS_ERR(dmic_codec_dev)) { ++ pr_err("%s: dmic-codec device registration failed\n", __func__); ++ return PTR_ERR(dmic_codec_dev); ++ } ++ ++ ret = platform_driver_register(&snd_rpi_hifiberry_dacplusadc_driver); ++ if (ret) { ++ pr_err("%s: platform driver registration failed\n", __func__); ++ platform_device_unregister(dmic_codec_dev); ++ } ++ ++ return ret; ++} ++module_init(hifiberry_dacplusadc_init); ++ ++static void __exit hifiberry_dacplusadc_exit(void) ++{ ++ platform_driver_unregister(&snd_rpi_hifiberry_dacplusadc_driver); ++ platform_device_unregister(dmic_codec_dev); ++} ++module_exit(hifiberry_dacplusadc_exit); ++ ++MODULE_AUTHOR("Joerg Schambacher "); ++MODULE_AUTHOR("Daniel Matuschek "); ++MODULE_DESCRIPTION("ASoC Driver for HiFiBerry DAC+ADC"); ++MODULE_LICENSE("GPL v2"); diff --git a/target/linux/brcm2708/patches-4.19/950-0306-overlays-sdio-Add-enhanced-1-bit-support.patch b/target/linux/brcm2708/patches-4.19/950-0306-overlays-sdio-Add-enhanced-1-bit-support.patch deleted file mode 100644 index 9a95c58740..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0306-overlays-sdio-Add-enhanced-1-bit-support.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 510aeba93fa3dde1e2890d49409bd1be2d72f3fe Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 10 Jan 2019 15:27:56 +0000 -Subject: [PATCH 306/703] overlays: sdio: Add enhanced 1-bit support - -"dtoverlay=sdio,bus_width=1,gpios_22_25" is equivalent to the sdio-1bit -overlay, which is now deprecated. - -"dtoverlay=sdio,bus_width=1,gpios_34_37" enables 1-bit mode on GPIOs 34-37. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/README | 24 +++++++++++---------- - arch/arm/boot/dts/overlays/sdio-overlay.dts | 20 ++++++++++++++++- - 2 files changed, 32 insertions(+), 12 deletions(-) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -479,8 +479,7 @@ Params: - - Name: bmp085_i2c-sensor - Info: This overlay is now deprecated - see i2c-sensor --Load: dtoverlay=bmp085_i2c-sensor --Params: -+Load: - - - Name: dht11 -@@ -1737,7 +1736,8 @@ Params: overclock_50 Clock (i - - Name: sdio - Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, -- and enables SDIO via GPIOs 22-27. -+ and enables SDIO via GPIOs 22-27. An example of use in 1-bit mode is -+ "dtoverlay=sdio,bus_width=1,gpios_22_25" - Load: dtoverlay=sdio,= - Params: sdio_overclock SDIO Clock (in MHz) to use when the MMC - framework requests 50MHz -@@ -1747,16 +1747,18 @@ Params: sdio_overclock SDIO Clo - - bus_width Set the SDIO host bus width (default 4 bits) - -+ gpios_22_25 Select GPIOs 22-25 for 1-bit mode. Must be used -+ with bus_width=1. This replaces the sdio-1bit -+ overlay, which is now deprecated. - --Name: sdio-1bit --Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock, -- and enables 1-bit SDIO via GPIOs 22-25. --Load: dtoverlay=sdio-1bit,= --Params: sdio_overclock SDIO Clock (in MHz) to use when the MMC -- framework requests 50MHz -+ gpios_34_37 Select GPIOs 34-37 for 1-bit mode. Must be used -+ with bus_width=1. - -- poll_once Disable SDIO-device polling every second -- (default on: polling once at boot-time) -+ -+Name: sdio-1bit -+Info: This overlay is now deprecated. Use -+ "dtoverlay=sdio,bus_width=1,gpios_22_25" instead. -+Load: - - - Name: sdtweak ---- a/arch/arm/boot/dts/overlays/sdio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts -@@ -32,7 +32,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&sdio_ovl_pins>; - non-removable; -- bus-width = <1>; -+ bus-width = <4>; - }; - }; - }; -@@ -49,6 +49,22 @@ - }; - - fragment@3 { -+ target = <&sdio_ovl_pins>; -+ __dormant__ { -+ brcm,pins = <22 23 24 25>; -+ brcm,pull = <0 2 2 2>; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&sdio_ovl_pins>; -+ __dormant__ { -+ brcm,pins = <34 35 36 37>; -+ brcm,pull = <0 2 2 2>; -+ }; -+ }; -+ -+ fragment@6 { - target-path = "/aliases"; - __overlay__ { - mmc1 = "/soc/sdio@7e300000"; -@@ -59,5 +75,7 @@ - poll_once = <&sdio_ovl>,"non-removable?"; - bus_width = <&sdio_ovl>,"bus-width:0"; - sdio_overclock = <&sdio_ovl>,"brcm,overclock-50:0"; -+ gpios_22_25 = <0>,"=3"; -+ gpios_34_37 = <0>,"=4"; - }; - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0307-Revert-pwm-Set-class-for-exported-channels-in-sysfs.patch b/target/linux/brcm2708/patches-4.19/950-0307-Revert-pwm-Set-class-for-exported-channels-in-sysfs.patch new file mode 100644 index 0000000000..01dd6dc1f9 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0307-Revert-pwm-Set-class-for-exported-channels-in-sysfs.patch @@ -0,0 +1,63 @@ +From 01a031fa350f9fa197451a3b4aed04c43c46c50e Mon Sep 17 00:00:00 2001 +From: Fabrice Gasnier +Date: Mon, 1 Oct 2018 15:23:56 +0200 +Subject: [PATCH 307/725] Revert "pwm: Set class for exported channels in + sysfs" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit c289d6625237aa785b484b4e94c23b3b91ea7e60 upstream. + +This reverts commit 7e5d1fd75c3dde9fc10c4472b9368089d1b81d00 ("pwm: Set +class for exported channels in sysfs") as it causes regression with +multiple pwm chip[1], when exporting a pwm channel (echo X > export): + +- ABI (Documentation/ABI/testing/sysfs-class-pwm) states pwmX should be + created in /sys/class/pwm/pwmchipN/pwmX +- Reverted patch causes new entry to be also created directly in + /sys/class/pwm/pwmX +- 1st time, exporting pwmX will create an entry in /sys/class/pwm/pwmX +- class attributes are added under pwmX folder, such as export, unexport + npwm, symlinks. This is wrong as it belongs to pwmchipN. It may cause + bad behavior and report wrong values. +- when another export happens on another pwmchip, it can't be created + (e.g. -EEXIST). This is causing the issue with multiple pwmchip. + +Example on stm32 (stm32429i-eval) platform: +$ ls /sys/class/pwm +pwmchip0 pwmchip4 + +$ cd /sys/class/pwm/pwmchip0/ +$ echo 0 > export +$ ls /sys/class/pwm +pwm0 pwmchip0 pwmchip4 + +$ cd /sys/class/pwm/pwmchip4/ +$ echo 0 > export +sysfs: cannot create duplicate filename '/class/pwm/pwm0' +...Exception stack follows... + +This is also seen on other platform [2] + +[1] https://lkml.org/lkml/2018/9/25/713 +[2] https://lkml.org/lkml/2018/9/25/447 + +Signed-off-by: Fabrice Gasnier +Tested-by: Gottfried Haider +Tested-by: Michal Vokáč +Signed-off-by: Thierry Reding +--- + drivers/pwm/sysfs.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/pwm/sysfs.c ++++ b/drivers/pwm/sysfs.c +@@ -263,7 +263,6 @@ static int pwm_export_child(struct devic + export->pwm = pwm; + mutex_init(&export->lock); + +- export->child.class = parent->class; + export->child.release = pwm_export_release; + export->child.parent = parent; + export->child.devt = MKDEV(0, 0); diff --git a/target/linux/brcm2708/patches-4.19/950-0307-dwc_otg-fix-bug-with-port_addr-assignment-for-single.patch b/target/linux/brcm2708/patches-4.19/950-0307-dwc_otg-fix-bug-with-port_addr-assignment-for-single.patch deleted file mode 100644 index a52aafd634..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0307-dwc_otg-fix-bug-with-port_addr-assignment-for-single.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0efd687c78d47645956af472eac1b8d8f3a973d5 Mon Sep 17 00:00:00 2001 -From: P33M -Date: Wed, 16 Jan 2019 10:17:52 +0000 -Subject: [PATCH 307/703] dwc_otg: fix bug with port_addr assignment for - single-TT hubs - -See https://github.com/raspberrypi/linux/issues/2734 - -The "Hub Port" field in the split transaction packet was always set -to 1 for single-TT hubs. The majority of single-TT hub products -apparently ignore this field and broadcast to all downstream enabled -ports, which masked the issue. A subset of hub devices apparently -need the port number to be exact or split transactions will fail. ---- - drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -@@ -232,7 +232,7 @@ static int _hub_info(dwc_otg_hcd_t * hcd - else - *hub_addr = urb->dev->tt->hub->devnum; - } -- *port_addr = urb->dev->tt->multi ? urb->dev->ttport : 1; -+ *port_addr = urb->dev->ttport; - } else { - *hub_addr = 0; - *port_addr = urb->dev->ttport; diff --git a/target/linux/brcm2708/patches-4.19/950-0308-configs-Add-CONFIG_USB_UAS-m.patch b/target/linux/brcm2708/patches-4.19/950-0308-configs-Add-CONFIG_USB_UAS-m.patch deleted file mode 100644 index 57869cc5e3..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0308-configs-Add-CONFIG_USB_UAS-m.patch +++ /dev/null @@ -1,46 +0,0 @@ -From a87e24f59adb93d2701e56245adefe599e8eef86 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 16 Jan 2019 21:26:13 +0000 -Subject: [PATCH 308/703] configs: Add CONFIG_USB_UAS=m - -Enable support for USB-attached-SCSI devicess. - -See: https://github.com/raspberrypi/linux/issues/2813 - -Signed-off-by: Phil Elwell ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - arch/arm64/configs/bcmrpi3_defconfig | 1 + - 3 files changed, 3 insertions(+) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1017,6 +1017,7 @@ CONFIG_USB_STORAGE_ONETOUCH=m - CONFIG_USB_STORAGE_KARMA=m - CONFIG_USB_STORAGE_CYPRESS_ATACB=m - CONFIG_USB_STORAGE_ENE_UB6250=m -+CONFIG_USB_UAS=m - CONFIG_USB_MDC800=m - CONFIG_USB_MICROTEK=m - CONFIG_USBIP_CORE=m ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1010,6 +1010,7 @@ CONFIG_USB_STORAGE_ONETOUCH=m - CONFIG_USB_STORAGE_KARMA=m - CONFIG_USB_STORAGE_CYPRESS_ATACB=m - CONFIG_USB_STORAGE_ENE_UB6250=m -+CONFIG_USB_UAS=m - CONFIG_USB_MDC800=m - CONFIG_USB_MICROTEK=m - CONFIG_USBIP_CORE=m ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -886,6 +886,7 @@ CONFIG_USB_STORAGE_ONETOUCH=m - CONFIG_USB_STORAGE_KARMA=m - CONFIG_USB_STORAGE_CYPRESS_ATACB=m - CONFIG_USB_STORAGE_ENE_UB6250=m -+CONFIG_USB_UAS=m - CONFIG_USB_MDC800=m - CONFIG_USB_MICROTEK=m - CONFIG_USBIP_CORE=m diff --git a/target/linux/brcm2708/patches-4.19/950-0308-pwm-Send-a-uevent-on-the-pwmchip-device-upon-channel.patch b/target/linux/brcm2708/patches-4.19/950-0308-pwm-Send-a-uevent-on-the-pwmchip-device-upon-channel.patch new file mode 100644 index 0000000000..29318711b7 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0308-pwm-Send-a-uevent-on-the-pwmchip-device-upon-channel.patch @@ -0,0 +1,86 @@ +From 30759f3a1d9090c99769dc76964ea414b5129d85 Mon Sep 17 00:00:00 2001 +From: Fabrice Gasnier +Date: Mon, 1 Oct 2018 15:23:57 +0200 +Subject: [PATCH 308/725] pwm: Send a uevent on the pwmchip device upon channel + sysfs (un)export +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 552c02e3e7cfe2744b59de285aaea70021ae95c9 upstream. + +This patch sends a uevent (KOBJ_CHANGE) on the pwmchipN device, +everytime a pwmX channel has been exported/unexported via sysfs. This +allows udev to implement rules on such events, like: + +SUBSYSTEM=="pwm*", PROGRAM="/bin/sh -c '\ + chown -R root:gpio /sys/class/pwm && chmod -R 770 /sys/class/pwm;\ + chown -R root:gpio +/sys/devices/platform/soc/*.pwm/pwm/pwmchip* && chmod -R 770 +/sys/devices/platform/soc/*.pwm/pwm/pwmchip*\ +'" + +This is a replacement patch for commit 7e5d1fd75c3d ("pwm: Set class for +exported channels in sysfs"), see [1]. + +basic testing: +$ udevadm monitor --environment & +$ echo 0 > /sys/class/pwm/pwmchip0/export +KERNEL[197.321736] change /devices/.../pwm/pwmchip0 (pwm) +ACTION=change +DEVPATH=/devices/.../pwm/pwmchip0 +EXPORT=pwm0 +SEQNUM=2045 +SUBSYSTEM=pwm + +[1] https://lkml.org/lkml/2018/9/25/713 + +Signed-off-by: Fabrice Gasnier +Tested-by: Gottfried Haider +Tested-by: Michal Vokáč +Signed-off-by: Thierry Reding +--- + drivers/pwm/sysfs.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/pwm/sysfs.c ++++ b/drivers/pwm/sysfs.c +@@ -249,6 +249,7 @@ static void pwm_export_release(struct de + static int pwm_export_child(struct device *parent, struct pwm_device *pwm) + { + struct pwm_export *export; ++ char *pwm_prop[2]; + int ret; + + if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags)) +@@ -276,6 +277,10 @@ static int pwm_export_child(struct devic + export = NULL; + return ret; + } ++ pwm_prop[0] = kasprintf(GFP_KERNEL, "EXPORT=pwm%u", pwm->hwpwm); ++ pwm_prop[1] = NULL; ++ kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop); ++ kfree(pwm_prop[0]); + + return 0; + } +@@ -288,6 +293,7 @@ static int pwm_unexport_match(struct dev + static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm) + { + struct device *child; ++ char *pwm_prop[2]; + + if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags)) + return -ENODEV; +@@ -296,6 +302,11 @@ static int pwm_unexport_child(struct dev + if (!child) + return -ENODEV; + ++ pwm_prop[0] = kasprintf(GFP_KERNEL, "UNEXPORT=pwm%u", pwm->hwpwm); ++ pwm_prop[1] = NULL; ++ kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop); ++ kfree(pwm_prop[0]); ++ + /* for device_find_child() */ + put_device(child); + device_unregister(child); diff --git a/target/linux/brcm2708/patches-4.19/950-0309-Added-driver-for-the-HiFiBerry-DAC-ADC-2694.patch b/target/linux/brcm2708/patches-4.19/950-0309-Added-driver-for-the-HiFiBerry-DAC-ADC-2694.patch deleted file mode 100644 index 4ce4243b7f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0309-Added-driver-for-the-HiFiBerry-DAC-ADC-2694.patch +++ /dev/null @@ -1,598 +0,0 @@ -From e4b9a8f537b069bd3017f30b21bceb811263c979 Mon Sep 17 00:00:00 2001 -From: HiFiBerry -Date: Mon, 8 Oct 2018 18:10:12 +0200 -Subject: [PATCH 309/703] Added driver for the HiFiBerry DAC+ ADC (#2694) - -Signed-off-by: Daniel Matuschek ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 21 + - .../overlays/hifiberry-dacplusadc-overlay.dts | 71 +++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - sound/soc/bcm/Kconfig | 8 + - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/hifiberry_dacplusadc.c | 407 ++++++++++++++++++ - 8 files changed, 512 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dacplusadc-overlay.dts - create mode 100644 sound/soc/bcm/hifiberry_dacplusadc.c - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -49,6 +49,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - hifiberry-amp.dtbo \ - hifiberry-dac.dtbo \ - hifiberry-dacplus.dtbo \ -+ hifiberry-dacplusadc.dtbo \ - hifiberry-digi.dtbo \ - hifiberry-digi-pro.dtbo \ - hy28a.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -779,6 +779,27 @@ Params: 24db_digital_gain Allow ga - master for bit clock and frame clock. - - -+Name: hifiberry-dacplusadc -+Info: Configures the HifiBerry DAC+ADC audio card -+Load: dtoverlay=hifiberry-dacplusadc,= -+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!) -+ slave Force DAC+ Pro into slave mode, using Pi as -+ master for bit clock and frame clock. -+ -+ - Name: hifiberry-digi - Info: Configures the HifiBerry Digi and Digi+ audio card - Load: dtoverlay=hifiberry-digi ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/hifiberry-dacplusadc-overlay.dts -@@ -0,0 +1,71 @@ -+// Definitions for HiFiBerry DAC+ADC -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/clocks"; -+ __overlay__ { -+ dacpro_osc: dacpro_osc { -+ compatible = "hifiberry,dacpro-clk"; -+ #clock-cells = <0>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm_codec: pcm5122@4d { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4d>; -+ clocks = <&dacpro_osc>; -+ AVDD-supply = <&vdd_3v3_reg>; -+ DVDD-supply = <&vdd_3v3_reg>; -+ CPVDD-supply = <&vdd_3v3_reg>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path = "/"; -+ __overlay__ { -+ dmic { -+ #sound-dai-cells = <0>; -+ compatible = "dmic-codec"; -+ num-channels = <2>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&sound>; -+ hifiberry_dacplusadc: __overlay__ { -+ compatible = "hifiberry,hifiberry-dacplusadc"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ 24db_digital_gain = -+ <&hifiberry_dacplusadc>,"hifiberry,24db_digital_gain?"; -+ slave = <&hifiberry_dacplusadc>,"hifiberry-dacplusadc,slave?"; -+ }; -+}; ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -905,6 +905,7 @@ CONFIG_SND_BCM2835_SOC_I2S=m - CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER=m - CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -898,6 +898,7 @@ CONFIG_SND_BCM2835_SOC_I2S=m - CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER=m - CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -46,6 +46,14 @@ config SND_BCM2708_SOC_HIFIBERRY_DACPLUS - help - Say Y or M if you want to add support for HifiBerry DAC+. - -+config SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC -+ tristate "Support for HifiBerry DAC+ADC" -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S -+ select SND_SOC_PCM512x_I2C -+ select SND_SOC_DMIC -+ help -+ Say Y or M if you want to add support for HifiBerry DAC+ADC. -+ - config SND_BCM2708_SOC_HIFIBERRY_DIGI - tristate "Support for HifiBerry Digi" - depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -14,6 +14,7 @@ snd-soc-googlevoicehat-codec-objs := goo - # BCM2708 Machine Support - snd-soc-3dlab-nano-player-objs := 3dlab-nano-player.o - snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o -+snd-soc-hifiberry-dacplusadc-objs := hifiberry_dacplusadc.o - snd-soc-justboom-dac-objs := justboom-dac.o - snd-soc-rpi-cirrus-objs := rpi-cirrus.o - snd-soc-rpi-proto-objs := rpi-proto.o -@@ -36,6 +37,7 @@ snd-soc-rpi-wm8804-soundcard-objs := rpi - obj-$(CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER) += snd-soc-3dlab-nano-player.o - obj-$(CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD) += snd-soc-googlevoicehat-codec.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o -+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC) += snd-soc-hifiberry-dacplusadc.o - obj-$(CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC) += snd-soc-justboom-dac.o - obj-$(CONFIG_SND_BCM2708_SOC_RPI_CIRRUS) += snd-soc-rpi-cirrus.o - obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o ---- /dev/null -+++ b/sound/soc/bcm/hifiberry_dacplusadc.c -@@ -0,0 +1,407 @@ -+/* -+ * ASoC Driver for HiFiBerry DAC+ / DAC Pro with ADC -+ * -+ * Author: Daniel Matuschek, Stuart MacLean -+ * Copyright 2014-2015 -+ * based on code by Florian Meier -+ * ADC added by Joerg Schambacher -+ * Copyright 2018 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "../codecs/pcm512x.h" -+ -+#define HIFIBERRY_DACPRO_NOCLOCK 0 -+#define HIFIBERRY_DACPRO_CLK44EN 1 -+#define HIFIBERRY_DACPRO_CLK48EN 2 -+ -+struct platform_device *dmic_codec_dev; -+ -+struct pcm512x_priv { -+ struct regmap *regmap; -+ struct clk *sclk; -+}; -+ -+/* Clock rate of CLK44EN attached to GPIO6 pin */ -+#define CLK_44EN_RATE 22579200UL -+/* Clock rate of CLK48EN attached to GPIO3 pin */ -+#define CLK_48EN_RATE 24576000UL -+ -+static bool slave; -+static bool snd_rpi_hifiberry_is_dacpro; -+static bool digital_gain_0db_limit = true; -+ -+static void snd_rpi_hifiberry_dacplusadc_select_clk(struct snd_soc_component *component, -+ int clk_id) -+{ -+ switch (clk_id) { -+ case HIFIBERRY_DACPRO_NOCLOCK: -+ snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x24, 0x00); -+ break; -+ case HIFIBERRY_DACPRO_CLK44EN: -+ snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x24, 0x20); -+ break; -+ case HIFIBERRY_DACPRO_CLK48EN: -+ snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x24, 0x04); -+ break; -+ } -+} -+ -+static void snd_rpi_hifiberry_dacplusadc_clk_gpio(struct snd_soc_component *component) -+{ -+ snd_soc_component_update_bits(component, PCM512x_GPIO_EN, 0x24, 0x24); -+ snd_soc_component_update_bits(component, PCM512x_GPIO_OUTPUT_3, 0x0f, 0x02); -+ snd_soc_component_update_bits(component, PCM512x_GPIO_OUTPUT_6, 0x0f, 0x02); -+} -+ -+static bool snd_rpi_hifiberry_dacplusadc_is_sclk(struct snd_soc_component *component) -+{ -+ unsigned int sck; -+ -+ snd_soc_component_read(component, PCM512x_RATE_DET_4, &sck); -+ return (!(sck & 0x40)); -+} -+ -+static bool snd_rpi_hifiberry_dacplusadc_is_sclk_sleep( -+ struct snd_soc_component *component) -+{ -+ msleep(2); -+ return snd_rpi_hifiberry_dacplusadc_is_sclk(component); -+} -+ -+static bool snd_rpi_hifiberry_dacplusadc_is_pro_card(struct snd_soc_component *component) -+{ -+ bool isClk44EN, isClk48En, isNoClk; -+ -+ snd_rpi_hifiberry_dacplusadc_clk_gpio(component); -+ -+ snd_rpi_hifiberry_dacplusadc_select_clk(component, HIFIBERRY_DACPRO_CLK44EN); -+ isClk44EN = snd_rpi_hifiberry_dacplusadc_is_sclk_sleep(component); -+ -+ snd_rpi_hifiberry_dacplusadc_select_clk(component, HIFIBERRY_DACPRO_NOCLOCK); -+ isNoClk = snd_rpi_hifiberry_dacplusadc_is_sclk_sleep(component); -+ -+ snd_rpi_hifiberry_dacplusadc_select_clk(component, HIFIBERRY_DACPRO_CLK48EN); -+ isClk48En = snd_rpi_hifiberry_dacplusadc_is_sclk_sleep(component); -+ -+ return (isClk44EN && isClk48En && !isNoClk); -+} -+ -+static int snd_rpi_hifiberry_dacplusadc_clk_for_rate(int sample_rate) -+{ -+ int type; -+ -+ switch (sample_rate) { -+ case 11025: -+ case 22050: -+ case 44100: -+ case 88200: -+ case 176400: -+ case 352800: -+ type = HIFIBERRY_DACPRO_CLK44EN; -+ break; -+ default: -+ type = HIFIBERRY_DACPRO_CLK48EN; -+ break; -+ } -+ return type; -+} -+ -+static void snd_rpi_hifiberry_dacplusadc_set_sclk(struct snd_soc_component *component, -+ int sample_rate) -+{ -+ struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component); -+ -+ if (!IS_ERR(pcm512x->sclk)) { -+ int ctype; -+ -+ ctype = snd_rpi_hifiberry_dacplusadc_clk_for_rate(sample_rate); -+ clk_set_rate(pcm512x->sclk, (ctype == HIFIBERRY_DACPRO_CLK44EN) -+ ? CLK_44EN_RATE : CLK_48EN_RATE); -+ snd_rpi_hifiberry_dacplusadc_select_clk(component, ctype); -+ } -+} -+ -+static int snd_rpi_hifiberry_dacplusadc_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ struct snd_soc_component *component = rtd->codec_dai->component; -+ struct pcm512x_priv *priv; -+ -+ if (slave) -+ snd_rpi_hifiberry_is_dacpro = false; -+ else -+ snd_rpi_hifiberry_is_dacpro = -+ snd_rpi_hifiberry_dacplusadc_is_pro_card(component); -+ -+ if (snd_rpi_hifiberry_is_dacpro) { -+ struct snd_soc_dai_link *dai = rtd->dai_link; -+ -+ dai->name = "HiFiBerry ADCDAC+ Pro"; -+ dai->stream_name = "HiFiBerry ADCDAC+ Pro HiFi"; -+ dai->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF -+ | SND_SOC_DAIFMT_CBM_CFM; -+ -+ snd_soc_component_update_bits(component, PCM512x_BCLK_LRCLK_CFG, 0x31, 0x11); -+ snd_soc_component_update_bits(component, PCM512x_MASTER_MODE, 0x03, 0x03); -+ snd_soc_component_update_bits(component, PCM512x_MASTER_CLKDIV_2, 0x7f, 63); -+ } else { -+ priv = snd_soc_component_get_drvdata(component); -+ priv->sclk = ERR_PTR(-ENOENT); -+ } -+ -+ snd_soc_component_update_bits(component, PCM512x_GPIO_EN, 0x08, 0x08); -+ snd_soc_component_update_bits(component, PCM512x_GPIO_OUTPUT_4, 0x0f, 0x02); -+ snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); -+ -+ 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_hifiberry_dacplusadc_update_rate_den( -+ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_component *component = rtd->codec_dai->component; -+ struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component); -+ struct snd_ratnum *rats_no_pll; -+ unsigned int num = 0, den = 0; -+ int err; -+ -+ rats_no_pll = devm_kzalloc(rtd->dev, sizeof(*rats_no_pll), GFP_KERNEL); -+ if (!rats_no_pll) -+ return -ENOMEM; -+ -+ rats_no_pll->num = clk_get_rate(pcm512x->sclk) / 64; -+ rats_no_pll->den_min = 1; -+ rats_no_pll->den_max = 128; -+ rats_no_pll->den_step = 1; -+ -+ err = snd_interval_ratnum(hw_param_interval(params, -+ SNDRV_PCM_HW_PARAM_RATE), 1, rats_no_pll, &num, &den); -+ if (err >= 0 && den) { -+ params->rate_num = num; -+ params->rate_den = den; -+ } -+ -+ devm_kfree(rtd->dev, rats_no_pll); -+ return 0; -+} -+ -+static int snd_rpi_hifiberry_dacplusadc_hw_params( -+ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) -+{ -+ int ret = 0; -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ int channels = params_channels(params); -+ int width = 32; -+ -+ if (snd_rpi_hifiberry_is_dacpro) { -+ struct snd_soc_component *component = rtd->codec_dai->component; -+ -+ width = snd_pcm_format_physical_width(params_format(params)); -+ -+ snd_rpi_hifiberry_dacplusadc_set_sclk(component, -+ params_rate(params)); -+ -+ ret = snd_rpi_hifiberry_dacplusadc_update_rate_den( -+ substream, params); -+ } -+ -+ ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x03, 0x03, -+ channels, width); -+ if (ret) -+ return ret; -+ ret = snd_soc_dai_set_tdm_slot(rtd->codec_dai, 0x03, 0x03, -+ channels, width); -+ return ret; -+} -+ -+static int hifiberry_dacplusadc_LED_cnt; -+ -+static int snd_rpi_hifiberry_dacplusadc_startup( -+ struct snd_pcm_substream *substream) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_component *component = rtd->codec_dai->component; -+ -+ snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, -+ 0x08, 0x08); -+ hifiberry_dacplusadc_LED_cnt++; -+ return 0; -+} -+ -+static void snd_rpi_hifiberry_dacplusadc_shutdown( -+ struct snd_pcm_substream *substream) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_component *component = rtd->codec_dai->component; -+ -+ hifiberry_dacplusadc_LED_cnt--; -+ if (!hifiberry_dacplusadc_LED_cnt) -+ snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, -+ 0x08, 0x00); -+} -+ -+/* machine stream operations */ -+static struct snd_soc_ops snd_rpi_hifiberry_dacplusadc_ops = { -+ .hw_params = snd_rpi_hifiberry_dacplusadc_hw_params, -+ .startup = snd_rpi_hifiberry_dacplusadc_startup, -+ .shutdown = snd_rpi_hifiberry_dacplusadc_shutdown, -+}; -+ -+static struct snd_soc_dai_link_component snd_rpi_hifiberry_dacplusadc_codecs[] = { -+ { -+ .name = "pcm512x.1-004d", -+ .dai_name = "pcm512x-hifi", -+ }, -+ { -+ .name = "dmic-codec", -+ .dai_name = "dmic-hifi", -+ }, -+}; -+ -+static struct snd_soc_dai_link snd_rpi_hifiberry_dacplusadc_dai[] = { -+{ -+ .name = "HiFiBerry DAC+ADC", -+ .stream_name = "HiFiBerry DAC+ADC HiFi", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .platform_name = "bcm2708-i2s.0", -+ .codecs = snd_rpi_hifiberry_dacplusadc_codecs, -+ .num_codecs = 2, -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBS_CFS, -+ .ops = &snd_rpi_hifiberry_dacplusadc_ops, -+ .init = snd_rpi_hifiberry_dacplusadc_init, -+}, -+}; -+ -+/* audio machine driver */ -+static struct snd_soc_card snd_rpi_hifiberry_dacplusadc = { -+ .name = "snd_rpi_hifiberry_dacplusadc", -+ .driver_name = "HifiberryDacpAdc", -+ .owner = THIS_MODULE, -+ .dai_link = snd_rpi_hifiberry_dacplusadc_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dacplusadc_dai), -+}; -+ -+ -+static int snd_rpi_hifiberry_dacplusadc_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_hifiberry_dacplusadc.dev = &pdev->dev; -+ if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai; -+ -+ dai = &snd_rpi_hifiberry_dacplusadc_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ if (i2s_node) { -+ dai->cpu_of_node = i2s_node; -+ dai->platform_of_node = i2s_node; -+ dai->cpu_dai_name = NULL; -+ dai->platform_name = NULL; -+ } -+ dai = &snd_rpi_hifiberry_dacplusadc_dai[1]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, "dmic", 0); -+ if (i2s_node) { -+ dai->cpu_of_node = i2s_node; -+ dai->platform_of_node = i2s_node; -+ } -+ -+ } -+ digital_gain_0db_limit = !of_property_read_bool( -+ pdev->dev.of_node, "hifiberry,24db_digital_gain"); -+ slave = of_property_read_bool(pdev->dev.of_node, -+ "hifiberry-dacplusadc,slave"); -+ -+ ret = devm_snd_soc_register_card(&pdev->dev, -+ &snd_rpi_hifiberry_dacplusadc); -+ if (ret && ret != -EPROBE_DEFER) -+ dev_err(&pdev->dev, -+ "snd_soc_register_card() failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static const struct of_device_id snd_rpi_hifiberry_dacplusadc_of_match[] = { -+ { .compatible = "hifiberry,hifiberry-dacplusadc", }, -+ {}, -+}; -+ -+MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_dacplusadc_of_match); -+ -+static struct platform_driver snd_rpi_hifiberry_dacplusadc_driver = { -+ .driver = { -+ .name = "snd-rpi-hifiberry-dacplusadc", -+ .owner = THIS_MODULE, -+ .of_match_table = snd_rpi_hifiberry_dacplusadc_of_match, -+ }, -+ .probe = snd_rpi_hifiberry_dacplusadc_probe, -+}; -+ -+static int __init hifiberry_dacplusadc_init(void) -+{ -+ int ret; -+ -+ dmic_codec_dev = platform_device_register_simple("dmic-codec", -1, NULL, -+ 0); -+ if (IS_ERR(dmic_codec_dev)) { -+ pr_err("%s: dmic-codec device registration failed\n", __func__); -+ return PTR_ERR(dmic_codec_dev); -+ } -+ -+ ret = platform_driver_register(&snd_rpi_hifiberry_dacplusadc_driver); -+ if (ret) { -+ pr_err("%s: platform driver registration failed\n", __func__); -+ platform_device_unregister(dmic_codec_dev); -+ } -+ -+ return ret; -+} -+module_init(hifiberry_dacplusadc_init); -+ -+static void __exit hifiberry_dacplusadc_exit(void) -+{ -+ platform_driver_unregister(&snd_rpi_hifiberry_dacplusadc_driver); -+ platform_device_unregister(dmic_codec_dev); -+} -+module_exit(hifiberry_dacplusadc_exit); -+ -+MODULE_AUTHOR("Joerg Schambacher "); -+MODULE_AUTHOR("Daniel Matuschek "); -+MODULE_DESCRIPTION("ASoC Driver for HiFiBerry DAC+ADC"); -+MODULE_LICENSE("GPL v2"); diff --git a/target/linux/brcm2708/patches-4.19/950-0309-usb-dwc2-Disable-all-EP-s-on-disconnect.patch b/target/linux/brcm2708/patches-4.19/950-0309-usb-dwc2-Disable-all-EP-s-on-disconnect.patch new file mode 100644 index 0000000000..22fc8dc279 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0309-usb-dwc2-Disable-all-EP-s-on-disconnect.patch @@ -0,0 +1,107 @@ +From 635c5ee81a0595cf3504e7ae4fce5e91d7e17da4 Mon Sep 17 00:00:00 2001 +From: Minas Harutyunyan +Date: Wed, 19 Sep 2018 18:13:52 +0400 +Subject: [PATCH 309/725] usb: dwc2: Disable all EP's on disconnect + +commit dccf1bad4be7eaa096c1f3697bd37883f9a08ecb upstream. + +Disabling all EP's allow to reset EP's to initial state. +On disconnect disable all EP's instead of just killing +all requests. Because of some platform didn't catch +disconnect event, same stuff added to +dwc2_hsotg_core_init_disconnected() function when USB +reset detected on the bus. + +Changed from version 1: +Changed lock acquire flow in dwc2_hsotg_ep_disable() +function. + +Signed-off-by: Minas Harutyunyan +Signed-off-by: Felipe Balbi +--- + drivers/usb/dwc2/gadget.c | 30 +++++++++++++++++++++++------- + 1 file changed, 23 insertions(+), 7 deletions(-) + +--- a/drivers/usb/dwc2/gadget.c ++++ b/drivers/usb/dwc2/gadget.c +@@ -3107,6 +3107,8 @@ static void kill_all_requests(struct dwc + dwc2_hsotg_txfifo_flush(hsotg, ep->fifo_index); + } + ++static int dwc2_hsotg_ep_disable(struct usb_ep *ep); ++ + /** + * dwc2_hsotg_disconnect - disconnect service + * @hsotg: The device state. +@@ -3125,13 +3127,12 @@ void dwc2_hsotg_disconnect(struct dwc2_h + hsotg->connected = 0; + hsotg->test_mode = 0; + ++ /* all endpoints should be shutdown */ + for (ep = 0; ep < hsotg->num_of_eps; ep++) { + if (hsotg->eps_in[ep]) +- kill_all_requests(hsotg, hsotg->eps_in[ep], +- -ESHUTDOWN); ++ dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep); + if (hsotg->eps_out[ep]) +- kill_all_requests(hsotg, hsotg->eps_out[ep], +- -ESHUTDOWN); ++ dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep); + } + + call_gadget(hsotg, disconnect); +@@ -3189,13 +3190,23 @@ void dwc2_hsotg_core_init_disconnected(s + u32 val; + u32 usbcfg; + u32 dcfg = 0; ++ int ep; + + /* Kill any ep0 requests as controller will be reinitialized */ + kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); + +- if (!is_usb_reset) ++ if (!is_usb_reset) { + if (dwc2_core_reset(hsotg, true)) + return; ++ } else { ++ /* all endpoints should be shutdown */ ++ for (ep = 1; ep < hsotg->num_of_eps; ep++) { ++ if (hsotg->eps_in[ep]) ++ dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep); ++ if (hsotg->eps_out[ep]) ++ dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep); ++ } ++ } + + /* + * we must now enable ep0 ready for host detection and then +@@ -3996,6 +4007,7 @@ static int dwc2_hsotg_ep_disable(struct + unsigned long flags; + u32 epctrl_reg; + u32 ctrl; ++ int locked; + + dev_dbg(hsotg->dev, "%s(ep %p)\n", __func__, ep); + +@@ -4011,7 +4023,9 @@ static int dwc2_hsotg_ep_disable(struct + + epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index); + +- spin_lock_irqsave(&hsotg->lock, flags); ++ locked = spin_is_locked(&hsotg->lock); ++ if (!locked) ++ spin_lock_irqsave(&hsotg->lock, flags); + + ctrl = dwc2_readl(hsotg, epctrl_reg); + +@@ -4035,7 +4049,9 @@ static int dwc2_hsotg_ep_disable(struct + hs_ep->fifo_index = 0; + hs_ep->fifo_size = 0; + +- spin_unlock_irqrestore(&hsotg->lock, flags); ++ if (!locked) ++ spin_unlock_irqrestore(&hsotg->lock, flags); ++ + return 0; + } + diff --git a/target/linux/brcm2708/patches-4.19/950-0310-Revert-pwm-Set-class-for-exported-channels-in-sysfs.patch b/target/linux/brcm2708/patches-4.19/950-0310-Revert-pwm-Set-class-for-exported-channels-in-sysfs.patch deleted file mode 100644 index ea8a2b2c06..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0310-Revert-pwm-Set-class-for-exported-channels-in-sysfs.patch +++ /dev/null @@ -1,63 +0,0 @@ -From d499c8f6171122d78a90c3a6403ac7c0c1f50887 Mon Sep 17 00:00:00 2001 -From: Fabrice Gasnier -Date: Mon, 1 Oct 2018 15:23:56 +0200 -Subject: [PATCH 310/703] Revert "pwm: Set class for exported channels in - sysfs" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -commit c289d6625237aa785b484b4e94c23b3b91ea7e60 upstream. - -This reverts commit 7e5d1fd75c3dde9fc10c4472b9368089d1b81d00 ("pwm: Set -class for exported channels in sysfs") as it causes regression with -multiple pwm chip[1], when exporting a pwm channel (echo X > export): - -- ABI (Documentation/ABI/testing/sysfs-class-pwm) states pwmX should be - created in /sys/class/pwm/pwmchipN/pwmX -- Reverted patch causes new entry to be also created directly in - /sys/class/pwm/pwmX -- 1st time, exporting pwmX will create an entry in /sys/class/pwm/pwmX -- class attributes are added under pwmX folder, such as export, unexport - npwm, symlinks. This is wrong as it belongs to pwmchipN. It may cause - bad behavior and report wrong values. -- when another export happens on another pwmchip, it can't be created - (e.g. -EEXIST). This is causing the issue with multiple pwmchip. - -Example on stm32 (stm32429i-eval) platform: -$ ls /sys/class/pwm -pwmchip0 pwmchip4 - -$ cd /sys/class/pwm/pwmchip0/ -$ echo 0 > export -$ ls /sys/class/pwm -pwm0 pwmchip0 pwmchip4 - -$ cd /sys/class/pwm/pwmchip4/ -$ echo 0 > export -sysfs: cannot create duplicate filename '/class/pwm/pwm0' -...Exception stack follows... - -This is also seen on other platform [2] - -[1] https://lkml.org/lkml/2018/9/25/713 -[2] https://lkml.org/lkml/2018/9/25/447 - -Signed-off-by: Fabrice Gasnier -Tested-by: Gottfried Haider -Tested-by: Michal Vokáč -Signed-off-by: Thierry Reding ---- - drivers/pwm/sysfs.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/pwm/sysfs.c -+++ b/drivers/pwm/sysfs.c -@@ -263,7 +263,6 @@ static int pwm_export_child(struct devic - export->pwm = pwm; - mutex_init(&export->lock); - -- export->child.class = parent->class; - export->child.release = pwm_export_release; - export->child.parent = parent; - export->child.devt = MKDEV(0, 0); diff --git a/target/linux/brcm2708/patches-4.19/950-0310-usb-dwc2-Fix-disable-all-EP-s-on-disconnect.patch b/target/linux/brcm2708/patches-4.19/950-0310-usb-dwc2-Fix-disable-all-EP-s-on-disconnect.patch new file mode 100644 index 0000000000..5336d6e6af --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0310-usb-dwc2-Fix-disable-all-EP-s-on-disconnect.patch @@ -0,0 +1,152 @@ +From ef5163a16655fba7490d8853172ecf91e8c8cc1a Mon Sep 17 00:00:00 2001 +From: Minas Harutyunyan +Date: Mon, 10 Dec 2018 18:09:32 +0400 +Subject: [PATCH 310/725] usb: dwc2: Fix disable all EP's on disconnect +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 4fe4f9fecc36956fd53c8edf96dd0c691ef98ff9 upstream. + +Disabling all EP's allow to reset EP's to initial state. +Introduced new function dwc2_hsotg_ep_disable_lock() which +before calling dwc2_hsotg_ep_disable() function acquire +hsotg->lock and release on exiting. +From dwc2_hsotg_ep_disable() function removed acquiring +hsotg->lock. +In dwc2_hsotg_core_init_disconnected() function when USB +reset interrupt asserted disabling all ep’s by +dwc2_hsotg_ep_disable() function. +This updates eliminating sparse imbalance warnings. + +Reverted changes in dwc2_hostg_disconnect() function. +Introduced new function dwc2_hsotg_ep_disable_lock(). +Changed dwc2_hsotg_ep_ops. Now disable point to +dwc2_hsotg_ep_disable_lock() function. +In functions dwc2_hsotg_udc_stop() and dwc2_hsotg_suspend() +dwc2_hsotg_ep_disable() function replaced by +dwc2_hsotg_ep_disable_lock() function. +In dwc2_hsotg_ep_disable() function removed acquiring +of hsotg->lock. + +Fixes: dccf1bad4be7 ("usb: dwc2: Disable all EP's on disconnect") +Signed-off-by: Minas Harutyunyan +Signed-off-by: Felipe Balbi +--- + drivers/usb/dwc2/gadget.c | 41 ++++++++++++++++++++++----------------- + 1 file changed, 23 insertions(+), 18 deletions(-) + +--- a/drivers/usb/dwc2/gadget.c ++++ b/drivers/usb/dwc2/gadget.c +@@ -3107,8 +3107,6 @@ static void kill_all_requests(struct dwc + dwc2_hsotg_txfifo_flush(hsotg, ep->fifo_index); + } + +-static int dwc2_hsotg_ep_disable(struct usb_ep *ep); +- + /** + * dwc2_hsotg_disconnect - disconnect service + * @hsotg: The device state. +@@ -3130,9 +3128,11 @@ void dwc2_hsotg_disconnect(struct dwc2_h + /* all endpoints should be shutdown */ + for (ep = 0; ep < hsotg->num_of_eps; ep++) { + if (hsotg->eps_in[ep]) +- dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep); ++ kill_all_requests(hsotg, hsotg->eps_in[ep], ++ -ESHUTDOWN); + if (hsotg->eps_out[ep]) +- dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep); ++ kill_all_requests(hsotg, hsotg->eps_out[ep], ++ -ESHUTDOWN); + } + + call_gadget(hsotg, disconnect); +@@ -3176,6 +3176,7 @@ static void dwc2_hsotg_irq_fifoempty(str + GINTSTS_PTXFEMP | \ + GINTSTS_RXFLVL) + ++static int dwc2_hsotg_ep_disable(struct usb_ep *ep); + /** + * dwc2_hsotg_core_init - issue softreset to the core + * @hsotg: The device state +@@ -4004,10 +4005,8 @@ static int dwc2_hsotg_ep_disable(struct + struct dwc2_hsotg *hsotg = hs_ep->parent; + int dir_in = hs_ep->dir_in; + int index = hs_ep->index; +- unsigned long flags; + u32 epctrl_reg; + u32 ctrl; +- int locked; + + dev_dbg(hsotg->dev, "%s(ep %p)\n", __func__, ep); + +@@ -4023,10 +4022,6 @@ static int dwc2_hsotg_ep_disable(struct + + epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index); + +- locked = spin_is_locked(&hsotg->lock); +- if (!locked) +- spin_lock_irqsave(&hsotg->lock, flags); +- + ctrl = dwc2_readl(hsotg, epctrl_reg); + + if (ctrl & DXEPCTL_EPENA) +@@ -4049,12 +4044,22 @@ static int dwc2_hsotg_ep_disable(struct + hs_ep->fifo_index = 0; + hs_ep->fifo_size = 0; + +- if (!locked) +- spin_unlock_irqrestore(&hsotg->lock, flags); +- + return 0; + } + ++static int dwc2_hsotg_ep_disable_lock(struct usb_ep *ep) ++{ ++ struct dwc2_hsotg_ep *hs_ep = our_ep(ep); ++ struct dwc2_hsotg *hsotg = hs_ep->parent; ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&hsotg->lock, flags); ++ ret = dwc2_hsotg_ep_disable(ep); ++ spin_unlock_irqrestore(&hsotg->lock, flags); ++ return ret; ++} ++ + /** + * on_list - check request is on the given endpoint + * @ep: The endpoint to check. +@@ -4202,7 +4207,7 @@ static int dwc2_hsotg_ep_sethalt_lock(st + + static const struct usb_ep_ops dwc2_hsotg_ep_ops = { + .enable = dwc2_hsotg_ep_enable, +- .disable = dwc2_hsotg_ep_disable, ++ .disable = dwc2_hsotg_ep_disable_lock, + .alloc_request = dwc2_hsotg_ep_alloc_request, + .free_request = dwc2_hsotg_ep_free_request, + .queue = dwc2_hsotg_ep_queue_lock, +@@ -4342,9 +4347,9 @@ static int dwc2_hsotg_udc_stop(struct us + /* all endpoints should be shutdown */ + for (ep = 1; ep < hsotg->num_of_eps; ep++) { + if (hsotg->eps_in[ep]) +- dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep); ++ dwc2_hsotg_ep_disable_lock(&hsotg->eps_in[ep]->ep); + if (hsotg->eps_out[ep]) +- dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep); ++ dwc2_hsotg_ep_disable_lock(&hsotg->eps_out[ep]->ep); + } + + spin_lock_irqsave(&hsotg->lock, flags); +@@ -4792,9 +4797,9 @@ int dwc2_hsotg_suspend(struct dwc2_hsotg + + for (ep = 0; ep < hsotg->num_of_eps; ep++) { + if (hsotg->eps_in[ep]) +- dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep); ++ dwc2_hsotg_ep_disable_lock(&hsotg->eps_in[ep]->ep); + if (hsotg->eps_out[ep]) +- dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep); ++ dwc2_hsotg_ep_disable_lock(&hsotg->eps_out[ep]->ep); + } + } + diff --git a/target/linux/brcm2708/patches-4.19/950-0311-overlays-Add-ssd1306-overlay-for-OLED-display.patch b/target/linux/brcm2708/patches-4.19/950-0311-overlays-Add-ssd1306-overlay-for-OLED-display.patch new file mode 100644 index 0000000000..a5bab1fe16 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0311-overlays-Add-ssd1306-overlay-for-OLED-display.patch @@ -0,0 +1,104 @@ +From 365b69204bfbfdf4060f8f88d9c54d65c82efc61 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 21 Jan 2019 21:17:27 +0000 +Subject: [PATCH 311/725] overlays: Add ssd1306 overlay for OLED display + +See: https://github.com/raspberrypi/firmware/issues/1098 + +Signed-off-by: mincepi +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 31 ++++++++++++++++ + .../arm/boot/dts/overlays/ssd1306-overlay.dts | 36 +++++++++++++++++++ + 3 files changed, 68 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/ssd1306-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -135,6 +135,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + spi2-1cs.dtbo \ + spi2-2cs.dtbo \ + spi2-3cs.dtbo \ ++ ssd1306.dtbo \ + superaudioboard.dtbo \ + sx150x.dtbo \ + tc358743.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1950,6 +1950,37 @@ Params: cs0_pin GPIO pin + is 'okay' or enabled). + + ++Name: ssd1306 ++Info: Overlay for activation of SSD1306 over I2C OLED display framebuffer. ++Load: dtoverlay=ssd1306,= ++Params: address Location in display memory of first character. ++ (default=0) ++ width Width of display. (default=128) ++ height Height of display. (default=64) ++ offset virtual channel a. (default=0) ++ normal Has no effect on displays tested. (default=not ++ set) ++ sequential Set this if every other scan line is missing. ++ (default=not set) ++ remapped Set this if display is garbled. (default=not ++ set) ++ inverted Set this if display is inverted and mirrored. ++ (default=not set) ++ ++ Examples: ++ Typical usage for 128x64 display: dtoverlay=ssd1306,inverted ++ ++ Typical usage for 128x32 display: dtoverlay=ssd1306,inverted,sequential ++ ++ i2c_baudrate=400000 will speed up the display. ++ ++ i2c_baudrate=1000000 seems to work even though it's not officially ++ supported by the hardware, and is faster still. ++ ++ For more information refer to the device datasheet at: ++ https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf ++ ++ + Name: superaudioboard + Info: Configures the SuperAudioBoard sound card + Load: dtoverlay=superaudioboard,= +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/ssd1306-overlay.dts +@@ -0,0 +1,36 @@ ++// Overlay for SSD1306 128x64 and 128x32 OLED displays ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2718"; ++ ++ fragment@0 { ++ target = <&i2c1>; ++ __overlay__ { ++ status = "okay"; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ssd1306: oled@3c{ ++ compatible = "solomon,ssd1306fb-i2c"; ++ reg = <0x3c>; ++ solomon,width = <128>; ++ solomon,height = <64>; ++ solomon,page-offset = <0>; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ address = <&ssd1306>,"reg:0"; ++ width = <&ssd1306>,"solomon,width:0"; ++ height = <&ssd1306>,"solomon,height:0"; ++ offset = <&ssd1306>,"solomon,page-offset:0"; ++ normal = <&ssd1306>,"solomon,segment-no-remap?"; ++ sequential = <&ssd1306>,"solomon,com-seq?"; ++ remapped = <&ssd1306>,"solomon,com-lrremap?"; ++ inverted = <&ssd1306>,"solomon,com-invdir?"; ++ }; ++}; diff --git a/target/linux/brcm2708/patches-4.19/950-0311-pwm-Send-a-uevent-on-the-pwmchip-device-upon-channel.patch b/target/linux/brcm2708/patches-4.19/950-0311-pwm-Send-a-uevent-on-the-pwmchip-device-upon-channel.patch deleted file mode 100644 index 33d6b4d8f3..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0311-pwm-Send-a-uevent-on-the-pwmchip-device-upon-channel.patch +++ /dev/null @@ -1,86 +0,0 @@ -From f88cefba19bb7ad7f92f721b94fcd9782f49a3c1 Mon Sep 17 00:00:00 2001 -From: Fabrice Gasnier -Date: Mon, 1 Oct 2018 15:23:57 +0200 -Subject: [PATCH 311/703] pwm: Send a uevent on the pwmchip device upon channel - sysfs (un)export -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -commit 552c02e3e7cfe2744b59de285aaea70021ae95c9 upstream. - -This patch sends a uevent (KOBJ_CHANGE) on the pwmchipN device, -everytime a pwmX channel has been exported/unexported via sysfs. This -allows udev to implement rules on such events, like: - -SUBSYSTEM=="pwm*", PROGRAM="/bin/sh -c '\ - chown -R root:gpio /sys/class/pwm && chmod -R 770 /sys/class/pwm;\ - chown -R root:gpio -/sys/devices/platform/soc/*.pwm/pwm/pwmchip* && chmod -R 770 -/sys/devices/platform/soc/*.pwm/pwm/pwmchip*\ -'" - -This is a replacement patch for commit 7e5d1fd75c3d ("pwm: Set class for -exported channels in sysfs"), see [1]. - -basic testing: -$ udevadm monitor --environment & -$ echo 0 > /sys/class/pwm/pwmchip0/export -KERNEL[197.321736] change /devices/.../pwm/pwmchip0 (pwm) -ACTION=change -DEVPATH=/devices/.../pwm/pwmchip0 -EXPORT=pwm0 -SEQNUM=2045 -SUBSYSTEM=pwm - -[1] https://lkml.org/lkml/2018/9/25/713 - -Signed-off-by: Fabrice Gasnier -Tested-by: Gottfried Haider -Tested-by: Michal Vokáč -Signed-off-by: Thierry Reding ---- - drivers/pwm/sysfs.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - ---- a/drivers/pwm/sysfs.c -+++ b/drivers/pwm/sysfs.c -@@ -249,6 +249,7 @@ static void pwm_export_release(struct de - static int pwm_export_child(struct device *parent, struct pwm_device *pwm) - { - struct pwm_export *export; -+ char *pwm_prop[2]; - int ret; - - if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags)) -@@ -276,6 +277,10 @@ static int pwm_export_child(struct devic - export = NULL; - return ret; - } -+ pwm_prop[0] = kasprintf(GFP_KERNEL, "EXPORT=pwm%u", pwm->hwpwm); -+ pwm_prop[1] = NULL; -+ kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop); -+ kfree(pwm_prop[0]); - - return 0; - } -@@ -288,6 +293,7 @@ static int pwm_unexport_match(struct dev - static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm) - { - struct device *child; -+ char *pwm_prop[2]; - - if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags)) - return -ENODEV; -@@ -296,6 +302,11 @@ static int pwm_unexport_child(struct dev - if (!child) - return -ENODEV; - -+ pwm_prop[0] = kasprintf(GFP_KERNEL, "UNEXPORT=pwm%u", pwm->hwpwm); -+ pwm_prop[1] = NULL; -+ kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop); -+ kfree(pwm_prop[0]); -+ - /* for device_find_child() */ - put_device(child); - device_unregister(child); diff --git a/target/linux/brcm2708/patches-4.19/950-0312-overlays-mcp23017-Support-the-MCP23008.patch b/target/linux/brcm2708/patches-4.19/950-0312-overlays-mcp23017-Support-the-MCP23008.patch new file mode 100644 index 0000000000..e244303fec --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0312-overlays-mcp23017-Support-the-MCP23008.patch @@ -0,0 +1,49 @@ +From b2fbf557758e2643df53d67d3855107dbfcae2f1 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 21 Jan 2019 12:19:57 +0000 +Subject: [PATCH 312/725] overlays: mcp23017: Support the MCP23008 + +Add an 'mcp23008' parameter to enable support for the MCP23008 device. + +See: https://github.com/raspberrypi/linux/issues/2818 + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/README | 2 ++ + arch/arm/boot/dts/overlays/mcp23017-overlay.dts | 10 +++++++++- + 2 files changed, 11 insertions(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1212,6 +1212,8 @@ Params: gpiopin Gpio pin + + addr I2C address of the MCP23017 (default: 0x20) + ++ mcp23008 Configure an MCP23008 instead. ++ + + Name: mcp23s17 + Info: Configures the MCP23S08/17 SPI GPIO expanders. +--- a/arch/arm/boot/dts/overlays/mcp23017-overlay.dts ++++ b/arch/arm/boot/dts/overlays/mcp23017-overlay.dts +@@ -44,11 +44,19 @@ + }; + }; + }; +- ++ ++ fragment@3 { ++ target = <&mcp23017>; ++ __dormant__ { ++ compatible = "microchip,mcp23008"; ++ }; ++ }; ++ + __overrides__ { + gpiopin = <&mcp23017_pins>,"brcm,pins:0", + <&mcp23017>,"interrupts:0"; + addr = <&mcp23017>,"reg:0"; ++ mcp23008 = <0>,"=3"; + }; + }; + diff --git a/target/linux/brcm2708/patches-4.19/950-0312-usb-dwc2-Disable-all-EP-s-on-disconnect.patch b/target/linux/brcm2708/patches-4.19/950-0312-usb-dwc2-Disable-all-EP-s-on-disconnect.patch deleted file mode 100644 index 90004c8b0f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0312-usb-dwc2-Disable-all-EP-s-on-disconnect.patch +++ /dev/null @@ -1,107 +0,0 @@ -From e87be7d6627b4dc1ebd9173b1bf29c16b4ebd93f Mon Sep 17 00:00:00 2001 -From: Minas Harutyunyan -Date: Wed, 19 Sep 2018 18:13:52 +0400 -Subject: [PATCH 312/703] usb: dwc2: Disable all EP's on disconnect - -commit dccf1bad4be7eaa096c1f3697bd37883f9a08ecb upstream. - -Disabling all EP's allow to reset EP's to initial state. -On disconnect disable all EP's instead of just killing -all requests. Because of some platform didn't catch -disconnect event, same stuff added to -dwc2_hsotg_core_init_disconnected() function when USB -reset detected on the bus. - -Changed from version 1: -Changed lock acquire flow in dwc2_hsotg_ep_disable() -function. - -Signed-off-by: Minas Harutyunyan -Signed-off-by: Felipe Balbi ---- - drivers/usb/dwc2/gadget.c | 30 +++++++++++++++++++++++------- - 1 file changed, 23 insertions(+), 7 deletions(-) - ---- a/drivers/usb/dwc2/gadget.c -+++ b/drivers/usb/dwc2/gadget.c -@@ -3107,6 +3107,8 @@ static void kill_all_requests(struct dwc - dwc2_hsotg_txfifo_flush(hsotg, ep->fifo_index); - } - -+static int dwc2_hsotg_ep_disable(struct usb_ep *ep); -+ - /** - * dwc2_hsotg_disconnect - disconnect service - * @hsotg: The device state. -@@ -3125,13 +3127,12 @@ void dwc2_hsotg_disconnect(struct dwc2_h - hsotg->connected = 0; - hsotg->test_mode = 0; - -+ /* all endpoints should be shutdown */ - for (ep = 0; ep < hsotg->num_of_eps; ep++) { - if (hsotg->eps_in[ep]) -- kill_all_requests(hsotg, hsotg->eps_in[ep], -- -ESHUTDOWN); -+ dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep); - if (hsotg->eps_out[ep]) -- kill_all_requests(hsotg, hsotg->eps_out[ep], -- -ESHUTDOWN); -+ dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep); - } - - call_gadget(hsotg, disconnect); -@@ -3189,13 +3190,23 @@ void dwc2_hsotg_core_init_disconnected(s - u32 val; - u32 usbcfg; - u32 dcfg = 0; -+ int ep; - - /* Kill any ep0 requests as controller will be reinitialized */ - kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); - -- if (!is_usb_reset) -+ if (!is_usb_reset) { - if (dwc2_core_reset(hsotg, true)) - return; -+ } else { -+ /* all endpoints should be shutdown */ -+ for (ep = 1; ep < hsotg->num_of_eps; ep++) { -+ if (hsotg->eps_in[ep]) -+ dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep); -+ if (hsotg->eps_out[ep]) -+ dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep); -+ } -+ } - - /* - * we must now enable ep0 ready for host detection and then -@@ -3996,6 +4007,7 @@ static int dwc2_hsotg_ep_disable(struct - unsigned long flags; - u32 epctrl_reg; - u32 ctrl; -+ int locked; - - dev_dbg(hsotg->dev, "%s(ep %p)\n", __func__, ep); - -@@ -4011,7 +4023,9 @@ static int dwc2_hsotg_ep_disable(struct - - epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index); - -- spin_lock_irqsave(&hsotg->lock, flags); -+ locked = spin_is_locked(&hsotg->lock); -+ if (!locked) -+ spin_lock_irqsave(&hsotg->lock, flags); - - ctrl = dwc2_readl(hsotg, epctrl_reg); - -@@ -4035,7 +4049,9 @@ static int dwc2_hsotg_ep_disable(struct - hs_ep->fifo_index = 0; - hs_ep->fifo_size = 0; - -- spin_unlock_irqrestore(&hsotg->lock, flags); -+ if (!locked) -+ spin_unlock_irqrestore(&hsotg->lock, flags); -+ - return 0; - } - diff --git a/target/linux/brcm2708/patches-4.19/950-0313-overlays-Add-mcp342x-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0313-overlays-Add-mcp342x-overlay.patch new file mode 100644 index 0000000000..7b30a9cf18 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0313-overlays-Add-mcp342x-overlay.patch @@ -0,0 +1,148 @@ +From f4d829afbb2bec39b872a706fe5f1382ca3864e5 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 21 Jan 2019 12:23:55 +0000 +Subject: [PATCH 313/725] overlays: Add mcp342x overlay + +Support the MCP342x family of ADCs from Microchip. + +See: https://github.com/raspberrypi/linux/issues/2819 + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 16 ++++ + .../arm/boot/dts/overlays/mcp342x-overlay.dts | 93 +++++++++++++++++++ + 3 files changed, 110 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/mcp342x-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -79,6 +79,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + mcp2515-can1.dtbo \ + mcp3008.dtbo \ + mcp3202.dtbo \ ++ mcp342x.dtbo \ + media-center.dtbo \ + midi-uart0.dtbo \ + midi-uart1.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1277,6 +1277,22 @@ Params: spi--present boolean, + spi--speed integer, set the spi bus speed for this device + + ++Name: mcp342x ++Info: Overlay for activation of Microchip MCP3421-3428 ADCs over I2C ++Load: dtoverlay=mcp342x,= ++Params: addr I2C bus address of device, for devices with ++ addresses that are configurable, e.g. by ++ hardware links (default=0x68) ++ mcp3421 The device is an MCP3421 ++ mcp3422 The device is an MCP3422 ++ mcp3423 The device is an MCP3423 ++ mcp3424 The device is an MCP3424 ++ mcp3425 The device is an MCP3425 ++ mcp3426 The device is an MCP3426 ++ mcp3427 The device is an MCP3427 ++ mcp3428 The device is an MCP3428 ++ ++ + Name: media-center + Info: Media Center HAT - 2.83" Touch Display + extras by Pi Supply + Load: dtoverlay=media-center,= +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/mcp342x-overlay.dts +@@ -0,0 +1,93 @@ ++// Overlay for MCP3421-8 ADCs from Microchip Semiconductor ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ status = "okay"; ++ ++ mcp342x: mcp@68 { ++ reg = <0x68>; ++ ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&mcp342x>; ++ __dormant__ { ++ compatible = "microchip,mcp3421"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&mcp342x>; ++ __dormant__ { ++ compatible = "microchip,mcp3422"; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&mcp342x>; ++ __dormant__ { ++ compatible = "microchip,mcp3423"; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&mcp342x>; ++ __dormant__ { ++ compatible = "microchip,mcp3424"; ++ }; ++ }; ++ ++ fragment@5 { ++ target = <&mcp342x>; ++ __dormant__ { ++ compatible = "microchip,mcp3425"; ++ }; ++ }; ++ ++ fragment@6 { ++ target = <&mcp342x>; ++ __dormant__ { ++ compatible = "microchip,mcp3426"; ++ }; ++ }; ++ ++ fragment@7 { ++ target = <&mcp342x>; ++ __dormant__ { ++ compatible = "microchip,mcp3427"; ++ }; ++ }; ++ ++ fragment@8 { ++ target = <&mcp342x>; ++ __dormant__ { ++ compatible = "microchip,mcp3428"; ++ }; ++ }; ++ ++ __overrides__ { ++ addr = <&mcp342x>,"reg:0"; ++ mcp3421 = <0>,"=1"; ++ mcp3422 = <0>,"=2"; ++ mcp3423 = <0>,"=3"; ++ mcp3424 = <0>,"=4"; ++ mcp3425 = <0>,"=5"; ++ mcp3426 = <0>,"=6"; ++ mcp3427 = <0>,"=7"; ++ mcp3428 = <0>,"=8"; ++ }; ++}; ++ diff --git a/target/linux/brcm2708/patches-4.19/950-0313-usb-dwc2-Fix-disable-all-EP-s-on-disconnect.patch b/target/linux/brcm2708/patches-4.19/950-0313-usb-dwc2-Fix-disable-all-EP-s-on-disconnect.patch deleted file mode 100644 index a0b0cad315..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0313-usb-dwc2-Fix-disable-all-EP-s-on-disconnect.patch +++ /dev/null @@ -1,152 +0,0 @@ -From c28c22b965a3c129fd4ba70a5e6b1b2353282d46 Mon Sep 17 00:00:00 2001 -From: Minas Harutyunyan -Date: Mon, 10 Dec 2018 18:09:32 +0400 -Subject: [PATCH 313/703] usb: dwc2: Fix disable all EP's on disconnect -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -commit 4fe4f9fecc36956fd53c8edf96dd0c691ef98ff9 upstream. - -Disabling all EP's allow to reset EP's to initial state. -Introduced new function dwc2_hsotg_ep_disable_lock() which -before calling dwc2_hsotg_ep_disable() function acquire -hsotg->lock and release on exiting. -From dwc2_hsotg_ep_disable() function removed acquiring -hsotg->lock. -In dwc2_hsotg_core_init_disconnected() function when USB -reset interrupt asserted disabling all ep’s by -dwc2_hsotg_ep_disable() function. -This updates eliminating sparse imbalance warnings. - -Reverted changes in dwc2_hostg_disconnect() function. -Introduced new function dwc2_hsotg_ep_disable_lock(). -Changed dwc2_hsotg_ep_ops. Now disable point to -dwc2_hsotg_ep_disable_lock() function. -In functions dwc2_hsotg_udc_stop() and dwc2_hsotg_suspend() -dwc2_hsotg_ep_disable() function replaced by -dwc2_hsotg_ep_disable_lock() function. -In dwc2_hsotg_ep_disable() function removed acquiring -of hsotg->lock. - -Fixes: dccf1bad4be7 ("usb: dwc2: Disable all EP's on disconnect") -Signed-off-by: Minas Harutyunyan -Signed-off-by: Felipe Balbi ---- - drivers/usb/dwc2/gadget.c | 41 ++++++++++++++++++++++----------------- - 1 file changed, 23 insertions(+), 18 deletions(-) - ---- a/drivers/usb/dwc2/gadget.c -+++ b/drivers/usb/dwc2/gadget.c -@@ -3107,8 +3107,6 @@ static void kill_all_requests(struct dwc - dwc2_hsotg_txfifo_flush(hsotg, ep->fifo_index); - } - --static int dwc2_hsotg_ep_disable(struct usb_ep *ep); -- - /** - * dwc2_hsotg_disconnect - disconnect service - * @hsotg: The device state. -@@ -3130,9 +3128,11 @@ void dwc2_hsotg_disconnect(struct dwc2_h - /* all endpoints should be shutdown */ - for (ep = 0; ep < hsotg->num_of_eps; ep++) { - if (hsotg->eps_in[ep]) -- dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep); -+ kill_all_requests(hsotg, hsotg->eps_in[ep], -+ -ESHUTDOWN); - if (hsotg->eps_out[ep]) -- dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep); -+ kill_all_requests(hsotg, hsotg->eps_out[ep], -+ -ESHUTDOWN); - } - - call_gadget(hsotg, disconnect); -@@ -3176,6 +3176,7 @@ static void dwc2_hsotg_irq_fifoempty(str - GINTSTS_PTXFEMP | \ - GINTSTS_RXFLVL) - -+static int dwc2_hsotg_ep_disable(struct usb_ep *ep); - /** - * dwc2_hsotg_core_init - issue softreset to the core - * @hsotg: The device state -@@ -4004,10 +4005,8 @@ static int dwc2_hsotg_ep_disable(struct - struct dwc2_hsotg *hsotg = hs_ep->parent; - int dir_in = hs_ep->dir_in; - int index = hs_ep->index; -- unsigned long flags; - u32 epctrl_reg; - u32 ctrl; -- int locked; - - dev_dbg(hsotg->dev, "%s(ep %p)\n", __func__, ep); - -@@ -4023,10 +4022,6 @@ static int dwc2_hsotg_ep_disable(struct - - epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index); - -- locked = spin_is_locked(&hsotg->lock); -- if (!locked) -- spin_lock_irqsave(&hsotg->lock, flags); -- - ctrl = dwc2_readl(hsotg, epctrl_reg); - - if (ctrl & DXEPCTL_EPENA) -@@ -4049,12 +4044,22 @@ static int dwc2_hsotg_ep_disable(struct - hs_ep->fifo_index = 0; - hs_ep->fifo_size = 0; - -- if (!locked) -- spin_unlock_irqrestore(&hsotg->lock, flags); -- - return 0; - } - -+static int dwc2_hsotg_ep_disable_lock(struct usb_ep *ep) -+{ -+ struct dwc2_hsotg_ep *hs_ep = our_ep(ep); -+ struct dwc2_hsotg *hsotg = hs_ep->parent; -+ unsigned long flags; -+ int ret; -+ -+ spin_lock_irqsave(&hsotg->lock, flags); -+ ret = dwc2_hsotg_ep_disable(ep); -+ spin_unlock_irqrestore(&hsotg->lock, flags); -+ return ret; -+} -+ - /** - * on_list - check request is on the given endpoint - * @ep: The endpoint to check. -@@ -4202,7 +4207,7 @@ static int dwc2_hsotg_ep_sethalt_lock(st - - static const struct usb_ep_ops dwc2_hsotg_ep_ops = { - .enable = dwc2_hsotg_ep_enable, -- .disable = dwc2_hsotg_ep_disable, -+ .disable = dwc2_hsotg_ep_disable_lock, - .alloc_request = dwc2_hsotg_ep_alloc_request, - .free_request = dwc2_hsotg_ep_free_request, - .queue = dwc2_hsotg_ep_queue_lock, -@@ -4342,9 +4347,9 @@ static int dwc2_hsotg_udc_stop(struct us - /* all endpoints should be shutdown */ - for (ep = 1; ep < hsotg->num_of_eps; ep++) { - if (hsotg->eps_in[ep]) -- dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep); -+ dwc2_hsotg_ep_disable_lock(&hsotg->eps_in[ep]->ep); - if (hsotg->eps_out[ep]) -- dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep); -+ dwc2_hsotg_ep_disable_lock(&hsotg->eps_out[ep]->ep); - } - - spin_lock_irqsave(&hsotg->lock, flags); -@@ -4792,9 +4797,9 @@ int dwc2_hsotg_suspend(struct dwc2_hsotg - - for (ep = 0; ep < hsotg->num_of_eps; ep++) { - if (hsotg->eps_in[ep]) -- dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep); -+ dwc2_hsotg_ep_disable_lock(&hsotg->eps_in[ep]->ep); - if (hsotg->eps_out[ep]) -- dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep); -+ dwc2_hsotg_ep_disable_lock(&hsotg->eps_out[ep]->ep); - } - } - diff --git a/target/linux/brcm2708/patches-4.19/950-0314-char-vcio-Add-compat-ioctl-handling.patch b/target/linux/brcm2708/patches-4.19/950-0314-char-vcio-Add-compat-ioctl-handling.patch new file mode 100644 index 0000000000..cd4bd43faf --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0314-char-vcio-Add-compat-ioctl-handling.patch @@ -0,0 +1,58 @@ +From cc33f2492b4b2c0d377f99c19a46207297004631 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 24 Jan 2019 13:56:30 +0000 +Subject: [PATCH 314/725] char: vcio: Add compat ioctl handling + +There was no compat ioctl handler, so 32 bit userspace on a +64 bit kernel failed as IOCTL_MBOX_PROPERTY used the size +of char*. + +Signed-off-by: Dave Stevenson +--- + drivers/char/broadcom/vcio.c | 22 +++++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +--- a/drivers/char/broadcom/vcio.c ++++ b/drivers/char/broadcom/vcio.c +@@ -24,6 +24,9 @@ + + #define VCIO_IOC_MAGIC 100 + #define IOCTL_MBOX_PROPERTY _IOWR(VCIO_IOC_MAGIC, 0, char *) ++#ifdef CONFIG_COMPAT ++#define IOCTL_MBOX_PROPERTY32 _IOWR(VCIO_IOC_MAGIC, 0, compat_uptr_t) ++#endif + + static struct { + dev_t devt; +@@ -87,13 +90,30 @@ static long vcio_device_ioctl(struct fil + case IOCTL_MBOX_PROPERTY: + return vcio_user_property_list((void *)ioctl_param); + default: +- pr_err("unknown ioctl: %d\n", ioctl_num); ++ pr_err("unknown ioctl: %x\n", ioctl_num); + return -EINVAL; + } + } + ++#ifdef CONFIG_COMPAT ++static long vcio_device_compat_ioctl(struct file *file, unsigned int ioctl_num, ++ unsigned long ioctl_param) ++{ ++ switch (ioctl_num) { ++ case IOCTL_MBOX_PROPERTY32: ++ return vcio_user_property_list(compat_ptr(ioctl_param)); ++ default: ++ pr_err("unknown ioctl: %x\n", ioctl_num); ++ return -EINVAL; ++ } ++} ++#endif ++ + const struct file_operations vcio_fops = { + .unlocked_ioctl = vcio_device_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = vcio_device_compat_ioctl, ++#endif + .open = vcio_device_open, + .release = vcio_device_release, + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0314-overlays-Add-ssd1306-overlay-for-OLED-display.patch b/target/linux/brcm2708/patches-4.19/950-0314-overlays-Add-ssd1306-overlay-for-OLED-display.patch deleted file mode 100644 index 3f59e9560c..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0314-overlays-Add-ssd1306-overlay-for-OLED-display.patch +++ /dev/null @@ -1,104 +0,0 @@ -From f6ed9ece5ed29ca16dc021ce0e9ab64bf4c879cb Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 21 Jan 2019 21:17:27 +0000 -Subject: [PATCH 314/703] overlays: Add ssd1306 overlay for OLED display - -See: https://github.com/raspberrypi/firmware/issues/1098 - -Signed-off-by: mincepi ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 31 ++++++++++++++++ - .../arm/boot/dts/overlays/ssd1306-overlay.dts | 36 +++++++++++++++++++ - 3 files changed, 68 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/ssd1306-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -135,6 +135,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - spi2-1cs.dtbo \ - spi2-2cs.dtbo \ - spi2-3cs.dtbo \ -+ ssd1306.dtbo \ - superaudioboard.dtbo \ - sx150x.dtbo \ - tc358743.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1950,6 +1950,37 @@ Params: cs0_pin GPIO pin - is 'okay' or enabled). - - -+Name: ssd1306 -+Info: Overlay for activation of SSD1306 over I2C OLED display framebuffer. -+Load: dtoverlay=ssd1306,= -+Params: address Location in display memory of first character. -+ (default=0) -+ width Width of display. (default=128) -+ height Height of display. (default=64) -+ offset virtual channel a. (default=0) -+ normal Has no effect on displays tested. (default=not -+ set) -+ sequential Set this if every other scan line is missing. -+ (default=not set) -+ remapped Set this if display is garbled. (default=not -+ set) -+ inverted Set this if display is inverted and mirrored. -+ (default=not set) -+ -+ Examples: -+ Typical usage for 128x64 display: dtoverlay=ssd1306,inverted -+ -+ Typical usage for 128x32 display: dtoverlay=ssd1306,inverted,sequential -+ -+ i2c_baudrate=400000 will speed up the display. -+ -+ i2c_baudrate=1000000 seems to work even though it's not officially -+ supported by the hardware, and is faster still. -+ -+ For more information refer to the device datasheet at: -+ https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf -+ -+ - Name: superaudioboard - Info: Configures the SuperAudioBoard sound card - Load: dtoverlay=superaudioboard,= ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/ssd1306-overlay.dts -@@ -0,0 +1,36 @@ -+// Overlay for SSD1306 128x64 and 128x32 OLED displays -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2718"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ status = "okay"; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ssd1306: oled@3c{ -+ compatible = "solomon,ssd1306fb-i2c"; -+ reg = <0x3c>; -+ solomon,width = <128>; -+ solomon,height = <64>; -+ solomon,page-offset = <0>; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ address = <&ssd1306>,"reg:0"; -+ width = <&ssd1306>,"solomon,width:0"; -+ height = <&ssd1306>,"solomon,height:0"; -+ offset = <&ssd1306>,"solomon,page-offset:0"; -+ normal = <&ssd1306>,"solomon,segment-no-remap?"; -+ sequential = <&ssd1306>,"solomon,com-seq?"; -+ remapped = <&ssd1306>,"solomon,com-lrremap?"; -+ inverted = <&ssd1306>,"solomon,com-invdir?"; -+ }; -+}; diff --git a/target/linux/brcm2708/patches-4.19/950-0315-char-vcio-Fail-probe-if-rpi_firmware-is-not-found.patch b/target/linux/brcm2708/patches-4.19/950-0315-char-vcio-Fail-probe-if-rpi_firmware-is-not-found.patch new file mode 100644 index 0000000000..825166f58c --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0315-char-vcio-Fail-probe-if-rpi_firmware-is-not-found.patch @@ -0,0 +1,28 @@ +From b6dcbc7b76285b6e599cc9a4e75e544fb23fe5f7 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 24 Jan 2019 14:03:28 +0000 +Subject: [PATCH 315/725] char: vcio: Fail probe if rpi_firmware is not found. + +Device Tree is now the only supported config mechanism, therefore +uncomment the block of code that fails the probe if the +firmware node can't be found. + +Signed-off-by: Dave Stevenson +--- + drivers/char/broadcom/vcio.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/char/broadcom/vcio.c ++++ b/drivers/char/broadcom/vcio.c +@@ -126,10 +126,9 @@ static int __init vcio_init(void) + + np = of_find_compatible_node(NULL, NULL, + "raspberrypi,bcm2835-firmware"); +-/* Uncomment this when we only boot with Device Tree + if (!of_device_is_available(np)) + return -ENODEV; +-*/ ++ + vcio.fw = rpi_firmware_get(np); + if (!vcio.fw) + return -ENODEV; diff --git a/target/linux/brcm2708/patches-4.19/950-0315-overlays-mcp23017-Support-the-MCP23008.patch b/target/linux/brcm2708/patches-4.19/950-0315-overlays-mcp23017-Support-the-MCP23008.patch deleted file mode 100644 index 24e1e03086..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0315-overlays-mcp23017-Support-the-MCP23008.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 1cfb681bddf0f63b99296987b155a8a9efdb7bbf Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 21 Jan 2019 12:19:57 +0000 -Subject: [PATCH 315/703] overlays: mcp23017: Support the MCP23008 - -Add an 'mcp23008' parameter to enable support for the MCP23008 device. - -See: https://github.com/raspberrypi/linux/issues/2818 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/README | 2 ++ - arch/arm/boot/dts/overlays/mcp23017-overlay.dts | 10 +++++++++- - 2 files changed, 11 insertions(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1212,6 +1212,8 @@ Params: gpiopin Gpio pin - - addr I2C address of the MCP23017 (default: 0x20) - -+ mcp23008 Configure an MCP23008 instead. -+ - - Name: mcp23s17 - Info: Configures the MCP23S08/17 SPI GPIO expanders. ---- a/arch/arm/boot/dts/overlays/mcp23017-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mcp23017-overlay.dts -@@ -44,11 +44,19 @@ - }; - }; - }; -- -+ -+ fragment@3 { -+ target = <&mcp23017>; -+ __dormant__ { -+ compatible = "microchip,mcp23008"; -+ }; -+ }; -+ - __overrides__ { - gpiopin = <&mcp23017_pins>,"brcm,pins:0", - <&mcp23017>,"interrupts:0"; - addr = <&mcp23017>,"reg:0"; -+ mcp23008 = <0>,"=3"; - }; - }; - diff --git a/target/linux/brcm2708/patches-4.19/950-0316-overlays-Add-mcp342x-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0316-overlays-Add-mcp342x-overlay.patch deleted file mode 100644 index 87c05781ae..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0316-overlays-Add-mcp342x-overlay.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 62f5819191c114130ce67a4b8f33abd35403f777 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 21 Jan 2019 12:23:55 +0000 -Subject: [PATCH 316/703] overlays: Add mcp342x overlay - -Support the MCP342x family of ADCs from Microchip. - -See: https://github.com/raspberrypi/linux/issues/2819 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 16 ++++ - .../arm/boot/dts/overlays/mcp342x-overlay.dts | 93 +++++++++++++++++++ - 3 files changed, 110 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/mcp342x-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -79,6 +79,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - mcp2515-can1.dtbo \ - mcp3008.dtbo \ - mcp3202.dtbo \ -+ mcp342x.dtbo \ - media-center.dtbo \ - midi-uart0.dtbo \ - midi-uart1.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1277,6 +1277,22 @@ Params: spi--present boolean, - spi--speed integer, set the spi bus speed for this device - - -+Name: mcp342x -+Info: Overlay for activation of Microchip MCP3421-3428 ADCs over I2C -+Load: dtoverlay=mcp342x,= -+Params: addr I2C bus address of device, for devices with -+ addresses that are configurable, e.g. by -+ hardware links (default=0x68) -+ mcp3421 The device is an MCP3421 -+ mcp3422 The device is an MCP3422 -+ mcp3423 The device is an MCP3423 -+ mcp3424 The device is an MCP3424 -+ mcp3425 The device is an MCP3425 -+ mcp3426 The device is an MCP3426 -+ mcp3427 The device is an MCP3427 -+ mcp3428 The device is an MCP3428 -+ -+ - Name: media-center - Info: Media Center HAT - 2.83" Touch Display + extras by Pi Supply - Load: dtoverlay=media-center,= ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/mcp342x-overlay.dts -@@ -0,0 +1,93 @@ -+// Overlay for MCP3421-8 ADCs from Microchip Semiconductor -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ status = "okay"; -+ -+ mcp342x: mcp@68 { -+ reg = <0x68>; -+ -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&mcp342x>; -+ __dormant__ { -+ compatible = "microchip,mcp3421"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&mcp342x>; -+ __dormant__ { -+ compatible = "microchip,mcp3422"; -+ }; -+ }; -+ -+ fragment@3 { -+ target = <&mcp342x>; -+ __dormant__ { -+ compatible = "microchip,mcp3423"; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&mcp342x>; -+ __dormant__ { -+ compatible = "microchip,mcp3424"; -+ }; -+ }; -+ -+ fragment@5 { -+ target = <&mcp342x>; -+ __dormant__ { -+ compatible = "microchip,mcp3425"; -+ }; -+ }; -+ -+ fragment@6 { -+ target = <&mcp342x>; -+ __dormant__ { -+ compatible = "microchip,mcp3426"; -+ }; -+ }; -+ -+ fragment@7 { -+ target = <&mcp342x>; -+ __dormant__ { -+ compatible = "microchip,mcp3427"; -+ }; -+ }; -+ -+ fragment@8 { -+ target = <&mcp342x>; -+ __dormant__ { -+ compatible = "microchip,mcp3428"; -+ }; -+ }; -+ -+ __overrides__ { -+ addr = <&mcp342x>,"reg:0"; -+ mcp3421 = <0>,"=1"; -+ mcp3422 = <0>,"=2"; -+ mcp3423 = <0>,"=3"; -+ mcp3424 = <0>,"=4"; -+ mcp3425 = <0>,"=5"; -+ mcp3426 = <0>,"=6"; -+ mcp3427 = <0>,"=7"; -+ mcp3428 = <0>,"=8"; -+ }; -+}; -+ diff --git a/target/linux/brcm2708/patches-4.19/950-0316-staging-mmal-vchiq-Fix-client_component-for-64-bit-k.patch b/target/linux/brcm2708/patches-4.19/950-0316-staging-mmal-vchiq-Fix-client_component-for-64-bit-k.patch new file mode 100644 index 0000000000..cf9dd4952c --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0316-staging-mmal-vchiq-Fix-client_component-for-64-bit-k.patch @@ -0,0 +1,68 @@ +From 211b9373ea9e8094d16a1eb9d0c2c18ab70c89de Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 22 Jan 2019 12:04:09 +0000 +Subject: [PATCH 316/725] staging: mmal-vchiq: Fix client_component for 64 bit + kernel + +The MMAL client_component field is used with the event +mechanism to allow the client to identify the component for +which the event is generated. +The field is only 32bits in size, therefore we can't use a +pointer to the component in a 64 bit kernel. + +Component handles are already held in an array per VCHI +instance, so use the array index as the client_component handle +to avoid having to create a new IDR for this purpose. + +Signed-off-by: Dave Stevenson +--- + .../staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 12 +++++++++--- + .../staging/vc04_services/vchiq-mmal/mmal-vchiq.h | 1 + + 2 files changed, 10 insertions(+), 3 deletions(-) + +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +@@ -473,9 +473,9 @@ buffer_from_host(struct vchiq_mmal_insta + static void event_to_host_cb(struct vchiq_mmal_instance *instance, + struct mmal_msg *msg, u32 msg_len) + { +- /* FIXME: Not going to work on 64 bit */ ++ int comp_idx = msg->u.event_to_host.client_component; + struct vchiq_mmal_component *component = +- (struct vchiq_mmal_component *)msg->u.event_to_host.client_component; ++ &instance->component[comp_idx]; + struct vchiq_mmal_port *port = NULL; + struct mmal_msg_context *msg_context; + u32 port_num = msg->u.event_to_host.port_num; +@@ -1074,7 +1074,7 @@ static int create_component(struct vchiq + + /* build component create message */ + m.h.type = MMAL_MSG_TYPE_COMPONENT_CREATE; +- m.u.component_create.client_component = (u32)(unsigned long)component; ++ m.u.component_create.client_component = component->client_component; + strncpy(m.u.component_create.name, name, + sizeof(m.u.component_create.name)); + +@@ -1869,6 +1869,12 @@ int vchiq_mmal_component_init(struct vch + goto unlock; + } + ++ /* We need a handle to reference back to our component structure. ++ * Use the array index in instance->component rather than rolling ++ * another IDR. ++ */ ++ component->client_component = idx; ++ + ret = create_component(instance, component, name); + if (ret < 0) { + pr_err("%s: failed to create component %d (Not enough GPU mem?)\n", +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h +@@ -97,6 +97,7 @@ struct vchiq_mmal_component { + struct vchiq_mmal_port input[MAX_PORT_COUNT]; /* input ports */ + struct vchiq_mmal_port output[MAX_PORT_COUNT]; /* output ports */ + struct vchiq_mmal_port clock[MAX_PORT_COUNT]; /* clock ports */ ++ u32 client_component; /* Used to ref back to client struct */ + }; + + int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance); diff --git a/target/linux/brcm2708/patches-4.19/950-0317-char-vcio-Add-compat-ioctl-handling.patch b/target/linux/brcm2708/patches-4.19/950-0317-char-vcio-Add-compat-ioctl-handling.patch deleted file mode 100644 index 8d6bf4a1ca..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0317-char-vcio-Add-compat-ioctl-handling.patch +++ /dev/null @@ -1,58 +0,0 @@ -From ee233473783f700db1c795d8114facae23ed776b Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 24 Jan 2019 13:56:30 +0000 -Subject: [PATCH 317/703] char: vcio: Add compat ioctl handling - -There was no compat ioctl handler, so 32 bit userspace on a -64 bit kernel failed as IOCTL_MBOX_PROPERTY used the size -of char*. - -Signed-off-by: Dave Stevenson ---- - drivers/char/broadcom/vcio.c | 22 +++++++++++++++++++++- - 1 file changed, 21 insertions(+), 1 deletion(-) - ---- a/drivers/char/broadcom/vcio.c -+++ b/drivers/char/broadcom/vcio.c -@@ -24,6 +24,9 @@ - - #define VCIO_IOC_MAGIC 100 - #define IOCTL_MBOX_PROPERTY _IOWR(VCIO_IOC_MAGIC, 0, char *) -+#ifdef CONFIG_COMPAT -+#define IOCTL_MBOX_PROPERTY32 _IOWR(VCIO_IOC_MAGIC, 0, compat_uptr_t) -+#endif - - static struct { - dev_t devt; -@@ -87,13 +90,30 @@ static long vcio_device_ioctl(struct fil - case IOCTL_MBOX_PROPERTY: - return vcio_user_property_list((void *)ioctl_param); - default: -- pr_err("unknown ioctl: %d\n", ioctl_num); -+ pr_err("unknown ioctl: %x\n", ioctl_num); - return -EINVAL; - } - } - -+#ifdef CONFIG_COMPAT -+static long vcio_device_compat_ioctl(struct file *file, unsigned int ioctl_num, -+ unsigned long ioctl_param) -+{ -+ switch (ioctl_num) { -+ case IOCTL_MBOX_PROPERTY32: -+ return vcio_user_property_list(compat_ptr(ioctl_param)); -+ default: -+ pr_err("unknown ioctl: %x\n", ioctl_num); -+ return -EINVAL; -+ } -+} -+#endif -+ - const struct file_operations vcio_fops = { - .unlocked_ioctl = vcio_device_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = vcio_device_compat_ioctl, -+#endif - .open = vcio_device_open, - .release = vcio_device_release, - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0317-staging-bcm2835-camera-Add-sanity-checks-for-queue_s.patch b/target/linux/brcm2708/patches-4.19/950-0317-staging-bcm2835-camera-Add-sanity-checks-for-queue_s.patch new file mode 100644 index 0000000000..1cb03a6c48 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0317-staging-bcm2835-camera-Add-sanity-checks-for-queue_s.patch @@ -0,0 +1,44 @@ +From c75de411b5c596c6323174c1a403e2f811410b31 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 15 Jan 2019 15:35:24 +0000 +Subject: [PATCH 317/725] staging: bcm2835-camera: Add sanity checks for + queue_setup/CREATE_BUFS + +Fixes a v4l2-compliance failure when passed a buffer that is +too small. +queue_setup wasn't handling the case where !(*nplanes), as +used from CREATE_BUFS and requiring the driver to sanity +check the provided buffer parameters. It was assuming that +it was always being used in the REQBUFS case where it provides +the buffer properties. + +Signed-off-by: Dave Stevenson +--- + .../bcm2835-camera/bcm2835-camera.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c ++++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +@@ -242,6 +242,22 @@ static int queue_setup(struct vb2_queue + return -EINVAL; + } + ++ /* Handle CREATE_BUFS situation - *nplanes != 0 */ ++ if (*nplanes) { ++ if (*nplanes != 1 || ++ sizes[0] < dev->capture.port->current_buffer.size) { ++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, ++ "%s: dev:%p Invalid buffer request from CREATE_BUFS, size %u < %u, nplanes %u != 1\n", ++ __func__, dev, sizes[0], ++ dev->capture.port->current_buffer.size, ++ *nplanes); ++ return -EINVAL; ++ } else { ++ return 0; ++ } ++ } ++ ++ /* Handle REQBUFS situation */ + size = dev->capture.port->current_buffer.size; + if (size == 0) { + v4l2_err(&dev->v4l2_dev, diff --git a/target/linux/brcm2708/patches-4.19/950-0318-char-vcio-Fail-probe-if-rpi_firmware-is-not-found.patch b/target/linux/brcm2708/patches-4.19/950-0318-char-vcio-Fail-probe-if-rpi_firmware-is-not-found.patch deleted file mode 100644 index 702ad73f6c..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0318-char-vcio-Fail-probe-if-rpi_firmware-is-not-found.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 4742e81159d5a54494f497a79834cf746f236681 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 24 Jan 2019 14:03:28 +0000 -Subject: [PATCH 318/703] char: vcio: Fail probe if rpi_firmware is not found. - -Device Tree is now the only supported config mechanism, therefore -uncomment the block of code that fails the probe if the -firmware node can't be found. - -Signed-off-by: Dave Stevenson ---- - drivers/char/broadcom/vcio.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/char/broadcom/vcio.c -+++ b/drivers/char/broadcom/vcio.c -@@ -126,10 +126,9 @@ static int __init vcio_init(void) - - np = of_find_compatible_node(NULL, NULL, - "raspberrypi,bcm2835-firmware"); --/* Uncomment this when we only boot with Device Tree - if (!of_device_is_available(np)) - return -ENODEV; --*/ -+ - vcio.fw = rpi_firmware_get(np); - if (!vcio.fw) - return -ENODEV; diff --git a/target/linux/brcm2708/patches-4.19/950-0318-staging-bcm2835-camera-Set-the-field-value-within-ea.patch b/target/linux/brcm2708/patches-4.19/950-0318-staging-bcm2835-camera-Set-the-field-value-within-ea.patch new file mode 100644 index 0000000000..739b59b146 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0318-staging-bcm2835-camera-Set-the-field-value-within-ea.patch @@ -0,0 +1,27 @@ +From b600d9b815e728a8451848a0bbf032083622305c Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 15 Jan 2019 16:32:33 +0000 +Subject: [PATCH 318/725] staging: bcm2835-camera: Set the field value within + each buffer + +Fixes a v4l2-compliance failure +v4l2-test-buffers.cpp(415): g_field() == V4L2_FIELD_ANY + +The driver only ever produces progresive frames, so field should +always be set to V4L2_FIELD_NONE. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c ++++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +@@ -443,6 +443,7 @@ static void buffer_cb(struct vchiq_mmal_ + } + dev->capture.last_timestamp = buf->vb.vb2_buf.timestamp; + buf->vb.sequence = dev->capture.sequence++; ++ buf->vb.field = V4L2_FIELD_NONE; + + vb2_set_plane_payload(&buf->vb.vb2_buf, 0, mmal_buf->length); + if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) diff --git a/target/linux/brcm2708/patches-4.19/950-0319-char-vc_mem-Fix-up-compat-ioctls-for-64bit-kernel.patch b/target/linux/brcm2708/patches-4.19/950-0319-char-vc_mem-Fix-up-compat-ioctls-for-64bit-kernel.patch new file mode 100644 index 0000000000..db374ddf9b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0319-char-vc_mem-Fix-up-compat-ioctls-for-64bit-kernel.patch @@ -0,0 +1,111 @@ +From 8dabeeeca0cd56ca8980b594e3ce938c4540f1d5 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 23 Jan 2019 18:25:50 +0000 +Subject: [PATCH 319/725] char: vc_mem: Fix up compat ioctls for 64bit kernel + +compat_ioctl wasn't defined, so 32bit user/64bit kernel +always failed. +VC_MEM_IOC_MEM_PHYS_ADDR was defined with parameter size +unsigned long, so the ioctl cmd changes between sizes. + +Signed-off-by: Dave Stevenson +--- + drivers/char/broadcom/vc_mem.c | 40 +++++++++++++++++++++++++++++---- + include/linux/broadcom/vc_mem.h | 4 ++++ + 2 files changed, 40 insertions(+), 4 deletions(-) + +--- a/drivers/char/broadcom/vc_mem.c ++++ b/drivers/char/broadcom/vc_mem.c +@@ -148,7 +148,7 @@ vc_mem_ioctl(struct file *file, unsigned + (void) cmd; + (void) arg; + +- pr_debug("%s: called file = 0x%p\n", __func__, file); ++ pr_debug("%s: called file = 0x%p, cmd %08x\n", __func__, file, cmd); + + switch (cmd) { + case VC_MEM_IOC_MEM_PHYS_ADDR: +@@ -167,7 +167,7 @@ vc_mem_ioctl(struct file *file, unsigned + // Get the videocore memory size first + vc_mem_get_size(); + +- pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__, ++ pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%x\n", __func__, + mm_vc_mem_size); + + if (copy_to_user((void *) arg, &mm_vc_mem_size, +@@ -181,7 +181,7 @@ vc_mem_ioctl(struct file *file, unsigned + // Get the videocore memory base + vc_mem_get_base(); + +- pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__, ++ pr_debug("%s: VC_MEM_IOC_MEM_BASE=%x\n", __func__, + mm_vc_mem_base); + + if (copy_to_user((void *) arg, &mm_vc_mem_base, +@@ -195,7 +195,7 @@ vc_mem_ioctl(struct file *file, unsigned + // Get the videocore memory base + vc_mem_get_base(); + +- pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __func__, ++ pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%x\n", __func__, + mm_vc_mem_base); + + if (copy_to_user((void *) arg, &mm_vc_mem_base, +@@ -214,6 +214,35 @@ vc_mem_ioctl(struct file *file, unsigned + return rc; + } + ++#ifdef CONFIG_COMPAT ++static long ++vc_mem_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ int rc = 0; ++ ++ switch (cmd) { ++ case VC_MEM_IOC_MEM_PHYS_ADDR32: ++ pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR32=0x%p\n", ++ __func__, (void *)mm_vc_mem_phys_addr); ++ ++ /* This isn't correct, but will cover us for now as ++ * VideoCore is 32bit only. ++ */ ++ if (copy_to_user((void *)arg, &mm_vc_mem_phys_addr, ++ sizeof(compat_ulong_t))) ++ rc = -EFAULT; ++ ++ break; ++ ++ default: ++ rc = vc_mem_ioctl(file, cmd, arg); ++ break; ++ } ++ ++ return rc; ++} ++#endif ++ + /**************************************************************************** + * + * vc_mem_mmap +@@ -259,6 +288,9 @@ static const struct file_operations vc_m + .open = vc_mem_open, + .release = vc_mem_release, + .unlocked_ioctl = vc_mem_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = vc_mem_compat_ioctl, ++#endif + .mmap = vc_mem_mmap, + }; + +--- a/include/linux/broadcom/vc_mem.h ++++ b/include/linux/broadcom/vc_mem.h +@@ -32,4 +32,8 @@ extern unsigned int mm_vc_mem_size; + extern int vc_mem_get_current_size( void ); + #endif + ++#ifdef CONFIG_COMPAT ++#define VC_MEM_IOC_MEM_PHYS_ADDR32 _IOR(VC_MEM_IOC_MAGIC, 0, compat_ulong_t) ++#endif ++ + #endif /* _VC_MEM_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0319-staging-mmal-vchiq-Fix-client_component-for-64-bit-k.patch b/target/linux/brcm2708/patches-4.19/950-0319-staging-mmal-vchiq-Fix-client_component-for-64-bit-k.patch deleted file mode 100644 index f06f3034e1..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0319-staging-mmal-vchiq-Fix-client_component-for-64-bit-k.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 4be57b2f957bfe584752bc59c3a7bdee1d615b98 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 22 Jan 2019 12:04:09 +0000 -Subject: [PATCH 319/703] staging: mmal-vchiq: Fix client_component for 64 bit - kernel - -The MMAL client_component field is used with the event -mechanism to allow the client to identify the component for -which the event is generated. -The field is only 32bits in size, therefore we can't use a -pointer to the component in a 64 bit kernel. - -Component handles are already held in an array per VCHI -instance, so use the array index as the client_component handle -to avoid having to create a new IDR for this purpose. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 12 +++++++++--- - .../staging/vc04_services/vchiq-mmal/mmal-vchiq.h | 1 + - 2 files changed, 10 insertions(+), 3 deletions(-) - ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -473,9 +473,9 @@ buffer_from_host(struct vchiq_mmal_insta - static void event_to_host_cb(struct vchiq_mmal_instance *instance, - struct mmal_msg *msg, u32 msg_len) - { -- /* FIXME: Not going to work on 64 bit */ -+ int comp_idx = msg->u.event_to_host.client_component; - struct vchiq_mmal_component *component = -- (struct vchiq_mmal_component *)msg->u.event_to_host.client_component; -+ &instance->component[comp_idx]; - struct vchiq_mmal_port *port = NULL; - struct mmal_msg_context *msg_context; - u32 port_num = msg->u.event_to_host.port_num; -@@ -1074,7 +1074,7 @@ static int create_component(struct vchiq - - /* build component create message */ - m.h.type = MMAL_MSG_TYPE_COMPONENT_CREATE; -- m.u.component_create.client_component = (u32)(unsigned long)component; -+ m.u.component_create.client_component = component->client_component; - strncpy(m.u.component_create.name, name, - sizeof(m.u.component_create.name)); - -@@ -1869,6 +1869,12 @@ int vchiq_mmal_component_init(struct vch - goto unlock; - } - -+ /* We need a handle to reference back to our component structure. -+ * Use the array index in instance->component rather than rolling -+ * another IDR. -+ */ -+ component->client_component = idx; -+ - ret = create_component(instance, component, name); - if (ret < 0) { - pr_err("%s: failed to create component %d (Not enough GPU mem?)\n", ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h -@@ -97,6 +97,7 @@ struct vchiq_mmal_component { - struct vchiq_mmal_port input[MAX_PORT_COUNT]; /* input ports */ - struct vchiq_mmal_port output[MAX_PORT_COUNT]; /* output ports */ - struct vchiq_mmal_port clock[MAX_PORT_COUNT]; /* clock ports */ -+ u32 client_component; /* Used to ref back to client struct */ - }; - - int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance); diff --git a/target/linux/brcm2708/patches-4.19/950-0320-char-vc_mem-Fix-all-coding-style-issues.patch b/target/linux/brcm2708/patches-4.19/950-0320-char-vc_mem-Fix-all-coding-style-issues.patch new file mode 100644 index 0000000000..2dbb589151 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0320-char-vc_mem-Fix-all-coding-style-issues.patch @@ -0,0 +1,428 @@ +From 26120a2fdc44fe84dcc0092cd6f00aa23e79bbb1 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 23 Jan 2019 18:37:29 +0000 +Subject: [PATCH 320/725] char: vc_mem: Fix all coding style issues. + +Cleans up all checkpatch errors in vc_mem.c and vc_mem.h +No functional change to the code. + +Signed-off-by: Dave Stevenson +--- + drivers/char/broadcom/vc_mem.c | 177 +++++++++++--------------------- + include/linux/broadcom/vc_mem.h | 38 +++---- + 2 files changed, 77 insertions(+), 138 deletions(-) + +--- a/drivers/char/broadcom/vc_mem.c ++++ b/drivers/char/broadcom/vc_mem.c +@@ -1,16 +1,16 @@ +-/***************************************************************************** +-* Copyright 2010 - 2011 Broadcom Corporation. All rights reserved. +-* +-* Unless you and Broadcom execute a separate written software license +-* agreement governing use of this software, this software is licensed to you +-* under the terms of the GNU General Public License version 2, available at +-* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). +-* +-* Notwithstanding the above, under no circumstances may you combine this +-* software in any way with any other Broadcom software provided under a +-* license other than the GPL, without Broadcom's express prior written +-* consent. +-*****************************************************************************/ ++/* ++ * Copyright 2010 - 2011 Broadcom Corporation. All rights reserved. ++ * ++ * Unless you and Broadcom execute a separate written software license ++ * agreement governing use of this software, this software is licensed to you ++ * under the terms of the GNU General Public License version 2, available at ++ * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). ++ * ++ * Notwithstanding the above, under no circumstances may you combine this ++ * software in any way with any other Broadcom software provided under a ++ * license other than the GPL, without Broadcom's express prior written ++ * consent. ++ */ + + #include + #include +@@ -26,11 +26,11 @@ + + #define DRIVER_NAME "vc-mem" + +-// Device (/dev) related variables +-static dev_t vc_mem_devnum = 0; +-static struct class *vc_mem_class = NULL; ++/* Device (/dev) related variables */ ++static dev_t vc_mem_devnum; ++static struct class *vc_mem_class; + static struct cdev vc_mem_cdev; +-static int vc_mem_inited = 0; ++static int vc_mem_inited; + + #ifdef CONFIG_DEBUG_FS + static struct dentry *vc_mem_debugfs_entry; +@@ -50,96 +50,55 @@ static struct dentry *vc_mem_debugfs_ent + * bootloader (and/or kernel). When that happens, the values of these variables + * would be calculated and assigned in the init function. + */ +-// in the 2835 VC in mapped above ARM, but ARM has full access to VC space +-unsigned long mm_vc_mem_phys_addr = 0x00000000; +-unsigned int mm_vc_mem_size = 0; +-unsigned int mm_vc_mem_base = 0; +- ++/* In the 2835 VC in mapped above ARM, but ARM has full access to VC space */ ++unsigned long mm_vc_mem_phys_addr; + EXPORT_SYMBOL(mm_vc_mem_phys_addr); ++unsigned int mm_vc_mem_size; + EXPORT_SYMBOL(mm_vc_mem_size); ++unsigned int mm_vc_mem_base; + EXPORT_SYMBOL(mm_vc_mem_base); + +-static uint phys_addr = 0; +-static uint mem_size = 0; +-static uint mem_base = 0; +- +- +-/**************************************************************************** +-* +-* vc_mem_open +-* +-***************************************************************************/ ++static uint phys_addr; ++static uint mem_size; ++static uint mem_base; + + static int + vc_mem_open(struct inode *inode, struct file *file) + { +- (void) inode; +- (void) file; ++ (void)inode; + + pr_debug("%s: called file = 0x%p\n", __func__, file); + + return 0; + } + +-/**************************************************************************** +-* +-* vc_mem_release +-* +-***************************************************************************/ +- + static int + vc_mem_release(struct inode *inode, struct file *file) + { +- (void) inode; +- (void) file; ++ (void)inode; + + pr_debug("%s: called file = 0x%p\n", __func__, file); + + return 0; + } + +-/**************************************************************************** +-* +-* vc_mem_get_size +-* +-***************************************************************************/ +- + static void + vc_mem_get_size(void) + { + } + +-/**************************************************************************** +-* +-* vc_mem_get_base +-* +-***************************************************************************/ +- + static void + vc_mem_get_base(void) + { + } + +-/**************************************************************************** +-* +-* vc_mem_get_current_size +-* +-***************************************************************************/ +- + int + vc_mem_get_current_size(void) + { + return mm_vc_mem_size; + } +- + EXPORT_SYMBOL_GPL(vc_mem_get_current_size); + +-/**************************************************************************** +-* +-* vc_mem_ioctl +-* +-***************************************************************************/ +- + static long + vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + { +@@ -154,52 +113,52 @@ vc_mem_ioctl(struct file *file, unsigned + case VC_MEM_IOC_MEM_PHYS_ADDR: + { + pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n", +- __func__, (void *) mm_vc_mem_phys_addr); ++ __func__, (void *)mm_vc_mem_phys_addr); + +- if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr, +- sizeof (mm_vc_mem_phys_addr)) != 0) { ++ if (copy_to_user((void *)arg, &mm_vc_mem_phys_addr, ++ sizeof(mm_vc_mem_phys_addr))) { + rc = -EFAULT; + } + break; + } + case VC_MEM_IOC_MEM_SIZE: + { +- // Get the videocore memory size first ++ /* Get the videocore memory size first */ + vc_mem_get_size(); + + pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%x\n", __func__, +- mm_vc_mem_size); ++ mm_vc_mem_size); + +- if (copy_to_user((void *) arg, &mm_vc_mem_size, +- sizeof (mm_vc_mem_size)) != 0) { ++ if (copy_to_user((void *)arg, &mm_vc_mem_size, ++ sizeof(mm_vc_mem_size))) { + rc = -EFAULT; + } + break; + } + case VC_MEM_IOC_MEM_BASE: + { +- // Get the videocore memory base ++ /* Get the videocore memory base */ + vc_mem_get_base(); + + pr_debug("%s: VC_MEM_IOC_MEM_BASE=%x\n", __func__, +- mm_vc_mem_base); ++ mm_vc_mem_base); + +- if (copy_to_user((void *) arg, &mm_vc_mem_base, +- sizeof (mm_vc_mem_base)) != 0) { ++ if (copy_to_user((void *)arg, &mm_vc_mem_base, ++ sizeof(mm_vc_mem_base))) { + rc = -EFAULT; + } + break; + } + case VC_MEM_IOC_MEM_LOAD: + { +- // Get the videocore memory base ++ /* Get the videocore memory base */ + vc_mem_get_base(); + + pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%x\n", __func__, + mm_vc_mem_base); + +- if (copy_to_user((void *) arg, &mm_vc_mem_base, +- sizeof (mm_vc_mem_base)) != 0) { ++ if (copy_to_user((void *)arg, &mm_vc_mem_base, ++ sizeof(mm_vc_mem_base))) { + rc = -EFAULT; + } + break; +@@ -243,12 +202,6 @@ vc_mem_compat_ioctl(struct file *file, u + } + #endif + +-/**************************************************************************** +-* +-* vc_mem_mmap +-* +-***************************************************************************/ +- + static int + vc_mem_mmap(struct file *filp, struct vm_area_struct *vma) + { +@@ -257,32 +210,26 @@ vc_mem_mmap(struct file *filp, struct vm + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + + pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n", +- __func__, (long) vma->vm_start, (long) vma->vm_end, +- (long) vma->vm_pgoff); ++ __func__, (long)vma->vm_start, (long)vma->vm_end, ++ (long)vma->vm_pgoff); + + if (offset + length > mm_vc_mem_size) { + pr_err("%s: length %ld is too big\n", __func__, length); + return -EINVAL; + } +- // Do not cache the memory map ++ /* Do not cache the memory map */ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + rc = remap_pfn_range(vma, vma->vm_start, + (mm_vc_mem_phys_addr >> PAGE_SHIFT) + + vma->vm_pgoff, length, vma->vm_page_prot); +- if (rc != 0) { ++ if (rc) + pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc); +- } + + return rc; + } + +-/**************************************************************************** +-* +-* File Operations for the driver. +-* +-***************************************************************************/ +- ++/* File Operations for the driver. */ + static const struct file_operations vc_mem_fops = { + .owner = THIS_MODULE, + .open = vc_mem_open, +@@ -316,7 +263,7 @@ static int vc_mem_debugfs_init( + vc_mem_debugfs_entry, + (u32 *)&mm_vc_mem_phys_addr)) { + dev_warn(dev, "%s:could not create vc_mem_phys entry\n", +- __func__); ++ __func__); + goto fail; + } + +@@ -325,7 +272,7 @@ static int vc_mem_debugfs_init( + vc_mem_debugfs_entry, + (u32 *)&mm_vc_mem_size)) { + dev_warn(dev, "%s:could not create vc_mem_size entry\n", +- __func__); ++ __func__); + goto fail; + } + +@@ -347,12 +294,7 @@ fail: + + #endif /* CONFIG_DEBUG_FS */ + +- +-/**************************************************************************** +-* +-* vc_mem_init +-* +-***************************************************************************/ ++/* Module load/unload functions */ + + static int __init + vc_mem_init(void) +@@ -369,16 +311,19 @@ vc_mem_init(void) + vc_mem_get_size(); + + pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n", +- mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); ++ mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, ++ mm_vc_mem_size / (1024 * 1024)); + +- if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { ++ rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME); ++ if (rc < 0) { + pr_err("%s: alloc_chrdev_region failed (rc=%d)\n", + __func__, rc); + goto out_err; + } + + cdev_init(&vc_mem_cdev, &vc_mem_fops); +- if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { ++ rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1); ++ if (rc) { + pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc); + goto out_unregister; + } +@@ -408,26 +353,20 @@ vc_mem_init(void) + + device_destroy(vc_mem_class, vc_mem_devnum); + +- out_class_destroy: ++out_class_destroy: + class_destroy(vc_mem_class); + vc_mem_class = NULL; + +- out_cdev_del: ++out_cdev_del: + cdev_del(&vc_mem_cdev); + +- out_unregister: ++out_unregister: + unregister_chrdev_region(vc_mem_devnum, 1); + +- out_err: ++out_err: + return -1; + } + +-/**************************************************************************** +-* +-* vc_mem_exit +-* +-***************************************************************************/ +- + static void __exit + vc_mem_exit(void) + { +--- a/include/linux/broadcom/vc_mem.h ++++ b/include/linux/broadcom/vc_mem.h +@@ -1,16 +1,16 @@ +-/***************************************************************************** +-* Copyright 2010 - 2011 Broadcom Corporation. All rights reserved. +-* +-* Unless you and Broadcom execute a separate written software license +-* agreement governing use of this software, this software is licensed to you +-* under the terms of the GNU General Public License version 2, available at +-* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). +-* +-* Notwithstanding the above, under no circumstances may you combine this +-* software in any way with any other Broadcom software provided under a +-* license other than the GPL, without Broadcom's express prior written +-* consent. +-*****************************************************************************/ ++/* ++ * Copyright 2010 - 2011 Broadcom Corporation. All rights reserved. ++ * ++ * Unless you and Broadcom execute a separate written software license ++ * agreement governing use of this software, this software is licensed to you ++ * under the terms of the GNU General Public License version 2, available at ++ * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). ++ * ++ * Notwithstanding the above, under no circumstances may you combine this ++ * software in any way with any other Broadcom software provided under a ++ * license other than the GPL, without Broadcom's express prior written ++ * consent. ++ */ + + #ifndef _VC_MEM_H + #define _VC_MEM_H +@@ -19,17 +19,17 @@ + + #define VC_MEM_IOC_MAGIC 'v' + +-#define VC_MEM_IOC_MEM_PHYS_ADDR _IOR( VC_MEM_IOC_MAGIC, 0, unsigned long ) +-#define VC_MEM_IOC_MEM_SIZE _IOR( VC_MEM_IOC_MAGIC, 1, unsigned int ) +-#define VC_MEM_IOC_MEM_BASE _IOR( VC_MEM_IOC_MAGIC, 2, unsigned int ) +-#define VC_MEM_IOC_MEM_LOAD _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int ) ++#define VC_MEM_IOC_MEM_PHYS_ADDR _IOR(VC_MEM_IOC_MAGIC, 0, unsigned long) ++#define VC_MEM_IOC_MEM_SIZE _IOR(VC_MEM_IOC_MAGIC, 1, unsigned int) ++#define VC_MEM_IOC_MEM_BASE _IOR(VC_MEM_IOC_MAGIC, 2, unsigned int) ++#define VC_MEM_IOC_MEM_LOAD _IOR(VC_MEM_IOC_MAGIC, 3, unsigned int) + +-#if defined( __KERNEL__ ) ++#ifdef __KERNEL__ + #define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF + + extern unsigned long mm_vc_mem_phys_addr; + extern unsigned int mm_vc_mem_size; +-extern int vc_mem_get_current_size( void ); ++extern int vc_mem_get_current_size(void); + #endif + + #ifdef CONFIG_COMPAT diff --git a/target/linux/brcm2708/patches-4.19/950-0320-staging-bcm2835-camera-Add-sanity-checks-for-queue_s.patch b/target/linux/brcm2708/patches-4.19/950-0320-staging-bcm2835-camera-Add-sanity-checks-for-queue_s.patch deleted file mode 100644 index 4a483c6611..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0320-staging-bcm2835-camera-Add-sanity-checks-for-queue_s.patch +++ /dev/null @@ -1,44 +0,0 @@ -From cd78829bc64d03ae095636e1c5ed851e9fd7abf2 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 15 Jan 2019 15:35:24 +0000 -Subject: [PATCH 320/703] staging: bcm2835-camera: Add sanity checks for - queue_setup/CREATE_BUFS - -Fixes a v4l2-compliance failure when passed a buffer that is -too small. -queue_setup wasn't handling the case where !(*nplanes), as -used from CREATE_BUFS and requiring the driver to sanity -check the provided buffer parameters. It was assuming that -it was always being used in the REQBUFS case where it provides -the buffer properties. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-camera/bcm2835-camera.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - ---- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c -+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c -@@ -242,6 +242,22 @@ static int queue_setup(struct vb2_queue - return -EINVAL; - } - -+ /* Handle CREATE_BUFS situation - *nplanes != 0 */ -+ if (*nplanes) { -+ if (*nplanes != 1 || -+ sizes[0] < dev->capture.port->current_buffer.size) { -+ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, -+ "%s: dev:%p Invalid buffer request from CREATE_BUFS, size %u < %u, nplanes %u != 1\n", -+ __func__, dev, sizes[0], -+ dev->capture.port->current_buffer.size, -+ *nplanes); -+ return -EINVAL; -+ } else { -+ return 0; -+ } -+ } -+ -+ /* Handle REQBUFS situation */ - size = dev->capture.port->current_buffer.size; - if (size == 0) { - v4l2_err(&dev->v4l2_dev, diff --git a/target/linux/brcm2708/patches-4.19/950-0321-clk-clk-bcm2835-Use-zd-when-printing-size_t.patch b/target/linux/brcm2708/patches-4.19/950-0321-clk-clk-bcm2835-Use-zd-when-printing-size_t.patch new file mode 100644 index 0000000000..461cc1e8e9 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0321-clk-clk-bcm2835-Use-zd-when-printing-size_t.patch @@ -0,0 +1,24 @@ +From a279fd3a9e17e2306f7c585cdc070913a456e9fa Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 24 Jan 2019 15:09:28 +0000 +Subject: [PATCH 321/725] clk: clk-bcm2835: Use %zd when printing size_t + +The debug text for how many clocks have been registered +uses "%d" with a size_t. Correct it to "%zd". + +Signed-off-by: Dave Stevenson +--- + 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 +@@ -2271,7 +2271,7 @@ static int bcm2835_clk_probe(struct plat + return ret; + + /* note that we have registered all the clocks */ +- dev_dbg(dev, "registered %d clocks\n", asize); ++ dev_dbg(dev, "registered %zd clocks\n", asize); + + return 0; + } diff --git a/target/linux/brcm2708/patches-4.19/950-0321-staging-bcm2835-camera-Set-the-field-value-within-ea.patch b/target/linux/brcm2708/patches-4.19/950-0321-staging-bcm2835-camera-Set-the-field-value-within-ea.patch deleted file mode 100644 index 895f5ddb64..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0321-staging-bcm2835-camera-Set-the-field-value-within-ea.patch +++ /dev/null @@ -1,27 +0,0 @@ -From a470862bbbcc79c925933bf3e5beb7265e9aef48 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 15 Jan 2019 16:32:33 +0000 -Subject: [PATCH 321/703] staging: bcm2835-camera: Set the field value within - each buffer - -Fixes a v4l2-compliance failure -v4l2-test-buffers.cpp(415): g_field() == V4L2_FIELD_ANY - -The driver only ever produces progresive frames, so field should -always be set to V4L2_FIELD_NONE. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c -+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c -@@ -443,6 +443,7 @@ static void buffer_cb(struct vchiq_mmal_ - } - dev->capture.last_timestamp = buf->vb.vb2_buf.timestamp; - buf->vb.sequence = dev->capture.sequence++; -+ buf->vb.field = V4L2_FIELD_NONE; - - vb2_set_plane_payload(&buf->vb.vb2_buf, 0, mmal_buf->length); - if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) diff --git a/target/linux/brcm2708/patches-4.19/950-0322-char-vc_mem-Fix-up-compat-ioctls-for-64bit-kernel.patch b/target/linux/brcm2708/patches-4.19/950-0322-char-vc_mem-Fix-up-compat-ioctls-for-64bit-kernel.patch deleted file mode 100644 index 261d82e75c..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0322-char-vc_mem-Fix-up-compat-ioctls-for-64bit-kernel.patch +++ /dev/null @@ -1,111 +0,0 @@ -From e2387d73874182f3aa3b0748bfa19b5cb292f97c Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 23 Jan 2019 18:25:50 +0000 -Subject: [PATCH 322/703] char: vc_mem: Fix up compat ioctls for 64bit kernel - -compat_ioctl wasn't defined, so 32bit user/64bit kernel -always failed. -VC_MEM_IOC_MEM_PHYS_ADDR was defined with parameter size -unsigned long, so the ioctl cmd changes between sizes. - -Signed-off-by: Dave Stevenson ---- - drivers/char/broadcom/vc_mem.c | 40 +++++++++++++++++++++++++++++---- - include/linux/broadcom/vc_mem.h | 4 ++++ - 2 files changed, 40 insertions(+), 4 deletions(-) - ---- a/drivers/char/broadcom/vc_mem.c -+++ b/drivers/char/broadcom/vc_mem.c -@@ -148,7 +148,7 @@ vc_mem_ioctl(struct file *file, unsigned - (void) cmd; - (void) arg; - -- pr_debug("%s: called file = 0x%p\n", __func__, file); -+ pr_debug("%s: called file = 0x%p, cmd %08x\n", __func__, file, cmd); - - switch (cmd) { - case VC_MEM_IOC_MEM_PHYS_ADDR: -@@ -167,7 +167,7 @@ vc_mem_ioctl(struct file *file, unsigned - // Get the videocore memory size first - vc_mem_get_size(); - -- pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__, -+ pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%x\n", __func__, - mm_vc_mem_size); - - if (copy_to_user((void *) arg, &mm_vc_mem_size, -@@ -181,7 +181,7 @@ vc_mem_ioctl(struct file *file, unsigned - // Get the videocore memory base - vc_mem_get_base(); - -- pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__, -+ pr_debug("%s: VC_MEM_IOC_MEM_BASE=%x\n", __func__, - mm_vc_mem_base); - - if (copy_to_user((void *) arg, &mm_vc_mem_base, -@@ -195,7 +195,7 @@ vc_mem_ioctl(struct file *file, unsigned - // Get the videocore memory base - vc_mem_get_base(); - -- pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __func__, -+ pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%x\n", __func__, - mm_vc_mem_base); - - if (copy_to_user((void *) arg, &mm_vc_mem_base, -@@ -214,6 +214,35 @@ vc_mem_ioctl(struct file *file, unsigned - return rc; - } - -+#ifdef CONFIG_COMPAT -+static long -+vc_mem_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ int rc = 0; -+ -+ switch (cmd) { -+ case VC_MEM_IOC_MEM_PHYS_ADDR32: -+ pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR32=0x%p\n", -+ __func__, (void *)mm_vc_mem_phys_addr); -+ -+ /* This isn't correct, but will cover us for now as -+ * VideoCore is 32bit only. -+ */ -+ if (copy_to_user((void *)arg, &mm_vc_mem_phys_addr, -+ sizeof(compat_ulong_t))) -+ rc = -EFAULT; -+ -+ break; -+ -+ default: -+ rc = vc_mem_ioctl(file, cmd, arg); -+ break; -+ } -+ -+ return rc; -+} -+#endif -+ - /**************************************************************************** - * - * vc_mem_mmap -@@ -259,6 +288,9 @@ static const struct file_operations vc_m - .open = vc_mem_open, - .release = vc_mem_release, - .unlocked_ioctl = vc_mem_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = vc_mem_compat_ioctl, -+#endif - .mmap = vc_mem_mmap, - }; - ---- a/include/linux/broadcom/vc_mem.h -+++ b/include/linux/broadcom/vc_mem.h -@@ -32,4 +32,8 @@ extern unsigned int mm_vc_mem_size; - extern int vc_mem_get_current_size( void ); - #endif - -+#ifdef CONFIG_COMPAT -+#define VC_MEM_IOC_MEM_PHYS_ADDR32 _IOR(VC_MEM_IOC_MAGIC, 0, compat_ulong_t) -+#endif -+ - #endif /* _VC_MEM_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0322-mfd-Add-rpi_sense_core-of-compatible-string.patch b/target/linux/brcm2708/patches-4.19/950-0322-mfd-Add-rpi_sense_core-of-compatible-string.patch new file mode 100644 index 0000000000..4ac56470eb --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0322-mfd-Add-rpi_sense_core-of-compatible-string.patch @@ -0,0 +1,26 @@ +From d80feb505001d17a4643c93ef342ec5d61e0122c Mon Sep 17 00:00:00 2001 +From: Serge Schneider +Date: Tue, 29 Jan 2019 12:05:49 +0000 +Subject: [PATCH 322/725] mfd: Add rpi_sense_core of compatible string + +--- + drivers/mfd/rpisense-core.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/mfd/rpisense-core.c ++++ b/drivers/mfd/rpisense-core.c +@@ -138,6 +138,14 @@ static const struct i2c_device_id rpisen + }; + MODULE_DEVICE_TABLE(i2c, rpisense_i2c_id); + ++#ifdef CONFIG_OF ++static const struct of_device_id rpisense_core_id[] = { ++ { .compatible = "rpi,rpi-sense" }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, rpisense_core_id); ++#endif ++ + + static struct i2c_driver rpisense_driver = { + .driver = { diff --git a/target/linux/brcm2708/patches-4.19/950-0323-char-vc_mem-Fix-all-coding-style-issues.patch b/target/linux/brcm2708/patches-4.19/950-0323-char-vc_mem-Fix-all-coding-style-issues.patch deleted file mode 100644 index 375d2afec1..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0323-char-vc_mem-Fix-all-coding-style-issues.patch +++ /dev/null @@ -1,428 +0,0 @@ -From 89452f1b5d1ebad50b1aab2eac896730ec2debfd Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 23 Jan 2019 18:37:29 +0000 -Subject: [PATCH 323/703] char: vc_mem: Fix all coding style issues. - -Cleans up all checkpatch errors in vc_mem.c and vc_mem.h -No functional change to the code. - -Signed-off-by: Dave Stevenson ---- - drivers/char/broadcom/vc_mem.c | 177 +++++++++++--------------------- - include/linux/broadcom/vc_mem.h | 38 +++---- - 2 files changed, 77 insertions(+), 138 deletions(-) - ---- a/drivers/char/broadcom/vc_mem.c -+++ b/drivers/char/broadcom/vc_mem.c -@@ -1,16 +1,16 @@ --/***************************************************************************** --* Copyright 2010 - 2011 Broadcom Corporation. All rights reserved. --* --* Unless you and Broadcom execute a separate written software license --* agreement governing use of this software, this software is licensed to you --* under the terms of the GNU General Public License version 2, available at --* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). --* --* Notwithstanding the above, under no circumstances may you combine this --* software in any way with any other Broadcom software provided under a --* license other than the GPL, without Broadcom's express prior written --* consent. --*****************************************************************************/ -+/* -+ * Copyright 2010 - 2011 Broadcom Corporation. All rights reserved. -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2, available at -+ * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a -+ * license other than the GPL, without Broadcom's express prior written -+ * consent. -+ */ - - #include - #include -@@ -26,11 +26,11 @@ - - #define DRIVER_NAME "vc-mem" - --// Device (/dev) related variables --static dev_t vc_mem_devnum = 0; --static struct class *vc_mem_class = NULL; -+/* Device (/dev) related variables */ -+static dev_t vc_mem_devnum; -+static struct class *vc_mem_class; - static struct cdev vc_mem_cdev; --static int vc_mem_inited = 0; -+static int vc_mem_inited; - - #ifdef CONFIG_DEBUG_FS - static struct dentry *vc_mem_debugfs_entry; -@@ -50,96 +50,55 @@ static struct dentry *vc_mem_debugfs_ent - * bootloader (and/or kernel). When that happens, the values of these variables - * would be calculated and assigned in the init function. - */ --// in the 2835 VC in mapped above ARM, but ARM has full access to VC space --unsigned long mm_vc_mem_phys_addr = 0x00000000; --unsigned int mm_vc_mem_size = 0; --unsigned int mm_vc_mem_base = 0; -- -+/* In the 2835 VC in mapped above ARM, but ARM has full access to VC space */ -+unsigned long mm_vc_mem_phys_addr; - EXPORT_SYMBOL(mm_vc_mem_phys_addr); -+unsigned int mm_vc_mem_size; - EXPORT_SYMBOL(mm_vc_mem_size); -+unsigned int mm_vc_mem_base; - EXPORT_SYMBOL(mm_vc_mem_base); - --static uint phys_addr = 0; --static uint mem_size = 0; --static uint mem_base = 0; -- -- --/**************************************************************************** --* --* vc_mem_open --* --***************************************************************************/ -+static uint phys_addr; -+static uint mem_size; -+static uint mem_base; - - static int - vc_mem_open(struct inode *inode, struct file *file) - { -- (void) inode; -- (void) file; -+ (void)inode; - - pr_debug("%s: called file = 0x%p\n", __func__, file); - - return 0; - } - --/**************************************************************************** --* --* vc_mem_release --* --***************************************************************************/ -- - static int - vc_mem_release(struct inode *inode, struct file *file) - { -- (void) inode; -- (void) file; -+ (void)inode; - - pr_debug("%s: called file = 0x%p\n", __func__, file); - - return 0; - } - --/**************************************************************************** --* --* vc_mem_get_size --* --***************************************************************************/ -- - static void - vc_mem_get_size(void) - { - } - --/**************************************************************************** --* --* vc_mem_get_base --* --***************************************************************************/ -- - static void - vc_mem_get_base(void) - { - } - --/**************************************************************************** --* --* vc_mem_get_current_size --* --***************************************************************************/ -- - int - vc_mem_get_current_size(void) - { - return mm_vc_mem_size; - } -- - EXPORT_SYMBOL_GPL(vc_mem_get_current_size); - --/**************************************************************************** --* --* vc_mem_ioctl --* --***************************************************************************/ -- - static long - vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) - { -@@ -154,52 +113,52 @@ vc_mem_ioctl(struct file *file, unsigned - case VC_MEM_IOC_MEM_PHYS_ADDR: - { - pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n", -- __func__, (void *) mm_vc_mem_phys_addr); -+ __func__, (void *)mm_vc_mem_phys_addr); - -- if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr, -- sizeof (mm_vc_mem_phys_addr)) != 0) { -+ if (copy_to_user((void *)arg, &mm_vc_mem_phys_addr, -+ sizeof(mm_vc_mem_phys_addr))) { - rc = -EFAULT; - } - break; - } - case VC_MEM_IOC_MEM_SIZE: - { -- // Get the videocore memory size first -+ /* Get the videocore memory size first */ - vc_mem_get_size(); - - pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%x\n", __func__, -- mm_vc_mem_size); -+ mm_vc_mem_size); - -- if (copy_to_user((void *) arg, &mm_vc_mem_size, -- sizeof (mm_vc_mem_size)) != 0) { -+ if (copy_to_user((void *)arg, &mm_vc_mem_size, -+ sizeof(mm_vc_mem_size))) { - rc = -EFAULT; - } - break; - } - case VC_MEM_IOC_MEM_BASE: - { -- // Get the videocore memory base -+ /* Get the videocore memory base */ - vc_mem_get_base(); - - pr_debug("%s: VC_MEM_IOC_MEM_BASE=%x\n", __func__, -- mm_vc_mem_base); -+ mm_vc_mem_base); - -- if (copy_to_user((void *) arg, &mm_vc_mem_base, -- sizeof (mm_vc_mem_base)) != 0) { -+ if (copy_to_user((void *)arg, &mm_vc_mem_base, -+ sizeof(mm_vc_mem_base))) { - rc = -EFAULT; - } - break; - } - case VC_MEM_IOC_MEM_LOAD: - { -- // Get the videocore memory base -+ /* Get the videocore memory base */ - vc_mem_get_base(); - - pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%x\n", __func__, - mm_vc_mem_base); - -- if (copy_to_user((void *) arg, &mm_vc_mem_base, -- sizeof (mm_vc_mem_base)) != 0) { -+ if (copy_to_user((void *)arg, &mm_vc_mem_base, -+ sizeof(mm_vc_mem_base))) { - rc = -EFAULT; - } - break; -@@ -243,12 +202,6 @@ vc_mem_compat_ioctl(struct file *file, u - } - #endif - --/**************************************************************************** --* --* vc_mem_mmap --* --***************************************************************************/ -- - static int - vc_mem_mmap(struct file *filp, struct vm_area_struct *vma) - { -@@ -257,32 +210,26 @@ vc_mem_mmap(struct file *filp, struct vm - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; - - pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n", -- __func__, (long) vma->vm_start, (long) vma->vm_end, -- (long) vma->vm_pgoff); -+ __func__, (long)vma->vm_start, (long)vma->vm_end, -+ (long)vma->vm_pgoff); - - if (offset + length > mm_vc_mem_size) { - pr_err("%s: length %ld is too big\n", __func__, length); - return -EINVAL; - } -- // Do not cache the memory map -+ /* Do not cache the memory map */ - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - - rc = remap_pfn_range(vma, vma->vm_start, - (mm_vc_mem_phys_addr >> PAGE_SHIFT) + - vma->vm_pgoff, length, vma->vm_page_prot); -- if (rc != 0) { -+ if (rc) - pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc); -- } - - return rc; - } - --/**************************************************************************** --* --* File Operations for the driver. --* --***************************************************************************/ -- -+/* File Operations for the driver. */ - static const struct file_operations vc_mem_fops = { - .owner = THIS_MODULE, - .open = vc_mem_open, -@@ -316,7 +263,7 @@ static int vc_mem_debugfs_init( - vc_mem_debugfs_entry, - (u32 *)&mm_vc_mem_phys_addr)) { - dev_warn(dev, "%s:could not create vc_mem_phys entry\n", -- __func__); -+ __func__); - goto fail; - } - -@@ -325,7 +272,7 @@ static int vc_mem_debugfs_init( - vc_mem_debugfs_entry, - (u32 *)&mm_vc_mem_size)) { - dev_warn(dev, "%s:could not create vc_mem_size entry\n", -- __func__); -+ __func__); - goto fail; - } - -@@ -347,12 +294,7 @@ fail: - - #endif /* CONFIG_DEBUG_FS */ - -- --/**************************************************************************** --* --* vc_mem_init --* --***************************************************************************/ -+/* Module load/unload functions */ - - static int __init - vc_mem_init(void) -@@ -369,16 +311,19 @@ vc_mem_init(void) - vc_mem_get_size(); - - pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n", -- mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); -+ mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, -+ mm_vc_mem_size / (1024 * 1024)); - -- if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { -+ rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME); -+ if (rc < 0) { - pr_err("%s: alloc_chrdev_region failed (rc=%d)\n", - __func__, rc); - goto out_err; - } - - cdev_init(&vc_mem_cdev, &vc_mem_fops); -- if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { -+ rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1); -+ if (rc) { - pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc); - goto out_unregister; - } -@@ -408,26 +353,20 @@ vc_mem_init(void) - - device_destroy(vc_mem_class, vc_mem_devnum); - -- out_class_destroy: -+out_class_destroy: - class_destroy(vc_mem_class); - vc_mem_class = NULL; - -- out_cdev_del: -+out_cdev_del: - cdev_del(&vc_mem_cdev); - -- out_unregister: -+out_unregister: - unregister_chrdev_region(vc_mem_devnum, 1); - -- out_err: -+out_err: - return -1; - } - --/**************************************************************************** --* --* vc_mem_exit --* --***************************************************************************/ -- - static void __exit - vc_mem_exit(void) - { ---- a/include/linux/broadcom/vc_mem.h -+++ b/include/linux/broadcom/vc_mem.h -@@ -1,16 +1,16 @@ --/***************************************************************************** --* Copyright 2010 - 2011 Broadcom Corporation. All rights reserved. --* --* Unless you and Broadcom execute a separate written software license --* agreement governing use of this software, this software is licensed to you --* under the terms of the GNU General Public License version 2, available at --* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). --* --* Notwithstanding the above, under no circumstances may you combine this --* software in any way with any other Broadcom software provided under a --* license other than the GPL, without Broadcom's express prior written --* consent. --*****************************************************************************/ -+/* -+ * Copyright 2010 - 2011 Broadcom Corporation. All rights reserved. -+ * -+ * Unless you and Broadcom execute a separate written software license -+ * agreement governing use of this software, this software is licensed to you -+ * under the terms of the GNU General Public License version 2, available at -+ * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). -+ * -+ * Notwithstanding the above, under no circumstances may you combine this -+ * software in any way with any other Broadcom software provided under a -+ * license other than the GPL, without Broadcom's express prior written -+ * consent. -+ */ - - #ifndef _VC_MEM_H - #define _VC_MEM_H -@@ -19,17 +19,17 @@ - - #define VC_MEM_IOC_MAGIC 'v' - --#define VC_MEM_IOC_MEM_PHYS_ADDR _IOR( VC_MEM_IOC_MAGIC, 0, unsigned long ) --#define VC_MEM_IOC_MEM_SIZE _IOR( VC_MEM_IOC_MAGIC, 1, unsigned int ) --#define VC_MEM_IOC_MEM_BASE _IOR( VC_MEM_IOC_MAGIC, 2, unsigned int ) --#define VC_MEM_IOC_MEM_LOAD _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int ) -+#define VC_MEM_IOC_MEM_PHYS_ADDR _IOR(VC_MEM_IOC_MAGIC, 0, unsigned long) -+#define VC_MEM_IOC_MEM_SIZE _IOR(VC_MEM_IOC_MAGIC, 1, unsigned int) -+#define VC_MEM_IOC_MEM_BASE _IOR(VC_MEM_IOC_MAGIC, 2, unsigned int) -+#define VC_MEM_IOC_MEM_LOAD _IOR(VC_MEM_IOC_MAGIC, 3, unsigned int) - --#if defined( __KERNEL__ ) -+#ifdef __KERNEL__ - #define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF - - extern unsigned long mm_vc_mem_phys_addr; - extern unsigned int mm_vc_mem_size; --extern int vc_mem_get_current_size( void ); -+extern int vc_mem_get_current_size(void); - #endif - - #ifdef CONFIG_COMPAT diff --git a/target/linux/brcm2708/patches-4.19/950-0323-gpu-vc4_firmware_kms-Fix-up-64-bit-compile-warnings.patch b/target/linux/brcm2708/patches-4.19/950-0323-gpu-vc4_firmware_kms-Fix-up-64-bit-compile-warnings.patch new file mode 100644 index 0000000000..20e8903d06 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0323-gpu-vc4_firmware_kms-Fix-up-64-bit-compile-warnings.patch @@ -0,0 +1,66 @@ +From f5f2adb60536b902d5c8ed8e0d93209062313a74 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 28 Jan 2019 14:40:16 +0000 +Subject: [PATCH 323/725] gpu: vc4_firmware_kms: Fix up 64 bit compile + warnings. + +Resolve two build warnings with regard using incorrectly +sized parameters in logging messages on 64 bit builds. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -160,14 +160,14 @@ 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", ++ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary update %dx%d@%d +%d,%d 0x%pad/%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], ++ &fbinfo->base, + fb->pitches[0]); + + ret = rpi_firmware_transaction(vc4->firmware, +@@ -197,6 +197,7 @@ static void vc4_cursor_plane_atomic_upda + struct drm_plane_state *state = plane->state; + struct drm_framebuffer *fb = state->fb; + struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); ++ dma_addr_t addr = bo->paddr + fb->offsets[0]; + int ret; + u32 packet_state[] = { + state->crtc->state->active, +@@ -206,13 +207,13 @@ static void vc4_cursor_plane_atomic_upda + }; + WARN_ON_ONCE(fb->pitches[0] != state->crtc_w * 4); + +- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] update %dx%d cursor at %d,%d (0x%08x/%d)", ++ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] update %dx%d cursor at %d,%d (0x%pad/%d)", + plane->base.id, plane->name, + state->crtc_w, + state->crtc_h, + state->crtc_x, + state->crtc_y, +- bo->paddr + fb->offsets[0], ++ &addr, + fb->pitches[0]); + + /* add on the top/left offsets when overscan is active */ +@@ -238,7 +239,7 @@ static void vc4_cursor_plane_atomic_upda + fb != old_state->fb) { + u32 packet_info[] = { state->crtc_w, state->crtc_h, + 0, /* unused */ +- bo->paddr + fb->offsets[0], ++ addr, + 0, 0, /* hotx, hoty */}; + + ret = rpi_firmware_property(vc4->firmware, diff --git a/target/linux/brcm2708/patches-4.19/950-0324-clk-clk-bcm2835-Use-zd-when-printing-size_t.patch b/target/linux/brcm2708/patches-4.19/950-0324-clk-clk-bcm2835-Use-zd-when-printing-size_t.patch deleted file mode 100644 index 303cfd7635..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0324-clk-clk-bcm2835-Use-zd-when-printing-size_t.patch +++ /dev/null @@ -1,24 +0,0 @@ -From efb7d0e1c98be0715d57d6fd41f2d8f9ec7b9afd Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 24 Jan 2019 15:09:28 +0000 -Subject: [PATCH 324/703] clk: clk-bcm2835: Use %zd when printing size_t - -The debug text for how many clocks have been registered -uses "%d" with a size_t. Correct it to "%zd". - -Signed-off-by: Dave Stevenson ---- - 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 -@@ -2271,7 +2271,7 @@ static int bcm2835_clk_probe(struct plat - return ret; - - /* note that we have registered all the clocks */ -- dev_dbg(dev, "registered %d clocks\n", asize); -+ dev_dbg(dev, "registered %zd clocks\n", asize); - - return 0; - } diff --git a/target/linux/brcm2708/patches-4.19/950-0324-input-rpi-ft5406-Clear-build-warning-on-64-bit-build.patch b/target/linux/brcm2708/patches-4.19/950-0324-input-rpi-ft5406-Clear-build-warning-on-64-bit-build.patch new file mode 100644 index 0000000000..8a1b5fa559 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0324-input-rpi-ft5406-Clear-build-warning-on-64-bit-build.patch @@ -0,0 +1,26 @@ +From 27447f66107940248d7875c908bf37384d9efd99 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 28 Jan 2019 14:42:34 +0000 +Subject: [PATCH 324/725] input: rpi-ft5406: Clear build warning on 64 bit + builds. + +Resolve 64 bit build warning over using %x with a dma_addr_t. + +Signed-off-by: Dave Stevenson +--- + drivers/input/touchscreen/rpi-ft5406.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/input/touchscreen/rpi-ft5406.c ++++ b/drivers/input/touchscreen/rpi-ft5406.c +@@ -218,8 +218,8 @@ static int ft5406_probe(struct platform_ + + if (!ts->ts_base) { + dev_warn(dev, +- "set failed, trying get (err:%d touchbuf:%x virt:%p bus:%x)\n", +- err, touchbuf, ts->ts_base, ts->bus_addr); ++ "set failed, trying get (err:%d touchbuf:%x virt:%p bus:%pad)\n", ++ err, touchbuf, ts->ts_base, &ts->bus_addr); + + err = rpi_firmware_property( + fw, diff --git a/target/linux/brcm2708/patches-4.19/950-0325-dtoverlays-Correct-DT-handling-camera-GPIOs.patch b/target/linux/brcm2708/patches-4.19/950-0325-dtoverlays-Correct-DT-handling-camera-GPIOs.patch new file mode 100644 index 0000000000..5c46143364 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0325-dtoverlays-Correct-DT-handling-camera-GPIOs.patch @@ -0,0 +1,85 @@ +From 63f283b8c56f4eaa2df0f46c9bdd174797316aa3 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 18 Sep 2018 10:47:38 +0100 +Subject: [PATCH 325/725] dtoverlays: Correct DT handling camera GPIOs + +The firmware has support for updating overrides with the correct +GPIO settings for the camera GPIOs, but the wrong device tree +setup ended up being merged. +Correct the DT configuration so that the firmware does set it +up correctly. + +Signed-off-by: Dave Stevenson +--- + arch/arm/boot/dts/bcm270x.dtsi | 7 +++++++ + arch/arm/boot/dts/overlays/README | 10 +--------- + arch/arm/boot/dts/overlays/ov5647-overlay.dts | 14 +++++++++++--- + 3 files changed, 19 insertions(+), 12 deletions(-) + +--- a/arch/arm/boot/dts/bcm270x.dtsi ++++ b/arch/arm/boot/dts/bcm270x.dtsi +@@ -152,6 +152,13 @@ + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; ++ ++ __overrides__ { ++ cam0-pwdn-ctrl; ++ cam0-pwdn; ++ cam0-led-ctrl; ++ cam0-led; ++ }; + }; + + &vc4 { +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1366,15 +1366,7 @@ Info: Omnivision OV5647 camera module. + Uses Unicam 1, which is the standard camera connector on most Pi + variants. + Load: dtoverlay=ov5647,= +-Params: cam0-pwdn GPIO used to control the sensor powerdown line. +- +- cam0-led GPIO used to control the sensor led +- Both these fields should be automatically filled +- in by the firmware to reflect the default GPIO +- configuration of the particular Pi variant in +- use. +- +- i2c_pins_0_1 Use pins 0&1 for the I2C instead of 44&45. ++Params: i2c_pins_0_1 Use pins 0&1 for the I2C instead of 44&45. + Useful on Compute Modules. + + i2c_pins_28_29 Use pins 28&29 for the I2C instead of 44&45. +--- a/arch/arm/boot/dts/overlays/ov5647-overlay.dts ++++ b/arch/arm/boot/dts/overlays/ov5647-overlay.dts +@@ -14,7 +14,7 @@ + status = "okay"; + + ov5647: ov5647@36 { +- compatible = "ov5647"; ++ compatible = "ovti,ov5647"; + reg = <0x36>; + status = "okay"; + +@@ -82,10 +82,18 @@ + }; + }; + ++ fragment@6 { ++ target-path="/__overrides__"; ++ __overlay__ { ++ cam0-pwdn-ctrl = <&ov5647>,"pwdn-gpios:0"; ++ cam0-pwdn = <&ov5647>,"pwdn-gpios:4"; ++ cam0-led-ctrl = <&ov5647>,"pwdn-gpios:12"; ++ cam0-led = <&ov5647>,"pwdn-gpios:16"; ++ }; ++ }; ++ + __overrides__ { + i2c_pins_0_1 = <0>,"-2-3+4"; + i2c_pins_28_29 = <0>,"+2-3-4"; +- cam0-pwdn = <&ov5647>,"pwdn-gpios:4"; +- cam0-led = <&ov5647>,"pwdn-gpios:16"; + }; + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0325-mfd-Add-rpi_sense_core-of-compatible-string.patch b/target/linux/brcm2708/patches-4.19/950-0325-mfd-Add-rpi_sense_core-of-compatible-string.patch deleted file mode 100644 index 0d95039d16..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0325-mfd-Add-rpi_sense_core-of-compatible-string.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 9f4e8de5ea95750736cda32007e7e5f099429396 Mon Sep 17 00:00:00 2001 -From: Serge Schneider -Date: Tue, 29 Jan 2019 12:05:49 +0000 -Subject: [PATCH 325/703] mfd: Add rpi_sense_core of compatible string - ---- - drivers/mfd/rpisense-core.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/mfd/rpisense-core.c -+++ b/drivers/mfd/rpisense-core.c -@@ -138,6 +138,14 @@ static const struct i2c_device_id rpisen - }; - MODULE_DEVICE_TABLE(i2c, rpisense_i2c_id); - -+#ifdef CONFIG_OF -+static const struct of_device_id rpisense_core_id[] = { -+ { .compatible = "rpi,rpi-sense" }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, rpisense_core_id); -+#endif -+ - - static struct i2c_driver rpisense_driver = { - .driver = { diff --git a/target/linux/brcm2708/patches-4.19/950-0326-gpu-vc4_firmware_kms-Fix-up-64-bit-compile-warnings.patch b/target/linux/brcm2708/patches-4.19/950-0326-gpu-vc4_firmware_kms-Fix-up-64-bit-compile-warnings.patch deleted file mode 100644 index d8fff0310d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0326-gpu-vc4_firmware_kms-Fix-up-64-bit-compile-warnings.patch +++ /dev/null @@ -1,66 +0,0 @@ -From dacca227ccf7120b91dac51cdb863aa6bcab9c2f Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 28 Jan 2019 14:40:16 +0000 -Subject: [PATCH 326/703] gpu: vc4_firmware_kms: Fix up 64 bit compile - warnings. - -Resolve two build warnings with regard using incorrectly -sized parameters in logging messages on 64 bit builds. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -160,14 +160,14 @@ 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", -+ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary update %dx%d@%d +%d,%d 0x%pad/%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], -+ &fbinfo->base, - fb->pitches[0]); - - ret = rpi_firmware_transaction(vc4->firmware, -@@ -197,6 +197,7 @@ static void vc4_cursor_plane_atomic_upda - struct drm_plane_state *state = plane->state; - struct drm_framebuffer *fb = state->fb; - struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); -+ dma_addr_t addr = bo->paddr + fb->offsets[0]; - int ret; - u32 packet_state[] = { - state->crtc->state->active, -@@ -206,13 +207,13 @@ static void vc4_cursor_plane_atomic_upda - }; - WARN_ON_ONCE(fb->pitches[0] != state->crtc_w * 4); - -- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] update %dx%d cursor at %d,%d (0x%08x/%d)", -+ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] update %dx%d cursor at %d,%d (0x%pad/%d)", - plane->base.id, plane->name, - state->crtc_w, - state->crtc_h, - state->crtc_x, - state->crtc_y, -- bo->paddr + fb->offsets[0], -+ &addr, - fb->pitches[0]); - - /* add on the top/left offsets when overscan is active */ -@@ -238,7 +239,7 @@ static void vc4_cursor_plane_atomic_upda - fb != old_state->fb) { - u32 packet_info[] = { state->crtc_w, state->crtc_h, - 0, /* unused */ -- bo->paddr + fb->offsets[0], -+ addr, - 0, 0, /* hotx, hoty */}; - - ret = rpi_firmware_property(vc4->firmware, diff --git a/target/linux/brcm2708/patches-4.19/950-0326-media-ov5647-Use-gpiod_set_value_cansleep.patch b/target/linux/brcm2708/patches-4.19/950-0326-media-ov5647-Use-gpiod_set_value_cansleep.patch new file mode 100644 index 0000000000..a12a914729 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0326-media-ov5647-Use-gpiod_set_value_cansleep.patch @@ -0,0 +1,54 @@ +From 31ef5a3641c54ac06d1d5bc9fffcdb96d892cbf0 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 18 Sep 2018 11:08:51 +0100 +Subject: [PATCH 326/725] media: ov5647: Use gpiod_set_value_cansleep + +All calls to the gpio library are in contexts that can sleep, +therefore there is no issue with having those GPIOs controlled +by controllers which require sleeping (eg I2C GPIO expanders). + +Switch to using gpiod_set_value_cansleep instead of gpiod_set_value +to avoid triggering the warning in gpiolib should the GPIO +controller need to sleep. + +Signed-off-by: Dave Stevenson +--- + drivers/media/i2c/ov5647.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/media/i2c/ov5647.c ++++ b/drivers/media/i2c/ov5647.c +@@ -373,7 +373,7 @@ static int ov5647_sensor_power(struct v4 + dev_dbg(&client->dev, "OV5647 power on\n"); + + if (ov5647->pwdn) { +- gpiod_set_value(ov5647->pwdn, 0); ++ gpiod_set_value_cansleep(ov5647->pwdn, 0); + msleep(PWDN_ACTIVE_DELAY_MS); + } + +@@ -415,7 +415,7 @@ static int ov5647_sensor_power(struct v4 + + clk_disable_unprepare(ov5647->xclk); + +- gpiod_set_value(ov5647->pwdn, 1); ++ gpiod_set_value_cansleep(ov5647->pwdn, 1); + } + + /* Update the power count. */ +@@ -649,13 +649,13 @@ static int ov5647_probe(struct i2c_clien + goto mutex_remove; + + if (sensor->pwdn) { +- gpiod_set_value(sensor->pwdn, 0); ++ gpiod_set_value_cansleep(sensor->pwdn, 0); + msleep(PWDN_ACTIVE_DELAY_MS); + } + + ret = ov5647_detect(sd); + +- gpiod_set_value(sensor->pwdn, 1); ++ gpiod_set_value_cansleep(sensor->pwdn, 1); + + if (ret < 0) + goto error; diff --git a/target/linux/brcm2708/patches-4.19/950-0327-input-rpi-ft5406-Clear-build-warning-on-64-bit-build.patch b/target/linux/brcm2708/patches-4.19/950-0327-input-rpi-ft5406-Clear-build-warning-on-64-bit-build.patch deleted file mode 100644 index ad4f2d5ed0..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0327-input-rpi-ft5406-Clear-build-warning-on-64-bit-build.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 9611b3067bd576a4a02bf503baf57db681571e3d Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 28 Jan 2019 14:42:34 +0000 -Subject: [PATCH 327/703] input: rpi-ft5406: Clear build warning on 64 bit - builds. - -Resolve 64 bit build warning over using %x with a dma_addr_t. - -Signed-off-by: Dave Stevenson ---- - drivers/input/touchscreen/rpi-ft5406.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/input/touchscreen/rpi-ft5406.c -+++ b/drivers/input/touchscreen/rpi-ft5406.c -@@ -218,8 +218,8 @@ static int ft5406_probe(struct platform_ - - if (!ts->ts_base) { - dev_warn(dev, -- "set failed, trying get (err:%d touchbuf:%x virt:%p bus:%x)\n", -- err, touchbuf, ts->ts_base, ts->bus_addr); -+ "set failed, trying get (err:%d touchbuf:%x virt:%p bus:%pad)\n", -+ err, touchbuf, ts->ts_base, &ts->bus_addr); - - err = rpi_firmware_property( - fw, diff --git a/target/linux/brcm2708/patches-4.19/950-0327-media-bcm2835-unicam-Power-on-subdev-on-open-release.patch b/target/linux/brcm2708/patches-4.19/950-0327-media-bcm2835-unicam-Power-on-subdev-on-open-release.patch new file mode 100644 index 0000000000..ab1dc23a5e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0327-media-bcm2835-unicam-Power-on-subdev-on-open-release.patch @@ -0,0 +1,121 @@ +From b5157050b90e884345d1d5ca9662cb8686f72b4a Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 29 Jan 2019 15:56:10 +0000 +Subject: [PATCH 327/725] media:bcm2835-unicam: Power on subdev on + open/release, not streaming + +The driver was powering on the source subdevice as part of STREAMON, +and powering it off in STREAMOFF. This isn't so great if there is a +significant amount of setup required for your device. + +Copy the approach taken in the Atmel ISC driver where s_power(1) is called +on first file handle open, and s_power(0) is called on the last release. + +See https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=232437 + +Signed-off-by: Dave Stevenson +--- + .../media/platform/bcm2835/bcm2835-unicam.c | 68 +++++++++++++++---- + 1 file changed, 54 insertions(+), 14 deletions(-) + +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -1237,11 +1237,6 @@ static int unicam_start_streaming(struct + unicam_err(dev, "Failed to enable CSI clock: %d\n", ret); + goto err_pm_put; + } +- ret = v4l2_subdev_call(dev->sensor, core, s_power, 1); +- if (ret < 0 && ret != -ENOIOCTLCMD) { +- unicam_err(dev, "power on failed in subdev\n"); +- goto err_clock_unprepare; +- } + dev->streaming = 1; + + unicam_start_rx(dev, addr); +@@ -1256,8 +1251,6 @@ static int unicam_start_streaming(struct + + err_disable_unicam: + unicam_disable(dev); +- v4l2_subdev_call(dev->sensor, core, s_power, 0); +-err_clock_unprepare: + clk_disable_unprepare(dev->clock); + err_pm_put: + unicam_runtime_put(dev); +@@ -1306,11 +1299,6 @@ static void unicam_stop_streaming(struct + dev->next_frm = NULL; + spin_unlock_irqrestore(&dev->dma_queue_lock, flags); + +- if (v4l2_subdev_has_op(dev->sensor, core, s_power)) { +- if (v4l2_subdev_call(dev->sensor, core, s_power, 0) < 0) +- unicam_err(dev, "power off failed in subdev\n"); +- } +- + clk_disable_unprepare(dev->clock); + unicam_runtime_put(dev); + } +@@ -1543,11 +1531,63 @@ static const struct vb2_ops unicam_video + .stop_streaming = unicam_stop_streaming, + }; + ++/* ++ * unicam_open : This function is based on the v4l2_fh_open helper function. ++ * It has been augmented to handle sensor subdevice power management, ++ */ ++static int unicam_open(struct file *file) ++{ ++ struct unicam_device *dev = video_drvdata(file); ++ int ret; ++ ++ mutex_lock(&dev->lock); ++ ++ ret = v4l2_fh_open(file); ++ if (ret) { ++ unicam_err(dev, "v4l2_fh_open failed\n"); ++ goto unlock; ++ } ++ ++ if (!v4l2_fh_is_singular_file(file)) ++ goto unlock; ++ ++ ret = v4l2_subdev_call(dev->sensor, core, s_power, 1); ++ if (ret < 0 && ret != -ENOIOCTLCMD) { ++ v4l2_fh_release(file); ++ goto unlock; ++ } ++ ++unlock: ++ mutex_unlock(&dev->lock); ++ return ret; ++} ++ ++static int unicam_release(struct file *file) ++{ ++ struct unicam_device *dev = video_drvdata(file); ++ struct v4l2_subdev *sd = dev->sensor; ++ bool fh_singular; ++ int ret; ++ ++ mutex_lock(&dev->lock); ++ ++ fh_singular = v4l2_fh_is_singular_file(file); ++ ++ ret = _vb2_fop_release(file, NULL); ++ ++ if (fh_singular) ++ v4l2_subdev_call(sd, core, s_power, 0); ++ ++ mutex_unlock(&dev->lock); ++ ++ return ret; ++} ++ + /* unicam capture driver file operations */ + static const struct v4l2_file_operations unicam_fops = { + .owner = THIS_MODULE, +- .open = v4l2_fh_open, +- .release = vb2_fop_release, ++ .open = unicam_open, ++ .release = unicam_release, + .read = vb2_fop_read, + .poll = vb2_fop_poll, + .unlocked_ioctl = video_ioctl2, diff --git a/target/linux/brcm2708/patches-4.19/950-0328-audioinjector-octo-revert-to-dummy-supplies.patch b/target/linux/brcm2708/patches-4.19/950-0328-audioinjector-octo-revert-to-dummy-supplies.patch new file mode 100644 index 0000000000..cf5c79df8f --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0328-audioinjector-octo-revert-to-dummy-supplies.patch @@ -0,0 +1,23 @@ +From 61225ddd346ff0633ced7774a4f65583fbeebc5c Mon Sep 17 00:00:00 2001 +From: Matt Flax +Date: Tue, 29 Jan 2019 14:56:03 +1100 +Subject: [PATCH 328/725] audioinjector-octo: revert to dummy supplies + +The Audio Injector Octo has had a lot of reports of not coming up on power cycles. By reverting to dummy supplies, the card comes up reliably. +--- + arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts | 4 ---- + 1 file changed, 4 deletions(-) + +--- a/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts ++++ b/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts +@@ -25,10 +25,6 @@ + reg = <0x48>; + clocks = <&cs42448_mclk>; + clock-names = "mclk"; +- VA-supply = <&vdd_5v0_reg>; +- VD-supply = <&vdd_3v3_reg>; +- VLS-supply = <&vdd_3v3_reg>; +- VLC-supply = <&vdd_3v3_reg>; + status = "okay"; + }; + diff --git a/target/linux/brcm2708/patches-4.19/950-0328-dtoverlays-Correct-DT-handling-camera-GPIOs.patch b/target/linux/brcm2708/patches-4.19/950-0328-dtoverlays-Correct-DT-handling-camera-GPIOs.patch deleted file mode 100644 index 707531c421..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0328-dtoverlays-Correct-DT-handling-camera-GPIOs.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 7ca9fd2d5c0488279fb746ef17c99f737416949d Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 18 Sep 2018 10:47:38 +0100 -Subject: [PATCH 328/703] dtoverlays: Correct DT handling camera GPIOs - -The firmware has support for updating overrides with the correct -GPIO settings for the camera GPIOs, but the wrong device tree -setup ended up being merged. -Correct the DT configuration so that the firmware does set it -up correctly. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/bcm270x.dtsi | 7 +++++++ - arch/arm/boot/dts/overlays/README | 10 +--------- - arch/arm/boot/dts/overlays/ov5647-overlay.dts | 14 +++++++++++--- - 3 files changed, 19 insertions(+), 12 deletions(-) - ---- a/arch/arm/boot/dts/bcm270x.dtsi -+++ b/arch/arm/boot/dts/bcm270x.dtsi -@@ -152,6 +152,13 @@ - regulator-max-microvolt = <3300000>; - regulator-always-on; - }; -+ -+ __overrides__ { -+ cam0-pwdn-ctrl; -+ cam0-pwdn; -+ cam0-led-ctrl; -+ cam0-led; -+ }; - }; - - &vc4 { ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1366,15 +1366,7 @@ Info: Omnivision OV5647 camera module. - Uses Unicam 1, which is the standard camera connector on most Pi - variants. - Load: dtoverlay=ov5647,= --Params: cam0-pwdn GPIO used to control the sensor powerdown line. -- -- cam0-led GPIO used to control the sensor led -- Both these fields should be automatically filled -- in by the firmware to reflect the default GPIO -- configuration of the particular Pi variant in -- use. -- -- i2c_pins_0_1 Use pins 0&1 for the I2C instead of 44&45. -+Params: i2c_pins_0_1 Use pins 0&1 for the I2C instead of 44&45. - Useful on Compute Modules. - - i2c_pins_28_29 Use pins 28&29 for the I2C instead of 44&45. ---- a/arch/arm/boot/dts/overlays/ov5647-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ov5647-overlay.dts -@@ -14,7 +14,7 @@ - status = "okay"; - - ov5647: ov5647@36 { -- compatible = "ov5647"; -+ compatible = "ovti,ov5647"; - reg = <0x36>; - status = "okay"; - -@@ -82,10 +82,18 @@ - }; - }; - -+ fragment@6 { -+ target-path="/__overrides__"; -+ __overlay__ { -+ cam0-pwdn-ctrl = <&ov5647>,"pwdn-gpios:0"; -+ cam0-pwdn = <&ov5647>,"pwdn-gpios:4"; -+ cam0-led-ctrl = <&ov5647>,"pwdn-gpios:12"; -+ cam0-led = <&ov5647>,"pwdn-gpios:16"; -+ }; -+ }; -+ - __overrides__ { - i2c_pins_0_1 = <0>,"-2-3+4"; - i2c_pins_28_29 = <0>,"+2-3-4"; -- cam0-pwdn = <&ov5647>,"pwdn-gpios:4"; -- cam0-led = <&ov5647>,"pwdn-gpios:16"; - }; - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0329-media-ov5647-Use-gpiod_set_value_cansleep.patch b/target/linux/brcm2708/patches-4.19/950-0329-media-ov5647-Use-gpiod_set_value_cansleep.patch deleted file mode 100644 index 5ac15ba630..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0329-media-ov5647-Use-gpiod_set_value_cansleep.patch +++ /dev/null @@ -1,54 +0,0 @@ -From eca3d1380c02a49273c89ce988532dd23a964860 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 18 Sep 2018 11:08:51 +0100 -Subject: [PATCH 329/703] media: ov5647: Use gpiod_set_value_cansleep - -All calls to the gpio library are in contexts that can sleep, -therefore there is no issue with having those GPIOs controlled -by controllers which require sleeping (eg I2C GPIO expanders). - -Switch to using gpiod_set_value_cansleep instead of gpiod_set_value -to avoid triggering the warning in gpiolib should the GPIO -controller need to sleep. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov5647.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/media/i2c/ov5647.c -+++ b/drivers/media/i2c/ov5647.c -@@ -373,7 +373,7 @@ static int ov5647_sensor_power(struct v4 - dev_dbg(&client->dev, "OV5647 power on\n"); - - if (ov5647->pwdn) { -- gpiod_set_value(ov5647->pwdn, 0); -+ gpiod_set_value_cansleep(ov5647->pwdn, 0); - msleep(PWDN_ACTIVE_DELAY_MS); - } - -@@ -415,7 +415,7 @@ static int ov5647_sensor_power(struct v4 - - clk_disable_unprepare(ov5647->xclk); - -- gpiod_set_value(ov5647->pwdn, 1); -+ gpiod_set_value_cansleep(ov5647->pwdn, 1); - } - - /* Update the power count. */ -@@ -649,13 +649,13 @@ static int ov5647_probe(struct i2c_clien - goto mutex_remove; - - if (sensor->pwdn) { -- gpiod_set_value(sensor->pwdn, 0); -+ gpiod_set_value_cansleep(sensor->pwdn, 0); - msleep(PWDN_ACTIVE_DELAY_MS); - } - - ret = ov5647_detect(sd); - -- gpiod_set_value(sensor->pwdn, 1); -+ gpiod_set_value_cansleep(sensor->pwdn, 1); - - if (ret < 0) - goto error; diff --git a/target/linux/brcm2708/patches-4.19/950-0329-staging-bcm2835-camera-Correct-ctrl-min-max-step-def.patch b/target/linux/brcm2708/patches-4.19/950-0329-staging-bcm2835-camera-Correct-ctrl-min-max-step-def.patch new file mode 100644 index 0000000000..14da217919 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0329-staging-bcm2835-camera-Correct-ctrl-min-max-step-def.patch @@ -0,0 +1,58 @@ +From 18d7a1b078978858569a03e4c0d373ac50f6d283 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 24 Jan 2019 16:20:38 +0000 +Subject: [PATCH 329/725] staging: bcm2835-camera: Correct ctrl + min/max/step/def to 64bit + +The V4L2 control API was expanded to take 64 bit values in commit +0ba2aeb6dab (Apr 16 2014), but as this driver wasn't in the mainline +kernel at that point this was overlooked. + +Update to use 64 bit values. This also fixes a couple of warnings +in 64 bit builds. + +Signed-off-by: Dave Stevenson +--- + .../vc04_services/bcm2835-camera/controls.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-camera/controls.c ++++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c +@@ -78,10 +78,10 @@ struct bm2835_mmal_v4l2_ctrl { + /* control minimum value or + * mask for MMAL_CONTROL_TYPE_STD_MENU + */ +- s32 min; +- s32 max; /* maximum value of control */ +- s32 def; /* default value of control */ +- s32 step; /* step size of the control */ ++ s64 min; ++ s64 max; /* maximum value of control */ ++ s64 def; /* default value of control */ ++ u64 step; /* step size of the control */ + const s64 *imenu; /* integer menu array */ + u32 mmal_id; /* mmal parameter id */ + bm2835_mmal_v4l2_ctrl_cb *setter; +@@ -1244,7 +1244,7 @@ int bm2835_mmal_init_controls(struct bm2 + + case MMAL_CONTROL_TYPE_STD_MENU: + { +- int mask = ctrl->min; ++ u64 mask = ctrl->min; + + if (ctrl->id == V4L2_CID_SCENE_MODE) { + /* Special handling to work out the mask +@@ -1254,11 +1254,11 @@ int bm2835_mmal_init_controls(struct bm2 + */ + int i; + +- mask = 1 << V4L2_SCENE_MODE_NONE; ++ mask = BIT(V4L2_SCENE_MODE_NONE); + for (i = 0; + i < ARRAY_SIZE(scene_configs); + i++) { +- mask |= 1 << scene_configs[i].v4l2_scene; ++ mask |= BIT(scene_configs[i].v4l2_scene); + } + mask = ~mask; + } diff --git a/target/linux/brcm2708/patches-4.19/950-0330-media-bcm2835-unicam-Power-on-subdev-on-open-release.patch b/target/linux/brcm2708/patches-4.19/950-0330-media-bcm2835-unicam-Power-on-subdev-on-open-release.patch deleted file mode 100644 index d6294cf206..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0330-media-bcm2835-unicam-Power-on-subdev-on-open-release.patch +++ /dev/null @@ -1,121 +0,0 @@ -From e627fc071de98ec50c88869b579bb90f15043e3d Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 29 Jan 2019 15:56:10 +0000 -Subject: [PATCH 330/703] media:bcm2835-unicam: Power on subdev on - open/release, not streaming - -The driver was powering on the source subdevice as part of STREAMON, -and powering it off in STREAMOFF. This isn't so great if there is a -significant amount of setup required for your device. - -Copy the approach taken in the Atmel ISC driver where s_power(1) is called -on first file handle open, and s_power(0) is called on the last release. - -See https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=232437 - -Signed-off-by: Dave Stevenson ---- - .../media/platform/bcm2835/bcm2835-unicam.c | 68 +++++++++++++++---- - 1 file changed, 54 insertions(+), 14 deletions(-) - ---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c -+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c -@@ -1237,11 +1237,6 @@ static int unicam_start_streaming(struct - unicam_err(dev, "Failed to enable CSI clock: %d\n", ret); - goto err_pm_put; - } -- ret = v4l2_subdev_call(dev->sensor, core, s_power, 1); -- if (ret < 0 && ret != -ENOIOCTLCMD) { -- unicam_err(dev, "power on failed in subdev\n"); -- goto err_clock_unprepare; -- } - dev->streaming = 1; - - unicam_start_rx(dev, addr); -@@ -1256,8 +1251,6 @@ static int unicam_start_streaming(struct - - err_disable_unicam: - unicam_disable(dev); -- v4l2_subdev_call(dev->sensor, core, s_power, 0); --err_clock_unprepare: - clk_disable_unprepare(dev->clock); - err_pm_put: - unicam_runtime_put(dev); -@@ -1306,11 +1299,6 @@ static void unicam_stop_streaming(struct - dev->next_frm = NULL; - spin_unlock_irqrestore(&dev->dma_queue_lock, flags); - -- if (v4l2_subdev_has_op(dev->sensor, core, s_power)) { -- if (v4l2_subdev_call(dev->sensor, core, s_power, 0) < 0) -- unicam_err(dev, "power off failed in subdev\n"); -- } -- - clk_disable_unprepare(dev->clock); - unicam_runtime_put(dev); - } -@@ -1543,11 +1531,63 @@ static const struct vb2_ops unicam_video - .stop_streaming = unicam_stop_streaming, - }; - -+/* -+ * unicam_open : This function is based on the v4l2_fh_open helper function. -+ * It has been augmented to handle sensor subdevice power management, -+ */ -+static int unicam_open(struct file *file) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ int ret; -+ -+ mutex_lock(&dev->lock); -+ -+ ret = v4l2_fh_open(file); -+ if (ret) { -+ unicam_err(dev, "v4l2_fh_open failed\n"); -+ goto unlock; -+ } -+ -+ if (!v4l2_fh_is_singular_file(file)) -+ goto unlock; -+ -+ ret = v4l2_subdev_call(dev->sensor, core, s_power, 1); -+ if (ret < 0 && ret != -ENOIOCTLCMD) { -+ v4l2_fh_release(file); -+ goto unlock; -+ } -+ -+unlock: -+ mutex_unlock(&dev->lock); -+ return ret; -+} -+ -+static int unicam_release(struct file *file) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ struct v4l2_subdev *sd = dev->sensor; -+ bool fh_singular; -+ int ret; -+ -+ mutex_lock(&dev->lock); -+ -+ fh_singular = v4l2_fh_is_singular_file(file); -+ -+ ret = _vb2_fop_release(file, NULL); -+ -+ if (fh_singular) -+ v4l2_subdev_call(sd, core, s_power, 0); -+ -+ mutex_unlock(&dev->lock); -+ -+ return ret; -+} -+ - /* unicam capture driver file operations */ - static const struct v4l2_file_operations unicam_fops = { - .owner = THIS_MODULE, -- .open = v4l2_fh_open, -- .release = vb2_fop_release, -+ .open = unicam_open, -+ .release = unicam_release, - .read = vb2_fop_read, - .poll = vb2_fop_poll, - .unlocked_ioctl = video_ioctl2, diff --git a/target/linux/brcm2708/patches-4.19/950-0330-staging-bcm2835-codec-variable-vb2-may-be-used-unini.patch b/target/linux/brcm2708/patches-4.19/950-0330-staging-bcm2835-codec-variable-vb2-may-be-used-unini.patch new file mode 100644 index 0000000000..a962de3eac --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0330-staging-bcm2835-codec-variable-vb2-may-be-used-unini.patch @@ -0,0 +1,37 @@ +From 9de4607bb5558db3856298e6f3674d9b794ed3bf Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 24 Jan 2019 16:40:01 +0000 +Subject: [PATCH 330/725] staging: bcm2835-codec: variable vb2 may be used + uninitialised + +In op_buffer_cb, the failure path checked whether there was +an associated vb2 buffer before the variable vb2 had been +assigned. + +Signed-off-by: Dave Stevenson +--- + .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -634,6 +634,9 @@ static void op_buffer_cb(struct vchiq_mm + __func__, status, mmal_buf, mmal_buf->length, + mmal_buf->mmal_flags, mmal_buf->pts); + ++ buf = container_of(mmal_buf, struct m2m_mmal_buffer, mmal); ++ vb2 = &buf->m2m.vb; ++ + if (status) { + /* error in transfer */ + if (vb2) { +@@ -658,9 +661,6 @@ static void op_buffer_cb(struct vchiq_mm + return; + } + +- buf = container_of(mmal_buf, struct m2m_mmal_buffer, mmal); +- vb2 = &buf->m2m.vb; +- + v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: length %lu, flags %x, idx %u\n", + __func__, mmal_buf->length, mmal_buf->mmal_flags, + vb2->vb2_buf.index); diff --git a/target/linux/brcm2708/patches-4.19/950-0331-audioinjector-octo-revert-to-dummy-supplies.patch b/target/linux/brcm2708/patches-4.19/950-0331-audioinjector-octo-revert-to-dummy-supplies.patch deleted file mode 100644 index db005e6af6..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0331-audioinjector-octo-revert-to-dummy-supplies.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 6fcdc4686f212cb572a0b93a293f6b6fb2a49992 Mon Sep 17 00:00:00 2001 -From: Matt Flax -Date: Tue, 29 Jan 2019 14:56:03 +1100 -Subject: [PATCH 331/703] audioinjector-octo: revert to dummy supplies - -The Audio Injector Octo has had a lot of reports of not coming up on power cycles. By reverting to dummy supplies, the card comes up reliably. ---- - arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts | 4 ---- - 1 file changed, 4 deletions(-) - ---- a/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts -+++ b/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts -@@ -25,10 +25,6 @@ - reg = <0x48>; - clocks = <&cs42448_mclk>; - clock-names = "mclk"; -- VA-supply = <&vdd_5v0_reg>; -- VD-supply = <&vdd_3v3_reg>; -- VLS-supply = <&vdd_3v3_reg>; -- VLC-supply = <&vdd_3v3_reg>; - status = "okay"; - }; - diff --git a/target/linux/brcm2708/patches-4.19/950-0331-staging-bcm2835-codec-Fix-potentially-uninitialised-.patch b/target/linux/brcm2708/patches-4.19/950-0331-staging-bcm2835-codec-Fix-potentially-uninitialised-.patch new file mode 100644 index 0000000000..18463669ff --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0331-staging-bcm2835-codec-Fix-potentially-uninitialised-.patch @@ -0,0 +1,25 @@ +From ba444bcaef82a4ffb43d6400459b213c9c696566 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 24 Jan 2019 16:36:19 +0000 +Subject: [PATCH 331/725] staging: bcm2835-codec: Fix potentially uninitialised + vars + +src_m2m_buf and dst_m2m_buf were printed in log messages +when there are code paths that don't initialise them. + +Signed-off-by: Dave Stevenson +--- + .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -743,7 +743,7 @@ static void device_run(void *priv) + struct bcm2835_codec_ctx *ctx = priv; + struct bcm2835_codec_dev *dev = ctx->dev; + struct vb2_v4l2_buffer *src_buf, *dst_buf; +- struct m2m_mmal_buffer *src_m2m_buf, *dst_m2m_buf; ++ struct m2m_mmal_buffer *src_m2m_buf = NULL, *dst_m2m_buf = NULL; + struct v4l2_m2m_buffer *m2m; + int ret; + diff --git a/target/linux/brcm2708/patches-4.19/950-0332-staging-bcm2835-camera-Correct-ctrl-min-max-step-def.patch b/target/linux/brcm2708/patches-4.19/950-0332-staging-bcm2835-camera-Correct-ctrl-min-max-step-def.patch deleted file mode 100644 index e8fb4e2337..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0332-staging-bcm2835-camera-Correct-ctrl-min-max-step-def.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0bdc8ddc14e97955e91c999b42f90f420a190027 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 24 Jan 2019 16:20:38 +0000 -Subject: [PATCH 332/703] staging: bcm2835-camera: Correct ctrl - min/max/step/def to 64bit - -The V4L2 control API was expanded to take 64 bit values in commit -0ba2aeb6dab (Apr 16 2014), but as this driver wasn't in the mainline -kernel at that point this was overlooked. - -Update to use 64 bit values. This also fixes a couple of warnings -in 64 bit builds. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/bcm2835-camera/controls.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-camera/controls.c -+++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c -@@ -78,10 +78,10 @@ struct bm2835_mmal_v4l2_ctrl { - /* control minimum value or - * mask for MMAL_CONTROL_TYPE_STD_MENU - */ -- s32 min; -- s32 max; /* maximum value of control */ -- s32 def; /* default value of control */ -- s32 step; /* step size of the control */ -+ s64 min; -+ s64 max; /* maximum value of control */ -+ s64 def; /* default value of control */ -+ u64 step; /* step size of the control */ - const s64 *imenu; /* integer menu array */ - u32 mmal_id; /* mmal parameter id */ - bm2835_mmal_v4l2_ctrl_cb *setter; -@@ -1244,7 +1244,7 @@ int bm2835_mmal_init_controls(struct bm2 - - case MMAL_CONTROL_TYPE_STD_MENU: - { -- int mask = ctrl->min; -+ u64 mask = ctrl->min; - - if (ctrl->id == V4L2_CID_SCENE_MODE) { - /* Special handling to work out the mask -@@ -1254,11 +1254,11 @@ int bm2835_mmal_init_controls(struct bm2 - */ - int i; - -- mask = 1 << V4L2_SCENE_MODE_NONE; -+ mask = BIT(V4L2_SCENE_MODE_NONE); - for (i = 0; - i < ARRAY_SIZE(scene_configs); - i++) { -- mask |= 1 << scene_configs[i].v4l2_scene; -+ mask |= BIT(scene_configs[i].v4l2_scene); - } - mask = ~mask; - } diff --git a/target/linux/brcm2708/patches-4.19/950-0332-video-bcm2708_fb-Add-compat_ioctl-support.patch b/target/linux/brcm2708/patches-4.19/950-0332-video-bcm2708_fb-Add-compat_ioctl-support.patch new file mode 100644 index 0000000000..e4fb0a135b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0332-video-bcm2708_fb-Add-compat_ioctl-support.patch @@ -0,0 +1,154 @@ +From de3edf2e5a0d2f8c9d20b8449e91d086ccf0514b Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 25 Jan 2019 17:12:54 +0000 +Subject: [PATCH 332/725] video: bcm2708_fb: Add compat_ioctl support. + +When using a 64 bit kernel with 32 bit userspace we need +compat ioctl handling for FBIODMACOPY as one of the +parameters is a pointer. + +Signed-off-by: Dave Stevenson +--- + drivers/video/fbdev/bcm2708_fb.c | 87 ++++++++++++++++++++++++-------- + 1 file changed, 66 insertions(+), 21 deletions(-) + +--- a/drivers/video/fbdev/bcm2708_fb.c ++++ b/drivers/video/fbdev/bcm2708_fb.c +@@ -482,9 +482,8 @@ static void dma_memcpy(struct bcm2708_fb + /* cache coherent but non-allocating in L1 and L2 */ + #define INTALIAS_L1L2_NONALLOCATING(x) (((x)&~0xc0000000)|0x80000000) + +-static long vc_mem_copy(struct bcm2708_fb *fb, unsigned long arg) ++static long vc_mem_copy(struct bcm2708_fb *fb, struct fb_dmacopy *ioparam) + { +- struct fb_dmacopy ioparam; + size_t size = PAGE_SIZE; + u32 *buf = NULL; + dma_addr_t bus_addr; +@@ -497,26 +496,16 @@ static long vc_mem_copy(struct bcm2708_f + goto out; + } + +- /* Get the parameter data. +- */ +- if (copy_from_user +- (&ioparam, (void *)arg, sizeof(ioparam)) != 0) { +- pr_err("[%s]: failed to copy-from-user\n", +- __func__); +- rc = -EFAULT; +- goto out; +- } +- +- if (fb->gpu.base == 0 || fb->gpu.length == 0) { ++ if (!fb->gpu.base || !fb->gpu.length) { + pr_err("[%s]: Unable to determine gpu memory (%x,%x)\n", + __func__, fb->gpu.base, fb->gpu.length); + return -EFAULT; + } + +- if (INTALIAS_NORMAL(ioparam.src) < fb->gpu.base || +- INTALIAS_NORMAL(ioparam.src) >= fb->gpu.base + fb->gpu.length) { ++ if (INTALIAS_NORMAL(ioparam->src) < fb->gpu.base || ++ INTALIAS_NORMAL(ioparam->src) >= fb->gpu.base + fb->gpu.length) { + pr_err("[%s]: Invalid memory access %x (%x-%x)", __func__, +- INTALIAS_NORMAL(ioparam.src), fb->gpu.base, ++ INTALIAS_NORMAL(ioparam->src), fb->gpu.base, + fb->gpu.base + fb->gpu.length); + return -EFAULT; + } +@@ -530,11 +519,11 @@ static long vc_mem_copy(struct bcm2708_f + goto out; + } + +- for (offset = 0; offset < ioparam.length; offset += size) { +- size_t remaining = ioparam.length - offset; ++ for (offset = 0; offset < ioparam->length; offset += size) { ++ size_t remaining = ioparam->length - offset; + size_t s = min(size, remaining); +- unsigned char *p = (unsigned char *)ioparam.src + offset; +- unsigned char *q = (unsigned char *)ioparam.dst + offset; ++ u8 *p = (u8 *)((uintptr_t)ioparam->src + offset); ++ u8 *q = (u8 *)ioparam->dst + offset; + + dma_memcpy(fb, bus_addr, + INTALIAS_L1L2_NONALLOCATING((dma_addr_t)p), size); +@@ -566,8 +555,19 @@ static int bcm2708_ioctl(struct fb_info + &dummy, sizeof(dummy)); + break; + case FBIODMACOPY: +- ret = vc_mem_copy(fb, arg); ++ { ++ struct fb_dmacopy ioparam; ++ /* Get the parameter data. ++ */ ++ if (copy_from_user ++ (&ioparam, (void *)arg, sizeof(ioparam))) { ++ pr_err("[%s]: failed to copy-from-user\n", __func__); ++ ret = -EFAULT; ++ break; ++ } ++ ret = vc_mem_copy(fb, &ioparam); + break; ++ } + default: + dev_dbg(info->device, "Unknown ioctl 0x%x\n", cmd); + return -ENOTTY; +@@ -578,6 +578,48 @@ static int bcm2708_ioctl(struct fb_info + + return ret; + } ++ ++#ifdef CONFIG_COMPAT ++struct fb_dmacopy32 { ++ compat_uptr_t dst; ++ __u32 src; ++ __u32 length; ++}; ++ ++#define FBIODMACOPY32 _IOW('z', 0x22, struct fb_dmacopy32) ++ ++static int bcm2708_compat_ioctl(struct fb_info *info, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct bcm2708_fb *fb = to_bcm2708(info); ++ int ret; ++ ++ switch (cmd) { ++ case FBIODMACOPY32: ++ { ++ struct fb_dmacopy32 param32; ++ struct fb_dmacopy param; ++ /* Get the parameter data. ++ */ ++ if (copy_from_user(¶m32, (void *)arg, sizeof(param32))) { ++ pr_err("[%s]: failed to copy-from-user\n", __func__); ++ ret = -EFAULT; ++ break; ++ } ++ param.dst = compat_ptr(param32.dst); ++ param.src = param32.src; ++ param.length = param32.length; ++ ret = vc_mem_copy(fb, ¶m); ++ break; ++ } ++ default: ++ ret = bcm2708_ioctl(info, cmd, arg); ++ break; ++ } ++ return ret; ++} ++#endif ++ + static void bcm2708_fb_fillrect(struct fb_info *info, + const struct fb_fillrect *rect) + { +@@ -768,6 +810,9 @@ static struct fb_ops bcm2708_fb_ops = { + .fb_imageblit = bcm2708_fb_imageblit, + .fb_pan_display = bcm2708_fb_pan_display, + .fb_ioctl = bcm2708_ioctl, ++#ifdef CONFIG_COMPAT ++ .fb_compat_ioctl = bcm2708_compat_ioctl, ++#endif + }; + + static int bcm2708_fb_register(struct bcm2708_fb *fb) diff --git a/target/linux/brcm2708/patches-4.19/950-0333-staging-bcm2835-codec-variable-vb2-may-be-used-unini.patch b/target/linux/brcm2708/patches-4.19/950-0333-staging-bcm2835-codec-variable-vb2-may-be-used-unini.patch deleted file mode 100644 index 79c953bea6..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0333-staging-bcm2835-codec-variable-vb2-may-be-used-unini.patch +++ /dev/null @@ -1,37 +0,0 @@ -From e53e03707c6de4230a67633e5eb534e244d21b9e Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 24 Jan 2019 16:40:01 +0000 -Subject: [PATCH 333/703] staging: bcm2835-codec: variable vb2 may be used - uninitialised - -In op_buffer_cb, the failure path checked whether there was -an associated vb2 buffer before the variable vb2 had been -assigned. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -634,6 +634,9 @@ static void op_buffer_cb(struct vchiq_mm - __func__, status, mmal_buf, mmal_buf->length, - mmal_buf->mmal_flags, mmal_buf->pts); - -+ buf = container_of(mmal_buf, struct m2m_mmal_buffer, mmal); -+ vb2 = &buf->m2m.vb; -+ - if (status) { - /* error in transfer */ - if (vb2) { -@@ -658,9 +661,6 @@ static void op_buffer_cb(struct vchiq_mm - return; - } - -- buf = container_of(mmal_buf, struct m2m_mmal_buffer, mmal); -- vb2 = &buf->m2m.vb; -- - v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: length %lu, flags %x, idx %u\n", - __func__, mmal_buf->length, mmal_buf->mmal_flags, - vb2->vb2_buf.index); diff --git a/target/linux/brcm2708/patches-4.19/950-0333-video-bcm2708_fb-Fix-warnings-on-64-bit-builds.patch b/target/linux/brcm2708/patches-4.19/950-0333-video-bcm2708_fb-Fix-warnings-on-64-bit-builds.patch new file mode 100644 index 0000000000..2a72c8c9ea --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0333-video-bcm2708_fb-Fix-warnings-on-64-bit-builds.patch @@ -0,0 +1,46 @@ +From adc3f3ca7e12a464413ccb451cdcd928a1018229 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 25 Jan 2019 17:11:39 +0000 +Subject: [PATCH 333/725] video: bcm2708_fb: Fix warnings on 64 bit builds + +Fix up logging lines where the wrong format specifiers were +being used. + +Signed-off-by: Dave Stevenson +--- + drivers/video/fbdev/bcm2708_fb.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +--- a/drivers/video/fbdev/bcm2708_fb.c ++++ b/drivers/video/fbdev/bcm2708_fb.c +@@ -513,8 +513,8 @@ static long vc_mem_copy(struct bcm2708_f + buf = dma_alloc_coherent(fb->fb.device, PAGE_ALIGN(size), &bus_addr, + GFP_ATOMIC); + if (!buf) { +- pr_err("[%s]: failed to dma_alloc_coherent(%d)\n", +- __func__, size); ++ pr_err("[%s]: failed to dma_alloc_coherent(%zd)\n", __func__, ++ size); + rc = -ENOMEM; + goto out; + } +@@ -910,8 +910,7 @@ static int bcm2708_fb_probe(struct platf + goto free_fb; + } + +- pr_info("BCM2708FB: allocated DMA memory %08x\n", +- fb->cb_handle); ++ pr_info("BCM2708FB: allocated DMA memory %pad\n", &fb->cb_handle); + + ret = bcm_dma_chan_alloc(BCM_DMA_FEATURE_BULK, + &fb->dma_chan_base, &fb->dma_irq); +@@ -929,8 +928,7 @@ static int bcm2708_fb_probe(struct platf + } + + +- pr_info("BCM2708FB: allocated DMA channel %d @ %p\n", +- fb->dma_chan, fb->dma_chan_base); ++ pr_info("BCM2708FB: allocated DMA channel %d\n", fb->dma_chan); + + fb->dev = dev; + fb->fb.device = &dev->dev; diff --git a/target/linux/brcm2708/patches-4.19/950-0334-staging-bcm2835-codec-Fix-potentially-uninitialised-.patch b/target/linux/brcm2708/patches-4.19/950-0334-staging-bcm2835-codec-Fix-potentially-uninitialised-.patch deleted file mode 100644 index 72688e4d47..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0334-staging-bcm2835-codec-Fix-potentially-uninitialised-.patch +++ /dev/null @@ -1,25 +0,0 @@ -From ee043e469252c42db198e66f4e4c290dcd48d4a0 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 24 Jan 2019 16:36:19 +0000 -Subject: [PATCH 334/703] staging: bcm2835-codec: Fix potentially uninitialised - vars - -src_m2m_buf and dst_m2m_buf were printed in log messages -when there are code paths that don't initialise them. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -743,7 +743,7 @@ static void device_run(void *priv) - struct bcm2835_codec_ctx *ctx = priv; - struct bcm2835_codec_dev *dev = ctx->dev; - struct vb2_v4l2_buffer *src_buf, *dst_buf; -- struct m2m_mmal_buffer *src_m2m_buf, *dst_m2m_buf; -+ struct m2m_mmal_buffer *src_m2m_buf = NULL, *dst_m2m_buf = NULL; - struct v4l2_m2m_buffer *m2m; - int ret; - diff --git a/target/linux/brcm2708/patches-4.19/950-0334-video-bcm2708_fb-Clean-up-coding-style-issues.patch b/target/linux/brcm2708/patches-4.19/950-0334-video-bcm2708_fb-Clean-up-coding-style-issues.patch new file mode 100644 index 0000000000..83e2a879da --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0334-video-bcm2708_fb-Clean-up-coding-style-issues.patch @@ -0,0 +1,275 @@ +From 48ec221a8e6a5f8386e4b5346ca5bc89651588a2 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 25 Jan 2019 17:32:54 +0000 +Subject: [PATCH 334/725] video: bcm2708_fb: Clean up coding style issues + +Now checkpatch clean except for 2 long lines, missing +SPDX header, and no DT documentation. + +Signed-off-by: Dave Stevenson +--- + drivers/video/fbdev/bcm2708_fb.c | 96 ++++++++++++++------------------ + 1 file changed, 42 insertions(+), 54 deletions(-) + +--- a/drivers/video/fbdev/bcm2708_fb.c ++++ b/drivers/video/fbdev/bcm2708_fb.c +@@ -41,7 +41,7 @@ + #define MODULE_NAME "bcm2708_fb" + + #ifdef BCM2708_FB_DEBUG +-#define print_debug(fmt, ...) pr_debug("%s:%s:%d: "fmt, \ ++#define print_debug(fmt, ...) pr_debug("%s:%s:%d: " fmt, \ + MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__) + #else + #define print_debug(fmt, ...) +@@ -57,7 +57,7 @@ static int fbheight = 480; /* module par + static int fbdepth = 32; /* module parameter */ + static int fbswap; /* module parameter */ + +-static u32 dma_busy_wait_threshold = 1<<15; ++static u32 dma_busy_wait_threshold = 1 << 15; + module_param(dma_busy_wait_threshold, int, 0644); + MODULE_PARM_DESC(dma_busy_wait_threshold, "Busy-wait for DMA completion below this area"); + +@@ -132,8 +132,8 @@ static int bcm2708_fb_debugfs_init(struc + fb->stats.regset.nregs = ARRAY_SIZE(stats_registers); + fb->stats.regset.base = &fb->stats; + +- if (!debugfs_create_regset32( +- "stats", 0444, fb->debugfs_dir, &fb->stats.regset)) { ++ if (!debugfs_create_regset32("stats", 0444, fb->debugfs_dir, ++ &fb->stats.regset)) { + pr_warn("%s: could not create statistics registers\n", + __func__); + goto fail; +@@ -223,25 +223,22 @@ static int bcm2708_fb_check_var(struct f + { + /* info input, var output */ + print_debug("%s(%p) %dx%d (%dx%d), %d, %d\n", +- __func__, +- info, +- info->var.xres, info->var.yres, info->var.xres_virtual, +- info->var.yres_virtual, (int)info->screen_size, +- info->var.bits_per_pixel); +- print_debug("%s(%p) %dx%d (%dx%d), %d\n", __func__, var, +- var->xres, var->yres, var->xres_virtual, var->yres_virtual, +- var->bits_per_pixel); ++ __func__, info, info->var.xres, info->var.yres, ++ info->var.xres_virtual, info->var.yres_virtual, ++ (int)info->screen_size, info->var.bits_per_pixel); ++ print_debug("%s(%p) %dx%d (%dx%d), %d\n", __func__, var, var->xres, ++ var->yres, var->xres_virtual, var->yres_virtual, ++ var->bits_per_pixel); + + if (!var->bits_per_pixel) + var->bits_per_pixel = 16; + + if (bcm2708_fb_set_bitfields(var) != 0) { + pr_err("%s: invalid bits_per_pixel %d\n", __func__, +- var->bits_per_pixel); ++ var->bits_per_pixel); + return -EINVAL; + } + +- + if (var->xres_virtual < var->xres) + var->xres_virtual = var->xres; + /* use highest possible virtual resolution */ +@@ -249,7 +246,7 @@ static int bcm2708_fb_check_var(struct f + var->yres_virtual = 480; + + pr_err("%s: virtual resolution set to maximum of %dx%d\n", +- __func__, var->xres_virtual, var->yres_virtual); ++ __func__, var->xres_virtual, var->yres_virtual); + } + if (var->yres_virtual < var->yres) + var->yres_virtual = var->yres; +@@ -294,9 +291,9 @@ static int bcm2708_fb_set_par(struct fb_ + int ret; + + print_debug("%s(%p) %dx%d (%dx%d), %d, %d\n", __func__, info, +- info->var.xres, info->var.yres, info->var.xres_virtual, +- info->var.yres_virtual, (int)info->screen_size, +- info->var.bits_per_pixel); ++ info->var.xres, info->var.yres, info->var.xres_virtual, ++ info->var.yres_virtual, (int)info->screen_size, ++ info->var.bits_per_pixel); + + ret = rpi_firmware_property_list(fb->fw, &fbinfo, sizeof(fbinfo)); + if (ret) { +@@ -328,12 +325,10 @@ static int bcm2708_fb_set_par(struct fb_ + return -ENOMEM; + } + +- print_debug( +- "%s: start = %p,%p width=%d, height=%d, bpp=%d, pitch=%d size=%d\n", +- __func__, +- (void *)fb->fb.screen_base, (void *)fb->fb_bus_address, +- fbinfo.xres, fbinfo.yres, fbinfo.bpp, +- fbinfo.pitch, (int)fb->fb.screen_size); ++ print_debug("%s: start = %p,%p width=%d, height=%d, bpp=%d, pitch=%d size=%d\n", ++ __func__, (void *)fb->fb.screen_base, ++ (void *)fb->fb_bus_address, fbinfo.xres, fbinfo.yres, ++ fbinfo.bpp, fbinfo.pitch, (int)fb->fb.screen_size); + + return 0; + } +@@ -345,7 +340,6 @@ static inline u32 convert_bitfield(int v + return (val >> (16 - bf->length) & mask) << bf->offset; + } + +- + static int bcm2708_fb_setcolreg(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + unsigned int transp, struct fb_info *info) +@@ -379,11 +373,11 @@ static int bcm2708_fb_setcolreg(unsigned + packet->offset = 0; + packet->length = regno + 1; + memcpy(packet->cmap, fb->gpu_cmap, +- sizeof(packet->cmap)); ++ sizeof(packet->cmap)); + ret = rpi_firmware_property(fb->fw, +- RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE, +- packet, +- (2 + packet->length) * sizeof(u32)); ++ RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE, ++ packet, ++ (2 + packet->length) * sizeof(u32)); + if (ret || packet->offset) + dev_err(info->device, + "Failed to set palette (%d,%u)\n", +@@ -392,9 +386,9 @@ static int bcm2708_fb_setcolreg(unsigned + } + } else if (regno < 16) { + fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) | +- convert_bitfield(blue, &fb->fb.var.blue) | +- convert_bitfield(green, &fb->fb.var.green) | +- convert_bitfield(red, &fb->fb.var.red); ++ convert_bitfield(blue, &fb->fb.var.blue) | ++ convert_bitfield(green, &fb->fb.var.green) | ++ convert_bitfield(red, &fb->fb.var.red); + } + return regno > 255; + } +@@ -437,8 +431,8 @@ static int bcm2708_fb_pan_display(struct + info->var.yoffset = var->yoffset; + result = bcm2708_fb_set_par(info); + if (result != 0) +- pr_err("%s(%d,%d) returns=%d\n", __func__, +- var->xoffset, var->yoffset, result); ++ pr_err("%s(%d,%d) returns=%d\n", __func__, var->xoffset, ++ var->yoffset, result); + return result; + } + +@@ -468,9 +462,8 @@ static void dma_memcpy(struct bcm2708_fb + cb->info |= BCM2708_DMA_INT_EN; + bcm_dma_start(fb->dma_chan_base, fb->cb_handle); + while (bcm_dma_is_busy(dma_chan)) { +- wait_event_interruptible( +- fb->dma_waitq, +- !bcm_dma_is_busy(dma_chan)); ++ wait_event_interruptible(fb->dma_waitq, ++ !bcm_dma_is_busy(dma_chan)); + } + fb->stats.dma_irqs++; + } +@@ -478,9 +471,9 @@ static void dma_memcpy(struct bcm2708_fb + } + + /* address with no aliases */ +-#define INTALIAS_NORMAL(x) ((x)&~0xc0000000) ++#define INTALIAS_NORMAL(x) ((x) & ~0xc0000000) + /* cache coherent but non-allocating in L1 and L2 */ +-#define INTALIAS_L1L2_NONALLOCATING(x) (((x)&~0xc0000000)|0x80000000) ++#define INTALIAS_L1L2_NONALLOCATING(x) (((x) & ~0xc0000000) | 0x80000000) + + static long vc_mem_copy(struct bcm2708_fb *fb, struct fb_dmacopy *ioparam) + { +@@ -498,15 +491,15 @@ static long vc_mem_copy(struct bcm2708_f + + if (!fb->gpu.base || !fb->gpu.length) { + pr_err("[%s]: Unable to determine gpu memory (%x,%x)\n", +- __func__, fb->gpu.base, fb->gpu.length); ++ __func__, fb->gpu.base, fb->gpu.length); + return -EFAULT; + } + + if (INTALIAS_NORMAL(ioparam->src) < fb->gpu.base || + INTALIAS_NORMAL(ioparam->src) >= fb->gpu.base + fb->gpu.length) { + pr_err("[%s]: Invalid memory access %x (%x-%x)", __func__, +- INTALIAS_NORMAL(ioparam->src), fb->gpu.base, +- fb->gpu.base + fb->gpu.length); ++ INTALIAS_NORMAL(ioparam->src), fb->gpu.base, ++ fb->gpu.base + fb->gpu.length); + return -EFAULT; + } + +@@ -528,8 +521,7 @@ static long vc_mem_copy(struct bcm2708_f + dma_memcpy(fb, bus_addr, + INTALIAS_L1L2_NONALLOCATING((dma_addr_t)p), size); + if (copy_to_user(q, buf, s) != 0) { +- pr_err("[%s]: failed to copy-to-user\n", +- __func__); ++ pr_err("[%s]: failed to copy-to-user\n", __func__); + rc = -EFAULT; + goto out; + } +@@ -755,7 +747,6 @@ static void bcm2708_fb_copyarea(struct f + /* end of dma control blocks chain */ + cb->next = 0; + +- + if (pixels < dma_busy_wait_threshold) { + bcm_dma_start(fb->dma_chan_base, fb->cb_handle); + bcm_dma_wait_idle(fb->dma_chan_base); +@@ -765,9 +756,8 @@ static void bcm2708_fb_copyarea(struct f + cb->info |= BCM2708_DMA_INT_EN; + bcm_dma_start(fb->dma_chan_base, fb->cb_handle); + while (bcm_dma_is_busy(dma_chan)) { +- wait_event_interruptible( +- fb->dma_waitq, +- !bcm_dma_is_busy(dma_chan)); ++ wait_event_interruptible(fb->dma_waitq, ++ !bcm_dma_is_busy(dma_chan)); + } + fb->stats.dma_irqs++; + } +@@ -863,7 +853,7 @@ static int bcm2708_fb_register(struct bc + return ret; + + print_debug("BCM2708FB: registering framebuffer (%dx%d@%d) (%d)\n", +- fbwidth, fbheight, fbdepth, fbswap); ++ fbwidth, fbheight, fbdepth, fbswap); + + ret = register_framebuffer(&fb->fb); + print_debug("BCM2708FB: register framebuffer (%d)\n", ret); +@@ -893,7 +883,7 @@ static int bcm2708_fb_probe(struct platf + if (!fw) + return -EPROBE_DEFER; + +- fb = kzalloc(sizeof(struct bcm2708_fb), GFP_KERNEL); ++ fb = kzalloc(sizeof(*fb), GFP_KERNEL); + if (!fb) { + ret = -ENOMEM; + goto free_region; +@@ -927,7 +917,6 @@ static int bcm2708_fb_probe(struct platf + goto free_dma_chan; + } + +- + pr_info("BCM2708FB: allocated DMA channel %d\n", fb->dma_chan); + + fb->dev = dev; +@@ -936,9 +925,8 @@ static int bcm2708_fb_probe(struct platf + /* failure here isn't fatal, but we'll fail in vc_mem_copy if + * fb->gpu is not valid + */ +- rpi_firmware_property(fb->fw, +- RPI_FIRMWARE_GET_VC_MEMORY, +- &fb->gpu, sizeof(fb->gpu)); ++ rpi_firmware_property(fb->fw, RPI_FIRMWARE_GET_VC_MEMORY, &fb->gpu, ++ sizeof(fb->gpu)); + + ret = bcm2708_fb_register(fb); + if (ret == 0) { diff --git a/target/linux/brcm2708/patches-4.19/950-0335-bcm2835-dma-Add-support-for-per-channel-flags.patch b/target/linux/brcm2708/patches-4.19/950-0335-bcm2835-dma-Add-support-for-per-channel-flags.patch new file mode 100644 index 0000000000..4a36e32adb --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0335-bcm2835-dma-Add-support-for-per-channel-flags.patch @@ -0,0 +1,48 @@ +From 579a73d009e45d7078246d01e5f311a79d04d291 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 20 Jul 2018 22:03:41 +0100 +Subject: [PATCH 335/725] bcm2835-dma: Add support for per-channel flags + +Add the ability to interpret the high bits of the dreq specifier as +flags to be included in the DMA_CS register. The motivation for this +change is the ability to set the DISDEBUG flag for SD card transfers +to avoid corruption when using the VPU debugger. + +Signed-off-by: Phil Elwell +--- + drivers/dma/bcm2835-dma.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/dma/bcm2835-dma.c ++++ b/drivers/dma/bcm2835-dma.c +@@ -146,6 +146,10 @@ struct bcm2835_desc { + #define BCM2835_DMA_S_DREQ BIT(10) /* enable SREQ for source */ + #define BCM2835_DMA_S_IGNORE BIT(11) /* ignore source reads - read 0 */ + #define BCM2835_DMA_BURST_LENGTH(x) ((x & 15) << 12) ++#define BCM2835_DMA_CS_FLAGS(x) (x & (BCM2835_DMA_PRIORITY(15) | \ ++ BCM2835_DMA_PANIC_PRIORITY(15) | \ ++ BCM2835_DMA_WAIT_FOR_WRITES | \ ++ BCM2835_DMA_DIS_DEBUG)) + #define BCM2835_DMA_PER_MAP(x) ((x & 31) << 16) /* REQ source */ + #define BCM2835_DMA_WAIT(x) ((x & 31) << 21) /* add DMA-wait cycles */ + #define BCM2835_DMA_NO_WIDE_BURSTS BIT(26) /* no 2 beat write bursts */ +@@ -461,7 +465,8 @@ static void bcm2835_dma_start_desc(struc + c->desc = d = to_bcm2835_dma_desc(&vd->tx); + + writel(d->cb_list[0].paddr, c->chan_base + BCM2835_DMA_ADDR); +- writel(BCM2835_DMA_ACTIVE, c->chan_base + BCM2835_DMA_CS); ++ writel(BCM2835_DMA_ACTIVE | BCM2835_DMA_CS_FLAGS(c->dreq), ++ c->chan_base + BCM2835_DMA_CS); + } + + static irqreturn_t bcm2835_dma_callback(int irq, void *data) +@@ -488,7 +493,8 @@ static irqreturn_t bcm2835_dma_callback( + * if this IRQ handler is threaded.) If the channel is finished, it + * will remain idle despite the ACTIVE flag being set. + */ +- writel(BCM2835_DMA_INT | BCM2835_DMA_ACTIVE, ++ writel(BCM2835_DMA_INT | BCM2835_DMA_ACTIVE | ++ BCM2835_DMA_CS_FLAGS(c->dreq), + c->chan_base + BCM2835_DMA_CS); + + d = c->desc; diff --git a/target/linux/brcm2708/patches-4.19/950-0335-video-bcm2708_fb-Add-compat_ioctl-support.patch b/target/linux/brcm2708/patches-4.19/950-0335-video-bcm2708_fb-Add-compat_ioctl-support.patch deleted file mode 100644 index af2c456418..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0335-video-bcm2708_fb-Add-compat_ioctl-support.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 5bdb5d6229725a096d7ded73a47034d8bb7f70be Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 25 Jan 2019 17:12:54 +0000 -Subject: [PATCH 335/703] video: bcm2708_fb: Add compat_ioctl support. - -When using a 64 bit kernel with 32 bit userspace we need -compat ioctl handling for FBIODMACOPY as one of the -parameters is a pointer. - -Signed-off-by: Dave Stevenson ---- - drivers/video/fbdev/bcm2708_fb.c | 87 ++++++++++++++++++++++++-------- - 1 file changed, 66 insertions(+), 21 deletions(-) - ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -482,9 +482,8 @@ static void dma_memcpy(struct bcm2708_fb - /* cache coherent but non-allocating in L1 and L2 */ - #define INTALIAS_L1L2_NONALLOCATING(x) (((x)&~0xc0000000)|0x80000000) - --static long vc_mem_copy(struct bcm2708_fb *fb, unsigned long arg) -+static long vc_mem_copy(struct bcm2708_fb *fb, struct fb_dmacopy *ioparam) - { -- struct fb_dmacopy ioparam; - size_t size = PAGE_SIZE; - u32 *buf = NULL; - dma_addr_t bus_addr; -@@ -497,26 +496,16 @@ static long vc_mem_copy(struct bcm2708_f - goto out; - } - -- /* Get the parameter data. -- */ -- if (copy_from_user -- (&ioparam, (void *)arg, sizeof(ioparam)) != 0) { -- pr_err("[%s]: failed to copy-from-user\n", -- __func__); -- rc = -EFAULT; -- goto out; -- } -- -- if (fb->gpu.base == 0 || fb->gpu.length == 0) { -+ if (!fb->gpu.base || !fb->gpu.length) { - pr_err("[%s]: Unable to determine gpu memory (%x,%x)\n", - __func__, fb->gpu.base, fb->gpu.length); - return -EFAULT; - } - -- if (INTALIAS_NORMAL(ioparam.src) < fb->gpu.base || -- INTALIAS_NORMAL(ioparam.src) >= fb->gpu.base + fb->gpu.length) { -+ if (INTALIAS_NORMAL(ioparam->src) < fb->gpu.base || -+ INTALIAS_NORMAL(ioparam->src) >= fb->gpu.base + fb->gpu.length) { - pr_err("[%s]: Invalid memory access %x (%x-%x)", __func__, -- INTALIAS_NORMAL(ioparam.src), fb->gpu.base, -+ INTALIAS_NORMAL(ioparam->src), fb->gpu.base, - fb->gpu.base + fb->gpu.length); - return -EFAULT; - } -@@ -530,11 +519,11 @@ static long vc_mem_copy(struct bcm2708_f - goto out; - } - -- for (offset = 0; offset < ioparam.length; offset += size) { -- size_t remaining = ioparam.length - offset; -+ for (offset = 0; offset < ioparam->length; offset += size) { -+ size_t remaining = ioparam->length - offset; - size_t s = min(size, remaining); -- unsigned char *p = (unsigned char *)ioparam.src + offset; -- unsigned char *q = (unsigned char *)ioparam.dst + offset; -+ u8 *p = (u8 *)((uintptr_t)ioparam->src + offset); -+ u8 *q = (u8 *)ioparam->dst + offset; - - dma_memcpy(fb, bus_addr, - INTALIAS_L1L2_NONALLOCATING((dma_addr_t)p), size); -@@ -566,8 +555,19 @@ static int bcm2708_ioctl(struct fb_info - &dummy, sizeof(dummy)); - break; - case FBIODMACOPY: -- ret = vc_mem_copy(fb, arg); -+ { -+ struct fb_dmacopy ioparam; -+ /* Get the parameter data. -+ */ -+ if (copy_from_user -+ (&ioparam, (void *)arg, sizeof(ioparam))) { -+ pr_err("[%s]: failed to copy-from-user\n", __func__); -+ ret = -EFAULT; -+ break; -+ } -+ ret = vc_mem_copy(fb, &ioparam); - break; -+ } - default: - dev_dbg(info->device, "Unknown ioctl 0x%x\n", cmd); - return -ENOTTY; -@@ -578,6 +578,48 @@ static int bcm2708_ioctl(struct fb_info - - return ret; - } -+ -+#ifdef CONFIG_COMPAT -+struct fb_dmacopy32 { -+ compat_uptr_t dst; -+ __u32 src; -+ __u32 length; -+}; -+ -+#define FBIODMACOPY32 _IOW('z', 0x22, struct fb_dmacopy32) -+ -+static int bcm2708_compat_ioctl(struct fb_info *info, unsigned int cmd, -+ unsigned long arg) -+{ -+ struct bcm2708_fb *fb = to_bcm2708(info); -+ int ret; -+ -+ switch (cmd) { -+ case FBIODMACOPY32: -+ { -+ struct fb_dmacopy32 param32; -+ struct fb_dmacopy param; -+ /* Get the parameter data. -+ */ -+ if (copy_from_user(¶m32, (void *)arg, sizeof(param32))) { -+ pr_err("[%s]: failed to copy-from-user\n", __func__); -+ ret = -EFAULT; -+ break; -+ } -+ param.dst = compat_ptr(param32.dst); -+ param.src = param32.src; -+ param.length = param32.length; -+ ret = vc_mem_copy(fb, ¶m); -+ break; -+ } -+ default: -+ ret = bcm2708_ioctl(info, cmd, arg); -+ break; -+ } -+ return ret; -+} -+#endif -+ - static void bcm2708_fb_fillrect(struct fb_info *info, - const struct fb_fillrect *rect) - { -@@ -768,6 +810,9 @@ static struct fb_ops bcm2708_fb_ops = { - .fb_imageblit = bcm2708_fb_imageblit, - .fb_pan_display = bcm2708_fb_pan_display, - .fb_ioctl = bcm2708_ioctl, -+#ifdef CONFIG_COMPAT -+ .fb_compat_ioctl = bcm2708_compat_ioctl, -+#endif - }; - - static int bcm2708_fb_register(struct bcm2708_fb *fb) diff --git a/target/linux/brcm2708/patches-4.19/950-0336-bcm283x-Set-the-DISDEBUG-flag-for-SD-transfers.patch b/target/linux/brcm2708/patches-4.19/950-0336-bcm283x-Set-the-DISDEBUG-flag-for-SD-transfers.patch new file mode 100644 index 0000000000..ec920aedfa --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0336-bcm283x-Set-the-DISDEBUG-flag-for-SD-transfers.patch @@ -0,0 +1,21 @@ +From b8c21591d254d10e730b40eb0b1bc87dfbe7cd4b Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 20 Jul 2018 22:08:05 +0100 +Subject: [PATCH 336/725] bcm283x: Set the DISDEBUG flag for SD transfers + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/bcm283x.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/bcm283x.dtsi ++++ b/arch/arm/boot/dts/bcm283x.dtsi +@@ -400,7 +400,7 @@ + reg = <0x7e202000 0x100>; + interrupts = <2 24>; + clocks = <&clocks BCM2835_CLOCK_VPU>; +- dmas = <&dma 13>; ++ dmas = <&dma (13|(1<<29))>; + dma-names = "rx-tx"; + status = "disabled"; + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0336-video-bcm2708_fb-Fix-warnings-on-64-bit-builds.patch b/target/linux/brcm2708/patches-4.19/950-0336-video-bcm2708_fb-Fix-warnings-on-64-bit-builds.patch deleted file mode 100644 index 4441c8545d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0336-video-bcm2708_fb-Fix-warnings-on-64-bit-builds.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 3695125662f57ce208b6769418bcda80bedbd5b6 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 25 Jan 2019 17:11:39 +0000 -Subject: [PATCH 336/703] video: bcm2708_fb: Fix warnings on 64 bit builds - -Fix up logging lines where the wrong format specifiers were -being used. - -Signed-off-by: Dave Stevenson ---- - drivers/video/fbdev/bcm2708_fb.c | 10 ++++------ - 1 file changed, 4 insertions(+), 6 deletions(-) - ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -513,8 +513,8 @@ static long vc_mem_copy(struct bcm2708_f - buf = dma_alloc_coherent(fb->fb.device, PAGE_ALIGN(size), &bus_addr, - GFP_ATOMIC); - if (!buf) { -- pr_err("[%s]: failed to dma_alloc_coherent(%d)\n", -- __func__, size); -+ pr_err("[%s]: failed to dma_alloc_coherent(%zd)\n", __func__, -+ size); - rc = -ENOMEM; - goto out; - } -@@ -910,8 +910,7 @@ static int bcm2708_fb_probe(struct platf - goto free_fb; - } - -- pr_info("BCM2708FB: allocated DMA memory %08x\n", -- fb->cb_handle); -+ pr_info("BCM2708FB: allocated DMA memory %pad\n", &fb->cb_handle); - - ret = bcm_dma_chan_alloc(BCM_DMA_FEATURE_BULK, - &fb->dma_chan_base, &fb->dma_irq); -@@ -929,8 +928,7 @@ static int bcm2708_fb_probe(struct platf - } - - -- pr_info("BCM2708FB: allocated DMA channel %d @ %p\n", -- fb->dma_chan, fb->dma_chan_base); -+ pr_info("BCM2708FB: allocated DMA channel %d\n", fb->dma_chan); - - fb->dev = dev; - fb->fb.device = &dev->dev; diff --git a/target/linux/brcm2708/patches-4.19/950-0337-ASoC-pcm512x-Implement-the-digital_mute-interface.patch b/target/linux/brcm2708/patches-4.19/950-0337-ASoC-pcm512x-Implement-the-digital_mute-interface.patch new file mode 100644 index 0000000000..bd268a6c56 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0337-ASoC-pcm512x-Implement-the-digital_mute-interface.patch @@ -0,0 +1,196 @@ +From 911ef52ced060fd14d56d5a2cb816b0732da9b46 Mon Sep 17 00:00:00 2001 +From: Dimitris Papavasiliou +Date: Sat, 24 Nov 2018 22:05:42 +0200 +Subject: [PATCH 337/725] ASoC: pcm512x: Implement the digital_mute interface + +[ Upstream commit 3500f1c589e92e0b6b1f8d31b4084fbde08d49cb ] + +Clicks and pops of various volumes can be produced while the device is +opened, closed, put into and taken out of standby, or reconfigured. +Fix this, by implementing the digital_mute interface, so that the +output is muted during such operations. + +Signed-off-by: Dimitris Papavasiliou +Signed-off-by: Mark Brown +--- + sound/soc/codecs/pcm512x.c | 121 ++++++++++++++++++++++++++++++++++++- + sound/soc/codecs/pcm512x.h | 2 + + 2 files changed, 121 insertions(+), 2 deletions(-) + +--- a/sound/soc/codecs/pcm512x.c ++++ b/sound/soc/codecs/pcm512x.c +@@ -53,6 +53,8 @@ struct pcm512x_priv { + unsigned long overclock_pll; + unsigned long overclock_dac; + unsigned long overclock_dsp; ++ int mute; ++ struct mutex mutex; + int lrclk_div; + }; + +@@ -385,6 +387,61 @@ static const struct soc_enum pcm512x_ved + SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDS_SHIFT, 4, + pcm512x_ramp_step_text); + ++static int pcm512x_update_mute(struct pcm512x_priv *pcm512x) ++{ ++ return regmap_update_bits( ++ pcm512x->regmap, PCM512x_MUTE, PCM512x_RQML | PCM512x_RQMR, ++ (!!(pcm512x->mute & 0x5) << PCM512x_RQML_SHIFT) ++ | (!!(pcm512x->mute & 0x3) << PCM512x_RQMR_SHIFT)); ++} ++ ++static int pcm512x_digital_playback_switch_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); ++ struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component); ++ ++ mutex_lock(&pcm512x->mutex); ++ ucontrol->value.integer.value[0] = !(pcm512x->mute & 0x4); ++ ucontrol->value.integer.value[1] = !(pcm512x->mute & 0x2); ++ mutex_unlock(&pcm512x->mutex); ++ ++ return 0; ++} ++ ++static int pcm512x_digital_playback_switch_put(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); ++ struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component); ++ int ret, changed = 0; ++ ++ mutex_lock(&pcm512x->mutex); ++ ++ if ((pcm512x->mute & 0x4) == (ucontrol->value.integer.value[0] << 2)) { ++ pcm512x->mute ^= 0x4; ++ changed = 1; ++ } ++ if ((pcm512x->mute & 0x2) == (ucontrol->value.integer.value[1] << 1)) { ++ pcm512x->mute ^= 0x2; ++ changed = 1; ++ } ++ ++ if (changed) { ++ ret = pcm512x_update_mute(pcm512x); ++ if (ret != 0) { ++ dev_err(component->dev, ++ "Failed to update digital mute: %d\n", ret); ++ mutex_unlock(&pcm512x->mutex); ++ return ret; ++ } ++ } ++ ++ mutex_unlock(&pcm512x->mutex); ++ ++ return changed; ++} ++ + static const struct snd_kcontrol_new pcm512x_controls[] = { + SOC_DOUBLE_R_TLV("Digital Playback Volume", PCM512x_DIGITAL_VOLUME_2, + PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv), +@@ -392,8 +449,15 @@ SOC_DOUBLE_TLV("Analogue Playback Volume + PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv), + SOC_DOUBLE_TLV("Analogue Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST, + PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv), +-SOC_DOUBLE("Digital Playback Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT, +- PCM512x_RQMR_SHIFT, 1, 1), ++{ ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "Digital Playback Switch", ++ .index = 0, ++ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, ++ .info = snd_ctl_boolean_stereo_info, ++ .get = pcm512x_digital_playback_switch_get, ++ .put = pcm512x_digital_playback_switch_put ++}, + + SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1), + SOC_ENUM("DSP Program", pcm512x_dsp_program), +@@ -1323,6 +1387,56 @@ static int pcm512x_set_fmt(struct snd_so + return 0; + } + ++static int pcm512x_digital_mute(struct snd_soc_dai *dai, int mute) ++{ ++ struct snd_soc_component *component = dai->component; ++ struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component); ++ int ret; ++ unsigned int mute_det; ++ ++ mutex_lock(&pcm512x->mutex); ++ ++ if (mute) { ++ pcm512x->mute |= 0x1; ++ ret = regmap_update_bits(pcm512x->regmap, PCM512x_MUTE, ++ PCM512x_RQML | PCM512x_RQMR, ++ PCM512x_RQML | PCM512x_RQMR); ++ if (ret != 0) { ++ dev_err(component->dev, ++ "Failed to set digital mute: %d\n", ret); ++ mutex_unlock(&pcm512x->mutex); ++ return ret; ++ } ++ ++ regmap_read_poll_timeout(pcm512x->regmap, ++ PCM512x_ANALOG_MUTE_DET, ++ mute_det, (mute_det & 0x3) == 0, ++ 200, 10000); ++ ++ mutex_unlock(&pcm512x->mutex); ++ } else { ++ pcm512x->mute &= ~0x1; ++ ret = pcm512x_update_mute(pcm512x); ++ if (ret != 0) { ++ dev_err(component->dev, ++ "Failed to update digital mute: %d\n", ret); ++ mutex_unlock(&pcm512x->mutex); ++ return ret; ++ } ++ ++ regmap_read_poll_timeout(pcm512x->regmap, ++ PCM512x_ANALOG_MUTE_DET, ++ mute_det, ++ (mute_det & 0x3) ++ == ((~pcm512x->mute >> 1) & 0x3), ++ 200, 10000); ++ } ++ ++ mutex_unlock(&pcm512x->mutex); ++ ++ return 0; ++} ++ + static int pcm512x_set_tdm_slot(struct snd_soc_dai *dai, + unsigned int tx_mask, unsigned int rx_mask, + int slots, int width) +@@ -1348,6 +1462,7 @@ static const struct snd_soc_dai_ops pcm5 + .startup = pcm512x_dai_startup, + .hw_params = pcm512x_hw_params, + .set_fmt = pcm512x_set_fmt, ++ .digital_mute = pcm512x_digital_mute, + .set_tdm_slot = pcm512x_set_tdm_slot, + }; + +@@ -1414,6 +1529,8 @@ int pcm512x_probe(struct device *dev, st + if (!pcm512x) + return -ENOMEM; + ++ mutex_init(&pcm512x->mutex); ++ + dev_set_drvdata(dev, pcm512x); + pcm512x->regmap = regmap; + +--- a/sound/soc/codecs/pcm512x.h ++++ b/sound/soc/codecs/pcm512x.h +@@ -112,7 +112,9 @@ + #define PCM512x_RQST_SHIFT 4 + + /* Page 0, Register 3 - mute */ ++#define PCM512x_RQMR (1 << 0) + #define PCM512x_RQMR_SHIFT 0 ++#define PCM512x_RQML (1 << 4) + #define PCM512x_RQML_SHIFT 4 + + /* Page 0, Register 4 - PLL */ diff --git a/target/linux/brcm2708/patches-4.19/950-0337-video-bcm2708_fb-Clean-up-coding-style-issues.patch b/target/linux/brcm2708/patches-4.19/950-0337-video-bcm2708_fb-Clean-up-coding-style-issues.patch deleted file mode 100644 index fcd34a1b27..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0337-video-bcm2708_fb-Clean-up-coding-style-issues.patch +++ /dev/null @@ -1,275 +0,0 @@ -From 9236c0f31f2052bbcd6386367ace3ebfad57da3d Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 25 Jan 2019 17:32:54 +0000 -Subject: [PATCH 337/703] video: bcm2708_fb: Clean up coding style issues - -Now checkpatch clean except for 2 long lines, missing -SPDX header, and no DT documentation. - -Signed-off-by: Dave Stevenson ---- - drivers/video/fbdev/bcm2708_fb.c | 96 ++++++++++++++------------------ - 1 file changed, 42 insertions(+), 54 deletions(-) - ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -41,7 +41,7 @@ - #define MODULE_NAME "bcm2708_fb" - - #ifdef BCM2708_FB_DEBUG --#define print_debug(fmt, ...) pr_debug("%s:%s:%d: "fmt, \ -+#define print_debug(fmt, ...) pr_debug("%s:%s:%d: " fmt, \ - MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__) - #else - #define print_debug(fmt, ...) -@@ -57,7 +57,7 @@ static int fbheight = 480; /* module par - static int fbdepth = 32; /* module parameter */ - static int fbswap; /* module parameter */ - --static u32 dma_busy_wait_threshold = 1<<15; -+static u32 dma_busy_wait_threshold = 1 << 15; - module_param(dma_busy_wait_threshold, int, 0644); - MODULE_PARM_DESC(dma_busy_wait_threshold, "Busy-wait for DMA completion below this area"); - -@@ -132,8 +132,8 @@ static int bcm2708_fb_debugfs_init(struc - fb->stats.regset.nregs = ARRAY_SIZE(stats_registers); - fb->stats.regset.base = &fb->stats; - -- if (!debugfs_create_regset32( -- "stats", 0444, fb->debugfs_dir, &fb->stats.regset)) { -+ if (!debugfs_create_regset32("stats", 0444, fb->debugfs_dir, -+ &fb->stats.regset)) { - pr_warn("%s: could not create statistics registers\n", - __func__); - goto fail; -@@ -223,25 +223,22 @@ static int bcm2708_fb_check_var(struct f - { - /* info input, var output */ - print_debug("%s(%p) %dx%d (%dx%d), %d, %d\n", -- __func__, -- info, -- info->var.xres, info->var.yres, info->var.xres_virtual, -- info->var.yres_virtual, (int)info->screen_size, -- info->var.bits_per_pixel); -- print_debug("%s(%p) %dx%d (%dx%d), %d\n", __func__, var, -- var->xres, var->yres, var->xres_virtual, var->yres_virtual, -- var->bits_per_pixel); -+ __func__, info, info->var.xres, info->var.yres, -+ info->var.xres_virtual, info->var.yres_virtual, -+ (int)info->screen_size, info->var.bits_per_pixel); -+ print_debug("%s(%p) %dx%d (%dx%d), %d\n", __func__, var, var->xres, -+ var->yres, var->xres_virtual, var->yres_virtual, -+ var->bits_per_pixel); - - if (!var->bits_per_pixel) - var->bits_per_pixel = 16; - - if (bcm2708_fb_set_bitfields(var) != 0) { - pr_err("%s: invalid bits_per_pixel %d\n", __func__, -- var->bits_per_pixel); -+ var->bits_per_pixel); - return -EINVAL; - } - -- - if (var->xres_virtual < var->xres) - var->xres_virtual = var->xres; - /* use highest possible virtual resolution */ -@@ -249,7 +246,7 @@ static int bcm2708_fb_check_var(struct f - var->yres_virtual = 480; - - pr_err("%s: virtual resolution set to maximum of %dx%d\n", -- __func__, var->xres_virtual, var->yres_virtual); -+ __func__, var->xres_virtual, var->yres_virtual); - } - if (var->yres_virtual < var->yres) - var->yres_virtual = var->yres; -@@ -294,9 +291,9 @@ static int bcm2708_fb_set_par(struct fb_ - int ret; - - print_debug("%s(%p) %dx%d (%dx%d), %d, %d\n", __func__, info, -- info->var.xres, info->var.yres, info->var.xres_virtual, -- info->var.yres_virtual, (int)info->screen_size, -- info->var.bits_per_pixel); -+ info->var.xres, info->var.yres, info->var.xres_virtual, -+ info->var.yres_virtual, (int)info->screen_size, -+ info->var.bits_per_pixel); - - ret = rpi_firmware_property_list(fb->fw, &fbinfo, sizeof(fbinfo)); - if (ret) { -@@ -328,12 +325,10 @@ static int bcm2708_fb_set_par(struct fb_ - return -ENOMEM; - } - -- print_debug( -- "%s: start = %p,%p width=%d, height=%d, bpp=%d, pitch=%d size=%d\n", -- __func__, -- (void *)fb->fb.screen_base, (void *)fb->fb_bus_address, -- fbinfo.xres, fbinfo.yres, fbinfo.bpp, -- fbinfo.pitch, (int)fb->fb.screen_size); -+ print_debug("%s: start = %p,%p width=%d, height=%d, bpp=%d, pitch=%d size=%d\n", -+ __func__, (void *)fb->fb.screen_base, -+ (void *)fb->fb_bus_address, fbinfo.xres, fbinfo.yres, -+ fbinfo.bpp, fbinfo.pitch, (int)fb->fb.screen_size); - - return 0; - } -@@ -345,7 +340,6 @@ static inline u32 convert_bitfield(int v - return (val >> (16 - bf->length) & mask) << bf->offset; - } - -- - static int bcm2708_fb_setcolreg(unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - unsigned int transp, struct fb_info *info) -@@ -379,11 +373,11 @@ static int bcm2708_fb_setcolreg(unsigned - packet->offset = 0; - packet->length = regno + 1; - memcpy(packet->cmap, fb->gpu_cmap, -- sizeof(packet->cmap)); -+ sizeof(packet->cmap)); - ret = rpi_firmware_property(fb->fw, -- RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE, -- packet, -- (2 + packet->length) * sizeof(u32)); -+ RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE, -+ packet, -+ (2 + packet->length) * sizeof(u32)); - if (ret || packet->offset) - dev_err(info->device, - "Failed to set palette (%d,%u)\n", -@@ -392,9 +386,9 @@ static int bcm2708_fb_setcolreg(unsigned - } - } else if (regno < 16) { - fb->cmap[regno] = convert_bitfield(transp, &fb->fb.var.transp) | -- convert_bitfield(blue, &fb->fb.var.blue) | -- convert_bitfield(green, &fb->fb.var.green) | -- convert_bitfield(red, &fb->fb.var.red); -+ convert_bitfield(blue, &fb->fb.var.blue) | -+ convert_bitfield(green, &fb->fb.var.green) | -+ convert_bitfield(red, &fb->fb.var.red); - } - return regno > 255; - } -@@ -437,8 +431,8 @@ static int bcm2708_fb_pan_display(struct - info->var.yoffset = var->yoffset; - result = bcm2708_fb_set_par(info); - if (result != 0) -- pr_err("%s(%d,%d) returns=%d\n", __func__, -- var->xoffset, var->yoffset, result); -+ pr_err("%s(%d,%d) returns=%d\n", __func__, var->xoffset, -+ var->yoffset, result); - return result; - } - -@@ -468,9 +462,8 @@ static void dma_memcpy(struct bcm2708_fb - cb->info |= BCM2708_DMA_INT_EN; - bcm_dma_start(fb->dma_chan_base, fb->cb_handle); - while (bcm_dma_is_busy(dma_chan)) { -- wait_event_interruptible( -- fb->dma_waitq, -- !bcm_dma_is_busy(dma_chan)); -+ wait_event_interruptible(fb->dma_waitq, -+ !bcm_dma_is_busy(dma_chan)); - } - fb->stats.dma_irqs++; - } -@@ -478,9 +471,9 @@ static void dma_memcpy(struct bcm2708_fb - } - - /* address with no aliases */ --#define INTALIAS_NORMAL(x) ((x)&~0xc0000000) -+#define INTALIAS_NORMAL(x) ((x) & ~0xc0000000) - /* cache coherent but non-allocating in L1 and L2 */ --#define INTALIAS_L1L2_NONALLOCATING(x) (((x)&~0xc0000000)|0x80000000) -+#define INTALIAS_L1L2_NONALLOCATING(x) (((x) & ~0xc0000000) | 0x80000000) - - static long vc_mem_copy(struct bcm2708_fb *fb, struct fb_dmacopy *ioparam) - { -@@ -498,15 +491,15 @@ static long vc_mem_copy(struct bcm2708_f - - if (!fb->gpu.base || !fb->gpu.length) { - pr_err("[%s]: Unable to determine gpu memory (%x,%x)\n", -- __func__, fb->gpu.base, fb->gpu.length); -+ __func__, fb->gpu.base, fb->gpu.length); - return -EFAULT; - } - - if (INTALIAS_NORMAL(ioparam->src) < fb->gpu.base || - INTALIAS_NORMAL(ioparam->src) >= fb->gpu.base + fb->gpu.length) { - pr_err("[%s]: Invalid memory access %x (%x-%x)", __func__, -- INTALIAS_NORMAL(ioparam->src), fb->gpu.base, -- fb->gpu.base + fb->gpu.length); -+ INTALIAS_NORMAL(ioparam->src), fb->gpu.base, -+ fb->gpu.base + fb->gpu.length); - return -EFAULT; - } - -@@ -528,8 +521,7 @@ static long vc_mem_copy(struct bcm2708_f - dma_memcpy(fb, bus_addr, - INTALIAS_L1L2_NONALLOCATING((dma_addr_t)p), size); - if (copy_to_user(q, buf, s) != 0) { -- pr_err("[%s]: failed to copy-to-user\n", -- __func__); -+ pr_err("[%s]: failed to copy-to-user\n", __func__); - rc = -EFAULT; - goto out; - } -@@ -755,7 +747,6 @@ static void bcm2708_fb_copyarea(struct f - /* end of dma control blocks chain */ - cb->next = 0; - -- - if (pixels < dma_busy_wait_threshold) { - bcm_dma_start(fb->dma_chan_base, fb->cb_handle); - bcm_dma_wait_idle(fb->dma_chan_base); -@@ -765,9 +756,8 @@ static void bcm2708_fb_copyarea(struct f - cb->info |= BCM2708_DMA_INT_EN; - bcm_dma_start(fb->dma_chan_base, fb->cb_handle); - while (bcm_dma_is_busy(dma_chan)) { -- wait_event_interruptible( -- fb->dma_waitq, -- !bcm_dma_is_busy(dma_chan)); -+ wait_event_interruptible(fb->dma_waitq, -+ !bcm_dma_is_busy(dma_chan)); - } - fb->stats.dma_irqs++; - } -@@ -863,7 +853,7 @@ static int bcm2708_fb_register(struct bc - return ret; - - print_debug("BCM2708FB: registering framebuffer (%dx%d@%d) (%d)\n", -- fbwidth, fbheight, fbdepth, fbswap); -+ fbwidth, fbheight, fbdepth, fbswap); - - ret = register_framebuffer(&fb->fb); - print_debug("BCM2708FB: register framebuffer (%d)\n", ret); -@@ -893,7 +883,7 @@ static int bcm2708_fb_probe(struct platf - if (!fw) - return -EPROBE_DEFER; - -- fb = kzalloc(sizeof(struct bcm2708_fb), GFP_KERNEL); -+ fb = kzalloc(sizeof(*fb), GFP_KERNEL); - if (!fb) { - ret = -ENOMEM; - goto free_region; -@@ -927,7 +917,6 @@ static int bcm2708_fb_probe(struct platf - goto free_dma_chan; - } - -- - pr_info("BCM2708FB: allocated DMA channel %d\n", fb->dma_chan); - - fb->dev = dev; -@@ -936,9 +925,8 @@ static int bcm2708_fb_probe(struct platf - /* failure here isn't fatal, but we'll fail in vc_mem_copy if - * fb->gpu is not valid - */ -- rpi_firmware_property(fb->fw, -- RPI_FIRMWARE_GET_VC_MEMORY, -- &fb->gpu, sizeof(fb->gpu)); -+ rpi_firmware_property(fb->fw, RPI_FIRMWARE_GET_VC_MEMORY, &fb->gpu, -+ sizeof(fb->gpu)); - - ret = bcm2708_fb_register(fb); - if (ret == 0) { diff --git a/target/linux/brcm2708/patches-4.19/950-0338-ASoC-pcm512x-Fix-a-double-unlock-in-pcm512x_digital_.patch b/target/linux/brcm2708/patches-4.19/950-0338-ASoC-pcm512x-Fix-a-double-unlock-in-pcm512x_digital_.patch new file mode 100644 index 0000000000..57b34da197 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0338-ASoC-pcm512x-Fix-a-double-unlock-in-pcm512x_digital_.patch @@ -0,0 +1,62 @@ +From b55252c4bca64c4c9df97b302cd52ffec3ee01b5 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Fri, 21 Dec 2018 12:11:20 +0300 +Subject: [PATCH 338/725] ASoC: pcm512x: Fix a double unlock in + pcm512x_digital_mute() + +[ Upstream commit 28b698b7342c7d5300cfe217cd77ff7d2a55e03d ] + +We accidentally call mutex_unlock(&pcm512x->mutex); twice in a row. + +I re-wrote the error handling to use "goto unlock;" instead of returning +directly. Hopefully, it makes the code a little simpler. + +Fixes: 3500f1c589e9 ("ASoC: pcm512x: Implement the digital_mute interface") +Signed-off-by: Dan Carpenter +Reviwed-by: Dimitris Papavasiliou +Signed-off-by: Mark Brown +--- + sound/soc/codecs/pcm512x.c | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) + +--- a/sound/soc/codecs/pcm512x.c ++++ b/sound/soc/codecs/pcm512x.c +@@ -1404,24 +1404,20 @@ static int pcm512x_digital_mute(struct s + if (ret != 0) { + dev_err(component->dev, + "Failed to set digital mute: %d\n", ret); +- mutex_unlock(&pcm512x->mutex); +- return ret; ++ goto unlock; + } + + regmap_read_poll_timeout(pcm512x->regmap, + PCM512x_ANALOG_MUTE_DET, + mute_det, (mute_det & 0x3) == 0, + 200, 10000); +- +- mutex_unlock(&pcm512x->mutex); + } else { + pcm512x->mute &= ~0x1; + ret = pcm512x_update_mute(pcm512x); + if (ret != 0) { + dev_err(component->dev, + "Failed to update digital mute: %d\n", ret); +- mutex_unlock(&pcm512x->mutex); +- return ret; ++ goto unlock; + } + + regmap_read_poll_timeout(pcm512x->regmap, +@@ -1432,9 +1428,10 @@ static int pcm512x_digital_mute(struct s + 200, 10000); + } + ++unlock: + mutex_unlock(&pcm512x->mutex); + +- return 0; ++ return ret; + } + + static int pcm512x_set_tdm_slot(struct snd_soc_dai *dai, diff --git a/target/linux/brcm2708/patches-4.19/950-0338-bcm2835-dma-Add-support-for-per-channel-flags.patch b/target/linux/brcm2708/patches-4.19/950-0338-bcm2835-dma-Add-support-for-per-channel-flags.patch deleted file mode 100644 index 5a1cd23d52..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0338-bcm2835-dma-Add-support-for-per-channel-flags.patch +++ /dev/null @@ -1,48 +0,0 @@ -From f1eb781eb15506a49307cd80ad5b70533622ee68 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 20 Jul 2018 22:03:41 +0100 -Subject: [PATCH 338/703] bcm2835-dma: Add support for per-channel flags - -Add the ability to interpret the high bits of the dreq specifier as -flags to be included in the DMA_CS register. The motivation for this -change is the ability to set the DISDEBUG flag for SD card transfers -to avoid corruption when using the VPU debugger. - -Signed-off-by: Phil Elwell ---- - drivers/dma/bcm2835-dma.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - ---- a/drivers/dma/bcm2835-dma.c -+++ b/drivers/dma/bcm2835-dma.c -@@ -146,6 +146,10 @@ struct bcm2835_desc { - #define BCM2835_DMA_S_DREQ BIT(10) /* enable SREQ for source */ - #define BCM2835_DMA_S_IGNORE BIT(11) /* ignore source reads - read 0 */ - #define BCM2835_DMA_BURST_LENGTH(x) ((x & 15) << 12) -+#define BCM2835_DMA_CS_FLAGS(x) (x & (BCM2835_DMA_PRIORITY(15) | \ -+ BCM2835_DMA_PANIC_PRIORITY(15) | \ -+ BCM2835_DMA_WAIT_FOR_WRITES | \ -+ BCM2835_DMA_DIS_DEBUG)) - #define BCM2835_DMA_PER_MAP(x) ((x & 31) << 16) /* REQ source */ - #define BCM2835_DMA_WAIT(x) ((x & 31) << 21) /* add DMA-wait cycles */ - #define BCM2835_DMA_NO_WIDE_BURSTS BIT(26) /* no 2 beat write bursts */ -@@ -461,7 +465,8 @@ static void bcm2835_dma_start_desc(struc - c->desc = d = to_bcm2835_dma_desc(&vd->tx); - - writel(d->cb_list[0].paddr, c->chan_base + BCM2835_DMA_ADDR); -- writel(BCM2835_DMA_ACTIVE, c->chan_base + BCM2835_DMA_CS); -+ writel(BCM2835_DMA_ACTIVE | BCM2835_DMA_CS_FLAGS(c->dreq), -+ c->chan_base + BCM2835_DMA_CS); - } - - static irqreturn_t bcm2835_dma_callback(int irq, void *data) -@@ -488,7 +493,8 @@ static irqreturn_t bcm2835_dma_callback( - * if this IRQ handler is threaded.) If the channel is finished, it - * will remain idle despite the ACTIVE flag being set. - */ -- writel(BCM2835_DMA_INT | BCM2835_DMA_ACTIVE, -+ writel(BCM2835_DMA_INT | BCM2835_DMA_ACTIVE | -+ BCM2835_DMA_CS_FLAGS(c->dreq), - c->chan_base + BCM2835_DMA_CS); - - d = c->desc; diff --git a/target/linux/brcm2708/patches-4.19/950-0339-bcm283x-Set-the-DISDEBUG-flag-for-SD-transfers.patch b/target/linux/brcm2708/patches-4.19/950-0339-bcm283x-Set-the-DISDEBUG-flag-for-SD-transfers.patch deleted file mode 100644 index abaa23923d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0339-bcm283x-Set-the-DISDEBUG-flag-for-SD-transfers.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 393156f30a06f1cd3e739e31b92e0f9a62857ea9 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 20 Jul 2018 22:08:05 +0100 -Subject: [PATCH 339/703] bcm283x: Set the DISDEBUG flag for SD transfers - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm283x.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/bcm283x.dtsi -+++ b/arch/arm/boot/dts/bcm283x.dtsi -@@ -400,7 +400,7 @@ - reg = <0x7e202000 0x100>; - interrupts = <2 24>; - clocks = <&clocks BCM2835_CLOCK_VPU>; -- dmas = <&dma 13>; -+ dmas = <&dma (13|(1<<29))>; - dma-names = "rx-tx"; - status = "disabled"; - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0339-usb-dwc_otg-Clean-up-build-warnings-on-64bit-kernels.patch b/target/linux/brcm2708/patches-4.19/950-0339-usb-dwc_otg-Clean-up-build-warnings-on-64bit-kernels.patch new file mode 100644 index 0000000000..b86e1239d4 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0339-usb-dwc_otg-Clean-up-build-warnings-on-64bit-kernels.patch @@ -0,0 +1,110 @@ +From 12c338acee0c756cbb4c8453882341cc0e8581e7 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 25 Jan 2019 16:03:31 +0000 +Subject: [PATCH 339/725] usb: dwc_otg: Clean up build warnings on 64bit + kernels + +No functional changes. Almost all are changes to logging lines. + +Signed-off-by: Dave Stevenson +--- + drivers/usb/host/dwc_otg/dwc_otg_driver.c | 3 +-- + drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 2 +- + drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 19 ++++++++++++++----- + drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 10 ++++------ + 4 files changed, 20 insertions(+), 14 deletions(-) + +--- a/drivers/usb/host/dwc_otg/dwc_otg_driver.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c +@@ -837,8 +837,7 @@ static int dwc_otg_driver_probe( + retval = -ENOMEM; + goto fail; + } +- dev_info(&_dev->dev, "base=0x%08x\n", +- (unsigned)dwc_otg_device->os_dep.base); ++ dev_info(&_dev->dev, "base=%p\n", dwc_otg_device->os_dep.base); + #endif + + /* +--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c +@@ -301,7 +301,7 @@ static int notrace fiq_iso_out_advance(s + last = 1; + + /* New DMA address - address of bounce buffer referred to in index */ +- hcdma.d32 = (uint32_t) &blob->channel[n].index[i].buf[0]; ++ hcdma.d32 = (dma_addr_t) blob->channel[n].index[i].buf; + //hcdma.d32 = FIQ_READ(st->dwc_regs_base + HC_START + (HC_OFFSET * n) + HC_DMA); + //hcdma.d32 += st->channel[n].dma_info.slot_len[i]; + fiq_print(FIQDBG_INT, st, "LAST: %01d ", last); +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c +@@ -1041,8 +1041,8 @@ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd + * moderately readable array casts. + */ + hcd->fiq_dmab = DWC_DMA_ALLOC(dev, (sizeof(struct fiq_dma_channel) * num_channels), &hcd->fiq_state->dma_base); +- DWC_WARN("FIQ DMA bounce buffers: virt = 0x%08x dma = 0x%08x len=%d", +- (unsigned int)hcd->fiq_dmab, (unsigned int)hcd->fiq_state->dma_base, ++ DWC_WARN("FIQ DMA bounce buffers: virt = %px dma = %pad len=%zu", ++ hcd->fiq_dmab, &hcd->fiq_state->dma_base, + sizeof(struct fiq_dma_channel) * num_channels); + + DWC_MEMSET(hcd->fiq_dmab, 0x6b, 9024); +@@ -1522,9 +1522,12 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h + /* + * Set dma_regs to bounce buffer. FIQ will update the + * state depending on transaction progress. ++ * Pointer arithmetic on hcd->fiq_state->dma_base (a dma_addr_t) ++ * to point it to the correct offset in the allocated buffers. + */ + blob = (struct fiq_dma_blob *) hcd->fiq_state->dma_base; +- st->hcdma_copy.d32 = (uint32_t) &blob->channel[hc->hc_num].index[0].buf[0]; ++ st->hcdma_copy.d32 = (dma_addr_t) blob->channel[hc->hc_num].index[0].buf; ++ + /* Calculate the max number of CSPLITS such that the FIQ can time out + * a transaction if it fails. + */ +@@ -1571,9 +1574,15 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h + st->nrpackets = i; + } + ptr = qtd->urb->buf + frame_desc->offset; +- /* Point the HC at the DMA address of the bounce buffers */ ++ /* ++ * Point the HC at the DMA address of the bounce buffers ++ * ++ * Pointer arithmetic on hcd->fiq_state->dma_base (a ++ * dma_addr_t) to point it to the correct offset in the ++ * allocated buffers. ++ */ + blob = (struct fiq_dma_blob *) hcd->fiq_state->dma_base; +- st->hcdma_copy.d32 = (uint32_t) &blob->channel[hc->hc_num].index[0].buf[0]; ++ st->hcdma_copy.d32 = (dma_addr_t) blob->channel[hc->hc_num].index[0].buf; + + /* fixup xfersize to the actual packet size */ + st->hctsiz_copy.b.pid = 0; +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c +@@ -454,11 +454,9 @@ static void hcd_init_fiq(void *cookie) + DWC_ERROR("Can't claim FIQ"); + BUG(); + } +- DWC_WARN("FIQ on core %d at 0x%08x", +- smp_processor_id(), +- (fiq_fsm_enable ? (int)&dwc_otg_fiq_fsm : (int)&dwc_otg_fiq_nop)); +- DWC_WARN("FIQ ASM at 0x%08x length %d", (int)&_dwc_otg_fiq_stub, (int)(&_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub)); +- set_fiq_handler((void *) &_dwc_otg_fiq_stub, &_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub); ++ DWC_WARN("FIQ on core %d", smp_processor_id()); ++ DWC_WARN("FIQ ASM at %px length %d", &_dwc_otg_fiq_stub, (int)(&_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub)); ++ set_fiq_handler((void *) &_dwc_otg_fiq_stub, &_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub); + memset(®s,0,sizeof(regs)); + + regs.ARM_r8 = (long) dwc_otg_hcd->fiq_state; +@@ -483,7 +481,7 @@ static void hcd_init_fiq(void *cookie) + dwc_otg_hcd->fiq_state->mphi_regs.outddb = otg_dev->os_dep.mphi_base + 0x2c; + dwc_otg_hcd->fiq_state->mphi_regs.intstat = otg_dev->os_dep.mphi_base + 0x50; + dwc_otg_hcd->fiq_state->dwc_regs_base = otg_dev->os_dep.base; +- DWC_WARN("MPHI regs_base at 0x%08x", (int)dwc_otg_hcd->fiq_state->mphi_regs.base); ++ DWC_WARN("MPHI regs_base at %px", dwc_otg_hcd->fiq_state->mphi_regs.base); + //Enable mphi peripheral + writel((1<<31),dwc_otg_hcd->fiq_state->mphi_regs.ctrl); + #ifdef DEBUG diff --git a/target/linux/brcm2708/patches-4.19/950-0340-ASoC-pcm512x-Implement-the-digital_mute-interface.patch b/target/linux/brcm2708/patches-4.19/950-0340-ASoC-pcm512x-Implement-the-digital_mute-interface.patch deleted file mode 100644 index 68855d8bf3..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0340-ASoC-pcm512x-Implement-the-digital_mute-interface.patch +++ /dev/null @@ -1,196 +0,0 @@ -From 9912d38ec8ef31866f61d526e1d3c001c657964e Mon Sep 17 00:00:00 2001 -From: Dimitris Papavasiliou -Date: Sat, 24 Nov 2018 22:05:42 +0200 -Subject: [PATCH 340/703] ASoC: pcm512x: Implement the digital_mute interface - -[ Upstream commit 3500f1c589e92e0b6b1f8d31b4084fbde08d49cb ] - -Clicks and pops of various volumes can be produced while the device is -opened, closed, put into and taken out of standby, or reconfigured. -Fix this, by implementing the digital_mute interface, so that the -output is muted during such operations. - -Signed-off-by: Dimitris Papavasiliou -Signed-off-by: Mark Brown ---- - sound/soc/codecs/pcm512x.c | 121 ++++++++++++++++++++++++++++++++++++- - sound/soc/codecs/pcm512x.h | 2 + - 2 files changed, 121 insertions(+), 2 deletions(-) - ---- a/sound/soc/codecs/pcm512x.c -+++ b/sound/soc/codecs/pcm512x.c -@@ -53,6 +53,8 @@ struct pcm512x_priv { - unsigned long overclock_pll; - unsigned long overclock_dac; - unsigned long overclock_dsp; -+ int mute; -+ struct mutex mutex; - int lrclk_div; - }; - -@@ -385,6 +387,61 @@ static const struct soc_enum pcm512x_ved - SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDS_SHIFT, 4, - pcm512x_ramp_step_text); - -+static int pcm512x_update_mute(struct pcm512x_priv *pcm512x) -+{ -+ return regmap_update_bits( -+ pcm512x->regmap, PCM512x_MUTE, PCM512x_RQML | PCM512x_RQMR, -+ (!!(pcm512x->mute & 0x5) << PCM512x_RQML_SHIFT) -+ | (!!(pcm512x->mute & 0x3) << PCM512x_RQMR_SHIFT)); -+} -+ -+static int pcm512x_digital_playback_switch_get(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); -+ struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component); -+ -+ mutex_lock(&pcm512x->mutex); -+ ucontrol->value.integer.value[0] = !(pcm512x->mute & 0x4); -+ ucontrol->value.integer.value[1] = !(pcm512x->mute & 0x2); -+ mutex_unlock(&pcm512x->mutex); -+ -+ return 0; -+} -+ -+static int pcm512x_digital_playback_switch_put(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); -+ struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component); -+ int ret, changed = 0; -+ -+ mutex_lock(&pcm512x->mutex); -+ -+ if ((pcm512x->mute & 0x4) == (ucontrol->value.integer.value[0] << 2)) { -+ pcm512x->mute ^= 0x4; -+ changed = 1; -+ } -+ if ((pcm512x->mute & 0x2) == (ucontrol->value.integer.value[1] << 1)) { -+ pcm512x->mute ^= 0x2; -+ changed = 1; -+ } -+ -+ if (changed) { -+ ret = pcm512x_update_mute(pcm512x); -+ if (ret != 0) { -+ dev_err(component->dev, -+ "Failed to update digital mute: %d\n", ret); -+ mutex_unlock(&pcm512x->mutex); -+ return ret; -+ } -+ } -+ -+ mutex_unlock(&pcm512x->mutex); -+ -+ return changed; -+} -+ - static const struct snd_kcontrol_new pcm512x_controls[] = { - SOC_DOUBLE_R_TLV("Digital Playback Volume", PCM512x_DIGITAL_VOLUME_2, - PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv), -@@ -392,8 +449,15 @@ SOC_DOUBLE_TLV("Analogue Playback Volume - PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv), - SOC_DOUBLE_TLV("Analogue Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST, - PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv), --SOC_DOUBLE("Digital Playback Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT, -- PCM512x_RQMR_SHIFT, 1, 1), -+{ -+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, -+ .name = "Digital Playback Switch", -+ .index = 0, -+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, -+ .info = snd_ctl_boolean_stereo_info, -+ .get = pcm512x_digital_playback_switch_get, -+ .put = pcm512x_digital_playback_switch_put -+}, - - SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1), - SOC_ENUM("DSP Program", pcm512x_dsp_program), -@@ -1323,6 +1387,56 @@ static int pcm512x_set_fmt(struct snd_so - return 0; - } - -+static int pcm512x_digital_mute(struct snd_soc_dai *dai, int mute) -+{ -+ struct snd_soc_component *component = dai->component; -+ struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component); -+ int ret; -+ unsigned int mute_det; -+ -+ mutex_lock(&pcm512x->mutex); -+ -+ if (mute) { -+ pcm512x->mute |= 0x1; -+ ret = regmap_update_bits(pcm512x->regmap, PCM512x_MUTE, -+ PCM512x_RQML | PCM512x_RQMR, -+ PCM512x_RQML | PCM512x_RQMR); -+ if (ret != 0) { -+ dev_err(component->dev, -+ "Failed to set digital mute: %d\n", ret); -+ mutex_unlock(&pcm512x->mutex); -+ return ret; -+ } -+ -+ regmap_read_poll_timeout(pcm512x->regmap, -+ PCM512x_ANALOG_MUTE_DET, -+ mute_det, (mute_det & 0x3) == 0, -+ 200, 10000); -+ -+ mutex_unlock(&pcm512x->mutex); -+ } else { -+ pcm512x->mute &= ~0x1; -+ ret = pcm512x_update_mute(pcm512x); -+ if (ret != 0) { -+ dev_err(component->dev, -+ "Failed to update digital mute: %d\n", ret); -+ mutex_unlock(&pcm512x->mutex); -+ return ret; -+ } -+ -+ regmap_read_poll_timeout(pcm512x->regmap, -+ PCM512x_ANALOG_MUTE_DET, -+ mute_det, -+ (mute_det & 0x3) -+ == ((~pcm512x->mute >> 1) & 0x3), -+ 200, 10000); -+ } -+ -+ mutex_unlock(&pcm512x->mutex); -+ -+ return 0; -+} -+ - static int pcm512x_set_tdm_slot(struct snd_soc_dai *dai, - unsigned int tx_mask, unsigned int rx_mask, - int slots, int width) -@@ -1348,6 +1462,7 @@ static const struct snd_soc_dai_ops pcm5 - .startup = pcm512x_dai_startup, - .hw_params = pcm512x_hw_params, - .set_fmt = pcm512x_set_fmt, -+ .digital_mute = pcm512x_digital_mute, - .set_tdm_slot = pcm512x_set_tdm_slot, - }; - -@@ -1414,6 +1529,8 @@ int pcm512x_probe(struct device *dev, st - if (!pcm512x) - return -ENOMEM; - -+ mutex_init(&pcm512x->mutex); -+ - dev_set_drvdata(dev, pcm512x); - pcm512x->regmap = regmap; - ---- a/sound/soc/codecs/pcm512x.h -+++ b/sound/soc/codecs/pcm512x.h -@@ -112,7 +112,9 @@ - #define PCM512x_RQST_SHIFT 4 - - /* Page 0, Register 3 - mute */ -+#define PCM512x_RQMR (1 << 0) - #define PCM512x_RQMR_SHIFT 0 -+#define PCM512x_RQML (1 << 4) - #define PCM512x_RQML_SHIFT 4 - - /* Page 0, Register 4 - PLL */ diff --git a/target/linux/brcm2708/patches-4.19/950-0340-usb-dwc_otg-Use-dma-allocation-for-mphi-dummy_send-b.patch b/target/linux/brcm2708/patches-4.19/950-0340-usb-dwc_otg-Use-dma-allocation-for-mphi-dummy_send-b.patch new file mode 100644 index 0000000000..dae7cf4319 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0340-usb-dwc_otg-Use-dma-allocation-for-mphi-dummy_send-b.patch @@ -0,0 +1,74 @@ +From 17d7702409b1627d408bf2242af57ade58b5b0f9 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 30 Jan 2019 17:47:51 +0000 +Subject: [PATCH 340/725] usb: dwc_otg: Use dma allocation for mphi dummy_send + buffer + +The FIQ driver used a kzalloc'ed buffer for dummy_send, +passing a kernel virtual address to the hardware block. +The buffer is only ever used for a dummy read, so it +should be harmless, but there is the chance that it will +cause exceptions. + +Use a dma allocation so that we have a genuine bus address, +and read from that. +Free the allocation when done for good measure. + +Signed-off-by: Dave Stevenson +--- + drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 4 ++-- + drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h | 1 + + drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 5 ++++- + 3 files changed, 7 insertions(+), 3 deletions(-) + +--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c +@@ -1347,7 +1347,7 @@ void notrace dwc_otg_fiq_fsm(struct fiq_ + /* We got an interrupt, didn't handle it. */ + if (kick_irq) { + state->mphi_int_count++; +- FIQ_WRITE(state->mphi_regs.outdda, (int) state->dummy_send); ++ FIQ_WRITE(state->mphi_regs.outdda, state->dummy_send_dma); + FIQ_WRITE(state->mphi_regs.outddb, (1<<29)); + + } +@@ -1408,7 +1408,7 @@ void notrace dwc_otg_fiq_nop(struct fiq_ + FIQ_WRITE(state->dwc_regs_base + GINTMSK, gintmsk.d32); + /* Force a clear before another dummy send */ + FIQ_WRITE(state->mphi_regs.intstat, (1<<29)); +- FIQ_WRITE(state->mphi_regs.outdda, (int) state->dummy_send); ++ FIQ_WRITE(state->mphi_regs.outdda, state->dummy_send_dma); + FIQ_WRITE(state->mphi_regs.outddb, (1<<29)); + + } +--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h ++++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h +@@ -352,6 +352,7 @@ struct fiq_state { + dma_addr_t dma_base; + struct fiq_dma_blob *fiq_dmab; + void *dummy_send; ++ dma_addr_t dummy_send_dma; + gintmsk_data_t gintmsk_saved; + haintmsk_data_t haintmsk_saved; + int mphi_int_count; +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c +@@ -929,6 +929,8 @@ static void dwc_otg_hcd_free(dwc_otg_hcd + DWC_TIMER_FREE(dwc_otg_hcd->conn_timer); + DWC_TASK_FREE(dwc_otg_hcd->reset_tasklet); + DWC_TASK_FREE(dwc_otg_hcd->completion_tasklet); ++ DWC_DMA_FREE(dev, 16, dwc_otg_hcd->fiq_state->dummy_send, ++ dwc_otg_hcd->fiq_state->dummy_send_dma); + DWC_FREE(dwc_otg_hcd->fiq_state); + + #ifdef DWC_DEV_SRPCAP +@@ -1021,7 +1023,8 @@ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd + for (i = 0; i < num_channels; i++) { + hcd->fiq_state->channel[i].fsm = FIQ_PASSTHROUGH; + } +- hcd->fiq_state->dummy_send = DWC_ALLOC_ATOMIC(16); ++ hcd->fiq_state->dummy_send = DWC_DMA_ALLOC_ATOMIC(dev, 16, ++ &hcd->fiq_state->dummy_send_dma); + + hcd->fiq_stack = DWC_ALLOC(sizeof(struct fiq_stack)); + if (!hcd->fiq_stack) { diff --git a/target/linux/brcm2708/patches-4.19/950-0341-ASoC-pcm512x-Fix-a-double-unlock-in-pcm512x_digital_.patch b/target/linux/brcm2708/patches-4.19/950-0341-ASoC-pcm512x-Fix-a-double-unlock-in-pcm512x_digital_.patch deleted file mode 100644 index 83113e92cd..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0341-ASoC-pcm512x-Fix-a-double-unlock-in-pcm512x_digital_.patch +++ /dev/null @@ -1,62 +0,0 @@ -From e0d60424f966b62d61300cec4ba7fd070abaf772 Mon Sep 17 00:00:00 2001 -From: Dan Carpenter -Date: Fri, 21 Dec 2018 12:11:20 +0300 -Subject: [PATCH 341/703] ASoC: pcm512x: Fix a double unlock in - pcm512x_digital_mute() - -[ Upstream commit 28b698b7342c7d5300cfe217cd77ff7d2a55e03d ] - -We accidentally call mutex_unlock(&pcm512x->mutex); twice in a row. - -I re-wrote the error handling to use "goto unlock;" instead of returning -directly. Hopefully, it makes the code a little simpler. - -Fixes: 3500f1c589e9 ("ASoC: pcm512x: Implement the digital_mute interface") -Signed-off-by: Dan Carpenter -Reviwed-by: Dimitris Papavasiliou -Signed-off-by: Mark Brown ---- - sound/soc/codecs/pcm512x.c | 11 ++++------- - 1 file changed, 4 insertions(+), 7 deletions(-) - ---- a/sound/soc/codecs/pcm512x.c -+++ b/sound/soc/codecs/pcm512x.c -@@ -1404,24 +1404,20 @@ static int pcm512x_digital_mute(struct s - if (ret != 0) { - dev_err(component->dev, - "Failed to set digital mute: %d\n", ret); -- mutex_unlock(&pcm512x->mutex); -- return ret; -+ goto unlock; - } - - regmap_read_poll_timeout(pcm512x->regmap, - PCM512x_ANALOG_MUTE_DET, - mute_det, (mute_det & 0x3) == 0, - 200, 10000); -- -- mutex_unlock(&pcm512x->mutex); - } else { - pcm512x->mute &= ~0x1; - ret = pcm512x_update_mute(pcm512x); - if (ret != 0) { - dev_err(component->dev, - "Failed to update digital mute: %d\n", ret); -- mutex_unlock(&pcm512x->mutex); -- return ret; -+ goto unlock; - } - - regmap_read_poll_timeout(pcm512x->regmap, -@@ -1432,9 +1428,10 @@ static int pcm512x_digital_mute(struct s - 200, 10000); - } - -+unlock: - mutex_unlock(&pcm512x->mutex); - -- return 0; -+ return ret; - } - - static int pcm512x_set_tdm_slot(struct snd_soc_dai *dai, diff --git a/target/linux/brcm2708/patches-4.19/950-0341-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch b/target/linux/brcm2708/patches-4.19/950-0341-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch new file mode 100644 index 0000000000..c73141de27 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0341-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch @@ -0,0 +1,47 @@ +From a42314a829d8a17ccfd533c90339348b09e85de8 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 29 Jan 2019 16:13:25 +0000 +Subject: [PATCH 341/725] staging: vchiq_arm: Set up dma ranges on child + devices + +The VCHIQ driver now loads the audio, camera, codec, and vc-sm +drivers as platform drivers. However they were not being given +the correct DMA configuration. + +Call of_dma_configure with the parent (VCHIQ) parameters to be +inherited by the child. + +Signed-off-by: Dave Stevenson +--- + .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +@@ -3585,6 +3585,7 @@ static struct platform_device * + vchiq_register_child(struct platform_device *pdev, const char *name) + { + struct platform_device_info pdevinfo; ++ struct platform_device *new_dev; + + memset(&pdevinfo, 0, sizeof(pdevinfo)); + +@@ -3593,7 +3594,17 @@ vchiq_register_child(struct platform_dev + pdevinfo.id = PLATFORM_DEVID_NONE; + pdevinfo.dma_mask = DMA_BIT_MASK(32); + +- return platform_device_register_full(&pdevinfo); ++ new_dev = platform_device_register_full(&pdevinfo); ++ if (!new_dev) ++ return NULL; ++ ++ /* ++ * We want the dma-ranges etc to be copied from the parent VCHIQ device ++ * to be passed on to the children too. ++ */ ++ of_dma_configure(&new_dev->dev, pdev->dev.of_node, true); ++ ++ return new_dev; + } + + static int vchiq_probe(struct platform_device *pdev) diff --git a/target/linux/brcm2708/patches-4.19/950-0342-staging-vc-sm-cma-Correct-DMA-configuration.patch b/target/linux/brcm2708/patches-4.19/950-0342-staging-vc-sm-cma-Correct-DMA-configuration.patch new file mode 100644 index 0000000000..ec6a42dfda --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0342-staging-vc-sm-cma-Correct-DMA-configuration.patch @@ -0,0 +1,44 @@ +From f1c5c628f7cab20490bec1cdafc53048b10b65f2 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 29 Jan 2019 16:24:41 +0000 +Subject: [PATCH 342/725] staging: vc-sm-cma: Correct DMA configuration. + +Now that VCHIQ is setting up the DMA configuration as our +parent device, don't try to configure it during probe. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 15 +++++---------- + 1 file changed, 5 insertions(+), 10 deletions(-) + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -703,9 +703,6 @@ err_free_mem: + /* Driver loading. */ + static int bcm2835_vc_sm_cma_probe(struct platform_device *pdev) + { +- struct device *dev = &pdev->dev; +- int err; +- + pr_info("%s: Videocore shared memory driver\n", __func__); + + sm_state = kzalloc(sizeof(*sm_state), GFP_KERNEL); +@@ -714,13 +711,11 @@ static int bcm2835_vc_sm_cma_probe(struc + sm_state->pdev = pdev; + mutex_init(&sm_state->map_lock); + +- dev->coherent_dma_mask = DMA_BIT_MASK(32); +- dev->dma_mask = &dev->coherent_dma_mask; +- err = of_dma_configure(dev, NULL, true); +- if (err) { +- dev_err(dev, "Unable to setup DMA: %d\n", err); +- return err; +- } ++ pdev->dev.dma_parms = devm_kzalloc(&pdev->dev, ++ sizeof(*pdev->dev.dma_parms), ++ GFP_KERNEL); ++ /* dma_set_max_seg_size checks if dma_parms is NULL. */ ++ dma_set_max_seg_size(&pdev->dev, 0x3FFFFFFF); + + vchiq_add_connected_callback(vc_sm_connected_init); + return 0; diff --git a/target/linux/brcm2708/patches-4.19/950-0342-usb-dwc_otg-Clean-up-build-warnings-on-64bit-kernels.patch b/target/linux/brcm2708/patches-4.19/950-0342-usb-dwc_otg-Clean-up-build-warnings-on-64bit-kernels.patch deleted file mode 100644 index de67efcd99..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0342-usb-dwc_otg-Clean-up-build-warnings-on-64bit-kernels.patch +++ /dev/null @@ -1,110 +0,0 @@ -From b10441b7ce4abbdb0f870f705cbb7d3520a57044 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 25 Jan 2019 16:03:31 +0000 -Subject: [PATCH 342/703] usb: dwc_otg: Clean up build warnings on 64bit - kernels - -No functional changes. Almost all are changes to logging lines. - -Signed-off-by: Dave Stevenson ---- - drivers/usb/host/dwc_otg/dwc_otg_driver.c | 3 +-- - drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 2 +- - drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 19 ++++++++++++++----- - drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 10 ++++------ - 4 files changed, 20 insertions(+), 14 deletions(-) - ---- a/drivers/usb/host/dwc_otg/dwc_otg_driver.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -@@ -837,8 +837,7 @@ static int dwc_otg_driver_probe( - retval = -ENOMEM; - goto fail; - } -- dev_info(&_dev->dev, "base=0x%08x\n", -- (unsigned)dwc_otg_device->os_dep.base); -+ dev_info(&_dev->dev, "base=%p\n", dwc_otg_device->os_dep.base); - #endif - - /* ---- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c -@@ -301,7 +301,7 @@ static int notrace fiq_iso_out_advance(s - last = 1; - - /* New DMA address - address of bounce buffer referred to in index */ -- hcdma.d32 = (uint32_t) &blob->channel[n].index[i].buf[0]; -+ hcdma.d32 = (dma_addr_t) blob->channel[n].index[i].buf; - //hcdma.d32 = FIQ_READ(st->dwc_regs_base + HC_START + (HC_OFFSET * n) + HC_DMA); - //hcdma.d32 += st->channel[n].dma_info.slot_len[i]; - fiq_print(FIQDBG_INT, st, "LAST: %01d ", last); ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -@@ -1041,8 +1041,8 @@ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd - * moderately readable array casts. - */ - hcd->fiq_dmab = DWC_DMA_ALLOC(dev, (sizeof(struct fiq_dma_channel) * num_channels), &hcd->fiq_state->dma_base); -- DWC_WARN("FIQ DMA bounce buffers: virt = 0x%08x dma = 0x%08x len=%d", -- (unsigned int)hcd->fiq_dmab, (unsigned int)hcd->fiq_state->dma_base, -+ DWC_WARN("FIQ DMA bounce buffers: virt = %px dma = %pad len=%zu", -+ hcd->fiq_dmab, &hcd->fiq_state->dma_base, - sizeof(struct fiq_dma_channel) * num_channels); - - DWC_MEMSET(hcd->fiq_dmab, 0x6b, 9024); -@@ -1522,9 +1522,12 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h - /* - * Set dma_regs to bounce buffer. FIQ will update the - * state depending on transaction progress. -+ * Pointer arithmetic on hcd->fiq_state->dma_base (a dma_addr_t) -+ * to point it to the correct offset in the allocated buffers. - */ - blob = (struct fiq_dma_blob *) hcd->fiq_state->dma_base; -- st->hcdma_copy.d32 = (uint32_t) &blob->channel[hc->hc_num].index[0].buf[0]; -+ st->hcdma_copy.d32 = (dma_addr_t) blob->channel[hc->hc_num].index[0].buf; -+ - /* Calculate the max number of CSPLITS such that the FIQ can time out - * a transaction if it fails. - */ -@@ -1571,9 +1574,15 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h - st->nrpackets = i; - } - ptr = qtd->urb->buf + frame_desc->offset; -- /* Point the HC at the DMA address of the bounce buffers */ -+ /* -+ * Point the HC at the DMA address of the bounce buffers -+ * -+ * Pointer arithmetic on hcd->fiq_state->dma_base (a -+ * dma_addr_t) to point it to the correct offset in the -+ * allocated buffers. -+ */ - blob = (struct fiq_dma_blob *) hcd->fiq_state->dma_base; -- st->hcdma_copy.d32 = (uint32_t) &blob->channel[hc->hc_num].index[0].buf[0]; -+ st->hcdma_copy.d32 = (dma_addr_t) blob->channel[hc->hc_num].index[0].buf; - - /* fixup xfersize to the actual packet size */ - st->hctsiz_copy.b.pid = 0; ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -@@ -454,11 +454,9 @@ static void hcd_init_fiq(void *cookie) - DWC_ERROR("Can't claim FIQ"); - BUG(); - } -- DWC_WARN("FIQ on core %d at 0x%08x", -- smp_processor_id(), -- (fiq_fsm_enable ? (int)&dwc_otg_fiq_fsm : (int)&dwc_otg_fiq_nop)); -- DWC_WARN("FIQ ASM at 0x%08x length %d", (int)&_dwc_otg_fiq_stub, (int)(&_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub)); -- set_fiq_handler((void *) &_dwc_otg_fiq_stub, &_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub); -+ DWC_WARN("FIQ on core %d", smp_processor_id()); -+ DWC_WARN("FIQ ASM at %px length %d", &_dwc_otg_fiq_stub, (int)(&_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub)); -+ set_fiq_handler((void *) &_dwc_otg_fiq_stub, &_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub); - memset(®s,0,sizeof(regs)); - - regs.ARM_r8 = (long) dwc_otg_hcd->fiq_state; -@@ -483,7 +481,7 @@ static void hcd_init_fiq(void *cookie) - dwc_otg_hcd->fiq_state->mphi_regs.outddb = otg_dev->os_dep.mphi_base + 0x2c; - dwc_otg_hcd->fiq_state->mphi_regs.intstat = otg_dev->os_dep.mphi_base + 0x50; - dwc_otg_hcd->fiq_state->dwc_regs_base = otg_dev->os_dep.base; -- DWC_WARN("MPHI regs_base at 0x%08x", (int)dwc_otg_hcd->fiq_state->mphi_regs.base); -+ DWC_WARN("MPHI regs_base at %px", dwc_otg_hcd->fiq_state->mphi_regs.base); - //Enable mphi peripheral - writel((1<<31),dwc_otg_hcd->fiq_state->mphi_regs.ctrl); - #ifdef DEBUG diff --git a/target/linux/brcm2708/patches-4.19/950-0343-staging-vc-sm-cma-Use-a-void-pointer-as-the-handle-w.patch b/target/linux/brcm2708/patches-4.19/950-0343-staging-vc-sm-cma-Use-a-void-pointer-as-the-handle-w.patch new file mode 100644 index 0000000000..1edffb16c2 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0343-staging-vc-sm-cma-Use-a-void-pointer-as-the-handle-w.patch @@ -0,0 +1,111 @@ +From 6d7ababea249987cb3014e62b54d8ee577179107 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 29 Jan 2019 16:29:00 +0000 +Subject: [PATCH 343/725] staging: vc-sm-cma: Use a void* pointer as the handle + within the kernel + +The driver was using an unsigned int as the handle to the outside world, +and doing a nasty cast to the struct dmabuf when handed it back. +This breaks badly with a 64 bit kernel where the pointer doesn't fit +in an unsigned int. + +Switch to using a void* within the kernel. Reality is that it is +a struct dma_buf*, but advertising it as such to other drivers seems +to encourage the use of it as such, and I'm not sure on the implications +of that. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 10 +++++----- + drivers/staging/vc04_services/vc-sm-cma/vc_sm_knl.h | 6 +++--- + drivers/staging/vc04_services/vchiq-mmal/mmal-common.h | 2 +- + drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 2 +- + 4 files changed, 10 insertions(+), 10 deletions(-) + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -745,7 +745,7 @@ static int bcm2835_vc_sm_cma_remove(stru + } + + /* Get an internal resource handle mapped from the external one. */ +-int vc_sm_cma_int_handle(int handle) ++int vc_sm_cma_int_handle(void *handle) + { + struct dma_buf *dma_buf = (struct dma_buf *)handle; + struct vc_sm_buffer *res; +@@ -762,7 +762,7 @@ int vc_sm_cma_int_handle(int handle) + EXPORT_SYMBOL_GPL(vc_sm_cma_int_handle); + + /* Free a previously allocated shared memory handle and block. */ +-int vc_sm_cma_free(int handle) ++int vc_sm_cma_free(void *handle) + { + struct dma_buf *dma_buf = (struct dma_buf *)handle; + +@@ -772,7 +772,7 @@ int vc_sm_cma_free(int handle) + return -EPERM; + } + +- pr_debug("%s: handle %08x/dmabuf %p\n", __func__, handle, dma_buf); ++ pr_debug("%s: handle %p/dmabuf %p\n", __func__, handle, dma_buf); + + dma_buf_put(dma_buf); + +@@ -781,7 +781,7 @@ int vc_sm_cma_free(int handle) + EXPORT_SYMBOL_GPL(vc_sm_cma_free); + + /* Import a dmabuf to be shared with VC. */ +-int vc_sm_cma_import_dmabuf(struct dma_buf *src_dmabuf, int *handle) ++int vc_sm_cma_import_dmabuf(struct dma_buf *src_dmabuf, void **handle) + { + struct dma_buf *new_dma_buf; + struct vc_sm_buffer *res; +@@ -801,7 +801,7 @@ int vc_sm_cma_import_dmabuf(struct dma_b + res = (struct vc_sm_buffer *)new_dma_buf->priv; + + /* Assign valid handle at this time.*/ +- *handle = (int)new_dma_buf; ++ *handle = new_dma_buf; + } else { + /* + * succeeded in importing the dma_buf, but then +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_knl.h ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_knl.h +@@ -17,12 +17,12 @@ + #endif + + /* Free a previously allocated or imported shared memory handle and block. */ +-int vc_sm_cma_free(int handle); ++int vc_sm_cma_free(void *handle); + + /* Get an internal resource handle mapped from the external one. */ +-int vc_sm_cma_int_handle(int handle); ++int vc_sm_cma_int_handle(void *handle); + + /* Import a block of memory into the GPU space. */ +-int vc_sm_cma_import_dmabuf(struct dma_buf *dmabuf, int *handle); ++int vc_sm_cma_import_dmabuf(struct dma_buf *dmabuf, void **handle); + + #endif /* __VC_SM_KNL_H__INCLUDED__ */ +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h +@@ -52,7 +52,7 @@ struct mmal_buffer { + struct mmal_msg_context *msg_context; + + struct dma_buf *dma_buf;/* Exported dmabuf fd from videobuf2 */ +- int vcsm_handle; /* VCSM handle having imported the dmabuf */ ++ void *vcsm_handle; /* VCSM handle having imported the dmabuf */ + u32 vc_handle; /* VC handle to that dmabuf */ + + u32 cmd; /* MMAL command. 0=data. */ +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +@@ -1794,7 +1794,7 @@ int mmal_vchi_buffer_cleanup(struct mmal + if (buf->vcsm_handle) { + int ret; + +- pr_debug("%s: vc_sm_cma_free on handle %08X\n", __func__, ++ pr_debug("%s: vc_sm_cma_free on handle %p\n", __func__, + buf->vcsm_handle); + ret = vc_sm_cma_free(buf->vcsm_handle); + if (ret) diff --git a/target/linux/brcm2708/patches-4.19/950-0343-usb-dwc_otg-Use-dma-allocation-for-mphi-dummy_send-b.patch b/target/linux/brcm2708/patches-4.19/950-0343-usb-dwc_otg-Use-dma-allocation-for-mphi-dummy_send-b.patch deleted file mode 100644 index 43a2877fd4..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0343-usb-dwc_otg-Use-dma-allocation-for-mphi-dummy_send-b.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 2aa9b698ab642535989a1bd69300f9a6e13395c9 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 30 Jan 2019 17:47:51 +0000 -Subject: [PATCH 343/703] usb: dwc_otg: Use dma allocation for mphi dummy_send - buffer - -The FIQ driver used a kzalloc'ed buffer for dummy_send, -passing a kernel virtual address to the hardware block. -The buffer is only ever used for a dummy read, so it -should be harmless, but there is the chance that it will -cause exceptions. - -Use a dma allocation so that we have a genuine bus address, -and read from that. -Free the allocation when done for good measure. - -Signed-off-by: Dave Stevenson ---- - drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 4 ++-- - drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h | 1 + - drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 5 ++++- - 3 files changed, 7 insertions(+), 3 deletions(-) - ---- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c -@@ -1347,7 +1347,7 @@ void notrace dwc_otg_fiq_fsm(struct fiq_ - /* We got an interrupt, didn't handle it. */ - if (kick_irq) { - state->mphi_int_count++; -- FIQ_WRITE(state->mphi_regs.outdda, (int) state->dummy_send); -+ FIQ_WRITE(state->mphi_regs.outdda, state->dummy_send_dma); - FIQ_WRITE(state->mphi_regs.outddb, (1<<29)); - - } -@@ -1408,7 +1408,7 @@ void notrace dwc_otg_fiq_nop(struct fiq_ - FIQ_WRITE(state->dwc_regs_base + GINTMSK, gintmsk.d32); - /* Force a clear before another dummy send */ - FIQ_WRITE(state->mphi_regs.intstat, (1<<29)); -- FIQ_WRITE(state->mphi_regs.outdda, (int) state->dummy_send); -+ FIQ_WRITE(state->mphi_regs.outdda, state->dummy_send_dma); - FIQ_WRITE(state->mphi_regs.outddb, (1<<29)); - - } ---- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h -+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h -@@ -352,6 +352,7 @@ struct fiq_state { - dma_addr_t dma_base; - struct fiq_dma_blob *fiq_dmab; - void *dummy_send; -+ dma_addr_t dummy_send_dma; - gintmsk_data_t gintmsk_saved; - haintmsk_data_t haintmsk_saved; - int mphi_int_count; ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -@@ -929,6 +929,8 @@ static void dwc_otg_hcd_free(dwc_otg_hcd - DWC_TIMER_FREE(dwc_otg_hcd->conn_timer); - DWC_TASK_FREE(dwc_otg_hcd->reset_tasklet); - DWC_TASK_FREE(dwc_otg_hcd->completion_tasklet); -+ DWC_DMA_FREE(dev, 16, dwc_otg_hcd->fiq_state->dummy_send, -+ dwc_otg_hcd->fiq_state->dummy_send_dma); - DWC_FREE(dwc_otg_hcd->fiq_state); - - #ifdef DWC_DEV_SRPCAP -@@ -1021,7 +1023,8 @@ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd - for (i = 0; i < num_channels; i++) { - hcd->fiq_state->channel[i].fsm = FIQ_PASSTHROUGH; - } -- hcd->fiq_state->dummy_send = DWC_ALLOC_ATOMIC(16); -+ hcd->fiq_state->dummy_send = DWC_DMA_ALLOC_ATOMIC(dev, 16, -+ &hcd->fiq_state->dummy_send_dma); - - hcd->fiq_stack = DWC_ALLOC(sizeof(struct fiq_stack)); - if (!hcd->fiq_stack) { diff --git a/target/linux/brcm2708/patches-4.19/950-0344-staging-vc-sm-cma-Fix-up-for-64bit-builds.patch b/target/linux/brcm2708/patches-4.19/950-0344-staging-vc-sm-cma-Fix-up-for-64bit-builds.patch new file mode 100644 index 0000000000..0ddbb4297e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0344-staging-vc-sm-cma-Fix-up-for-64bit-builds.patch @@ -0,0 +1,199 @@ +From 8da5f5ca322c3b6c5c9055381af9db67f724bdc3 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 29 Jan 2019 16:32:57 +0000 +Subject: [PATCH 344/725] staging: vc-sm-cma: Fix up for 64bit builds + +There were a number of logging lines that were using +inappropriate formatting under 64bit kernels. + +The kernel_id field passed to/from the VPU was being +abused for storing the struct vc_sm_buffer *. +This breaks with 64bit kernels, so change to using an IDR. + +Signed-off-by: Dave Stevenson +--- + .../staging/vc04_services/vc-sm-cma/vc_sm.c | 60 +++++++++++++++---- + .../vc04_services/vc-sm-cma/vc_sm_cma_vchi.c | 3 +- + 2 files changed, 48 insertions(+), 15 deletions(-) + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -75,6 +75,9 @@ struct sm_state_t { + struct miscdevice dev; + struct sm_instance *sm_handle; /* Handle for videocore service. */ + ++ spinlock_t kernelid_map_lock; /* Spinlock protecting kernelid_map */ ++ struct idr kernelid_map; ++ + struct mutex map_lock; /* Global map lock. */ + struct list_head buffer_list; /* List of buffer. */ + +@@ -97,6 +100,29 @@ static int sm_inited; + + /* ---- Private Functions ------------------------------------------------ */ + ++static int get_kernel_id(struct vc_sm_buffer *buffer) ++{ ++ int handle; ++ ++ spin_lock(&sm_state->kernelid_map_lock); ++ handle = idr_alloc(&sm_state->kernelid_map, buffer, 0, 0, GFP_KERNEL); ++ spin_unlock(&sm_state->kernelid_map_lock); ++ ++ return handle; ++} ++ ++static struct vc_sm_buffer *lookup_kernel_id(int handle) ++{ ++ return idr_find(&sm_state->kernelid_map, handle); ++} ++ ++static void free_kernel_id(int handle) ++{ ++ spin_lock(&sm_state->kernelid_map_lock); ++ idr_remove(&sm_state->kernelid_map, handle); ++ spin_unlock(&sm_state->kernelid_map_lock); ++} ++ + static int vc_sm_cma_seq_file_show(struct seq_file *s, void *v) + { + struct sm_pde_t *sm_pde; +@@ -129,8 +155,7 @@ static int vc_sm_cma_global_state_show(s + if (!sm_state) + return 0; + +- seq_printf(s, "\nVC-ServiceHandle 0x%x\n", +- (unsigned int)sm_state->sm_handle); ++ seq_printf(s, "\nVC-ServiceHandle %p\n", sm_state->sm_handle); + + /* Log all applicable mapping(s). */ + +@@ -145,7 +170,7 @@ static int vc_sm_cma_global_state_show(s + resource); + seq_printf(s, " NAME %s\n", + resource->name); +- seq_printf(s, " SIZE %d\n", ++ seq_printf(s, " SIZE %zu\n", + resource->size); + seq_printf(s, " DMABUF %p\n", + resource->dma_buf); +@@ -181,7 +206,7 @@ static void vc_sm_add_resource(struct vc + list_add(&buffer->global_buffer_list, &sm_state->buffer_list); + mutex_unlock(&sm_state->map_lock); + +- pr_debug("[%s]: added buffer %p (name %s, size %d)\n", ++ pr_debug("[%s]: added buffer %p (name %s, size %zu)\n", + __func__, buffer, buffer->name, buffer->size); + } + +@@ -194,7 +219,7 @@ static void vc_sm_release_resource(struc + mutex_lock(&sm_state->map_lock); + mutex_lock(&buffer->lock); + +- pr_debug("[%s]: buffer %p (name %s, size %d)\n", ++ pr_debug("[%s]: buffer %p (name %s, size %zu)\n", + __func__, buffer, buffer->name, buffer->size); + + if (buffer->vc_handle && buffer->vpu_state == VPU_MAPPED) { +@@ -443,6 +468,7 @@ vc_sm_cma_import_dmabuf_internal(struct + struct vc_sm_import_result result = { }; + struct dma_buf_attachment *attach = NULL; + struct sg_table *sgt = NULL; ++ dma_addr_t dma_addr; + int ret = 0; + int status; + +@@ -478,21 +504,22 @@ vc_sm_cma_import_dmabuf_internal(struct + } + + import.type = VC_SM_ALLOC_NON_CACHED; +- import.addr = (uint32_t)sg_dma_address(sgt->sgl); ++ dma_addr = sg_dma_address(sgt->sgl); ++ import.addr = (uint32_t)dma_addr; + if ((import.addr & 0xC0000000) != 0xC0000000) { +- pr_err("%s: Expecting an uncached alias for dma_addr %08x\n", +- __func__, import.addr); ++ pr_err("%s: Expecting an uncached alias for dma_addr %pad\n", ++ __func__, &dma_addr); + import.addr |= 0xC0000000; + } + import.size = sg_dma_len(sgt->sgl); + import.allocator = current->tgid; +- import.kernel_id = (uint32_t)buffer; //FIXME: 64 bit support needed. ++ import.kernel_id = get_kernel_id(buffer); + + memcpy(import.name, VC_SM_RESOURCE_NAME_DEFAULT, + sizeof(VC_SM_RESOURCE_NAME_DEFAULT)); + +- pr_debug("[%s]: attempt to import \"%s\" data - type %u, addr %p, size %u\n", +- __func__, import.name, import.type, (void *)import.addr, ++ pr_debug("[%s]: attempt to import \"%s\" data - type %u, addr %pad, size %u\n", ++ __func__, import.name, import.type, &dma_addr, + import.size); + + /* Allocate the videocore buffer. */ +@@ -527,7 +554,7 @@ vc_sm_cma_import_dmabuf_internal(struct + + buffer->attach = attach; + buffer->sgt = sgt; +- buffer->dma_addr = sg_dma_address(sgt->sgl); ++ buffer->dma_addr = dma_addr; + buffer->in_use = 1; + + /* +@@ -559,6 +586,7 @@ error: + vc_sm_cma_vchi_free(sm_state->sm_handle, &free, + &sm_state->int_trans_id); + } ++ free_kernel_id(import.kernel_id); + kfree(buffer); + if (sgt) + dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); +@@ -586,7 +614,7 @@ vc_sm_vpu_event(struct sm_instance *inst + { + struct vc_sm_released *release = (struct vc_sm_released *)reply; + struct vc_sm_buffer *buffer = +- (struct vc_sm_buffer *)release->kernel_id; ++ lookup_kernel_id(release->kernel_id); + + /* + * FIXME: Need to check buffer is still valid and allocated +@@ -599,6 +627,7 @@ vc_sm_vpu_event(struct sm_instance *inst + buffer->vc_handle = 0; + buffer->vpu_state = VPU_NOT_MAPPED; + mutex_unlock(&buffer->lock); ++ free_kernel_id(release->kernel_id); + + vc_sm_release_resource(buffer, 0); + } +@@ -711,6 +740,9 @@ static int bcm2835_vc_sm_cma_probe(struc + sm_state->pdev = pdev; + mutex_init(&sm_state->map_lock); + ++ spin_lock_init(&sm_state->kernelid_map_lock); ++ idr_init_base(&sm_state->kernelid_map, 1); ++ + pdev->dev.dma_parms = devm_kzalloc(&pdev->dev, + sizeof(*pdev->dev.dma_parms), + GFP_KERNEL); +@@ -735,6 +767,8 @@ static int bcm2835_vc_sm_cma_remove(stru + /* Stop the videocore shared memory service. */ + vc_sm_cma_vchi_stop(&sm_state->sm_handle); + ++ idr_destroy(&sm_state->kernelid_map); ++ + /* Free the memory for the state structure. */ + mutex_destroy(&sm_state->map_lock); + kfree(sm_state); +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c +@@ -356,8 +356,7 @@ struct sm_instance *vc_sm_cma_vchi_init( + set_user_nice(instance->io_thread, -10); + wake_up_process(instance->io_thread); + +- pr_debug("%s: success - instance 0x%x", __func__, +- (unsigned int)instance); ++ pr_debug("%s: success - instance %p", __func__, instance); + return instance; + + err_close_services: diff --git a/target/linux/brcm2708/patches-4.19/950-0344-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch b/target/linux/brcm2708/patches-4.19/950-0344-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch deleted file mode 100644 index 760042c5c4..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0344-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0a0aaf192a20f9c5552c0fca4f5b29c3d31784ab Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 29 Jan 2019 16:13:25 +0000 -Subject: [PATCH 344/703] staging: vchiq_arm: Set up dma ranges on child - devices - -The VCHIQ driver now loads the audio, camera, codec, and vc-sm -drivers as platform drivers. However they were not being given -the correct DMA configuration. - -Call of_dma_configure with the parent (VCHIQ) parameters to be -inherited by the child. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -3585,6 +3585,7 @@ static struct platform_device * - vchiq_register_child(struct platform_device *pdev, const char *name) - { - struct platform_device_info pdevinfo; -+ struct platform_device *new_dev; - - memset(&pdevinfo, 0, sizeof(pdevinfo)); - -@@ -3593,7 +3594,17 @@ vchiq_register_child(struct platform_dev - pdevinfo.id = PLATFORM_DEVID_NONE; - pdevinfo.dma_mask = DMA_BIT_MASK(32); - -- return platform_device_register_full(&pdevinfo); -+ new_dev = platform_device_register_full(&pdevinfo); -+ if (!new_dev) -+ return NULL; -+ -+ /* -+ * We want the dma-ranges etc to be copied from the parent VCHIQ device -+ * to be passed on to the children too. -+ */ -+ of_dma_configure(&new_dev->dev, pdev->dev.of_node, true); -+ -+ return new_dev; - } - - static int vchiq_probe(struct platform_device *pdev) diff --git a/target/linux/brcm2708/patches-4.19/950-0345-configs-Add-Unicam-and-subdevices-to-bcmrpi3_defconf.patch b/target/linux/brcm2708/patches-4.19/950-0345-configs-Add-Unicam-and-subdevices-to-bcmrpi3_defconf.patch new file mode 100644 index 0000000000..ef3363abaa --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0345-configs-Add-Unicam-and-subdevices-to-bcmrpi3_defconf.patch @@ -0,0 +1,47 @@ +From e8ee011946b8c53828e512c3bf2a964934073a4e Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 4 Feb 2019 12:35:06 +0000 +Subject: [PATCH 345/725] configs: Add Unicam and subdevices to + bcmrpi3_defconfig + +The bcm2835-unicam, tc358743, adv7180 (for adv7282m) and ov5647 +have been tested on a 64bit kernel and shown to work. +Add them to the config. + +Signed-off-by: Dave Stevenson +--- + arch/arm64/configs/bcmrpi3_defconfig | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -645,6 +645,7 @@ CONFIG_MEDIA_ANALOG_TV_SUPPORT=y + CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y + CONFIG_MEDIA_RADIO_SUPPORT=y + CONFIG_MEDIA_CONTROLLER=y ++CONFIG_VIDEO_V4L2_SUBDEV_API=y + CONFIG_MEDIA_USB_SUPPORT=y + CONFIG_USB_VIDEO_CLASS=m + CONFIG_USB_M5602=m +@@ -727,6 +728,7 @@ CONFIG_VIDEO_EM28XX_V4L2=m + CONFIG_VIDEO_EM28XX_ALSA=m + CONFIG_VIDEO_EM28XX_DVB=m + CONFIG_V4L_PLATFORM_DRIVERS=y ++CONFIG_VIDEO_BCM2835_UNICAM=m + CONFIG_RADIO_SI470X=m + CONFIG_USB_SI470X=m + CONFIG_I2C_SI470X=m +@@ -746,10 +748,13 @@ CONFIG_RADIO_WL128X=m + # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set + CONFIG_VIDEO_UDA1342=m + CONFIG_VIDEO_SONY_BTF_MPX=m ++CONFIG_VIDEO_ADV7180=m ++CONFIG_VIDEO_TC358743=m + CONFIG_VIDEO_TVP5150=m + CONFIG_VIDEO_TW2804=m + CONFIG_VIDEO_TW9903=m + CONFIG_VIDEO_TW9906=m ++CONFIG_VIDEO_OV5647=m + CONFIG_VIDEO_OV7640=m + CONFIG_VIDEO_MT9V011=m + CONFIG_DRM=m diff --git a/target/linux/brcm2708/patches-4.19/950-0345-staging-vc-sm-cma-Correct-DMA-configuration.patch b/target/linux/brcm2708/patches-4.19/950-0345-staging-vc-sm-cma-Correct-DMA-configuration.patch deleted file mode 100644 index f2b66d0634..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0345-staging-vc-sm-cma-Correct-DMA-configuration.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 6fab727ac8fd457541d36edf07e6615c20341372 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 29 Jan 2019 16:24:41 +0000 -Subject: [PATCH 345/703] staging: vc-sm-cma: Correct DMA configuration. - -Now that VCHIQ is setting up the DMA configuration as our -parent device, don't try to configure it during probe. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 15 +++++---------- - 1 file changed, 5 insertions(+), 10 deletions(-) - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -703,9 +703,6 @@ err_free_mem: - /* Driver loading. */ - static int bcm2835_vc_sm_cma_probe(struct platform_device *pdev) - { -- struct device *dev = &pdev->dev; -- int err; -- - pr_info("%s: Videocore shared memory driver\n", __func__); - - sm_state = kzalloc(sizeof(*sm_state), GFP_KERNEL); -@@ -714,13 +711,11 @@ static int bcm2835_vc_sm_cma_probe(struc - sm_state->pdev = pdev; - mutex_init(&sm_state->map_lock); - -- dev->coherent_dma_mask = DMA_BIT_MASK(32); -- dev->dma_mask = &dev->coherent_dma_mask; -- err = of_dma_configure(dev, NULL, true); -- if (err) { -- dev_err(dev, "Unable to setup DMA: %d\n", err); -- return err; -- } -+ pdev->dev.dma_parms = devm_kzalloc(&pdev->dev, -+ sizeof(*pdev->dev.dma_parms), -+ GFP_KERNEL); -+ /* dma_set_max_seg_size checks if dma_parms is NULL. */ -+ dma_set_max_seg_size(&pdev->dev, 0x3FFFFFFF); - - vchiq_add_connected_callback(vc_sm_connected_init); - return 0; diff --git a/target/linux/brcm2708/patches-4.19/950-0346-configs-Add-VIDEO_BCM2835-to-bcmrpi3_defconfig.patch b/target/linux/brcm2708/patches-4.19/950-0346-configs-Add-VIDEO_BCM2835-to-bcmrpi3_defconfig.patch new file mode 100644 index 0000000000..1724e36040 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0346-configs-Add-VIDEO_BCM2835-to-bcmrpi3_defconfig.patch @@ -0,0 +1,23 @@ +From bfd4f57fa06a92d61ca39d3fde743cdac35b03f9 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 4 Feb 2019 12:45:25 +0000 +Subject: [PATCH 346/725] configs: Add VIDEO_BCM2835 to bcmrpi3_defconfig + +This is now shown to work with 64 bit kernels, so add it to +the defconfig. + +Signed-off-by: Dave Stevenson +--- + arch/arm64/configs/bcmrpi3_defconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -1070,6 +1070,7 @@ CONFIG_FB_TFT_WATTEROTT=m + CONFIG_FB_FLEX=m + CONFIG_FB_TFT_FBTFT_DEVICE=m + CONFIG_SND_BCM2835=m ++CONFIG_VIDEO_BCM2835=m + CONFIG_MAILBOX=y + CONFIG_BCM2835_MBOX=y + # CONFIG_IOMMU_SUPPORT is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0346-staging-vc-sm-cma-Use-a-void-pointer-as-the-handle-w.patch b/target/linux/brcm2708/patches-4.19/950-0346-staging-vc-sm-cma-Use-a-void-pointer-as-the-handle-w.patch deleted file mode 100644 index c263663533..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0346-staging-vc-sm-cma-Use-a-void-pointer-as-the-handle-w.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 0bdf03ed6435089119a3d502f84f8943a12f65ac Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 29 Jan 2019 16:29:00 +0000 -Subject: [PATCH 346/703] staging: vc-sm-cma: Use a void* pointer as the handle - within the kernel - -The driver was using an unsigned int as the handle to the outside world, -and doing a nasty cast to the struct dmabuf when handed it back. -This breaks badly with a 64 bit kernel where the pointer doesn't fit -in an unsigned int. - -Switch to using a void* within the kernel. Reality is that it is -a struct dma_buf*, but advertising it as such to other drivers seems -to encourage the use of it as such, and I'm not sure on the implications -of that. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 10 +++++----- - drivers/staging/vc04_services/vc-sm-cma/vc_sm_knl.h | 6 +++--- - drivers/staging/vc04_services/vchiq-mmal/mmal-common.h | 2 +- - drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 2 +- - 4 files changed, 10 insertions(+), 10 deletions(-) - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -745,7 +745,7 @@ static int bcm2835_vc_sm_cma_remove(stru - } - - /* Get an internal resource handle mapped from the external one. */ --int vc_sm_cma_int_handle(int handle) -+int vc_sm_cma_int_handle(void *handle) - { - struct dma_buf *dma_buf = (struct dma_buf *)handle; - struct vc_sm_buffer *res; -@@ -762,7 +762,7 @@ int vc_sm_cma_int_handle(int handle) - EXPORT_SYMBOL_GPL(vc_sm_cma_int_handle); - - /* Free a previously allocated shared memory handle and block. */ --int vc_sm_cma_free(int handle) -+int vc_sm_cma_free(void *handle) - { - struct dma_buf *dma_buf = (struct dma_buf *)handle; - -@@ -772,7 +772,7 @@ int vc_sm_cma_free(int handle) - return -EPERM; - } - -- pr_debug("%s: handle %08x/dmabuf %p\n", __func__, handle, dma_buf); -+ pr_debug("%s: handle %p/dmabuf %p\n", __func__, handle, dma_buf); - - dma_buf_put(dma_buf); - -@@ -781,7 +781,7 @@ int vc_sm_cma_free(int handle) - EXPORT_SYMBOL_GPL(vc_sm_cma_free); - - /* Import a dmabuf to be shared with VC. */ --int vc_sm_cma_import_dmabuf(struct dma_buf *src_dmabuf, int *handle) -+int vc_sm_cma_import_dmabuf(struct dma_buf *src_dmabuf, void **handle) - { - struct dma_buf *new_dma_buf; - struct vc_sm_buffer *res; -@@ -801,7 +801,7 @@ int vc_sm_cma_import_dmabuf(struct dma_b - res = (struct vc_sm_buffer *)new_dma_buf->priv; - - /* Assign valid handle at this time.*/ -- *handle = (int)new_dma_buf; -+ *handle = new_dma_buf; - } else { - /* - * succeeded in importing the dma_buf, but then ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_knl.h -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_knl.h -@@ -17,12 +17,12 @@ - #endif - - /* Free a previously allocated or imported shared memory handle and block. */ --int vc_sm_cma_free(int handle); -+int vc_sm_cma_free(void *handle); - - /* Get an internal resource handle mapped from the external one. */ --int vc_sm_cma_int_handle(int handle); -+int vc_sm_cma_int_handle(void *handle); - - /* Import a block of memory into the GPU space. */ --int vc_sm_cma_import_dmabuf(struct dma_buf *dmabuf, int *handle); -+int vc_sm_cma_import_dmabuf(struct dma_buf *dmabuf, void **handle); - - #endif /* __VC_SM_KNL_H__INCLUDED__ */ ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h -@@ -52,7 +52,7 @@ struct mmal_buffer { - struct mmal_msg_context *msg_context; - - struct dma_buf *dma_buf;/* Exported dmabuf fd from videobuf2 */ -- int vcsm_handle; /* VCSM handle having imported the dmabuf */ -+ void *vcsm_handle; /* VCSM handle having imported the dmabuf */ - u32 vc_handle; /* VC handle to that dmabuf */ - - u32 cmd; /* MMAL command. 0=data. */ ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -1794,7 +1794,7 @@ int mmal_vchi_buffer_cleanup(struct mmal - if (buf->vcsm_handle) { - int ret; - -- pr_debug("%s: vc_sm_cma_free on handle %08X\n", __func__, -+ pr_debug("%s: vc_sm_cma_free on handle %p\n", __func__, - buf->vcsm_handle); - ret = vc_sm_cma_free(buf->vcsm_handle); - if (ret) diff --git a/target/linux/brcm2708/patches-4.19/950-0347-configs-Add-V4L2-codec-driver-to-bcmrpi3_defconfig.patch b/target/linux/brcm2708/patches-4.19/950-0347-configs-Add-V4L2-codec-driver-to-bcmrpi3_defconfig.patch new file mode 100644 index 0000000000..24e7dd54f8 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0347-configs-Add-V4L2-codec-driver-to-bcmrpi3_defconfig.patch @@ -0,0 +1,23 @@ +From b12753c64741f12e50380ac8f6d8da36766904d5 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 4 Feb 2019 13:42:51 +0000 +Subject: [PATCH 347/725] configs: Add V4L2 codec driver to bcmrpi3_defconfig + +As this is now fixed to work with 64bit kernels, add it to the +defconfig. + +Signed-off-by: Dave Stevenson +--- + arch/arm64/configs/bcmrpi3_defconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -1071,6 +1071,7 @@ CONFIG_FB_FLEX=m + CONFIG_FB_TFT_FBTFT_DEVICE=m + CONFIG_SND_BCM2835=m + CONFIG_VIDEO_BCM2835=m ++CONFIG_VIDEO_CODEC_BCM2835=m + CONFIG_MAILBOX=y + CONFIG_BCM2835_MBOX=y + # CONFIG_IOMMU_SUPPORT is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0347-staging-vc-sm-cma-Fix-up-for-64bit-builds.patch b/target/linux/brcm2708/patches-4.19/950-0347-staging-vc-sm-cma-Fix-up-for-64bit-builds.patch deleted file mode 100644 index df49149d61..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0347-staging-vc-sm-cma-Fix-up-for-64bit-builds.patch +++ /dev/null @@ -1,199 +0,0 @@ -From 857c68b05d9b99e26d1dd460f349ed33857dbf71 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 29 Jan 2019 16:32:57 +0000 -Subject: [PATCH 347/703] staging: vc-sm-cma: Fix up for 64bit builds - -There were a number of logging lines that were using -inappropriate formatting under 64bit kernels. - -The kernel_id field passed to/from the VPU was being -abused for storing the struct vc_sm_buffer *. -This breaks with 64bit kernels, so change to using an IDR. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/vc-sm-cma/vc_sm.c | 60 +++++++++++++++---- - .../vc04_services/vc-sm-cma/vc_sm_cma_vchi.c | 3 +- - 2 files changed, 48 insertions(+), 15 deletions(-) - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -75,6 +75,9 @@ struct sm_state_t { - struct miscdevice dev; - struct sm_instance *sm_handle; /* Handle for videocore service. */ - -+ spinlock_t kernelid_map_lock; /* Spinlock protecting kernelid_map */ -+ struct idr kernelid_map; -+ - struct mutex map_lock; /* Global map lock. */ - struct list_head buffer_list; /* List of buffer. */ - -@@ -97,6 +100,29 @@ static int sm_inited; - - /* ---- Private Functions ------------------------------------------------ */ - -+static int get_kernel_id(struct vc_sm_buffer *buffer) -+{ -+ int handle; -+ -+ spin_lock(&sm_state->kernelid_map_lock); -+ handle = idr_alloc(&sm_state->kernelid_map, buffer, 0, 0, GFP_KERNEL); -+ spin_unlock(&sm_state->kernelid_map_lock); -+ -+ return handle; -+} -+ -+static struct vc_sm_buffer *lookup_kernel_id(int handle) -+{ -+ return idr_find(&sm_state->kernelid_map, handle); -+} -+ -+static void free_kernel_id(int handle) -+{ -+ spin_lock(&sm_state->kernelid_map_lock); -+ idr_remove(&sm_state->kernelid_map, handle); -+ spin_unlock(&sm_state->kernelid_map_lock); -+} -+ - static int vc_sm_cma_seq_file_show(struct seq_file *s, void *v) - { - struct sm_pde_t *sm_pde; -@@ -129,8 +155,7 @@ static int vc_sm_cma_global_state_show(s - if (!sm_state) - return 0; - -- seq_printf(s, "\nVC-ServiceHandle 0x%x\n", -- (unsigned int)sm_state->sm_handle); -+ seq_printf(s, "\nVC-ServiceHandle %p\n", sm_state->sm_handle); - - /* Log all applicable mapping(s). */ - -@@ -145,7 +170,7 @@ static int vc_sm_cma_global_state_show(s - resource); - seq_printf(s, " NAME %s\n", - resource->name); -- seq_printf(s, " SIZE %d\n", -+ seq_printf(s, " SIZE %zu\n", - resource->size); - seq_printf(s, " DMABUF %p\n", - resource->dma_buf); -@@ -181,7 +206,7 @@ static void vc_sm_add_resource(struct vc - list_add(&buffer->global_buffer_list, &sm_state->buffer_list); - mutex_unlock(&sm_state->map_lock); - -- pr_debug("[%s]: added buffer %p (name %s, size %d)\n", -+ pr_debug("[%s]: added buffer %p (name %s, size %zu)\n", - __func__, buffer, buffer->name, buffer->size); - } - -@@ -194,7 +219,7 @@ static void vc_sm_release_resource(struc - mutex_lock(&sm_state->map_lock); - mutex_lock(&buffer->lock); - -- pr_debug("[%s]: buffer %p (name %s, size %d)\n", -+ pr_debug("[%s]: buffer %p (name %s, size %zu)\n", - __func__, buffer, buffer->name, buffer->size); - - if (buffer->vc_handle && buffer->vpu_state == VPU_MAPPED) { -@@ -443,6 +468,7 @@ vc_sm_cma_import_dmabuf_internal(struct - struct vc_sm_import_result result = { }; - struct dma_buf_attachment *attach = NULL; - struct sg_table *sgt = NULL; -+ dma_addr_t dma_addr; - int ret = 0; - int status; - -@@ -478,21 +504,22 @@ vc_sm_cma_import_dmabuf_internal(struct - } - - import.type = VC_SM_ALLOC_NON_CACHED; -- import.addr = (uint32_t)sg_dma_address(sgt->sgl); -+ dma_addr = sg_dma_address(sgt->sgl); -+ import.addr = (uint32_t)dma_addr; - if ((import.addr & 0xC0000000) != 0xC0000000) { -- pr_err("%s: Expecting an uncached alias for dma_addr %08x\n", -- __func__, import.addr); -+ pr_err("%s: Expecting an uncached alias for dma_addr %pad\n", -+ __func__, &dma_addr); - import.addr |= 0xC0000000; - } - import.size = sg_dma_len(sgt->sgl); - import.allocator = current->tgid; -- import.kernel_id = (uint32_t)buffer; //FIXME: 64 bit support needed. -+ import.kernel_id = get_kernel_id(buffer); - - memcpy(import.name, VC_SM_RESOURCE_NAME_DEFAULT, - sizeof(VC_SM_RESOURCE_NAME_DEFAULT)); - -- pr_debug("[%s]: attempt to import \"%s\" data - type %u, addr %p, size %u\n", -- __func__, import.name, import.type, (void *)import.addr, -+ pr_debug("[%s]: attempt to import \"%s\" data - type %u, addr %pad, size %u\n", -+ __func__, import.name, import.type, &dma_addr, - import.size); - - /* Allocate the videocore buffer. */ -@@ -527,7 +554,7 @@ vc_sm_cma_import_dmabuf_internal(struct - - buffer->attach = attach; - buffer->sgt = sgt; -- buffer->dma_addr = sg_dma_address(sgt->sgl); -+ buffer->dma_addr = dma_addr; - buffer->in_use = 1; - - /* -@@ -559,6 +586,7 @@ error: - vc_sm_cma_vchi_free(sm_state->sm_handle, &free, - &sm_state->int_trans_id); - } -+ free_kernel_id(import.kernel_id); - kfree(buffer); - if (sgt) - dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); -@@ -586,7 +614,7 @@ vc_sm_vpu_event(struct sm_instance *inst - { - struct vc_sm_released *release = (struct vc_sm_released *)reply; - struct vc_sm_buffer *buffer = -- (struct vc_sm_buffer *)release->kernel_id; -+ lookup_kernel_id(release->kernel_id); - - /* - * FIXME: Need to check buffer is still valid and allocated -@@ -599,6 +627,7 @@ vc_sm_vpu_event(struct sm_instance *inst - buffer->vc_handle = 0; - buffer->vpu_state = VPU_NOT_MAPPED; - mutex_unlock(&buffer->lock); -+ free_kernel_id(release->kernel_id); - - vc_sm_release_resource(buffer, 0); - } -@@ -711,6 +740,9 @@ static int bcm2835_vc_sm_cma_probe(struc - sm_state->pdev = pdev; - mutex_init(&sm_state->map_lock); - -+ spin_lock_init(&sm_state->kernelid_map_lock); -+ idr_init_base(&sm_state->kernelid_map, 1); -+ - pdev->dev.dma_parms = devm_kzalloc(&pdev->dev, - sizeof(*pdev->dev.dma_parms), - GFP_KERNEL); -@@ -735,6 +767,8 @@ static int bcm2835_vc_sm_cma_remove(stru - /* Stop the videocore shared memory service. */ - vc_sm_cma_vchi_stop(&sm_state->sm_handle); - -+ idr_destroy(&sm_state->kernelid_map); -+ - /* Free the memory for the state structure. */ - mutex_destroy(&sm_state->map_lock); - kfree(sm_state); ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c -@@ -356,8 +356,7 @@ struct sm_instance *vc_sm_cma_vchi_init( - set_user_nice(instance->io_thread, -10); - wake_up_process(instance->io_thread); - -- pr_debug("%s: success - instance 0x%x", __func__, -- (unsigned int)instance); -+ pr_debug("%s: success - instance %p", __func__, instance); - return instance; - - err_close_services: diff --git a/target/linux/brcm2708/patches-4.19/950-0348-config-Add-IPVLAN-module-to-bcmrpi3_defconfig.patch b/target/linux/brcm2708/patches-4.19/950-0348-config-Add-IPVLAN-module-to-bcmrpi3_defconfig.patch new file mode 100644 index 0000000000..2665db3f80 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0348-config-Add-IPVLAN-module-to-bcmrpi3_defconfig.patch @@ -0,0 +1,22 @@ +From 3a9bd6dd0db77f25d3bcbc2fd92ccd96cda854a8 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 5 Feb 2019 12:31:23 +0000 +Subject: [PATCH 348/725] config: Add IPVLAN module to bcmrpi3_defconfig + +It's built for the 32bit kernels, but not for the 64bit ones. + +Signed-off-by: Dave Stevenson +--- + arch/arm64/configs/bcmrpi3_defconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -430,6 +430,7 @@ CONFIG_BONDING=m + CONFIG_DUMMY=m + CONFIG_IFB=m + CONFIG_MACVLAN=m ++CONFIG_IPVLAN=m + CONFIG_VXLAN=m + CONFIG_NETCONSOLE=m + CONFIG_TUN=m diff --git a/target/linux/brcm2708/patches-4.19/950-0348-configs-Add-Unicam-and-subdevices-to-bcmrpi3_defconf.patch b/target/linux/brcm2708/patches-4.19/950-0348-configs-Add-Unicam-and-subdevices-to-bcmrpi3_defconf.patch deleted file mode 100644 index 08e51c0b91..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0348-configs-Add-Unicam-and-subdevices-to-bcmrpi3_defconf.patch +++ /dev/null @@ -1,47 +0,0 @@ -From a707e82004fa7e421a531690d3b072e53fa05819 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 4 Feb 2019 12:35:06 +0000 -Subject: [PATCH 348/703] configs: Add Unicam and subdevices to - bcmrpi3_defconfig - -The bcm2835-unicam, tc358743, adv7180 (for adv7282m) and ov5647 -have been tested on a 64bit kernel and shown to work. -Add them to the config. - -Signed-off-by: Dave Stevenson ---- - arch/arm64/configs/bcmrpi3_defconfig | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -645,6 +645,7 @@ CONFIG_MEDIA_ANALOG_TV_SUPPORT=y - CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y - CONFIG_MEDIA_RADIO_SUPPORT=y - CONFIG_MEDIA_CONTROLLER=y -+CONFIG_VIDEO_V4L2_SUBDEV_API=y - CONFIG_MEDIA_USB_SUPPORT=y - CONFIG_USB_VIDEO_CLASS=m - CONFIG_USB_M5602=m -@@ -727,6 +728,7 @@ CONFIG_VIDEO_EM28XX_V4L2=m - CONFIG_VIDEO_EM28XX_ALSA=m - CONFIG_VIDEO_EM28XX_DVB=m - CONFIG_V4L_PLATFORM_DRIVERS=y -+CONFIG_VIDEO_BCM2835_UNICAM=m - CONFIG_RADIO_SI470X=m - CONFIG_USB_SI470X=m - CONFIG_I2C_SI470X=m -@@ -746,10 +748,13 @@ CONFIG_RADIO_WL128X=m - # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set - CONFIG_VIDEO_UDA1342=m - CONFIG_VIDEO_SONY_BTF_MPX=m -+CONFIG_VIDEO_ADV7180=m -+CONFIG_VIDEO_TC358743=m - CONFIG_VIDEO_TVP5150=m - CONFIG_VIDEO_TW2804=m - CONFIG_VIDEO_TW9903=m - CONFIG_VIDEO_TW9906=m -+CONFIG_VIDEO_OV5647=m - CONFIG_VIDEO_OV7640=m - CONFIG_VIDEO_MT9V011=m - CONFIG_DRM=m diff --git a/target/linux/brcm2708/patches-4.19/950-0349-configs-Add-VIDEO_BCM2835-to-bcmrpi3_defconfig.patch b/target/linux/brcm2708/patches-4.19/950-0349-configs-Add-VIDEO_BCM2835-to-bcmrpi3_defconfig.patch deleted file mode 100644 index d424bfaa3f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0349-configs-Add-VIDEO_BCM2835-to-bcmrpi3_defconfig.patch +++ /dev/null @@ -1,23 +0,0 @@ -From a44812330b02d78a28b17f1e364e73d827f4a872 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 4 Feb 2019 12:45:25 +0000 -Subject: [PATCH 349/703] configs: Add VIDEO_BCM2835 to bcmrpi3_defconfig - -This is now shown to work with 64 bit kernels, so add it to -the defconfig. - -Signed-off-by: Dave Stevenson ---- - arch/arm64/configs/bcmrpi3_defconfig | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -1070,6 +1070,7 @@ CONFIG_FB_TFT_WATTEROTT=m - CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_SND_BCM2835=m -+CONFIG_VIDEO_BCM2835=m - CONFIG_MAILBOX=y - CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0349-configs-Enable-the-AD193x-codecs.patch b/target/linux/brcm2708/patches-4.19/950-0349-configs-Enable-the-AD193x-codecs.patch new file mode 100644 index 0000000000..832fc24b62 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0349-configs-Enable-the-AD193x-codecs.patch @@ -0,0 +1,64 @@ +From b3f3a83a0db08c6f4f68645f466cc3c64331b982 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 7 Feb 2019 18:16:25 +0000 +Subject: [PATCH 349/725] configs: Enable the AD193x codecs + +See: https://github.com/raspberrypi/linux/issues/2850 + +Signed-off-by: Phil Elwell +--- + arch/arm/configs/bcm2709_defconfig | 2 ++ + arch/arm/configs/bcmrpi_defconfig | 2 ++ + arch/arm64/configs/bcmrpi3_defconfig | 2 ++ + sound/soc/codecs/Kconfig | 4 ++-- + 4 files changed, 8 insertions(+), 2 deletions(-) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -930,6 +930,8 @@ CONFIG_SND_BCM2708_SOC_ALLO_DIGIONE=m + CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC=m + CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m + CONFIG_SND_PISOUND=m ++CONFIG_SND_SOC_AD193X_SPI=m ++CONFIG_SND_SOC_AD193X_I2C=m + CONFIG_SND_SOC_ADAU1701=m + CONFIG_SND_SOC_ADAU7002=m + CONFIG_SND_SOC_AK4554=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -923,6 +923,8 @@ CONFIG_SND_BCM2708_SOC_ALLO_DIGIONE=m + CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC=m + CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m + CONFIG_SND_PISOUND=m ++CONFIG_SND_SOC_AD193X_SPI=m ++CONFIG_SND_SOC_AD193X_I2C=m + CONFIG_SND_SOC_ADAU1701=m + CONFIG_SND_SOC_ADAU7002=m + CONFIG_SND_SOC_AK4554=m +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -811,6 +811,8 @@ CONFIG_SND_DIGIDAC1_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m + CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m + CONFIG_SND_PISOUND=m ++CONFIG_SND_SOC_AD193X_SPI=m ++CONFIG_SND_SOC_AD193X_I2C=m + CONFIG_SND_SOC_ADAU1701=m + CONFIG_SND_SOC_AK4554=m + CONFIG_SND_SOC_CS4271_I2C=m +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -295,11 +295,11 @@ config SND_SOC_AD193X + tristate + + config SND_SOC_AD193X_SPI +- tristate ++ tristate "Analog Devices AU193X CODEC - SPI" + select SND_SOC_AD193X + + config SND_SOC_AD193X_I2C +- tristate ++ tristate "Analog Devices AU193X CODEC - I2C" + select SND_SOC_AD193X + + config SND_SOC_AD1980 diff --git a/target/linux/brcm2708/patches-4.19/950-0350-configs-Add-V4L2-codec-driver-to-bcmrpi3_defconfig.patch b/target/linux/brcm2708/patches-4.19/950-0350-configs-Add-V4L2-codec-driver-to-bcmrpi3_defconfig.patch deleted file mode 100644 index ef8ea1d18b..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0350-configs-Add-V4L2-codec-driver-to-bcmrpi3_defconfig.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 426d55354b0d23a514ee80596f22d1ea2a58b811 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 4 Feb 2019 13:42:51 +0000 -Subject: [PATCH 350/703] configs: Add V4L2 codec driver to bcmrpi3_defconfig - -As this is now fixed to work with 64bit kernels, add it to the -defconfig. - -Signed-off-by: Dave Stevenson ---- - arch/arm64/configs/bcmrpi3_defconfig | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -1071,6 +1071,7 @@ CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_SND_BCM2835=m - CONFIG_VIDEO_BCM2835=m -+CONFIG_VIDEO_CODEC_BCM2835=m - CONFIG_MAILBOX=y - CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0350-overlays-balenaFin-v1.1.0-carrier-board-update.patch b/target/linux/brcm2708/patches-4.19/950-0350-overlays-balenaFin-v1.1.0-carrier-board-update.patch new file mode 100644 index 0000000000..ea3f8c622f --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0350-overlays-balenaFin-v1.1.0-carrier-board-update.patch @@ -0,0 +1,109 @@ +From 0bafdbbfcc0a583808997ffff5110a10b9d8b49e Mon Sep 17 00:00:00 2001 +From: Zahari Petkov +Date: Fri, 8 Feb 2019 13:03:38 +0200 +Subject: [PATCH 350/725] overlays: balenaFin v1.1.0 carrier board update + +A backward compatible update for the balenaFin carrier board for the +Raspberry Pi Compute Module 3/3+ Lite. + +The updated overlay includes: + * support for the newly introduced RGB LEDs + * i2c-gpio and SDIO improvements + * DT based Marvell 88W8887 configuration + +Signed-off-by: Zahari Petkov +--- + arch/arm/boot/dts/overlays/README | 2 +- + .../boot/dts/overlays/balena-fin-overlay.dts | 46 ++++++++++++++++++- + 2 files changed, 45 insertions(+), 3 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -472,7 +472,7 @@ Params: swap_lr Reverse + + Name: balena-fin + Info: Overlay that enables WiFi, Bluetooth and the GPIO expander on the +- Balena Fin board. ++ balenaFin carrier board for the Raspberry Pi Compute Module 3/3+ Lite. + Load: dtoverlay=balena-fin + Params: + +--- a/arch/arm/boot/dts/overlays/balena-fin-overlay.dts ++++ b/arch/arm/boot/dts/overlays/balena-fin-overlay.dts +@@ -11,6 +11,7 @@ + pinctrl-0 = <&sdio_pins>; + bus-width = <4>; + brcm,overclock-50 = <35>; ++ non-removable; + status = "okay"; + }; + }; +@@ -34,7 +35,8 @@ + fragment@2 { + target-path = "/"; + __overlay__ { +- // We should investigate how to switch to mmc-pwrseq-sd8787 ++ // We should switch to mmc-pwrseq-sd8787 after making it ++ // compatible with sd8887 + // Currently that module requires two GPIOs to function since it + // targets a slightly different chip + power_ctrl: power_ctrl { +@@ -46,10 +48,21 @@ + i2c_soft: i2c@0 { + compatible = "i2c-gpio"; + gpios = <&gpio 43 0 /* sda */ &gpio 42 0 /* scl */>; +- i2c-gpio,delay-us = <2>; /* ~100 kHz */ ++ i2c-gpio,delay-us = <5>; ++ i2c-gpio,scl-open-drain; ++ i2c-gpio,sda-open-drain; + #address-cells = <1>; + #size-cells = <0>; + }; ++ ++ sd8xxx-wlan { ++ drvdbg = <0x6>; ++ drv_mode = <0x1>; ++ cfg80211_wext = <0xf>; ++ sta_name = "wlan"; ++ wfd_name = "p2p"; ++ cal_data_cfg = "none"; ++ }; + }; + }; + +@@ -74,6 +87,35 @@ + reg = <0x68>; + status = "okay"; + }; ++ ++ // RGB LEDs (>= v1.1.0) ++ pca9633: pca9633@62 { ++ compatible = "nxp,pca9633"; ++ reg = <0x62>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ red@0 { ++ label = "red"; ++ reg = <0>; ++ linux,default-trigger = "none"; ++ }; ++ green@1 { ++ label = "green"; ++ reg = <1>; ++ linux,default-trigger = "none"; ++ }; ++ blue@2 { ++ label = "blue"; ++ reg = <2>; ++ linux,default-trigger = "none"; ++ }; ++ unused@3 { ++ label = "unused"; ++ reg = <3>; ++ linux,default-trigger = "none"; ++ }; ++ }; + }; + }; + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0351-config-Add-IPVLAN-module-to-bcmrpi3_defconfig.patch b/target/linux/brcm2708/patches-4.19/950-0351-config-Add-IPVLAN-module-to-bcmrpi3_defconfig.patch deleted file mode 100644 index 5b504167c0..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0351-config-Add-IPVLAN-module-to-bcmrpi3_defconfig.patch +++ /dev/null @@ -1,22 +0,0 @@ -From ba6462e05310a26c30e22aab737db4eb5ae938a8 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 5 Feb 2019 12:31:23 +0000 -Subject: [PATCH 351/703] config: Add IPVLAN module to bcmrpi3_defconfig - -It's built for the 32bit kernels, but not for the 64bit ones. - -Signed-off-by: Dave Stevenson ---- - arch/arm64/configs/bcmrpi3_defconfig | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -430,6 +430,7 @@ CONFIG_BONDING=m - CONFIG_DUMMY=m - CONFIG_IFB=m - CONFIG_MACVLAN=m -+CONFIG_IPVLAN=m - CONFIG_VXLAN=m - CONFIG_NETCONSOLE=m - CONFIG_TUN=m diff --git a/target/linux/brcm2708/patches-4.19/950-0351-configs-Add-CONFIG_LEDS_PCA963X-m.patch b/target/linux/brcm2708/patches-4.19/950-0351-configs-Add-CONFIG_LEDS_PCA963X-m.patch new file mode 100644 index 0000000000..d6a7d8ea99 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0351-configs-Add-CONFIG_LEDS_PCA963X-m.patch @@ -0,0 +1,47 @@ +From 6f7b49f8483bfbda41b7a33037729df18f2b84c7 Mon Sep 17 00:00:00 2001 +From: Zahari Petkov +Date: Fri, 8 Feb 2019 13:33:47 +0200 +Subject: [PATCH 351/725] configs: Add CONFIG_LEDS_PCA963X=m + +Enable support for PCA963x I2C chip. + +Needed for the balenaFin v1.1.0 carrier board for the +Raspberry Pi Compute Module 3/3+ Lite. + +Signed-off-by: Zahari Petkov +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + arch/arm64/configs/bcmrpi3_defconfig | 1 + + 3 files changed, 3 insertions(+) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -1124,6 +1124,7 @@ CONFIG_MMC_SDHCI_PLTFM=y + CONFIG_MMC_SPI=m + CONFIG_LEDS_CLASS=y + CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_PCA963X=m + CONFIG_LEDS_TRIGGER_TIMER=y + CONFIG_LEDS_TRIGGER_ONESHOT=y + CONFIG_LEDS_TRIGGER_HEARTBEAT=y +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -1117,6 +1117,7 @@ CONFIG_MMC_SDHCI_PLTFM=y + CONFIG_MMC_SPI=m + CONFIG_LEDS_CLASS=y + CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_PCA963X=m + CONFIG_LEDS_TRIGGER_TIMER=y + CONFIG_LEDS_TRIGGER_ONESHOT=y + CONFIG_LEDS_TRIGGER_HEARTBEAT=y +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -984,6 +984,7 @@ CONFIG_MMC_SDHCI_IPROC=m + CONFIG_MMC_SPI=m + CONFIG_LEDS_CLASS=y + CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_PCA963X=m + CONFIG_LEDS_TRIGGER_TIMER=y + CONFIG_LEDS_TRIGGER_ONESHOT=y + CONFIG_LEDS_TRIGGER_HEARTBEAT=y diff --git a/target/linux/brcm2708/patches-4.19/950-0352-Revert-brcmfmac-Mute-expected-startup-errors.patch b/target/linux/brcm2708/patches-4.19/950-0352-Revert-brcmfmac-Mute-expected-startup-errors.patch new file mode 100644 index 0000000000..18d0a22906 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0352-Revert-brcmfmac-Mute-expected-startup-errors.patch @@ -0,0 +1,26 @@ +From 0f8f6eb08cb335806221680471fcaa9afe7ddd02 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 18 Feb 2019 15:43:30 +0000 +Subject: [PATCH 352/725] Revert "brcmfmac: Mute expected startup 'errors'" + +This reverts commit 34eba9138ccf8d84552ab9dae37d8f348640e663. + +Upstream patch 26e537884a ("brcmfmac: Do not complain about country code "00") +fixes the same issue, so drop this downstream patch. + +Signed-off-by: Phil Elwell +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6844,8 +6844,6 @@ static void brcmf_cfg80211_reg_notifier( + /* ignore non-ISO3166 country codes */ + for (i = 0; i < 2; i++) + if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') { +- if (req->alpha2[0] == '0' && req->alpha2[1] == '0') +- return; + brcmf_err("not an ISO3166 code (0x%02x 0x%02x)\n", + req->alpha2[0], req->alpha2[1]); + return; diff --git a/target/linux/brcm2708/patches-4.19/950-0352-configs-Enable-the-AD193x-codecs.patch b/target/linux/brcm2708/patches-4.19/950-0352-configs-Enable-the-AD193x-codecs.patch deleted file mode 100644 index b755ae0513..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0352-configs-Enable-the-AD193x-codecs.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 09e5438e80f821df067895228f0a78d28da17846 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 7 Feb 2019 18:16:25 +0000 -Subject: [PATCH 352/703] configs: Enable the AD193x codecs - -See: https://github.com/raspberrypi/linux/issues/2850 - -Signed-off-by: Phil Elwell ---- - arch/arm/configs/bcm2709_defconfig | 2 ++ - arch/arm/configs/bcmrpi_defconfig | 2 ++ - arch/arm64/configs/bcmrpi3_defconfig | 2 ++ - sound/soc/codecs/Kconfig | 4 ++-- - 4 files changed, 8 insertions(+), 2 deletions(-) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -930,6 +930,8 @@ CONFIG_SND_BCM2708_SOC_ALLO_DIGIONE=m - CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC=m - CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m - CONFIG_SND_PISOUND=m -+CONFIG_SND_SOC_AD193X_SPI=m -+CONFIG_SND_SOC_AD193X_I2C=m - CONFIG_SND_SOC_ADAU1701=m - CONFIG_SND_SOC_ADAU7002=m - CONFIG_SND_SOC_AK4554=m ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -923,6 +923,8 @@ CONFIG_SND_BCM2708_SOC_ALLO_DIGIONE=m - CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC=m - CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m - CONFIG_SND_PISOUND=m -+CONFIG_SND_SOC_AD193X_SPI=m -+CONFIG_SND_SOC_AD193X_I2C=m - CONFIG_SND_SOC_ADAU1701=m - CONFIG_SND_SOC_ADAU7002=m - CONFIG_SND_SOC_AK4554=m ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -811,6 +811,8 @@ CONFIG_SND_DIGIDAC1_SOUNDCARD=m - CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m - CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m - CONFIG_SND_PISOUND=m -+CONFIG_SND_SOC_AD193X_SPI=m -+CONFIG_SND_SOC_AD193X_I2C=m - CONFIG_SND_SOC_ADAU1701=m - CONFIG_SND_SOC_AK4554=m - CONFIG_SND_SOC_CS4271_I2C=m ---- a/sound/soc/codecs/Kconfig -+++ b/sound/soc/codecs/Kconfig -@@ -295,11 +295,11 @@ config SND_SOC_AD193X - tristate - - config SND_SOC_AD193X_SPI -- tristate -+ tristate "Analog Devices AU193X CODEC - SPI" - select SND_SOC_AD193X - - config SND_SOC_AD193X_I2C -- tristate -+ tristate "Analog Devices AU193X CODEC - I2C" - select SND_SOC_AD193X - - config SND_SOC_AD1980 diff --git a/target/linux/brcm2708/patches-4.19/950-0353-gpu-vc4-fkms-Update-driver-to-not-use-plane-crtc.patch b/target/linux/brcm2708/patches-4.19/950-0353-gpu-vc4-fkms-Update-driver-to-not-use-plane-crtc.patch new file mode 100644 index 0000000000..37bf3dee27 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0353-gpu-vc4-fkms-Update-driver-to-not-use-plane-crtc.patch @@ -0,0 +1,36 @@ +From fc900e617330d4d1763c517cec2d46c6ea59f29d Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 19 Feb 2019 15:06:31 +0000 +Subject: [PATCH 353/725] gpu:vc4-fkms: Update driver to not use plane->crtc. + +Following on from +commit 2f958af7fc248 ("drm/vc4: Stop updating plane->fb/crtc") +do the same in the firmwarekms driver and look at plane_state->crtc +instead. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -193,8 +193,8 @@ static void vc4_cursor_plane_atomic_upda + struct drm_plane_state *old_state) + { + struct vc4_dev *vc4 = to_vc4_dev(plane->dev); +- struct vc4_crtc *vc4_crtc = to_vc4_crtc(plane->crtc); + struct drm_plane_state *state = plane->state; ++ struct vc4_crtc *vc4_crtc = to_vc4_crtc(state->crtc); + struct drm_framebuffer *fb = state->fb; + struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); + dma_addr_t addr = bo->paddr + fb->offsets[0]; +@@ -682,8 +682,6 @@ static int vc4_fkms_bind(struct device * + drm_crtc_init_with_planes(drm, crtc, primary_plane, cursor_plane, + &vc4_crtc_funcs, NULL); + drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs); +- primary_plane->crtc = crtc; +- cursor_plane->crtc = crtc; + + vc4_encoder = devm_kzalloc(dev, sizeof(*vc4_encoder), GFP_KERNEL); + if (!vc4_encoder) diff --git a/target/linux/brcm2708/patches-4.19/950-0353-overlays-balenaFin-v1.1.0-carrier-board-update.patch b/target/linux/brcm2708/patches-4.19/950-0353-overlays-balenaFin-v1.1.0-carrier-board-update.patch deleted file mode 100644 index a8ab145d78..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0353-overlays-balenaFin-v1.1.0-carrier-board-update.patch +++ /dev/null @@ -1,109 +0,0 @@ -From d9e484de16eef5f3daa61a8df462ff35ebe1aedc Mon Sep 17 00:00:00 2001 -From: Zahari Petkov -Date: Fri, 8 Feb 2019 13:03:38 +0200 -Subject: [PATCH 353/703] overlays: balenaFin v1.1.0 carrier board update - -A backward compatible update for the balenaFin carrier board for the -Raspberry Pi Compute Module 3/3+ Lite. - -The updated overlay includes: - * support for the newly introduced RGB LEDs - * i2c-gpio and SDIO improvements - * DT based Marvell 88W8887 configuration - -Signed-off-by: Zahari Petkov ---- - arch/arm/boot/dts/overlays/README | 2 +- - .../boot/dts/overlays/balena-fin-overlay.dts | 46 ++++++++++++++++++- - 2 files changed, 45 insertions(+), 3 deletions(-) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -472,7 +472,7 @@ Params: swap_lr Reverse - - Name: balena-fin - Info: Overlay that enables WiFi, Bluetooth and the GPIO expander on the -- Balena Fin board. -+ balenaFin carrier board for the Raspberry Pi Compute Module 3/3+ Lite. - Load: dtoverlay=balena-fin - Params: - ---- a/arch/arm/boot/dts/overlays/balena-fin-overlay.dts -+++ b/arch/arm/boot/dts/overlays/balena-fin-overlay.dts -@@ -11,6 +11,7 @@ - pinctrl-0 = <&sdio_pins>; - bus-width = <4>; - brcm,overclock-50 = <35>; -+ non-removable; - status = "okay"; - }; - }; -@@ -34,7 +35,8 @@ - fragment@2 { - target-path = "/"; - __overlay__ { -- // We should investigate how to switch to mmc-pwrseq-sd8787 -+ // We should switch to mmc-pwrseq-sd8787 after making it -+ // compatible with sd8887 - // Currently that module requires two GPIOs to function since it - // targets a slightly different chip - power_ctrl: power_ctrl { -@@ -46,10 +48,21 @@ - i2c_soft: i2c@0 { - compatible = "i2c-gpio"; - gpios = <&gpio 43 0 /* sda */ &gpio 42 0 /* scl */>; -- i2c-gpio,delay-us = <2>; /* ~100 kHz */ -+ i2c-gpio,delay-us = <5>; -+ i2c-gpio,scl-open-drain; -+ i2c-gpio,sda-open-drain; - #address-cells = <1>; - #size-cells = <0>; - }; -+ -+ sd8xxx-wlan { -+ drvdbg = <0x6>; -+ drv_mode = <0x1>; -+ cfg80211_wext = <0xf>; -+ sta_name = "wlan"; -+ wfd_name = "p2p"; -+ cal_data_cfg = "none"; -+ }; - }; - }; - -@@ -74,6 +87,35 @@ - reg = <0x68>; - status = "okay"; - }; -+ -+ // RGB LEDs (>= v1.1.0) -+ pca9633: pca9633@62 { -+ compatible = "nxp,pca9633"; -+ reg = <0x62>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ red@0 { -+ label = "red"; -+ reg = <0>; -+ linux,default-trigger = "none"; -+ }; -+ green@1 { -+ label = "green"; -+ reg = <1>; -+ linux,default-trigger = "none"; -+ }; -+ blue@2 { -+ label = "blue"; -+ reg = <2>; -+ linux,default-trigger = "none"; -+ }; -+ unused@3 { -+ label = "unused"; -+ reg = <3>; -+ linux,default-trigger = "none"; -+ }; -+ }; - }; - }; - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0354-configs-Add-CONFIG_LEDS_PCA963X-m.patch b/target/linux/brcm2708/patches-4.19/950-0354-configs-Add-CONFIG_LEDS_PCA963X-m.patch deleted file mode 100644 index 5e8eb9733e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0354-configs-Add-CONFIG_LEDS_PCA963X-m.patch +++ /dev/null @@ -1,47 +0,0 @@ -From dbf219eac8302d979a6602b7f2f48ca58a0225e7 Mon Sep 17 00:00:00 2001 -From: Zahari Petkov -Date: Fri, 8 Feb 2019 13:33:47 +0200 -Subject: [PATCH 354/703] configs: Add CONFIG_LEDS_PCA963X=m - -Enable support for PCA963x I2C chip. - -Needed for the balenaFin v1.1.0 carrier board for the -Raspberry Pi Compute Module 3/3+ Lite. - -Signed-off-by: Zahari Petkov ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - arch/arm64/configs/bcmrpi3_defconfig | 1 + - 3 files changed, 3 insertions(+) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1124,6 +1124,7 @@ CONFIG_MMC_SDHCI_PLTFM=y - CONFIG_MMC_SPI=m - CONFIG_LEDS_CLASS=y - CONFIG_LEDS_GPIO=y -+CONFIG_LEDS_PCA963X=m - CONFIG_LEDS_TRIGGER_TIMER=y - CONFIG_LEDS_TRIGGER_ONESHOT=y - CONFIG_LEDS_TRIGGER_HEARTBEAT=y ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1117,6 +1117,7 @@ CONFIG_MMC_SDHCI_PLTFM=y - CONFIG_MMC_SPI=m - CONFIG_LEDS_CLASS=y - CONFIG_LEDS_GPIO=y -+CONFIG_LEDS_PCA963X=m - CONFIG_LEDS_TRIGGER_TIMER=y - CONFIG_LEDS_TRIGGER_ONESHOT=y - CONFIG_LEDS_TRIGGER_HEARTBEAT=y ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -984,6 +984,7 @@ CONFIG_MMC_SDHCI_IPROC=m - CONFIG_MMC_SPI=m - CONFIG_LEDS_CLASS=y - CONFIG_LEDS_GPIO=y -+CONFIG_LEDS_PCA963X=m - CONFIG_LEDS_TRIGGER_TIMER=y - CONFIG_LEDS_TRIGGER_ONESHOT=y - CONFIG_LEDS_TRIGGER_HEARTBEAT=y diff --git a/target/linux/brcm2708/patches-4.19/950-0354-drm-vc4-Programming-the-CTM-is-conditional-on-runnin.patch b/target/linux/brcm2708/patches-4.19/950-0354-drm-vc4-Programming-the-CTM-is-conditional-on-runnin.patch new file mode 100644 index 0000000000..20e77b95b2 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0354-drm-vc4-Programming-the-CTM-is-conditional-on-runnin.patch @@ -0,0 +1,26 @@ +From 85081cca82099c3fc27c3eaa9342928ca99e2ede Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 19 Feb 2019 15:18:25 +0000 +Subject: [PATCH 354/725] drm: vc4: Programming the CTM is conditional on + running full KMS + +vc4_ctm_commit writes to HVS registers, so this is only applicable +when in full KMS mode, not in firmware KMS mode. Add this conditional. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_kms.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/vc4/vc4_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_kms.c +@@ -147,7 +147,8 @@ vc4_atomic_complete_commit(struct drm_at + + drm_atomic_helper_commit_modeset_disables(dev, state); + +- vc4_ctm_commit(vc4, state); ++ if (!vc4->firmware_kms) ++ vc4_ctm_commit(vc4, state); + + drm_atomic_helper_commit_planes(dev, state, 0); + diff --git a/target/linux/brcm2708/patches-4.19/950-0355-Revert-brcmfmac-Mute-expected-startup-errors.patch b/target/linux/brcm2708/patches-4.19/950-0355-Revert-brcmfmac-Mute-expected-startup-errors.patch deleted file mode 100644 index eab48b688c..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0355-Revert-brcmfmac-Mute-expected-startup-errors.patch +++ /dev/null @@ -1,26 +0,0 @@ -From a0ee8937092bd619a1b99cc5e39dc579be5fdd9a Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 18 Feb 2019 15:43:30 +0000 -Subject: [PATCH 355/703] Revert "brcmfmac: Mute expected startup 'errors'" - -This reverts commit 34eba9138ccf8d84552ab9dae37d8f348640e663. - -Upstream patch 26e537884a ("brcmfmac: Do not complain about country code "00") -fixes the same issue, so drop this downstream patch. - -Signed-off-by: Phil Elwell ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -6844,8 +6844,6 @@ static void brcmf_cfg80211_reg_notifier( - /* ignore non-ISO3166 country codes */ - for (i = 0; i < 2; i++) - if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') { -- if (req->alpha2[0] == '0' && req->alpha2[1] == '0') -- return; - brcmf_err("not an ISO3166 code (0x%02x 0x%02x)\n", - req->alpha2[0], req->alpha2[1]); - return; diff --git a/target/linux/brcm2708/patches-4.19/950-0355-staging-mmal_vchiq-Add-in-the-Bayer-encoding-formats.patch b/target/linux/brcm2708/patches-4.19/950-0355-staging-mmal_vchiq-Add-in-the-Bayer-encoding-formats.patch new file mode 100644 index 0000000000..3e03502086 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0355-staging-mmal_vchiq-Add-in-the-Bayer-encoding-formats.patch @@ -0,0 +1,51 @@ +From 52c981d9c8330fe6c34d436083bee9ecc9d5c80c Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 13 Feb 2019 12:33:29 +0000 +Subject: [PATCH 355/725] staging: mmal_vchiq: Add in the Bayer encoding + formats + +The list of formats was copied before Bayer support was added. +The ISP supports Bayer and is being supported by the bcm2835_codec +driver, so add in the encodings for them. + +Signed-off-by: Dave Stevenson +--- + .../vc04_services/vchiq-mmal/mmal-encodings.h | 27 +++++++++++++++++++ + 1 file changed, 27 insertions(+) + +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h +@@ -69,6 +69,33 @@ + */ + #define MMAL_ENCODING_OPAQUE MMAL_FOURCC('O', 'P', 'Q', 'V') + ++/* Bayer formats ++ * FourCC values copied from V4L2 where defined. ++ */ ++/* 8 bit per pixel Bayer formats. */ ++#define MMAL_ENCODING_BAYER_SBGGR8 MMAL_FOURCC('B', 'A', '8', '1') ++#define MMAL_ENCODING_BAYER_SGBRG8 MMAL_FOURCC('G', 'B', 'R', 'G') ++#define MMAL_ENCODING_BAYER_SGRBG8 MMAL_FOURCC('G', 'R', 'B', 'G') ++#define MMAL_ENCODING_BAYER_SRGGB8 MMAL_FOURCC('R', 'G', 'G', 'B') ++ ++/* 10 bit per pixel packed Bayer formats. */ ++#define MMAL_ENCODING_BAYER_SBGGR10P MMAL_FOURCC('p', 'B', 'A', 'A') ++#define MMAL_ENCODING_BAYER_SGRBG10P MMAL_FOURCC('p', 'g', 'A', 'A') ++#define MMAL_ENCODING_BAYER_SGBRG10P MMAL_FOURCC('p', 'G', 'A', 'A') ++#define MMAL_ENCODING_BAYER_SRGGB10P MMAL_FOURCC('p', 'R', 'A', 'A') ++ ++/* 12 bit per pixel packed Bayer formats. */ ++#define MMAL_ENCODING_BAYER_SBGGR12P MMAL_FOURCC('p', 'B', '1', '2') ++#define MMAL_ENCODING_BAYER_SGRBG12P MMAL_FOURCC('p', 'g', '1', '2') ++#define MMAL_ENCODING_BAYER_SGBRG12P MMAL_FOURCC('p', 'G', '1', '2') ++#define MMAL_ENCODING_BAYER_SRGGB12P MMAL_FOURCC('p', 'R', '1', '2') ++ ++/* 16 bit per pixel Bayer formats. */ ++#define MMAL_ENCODING_BAYER_SBGGR16 MMAL_FOURCC('B', 'G', '1', '6') ++#define MMAL_ENCODING_BAYER_SGBRG16 MMAL_FOURCC('G', 'B', '1', '6') ++#define MMAL_ENCODING_BAYER_SGRBG16 MMAL_FOURCC('G', 'R', '1', '6') ++#define MMAL_ENCODING_BAYER_SRGGB16 MMAL_FOURCC('R', 'G', '1', '6') ++ + /** An EGL image handle + */ + #define MMAL_ENCODING_EGL_IMAGE MMAL_FOURCC('E', 'G', 'L', 'I') diff --git a/target/linux/brcm2708/patches-4.19/950-0356-gpu-vc4-fkms-Update-driver-to-not-use-plane-crtc.patch b/target/linux/brcm2708/patches-4.19/950-0356-gpu-vc4-fkms-Update-driver-to-not-use-plane-crtc.patch deleted file mode 100644 index 7188a7acb3..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0356-gpu-vc4-fkms-Update-driver-to-not-use-plane-crtc.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 477a46fa014209503a601add47994f7bc4b2093a Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 19 Feb 2019 15:06:31 +0000 -Subject: [PATCH 356/703] gpu:vc4-fkms: Update driver to not use plane->crtc. - -Following on from -commit 2f958af7fc248 ("drm/vc4: Stop updating plane->fb/crtc") -do the same in the firmwarekms driver and look at plane_state->crtc -instead. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -193,8 +193,8 @@ static void vc4_cursor_plane_atomic_upda - struct drm_plane_state *old_state) - { - struct vc4_dev *vc4 = to_vc4_dev(plane->dev); -- struct vc4_crtc *vc4_crtc = to_vc4_crtc(plane->crtc); - struct drm_plane_state *state = plane->state; -+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(state->crtc); - struct drm_framebuffer *fb = state->fb; - struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); - dma_addr_t addr = bo->paddr + fb->offsets[0]; -@@ -682,8 +682,6 @@ static int vc4_fkms_bind(struct device * - drm_crtc_init_with_planes(drm, crtc, primary_plane, cursor_plane, - &vc4_crtc_funcs, NULL); - drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs); -- primary_plane->crtc = crtc; -- cursor_plane->crtc = crtc; - - vc4_encoder = devm_kzalloc(dev, sizeof(*vc4_encoder), GFP_KERNEL); - if (!vc4_encoder) diff --git a/target/linux/brcm2708/patches-4.19/950-0356-staging-mmal-vchiq-Always-return-the-param-size-from.patch b/target/linux/brcm2708/patches-4.19/950-0356-staging-mmal-vchiq-Always-return-the-param-size-from.patch new file mode 100644 index 0000000000..1eeba28f62 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0356-staging-mmal-vchiq-Always-return-the-param-size-from.patch @@ -0,0 +1,38 @@ +From ffdd605fc5bf096855bd24311bb0f112257dd53e Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 13 Feb 2019 12:36:56 +0000 +Subject: [PATCH 356/725] staging: mmal-vchiq: Always return the param size + from param_get + +mmal-vchiq is a reimplementation of the userland library for MMAL. +When getting a parameter, the client provides the storage and +the size of the storage. The VPU then returns the size of the +parameter that it wished to return, and as much as possible of +that parameter is returned to the client. + +The implementation previously only returned the size provided +by the VPU should it exceed the buffer size. So for parameters +such as the supported encodings list the client had no idea +how much of the provided storage had been populated. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +@@ -1413,11 +1413,12 @@ static int port_parameter_get(struct vch + */ + memcpy(value, &rmsg->u.port_parameter_get_reply.value, + *value_size); +- *value_size = rmsg->u.port_parameter_get_reply.size; + } else { + memcpy(value, &rmsg->u.port_parameter_get_reply.value, + rmsg->u.port_parameter_get_reply.size); + } ++ /* Always report the size of the returned parameter to the caller */ ++ *value_size = rmsg->u.port_parameter_get_reply.size; + + pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n", __func__, + ret, port->component->handle, port->handle, parameter_id); diff --git a/target/linux/brcm2708/patches-4.19/950-0357-drm-vc4-Programming-the-CTM-is-conditional-on-runnin.patch b/target/linux/brcm2708/patches-4.19/950-0357-drm-vc4-Programming-the-CTM-is-conditional-on-runnin.patch deleted file mode 100644 index 2fd12593d7..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0357-drm-vc4-Programming-the-CTM-is-conditional-on-runnin.patch +++ /dev/null @@ -1,26 +0,0 @@ -From d75d01225814a7c722affe33f3bfe0ba72fe49a8 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 19 Feb 2019 15:18:25 +0000 -Subject: [PATCH 357/703] drm: vc4: Programming the CTM is conditional on - running full KMS - -vc4_ctm_commit writes to HVS registers, so this is only applicable -when in full KMS mode, not in firmware KMS mode. Add this conditional. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_kms.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -147,7 +147,8 @@ vc4_atomic_complete_commit(struct drm_at - - drm_atomic_helper_commit_modeset_disables(dev, state); - -- vc4_ctm_commit(vc4, state); -+ if (!vc4->firmware_kms) -+ vc4_ctm_commit(vc4, state); - - drm_atomic_helper_commit_planes(dev, state, 0); - diff --git a/target/linux/brcm2708/patches-4.19/950-0357-staging-mmal-vchiq-If-the-VPU-returns-an-error-don-t.patch b/target/linux/brcm2708/patches-4.19/950-0357-staging-mmal-vchiq-If-the-VPU-returns-an-error-don-t.patch new file mode 100644 index 0000000000..926cbde2a1 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0357-staging-mmal-vchiq-If-the-VPU-returns-an-error-don-t.patch @@ -0,0 +1,29 @@ +From 778f855d699bd67e1eb177c7a0bcc30af550ce6a Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 13 Feb 2019 12:51:03 +0000 +Subject: [PATCH 357/725] staging: mmal-vchiq: If the VPU returns an error, + don't negate it + +There is an enum for the errors that the VPU can return. +port_parameter_get was negating that value, but also using -EINVAL +from the Linux error codes. +Pass the VPU error code as positive values. Should the function +need to pass a Linux failure, then return that as negative. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +@@ -1401,7 +1401,8 @@ static int port_parameter_get(struct vch + goto release_msg; + } + +- ret = -rmsg->u.port_parameter_get_reply.status; ++ ret = rmsg->u.port_parameter_get_reply.status; ++ + /* port_parameter_get_reply.size includes the header, + * whilst *value_size doesn't. + */ diff --git a/target/linux/brcm2708/patches-4.19/950-0358-staging-bcm2835_codec-Query-supported-formats-from-t.patch b/target/linux/brcm2708/patches-4.19/950-0358-staging-bcm2835_codec-Query-supported-formats-from-t.patch new file mode 100644 index 0000000000..6efef5ceec --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0358-staging-bcm2835_codec-Query-supported-formats-from-t.patch @@ -0,0 +1,727 @@ +From b39574e09f52569d27b1904771a433f02bf5e547 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 13 Feb 2019 13:44:00 +0000 +Subject: [PATCH 358/725] staging: bcm2835_codec: Query supported formats from + the component + +The driver was previously working with hard coded tables of +which video formats were supported by each component. +The components advertise this information via a MMAL parameter, +so retrieve the information from there during probe, and store +in the state structure for that device. + +Signed-off-by: Dave Stevenson +--- + .../bcm2835-codec/bcm2835-v4l2-codec.c | 455 +++++++++++++----- + 1 file changed, 327 insertions(+), 128 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -88,17 +88,12 @@ struct bcm2835_codec_fmt { + int bytesperline_align; + u32 flags; + u32 mmal_fmt; +- bool decode_only; +- bool encode_only; + int size_multiplier_x2; + }; + +-/* Supported raw pixel formats. Those supported for both encode and decode +- * must come first, with those only supported for decode coming after (there +- * are no formats supported for encode only). +- */ +-static struct bcm2835_codec_fmt raw_formats[] = { ++static const struct bcm2835_codec_fmt supported_formats[] = { + { ++ /* YUV formats */ + .fourcc = V4L2_PIX_FMT_YUV420, + .depth = 8, + .bytesperline_align = 32, +@@ -139,7 +134,6 @@ static struct bcm2835_codec_fmt raw_form + .bytesperline_align = 32, + .flags = 0, + .mmal_fmt = MMAL_ENCODING_YUYV, +- .encode_only = true, + .size_multiplier_x2 = 2, + }, { + .fourcc = V4L2_PIX_FMT_UYVY, +@@ -147,7 +141,6 @@ static struct bcm2835_codec_fmt raw_form + .bytesperline_align = 32, + .flags = 0, + .mmal_fmt = MMAL_ENCODING_UYVY, +- .encode_only = true, + .size_multiplier_x2 = 2, + }, { + .fourcc = V4L2_PIX_FMT_YVYU, +@@ -155,7 +148,6 @@ static struct bcm2835_codec_fmt raw_form + .bytesperline_align = 32, + .flags = 0, + .mmal_fmt = MMAL_ENCODING_YVYU, +- .encode_only = true, + .size_multiplier_x2 = 2, + }, { + .fourcc = V4L2_PIX_FMT_VYUY, +@@ -163,15 +155,14 @@ static struct bcm2835_codec_fmt raw_form + .bytesperline_align = 32, + .flags = 0, + .mmal_fmt = MMAL_ENCODING_VYUY, +- .encode_only = true, + .size_multiplier_x2 = 2, + }, { ++ /* RGB formats */ + .fourcc = V4L2_PIX_FMT_RGB24, + .depth = 24, + .bytesperline_align = 32, + .flags = 0, + .mmal_fmt = MMAL_ENCODING_RGB24, +- .encode_only = true, + .size_multiplier_x2 = 2, + }, { + .fourcc = V4L2_PIX_FMT_BGR24, +@@ -179,7 +170,6 @@ static struct bcm2835_codec_fmt raw_form + .bytesperline_align = 32, + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BGR24, +- .encode_only = true, + .size_multiplier_x2 = 2, + }, { + .fourcc = V4L2_PIX_FMT_BGR32, +@@ -187,17 +177,126 @@ static struct bcm2835_codec_fmt raw_form + .bytesperline_align = 32, + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BGRA, +- .encode_only = true, + .size_multiplier_x2 = 2, +- }, +-}; +- +-/* Supported encoded formats. Those supported for both encode and decode +- * must come first, with those only supported for decode coming after (there +- * are no formats supported for encode only). +- */ +-static struct bcm2835_codec_fmt encoded_formats[] = { +- { ++ }, { ++ /* Bayer formats */ ++ /* 8 bit */ ++ .fourcc = V4L2_PIX_FMT_SRGGB8, ++ .depth = 8, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB8, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SBGGR8, ++ .depth = 8, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR8, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGRBG8, ++ .depth = 8, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG8, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGBRG8, ++ .depth = 8, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG8, ++ .size_multiplier_x2 = 2, ++ }, { ++ /* 10 bit */ ++ .fourcc = V4L2_PIX_FMT_SRGGB10P, ++ .depth = 10, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB10P, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SBGGR10P, ++ .depth = 10, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR10P, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGRBG10P, ++ .depth = 10, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG10P, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGBRG10P, ++ .depth = 10, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG10P, ++ .size_multiplier_x2 = 2, ++ }, { ++ /* 12 bit */ ++ .fourcc = V4L2_PIX_FMT_SRGGB12P, ++ .depth = 12, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB12P, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SBGGR12P, ++ .depth = 12, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR12P, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGRBG12P, ++ .depth = 12, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG12P, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGBRG12P, ++ .depth = 12, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG12P, ++ .size_multiplier_x2 = 2, ++ }, { ++ /* 16 bit */ ++ .fourcc = V4L2_PIX_FMT_SRGGB16, ++ .depth = 16, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB16, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SBGGR16, ++ .depth = 16, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR16, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGRBG16, ++ .depth = 16, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG16, ++ .size_multiplier_x2 = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGBRG16, ++ .depth = 16, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG16, ++ .size_multiplier_x2 = 2, ++ }, { ++ /* Compressed formats */ + .fourcc = V4L2_PIX_FMT_H264, + .depth = 0, + .flags = V4L2_FMT_FLAG_COMPRESSED, +@@ -212,30 +311,22 @@ static struct bcm2835_codec_fmt encoded_ + .depth = 0, + .flags = V4L2_FMT_FLAG_COMPRESSED, + .mmal_fmt = MMAL_ENCODING_MP4V, +- .decode_only = true, + }, { + .fourcc = V4L2_PIX_FMT_H263, + .depth = 0, + .flags = V4L2_FMT_FLAG_COMPRESSED, + .mmal_fmt = MMAL_ENCODING_H263, +- .decode_only = true, + }, { + .fourcc = V4L2_PIX_FMT_MPEG2, + .depth = 0, + .flags = V4L2_FMT_FLAG_COMPRESSED, + .mmal_fmt = MMAL_ENCODING_MP2V, +- .decode_only = true, + }, { + .fourcc = V4L2_PIX_FMT_VP8, + .depth = 0, + .flags = V4L2_FMT_FLAG_COMPRESSED, + .mmal_fmt = MMAL_ENCODING_VP8, +- .decode_only = true, + }, +- /* +- * This list couold include VP6 and Theorafor decode, but V4L2 doesn't +- * support them. +- */ + }; + + struct bcm2835_codec_fmt_list { +@@ -243,19 +334,6 @@ struct bcm2835_codec_fmt_list { + unsigned int num_entries; + }; + +-#define RAW_LIST 0 +-#define ENCODED_LIST 1 +- +-struct bcm2835_codec_fmt_list formats[] = { +- { +- .list = raw_formats, +- .num_entries = ARRAY_SIZE(raw_formats), +- }, { +- .list = encoded_formats, +- .num_entries = ARRAY_SIZE(encoded_formats), +- }, +-}; +- + struct m2m_mmal_buffer { + struct v4l2_m2m_buffer m2m; + struct mmal_buffer mmal; +@@ -284,52 +362,6 @@ struct bcm2835_codec_q_data { + bool eos_buffer_in_use; /* debug only */ + }; + +-enum { +- V4L2_M2M_SRC = 0, +- V4L2_M2M_DST = 1, +-}; +- +-static inline struct bcm2835_codec_fmt_list *get_format_list(bool decode, +- bool capture) +-{ +- return decode ^ capture ? &formats[ENCODED_LIST] : &formats[RAW_LIST]; +-} +- +-static struct bcm2835_codec_fmt *get_default_format(bool decode, bool capture) +-{ +- return &get_format_list(decode, capture)->list[0]; +-} +- +-static struct bcm2835_codec_fmt *find_format(struct v4l2_format *f, bool decode, +- bool capture) +-{ +- struct bcm2835_codec_fmt *fmt; +- unsigned int k; +- struct bcm2835_codec_fmt_list *fmts = get_format_list(decode, capture); +- +- for (k = 0; k < fmts->num_entries; k++) { +- fmt = &fmts->list[k]; +- if (fmt->fourcc == f->fmt.pix.pixelformat) +- break; +- } +- +- /* +- * Some compressed formats are only supported for decoding, not +- * encoding. +- */ +- if (!decode && fmts->list[k].decode_only) +- return NULL; +- +- /* Some pixel formats are only supported for encoding, not decoding. */ +- if (decode && fmts->list[k].encode_only) +- return NULL; +- +- if (k == fmts->num_entries) +- return NULL; +- +- return &fmts->list[k]; +-} +- + struct bcm2835_codec_dev { + struct platform_device *pdev; + +@@ -342,6 +374,9 @@ struct bcm2835_codec_dev { + + /* allocated mmal instance and components */ + bool decode; /* Is this instance a decoder? */ ++ /* The list of formats supported on input and output queues. */ ++ struct bcm2835_codec_fmt_list supported_fmts[2]; ++ + struct vchiq_mmal_instance *instance; + + struct v4l2_m2m_dev *m2m_dev; +@@ -374,8 +409,59 @@ struct bcm2835_codec_ctx { + struct bcm2835_codec_driver { + struct bcm2835_codec_dev *encode; + struct bcm2835_codec_dev *decode; ++ struct bcm2835_codec_dev *isp; ++}; ++ ++enum { ++ V4L2_M2M_SRC = 0, ++ V4L2_M2M_DST = 1, + }; + ++static const struct bcm2835_codec_fmt *get_fmt(u32 mmal_fmt) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(supported_formats); i++) { ++ if (supported_formats[i].mmal_fmt == mmal_fmt) ++ return &supported_formats[i]; ++ } ++ return NULL; ++} ++ ++static inline ++struct bcm2835_codec_fmt_list *get_format_list(struct bcm2835_codec_dev *dev, ++ bool capture) ++{ ++ return &dev->supported_fmts[capture ? 1 : 0]; ++} ++ ++static ++struct bcm2835_codec_fmt *get_default_format(struct bcm2835_codec_dev *dev, ++ bool capture) ++{ ++ return &dev->supported_fmts[capture ? 1 : 0].list[0]; ++} ++ ++static struct bcm2835_codec_fmt *find_format(struct v4l2_format *f, ++ struct bcm2835_codec_dev *dev, ++ bool capture) ++{ ++ struct bcm2835_codec_fmt *fmt; ++ unsigned int k; ++ struct bcm2835_codec_fmt_list *fmts = ++ &dev->supported_fmts[capture ? 1 : 0]; ++ ++ for (k = 0; k < fmts->num_entries; k++) { ++ fmt = &fmts->list[k]; ++ if (fmt->fourcc == f->fmt.pix.pixelformat) ++ break; ++ } ++ if (k == fmts->num_entries) ++ return NULL; ++ ++ return &fmts->list[k]; ++} ++ + static inline struct bcm2835_codec_ctx *file2ctx(struct file *file) + { + return container_of(file->private_data, struct bcm2835_codec_ctx, fh); +@@ -456,7 +542,6 @@ static inline unsigned int get_bytesperl + } + + static void setup_mmal_port_format(struct bcm2835_codec_ctx *ctx, +- bool decode, + struct bcm2835_codec_q_data *q_data, + struct vchiq_mmal_port *port) + { +@@ -473,7 +558,7 @@ static void setup_mmal_port_format(struc + port->es.video.frame_rate.den = 1; + } else { + /* Compressed format - leave resolution as 0 for decode */ +- if (decode) { ++ if (ctx->dev->decode) { + port->es.video.width = 0; + port->es.video.height = 0; + port->es.video.crop.width = 0; +@@ -802,22 +887,15 @@ static int vidioc_querycap(struct file * + return 0; + } + +-static int enum_fmt(struct v4l2_fmtdesc *f, bool decode, bool capture) ++static int enum_fmt(struct v4l2_fmtdesc *f, struct bcm2835_codec_ctx *ctx, ++ bool capture) + { + struct bcm2835_codec_fmt *fmt; +- struct bcm2835_codec_fmt_list *fmts = get_format_list(decode, capture); ++ struct bcm2835_codec_fmt_list *fmts = ++ get_format_list(ctx->dev, capture); + + if (f->index < fmts->num_entries) { + /* Format found */ +- /* Check format isn't a decode only format when encoding */ +- if (!decode && +- fmts->list[f->index].decode_only) +- return -EINVAL; +- /* Check format isn't a decode only format when encoding */ +- if (decode && +- fmts->list[f->index].encode_only) +- return -EINVAL; +- + fmt = &fmts->list[f->index]; + f->pixelformat = fmt->fourcc; + f->flags = fmt->flags; +@@ -833,7 +911,7 @@ static int vidioc_enum_fmt_vid_cap(struc + { + struct bcm2835_codec_ctx *ctx = file2ctx(file); + +- return enum_fmt(f, ctx->dev->decode, true); ++ return enum_fmt(f, ctx, true); + } + + static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, +@@ -841,7 +919,7 @@ static int vidioc_enum_fmt_vid_out(struc + { + struct bcm2835_codec_ctx *ctx = file2ctx(file); + +- return enum_fmt(f, ctx->dev->decode, false); ++ return enum_fmt(f, ctx, false); + } + + static int vidioc_g_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f) +@@ -933,11 +1011,11 @@ static int vidioc_try_fmt_vid_cap(struct + struct bcm2835_codec_fmt *fmt; + struct bcm2835_codec_ctx *ctx = file2ctx(file); + +- fmt = find_format(f, ctx->dev->decode, true); ++ fmt = find_format(f, ctx->dev, true); + if (!fmt) { +- f->fmt.pix.pixelformat = get_default_format(ctx->dev->decode, ++ f->fmt.pix.pixelformat = get_default_format(ctx->dev, + true)->fourcc; +- fmt = find_format(f, ctx->dev->decode, true); ++ fmt = find_format(f, ctx->dev, true); + } + + return vidioc_try_fmt(f, fmt); +@@ -949,11 +1027,11 @@ static int vidioc_try_fmt_vid_out(struct + struct bcm2835_codec_fmt *fmt; + struct bcm2835_codec_ctx *ctx = file2ctx(file); + +- fmt = find_format(f, ctx->dev->decode, false); ++ fmt = find_format(f, ctx->dev, false); + if (!fmt) { +- f->fmt.pix.pixelformat = get_default_format(ctx->dev->decode, ++ f->fmt.pix.pixelformat = get_default_format(ctx->dev, + false)->fourcc; +- fmt = find_format(f, ctx->dev->decode, false); ++ fmt = find_format(f, ctx->dev, false); + } + + if (!f->fmt.pix.colorspace) +@@ -988,7 +1066,7 @@ static int vidioc_s_fmt(struct bcm2835_c + return -EBUSY; + } + +- q_data->fmt = find_format(f, ctx->dev->decode, ++ q_data->fmt = find_format(f, ctx->dev, + f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE); + q_data->crop_width = f->fmt.pix.width; + q_data->height = f->fmt.pix.height; +@@ -1041,7 +1119,7 @@ static int vidioc_s_fmt(struct bcm2835_c + if (!port) + return 0; + +- setup_mmal_port_format(ctx, ctx->dev->decode, q_data, port); ++ setup_mmal_port_format(ctx, q_data, port); + ret = vchiq_mmal_port_set_format(ctx->dev->instance, port); + if (ret) { + v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed vchiq_mmal_port_set_format on port, ret %d\n", +@@ -1064,8 +1142,7 @@ static int vidioc_s_fmt(struct bcm2835_c + struct bcm2835_codec_q_data *q_data_dst = + &ctx->q_data[V4L2_M2M_DST]; + +- setup_mmal_port_format(ctx, ctx->dev->decode, q_data_dst, +- port_dst); ++ setup_mmal_port_format(ctx, q_data_dst, port_dst); + ret = vchiq_mmal_port_set_format(ctx->dev->instance, port_dst); + if (ret) { + v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed vchiq_mmal_port_set_format on output port, ret %d\n", +@@ -1636,10 +1713,10 @@ static int bcm2835_codec_create_componen + MMAL_PARAMETER_ZERO_COPY, &enable, + sizeof(enable)); + +- setup_mmal_port_format(ctx, dev->decode, &ctx->q_data[V4L2_M2M_SRC], ++ setup_mmal_port_format(ctx, &ctx->q_data[V4L2_M2M_SRC], + &ctx->component->input[0]); + +- setup_mmal_port_format(ctx, dev->decode, &ctx->q_data[V4L2_M2M_DST], ++ setup_mmal_port_format(ctx, &ctx->q_data[V4L2_M2M_DST], + &ctx->component->output[0]); + + ret = vchiq_mmal_port_set_format(dev->instance, +@@ -2025,8 +2102,8 @@ static int bcm2835_codec_open(struct fil + goto open_unlock; + } + +- ctx->q_data[V4L2_M2M_SRC].fmt = get_default_format(dev->decode, false); +- ctx->q_data[V4L2_M2M_DST].fmt = get_default_format(dev->decode, true); ++ ctx->q_data[V4L2_M2M_SRC].fmt = get_default_format(dev, false); ++ ctx->q_data[V4L2_M2M_DST].fmt = get_default_format(dev, true); + if (dev->decode) { + /* + * Input width and height are irrelevant as they will be defined +@@ -2209,13 +2286,130 @@ static const struct v4l2_m2m_ops m2m_ops + .job_abort = job_abort, + }; + ++/* Size of the array to provide to the VPU when asking for the list of supported ++ * formats. ++ * The ISP component currently advertises 33 input formats, so add a small ++ * overhead on that. ++ */ ++#define MAX_SUPPORTED_ENCODINGS 40 ++ ++/* Populate dev->supported_fmts with the formats supported by those ports. */ ++static int bcm2835_codec_get_supported_fmts(struct bcm2835_codec_dev *dev) ++{ ++ struct bcm2835_codec_fmt *list; ++ struct vchiq_mmal_component *component; ++ u32 fourccs[MAX_SUPPORTED_ENCODINGS]; ++ u32 param_size = sizeof(fourccs); ++ unsigned int i, j, num_encodings; ++ int ret; ++ ++ ret = vchiq_mmal_component_init(dev->instance, ++ dev->decode ? ++ "ril.video_decode" : ++ "ril.video_encode", ++ &component); ++ if (ret < 0) { ++ v4l2_err(&dev->v4l2_dev, "%s: failed to create component\n", ++ __func__); ++ return -ENOMEM; ++ } ++ ++ ret = vchiq_mmal_port_parameter_get(dev->instance, ++ &component->input[0], ++ MMAL_PARAMETER_SUPPORTED_ENCODINGS, ++ &fourccs, ++ ¶m_size); ++ ++ if (ret) { ++ if (ret == MMAL_MSG_STATUS_ENOSPC) { ++ v4l2_err(&dev->v4l2_dev, "%s: port has more encoding than we provided space for. Some are dropped.\n", ++ __func__); ++ num_encodings = MAX_SUPPORTED_ENCODINGS; ++ } else { ++ v4l2_err(&dev->v4l2_dev, "%s: get_param ret %u.\n", ++ __func__, ret); ++ ret = -EINVAL; ++ goto destroy_component; ++ } ++ } else { ++ num_encodings = param_size / sizeof(u32); ++ } ++ ++ /* Assume at this stage that all encodings will be supported in V4L2. ++ * Any that aren't supported will waste a very small amount of memory. ++ */ ++ list = devm_kzalloc(&dev->pdev->dev, ++ sizeof(struct bcm2835_codec_fmt) * num_encodings, ++ GFP_KERNEL); ++ if (!list) { ++ ret = -ENOMEM; ++ goto destroy_component; ++ } ++ dev->supported_fmts[0].list = list; ++ ++ for (i = 0, j = 0; i < num_encodings; i++) { ++ const struct bcm2835_codec_fmt *fmt = get_fmt(fourccs[i]); ++ ++ if (fmt) { ++ list[j] = *fmt; ++ j++; ++ } ++ } ++ dev->supported_fmts[0].num_entries = j; ++ ++ param_size = sizeof(fourccs); ++ ret = vchiq_mmal_port_parameter_get(dev->instance, ++ &component->output[0], ++ MMAL_PARAMETER_SUPPORTED_ENCODINGS, ++ &fourccs, ++ ¶m_size); ++ ++ if (ret) { ++ if (ret == MMAL_MSG_STATUS_ENOSPC) { ++ v4l2_err(&dev->v4l2_dev, "%s: port has more encoding than we provided space for. Some are dropped.\n", ++ __func__); ++ num_encodings = MAX_SUPPORTED_ENCODINGS; ++ } else { ++ ret = -EINVAL; ++ goto destroy_component; ++ } ++ } else { ++ num_encodings = param_size / sizeof(u32); ++ } ++ /* Assume at this stage that all encodings will be supported in V4L2. */ ++ list = devm_kzalloc(&dev->pdev->dev, ++ sizeof(struct bcm2835_codec_fmt) * num_encodings, ++ GFP_KERNEL); ++ if (!list) { ++ ret = -ENOMEM; ++ goto destroy_component; ++ } ++ dev->supported_fmts[1].list = list; ++ ++ for (i = 0, j = 0; i < num_encodings; i++) { ++ const struct bcm2835_codec_fmt *fmt = get_fmt(fourccs[i]); ++ ++ if (fmt) { ++ list[j] = *fmt; ++ j++; ++ } ++ } ++ dev->supported_fmts[1].num_entries = j; ++ ++ ret = 0; ++ ++destroy_component: ++ vchiq_mmal_component_finalise(dev->instance, component); ++ ++ return ret; ++} ++ + static int bcm2835_codec_create(struct platform_device *pdev, + struct bcm2835_codec_dev **new_dev, + bool decode) + { + struct bcm2835_codec_dev *dev; + struct video_device *vfd; +- struct vchiq_mmal_instance *instance = NULL; + int video_nr; + int ret; + +@@ -2227,10 +2421,18 @@ static int bcm2835_codec_create(struct p + + dev->decode = decode; + +- ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); ++ ret = vchiq_mmal_init(&dev->instance); + if (ret) + return ret; + ++ ret = bcm2835_codec_get_supported_fmts(dev); ++ if (ret) ++ goto vchiq_finalise; ++ ++ ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); ++ if (ret) ++ goto vchiq_finalise; ++ + atomic_set(&dev->num_inst, 0); + mutex_init(&dev->dev_mutex); + +@@ -2270,12 +2472,7 @@ static int bcm2835_codec_create(struct p + goto err_m2m; + } + +- ret = vchiq_mmal_init(&instance); +- if (ret < 0) +- goto err_m2m; +- dev->instance = instance; +- +- v4l2_info(&dev->v4l2_dev, "Loaded V4L2 %s codec\n", ++ v4l2_info(&dev->v4l2_dev, "Loaded V4L2 %s\n", + dev->decode ? "decode" : "encode"); + return 0; + +@@ -2284,7 +2481,8 @@ err_m2m: + video_unregister_device(&dev->vfd); + unreg_dev: + v4l2_device_unregister(&dev->v4l2_dev); +- ++vchiq_finalise: ++ vchiq_mmal_finalise(dev->instance); + return ret; + } + +@@ -2297,6 +2495,7 @@ static int bcm2835_codec_destroy(struct + v4l2_m2m_release(dev->m2m_dev); + video_unregister_device(&dev->vfd); + v4l2_device_unregister(&dev->v4l2_dev); ++ vchiq_mmal_finalise(dev->instance); + + return 0; + } diff --git a/target/linux/brcm2708/patches-4.19/950-0358-staging-mmal_vchiq-Add-in-the-Bayer-encoding-formats.patch b/target/linux/brcm2708/patches-4.19/950-0358-staging-mmal_vchiq-Add-in-the-Bayer-encoding-formats.patch deleted file mode 100644 index 68d53280ad..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0358-staging-mmal_vchiq-Add-in-the-Bayer-encoding-formats.patch +++ /dev/null @@ -1,51 +0,0 @@ -From f65a0ba774c5ef012f45ea3136565713aa4884d5 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 13 Feb 2019 12:33:29 +0000 -Subject: [PATCH 358/703] staging: mmal_vchiq: Add in the Bayer encoding - formats - -The list of formats was copied before Bayer support was added. -The ISP supports Bayer and is being supported by the bcm2835_codec -driver, so add in the encodings for them. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/vchiq-mmal/mmal-encodings.h | 27 +++++++++++++++++++ - 1 file changed, 27 insertions(+) - ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h -@@ -69,6 +69,33 @@ - */ - #define MMAL_ENCODING_OPAQUE MMAL_FOURCC('O', 'P', 'Q', 'V') - -+/* Bayer formats -+ * FourCC values copied from V4L2 where defined. -+ */ -+/* 8 bit per pixel Bayer formats. */ -+#define MMAL_ENCODING_BAYER_SBGGR8 MMAL_FOURCC('B', 'A', '8', '1') -+#define MMAL_ENCODING_BAYER_SGBRG8 MMAL_FOURCC('G', 'B', 'R', 'G') -+#define MMAL_ENCODING_BAYER_SGRBG8 MMAL_FOURCC('G', 'R', 'B', 'G') -+#define MMAL_ENCODING_BAYER_SRGGB8 MMAL_FOURCC('R', 'G', 'G', 'B') -+ -+/* 10 bit per pixel packed Bayer formats. */ -+#define MMAL_ENCODING_BAYER_SBGGR10P MMAL_FOURCC('p', 'B', 'A', 'A') -+#define MMAL_ENCODING_BAYER_SGRBG10P MMAL_FOURCC('p', 'g', 'A', 'A') -+#define MMAL_ENCODING_BAYER_SGBRG10P MMAL_FOURCC('p', 'G', 'A', 'A') -+#define MMAL_ENCODING_BAYER_SRGGB10P MMAL_FOURCC('p', 'R', 'A', 'A') -+ -+/* 12 bit per pixel packed Bayer formats. */ -+#define MMAL_ENCODING_BAYER_SBGGR12P MMAL_FOURCC('p', 'B', '1', '2') -+#define MMAL_ENCODING_BAYER_SGRBG12P MMAL_FOURCC('p', 'g', '1', '2') -+#define MMAL_ENCODING_BAYER_SGBRG12P MMAL_FOURCC('p', 'G', '1', '2') -+#define MMAL_ENCODING_BAYER_SRGGB12P MMAL_FOURCC('p', 'R', '1', '2') -+ -+/* 16 bit per pixel Bayer formats. */ -+#define MMAL_ENCODING_BAYER_SBGGR16 MMAL_FOURCC('B', 'G', '1', '6') -+#define MMAL_ENCODING_BAYER_SGBRG16 MMAL_FOURCC('G', 'B', '1', '6') -+#define MMAL_ENCODING_BAYER_SGRBG16 MMAL_FOURCC('G', 'R', '1', '6') -+#define MMAL_ENCODING_BAYER_SRGGB16 MMAL_FOURCC('R', 'G', '1', '6') -+ - /** An EGL image handle - */ - #define MMAL_ENCODING_EGL_IMAGE MMAL_FOURCC('E', 'G', 'L', 'I') diff --git a/target/linux/brcm2708/patches-4.19/950-0359-staging-bcm2835_codec-Add-support-for-the-ISP-as-an-.patch b/target/linux/brcm2708/patches-4.19/950-0359-staging-bcm2835_codec-Add-support-for-the-ISP-as-an-.patch new file mode 100644 index 0000000000..28cf8500a0 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0359-staging-bcm2835_codec-Add-support-for-the-ISP-as-an-.patch @@ -0,0 +1,384 @@ +From e65784b32dfce82b3eb6c5e700675e7417c4d3c4 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 13 Feb 2019 14:07:52 +0000 +Subject: [PATCH 359/725] staging: bcm2835_codec: Add support for the ISP as an + M2M device + +The MMAL ISP component can also use this same V4L2 wrapper to +provide a M2M format conversion and resizer. +Instantiate 3 V4L2 devices now, one for each of decode, encode, +and isp. +The ISP currently doesn't expose any controls via V4L2, but this +can be extended in the future. + +Signed-off-by: Dave Stevenson +--- + .../bcm2835-codec/bcm2835-v4l2-codec.c | 132 ++++++++++++------ + 1 file changed, 92 insertions(+), 40 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -54,10 +54,26 @@ static int encode_video_nr = 11; + module_param(encode_video_nr, int, 0644); + MODULE_PARM_DESC(encode_video_nr, "encoder video device number"); + ++static int isp_video_nr = 12; ++module_param(isp_video_nr, int, 0644); ++MODULE_PARM_DESC(isp_video_nr, "isp video device number"); ++ + static unsigned int debug; + module_param(debug, uint, 0644); + MODULE_PARM_DESC(debug, "activates debug info (0-3)"); + ++enum bcm2835_codec_role { ++ DECODE, ++ ENCODE, ++ ISP, ++}; ++ ++static const char * const components[] = { ++ "ril.video_decode", ++ "ril.video_encode", ++ "ril.isp", ++}; ++ + #define MIN_W 32 + #define MIN_H 32 + #define MAX_W 1920 +@@ -373,7 +389,7 @@ struct bcm2835_codec_dev { + atomic_t num_inst; + + /* allocated mmal instance and components */ +- bool decode; /* Is this instance a decoder? */ ++ enum bcm2835_codec_role role; + /* The list of formats supported on input and output queues. */ + struct bcm2835_codec_fmt_list supported_fmts[2]; + +@@ -558,7 +574,7 @@ static void setup_mmal_port_format(struc + port->es.video.frame_rate.den = 1; + } else { + /* Compressed format - leave resolution as 0 for decode */ +- if (ctx->dev->decode) { ++ if (ctx->dev->role == DECODE) { + port->es.video.width = 0; + port->es.video.height = 0; + port->es.video.crop.width = 0; +@@ -1089,7 +1105,8 @@ static int vidioc_s_fmt(struct bcm2835_c + v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Calulated bpl as %u, size %u\n", + q_data->bytesperline, q_data->sizeimage); + +- if (ctx->dev->decode && q_data->fmt->flags & V4L2_FMT_FLAG_COMPRESSED && ++ if (ctx->dev->role == DECODE && ++ q_data->fmt->flags & V4L2_FMT_FLAG_COMPRESSED && + f->fmt.pix.width && f->fmt.pix.height) { + /* + * On the decoder, if provided with a resolution on the input +@@ -1188,7 +1205,8 @@ static int vidioc_g_selection(struct fil + bool capture_queue = s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? + true : false; + +- if (capture_queue ^ ctx->dev->decode) ++ if ((ctx->dev->role == DECODE && !capture_queue) || ++ (ctx->dev->role == ENCODE && capture_queue)) + /* OUTPUT on decoder and CAPTURE on encoder are not valid. */ + return -EINVAL; + +@@ -1196,7 +1214,8 @@ static int vidioc_g_selection(struct fil + if (!q_data) + return -EINVAL; + +- if (ctx->dev->decode) { ++ switch (ctx->dev->role) { ++ case DECODE: + switch (s->target) { + case V4L2_SEL_TGT_COMPOSE_DEFAULT: + case V4L2_SEL_TGT_COMPOSE: +@@ -1214,7 +1233,8 @@ static int vidioc_g_selection(struct fil + default: + return -EINVAL; + } +- } else { ++ break; ++ case ENCODE: + switch (s->target) { + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP_BOUNDS: +@@ -1232,6 +1252,9 @@ static int vidioc_g_selection(struct fil + default: + return -EINVAL; + } ++ break; ++ case ISP: ++ break; + } + + return 0; +@@ -1249,7 +1272,8 @@ static int vidioc_s_selection(struct fil + __func__, ctx, s->type, q_data, s->target, s->r.left, s->r.top, + s->r.width, s->r.height); + +- if (capture_queue ^ ctx->dev->decode) ++ if ((ctx->dev->role == DECODE && !capture_queue) || ++ (ctx->dev->role == ENCODE && capture_queue)) + /* OUTPUT on decoder and CAPTURE on encoder are not valid. */ + return -EINVAL; + +@@ -1257,7 +1281,8 @@ static int vidioc_s_selection(struct fil + if (!q_data) + return -EINVAL; + +- if (ctx->dev->decode) { ++ switch (ctx->dev->role) { ++ case DECODE: + switch (s->target) { + case V4L2_SEL_TGT_COMPOSE: + /* Accept cropped image */ +@@ -1272,7 +1297,8 @@ static int vidioc_s_selection(struct fil + default: + return -EINVAL; + } +- } else { ++ break; ++ case ENCODE: + switch (s->target) { + case V4L2_SEL_TGT_CROP: + /* Only support crop from (0,0) */ +@@ -1287,6 +1313,9 @@ static int vidioc_s_selection(struct fil + default: + return -EINVAL; + } ++ break; ++ case ISP: ++ break; + } + + return 0; +@@ -1490,7 +1519,7 @@ static int vidioc_try_decoder_cmd(struct + { + struct bcm2835_codec_ctx *ctx = file2ctx(file); + +- if (!ctx->dev->decode) ++ if (ctx->dev->role != DECODE) + return -EINVAL; + + switch (cmd->cmd) { +@@ -1564,7 +1593,7 @@ static int vidioc_try_encoder_cmd(struct + { + struct bcm2835_codec_ctx *ctx = file2ctx(file); + +- if (ctx->dev->decode) ++ if (ctx->dev->role != ENCODE) + return -EINVAL; + + switch (cmd->cmd) { +@@ -1697,12 +1726,11 @@ static int bcm2835_codec_create_componen + unsigned int enable = 1; + int ret; + +- ret = vchiq_mmal_component_init(dev->instance, dev->decode ? +- "ril.video_decode" : "ril.video_encode", ++ ret = vchiq_mmal_component_init(dev->instance, components[dev->role], + &ctx->component); + if (ret < 0) { +- v4l2_err(&dev->v4l2_dev, "%s: failed to create component for %s\n", +- __func__, dev->decode ? "decode" : "encode"); ++ v4l2_err(&dev->v4l2_dev, "%s: failed to create component %s\n", ++ __func__, components[dev->role]); + return -ENOMEM; + } + +@@ -1729,13 +1757,7 @@ static int bcm2835_codec_create_componen + if (ret < 0) + goto destroy_component; + +- if (dev->decode) { +- if (ctx->q_data[V4L2_M2M_DST].sizeimage < +- ctx->component->output[0].minimum_buffer.size) +- v4l2_err(&dev->v4l2_dev, "buffer size mismatch sizeimage %u < min size %u\n", +- ctx->q_data[V4L2_M2M_DST].sizeimage, +- ctx->component->output[0].minimum_buffer.size); +- } else { ++ if (dev->role == ENCODE) { + if (ctx->q_data[V4L2_M2M_SRC].sizeimage < + ctx->component->output[0].minimum_buffer.size) + v4l2_err(&dev->v4l2_dev, "buffer size mismatch sizeimage %u < min size %u\n", +@@ -1744,6 +1766,12 @@ static int bcm2835_codec_create_componen + + /* Now we have a component we can set all the ctrls */ + bcm2835_codec_set_ctrls(ctx); ++ } else { ++ if (ctx->q_data[V4L2_M2M_DST].sizeimage < ++ ctx->component->output[0].minimum_buffer.size) ++ v4l2_err(&dev->v4l2_dev, "buffer size mismatch sizeimage %u < min size %u\n", ++ ctx->q_data[V4L2_M2M_DST].sizeimage, ++ ctx->component->output[0].minimum_buffer.size); + } + + return 0; +@@ -2090,8 +2118,6 @@ static int bcm2835_codec_open(struct fil + struct v4l2_ctrl_handler *hdl; + int rc = 0; + +- v4l2_dbg(1, debug, &dev->v4l2_dev, "Creating instance for %s\n", +- dev->decode ? "decode" : "encode"); + if (mutex_lock_interruptible(&dev->dev_mutex)) { + v4l2_err(&dev->v4l2_dev, "Mutex fail\n"); + return -ERESTARTSYS; +@@ -2104,7 +2130,8 @@ static int bcm2835_codec_open(struct fil + + ctx->q_data[V4L2_M2M_SRC].fmt = get_default_format(dev, false); + ctx->q_data[V4L2_M2M_DST].fmt = get_default_format(dev, true); +- if (dev->decode) { ++ switch (dev->role) { ++ case DECODE: + /* + * Input width and height are irrelevant as they will be defined + * by the bitstream not the format. Required by V4L2 though. +@@ -2126,7 +2153,8 @@ static int bcm2835_codec_open(struct fil + get_sizeimage(ctx->q_data[V4L2_M2M_DST].bytesperline, + ctx->q_data[V4L2_M2M_DST].height, + ctx->q_data[V4L2_M2M_DST].fmt); +- } else { ++ break; ++ case ENCODE: + ctx->q_data[V4L2_M2M_SRC].crop_width = DEFAULT_WIDTH; + ctx->q_data[V4L2_M2M_SRC].crop_height = DEFAULT_HEIGHT; + ctx->q_data[V4L2_M2M_SRC].height = DEFAULT_HEIGHT; +@@ -2144,6 +2172,9 @@ static int bcm2835_codec_open(struct fil + ctx->q_data[V4L2_M2M_DST].height = DEFAULT_HEIGHT; + ctx->q_data[V4L2_M2M_DST].sizeimage = + DEF_COMP_BUF_SIZE_720P_OR_LESS; ++ break; ++ case ISP: ++ break; + } + + ctx->colorspace = V4L2_COLORSPACE_REC709; +@@ -2154,7 +2185,7 @@ static int bcm2835_codec_open(struct fil + file->private_data = &ctx->fh; + ctx->dev = dev; + hdl = &ctx->hdl; +- if (!dev->decode) { ++ if (dev->role == ENCODE) { + /* Encode controls */ + v4l2_ctrl_handler_init(hdl, 6); + +@@ -2303,14 +2334,11 @@ static int bcm2835_codec_get_supported_f + unsigned int i, j, num_encodings; + int ret; + +- ret = vchiq_mmal_component_init(dev->instance, +- dev->decode ? +- "ril.video_decode" : +- "ril.video_encode", ++ ret = vchiq_mmal_component_init(dev->instance, components[dev->role], + &component); + if (ret < 0) { +- v4l2_err(&dev->v4l2_dev, "%s: failed to create component\n", +- __func__); ++ v4l2_err(&dev->v4l2_dev, "%s: failed to create component %s\n", ++ __func__, components[dev->role]); + return -ENOMEM; + } + +@@ -2406,12 +2434,13 @@ destroy_component: + + static int bcm2835_codec_create(struct platform_device *pdev, + struct bcm2835_codec_dev **new_dev, +- bool decode) ++ enum bcm2835_codec_role role) + { + struct bcm2835_codec_dev *dev; + struct video_device *vfd; + int video_nr; + int ret; ++ const static char *roles[] = {"decode", "encode", "isp"}; + + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); + if (!dev) +@@ -2419,7 +2448,7 @@ static int bcm2835_codec_create(struct p + + dev->pdev = pdev; + +- dev->decode = decode; ++ dev->role = role; + + ret = vchiq_mmal_init(&dev->instance); + if (ret) +@@ -2441,14 +2470,27 @@ static int bcm2835_codec_create(struct p + vfd->lock = &dev->dev_mutex; + vfd->v4l2_dev = &dev->v4l2_dev; + +- if (dev->decode) { ++ switch (role) { ++ case DECODE: + v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD); + v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); + video_nr = decode_video_nr; +- } else { ++ break; ++ case ENCODE: + v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD); + v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD); + video_nr = encode_video_nr; ++ break; ++ case ISP: ++ v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD); ++ v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); ++ v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD); ++ v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD); ++ video_nr = isp_video_nr; ++ break; ++ default: ++ ret = -EINVAL; ++ goto unreg_dev; + } + + ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); +@@ -2473,7 +2515,7 @@ static int bcm2835_codec_create(struct p + } + + v4l2_info(&dev->v4l2_dev, "Loaded V4L2 %s\n", +- dev->decode ? "decode" : "encode"); ++ roles[role]); + return 0; + + err_m2m: +@@ -2509,11 +2551,15 @@ static int bcm2835_codec_probe(struct pl + if (!drv) + return -ENOMEM; + +- ret = bcm2835_codec_create(pdev, &drv->encode, false); ++ ret = bcm2835_codec_create(pdev, &drv->decode, DECODE); + if (ret) + goto out; + +- ret = bcm2835_codec_create(pdev, &drv->decode, true); ++ ret = bcm2835_codec_create(pdev, &drv->encode, ENCODE); ++ if (ret) ++ goto out; ++ ++ ret = bcm2835_codec_create(pdev, &drv->isp, ISP); + if (ret) + goto out; + +@@ -2526,6 +2572,10 @@ out: + bcm2835_codec_destroy(drv->encode); + drv->encode = NULL; + } ++ if (drv->decode) { ++ bcm2835_codec_destroy(drv->decode); ++ drv->decode = NULL; ++ } + return ret; + } + +@@ -2533,6 +2583,8 @@ static int bcm2835_codec_remove(struct p + { + struct bcm2835_codec_driver *drv = platform_get_drvdata(pdev); + ++ bcm2835_codec_destroy(drv->isp); ++ + bcm2835_codec_destroy(drv->encode); + + bcm2835_codec_destroy(drv->decode); diff --git a/target/linux/brcm2708/patches-4.19/950-0359-staging-mmal-vchiq-Always-return-the-param-size-from.patch b/target/linux/brcm2708/patches-4.19/950-0359-staging-mmal-vchiq-Always-return-the-param-size-from.patch deleted file mode 100644 index f43d5c4412..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0359-staging-mmal-vchiq-Always-return-the-param-size-from.patch +++ /dev/null @@ -1,38 +0,0 @@ -From c6d50172818f5fdc61d561ba9124c72a2ae49718 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 13 Feb 2019 12:36:56 +0000 -Subject: [PATCH 359/703] staging: mmal-vchiq: Always return the param size - from param_get - -mmal-vchiq is a reimplementation of the userland library for MMAL. -When getting a parameter, the client provides the storage and -the size of the storage. The VPU then returns the size of the -parameter that it wished to return, and as much as possible of -that parameter is returned to the client. - -The implementation previously only returned the size provided -by the VPU should it exceed the buffer size. So for parameters -such as the supported encodings list the client had no idea -how much of the provided storage had been populated. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -1413,11 +1413,12 @@ static int port_parameter_get(struct vch - */ - memcpy(value, &rmsg->u.port_parameter_get_reply.value, - *value_size); -- *value_size = rmsg->u.port_parameter_get_reply.size; - } else { - memcpy(value, &rmsg->u.port_parameter_get_reply.value, - rmsg->u.port_parameter_get_reply.size); - } -+ /* Always report the size of the returned parameter to the caller */ -+ *value_size = rmsg->u.port_parameter_get_reply.size; - - pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n", __func__, - ret, port->component->handle, port->handle, parameter_id); diff --git a/target/linux/brcm2708/patches-4.19/950-0360-staging-bcm2835_codec-Add-an-option-for-ignoring-Bay.patch b/target/linux/brcm2708/patches-4.19/950-0360-staging-bcm2835_codec-Add-an-option-for-ignoring-Bay.patch new file mode 100644 index 0000000000..f1119f5750 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0360-staging-bcm2835_codec-Add-an-option-for-ignoring-Bay.patch @@ -0,0 +1,179 @@ +From 262f0a84a1d213c703c4f527d569687bec912fe4 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 15 Feb 2019 11:36:14 +0000 +Subject: [PATCH 360/725] staging: bcm2835_codec: Add an option for ignoring + Bayer formats. + +This is a workaround for GStreamer currently not identifying Bayer +as a raw format, therefore any device that supports it does not +match the criteria for v4l2convert. + +Signed-off-by: Dave Stevenson +--- + .../bcm2835-codec/bcm2835-v4l2-codec.c | 29 ++++++++++++++++++- + 1 file changed, 28 insertions(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -58,6 +58,15 @@ static int isp_video_nr = 12; + module_param(isp_video_nr, int, 0644); + MODULE_PARM_DESC(isp_video_nr, "isp video device number"); + ++/* ++ * Workaround for GStreamer v4l2convert component not considering Bayer formats ++ * as raw, and therefore not considering a V4L2 device that supports them as ++ * as a suitable candidate. ++ */ ++static bool disable_bayer; ++module_param(disable_bayer, bool, 0644); ++MODULE_PARM_DESC(disable_bayer, "Disable support for Bayer formats"); ++ + static unsigned int debug; + module_param(debug, uint, 0644); + MODULE_PARM_DESC(debug, "activates debug info (0-3)"); +@@ -105,6 +114,7 @@ struct bcm2835_codec_fmt { + u32 flags; + u32 mmal_fmt; + int size_multiplier_x2; ++ bool is_bayer; + }; + + static const struct bcm2835_codec_fmt supported_formats[] = { +@@ -203,6 +213,7 @@ static const struct bcm2835_codec_fmt su + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB8, + .size_multiplier_x2 = 2, ++ .is_bayer = true, + }, { + .fourcc = V4L2_PIX_FMT_SBGGR8, + .depth = 8, +@@ -210,6 +221,7 @@ static const struct bcm2835_codec_fmt su + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR8, + .size_multiplier_x2 = 2, ++ .is_bayer = true, + }, { + .fourcc = V4L2_PIX_FMT_SGRBG8, + .depth = 8, +@@ -217,6 +229,7 @@ static const struct bcm2835_codec_fmt su + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG8, + .size_multiplier_x2 = 2, ++ .is_bayer = true, + }, { + .fourcc = V4L2_PIX_FMT_SGBRG8, + .depth = 8, +@@ -224,6 +237,7 @@ static const struct bcm2835_codec_fmt su + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG8, + .size_multiplier_x2 = 2, ++ .is_bayer = true, + }, { + /* 10 bit */ + .fourcc = V4L2_PIX_FMT_SRGGB10P, +@@ -232,6 +246,7 @@ static const struct bcm2835_codec_fmt su + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB10P, + .size_multiplier_x2 = 2, ++ .is_bayer = true, + }, { + .fourcc = V4L2_PIX_FMT_SBGGR10P, + .depth = 10, +@@ -239,6 +254,7 @@ static const struct bcm2835_codec_fmt su + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR10P, + .size_multiplier_x2 = 2, ++ .is_bayer = true, + }, { + .fourcc = V4L2_PIX_FMT_SGRBG10P, + .depth = 10, +@@ -246,6 +262,7 @@ static const struct bcm2835_codec_fmt su + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG10P, + .size_multiplier_x2 = 2, ++ .is_bayer = true, + }, { + .fourcc = V4L2_PIX_FMT_SGBRG10P, + .depth = 10, +@@ -253,6 +270,7 @@ static const struct bcm2835_codec_fmt su + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG10P, + .size_multiplier_x2 = 2, ++ .is_bayer = true, + }, { + /* 12 bit */ + .fourcc = V4L2_PIX_FMT_SRGGB12P, +@@ -261,6 +279,7 @@ static const struct bcm2835_codec_fmt su + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB12P, + .size_multiplier_x2 = 2, ++ .is_bayer = true, + }, { + .fourcc = V4L2_PIX_FMT_SBGGR12P, + .depth = 12, +@@ -268,6 +287,7 @@ static const struct bcm2835_codec_fmt su + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR12P, + .size_multiplier_x2 = 2, ++ .is_bayer = true, + }, { + .fourcc = V4L2_PIX_FMT_SGRBG12P, + .depth = 12, +@@ -275,6 +295,7 @@ static const struct bcm2835_codec_fmt su + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG12P, + .size_multiplier_x2 = 2, ++ .is_bayer = true, + }, { + .fourcc = V4L2_PIX_FMT_SGBRG12P, + .depth = 12, +@@ -282,6 +303,7 @@ static const struct bcm2835_codec_fmt su + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG12P, + .size_multiplier_x2 = 2, ++ .is_bayer = true, + }, { + /* 16 bit */ + .fourcc = V4L2_PIX_FMT_SRGGB16, +@@ -290,6 +312,7 @@ static const struct bcm2835_codec_fmt su + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB16, + .size_multiplier_x2 = 2, ++ .is_bayer = true, + }, { + .fourcc = V4L2_PIX_FMT_SBGGR16, + .depth = 16, +@@ -297,6 +320,7 @@ static const struct bcm2835_codec_fmt su + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR16, + .size_multiplier_x2 = 2, ++ .is_bayer = true, + }, { + .fourcc = V4L2_PIX_FMT_SGRBG16, + .depth = 16, +@@ -304,6 +328,7 @@ static const struct bcm2835_codec_fmt su + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG16, + .size_multiplier_x2 = 2, ++ .is_bayer = true, + }, { + .fourcc = V4L2_PIX_FMT_SGBRG16, + .depth = 16, +@@ -311,6 +336,7 @@ static const struct bcm2835_codec_fmt su + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG16, + .size_multiplier_x2 = 2, ++ .is_bayer = true, + }, { + /* Compressed formats */ + .fourcc = V4L2_PIX_FMT_H264, +@@ -438,7 +464,8 @@ static const struct bcm2835_codec_fmt *g + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(supported_formats); i++) { +- if (supported_formats[i].mmal_fmt == mmal_fmt) ++ if (supported_formats[i].mmal_fmt == mmal_fmt && ++ (!disable_bayer || !supported_formats[i].is_bayer)) + return &supported_formats[i]; + } + return NULL; diff --git a/target/linux/brcm2708/patches-4.19/950-0360-staging-mmal-vchiq-If-the-VPU-returns-an-error-don-t.patch b/target/linux/brcm2708/patches-4.19/950-0360-staging-mmal-vchiq-If-the-VPU-returns-an-error-don-t.patch deleted file mode 100644 index d9b3d7e77f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0360-staging-mmal-vchiq-If-the-VPU-returns-an-error-don-t.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 351eab98f47fae8172a91cb8d65237dd1fd41a11 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 13 Feb 2019 12:51:03 +0000 -Subject: [PATCH 360/703] staging: mmal-vchiq: If the VPU returns an error, - don't negate it - -There is an enum for the errors that the VPU can return. -port_parameter_get was negating that value, but also using -EINVAL -from the Linux error codes. -Pass the VPU error code as positive values. Should the function -need to pass a Linux failure, then return that as negative. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -1401,7 +1401,8 @@ static int port_parameter_get(struct vch - goto release_msg; - } - -- ret = -rmsg->u.port_parameter_get_reply.status; -+ ret = rmsg->u.port_parameter_get_reply.status; -+ - /* port_parameter_get_reply.size includes the header, - * whilst *value_size doesn't. - */ diff --git a/target/linux/brcm2708/patches-4.19/950-0361-staging-bcm2835_codec-Fix-handling-of-VB2_MEMORY_DMA.patch b/target/linux/brcm2708/patches-4.19/950-0361-staging-bcm2835_codec-Fix-handling-of-VB2_MEMORY_DMA.patch new file mode 100644 index 0000000000..1b7a2c1720 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0361-staging-bcm2835_codec-Fix-handling-of-VB2_MEMORY_DMA.patch @@ -0,0 +1,186 @@ +From bb88b7400187b6878bd077b8950d3b03dd5b1d02 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 15 Feb 2019 11:38:45 +0000 +Subject: [PATCH 361/725] staging: bcm2835_codec: Fix handling of + VB2_MEMORY_DMABUF buffers + +If the queue is configured as VB2_MEMORY_DMABUF then vb2_core_expbuf +fails as it ensures the queue is defined as VB2_MEMORY_MMAP. + +Correct the handling so that we unmap the buffer from vcsm and the +VPU on cleanup, and then correctly get the dma buf of the new buffer. + +Signed-off-by: Dave Stevenson +--- + .../bcm2835-codec/bcm2835-v4l2-codec.c | 80 +++++++++++++------ + .../vc04_services/vchiq-mmal/mmal-vchiq.c | 21 +++-- + .../vc04_services/vchiq-mmal/mmal-vchiq.h | 2 + + 3 files changed, 73 insertions(+), 30 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -1852,6 +1852,18 @@ static int bcm2835_codec_queue_setup(str + return 0; + } + ++static int bcm2835_codec_mmal_buf_cleanup(struct mmal_buffer *mmal_buf) ++{ ++ mmal_vchi_buffer_cleanup(mmal_buf); ++ ++ if (mmal_buf->dma_buf) { ++ dma_buf_put(mmal_buf->dma_buf); ++ mmal_buf->dma_buf = NULL; ++ } ++ ++ return 0; ++} ++ + static int bcm2835_codec_buf_init(struct vb2_buffer *vb) + { + struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); +@@ -1880,6 +1892,7 @@ static int bcm2835_codec_buf_prepare(str + vb); + struct m2m_mmal_buffer *buf = container_of(m2m, struct m2m_mmal_buffer, + m2m); ++ struct dma_buf *dma_buf; + int ret; + + v4l2_dbg(4, debug, &ctx->dev->v4l2_dev, "%s: type: %d ptr %p\n", +@@ -1906,20 +1919,48 @@ static int bcm2835_codec_buf_prepare(str + if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) + vb2_set_plane_payload(vb, 0, q_data->sizeimage); + +- /* +- * We want to do this at init, but vb2_core_expbuf checks that the +- * index < q->num_buffers, and q->num_buffers only gets updated once +- * all the buffers are allocated. +- */ +- if (!buf->mmal.dma_buf) { +- ret = vb2_core_expbuf_dmabuf(vb->vb2_queue, +- vb->vb2_queue->type, vb->index, 0, +- O_CLOEXEC, &buf->mmal.dma_buf); +- if (ret) +- v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed to expbuf idx %d, ret %d\n", +- __func__, vb->index, ret); +- } else { ++ switch (vb->memory) { ++ case VB2_MEMORY_DMABUF: ++ dma_buf = dma_buf_get(vb->planes[0].m.fd); ++ ++ if (dma_buf != buf->mmal.dma_buf) { ++ /* dmabuf either hasn't already been mapped, or it has ++ * changed. ++ */ ++ if (buf->mmal.dma_buf) { ++ v4l2_err(&ctx->dev->v4l2_dev, ++ "%s Buffer changed - why did the core not call cleanup?\n", ++ __func__); ++ bcm2835_codec_mmal_buf_cleanup(&buf->mmal); ++ } ++ ++ buf->mmal.dma_buf = dma_buf; ++ } + ret = 0; ++ break; ++ case VB2_MEMORY_MMAP: ++ /* ++ * We want to do this at init, but vb2_core_expbuf checks that ++ * the index < q->num_buffers, and q->num_buffers only gets ++ * updated once all the buffers are allocated. ++ */ ++ if (!buf->mmal.dma_buf) { ++ ret = vb2_core_expbuf_dmabuf(vb->vb2_queue, ++ vb->vb2_queue->type, ++ vb->index, 0, ++ O_CLOEXEC, ++ &buf->mmal.dma_buf); ++ if (ret) ++ v4l2_err(&ctx->dev->v4l2_dev, ++ "%s: Failed to expbuf idx %d, ret %d\n", ++ __func__, vb->index, ret); ++ } else { ++ ret = 0; ++ } ++ break; ++ default: ++ ret = -EINVAL; ++ break; + } + + return ret; +@@ -1948,12 +1989,7 @@ static void bcm2835_codec_buffer_cleanup + v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: ctx:%p, vb %p\n", + __func__, ctx, vb); + +- mmal_vchi_buffer_cleanup(&buf->mmal); +- +- if (buf->mmal.dma_buf) { +- dma_buf_put(buf->mmal.dma_buf); +- buf->mmal.dma_buf = NULL; +- } ++ bcm2835_codec_mmal_buf_cleanup(&buf->mmal); + } + + static int bcm2835_codec_start_streaming(struct vb2_queue *q, +@@ -2067,11 +2103,7 @@ static void bcm2835_codec_stop_streaming + m2m = container_of(vb2, struct v4l2_m2m_buffer, vb); + buf = container_of(m2m, struct m2m_mmal_buffer, m2m); + +- mmal_vchi_buffer_cleanup(&buf->mmal); +- if (buf->mmal.dma_buf) { +- dma_buf_put(buf->mmal.dma_buf); +- buf->mmal.dma_buf = NULL; +- } ++ bcm2835_codec_mmal_buf_cleanup(&buf->mmal); + } + + /* If both ports disabled, then disable the component */ +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +@@ -1785,13 +1785,9 @@ int mmal_vchi_buffer_init(struct vchiq_m + } + EXPORT_SYMBOL_GPL(mmal_vchi_buffer_init); + +-int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf) ++int mmal_vchi_buffer_unmap(struct mmal_buffer *buf) + { +- struct mmal_msg_context *msg_context = buf->msg_context; +- +- if (msg_context) +- release_msg_context(msg_context); +- buf->msg_context = NULL; ++ int ret = 0; + + if (buf->vcsm_handle) { + int ret; +@@ -1803,6 +1799,19 @@ int mmal_vchi_buffer_cleanup(struct mmal + pr_err("%s: vcsm_free failed, ret %d\n", __func__, ret); + buf->vcsm_handle = 0; + } ++ return ret; ++} ++EXPORT_SYMBOL_GPL(mmal_vchi_buffer_unmap); ++ ++int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf) ++{ ++ struct mmal_msg_context *msg_context = buf->msg_context; ++ ++ if (msg_context) ++ release_msg_context(msg_context); ++ buf->msg_context = NULL; ++ ++ mmal_vchi_buffer_unmap(buf); + return 0; + } + EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup); +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h +@@ -167,6 +167,8 @@ int vchiq_mmal_submit_buffer(struct vchi + struct vchiq_mmal_port *port, + struct mmal_buffer *buf); + ++int mmal_vchi_buffer_unmap(struct mmal_buffer *buf); ++ + int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance, + struct mmal_buffer *buf); + int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf); diff --git a/target/linux/brcm2708/patches-4.19/950-0361-staging-bcm2835_codec-Query-supported-formats-from-t.patch b/target/linux/brcm2708/patches-4.19/950-0361-staging-bcm2835_codec-Query-supported-formats-from-t.patch deleted file mode 100644 index e4b7981c29..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0361-staging-bcm2835_codec-Query-supported-formats-from-t.patch +++ /dev/null @@ -1,727 +0,0 @@ -From 467255263f6d2c85b43a98300d283869d72a3ac3 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 13 Feb 2019 13:44:00 +0000 -Subject: [PATCH 361/703] staging: bcm2835_codec: Query supported formats from - the component - -The driver was previously working with hard coded tables of -which video formats were supported by each component. -The components advertise this information via a MMAL parameter, -so retrieve the information from there during probe, and store -in the state structure for that device. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 455 +++++++++++++----- - 1 file changed, 327 insertions(+), 128 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -88,17 +88,12 @@ struct bcm2835_codec_fmt { - int bytesperline_align; - u32 flags; - u32 mmal_fmt; -- bool decode_only; -- bool encode_only; - int size_multiplier_x2; - }; - --/* Supported raw pixel formats. Those supported for both encode and decode -- * must come first, with those only supported for decode coming after (there -- * are no formats supported for encode only). -- */ --static struct bcm2835_codec_fmt raw_formats[] = { -+static const struct bcm2835_codec_fmt supported_formats[] = { - { -+ /* YUV formats */ - .fourcc = V4L2_PIX_FMT_YUV420, - .depth = 8, - .bytesperline_align = 32, -@@ -139,7 +134,6 @@ static struct bcm2835_codec_fmt raw_form - .bytesperline_align = 32, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_YUYV, -- .encode_only = true, - .size_multiplier_x2 = 2, - }, { - .fourcc = V4L2_PIX_FMT_UYVY, -@@ -147,7 +141,6 @@ static struct bcm2835_codec_fmt raw_form - .bytesperline_align = 32, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_UYVY, -- .encode_only = true, - .size_multiplier_x2 = 2, - }, { - .fourcc = V4L2_PIX_FMT_YVYU, -@@ -155,7 +148,6 @@ static struct bcm2835_codec_fmt raw_form - .bytesperline_align = 32, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_YVYU, -- .encode_only = true, - .size_multiplier_x2 = 2, - }, { - .fourcc = V4L2_PIX_FMT_VYUY, -@@ -163,15 +155,14 @@ static struct bcm2835_codec_fmt raw_form - .bytesperline_align = 32, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_VYUY, -- .encode_only = true, - .size_multiplier_x2 = 2, - }, { -+ /* RGB formats */ - .fourcc = V4L2_PIX_FMT_RGB24, - .depth = 24, - .bytesperline_align = 32, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_RGB24, -- .encode_only = true, - .size_multiplier_x2 = 2, - }, { - .fourcc = V4L2_PIX_FMT_BGR24, -@@ -179,7 +170,6 @@ static struct bcm2835_codec_fmt raw_form - .bytesperline_align = 32, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BGR24, -- .encode_only = true, - .size_multiplier_x2 = 2, - }, { - .fourcc = V4L2_PIX_FMT_BGR32, -@@ -187,17 +177,126 @@ static struct bcm2835_codec_fmt raw_form - .bytesperline_align = 32, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BGRA, -- .encode_only = true, - .size_multiplier_x2 = 2, -- }, --}; -- --/* Supported encoded formats. Those supported for both encode and decode -- * must come first, with those only supported for decode coming after (there -- * are no formats supported for encode only). -- */ --static struct bcm2835_codec_fmt encoded_formats[] = { -- { -+ }, { -+ /* Bayer formats */ -+ /* 8 bit */ -+ .fourcc = V4L2_PIX_FMT_SRGGB8, -+ .depth = 8, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB8, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SBGGR8, -+ .depth = 8, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR8, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGRBG8, -+ .depth = 8, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG8, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGBRG8, -+ .depth = 8, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG8, -+ .size_multiplier_x2 = 2, -+ }, { -+ /* 10 bit */ -+ .fourcc = V4L2_PIX_FMT_SRGGB10P, -+ .depth = 10, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB10P, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SBGGR10P, -+ .depth = 10, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR10P, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGRBG10P, -+ .depth = 10, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG10P, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGBRG10P, -+ .depth = 10, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG10P, -+ .size_multiplier_x2 = 2, -+ }, { -+ /* 12 bit */ -+ .fourcc = V4L2_PIX_FMT_SRGGB12P, -+ .depth = 12, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB12P, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SBGGR12P, -+ .depth = 12, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR12P, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGRBG12P, -+ .depth = 12, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG12P, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGBRG12P, -+ .depth = 12, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG12P, -+ .size_multiplier_x2 = 2, -+ }, { -+ /* 16 bit */ -+ .fourcc = V4L2_PIX_FMT_SRGGB16, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB16, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SBGGR16, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR16, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGRBG16, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG16, -+ .size_multiplier_x2 = 2, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGBRG16, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG16, -+ .size_multiplier_x2 = 2, -+ }, { -+ /* Compressed formats */ - .fourcc = V4L2_PIX_FMT_H264, - .depth = 0, - .flags = V4L2_FMT_FLAG_COMPRESSED, -@@ -212,30 +311,22 @@ static struct bcm2835_codec_fmt encoded_ - .depth = 0, - .flags = V4L2_FMT_FLAG_COMPRESSED, - .mmal_fmt = MMAL_ENCODING_MP4V, -- .decode_only = true, - }, { - .fourcc = V4L2_PIX_FMT_H263, - .depth = 0, - .flags = V4L2_FMT_FLAG_COMPRESSED, - .mmal_fmt = MMAL_ENCODING_H263, -- .decode_only = true, - }, { - .fourcc = V4L2_PIX_FMT_MPEG2, - .depth = 0, - .flags = V4L2_FMT_FLAG_COMPRESSED, - .mmal_fmt = MMAL_ENCODING_MP2V, -- .decode_only = true, - }, { - .fourcc = V4L2_PIX_FMT_VP8, - .depth = 0, - .flags = V4L2_FMT_FLAG_COMPRESSED, - .mmal_fmt = MMAL_ENCODING_VP8, -- .decode_only = true, - }, -- /* -- * This list couold include VP6 and Theorafor decode, but V4L2 doesn't -- * support them. -- */ - }; - - struct bcm2835_codec_fmt_list { -@@ -243,19 +334,6 @@ struct bcm2835_codec_fmt_list { - unsigned int num_entries; - }; - --#define RAW_LIST 0 --#define ENCODED_LIST 1 -- --struct bcm2835_codec_fmt_list formats[] = { -- { -- .list = raw_formats, -- .num_entries = ARRAY_SIZE(raw_formats), -- }, { -- .list = encoded_formats, -- .num_entries = ARRAY_SIZE(encoded_formats), -- }, --}; -- - struct m2m_mmal_buffer { - struct v4l2_m2m_buffer m2m; - struct mmal_buffer mmal; -@@ -284,52 +362,6 @@ struct bcm2835_codec_q_data { - bool eos_buffer_in_use; /* debug only */ - }; - --enum { -- V4L2_M2M_SRC = 0, -- V4L2_M2M_DST = 1, --}; -- --static inline struct bcm2835_codec_fmt_list *get_format_list(bool decode, -- bool capture) --{ -- return decode ^ capture ? &formats[ENCODED_LIST] : &formats[RAW_LIST]; --} -- --static struct bcm2835_codec_fmt *get_default_format(bool decode, bool capture) --{ -- return &get_format_list(decode, capture)->list[0]; --} -- --static struct bcm2835_codec_fmt *find_format(struct v4l2_format *f, bool decode, -- bool capture) --{ -- struct bcm2835_codec_fmt *fmt; -- unsigned int k; -- struct bcm2835_codec_fmt_list *fmts = get_format_list(decode, capture); -- -- for (k = 0; k < fmts->num_entries; k++) { -- fmt = &fmts->list[k]; -- if (fmt->fourcc == f->fmt.pix.pixelformat) -- break; -- } -- -- /* -- * Some compressed formats are only supported for decoding, not -- * encoding. -- */ -- if (!decode && fmts->list[k].decode_only) -- return NULL; -- -- /* Some pixel formats are only supported for encoding, not decoding. */ -- if (decode && fmts->list[k].encode_only) -- return NULL; -- -- if (k == fmts->num_entries) -- return NULL; -- -- return &fmts->list[k]; --} -- - struct bcm2835_codec_dev { - struct platform_device *pdev; - -@@ -342,6 +374,9 @@ struct bcm2835_codec_dev { - - /* allocated mmal instance and components */ - bool decode; /* Is this instance a decoder? */ -+ /* The list of formats supported on input and output queues. */ -+ struct bcm2835_codec_fmt_list supported_fmts[2]; -+ - struct vchiq_mmal_instance *instance; - - struct v4l2_m2m_dev *m2m_dev; -@@ -374,8 +409,59 @@ struct bcm2835_codec_ctx { - struct bcm2835_codec_driver { - struct bcm2835_codec_dev *encode; - struct bcm2835_codec_dev *decode; -+ struct bcm2835_codec_dev *isp; -+}; -+ -+enum { -+ V4L2_M2M_SRC = 0, -+ V4L2_M2M_DST = 1, - }; - -+static const struct bcm2835_codec_fmt *get_fmt(u32 mmal_fmt) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < ARRAY_SIZE(supported_formats); i++) { -+ if (supported_formats[i].mmal_fmt == mmal_fmt) -+ return &supported_formats[i]; -+ } -+ return NULL; -+} -+ -+static inline -+struct bcm2835_codec_fmt_list *get_format_list(struct bcm2835_codec_dev *dev, -+ bool capture) -+{ -+ return &dev->supported_fmts[capture ? 1 : 0]; -+} -+ -+static -+struct bcm2835_codec_fmt *get_default_format(struct bcm2835_codec_dev *dev, -+ bool capture) -+{ -+ return &dev->supported_fmts[capture ? 1 : 0].list[0]; -+} -+ -+static struct bcm2835_codec_fmt *find_format(struct v4l2_format *f, -+ struct bcm2835_codec_dev *dev, -+ bool capture) -+{ -+ struct bcm2835_codec_fmt *fmt; -+ unsigned int k; -+ struct bcm2835_codec_fmt_list *fmts = -+ &dev->supported_fmts[capture ? 1 : 0]; -+ -+ for (k = 0; k < fmts->num_entries; k++) { -+ fmt = &fmts->list[k]; -+ if (fmt->fourcc == f->fmt.pix.pixelformat) -+ break; -+ } -+ if (k == fmts->num_entries) -+ return NULL; -+ -+ return &fmts->list[k]; -+} -+ - static inline struct bcm2835_codec_ctx *file2ctx(struct file *file) - { - return container_of(file->private_data, struct bcm2835_codec_ctx, fh); -@@ -456,7 +542,6 @@ static inline unsigned int get_bytesperl - } - - static void setup_mmal_port_format(struct bcm2835_codec_ctx *ctx, -- bool decode, - struct bcm2835_codec_q_data *q_data, - struct vchiq_mmal_port *port) - { -@@ -473,7 +558,7 @@ static void setup_mmal_port_format(struc - port->es.video.frame_rate.den = 1; - } else { - /* Compressed format - leave resolution as 0 for decode */ -- if (decode) { -+ if (ctx->dev->decode) { - port->es.video.width = 0; - port->es.video.height = 0; - port->es.video.crop.width = 0; -@@ -802,22 +887,15 @@ static int vidioc_querycap(struct file * - return 0; - } - --static int enum_fmt(struct v4l2_fmtdesc *f, bool decode, bool capture) -+static int enum_fmt(struct v4l2_fmtdesc *f, struct bcm2835_codec_ctx *ctx, -+ bool capture) - { - struct bcm2835_codec_fmt *fmt; -- struct bcm2835_codec_fmt_list *fmts = get_format_list(decode, capture); -+ struct bcm2835_codec_fmt_list *fmts = -+ get_format_list(ctx->dev, capture); - - if (f->index < fmts->num_entries) { - /* Format found */ -- /* Check format isn't a decode only format when encoding */ -- if (!decode && -- fmts->list[f->index].decode_only) -- return -EINVAL; -- /* Check format isn't a decode only format when encoding */ -- if (decode && -- fmts->list[f->index].encode_only) -- return -EINVAL; -- - fmt = &fmts->list[f->index]; - f->pixelformat = fmt->fourcc; - f->flags = fmt->flags; -@@ -833,7 +911,7 @@ static int vidioc_enum_fmt_vid_cap(struc - { - struct bcm2835_codec_ctx *ctx = file2ctx(file); - -- return enum_fmt(f, ctx->dev->decode, true); -+ return enum_fmt(f, ctx, true); - } - - static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, -@@ -841,7 +919,7 @@ static int vidioc_enum_fmt_vid_out(struc - { - struct bcm2835_codec_ctx *ctx = file2ctx(file); - -- return enum_fmt(f, ctx->dev->decode, false); -+ return enum_fmt(f, ctx, false); - } - - static int vidioc_g_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f) -@@ -933,11 +1011,11 @@ static int vidioc_try_fmt_vid_cap(struct - struct bcm2835_codec_fmt *fmt; - struct bcm2835_codec_ctx *ctx = file2ctx(file); - -- fmt = find_format(f, ctx->dev->decode, true); -+ fmt = find_format(f, ctx->dev, true); - if (!fmt) { -- f->fmt.pix.pixelformat = get_default_format(ctx->dev->decode, -+ f->fmt.pix.pixelformat = get_default_format(ctx->dev, - true)->fourcc; -- fmt = find_format(f, ctx->dev->decode, true); -+ fmt = find_format(f, ctx->dev, true); - } - - return vidioc_try_fmt(f, fmt); -@@ -949,11 +1027,11 @@ static int vidioc_try_fmt_vid_out(struct - struct bcm2835_codec_fmt *fmt; - struct bcm2835_codec_ctx *ctx = file2ctx(file); - -- fmt = find_format(f, ctx->dev->decode, false); -+ fmt = find_format(f, ctx->dev, false); - if (!fmt) { -- f->fmt.pix.pixelformat = get_default_format(ctx->dev->decode, -+ f->fmt.pix.pixelformat = get_default_format(ctx->dev, - false)->fourcc; -- fmt = find_format(f, ctx->dev->decode, false); -+ fmt = find_format(f, ctx->dev, false); - } - - if (!f->fmt.pix.colorspace) -@@ -988,7 +1066,7 @@ static int vidioc_s_fmt(struct bcm2835_c - return -EBUSY; - } - -- q_data->fmt = find_format(f, ctx->dev->decode, -+ q_data->fmt = find_format(f, ctx->dev, - f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE); - q_data->crop_width = f->fmt.pix.width; - q_data->height = f->fmt.pix.height; -@@ -1041,7 +1119,7 @@ static int vidioc_s_fmt(struct bcm2835_c - if (!port) - return 0; - -- setup_mmal_port_format(ctx, ctx->dev->decode, q_data, port); -+ setup_mmal_port_format(ctx, q_data, port); - ret = vchiq_mmal_port_set_format(ctx->dev->instance, port); - if (ret) { - v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed vchiq_mmal_port_set_format on port, ret %d\n", -@@ -1064,8 +1142,7 @@ static int vidioc_s_fmt(struct bcm2835_c - struct bcm2835_codec_q_data *q_data_dst = - &ctx->q_data[V4L2_M2M_DST]; - -- setup_mmal_port_format(ctx, ctx->dev->decode, q_data_dst, -- port_dst); -+ setup_mmal_port_format(ctx, q_data_dst, port_dst); - ret = vchiq_mmal_port_set_format(ctx->dev->instance, port_dst); - if (ret) { - v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed vchiq_mmal_port_set_format on output port, ret %d\n", -@@ -1636,10 +1713,10 @@ static int bcm2835_codec_create_componen - MMAL_PARAMETER_ZERO_COPY, &enable, - sizeof(enable)); - -- setup_mmal_port_format(ctx, dev->decode, &ctx->q_data[V4L2_M2M_SRC], -+ setup_mmal_port_format(ctx, &ctx->q_data[V4L2_M2M_SRC], - &ctx->component->input[0]); - -- setup_mmal_port_format(ctx, dev->decode, &ctx->q_data[V4L2_M2M_DST], -+ setup_mmal_port_format(ctx, &ctx->q_data[V4L2_M2M_DST], - &ctx->component->output[0]); - - ret = vchiq_mmal_port_set_format(dev->instance, -@@ -2025,8 +2102,8 @@ static int bcm2835_codec_open(struct fil - goto open_unlock; - } - -- ctx->q_data[V4L2_M2M_SRC].fmt = get_default_format(dev->decode, false); -- ctx->q_data[V4L2_M2M_DST].fmt = get_default_format(dev->decode, true); -+ ctx->q_data[V4L2_M2M_SRC].fmt = get_default_format(dev, false); -+ ctx->q_data[V4L2_M2M_DST].fmt = get_default_format(dev, true); - if (dev->decode) { - /* - * Input width and height are irrelevant as they will be defined -@@ -2209,13 +2286,130 @@ static const struct v4l2_m2m_ops m2m_ops - .job_abort = job_abort, - }; - -+/* Size of the array to provide to the VPU when asking for the list of supported -+ * formats. -+ * The ISP component currently advertises 33 input formats, so add a small -+ * overhead on that. -+ */ -+#define MAX_SUPPORTED_ENCODINGS 40 -+ -+/* Populate dev->supported_fmts with the formats supported by those ports. */ -+static int bcm2835_codec_get_supported_fmts(struct bcm2835_codec_dev *dev) -+{ -+ struct bcm2835_codec_fmt *list; -+ struct vchiq_mmal_component *component; -+ u32 fourccs[MAX_SUPPORTED_ENCODINGS]; -+ u32 param_size = sizeof(fourccs); -+ unsigned int i, j, num_encodings; -+ int ret; -+ -+ ret = vchiq_mmal_component_init(dev->instance, -+ dev->decode ? -+ "ril.video_decode" : -+ "ril.video_encode", -+ &component); -+ if (ret < 0) { -+ v4l2_err(&dev->v4l2_dev, "%s: failed to create component\n", -+ __func__); -+ return -ENOMEM; -+ } -+ -+ ret = vchiq_mmal_port_parameter_get(dev->instance, -+ &component->input[0], -+ MMAL_PARAMETER_SUPPORTED_ENCODINGS, -+ &fourccs, -+ ¶m_size); -+ -+ if (ret) { -+ if (ret == MMAL_MSG_STATUS_ENOSPC) { -+ v4l2_err(&dev->v4l2_dev, "%s: port has more encoding than we provided space for. Some are dropped.\n", -+ __func__); -+ num_encodings = MAX_SUPPORTED_ENCODINGS; -+ } else { -+ v4l2_err(&dev->v4l2_dev, "%s: get_param ret %u.\n", -+ __func__, ret); -+ ret = -EINVAL; -+ goto destroy_component; -+ } -+ } else { -+ num_encodings = param_size / sizeof(u32); -+ } -+ -+ /* Assume at this stage that all encodings will be supported in V4L2. -+ * Any that aren't supported will waste a very small amount of memory. -+ */ -+ list = devm_kzalloc(&dev->pdev->dev, -+ sizeof(struct bcm2835_codec_fmt) * num_encodings, -+ GFP_KERNEL); -+ if (!list) { -+ ret = -ENOMEM; -+ goto destroy_component; -+ } -+ dev->supported_fmts[0].list = list; -+ -+ for (i = 0, j = 0; i < num_encodings; i++) { -+ const struct bcm2835_codec_fmt *fmt = get_fmt(fourccs[i]); -+ -+ if (fmt) { -+ list[j] = *fmt; -+ j++; -+ } -+ } -+ dev->supported_fmts[0].num_entries = j; -+ -+ param_size = sizeof(fourccs); -+ ret = vchiq_mmal_port_parameter_get(dev->instance, -+ &component->output[0], -+ MMAL_PARAMETER_SUPPORTED_ENCODINGS, -+ &fourccs, -+ ¶m_size); -+ -+ if (ret) { -+ if (ret == MMAL_MSG_STATUS_ENOSPC) { -+ v4l2_err(&dev->v4l2_dev, "%s: port has more encoding than we provided space for. Some are dropped.\n", -+ __func__); -+ num_encodings = MAX_SUPPORTED_ENCODINGS; -+ } else { -+ ret = -EINVAL; -+ goto destroy_component; -+ } -+ } else { -+ num_encodings = param_size / sizeof(u32); -+ } -+ /* Assume at this stage that all encodings will be supported in V4L2. */ -+ list = devm_kzalloc(&dev->pdev->dev, -+ sizeof(struct bcm2835_codec_fmt) * num_encodings, -+ GFP_KERNEL); -+ if (!list) { -+ ret = -ENOMEM; -+ goto destroy_component; -+ } -+ dev->supported_fmts[1].list = list; -+ -+ for (i = 0, j = 0; i < num_encodings; i++) { -+ const struct bcm2835_codec_fmt *fmt = get_fmt(fourccs[i]); -+ -+ if (fmt) { -+ list[j] = *fmt; -+ j++; -+ } -+ } -+ dev->supported_fmts[1].num_entries = j; -+ -+ ret = 0; -+ -+destroy_component: -+ vchiq_mmal_component_finalise(dev->instance, component); -+ -+ return ret; -+} -+ - static int bcm2835_codec_create(struct platform_device *pdev, - struct bcm2835_codec_dev **new_dev, - bool decode) - { - struct bcm2835_codec_dev *dev; - struct video_device *vfd; -- struct vchiq_mmal_instance *instance = NULL; - int video_nr; - int ret; - -@@ -2227,10 +2421,18 @@ static int bcm2835_codec_create(struct p - - dev->decode = decode; - -- ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); -+ ret = vchiq_mmal_init(&dev->instance); - if (ret) - return ret; - -+ ret = bcm2835_codec_get_supported_fmts(dev); -+ if (ret) -+ goto vchiq_finalise; -+ -+ ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); -+ if (ret) -+ goto vchiq_finalise; -+ - atomic_set(&dev->num_inst, 0); - mutex_init(&dev->dev_mutex); - -@@ -2270,12 +2472,7 @@ static int bcm2835_codec_create(struct p - goto err_m2m; - } - -- ret = vchiq_mmal_init(&instance); -- if (ret < 0) -- goto err_m2m; -- dev->instance = instance; -- -- v4l2_info(&dev->v4l2_dev, "Loaded V4L2 %s codec\n", -+ v4l2_info(&dev->v4l2_dev, "Loaded V4L2 %s\n", - dev->decode ? "decode" : "encode"); - return 0; - -@@ -2284,7 +2481,8 @@ err_m2m: - video_unregister_device(&dev->vfd); - unreg_dev: - v4l2_device_unregister(&dev->v4l2_dev); -- -+vchiq_finalise: -+ vchiq_mmal_finalise(dev->instance); - return ret; - } - -@@ -2297,6 +2495,7 @@ static int bcm2835_codec_destroy(struct - v4l2_m2m_release(dev->m2m_dev); - video_unregister_device(&dev->vfd); - v4l2_device_unregister(&dev->v4l2_dev); -+ vchiq_mmal_finalise(dev->instance); - - return 0; - } diff --git a/target/linux/brcm2708/patches-4.19/950-0362-staging-bcm2835_codec-Add-support-for-the-ISP-as-an-.patch b/target/linux/brcm2708/patches-4.19/950-0362-staging-bcm2835_codec-Add-support-for-the-ISP-as-an-.patch deleted file mode 100644 index 4a83858c5f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0362-staging-bcm2835_codec-Add-support-for-the-ISP-as-an-.patch +++ /dev/null @@ -1,384 +0,0 @@ -From dd3aa42c6ca22eae1b91f78f6de85935bcd6ab0e Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 13 Feb 2019 14:07:52 +0000 -Subject: [PATCH 362/703] staging: bcm2835_codec: Add support for the ISP as an - M2M device - -The MMAL ISP component can also use this same V4L2 wrapper to -provide a M2M format conversion and resizer. -Instantiate 3 V4L2 devices now, one for each of decode, encode, -and isp. -The ISP currently doesn't expose any controls via V4L2, but this -can be extended in the future. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 132 ++++++++++++------ - 1 file changed, 92 insertions(+), 40 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -54,10 +54,26 @@ static int encode_video_nr = 11; - module_param(encode_video_nr, int, 0644); - MODULE_PARM_DESC(encode_video_nr, "encoder video device number"); - -+static int isp_video_nr = 12; -+module_param(isp_video_nr, int, 0644); -+MODULE_PARM_DESC(isp_video_nr, "isp video device number"); -+ - static unsigned int debug; - module_param(debug, uint, 0644); - MODULE_PARM_DESC(debug, "activates debug info (0-3)"); - -+enum bcm2835_codec_role { -+ DECODE, -+ ENCODE, -+ ISP, -+}; -+ -+static const char * const components[] = { -+ "ril.video_decode", -+ "ril.video_encode", -+ "ril.isp", -+}; -+ - #define MIN_W 32 - #define MIN_H 32 - #define MAX_W 1920 -@@ -373,7 +389,7 @@ struct bcm2835_codec_dev { - atomic_t num_inst; - - /* allocated mmal instance and components */ -- bool decode; /* Is this instance a decoder? */ -+ enum bcm2835_codec_role role; - /* The list of formats supported on input and output queues. */ - struct bcm2835_codec_fmt_list supported_fmts[2]; - -@@ -558,7 +574,7 @@ static void setup_mmal_port_format(struc - port->es.video.frame_rate.den = 1; - } else { - /* Compressed format - leave resolution as 0 for decode */ -- if (ctx->dev->decode) { -+ if (ctx->dev->role == DECODE) { - port->es.video.width = 0; - port->es.video.height = 0; - port->es.video.crop.width = 0; -@@ -1089,7 +1105,8 @@ static int vidioc_s_fmt(struct bcm2835_c - v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Calulated bpl as %u, size %u\n", - q_data->bytesperline, q_data->sizeimage); - -- if (ctx->dev->decode && q_data->fmt->flags & V4L2_FMT_FLAG_COMPRESSED && -+ if (ctx->dev->role == DECODE && -+ q_data->fmt->flags & V4L2_FMT_FLAG_COMPRESSED && - f->fmt.pix.width && f->fmt.pix.height) { - /* - * On the decoder, if provided with a resolution on the input -@@ -1188,7 +1205,8 @@ static int vidioc_g_selection(struct fil - bool capture_queue = s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? - true : false; - -- if (capture_queue ^ ctx->dev->decode) -+ if ((ctx->dev->role == DECODE && !capture_queue) || -+ (ctx->dev->role == ENCODE && capture_queue)) - /* OUTPUT on decoder and CAPTURE on encoder are not valid. */ - return -EINVAL; - -@@ -1196,7 +1214,8 @@ static int vidioc_g_selection(struct fil - if (!q_data) - return -EINVAL; - -- if (ctx->dev->decode) { -+ switch (ctx->dev->role) { -+ case DECODE: - switch (s->target) { - case V4L2_SEL_TGT_COMPOSE_DEFAULT: - case V4L2_SEL_TGT_COMPOSE: -@@ -1214,7 +1233,8 @@ static int vidioc_g_selection(struct fil - default: - return -EINVAL; - } -- } else { -+ break; -+ case ENCODE: - switch (s->target) { - case V4L2_SEL_TGT_CROP_DEFAULT: - case V4L2_SEL_TGT_CROP_BOUNDS: -@@ -1232,6 +1252,9 @@ static int vidioc_g_selection(struct fil - default: - return -EINVAL; - } -+ break; -+ case ISP: -+ break; - } - - return 0; -@@ -1249,7 +1272,8 @@ static int vidioc_s_selection(struct fil - __func__, ctx, s->type, q_data, s->target, s->r.left, s->r.top, - s->r.width, s->r.height); - -- if (capture_queue ^ ctx->dev->decode) -+ if ((ctx->dev->role == DECODE && !capture_queue) || -+ (ctx->dev->role == ENCODE && capture_queue)) - /* OUTPUT on decoder and CAPTURE on encoder are not valid. */ - return -EINVAL; - -@@ -1257,7 +1281,8 @@ static int vidioc_s_selection(struct fil - if (!q_data) - return -EINVAL; - -- if (ctx->dev->decode) { -+ switch (ctx->dev->role) { -+ case DECODE: - switch (s->target) { - case V4L2_SEL_TGT_COMPOSE: - /* Accept cropped image */ -@@ -1272,7 +1297,8 @@ static int vidioc_s_selection(struct fil - default: - return -EINVAL; - } -- } else { -+ break; -+ case ENCODE: - switch (s->target) { - case V4L2_SEL_TGT_CROP: - /* Only support crop from (0,0) */ -@@ -1287,6 +1313,9 @@ static int vidioc_s_selection(struct fil - default: - return -EINVAL; - } -+ break; -+ case ISP: -+ break; - } - - return 0; -@@ -1490,7 +1519,7 @@ static int vidioc_try_decoder_cmd(struct - { - struct bcm2835_codec_ctx *ctx = file2ctx(file); - -- if (!ctx->dev->decode) -+ if (ctx->dev->role != DECODE) - return -EINVAL; - - switch (cmd->cmd) { -@@ -1564,7 +1593,7 @@ static int vidioc_try_encoder_cmd(struct - { - struct bcm2835_codec_ctx *ctx = file2ctx(file); - -- if (ctx->dev->decode) -+ if (ctx->dev->role != ENCODE) - return -EINVAL; - - switch (cmd->cmd) { -@@ -1697,12 +1726,11 @@ static int bcm2835_codec_create_componen - unsigned int enable = 1; - int ret; - -- ret = vchiq_mmal_component_init(dev->instance, dev->decode ? -- "ril.video_decode" : "ril.video_encode", -+ ret = vchiq_mmal_component_init(dev->instance, components[dev->role], - &ctx->component); - if (ret < 0) { -- v4l2_err(&dev->v4l2_dev, "%s: failed to create component for %s\n", -- __func__, dev->decode ? "decode" : "encode"); -+ v4l2_err(&dev->v4l2_dev, "%s: failed to create component %s\n", -+ __func__, components[dev->role]); - return -ENOMEM; - } - -@@ -1729,13 +1757,7 @@ static int bcm2835_codec_create_componen - if (ret < 0) - goto destroy_component; - -- if (dev->decode) { -- if (ctx->q_data[V4L2_M2M_DST].sizeimage < -- ctx->component->output[0].minimum_buffer.size) -- v4l2_err(&dev->v4l2_dev, "buffer size mismatch sizeimage %u < min size %u\n", -- ctx->q_data[V4L2_M2M_DST].sizeimage, -- ctx->component->output[0].minimum_buffer.size); -- } else { -+ if (dev->role == ENCODE) { - if (ctx->q_data[V4L2_M2M_SRC].sizeimage < - ctx->component->output[0].minimum_buffer.size) - v4l2_err(&dev->v4l2_dev, "buffer size mismatch sizeimage %u < min size %u\n", -@@ -1744,6 +1766,12 @@ static int bcm2835_codec_create_componen - - /* Now we have a component we can set all the ctrls */ - bcm2835_codec_set_ctrls(ctx); -+ } else { -+ if (ctx->q_data[V4L2_M2M_DST].sizeimage < -+ ctx->component->output[0].minimum_buffer.size) -+ v4l2_err(&dev->v4l2_dev, "buffer size mismatch sizeimage %u < min size %u\n", -+ ctx->q_data[V4L2_M2M_DST].sizeimage, -+ ctx->component->output[0].minimum_buffer.size); - } - - return 0; -@@ -2090,8 +2118,6 @@ static int bcm2835_codec_open(struct fil - struct v4l2_ctrl_handler *hdl; - int rc = 0; - -- v4l2_dbg(1, debug, &dev->v4l2_dev, "Creating instance for %s\n", -- dev->decode ? "decode" : "encode"); - if (mutex_lock_interruptible(&dev->dev_mutex)) { - v4l2_err(&dev->v4l2_dev, "Mutex fail\n"); - return -ERESTARTSYS; -@@ -2104,7 +2130,8 @@ static int bcm2835_codec_open(struct fil - - ctx->q_data[V4L2_M2M_SRC].fmt = get_default_format(dev, false); - ctx->q_data[V4L2_M2M_DST].fmt = get_default_format(dev, true); -- if (dev->decode) { -+ switch (dev->role) { -+ case DECODE: - /* - * Input width and height are irrelevant as they will be defined - * by the bitstream not the format. Required by V4L2 though. -@@ -2126,7 +2153,8 @@ static int bcm2835_codec_open(struct fil - get_sizeimage(ctx->q_data[V4L2_M2M_DST].bytesperline, - ctx->q_data[V4L2_M2M_DST].height, - ctx->q_data[V4L2_M2M_DST].fmt); -- } else { -+ break; -+ case ENCODE: - ctx->q_data[V4L2_M2M_SRC].crop_width = DEFAULT_WIDTH; - ctx->q_data[V4L2_M2M_SRC].crop_height = DEFAULT_HEIGHT; - ctx->q_data[V4L2_M2M_SRC].height = DEFAULT_HEIGHT; -@@ -2144,6 +2172,9 @@ static int bcm2835_codec_open(struct fil - ctx->q_data[V4L2_M2M_DST].height = DEFAULT_HEIGHT; - ctx->q_data[V4L2_M2M_DST].sizeimage = - DEF_COMP_BUF_SIZE_720P_OR_LESS; -+ break; -+ case ISP: -+ break; - } - - ctx->colorspace = V4L2_COLORSPACE_REC709; -@@ -2154,7 +2185,7 @@ static int bcm2835_codec_open(struct fil - file->private_data = &ctx->fh; - ctx->dev = dev; - hdl = &ctx->hdl; -- if (!dev->decode) { -+ if (dev->role == ENCODE) { - /* Encode controls */ - v4l2_ctrl_handler_init(hdl, 6); - -@@ -2303,14 +2334,11 @@ static int bcm2835_codec_get_supported_f - unsigned int i, j, num_encodings; - int ret; - -- ret = vchiq_mmal_component_init(dev->instance, -- dev->decode ? -- "ril.video_decode" : -- "ril.video_encode", -+ ret = vchiq_mmal_component_init(dev->instance, components[dev->role], - &component); - if (ret < 0) { -- v4l2_err(&dev->v4l2_dev, "%s: failed to create component\n", -- __func__); -+ v4l2_err(&dev->v4l2_dev, "%s: failed to create component %s\n", -+ __func__, components[dev->role]); - return -ENOMEM; - } - -@@ -2406,12 +2434,13 @@ destroy_component: - - static int bcm2835_codec_create(struct platform_device *pdev, - struct bcm2835_codec_dev **new_dev, -- bool decode) -+ enum bcm2835_codec_role role) - { - struct bcm2835_codec_dev *dev; - struct video_device *vfd; - int video_nr; - int ret; -+ const static char *roles[] = {"decode", "encode", "isp"}; - - dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); - if (!dev) -@@ -2419,7 +2448,7 @@ static int bcm2835_codec_create(struct p - - dev->pdev = pdev; - -- dev->decode = decode; -+ dev->role = role; - - ret = vchiq_mmal_init(&dev->instance); - if (ret) -@@ -2441,14 +2470,27 @@ static int bcm2835_codec_create(struct p - vfd->lock = &dev->dev_mutex; - vfd->v4l2_dev = &dev->v4l2_dev; - -- if (dev->decode) { -+ switch (role) { -+ case DECODE: - v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD); - v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); - video_nr = decode_video_nr; -- } else { -+ break; -+ case ENCODE: - v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD); - v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD); - video_nr = encode_video_nr; -+ break; -+ case ISP: -+ v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD); -+ v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); -+ v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD); -+ v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD); -+ video_nr = isp_video_nr; -+ break; -+ default: -+ ret = -EINVAL; -+ goto unreg_dev; - } - - ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); -@@ -2473,7 +2515,7 @@ static int bcm2835_codec_create(struct p - } - - v4l2_info(&dev->v4l2_dev, "Loaded V4L2 %s\n", -- dev->decode ? "decode" : "encode"); -+ roles[role]); - return 0; - - err_m2m: -@@ -2509,11 +2551,15 @@ static int bcm2835_codec_probe(struct pl - if (!drv) - return -ENOMEM; - -- ret = bcm2835_codec_create(pdev, &drv->encode, false); -+ ret = bcm2835_codec_create(pdev, &drv->decode, DECODE); - if (ret) - goto out; - -- ret = bcm2835_codec_create(pdev, &drv->decode, true); -+ ret = bcm2835_codec_create(pdev, &drv->encode, ENCODE); -+ if (ret) -+ goto out; -+ -+ ret = bcm2835_codec_create(pdev, &drv->isp, ISP); - if (ret) - goto out; - -@@ -2526,6 +2572,10 @@ out: - bcm2835_codec_destroy(drv->encode); - drv->encode = NULL; - } -+ if (drv->decode) { -+ bcm2835_codec_destroy(drv->decode); -+ drv->decode = NULL; -+ } - return ret; - } - -@@ -2533,6 +2583,8 @@ static int bcm2835_codec_remove(struct p - { - struct bcm2835_codec_driver *drv = platform_get_drvdata(pdev); - -+ bcm2835_codec_destroy(drv->isp); -+ - bcm2835_codec_destroy(drv->encode); - - bcm2835_codec_destroy(drv->decode); diff --git a/target/linux/brcm2708/patches-4.19/950-0362-staging-mmal-vchiq-Update-mmal_parameters.h-with-rec.patch b/target/linux/brcm2708/patches-4.19/950-0362-staging-mmal-vchiq-Update-mmal_parameters.h-with-rec.patch new file mode 100644 index 0000000000..6f49536965 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0362-staging-mmal-vchiq-Update-mmal_parameters.h-with-rec.patch @@ -0,0 +1,56 @@ +From d5e64fca8218f9553172720752629c8145c91b9e Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 18 Feb 2019 15:52:29 +0000 +Subject: [PATCH 362/725] staging: mmal-vchiq: Update mmal_parameters.h with + recently defined params + +mmal_parameters.h hasn't been updated to reflect additions made +over the last few years. Update it to reflect the currently +supported parameters. + +Signed-off-by: Dave Stevenson +--- + .../vchiq-mmal/mmal-parameters.h | 32 ++++++++++++++++++- + 1 file changed, 31 insertions(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h +@@ -580,7 +580,37 @@ enum mmal_parameter_video_type { + MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_DELAY_HRD_FLAG, + + /**< @ref MMAL_PARAMETER_BOOLEAN_T */ +- MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER ++ MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER, ++ ++ /**< Take a @ref MMAL_PARAMETER_BOOLEAN_T. */ ++ MMAL_PARAMETER_VIDEO_ENCODE_SEI_ENABLE, ++ ++ /**< Take a @ref MMAL_PARAMETER_BOOLEAN_T. */ ++ MMAL_PARAMETER_VIDEO_ENCODE_INLINE_VECTORS, ++ ++ /**< Take a @ref MMAL_PARAMETER_VIDEO_RENDER_STATS_T. */ ++ MMAL_PARAMETER_VIDEO_RENDER_STATS, ++ ++ /**< Take a @ref MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T. */ ++ MMAL_PARAMETER_VIDEO_INTERLACE_TYPE, ++ ++ /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_VIDEO_INTERPOLATE_TIMESTAMPS, ++ ++ /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_VIDEO_ENCODE_SPS_TIMING, ++ ++ /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ ++ MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS, ++ ++ /**< Takes a @ref MMAL_PARAMETER_SOURCE_PATTERN_T */ ++ MMAL_PARAMETER_VIDEO_SOURCE_PATTERN, ++ ++ /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ ++ MMAL_PARAMETER_VIDEO_ENCODE_SEPARATE_NAL_BUFS, ++ ++ /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ ++ MMAL_PARAMETER_VIDEO_DROPPABLE_PFRAME_LENGTH, + }; + + /** Valid mirror modes */ diff --git a/target/linux/brcm2708/patches-4.19/950-0363-staging-bcm2835_codec-Add-an-option-for-ignoring-Bay.patch b/target/linux/brcm2708/patches-4.19/950-0363-staging-bcm2835_codec-Add-an-option-for-ignoring-Bay.patch deleted file mode 100644 index f1b512fdd2..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0363-staging-bcm2835_codec-Add-an-option-for-ignoring-Bay.patch +++ /dev/null @@ -1,179 +0,0 @@ -From bb5864d9cbab452b7946b5ef97e781cf6e18e8b9 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 15 Feb 2019 11:36:14 +0000 -Subject: [PATCH 363/703] staging: bcm2835_codec: Add an option for ignoring - Bayer formats. - -This is a workaround for GStreamer currently not identifying Bayer -as a raw format, therefore any device that supports it does not -match the criteria for v4l2convert. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 29 ++++++++++++++++++- - 1 file changed, 28 insertions(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -58,6 +58,15 @@ static int isp_video_nr = 12; - module_param(isp_video_nr, int, 0644); - MODULE_PARM_DESC(isp_video_nr, "isp video device number"); - -+/* -+ * Workaround for GStreamer v4l2convert component not considering Bayer formats -+ * as raw, and therefore not considering a V4L2 device that supports them as -+ * as a suitable candidate. -+ */ -+static bool disable_bayer; -+module_param(disable_bayer, bool, 0644); -+MODULE_PARM_DESC(disable_bayer, "Disable support for Bayer formats"); -+ - static unsigned int debug; - module_param(debug, uint, 0644); - MODULE_PARM_DESC(debug, "activates debug info (0-3)"); -@@ -105,6 +114,7 @@ struct bcm2835_codec_fmt { - u32 flags; - u32 mmal_fmt; - int size_multiplier_x2; -+ bool is_bayer; - }; - - static const struct bcm2835_codec_fmt supported_formats[] = { -@@ -203,6 +213,7 @@ static const struct bcm2835_codec_fmt su - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB8, - .size_multiplier_x2 = 2, -+ .is_bayer = true, - }, { - .fourcc = V4L2_PIX_FMT_SBGGR8, - .depth = 8, -@@ -210,6 +221,7 @@ static const struct bcm2835_codec_fmt su - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR8, - .size_multiplier_x2 = 2, -+ .is_bayer = true, - }, { - .fourcc = V4L2_PIX_FMT_SGRBG8, - .depth = 8, -@@ -217,6 +229,7 @@ static const struct bcm2835_codec_fmt su - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG8, - .size_multiplier_x2 = 2, -+ .is_bayer = true, - }, { - .fourcc = V4L2_PIX_FMT_SGBRG8, - .depth = 8, -@@ -224,6 +237,7 @@ static const struct bcm2835_codec_fmt su - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG8, - .size_multiplier_x2 = 2, -+ .is_bayer = true, - }, { - /* 10 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB10P, -@@ -232,6 +246,7 @@ static const struct bcm2835_codec_fmt su - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB10P, - .size_multiplier_x2 = 2, -+ .is_bayer = true, - }, { - .fourcc = V4L2_PIX_FMT_SBGGR10P, - .depth = 10, -@@ -239,6 +254,7 @@ static const struct bcm2835_codec_fmt su - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR10P, - .size_multiplier_x2 = 2, -+ .is_bayer = true, - }, { - .fourcc = V4L2_PIX_FMT_SGRBG10P, - .depth = 10, -@@ -246,6 +262,7 @@ static const struct bcm2835_codec_fmt su - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG10P, - .size_multiplier_x2 = 2, -+ .is_bayer = true, - }, { - .fourcc = V4L2_PIX_FMT_SGBRG10P, - .depth = 10, -@@ -253,6 +270,7 @@ static const struct bcm2835_codec_fmt su - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG10P, - .size_multiplier_x2 = 2, -+ .is_bayer = true, - }, { - /* 12 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB12P, -@@ -261,6 +279,7 @@ static const struct bcm2835_codec_fmt su - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB12P, - .size_multiplier_x2 = 2, -+ .is_bayer = true, - }, { - .fourcc = V4L2_PIX_FMT_SBGGR12P, - .depth = 12, -@@ -268,6 +287,7 @@ static const struct bcm2835_codec_fmt su - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR12P, - .size_multiplier_x2 = 2, -+ .is_bayer = true, - }, { - .fourcc = V4L2_PIX_FMT_SGRBG12P, - .depth = 12, -@@ -275,6 +295,7 @@ static const struct bcm2835_codec_fmt su - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG12P, - .size_multiplier_x2 = 2, -+ .is_bayer = true, - }, { - .fourcc = V4L2_PIX_FMT_SGBRG12P, - .depth = 12, -@@ -282,6 +303,7 @@ static const struct bcm2835_codec_fmt su - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG12P, - .size_multiplier_x2 = 2, -+ .is_bayer = true, - }, { - /* 16 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB16, -@@ -290,6 +312,7 @@ static const struct bcm2835_codec_fmt su - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB16, - .size_multiplier_x2 = 2, -+ .is_bayer = true, - }, { - .fourcc = V4L2_PIX_FMT_SBGGR16, - .depth = 16, -@@ -297,6 +320,7 @@ static const struct bcm2835_codec_fmt su - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR16, - .size_multiplier_x2 = 2, -+ .is_bayer = true, - }, { - .fourcc = V4L2_PIX_FMT_SGRBG16, - .depth = 16, -@@ -304,6 +328,7 @@ static const struct bcm2835_codec_fmt su - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG16, - .size_multiplier_x2 = 2, -+ .is_bayer = true, - }, { - .fourcc = V4L2_PIX_FMT_SGBRG16, - .depth = 16, -@@ -311,6 +336,7 @@ static const struct bcm2835_codec_fmt su - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG16, - .size_multiplier_x2 = 2, -+ .is_bayer = true, - }, { - /* Compressed formats */ - .fourcc = V4L2_PIX_FMT_H264, -@@ -438,7 +464,8 @@ static const struct bcm2835_codec_fmt *g - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(supported_formats); i++) { -- if (supported_formats[i].mmal_fmt == mmal_fmt) -+ if (supported_formats[i].mmal_fmt == mmal_fmt && -+ (!disable_bayer || !supported_formats[i].is_bayer)) - return &supported_formats[i]; - } - return NULL; diff --git a/target/linux/brcm2708/patches-4.19/950-0363-staging-bcm2835_codec-Include-timing-info-in-SPS-hea.patch b/target/linux/brcm2708/patches-4.19/950-0363-staging-bcm2835_codec-Include-timing-info-in-SPS-hea.patch new file mode 100644 index 0000000000..7f45c0e729 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0363-staging-bcm2835_codec-Include-timing-info-in-SPS-hea.patch @@ -0,0 +1,44 @@ +From 87a65d77b96f9d87d0df9da9505a3dbbadf70baf Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 18 Feb 2019 15:56:42 +0000 +Subject: [PATCH 363/725] staging: bcm2835_codec: Include timing info in SPS + headers + +Inserting timing information into the VUI block of the SPS is +optional with the VPU encoder. +GStreamer appears to require them when using V4L2 M2M, therefore +set the option to enable them from the encoder. + +Signed-off-by: Dave Stevenson +--- + .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -1785,6 +1785,8 @@ static int bcm2835_codec_create_componen + goto destroy_component; + + if (dev->role == ENCODE) { ++ u32 param = 1; ++ + if (ctx->q_data[V4L2_M2M_SRC].sizeimage < + ctx->component->output[0].minimum_buffer.size) + v4l2_err(&dev->v4l2_dev, "buffer size mismatch sizeimage %u < min size %u\n", +@@ -1793,6 +1795,16 @@ static int bcm2835_codec_create_componen + + /* Now we have a component we can set all the ctrls */ + bcm2835_codec_set_ctrls(ctx); ++ ++ /* Enable SPS Timing header so framerate information is encoded ++ * in the H264 header. ++ */ ++ vchiq_mmal_port_parameter_set( ++ ctx->dev->instance, ++ &ctx->component->output[0], ++ MMAL_PARAMETER_VIDEO_ENCODE_SPS_TIMING, ++ ¶m, sizeof(param)); ++ + } else { + if (ctx->q_data[V4L2_M2M_DST].sizeimage < + ctx->component->output[0].minimum_buffer.size) diff --git a/target/linux/brcm2708/patches-4.19/950-0364-drm-vc4-Don-t-wait-for-vblank-on-fkms-cursor-updates.patch b/target/linux/brcm2708/patches-4.19/950-0364-drm-vc4-Don-t-wait-for-vblank-on-fkms-cursor-updates.patch new file mode 100644 index 0000000000..178d172aa7 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0364-drm-vc4-Don-t-wait-for-vblank-on-fkms-cursor-updates.patch @@ -0,0 +1,28 @@ +From 7f97b8d48bb2c2f67c8f7a81983e7223c91adfb0 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 5 Feb 2018 18:53:18 +0000 +Subject: [PATCH 364/725] drm/vc4: Don't wait for vblank on fkms cursor + updates. + +We don't use the same async update path between fkms and normal kms, +and the normal kms workaround ended up making us wait. This became a +larger problem in rpi-4.14.y, as the USB HID update rate throttling +got (accidentally?) dropped. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_kms.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/vc4/vc4_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_kms.c +@@ -222,7 +222,8 @@ static int vc4_atomic_commit(struct drm_ + * drm_atomic_helper_setup_commit() from auto-completing + * commit->flip_done. + */ +- state->legacy_cursor_update = false; ++ if (!vc4->firmware_kms) ++ state->legacy_cursor_update = false; + ret = drm_atomic_helper_setup_commit(state, nonblock); + if (ret) + return ret; diff --git a/target/linux/brcm2708/patches-4.19/950-0364-staging-bcm2835_codec-Fix-handling-of-VB2_MEMORY_DMA.patch b/target/linux/brcm2708/patches-4.19/950-0364-staging-bcm2835_codec-Fix-handling-of-VB2_MEMORY_DMA.patch deleted file mode 100644 index 5bd32d1184..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0364-staging-bcm2835_codec-Fix-handling-of-VB2_MEMORY_DMA.patch +++ /dev/null @@ -1,186 +0,0 @@ -From d103cd3b55e4285f2c0ad937cf31bea9ebaa4d21 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 15 Feb 2019 11:38:45 +0000 -Subject: [PATCH 364/703] staging: bcm2835_codec: Fix handling of - VB2_MEMORY_DMABUF buffers - -If the queue is configured as VB2_MEMORY_DMABUF then vb2_core_expbuf -fails as it ensures the queue is defined as VB2_MEMORY_MMAP. - -Correct the handling so that we unmap the buffer from vcsm and the -VPU on cleanup, and then correctly get the dma buf of the new buffer. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 80 +++++++++++++------ - .../vc04_services/vchiq-mmal/mmal-vchiq.c | 21 +++-- - .../vc04_services/vchiq-mmal/mmal-vchiq.h | 2 + - 3 files changed, 73 insertions(+), 30 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -1852,6 +1852,18 @@ static int bcm2835_codec_queue_setup(str - return 0; - } - -+static int bcm2835_codec_mmal_buf_cleanup(struct mmal_buffer *mmal_buf) -+{ -+ mmal_vchi_buffer_cleanup(mmal_buf); -+ -+ if (mmal_buf->dma_buf) { -+ dma_buf_put(mmal_buf->dma_buf); -+ mmal_buf->dma_buf = NULL; -+ } -+ -+ return 0; -+} -+ - static int bcm2835_codec_buf_init(struct vb2_buffer *vb) - { - struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); -@@ -1880,6 +1892,7 @@ static int bcm2835_codec_buf_prepare(str - vb); - struct m2m_mmal_buffer *buf = container_of(m2m, struct m2m_mmal_buffer, - m2m); -+ struct dma_buf *dma_buf; - int ret; - - v4l2_dbg(4, debug, &ctx->dev->v4l2_dev, "%s: type: %d ptr %p\n", -@@ -1906,20 +1919,48 @@ static int bcm2835_codec_buf_prepare(str - if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) - vb2_set_plane_payload(vb, 0, q_data->sizeimage); - -- /* -- * We want to do this at init, but vb2_core_expbuf checks that the -- * index < q->num_buffers, and q->num_buffers only gets updated once -- * all the buffers are allocated. -- */ -- if (!buf->mmal.dma_buf) { -- ret = vb2_core_expbuf_dmabuf(vb->vb2_queue, -- vb->vb2_queue->type, vb->index, 0, -- O_CLOEXEC, &buf->mmal.dma_buf); -- if (ret) -- v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed to expbuf idx %d, ret %d\n", -- __func__, vb->index, ret); -- } else { -+ switch (vb->memory) { -+ case VB2_MEMORY_DMABUF: -+ dma_buf = dma_buf_get(vb->planes[0].m.fd); -+ -+ if (dma_buf != buf->mmal.dma_buf) { -+ /* dmabuf either hasn't already been mapped, or it has -+ * changed. -+ */ -+ if (buf->mmal.dma_buf) { -+ v4l2_err(&ctx->dev->v4l2_dev, -+ "%s Buffer changed - why did the core not call cleanup?\n", -+ __func__); -+ bcm2835_codec_mmal_buf_cleanup(&buf->mmal); -+ } -+ -+ buf->mmal.dma_buf = dma_buf; -+ } - ret = 0; -+ break; -+ case VB2_MEMORY_MMAP: -+ /* -+ * We want to do this at init, but vb2_core_expbuf checks that -+ * the index < q->num_buffers, and q->num_buffers only gets -+ * updated once all the buffers are allocated. -+ */ -+ if (!buf->mmal.dma_buf) { -+ ret = vb2_core_expbuf_dmabuf(vb->vb2_queue, -+ vb->vb2_queue->type, -+ vb->index, 0, -+ O_CLOEXEC, -+ &buf->mmal.dma_buf); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, -+ "%s: Failed to expbuf idx %d, ret %d\n", -+ __func__, vb->index, ret); -+ } else { -+ ret = 0; -+ } -+ break; -+ default: -+ ret = -EINVAL; -+ break; - } - - return ret; -@@ -1948,12 +1989,7 @@ static void bcm2835_codec_buffer_cleanup - v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: ctx:%p, vb %p\n", - __func__, ctx, vb); - -- mmal_vchi_buffer_cleanup(&buf->mmal); -- -- if (buf->mmal.dma_buf) { -- dma_buf_put(buf->mmal.dma_buf); -- buf->mmal.dma_buf = NULL; -- } -+ bcm2835_codec_mmal_buf_cleanup(&buf->mmal); - } - - static int bcm2835_codec_start_streaming(struct vb2_queue *q, -@@ -2067,11 +2103,7 @@ static void bcm2835_codec_stop_streaming - m2m = container_of(vb2, struct v4l2_m2m_buffer, vb); - buf = container_of(m2m, struct m2m_mmal_buffer, m2m); - -- mmal_vchi_buffer_cleanup(&buf->mmal); -- if (buf->mmal.dma_buf) { -- dma_buf_put(buf->mmal.dma_buf); -- buf->mmal.dma_buf = NULL; -- } -+ bcm2835_codec_mmal_buf_cleanup(&buf->mmal); - } - - /* If both ports disabled, then disable the component */ ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -1785,13 +1785,9 @@ int mmal_vchi_buffer_init(struct vchiq_m - } - EXPORT_SYMBOL_GPL(mmal_vchi_buffer_init); - --int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf) -+int mmal_vchi_buffer_unmap(struct mmal_buffer *buf) - { -- struct mmal_msg_context *msg_context = buf->msg_context; -- -- if (msg_context) -- release_msg_context(msg_context); -- buf->msg_context = NULL; -+ int ret = 0; - - if (buf->vcsm_handle) { - int ret; -@@ -1803,6 +1799,19 @@ int mmal_vchi_buffer_cleanup(struct mmal - pr_err("%s: vcsm_free failed, ret %d\n", __func__, ret); - buf->vcsm_handle = 0; - } -+ return ret; -+} -+EXPORT_SYMBOL_GPL(mmal_vchi_buffer_unmap); -+ -+int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf) -+{ -+ struct mmal_msg_context *msg_context = buf->msg_context; -+ -+ if (msg_context) -+ release_msg_context(msg_context); -+ buf->msg_context = NULL; -+ -+ mmal_vchi_buffer_unmap(buf); - return 0; - } - EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup); ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h -@@ -167,6 +167,8 @@ int vchiq_mmal_submit_buffer(struct vchi - struct vchiq_mmal_port *port, - struct mmal_buffer *buf); - -+int mmal_vchi_buffer_unmap(struct mmal_buffer *buf); -+ - int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance, - struct mmal_buffer *buf); - int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf); diff --git a/target/linux/brcm2708/patches-4.19/950-0365-Fix-for-Pisound-kernel-module-in-Real-Time-kernel-co.patch b/target/linux/brcm2708/patches-4.19/950-0365-Fix-for-Pisound-kernel-module-in-Real-Time-kernel-co.patch new file mode 100644 index 0000000000..0ad588bd24 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0365-Fix-for-Pisound-kernel-module-in-Real-Time-kernel-co.patch @@ -0,0 +1,38 @@ +From 482738fa793cdc446e827233edc24d3db86ab1c0 Mon Sep 17 00:00:00 2001 +From: Giedrius +Date: Wed, 27 Feb 2019 14:27:28 +0000 +Subject: [PATCH 365/725] Fix for Pisound kernel module in Real Time kernel + configuration. + +When handler of data_available interrupt is fired, queue_work ends up +getting called and it can block on a spin lock which is not allowed in +interrupt context. The fix was to run the handler from a thread context +instead. +--- + sound/soc/bcm/pisound.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/sound/soc/bcm/pisound.c ++++ b/sound/soc/bcm/pisound.c +@@ -1,6 +1,6 @@ + /* + * Pisound Linux kernel module. +- * Copyright (C) 2016-2017 Vilniaus Blokas UAB, https://blokas.io/pisound ++ * Copyright (C) 2016-2019 Vilniaus Blokas UAB, https://blokas.io/pisound + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License +@@ -532,10 +532,10 @@ static void pisnd_spi_gpio_uninit(void) + + static int pisnd_spi_gpio_irq_init(struct device *dev) + { +- return request_irq( +- gpiod_to_irq(data_available), ++ return request_threaded_irq( ++ gpiod_to_irq(data_available), NULL, + data_available_interrupt_handler, +- IRQF_TIMER | IRQF_TRIGGER_RISING, ++ IRQF_TIMER | IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "data_available_int", + NULL + ); diff --git a/target/linux/brcm2708/patches-4.19/950-0365-staging-mmal-vchiq-Update-mmal_parameters.h-with-rec.patch b/target/linux/brcm2708/patches-4.19/950-0365-staging-mmal-vchiq-Update-mmal_parameters.h-with-rec.patch deleted file mode 100644 index 342c22f80c..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0365-staging-mmal-vchiq-Update-mmal_parameters.h-with-rec.patch +++ /dev/null @@ -1,56 +0,0 @@ -From c295d66017878afeee903f9f324b59e847dfb69b Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 18 Feb 2019 15:52:29 +0000 -Subject: [PATCH 365/703] staging: mmal-vchiq: Update mmal_parameters.h with - recently defined params - -mmal_parameters.h hasn't been updated to reflect additions made -over the last few years. Update it to reflect the currently -supported parameters. - -Signed-off-by: Dave Stevenson ---- - .../vchiq-mmal/mmal-parameters.h | 32 ++++++++++++++++++- - 1 file changed, 31 insertions(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h -@@ -580,7 +580,37 @@ enum mmal_parameter_video_type { - MMAL_PARAMETER_VIDEO_ENCODE_H264_LOW_DELAY_HRD_FLAG, - - /**< @ref MMAL_PARAMETER_BOOLEAN_T */ -- MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER -+ MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER, -+ -+ /**< Take a @ref MMAL_PARAMETER_BOOLEAN_T. */ -+ MMAL_PARAMETER_VIDEO_ENCODE_SEI_ENABLE, -+ -+ /**< Take a @ref MMAL_PARAMETER_BOOLEAN_T. */ -+ MMAL_PARAMETER_VIDEO_ENCODE_INLINE_VECTORS, -+ -+ /**< Take a @ref MMAL_PARAMETER_VIDEO_RENDER_STATS_T. */ -+ MMAL_PARAMETER_VIDEO_RENDER_STATS, -+ -+ /**< Take a @ref MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T. */ -+ MMAL_PARAMETER_VIDEO_INTERLACE_TYPE, -+ -+ /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_VIDEO_INTERPOLATE_TIMESTAMPS, -+ -+ /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_VIDEO_ENCODE_SPS_TIMING, -+ -+ /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ -+ MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS, -+ -+ /**< Takes a @ref MMAL_PARAMETER_SOURCE_PATTERN_T */ -+ MMAL_PARAMETER_VIDEO_SOURCE_PATTERN, -+ -+ /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_VIDEO_ENCODE_SEPARATE_NAL_BUFS, -+ -+ /**< Takes a @ref MMAL_PARAMETER_UINT32_T */ -+ MMAL_PARAMETER_VIDEO_DROPPABLE_PFRAME_LENGTH, - }; - - /** Valid mirror modes */ diff --git a/target/linux/brcm2708/patches-4.19/950-0366-config-Add-CONFIG_FB_TFT_SH1106-m.patch b/target/linux/brcm2708/patches-4.19/950-0366-config-Add-CONFIG_FB_TFT_SH1106-m.patch new file mode 100644 index 0000000000..c0935341fe --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0366-config-Add-CONFIG_FB_TFT_SH1106-m.patch @@ -0,0 +1,64 @@ +From 2ff0243b891590549f6669104be51b76325ce167 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 27 Feb 2019 20:08:48 +0000 +Subject: [PATCH 366/725] config: Add CONFIG_FB_TFT_SH1106=m + +See: https://github.com/raspberrypi/linux/issues/2876 + +Signed-off-by: Phil Elwell +--- + arch/arm/configs/bcm2709_defconfig | 3 ++- + arch/arm/configs/bcmrpi_defconfig | 3 ++- + arch/arm64/configs/bcmrpi3_defconfig | 1 + + 3 files changed, 5 insertions(+), 2 deletions(-) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -905,8 +905,8 @@ CONFIG_SND_BCM2835_SOC_I2S=m + CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER=m + CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m +-CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m + CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=m +@@ -1203,6 +1203,7 @@ CONFIG_FB_TFT_PCD8544=m + CONFIG_FB_TFT_RA8875=m + CONFIG_FB_TFT_S6D02A1=m + CONFIG_FB_TFT_S6D1121=m ++CONFIG_FB_TFT_SH1106=m + CONFIG_FB_TFT_SSD1289=m + CONFIG_FB_TFT_SSD1306=m + CONFIG_FB_TFT_SSD1331=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -898,8 +898,8 @@ CONFIG_SND_BCM2835_SOC_I2S=m + CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER=m + CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m +-CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m + CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=m +@@ -1196,6 +1196,7 @@ CONFIG_FB_TFT_PCD8544=m + CONFIG_FB_TFT_RA8875=m + CONFIG_FB_TFT_S6D02A1=m + CONFIG_FB_TFT_S6D1121=m ++CONFIG_FB_TFT_SH1106=m + CONFIG_FB_TFT_SSD1289=m + CONFIG_FB_TFT_SSD1306=m + CONFIG_FB_TFT_SSD1331=m +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -1061,6 +1061,7 @@ CONFIG_FB_TFT_PCD8544=m + CONFIG_FB_TFT_RA8875=m + CONFIG_FB_TFT_S6D02A1=m + CONFIG_FB_TFT_S6D1121=m ++CONFIG_FB_TFT_SH1106=m + CONFIG_FB_TFT_SSD1289=m + CONFIG_FB_TFT_SSD1306=m + CONFIG_FB_TFT_SSD1331=m diff --git a/target/linux/brcm2708/patches-4.19/950-0366-staging-bcm2835_codec-Include-timing-info-in-SPS-hea.patch b/target/linux/brcm2708/patches-4.19/950-0366-staging-bcm2835_codec-Include-timing-info-in-SPS-hea.patch deleted file mode 100644 index b0c449bd27..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0366-staging-bcm2835_codec-Include-timing-info-in-SPS-hea.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 90a411bf61170375a4392b603e6f085ff0c68927 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 18 Feb 2019 15:56:42 +0000 -Subject: [PATCH 366/703] staging: bcm2835_codec: Include timing info in SPS - headers - -Inserting timing information into the VUI block of the SPS is -optional with the VPU encoder. -GStreamer appears to require them when using V4L2 M2M, therefore -set the option to enable them from the encoder. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -1785,6 +1785,8 @@ static int bcm2835_codec_create_componen - goto destroy_component; - - if (dev->role == ENCODE) { -+ u32 param = 1; -+ - if (ctx->q_data[V4L2_M2M_SRC].sizeimage < - ctx->component->output[0].minimum_buffer.size) - v4l2_err(&dev->v4l2_dev, "buffer size mismatch sizeimage %u < min size %u\n", -@@ -1793,6 +1795,16 @@ static int bcm2835_codec_create_componen - - /* Now we have a component we can set all the ctrls */ - bcm2835_codec_set_ctrls(ctx); -+ -+ /* Enable SPS Timing header so framerate information is encoded -+ * in the H264 header. -+ */ -+ vchiq_mmal_port_parameter_set( -+ ctx->dev->instance, -+ &ctx->component->output[0], -+ MMAL_PARAMETER_VIDEO_ENCODE_SPS_TIMING, -+ ¶m, sizeof(param)); -+ - } else { - if (ctx->q_data[V4L2_M2M_DST].sizeimage < - ctx->component->output[0].minimum_buffer.size) diff --git a/target/linux/brcm2708/patches-4.19/950-0367-Added-mute-stream-func.patch b/target/linux/brcm2708/patches-4.19/950-0367-Added-mute-stream-func.patch new file mode 100644 index 0000000000..824ab4de9f --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0367-Added-mute-stream-func.patch @@ -0,0 +1,146 @@ +From c5d112f24ec5bc168f8af900f7ed0cd7341ef6ba Mon Sep 17 00:00:00 2001 +From: Jaikumar +Date: Thu, 7 Jun 2018 21:22:45 +0530 +Subject: [PATCH 367/725] Added mute stream func + +Signed-off-by: Jaikumar +--- + sound/soc/bcm/allo-katana-codec.c | 60 ++++++++++++++++++++++--------- + 1 file changed, 44 insertions(+), 16 deletions(-) + +--- a/sound/soc/bcm/allo-katana-codec.c ++++ b/sound/soc/bcm/allo-katana-codec.c +@@ -31,21 +31,23 @@ + + #define KATANA_CODEC_CHIP_ID 0x30 + #define KATANA_CODEC_VIRT_BASE 0x100 +-#define KATANA_CODEC_PAGE 0 ++#define KATANA_CODEC_PAGE 0 + + #define KATANA_CODEC_CHIP_ID_REG (KATANA_CODEC_VIRT_BASE + 0) +-#define KATANA_CODEC_RESET (KATANA_CODEC_VIRT_BASE + 1) ++#define KATANA_CODEC_RESET (KATANA_CODEC_VIRT_BASE + 1) + #define KATANA_CODEC_VOLUME_1 (KATANA_CODEC_VIRT_BASE + 2) + #define KATANA_CODEC_VOLUME_2 (KATANA_CODEC_VIRT_BASE + 3) +-#define KATANA_CODEC_MUTE (KATANA_CODEC_VIRT_BASE + 4) ++#define KATANA_CODEC_MUTE (KATANA_CODEC_VIRT_BASE + 4) + #define KATANA_CODEC_DSP_PROGRAM (KATANA_CODEC_VIRT_BASE + 5) + #define KATANA_CODEC_DEEMPHASIS (KATANA_CODEC_VIRT_BASE + 6) +-#define KATANA_CODEC_DOP (KATANA_CODEC_VIRT_BASE + 7) +-#define KATANA_CODEC_FORMAT (KATANA_CODEC_VIRT_BASE + 8) ++#define KATANA_CODEC_DOP (KATANA_CODEC_VIRT_BASE + 7) ++#define KATANA_CODEC_FORMAT (KATANA_CODEC_VIRT_BASE + 8) + #define KATANA_CODEC_COMMAND (KATANA_CODEC_VIRT_BASE + 9) +-#define KATANA_CODEC_MAX_REGISTER (KATANA_CODEC_VIRT_BASE + 9) ++#define KATANA_CODEC_MUTE_STREAM (KATANA_CODEC_VIRT_BASE + 10) + +-#define KATANA_CODEC_FMT 0xff ++#define KATANA_CODEC_MAX_REGISTER (KATANA_CODEC_VIRT_BASE + 10) ++ ++#define KATANA_CODEC_FMT 0xff + #define KATANA_CODEC_CHAN_MONO 0x00 + #define KATANA_CODEC_CHAN_STEREO 0x80 + #define KATANA_CODEC_ALEN_16 0x10 +@@ -135,7 +137,8 @@ static const struct snd_kcontrol_new kat + SOC_SINGLE("DoP Playback Switch", KATANA_CODEC_DOP, 0, 1, 1) + }; + +-static bool katana_codec_readable_register(struct device *dev, unsigned int reg) ++static bool katana_codec_readable_register(struct device *dev, ++ unsigned int reg) + { + switch (reg) { + case KATANA_CODEC_CHIP_ID_REG: +@@ -150,13 +153,15 @@ static int katana_codec_hw_params(struct + struct snd_soc_dai *dai) + { + struct snd_soc_component *component = dai->component; +- struct katana_codec_priv *katana_codec = snd_soc_component_get_drvdata(component); ++ struct katana_codec_priv *katana_codec = ++ snd_soc_component_get_drvdata(component); + int fmt = 0; + int ret; + +- dev_dbg(component->card->dev, "hw_params %u Hz, %u channels\n", ++ dev_dbg(component->card->dev, "hw_params %u Hz, %u channels, %u bits\n", + params_rate(params), +- params_channels(params)); ++ params_channels(params), ++ params_width(params)); + + switch (katana_codec->fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: // master +@@ -212,13 +217,17 @@ static int katana_codec_hw_params(struct + return -EINVAL; + } + +- ret = regmap_write(katana_codec->regmap, KATANA_CODEC_FORMAT, fmt); ++ ret = regmap_write(katana_codec->regmap, KATANA_CODEC_FORMAT, ++ fmt); + if (ret != 0) { + dev_err(component->card->dev, "Failed to set format: %d\n", ret); + return ret; + } + break; + ++ case SND_SOC_DAIFMT_CBS_CFS: ++ break; ++ + default: + return -EINVAL; + } +@@ -229,14 +238,33 @@ static int katana_codec_hw_params(struct + static int katana_codec_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) + { + struct snd_soc_component *component = dai->component; +- struct katana_codec_priv *katana_codec = snd_soc_component_get_drvdata(component); ++ struct katana_codec_priv *katana_codec = ++ snd_soc_component_get_drvdata(component); + + katana_codec->fmt = fmt; + + return 0; + } + ++int katana_codec_dai_mute_stream(struct snd_soc_dai *dai, int mute, ++ int stream) ++{ ++ struct snd_soc_component *component = dai->component; ++ struct katana_codec_priv *katana_codec = ++ snd_soc_component_get_drvdata(component); ++ int ret = 0; ++ ++ ret = regmap_write(katana_codec->regmap, KATANA_CODEC_MUTE_STREAM, ++ mute); ++ if (ret != 0) { ++ dev_err(component->card->dev, "Failed to set mute: %d\n", ret); ++ return ret; ++ } ++ return ret; ++} ++ + static const struct snd_soc_dai_ops katana_codec_dai_ops = { ++ .mute_stream = katana_codec_dai_mute_stream, + .hw_params = katana_codec_hw_params, + .set_fmt = katana_codec_set_fmt, + }; +@@ -300,7 +328,7 @@ static int allo_katana_component_probe(s + return PTR_ERR(regmap); + + katana_codec = devm_kzalloc(dev, sizeof(struct katana_codec_priv), +- GFP_KERNEL); ++ GFP_KERNEL); + if (!katana_codec) + return -ENOMEM; + +@@ -348,8 +376,8 @@ static struct i2c_driver allo_katana_com + .remove = allo_katana_component_remove, + .id_table = allo_katana_component_id, + .driver = { +- .name = "allo-katana-codec", +- .of_match_table = allo_katana_codec_of_match, ++ .name = "allo-katana-codec", ++ .of_match_table = allo_katana_codec_of_match, + }, + }; + diff --git a/target/linux/brcm2708/patches-4.19/950-0367-drm-vc4-Don-t-wait-for-vblank-on-fkms-cursor-updates.patch b/target/linux/brcm2708/patches-4.19/950-0367-drm-vc4-Don-t-wait-for-vblank-on-fkms-cursor-updates.patch deleted file mode 100644 index f49a1ce978..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0367-drm-vc4-Don-t-wait-for-vblank-on-fkms-cursor-updates.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 2e2eb767bf98517b95fc7d7e1d28b802b41bfcd9 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 5 Feb 2018 18:53:18 +0000 -Subject: [PATCH 367/703] drm/vc4: Don't wait for vblank on fkms cursor - updates. - -We don't use the same async update path between fkms and normal kms, -and the normal kms workaround ended up making us wait. This became a -larger problem in rpi-4.14.y, as the USB HID update rate throttling -got (accidentally?) dropped. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_kms.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -222,7 +222,8 @@ static int vc4_atomic_commit(struct drm_ - * drm_atomic_helper_setup_commit() from auto-completing - * commit->flip_done. - */ -- state->legacy_cursor_update = false; -+ if (!vc4->firmware_kms) -+ state->legacy_cursor_update = false; - ret = drm_atomic_helper_setup_commit(state, nonblock); - if (ret) - return ret; diff --git a/target/linux/brcm2708/patches-4.19/950-0368-Fix-for-Pisound-kernel-module-in-Real-Time-kernel-co.patch b/target/linux/brcm2708/patches-4.19/950-0368-Fix-for-Pisound-kernel-module-in-Real-Time-kernel-co.patch deleted file mode 100644 index 916a35957d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0368-Fix-for-Pisound-kernel-module-in-Real-Time-kernel-co.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 3e9ce629c2f5f9f58c0b869261226ab811e2d5a7 Mon Sep 17 00:00:00 2001 -From: Giedrius -Date: Wed, 27 Feb 2019 14:27:28 +0000 -Subject: [PATCH 368/703] Fix for Pisound kernel module in Real Time kernel - configuration. - -When handler of data_available interrupt is fired, queue_work ends up -getting called and it can block on a spin lock which is not allowed in -interrupt context. The fix was to run the handler from a thread context -instead. ---- - sound/soc/bcm/pisound.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/sound/soc/bcm/pisound.c -+++ b/sound/soc/bcm/pisound.c -@@ -1,6 +1,6 @@ - /* - * Pisound Linux kernel module. -- * Copyright (C) 2016-2017 Vilniaus Blokas UAB, https://blokas.io/pisound -+ * Copyright (C) 2016-2019 Vilniaus Blokas UAB, https://blokas.io/pisound - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License -@@ -532,10 +532,10 @@ static void pisnd_spi_gpio_uninit(void) - - static int pisnd_spi_gpio_irq_init(struct device *dev) - { -- return request_irq( -- gpiod_to_irq(data_available), -+ return request_threaded_irq( -+ gpiod_to_irq(data_available), NULL, - data_available_interrupt_handler, -- IRQF_TIMER | IRQF_TRIGGER_RISING, -+ IRQF_TIMER | IRQF_TRIGGER_RISING | IRQF_ONESHOT, - "data_available_int", - NULL - ); diff --git a/target/linux/brcm2708/patches-4.19/950-0368-lan78xx-EEE-support-is-now-a-PHY-property.patch b/target/linux/brcm2708/patches-4.19/950-0368-lan78xx-EEE-support-is-now-a-PHY-property.patch new file mode 100644 index 0000000000..cd9b8f3ec9 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0368-lan78xx-EEE-support-is-now-a-PHY-property.patch @@ -0,0 +1,26 @@ +From 6a63c8e17c19fe3aa7b112a0f63fd5ad8b2f9d9c Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 5 Mar 2019 09:51:22 +0000 +Subject: [PATCH 368/725] lan78xx: EEE support is now a PHY property + +Now that EEE support is a property of the PHY, use the PHY's DT node +when querying the EEE-related properties. + +See: https://github.com/raspberrypi/linux/issues/2882 + +Signed-off-by: Phil Elwell +--- + drivers/net/usb/lan78xx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -2191,7 +2191,7 @@ static int lan78xx_phy_init(struct lan78 + mii_adv = (u32)mii_advertise_flowctrl(dev->fc_request_control); + phydev->advertising |= mii_adv_to_ethtool_adv_t(mii_adv); + +- if (of_property_read_bool(dev->udev->dev.of_node, ++ if (of_property_read_bool(phydev->mdio.dev.of_node, + "microchip,eee-enabled")) { + struct ethtool_eee edata; + memset(&edata, 0, sizeof(edata)); diff --git a/target/linux/brcm2708/patches-4.19/950-0369-config-Add-CONFIG_FB_TFT_SH1106-m.patch b/target/linux/brcm2708/patches-4.19/950-0369-config-Add-CONFIG_FB_TFT_SH1106-m.patch deleted file mode 100644 index efd96dd898..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0369-config-Add-CONFIG_FB_TFT_SH1106-m.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 9a9dd897e8de1bbf48dae13f1bdaa99996ab3b52 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 27 Feb 2019 20:08:48 +0000 -Subject: [PATCH 369/703] config: Add CONFIG_FB_TFT_SH1106=m - -See: https://github.com/raspberrypi/linux/issues/2876 - -Signed-off-by: Phil Elwell ---- - arch/arm/configs/bcm2709_defconfig | 3 ++- - arch/arm/configs/bcmrpi_defconfig | 3 ++- - arch/arm64/configs/bcmrpi3_defconfig | 1 + - 3 files changed, 5 insertions(+), 2 deletions(-) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -905,8 +905,8 @@ CONFIG_SND_BCM2835_SOC_I2S=m - CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER=m - CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m --CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m - CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=m -@@ -1203,6 +1203,7 @@ CONFIG_FB_TFT_PCD8544=m - CONFIG_FB_TFT_RA8875=m - CONFIG_FB_TFT_S6D02A1=m - CONFIG_FB_TFT_S6D1121=m -+CONFIG_FB_TFT_SH1106=m - CONFIG_FB_TFT_SSD1289=m - CONFIG_FB_TFT_SSD1306=m - CONFIG_FB_TFT_SSD1331=m ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -898,8 +898,8 @@ CONFIG_SND_BCM2835_SOC_I2S=m - CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER=m - CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m --CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m - CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=m -@@ -1196,6 +1196,7 @@ CONFIG_FB_TFT_PCD8544=m - CONFIG_FB_TFT_RA8875=m - CONFIG_FB_TFT_S6D02A1=m - CONFIG_FB_TFT_S6D1121=m -+CONFIG_FB_TFT_SH1106=m - CONFIG_FB_TFT_SSD1289=m - CONFIG_FB_TFT_SSD1306=m - CONFIG_FB_TFT_SSD1331=m ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -1061,6 +1061,7 @@ CONFIG_FB_TFT_PCD8544=m - CONFIG_FB_TFT_RA8875=m - CONFIG_FB_TFT_S6D02A1=m - CONFIG_FB_TFT_S6D1121=m -+CONFIG_FB_TFT_SH1106=m - CONFIG_FB_TFT_SSD1289=m - CONFIG_FB_TFT_SSD1306=m - CONFIG_FB_TFT_SSD1331=m diff --git a/target/linux/brcm2708/patches-4.19/950-0369-video-bcm2708_fb-Try-allocating-on-the-ARM-and-passi.patch b/target/linux/brcm2708/patches-4.19/950-0369-video-bcm2708_fb-Try-allocating-on-the-ARM-and-passi.patch new file mode 100644 index 0000000000..7409605cb4 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0369-video-bcm2708_fb-Try-allocating-on-the-ARM-and-passi.patch @@ -0,0 +1,162 @@ +From 2f1aba45a3100491bc06f5ce8b9d1e49a5bc261d Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 27 Feb 2019 17:30:33 +0000 +Subject: [PATCH 369/725] video: bcm2708_fb: Try allocating on the ARM and + passing to VPU + +Currently the VPU allocates the contiguous buffer for the +framebuffer. +Try an alternate path first where we use dma_alloc_coherent +and pass the buffer to the VPU. Should the VPU firmware not +support that path, then free the buffer and revert to the +old behaviour of using the VPU allocation. + +Signed-off-by: Dave Stevenson +--- + drivers/video/fbdev/bcm2708_fb.c | 102 ++++++++++++++++++--- + include/soc/bcm2835/raspberrypi-firmware.h | 1 + + 2 files changed, 91 insertions(+), 12 deletions(-) + +--- a/drivers/video/fbdev/bcm2708_fb.c ++++ b/drivers/video/fbdev/bcm2708_fb.c +@@ -98,6 +98,11 @@ struct bcm2708_fb { + struct bcm2708_fb_stats stats; + unsigned long fb_bus_address; + struct { u32 base, length; } gpu; ++ ++ bool disable_arm_alloc; ++ unsigned int image_size; ++ dma_addr_t dma_addr; ++ void *cpuaddr; + }; + + #define to_bcm2708(info) container_of(info, struct bcm2708_fb, fb) +@@ -283,23 +288,88 @@ static int bcm2708_fb_set_par(struct fb_ + .xoffset = info->var.xoffset, + .yoffset = info->var.yoffset, + .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 }, +- .base = 0, +- .screen_size = 0, +- .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH, 4, 0 }, +- .pitch = 0, ++ /* base and screen_size will be initialised later */ ++ .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH, 4, 0 }, ++ /* pitch will be initialised later */ + }; +- int ret; ++ int ret, image_size; ++ + + print_debug("%s(%p) %dx%d (%dx%d), %d, %d\n", __func__, info, + info->var.xres, info->var.yres, info->var.xres_virtual, + info->var.yres_virtual, (int)info->screen_size, + info->var.bits_per_pixel); + +- ret = rpi_firmware_property_list(fb->fw, &fbinfo, sizeof(fbinfo)); ++ /* Try allocating our own buffer. We can specify all the parameters */ ++ image_size = ((info->var.xres * info->var.yres) * ++ info->var.bits_per_pixel) >> 3; ++ ++ if (!fb->disable_arm_alloc && ++ (image_size != fb->image_size || !fb->dma_addr)) { ++ if (fb->dma_addr) { ++ dma_free_coherent(info->device, fb->image_size, ++ fb->cpuaddr, fb->dma_addr); ++ fb->image_size = 0; ++ fb->cpuaddr = NULL; ++ fb->dma_addr = 0; ++ } ++ ++ fb->cpuaddr = dma_alloc_coherent(info->device, image_size, ++ &fb->dma_addr, GFP_KERNEL); ++ ++ if (!fb->cpuaddr) { ++ fb->dma_addr = 0; ++ fb->disable_arm_alloc = true; ++ } else { ++ fb->image_size = image_size; ++ } ++ } ++ ++ if (fb->cpuaddr) { ++ fbinfo.base = fb->dma_addr; ++ fbinfo.screen_size = image_size; ++ fbinfo.pitch = (info->var.xres * info->var.bits_per_pixel) >> 3; ++ ++ ret = rpi_firmware_property_list(fb->fw, &fbinfo, ++ sizeof(fbinfo)); ++ if (ret || fbinfo.base != fb->dma_addr) { ++ /* Firmware either failed, or assigned a different base ++ * address (ie it doesn't support being passed an FB ++ * allocation). ++ * Destroy the allocation, and don't try again. ++ */ ++ dma_free_coherent(info->device, fb->image_size, ++ fb->cpuaddr, fb->dma_addr); ++ fb->image_size = 0; ++ fb->cpuaddr = NULL; ++ fb->dma_addr = 0; ++ fb->disable_arm_alloc = true; ++ } ++ } else { ++ /* Our allocation failed - drop into the old scheme of ++ * allocation by the VPU. ++ */ ++ ret = -ENOMEM; ++ } ++ + if (ret) { +- dev_err(info->device, +- "Failed to allocate GPU framebuffer (%d)\n", ret); +- return ret; ++ /* Old scheme: ++ * - FRAMEBUFFER_ALLOCATE passes 0 for base and screen_size. ++ * - GET_PITCH instead of SET_PITCH. ++ */ ++ fbinfo.base = 0; ++ fbinfo.screen_size = 0; ++ fbinfo.tag6.tag = RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH; ++ fbinfo.pitch = 0; ++ ++ ret = rpi_firmware_property_list(fb->fw, &fbinfo, ++ sizeof(fbinfo)); ++ if (ret) { ++ dev_err(info->device, ++ "Failed to allocate GPU framebuffer (%d)\n", ++ ret); ++ return ret; ++ } + } + + if (info->var.bits_per_pixel <= 8) +@@ -314,9 +384,17 @@ static int bcm2708_fb_set_par(struct fb_ + fb->fb.fix.smem_start = fbinfo.base; + fb->fb.fix.smem_len = fbinfo.pitch * fbinfo.yres_virtual; + fb->fb.screen_size = fbinfo.screen_size; +- if (fb->fb.screen_base) +- iounmap(fb->fb.screen_base); +- fb->fb.screen_base = ioremap_wc(fbinfo.base, fb->fb.screen_size); ++ ++ if (!fb->dma_addr) { ++ if (fb->fb.screen_base) ++ iounmap(fb->fb.screen_base); ++ ++ fb->fb.screen_base = ioremap_wc(fbinfo.base, ++ fb->fb.screen_size); ++ } else { ++ fb->fb.screen_base = fb->cpuaddr; ++ } ++ + if (!fb->fb.screen_base) { + /* the console may currently be locked */ + console_trylock(); +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -128,6 +128,7 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, + RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER = 0x00048006, + RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE = 0x00048007, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH = 0x00048008, + RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, + RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, + RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, diff --git a/target/linux/brcm2708/patches-4.19/950-0370-Added-mute-stream-func.patch b/target/linux/brcm2708/patches-4.19/950-0370-Added-mute-stream-func.patch deleted file mode 100644 index f7e6b4cf0a..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0370-Added-mute-stream-func.patch +++ /dev/null @@ -1,146 +0,0 @@ -From ac5d3c0f1d947302f4d518187357720711f4961d Mon Sep 17 00:00:00 2001 -From: Jaikumar -Date: Thu, 7 Jun 2018 21:22:45 +0530 -Subject: [PATCH 370/703] Added mute stream func - -Signed-off-by: Jaikumar ---- - sound/soc/bcm/allo-katana-codec.c | 60 ++++++++++++++++++++++--------- - 1 file changed, 44 insertions(+), 16 deletions(-) - ---- a/sound/soc/bcm/allo-katana-codec.c -+++ b/sound/soc/bcm/allo-katana-codec.c -@@ -31,21 +31,23 @@ - - #define KATANA_CODEC_CHIP_ID 0x30 - #define KATANA_CODEC_VIRT_BASE 0x100 --#define KATANA_CODEC_PAGE 0 -+#define KATANA_CODEC_PAGE 0 - - #define KATANA_CODEC_CHIP_ID_REG (KATANA_CODEC_VIRT_BASE + 0) --#define KATANA_CODEC_RESET (KATANA_CODEC_VIRT_BASE + 1) -+#define KATANA_CODEC_RESET (KATANA_CODEC_VIRT_BASE + 1) - #define KATANA_CODEC_VOLUME_1 (KATANA_CODEC_VIRT_BASE + 2) - #define KATANA_CODEC_VOLUME_2 (KATANA_CODEC_VIRT_BASE + 3) --#define KATANA_CODEC_MUTE (KATANA_CODEC_VIRT_BASE + 4) -+#define KATANA_CODEC_MUTE (KATANA_CODEC_VIRT_BASE + 4) - #define KATANA_CODEC_DSP_PROGRAM (KATANA_CODEC_VIRT_BASE + 5) - #define KATANA_CODEC_DEEMPHASIS (KATANA_CODEC_VIRT_BASE + 6) --#define KATANA_CODEC_DOP (KATANA_CODEC_VIRT_BASE + 7) --#define KATANA_CODEC_FORMAT (KATANA_CODEC_VIRT_BASE + 8) -+#define KATANA_CODEC_DOP (KATANA_CODEC_VIRT_BASE + 7) -+#define KATANA_CODEC_FORMAT (KATANA_CODEC_VIRT_BASE + 8) - #define KATANA_CODEC_COMMAND (KATANA_CODEC_VIRT_BASE + 9) --#define KATANA_CODEC_MAX_REGISTER (KATANA_CODEC_VIRT_BASE + 9) -+#define KATANA_CODEC_MUTE_STREAM (KATANA_CODEC_VIRT_BASE + 10) - --#define KATANA_CODEC_FMT 0xff -+#define KATANA_CODEC_MAX_REGISTER (KATANA_CODEC_VIRT_BASE + 10) -+ -+#define KATANA_CODEC_FMT 0xff - #define KATANA_CODEC_CHAN_MONO 0x00 - #define KATANA_CODEC_CHAN_STEREO 0x80 - #define KATANA_CODEC_ALEN_16 0x10 -@@ -135,7 +137,8 @@ static const struct snd_kcontrol_new kat - SOC_SINGLE("DoP Playback Switch", KATANA_CODEC_DOP, 0, 1, 1) - }; - --static bool katana_codec_readable_register(struct device *dev, unsigned int reg) -+static bool katana_codec_readable_register(struct device *dev, -+ unsigned int reg) - { - switch (reg) { - case KATANA_CODEC_CHIP_ID_REG: -@@ -150,13 +153,15 @@ static int katana_codec_hw_params(struct - struct snd_soc_dai *dai) - { - struct snd_soc_component *component = dai->component; -- struct katana_codec_priv *katana_codec = snd_soc_component_get_drvdata(component); -+ struct katana_codec_priv *katana_codec = -+ snd_soc_component_get_drvdata(component); - int fmt = 0; - int ret; - -- dev_dbg(component->card->dev, "hw_params %u Hz, %u channels\n", -+ dev_dbg(component->card->dev, "hw_params %u Hz, %u channels, %u bits\n", - params_rate(params), -- params_channels(params)); -+ params_channels(params), -+ params_width(params)); - - switch (katana_codec->fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: // master -@@ -212,13 +217,17 @@ static int katana_codec_hw_params(struct - return -EINVAL; - } - -- ret = regmap_write(katana_codec->regmap, KATANA_CODEC_FORMAT, fmt); -+ ret = regmap_write(katana_codec->regmap, KATANA_CODEC_FORMAT, -+ fmt); - if (ret != 0) { - dev_err(component->card->dev, "Failed to set format: %d\n", ret); - return ret; - } - break; - -+ case SND_SOC_DAIFMT_CBS_CFS: -+ break; -+ - default: - return -EINVAL; - } -@@ -229,14 +238,33 @@ static int katana_codec_hw_params(struct - static int katana_codec_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) - { - struct snd_soc_component *component = dai->component; -- struct katana_codec_priv *katana_codec = snd_soc_component_get_drvdata(component); -+ struct katana_codec_priv *katana_codec = -+ snd_soc_component_get_drvdata(component); - - katana_codec->fmt = fmt; - - return 0; - } - -+int katana_codec_dai_mute_stream(struct snd_soc_dai *dai, int mute, -+ int stream) -+{ -+ struct snd_soc_component *component = dai->component; -+ struct katana_codec_priv *katana_codec = -+ snd_soc_component_get_drvdata(component); -+ int ret = 0; -+ -+ ret = regmap_write(katana_codec->regmap, KATANA_CODEC_MUTE_STREAM, -+ mute); -+ if (ret != 0) { -+ dev_err(component->card->dev, "Failed to set mute: %d\n", ret); -+ return ret; -+ } -+ return ret; -+} -+ - static const struct snd_soc_dai_ops katana_codec_dai_ops = { -+ .mute_stream = katana_codec_dai_mute_stream, - .hw_params = katana_codec_hw_params, - .set_fmt = katana_codec_set_fmt, - }; -@@ -300,7 +328,7 @@ static int allo_katana_component_probe(s - return PTR_ERR(regmap); - - katana_codec = devm_kzalloc(dev, sizeof(struct katana_codec_priv), -- GFP_KERNEL); -+ GFP_KERNEL); - if (!katana_codec) - return -ENOMEM; - -@@ -348,8 +376,8 @@ static struct i2c_driver allo_katana_com - .remove = allo_katana_component_remove, - .id_table = allo_katana_component_id, - .driver = { -- .name = "allo-katana-codec", -- .of_match_table = allo_katana_codec_of_match, -+ .name = "allo-katana-codec", -+ .of_match_table = allo_katana_codec_of_match, - }, - }; - diff --git a/target/linux/brcm2708/patches-4.19/950-0370-staging-vc_sm_cma-Remove-erroneous-misc_deregister.patch b/target/linux/brcm2708/patches-4.19/950-0370-staging-vc_sm_cma-Remove-erroneous-misc_deregister.patch new file mode 100644 index 0000000000..21178db0f3 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0370-staging-vc_sm_cma-Remove-erroneous-misc_deregister.patch @@ -0,0 +1,44 @@ +From 619a09baf2013206075d950ed54093b5573c0886 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 8 Mar 2019 10:38:59 +0000 +Subject: [PATCH 370/725] staging: vc_sm_cma: Remove erroneous misc_deregister + +Code from the misc /dev node was still present in +bcm2835_vc_sm_cma_remove, which caused a NULL deref. +Remove it. + +See #2885. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 5 ----- + 1 file changed, 5 deletions(-) + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -25,7 +25,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -72,7 +71,6 @@ struct sm_pde_t { + struct sm_state_t { + struct platform_device *pdev; + +- struct miscdevice dev; + struct sm_instance *sm_handle; /* Handle for videocore service. */ + + spinlock_t kernelid_map_lock; /* Spinlock protecting kernelid_map */ +@@ -758,9 +756,6 @@ static int bcm2835_vc_sm_cma_remove(stru + { + pr_debug("[%s]: start\n", __func__); + if (sm_inited) { +- /* Remove shared memory device. */ +- misc_deregister(&sm_state->dev); +- + /* Remove all proc entries. */ + //debugfs_remove_recursive(sm_state->dir_root); + diff --git a/target/linux/brcm2708/patches-4.19/950-0371-lan78xx-EEE-support-is-now-a-PHY-property.patch b/target/linux/brcm2708/patches-4.19/950-0371-lan78xx-EEE-support-is-now-a-PHY-property.patch deleted file mode 100644 index dda084d7a3..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0371-lan78xx-EEE-support-is-now-a-PHY-property.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 9fc96f927bdcefe90e8646c23c6eea65b07e72ab Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 5 Mar 2019 09:51:22 +0000 -Subject: [PATCH 371/703] lan78xx: EEE support is now a PHY property - -Now that EEE support is a property of the PHY, use the PHY's DT node -when querying the EEE-related properties. - -See: https://github.com/raspberrypi/linux/issues/2882 - -Signed-off-by: Phil Elwell ---- - drivers/net/usb/lan78xx.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/usb/lan78xx.c -+++ b/drivers/net/usb/lan78xx.c -@@ -2191,7 +2191,7 @@ static int lan78xx_phy_init(struct lan78 - mii_adv = (u32)mii_advertise_flowctrl(dev->fc_request_control); - phydev->advertising |= mii_adv_to_ethtool_adv_t(mii_adv); - -- if (of_property_read_bool(dev->udev->dev.of_node, -+ if (of_property_read_bool(phydev->mdio.dev.of_node, - "microchip,eee-enabled")) { - struct ethtool_eee edata; - memset(&edata, 0, sizeof(edata)); diff --git a/target/linux/brcm2708/patches-4.19/950-0371-vcsm-Fix-makefile-include-on-out-of-tree-builds.patch b/target/linux/brcm2708/patches-4.19/950-0371-vcsm-Fix-makefile-include-on-out-of-tree-builds.patch new file mode 100644 index 0000000000..649c2c00dd --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0371-vcsm-Fix-makefile-include-on-out-of-tree-builds.patch @@ -0,0 +1,27 @@ +From b099a5f2e10c96955495398cf0605dde36b96a77 Mon Sep 17 00:00:00 2001 +From: Kieran Bingham +Date: Mon, 18 Mar 2019 17:14:51 +0000 +Subject: [PATCH 371/725] vcsm: Fix makefile include on out-of-tree builds + +The vc_sm module tries to include the 'fs' directory from the +$(srctree). $(srctree) is already provided by the build system, and +causes the include path to be duplicated. + +With -Werror this fails to compile. + +Remove the unnecessary variable. + +Signed-off-by: Kieran Bingham +--- + drivers/char/broadcom/vc_sm/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/char/broadcom/vc_sm/Makefile ++++ b/drivers/char/broadcom/vc_sm/Makefile +@@ -1,5 +1,5 @@ + ccflags-$(CONFIG_BCM_VC_SM) += -Werror -Wall -Wstrict-prototypes -Wno-trigraphs -O2 +-ccflags-$(CONFIG_BCM_VC_SM) += -I"drivers/staging/vc04_services" -I"drivers/staging/vc04_services/interface/vchi" -I"drivers/staging/vc04_services/interface/vchiq_arm" -I"$(srctree)/fs/" ++ccflags-$(CONFIG_BCM_VC_SM) += -I"drivers/staging/vc04_services" -I"drivers/staging/vc04_services/interface/vchi" -I"drivers/staging/vc04_services/interface/vchiq_arm" -I"fs" + ccflags-$(CONFIG_BCM_VC_SM) += -DOS_ASSERT_FAILURE -D__STDC_VERSION=199901L -D__STDC_VERSION__=199901L -D__VCCOREVER__=0 -D__KERNEL__ -D__linux__ + + obj-$(CONFIG_BCM_VC_SM) := vc-sm.o diff --git a/target/linux/brcm2708/patches-4.19/950-0372-vcsm-Remove-set-but-unused-variable.patch b/target/linux/brcm2708/patches-4.19/950-0372-vcsm-Remove-set-but-unused-variable.patch new file mode 100644 index 0000000000..8da8673352 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0372-vcsm-Remove-set-but-unused-variable.patch @@ -0,0 +1,28 @@ +From 43825a3d741e4c4f4c010349ad59a437cc8de9a8 Mon Sep 17 00:00:00 2001 +From: Kieran Bingham +Date: Mon, 18 Mar 2019 17:16:41 +0000 +Subject: [PATCH 372/725] vcsm: Remove set but unused variable + +The 'success' variable is set by the call to vchi_service_close() but never checked. +Remove it, keeping the call in place. + +Signed-off-by: Kieran Bingham +--- + drivers/char/broadcom/vc_sm/vc_vchi_sm.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/char/broadcom/vc_sm/vc_vchi_sm.c ++++ b/drivers/char/broadcom/vc_sm/vc_vchi_sm.c +@@ -361,11 +361,9 @@ int vc_vchi_sm_stop(struct sm_instance * + + /* Close all VCHI service connections */ + for (i = 0; i < instance->num_connections; i++) { +- int32_t success; +- + vchi_service_use(instance->vchi_handle[i]); + +- success = vchi_service_close(instance->vchi_handle[i]); ++ vchi_service_close(instance->vchi_handle[i]); + } + + kfree(instance); diff --git a/target/linux/brcm2708/patches-4.19/950-0372-video-bcm2708_fb-Try-allocating-on-the-ARM-and-passi.patch b/target/linux/brcm2708/patches-4.19/950-0372-video-bcm2708_fb-Try-allocating-on-the-ARM-and-passi.patch deleted file mode 100644 index aa43b8bc27..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0372-video-bcm2708_fb-Try-allocating-on-the-ARM-and-passi.patch +++ /dev/null @@ -1,162 +0,0 @@ -From 7e709c572681a79ed9f906ceeb01a9cc8ca77049 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 27 Feb 2019 17:30:33 +0000 -Subject: [PATCH 372/703] video: bcm2708_fb: Try allocating on the ARM and - passing to VPU - -Currently the VPU allocates the contiguous buffer for the -framebuffer. -Try an alternate path first where we use dma_alloc_coherent -and pass the buffer to the VPU. Should the VPU firmware not -support that path, then free the buffer and revert to the -old behaviour of using the VPU allocation. - -Signed-off-by: Dave Stevenson ---- - drivers/video/fbdev/bcm2708_fb.c | 102 ++++++++++++++++++--- - include/soc/bcm2835/raspberrypi-firmware.h | 1 + - 2 files changed, 91 insertions(+), 12 deletions(-) - ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -98,6 +98,11 @@ struct bcm2708_fb { - struct bcm2708_fb_stats stats; - unsigned long fb_bus_address; - struct { u32 base, length; } gpu; -+ -+ bool disable_arm_alloc; -+ unsigned int image_size; -+ dma_addr_t dma_addr; -+ void *cpuaddr; - }; - - #define to_bcm2708(info) container_of(info, struct bcm2708_fb, fb) -@@ -283,23 +288,88 @@ static int bcm2708_fb_set_par(struct fb_ - .xoffset = info->var.xoffset, - .yoffset = info->var.yoffset, - .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 }, -- .base = 0, -- .screen_size = 0, -- .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH, 4, 0 }, -- .pitch = 0, -+ /* base and screen_size will be initialised later */ -+ .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH, 4, 0 }, -+ /* pitch will be initialised later */ - }; -- int ret; -+ int ret, image_size; -+ - - print_debug("%s(%p) %dx%d (%dx%d), %d, %d\n", __func__, info, - info->var.xres, info->var.yres, info->var.xres_virtual, - info->var.yres_virtual, (int)info->screen_size, - info->var.bits_per_pixel); - -- ret = rpi_firmware_property_list(fb->fw, &fbinfo, sizeof(fbinfo)); -+ /* Try allocating our own buffer. We can specify all the parameters */ -+ image_size = ((info->var.xres * info->var.yres) * -+ info->var.bits_per_pixel) >> 3; -+ -+ if (!fb->disable_arm_alloc && -+ (image_size != fb->image_size || !fb->dma_addr)) { -+ if (fb->dma_addr) { -+ dma_free_coherent(info->device, fb->image_size, -+ fb->cpuaddr, fb->dma_addr); -+ fb->image_size = 0; -+ fb->cpuaddr = NULL; -+ fb->dma_addr = 0; -+ } -+ -+ fb->cpuaddr = dma_alloc_coherent(info->device, image_size, -+ &fb->dma_addr, GFP_KERNEL); -+ -+ if (!fb->cpuaddr) { -+ fb->dma_addr = 0; -+ fb->disable_arm_alloc = true; -+ } else { -+ fb->image_size = image_size; -+ } -+ } -+ -+ if (fb->cpuaddr) { -+ fbinfo.base = fb->dma_addr; -+ fbinfo.screen_size = image_size; -+ fbinfo.pitch = (info->var.xres * info->var.bits_per_pixel) >> 3; -+ -+ ret = rpi_firmware_property_list(fb->fw, &fbinfo, -+ sizeof(fbinfo)); -+ if (ret || fbinfo.base != fb->dma_addr) { -+ /* Firmware either failed, or assigned a different base -+ * address (ie it doesn't support being passed an FB -+ * allocation). -+ * Destroy the allocation, and don't try again. -+ */ -+ dma_free_coherent(info->device, fb->image_size, -+ fb->cpuaddr, fb->dma_addr); -+ fb->image_size = 0; -+ fb->cpuaddr = NULL; -+ fb->dma_addr = 0; -+ fb->disable_arm_alloc = true; -+ } -+ } else { -+ /* Our allocation failed - drop into the old scheme of -+ * allocation by the VPU. -+ */ -+ ret = -ENOMEM; -+ } -+ - if (ret) { -- dev_err(info->device, -- "Failed to allocate GPU framebuffer (%d)\n", ret); -- return ret; -+ /* Old scheme: -+ * - FRAMEBUFFER_ALLOCATE passes 0 for base and screen_size. -+ * - GET_PITCH instead of SET_PITCH. -+ */ -+ fbinfo.base = 0; -+ fbinfo.screen_size = 0; -+ fbinfo.tag6.tag = RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH; -+ fbinfo.pitch = 0; -+ -+ ret = rpi_firmware_property_list(fb->fw, &fbinfo, -+ sizeof(fbinfo)); -+ if (ret) { -+ dev_err(info->device, -+ "Failed to allocate GPU framebuffer (%d)\n", -+ ret); -+ return ret; -+ } - } - - if (info->var.bits_per_pixel <= 8) -@@ -314,9 +384,17 @@ static int bcm2708_fb_set_par(struct fb_ - fb->fb.fix.smem_start = fbinfo.base; - fb->fb.fix.smem_len = fbinfo.pitch * fbinfo.yres_virtual; - fb->fb.screen_size = fbinfo.screen_size; -- if (fb->fb.screen_base) -- iounmap(fb->fb.screen_base); -- fb->fb.screen_base = ioremap_wc(fbinfo.base, fb->fb.screen_size); -+ -+ if (!fb->dma_addr) { -+ if (fb->fb.screen_base) -+ iounmap(fb->fb.screen_base); -+ -+ fb->fb.screen_base = ioremap_wc(fbinfo.base, -+ fb->fb.screen_size); -+ } else { -+ fb->fb.screen_base = fb->cpuaddr; -+ } -+ - if (!fb->fb.screen_base) { - /* the console may currently be locked */ - console_trylock(); ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -128,6 +128,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, - RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER = 0x00048006, - RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE = 0x00048007, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH = 0x00048008, - RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, - RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, - RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, diff --git a/target/linux/brcm2708/patches-4.19/950-0373-staging-vc_sm_cma-Remove-erroneous-misc_deregister.patch b/target/linux/brcm2708/patches-4.19/950-0373-staging-vc_sm_cma-Remove-erroneous-misc_deregister.patch deleted file mode 100644 index 82d8fe493d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0373-staging-vc_sm_cma-Remove-erroneous-misc_deregister.patch +++ /dev/null @@ -1,44 +0,0 @@ -From d5fc03cec741a893fd37150f3fecef0cbb6ecb19 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 8 Mar 2019 10:38:59 +0000 -Subject: [PATCH 373/703] staging: vc_sm_cma: Remove erroneous misc_deregister - -Code from the misc /dev node was still present in -bcm2835_vc_sm_cma_remove, which caused a NULL deref. -Remove it. - -See #2885. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 5 ----- - 1 file changed, 5 deletions(-) - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -25,7 +25,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -72,7 +71,6 @@ struct sm_pde_t { - struct sm_state_t { - struct platform_device *pdev; - -- struct miscdevice dev; - struct sm_instance *sm_handle; /* Handle for videocore service. */ - - spinlock_t kernelid_map_lock; /* Spinlock protecting kernelid_map */ -@@ -758,9 +756,6 @@ static int bcm2835_vc_sm_cma_remove(stru - { - pr_debug("[%s]: start\n", __func__); - if (sm_inited) { -- /* Remove shared memory device. */ -- misc_deregister(&sm_state->dev); -- - /* Remove all proc entries. */ - //debugfs_remove_recursive(sm_state->dir_root); - diff --git a/target/linux/brcm2708/patches-4.19/950-0373-vcsm-Reduce-scope-of-local-functions.patch b/target/linux/brcm2708/patches-4.19/950-0373-vcsm-Reduce-scope-of-local-functions.patch new file mode 100644 index 0000000000..2a88541aa1 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0373-vcsm-Reduce-scope-of-local-functions.patch @@ -0,0 +1,69 @@ +From 6a0844db98dec3f03b6af8a91d0da108dadda602 Mon Sep 17 00:00:00 2001 +From: Kieran Bingham +Date: Mon, 18 Mar 2019 17:17:40 +0000 +Subject: [PATCH 373/725] vcsm: Reduce scope of local functions + +The functions: + + vc_vchi_sm_send_msg + vc_sm_ioctl_alloc + vc_sm_ioctl_alloc_share + vc_sm_ioctl_import_dmabuf + +Are declared without a prototype. They are not used outside of this +module, thus - convert them to static functions. + +Signed-off-by: Kieran Bingham +--- + drivers/char/broadcom/vc_sm/vc_vchi_sm.c | 2 +- + drivers/char/broadcom/vc_sm/vmcs_sm.c | 14 +++++++------- + 2 files changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/char/broadcom/vc_sm/vc_vchi_sm.c ++++ b/drivers/char/broadcom/vc_sm/vc_vchi_sm.c +@@ -375,7 +375,7 @@ lock: + return -EINVAL; + } + +-int vc_vchi_sm_send_msg(struct sm_instance *handle, ++static int vc_vchi_sm_send_msg(struct sm_instance *handle, + enum vc_sm_msg_type msg_id, + void *msg, uint32_t msg_size, + void *result, uint32_t result_size, +--- a/drivers/char/broadcom/vc_sm/vmcs_sm.c ++++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c +@@ -1574,8 +1574,8 @@ error: + } + + /* Allocate a shared memory handle and block. */ +-int vc_sm_ioctl_alloc(struct sm_priv_data_t *private, +- struct vmcs_sm_ioctl_alloc *ioparam) ++static int vc_sm_ioctl_alloc(struct sm_priv_data_t *private, ++ struct vmcs_sm_ioctl_alloc *ioparam) + { + int ret = 0; + int status; +@@ -1685,8 +1685,8 @@ error: + } + + /* Share an allocate memory handle and block.*/ +-int vc_sm_ioctl_alloc_share(struct sm_priv_data_t *private, +- struct vmcs_sm_ioctl_alloc_share *ioparam) ++static int vc_sm_ioctl_alloc_share(struct sm_priv_data_t *private, ++ struct vmcs_sm_ioctl_alloc_share *ioparam) + { + struct sm_resource_t *resource, *shared_resource; + int ret = 0; +@@ -2200,9 +2200,9 @@ error: + } + + /* Import a contiguous block of memory to be shared with VC. */ +-int vc_sm_ioctl_import_dmabuf(struct sm_priv_data_t *private, +- struct vmcs_sm_ioctl_import_dmabuf *ioparam, +- struct dma_buf *src_dma_buf) ++static int vc_sm_ioctl_import_dmabuf(struct sm_priv_data_t *private, ++ struct vmcs_sm_ioctl_import_dmabuf *ioparam, ++ struct dma_buf *src_dma_buf) + { + int ret = 0; + int status; diff --git a/target/linux/brcm2708/patches-4.19/950-0374-staging-bcm2835-codec-NULL-component-handle-on-queue.patch b/target/linux/brcm2708/patches-4.19/950-0374-staging-bcm2835-codec-NULL-component-handle-on-queue.patch new file mode 100644 index 0000000000..58d51bf5e9 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0374-staging-bcm2835-codec-NULL-component-handle-on-queue.patch @@ -0,0 +1,59 @@ +From 4bf51ec794b95f976557ecafbc278bc00952fc32 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 19 Mar 2019 17:55:09 +0000 +Subject: [PATCH 374/725] staging: bcm2835-codec: NULL component handle on + queue_setup failure + +queue_setup tries creating the relevant MMAL component and configures +the input and output ports as we're expecting to start streaming. +If the port configuration failed then it destroyed the component, +but failed to clear the component handle, therefore release tried +destroying the component again. +Adds some logging should the port config fail as well. + +Signed-off-by: Dave Stevenson +--- + .../bcm2835-codec/bcm2835-v4l2-codec.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -1776,13 +1776,21 @@ static int bcm2835_codec_create_componen + + ret = vchiq_mmal_port_set_format(dev->instance, + &ctx->component->input[0]); +- if (ret < 0) ++ if (ret < 0) { ++ v4l2_dbg(1, debug, &dev->v4l2_dev, ++ "%s: vchiq_mmal_port_set_format ip port failed\n", ++ __func__); + goto destroy_component; ++ } + + ret = vchiq_mmal_port_set_format(dev->instance, + &ctx->component->output[0]); +- if (ret < 0) ++ if (ret < 0) { ++ v4l2_dbg(1, debug, &dev->v4l2_dev, ++ "%s: vchiq_mmal_port_set_format op port failed\n", ++ __func__); + goto destroy_component; ++ } + + if (dev->role == ENCODE) { + u32 param = 1; +@@ -1812,11 +1820,14 @@ static int bcm2835_codec_create_componen + ctx->q_data[V4L2_M2M_DST].sizeimage, + ctx->component->output[0].minimum_buffer.size); + } ++ v4l2_dbg(2, debug, &dev->v4l2_dev, "%s: component created as %s\n", ++ __func__, components[dev->role]); + + return 0; + + destroy_component: + vchiq_mmal_component_finalise(ctx->dev->instance, ctx->component); ++ ctx->component = NULL; + + return ret; + } diff --git a/target/linux/brcm2708/patches-4.19/950-0374-vcsm-Fix-makefile-include-on-out-of-tree-builds.patch b/target/linux/brcm2708/patches-4.19/950-0374-vcsm-Fix-makefile-include-on-out-of-tree-builds.patch deleted file mode 100644 index d4a4539eef..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0374-vcsm-Fix-makefile-include-on-out-of-tree-builds.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 902c22fdf3bf32f26412cef747bc7d657abcf194 Mon Sep 17 00:00:00 2001 -From: Kieran Bingham -Date: Mon, 18 Mar 2019 17:14:51 +0000 -Subject: [PATCH 374/703] vcsm: Fix makefile include on out-of-tree builds - -The vc_sm module tries to include the 'fs' directory from the -$(srctree). $(srctree) is already provided by the build system, and -causes the include path to be duplicated. - -With -Werror this fails to compile. - -Remove the unnecessary variable. - -Signed-off-by: Kieran Bingham ---- - drivers/char/broadcom/vc_sm/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/char/broadcom/vc_sm/Makefile -+++ b/drivers/char/broadcom/vc_sm/Makefile -@@ -1,5 +1,5 @@ - ccflags-$(CONFIG_BCM_VC_SM) += -Werror -Wall -Wstrict-prototypes -Wno-trigraphs -O2 --ccflags-$(CONFIG_BCM_VC_SM) += -I"drivers/staging/vc04_services" -I"drivers/staging/vc04_services/interface/vchi" -I"drivers/staging/vc04_services/interface/vchiq_arm" -I"$(srctree)/fs/" -+ccflags-$(CONFIG_BCM_VC_SM) += -I"drivers/staging/vc04_services" -I"drivers/staging/vc04_services/interface/vchi" -I"drivers/staging/vc04_services/interface/vchiq_arm" -I"fs" - ccflags-$(CONFIG_BCM_VC_SM) += -DOS_ASSERT_FAILURE -D__STDC_VERSION=199901L -D__STDC_VERSION__=199901L -D__VCCOREVER__=0 -D__KERNEL__ -D__linux__ - - obj-$(CONFIG_BCM_VC_SM) := vc-sm.o diff --git a/target/linux/brcm2708/patches-4.19/950-0375-staging-vc-sm-cma-Remove-the-debugfs-directory-on-re.patch b/target/linux/brcm2708/patches-4.19/950-0375-staging-vc-sm-cma-Remove-the-debugfs-directory-on-re.patch new file mode 100644 index 0000000000..635a11ea96 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0375-staging-vc-sm-cma-Remove-the-debugfs-directory-on-re.patch @@ -0,0 +1,24 @@ +From 5dad012904e526aea593b8d70788f22c91c33f19 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 8 Mar 2019 10:49:17 +0000 +Subject: [PATCH 375/725] staging: vc-sm-cma: Remove the debugfs directory on + remove + +Without removing that, reloading the driver fails. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -757,7 +757,7 @@ static int bcm2835_vc_sm_cma_remove(stru + pr_debug("[%s]: start\n", __func__); + if (sm_inited) { + /* Remove all proc entries. */ +- //debugfs_remove_recursive(sm_state->dir_root); ++ debugfs_remove_recursive(sm_state->dir_root); + + /* Stop the videocore shared memory service. */ + vc_sm_cma_vchi_stop(&sm_state->sm_handle); diff --git a/target/linux/brcm2708/patches-4.19/950-0375-vcsm-Remove-set-but-unused-variable.patch b/target/linux/brcm2708/patches-4.19/950-0375-vcsm-Remove-set-but-unused-variable.patch deleted file mode 100644 index cce2facc4b..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0375-vcsm-Remove-set-but-unused-variable.patch +++ /dev/null @@ -1,28 +0,0 @@ -From ea8f08311188a54cafb0ad39702c173ae7c2a3e3 Mon Sep 17 00:00:00 2001 -From: Kieran Bingham -Date: Mon, 18 Mar 2019 17:16:41 +0000 -Subject: [PATCH 375/703] vcsm: Remove set but unused variable - -The 'success' variable is set by the call to vchi_service_close() but never checked. -Remove it, keeping the call in place. - -Signed-off-by: Kieran Bingham ---- - drivers/char/broadcom/vc_sm/vc_vchi_sm.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/char/broadcom/vc_sm/vc_vchi_sm.c -+++ b/drivers/char/broadcom/vc_sm/vc_vchi_sm.c -@@ -361,11 +361,9 @@ int vc_vchi_sm_stop(struct sm_instance * - - /* Close all VCHI service connections */ - for (i = 0; i < instance->num_connections; i++) { -- int32_t success; -- - vchi_service_use(instance->vchi_handle[i]); - -- success = vchi_service_close(instance->vchi_handle[i]); -+ vchi_service_close(instance->vchi_handle[i]); - } - - kfree(instance); diff --git a/target/linux/brcm2708/patches-4.19/950-0376-staging-vc-sm-cma-Use-devm_-allocs-for-sm_state.patch b/target/linux/brcm2708/patches-4.19/950-0376-staging-vc-sm-cma-Use-devm_-allocs-for-sm_state.patch new file mode 100644 index 0000000000..25586bf722 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0376-staging-vc-sm-cma-Use-devm_-allocs-for-sm_state.patch @@ -0,0 +1,69 @@ +From 6c76990e7f308e56f1e11413f6bbf852963c2113 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 8 Mar 2019 11:06:41 +0000 +Subject: [PATCH 376/725] staging: vc-sm-cma: Use devm_ allocs for sm_state. + +Use managed allocations for sm_state, removing reliance on +manual management. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -656,7 +656,7 @@ static void vc_sm_connected_init(void) + __func__, ret); + + ret = -EIO; +- goto err_free_mem; ++ goto err_failed; + } + + ret = vchi_connect(NULL, 0, vchi_instance); +@@ -665,7 +665,7 @@ static void vc_sm_connected_init(void) + __func__, ret); + + ret = -EIO; +- goto err_free_mem; ++ goto err_failed; + } + + /* Initialize an instance of the shared memory service. */ +@@ -676,7 +676,7 @@ static void vc_sm_connected_init(void) + __func__); + + ret = -EPERM; +- goto err_free_mem; ++ goto err_failed; + } + + /* Create a debug fs directory entry (root). */ +@@ -722,8 +722,7 @@ err_remove_shared_memory: + debugfs_remove_recursive(sm_state->dir_root); + err_stop_sm_service: + vc_sm_cma_vchi_stop(&sm_state->sm_handle); +-err_free_mem: +- kfree(sm_state); ++err_failed: + pr_info("[%s]: failed, ret %d\n", __func__, ret); + } + +@@ -732,7 +731,7 @@ static int bcm2835_vc_sm_cma_probe(struc + { + pr_info("%s: Videocore shared memory driver\n", __func__); + +- sm_state = kzalloc(sizeof(*sm_state), GFP_KERNEL); ++ sm_state = devm_kzalloc(&pdev->dev, sizeof(*sm_state), GFP_KERNEL); + if (!sm_state) + return -ENOMEM; + sm_state->pdev = pdev; +@@ -766,7 +765,6 @@ static int bcm2835_vc_sm_cma_remove(stru + + /* Free the memory for the state structure. */ + mutex_destroy(&sm_state->map_lock); +- kfree(sm_state); + } + + pr_debug("[%s]: end\n", __func__); diff --git a/target/linux/brcm2708/patches-4.19/950-0376-vcsm-Reduce-scope-of-local-functions.patch b/target/linux/brcm2708/patches-4.19/950-0376-vcsm-Reduce-scope-of-local-functions.patch deleted file mode 100644 index 2f4134775e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0376-vcsm-Reduce-scope-of-local-functions.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 84195d1efab9720f7d378cd4e01a57eb5b864a2e Mon Sep 17 00:00:00 2001 -From: Kieran Bingham -Date: Mon, 18 Mar 2019 17:17:40 +0000 -Subject: [PATCH 376/703] vcsm: Reduce scope of local functions - -The functions: - - vc_vchi_sm_send_msg - vc_sm_ioctl_alloc - vc_sm_ioctl_alloc_share - vc_sm_ioctl_import_dmabuf - -Are declared without a prototype. They are not used outside of this -module, thus - convert them to static functions. - -Signed-off-by: Kieran Bingham ---- - drivers/char/broadcom/vc_sm/vc_vchi_sm.c | 2 +- - drivers/char/broadcom/vc_sm/vmcs_sm.c | 14 +++++++------- - 2 files changed, 8 insertions(+), 8 deletions(-) - ---- a/drivers/char/broadcom/vc_sm/vc_vchi_sm.c -+++ b/drivers/char/broadcom/vc_sm/vc_vchi_sm.c -@@ -375,7 +375,7 @@ lock: - return -EINVAL; - } - --int vc_vchi_sm_send_msg(struct sm_instance *handle, -+static int vc_vchi_sm_send_msg(struct sm_instance *handle, - enum vc_sm_msg_type msg_id, - void *msg, uint32_t msg_size, - void *result, uint32_t result_size, ---- a/drivers/char/broadcom/vc_sm/vmcs_sm.c -+++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c -@@ -1574,8 +1574,8 @@ error: - } - - /* Allocate a shared memory handle and block. */ --int vc_sm_ioctl_alloc(struct sm_priv_data_t *private, -- struct vmcs_sm_ioctl_alloc *ioparam) -+static int vc_sm_ioctl_alloc(struct sm_priv_data_t *private, -+ struct vmcs_sm_ioctl_alloc *ioparam) - { - int ret = 0; - int status; -@@ -1685,8 +1685,8 @@ error: - } - - /* Share an allocate memory handle and block.*/ --int vc_sm_ioctl_alloc_share(struct sm_priv_data_t *private, -- struct vmcs_sm_ioctl_alloc_share *ioparam) -+static int vc_sm_ioctl_alloc_share(struct sm_priv_data_t *private, -+ struct vmcs_sm_ioctl_alloc_share *ioparam) - { - struct sm_resource_t *resource, *shared_resource; - int ret = 0; -@@ -2200,9 +2200,9 @@ error: - } - - /* Import a contiguous block of memory to be shared with VC. */ --int vc_sm_ioctl_import_dmabuf(struct sm_priv_data_t *private, -- struct vmcs_sm_ioctl_import_dmabuf *ioparam, -- struct dma_buf *src_dma_buf) -+static int vc_sm_ioctl_import_dmabuf(struct sm_priv_data_t *private, -+ struct vmcs_sm_ioctl_import_dmabuf *ioparam, -+ struct dma_buf *src_dma_buf) - { - int ret = 0; - int status; diff --git a/target/linux/brcm2708/patches-4.19/950-0377-staging-bcm2835-codec-NULL-component-handle-on-queue.patch b/target/linux/brcm2708/patches-4.19/950-0377-staging-bcm2835-codec-NULL-component-handle-on-queue.patch deleted file mode 100644 index 37d499a84e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0377-staging-bcm2835-codec-NULL-component-handle-on-queue.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 521d98b25f82438027cb6b88bdbb76d552426aae Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 19 Mar 2019 17:55:09 +0000 -Subject: [PATCH 377/703] staging: bcm2835-codec: NULL component handle on - queue_setup failure - -queue_setup tries creating the relevant MMAL component and configures -the input and output ports as we're expecting to start streaming. -If the port configuration failed then it destroyed the component, -but failed to clear the component handle, therefore release tried -destroying the component again. -Adds some logging should the port config fail as well. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 15 +++++++++++++-- - 1 file changed, 13 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -1776,13 +1776,21 @@ static int bcm2835_codec_create_componen - - ret = vchiq_mmal_port_set_format(dev->instance, - &ctx->component->input[0]); -- if (ret < 0) -+ if (ret < 0) { -+ v4l2_dbg(1, debug, &dev->v4l2_dev, -+ "%s: vchiq_mmal_port_set_format ip port failed\n", -+ __func__); - goto destroy_component; -+ } - - ret = vchiq_mmal_port_set_format(dev->instance, - &ctx->component->output[0]); -- if (ret < 0) -+ if (ret < 0) { -+ v4l2_dbg(1, debug, &dev->v4l2_dev, -+ "%s: vchiq_mmal_port_set_format op port failed\n", -+ __func__); - goto destroy_component; -+ } - - if (dev->role == ENCODE) { - u32 param = 1; -@@ -1812,11 +1820,14 @@ static int bcm2835_codec_create_componen - ctx->q_data[V4L2_M2M_DST].sizeimage, - ctx->component->output[0].minimum_buffer.size); - } -+ v4l2_dbg(2, debug, &dev->v4l2_dev, "%s: component created as %s\n", -+ __func__, components[dev->role]); - - return 0; - - destroy_component: - vchiq_mmal_component_finalise(ctx->dev->instance, ctx->component); -+ ctx->component = NULL; - - return ret; - } diff --git a/target/linux/brcm2708/patches-4.19/950-0377-staging-vc-sm-cma-Don-t-fail-if-debugfs-calls-fail.patch b/target/linux/brcm2708/patches-4.19/950-0377-staging-vc-sm-cma-Don-t-fail-if-debugfs-calls-fail.patch new file mode 100644 index 0000000000..f8d468fc82 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0377-staging-vc-sm-cma-Don-t-fail-if-debugfs-calls-fail.patch @@ -0,0 +1,37 @@ +From 0631e31c3eb8c6d7ca996cac1cb207d25c4cfa75 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 8 Mar 2019 11:09:49 +0000 +Subject: [PATCH 377/725] staging: vc-sm-cma: Don't fail if debugfs calls fail. + +Return codes from debugfs calls should never alter the +flow of the main code. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 8 -------- + 1 file changed, 8 deletions(-) + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -681,13 +681,6 @@ static void vc_sm_connected_init(void) + + /* Create a debug fs directory entry (root). */ + sm_state->dir_root = debugfs_create_dir(VC_SM_DIR_ROOT_NAME, NULL); +- if (!sm_state->dir_root) { +- pr_err("[%s]: failed to create \'%s\' directory entry\n", +- __func__, VC_SM_DIR_ROOT_NAME); +- +- ret = -EPERM; +- goto err_stop_sm_service; +- } + + sm_state->dir_state.show = &vc_sm_cma_global_state_show; + sm_state->dir_state.dir_entry = +@@ -720,7 +713,6 @@ static void vc_sm_connected_init(void) + + err_remove_shared_memory: + debugfs_remove_recursive(sm_state->dir_root); +-err_stop_sm_service: + vc_sm_cma_vchi_stop(&sm_state->sm_handle); + err_failed: + pr_info("[%s]: failed, ret %d\n", __func__, ret); diff --git a/target/linux/brcm2708/patches-4.19/950-0378-staging-vc-sm-cma-Ensure-mutex-and-idr-are-destroyed.patch b/target/linux/brcm2708/patches-4.19/950-0378-staging-vc-sm-cma-Ensure-mutex-and-idr-are-destroyed.patch new file mode 100644 index 0000000000..3b8dbff3c0 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0378-staging-vc-sm-cma-Ensure-mutex-and-idr-are-destroyed.patch @@ -0,0 +1,27 @@ +From 00c129ebdf07e600f112197e62435aa6485a2e59 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 8 Mar 2019 11:11:46 +0000 +Subject: [PATCH 378/725] staging: vc-sm-cma: Ensure mutex and idr are + destroyed + +map_lock and kernelid_map are created in probe, but not released +in release should the vcsm service not connect (eg running the +cutdown firmware). + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -752,7 +752,9 @@ static int bcm2835_vc_sm_cma_remove(stru + + /* Stop the videocore shared memory service. */ + vc_sm_cma_vchi_stop(&sm_state->sm_handle); ++ } + ++ if (sm_state) { + idr_destroy(&sm_state->kernelid_map); + + /* Free the memory for the state structure. */ diff --git a/target/linux/brcm2708/patches-4.19/950-0378-staging-vc-sm-cma-Remove-the-debugfs-directory-on-re.patch b/target/linux/brcm2708/patches-4.19/950-0378-staging-vc-sm-cma-Remove-the-debugfs-directory-on-re.patch deleted file mode 100644 index 1456a2b9a8..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0378-staging-vc-sm-cma-Remove-the-debugfs-directory-on-re.patch +++ /dev/null @@ -1,24 +0,0 @@ -From efa4c15a8012b80f3c1a63d7b79bfbaf013bf404 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 8 Mar 2019 10:49:17 +0000 -Subject: [PATCH 378/703] staging: vc-sm-cma: Remove the debugfs directory on - remove - -Without removing that, reloading the driver fails. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -757,7 +757,7 @@ static int bcm2835_vc_sm_cma_remove(stru - pr_debug("[%s]: start\n", __func__); - if (sm_inited) { - /* Remove all proc entries. */ -- //debugfs_remove_recursive(sm_state->dir_root); -+ debugfs_remove_recursive(sm_state->dir_root); - - /* Stop the videocore shared memory service. */ - vc_sm_cma_vchi_stop(&sm_state->sm_handle); diff --git a/target/linux/brcm2708/patches-4.19/950-0379-staging-bcm2835_codec-Clean-up-logging-on-unloading-.patch b/target/linux/brcm2708/patches-4.19/950-0379-staging-bcm2835_codec-Clean-up-logging-on-unloading-.patch new file mode 100644 index 0000000000..391a70d1dd --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0379-staging-bcm2835_codec-Clean-up-logging-on-unloading-.patch @@ -0,0 +1,49 @@ +From 3c6328c7e96f5422a772c1d07f04dbebdc99955b Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 8 Mar 2019 11:26:00 +0000 +Subject: [PATCH 379/725] staging: bcm2835_codec: Clean up logging on unloading + the driver + +The log line was missing a closing \n, so wasn't added to the +log immediately. +Adds the function of the V4L2 device that is being unregistered +too. + +Signed-off-by: Dave Stevenson +--- + .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -77,6 +77,12 @@ enum bcm2835_codec_role { + ISP, + }; + ++const static char *roles[] = { ++ "decode", ++ "encode", ++ "isp" ++}; ++ + static const char * const components[] = { + "ril.video_decode", + "ril.video_encode", +@@ -2522,7 +2528,6 @@ static int bcm2835_codec_create(struct p + struct video_device *vfd; + int video_nr; + int ret; +- const static char *roles[] = {"decode", "encode", "isp"}; + + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); + if (!dev) +@@ -2615,7 +2620,8 @@ static int bcm2835_codec_destroy(struct + if (!dev) + return -ENODEV; + +- v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME); ++ v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME ", %s\n", ++ roles[dev->role]); + v4l2_m2m_release(dev->m2m_dev); + video_unregister_device(&dev->vfd); + v4l2_device_unregister(&dev->v4l2_dev); diff --git a/target/linux/brcm2708/patches-4.19/950-0379-staging-vc-sm-cma-Use-devm_-allocs-for-sm_state.patch b/target/linux/brcm2708/patches-4.19/950-0379-staging-vc-sm-cma-Use-devm_-allocs-for-sm_state.patch deleted file mode 100644 index 5473144316..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0379-staging-vc-sm-cma-Use-devm_-allocs-for-sm_state.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 95d0b2763bc5b18a8e9f7dc2db1ff101364056ef Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 8 Mar 2019 11:06:41 +0000 -Subject: [PATCH 379/703] staging: vc-sm-cma: Use devm_ allocs for sm_state. - -Use managed allocations for sm_state, removing reliance on -manual management. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 12 +++++------- - 1 file changed, 5 insertions(+), 7 deletions(-) - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -656,7 +656,7 @@ static void vc_sm_connected_init(void) - __func__, ret); - - ret = -EIO; -- goto err_free_mem; -+ goto err_failed; - } - - ret = vchi_connect(NULL, 0, vchi_instance); -@@ -665,7 +665,7 @@ static void vc_sm_connected_init(void) - __func__, ret); - - ret = -EIO; -- goto err_free_mem; -+ goto err_failed; - } - - /* Initialize an instance of the shared memory service. */ -@@ -676,7 +676,7 @@ static void vc_sm_connected_init(void) - __func__); - - ret = -EPERM; -- goto err_free_mem; -+ goto err_failed; - } - - /* Create a debug fs directory entry (root). */ -@@ -722,8 +722,7 @@ err_remove_shared_memory: - debugfs_remove_recursive(sm_state->dir_root); - err_stop_sm_service: - vc_sm_cma_vchi_stop(&sm_state->sm_handle); --err_free_mem: -- kfree(sm_state); -+err_failed: - pr_info("[%s]: failed, ret %d\n", __func__, ret); - } - -@@ -732,7 +731,7 @@ static int bcm2835_vc_sm_cma_probe(struc - { - pr_info("%s: Videocore shared memory driver\n", __func__); - -- sm_state = kzalloc(sizeof(*sm_state), GFP_KERNEL); -+ sm_state = devm_kzalloc(&pdev->dev, sizeof(*sm_state), GFP_KERNEL); - if (!sm_state) - return -ENOMEM; - sm_state->pdev = pdev; -@@ -766,7 +765,6 @@ static int bcm2835_vc_sm_cma_remove(stru - - /* Free the memory for the state structure. */ - mutex_destroy(&sm_state->map_lock); -- kfree(sm_state); - } - - pr_debug("[%s]: end\n", __func__); diff --git a/target/linux/brcm2708/patches-4.19/950-0380-configs-Enable-MT76-USB-wifi.patch b/target/linux/brcm2708/patches-4.19/950-0380-configs-Enable-MT76-USB-wifi.patch new file mode 100644 index 0000000000..3f398e12a2 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0380-configs-Enable-MT76-USB-wifi.patch @@ -0,0 +1,45 @@ +From cbdcfb234a1fff16c988f2c4660ac8a6755b63d8 Mon Sep 17 00:00:00 2001 +From: Stefan Wahren +Date: Thu, 7 Mar 2019 19:27:05 +0100 +Subject: [PATCH 380/725] configs: Enable MT76 USB wifi + +Signed-off-by: Stefan Wahren +--- + 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 +@@ -526,6 +526,8 @@ CONFIG_LIBERTAS_THINFIRM_USB=m + CONFIG_MWIFIEX=m + CONFIG_MWIFIEX_SDIO=m + CONFIG_MT7601U=m ++CONFIG_MT76x0U=m ++CONFIG_MT76x2U=m + CONFIG_RT2X00=m + CONFIG_RT2500USB=m + CONFIG_RT73USB=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -520,6 +520,8 @@ CONFIG_LIBERTAS_THINFIRM_USB=m + CONFIG_MWIFIEX=m + CONFIG_MWIFIEX_SDIO=m + CONFIG_MT7601U=m ++CONFIG_MT76x0U=m ++CONFIG_MT76x2U=m + CONFIG_RT2X00=m + CONFIG_RT2500USB=m + CONFIG_RT73USB=m +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -512,6 +512,8 @@ CONFIG_LIBERTAS_THINFIRM_USB=m + CONFIG_MWIFIEX=m + CONFIG_MWIFIEX_SDIO=m + CONFIG_MT7601U=m ++CONFIG_MT76x0U=m ++CONFIG_MT76x2U=m + CONFIG_RT2X00=m + CONFIG_RT2500USB=m + CONFIG_RT73USB=m diff --git a/target/linux/brcm2708/patches-4.19/950-0380-staging-vc-sm-cma-Don-t-fail-if-debugfs-calls-fail.patch b/target/linux/brcm2708/patches-4.19/950-0380-staging-vc-sm-cma-Don-t-fail-if-debugfs-calls-fail.patch deleted file mode 100644 index d7016935f9..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0380-staging-vc-sm-cma-Don-t-fail-if-debugfs-calls-fail.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 367e360d68d9dfd7f1b213a47576139ffb6028c8 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 8 Mar 2019 11:09:49 +0000 -Subject: [PATCH 380/703] staging: vc-sm-cma: Don't fail if debugfs calls fail. - -Return codes from debugfs calls should never alter the -flow of the main code. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 8 -------- - 1 file changed, 8 deletions(-) - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -681,13 +681,6 @@ static void vc_sm_connected_init(void) - - /* Create a debug fs directory entry (root). */ - sm_state->dir_root = debugfs_create_dir(VC_SM_DIR_ROOT_NAME, NULL); -- if (!sm_state->dir_root) { -- pr_err("[%s]: failed to create \'%s\' directory entry\n", -- __func__, VC_SM_DIR_ROOT_NAME); -- -- ret = -EPERM; -- goto err_stop_sm_service; -- } - - sm_state->dir_state.show = &vc_sm_cma_global_state_show; - sm_state->dir_state.dir_entry = -@@ -720,7 +713,6 @@ static void vc_sm_connected_init(void) - - err_remove_shared_memory: - debugfs_remove_recursive(sm_state->dir_root); --err_stop_sm_service: - vc_sm_cma_vchi_stop(&sm_state->sm_handle); - err_failed: - pr_info("[%s]: failed, ret %d\n", __func__, ret); diff --git a/target/linux/brcm2708/patches-4.19/950-0381-bcm2835-sdhost-Allow-for-sg-entries-that-cross-pages.patch b/target/linux/brcm2708/patches-4.19/950-0381-bcm2835-sdhost-Allow-for-sg-entries-that-cross-pages.patch new file mode 100644 index 0000000000..8aa69c8dbb --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0381-bcm2835-sdhost-Allow-for-sg-entries-that-cross-pages.patch @@ -0,0 +1,32 @@ +From d107d70cd01d1cd93fe0c61d8c0fc0ff7a2fc064 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 13 Mar 2019 14:19:11 +0000 +Subject: [PATCH 381/725] bcm2835-sdhost: Allow for sg entries that cross pages + +The dma_complete handling code calculates a virtual address for a page +then adds an offset, but if the offset is more than a page and HIGHMEM +is in use then the summed address could be in an unmapped (or just +incorrect) page. + +The upstream SDHOST driver allows for this possibility - copy the code +that does so. + +Signed-off-by: Phil Elwell +--- + drivers/mmc/host/bcm2835-sdhost.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/mmc/host/bcm2835-sdhost.c ++++ b/drivers/mmc/host/bcm2835-sdhost.c +@@ -543,6 +543,11 @@ static void bcm2835_sdhost_dma_complete( + void *page; + u32 *buf; + ++ if (host->drain_offset & PAGE_MASK) { ++ host->drain_page += host->drain_offset >> PAGE_SHIFT; ++ host->drain_offset &= ~PAGE_MASK; ++ } ++ + page = kmap_atomic(host->drain_page); + buf = page + host->drain_offset; + diff --git a/target/linux/brcm2708/patches-4.19/950-0381-staging-vc-sm-cma-Ensure-mutex-and-idr-are-destroyed.patch b/target/linux/brcm2708/patches-4.19/950-0381-staging-vc-sm-cma-Ensure-mutex-and-idr-are-destroyed.patch deleted file mode 100644 index 6c0f1d09df..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0381-staging-vc-sm-cma-Ensure-mutex-and-idr-are-destroyed.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 47046caff7455c46f07b7fd816cdd23ab9801842 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 8 Mar 2019 11:11:46 +0000 -Subject: [PATCH 381/703] staging: vc-sm-cma: Ensure mutex and idr are - destroyed - -map_lock and kernelid_map are created in probe, but not released -in release should the vcsm service not connect (eg running the -cutdown firmware). - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -752,7 +752,9 @@ static int bcm2835_vc_sm_cma_remove(stru - - /* Stop the videocore shared memory service. */ - vc_sm_cma_vchi_stop(&sm_state->sm_handle); -+ } - -+ if (sm_state) { - idr_destroy(&sm_state->kernelid_map); - - /* Free the memory for the state structure. */ diff --git a/target/linux/brcm2708/patches-4.19/950-0382-overlays-sdio-Added-4-bit-support-on-GPIOs-34-39.-29.patch b/target/linux/brcm2708/patches-4.19/950-0382-overlays-sdio-Added-4-bit-support-on-GPIOs-34-39.-29.patch new file mode 100644 index 0000000000..52c4217c8f --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0382-overlays-sdio-Added-4-bit-support-on-GPIOs-34-39.-29.patch @@ -0,0 +1,47 @@ +From 71b44014034d34752cc9dcd23b364da15e059b54 Mon Sep 17 00:00:00 2001 +From: Adrien RICCIARDI +Date: Fri, 22 Mar 2019 11:35:30 +0100 +Subject: [PATCH 382/725] overlays: sdio: Added 4-bit support on GPIOs 34-39. + (#2903) + +--- + arch/arm/boot/dts/overlays/README | 3 +++ + arch/arm/boot/dts/overlays/sdio-overlay.dts | 9 +++++++++ + 2 files changed, 12 insertions(+) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1785,6 +1785,9 @@ Params: sdio_overclock SDIO Clo + gpios_34_37 Select GPIOs 34-37 for 1-bit mode. Must be used + with bus_width=1. + ++ gpios_34_39 Select GPIOs 34-39 for 4-bit mode. Must be used ++ with bus_width=4 (the default). ++ + + Name: sdio-1bit + Info: This overlay is now deprecated. Use +--- a/arch/arm/boot/dts/overlays/sdio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts +@@ -64,6 +64,14 @@ + }; + }; + ++ fragment@5 { ++ target = <&sdio_ovl_pins>; ++ __dormant__ { ++ brcm,pins = <34 35 36 37 38 39>; ++ brcm,pull = <0 2 2 2 2 2>; ++ }; ++ }; ++ + fragment@6 { + target-path = "/aliases"; + __overlay__ { +@@ -77,5 +85,6 @@ + sdio_overclock = <&sdio_ovl>,"brcm,overclock-50:0"; + gpios_22_25 = <0>,"=3"; + gpios_34_37 = <0>,"=4"; ++ gpios_34_39 = <0>,"=5"; + }; + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0382-staging-bcm2835_codec-Clean-up-logging-on-unloading-.patch b/target/linux/brcm2708/patches-4.19/950-0382-staging-bcm2835_codec-Clean-up-logging-on-unloading-.patch deleted file mode 100644 index 632c4f3a59..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0382-staging-bcm2835_codec-Clean-up-logging-on-unloading-.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 7b588426000023ff56672cb1e2811e382cb49032 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 8 Mar 2019 11:26:00 +0000 -Subject: [PATCH 382/703] staging: bcm2835_codec: Clean up logging on unloading - the driver - -The log line was missing a closing \n, so wasn't added to the -log immediately. -Adds the function of the V4L2 device that is being unregistered -too. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -77,6 +77,12 @@ enum bcm2835_codec_role { - ISP, - }; - -+const static char *roles[] = { -+ "decode", -+ "encode", -+ "isp" -+}; -+ - static const char * const components[] = { - "ril.video_decode", - "ril.video_encode", -@@ -2522,7 +2528,6 @@ static int bcm2835_codec_create(struct p - struct video_device *vfd; - int video_nr; - int ret; -- const static char *roles[] = {"decode", "encode", "isp"}; - - dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); - if (!dev) -@@ -2615,7 +2620,8 @@ static int bcm2835_codec_destroy(struct - if (!dev) - return -ENODEV; - -- v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME); -+ v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME ", %s\n", -+ roles[dev->role]); - v4l2_m2m_release(dev->m2m_dev); - video_unregister_device(&dev->vfd); - v4l2_device_unregister(&dev->v4l2_dev); diff --git a/target/linux/brcm2708/patches-4.19/950-0383-configs-Enable-MT76-USB-wifi.patch b/target/linux/brcm2708/patches-4.19/950-0383-configs-Enable-MT76-USB-wifi.patch deleted file mode 100644 index a938c986f4..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0383-configs-Enable-MT76-USB-wifi.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 942452eb02558e142288e4e9476281d5a5554cb2 Mon Sep 17 00:00:00 2001 -From: Stefan Wahren -Date: Thu, 7 Mar 2019 19:27:05 +0100 -Subject: [PATCH 383/703] configs: Enable MT76 USB wifi - -Signed-off-by: Stefan Wahren ---- - 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 -@@ -526,6 +526,8 @@ CONFIG_LIBERTAS_THINFIRM_USB=m - CONFIG_MWIFIEX=m - CONFIG_MWIFIEX_SDIO=m - CONFIG_MT7601U=m -+CONFIG_MT76x0U=m -+CONFIG_MT76x2U=m - CONFIG_RT2X00=m - CONFIG_RT2500USB=m - CONFIG_RT73USB=m ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -520,6 +520,8 @@ CONFIG_LIBERTAS_THINFIRM_USB=m - CONFIG_MWIFIEX=m - CONFIG_MWIFIEX_SDIO=m - CONFIG_MT7601U=m -+CONFIG_MT76x0U=m -+CONFIG_MT76x2U=m - CONFIG_RT2X00=m - CONFIG_RT2500USB=m - CONFIG_RT73USB=m ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -512,6 +512,8 @@ CONFIG_LIBERTAS_THINFIRM_USB=m - CONFIG_MWIFIEX=m - CONFIG_MWIFIEX_SDIO=m - CONFIG_MT7601U=m -+CONFIG_MT76x0U=m -+CONFIG_MT76x2U=m - CONFIG_RT2X00=m - CONFIG_RT2500USB=m - CONFIG_RT73USB=m diff --git a/target/linux/brcm2708/patches-4.19/950-0383-overlays-Fix-multiple-instantiation-of-sc16is7xx.patch b/target/linux/brcm2708/patches-4.19/950-0383-overlays-Fix-multiple-instantiation-of-sc16is7xx.patch new file mode 100644 index 0000000000..15badf1481 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0383-overlays-Fix-multiple-instantiation-of-sc16is7xx.patch @@ -0,0 +1,57 @@ +From 94090199a0033419d35c90cd23ff9450f77b19e8 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 22 Mar 2019 16:44:47 +0000 +Subject: [PATCH 383/725] overlays: Fix multiple-instantiation of sc16is7xx* + +The registration of the fixed clocks uses the node name as the clock +name, causing a clash if two clock nodes have the same name, regardless +of the path to the node. Fix the issue by overwriting the clock node +names using the value of the "addr" parameter, providing a crude +disambiguation. (A bit of string pasting to form "sc16is752_clk_" +would have been nice, but that is outside the abilities of the overlay +parameter mechanism.) + +Also give the sc16is750-i2c overlay the xtal parameter for symmetry. + +See: https://www.raspberrypi.org/forums/viewtopic.php?f=107&t=235650 + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/README | 1 + + arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts | 3 ++- + arch/arm/boot/dts/overlays/sc16is752-i2c-overlay.dts | 2 +- + 3 files changed, 4 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1725,6 +1725,7 @@ Info: Overlay for the NXP SC16IS750 UA + Load: dtoverlay=sc16is750-i2c,= + Params: int_pin GPIO used for IRQ (default 24) + addr Address (default 0x48) ++ xtal On-board crystal frequency (default 14745600) + + + Name: sc16is752-i2c +--- a/arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts +@@ -31,7 +31,8 @@ + + __overrides__ { + int_pin = <&sc16is750>,"interrupts:0"; +- addr = <&sc16is750>,"reg:0"; ++ addr = <&sc16is750>,"reg:0",<&sc16is750_clk>,"name"; ++ xtal = <&sc16is750>,"clock-frequency:0"; + }; + + }; +--- a/arch/arm/boot/dts/overlays/sc16is752-i2c-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sc16is752-i2c-overlay.dts +@@ -34,7 +34,7 @@ + + __overrides__ { + int_pin = <&sc16is752>,"interrupts:0"; +- addr = <&sc16is752>,"reg:0"; ++ addr = <&sc16is752>,"reg:0",<&sc16is752_clk>,"name"; + xtal = <&sc16is752>,"clock-frequency:0"; + }; + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0384-bcm2835-sdhost-Allow-for-sg-entries-that-cross-pages.patch b/target/linux/brcm2708/patches-4.19/950-0384-bcm2835-sdhost-Allow-for-sg-entries-that-cross-pages.patch deleted file mode 100644 index 719cd6669c..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0384-bcm2835-sdhost-Allow-for-sg-entries-that-cross-pages.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 7d87e7c1dbf0be8015daec4ae7eb2a87147915d5 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 13 Mar 2019 14:19:11 +0000 -Subject: [PATCH 384/703] bcm2835-sdhost: Allow for sg entries that cross pages - -The dma_complete handling code calculates a virtual address for a page -then adds an offset, but if the offset is more than a page and HIGHMEM -is in use then the summed address could be in an unmapped (or just -incorrect) page. - -The upstream SDHOST driver allows for this possibility - copy the code -that does so. - -Signed-off-by: Phil Elwell ---- - drivers/mmc/host/bcm2835-sdhost.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -543,6 +543,11 @@ static void bcm2835_sdhost_dma_complete( - void *page; - u32 *buf; - -+ if (host->drain_offset & PAGE_MASK) { -+ host->drain_page += host->drain_offset >> PAGE_SHIFT; -+ host->drain_offset &= ~PAGE_MASK; -+ } -+ - page = kmap_atomic(host->drain_page); - buf = page + host->drain_offset; - diff --git a/target/linux/brcm2708/patches-4.19/950-0384-configs-Re-enable-CONFIG_NETFILTER_XT_MATCH_SOCKET.patch b/target/linux/brcm2708/patches-4.19/950-0384-configs-Re-enable-CONFIG_NETFILTER_XT_MATCH_SOCKET.patch new file mode 100644 index 0000000000..c8f2f084fb --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0384-configs-Re-enable-CONFIG_NETFILTER_XT_MATCH_SOCKET.patch @@ -0,0 +1,47 @@ +From d5175a2f4c71f99a997aff9a1b441152896d34bd Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Sun, 24 Mar 2019 20:54:25 +0000 +Subject: [PATCH 384/725] configs: Re-enable CONFIG_NETFILTER_XT_MATCH_SOCKET + +A Kconfig change in 4.10 caused the xt_socket module to no-longer be +included in Raspbian builds. Fix the defconfigs to re-enable it. + +See: https://github.com/raspberrypi/linux/issues/2905 + +Signed-off-by: Phil Elwell +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + arch/arm64/configs/bcmrpi3_defconfig | 1 + + 3 files changed, 3 insertions(+) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -186,6 +186,7 @@ CONFIG_NETFILTER_XT_MATCH_QUOTA=m + CONFIG_NETFILTER_XT_MATCH_RATEEST=m + CONFIG_NETFILTER_XT_MATCH_REALM=m + CONFIG_NETFILTER_XT_MATCH_RECENT=m ++CONFIG_NETFILTER_XT_MATCH_SOCKET=m + CONFIG_NETFILTER_XT_MATCH_STATE=m + CONFIG_NETFILTER_XT_MATCH_STATISTIC=m + CONFIG_NETFILTER_XT_MATCH_STRING=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -180,6 +180,7 @@ CONFIG_NETFILTER_XT_MATCH_QUOTA=m + CONFIG_NETFILTER_XT_MATCH_RATEEST=m + CONFIG_NETFILTER_XT_MATCH_REALM=m + CONFIG_NETFILTER_XT_MATCH_RECENT=m ++CONFIG_NETFILTER_XT_MATCH_SOCKET=m + CONFIG_NETFILTER_XT_MATCH_STATE=m + CONFIG_NETFILTER_XT_MATCH_STATISTIC=m + CONFIG_NETFILTER_XT_MATCH_STRING=m +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -181,6 +181,7 @@ CONFIG_NETFILTER_XT_MATCH_QUOTA=m + CONFIG_NETFILTER_XT_MATCH_RATEEST=m + CONFIG_NETFILTER_XT_MATCH_REALM=m + CONFIG_NETFILTER_XT_MATCH_RECENT=m ++CONFIG_NETFILTER_XT_MATCH_SOCKET=m + CONFIG_NETFILTER_XT_MATCH_STATE=m + CONFIG_NETFILTER_XT_MATCH_STATISTIC=m + CONFIG_NETFILTER_XT_MATCH_STRING=m diff --git a/target/linux/brcm2708/patches-4.19/950-0385-bcm2835-mmc-Fix-DMA-channel-leak.patch b/target/linux/brcm2708/patches-4.19/950-0385-bcm2835-mmc-Fix-DMA-channel-leak.patch new file mode 100644 index 0000000000..22ebcd83a2 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0385-bcm2835-mmc-Fix-DMA-channel-leak.patch @@ -0,0 +1,42 @@ +From d41f9c275d6cded64675a2b97084e9fdba8484f3 Mon Sep 17 00:00:00 2001 +From: Lukas Wunner +Date: Wed, 16 Jan 2019 12:22:32 +0100 +Subject: [PATCH 385/725] bcm2835-mmc: Fix DMA channel leak + +The BCM2835 MMC host driver requests a DMA channel on probe but neglects +to release the channel in the probe error path and on driver unbind. + +I'm seeing this happen on every boot of the Compute Module 3: On first +driver probe, DMA channel 2 is allocated and then leaked with a "could +not get clk, deferring probe" message. On second driver probe, channel 4 +is allocated. + +Fix it. + +Signed-off-by: Lukas Wunner +Cc: Frank Pavlic +--- + drivers/mmc/host/bcm2835-mmc.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/mmc/host/bcm2835-mmc.c ++++ b/drivers/mmc/host/bcm2835-mmc.c +@@ -1503,6 +1503,8 @@ static int bcm2835_mmc_probe(struct plat + + return 0; + err: ++ if (host->dma_chan_rxtx) ++ dma_release_channel(host->dma_chan_rxtx); + mmc_free_host(mmc); + + return ret; +@@ -1548,6 +1550,9 @@ static int bcm2835_mmc_remove(struct pla + + tasklet_kill(&host->finish_tasklet); + ++ if (host->dma_chan_rxtx) ++ dma_release_channel(host->dma_chan_rxtx); ++ + mmc_free_host(host->mmc); + platform_set_drvdata(pdev, NULL); + diff --git a/target/linux/brcm2708/patches-4.19/950-0385-overlays-sdio-Added-4-bit-support-on-GPIOs-34-39.-29.patch b/target/linux/brcm2708/patches-4.19/950-0385-overlays-sdio-Added-4-bit-support-on-GPIOs-34-39.-29.patch deleted file mode 100644 index 4fe40ed0ae..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0385-overlays-sdio-Added-4-bit-support-on-GPIOs-34-39.-29.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 693450014feff59f24614f8032e7e1b798d8694c Mon Sep 17 00:00:00 2001 -From: Adrien RICCIARDI -Date: Fri, 22 Mar 2019 11:35:30 +0100 -Subject: [PATCH 385/703] overlays: sdio: Added 4-bit support on GPIOs 34-39. - (#2903) - ---- - arch/arm/boot/dts/overlays/README | 3 +++ - arch/arm/boot/dts/overlays/sdio-overlay.dts | 9 +++++++++ - 2 files changed, 12 insertions(+) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1785,6 +1785,9 @@ Params: sdio_overclock SDIO Clo - gpios_34_37 Select GPIOs 34-37 for 1-bit mode. Must be used - with bus_width=1. - -+ gpios_34_39 Select GPIOs 34-39 for 4-bit mode. Must be used -+ with bus_width=4 (the default). -+ - - Name: sdio-1bit - Info: This overlay is now deprecated. Use ---- a/arch/arm/boot/dts/overlays/sdio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts -@@ -64,6 +64,14 @@ - }; - }; - -+ fragment@5 { -+ target = <&sdio_ovl_pins>; -+ __dormant__ { -+ brcm,pins = <34 35 36 37 38 39>; -+ brcm,pull = <0 2 2 2 2 2>; -+ }; -+ }; -+ - fragment@6 { - target-path = "/aliases"; - __overlay__ { -@@ -77,5 +85,6 @@ - sdio_overclock = <&sdio_ovl>,"brcm,overclock-50:0"; - gpios_22_25 = <0>,"=3"; - gpios_34_37 = <0>,"=4"; -+ gpios_34_39 = <0>,"=5"; - }; - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0386-bcm2835-mmc-Fix-struct-mmc_host-leak-on-probe.patch b/target/linux/brcm2708/patches-4.19/950-0386-bcm2835-mmc-Fix-struct-mmc_host-leak-on-probe.patch new file mode 100644 index 0000000000..cf8f7ac161 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0386-bcm2835-mmc-Fix-struct-mmc_host-leak-on-probe.patch @@ -0,0 +1,29 @@ +From 1a0d67591fc1b7a33e7769caaba13f9a08ca4f25 Mon Sep 17 00:00:00 2001 +From: Lukas Wunner +Date: Sat, 19 Jan 2019 08:06:48 +0100 +Subject: [PATCH 386/725] bcm2835-mmc: Fix struct mmc_host leak on probe + +The BCM2835 MMC host driver requests the bus address of the host's +register map on probe. If that fails, the driver leaks the struct +mmc_host allocated earlier. + +Fix it. + +Signed-off-by: Lukas Wunner +Cc: Frank Pavlic +--- + drivers/mmc/host/bcm2835-mmc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/mmc/host/bcm2835-mmc.c ++++ b/drivers/mmc/host/bcm2835-mmc.c +@@ -1439,7 +1439,8 @@ static int bcm2835_mmc_probe(struct plat + addr = of_get_address(node, 0, NULL, NULL); + if (!addr) { + dev_err(dev, "could not get DMA-register address\n"); +- return -ENODEV; ++ ret = -ENODEV; ++ goto err; + } + host->bus_addr = be32_to_cpup(addr); + pr_debug(" - ioaddr %lx, iomem->start %lx, bus_addr %lx\n", diff --git a/target/linux/brcm2708/patches-4.19/950-0386-overlays-Fix-multiple-instantiation-of-sc16is7xx.patch b/target/linux/brcm2708/patches-4.19/950-0386-overlays-Fix-multiple-instantiation-of-sc16is7xx.patch deleted file mode 100644 index e2fe7d5903..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0386-overlays-Fix-multiple-instantiation-of-sc16is7xx.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 018329c19febff752bf09820eda6465748ae9c65 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 22 Mar 2019 16:44:47 +0000 -Subject: [PATCH 386/703] overlays: Fix multiple-instantiation of sc16is7xx* - -The registration of the fixed clocks uses the node name as the clock -name, causing a clash if two clock nodes have the same name, regardless -of the path to the node. Fix the issue by overwriting the clock node -names using the value of the "addr" parameter, providing a crude -disambiguation. (A bit of string pasting to form "sc16is752_clk_" -would have been nice, but that is outside the abilities of the overlay -parameter mechanism.) - -Also give the sc16is750-i2c overlay the xtal parameter for symmetry. - -See: https://www.raspberrypi.org/forums/viewtopic.php?f=107&t=235650 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/README | 1 + - arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts | 3 ++- - arch/arm/boot/dts/overlays/sc16is752-i2c-overlay.dts | 2 +- - 3 files changed, 4 insertions(+), 2 deletions(-) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1725,6 +1725,7 @@ Info: Overlay for the NXP SC16IS750 UA - Load: dtoverlay=sc16is750-i2c,= - Params: int_pin GPIO used for IRQ (default 24) - addr Address (default 0x48) -+ xtal On-board crystal frequency (default 14745600) - - - Name: sc16is752-i2c ---- a/arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts -@@ -31,7 +31,8 @@ - - __overrides__ { - int_pin = <&sc16is750>,"interrupts:0"; -- addr = <&sc16is750>,"reg:0"; -+ addr = <&sc16is750>,"reg:0",<&sc16is750_clk>,"name"; -+ xtal = <&sc16is750>,"clock-frequency:0"; - }; - - }; ---- a/arch/arm/boot/dts/overlays/sc16is752-i2c-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sc16is752-i2c-overlay.dts -@@ -34,7 +34,7 @@ - - __overrides__ { - int_pin = <&sc16is752>,"interrupts:0"; -- addr = <&sc16is752>,"reg:0"; -+ addr = <&sc16is752>,"reg:0",<&sc16is752_clk>,"name"; - xtal = <&sc16is752>,"clock-frequency:0"; - }; - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0387-bcm2835-mmc-Fix-duplicate-free_irq-on-remove.patch b/target/linux/brcm2708/patches-4.19/950-0387-bcm2835-mmc-Fix-duplicate-free_irq-on-remove.patch new file mode 100644 index 0000000000..eda21e1367 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0387-bcm2835-mmc-Fix-duplicate-free_irq-on-remove.patch @@ -0,0 +1,38 @@ +From 56b3d0e6446f081d0c3e8c52e651f8d45d488b45 Mon Sep 17 00:00:00 2001 +From: Lukas Wunner +Date: Sat, 19 Jan 2019 09:00:26 +0100 +Subject: [PATCH 387/725] bcm2835-mmc: Fix duplicate free_irq() on remove + +The BCM2835 MMC host driver requests its interrupt as a device-managed +resource, so the interrupt is automatically freed after the driver is +unbound. + +However on driver unbind, bcm2835_mmc_remove() frees the interrupt +explicitly to avoid invocation of the interrupt handler after driver +structures have been torn down. + +The interrupt is thus freed twice, leading to a WARN splat in +__free_irq(). Fix by not requesting the interrupt as a device-managed +resource. + +Signed-off-by: Lukas Wunner +Cc: Frank Pavlic +--- + drivers/mmc/host/bcm2835-mmc.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/mmc/host/bcm2835-mmc.c ++++ b/drivers/mmc/host/bcm2835-mmc.c +@@ -1389,9 +1389,9 @@ static int bcm2835_mmc_add_host(struct b + init_waitqueue_head(&host->buf_ready_int); + + bcm2835_mmc_init(host, 0); +- ret = devm_request_threaded_irq(dev, host->irq, bcm2835_mmc_irq, +- bcm2835_mmc_thread_irq, IRQF_SHARED, +- mmc_hostname(mmc), host); ++ ret = request_threaded_irq(host->irq, bcm2835_mmc_irq, ++ bcm2835_mmc_thread_irq, IRQF_SHARED, ++ mmc_hostname(mmc), host); + if (ret) { + dev_err(dev, "Failed to request IRQ %d: %d\n", host->irq, ret); + goto untasklet; diff --git a/target/linux/brcm2708/patches-4.19/950-0387-configs-Re-enable-CONFIG_NETFILTER_XT_MATCH_SOCKET.patch b/target/linux/brcm2708/patches-4.19/950-0387-configs-Re-enable-CONFIG_NETFILTER_XT_MATCH_SOCKET.patch deleted file mode 100644 index da1295c528..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0387-configs-Re-enable-CONFIG_NETFILTER_XT_MATCH_SOCKET.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 59f78628ccd725312dd1ff24d1b0952fa8203ee2 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Sun, 24 Mar 2019 20:54:25 +0000 -Subject: [PATCH 387/703] configs: Re-enable CONFIG_NETFILTER_XT_MATCH_SOCKET - -A Kconfig change in 4.10 caused the xt_socket module to no-longer be -included in Raspbian builds. Fix the defconfigs to re-enable it. - -See: https://github.com/raspberrypi/linux/issues/2905 - -Signed-off-by: Phil Elwell ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - arch/arm64/configs/bcmrpi3_defconfig | 1 + - 3 files changed, 3 insertions(+) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -186,6 +186,7 @@ CONFIG_NETFILTER_XT_MATCH_QUOTA=m - CONFIG_NETFILTER_XT_MATCH_RATEEST=m - CONFIG_NETFILTER_XT_MATCH_REALM=m - CONFIG_NETFILTER_XT_MATCH_RECENT=m -+CONFIG_NETFILTER_XT_MATCH_SOCKET=m - CONFIG_NETFILTER_XT_MATCH_STATE=m - CONFIG_NETFILTER_XT_MATCH_STATISTIC=m - CONFIG_NETFILTER_XT_MATCH_STRING=m ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -180,6 +180,7 @@ CONFIG_NETFILTER_XT_MATCH_QUOTA=m - CONFIG_NETFILTER_XT_MATCH_RATEEST=m - CONFIG_NETFILTER_XT_MATCH_REALM=m - CONFIG_NETFILTER_XT_MATCH_RECENT=m -+CONFIG_NETFILTER_XT_MATCH_SOCKET=m - CONFIG_NETFILTER_XT_MATCH_STATE=m - CONFIG_NETFILTER_XT_MATCH_STATISTIC=m - CONFIG_NETFILTER_XT_MATCH_STRING=m ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -181,6 +181,7 @@ CONFIG_NETFILTER_XT_MATCH_QUOTA=m - CONFIG_NETFILTER_XT_MATCH_RATEEST=m - CONFIG_NETFILTER_XT_MATCH_REALM=m - CONFIG_NETFILTER_XT_MATCH_RECENT=m -+CONFIG_NETFILTER_XT_MATCH_SOCKET=m - CONFIG_NETFILTER_XT_MATCH_STATE=m - CONFIG_NETFILTER_XT_MATCH_STATISTIC=m - CONFIG_NETFILTER_XT_MATCH_STRING=m diff --git a/target/linux/brcm2708/patches-4.19/950-0388-bcm2835-mmc-Fix-DMA-channel-leak.patch b/target/linux/brcm2708/patches-4.19/950-0388-bcm2835-mmc-Fix-DMA-channel-leak.patch deleted file mode 100644 index b61b81418a..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0388-bcm2835-mmc-Fix-DMA-channel-leak.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 94a6414f6aaef2575eeb36149d65c79c13b85922 Mon Sep 17 00:00:00 2001 -From: Lukas Wunner -Date: Wed, 16 Jan 2019 12:22:32 +0100 -Subject: [PATCH 388/703] bcm2835-mmc: Fix DMA channel leak - -The BCM2835 MMC host driver requests a DMA channel on probe but neglects -to release the channel in the probe error path and on driver unbind. - -I'm seeing this happen on every boot of the Compute Module 3: On first -driver probe, DMA channel 2 is allocated and then leaked with a "could -not get clk, deferring probe" message. On second driver probe, channel 4 -is allocated. - -Fix it. - -Signed-off-by: Lukas Wunner -Cc: Frank Pavlic ---- - drivers/mmc/host/bcm2835-mmc.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -1503,6 +1503,8 @@ static int bcm2835_mmc_probe(struct plat - - return 0; - err: -+ if (host->dma_chan_rxtx) -+ dma_release_channel(host->dma_chan_rxtx); - mmc_free_host(mmc); - - return ret; -@@ -1548,6 +1550,9 @@ static int bcm2835_mmc_remove(struct pla - - tasklet_kill(&host->finish_tasklet); - -+ if (host->dma_chan_rxtx) -+ dma_release_channel(host->dma_chan_rxtx); -+ - mmc_free_host(host->mmc); - platform_set_drvdata(pdev, NULL); - diff --git a/target/linux/brcm2708/patches-4.19/950-0388-bcm2835-mmc-Handle-mmc_add_host-errors.patch b/target/linux/brcm2708/patches-4.19/950-0388-bcm2835-mmc-Handle-mmc_add_host-errors.patch new file mode 100644 index 0000000000..64547b49e0 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0388-bcm2835-mmc-Handle-mmc_add_host-errors.patch @@ -0,0 +1,35 @@ +From b4a62a0eae7852a4dde5f055bb89833ea80d554a Mon Sep 17 00:00:00 2001 +From: Lukas Wunner +Date: Tue, 22 Jan 2019 12:29:45 +0100 +Subject: [PATCH 388/725] bcm2835-mmc: Handle mmc_add_host() errors + +The BCM2835 MMC host driver calls mmc_add_host() but doesn't check its +return value. Errors occurring in that function are therefore not +handled. Fix it. + +Signed-off-by: Lukas Wunner +Cc: Frank Pavlic +--- + drivers/mmc/host/bcm2835-mmc.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/mmc/host/bcm2835-mmc.c ++++ b/drivers/mmc/host/bcm2835-mmc.c +@@ -1398,10 +1398,16 @@ static int bcm2835_mmc_add_host(struct b + } + + mmiowb(); +- mmc_add_host(mmc); ++ ret = mmc_add_host(mmc); ++ if (ret) { ++ dev_err(dev, "could not add MMC host\n"); ++ goto free_irq; ++ } + + return 0; + ++free_irq: ++ free_irq(host->irq, host); + untasklet: + tasklet_kill(&host->finish_tasklet); + diff --git a/target/linux/brcm2708/patches-4.19/950-0389-bcm2835-mmc-Deduplicate-reset-of-driver-data-on-remo.patch b/target/linux/brcm2708/patches-4.19/950-0389-bcm2835-mmc-Deduplicate-reset-of-driver-data-on-remo.patch new file mode 100644 index 0000000000..52edada413 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0389-bcm2835-mmc-Deduplicate-reset-of-driver-data-on-remo.patch @@ -0,0 +1,26 @@ +From 3f0851774265e0097e015672ee860983608c9b14 Mon Sep 17 00:00:00 2001 +From: Lukas Wunner +Date: Sat, 19 Jan 2019 08:42:40 +0100 +Subject: [PATCH 389/725] bcm2835-mmc: Deduplicate reset of driver data on + remove + +The BCM2835 MMC host driver sets the device's driver data pointer to +NULL on ->remove() even though the driver core subsequently does the +same in __device_release_driver(). Drop the duplicate assignment. + +Signed-off-by: Lukas Wunner +Cc: Frank Pavlic +--- + drivers/mmc/host/bcm2835-mmc.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/mmc/host/bcm2835-mmc.c ++++ b/drivers/mmc/host/bcm2835-mmc.c +@@ -1561,7 +1561,6 @@ static int bcm2835_mmc_remove(struct pla + dma_release_channel(host->dma_chan_rxtx); + + mmc_free_host(host->mmc); +- platform_set_drvdata(pdev, NULL); + + return 0; + } diff --git a/target/linux/brcm2708/patches-4.19/950-0389-bcm2835-mmc-Fix-struct-mmc_host-leak-on-probe.patch b/target/linux/brcm2708/patches-4.19/950-0389-bcm2835-mmc-Fix-struct-mmc_host-leak-on-probe.patch deleted file mode 100644 index 6265a6ba7b..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0389-bcm2835-mmc-Fix-struct-mmc_host-leak-on-probe.patch +++ /dev/null @@ -1,29 +0,0 @@ -From eaea13d958263b1fae8a96ffe184f91b0ca526cd Mon Sep 17 00:00:00 2001 -From: Lukas Wunner -Date: Sat, 19 Jan 2019 08:06:48 +0100 -Subject: [PATCH 389/703] bcm2835-mmc: Fix struct mmc_host leak on probe - -The BCM2835 MMC host driver requests the bus address of the host's -register map on probe. If that fails, the driver leaks the struct -mmc_host allocated earlier. - -Fix it. - -Signed-off-by: Lukas Wunner -Cc: Frank Pavlic ---- - drivers/mmc/host/bcm2835-mmc.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -1439,7 +1439,8 @@ static int bcm2835_mmc_probe(struct plat - addr = of_get_address(node, 0, NULL, NULL); - if (!addr) { - dev_err(dev, "could not get DMA-register address\n"); -- return -ENODEV; -+ ret = -ENODEV; -+ goto err; - } - host->bus_addr = be32_to_cpup(addr); - pr_debug(" - ioaddr %lx, iomem->start %lx, bus_addr %lx\n", diff --git a/target/linux/brcm2708/patches-4.19/950-0390-bcm2835-mmc-Fix-duplicate-free_irq-on-remove.patch b/target/linux/brcm2708/patches-4.19/950-0390-bcm2835-mmc-Fix-duplicate-free_irq-on-remove.patch deleted file mode 100644 index 24e3d178aa..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0390-bcm2835-mmc-Fix-duplicate-free_irq-on-remove.patch +++ /dev/null @@ -1,38 +0,0 @@ -From d2ba7664d279bf06ad8ffc281cbefe29ddc180e7 Mon Sep 17 00:00:00 2001 -From: Lukas Wunner -Date: Sat, 19 Jan 2019 09:00:26 +0100 -Subject: [PATCH 390/703] bcm2835-mmc: Fix duplicate free_irq() on remove - -The BCM2835 MMC host driver requests its interrupt as a device-managed -resource, so the interrupt is automatically freed after the driver is -unbound. - -However on driver unbind, bcm2835_mmc_remove() frees the interrupt -explicitly to avoid invocation of the interrupt handler after driver -structures have been torn down. - -The interrupt is thus freed twice, leading to a WARN splat in -__free_irq(). Fix by not requesting the interrupt as a device-managed -resource. - -Signed-off-by: Lukas Wunner -Cc: Frank Pavlic ---- - drivers/mmc/host/bcm2835-mmc.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -1389,9 +1389,9 @@ static int bcm2835_mmc_add_host(struct b - init_waitqueue_head(&host->buf_ready_int); - - bcm2835_mmc_init(host, 0); -- ret = devm_request_threaded_irq(dev, host->irq, bcm2835_mmc_irq, -- bcm2835_mmc_thread_irq, IRQF_SHARED, -- mmc_hostname(mmc), host); -+ ret = request_threaded_irq(host->irq, bcm2835_mmc_irq, -+ bcm2835_mmc_thread_irq, IRQF_SHARED, -+ mmc_hostname(mmc), host); - if (ret) { - dev_err(dev, "Failed to request IRQ %d: %d\n", host->irq, ret); - goto untasklet; diff --git a/target/linux/brcm2708/patches-4.19/950-0390-configs-Add-CONFIG_BATTERY_MAX17040.patch b/target/linux/brcm2708/patches-4.19/950-0390-configs-Add-CONFIG_BATTERY_MAX17040.patch new file mode 100644 index 0000000000..d1157610d1 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0390-configs-Add-CONFIG_BATTERY_MAX17040.patch @@ -0,0 +1,44 @@ +From a6d3c7bab1486b7d4b0b8b410c5267ed63894861 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 25 Mar 2019 17:54:05 +0000 +Subject: [PATCH 390/725] configs: Add CONFIG_BATTERY_MAX17040 + +See: https://github.com/raspberrypi/linux/issues/2906 + +Signed-off-by: Phil Elwell +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + arch/arm64/configs/bcmrpi3_defconfig | 1 + + 3 files changed, 3 insertions(+) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -659,6 +659,7 @@ CONFIG_W1_SLAVE_DS28E04=m + CONFIG_POWER_RESET=y + CONFIG_POWER_RESET_GPIO=y + CONFIG_BATTERY_DS2760=m ++CONFIG_BATTERY_MAX17040=m + CONFIG_BATTERY_GAUGE_LTC2941=m + CONFIG_HWMON=m + CONFIG_SENSORS_DS1621=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -652,6 +652,7 @@ CONFIG_W1_SLAVE_DS28E04=m + CONFIG_POWER_RESET=y + CONFIG_POWER_RESET_GPIO=y + CONFIG_BATTERY_DS2760=m ++CONFIG_BATTERY_MAX17040=m + CONFIG_BATTERY_GAUGE_LTC2941=m + CONFIG_HWMON=m + CONFIG_SENSORS_DS1621=m +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -629,6 +629,7 @@ CONFIG_W1_SLAVE_DS2781=m + CONFIG_W1_SLAVE_DS28E04=m + CONFIG_POWER_RESET_GPIO=y + CONFIG_BATTERY_DS2760=m ++CONFIG_BATTERY_MAX17040=m + CONFIG_HWMON=m + CONFIG_SENSORS_LM75=m + CONFIG_SENSORS_SHT21=m diff --git a/target/linux/brcm2708/patches-4.19/950-0391-bcm2835-mmc-Handle-mmc_add_host-errors.patch b/target/linux/brcm2708/patches-4.19/950-0391-bcm2835-mmc-Handle-mmc_add_host-errors.patch deleted file mode 100644 index 10db02ede1..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0391-bcm2835-mmc-Handle-mmc_add_host-errors.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 3c29f09811abafef65e431bc70a66ef78625c08a Mon Sep 17 00:00:00 2001 -From: Lukas Wunner -Date: Tue, 22 Jan 2019 12:29:45 +0100 -Subject: [PATCH 391/703] bcm2835-mmc: Handle mmc_add_host() errors - -The BCM2835 MMC host driver calls mmc_add_host() but doesn't check its -return value. Errors occurring in that function are therefore not -handled. Fix it. - -Signed-off-by: Lukas Wunner -Cc: Frank Pavlic ---- - drivers/mmc/host/bcm2835-mmc.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -1398,10 +1398,16 @@ static int bcm2835_mmc_add_host(struct b - } - - mmiowb(); -- mmc_add_host(mmc); -+ ret = mmc_add_host(mmc); -+ if (ret) { -+ dev_err(dev, "could not add MMC host\n"); -+ goto free_irq; -+ } - - return 0; - -+free_irq: -+ free_irq(host->irq, host); - untasklet: - tasklet_kill(&host->finish_tasklet); - diff --git a/target/linux/brcm2708/patches-4.19/950-0391-overlays-Add-max17040-support-to-i2c-sensor.patch b/target/linux/brcm2708/patches-4.19/950-0391-overlays-Add-max17040-support-to-i2c-sensor.patch new file mode 100644 index 0000000000..d08fc7f85c --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0391-overlays-Add-max17040-support-to-i2c-sensor.patch @@ -0,0 +1,56 @@ +From a8034b01d807e4c393356d7b46183dd5d2b40df3 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 25 Mar 2019 18:03:48 +0000 +Subject: [PATCH 391/725] overlays: Add max17040 support to i2c-sensor + +See: https://github.com/raspberrypi/linux/issues/2906 + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/README | 3 +++ + .../arm/boot/dts/overlays/i2c-sensor-overlay.dts | 16 ++++++++++++++++ + 2 files changed, 19 insertions(+) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1030,6 +1030,9 @@ Params: addr Set the + + lm75addr Deprecated - use addr parameter instead + ++ max17040 Select the Maxim Integrated MAX17040 battery ++ monitor ++ + sht3x Select the Sensiron SHT3x temperature and + humidity sensor. Valid addresses 0x44-0x45, + default 0x44 +--- a/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts +@@ -201,6 +201,21 @@ + }; + }; + ++ fragment@13 { ++ target = <&i2c_arm>; ++ __dormant__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ max17040: max17040@36 { ++ compatible = "maxim,max17040"; ++ reg = <0x36>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ + __overrides__ { + addr = <&bme280>,"reg:0", <&bmp280>,"reg:0", <&tmp102>,"reg:0", + <&lm75>,"reg:0", <&hdc100x>,"reg:0", <&sht3x>,"reg:0", +@@ -219,5 +234,6 @@ + veml6070 = <0>,"+10"; + sht3x = <0>,"+11"; + ds1621 = <0>,"+12"; ++ max17040 = <0>,"+13"; + }; + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0392-bcm2835-mmc-Deduplicate-reset-of-driver-data-on-remo.patch b/target/linux/brcm2708/patches-4.19/950-0392-bcm2835-mmc-Deduplicate-reset-of-driver-data-on-remo.patch deleted file mode 100644 index 2e897aedc0..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0392-bcm2835-mmc-Deduplicate-reset-of-driver-data-on-remo.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 706fb772745fae3b0ea6a36830cc92eaf1c22606 Mon Sep 17 00:00:00 2001 -From: Lukas Wunner -Date: Sat, 19 Jan 2019 08:42:40 +0100 -Subject: [PATCH 392/703] bcm2835-mmc: Deduplicate reset of driver data on - remove - -The BCM2835 MMC host driver sets the device's driver data pointer to -NULL on ->remove() even though the driver core subsequently does the -same in __device_release_driver(). Drop the duplicate assignment. - -Signed-off-by: Lukas Wunner -Cc: Frank Pavlic ---- - drivers/mmc/host/bcm2835-mmc.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -1561,7 +1561,6 @@ static int bcm2835_mmc_remove(struct pla - dma_release_channel(host->dma_chan_rxtx); - - mmc_free_host(host->mmc); -- platform_set_drvdata(pdev, NULL); - - return 0; - } diff --git a/target/linux/brcm2708/patches-4.19/950-0392-defconfigs-disable-memory-and-IO-cgroups-2908.patch b/target/linux/brcm2708/patches-4.19/950-0392-defconfigs-disable-memory-and-IO-cgroups-2908.patch new file mode 100644 index 0000000000..1cbac0ea44 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0392-defconfigs-disable-memory-and-IO-cgroups-2908.patch @@ -0,0 +1,81 @@ +From 38bdf55c84e6f388db3dfb96d3c6617abcc10067 Mon Sep 17 00:00:00 2001 +From: P33M +Date: Tue, 26 Mar 2019 09:48:25 +0000 +Subject: [PATCH 392/725] defconfigs: disable memory and IO cgroups (#2908) + +Due to an upstream bug, memory is leaked in the inode cache when cgroups +are enabled. Disable as this is causing crashes. + +See: https://github.com/raspberrypi/linux/issues/2829 +--- + arch/arm/configs/bcm2709_defconfig | 4 ---- + arch/arm/configs/bcmrpi_defconfig | 4 ---- + arch/arm64/configs/bcmrpi3_defconfig | 4 ---- + 3 files changed, 12 deletions(-) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -14,8 +14,6 @@ CONFIG_TASK_XACCT=y + CONFIG_TASK_IO_ACCOUNTING=y + CONFIG_IKCONFIG=m + CONFIG_IKCONFIG_PROC=y +-CONFIG_MEMCG=y +-CONFIG_BLK_CGROUP=y + CONFIG_CGROUP_FREEZER=y + CONFIG_CPUSETS=y + CONFIG_CGROUP_DEVICE=y +@@ -64,10 +62,8 @@ CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + CONFIG_MODVERSIONS=y + CONFIG_MODULE_SRCVERSION_ALL=y +-CONFIG_BLK_DEV_THROTTLING=y + CONFIG_PARTITION_ADVANCED=y + CONFIG_MAC_PARTITION=y +-CONFIG_CFQ_GROUP_IOSCHED=y + CONFIG_BINFMT_MISC=m + CONFIG_CLEANCACHE=y + CONFIG_FRONTSWAP=y +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -13,8 +13,6 @@ CONFIG_TASK_XACCT=y + CONFIG_TASK_IO_ACCOUNTING=y + CONFIG_IKCONFIG=m + CONFIG_IKCONFIG_PROC=y +-CONFIG_MEMCG=y +-CONFIG_BLK_CGROUP=y + CONFIG_CGROUP_FREEZER=y + CONFIG_CGROUP_DEVICE=y + CONFIG_CGROUP_CPUACCT=y +@@ -58,10 +56,8 @@ CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + CONFIG_MODVERSIONS=y + CONFIG_MODULE_SRCVERSION_ALL=y +-CONFIG_BLK_DEV_THROTTLING=y + CONFIG_PARTITION_ADVANCED=y + CONFIG_MAC_PARTITION=y +-CONFIG_CFQ_GROUP_IOSCHED=y + CONFIG_BINFMT_MISC=m + CONFIG_CLEANCACHE=y + CONFIG_FRONTSWAP=y +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -13,8 +13,6 @@ CONFIG_TASK_XACCT=y + CONFIG_TASK_IO_ACCOUNTING=y + CONFIG_IKCONFIG=m + CONFIG_IKCONFIG_PROC=y +-CONFIG_MEMCG=y +-CONFIG_BLK_CGROUP=y + CONFIG_CGROUP_FREEZER=y + CONFIG_CPUSETS=y + CONFIG_CGROUP_DEVICE=y +@@ -62,10 +60,8 @@ CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + CONFIG_MODVERSIONS=y + CONFIG_MODULE_SRCVERSION_ALL=y +-CONFIG_BLK_DEV_THROTTLING=y + CONFIG_PARTITION_ADVANCED=y + CONFIG_MAC_PARTITION=y +-CONFIG_CFQ_GROUP_IOSCHED=y + CONFIG_BINFMT_MISC=y + CONFIG_CLEANCACHE=y + CONFIG_FRONTSWAP=y diff --git a/target/linux/brcm2708/patches-4.19/950-0393-configs-Add-CONFIG_BATTERY_MAX17040.patch b/target/linux/brcm2708/patches-4.19/950-0393-configs-Add-CONFIG_BATTERY_MAX17040.patch deleted file mode 100644 index 5087075ab9..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0393-configs-Add-CONFIG_BATTERY_MAX17040.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 034896f9b6faf8107788575990c2cec2a6ef964e Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 25 Mar 2019 17:54:05 +0000 -Subject: [PATCH 393/703] configs: Add CONFIG_BATTERY_MAX17040 - -See: https://github.com/raspberrypi/linux/issues/2906 - -Signed-off-by: Phil Elwell ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - arch/arm64/configs/bcmrpi3_defconfig | 1 + - 3 files changed, 3 insertions(+) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -659,6 +659,7 @@ CONFIG_W1_SLAVE_DS28E04=m - CONFIG_POWER_RESET=y - CONFIG_POWER_RESET_GPIO=y - CONFIG_BATTERY_DS2760=m -+CONFIG_BATTERY_MAX17040=m - CONFIG_BATTERY_GAUGE_LTC2941=m - CONFIG_HWMON=m - CONFIG_SENSORS_DS1621=m ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -652,6 +652,7 @@ CONFIG_W1_SLAVE_DS28E04=m - CONFIG_POWER_RESET=y - CONFIG_POWER_RESET_GPIO=y - CONFIG_BATTERY_DS2760=m -+CONFIG_BATTERY_MAX17040=m - CONFIG_BATTERY_GAUGE_LTC2941=m - CONFIG_HWMON=m - CONFIG_SENSORS_DS1621=m ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -629,6 +629,7 @@ CONFIG_W1_SLAVE_DS2781=m - CONFIG_W1_SLAVE_DS28E04=m - CONFIG_POWER_RESET_GPIO=y - CONFIG_BATTERY_DS2760=m -+CONFIG_BATTERY_MAX17040=m - CONFIG_HWMON=m - CONFIG_SENSORS_LM75=m - CONFIG_SENSORS_SHT21=m diff --git a/target/linux/brcm2708/patches-4.19/950-0393-media-bcm2835-unicam-Add-support-for-enum-framesizes.patch b/target/linux/brcm2708/patches-4.19/950-0393-media-bcm2835-unicam-Add-support-for-enum-framesizes.patch new file mode 100644 index 0000000000..6f4cbf093a --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0393-media-bcm2835-unicam-Add-support-for-enum-framesizes.patch @@ -0,0 +1,133 @@ +From 4ee5be44a136685a674ef2e3560e4062a26a2bfb Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 5 Mar 2019 15:43:27 +0000 +Subject: [PATCH 393/725] media: bcm2835-unicam: Add support for enum + framesizes and frameintervals + +vidioc_enum_framesizes and vidioc_enum_frameintervals weren't implemented, +therefore clients couldn't enumerate the supported resolutions. + +Implement them by forwarding on to the sensor driver. + +Signed-off-by: Dave Stevenson +--- + .../media/platform/bcm2835/bcm2835-unicam.c | 94 +++++++++++++++++++ + 1 file changed, 94 insertions(+) + +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -1406,6 +1406,84 @@ static int unicam_g_edid(struct file *fi + return v4l2_subdev_call(dev->sensor, pad, get_edid, edid); + } + ++static int unicam_enum_framesizes(struct file *file, void *priv, ++ struct v4l2_frmsizeenum *fsize) ++{ ++ struct unicam_device *dev = video_drvdata(file); ++ const struct unicam_fmt *fmt; ++ struct v4l2_subdev_frame_size_enum fse; ++ int ret; ++ ++ /* check for valid format */ ++ fmt = find_format_by_pix(dev, fsize->pixel_format); ++ if (!fmt) { ++ unicam_dbg(3, dev, "Invalid pixel code: %x\n", ++ fsize->pixel_format); ++ return -EINVAL; ++ } ++ ++ fse.index = fsize->index; ++ fse.pad = 0; ++ fse.code = fmt->code; ++ ++ ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_size, NULL, &fse); ++ if (ret) ++ return ret; ++ ++ unicam_dbg(1, dev, "%s: index: %d code: %x W:[%d,%d] H:[%d,%d]\n", ++ __func__, fse.index, fse.code, fse.min_width, fse.max_width, ++ fse.min_height, fse.max_height); ++ ++ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; ++ fsize->discrete.width = fse.max_width; ++ fsize->discrete.height = fse.max_height; ++ ++ return 0; ++} ++ ++static int unicam_enum_frameintervals(struct file *file, void *priv, ++ struct v4l2_frmivalenum *fival) ++{ ++ struct unicam_device *dev = video_drvdata(file); ++ const struct unicam_fmt *fmt; ++ struct v4l2_subdev_frame_interval_enum fie = { ++ .index = fival->index, ++ .width = fival->width, ++ .height = fival->height, ++ .which = V4L2_SUBDEV_FORMAT_ACTIVE, ++ }; ++ int ret; ++ ++ fmt = find_format_by_pix(dev, fival->pixel_format); ++ if (!fmt) ++ return -EINVAL; ++ ++ fie.code = fmt->code; ++ ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_interval, ++ NULL, &fie); ++ if (ret) ++ return ret; ++ ++ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; ++ fival->discrete = fie.interval; ++ ++ return 0; ++} ++ ++static int unicam_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) ++{ ++ struct unicam_device *dev = video_drvdata(file); ++ ++ return v4l2_g_parm_cap(video_devdata(file), dev->sensor, a); ++} ++ ++static int unicam_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) ++{ ++ struct unicam_device *dev = video_drvdata(file); ++ ++ return v4l2_s_parm_cap(video_devdata(file), dev->sensor, a); ++} ++ + static int unicam_g_dv_timings(struct file *file, void *priv, + struct v4l2_dv_timings *timings) + { +@@ -1613,6 +1691,12 @@ static const struct v4l2_ioctl_ops unica + .vidioc_g_edid = unicam_g_edid, + .vidioc_s_edid = unicam_s_edid, + ++ .vidioc_enum_framesizes = unicam_enum_framesizes, ++ .vidioc_enum_frameintervals = unicam_enum_frameintervals, ++ ++ .vidioc_g_parm = unicam_g_parm, ++ .vidioc_s_parm = unicam_s_parm, ++ + .vidioc_s_dv_timings = unicam_s_dv_timings, + .vidioc_g_dv_timings = unicam_g_dv_timings, + .vidioc_query_dv_timings = unicam_query_dv_timings, +@@ -1850,6 +1934,16 @@ static int unicam_probe_complete(struct + v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_ENUM_DV_TIMINGS); + v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_QUERY_DV_TIMINGS); + } ++ if (!v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_interval)) ++ v4l2_disable_ioctl(&unicam->video_dev, ++ VIDIOC_ENUM_FRAMEINTERVALS); ++ if (!v4l2_subdev_has_op(unicam->sensor, video, g_frame_interval)) ++ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_G_PARM); ++ if (!v4l2_subdev_has_op(unicam->sensor, video, s_frame_interval)) ++ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_S_PARM); ++ ++ if (!v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_size)) ++ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_ENUM_FRAMESIZES); + + ret = v4l2_device_register_subdev_nodes(&unicam->v4l2_dev); + if (ret) { diff --git a/target/linux/brcm2708/patches-4.19/950-0394-overlays-Add-max17040-support-to-i2c-sensor.patch b/target/linux/brcm2708/patches-4.19/950-0394-overlays-Add-max17040-support-to-i2c-sensor.patch deleted file mode 100644 index 1372d7d7a9..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0394-overlays-Add-max17040-support-to-i2c-sensor.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 1ec52e16794513c5802ad219d317ac1f825b6346 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 25 Mar 2019 18:03:48 +0000 -Subject: [PATCH 394/703] overlays: Add max17040 support to i2c-sensor - -See: https://github.com/raspberrypi/linux/issues/2906 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/README | 3 +++ - .../arm/boot/dts/overlays/i2c-sensor-overlay.dts | 16 ++++++++++++++++ - 2 files changed, 19 insertions(+) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1030,6 +1030,9 @@ Params: addr Set the - - lm75addr Deprecated - use addr parameter instead - -+ max17040 Select the Maxim Integrated MAX17040 battery -+ monitor -+ - sht3x Select the Sensiron SHT3x temperature and - humidity sensor. Valid addresses 0x44-0x45, - default 0x44 ---- a/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts -@@ -201,6 +201,21 @@ - }; - }; - -+ fragment@13 { -+ target = <&i2c_arm>; -+ __dormant__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ max17040: max17040@36 { -+ compatible = "maxim,max17040"; -+ reg = <0x36>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ - __overrides__ { - addr = <&bme280>,"reg:0", <&bmp280>,"reg:0", <&tmp102>,"reg:0", - <&lm75>,"reg:0", <&hdc100x>,"reg:0", <&sht3x>,"reg:0", -@@ -219,5 +234,6 @@ - veml6070 = <0>,"+10"; - sht3x = <0>,"+11"; - ds1621 = <0>,"+12"; -+ max17040 = <0>,"+13"; - }; - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0394-staging-bcm2835-codec-Refactor-default-resolution-co.patch b/target/linux/brcm2708/patches-4.19/950-0394-staging-bcm2835-codec-Refactor-default-resolution-co.patch new file mode 100644 index 0000000000..d2035fe62f --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0394-staging-bcm2835-codec-Refactor-default-resolution-co.patch @@ -0,0 +1,154 @@ +From 3307d285c4e10366fbd310203c19260d5e320b97 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 20 Mar 2019 10:06:51 +0000 +Subject: [PATCH 394/725] staging: bcm2835-codec: Refactor default resolution + code + +The default resolution code was different for each role +as compressed formats need to pass bytesperline as 0 and +set up customised buffer sizes. +This is common setup, therefore amend get_sizeimage and +get_bytesperline to do the correct thing whether compressed +or uncompressed. + +Signed-off-by: Dave Stevenson +--- + .../bcm2835-codec/bcm2835-v4l2-codec.c | 103 +++++++----------- + 1 file changed, 40 insertions(+), 63 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -578,10 +578,17 @@ static void job_abort(void *priv) + ctx->aborting = 1; + } + +-static inline unsigned int get_sizeimage(int bpl, int height, ++static inline unsigned int get_sizeimage(int bpl, int width, int height, + struct bcm2835_codec_fmt *fmt) + { +- return (bpl * height * fmt->size_multiplier_x2) >> 1; ++ if (fmt->flags & V4L2_FMT_FLAG_COMPRESSED) { ++ if (width * height > 1280 * 720) ++ return DEF_COMP_BUF_SIZE_GREATER_720P; ++ else ++ return DEF_COMP_BUF_SIZE_720P_OR_LESS; ++ } else { ++ return (bpl * height * fmt->size_multiplier_x2) >> 1; ++ } + } + + static inline unsigned int get_bytesperline(int width, +@@ -1032,22 +1039,13 @@ static int vidioc_try_fmt(struct v4l2_fo + * some of the pixels are active. + */ + f->fmt.pix.height = ALIGN(f->fmt.pix.height, 16); +- +- f->fmt.pix.bytesperline = get_bytesperline(f->fmt.pix.width, +- fmt); +- f->fmt.pix.sizeimage = get_sizeimage(f->fmt.pix.bytesperline, +- f->fmt.pix.height, +- fmt); +- } else { +- u32 min_size = f->fmt.pix.width > 1280 || +- f->fmt.pix.height > 720 ? +- DEF_COMP_BUF_SIZE_GREATER_720P : +- DEF_COMP_BUF_SIZE_720P_OR_LESS; +- +- f->fmt.pix.bytesperline = 0; +- if (f->fmt.pix.sizeimage < min_size) +- f->fmt.pix.sizeimage = min_size; + } ++ f->fmt.pix.bytesperline = get_bytesperline(f->fmt.pix.width, ++ fmt); ++ f->fmt.pix.sizeimage = get_sizeimage(f->fmt.pix.bytesperline, ++ f->fmt.pix.width, ++ f->fmt.pix.height, ++ fmt); + + f->fmt.pix.field = V4L2_FIELD_NONE; + +@@ -1159,6 +1157,7 @@ static int vidioc_s_fmt(struct bcm2835_c + q_data_dst->bytesperline = + get_bytesperline(f->fmt.pix.width, q_data_dst->fmt); + q_data_dst->sizeimage = get_sizeimage(q_data_dst->bytesperline, ++ q_data_dst->crop_width, + q_data_dst->height, + q_data_dst->fmt); + update_capture_port = true; +@@ -2218,52 +2217,30 @@ static int bcm2835_codec_open(struct fil + + ctx->q_data[V4L2_M2M_SRC].fmt = get_default_format(dev, false); + ctx->q_data[V4L2_M2M_DST].fmt = get_default_format(dev, true); +- switch (dev->role) { +- case DECODE: +- /* +- * Input width and height are irrelevant as they will be defined +- * by the bitstream not the format. Required by V4L2 though. +- */ +- ctx->q_data[V4L2_M2M_SRC].crop_width = DEFAULT_WIDTH; +- ctx->q_data[V4L2_M2M_SRC].crop_height = DEFAULT_HEIGHT; +- ctx->q_data[V4L2_M2M_SRC].height = DEFAULT_HEIGHT; +- ctx->q_data[V4L2_M2M_SRC].bytesperline = 0; +- ctx->q_data[V4L2_M2M_SRC].sizeimage = +- DEF_COMP_BUF_SIZE_720P_OR_LESS; +- +- ctx->q_data[V4L2_M2M_DST].crop_width = DEFAULT_WIDTH; +- ctx->q_data[V4L2_M2M_DST].crop_height = DEFAULT_HEIGHT; +- ctx->q_data[V4L2_M2M_DST].height = DEFAULT_HEIGHT; +- ctx->q_data[V4L2_M2M_DST].bytesperline = +- get_bytesperline(DEFAULT_WIDTH, +- ctx->q_data[V4L2_M2M_DST].fmt); +- ctx->q_data[V4L2_M2M_DST].sizeimage = +- get_sizeimage(ctx->q_data[V4L2_M2M_DST].bytesperline, +- ctx->q_data[V4L2_M2M_DST].height, +- ctx->q_data[V4L2_M2M_DST].fmt); +- break; +- case ENCODE: +- ctx->q_data[V4L2_M2M_SRC].crop_width = DEFAULT_WIDTH; +- ctx->q_data[V4L2_M2M_SRC].crop_height = DEFAULT_HEIGHT; +- ctx->q_data[V4L2_M2M_SRC].height = DEFAULT_HEIGHT; +- ctx->q_data[V4L2_M2M_SRC].bytesperline = +- get_bytesperline(DEFAULT_WIDTH, +- ctx->q_data[V4L2_M2M_SRC].fmt); +- ctx->q_data[V4L2_M2M_SRC].sizeimage = +- get_sizeimage(ctx->q_data[V4L2_M2M_SRC].bytesperline, +- ctx->q_data[V4L2_M2M_SRC].height, +- ctx->q_data[V4L2_M2M_SRC].fmt); +- +- ctx->q_data[V4L2_M2M_DST].crop_width = DEFAULT_WIDTH; +- ctx->q_data[V4L2_M2M_DST].crop_height = DEFAULT_HEIGHT; +- ctx->q_data[V4L2_M2M_DST].bytesperline = 0; +- ctx->q_data[V4L2_M2M_DST].height = DEFAULT_HEIGHT; +- ctx->q_data[V4L2_M2M_DST].sizeimage = +- DEF_COMP_BUF_SIZE_720P_OR_LESS; +- break; +- case ISP: +- break; +- } ++ ++ ctx->q_data[V4L2_M2M_SRC].crop_width = DEFAULT_WIDTH; ++ ctx->q_data[V4L2_M2M_SRC].crop_height = DEFAULT_HEIGHT; ++ ctx->q_data[V4L2_M2M_SRC].height = DEFAULT_HEIGHT; ++ ctx->q_data[V4L2_M2M_SRC].bytesperline = ++ get_bytesperline(DEFAULT_WIDTH, ++ ctx->q_data[V4L2_M2M_SRC].fmt); ++ ctx->q_data[V4L2_M2M_SRC].sizeimage = ++ get_sizeimage(ctx->q_data[V4L2_M2M_SRC].bytesperline, ++ ctx->q_data[V4L2_M2M_SRC].crop_width, ++ ctx->q_data[V4L2_M2M_SRC].height, ++ ctx->q_data[V4L2_M2M_SRC].fmt); ++ ++ ctx->q_data[V4L2_M2M_DST].crop_width = DEFAULT_WIDTH; ++ ctx->q_data[V4L2_M2M_DST].crop_height = DEFAULT_HEIGHT; ++ ctx->q_data[V4L2_M2M_DST].height = DEFAULT_HEIGHT; ++ ctx->q_data[V4L2_M2M_DST].bytesperline = ++ get_bytesperline(DEFAULT_WIDTH, ++ ctx->q_data[V4L2_M2M_DST].fmt); ++ ctx->q_data[V4L2_M2M_DST].sizeimage = ++ get_sizeimage(ctx->q_data[V4L2_M2M_DST].bytesperline, ++ ctx->q_data[V4L2_M2M_DST].crop_width, ++ ctx->q_data[V4L2_M2M_DST].height, ++ ctx->q_data[V4L2_M2M_DST].fmt); + + ctx->colorspace = V4L2_COLORSPACE_REC709; + ctx->bitrate = 10 * 1000 * 1000; diff --git a/target/linux/brcm2708/patches-4.19/950-0395-defconfigs-disable-memory-and-IO-cgroups-2908.patch b/target/linux/brcm2708/patches-4.19/950-0395-defconfigs-disable-memory-and-IO-cgroups-2908.patch deleted file mode 100644 index 1b06ed3744..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0395-defconfigs-disable-memory-and-IO-cgroups-2908.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 77816ef138e56144d51a5948d5a9646a4e1f2aa8 Mon Sep 17 00:00:00 2001 -From: P33M -Date: Tue, 26 Mar 2019 09:48:25 +0000 -Subject: [PATCH 395/703] defconfigs: disable memory and IO cgroups (#2908) - -Due to an upstream bug, memory is leaked in the inode cache when cgroups -are enabled. Disable as this is causing crashes. - -See: https://github.com/raspberrypi/linux/issues/2829 ---- - arch/arm/configs/bcm2709_defconfig | 4 ---- - arch/arm/configs/bcmrpi_defconfig | 4 ---- - arch/arm64/configs/bcmrpi3_defconfig | 4 ---- - 3 files changed, 12 deletions(-) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -14,8 +14,6 @@ CONFIG_TASK_XACCT=y - CONFIG_TASK_IO_ACCOUNTING=y - CONFIG_IKCONFIG=m - CONFIG_IKCONFIG_PROC=y --CONFIG_MEMCG=y --CONFIG_BLK_CGROUP=y - CONFIG_CGROUP_FREEZER=y - CONFIG_CPUSETS=y - CONFIG_CGROUP_DEVICE=y -@@ -64,10 +62,8 @@ CONFIG_MODULES=y - CONFIG_MODULE_UNLOAD=y - CONFIG_MODVERSIONS=y - CONFIG_MODULE_SRCVERSION_ALL=y --CONFIG_BLK_DEV_THROTTLING=y - CONFIG_PARTITION_ADVANCED=y - CONFIG_MAC_PARTITION=y --CONFIG_CFQ_GROUP_IOSCHED=y - CONFIG_BINFMT_MISC=m - CONFIG_CLEANCACHE=y - CONFIG_FRONTSWAP=y ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -13,8 +13,6 @@ CONFIG_TASK_XACCT=y - CONFIG_TASK_IO_ACCOUNTING=y - CONFIG_IKCONFIG=m - CONFIG_IKCONFIG_PROC=y --CONFIG_MEMCG=y --CONFIG_BLK_CGROUP=y - CONFIG_CGROUP_FREEZER=y - CONFIG_CGROUP_DEVICE=y - CONFIG_CGROUP_CPUACCT=y -@@ -58,10 +56,8 @@ CONFIG_MODULES=y - CONFIG_MODULE_UNLOAD=y - CONFIG_MODVERSIONS=y - CONFIG_MODULE_SRCVERSION_ALL=y --CONFIG_BLK_DEV_THROTTLING=y - CONFIG_PARTITION_ADVANCED=y - CONFIG_MAC_PARTITION=y --CONFIG_CFQ_GROUP_IOSCHED=y - CONFIG_BINFMT_MISC=m - CONFIG_CLEANCACHE=y - CONFIG_FRONTSWAP=y ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -13,8 +13,6 @@ CONFIG_TASK_XACCT=y - CONFIG_TASK_IO_ACCOUNTING=y - CONFIG_IKCONFIG=m - CONFIG_IKCONFIG_PROC=y --CONFIG_MEMCG=y --CONFIG_BLK_CGROUP=y - CONFIG_CGROUP_FREEZER=y - CONFIG_CPUSETS=y - CONFIG_CGROUP_DEVICE=y -@@ -62,10 +60,8 @@ CONFIG_MODULES=y - CONFIG_MODULE_UNLOAD=y - CONFIG_MODVERSIONS=y - CONFIG_MODULE_SRCVERSION_ALL=y --CONFIG_BLK_DEV_THROTTLING=y - CONFIG_PARTITION_ADVANCED=y - CONFIG_MAC_PARTITION=y --CONFIG_CFQ_GROUP_IOSCHED=y - CONFIG_BINFMT_MISC=y - CONFIG_CLEANCACHE=y - CONFIG_FRONTSWAP=y diff --git a/target/linux/brcm2708/patches-4.19/950-0395-nvmem-add-type-attribute.patch b/target/linux/brcm2708/patches-4.19/950-0395-nvmem-add-type-attribute.patch new file mode 100644 index 0000000000..cb88272cce --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0395-nvmem-add-type-attribute.patch @@ -0,0 +1,131 @@ +From b3acb96a394db9adcc13aae8321e3d18bbd7d30d Mon Sep 17 00:00:00 2001 +From: Alexandre Belloni +Date: Fri, 30 Nov 2018 11:53:20 +0000 +Subject: [PATCH 395/725] nvmem: add type attribute + +commit 16688453661b6d5159be558a1f8c1f54463a420f upstream. + +Add a type attribute so userspace is able to know how the data is stored as +this can help taking the correct decision when selecting which device to +use. This will also help program display the proper warnings when burning +fuses for example. + +Signed-off-by: Alexandre Belloni +Signed-off-by: Srinivas Kandagatla +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 21 +++++++++++++++++++++ + include/linux/nvmem-provider.h | 16 ++++++++++++++++ + 2 files changed, 37 insertions(+) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -36,6 +36,7 @@ struct nvmem_device { + size_t size; + bool read_only; + int flags; ++ enum nvmem_type type; + struct bin_attribute eeprom; + struct device *base_dev; + nvmem_reg_read_t reg_read; +@@ -84,6 +85,21 @@ static int nvmem_reg_write(struct nvmem_ + return -EINVAL; + } + ++static ssize_t type_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct nvmem_device *nvmem = to_nvmem_device(dev); ++ ++ return sprintf(buf, "%s\n", nvmem_type_str[nvmem->type]); ++} ++ ++static DEVICE_ATTR_RO(type); ++ ++static struct attribute *nvmem_attrs[] = { ++ &dev_attr_type.attr, ++ NULL, ++}; ++ + static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t pos, size_t count) +@@ -169,6 +185,7 @@ static struct bin_attribute *nvmem_bin_r + + static const struct attribute_group nvmem_bin_rw_group = { + .bin_attrs = nvmem_bin_rw_attributes, ++ .attrs = nvmem_attrs, + }; + + static const struct attribute_group *nvmem_rw_dev_groups[] = { +@@ -192,6 +209,7 @@ static struct bin_attribute *nvmem_bin_r + + static const struct attribute_group nvmem_bin_ro_group = { + .bin_attrs = nvmem_bin_ro_attributes, ++ .attrs = nvmem_attrs, + }; + + static const struct attribute_group *nvmem_ro_dev_groups[] = { +@@ -216,6 +234,7 @@ static struct bin_attribute *nvmem_bin_r + + static const struct attribute_group nvmem_bin_rw_root_group = { + .bin_attrs = nvmem_bin_rw_root_attributes, ++ .attrs = nvmem_attrs, + }; + + static const struct attribute_group *nvmem_rw_root_dev_groups[] = { +@@ -239,6 +258,7 @@ static struct bin_attribute *nvmem_bin_r + + static const struct attribute_group nvmem_bin_ro_root_group = { + .bin_attrs = nvmem_bin_ro_root_attributes, ++ .attrs = nvmem_attrs, + }; + + static const struct attribute_group *nvmem_ro_root_dev_groups[] = { +@@ -478,6 +498,7 @@ struct nvmem_device *nvmem_register(cons + nvmem->dev.bus = &nvmem_bus_type; + nvmem->dev.parent = config->dev; + nvmem->priv = config->priv; ++ nvmem->type = config->type; + nvmem->reg_read = config->reg_read; + nvmem->reg_write = config->reg_write; + nvmem->dev.of_node = config->dev->of_node; +--- a/include/linux/nvmem-provider.h ++++ b/include/linux/nvmem-provider.h +@@ -22,6 +22,20 @@ typedef int (*nvmem_reg_read_t)(void *pr + typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, + void *val, size_t bytes); + ++enum nvmem_type { ++ NVMEM_TYPE_UNKNOWN = 0, ++ NVMEM_TYPE_EEPROM, ++ NVMEM_TYPE_OTP, ++ NVMEM_TYPE_BATTERY_BACKED, ++}; ++ ++static const char * const nvmem_type_str[] = { ++ [NVMEM_TYPE_UNKNOWN] = "Unknown", ++ [NVMEM_TYPE_EEPROM] = "EEPROM", ++ [NVMEM_TYPE_OTP] = "OTP", ++ [NVMEM_TYPE_BATTERY_BACKED] = "Battery backed", ++}; ++ + /** + * struct nvmem_config - NVMEM device configuration + * +@@ -31,6 +45,7 @@ typedef int (*nvmem_reg_write_t)(void *p + * @owner: Pointer to exporter module. Used for refcounting. + * @cells: Optional array of pre-defined NVMEM cells. + * @ncells: Number of elements in cells. ++ * @type: Type of the nvmem storage + * @read_only: Device is read-only. + * @root_only: Device is accessibly to root only. + * @reg_read: Callback to read data. +@@ -54,6 +69,7 @@ struct nvmem_config { + struct module *owner; + const struct nvmem_cell_info *cells; + int ncells; ++ enum nvmem_type type; + bool read_only; + bool root_only; + nvmem_reg_read_t reg_read; diff --git a/target/linux/brcm2708/patches-4.19/950-0396-media-bcm2835-unicam-Add-support-for-enum-framesizes.patch b/target/linux/brcm2708/patches-4.19/950-0396-media-bcm2835-unicam-Add-support-for-enum-framesizes.patch deleted file mode 100644 index edff74cecf..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0396-media-bcm2835-unicam-Add-support-for-enum-framesizes.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 99e2a119c5dc323c698f8b7f699c20599c05e23e Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 5 Mar 2019 15:43:27 +0000 -Subject: [PATCH 396/703] media: bcm2835-unicam: Add support for enum - framesizes and frameintervals - -vidioc_enum_framesizes and vidioc_enum_frameintervals weren't implemented, -therefore clients couldn't enumerate the supported resolutions. - -Implement them by forwarding on to the sensor driver. - -Signed-off-by: Dave Stevenson ---- - .../media/platform/bcm2835/bcm2835-unicam.c | 94 +++++++++++++++++++ - 1 file changed, 94 insertions(+) - ---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c -+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c -@@ -1406,6 +1406,84 @@ static int unicam_g_edid(struct file *fi - return v4l2_subdev_call(dev->sensor, pad, get_edid, edid); - } - -+static int unicam_enum_framesizes(struct file *file, void *priv, -+ struct v4l2_frmsizeenum *fsize) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ const struct unicam_fmt *fmt; -+ struct v4l2_subdev_frame_size_enum fse; -+ int ret; -+ -+ /* check for valid format */ -+ fmt = find_format_by_pix(dev, fsize->pixel_format); -+ if (!fmt) { -+ unicam_dbg(3, dev, "Invalid pixel code: %x\n", -+ fsize->pixel_format); -+ return -EINVAL; -+ } -+ -+ fse.index = fsize->index; -+ fse.pad = 0; -+ fse.code = fmt->code; -+ -+ ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_size, NULL, &fse); -+ if (ret) -+ return ret; -+ -+ unicam_dbg(1, dev, "%s: index: %d code: %x W:[%d,%d] H:[%d,%d]\n", -+ __func__, fse.index, fse.code, fse.min_width, fse.max_width, -+ fse.min_height, fse.max_height); -+ -+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; -+ fsize->discrete.width = fse.max_width; -+ fsize->discrete.height = fse.max_height; -+ -+ return 0; -+} -+ -+static int unicam_enum_frameintervals(struct file *file, void *priv, -+ struct v4l2_frmivalenum *fival) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ const struct unicam_fmt *fmt; -+ struct v4l2_subdev_frame_interval_enum fie = { -+ .index = fival->index, -+ .width = fival->width, -+ .height = fival->height, -+ .which = V4L2_SUBDEV_FORMAT_ACTIVE, -+ }; -+ int ret; -+ -+ fmt = find_format_by_pix(dev, fival->pixel_format); -+ if (!fmt) -+ return -EINVAL; -+ -+ fie.code = fmt->code; -+ ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_interval, -+ NULL, &fie); -+ if (ret) -+ return ret; -+ -+ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; -+ fival->discrete = fie.interval; -+ -+ return 0; -+} -+ -+static int unicam_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ -+ return v4l2_g_parm_cap(video_devdata(file), dev->sensor, a); -+} -+ -+static int unicam_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ -+ return v4l2_s_parm_cap(video_devdata(file), dev->sensor, a); -+} -+ - static int unicam_g_dv_timings(struct file *file, void *priv, - struct v4l2_dv_timings *timings) - { -@@ -1613,6 +1691,12 @@ static const struct v4l2_ioctl_ops unica - .vidioc_g_edid = unicam_g_edid, - .vidioc_s_edid = unicam_s_edid, - -+ .vidioc_enum_framesizes = unicam_enum_framesizes, -+ .vidioc_enum_frameintervals = unicam_enum_frameintervals, -+ -+ .vidioc_g_parm = unicam_g_parm, -+ .vidioc_s_parm = unicam_s_parm, -+ - .vidioc_s_dv_timings = unicam_s_dv_timings, - .vidioc_g_dv_timings = unicam_g_dv_timings, - .vidioc_query_dv_timings = unicam_query_dv_timings, -@@ -1850,6 +1934,16 @@ static int unicam_probe_complete(struct - v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_ENUM_DV_TIMINGS); - v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_QUERY_DV_TIMINGS); - } -+ if (!v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_interval)) -+ v4l2_disable_ioctl(&unicam->video_dev, -+ VIDIOC_ENUM_FRAMEINTERVALS); -+ if (!v4l2_subdev_has_op(unicam->sensor, video, g_frame_interval)) -+ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_G_PARM); -+ if (!v4l2_subdev_has_op(unicam->sensor, video, s_frame_interval)) -+ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_S_PARM); -+ -+ if (!v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_size)) -+ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_ENUM_FRAMESIZES); - - ret = v4l2_device_register_subdev_nodes(&unicam->v4l2_dev); - if (ret) { diff --git a/target/linux/brcm2708/patches-4.19/950-0396-rtc-rv3028-add-new-driver.patch b/target/linux/brcm2708/patches-4.19/950-0396-rtc-rv3028-add-new-driver.patch new file mode 100644 index 0000000000..823aac89bb --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0396-rtc-rv3028-add-new-driver.patch @@ -0,0 +1,860 @@ +From 5437fefa8d11d8c2f9da39e393c83417cadabf83 Mon Sep 17 00:00:00 2001 +From: Alexandre Belloni +Date: Wed, 13 Feb 2019 00:21:36 +0100 +Subject: [PATCH 396/725] rtc: rv3028: add new driver + +upstream commit e6e7376cfd7b3f9b63de3a22792f64d9bfb2ab53. + +Add a driver for the MicroCrystal RV-3028. It is a SMT Real-Time Clock +Module that incorporates an integrated CMOS circuit together with an XTAL. +It has an i2c interface. + +The driver handles date/time, alarms, trickle charging, timestamping, +frequency offset correction, EEPROM and NVRAM. + +Signed-off-by: Alexandre Belloni +--- + Documentation/devicetree/bindings/rtc/rtc.txt | 69 ++ + drivers/rtc/Kconfig | 9 + + drivers/rtc/Makefile | 1 + + drivers/rtc/rtc-rv3028.c | 733 ++++++++++++++++++ + 4 files changed, 812 insertions(+) + create mode 100644 Documentation/devicetree/bindings/rtc/rtc.txt + create mode 100644 drivers/rtc/rtc-rv3028.c + +--- /dev/null ++++ b/Documentation/devicetree/bindings/rtc/rtc.txt +@@ -0,0 +1,69 @@ ++Generic device tree bindings for Real Time Clock devices ++======================================================== ++ ++This document describes generic bindings which can be used to describe Real Time ++Clock devices in a device tree. ++ ++Required properties ++------------------- ++ ++- compatible : name of RTC device following generic names recommended practice. ++ ++For other required properties e.g. to describe register sets, ++clocks, etc. check the binding documentation of the specific driver. ++ ++Optional properties ++------------------- ++ ++- start-year : if provided, the default hardware range supported by the RTC is ++ shifted so the first usable year is the specified one. ++ ++The following properties may not be supported by all drivers. However, if a ++driver wants to support one of the below features, it should adapt the bindings ++below. ++- trickle-resistor-ohms : Selected resistor for trickle charger. Should be given ++ if trickle charger should be enabled ++- trickle-diode-disable : Do not use internal trickle charger diode Should be ++ given if internal trickle charger diode should be ++ disabled ++- wakeup-source : Enables wake up of host system on alarm ++- quartz-load-femtofarads : The capacitive load of the quartz(x-tal), ++ expressed in femto Farad (fF). ++ The default value shall be listed (if optional), ++ and likewise all valid values. ++ ++Trivial RTCs ++------------ ++ ++This is a list of trivial RTC devices that have simple device tree ++bindings, consisting only of a compatible field, an address and ++possibly an interrupt line. ++ ++ ++Compatible Vendor / Chip ++========== ============= ++abracon,abb5zes3 AB-RTCMC-32.768kHz-B5ZE-S3: Real Time Clock/Calendar Module with I2C Interface ++dallas,ds1374 I2C, 32-Bit Binary Counter Watchdog RTC with Trickle Charger and Reset Input/Output ++dallas,ds1672 Dallas DS1672 Real-time Clock ++dallas,ds3232 Extremely Accurate I²C RTC with Integrated Crystal and SRAM ++epson,rx8010 I2C-BUS INTERFACE REAL TIME CLOCK MODULE ++epson,rx8581 I2C-BUS INTERFACE REAL TIME CLOCK MODULE ++emmicro,em3027 EM Microelectronic EM3027 Real-time Clock ++isil,isl1208 Intersil ISL1208 Low Power RTC with Battery Backed SRAM ++isil,isl1218 Intersil ISL1218 Low Power RTC with Battery Backed SRAM ++isil,isl12022 Intersil ISL12022 Real-time Clock ++microcrystal,rv3028 Real Time Clock Module with I2C-Bus ++microcrystal,rv3029 Real Time Clock Module with I2C-Bus ++microcrystal,rv8523 Real Time Clock ++nxp,pcf2127 Real-time clock ++nxp,pcf2129 Real-time clock ++nxp,pcf8563 Real-time clock/calendar ++pericom,pt7c4338 Real-time Clock Module ++ricoh,r2025sd I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC ++ricoh,r2221tl I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC ++ricoh,rs5c372a I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC ++ricoh,rs5c372b I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC ++ricoh,rv5c386 I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC ++ricoh,rv5c387a I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC ++sii,s35390a 2-wire CMOS real-time clock ++whwave,sd3078 I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC +--- a/drivers/rtc/Kconfig ++++ b/drivers/rtc/Kconfig +@@ -625,6 +625,15 @@ config RTC_DRV_EM3027 + This driver can also be built as a module. If so, the module + will be called rtc-em3027. + ++config RTC_DRV_RV3028 ++ tristate "Micro Crystal RV3028" ++ help ++ If you say yes here you get support for the Micro Crystal ++ RV3028. ++ ++ This driver can also be built as a module. If so, the module ++ will be called rtc-rv3028. ++ + config RTC_DRV_RV8803 + tristate "Micro Crystal RV8803, Epson RX8900" + help +--- a/drivers/rtc/Makefile ++++ b/drivers/rtc/Makefile +@@ -136,6 +136,7 @@ obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5 + obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o + obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o + obj-$(CONFIG_RTC_DRV_RTD119X) += rtc-rtd119x.o ++obj-$(CONFIG_RTC_DRV_RV3028) += rtc-rv3028.o + obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o + obj-$(CONFIG_RTC_DRV_RV8803) += rtc-rv8803.o + obj-$(CONFIG_RTC_DRV_RX4581) += rtc-rx4581.o +--- /dev/null ++++ b/drivers/rtc/rtc-rv3028.c +@@ -0,0 +1,733 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * RTC driver for the Micro Crystal RV3028 ++ * ++ * Copyright (C) 2019 Micro Crystal SA ++ * ++ * Alexandre Belloni ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "rtc-core.h" ++ ++#define RV3028_SEC 0x00 ++#define RV3028_MIN 0x01 ++#define RV3028_HOUR 0x02 ++#define RV3028_WDAY 0x03 ++#define RV3028_DAY 0x04 ++#define RV3028_MONTH 0x05 ++#define RV3028_YEAR 0x06 ++#define RV3028_ALARM_MIN 0x07 ++#define RV3028_ALARM_HOUR 0x08 ++#define RV3028_ALARM_DAY 0x09 ++#define RV3028_STATUS 0x0E ++#define RV3028_CTRL1 0x0F ++#define RV3028_CTRL2 0x10 ++#define RV3028_EVT_CTRL 0x13 ++#define RV3028_TS_COUNT 0x14 ++#define RV3028_TS_SEC 0x15 ++#define RV3028_RAM1 0x1F ++#define RV3028_EEPROM_ADDR 0x25 ++#define RV3028_EEPROM_DATA 0x26 ++#define RV3028_EEPROM_CMD 0x27 ++#define RV3028_CLKOUT 0x35 ++#define RV3028_OFFSET 0x36 ++#define RV3028_BACKUP 0x37 ++ ++#define RV3028_STATUS_PORF BIT(0) ++#define RV3028_STATUS_EVF BIT(1) ++#define RV3028_STATUS_AF BIT(2) ++#define RV3028_STATUS_TF BIT(3) ++#define RV3028_STATUS_UF BIT(4) ++#define RV3028_STATUS_BSF BIT(5) ++#define RV3028_STATUS_CLKF BIT(6) ++#define RV3028_STATUS_EEBUSY BIT(7) ++ ++#define RV3028_CTRL1_EERD BIT(3) ++#define RV3028_CTRL1_WADA BIT(5) ++ ++#define RV3028_CTRL2_RESET BIT(0) ++#define RV3028_CTRL2_12_24 BIT(1) ++#define RV3028_CTRL2_EIE BIT(2) ++#define RV3028_CTRL2_AIE BIT(3) ++#define RV3028_CTRL2_TIE BIT(4) ++#define RV3028_CTRL2_UIE BIT(5) ++#define RV3028_CTRL2_TSE BIT(7) ++ ++#define RV3028_EVT_CTRL_TSR BIT(2) ++ ++#define RV3028_EEPROM_CMD_WRITE 0x21 ++#define RV3028_EEPROM_CMD_READ 0x22 ++ ++#define RV3028_EEBUSY_POLL 10000 ++#define RV3028_EEBUSY_TIMEOUT 100000 ++ ++#define RV3028_BACKUP_TCE BIT(5) ++#define RV3028_BACKUP_TCR_MASK GENMASK(1,0) ++ ++#define OFFSET_STEP_PPT 953674 ++ ++enum rv3028_type { ++ rv_3028, ++}; ++ ++struct rv3028_data { ++ struct regmap *regmap; ++ struct rtc_device *rtc; ++ enum rv3028_type type; ++}; ++ ++static u16 rv3028_trickle_resistors[] = {1000, 3000, 6000, 11000}; ++ ++static ssize_t timestamp0_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent); ++ ++ regmap_update_bits(rv3028->regmap, RV3028_EVT_CTRL, RV3028_EVT_CTRL_TSR, ++ RV3028_EVT_CTRL_TSR); ++ ++ return count; ++}; ++ ++static ssize_t timestamp0_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent); ++ struct rtc_time tm; ++ int ret, count; ++ u8 date[6]; ++ ++ ret = regmap_read(rv3028->regmap, RV3028_TS_COUNT, &count); ++ if (ret) ++ return ret; ++ ++ if (!count) ++ return 0; ++ ++ ret = regmap_bulk_read(rv3028->regmap, RV3028_TS_SEC, date, ++ sizeof(date)); ++ if (ret) ++ return ret; ++ ++ tm.tm_sec = bcd2bin(date[0]); ++ tm.tm_min = bcd2bin(date[1]); ++ tm.tm_hour = bcd2bin(date[2]); ++ tm.tm_mday = bcd2bin(date[3]); ++ tm.tm_mon = bcd2bin(date[4]) - 1; ++ tm.tm_year = bcd2bin(date[5]) + 100; ++ ++ ret = rtc_valid_tm(&tm); ++ if (ret) ++ return ret; ++ ++ return sprintf(buf, "%llu\n", ++ (unsigned long long)rtc_tm_to_time64(&tm)); ++}; ++ ++static DEVICE_ATTR_RW(timestamp0); ++ ++static ssize_t timestamp0_count_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent); ++ int ret, count; ++ ++ ret = regmap_read(rv3028->regmap, RV3028_TS_COUNT, &count); ++ if (ret) ++ return ret; ++ ++ return sprintf(buf, "%u\n", count); ++}; ++ ++static DEVICE_ATTR_RO(timestamp0_count); ++ ++static struct attribute *rv3028_attrs[] = { ++ &dev_attr_timestamp0.attr, ++ &dev_attr_timestamp0_count.attr, ++ NULL ++}; ++ ++static const struct attribute_group rv3028_attr_group = { ++ .attrs = rv3028_attrs, ++}; ++ ++static irqreturn_t rv3028_handle_irq(int irq, void *dev_id) ++{ ++ struct rv3028_data *rv3028 = dev_id; ++ unsigned long events = 0; ++ u32 status = 0, ctrl = 0; ++ ++ if (regmap_read(rv3028->regmap, RV3028_STATUS, &status) < 0 || ++ status == 0) { ++ return IRQ_NONE; ++ } ++ ++ if (status & RV3028_STATUS_PORF) ++ dev_warn(&rv3028->rtc->dev, "Voltage low, data loss detected.\n"); ++ ++ if (status & RV3028_STATUS_TF) { ++ status |= RV3028_STATUS_TF; ++ ctrl |= RV3028_CTRL2_TIE; ++ events |= RTC_PF; ++ } ++ ++ if (status & RV3028_STATUS_AF) { ++ status |= RV3028_STATUS_AF; ++ ctrl |= RV3028_CTRL2_AIE; ++ events |= RTC_AF; ++ } ++ ++ if (status & RV3028_STATUS_UF) { ++ status |= RV3028_STATUS_UF; ++ ctrl |= RV3028_CTRL2_UIE; ++ events |= RTC_UF; ++ } ++ ++ if (events) { ++ rtc_update_irq(rv3028->rtc, 1, events); ++ regmap_update_bits(rv3028->regmap, RV3028_STATUS, status, 0); ++ regmap_update_bits(rv3028->regmap, RV3028_CTRL2, ctrl, 0); ++ } ++ ++ if (status & RV3028_STATUS_EVF) { ++ sysfs_notify(&rv3028->rtc->dev.kobj, NULL, ++ dev_attr_timestamp0.attr.name); ++ dev_warn(&rv3028->rtc->dev, "event detected"); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static int rv3028_get_time(struct device *dev, struct rtc_time *tm) ++{ ++ struct rv3028_data *rv3028 = dev_get_drvdata(dev); ++ u8 date[7]; ++ int ret, status; ++ ++ ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status); ++ if (ret < 0) ++ return ret; ++ ++ if (status & RV3028_STATUS_PORF) { ++ dev_warn(dev, "Voltage low, data is invalid.\n"); ++ return -EINVAL; ++ } ++ ++ ret = regmap_bulk_read(rv3028->regmap, RV3028_SEC, date, sizeof(date)); ++ if (ret) ++ return ret; ++ ++ tm->tm_sec = bcd2bin(date[RV3028_SEC] & 0x7f); ++ tm->tm_min = bcd2bin(date[RV3028_MIN] & 0x7f); ++ tm->tm_hour = bcd2bin(date[RV3028_HOUR] & 0x3f); ++ tm->tm_wday = ilog2(date[RV3028_WDAY] & 0x7f); ++ tm->tm_mday = bcd2bin(date[RV3028_DAY] & 0x3f); ++ tm->tm_mon = bcd2bin(date[RV3028_MONTH] & 0x1f) - 1; ++ tm->tm_year = bcd2bin(date[RV3028_YEAR]) + 100; ++ ++ return 0; ++} ++ ++static int rv3028_set_time(struct device *dev, struct rtc_time *tm) ++{ ++ struct rv3028_data *rv3028 = dev_get_drvdata(dev); ++ u8 date[7]; ++ int ret; ++ ++ date[RV3028_SEC] = bin2bcd(tm->tm_sec); ++ date[RV3028_MIN] = bin2bcd(tm->tm_min); ++ date[RV3028_HOUR] = bin2bcd(tm->tm_hour); ++ date[RV3028_WDAY] = 1 << (tm->tm_wday); ++ date[RV3028_DAY] = bin2bcd(tm->tm_mday); ++ date[RV3028_MONTH] = bin2bcd(tm->tm_mon + 1); ++ date[RV3028_YEAR] = bin2bcd(tm->tm_year - 100); ++ ++ /* ++ * Writing to the Seconds register has the same effect as setting RESET ++ * bit to 1 ++ */ ++ ret = regmap_bulk_write(rv3028->regmap, RV3028_SEC, date, ++ sizeof(date)); ++ if (ret) ++ return ret; ++ ++ ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS, ++ RV3028_STATUS_PORF, 0); ++ ++ return ret; ++} ++ ++static int rv3028_get_alarm(struct device *dev, struct rtc_wkalrm *alrm) ++{ ++ struct rv3028_data *rv3028 = dev_get_drvdata(dev); ++ u8 alarmvals[3]; ++ int status, ctrl, ret; ++ ++ ret = regmap_bulk_read(rv3028->regmap, RV3028_ALARM_MIN, alarmvals, ++ sizeof(alarmvals)); ++ if (ret) ++ return ret; ++ ++ ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status); ++ if (ret < 0) ++ return ret; ++ ++ ret = regmap_read(rv3028->regmap, RV3028_CTRL2, &ctrl); ++ if (ret < 0) ++ return ret; ++ ++ alrm->time.tm_sec = 0; ++ alrm->time.tm_min = bcd2bin(alarmvals[0] & 0x7f); ++ alrm->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f); ++ alrm->time.tm_mday = bcd2bin(alarmvals[2] & 0x3f); ++ ++ alrm->enabled = !!(ctrl & RV3028_CTRL2_AIE); ++ alrm->pending = (status & RV3028_STATUS_AF) && alrm->enabled; ++ ++ return 0; ++} ++ ++static int rv3028_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ++{ ++ struct rv3028_data *rv3028 = dev_get_drvdata(dev); ++ u8 alarmvals[3]; ++ u8 ctrl = 0; ++ int ret; ++ ++ /* The alarm has no seconds, round up to nearest minute */ ++ if (alrm->time.tm_sec) { ++ time64_t alarm_time = rtc_tm_to_time64(&alrm->time); ++ ++ alarm_time += 60 - alrm->time.tm_sec; ++ rtc_time64_to_tm(alarm_time, &alrm->time); ++ } ++ ++ ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2, ++ RV3028_CTRL2_AIE | RV3028_CTRL2_UIE, 0); ++ if (ret) ++ return ret; ++ ++ alarmvals[0] = bin2bcd(alrm->time.tm_min); ++ alarmvals[1] = bin2bcd(alrm->time.tm_hour); ++ alarmvals[2] = bin2bcd(alrm->time.tm_mday); ++ ++ ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS, ++ RV3028_STATUS_AF, 0); ++ if (ret) ++ return ret; ++ ++ ret = regmap_bulk_write(rv3028->regmap, RV3028_ALARM_MIN, alarmvals, ++ sizeof(alarmvals)); ++ if (ret) ++ return ret; ++ ++ if (alrm->enabled) { ++ if (rv3028->rtc->uie_rtctimer.enabled) ++ ctrl |= RV3028_CTRL2_UIE; ++ if (rv3028->rtc->aie_timer.enabled) ++ ctrl |= RV3028_CTRL2_AIE; ++ } ++ ++ ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2, ++ RV3028_CTRL2_UIE | RV3028_CTRL2_AIE, ctrl); ++ ++ return ret; ++} ++ ++static int rv3028_alarm_irq_enable(struct device *dev, unsigned int enabled) ++{ ++ struct rv3028_data *rv3028 = dev_get_drvdata(dev); ++ int ctrl = 0, ret; ++ ++ if (enabled) { ++ if (rv3028->rtc->uie_rtctimer.enabled) ++ ctrl |= RV3028_CTRL2_UIE; ++ if (rv3028->rtc->aie_timer.enabled) ++ ctrl |= RV3028_CTRL2_AIE; ++ } ++ ++ ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS, ++ RV3028_STATUS_AF | RV3028_STATUS_UF, 0); ++ if (ret) ++ return ret; ++ ++ ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2, ++ RV3028_CTRL2_UIE | RV3028_CTRL2_AIE, ctrl); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int rv3028_read_offset(struct device *dev, long *offset) ++{ ++ struct rv3028_data *rv3028 = dev_get_drvdata(dev); ++ int ret, value, steps; ++ ++ ret = regmap_read(rv3028->regmap, RV3028_OFFSET, &value); ++ if (ret < 0) ++ return ret; ++ ++ steps = sign_extend32(value << 1, 8); ++ ++ ret = regmap_read(rv3028->regmap, RV3028_BACKUP, &value); ++ if (ret < 0) ++ return ret; ++ ++ steps += value >> 7; ++ ++ *offset = DIV_ROUND_CLOSEST(steps * OFFSET_STEP_PPT, 1000); ++ ++ return 0; ++} ++ ++static int rv3028_set_offset(struct device *dev, long offset) ++{ ++ struct rv3028_data *rv3028 = dev_get_drvdata(dev); ++ int ret; ++ ++ offset = clamp(offset, -244141L, 243187L) * 1000; ++ offset = DIV_ROUND_CLOSEST(offset, OFFSET_STEP_PPT); ++ ++ ret = regmap_write(rv3028->regmap, RV3028_OFFSET, offset >> 1); ++ if (ret < 0) ++ return ret; ++ ++ return regmap_update_bits(rv3028->regmap, RV3028_BACKUP, BIT(7), ++ offset << 7); ++} ++ ++static int rv3028_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) ++{ ++ struct rv3028_data *rv3028 = dev_get_drvdata(dev); ++ int status, ret = 0; ++ ++ switch (cmd) { ++ case RTC_VL_READ: ++ ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status); ++ if (ret < 0) ++ return ret; ++ ++ if (status & RV3028_STATUS_PORF) ++ dev_warn(&rv3028->rtc->dev, "Voltage low, data loss detected.\n"); ++ ++ status &= RV3028_STATUS_PORF; ++ ++ if (copy_to_user((void __user *)arg, &status, sizeof(int))) ++ return -EFAULT; ++ ++ return 0; ++ ++ case RTC_VL_CLR: ++ ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS, ++ RV3028_STATUS_PORF, 0); ++ ++ return ret; ++ ++ default: ++ return -ENOIOCTLCMD; ++ } ++} ++ ++static int rv3028_nvram_write(void *priv, unsigned int offset, void *val, ++ size_t bytes) ++{ ++ return regmap_bulk_write(priv, RV3028_RAM1 + offset, val, bytes); ++} ++ ++static int rv3028_nvram_read(void *priv, unsigned int offset, void *val, ++ size_t bytes) ++{ ++ return regmap_bulk_read(priv, RV3028_RAM1 + offset, val, bytes); ++} ++ ++static int rv3028_eeprom_write(void *priv, unsigned int offset, void *val, ++ size_t bytes) ++{ ++ u32 status, ctrl1; ++ int i, ret, err; ++ u8 *buf = val; ++ ++ ret = regmap_read(priv, RV3028_CTRL1, &ctrl1); ++ if (ret) ++ return ret; ++ ++ if (!(ctrl1 & RV3028_CTRL1_EERD)) { ++ ret = regmap_update_bits(priv, RV3028_CTRL1, ++ RV3028_CTRL1_EERD, RV3028_CTRL1_EERD); ++ if (ret) ++ return ret; ++ ++ ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, ++ !(status & RV3028_STATUS_EEBUSY), ++ RV3028_EEBUSY_POLL, ++ RV3028_EEBUSY_TIMEOUT); ++ if (ret) ++ goto restore_eerd; ++ } ++ ++ for (i = 0; i < bytes; i++) { ++ ret = regmap_write(priv, RV3028_EEPROM_ADDR, offset + i); ++ if (ret) ++ goto restore_eerd; ++ ++ ret = regmap_write(priv, RV3028_EEPROM_DATA, buf[i]); ++ if (ret) ++ goto restore_eerd; ++ ++ ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0); ++ if (ret) ++ goto restore_eerd; ++ ++ ret = regmap_write(priv, RV3028_EEPROM_CMD, ++ RV3028_EEPROM_CMD_WRITE); ++ if (ret) ++ goto restore_eerd; ++ ++ usleep_range(RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT); ++ ++ ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, ++ !(status & RV3028_STATUS_EEBUSY), ++ RV3028_EEBUSY_POLL, ++ RV3028_EEBUSY_TIMEOUT); ++ if (ret) ++ goto restore_eerd; ++ } ++ ++restore_eerd: ++ if (!(ctrl1 & RV3028_CTRL1_EERD)) ++ { ++ err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD, ++ 0); ++ if (err && !ret) ++ ret = err; ++ } ++ ++ return ret; ++} ++ ++static int rv3028_eeprom_read(void *priv, unsigned int offset, void *val, ++ size_t bytes) ++{ ++ u32 status, ctrl1, data; ++ int i, ret, err; ++ u8 *buf = val; ++ ++ ret = regmap_read(priv, RV3028_CTRL1, &ctrl1); ++ if (ret) ++ return ret; ++ ++ if (!(ctrl1 & RV3028_CTRL1_EERD)) { ++ ret = regmap_update_bits(priv, RV3028_CTRL1, ++ RV3028_CTRL1_EERD, RV3028_CTRL1_EERD); ++ if (ret) ++ return ret; ++ ++ ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, ++ !(status & RV3028_STATUS_EEBUSY), ++ RV3028_EEBUSY_POLL, ++ RV3028_EEBUSY_TIMEOUT); ++ if (ret) ++ goto restore_eerd; ++ } ++ ++ for (i = 0; i < bytes; i++) { ++ ret = regmap_write(priv, RV3028_EEPROM_ADDR, offset + i); ++ if (ret) ++ goto restore_eerd; ++ ++ ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0); ++ if (ret) ++ goto restore_eerd; ++ ++ ret = regmap_write(priv, RV3028_EEPROM_CMD, ++ RV3028_EEPROM_CMD_READ); ++ if (ret) ++ goto restore_eerd; ++ ++ ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, ++ !(status & RV3028_STATUS_EEBUSY), ++ RV3028_EEBUSY_POLL, ++ RV3028_EEBUSY_TIMEOUT); ++ if (ret) ++ goto restore_eerd; ++ ++ ret = regmap_read(priv, RV3028_EEPROM_DATA, &data); ++ if (ret) ++ goto restore_eerd; ++ buf[i] = data; ++ } ++ ++restore_eerd: ++ if (!(ctrl1 & RV3028_CTRL1_EERD)) ++ { ++ err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD, ++ 0); ++ if (err && !ret) ++ ret = err; ++ } ++ ++ return ret; ++} ++ ++static struct rtc_class_ops rv3028_rtc_ops = { ++ .read_time = rv3028_get_time, ++ .set_time = rv3028_set_time, ++ .read_offset = rv3028_read_offset, ++ .set_offset = rv3028_set_offset, ++ .ioctl = rv3028_ioctl, ++}; ++ ++static const struct regmap_config regmap_config = { ++ .reg_bits = 8, ++ .val_bits = 8, ++ .max_register = 0x37, ++}; ++ ++static int rv3028_probe(struct i2c_client *client) ++{ ++ struct rv3028_data *rv3028; ++ int ret, status; ++ u32 ohms; ++ struct nvmem_config nvmem_cfg = { ++ .name = "rv3028_nvram", ++ .word_size = 1, ++ .stride = 1, ++ .size = 2, ++ .type = NVMEM_TYPE_BATTERY_BACKED, ++ .reg_read = rv3028_nvram_read, ++ .reg_write = rv3028_nvram_write, ++ }; ++ struct nvmem_config eeprom_cfg = { ++ .name = "rv3028_eeprom", ++ .word_size = 1, ++ .stride = 1, ++ .size = 43, ++ .type = NVMEM_TYPE_EEPROM, ++ .reg_read = rv3028_eeprom_read, ++ .reg_write = rv3028_eeprom_write, ++ }; ++ ++ rv3028 = devm_kzalloc(&client->dev, sizeof(struct rv3028_data), ++ GFP_KERNEL); ++ if (!rv3028) ++ return -ENOMEM; ++ ++ rv3028->regmap = devm_regmap_init_i2c(client, ®map_config); ++ ++ i2c_set_clientdata(client, rv3028); ++ ++ ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status); ++ if (ret < 0) ++ return ret; ++ ++ if (status & RV3028_STATUS_PORF) ++ dev_warn(&client->dev, "Voltage low, data loss detected.\n"); ++ ++ if (status & RV3028_STATUS_AF) ++ dev_warn(&client->dev, "An alarm may have been missed.\n"); ++ ++ rv3028->rtc = devm_rtc_allocate_device(&client->dev); ++ if (IS_ERR(rv3028->rtc)) { ++ return PTR_ERR(rv3028->rtc); ++ } ++ ++ if (client->irq > 0) { ++ ret = devm_request_threaded_irq(&client->dev, client->irq, ++ NULL, rv3028_handle_irq, ++ IRQF_TRIGGER_LOW | IRQF_ONESHOT, ++ "rv3028", rv3028); ++ if (ret) { ++ dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); ++ client->irq = 0; ++ } else { ++ rv3028_rtc_ops.read_alarm = rv3028_get_alarm; ++ rv3028_rtc_ops.set_alarm = rv3028_set_alarm; ++ rv3028_rtc_ops.alarm_irq_enable = rv3028_alarm_irq_enable; ++ } ++ } ++ ++ ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL1, ++ RV3028_CTRL1_WADA, RV3028_CTRL1_WADA); ++ if (ret) ++ return ret; ++ ++ /* setup timestamping */ ++ ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2, ++ RV3028_CTRL2_EIE | RV3028_CTRL2_TSE, ++ RV3028_CTRL2_EIE | RV3028_CTRL2_TSE); ++ if (ret) ++ return ret; ++ ++ /* setup trickle charger */ ++ if (!device_property_read_u32(&client->dev, "trickle-resistor-ohms", ++ &ohms)) { ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(rv3028_trickle_resistors); i++) ++ if (ohms == rv3028_trickle_resistors[i]) ++ break; ++ ++ if (i < ARRAY_SIZE(rv3028_trickle_resistors)) { ++ ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP, ++ RV3028_BACKUP_TCE | ++ RV3028_BACKUP_TCR_MASK, ++ RV3028_BACKUP_TCE | i); ++ if (ret) ++ return ret; ++ } else { ++ dev_warn(&client->dev, "invalid trickle resistor value\n"); ++ } ++ } ++ ++ ret = rtc_add_group(rv3028->rtc, &rv3028_attr_group); ++ if (ret) ++ return ret; ++ ++ rv3028->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; ++ rv3028->rtc->range_max = RTC_TIMESTAMP_END_2099; ++ rv3028->rtc->ops = &rv3028_rtc_ops; ++ ret = rtc_register_device(rv3028->rtc); ++ if (ret) ++ return ret; ++ ++ nvmem_cfg.priv = rv3028->regmap; ++ rtc_nvmem_register(rv3028->rtc, &nvmem_cfg); ++ eeprom_cfg.priv = rv3028->regmap; ++ rtc_nvmem_register(rv3028->rtc, &eeprom_cfg); ++ ++ rv3028->rtc->max_user_freq = 1; ++ ++ return 0; ++} ++ ++static const struct of_device_id rv3028_of_match[] = { ++ { .compatible = "microcrystal,rv3028", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, rv3028_of_match); ++ ++static struct i2c_driver rv3028_driver = { ++ .driver = { ++ .name = "rtc-rv3028", ++ .of_match_table = of_match_ptr(rv3028_of_match), ++ }, ++ .probe_new = rv3028_probe, ++}; ++module_i2c_driver(rv3028_driver); ++ ++MODULE_AUTHOR("Alexandre Belloni "); ++MODULE_DESCRIPTION("Micro Crystal RV3028 RTC driver"); ++MODULE_LICENSE("GPL v2"); diff --git a/target/linux/brcm2708/patches-4.19/950-0397-configs-Add-RTC_DRV_RV3028-m.patch b/target/linux/brcm2708/patches-4.19/950-0397-configs-Add-RTC_DRV_RV3028-m.patch new file mode 100644 index 0000000000..499fa643c8 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0397-configs-Add-RTC_DRV_RV3028-m.patch @@ -0,0 +1,44 @@ +From bfb96e21b688b5c798db9a6082ad76e72721693e Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 28 Mar 2019 13:13:52 +0000 +Subject: [PATCH 397/725] configs: Add RTC_DRV_RV3028=m + +See: https://github.com/raspberrypi/linux/issues/2912 + +Signed-off-by: Phil Elwell +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + arch/arm64/configs/bcmrpi3_defconfig | 1 + + 3 files changed, 3 insertions(+) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -1157,6 +1157,7 @@ CONFIG_RTC_DRV_FM3130=m + CONFIG_RTC_DRV_RX8581=m + CONFIG_RTC_DRV_RX8025=m + CONFIG_RTC_DRV_EM3027=m ++CONFIG_RTC_DRV_RV3028=m + CONFIG_RTC_DRV_M41T93=m + CONFIG_RTC_DRV_M41T94=m + CONFIG_RTC_DRV_DS1302=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -1150,6 +1150,7 @@ CONFIG_RTC_DRV_FM3130=m + CONFIG_RTC_DRV_RX8581=m + CONFIG_RTC_DRV_RX8025=m + CONFIG_RTC_DRV_EM3027=m ++CONFIG_RTC_DRV_RV3028=m + CONFIG_RTC_DRV_M41T93=m + CONFIG_RTC_DRV_M41T94=m + CONFIG_RTC_DRV_DS1302=m +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -1017,6 +1017,7 @@ CONFIG_RTC_DRV_FM3130=m + CONFIG_RTC_DRV_RX8581=m + CONFIG_RTC_DRV_RX8025=m + CONFIG_RTC_DRV_EM3027=m ++CONFIG_RTC_DRV_RV3028=m + CONFIG_RTC_DRV_M41T93=m + CONFIG_RTC_DRV_M41T94=m + CONFIG_RTC_DRV_DS1302=m diff --git a/target/linux/brcm2708/patches-4.19/950-0397-staging-bcm2835-codec-Refactor-default-resolution-co.patch b/target/linux/brcm2708/patches-4.19/950-0397-staging-bcm2835-codec-Refactor-default-resolution-co.patch deleted file mode 100644 index 2340d71826..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0397-staging-bcm2835-codec-Refactor-default-resolution-co.patch +++ /dev/null @@ -1,154 +0,0 @@ -From a0019271c4c0b0a156770fdb53267010627f03b1 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 20 Mar 2019 10:06:51 +0000 -Subject: [PATCH 397/703] staging: bcm2835-codec: Refactor default resolution - code - -The default resolution code was different for each role -as compressed formats need to pass bytesperline as 0 and -set up customised buffer sizes. -This is common setup, therefore amend get_sizeimage and -get_bytesperline to do the correct thing whether compressed -or uncompressed. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 103 +++++++----------- - 1 file changed, 40 insertions(+), 63 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -578,10 +578,17 @@ static void job_abort(void *priv) - ctx->aborting = 1; - } - --static inline unsigned int get_sizeimage(int bpl, int height, -+static inline unsigned int get_sizeimage(int bpl, int width, int height, - struct bcm2835_codec_fmt *fmt) - { -- return (bpl * height * fmt->size_multiplier_x2) >> 1; -+ if (fmt->flags & V4L2_FMT_FLAG_COMPRESSED) { -+ if (width * height > 1280 * 720) -+ return DEF_COMP_BUF_SIZE_GREATER_720P; -+ else -+ return DEF_COMP_BUF_SIZE_720P_OR_LESS; -+ } else { -+ return (bpl * height * fmt->size_multiplier_x2) >> 1; -+ } - } - - static inline unsigned int get_bytesperline(int width, -@@ -1032,22 +1039,13 @@ static int vidioc_try_fmt(struct v4l2_fo - * some of the pixels are active. - */ - f->fmt.pix.height = ALIGN(f->fmt.pix.height, 16); -- -- f->fmt.pix.bytesperline = get_bytesperline(f->fmt.pix.width, -- fmt); -- f->fmt.pix.sizeimage = get_sizeimage(f->fmt.pix.bytesperline, -- f->fmt.pix.height, -- fmt); -- } else { -- u32 min_size = f->fmt.pix.width > 1280 || -- f->fmt.pix.height > 720 ? -- DEF_COMP_BUF_SIZE_GREATER_720P : -- DEF_COMP_BUF_SIZE_720P_OR_LESS; -- -- f->fmt.pix.bytesperline = 0; -- if (f->fmt.pix.sizeimage < min_size) -- f->fmt.pix.sizeimage = min_size; - } -+ f->fmt.pix.bytesperline = get_bytesperline(f->fmt.pix.width, -+ fmt); -+ f->fmt.pix.sizeimage = get_sizeimage(f->fmt.pix.bytesperline, -+ f->fmt.pix.width, -+ f->fmt.pix.height, -+ fmt); - - f->fmt.pix.field = V4L2_FIELD_NONE; - -@@ -1159,6 +1157,7 @@ static int vidioc_s_fmt(struct bcm2835_c - q_data_dst->bytesperline = - get_bytesperline(f->fmt.pix.width, q_data_dst->fmt); - q_data_dst->sizeimage = get_sizeimage(q_data_dst->bytesperline, -+ q_data_dst->crop_width, - q_data_dst->height, - q_data_dst->fmt); - update_capture_port = true; -@@ -2218,52 +2217,30 @@ static int bcm2835_codec_open(struct fil - - ctx->q_data[V4L2_M2M_SRC].fmt = get_default_format(dev, false); - ctx->q_data[V4L2_M2M_DST].fmt = get_default_format(dev, true); -- switch (dev->role) { -- case DECODE: -- /* -- * Input width and height are irrelevant as they will be defined -- * by the bitstream not the format. Required by V4L2 though. -- */ -- ctx->q_data[V4L2_M2M_SRC].crop_width = DEFAULT_WIDTH; -- ctx->q_data[V4L2_M2M_SRC].crop_height = DEFAULT_HEIGHT; -- ctx->q_data[V4L2_M2M_SRC].height = DEFAULT_HEIGHT; -- ctx->q_data[V4L2_M2M_SRC].bytesperline = 0; -- ctx->q_data[V4L2_M2M_SRC].sizeimage = -- DEF_COMP_BUF_SIZE_720P_OR_LESS; -- -- ctx->q_data[V4L2_M2M_DST].crop_width = DEFAULT_WIDTH; -- ctx->q_data[V4L2_M2M_DST].crop_height = DEFAULT_HEIGHT; -- ctx->q_data[V4L2_M2M_DST].height = DEFAULT_HEIGHT; -- ctx->q_data[V4L2_M2M_DST].bytesperline = -- get_bytesperline(DEFAULT_WIDTH, -- ctx->q_data[V4L2_M2M_DST].fmt); -- ctx->q_data[V4L2_M2M_DST].sizeimage = -- get_sizeimage(ctx->q_data[V4L2_M2M_DST].bytesperline, -- ctx->q_data[V4L2_M2M_DST].height, -- ctx->q_data[V4L2_M2M_DST].fmt); -- break; -- case ENCODE: -- ctx->q_data[V4L2_M2M_SRC].crop_width = DEFAULT_WIDTH; -- ctx->q_data[V4L2_M2M_SRC].crop_height = DEFAULT_HEIGHT; -- ctx->q_data[V4L2_M2M_SRC].height = DEFAULT_HEIGHT; -- ctx->q_data[V4L2_M2M_SRC].bytesperline = -- get_bytesperline(DEFAULT_WIDTH, -- ctx->q_data[V4L2_M2M_SRC].fmt); -- ctx->q_data[V4L2_M2M_SRC].sizeimage = -- get_sizeimage(ctx->q_data[V4L2_M2M_SRC].bytesperline, -- ctx->q_data[V4L2_M2M_SRC].height, -- ctx->q_data[V4L2_M2M_SRC].fmt); -- -- ctx->q_data[V4L2_M2M_DST].crop_width = DEFAULT_WIDTH; -- ctx->q_data[V4L2_M2M_DST].crop_height = DEFAULT_HEIGHT; -- ctx->q_data[V4L2_M2M_DST].bytesperline = 0; -- ctx->q_data[V4L2_M2M_DST].height = DEFAULT_HEIGHT; -- ctx->q_data[V4L2_M2M_DST].sizeimage = -- DEF_COMP_BUF_SIZE_720P_OR_LESS; -- break; -- case ISP: -- break; -- } -+ -+ ctx->q_data[V4L2_M2M_SRC].crop_width = DEFAULT_WIDTH; -+ ctx->q_data[V4L2_M2M_SRC].crop_height = DEFAULT_HEIGHT; -+ ctx->q_data[V4L2_M2M_SRC].height = DEFAULT_HEIGHT; -+ ctx->q_data[V4L2_M2M_SRC].bytesperline = -+ get_bytesperline(DEFAULT_WIDTH, -+ ctx->q_data[V4L2_M2M_SRC].fmt); -+ ctx->q_data[V4L2_M2M_SRC].sizeimage = -+ get_sizeimage(ctx->q_data[V4L2_M2M_SRC].bytesperline, -+ ctx->q_data[V4L2_M2M_SRC].crop_width, -+ ctx->q_data[V4L2_M2M_SRC].height, -+ ctx->q_data[V4L2_M2M_SRC].fmt); -+ -+ ctx->q_data[V4L2_M2M_DST].crop_width = DEFAULT_WIDTH; -+ ctx->q_data[V4L2_M2M_DST].crop_height = DEFAULT_HEIGHT; -+ ctx->q_data[V4L2_M2M_DST].height = DEFAULT_HEIGHT; -+ ctx->q_data[V4L2_M2M_DST].bytesperline = -+ get_bytesperline(DEFAULT_WIDTH, -+ ctx->q_data[V4L2_M2M_DST].fmt); -+ ctx->q_data[V4L2_M2M_DST].sizeimage = -+ get_sizeimage(ctx->q_data[V4L2_M2M_DST].bytesperline, -+ ctx->q_data[V4L2_M2M_DST].crop_width, -+ ctx->q_data[V4L2_M2M_DST].height, -+ ctx->q_data[V4L2_M2M_DST].fmt); - - ctx->colorspace = V4L2_COLORSPACE_REC709; - ctx->bitrate = 10 * 1000 * 1000; diff --git a/target/linux/brcm2708/patches-4.19/950-0398-nvmem-add-type-attribute.patch b/target/linux/brcm2708/patches-4.19/950-0398-nvmem-add-type-attribute.patch deleted file mode 100644 index de3b5ede20..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0398-nvmem-add-type-attribute.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 8d82ada47578fd867da43108fadcd77e3f57f056 Mon Sep 17 00:00:00 2001 -From: Alexandre Belloni -Date: Fri, 30 Nov 2018 11:53:20 +0000 -Subject: [PATCH 398/703] nvmem: add type attribute - -commit 16688453661b6d5159be558a1f8c1f54463a420f upstream. - -Add a type attribute so userspace is able to know how the data is stored as -this can help taking the correct decision when selecting which device to -use. This will also help program display the proper warnings when burning -fuses for example. - -Signed-off-by: Alexandre Belloni -Signed-off-by: Srinivas Kandagatla -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 21 +++++++++++++++++++++ - include/linux/nvmem-provider.h | 16 ++++++++++++++++ - 2 files changed, 37 insertions(+) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -36,6 +36,7 @@ struct nvmem_device { - size_t size; - bool read_only; - int flags; -+ enum nvmem_type type; - struct bin_attribute eeprom; - struct device *base_dev; - nvmem_reg_read_t reg_read; -@@ -84,6 +85,21 @@ static int nvmem_reg_write(struct nvmem_ - return -EINVAL; - } - -+static ssize_t type_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct nvmem_device *nvmem = to_nvmem_device(dev); -+ -+ return sprintf(buf, "%s\n", nvmem_type_str[nvmem->type]); -+} -+ -+static DEVICE_ATTR_RO(type); -+ -+static struct attribute *nvmem_attrs[] = { -+ &dev_attr_type.attr, -+ NULL, -+}; -+ - static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, - char *buf, loff_t pos, size_t count) -@@ -169,6 +185,7 @@ static struct bin_attribute *nvmem_bin_r - - static const struct attribute_group nvmem_bin_rw_group = { - .bin_attrs = nvmem_bin_rw_attributes, -+ .attrs = nvmem_attrs, - }; - - static const struct attribute_group *nvmem_rw_dev_groups[] = { -@@ -192,6 +209,7 @@ static struct bin_attribute *nvmem_bin_r - - static const struct attribute_group nvmem_bin_ro_group = { - .bin_attrs = nvmem_bin_ro_attributes, -+ .attrs = nvmem_attrs, - }; - - static const struct attribute_group *nvmem_ro_dev_groups[] = { -@@ -216,6 +234,7 @@ static struct bin_attribute *nvmem_bin_r - - static const struct attribute_group nvmem_bin_rw_root_group = { - .bin_attrs = nvmem_bin_rw_root_attributes, -+ .attrs = nvmem_attrs, - }; - - static const struct attribute_group *nvmem_rw_root_dev_groups[] = { -@@ -239,6 +258,7 @@ static struct bin_attribute *nvmem_bin_r - - static const struct attribute_group nvmem_bin_ro_root_group = { - .bin_attrs = nvmem_bin_ro_root_attributes, -+ .attrs = nvmem_attrs, - }; - - static const struct attribute_group *nvmem_ro_root_dev_groups[] = { -@@ -478,6 +498,7 @@ struct nvmem_device *nvmem_register(cons - nvmem->dev.bus = &nvmem_bus_type; - nvmem->dev.parent = config->dev; - nvmem->priv = config->priv; -+ nvmem->type = config->type; - nvmem->reg_read = config->reg_read; - nvmem->reg_write = config->reg_write; - nvmem->dev.of_node = config->dev->of_node; ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -22,6 +22,20 @@ typedef int (*nvmem_reg_read_t)(void *pr - typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, - void *val, size_t bytes); - -+enum nvmem_type { -+ NVMEM_TYPE_UNKNOWN = 0, -+ NVMEM_TYPE_EEPROM, -+ NVMEM_TYPE_OTP, -+ NVMEM_TYPE_BATTERY_BACKED, -+}; -+ -+static const char * const nvmem_type_str[] = { -+ [NVMEM_TYPE_UNKNOWN] = "Unknown", -+ [NVMEM_TYPE_EEPROM] = "EEPROM", -+ [NVMEM_TYPE_OTP] = "OTP", -+ [NVMEM_TYPE_BATTERY_BACKED] = "Battery backed", -+}; -+ - /** - * struct nvmem_config - NVMEM device configuration - * -@@ -31,6 +45,7 @@ typedef int (*nvmem_reg_write_t)(void *p - * @owner: Pointer to exporter module. Used for refcounting. - * @cells: Optional array of pre-defined NVMEM cells. - * @ncells: Number of elements in cells. -+ * @type: Type of the nvmem storage - * @read_only: Device is read-only. - * @root_only: Device is accessibly to root only. - * @reg_read: Callback to read data. -@@ -54,6 +69,7 @@ struct nvmem_config { - struct module *owner; - const struct nvmem_cell_info *cells; - int ncells; -+ enum nvmem_type type; - bool read_only; - bool root_only; - nvmem_reg_read_t reg_read; diff --git a/target/linux/brcm2708/patches-4.19/950-0398-overlays-Add-rv3028-to-i2c-rtc.patch b/target/linux/brcm2708/patches-4.19/950-0398-overlays-Add-rv3028-to-i2c-rtc.patch new file mode 100644 index 0000000000..6f065ea6fc --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0398-overlays-Add-rv3028-to-i2c-rtc.patch @@ -0,0 +1,75 @@ +From cf17a30d916eedceda8a4be81259e3813c5a3490 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 28 Mar 2019 13:26:59 +0000 +Subject: [PATCH 398/725] overlays: Add rv3028 to i2c-rtc + +See: https://github.com/raspberrypi/linux/issues/2912 + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/README | 4 +++- + .../arm/boot/dts/overlays/i2c-rtc-overlay.dts | 19 ++++++++++++++++++- + 2 files changed, 21 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -939,6 +939,8 @@ Params: abx80x Select o + + pcf8563 Select the PCF8563 device + ++ rv3028 Select the Micro Crystal RV3028 device ++ + addr Sets the address for the RTC. Note that the + device must be configured to use the specified + address. +@@ -947,7 +949,7 @@ Params: abx80x Select o + "schottky" (ABx80x only) + + trickle-resistor-ohms Resistor value for trickle charge (DS1339, +- ABx80x) ++ ABx80x, RV3028) + + wakeup-source Specify that the RTC can be used as a wakeup + source +--- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts +@@ -158,6 +158,21 @@ + }; + }; + ++ fragment@10 { ++ target = <&i2c_arm>; ++ __dormant__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ rv3028: rv3028@52 { ++ compatible = "microcrystal,rv3028"; ++ reg = <0x52>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ + __overrides__ { + abx80x = <0>,"+0"; + ds1307 = <0>,"+1"; +@@ -169,6 +184,7 @@ + pcf8523 = <0>,"+7"; + pcf8563 = <0>,"+8"; + m41t62 = <0>,"+9"; ++ rv3028 = <0>,"+10"; + + addr = <&abx80x>, "reg:0", + <&ds1307>, "reg:0", +@@ -182,7 +198,8 @@ + <&m41t62>, "reg:0"; + trickle-diode-type = <&abx80x>,"abracon,tc-diode"; + trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0", +- <&abx80x>,"abracon,tc-resistor"; ++ <&abx80x>,"abracon,tc-resistor", ++ <&rv3028>,"trickle-resistor-ohms:0"; + wakeup-source = <&ds1339>,"wakeup-source?", + <&ds3231>,"wakeup-source?", + <&mcp7940x>,"wakeup-source?", diff --git a/target/linux/brcm2708/patches-4.19/950-0399-ASoC-tlv320aic32x4-SND_SOC_DAPM_MICBIAS-is-deprecate.patch b/target/linux/brcm2708/patches-4.19/950-0399-ASoC-tlv320aic32x4-SND_SOC_DAPM_MICBIAS-is-deprecate.patch new file mode 100644 index 0000000000..410157c459 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0399-ASoC-tlv320aic32x4-SND_SOC_DAPM_MICBIAS-is-deprecate.patch @@ -0,0 +1,78 @@ +From aa84e9cf563d82701357486ed17fd390fe28e692 Mon Sep 17 00:00:00 2001 +From: b-ak +Date: Wed, 9 Jan 2019 22:41:21 +0530 +Subject: [PATCH 399/725] ASoC: tlv320aic32x4: SND_SOC_DAPM_MICBIAS is + deprecated + +commit 04d979d7a7bac2f645cd827ea37e5ffa5b4e1f97 upstream. + +SND_SOC_DAPM_MICBIAS is deprecated, replace it with SND_SOC_DAPM_SUPPLY. + +MICBIAS voltage wasn't supplied to the microphone with the older +SND_SOC_DAPM_MICBIAS widget, hence the microphone wouldn't work. + +This patch fixes the problem. + +Signed-off-by: b-ak +Signed-off-by: Mark Brown +--- + sound/soc/codecs/tlv320aic32x4.c | 30 +++++++++++++++++++++++++++++- + sound/soc/codecs/tlv320aic32x4.h | 1 + + 2 files changed, 30 insertions(+), 1 deletion(-) + +--- a/sound/soc/codecs/tlv320aic32x4.c ++++ b/sound/soc/codecs/tlv320aic32x4.c +@@ -79,6 +79,32 @@ struct aic32x4_priv { + struct device *dev; + }; + ++static int mic_bias_event(struct snd_soc_dapm_widget *w, ++ struct snd_kcontrol *kcontrol, int event) ++{ ++ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); ++ ++ switch (event) { ++ case SND_SOC_DAPM_POST_PMU: ++ /* Change Mic Bias Registor */ ++ snd_soc_component_update_bits(component, AIC32X4_MICBIAS, ++ AIC32x4_MICBIAS_MASK, ++ AIC32X4_MICBIAS_LDOIN | ++ AIC32X4_MICBIAS_2075V); ++ printk(KERN_DEBUG "%s: Mic Bias will be turned ON\n", __func__); ++ break; ++ case SND_SOC_DAPM_PRE_PMD: ++ snd_soc_component_update_bits(component, AIC32X4_MICBIAS, ++ AIC32x4_MICBIAS_MASK, 0); ++ printk(KERN_DEBUG "%s: Mic Bias will be turned OFF\n", ++ __func__); ++ break; ++ } ++ ++ return 0; ++} ++ ++ + static int aic32x4_get_mfp1_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) + { +@@ -450,7 +476,9 @@ static const struct snd_soc_dapm_widget + SND_SOC_DAPM_MUX("IN3_R to Left Mixer Negative Resistor", SND_SOC_NOPM, 0, 0, + in3r_to_lmixer_controls), + +- SND_SOC_DAPM_MICBIAS("Mic Bias", AIC32X4_MICBIAS, 6, 0), ++ SND_SOC_DAPM_SUPPLY("Mic Bias", AIC32X4_MICBIAS, 6, 0, mic_bias_event, ++ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), ++ + + SND_SOC_DAPM_OUTPUT("HPL"), + SND_SOC_DAPM_OUTPUT("HPR"), +--- a/sound/soc/codecs/tlv320aic32x4.h ++++ b/sound/soc/codecs/tlv320aic32x4.h +@@ -195,6 +195,7 @@ int aic32x4_remove(struct device *dev); + /* AIC32X4_MICBIAS */ + #define AIC32X4_MICBIAS_LDOIN BIT(3) + #define AIC32X4_MICBIAS_2075V 0x60 ++#define AIC32x4_MICBIAS_MASK GENMASK(6, 3) + + /* AIC32X4_LMICPGANIN */ + #define AIC32X4_LMICPGANIN_IN2R_10K 0x10 diff --git a/target/linux/brcm2708/patches-4.19/950-0399-rtc-rv3028-add-new-driver.patch b/target/linux/brcm2708/patches-4.19/950-0399-rtc-rv3028-add-new-driver.patch deleted file mode 100644 index b4e3a31546..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0399-rtc-rv3028-add-new-driver.patch +++ /dev/null @@ -1,860 +0,0 @@ -From f2e44f13f6524a60c5d3c1395ba3e323f72eff6d Mon Sep 17 00:00:00 2001 -From: Alexandre Belloni -Date: Wed, 13 Feb 2019 00:21:36 +0100 -Subject: [PATCH 399/703] rtc: rv3028: add new driver - -upstream commit e6e7376cfd7b3f9b63de3a22792f64d9bfb2ab53. - -Add a driver for the MicroCrystal RV-3028. It is a SMT Real-Time Clock -Module that incorporates an integrated CMOS circuit together with an XTAL. -It has an i2c interface. - -The driver handles date/time, alarms, trickle charging, timestamping, -frequency offset correction, EEPROM and NVRAM. - -Signed-off-by: Alexandre Belloni ---- - Documentation/devicetree/bindings/rtc/rtc.txt | 69 ++ - drivers/rtc/Kconfig | 9 + - drivers/rtc/Makefile | 1 + - drivers/rtc/rtc-rv3028.c | 733 ++++++++++++++++++ - 4 files changed, 812 insertions(+) - create mode 100644 Documentation/devicetree/bindings/rtc/rtc.txt - create mode 100644 drivers/rtc/rtc-rv3028.c - ---- /dev/null -+++ b/Documentation/devicetree/bindings/rtc/rtc.txt -@@ -0,0 +1,69 @@ -+Generic device tree bindings for Real Time Clock devices -+======================================================== -+ -+This document describes generic bindings which can be used to describe Real Time -+Clock devices in a device tree. -+ -+Required properties -+------------------- -+ -+- compatible : name of RTC device following generic names recommended practice. -+ -+For other required properties e.g. to describe register sets, -+clocks, etc. check the binding documentation of the specific driver. -+ -+Optional properties -+------------------- -+ -+- start-year : if provided, the default hardware range supported by the RTC is -+ shifted so the first usable year is the specified one. -+ -+The following properties may not be supported by all drivers. However, if a -+driver wants to support one of the below features, it should adapt the bindings -+below. -+- trickle-resistor-ohms : Selected resistor for trickle charger. Should be given -+ if trickle charger should be enabled -+- trickle-diode-disable : Do not use internal trickle charger diode Should be -+ given if internal trickle charger diode should be -+ disabled -+- wakeup-source : Enables wake up of host system on alarm -+- quartz-load-femtofarads : The capacitive load of the quartz(x-tal), -+ expressed in femto Farad (fF). -+ The default value shall be listed (if optional), -+ and likewise all valid values. -+ -+Trivial RTCs -+------------ -+ -+This is a list of trivial RTC devices that have simple device tree -+bindings, consisting only of a compatible field, an address and -+possibly an interrupt line. -+ -+ -+Compatible Vendor / Chip -+========== ============= -+abracon,abb5zes3 AB-RTCMC-32.768kHz-B5ZE-S3: Real Time Clock/Calendar Module with I2C Interface -+dallas,ds1374 I2C, 32-Bit Binary Counter Watchdog RTC with Trickle Charger and Reset Input/Output -+dallas,ds1672 Dallas DS1672 Real-time Clock -+dallas,ds3232 Extremely Accurate I²C RTC with Integrated Crystal and SRAM -+epson,rx8010 I2C-BUS INTERFACE REAL TIME CLOCK MODULE -+epson,rx8581 I2C-BUS INTERFACE REAL TIME CLOCK MODULE -+emmicro,em3027 EM Microelectronic EM3027 Real-time Clock -+isil,isl1208 Intersil ISL1208 Low Power RTC with Battery Backed SRAM -+isil,isl1218 Intersil ISL1218 Low Power RTC with Battery Backed SRAM -+isil,isl12022 Intersil ISL12022 Real-time Clock -+microcrystal,rv3028 Real Time Clock Module with I2C-Bus -+microcrystal,rv3029 Real Time Clock Module with I2C-Bus -+microcrystal,rv8523 Real Time Clock -+nxp,pcf2127 Real-time clock -+nxp,pcf2129 Real-time clock -+nxp,pcf8563 Real-time clock/calendar -+pericom,pt7c4338 Real-time Clock Module -+ricoh,r2025sd I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC -+ricoh,r2221tl I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC -+ricoh,rs5c372a I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC -+ricoh,rs5c372b I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC -+ricoh,rv5c386 I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC -+ricoh,rv5c387a I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC -+sii,s35390a 2-wire CMOS real-time clock -+whwave,sd3078 I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC ---- a/drivers/rtc/Kconfig -+++ b/drivers/rtc/Kconfig -@@ -625,6 +625,15 @@ config RTC_DRV_EM3027 - This driver can also be built as a module. If so, the module - will be called rtc-em3027. - -+config RTC_DRV_RV3028 -+ tristate "Micro Crystal RV3028" -+ help -+ If you say yes here you get support for the Micro Crystal -+ RV3028. -+ -+ This driver can also be built as a module. If so, the module -+ will be called rtc-rv3028. -+ - config RTC_DRV_RV8803 - tristate "Micro Crystal RV8803, Epson RX8900" - help ---- a/drivers/rtc/Makefile -+++ b/drivers/rtc/Makefile -@@ -136,6 +136,7 @@ obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5 - obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o - obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o - obj-$(CONFIG_RTC_DRV_RTD119X) += rtc-rtd119x.o -+obj-$(CONFIG_RTC_DRV_RV3028) += rtc-rv3028.o - obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o - obj-$(CONFIG_RTC_DRV_RV8803) += rtc-rv8803.o - obj-$(CONFIG_RTC_DRV_RX4581) += rtc-rx4581.o ---- /dev/null -+++ b/drivers/rtc/rtc-rv3028.c -@@ -0,0 +1,733 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * RTC driver for the Micro Crystal RV3028 -+ * -+ * Copyright (C) 2019 Micro Crystal SA -+ * -+ * Alexandre Belloni -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "rtc-core.h" -+ -+#define RV3028_SEC 0x00 -+#define RV3028_MIN 0x01 -+#define RV3028_HOUR 0x02 -+#define RV3028_WDAY 0x03 -+#define RV3028_DAY 0x04 -+#define RV3028_MONTH 0x05 -+#define RV3028_YEAR 0x06 -+#define RV3028_ALARM_MIN 0x07 -+#define RV3028_ALARM_HOUR 0x08 -+#define RV3028_ALARM_DAY 0x09 -+#define RV3028_STATUS 0x0E -+#define RV3028_CTRL1 0x0F -+#define RV3028_CTRL2 0x10 -+#define RV3028_EVT_CTRL 0x13 -+#define RV3028_TS_COUNT 0x14 -+#define RV3028_TS_SEC 0x15 -+#define RV3028_RAM1 0x1F -+#define RV3028_EEPROM_ADDR 0x25 -+#define RV3028_EEPROM_DATA 0x26 -+#define RV3028_EEPROM_CMD 0x27 -+#define RV3028_CLKOUT 0x35 -+#define RV3028_OFFSET 0x36 -+#define RV3028_BACKUP 0x37 -+ -+#define RV3028_STATUS_PORF BIT(0) -+#define RV3028_STATUS_EVF BIT(1) -+#define RV3028_STATUS_AF BIT(2) -+#define RV3028_STATUS_TF BIT(3) -+#define RV3028_STATUS_UF BIT(4) -+#define RV3028_STATUS_BSF BIT(5) -+#define RV3028_STATUS_CLKF BIT(6) -+#define RV3028_STATUS_EEBUSY BIT(7) -+ -+#define RV3028_CTRL1_EERD BIT(3) -+#define RV3028_CTRL1_WADA BIT(5) -+ -+#define RV3028_CTRL2_RESET BIT(0) -+#define RV3028_CTRL2_12_24 BIT(1) -+#define RV3028_CTRL2_EIE BIT(2) -+#define RV3028_CTRL2_AIE BIT(3) -+#define RV3028_CTRL2_TIE BIT(4) -+#define RV3028_CTRL2_UIE BIT(5) -+#define RV3028_CTRL2_TSE BIT(7) -+ -+#define RV3028_EVT_CTRL_TSR BIT(2) -+ -+#define RV3028_EEPROM_CMD_WRITE 0x21 -+#define RV3028_EEPROM_CMD_READ 0x22 -+ -+#define RV3028_EEBUSY_POLL 10000 -+#define RV3028_EEBUSY_TIMEOUT 100000 -+ -+#define RV3028_BACKUP_TCE BIT(5) -+#define RV3028_BACKUP_TCR_MASK GENMASK(1,0) -+ -+#define OFFSET_STEP_PPT 953674 -+ -+enum rv3028_type { -+ rv_3028, -+}; -+ -+struct rv3028_data { -+ struct regmap *regmap; -+ struct rtc_device *rtc; -+ enum rv3028_type type; -+}; -+ -+static u16 rv3028_trickle_resistors[] = {1000, 3000, 6000, 11000}; -+ -+static ssize_t timestamp0_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent); -+ -+ regmap_update_bits(rv3028->regmap, RV3028_EVT_CTRL, RV3028_EVT_CTRL_TSR, -+ RV3028_EVT_CTRL_TSR); -+ -+ return count; -+}; -+ -+static ssize_t timestamp0_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent); -+ struct rtc_time tm; -+ int ret, count; -+ u8 date[6]; -+ -+ ret = regmap_read(rv3028->regmap, RV3028_TS_COUNT, &count); -+ if (ret) -+ return ret; -+ -+ if (!count) -+ return 0; -+ -+ ret = regmap_bulk_read(rv3028->regmap, RV3028_TS_SEC, date, -+ sizeof(date)); -+ if (ret) -+ return ret; -+ -+ tm.tm_sec = bcd2bin(date[0]); -+ tm.tm_min = bcd2bin(date[1]); -+ tm.tm_hour = bcd2bin(date[2]); -+ tm.tm_mday = bcd2bin(date[3]); -+ tm.tm_mon = bcd2bin(date[4]) - 1; -+ tm.tm_year = bcd2bin(date[5]) + 100; -+ -+ ret = rtc_valid_tm(&tm); -+ if (ret) -+ return ret; -+ -+ return sprintf(buf, "%llu\n", -+ (unsigned long long)rtc_tm_to_time64(&tm)); -+}; -+ -+static DEVICE_ATTR_RW(timestamp0); -+ -+static ssize_t timestamp0_count_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent); -+ int ret, count; -+ -+ ret = regmap_read(rv3028->regmap, RV3028_TS_COUNT, &count); -+ if (ret) -+ return ret; -+ -+ return sprintf(buf, "%u\n", count); -+}; -+ -+static DEVICE_ATTR_RO(timestamp0_count); -+ -+static struct attribute *rv3028_attrs[] = { -+ &dev_attr_timestamp0.attr, -+ &dev_attr_timestamp0_count.attr, -+ NULL -+}; -+ -+static const struct attribute_group rv3028_attr_group = { -+ .attrs = rv3028_attrs, -+}; -+ -+static irqreturn_t rv3028_handle_irq(int irq, void *dev_id) -+{ -+ struct rv3028_data *rv3028 = dev_id; -+ unsigned long events = 0; -+ u32 status = 0, ctrl = 0; -+ -+ if (regmap_read(rv3028->regmap, RV3028_STATUS, &status) < 0 || -+ status == 0) { -+ return IRQ_NONE; -+ } -+ -+ if (status & RV3028_STATUS_PORF) -+ dev_warn(&rv3028->rtc->dev, "Voltage low, data loss detected.\n"); -+ -+ if (status & RV3028_STATUS_TF) { -+ status |= RV3028_STATUS_TF; -+ ctrl |= RV3028_CTRL2_TIE; -+ events |= RTC_PF; -+ } -+ -+ if (status & RV3028_STATUS_AF) { -+ status |= RV3028_STATUS_AF; -+ ctrl |= RV3028_CTRL2_AIE; -+ events |= RTC_AF; -+ } -+ -+ if (status & RV3028_STATUS_UF) { -+ status |= RV3028_STATUS_UF; -+ ctrl |= RV3028_CTRL2_UIE; -+ events |= RTC_UF; -+ } -+ -+ if (events) { -+ rtc_update_irq(rv3028->rtc, 1, events); -+ regmap_update_bits(rv3028->regmap, RV3028_STATUS, status, 0); -+ regmap_update_bits(rv3028->regmap, RV3028_CTRL2, ctrl, 0); -+ } -+ -+ if (status & RV3028_STATUS_EVF) { -+ sysfs_notify(&rv3028->rtc->dev.kobj, NULL, -+ dev_attr_timestamp0.attr.name); -+ dev_warn(&rv3028->rtc->dev, "event detected"); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static int rv3028_get_time(struct device *dev, struct rtc_time *tm) -+{ -+ struct rv3028_data *rv3028 = dev_get_drvdata(dev); -+ u8 date[7]; -+ int ret, status; -+ -+ ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status); -+ if (ret < 0) -+ return ret; -+ -+ if (status & RV3028_STATUS_PORF) { -+ dev_warn(dev, "Voltage low, data is invalid.\n"); -+ return -EINVAL; -+ } -+ -+ ret = regmap_bulk_read(rv3028->regmap, RV3028_SEC, date, sizeof(date)); -+ if (ret) -+ return ret; -+ -+ tm->tm_sec = bcd2bin(date[RV3028_SEC] & 0x7f); -+ tm->tm_min = bcd2bin(date[RV3028_MIN] & 0x7f); -+ tm->tm_hour = bcd2bin(date[RV3028_HOUR] & 0x3f); -+ tm->tm_wday = ilog2(date[RV3028_WDAY] & 0x7f); -+ tm->tm_mday = bcd2bin(date[RV3028_DAY] & 0x3f); -+ tm->tm_mon = bcd2bin(date[RV3028_MONTH] & 0x1f) - 1; -+ tm->tm_year = bcd2bin(date[RV3028_YEAR]) + 100; -+ -+ return 0; -+} -+ -+static int rv3028_set_time(struct device *dev, struct rtc_time *tm) -+{ -+ struct rv3028_data *rv3028 = dev_get_drvdata(dev); -+ u8 date[7]; -+ int ret; -+ -+ date[RV3028_SEC] = bin2bcd(tm->tm_sec); -+ date[RV3028_MIN] = bin2bcd(tm->tm_min); -+ date[RV3028_HOUR] = bin2bcd(tm->tm_hour); -+ date[RV3028_WDAY] = 1 << (tm->tm_wday); -+ date[RV3028_DAY] = bin2bcd(tm->tm_mday); -+ date[RV3028_MONTH] = bin2bcd(tm->tm_mon + 1); -+ date[RV3028_YEAR] = bin2bcd(tm->tm_year - 100); -+ -+ /* -+ * Writing to the Seconds register has the same effect as setting RESET -+ * bit to 1 -+ */ -+ ret = regmap_bulk_write(rv3028->regmap, RV3028_SEC, date, -+ sizeof(date)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS, -+ RV3028_STATUS_PORF, 0); -+ -+ return ret; -+} -+ -+static int rv3028_get_alarm(struct device *dev, struct rtc_wkalrm *alrm) -+{ -+ struct rv3028_data *rv3028 = dev_get_drvdata(dev); -+ u8 alarmvals[3]; -+ int status, ctrl, ret; -+ -+ ret = regmap_bulk_read(rv3028->regmap, RV3028_ALARM_MIN, alarmvals, -+ sizeof(alarmvals)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status); -+ if (ret < 0) -+ return ret; -+ -+ ret = regmap_read(rv3028->regmap, RV3028_CTRL2, &ctrl); -+ if (ret < 0) -+ return ret; -+ -+ alrm->time.tm_sec = 0; -+ alrm->time.tm_min = bcd2bin(alarmvals[0] & 0x7f); -+ alrm->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f); -+ alrm->time.tm_mday = bcd2bin(alarmvals[2] & 0x3f); -+ -+ alrm->enabled = !!(ctrl & RV3028_CTRL2_AIE); -+ alrm->pending = (status & RV3028_STATUS_AF) && alrm->enabled; -+ -+ return 0; -+} -+ -+static int rv3028_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) -+{ -+ struct rv3028_data *rv3028 = dev_get_drvdata(dev); -+ u8 alarmvals[3]; -+ u8 ctrl = 0; -+ int ret; -+ -+ /* The alarm has no seconds, round up to nearest minute */ -+ if (alrm->time.tm_sec) { -+ time64_t alarm_time = rtc_tm_to_time64(&alrm->time); -+ -+ alarm_time += 60 - alrm->time.tm_sec; -+ rtc_time64_to_tm(alarm_time, &alrm->time); -+ } -+ -+ ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2, -+ RV3028_CTRL2_AIE | RV3028_CTRL2_UIE, 0); -+ if (ret) -+ return ret; -+ -+ alarmvals[0] = bin2bcd(alrm->time.tm_min); -+ alarmvals[1] = bin2bcd(alrm->time.tm_hour); -+ alarmvals[2] = bin2bcd(alrm->time.tm_mday); -+ -+ ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS, -+ RV3028_STATUS_AF, 0); -+ if (ret) -+ return ret; -+ -+ ret = regmap_bulk_write(rv3028->regmap, RV3028_ALARM_MIN, alarmvals, -+ sizeof(alarmvals)); -+ if (ret) -+ return ret; -+ -+ if (alrm->enabled) { -+ if (rv3028->rtc->uie_rtctimer.enabled) -+ ctrl |= RV3028_CTRL2_UIE; -+ if (rv3028->rtc->aie_timer.enabled) -+ ctrl |= RV3028_CTRL2_AIE; -+ } -+ -+ ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2, -+ RV3028_CTRL2_UIE | RV3028_CTRL2_AIE, ctrl); -+ -+ return ret; -+} -+ -+static int rv3028_alarm_irq_enable(struct device *dev, unsigned int enabled) -+{ -+ struct rv3028_data *rv3028 = dev_get_drvdata(dev); -+ int ctrl = 0, ret; -+ -+ if (enabled) { -+ if (rv3028->rtc->uie_rtctimer.enabled) -+ ctrl |= RV3028_CTRL2_UIE; -+ if (rv3028->rtc->aie_timer.enabled) -+ ctrl |= RV3028_CTRL2_AIE; -+ } -+ -+ ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS, -+ RV3028_STATUS_AF | RV3028_STATUS_UF, 0); -+ if (ret) -+ return ret; -+ -+ ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2, -+ RV3028_CTRL2_UIE | RV3028_CTRL2_AIE, ctrl); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static int rv3028_read_offset(struct device *dev, long *offset) -+{ -+ struct rv3028_data *rv3028 = dev_get_drvdata(dev); -+ int ret, value, steps; -+ -+ ret = regmap_read(rv3028->regmap, RV3028_OFFSET, &value); -+ if (ret < 0) -+ return ret; -+ -+ steps = sign_extend32(value << 1, 8); -+ -+ ret = regmap_read(rv3028->regmap, RV3028_BACKUP, &value); -+ if (ret < 0) -+ return ret; -+ -+ steps += value >> 7; -+ -+ *offset = DIV_ROUND_CLOSEST(steps * OFFSET_STEP_PPT, 1000); -+ -+ return 0; -+} -+ -+static int rv3028_set_offset(struct device *dev, long offset) -+{ -+ struct rv3028_data *rv3028 = dev_get_drvdata(dev); -+ int ret; -+ -+ offset = clamp(offset, -244141L, 243187L) * 1000; -+ offset = DIV_ROUND_CLOSEST(offset, OFFSET_STEP_PPT); -+ -+ ret = regmap_write(rv3028->regmap, RV3028_OFFSET, offset >> 1); -+ if (ret < 0) -+ return ret; -+ -+ return regmap_update_bits(rv3028->regmap, RV3028_BACKUP, BIT(7), -+ offset << 7); -+} -+ -+static int rv3028_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) -+{ -+ struct rv3028_data *rv3028 = dev_get_drvdata(dev); -+ int status, ret = 0; -+ -+ switch (cmd) { -+ case RTC_VL_READ: -+ ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status); -+ if (ret < 0) -+ return ret; -+ -+ if (status & RV3028_STATUS_PORF) -+ dev_warn(&rv3028->rtc->dev, "Voltage low, data loss detected.\n"); -+ -+ status &= RV3028_STATUS_PORF; -+ -+ if (copy_to_user((void __user *)arg, &status, sizeof(int))) -+ return -EFAULT; -+ -+ return 0; -+ -+ case RTC_VL_CLR: -+ ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS, -+ RV3028_STATUS_PORF, 0); -+ -+ return ret; -+ -+ default: -+ return -ENOIOCTLCMD; -+ } -+} -+ -+static int rv3028_nvram_write(void *priv, unsigned int offset, void *val, -+ size_t bytes) -+{ -+ return regmap_bulk_write(priv, RV3028_RAM1 + offset, val, bytes); -+} -+ -+static int rv3028_nvram_read(void *priv, unsigned int offset, void *val, -+ size_t bytes) -+{ -+ return regmap_bulk_read(priv, RV3028_RAM1 + offset, val, bytes); -+} -+ -+static int rv3028_eeprom_write(void *priv, unsigned int offset, void *val, -+ size_t bytes) -+{ -+ u32 status, ctrl1; -+ int i, ret, err; -+ u8 *buf = val; -+ -+ ret = regmap_read(priv, RV3028_CTRL1, &ctrl1); -+ if (ret) -+ return ret; -+ -+ if (!(ctrl1 & RV3028_CTRL1_EERD)) { -+ ret = regmap_update_bits(priv, RV3028_CTRL1, -+ RV3028_CTRL1_EERD, RV3028_CTRL1_EERD); -+ if (ret) -+ return ret; -+ -+ ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, -+ !(status & RV3028_STATUS_EEBUSY), -+ RV3028_EEBUSY_POLL, -+ RV3028_EEBUSY_TIMEOUT); -+ if (ret) -+ goto restore_eerd; -+ } -+ -+ for (i = 0; i < bytes; i++) { -+ ret = regmap_write(priv, RV3028_EEPROM_ADDR, offset + i); -+ if (ret) -+ goto restore_eerd; -+ -+ ret = regmap_write(priv, RV3028_EEPROM_DATA, buf[i]); -+ if (ret) -+ goto restore_eerd; -+ -+ ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0); -+ if (ret) -+ goto restore_eerd; -+ -+ ret = regmap_write(priv, RV3028_EEPROM_CMD, -+ RV3028_EEPROM_CMD_WRITE); -+ if (ret) -+ goto restore_eerd; -+ -+ usleep_range(RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT); -+ -+ ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, -+ !(status & RV3028_STATUS_EEBUSY), -+ RV3028_EEBUSY_POLL, -+ RV3028_EEBUSY_TIMEOUT); -+ if (ret) -+ goto restore_eerd; -+ } -+ -+restore_eerd: -+ if (!(ctrl1 & RV3028_CTRL1_EERD)) -+ { -+ err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD, -+ 0); -+ if (err && !ret) -+ ret = err; -+ } -+ -+ return ret; -+} -+ -+static int rv3028_eeprom_read(void *priv, unsigned int offset, void *val, -+ size_t bytes) -+{ -+ u32 status, ctrl1, data; -+ int i, ret, err; -+ u8 *buf = val; -+ -+ ret = regmap_read(priv, RV3028_CTRL1, &ctrl1); -+ if (ret) -+ return ret; -+ -+ if (!(ctrl1 & RV3028_CTRL1_EERD)) { -+ ret = regmap_update_bits(priv, RV3028_CTRL1, -+ RV3028_CTRL1_EERD, RV3028_CTRL1_EERD); -+ if (ret) -+ return ret; -+ -+ ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, -+ !(status & RV3028_STATUS_EEBUSY), -+ RV3028_EEBUSY_POLL, -+ RV3028_EEBUSY_TIMEOUT); -+ if (ret) -+ goto restore_eerd; -+ } -+ -+ for (i = 0; i < bytes; i++) { -+ ret = regmap_write(priv, RV3028_EEPROM_ADDR, offset + i); -+ if (ret) -+ goto restore_eerd; -+ -+ ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0); -+ if (ret) -+ goto restore_eerd; -+ -+ ret = regmap_write(priv, RV3028_EEPROM_CMD, -+ RV3028_EEPROM_CMD_READ); -+ if (ret) -+ goto restore_eerd; -+ -+ ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, -+ !(status & RV3028_STATUS_EEBUSY), -+ RV3028_EEBUSY_POLL, -+ RV3028_EEBUSY_TIMEOUT); -+ if (ret) -+ goto restore_eerd; -+ -+ ret = regmap_read(priv, RV3028_EEPROM_DATA, &data); -+ if (ret) -+ goto restore_eerd; -+ buf[i] = data; -+ } -+ -+restore_eerd: -+ if (!(ctrl1 & RV3028_CTRL1_EERD)) -+ { -+ err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD, -+ 0); -+ if (err && !ret) -+ ret = err; -+ } -+ -+ return ret; -+} -+ -+static struct rtc_class_ops rv3028_rtc_ops = { -+ .read_time = rv3028_get_time, -+ .set_time = rv3028_set_time, -+ .read_offset = rv3028_read_offset, -+ .set_offset = rv3028_set_offset, -+ .ioctl = rv3028_ioctl, -+}; -+ -+static const struct regmap_config regmap_config = { -+ .reg_bits = 8, -+ .val_bits = 8, -+ .max_register = 0x37, -+}; -+ -+static int rv3028_probe(struct i2c_client *client) -+{ -+ struct rv3028_data *rv3028; -+ int ret, status; -+ u32 ohms; -+ struct nvmem_config nvmem_cfg = { -+ .name = "rv3028_nvram", -+ .word_size = 1, -+ .stride = 1, -+ .size = 2, -+ .type = NVMEM_TYPE_BATTERY_BACKED, -+ .reg_read = rv3028_nvram_read, -+ .reg_write = rv3028_nvram_write, -+ }; -+ struct nvmem_config eeprom_cfg = { -+ .name = "rv3028_eeprom", -+ .word_size = 1, -+ .stride = 1, -+ .size = 43, -+ .type = NVMEM_TYPE_EEPROM, -+ .reg_read = rv3028_eeprom_read, -+ .reg_write = rv3028_eeprom_write, -+ }; -+ -+ rv3028 = devm_kzalloc(&client->dev, sizeof(struct rv3028_data), -+ GFP_KERNEL); -+ if (!rv3028) -+ return -ENOMEM; -+ -+ rv3028->regmap = devm_regmap_init_i2c(client, ®map_config); -+ -+ i2c_set_clientdata(client, rv3028); -+ -+ ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status); -+ if (ret < 0) -+ return ret; -+ -+ if (status & RV3028_STATUS_PORF) -+ dev_warn(&client->dev, "Voltage low, data loss detected.\n"); -+ -+ if (status & RV3028_STATUS_AF) -+ dev_warn(&client->dev, "An alarm may have been missed.\n"); -+ -+ rv3028->rtc = devm_rtc_allocate_device(&client->dev); -+ if (IS_ERR(rv3028->rtc)) { -+ return PTR_ERR(rv3028->rtc); -+ } -+ -+ if (client->irq > 0) { -+ ret = devm_request_threaded_irq(&client->dev, client->irq, -+ NULL, rv3028_handle_irq, -+ IRQF_TRIGGER_LOW | IRQF_ONESHOT, -+ "rv3028", rv3028); -+ if (ret) { -+ dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); -+ client->irq = 0; -+ } else { -+ rv3028_rtc_ops.read_alarm = rv3028_get_alarm; -+ rv3028_rtc_ops.set_alarm = rv3028_set_alarm; -+ rv3028_rtc_ops.alarm_irq_enable = rv3028_alarm_irq_enable; -+ } -+ } -+ -+ ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL1, -+ RV3028_CTRL1_WADA, RV3028_CTRL1_WADA); -+ if (ret) -+ return ret; -+ -+ /* setup timestamping */ -+ ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2, -+ RV3028_CTRL2_EIE | RV3028_CTRL2_TSE, -+ RV3028_CTRL2_EIE | RV3028_CTRL2_TSE); -+ if (ret) -+ return ret; -+ -+ /* setup trickle charger */ -+ if (!device_property_read_u32(&client->dev, "trickle-resistor-ohms", -+ &ohms)) { -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(rv3028_trickle_resistors); i++) -+ if (ohms == rv3028_trickle_resistors[i]) -+ break; -+ -+ if (i < ARRAY_SIZE(rv3028_trickle_resistors)) { -+ ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP, -+ RV3028_BACKUP_TCE | -+ RV3028_BACKUP_TCR_MASK, -+ RV3028_BACKUP_TCE | i); -+ if (ret) -+ return ret; -+ } else { -+ dev_warn(&client->dev, "invalid trickle resistor value\n"); -+ } -+ } -+ -+ ret = rtc_add_group(rv3028->rtc, &rv3028_attr_group); -+ if (ret) -+ return ret; -+ -+ rv3028->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; -+ rv3028->rtc->range_max = RTC_TIMESTAMP_END_2099; -+ rv3028->rtc->ops = &rv3028_rtc_ops; -+ ret = rtc_register_device(rv3028->rtc); -+ if (ret) -+ return ret; -+ -+ nvmem_cfg.priv = rv3028->regmap; -+ rtc_nvmem_register(rv3028->rtc, &nvmem_cfg); -+ eeprom_cfg.priv = rv3028->regmap; -+ rtc_nvmem_register(rv3028->rtc, &eeprom_cfg); -+ -+ rv3028->rtc->max_user_freq = 1; -+ -+ return 0; -+} -+ -+static const struct of_device_id rv3028_of_match[] = { -+ { .compatible = "microcrystal,rv3028", }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, rv3028_of_match); -+ -+static struct i2c_driver rv3028_driver = { -+ .driver = { -+ .name = "rtc-rv3028", -+ .of_match_table = of_match_ptr(rv3028_of_match), -+ }, -+ .probe_new = rv3028_probe, -+}; -+module_i2c_driver(rv3028_driver); -+ -+MODULE_AUTHOR("Alexandre Belloni "); -+MODULE_DESCRIPTION("Micro Crystal RV3028 RTC driver"); -+MODULE_LICENSE("GPL v2"); diff --git a/target/linux/brcm2708/patches-4.19/950-0400-ASoC-tlv320aic32x4-Break-out-clock-setting-into-sepa.patch b/target/linux/brcm2708/patches-4.19/950-0400-ASoC-tlv320aic32x4-Break-out-clock-setting-into-sepa.patch new file mode 100644 index 0000000000..8061e7e329 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0400-ASoC-tlv320aic32x4-Break-out-clock-setting-into-sepa.patch @@ -0,0 +1,64 @@ +From b1658d7dba649351779a09c99c5db424f6a44ee1 Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Mon, 18 Mar 2019 20:37:44 -0700 +Subject: [PATCH 400/725] ASoC: tlv320aic32x4: Break out clock setting into + separate function + +commit bf31cbfbe25001036e1e096b1c260bf871766ea5 upstream. + +Break the clock setting logic out from the main hw_params. It's +rather large and unweildy and makes for a large function. This +also better enables some of the following changes to the clock +tree access in the driver. + +Signed-off-by: Annaliese McDermond +Signed-off-by: Mark Brown +--- + sound/soc/codecs/tlv320aic32x4.c | 26 ++++++++++++++++++-------- + 1 file changed, 18 insertions(+), 8 deletions(-) + +--- a/sound/soc/codecs/tlv320aic32x4.c ++++ b/sound/soc/codecs/tlv320aic32x4.c +@@ -698,17 +698,13 @@ static int aic32x4_set_dai_fmt(struct sn + return 0; + } + +-static int aic32x4_hw_params(struct snd_pcm_substream *substream, +- struct snd_pcm_hw_params *params, +- struct snd_soc_dai *dai) ++static int aic32x4_setup_clocks(struct snd_soc_component *component, ++ unsigned int sample_rate, ++ unsigned int parent_rate) + { +- struct snd_soc_component *component = dai->component; +- struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component); +- u8 iface1_reg = 0; +- u8 dacsetup_reg = 0; + int i; + +- i = aic32x4_get_divs(aic32x4->sysclk, params_rate(params)); ++ i = aic32x4_get_divs(parent_rate, sample_rate); + if (i < 0) { + printk(KERN_ERR "aic32x4: sampling rate not supported\n"); + return i; +@@ -765,6 +761,20 @@ static int aic32x4_hw_params(struct snd_ + snd_soc_component_update_bits(component, AIC32X4_BCLKN, + AIC32X4_BCLK_MASK, aic32x4_divs[i].blck_N); + ++ return 0; ++} ++ ++static int aic32x4_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_component *component = dai->component; ++ struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component); ++ u8 iface1_reg = 0; ++ u8 dacsetup_reg = 0; ++ ++ aic32x4_setup_clocks(component, params_rate(params), aic32x4->sysclk); ++ + switch (params_width(params)) { + case 16: + iface1_reg |= (AIC32X4_WORD_LEN_16BITS << diff --git a/target/linux/brcm2708/patches-4.19/950-0400-configs-Add-RTC_DRV_RV3028-m.patch b/target/linux/brcm2708/patches-4.19/950-0400-configs-Add-RTC_DRV_RV3028-m.patch deleted file mode 100644 index 04080509a1..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0400-configs-Add-RTC_DRV_RV3028-m.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 709dd35519e82a34da3fdbb9053f3173e7319167 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 28 Mar 2019 13:13:52 +0000 -Subject: [PATCH 400/703] configs: Add RTC_DRV_RV3028=m - -See: https://github.com/raspberrypi/linux/issues/2912 - -Signed-off-by: Phil Elwell ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - arch/arm64/configs/bcmrpi3_defconfig | 1 + - 3 files changed, 3 insertions(+) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1157,6 +1157,7 @@ CONFIG_RTC_DRV_FM3130=m - CONFIG_RTC_DRV_RX8581=m - CONFIG_RTC_DRV_RX8025=m - CONFIG_RTC_DRV_EM3027=m -+CONFIG_RTC_DRV_RV3028=m - CONFIG_RTC_DRV_M41T93=m - CONFIG_RTC_DRV_M41T94=m - CONFIG_RTC_DRV_DS1302=m ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1150,6 +1150,7 @@ CONFIG_RTC_DRV_FM3130=m - CONFIG_RTC_DRV_RX8581=m - CONFIG_RTC_DRV_RX8025=m - CONFIG_RTC_DRV_EM3027=m -+CONFIG_RTC_DRV_RV3028=m - CONFIG_RTC_DRV_M41T93=m - CONFIG_RTC_DRV_M41T94=m - CONFIG_RTC_DRV_DS1302=m ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -1017,6 +1017,7 @@ CONFIG_RTC_DRV_FM3130=m - CONFIG_RTC_DRV_RX8581=m - CONFIG_RTC_DRV_RX8025=m - CONFIG_RTC_DRV_EM3027=m -+CONFIG_RTC_DRV_RV3028=m - CONFIG_RTC_DRV_M41T93=m - CONFIG_RTC_DRV_M41T94=m - CONFIG_RTC_DRV_DS1302=m diff --git a/target/linux/brcm2708/patches-4.19/950-0401-ASoC-tlv320aic32x4-Properly-Set-Processing-Blocks.patch b/target/linux/brcm2708/patches-4.19/950-0401-ASoC-tlv320aic32x4-Properly-Set-Processing-Blocks.patch new file mode 100644 index 0000000000..4527e799f1 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0401-ASoC-tlv320aic32x4-Properly-Set-Processing-Blocks.patch @@ -0,0 +1,111 @@ +From 09a140eacfbdb3d3b02f97ef6f226a00780f12ea Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Wed, 20 Mar 2019 19:38:44 -0700 +Subject: [PATCH 401/725] ASoC: tlv320aic32x4: Properly Set Processing Blocks + +commit c95e3a4b96293403a427b5185e60fad28af51fdd upstream. + +Different processing blocks are required for different sampling +rates and power parameters. Set the processing blocks based +on this information. + +Signed-off-by: Annaliese McDermond +Signed-off-by: Mark Brown +--- + sound/soc/codecs/tlv320aic32x4.c | 56 ++++++++++++++++++++------------ + 1 file changed, 36 insertions(+), 20 deletions(-) + +--- a/sound/soc/codecs/tlv320aic32x4.c ++++ b/sound/soc/codecs/tlv320aic32x4.c +@@ -59,6 +59,8 @@ struct aic32x4_rate_divs { + u8 nadc; + u8 madc; + u8 blck_N; ++ u8 r_block; ++ u8 p_block; + }; + + struct aic32x4_priv { +@@ -307,34 +309,34 @@ static const struct snd_kcontrol_new aic + + static const struct aic32x4_rate_divs aic32x4_divs[] = { + /* 8k rate */ +- {12000000, 8000, 1, 7, 6800, 768, 5, 3, 128, 5, 18, 24}, +- {24000000, 8000, 2, 7, 6800, 768, 15, 1, 64, 45, 4, 24}, +- {25000000, 8000, 2, 7, 3728, 768, 15, 1, 64, 45, 4, 24}, ++ {12000000, 8000, 1, 7, 6800, 768, 5, 3, 128, 5, 18, 24, 1, 1}, ++ {24000000, 8000, 2, 7, 6800, 768, 15, 1, 64, 45, 4, 24, 1, 1}, ++ {25000000, 8000, 2, 7, 3728, 768, 15, 1, 64, 45, 4, 24, 1, 1}, + /* 11.025k rate */ +- {12000000, 11025, 1, 7, 5264, 512, 8, 2, 128, 8, 8, 16}, +- {24000000, 11025, 2, 7, 5264, 512, 16, 1, 64, 32, 4, 16}, ++ {12000000, 11025, 1, 7, 5264, 512, 8, 2, 128, 8, 8, 16, 1, 1}, ++ {24000000, 11025, 2, 7, 5264, 512, 16, 1, 64, 32, 4, 16, 1, 1}, + /* 16k rate */ +- {12000000, 16000, 1, 7, 6800, 384, 5, 3, 128, 5, 9, 12}, +- {24000000, 16000, 2, 7, 6800, 384, 15, 1, 64, 18, 5, 12}, +- {25000000, 16000, 2, 7, 3728, 384, 15, 1, 64, 18, 5, 12}, ++ {12000000, 16000, 1, 7, 6800, 384, 5, 3, 128, 5, 9, 12, 1, 1}, ++ {24000000, 16000, 2, 7, 6800, 384, 15, 1, 64, 18, 5, 12, 1, 1}, ++ {25000000, 16000, 2, 7, 3728, 384, 15, 1, 64, 18, 5, 12, 1, 1}, + /* 22.05k rate */ +- {12000000, 22050, 1, 7, 5264, 256, 4, 4, 128, 4, 8, 8}, +- {24000000, 22050, 2, 7, 5264, 256, 16, 1, 64, 16, 4, 8}, +- {25000000, 22050, 2, 7, 2253, 256, 16, 1, 64, 16, 4, 8}, ++ {12000000, 22050, 1, 7, 5264, 256, 4, 4, 128, 4, 8, 8, 1, 1}, ++ {24000000, 22050, 2, 7, 5264, 256, 16, 1, 64, 16, 4, 8, 1, 1}, ++ {25000000, 22050, 2, 7, 2253, 256, 16, 1, 64, 16, 4, 8, 1, 1}, + /* 32k rate */ +- {12000000, 32000, 1, 7, 1680, 192, 2, 7, 64, 2, 21, 6}, +- {24000000, 32000, 2, 7, 1680, 192, 7, 2, 64, 7, 6, 6}, ++ {12000000, 32000, 1, 7, 1680, 192, 2, 7, 64, 2, 21, 6, 1, 1}, ++ {24000000, 32000, 2, 7, 1680, 192, 7, 2, 64, 7, 6, 6, 1, 1}, + /* 44.1k rate */ +- {12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4}, +- {24000000, 44100, 2, 7, 5264, 128, 8, 2, 64, 8, 4, 4}, +- {25000000, 44100, 2, 7, 2253, 128, 8, 2, 64, 8, 4, 4}, ++ {12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4, 1, 1}, ++ {24000000, 44100, 2, 7, 5264, 128, 8, 2, 64, 8, 4, 4, 1, 1}, ++ {25000000, 44100, 2, 7, 2253, 128, 8, 2, 64, 8, 4, 4, 1, 1}, + /* 48k rate */ +- {12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4}, +- {24000000, 48000, 2, 8, 1920, 128, 8, 2, 64, 8, 4, 4}, +- {25000000, 48000, 2, 7, 8643, 128, 8, 2, 64, 8, 4, 4}, ++ {12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4, 1, 1}, ++ {24000000, 48000, 2, 8, 1920, 128, 8, 2, 64, 8, 4, 4, 1, 1}, ++ {25000000, 48000, 2, 7, 8643, 128, 8, 2, 64, 8, 4, 4, 1, 1}, + + /* 96k rate */ +- {25000000, 96000, 2, 7, 8643, 64, 4, 4, 64, 4, 4, 1}, ++ {25000000, 96000, 2, 7, 8643, 64, 4, 4, 64, 4, 4, 1, 1, 9}, + }; + + static const struct snd_kcontrol_new hpl_output_mixer_controls[] = { +@@ -698,6 +700,18 @@ static int aic32x4_set_dai_fmt(struct sn + return 0; + } + ++static int aic32x4_set_processing_blocks(struct snd_soc_component *component, ++ u8 r_block, u8 p_block) ++{ ++ if (r_block > 18 || p_block > 25) ++ return -EINVAL; ++ ++ snd_soc_component_write(component, AIC32X4_ADCSPB, r_block); ++ snd_soc_component_write(component, AIC32X4_DACSPB, p_block); ++ ++ return 0; ++} ++ + static int aic32x4_setup_clocks(struct snd_soc_component *component, + unsigned int sample_rate, + unsigned int parent_rate) +@@ -710,6 +724,8 @@ static int aic32x4_setup_clocks(struct s + return i; + } + ++ aic32x4_set_processing_blocks(component, aic32x4_divs[i].r_block, aic32x4_divs[i].p_block); ++ + /* MCLK as PLL_CLKIN */ + snd_soc_component_update_bits(component, AIC32X4_CLKMUX, AIC32X4_PLL_CLKIN_MASK, + AIC32X4_PLL_CLKIN_MCLK << AIC32X4_PLL_CLKIN_SHIFT); diff --git a/target/linux/brcm2708/patches-4.19/950-0401-overlays-Add-rv3028-to-i2c-rtc.patch b/target/linux/brcm2708/patches-4.19/950-0401-overlays-Add-rv3028-to-i2c-rtc.patch deleted file mode 100644 index eb06748299..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0401-overlays-Add-rv3028-to-i2c-rtc.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 7eab8a839b1994c2b16c955af4ad805022acccb7 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 28 Mar 2019 13:26:59 +0000 -Subject: [PATCH 401/703] overlays: Add rv3028 to i2c-rtc - -See: https://github.com/raspberrypi/linux/issues/2912 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/README | 4 +++- - .../arm/boot/dts/overlays/i2c-rtc-overlay.dts | 19 ++++++++++++++++++- - 2 files changed, 21 insertions(+), 2 deletions(-) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -939,6 +939,8 @@ Params: abx80x Select o - - pcf8563 Select the PCF8563 device - -+ rv3028 Select the Micro Crystal RV3028 device -+ - addr Sets the address for the RTC. Note that the - device must be configured to use the specified - address. -@@ -947,7 +949,7 @@ Params: abx80x Select o - "schottky" (ABx80x only) - - trickle-resistor-ohms Resistor value for trickle charge (DS1339, -- ABx80x) -+ ABx80x, RV3028) - - wakeup-source Specify that the RTC can be used as a wakeup - source ---- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -@@ -158,6 +158,21 @@ - }; - }; - -+ fragment@10 { -+ target = <&i2c_arm>; -+ __dormant__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ rv3028: rv3028@52 { -+ compatible = "microcrystal,rv3028"; -+ reg = <0x52>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ - __overrides__ { - abx80x = <0>,"+0"; - ds1307 = <0>,"+1"; -@@ -169,6 +184,7 @@ - pcf8523 = <0>,"+7"; - pcf8563 = <0>,"+8"; - m41t62 = <0>,"+9"; -+ rv3028 = <0>,"+10"; - - addr = <&abx80x>, "reg:0", - <&ds1307>, "reg:0", -@@ -182,7 +198,8 @@ - <&m41t62>, "reg:0"; - trickle-diode-type = <&abx80x>,"abracon,tc-diode"; - trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0", -- <&abx80x>,"abracon,tc-resistor"; -+ <&abx80x>,"abracon,tc-resistor", -+ <&rv3028>,"trickle-resistor-ohms:0"; - wakeup-source = <&ds1339>,"wakeup-source?", - <&ds3231>,"wakeup-source?", - <&mcp7940x>,"wakeup-source?", diff --git a/target/linux/brcm2708/patches-4.19/950-0402-ASoC-tlv320aic32x4-Model-PLL-in-CCF.patch b/target/linux/brcm2708/patches-4.19/950-0402-ASoC-tlv320aic32x4-Model-PLL-in-CCF.patch new file mode 100644 index 0000000000..2b84d3c127 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0402-ASoC-tlv320aic32x4-Model-PLL-in-CCF.patch @@ -0,0 +1,877 @@ +From 721de503c943a8c9f0b957e27099c7b2ec38a37a Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Thu, 21 Mar 2019 17:58:45 -0700 +Subject: [PATCH 402/725] ASoC: tlv320aic32x4: Model PLL in CCF + +commit 514b044cba667e4b7c383ec79b42b997e624b91d upstream. + +Model and manage the on-board PLL as a component in the Core +Clock Framework. This should allow us to do some more complex +clock management and power control. Also, some of the +on-board chip clocks can be exposed to the outside, and this +change will make those clocks easier to consume by other +parts of the kernel. + +Signed-off-by: Annaliese McDermond +Signed-off-by: Mark Brown +--- + sound/soc/codecs/Kconfig | 1 + + sound/soc/codecs/Makefile | 2 +- + sound/soc/codecs/tlv320aic32x4-clk.c | 323 +++++++++++++++++++++++++++ + sound/soc/codecs/tlv320aic32x4.c | 195 ++++++++-------- + sound/soc/codecs/tlv320aic32x4.h | 5 + + 5 files changed, 431 insertions(+), 95 deletions(-) + create mode 100644 sound/soc/codecs/tlv320aic32x4-clk.c + +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -1025,6 +1025,7 @@ config SND_SOC_TLV320AIC31XX + + config SND_SOC_TLV320AIC32X4 + tristate ++ depends on COMMON_CLK + + config SND_SOC_TLV320AIC32X4_I2C + tristate "Texas Instruments TLV320AIC32x4 audio CODECs - I2C" +--- a/sound/soc/codecs/Makefile ++++ b/sound/soc/codecs/Makefile +@@ -182,7 +182,7 @@ snd-soc-tlv320aic23-i2c-objs := tlv320ai + snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o + snd-soc-tlv320aic26-objs := tlv320aic26.o + snd-soc-tlv320aic31xx-objs := tlv320aic31xx.o +-snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o ++snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o tlv320aic32x4-clk.o + snd-soc-tlv320aic32x4-i2c-objs := tlv320aic32x4-i2c.o + snd-soc-tlv320aic32x4-spi-objs := tlv320aic32x4-spi.o + snd-soc-tlv320aic3x-objs := tlv320aic3x.o +--- /dev/null ++++ b/sound/soc/codecs/tlv320aic32x4-clk.c +@@ -0,0 +1,323 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Clock Tree for the Texas Instruments TLV320AIC32x4 ++ * ++ * Copyright 2019 Annaliese McDermond ++ * ++ * Author: Annaliese McDermond ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include "tlv320aic32x4.h" ++ ++#define to_clk_aic32x4(_hw) container_of(_hw, struct clk_aic32x4, hw) ++struct clk_aic32x4 { ++ struct clk_hw hw; ++ struct device *dev; ++ struct regmap *regmap; ++ unsigned int reg; ++}; ++ ++/* ++ * struct clk_aic32x4_pll_muldiv - Multiplier/divider settings ++ * @p: Divider ++ * @r: first multiplier ++ * @j: integer part of second multiplier ++ * @d: decimal part of second multiplier ++ */ ++struct clk_aic32x4_pll_muldiv { ++ u8 p; ++ u16 r; ++ u8 j; ++ u16 d; ++}; ++ ++struct aic32x4_clkdesc { ++ const char *name; ++ const char * const *parent_names; ++ unsigned int num_parents; ++ const struct clk_ops *ops; ++ unsigned int reg; ++}; ++ ++static int clk_aic32x4_pll_prepare(struct clk_hw *hw) ++{ ++ struct clk_aic32x4 *pll = to_clk_aic32x4(hw); ++ ++ return regmap_update_bits(pll->regmap, AIC32X4_PLLPR, ++ AIC32X4_PLLEN, AIC32X4_PLLEN); ++} ++ ++static void clk_aic32x4_pll_unprepare(struct clk_hw *hw) ++{ ++ struct clk_aic32x4 *pll = to_clk_aic32x4(hw); ++ ++ regmap_update_bits(pll->regmap, AIC32X4_PLLPR, ++ AIC32X4_PLLEN, 0); ++} ++ ++static int clk_aic32x4_pll_is_prepared(struct clk_hw *hw) ++{ ++ struct clk_aic32x4 *pll = to_clk_aic32x4(hw); ++ ++ unsigned int val; ++ int ret; ++ ++ ret = regmap_read(pll->regmap, AIC32X4_PLLPR, &val); ++ if (ret < 0) ++ return ret; ++ ++ return !!(val & AIC32X4_PLLEN); ++} ++ ++static int clk_aic32x4_pll_get_muldiv(struct clk_aic32x4 *pll, ++ struct clk_aic32x4_pll_muldiv *settings) ++{ ++ /* Change to use regmap_bulk_read? */ ++ unsigned int val; ++ int ret; ++ ++ ret = regmap_read(pll->regmap, AIC32X4_PLLPR, &val); ++ if (ret) ++ return ret; ++ settings->r = val & AIC32X4_PLL_R_MASK; ++ settings->p = (val & AIC32X4_PLL_P_MASK) >> AIC32X4_PLL_P_SHIFT; ++ ++ ret = regmap_read(pll->regmap, AIC32X4_PLLJ, &val); ++ if (ret < 0) ++ return ret; ++ settings->j = val; ++ ++ ret = regmap_read(pll->regmap, AIC32X4_PLLDMSB, &val); ++ if (ret < 0) ++ return ret; ++ settings->d = val << 8; ++ ++ ret = regmap_read(pll->regmap, AIC32X4_PLLDLSB, &val); ++ if (ret < 0) ++ return ret; ++ settings->d |= val; ++ ++ return 0; ++} ++ ++static int clk_aic32x4_pll_set_muldiv(struct clk_aic32x4 *pll, ++ struct clk_aic32x4_pll_muldiv *settings) ++{ ++ int ret; ++ /* Change to use regmap_bulk_write for some if not all? */ ++ ++ ret = regmap_update_bits(pll->regmap, AIC32X4_PLLPR, ++ AIC32X4_PLL_R_MASK, settings->r); ++ if (ret < 0) ++ return ret; ++ ++ ret = regmap_update_bits(pll->regmap, AIC32X4_PLLPR, ++ AIC32X4_PLL_P_MASK, ++ settings->p << AIC32X4_PLL_P_SHIFT); ++ if (ret < 0) ++ return ret; ++ ++ ret = regmap_write(pll->regmap, AIC32X4_PLLJ, settings->j); ++ if (ret < 0) ++ return ret; ++ ++ ret = regmap_write(pll->regmap, AIC32X4_PLLDMSB, (settings->d >> 8)); ++ if (ret < 0) ++ return ret; ++ ret = regmap_write(pll->regmap, AIC32X4_PLLDLSB, (settings->d & 0xff)); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++static unsigned long clk_aic32x4_pll_calc_rate( ++ struct clk_aic32x4_pll_muldiv *settings, ++ unsigned long parent_rate) ++{ ++ u64 rate; ++ /* ++ * We scale j by 10000 to account for the decimal part of P and divide ++ * it back out later. ++ */ ++ rate = (u64) parent_rate * settings->r * ++ ((settings->j * 10000) + settings->d); ++ ++ return (unsigned long) DIV_ROUND_UP_ULL(rate, settings->p * 10000); ++} ++ ++static int clk_aic32x4_pll_calc_muldiv(struct clk_aic32x4_pll_muldiv *settings, ++ unsigned long rate, unsigned long parent_rate) ++{ ++ u64 multiplier; ++ ++ settings->p = parent_rate / AIC32X4_MAX_PLL_CLKIN + 1; ++ if (settings->p > 8) ++ return -1; ++ ++ /* ++ * We scale this figure by 10000 so that we can get the decimal part ++ * of the multiplier. This is because we can't do floating point ++ * math in the kernel. ++ */ ++ multiplier = (u64) rate * settings->p * 10000; ++ do_div(multiplier, parent_rate); ++ ++ /* ++ * J can't be over 64, so R can scale this. ++ * R can't be greater than 4. ++ */ ++ settings->r = ((u32) multiplier / 640000) + 1; ++ if (settings->r > 4) ++ return -1; ++ do_div(multiplier, settings->r); ++ ++ /* ++ * J can't be < 1. ++ */ ++ if (multiplier < 10000) ++ return -1; ++ ++ /* Figure out the integer part, J, and the fractional part, D. */ ++ settings->j = (u32) multiplier / 10000; ++ settings->d = (u32) multiplier % 10000; ++ ++ return 0; ++} ++ ++static unsigned long clk_aic32x4_pll_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct clk_aic32x4 *pll = to_clk_aic32x4(hw); ++ struct clk_aic32x4_pll_muldiv settings; ++ int ret; ++ ++ ret = clk_aic32x4_pll_get_muldiv(pll, &settings); ++ if (ret < 0) ++ return 0; ++ ++ return clk_aic32x4_pll_calc_rate(&settings, parent_rate); ++} ++ ++static long clk_aic32x4_pll_round_rate(struct clk_hw *hw, ++ unsigned long rate, ++ unsigned long *parent_rate) ++{ ++ struct clk_aic32x4_pll_muldiv settings; ++ int ret; ++ ++ ret = clk_aic32x4_pll_calc_muldiv(&settings, rate, *parent_rate); ++ if (ret < 0) ++ return 0; ++ ++ return clk_aic32x4_pll_calc_rate(&settings, *parent_rate); ++} ++ ++static int clk_aic32x4_pll_set_rate(struct clk_hw *hw, ++ unsigned long rate, ++ unsigned long parent_rate) ++{ ++ struct clk_aic32x4 *pll = to_clk_aic32x4(hw); ++ struct clk_aic32x4_pll_muldiv settings; ++ int ret; ++ ++ ret = clk_aic32x4_pll_calc_muldiv(&settings, rate, parent_rate); ++ if (ret < 0) ++ return -EINVAL; ++ ++ return clk_aic32x4_pll_set_muldiv(pll, &settings); ++} ++ ++static int clk_aic32x4_pll_set_parent(struct clk_hw *hw, u8 index) ++{ ++ struct clk_aic32x4 *pll = to_clk_aic32x4(hw); ++ ++ return regmap_update_bits(pll->regmap, ++ AIC32X4_CLKMUX, ++ AIC32X4_PLL_CLKIN_MASK, ++ index << AIC32X4_PLL_CLKIN_SHIFT); ++} ++ ++static u8 clk_aic32x4_pll_get_parent(struct clk_hw *hw) ++{ ++ struct clk_aic32x4 *pll = to_clk_aic32x4(hw); ++ unsigned int val; ++ ++ regmap_read(pll->regmap, AIC32X4_PLLPR, &val); ++ ++ return (val & AIC32X4_PLL_CLKIN_MASK) >> AIC32X4_PLL_CLKIN_SHIFT; ++} ++ ++ ++static const struct clk_ops aic32x4_pll_ops = { ++ .prepare = clk_aic32x4_pll_prepare, ++ .unprepare = clk_aic32x4_pll_unprepare, ++ .is_prepared = clk_aic32x4_pll_is_prepared, ++ .recalc_rate = clk_aic32x4_pll_recalc_rate, ++ .round_rate = clk_aic32x4_pll_round_rate, ++ .set_rate = clk_aic32x4_pll_set_rate, ++ .set_parent = clk_aic32x4_pll_set_parent, ++ .get_parent = clk_aic32x4_pll_get_parent, ++}; ++ ++static struct aic32x4_clkdesc aic32x4_clkdesc_array[] = { ++ { ++ .name = "pll", ++ .parent_names = ++ (const char* []) { "mclk", "bclk", "gpio", "din" }, ++ .num_parents = 4, ++ .ops = &aic32x4_pll_ops, ++ .reg = 0, ++ }, ++}; ++ ++static struct clk *aic32x4_register_clk(struct device *dev, ++ struct aic32x4_clkdesc *desc) ++{ ++ struct clk_init_data init; ++ struct clk_aic32x4 *priv; ++ const char *devname = dev_name(dev); ++ ++ init.ops = desc->ops; ++ init.name = desc->name; ++ init.parent_names = desc->parent_names; ++ init.num_parents = desc->num_parents; ++ init.flags = 0; ++ ++ priv = devm_kzalloc(dev, sizeof(struct clk_aic32x4), GFP_KERNEL); ++ if (priv == NULL) ++ return (struct clk *) -ENOMEM; ++ ++ priv->dev = dev; ++ priv->hw.init = &init; ++ priv->regmap = dev_get_regmap(dev, NULL); ++ priv->reg = desc->reg; ++ ++ clk_hw_register_clkdev(&priv->hw, desc->name, devname); ++ return devm_clk_register(dev, &priv->hw); ++} ++ ++int aic32x4_register_clocks(struct device *dev, const char *mclk_name) ++{ ++ int i; ++ ++ /* ++ * These lines are here to preserve the current functionality of ++ * the driver with regard to the DT. These should eventually be set ++ * by DT nodes so that the connections can be set up in configuration ++ * rather than code. ++ */ ++ aic32x4_clkdesc_array[0].parent_names = ++ (const char* []) { mclk_name, "bclk", "gpio", "din" }; ++ ++ for (i = 0; i < ARRAY_SIZE(aic32x4_clkdesc_array); ++i) ++ aic32x4_register_clk(dev, &aic32x4_clkdesc_array[i]); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(aic32x4_register_clocks); +--- a/sound/soc/codecs/tlv320aic32x4.c ++++ b/sound/soc/codecs/tlv320aic32x4.c +@@ -14,7 +14,7 @@ + * + * 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 ++ * 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 +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -49,9 +50,7 @@ + struct aic32x4_rate_divs { + u32 mclk; + u32 rate; +- u8 p_val; +- u8 pll_j; +- u16 pll_d; ++ unsigned long pll_rate; + u16 dosr; + u8 ndac; + u8 mdac; +@@ -71,6 +70,7 @@ struct aic32x4_priv { + bool swapdacs; + int rstn_gpio; + struct clk *mclk; ++ const char *mclk_name; + + struct regulator *supply_ldo; + struct regulator *supply_iov; +@@ -309,34 +309,34 @@ static const struct snd_kcontrol_new aic + + static const struct aic32x4_rate_divs aic32x4_divs[] = { + /* 8k rate */ +- {12000000, 8000, 1, 7, 6800, 768, 5, 3, 128, 5, 18, 24, 1, 1}, +- {24000000, 8000, 2, 7, 6800, 768, 15, 1, 64, 45, 4, 24, 1, 1}, +- {25000000, 8000, 2, 7, 3728, 768, 15, 1, 64, 45, 4, 24, 1, 1}, ++ { 12000000, 8000, 57120000, 768, 5, 3, 128, 5, 18, 24, 1, 1 }, ++ { 24000000, 8000, 57120000, 768, 15, 1, 64, 45, 4, 24, 1, 1 }, ++ { 25000000, 8000, 32620000, 768, 15, 1, 64, 45, 4, 24, 1, 1 }, + /* 11.025k rate */ +- {12000000, 11025, 1, 7, 5264, 512, 8, 2, 128, 8, 8, 16, 1, 1}, +- {24000000, 11025, 2, 7, 5264, 512, 16, 1, 64, 32, 4, 16, 1, 1}, ++ { 12000000, 11025, 44217600, 512, 8, 2, 128, 8, 8, 16, 1, 1 }, ++ { 24000000, 11025, 44217600, 512, 16, 1, 64, 32, 4, 16, 1, 1 }, + /* 16k rate */ +- {12000000, 16000, 1, 7, 6800, 384, 5, 3, 128, 5, 9, 12, 1, 1}, +- {24000000, 16000, 2, 7, 6800, 384, 15, 1, 64, 18, 5, 12, 1, 1}, +- {25000000, 16000, 2, 7, 3728, 384, 15, 1, 64, 18, 5, 12, 1, 1}, ++ { 12000000, 16000, 57120000, 384, 5, 3, 128, 5, 9, 12, 1, 1 }, ++ { 24000000, 16000, 57120000, 384, 15, 1, 64, 18, 5, 12, 1, 1 }, ++ { 25000000, 16000, 32620000, 384, 15, 1, 64, 18, 5, 12, 1, 1 }, + /* 22.05k rate */ +- {12000000, 22050, 1, 7, 5264, 256, 4, 4, 128, 4, 8, 8, 1, 1}, +- {24000000, 22050, 2, 7, 5264, 256, 16, 1, 64, 16, 4, 8, 1, 1}, +- {25000000, 22050, 2, 7, 2253, 256, 16, 1, 64, 16, 4, 8, 1, 1}, ++ { 12000000, 22050, 44217600, 256, 4, 4, 128, 4, 8, 8, 1, 1 }, ++ { 24000000, 22050, 44217600, 256, 16, 1, 64, 16, 4, 8, 1, 1 }, ++ { 25000000, 22050, 19713750, 256, 16, 1, 64, 16, 4, 8, 1, 1 }, + /* 32k rate */ +- {12000000, 32000, 1, 7, 1680, 192, 2, 7, 64, 2, 21, 6, 1, 1}, +- {24000000, 32000, 2, 7, 1680, 192, 7, 2, 64, 7, 6, 6, 1, 1}, ++ { 12000000, 32000, 14112000, 192, 2, 7, 64, 2, 21, 6, 1, 1 }, ++ { 24000000, 32000, 14112000, 192, 7, 2, 64, 7, 6, 6, 1, 1 }, + /* 44.1k rate */ +- {12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4, 1, 1}, +- {24000000, 44100, 2, 7, 5264, 128, 8, 2, 64, 8, 4, 4, 1, 1}, +- {25000000, 44100, 2, 7, 2253, 128, 8, 2, 64, 8, 4, 4, 1, 1}, ++ { 12000000, 44100, 44217600, 128, 2, 8, 128, 2, 8, 4, 1, 1 }, ++ { 24000000, 44100, 44217600, 128, 8, 2, 64, 8, 4, 4, 1, 1 }, ++ { 25000000, 44100, 19713750, 128, 8, 2, 64, 8, 4, 4, 1, 1 }, + /* 48k rate */ +- {12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4, 1, 1}, +- {24000000, 48000, 2, 8, 1920, 128, 8, 2, 64, 8, 4, 4, 1, 1}, +- {25000000, 48000, 2, 7, 8643, 128, 8, 2, 64, 8, 4, 4, 1, 1}, ++ { 12000000, 48000, 18432000, 128, 2, 8, 128, 2, 8, 4, 1, 1 }, ++ { 24000000, 48000, 18432000, 128, 8, 2, 64, 8, 4, 4, 1, 1 }, ++ { 25000000, 48000, 75626250, 128, 8, 2, 64, 8, 4, 4, 1, 1 }, + + /* 96k rate */ +- {25000000, 96000, 2, 7, 8643, 64, 4, 4, 64, 4, 4, 1, 1, 9}, ++ { 25000000, 96000, 75626250, 64, 4, 4, 64, 4, 4, 1, 1, 9 }, + }; + + static const struct snd_kcontrol_new hpl_output_mixer_controls[] = { +@@ -393,7 +393,7 @@ static const struct snd_kcontrol_new in3 + SOC_DAPM_ENUM("IN3_R L- Switch", in3r_lpga_n_enum), + }; + +-/* Right mixer pins */ ++/* Right mixer pins */ + static SOC_ENUM_SINGLE_DECL(in1r_rpga_p_enum, AIC32X4_RMICPGAPIN, 6, resistor_text); + static SOC_ENUM_SINGLE_DECL(in2r_rpga_p_enum, AIC32X4_RMICPGAPIN, 4, resistor_text); + static SOC_ENUM_SINGLE_DECL(in3r_rpga_p_enum, AIC32X4_RMICPGAPIN, 2, resistor_text); +@@ -597,7 +597,7 @@ static const struct snd_soc_dapm_route a + static const struct regmap_range_cfg aic32x4_regmap_pages[] = { + { + .selector_reg = 0, +- .selector_mask = 0xff, ++ .selector_mask = 0xff, + .window_start = 0, + .window_len = 128, + .range_min = 0, +@@ -618,7 +618,7 @@ static inline int aic32x4_get_divs(int m + + for (i = 0; i < ARRAY_SIZE(aic32x4_divs); i++) { + if ((aic32x4_divs[i].rate == rate) +- && (aic32x4_divs[i].mclk == mclk)) { ++ && (aic32x4_divs[i].mclk == mclk)) { + return i; + } + } +@@ -690,12 +690,12 @@ static int aic32x4_set_dai_fmt(struct sn + } + + snd_soc_component_update_bits(component, AIC32X4_IFACE1, +- AIC32X4_IFACE1_DATATYPE_MASK | +- AIC32X4_IFACE1_MASTER_MASK, iface_reg_1); ++ AIC32X4_IFACE1_DATATYPE_MASK | ++ AIC32X4_IFACE1_MASTER_MASK, iface_reg_1); + snd_soc_component_update_bits(component, AIC32X4_IFACE2, +- AIC32X4_DATA_OFFSET_MASK, iface_reg_2); ++ AIC32X4_DATA_OFFSET_MASK, iface_reg_2); + snd_soc_component_update_bits(component, AIC32X4_IFACE3, +- AIC32X4_BCLKINV_MASK, iface_reg_3); ++ AIC32X4_BCLKINV_MASK, iface_reg_3); + + return 0; + } +@@ -717,6 +717,11 @@ static int aic32x4_setup_clocks(struct s + unsigned int parent_rate) + { + int i; ++ int ret; ++ ++ struct clk_bulk_data clocks[] = { ++ { .id = "pll" }, ++ }; + + i = aic32x4_get_divs(parent_rate, sample_rate); + if (i < 0) { +@@ -724,39 +729,29 @@ static int aic32x4_setup_clocks(struct s + return i; + } + ++ ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks); ++ if (ret) ++ return ret; ++ ++ clk_set_rate(clocks[0].clk, sample_rate); ++ + aic32x4_set_processing_blocks(component, aic32x4_divs[i].r_block, aic32x4_divs[i].p_block); + +- /* MCLK as PLL_CLKIN */ +- snd_soc_component_update_bits(component, AIC32X4_CLKMUX, AIC32X4_PLL_CLKIN_MASK, +- AIC32X4_PLL_CLKIN_MCLK << AIC32X4_PLL_CLKIN_SHIFT); + /* PLL as CODEC_CLKIN */ +- snd_soc_component_update_bits(component, AIC32X4_CLKMUX, AIC32X4_CODEC_CLKIN_MASK, +- AIC32X4_CODEC_CLKIN_PLL << AIC32X4_CODEC_CLKIN_SHIFT); ++ snd_soc_component_update_bits(component, AIC32X4_CLKMUX, ++ AIC32X4_CODEC_CLKIN_MASK, ++ AIC32X4_CODEC_CLKIN_PLL << AIC32X4_CODEC_CLKIN_SHIFT); + /* DAC_MOD_CLK as BDIV_CLKIN */ + snd_soc_component_update_bits(component, AIC32X4_IFACE3, AIC32X4_BDIVCLK_MASK, +- AIC32X4_DACMOD2BCLK << AIC32X4_BDIVCLK_SHIFT); +- +- /* We will fix R value to 1 and will make P & J=K.D as variable */ +- snd_soc_component_update_bits(component, AIC32X4_PLLPR, AIC32X4_PLL_R_MASK, 0x01); +- +- /* PLL P value */ +- snd_soc_component_update_bits(component, AIC32X4_PLLPR, AIC32X4_PLL_P_MASK, +- aic32x4_divs[i].p_val << AIC32X4_PLL_P_SHIFT); +- +- /* PLL J value */ +- snd_soc_component_write(component, AIC32X4_PLLJ, aic32x4_divs[i].pll_j); +- +- /* PLL D value */ +- snd_soc_component_write(component, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8)); +- snd_soc_component_write(component, AIC32X4_PLLDLSB, (aic32x4_divs[i].pll_d & 0xff)); ++ AIC32X4_DACMOD2BCLK << AIC32X4_BDIVCLK_SHIFT); + + /* NDAC divider value */ + snd_soc_component_update_bits(component, AIC32X4_NDAC, +- AIC32X4_NDAC_MASK, aic32x4_divs[i].ndac); ++ AIC32X4_NDAC_MASK, aic32x4_divs[i].ndac); + + /* MDAC divider value */ + snd_soc_component_update_bits(component, AIC32X4_MDAC, +- AIC32X4_MDAC_MASK, aic32x4_divs[i].mdac); ++ AIC32X4_MDAC_MASK, aic32x4_divs[i].mdac); + + /* DOSR MSB & LSB values */ + snd_soc_component_write(component, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8); +@@ -764,18 +759,18 @@ static int aic32x4_setup_clocks(struct s + + /* NADC divider value */ + snd_soc_component_update_bits(component, AIC32X4_NADC, +- AIC32X4_NADC_MASK, aic32x4_divs[i].nadc); ++ AIC32X4_NADC_MASK, aic32x4_divs[i].nadc); + + /* MADC divider value */ + snd_soc_component_update_bits(component, AIC32X4_MADC, +- AIC32X4_MADC_MASK, aic32x4_divs[i].madc); ++ AIC32X4_MADC_MASK, aic32x4_divs[i].madc); + + /* AOSR value */ + snd_soc_component_write(component, AIC32X4_AOSR, aic32x4_divs[i].aosr); + + /* BCLK N divider */ + snd_soc_component_update_bits(component, AIC32X4_BCLKN, +- AIC32X4_BCLK_MASK, aic32x4_divs[i].blck_N); ++ AIC32X4_BCLK_MASK, aic32x4_divs[i].blck_N); + + return 0; + } +@@ -794,23 +789,23 @@ static int aic32x4_hw_params(struct snd_ + switch (params_width(params)) { + case 16: + iface1_reg |= (AIC32X4_WORD_LEN_16BITS << +- AIC32X4_IFACE1_DATALEN_SHIFT); ++ AIC32X4_IFACE1_DATALEN_SHIFT); + break; + case 20: + iface1_reg |= (AIC32X4_WORD_LEN_20BITS << +- AIC32X4_IFACE1_DATALEN_SHIFT); ++ AIC32X4_IFACE1_DATALEN_SHIFT); + break; + case 24: + iface1_reg |= (AIC32X4_WORD_LEN_24BITS << +- AIC32X4_IFACE1_DATALEN_SHIFT); ++ AIC32X4_IFACE1_DATALEN_SHIFT); + break; + case 32: + iface1_reg |= (AIC32X4_WORD_LEN_32BITS << +- AIC32X4_IFACE1_DATALEN_SHIFT); ++ AIC32X4_IFACE1_DATALEN_SHIFT); + break; + } + snd_soc_component_update_bits(component, AIC32X4_IFACE1, +- AIC32X4_IFACE1_DATALEN_MASK, iface1_reg); ++ AIC32X4_IFACE1_DATALEN_MASK, iface1_reg); + + if (params_channels(params) == 1) { + dacsetup_reg = AIC32X4_RDAC2LCHN | AIC32X4_LDAC2LCHN; +@@ -821,7 +816,7 @@ static int aic32x4_hw_params(struct snd_ + dacsetup_reg = AIC32X4_LDAC2LCHN | AIC32X4_RDAC2RCHN; + } + snd_soc_component_update_bits(component, AIC32X4_DACSETUP, +- AIC32X4_DAC_CHAN_MASK, dacsetup_reg); ++ AIC32X4_DAC_CHAN_MASK, dacsetup_reg); + + return 0; + } +@@ -831,7 +826,7 @@ static int aic32x4_mute(struct snd_soc_d + struct snd_soc_component *component = dai->component; + + snd_soc_component_update_bits(component, AIC32X4_DACMUTE, +- AIC32X4_MUTEON, mute ? AIC32X4_MUTEON : 0); ++ AIC32X4_MUTEON, mute ? AIC32X4_MUTEON : 0); + + return 0; + } +@@ -853,27 +848,27 @@ static int aic32x4_set_bias_level(struct + + /* Switch on PLL */ + snd_soc_component_update_bits(component, AIC32X4_PLLPR, +- AIC32X4_PLLEN, AIC32X4_PLLEN); ++ AIC32X4_PLLEN, AIC32X4_PLLEN); + + /* Switch on NDAC Divider */ + snd_soc_component_update_bits(component, AIC32X4_NDAC, +- AIC32X4_NDACEN, AIC32X4_NDACEN); ++ AIC32X4_NDACEN, AIC32X4_NDACEN); + + /* Switch on MDAC Divider */ + snd_soc_component_update_bits(component, AIC32X4_MDAC, +- AIC32X4_MDACEN, AIC32X4_MDACEN); ++ AIC32X4_MDACEN, AIC32X4_MDACEN); + + /* Switch on NADC Divider */ + snd_soc_component_update_bits(component, AIC32X4_NADC, +- AIC32X4_NADCEN, AIC32X4_NADCEN); ++ AIC32X4_NADCEN, AIC32X4_NADCEN); + + /* Switch on MADC Divider */ + snd_soc_component_update_bits(component, AIC32X4_MADC, +- AIC32X4_MADCEN, AIC32X4_MADCEN); ++ AIC32X4_MADCEN, AIC32X4_MADCEN); + + /* Switch on BCLK_N Divider */ + snd_soc_component_update_bits(component, AIC32X4_BCLKN, +- AIC32X4_BCLKEN, AIC32X4_BCLKEN); ++ AIC32X4_BCLKEN, AIC32X4_BCLKEN); + break; + case SND_SOC_BIAS_PREPARE: + break; +@@ -884,27 +879,27 @@ static int aic32x4_set_bias_level(struct + + /* Switch off BCLK_N Divider */ + snd_soc_component_update_bits(component, AIC32X4_BCLKN, +- AIC32X4_BCLKEN, 0); ++ AIC32X4_BCLKEN, 0); + + /* Switch off MADC Divider */ + snd_soc_component_update_bits(component, AIC32X4_MADC, +- AIC32X4_MADCEN, 0); ++ AIC32X4_MADCEN, 0); + + /* Switch off NADC Divider */ + snd_soc_component_update_bits(component, AIC32X4_NADC, +- AIC32X4_NADCEN, 0); ++ AIC32X4_NADCEN, 0); + + /* Switch off MDAC Divider */ + snd_soc_component_update_bits(component, AIC32X4_MDAC, +- AIC32X4_MDACEN, 0); ++ AIC32X4_MDACEN, 0); + + /* Switch off NDAC Divider */ + snd_soc_component_update_bits(component, AIC32X4_NDAC, +- AIC32X4_NDACEN, 0); ++ AIC32X4_NDACEN, 0); + + /* Switch off PLL */ + snd_soc_component_update_bits(component, AIC32X4_PLLPR, +- AIC32X4_PLLEN, 0); ++ AIC32X4_PLLEN, 0); + + /* Switch off master clock */ + clk_disable_unprepare(aic32x4->mclk); +@@ -916,7 +911,7 @@ static int aic32x4_set_bias_level(struct + } + + #define AIC32X4_RATES SNDRV_PCM_RATE_8000_96000 +-#define AIC32X4_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ ++#define AIC32X4_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ + | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) + + static const struct snd_soc_dai_ops aic32x4_ops = { +@@ -929,17 +924,17 @@ static const struct snd_soc_dai_ops aic3 + static struct snd_soc_dai_driver aic32x4_dai = { + .name = "tlv320aic32x4-hifi", + .playback = { +- .stream_name = "Playback", +- .channels_min = 1, +- .channels_max = 2, +- .rates = AIC32X4_RATES, +- .formats = AIC32X4_FORMATS,}, ++ .stream_name = "Playback", ++ .channels_min = 1, ++ .channels_max = 2, ++ .rates = AIC32X4_RATES, ++ .formats = AIC32X4_FORMATS,}, + .capture = { +- .stream_name = "Capture", +- .channels_min = 1, +- .channels_max = 2, +- .rates = AIC32X4_RATES, +- .formats = AIC32X4_FORMATS,}, ++ .stream_name = "Capture", ++ .channels_min = 1, ++ .channels_max = 2, ++ .rates = AIC32X4_RATES, ++ .formats = AIC32X4_FORMATS,}, + .ops = &aic32x4_ops, + .symmetric_rates = 1, + }; +@@ -952,7 +947,7 @@ static void aic32x4_setup_gpios(struct s + /* MFP1 */ + if (aic32x4->setup->gpio_func[0] != AIC32X4_MFPX_DEFAULT_VALUE) { + snd_soc_component_write(component, AIC32X4_DINCTL, +- aic32x4->setup->gpio_func[0]); ++ aic32x4->setup->gpio_func[0]); + snd_soc_add_component_controls(component, aic32x4_mfp1, + ARRAY_SIZE(aic32x4_mfp1)); + } +@@ -960,7 +955,7 @@ static void aic32x4_setup_gpios(struct s + /* MFP2 */ + if (aic32x4->setup->gpio_func[1] != AIC32X4_MFPX_DEFAULT_VALUE) { + snd_soc_component_write(component, AIC32X4_DOUTCTL, +- aic32x4->setup->gpio_func[1]); ++ aic32x4->setup->gpio_func[1]); + snd_soc_add_component_controls(component, aic32x4_mfp2, + ARRAY_SIZE(aic32x4_mfp2)); + } +@@ -968,7 +963,7 @@ static void aic32x4_setup_gpios(struct s + /* MFP3 */ + if (aic32x4->setup->gpio_func[2] != AIC32X4_MFPX_DEFAULT_VALUE) { + snd_soc_component_write(component, AIC32X4_SCLKCTL, +- aic32x4->setup->gpio_func[2]); ++ aic32x4->setup->gpio_func[2]); + snd_soc_add_component_controls(component, aic32x4_mfp3, + ARRAY_SIZE(aic32x4_mfp3)); + } +@@ -976,7 +971,7 @@ static void aic32x4_setup_gpios(struct s + /* MFP4 */ + if (aic32x4->setup->gpio_func[3] != AIC32X4_MFPX_DEFAULT_VALUE) { + snd_soc_component_write(component, AIC32X4_MISOCTL, +- aic32x4->setup->gpio_func[3]); ++ aic32x4->setup->gpio_func[3]); + snd_soc_add_component_controls(component, aic32x4_mfp4, + ARRAY_SIZE(aic32x4_mfp4)); + } +@@ -984,7 +979,7 @@ static void aic32x4_setup_gpios(struct s + /* MFP5 */ + if (aic32x4->setup->gpio_func[4] != AIC32X4_MFPX_DEFAULT_VALUE) { + snd_soc_component_write(component, AIC32X4_GPIOCTL, +- aic32x4->setup->gpio_func[4]); ++ aic32x4->setup->gpio_func[4]); + snd_soc_add_component_controls(component, aic32x4_mfp5, + ARRAY_SIZE(aic32x4_mfp5)); + } +@@ -1007,8 +1002,8 @@ static int aic32x4_component_probe(struc + + /* Power platform configuration */ + if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) { +- snd_soc_component_write(component, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN | +- AIC32X4_MICBIAS_2075V); ++ snd_soc_component_write(component, AIC32X4_MICBIAS, ++ AIC32X4_MICBIAS_LDOIN | AIC32X4_MICBIAS_2075V); + } + if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE) + snd_soc_component_write(component, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE); +@@ -1071,12 +1066,18 @@ static int aic32x4_parse_dt(struct aic32 + struct device_node *np) + { + struct aic32x4_setup_data *aic32x4_setup; ++ int ret; + + aic32x4_setup = devm_kzalloc(aic32x4->dev, sizeof(*aic32x4_setup), + GFP_KERNEL); + if (!aic32x4_setup) + return -ENOMEM; + ++ ret = of_property_match_string(np, "clock-names", "mclk"); ++ if (ret < 0) ++ return -EINVAL; ++ aic32x4->mclk_name = of_clk_get_parent_name(np, ret); ++ + aic32x4->swapdacs = false; + aic32x4->micpga_routing = 0; + aic32x4->rstn_gpio = of_get_named_gpio(np, "reset-gpios", 0); +@@ -1198,7 +1199,7 @@ int aic32x4_probe(struct device *dev, st + return PTR_ERR(regmap); + + aic32x4 = devm_kzalloc(dev, sizeof(struct aic32x4_priv), +- GFP_KERNEL); ++ GFP_KERNEL); + if (aic32x4 == NULL) + return -ENOMEM; + +@@ -1210,6 +1211,7 @@ int aic32x4_probe(struct device *dev, st + aic32x4->swapdacs = pdata->swapdacs; + aic32x4->micpga_routing = pdata->micpga_routing; + aic32x4->rstn_gpio = pdata->rstn_gpio; ++ aic32x4->mclk_name = "mclk"; + } else if (np) { + ret = aic32x4_parse_dt(aic32x4, np); + if (ret) { +@@ -1221,6 +1223,7 @@ int aic32x4_probe(struct device *dev, st + aic32x4->swapdacs = false; + aic32x4->micpga_routing = 0; + aic32x4->rstn_gpio = -1; ++ aic32x4->mclk_name = "mclk"; + } + + aic32x4->mclk = devm_clk_get(dev, "mclk"); +@@ -1229,6 +1232,10 @@ int aic32x4_probe(struct device *dev, st + return PTR_ERR(aic32x4->mclk); + } + ++ ret = aic32x4_register_clocks(dev, aic32x4->mclk_name); ++ if (ret) ++ return ret; ++ + if (gpio_is_valid(aic32x4->rstn_gpio)) { + ret = devm_gpio_request_one(dev, aic32x4->rstn_gpio, + GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn"); +--- a/sound/soc/codecs/tlv320aic32x4.h ++++ b/sound/soc/codecs/tlv320aic32x4.h +@@ -16,6 +16,7 @@ struct regmap_config; + extern const struct regmap_config aic32x4_regmap_config; + int aic32x4_probe(struct device *dev, struct regmap *regmap); + int aic32x4_remove(struct device *dev); ++int aic32x4_register_clocks(struct device *dev, const char *mclk_name); + + /* tlv320aic32x4 register space (in decimal to match datasheet) */ + +@@ -205,4 +206,8 @@ int aic32x4_remove(struct device *dev); + #define AIC32X4_RMICPGANIN_IN1L_10K 0x10 + #define AIC32X4_RMICPGANIN_CM1R_10K 0x40 + ++/* Clock Limits */ ++#define AIC32X4_MAX_PLL_CLKIN 20000000 ++ ++ + #endif /* _TLV320AIC32X4_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0402-ASoC-tlv320aic32x4-SND_SOC_DAPM_MICBIAS-is-deprecate.patch b/target/linux/brcm2708/patches-4.19/950-0402-ASoC-tlv320aic32x4-SND_SOC_DAPM_MICBIAS-is-deprecate.patch deleted file mode 100644 index 4dc424b430..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0402-ASoC-tlv320aic32x4-SND_SOC_DAPM_MICBIAS-is-deprecate.patch +++ /dev/null @@ -1,78 +0,0 @@ -From e4e16b18401abf412c5d1d6435176e609a33c1ed Mon Sep 17 00:00:00 2001 -From: b-ak -Date: Wed, 9 Jan 2019 22:41:21 +0530 -Subject: [PATCH 402/703] ASoC: tlv320aic32x4: SND_SOC_DAPM_MICBIAS is - deprecated - -commit 04d979d7a7bac2f645cd827ea37e5ffa5b4e1f97 upstream. - -SND_SOC_DAPM_MICBIAS is deprecated, replace it with SND_SOC_DAPM_SUPPLY. - -MICBIAS voltage wasn't supplied to the microphone with the older -SND_SOC_DAPM_MICBIAS widget, hence the microphone wouldn't work. - -This patch fixes the problem. - -Signed-off-by: b-ak -Signed-off-by: Mark Brown ---- - sound/soc/codecs/tlv320aic32x4.c | 30 +++++++++++++++++++++++++++++- - sound/soc/codecs/tlv320aic32x4.h | 1 + - 2 files changed, 30 insertions(+), 1 deletion(-) - ---- a/sound/soc/codecs/tlv320aic32x4.c -+++ b/sound/soc/codecs/tlv320aic32x4.c -@@ -79,6 +79,32 @@ struct aic32x4_priv { - struct device *dev; - }; - -+static int mic_bias_event(struct snd_soc_dapm_widget *w, -+ struct snd_kcontrol *kcontrol, int event) -+{ -+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); -+ -+ switch (event) { -+ case SND_SOC_DAPM_POST_PMU: -+ /* Change Mic Bias Registor */ -+ snd_soc_component_update_bits(component, AIC32X4_MICBIAS, -+ AIC32x4_MICBIAS_MASK, -+ AIC32X4_MICBIAS_LDOIN | -+ AIC32X4_MICBIAS_2075V); -+ printk(KERN_DEBUG "%s: Mic Bias will be turned ON\n", __func__); -+ break; -+ case SND_SOC_DAPM_PRE_PMD: -+ snd_soc_component_update_bits(component, AIC32X4_MICBIAS, -+ AIC32x4_MICBIAS_MASK, 0); -+ printk(KERN_DEBUG "%s: Mic Bias will be turned OFF\n", -+ __func__); -+ break; -+ } -+ -+ return 0; -+} -+ -+ - static int aic32x4_get_mfp1_gpio(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { -@@ -450,7 +476,9 @@ static const struct snd_soc_dapm_widget - SND_SOC_DAPM_MUX("IN3_R to Left Mixer Negative Resistor", SND_SOC_NOPM, 0, 0, - in3r_to_lmixer_controls), - -- SND_SOC_DAPM_MICBIAS("Mic Bias", AIC32X4_MICBIAS, 6, 0), -+ SND_SOC_DAPM_SUPPLY("Mic Bias", AIC32X4_MICBIAS, 6, 0, mic_bias_event, -+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), -+ - - SND_SOC_DAPM_OUTPUT("HPL"), - SND_SOC_DAPM_OUTPUT("HPR"), ---- a/sound/soc/codecs/tlv320aic32x4.h -+++ b/sound/soc/codecs/tlv320aic32x4.h -@@ -195,6 +195,7 @@ int aic32x4_remove(struct device *dev); - /* AIC32X4_MICBIAS */ - #define AIC32X4_MICBIAS_LDOIN BIT(3) - #define AIC32X4_MICBIAS_2075V 0x60 -+#define AIC32x4_MICBIAS_MASK GENMASK(6, 3) - - /* AIC32X4_LMICPGANIN */ - #define AIC32X4_LMICPGANIN_IN2R_10K 0x10 diff --git a/target/linux/brcm2708/patches-4.19/950-0403-ASoC-tlv320aic32x4-Break-out-clock-setting-into-sepa.patch b/target/linux/brcm2708/patches-4.19/950-0403-ASoC-tlv320aic32x4-Break-out-clock-setting-into-sepa.patch deleted file mode 100644 index 29135a8f69..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0403-ASoC-tlv320aic32x4-Break-out-clock-setting-into-sepa.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 8ce90120ea5e084d5d9f2b5b1a449edef6099b0b Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Mon, 18 Mar 2019 20:37:44 -0700 -Subject: [PATCH 403/703] ASoC: tlv320aic32x4: Break out clock setting into - separate function - -commit bf31cbfbe25001036e1e096b1c260bf871766ea5 upstream. - -Break the clock setting logic out from the main hw_params. It's -rather large and unweildy and makes for a large function. This -also better enables some of the following changes to the clock -tree access in the driver. - -Signed-off-by: Annaliese McDermond -Signed-off-by: Mark Brown ---- - sound/soc/codecs/tlv320aic32x4.c | 26 ++++++++++++++++++-------- - 1 file changed, 18 insertions(+), 8 deletions(-) - ---- a/sound/soc/codecs/tlv320aic32x4.c -+++ b/sound/soc/codecs/tlv320aic32x4.c -@@ -698,17 +698,13 @@ static int aic32x4_set_dai_fmt(struct sn - return 0; - } - --static int aic32x4_hw_params(struct snd_pcm_substream *substream, -- struct snd_pcm_hw_params *params, -- struct snd_soc_dai *dai) -+static int aic32x4_setup_clocks(struct snd_soc_component *component, -+ unsigned int sample_rate, -+ unsigned int parent_rate) - { -- struct snd_soc_component *component = dai->component; -- struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component); -- u8 iface1_reg = 0; -- u8 dacsetup_reg = 0; - int i; - -- i = aic32x4_get_divs(aic32x4->sysclk, params_rate(params)); -+ i = aic32x4_get_divs(parent_rate, sample_rate); - if (i < 0) { - printk(KERN_ERR "aic32x4: sampling rate not supported\n"); - return i; -@@ -765,6 +761,20 @@ static int aic32x4_hw_params(struct snd_ - snd_soc_component_update_bits(component, AIC32X4_BCLKN, - AIC32X4_BCLK_MASK, aic32x4_divs[i].blck_N); - -+ return 0; -+} -+ -+static int aic32x4_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params, -+ struct snd_soc_dai *dai) -+{ -+ struct snd_soc_component *component = dai->component; -+ struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component); -+ u8 iface1_reg = 0; -+ u8 dacsetup_reg = 0; -+ -+ aic32x4_setup_clocks(component, params_rate(params), aic32x4->sysclk); -+ - switch (params_width(params)) { - case 16: - iface1_reg |= (AIC32X4_WORD_LEN_16BITS << diff --git a/target/linux/brcm2708/patches-4.19/950-0403-ASoC-tlv320aic32x4-Model-CODEC_CLKIN-in-CCF.patch b/target/linux/brcm2708/patches-4.19/950-0403-ASoC-tlv320aic32x4-Model-CODEC_CLKIN-in-CCF.patch new file mode 100644 index 0000000000..d287037dca --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0403-ASoC-tlv320aic32x4-Model-CODEC_CLKIN-in-CCF.patch @@ -0,0 +1,120 @@ +From 7ba72b1d9a6bc4d3db7d38a24c5c23bc3e8184da Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Thu, 21 Mar 2019 17:58:46 -0700 +Subject: [PATCH 403/725] ASoC: tlv320aic32x4: Model CODEC_CLKIN in CCF + +commit fd2df3aeafa4b4cc468d58e147e0822967034b71 upstream. + +Model and manage codec clock input as a component in the Core +Clock Framework. This should allow us to do some more complex +clock management and power control. Also, some of the +on-board chip clocks can be exposed to the outside, and this +change will make those clocks easier to consume by other +parts of the kernel. + +Signed-off-by: Annaliese McDermond +Signed-off-by: Mark Brown +--- + sound/soc/codecs/tlv320aic32x4-clk.c | 34 ++++++++++++++++++++++++++++ + sound/soc/codecs/tlv320aic32x4.c | 18 +++++++++++---- + 2 files changed, 47 insertions(+), 5 deletions(-) + +--- a/sound/soc/codecs/tlv320aic32x4-clk.c ++++ b/sound/soc/codecs/tlv320aic32x4-clk.c +@@ -265,6 +265,30 @@ static const struct clk_ops aic32x4_pll_ + .get_parent = clk_aic32x4_pll_get_parent, + }; + ++static int clk_aic32x4_codec_clkin_set_parent(struct clk_hw *hw, u8 index) ++{ ++ struct clk_aic32x4 *mux = to_clk_aic32x4(hw); ++ ++ return regmap_update_bits(mux->regmap, ++ AIC32X4_CLKMUX, ++ AIC32X4_CODEC_CLKIN_MASK, index << AIC32X4_CODEC_CLKIN_SHIFT); ++} ++ ++static u8 clk_aic32x4_codec_clkin_get_parent(struct clk_hw *hw) ++{ ++ struct clk_aic32x4 *mux = to_clk_aic32x4(hw); ++ unsigned int val; ++ ++ regmap_read(mux->regmap, AIC32X4_CLKMUX, &val); ++ ++ return (val & AIC32X4_CODEC_CLKIN_MASK) >> AIC32X4_CODEC_CLKIN_SHIFT; ++} ++ ++static const struct clk_ops aic32x4_codec_clkin_ops = { ++ .set_parent = clk_aic32x4_codec_clkin_set_parent, ++ .get_parent = clk_aic32x4_codec_clkin_get_parent, ++}; ++ + static struct aic32x4_clkdesc aic32x4_clkdesc_array[] = { + { + .name = "pll", +@@ -274,6 +298,14 @@ static struct aic32x4_clkdesc aic32x4_cl + .ops = &aic32x4_pll_ops, + .reg = 0, + }, ++ { ++ .name = "codec_clkin", ++ .parent_names = ++ (const char *[]) { "mclk", "bclk", "gpio", "pll" }, ++ .num_parents = 4, ++ .ops = &aic32x4_codec_clkin_ops, ++ .reg = 0, ++ }, + }; + + static struct clk *aic32x4_register_clk(struct device *dev, +@@ -314,6 +346,8 @@ int aic32x4_register_clocks(struct devic + */ + aic32x4_clkdesc_array[0].parent_names = + (const char* []) { mclk_name, "bclk", "gpio", "din" }; ++ aic32x4_clkdesc_array[1].parent_names = ++ (const char *[]) { mclk_name, "bclk", "gpio", "pll" }; + + for (i = 0; i < ARRAY_SIZE(aic32x4_clkdesc_array); ++i) + aic32x4_register_clk(dev, &aic32x4_clkdesc_array[i]); +--- a/sound/soc/codecs/tlv320aic32x4.c ++++ b/sound/soc/codecs/tlv320aic32x4.c +@@ -737,12 +737,9 @@ static int aic32x4_setup_clocks(struct s + + aic32x4_set_processing_blocks(component, aic32x4_divs[i].r_block, aic32x4_divs[i].p_block); + +- /* PLL as CODEC_CLKIN */ +- snd_soc_component_update_bits(component, AIC32X4_CLKMUX, +- AIC32X4_CODEC_CLKIN_MASK, +- AIC32X4_CODEC_CLKIN_PLL << AIC32X4_CODEC_CLKIN_SHIFT); + /* DAC_MOD_CLK as BDIV_CLKIN */ +- snd_soc_component_update_bits(component, AIC32X4_IFACE3, AIC32X4_BDIVCLK_MASK, ++ snd_soc_component_update_bits(component, AIC32X4_IFACE3, ++ AIC32X4_BDIVCLK_MASK, + AIC32X4_DACMOD2BCLK << AIC32X4_BDIVCLK_SHIFT); + + /* NDAC divider value */ +@@ -989,6 +986,15 @@ static int aic32x4_component_probe(struc + { + struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component); + u32 tmp_reg; ++ int ret; ++ ++ struct clk_bulk_data clocks[] = { ++ { .id = "codec_clkin" }, ++ }; ++ ++ ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks); ++ if (ret) ++ return ret; + + if (gpio_is_valid(aic32x4->rstn_gpio)) { + ndelay(10); +@@ -1000,6 +1006,8 @@ static int aic32x4_component_probe(struc + if (aic32x4->setup) + aic32x4_setup_gpios(component); + ++ clk_set_parent(clocks[0].clk, clocks[1].clk); ++ + /* Power platform configuration */ + if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) { + snd_soc_component_write(component, AIC32X4_MICBIAS, diff --git a/target/linux/brcm2708/patches-4.19/950-0404-ASoC-tlv320aic32x4-Model-DAC-ADC-dividers-in-CCF.patch b/target/linux/brcm2708/patches-4.19/950-0404-ASoC-tlv320aic32x4-Model-DAC-ADC-dividers-in-CCF.patch new file mode 100644 index 0000000000..bafad882ea --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0404-ASoC-tlv320aic32x4-Model-DAC-ADC-dividers-in-CCF.patch @@ -0,0 +1,306 @@ +From c4c080628e85c7860986c64a7a0b7f56a521fef6 Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Thu, 21 Mar 2019 17:58:47 -0700 +Subject: [PATCH 404/725] ASoC: tlv320aic32x4: Model DAC/ADC dividers in CCF + +commit a51b50062091619915c5155085bbe13a7aca6903 upstream. + +Model and manage DAC/ADC dividers as components in the Core +Clock Framework. This should allow us to do some more complex +clock management and power control. Also, some of the +on-board chip clocks can be exposed to the outside, and this +change will make those clocks easier to consume by other +parts of the kernel. + +Signed-off-by: Annaliese McDermond +Signed-off-by: Mark Brown +--- + sound/soc/codecs/tlv320aic32x4-clk.c | 90 ++++++++++++++++++++++++ + sound/soc/codecs/tlv320aic32x4.c | 101 +++++++++++++++------------ + sound/soc/codecs/tlv320aic32x4.h | 4 ++ + 3 files changed, 151 insertions(+), 44 deletions(-) + +--- a/sound/soc/codecs/tlv320aic32x4-clk.c ++++ b/sound/soc/codecs/tlv320aic32x4-clk.c +@@ -289,6 +289,68 @@ static const struct clk_ops aic32x4_code + .get_parent = clk_aic32x4_codec_clkin_get_parent, + }; + ++static int clk_aic32x4_div_prepare(struct clk_hw *hw) ++{ ++ struct clk_aic32x4 *div = to_clk_aic32x4(hw); ++ ++ return regmap_update_bits(div->regmap, div->reg, ++ AIC32X4_DIVEN, AIC32X4_DIVEN); ++} ++ ++static void clk_aic32x4_div_unprepare(struct clk_hw *hw) ++{ ++ struct clk_aic32x4 *div = to_clk_aic32x4(hw); ++ ++ regmap_update_bits(div->regmap, div->reg, ++ AIC32X4_DIVEN, 0); ++} ++ ++static int clk_aic32x4_div_set_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long parent_rate) ++{ ++ struct clk_aic32x4 *div = to_clk_aic32x4(hw); ++ u8 divisor; ++ ++ divisor = DIV_ROUND_UP(parent_rate, rate); ++ if (divisor > 128) ++ return -EINVAL; ++ ++ return regmap_update_bits(div->regmap, div->reg, ++ AIC32X4_DIV_MASK, divisor); ++} ++ ++static long clk_aic32x4_div_round_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long *parent_rate) ++{ ++ unsigned long divisor; ++ ++ divisor = DIV_ROUND_UP(*parent_rate, rate); ++ if (divisor > 128) ++ return -EINVAL; ++ ++ return DIV_ROUND_UP(*parent_rate, divisor); ++} ++ ++static unsigned long clk_aic32x4_div_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct clk_aic32x4 *div = to_clk_aic32x4(hw); ++ ++ unsigned int val; ++ ++ regmap_read(div->regmap, div->reg, &val); ++ ++ return DIV_ROUND_UP(parent_rate, val & AIC32X4_DIV_MASK); ++} ++ ++static const struct clk_ops aic32x4_div_ops = { ++ .prepare = clk_aic32x4_div_prepare, ++ .unprepare = clk_aic32x4_div_unprepare, ++ .set_rate = clk_aic32x4_div_set_rate, ++ .round_rate = clk_aic32x4_div_round_rate, ++ .recalc_rate = clk_aic32x4_div_recalc_rate, ++}; ++ + static struct aic32x4_clkdesc aic32x4_clkdesc_array[] = { + { + .name = "pll", +@@ -306,6 +368,34 @@ static struct aic32x4_clkdesc aic32x4_cl + .ops = &aic32x4_codec_clkin_ops, + .reg = 0, + }, ++ { ++ .name = "ndac", ++ .parent_names = (const char * []) { "codec_clkin" }, ++ .num_parents = 1, ++ .ops = &aic32x4_div_ops, ++ .reg = AIC32X4_NDAC, ++ }, ++ { ++ .name = "mdac", ++ .parent_names = (const char * []) { "ndac" }, ++ .num_parents = 1, ++ .ops = &aic32x4_div_ops, ++ .reg = AIC32X4_MDAC, ++ }, ++ { ++ .name = "nadc", ++ .parent_names = (const char * []) { "codec_clkin" }, ++ .num_parents = 1, ++ .ops = &aic32x4_div_ops, ++ .reg = AIC32X4_NADC, ++ }, ++ { ++ .name = "madc", ++ .parent_names = (const char * []) { "nadc" }, ++ .num_parents = 1, ++ .ops = &aic32x4_div_ops, ++ .reg = AIC32X4_MADC, ++ }, + }; + + static struct clk *aic32x4_register_clk(struct device *dev, +--- a/sound/soc/codecs/tlv320aic32x4.c ++++ b/sound/soc/codecs/tlv320aic32x4.c +@@ -52,11 +52,11 @@ struct aic32x4_rate_divs { + u32 rate; + unsigned long pll_rate; + u16 dosr; +- u8 ndac; +- u8 mdac; ++ unsigned long ndac_rate; ++ unsigned long mdac_rate; + u8 aosr; +- u8 nadc; +- u8 madc; ++ unsigned long nadc_rate; ++ unsigned long madc_rate; + u8 blck_N; + u8 r_block; + u8 p_block; +@@ -309,34 +309,54 @@ static const struct snd_kcontrol_new aic + + static const struct aic32x4_rate_divs aic32x4_divs[] = { + /* 8k rate */ +- { 12000000, 8000, 57120000, 768, 5, 3, 128, 5, 18, 24, 1, 1 }, +- { 24000000, 8000, 57120000, 768, 15, 1, 64, 45, 4, 24, 1, 1 }, +- { 25000000, 8000, 32620000, 768, 15, 1, 64, 45, 4, 24, 1, 1 }, ++ { 12000000, 8000, 57120000, 768, 18432000, 6144000, 128, 18432000, ++ 1024000, 24, 1, 1 }, ++ { 24000000, 8000, 57120000, 768, 6144000, 6144000, 64, 2048000, ++ 512000, 24, 1, 1 }, ++ { 25000000, 8000, 32620000, 768, 6144000, 6144000, 64, 2048000, ++ 512000, 24, 1, 1 }, + /* 11.025k rate */ +- { 12000000, 11025, 44217600, 512, 8, 2, 128, 8, 8, 16, 1, 1 }, +- { 24000000, 11025, 44217600, 512, 16, 1, 64, 32, 4, 16, 1, 1 }, ++ { 12000000, 11025, 44217600, 512, 11289600, 5644800, 128, 11289600, ++ 1411200, 16, 1, 1 }, ++ { 24000000, 11025, 44217600, 512, 5644800, 5644800, 64, 2822400, ++ 705600, 16, 1, 1 }, + /* 16k rate */ +- { 12000000, 16000, 57120000, 384, 5, 3, 128, 5, 9, 12, 1, 1 }, +- { 24000000, 16000, 57120000, 384, 15, 1, 64, 18, 5, 12, 1, 1 }, +- { 25000000, 16000, 32620000, 384, 15, 1, 64, 18, 5, 12, 1, 1 }, ++ { 12000000, 16000, 57120000, 384, 18432000, 6144000, 128, 18432000, ++ 2048000, 12, 1, 1 }, ++ { 24000000, 16000, 57120000, 384, 6144000, 6144000, 64, 5120000, ++ 1024000, 12, 1, 1 }, ++ { 25000000, 16000, 32620000, 384, 6144000, 6144000, 64, 5120000, ++ 1024000, 12, 1, 1 }, + /* 22.05k rate */ +- { 12000000, 22050, 44217600, 256, 4, 4, 128, 4, 8, 8, 1, 1 }, +- { 24000000, 22050, 44217600, 256, 16, 1, 64, 16, 4, 8, 1, 1 }, +- { 25000000, 22050, 19713750, 256, 16, 1, 64, 16, 4, 8, 1, 1 }, ++ { 12000000, 22050, 44217600, 256, 22579200, 5644800, 128, 22579200, ++ 2822400, 8, 1, 1 }, ++ { 24000000, 22050, 44217600, 256, 5644800, 5644800, 64, 5644800, ++ 1411200, 8, 1, 1 }, ++ { 25000000, 22050, 19713750, 256, 5644800, 5644800, 64, 5644800, ++ 1411200, 8, 1, 1 }, + /* 32k rate */ +- { 12000000, 32000, 14112000, 192, 2, 7, 64, 2, 21, 6, 1, 1 }, +- { 24000000, 32000, 14112000, 192, 7, 2, 64, 7, 6, 6, 1, 1 }, ++ { 12000000, 32000, 14112000, 192, 43008000, 6144000, 64, 43008000, ++ 2048000, 6, 1, 1 }, ++ { 24000000, 32000, 14112000, 192, 12288000, 6144000, 64, 12288000, ++ 2048000, 6, 1, 1 }, + /* 44.1k rate */ +- { 12000000, 44100, 44217600, 128, 2, 8, 128, 2, 8, 4, 1, 1 }, +- { 24000000, 44100, 44217600, 128, 8, 2, 64, 8, 4, 4, 1, 1 }, +- { 25000000, 44100, 19713750, 128, 8, 2, 64, 8, 4, 4, 1, 1 }, ++ { 12000000, 44100, 44217600, 128, 45158400, 5644800, 128, 45158400, ++ 5644800, 4, 1, 1 }, ++ { 24000000, 44100, 44217600, 128, 11289600, 5644800, 64, 11289600, ++ 2822400, 4, 1, 1 }, ++ { 25000000, 44100, 19713750, 128, 11289600, 5644800, 64, 11289600, ++ 2822400, 4, 1, 1 }, + /* 48k rate */ +- { 12000000, 48000, 18432000, 128, 2, 8, 128, 2, 8, 4, 1, 1 }, +- { 24000000, 48000, 18432000, 128, 8, 2, 64, 8, 4, 4, 1, 1 }, +- { 25000000, 48000, 75626250, 128, 8, 2, 64, 8, 4, 4, 1, 1 }, ++ { 12000000, 48000, 18432000, 128, 49152000, 6144000, 128, 49152000, ++ 6144000, 4, 1, 1 }, ++ { 24000000, 48000, 18432000, 128, 12288000, 6144000, 64, 12288000, ++ 3072000, 4, 1, 1 }, ++ { 25000000, 48000, 75626250, 128, 12288000, 6144000, 64, 12288000, ++ 3072000, 4, 1, 1 }, + + /* 96k rate */ +- { 25000000, 96000, 75626250, 64, 4, 4, 64, 4, 4, 1, 1, 9 }, ++ { 25000000, 96000, 75626250, 64, 24576000, 6144000, 64, 24576000, ++ 6144000, 1, 1, 9 }, + }; + + static const struct snd_kcontrol_new hpl_output_mixer_controls[] = { +@@ -721,6 +741,10 @@ static int aic32x4_setup_clocks(struct s + + struct clk_bulk_data clocks[] = { + { .id = "pll" }, ++ { .id = "nadc" }, ++ { .id = "madc" }, ++ { .id = "ndac" }, ++ { .id = "mdac" }, + }; + + i = aic32x4_get_divs(parent_rate, sample_rate); +@@ -733,7 +757,11 @@ static int aic32x4_setup_clocks(struct s + if (ret) + return ret; + +- clk_set_rate(clocks[0].clk, sample_rate); ++ clk_set_rate(clocks[0].clk, aic32x4_divs[i].pll_rate); ++ clk_set_rate(clocks[1].clk, aic32x4_divs[i].nadc_rate); ++ clk_set_rate(clocks[2].clk, aic32x4_divs[i].madc_rate); ++ clk_set_rate(clocks[3].clk, aic32x4_divs[i].ndac_rate); ++ clk_set_rate(clocks[4].clk, aic32x4_divs[i].mdac_rate); + + aic32x4_set_processing_blocks(component, aic32x4_divs[i].r_block, aic32x4_divs[i].p_block); + +@@ -742,26 +770,10 @@ static int aic32x4_setup_clocks(struct s + AIC32X4_BDIVCLK_MASK, + AIC32X4_DACMOD2BCLK << AIC32X4_BDIVCLK_SHIFT); + +- /* NDAC divider value */ +- snd_soc_component_update_bits(component, AIC32X4_NDAC, +- AIC32X4_NDAC_MASK, aic32x4_divs[i].ndac); +- +- /* MDAC divider value */ +- snd_soc_component_update_bits(component, AIC32X4_MDAC, +- AIC32X4_MDAC_MASK, aic32x4_divs[i].mdac); +- + /* DOSR MSB & LSB values */ + snd_soc_component_write(component, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8); + snd_soc_component_write(component, AIC32X4_DOSRLSB, (aic32x4_divs[i].dosr & 0xff)); + +- /* NADC divider value */ +- snd_soc_component_update_bits(component, AIC32X4_NADC, +- AIC32X4_NADC_MASK, aic32x4_divs[i].nadc); +- +- /* MADC divider value */ +- snd_soc_component_update_bits(component, AIC32X4_MADC, +- AIC32X4_MADC_MASK, aic32x4_divs[i].madc); +- + /* AOSR value */ + snd_soc_component_write(component, AIC32X4_AOSR, aic32x4_divs[i].aosr); + +@@ -773,8 +785,8 @@ static int aic32x4_setup_clocks(struct s + } + + static int aic32x4_hw_params(struct snd_pcm_substream *substream, +- struct snd_pcm_hw_params *params, +- struct snd_soc_dai *dai) ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) + { + struct snd_soc_component *component = dai->component; + struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component); +@@ -989,7 +1001,8 @@ static int aic32x4_component_probe(struc + int ret; + + struct clk_bulk_data clocks[] = { +- { .id = "codec_clkin" }, ++ { .id = "codec_clkin" }, ++ { .id = "pll" }, + }; + + ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks); +--- a/sound/soc/codecs/tlv320aic32x4.h ++++ b/sound/soc/codecs/tlv320aic32x4.h +@@ -206,6 +206,10 @@ int aic32x4_register_clocks(struct devic + #define AIC32X4_RMICPGANIN_IN1L_10K 0x10 + #define AIC32X4_RMICPGANIN_CM1R_10K 0x40 + ++/* Common mask and enable for all of the dividers */ ++#define AIC32X4_DIVEN BIT(7) ++#define AIC32X4_DIV_MASK GENMASK(6, 0) ++ + /* Clock Limits */ + #define AIC32X4_MAX_PLL_CLKIN 20000000 + diff --git a/target/linux/brcm2708/patches-4.19/950-0404-ASoC-tlv320aic32x4-Properly-Set-Processing-Blocks.patch b/target/linux/brcm2708/patches-4.19/950-0404-ASoC-tlv320aic32x4-Properly-Set-Processing-Blocks.patch deleted file mode 100644 index 41675f7a53..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0404-ASoC-tlv320aic32x4-Properly-Set-Processing-Blocks.patch +++ /dev/null @@ -1,111 +0,0 @@ -From d41102524cf14a1098a735add06aa4d67c631130 Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Wed, 20 Mar 2019 19:38:44 -0700 -Subject: [PATCH 404/703] ASoC: tlv320aic32x4: Properly Set Processing Blocks - -commit c95e3a4b96293403a427b5185e60fad28af51fdd upstream. - -Different processing blocks are required for different sampling -rates and power parameters. Set the processing blocks based -on this information. - -Signed-off-by: Annaliese McDermond -Signed-off-by: Mark Brown ---- - sound/soc/codecs/tlv320aic32x4.c | 56 ++++++++++++++++++++------------ - 1 file changed, 36 insertions(+), 20 deletions(-) - ---- a/sound/soc/codecs/tlv320aic32x4.c -+++ b/sound/soc/codecs/tlv320aic32x4.c -@@ -59,6 +59,8 @@ struct aic32x4_rate_divs { - u8 nadc; - u8 madc; - u8 blck_N; -+ u8 r_block; -+ u8 p_block; - }; - - struct aic32x4_priv { -@@ -307,34 +309,34 @@ static const struct snd_kcontrol_new aic - - static const struct aic32x4_rate_divs aic32x4_divs[] = { - /* 8k rate */ -- {12000000, 8000, 1, 7, 6800, 768, 5, 3, 128, 5, 18, 24}, -- {24000000, 8000, 2, 7, 6800, 768, 15, 1, 64, 45, 4, 24}, -- {25000000, 8000, 2, 7, 3728, 768, 15, 1, 64, 45, 4, 24}, -+ {12000000, 8000, 1, 7, 6800, 768, 5, 3, 128, 5, 18, 24, 1, 1}, -+ {24000000, 8000, 2, 7, 6800, 768, 15, 1, 64, 45, 4, 24, 1, 1}, -+ {25000000, 8000, 2, 7, 3728, 768, 15, 1, 64, 45, 4, 24, 1, 1}, - /* 11.025k rate */ -- {12000000, 11025, 1, 7, 5264, 512, 8, 2, 128, 8, 8, 16}, -- {24000000, 11025, 2, 7, 5264, 512, 16, 1, 64, 32, 4, 16}, -+ {12000000, 11025, 1, 7, 5264, 512, 8, 2, 128, 8, 8, 16, 1, 1}, -+ {24000000, 11025, 2, 7, 5264, 512, 16, 1, 64, 32, 4, 16, 1, 1}, - /* 16k rate */ -- {12000000, 16000, 1, 7, 6800, 384, 5, 3, 128, 5, 9, 12}, -- {24000000, 16000, 2, 7, 6800, 384, 15, 1, 64, 18, 5, 12}, -- {25000000, 16000, 2, 7, 3728, 384, 15, 1, 64, 18, 5, 12}, -+ {12000000, 16000, 1, 7, 6800, 384, 5, 3, 128, 5, 9, 12, 1, 1}, -+ {24000000, 16000, 2, 7, 6800, 384, 15, 1, 64, 18, 5, 12, 1, 1}, -+ {25000000, 16000, 2, 7, 3728, 384, 15, 1, 64, 18, 5, 12, 1, 1}, - /* 22.05k rate */ -- {12000000, 22050, 1, 7, 5264, 256, 4, 4, 128, 4, 8, 8}, -- {24000000, 22050, 2, 7, 5264, 256, 16, 1, 64, 16, 4, 8}, -- {25000000, 22050, 2, 7, 2253, 256, 16, 1, 64, 16, 4, 8}, -+ {12000000, 22050, 1, 7, 5264, 256, 4, 4, 128, 4, 8, 8, 1, 1}, -+ {24000000, 22050, 2, 7, 5264, 256, 16, 1, 64, 16, 4, 8, 1, 1}, -+ {25000000, 22050, 2, 7, 2253, 256, 16, 1, 64, 16, 4, 8, 1, 1}, - /* 32k rate */ -- {12000000, 32000, 1, 7, 1680, 192, 2, 7, 64, 2, 21, 6}, -- {24000000, 32000, 2, 7, 1680, 192, 7, 2, 64, 7, 6, 6}, -+ {12000000, 32000, 1, 7, 1680, 192, 2, 7, 64, 2, 21, 6, 1, 1}, -+ {24000000, 32000, 2, 7, 1680, 192, 7, 2, 64, 7, 6, 6, 1, 1}, - /* 44.1k rate */ -- {12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4}, -- {24000000, 44100, 2, 7, 5264, 128, 8, 2, 64, 8, 4, 4}, -- {25000000, 44100, 2, 7, 2253, 128, 8, 2, 64, 8, 4, 4}, -+ {12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4, 1, 1}, -+ {24000000, 44100, 2, 7, 5264, 128, 8, 2, 64, 8, 4, 4, 1, 1}, -+ {25000000, 44100, 2, 7, 2253, 128, 8, 2, 64, 8, 4, 4, 1, 1}, - /* 48k rate */ -- {12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4}, -- {24000000, 48000, 2, 8, 1920, 128, 8, 2, 64, 8, 4, 4}, -- {25000000, 48000, 2, 7, 8643, 128, 8, 2, 64, 8, 4, 4}, -+ {12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4, 1, 1}, -+ {24000000, 48000, 2, 8, 1920, 128, 8, 2, 64, 8, 4, 4, 1, 1}, -+ {25000000, 48000, 2, 7, 8643, 128, 8, 2, 64, 8, 4, 4, 1, 1}, - - /* 96k rate */ -- {25000000, 96000, 2, 7, 8643, 64, 4, 4, 64, 4, 4, 1}, -+ {25000000, 96000, 2, 7, 8643, 64, 4, 4, 64, 4, 4, 1, 1, 9}, - }; - - static const struct snd_kcontrol_new hpl_output_mixer_controls[] = { -@@ -698,6 +700,18 @@ static int aic32x4_set_dai_fmt(struct sn - return 0; - } - -+static int aic32x4_set_processing_blocks(struct snd_soc_component *component, -+ u8 r_block, u8 p_block) -+{ -+ if (r_block > 18 || p_block > 25) -+ return -EINVAL; -+ -+ snd_soc_component_write(component, AIC32X4_ADCSPB, r_block); -+ snd_soc_component_write(component, AIC32X4_DACSPB, p_block); -+ -+ return 0; -+} -+ - static int aic32x4_setup_clocks(struct snd_soc_component *component, - unsigned int sample_rate, - unsigned int parent_rate) -@@ -710,6 +724,8 @@ static int aic32x4_setup_clocks(struct s - return i; - } - -+ aic32x4_set_processing_blocks(component, aic32x4_divs[i].r_block, aic32x4_divs[i].p_block); -+ - /* MCLK as PLL_CLKIN */ - snd_soc_component_update_bits(component, AIC32X4_CLKMUX, AIC32X4_PLL_CLKIN_MASK, - AIC32X4_PLL_CLKIN_MCLK << AIC32X4_PLL_CLKIN_SHIFT); diff --git a/target/linux/brcm2708/patches-4.19/950-0405-ASoC-tlv320aic32x4-Model-BDIV-divider-in-CCF.patch b/target/linux/brcm2708/patches-4.19/950-0405-ASoC-tlv320aic32x4-Model-BDIV-divider-in-CCF.patch new file mode 100644 index 0000000000..8fd48d06f6 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0405-ASoC-tlv320aic32x4-Model-BDIV-divider-in-CCF.patch @@ -0,0 +1,210 @@ +From 0ce031ad1a56ab6201bf6fbe7e14bc1e0979e8c3 Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Thu, 21 Mar 2019 17:58:48 -0700 +Subject: [PATCH 405/725] ASoC: tlv320aic32x4: Model BDIV divider in CCF + +commit 9b484124ebd906c4d6bc826cc0d417e80cc1105c upstream. + +Model and manage BDIV divider as components in the Core +Clock Framework. This should allow us to do some more complex +clock management and power control. Also, some of the +on-board chip clocks can be exposed to the outside, and this +change will make those clocks easier to consume by other +parts of the kernel. + +Signed-off-by: Annaliese McDermond +Signed-off-by: Mark Brown +--- + sound/soc/codecs/tlv320aic32x4-clk.c | 36 ++++++++++++++++++ + sound/soc/codecs/tlv320aic32x4.c | 56 +++++++++++++--------------- + 2 files changed, 62 insertions(+), 30 deletions(-) + +--- a/sound/soc/codecs/tlv320aic32x4-clk.c ++++ b/sound/soc/codecs/tlv320aic32x4-clk.c +@@ -351,6 +351,34 @@ static const struct clk_ops aic32x4_div_ + .recalc_rate = clk_aic32x4_div_recalc_rate, + }; + ++static int clk_aic32x4_bdiv_set_parent(struct clk_hw *hw, u8 index) ++{ ++ struct clk_aic32x4 *mux = to_clk_aic32x4(hw); ++ ++ return regmap_update_bits(mux->regmap, AIC32X4_IFACE3, ++ AIC32X4_BDIVCLK_MASK, index); ++} ++ ++static u8 clk_aic32x4_bdiv_get_parent(struct clk_hw *hw) ++{ ++ struct clk_aic32x4 *mux = to_clk_aic32x4(hw); ++ unsigned int val; ++ ++ regmap_read(mux->regmap, AIC32X4_IFACE3, &val); ++ ++ return val & AIC32X4_BDIVCLK_MASK; ++} ++ ++static const struct clk_ops aic32x4_bdiv_ops = { ++ .prepare = clk_aic32x4_div_prepare, ++ .unprepare = clk_aic32x4_div_unprepare, ++ .set_parent = clk_aic32x4_bdiv_set_parent, ++ .get_parent = clk_aic32x4_bdiv_get_parent, ++ .set_rate = clk_aic32x4_div_set_rate, ++ .round_rate = clk_aic32x4_div_round_rate, ++ .recalc_rate = clk_aic32x4_div_recalc_rate, ++}; ++ + static struct aic32x4_clkdesc aic32x4_clkdesc_array[] = { + { + .name = "pll", +@@ -396,6 +424,14 @@ static struct aic32x4_clkdesc aic32x4_cl + .ops = &aic32x4_div_ops, + .reg = AIC32X4_MADC, + }, ++ { ++ .name = "bdiv", ++ .parent_names = ++ (const char *[]) { "ndac", "mdac", "nadc", "madc" }, ++ .num_parents = 4, ++ .ops = &aic32x4_bdiv_ops, ++ .reg = AIC32X4_BCLKN, ++ }, + }; + + static struct clk *aic32x4_register_clk(struct device *dev, +--- a/sound/soc/codecs/tlv320aic32x4.c ++++ b/sound/soc/codecs/tlv320aic32x4.c +@@ -57,7 +57,7 @@ struct aic32x4_rate_divs { + u8 aosr; + unsigned long nadc_rate; + unsigned long madc_rate; +- u8 blck_N; ++ unsigned long bdiv_rate; + u8 r_block; + u8 p_block; + }; +@@ -310,53 +310,53 @@ static const struct snd_kcontrol_new aic + static const struct aic32x4_rate_divs aic32x4_divs[] = { + /* 8k rate */ + { 12000000, 8000, 57120000, 768, 18432000, 6144000, 128, 18432000, +- 1024000, 24, 1, 1 }, ++ 1024000, 256000, 1, 1 }, + { 24000000, 8000, 57120000, 768, 6144000, 6144000, 64, 2048000, +- 512000, 24, 1, 1 }, ++ 512000, 256000, 1, 1 }, + { 25000000, 8000, 32620000, 768, 6144000, 6144000, 64, 2048000, +- 512000, 24, 1, 1 }, ++ 512000, 256000, 1, 1 }, + /* 11.025k rate */ + { 12000000, 11025, 44217600, 512, 11289600, 5644800, 128, 11289600, +- 1411200, 16, 1, 1 }, ++ 1411200, 352800, 1, 1 }, + { 24000000, 11025, 44217600, 512, 5644800, 5644800, 64, 2822400, +- 705600, 16, 1, 1 }, ++ 705600, 352800, 1, 1 }, + /* 16k rate */ + { 12000000, 16000, 57120000, 384, 18432000, 6144000, 128, 18432000, +- 2048000, 12, 1, 1 }, ++ 2048000, 512000, 1, 1 }, + { 24000000, 16000, 57120000, 384, 6144000, 6144000, 64, 5120000, +- 1024000, 12, 1, 1 }, ++ 1024000, 512000, 1, 1 }, + { 25000000, 16000, 32620000, 384, 6144000, 6144000, 64, 5120000, +- 1024000, 12, 1, 1 }, ++ 1024000, 512000, 1, 1 }, + /* 22.05k rate */ + { 12000000, 22050, 44217600, 256, 22579200, 5644800, 128, 22579200, +- 2822400, 8, 1, 1 }, ++ 2822400, 705600, 1, 1 }, + { 24000000, 22050, 44217600, 256, 5644800, 5644800, 64, 5644800, +- 1411200, 8, 1, 1 }, ++ 1411200, 705600, 1, 1 }, + { 25000000, 22050, 19713750, 256, 5644800, 5644800, 64, 5644800, +- 1411200, 8, 1, 1 }, ++ 1411200, 705600, 1, 1 }, + /* 32k rate */ + { 12000000, 32000, 14112000, 192, 43008000, 6144000, 64, 43008000, +- 2048000, 6, 1, 1 }, ++ 2048000, 1024000, 1, 1 }, + { 24000000, 32000, 14112000, 192, 12288000, 6144000, 64, 12288000, +- 2048000, 6, 1, 1 }, ++ 2048000, 1024000, 1, 1 }, + /* 44.1k rate */ + { 12000000, 44100, 44217600, 128, 45158400, 5644800, 128, 45158400, +- 5644800, 4, 1, 1 }, ++ 5644800, 1411200, 1, 1 }, + { 24000000, 44100, 44217600, 128, 11289600, 5644800, 64, 11289600, +- 2822400, 4, 1, 1 }, ++ 2822400, 1411200, 1, 1 }, + { 25000000, 44100, 19713750, 128, 11289600, 5644800, 64, 11289600, +- 2822400, 4, 1, 1 }, ++ 2822400, 1411200, 1, 1 }, + /* 48k rate */ + { 12000000, 48000, 18432000, 128, 49152000, 6144000, 128, 49152000, +- 6144000, 4, 1, 1 }, ++ 6144000, 1536000, 1, 1 }, + { 24000000, 48000, 18432000, 128, 12288000, 6144000, 64, 12288000, +- 3072000, 4, 1, 1 }, ++ 3072000, 1536000, 1, 1 }, + { 25000000, 48000, 75626250, 128, 12288000, 6144000, 64, 12288000, +- 3072000, 4, 1, 1 }, ++ 3072000, 1536000, 1, 1 }, + + /* 96k rate */ + { 25000000, 96000, 75626250, 64, 24576000, 6144000, 64, 24576000, +- 6144000, 1, 1, 9 }, ++ 6144000, 3072000, 1, 9 }, + }; + + static const struct snd_kcontrol_new hpl_output_mixer_controls[] = { +@@ -745,6 +745,7 @@ static int aic32x4_setup_clocks(struct s + { .id = "madc" }, + { .id = "ndac" }, + { .id = "mdac" }, ++ { .id = "bdiv" }, + }; + + i = aic32x4_get_divs(parent_rate, sample_rate); +@@ -762,14 +763,10 @@ static int aic32x4_setup_clocks(struct s + clk_set_rate(clocks[2].clk, aic32x4_divs[i].madc_rate); + clk_set_rate(clocks[3].clk, aic32x4_divs[i].ndac_rate); + clk_set_rate(clocks[4].clk, aic32x4_divs[i].mdac_rate); ++ clk_set_rate(clocks[5].clk, aic32x4_divs[i].bdiv_rate); + + aic32x4_set_processing_blocks(component, aic32x4_divs[i].r_block, aic32x4_divs[i].p_block); + +- /* DAC_MOD_CLK as BDIV_CLKIN */ +- snd_soc_component_update_bits(component, AIC32X4_IFACE3, +- AIC32X4_BDIVCLK_MASK, +- AIC32X4_DACMOD2BCLK << AIC32X4_BDIVCLK_SHIFT); +- + /* DOSR MSB & LSB values */ + snd_soc_component_write(component, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8); + snd_soc_component_write(component, AIC32X4_DOSRLSB, (aic32x4_divs[i].dosr & 0xff)); +@@ -777,10 +774,6 @@ static int aic32x4_setup_clocks(struct s + /* AOSR value */ + snd_soc_component_write(component, AIC32X4_AOSR, aic32x4_divs[i].aosr); + +- /* BCLK N divider */ +- snd_soc_component_update_bits(component, AIC32X4_BCLKN, +- AIC32X4_BCLK_MASK, aic32x4_divs[i].blck_N); +- + return 0; + } + +@@ -1003,6 +996,8 @@ static int aic32x4_component_probe(struc + struct clk_bulk_data clocks[] = { + { .id = "codec_clkin" }, + { .id = "pll" }, ++ { .id = "bdiv" }, ++ { .id = "mdac" }, + }; + + ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks); +@@ -1020,6 +1015,7 @@ static int aic32x4_component_probe(struc + aic32x4_setup_gpios(component); + + clk_set_parent(clocks[0].clk, clocks[1].clk); ++ clk_set_parent(clocks[2].clk, clocks[3].clk); + + /* Power platform configuration */ + if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) { diff --git a/target/linux/brcm2708/patches-4.19/950-0405-ASoC-tlv320aic32x4-Model-PLL-in-CCF.patch b/target/linux/brcm2708/patches-4.19/950-0405-ASoC-tlv320aic32x4-Model-PLL-in-CCF.patch deleted file mode 100644 index 5ac36a917c..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0405-ASoC-tlv320aic32x4-Model-PLL-in-CCF.patch +++ /dev/null @@ -1,877 +0,0 @@ -From 12e71e0f6b9009a5de89b2073a53c55c9ae28a40 Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Thu, 21 Mar 2019 17:58:45 -0700 -Subject: [PATCH 405/703] ASoC: tlv320aic32x4: Model PLL in CCF - -commit 514b044cba667e4b7c383ec79b42b997e624b91d upstream. - -Model and manage the on-board PLL as a component in the Core -Clock Framework. This should allow us to do some more complex -clock management and power control. Also, some of the -on-board chip clocks can be exposed to the outside, and this -change will make those clocks easier to consume by other -parts of the kernel. - -Signed-off-by: Annaliese McDermond -Signed-off-by: Mark Brown ---- - sound/soc/codecs/Kconfig | 1 + - sound/soc/codecs/Makefile | 2 +- - sound/soc/codecs/tlv320aic32x4-clk.c | 323 +++++++++++++++++++++++++++ - sound/soc/codecs/tlv320aic32x4.c | 195 ++++++++-------- - sound/soc/codecs/tlv320aic32x4.h | 5 + - 5 files changed, 431 insertions(+), 95 deletions(-) - create mode 100644 sound/soc/codecs/tlv320aic32x4-clk.c - ---- a/sound/soc/codecs/Kconfig -+++ b/sound/soc/codecs/Kconfig -@@ -1025,6 +1025,7 @@ config SND_SOC_TLV320AIC31XX - - config SND_SOC_TLV320AIC32X4 - tristate -+ depends on COMMON_CLK - - config SND_SOC_TLV320AIC32X4_I2C - tristate "Texas Instruments TLV320AIC32x4 audio CODECs - I2C" ---- a/sound/soc/codecs/Makefile -+++ b/sound/soc/codecs/Makefile -@@ -182,7 +182,7 @@ snd-soc-tlv320aic23-i2c-objs := tlv320ai - snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o - snd-soc-tlv320aic26-objs := tlv320aic26.o - snd-soc-tlv320aic31xx-objs := tlv320aic31xx.o --snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o -+snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o tlv320aic32x4-clk.o - snd-soc-tlv320aic32x4-i2c-objs := tlv320aic32x4-i2c.o - snd-soc-tlv320aic32x4-spi-objs := tlv320aic32x4-spi.o - snd-soc-tlv320aic3x-objs := tlv320aic3x.o ---- /dev/null -+++ b/sound/soc/codecs/tlv320aic32x4-clk.c -@@ -0,0 +1,323 @@ -+/* SPDX-License-Identifier: GPL-2.0 -+ * -+ * Clock Tree for the Texas Instruments TLV320AIC32x4 -+ * -+ * Copyright 2019 Annaliese McDermond -+ * -+ * Author: Annaliese McDermond -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "tlv320aic32x4.h" -+ -+#define to_clk_aic32x4(_hw) container_of(_hw, struct clk_aic32x4, hw) -+struct clk_aic32x4 { -+ struct clk_hw hw; -+ struct device *dev; -+ struct regmap *regmap; -+ unsigned int reg; -+}; -+ -+/* -+ * struct clk_aic32x4_pll_muldiv - Multiplier/divider settings -+ * @p: Divider -+ * @r: first multiplier -+ * @j: integer part of second multiplier -+ * @d: decimal part of second multiplier -+ */ -+struct clk_aic32x4_pll_muldiv { -+ u8 p; -+ u16 r; -+ u8 j; -+ u16 d; -+}; -+ -+struct aic32x4_clkdesc { -+ const char *name; -+ const char * const *parent_names; -+ unsigned int num_parents; -+ const struct clk_ops *ops; -+ unsigned int reg; -+}; -+ -+static int clk_aic32x4_pll_prepare(struct clk_hw *hw) -+{ -+ struct clk_aic32x4 *pll = to_clk_aic32x4(hw); -+ -+ return regmap_update_bits(pll->regmap, AIC32X4_PLLPR, -+ AIC32X4_PLLEN, AIC32X4_PLLEN); -+} -+ -+static void clk_aic32x4_pll_unprepare(struct clk_hw *hw) -+{ -+ struct clk_aic32x4 *pll = to_clk_aic32x4(hw); -+ -+ regmap_update_bits(pll->regmap, AIC32X4_PLLPR, -+ AIC32X4_PLLEN, 0); -+} -+ -+static int clk_aic32x4_pll_is_prepared(struct clk_hw *hw) -+{ -+ struct clk_aic32x4 *pll = to_clk_aic32x4(hw); -+ -+ unsigned int val; -+ int ret; -+ -+ ret = regmap_read(pll->regmap, AIC32X4_PLLPR, &val); -+ if (ret < 0) -+ return ret; -+ -+ return !!(val & AIC32X4_PLLEN); -+} -+ -+static int clk_aic32x4_pll_get_muldiv(struct clk_aic32x4 *pll, -+ struct clk_aic32x4_pll_muldiv *settings) -+{ -+ /* Change to use regmap_bulk_read? */ -+ unsigned int val; -+ int ret; -+ -+ ret = regmap_read(pll->regmap, AIC32X4_PLLPR, &val); -+ if (ret) -+ return ret; -+ settings->r = val & AIC32X4_PLL_R_MASK; -+ settings->p = (val & AIC32X4_PLL_P_MASK) >> AIC32X4_PLL_P_SHIFT; -+ -+ ret = regmap_read(pll->regmap, AIC32X4_PLLJ, &val); -+ if (ret < 0) -+ return ret; -+ settings->j = val; -+ -+ ret = regmap_read(pll->regmap, AIC32X4_PLLDMSB, &val); -+ if (ret < 0) -+ return ret; -+ settings->d = val << 8; -+ -+ ret = regmap_read(pll->regmap, AIC32X4_PLLDLSB, &val); -+ if (ret < 0) -+ return ret; -+ settings->d |= val; -+ -+ return 0; -+} -+ -+static int clk_aic32x4_pll_set_muldiv(struct clk_aic32x4 *pll, -+ struct clk_aic32x4_pll_muldiv *settings) -+{ -+ int ret; -+ /* Change to use regmap_bulk_write for some if not all? */ -+ -+ ret = regmap_update_bits(pll->regmap, AIC32X4_PLLPR, -+ AIC32X4_PLL_R_MASK, settings->r); -+ if (ret < 0) -+ return ret; -+ -+ ret = regmap_update_bits(pll->regmap, AIC32X4_PLLPR, -+ AIC32X4_PLL_P_MASK, -+ settings->p << AIC32X4_PLL_P_SHIFT); -+ if (ret < 0) -+ return ret; -+ -+ ret = regmap_write(pll->regmap, AIC32X4_PLLJ, settings->j); -+ if (ret < 0) -+ return ret; -+ -+ ret = regmap_write(pll->regmap, AIC32X4_PLLDMSB, (settings->d >> 8)); -+ if (ret < 0) -+ return ret; -+ ret = regmap_write(pll->regmap, AIC32X4_PLLDLSB, (settings->d & 0xff)); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static unsigned long clk_aic32x4_pll_calc_rate( -+ struct clk_aic32x4_pll_muldiv *settings, -+ unsigned long parent_rate) -+{ -+ u64 rate; -+ /* -+ * We scale j by 10000 to account for the decimal part of P and divide -+ * it back out later. -+ */ -+ rate = (u64) parent_rate * settings->r * -+ ((settings->j * 10000) + settings->d); -+ -+ return (unsigned long) DIV_ROUND_UP_ULL(rate, settings->p * 10000); -+} -+ -+static int clk_aic32x4_pll_calc_muldiv(struct clk_aic32x4_pll_muldiv *settings, -+ unsigned long rate, unsigned long parent_rate) -+{ -+ u64 multiplier; -+ -+ settings->p = parent_rate / AIC32X4_MAX_PLL_CLKIN + 1; -+ if (settings->p > 8) -+ return -1; -+ -+ /* -+ * We scale this figure by 10000 so that we can get the decimal part -+ * of the multiplier. This is because we can't do floating point -+ * math in the kernel. -+ */ -+ multiplier = (u64) rate * settings->p * 10000; -+ do_div(multiplier, parent_rate); -+ -+ /* -+ * J can't be over 64, so R can scale this. -+ * R can't be greater than 4. -+ */ -+ settings->r = ((u32) multiplier / 640000) + 1; -+ if (settings->r > 4) -+ return -1; -+ do_div(multiplier, settings->r); -+ -+ /* -+ * J can't be < 1. -+ */ -+ if (multiplier < 10000) -+ return -1; -+ -+ /* Figure out the integer part, J, and the fractional part, D. */ -+ settings->j = (u32) multiplier / 10000; -+ settings->d = (u32) multiplier % 10000; -+ -+ return 0; -+} -+ -+static unsigned long clk_aic32x4_pll_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ struct clk_aic32x4 *pll = to_clk_aic32x4(hw); -+ struct clk_aic32x4_pll_muldiv settings; -+ int ret; -+ -+ ret = clk_aic32x4_pll_get_muldiv(pll, &settings); -+ if (ret < 0) -+ return 0; -+ -+ return clk_aic32x4_pll_calc_rate(&settings, parent_rate); -+} -+ -+static long clk_aic32x4_pll_round_rate(struct clk_hw *hw, -+ unsigned long rate, -+ unsigned long *parent_rate) -+{ -+ struct clk_aic32x4_pll_muldiv settings; -+ int ret; -+ -+ ret = clk_aic32x4_pll_calc_muldiv(&settings, rate, *parent_rate); -+ if (ret < 0) -+ return 0; -+ -+ return clk_aic32x4_pll_calc_rate(&settings, *parent_rate); -+} -+ -+static int clk_aic32x4_pll_set_rate(struct clk_hw *hw, -+ unsigned long rate, -+ unsigned long parent_rate) -+{ -+ struct clk_aic32x4 *pll = to_clk_aic32x4(hw); -+ struct clk_aic32x4_pll_muldiv settings; -+ int ret; -+ -+ ret = clk_aic32x4_pll_calc_muldiv(&settings, rate, parent_rate); -+ if (ret < 0) -+ return -EINVAL; -+ -+ return clk_aic32x4_pll_set_muldiv(pll, &settings); -+} -+ -+static int clk_aic32x4_pll_set_parent(struct clk_hw *hw, u8 index) -+{ -+ struct clk_aic32x4 *pll = to_clk_aic32x4(hw); -+ -+ return regmap_update_bits(pll->regmap, -+ AIC32X4_CLKMUX, -+ AIC32X4_PLL_CLKIN_MASK, -+ index << AIC32X4_PLL_CLKIN_SHIFT); -+} -+ -+static u8 clk_aic32x4_pll_get_parent(struct clk_hw *hw) -+{ -+ struct clk_aic32x4 *pll = to_clk_aic32x4(hw); -+ unsigned int val; -+ -+ regmap_read(pll->regmap, AIC32X4_PLLPR, &val); -+ -+ return (val & AIC32X4_PLL_CLKIN_MASK) >> AIC32X4_PLL_CLKIN_SHIFT; -+} -+ -+ -+static const struct clk_ops aic32x4_pll_ops = { -+ .prepare = clk_aic32x4_pll_prepare, -+ .unprepare = clk_aic32x4_pll_unprepare, -+ .is_prepared = clk_aic32x4_pll_is_prepared, -+ .recalc_rate = clk_aic32x4_pll_recalc_rate, -+ .round_rate = clk_aic32x4_pll_round_rate, -+ .set_rate = clk_aic32x4_pll_set_rate, -+ .set_parent = clk_aic32x4_pll_set_parent, -+ .get_parent = clk_aic32x4_pll_get_parent, -+}; -+ -+static struct aic32x4_clkdesc aic32x4_clkdesc_array[] = { -+ { -+ .name = "pll", -+ .parent_names = -+ (const char* []) { "mclk", "bclk", "gpio", "din" }, -+ .num_parents = 4, -+ .ops = &aic32x4_pll_ops, -+ .reg = 0, -+ }, -+}; -+ -+static struct clk *aic32x4_register_clk(struct device *dev, -+ struct aic32x4_clkdesc *desc) -+{ -+ struct clk_init_data init; -+ struct clk_aic32x4 *priv; -+ const char *devname = dev_name(dev); -+ -+ init.ops = desc->ops; -+ init.name = desc->name; -+ init.parent_names = desc->parent_names; -+ init.num_parents = desc->num_parents; -+ init.flags = 0; -+ -+ priv = devm_kzalloc(dev, sizeof(struct clk_aic32x4), GFP_KERNEL); -+ if (priv == NULL) -+ return (struct clk *) -ENOMEM; -+ -+ priv->dev = dev; -+ priv->hw.init = &init; -+ priv->regmap = dev_get_regmap(dev, NULL); -+ priv->reg = desc->reg; -+ -+ clk_hw_register_clkdev(&priv->hw, desc->name, devname); -+ return devm_clk_register(dev, &priv->hw); -+} -+ -+int aic32x4_register_clocks(struct device *dev, const char *mclk_name) -+{ -+ int i; -+ -+ /* -+ * These lines are here to preserve the current functionality of -+ * the driver with regard to the DT. These should eventually be set -+ * by DT nodes so that the connections can be set up in configuration -+ * rather than code. -+ */ -+ aic32x4_clkdesc_array[0].parent_names = -+ (const char* []) { mclk_name, "bclk", "gpio", "din" }; -+ -+ for (i = 0; i < ARRAY_SIZE(aic32x4_clkdesc_array); ++i) -+ aic32x4_register_clk(dev, &aic32x4_clkdesc_array[i]); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(aic32x4_register_clocks); ---- a/sound/soc/codecs/tlv320aic32x4.c -+++ b/sound/soc/codecs/tlv320aic32x4.c -@@ -14,7 +14,7 @@ - * - * 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 -+ * 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 -@@ -33,6 +33,7 @@ - #include - #include - #include -+#include - #include - - #include -@@ -49,9 +50,7 @@ - struct aic32x4_rate_divs { - u32 mclk; - u32 rate; -- u8 p_val; -- u8 pll_j; -- u16 pll_d; -+ unsigned long pll_rate; - u16 dosr; - u8 ndac; - u8 mdac; -@@ -71,6 +70,7 @@ struct aic32x4_priv { - bool swapdacs; - int rstn_gpio; - struct clk *mclk; -+ const char *mclk_name; - - struct regulator *supply_ldo; - struct regulator *supply_iov; -@@ -309,34 +309,34 @@ static const struct snd_kcontrol_new aic - - static const struct aic32x4_rate_divs aic32x4_divs[] = { - /* 8k rate */ -- {12000000, 8000, 1, 7, 6800, 768, 5, 3, 128, 5, 18, 24, 1, 1}, -- {24000000, 8000, 2, 7, 6800, 768, 15, 1, 64, 45, 4, 24, 1, 1}, -- {25000000, 8000, 2, 7, 3728, 768, 15, 1, 64, 45, 4, 24, 1, 1}, -+ { 12000000, 8000, 57120000, 768, 5, 3, 128, 5, 18, 24, 1, 1 }, -+ { 24000000, 8000, 57120000, 768, 15, 1, 64, 45, 4, 24, 1, 1 }, -+ { 25000000, 8000, 32620000, 768, 15, 1, 64, 45, 4, 24, 1, 1 }, - /* 11.025k rate */ -- {12000000, 11025, 1, 7, 5264, 512, 8, 2, 128, 8, 8, 16, 1, 1}, -- {24000000, 11025, 2, 7, 5264, 512, 16, 1, 64, 32, 4, 16, 1, 1}, -+ { 12000000, 11025, 44217600, 512, 8, 2, 128, 8, 8, 16, 1, 1 }, -+ { 24000000, 11025, 44217600, 512, 16, 1, 64, 32, 4, 16, 1, 1 }, - /* 16k rate */ -- {12000000, 16000, 1, 7, 6800, 384, 5, 3, 128, 5, 9, 12, 1, 1}, -- {24000000, 16000, 2, 7, 6800, 384, 15, 1, 64, 18, 5, 12, 1, 1}, -- {25000000, 16000, 2, 7, 3728, 384, 15, 1, 64, 18, 5, 12, 1, 1}, -+ { 12000000, 16000, 57120000, 384, 5, 3, 128, 5, 9, 12, 1, 1 }, -+ { 24000000, 16000, 57120000, 384, 15, 1, 64, 18, 5, 12, 1, 1 }, -+ { 25000000, 16000, 32620000, 384, 15, 1, 64, 18, 5, 12, 1, 1 }, - /* 22.05k rate */ -- {12000000, 22050, 1, 7, 5264, 256, 4, 4, 128, 4, 8, 8, 1, 1}, -- {24000000, 22050, 2, 7, 5264, 256, 16, 1, 64, 16, 4, 8, 1, 1}, -- {25000000, 22050, 2, 7, 2253, 256, 16, 1, 64, 16, 4, 8, 1, 1}, -+ { 12000000, 22050, 44217600, 256, 4, 4, 128, 4, 8, 8, 1, 1 }, -+ { 24000000, 22050, 44217600, 256, 16, 1, 64, 16, 4, 8, 1, 1 }, -+ { 25000000, 22050, 19713750, 256, 16, 1, 64, 16, 4, 8, 1, 1 }, - /* 32k rate */ -- {12000000, 32000, 1, 7, 1680, 192, 2, 7, 64, 2, 21, 6, 1, 1}, -- {24000000, 32000, 2, 7, 1680, 192, 7, 2, 64, 7, 6, 6, 1, 1}, -+ { 12000000, 32000, 14112000, 192, 2, 7, 64, 2, 21, 6, 1, 1 }, -+ { 24000000, 32000, 14112000, 192, 7, 2, 64, 7, 6, 6, 1, 1 }, - /* 44.1k rate */ -- {12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4, 1, 1}, -- {24000000, 44100, 2, 7, 5264, 128, 8, 2, 64, 8, 4, 4, 1, 1}, -- {25000000, 44100, 2, 7, 2253, 128, 8, 2, 64, 8, 4, 4, 1, 1}, -+ { 12000000, 44100, 44217600, 128, 2, 8, 128, 2, 8, 4, 1, 1 }, -+ { 24000000, 44100, 44217600, 128, 8, 2, 64, 8, 4, 4, 1, 1 }, -+ { 25000000, 44100, 19713750, 128, 8, 2, 64, 8, 4, 4, 1, 1 }, - /* 48k rate */ -- {12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4, 1, 1}, -- {24000000, 48000, 2, 8, 1920, 128, 8, 2, 64, 8, 4, 4, 1, 1}, -- {25000000, 48000, 2, 7, 8643, 128, 8, 2, 64, 8, 4, 4, 1, 1}, -+ { 12000000, 48000, 18432000, 128, 2, 8, 128, 2, 8, 4, 1, 1 }, -+ { 24000000, 48000, 18432000, 128, 8, 2, 64, 8, 4, 4, 1, 1 }, -+ { 25000000, 48000, 75626250, 128, 8, 2, 64, 8, 4, 4, 1, 1 }, - - /* 96k rate */ -- {25000000, 96000, 2, 7, 8643, 64, 4, 4, 64, 4, 4, 1, 1, 9}, -+ { 25000000, 96000, 75626250, 64, 4, 4, 64, 4, 4, 1, 1, 9 }, - }; - - static const struct snd_kcontrol_new hpl_output_mixer_controls[] = { -@@ -393,7 +393,7 @@ static const struct snd_kcontrol_new in3 - SOC_DAPM_ENUM("IN3_R L- Switch", in3r_lpga_n_enum), - }; - --/* Right mixer pins */ -+/* Right mixer pins */ - static SOC_ENUM_SINGLE_DECL(in1r_rpga_p_enum, AIC32X4_RMICPGAPIN, 6, resistor_text); - static SOC_ENUM_SINGLE_DECL(in2r_rpga_p_enum, AIC32X4_RMICPGAPIN, 4, resistor_text); - static SOC_ENUM_SINGLE_DECL(in3r_rpga_p_enum, AIC32X4_RMICPGAPIN, 2, resistor_text); -@@ -597,7 +597,7 @@ static const struct snd_soc_dapm_route a - static const struct regmap_range_cfg aic32x4_regmap_pages[] = { - { - .selector_reg = 0, -- .selector_mask = 0xff, -+ .selector_mask = 0xff, - .window_start = 0, - .window_len = 128, - .range_min = 0, -@@ -618,7 +618,7 @@ static inline int aic32x4_get_divs(int m - - for (i = 0; i < ARRAY_SIZE(aic32x4_divs); i++) { - if ((aic32x4_divs[i].rate == rate) -- && (aic32x4_divs[i].mclk == mclk)) { -+ && (aic32x4_divs[i].mclk == mclk)) { - return i; - } - } -@@ -690,12 +690,12 @@ static int aic32x4_set_dai_fmt(struct sn - } - - snd_soc_component_update_bits(component, AIC32X4_IFACE1, -- AIC32X4_IFACE1_DATATYPE_MASK | -- AIC32X4_IFACE1_MASTER_MASK, iface_reg_1); -+ AIC32X4_IFACE1_DATATYPE_MASK | -+ AIC32X4_IFACE1_MASTER_MASK, iface_reg_1); - snd_soc_component_update_bits(component, AIC32X4_IFACE2, -- AIC32X4_DATA_OFFSET_MASK, iface_reg_2); -+ AIC32X4_DATA_OFFSET_MASK, iface_reg_2); - snd_soc_component_update_bits(component, AIC32X4_IFACE3, -- AIC32X4_BCLKINV_MASK, iface_reg_3); -+ AIC32X4_BCLKINV_MASK, iface_reg_3); - - return 0; - } -@@ -717,6 +717,11 @@ static int aic32x4_setup_clocks(struct s - unsigned int parent_rate) - { - int i; -+ int ret; -+ -+ struct clk_bulk_data clocks[] = { -+ { .id = "pll" }, -+ }; - - i = aic32x4_get_divs(parent_rate, sample_rate); - if (i < 0) { -@@ -724,39 +729,29 @@ static int aic32x4_setup_clocks(struct s - return i; - } - -+ ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks); -+ if (ret) -+ return ret; -+ -+ clk_set_rate(clocks[0].clk, sample_rate); -+ - aic32x4_set_processing_blocks(component, aic32x4_divs[i].r_block, aic32x4_divs[i].p_block); - -- /* MCLK as PLL_CLKIN */ -- snd_soc_component_update_bits(component, AIC32X4_CLKMUX, AIC32X4_PLL_CLKIN_MASK, -- AIC32X4_PLL_CLKIN_MCLK << AIC32X4_PLL_CLKIN_SHIFT); - /* PLL as CODEC_CLKIN */ -- snd_soc_component_update_bits(component, AIC32X4_CLKMUX, AIC32X4_CODEC_CLKIN_MASK, -- AIC32X4_CODEC_CLKIN_PLL << AIC32X4_CODEC_CLKIN_SHIFT); -+ snd_soc_component_update_bits(component, AIC32X4_CLKMUX, -+ AIC32X4_CODEC_CLKIN_MASK, -+ AIC32X4_CODEC_CLKIN_PLL << AIC32X4_CODEC_CLKIN_SHIFT); - /* DAC_MOD_CLK as BDIV_CLKIN */ - snd_soc_component_update_bits(component, AIC32X4_IFACE3, AIC32X4_BDIVCLK_MASK, -- AIC32X4_DACMOD2BCLK << AIC32X4_BDIVCLK_SHIFT); -- -- /* We will fix R value to 1 and will make P & J=K.D as variable */ -- snd_soc_component_update_bits(component, AIC32X4_PLLPR, AIC32X4_PLL_R_MASK, 0x01); -- -- /* PLL P value */ -- snd_soc_component_update_bits(component, AIC32X4_PLLPR, AIC32X4_PLL_P_MASK, -- aic32x4_divs[i].p_val << AIC32X4_PLL_P_SHIFT); -- -- /* PLL J value */ -- snd_soc_component_write(component, AIC32X4_PLLJ, aic32x4_divs[i].pll_j); -- -- /* PLL D value */ -- snd_soc_component_write(component, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8)); -- snd_soc_component_write(component, AIC32X4_PLLDLSB, (aic32x4_divs[i].pll_d & 0xff)); -+ AIC32X4_DACMOD2BCLK << AIC32X4_BDIVCLK_SHIFT); - - /* NDAC divider value */ - snd_soc_component_update_bits(component, AIC32X4_NDAC, -- AIC32X4_NDAC_MASK, aic32x4_divs[i].ndac); -+ AIC32X4_NDAC_MASK, aic32x4_divs[i].ndac); - - /* MDAC divider value */ - snd_soc_component_update_bits(component, AIC32X4_MDAC, -- AIC32X4_MDAC_MASK, aic32x4_divs[i].mdac); -+ AIC32X4_MDAC_MASK, aic32x4_divs[i].mdac); - - /* DOSR MSB & LSB values */ - snd_soc_component_write(component, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8); -@@ -764,18 +759,18 @@ static int aic32x4_setup_clocks(struct s - - /* NADC divider value */ - snd_soc_component_update_bits(component, AIC32X4_NADC, -- AIC32X4_NADC_MASK, aic32x4_divs[i].nadc); -+ AIC32X4_NADC_MASK, aic32x4_divs[i].nadc); - - /* MADC divider value */ - snd_soc_component_update_bits(component, AIC32X4_MADC, -- AIC32X4_MADC_MASK, aic32x4_divs[i].madc); -+ AIC32X4_MADC_MASK, aic32x4_divs[i].madc); - - /* AOSR value */ - snd_soc_component_write(component, AIC32X4_AOSR, aic32x4_divs[i].aosr); - - /* BCLK N divider */ - snd_soc_component_update_bits(component, AIC32X4_BCLKN, -- AIC32X4_BCLK_MASK, aic32x4_divs[i].blck_N); -+ AIC32X4_BCLK_MASK, aic32x4_divs[i].blck_N); - - return 0; - } -@@ -794,23 +789,23 @@ static int aic32x4_hw_params(struct snd_ - switch (params_width(params)) { - case 16: - iface1_reg |= (AIC32X4_WORD_LEN_16BITS << -- AIC32X4_IFACE1_DATALEN_SHIFT); -+ AIC32X4_IFACE1_DATALEN_SHIFT); - break; - case 20: - iface1_reg |= (AIC32X4_WORD_LEN_20BITS << -- AIC32X4_IFACE1_DATALEN_SHIFT); -+ AIC32X4_IFACE1_DATALEN_SHIFT); - break; - case 24: - iface1_reg |= (AIC32X4_WORD_LEN_24BITS << -- AIC32X4_IFACE1_DATALEN_SHIFT); -+ AIC32X4_IFACE1_DATALEN_SHIFT); - break; - case 32: - iface1_reg |= (AIC32X4_WORD_LEN_32BITS << -- AIC32X4_IFACE1_DATALEN_SHIFT); -+ AIC32X4_IFACE1_DATALEN_SHIFT); - break; - } - snd_soc_component_update_bits(component, AIC32X4_IFACE1, -- AIC32X4_IFACE1_DATALEN_MASK, iface1_reg); -+ AIC32X4_IFACE1_DATALEN_MASK, iface1_reg); - - if (params_channels(params) == 1) { - dacsetup_reg = AIC32X4_RDAC2LCHN | AIC32X4_LDAC2LCHN; -@@ -821,7 +816,7 @@ static int aic32x4_hw_params(struct snd_ - dacsetup_reg = AIC32X4_LDAC2LCHN | AIC32X4_RDAC2RCHN; - } - snd_soc_component_update_bits(component, AIC32X4_DACSETUP, -- AIC32X4_DAC_CHAN_MASK, dacsetup_reg); -+ AIC32X4_DAC_CHAN_MASK, dacsetup_reg); - - return 0; - } -@@ -831,7 +826,7 @@ static int aic32x4_mute(struct snd_soc_d - struct snd_soc_component *component = dai->component; - - snd_soc_component_update_bits(component, AIC32X4_DACMUTE, -- AIC32X4_MUTEON, mute ? AIC32X4_MUTEON : 0); -+ AIC32X4_MUTEON, mute ? AIC32X4_MUTEON : 0); - - return 0; - } -@@ -853,27 +848,27 @@ static int aic32x4_set_bias_level(struct - - /* Switch on PLL */ - snd_soc_component_update_bits(component, AIC32X4_PLLPR, -- AIC32X4_PLLEN, AIC32X4_PLLEN); -+ AIC32X4_PLLEN, AIC32X4_PLLEN); - - /* Switch on NDAC Divider */ - snd_soc_component_update_bits(component, AIC32X4_NDAC, -- AIC32X4_NDACEN, AIC32X4_NDACEN); -+ AIC32X4_NDACEN, AIC32X4_NDACEN); - - /* Switch on MDAC Divider */ - snd_soc_component_update_bits(component, AIC32X4_MDAC, -- AIC32X4_MDACEN, AIC32X4_MDACEN); -+ AIC32X4_MDACEN, AIC32X4_MDACEN); - - /* Switch on NADC Divider */ - snd_soc_component_update_bits(component, AIC32X4_NADC, -- AIC32X4_NADCEN, AIC32X4_NADCEN); -+ AIC32X4_NADCEN, AIC32X4_NADCEN); - - /* Switch on MADC Divider */ - snd_soc_component_update_bits(component, AIC32X4_MADC, -- AIC32X4_MADCEN, AIC32X4_MADCEN); -+ AIC32X4_MADCEN, AIC32X4_MADCEN); - - /* Switch on BCLK_N Divider */ - snd_soc_component_update_bits(component, AIC32X4_BCLKN, -- AIC32X4_BCLKEN, AIC32X4_BCLKEN); -+ AIC32X4_BCLKEN, AIC32X4_BCLKEN); - break; - case SND_SOC_BIAS_PREPARE: - break; -@@ -884,27 +879,27 @@ static int aic32x4_set_bias_level(struct - - /* Switch off BCLK_N Divider */ - snd_soc_component_update_bits(component, AIC32X4_BCLKN, -- AIC32X4_BCLKEN, 0); -+ AIC32X4_BCLKEN, 0); - - /* Switch off MADC Divider */ - snd_soc_component_update_bits(component, AIC32X4_MADC, -- AIC32X4_MADCEN, 0); -+ AIC32X4_MADCEN, 0); - - /* Switch off NADC Divider */ - snd_soc_component_update_bits(component, AIC32X4_NADC, -- AIC32X4_NADCEN, 0); -+ AIC32X4_NADCEN, 0); - - /* Switch off MDAC Divider */ - snd_soc_component_update_bits(component, AIC32X4_MDAC, -- AIC32X4_MDACEN, 0); -+ AIC32X4_MDACEN, 0); - - /* Switch off NDAC Divider */ - snd_soc_component_update_bits(component, AIC32X4_NDAC, -- AIC32X4_NDACEN, 0); -+ AIC32X4_NDACEN, 0); - - /* Switch off PLL */ - snd_soc_component_update_bits(component, AIC32X4_PLLPR, -- AIC32X4_PLLEN, 0); -+ AIC32X4_PLLEN, 0); - - /* Switch off master clock */ - clk_disable_unprepare(aic32x4->mclk); -@@ -916,7 +911,7 @@ static int aic32x4_set_bias_level(struct - } - - #define AIC32X4_RATES SNDRV_PCM_RATE_8000_96000 --#define AIC32X4_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ -+#define AIC32X4_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ - | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) - - static const struct snd_soc_dai_ops aic32x4_ops = { -@@ -929,17 +924,17 @@ static const struct snd_soc_dai_ops aic3 - static struct snd_soc_dai_driver aic32x4_dai = { - .name = "tlv320aic32x4-hifi", - .playback = { -- .stream_name = "Playback", -- .channels_min = 1, -- .channels_max = 2, -- .rates = AIC32X4_RATES, -- .formats = AIC32X4_FORMATS,}, -+ .stream_name = "Playback", -+ .channels_min = 1, -+ .channels_max = 2, -+ .rates = AIC32X4_RATES, -+ .formats = AIC32X4_FORMATS,}, - .capture = { -- .stream_name = "Capture", -- .channels_min = 1, -- .channels_max = 2, -- .rates = AIC32X4_RATES, -- .formats = AIC32X4_FORMATS,}, -+ .stream_name = "Capture", -+ .channels_min = 1, -+ .channels_max = 2, -+ .rates = AIC32X4_RATES, -+ .formats = AIC32X4_FORMATS,}, - .ops = &aic32x4_ops, - .symmetric_rates = 1, - }; -@@ -952,7 +947,7 @@ static void aic32x4_setup_gpios(struct s - /* MFP1 */ - if (aic32x4->setup->gpio_func[0] != AIC32X4_MFPX_DEFAULT_VALUE) { - snd_soc_component_write(component, AIC32X4_DINCTL, -- aic32x4->setup->gpio_func[0]); -+ aic32x4->setup->gpio_func[0]); - snd_soc_add_component_controls(component, aic32x4_mfp1, - ARRAY_SIZE(aic32x4_mfp1)); - } -@@ -960,7 +955,7 @@ static void aic32x4_setup_gpios(struct s - /* MFP2 */ - if (aic32x4->setup->gpio_func[1] != AIC32X4_MFPX_DEFAULT_VALUE) { - snd_soc_component_write(component, AIC32X4_DOUTCTL, -- aic32x4->setup->gpio_func[1]); -+ aic32x4->setup->gpio_func[1]); - snd_soc_add_component_controls(component, aic32x4_mfp2, - ARRAY_SIZE(aic32x4_mfp2)); - } -@@ -968,7 +963,7 @@ static void aic32x4_setup_gpios(struct s - /* MFP3 */ - if (aic32x4->setup->gpio_func[2] != AIC32X4_MFPX_DEFAULT_VALUE) { - snd_soc_component_write(component, AIC32X4_SCLKCTL, -- aic32x4->setup->gpio_func[2]); -+ aic32x4->setup->gpio_func[2]); - snd_soc_add_component_controls(component, aic32x4_mfp3, - ARRAY_SIZE(aic32x4_mfp3)); - } -@@ -976,7 +971,7 @@ static void aic32x4_setup_gpios(struct s - /* MFP4 */ - if (aic32x4->setup->gpio_func[3] != AIC32X4_MFPX_DEFAULT_VALUE) { - snd_soc_component_write(component, AIC32X4_MISOCTL, -- aic32x4->setup->gpio_func[3]); -+ aic32x4->setup->gpio_func[3]); - snd_soc_add_component_controls(component, aic32x4_mfp4, - ARRAY_SIZE(aic32x4_mfp4)); - } -@@ -984,7 +979,7 @@ static void aic32x4_setup_gpios(struct s - /* MFP5 */ - if (aic32x4->setup->gpio_func[4] != AIC32X4_MFPX_DEFAULT_VALUE) { - snd_soc_component_write(component, AIC32X4_GPIOCTL, -- aic32x4->setup->gpio_func[4]); -+ aic32x4->setup->gpio_func[4]); - snd_soc_add_component_controls(component, aic32x4_mfp5, - ARRAY_SIZE(aic32x4_mfp5)); - } -@@ -1007,8 +1002,8 @@ static int aic32x4_component_probe(struc - - /* Power platform configuration */ - if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) { -- snd_soc_component_write(component, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN | -- AIC32X4_MICBIAS_2075V); -+ snd_soc_component_write(component, AIC32X4_MICBIAS, -+ AIC32X4_MICBIAS_LDOIN | AIC32X4_MICBIAS_2075V); - } - if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE) - snd_soc_component_write(component, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE); -@@ -1071,12 +1066,18 @@ static int aic32x4_parse_dt(struct aic32 - struct device_node *np) - { - struct aic32x4_setup_data *aic32x4_setup; -+ int ret; - - aic32x4_setup = devm_kzalloc(aic32x4->dev, sizeof(*aic32x4_setup), - GFP_KERNEL); - if (!aic32x4_setup) - return -ENOMEM; - -+ ret = of_property_match_string(np, "clock-names", "mclk"); -+ if (ret < 0) -+ return -EINVAL; -+ aic32x4->mclk_name = of_clk_get_parent_name(np, ret); -+ - aic32x4->swapdacs = false; - aic32x4->micpga_routing = 0; - aic32x4->rstn_gpio = of_get_named_gpio(np, "reset-gpios", 0); -@@ -1198,7 +1199,7 @@ int aic32x4_probe(struct device *dev, st - return PTR_ERR(regmap); - - aic32x4 = devm_kzalloc(dev, sizeof(struct aic32x4_priv), -- GFP_KERNEL); -+ GFP_KERNEL); - if (aic32x4 == NULL) - return -ENOMEM; - -@@ -1210,6 +1211,7 @@ int aic32x4_probe(struct device *dev, st - aic32x4->swapdacs = pdata->swapdacs; - aic32x4->micpga_routing = pdata->micpga_routing; - aic32x4->rstn_gpio = pdata->rstn_gpio; -+ aic32x4->mclk_name = "mclk"; - } else if (np) { - ret = aic32x4_parse_dt(aic32x4, np); - if (ret) { -@@ -1221,6 +1223,7 @@ int aic32x4_probe(struct device *dev, st - aic32x4->swapdacs = false; - aic32x4->micpga_routing = 0; - aic32x4->rstn_gpio = -1; -+ aic32x4->mclk_name = "mclk"; - } - - aic32x4->mclk = devm_clk_get(dev, "mclk"); -@@ -1229,6 +1232,10 @@ int aic32x4_probe(struct device *dev, st - return PTR_ERR(aic32x4->mclk); - } - -+ ret = aic32x4_register_clocks(dev, aic32x4->mclk_name); -+ if (ret) -+ return ret; -+ - if (gpio_is_valid(aic32x4->rstn_gpio)) { - ret = devm_gpio_request_one(dev, aic32x4->rstn_gpio, - GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn"); ---- a/sound/soc/codecs/tlv320aic32x4.h -+++ b/sound/soc/codecs/tlv320aic32x4.h -@@ -16,6 +16,7 @@ struct regmap_config; - extern const struct regmap_config aic32x4_regmap_config; - int aic32x4_probe(struct device *dev, struct regmap *regmap); - int aic32x4_remove(struct device *dev); -+int aic32x4_register_clocks(struct device *dev, const char *mclk_name); - - /* tlv320aic32x4 register space (in decimal to match datasheet) */ - -@@ -205,4 +206,8 @@ int aic32x4_remove(struct device *dev); - #define AIC32X4_RMICPGANIN_IN1L_10K 0x10 - #define AIC32X4_RMICPGANIN_CM1R_10K 0x40 - -+/* Clock Limits */ -+#define AIC32X4_MAX_PLL_CLKIN 20000000 -+ -+ - #endif /* _TLV320AIC32X4_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0406-ASoC-tlv320aic32x4-Control-clock-gating-with-CCF.patch b/target/linux/brcm2708/patches-4.19/950-0406-ASoC-tlv320aic32x4-Control-clock-gating-with-CCF.patch new file mode 100644 index 0000000000..dc83350b72 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0406-ASoC-tlv320aic32x4-Control-clock-gating-with-CCF.patch @@ -0,0 +1,109 @@ +From 95c6e21b0ab366f5433d5c89aa5ae961ad40d2e6 Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Thu, 21 Mar 2019 17:58:49 -0700 +Subject: [PATCH 406/725] ASoC: tlv320aic32x4: Control clock gating with CCF + +commit d25970b5fd51e9fcf0afbe190908ea4049454da4 upstream. + +Control the clock gating to the various clock components to use +the CCF. This allows us to prepare_enalbe only 3 clocks and the +relationships assigned to them will cause upstream clockss to +enable automatically. Additionally we can do this in a single +call to the CCF. + +Signed-off-by: Annaliese McDermond +Signed-off-by: Mark Brown +--- + sound/soc/codecs/tlv320aic32x4.c | 67 +++++++------------------------- + 1 file changed, 13 insertions(+), 54 deletions(-) + +--- a/sound/soc/codecs/tlv320aic32x4.c ++++ b/sound/soc/codecs/tlv320aic32x4.c +@@ -836,41 +836,25 @@ static int aic32x4_mute(struct snd_soc_d + static int aic32x4_set_bias_level(struct snd_soc_component *component, + enum snd_soc_bias_level level) + { +- struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component); + int ret; + ++ struct clk_bulk_data clocks[] = { ++ { .id = "madc" }, ++ { .id = "mdac" }, ++ { .id = "bdiv" }, ++ }; ++ ++ ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks); ++ if (ret) ++ return ret; ++ + switch (level) { + case SND_SOC_BIAS_ON: +- /* Switch on master clock */ +- ret = clk_prepare_enable(aic32x4->mclk); ++ ret = clk_bulk_prepare_enable(ARRAY_SIZE(clocks), clocks); + if (ret) { +- dev_err(component->dev, "Failed to enable master clock\n"); ++ dev_err(component->dev, "Failed to enable clocks\n"); + return ret; + } +- +- /* Switch on PLL */ +- snd_soc_component_update_bits(component, AIC32X4_PLLPR, +- AIC32X4_PLLEN, AIC32X4_PLLEN); +- +- /* Switch on NDAC Divider */ +- snd_soc_component_update_bits(component, AIC32X4_NDAC, +- AIC32X4_NDACEN, AIC32X4_NDACEN); +- +- /* Switch on MDAC Divider */ +- snd_soc_component_update_bits(component, AIC32X4_MDAC, +- AIC32X4_MDACEN, AIC32X4_MDACEN); +- +- /* Switch on NADC Divider */ +- snd_soc_component_update_bits(component, AIC32X4_NADC, +- AIC32X4_NADCEN, AIC32X4_NADCEN); +- +- /* Switch on MADC Divider */ +- snd_soc_component_update_bits(component, AIC32X4_MADC, +- AIC32X4_MADCEN, AIC32X4_MADCEN); +- +- /* Switch on BCLK_N Divider */ +- snd_soc_component_update_bits(component, AIC32X4_BCLKN, +- AIC32X4_BCLKEN, AIC32X4_BCLKEN); + break; + case SND_SOC_BIAS_PREPARE: + break; +@@ -879,32 +863,7 @@ static int aic32x4_set_bias_level(struct + if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) + break; + +- /* Switch off BCLK_N Divider */ +- snd_soc_component_update_bits(component, AIC32X4_BCLKN, +- AIC32X4_BCLKEN, 0); +- +- /* Switch off MADC Divider */ +- snd_soc_component_update_bits(component, AIC32X4_MADC, +- AIC32X4_MADCEN, 0); +- +- /* Switch off NADC Divider */ +- snd_soc_component_update_bits(component, AIC32X4_NADC, +- AIC32X4_NADCEN, 0); +- +- /* Switch off MDAC Divider */ +- snd_soc_component_update_bits(component, AIC32X4_MDAC, +- AIC32X4_MDACEN, 0); +- +- /* Switch off NDAC Divider */ +- snd_soc_component_update_bits(component, AIC32X4_NDAC, +- AIC32X4_NDACEN, 0); +- +- /* Switch off PLL */ +- snd_soc_component_update_bits(component, AIC32X4_PLLPR, +- AIC32X4_PLLEN, 0); +- +- /* Switch off master clock */ +- clk_disable_unprepare(aic32x4->mclk); ++ clk_bulk_disable_unprepare(ARRAY_SIZE(clocks), clocks); + break; + case SND_SOC_BIAS_OFF: + break; diff --git a/target/linux/brcm2708/patches-4.19/950-0406-ASoC-tlv320aic32x4-Model-CODEC_CLKIN-in-CCF.patch b/target/linux/brcm2708/patches-4.19/950-0406-ASoC-tlv320aic32x4-Model-CODEC_CLKIN-in-CCF.patch deleted file mode 100644 index b8797fe3df..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0406-ASoC-tlv320aic32x4-Model-CODEC_CLKIN-in-CCF.patch +++ /dev/null @@ -1,120 +0,0 @@ -From f0192af931c8aea25440c014b9a995a3bf1a5363 Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Thu, 21 Mar 2019 17:58:46 -0700 -Subject: [PATCH 406/703] ASoC: tlv320aic32x4: Model CODEC_CLKIN in CCF - -commit fd2df3aeafa4b4cc468d58e147e0822967034b71 upstream. - -Model and manage codec clock input as a component in the Core -Clock Framework. This should allow us to do some more complex -clock management and power control. Also, some of the -on-board chip clocks can be exposed to the outside, and this -change will make those clocks easier to consume by other -parts of the kernel. - -Signed-off-by: Annaliese McDermond -Signed-off-by: Mark Brown ---- - sound/soc/codecs/tlv320aic32x4-clk.c | 34 ++++++++++++++++++++++++++++ - sound/soc/codecs/tlv320aic32x4.c | 18 +++++++++++---- - 2 files changed, 47 insertions(+), 5 deletions(-) - ---- a/sound/soc/codecs/tlv320aic32x4-clk.c -+++ b/sound/soc/codecs/tlv320aic32x4-clk.c -@@ -265,6 +265,30 @@ static const struct clk_ops aic32x4_pll_ - .get_parent = clk_aic32x4_pll_get_parent, - }; - -+static int clk_aic32x4_codec_clkin_set_parent(struct clk_hw *hw, u8 index) -+{ -+ struct clk_aic32x4 *mux = to_clk_aic32x4(hw); -+ -+ return regmap_update_bits(mux->regmap, -+ AIC32X4_CLKMUX, -+ AIC32X4_CODEC_CLKIN_MASK, index << AIC32X4_CODEC_CLKIN_SHIFT); -+} -+ -+static u8 clk_aic32x4_codec_clkin_get_parent(struct clk_hw *hw) -+{ -+ struct clk_aic32x4 *mux = to_clk_aic32x4(hw); -+ unsigned int val; -+ -+ regmap_read(mux->regmap, AIC32X4_CLKMUX, &val); -+ -+ return (val & AIC32X4_CODEC_CLKIN_MASK) >> AIC32X4_CODEC_CLKIN_SHIFT; -+} -+ -+static const struct clk_ops aic32x4_codec_clkin_ops = { -+ .set_parent = clk_aic32x4_codec_clkin_set_parent, -+ .get_parent = clk_aic32x4_codec_clkin_get_parent, -+}; -+ - static struct aic32x4_clkdesc aic32x4_clkdesc_array[] = { - { - .name = "pll", -@@ -274,6 +298,14 @@ static struct aic32x4_clkdesc aic32x4_cl - .ops = &aic32x4_pll_ops, - .reg = 0, - }, -+ { -+ .name = "codec_clkin", -+ .parent_names = -+ (const char *[]) { "mclk", "bclk", "gpio", "pll" }, -+ .num_parents = 4, -+ .ops = &aic32x4_codec_clkin_ops, -+ .reg = 0, -+ }, - }; - - static struct clk *aic32x4_register_clk(struct device *dev, -@@ -314,6 +346,8 @@ int aic32x4_register_clocks(struct devic - */ - aic32x4_clkdesc_array[0].parent_names = - (const char* []) { mclk_name, "bclk", "gpio", "din" }; -+ aic32x4_clkdesc_array[1].parent_names = -+ (const char *[]) { mclk_name, "bclk", "gpio", "pll" }; - - for (i = 0; i < ARRAY_SIZE(aic32x4_clkdesc_array); ++i) - aic32x4_register_clk(dev, &aic32x4_clkdesc_array[i]); ---- a/sound/soc/codecs/tlv320aic32x4.c -+++ b/sound/soc/codecs/tlv320aic32x4.c -@@ -737,12 +737,9 @@ static int aic32x4_setup_clocks(struct s - - aic32x4_set_processing_blocks(component, aic32x4_divs[i].r_block, aic32x4_divs[i].p_block); - -- /* PLL as CODEC_CLKIN */ -- snd_soc_component_update_bits(component, AIC32X4_CLKMUX, -- AIC32X4_CODEC_CLKIN_MASK, -- AIC32X4_CODEC_CLKIN_PLL << AIC32X4_CODEC_CLKIN_SHIFT); - /* DAC_MOD_CLK as BDIV_CLKIN */ -- snd_soc_component_update_bits(component, AIC32X4_IFACE3, AIC32X4_BDIVCLK_MASK, -+ snd_soc_component_update_bits(component, AIC32X4_IFACE3, -+ AIC32X4_BDIVCLK_MASK, - AIC32X4_DACMOD2BCLK << AIC32X4_BDIVCLK_SHIFT); - - /* NDAC divider value */ -@@ -989,6 +986,15 @@ static int aic32x4_component_probe(struc - { - struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component); - u32 tmp_reg; -+ int ret; -+ -+ struct clk_bulk_data clocks[] = { -+ { .id = "codec_clkin" }, -+ }; -+ -+ ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks); -+ if (ret) -+ return ret; - - if (gpio_is_valid(aic32x4->rstn_gpio)) { - ndelay(10); -@@ -1000,6 +1006,8 @@ static int aic32x4_component_probe(struc - if (aic32x4->setup) - aic32x4_setup_gpios(component); - -+ clk_set_parent(clocks[0].clk, clocks[1].clk); -+ - /* Power platform configuration */ - if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) { - snd_soc_component_write(component, AIC32X4_MICBIAS, diff --git a/target/linux/brcm2708/patches-4.19/950-0407-ASoC-tlv320aic32x4-Model-DAC-ADC-dividers-in-CCF.patch b/target/linux/brcm2708/patches-4.19/950-0407-ASoC-tlv320aic32x4-Model-DAC-ADC-dividers-in-CCF.patch deleted file mode 100644 index a4c3e1c0f4..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0407-ASoC-tlv320aic32x4-Model-DAC-ADC-dividers-in-CCF.patch +++ /dev/null @@ -1,306 +0,0 @@ -From 532403e3a16502340711131fd075cd7dd4dd20b1 Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Thu, 21 Mar 2019 17:58:47 -0700 -Subject: [PATCH 407/703] ASoC: tlv320aic32x4: Model DAC/ADC dividers in CCF - -commit a51b50062091619915c5155085bbe13a7aca6903 upstream. - -Model and manage DAC/ADC dividers as components in the Core -Clock Framework. This should allow us to do some more complex -clock management and power control. Also, some of the -on-board chip clocks can be exposed to the outside, and this -change will make those clocks easier to consume by other -parts of the kernel. - -Signed-off-by: Annaliese McDermond -Signed-off-by: Mark Brown ---- - sound/soc/codecs/tlv320aic32x4-clk.c | 90 ++++++++++++++++++++++++ - sound/soc/codecs/tlv320aic32x4.c | 101 +++++++++++++++------------ - sound/soc/codecs/tlv320aic32x4.h | 4 ++ - 3 files changed, 151 insertions(+), 44 deletions(-) - ---- a/sound/soc/codecs/tlv320aic32x4-clk.c -+++ b/sound/soc/codecs/tlv320aic32x4-clk.c -@@ -289,6 +289,68 @@ static const struct clk_ops aic32x4_code - .get_parent = clk_aic32x4_codec_clkin_get_parent, - }; - -+static int clk_aic32x4_div_prepare(struct clk_hw *hw) -+{ -+ struct clk_aic32x4 *div = to_clk_aic32x4(hw); -+ -+ return regmap_update_bits(div->regmap, div->reg, -+ AIC32X4_DIVEN, AIC32X4_DIVEN); -+} -+ -+static void clk_aic32x4_div_unprepare(struct clk_hw *hw) -+{ -+ struct clk_aic32x4 *div = to_clk_aic32x4(hw); -+ -+ regmap_update_bits(div->regmap, div->reg, -+ AIC32X4_DIVEN, 0); -+} -+ -+static int clk_aic32x4_div_set_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long parent_rate) -+{ -+ struct clk_aic32x4 *div = to_clk_aic32x4(hw); -+ u8 divisor; -+ -+ divisor = DIV_ROUND_UP(parent_rate, rate); -+ if (divisor > 128) -+ return -EINVAL; -+ -+ return regmap_update_bits(div->regmap, div->reg, -+ AIC32X4_DIV_MASK, divisor); -+} -+ -+static long clk_aic32x4_div_round_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long *parent_rate) -+{ -+ unsigned long divisor; -+ -+ divisor = DIV_ROUND_UP(*parent_rate, rate); -+ if (divisor > 128) -+ return -EINVAL; -+ -+ return DIV_ROUND_UP(*parent_rate, divisor); -+} -+ -+static unsigned long clk_aic32x4_div_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ struct clk_aic32x4 *div = to_clk_aic32x4(hw); -+ -+ unsigned int val; -+ -+ regmap_read(div->regmap, div->reg, &val); -+ -+ return DIV_ROUND_UP(parent_rate, val & AIC32X4_DIV_MASK); -+} -+ -+static const struct clk_ops aic32x4_div_ops = { -+ .prepare = clk_aic32x4_div_prepare, -+ .unprepare = clk_aic32x4_div_unprepare, -+ .set_rate = clk_aic32x4_div_set_rate, -+ .round_rate = clk_aic32x4_div_round_rate, -+ .recalc_rate = clk_aic32x4_div_recalc_rate, -+}; -+ - static struct aic32x4_clkdesc aic32x4_clkdesc_array[] = { - { - .name = "pll", -@@ -306,6 +368,34 @@ static struct aic32x4_clkdesc aic32x4_cl - .ops = &aic32x4_codec_clkin_ops, - .reg = 0, - }, -+ { -+ .name = "ndac", -+ .parent_names = (const char * []) { "codec_clkin" }, -+ .num_parents = 1, -+ .ops = &aic32x4_div_ops, -+ .reg = AIC32X4_NDAC, -+ }, -+ { -+ .name = "mdac", -+ .parent_names = (const char * []) { "ndac" }, -+ .num_parents = 1, -+ .ops = &aic32x4_div_ops, -+ .reg = AIC32X4_MDAC, -+ }, -+ { -+ .name = "nadc", -+ .parent_names = (const char * []) { "codec_clkin" }, -+ .num_parents = 1, -+ .ops = &aic32x4_div_ops, -+ .reg = AIC32X4_NADC, -+ }, -+ { -+ .name = "madc", -+ .parent_names = (const char * []) { "nadc" }, -+ .num_parents = 1, -+ .ops = &aic32x4_div_ops, -+ .reg = AIC32X4_MADC, -+ }, - }; - - static struct clk *aic32x4_register_clk(struct device *dev, ---- a/sound/soc/codecs/tlv320aic32x4.c -+++ b/sound/soc/codecs/tlv320aic32x4.c -@@ -52,11 +52,11 @@ struct aic32x4_rate_divs { - u32 rate; - unsigned long pll_rate; - u16 dosr; -- u8 ndac; -- u8 mdac; -+ unsigned long ndac_rate; -+ unsigned long mdac_rate; - u8 aosr; -- u8 nadc; -- u8 madc; -+ unsigned long nadc_rate; -+ unsigned long madc_rate; - u8 blck_N; - u8 r_block; - u8 p_block; -@@ -309,34 +309,54 @@ static const struct snd_kcontrol_new aic - - static const struct aic32x4_rate_divs aic32x4_divs[] = { - /* 8k rate */ -- { 12000000, 8000, 57120000, 768, 5, 3, 128, 5, 18, 24, 1, 1 }, -- { 24000000, 8000, 57120000, 768, 15, 1, 64, 45, 4, 24, 1, 1 }, -- { 25000000, 8000, 32620000, 768, 15, 1, 64, 45, 4, 24, 1, 1 }, -+ { 12000000, 8000, 57120000, 768, 18432000, 6144000, 128, 18432000, -+ 1024000, 24, 1, 1 }, -+ { 24000000, 8000, 57120000, 768, 6144000, 6144000, 64, 2048000, -+ 512000, 24, 1, 1 }, -+ { 25000000, 8000, 32620000, 768, 6144000, 6144000, 64, 2048000, -+ 512000, 24, 1, 1 }, - /* 11.025k rate */ -- { 12000000, 11025, 44217600, 512, 8, 2, 128, 8, 8, 16, 1, 1 }, -- { 24000000, 11025, 44217600, 512, 16, 1, 64, 32, 4, 16, 1, 1 }, -+ { 12000000, 11025, 44217600, 512, 11289600, 5644800, 128, 11289600, -+ 1411200, 16, 1, 1 }, -+ { 24000000, 11025, 44217600, 512, 5644800, 5644800, 64, 2822400, -+ 705600, 16, 1, 1 }, - /* 16k rate */ -- { 12000000, 16000, 57120000, 384, 5, 3, 128, 5, 9, 12, 1, 1 }, -- { 24000000, 16000, 57120000, 384, 15, 1, 64, 18, 5, 12, 1, 1 }, -- { 25000000, 16000, 32620000, 384, 15, 1, 64, 18, 5, 12, 1, 1 }, -+ { 12000000, 16000, 57120000, 384, 18432000, 6144000, 128, 18432000, -+ 2048000, 12, 1, 1 }, -+ { 24000000, 16000, 57120000, 384, 6144000, 6144000, 64, 5120000, -+ 1024000, 12, 1, 1 }, -+ { 25000000, 16000, 32620000, 384, 6144000, 6144000, 64, 5120000, -+ 1024000, 12, 1, 1 }, - /* 22.05k rate */ -- { 12000000, 22050, 44217600, 256, 4, 4, 128, 4, 8, 8, 1, 1 }, -- { 24000000, 22050, 44217600, 256, 16, 1, 64, 16, 4, 8, 1, 1 }, -- { 25000000, 22050, 19713750, 256, 16, 1, 64, 16, 4, 8, 1, 1 }, -+ { 12000000, 22050, 44217600, 256, 22579200, 5644800, 128, 22579200, -+ 2822400, 8, 1, 1 }, -+ { 24000000, 22050, 44217600, 256, 5644800, 5644800, 64, 5644800, -+ 1411200, 8, 1, 1 }, -+ { 25000000, 22050, 19713750, 256, 5644800, 5644800, 64, 5644800, -+ 1411200, 8, 1, 1 }, - /* 32k rate */ -- { 12000000, 32000, 14112000, 192, 2, 7, 64, 2, 21, 6, 1, 1 }, -- { 24000000, 32000, 14112000, 192, 7, 2, 64, 7, 6, 6, 1, 1 }, -+ { 12000000, 32000, 14112000, 192, 43008000, 6144000, 64, 43008000, -+ 2048000, 6, 1, 1 }, -+ { 24000000, 32000, 14112000, 192, 12288000, 6144000, 64, 12288000, -+ 2048000, 6, 1, 1 }, - /* 44.1k rate */ -- { 12000000, 44100, 44217600, 128, 2, 8, 128, 2, 8, 4, 1, 1 }, -- { 24000000, 44100, 44217600, 128, 8, 2, 64, 8, 4, 4, 1, 1 }, -- { 25000000, 44100, 19713750, 128, 8, 2, 64, 8, 4, 4, 1, 1 }, -+ { 12000000, 44100, 44217600, 128, 45158400, 5644800, 128, 45158400, -+ 5644800, 4, 1, 1 }, -+ { 24000000, 44100, 44217600, 128, 11289600, 5644800, 64, 11289600, -+ 2822400, 4, 1, 1 }, -+ { 25000000, 44100, 19713750, 128, 11289600, 5644800, 64, 11289600, -+ 2822400, 4, 1, 1 }, - /* 48k rate */ -- { 12000000, 48000, 18432000, 128, 2, 8, 128, 2, 8, 4, 1, 1 }, -- { 24000000, 48000, 18432000, 128, 8, 2, 64, 8, 4, 4, 1, 1 }, -- { 25000000, 48000, 75626250, 128, 8, 2, 64, 8, 4, 4, 1, 1 }, -+ { 12000000, 48000, 18432000, 128, 49152000, 6144000, 128, 49152000, -+ 6144000, 4, 1, 1 }, -+ { 24000000, 48000, 18432000, 128, 12288000, 6144000, 64, 12288000, -+ 3072000, 4, 1, 1 }, -+ { 25000000, 48000, 75626250, 128, 12288000, 6144000, 64, 12288000, -+ 3072000, 4, 1, 1 }, - - /* 96k rate */ -- { 25000000, 96000, 75626250, 64, 4, 4, 64, 4, 4, 1, 1, 9 }, -+ { 25000000, 96000, 75626250, 64, 24576000, 6144000, 64, 24576000, -+ 6144000, 1, 1, 9 }, - }; - - static const struct snd_kcontrol_new hpl_output_mixer_controls[] = { -@@ -721,6 +741,10 @@ static int aic32x4_setup_clocks(struct s - - struct clk_bulk_data clocks[] = { - { .id = "pll" }, -+ { .id = "nadc" }, -+ { .id = "madc" }, -+ { .id = "ndac" }, -+ { .id = "mdac" }, - }; - - i = aic32x4_get_divs(parent_rate, sample_rate); -@@ -733,7 +757,11 @@ static int aic32x4_setup_clocks(struct s - if (ret) - return ret; - -- clk_set_rate(clocks[0].clk, sample_rate); -+ clk_set_rate(clocks[0].clk, aic32x4_divs[i].pll_rate); -+ clk_set_rate(clocks[1].clk, aic32x4_divs[i].nadc_rate); -+ clk_set_rate(clocks[2].clk, aic32x4_divs[i].madc_rate); -+ clk_set_rate(clocks[3].clk, aic32x4_divs[i].ndac_rate); -+ clk_set_rate(clocks[4].clk, aic32x4_divs[i].mdac_rate); - - aic32x4_set_processing_blocks(component, aic32x4_divs[i].r_block, aic32x4_divs[i].p_block); - -@@ -742,26 +770,10 @@ static int aic32x4_setup_clocks(struct s - AIC32X4_BDIVCLK_MASK, - AIC32X4_DACMOD2BCLK << AIC32X4_BDIVCLK_SHIFT); - -- /* NDAC divider value */ -- snd_soc_component_update_bits(component, AIC32X4_NDAC, -- AIC32X4_NDAC_MASK, aic32x4_divs[i].ndac); -- -- /* MDAC divider value */ -- snd_soc_component_update_bits(component, AIC32X4_MDAC, -- AIC32X4_MDAC_MASK, aic32x4_divs[i].mdac); -- - /* DOSR MSB & LSB values */ - snd_soc_component_write(component, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8); - snd_soc_component_write(component, AIC32X4_DOSRLSB, (aic32x4_divs[i].dosr & 0xff)); - -- /* NADC divider value */ -- snd_soc_component_update_bits(component, AIC32X4_NADC, -- AIC32X4_NADC_MASK, aic32x4_divs[i].nadc); -- -- /* MADC divider value */ -- snd_soc_component_update_bits(component, AIC32X4_MADC, -- AIC32X4_MADC_MASK, aic32x4_divs[i].madc); -- - /* AOSR value */ - snd_soc_component_write(component, AIC32X4_AOSR, aic32x4_divs[i].aosr); - -@@ -773,8 +785,8 @@ static int aic32x4_setup_clocks(struct s - } - - static int aic32x4_hw_params(struct snd_pcm_substream *substream, -- struct snd_pcm_hw_params *params, -- struct snd_soc_dai *dai) -+ struct snd_pcm_hw_params *params, -+ struct snd_soc_dai *dai) - { - struct snd_soc_component *component = dai->component; - struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component); -@@ -989,7 +1001,8 @@ static int aic32x4_component_probe(struc - int ret; - - struct clk_bulk_data clocks[] = { -- { .id = "codec_clkin" }, -+ { .id = "codec_clkin" }, -+ { .id = "pll" }, - }; - - ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks); ---- a/sound/soc/codecs/tlv320aic32x4.h -+++ b/sound/soc/codecs/tlv320aic32x4.h -@@ -206,6 +206,10 @@ int aic32x4_register_clocks(struct devic - #define AIC32X4_RMICPGANIN_IN1L_10K 0x10 - #define AIC32X4_RMICPGANIN_CM1R_10K 0x40 - -+/* Common mask and enable for all of the dividers */ -+#define AIC32X4_DIVEN BIT(7) -+#define AIC32X4_DIV_MASK GENMASK(6, 0) -+ - /* Clock Limits */ - #define AIC32X4_MAX_PLL_CLKIN 20000000 - diff --git a/target/linux/brcm2708/patches-4.19/950-0407-ASoC-tlv320aic32x4-Move-aosr-and-dosr-setting-to-sep.patch b/target/linux/brcm2708/patches-4.19/950-0407-ASoC-tlv320aic32x4-Move-aosr-and-dosr-setting-to-sep.patch new file mode 100644 index 0000000000..65518cf637 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0407-ASoC-tlv320aic32x4-Move-aosr-and-dosr-setting-to-sep.patch @@ -0,0 +1,58 @@ +From 8c49a3384501933c9919a44504b4f3148a16320a Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Thu, 21 Mar 2019 17:58:50 -0700 +Subject: [PATCH 407/725] ASoC: tlv320aic32x4: Move aosr and dosr setting to + separate functions + +commit fbafbf6517274a797e6e6508c18dd8dba5920c89 upstream. + +Move these to separate helper functions. This looks cleaner and fits +better with the new clock setting in CCF. + +Signed-off-by: Annaliese McDermond +Signed-off-by: Mark Brown +--- + sound/soc/codecs/tlv320aic32x4.c | 24 +++++++++++++++++------- + 1 file changed, 17 insertions(+), 7 deletions(-) + +--- a/sound/soc/codecs/tlv320aic32x4.c ++++ b/sound/soc/codecs/tlv320aic32x4.c +@@ -720,6 +720,20 @@ static int aic32x4_set_dai_fmt(struct sn + return 0; + } + ++static int aic32x4_set_aosr(struct snd_soc_component *component, u8 aosr) ++{ ++ return snd_soc_component_write(component, AIC32X4_AOSR, aosr); ++} ++ ++static int aic32x4_set_dosr(struct snd_soc_component *component, u16 dosr) ++{ ++ snd_soc_component_write(component, AIC32X4_DOSRMSB, dosr >> 8); ++ snd_soc_component_write(component, AIC32X4_DOSRLSB, ++ (dosr & 0xff)); ++ ++ return 0; ++} ++ + static int aic32x4_set_processing_blocks(struct snd_soc_component *component, + u8 r_block, u8 p_block) + { +@@ -765,14 +779,10 @@ static int aic32x4_setup_clocks(struct s + clk_set_rate(clocks[4].clk, aic32x4_divs[i].mdac_rate); + clk_set_rate(clocks[5].clk, aic32x4_divs[i].bdiv_rate); + +- aic32x4_set_processing_blocks(component, aic32x4_divs[i].r_block, aic32x4_divs[i].p_block); ++ aic32x4_set_aosr(component, aic32x4_divs[i].aosr); ++ aic32x4_set_dosr(component, aic32x4_divs[i].dosr); + +- /* DOSR MSB & LSB values */ +- snd_soc_component_write(component, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8); +- snd_soc_component_write(component, AIC32X4_DOSRLSB, (aic32x4_divs[i].dosr & 0xff)); +- +- /* AOSR value */ +- snd_soc_component_write(component, AIC32X4_AOSR, aic32x4_divs[i].aosr); ++ aic32x4_set_processing_blocks(component, aic32x4_divs[i].r_block, aic32x4_divs[i].p_block); + + return 0; + } diff --git a/target/linux/brcm2708/patches-4.19/950-0408-ASoC-tlv320aic32x4-Dynamically-Determine-Clocking.patch b/target/linux/brcm2708/patches-4.19/950-0408-ASoC-tlv320aic32x4-Dynamically-Determine-Clocking.patch new file mode 100644 index 0000000000..61113fd903 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0408-ASoC-tlv320aic32x4-Dynamically-Determine-Clocking.patch @@ -0,0 +1,285 @@ +From d246d5e5edb858db81b72b58c1f2ef0f0b15fb97 Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Thu, 21 Mar 2019 17:58:51 -0700 +Subject: [PATCH 408/725] ASoC: tlv320aic32x4: Dynamically Determine Clocking + +commit 96c3bb00239de4fb5f4ddca42c1f90d6d9b3c697 upstream. + +The existing code uses a static lookup table to determine the +settings of the various clock devices on board the chip. This is +limiting in a couple of ways. First, this doesn't allow for any +master clock rates other than the three that have been +precalculated. Additionally, new sample rates are difficult to +add to the table. Witness that the chip is capable of 192000 Hz +sampling, but it is not provided by this driver. Last, if the +driver is clocked by something that isn't a crystal, the +upstream clock may not be able to achieve exactly the rate +requested in the driver. This will mean that clocking will be +slightly off for the sampling clock or that it won't work at all. + +This patch determines the settings for all of the clocks at +runtime considering the real conditions of the clocks in the +system. The rules for the clocks are in TI's SLAA557 application +guide on pages 37, 51 and 77. + +Signed-off-by: Annaliese McDermond +Signed-off-by: Mark Brown +--- + sound/soc/codecs/tlv320aic32x4.c | 190 ++++++++++++++----------------- + sound/soc/codecs/tlv320aic32x4.h | 4 +- + 2 files changed, 90 insertions(+), 104 deletions(-) + +--- a/sound/soc/codecs/tlv320aic32x4.c ++++ b/sound/soc/codecs/tlv320aic32x4.c +@@ -47,21 +47,6 @@ + + #include "tlv320aic32x4.h" + +-struct aic32x4_rate_divs { +- u32 mclk; +- u32 rate; +- unsigned long pll_rate; +- u16 dosr; +- unsigned long ndac_rate; +- unsigned long mdac_rate; +- u8 aosr; +- unsigned long nadc_rate; +- unsigned long madc_rate; +- unsigned long bdiv_rate; +- u8 r_block; +- u8 p_block; +-}; +- + struct aic32x4_priv { + struct regmap *regmap; + u32 sysclk; +@@ -307,58 +292,6 @@ static const struct snd_kcontrol_new aic + 0, 0x0F, 0), + }; + +-static const struct aic32x4_rate_divs aic32x4_divs[] = { +- /* 8k rate */ +- { 12000000, 8000, 57120000, 768, 18432000, 6144000, 128, 18432000, +- 1024000, 256000, 1, 1 }, +- { 24000000, 8000, 57120000, 768, 6144000, 6144000, 64, 2048000, +- 512000, 256000, 1, 1 }, +- { 25000000, 8000, 32620000, 768, 6144000, 6144000, 64, 2048000, +- 512000, 256000, 1, 1 }, +- /* 11.025k rate */ +- { 12000000, 11025, 44217600, 512, 11289600, 5644800, 128, 11289600, +- 1411200, 352800, 1, 1 }, +- { 24000000, 11025, 44217600, 512, 5644800, 5644800, 64, 2822400, +- 705600, 352800, 1, 1 }, +- /* 16k rate */ +- { 12000000, 16000, 57120000, 384, 18432000, 6144000, 128, 18432000, +- 2048000, 512000, 1, 1 }, +- { 24000000, 16000, 57120000, 384, 6144000, 6144000, 64, 5120000, +- 1024000, 512000, 1, 1 }, +- { 25000000, 16000, 32620000, 384, 6144000, 6144000, 64, 5120000, +- 1024000, 512000, 1, 1 }, +- /* 22.05k rate */ +- { 12000000, 22050, 44217600, 256, 22579200, 5644800, 128, 22579200, +- 2822400, 705600, 1, 1 }, +- { 24000000, 22050, 44217600, 256, 5644800, 5644800, 64, 5644800, +- 1411200, 705600, 1, 1 }, +- { 25000000, 22050, 19713750, 256, 5644800, 5644800, 64, 5644800, +- 1411200, 705600, 1, 1 }, +- /* 32k rate */ +- { 12000000, 32000, 14112000, 192, 43008000, 6144000, 64, 43008000, +- 2048000, 1024000, 1, 1 }, +- { 24000000, 32000, 14112000, 192, 12288000, 6144000, 64, 12288000, +- 2048000, 1024000, 1, 1 }, +- /* 44.1k rate */ +- { 12000000, 44100, 44217600, 128, 45158400, 5644800, 128, 45158400, +- 5644800, 1411200, 1, 1 }, +- { 24000000, 44100, 44217600, 128, 11289600, 5644800, 64, 11289600, +- 2822400, 1411200, 1, 1 }, +- { 25000000, 44100, 19713750, 128, 11289600, 5644800, 64, 11289600, +- 2822400, 1411200, 1, 1 }, +- /* 48k rate */ +- { 12000000, 48000, 18432000, 128, 49152000, 6144000, 128, 49152000, +- 6144000, 1536000, 1, 1 }, +- { 24000000, 48000, 18432000, 128, 12288000, 6144000, 64, 12288000, +- 3072000, 1536000, 1, 1 }, +- { 25000000, 48000, 75626250, 128, 12288000, 6144000, 64, 12288000, +- 3072000, 1536000, 1, 1 }, +- +- /* 96k rate */ +- { 25000000, 96000, 75626250, 64, 24576000, 6144000, 64, 24576000, +- 6144000, 3072000, 1, 9 }, +-}; +- + static const struct snd_kcontrol_new hpl_output_mixer_controls[] = { + SOC_DAPM_SINGLE("L_DAC Switch", AIC32X4_HPLROUTE, 3, 1, 0), + SOC_DAPM_SINGLE("IN1_L Switch", AIC32X4_HPLROUTE, 2, 1, 0), +@@ -632,20 +565,6 @@ const struct regmap_config aic32x4_regma + }; + EXPORT_SYMBOL(aic32x4_regmap_config); + +-static inline int aic32x4_get_divs(int mclk, int rate) +-{ +- int i; +- +- for (i = 0; i < ARRAY_SIZE(aic32x4_divs); i++) { +- if ((aic32x4_divs[i].rate == rate) +- && (aic32x4_divs[i].mclk == mclk)) { +- return i; +- } +- } +- printk(KERN_ERR "aic32x4: master clock and sample rate is not supported\n"); +- return -EINVAL; +-} +- + static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) + { +@@ -747,11 +666,17 @@ static int aic32x4_set_processing_blocks + } + + static int aic32x4_setup_clocks(struct snd_soc_component *component, +- unsigned int sample_rate, +- unsigned int parent_rate) ++ unsigned int sample_rate) + { +- int i; ++ u8 aosr; ++ u16 dosr; ++ u8 adc_resource_class, dac_resource_class; ++ u8 madc, nadc, mdac, ndac, max_nadc, min_mdac, max_ndac; ++ u8 dosr_increment; ++ u16 max_dosr, min_dosr; ++ unsigned long mclk_rate, adc_clock_rate, dac_clock_rate; + int ret; ++ struct clk *mclk; + + struct clk_bulk_data clocks[] = { + { .id = "pll" }, +@@ -761,30 +686,89 @@ static int aic32x4_setup_clocks(struct s + { .id = "mdac" }, + { .id = "bdiv" }, + }; +- +- i = aic32x4_get_divs(parent_rate, sample_rate); +- if (i < 0) { +- printk(KERN_ERR "aic32x4: sampling rate not supported\n"); +- return i; +- } +- + ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks); + if (ret) + return ret; + +- clk_set_rate(clocks[0].clk, aic32x4_divs[i].pll_rate); +- clk_set_rate(clocks[1].clk, aic32x4_divs[i].nadc_rate); +- clk_set_rate(clocks[2].clk, aic32x4_divs[i].madc_rate); +- clk_set_rate(clocks[3].clk, aic32x4_divs[i].ndac_rate); +- clk_set_rate(clocks[4].clk, aic32x4_divs[i].mdac_rate); +- clk_set_rate(clocks[5].clk, aic32x4_divs[i].bdiv_rate); ++ mclk = clk_get_parent(clocks[1].clk); ++ mclk_rate = clk_get_rate(mclk); + +- aic32x4_set_aosr(component, aic32x4_divs[i].aosr); +- aic32x4_set_dosr(component, aic32x4_divs[i].dosr); ++ if (sample_rate <= 48000) { ++ aosr = 128; ++ adc_resource_class = 6; ++ dac_resource_class = 8; ++ dosr_increment = 8; ++ aic32x4_set_processing_blocks(component, 1, 1); ++ } else if (sample_rate <= 96000) { ++ aosr = 64; ++ adc_resource_class = 6; ++ dac_resource_class = 8; ++ dosr_increment = 4; ++ aic32x4_set_processing_blocks(component, 1, 9); ++ } else if (sample_rate == 192000) { ++ aosr = 32; ++ adc_resource_class = 3; ++ dac_resource_class = 4; ++ dosr_increment = 2; ++ aic32x4_set_processing_blocks(component, 13, 19); ++ } else { ++ dev_err(component->dev, "Sampling rate not supported\n"); ++ return -EINVAL; ++ } + +- aic32x4_set_processing_blocks(component, aic32x4_divs[i].r_block, aic32x4_divs[i].p_block); ++ madc = DIV_ROUND_UP((32 * adc_resource_class), aosr); ++ max_dosr = (AIC32X4_MAX_DOSR_FREQ / sample_rate / dosr_increment) * ++ dosr_increment; ++ min_dosr = (AIC32X4_MIN_DOSR_FREQ / sample_rate / dosr_increment) * ++ dosr_increment; ++ max_nadc = AIC32X4_MAX_CODEC_CLKIN_FREQ / (madc * aosr * sample_rate); ++ ++ for (nadc = max_nadc; nadc > 0; --nadc) { ++ adc_clock_rate = nadc * madc * aosr * sample_rate; ++ for (dosr = max_dosr; dosr >= min_dosr; ++ dosr -= dosr_increment) { ++ min_mdac = DIV_ROUND_UP((32 * dac_resource_class), dosr); ++ max_ndac = AIC32X4_MAX_CODEC_CLKIN_FREQ / ++ (min_mdac * dosr * sample_rate); ++ for (mdac = min_mdac; mdac <= 128; ++mdac) { ++ for (ndac = max_ndac; ndac > 0; --ndac) { ++ dac_clock_rate = ndac * mdac * dosr * ++ sample_rate; ++ if (dac_clock_rate == adc_clock_rate) { ++ if (clk_round_rate(clocks[0].clk, dac_clock_rate) == 0) ++ continue; ++ ++ clk_set_rate(clocks[0].clk, ++ dac_clock_rate); ++ ++ clk_set_rate(clocks[1].clk, ++ sample_rate * aosr * ++ madc); ++ clk_set_rate(clocks[2].clk, ++ sample_rate * aosr); ++ aic32x4_set_aosr(component, ++ aosr); ++ ++ clk_set_rate(clocks[3].clk, ++ sample_rate * dosr * ++ mdac); ++ clk_set_rate(clocks[4].clk, ++ sample_rate * dosr); ++ aic32x4_set_dosr(component, ++ dosr); ++ ++ clk_set_rate(clocks[5].clk, ++ sample_rate * 32); ++ return 0; ++ } ++ } ++ } ++ } ++ } + +- return 0; ++ dev_err(component->dev, ++ "Could not set clocks to support sample rate.\n"); ++ return -EINVAL; + } + + static int aic32x4_hw_params(struct snd_pcm_substream *substream, +@@ -796,7 +780,7 @@ static int aic32x4_hw_params(struct snd_ + u8 iface1_reg = 0; + u8 dacsetup_reg = 0; + +- aic32x4_setup_clocks(component, params_rate(params), aic32x4->sysclk); ++ aic32x4_setup_clocks(component, params_rate(params)); + + switch (params_width(params)) { + case 16: +--- a/sound/soc/codecs/tlv320aic32x4.h ++++ b/sound/soc/codecs/tlv320aic32x4.h +@@ -211,7 +211,9 @@ int aic32x4_register_clocks(struct devic + #define AIC32X4_DIV_MASK GENMASK(6, 0) + + /* Clock Limits */ ++#define AIC32X4_MAX_DOSR_FREQ 6200000 ++#define AIC32X4_MIN_DOSR_FREQ 2800000 ++#define AIC32X4_MAX_CODEC_CLKIN_FREQ 110000000 + #define AIC32X4_MAX_PLL_CLKIN 20000000 + +- + #endif /* _TLV320AIC32X4_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0408-ASoC-tlv320aic32x4-Model-BDIV-divider-in-CCF.patch b/target/linux/brcm2708/patches-4.19/950-0408-ASoC-tlv320aic32x4-Model-BDIV-divider-in-CCF.patch deleted file mode 100644 index 41e5e4bfd2..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0408-ASoC-tlv320aic32x4-Model-BDIV-divider-in-CCF.patch +++ /dev/null @@ -1,210 +0,0 @@ -From f057c2ccc9c5fddca55fb42032395cf355f918e8 Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Thu, 21 Mar 2019 17:58:48 -0700 -Subject: [PATCH 408/703] ASoC: tlv320aic32x4: Model BDIV divider in CCF - -commit 9b484124ebd906c4d6bc826cc0d417e80cc1105c upstream. - -Model and manage BDIV divider as components in the Core -Clock Framework. This should allow us to do some more complex -clock management and power control. Also, some of the -on-board chip clocks can be exposed to the outside, and this -change will make those clocks easier to consume by other -parts of the kernel. - -Signed-off-by: Annaliese McDermond -Signed-off-by: Mark Brown ---- - sound/soc/codecs/tlv320aic32x4-clk.c | 36 ++++++++++++++++++ - sound/soc/codecs/tlv320aic32x4.c | 56 +++++++++++++--------------- - 2 files changed, 62 insertions(+), 30 deletions(-) - ---- a/sound/soc/codecs/tlv320aic32x4-clk.c -+++ b/sound/soc/codecs/tlv320aic32x4-clk.c -@@ -351,6 +351,34 @@ static const struct clk_ops aic32x4_div_ - .recalc_rate = clk_aic32x4_div_recalc_rate, - }; - -+static int clk_aic32x4_bdiv_set_parent(struct clk_hw *hw, u8 index) -+{ -+ struct clk_aic32x4 *mux = to_clk_aic32x4(hw); -+ -+ return regmap_update_bits(mux->regmap, AIC32X4_IFACE3, -+ AIC32X4_BDIVCLK_MASK, index); -+} -+ -+static u8 clk_aic32x4_bdiv_get_parent(struct clk_hw *hw) -+{ -+ struct clk_aic32x4 *mux = to_clk_aic32x4(hw); -+ unsigned int val; -+ -+ regmap_read(mux->regmap, AIC32X4_IFACE3, &val); -+ -+ return val & AIC32X4_BDIVCLK_MASK; -+} -+ -+static const struct clk_ops aic32x4_bdiv_ops = { -+ .prepare = clk_aic32x4_div_prepare, -+ .unprepare = clk_aic32x4_div_unprepare, -+ .set_parent = clk_aic32x4_bdiv_set_parent, -+ .get_parent = clk_aic32x4_bdiv_get_parent, -+ .set_rate = clk_aic32x4_div_set_rate, -+ .round_rate = clk_aic32x4_div_round_rate, -+ .recalc_rate = clk_aic32x4_div_recalc_rate, -+}; -+ - static struct aic32x4_clkdesc aic32x4_clkdesc_array[] = { - { - .name = "pll", -@@ -396,6 +424,14 @@ static struct aic32x4_clkdesc aic32x4_cl - .ops = &aic32x4_div_ops, - .reg = AIC32X4_MADC, - }, -+ { -+ .name = "bdiv", -+ .parent_names = -+ (const char *[]) { "ndac", "mdac", "nadc", "madc" }, -+ .num_parents = 4, -+ .ops = &aic32x4_bdiv_ops, -+ .reg = AIC32X4_BCLKN, -+ }, - }; - - static struct clk *aic32x4_register_clk(struct device *dev, ---- a/sound/soc/codecs/tlv320aic32x4.c -+++ b/sound/soc/codecs/tlv320aic32x4.c -@@ -57,7 +57,7 @@ struct aic32x4_rate_divs { - u8 aosr; - unsigned long nadc_rate; - unsigned long madc_rate; -- u8 blck_N; -+ unsigned long bdiv_rate; - u8 r_block; - u8 p_block; - }; -@@ -310,53 +310,53 @@ static const struct snd_kcontrol_new aic - static const struct aic32x4_rate_divs aic32x4_divs[] = { - /* 8k rate */ - { 12000000, 8000, 57120000, 768, 18432000, 6144000, 128, 18432000, -- 1024000, 24, 1, 1 }, -+ 1024000, 256000, 1, 1 }, - { 24000000, 8000, 57120000, 768, 6144000, 6144000, 64, 2048000, -- 512000, 24, 1, 1 }, -+ 512000, 256000, 1, 1 }, - { 25000000, 8000, 32620000, 768, 6144000, 6144000, 64, 2048000, -- 512000, 24, 1, 1 }, -+ 512000, 256000, 1, 1 }, - /* 11.025k rate */ - { 12000000, 11025, 44217600, 512, 11289600, 5644800, 128, 11289600, -- 1411200, 16, 1, 1 }, -+ 1411200, 352800, 1, 1 }, - { 24000000, 11025, 44217600, 512, 5644800, 5644800, 64, 2822400, -- 705600, 16, 1, 1 }, -+ 705600, 352800, 1, 1 }, - /* 16k rate */ - { 12000000, 16000, 57120000, 384, 18432000, 6144000, 128, 18432000, -- 2048000, 12, 1, 1 }, -+ 2048000, 512000, 1, 1 }, - { 24000000, 16000, 57120000, 384, 6144000, 6144000, 64, 5120000, -- 1024000, 12, 1, 1 }, -+ 1024000, 512000, 1, 1 }, - { 25000000, 16000, 32620000, 384, 6144000, 6144000, 64, 5120000, -- 1024000, 12, 1, 1 }, -+ 1024000, 512000, 1, 1 }, - /* 22.05k rate */ - { 12000000, 22050, 44217600, 256, 22579200, 5644800, 128, 22579200, -- 2822400, 8, 1, 1 }, -+ 2822400, 705600, 1, 1 }, - { 24000000, 22050, 44217600, 256, 5644800, 5644800, 64, 5644800, -- 1411200, 8, 1, 1 }, -+ 1411200, 705600, 1, 1 }, - { 25000000, 22050, 19713750, 256, 5644800, 5644800, 64, 5644800, -- 1411200, 8, 1, 1 }, -+ 1411200, 705600, 1, 1 }, - /* 32k rate */ - { 12000000, 32000, 14112000, 192, 43008000, 6144000, 64, 43008000, -- 2048000, 6, 1, 1 }, -+ 2048000, 1024000, 1, 1 }, - { 24000000, 32000, 14112000, 192, 12288000, 6144000, 64, 12288000, -- 2048000, 6, 1, 1 }, -+ 2048000, 1024000, 1, 1 }, - /* 44.1k rate */ - { 12000000, 44100, 44217600, 128, 45158400, 5644800, 128, 45158400, -- 5644800, 4, 1, 1 }, -+ 5644800, 1411200, 1, 1 }, - { 24000000, 44100, 44217600, 128, 11289600, 5644800, 64, 11289600, -- 2822400, 4, 1, 1 }, -+ 2822400, 1411200, 1, 1 }, - { 25000000, 44100, 19713750, 128, 11289600, 5644800, 64, 11289600, -- 2822400, 4, 1, 1 }, -+ 2822400, 1411200, 1, 1 }, - /* 48k rate */ - { 12000000, 48000, 18432000, 128, 49152000, 6144000, 128, 49152000, -- 6144000, 4, 1, 1 }, -+ 6144000, 1536000, 1, 1 }, - { 24000000, 48000, 18432000, 128, 12288000, 6144000, 64, 12288000, -- 3072000, 4, 1, 1 }, -+ 3072000, 1536000, 1, 1 }, - { 25000000, 48000, 75626250, 128, 12288000, 6144000, 64, 12288000, -- 3072000, 4, 1, 1 }, -+ 3072000, 1536000, 1, 1 }, - - /* 96k rate */ - { 25000000, 96000, 75626250, 64, 24576000, 6144000, 64, 24576000, -- 6144000, 1, 1, 9 }, -+ 6144000, 3072000, 1, 9 }, - }; - - static const struct snd_kcontrol_new hpl_output_mixer_controls[] = { -@@ -745,6 +745,7 @@ static int aic32x4_setup_clocks(struct s - { .id = "madc" }, - { .id = "ndac" }, - { .id = "mdac" }, -+ { .id = "bdiv" }, - }; - - i = aic32x4_get_divs(parent_rate, sample_rate); -@@ -762,14 +763,10 @@ static int aic32x4_setup_clocks(struct s - clk_set_rate(clocks[2].clk, aic32x4_divs[i].madc_rate); - clk_set_rate(clocks[3].clk, aic32x4_divs[i].ndac_rate); - clk_set_rate(clocks[4].clk, aic32x4_divs[i].mdac_rate); -+ clk_set_rate(clocks[5].clk, aic32x4_divs[i].bdiv_rate); - - aic32x4_set_processing_blocks(component, aic32x4_divs[i].r_block, aic32x4_divs[i].p_block); - -- /* DAC_MOD_CLK as BDIV_CLKIN */ -- snd_soc_component_update_bits(component, AIC32X4_IFACE3, -- AIC32X4_BDIVCLK_MASK, -- AIC32X4_DACMOD2BCLK << AIC32X4_BDIVCLK_SHIFT); -- - /* DOSR MSB & LSB values */ - snd_soc_component_write(component, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8); - snd_soc_component_write(component, AIC32X4_DOSRLSB, (aic32x4_divs[i].dosr & 0xff)); -@@ -777,10 +774,6 @@ static int aic32x4_setup_clocks(struct s - /* AOSR value */ - snd_soc_component_write(component, AIC32X4_AOSR, aic32x4_divs[i].aosr); - -- /* BCLK N divider */ -- snd_soc_component_update_bits(component, AIC32X4_BCLKN, -- AIC32X4_BCLK_MASK, aic32x4_divs[i].blck_N); -- - return 0; - } - -@@ -1003,6 +996,8 @@ static int aic32x4_component_probe(struc - struct clk_bulk_data clocks[] = { - { .id = "codec_clkin" }, - { .id = "pll" }, -+ { .id = "bdiv" }, -+ { .id = "mdac" }, - }; - - ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks); -@@ -1020,6 +1015,7 @@ static int aic32x4_component_probe(struc - aic32x4_setup_gpios(component); - - clk_set_parent(clocks[0].clk, clocks[1].clk); -+ clk_set_parent(clocks[2].clk, clocks[3].clk); - - /* Power platform configuration */ - if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) { diff --git a/target/linux/brcm2708/patches-4.19/950-0409-ASoC-tlv320aic32x4-Control-clock-gating-with-CCF.patch b/target/linux/brcm2708/patches-4.19/950-0409-ASoC-tlv320aic32x4-Control-clock-gating-with-CCF.patch deleted file mode 100644 index 1f6aed664e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0409-ASoC-tlv320aic32x4-Control-clock-gating-with-CCF.patch +++ /dev/null @@ -1,109 +0,0 @@ -From eea2c82299034bb146f3ad10e8ed4c2d574777df Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Thu, 21 Mar 2019 17:58:49 -0700 -Subject: [PATCH 409/703] ASoC: tlv320aic32x4: Control clock gating with CCF - -commit d25970b5fd51e9fcf0afbe190908ea4049454da4 upstream. - -Control the clock gating to the various clock components to use -the CCF. This allows us to prepare_enalbe only 3 clocks and the -relationships assigned to them will cause upstream clockss to -enable automatically. Additionally we can do this in a single -call to the CCF. - -Signed-off-by: Annaliese McDermond -Signed-off-by: Mark Brown ---- - sound/soc/codecs/tlv320aic32x4.c | 67 +++++++------------------------- - 1 file changed, 13 insertions(+), 54 deletions(-) - ---- a/sound/soc/codecs/tlv320aic32x4.c -+++ b/sound/soc/codecs/tlv320aic32x4.c -@@ -836,41 +836,25 @@ static int aic32x4_mute(struct snd_soc_d - static int aic32x4_set_bias_level(struct snd_soc_component *component, - enum snd_soc_bias_level level) - { -- struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component); - int ret; - -+ struct clk_bulk_data clocks[] = { -+ { .id = "madc" }, -+ { .id = "mdac" }, -+ { .id = "bdiv" }, -+ }; -+ -+ ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks); -+ if (ret) -+ return ret; -+ - switch (level) { - case SND_SOC_BIAS_ON: -- /* Switch on master clock */ -- ret = clk_prepare_enable(aic32x4->mclk); -+ ret = clk_bulk_prepare_enable(ARRAY_SIZE(clocks), clocks); - if (ret) { -- dev_err(component->dev, "Failed to enable master clock\n"); -+ dev_err(component->dev, "Failed to enable clocks\n"); - return ret; - } -- -- /* Switch on PLL */ -- snd_soc_component_update_bits(component, AIC32X4_PLLPR, -- AIC32X4_PLLEN, AIC32X4_PLLEN); -- -- /* Switch on NDAC Divider */ -- snd_soc_component_update_bits(component, AIC32X4_NDAC, -- AIC32X4_NDACEN, AIC32X4_NDACEN); -- -- /* Switch on MDAC Divider */ -- snd_soc_component_update_bits(component, AIC32X4_MDAC, -- AIC32X4_MDACEN, AIC32X4_MDACEN); -- -- /* Switch on NADC Divider */ -- snd_soc_component_update_bits(component, AIC32X4_NADC, -- AIC32X4_NADCEN, AIC32X4_NADCEN); -- -- /* Switch on MADC Divider */ -- snd_soc_component_update_bits(component, AIC32X4_MADC, -- AIC32X4_MADCEN, AIC32X4_MADCEN); -- -- /* Switch on BCLK_N Divider */ -- snd_soc_component_update_bits(component, AIC32X4_BCLKN, -- AIC32X4_BCLKEN, AIC32X4_BCLKEN); - break; - case SND_SOC_BIAS_PREPARE: - break; -@@ -879,32 +863,7 @@ static int aic32x4_set_bias_level(struct - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) - break; - -- /* Switch off BCLK_N Divider */ -- snd_soc_component_update_bits(component, AIC32X4_BCLKN, -- AIC32X4_BCLKEN, 0); -- -- /* Switch off MADC Divider */ -- snd_soc_component_update_bits(component, AIC32X4_MADC, -- AIC32X4_MADCEN, 0); -- -- /* Switch off NADC Divider */ -- snd_soc_component_update_bits(component, AIC32X4_NADC, -- AIC32X4_NADCEN, 0); -- -- /* Switch off MDAC Divider */ -- snd_soc_component_update_bits(component, AIC32X4_MDAC, -- AIC32X4_MDACEN, 0); -- -- /* Switch off NDAC Divider */ -- snd_soc_component_update_bits(component, AIC32X4_NDAC, -- AIC32X4_NDACEN, 0); -- -- /* Switch off PLL */ -- snd_soc_component_update_bits(component, AIC32X4_PLLPR, -- AIC32X4_PLLEN, 0); -- -- /* Switch off master clock */ -- clk_disable_unprepare(aic32x4->mclk); -+ clk_bulk_disable_unprepare(ARRAY_SIZE(clocks), clocks); - break; - case SND_SOC_BIAS_OFF: - break; diff --git a/target/linux/brcm2708/patches-4.19/950-0409-ASoC-tlv320aic32x4-Restructure-set_dai_sysclk.patch b/target/linux/brcm2708/patches-4.19/950-0409-ASoC-tlv320aic32x4-Restructure-set_dai_sysclk.patch new file mode 100644 index 0000000000..58e20d2f74 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0409-ASoC-tlv320aic32x4-Restructure-set_dai_sysclk.patch @@ -0,0 +1,51 @@ +From 58dc9e3363b946adc015c9b6d9f8b4c9c85f08a6 Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Thu, 21 Mar 2019 17:58:52 -0700 +Subject: [PATCH 409/725] ASoC: tlv320aic32x4: Restructure set_dai_sysclk + +commit aa6a60f7be925210d5156f0e8025f3afe1f4f54d upstream. + +The sysclk is now managed by the CCF. Change this function +to merely find the system clock and set it using +clk_set_rate. + +Signed-off-by: Annaliese McDermond +Signed-off-by: Mark Brown +--- + sound/soc/codecs/tlv320aic32x4.c | 17 ++++++----------- + 1 file changed, 6 insertions(+), 11 deletions(-) + +--- a/sound/soc/codecs/tlv320aic32x4.c ++++ b/sound/soc/codecs/tlv320aic32x4.c +@@ -49,7 +49,6 @@ + + struct aic32x4_priv { + struct regmap *regmap; +- u32 sysclk; + u32 power_cfg; + u32 micpga_routing; + bool swapdacs; +@@ -569,17 +568,13 @@ static int aic32x4_set_dai_sysclk(struct + int clk_id, unsigned int freq, int dir) + { + struct snd_soc_component *component = codec_dai->component; +- struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component); ++ struct clk *mclk; ++ struct clk *pll; + +- switch (freq) { +- case 12000000: +- case 24000000: +- case 25000000: +- aic32x4->sysclk = freq; +- return 0; +- } +- printk(KERN_ERR "aic32x4: invalid frequency to set DAI system clock\n"); +- return -EINVAL; ++ pll = devm_clk_get(component->dev, "pll"); ++ mclk = clk_get_parent(pll); ++ ++ return clk_set_rate(mclk, freq); + } + + static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) diff --git a/target/linux/brcm2708/patches-4.19/950-0410-ASoC-tlv320aic32x4-Move-aosr-and-dosr-setting-to-sep.patch b/target/linux/brcm2708/patches-4.19/950-0410-ASoC-tlv320aic32x4-Move-aosr-and-dosr-setting-to-sep.patch deleted file mode 100644 index 291f107c8a..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0410-ASoC-tlv320aic32x4-Move-aosr-and-dosr-setting-to-sep.patch +++ /dev/null @@ -1,58 +0,0 @@ -From d69dddf58047b95c5ade57c246e7d4994d439f23 Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Thu, 21 Mar 2019 17:58:50 -0700 -Subject: [PATCH 410/703] ASoC: tlv320aic32x4: Move aosr and dosr setting to - separate functions - -commit fbafbf6517274a797e6e6508c18dd8dba5920c89 upstream. - -Move these to separate helper functions. This looks cleaner and fits -better with the new clock setting in CCF. - -Signed-off-by: Annaliese McDermond -Signed-off-by: Mark Brown ---- - sound/soc/codecs/tlv320aic32x4.c | 24 +++++++++++++++++------- - 1 file changed, 17 insertions(+), 7 deletions(-) - ---- a/sound/soc/codecs/tlv320aic32x4.c -+++ b/sound/soc/codecs/tlv320aic32x4.c -@@ -720,6 +720,20 @@ static int aic32x4_set_dai_fmt(struct sn - return 0; - } - -+static int aic32x4_set_aosr(struct snd_soc_component *component, u8 aosr) -+{ -+ return snd_soc_component_write(component, AIC32X4_AOSR, aosr); -+} -+ -+static int aic32x4_set_dosr(struct snd_soc_component *component, u16 dosr) -+{ -+ snd_soc_component_write(component, AIC32X4_DOSRMSB, dosr >> 8); -+ snd_soc_component_write(component, AIC32X4_DOSRLSB, -+ (dosr & 0xff)); -+ -+ return 0; -+} -+ - static int aic32x4_set_processing_blocks(struct snd_soc_component *component, - u8 r_block, u8 p_block) - { -@@ -765,14 +779,10 @@ static int aic32x4_setup_clocks(struct s - clk_set_rate(clocks[4].clk, aic32x4_divs[i].mdac_rate); - clk_set_rate(clocks[5].clk, aic32x4_divs[i].bdiv_rate); - -- aic32x4_set_processing_blocks(component, aic32x4_divs[i].r_block, aic32x4_divs[i].p_block); -+ aic32x4_set_aosr(component, aic32x4_divs[i].aosr); -+ aic32x4_set_dosr(component, aic32x4_divs[i].dosr); - -- /* DOSR MSB & LSB values */ -- snd_soc_component_write(component, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8); -- snd_soc_component_write(component, AIC32X4_DOSRLSB, (aic32x4_divs[i].dosr & 0xff)); -- -- /* AOSR value */ -- snd_soc_component_write(component, AIC32X4_AOSR, aic32x4_divs[i].aosr); -+ aic32x4_set_processing_blocks(component, aic32x4_divs[i].r_block, aic32x4_divs[i].p_block); - - return 0; - } diff --git a/target/linux/brcm2708/patches-4.19/950-0410-ASoC-tlv320aic32x4-Remove-mclk-references.patch b/target/linux/brcm2708/patches-4.19/950-0410-ASoC-tlv320aic32x4-Remove-mclk-references.patch new file mode 100644 index 0000000000..6ba1821f2f --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0410-ASoC-tlv320aic32x4-Remove-mclk-references.patch @@ -0,0 +1,39 @@ +From a815db43f1cd8dc8ac18d06c20526883d285c527 Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Thu, 21 Mar 2019 17:58:53 -0700 +Subject: [PATCH 410/725] ASoC: tlv320aic32x4: Remove mclk references + +commit 78f2d58a289302e56a7def96a783a7686ebf27e2 upstream. + +mclk is not used by anything anymore. Remove support for it. +All that information now comes from the clock tree. + +Signed-off-by: Annaliese McDermond +Signed-off-by: Mark Brown +--- + sound/soc/codecs/tlv320aic32x4.c | 7 ------- + 1 file changed, 7 deletions(-) + +--- a/sound/soc/codecs/tlv320aic32x4.c ++++ b/sound/soc/codecs/tlv320aic32x4.c +@@ -53,7 +53,6 @@ struct aic32x4_priv { + u32 micpga_routing; + bool swapdacs; + int rstn_gpio; +- struct clk *mclk; + const char *mclk_name; + + struct regulator *supply_ldo; +@@ -1191,12 +1190,6 @@ int aic32x4_probe(struct device *dev, st + aic32x4->mclk_name = "mclk"; + } + +- aic32x4->mclk = devm_clk_get(dev, "mclk"); +- if (IS_ERR(aic32x4->mclk)) { +- dev_err(dev, "Failed getting the mclk. The current implementation does not support the usage of this codec without mclk\n"); +- return PTR_ERR(aic32x4->mclk); +- } +- + ret = aic32x4_register_clocks(dev, aic32x4->mclk_name); + if (ret) + return ret; diff --git a/target/linux/brcm2708/patches-4.19/950-0411-ASoC-tlv320aic32x4-Allow-192000-Sample-Rate.patch b/target/linux/brcm2708/patches-4.19/950-0411-ASoC-tlv320aic32x4-Allow-192000-Sample-Rate.patch new file mode 100644 index 0000000000..0ccb56b21e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0411-ASoC-tlv320aic32x4-Allow-192000-Sample-Rate.patch @@ -0,0 +1,27 @@ +From 7ce5af6517eee229b6ef65126a672a0d5c42d315 Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Thu, 21 Mar 2019 17:58:54 -0700 +Subject: [PATCH 411/725] ASoC: tlv320aic32x4: Allow 192000 Sample Rate + +commit 6d56ee1550b8a81bc63c80051ff78d8d704b09ba upstream. + +The clocking and processing blocks are now properly set up to +support 192000 sample rates. Allow drivers to ask for that. + +Signed-off-by: Annaliese McDermond +Signed-off-by: Mark Brown +--- + sound/soc/codecs/tlv320aic32x4.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/soc/codecs/tlv320aic32x4.c ++++ b/sound/soc/codecs/tlv320aic32x4.c +@@ -859,7 +859,7 @@ static int aic32x4_set_bias_level(struct + return 0; + } + +-#define AIC32X4_RATES SNDRV_PCM_RATE_8000_96000 ++#define AIC32X4_RATES SNDRV_PCM_RATE_8000_192000 + #define AIC32X4_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ + | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) + diff --git a/target/linux/brcm2708/patches-4.19/950-0411-ASoC-tlv320aic32x4-Dynamically-Determine-Clocking.patch b/target/linux/brcm2708/patches-4.19/950-0411-ASoC-tlv320aic32x4-Dynamically-Determine-Clocking.patch deleted file mode 100644 index b31a93c8cf..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0411-ASoC-tlv320aic32x4-Dynamically-Determine-Clocking.patch +++ /dev/null @@ -1,285 +0,0 @@ -From 60aee9d4b5857dbefc658ff7b3317cacf568a5d5 Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Thu, 21 Mar 2019 17:58:51 -0700 -Subject: [PATCH 411/703] ASoC: tlv320aic32x4: Dynamically Determine Clocking - -commit 96c3bb00239de4fb5f4ddca42c1f90d6d9b3c697 upstream. - -The existing code uses a static lookup table to determine the -settings of the various clock devices on board the chip. This is -limiting in a couple of ways. First, this doesn't allow for any -master clock rates other than the three that have been -precalculated. Additionally, new sample rates are difficult to -add to the table. Witness that the chip is capable of 192000 Hz -sampling, but it is not provided by this driver. Last, if the -driver is clocked by something that isn't a crystal, the -upstream clock may not be able to achieve exactly the rate -requested in the driver. This will mean that clocking will be -slightly off for the sampling clock or that it won't work at all. - -This patch determines the settings for all of the clocks at -runtime considering the real conditions of the clocks in the -system. The rules for the clocks are in TI's SLAA557 application -guide on pages 37, 51 and 77. - -Signed-off-by: Annaliese McDermond -Signed-off-by: Mark Brown ---- - sound/soc/codecs/tlv320aic32x4.c | 190 ++++++++++++++----------------- - sound/soc/codecs/tlv320aic32x4.h | 4 +- - 2 files changed, 90 insertions(+), 104 deletions(-) - ---- a/sound/soc/codecs/tlv320aic32x4.c -+++ b/sound/soc/codecs/tlv320aic32x4.c -@@ -47,21 +47,6 @@ - - #include "tlv320aic32x4.h" - --struct aic32x4_rate_divs { -- u32 mclk; -- u32 rate; -- unsigned long pll_rate; -- u16 dosr; -- unsigned long ndac_rate; -- unsigned long mdac_rate; -- u8 aosr; -- unsigned long nadc_rate; -- unsigned long madc_rate; -- unsigned long bdiv_rate; -- u8 r_block; -- u8 p_block; --}; -- - struct aic32x4_priv { - struct regmap *regmap; - u32 sysclk; -@@ -307,58 +292,6 @@ static const struct snd_kcontrol_new aic - 0, 0x0F, 0), - }; - --static const struct aic32x4_rate_divs aic32x4_divs[] = { -- /* 8k rate */ -- { 12000000, 8000, 57120000, 768, 18432000, 6144000, 128, 18432000, -- 1024000, 256000, 1, 1 }, -- { 24000000, 8000, 57120000, 768, 6144000, 6144000, 64, 2048000, -- 512000, 256000, 1, 1 }, -- { 25000000, 8000, 32620000, 768, 6144000, 6144000, 64, 2048000, -- 512000, 256000, 1, 1 }, -- /* 11.025k rate */ -- { 12000000, 11025, 44217600, 512, 11289600, 5644800, 128, 11289600, -- 1411200, 352800, 1, 1 }, -- { 24000000, 11025, 44217600, 512, 5644800, 5644800, 64, 2822400, -- 705600, 352800, 1, 1 }, -- /* 16k rate */ -- { 12000000, 16000, 57120000, 384, 18432000, 6144000, 128, 18432000, -- 2048000, 512000, 1, 1 }, -- { 24000000, 16000, 57120000, 384, 6144000, 6144000, 64, 5120000, -- 1024000, 512000, 1, 1 }, -- { 25000000, 16000, 32620000, 384, 6144000, 6144000, 64, 5120000, -- 1024000, 512000, 1, 1 }, -- /* 22.05k rate */ -- { 12000000, 22050, 44217600, 256, 22579200, 5644800, 128, 22579200, -- 2822400, 705600, 1, 1 }, -- { 24000000, 22050, 44217600, 256, 5644800, 5644800, 64, 5644800, -- 1411200, 705600, 1, 1 }, -- { 25000000, 22050, 19713750, 256, 5644800, 5644800, 64, 5644800, -- 1411200, 705600, 1, 1 }, -- /* 32k rate */ -- { 12000000, 32000, 14112000, 192, 43008000, 6144000, 64, 43008000, -- 2048000, 1024000, 1, 1 }, -- { 24000000, 32000, 14112000, 192, 12288000, 6144000, 64, 12288000, -- 2048000, 1024000, 1, 1 }, -- /* 44.1k rate */ -- { 12000000, 44100, 44217600, 128, 45158400, 5644800, 128, 45158400, -- 5644800, 1411200, 1, 1 }, -- { 24000000, 44100, 44217600, 128, 11289600, 5644800, 64, 11289600, -- 2822400, 1411200, 1, 1 }, -- { 25000000, 44100, 19713750, 128, 11289600, 5644800, 64, 11289600, -- 2822400, 1411200, 1, 1 }, -- /* 48k rate */ -- { 12000000, 48000, 18432000, 128, 49152000, 6144000, 128, 49152000, -- 6144000, 1536000, 1, 1 }, -- { 24000000, 48000, 18432000, 128, 12288000, 6144000, 64, 12288000, -- 3072000, 1536000, 1, 1 }, -- { 25000000, 48000, 75626250, 128, 12288000, 6144000, 64, 12288000, -- 3072000, 1536000, 1, 1 }, -- -- /* 96k rate */ -- { 25000000, 96000, 75626250, 64, 24576000, 6144000, 64, 24576000, -- 6144000, 3072000, 1, 9 }, --}; -- - static const struct snd_kcontrol_new hpl_output_mixer_controls[] = { - SOC_DAPM_SINGLE("L_DAC Switch", AIC32X4_HPLROUTE, 3, 1, 0), - SOC_DAPM_SINGLE("IN1_L Switch", AIC32X4_HPLROUTE, 2, 1, 0), -@@ -632,20 +565,6 @@ const struct regmap_config aic32x4_regma - }; - EXPORT_SYMBOL(aic32x4_regmap_config); - --static inline int aic32x4_get_divs(int mclk, int rate) --{ -- int i; -- -- for (i = 0; i < ARRAY_SIZE(aic32x4_divs); i++) { -- if ((aic32x4_divs[i].rate == rate) -- && (aic32x4_divs[i].mclk == mclk)) { -- return i; -- } -- } -- printk(KERN_ERR "aic32x4: master clock and sample rate is not supported\n"); -- return -EINVAL; --} -- - static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai, - int clk_id, unsigned int freq, int dir) - { -@@ -747,11 +666,17 @@ static int aic32x4_set_processing_blocks - } - - static int aic32x4_setup_clocks(struct snd_soc_component *component, -- unsigned int sample_rate, -- unsigned int parent_rate) -+ unsigned int sample_rate) - { -- int i; -+ u8 aosr; -+ u16 dosr; -+ u8 adc_resource_class, dac_resource_class; -+ u8 madc, nadc, mdac, ndac, max_nadc, min_mdac, max_ndac; -+ u8 dosr_increment; -+ u16 max_dosr, min_dosr; -+ unsigned long mclk_rate, adc_clock_rate, dac_clock_rate; - int ret; -+ struct clk *mclk; - - struct clk_bulk_data clocks[] = { - { .id = "pll" }, -@@ -761,30 +686,89 @@ static int aic32x4_setup_clocks(struct s - { .id = "mdac" }, - { .id = "bdiv" }, - }; -- -- i = aic32x4_get_divs(parent_rate, sample_rate); -- if (i < 0) { -- printk(KERN_ERR "aic32x4: sampling rate not supported\n"); -- return i; -- } -- - ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks); - if (ret) - return ret; - -- clk_set_rate(clocks[0].clk, aic32x4_divs[i].pll_rate); -- clk_set_rate(clocks[1].clk, aic32x4_divs[i].nadc_rate); -- clk_set_rate(clocks[2].clk, aic32x4_divs[i].madc_rate); -- clk_set_rate(clocks[3].clk, aic32x4_divs[i].ndac_rate); -- clk_set_rate(clocks[4].clk, aic32x4_divs[i].mdac_rate); -- clk_set_rate(clocks[5].clk, aic32x4_divs[i].bdiv_rate); -+ mclk = clk_get_parent(clocks[1].clk); -+ mclk_rate = clk_get_rate(mclk); - -- aic32x4_set_aosr(component, aic32x4_divs[i].aosr); -- aic32x4_set_dosr(component, aic32x4_divs[i].dosr); -+ if (sample_rate <= 48000) { -+ aosr = 128; -+ adc_resource_class = 6; -+ dac_resource_class = 8; -+ dosr_increment = 8; -+ aic32x4_set_processing_blocks(component, 1, 1); -+ } else if (sample_rate <= 96000) { -+ aosr = 64; -+ adc_resource_class = 6; -+ dac_resource_class = 8; -+ dosr_increment = 4; -+ aic32x4_set_processing_blocks(component, 1, 9); -+ } else if (sample_rate == 192000) { -+ aosr = 32; -+ adc_resource_class = 3; -+ dac_resource_class = 4; -+ dosr_increment = 2; -+ aic32x4_set_processing_blocks(component, 13, 19); -+ } else { -+ dev_err(component->dev, "Sampling rate not supported\n"); -+ return -EINVAL; -+ } - -- aic32x4_set_processing_blocks(component, aic32x4_divs[i].r_block, aic32x4_divs[i].p_block); -+ madc = DIV_ROUND_UP((32 * adc_resource_class), aosr); -+ max_dosr = (AIC32X4_MAX_DOSR_FREQ / sample_rate / dosr_increment) * -+ dosr_increment; -+ min_dosr = (AIC32X4_MIN_DOSR_FREQ / sample_rate / dosr_increment) * -+ dosr_increment; -+ max_nadc = AIC32X4_MAX_CODEC_CLKIN_FREQ / (madc * aosr * sample_rate); -+ -+ for (nadc = max_nadc; nadc > 0; --nadc) { -+ adc_clock_rate = nadc * madc * aosr * sample_rate; -+ for (dosr = max_dosr; dosr >= min_dosr; -+ dosr -= dosr_increment) { -+ min_mdac = DIV_ROUND_UP((32 * dac_resource_class), dosr); -+ max_ndac = AIC32X4_MAX_CODEC_CLKIN_FREQ / -+ (min_mdac * dosr * sample_rate); -+ for (mdac = min_mdac; mdac <= 128; ++mdac) { -+ for (ndac = max_ndac; ndac > 0; --ndac) { -+ dac_clock_rate = ndac * mdac * dosr * -+ sample_rate; -+ if (dac_clock_rate == adc_clock_rate) { -+ if (clk_round_rate(clocks[0].clk, dac_clock_rate) == 0) -+ continue; -+ -+ clk_set_rate(clocks[0].clk, -+ dac_clock_rate); -+ -+ clk_set_rate(clocks[1].clk, -+ sample_rate * aosr * -+ madc); -+ clk_set_rate(clocks[2].clk, -+ sample_rate * aosr); -+ aic32x4_set_aosr(component, -+ aosr); -+ -+ clk_set_rate(clocks[3].clk, -+ sample_rate * dosr * -+ mdac); -+ clk_set_rate(clocks[4].clk, -+ sample_rate * dosr); -+ aic32x4_set_dosr(component, -+ dosr); -+ -+ clk_set_rate(clocks[5].clk, -+ sample_rate * 32); -+ return 0; -+ } -+ } -+ } -+ } -+ } - -- return 0; -+ dev_err(component->dev, -+ "Could not set clocks to support sample rate.\n"); -+ return -EINVAL; - } - - static int aic32x4_hw_params(struct snd_pcm_substream *substream, -@@ -796,7 +780,7 @@ static int aic32x4_hw_params(struct snd_ - u8 iface1_reg = 0; - u8 dacsetup_reg = 0; - -- aic32x4_setup_clocks(component, params_rate(params), aic32x4->sysclk); -+ aic32x4_setup_clocks(component, params_rate(params)); - - switch (params_width(params)) { - case 16: ---- a/sound/soc/codecs/tlv320aic32x4.h -+++ b/sound/soc/codecs/tlv320aic32x4.h -@@ -211,7 +211,9 @@ int aic32x4_register_clocks(struct devic - #define AIC32X4_DIV_MASK GENMASK(6, 0) - - /* Clock Limits */ -+#define AIC32X4_MAX_DOSR_FREQ 6200000 -+#define AIC32X4_MIN_DOSR_FREQ 2800000 -+#define AIC32X4_MAX_CODEC_CLKIN_FREQ 110000000 - #define AIC32X4_MAX_PLL_CLKIN 20000000 - -- - #endif /* _TLV320AIC32X4_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0412-ASoC-tlv320aic32x4-Only-enable-with-common-clock.patch b/target/linux/brcm2708/patches-4.19/950-0412-ASoC-tlv320aic32x4-Only-enable-with-common-clock.patch new file mode 100644 index 0000000000..3afb9ec965 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0412-ASoC-tlv320aic32x4-Only-enable-with-common-clock.patch @@ -0,0 +1,43 @@ +From 618baa8ddc305c5bbe1cd4682c9df252e6fc386c Mon Sep 17 00:00:00 2001 +From: Mark Brown +Date: Tue, 26 Mar 2019 13:10:13 +0000 +Subject: [PATCH 412/725] ASoC: tlv320aic32x4: Only enable with common clock + +commit 64f01d2b5ccc621c3aa66b82daf9154f5581f36a upstream. + +Some architectures do not yet support the common clock API at all but +the tlv320aic32x4 driver now requires it. + +Reported-by: Stephen Rothwell +Signed-off-by: Mark Brown +--- + sound/soc/codecs/Kconfig | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -170,8 +170,8 @@ config SND_SOC_ALL_CODECS + 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 +- select SND_SOC_TLV320AIC32X4_SPI if SPI_MASTER ++ select SND_SOC_TLV320AIC32X4_I2C if I2C && COMMON_CLK ++ select SND_SOC_TLV320AIC32X4_SPI if SPI_MASTER && COMMON_CLK + select SND_SOC_TLV320AIC3X if I2C + select SND_SOC_TPA6130A2 if I2C + select SND_SOC_TLV320DAC33 if I2C +@@ -1030,11 +1030,13 @@ config SND_SOC_TLV320AIC32X4 + config SND_SOC_TLV320AIC32X4_I2C + tristate "Texas Instruments TLV320AIC32x4 audio CODECs - I2C" + depends on I2C ++ depends on COMMON_CLK + select SND_SOC_TLV320AIC32X4 + + config SND_SOC_TLV320AIC32X4_SPI + tristate "Texas Instruments TLV320AIC32x4 audio CODECs - SPI" + depends on SPI_MASTER ++ depends on COMMON_CLK + select SND_SOC_TLV320AIC32X4 + + config SND_SOC_TLV320AIC3X diff --git a/target/linux/brcm2708/patches-4.19/950-0412-ASoC-tlv320aic32x4-Restructure-set_dai_sysclk.patch b/target/linux/brcm2708/patches-4.19/950-0412-ASoC-tlv320aic32x4-Restructure-set_dai_sysclk.patch deleted file mode 100644 index ff61edf97e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0412-ASoC-tlv320aic32x4-Restructure-set_dai_sysclk.patch +++ /dev/null @@ -1,51 +0,0 @@ -From dc848cfb79aa1a4cea301c388e920e4205ac791a Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Thu, 21 Mar 2019 17:58:52 -0700 -Subject: [PATCH 412/703] ASoC: tlv320aic32x4: Restructure set_dai_sysclk - -commit aa6a60f7be925210d5156f0e8025f3afe1f4f54d upstream. - -The sysclk is now managed by the CCF. Change this function -to merely find the system clock and set it using -clk_set_rate. - -Signed-off-by: Annaliese McDermond -Signed-off-by: Mark Brown ---- - sound/soc/codecs/tlv320aic32x4.c | 17 ++++++----------- - 1 file changed, 6 insertions(+), 11 deletions(-) - ---- a/sound/soc/codecs/tlv320aic32x4.c -+++ b/sound/soc/codecs/tlv320aic32x4.c -@@ -49,7 +49,6 @@ - - struct aic32x4_priv { - struct regmap *regmap; -- u32 sysclk; - u32 power_cfg; - u32 micpga_routing; - bool swapdacs; -@@ -569,17 +568,13 @@ static int aic32x4_set_dai_sysclk(struct - int clk_id, unsigned int freq, int dir) - { - struct snd_soc_component *component = codec_dai->component; -- struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component); -+ struct clk *mclk; -+ struct clk *pll; - -- switch (freq) { -- case 12000000: -- case 24000000: -- case 25000000: -- aic32x4->sysclk = freq; -- return 0; -- } -- printk(KERN_ERR "aic32x4: invalid frequency to set DAI system clock\n"); -- return -EINVAL; -+ pll = devm_clk_get(component->dev, "pll"); -+ mclk = clk_get_parent(pll); -+ -+ return clk_set_rate(mclk, freq); - } - - static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) diff --git a/target/linux/brcm2708/patches-4.19/950-0413-ASoC-tlv320aic32x4-Remove-mclk-references.patch b/target/linux/brcm2708/patches-4.19/950-0413-ASoC-tlv320aic32x4-Remove-mclk-references.patch deleted file mode 100644 index cc7251a78d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0413-ASoC-tlv320aic32x4-Remove-mclk-references.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 76203a21b47e2dcbb3619a9655cc4918e4d496a5 Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Thu, 21 Mar 2019 17:58:53 -0700 -Subject: [PATCH 413/703] ASoC: tlv320aic32x4: Remove mclk references - -commit 78f2d58a289302e56a7def96a783a7686ebf27e2 upstream. - -mclk is not used by anything anymore. Remove support for it. -All that information now comes from the clock tree. - -Signed-off-by: Annaliese McDermond -Signed-off-by: Mark Brown ---- - sound/soc/codecs/tlv320aic32x4.c | 7 ------- - 1 file changed, 7 deletions(-) - ---- a/sound/soc/codecs/tlv320aic32x4.c -+++ b/sound/soc/codecs/tlv320aic32x4.c -@@ -53,7 +53,6 @@ struct aic32x4_priv { - u32 micpga_routing; - bool swapdacs; - int rstn_gpio; -- struct clk *mclk; - const char *mclk_name; - - struct regulator *supply_ldo; -@@ -1191,12 +1190,6 @@ int aic32x4_probe(struct device *dev, st - aic32x4->mclk_name = "mclk"; - } - -- aic32x4->mclk = devm_clk_get(dev, "mclk"); -- if (IS_ERR(aic32x4->mclk)) { -- dev_err(dev, "Failed getting the mclk. The current implementation does not support the usage of this codec without mclk\n"); -- return PTR_ERR(aic32x4->mclk); -- } -- - ret = aic32x4_register_clocks(dev, aic32x4->mclk_name); - if (ret) - return ret; diff --git a/target/linux/brcm2708/patches-4.19/950-0413-Audiophonics-I-Sabre-9038Q2M-DAC-driver.patch b/target/linux/brcm2708/patches-4.19/950-0413-Audiophonics-I-Sabre-9038Q2M-DAC-driver.patch new file mode 100644 index 0000000000..0f40a63fa0 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0413-Audiophonics-I-Sabre-9038Q2M-DAC-driver.patch @@ -0,0 +1,794 @@ +From 739091e806876265d78915310e4037d0061648f8 Mon Sep 17 00:00:00 2001 +From: FERHAT Nicolas +Date: Fri, 5 Apr 2019 13:06:42 +0100 +Subject: [PATCH 413/725] Audiophonics I-Sabre 9038Q2M DAC driver + +Signed-off-by: Audiophonics +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 6 + + .../boot/dts/overlays/i-sabre-q2m-overlay.dts | 39 ++ + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + arch/arm64/configs/bcmrpi3_defconfig | 1 + + sound/soc/bcm/Kconfig | 7 + + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/i-sabre-q2m.c | 157 +++++++ + sound/soc/codecs/Kconfig | 5 + + sound/soc/codecs/Makefile | 2 + + sound/soc/codecs/i-sabre-codec.c | 392 ++++++++++++++++++ + sound/soc/codecs/i-sabre-codec.h | 42 ++ + 13 files changed, 656 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/i-sabre-q2m-overlay.dts + create mode 100644 sound/soc/bcm/i-sabre-q2m.c + create mode 100644 sound/soc/codecs/i-sabre-codec.c + create mode 100644 sound/soc/codecs/i-sabre-codec.h + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -55,6 +55,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + hy28a.dtbo \ + hy28b.dtbo \ + hy28b-2017.dtbo \ ++ i-sabre-q2m.dtbo \ + i2c-bcm2708.dtbo \ + i2c-gpio.dtbo \ + i2c-mux.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -869,6 +869,12 @@ Params: speed Display + ledgpio GPIO used to control backlight + + ++Name: i-sabre-q2m ++Info: Configures the Audiophonics I-SABRE Q2M DAC ++Load: dtoverlay=i-sabre-q2m ++Params: ++ ++ + Name: i2c-bcm2708 + Info: Fall back to the i2c_bcm2708 driver for the i2c_arm bus. + Load: dtoverlay=i2c-bcm2708 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i-sabre-q2m-overlay.dts +@@ -0,0 +1,39 @@ ++// Definitions for I-Sabre Q2M ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ frag0: __overlay__ { ++ compatible = "audiophonics,i-sabre-q2m"; ++ 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"; ++ ++ i-sabre-codec@48 { ++ #sound-dai-cells = <0>; ++ compatible = "audiophonics,i-sabre-codec"; ++ reg = <0x48>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -916,6 +916,7 @@ CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m + CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m + CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m + CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m ++CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m + CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m + CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m + CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -909,6 +909,7 @@ CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m + CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m + CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m + CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m ++CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m + CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m + CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m + CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -804,6 +804,7 @@ CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m + CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m + CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m + CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m ++CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m + CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m + CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m + CONFIG_SND_AUDIOSENSE_PI=m +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -123,6 +123,13 @@ config SND_BCM2708_SOC_IQAUDIO_DIGI + help + Say Y or M if you want to add support for IQAudIO Digital IO board. + ++config SND_BCM2708_SOC_I_SABRE_Q2M ++ tristate "Support for Audiophonics I-Sabre Q2M DAC" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_I_SABRE_CODEC ++ help ++ Say Y or M if you want to add support for Audiophonics I-SABRE Q2M DAC ++ + config SND_BCM2708_SOC_ADAU1977_ADC + tristate "Support for ADAU1977 ADC" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -19,6 +19,7 @@ snd-soc-justboom-dac-objs := justboom-da + snd-soc-rpi-cirrus-objs := rpi-cirrus.o + snd-soc-rpi-proto-objs := rpi-proto.o + snd-soc-iqaudio-dac-objs := iqaudio-dac.o ++ snd-soc-i-sabre-q2m-objs := i-sabre-q2m.o + snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o + snd-soc-audioinjector-octo-soundcard-objs := audioinjector-octo-soundcard.o + snd-soc-audiosense-pi-objs := audiosense-pi.o +@@ -42,6 +43,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_JUSTBOOM_DA + obj-$(CONFIG_SND_BCM2708_SOC_RPI_CIRRUS) += snd-soc-rpi-cirrus.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 ++ obj-$(CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M) += snd-soc-i-sabre-q2m.o + obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o + obj-$(CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD) += snd-soc-audioinjector-octo-soundcard.o + obj-$(CONFIG_SND_AUDIOSENSE_PI) += snd-soc-audiosense-pi.o +--- /dev/null ++++ b/sound/soc/bcm/i-sabre-q2m.c +@@ -0,0 +1,157 @@ ++/* ++ * ASoC Driver for I-Sabre Q2M ++ * ++ * Author: Satoru Kawase ++ * Modified by: Xiao Qingyong ++ * Update kernel v4.18+ by : Audiophonics ++ * Copyright 2018 Audiophonics ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "../codecs/i-sabre-codec.h" ++ ++ ++static int snd_rpi_i_sabre_q2m_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ struct snd_soc_component *component = rtd->codec_dai->component; ++ unsigned int value; ++ ++ /* Device ID */ ++ value = snd_soc_component_read32(component, ISABRECODEC_REG_01); ++ dev_info(component->card->dev, "Audiophonics Device ID : %02X\n", value); ++ ++ /* API revision */ ++ value = snd_soc_component_read32(component, ISABRECODEC_REG_02); ++ dev_info(component->card->dev, "Audiophonics API revision : %02X\n", value); ++ ++ return 0; ++} ++ ++static int snd_rpi_i_sabre_q2m_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; ++ int bclk_ratio; ++ ++ bclk_ratio = snd_pcm_format_physical_width( ++ params_format(params)) * params_channels(params); ++ return snd_soc_dai_set_bclk_ratio(cpu_dai, bclk_ratio); ++} ++ ++/* machine stream operations */ ++static struct snd_soc_ops snd_rpi_i_sabre_q2m_ops = { ++ .hw_params = snd_rpi_i_sabre_q2m_hw_params, ++}; ++ ++ ++static struct snd_soc_dai_link snd_rpi_i_sabre_q2m_dai[] = { ++ { ++ .name = "I-Sabre Q2M", ++ .stream_name = "I-Sabre Q2M DAC", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "i-sabre-codec-dai", ++ .platform_name = "bcm2708-i2s.0", ++ .codec_name = "i-sabre-codec-i2c.1-0048", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF ++ | SND_SOC_DAIFMT_CBS_CFS, ++ .init = snd_rpi_i_sabre_q2m_init, ++ .ops = &snd_rpi_i_sabre_q2m_ops, ++ } ++}; ++ ++/* audio machine driver */ ++static struct snd_soc_card snd_rpi_i_sabre_q2m = { ++ .name = "I-Sabre Q2M DAC", ++ .owner = THIS_MODULE, ++ .dai_link = snd_rpi_i_sabre_q2m_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_i_sabre_q2m_dai) ++}; ++ ++ ++static int snd_rpi_i_sabre_q2m_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ snd_rpi_i_sabre_q2m.dev = &pdev->dev; ++ if (pdev->dev.of_node) { ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai; ++ ++ dai = &snd_rpi_i_sabre_q2m_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; ++ } else { ++ dev_err(&pdev->dev, ++ "Property 'i2s-controller' missing or invalid\n"); ++ return (-EINVAL); ++ } ++ ++ dai->name = "I-Sabre Q2M"; ++ dai->stream_name = "I-Sabre Q2M DAC"; ++ dai->dai_fmt = SND_SOC_DAIFMT_I2S ++ | SND_SOC_DAIFMT_NB_NF ++ | SND_SOC_DAIFMT_CBS_CFS; ++ } ++ ++ /* Wait for registering codec driver */ ++ mdelay(50); ++ ++ ret = snd_soc_register_card(&snd_rpi_i_sabre_q2m); ++ if (ret) { ++ dev_err(&pdev->dev, ++ "snd_soc_register_card() failed: %d\n", ret); ++ } ++ ++ return ret; ++} ++ ++static int snd_rpi_i_sabre_q2m_remove(struct platform_device *pdev) ++{ ++ return snd_soc_unregister_card(&snd_rpi_i_sabre_q2m); ++} ++ ++static const struct of_device_id snd_rpi_i_sabre_q2m_of_match[] = { ++ { .compatible = "audiophonics,i-sabre-q2m", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, snd_rpi_i_sabre_q2m_of_match); ++ ++static struct platform_driver snd_rpi_i_sabre_q2m_driver = { ++ .driver = { ++ .name = "snd-rpi-i-sabre-q2m", ++ .owner = THIS_MODULE, ++ .of_match_table = snd_rpi_i_sabre_q2m_of_match, ++ }, ++ .probe = snd_rpi_i_sabre_q2m_probe, ++ .remove = snd_rpi_i_sabre_q2m_remove, ++}; ++module_platform_driver(snd_rpi_i_sabre_q2m_driver); ++ ++MODULE_DESCRIPTION("ASoC Driver for I-Sabre Q2M"); ++MODULE_AUTHOR("Audiophonics "); ++MODULE_LICENSE("GPL"); +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -85,6 +85,7 @@ config SND_SOC_ALL_CODECS + select SND_SOC_ICS43432 + select SND_SOC_INNO_RK3036 + select SND_SOC_ISABELLE if I2C ++ select SND_SOC_I_SABRE_CODEC if I2C + select SND_SOC_JZ4740_CODEC + select SND_SOC_LM4857 if I2C + select SND_SOC_LM49453 if I2C +@@ -1322,4 +1323,8 @@ config SND_SOC_TPA6130A2 + tristate "Texas Instruments TPA6130A2 headphone amplifier" + depends on I2C + ++config SND_SOC_I_SABRE_CODEC ++ tristate "Audiophonics I-SABRE Codec" ++ depends on I2C ++ + endmenu +--- a/sound/soc/codecs/Makefile ++++ b/sound/soc/codecs/Makefile +@@ -81,6 +81,7 @@ snd-soc-hdac-hdmi-objs := hdac_hdmi.o + snd-soc-ics43432-objs := ics43432.o + snd-soc-inno-rk3036-objs := inno_rk3036.o + snd-soc-isabelle-objs := isabelle.o ++snd-soc-i-sabre-codec-objs := i-sabre-codec.o + snd-soc-jz4740-codec-objs := jz4740.o + snd-soc-l3-objs := l3.o + snd-soc-lm4857-objs := lm4857.o +@@ -343,6 +344,7 @@ obj-$(CONFIG_SND_SOC_HDAC_HDMI) += snd-s + obj-$(CONFIG_SND_SOC_ICS43432) += snd-soc-ics43432.o + obj-$(CONFIG_SND_SOC_INNO_RK3036) += snd-soc-inno-rk3036.o + obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o ++obj-$(CONFIG_SND_SOC_I_SABRE_CODEC) += snd-soc-i-sabre-codec.o + obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o + obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o + obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o +--- /dev/null ++++ b/sound/soc/codecs/i-sabre-codec.c +@@ -0,0 +1,392 @@ ++/* ++ * Driver for I-Sabre Q2M ++ * ++ * Author: Satoru Kawase ++ * Modified by: Xiao Qingyong ++ * Modified by: JC BARBAUD (Mute) ++ * Update kernel v4.18+ by : Audiophonics ++ * Copyright 2018 Audiophonics ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "i-sabre-codec.h" ++ ++ ++/* I-Sabre Q2M Codec Private Data */ ++struct i_sabre_codec_priv { ++ struct regmap *regmap; ++ unsigned int fmt; ++}; ++ ++ ++/* I-Sabre Q2M Codec Default Register Value */ ++static const struct reg_default i_sabre_codec_reg_defaults[] = { ++ { ISABRECODEC_REG_10, 0x00 }, ++ { ISABRECODEC_REG_20, 0x00 }, ++ { ISABRECODEC_REG_21, 0x00 }, ++ { ISABRECODEC_REG_22, 0x00 }, ++ { ISABRECODEC_REG_24, 0x00 }, ++}; ++ ++ ++static bool i_sabre_codec_writeable(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case ISABRECODEC_REG_10: ++ case ISABRECODEC_REG_20: ++ case ISABRECODEC_REG_21: ++ case ISABRECODEC_REG_22: ++ case ISABRECODEC_REG_24: ++ return true; ++ ++ default: ++ return false; ++ } ++} ++ ++static bool i_sabre_codec_readable(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case ISABRECODEC_REG_01: ++ case ISABRECODEC_REG_02: ++ case ISABRECODEC_REG_10: ++ case ISABRECODEC_REG_20: ++ case ISABRECODEC_REG_21: ++ case ISABRECODEC_REG_22: ++ case ISABRECODEC_REG_24: ++ return true; ++ ++ default: ++ return false; ++ } ++} ++ ++static bool i_sabre_codec_volatile(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case ISABRECODEC_REG_01: ++ case ISABRECODEC_REG_02: ++ return true; ++ ++ default: ++ return false; ++ } ++} ++ ++ ++/* Volume Scale */ ++static const DECLARE_TLV_DB_SCALE(volume_tlv, -10000, 100, 0); ++ ++ ++/* Filter Type */ ++static const char * const fir_filter_type_texts[] = { ++ "brick wall", ++ "corrected minimum phase fast", ++ "minimum phase slow", ++ "minimum phase fast", ++ "linear phase slow", ++ "linear phase fast", ++ "apodizing fast", ++}; ++ ++static SOC_ENUM_SINGLE_DECL(i_sabre_fir_filter_type_enum, ++ ISABRECODEC_REG_22, 0, fir_filter_type_texts); ++ ++ ++/* I2S / SPDIF Select */ ++static const char * const iis_spdif_sel_texts[] = { ++ "I2S", ++ "SPDIF", ++}; ++ ++static SOC_ENUM_SINGLE_DECL(i_sabre_iis_spdif_sel_enum, ++ ISABRECODEC_REG_24, 0, iis_spdif_sel_texts); ++ ++ ++/* Control */ ++static const struct snd_kcontrol_new i_sabre_codec_controls[] = { ++SOC_SINGLE_RANGE_TLV("Digital Playback Volume", ISABRECODEC_REG_20, 0, 0, 100, 1, volume_tlv), ++SOC_SINGLE("Digital Playback Switch", ISABRECODEC_REG_21, 0, 1, 1), ++SOC_ENUM("FIR Filter Type", i_sabre_fir_filter_type_enum), ++SOC_ENUM("I2S/SPDIF Select", i_sabre_iis_spdif_sel_enum), ++}; ++ ++ ++static const u32 i_sabre_codec_dai_rates_slave[] = { ++ 8000, 11025, 16000, 22050, 32000, ++ 44100, 48000, 64000, 88200, 96000, ++ 176400, 192000, 352800, 384000, ++ 705600, 768000, 1411200, 1536000 ++}; ++ ++static const struct snd_pcm_hw_constraint_list constraints_slave = { ++ .list = i_sabre_codec_dai_rates_slave, ++ .count = ARRAY_SIZE(i_sabre_codec_dai_rates_slave), ++}; ++ ++static int i_sabre_codec_dai_startup_slave( ++ struct snd_pcm_substream *substream, struct snd_soc_dai *dai) ++{ ++ struct snd_soc_component *component = dai->component; ++ int ret; ++ ++ ret = snd_pcm_hw_constraint_list(substream->runtime, ++ 0, SNDRV_PCM_HW_PARAM_RATE, &constraints_slave); ++ if (ret != 0) { ++ dev_err(component->card->dev, "Failed to setup rates constraints: %d\n", ret); ++ } ++ ++ return ret; ++} ++ ++static int i_sabre_codec_dai_startup( ++ struct snd_pcm_substream *substream, struct snd_soc_dai *dai) ++{ ++ struct snd_soc_component *component = dai->component; ++ struct i_sabre_codec_priv *i_sabre_codec ++ = snd_soc_component_get_drvdata(component); ++ ++ switch (i_sabre_codec->fmt & SND_SOC_DAIFMT_MASTER_MASK) { ++ case SND_SOC_DAIFMT_CBS_CFS: ++ return i_sabre_codec_dai_startup_slave(substream, dai); ++ ++ default: ++ return (-EINVAL); ++ } ++} ++ ++static int i_sabre_codec_hw_params( ++ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_component *component = dai->component; ++ struct i_sabre_codec_priv *i_sabre_codec ++ = snd_soc_component_get_drvdata(component); ++ unsigned int daifmt; ++ int format_width; ++ ++ dev_dbg(component->card->dev, "hw_params %u Hz, %u channels\n", ++ params_rate(params), params_channels(params)); ++ ++ /* Check I2S Format (Bit Size) */ ++ format_width = snd_pcm_format_width(params_format(params)); ++ if ((format_width != 32) && (format_width != 16)) { ++ dev_err(component->card->dev, "Bad frame size: %d\n", ++ snd_pcm_format_width(params_format(params))); ++ return (-EINVAL); ++ } ++ ++ /* Check Slave Mode */ ++ daifmt = i_sabre_codec->fmt & SND_SOC_DAIFMT_MASTER_MASK; ++ if (daifmt != SND_SOC_DAIFMT_CBS_CFS) { ++ return (-EINVAL); ++ } ++ ++ /* Notify Sampling Frequency */ ++ switch (params_rate(params)) ++ { ++ case 44100: ++ case 48000: ++ case 88200: ++ case 96000: ++ case 176400: ++ case 192000: ++ snd_soc_component_update_bits(component, ISABRECODEC_REG_10, 0x01, 0x00); ++ break; ++ ++ case 352800: ++ case 384000: ++ case 705600: ++ case 768000: ++ case 1411200: ++ case 1536000: ++ snd_soc_component_update_bits(component, ISABRECODEC_REG_10, 0x01, 0x01); ++ break; ++ } ++ ++ return 0; ++} ++ ++static int i_sabre_codec_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) ++{ ++ struct snd_soc_component *component = dai->component; ++ struct i_sabre_codec_priv *i_sabre_codec ++ = snd_soc_component_get_drvdata(component); ++ ++ /* interface format */ ++ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { ++ case SND_SOC_DAIFMT_I2S: ++ break; ++ ++ case SND_SOC_DAIFMT_RIGHT_J: ++ case SND_SOC_DAIFMT_LEFT_J: ++ default: ++ return (-EINVAL); ++ } ++ ++ /* clock inversion */ ++ if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) { ++ return (-EINVAL); ++ } ++ ++ /* Set Audio Data Format */ ++ i_sabre_codec->fmt = fmt; ++ ++ return 0; ++} ++ ++static int i_sabre_codec_dac_mute(struct snd_soc_dai *dai, int mute) ++{ ++ struct snd_soc_component *component = dai->component; ++ ++ if (mute) { ++ snd_soc_component_update_bits(component, ISABRECODEC_REG_21, 0x01, 0x01); ++ } else { ++ snd_soc_component_update_bits(component, ISABRECODEC_REG_21, 0x01, 0x00); ++ } ++ ++ return 0; ++} ++ ++ ++static const struct snd_soc_dai_ops i_sabre_codec_dai_ops = { ++ .startup = i_sabre_codec_dai_startup, ++ .hw_params = i_sabre_codec_hw_params, ++ .set_fmt = i_sabre_codec_set_fmt, ++ .digital_mute = i_sabre_codec_dac_mute, ++}; ++ ++static struct snd_soc_dai_driver i_sabre_codec_dai = { ++ .name = "i-sabre-codec-dai", ++ .playback = { ++ .stream_name = "Playback", ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = SNDRV_PCM_RATE_CONTINUOUS, ++ .rate_min = 8000, ++ .rate_max = 1536000, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE ++ | SNDRV_PCM_FMTBIT_S32_LE, ++ }, ++ .ops = &i_sabre_codec_dai_ops, ++}; ++ ++static struct snd_soc_component_driver i_sabre_codec_codec_driver = { ++ .controls = i_sabre_codec_controls, ++ .num_controls = ARRAY_SIZE(i_sabre_codec_controls), ++}; ++ ++ ++static const struct regmap_config i_sabre_codec_regmap = { ++ .reg_bits = 8, ++ .val_bits = 8, ++ .max_register = ISABRECODEC_MAX_REG, ++ ++ .reg_defaults = i_sabre_codec_reg_defaults, ++ .num_reg_defaults = ARRAY_SIZE(i_sabre_codec_reg_defaults), ++ ++ .writeable_reg = i_sabre_codec_writeable, ++ .readable_reg = i_sabre_codec_readable, ++ .volatile_reg = i_sabre_codec_volatile, ++ ++ .cache_type = REGCACHE_RBTREE, ++}; ++ ++ ++static int i_sabre_codec_probe(struct device *dev, struct regmap *regmap) ++{ ++ struct i_sabre_codec_priv *i_sabre_codec; ++ int ret; ++ ++ i_sabre_codec = devm_kzalloc(dev, sizeof(*i_sabre_codec), GFP_KERNEL); ++ if (!i_sabre_codec) { ++ dev_err(dev, "devm_kzalloc"); ++ return (-ENOMEM); ++ } ++ ++ i_sabre_codec->regmap = regmap; ++ ++ dev_set_drvdata(dev, i_sabre_codec); ++ ++ ret = snd_soc_register_component(dev, ++ &i_sabre_codec_codec_driver, &i_sabre_codec_dai, 1); ++ if (ret != 0) { ++ dev_err(dev, "Failed to register CODEC: %d\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void i_sabre_codec_remove(struct device *dev) ++{ ++ snd_soc_unregister_component(dev); ++} ++ ++ ++static int i_sabre_codec_i2c_probe( ++ struct i2c_client *i2c, const struct i2c_device_id *id) ++{ ++ struct regmap *regmap; ++ ++ regmap = devm_regmap_init_i2c(i2c, &i_sabre_codec_regmap); ++ if (IS_ERR(regmap)) { ++ return PTR_ERR(regmap); ++ } ++ ++ return i_sabre_codec_probe(&i2c->dev, regmap); ++} ++ ++static int i_sabre_codec_i2c_remove(struct i2c_client *i2c) ++{ ++ i_sabre_codec_remove(&i2c->dev); ++ ++ return 0; ++} ++ ++ ++static const struct i2c_device_id i_sabre_codec_i2c_id[] = { ++ { "i-sabre-codec", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(i2c, i_sabre_codec_i2c_id); ++ ++static const struct of_device_id i_sabre_codec_of_match[] = { ++ { .compatible = "audiophonics,i-sabre-codec", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, i_sabre_codec_of_match); ++ ++static struct i2c_driver i_sabre_codec_i2c_driver = { ++ .driver = { ++ .name = "i-sabre-codec-i2c", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(i_sabre_codec_of_match), ++ }, ++ .probe = i_sabre_codec_i2c_probe, ++ .remove = i_sabre_codec_i2c_remove, ++ .id_table = i_sabre_codec_i2c_id, ++}; ++module_i2c_driver(i_sabre_codec_i2c_driver); ++ ++ ++MODULE_DESCRIPTION("ASoC I-Sabre Q2M codec driver"); ++MODULE_AUTHOR("Audiophonics "); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ b/sound/soc/codecs/i-sabre-codec.h +@@ -0,0 +1,42 @@ ++/* ++ * Driver for I-Sabre Q2M ++ * ++ * Author: Satoru Kawase ++ * Modified by: Xiao Qingyong ++ * Copyright 2018 Audiophonics ++ * ++ * 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 _SND_SOC_ISABRECODEC ++#define _SND_SOC_ISABRECODEC ++ ++ ++/* ISABRECODEC Register Address */ ++#define ISABRECODEC_REG_01 0x01 /* Virtual Device ID : 0x01 = es9038q2m */ ++#define ISABRECODEC_REG_02 0x02 /* API revision : 0x01 = Revision 01 */ ++#define ISABRECODEC_REG_10 0x10 /* 0x01 = above 192kHz, 0x00 = otherwise */ ++#define ISABRECODEC_REG_20 0x20 /* 0 - 100 (decimal value, 0 = min., 100 = max.) */ ++#define ISABRECODEC_REG_21 0x21 /* 0x00 = Mute OFF, 0x01 = Mute ON */ ++#define ISABRECODEC_REG_22 0x22 ++/* ++ 0x00 = brick wall, ++ 0x01 = corrected minimum phase fast, ++ 0x02 = minimum phase slow, ++ 0x03 = minimum phase fast, ++ 0x04 = linear phase slow, ++ 0x05 = linear phase fast, ++ 0x06 = apodizing fast, ++*/ ++//#define ISABRECODEC_REG_23 0x23 /* reserved */ ++#define ISABRECODEC_REG_24 0x24 /* 0x00 = I2S, 0x01 = SPDIF */ ++#define ISABRECODEC_MAX_REG 0x24 /* Maximum Register Number */ ++ ++#endif /* _SND_SOC_ISABRECODEC */ diff --git a/target/linux/brcm2708/patches-4.19/950-0414-ASoC-tlv320aic32x4-Allow-192000-Sample-Rate.patch b/target/linux/brcm2708/patches-4.19/950-0414-ASoC-tlv320aic32x4-Allow-192000-Sample-Rate.patch deleted file mode 100644 index 75f744adb8..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0414-ASoC-tlv320aic32x4-Allow-192000-Sample-Rate.patch +++ /dev/null @@ -1,27 +0,0 @@ -From c72904446aa20ab6136502697641545cc5e7dc7e Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Thu, 21 Mar 2019 17:58:54 -0700 -Subject: [PATCH 414/703] ASoC: tlv320aic32x4: Allow 192000 Sample Rate - -commit 6d56ee1550b8a81bc63c80051ff78d8d704b09ba upstream. - -The clocking and processing blocks are now properly set up to -support 192000 sample rates. Allow drivers to ask for that. - -Signed-off-by: Annaliese McDermond -Signed-off-by: Mark Brown ---- - sound/soc/codecs/tlv320aic32x4.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/sound/soc/codecs/tlv320aic32x4.c -+++ b/sound/soc/codecs/tlv320aic32x4.c -@@ -859,7 +859,7 @@ static int aic32x4_set_bias_level(struct - return 0; - } - --#define AIC32X4_RATES SNDRV_PCM_RATE_8000_96000 -+#define AIC32X4_RATES SNDRV_PCM_RATE_8000_192000 - #define AIC32X4_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ - | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) - diff --git a/target/linux/brcm2708/patches-4.19/950-0414-ASoC-tlv320aic32x4-Change-author-s-name.patch b/target/linux/brcm2708/patches-4.19/950-0414-ASoC-tlv320aic32x4-Change-author-s-name.patch new file mode 100644 index 0000000000..643ad77403 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0414-ASoC-tlv320aic32x4-Change-author-s-name.patch @@ -0,0 +1,54 @@ +From 05c2d56f6c014aea65288abbb10a28feb2c284fb Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Wed, 3 Apr 2019 21:17:15 -0700 +Subject: [PATCH 414/725] ASoC: tlv320aic32x4: Change author's name + +commit 7297ba6c74c5b9e78d8e936af82eecfcf7d32dfb upstream. + +The author of these files has changed her name. Update +instances in the code of her dead name to current legal +name. + +Signed-off-by: Annaliese McDermond +Signed-off-by: Mark Brown +--- + sound/soc/codecs/tlv320aic32x4-i2c.c | 4 ++-- + sound/soc/codecs/tlv320aic32x4-spi.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/sound/soc/codecs/tlv320aic32x4-i2c.c ++++ b/sound/soc/codecs/tlv320aic32x4-i2c.c +@@ -3,7 +3,7 @@ + * + * Copyright 2011 NW Digital Radio + * +- * Author: Jeremy McDermond ++ * Author: Annaliese McDermond + * + * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27. + * +@@ -72,5 +72,5 @@ static struct i2c_driver aic32x4_i2c_dri + module_i2c_driver(aic32x4_i2c_driver); + + MODULE_DESCRIPTION("ASoC TLV320AIC32x4 codec driver I2C"); +-MODULE_AUTHOR("Jeremy McDermond "); ++MODULE_AUTHOR("Annaliese McDermond "); + MODULE_LICENSE("GPL"); +--- a/sound/soc/codecs/tlv320aic32x4-spi.c ++++ b/sound/soc/codecs/tlv320aic32x4-spi.c +@@ -3,7 +3,7 @@ + * + * Copyright 2011 NW Digital Radio + * +- * Author: Jeremy McDermond ++ * Author: Annaliese McDermond + * + * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27. + * +@@ -74,5 +74,5 @@ static struct spi_driver aic32x4_spi_dri + module_spi_driver(aic32x4_spi_driver); + + MODULE_DESCRIPTION("ASoC TLV320AIC32x4 codec driver SPI"); +-MODULE_AUTHOR("Jeremy McDermond "); ++MODULE_AUTHOR("Annaliese McDermond "); + MODULE_LICENSE("GPL"); diff --git a/target/linux/brcm2708/patches-4.19/950-0415-ASoC-tlv320aic32x4-Only-enable-with-common-clock.patch b/target/linux/brcm2708/patches-4.19/950-0415-ASoC-tlv320aic32x4-Only-enable-with-common-clock.patch deleted file mode 100644 index 06084e41f4..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0415-ASoC-tlv320aic32x4-Only-enable-with-common-clock.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 499d000a3d56edf6c5d2bf81de6d7af5348eb258 Mon Sep 17 00:00:00 2001 -From: Mark Brown -Date: Tue, 26 Mar 2019 13:10:13 +0000 -Subject: [PATCH 415/703] ASoC: tlv320aic32x4: Only enable with common clock - -commit 64f01d2b5ccc621c3aa66b82daf9154f5581f36a upstream. - -Some architectures do not yet support the common clock API at all but -the tlv320aic32x4 driver now requires it. - -Reported-by: Stephen Rothwell -Signed-off-by: Mark Brown ---- - sound/soc/codecs/Kconfig | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/sound/soc/codecs/Kconfig -+++ b/sound/soc/codecs/Kconfig -@@ -170,8 +170,8 @@ config SND_SOC_ALL_CODECS - 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 -- select SND_SOC_TLV320AIC32X4_SPI if SPI_MASTER -+ select SND_SOC_TLV320AIC32X4_I2C if I2C && COMMON_CLK -+ select SND_SOC_TLV320AIC32X4_SPI if SPI_MASTER && COMMON_CLK - select SND_SOC_TLV320AIC3X if I2C - select SND_SOC_TPA6130A2 if I2C - select SND_SOC_TLV320DAC33 if I2C -@@ -1030,11 +1030,13 @@ config SND_SOC_TLV320AIC32X4 - config SND_SOC_TLV320AIC32X4_I2C - tristate "Texas Instruments TLV320AIC32x4 audio CODECs - I2C" - depends on I2C -+ depends on COMMON_CLK - select SND_SOC_TLV320AIC32X4 - - config SND_SOC_TLV320AIC32X4_SPI - tristate "Texas Instruments TLV320AIC32x4 audio CODECs - SPI" - depends on SPI_MASTER -+ depends on COMMON_CLK - select SND_SOC_TLV320AIC32X4 - - config SND_SOC_TLV320AIC3X diff --git a/target/linux/brcm2708/patches-4.19/950-0415-ASoC-tlv320aic32x4-Update-copyright-and-use-SPDX-ide.patch b/target/linux/brcm2708/patches-4.19/950-0415-ASoC-tlv320aic32x4-Update-copyright-and-use-SPDX-ide.patch new file mode 100644 index 0000000000..9ac0a58622 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0415-ASoC-tlv320aic32x4-Update-copyright-and-use-SPDX-ide.patch @@ -0,0 +1,70 @@ +From 019b18d8dd0b7c6e8123ae6fb91235b21d80833b Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Wed, 3 Apr 2019 21:17:16 -0700 +Subject: [PATCH 415/725] ASoC: tlv320aic32x4: Update copyright and use SPDX + identifier + +commit 8a1d95c393d971e624fc28f11516b0bc3a7fa706 upstream. + +Update the copyright dates and use the SPDX identifier instead +of reciting the license. + +Signed-off-by: Annaliese McDermond +Signed-off-by: Mark Brown +--- + sound/soc/codecs/tlv320aic32x4-i2c.c | 14 ++------------ + sound/soc/codecs/tlv320aic32x4-spi.c | 14 ++------------ + 2 files changed, 4 insertions(+), 24 deletions(-) + +--- a/sound/soc/codecs/tlv320aic32x4-i2c.c ++++ b/sound/soc/codecs/tlv320aic32x4-i2c.c +@@ -1,21 +1,11 @@ +-/* +- * linux/sound/soc/codecs/tlv320aic32x4-i2c.c ++/* SPDX-License-Identifier: GPL-2.0 + * +- * Copyright 2011 NW Digital Radio ++ * Copyright 2011-2019 NW Digital Radio + * + * Author: Annaliese McDermond + * + * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27. + * +- * 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. +- * +- * 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 +--- a/sound/soc/codecs/tlv320aic32x4-spi.c ++++ b/sound/soc/codecs/tlv320aic32x4-spi.c +@@ -1,21 +1,11 @@ +-/* +- * linux/sound/soc/codecs/tlv320aic32x4-spi.c ++/* SPDX-License-Identifier: GPL-2.0 + * +- * Copyright 2011 NW Digital Radio ++ * Copyright 2011-2019 NW Digital Radio + * + * Author: Annaliese McDermond + * + * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27. + * +- * 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. +- * +- * 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 diff --git a/target/linux/brcm2708/patches-4.19/950-0416-ASoC-tlv320aic32x4-Add-Switch-for-Setting-Common-Mod.patch b/target/linux/brcm2708/patches-4.19/950-0416-ASoC-tlv320aic32x4-Add-Switch-for-Setting-Common-Mod.patch new file mode 100644 index 0000000000..c300197bf4 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0416-ASoC-tlv320aic32x4-Add-Switch-for-Setting-Common-Mod.patch @@ -0,0 +1,40 @@ +From 283878c9a11df280fe7621f79409a1228de68843 Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Wed, 3 Apr 2019 21:01:54 -0700 +Subject: [PATCH 416/725] ASoC: tlv320aic32x4: Add Switch for Setting Common + Mode Voltage + +commit 44ceee847e27c828f2f1ef4e400e6bc0c8d04de3 upstream. + +Add a switch for setting common mode voltage. This can allow +for higher drive levels on the amplifier outputs. + +Signed-off-by: Annaliese McDermond +Signed-off-by: Mark Brown +--- + sound/soc/codecs/tlv320aic32x4.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/sound/soc/codecs/tlv320aic32x4.c ++++ b/sound/soc/codecs/tlv320aic32x4.c +@@ -242,6 +242,12 @@ static DECLARE_TLV_DB_SCALE(tlv_driver_g + /* -12dB min, 0.5dB steps */ + static DECLARE_TLV_DB_SCALE(tlv_adc_vol, -1200, 50, 0); + ++static const char * const lo_cm_text[] = { ++ "Full Chip", "1.65V", ++}; ++ ++static SOC_ENUM_SINGLE_DECL(lo_cm_enum, AIC32X4_CMMODE, 3, lo_cm_text); ++ + static const struct snd_kcontrol_new aic32x4_snd_controls[] = { + SOC_DOUBLE_R_S_TLV("PCM Playback Volume", AIC32X4_LDACVOL, + AIC32X4_RDACVOL, 0, -0x7f, 0x30, 7, 0, tlv_pcm), +@@ -255,6 +261,7 @@ static const struct snd_kcontrol_new aic + AIC32X4_HPRGAIN, 6, 0x01, 1), + SOC_DOUBLE_R("LO DAC Playback Switch", AIC32X4_LOLGAIN, + AIC32X4_LORGAIN, 6, 0x01, 1), ++ SOC_ENUM("LO Playback Common Mode Switch", lo_cm_enum), + SOC_DOUBLE_R("Mic PGA Switch", AIC32X4_LMICPGAVOL, + AIC32X4_RMICPGAVOL, 7, 0x01, 1), + diff --git a/target/linux/brcm2708/patches-4.19/950-0416-Audiophonics-I-Sabre-9038Q2M-DAC-driver.patch b/target/linux/brcm2708/patches-4.19/950-0416-Audiophonics-I-Sabre-9038Q2M-DAC-driver.patch deleted file mode 100644 index 919faf736b..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0416-Audiophonics-I-Sabre-9038Q2M-DAC-driver.patch +++ /dev/null @@ -1,794 +0,0 @@ -From b40f72a9aeee6ce7d7df3a3b3ff602234215fe79 Mon Sep 17 00:00:00 2001 -From: FERHAT Nicolas -Date: Fri, 5 Apr 2019 13:06:42 +0100 -Subject: [PATCH 416/703] Audiophonics I-Sabre 9038Q2M DAC driver - -Signed-off-by: Audiophonics ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 6 + - .../boot/dts/overlays/i-sabre-q2m-overlay.dts | 39 ++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - arch/arm64/configs/bcmrpi3_defconfig | 1 + - sound/soc/bcm/Kconfig | 7 + - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/i-sabre-q2m.c | 157 +++++++ - sound/soc/codecs/Kconfig | 5 + - sound/soc/codecs/Makefile | 2 + - sound/soc/codecs/i-sabre-codec.c | 392 ++++++++++++++++++ - sound/soc/codecs/i-sabre-codec.h | 42 ++ - 13 files changed, 656 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/i-sabre-q2m-overlay.dts - create mode 100644 sound/soc/bcm/i-sabre-q2m.c - create mode 100644 sound/soc/codecs/i-sabre-codec.c - create mode 100644 sound/soc/codecs/i-sabre-codec.h - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -55,6 +55,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - hy28a.dtbo \ - hy28b.dtbo \ - hy28b-2017.dtbo \ -+ i-sabre-q2m.dtbo \ - i2c-bcm2708.dtbo \ - i2c-gpio.dtbo \ - i2c-mux.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -869,6 +869,12 @@ Params: speed Display - ledgpio GPIO used to control backlight - - -+Name: i-sabre-q2m -+Info: Configures the Audiophonics I-SABRE Q2M DAC -+Load: dtoverlay=i-sabre-q2m -+Params: -+ -+ - Name: i2c-bcm2708 - Info: Fall back to the i2c_bcm2708 driver for the i2c_arm bus. - Load: dtoverlay=i2c-bcm2708 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/i-sabre-q2m-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for I-Sabre Q2M -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ frag0: __overlay__ { -+ compatible = "audiophonics,i-sabre-q2m"; -+ 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"; -+ -+ i-sabre-codec@48 { -+ #sound-dai-cells = <0>; -+ compatible = "audiophonics,i-sabre-codec"; -+ reg = <0x48>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -916,6 +916,7 @@ CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m - CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m -+CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m - CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m - CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m - CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -909,6 +909,7 @@ CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m - CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m -+CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m - CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m - CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m - CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -804,6 +804,7 @@ CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m - CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m -+CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m - CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m - CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m - CONFIG_SND_AUDIOSENSE_PI=m ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -123,6 +123,13 @@ config SND_BCM2708_SOC_IQAUDIO_DIGI - help - Say Y or M if you want to add support for IQAudIO Digital IO board. - -+config SND_BCM2708_SOC_I_SABRE_Q2M -+ tristate "Support for Audiophonics I-Sabre Q2M DAC" -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S -+ select SND_SOC_I_SABRE_CODEC -+ help -+ Say Y or M if you want to add support for Audiophonics I-SABRE Q2M DAC -+ - config SND_BCM2708_SOC_ADAU1977_ADC - tristate "Support for ADAU1977 ADC" - depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -19,6 +19,7 @@ snd-soc-justboom-dac-objs := justboom-da - snd-soc-rpi-cirrus-objs := rpi-cirrus.o - snd-soc-rpi-proto-objs := rpi-proto.o - snd-soc-iqaudio-dac-objs := iqaudio-dac.o -+ snd-soc-i-sabre-q2m-objs := i-sabre-q2m.o - snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o - snd-soc-audioinjector-octo-soundcard-objs := audioinjector-octo-soundcard.o - snd-soc-audiosense-pi-objs := audiosense-pi.o -@@ -42,6 +43,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_JUSTBOOM_DA - obj-$(CONFIG_SND_BCM2708_SOC_RPI_CIRRUS) += snd-soc-rpi-cirrus.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 -+ obj-$(CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M) += snd-soc-i-sabre-q2m.o - obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o - obj-$(CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD) += snd-soc-audioinjector-octo-soundcard.o - obj-$(CONFIG_SND_AUDIOSENSE_PI) += snd-soc-audiosense-pi.o ---- /dev/null -+++ b/sound/soc/bcm/i-sabre-q2m.c -@@ -0,0 +1,157 @@ -+/* -+ * ASoC Driver for I-Sabre Q2M -+ * -+ * Author: Satoru Kawase -+ * Modified by: Xiao Qingyong -+ * Update kernel v4.18+ by : Audiophonics -+ * Copyright 2018 Audiophonics -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "../codecs/i-sabre-codec.h" -+ -+ -+static int snd_rpi_i_sabre_q2m_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ struct snd_soc_component *component = rtd->codec_dai->component; -+ unsigned int value; -+ -+ /* Device ID */ -+ value = snd_soc_component_read32(component, ISABRECODEC_REG_01); -+ dev_info(component->card->dev, "Audiophonics Device ID : %02X\n", value); -+ -+ /* API revision */ -+ value = snd_soc_component_read32(component, ISABRECODEC_REG_02); -+ dev_info(component->card->dev, "Audiophonics API revision : %02X\n", value); -+ -+ return 0; -+} -+ -+static int snd_rpi_i_sabre_q2m_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; -+ int bclk_ratio; -+ -+ bclk_ratio = snd_pcm_format_physical_width( -+ params_format(params)) * params_channels(params); -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, bclk_ratio); -+} -+ -+/* machine stream operations */ -+static struct snd_soc_ops snd_rpi_i_sabre_q2m_ops = { -+ .hw_params = snd_rpi_i_sabre_q2m_hw_params, -+}; -+ -+ -+static struct snd_soc_dai_link snd_rpi_i_sabre_q2m_dai[] = { -+ { -+ .name = "I-Sabre Q2M", -+ .stream_name = "I-Sabre Q2M DAC", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "i-sabre-codec-dai", -+ .platform_name = "bcm2708-i2s.0", -+ .codec_name = "i-sabre-codec-i2c.1-0048", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF -+ | SND_SOC_DAIFMT_CBS_CFS, -+ .init = snd_rpi_i_sabre_q2m_init, -+ .ops = &snd_rpi_i_sabre_q2m_ops, -+ } -+}; -+ -+/* audio machine driver */ -+static struct snd_soc_card snd_rpi_i_sabre_q2m = { -+ .name = "I-Sabre Q2M DAC", -+ .owner = THIS_MODULE, -+ .dai_link = snd_rpi_i_sabre_q2m_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_i_sabre_q2m_dai) -+}; -+ -+ -+static int snd_rpi_i_sabre_q2m_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_i_sabre_q2m.dev = &pdev->dev; -+ if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai; -+ -+ dai = &snd_rpi_i_sabre_q2m_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; -+ } else { -+ dev_err(&pdev->dev, -+ "Property 'i2s-controller' missing or invalid\n"); -+ return (-EINVAL); -+ } -+ -+ dai->name = "I-Sabre Q2M"; -+ dai->stream_name = "I-Sabre Q2M DAC"; -+ dai->dai_fmt = SND_SOC_DAIFMT_I2S -+ | SND_SOC_DAIFMT_NB_NF -+ | SND_SOC_DAIFMT_CBS_CFS; -+ } -+ -+ /* Wait for registering codec driver */ -+ mdelay(50); -+ -+ ret = snd_soc_register_card(&snd_rpi_i_sabre_q2m); -+ if (ret) { -+ dev_err(&pdev->dev, -+ "snd_soc_register_card() failed: %d\n", ret); -+ } -+ -+ return ret; -+} -+ -+static int snd_rpi_i_sabre_q2m_remove(struct platform_device *pdev) -+{ -+ return snd_soc_unregister_card(&snd_rpi_i_sabre_q2m); -+} -+ -+static const struct of_device_id snd_rpi_i_sabre_q2m_of_match[] = { -+ { .compatible = "audiophonics,i-sabre-q2m", }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, snd_rpi_i_sabre_q2m_of_match); -+ -+static struct platform_driver snd_rpi_i_sabre_q2m_driver = { -+ .driver = { -+ .name = "snd-rpi-i-sabre-q2m", -+ .owner = THIS_MODULE, -+ .of_match_table = snd_rpi_i_sabre_q2m_of_match, -+ }, -+ .probe = snd_rpi_i_sabre_q2m_probe, -+ .remove = snd_rpi_i_sabre_q2m_remove, -+}; -+module_platform_driver(snd_rpi_i_sabre_q2m_driver); -+ -+MODULE_DESCRIPTION("ASoC Driver for I-Sabre Q2M"); -+MODULE_AUTHOR("Audiophonics "); -+MODULE_LICENSE("GPL"); ---- a/sound/soc/codecs/Kconfig -+++ b/sound/soc/codecs/Kconfig -@@ -85,6 +85,7 @@ config SND_SOC_ALL_CODECS - select SND_SOC_ICS43432 - select SND_SOC_INNO_RK3036 - select SND_SOC_ISABELLE if I2C -+ select SND_SOC_I_SABRE_CODEC if I2C - select SND_SOC_JZ4740_CODEC - select SND_SOC_LM4857 if I2C - select SND_SOC_LM49453 if I2C -@@ -1322,4 +1323,8 @@ config SND_SOC_TPA6130A2 - tristate "Texas Instruments TPA6130A2 headphone amplifier" - depends on I2C - -+config SND_SOC_I_SABRE_CODEC -+ tristate "Audiophonics I-SABRE Codec" -+ depends on I2C -+ - endmenu ---- a/sound/soc/codecs/Makefile -+++ b/sound/soc/codecs/Makefile -@@ -81,6 +81,7 @@ snd-soc-hdac-hdmi-objs := hdac_hdmi.o - snd-soc-ics43432-objs := ics43432.o - snd-soc-inno-rk3036-objs := inno_rk3036.o - snd-soc-isabelle-objs := isabelle.o -+snd-soc-i-sabre-codec-objs := i-sabre-codec.o - snd-soc-jz4740-codec-objs := jz4740.o - snd-soc-l3-objs := l3.o - snd-soc-lm4857-objs := lm4857.o -@@ -343,6 +344,7 @@ obj-$(CONFIG_SND_SOC_HDAC_HDMI) += snd-s - obj-$(CONFIG_SND_SOC_ICS43432) += snd-soc-ics43432.o - obj-$(CONFIG_SND_SOC_INNO_RK3036) += snd-soc-inno-rk3036.o - obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o -+obj-$(CONFIG_SND_SOC_I_SABRE_CODEC) += snd-soc-i-sabre-codec.o - obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o - obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o - obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o ---- /dev/null -+++ b/sound/soc/codecs/i-sabre-codec.c -@@ -0,0 +1,392 @@ -+/* -+ * Driver for I-Sabre Q2M -+ * -+ * Author: Satoru Kawase -+ * Modified by: Xiao Qingyong -+ * Modified by: JC BARBAUD (Mute) -+ * Update kernel v4.18+ by : Audiophonics -+ * Copyright 2018 Audiophonics -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "i-sabre-codec.h" -+ -+ -+/* I-Sabre Q2M Codec Private Data */ -+struct i_sabre_codec_priv { -+ struct regmap *regmap; -+ unsigned int fmt; -+}; -+ -+ -+/* I-Sabre Q2M Codec Default Register Value */ -+static const struct reg_default i_sabre_codec_reg_defaults[] = { -+ { ISABRECODEC_REG_10, 0x00 }, -+ { ISABRECODEC_REG_20, 0x00 }, -+ { ISABRECODEC_REG_21, 0x00 }, -+ { ISABRECODEC_REG_22, 0x00 }, -+ { ISABRECODEC_REG_24, 0x00 }, -+}; -+ -+ -+static bool i_sabre_codec_writeable(struct device *dev, unsigned int reg) -+{ -+ switch (reg) { -+ case ISABRECODEC_REG_10: -+ case ISABRECODEC_REG_20: -+ case ISABRECODEC_REG_21: -+ case ISABRECODEC_REG_22: -+ case ISABRECODEC_REG_24: -+ return true; -+ -+ default: -+ return false; -+ } -+} -+ -+static bool i_sabre_codec_readable(struct device *dev, unsigned int reg) -+{ -+ switch (reg) { -+ case ISABRECODEC_REG_01: -+ case ISABRECODEC_REG_02: -+ case ISABRECODEC_REG_10: -+ case ISABRECODEC_REG_20: -+ case ISABRECODEC_REG_21: -+ case ISABRECODEC_REG_22: -+ case ISABRECODEC_REG_24: -+ return true; -+ -+ default: -+ return false; -+ } -+} -+ -+static bool i_sabre_codec_volatile(struct device *dev, unsigned int reg) -+{ -+ switch (reg) { -+ case ISABRECODEC_REG_01: -+ case ISABRECODEC_REG_02: -+ return true; -+ -+ default: -+ return false; -+ } -+} -+ -+ -+/* Volume Scale */ -+static const DECLARE_TLV_DB_SCALE(volume_tlv, -10000, 100, 0); -+ -+ -+/* Filter Type */ -+static const char * const fir_filter_type_texts[] = { -+ "brick wall", -+ "corrected minimum phase fast", -+ "minimum phase slow", -+ "minimum phase fast", -+ "linear phase slow", -+ "linear phase fast", -+ "apodizing fast", -+}; -+ -+static SOC_ENUM_SINGLE_DECL(i_sabre_fir_filter_type_enum, -+ ISABRECODEC_REG_22, 0, fir_filter_type_texts); -+ -+ -+/* I2S / SPDIF Select */ -+static const char * const iis_spdif_sel_texts[] = { -+ "I2S", -+ "SPDIF", -+}; -+ -+static SOC_ENUM_SINGLE_DECL(i_sabre_iis_spdif_sel_enum, -+ ISABRECODEC_REG_24, 0, iis_spdif_sel_texts); -+ -+ -+/* Control */ -+static const struct snd_kcontrol_new i_sabre_codec_controls[] = { -+SOC_SINGLE_RANGE_TLV("Digital Playback Volume", ISABRECODEC_REG_20, 0, 0, 100, 1, volume_tlv), -+SOC_SINGLE("Digital Playback Switch", ISABRECODEC_REG_21, 0, 1, 1), -+SOC_ENUM("FIR Filter Type", i_sabre_fir_filter_type_enum), -+SOC_ENUM("I2S/SPDIF Select", i_sabre_iis_spdif_sel_enum), -+}; -+ -+ -+static const u32 i_sabre_codec_dai_rates_slave[] = { -+ 8000, 11025, 16000, 22050, 32000, -+ 44100, 48000, 64000, 88200, 96000, -+ 176400, 192000, 352800, 384000, -+ 705600, 768000, 1411200, 1536000 -+}; -+ -+static const struct snd_pcm_hw_constraint_list constraints_slave = { -+ .list = i_sabre_codec_dai_rates_slave, -+ .count = ARRAY_SIZE(i_sabre_codec_dai_rates_slave), -+}; -+ -+static int i_sabre_codec_dai_startup_slave( -+ struct snd_pcm_substream *substream, struct snd_soc_dai *dai) -+{ -+ struct snd_soc_component *component = dai->component; -+ int ret; -+ -+ ret = snd_pcm_hw_constraint_list(substream->runtime, -+ 0, SNDRV_PCM_HW_PARAM_RATE, &constraints_slave); -+ if (ret != 0) { -+ dev_err(component->card->dev, "Failed to setup rates constraints: %d\n", ret); -+ } -+ -+ return ret; -+} -+ -+static int i_sabre_codec_dai_startup( -+ struct snd_pcm_substream *substream, struct snd_soc_dai *dai) -+{ -+ struct snd_soc_component *component = dai->component; -+ struct i_sabre_codec_priv *i_sabre_codec -+ = snd_soc_component_get_drvdata(component); -+ -+ switch (i_sabre_codec->fmt & SND_SOC_DAIFMT_MASTER_MASK) { -+ case SND_SOC_DAIFMT_CBS_CFS: -+ return i_sabre_codec_dai_startup_slave(substream, dai); -+ -+ default: -+ return (-EINVAL); -+ } -+} -+ -+static int i_sabre_codec_hw_params( -+ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, -+ struct snd_soc_dai *dai) -+{ -+ struct snd_soc_component *component = dai->component; -+ struct i_sabre_codec_priv *i_sabre_codec -+ = snd_soc_component_get_drvdata(component); -+ unsigned int daifmt; -+ int format_width; -+ -+ dev_dbg(component->card->dev, "hw_params %u Hz, %u channels\n", -+ params_rate(params), params_channels(params)); -+ -+ /* Check I2S Format (Bit Size) */ -+ format_width = snd_pcm_format_width(params_format(params)); -+ if ((format_width != 32) && (format_width != 16)) { -+ dev_err(component->card->dev, "Bad frame size: %d\n", -+ snd_pcm_format_width(params_format(params))); -+ return (-EINVAL); -+ } -+ -+ /* Check Slave Mode */ -+ daifmt = i_sabre_codec->fmt & SND_SOC_DAIFMT_MASTER_MASK; -+ if (daifmt != SND_SOC_DAIFMT_CBS_CFS) { -+ return (-EINVAL); -+ } -+ -+ /* Notify Sampling Frequency */ -+ switch (params_rate(params)) -+ { -+ case 44100: -+ case 48000: -+ case 88200: -+ case 96000: -+ case 176400: -+ case 192000: -+ snd_soc_component_update_bits(component, ISABRECODEC_REG_10, 0x01, 0x00); -+ break; -+ -+ case 352800: -+ case 384000: -+ case 705600: -+ case 768000: -+ case 1411200: -+ case 1536000: -+ snd_soc_component_update_bits(component, ISABRECODEC_REG_10, 0x01, 0x01); -+ break; -+ } -+ -+ return 0; -+} -+ -+static int i_sabre_codec_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) -+{ -+ struct snd_soc_component *component = dai->component; -+ struct i_sabre_codec_priv *i_sabre_codec -+ = snd_soc_component_get_drvdata(component); -+ -+ /* interface format */ -+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { -+ case SND_SOC_DAIFMT_I2S: -+ break; -+ -+ case SND_SOC_DAIFMT_RIGHT_J: -+ case SND_SOC_DAIFMT_LEFT_J: -+ default: -+ return (-EINVAL); -+ } -+ -+ /* clock inversion */ -+ if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) { -+ return (-EINVAL); -+ } -+ -+ /* Set Audio Data Format */ -+ i_sabre_codec->fmt = fmt; -+ -+ return 0; -+} -+ -+static int i_sabre_codec_dac_mute(struct snd_soc_dai *dai, int mute) -+{ -+ struct snd_soc_component *component = dai->component; -+ -+ if (mute) { -+ snd_soc_component_update_bits(component, ISABRECODEC_REG_21, 0x01, 0x01); -+ } else { -+ snd_soc_component_update_bits(component, ISABRECODEC_REG_21, 0x01, 0x00); -+ } -+ -+ return 0; -+} -+ -+ -+static const struct snd_soc_dai_ops i_sabre_codec_dai_ops = { -+ .startup = i_sabre_codec_dai_startup, -+ .hw_params = i_sabre_codec_hw_params, -+ .set_fmt = i_sabre_codec_set_fmt, -+ .digital_mute = i_sabre_codec_dac_mute, -+}; -+ -+static struct snd_soc_dai_driver i_sabre_codec_dai = { -+ .name = "i-sabre-codec-dai", -+ .playback = { -+ .stream_name = "Playback", -+ .channels_min = 2, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_CONTINUOUS, -+ .rate_min = 8000, -+ .rate_max = 1536000, -+ .formats = SNDRV_PCM_FMTBIT_S16_LE -+ | SNDRV_PCM_FMTBIT_S32_LE, -+ }, -+ .ops = &i_sabre_codec_dai_ops, -+}; -+ -+static struct snd_soc_component_driver i_sabre_codec_codec_driver = { -+ .controls = i_sabre_codec_controls, -+ .num_controls = ARRAY_SIZE(i_sabre_codec_controls), -+}; -+ -+ -+static const struct regmap_config i_sabre_codec_regmap = { -+ .reg_bits = 8, -+ .val_bits = 8, -+ .max_register = ISABRECODEC_MAX_REG, -+ -+ .reg_defaults = i_sabre_codec_reg_defaults, -+ .num_reg_defaults = ARRAY_SIZE(i_sabre_codec_reg_defaults), -+ -+ .writeable_reg = i_sabre_codec_writeable, -+ .readable_reg = i_sabre_codec_readable, -+ .volatile_reg = i_sabre_codec_volatile, -+ -+ .cache_type = REGCACHE_RBTREE, -+}; -+ -+ -+static int i_sabre_codec_probe(struct device *dev, struct regmap *regmap) -+{ -+ struct i_sabre_codec_priv *i_sabre_codec; -+ int ret; -+ -+ i_sabre_codec = devm_kzalloc(dev, sizeof(*i_sabre_codec), GFP_KERNEL); -+ if (!i_sabre_codec) { -+ dev_err(dev, "devm_kzalloc"); -+ return (-ENOMEM); -+ } -+ -+ i_sabre_codec->regmap = regmap; -+ -+ dev_set_drvdata(dev, i_sabre_codec); -+ -+ ret = snd_soc_register_component(dev, -+ &i_sabre_codec_codec_driver, &i_sabre_codec_dai, 1); -+ if (ret != 0) { -+ dev_err(dev, "Failed to register CODEC: %d\n", ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void i_sabre_codec_remove(struct device *dev) -+{ -+ snd_soc_unregister_component(dev); -+} -+ -+ -+static int i_sabre_codec_i2c_probe( -+ struct i2c_client *i2c, const struct i2c_device_id *id) -+{ -+ struct regmap *regmap; -+ -+ regmap = devm_regmap_init_i2c(i2c, &i_sabre_codec_regmap); -+ if (IS_ERR(regmap)) { -+ return PTR_ERR(regmap); -+ } -+ -+ return i_sabre_codec_probe(&i2c->dev, regmap); -+} -+ -+static int i_sabre_codec_i2c_remove(struct i2c_client *i2c) -+{ -+ i_sabre_codec_remove(&i2c->dev); -+ -+ return 0; -+} -+ -+ -+static const struct i2c_device_id i_sabre_codec_i2c_id[] = { -+ { "i-sabre-codec", }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, i_sabre_codec_i2c_id); -+ -+static const struct of_device_id i_sabre_codec_of_match[] = { -+ { .compatible = "audiophonics,i-sabre-codec", }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, i_sabre_codec_of_match); -+ -+static struct i2c_driver i_sabre_codec_i2c_driver = { -+ .driver = { -+ .name = "i-sabre-codec-i2c", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(i_sabre_codec_of_match), -+ }, -+ .probe = i_sabre_codec_i2c_probe, -+ .remove = i_sabre_codec_i2c_remove, -+ .id_table = i_sabre_codec_i2c_id, -+}; -+module_i2c_driver(i_sabre_codec_i2c_driver); -+ -+ -+MODULE_DESCRIPTION("ASoC I-Sabre Q2M codec driver"); -+MODULE_AUTHOR("Audiophonics "); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/sound/soc/codecs/i-sabre-codec.h -@@ -0,0 +1,42 @@ -+/* -+ * Driver for I-Sabre Q2M -+ * -+ * Author: Satoru Kawase -+ * Modified by: Xiao Qingyong -+ * Copyright 2018 Audiophonics -+ * -+ * 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 _SND_SOC_ISABRECODEC -+#define _SND_SOC_ISABRECODEC -+ -+ -+/* ISABRECODEC Register Address */ -+#define ISABRECODEC_REG_01 0x01 /* Virtual Device ID : 0x01 = es9038q2m */ -+#define ISABRECODEC_REG_02 0x02 /* API revision : 0x01 = Revision 01 */ -+#define ISABRECODEC_REG_10 0x10 /* 0x01 = above 192kHz, 0x00 = otherwise */ -+#define ISABRECODEC_REG_20 0x20 /* 0 - 100 (decimal value, 0 = min., 100 = max.) */ -+#define ISABRECODEC_REG_21 0x21 /* 0x00 = Mute OFF, 0x01 = Mute ON */ -+#define ISABRECODEC_REG_22 0x22 -+/* -+ 0x00 = brick wall, -+ 0x01 = corrected minimum phase fast, -+ 0x02 = minimum phase slow, -+ 0x03 = minimum phase fast, -+ 0x04 = linear phase slow, -+ 0x05 = linear phase fast, -+ 0x06 = apodizing fast, -+*/ -+//#define ISABRECODEC_REG_23 0x23 /* reserved */ -+#define ISABRECODEC_REG_24 0x24 /* 0x00 = I2S, 0x01 = SPDIF */ -+#define ISABRECODEC_MAX_REG 0x24 /* Maximum Register Number */ -+ -+#endif /* _SND_SOC_ISABRECODEC */ diff --git a/target/linux/brcm2708/patches-4.19/950-0417-ASoC-tlv320aic32x4-Add-Playback-PowerTune-Controls.patch b/target/linux/brcm2708/patches-4.19/950-0417-ASoC-tlv320aic32x4-Add-Playback-PowerTune-Controls.patch new file mode 100644 index 0000000000..ae317c813c --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0417-ASoC-tlv320aic32x4-Add-Playback-PowerTune-Controls.patch @@ -0,0 +1,52 @@ +From 731092f2b29ef4e1c0081698d683d9542426e500 Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Wed, 3 Apr 2019 21:01:55 -0700 +Subject: [PATCH 417/725] ASoC: tlv320aic32x4: Add Playback PowerTune Controls + +commit d3e6e374566e1154820a9a3dc82f7eef646fcf95 upstream. + +PowerTune controls the power level of the chip. On playback this +indirectly controls things like the gain of the various output +amplifiers. This can allow for the decrease of output levels +from the codec. This adds controls for those power levels to +the driver. + +Signed-off-by: Annaliese McDermond +Signed-off-by: Mark Brown +--- + sound/soc/codecs/tlv320aic32x4.c | 9 +++++++++ + sound/soc/codecs/tlv320aic32x4.h | 2 ++ + 2 files changed, 11 insertions(+) + +--- a/sound/soc/codecs/tlv320aic32x4.c ++++ b/sound/soc/codecs/tlv320aic32x4.c +@@ -248,9 +248,18 @@ static const char * const lo_cm_text[] = + + static SOC_ENUM_SINGLE_DECL(lo_cm_enum, AIC32X4_CMMODE, 3, lo_cm_text); + ++static const char * const ptm_text[] = { ++ "P3", "P2", "P1", ++}; ++ ++static SOC_ENUM_SINGLE_DECL(l_ptm_enum, AIC32X4_LPLAYBACK, 2, ptm_text); ++static SOC_ENUM_SINGLE_DECL(r_ptm_enum, AIC32X4_RPLAYBACK, 2, ptm_text); ++ + static const struct snd_kcontrol_new aic32x4_snd_controls[] = { + SOC_DOUBLE_R_S_TLV("PCM Playback Volume", AIC32X4_LDACVOL, + AIC32X4_RDACVOL, 0, -0x7f, 0x30, 7, 0, tlv_pcm), ++ SOC_ENUM("DAC Left Playback PowerTune Switch", l_ptm_enum), ++ SOC_ENUM("DAC Right Playback PowerTune Switch", r_ptm_enum), + SOC_DOUBLE_R_S_TLV("HP Driver Gain Volume", AIC32X4_HPLGAIN, + AIC32X4_HPRGAIN, 0, -0x6, 0x1d, 5, 0, + tlv_driver_gain), +--- a/sound/soc/codecs/tlv320aic32x4.h ++++ b/sound/soc/codecs/tlv320aic32x4.h +@@ -78,6 +78,8 @@ int aic32x4_register_clocks(struct devic + + #define AIC32X4_PWRCFG AIC32X4_REG(1, 1) + #define AIC32X4_LDOCTL AIC32X4_REG(1, 2) ++#define AIC32X4_LPLAYBACK AIC32X4_REG(1, 3) ++#define AIC32X4_RPLAYBACK AIC32X4_REG(1, 4) + #define AIC32X4_OUTPWRCTL AIC32X4_REG(1, 9) + #define AIC32X4_CMMODE AIC32X4_REG(1, 10) + #define AIC32X4_HPLROUTE AIC32X4_REG(1, 12) diff --git a/target/linux/brcm2708/patches-4.19/950-0417-ASoC-tlv320aic32x4-Change-author-s-name.patch b/target/linux/brcm2708/patches-4.19/950-0417-ASoC-tlv320aic32x4-Change-author-s-name.patch deleted file mode 100644 index 1c01edc304..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0417-ASoC-tlv320aic32x4-Change-author-s-name.patch +++ /dev/null @@ -1,54 +0,0 @@ -From fcde4e55513ec62d7a0fdc18c9db9445de741f4f Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Wed, 3 Apr 2019 21:17:15 -0700 -Subject: [PATCH 417/703] ASoC: tlv320aic32x4: Change author's name - -commit 7297ba6c74c5b9e78d8e936af82eecfcf7d32dfb upstream. - -The author of these files has changed her name. Update -instances in the code of her dead name to current legal -name. - -Signed-off-by: Annaliese McDermond -Signed-off-by: Mark Brown ---- - sound/soc/codecs/tlv320aic32x4-i2c.c | 4 ++-- - sound/soc/codecs/tlv320aic32x4-spi.c | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - ---- a/sound/soc/codecs/tlv320aic32x4-i2c.c -+++ b/sound/soc/codecs/tlv320aic32x4-i2c.c -@@ -3,7 +3,7 @@ - * - * Copyright 2011 NW Digital Radio - * -- * Author: Jeremy McDermond -+ * Author: Annaliese McDermond - * - * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27. - * -@@ -72,5 +72,5 @@ static struct i2c_driver aic32x4_i2c_dri - module_i2c_driver(aic32x4_i2c_driver); - - MODULE_DESCRIPTION("ASoC TLV320AIC32x4 codec driver I2C"); --MODULE_AUTHOR("Jeremy McDermond "); -+MODULE_AUTHOR("Annaliese McDermond "); - MODULE_LICENSE("GPL"); ---- a/sound/soc/codecs/tlv320aic32x4-spi.c -+++ b/sound/soc/codecs/tlv320aic32x4-spi.c -@@ -3,7 +3,7 @@ - * - * Copyright 2011 NW Digital Radio - * -- * Author: Jeremy McDermond -+ * Author: Annaliese McDermond - * - * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27. - * -@@ -74,5 +74,5 @@ static struct spi_driver aic32x4_spi_dri - module_spi_driver(aic32x4_spi_driver); - - MODULE_DESCRIPTION("ASoC TLV320AIC32x4 codec driver SPI"); --MODULE_AUTHOR("Jeremy McDermond "); -+MODULE_AUTHOR("Annaliese McDermond "); - MODULE_LICENSE("GPL"); diff --git a/target/linux/brcm2708/patches-4.19/950-0418-ASoC-tlv320aic32x4-Update-copyright-and-use-SPDX-ide.patch b/target/linux/brcm2708/patches-4.19/950-0418-ASoC-tlv320aic32x4-Update-copyright-and-use-SPDX-ide.patch deleted file mode 100644 index 530f8a495b..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0418-ASoC-tlv320aic32x4-Update-copyright-and-use-SPDX-ide.patch +++ /dev/null @@ -1,70 +0,0 @@ -From c287dc67e33f04d09f8bc0d2cdf900d6b720fc78 Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Wed, 3 Apr 2019 21:17:16 -0700 -Subject: [PATCH 418/703] ASoC: tlv320aic32x4: Update copyright and use SPDX - identifier - -commit 8a1d95c393d971e624fc28f11516b0bc3a7fa706 upstream. - -Update the copyright dates and use the SPDX identifier instead -of reciting the license. - -Signed-off-by: Annaliese McDermond -Signed-off-by: Mark Brown ---- - sound/soc/codecs/tlv320aic32x4-i2c.c | 14 ++------------ - sound/soc/codecs/tlv320aic32x4-spi.c | 14 ++------------ - 2 files changed, 4 insertions(+), 24 deletions(-) - ---- a/sound/soc/codecs/tlv320aic32x4-i2c.c -+++ b/sound/soc/codecs/tlv320aic32x4-i2c.c -@@ -1,21 +1,11 @@ --/* -- * linux/sound/soc/codecs/tlv320aic32x4-i2c.c -+/* SPDX-License-Identifier: GPL-2.0 - * -- * Copyright 2011 NW Digital Radio -+ * Copyright 2011-2019 NW Digital Radio - * - * Author: Annaliese McDermond - * - * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27. - * -- * 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. -- * -- * 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 ---- a/sound/soc/codecs/tlv320aic32x4-spi.c -+++ b/sound/soc/codecs/tlv320aic32x4-spi.c -@@ -1,21 +1,11 @@ --/* -- * linux/sound/soc/codecs/tlv320aic32x4-spi.c -+/* SPDX-License-Identifier: GPL-2.0 - * -- * Copyright 2011 NW Digital Radio -+ * Copyright 2011-2019 NW Digital Radio - * - * Author: Annaliese McDermond - * - * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27. - * -- * 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. -- * -- * 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 diff --git a/target/linux/brcm2708/patches-4.19/950-0418-dtoverlays-Add-Support-for-the-UDRC-DRAWS.patch b/target/linux/brcm2708/patches-4.19/950-0418-dtoverlays-Add-Support-for-the-UDRC-DRAWS.patch new file mode 100644 index 0000000000..04b0813921 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0418-dtoverlays-Add-Support-for-the-UDRC-DRAWS.patch @@ -0,0 +1,445 @@ +From 3fbe7d511602b2888eec568b8870484a06e165e7 Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Sun, 17 Mar 2019 16:48:36 -0700 +Subject: [PATCH 418/725] dtoverlays: Add Support for the UDRC/DRAWS + +Adds a new overlay to support the Northwest Digital Radio +DRAWS and UDRC HATs. See http://nwdigitalradio.com. + +Signed-off-by: Annaliese McDermond +--- + arch/arm/boot/dts/overlays/Makefile | 2 + + arch/arm/boot/dts/overlays/README | 59 ++++++ + arch/arm/boot/dts/overlays/draws-overlay.dts | 200 +++++++++++++++++++ + arch/arm/boot/dts/overlays/udrc-overlay.dts | 128 ++++++++++++ + 4 files changed, 389 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/draws-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/udrc-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -29,6 +29,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + dionaudio-loco-v2.dtbo \ + dpi18.dtbo \ + dpi24.dtbo \ ++ draws.dtbo \ + dwc-otg.dtbo \ + dwc2.dtbo \ + enc28j60.dtbo \ +@@ -146,6 +147,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + tpm-slb9670.dtbo \ + uart0.dtbo \ + uart1.dtbo \ ++ udrc.dtbo \ + upstream.dtbo \ + upstream-aux-interrupt.dtbo \ + vc4-fkms-v3d.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -531,6 +531,59 @@ Load: dtoverlay=dpi24 + Params: + + ++Name: draws ++Info: Configures the NW Digital Radio DRAWS Hat ++ ++ The board includes an ADC to measure various board values and also ++ provides two analog user inputs on the expansion header. The ADC ++ can be configured for various sample rates and gain values to adjust ++ the input range. Tables describing the two parameters follow. ++ ++ ADC Gain Values: ++ 0 = +/- 6.144V ++ 1 = +/- 4.096V ++ 2 = +/- 2.048V ++ 3 = +/- 1.024V ++ 4 = +/- 0.512V ++ 5 = +/- 0.256V ++ 6 = +/- 0.256V ++ 7 = +/- 0.256V ++ ++ ADC Datarate Values: ++ 0 = 128sps ++ 1 = 250sps ++ 2 = 490sps ++ 3 = 920sps ++ 4 = 1600sps (default) ++ 5 = 2400sps ++ 6 = 3300sps ++ 7 = 3300sps ++Load: dtoverlay=draws,= ++Params: draws_adc_ch4_gain Sets the full scale resolution of the ADCs ++ input voltage sensor (default 1) ++ ++ draws_adc_ch4_datarate Sets the datarate of the ADCs input voltage ++ sensor ++ ++ draws_adc_ch5_gain Sets the full scale resolution of the ADCs ++ 5V rail voltage sensor (default 1) ++ ++ draws_adc_ch5_datarate Sets the datarate of the ADCs 4V rail voltage ++ sensor ++ ++ draws_adc_ch6_gain Sets the full scale resolution of the ADCs ++ AIN2 input (default 2) ++ ++ draws_adc_ch6_datarate Sets the datarate of the ADCs AIN2 input ++ ++ draws_adc_ch7_gain Sets the full scale resolution of the ADCs ++ AIN3 input (default 2) ++ ++ draws_adc_ch7_datarate Sets the datarate of the ADCs AIN3 input ++ ++ alsaname Name of the ALSA audio device (default "draws") ++ ++ + Name: dwc-otg + Info: Selects the dwc_otg USB controller driver which has fiq support. This + is the default on all except the Pi Zero which defaults to dwc2. +@@ -2117,6 +2170,12 @@ Params: txd1_pin GPIO pin + rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) + + ++Name: udrc ++Info: Configures the NW Digital Radio UDRC Hat ++Load: dtoverlay=udrc,= ++Params: alsaname Name of the ALSA audio device (default "udrc") ++ ++ + Name: upstream + Info: Allow usage of downstream .dtb with upstream kernel. Comprises + vc4-kms-v3d, dwc2 and upstream-aux-interrupt overlays. +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/draws-overlay.dts +@@ -0,0 +1,200 @@ ++#include ++/* ++ * Device tree overlay for the DRAWS Hardware ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ fragment@0 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ regulators { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ udrc0_ldoin: udrc0_ldoin { ++ compatible = "regulator-fixed"; ++ regulator-name = "ldoin"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ }; ++ }; ++ ++ pps: pps { ++ compatible = "pps-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pps_pins>; ++ gpios = <&gpio 7 0>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c_arm>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ tlv320aic32x4: tlv320aic32x4@18 { ++ compatible = "ti,tlv320aic32x4"; ++ reg = <0x18>; ++ #sound-dai-cells = <0>; ++ status = "okay"; ++ ++ clocks = <&clocks BCM2835_CLOCK_GP0>; ++ clock-names = "mclk"; ++ assigned-clocks = <&clocks BCM2835_CLOCK_GP0>; ++ assigned-clock-rates = <25000000>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpclk0_pin &aic3204_reset>; ++ ++ reset-gpios = <&gpio 13 0>; ++ ++ iov-supply = <&udrc0_ldoin>; ++ ldoin-supply = <&udrc0_ldoin>; ++ }; ++ ++ sc16is752: sc16is752@50 { ++ compatible = "nxp,sc16is752"; ++ reg = <0x50>; ++ clocks = <&sc16is752_clk>; ++ interrupt-parent = <&gpio>; ++ interrupts = <17 2>; /* IRQ_TYPE_EDGE_FALLING */ ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sc16is752_irq>; ++ ++ sc16is752_clk: sc16is752_clk { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <1843200>; ++ }; ++ }; ++ ++ tla2024: tla2024@48 { ++ compatible = "ti,ads1015"; ++ reg = <0x48>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ adc_ch4: channel@4 { ++ reg = <4>; ++ ti,gain = <1>; ++ ti,datarate = <4>; ++ }; ++ ++ adc_ch5: channel@5 { ++ reg = <5>; ++ ti,gain = <1>; ++ ti,datarate = <4>; ++ }; ++ ++ adc_ch6: channel@6 { ++ reg = <6>; ++ ti,gain = <2>; ++ ti,datarate = <4>; ++ }; ++ ++ adc_ch7: channel@7 { ++ reg = <7>; ++ ti,gain = <2>; ++ ti,datarate = <4>; ++ }; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&sound>; ++ snd: __overlay__ { ++ compatible = "simple-audio-card"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ ++ simple-audio-card,name = "draws"; ++ simple-audio-card,format = "i2s"; ++ ++ simple-audio-card,bitclock-master = <&dailink0_master>; ++ simple-audio-card,frame-master = <&dailink0_master>; ++ ++ simple-audio-card,widgets = ++ "Line", "Line In", ++ "Line", "Line Out"; ++ ++ simple-audio-card,routing = ++ "IN1_R", "Line In", ++ "IN1_L", "Line In", ++ "CM_L", "Line In", ++ "CM_R", "Line In", ++ "Line Out", "LOR", ++ "Line Out", "LOL"; ++ ++ dailink0_master: simple-audio-card,cpu { ++ sound-dai = <&i2s>; ++ }; ++ ++ simple-audio-card,codec { ++ sound-dai = <&tlv320aic32x4>; ++ }; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&gpio>; ++ __overlay__ { ++ gpclk0_pin: gpclk0_pin { ++ brcm,pins = <4>; ++ brcm,function = <4>; ++ }; ++ ++ aic3204_reset: aic3204_reset { ++ brcm,pins = <13>; ++ brcm,function = <1>; ++ brcm,pull = <1>; ++ }; ++ ++ aic3204_gpio: aic3204_gpio { ++ brcm,pins = <26>; ++ }; ++ ++ sc16is752_irq: sc16is752_irq { ++ brcm,pins = <17>; ++ brcm,function = <0>; ++ brcm,pull = <2>; ++ }; ++ ++ pps_pins: pps_pins { ++ brcm,pins = <7>; ++ brcm,function = <0>; ++ brcm,pull = <0>; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ draws_adc_ch4_gain = <&adc_ch4>,"ti,gain:0"; ++ draws_adc_ch4_datarate = <&adc_ch4>,"ti,datarate:0"; ++ draws_adc_ch5_gain = <&adc_ch5>,"ti,gain:0"; ++ draws_adc_ch5_datarate = <&adc_ch5>,"ti,datarate:0"; ++ draws_adc_ch6_gain = <&adc_ch6>,"ti,gain:0"; ++ draws_adc_ch6_datarate = <&adc_ch6>,"ti,datarate:0"; ++ draws_adc_ch7_gain = <&adc_ch7>,"ti,gain:0"; ++ draws_adc_ch7_datarate = <&adc_ch7>,"ti,datarate:0"; ++ alsaname = <&snd>, "simple-audio-card,name"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/udrc-overlay.dts +@@ -0,0 +1,128 @@ ++#include ++/* ++ * Device tree overlay for the Universal Digital Radio Controller ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ fragment@0 { ++ target = <&i2s>; ++ __overlay__ { ++ clocks = <&clocks BCM2835_CLOCK_PCM>; ++ clock-names = "pcm"; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ regulators { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ udrc0_ldoin: udrc0_ldoin { ++ compatible = "regulator-fixed"; ++ regulator-name = "ldoin"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ }; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ clocks = <&clocks BCM2835_CLOCK_VPU>; ++ clock-frequency = <400000>; ++ ++ tlv320aic32x4: tlv320aic32x4@18 { ++ compatible = "ti,tlv320aic32x4"; ++ #sound-dai-cells = <0>; ++ reg = <0x18>; ++ status = "okay"; ++ ++ clocks = <&clocks BCM2835_CLOCK_GP0>; ++ clock-names = "mclk"; ++ assigned-clocks = <&clocks BCM2835_CLOCK_GP0>; ++ assigned-clock-rates = <25000000>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpclk0_pin &aic3204_reset>; ++ ++ reset-gpios = <&gpio 13 0>; ++ ++ iov-supply = <&udrc0_ldoin>; ++ ldoin-supply = <&udrc0_ldoin>; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&sound>; ++ snd: __overlay__ { ++ compatible = "simple-audio-card"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ ++ simple-audio-card,name = "udrc"; ++ simple-audio-card,format = "i2s"; ++ ++ simple-audio-card,bitclock-master = <&dailink0_master>; ++ simple-audio-card,frame-master = <&dailink0_master>; ++ ++ simple-audio-card,widgets = ++ "Line", "Line In", ++ "Line", "Line Out"; ++ ++ simple-audio-card,routing = ++ "IN1_R", "Line In", ++ "IN1_L", "Line In", ++ "CM_L", "Line In", ++ "CM_R", "Line In", ++ "Line Out", "LOR", ++ "Line Out", "LOL"; ++ ++ dailink0_master: simple-audio-card,cpu { ++ sound-dai = <&i2s>; ++ }; ++ ++ simple-audio-card,codec { ++ sound-dai = <&tlv320aic32x4>; ++ }; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&gpio>; ++ __overlay__ { ++ gpclk0_pin: gpclk0_pin { ++ brcm,pins = <4>; ++ brcm,function = <4>; ++ }; ++ ++ aic3204_reset: aic3204_reset { ++ brcm,pins = <13>; ++ brcm,function = <1>; ++ brcm,pull = <1>; ++ }; ++ ++ aic3204_gpio: aic3204_gpio { ++ brcm,pins = <26>; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ alsaname = <&snd>, "simple-audio-card,name"; ++ }; ++}; diff --git a/target/linux/brcm2708/patches-4.19/950-0419-ASoC-tlv320aic32x4-Add-Switch-for-Setting-Common-Mod.patch b/target/linux/brcm2708/patches-4.19/950-0419-ASoC-tlv320aic32x4-Add-Switch-for-Setting-Common-Mod.patch deleted file mode 100644 index 07b71d0233..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0419-ASoC-tlv320aic32x4-Add-Switch-for-Setting-Common-Mod.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 8821b9227b5e19f7a745c5836b6ef4b9a478904f Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Wed, 3 Apr 2019 21:01:54 -0700 -Subject: [PATCH 419/703] ASoC: tlv320aic32x4: Add Switch for Setting Common - Mode Voltage - -commit 44ceee847e27c828f2f1ef4e400e6bc0c8d04de3 upstream. - -Add a switch for setting common mode voltage. This can allow -for higher drive levels on the amplifier outputs. - -Signed-off-by: Annaliese McDermond -Signed-off-by: Mark Brown ---- - sound/soc/codecs/tlv320aic32x4.c | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/sound/soc/codecs/tlv320aic32x4.c -+++ b/sound/soc/codecs/tlv320aic32x4.c -@@ -242,6 +242,12 @@ static DECLARE_TLV_DB_SCALE(tlv_driver_g - /* -12dB min, 0.5dB steps */ - static DECLARE_TLV_DB_SCALE(tlv_adc_vol, -1200, 50, 0); - -+static const char * const lo_cm_text[] = { -+ "Full Chip", "1.65V", -+}; -+ -+static SOC_ENUM_SINGLE_DECL(lo_cm_enum, AIC32X4_CMMODE, 3, lo_cm_text); -+ - static const struct snd_kcontrol_new aic32x4_snd_controls[] = { - SOC_DOUBLE_R_S_TLV("PCM Playback Volume", AIC32X4_LDACVOL, - AIC32X4_RDACVOL, 0, -0x7f, 0x30, 7, 0, tlv_pcm), -@@ -255,6 +261,7 @@ static const struct snd_kcontrol_new aic - AIC32X4_HPRGAIN, 6, 0x01, 1), - SOC_DOUBLE_R("LO DAC Playback Switch", AIC32X4_LOLGAIN, - AIC32X4_LORGAIN, 6, 0x01, 1), -+ SOC_ENUM("LO Playback Common Mode Switch", lo_cm_enum), - SOC_DOUBLE_R("Mic PGA Switch", AIC32X4_LMICPGAVOL, - AIC32X4_RMICPGAVOL, 7, 0x01, 1), - diff --git a/target/linux/brcm2708/patches-4.19/950-0419-dwc_otg-only-do_split-when-we-actually-need-to-do-a-.patch b/target/linux/brcm2708/patches-4.19/950-0419-dwc_otg-only-do_split-when-we-actually-need-to-do-a-.patch new file mode 100644 index 0000000000..dc02972219 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0419-dwc_otg-only-do_split-when-we-actually-need-to-do-a-.patch @@ -0,0 +1,55 @@ +From d3245a8de2208d8147707fb35cd3a6da99107cc6 Mon Sep 17 00:00:00 2001 +From: P33M +Date: Mon, 8 Apr 2019 12:45:23 +0100 +Subject: [PATCH 419/725] dwc_otg: only do_split when we actually need to do a + split + +The previous test would fail if the root port was in fullspeed mode +and there was a hub between the FS device and the root port. While +the transfer worked, the schedule mangling performed for high-speed +split transfers would break leading to an 8ms polling interval. +--- + drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c +@@ -167,8 +167,10 @@ void qh_init(dwc_otg_hcd_t * hcd, dwc_ot + char *speed, *type; + int dev_speed; + uint32_t hub_addr, hub_port; ++ hprt0_data_t hprt; + + dwc_memset(qh, 0, sizeof(dwc_otg_qh_t)); ++ hprt.d32 = DWC_READ_REG32(hcd->core_if->host_if->hprt0); + + /* Initialize QH */ + qh->ep_type = dwc_otg_hcd_get_pipe_type(&urb->pipe_info); +@@ -191,9 +193,8 @@ void qh_init(dwc_otg_hcd_t * hcd, dwc_ot + + qh->nak_frame = 0xffff; + +- if (((dev_speed == USB_SPEED_LOW) || +- (dev_speed == USB_SPEED_FULL)) && +- (hub_addr != 0 && hub_addr != 1)) { ++ if (hprt.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED && ++ dev_speed != USB_SPEED_HIGH) { + DWC_DEBUGPL(DBG_HCD, + "QH init: EP %d: TT found at hub addr %d, for port %d\n", + dwc_otg_hcd_get_ep_num(&urb->pipe_info), hub_addr, +@@ -204,7 +205,6 @@ void qh_init(dwc_otg_hcd_t * hcd, dwc_ot + + if (qh->ep_type == UE_INTERRUPT || qh->ep_type == UE_ISOCHRONOUS) { + /* Compute scheduling parameters once and save them. */ +- hprt0_data_t hprt; + + /** @todo Account for split transfers in the bus time. */ + int bytecount = +@@ -219,7 +219,6 @@ void qh_init(dwc_otg_hcd_t * hcd, dwc_ot + SCHEDULE_SLOP); + qh->interval = urb->interval; + +- hprt.d32 = DWC_READ_REG32(hcd->core_if->host_if->hprt0); + if (hprt.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED) { + if (dev_speed == USB_SPEED_LOW || + dev_speed == USB_SPEED_FULL) { diff --git a/target/linux/brcm2708/patches-4.19/950-0420-ASoC-tlv320aic32x4-Add-Playback-PowerTune-Controls.patch b/target/linux/brcm2708/patches-4.19/950-0420-ASoC-tlv320aic32x4-Add-Playback-PowerTune-Controls.patch deleted file mode 100644 index b806e674c7..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0420-ASoC-tlv320aic32x4-Add-Playback-PowerTune-Controls.patch +++ /dev/null @@ -1,52 +0,0 @@ -From cbea77ecf69bf49def7f8222e38037a9349adbaa Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Wed, 3 Apr 2019 21:01:55 -0700 -Subject: [PATCH 420/703] ASoC: tlv320aic32x4: Add Playback PowerTune Controls - -commit d3e6e374566e1154820a9a3dc82f7eef646fcf95 upstream. - -PowerTune controls the power level of the chip. On playback this -indirectly controls things like the gain of the various output -amplifiers. This can allow for the decrease of output levels -from the codec. This adds controls for those power levels to -the driver. - -Signed-off-by: Annaliese McDermond -Signed-off-by: Mark Brown ---- - sound/soc/codecs/tlv320aic32x4.c | 9 +++++++++ - sound/soc/codecs/tlv320aic32x4.h | 2 ++ - 2 files changed, 11 insertions(+) - ---- a/sound/soc/codecs/tlv320aic32x4.c -+++ b/sound/soc/codecs/tlv320aic32x4.c -@@ -248,9 +248,18 @@ static const char * const lo_cm_text[] = - - static SOC_ENUM_SINGLE_DECL(lo_cm_enum, AIC32X4_CMMODE, 3, lo_cm_text); - -+static const char * const ptm_text[] = { -+ "P3", "P2", "P1", -+}; -+ -+static SOC_ENUM_SINGLE_DECL(l_ptm_enum, AIC32X4_LPLAYBACK, 2, ptm_text); -+static SOC_ENUM_SINGLE_DECL(r_ptm_enum, AIC32X4_RPLAYBACK, 2, ptm_text); -+ - static const struct snd_kcontrol_new aic32x4_snd_controls[] = { - SOC_DOUBLE_R_S_TLV("PCM Playback Volume", AIC32X4_LDACVOL, - AIC32X4_RDACVOL, 0, -0x7f, 0x30, 7, 0, tlv_pcm), -+ SOC_ENUM("DAC Left Playback PowerTune Switch", l_ptm_enum), -+ SOC_ENUM("DAC Right Playback PowerTune Switch", r_ptm_enum), - SOC_DOUBLE_R_S_TLV("HP Driver Gain Volume", AIC32X4_HPLGAIN, - AIC32X4_HPRGAIN, 0, -0x6, 0x1d, 5, 0, - tlv_driver_gain), ---- a/sound/soc/codecs/tlv320aic32x4.h -+++ b/sound/soc/codecs/tlv320aic32x4.h -@@ -78,6 +78,8 @@ int aic32x4_register_clocks(struct devic - - #define AIC32X4_PWRCFG AIC32X4_REG(1, 1) - #define AIC32X4_LDOCTL AIC32X4_REG(1, 2) -+#define AIC32X4_LPLAYBACK AIC32X4_REG(1, 3) -+#define AIC32X4_RPLAYBACK AIC32X4_REG(1, 4) - #define AIC32X4_OUTPWRCTL AIC32X4_REG(1, 9) - #define AIC32X4_CMMODE AIC32X4_REG(1, 10) - #define AIC32X4_HPLROUTE AIC32X4_REG(1, 12) diff --git a/target/linux/brcm2708/patches-4.19/950-0420-Input-ili210x-fetch-touchscreen-geometry-from-DT.patch b/target/linux/brcm2708/patches-4.19/950-0420-Input-ili210x-fetch-touchscreen-geometry-from-DT.patch new file mode 100644 index 0000000000..036a7ac8a3 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0420-Input-ili210x-fetch-touchscreen-geometry-from-DT.patch @@ -0,0 +1,490 @@ +From 15ad41e728284da6191d9bd6ac77f797660bb54f Mon Sep 17 00:00:00 2001 +From: Samuel Hsu +Date: Mon, 8 Apr 2019 16:42:17 +0200 +Subject: [PATCH 420/725] Input: ili210x - fetch touchscreen geometry from DT + +commit f67cc3e927d8414ad3872e046764534ea1f5db0d upstream + +Fetching the geometry from the ILI251x registers seems unreliable and +sometimes returns all zeroes. Add support for fetching the geometry and +axis inversion from DT instead. + +Signed-off-by: Marek Vasut +Signed-off-by: Dmitry Torokhov +--- + drivers/input/touchscreen/ili210x.c | 321 +++++++++++++++++----------- + 1 file changed, 194 insertions(+), 127 deletions(-) + +--- a/drivers/input/touchscreen/ili210x.c ++++ b/drivers/input/touchscreen/ili210x.c +@@ -4,11 +4,15 @@ + #include + #include + #include ++#include + #include + #include +-#include ++#include ++#include ++#include + +-#define MAX_TOUCHES 2 ++#define ILI210X_TOUCHES 2 ++#define ILI251X_TOUCHES 10 + #define DEFAULT_POLL_PERIOD 20 + + /* Touchscreen commands */ +@@ -17,41 +21,32 @@ + #define REG_FIRMWARE_VERSION 0x40 + #define REG_CALIBRATE 0xcc + +-struct finger { +- u8 x_low; +- u8 x_high; +- u8 y_low; +- u8 y_high; +-} __packed; +- +-struct touchdata { +- u8 status; +- struct finger finger[MAX_TOUCHES]; +-} __packed; +- +-struct panel_info { +- struct finger finger_max; +- u8 xchannel_num; +- u8 ychannel_num; +-} __packed; +- + struct firmware_version { + u8 id; + u8 major; + u8 minor; + } __packed; + ++enum ili2xxx_model { ++ MODEL_ILI210X, ++ MODEL_ILI251X, ++}; ++ + struct ili210x { + struct i2c_client *client; + struct input_dev *input; +- bool (*get_pendown_state)(void); + unsigned int poll_period; + struct delayed_work dwork; ++ struct gpio_desc *reset_gpio; ++ struct touchscreen_properties prop; ++ enum ili2xxx_model model; ++ unsigned int max_touches; + }; + + static int ili210x_read_reg(struct i2c_client *client, u8 reg, void *buf, + size_t len) + { ++ struct ili210x *priv = i2c_get_clientdata(client); + struct i2c_msg msg[2] = { + { + .addr = client->addr, +@@ -67,7 +62,38 @@ static int ili210x_read_reg(struct i2c_c + } + }; + +- if (i2c_transfer(client->adapter, msg, 2) != 2) { ++ if (priv->model == MODEL_ILI251X) { ++ if (i2c_transfer(client->adapter, msg, 1) != 1) { ++ dev_err(&client->dev, "i2c transfer failed\n"); ++ return -EIO; ++ } ++ ++ usleep_range(5000, 5500); ++ ++ if (i2c_transfer(client->adapter, msg + 1, 1) != 1) { ++ dev_err(&client->dev, "i2c transfer failed\n"); ++ return -EIO; ++ } ++ } else { ++ if (i2c_transfer(client->adapter, msg, 2) != 2) { ++ dev_err(&client->dev, "i2c transfer failed\n"); ++ return -EIO; ++ } ++ } ++ ++ return 0; ++} ++ ++static int ili210x_read(struct i2c_client *client, void *buf, size_t len) ++{ ++ struct i2c_msg msg = { ++ .addr = client->addr, ++ .flags = I2C_M_RD, ++ .len = len, ++ .buf = buf, ++ }; ++ ++ if (i2c_transfer(client->adapter, &msg, 1) != 1) { + dev_err(&client->dev, "i2c transfer failed\n"); + return -EIO; + } +@@ -75,42 +101,72 @@ static int ili210x_read_reg(struct i2c_c + return 0; + } + +-static void ili210x_report_events(struct input_dev *input, +- const struct touchdata *touchdata) ++static bool ili210x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata, ++ unsigned int finger, ++ unsigned int *x, unsigned int *y) + { +- int i; +- bool touch; +- unsigned int x, y; +- const struct finger *finger; ++ if (finger >= ILI210X_TOUCHES) ++ return false; + +- for (i = 0; i < MAX_TOUCHES; i++) { +- input_mt_slot(input, i); ++ if (touchdata[0] & BIT(finger)) ++ return false; + +- finger = &touchdata->finger[i]; ++ *x = get_unaligned_be16(touchdata + 1 + (finger * 4) + 0); ++ *y = get_unaligned_be16(touchdata + 1 + (finger * 4) + 2); + +- touch = touchdata->status & (1 << i); +- input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); +- if (touch) { +- x = finger->x_low | (finger->x_high << 8); +- y = finger->y_low | (finger->y_high << 8); ++ return true; ++} ++ ++static bool ili251x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata, ++ unsigned int finger, ++ unsigned int *x, unsigned int *y) ++{ ++ if (finger >= ILI251X_TOUCHES) ++ return false; ++ ++ *x = get_unaligned_be16(touchdata + 1 + (finger * 5) + 0); ++ if (!(*x & BIT(15))) /* Touch indication */ ++ return false; ++ ++ *x &= 0x3fff; ++ *y = get_unaligned_be16(touchdata + 1 + (finger * 5) + 2); ++ ++ return true; ++} ++ ++static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata) ++{ ++ struct input_dev *input = priv->input; ++ int i; ++ bool contact = false, touch = false; ++ unsigned int x = 0, y = 0; + +- input_report_abs(input, ABS_MT_POSITION_X, x); +- input_report_abs(input, ABS_MT_POSITION_Y, y); ++ for (i = 0; i < priv->max_touches; i++) { ++ if (priv->model == MODEL_ILI210X) { ++ touch = ili210x_touchdata_to_coords(priv, touchdata, ++ i, &x, &y); ++ } else if (priv->model == MODEL_ILI251X) { ++ touch = ili251x_touchdata_to_coords(priv, touchdata, ++ i, &x, &y); ++ if (touch) ++ contact = true; + } ++ ++ input_mt_slot(input, i); ++ input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); ++ if (!touch) ++ continue; ++ touchscreen_report_pos(input, &priv->prop, x, y, ++ true); + } + + input_mt_report_pointer_emulation(input, false); + input_sync(input); +-} + +-static bool get_pendown_state(const struct ili210x *priv) +-{ +- bool state = false; +- +- if (priv->get_pendown_state) +- state = priv->get_pendown_state(); ++ if (priv->model == MODEL_ILI210X) ++ contact = touchdata[0] & 0xf3; + +- return state; ++ return contact; + } + + static void ili210x_work(struct work_struct *work) +@@ -118,20 +174,29 @@ static void ili210x_work(struct work_str + struct ili210x *priv = container_of(work, struct ili210x, + dwork.work); + struct i2c_client *client = priv->client; +- struct touchdata touchdata; +- int error; ++ u8 touchdata[64] = { 0 }; ++ bool touch; ++ int error = -EINVAL; ++ ++ if (priv->model == MODEL_ILI210X) { ++ error = ili210x_read_reg(client, REG_TOUCHDATA, ++ touchdata, sizeof(touchdata)); ++ } else if (priv->model == MODEL_ILI251X) { ++ error = ili210x_read_reg(client, REG_TOUCHDATA, ++ touchdata, 31); ++ if (!error && touchdata[0] == 2) ++ error = ili210x_read(client, &touchdata[31], 20); ++ } + +- error = ili210x_read_reg(client, REG_TOUCHDATA, +- &touchdata, sizeof(touchdata)); + if (error) { + dev_err(&client->dev, + "Unable to get touchdata, err = %d\n", error); + return; + } + +- ili210x_report_events(priv->input, &touchdata); ++ touch = ili210x_report_events(priv, touchdata); + +- if ((touchdata.status & 0xf3) || get_pendown_state(priv)) ++ if (touch) + schedule_delayed_work(&priv->dwork, + msecs_to_jiffies(priv->poll_period)); + } +@@ -180,30 +245,76 @@ static const struct attribute_group ili2 + .attrs = ili210x_attributes, + }; + ++static void ili210x_power_down(void *data) ++{ ++ struct gpio_desc *reset_gpio = data; ++ ++ gpiod_set_value_cansleep(reset_gpio, 1); ++} ++ ++static void ili210x_cancel_work(void *data) ++{ ++ struct ili210x *priv = data; ++ ++ cancel_delayed_work_sync(&priv->dwork); ++} ++ + static int ili210x_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) + { + struct device *dev = &client->dev; +- const struct ili210x_platform_data *pdata = dev_get_platdata(dev); + struct ili210x *priv; ++ struct gpio_desc *reset_gpio; + struct input_dev *input; +- struct panel_info panel; + struct firmware_version firmware; +- int xmax, ymax; ++ enum ili2xxx_model model; + int error; + +- dev_dbg(dev, "Probing for ILI210X I2C Touschreen driver"); ++ model = (enum ili2xxx_model)id->driver_data; + +- if (!pdata) { +- dev_err(dev, "No platform data!\n"); +- return -EINVAL; +- } ++ dev_dbg(dev, "Probing for ILI210X I2C Touschreen driver"); + + if (client->irq <= 0) { + dev_err(dev, "No IRQ!\n"); + return -EINVAL; + } + ++ reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); ++ if (IS_ERR(reset_gpio)) ++ return PTR_ERR(reset_gpio); ++ ++ if (reset_gpio) { ++ error = devm_add_action_or_reset(dev, ili210x_power_down, ++ reset_gpio); ++ if (error) ++ return error; ++ ++ usleep_range(50, 100); ++ gpiod_set_value_cansleep(reset_gpio, 0); ++ msleep(100); ++ } ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ input = devm_input_allocate_device(dev); ++ if (!input) ++ return -ENOMEM; ++ ++ priv->client = client; ++ priv->input = input; ++ priv->poll_period = DEFAULT_POLL_PERIOD; ++ INIT_DELAYED_WORK(&priv->dwork, ili210x_work); ++ priv->reset_gpio = reset_gpio; ++ priv->model = model; ++ if (model == MODEL_ILI210X) ++ priv->max_touches = ILI210X_TOUCHES; ++ if (model == MODEL_ILI251X) ++ priv->max_touches = ILI251X_TOUCHES; ++ ++ i2c_set_clientdata(client, priv); ++ + /* Get firmware version */ + error = ili210x_read_reg(client, REG_FIRMWARE_VERSION, + &firmware, sizeof(firmware)); +@@ -213,70 +324,40 @@ static int ili210x_i2c_probe(struct i2c_ + return error; + } + +- /* get panel info */ +- error = ili210x_read_reg(client, REG_PANEL_INFO, &panel, sizeof(panel)); +- if (error) { +- dev_err(dev, "Failed to get panel information, err: %d\n", +- error); +- return error; +- } +- +- xmax = panel.finger_max.x_low | (panel.finger_max.x_high << 8); +- ymax = panel.finger_max.y_low | (panel.finger_max.y_high << 8); +- +- priv = kzalloc(sizeof(*priv), GFP_KERNEL); +- input = input_allocate_device(); +- if (!priv || !input) { +- error = -ENOMEM; +- goto err_free_mem; +- } +- +- priv->client = client; +- priv->input = input; +- priv->get_pendown_state = pdata->get_pendown_state; +- priv->poll_period = pdata->poll_period ? : DEFAULT_POLL_PERIOD; +- INIT_DELAYED_WORK(&priv->dwork, ili210x_work); +- + /* Setup input device */ + input->name = "ILI210x Touchscreen"; + input->id.bustype = BUS_I2C; + input->dev.parent = dev; + +- __set_bit(EV_SYN, input->evbit); +- __set_bit(EV_KEY, input->evbit); +- __set_bit(EV_ABS, input->evbit); +- __set_bit(BTN_TOUCH, input->keybit); +- +- /* Single touch */ +- input_set_abs_params(input, ABS_X, 0, xmax, 0, 0); +- input_set_abs_params(input, ABS_Y, 0, ymax, 0, 0); +- + /* Multi touch */ +- input_mt_init_slots(input, MAX_TOUCHES, 0); +- input_set_abs_params(input, ABS_MT_POSITION_X, 0, xmax, 0, 0); +- input_set_abs_params(input, ABS_MT_POSITION_Y, 0, ymax, 0, 0); ++ input_set_abs_params(input, ABS_MT_POSITION_X, 0, 0xffff, 0, 0); ++ input_set_abs_params(input, ABS_MT_POSITION_Y, 0, 0xffff, 0, 0); ++ touchscreen_parse_properties(input, true, &priv->prop); ++ input_mt_init_slots(input, priv->max_touches, INPUT_MT_DIRECT); + +- i2c_set_clientdata(client, priv); ++ error = devm_add_action(dev, ili210x_cancel_work, priv); ++ if (error) ++ return error; + +- error = request_irq(client->irq, ili210x_irq, pdata->irq_flags, +- client->name, priv); ++ error = devm_request_irq(dev, client->irq, ili210x_irq, 0, ++ client->name, priv); + if (error) { + dev_err(dev, "Unable to request touchscreen IRQ, err: %d\n", + error); +- goto err_free_mem; ++ return error; + } + +- error = sysfs_create_group(&dev->kobj, &ili210x_attr_group); ++ error = devm_device_add_group(dev, &ili210x_attr_group); + if (error) { + dev_err(dev, "Unable to create sysfs attributes, err: %d\n", + error); +- goto err_free_irq; ++ return error; + } + + error = input_register_device(priv->input); + if (error) { + dev_err(dev, "Cannot register input device, err: %d\n", error); +- goto err_remove_sysfs; ++ return error; + } + + device_init_wakeup(dev, 1); +@@ -286,28 +367,6 @@ static int ili210x_i2c_probe(struct i2c_ + client->irq, firmware.id, firmware.major, firmware.minor); + + return 0; +- +-err_remove_sysfs: +- sysfs_remove_group(&dev->kobj, &ili210x_attr_group); +-err_free_irq: +- free_irq(client->irq, priv); +-err_free_mem: +- input_free_device(input); +- kfree(priv); +- return error; +-} +- +-static int ili210x_i2c_remove(struct i2c_client *client) +-{ +- struct ili210x *priv = i2c_get_clientdata(client); +- +- sysfs_remove_group(&client->dev.kobj, &ili210x_attr_group); +- free_irq(priv->client->irq, priv); +- cancel_delayed_work_sync(&priv->dwork); +- input_unregister_device(priv->input); +- kfree(priv); +- +- return 0; + } + + static int __maybe_unused ili210x_i2c_suspend(struct device *dev) +@@ -334,19 +393,27 @@ static SIMPLE_DEV_PM_OPS(ili210x_i2c_pm, + ili210x_i2c_suspend, ili210x_i2c_resume); + + static const struct i2c_device_id ili210x_i2c_id[] = { +- { "ili210x", 0 }, ++ { "ili210x", MODEL_ILI210X }, ++ { "ili251x", MODEL_ILI251X }, + { } + }; + MODULE_DEVICE_TABLE(i2c, ili210x_i2c_id); + ++static const struct of_device_id ili210x_dt_ids[] = { ++ { .compatible = "ilitek,ili210x", .data = (void *)MODEL_ILI210X }, ++ { .compatible = "ilitek,ili251x", .data = (void *)MODEL_ILI251X }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, ili210x_dt_ids); ++ + static struct i2c_driver ili210x_ts_driver = { + .driver = { + .name = "ili210x_i2c", + .pm = &ili210x_i2c_pm, ++ .of_match_table = ili210x_dt_ids, + }, + .id_table = ili210x_i2c_id, + .probe = ili210x_i2c_probe, +- .remove = ili210x_i2c_remove, + }; + + module_i2c_driver(ili210x_ts_driver); diff --git a/target/linux/brcm2708/patches-4.19/950-0421-Input-ili210x-add-DT-binding-document.patch b/target/linux/brcm2708/patches-4.19/950-0421-Input-ili210x-add-DT-binding-document.patch new file mode 100644 index 0000000000..3f768e22ad --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0421-Input-ili210x-add-DT-binding-document.patch @@ -0,0 +1,47 @@ +From 5157a5c0fa2f7489e3ebf20dcbd9a7078ced6afd Mon Sep 17 00:00:00 2001 +From: Samuel Hsu +Date: Mon, 8 Apr 2019 16:49:51 +0200 +Subject: [PATCH 421/725] Input: ili210x - add DT binding document + +commit 41a852e002e65ab7a1e6841b485d72d022e95df2 upstream + +Add DT binding document for the Ilitek ILI210x and ILI251x +touchscreen controllers. + +Signed-off-by: Marek Vasut +Reviewed-by: Rob Herring +Signed-off-by: Dmitry Torokhov +--- + .../bindings/input/ilitek,ili2xxx.txt | 26 +++++++++++++++++++ + 1 file changed, 26 insertions(+) + create mode 100644 Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt + +--- /dev/null ++++ b/Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt +@@ -0,0 +1,26 @@ ++Ilitek ILI210x/ILI251x touchscreen controller ++ ++Required properties: ++- compatible: ++ ilitek,ili210x for ILI210x ++ ilitek,ili251x for ILI251x ++ ++- reg: The I2C address of the device ++ ++- interrupts: The sink for the touchscreen's IRQ output ++ See ../interrupt-controller/interrupts.txt ++ ++Optional properties for main touchpad device: ++ ++- reset-gpios: GPIO specifier for the touchscreen's reset pin (active low) ++ ++Example: ++ ++ touchscreen@41 { ++ compatible = "ilitek,ili251x"; ++ reg = <0x41>; ++ interrupt-parent = <&gpio4>; ++ interrupts = <7 IRQ_TYPE_EDGE_FALLING>; ++ reset-gpios = <&gpio5 21 GPIO_ACTIVE_LOW>; ++ }; ++ diff --git a/target/linux/brcm2708/patches-4.19/950-0421-dtoverlays-Add-Support-for-the-UDRC-DRAWS.patch b/target/linux/brcm2708/patches-4.19/950-0421-dtoverlays-Add-Support-for-the-UDRC-DRAWS.patch deleted file mode 100644 index 8da46da0e2..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0421-dtoverlays-Add-Support-for-the-UDRC-DRAWS.patch +++ /dev/null @@ -1,445 +0,0 @@ -From f1e74b2152a21e848075ea40ba8e8665f8313739 Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Sun, 17 Mar 2019 16:48:36 -0700 -Subject: [PATCH 421/703] dtoverlays: Add Support for the UDRC/DRAWS - -Adds a new overlay to support the Northwest Digital Radio -DRAWS and UDRC HATs. See http://nwdigitalradio.com. - -Signed-off-by: Annaliese McDermond ---- - arch/arm/boot/dts/overlays/Makefile | 2 + - arch/arm/boot/dts/overlays/README | 59 ++++++ - arch/arm/boot/dts/overlays/draws-overlay.dts | 200 +++++++++++++++++++ - arch/arm/boot/dts/overlays/udrc-overlay.dts | 128 ++++++++++++ - 4 files changed, 389 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/draws-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/udrc-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -29,6 +29,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - dionaudio-loco-v2.dtbo \ - dpi18.dtbo \ - dpi24.dtbo \ -+ draws.dtbo \ - dwc-otg.dtbo \ - dwc2.dtbo \ - enc28j60.dtbo \ -@@ -146,6 +147,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - tpm-slb9670.dtbo \ - uart0.dtbo \ - uart1.dtbo \ -+ udrc.dtbo \ - upstream.dtbo \ - upstream-aux-interrupt.dtbo \ - vc4-fkms-v3d.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -531,6 +531,59 @@ Load: dtoverlay=dpi24 - Params: - - -+Name: draws -+Info: Configures the NW Digital Radio DRAWS Hat -+ -+ The board includes an ADC to measure various board values and also -+ provides two analog user inputs on the expansion header. The ADC -+ can be configured for various sample rates and gain values to adjust -+ the input range. Tables describing the two parameters follow. -+ -+ ADC Gain Values: -+ 0 = +/- 6.144V -+ 1 = +/- 4.096V -+ 2 = +/- 2.048V -+ 3 = +/- 1.024V -+ 4 = +/- 0.512V -+ 5 = +/- 0.256V -+ 6 = +/- 0.256V -+ 7 = +/- 0.256V -+ -+ ADC Datarate Values: -+ 0 = 128sps -+ 1 = 250sps -+ 2 = 490sps -+ 3 = 920sps -+ 4 = 1600sps (default) -+ 5 = 2400sps -+ 6 = 3300sps -+ 7 = 3300sps -+Load: dtoverlay=draws,= -+Params: draws_adc_ch4_gain Sets the full scale resolution of the ADCs -+ input voltage sensor (default 1) -+ -+ draws_adc_ch4_datarate Sets the datarate of the ADCs input voltage -+ sensor -+ -+ draws_adc_ch5_gain Sets the full scale resolution of the ADCs -+ 5V rail voltage sensor (default 1) -+ -+ draws_adc_ch5_datarate Sets the datarate of the ADCs 4V rail voltage -+ sensor -+ -+ draws_adc_ch6_gain Sets the full scale resolution of the ADCs -+ AIN2 input (default 2) -+ -+ draws_adc_ch6_datarate Sets the datarate of the ADCs AIN2 input -+ -+ draws_adc_ch7_gain Sets the full scale resolution of the ADCs -+ AIN3 input (default 2) -+ -+ draws_adc_ch7_datarate Sets the datarate of the ADCs AIN3 input -+ -+ alsaname Name of the ALSA audio device (default "draws") -+ -+ - Name: dwc-otg - Info: Selects the dwc_otg USB controller driver which has fiq support. This - is the default on all except the Pi Zero which defaults to dwc2. -@@ -2117,6 +2170,12 @@ Params: txd1_pin GPIO pin - rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) - - -+Name: udrc -+Info: Configures the NW Digital Radio UDRC Hat -+Load: dtoverlay=udrc,= -+Params: alsaname Name of the ALSA audio device (default "udrc") -+ -+ - Name: upstream - Info: Allow usage of downstream .dtb with upstream kernel. Comprises - vc4-kms-v3d, dwc2 and upstream-aux-interrupt overlays. ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/draws-overlay.dts -@@ -0,0 +1,200 @@ -+#include -+/* -+ * Device tree overlay for the DRAWS Hardware -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ fragment@0 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target-path = "/"; -+ __overlay__ { -+ regulators { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ udrc0_ldoin: udrc0_ldoin { -+ compatible = "regulator-fixed"; -+ regulator-name = "ldoin"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ }; -+ }; -+ -+ pps: pps { -+ compatible = "pps-gpio"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pps_pins>; -+ gpios = <&gpio 7 0>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c_arm>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ tlv320aic32x4: tlv320aic32x4@18 { -+ compatible = "ti,tlv320aic32x4"; -+ reg = <0x18>; -+ #sound-dai-cells = <0>; -+ status = "okay"; -+ -+ clocks = <&clocks BCM2835_CLOCK_GP0>; -+ clock-names = "mclk"; -+ assigned-clocks = <&clocks BCM2835_CLOCK_GP0>; -+ assigned-clock-rates = <25000000>; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gpclk0_pin &aic3204_reset>; -+ -+ reset-gpios = <&gpio 13 0>; -+ -+ iov-supply = <&udrc0_ldoin>; -+ ldoin-supply = <&udrc0_ldoin>; -+ }; -+ -+ sc16is752: sc16is752@50 { -+ compatible = "nxp,sc16is752"; -+ reg = <0x50>; -+ clocks = <&sc16is752_clk>; -+ interrupt-parent = <&gpio>; -+ interrupts = <17 2>; /* IRQ_TYPE_EDGE_FALLING */ -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sc16is752_irq>; -+ -+ sc16is752_clk: sc16is752_clk { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <1843200>; -+ }; -+ }; -+ -+ tla2024: tla2024@48 { -+ compatible = "ti,ads1015"; -+ reg = <0x48>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ adc_ch4: channel@4 { -+ reg = <4>; -+ ti,gain = <1>; -+ ti,datarate = <4>; -+ }; -+ -+ adc_ch5: channel@5 { -+ reg = <5>; -+ ti,gain = <1>; -+ ti,datarate = <4>; -+ }; -+ -+ adc_ch6: channel@6 { -+ reg = <6>; -+ ti,gain = <2>; -+ ti,datarate = <4>; -+ }; -+ -+ adc_ch7: channel@7 { -+ reg = <7>; -+ ti,gain = <2>; -+ ti,datarate = <4>; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target = <&sound>; -+ snd: __overlay__ { -+ compatible = "simple-audio-card"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ -+ simple-audio-card,name = "draws"; -+ simple-audio-card,format = "i2s"; -+ -+ simple-audio-card,bitclock-master = <&dailink0_master>; -+ simple-audio-card,frame-master = <&dailink0_master>; -+ -+ simple-audio-card,widgets = -+ "Line", "Line In", -+ "Line", "Line Out"; -+ -+ simple-audio-card,routing = -+ "IN1_R", "Line In", -+ "IN1_L", "Line In", -+ "CM_L", "Line In", -+ "CM_R", "Line In", -+ "Line Out", "LOR", -+ "Line Out", "LOL"; -+ -+ dailink0_master: simple-audio-card,cpu { -+ sound-dai = <&i2s>; -+ }; -+ -+ simple-audio-card,codec { -+ sound-dai = <&tlv320aic32x4>; -+ }; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&gpio>; -+ __overlay__ { -+ gpclk0_pin: gpclk0_pin { -+ brcm,pins = <4>; -+ brcm,function = <4>; -+ }; -+ -+ aic3204_reset: aic3204_reset { -+ brcm,pins = <13>; -+ brcm,function = <1>; -+ brcm,pull = <1>; -+ }; -+ -+ aic3204_gpio: aic3204_gpio { -+ brcm,pins = <26>; -+ }; -+ -+ sc16is752_irq: sc16is752_irq { -+ brcm,pins = <17>; -+ brcm,function = <0>; -+ brcm,pull = <2>; -+ }; -+ -+ pps_pins: pps_pins { -+ brcm,pins = <7>; -+ brcm,function = <0>; -+ brcm,pull = <0>; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ draws_adc_ch4_gain = <&adc_ch4>,"ti,gain:0"; -+ draws_adc_ch4_datarate = <&adc_ch4>,"ti,datarate:0"; -+ draws_adc_ch5_gain = <&adc_ch5>,"ti,gain:0"; -+ draws_adc_ch5_datarate = <&adc_ch5>,"ti,datarate:0"; -+ draws_adc_ch6_gain = <&adc_ch6>,"ti,gain:0"; -+ draws_adc_ch6_datarate = <&adc_ch6>,"ti,datarate:0"; -+ draws_adc_ch7_gain = <&adc_ch7>,"ti,gain:0"; -+ draws_adc_ch7_datarate = <&adc_ch7>,"ti,datarate:0"; -+ alsaname = <&snd>, "simple-audio-card,name"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/udrc-overlay.dts -@@ -0,0 +1,128 @@ -+#include -+/* -+ * Device tree overlay for the Universal Digital Radio Controller -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ fragment@0 { -+ target = <&i2s>; -+ __overlay__ { -+ clocks = <&clocks BCM2835_CLOCK_PCM>; -+ clock-names = "pcm"; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target-path = "/"; -+ __overlay__ { -+ regulators { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ udrc0_ldoin: udrc0_ldoin { -+ compatible = "regulator-fixed"; -+ regulator-name = "ldoin"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ clocks = <&clocks BCM2835_CLOCK_VPU>; -+ clock-frequency = <400000>; -+ -+ tlv320aic32x4: tlv320aic32x4@18 { -+ compatible = "ti,tlv320aic32x4"; -+ #sound-dai-cells = <0>; -+ reg = <0x18>; -+ status = "okay"; -+ -+ clocks = <&clocks BCM2835_CLOCK_GP0>; -+ clock-names = "mclk"; -+ assigned-clocks = <&clocks BCM2835_CLOCK_GP0>; -+ assigned-clock-rates = <25000000>; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gpclk0_pin &aic3204_reset>; -+ -+ reset-gpios = <&gpio 13 0>; -+ -+ iov-supply = <&udrc0_ldoin>; -+ ldoin-supply = <&udrc0_ldoin>; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target = <&sound>; -+ snd: __overlay__ { -+ compatible = "simple-audio-card"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ -+ simple-audio-card,name = "udrc"; -+ simple-audio-card,format = "i2s"; -+ -+ simple-audio-card,bitclock-master = <&dailink0_master>; -+ simple-audio-card,frame-master = <&dailink0_master>; -+ -+ simple-audio-card,widgets = -+ "Line", "Line In", -+ "Line", "Line Out"; -+ -+ simple-audio-card,routing = -+ "IN1_R", "Line In", -+ "IN1_L", "Line In", -+ "CM_L", "Line In", -+ "CM_R", "Line In", -+ "Line Out", "LOR", -+ "Line Out", "LOL"; -+ -+ dailink0_master: simple-audio-card,cpu { -+ sound-dai = <&i2s>; -+ }; -+ -+ simple-audio-card,codec { -+ sound-dai = <&tlv320aic32x4>; -+ }; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&gpio>; -+ __overlay__ { -+ gpclk0_pin: gpclk0_pin { -+ brcm,pins = <4>; -+ brcm,function = <4>; -+ }; -+ -+ aic3204_reset: aic3204_reset { -+ brcm,pins = <13>; -+ brcm,function = <1>; -+ brcm,pull = <1>; -+ }; -+ -+ aic3204_gpio: aic3204_gpio { -+ brcm,pins = <26>; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ alsaname = <&snd>, "simple-audio-card,name"; -+ }; -+}; diff --git a/target/linux/brcm2708/patches-4.19/950-0422-configs-Add-TOUCHSCREEN_ILI210X-m.patch b/target/linux/brcm2708/patches-4.19/950-0422-configs-Add-TOUCHSCREEN_ILI210X-m.patch new file mode 100644 index 0000000000..9b25e59e2b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0422-configs-Add-TOUCHSCREEN_ILI210X-m.patch @@ -0,0 +1,42 @@ +From f3d6c9f20cf6c0f0f970b4ded850b23c0554e779 Mon Sep 17 00:00:00 2001 +From: Samuel Hsu +Date: Mon, 8 Apr 2019 16:54:34 +0200 +Subject: [PATCH 422/725] configs: Add TOUCHSCREEN_ILI210X=m + +Signed-off-by: Samuel Hsu +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + arch/arm64/configs/bcmrpi3_defconfig | 1 + + 3 files changed, 3 insertions(+) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -565,6 +565,7 @@ CONFIG_TOUCHSCREEN_ADS7846=m + CONFIG_TOUCHSCREEN_EGALAX=m + CONFIG_TOUCHSCREEN_EXC3000=m + CONFIG_TOUCHSCREEN_GOODIX=m ++CONFIG_TOUCHSCREEN_ILI210X=m + CONFIG_TOUCHSCREEN_EDT_FT5X06=m + CONFIG_TOUCHSCREEN_RPI_FT5406=m + CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -559,6 +559,7 @@ CONFIG_TOUCHSCREEN_ADS7846=m + CONFIG_TOUCHSCREEN_EGALAX=m + CONFIG_TOUCHSCREEN_EXC3000=m + CONFIG_TOUCHSCREEN_GOODIX=m ++CONFIG_TOUCHSCREEN_ILI210X=m + CONFIG_TOUCHSCREEN_EDT_FT5X06=m + CONFIG_TOUCHSCREEN_RPI_FT5406=m + CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -547,6 +547,7 @@ CONFIG_INPUT_TOUCHSCREEN=y + CONFIG_TOUCHSCREEN_ADS7846=m + CONFIG_TOUCHSCREEN_EGALAX=m + CONFIG_TOUCHSCREEN_EKTF2127=m ++CONFIG_TOUCHSCREEN_ILI210X=m + CONFIG_TOUCHSCREEN_RPI_FT5406=m + CONFIG_TOUCHSCREEN_USB_COMPOSITE=m + CONFIG_TOUCHSCREEN_STMPE=m diff --git a/target/linux/brcm2708/patches-4.19/950-0422-dwc_otg-only-do_split-when-we-actually-need-to-do-a-.patch b/target/linux/brcm2708/patches-4.19/950-0422-dwc_otg-only-do_split-when-we-actually-need-to-do-a-.patch deleted file mode 100644 index 443b6408d4..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0422-dwc_otg-only-do_split-when-we-actually-need-to-do-a-.patch +++ /dev/null @@ -1,55 +0,0 @@ -From e30b8c6f64fe1cd5ea4e522186847be170efe88b Mon Sep 17 00:00:00 2001 -From: P33M -Date: Mon, 8 Apr 2019 12:45:23 +0100 -Subject: [PATCH 422/703] dwc_otg: only do_split when we actually need to do a - split - -The previous test would fail if the root port was in fullspeed mode -and there was a hub between the FS device and the root port. While -the transfer worked, the schedule mangling performed for high-speed -split transfers would break leading to an 8ms polling interval. ---- - drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 9 ++++----- - 1 file changed, 4 insertions(+), 5 deletions(-) - ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -@@ -167,8 +167,10 @@ void qh_init(dwc_otg_hcd_t * hcd, dwc_ot - char *speed, *type; - int dev_speed; - uint32_t hub_addr, hub_port; -+ hprt0_data_t hprt; - - dwc_memset(qh, 0, sizeof(dwc_otg_qh_t)); -+ hprt.d32 = DWC_READ_REG32(hcd->core_if->host_if->hprt0); - - /* Initialize QH */ - qh->ep_type = dwc_otg_hcd_get_pipe_type(&urb->pipe_info); -@@ -191,9 +193,8 @@ void qh_init(dwc_otg_hcd_t * hcd, dwc_ot - - qh->nak_frame = 0xffff; - -- if (((dev_speed == USB_SPEED_LOW) || -- (dev_speed == USB_SPEED_FULL)) && -- (hub_addr != 0 && hub_addr != 1)) { -+ if (hprt.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED && -+ dev_speed != USB_SPEED_HIGH) { - DWC_DEBUGPL(DBG_HCD, - "QH init: EP %d: TT found at hub addr %d, for port %d\n", - dwc_otg_hcd_get_ep_num(&urb->pipe_info), hub_addr, -@@ -204,7 +205,6 @@ void qh_init(dwc_otg_hcd_t * hcd, dwc_ot - - if (qh->ep_type == UE_INTERRUPT || qh->ep_type == UE_ISOCHRONOUS) { - /* Compute scheduling parameters once and save them. */ -- hprt0_data_t hprt; - - /** @todo Account for split transfers in the bus time. */ - int bytecount = -@@ -219,7 +219,6 @@ void qh_init(dwc_otg_hcd_t * hcd, dwc_ot - SCHEDULE_SLOP); - qh->interval = urb->interval; - -- hprt.d32 = DWC_READ_REG32(hcd->core_if->host_if->hprt0); - if (hprt.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED) { - if (dev_speed == USB_SPEED_LOW || - dev_speed == USB_SPEED_FULL) { diff --git a/target/linux/brcm2708/patches-4.19/950-0423-BCM2708-Add-core-Device-Tree-support-ilitek251x.patch b/target/linux/brcm2708/patches-4.19/950-0423-BCM2708-Add-core-Device-Tree-support-ilitek251x.patch new file mode 100644 index 0000000000..f4560fec78 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0423-BCM2708-Add-core-Device-Tree-support-ilitek251x.patch @@ -0,0 +1,91 @@ +From 3c0bead8692a211c548d046790dc4129128fbff1 Mon Sep 17 00:00:00 2001 +From: Samuel Hsu +Date: Mon, 8 Apr 2019 17:06:44 +0200 +Subject: [PATCH 423/725] BCM2708: Add core Device Tree support, ilitek251x + +Signed-off-by: Samuel Hsu +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 11 +++++ + .../boot/dts/overlays/ilitek251x-overlay.dts | 45 +++++++++++++++++++ + 3 files changed, 57 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/ilitek251x-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -67,6 +67,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + i2c0-bcm2708.dtbo \ + i2c1-bcm2708.dtbo \ + i2s-gpio28-31.dtbo \ ++ ilitek251x.dtbo \ + iqaudio-dac.dtbo \ + iqaudio-dacplus.dtbo \ + iqaudio-digi-wm8804-audio.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1146,6 +1146,17 @@ Load: dtoverlay=i2s-gpio28-31 + Params: + + ++Name: ilitek251x ++Info: Enables I2C connected Ilitek 251x multiple touch controller using ++ GPIO 4 (pin 7 on GPIO header) for interrupt. ++Load: dtoverlay=ilitek251x,= ++Params: interrupt GPIO used for interrupt (default 4) ++ sizex Touchscreen size x, horizontal resolution of ++ touchscreen (in pixels) ++ sizey Touchscreen size y, vertical resolution of ++ touchscreen (in pixels) ++ ++ + Name: iqaudio-dac + Info: Configures the IQaudio DAC audio card + Load: dtoverlay=iqaudio-dac, +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/ilitek251x-overlay.dts +@@ -0,0 +1,45 @@ ++// Device tree overlay for I2C connected Ilitek multiple touch controller ++/dts-v1/; ++/plugin/; ++ ++ / { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ ili251x_pins: ili251x_pins { ++ brcm,pins = <4>; // interrupt ++ brcm,function = <0>; // in ++ brcm,pull = <2>; // pull-up // ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ ili251x: ili251x@41 { ++ compatible = "ilitek,ili251x"; ++ reg = <0x41>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ili251x_pins>; ++ interrupt-parent = <&gpio>; ++ interrupts = <4 8>; // high-to-low edge triggered ++ touchscreen-size-x = <16384>; ++ touchscreen-size-y = <9600>; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ interrupt = <&ili251x_pins>,"brcm,pins:0", ++ <&ili251x>,"interrupts:0"; ++ sizex = <&ili251x>,"touchscreen-size-x:0"; ++ sizey = <&ili251x>,"touchscreen-size-y:0"; ++ }; ++}; diff --git a/target/linux/brcm2708/patches-4.19/950-0423-Input-ili210x-fetch-touchscreen-geometry-from-DT.patch b/target/linux/brcm2708/patches-4.19/950-0423-Input-ili210x-fetch-touchscreen-geometry-from-DT.patch deleted file mode 100644 index 763bcbbf5f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0423-Input-ili210x-fetch-touchscreen-geometry-from-DT.patch +++ /dev/null @@ -1,490 +0,0 @@ -From 7424847b3053bb995d52b13b6b7a387d682cde31 Mon Sep 17 00:00:00 2001 -From: Samuel Hsu -Date: Mon, 8 Apr 2019 16:42:17 +0200 -Subject: [PATCH 423/703] Input: ili210x - fetch touchscreen geometry from DT - -commit f67cc3e927d8414ad3872e046764534ea1f5db0d upstream - -Fetching the geometry from the ILI251x registers seems unreliable and -sometimes returns all zeroes. Add support for fetching the geometry and -axis inversion from DT instead. - -Signed-off-by: Marek Vasut -Signed-off-by: Dmitry Torokhov ---- - drivers/input/touchscreen/ili210x.c | 321 +++++++++++++++++----------- - 1 file changed, 194 insertions(+), 127 deletions(-) - ---- a/drivers/input/touchscreen/ili210x.c -+++ b/drivers/input/touchscreen/ili210x.c -@@ -4,11 +4,15 @@ - #include - #include - #include -+#include - #include - #include --#include -+#include -+#include -+#include - --#define MAX_TOUCHES 2 -+#define ILI210X_TOUCHES 2 -+#define ILI251X_TOUCHES 10 - #define DEFAULT_POLL_PERIOD 20 - - /* Touchscreen commands */ -@@ -17,41 +21,32 @@ - #define REG_FIRMWARE_VERSION 0x40 - #define REG_CALIBRATE 0xcc - --struct finger { -- u8 x_low; -- u8 x_high; -- u8 y_low; -- u8 y_high; --} __packed; -- --struct touchdata { -- u8 status; -- struct finger finger[MAX_TOUCHES]; --} __packed; -- --struct panel_info { -- struct finger finger_max; -- u8 xchannel_num; -- u8 ychannel_num; --} __packed; -- - struct firmware_version { - u8 id; - u8 major; - u8 minor; - } __packed; - -+enum ili2xxx_model { -+ MODEL_ILI210X, -+ MODEL_ILI251X, -+}; -+ - struct ili210x { - struct i2c_client *client; - struct input_dev *input; -- bool (*get_pendown_state)(void); - unsigned int poll_period; - struct delayed_work dwork; -+ struct gpio_desc *reset_gpio; -+ struct touchscreen_properties prop; -+ enum ili2xxx_model model; -+ unsigned int max_touches; - }; - - static int ili210x_read_reg(struct i2c_client *client, u8 reg, void *buf, - size_t len) - { -+ struct ili210x *priv = i2c_get_clientdata(client); - struct i2c_msg msg[2] = { - { - .addr = client->addr, -@@ -67,7 +62,38 @@ static int ili210x_read_reg(struct i2c_c - } - }; - -- if (i2c_transfer(client->adapter, msg, 2) != 2) { -+ if (priv->model == MODEL_ILI251X) { -+ if (i2c_transfer(client->adapter, msg, 1) != 1) { -+ dev_err(&client->dev, "i2c transfer failed\n"); -+ return -EIO; -+ } -+ -+ usleep_range(5000, 5500); -+ -+ if (i2c_transfer(client->adapter, msg + 1, 1) != 1) { -+ dev_err(&client->dev, "i2c transfer failed\n"); -+ return -EIO; -+ } -+ } else { -+ if (i2c_transfer(client->adapter, msg, 2) != 2) { -+ dev_err(&client->dev, "i2c transfer failed\n"); -+ return -EIO; -+ } -+ } -+ -+ return 0; -+} -+ -+static int ili210x_read(struct i2c_client *client, void *buf, size_t len) -+{ -+ struct i2c_msg msg = { -+ .addr = client->addr, -+ .flags = I2C_M_RD, -+ .len = len, -+ .buf = buf, -+ }; -+ -+ if (i2c_transfer(client->adapter, &msg, 1) != 1) { - dev_err(&client->dev, "i2c transfer failed\n"); - return -EIO; - } -@@ -75,42 +101,72 @@ static int ili210x_read_reg(struct i2c_c - return 0; - } - --static void ili210x_report_events(struct input_dev *input, -- const struct touchdata *touchdata) -+static bool ili210x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata, -+ unsigned int finger, -+ unsigned int *x, unsigned int *y) - { -- int i; -- bool touch; -- unsigned int x, y; -- const struct finger *finger; -+ if (finger >= ILI210X_TOUCHES) -+ return false; - -- for (i = 0; i < MAX_TOUCHES; i++) { -- input_mt_slot(input, i); -+ if (touchdata[0] & BIT(finger)) -+ return false; - -- finger = &touchdata->finger[i]; -+ *x = get_unaligned_be16(touchdata + 1 + (finger * 4) + 0); -+ *y = get_unaligned_be16(touchdata + 1 + (finger * 4) + 2); - -- touch = touchdata->status & (1 << i); -- input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); -- if (touch) { -- x = finger->x_low | (finger->x_high << 8); -- y = finger->y_low | (finger->y_high << 8); -+ return true; -+} -+ -+static bool ili251x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata, -+ unsigned int finger, -+ unsigned int *x, unsigned int *y) -+{ -+ if (finger >= ILI251X_TOUCHES) -+ return false; -+ -+ *x = get_unaligned_be16(touchdata + 1 + (finger * 5) + 0); -+ if (!(*x & BIT(15))) /* Touch indication */ -+ return false; -+ -+ *x &= 0x3fff; -+ *y = get_unaligned_be16(touchdata + 1 + (finger * 5) + 2); -+ -+ return true; -+} -+ -+static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata) -+{ -+ struct input_dev *input = priv->input; -+ int i; -+ bool contact = false, touch = false; -+ unsigned int x = 0, y = 0; - -- input_report_abs(input, ABS_MT_POSITION_X, x); -- input_report_abs(input, ABS_MT_POSITION_Y, y); -+ for (i = 0; i < priv->max_touches; i++) { -+ if (priv->model == MODEL_ILI210X) { -+ touch = ili210x_touchdata_to_coords(priv, touchdata, -+ i, &x, &y); -+ } else if (priv->model == MODEL_ILI251X) { -+ touch = ili251x_touchdata_to_coords(priv, touchdata, -+ i, &x, &y); -+ if (touch) -+ contact = true; - } -+ -+ input_mt_slot(input, i); -+ input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); -+ if (!touch) -+ continue; -+ touchscreen_report_pos(input, &priv->prop, x, y, -+ true); - } - - input_mt_report_pointer_emulation(input, false); - input_sync(input); --} - --static bool get_pendown_state(const struct ili210x *priv) --{ -- bool state = false; -- -- if (priv->get_pendown_state) -- state = priv->get_pendown_state(); -+ if (priv->model == MODEL_ILI210X) -+ contact = touchdata[0] & 0xf3; - -- return state; -+ return contact; - } - - static void ili210x_work(struct work_struct *work) -@@ -118,20 +174,29 @@ static void ili210x_work(struct work_str - struct ili210x *priv = container_of(work, struct ili210x, - dwork.work); - struct i2c_client *client = priv->client; -- struct touchdata touchdata; -- int error; -+ u8 touchdata[64] = { 0 }; -+ bool touch; -+ int error = -EINVAL; -+ -+ if (priv->model == MODEL_ILI210X) { -+ error = ili210x_read_reg(client, REG_TOUCHDATA, -+ touchdata, sizeof(touchdata)); -+ } else if (priv->model == MODEL_ILI251X) { -+ error = ili210x_read_reg(client, REG_TOUCHDATA, -+ touchdata, 31); -+ if (!error && touchdata[0] == 2) -+ error = ili210x_read(client, &touchdata[31], 20); -+ } - -- error = ili210x_read_reg(client, REG_TOUCHDATA, -- &touchdata, sizeof(touchdata)); - if (error) { - dev_err(&client->dev, - "Unable to get touchdata, err = %d\n", error); - return; - } - -- ili210x_report_events(priv->input, &touchdata); -+ touch = ili210x_report_events(priv, touchdata); - -- if ((touchdata.status & 0xf3) || get_pendown_state(priv)) -+ if (touch) - schedule_delayed_work(&priv->dwork, - msecs_to_jiffies(priv->poll_period)); - } -@@ -180,30 +245,76 @@ static const struct attribute_group ili2 - .attrs = ili210x_attributes, - }; - -+static void ili210x_power_down(void *data) -+{ -+ struct gpio_desc *reset_gpio = data; -+ -+ gpiod_set_value_cansleep(reset_gpio, 1); -+} -+ -+static void ili210x_cancel_work(void *data) -+{ -+ struct ili210x *priv = data; -+ -+ cancel_delayed_work_sync(&priv->dwork); -+} -+ - static int ili210x_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) - { - struct device *dev = &client->dev; -- const struct ili210x_platform_data *pdata = dev_get_platdata(dev); - struct ili210x *priv; -+ struct gpio_desc *reset_gpio; - struct input_dev *input; -- struct panel_info panel; - struct firmware_version firmware; -- int xmax, ymax; -+ enum ili2xxx_model model; - int error; - -- dev_dbg(dev, "Probing for ILI210X I2C Touschreen driver"); -+ model = (enum ili2xxx_model)id->driver_data; - -- if (!pdata) { -- dev_err(dev, "No platform data!\n"); -- return -EINVAL; -- } -+ dev_dbg(dev, "Probing for ILI210X I2C Touschreen driver"); - - if (client->irq <= 0) { - dev_err(dev, "No IRQ!\n"); - return -EINVAL; - } - -+ reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); -+ if (IS_ERR(reset_gpio)) -+ return PTR_ERR(reset_gpio); -+ -+ if (reset_gpio) { -+ error = devm_add_action_or_reset(dev, ili210x_power_down, -+ reset_gpio); -+ if (error) -+ return error; -+ -+ usleep_range(50, 100); -+ gpiod_set_value_cansleep(reset_gpio, 0); -+ msleep(100); -+ } -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ input = devm_input_allocate_device(dev); -+ if (!input) -+ return -ENOMEM; -+ -+ priv->client = client; -+ priv->input = input; -+ priv->poll_period = DEFAULT_POLL_PERIOD; -+ INIT_DELAYED_WORK(&priv->dwork, ili210x_work); -+ priv->reset_gpio = reset_gpio; -+ priv->model = model; -+ if (model == MODEL_ILI210X) -+ priv->max_touches = ILI210X_TOUCHES; -+ if (model == MODEL_ILI251X) -+ priv->max_touches = ILI251X_TOUCHES; -+ -+ i2c_set_clientdata(client, priv); -+ - /* Get firmware version */ - error = ili210x_read_reg(client, REG_FIRMWARE_VERSION, - &firmware, sizeof(firmware)); -@@ -213,70 +324,40 @@ static int ili210x_i2c_probe(struct i2c_ - return error; - } - -- /* get panel info */ -- error = ili210x_read_reg(client, REG_PANEL_INFO, &panel, sizeof(panel)); -- if (error) { -- dev_err(dev, "Failed to get panel information, err: %d\n", -- error); -- return error; -- } -- -- xmax = panel.finger_max.x_low | (panel.finger_max.x_high << 8); -- ymax = panel.finger_max.y_low | (panel.finger_max.y_high << 8); -- -- priv = kzalloc(sizeof(*priv), GFP_KERNEL); -- input = input_allocate_device(); -- if (!priv || !input) { -- error = -ENOMEM; -- goto err_free_mem; -- } -- -- priv->client = client; -- priv->input = input; -- priv->get_pendown_state = pdata->get_pendown_state; -- priv->poll_period = pdata->poll_period ? : DEFAULT_POLL_PERIOD; -- INIT_DELAYED_WORK(&priv->dwork, ili210x_work); -- - /* Setup input device */ - input->name = "ILI210x Touchscreen"; - input->id.bustype = BUS_I2C; - input->dev.parent = dev; - -- __set_bit(EV_SYN, input->evbit); -- __set_bit(EV_KEY, input->evbit); -- __set_bit(EV_ABS, input->evbit); -- __set_bit(BTN_TOUCH, input->keybit); -- -- /* Single touch */ -- input_set_abs_params(input, ABS_X, 0, xmax, 0, 0); -- input_set_abs_params(input, ABS_Y, 0, ymax, 0, 0); -- - /* Multi touch */ -- input_mt_init_slots(input, MAX_TOUCHES, 0); -- input_set_abs_params(input, ABS_MT_POSITION_X, 0, xmax, 0, 0); -- input_set_abs_params(input, ABS_MT_POSITION_Y, 0, ymax, 0, 0); -+ input_set_abs_params(input, ABS_MT_POSITION_X, 0, 0xffff, 0, 0); -+ input_set_abs_params(input, ABS_MT_POSITION_Y, 0, 0xffff, 0, 0); -+ touchscreen_parse_properties(input, true, &priv->prop); -+ input_mt_init_slots(input, priv->max_touches, INPUT_MT_DIRECT); - -- i2c_set_clientdata(client, priv); -+ error = devm_add_action(dev, ili210x_cancel_work, priv); -+ if (error) -+ return error; - -- error = request_irq(client->irq, ili210x_irq, pdata->irq_flags, -- client->name, priv); -+ error = devm_request_irq(dev, client->irq, ili210x_irq, 0, -+ client->name, priv); - if (error) { - dev_err(dev, "Unable to request touchscreen IRQ, err: %d\n", - error); -- goto err_free_mem; -+ return error; - } - -- error = sysfs_create_group(&dev->kobj, &ili210x_attr_group); -+ error = devm_device_add_group(dev, &ili210x_attr_group); - if (error) { - dev_err(dev, "Unable to create sysfs attributes, err: %d\n", - error); -- goto err_free_irq; -+ return error; - } - - error = input_register_device(priv->input); - if (error) { - dev_err(dev, "Cannot register input device, err: %d\n", error); -- goto err_remove_sysfs; -+ return error; - } - - device_init_wakeup(dev, 1); -@@ -286,28 +367,6 @@ static int ili210x_i2c_probe(struct i2c_ - client->irq, firmware.id, firmware.major, firmware.minor); - - return 0; -- --err_remove_sysfs: -- sysfs_remove_group(&dev->kobj, &ili210x_attr_group); --err_free_irq: -- free_irq(client->irq, priv); --err_free_mem: -- input_free_device(input); -- kfree(priv); -- return error; --} -- --static int ili210x_i2c_remove(struct i2c_client *client) --{ -- struct ili210x *priv = i2c_get_clientdata(client); -- -- sysfs_remove_group(&client->dev.kobj, &ili210x_attr_group); -- free_irq(priv->client->irq, priv); -- cancel_delayed_work_sync(&priv->dwork); -- input_unregister_device(priv->input); -- kfree(priv); -- -- return 0; - } - - static int __maybe_unused ili210x_i2c_suspend(struct device *dev) -@@ -334,19 +393,27 @@ static SIMPLE_DEV_PM_OPS(ili210x_i2c_pm, - ili210x_i2c_suspend, ili210x_i2c_resume); - - static const struct i2c_device_id ili210x_i2c_id[] = { -- { "ili210x", 0 }, -+ { "ili210x", MODEL_ILI210X }, -+ { "ili251x", MODEL_ILI251X }, - { } - }; - MODULE_DEVICE_TABLE(i2c, ili210x_i2c_id); - -+static const struct of_device_id ili210x_dt_ids[] = { -+ { .compatible = "ilitek,ili210x", .data = (void *)MODEL_ILI210X }, -+ { .compatible = "ilitek,ili251x", .data = (void *)MODEL_ILI251X }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, ili210x_dt_ids); -+ - static struct i2c_driver ili210x_ts_driver = { - .driver = { - .name = "ili210x_i2c", - .pm = &ili210x_i2c_pm, -+ .of_match_table = ili210x_dt_ids, - }, - .id_table = ili210x_i2c_id, - .probe = ili210x_i2c_probe, -- .remove = ili210x_i2c_remove, - }; - - module_i2c_driver(ili210x_ts_driver); diff --git a/target/linux/brcm2708/patches-4.19/950-0424-Input-ili210x-add-DT-binding-document.patch b/target/linux/brcm2708/patches-4.19/950-0424-Input-ili210x-add-DT-binding-document.patch deleted file mode 100644 index 50dbc95393..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0424-Input-ili210x-add-DT-binding-document.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 5cea7939c6062752322697e33f8a90e33fca461f Mon Sep 17 00:00:00 2001 -From: Samuel Hsu -Date: Mon, 8 Apr 2019 16:49:51 +0200 -Subject: [PATCH 424/703] Input: ili210x - add DT binding document - -commit 41a852e002e65ab7a1e6841b485d72d022e95df2 upstream - -Add DT binding document for the Ilitek ILI210x and ILI251x -touchscreen controllers. - -Signed-off-by: Marek Vasut -Reviewed-by: Rob Herring -Signed-off-by: Dmitry Torokhov ---- - .../bindings/input/ilitek,ili2xxx.txt | 26 +++++++++++++++++++ - 1 file changed, 26 insertions(+) - create mode 100644 Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt -@@ -0,0 +1,26 @@ -+Ilitek ILI210x/ILI251x touchscreen controller -+ -+Required properties: -+- compatible: -+ ilitek,ili210x for ILI210x -+ ilitek,ili251x for ILI251x -+ -+- reg: The I2C address of the device -+ -+- interrupts: The sink for the touchscreen's IRQ output -+ See ../interrupt-controller/interrupts.txt -+ -+Optional properties for main touchpad device: -+ -+- reset-gpios: GPIO specifier for the touchscreen's reset pin (active low) -+ -+Example: -+ -+ touchscreen@41 { -+ compatible = "ilitek,ili251x"; -+ reg = <0x41>; -+ interrupt-parent = <&gpio4>; -+ interrupts = <7 IRQ_TYPE_EDGE_FALLING>; -+ reset-gpios = <&gpio5 21 GPIO_ACTIVE_LOW>; -+ }; -+ diff --git a/target/linux/brcm2708/patches-4.19/950-0424-dwc_otg-fix-locking-around-dequeueing-and-killing-UR.patch b/target/linux/brcm2708/patches-4.19/950-0424-dwc_otg-fix-locking-around-dequeueing-and-killing-UR.patch new file mode 100644 index 0000000000..b4f4d41772 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0424-dwc_otg-fix-locking-around-dequeueing-and-killing-UR.patch @@ -0,0 +1,63 @@ +From 9b55ce7579702f6a0bde5cd3e97b745f7b3f0239 Mon Sep 17 00:00:00 2001 +From: P33M +Date: Tue, 9 Apr 2019 16:40:48 +0100 +Subject: [PATCH 424/725] dwc_otg: fix locking around dequeueing and killing + URBs + +kill_urbs_in_qh_list() is practically only ever called with the fiq lock +already held, so don't spinlock twice in the case where we need to cancel +an isochronous transfer. + +Also fix up a case where the global interrupt register could be read with +the fiq lock not held. + +Fixes the deadlock seen in https://github.com/raspberrypi/linux/issues/2907 +--- + drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 9 +++++++-- + drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 4 ---- + 2 files changed, 7 insertions(+), 6 deletions(-) + +--- a/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c +@@ -1344,16 +1344,21 @@ static inline uint32_t dwc_otg_read_comm + */ + gintmsk_common.b.portintr = 1; + } +- gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts); +- gintmsk.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk); + if(fiq_enable) { + local_fiq_disable(); ++ fiq_fsm_spin_lock(&hcd->fiq_state->lock); ++ gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts); ++ gintmsk.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk); + /* Pull in the interrupts that the FIQ has masked */ + gintmsk.d32 |= ~(hcd->fiq_state->gintmsk_saved.d32); + gintmsk.d32 |= gintmsk_common.d32; + /* for the upstairs function to reenable - have to read it here in case FIQ triggers again */ + reenable_gintmsk->d32 = gintmsk.d32; ++ fiq_fsm_spin_unlock(&hcd->fiq_state->lock); + local_fiq_enable(); ++ } else { ++ gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts); ++ gintmsk.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk); + } + + gahbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gahbcfg); +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c +@@ -195,15 +195,11 @@ static void kill_urbs_in_qh_list(dwc_otg + * but not yet been through the IRQ handler. + */ + if (fiq_fsm_enable && (hcd->fiq_state->channel[qh->channel->hc_num].fsm != FIQ_PASSTHROUGH)) { +- local_fiq_disable(); +- fiq_fsm_spin_lock(&hcd->fiq_state->lock); + qh->channel->halt_status = DWC_OTG_HC_XFER_URB_DEQUEUE; + qh->channel->halt_pending = 1; + if (hcd->fiq_state->channel[n].fsm == FIQ_HS_ISOC_TURBO || + hcd->fiq_state->channel[n].fsm == FIQ_HS_ISOC_SLEEPING) + hcd->fiq_state->channel[n].fsm = FIQ_HS_ISOC_ABORTED; +- fiq_fsm_spin_unlock(&hcd->fiq_state->lock); +- local_fiq_enable(); + } else { + dwc_otg_hc_halt(hcd->core_if, qh->channel, + DWC_OTG_HC_XFER_URB_DEQUEUE); diff --git a/target/linux/brcm2708/patches-4.19/950-0425-configs-Add-TOUCHSCREEN_ILI210X-m.patch b/target/linux/brcm2708/patches-4.19/950-0425-configs-Add-TOUCHSCREEN_ILI210X-m.patch deleted file mode 100644 index 970ae3a95e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0425-configs-Add-TOUCHSCREEN_ILI210X-m.patch +++ /dev/null @@ -1,42 +0,0 @@ -From e01ec5fd94e01b665f4deb1567f5b1da0537cce8 Mon Sep 17 00:00:00 2001 -From: Samuel Hsu -Date: Mon, 8 Apr 2019 16:54:34 +0200 -Subject: [PATCH 425/703] configs: Add TOUCHSCREEN_ILI210X=m - -Signed-off-by: Samuel Hsu ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - arch/arm64/configs/bcmrpi3_defconfig | 1 + - 3 files changed, 3 insertions(+) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -565,6 +565,7 @@ CONFIG_TOUCHSCREEN_ADS7846=m - CONFIG_TOUCHSCREEN_EGALAX=m - CONFIG_TOUCHSCREEN_EXC3000=m - CONFIG_TOUCHSCREEN_GOODIX=m -+CONFIG_TOUCHSCREEN_ILI210X=m - CONFIG_TOUCHSCREEN_EDT_FT5X06=m - CONFIG_TOUCHSCREEN_RPI_FT5406=m - CONFIG_TOUCHSCREEN_USB_COMPOSITE=m ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -559,6 +559,7 @@ CONFIG_TOUCHSCREEN_ADS7846=m - CONFIG_TOUCHSCREEN_EGALAX=m - CONFIG_TOUCHSCREEN_EXC3000=m - CONFIG_TOUCHSCREEN_GOODIX=m -+CONFIG_TOUCHSCREEN_ILI210X=m - CONFIG_TOUCHSCREEN_EDT_FT5X06=m - CONFIG_TOUCHSCREEN_RPI_FT5406=m - CONFIG_TOUCHSCREEN_USB_COMPOSITE=m ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -547,6 +547,7 @@ CONFIG_INPUT_TOUCHSCREEN=y - CONFIG_TOUCHSCREEN_ADS7846=m - CONFIG_TOUCHSCREEN_EGALAX=m - CONFIG_TOUCHSCREEN_EKTF2127=m -+CONFIG_TOUCHSCREEN_ILI210X=m - CONFIG_TOUCHSCREEN_RPI_FT5406=m - CONFIG_TOUCHSCREEN_USB_COMPOSITE=m - CONFIG_TOUCHSCREEN_STMPE=m diff --git a/target/linux/brcm2708/patches-4.19/950-0425-rtc-rv3028-Add-backup-switchover-mode-support.patch b/target/linux/brcm2708/patches-4.19/950-0425-rtc-rv3028-Add-backup-switchover-mode-support.patch new file mode 100644 index 0000000000..4fcefaf2c1 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0425-rtc-rv3028-Add-backup-switchover-mode-support.patch @@ -0,0 +1,50 @@ +From 94ff67715e55c545dccbc00c8930a7566ba05a6c Mon Sep 17 00:00:00 2001 +From: Phil Howard +Date: Fri, 29 Mar 2019 10:53:14 +0000 +Subject: [PATCH 425/725] rtc: rv3028: Add backup switchover mode support + +Signed-off-by: Phil Howard +--- + drivers/rtc/rtc-rv3028.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/drivers/rtc/rtc-rv3028.c ++++ b/drivers/rtc/rtc-rv3028.c +@@ -74,6 +74,7 @@ + + #define RV3028_BACKUP_TCE BIT(5) + #define RV3028_BACKUP_TCR_MASK GENMASK(1,0) ++#define RV3028_BACKUP_BSM_MASK 0x0C + + #define OFFSET_STEP_PPT 953674 + +@@ -601,6 +602,7 @@ static int rv3028_probe(struct i2c_clien + struct rv3028_data *rv3028; + int ret, status; + u32 ohms; ++ u8 bsm; + struct nvmem_config nvmem_cfg = { + .name = "rv3028_nvram", + .word_size = 1, +@@ -671,6 +673,21 @@ static int rv3028_probe(struct i2c_clien + if (ret) + return ret; + ++ /* setup backup switchover mode */ ++ if (!device_property_read_u8(&client->dev, "backup-switchover-mode", ++ &bsm)) { ++ if (bsm <= 3) { ++ ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP, ++ RV3028_BACKUP_BSM_MASK, ++ (bsm & 0x03) << 2); ++ ++ if (ret) ++ return ret; ++ } else { ++ dev_warn(&client->dev, "invalid backup switchover mode value\n"); ++ } ++ } ++ + /* setup trickle charger */ + if (!device_property_read_u32(&client->dev, "trickle-resistor-ohms", + &ohms)) { diff --git a/target/linux/brcm2708/patches-4.19/950-0426-BCM2708-Add-core-Device-Tree-support-ilitek251x.patch b/target/linux/brcm2708/patches-4.19/950-0426-BCM2708-Add-core-Device-Tree-support-ilitek251x.patch deleted file mode 100644 index b2b62ba39a..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0426-BCM2708-Add-core-Device-Tree-support-ilitek251x.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 7b15bdfee1c922d6c3e92329cd23a45e77e036ae Mon Sep 17 00:00:00 2001 -From: Samuel Hsu -Date: Mon, 8 Apr 2019 17:06:44 +0200 -Subject: [PATCH 426/703] BCM2708: Add core Device Tree support, ilitek251x - -Signed-off-by: Samuel Hsu ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 11 +++++ - .../boot/dts/overlays/ilitek251x-overlay.dts | 45 +++++++++++++++++++ - 3 files changed, 57 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/ilitek251x-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -67,6 +67,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - i2c0-bcm2708.dtbo \ - i2c1-bcm2708.dtbo \ - i2s-gpio28-31.dtbo \ -+ ilitek251x.dtbo \ - iqaudio-dac.dtbo \ - iqaudio-dacplus.dtbo \ - iqaudio-digi-wm8804-audio.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1146,6 +1146,17 @@ Load: dtoverlay=i2s-gpio28-31 - Params: - - -+Name: ilitek251x -+Info: Enables I2C connected Ilitek 251x multiple touch controller using -+ GPIO 4 (pin 7 on GPIO header) for interrupt. -+Load: dtoverlay=ilitek251x,= -+Params: interrupt GPIO used for interrupt (default 4) -+ sizex Touchscreen size x, horizontal resolution of -+ touchscreen (in pixels) -+ sizey Touchscreen size y, vertical resolution of -+ touchscreen (in pixels) -+ -+ - Name: iqaudio-dac - Info: Configures the IQaudio DAC audio card - Load: dtoverlay=iqaudio-dac, ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/ilitek251x-overlay.dts -@@ -0,0 +1,45 @@ -+// Device tree overlay for I2C connected Ilitek multiple touch controller -+/dts-v1/; -+/plugin/; -+ -+ / { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&gpio>; -+ __overlay__ { -+ ili251x_pins: ili251x_pins { -+ brcm,pins = <4>; // interrupt -+ brcm,function = <0>; // in -+ brcm,pull = <2>; // pull-up // -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ ili251x: ili251x@41 { -+ compatible = "ilitek,ili251x"; -+ reg = <0x41>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&ili251x_pins>; -+ interrupt-parent = <&gpio>; -+ interrupts = <4 8>; // high-to-low edge triggered -+ touchscreen-size-x = <16384>; -+ touchscreen-size-y = <9600>; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ interrupt = <&ili251x_pins>,"brcm,pins:0", -+ <&ili251x>,"interrupts:0"; -+ sizex = <&ili251x>,"touchscreen-size-x:0"; -+ sizey = <&ili251x>,"touchscreen-size-y:0"; -+ }; -+}; diff --git a/target/linux/brcm2708/patches-4.19/950-0426-dt-bindings-rv3028-backup-switchover-support.patch b/target/linux/brcm2708/patches-4.19/950-0426-dt-bindings-rv3028-backup-switchover-support.patch new file mode 100644 index 0000000000..2d0b40dd3e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0426-dt-bindings-rv3028-backup-switchover-support.patch @@ -0,0 +1,20 @@ +From 35cd2dda8463e8a1d20789487505809723953464 Mon Sep 17 00:00:00 2001 +From: Phil Howard +Date: Fri, 29 Mar 2019 10:57:07 +0000 +Subject: [PATCH 426/725] dt-bindings: rv3028 backup switchover support + +Signed-off-by: Phil Howard +--- + Documentation/devicetree/bindings/rtc/rtc.txt | 1 + + 1 file changed, 1 insertion(+) + +--- a/Documentation/devicetree/bindings/rtc/rtc.txt ++++ b/Documentation/devicetree/bindings/rtc/rtc.txt +@@ -26,6 +26,7 @@ below. + - trickle-diode-disable : Do not use internal trickle charger diode Should be + given if internal trickle charger diode should be + disabled ++- backup-switchover-mode : Configure RTC backup power supply switch behaviour + - wakeup-source : Enables wake up of host system on alarm + - quartz-load-femtofarads : The capacitive load of the quartz(x-tal), + expressed in femto Farad (fF). diff --git a/target/linux/brcm2708/patches-4.19/950-0427-dwc_otg-fix-locking-around-dequeueing-and-killing-UR.patch b/target/linux/brcm2708/patches-4.19/950-0427-dwc_otg-fix-locking-around-dequeueing-and-killing-UR.patch deleted file mode 100644 index c04b503584..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0427-dwc_otg-fix-locking-around-dequeueing-and-killing-UR.patch +++ /dev/null @@ -1,63 +0,0 @@ -From ddd696d15f75315f1a20d5da57d94ed65d8c1404 Mon Sep 17 00:00:00 2001 -From: P33M -Date: Tue, 9 Apr 2019 16:40:48 +0100 -Subject: [PATCH 427/703] dwc_otg: fix locking around dequeueing and killing - URBs - -kill_urbs_in_qh_list() is practically only ever called with the fiq lock -already held, so don't spinlock twice in the case where we need to cancel -an isochronous transfer. - -Also fix up a case where the global interrupt register could be read with -the fiq lock not held. - -Fixes the deadlock seen in https://github.com/raspberrypi/linux/issues/2907 ---- - drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 9 +++++++-- - drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 4 ---- - 2 files changed, 7 insertions(+), 6 deletions(-) - ---- a/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c -@@ -1344,16 +1344,21 @@ static inline uint32_t dwc_otg_read_comm - */ - gintmsk_common.b.portintr = 1; - } -- gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts); -- gintmsk.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk); - if(fiq_enable) { - local_fiq_disable(); -+ fiq_fsm_spin_lock(&hcd->fiq_state->lock); -+ gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts); -+ gintmsk.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk); - /* Pull in the interrupts that the FIQ has masked */ - gintmsk.d32 |= ~(hcd->fiq_state->gintmsk_saved.d32); - gintmsk.d32 |= gintmsk_common.d32; - /* for the upstairs function to reenable - have to read it here in case FIQ triggers again */ - reenable_gintmsk->d32 = gintmsk.d32; -+ fiq_fsm_spin_unlock(&hcd->fiq_state->lock); - local_fiq_enable(); -+ } else { -+ gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts); -+ gintmsk.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk); - } - - gahbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gahbcfg); ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -@@ -195,15 +195,11 @@ static void kill_urbs_in_qh_list(dwc_otg - * but not yet been through the IRQ handler. - */ - if (fiq_fsm_enable && (hcd->fiq_state->channel[qh->channel->hc_num].fsm != FIQ_PASSTHROUGH)) { -- local_fiq_disable(); -- fiq_fsm_spin_lock(&hcd->fiq_state->lock); - qh->channel->halt_status = DWC_OTG_HC_XFER_URB_DEQUEUE; - qh->channel->halt_pending = 1; - if (hcd->fiq_state->channel[n].fsm == FIQ_HS_ISOC_TURBO || - hcd->fiq_state->channel[n].fsm == FIQ_HS_ISOC_SLEEPING) - hcd->fiq_state->channel[n].fsm = FIQ_HS_ISOC_ABORTED; -- fiq_fsm_spin_unlock(&hcd->fiq_state->lock); -- local_fiq_enable(); - } else { - dwc_otg_hc_halt(hcd->core_if, qh->channel, - DWC_OTG_HC_XFER_URB_DEQUEUE); diff --git a/target/linux/brcm2708/patches-4.19/950-0427-overlays-Add-rv3028-backup-switchover-support-to-i2c.patch b/target/linux/brcm2708/patches-4.19/950-0427-overlays-Add-rv3028-backup-switchover-support-to-i2c.patch new file mode 100644 index 0000000000..a9ba11ad76 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0427-overlays-Add-rv3028-backup-switchover-support-to-i2c.patch @@ -0,0 +1,34 @@ +From 3ef74a4e32c2d5d7893b6743e2379fbfcac6fd91 Mon Sep 17 00:00:00 2001 +From: Phil Howard +Date: Fri, 29 Mar 2019 10:59:55 +0000 +Subject: [PATCH 427/725] overlays: Add rv3028 backup switchover support to + i2c-rtc + +Signed-off-by: Phil Howard +--- + arch/arm/boot/dts/overlays/README | 3 +++ + arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 1 + + 2 files changed, 4 insertions(+) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1013,6 +1013,9 @@ Params: abx80x Select o + wakeup-source Specify that the RTC can be used as a wakeup + source + ++ backup-switchover-mode Backup power supply switch mode. Must be 0 for ++ off or 1 for Vdd < VBackup (RV3028 only) ++ + + Name: i2c-rtc-gpio + Info: Adds support for a number of I2C Real Time Clock devices +--- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts +@@ -200,6 +200,7 @@ + trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0", + <&abx80x>,"abracon,tc-resistor", + <&rv3028>,"trickle-resistor-ohms:0"; ++ backup-switchover-mode = <&rv3028>,"backup-switchover-mode:0"; + wakeup-source = <&ds1339>,"wakeup-source?", + <&ds3231>,"wakeup-source?", + <&mcp7940x>,"wakeup-source?", diff --git a/target/linux/brcm2708/patches-4.19/950-0428-Maxim-MAX98357A-I2S-DAC-overlay-2935.patch b/target/linux/brcm2708/patches-4.19/950-0428-Maxim-MAX98357A-I2S-DAC-overlay-2935.patch new file mode 100644 index 0000000000..700209247e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0428-Maxim-MAX98357A-I2S-DAC-overlay-2935.patch @@ -0,0 +1,130 @@ +From 8a063d9d7c86075dbae91ef353540ab7724cce35 Mon Sep 17 00:00:00 2001 +From: wavelet2 <20504977+wavelet2@users.noreply.github.com> +Date: Mon, 15 Apr 2019 10:00:20 +0100 +Subject: [PATCH 428/725] Maxim MAX98357A I2S DAC overlay (#2935) + +Add overlay for Maxim MAX98357A I2S DAC. + +Signed-off-by: Richard Steedman +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 9 ++ + .../boot/dts/overlays/max98357a-overlay.dts | 84 +++++++++++++++++++ + 3 files changed, 94 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/max98357a-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -75,6 +75,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + justboom-dac.dtbo \ + justboom-digi.dtbo \ + ltc294x.dtbo \ ++ max98357a.dtbo \ + mbed-dac.dtbo \ + mcp23017.dtbo \ + mcp23s17.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1276,6 +1276,15 @@ Params: ltc2941 Select t + See the datasheet for more information. + + ++Name: max98357a ++Info: Configures the Maxim MAX98357A I2S DAC ++Load: dtoverlay=max98357a,= ++Params: no-sdmode Driver does not manage the state of the DAC's ++ SD_MODE pin (i.e. chip is always on). ++ sdmode-pin integer, GPIO pin connected to the SD_MODE input ++ of the DAC (default GPIO4 if parameter omitted). ++ ++ + Name: mbed-dac + Info: Configures the mbed AudioCODEC (TLV320AIC23B) + Load: dtoverlay=mbed-dac +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/max98357a-overlay.dts +@@ -0,0 +1,84 @@ ++// Overlay for Maxim MAX98357A audio DAC ++ ++// dtparams: ++// no-sdmode - SD_MODE pin not managed by driver. ++// sdmode-pin - Specify GPIO pin to which SD_MODE is connected (default 4). ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ /* Enable I2S */ ++ fragment@0 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ /* DAC whose SD_MODE pin is managed by driver (via GPIO pin) */ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ max98357a_dac: max98357a { ++ compatible = "maxim,max98357a"; ++ #sound-dai-cells = <0>; ++ sdmode-gpios = <&gpio 4 0>; /* 2nd word overwritten by sdmode-pin parameter */ ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ /* DAC whose SD_MODE pin is not managed by driver */ ++ fragment@2 { ++ target-path = "/"; ++ __dormant__ { ++ max98357a_nsd: max98357a { ++ compatible = "maxim,max98357a"; ++ #sound-dai-cells = <0>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ /* Soundcard connecting I2S to DAC with SD_MODE */ ++ fragment@3 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,name = "MAX98357A"; ++ status = "okay"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&max98357a_dac>; ++ }; ++ }; ++ }; ++ ++ /* Soundcard connecting I2S to DAC without SD_MODE */ ++ fragment@4 { ++ target = <&sound>; ++ __dormant__ { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,name = "MAX98357A"; ++ status = "okay"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&max98357a_nsd>; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ no-sdmode = <0>,"-1+2-3+4"; ++ sdmode-pin = <&max98357a_dac>,"sdmode-gpios:4"; ++ }; ++}; diff --git a/target/linux/brcm2708/patches-4.19/950-0428-rtc-rv3028-Add-backup-switchover-mode-support.patch b/target/linux/brcm2708/patches-4.19/950-0428-rtc-rv3028-Add-backup-switchover-mode-support.patch deleted file mode 100644 index 765f8c1f53..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0428-rtc-rv3028-Add-backup-switchover-mode-support.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 5159281b7a2fe2f4dc1cc2f1cd97d45972f02d99 Mon Sep 17 00:00:00 2001 -From: Phil Howard -Date: Fri, 29 Mar 2019 10:53:14 +0000 -Subject: [PATCH 428/703] rtc: rv3028: Add backup switchover mode support - -Signed-off-by: Phil Howard ---- - drivers/rtc/rtc-rv3028.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - ---- a/drivers/rtc/rtc-rv3028.c -+++ b/drivers/rtc/rtc-rv3028.c -@@ -74,6 +74,7 @@ - - #define RV3028_BACKUP_TCE BIT(5) - #define RV3028_BACKUP_TCR_MASK GENMASK(1,0) -+#define RV3028_BACKUP_BSM_MASK 0x0C - - #define OFFSET_STEP_PPT 953674 - -@@ -601,6 +602,7 @@ static int rv3028_probe(struct i2c_clien - struct rv3028_data *rv3028; - int ret, status; - u32 ohms; -+ u8 bsm; - struct nvmem_config nvmem_cfg = { - .name = "rv3028_nvram", - .word_size = 1, -@@ -671,6 +673,21 @@ static int rv3028_probe(struct i2c_clien - if (ret) - return ret; - -+ /* setup backup switchover mode */ -+ if (!device_property_read_u8(&client->dev, "backup-switchover-mode", -+ &bsm)) { -+ if (bsm <= 3) { -+ ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP, -+ RV3028_BACKUP_BSM_MASK, -+ (bsm & 0x03) << 2); -+ -+ if (ret) -+ return ret; -+ } else { -+ dev_warn(&client->dev, "invalid backup switchover mode value\n"); -+ } -+ } -+ - /* setup trickle charger */ - if (!device_property_read_u32(&client->dev, "trickle-resistor-ohms", - &ohms)) { diff --git a/target/linux/brcm2708/patches-4.19/950-0429-dt-bindings-rv3028-backup-switchover-support.patch b/target/linux/brcm2708/patches-4.19/950-0429-dt-bindings-rv3028-backup-switchover-support.patch deleted file mode 100644 index 7a9c962deb..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0429-dt-bindings-rv3028-backup-switchover-support.patch +++ /dev/null @@ -1,20 +0,0 @@ -From ea30c9b919bbd7695f99e0467f3546ac945d4e54 Mon Sep 17 00:00:00 2001 -From: Phil Howard -Date: Fri, 29 Mar 2019 10:57:07 +0000 -Subject: [PATCH 429/703] dt-bindings: rv3028 backup switchover support - -Signed-off-by: Phil Howard ---- - Documentation/devicetree/bindings/rtc/rtc.txt | 1 + - 1 file changed, 1 insertion(+) - ---- a/Documentation/devicetree/bindings/rtc/rtc.txt -+++ b/Documentation/devicetree/bindings/rtc/rtc.txt -@@ -26,6 +26,7 @@ below. - - trickle-diode-disable : Do not use internal trickle charger diode Should be - given if internal trickle charger diode should be - disabled -+- backup-switchover-mode : Configure RTC backup power supply switch behaviour - - wakeup-source : Enables wake up of host system on alarm - - quartz-load-femtofarads : The capacitive load of the quartz(x-tal), - expressed in femto Farad (fF). diff --git a/target/linux/brcm2708/patches-4.19/950-0429-sound-Fixes-for-audioinjector-octo-under-4.19.patch b/target/linux/brcm2708/patches-4.19/950-0429-sound-Fixes-for-audioinjector-octo-under-4.19.patch new file mode 100644 index 0000000000..93a0c9029a --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0429-sound-Fixes-for-audioinjector-octo-under-4.19.patch @@ -0,0 +1,108 @@ +From c349bcade000820be4f53dd2d189887ec11794d4 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 21 Mar 2019 11:19:46 +0000 +Subject: [PATCH 429/725] sound: Fixes for audioinjector-octo under 4.19 + +1. Move the DT alias declaration to the I2C shim in the cases +where the shim is enabled. This works around a problem caused by a +4.19 commit [1] that generates DT/OF uevents for I2C drivers. + +2. Fix the diagnostics in an error path of the soundcard driver to +correctly identify the reason for the failure to load. + +3. Move the declaration of the clock node in the overlay outside +the I2C node to avoid warnings. + +4. Sort the overlay nodes so that dependencies are only to earlier +fragments, in an attempt to get runtime dtoverlay application to +work (it still doesn't...) + +See: https://github.com/Audio-Injector/Octo/issues/14 +Signed-off-by: Phil Elwell + +[1] af503716ac14 ("i2c: core: report OF style module alias for devices registered via OF") +--- + .../overlays/audioinjector-addons-overlay.dts | 19 ++++++++++++------- + sound/soc/bcm/audioinjector-octo-soundcard.c | 2 +- + sound/soc/codecs/cs42xx8-i2c.c | 7 +++++++ + sound/soc/codecs/cs42xx8.c | 2 ++ + 4 files changed, 22 insertions(+), 8 deletions(-) + +--- a/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts ++++ b/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts +@@ -13,6 +13,17 @@ + }; + + fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ cs42448_mclk: codec-mclk { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <49152000>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; +@@ -27,16 +38,10 @@ + clock-names = "mclk"; + status = "okay"; + }; +- +- cs42448_mclk: codec-mclk { +- compatible = "fixed-clock"; +- #clock-cells = <0>; +- clock-frequency = <49152000>; +- }; + }; + }; + +- fragment@2 { ++ fragment@3 { + target = <&sound>; + snd: __overlay__ { + compatible = "ai,audioinjector-octo-soundcard"; +--- a/sound/soc/bcm/audioinjector-octo-soundcard.c ++++ b/sound/soc/bcm/audioinjector-octo-soundcard.c +@@ -297,7 +297,7 @@ static int audioinjector_octo_probe(stru + dai->codec_name = NULL; + dai->codec_of_node = codec_node; + } else +- if (!dai->cpu_of_node) { ++ if (!i2s_node) { + dev_err(&pdev->dev, + "i2s-controller missing or invalid in DT\n"); + return -EINVAL; +--- a/sound/soc/codecs/cs42xx8-i2c.c ++++ b/sound/soc/codecs/cs42xx8-i2c.c +@@ -45,6 +45,13 @@ static struct i2c_device_id cs42xx8_i2c_ + }; + MODULE_DEVICE_TABLE(i2c, cs42xx8_i2c_id); + ++const struct of_device_id cs42xx8_of_match[] = { ++ { .compatible = "cirrus,cs42448", .data = &cs42448_data, }, ++ { .compatible = "cirrus,cs42888", .data = &cs42888_data, }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, cs42xx8_of_match); ++ + static struct i2c_driver cs42xx8_i2c_driver = { + .driver = { + .name = "cs42xx8", +--- a/sound/soc/codecs/cs42xx8.c ++++ b/sound/soc/codecs/cs42xx8.c +@@ -436,8 +436,10 @@ const struct of_device_id cs42xx8_of_mat + { .compatible = "cirrus,cs42888", .data = &cs42888_data, }, + { /* sentinel */ } + }; ++#if !IS_ENABLED(CONFIG_SND_SOC_CS42XX8_I2C) + MODULE_DEVICE_TABLE(of, cs42xx8_of_match); + EXPORT_SYMBOL_GPL(cs42xx8_of_match); ++#endif + + int cs42xx8_probe(struct device *dev, struct regmap *regmap) + { diff --git a/target/linux/brcm2708/patches-4.19/950-0430-Revert-cgroup-Disable-cgroup-memory-by-default.patch b/target/linux/brcm2708/patches-4.19/950-0430-Revert-cgroup-Disable-cgroup-memory-by-default.patch new file mode 100644 index 0000000000..2ed5dc03b2 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0430-Revert-cgroup-Disable-cgroup-memory-by-default.patch @@ -0,0 +1,63 @@ +From 95eef94518f050146820340787b2472db13c38ae Mon Sep 17 00:00:00 2001 +From: P33M +Date: Wed, 24 Apr 2019 14:25:09 +0100 +Subject: [PATCH 430/725] Revert "cgroup: Disable cgroup "memory" by default" + +This reverts commit cd6ce4d0ded13c94ff5208c679ed5e030263149b. +--- + kernel/cgroup/cgroup.c | 30 ------------------------------ + 1 file changed, 30 deletions(-) + +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -5296,8 +5296,6 @@ int __init cgroup_init_early(void) + } + + static u16 cgroup_disable_mask __initdata; +-static u16 cgroup_enable_mask __initdata; +-static int __init cgroup_disable(char *str); + + /** + * cgroup_init - cgroup initialization +@@ -5338,12 +5336,6 @@ int __init cgroup_init(void) + + mutex_unlock(&cgroup_mutex); + +- /* Apply an implicit disable... */ +- cgroup_disable("memory"); +- +- /* ...knowing that an explicit enable will override it. */ +- cgroup_disable_mask &= ~cgroup_enable_mask; +- + for_each_subsys(ss, ssid) { + if (ss->early_init) { + struct cgroup_subsys_state *css = +@@ -5727,28 +5719,6 @@ static int __init cgroup_disable(char *s + } + __setup("cgroup_disable=", cgroup_disable); + +-static int __init cgroup_enable(char *str) +-{ +- struct cgroup_subsys *ss; +- char *token; +- int i; +- +- while ((token = strsep(&str, ",")) != NULL) { +- if (!*token) +- continue; +- +- for_each_subsys(ss, i) { +- if (strcmp(token, ss->name) && +- strcmp(token, ss->legacy_name)) +- continue; +- +- cgroup_enable_mask |= 1 << i; +- } +- } +- return 1; +-} +-__setup("cgroup_enable=", cgroup_enable); +- + /** + * css_tryget_online_from_dir - get corresponding css from a cgroup dentry + * @dentry: directory dentry of interest diff --git a/target/linux/brcm2708/patches-4.19/950-0430-overlays-Add-rv3028-backup-switchover-support-to-i2c.patch b/target/linux/brcm2708/patches-4.19/950-0430-overlays-Add-rv3028-backup-switchover-support-to-i2c.patch deleted file mode 100644 index 08a205c27a..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0430-overlays-Add-rv3028-backup-switchover-support-to-i2c.patch +++ /dev/null @@ -1,34 +0,0 @@ -From a73793c4cea3ef39d203c6a0e7e3456629e25f5e Mon Sep 17 00:00:00 2001 -From: Phil Howard -Date: Fri, 29 Mar 2019 10:59:55 +0000 -Subject: [PATCH 430/703] overlays: Add rv3028 backup switchover support to - i2c-rtc - -Signed-off-by: Phil Howard ---- - arch/arm/boot/dts/overlays/README | 3 +++ - arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 1 + - 2 files changed, 4 insertions(+) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1013,6 +1013,9 @@ Params: abx80x Select o - wakeup-source Specify that the RTC can be used as a wakeup - source - -+ backup-switchover-mode Backup power supply switch mode. Must be 0 for -+ off or 1 for Vdd < VBackup (RV3028 only) -+ - - Name: i2c-rtc-gpio - Info: Adds support for a number of I2C Real Time Clock devices ---- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -@@ -200,6 +200,7 @@ - trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0", - <&abx80x>,"abracon,tc-resistor", - <&rv3028>,"trickle-resistor-ohms:0"; -+ backup-switchover-mode = <&rv3028>,"backup-switchover-mode:0"; - wakeup-source = <&ds1339>,"wakeup-source?", - <&ds3231>,"wakeup-source?", - <&mcp7940x>,"wakeup-source?", diff --git a/target/linux/brcm2708/patches-4.19/950-0431-Maxim-MAX98357A-I2S-DAC-overlay-2935.patch b/target/linux/brcm2708/patches-4.19/950-0431-Maxim-MAX98357A-I2S-DAC-overlay-2935.patch deleted file mode 100644 index c9136fda0f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0431-Maxim-MAX98357A-I2S-DAC-overlay-2935.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 43371fb1fb2a2eaefe54288bcd61d015237c25fe Mon Sep 17 00:00:00 2001 -From: wavelet2 <20504977+wavelet2@users.noreply.github.com> -Date: Mon, 15 Apr 2019 10:00:20 +0100 -Subject: [PATCH 431/703] Maxim MAX98357A I2S DAC overlay (#2935) - -Add overlay for Maxim MAX98357A I2S DAC. - -Signed-off-by: Richard Steedman ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 9 ++ - .../boot/dts/overlays/max98357a-overlay.dts | 84 +++++++++++++++++++ - 3 files changed, 94 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/max98357a-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -75,6 +75,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - justboom-dac.dtbo \ - justboom-digi.dtbo \ - ltc294x.dtbo \ -+ max98357a.dtbo \ - mbed-dac.dtbo \ - mcp23017.dtbo \ - mcp23s17.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1276,6 +1276,15 @@ Params: ltc2941 Select t - See the datasheet for more information. - - -+Name: max98357a -+Info: Configures the Maxim MAX98357A I2S DAC -+Load: dtoverlay=max98357a,= -+Params: no-sdmode Driver does not manage the state of the DAC's -+ SD_MODE pin (i.e. chip is always on). -+ sdmode-pin integer, GPIO pin connected to the SD_MODE input -+ of the DAC (default GPIO4 if parameter omitted). -+ -+ - Name: mbed-dac - Info: Configures the mbed AudioCODEC (TLV320AIC23B) - Load: dtoverlay=mbed-dac ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/max98357a-overlay.dts -@@ -0,0 +1,84 @@ -+// Overlay for Maxim MAX98357A audio DAC -+ -+// dtparams: -+// no-sdmode - SD_MODE pin not managed by driver. -+// sdmode-pin - Specify GPIO pin to which SD_MODE is connected (default 4). -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ /* Enable I2S */ -+ fragment@0 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ /* DAC whose SD_MODE pin is managed by driver (via GPIO pin) */ -+ fragment@1 { -+ target-path = "/"; -+ __overlay__ { -+ max98357a_dac: max98357a { -+ compatible = "maxim,max98357a"; -+ #sound-dai-cells = <0>; -+ sdmode-gpios = <&gpio 4 0>; /* 2nd word overwritten by sdmode-pin parameter */ -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ /* DAC whose SD_MODE pin is not managed by driver */ -+ fragment@2 { -+ target-path = "/"; -+ __dormant__ { -+ max98357a_nsd: max98357a { -+ compatible = "maxim,max98357a"; -+ #sound-dai-cells = <0>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ /* Soundcard connecting I2S to DAC with SD_MODE */ -+ fragment@3 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "simple-audio-card"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,name = "MAX98357A"; -+ status = "okay"; -+ simple-audio-card,cpu { -+ sound-dai = <&i2s>; -+ }; -+ simple-audio-card,codec { -+ sound-dai = <&max98357a_dac>; -+ }; -+ }; -+ }; -+ -+ /* Soundcard connecting I2S to DAC without SD_MODE */ -+ fragment@4 { -+ target = <&sound>; -+ __dormant__ { -+ compatible = "simple-audio-card"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,name = "MAX98357A"; -+ status = "okay"; -+ simple-audio-card,cpu { -+ sound-dai = <&i2s>; -+ }; -+ simple-audio-card,codec { -+ sound-dai = <&max98357a_nsd>; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ no-sdmode = <0>,"-1+2-3+4"; -+ sdmode-pin = <&max98357a_dac>,"sdmode-gpios:4"; -+ }; -+}; diff --git a/target/linux/brcm2708/patches-4.19/950-0431-Revert-defconfigs-disable-memory-and-IO-cgroups-2908.patch b/target/linux/brcm2708/patches-4.19/950-0431-Revert-defconfigs-disable-memory-and-IO-cgroups-2908.patch new file mode 100644 index 0000000000..87be3b154c --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0431-Revert-defconfigs-disable-memory-and-IO-cgroups-2908.patch @@ -0,0 +1,79 @@ +From 6e1f012d8072528275a751fa9b12496bfcc07088 Mon Sep 17 00:00:00 2001 +From: P33M +Date: Wed, 24 Apr 2019 14:25:41 +0100 +Subject: [PATCH 431/725] Revert "defconfigs: disable memory and IO cgroups + (#2908)" + +This reverts commit 9881cdbf446081f71c62f39f4c56a21001baea73. +--- + arch/arm/configs/bcm2709_defconfig | 4 ++++ + arch/arm/configs/bcmrpi_defconfig | 4 ++++ + arch/arm64/configs/bcmrpi3_defconfig | 4 ++++ + 3 files changed, 12 insertions(+) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -14,6 +14,8 @@ CONFIG_TASK_XACCT=y + CONFIG_TASK_IO_ACCOUNTING=y + CONFIG_IKCONFIG=m + CONFIG_IKCONFIG_PROC=y ++CONFIG_MEMCG=y ++CONFIG_BLK_CGROUP=y + CONFIG_CGROUP_FREEZER=y + CONFIG_CPUSETS=y + CONFIG_CGROUP_DEVICE=y +@@ -62,8 +64,10 @@ CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + CONFIG_MODVERSIONS=y + CONFIG_MODULE_SRCVERSION_ALL=y ++CONFIG_BLK_DEV_THROTTLING=y + CONFIG_PARTITION_ADVANCED=y + CONFIG_MAC_PARTITION=y ++CONFIG_CFQ_GROUP_IOSCHED=y + CONFIG_BINFMT_MISC=m + CONFIG_CLEANCACHE=y + CONFIG_FRONTSWAP=y +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -13,6 +13,8 @@ CONFIG_TASK_XACCT=y + CONFIG_TASK_IO_ACCOUNTING=y + CONFIG_IKCONFIG=m + CONFIG_IKCONFIG_PROC=y ++CONFIG_MEMCG=y ++CONFIG_BLK_CGROUP=y + CONFIG_CGROUP_FREEZER=y + CONFIG_CGROUP_DEVICE=y + CONFIG_CGROUP_CPUACCT=y +@@ -56,8 +58,10 @@ CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + CONFIG_MODVERSIONS=y + CONFIG_MODULE_SRCVERSION_ALL=y ++CONFIG_BLK_DEV_THROTTLING=y + CONFIG_PARTITION_ADVANCED=y + CONFIG_MAC_PARTITION=y ++CONFIG_CFQ_GROUP_IOSCHED=y + CONFIG_BINFMT_MISC=m + CONFIG_CLEANCACHE=y + CONFIG_FRONTSWAP=y +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -13,6 +13,8 @@ CONFIG_TASK_XACCT=y + CONFIG_TASK_IO_ACCOUNTING=y + CONFIG_IKCONFIG=m + CONFIG_IKCONFIG_PROC=y ++CONFIG_MEMCG=y ++CONFIG_BLK_CGROUP=y + CONFIG_CGROUP_FREEZER=y + CONFIG_CPUSETS=y + CONFIG_CGROUP_DEVICE=y +@@ -60,8 +62,10 @@ CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + CONFIG_MODVERSIONS=y + CONFIG_MODULE_SRCVERSION_ALL=y ++CONFIG_BLK_DEV_THROTTLING=y + CONFIG_PARTITION_ADVANCED=y + CONFIG_MAC_PARTITION=y ++CONFIG_CFQ_GROUP_IOSCHED=y + CONFIG_BINFMT_MISC=y + CONFIG_CLEANCACHE=y + CONFIG_FRONTSWAP=y diff --git a/target/linux/brcm2708/patches-4.19/950-0432-overlays-Add-PiGlow-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0432-overlays-Add-PiGlow-overlay.patch new file mode 100644 index 0000000000..18053af681 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0432-overlays-Add-PiGlow-overlay.patch @@ -0,0 +1,147 @@ +From 54882fd6678b052c68040caa38c70b2c3af0c958 Mon Sep 17 00:00:00 2001 +From: Stefan Wahren +Date: Mon, 29 Apr 2019 19:35:33 +0200 +Subject: [PATCH 432/725] overlays: Add PiGlow overlay + +The PiGlow is a small add-on board for the Raspberry Pi that provides +18 individually controllable LEDs (SN3218) and uses the following pins: + +P1 & P17 (3V3) +P2 (5V) +P3 (SDA) +P5 (SCL) +P14 (GND) + +Signed-off-by: Stefan Wahren +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 6 ++ + arch/arm/boot/dts/overlays/piglow-overlay.dts | 97 +++++++++++++++++++ + 3 files changed, 104 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/piglow-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -97,6 +97,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + pi3-disable-wifi.dtbo \ + pi3-miniuart-bt.dtbo \ + pibell.dtbo \ ++ piglow.dtbo \ + piscreen.dtbo \ + piscreen2r.dtbo \ + pisound.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1532,6 +1532,12 @@ Params: alsaname Set the + "PiBell") + + ++Name: piglow ++Info: Configures the PiGlow by pimoroni.com ++Load: dtoverlay=piglow ++Params: ++ ++ + Name: piscreen + Info: PiScreen display by OzzMaker.com + Load: dtoverlay=piscreen,= +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/piglow-overlay.dts +@@ -0,0 +1,97 @@ ++// Definitions for SN3218 LED driver from Si-En Technology on PiGlow ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&i2c_arm>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ sn3218@54 { ++ compatible = "si-en,sn3218"; ++ reg = <0x54>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ led@1 { ++ reg = <1>; ++ label = "piglow:red:led1"; ++ }; ++ led@2 { ++ reg = <2>; ++ label = "piglow:orange:led2"; ++ }; ++ led@3 { ++ reg = <3>; ++ label = "piglow:yellow:led3"; ++ }; ++ led@4 { ++ reg = <4>; ++ label = "piglow:green:led4"; ++ }; ++ led@5 { ++ reg = <5>; ++ label = "piglow:blue:led5"; ++ }; ++ led@6 { ++ reg = <6>; ++ label = "piglow:green:led6"; ++ }; ++ led@7 { ++ reg = <7>; ++ label = "piglow:red:led7"; ++ }; ++ led@8 { ++ reg = <8>; ++ label = "piglow:orange:led8"; ++ }; ++ led@9 { ++ reg = <9>; ++ label = "piglow:yellow:led9"; ++ }; ++ led@10 { ++ reg = <10>; ++ label = "piglow:white:led10"; ++ }; ++ led@11 { ++ reg = <11>; ++ label = "piglow:white:led11"; ++ }; ++ led@12 { ++ reg = <12>; ++ label = "piglow:blue:led12"; ++ }; ++ led@13 { ++ reg = <13>; ++ label = "piglow:white:led13"; ++ }; ++ led@14 { ++ reg = <14>; ++ label = "piglow:green:led14"; ++ }; ++ led@15 { ++ reg = <15>; ++ label = "piglow:blue:led15"; ++ }; ++ led@16 { ++ reg = <16>; ++ label = "piglow:yellow:led16"; ++ }; ++ led@17 { ++ reg = <17>; ++ label = "piglow:orange:led17"; ++ }; ++ led@18 { ++ reg = <18>; ++ label = "piglow:red:led18"; ++ }; ++ }; ++ }; ++ }; ++}; diff --git a/target/linux/brcm2708/patches-4.19/950-0432-sound-Fixes-for-audioinjector-octo-under-4.19.patch b/target/linux/brcm2708/patches-4.19/950-0432-sound-Fixes-for-audioinjector-octo-under-4.19.patch deleted file mode 100644 index b4cf231397..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0432-sound-Fixes-for-audioinjector-octo-under-4.19.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 7ed120d6a2733f70a5c8ee15844e1f02aec3f421 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 21 Mar 2019 11:19:46 +0000 -Subject: [PATCH 432/703] sound: Fixes for audioinjector-octo under 4.19 - -1. Move the DT alias declaration to the I2C shim in the cases -where the shim is enabled. This works around a problem caused by a -4.19 commit [1] that generates DT/OF uevents for I2C drivers. - -2. Fix the diagnostics in an error path of the soundcard driver to -correctly identify the reason for the failure to load. - -3. Move the declaration of the clock node in the overlay outside -the I2C node to avoid warnings. - -4. Sort the overlay nodes so that dependencies are only to earlier -fragments, in an attempt to get runtime dtoverlay application to -work (it still doesn't...) - -See: https://github.com/Audio-Injector/Octo/issues/14 -Signed-off-by: Phil Elwell - -[1] af503716ac14 ("i2c: core: report OF style module alias for devices registered via OF") ---- - .../overlays/audioinjector-addons-overlay.dts | 19 ++++++++++++------- - sound/soc/bcm/audioinjector-octo-soundcard.c | 2 +- - sound/soc/codecs/cs42xx8-i2c.c | 7 +++++++ - sound/soc/codecs/cs42xx8.c | 2 ++ - 4 files changed, 22 insertions(+), 8 deletions(-) - ---- a/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts -+++ b/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts -@@ -13,6 +13,17 @@ - }; - - fragment@1 { -+ target-path = "/"; -+ __overlay__ { -+ cs42448_mclk: codec-mclk { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <49152000>; -+ }; -+ }; -+ }; -+ -+ fragment@2 { - target = <&i2c1>; - __overlay__ { - #address-cells = <1>; -@@ -27,16 +38,10 @@ - clock-names = "mclk"; - status = "okay"; - }; -- -- cs42448_mclk: codec-mclk { -- compatible = "fixed-clock"; -- #clock-cells = <0>; -- clock-frequency = <49152000>; -- }; - }; - }; - -- fragment@2 { -+ fragment@3 { - target = <&sound>; - snd: __overlay__ { - compatible = "ai,audioinjector-octo-soundcard"; ---- a/sound/soc/bcm/audioinjector-octo-soundcard.c -+++ b/sound/soc/bcm/audioinjector-octo-soundcard.c -@@ -297,7 +297,7 @@ static int audioinjector_octo_probe(stru - dai->codec_name = NULL; - dai->codec_of_node = codec_node; - } else -- if (!dai->cpu_of_node) { -+ if (!i2s_node) { - dev_err(&pdev->dev, - "i2s-controller missing or invalid in DT\n"); - return -EINVAL; ---- a/sound/soc/codecs/cs42xx8-i2c.c -+++ b/sound/soc/codecs/cs42xx8-i2c.c -@@ -45,6 +45,13 @@ static struct i2c_device_id cs42xx8_i2c_ - }; - MODULE_DEVICE_TABLE(i2c, cs42xx8_i2c_id); - -+const struct of_device_id cs42xx8_of_match[] = { -+ { .compatible = "cirrus,cs42448", .data = &cs42448_data, }, -+ { .compatible = "cirrus,cs42888", .data = &cs42888_data, }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, cs42xx8_of_match); -+ - static struct i2c_driver cs42xx8_i2c_driver = { - .driver = { - .name = "cs42xx8", ---- a/sound/soc/codecs/cs42xx8.c -+++ b/sound/soc/codecs/cs42xx8.c -@@ -436,8 +436,10 @@ const struct of_device_id cs42xx8_of_mat - { .compatible = "cirrus,cs42888", .data = &cs42888_data, }, - { /* sentinel */ } - }; -+#if !IS_ENABLED(CONFIG_SND_SOC_CS42XX8_I2C) - MODULE_DEVICE_TABLE(of, cs42xx8_of_match); - EXPORT_SYMBOL_GPL(cs42xx8_of_match); -+#endif - - int cs42xx8_probe(struct device *dev, struct regmap *regmap) - { diff --git a/target/linux/brcm2708/patches-4.19/950-0433-Revert-cgroup-Disable-cgroup-memory-by-default.patch b/target/linux/brcm2708/patches-4.19/950-0433-Revert-cgroup-Disable-cgroup-memory-by-default.patch deleted file mode 100644 index efc145e1a6..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0433-Revert-cgroup-Disable-cgroup-memory-by-default.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 18c18a16cbf0007907319d5472351f6bc3e7135d Mon Sep 17 00:00:00 2001 -From: P33M -Date: Wed, 24 Apr 2019 14:25:09 +0100 -Subject: [PATCH 433/703] Revert "cgroup: Disable cgroup "memory" by default" - -This reverts commit cd6ce4d0ded13c94ff5208c679ed5e030263149b. ---- - kernel/cgroup/cgroup.c | 30 ------------------------------ - 1 file changed, 30 deletions(-) - ---- a/kernel/cgroup/cgroup.c -+++ b/kernel/cgroup/cgroup.c -@@ -5296,8 +5296,6 @@ int __init cgroup_init_early(void) - } - - static u16 cgroup_disable_mask __initdata; --static u16 cgroup_enable_mask __initdata; --static int __init cgroup_disable(char *str); - - /** - * cgroup_init - cgroup initialization -@@ -5338,12 +5336,6 @@ int __init cgroup_init(void) - - mutex_unlock(&cgroup_mutex); - -- /* Apply an implicit disable... */ -- cgroup_disable("memory"); -- -- /* ...knowing that an explicit enable will override it. */ -- cgroup_disable_mask &= ~cgroup_enable_mask; -- - for_each_subsys(ss, ssid) { - if (ss->early_init) { - struct cgroup_subsys_state *css = -@@ -5727,28 +5719,6 @@ static int __init cgroup_disable(char *s - } - __setup("cgroup_disable=", cgroup_disable); - --static int __init cgroup_enable(char *str) --{ -- struct cgroup_subsys *ss; -- char *token; -- int i; -- -- while ((token = strsep(&str, ",")) != NULL) { -- if (!*token) -- continue; -- -- for_each_subsys(ss, i) { -- if (strcmp(token, ss->name) && -- strcmp(token, ss->legacy_name)) -- continue; -- -- cgroup_enable_mask |= 1 << i; -- } -- } -- return 1; --} --__setup("cgroup_enable=", cgroup_enable); -- - /** - * css_tryget_online_from_dir - get corresponding css from a cgroup dentry - * @dentry: directory dentry of interest diff --git a/target/linux/brcm2708/patches-4.19/950-0433-configs-enable-LED-driver-for-PiGlow.patch b/target/linux/brcm2708/patches-4.19/950-0433-configs-enable-LED-driver-for-PiGlow.patch new file mode 100644 index 0000000000..727645fa78 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0433-configs-enable-LED-driver-for-PiGlow.patch @@ -0,0 +1,52 @@ +From d100cd5246ac51acdcfc4bec574e127ee61dcf99 Mon Sep 17 00:00:00 2001 +From: Stefan Wahren +Date: Mon, 29 Apr 2019 19:28:51 +0200 +Subject: [PATCH 433/725] configs: enable LED driver for PiGlow + +Signed-off-by: Stefan Wahren +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + arch/arm64/configs/bcmrpi3_defconfig | 3 ++- + 3 files changed, 4 insertions(+), 1 deletion(-) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -1131,6 +1131,7 @@ CONFIG_MMC_SPI=m + CONFIG_LEDS_CLASS=y + CONFIG_LEDS_GPIO=y + CONFIG_LEDS_PCA963X=m ++CONFIG_LEDS_IS31FL32XX=m + CONFIG_LEDS_TRIGGER_TIMER=y + CONFIG_LEDS_TRIGGER_ONESHOT=y + CONFIG_LEDS_TRIGGER_HEARTBEAT=y +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -1124,6 +1124,7 @@ CONFIG_MMC_SPI=m + CONFIG_LEDS_CLASS=y + CONFIG_LEDS_GPIO=y + CONFIG_LEDS_PCA963X=m ++CONFIG_LEDS_IS31FL32XX=m + CONFIG_LEDS_TRIGGER_TIMER=y + CONFIG_LEDS_TRIGGER_ONESHOT=y + CONFIG_LEDS_TRIGGER_HEARTBEAT=y +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -550,8 +550,8 @@ CONFIG_JOYSTICK_RPISENSE=m + CONFIG_INPUT_TOUCHSCREEN=y + CONFIG_TOUCHSCREEN_ADS7846=m + CONFIG_TOUCHSCREEN_EGALAX=m +-CONFIG_TOUCHSCREEN_EKTF2127=m + CONFIG_TOUCHSCREEN_ILI210X=m ++CONFIG_TOUCHSCREEN_EKTF2127=m + CONFIG_TOUCHSCREEN_RPI_FT5406=m + CONFIG_TOUCHSCREEN_USB_COMPOSITE=m + CONFIG_TOUCHSCREEN_STMPE=m +@@ -991,6 +991,7 @@ CONFIG_MMC_SPI=m + CONFIG_LEDS_CLASS=y + CONFIG_LEDS_GPIO=y + CONFIG_LEDS_PCA963X=m ++CONFIG_LEDS_IS31FL32XX=m + CONFIG_LEDS_TRIGGER_TIMER=y + CONFIG_LEDS_TRIGGER_ONESHOT=y + CONFIG_LEDS_TRIGGER_HEARTBEAT=y diff --git a/target/linux/brcm2708/patches-4.19/950-0434-Revert-bcm2835-interpolate-audio-delay.patch b/target/linux/brcm2708/patches-4.19/950-0434-Revert-bcm2835-interpolate-audio-delay.patch new file mode 100644 index 0000000000..bb6c2fe6e4 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0434-Revert-bcm2835-interpolate-audio-delay.patch @@ -0,0 +1,71 @@ +From 48f4f82875a8bc8fe399714114daee135592d963 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 29 Apr 2019 19:16:14 +0100 +Subject: [PATCH 434/725] Revert "bcm2835: interpolate audio delay" + +commit fb4b9f02986fcb5ae751106ef9b027806b5dd750 upstream. + +This reverts commit fb8cc99f05687ca5565dc53a7ee0dd86aefad952. +--- + .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 12 +----------- + .../staging/vc04_services/bcm2835-audio/bcm2835.h | 1 - + 2 files changed, 1 insertion(+), 12 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -11,7 +11,7 @@ + /* hardware definition */ + static const struct snd_pcm_hardware snd_bcm2835_playback_hw = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | +- SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BATCH), ++ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), + .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, + .rate_min = 8000, +@@ -81,8 +81,6 @@ void bcm2835_playback_fifo(struct bcm283 + alsa_stream->pos %= alsa_stream->buffer_size; + } + +- alsa_stream->interpolate_start = ktime_get_ns(); +- + if (alsa_stream->substream) { + if (new_period) + snd_pcm_period_elapsed(alsa_stream->substream); +@@ -308,7 +306,6 @@ static int snd_bcm2835_pcm_prepare(struc + alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream); + alsa_stream->period_size = snd_pcm_lib_period_bytes(substream); + alsa_stream->pos = 0; +- alsa_stream->interpolate_start = ktime_get_ns(); + + audio_debug("buffer_size=%d, period_size=%d pos=%d frame_bits=%d\n", + alsa_stream->buffer_size, alsa_stream->period_size, +@@ -400,19 +397,12 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_s + { + struct snd_pcm_runtime *runtime = substream->runtime; + struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; +- u64 now = ktime_get_ns(); + + audio_debug("pcm_pointer... (%d) hwptr=%d appl=%d pos=%d\n", 0, + frames_to_bytes(runtime, runtime->status->hw_ptr), + frames_to_bytes(runtime, runtime->control->appl_ptr), + alsa_stream->pos); + +- /* Give userspace better delay reporting by interpolating between GPU +- * notifications, assuming audio speed is close enough to the clock +- * used for ktime */ +- if (alsa_stream->interpolate_start && alsa_stream->interpolate_start < now) +- runtime->delay = -(int)div_u64((now - alsa_stream->interpolate_start) * runtime->rate, 1000000000); +- + return snd_pcm_indirect_playback_pointer(substream, + &alsa_stream->pcm_indirect, + alsa_stream->pos); +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h +@@ -133,7 +133,6 @@ struct bcm2835_alsa_stream { + unsigned int pos; + unsigned int buffer_size; + unsigned int period_size; +- u64 interpolate_start; + + atomic_t retrieved; + struct bcm2835_audio_instance *instance; diff --git a/target/linux/brcm2708/patches-4.19/950-0434-Revert-defconfigs-disable-memory-and-IO-cgroups-2908.patch b/target/linux/brcm2708/patches-4.19/950-0434-Revert-defconfigs-disable-memory-and-IO-cgroups-2908.patch deleted file mode 100644 index 746a5bc0c1..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0434-Revert-defconfigs-disable-memory-and-IO-cgroups-2908.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 76088decdde58c18a100c2fc7f15f9abbead6eef Mon Sep 17 00:00:00 2001 -From: P33M -Date: Wed, 24 Apr 2019 14:25:41 +0100 -Subject: [PATCH 434/703] Revert "defconfigs: disable memory and IO cgroups - (#2908)" - -This reverts commit 9881cdbf446081f71c62f39f4c56a21001baea73. ---- - arch/arm/configs/bcm2709_defconfig | 4 ++++ - arch/arm/configs/bcmrpi_defconfig | 4 ++++ - arch/arm64/configs/bcmrpi3_defconfig | 4 ++++ - 3 files changed, 12 insertions(+) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -14,6 +14,8 @@ CONFIG_TASK_XACCT=y - CONFIG_TASK_IO_ACCOUNTING=y - CONFIG_IKCONFIG=m - CONFIG_IKCONFIG_PROC=y -+CONFIG_MEMCG=y -+CONFIG_BLK_CGROUP=y - CONFIG_CGROUP_FREEZER=y - CONFIG_CPUSETS=y - CONFIG_CGROUP_DEVICE=y -@@ -62,8 +64,10 @@ CONFIG_MODULES=y - CONFIG_MODULE_UNLOAD=y - CONFIG_MODVERSIONS=y - CONFIG_MODULE_SRCVERSION_ALL=y -+CONFIG_BLK_DEV_THROTTLING=y - CONFIG_PARTITION_ADVANCED=y - CONFIG_MAC_PARTITION=y -+CONFIG_CFQ_GROUP_IOSCHED=y - CONFIG_BINFMT_MISC=m - CONFIG_CLEANCACHE=y - CONFIG_FRONTSWAP=y ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -13,6 +13,8 @@ CONFIG_TASK_XACCT=y - CONFIG_TASK_IO_ACCOUNTING=y - CONFIG_IKCONFIG=m - CONFIG_IKCONFIG_PROC=y -+CONFIG_MEMCG=y -+CONFIG_BLK_CGROUP=y - CONFIG_CGROUP_FREEZER=y - CONFIG_CGROUP_DEVICE=y - CONFIG_CGROUP_CPUACCT=y -@@ -56,8 +58,10 @@ CONFIG_MODULES=y - CONFIG_MODULE_UNLOAD=y - CONFIG_MODVERSIONS=y - CONFIG_MODULE_SRCVERSION_ALL=y -+CONFIG_BLK_DEV_THROTTLING=y - CONFIG_PARTITION_ADVANCED=y - CONFIG_MAC_PARTITION=y -+CONFIG_CFQ_GROUP_IOSCHED=y - CONFIG_BINFMT_MISC=m - CONFIG_CLEANCACHE=y - CONFIG_FRONTSWAP=y ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -13,6 +13,8 @@ CONFIG_TASK_XACCT=y - CONFIG_TASK_IO_ACCOUNTING=y - CONFIG_IKCONFIG=m - CONFIG_IKCONFIG_PROC=y -+CONFIG_MEMCG=y -+CONFIG_BLK_CGROUP=y - CONFIG_CGROUP_FREEZER=y - CONFIG_CPUSETS=y - CONFIG_CGROUP_DEVICE=y -@@ -60,8 +62,10 @@ CONFIG_MODULES=y - CONFIG_MODULE_UNLOAD=y - CONFIG_MODVERSIONS=y - CONFIG_MODULE_SRCVERSION_ALL=y -+CONFIG_BLK_DEV_THROTTLING=y - CONFIG_PARTITION_ADVANCED=y - CONFIG_MAC_PARTITION=y -+CONFIG_CFQ_GROUP_IOSCHED=y - CONFIG_BINFMT_MISC=y - CONFIG_CLEANCACHE=y - CONFIG_FRONTSWAP=y diff --git a/target/linux/brcm2708/patches-4.19/950-0435-Revert-staging-bcm2835-audio-Enable-compile-test.patch b/target/linux/brcm2708/patches-4.19/950-0435-Revert-staging-bcm2835-audio-Enable-compile-test.patch new file mode 100644 index 0000000000..a501aaf1bc --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0435-Revert-staging-bcm2835-audio-Enable-compile-test.patch @@ -0,0 +1,22 @@ +From 12c14e45b31f60c1fd591d4aebbfcd7c2b730e67 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 29 Apr 2019 19:16:15 +0100 +Subject: [PATCH 435/725] Revert "staging: bcm2835-audio: Enable compile test" + +commit 4eae66777a262ac9707980ea0cfe902afadfb577 upstream. + +This reverts commit 02d205a57c4c943fc2a5b1ac7c912ce01944f700. +--- + drivers/staging/vc04_services/bcm2835-audio/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/Kconfig ++++ b/drivers/staging/vc04_services/bcm2835-audio/Kconfig +@@ -1,6 +1,6 @@ + config SND_BCM2835 + tristate "BCM2835 Audio" +- depends on (ARCH_BCM2835 || COMPILE_TEST) && SND ++ depends on ARCH_BCM2835 && SND + select SND_PCM + select BCM2835_VCHIQ + help diff --git a/target/linux/brcm2708/patches-4.19/950-0435-overlays-Add-PiGlow-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0435-overlays-Add-PiGlow-overlay.patch deleted file mode 100644 index 323b6cd7cd..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0435-overlays-Add-PiGlow-overlay.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 1c61854d266759522f33e59fb58de1cb9470d886 Mon Sep 17 00:00:00 2001 -From: Stefan Wahren -Date: Mon, 29 Apr 2019 19:35:33 +0200 -Subject: [PATCH 435/703] overlays: Add PiGlow overlay - -The PiGlow is a small add-on board for the Raspberry Pi that provides -18 individually controllable LEDs (SN3218) and uses the following pins: - -P1 & P17 (3V3) -P2 (5V) -P3 (SDA) -P5 (SCL) -P14 (GND) - -Signed-off-by: Stefan Wahren ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 6 ++ - arch/arm/boot/dts/overlays/piglow-overlay.dts | 97 +++++++++++++++++++ - 3 files changed, 104 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/piglow-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -97,6 +97,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - pi3-disable-wifi.dtbo \ - pi3-miniuart-bt.dtbo \ - pibell.dtbo \ -+ piglow.dtbo \ - piscreen.dtbo \ - piscreen2r.dtbo \ - pisound.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1532,6 +1532,12 @@ Params: alsaname Set the - "PiBell") - - -+Name: piglow -+Info: Configures the PiGlow by pimoroni.com -+Load: dtoverlay=piglow -+Params: -+ -+ - Name: piscreen - Info: PiScreen display by OzzMaker.com - Load: dtoverlay=piscreen,= ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/piglow-overlay.dts -@@ -0,0 +1,97 @@ -+// Definitions for SN3218 LED driver from Si-En Technology on PiGlow -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c_arm>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ sn3218@54 { -+ compatible = "si-en,sn3218"; -+ reg = <0x54>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ led@1 { -+ reg = <1>; -+ label = "piglow:red:led1"; -+ }; -+ led@2 { -+ reg = <2>; -+ label = "piglow:orange:led2"; -+ }; -+ led@3 { -+ reg = <3>; -+ label = "piglow:yellow:led3"; -+ }; -+ led@4 { -+ reg = <4>; -+ label = "piglow:green:led4"; -+ }; -+ led@5 { -+ reg = <5>; -+ label = "piglow:blue:led5"; -+ }; -+ led@6 { -+ reg = <6>; -+ label = "piglow:green:led6"; -+ }; -+ led@7 { -+ reg = <7>; -+ label = "piglow:red:led7"; -+ }; -+ led@8 { -+ reg = <8>; -+ label = "piglow:orange:led8"; -+ }; -+ led@9 { -+ reg = <9>; -+ label = "piglow:yellow:led9"; -+ }; -+ led@10 { -+ reg = <10>; -+ label = "piglow:white:led10"; -+ }; -+ led@11 { -+ reg = <11>; -+ label = "piglow:white:led11"; -+ }; -+ led@12 { -+ reg = <12>; -+ label = "piglow:blue:led12"; -+ }; -+ led@13 { -+ reg = <13>; -+ label = "piglow:white:led13"; -+ }; -+ led@14 { -+ reg = <14>; -+ label = "piglow:green:led14"; -+ }; -+ led@15 { -+ reg = <15>; -+ label = "piglow:blue:led15"; -+ }; -+ led@16 { -+ reg = <16>; -+ label = "piglow:yellow:led16"; -+ }; -+ led@17 { -+ reg = <17>; -+ label = "piglow:orange:led17"; -+ }; -+ led@18 { -+ reg = <18>; -+ label = "piglow:red:led18"; -+ }; -+ }; -+ }; -+ }; -+}; diff --git a/target/linux/brcm2708/patches-4.19/950-0436-Revert-staging-bcm2835-audio-use-module_platform_dri.patch b/target/linux/brcm2708/patches-4.19/950-0436-Revert-staging-bcm2835-audio-use-module_platform_dri.patch new file mode 100644 index 0000000000..0baf5c3627 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0436-Revert-staging-bcm2835-audio-use-module_platform_dri.patch @@ -0,0 +1,42 @@ +From fc06fbe84cdcd35d8be8775576f07c52ccdf8cd2 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 29 Apr 2019 19:16:16 +0100 +Subject: [PATCH 436/725] Revert "staging: bcm2835-audio: use + module_platform_driver() macro" + +commit ed4c2e5dc4216d5dded502bfcf594d3984e6bccd upstream. + +This reverts commit 786ced30fec053b27248ed5b24dcde61ed3f47f6. +--- + .../vc04_services/bcm2835-audio/bcm2835.c | 20 ++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +@@ -470,7 +470,25 @@ static struct platform_driver bcm2835_al + .of_match_table = snd_bcm2835_of_match_table, + }, + }; +-module_platform_driver(bcm2835_alsa0_driver); ++ ++static int bcm2835_alsa_device_init(void) ++{ ++ int retval; ++ ++ retval = platform_driver_register(&bcm2835_alsa0_driver); ++ if (retval) ++ pr_err("Error registering bcm2835_audio driver %d .\n", retval); ++ ++ return retval; ++} ++ ++static void bcm2835_alsa_device_exit(void) ++{ ++ platform_driver_unregister(&bcm2835_alsa0_driver); ++} ++ ++late_initcall(bcm2835_alsa_device_init); ++module_exit(bcm2835_alsa_device_exit); + + MODULE_AUTHOR("Dom Cobley"); + MODULE_DESCRIPTION("Alsa driver for BCM2835 chip"); diff --git a/target/linux/brcm2708/patches-4.19/950-0436-configs-enable-LED-driver-for-PiGlow.patch b/target/linux/brcm2708/patches-4.19/950-0436-configs-enable-LED-driver-for-PiGlow.patch deleted file mode 100644 index 0bde83669e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0436-configs-enable-LED-driver-for-PiGlow.patch +++ /dev/null @@ -1,52 +0,0 @@ -From bf7d2a13c0617dd23e0a394bccd9b41b2295ead0 Mon Sep 17 00:00:00 2001 -From: Stefan Wahren -Date: Mon, 29 Apr 2019 19:28:51 +0200 -Subject: [PATCH 436/703] configs: enable LED driver for PiGlow - -Signed-off-by: Stefan Wahren ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - arch/arm64/configs/bcmrpi3_defconfig | 3 ++- - 3 files changed, 4 insertions(+), 1 deletion(-) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1131,6 +1131,7 @@ CONFIG_MMC_SPI=m - CONFIG_LEDS_CLASS=y - CONFIG_LEDS_GPIO=y - CONFIG_LEDS_PCA963X=m -+CONFIG_LEDS_IS31FL32XX=m - CONFIG_LEDS_TRIGGER_TIMER=y - CONFIG_LEDS_TRIGGER_ONESHOT=y - CONFIG_LEDS_TRIGGER_HEARTBEAT=y ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1124,6 +1124,7 @@ CONFIG_MMC_SPI=m - CONFIG_LEDS_CLASS=y - CONFIG_LEDS_GPIO=y - CONFIG_LEDS_PCA963X=m -+CONFIG_LEDS_IS31FL32XX=m - CONFIG_LEDS_TRIGGER_TIMER=y - CONFIG_LEDS_TRIGGER_ONESHOT=y - CONFIG_LEDS_TRIGGER_HEARTBEAT=y ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -550,8 +550,8 @@ CONFIG_JOYSTICK_RPISENSE=m - CONFIG_INPUT_TOUCHSCREEN=y - CONFIG_TOUCHSCREEN_ADS7846=m - CONFIG_TOUCHSCREEN_EGALAX=m --CONFIG_TOUCHSCREEN_EKTF2127=m - CONFIG_TOUCHSCREEN_ILI210X=m -+CONFIG_TOUCHSCREEN_EKTF2127=m - CONFIG_TOUCHSCREEN_RPI_FT5406=m - CONFIG_TOUCHSCREEN_USB_COMPOSITE=m - CONFIG_TOUCHSCREEN_STMPE=m -@@ -991,6 +991,7 @@ CONFIG_MMC_SPI=m - CONFIG_LEDS_CLASS=y - CONFIG_LEDS_GPIO=y - CONFIG_LEDS_PCA963X=m -+CONFIG_LEDS_IS31FL32XX=m - CONFIG_LEDS_TRIGGER_TIMER=y - CONFIG_LEDS_TRIGGER_ONESHOT=y - CONFIG_LEDS_TRIGGER_HEARTBEAT=y diff --git a/target/linux/brcm2708/patches-4.19/950-0437-Revert-bcm2835-interpolate-audio-delay.patch b/target/linux/brcm2708/patches-4.19/950-0437-Revert-bcm2835-interpolate-audio-delay.patch deleted file mode 100644 index a8693c5232..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0437-Revert-bcm2835-interpolate-audio-delay.patch +++ /dev/null @@ -1,71 +0,0 @@ -From fe6afd9a110a042d2f00934b3a95ae57471f18cf Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 29 Apr 2019 19:16:14 +0100 -Subject: [PATCH 437/703] Revert "bcm2835: interpolate audio delay" - -commit fb4b9f02986fcb5ae751106ef9b027806b5dd750 upstream. - -This reverts commit fb8cc99f05687ca5565dc53a7ee0dd86aefad952. ---- - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 12 +----------- - .../staging/vc04_services/bcm2835-audio/bcm2835.h | 1 - - 2 files changed, 1 insertion(+), 12 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -11,7 +11,7 @@ - /* hardware definition */ - static const struct snd_pcm_hardware snd_bcm2835_playback_hw = { - .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | -- SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BATCH), -+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), - .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, - .rate_min = 8000, -@@ -81,8 +81,6 @@ void bcm2835_playback_fifo(struct bcm283 - alsa_stream->pos %= alsa_stream->buffer_size; - } - -- alsa_stream->interpolate_start = ktime_get_ns(); -- - if (alsa_stream->substream) { - if (new_period) - snd_pcm_period_elapsed(alsa_stream->substream); -@@ -308,7 +306,6 @@ static int snd_bcm2835_pcm_prepare(struc - alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream); - alsa_stream->period_size = snd_pcm_lib_period_bytes(substream); - alsa_stream->pos = 0; -- alsa_stream->interpolate_start = ktime_get_ns(); - - audio_debug("buffer_size=%d, period_size=%d pos=%d frame_bits=%d\n", - alsa_stream->buffer_size, alsa_stream->period_size, -@@ -400,19 +397,12 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_s - { - struct snd_pcm_runtime *runtime = substream->runtime; - struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; -- u64 now = ktime_get_ns(); - - audio_debug("pcm_pointer... (%d) hwptr=%d appl=%d pos=%d\n", 0, - frames_to_bytes(runtime, runtime->status->hw_ptr), - frames_to_bytes(runtime, runtime->control->appl_ptr), - alsa_stream->pos); - -- /* Give userspace better delay reporting by interpolating between GPU -- * notifications, assuming audio speed is close enough to the clock -- * used for ktime */ -- if (alsa_stream->interpolate_start && alsa_stream->interpolate_start < now) -- runtime->delay = -(int)div_u64((now - alsa_stream->interpolate_start) * runtime->rate, 1000000000); -- - return snd_pcm_indirect_playback_pointer(substream, - &alsa_stream->pcm_indirect, - alsa_stream->pos); ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -@@ -133,7 +133,6 @@ struct bcm2835_alsa_stream { - unsigned int pos; - unsigned int buffer_size; - unsigned int period_size; -- u64 interpolate_start; - - atomic_t retrieved; - struct bcm2835_audio_instance *instance; diff --git a/target/linux/brcm2708/patches-4.19/950-0437-staging-bcm2835-audio-Clean-up-mutex-locks.patch b/target/linux/brcm2708/patches-4.19/950-0437-staging-bcm2835-audio-Clean-up-mutex-locks.patch new file mode 100644 index 0000000000..dfa0573510 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0437-staging-bcm2835-audio-Clean-up-mutex-locks.patch @@ -0,0 +1,301 @@ +From 2dc2366eddba3b7a59d1f19b7ce13f7a52574d63 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:30 +0200 +Subject: [PATCH 437/725] staging: bcm2835-audio: Clean up mutex locks + +commit ce4bb1aa271a97047b80ac917a5d91b54925913b upstream. + +snd-bcm2835 driver takes the lock with mutex_lock_interruptible() in +all places, which don't make sense. Replace them with the simple +mutex_lock(). + +Also taking a mutex lock right after creating it for each PCM object +is nonsense, too. It cannot be racy at that point. We can get rid of +it. + +Last but not least, initializing chip->audio_mutex at each place is +error-prone. Initialize properly at creating the chip object in +snd_bcm2835_create() instead. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-ctl.c | 18 +++---- + .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 33 ++----------- + .../bcm2835-audio/bcm2835-vchiq.c | 47 ++++--------------- + .../vc04_services/bcm2835-audio/bcm2835.c | 1 + + 4 files changed, 20 insertions(+), 79 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c +@@ -77,8 +77,7 @@ static int snd_bcm2835_ctl_get(struct sn + { + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); + +- if (mutex_lock_interruptible(&chip->audio_mutex)) +- return -EINTR; ++ mutex_lock(&chip->audio_mutex); + + BUG_ON(!chip && !(chip->avail_substreams & AVAIL_SUBSTREAMS_MASK)); + +@@ -99,8 +98,7 @@ static int snd_bcm2835_ctl_put(struct sn + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); + int changed = 0; + +- if (mutex_lock_interruptible(&chip->audio_mutex)) +- return -EINTR; ++ mutex_lock(&chip->audio_mutex); + + if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) { + audio_info("Volume change attempted.. volume = %d new_volume = %d\n", chip->volume, (int)ucontrol->value.integer.value[0]); +@@ -187,8 +185,7 @@ static int snd_bcm2835_spdif_default_get + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); + int i; + +- if (mutex_lock_interruptible(&chip->audio_mutex)) +- return -EINTR; ++ mutex_lock(&chip->audio_mutex); + + for (i = 0; i < 4; i++) + ucontrol->value.iec958.status[i] = +@@ -205,8 +202,7 @@ static int snd_bcm2835_spdif_default_put + unsigned int val = 0; + int i, change; + +- if (mutex_lock_interruptible(&chip->audio_mutex)) +- return -EINTR; ++ mutex_lock(&chip->audio_mutex); + + for (i = 0; i < 4; i++) + val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8); +@@ -251,8 +247,7 @@ static int snd_bcm2835_spdif_stream_get( + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); + int i; + +- if (mutex_lock_interruptible(&chip->audio_mutex)) +- return -EINTR; ++ mutex_lock(&chip->audio_mutex); + + for (i = 0; i < 4; i++) + ucontrol->value.iec958.status[i] = +@@ -269,8 +264,7 @@ static int snd_bcm2835_spdif_stream_put( + unsigned int val = 0; + int i, change; + +- if (mutex_lock_interruptible(&chip->audio_mutex)) +- return -EINTR; ++ mutex_lock(&chip->audio_mutex); + + for (i = 0; i < 4; i++) + val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8); +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -99,10 +99,7 @@ static int snd_bcm2835_playback_open_gen + int idx; + int err; + +- if (mutex_lock_interruptible(&chip->audio_mutex)) { +- audio_error("Interrupted whilst waiting for lock\n"); +- return -EINTR; +- } ++ mutex_lock(&chip->audio_mutex); + audio_info("Alsa open (%d)\n", substream->number); + idx = substream->number; + +@@ -194,10 +191,7 @@ static int snd_bcm2835_playback_close(st + struct bcm2835_alsa_stream *alsa_stream; + + chip = snd_pcm_substream_chip(substream); +- if (mutex_lock_interruptible(&chip->audio_mutex)) { +- audio_error("Interrupted whilst waiting for lock\n"); +- return -EINTR; +- } ++ mutex_lock(&chip->audio_mutex); + runtime = substream->runtime; + alsa_stream = runtime->private_data; + +@@ -274,8 +268,7 @@ static int snd_bcm2835_pcm_prepare(struc + int channels; + int err; + +- if (mutex_lock_interruptible(&chip->audio_mutex)) +- return -EINTR; ++ mutex_lock(&chip->audio_mutex); + + /* notify the vchiq that it should enter spdif passthrough mode by + * setting channels=0 (see +@@ -449,14 +442,9 @@ int snd_bcm2835_new_pcm(struct bcm2835_c + struct snd_pcm *pcm; + int err; + +- mutex_init(&chip->audio_mutex); +- if (mutex_lock_interruptible(&chip->audio_mutex)) { +- audio_error("Interrupted whilst waiting for lock\n"); +- return -EINTR; +- } + err = snd_pcm_new(chip->card, "bcm2835 ALSA", 0, numchannels, 0, &pcm); + if (err < 0) +- goto out; ++ return err; + pcm->private_data = chip; + strcpy(pcm->name, "bcm2835 ALSA"); + chip->pcm = pcm; +@@ -474,9 +462,6 @@ int snd_bcm2835_new_pcm(struct bcm2835_c + snd_bcm2835_playback_hw.buffer_bytes_max, + snd_bcm2835_playback_hw.buffer_bytes_max); + +-out: +- mutex_unlock(&chip->audio_mutex); +- + return 0; + } + +@@ -485,13 +470,9 @@ int snd_bcm2835_new_spdif_pcm(struct bcm + struct snd_pcm *pcm; + int err; + +- if (mutex_lock_interruptible(&chip->audio_mutex)) { +- audio_error("Interrupted whilst waiting for lock\n"); +- return -EINTR; +- } + err = snd_pcm_new(chip->card, "bcm2835 ALSA", 1, 1, 0, &pcm); + if (err < 0) +- goto out; ++ return err; + + pcm->private_data = chip; + strcpy(pcm->name, "bcm2835 IEC958/HDMI"); +@@ -504,8 +485,6 @@ int snd_bcm2835_new_spdif_pcm(struct bcm + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, + snd_dma_continuous_data(GFP_KERNEL), + snd_bcm2835_playback_spdif_hw.buffer_bytes_max, snd_bcm2835_playback_spdif_hw.buffer_bytes_max); +-out: +- mutex_unlock(&chip->audio_mutex); + + return 0; + } +@@ -518,8 +497,6 @@ int snd_bcm2835_new_simple_pcm(struct bc + struct snd_pcm *pcm; + int err; + +- mutex_init(&chip->audio_mutex); +- + err = snd_pcm_new(chip->card, name, 0, numchannels, + 0, &pcm); + if (err) +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +@@ -319,11 +319,7 @@ static int vc_vchi_audio_deinit(struct b + } + + LOG_DBG(" .. about to lock (%d)\n", instance->num_connections); +- if (mutex_lock_interruptible(&instance->vchi_mutex)) { +- LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", +- instance->num_connections); +- return -EINTR; +- } ++ mutex_lock(&instance->vchi_mutex); + + /* Close all VCHI service connections */ + for (i = 0; i < instance->num_connections; i++) { +@@ -434,11 +430,7 @@ int bcm2835_audio_open(struct bcm2835_al + instance = alsa_stream->instance; + LOG_DBG(" instance (%p)\n", instance); + +- if (mutex_lock_interruptible(&instance->vchi_mutex)) { +- LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", instance->num_connections); +- ret = -EINTR; +- goto free_wq; +- } ++ mutex_lock(&instance->vchi_mutex); + vchi_service_use(instance->vchi_handle[0]); + + m.type = VC_AUDIO_MSG_TYPE_OPEN; +@@ -479,11 +471,7 @@ static int bcm2835_audio_set_ctls_chan(s + LOG_INFO(" Setting ALSA dest(%d), volume(%d)\n", + chip->dest, chip->volume); + +- if (mutex_lock_interruptible(&instance->vchi_mutex)) { +- LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", +- instance->num_connections); +- return -EINTR; +- } ++ mutex_lock(&instance->vchi_mutex); + vchi_service_use(instance->vchi_handle[0]); + + instance->result = -1; +@@ -569,10 +557,7 @@ int bcm2835_audio_set_params(struct bcm2 + return -EINVAL; + } + +- if (mutex_lock_interruptible(&instance->vchi_mutex)) { +- LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", instance->num_connections); +- return -EINTR; +- } ++ mutex_lock(&instance->vchi_mutex); + vchi_service_use(instance->vchi_handle[0]); + + instance->result = -1; +@@ -629,11 +614,7 @@ static int bcm2835_audio_start_worker(st + int status; + int ret; + +- if (mutex_lock_interruptible(&instance->vchi_mutex)) { +- LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", +- instance->num_connections); +- return -EINTR; +- } ++ mutex_lock(&instance->vchi_mutex); + vchi_service_use(instance->vchi_handle[0]); + + m.type = VC_AUDIO_MSG_TYPE_START; +@@ -665,11 +646,7 @@ static int bcm2835_audio_stop_worker(str + int status; + int ret; + +- if (mutex_lock_interruptible(&instance->vchi_mutex)) { +- LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", +- instance->num_connections); +- return -EINTR; +- } ++ mutex_lock(&instance->vchi_mutex); + vchi_service_use(instance->vchi_handle[0]); + + m.type = VC_AUDIO_MSG_TYPE_STOP; +@@ -704,11 +681,7 @@ int bcm2835_audio_close(struct bcm2835_a + + my_workqueue_quit(alsa_stream); + +- if (mutex_lock_interruptible(&instance->vchi_mutex)) { +- LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", +- instance->num_connections); +- return -EINTR; +- } ++ mutex_lock(&instance->vchi_mutex); + vchi_service_use(instance->vchi_handle[0]); + + m.type = VC_AUDIO_MSG_TYPE_CLOSE; +@@ -761,11 +734,7 @@ static int bcm2835_audio_write_worker(st + + LOG_INFO(" Writing %d bytes from %p\n", count, src); + +- if (mutex_lock_interruptible(&instance->vchi_mutex)) { +- LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", +- instance->num_connections); +- return -EINTR; +- } ++ mutex_lock(&instance->vchi_mutex); + vchi_service_use(instance->vchi_handle[0]); + + if (instance->peer_version == 0 && +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +@@ -149,6 +149,7 @@ static int snd_bcm2835_create(struct snd + return -ENOMEM; + + chip->card = card; ++ mutex_init(&chip->audio_mutex); + + chip->vchi_ctx = devres_find(card->dev->parent, + bcm2835_devm_free_vchi_ctx, NULL, NULL); diff --git a/target/linux/brcm2708/patches-4.19/950-0438-Revert-staging-bcm2835-audio-Enable-compile-test.patch b/target/linux/brcm2708/patches-4.19/950-0438-Revert-staging-bcm2835-audio-Enable-compile-test.patch deleted file mode 100644 index 671bd39a7d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0438-Revert-staging-bcm2835-audio-Enable-compile-test.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 5776c86dca6b3bc3c96d28514b1c5b398c7c6b8f Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 29 Apr 2019 19:16:15 +0100 -Subject: [PATCH 438/703] Revert "staging: bcm2835-audio: Enable compile test" - -commit 4eae66777a262ac9707980ea0cfe902afadfb577 upstream. - -This reverts commit 02d205a57c4c943fc2a5b1ac7c912ce01944f700. ---- - drivers/staging/vc04_services/bcm2835-audio/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/Kconfig -+++ b/drivers/staging/vc04_services/bcm2835-audio/Kconfig -@@ -1,6 +1,6 @@ - config SND_BCM2835 - tristate "BCM2835 Audio" -- depends on (ARCH_BCM2835 || COMPILE_TEST) && SND -+ depends on ARCH_BCM2835 && SND - select SND_PCM - select BCM2835_VCHIQ - help diff --git a/target/linux/brcm2708/patches-4.19/950-0438-staging-bcm2835-audio-Remove-redundant-spdif-stream-.patch b/target/linux/brcm2708/patches-4.19/950-0438-staging-bcm2835-audio-Remove-redundant-spdif-stream-.patch new file mode 100644 index 0000000000..7e73c33c28 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0438-staging-bcm2835-audio-Remove-redundant-spdif-stream-.patch @@ -0,0 +1,89 @@ +From b44bb742007c7ef0b6507a3573dfca716192c200 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:31 +0200 +Subject: [PATCH 438/725] staging: bcm2835-audio: Remove redundant spdif stream + ctls + +commit ab91e26229eaca2832df51e13c1285aea3be33ab upstream. + +The "IEC958 Playback Stream" control does basically the very same +thing as "IEC958 Playback Default" redundantly. The former should +have been stream-specific and restored after closing the stream, but +we don't do in that way. + +Since it's nothing but confusion, remove this fake. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-ctl.c | 51 ------------------- + 1 file changed, 51 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c +@@ -233,48 +233,6 @@ static int snd_bcm2835_spdif_mask_get(st + return 0; + } + +-static int snd_bcm2835_spdif_stream_info(struct snd_kcontrol *kcontrol, +- struct snd_ctl_elem_info *uinfo) +-{ +- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; +- uinfo->count = 1; +- return 0; +-} +- +-static int snd_bcm2835_spdif_stream_get(struct snd_kcontrol *kcontrol, +- struct snd_ctl_elem_value *ucontrol) +-{ +- struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); +- int i; +- +- mutex_lock(&chip->audio_mutex); +- +- for (i = 0; i < 4; i++) +- ucontrol->value.iec958.status[i] = +- (chip->spdif_status >> (i * 8)) & 0xff; +- +- mutex_unlock(&chip->audio_mutex); +- return 0; +-} +- +-static int snd_bcm2835_spdif_stream_put(struct snd_kcontrol *kcontrol, +- struct snd_ctl_elem_value *ucontrol) +-{ +- struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); +- unsigned int val = 0; +- int i, change; +- +- mutex_lock(&chip->audio_mutex); +- +- for (i = 0; i < 4; i++) +- val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8); +- change = val != chip->spdif_status; +- chip->spdif_status = val; +- +- mutex_unlock(&chip->audio_mutex); +- return change; +-} +- + static struct snd_kcontrol_new snd_bcm2835_spdif[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, +@@ -290,15 +248,6 @@ static struct snd_kcontrol_new snd_bcm28 + .info = snd_bcm2835_spdif_mask_info, + .get = snd_bcm2835_spdif_mask_get, + }, +- { +- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | +- SNDRV_CTL_ELEM_ACCESS_INACTIVE, +- .iface = SNDRV_CTL_ELEM_IFACE_PCM, +- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM), +- .info = snd_bcm2835_spdif_stream_info, +- .get = snd_bcm2835_spdif_stream_get, +- .put = snd_bcm2835_spdif_stream_put, +- }, + }; + + int snd_bcm2835_new_ctl(struct bcm2835_chip *chip) diff --git a/target/linux/brcm2708/patches-4.19/950-0439-Revert-staging-bcm2835-audio-use-module_platform_dri.patch b/target/linux/brcm2708/patches-4.19/950-0439-Revert-staging-bcm2835-audio-use-module_platform_dri.patch deleted file mode 100644 index 5ce5a24f9d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0439-Revert-staging-bcm2835-audio-use-module_platform_dri.patch +++ /dev/null @@ -1,42 +0,0 @@ -From f1137241f30689ffe38dd414c73f0b17bf08ecc8 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 29 Apr 2019 19:16:16 +0100 -Subject: [PATCH 439/703] Revert "staging: bcm2835-audio: use - module_platform_driver() macro" - -commit ed4c2e5dc4216d5dded502bfcf594d3984e6bccd upstream. - -This reverts commit 786ced30fec053b27248ed5b24dcde61ed3f47f6. ---- - .../vc04_services/bcm2835-audio/bcm2835.c | 20 ++++++++++++++++++- - 1 file changed, 19 insertions(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -470,7 +470,25 @@ static struct platform_driver bcm2835_al - .of_match_table = snd_bcm2835_of_match_table, - }, - }; --module_platform_driver(bcm2835_alsa0_driver); -+ -+static int bcm2835_alsa_device_init(void) -+{ -+ int retval; -+ -+ retval = platform_driver_register(&bcm2835_alsa0_driver); -+ if (retval) -+ pr_err("Error registering bcm2835_audio driver %d .\n", retval); -+ -+ return retval; -+} -+ -+static void bcm2835_alsa_device_exit(void) -+{ -+ platform_driver_unregister(&bcm2835_alsa0_driver); -+} -+ -+late_initcall(bcm2835_alsa_device_init); -+module_exit(bcm2835_alsa_device_exit); - - MODULE_AUTHOR("Dom Cobley"); - MODULE_DESCRIPTION("Alsa driver for BCM2835 chip"); diff --git a/target/linux/brcm2708/patches-4.19/950-0439-staging-bcm2835-audio-Clean-up-include-files-in-bcm2.patch b/target/linux/brcm2708/patches-4.19/950-0439-staging-bcm2835-audio-Clean-up-include-files-in-bcm2.patch new file mode 100644 index 0000000000..3be40959b8 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0439-staging-bcm2835-audio-Clean-up-include-files-in-bcm2.patch @@ -0,0 +1,43 @@ +From 62a36a18cad14a7a262c8e5f4bbce3db01aa35e1 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:32 +0200 +Subject: [PATCH 439/725] staging: bcm2835-audio: Clean up include files in + bcm2835-ctl.c + +commit 821950d3da4bf97bcfedcb812176a0f26b833db0 upstream. + +Only a few of them are really needed. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-ctl.c | 15 --------------- + 1 file changed, 15 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c +@@ -1,23 +1,8 @@ + // SPDX-License-Identifier: GPL-2.0 + /* Copyright 2011 Broadcom Corporation. All rights reserved. */ + +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- + #include + #include +-#include +-#include +-#include +-#include + #include + #include + diff --git a/target/linux/brcm2708/patches-4.19/950-0440-staging-bcm2835-audio-Clean-up-mutex-locks.patch b/target/linux/brcm2708/patches-4.19/950-0440-staging-bcm2835-audio-Clean-up-mutex-locks.patch deleted file mode 100644 index 941c40207b..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0440-staging-bcm2835-audio-Clean-up-mutex-locks.patch +++ /dev/null @@ -1,301 +0,0 @@ -From 8fa93d6fee921789b90a1b3be272366df36e026e Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:30 +0200 -Subject: [PATCH 440/703] staging: bcm2835-audio: Clean up mutex locks - -commit ce4bb1aa271a97047b80ac917a5d91b54925913b upstream. - -snd-bcm2835 driver takes the lock with mutex_lock_interruptible() in -all places, which don't make sense. Replace them with the simple -mutex_lock(). - -Also taking a mutex lock right after creating it for each PCM object -is nonsense, too. It cannot be racy at that point. We can get rid of -it. - -Last but not least, initializing chip->audio_mutex at each place is -error-prone. Initialize properly at creating the chip object in -snd_bcm2835_create() instead. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-ctl.c | 18 +++---- - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 33 ++----------- - .../bcm2835-audio/bcm2835-vchiq.c | 47 ++++--------------- - .../vc04_services/bcm2835-audio/bcm2835.c | 1 + - 4 files changed, 20 insertions(+), 79 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c -@@ -77,8 +77,7 @@ static int snd_bcm2835_ctl_get(struct sn - { - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); - -- if (mutex_lock_interruptible(&chip->audio_mutex)) -- return -EINTR; -+ mutex_lock(&chip->audio_mutex); - - BUG_ON(!chip && !(chip->avail_substreams & AVAIL_SUBSTREAMS_MASK)); - -@@ -99,8 +98,7 @@ static int snd_bcm2835_ctl_put(struct sn - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); - int changed = 0; - -- if (mutex_lock_interruptible(&chip->audio_mutex)) -- return -EINTR; -+ mutex_lock(&chip->audio_mutex); - - if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) { - audio_info("Volume change attempted.. volume = %d new_volume = %d\n", chip->volume, (int)ucontrol->value.integer.value[0]); -@@ -187,8 +185,7 @@ static int snd_bcm2835_spdif_default_get - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); - int i; - -- if (mutex_lock_interruptible(&chip->audio_mutex)) -- return -EINTR; -+ mutex_lock(&chip->audio_mutex); - - for (i = 0; i < 4; i++) - ucontrol->value.iec958.status[i] = -@@ -205,8 +202,7 @@ static int snd_bcm2835_spdif_default_put - unsigned int val = 0; - int i, change; - -- if (mutex_lock_interruptible(&chip->audio_mutex)) -- return -EINTR; -+ mutex_lock(&chip->audio_mutex); - - for (i = 0; i < 4; i++) - val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8); -@@ -251,8 +247,7 @@ static int snd_bcm2835_spdif_stream_get( - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); - int i; - -- if (mutex_lock_interruptible(&chip->audio_mutex)) -- return -EINTR; -+ mutex_lock(&chip->audio_mutex); - - for (i = 0; i < 4; i++) - ucontrol->value.iec958.status[i] = -@@ -269,8 +264,7 @@ static int snd_bcm2835_spdif_stream_put( - unsigned int val = 0; - int i, change; - -- if (mutex_lock_interruptible(&chip->audio_mutex)) -- return -EINTR; -+ mutex_lock(&chip->audio_mutex); - - for (i = 0; i < 4; i++) - val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8); ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -99,10 +99,7 @@ static int snd_bcm2835_playback_open_gen - int idx; - int err; - -- if (mutex_lock_interruptible(&chip->audio_mutex)) { -- audio_error("Interrupted whilst waiting for lock\n"); -- return -EINTR; -- } -+ mutex_lock(&chip->audio_mutex); - audio_info("Alsa open (%d)\n", substream->number); - idx = substream->number; - -@@ -194,10 +191,7 @@ static int snd_bcm2835_playback_close(st - struct bcm2835_alsa_stream *alsa_stream; - - chip = snd_pcm_substream_chip(substream); -- if (mutex_lock_interruptible(&chip->audio_mutex)) { -- audio_error("Interrupted whilst waiting for lock\n"); -- return -EINTR; -- } -+ mutex_lock(&chip->audio_mutex); - runtime = substream->runtime; - alsa_stream = runtime->private_data; - -@@ -274,8 +268,7 @@ static int snd_bcm2835_pcm_prepare(struc - int channels; - int err; - -- if (mutex_lock_interruptible(&chip->audio_mutex)) -- return -EINTR; -+ mutex_lock(&chip->audio_mutex); - - /* notify the vchiq that it should enter spdif passthrough mode by - * setting channels=0 (see -@@ -449,14 +442,9 @@ int snd_bcm2835_new_pcm(struct bcm2835_c - struct snd_pcm *pcm; - int err; - -- mutex_init(&chip->audio_mutex); -- if (mutex_lock_interruptible(&chip->audio_mutex)) { -- audio_error("Interrupted whilst waiting for lock\n"); -- return -EINTR; -- } - err = snd_pcm_new(chip->card, "bcm2835 ALSA", 0, numchannels, 0, &pcm); - if (err < 0) -- goto out; -+ return err; - pcm->private_data = chip; - strcpy(pcm->name, "bcm2835 ALSA"); - chip->pcm = pcm; -@@ -474,9 +462,6 @@ int snd_bcm2835_new_pcm(struct bcm2835_c - snd_bcm2835_playback_hw.buffer_bytes_max, - snd_bcm2835_playback_hw.buffer_bytes_max); - --out: -- mutex_unlock(&chip->audio_mutex); -- - return 0; - } - -@@ -485,13 +470,9 @@ int snd_bcm2835_new_spdif_pcm(struct bcm - struct snd_pcm *pcm; - int err; - -- if (mutex_lock_interruptible(&chip->audio_mutex)) { -- audio_error("Interrupted whilst waiting for lock\n"); -- return -EINTR; -- } - err = snd_pcm_new(chip->card, "bcm2835 ALSA", 1, 1, 0, &pcm); - if (err < 0) -- goto out; -+ return err; - - pcm->private_data = chip; - strcpy(pcm->name, "bcm2835 IEC958/HDMI"); -@@ -504,8 +485,6 @@ int snd_bcm2835_new_spdif_pcm(struct bcm - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, - snd_dma_continuous_data(GFP_KERNEL), - snd_bcm2835_playback_spdif_hw.buffer_bytes_max, snd_bcm2835_playback_spdif_hw.buffer_bytes_max); --out: -- mutex_unlock(&chip->audio_mutex); - - return 0; - } -@@ -518,8 +497,6 @@ int snd_bcm2835_new_simple_pcm(struct bc - struct snd_pcm *pcm; - int err; - -- mutex_init(&chip->audio_mutex); -- - err = snd_pcm_new(chip->card, name, 0, numchannels, - 0, &pcm); - if (err) ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -@@ -319,11 +319,7 @@ static int vc_vchi_audio_deinit(struct b - } - - LOG_DBG(" .. about to lock (%d)\n", instance->num_connections); -- if (mutex_lock_interruptible(&instance->vchi_mutex)) { -- LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", -- instance->num_connections); -- return -EINTR; -- } -+ mutex_lock(&instance->vchi_mutex); - - /* Close all VCHI service connections */ - for (i = 0; i < instance->num_connections; i++) { -@@ -434,11 +430,7 @@ int bcm2835_audio_open(struct bcm2835_al - instance = alsa_stream->instance; - LOG_DBG(" instance (%p)\n", instance); - -- if (mutex_lock_interruptible(&instance->vchi_mutex)) { -- LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", instance->num_connections); -- ret = -EINTR; -- goto free_wq; -- } -+ mutex_lock(&instance->vchi_mutex); - vchi_service_use(instance->vchi_handle[0]); - - m.type = VC_AUDIO_MSG_TYPE_OPEN; -@@ -479,11 +471,7 @@ static int bcm2835_audio_set_ctls_chan(s - LOG_INFO(" Setting ALSA dest(%d), volume(%d)\n", - chip->dest, chip->volume); - -- if (mutex_lock_interruptible(&instance->vchi_mutex)) { -- LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", -- instance->num_connections); -- return -EINTR; -- } -+ mutex_lock(&instance->vchi_mutex); - vchi_service_use(instance->vchi_handle[0]); - - instance->result = -1; -@@ -569,10 +557,7 @@ int bcm2835_audio_set_params(struct bcm2 - return -EINVAL; - } - -- if (mutex_lock_interruptible(&instance->vchi_mutex)) { -- LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", instance->num_connections); -- return -EINTR; -- } -+ mutex_lock(&instance->vchi_mutex); - vchi_service_use(instance->vchi_handle[0]); - - instance->result = -1; -@@ -629,11 +614,7 @@ static int bcm2835_audio_start_worker(st - int status; - int ret; - -- if (mutex_lock_interruptible(&instance->vchi_mutex)) { -- LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", -- instance->num_connections); -- return -EINTR; -- } -+ mutex_lock(&instance->vchi_mutex); - vchi_service_use(instance->vchi_handle[0]); - - m.type = VC_AUDIO_MSG_TYPE_START; -@@ -665,11 +646,7 @@ static int bcm2835_audio_stop_worker(str - int status; - int ret; - -- if (mutex_lock_interruptible(&instance->vchi_mutex)) { -- LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", -- instance->num_connections); -- return -EINTR; -- } -+ mutex_lock(&instance->vchi_mutex); - vchi_service_use(instance->vchi_handle[0]); - - m.type = VC_AUDIO_MSG_TYPE_STOP; -@@ -704,11 +681,7 @@ int bcm2835_audio_close(struct bcm2835_a - - my_workqueue_quit(alsa_stream); - -- if (mutex_lock_interruptible(&instance->vchi_mutex)) { -- LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", -- instance->num_connections); -- return -EINTR; -- } -+ mutex_lock(&instance->vchi_mutex); - vchi_service_use(instance->vchi_handle[0]); - - m.type = VC_AUDIO_MSG_TYPE_CLOSE; -@@ -761,11 +734,7 @@ static int bcm2835_audio_write_worker(st - - LOG_INFO(" Writing %d bytes from %p\n", count, src); - -- if (mutex_lock_interruptible(&instance->vchi_mutex)) { -- LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", -- instance->num_connections); -- return -EINTR; -- } -+ mutex_lock(&instance->vchi_mutex); - vchi_service_use(instance->vchi_handle[0]); - - if (instance->peer_version == 0 && ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -149,6 +149,7 @@ static int snd_bcm2835_create(struct snd - return -ENOMEM; - - chip->card = card; -+ mutex_init(&chip->audio_mutex); - - chip->vchi_ctx = devres_find(card->dev->parent, - bcm2835_devm_free_vchi_ctx, NULL, NULL); diff --git a/target/linux/brcm2708/patches-4.19/950-0440-staging-bcm2835-audio-Remove-redundant-substream-mas.patch b/target/linux/brcm2708/patches-4.19/950-0440-staging-bcm2835-audio-Remove-redundant-substream-mas.patch new file mode 100644 index 0000000000..2f913d110b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0440-staging-bcm2835-audio-Remove-redundant-substream-mas.patch @@ -0,0 +1,111 @@ +From 176ca4daf9b956adbdb6846a457053db375d3954 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:33 +0200 +Subject: [PATCH 440/725] staging: bcm2835-audio: Remove redundant substream + mask checks + +commit 14b1f4cba853a11c7b381ad919622f38eb194bd7 upstream. + +The avail_substreams bit mask is checked for the possible racy +accesses, but this cannot happen in practice; i.e. the assignment and +the check are superfluous. + +Let's rip them off. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-ctl.c | 2 -- + .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 8 -------- + .../vc04_services/bcm2835-audio/bcm2835-vchiq.c | 17 +++++++---------- + .../vc04_services/bcm2835-audio/bcm2835.c | 5 +---- + .../vc04_services/bcm2835-audio/bcm2835.h | 2 -- + 5 files changed, 8 insertions(+), 26 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c +@@ -64,8 +64,6 @@ static int snd_bcm2835_ctl_get(struct sn + + mutex_lock(&chip->audio_mutex); + +- BUG_ON(!chip && !(chip->avail_substreams & AVAIL_SUBSTREAMS_MASK)); +- + if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) + ucontrol->value.integer.value[0] = chip2alsa(chip->volume); + else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -118,14 +118,6 @@ static int snd_bcm2835_playback_open_gen + goto out; + } + +- /* Check if we are ready */ +- if (!(chip->avail_substreams & (1 << idx))) { +- /* We are not ready yet */ +- audio_error("substream(%d) device is not ready yet\n", idx); +- err = -EAGAIN; +- goto out; +- } +- + alsa_stream = kzalloc(sizeof(*alsa_stream), GFP_KERNEL); + if (!alsa_stream) { + err = -ENOMEM; +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +@@ -523,16 +523,13 @@ int bcm2835_audio_set_ctls(struct bcm283 + + /* change ctls for all substreams */ + for (i = 0; i < MAX_SUBSTREAMS; i++) { +- if (chip->avail_substreams & (1 << i)) { +- if (!chip->alsa_stream[i]) { +- LOG_DBG(" No ALSA stream available?! %i:%p (%x)\n", i, chip->alsa_stream[i], chip->avail_substreams); +- ret = 0; +- } else if (bcm2835_audio_set_ctls_chan(chip->alsa_stream[i], chip) != 0) { +- LOG_ERR("Couldn't set the controls for stream %d\n", i); +- ret = -1; +- } else { +- LOG_DBG(" Controls set for stream %d\n", i); +- } ++ if (!chip->alsa_stream[i]) ++ continue; ++ if (bcm2835_audio_set_ctls_chan(chip->alsa_stream[i], chip) != 0) { ++ LOG_ERR("Couldn't set the controls for stream %d\n", i); ++ ret = -1; ++ } else { ++ LOG_DBG(" Controls set for stream %d\n", i); + } + } + return ret; +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +@@ -280,7 +280,7 @@ static int snd_add_child_device(struct d + struct snd_card *card; + struct device *child; + struct bcm2835_chip *chip; +- int err, i; ++ int err; + + child = snd_create_device(device, &audio_driver->driver, + audio_driver->driver.name); +@@ -325,9 +325,6 @@ static int snd_add_child_device(struct d + return err; + } + +- for (i = 0; i < numchans; i++) +- chip->avail_substreams |= (1 << i); +- + err = snd_card_register(card); + if (err) { + dev_err(child, "Failed to register card, error %d\n", err); +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h +@@ -98,8 +98,6 @@ struct bcm2835_chip { + struct snd_card *card; + struct snd_pcm *pcm; + struct snd_pcm *pcm_spdif; +- /* Bitmat for valid reg_base and irq numbers */ +- unsigned int avail_substreams; + struct device *dev; + struct bcm2835_alsa_stream *alsa_stream[MAX_SUBSTREAMS]; + diff --git a/target/linux/brcm2708/patches-4.19/950-0441-staging-bcm2835-audio-Fix-mute-controls-volume-handl.patch b/target/linux/brcm2708/patches-4.19/950-0441-staging-bcm2835-audio-Fix-mute-controls-volume-handl.patch new file mode 100644 index 0000000000..91f684b9a6 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0441-staging-bcm2835-audio-Fix-mute-controls-volume-handl.patch @@ -0,0 +1,273 @@ +From a51b0db4416ffc832c98adbe815337c8f1c1d47e Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:34 +0200 +Subject: [PATCH 441/725] staging: bcm2835-audio: Fix mute controls, volume + handling cleanup + +commit 495e5a0d83d3902c741771f267a702ae19da8ab6 upstream. + +In the current code, the mute control is dealt in a special manner, +modifying the current volume and saving the old volume, etc. This is +inconsistent (e.g. change the volume while muted, then unmute), and +way too complex. + +Also, the whole volume handling code has conversion between ALSA +volume and raw volume values, which can lead to another +inconsistency and complexity. + +This patch simplifies these points: +- The ALSA volume value is saved in chip->volume +- volume->mute saves the mute state +- The mute state is evaluated only when the actual volume is passed to + the hardware, bcm2835_audio_set_ctls() + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-ctl.c | 84 +++++++------------ + .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 6 +- + .../bcm2835-audio/bcm2835-vchiq.c | 32 ++----- + .../vc04_services/bcm2835-audio/bcm2835.h | 5 +- + 4 files changed, 45 insertions(+), 82 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c +@@ -12,6 +12,21 @@ + #define CTRL_VOL_MAX 400 + #define CTRL_VOL_MIN -10239 /* originally -10240 */ + ++static int bcm2835_audio_set_chip_ctls(struct bcm2835_chip *chip) ++{ ++ int i, err = 0; ++ ++ /* change ctls for all substreams */ ++ for (i = 0; i < MAX_SUBSTREAMS; i++) { ++ if (chip->alsa_stream[i]) { ++ err = bcm2835_audio_set_ctls(chip->alsa_stream[i]); ++ if (err < 0) ++ break; ++ } ++ } ++ return err; ++} ++ + static int snd_bcm2835_ctl_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) + { +@@ -34,29 +49,6 @@ static int snd_bcm2835_ctl_info(struct s + return 0; + } + +-/* toggles mute on or off depending on the value of nmute, and returns +- * 1 if the mute value was changed, otherwise 0 +- */ +-static int toggle_mute(struct bcm2835_chip *chip, int nmute) +-{ +- /* if settings are ok, just return 0 */ +- if (chip->mute == nmute) +- return 0; +- +- /* if the sound is muted then we need to unmute */ +- if (chip->mute == CTRL_VOL_MUTE) { +- chip->volume = chip->old_volume; /* copy the old volume back */ +- audio_info("Unmuting, old_volume = %d, volume = %d ...\n", chip->old_volume, chip->volume); +- } else /* otherwise we mute */ { +- chip->old_volume = chip->volume; +- chip->volume = 26214; /* set volume to minimum level AKA mute */ +- audio_info("Muting, old_volume = %d, volume = %d ...\n", chip->old_volume, chip->volume); +- } +- +- chip->mute = nmute; +- return 1; +-} +- + static int snd_bcm2835_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) + { +@@ -65,7 +57,7 @@ static int snd_bcm2835_ctl_get(struct sn + mutex_lock(&chip->audio_mutex); + + if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) +- ucontrol->value.integer.value[0] = chip2alsa(chip->volume); ++ ucontrol->value.integer.value[0] = chip->volume; + else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) + ucontrol->value.integer.value[0] = chip->mute; + else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) +@@ -79,38 +71,26 @@ static int snd_bcm2835_ctl_put(struct sn + struct snd_ctl_elem_value *ucontrol) + { + struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); ++ int val, *valp; + int changed = 0; + +- mutex_lock(&chip->audio_mutex); +- +- if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) { +- audio_info("Volume change attempted.. volume = %d new_volume = %d\n", chip->volume, (int)ucontrol->value.integer.value[0]); +- if (chip->mute == CTRL_VOL_MUTE) { +- /* changed = toggle_mute(chip, CTRL_VOL_UNMUTE); */ +- changed = 1; /* should return 0 to signify no change but the mixer takes this as the opposite sign (no idea why) */ +- goto unlock; +- } +- if (changed || (ucontrol->value.integer.value[0] != chip2alsa(chip->volume))) { +- chip->volume = alsa2chip(ucontrol->value.integer.value[0]); +- changed = 1; +- } +- +- } else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) { +- /* Now implemented */ +- audio_info(" Mute attempted\n"); +- changed = toggle_mute(chip, ucontrol->value.integer.value[0]); ++ if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) ++ valp = &chip->volume; ++ else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) ++ valp = &chip->mute; ++ else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) ++ valp = &chip->dest; ++ else ++ return -EINVAL; + +- } else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) { +- if (ucontrol->value.integer.value[0] != chip->dest) { +- chip->dest = ucontrol->value.integer.value[0]; +- changed = 1; +- } ++ val = ucontrol->value.integer.value[0]; ++ mutex_lock(&chip->audio_mutex); ++ if (val != *valp) { ++ *valp = val; ++ changed = 1; ++ if (bcm2835_audio_set_chip_ctls(chip)) ++ dev_err(chip->card->dev, "Failed to set ALSA controls..\n"); + } +- +- if (changed && bcm2835_audio_set_ctls(chip)) +- dev_err(chip->card->dev, "Failed to set ALSA controls..\n"); +- +-unlock: + mutex_unlock(&chip->audio_mutex); + return changed; + } +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -280,7 +280,7 @@ static int snd_bcm2835_pcm_prepare(struc + bcm2835_audio_setup(alsa_stream); + + /* in preparation of the stream, set the controls (volume level) of the stream */ +- bcm2835_audio_set_ctls(alsa_stream->chip); ++ bcm2835_audio_set_ctls(alsa_stream); + + memset(&alsa_stream->pcm_indirect, 0, sizeof(alsa_stream->pcm_indirect)); + +@@ -441,7 +441,7 @@ int snd_bcm2835_new_pcm(struct bcm2835_c + strcpy(pcm->name, "bcm2835 ALSA"); + chip->pcm = pcm; + chip->dest = AUDIO_DEST_AUTO; +- chip->volume = alsa2chip(0); ++ chip->volume = 0; + chip->mute = CTRL_VOL_UNMUTE; /*disable mute on startup */ + /* set operators */ + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, +@@ -498,7 +498,7 @@ int snd_bcm2835_new_simple_pcm(struct bc + strcpy(pcm->name, name); + chip->pcm = pcm; + chip->dest = route; +- chip->volume = alsa2chip(0); ++ chip->volume = 0; + chip->mute = CTRL_VOL_UNMUTE; + + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +@@ -460,11 +460,11 @@ free_wq: + return ret; + } + +-static int bcm2835_audio_set_ctls_chan(struct bcm2835_alsa_stream *alsa_stream, +- struct bcm2835_chip *chip) ++int bcm2835_audio_set_ctls(struct bcm2835_alsa_stream *alsa_stream) + { + struct vc_audio_msg m; + struct bcm2835_audio_instance *instance = alsa_stream->instance; ++ struct bcm2835_chip *chip = alsa_stream->chip; + int status; + int ret; + +@@ -478,7 +478,10 @@ static int bcm2835_audio_set_ctls_chan(s + + m.type = VC_AUDIO_MSG_TYPE_CONTROL; + m.u.control.dest = chip->dest; +- m.u.control.volume = chip->volume; ++ if (!chip->mute) ++ m.u.control.volume = CHIP_MIN_VOLUME; ++ else ++ m.u.control.volume = alsa2chip(chip->volume); + + /* Create the message available completion */ + init_completion(&instance->msg_avail_comp); +@@ -514,27 +517,6 @@ unlock: + return ret; + } + +-int bcm2835_audio_set_ctls(struct bcm2835_chip *chip) +-{ +- int i; +- int ret = 0; +- +- LOG_DBG(" Setting ALSA dest(%d), volume(%d)\n", chip->dest, chip->volume); +- +- /* change ctls for all substreams */ +- for (i = 0; i < MAX_SUBSTREAMS; i++) { +- if (!chip->alsa_stream[i]) +- continue; +- if (bcm2835_audio_set_ctls_chan(chip->alsa_stream[i], chip) != 0) { +- LOG_ERR("Couldn't set the controls for stream %d\n", i); +- ret = -1; +- } else { +- LOG_DBG(" Controls set for stream %d\n", i); +- } +- } +- return ret; +-} +- + int bcm2835_audio_set_params(struct bcm2835_alsa_stream *alsa_stream, + unsigned int channels, unsigned int samplerate, + unsigned int bps) +@@ -548,7 +530,7 @@ int bcm2835_audio_set_params(struct bcm2 + channels, samplerate, bps); + + /* resend ctls - alsa_stream may not have been open when first send */ +- ret = bcm2835_audio_set_ctls_chan(alsa_stream, alsa_stream->chip); ++ ret = bcm2835_audio_set_ctls(alsa_stream); + if (ret) { + LOG_ERR(" Alsa controls not supported\n"); + return -EINVAL; +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h +@@ -74,6 +74,8 @@ enum { + // convert chip to alsa volume + #define chip2alsa(vol) -(((vol) * 100) >> 8) + ++#define CHIP_MIN_VOLUME 26214 /* minimum level aka mute */ ++ + /* Some constants for values .. */ + enum snd_bcm2835_route { + AUDIO_DEST_AUTO = 0, +@@ -102,7 +104,6 @@ struct bcm2835_chip { + struct bcm2835_alsa_stream *alsa_stream[MAX_SUBSTREAMS]; + + int volume; +- int old_volume; /* stores the volume value whist muted */ + int dest; + int mute; + +@@ -160,7 +161,7 @@ int bcm2835_audio_set_params(struct bcm2 + int bcm2835_audio_setup(struct bcm2835_alsa_stream *alsa_stream); + int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream); + int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream); +-int bcm2835_audio_set_ctls(struct bcm2835_chip *chip); ++int bcm2835_audio_set_ctls(struct bcm2835_alsa_stream *alsa_stream); + int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream, + unsigned int count, + void *src); diff --git a/target/linux/brcm2708/patches-4.19/950-0441-staging-bcm2835-audio-Remove-redundant-spdif-stream-.patch b/target/linux/brcm2708/patches-4.19/950-0441-staging-bcm2835-audio-Remove-redundant-spdif-stream-.patch deleted file mode 100644 index 99b9ed23cd..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0441-staging-bcm2835-audio-Remove-redundant-spdif-stream-.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 5171b87bdf5a98d8d24f9fd7a5f3b6304e8ce5ad Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:31 +0200 -Subject: [PATCH 441/703] staging: bcm2835-audio: Remove redundant spdif stream - ctls - -commit ab91e26229eaca2832df51e13c1285aea3be33ab upstream. - -The "IEC958 Playback Stream" control does basically the very same -thing as "IEC958 Playback Default" redundantly. The former should -have been stream-specific and restored after closing the stream, but -we don't do in that way. - -Since it's nothing but confusion, remove this fake. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-ctl.c | 51 ------------------- - 1 file changed, 51 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c -@@ -233,48 +233,6 @@ static int snd_bcm2835_spdif_mask_get(st - return 0; - } - --static int snd_bcm2835_spdif_stream_info(struct snd_kcontrol *kcontrol, -- struct snd_ctl_elem_info *uinfo) --{ -- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; -- uinfo->count = 1; -- return 0; --} -- --static int snd_bcm2835_spdif_stream_get(struct snd_kcontrol *kcontrol, -- struct snd_ctl_elem_value *ucontrol) --{ -- struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); -- int i; -- -- mutex_lock(&chip->audio_mutex); -- -- for (i = 0; i < 4; i++) -- ucontrol->value.iec958.status[i] = -- (chip->spdif_status >> (i * 8)) & 0xff; -- -- mutex_unlock(&chip->audio_mutex); -- return 0; --} -- --static int snd_bcm2835_spdif_stream_put(struct snd_kcontrol *kcontrol, -- struct snd_ctl_elem_value *ucontrol) --{ -- struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); -- unsigned int val = 0; -- int i, change; -- -- mutex_lock(&chip->audio_mutex); -- -- for (i = 0; i < 4; i++) -- val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8); -- change = val != chip->spdif_status; -- chip->spdif_status = val; -- -- mutex_unlock(&chip->audio_mutex); -- return change; --} -- - static struct snd_kcontrol_new snd_bcm2835_spdif[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_PCM, -@@ -290,15 +248,6 @@ static struct snd_kcontrol_new snd_bcm28 - .info = snd_bcm2835_spdif_mask_info, - .get = snd_bcm2835_spdif_mask_get, - }, -- { -- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | -- SNDRV_CTL_ELEM_ACCESS_INACTIVE, -- .iface = SNDRV_CTL_ELEM_IFACE_PCM, -- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM), -- .info = snd_bcm2835_spdif_stream_info, -- .get = snd_bcm2835_spdif_stream_get, -- .put = snd_bcm2835_spdif_stream_put, -- }, - }; - - int snd_bcm2835_new_ctl(struct bcm2835_chip *chip) diff --git a/target/linux/brcm2708/patches-4.19/950-0442-staging-bcm2835-audio-Clean-up-include-files-in-bcm2.patch b/target/linux/brcm2708/patches-4.19/950-0442-staging-bcm2835-audio-Clean-up-include-files-in-bcm2.patch deleted file mode 100644 index 1b8dcd0191..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0442-staging-bcm2835-audio-Clean-up-include-files-in-bcm2.patch +++ /dev/null @@ -1,43 +0,0 @@ -From eaa6771ead56c4388b41740e502b652912423d65 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:32 +0200 -Subject: [PATCH 442/703] staging: bcm2835-audio: Clean up include files in - bcm2835-ctl.c - -commit 821950d3da4bf97bcfedcb812176a0f26b833db0 upstream. - -Only a few of them are really needed. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-ctl.c | 15 --------------- - 1 file changed, 15 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c -@@ -1,23 +1,8 @@ - // SPDX-License-Identifier: GPL-2.0 - /* Copyright 2011 Broadcom Corporation. All rights reserved. */ - --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- - #include - #include --#include --#include --#include --#include - #include - #include - diff --git a/target/linux/brcm2708/patches-4.19/950-0442-staging-bcm2835-audio-Remove-redundant-function-call.patch b/target/linux/brcm2708/patches-4.19/950-0442-staging-bcm2835-audio-Remove-redundant-function-call.patch new file mode 100644 index 0000000000..1c16390227 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0442-staging-bcm2835-audio-Remove-redundant-function-call.patch @@ -0,0 +1,95 @@ +From 641b5ca89295f0cdb0990a2d7b866200643c6a8d Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:35 +0200 +Subject: [PATCH 442/725] staging: bcm2835-audio: Remove redundant function + calls + +commit 124950ebe9fa8547c59e8d4acc8d6c59e6278ed6 upstream. + +bcm2835_audio_setup(), bcm2835_audio_flush_buffers() and +bcm2835_audio_flush_playback_buffers() functions do implement +nothing. + +Also, bcm2835_audio_set_ctls() is already called inside +bcm2835_audio_set_params(), so the later call is superfluous. + +This patch removes these superfluous implementations. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 5 ----- + .../bcm2835-audio/bcm2835-vchiq.c | 21 ------------------- + .../vc04_services/bcm2835-audio/bcm2835.h | 3 --- + 3 files changed, 29 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -277,11 +277,6 @@ static int snd_bcm2835_pcm_prepare(struc + if (err < 0) + audio_error(" error setting hw params\n"); + +- bcm2835_audio_setup(alsa_stream); +- +- /* in preparation of the stream, set the controls (volume level) of the stream */ +- bcm2835_audio_set_ctls(alsa_stream); +- + memset(&alsa_stream->pcm_indirect, 0, sizeof(alsa_stream->pcm_indirect)); + + alsa_stream->pcm_indirect.hw_buffer_size = +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +@@ -580,12 +580,6 @@ unlock: + return ret; + } + +-int bcm2835_audio_setup(struct bcm2835_alsa_stream *alsa_stream) +-{ +- +- return 0; +-} +- + static int bcm2835_audio_start_worker(struct bcm2835_alsa_stream *alsa_stream) + { + struct vc_audio_msg m; +@@ -774,21 +768,6 @@ unlock: + return ret; + } + +-/** +- * Returns all buffers from arm->vc +- */ +-void bcm2835_audio_flush_buffers(struct bcm2835_alsa_stream *alsa_stream) +-{ +-} +- +-/** +- * Forces VC to flush(drop) its filled playback buffers and +- * return them the us. (VC->ARM) +- */ +-void bcm2835_audio_flush_playback_buffers(struct bcm2835_alsa_stream *alsa_stream) +-{ +-} +- + unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream) + { + unsigned int count = atomic_read(&alsa_stream->retrieved); +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h +@@ -158,7 +158,6 @@ int bcm2835_audio_close(struct bcm2835_a + int bcm2835_audio_set_params(struct bcm2835_alsa_stream *alsa_stream, + unsigned int channels, unsigned int samplerate, + unsigned int bps); +-int bcm2835_audio_setup(struct bcm2835_alsa_stream *alsa_stream); + int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream); + int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream); + int bcm2835_audio_set_ctls(struct bcm2835_alsa_stream *alsa_stream); +@@ -167,7 +166,5 @@ int bcm2835_audio_write(struct bcm2835_a + void *src); + void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream); + unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream); +-void bcm2835_audio_flush_buffers(struct bcm2835_alsa_stream *alsa_stream); +-void bcm2835_audio_flush_playback_buffers(struct bcm2835_alsa_stream *alsa_stream); + + #endif /* __SOUND_ARM_BCM2835_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0443-staging-bcm2835-audio-Remove-redundant-substream-mas.patch b/target/linux/brcm2708/patches-4.19/950-0443-staging-bcm2835-audio-Remove-redundant-substream-mas.patch deleted file mode 100644 index 1b9b919eb2..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0443-staging-bcm2835-audio-Remove-redundant-substream-mas.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 48113d6d98bd0f810b439741bb0da982b1abe4c1 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:33 +0200 -Subject: [PATCH 443/703] staging: bcm2835-audio: Remove redundant substream - mask checks - -commit 14b1f4cba853a11c7b381ad919622f38eb194bd7 upstream. - -The avail_substreams bit mask is checked for the possible racy -accesses, but this cannot happen in practice; i.e. the assignment and -the check are superfluous. - -Let's rip them off. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-ctl.c | 2 -- - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 8 -------- - .../vc04_services/bcm2835-audio/bcm2835-vchiq.c | 17 +++++++---------- - .../vc04_services/bcm2835-audio/bcm2835.c | 5 +---- - .../vc04_services/bcm2835-audio/bcm2835.h | 2 -- - 5 files changed, 8 insertions(+), 26 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c -@@ -64,8 +64,6 @@ static int snd_bcm2835_ctl_get(struct sn - - mutex_lock(&chip->audio_mutex); - -- BUG_ON(!chip && !(chip->avail_substreams & AVAIL_SUBSTREAMS_MASK)); -- - if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) - ucontrol->value.integer.value[0] = chip2alsa(chip->volume); - else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -118,14 +118,6 @@ static int snd_bcm2835_playback_open_gen - goto out; - } - -- /* Check if we are ready */ -- if (!(chip->avail_substreams & (1 << idx))) { -- /* We are not ready yet */ -- audio_error("substream(%d) device is not ready yet\n", idx); -- err = -EAGAIN; -- goto out; -- } -- - alsa_stream = kzalloc(sizeof(*alsa_stream), GFP_KERNEL); - if (!alsa_stream) { - err = -ENOMEM; ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -@@ -523,16 +523,13 @@ int bcm2835_audio_set_ctls(struct bcm283 - - /* change ctls for all substreams */ - for (i = 0; i < MAX_SUBSTREAMS; i++) { -- if (chip->avail_substreams & (1 << i)) { -- if (!chip->alsa_stream[i]) { -- LOG_DBG(" No ALSA stream available?! %i:%p (%x)\n", i, chip->alsa_stream[i], chip->avail_substreams); -- ret = 0; -- } else if (bcm2835_audio_set_ctls_chan(chip->alsa_stream[i], chip) != 0) { -- LOG_ERR("Couldn't set the controls for stream %d\n", i); -- ret = -1; -- } else { -- LOG_DBG(" Controls set for stream %d\n", i); -- } -+ if (!chip->alsa_stream[i]) -+ continue; -+ if (bcm2835_audio_set_ctls_chan(chip->alsa_stream[i], chip) != 0) { -+ LOG_ERR("Couldn't set the controls for stream %d\n", i); -+ ret = -1; -+ } else { -+ LOG_DBG(" Controls set for stream %d\n", i); - } - } - return ret; ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -280,7 +280,7 @@ static int snd_add_child_device(struct d - struct snd_card *card; - struct device *child; - struct bcm2835_chip *chip; -- int err, i; -+ int err; - - child = snd_create_device(device, &audio_driver->driver, - audio_driver->driver.name); -@@ -325,9 +325,6 @@ static int snd_add_child_device(struct d - return err; - } - -- for (i = 0; i < numchans; i++) -- chip->avail_substreams |= (1 << i); -- - err = snd_card_register(card); - if (err) { - dev_err(child, "Failed to register card, error %d\n", err); ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -@@ -98,8 +98,6 @@ struct bcm2835_chip { - struct snd_card *card; - struct snd_pcm *pcm; - struct snd_pcm *pcm_spdif; -- /* Bitmat for valid reg_base and irq numbers */ -- unsigned int avail_substreams; - struct device *dev; - struct bcm2835_alsa_stream *alsa_stream[MAX_SUBSTREAMS]; - diff --git a/target/linux/brcm2708/patches-4.19/950-0443-staging-bcm2835-audio-Remove-superfluous-open-flag.patch b/target/linux/brcm2708/patches-4.19/950-0443-staging-bcm2835-audio-Remove-superfluous-open-flag.patch new file mode 100644 index 0000000000..aa4b7ef16a --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0443-staging-bcm2835-audio-Remove-superfluous-open-flag.patch @@ -0,0 +1,61 @@ +From e935363e043245369cb6b566348e86b0be6c0840 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:36 +0200 +Subject: [PATCH 443/725] staging: bcm2835-audio: Remove superfluous open flag + +commit ad13924de6b07cb52714ea1809c57b2e72a24504 upstream. + +All the alsa_stream->open flag checks in the current code are +redundant, and they cannot be racy. For the code simplification, +let's remove the flag and its check. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 9 ++------- + drivers/staging/vc04_services/bcm2835-audio/bcm2835.h | 1 - + 2 files changed, 2 insertions(+), 8 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -57,8 +57,7 @@ void bcm2835_playback_fifo(struct bcm283 + audio_info("alsa_stream=%p substream=%p\n", alsa_stream, + alsa_stream ? alsa_stream->substream : 0); + +- if (alsa_stream->open) +- consumed = bcm2835_audio_retrieve_buffers(alsa_stream); ++ consumed = bcm2835_audio_retrieve_buffers(alsa_stream); + + /* We get called only if playback was triggered, So, the number of buffers we retrieve in + * each iteration are the buffers that have been played out already +@@ -154,7 +153,6 @@ static int snd_bcm2835_playback_open_gen + chip->alsa_stream[idx] = alsa_stream; + + chip->opened |= (1 << idx); +- alsa_stream->open = 1; + alsa_stream->draining = 1; + + out: +@@ -205,10 +203,7 @@ static int snd_bcm2835_playback_close(st + alsa_stream->period_size = 0; + alsa_stream->buffer_size = 0; + +- if (alsa_stream->open) { +- alsa_stream->open = 0; +- bcm2835_audio_close(alsa_stream); +- } ++ bcm2835_audio_close(alsa_stream); + if (alsa_stream->chip) + alsa_stream->chip->alsa_stream[alsa_stream->idx] = NULL; + /* +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h +@@ -121,7 +121,6 @@ struct bcm2835_alsa_stream { + + spinlock_t lock; + +- int open; + int running; + int draining; + diff --git a/target/linux/brcm2708/patches-4.19/950-0444-staging-bcm2835-audio-Drop-useless-running-flag-and-.patch b/target/linux/brcm2708/patches-4.19/950-0444-staging-bcm2835-audio-Drop-useless-running-flag-and-.patch new file mode 100644 index 0000000000..42277b6fdd --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0444-staging-bcm2835-audio-Drop-useless-running-flag-and-.patch @@ -0,0 +1,106 @@ +From 70e1a30534d17ecf4fb6a5e04241b1d1704a909d Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:37 +0200 +Subject: [PATCH 444/725] staging: bcm2835-audio: Drop useless running flag and + check + +commit 02f2376321d75e78117f39ff81f215254ee6b4ef upstream. + +The running flag of alsa_stream is basically useless. The running +state is strictly controlled in ALSA PCM core side, hence the check in +PCM trigger and close callbacks are superfluous. + +Also, the prefill ack at trigger start became superfluous nowadays +with the ALSA PCM core update. + +Let's rip them off. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 46 ++++--------------- + .../vc04_services/bcm2835-audio/bcm2835.h | 1 - + 2 files changed, 8 insertions(+), 39 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -187,19 +187,6 @@ static int snd_bcm2835_playback_close(st + + audio_info("Alsa close\n"); + +- /* +- * Call stop if it's still running. This happens when app +- * is force killed and we don't get a stop trigger. +- */ +- if (alsa_stream->running) { +- int err; +- +- err = bcm2835_audio_stop(alsa_stream); +- alsa_stream->running = 0; +- if (err) +- audio_error(" Failed to STOP alsa device\n"); +- } +- + alsa_stream->period_size = 0; + alsa_stream->buffer_size = 0; + +@@ -324,27 +311,13 @@ static int snd_bcm2835_pcm_trigger(struc + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: +- audio_debug("bcm2835_AUDIO_TRIGGER_START running=%d\n", +- alsa_stream->running); +- if (!alsa_stream->running) { +- err = bcm2835_audio_start(alsa_stream); +- if (!err) { +- alsa_stream->pcm_indirect.hw_io = +- alsa_stream->pcm_indirect.hw_data = +- bytes_to_frames(runtime, +- alsa_stream->pos); +- substream->ops->ack(substream); +- alsa_stream->running = 1; +- alsa_stream->draining = 1; +- } else { +- audio_error(" Failed to START alsa device (%d)\n", err); +- } +- } ++ err = bcm2835_audio_start(alsa_stream); ++ if (!err) ++ alsa_stream->draining = 1; ++ else ++ audio_error(" Failed to START alsa device (%d)\n", err); + break; + case SNDRV_PCM_TRIGGER_STOP: +- audio_debug +- ("bcm2835_AUDIO_TRIGGER_STOP running=%d draining=%d\n", +- alsa_stream->running, runtime->status->state == SNDRV_PCM_STATE_DRAINING); + if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { + audio_info("DRAINING\n"); + alsa_stream->draining = 1; +@@ -352,12 +325,9 @@ static int snd_bcm2835_pcm_trigger(struc + audio_info("DROPPING\n"); + alsa_stream->draining = 0; + } +- if (alsa_stream->running) { +- err = bcm2835_audio_stop(alsa_stream); +- if (err != 0) +- audio_error(" Failed to STOP alsa device (%d)\n", err); +- alsa_stream->running = 0; +- } ++ err = bcm2835_audio_stop(alsa_stream); ++ if (err != 0) ++ audio_error(" Failed to STOP alsa device (%d)\n", err); + break; + default: + err = -EINVAL; +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h +@@ -121,7 +121,6 @@ struct bcm2835_alsa_stream { + + spinlock_t lock; + +- int running; + int draining; + + int channels; diff --git a/target/linux/brcm2708/patches-4.19/950-0444-staging-bcm2835-audio-Fix-mute-controls-volume-handl.patch b/target/linux/brcm2708/patches-4.19/950-0444-staging-bcm2835-audio-Fix-mute-controls-volume-handl.patch deleted file mode 100644 index ea2d72b39c..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0444-staging-bcm2835-audio-Fix-mute-controls-volume-handl.patch +++ /dev/null @@ -1,273 +0,0 @@ -From 8e1cbe403cccb0269ad6563cf223a220f2173964 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:34 +0200 -Subject: [PATCH 444/703] staging: bcm2835-audio: Fix mute controls, volume - handling cleanup - -commit 495e5a0d83d3902c741771f267a702ae19da8ab6 upstream. - -In the current code, the mute control is dealt in a special manner, -modifying the current volume and saving the old volume, etc. This is -inconsistent (e.g. change the volume while muted, then unmute), and -way too complex. - -Also, the whole volume handling code has conversion between ALSA -volume and raw volume values, which can lead to another -inconsistency and complexity. - -This patch simplifies these points: -- The ALSA volume value is saved in chip->volume -- volume->mute saves the mute state -- The mute state is evaluated only when the actual volume is passed to - the hardware, bcm2835_audio_set_ctls() - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-ctl.c | 84 +++++++------------ - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 6 +- - .../bcm2835-audio/bcm2835-vchiq.c | 32 ++----- - .../vc04_services/bcm2835-audio/bcm2835.h | 5 +- - 4 files changed, 45 insertions(+), 82 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c -@@ -12,6 +12,21 @@ - #define CTRL_VOL_MAX 400 - #define CTRL_VOL_MIN -10239 /* originally -10240 */ - -+static int bcm2835_audio_set_chip_ctls(struct bcm2835_chip *chip) -+{ -+ int i, err = 0; -+ -+ /* change ctls for all substreams */ -+ for (i = 0; i < MAX_SUBSTREAMS; i++) { -+ if (chip->alsa_stream[i]) { -+ err = bcm2835_audio_set_ctls(chip->alsa_stream[i]); -+ if (err < 0) -+ break; -+ } -+ } -+ return err; -+} -+ - static int snd_bcm2835_ctl_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) - { -@@ -34,29 +49,6 @@ static int snd_bcm2835_ctl_info(struct s - return 0; - } - --/* toggles mute on or off depending on the value of nmute, and returns -- * 1 if the mute value was changed, otherwise 0 -- */ --static int toggle_mute(struct bcm2835_chip *chip, int nmute) --{ -- /* if settings are ok, just return 0 */ -- if (chip->mute == nmute) -- return 0; -- -- /* if the sound is muted then we need to unmute */ -- if (chip->mute == CTRL_VOL_MUTE) { -- chip->volume = chip->old_volume; /* copy the old volume back */ -- audio_info("Unmuting, old_volume = %d, volume = %d ...\n", chip->old_volume, chip->volume); -- } else /* otherwise we mute */ { -- chip->old_volume = chip->volume; -- chip->volume = 26214; /* set volume to minimum level AKA mute */ -- audio_info("Muting, old_volume = %d, volume = %d ...\n", chip->old_volume, chip->volume); -- } -- -- chip->mute = nmute; -- return 1; --} -- - static int snd_bcm2835_ctl_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { -@@ -65,7 +57,7 @@ static int snd_bcm2835_ctl_get(struct sn - mutex_lock(&chip->audio_mutex); - - if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) -- ucontrol->value.integer.value[0] = chip2alsa(chip->volume); -+ ucontrol->value.integer.value[0] = chip->volume; - else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) - ucontrol->value.integer.value[0] = chip->mute; - else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) -@@ -79,38 +71,26 @@ static int snd_bcm2835_ctl_put(struct sn - struct snd_ctl_elem_value *ucontrol) - { - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); -+ int val, *valp; - int changed = 0; - -- mutex_lock(&chip->audio_mutex); -- -- if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) { -- audio_info("Volume change attempted.. volume = %d new_volume = %d\n", chip->volume, (int)ucontrol->value.integer.value[0]); -- if (chip->mute == CTRL_VOL_MUTE) { -- /* changed = toggle_mute(chip, CTRL_VOL_UNMUTE); */ -- changed = 1; /* should return 0 to signify no change but the mixer takes this as the opposite sign (no idea why) */ -- goto unlock; -- } -- if (changed || (ucontrol->value.integer.value[0] != chip2alsa(chip->volume))) { -- chip->volume = alsa2chip(ucontrol->value.integer.value[0]); -- changed = 1; -- } -- -- } else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) { -- /* Now implemented */ -- audio_info(" Mute attempted\n"); -- changed = toggle_mute(chip, ucontrol->value.integer.value[0]); -+ if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) -+ valp = &chip->volume; -+ else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) -+ valp = &chip->mute; -+ else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) -+ valp = &chip->dest; -+ else -+ return -EINVAL; - -- } else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) { -- if (ucontrol->value.integer.value[0] != chip->dest) { -- chip->dest = ucontrol->value.integer.value[0]; -- changed = 1; -- } -+ val = ucontrol->value.integer.value[0]; -+ mutex_lock(&chip->audio_mutex); -+ if (val != *valp) { -+ *valp = val; -+ changed = 1; -+ if (bcm2835_audio_set_chip_ctls(chip)) -+ dev_err(chip->card->dev, "Failed to set ALSA controls..\n"); - } -- -- if (changed && bcm2835_audio_set_ctls(chip)) -- dev_err(chip->card->dev, "Failed to set ALSA controls..\n"); -- --unlock: - mutex_unlock(&chip->audio_mutex); - return changed; - } ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -280,7 +280,7 @@ static int snd_bcm2835_pcm_prepare(struc - bcm2835_audio_setup(alsa_stream); - - /* in preparation of the stream, set the controls (volume level) of the stream */ -- bcm2835_audio_set_ctls(alsa_stream->chip); -+ bcm2835_audio_set_ctls(alsa_stream); - - memset(&alsa_stream->pcm_indirect, 0, sizeof(alsa_stream->pcm_indirect)); - -@@ -441,7 +441,7 @@ int snd_bcm2835_new_pcm(struct bcm2835_c - strcpy(pcm->name, "bcm2835 ALSA"); - chip->pcm = pcm; - chip->dest = AUDIO_DEST_AUTO; -- chip->volume = alsa2chip(0); -+ chip->volume = 0; - chip->mute = CTRL_VOL_UNMUTE; /*disable mute on startup */ - /* set operators */ - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, -@@ -498,7 +498,7 @@ int snd_bcm2835_new_simple_pcm(struct bc - strcpy(pcm->name, name); - chip->pcm = pcm; - chip->dest = route; -- chip->volume = alsa2chip(0); -+ chip->volume = 0; - chip->mute = CTRL_VOL_UNMUTE; - - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -@@ -460,11 +460,11 @@ free_wq: - return ret; - } - --static int bcm2835_audio_set_ctls_chan(struct bcm2835_alsa_stream *alsa_stream, -- struct bcm2835_chip *chip) -+int bcm2835_audio_set_ctls(struct bcm2835_alsa_stream *alsa_stream) - { - struct vc_audio_msg m; - struct bcm2835_audio_instance *instance = alsa_stream->instance; -+ struct bcm2835_chip *chip = alsa_stream->chip; - int status; - int ret; - -@@ -478,7 +478,10 @@ static int bcm2835_audio_set_ctls_chan(s - - m.type = VC_AUDIO_MSG_TYPE_CONTROL; - m.u.control.dest = chip->dest; -- m.u.control.volume = chip->volume; -+ if (!chip->mute) -+ m.u.control.volume = CHIP_MIN_VOLUME; -+ else -+ m.u.control.volume = alsa2chip(chip->volume); - - /* Create the message available completion */ - init_completion(&instance->msg_avail_comp); -@@ -514,27 +517,6 @@ unlock: - return ret; - } - --int bcm2835_audio_set_ctls(struct bcm2835_chip *chip) --{ -- int i; -- int ret = 0; -- -- LOG_DBG(" Setting ALSA dest(%d), volume(%d)\n", chip->dest, chip->volume); -- -- /* change ctls for all substreams */ -- for (i = 0; i < MAX_SUBSTREAMS; i++) { -- if (!chip->alsa_stream[i]) -- continue; -- if (bcm2835_audio_set_ctls_chan(chip->alsa_stream[i], chip) != 0) { -- LOG_ERR("Couldn't set the controls for stream %d\n", i); -- ret = -1; -- } else { -- LOG_DBG(" Controls set for stream %d\n", i); -- } -- } -- return ret; --} -- - int bcm2835_audio_set_params(struct bcm2835_alsa_stream *alsa_stream, - unsigned int channels, unsigned int samplerate, - unsigned int bps) -@@ -548,7 +530,7 @@ int bcm2835_audio_set_params(struct bcm2 - channels, samplerate, bps); - - /* resend ctls - alsa_stream may not have been open when first send */ -- ret = bcm2835_audio_set_ctls_chan(alsa_stream, alsa_stream->chip); -+ ret = bcm2835_audio_set_ctls(alsa_stream); - if (ret) { - LOG_ERR(" Alsa controls not supported\n"); - return -EINVAL; ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -@@ -74,6 +74,8 @@ enum { - // convert chip to alsa volume - #define chip2alsa(vol) -(((vol) * 100) >> 8) - -+#define CHIP_MIN_VOLUME 26214 /* minimum level aka mute */ -+ - /* Some constants for values .. */ - enum snd_bcm2835_route { - AUDIO_DEST_AUTO = 0, -@@ -102,7 +104,6 @@ struct bcm2835_chip { - struct bcm2835_alsa_stream *alsa_stream[MAX_SUBSTREAMS]; - - int volume; -- int old_volume; /* stores the volume value whist muted */ - int dest; - int mute; - -@@ -160,7 +161,7 @@ int bcm2835_audio_set_params(struct bcm2 - int bcm2835_audio_setup(struct bcm2835_alsa_stream *alsa_stream); - int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream); - int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream); --int bcm2835_audio_set_ctls(struct bcm2835_chip *chip); -+int bcm2835_audio_set_ctls(struct bcm2835_alsa_stream *alsa_stream); - int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream, - unsigned int count, - void *src); diff --git a/target/linux/brcm2708/patches-4.19/950-0445-staging-bcm2835-audio-Fix-incorrect-draining-handlin.patch b/target/linux/brcm2708/patches-4.19/950-0445-staging-bcm2835-audio-Fix-incorrect-draining-handlin.patch new file mode 100644 index 0000000000..5cd0af06ed --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0445-staging-bcm2835-audio-Fix-incorrect-draining-handlin.patch @@ -0,0 +1,69 @@ +From 52a5b0e8e24f31fdef175e76405fd4ee08936f26 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:38 +0200 +Subject: [PATCH 445/725] staging: bcm2835-audio: Fix incorrect draining + handling + +commit 7d2a91f5f1bcf08ca257bcf1ed9721fcd341f834 upstream. + +The handling of SNDRV_PCM_TRIGGER_STOP at the trigger callback is +incorrect: when the STOP is issued, the driver is supposed to drop the +stream immediately. Meanwhile bcm2835 driver checks the DRAINING +state and tries to issue some different command. + +This patch straightens things a bit, dropping the incorrect state +checks. The draining behavior would be still not perfect at this +point, but will be improved in a later patch. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 18 ++++++------------ + 1 file changed, 6 insertions(+), 12 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -153,7 +153,6 @@ static int snd_bcm2835_playback_open_gen + chip->alsa_stream[idx] = alsa_stream; + + chip->opened |= (1 << idx); +- alsa_stream->draining = 1; + + out: + mutex_unlock(&chip->audio_mutex); +@@ -268,6 +267,7 @@ static int snd_bcm2835_pcm_prepare(struc + alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream); + alsa_stream->period_size = snd_pcm_lib_period_bytes(substream); + alsa_stream->pos = 0; ++ alsa_stream->draining = false; + + audio_debug("buffer_size=%d, period_size=%d pos=%d frame_bits=%d\n", + alsa_stream->buffer_size, alsa_stream->period_size, +@@ -312,21 +312,15 @@ static int snd_bcm2835_pcm_trigger(struc + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + err = bcm2835_audio_start(alsa_stream); +- if (!err) +- alsa_stream->draining = 1; +- else ++ if (err) + audio_error(" Failed to START alsa device (%d)\n", err); + break; ++ case SNDRV_PCM_TRIGGER_DRAIN: ++ alsa_stream->draining = true; ++ break; + case SNDRV_PCM_TRIGGER_STOP: +- if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { +- audio_info("DRAINING\n"); +- alsa_stream->draining = 1; +- } else { +- audio_info("DROPPING\n"); +- alsa_stream->draining = 0; +- } + err = bcm2835_audio_stop(alsa_stream); +- if (err != 0) ++ if (err) + audio_error(" Failed to STOP alsa device (%d)\n", err); + break; + default: diff --git a/target/linux/brcm2708/patches-4.19/950-0445-staging-bcm2835-audio-Remove-redundant-function-call.patch b/target/linux/brcm2708/patches-4.19/950-0445-staging-bcm2835-audio-Remove-redundant-function-call.patch deleted file mode 100644 index 7154e0f95a..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0445-staging-bcm2835-audio-Remove-redundant-function-call.patch +++ /dev/null @@ -1,95 +0,0 @@ -From c778d5d0208598e0595e59b2795b92580483971d Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:35 +0200 -Subject: [PATCH 445/703] staging: bcm2835-audio: Remove redundant function - calls - -commit 124950ebe9fa8547c59e8d4acc8d6c59e6278ed6 upstream. - -bcm2835_audio_setup(), bcm2835_audio_flush_buffers() and -bcm2835_audio_flush_playback_buffers() functions do implement -nothing. - -Also, bcm2835_audio_set_ctls() is already called inside -bcm2835_audio_set_params(), so the later call is superfluous. - -This patch removes these superfluous implementations. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 5 ----- - .../bcm2835-audio/bcm2835-vchiq.c | 21 ------------------- - .../vc04_services/bcm2835-audio/bcm2835.h | 3 --- - 3 files changed, 29 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -277,11 +277,6 @@ static int snd_bcm2835_pcm_prepare(struc - if (err < 0) - audio_error(" error setting hw params\n"); - -- bcm2835_audio_setup(alsa_stream); -- -- /* in preparation of the stream, set the controls (volume level) of the stream */ -- bcm2835_audio_set_ctls(alsa_stream); -- - memset(&alsa_stream->pcm_indirect, 0, sizeof(alsa_stream->pcm_indirect)); - - alsa_stream->pcm_indirect.hw_buffer_size = ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -@@ -580,12 +580,6 @@ unlock: - return ret; - } - --int bcm2835_audio_setup(struct bcm2835_alsa_stream *alsa_stream) --{ -- -- return 0; --} -- - static int bcm2835_audio_start_worker(struct bcm2835_alsa_stream *alsa_stream) - { - struct vc_audio_msg m; -@@ -774,21 +768,6 @@ unlock: - return ret; - } - --/** -- * Returns all buffers from arm->vc -- */ --void bcm2835_audio_flush_buffers(struct bcm2835_alsa_stream *alsa_stream) --{ --} -- --/** -- * Forces VC to flush(drop) its filled playback buffers and -- * return them the us. (VC->ARM) -- */ --void bcm2835_audio_flush_playback_buffers(struct bcm2835_alsa_stream *alsa_stream) --{ --} -- - unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream) - { - unsigned int count = atomic_read(&alsa_stream->retrieved); ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -@@ -158,7 +158,6 @@ int bcm2835_audio_close(struct bcm2835_a - int bcm2835_audio_set_params(struct bcm2835_alsa_stream *alsa_stream, - unsigned int channels, unsigned int samplerate, - unsigned int bps); --int bcm2835_audio_setup(struct bcm2835_alsa_stream *alsa_stream); - int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream); - int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream); - int bcm2835_audio_set_ctls(struct bcm2835_alsa_stream *alsa_stream); -@@ -167,7 +166,5 @@ int bcm2835_audio_write(struct bcm2835_a - void *src); - void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream); - unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream); --void bcm2835_audio_flush_buffers(struct bcm2835_alsa_stream *alsa_stream); --void bcm2835_audio_flush_playback_buffers(struct bcm2835_alsa_stream *alsa_stream); - - #endif /* __SOUND_ARM_BCM2835_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0446-staging-bcm2835-audio-Kill-unused-spinlock.patch b/target/linux/brcm2708/patches-4.19/950-0446-staging-bcm2835-audio-Kill-unused-spinlock.patch new file mode 100644 index 0000000000..bff1693e9c --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0446-staging-bcm2835-audio-Kill-unused-spinlock.patch @@ -0,0 +1,39 @@ +From 0f4ac0deca99ce7936a43d1e1f7b712a30dc554d Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:39 +0200 +Subject: [PATCH 446/725] staging: bcm2835-audio: Kill unused spinlock + +commit 5332f6f012c0bf3a45c77dbc0f79814443a884d4 upstream. + +The alsa_stream->lock is never used. Kill it. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 2 -- + drivers/staging/vc04_services/bcm2835-audio/bcm2835.h | 2 -- + 2 files changed, 4 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -128,8 +128,6 @@ static int snd_bcm2835_playback_open_gen + alsa_stream->substream = substream; + alsa_stream->idx = idx; + +- spin_lock_init(&alsa_stream->lock); +- + err = bcm2835_audio_open(alsa_stream); + if (err) { + kfree(alsa_stream); +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h +@@ -119,8 +119,6 @@ struct bcm2835_alsa_stream { + struct snd_pcm_substream *substream; + struct snd_pcm_indirect pcm_indirect; + +- spinlock_t lock; +- + int draining; + + int channels; diff --git a/target/linux/brcm2708/patches-4.19/950-0446-staging-bcm2835-audio-Remove-superfluous-open-flag.patch b/target/linux/brcm2708/patches-4.19/950-0446-staging-bcm2835-audio-Remove-superfluous-open-flag.patch deleted file mode 100644 index 26a3ddf36a..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0446-staging-bcm2835-audio-Remove-superfluous-open-flag.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 5894f3d0de921dd5134004906643a1d1219b13cf Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:36 +0200 -Subject: [PATCH 446/703] staging: bcm2835-audio: Remove superfluous open flag - -commit ad13924de6b07cb52714ea1809c57b2e72a24504 upstream. - -All the alsa_stream->open flag checks in the current code are -redundant, and they cannot be racy. For the code simplification, -let's remove the flag and its check. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 9 ++------- - drivers/staging/vc04_services/bcm2835-audio/bcm2835.h | 1 - - 2 files changed, 2 insertions(+), 8 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -57,8 +57,7 @@ void bcm2835_playback_fifo(struct bcm283 - audio_info("alsa_stream=%p substream=%p\n", alsa_stream, - alsa_stream ? alsa_stream->substream : 0); - -- if (alsa_stream->open) -- consumed = bcm2835_audio_retrieve_buffers(alsa_stream); -+ consumed = bcm2835_audio_retrieve_buffers(alsa_stream); - - /* We get called only if playback was triggered, So, the number of buffers we retrieve in - * each iteration are the buffers that have been played out already -@@ -154,7 +153,6 @@ static int snd_bcm2835_playback_open_gen - chip->alsa_stream[idx] = alsa_stream; - - chip->opened |= (1 << idx); -- alsa_stream->open = 1; - alsa_stream->draining = 1; - - out: -@@ -205,10 +203,7 @@ static int snd_bcm2835_playback_close(st - alsa_stream->period_size = 0; - alsa_stream->buffer_size = 0; - -- if (alsa_stream->open) { -- alsa_stream->open = 0; -- bcm2835_audio_close(alsa_stream); -- } -+ bcm2835_audio_close(alsa_stream); - if (alsa_stream->chip) - alsa_stream->chip->alsa_stream[alsa_stream->idx] = NULL; - /* ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -@@ -121,7 +121,6 @@ struct bcm2835_alsa_stream { - - spinlock_t lock; - -- int open; - int running; - int draining; - diff --git a/target/linux/brcm2708/patches-4.19/950-0447-staging-bcm2835-audio-Drop-useless-running-flag-and-.patch b/target/linux/brcm2708/patches-4.19/950-0447-staging-bcm2835-audio-Drop-useless-running-flag-and-.patch deleted file mode 100644 index ba0c220c3e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0447-staging-bcm2835-audio-Drop-useless-running-flag-and-.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 2dd8625b99a3244bf632278cd7fdd74dffaeb3a3 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:37 +0200 -Subject: [PATCH 447/703] staging: bcm2835-audio: Drop useless running flag and - check - -commit 02f2376321d75e78117f39ff81f215254ee6b4ef upstream. - -The running flag of alsa_stream is basically useless. The running -state is strictly controlled in ALSA PCM core side, hence the check in -PCM trigger and close callbacks are superfluous. - -Also, the prefill ack at trigger start became superfluous nowadays -with the ALSA PCM core update. - -Let's rip them off. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 46 ++++--------------- - .../vc04_services/bcm2835-audio/bcm2835.h | 1 - - 2 files changed, 8 insertions(+), 39 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -187,19 +187,6 @@ static int snd_bcm2835_playback_close(st - - audio_info("Alsa close\n"); - -- /* -- * Call stop if it's still running. This happens when app -- * is force killed and we don't get a stop trigger. -- */ -- if (alsa_stream->running) { -- int err; -- -- err = bcm2835_audio_stop(alsa_stream); -- alsa_stream->running = 0; -- if (err) -- audio_error(" Failed to STOP alsa device\n"); -- } -- - alsa_stream->period_size = 0; - alsa_stream->buffer_size = 0; - -@@ -324,27 +311,13 @@ static int snd_bcm2835_pcm_trigger(struc - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: -- audio_debug("bcm2835_AUDIO_TRIGGER_START running=%d\n", -- alsa_stream->running); -- if (!alsa_stream->running) { -- err = bcm2835_audio_start(alsa_stream); -- if (!err) { -- alsa_stream->pcm_indirect.hw_io = -- alsa_stream->pcm_indirect.hw_data = -- bytes_to_frames(runtime, -- alsa_stream->pos); -- substream->ops->ack(substream); -- alsa_stream->running = 1; -- alsa_stream->draining = 1; -- } else { -- audio_error(" Failed to START alsa device (%d)\n", err); -- } -- } -+ err = bcm2835_audio_start(alsa_stream); -+ if (!err) -+ alsa_stream->draining = 1; -+ else -+ audio_error(" Failed to START alsa device (%d)\n", err); - break; - case SNDRV_PCM_TRIGGER_STOP: -- audio_debug -- ("bcm2835_AUDIO_TRIGGER_STOP running=%d draining=%d\n", -- alsa_stream->running, runtime->status->state == SNDRV_PCM_STATE_DRAINING); - if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { - audio_info("DRAINING\n"); - alsa_stream->draining = 1; -@@ -352,12 +325,9 @@ static int snd_bcm2835_pcm_trigger(struc - audio_info("DROPPING\n"); - alsa_stream->draining = 0; - } -- if (alsa_stream->running) { -- err = bcm2835_audio_stop(alsa_stream); -- if (err != 0) -- audio_error(" Failed to STOP alsa device (%d)\n", err); -- alsa_stream->running = 0; -- } -+ err = bcm2835_audio_stop(alsa_stream); -+ if (err != 0) -+ audio_error(" Failed to STOP alsa device (%d)\n", err); - break; - default: - err = -EINVAL; ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -@@ -121,7 +121,6 @@ struct bcm2835_alsa_stream { - - spinlock_t lock; - -- int running; - int draining; - - int channels; diff --git a/target/linux/brcm2708/patches-4.19/950-0447-staging-bcm2835-audio-Use-PCM-runtime-values-instead.patch b/target/linux/brcm2708/patches-4.19/950-0447-staging-bcm2835-audio-Use-PCM-runtime-values-instead.patch new file mode 100644 index 0000000000..5d8753f415 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0447-staging-bcm2835-audio-Use-PCM-runtime-values-instead.patch @@ -0,0 +1,74 @@ +From aaf04413a17530437872ec909f2af1fb012e9954 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:40 +0200 +Subject: [PATCH 447/725] staging: bcm2835-audio: Use PCM runtime values + instead + +commit b8f7fdd50890b848e085c0519469aed4ff4d9b54 upstream. + +Some fields in alsa_stream are the values we keep already in PCM +runtime object, hence they are redundant. Use the standard PCM +runtime values instead of the private copies. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 23 ++++--------------- + .../vc04_services/bcm2835-audio/bcm2835.h | 4 ---- + 2 files changed, 4 insertions(+), 23 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -206,22 +206,7 @@ static int snd_bcm2835_playback_close(st + static int snd_bcm2835_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) + { +- struct snd_pcm_runtime *runtime = substream->runtime; +- struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; +- int err; +- +- err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); +- if (err < 0) { +- audio_error +- (" pcm_lib_malloc failed to allocated pages for buffers\n"); +- return err; +- } +- +- alsa_stream->channels = params_channels(params); +- alsa_stream->params_rate = params_rate(params); +- alsa_stream->pcm_format_width = snd_pcm_format_width(params_format(params)); +- +- return err; ++ return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); + } + + /* hw_free callback */ +@@ -248,11 +233,11 @@ static int snd_bcm2835_pcm_prepare(struc + if (chip->spdif_status & IEC958_AES0_NONAUDIO) + channels = 0; + else +- channels = alsa_stream->channels; ++ channels = runtime->channels; + + err = bcm2835_audio_set_params(alsa_stream, channels, +- alsa_stream->params_rate, +- alsa_stream->pcm_format_width); ++ runtime->rate, ++ snd_pcm_format_width(runtime->format)); + if (err < 0) + audio_error(" error setting hw params\n"); + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h +@@ -121,10 +121,6 @@ struct bcm2835_alsa_stream { + + int draining; + +- int channels; +- int params_rate; +- int pcm_format_width; +- + unsigned int pos; + unsigned int buffer_size; + unsigned int period_size; diff --git a/target/linux/brcm2708/patches-4.19/950-0448-staging-bcm2835-audio-Drop-unnecessary-pcm-indirect-.patch b/target/linux/brcm2708/patches-4.19/950-0448-staging-bcm2835-audio-Drop-unnecessary-pcm-indirect-.patch new file mode 100644 index 0000000000..890fb18758 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0448-staging-bcm2835-audio-Drop-unnecessary-pcm-indirect-.patch @@ -0,0 +1,29 @@ +From 1e69d6aed91e759114adec689fe954890dbac0d0 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:41 +0200 +Subject: [PATCH 448/725] staging: bcm2835-audio: Drop unnecessary pcm indirect + setup + +commit 7318ec896f4856fae2bb013858e422fa078201e1 upstream. + +The hw_queue_size of PCM indirect helper doesn't need to be set up if +you use the whole given buffer size. Drop the useless +initialization, which just confuses readers. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -280,7 +280,6 @@ static int snd_bcm2835_pcm_ack(struct sn + struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; + struct snd_pcm_indirect *pcm_indirect = &alsa_stream->pcm_indirect; + +- pcm_indirect->hw_queue_size = runtime->hw.buffer_bytes_max; + return snd_pcm_indirect_playback_transfer(substream, pcm_indirect, + snd_bcm2835_pcm_transfer); + } diff --git a/target/linux/brcm2708/patches-4.19/950-0448-staging-bcm2835-audio-Fix-incorrect-draining-handlin.patch b/target/linux/brcm2708/patches-4.19/950-0448-staging-bcm2835-audio-Fix-incorrect-draining-handlin.patch deleted file mode 100644 index 16c6d3d5a1..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0448-staging-bcm2835-audio-Fix-incorrect-draining-handlin.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 0938ad598509c19a256d5fc63b9002ad9cf59a14 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:38 +0200 -Subject: [PATCH 448/703] staging: bcm2835-audio: Fix incorrect draining - handling - -commit 7d2a91f5f1bcf08ca257bcf1ed9721fcd341f834 upstream. - -The handling of SNDRV_PCM_TRIGGER_STOP at the trigger callback is -incorrect: when the STOP is issued, the driver is supposed to drop the -stream immediately. Meanwhile bcm2835 driver checks the DRAINING -state and tries to issue some different command. - -This patch straightens things a bit, dropping the incorrect state -checks. The draining behavior would be still not perfect at this -point, but will be improved in a later patch. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 18 ++++++------------ - 1 file changed, 6 insertions(+), 12 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -153,7 +153,6 @@ static int snd_bcm2835_playback_open_gen - chip->alsa_stream[idx] = alsa_stream; - - chip->opened |= (1 << idx); -- alsa_stream->draining = 1; - - out: - mutex_unlock(&chip->audio_mutex); -@@ -268,6 +267,7 @@ static int snd_bcm2835_pcm_prepare(struc - alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream); - alsa_stream->period_size = snd_pcm_lib_period_bytes(substream); - alsa_stream->pos = 0; -+ alsa_stream->draining = false; - - audio_debug("buffer_size=%d, period_size=%d pos=%d frame_bits=%d\n", - alsa_stream->buffer_size, alsa_stream->period_size, -@@ -312,21 +312,15 @@ static int snd_bcm2835_pcm_trigger(struc - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - err = bcm2835_audio_start(alsa_stream); -- if (!err) -- alsa_stream->draining = 1; -- else -+ if (err) - audio_error(" Failed to START alsa device (%d)\n", err); - break; -+ case SNDRV_PCM_TRIGGER_DRAIN: -+ alsa_stream->draining = true; -+ break; - case SNDRV_PCM_TRIGGER_STOP: -- if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { -- audio_info("DRAINING\n"); -- alsa_stream->draining = 1; -- } else { -- audio_info("DROPPING\n"); -- alsa_stream->draining = 0; -- } - err = bcm2835_audio_stop(alsa_stream); -- if (err != 0) -+ if (err) - audio_error(" Failed to STOP alsa device (%d)\n", err); - break; - default: diff --git a/target/linux/brcm2708/patches-4.19/950-0449-staging-bcm2835-audio-Drop-useless-NULL-check.patch b/target/linux/brcm2708/patches-4.19/950-0449-staging-bcm2835-audio-Drop-useless-NULL-check.patch new file mode 100644 index 0000000000..af84cd6cb5 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0449-staging-bcm2835-audio-Drop-useless-NULL-check.patch @@ -0,0 +1,28 @@ +From 8756f60e33dfa2c92d8d3c2abd162c084a9d92c6 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:42 +0200 +Subject: [PATCH 449/725] staging: bcm2835-audio: Drop useless NULL check + +commit 8bcf9f252c29c2d5bcce3db605c0ebf1ef230f9c upstream. + +alsa_stream->chip can be never NULL. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -188,8 +188,7 @@ static int snd_bcm2835_playback_close(st + alsa_stream->buffer_size = 0; + + bcm2835_audio_close(alsa_stream); +- if (alsa_stream->chip) +- alsa_stream->chip->alsa_stream[alsa_stream->idx] = NULL; ++ alsa_stream->chip->alsa_stream[alsa_stream->idx] = NULL; + /* + * Do not free up alsa_stream here, it will be freed up by + * runtime->private_free callback we registered in *_open above diff --git a/target/linux/brcm2708/patches-4.19/950-0449-staging-bcm2835-audio-Kill-unused-spinlock.patch b/target/linux/brcm2708/patches-4.19/950-0449-staging-bcm2835-audio-Kill-unused-spinlock.patch deleted file mode 100644 index 9caaf33f2f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0449-staging-bcm2835-audio-Kill-unused-spinlock.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 7634e4d73bc54cd1382ccffd72ab07db522f2667 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:39 +0200 -Subject: [PATCH 449/703] staging: bcm2835-audio: Kill unused spinlock - -commit 5332f6f012c0bf3a45c77dbc0f79814443a884d4 upstream. - -The alsa_stream->lock is never used. Kill it. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 2 -- - drivers/staging/vc04_services/bcm2835-audio/bcm2835.h | 2 -- - 2 files changed, 4 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -128,8 +128,6 @@ static int snd_bcm2835_playback_open_gen - alsa_stream->substream = substream; - alsa_stream->idx = idx; - -- spin_lock_init(&alsa_stream->lock); -- - err = bcm2835_audio_open(alsa_stream); - if (err) { - kfree(alsa_stream); ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -@@ -119,8 +119,6 @@ struct bcm2835_alsa_stream { - struct snd_pcm_substream *substream; - struct snd_pcm_indirect pcm_indirect; - -- spinlock_t lock; -- - int draining; - - int channels; diff --git a/target/linux/brcm2708/patches-4.19/950-0450-staging-bcm2835-audio-Propagate-parameter-setup-erro.patch b/target/linux/brcm2708/patches-4.19/950-0450-staging-bcm2835-audio-Propagate-parameter-setup-erro.patch new file mode 100644 index 0000000000..e595bc1dad --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0450-staging-bcm2835-audio-Propagate-parameter-setup-erro.patch @@ -0,0 +1,40 @@ +From da7c23faa34cb7ace6c22dbdfba3eb3ee047454f Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:43 +0200 +Subject: [PATCH 450/725] staging: bcm2835-audio: Propagate parameter setup + error + +commit fee5638fe552ff8222c3a5bdcc4a34255e248d8c upstream. + +When the parameter setup fails, the driver should propagate the error +code instead of silently ignoring it. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -238,7 +238,7 @@ static int snd_bcm2835_pcm_prepare(struc + runtime->rate, + snd_pcm_format_width(runtime->format)); + if (err < 0) +- audio_error(" error setting hw params\n"); ++ goto out; + + memset(&alsa_stream->pcm_indirect, 0, sizeof(alsa_stream->pcm_indirect)); + +@@ -255,8 +255,9 @@ static int snd_bcm2835_pcm_prepare(struc + alsa_stream->buffer_size, alsa_stream->period_size, + alsa_stream->pos, runtime->frame_bits); + ++ out: + mutex_unlock(&chip->audio_mutex); +- return 0; ++ return err; + } + + static void snd_bcm2835_pcm_transfer(struct snd_pcm_substream *substream, diff --git a/target/linux/brcm2708/patches-4.19/950-0450-staging-bcm2835-audio-Use-PCM-runtime-values-instead.patch b/target/linux/brcm2708/patches-4.19/950-0450-staging-bcm2835-audio-Use-PCM-runtime-values-instead.patch deleted file mode 100644 index a01aa145fe..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0450-staging-bcm2835-audio-Use-PCM-runtime-values-instead.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 5e97bf3a60f5ebcb1e4135fe1d92f649c920ff81 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:40 +0200 -Subject: [PATCH 450/703] staging: bcm2835-audio: Use PCM runtime values - instead - -commit b8f7fdd50890b848e085c0519469aed4ff4d9b54 upstream. - -Some fields in alsa_stream are the values we keep already in PCM -runtime object, hence they are redundant. Use the standard PCM -runtime values instead of the private copies. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 23 ++++--------------- - .../vc04_services/bcm2835-audio/bcm2835.h | 4 ---- - 2 files changed, 4 insertions(+), 23 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -206,22 +206,7 @@ static int snd_bcm2835_playback_close(st - static int snd_bcm2835_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) - { -- struct snd_pcm_runtime *runtime = substream->runtime; -- struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; -- int err; -- -- err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); -- if (err < 0) { -- audio_error -- (" pcm_lib_malloc failed to allocated pages for buffers\n"); -- return err; -- } -- -- alsa_stream->channels = params_channels(params); -- alsa_stream->params_rate = params_rate(params); -- alsa_stream->pcm_format_width = snd_pcm_format_width(params_format(params)); -- -- return err; -+ return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); - } - - /* hw_free callback */ -@@ -248,11 +233,11 @@ static int snd_bcm2835_pcm_prepare(struc - if (chip->spdif_status & IEC958_AES0_NONAUDIO) - channels = 0; - else -- channels = alsa_stream->channels; -+ channels = runtime->channels; - - err = bcm2835_audio_set_params(alsa_stream, channels, -- alsa_stream->params_rate, -- alsa_stream->pcm_format_width); -+ runtime->rate, -+ snd_pcm_format_width(runtime->format)); - if (err < 0) - audio_error(" error setting hw params\n"); - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -@@ -121,10 +121,6 @@ struct bcm2835_alsa_stream { - - int draining; - -- int channels; -- int params_rate; -- int pcm_format_width; -- - unsigned int pos; - unsigned int buffer_size; - unsigned int period_size; diff --git a/target/linux/brcm2708/patches-4.19/950-0451-staging-bcm2835-audio-Drop-debug-messages-in-bcm2835.patch b/target/linux/brcm2708/patches-4.19/950-0451-staging-bcm2835-audio-Drop-debug-messages-in-bcm2835.patch new file mode 100644 index 0000000000..44b09da23f --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0451-staging-bcm2835-audio-Drop-debug-messages-in-bcm2835.patch @@ -0,0 +1,150 @@ +From 3341080850b4ad6e51017afa9ca83020487f1c3d Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:44 +0200 +Subject: [PATCH 451/725] staging: bcm2835-audio: Drop debug messages in + bcm2835-pcm.c + +commit 055e1c330d04df87d4730a5db837161c11ddaafc upstream. + +These debug messages worsen the code readability a lot while they give +little debuggability (which we already have via tracing, in anyway). + +Let's clean them up. This allows us to reduce the +snd_bcm2835_pcm_lib_ioctl() function to be a direct call of the +snd_pcm_lib_ioctl callback (like most other drivers do), too. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 51 +++---------------- + 1 file changed, 7 insertions(+), 44 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -44,9 +44,7 @@ static const struct snd_pcm_hardware snd + + static void snd_bcm2835_playback_free(struct snd_pcm_runtime *runtime) + { +- audio_info("Freeing up alsa stream here ..\n"); + kfree(runtime->private_data); +- runtime->private_data = NULL; + } + + void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream) +@@ -99,7 +97,6 @@ static int snd_bcm2835_playback_open_gen + int err; + + mutex_lock(&chip->audio_mutex); +- audio_info("Alsa open (%d)\n", substream->number); + idx = substream->number; + + if (spdif && chip->opened) { +@@ -182,8 +179,6 @@ static int snd_bcm2835_playback_close(st + runtime = substream->runtime; + alsa_stream = runtime->private_data; + +- audio_info("Alsa close\n"); +- + alsa_stream->period_size = 0; + alsa_stream->buffer_size = 0; + +@@ -251,10 +246,6 @@ static int snd_bcm2835_pcm_prepare(struc + alsa_stream->pos = 0; + alsa_stream->draining = false; + +- audio_debug("buffer_size=%d, period_size=%d pos=%d frame_bits=%d\n", +- alsa_stream->buffer_size, alsa_stream->period_size, +- alsa_stream->pos, runtime->frame_bits); +- + out: + mutex_unlock(&chip->audio_mutex); + return err; +@@ -266,12 +257,8 @@ static void snd_bcm2835_pcm_transfer(str + struct snd_pcm_runtime *runtime = substream->runtime; + struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; + void *src = (void *) (substream->runtime->dma_area + rec->sw_data); +- int err; +- +- err = bcm2835_audio_write(alsa_stream, bytes, src); +- if (err) +- audio_error(" Failed to transfer to alsa device (%d)\n", err); + ++ bcm2835_audio_write(alsa_stream, bytes, src); + } + + static int snd_bcm2835_pcm_ack(struct snd_pcm_substream *substream) +@@ -289,27 +276,18 @@ static int snd_bcm2835_pcm_trigger(struc + { + struct snd_pcm_runtime *runtime = substream->runtime; + struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; +- int err = 0; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: +- err = bcm2835_audio_start(alsa_stream); +- if (err) +- audio_error(" Failed to START alsa device (%d)\n", err); +- break; ++ return bcm2835_audio_start(alsa_stream); + case SNDRV_PCM_TRIGGER_DRAIN: + alsa_stream->draining = true; +- break; ++ return 0; + case SNDRV_PCM_TRIGGER_STOP: +- err = bcm2835_audio_stop(alsa_stream); +- if (err) +- audio_error(" Failed to STOP alsa device (%d)\n", err); +- break; ++ return bcm2835_audio_stop(alsa_stream); + default: +- err = -EINVAL; ++ return -EINVAL; + } +- +- return err; + } + + /* pointer callback */ +@@ -319,31 +297,16 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_s + struct snd_pcm_runtime *runtime = substream->runtime; + struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; + +- audio_debug("pcm_pointer... (%d) hwptr=%d appl=%d pos=%d\n", 0, +- frames_to_bytes(runtime, runtime->status->hw_ptr), +- frames_to_bytes(runtime, runtime->control->appl_ptr), +- alsa_stream->pos); +- + return snd_pcm_indirect_playback_pointer(substream, + &alsa_stream->pcm_indirect, + alsa_stream->pos); + } + +-static int snd_bcm2835_pcm_lib_ioctl(struct snd_pcm_substream *substream, +- unsigned int cmd, void *arg) +-{ +- int ret = snd_pcm_lib_ioctl(substream, cmd, arg); +- +- audio_info(" .. substream=%p, cmd=%d, arg=%p (%x) ret=%d\n", substream, +- cmd, arg, arg ? *(unsigned int *)arg : 0, ret); +- return ret; +-} +- + /* operators */ + static const struct snd_pcm_ops snd_bcm2835_playback_ops = { + .open = snd_bcm2835_playback_open, + .close = snd_bcm2835_playback_close, +- .ioctl = snd_bcm2835_pcm_lib_ioctl, ++ .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_bcm2835_pcm_hw_params, + .hw_free = snd_bcm2835_pcm_hw_free, + .prepare = snd_bcm2835_pcm_prepare, +@@ -355,7 +318,7 @@ static const struct snd_pcm_ops snd_bcm2 + static const struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = { + .open = snd_bcm2835_playback_spdif_open, + .close = snd_bcm2835_playback_close, +- .ioctl = snd_bcm2835_pcm_lib_ioctl, ++ .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_bcm2835_pcm_hw_params, + .hw_free = snd_bcm2835_pcm_hw_free, + .prepare = snd_bcm2835_pcm_prepare, diff --git a/target/linux/brcm2708/patches-4.19/950-0451-staging-bcm2835-audio-Drop-unnecessary-pcm-indirect-.patch b/target/linux/brcm2708/patches-4.19/950-0451-staging-bcm2835-audio-Drop-unnecessary-pcm-indirect-.patch deleted file mode 100644 index c1946bbfb3..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0451-staging-bcm2835-audio-Drop-unnecessary-pcm-indirect-.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 82365fbb4b8d2b7602c765b49524da2895efba61 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:41 +0200 -Subject: [PATCH 451/703] staging: bcm2835-audio: Drop unnecessary pcm indirect - setup - -commit 7318ec896f4856fae2bb013858e422fa078201e1 upstream. - -The hw_queue_size of PCM indirect helper doesn't need to be set up if -you use the whole given buffer size. Drop the useless -initialization, which just confuses readers. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -280,7 +280,6 @@ static int snd_bcm2835_pcm_ack(struct sn - struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; - struct snd_pcm_indirect *pcm_indirect = &alsa_stream->pcm_indirect; - -- pcm_indirect->hw_queue_size = runtime->hw.buffer_bytes_max; - return snd_pcm_indirect_playback_transfer(substream, pcm_indirect, - snd_bcm2835_pcm_transfer); - } diff --git a/target/linux/brcm2708/patches-4.19/950-0452-staging-bcm2835-audio-Drop-superfluous-mutex-lock-du.patch b/target/linux/brcm2708/patches-4.19/950-0452-staging-bcm2835-audio-Drop-superfluous-mutex-lock-du.patch new file mode 100644 index 0000000000..c0a92f8cf7 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0452-staging-bcm2835-audio-Drop-superfluous-mutex-lock-du.patch @@ -0,0 +1,49 @@ +From e890c7d7d4476ed6276f0d902a83b6d34ad513f2 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:45 +0200 +Subject: [PATCH 452/725] staging: bcm2835-audio: Drop superfluous mutex lock + during prepare + +commit f0eb15d055380ff127e5f12c8fad2b36bdb3c006 upstream. + +The chip->audio_mutex is used basically for protecting the opened +stream assignment, and the prepare callback is irrelevant with it. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -218,8 +218,6 @@ static int snd_bcm2835_pcm_prepare(struc + int channels; + int err; + +- mutex_lock(&chip->audio_mutex); +- + /* notify the vchiq that it should enter spdif passthrough mode by + * setting channels=0 (see + * https://github.com/raspberrypi/linux/issues/528) +@@ -233,7 +231,7 @@ static int snd_bcm2835_pcm_prepare(struc + runtime->rate, + snd_pcm_format_width(runtime->format)); + if (err < 0) +- goto out; ++ return err; + + memset(&alsa_stream->pcm_indirect, 0, sizeof(alsa_stream->pcm_indirect)); + +@@ -246,9 +244,7 @@ static int snd_bcm2835_pcm_prepare(struc + alsa_stream->pos = 0; + alsa_stream->draining = false; + +- out: +- mutex_unlock(&chip->audio_mutex); +- return err; ++ return 0; + } + + static void snd_bcm2835_pcm_transfer(struct snd_pcm_substream *substream, diff --git a/target/linux/brcm2708/patches-4.19/950-0452-staging-bcm2835-audio-Drop-useless-NULL-check.patch b/target/linux/brcm2708/patches-4.19/950-0452-staging-bcm2835-audio-Drop-useless-NULL-check.patch deleted file mode 100644 index c6205a0d54..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0452-staging-bcm2835-audio-Drop-useless-NULL-check.patch +++ /dev/null @@ -1,28 +0,0 @@ -From fa0533b8020b056d559cfdcb86da8ee332ae8a02 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:42 +0200 -Subject: [PATCH 452/703] staging: bcm2835-audio: Drop useless NULL check - -commit 8bcf9f252c29c2d5bcce3db605c0ebf1ef230f9c upstream. - -alsa_stream->chip can be never NULL. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -188,8 +188,7 @@ static int snd_bcm2835_playback_close(st - alsa_stream->buffer_size = 0; - - bcm2835_audio_close(alsa_stream); -- if (alsa_stream->chip) -- alsa_stream->chip->alsa_stream[alsa_stream->idx] = NULL; -+ alsa_stream->chip->alsa_stream[alsa_stream->idx] = NULL; - /* - * Do not free up alsa_stream here, it will be freed up by - * runtime->private_free callback we registered in *_open above diff --git a/target/linux/brcm2708/patches-4.19/950-0453-staging-bcm2835-audio-Add-10ms-period-constraint.patch b/target/linux/brcm2708/patches-4.19/950-0453-staging-bcm2835-audio-Add-10ms-period-constraint.patch new file mode 100644 index 0000000000..68df360809 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0453-staging-bcm2835-audio-Add-10ms-period-constraint.patch @@ -0,0 +1,33 @@ +From 9634bb7bf8aa4fe86d00ff572c3290dfa042a8d6 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:46 +0200 +Subject: [PATCH 453/725] staging: bcm2835-audio: Add 10ms period constraint + +commit 93c66acaf68b5247c3121a46a71ff6a70fc1d492 upstream. + +It seems that the resolution of vc04 callback is in 10 msec; i.e. the +minimal period size is also 10 msec. + +This patch adds the corresponding hw constraint. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -145,6 +145,11 @@ static int snd_bcm2835_playback_open_gen + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, + 16); + ++ /* position update is in 10ms order */ ++ snd_pcm_hw_constraint_minmax(runtime, ++ SNDRV_PCM_HW_PARAM_PERIOD_TIME, ++ 10 * 1000, UINT_MAX); ++ + chip->alsa_stream[idx] = alsa_stream; + + chip->opened |= (1 << idx); diff --git a/target/linux/brcm2708/patches-4.19/950-0453-staging-bcm2835-audio-Propagate-parameter-setup-erro.patch b/target/linux/brcm2708/patches-4.19/950-0453-staging-bcm2835-audio-Propagate-parameter-setup-erro.patch deleted file mode 100644 index 884171b334..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0453-staging-bcm2835-audio-Propagate-parameter-setup-erro.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 10310b6f36d3573f55e3ab318204aebe9f1a60f8 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:43 +0200 -Subject: [PATCH 453/703] staging: bcm2835-audio: Propagate parameter setup - error - -commit fee5638fe552ff8222c3a5bdcc4a34255e248d8c upstream. - -When the parameter setup fails, the driver should propagate the error -code instead of silently ignoring it. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -238,7 +238,7 @@ static int snd_bcm2835_pcm_prepare(struc - runtime->rate, - snd_pcm_format_width(runtime->format)); - if (err < 0) -- audio_error(" error setting hw params\n"); -+ goto out; - - memset(&alsa_stream->pcm_indirect, 0, sizeof(alsa_stream->pcm_indirect)); - -@@ -255,8 +255,9 @@ static int snd_bcm2835_pcm_prepare(struc - alsa_stream->buffer_size, alsa_stream->period_size, - alsa_stream->pos, runtime->frame_bits); - -+ out: - mutex_unlock(&chip->audio_mutex); -- return 0; -+ return err; - } - - static void snd_bcm2835_pcm_transfer(struct snd_pcm_substream *substream, diff --git a/target/linux/brcm2708/patches-4.19/950-0454-staging-bcm2835-audio-Drop-debug-messages-in-bcm2835.patch b/target/linux/brcm2708/patches-4.19/950-0454-staging-bcm2835-audio-Drop-debug-messages-in-bcm2835.patch deleted file mode 100644 index 0955df5595..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0454-staging-bcm2835-audio-Drop-debug-messages-in-bcm2835.patch +++ /dev/null @@ -1,150 +0,0 @@ -From 50292f7a57de792cb23b3883594b0e102e74e9e2 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:44 +0200 -Subject: [PATCH 454/703] staging: bcm2835-audio: Drop debug messages in - bcm2835-pcm.c - -commit 055e1c330d04df87d4730a5db837161c11ddaafc upstream. - -These debug messages worsen the code readability a lot while they give -little debuggability (which we already have via tracing, in anyway). - -Let's clean them up. This allows us to reduce the -snd_bcm2835_pcm_lib_ioctl() function to be a direct call of the -snd_pcm_lib_ioctl callback (like most other drivers do), too. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 51 +++---------------- - 1 file changed, 7 insertions(+), 44 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -44,9 +44,7 @@ static const struct snd_pcm_hardware snd - - static void snd_bcm2835_playback_free(struct snd_pcm_runtime *runtime) - { -- audio_info("Freeing up alsa stream here ..\n"); - kfree(runtime->private_data); -- runtime->private_data = NULL; - } - - void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream) -@@ -99,7 +97,6 @@ static int snd_bcm2835_playback_open_gen - int err; - - mutex_lock(&chip->audio_mutex); -- audio_info("Alsa open (%d)\n", substream->number); - idx = substream->number; - - if (spdif && chip->opened) { -@@ -182,8 +179,6 @@ static int snd_bcm2835_playback_close(st - runtime = substream->runtime; - alsa_stream = runtime->private_data; - -- audio_info("Alsa close\n"); -- - alsa_stream->period_size = 0; - alsa_stream->buffer_size = 0; - -@@ -251,10 +246,6 @@ static int snd_bcm2835_pcm_prepare(struc - alsa_stream->pos = 0; - alsa_stream->draining = false; - -- audio_debug("buffer_size=%d, period_size=%d pos=%d frame_bits=%d\n", -- alsa_stream->buffer_size, alsa_stream->period_size, -- alsa_stream->pos, runtime->frame_bits); -- - out: - mutex_unlock(&chip->audio_mutex); - return err; -@@ -266,12 +257,8 @@ static void snd_bcm2835_pcm_transfer(str - struct snd_pcm_runtime *runtime = substream->runtime; - struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; - void *src = (void *) (substream->runtime->dma_area + rec->sw_data); -- int err; -- -- err = bcm2835_audio_write(alsa_stream, bytes, src); -- if (err) -- audio_error(" Failed to transfer to alsa device (%d)\n", err); - -+ bcm2835_audio_write(alsa_stream, bytes, src); - } - - static int snd_bcm2835_pcm_ack(struct snd_pcm_substream *substream) -@@ -289,27 +276,18 @@ static int snd_bcm2835_pcm_trigger(struc - { - struct snd_pcm_runtime *runtime = substream->runtime; - struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; -- int err = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: -- err = bcm2835_audio_start(alsa_stream); -- if (err) -- audio_error(" Failed to START alsa device (%d)\n", err); -- break; -+ return bcm2835_audio_start(alsa_stream); - case SNDRV_PCM_TRIGGER_DRAIN: - alsa_stream->draining = true; -- break; -+ return 0; - case SNDRV_PCM_TRIGGER_STOP: -- err = bcm2835_audio_stop(alsa_stream); -- if (err) -- audio_error(" Failed to STOP alsa device (%d)\n", err); -- break; -+ return bcm2835_audio_stop(alsa_stream); - default: -- err = -EINVAL; -+ return -EINVAL; - } -- -- return err; - } - - /* pointer callback */ -@@ -319,31 +297,16 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_s - struct snd_pcm_runtime *runtime = substream->runtime; - struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; - -- audio_debug("pcm_pointer... (%d) hwptr=%d appl=%d pos=%d\n", 0, -- frames_to_bytes(runtime, runtime->status->hw_ptr), -- frames_to_bytes(runtime, runtime->control->appl_ptr), -- alsa_stream->pos); -- - return snd_pcm_indirect_playback_pointer(substream, - &alsa_stream->pcm_indirect, - alsa_stream->pos); - } - --static int snd_bcm2835_pcm_lib_ioctl(struct snd_pcm_substream *substream, -- unsigned int cmd, void *arg) --{ -- int ret = snd_pcm_lib_ioctl(substream, cmd, arg); -- -- audio_info(" .. substream=%p, cmd=%d, arg=%p (%x) ret=%d\n", substream, -- cmd, arg, arg ? *(unsigned int *)arg : 0, ret); -- return ret; --} -- - /* operators */ - static const struct snd_pcm_ops snd_bcm2835_playback_ops = { - .open = snd_bcm2835_playback_open, - .close = snd_bcm2835_playback_close, -- .ioctl = snd_bcm2835_pcm_lib_ioctl, -+ .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_bcm2835_pcm_hw_params, - .hw_free = snd_bcm2835_pcm_hw_free, - .prepare = snd_bcm2835_pcm_prepare, -@@ -355,7 +318,7 @@ static const struct snd_pcm_ops snd_bcm2 - static const struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = { - .open = snd_bcm2835_playback_spdif_open, - .close = snd_bcm2835_playback_close, -- .ioctl = snd_bcm2835_pcm_lib_ioctl, -+ .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_bcm2835_pcm_hw_params, - .hw_free = snd_bcm2835_pcm_hw_free, - .prepare = snd_bcm2835_pcm_prepare, diff --git a/target/linux/brcm2708/patches-4.19/950-0454-staging-bcm2835-audio-Make-single-vchi-handle.patch b/target/linux/brcm2708/patches-4.19/950-0454-staging-bcm2835-audio-Make-single-vchi-handle.patch new file mode 100644 index 0000000000..1637b842ce --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0454-staging-bcm2835-audio-Make-single-vchi-handle.patch @@ -0,0 +1,412 @@ +From 2aa144a5c55a27072f21c0dcb8efa180a46c4cd1 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:47 +0200 +Subject: [PATCH 454/725] staging: bcm2835-audio: Make single vchi handle + +commit 326a6edcb2ada56375bd7d3fc24c83f58e8da7f3 upstream. + +The bcm2835_audio_instance object contains the array of +VCHI_SERVICE_HANDLE_T, while the code assumes and uses only the first +element explicitly. Let's reduce to a single vchi handle for +simplifying the code. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../bcm2835-audio/bcm2835-vchiq.c | 170 ++++++------------ + 1 file changed, 58 insertions(+), 112 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +@@ -44,8 +44,7 @@ + #endif + + struct bcm2835_audio_instance { +- unsigned int num_connections; +- VCHI_SERVICE_HANDLE_T vchi_handle[VCHI_MAX_NUM_CONNECTIONS]; ++ VCHI_SERVICE_HANDLE_T vchi_handle; + struct completion msg_avail_comp; + struct mutex vchi_mutex; + struct bcm2835_alsa_stream *alsa_stream; +@@ -202,12 +201,12 @@ static void audio_vchi_callback(void *pa + BUG(); + return; + } +- if (!instance->vchi_handle[0]) { +- LOG_ERR(" .. instance->vchi_handle[0] is null\n"); ++ if (!instance->vchi_handle) { ++ LOG_ERR(" .. instance->vchi_handle is null\n"); + BUG(); + return; + } +- status = vchi_msg_dequeue(instance->vchi_handle[0], ++ status = vchi_msg_dequeue(instance->vchi_handle, + &m, sizeof(m), &msg_len, VCHI_FLAGS_NONE); + if (m.type == VC_AUDIO_MSG_TYPE_RESULT) { + LOG_DBG(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_RESULT, success=%d\n", +@@ -237,102 +236,61 @@ static void audio_vchi_callback(void *pa + + static struct bcm2835_audio_instance * + vc_vchi_audio_init(VCHI_INSTANCE_T vchi_instance, +- VCHI_CONNECTION_T **vchi_connections, +- unsigned int num_connections) ++ VCHI_CONNECTION_T *vchi_connection) + { +- unsigned int i; ++ SERVICE_CREATION_T params = { ++ .version = VCHI_VERSION_EX(VC_AUDIOSERV_VER, VC_AUDIOSERV_MIN_VER), ++ .service_id = VC_AUDIO_SERVER_NAME, ++ .connection = vchi_connection, ++ .rx_fifo_size = 0, ++ .tx_fifo_size = 0, ++ .callback = audio_vchi_callback, ++ .want_unaligned_bulk_rx = 1, //TODO: remove VCOS_FALSE ++ .want_unaligned_bulk_tx = 1, //TODO: remove VCOS_FALSE ++ .want_crc = 0 ++ }; + struct bcm2835_audio_instance *instance; + int status; +- int ret; +- +- LOG_DBG("%s: start", __func__); + +- if (num_connections > VCHI_MAX_NUM_CONNECTIONS) { +- LOG_ERR("%s: unsupported number of connections %u (max=%u)\n", +- __func__, num_connections, VCHI_MAX_NUM_CONNECTIONS); +- +- return ERR_PTR(-EINVAL); +- } + /* Allocate memory for this instance */ + instance = kzalloc(sizeof(*instance), GFP_KERNEL); + if (!instance) + return ERR_PTR(-ENOMEM); + +- instance->num_connections = num_connections; +- + /* Create a lock for exclusive, serialized VCHI connection access */ + mutex_init(&instance->vchi_mutex); + /* Open the VCHI service connections */ +- for (i = 0; i < num_connections; i++) { +- SERVICE_CREATION_T params = { +- .version = VCHI_VERSION_EX(VC_AUDIOSERV_VER, VC_AUDIOSERV_MIN_VER), +- .service_id = VC_AUDIO_SERVER_NAME, +- .connection = vchi_connections[i], +- .rx_fifo_size = 0, +- .tx_fifo_size = 0, +- .callback = audio_vchi_callback, +- .callback_param = instance, +- .want_unaligned_bulk_rx = 1, //TODO: remove VCOS_FALSE +- .want_unaligned_bulk_tx = 1, //TODO: remove VCOS_FALSE +- .want_crc = 0 +- }; +- +- LOG_DBG("%s: about to open %i\n", __func__, i); +- status = vchi_service_open(vchi_instance, ¶ms, +- &instance->vchi_handle[i]); ++ params.callback_param = instance, + +- LOG_DBG("%s: opened %i: %p=%d\n", __func__, i, instance->vchi_handle[i], status); +- if (status) { +- LOG_ERR("%s: failed to open VCHI service connection (status=%d)\n", +- __func__, status); +- ret = -EPERM; +- goto err_close_services; +- } +- /* Finished with the service for now */ +- vchi_service_release(instance->vchi_handle[i]); +- } +- +- LOG_DBG("%s: okay\n", __func__); +- return instance; ++ status = vchi_service_open(vchi_instance, ¶ms, ++ &instance->vchi_handle); + +-err_close_services: +- for (i = 0; i < instance->num_connections; i++) { +- LOG_ERR("%s: closing %i: %p\n", __func__, i, instance->vchi_handle[i]); +- if (instance->vchi_handle[i]) +- vchi_service_close(instance->vchi_handle[i]); ++ if (status) { ++ LOG_ERR("%s: failed to open VCHI service connection (status=%d)\n", ++ __func__, status); ++ kfree(instance); ++ return ERR_PTR(-EPERM); + } + +- kfree(instance); +- LOG_ERR("%s: error\n", __func__); ++ /* Finished with the service for now */ ++ vchi_service_release(instance->vchi_handle); + +- return ERR_PTR(ret); ++ return instance; + } + + static int vc_vchi_audio_deinit(struct bcm2835_audio_instance *instance) + { +- unsigned int i; +- +- if (!instance) { +- LOG_ERR("%s: invalid handle %p\n", __func__, instance); +- +- return -1; +- } ++ int status; + +- LOG_DBG(" .. about to lock (%d)\n", instance->num_connections); + mutex_lock(&instance->vchi_mutex); + + /* Close all VCHI service connections */ +- for (i = 0; i < instance->num_connections; i++) { +- int status; +- +- LOG_DBG(" .. %i:closing %p\n", i, instance->vchi_handle[i]); +- vchi_service_use(instance->vchi_handle[i]); ++ vchi_service_use(instance->vchi_handle); + +- status = vchi_service_close(instance->vchi_handle[i]); +- if (status) { +- LOG_DBG("%s: failed to close VCHI service connection (status=%d)\n", +- __func__, status); +- } ++ status = vchi_service_close(instance->vchi_handle); ++ if (status) { ++ LOG_DBG("%s: failed to close VCHI service connection (status=%d)\n", ++ __func__, status); + } + + mutex_unlock(&instance->vchi_mutex); +@@ -383,19 +341,9 @@ static int bcm2835_audio_open_connection + (struct bcm2835_audio_instance *)alsa_stream->instance; + struct bcm2835_vchi_ctx *vhci_ctx = alsa_stream->chip->vchi_ctx; + +- LOG_INFO("%s: start\n", __func__); +- BUG_ON(instance); +- if (instance) { +- LOG_ERR("%s: VCHI instance already open (%p)\n", +- __func__, instance); +- instance->alsa_stream = alsa_stream; +- alsa_stream->instance = instance; +- return 0; +- } +- + /* Initialize an instance of the audio service */ + instance = vc_vchi_audio_init(vhci_ctx->vchi_instance, +- &vhci_ctx->vchi_connection, 1); ++ vhci_ctx->vchi_connection); + + if (IS_ERR(instance)) { + LOG_ERR("%s: failed to initialize audio service\n", __func__); +@@ -407,8 +355,6 @@ static int bcm2835_audio_open_connection + instance->alsa_stream = alsa_stream; + alsa_stream->instance = instance; + +- LOG_DBG(" success !\n"); +- + return 0; + } + +@@ -431,12 +377,12 @@ int bcm2835_audio_open(struct bcm2835_al + LOG_DBG(" instance (%p)\n", instance); + + mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle[0]); ++ vchi_service_use(instance->vchi_handle); + + m.type = VC_AUDIO_MSG_TYPE_OPEN; + + /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], ++ status = bcm2835_vchi_msg_queue(instance->vchi_handle, + &m, sizeof(m)); + + if (status) { +@@ -450,7 +396,7 @@ int bcm2835_audio_open(struct bcm2835_al + ret = 0; + + unlock: +- vchi_service_release(instance->vchi_handle[0]); ++ vchi_service_release(instance->vchi_handle); + mutex_unlock(&instance->vchi_mutex); + + free_wq: +@@ -472,7 +418,7 @@ int bcm2835_audio_set_ctls(struct bcm283 + chip->dest, chip->volume); + + mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle[0]); ++ vchi_service_use(instance->vchi_handle); + + instance->result = -1; + +@@ -487,7 +433,7 @@ int bcm2835_audio_set_ctls(struct bcm283 + init_completion(&instance->msg_avail_comp); + + /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], ++ status = bcm2835_vchi_msg_queue(instance->vchi_handle, + &m, sizeof(m)); + + if (status) { +@@ -511,7 +457,7 @@ int bcm2835_audio_set_ctls(struct bcm283 + ret = 0; + + unlock: +- vchi_service_release(instance->vchi_handle[0]); ++ vchi_service_release(instance->vchi_handle); + mutex_unlock(&instance->vchi_mutex); + + return ret; +@@ -537,7 +483,7 @@ int bcm2835_audio_set_params(struct bcm2 + } + + mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle[0]); ++ vchi_service_use(instance->vchi_handle); + + instance->result = -1; + +@@ -550,7 +496,7 @@ int bcm2835_audio_set_params(struct bcm2 + init_completion(&instance->msg_avail_comp); + + /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], ++ status = bcm2835_vchi_msg_queue(instance->vchi_handle, + &m, sizeof(m)); + + if (status) { +@@ -574,7 +520,7 @@ int bcm2835_audio_set_params(struct bcm2 + ret = 0; + + unlock: +- vchi_service_release(instance->vchi_handle[0]); ++ vchi_service_release(instance->vchi_handle); + mutex_unlock(&instance->vchi_mutex); + + return ret; +@@ -588,12 +534,12 @@ static int bcm2835_audio_start_worker(st + int ret; + + mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle[0]); ++ vchi_service_use(instance->vchi_handle); + + m.type = VC_AUDIO_MSG_TYPE_START; + + /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], ++ status = bcm2835_vchi_msg_queue(instance->vchi_handle, + &m, sizeof(m)); + + if (status) { +@@ -607,7 +553,7 @@ static int bcm2835_audio_start_worker(st + ret = 0; + + unlock: +- vchi_service_release(instance->vchi_handle[0]); ++ vchi_service_release(instance->vchi_handle); + mutex_unlock(&instance->vchi_mutex); + return ret; + } +@@ -620,13 +566,13 @@ static int bcm2835_audio_stop_worker(str + int ret; + + mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle[0]); ++ vchi_service_use(instance->vchi_handle); + + m.type = VC_AUDIO_MSG_TYPE_STOP; + m.u.stop.draining = alsa_stream->draining; + + /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], ++ status = bcm2835_vchi_msg_queue(instance->vchi_handle, + &m, sizeof(m)); + + if (status) { +@@ -640,7 +586,7 @@ static int bcm2835_audio_stop_worker(str + ret = 0; + + unlock: +- vchi_service_release(instance->vchi_handle[0]); ++ vchi_service_release(instance->vchi_handle); + mutex_unlock(&instance->vchi_mutex); + return ret; + } +@@ -655,7 +601,7 @@ int bcm2835_audio_close(struct bcm2835_a + my_workqueue_quit(alsa_stream); + + mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle[0]); ++ vchi_service_use(instance->vchi_handle); + + m.type = VC_AUDIO_MSG_TYPE_CLOSE; + +@@ -663,7 +609,7 @@ int bcm2835_audio_close(struct bcm2835_a + init_completion(&instance->msg_avail_comp); + + /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], ++ status = bcm2835_vchi_msg_queue(instance->vchi_handle, + &m, sizeof(m)); + + if (status) { +@@ -687,7 +633,7 @@ int bcm2835_audio_close(struct bcm2835_a + ret = 0; + + unlock: +- vchi_service_release(instance->vchi_handle[0]); ++ vchi_service_release(instance->vchi_handle); + mutex_unlock(&instance->vchi_mutex); + + /* Stop the audio service */ +@@ -708,10 +654,10 @@ static int bcm2835_audio_write_worker(st + LOG_INFO(" Writing %d bytes from %p\n", count, src); + + mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle[0]); ++ vchi_service_use(instance->vchi_handle); + + if (instance->peer_version == 0 && +- vchi_get_peer_version(instance->vchi_handle[0], &instance->peer_version) == 0) ++ vchi_get_peer_version(instance->vchi_handle, &instance->peer_version) == 0) + LOG_DBG("%s: client version %d connected\n", __func__, instance->peer_version); + + m.type = VC_AUDIO_MSG_TYPE_WRITE; +@@ -723,7 +669,7 @@ static int bcm2835_audio_write_worker(st + m.u.write.silence = src == NULL; + + /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], ++ status = bcm2835_vchi_msg_queue(instance->vchi_handle, + &m, sizeof(m)); + + if (status) { +@@ -736,7 +682,7 @@ static int bcm2835_audio_write_worker(st + if (!m.u.write.silence) { + if (!m.u.write.max_packet) { + /* Send the message to the videocore */ +- status = vchi_bulk_queue_transmit(instance->vchi_handle[0], ++ status = vchi_bulk_queue_transmit(instance->vchi_handle, + src, count, + 0 * VCHI_FLAGS_BLOCK_UNTIL_QUEUED + + +@@ -746,7 +692,7 @@ static int bcm2835_audio_write_worker(st + while (count > 0) { + int bytes = min_t(int, m.u.write.max_packet, count); + +- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], ++ status = bcm2835_vchi_msg_queue(instance->vchi_handle, + src, bytes); + src = (char *)src + bytes; + count -= bytes; +@@ -763,7 +709,7 @@ static int bcm2835_audio_write_worker(st + ret = 0; + + unlock: +- vchi_service_release(instance->vchi_handle[0]); ++ vchi_service_release(instance->vchi_handle); + mutex_unlock(&instance->vchi_mutex); + return ret; + } diff --git a/target/linux/brcm2708/patches-4.19/950-0455-staging-bcm2835-audio-Code-refactoring-of-vchiq-acce.patch b/target/linux/brcm2708/patches-4.19/950-0455-staging-bcm2835-audio-Code-refactoring-of-vchiq-acce.patch new file mode 100644 index 0000000000..3ad4aeeb4b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0455-staging-bcm2835-audio-Code-refactoring-of-vchiq-acce.patch @@ -0,0 +1,575 @@ +From 4cb3893de2db276e3db35ad61092c9f9cf2f705d Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:48 +0200 +Subject: [PATCH 455/725] staging: bcm2835-audio: Code refactoring of vchiq + accessor codes + +commit 769a8e9bf5cf39813f52962fdafdf7e4d52ad585 upstream. + +This is a cleanup and code refactoring in bcm2835-vchiq.c. + +The major code changes are to provide local helpers for easier use of +lock / unlock, and message passing with/without response wait. This +allows us to reduce lots of open codes. + +Also, the max packet is set at opening the stream, not at each time +when the write gets called. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../bcm2835-audio/bcm2835-vchiq.c | 440 ++++++------------ + 1 file changed, 142 insertions(+), 298 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +@@ -49,6 +49,7 @@ struct bcm2835_audio_instance { + struct mutex vchi_mutex; + struct bcm2835_alsa_stream *alsa_stream; + int result; ++ unsigned int max_packet; + short peer_version; + }; + +@@ -65,16 +66,68 @@ static int bcm2835_audio_start_worker(st + static int bcm2835_audio_write_worker(struct bcm2835_alsa_stream *alsa_stream, + unsigned int count, void *src); + +-// Routine to send a message across a service ++static void bcm2835_audio_lock(struct bcm2835_audio_instance *instance) ++{ ++ mutex_lock(&instance->vchi_mutex); ++ vchi_service_use(instance->vchi_handle); ++} ++ ++static void bcm2835_audio_unlock(struct bcm2835_audio_instance *instance) ++{ ++ vchi_service_release(instance->vchi_handle); ++ mutex_unlock(&instance->vchi_mutex); ++} ++ ++static int bcm2835_audio_send_msg_locked(struct bcm2835_audio_instance *instance, ++ struct vc_audio_msg *m, bool wait) ++{ ++ int status; ++ ++ if (wait) { ++ instance->result = -1; ++ init_completion(&instance->msg_avail_comp); ++ } ++ ++ status = vchi_queue_kernel_message(instance->vchi_handle, ++ m, sizeof(*m)); ++ if (status) { ++ LOG_ERR("vchi message queue failed: %d, msg=%d\n", ++ status, m->type); ++ return -EIO; ++ } ++ ++ if (wait) { ++ if (!wait_for_completion_timeout(&instance->msg_avail_comp, ++ msecs_to_jiffies(10 * 1000))) { ++ LOG_ERR("vchi message timeout, msg=%d\n", m->type); ++ return -ETIMEDOUT; ++ } else if (instance->result) { ++ LOG_ERR("vchi message response error:%d, msg=%d\n", ++ instance->result, m->type); ++ return -EIO; ++ } ++ } ++ ++ return 0; ++} + +-static int +-bcm2835_vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle, +- void *data, +- unsigned int size) +-{ +- return vchi_queue_kernel_message(handle, +- data, +- size); ++static int bcm2835_audio_send_msg(struct bcm2835_audio_instance *instance, ++ struct vc_audio_msg *m, bool wait) ++{ ++ int err; ++ ++ bcm2835_audio_lock(instance); ++ err = bcm2835_audio_send_msg_locked(instance, m, wait); ++ bcm2835_audio_unlock(instance); ++ return err; ++} ++ ++static int bcm2835_audio_send_simple(struct bcm2835_audio_instance *instance, ++ int type, bool wait) ++{ ++ struct vc_audio_msg m = { .type = type }; ++ ++ return bcm2835_audio_send_msg(instance, &m, wait); + } + + static const u32 BCM2835_AUDIO_WRITE_COOKIE1 = ('B' << 24 | 'C' << 16 | +@@ -283,10 +336,9 @@ static int vc_vchi_audio_deinit(struct b + int status; + + mutex_lock(&instance->vchi_mutex); +- +- /* Close all VCHI service connections */ + vchi_service_use(instance->vchi_handle); + ++ /* Close all VCHI service connections */ + status = vchi_service_close(instance->vchi_handle); + if (status) { + LOG_DBG("%s: failed to close VCHI service connection (status=%d)\n", +@@ -345,12 +397,8 @@ static int bcm2835_audio_open_connection + instance = vc_vchi_audio_init(vhci_ctx->vchi_instance, + vhci_ctx->vchi_connection); + +- if (IS_ERR(instance)) { +- LOG_ERR("%s: failed to initialize audio service\n", __func__); +- +- /* vchi_instance is retained for use the next time. */ ++ if (IS_ERR(instance)) + return PTR_ERR(instance); +- } + + instance->alsa_stream = alsa_stream; + alsa_stream->instance = instance; +@@ -361,66 +409,44 @@ static int bcm2835_audio_open_connection + int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream) + { + struct bcm2835_audio_instance *instance; +- struct vc_audio_msg m; +- int status; +- int ret; ++ int err; + + alsa_stream->my_wq = alloc_workqueue("my_queue", WQ_HIGHPRI, 1); + if (!alsa_stream->my_wq) + return -ENOMEM; + +- ret = bcm2835_audio_open_connection(alsa_stream); +- if (ret) ++ err = bcm2835_audio_open_connection(alsa_stream); ++ if (err < 0) + goto free_wq; + + instance = alsa_stream->instance; +- LOG_DBG(" instance (%p)\n", instance); +- +- mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle); +- +- m.type = VC_AUDIO_MSG_TYPE_OPEN; +- +- /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle, +- &m, sizeof(m)); +- +- if (status) { +- LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", +- __func__, status); +- +- ret = -1; +- goto unlock; +- } +- +- ret = 0; + +-unlock: +- vchi_service_release(instance->vchi_handle); +- mutex_unlock(&instance->vchi_mutex); ++ err = bcm2835_audio_send_simple(instance, VC_AUDIO_MSG_TYPE_OPEN, ++ false); ++ if (err < 0) ++ goto deinit; ++ ++ bcm2835_audio_lock(instance); ++ vchi_get_peer_version(instance->vchi_handle, &instance->peer_version); ++ bcm2835_audio_unlock(instance); ++ if (instance->peer_version < 2 || force_bulk) ++ instance->max_packet = 0; /* bulk transfer */ ++ else ++ instance->max_packet = 4000; + +-free_wq: +- if (ret) +- destroy_workqueue(alsa_stream->my_wq); ++ return 0; + +- return ret; ++ deinit: ++ vc_vchi_audio_deinit(instance); ++ free_wq: ++ destroy_workqueue(alsa_stream->my_wq); ++ return err; + } + + int bcm2835_audio_set_ctls(struct bcm2835_alsa_stream *alsa_stream) + { +- struct vc_audio_msg m; +- struct bcm2835_audio_instance *instance = alsa_stream->instance; + struct bcm2835_chip *chip = alsa_stream->chip; +- int status; +- int ret; +- +- LOG_INFO(" Setting ALSA dest(%d), volume(%d)\n", +- chip->dest, chip->volume); +- +- mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle); +- +- instance->result = -1; ++ struct vc_audio_msg m = {}; + + m.type = VC_AUDIO_MSG_TYPE_CONTROL; + m.u.control.dest = chip->dest; +@@ -429,289 +455,107 @@ int bcm2835_audio_set_ctls(struct bcm283 + else + m.u.control.volume = alsa2chip(chip->volume); + +- /* Create the message available completion */ +- init_completion(&instance->msg_avail_comp); +- +- /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle, +- &m, sizeof(m)); +- +- if (status) { +- LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", +- __func__, status); +- +- ret = -1; +- goto unlock; +- } +- +- /* We are expecting a reply from the videocore */ +- wait_for_completion(&instance->msg_avail_comp); +- +- if (instance->result) { +- LOG_ERR("%s: result=%d\n", __func__, instance->result); +- +- ret = -1; +- goto unlock; +- } +- +- ret = 0; +- +-unlock: +- vchi_service_release(instance->vchi_handle); +- mutex_unlock(&instance->vchi_mutex); +- +- return ret; ++ return bcm2835_audio_send_msg(alsa_stream->instance, &m, true); + } + + int bcm2835_audio_set_params(struct bcm2835_alsa_stream *alsa_stream, + unsigned int channels, unsigned int samplerate, + unsigned int bps) + { +- struct vc_audio_msg m; +- struct bcm2835_audio_instance *instance = alsa_stream->instance; +- int status; +- int ret; +- +- LOG_INFO(" Setting ALSA channels(%d), samplerate(%d), bits-per-sample(%d)\n", +- channels, samplerate, bps); ++ struct vc_audio_msg m = { ++ .type = VC_AUDIO_MSG_TYPE_CONFIG, ++ .u.config.channels = channels, ++ .u.config.samplerate = samplerate, ++ .u.config.bps = bps, ++ }; ++ int err; + + /* resend ctls - alsa_stream may not have been open when first send */ +- ret = bcm2835_audio_set_ctls(alsa_stream); +- if (ret) { +- LOG_ERR(" Alsa controls not supported\n"); +- return -EINVAL; +- } ++ err = bcm2835_audio_set_ctls(alsa_stream); ++ if (err) ++ return err; + +- mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle); +- +- instance->result = -1; +- +- m.type = VC_AUDIO_MSG_TYPE_CONFIG; +- m.u.config.channels = channels; +- m.u.config.samplerate = samplerate; +- m.u.config.bps = bps; +- +- /* Create the message available completion */ +- init_completion(&instance->msg_avail_comp); +- +- /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle, +- &m, sizeof(m)); +- +- if (status) { +- LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", +- __func__, status); +- +- ret = -1; +- goto unlock; +- } +- +- /* We are expecting a reply from the videocore */ +- wait_for_completion(&instance->msg_avail_comp); +- +- if (instance->result) { +- LOG_ERR("%s: result=%d", __func__, instance->result); +- +- ret = -1; +- goto unlock; +- } +- +- ret = 0; +- +-unlock: +- vchi_service_release(instance->vchi_handle); +- mutex_unlock(&instance->vchi_mutex); +- +- return ret; ++ return bcm2835_audio_send_msg(alsa_stream->instance, &m, true); + } + + static int bcm2835_audio_start_worker(struct bcm2835_alsa_stream *alsa_stream) + { +- struct vc_audio_msg m; +- struct bcm2835_audio_instance *instance = alsa_stream->instance; +- int status; +- int ret; +- +- mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle); +- +- m.type = VC_AUDIO_MSG_TYPE_START; +- +- /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle, +- &m, sizeof(m)); +- +- if (status) { +- LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", +- __func__, status); +- +- ret = -1; +- goto unlock; +- } +- +- ret = 0; +- +-unlock: +- vchi_service_release(instance->vchi_handle); +- mutex_unlock(&instance->vchi_mutex); +- return ret; ++ return bcm2835_audio_send_simple(alsa_stream->instance, ++ VC_AUDIO_MSG_TYPE_START, false); + } + + static int bcm2835_audio_stop_worker(struct bcm2835_alsa_stream *alsa_stream) + { +- struct vc_audio_msg m; +- struct bcm2835_audio_instance *instance = alsa_stream->instance; +- int status; +- int ret; +- +- mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle); +- +- m.type = VC_AUDIO_MSG_TYPE_STOP; +- m.u.stop.draining = alsa_stream->draining; +- +- /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle, +- &m, sizeof(m)); +- +- if (status) { +- LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", +- __func__, status); +- +- ret = -1; +- goto unlock; +- } +- +- ret = 0; +- +-unlock: +- vchi_service_release(instance->vchi_handle); +- mutex_unlock(&instance->vchi_mutex); +- return ret; ++ return bcm2835_audio_send_simple(alsa_stream->instance, ++ VC_AUDIO_MSG_TYPE_STOP, false); + } + + int bcm2835_audio_close(struct bcm2835_alsa_stream *alsa_stream) + { +- struct vc_audio_msg m; + struct bcm2835_audio_instance *instance = alsa_stream->instance; +- int status; +- int ret; ++ int err; + + my_workqueue_quit(alsa_stream); + +- mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle); +- +- m.type = VC_AUDIO_MSG_TYPE_CLOSE; +- +- /* Create the message available completion */ +- init_completion(&instance->msg_avail_comp); +- +- /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle, +- &m, sizeof(m)); +- +- if (status) { +- LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", +- __func__, status); +- ret = -1; +- goto unlock; +- } +- +- /* We are expecting a reply from the videocore */ +- wait_for_completion(&instance->msg_avail_comp); +- +- if (instance->result) { +- LOG_ERR("%s: failed result (result=%d)\n", +- __func__, instance->result); +- +- ret = -1; +- goto unlock; +- } +- +- ret = 0; +- +-unlock: +- vchi_service_release(instance->vchi_handle); +- mutex_unlock(&instance->vchi_mutex); ++ err = bcm2835_audio_send_simple(alsa_stream->instance, ++ VC_AUDIO_MSG_TYPE_CLOSE, true); + + /* Stop the audio service */ + vc_vchi_audio_deinit(instance); + alsa_stream->instance = NULL; + +- return ret; ++ return err; + } + + static int bcm2835_audio_write_worker(struct bcm2835_alsa_stream *alsa_stream, +- unsigned int count, void *src) ++ unsigned int size, void *src) + { +- struct vc_audio_msg m; + struct bcm2835_audio_instance *instance = alsa_stream->instance; +- int status; +- int ret; +- +- LOG_INFO(" Writing %d bytes from %p\n", count, src); +- +- mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle); ++ struct vc_audio_msg m = { ++ .type = VC_AUDIO_MSG_TYPE_WRITE, ++ .u.write.count = size, ++ .u.write.max_packet = instance->max_packet, ++ .u.write.cookie1 = BCM2835_AUDIO_WRITE_COOKIE1, ++ .u.write.cookie2 = BCM2835_AUDIO_WRITE_COOKIE2, ++ }; ++ unsigned int count; ++ int err, status; + +- if (instance->peer_version == 0 && +- vchi_get_peer_version(instance->vchi_handle, &instance->peer_version) == 0) +- LOG_DBG("%s: client version %d connected\n", __func__, instance->peer_version); +- +- m.type = VC_AUDIO_MSG_TYPE_WRITE; +- m.u.write.count = count; +- // old version uses bulk, new version uses control +- m.u.write.max_packet = instance->peer_version < 2 || force_bulk ? 0 : 4000; +- m.u.write.cookie1 = BCM2835_AUDIO_WRITE_COOKIE1; +- m.u.write.cookie2 = BCM2835_AUDIO_WRITE_COOKIE2; +- m.u.write.silence = src == NULL; +- +- /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle, +- &m, sizeof(m)); ++ if (!size) ++ return 0; + +- if (status) { +- LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", +- __func__, status); +- +- ret = -1; ++ bcm2835_audio_lock(instance); ++ err = bcm2835_audio_send_msg_locked(instance, &m, false); ++ if (err < 0) + goto unlock; +- } +- if (!m.u.write.silence) { +- if (!m.u.write.max_packet) { +- /* Send the message to the videocore */ +- status = vchi_bulk_queue_transmit(instance->vchi_handle, +- src, count, +- 0 * VCHI_FLAGS_BLOCK_UNTIL_QUEUED +- + +- 1 * VCHI_FLAGS_BLOCK_UNTIL_DATA_READ, +- NULL); +- } else { +- while (count > 0) { +- int bytes = min_t(int, m.u.write.max_packet, count); + +- status = bcm2835_vchi_msg_queue(instance->vchi_handle, +- src, bytes); +- src = (char *)src + bytes; +- count -= bytes; +- } +- } +- if (status) { +- LOG_ERR("%s: failed on vchi_bulk_queue_transmit (status=%d)\n", +- __func__, status); ++ count = size; ++ if (!instance->max_packet) { ++ /* Send the message to the videocore */ ++ status = vchi_bulk_queue_transmit(instance->vchi_handle, ++ src, count, ++ VCHI_FLAGS_BLOCK_UNTIL_DATA_READ, ++ NULL); ++ } else { ++ while (count > 0) { ++ int bytes = min(instance->max_packet, count); + +- ret = -1; +- goto unlock; ++ status = vchi_queue_kernel_message(instance->vchi_handle, ++ src, bytes); ++ src += bytes; ++ count -= bytes; + } + } +- ret = 0; + +-unlock: +- vchi_service_release(instance->vchi_handle); +- mutex_unlock(&instance->vchi_mutex); +- return ret; ++ if (status) { ++ LOG_ERR("failed on %d bytes transfer (status=%d)\n", ++ size, status); ++ err = -EIO; ++ } ++ ++ unlock: ++ bcm2835_audio_unlock(instance); ++ return err; + } + + unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream) diff --git a/target/linux/brcm2708/patches-4.19/950-0455-staging-bcm2835-audio-Drop-superfluous-mutex-lock-du.patch b/target/linux/brcm2708/patches-4.19/950-0455-staging-bcm2835-audio-Drop-superfluous-mutex-lock-du.patch deleted file mode 100644 index 6a36ee056e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0455-staging-bcm2835-audio-Drop-superfluous-mutex-lock-du.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 1eb403fb6c5f6b8bea96e9bd0d6b87949aab172f Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:45 +0200 -Subject: [PATCH 455/703] staging: bcm2835-audio: Drop superfluous mutex lock - during prepare - -commit f0eb15d055380ff127e5f12c8fad2b36bdb3c006 upstream. - -The chip->audio_mutex is used basically for protecting the opened -stream assignment, and the prepare callback is irrelevant with it. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -218,8 +218,6 @@ static int snd_bcm2835_pcm_prepare(struc - int channels; - int err; - -- mutex_lock(&chip->audio_mutex); -- - /* notify the vchiq that it should enter spdif passthrough mode by - * setting channels=0 (see - * https://github.com/raspberrypi/linux/issues/528) -@@ -233,7 +231,7 @@ static int snd_bcm2835_pcm_prepare(struc - runtime->rate, - snd_pcm_format_width(runtime->format)); - if (err < 0) -- goto out; -+ return err; - - memset(&alsa_stream->pcm_indirect, 0, sizeof(alsa_stream->pcm_indirect)); - -@@ -246,9 +244,7 @@ static int snd_bcm2835_pcm_prepare(struc - alsa_stream->pos = 0; - alsa_stream->draining = false; - -- out: -- mutex_unlock(&chip->audio_mutex); -- return err; -+ return 0; - } - - static void snd_bcm2835_pcm_transfer(struct snd_pcm_substream *substream, diff --git a/target/linux/brcm2708/patches-4.19/950-0456-staging-bcm2835-audio-Add-10ms-period-constraint.patch b/target/linux/brcm2708/patches-4.19/950-0456-staging-bcm2835-audio-Add-10ms-period-constraint.patch deleted file mode 100644 index 7549032b39..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0456-staging-bcm2835-audio-Add-10ms-period-constraint.patch +++ /dev/null @@ -1,33 +0,0 @@ -From c0c56af886a1f7078dcd78ab46d7480009b080a2 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:46 +0200 -Subject: [PATCH 456/703] staging: bcm2835-audio: Add 10ms period constraint - -commit 93c66acaf68b5247c3121a46a71ff6a70fc1d492 upstream. - -It seems that the resolution of vc04 callback is in 10 msec; i.e. the -minimal period size is also 10 msec. - -This patch adds the corresponding hw constraint. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -145,6 +145,11 @@ static int snd_bcm2835_playback_open_gen - SNDRV_PCM_HW_PARAM_PERIOD_BYTES, - 16); - -+ /* position update is in 10ms order */ -+ snd_pcm_hw_constraint_minmax(runtime, -+ SNDRV_PCM_HW_PARAM_PERIOD_TIME, -+ 10 * 1000, UINT_MAX); -+ - chip->alsa_stream[idx] = alsa_stream; - - chip->opened |= (1 << idx); diff --git a/target/linux/brcm2708/patches-4.19/950-0456-staging-bcm2835-audio-Operate-non-atomic-PCM-ops.patch b/target/linux/brcm2708/patches-4.19/950-0456-staging-bcm2835-audio-Operate-non-atomic-PCM-ops.patch new file mode 100644 index 0000000000..e9330645bb --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0456-staging-bcm2835-audio-Operate-non-atomic-PCM-ops.patch @@ -0,0 +1,593 @@ +From 43fad60114297457914dae77debd68ed185f66e9 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:49 +0200 +Subject: [PATCH 456/725] staging: bcm2835-audio: Operate non-atomic PCM ops + +commit 5c7883e5f27e829f3f3a2ba174d4a724bfd5f026 upstream. + +This is the most significant part in the patch series. + +The bcm2835-audio driver used to queue the commands to vc04 core via +workqueue, but basically the whole accesses to vc04 core are done in +the sleepable context, including the callback calls. In such a case, +rewriting the code using non-atomic PCM ops will simplify the logic a +lot. + +This patch does it: all workqueue are gone and each former-work +implementation is now directly called from PCM ops like trigger and +write transfer. + +Along with it, the DMA position updater, bcm2835_playback_fifo(), was +also rewritten to use a simpler logic. Now it handles the XRUN and +draining properly by calling snd_pcm_stop() conditionally. + +The current position is kept in atomic_t value so that it can be read +concurrently from the pointer callback. + +Also, the bcm2835_audio_instance object is allocated at the beginning +of bcm2835_audio_open(). This makes the resource management clearer. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 74 +++--- + .../bcm2835-audio/bcm2835-vchiq.c | 244 +++--------------- + .../vc04_services/bcm2835-audio/bcm2835.h | 9 +- + 3 files changed, 82 insertions(+), 245 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -11,7 +11,8 @@ + /* hardware definition */ + static const struct snd_pcm_hardware snd_bcm2835_playback_hw = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | +- SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), ++ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | ++ SNDRV_PCM_INFO_DRAIN_TRIGGER), + .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, + .rate_min = 8000, +@@ -27,7 +28,8 @@ static const struct snd_pcm_hardware snd + + static const struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | +- SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), ++ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | ++ SNDRV_PCM_INFO_DRAIN_TRIGGER), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000, +@@ -47,42 +49,34 @@ static void snd_bcm2835_playback_free(st + kfree(runtime->private_data); + } + +-void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream) ++void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream, ++ unsigned int bytes) + { +- unsigned int consumed = 0; +- int new_period = 0; ++ struct snd_pcm_substream *substream = alsa_stream->substream; ++ unsigned int pos; + +- audio_info("alsa_stream=%p substream=%p\n", alsa_stream, +- alsa_stream ? alsa_stream->substream : 0); ++ if (!alsa_stream->period_size) ++ return; + +- consumed = bcm2835_audio_retrieve_buffers(alsa_stream); +- +- /* We get called only if playback was triggered, So, the number of buffers we retrieve in +- * each iteration are the buffers that have been played out already +- */ +- +- if (alsa_stream->period_size) { +- if ((alsa_stream->pos / alsa_stream->period_size) != +- ((alsa_stream->pos + consumed) / alsa_stream->period_size)) +- new_period = 1; +- } +- audio_debug("updating pos cur: %d + %d max:%d period_bytes:%d, hw_ptr: %d new_period:%d\n", +- alsa_stream->pos, +- consumed, +- alsa_stream->buffer_size, +- (int) (alsa_stream->period_size * alsa_stream->substream->runtime->periods), +- frames_to_bytes(alsa_stream->substream->runtime, alsa_stream->substream->runtime->status->hw_ptr), +- new_period); +- if (alsa_stream->buffer_size) { +- alsa_stream->pos += consumed & ~(1 << 30); +- alsa_stream->pos %= alsa_stream->buffer_size; ++ if (bytes >= alsa_stream->buffer_size) { ++ snd_pcm_stream_lock(substream); ++ snd_pcm_stop(substream, ++ alsa_stream->draining ? ++ SNDRV_PCM_STATE_SETUP : ++ SNDRV_PCM_STATE_XRUN); ++ snd_pcm_stream_unlock(substream); ++ return; + } + +- if (alsa_stream->substream) { +- if (new_period) +- snd_pcm_period_elapsed(alsa_stream->substream); +- } else { +- audio_warning(" unexpected NULL substream\n"); ++ pos = atomic_read(&alsa_stream->pos); ++ pos += bytes; ++ pos %= alsa_stream->buffer_size; ++ atomic_set(&alsa_stream->pos, pos); ++ ++ alsa_stream->period_offset += bytes; ++ if (alsa_stream->period_offset >= alsa_stream->period_size) { ++ alsa_stream->period_offset %= alsa_stream->period_size; ++ snd_pcm_period_elapsed(substream); + } + } + +@@ -246,7 +240,8 @@ static int snd_bcm2835_pcm_prepare(struc + + alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream); + alsa_stream->period_size = snd_pcm_lib_period_bytes(substream); +- alsa_stream->pos = 0; ++ atomic_set(&alsa_stream->pos, 0); ++ alsa_stream->period_offset = 0; + alsa_stream->draining = false; + + return 0; +@@ -283,7 +278,7 @@ static int snd_bcm2835_pcm_trigger(struc + return bcm2835_audio_start(alsa_stream); + case SNDRV_PCM_TRIGGER_DRAIN: + alsa_stream->draining = true; +- return 0; ++ return bcm2835_audio_drain(alsa_stream); + case SNDRV_PCM_TRIGGER_STOP: + return bcm2835_audio_stop(alsa_stream); + default: +@@ -300,7 +295,7 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_s + + return snd_pcm_indirect_playback_pointer(substream, + &alsa_stream->pcm_indirect, +- alsa_stream->pos); ++ atomic_read(&alsa_stream->pos)); + } + + /* operators */ +@@ -338,6 +333,7 @@ int snd_bcm2835_new_pcm(struct bcm2835_c + if (err < 0) + return err; + pcm->private_data = chip; ++ pcm->nonatomic = true; + strcpy(pcm->name, "bcm2835 ALSA"); + chip->pcm = pcm; + chip->dest = AUDIO_DEST_AUTO; +@@ -367,6 +363,7 @@ int snd_bcm2835_new_spdif_pcm(struct bcm + return err; + + pcm->private_data = chip; ++ pcm->nonatomic = true; + strcpy(pcm->name, "bcm2835 IEC958/HDMI"); + chip->pcm_spdif = pcm; + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, +@@ -395,6 +392,7 @@ int snd_bcm2835_new_simple_pcm(struct bc + return err; + + pcm->private_data = chip; ++ pcm->nonatomic = true; + strcpy(pcm->name, name); + chip->pcm = pcm; + chip->dest = route; +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +@@ -26,10 +26,6 @@ + + /* ---- Private Constants and Types ------------------------------------------ */ + +-#define BCM2835_AUDIO_STOP 0 +-#define BCM2835_AUDIO_START 1 +-#define BCM2835_AUDIO_WRITE 2 +- + /* Logging macros (for remapping to other logging mechanisms, i.e., printf) */ + #ifdef AUDIO_DEBUG_ENABLE + #define LOG_ERR(fmt, arg...) pr_err("%s:%d " fmt, __func__, __LINE__, ##arg) +@@ -55,17 +51,6 @@ struct bcm2835_audio_instance { + + static bool force_bulk; + +-/* ---- Private Variables ---------------------------------------------------- */ +- +-/* ---- Private Function Prototypes ------------------------------------------ */ +- +-/* ---- Private Functions ---------------------------------------------------- */ +- +-static int bcm2835_audio_stop_worker(struct bcm2835_alsa_stream *alsa_stream); +-static int bcm2835_audio_start_worker(struct bcm2835_alsa_stream *alsa_stream); +-static int bcm2835_audio_write_worker(struct bcm2835_alsa_stream *alsa_stream, +- unsigned int count, void *src); +- + static void bcm2835_audio_lock(struct bcm2835_audio_instance *instance) + { + mutex_lock(&instance->vchi_mutex); +@@ -135,108 +120,6 @@ static const u32 BCM2835_AUDIO_WRITE_COO + static const u32 BCM2835_AUDIO_WRITE_COOKIE2 = ('D' << 24 | 'A' << 16 | + 'T' << 8 | 'A'); + +-struct bcm2835_audio_work { +- struct work_struct my_work; +- struct bcm2835_alsa_stream *alsa_stream; +- int cmd; +- void *src; +- unsigned int count; +-}; +- +-static void my_wq_function(struct work_struct *work) +-{ +- struct bcm2835_audio_work *w = +- container_of(work, struct bcm2835_audio_work, my_work); +- int ret = -9; +- +- switch (w->cmd) { +- case BCM2835_AUDIO_START: +- ret = bcm2835_audio_start_worker(w->alsa_stream); +- break; +- case BCM2835_AUDIO_STOP: +- ret = bcm2835_audio_stop_worker(w->alsa_stream); +- break; +- case BCM2835_AUDIO_WRITE: +- ret = bcm2835_audio_write_worker(w->alsa_stream, w->count, +- w->src); +- break; +- default: +- LOG_ERR(" Unexpected work: %p:%d\n", w->alsa_stream, w->cmd); +- break; +- } +- kfree((void *)work); +-} +- +-int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream) +-{ +- struct bcm2835_audio_work *work; +- +- work = kmalloc(sizeof(*work), GFP_ATOMIC); +- /*--- Queue some work (item 1) ---*/ +- if (!work) { +- LOG_ERR(" .. Error: NULL work kmalloc\n"); +- return -ENOMEM; +- } +- INIT_WORK(&work->my_work, my_wq_function); +- work->alsa_stream = alsa_stream; +- work->cmd = BCM2835_AUDIO_START; +- if (!queue_work(alsa_stream->my_wq, &work->my_work)) { +- kfree(work); +- return -EBUSY; +- } +- return 0; +-} +- +-int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream) +-{ +- struct bcm2835_audio_work *work; +- +- work = kmalloc(sizeof(*work), GFP_ATOMIC); +- /*--- Queue some work (item 1) ---*/ +- if (!work) { +- LOG_ERR(" .. Error: NULL work kmalloc\n"); +- return -ENOMEM; +- } +- INIT_WORK(&work->my_work, my_wq_function); +- work->alsa_stream = alsa_stream; +- work->cmd = BCM2835_AUDIO_STOP; +- if (!queue_work(alsa_stream->my_wq, &work->my_work)) { +- kfree(work); +- return -EBUSY; +- } +- return 0; +-} +- +-int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream, +- unsigned int count, void *src) +-{ +- struct bcm2835_audio_work *work; +- +- work = kmalloc(sizeof(*work), GFP_ATOMIC); +- /*--- Queue some work (item 1) ---*/ +- if (!work) { +- LOG_ERR(" .. Error: NULL work kmalloc\n"); +- return -ENOMEM; +- } +- INIT_WORK(&work->my_work, my_wq_function); +- work->alsa_stream = alsa_stream; +- work->cmd = BCM2835_AUDIO_WRITE; +- work->src = src; +- work->count = count; +- if (!queue_work(alsa_stream->my_wq, &work->my_work)) { +- kfree(work); +- return -EBUSY; +- } +- return 0; +-} +- +-static void my_workqueue_quit(struct bcm2835_alsa_stream *alsa_stream) +-{ +- flush_workqueue(alsa_stream->my_wq); +- destroy_workqueue(alsa_stream->my_wq); +- alsa_stream->my_wq = NULL; +-} +- + static void audio_vchi_callback(void *param, + const VCHI_CALLBACK_REASON_T reason, + void *msg_handle) +@@ -249,47 +132,27 @@ static void audio_vchi_callback(void *pa + if (reason != VCHI_CALLBACK_MSG_AVAILABLE) + return; + +- if (!instance) { +- LOG_ERR(" .. instance is null\n"); +- BUG(); +- return; +- } +- if (!instance->vchi_handle) { +- LOG_ERR(" .. instance->vchi_handle is null\n"); +- BUG(); +- return; +- } + status = vchi_msg_dequeue(instance->vchi_handle, + &m, sizeof(m), &msg_len, VCHI_FLAGS_NONE); + if (m.type == VC_AUDIO_MSG_TYPE_RESULT) { +- LOG_DBG(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_RESULT, success=%d\n", +- instance, m.u.result.success); + instance->result = m.u.result.success; + complete(&instance->msg_avail_comp); + } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) { +- struct bcm2835_alsa_stream *alsa_stream = instance->alsa_stream; +- +- LOG_DBG(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_COMPLETE, complete=%d\n", +- instance, m.u.complete.count); + if (m.u.complete.cookie1 != BCM2835_AUDIO_WRITE_COOKIE1 || + m.u.complete.cookie2 != BCM2835_AUDIO_WRITE_COOKIE2) +- LOG_ERR(" .. response is corrupt\n"); +- else if (alsa_stream) { +- atomic_add(m.u.complete.count, +- &alsa_stream->retrieved); +- bcm2835_playback_fifo(alsa_stream); +- } else { +- LOG_ERR(" .. unexpected alsa_stream=%p\n", +- alsa_stream); +- } ++ LOG_ERR("invalid cookie\n"); ++ else ++ bcm2835_playback_fifo(instance->alsa_stream, ++ m.u.complete.count); + } else { +- LOG_ERR(" .. unexpected m.type=%d\n", m.type); ++ LOG_ERR("unexpected callback type=%d\n", m.type); + } + } + +-static struct bcm2835_audio_instance * ++static int + vc_vchi_audio_init(VCHI_INSTANCE_T vchi_instance, +- VCHI_CONNECTION_T *vchi_connection) ++ VCHI_CONNECTION_T *vchi_connection, ++ struct bcm2835_audio_instance *instance) + { + SERVICE_CREATION_T params = { + .version = VCHI_VERSION_EX(VC_AUDIOSERV_VER, VC_AUDIOSERV_MIN_VER), +@@ -298,23 +161,14 @@ vc_vchi_audio_init(VCHI_INSTANCE_T vchi_ + .rx_fifo_size = 0, + .tx_fifo_size = 0, + .callback = audio_vchi_callback, ++ .callback_param = instance, + .want_unaligned_bulk_rx = 1, //TODO: remove VCOS_FALSE + .want_unaligned_bulk_tx = 1, //TODO: remove VCOS_FALSE + .want_crc = 0 + }; +- struct bcm2835_audio_instance *instance; + int status; + +- /* Allocate memory for this instance */ +- instance = kzalloc(sizeof(*instance), GFP_KERNEL); +- if (!instance) +- return ERR_PTR(-ENOMEM); +- +- /* Create a lock for exclusive, serialized VCHI connection access */ +- mutex_init(&instance->vchi_mutex); + /* Open the VCHI service connections */ +- params.callback_param = instance, +- + status = vchi_service_open(vchi_instance, ¶ms, + &instance->vchi_handle); + +@@ -322,16 +176,16 @@ vc_vchi_audio_init(VCHI_INSTANCE_T vchi_ + LOG_ERR("%s: failed to open VCHI service connection (status=%d)\n", + __func__, status); + kfree(instance); +- return ERR_PTR(-EPERM); ++ return -EPERM; + } + + /* Finished with the service for now */ + vchi_service_release(instance->vchi_handle); + +- return instance; ++ return 0; + } + +-static int vc_vchi_audio_deinit(struct bcm2835_audio_instance *instance) ++static void vc_vchi_audio_deinit(struct bcm2835_audio_instance *instance) + { + int status; + +@@ -346,10 +200,6 @@ static int vc_vchi_audio_deinit(struct b + } + + mutex_unlock(&instance->vchi_mutex); +- +- kfree(instance); +- +- return 0; + } + + int bcm2835_new_vchi_ctx(struct bcm2835_vchi_ctx *vchi_ctx) +@@ -387,39 +237,25 @@ void bcm2835_free_vchi_ctx(struct bcm283 + vchi_ctx->vchi_instance = NULL; + } + +-static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream) +-{ +- struct bcm2835_audio_instance *instance = +- (struct bcm2835_audio_instance *)alsa_stream->instance; +- struct bcm2835_vchi_ctx *vhci_ctx = alsa_stream->chip->vchi_ctx; +- +- /* Initialize an instance of the audio service */ +- instance = vc_vchi_audio_init(vhci_ctx->vchi_instance, +- vhci_ctx->vchi_connection); +- +- if (IS_ERR(instance)) +- return PTR_ERR(instance); +- +- instance->alsa_stream = alsa_stream; +- alsa_stream->instance = instance; +- +- return 0; +-} +- + int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream) + { ++ struct bcm2835_vchi_ctx *vchi_ctx = alsa_stream->chip->vchi_ctx; + struct bcm2835_audio_instance *instance; + int err; + +- alsa_stream->my_wq = alloc_workqueue("my_queue", WQ_HIGHPRI, 1); +- if (!alsa_stream->my_wq) ++ /* Allocate memory for this instance */ ++ instance = kzalloc(sizeof(*instance), GFP_KERNEL); ++ if (!instance) + return -ENOMEM; ++ mutex_init(&instance->vchi_mutex); ++ instance->alsa_stream = alsa_stream; ++ alsa_stream->instance = instance; + +- err = bcm2835_audio_open_connection(alsa_stream); ++ err = vc_vchi_audio_init(vchi_ctx->vchi_instance, ++ vchi_ctx->vchi_connection, ++ instance); + if (err < 0) +- goto free_wq; +- +- instance = alsa_stream->instance; ++ goto free_instance; + + err = bcm2835_audio_send_simple(instance, VC_AUDIO_MSG_TYPE_OPEN, + false); +@@ -438,8 +274,9 @@ int bcm2835_audio_open(struct bcm2835_al + + deinit: + vc_vchi_audio_deinit(instance); +- free_wq: +- destroy_workqueue(alsa_stream->my_wq); ++ free_instance: ++ alsa_stream->instance = NULL; ++ kfree(instance); + return err; + } + +@@ -478,37 +315,46 @@ int bcm2835_audio_set_params(struct bcm2 + return bcm2835_audio_send_msg(alsa_stream->instance, &m, true); + } + +-static int bcm2835_audio_start_worker(struct bcm2835_alsa_stream *alsa_stream) ++int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream) + { + return bcm2835_audio_send_simple(alsa_stream->instance, + VC_AUDIO_MSG_TYPE_START, false); + } + +-static int bcm2835_audio_stop_worker(struct bcm2835_alsa_stream *alsa_stream) ++int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream) + { + return bcm2835_audio_send_simple(alsa_stream->instance, + VC_AUDIO_MSG_TYPE_STOP, false); + } + ++int bcm2835_audio_drain(struct bcm2835_alsa_stream *alsa_stream) ++{ ++ struct vc_audio_msg m = { ++ .type = VC_AUDIO_MSG_TYPE_STOP, ++ .u.stop.draining = 1, ++ }; ++ ++ return bcm2835_audio_send_msg(alsa_stream->instance, &m, false); ++} ++ + int bcm2835_audio_close(struct bcm2835_alsa_stream *alsa_stream) + { + struct bcm2835_audio_instance *instance = alsa_stream->instance; + int err; + +- my_workqueue_quit(alsa_stream); +- + err = bcm2835_audio_send_simple(alsa_stream->instance, + VC_AUDIO_MSG_TYPE_CLOSE, true); + + /* Stop the audio service */ + vc_vchi_audio_deinit(instance); + alsa_stream->instance = NULL; ++ kfree(instance); + + return err; + } + +-static int bcm2835_audio_write_worker(struct bcm2835_alsa_stream *alsa_stream, +- unsigned int size, void *src) ++int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream, ++ unsigned int size, void *src) + { + struct bcm2835_audio_instance *instance = alsa_stream->instance; + struct vc_audio_msg m = { +@@ -558,13 +404,5 @@ static int bcm2835_audio_write_worker(st + return err; + } + +-unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream) +-{ +- unsigned int count = atomic_read(&alsa_stream->retrieved); +- +- atomic_sub(count, &alsa_stream->retrieved); +- return count; +-} +- + module_param(force_bulk, bool, 0444); + MODULE_PARM_DESC(force_bulk, "Force use of vchiq bulk for audio"); +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h +@@ -121,13 +121,12 @@ struct bcm2835_alsa_stream { + + int draining; + +- unsigned int pos; ++ atomic_t pos; ++ unsigned int period_offset; + unsigned int buffer_size; + unsigned int period_size; + +- atomic_t retrieved; + struct bcm2835_audio_instance *instance; +- struct workqueue_struct *my_wq; + int idx; + }; + +@@ -152,11 +151,13 @@ int bcm2835_audio_set_params(struct bcm2 + unsigned int bps); + int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream); + int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream); ++int bcm2835_audio_drain(struct bcm2835_alsa_stream *alsa_stream); + int bcm2835_audio_set_ctls(struct bcm2835_alsa_stream *alsa_stream); + int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream, + unsigned int count, + void *src); +-void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream); ++void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream, ++ unsigned int size); + unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream); + + #endif /* __SOUND_ARM_BCM2835_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0457-staging-bcm2835-audio-Make-single-vchi-handle.patch b/target/linux/brcm2708/patches-4.19/950-0457-staging-bcm2835-audio-Make-single-vchi-handle.patch deleted file mode 100644 index 6b0e3715ed..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0457-staging-bcm2835-audio-Make-single-vchi-handle.patch +++ /dev/null @@ -1,412 +0,0 @@ -From 8456d764799cf7bc661892900cb08b3943e3bda2 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:47 +0200 -Subject: [PATCH 457/703] staging: bcm2835-audio: Make single vchi handle - -commit 326a6edcb2ada56375bd7d3fc24c83f58e8da7f3 upstream. - -The bcm2835_audio_instance object contains the array of -VCHI_SERVICE_HANDLE_T, while the code assumes and uses only the first -element explicitly. Let's reduce to a single vchi handle for -simplifying the code. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../bcm2835-audio/bcm2835-vchiq.c | 170 ++++++------------ - 1 file changed, 58 insertions(+), 112 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -@@ -44,8 +44,7 @@ - #endif - - struct bcm2835_audio_instance { -- unsigned int num_connections; -- VCHI_SERVICE_HANDLE_T vchi_handle[VCHI_MAX_NUM_CONNECTIONS]; -+ VCHI_SERVICE_HANDLE_T vchi_handle; - struct completion msg_avail_comp; - struct mutex vchi_mutex; - struct bcm2835_alsa_stream *alsa_stream; -@@ -202,12 +201,12 @@ static void audio_vchi_callback(void *pa - BUG(); - return; - } -- if (!instance->vchi_handle[0]) { -- LOG_ERR(" .. instance->vchi_handle[0] is null\n"); -+ if (!instance->vchi_handle) { -+ LOG_ERR(" .. instance->vchi_handle is null\n"); - BUG(); - return; - } -- status = vchi_msg_dequeue(instance->vchi_handle[0], -+ status = vchi_msg_dequeue(instance->vchi_handle, - &m, sizeof(m), &msg_len, VCHI_FLAGS_NONE); - if (m.type == VC_AUDIO_MSG_TYPE_RESULT) { - LOG_DBG(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_RESULT, success=%d\n", -@@ -237,102 +236,61 @@ static void audio_vchi_callback(void *pa - - static struct bcm2835_audio_instance * - vc_vchi_audio_init(VCHI_INSTANCE_T vchi_instance, -- VCHI_CONNECTION_T **vchi_connections, -- unsigned int num_connections) -+ VCHI_CONNECTION_T *vchi_connection) - { -- unsigned int i; -+ SERVICE_CREATION_T params = { -+ .version = VCHI_VERSION_EX(VC_AUDIOSERV_VER, VC_AUDIOSERV_MIN_VER), -+ .service_id = VC_AUDIO_SERVER_NAME, -+ .connection = vchi_connection, -+ .rx_fifo_size = 0, -+ .tx_fifo_size = 0, -+ .callback = audio_vchi_callback, -+ .want_unaligned_bulk_rx = 1, //TODO: remove VCOS_FALSE -+ .want_unaligned_bulk_tx = 1, //TODO: remove VCOS_FALSE -+ .want_crc = 0 -+ }; - struct bcm2835_audio_instance *instance; - int status; -- int ret; -- -- LOG_DBG("%s: start", __func__); - -- if (num_connections > VCHI_MAX_NUM_CONNECTIONS) { -- LOG_ERR("%s: unsupported number of connections %u (max=%u)\n", -- __func__, num_connections, VCHI_MAX_NUM_CONNECTIONS); -- -- return ERR_PTR(-EINVAL); -- } - /* Allocate memory for this instance */ - instance = kzalloc(sizeof(*instance), GFP_KERNEL); - if (!instance) - return ERR_PTR(-ENOMEM); - -- instance->num_connections = num_connections; -- - /* Create a lock for exclusive, serialized VCHI connection access */ - mutex_init(&instance->vchi_mutex); - /* Open the VCHI service connections */ -- for (i = 0; i < num_connections; i++) { -- SERVICE_CREATION_T params = { -- .version = VCHI_VERSION_EX(VC_AUDIOSERV_VER, VC_AUDIOSERV_MIN_VER), -- .service_id = VC_AUDIO_SERVER_NAME, -- .connection = vchi_connections[i], -- .rx_fifo_size = 0, -- .tx_fifo_size = 0, -- .callback = audio_vchi_callback, -- .callback_param = instance, -- .want_unaligned_bulk_rx = 1, //TODO: remove VCOS_FALSE -- .want_unaligned_bulk_tx = 1, //TODO: remove VCOS_FALSE -- .want_crc = 0 -- }; -- -- LOG_DBG("%s: about to open %i\n", __func__, i); -- status = vchi_service_open(vchi_instance, ¶ms, -- &instance->vchi_handle[i]); -+ params.callback_param = instance, - -- LOG_DBG("%s: opened %i: %p=%d\n", __func__, i, instance->vchi_handle[i], status); -- if (status) { -- LOG_ERR("%s: failed to open VCHI service connection (status=%d)\n", -- __func__, status); -- ret = -EPERM; -- goto err_close_services; -- } -- /* Finished with the service for now */ -- vchi_service_release(instance->vchi_handle[i]); -- } -- -- LOG_DBG("%s: okay\n", __func__); -- return instance; -+ status = vchi_service_open(vchi_instance, ¶ms, -+ &instance->vchi_handle); - --err_close_services: -- for (i = 0; i < instance->num_connections; i++) { -- LOG_ERR("%s: closing %i: %p\n", __func__, i, instance->vchi_handle[i]); -- if (instance->vchi_handle[i]) -- vchi_service_close(instance->vchi_handle[i]); -+ if (status) { -+ LOG_ERR("%s: failed to open VCHI service connection (status=%d)\n", -+ __func__, status); -+ kfree(instance); -+ return ERR_PTR(-EPERM); - } - -- kfree(instance); -- LOG_ERR("%s: error\n", __func__); -+ /* Finished with the service for now */ -+ vchi_service_release(instance->vchi_handle); - -- return ERR_PTR(ret); -+ return instance; - } - - static int vc_vchi_audio_deinit(struct bcm2835_audio_instance *instance) - { -- unsigned int i; -- -- if (!instance) { -- LOG_ERR("%s: invalid handle %p\n", __func__, instance); -- -- return -1; -- } -+ int status; - -- LOG_DBG(" .. about to lock (%d)\n", instance->num_connections); - mutex_lock(&instance->vchi_mutex); - - /* Close all VCHI service connections */ -- for (i = 0; i < instance->num_connections; i++) { -- int status; -- -- LOG_DBG(" .. %i:closing %p\n", i, instance->vchi_handle[i]); -- vchi_service_use(instance->vchi_handle[i]); -+ vchi_service_use(instance->vchi_handle); - -- status = vchi_service_close(instance->vchi_handle[i]); -- if (status) { -- LOG_DBG("%s: failed to close VCHI service connection (status=%d)\n", -- __func__, status); -- } -+ status = vchi_service_close(instance->vchi_handle); -+ if (status) { -+ LOG_DBG("%s: failed to close VCHI service connection (status=%d)\n", -+ __func__, status); - } - - mutex_unlock(&instance->vchi_mutex); -@@ -383,19 +341,9 @@ static int bcm2835_audio_open_connection - (struct bcm2835_audio_instance *)alsa_stream->instance; - struct bcm2835_vchi_ctx *vhci_ctx = alsa_stream->chip->vchi_ctx; - -- LOG_INFO("%s: start\n", __func__); -- BUG_ON(instance); -- if (instance) { -- LOG_ERR("%s: VCHI instance already open (%p)\n", -- __func__, instance); -- instance->alsa_stream = alsa_stream; -- alsa_stream->instance = instance; -- return 0; -- } -- - /* Initialize an instance of the audio service */ - instance = vc_vchi_audio_init(vhci_ctx->vchi_instance, -- &vhci_ctx->vchi_connection, 1); -+ vhci_ctx->vchi_connection); - - if (IS_ERR(instance)) { - LOG_ERR("%s: failed to initialize audio service\n", __func__); -@@ -407,8 +355,6 @@ static int bcm2835_audio_open_connection - instance->alsa_stream = alsa_stream; - alsa_stream->instance = instance; - -- LOG_DBG(" success !\n"); -- - return 0; - } - -@@ -431,12 +377,12 @@ int bcm2835_audio_open(struct bcm2835_al - LOG_DBG(" instance (%p)\n", instance); - - mutex_lock(&instance->vchi_mutex); -- vchi_service_use(instance->vchi_handle[0]); -+ vchi_service_use(instance->vchi_handle); - - m.type = VC_AUDIO_MSG_TYPE_OPEN; - - /* Send the message to the videocore */ -- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], -+ status = bcm2835_vchi_msg_queue(instance->vchi_handle, - &m, sizeof(m)); - - if (status) { -@@ -450,7 +396,7 @@ int bcm2835_audio_open(struct bcm2835_al - ret = 0; - - unlock: -- vchi_service_release(instance->vchi_handle[0]); -+ vchi_service_release(instance->vchi_handle); - mutex_unlock(&instance->vchi_mutex); - - free_wq: -@@ -472,7 +418,7 @@ int bcm2835_audio_set_ctls(struct bcm283 - chip->dest, chip->volume); - - mutex_lock(&instance->vchi_mutex); -- vchi_service_use(instance->vchi_handle[0]); -+ vchi_service_use(instance->vchi_handle); - - instance->result = -1; - -@@ -487,7 +433,7 @@ int bcm2835_audio_set_ctls(struct bcm283 - init_completion(&instance->msg_avail_comp); - - /* Send the message to the videocore */ -- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], -+ status = bcm2835_vchi_msg_queue(instance->vchi_handle, - &m, sizeof(m)); - - if (status) { -@@ -511,7 +457,7 @@ int bcm2835_audio_set_ctls(struct bcm283 - ret = 0; - - unlock: -- vchi_service_release(instance->vchi_handle[0]); -+ vchi_service_release(instance->vchi_handle); - mutex_unlock(&instance->vchi_mutex); - - return ret; -@@ -537,7 +483,7 @@ int bcm2835_audio_set_params(struct bcm2 - } - - mutex_lock(&instance->vchi_mutex); -- vchi_service_use(instance->vchi_handle[0]); -+ vchi_service_use(instance->vchi_handle); - - instance->result = -1; - -@@ -550,7 +496,7 @@ int bcm2835_audio_set_params(struct bcm2 - init_completion(&instance->msg_avail_comp); - - /* Send the message to the videocore */ -- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], -+ status = bcm2835_vchi_msg_queue(instance->vchi_handle, - &m, sizeof(m)); - - if (status) { -@@ -574,7 +520,7 @@ int bcm2835_audio_set_params(struct bcm2 - ret = 0; - - unlock: -- vchi_service_release(instance->vchi_handle[0]); -+ vchi_service_release(instance->vchi_handle); - mutex_unlock(&instance->vchi_mutex); - - return ret; -@@ -588,12 +534,12 @@ static int bcm2835_audio_start_worker(st - int ret; - - mutex_lock(&instance->vchi_mutex); -- vchi_service_use(instance->vchi_handle[0]); -+ vchi_service_use(instance->vchi_handle); - - m.type = VC_AUDIO_MSG_TYPE_START; - - /* Send the message to the videocore */ -- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], -+ status = bcm2835_vchi_msg_queue(instance->vchi_handle, - &m, sizeof(m)); - - if (status) { -@@ -607,7 +553,7 @@ static int bcm2835_audio_start_worker(st - ret = 0; - - unlock: -- vchi_service_release(instance->vchi_handle[0]); -+ vchi_service_release(instance->vchi_handle); - mutex_unlock(&instance->vchi_mutex); - return ret; - } -@@ -620,13 +566,13 @@ static int bcm2835_audio_stop_worker(str - int ret; - - mutex_lock(&instance->vchi_mutex); -- vchi_service_use(instance->vchi_handle[0]); -+ vchi_service_use(instance->vchi_handle); - - m.type = VC_AUDIO_MSG_TYPE_STOP; - m.u.stop.draining = alsa_stream->draining; - - /* Send the message to the videocore */ -- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], -+ status = bcm2835_vchi_msg_queue(instance->vchi_handle, - &m, sizeof(m)); - - if (status) { -@@ -640,7 +586,7 @@ static int bcm2835_audio_stop_worker(str - ret = 0; - - unlock: -- vchi_service_release(instance->vchi_handle[0]); -+ vchi_service_release(instance->vchi_handle); - mutex_unlock(&instance->vchi_mutex); - return ret; - } -@@ -655,7 +601,7 @@ int bcm2835_audio_close(struct bcm2835_a - my_workqueue_quit(alsa_stream); - - mutex_lock(&instance->vchi_mutex); -- vchi_service_use(instance->vchi_handle[0]); -+ vchi_service_use(instance->vchi_handle); - - m.type = VC_AUDIO_MSG_TYPE_CLOSE; - -@@ -663,7 +609,7 @@ int bcm2835_audio_close(struct bcm2835_a - init_completion(&instance->msg_avail_comp); - - /* Send the message to the videocore */ -- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], -+ status = bcm2835_vchi_msg_queue(instance->vchi_handle, - &m, sizeof(m)); - - if (status) { -@@ -687,7 +633,7 @@ int bcm2835_audio_close(struct bcm2835_a - ret = 0; - - unlock: -- vchi_service_release(instance->vchi_handle[0]); -+ vchi_service_release(instance->vchi_handle); - mutex_unlock(&instance->vchi_mutex); - - /* Stop the audio service */ -@@ -708,10 +654,10 @@ static int bcm2835_audio_write_worker(st - LOG_INFO(" Writing %d bytes from %p\n", count, src); - - mutex_lock(&instance->vchi_mutex); -- vchi_service_use(instance->vchi_handle[0]); -+ vchi_service_use(instance->vchi_handle); - - if (instance->peer_version == 0 && -- vchi_get_peer_version(instance->vchi_handle[0], &instance->peer_version) == 0) -+ vchi_get_peer_version(instance->vchi_handle, &instance->peer_version) == 0) - LOG_DBG("%s: client version %d connected\n", __func__, instance->peer_version); - - m.type = VC_AUDIO_MSG_TYPE_WRITE; -@@ -723,7 +669,7 @@ static int bcm2835_audio_write_worker(st - m.u.write.silence = src == NULL; - - /* Send the message to the videocore */ -- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], -+ status = bcm2835_vchi_msg_queue(instance->vchi_handle, - &m, sizeof(m)); - - if (status) { -@@ -736,7 +682,7 @@ static int bcm2835_audio_write_worker(st - if (!m.u.write.silence) { - if (!m.u.write.max_packet) { - /* Send the message to the videocore */ -- status = vchi_bulk_queue_transmit(instance->vchi_handle[0], -+ status = vchi_bulk_queue_transmit(instance->vchi_handle, - src, count, - 0 * VCHI_FLAGS_BLOCK_UNTIL_QUEUED - + -@@ -746,7 +692,7 @@ static int bcm2835_audio_write_worker(st - while (count > 0) { - int bytes = min_t(int, m.u.write.max_packet, count); - -- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], -+ status = bcm2835_vchi_msg_queue(instance->vchi_handle, - src, bytes); - src = (char *)src + bytes; - count -= bytes; -@@ -763,7 +709,7 @@ static int bcm2835_audio_write_worker(st - ret = 0; - - unlock: -- vchi_service_release(instance->vchi_handle[0]); -+ vchi_service_release(instance->vchi_handle); - mutex_unlock(&instance->vchi_mutex); - return ret; - } diff --git a/target/linux/brcm2708/patches-4.19/950-0457-staging-bcm2835-audio-Use-card-private_data.patch b/target/linux/brcm2708/patches-4.19/950-0457-staging-bcm2835-audio-Use-card-private_data.patch new file mode 100644 index 0000000000..37b02c1993 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0457-staging-bcm2835-audio-Use-card-private_data.patch @@ -0,0 +1,138 @@ +From 45a6f73971c5e20f256ad2faa1c17d3525affa15 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:50 +0200 +Subject: [PATCH 457/725] staging: bcm2835-audio: Use card->private_data + +commit 898001a0c845cefe5d47d133485712412853f0a8 upstream. + +Instead of allocating a separate snd_device object, let snd_card_new() +allocate the private resource. This simplifies the code. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835.c | 91 +++---------------- + 1 file changed, 13 insertions(+), 78 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +@@ -86,9 +86,6 @@ static int bcm2835_devm_add_vchi_ctx(str + + static void snd_bcm2835_release(struct device *dev) + { +- struct bcm2835_chip *chip = dev_get_drvdata(dev); +- +- kfree(chip); + } + + static struct device * +@@ -117,69 +114,6 @@ snd_create_device(struct device *parent, + return device; + } + +-/* component-destructor +- * (see "Management of Cards and Components") +- */ +-static int snd_bcm2835_dev_free(struct snd_device *device) +-{ +- struct bcm2835_chip *chip = device->device_data; +- struct snd_card *card = chip->card; +- +- snd_device_free(card, chip); +- +- return 0; +-} +- +-/* chip-specific constructor +- * (see "Management of Cards and Components") +- */ +-static int snd_bcm2835_create(struct snd_card *card, +- struct bcm2835_chip **rchip) +-{ +- struct bcm2835_chip *chip; +- int err; +- static struct snd_device_ops ops = { +- .dev_free = snd_bcm2835_dev_free, +- }; +- +- *rchip = NULL; +- +- chip = kzalloc(sizeof(*chip), GFP_KERNEL); +- if (!chip) +- return -ENOMEM; +- +- chip->card = card; +- mutex_init(&chip->audio_mutex); +- +- chip->vchi_ctx = devres_find(card->dev->parent, +- bcm2835_devm_free_vchi_ctx, NULL, NULL); +- if (!chip->vchi_ctx) { +- kfree(chip); +- return -ENODEV; +- } +- +- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); +- if (err) { +- kfree(chip); +- return err; +- } +- +- *rchip = chip; +- return 0; +-} +- +-static struct snd_card *snd_bcm2835_card_new(struct device *dev) +-{ +- struct snd_card *card; +- int ret; +- +- ret = snd_card_new(dev, -1, NULL, THIS_MODULE, 0, &card); +- if (ret) +- return ERR_PTR(ret); +- +- return card; +-} +- + typedef int (*bcm2835_audio_newpcm_func)(struct bcm2835_chip *chip, + const char *name, + enum snd_bcm2835_route route, +@@ -292,25 +226,26 @@ static int snd_add_child_device(struct d + return PTR_ERR(child); + } + +- card = snd_bcm2835_card_new(child); +- if (IS_ERR(card)) { ++ err = snd_card_new(child, -1, NULL, THIS_MODULE, sizeof(*chip), &card); ++ if (err < 0) { + dev_err(child, "Failed to create card"); +- return PTR_ERR(card); ++ return err; + } + +- snd_card_set_dev(card, child); ++ chip = card->private_data; ++ chip->card = card; ++ chip->dev = child; ++ mutex_init(&chip->audio_mutex); ++ ++ chip->vchi_ctx = devres_find(device, ++ bcm2835_devm_free_vchi_ctx, NULL, NULL); ++ if (!chip->vchi_ctx) ++ return -ENODEV; ++ + strcpy(card->driver, audio_driver->driver.name); + strcpy(card->shortname, audio_driver->shortname); + strcpy(card->longname, audio_driver->longname); + +- err = snd_bcm2835_create(card, &chip); +- if (err) { +- dev_err(child, "Failed to create chip, error %d\n", err); +- return err; +- } +- +- chip->dev = child; +- + err = audio_driver->newpcm(chip, audio_driver->shortname, + audio_driver->route, + numchans); diff --git a/target/linux/brcm2708/patches-4.19/950-0458-staging-bcm2835-audio-Code-refactoring-of-vchiq-acce.patch b/target/linux/brcm2708/patches-4.19/950-0458-staging-bcm2835-audio-Code-refactoring-of-vchiq-acce.patch deleted file mode 100644 index 0cc2de5c88..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0458-staging-bcm2835-audio-Code-refactoring-of-vchiq-acce.patch +++ /dev/null @@ -1,575 +0,0 @@ -From 8ef08ec7a6a8f3bb42b8000e84cc444c88e60f8d Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:48 +0200 -Subject: [PATCH 458/703] staging: bcm2835-audio: Code refactoring of vchiq - accessor codes - -commit 769a8e9bf5cf39813f52962fdafdf7e4d52ad585 upstream. - -This is a cleanup and code refactoring in bcm2835-vchiq.c. - -The major code changes are to provide local helpers for easier use of -lock / unlock, and message passing with/without response wait. This -allows us to reduce lots of open codes. - -Also, the max packet is set at opening the stream, not at each time -when the write gets called. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../bcm2835-audio/bcm2835-vchiq.c | 440 ++++++------------ - 1 file changed, 142 insertions(+), 298 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -@@ -49,6 +49,7 @@ struct bcm2835_audio_instance { - struct mutex vchi_mutex; - struct bcm2835_alsa_stream *alsa_stream; - int result; -+ unsigned int max_packet; - short peer_version; - }; - -@@ -65,16 +66,68 @@ static int bcm2835_audio_start_worker(st - static int bcm2835_audio_write_worker(struct bcm2835_alsa_stream *alsa_stream, - unsigned int count, void *src); - --// Routine to send a message across a service -+static void bcm2835_audio_lock(struct bcm2835_audio_instance *instance) -+{ -+ mutex_lock(&instance->vchi_mutex); -+ vchi_service_use(instance->vchi_handle); -+} -+ -+static void bcm2835_audio_unlock(struct bcm2835_audio_instance *instance) -+{ -+ vchi_service_release(instance->vchi_handle); -+ mutex_unlock(&instance->vchi_mutex); -+} -+ -+static int bcm2835_audio_send_msg_locked(struct bcm2835_audio_instance *instance, -+ struct vc_audio_msg *m, bool wait) -+{ -+ int status; -+ -+ if (wait) { -+ instance->result = -1; -+ init_completion(&instance->msg_avail_comp); -+ } -+ -+ status = vchi_queue_kernel_message(instance->vchi_handle, -+ m, sizeof(*m)); -+ if (status) { -+ LOG_ERR("vchi message queue failed: %d, msg=%d\n", -+ status, m->type); -+ return -EIO; -+ } -+ -+ if (wait) { -+ if (!wait_for_completion_timeout(&instance->msg_avail_comp, -+ msecs_to_jiffies(10 * 1000))) { -+ LOG_ERR("vchi message timeout, msg=%d\n", m->type); -+ return -ETIMEDOUT; -+ } else if (instance->result) { -+ LOG_ERR("vchi message response error:%d, msg=%d\n", -+ instance->result, m->type); -+ return -EIO; -+ } -+ } -+ -+ return 0; -+} - --static int --bcm2835_vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle, -- void *data, -- unsigned int size) --{ -- return vchi_queue_kernel_message(handle, -- data, -- size); -+static int bcm2835_audio_send_msg(struct bcm2835_audio_instance *instance, -+ struct vc_audio_msg *m, bool wait) -+{ -+ int err; -+ -+ bcm2835_audio_lock(instance); -+ err = bcm2835_audio_send_msg_locked(instance, m, wait); -+ bcm2835_audio_unlock(instance); -+ return err; -+} -+ -+static int bcm2835_audio_send_simple(struct bcm2835_audio_instance *instance, -+ int type, bool wait) -+{ -+ struct vc_audio_msg m = { .type = type }; -+ -+ return bcm2835_audio_send_msg(instance, &m, wait); - } - - static const u32 BCM2835_AUDIO_WRITE_COOKIE1 = ('B' << 24 | 'C' << 16 | -@@ -283,10 +336,9 @@ static int vc_vchi_audio_deinit(struct b - int status; - - mutex_lock(&instance->vchi_mutex); -- -- /* Close all VCHI service connections */ - vchi_service_use(instance->vchi_handle); - -+ /* Close all VCHI service connections */ - status = vchi_service_close(instance->vchi_handle); - if (status) { - LOG_DBG("%s: failed to close VCHI service connection (status=%d)\n", -@@ -345,12 +397,8 @@ static int bcm2835_audio_open_connection - instance = vc_vchi_audio_init(vhci_ctx->vchi_instance, - vhci_ctx->vchi_connection); - -- if (IS_ERR(instance)) { -- LOG_ERR("%s: failed to initialize audio service\n", __func__); -- -- /* vchi_instance is retained for use the next time. */ -+ if (IS_ERR(instance)) - return PTR_ERR(instance); -- } - - instance->alsa_stream = alsa_stream; - alsa_stream->instance = instance; -@@ -361,66 +409,44 @@ static int bcm2835_audio_open_connection - int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream) - { - struct bcm2835_audio_instance *instance; -- struct vc_audio_msg m; -- int status; -- int ret; -+ int err; - - alsa_stream->my_wq = alloc_workqueue("my_queue", WQ_HIGHPRI, 1); - if (!alsa_stream->my_wq) - return -ENOMEM; - -- ret = bcm2835_audio_open_connection(alsa_stream); -- if (ret) -+ err = bcm2835_audio_open_connection(alsa_stream); -+ if (err < 0) - goto free_wq; - - instance = alsa_stream->instance; -- LOG_DBG(" instance (%p)\n", instance); -- -- mutex_lock(&instance->vchi_mutex); -- vchi_service_use(instance->vchi_handle); -- -- m.type = VC_AUDIO_MSG_TYPE_OPEN; -- -- /* Send the message to the videocore */ -- status = bcm2835_vchi_msg_queue(instance->vchi_handle, -- &m, sizeof(m)); -- -- if (status) { -- LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", -- __func__, status); -- -- ret = -1; -- goto unlock; -- } -- -- ret = 0; - --unlock: -- vchi_service_release(instance->vchi_handle); -- mutex_unlock(&instance->vchi_mutex); -+ err = bcm2835_audio_send_simple(instance, VC_AUDIO_MSG_TYPE_OPEN, -+ false); -+ if (err < 0) -+ goto deinit; -+ -+ bcm2835_audio_lock(instance); -+ vchi_get_peer_version(instance->vchi_handle, &instance->peer_version); -+ bcm2835_audio_unlock(instance); -+ if (instance->peer_version < 2 || force_bulk) -+ instance->max_packet = 0; /* bulk transfer */ -+ else -+ instance->max_packet = 4000; - --free_wq: -- if (ret) -- destroy_workqueue(alsa_stream->my_wq); -+ return 0; - -- return ret; -+ deinit: -+ vc_vchi_audio_deinit(instance); -+ free_wq: -+ destroy_workqueue(alsa_stream->my_wq); -+ return err; - } - - int bcm2835_audio_set_ctls(struct bcm2835_alsa_stream *alsa_stream) - { -- struct vc_audio_msg m; -- struct bcm2835_audio_instance *instance = alsa_stream->instance; - struct bcm2835_chip *chip = alsa_stream->chip; -- int status; -- int ret; -- -- LOG_INFO(" Setting ALSA dest(%d), volume(%d)\n", -- chip->dest, chip->volume); -- -- mutex_lock(&instance->vchi_mutex); -- vchi_service_use(instance->vchi_handle); -- -- instance->result = -1; -+ struct vc_audio_msg m = {}; - - m.type = VC_AUDIO_MSG_TYPE_CONTROL; - m.u.control.dest = chip->dest; -@@ -429,289 +455,107 @@ int bcm2835_audio_set_ctls(struct bcm283 - else - m.u.control.volume = alsa2chip(chip->volume); - -- /* Create the message available completion */ -- init_completion(&instance->msg_avail_comp); -- -- /* Send the message to the videocore */ -- status = bcm2835_vchi_msg_queue(instance->vchi_handle, -- &m, sizeof(m)); -- -- if (status) { -- LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", -- __func__, status); -- -- ret = -1; -- goto unlock; -- } -- -- /* We are expecting a reply from the videocore */ -- wait_for_completion(&instance->msg_avail_comp); -- -- if (instance->result) { -- LOG_ERR("%s: result=%d\n", __func__, instance->result); -- -- ret = -1; -- goto unlock; -- } -- -- ret = 0; -- --unlock: -- vchi_service_release(instance->vchi_handle); -- mutex_unlock(&instance->vchi_mutex); -- -- return ret; -+ return bcm2835_audio_send_msg(alsa_stream->instance, &m, true); - } - - int bcm2835_audio_set_params(struct bcm2835_alsa_stream *alsa_stream, - unsigned int channels, unsigned int samplerate, - unsigned int bps) - { -- struct vc_audio_msg m; -- struct bcm2835_audio_instance *instance = alsa_stream->instance; -- int status; -- int ret; -- -- LOG_INFO(" Setting ALSA channels(%d), samplerate(%d), bits-per-sample(%d)\n", -- channels, samplerate, bps); -+ struct vc_audio_msg m = { -+ .type = VC_AUDIO_MSG_TYPE_CONFIG, -+ .u.config.channels = channels, -+ .u.config.samplerate = samplerate, -+ .u.config.bps = bps, -+ }; -+ int err; - - /* resend ctls - alsa_stream may not have been open when first send */ -- ret = bcm2835_audio_set_ctls(alsa_stream); -- if (ret) { -- LOG_ERR(" Alsa controls not supported\n"); -- return -EINVAL; -- } -+ err = bcm2835_audio_set_ctls(alsa_stream); -+ if (err) -+ return err; - -- mutex_lock(&instance->vchi_mutex); -- vchi_service_use(instance->vchi_handle); -- -- instance->result = -1; -- -- m.type = VC_AUDIO_MSG_TYPE_CONFIG; -- m.u.config.channels = channels; -- m.u.config.samplerate = samplerate; -- m.u.config.bps = bps; -- -- /* Create the message available completion */ -- init_completion(&instance->msg_avail_comp); -- -- /* Send the message to the videocore */ -- status = bcm2835_vchi_msg_queue(instance->vchi_handle, -- &m, sizeof(m)); -- -- if (status) { -- LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", -- __func__, status); -- -- ret = -1; -- goto unlock; -- } -- -- /* We are expecting a reply from the videocore */ -- wait_for_completion(&instance->msg_avail_comp); -- -- if (instance->result) { -- LOG_ERR("%s: result=%d", __func__, instance->result); -- -- ret = -1; -- goto unlock; -- } -- -- ret = 0; -- --unlock: -- vchi_service_release(instance->vchi_handle); -- mutex_unlock(&instance->vchi_mutex); -- -- return ret; -+ return bcm2835_audio_send_msg(alsa_stream->instance, &m, true); - } - - static int bcm2835_audio_start_worker(struct bcm2835_alsa_stream *alsa_stream) - { -- struct vc_audio_msg m; -- struct bcm2835_audio_instance *instance = alsa_stream->instance; -- int status; -- int ret; -- -- mutex_lock(&instance->vchi_mutex); -- vchi_service_use(instance->vchi_handle); -- -- m.type = VC_AUDIO_MSG_TYPE_START; -- -- /* Send the message to the videocore */ -- status = bcm2835_vchi_msg_queue(instance->vchi_handle, -- &m, sizeof(m)); -- -- if (status) { -- LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", -- __func__, status); -- -- ret = -1; -- goto unlock; -- } -- -- ret = 0; -- --unlock: -- vchi_service_release(instance->vchi_handle); -- mutex_unlock(&instance->vchi_mutex); -- return ret; -+ return bcm2835_audio_send_simple(alsa_stream->instance, -+ VC_AUDIO_MSG_TYPE_START, false); - } - - static int bcm2835_audio_stop_worker(struct bcm2835_alsa_stream *alsa_stream) - { -- struct vc_audio_msg m; -- struct bcm2835_audio_instance *instance = alsa_stream->instance; -- int status; -- int ret; -- -- mutex_lock(&instance->vchi_mutex); -- vchi_service_use(instance->vchi_handle); -- -- m.type = VC_AUDIO_MSG_TYPE_STOP; -- m.u.stop.draining = alsa_stream->draining; -- -- /* Send the message to the videocore */ -- status = bcm2835_vchi_msg_queue(instance->vchi_handle, -- &m, sizeof(m)); -- -- if (status) { -- LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", -- __func__, status); -- -- ret = -1; -- goto unlock; -- } -- -- ret = 0; -- --unlock: -- vchi_service_release(instance->vchi_handle); -- mutex_unlock(&instance->vchi_mutex); -- return ret; -+ return bcm2835_audio_send_simple(alsa_stream->instance, -+ VC_AUDIO_MSG_TYPE_STOP, false); - } - - int bcm2835_audio_close(struct bcm2835_alsa_stream *alsa_stream) - { -- struct vc_audio_msg m; - struct bcm2835_audio_instance *instance = alsa_stream->instance; -- int status; -- int ret; -+ int err; - - my_workqueue_quit(alsa_stream); - -- mutex_lock(&instance->vchi_mutex); -- vchi_service_use(instance->vchi_handle); -- -- m.type = VC_AUDIO_MSG_TYPE_CLOSE; -- -- /* Create the message available completion */ -- init_completion(&instance->msg_avail_comp); -- -- /* Send the message to the videocore */ -- status = bcm2835_vchi_msg_queue(instance->vchi_handle, -- &m, sizeof(m)); -- -- if (status) { -- LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", -- __func__, status); -- ret = -1; -- goto unlock; -- } -- -- /* We are expecting a reply from the videocore */ -- wait_for_completion(&instance->msg_avail_comp); -- -- if (instance->result) { -- LOG_ERR("%s: failed result (result=%d)\n", -- __func__, instance->result); -- -- ret = -1; -- goto unlock; -- } -- -- ret = 0; -- --unlock: -- vchi_service_release(instance->vchi_handle); -- mutex_unlock(&instance->vchi_mutex); -+ err = bcm2835_audio_send_simple(alsa_stream->instance, -+ VC_AUDIO_MSG_TYPE_CLOSE, true); - - /* Stop the audio service */ - vc_vchi_audio_deinit(instance); - alsa_stream->instance = NULL; - -- return ret; -+ return err; - } - - static int bcm2835_audio_write_worker(struct bcm2835_alsa_stream *alsa_stream, -- unsigned int count, void *src) -+ unsigned int size, void *src) - { -- struct vc_audio_msg m; - struct bcm2835_audio_instance *instance = alsa_stream->instance; -- int status; -- int ret; -- -- LOG_INFO(" Writing %d bytes from %p\n", count, src); -- -- mutex_lock(&instance->vchi_mutex); -- vchi_service_use(instance->vchi_handle); -+ struct vc_audio_msg m = { -+ .type = VC_AUDIO_MSG_TYPE_WRITE, -+ .u.write.count = size, -+ .u.write.max_packet = instance->max_packet, -+ .u.write.cookie1 = BCM2835_AUDIO_WRITE_COOKIE1, -+ .u.write.cookie2 = BCM2835_AUDIO_WRITE_COOKIE2, -+ }; -+ unsigned int count; -+ int err, status; - -- if (instance->peer_version == 0 && -- vchi_get_peer_version(instance->vchi_handle, &instance->peer_version) == 0) -- LOG_DBG("%s: client version %d connected\n", __func__, instance->peer_version); -- -- m.type = VC_AUDIO_MSG_TYPE_WRITE; -- m.u.write.count = count; -- // old version uses bulk, new version uses control -- m.u.write.max_packet = instance->peer_version < 2 || force_bulk ? 0 : 4000; -- m.u.write.cookie1 = BCM2835_AUDIO_WRITE_COOKIE1; -- m.u.write.cookie2 = BCM2835_AUDIO_WRITE_COOKIE2; -- m.u.write.silence = src == NULL; -- -- /* Send the message to the videocore */ -- status = bcm2835_vchi_msg_queue(instance->vchi_handle, -- &m, sizeof(m)); -+ if (!size) -+ return 0; - -- if (status) { -- LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", -- __func__, status); -- -- ret = -1; -+ bcm2835_audio_lock(instance); -+ err = bcm2835_audio_send_msg_locked(instance, &m, false); -+ if (err < 0) - goto unlock; -- } -- if (!m.u.write.silence) { -- if (!m.u.write.max_packet) { -- /* Send the message to the videocore */ -- status = vchi_bulk_queue_transmit(instance->vchi_handle, -- src, count, -- 0 * VCHI_FLAGS_BLOCK_UNTIL_QUEUED -- + -- 1 * VCHI_FLAGS_BLOCK_UNTIL_DATA_READ, -- NULL); -- } else { -- while (count > 0) { -- int bytes = min_t(int, m.u.write.max_packet, count); - -- status = bcm2835_vchi_msg_queue(instance->vchi_handle, -- src, bytes); -- src = (char *)src + bytes; -- count -= bytes; -- } -- } -- if (status) { -- LOG_ERR("%s: failed on vchi_bulk_queue_transmit (status=%d)\n", -- __func__, status); -+ count = size; -+ if (!instance->max_packet) { -+ /* Send the message to the videocore */ -+ status = vchi_bulk_queue_transmit(instance->vchi_handle, -+ src, count, -+ VCHI_FLAGS_BLOCK_UNTIL_DATA_READ, -+ NULL); -+ } else { -+ while (count > 0) { -+ int bytes = min(instance->max_packet, count); - -- ret = -1; -- goto unlock; -+ status = vchi_queue_kernel_message(instance->vchi_handle, -+ src, bytes); -+ src += bytes; -+ count -= bytes; - } - } -- ret = 0; - --unlock: -- vchi_service_release(instance->vchi_handle); -- mutex_unlock(&instance->vchi_mutex); -- return ret; -+ if (status) { -+ LOG_ERR("failed on %d bytes transfer (status=%d)\n", -+ size, status); -+ err = -EIO; -+ } -+ -+ unlock: -+ bcm2835_audio_unlock(instance); -+ return err; - } - - unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream) diff --git a/target/linux/brcm2708/patches-4.19/950-0458-staging-bcm2835-audio-Use-standard-error-print-helpe.patch b/target/linux/brcm2708/patches-4.19/950-0458-staging-bcm2835-audio-Use-standard-error-print-helpe.patch new file mode 100644 index 0000000000..ece160d9db --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0458-staging-bcm2835-audio-Use-standard-error-print-helpe.patch @@ -0,0 +1,237 @@ +From 2648530ca51dc98d65f1c747de4f7ddd20af6d62 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:51 +0200 +Subject: [PATCH 458/725] staging: bcm2835-audio: Use standard error print + helpers + +commit b7584b64168208ebc14160770c0966b8b12fc16b upstream. + +For making the whole code more consistent, replace the home-made debug +print macros with the standard dev_err() & co. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 4 +- + .../bcm2835-audio/bcm2835-vchiq.c | 52 ++++++++----------- + .../vc04_services/bcm2835-audio/bcm2835.c | 2 +- + .../vc04_services/bcm2835-audio/bcm2835.h | 43 +-------------- + 4 files changed, 27 insertions(+), 74 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -101,8 +101,8 @@ static int snd_bcm2835_playback_open_gen + goto out; + } + if (idx >= MAX_SUBSTREAMS) { +- audio_error +- ("substream(%d) device doesn't exist max(%d) substreams allowed\n", ++ dev_err(chip->dev, ++ "substream(%d) device doesn't exist max(%d) substreams allowed\n", + idx, MAX_SUBSTREAMS); + err = -ENODEV; + goto out; +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +@@ -26,20 +26,8 @@ + + /* ---- Private Constants and Types ------------------------------------------ */ + +-/* Logging macros (for remapping to other logging mechanisms, i.e., printf) */ +-#ifdef AUDIO_DEBUG_ENABLE +-#define LOG_ERR(fmt, arg...) pr_err("%s:%d " fmt, __func__, __LINE__, ##arg) +-#define LOG_WARN(fmt, arg...) pr_info("%s:%d " fmt, __func__, __LINE__, ##arg) +-#define LOG_INFO(fmt, arg...) pr_info("%s:%d " fmt, __func__, __LINE__, ##arg) +-#define LOG_DBG(fmt, arg...) pr_info("%s:%d " fmt, __func__, __LINE__, ##arg) +-#else +-#define LOG_ERR(fmt, arg...) pr_err("%s:%d " fmt, __func__, __LINE__, ##arg) +-#define LOG_WARN(fmt, arg...) no_printk(fmt, ##arg) +-#define LOG_INFO(fmt, arg...) no_printk(fmt, ##arg) +-#define LOG_DBG(fmt, arg...) no_printk(fmt, ##arg) +-#endif +- + struct bcm2835_audio_instance { ++ struct device *dev; + VCHI_SERVICE_HANDLE_T vchi_handle; + struct completion msg_avail_comp; + struct mutex vchi_mutex; +@@ -76,7 +64,8 @@ static int bcm2835_audio_send_msg_locked + status = vchi_queue_kernel_message(instance->vchi_handle, + m, sizeof(*m)); + if (status) { +- LOG_ERR("vchi message queue failed: %d, msg=%d\n", ++ dev_err(instance->dev, ++ "vchi message queue failed: %d, msg=%d\n", + status, m->type); + return -EIO; + } +@@ -84,10 +73,12 @@ static int bcm2835_audio_send_msg_locked + if (wait) { + if (!wait_for_completion_timeout(&instance->msg_avail_comp, + msecs_to_jiffies(10 * 1000))) { +- LOG_ERR("vchi message timeout, msg=%d\n", m->type); ++ dev_err(instance->dev, ++ "vchi message timeout, msg=%d\n", m->type); + return -ETIMEDOUT; + } else if (instance->result) { +- LOG_ERR("vchi message response error:%d, msg=%d\n", ++ dev_err(instance->dev, ++ "vchi message response error:%d, msg=%d\n", + instance->result, m->type); + return -EIO; + } +@@ -140,12 +131,12 @@ static void audio_vchi_callback(void *pa + } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) { + if (m.u.complete.cookie1 != BCM2835_AUDIO_WRITE_COOKIE1 || + m.u.complete.cookie2 != BCM2835_AUDIO_WRITE_COOKIE2) +- LOG_ERR("invalid cookie\n"); ++ dev_err(instance->dev, "invalid cookie\n"); + else + bcm2835_playback_fifo(instance->alsa_stream, + m.u.complete.count); + } else { +- LOG_ERR("unexpected callback type=%d\n", m.type); ++ dev_err(instance->dev, "unexpected callback type=%d\n", m.type); + } + } + +@@ -173,8 +164,9 @@ vc_vchi_audio_init(VCHI_INSTANCE_T vchi_ + &instance->vchi_handle); + + if (status) { +- LOG_ERR("%s: failed to open VCHI service connection (status=%d)\n", +- __func__, status); ++ dev_err(instance->dev, ++ "failed to open VCHI service connection (status=%d)\n", ++ status); + kfree(instance); + return -EPERM; + } +@@ -195,30 +187,30 @@ static void vc_vchi_audio_deinit(struct + /* Close all VCHI service connections */ + status = vchi_service_close(instance->vchi_handle); + if (status) { +- LOG_DBG("%s: failed to close VCHI service connection (status=%d)\n", +- __func__, status); ++ dev_err(instance->dev, ++ "failed to close VCHI service connection (status=%d)\n", ++ status); + } + + mutex_unlock(&instance->vchi_mutex); + } + +-int bcm2835_new_vchi_ctx(struct bcm2835_vchi_ctx *vchi_ctx) ++int bcm2835_new_vchi_ctx(struct device *dev, struct bcm2835_vchi_ctx *vchi_ctx) + { + int ret; + + /* Initialize and create a VCHI connection */ + ret = vchi_initialise(&vchi_ctx->vchi_instance); + if (ret) { +- LOG_ERR("%s: failed to initialise VCHI instance (ret=%d)\n", +- __func__, ret); +- ++ dev_err(dev, "failed to initialise VCHI instance (ret=%d)\n", ++ ret); + return -EIO; + } + + ret = vchi_connect(NULL, 0, vchi_ctx->vchi_instance); + if (ret) { +- LOG_ERR("%s: failed to connect VCHI instance (ret=%d)\n", +- __func__, ret); ++ dev_dbg(dev, "failed to connect VCHI instance (ret=%d)\n", ++ ret); + + kfree(vchi_ctx->vchi_instance); + vchi_ctx->vchi_instance = NULL; +@@ -248,6 +240,7 @@ int bcm2835_audio_open(struct bcm2835_al + if (!instance) + return -ENOMEM; + mutex_init(&instance->vchi_mutex); ++ instance->dev = alsa_stream->chip->dev; + instance->alsa_stream = alsa_stream; + alsa_stream->instance = instance; + +@@ -394,7 +387,8 @@ int bcm2835_audio_write(struct bcm2835_a + } + + if (status) { +- LOG_ERR("failed on %d bytes transfer (status=%d)\n", ++ dev_err(instance->dev, ++ "failed on %d bytes transfer (status=%d)\n", + size, status); + err = -EIO; + } +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +@@ -73,7 +73,7 @@ static int bcm2835_devm_add_vchi_ctx(str + + memset(vchi_ctx, 0, sizeof(*vchi_ctx)); + +- ret = bcm2835_new_vchi_ctx(vchi_ctx); ++ ret = bcm2835_new_vchi_ctx(dev, vchi_ctx); + if (ret) { + devres_free(vchi_ctx); + return ret; +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h +@@ -17,47 +17,6 @@ + + #include "interface/vchi/vchi.h" + +-/* +- * #define AUDIO_DEBUG_ENABLE +- * #define AUDIO_VERBOSE_DEBUG_ENABLE +- */ +- +-/* Debug macros */ +- +-#ifdef AUDIO_DEBUG_ENABLE +-#ifdef AUDIO_VERBOSE_DEBUG_ENABLE +- +-#define audio_debug(fmt, arg...) \ +- pr_info("%s:%d " fmt, __func__, __LINE__, ##arg) +- +-#define audio_info(fmt, arg...) \ +- pr_info("%s:%d " fmt, __func__, __LINE__, ##arg) +- +-#else +- +-#define audio_debug(fmt, arg...) +- +-#define audio_info(fmt, arg...) +- +-#endif /* AUDIO_VERBOSE_DEBUG_ENABLE */ +- +-#else +- +-#define audio_debug(fmt, arg...) +- +-#define audio_info(fmt, arg...) +- +-#endif /* AUDIO_DEBUG_ENABLE */ +- +-#define audio_error(fmt, arg...) \ +- pr_err("%s:%d " fmt, __func__, __LINE__, ##arg) +- +-#define audio_warning(fmt, arg...) \ +- pr_warn("%s:%d " fmt, __func__, __LINE__, ##arg) +- +-#define audio_alert(fmt, arg...) \ +- pr_alert("%s:%d " fmt, __func__, __LINE__, ##arg) +- + #define MAX_SUBSTREAMS (8) + #define AVAIL_SUBSTREAMS_MASK (0xff) + +@@ -141,7 +100,7 @@ int snd_bcm2835_new_simple_pcm(struct bc + int snd_bcm2835_new_hdmi_ctl(struct bcm2835_chip *chip); + int snd_bcm2835_new_headphones_ctl(struct bcm2835_chip *chip); + +-int bcm2835_new_vchi_ctx(struct bcm2835_vchi_ctx *vchi_ctx); ++int bcm2835_new_vchi_ctx(struct device *dev, struct bcm2835_vchi_ctx *vchi_ctx); + void bcm2835_free_vchi_ctx(struct bcm2835_vchi_ctx *vchi_ctx); + + int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream); diff --git a/target/linux/brcm2708/patches-4.19/950-0459-staging-bcm2835-audio-Operate-non-atomic-PCM-ops.patch b/target/linux/brcm2708/patches-4.19/950-0459-staging-bcm2835-audio-Operate-non-atomic-PCM-ops.patch deleted file mode 100644 index 5ce175fde8..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0459-staging-bcm2835-audio-Operate-non-atomic-PCM-ops.patch +++ /dev/null @@ -1,593 +0,0 @@ -From 8f5871c73ba767c9443eb02c4ca0cb7df56982e8 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:49 +0200 -Subject: [PATCH 459/703] staging: bcm2835-audio: Operate non-atomic PCM ops - -commit 5c7883e5f27e829f3f3a2ba174d4a724bfd5f026 upstream. - -This is the most significant part in the patch series. - -The bcm2835-audio driver used to queue the commands to vc04 core via -workqueue, but basically the whole accesses to vc04 core are done in -the sleepable context, including the callback calls. In such a case, -rewriting the code using non-atomic PCM ops will simplify the logic a -lot. - -This patch does it: all workqueue are gone and each former-work -implementation is now directly called from PCM ops like trigger and -write transfer. - -Along with it, the DMA position updater, bcm2835_playback_fifo(), was -also rewritten to use a simpler logic. Now it handles the XRUN and -draining properly by calling snd_pcm_stop() conditionally. - -The current position is kept in atomic_t value so that it can be read -concurrently from the pointer callback. - -Also, the bcm2835_audio_instance object is allocated at the beginning -of bcm2835_audio_open(). This makes the resource management clearer. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 74 +++--- - .../bcm2835-audio/bcm2835-vchiq.c | 244 +++--------------- - .../vc04_services/bcm2835-audio/bcm2835.h | 9 +- - 3 files changed, 82 insertions(+), 245 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -11,7 +11,8 @@ - /* hardware definition */ - static const struct snd_pcm_hardware snd_bcm2835_playback_hw = { - .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | -- SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), -+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | -+ SNDRV_PCM_INFO_DRAIN_TRIGGER), - .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, - .rate_min = 8000, -@@ -27,7 +28,8 @@ static const struct snd_pcm_hardware snd - - static const struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = { - .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | -- SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), -+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | -+ SNDRV_PCM_INFO_DRAIN_TRIGGER), - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000, -@@ -47,42 +49,34 @@ static void snd_bcm2835_playback_free(st - kfree(runtime->private_data); - } - --void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream) -+void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream, -+ unsigned int bytes) - { -- unsigned int consumed = 0; -- int new_period = 0; -+ struct snd_pcm_substream *substream = alsa_stream->substream; -+ unsigned int pos; - -- audio_info("alsa_stream=%p substream=%p\n", alsa_stream, -- alsa_stream ? alsa_stream->substream : 0); -+ if (!alsa_stream->period_size) -+ return; - -- consumed = bcm2835_audio_retrieve_buffers(alsa_stream); -- -- /* We get called only if playback was triggered, So, the number of buffers we retrieve in -- * each iteration are the buffers that have been played out already -- */ -- -- if (alsa_stream->period_size) { -- if ((alsa_stream->pos / alsa_stream->period_size) != -- ((alsa_stream->pos + consumed) / alsa_stream->period_size)) -- new_period = 1; -- } -- audio_debug("updating pos cur: %d + %d max:%d period_bytes:%d, hw_ptr: %d new_period:%d\n", -- alsa_stream->pos, -- consumed, -- alsa_stream->buffer_size, -- (int) (alsa_stream->period_size * alsa_stream->substream->runtime->periods), -- frames_to_bytes(alsa_stream->substream->runtime, alsa_stream->substream->runtime->status->hw_ptr), -- new_period); -- if (alsa_stream->buffer_size) { -- alsa_stream->pos += consumed & ~(1 << 30); -- alsa_stream->pos %= alsa_stream->buffer_size; -+ if (bytes >= alsa_stream->buffer_size) { -+ snd_pcm_stream_lock(substream); -+ snd_pcm_stop(substream, -+ alsa_stream->draining ? -+ SNDRV_PCM_STATE_SETUP : -+ SNDRV_PCM_STATE_XRUN); -+ snd_pcm_stream_unlock(substream); -+ return; - } - -- if (alsa_stream->substream) { -- if (new_period) -- snd_pcm_period_elapsed(alsa_stream->substream); -- } else { -- audio_warning(" unexpected NULL substream\n"); -+ pos = atomic_read(&alsa_stream->pos); -+ pos += bytes; -+ pos %= alsa_stream->buffer_size; -+ atomic_set(&alsa_stream->pos, pos); -+ -+ alsa_stream->period_offset += bytes; -+ if (alsa_stream->period_offset >= alsa_stream->period_size) { -+ alsa_stream->period_offset %= alsa_stream->period_size; -+ snd_pcm_period_elapsed(substream); - } - } - -@@ -246,7 +240,8 @@ static int snd_bcm2835_pcm_prepare(struc - - alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream); - alsa_stream->period_size = snd_pcm_lib_period_bytes(substream); -- alsa_stream->pos = 0; -+ atomic_set(&alsa_stream->pos, 0); -+ alsa_stream->period_offset = 0; - alsa_stream->draining = false; - - return 0; -@@ -283,7 +278,7 @@ static int snd_bcm2835_pcm_trigger(struc - return bcm2835_audio_start(alsa_stream); - case SNDRV_PCM_TRIGGER_DRAIN: - alsa_stream->draining = true; -- return 0; -+ return bcm2835_audio_drain(alsa_stream); - case SNDRV_PCM_TRIGGER_STOP: - return bcm2835_audio_stop(alsa_stream); - default: -@@ -300,7 +295,7 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_s - - return snd_pcm_indirect_playback_pointer(substream, - &alsa_stream->pcm_indirect, -- alsa_stream->pos); -+ atomic_read(&alsa_stream->pos)); - } - - /* operators */ -@@ -338,6 +333,7 @@ int snd_bcm2835_new_pcm(struct bcm2835_c - if (err < 0) - return err; - pcm->private_data = chip; -+ pcm->nonatomic = true; - strcpy(pcm->name, "bcm2835 ALSA"); - chip->pcm = pcm; - chip->dest = AUDIO_DEST_AUTO; -@@ -367,6 +363,7 @@ int snd_bcm2835_new_spdif_pcm(struct bcm - return err; - - pcm->private_data = chip; -+ pcm->nonatomic = true; - strcpy(pcm->name, "bcm2835 IEC958/HDMI"); - chip->pcm_spdif = pcm; - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, -@@ -395,6 +392,7 @@ int snd_bcm2835_new_simple_pcm(struct bc - return err; - - pcm->private_data = chip; -+ pcm->nonatomic = true; - strcpy(pcm->name, name); - chip->pcm = pcm; - chip->dest = route; ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -@@ -26,10 +26,6 @@ - - /* ---- Private Constants and Types ------------------------------------------ */ - --#define BCM2835_AUDIO_STOP 0 --#define BCM2835_AUDIO_START 1 --#define BCM2835_AUDIO_WRITE 2 -- - /* Logging macros (for remapping to other logging mechanisms, i.e., printf) */ - #ifdef AUDIO_DEBUG_ENABLE - #define LOG_ERR(fmt, arg...) pr_err("%s:%d " fmt, __func__, __LINE__, ##arg) -@@ -55,17 +51,6 @@ struct bcm2835_audio_instance { - - static bool force_bulk; - --/* ---- Private Variables ---------------------------------------------------- */ -- --/* ---- Private Function Prototypes ------------------------------------------ */ -- --/* ---- Private Functions ---------------------------------------------------- */ -- --static int bcm2835_audio_stop_worker(struct bcm2835_alsa_stream *alsa_stream); --static int bcm2835_audio_start_worker(struct bcm2835_alsa_stream *alsa_stream); --static int bcm2835_audio_write_worker(struct bcm2835_alsa_stream *alsa_stream, -- unsigned int count, void *src); -- - static void bcm2835_audio_lock(struct bcm2835_audio_instance *instance) - { - mutex_lock(&instance->vchi_mutex); -@@ -135,108 +120,6 @@ static const u32 BCM2835_AUDIO_WRITE_COO - static const u32 BCM2835_AUDIO_WRITE_COOKIE2 = ('D' << 24 | 'A' << 16 | - 'T' << 8 | 'A'); - --struct bcm2835_audio_work { -- struct work_struct my_work; -- struct bcm2835_alsa_stream *alsa_stream; -- int cmd; -- void *src; -- unsigned int count; --}; -- --static void my_wq_function(struct work_struct *work) --{ -- struct bcm2835_audio_work *w = -- container_of(work, struct bcm2835_audio_work, my_work); -- int ret = -9; -- -- switch (w->cmd) { -- case BCM2835_AUDIO_START: -- ret = bcm2835_audio_start_worker(w->alsa_stream); -- break; -- case BCM2835_AUDIO_STOP: -- ret = bcm2835_audio_stop_worker(w->alsa_stream); -- break; -- case BCM2835_AUDIO_WRITE: -- ret = bcm2835_audio_write_worker(w->alsa_stream, w->count, -- w->src); -- break; -- default: -- LOG_ERR(" Unexpected work: %p:%d\n", w->alsa_stream, w->cmd); -- break; -- } -- kfree((void *)work); --} -- --int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream) --{ -- struct bcm2835_audio_work *work; -- -- work = kmalloc(sizeof(*work), GFP_ATOMIC); -- /*--- Queue some work (item 1) ---*/ -- if (!work) { -- LOG_ERR(" .. Error: NULL work kmalloc\n"); -- return -ENOMEM; -- } -- INIT_WORK(&work->my_work, my_wq_function); -- work->alsa_stream = alsa_stream; -- work->cmd = BCM2835_AUDIO_START; -- if (!queue_work(alsa_stream->my_wq, &work->my_work)) { -- kfree(work); -- return -EBUSY; -- } -- return 0; --} -- --int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream) --{ -- struct bcm2835_audio_work *work; -- -- work = kmalloc(sizeof(*work), GFP_ATOMIC); -- /*--- Queue some work (item 1) ---*/ -- if (!work) { -- LOG_ERR(" .. Error: NULL work kmalloc\n"); -- return -ENOMEM; -- } -- INIT_WORK(&work->my_work, my_wq_function); -- work->alsa_stream = alsa_stream; -- work->cmd = BCM2835_AUDIO_STOP; -- if (!queue_work(alsa_stream->my_wq, &work->my_work)) { -- kfree(work); -- return -EBUSY; -- } -- return 0; --} -- --int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream, -- unsigned int count, void *src) --{ -- struct bcm2835_audio_work *work; -- -- work = kmalloc(sizeof(*work), GFP_ATOMIC); -- /*--- Queue some work (item 1) ---*/ -- if (!work) { -- LOG_ERR(" .. Error: NULL work kmalloc\n"); -- return -ENOMEM; -- } -- INIT_WORK(&work->my_work, my_wq_function); -- work->alsa_stream = alsa_stream; -- work->cmd = BCM2835_AUDIO_WRITE; -- work->src = src; -- work->count = count; -- if (!queue_work(alsa_stream->my_wq, &work->my_work)) { -- kfree(work); -- return -EBUSY; -- } -- return 0; --} -- --static void my_workqueue_quit(struct bcm2835_alsa_stream *alsa_stream) --{ -- flush_workqueue(alsa_stream->my_wq); -- destroy_workqueue(alsa_stream->my_wq); -- alsa_stream->my_wq = NULL; --} -- - static void audio_vchi_callback(void *param, - const VCHI_CALLBACK_REASON_T reason, - void *msg_handle) -@@ -249,47 +132,27 @@ static void audio_vchi_callback(void *pa - if (reason != VCHI_CALLBACK_MSG_AVAILABLE) - return; - -- if (!instance) { -- LOG_ERR(" .. instance is null\n"); -- BUG(); -- return; -- } -- if (!instance->vchi_handle) { -- LOG_ERR(" .. instance->vchi_handle is null\n"); -- BUG(); -- return; -- } - status = vchi_msg_dequeue(instance->vchi_handle, - &m, sizeof(m), &msg_len, VCHI_FLAGS_NONE); - if (m.type == VC_AUDIO_MSG_TYPE_RESULT) { -- LOG_DBG(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_RESULT, success=%d\n", -- instance, m.u.result.success); - instance->result = m.u.result.success; - complete(&instance->msg_avail_comp); - } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) { -- struct bcm2835_alsa_stream *alsa_stream = instance->alsa_stream; -- -- LOG_DBG(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_COMPLETE, complete=%d\n", -- instance, m.u.complete.count); - if (m.u.complete.cookie1 != BCM2835_AUDIO_WRITE_COOKIE1 || - m.u.complete.cookie2 != BCM2835_AUDIO_WRITE_COOKIE2) -- LOG_ERR(" .. response is corrupt\n"); -- else if (alsa_stream) { -- atomic_add(m.u.complete.count, -- &alsa_stream->retrieved); -- bcm2835_playback_fifo(alsa_stream); -- } else { -- LOG_ERR(" .. unexpected alsa_stream=%p\n", -- alsa_stream); -- } -+ LOG_ERR("invalid cookie\n"); -+ else -+ bcm2835_playback_fifo(instance->alsa_stream, -+ m.u.complete.count); - } else { -- LOG_ERR(" .. unexpected m.type=%d\n", m.type); -+ LOG_ERR("unexpected callback type=%d\n", m.type); - } - } - --static struct bcm2835_audio_instance * -+static int - vc_vchi_audio_init(VCHI_INSTANCE_T vchi_instance, -- VCHI_CONNECTION_T *vchi_connection) -+ VCHI_CONNECTION_T *vchi_connection, -+ struct bcm2835_audio_instance *instance) - { - SERVICE_CREATION_T params = { - .version = VCHI_VERSION_EX(VC_AUDIOSERV_VER, VC_AUDIOSERV_MIN_VER), -@@ -298,23 +161,14 @@ vc_vchi_audio_init(VCHI_INSTANCE_T vchi_ - .rx_fifo_size = 0, - .tx_fifo_size = 0, - .callback = audio_vchi_callback, -+ .callback_param = instance, - .want_unaligned_bulk_rx = 1, //TODO: remove VCOS_FALSE - .want_unaligned_bulk_tx = 1, //TODO: remove VCOS_FALSE - .want_crc = 0 - }; -- struct bcm2835_audio_instance *instance; - int status; - -- /* Allocate memory for this instance */ -- instance = kzalloc(sizeof(*instance), GFP_KERNEL); -- if (!instance) -- return ERR_PTR(-ENOMEM); -- -- /* Create a lock for exclusive, serialized VCHI connection access */ -- mutex_init(&instance->vchi_mutex); - /* Open the VCHI service connections */ -- params.callback_param = instance, -- - status = vchi_service_open(vchi_instance, ¶ms, - &instance->vchi_handle); - -@@ -322,16 +176,16 @@ vc_vchi_audio_init(VCHI_INSTANCE_T vchi_ - LOG_ERR("%s: failed to open VCHI service connection (status=%d)\n", - __func__, status); - kfree(instance); -- return ERR_PTR(-EPERM); -+ return -EPERM; - } - - /* Finished with the service for now */ - vchi_service_release(instance->vchi_handle); - -- return instance; -+ return 0; - } - --static int vc_vchi_audio_deinit(struct bcm2835_audio_instance *instance) -+static void vc_vchi_audio_deinit(struct bcm2835_audio_instance *instance) - { - int status; - -@@ -346,10 +200,6 @@ static int vc_vchi_audio_deinit(struct b - } - - mutex_unlock(&instance->vchi_mutex); -- -- kfree(instance); -- -- return 0; - } - - int bcm2835_new_vchi_ctx(struct bcm2835_vchi_ctx *vchi_ctx) -@@ -387,39 +237,25 @@ void bcm2835_free_vchi_ctx(struct bcm283 - vchi_ctx->vchi_instance = NULL; - } - --static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream) --{ -- struct bcm2835_audio_instance *instance = -- (struct bcm2835_audio_instance *)alsa_stream->instance; -- struct bcm2835_vchi_ctx *vhci_ctx = alsa_stream->chip->vchi_ctx; -- -- /* Initialize an instance of the audio service */ -- instance = vc_vchi_audio_init(vhci_ctx->vchi_instance, -- vhci_ctx->vchi_connection); -- -- if (IS_ERR(instance)) -- return PTR_ERR(instance); -- -- instance->alsa_stream = alsa_stream; -- alsa_stream->instance = instance; -- -- return 0; --} -- - int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream) - { -+ struct bcm2835_vchi_ctx *vchi_ctx = alsa_stream->chip->vchi_ctx; - struct bcm2835_audio_instance *instance; - int err; - -- alsa_stream->my_wq = alloc_workqueue("my_queue", WQ_HIGHPRI, 1); -- if (!alsa_stream->my_wq) -+ /* Allocate memory for this instance */ -+ instance = kzalloc(sizeof(*instance), GFP_KERNEL); -+ if (!instance) - return -ENOMEM; -+ mutex_init(&instance->vchi_mutex); -+ instance->alsa_stream = alsa_stream; -+ alsa_stream->instance = instance; - -- err = bcm2835_audio_open_connection(alsa_stream); -+ err = vc_vchi_audio_init(vchi_ctx->vchi_instance, -+ vchi_ctx->vchi_connection, -+ instance); - if (err < 0) -- goto free_wq; -- -- instance = alsa_stream->instance; -+ goto free_instance; - - err = bcm2835_audio_send_simple(instance, VC_AUDIO_MSG_TYPE_OPEN, - false); -@@ -438,8 +274,9 @@ int bcm2835_audio_open(struct bcm2835_al - - deinit: - vc_vchi_audio_deinit(instance); -- free_wq: -- destroy_workqueue(alsa_stream->my_wq); -+ free_instance: -+ alsa_stream->instance = NULL; -+ kfree(instance); - return err; - } - -@@ -478,37 +315,46 @@ int bcm2835_audio_set_params(struct bcm2 - return bcm2835_audio_send_msg(alsa_stream->instance, &m, true); - } - --static int bcm2835_audio_start_worker(struct bcm2835_alsa_stream *alsa_stream) -+int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream) - { - return bcm2835_audio_send_simple(alsa_stream->instance, - VC_AUDIO_MSG_TYPE_START, false); - } - --static int bcm2835_audio_stop_worker(struct bcm2835_alsa_stream *alsa_stream) -+int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream) - { - return bcm2835_audio_send_simple(alsa_stream->instance, - VC_AUDIO_MSG_TYPE_STOP, false); - } - -+int bcm2835_audio_drain(struct bcm2835_alsa_stream *alsa_stream) -+{ -+ struct vc_audio_msg m = { -+ .type = VC_AUDIO_MSG_TYPE_STOP, -+ .u.stop.draining = 1, -+ }; -+ -+ return bcm2835_audio_send_msg(alsa_stream->instance, &m, false); -+} -+ - int bcm2835_audio_close(struct bcm2835_alsa_stream *alsa_stream) - { - struct bcm2835_audio_instance *instance = alsa_stream->instance; - int err; - -- my_workqueue_quit(alsa_stream); -- - err = bcm2835_audio_send_simple(alsa_stream->instance, - VC_AUDIO_MSG_TYPE_CLOSE, true); - - /* Stop the audio service */ - vc_vchi_audio_deinit(instance); - alsa_stream->instance = NULL; -+ kfree(instance); - - return err; - } - --static int bcm2835_audio_write_worker(struct bcm2835_alsa_stream *alsa_stream, -- unsigned int size, void *src) -+int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream, -+ unsigned int size, void *src) - { - struct bcm2835_audio_instance *instance = alsa_stream->instance; - struct vc_audio_msg m = { -@@ -558,13 +404,5 @@ static int bcm2835_audio_write_worker(st - return err; - } - --unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream) --{ -- unsigned int count = atomic_read(&alsa_stream->retrieved); -- -- atomic_sub(count, &alsa_stream->retrieved); -- return count; --} -- - module_param(force_bulk, bool, 0444); - MODULE_PARM_DESC(force_bulk, "Force use of vchiq bulk for audio"); ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -@@ -121,13 +121,12 @@ struct bcm2835_alsa_stream { - - int draining; - -- unsigned int pos; -+ atomic_t pos; -+ unsigned int period_offset; - unsigned int buffer_size; - unsigned int period_size; - -- atomic_t retrieved; - struct bcm2835_audio_instance *instance; -- struct workqueue_struct *my_wq; - int idx; - }; - -@@ -152,11 +151,13 @@ int bcm2835_audio_set_params(struct bcm2 - unsigned int bps); - int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream); - int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream); -+int bcm2835_audio_drain(struct bcm2835_alsa_stream *alsa_stream); - int bcm2835_audio_set_ctls(struct bcm2835_alsa_stream *alsa_stream); - int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream, - unsigned int count, - void *src); --void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream); -+void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream, -+ unsigned int size); - unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream); - - #endif /* __SOUND_ARM_BCM2835_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0459-staging-bcm2835-audio-Remove-unnecessary-header-file.patch b/target/linux/brcm2708/patches-4.19/950-0459-staging-bcm2835-audio-Remove-unnecessary-header-file.patch new file mode 100644 index 0000000000..dce174a5b0 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0459-staging-bcm2835-audio-Remove-unnecessary-header-file.patch @@ -0,0 +1,73 @@ +From abed6180470d4004c4578a7a28b846b3517149f9 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:52 +0200 +Subject: [PATCH 459/725] staging: bcm2835-audio: Remove unnecessary header + file includes + +commit 7e46fff5f19ce2b8a9891e4c08631c64d06e9e17 upstream. + +Yet a few header files are included unnecessarily. Drop them. + +Also remove trivial comments. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../bcm2835-audio/bcm2835-vchiq.c | 19 ------------------- + .../vc04_services/bcm2835-audio/bcm2835.h | 6 ------ + 2 files changed, 25 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +@@ -1,31 +1,12 @@ + // SPDX-License-Identifier: GPL-2.0 + /* Copyright 2011 Broadcom Corporation. All rights reserved. */ + +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include + #include +-#include +-#include + #include + #include +- + #include "bcm2835.h" +- +-/* ---- Include Files -------------------------------------------------------- */ +- + #include "vc_vchi_audioserv_defs.h" + +-/* ---- Private Constants and Types ------------------------------------------ */ +- + struct bcm2835_audio_instance { + struct device *dev; + VCHI_SERVICE_HANDLE_T vchi_handle; +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h +@@ -5,16 +5,10 @@ + #define __SOUND_ARM_BCM2835_H + + #include +-#include +-#include + #include + #include +-#include + #include +-#include + #include +-#include +- + #include "interface/vchi/vchi.h" + + #define MAX_SUBSTREAMS (8) diff --git a/target/linux/brcm2708/patches-4.19/950-0460-staging-bcm2835-audio-Move-module-parameter-descript.patch b/target/linux/brcm2708/patches-4.19/950-0460-staging-bcm2835-audio-Move-module-parameter-descript.patch new file mode 100644 index 0000000000..aa6eaef79a --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0460-staging-bcm2835-audio-Move-module-parameter-descript.patch @@ -0,0 +1,36 @@ +From 7f64018d201f24f5922a61a14363d87560b5b0fd Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:53 +0200 +Subject: [PATCH 460/725] staging: bcm2835-audio: Move module parameter + description + +commit b876f2075808e95e244053caa53fa7e86e929a99 upstream. + +For more consistency, move the module parameter description right +after its variable definition. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +@@ -19,6 +19,8 @@ struct bcm2835_audio_instance { + }; + + static bool force_bulk; ++module_param(force_bulk, bool, 0444); ++MODULE_PARM_DESC(force_bulk, "Force use of vchiq bulk for audio"); + + static void bcm2835_audio_lock(struct bcm2835_audio_instance *instance) + { +@@ -378,6 +380,3 @@ int bcm2835_audio_write(struct bcm2835_a + bcm2835_audio_unlock(instance); + return err; + } +- +-module_param(force_bulk, bool, 0444); +-MODULE_PARM_DESC(force_bulk, "Force use of vchiq bulk for audio"); diff --git a/target/linux/brcm2708/patches-4.19/950-0460-staging-bcm2835-audio-Use-card-private_data.patch b/target/linux/brcm2708/patches-4.19/950-0460-staging-bcm2835-audio-Use-card-private_data.patch deleted file mode 100644 index f97f3124c9..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0460-staging-bcm2835-audio-Use-card-private_data.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 18bd0bcc6b0455640038084fa6ab3b06462319c5 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:50 +0200 -Subject: [PATCH 460/703] staging: bcm2835-audio: Use card->private_data - -commit 898001a0c845cefe5d47d133485712412853f0a8 upstream. - -Instead of allocating a separate snd_device object, let snd_card_new() -allocate the private resource. This simplifies the code. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835.c | 91 +++---------------- - 1 file changed, 13 insertions(+), 78 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -86,9 +86,6 @@ static int bcm2835_devm_add_vchi_ctx(str - - static void snd_bcm2835_release(struct device *dev) - { -- struct bcm2835_chip *chip = dev_get_drvdata(dev); -- -- kfree(chip); - } - - static struct device * -@@ -117,69 +114,6 @@ snd_create_device(struct device *parent, - return device; - } - --/* component-destructor -- * (see "Management of Cards and Components") -- */ --static int snd_bcm2835_dev_free(struct snd_device *device) --{ -- struct bcm2835_chip *chip = device->device_data; -- struct snd_card *card = chip->card; -- -- snd_device_free(card, chip); -- -- return 0; --} -- --/* chip-specific constructor -- * (see "Management of Cards and Components") -- */ --static int snd_bcm2835_create(struct snd_card *card, -- struct bcm2835_chip **rchip) --{ -- struct bcm2835_chip *chip; -- int err; -- static struct snd_device_ops ops = { -- .dev_free = snd_bcm2835_dev_free, -- }; -- -- *rchip = NULL; -- -- chip = kzalloc(sizeof(*chip), GFP_KERNEL); -- if (!chip) -- return -ENOMEM; -- -- chip->card = card; -- mutex_init(&chip->audio_mutex); -- -- chip->vchi_ctx = devres_find(card->dev->parent, -- bcm2835_devm_free_vchi_ctx, NULL, NULL); -- if (!chip->vchi_ctx) { -- kfree(chip); -- return -ENODEV; -- } -- -- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); -- if (err) { -- kfree(chip); -- return err; -- } -- -- *rchip = chip; -- return 0; --} -- --static struct snd_card *snd_bcm2835_card_new(struct device *dev) --{ -- struct snd_card *card; -- int ret; -- -- ret = snd_card_new(dev, -1, NULL, THIS_MODULE, 0, &card); -- if (ret) -- return ERR_PTR(ret); -- -- return card; --} -- - typedef int (*bcm2835_audio_newpcm_func)(struct bcm2835_chip *chip, - const char *name, - enum snd_bcm2835_route route, -@@ -292,25 +226,26 @@ static int snd_add_child_device(struct d - return PTR_ERR(child); - } - -- card = snd_bcm2835_card_new(child); -- if (IS_ERR(card)) { -+ err = snd_card_new(child, -1, NULL, THIS_MODULE, sizeof(*chip), &card); -+ if (err < 0) { - dev_err(child, "Failed to create card"); -- return PTR_ERR(card); -+ return err; - } - -- snd_card_set_dev(card, child); -+ chip = card->private_data; -+ chip->card = card; -+ chip->dev = child; -+ mutex_init(&chip->audio_mutex); -+ -+ chip->vchi_ctx = devres_find(device, -+ bcm2835_devm_free_vchi_ctx, NULL, NULL); -+ if (!chip->vchi_ctx) -+ return -ENODEV; -+ - strcpy(card->driver, audio_driver->driver.name); - strcpy(card->shortname, audio_driver->shortname); - strcpy(card->longname, audio_driver->longname); - -- err = snd_bcm2835_create(card, &chip); -- if (err) { -- dev_err(child, "Failed to create chip, error %d\n", err); -- return err; -- } -- -- chip->dev = child; -- - err = audio_driver->newpcm(chip, audio_driver->shortname, - audio_driver->route, - numchans); diff --git a/target/linux/brcm2708/patches-4.19/950-0461-staging-bcm2835-audio-Use-coherent-device-buffers.patch b/target/linux/brcm2708/patches-4.19/950-0461-staging-bcm2835-audio-Use-coherent-device-buffers.patch new file mode 100644 index 0000000000..14347aa87f --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0461-staging-bcm2835-audio-Use-coherent-device-buffers.patch @@ -0,0 +1,61 @@ +From eeb863318a36c32dd4bb6a5767980485050cd85c Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:54 +0200 +Subject: [PATCH 461/725] staging: bcm2835-audio: Use coherent device buffers + +commit ad29c6e6cbf6f2af7362b043adad51a3be3d39c7 upstream. + +The memory access to the pages allocated with +SNDRV_DMA_TYPE_CONTINUOUS are basically non-coherent, and it becomes a +problem when a process accesses via mmap. + +For the more consistent access, use the device coherent memory, just +by replacing the call pattern in the allocator helpers. + +The only point we need to be careful for is the device object passed +there; since bcm2835-audio driver creates fake devices and each card +is created on top of that, we need to pass its parent device as the +real device object. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -345,8 +345,8 @@ int snd_bcm2835_new_pcm(struct bcm2835_c + + /* pre-allocation of buffers */ + /* NOTE: this may fail */ +- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, +- snd_dma_continuous_data(GFP_KERNEL), ++ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, ++ chip->card->dev->parent, + snd_bcm2835_playback_hw.buffer_bytes_max, + snd_bcm2835_playback_hw.buffer_bytes_max); + +@@ -371,8 +371,8 @@ int snd_bcm2835_new_spdif_pcm(struct bcm + + /* pre-allocation of buffers */ + /* NOTE: this may fail */ +- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, +- snd_dma_continuous_data(GFP_KERNEL), ++ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, ++ chip->card->dev->parent, + snd_bcm2835_playback_spdif_hw.buffer_bytes_max, snd_bcm2835_playback_spdif_hw.buffer_bytes_max); + + return 0; +@@ -404,8 +404,8 @@ int snd_bcm2835_new_simple_pcm(struct bc + + snd_pcm_lib_preallocate_pages_for_all( + pcm, +- SNDRV_DMA_TYPE_CONTINUOUS, +- snd_dma_continuous_data(GFP_KERNEL), ++ SNDRV_DMA_TYPE_DEV, ++ chip->card->dev->parent, + snd_bcm2835_playback_hw.buffer_bytes_max, + snd_bcm2835_playback_hw.buffer_bytes_max); + diff --git a/target/linux/brcm2708/patches-4.19/950-0461-staging-bcm2835-audio-Use-standard-error-print-helpe.patch b/target/linux/brcm2708/patches-4.19/950-0461-staging-bcm2835-audio-Use-standard-error-print-helpe.patch deleted file mode 100644 index 762de4b21f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0461-staging-bcm2835-audio-Use-standard-error-print-helpe.patch +++ /dev/null @@ -1,237 +0,0 @@ -From 1dff63cdd20b6dfc763d01d35dff231b8abe8175 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:51 +0200 -Subject: [PATCH 461/703] staging: bcm2835-audio: Use standard error print - helpers - -commit b7584b64168208ebc14160770c0966b8b12fc16b upstream. - -For making the whole code more consistent, replace the home-made debug -print macros with the standard dev_err() & co. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 4 +- - .../bcm2835-audio/bcm2835-vchiq.c | 52 ++++++++----------- - .../vc04_services/bcm2835-audio/bcm2835.c | 2 +- - .../vc04_services/bcm2835-audio/bcm2835.h | 43 +-------------- - 4 files changed, 27 insertions(+), 74 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -101,8 +101,8 @@ static int snd_bcm2835_playback_open_gen - goto out; - } - if (idx >= MAX_SUBSTREAMS) { -- audio_error -- ("substream(%d) device doesn't exist max(%d) substreams allowed\n", -+ dev_err(chip->dev, -+ "substream(%d) device doesn't exist max(%d) substreams allowed\n", - idx, MAX_SUBSTREAMS); - err = -ENODEV; - goto out; ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -@@ -26,20 +26,8 @@ - - /* ---- Private Constants and Types ------------------------------------------ */ - --/* Logging macros (for remapping to other logging mechanisms, i.e., printf) */ --#ifdef AUDIO_DEBUG_ENABLE --#define LOG_ERR(fmt, arg...) pr_err("%s:%d " fmt, __func__, __LINE__, ##arg) --#define LOG_WARN(fmt, arg...) pr_info("%s:%d " fmt, __func__, __LINE__, ##arg) --#define LOG_INFO(fmt, arg...) pr_info("%s:%d " fmt, __func__, __LINE__, ##arg) --#define LOG_DBG(fmt, arg...) pr_info("%s:%d " fmt, __func__, __LINE__, ##arg) --#else --#define LOG_ERR(fmt, arg...) pr_err("%s:%d " fmt, __func__, __LINE__, ##arg) --#define LOG_WARN(fmt, arg...) no_printk(fmt, ##arg) --#define LOG_INFO(fmt, arg...) no_printk(fmt, ##arg) --#define LOG_DBG(fmt, arg...) no_printk(fmt, ##arg) --#endif -- - struct bcm2835_audio_instance { -+ struct device *dev; - VCHI_SERVICE_HANDLE_T vchi_handle; - struct completion msg_avail_comp; - struct mutex vchi_mutex; -@@ -76,7 +64,8 @@ static int bcm2835_audio_send_msg_locked - status = vchi_queue_kernel_message(instance->vchi_handle, - m, sizeof(*m)); - if (status) { -- LOG_ERR("vchi message queue failed: %d, msg=%d\n", -+ dev_err(instance->dev, -+ "vchi message queue failed: %d, msg=%d\n", - status, m->type); - return -EIO; - } -@@ -84,10 +73,12 @@ static int bcm2835_audio_send_msg_locked - if (wait) { - if (!wait_for_completion_timeout(&instance->msg_avail_comp, - msecs_to_jiffies(10 * 1000))) { -- LOG_ERR("vchi message timeout, msg=%d\n", m->type); -+ dev_err(instance->dev, -+ "vchi message timeout, msg=%d\n", m->type); - return -ETIMEDOUT; - } else if (instance->result) { -- LOG_ERR("vchi message response error:%d, msg=%d\n", -+ dev_err(instance->dev, -+ "vchi message response error:%d, msg=%d\n", - instance->result, m->type); - return -EIO; - } -@@ -140,12 +131,12 @@ static void audio_vchi_callback(void *pa - } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) { - if (m.u.complete.cookie1 != BCM2835_AUDIO_WRITE_COOKIE1 || - m.u.complete.cookie2 != BCM2835_AUDIO_WRITE_COOKIE2) -- LOG_ERR("invalid cookie\n"); -+ dev_err(instance->dev, "invalid cookie\n"); - else - bcm2835_playback_fifo(instance->alsa_stream, - m.u.complete.count); - } else { -- LOG_ERR("unexpected callback type=%d\n", m.type); -+ dev_err(instance->dev, "unexpected callback type=%d\n", m.type); - } - } - -@@ -173,8 +164,9 @@ vc_vchi_audio_init(VCHI_INSTANCE_T vchi_ - &instance->vchi_handle); - - if (status) { -- LOG_ERR("%s: failed to open VCHI service connection (status=%d)\n", -- __func__, status); -+ dev_err(instance->dev, -+ "failed to open VCHI service connection (status=%d)\n", -+ status); - kfree(instance); - return -EPERM; - } -@@ -195,30 +187,30 @@ static void vc_vchi_audio_deinit(struct - /* Close all VCHI service connections */ - status = vchi_service_close(instance->vchi_handle); - if (status) { -- LOG_DBG("%s: failed to close VCHI service connection (status=%d)\n", -- __func__, status); -+ dev_err(instance->dev, -+ "failed to close VCHI service connection (status=%d)\n", -+ status); - } - - mutex_unlock(&instance->vchi_mutex); - } - --int bcm2835_new_vchi_ctx(struct bcm2835_vchi_ctx *vchi_ctx) -+int bcm2835_new_vchi_ctx(struct device *dev, struct bcm2835_vchi_ctx *vchi_ctx) - { - int ret; - - /* Initialize and create a VCHI connection */ - ret = vchi_initialise(&vchi_ctx->vchi_instance); - if (ret) { -- LOG_ERR("%s: failed to initialise VCHI instance (ret=%d)\n", -- __func__, ret); -- -+ dev_err(dev, "failed to initialise VCHI instance (ret=%d)\n", -+ ret); - return -EIO; - } - - ret = vchi_connect(NULL, 0, vchi_ctx->vchi_instance); - if (ret) { -- LOG_ERR("%s: failed to connect VCHI instance (ret=%d)\n", -- __func__, ret); -+ dev_dbg(dev, "failed to connect VCHI instance (ret=%d)\n", -+ ret); - - kfree(vchi_ctx->vchi_instance); - vchi_ctx->vchi_instance = NULL; -@@ -248,6 +240,7 @@ int bcm2835_audio_open(struct bcm2835_al - if (!instance) - return -ENOMEM; - mutex_init(&instance->vchi_mutex); -+ instance->dev = alsa_stream->chip->dev; - instance->alsa_stream = alsa_stream; - alsa_stream->instance = instance; - -@@ -394,7 +387,8 @@ int bcm2835_audio_write(struct bcm2835_a - } - - if (status) { -- LOG_ERR("failed on %d bytes transfer (status=%d)\n", -+ dev_err(instance->dev, -+ "failed on %d bytes transfer (status=%d)\n", - size, status); - err = -EIO; - } ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -73,7 +73,7 @@ static int bcm2835_devm_add_vchi_ctx(str - - memset(vchi_ctx, 0, sizeof(*vchi_ctx)); - -- ret = bcm2835_new_vchi_ctx(vchi_ctx); -+ ret = bcm2835_new_vchi_ctx(dev, vchi_ctx); - if (ret) { - devres_free(vchi_ctx); - return ret; ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -@@ -17,47 +17,6 @@ - - #include "interface/vchi/vchi.h" - --/* -- * #define AUDIO_DEBUG_ENABLE -- * #define AUDIO_VERBOSE_DEBUG_ENABLE -- */ -- --/* Debug macros */ -- --#ifdef AUDIO_DEBUG_ENABLE --#ifdef AUDIO_VERBOSE_DEBUG_ENABLE -- --#define audio_debug(fmt, arg...) \ -- pr_info("%s:%d " fmt, __func__, __LINE__, ##arg) -- --#define audio_info(fmt, arg...) \ -- pr_info("%s:%d " fmt, __func__, __LINE__, ##arg) -- --#else -- --#define audio_debug(fmt, arg...) -- --#define audio_info(fmt, arg...) -- --#endif /* AUDIO_VERBOSE_DEBUG_ENABLE */ -- --#else -- --#define audio_debug(fmt, arg...) -- --#define audio_info(fmt, arg...) -- --#endif /* AUDIO_DEBUG_ENABLE */ -- --#define audio_error(fmt, arg...) \ -- pr_err("%s:%d " fmt, __func__, __LINE__, ##arg) -- --#define audio_warning(fmt, arg...) \ -- pr_warn("%s:%d " fmt, __func__, __LINE__, ##arg) -- --#define audio_alert(fmt, arg...) \ -- pr_alert("%s:%d " fmt, __func__, __LINE__, ##arg) -- - #define MAX_SUBSTREAMS (8) - #define AVAIL_SUBSTREAMS_MASK (0xff) - -@@ -141,7 +100,7 @@ int snd_bcm2835_new_simple_pcm(struct bc - int snd_bcm2835_new_hdmi_ctl(struct bcm2835_chip *chip); - int snd_bcm2835_new_headphones_ctl(struct bcm2835_chip *chip); - --int bcm2835_new_vchi_ctx(struct bcm2835_vchi_ctx *vchi_ctx); -+int bcm2835_new_vchi_ctx(struct device *dev, struct bcm2835_vchi_ctx *vchi_ctx); - void bcm2835_free_vchi_ctx(struct bcm2835_vchi_ctx *vchi_ctx); - - int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream); diff --git a/target/linux/brcm2708/patches-4.19/950-0462-staging-bcm2835-audio-Remove-unnecessary-header-file.patch b/target/linux/brcm2708/patches-4.19/950-0462-staging-bcm2835-audio-Remove-unnecessary-header-file.patch deleted file mode 100644 index 1f50734257..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0462-staging-bcm2835-audio-Remove-unnecessary-header-file.patch +++ /dev/null @@ -1,73 +0,0 @@ -From d202703ef99f5d370997c2372e8b0e0873834868 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:52 +0200 -Subject: [PATCH 462/703] staging: bcm2835-audio: Remove unnecessary header - file includes - -commit 7e46fff5f19ce2b8a9891e4c08631c64d06e9e17 upstream. - -Yet a few header files are included unnecessarily. Drop them. - -Also remove trivial comments. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../bcm2835-audio/bcm2835-vchiq.c | 19 ------------------- - .../vc04_services/bcm2835-audio/bcm2835.h | 6 ------ - 2 files changed, 25 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -@@ -1,31 +1,12 @@ - // SPDX-License-Identifier: GPL-2.0 - /* Copyright 2011 Broadcom Corporation. All rights reserved. */ - --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include - #include --#include --#include - #include - #include -- - #include "bcm2835.h" -- --/* ---- Include Files -------------------------------------------------------- */ -- - #include "vc_vchi_audioserv_defs.h" - --/* ---- Private Constants and Types ------------------------------------------ */ -- - struct bcm2835_audio_instance { - struct device *dev; - VCHI_SERVICE_HANDLE_T vchi_handle; ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -@@ -5,16 +5,10 @@ - #define __SOUND_ARM_BCM2835_H - - #include --#include --#include - #include - #include --#include - #include --#include - #include --#include -- - #include "interface/vchi/vchi.h" - - #define MAX_SUBSTREAMS (8) diff --git a/target/linux/brcm2708/patches-4.19/950-0462-staging-bcm2835-audio-Set-SNDRV_PCM_INFO_SYNC_APPLPT.patch b/target/linux/brcm2708/patches-4.19/950-0462-staging-bcm2835-audio-Set-SNDRV_PCM_INFO_SYNC_APPLPT.patch new file mode 100644 index 0000000000..d74445d006 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0462-staging-bcm2835-audio-Set-SNDRV_PCM_INFO_SYNC_APPLPT.patch @@ -0,0 +1,40 @@ +From e700838ddf8bdae4ecf25d031e46d8624eba00e1 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:55 +0200 +Subject: [PATCH 462/725] staging: bcm2835-audio: Set + SNDRV_PCM_INFO_SYNC_APPLPTR + +commit b59d6a5f73501f74848d6700101e7736afe3d54a upstream. + +The recent ALSA PCM core supports the SNDRV_PCM_INFO_SYNC_APPLPTR flag +indicating that the driver needs the ack call at each appl_ptr +update. This is requirement for the indirect PCM implementations like +bcm2835-audio driver, too. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -12,7 +12,7 @@ + static const struct snd_pcm_hardware snd_bcm2835_playback_hw = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | +- SNDRV_PCM_INFO_DRAIN_TRIGGER), ++ SNDRV_PCM_INFO_DRAIN_TRIGGER | SNDRV_PCM_INFO_SYNC_APPLPTR), + .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, + .rate_min = 8000, +@@ -29,7 +29,7 @@ static const struct snd_pcm_hardware snd + static const struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | +- SNDRV_PCM_INFO_DRAIN_TRIGGER), ++ SNDRV_PCM_INFO_DRAIN_TRIGGER | SNDRV_PCM_INFO_SYNC_APPLPTR), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000, diff --git a/target/linux/brcm2708/patches-4.19/950-0463-staging-bcm2835-audio-Move-module-parameter-descript.patch b/target/linux/brcm2708/patches-4.19/950-0463-staging-bcm2835-audio-Move-module-parameter-descript.patch deleted file mode 100644 index b50ba98765..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0463-staging-bcm2835-audio-Move-module-parameter-descript.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 4337174647cfd9a5bde517543ec1093d43c81522 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:53 +0200 -Subject: [PATCH 463/703] staging: bcm2835-audio: Move module parameter - description - -commit b876f2075808e95e244053caa53fa7e86e929a99 upstream. - -For more consistency, move the module parameter description right -after its variable definition. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -@@ -19,6 +19,8 @@ struct bcm2835_audio_instance { - }; - - static bool force_bulk; -+module_param(force_bulk, bool, 0444); -+MODULE_PARM_DESC(force_bulk, "Force use of vchiq bulk for audio"); - - static void bcm2835_audio_lock(struct bcm2835_audio_instance *instance) - { -@@ -378,6 +380,3 @@ int bcm2835_audio_write(struct bcm2835_a - bcm2835_audio_unlock(instance); - return err; - } -- --module_param(force_bulk, bool, 0444); --MODULE_PARM_DESC(force_bulk, "Force use of vchiq bulk for audio"); diff --git a/target/linux/brcm2708/patches-4.19/950-0463-staging-bcm2835-audio-Simplify-PCM-creation-helpers.patch b/target/linux/brcm2708/patches-4.19/950-0463-staging-bcm2835-audio-Simplify-PCM-creation-helpers.patch new file mode 100644 index 0000000000..2798db416e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0463-staging-bcm2835-audio-Simplify-PCM-creation-helpers.patch @@ -0,0 +1,196 @@ +From dc765e2328fdd22b055101bbe848fb50b0a592b9 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:56 +0200 +Subject: [PATCH 463/725] staging: bcm2835-audio: Simplify PCM creation helpers + +commit 74470ffeb9aed5548654cfca881bf1d7469fe9c4 upstream. + +All three functions to create PCM objects are fairly resemble, and can +be unified to a single common helper. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 87 ++++--------------- + .../vc04_services/bcm2835-audio/bcm2835.c | 17 +++- + .../vc04_services/bcm2835-audio/bcm2835.h | 9 +- + 3 files changed, 32 insertions(+), 81 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -324,91 +324,36 @@ static const struct snd_pcm_ops snd_bcm2 + }; + + /* create a pcm device */ +-int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, u32 numchannels) ++int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, const char *name, ++ int idx, enum snd_bcm2835_route route, ++ u32 numchannels, bool spdif) + { + struct snd_pcm *pcm; + int err; + +- err = snd_pcm_new(chip->card, "bcm2835 ALSA", 0, numchannels, 0, &pcm); +- if (err < 0) +- return err; +- pcm->private_data = chip; +- pcm->nonatomic = true; +- strcpy(pcm->name, "bcm2835 ALSA"); +- chip->pcm = pcm; +- chip->dest = AUDIO_DEST_AUTO; +- chip->volume = 0; +- chip->mute = CTRL_VOL_UNMUTE; /*disable mute on startup */ +- /* set operators */ +- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, +- &snd_bcm2835_playback_ops); +- +- /* pre-allocation of buffers */ +- /* NOTE: this may fail */ +- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, +- chip->card->dev->parent, +- snd_bcm2835_playback_hw.buffer_bytes_max, +- snd_bcm2835_playback_hw.buffer_bytes_max); +- +- return 0; +-} +- +-int snd_bcm2835_new_spdif_pcm(struct bcm2835_chip *chip) +-{ +- struct snd_pcm *pcm; +- int err; +- +- err = snd_pcm_new(chip->card, "bcm2835 ALSA", 1, 1, 0, &pcm); +- if (err < 0) +- return err; +- +- pcm->private_data = chip; +- pcm->nonatomic = true; +- strcpy(pcm->name, "bcm2835 IEC958/HDMI"); +- chip->pcm_spdif = pcm; +- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, +- &snd_bcm2835_playback_spdif_ops); +- +- /* pre-allocation of buffers */ +- /* NOTE: this may fail */ +- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, +- chip->card->dev->parent, +- snd_bcm2835_playback_spdif_hw.buffer_bytes_max, snd_bcm2835_playback_spdif_hw.buffer_bytes_max); +- +- return 0; +-} +- +-int snd_bcm2835_new_simple_pcm(struct bcm2835_chip *chip, +- const char *name, +- enum snd_bcm2835_route route, +- u32 numchannels) +-{ +- struct snd_pcm *pcm; +- int err; +- +- err = snd_pcm_new(chip->card, name, 0, numchannels, +- 0, &pcm); ++ err = snd_pcm_new(chip->card, name, idx, numchannels, 0, &pcm); + if (err) + return err; + + pcm->private_data = chip; + pcm->nonatomic = true; + strcpy(pcm->name, name); +- chip->pcm = pcm; +- chip->dest = route; +- chip->volume = 0; +- chip->mute = CTRL_VOL_UNMUTE; ++ if (!spdif) { ++ chip->dest = route; ++ chip->volume = 0; ++ chip->mute = CTRL_VOL_UNMUTE; ++ } + + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, ++ spdif ? &snd_bcm2835_playback_spdif_ops : + &snd_bcm2835_playback_ops); + +- snd_pcm_lib_preallocate_pages_for_all( +- pcm, +- SNDRV_DMA_TYPE_DEV, +- chip->card->dev->parent, +- snd_bcm2835_playback_hw.buffer_bytes_max, +- snd_bcm2835_playback_hw.buffer_bytes_max); ++ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, ++ chip->card->dev->parent, 128 * 1024, 128 * 1024); + ++ if (spdif) ++ chip->pcm_spdif = pcm; ++ else ++ chip->pcm = pcm; + return 0; + } +- +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +@@ -138,17 +138,26 @@ static int bcm2835_audio_alsa_newpcm(str + { + int err; + +- err = snd_bcm2835_new_pcm(chip, numchannels - 1); ++ err = snd_bcm2835_new_pcm(chip, "bcm2835 ALSA", 0, AUDIO_DEST_AUTO, ++ numchannels - 1, false); + if (err) + return err; + +- err = snd_bcm2835_new_spdif_pcm(chip); ++ err = snd_bcm2835_new_pcm(chip, "bcm2835 IEC958/HDMI", 1, 0, 1, true); + if (err) + return err; + + return 0; + } + ++static int bcm2835_audio_simple_newpcm(struct bcm2835_chip *chip, ++ const char *name, ++ enum snd_bcm2835_route route, ++ u32 numchannels) ++{ ++ return snd_bcm2835_new_pcm(chip, name, 0, route, numchannels, false); ++} ++ + static struct bcm2835_audio_driver bcm2835_audio_alsa = { + .driver = { + .name = "bcm2835_alsa", +@@ -169,7 +178,7 @@ static struct bcm2835_audio_driver bcm28 + .shortname = "bcm2835 HDMI", + .longname = "bcm2835 HDMI", + .minchannels = 1, +- .newpcm = snd_bcm2835_new_simple_pcm, ++ .newpcm = bcm2835_audio_simple_newpcm, + .newctl = snd_bcm2835_new_hdmi_ctl, + .route = AUDIO_DEST_HDMI + }; +@@ -182,7 +191,7 @@ static struct bcm2835_audio_driver bcm28 + .shortname = "bcm2835 Headphones", + .longname = "bcm2835 Headphones", + .minchannels = 1, +- .newpcm = snd_bcm2835_new_simple_pcm, ++ .newpcm = bcm2835_audio_simple_newpcm, + .newctl = snd_bcm2835_new_headphones_ctl, + .route = AUDIO_DEST_HEADPHONES + }; +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h +@@ -84,12 +84,9 @@ struct bcm2835_alsa_stream { + }; + + int snd_bcm2835_new_ctl(struct bcm2835_chip *chip); +-int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, u32 numchannels); +-int snd_bcm2835_new_spdif_pcm(struct bcm2835_chip *chip); +-int snd_bcm2835_new_simple_pcm(struct bcm2835_chip *chip, +- const char *name, +- enum snd_bcm2835_route route, +- u32 numchannels); ++int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, const char *name, ++ int idx, enum snd_bcm2835_route route, ++ u32 numchannels, bool spdif); + + int snd_bcm2835_new_hdmi_ctl(struct bcm2835_chip *chip); + int snd_bcm2835_new_headphones_ctl(struct bcm2835_chip *chip); diff --git a/target/linux/brcm2708/patches-4.19/950-0464-staging-bcm2835-audio-Simplify-kctl-creation-helpers.patch b/target/linux/brcm2708/patches-4.19/950-0464-staging-bcm2835-audio-Simplify-kctl-creation-helpers.patch new file mode 100644 index 0000000000..792b1b8a50 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0464-staging-bcm2835-audio-Simplify-kctl-creation-helpers.patch @@ -0,0 +1,161 @@ +From 9b2cae69685c0cb362aba7341acec397b783e49b Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:57 +0200 +Subject: [PATCH 464/725] staging: bcm2835-audio: Simplify kctl creation + helpers + +commit dc5c0eb1e8601206dffbfc302cbd190f89dcd040 upstream. + +Just a minor code refactoring and adding some const prefix. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-ctl.c | 69 +++++++------------ + 1 file changed, 25 insertions(+), 44 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c +@@ -97,40 +97,34 @@ static int snd_bcm2835_ctl_put(struct sn + + static DECLARE_TLV_DB_SCALE(snd_bcm2835_db_scale, CTRL_VOL_MIN, 1, 1); + +-static struct snd_kcontrol_new snd_bcm2835_ctl[] = { ++static const struct snd_kcontrol_new snd_bcm2835_ctl[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "PCM Playback Volume", +- .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, + .private_value = PCM_PLAYBACK_VOLUME, + .info = snd_bcm2835_ctl_info, + .get = snd_bcm2835_ctl_get, + .put = snd_bcm2835_ctl_put, +- .count = 1, + .tlv = {.p = snd_bcm2835_db_scale} + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "PCM Playback Switch", +- .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = PCM_PLAYBACK_MUTE, + .info = snd_bcm2835_ctl_info, + .get = snd_bcm2835_ctl_get, + .put = snd_bcm2835_ctl_put, +- .count = 1, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "PCM Playback Route", +- .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = PCM_PLAYBACK_DEVICE, + .info = snd_bcm2835_ctl_info, + .get = snd_bcm2835_ctl_get, + .put = snd_bcm2835_ctl_put, +- .count = 1, + }, + }; + +@@ -196,7 +190,7 @@ static int snd_bcm2835_spdif_mask_get(st + return 0; + } + +-static struct snd_kcontrol_new snd_bcm2835_spdif[] = { ++static const struct snd_kcontrol_new snd_bcm2835_spdif[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), +@@ -213,28 +207,32 @@ static struct snd_kcontrol_new snd_bcm28 + }, + }; + +-int snd_bcm2835_new_ctl(struct bcm2835_chip *chip) ++static int create_ctls(struct bcm2835_chip *chip, size_t size, ++ const struct snd_kcontrol_new *kctls) + { +- int err; +- unsigned int idx; ++ int i, err; + +- strcpy(chip->card->mixername, "Broadcom Mixer"); +- for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_ctl); idx++) { +- err = snd_ctl_add(chip->card, +- snd_ctl_new1(&snd_bcm2835_ctl[idx], chip)); +- if (err < 0) +- return err; +- } +- for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_spdif); idx++) { +- err = snd_ctl_add(chip->card, +- snd_ctl_new1(&snd_bcm2835_spdif[idx], chip)); ++ for (i = 0; i < size; i++) { ++ err = snd_ctl_add(chip->card, snd_ctl_new1(&kctls[i], chip)); + if (err < 0) + return err; + } + return 0; + } + +-static struct snd_kcontrol_new snd_bcm2835_headphones_ctl[] = { ++int snd_bcm2835_new_ctl(struct bcm2835_chip *chip) ++{ ++ int err; ++ ++ strcpy(chip->card->mixername, "Broadcom Mixer"); ++ err = create_ctls(chip, ARRAY_SIZE(snd_bcm2835_ctl), snd_bcm2835_ctl); ++ if (err < 0) ++ return err; ++ return create_ctls(chip, ARRAY_SIZE(snd_bcm2835_spdif), ++ snd_bcm2835_spdif); ++} ++ ++static const struct snd_kcontrol_new snd_bcm2835_headphones_ctl[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Headphone Playback Volume", +@@ -263,21 +261,12 @@ static struct snd_kcontrol_new snd_bcm28 + + int snd_bcm2835_new_headphones_ctl(struct bcm2835_chip *chip) + { +- int err; +- unsigned int idx; +- + strcpy(chip->card->mixername, "Broadcom Mixer"); +- for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_headphones_ctl); idx++) { +- err = snd_ctl_add(chip->card, +- snd_ctl_new1(&snd_bcm2835_headphones_ctl[idx], +- chip)); +- if (err) +- return err; +- } +- return 0; ++ return create_ctls(chip, ARRAY_SIZE(snd_bcm2835_headphones_ctl), ++ snd_bcm2835_headphones_ctl); + } + +-static struct snd_kcontrol_new snd_bcm2835_hdmi[] = { ++static const struct snd_kcontrol_new snd_bcm2835_hdmi[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "HDMI Playback Volume", +@@ -306,16 +295,8 @@ static struct snd_kcontrol_new snd_bcm28 + + int snd_bcm2835_new_hdmi_ctl(struct bcm2835_chip *chip) + { +- int err; +- unsigned int idx; +- + strcpy(chip->card->mixername, "Broadcom Mixer"); +- for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_hdmi); idx++) { +- err = snd_ctl_add(chip->card, +- snd_ctl_new1(&snd_bcm2835_hdmi[idx], chip)); +- if (err) +- return err; +- } +- return 0; ++ return create_ctls(chip, ARRAY_SIZE(snd_bcm2835_hdmi), ++ snd_bcm2835_hdmi); + } + diff --git a/target/linux/brcm2708/patches-4.19/950-0464-staging-bcm2835-audio-Use-coherent-device-buffers.patch b/target/linux/brcm2708/patches-4.19/950-0464-staging-bcm2835-audio-Use-coherent-device-buffers.patch deleted file mode 100644 index 384eb49d6f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0464-staging-bcm2835-audio-Use-coherent-device-buffers.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 4ff1a81a824daafb1c0fd56d299852ada0dd0b05 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:54 +0200 -Subject: [PATCH 464/703] staging: bcm2835-audio: Use coherent device buffers - -commit ad29c6e6cbf6f2af7362b043adad51a3be3d39c7 upstream. - -The memory access to the pages allocated with -SNDRV_DMA_TYPE_CONTINUOUS are basically non-coherent, and it becomes a -problem when a process accesses via mmap. - -For the more consistent access, use the device coherent memory, just -by replacing the call pattern in the allocator helpers. - -The only point we need to be careful for is the device object passed -there; since bcm2835-audio driver creates fake devices and each card -is created on top of that, we need to pass its parent device as the -real device object. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -345,8 +345,8 @@ int snd_bcm2835_new_pcm(struct bcm2835_c - - /* pre-allocation of buffers */ - /* NOTE: this may fail */ -- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, -- snd_dma_continuous_data(GFP_KERNEL), -+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, -+ chip->card->dev->parent, - snd_bcm2835_playback_hw.buffer_bytes_max, - snd_bcm2835_playback_hw.buffer_bytes_max); - -@@ -371,8 +371,8 @@ int snd_bcm2835_new_spdif_pcm(struct bcm - - /* pre-allocation of buffers */ - /* NOTE: this may fail */ -- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, -- snd_dma_continuous_data(GFP_KERNEL), -+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, -+ chip->card->dev->parent, - snd_bcm2835_playback_spdif_hw.buffer_bytes_max, snd_bcm2835_playback_spdif_hw.buffer_bytes_max); - - return 0; -@@ -404,8 +404,8 @@ int snd_bcm2835_new_simple_pcm(struct bc - - snd_pcm_lib_preallocate_pages_for_all( - pcm, -- SNDRV_DMA_TYPE_CONTINUOUS, -- snd_dma_continuous_data(GFP_KERNEL), -+ SNDRV_DMA_TYPE_DEV, -+ chip->card->dev->parent, - snd_bcm2835_playback_hw.buffer_bytes_max, - snd_bcm2835_playback_hw.buffer_bytes_max); - diff --git a/target/linux/brcm2708/patches-4.19/950-0465-staging-bcm2835-audio-Set-SNDRV_PCM_INFO_SYNC_APPLPT.patch b/target/linux/brcm2708/patches-4.19/950-0465-staging-bcm2835-audio-Set-SNDRV_PCM_INFO_SYNC_APPLPT.patch deleted file mode 100644 index 2eda52040d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0465-staging-bcm2835-audio-Set-SNDRV_PCM_INFO_SYNC_APPLPT.patch +++ /dev/null @@ -1,40 +0,0 @@ -From b30057f82f95a75c641ff5ffe6bdb4d4507ecd8e Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:55 +0200 -Subject: [PATCH 465/703] staging: bcm2835-audio: Set - SNDRV_PCM_INFO_SYNC_APPLPTR - -commit b59d6a5f73501f74848d6700101e7736afe3d54a upstream. - -The recent ALSA PCM core supports the SNDRV_PCM_INFO_SYNC_APPLPTR flag -indicating that the driver needs the ack call at each appl_ptr -update. This is requirement for the indirect PCM implementations like -bcm2835-audio driver, too. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -12,7 +12,7 @@ - static const struct snd_pcm_hardware snd_bcm2835_playback_hw = { - .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | -- SNDRV_PCM_INFO_DRAIN_TRIGGER), -+ SNDRV_PCM_INFO_DRAIN_TRIGGER | SNDRV_PCM_INFO_SYNC_APPLPTR), - .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, - .rate_min = 8000, -@@ -29,7 +29,7 @@ static const struct snd_pcm_hardware snd - static const struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = { - .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | -- SNDRV_PCM_INFO_DRAIN_TRIGGER), -+ SNDRV_PCM_INFO_DRAIN_TRIGGER | SNDRV_PCM_INFO_SYNC_APPLPTR), - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000, diff --git a/target/linux/brcm2708/patches-4.19/950-0465-staging-bcm2835-audio-Simplify-card-object-managemen.patch b/target/linux/brcm2708/patches-4.19/950-0465-staging-bcm2835-audio-Simplify-card-object-managemen.patch new file mode 100644 index 0000000000..fd7d38c8d2 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0465-staging-bcm2835-audio-Simplify-card-object-managemen.patch @@ -0,0 +1,212 @@ +From 61a4c0f40810dde6cd4d562d452defcefdddd27a Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:58 +0200 +Subject: [PATCH 465/725] staging: bcm2835-audio: Simplify card object + management + +commit 872ae2d63d516a2a3b9c833d8685afcfa7814542 upstream. + +Instead of creating a dummy child device to manage the card object, +just use devm stuff directly for releasing with snd_card_free(). +This results in a lot of code reduction. + +Since the dummy child devices are gone, the device object to be passed +to the memory allocator needs to be adjusted as well. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 2 +- + .../vc04_services/bcm2835-audio/bcm2835.c | 120 +++++------------- + 2 files changed, 33 insertions(+), 89 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -349,7 +349,7 @@ int snd_bcm2835_new_pcm(struct bcm2835_c + &snd_bcm2835_playback_ops); + + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, +- chip->card->dev->parent, 128 * 1024, 128 * 1024); ++ chip->card->dev, 128 * 1024, 128 * 1024); + + if (spdif) + chip->pcm_spdif = pcm; +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +@@ -22,38 +22,6 @@ module_param(enable_compat_alsa, bool, 0 + MODULE_PARM_DESC(enable_compat_alsa, + "Enables ALSA compatibility virtual audio device"); + +-static void snd_devm_unregister_child(struct device *dev, void *res) +-{ +- struct device *childdev = *(struct device **)res; +- struct bcm2835_chip *chip = dev_get_drvdata(childdev); +- struct snd_card *card = chip->card; +- +- snd_card_free(card); +- +- device_unregister(childdev); +-} +- +-static int snd_devm_add_child(struct device *dev, struct device *child) +-{ +- struct device **dr; +- int ret; +- +- dr = devres_alloc(snd_devm_unregister_child, sizeof(*dr), GFP_KERNEL); +- if (!dr) +- return -ENOMEM; +- +- ret = device_add(child); +- if (ret) { +- devres_free(dr); +- return ret; +- } +- +- *dr = child; +- devres_add(dev, dr); +- +- return 0; +-} +- + static void bcm2835_devm_free_vchi_ctx(struct device *dev, void *res) + { + struct bcm2835_vchi_ctx *vchi_ctx = res; +@@ -84,36 +52,6 @@ static int bcm2835_devm_add_vchi_ctx(str + return 0; + } + +-static void snd_bcm2835_release(struct device *dev) +-{ +-} +- +-static struct device * +-snd_create_device(struct device *parent, +- struct device_driver *driver, +- const char *name) +-{ +- struct device *device; +- int ret; +- +- device = devm_kzalloc(parent, sizeof(*device), GFP_KERNEL); +- if (!device) +- return ERR_PTR(-ENOMEM); +- +- device_initialize(device); +- device->parent = parent; +- device->driver = driver; +- device->release = snd_bcm2835_release; +- +- dev_set_name(device, "%s", name); +- +- ret = snd_devm_add_child(parent, device); +- if (ret) +- return ERR_PTR(ret); +- +- return device; +-} +- + typedef int (*bcm2835_audio_newpcm_func)(struct bcm2835_chip *chip, + const char *name, + enum snd_bcm2835_route route, +@@ -216,40 +154,36 @@ static struct bcm2835_audio_drivers chil + }, + }; + +-static int snd_add_child_device(struct device *device, ++static void bcm2835_card_free(void *data) ++{ ++ snd_card_free(data); ++} ++ ++static int snd_add_child_device(struct device *dev, + struct bcm2835_audio_driver *audio_driver, + u32 numchans) + { + struct snd_card *card; +- struct device *child; + struct bcm2835_chip *chip; + int err; + +- child = snd_create_device(device, &audio_driver->driver, +- audio_driver->driver.name); +- if (IS_ERR(child)) { +- dev_err(device, +- "Unable to create child device %p, error %ld", +- audio_driver->driver.name, +- PTR_ERR(child)); +- return PTR_ERR(child); +- } +- +- err = snd_card_new(child, -1, NULL, THIS_MODULE, sizeof(*chip), &card); ++ err = snd_card_new(dev, -1, NULL, THIS_MODULE, sizeof(*chip), &card); + if (err < 0) { +- dev_err(child, "Failed to create card"); ++ dev_err(dev, "Failed to create card"); + return err; + } + + chip = card->private_data; + chip->card = card; +- chip->dev = child; ++ chip->dev = dev; + mutex_init(&chip->audio_mutex); + +- chip->vchi_ctx = devres_find(device, ++ chip->vchi_ctx = devres_find(dev, + bcm2835_devm_free_vchi_ctx, NULL, NULL); +- if (!chip->vchi_ctx) +- return -ENODEV; ++ if (!chip->vchi_ctx) { ++ err = -ENODEV; ++ goto error; ++ } + + strcpy(card->driver, audio_driver->driver.name); + strcpy(card->shortname, audio_driver->shortname); +@@ -259,26 +193,36 @@ static int snd_add_child_device(struct d + audio_driver->route, + numchans); + if (err) { +- dev_err(child, "Failed to create pcm, error %d\n", err); +- return err; ++ dev_err(dev, "Failed to create pcm, error %d\n", err); ++ goto error; + } + + err = audio_driver->newctl(chip); + if (err) { +- dev_err(child, "Failed to create controls, error %d\n", err); +- return err; ++ dev_err(dev, "Failed to create controls, error %d\n", err); ++ goto error; + } + + err = snd_card_register(card); + if (err) { +- dev_err(child, "Failed to register card, error %d\n", err); +- return err; ++ dev_err(dev, "Failed to register card, error %d\n", err); ++ goto error; + } + +- dev_set_drvdata(child, chip); +- dev_info(child, "card created with %d channels\n", numchans); ++ dev_set_drvdata(dev, chip); + ++ err = devm_add_action(dev, bcm2835_card_free, card); ++ if (err < 0) { ++ dev_err(dev, "Failed to add devm action, err %d\n", err); ++ goto error; ++ } ++ ++ dev_info(dev, "card created with %d channels\n", numchans); + return 0; ++ ++ error: ++ snd_card_free(card); ++ return err; + } + + static int snd_add_child_devices(struct device *device, u32 numchans) diff --git a/target/linux/brcm2708/patches-4.19/950-0466-staging-bcm2835-audio-Simplify-PCM-creation-helpers.patch b/target/linux/brcm2708/patches-4.19/950-0466-staging-bcm2835-audio-Simplify-PCM-creation-helpers.patch deleted file mode 100644 index 5d26935396..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0466-staging-bcm2835-audio-Simplify-PCM-creation-helpers.patch +++ /dev/null @@ -1,196 +0,0 @@ -From 1d7ccadf57b043d8721a5110ac9203e9883fceb2 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:56 +0200 -Subject: [PATCH 466/703] staging: bcm2835-audio: Simplify PCM creation helpers - -commit 74470ffeb9aed5548654cfca881bf1d7469fe9c4 upstream. - -All three functions to create PCM objects are fairly resemble, and can -be unified to a single common helper. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 87 ++++--------------- - .../vc04_services/bcm2835-audio/bcm2835.c | 17 +++- - .../vc04_services/bcm2835-audio/bcm2835.h | 9 +- - 3 files changed, 32 insertions(+), 81 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -324,91 +324,36 @@ static const struct snd_pcm_ops snd_bcm2 - }; - - /* create a pcm device */ --int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, u32 numchannels) -+int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, const char *name, -+ int idx, enum snd_bcm2835_route route, -+ u32 numchannels, bool spdif) - { - struct snd_pcm *pcm; - int err; - -- err = snd_pcm_new(chip->card, "bcm2835 ALSA", 0, numchannels, 0, &pcm); -- if (err < 0) -- return err; -- pcm->private_data = chip; -- pcm->nonatomic = true; -- strcpy(pcm->name, "bcm2835 ALSA"); -- chip->pcm = pcm; -- chip->dest = AUDIO_DEST_AUTO; -- chip->volume = 0; -- chip->mute = CTRL_VOL_UNMUTE; /*disable mute on startup */ -- /* set operators */ -- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, -- &snd_bcm2835_playback_ops); -- -- /* pre-allocation of buffers */ -- /* NOTE: this may fail */ -- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, -- chip->card->dev->parent, -- snd_bcm2835_playback_hw.buffer_bytes_max, -- snd_bcm2835_playback_hw.buffer_bytes_max); -- -- return 0; --} -- --int snd_bcm2835_new_spdif_pcm(struct bcm2835_chip *chip) --{ -- struct snd_pcm *pcm; -- int err; -- -- err = snd_pcm_new(chip->card, "bcm2835 ALSA", 1, 1, 0, &pcm); -- if (err < 0) -- return err; -- -- pcm->private_data = chip; -- pcm->nonatomic = true; -- strcpy(pcm->name, "bcm2835 IEC958/HDMI"); -- chip->pcm_spdif = pcm; -- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, -- &snd_bcm2835_playback_spdif_ops); -- -- /* pre-allocation of buffers */ -- /* NOTE: this may fail */ -- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, -- chip->card->dev->parent, -- snd_bcm2835_playback_spdif_hw.buffer_bytes_max, snd_bcm2835_playback_spdif_hw.buffer_bytes_max); -- -- return 0; --} -- --int snd_bcm2835_new_simple_pcm(struct bcm2835_chip *chip, -- const char *name, -- enum snd_bcm2835_route route, -- u32 numchannels) --{ -- struct snd_pcm *pcm; -- int err; -- -- err = snd_pcm_new(chip->card, name, 0, numchannels, -- 0, &pcm); -+ err = snd_pcm_new(chip->card, name, idx, numchannels, 0, &pcm); - if (err) - return err; - - pcm->private_data = chip; - pcm->nonatomic = true; - strcpy(pcm->name, name); -- chip->pcm = pcm; -- chip->dest = route; -- chip->volume = 0; -- chip->mute = CTRL_VOL_UNMUTE; -+ if (!spdif) { -+ chip->dest = route; -+ chip->volume = 0; -+ chip->mute = CTRL_VOL_UNMUTE; -+ } - - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, -+ spdif ? &snd_bcm2835_playback_spdif_ops : - &snd_bcm2835_playback_ops); - -- snd_pcm_lib_preallocate_pages_for_all( -- pcm, -- SNDRV_DMA_TYPE_DEV, -- chip->card->dev->parent, -- snd_bcm2835_playback_hw.buffer_bytes_max, -- snd_bcm2835_playback_hw.buffer_bytes_max); -+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, -+ chip->card->dev->parent, 128 * 1024, 128 * 1024); - -+ if (spdif) -+ chip->pcm_spdif = pcm; -+ else -+ chip->pcm = pcm; - return 0; - } -- ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -138,17 +138,26 @@ static int bcm2835_audio_alsa_newpcm(str - { - int err; - -- err = snd_bcm2835_new_pcm(chip, numchannels - 1); -+ err = snd_bcm2835_new_pcm(chip, "bcm2835 ALSA", 0, AUDIO_DEST_AUTO, -+ numchannels - 1, false); - if (err) - return err; - -- err = snd_bcm2835_new_spdif_pcm(chip); -+ err = snd_bcm2835_new_pcm(chip, "bcm2835 IEC958/HDMI", 1, 0, 1, true); - if (err) - return err; - - return 0; - } - -+static int bcm2835_audio_simple_newpcm(struct bcm2835_chip *chip, -+ const char *name, -+ enum snd_bcm2835_route route, -+ u32 numchannels) -+{ -+ return snd_bcm2835_new_pcm(chip, name, 0, route, numchannels, false); -+} -+ - static struct bcm2835_audio_driver bcm2835_audio_alsa = { - .driver = { - .name = "bcm2835_alsa", -@@ -169,7 +178,7 @@ static struct bcm2835_audio_driver bcm28 - .shortname = "bcm2835 HDMI", - .longname = "bcm2835 HDMI", - .minchannels = 1, -- .newpcm = snd_bcm2835_new_simple_pcm, -+ .newpcm = bcm2835_audio_simple_newpcm, - .newctl = snd_bcm2835_new_hdmi_ctl, - .route = AUDIO_DEST_HDMI - }; -@@ -182,7 +191,7 @@ static struct bcm2835_audio_driver bcm28 - .shortname = "bcm2835 Headphones", - .longname = "bcm2835 Headphones", - .minchannels = 1, -- .newpcm = snd_bcm2835_new_simple_pcm, -+ .newpcm = bcm2835_audio_simple_newpcm, - .newctl = snd_bcm2835_new_headphones_ctl, - .route = AUDIO_DEST_HEADPHONES - }; ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -@@ -84,12 +84,9 @@ struct bcm2835_alsa_stream { - }; - - int snd_bcm2835_new_ctl(struct bcm2835_chip *chip); --int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, u32 numchannels); --int snd_bcm2835_new_spdif_pcm(struct bcm2835_chip *chip); --int snd_bcm2835_new_simple_pcm(struct bcm2835_chip *chip, -- const char *name, -- enum snd_bcm2835_route route, -- u32 numchannels); -+int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, const char *name, -+ int idx, enum snd_bcm2835_route route, -+ u32 numchannels, bool spdif); - - int snd_bcm2835_new_hdmi_ctl(struct bcm2835_chip *chip); - int snd_bcm2835_new_headphones_ctl(struct bcm2835_chip *chip); diff --git a/target/linux/brcm2708/patches-4.19/950-0466-staging-bcm2835-audio-unify-FOURCC-command-definitio.patch b/target/linux/brcm2708/patches-4.19/950-0466-staging-bcm2835-audio-unify-FOURCC-command-definitio.patch new file mode 100644 index 0000000000..0acabf4013 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0466-staging-bcm2835-audio-unify-FOURCC-command-definitio.patch @@ -0,0 +1,71 @@ +From 324af1fceb517d7250b13a31e5185c06f4366d5c Mon Sep 17 00:00:00 2001 +From: Nicolas Saenz Julienne +Date: Wed, 17 Oct 2018 21:01:50 +0200 +Subject: [PATCH 466/725] staging: bcm2835-audio: unify FOURCC command + definitions + +commit a90d8f49cc7fd7220aa24b85fc74ef3cfd62b96f upstream. + +The device communicates with the audio core using FOURCC codes. The +driver was generating them using different macros/expressions. We now +use the same macro to create them and centralize all the definitions. + +Signed-off-by: Nicolas Saenz Julienne +Reviewed-by: Takashi Iwai +Acked-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-vchiq.c | 13 ++++--------- + .../bcm2835-audio/vc_vchi_audioserv_defs.h | 4 +++- + 2 files changed, 7 insertions(+), 10 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +@@ -89,11 +89,6 @@ static int bcm2835_audio_send_simple(str + return bcm2835_audio_send_msg(instance, &m, wait); + } + +-static const u32 BCM2835_AUDIO_WRITE_COOKIE1 = ('B' << 24 | 'C' << 16 | +- 'M' << 8 | 'A'); +-static const u32 BCM2835_AUDIO_WRITE_COOKIE2 = ('D' << 24 | 'A' << 16 | +- 'T' << 8 | 'A'); +- + static void audio_vchi_callback(void *param, + const VCHI_CALLBACK_REASON_T reason, + void *msg_handle) +@@ -112,8 +107,8 @@ static void audio_vchi_callback(void *pa + instance->result = m.u.result.success; + complete(&instance->msg_avail_comp); + } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) { +- if (m.u.complete.cookie1 != BCM2835_AUDIO_WRITE_COOKIE1 || +- m.u.complete.cookie2 != BCM2835_AUDIO_WRITE_COOKIE2) ++ if (m.u.complete.cookie1 != VC_AUDIO_WRITE_COOKIE1 || ++ m.u.complete.cookie2 != VC_AUDIO_WRITE_COOKIE2) + dev_err(instance->dev, "invalid cookie\n"); + else + bcm2835_playback_fifo(instance->alsa_stream, +@@ -337,8 +332,8 @@ int bcm2835_audio_write(struct bcm2835_a + .type = VC_AUDIO_MSG_TYPE_WRITE, + .u.write.count = size, + .u.write.max_packet = instance->max_packet, +- .u.write.cookie1 = BCM2835_AUDIO_WRITE_COOKIE1, +- .u.write.cookie2 = BCM2835_AUDIO_WRITE_COOKIE2, ++ .u.write.cookie1 = VC_AUDIO_WRITE_COOKIE1, ++ .u.write.cookie2 = VC_AUDIO_WRITE_COOKIE2, + }; + unsigned int count; + int err, status; +--- a/drivers/staging/vc04_services/bcm2835-audio/vc_vchi_audioserv_defs.h ++++ b/drivers/staging/vc04_services/bcm2835-audio/vc_vchi_audioserv_defs.h +@@ -7,8 +7,10 @@ + #define VC_AUDIOSERV_MIN_VER 1 + #define VC_AUDIOSERV_VER 2 + +-/* FourCC code used for VCHI connection */ ++/* FourCC codes used for VCHI communication */ + #define VC_AUDIO_SERVER_NAME MAKE_FOURCC("AUDS") ++#define VC_AUDIO_WRITE_COOKIE1 MAKE_FOURCC("BCMA") ++#define VC_AUDIO_WRITE_COOKIE2 MAKE_FOURCC("DATA") + + /* + * List of screens that are currently supported diff --git a/target/linux/brcm2708/patches-4.19/950-0467-staging-bcm2835-audio-Simplify-kctl-creation-helpers.patch b/target/linux/brcm2708/patches-4.19/950-0467-staging-bcm2835-audio-Simplify-kctl-creation-helpers.patch deleted file mode 100644 index 8454f7c9c8..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0467-staging-bcm2835-audio-Simplify-kctl-creation-helpers.patch +++ /dev/null @@ -1,161 +0,0 @@ -From af83d44b51e549b26c1f0db6cfc3207cf9e44d50 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:57 +0200 -Subject: [PATCH 467/703] staging: bcm2835-audio: Simplify kctl creation - helpers - -commit dc5c0eb1e8601206dffbfc302cbd190f89dcd040 upstream. - -Just a minor code refactoring and adding some const prefix. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-ctl.c | 69 +++++++------------ - 1 file changed, 25 insertions(+), 44 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c -@@ -97,40 +97,34 @@ static int snd_bcm2835_ctl_put(struct sn - - static DECLARE_TLV_DB_SCALE(snd_bcm2835_db_scale, CTRL_VOL_MIN, 1, 1); - --static struct snd_kcontrol_new snd_bcm2835_ctl[] = { -+static const struct snd_kcontrol_new snd_bcm2835_ctl[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Volume", -- .index = 0, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, - .private_value = PCM_PLAYBACK_VOLUME, - .info = snd_bcm2835_ctl_info, - .get = snd_bcm2835_ctl_get, - .put = snd_bcm2835_ctl_put, -- .count = 1, - .tlv = {.p = snd_bcm2835_db_scale} - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Switch", -- .index = 0, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .private_value = PCM_PLAYBACK_MUTE, - .info = snd_bcm2835_ctl_info, - .get = snd_bcm2835_ctl_get, - .put = snd_bcm2835_ctl_put, -- .count = 1, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Route", -- .index = 0, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .private_value = PCM_PLAYBACK_DEVICE, - .info = snd_bcm2835_ctl_info, - .get = snd_bcm2835_ctl_get, - .put = snd_bcm2835_ctl_put, -- .count = 1, - }, - }; - -@@ -196,7 +190,7 @@ static int snd_bcm2835_spdif_mask_get(st - return 0; - } - --static struct snd_kcontrol_new snd_bcm2835_spdif[] = { -+static const struct snd_kcontrol_new snd_bcm2835_spdif[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), -@@ -213,28 +207,32 @@ static struct snd_kcontrol_new snd_bcm28 - }, - }; - --int snd_bcm2835_new_ctl(struct bcm2835_chip *chip) -+static int create_ctls(struct bcm2835_chip *chip, size_t size, -+ const struct snd_kcontrol_new *kctls) - { -- int err; -- unsigned int idx; -+ int i, err; - -- strcpy(chip->card->mixername, "Broadcom Mixer"); -- for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_ctl); idx++) { -- err = snd_ctl_add(chip->card, -- snd_ctl_new1(&snd_bcm2835_ctl[idx], chip)); -- if (err < 0) -- return err; -- } -- for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_spdif); idx++) { -- err = snd_ctl_add(chip->card, -- snd_ctl_new1(&snd_bcm2835_spdif[idx], chip)); -+ for (i = 0; i < size; i++) { -+ err = snd_ctl_add(chip->card, snd_ctl_new1(&kctls[i], chip)); - if (err < 0) - return err; - } - return 0; - } - --static struct snd_kcontrol_new snd_bcm2835_headphones_ctl[] = { -+int snd_bcm2835_new_ctl(struct bcm2835_chip *chip) -+{ -+ int err; -+ -+ strcpy(chip->card->mixername, "Broadcom Mixer"); -+ err = create_ctls(chip, ARRAY_SIZE(snd_bcm2835_ctl), snd_bcm2835_ctl); -+ if (err < 0) -+ return err; -+ return create_ctls(chip, ARRAY_SIZE(snd_bcm2835_spdif), -+ snd_bcm2835_spdif); -+} -+ -+static const struct snd_kcontrol_new snd_bcm2835_headphones_ctl[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Headphone Playback Volume", -@@ -263,21 +261,12 @@ static struct snd_kcontrol_new snd_bcm28 - - int snd_bcm2835_new_headphones_ctl(struct bcm2835_chip *chip) - { -- int err; -- unsigned int idx; -- - strcpy(chip->card->mixername, "Broadcom Mixer"); -- for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_headphones_ctl); idx++) { -- err = snd_ctl_add(chip->card, -- snd_ctl_new1(&snd_bcm2835_headphones_ctl[idx], -- chip)); -- if (err) -- return err; -- } -- return 0; -+ return create_ctls(chip, ARRAY_SIZE(snd_bcm2835_headphones_ctl), -+ snd_bcm2835_headphones_ctl); - } - --static struct snd_kcontrol_new snd_bcm2835_hdmi[] = { -+static const struct snd_kcontrol_new snd_bcm2835_hdmi[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "HDMI Playback Volume", -@@ -306,16 +295,8 @@ static struct snd_kcontrol_new snd_bcm28 - - int snd_bcm2835_new_hdmi_ctl(struct bcm2835_chip *chip) - { -- int err; -- unsigned int idx; -- - strcpy(chip->card->mixername, "Broadcom Mixer"); -- for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_hdmi); idx++) { -- err = snd_ctl_add(chip->card, -- snd_ctl_new1(&snd_bcm2835_hdmi[idx], chip)); -- if (err) -- return err; -- } -- return 0; -+ return create_ctls(chip, ARRAY_SIZE(snd_bcm2835_hdmi), -+ snd_bcm2835_hdmi); - } - diff --git a/target/linux/brcm2708/patches-4.19/950-0467-staging-bcm2835-audio-don-t-initialize-memory-twice.patch b/target/linux/brcm2708/patches-4.19/950-0467-staging-bcm2835-audio-don-t-initialize-memory-twice.patch new file mode 100644 index 0000000000..a115399735 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0467-staging-bcm2835-audio-don-t-initialize-memory-twice.patch @@ -0,0 +1,30 @@ +From e2389771445d4c01aa8c2cfdc5f854451ba1d29d Mon Sep 17 00:00:00 2001 +From: Nicolas Saenz Julienne +Date: Wed, 17 Oct 2018 21:01:51 +0200 +Subject: [PATCH 467/725] staging: bcm2835-audio: don't initialize memory twice + +commit 2e5f59fb77397cab3bc3d156e8be4164a67d32ef upstream. + +The memory is being allocated with devres_alloc(), wich ultimately uses +__GFP_ZERO to call kmalloc. We don't need to zero the memory area again +in bcm2835-audio. + +Signed-off-by: Nicolas Saenz Julienne +Reviewed-by: Takashi Iwai +Acked-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/vc04_services/bcm2835-audio/bcm2835.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +@@ -39,8 +39,6 @@ static int bcm2835_devm_add_vchi_ctx(str + if (!vchi_ctx) + return -ENOMEM; + +- memset(vchi_ctx, 0, sizeof(*vchi_ctx)); +- + ret = bcm2835_new_vchi_ctx(dev, vchi_ctx); + if (ret) { + devres_free(vchi_ctx); diff --git a/target/linux/brcm2708/patches-4.19/950-0468-staging-bcm2835-audio-Simplify-card-object-managemen.patch b/target/linux/brcm2708/patches-4.19/950-0468-staging-bcm2835-audio-Simplify-card-object-managemen.patch deleted file mode 100644 index 9d2b10a7a3..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0468-staging-bcm2835-audio-Simplify-card-object-managemen.patch +++ /dev/null @@ -1,212 +0,0 @@ -From 18c2353cd57e25ececa0551b2ec22fd1f76f6484 Mon Sep 17 00:00:00 2001 -From: Takashi Iwai -Date: Tue, 4 Sep 2018 17:58:58 +0200 -Subject: [PATCH 468/703] staging: bcm2835-audio: Simplify card object - management - -commit 872ae2d63d516a2a3b9c833d8685afcfa7814542 upstream. - -Instead of creating a dummy child device to manage the card object, -just use devm stuff directly for releasing with snd_card_free(). -This results in a lot of code reduction. - -Since the dummy child devices are gone, the device object to be passed -to the memory allocator needs to be adjusted as well. - -Signed-off-by: Takashi Iwai -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 2 +- - .../vc04_services/bcm2835-audio/bcm2835.c | 120 +++++------------- - 2 files changed, 33 insertions(+), 89 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -349,7 +349,7 @@ int snd_bcm2835_new_pcm(struct bcm2835_c - &snd_bcm2835_playback_ops); - - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, -- chip->card->dev->parent, 128 * 1024, 128 * 1024); -+ chip->card->dev, 128 * 1024, 128 * 1024); - - if (spdif) - chip->pcm_spdif = pcm; ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -22,38 +22,6 @@ module_param(enable_compat_alsa, bool, 0 - MODULE_PARM_DESC(enable_compat_alsa, - "Enables ALSA compatibility virtual audio device"); - --static void snd_devm_unregister_child(struct device *dev, void *res) --{ -- struct device *childdev = *(struct device **)res; -- struct bcm2835_chip *chip = dev_get_drvdata(childdev); -- struct snd_card *card = chip->card; -- -- snd_card_free(card); -- -- device_unregister(childdev); --} -- --static int snd_devm_add_child(struct device *dev, struct device *child) --{ -- struct device **dr; -- int ret; -- -- dr = devres_alloc(snd_devm_unregister_child, sizeof(*dr), GFP_KERNEL); -- if (!dr) -- return -ENOMEM; -- -- ret = device_add(child); -- if (ret) { -- devres_free(dr); -- return ret; -- } -- -- *dr = child; -- devres_add(dev, dr); -- -- return 0; --} -- - static void bcm2835_devm_free_vchi_ctx(struct device *dev, void *res) - { - struct bcm2835_vchi_ctx *vchi_ctx = res; -@@ -84,36 +52,6 @@ static int bcm2835_devm_add_vchi_ctx(str - return 0; - } - --static void snd_bcm2835_release(struct device *dev) --{ --} -- --static struct device * --snd_create_device(struct device *parent, -- struct device_driver *driver, -- const char *name) --{ -- struct device *device; -- int ret; -- -- device = devm_kzalloc(parent, sizeof(*device), GFP_KERNEL); -- if (!device) -- return ERR_PTR(-ENOMEM); -- -- device_initialize(device); -- device->parent = parent; -- device->driver = driver; -- device->release = snd_bcm2835_release; -- -- dev_set_name(device, "%s", name); -- -- ret = snd_devm_add_child(parent, device); -- if (ret) -- return ERR_PTR(ret); -- -- return device; --} -- - typedef int (*bcm2835_audio_newpcm_func)(struct bcm2835_chip *chip, - const char *name, - enum snd_bcm2835_route route, -@@ -216,40 +154,36 @@ static struct bcm2835_audio_drivers chil - }, - }; - --static int snd_add_child_device(struct device *device, -+static void bcm2835_card_free(void *data) -+{ -+ snd_card_free(data); -+} -+ -+static int snd_add_child_device(struct device *dev, - struct bcm2835_audio_driver *audio_driver, - u32 numchans) - { - struct snd_card *card; -- struct device *child; - struct bcm2835_chip *chip; - int err; - -- child = snd_create_device(device, &audio_driver->driver, -- audio_driver->driver.name); -- if (IS_ERR(child)) { -- dev_err(device, -- "Unable to create child device %p, error %ld", -- audio_driver->driver.name, -- PTR_ERR(child)); -- return PTR_ERR(child); -- } -- -- err = snd_card_new(child, -1, NULL, THIS_MODULE, sizeof(*chip), &card); -+ err = snd_card_new(dev, -1, NULL, THIS_MODULE, sizeof(*chip), &card); - if (err < 0) { -- dev_err(child, "Failed to create card"); -+ dev_err(dev, "Failed to create card"); - return err; - } - - chip = card->private_data; - chip->card = card; -- chip->dev = child; -+ chip->dev = dev; - mutex_init(&chip->audio_mutex); - -- chip->vchi_ctx = devres_find(device, -+ chip->vchi_ctx = devres_find(dev, - bcm2835_devm_free_vchi_ctx, NULL, NULL); -- if (!chip->vchi_ctx) -- return -ENODEV; -+ if (!chip->vchi_ctx) { -+ err = -ENODEV; -+ goto error; -+ } - - strcpy(card->driver, audio_driver->driver.name); - strcpy(card->shortname, audio_driver->shortname); -@@ -259,26 +193,36 @@ static int snd_add_child_device(struct d - audio_driver->route, - numchans); - if (err) { -- dev_err(child, "Failed to create pcm, error %d\n", err); -- return err; -+ dev_err(dev, "Failed to create pcm, error %d\n", err); -+ goto error; - } - - err = audio_driver->newctl(chip); - if (err) { -- dev_err(child, "Failed to create controls, error %d\n", err); -- return err; -+ dev_err(dev, "Failed to create controls, error %d\n", err); -+ goto error; - } - - err = snd_card_register(card); - if (err) { -- dev_err(child, "Failed to register card, error %d\n", err); -- return err; -+ dev_err(dev, "Failed to register card, error %d\n", err); -+ goto error; - } - -- dev_set_drvdata(child, chip); -- dev_info(child, "card created with %d channels\n", numchans); -+ dev_set_drvdata(dev, chip); - -+ err = devm_add_action(dev, bcm2835_card_free, card); -+ if (err < 0) { -+ dev_err(dev, "Failed to add devm action, err %d\n", err); -+ goto error; -+ } -+ -+ dev_info(dev, "card created with %d channels\n", numchans); - return 0; -+ -+ error: -+ snd_card_free(card); -+ return err; - } - - static int snd_add_child_devices(struct device *device, u32 numchans) diff --git a/target/linux/brcm2708/patches-4.19/950-0468-staging-bcm2835-audio-reorder-variable-declarations-.patch b/target/linux/brcm2708/patches-4.19/950-0468-staging-bcm2835-audio-reorder-variable-declarations-.patch new file mode 100644 index 0000000000..ab2ac8b1b6 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0468-staging-bcm2835-audio-reorder-variable-declarations-.patch @@ -0,0 +1,118 @@ +From 28436930910a42f2127e0b91dcdf20ec99d1da41 Mon Sep 17 00:00:00 2001 +From: Nicolas Saenz Julienne +Date: Wed, 17 Oct 2018 21:01:52 +0200 +Subject: [PATCH 468/725] staging: bcm2835-audio: reorder variable declarations + & remove trivial comments + +commit d048385a070552ae819f99f05bd03ec41072783d upstream. + +When it comes to declaring variables it's preferred, when possible, to +use an inverted tree organization scheme. + +Also, removes some comments that were useless. + +Signed-off-by: Nicolas Saenz Julienne +Reviewed-by: Takashi Iwai +Acked-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 10 ++-------- + .../vc04_services/bcm2835-audio/bcm2835-vchiq.c | 4 ++-- + .../staging/vc04_services/bcm2835-audio/bcm2835.c | 14 +++++++------- + 3 files changed, 11 insertions(+), 17 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -164,14 +164,11 @@ static int snd_bcm2835_playback_spdif_op + return snd_bcm2835_playback_open_generic(substream, 1); + } + +-/* close callback */ + static int snd_bcm2835_playback_close(struct snd_pcm_substream *substream) + { +- /* the hardware-specific codes will be here */ +- +- struct bcm2835_chip *chip; +- struct snd_pcm_runtime *runtime; + struct bcm2835_alsa_stream *alsa_stream; ++ struct snd_pcm_runtime *runtime; ++ struct bcm2835_chip *chip; + + chip = snd_pcm_substream_chip(substream); + mutex_lock(&chip->audio_mutex); +@@ -195,20 +192,17 @@ static int snd_bcm2835_playback_close(st + return 0; + } + +-/* hw_params callback */ + static int snd_bcm2835_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) + { + return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); + } + +-/* hw_free callback */ + static int snd_bcm2835_pcm_hw_free(struct snd_pcm_substream *substream) + { + return snd_pcm_lib_free_pages(substream); + } + +-/* prepare callback */ + static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) + { + struct bcm2835_chip *chip = snd_pcm_substream_chip(substream); +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +@@ -94,9 +94,9 @@ static void audio_vchi_callback(void *pa + void *msg_handle) + { + struct bcm2835_audio_instance *instance = param; +- int status; +- int msg_len; + struct vc_audio_msg m; ++ int msg_len; ++ int status; + + if (reason != VCHI_CALLBACK_MSG_AVAILABLE) + return; +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +@@ -161,8 +161,8 @@ static int snd_add_child_device(struct d + struct bcm2835_audio_driver *audio_driver, + u32 numchans) + { +- struct snd_card *card; + struct bcm2835_chip *chip; ++ struct snd_card *card; + int err; + + err = snd_card_new(dev, -1, NULL, THIS_MODULE, sizeof(*chip), &card); +@@ -225,12 +225,12 @@ static int snd_add_child_device(struct d + + static int snd_add_child_devices(struct device *device, u32 numchans) + { +- int i; +- int count_devices = 0; +- int minchannels = 0; +- int extrachannels = 0; + int extrachannels_per_driver = 0; + int extrachannels_remainder = 0; ++ int count_devices = 0; ++ int extrachannels = 0; ++ int minchannels = 0; ++ int i; + + for (i = 0; i < ARRAY_SIZE(children_devices); i++) + if (*children_devices[i].is_enabled) +@@ -258,9 +258,9 @@ static int snd_add_child_devices(struct + extrachannels_remainder); + + for (i = 0; i < ARRAY_SIZE(children_devices); i++) { +- int err; +- int numchannels_this_device; + struct bcm2835_audio_driver *audio_driver; ++ int numchannels_this_device; ++ int err; + + if (!*children_devices[i].is_enabled) + continue; diff --git a/target/linux/brcm2708/patches-4.19/950-0469-staging-bcm2835-audio-unify-FOURCC-command-definitio.patch b/target/linux/brcm2708/patches-4.19/950-0469-staging-bcm2835-audio-unify-FOURCC-command-definitio.patch deleted file mode 100644 index 04e2dfbcbf..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0469-staging-bcm2835-audio-unify-FOURCC-command-definitio.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 6bfd152edc4d9a19836dc2a12c9545a5ccc1a87f Mon Sep 17 00:00:00 2001 -From: Nicolas Saenz Julienne -Date: Wed, 17 Oct 2018 21:01:50 +0200 -Subject: [PATCH 469/703] staging: bcm2835-audio: unify FOURCC command - definitions - -commit a90d8f49cc7fd7220aa24b85fc74ef3cfd62b96f upstream. - -The device communicates with the audio core using FOURCC codes. The -driver was generating them using different macros/expressions. We now -use the same macro to create them and centralize all the definitions. - -Signed-off-by: Nicolas Saenz Julienne -Reviewed-by: Takashi Iwai -Acked-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-vchiq.c | 13 ++++--------- - .../bcm2835-audio/vc_vchi_audioserv_defs.h | 4 +++- - 2 files changed, 7 insertions(+), 10 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -@@ -89,11 +89,6 @@ static int bcm2835_audio_send_simple(str - return bcm2835_audio_send_msg(instance, &m, wait); - } - --static const u32 BCM2835_AUDIO_WRITE_COOKIE1 = ('B' << 24 | 'C' << 16 | -- 'M' << 8 | 'A'); --static const u32 BCM2835_AUDIO_WRITE_COOKIE2 = ('D' << 24 | 'A' << 16 | -- 'T' << 8 | 'A'); -- - static void audio_vchi_callback(void *param, - const VCHI_CALLBACK_REASON_T reason, - void *msg_handle) -@@ -112,8 +107,8 @@ static void audio_vchi_callback(void *pa - instance->result = m.u.result.success; - complete(&instance->msg_avail_comp); - } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) { -- if (m.u.complete.cookie1 != BCM2835_AUDIO_WRITE_COOKIE1 || -- m.u.complete.cookie2 != BCM2835_AUDIO_WRITE_COOKIE2) -+ if (m.u.complete.cookie1 != VC_AUDIO_WRITE_COOKIE1 || -+ m.u.complete.cookie2 != VC_AUDIO_WRITE_COOKIE2) - dev_err(instance->dev, "invalid cookie\n"); - else - bcm2835_playback_fifo(instance->alsa_stream, -@@ -337,8 +332,8 @@ int bcm2835_audio_write(struct bcm2835_a - .type = VC_AUDIO_MSG_TYPE_WRITE, - .u.write.count = size, - .u.write.max_packet = instance->max_packet, -- .u.write.cookie1 = BCM2835_AUDIO_WRITE_COOKIE1, -- .u.write.cookie2 = BCM2835_AUDIO_WRITE_COOKIE2, -+ .u.write.cookie1 = VC_AUDIO_WRITE_COOKIE1, -+ .u.write.cookie2 = VC_AUDIO_WRITE_COOKIE2, - }; - unsigned int count; - int err, status; ---- a/drivers/staging/vc04_services/bcm2835-audio/vc_vchi_audioserv_defs.h -+++ b/drivers/staging/vc04_services/bcm2835-audio/vc_vchi_audioserv_defs.h -@@ -7,8 +7,10 @@ - #define VC_AUDIOSERV_MIN_VER 1 - #define VC_AUDIOSERV_VER 2 - --/* FourCC code used for VCHI connection */ -+/* FourCC codes used for VCHI communication */ - #define VC_AUDIO_SERVER_NAME MAKE_FOURCC("AUDS") -+#define VC_AUDIO_WRITE_COOKIE1 MAKE_FOURCC("BCMA") -+#define VC_AUDIO_WRITE_COOKIE2 MAKE_FOURCC("DATA") - - /* - * List of screens that are currently supported diff --git a/target/linux/brcm2708/patches-4.19/950-0469-staging-bcm2835-audio-use-anonymous-union-in-struct-.patch b/target/linux/brcm2708/patches-4.19/950-0469-staging-bcm2835-audio-use-anonymous-union-in-struct-.patch new file mode 100644 index 0000000000..577b858c72 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0469-staging-bcm2835-audio-use-anonymous-union-in-struct-.patch @@ -0,0 +1,105 @@ +From 5f7ebc0e341a4bf93db4c8e031b0e260be567e00 Mon Sep 17 00:00:00 2001 +From: Nicolas Saenz Julienne +Date: Wed, 17 Oct 2018 21:01:53 +0200 +Subject: [PATCH 469/725] staging: bcm2835-audio: use anonymous union in struct + vc_audio_msg + +commit 9c2eaf7da855d314a369d48b9cbf8ac80717a1d0 upstream. + +In this case explicitly naming the union doesn't help overall code +comprehension and clutters it. + +Signed-off-by: Nicolas Saenz Julienne +Reviewed-by: Takashi Iwai +Acked-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../bcm2835-audio/bcm2835-vchiq.c | 30 +++++++++---------- + .../bcm2835-audio/vc_vchi_audioserv_defs.h | 2 +- + 2 files changed, 16 insertions(+), 16 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +@@ -104,15 +104,15 @@ static void audio_vchi_callback(void *pa + status = vchi_msg_dequeue(instance->vchi_handle, + &m, sizeof(m), &msg_len, VCHI_FLAGS_NONE); + if (m.type == VC_AUDIO_MSG_TYPE_RESULT) { +- instance->result = m.u.result.success; ++ instance->result = m.result.success; + complete(&instance->msg_avail_comp); + } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) { +- if (m.u.complete.cookie1 != VC_AUDIO_WRITE_COOKIE1 || +- m.u.complete.cookie2 != VC_AUDIO_WRITE_COOKIE2) ++ if (m.complete.cookie1 != VC_AUDIO_WRITE_COOKIE1 || ++ m.complete.cookie2 != VC_AUDIO_WRITE_COOKIE2) + dev_err(instance->dev, "invalid cookie\n"); + else + bcm2835_playback_fifo(instance->alsa_stream, +- m.u.complete.count); ++ m.complete.count); + } else { + dev_err(instance->dev, "unexpected callback type=%d\n", m.type); + } +@@ -257,11 +257,11 @@ int bcm2835_audio_set_ctls(struct bcm283 + struct vc_audio_msg m = {}; + + m.type = VC_AUDIO_MSG_TYPE_CONTROL; +- m.u.control.dest = chip->dest; ++ m.control.dest = chip->dest; + if (!chip->mute) +- m.u.control.volume = CHIP_MIN_VOLUME; ++ m.control.volume = CHIP_MIN_VOLUME; + else +- m.u.control.volume = alsa2chip(chip->volume); ++ m.control.volume = alsa2chip(chip->volume); + + return bcm2835_audio_send_msg(alsa_stream->instance, &m, true); + } +@@ -272,9 +272,9 @@ int bcm2835_audio_set_params(struct bcm2 + { + struct vc_audio_msg m = { + .type = VC_AUDIO_MSG_TYPE_CONFIG, +- .u.config.channels = channels, +- .u.config.samplerate = samplerate, +- .u.config.bps = bps, ++ .config.channels = channels, ++ .config.samplerate = samplerate, ++ .config.bps = bps, + }; + int err; + +@@ -302,7 +302,7 @@ int bcm2835_audio_drain(struct bcm2835_a + { + struct vc_audio_msg m = { + .type = VC_AUDIO_MSG_TYPE_STOP, +- .u.stop.draining = 1, ++ .stop.draining = 1, + }; + + return bcm2835_audio_send_msg(alsa_stream->instance, &m, false); +@@ -330,10 +330,10 @@ int bcm2835_audio_write(struct bcm2835_a + struct bcm2835_audio_instance *instance = alsa_stream->instance; + struct vc_audio_msg m = { + .type = VC_AUDIO_MSG_TYPE_WRITE, +- .u.write.count = size, +- .u.write.max_packet = instance->max_packet, +- .u.write.cookie1 = VC_AUDIO_WRITE_COOKIE1, +- .u.write.cookie2 = VC_AUDIO_WRITE_COOKIE2, ++ .write.count = size, ++ .write.max_packet = instance->max_packet, ++ .write.cookie1 = VC_AUDIO_WRITE_COOKIE1, ++ .write.cookie2 = VC_AUDIO_WRITE_COOKIE2, + }; + unsigned int count; + int err, status; +--- a/drivers/staging/vc04_services/bcm2835-audio/vc_vchi_audioserv_defs.h ++++ b/drivers/staging/vc04_services/bcm2835-audio/vc_vchi_audioserv_defs.h +@@ -93,7 +93,7 @@ struct vc_audio_msg { + struct vc_audio_write write; + struct vc_audio_result result; + struct vc_audio_complete complete; +- } u; ++ }; + }; + + #endif /* _VC_AUDIO_DEFS_H_ */ diff --git a/target/linux/brcm2708/patches-4.19/950-0470-staging-bcm2835-audio-don-t-initialize-memory-twice.patch b/target/linux/brcm2708/patches-4.19/950-0470-staging-bcm2835-audio-don-t-initialize-memory-twice.patch deleted file mode 100644 index 9845a03f08..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0470-staging-bcm2835-audio-don-t-initialize-memory-twice.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 2477bc42397c7be4c74429b6fb8c1325765b9a46 Mon Sep 17 00:00:00 2001 -From: Nicolas Saenz Julienne -Date: Wed, 17 Oct 2018 21:01:51 +0200 -Subject: [PATCH 470/703] staging: bcm2835-audio: don't initialize memory twice - -commit 2e5f59fb77397cab3bc3d156e8be4164a67d32ef upstream. - -The memory is being allocated with devres_alloc(), wich ultimately uses -__GFP_ZERO to call kmalloc. We don't need to zero the memory area again -in bcm2835-audio. - -Signed-off-by: Nicolas Saenz Julienne -Reviewed-by: Takashi Iwai -Acked-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/vc04_services/bcm2835-audio/bcm2835.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -39,8 +39,6 @@ static int bcm2835_devm_add_vchi_ctx(str - if (!vchi_ctx) - return -ENOMEM; - -- memset(vchi_ctx, 0, sizeof(*vchi_ctx)); -- - ret = bcm2835_new_vchi_ctx(dev, vchi_ctx); - if (ret) { - devres_free(vchi_ctx); diff --git a/target/linux/brcm2708/patches-4.19/950-0470-staging-bcm2835-audio-more-generic-probe-function-na.patch b/target/linux/brcm2708/patches-4.19/950-0470-staging-bcm2835-audio-more-generic-probe-function-na.patch new file mode 100644 index 0000000000..b5ce9b0688 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0470-staging-bcm2835-audio-more-generic-probe-function-na.patch @@ -0,0 +1,39 @@ +From 769a356761d6848a6ba1d396d97c76d6ff81451f Mon Sep 17 00:00:00 2001 +From: Nicolas Saenz Julienne +Date: Wed, 17 Oct 2018 21:01:54 +0200 +Subject: [PATCH 470/725] staging: bcm2835-audio: more generic probe function + name + +commit 96f3bd8ae6516898c7b411ecb87064bb0dd25415 upstream. + +There will only be one probe function, there is no use for appendig +"_dt" the end of the name. + +Signed-off-by: Nicolas Saenz Julienne +Reviewed-by: Takashi Iwai +Acked-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/vc04_services/bcm2835-audio/bcm2835.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +@@ -291,7 +291,7 @@ static int snd_add_child_devices(struct + return 0; + } + +-static int snd_bcm2835_alsa_probe_dt(struct platform_device *pdev) ++static int snd_bcm2835_alsa_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; + u32 numchans; +@@ -344,7 +344,7 @@ static const struct of_device_id snd_bcm + MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); + + static struct platform_driver bcm2835_alsa0_driver = { +- .probe = snd_bcm2835_alsa_probe_dt, ++ .probe = snd_bcm2835_alsa_probe, + #ifdef CONFIG_PM + .suspend = snd_bcm2835_alsa_suspend, + .resume = snd_bcm2835_alsa_resume, diff --git a/target/linux/brcm2708/patches-4.19/950-0471-staging-bcm2835-audio-rename-platform_driver-structu.patch b/target/linux/brcm2708/patches-4.19/950-0471-staging-bcm2835-audio-rename-platform_driver-structu.patch new file mode 100644 index 0000000000..40d24893c4 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0471-staging-bcm2835-audio-rename-platform_driver-structu.patch @@ -0,0 +1,47 @@ +From e46a97daa661f61453787ef90c95fe02e36ba48d Mon Sep 17 00:00:00 2001 +From: Nicolas Saenz Julienne +Date: Wed, 17 Oct 2018 21:01:55 +0200 +Subject: [PATCH 471/725] staging: bcm2835-audio: rename platform_driver + structure + +commit 82cdc0c6b6faf877e2aecb957cffa9cb578cc572 upstream. + +It was called bcm2835_alsa0_driver, that "0" didn't mean much. + +Suggested-by: Takashi Iwai +Signed-off-by: Nicolas Saenz Julienne +Acked-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/vc04_services/bcm2835-audio/bcm2835.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +@@ -343,7 +343,7 @@ static const struct of_device_id snd_bcm + }; + MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); + +-static struct platform_driver bcm2835_alsa0_driver = { ++static struct platform_driver bcm2835_alsa_driver = { + .probe = snd_bcm2835_alsa_probe, + #ifdef CONFIG_PM + .suspend = snd_bcm2835_alsa_suspend, +@@ -359,7 +359,7 @@ static int bcm2835_alsa_device_init(void + { + int retval; + +- retval = platform_driver_register(&bcm2835_alsa0_driver); ++ retval = platform_driver_register(&bcm2835_alsa_driver); + if (retval) + pr_err("Error registering bcm2835_audio driver %d .\n", retval); + +@@ -368,7 +368,7 @@ static int bcm2835_alsa_device_init(void + + static void bcm2835_alsa_device_exit(void) + { +- platform_driver_unregister(&bcm2835_alsa0_driver); ++ platform_driver_unregister(&bcm2835_alsa_driver); + } + + late_initcall(bcm2835_alsa_device_init); diff --git a/target/linux/brcm2708/patches-4.19/950-0471-staging-bcm2835-audio-reorder-variable-declarations-.patch b/target/linux/brcm2708/patches-4.19/950-0471-staging-bcm2835-audio-reorder-variable-declarations-.patch deleted file mode 100644 index d43c1675aa..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0471-staging-bcm2835-audio-reorder-variable-declarations-.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 42b0651189ceea6c9684931d68566091a37914a3 Mon Sep 17 00:00:00 2001 -From: Nicolas Saenz Julienne -Date: Wed, 17 Oct 2018 21:01:52 +0200 -Subject: [PATCH 471/703] staging: bcm2835-audio: reorder variable declarations - & remove trivial comments - -commit d048385a070552ae819f99f05bd03ec41072783d upstream. - -When it comes to declaring variables it's preferred, when possible, to -use an inverted tree organization scheme. - -Also, removes some comments that were useless. - -Signed-off-by: Nicolas Saenz Julienne -Reviewed-by: Takashi Iwai -Acked-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 10 ++-------- - .../vc04_services/bcm2835-audio/bcm2835-vchiq.c | 4 ++-- - .../staging/vc04_services/bcm2835-audio/bcm2835.c | 14 +++++++------- - 3 files changed, 11 insertions(+), 17 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -164,14 +164,11 @@ static int snd_bcm2835_playback_spdif_op - return snd_bcm2835_playback_open_generic(substream, 1); - } - --/* close callback */ - static int snd_bcm2835_playback_close(struct snd_pcm_substream *substream) - { -- /* the hardware-specific codes will be here */ -- -- struct bcm2835_chip *chip; -- struct snd_pcm_runtime *runtime; - struct bcm2835_alsa_stream *alsa_stream; -+ struct snd_pcm_runtime *runtime; -+ struct bcm2835_chip *chip; - - chip = snd_pcm_substream_chip(substream); - mutex_lock(&chip->audio_mutex); -@@ -195,20 +192,17 @@ static int snd_bcm2835_playback_close(st - return 0; - } - --/* hw_params callback */ - static int snd_bcm2835_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) - { - return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); - } - --/* hw_free callback */ - static int snd_bcm2835_pcm_hw_free(struct snd_pcm_substream *substream) - { - return snd_pcm_lib_free_pages(substream); - } - --/* prepare callback */ - static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) - { - struct bcm2835_chip *chip = snd_pcm_substream_chip(substream); ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -@@ -94,9 +94,9 @@ static void audio_vchi_callback(void *pa - void *msg_handle) - { - struct bcm2835_audio_instance *instance = param; -- int status; -- int msg_len; - struct vc_audio_msg m; -+ int msg_len; -+ int status; - - if (reason != VCHI_CALLBACK_MSG_AVAILABLE) - return; ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -161,8 +161,8 @@ static int snd_add_child_device(struct d - struct bcm2835_audio_driver *audio_driver, - u32 numchans) - { -- struct snd_card *card; - struct bcm2835_chip *chip; -+ struct snd_card *card; - int err; - - err = snd_card_new(dev, -1, NULL, THIS_MODULE, sizeof(*chip), &card); -@@ -225,12 +225,12 @@ static int snd_add_child_device(struct d - - static int snd_add_child_devices(struct device *device, u32 numchans) - { -- int i; -- int count_devices = 0; -- int minchannels = 0; -- int extrachannels = 0; - int extrachannels_per_driver = 0; - int extrachannels_remainder = 0; -+ int count_devices = 0; -+ int extrachannels = 0; -+ int minchannels = 0; -+ int i; - - for (i = 0; i < ARRAY_SIZE(children_devices); i++) - if (*children_devices[i].is_enabled) -@@ -258,9 +258,9 @@ static int snd_add_child_devices(struct - extrachannels_remainder); - - for (i = 0; i < ARRAY_SIZE(children_devices); i++) { -- int err; -- int numchannels_this_device; - struct bcm2835_audio_driver *audio_driver; -+ int numchannels_this_device; -+ int err; - - if (!*children_devices[i].is_enabled) - continue; diff --git a/target/linux/brcm2708/patches-4.19/950-0472-staging-bcm2835-audio-update-TODO.patch b/target/linux/brcm2708/patches-4.19/950-0472-staging-bcm2835-audio-update-TODO.patch new file mode 100644 index 0000000000..954a113915 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0472-staging-bcm2835-audio-update-TODO.patch @@ -0,0 +1,56 @@ +From c13b55d072cfd79e0dc17a80ee7536b272e5bcca Mon Sep 17 00:00:00 2001 +From: Nicolas Saenz Julienne +Date: Wed, 17 Oct 2018 21:01:56 +0200 +Subject: [PATCH 472/725] staging: bcm2835-audio: update TODO + +commit 01ec7398c56e8f1b903ecb3c5c75400e263eef43 upstream. + +The following tasks were completed or not the right solution: + +1/2- Not the proper solution, we should register a platform device in +vchiq the same way it's done with bcm2835-camera as commented here: +https://lkml.org/lkml/2018/10/16/1131 + +2/3- Fixed by Takashi Iwai here: https://lkml.org/lkml/2018/9/4/587 + +Also, adds a new task as per mailing list conversation. + +Signed-off-by: Nicolas Saenz Julienne +Acked-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../staging/vc04_services/bcm2835-audio/TODO | 25 +++---------------- + 1 file changed, 3 insertions(+), 22 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/TODO ++++ b/drivers/staging/vc04_services/bcm2835-audio/TODO +@@ -4,26 +4,7 @@ + * * + ***************************************************************************** + ++1) Revisit multi-cards options and PCM route mixer control (as per comment ++https://lkml.org/lkml/2018/9/8/200) + +-1) Document the device tree node +- +-The downstream tree(the tree that the driver was imported from) at +-http://www.github.com/raspberrypi/linux uses this node: +- +-audio: audio { +- compatible = "brcm,bcm2835-audio"; +- brcm,pwm-channels = <8>; +-}; +- +-Since the driver requires the use of VCHIQ, it may be useful to have a link +-in the device tree to the VCHIQ driver. +- +-2) Gracefully handle the case where VCHIQ is missing from the device tree or +-it has not been initialized yet. +- +-3) Review error handling and remove duplicate code. +- +-4) Cleanup the logging mechanism. The driver should probably be using the +-standard kernel logging mechanisms such as dev_info, dev_dbg, and friends. +- +-5) Fix the remaining checkpatch.pl errors and warnings. ++2) Fix the remaining checkpatch.pl errors and warnings. diff --git a/target/linux/brcm2708/patches-4.19/950-0472-staging-bcm2835-audio-use-anonymous-union-in-struct-.patch b/target/linux/brcm2708/patches-4.19/950-0472-staging-bcm2835-audio-use-anonymous-union-in-struct-.patch deleted file mode 100644 index 5e5fdceabd..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0472-staging-bcm2835-audio-use-anonymous-union-in-struct-.patch +++ /dev/null @@ -1,105 +0,0 @@ -From ba6476674aaab4ed91db3792eb860c65ff6c588f Mon Sep 17 00:00:00 2001 -From: Nicolas Saenz Julienne -Date: Wed, 17 Oct 2018 21:01:53 +0200 -Subject: [PATCH 472/703] staging: bcm2835-audio: use anonymous union in struct - vc_audio_msg - -commit 9c2eaf7da855d314a369d48b9cbf8ac80717a1d0 upstream. - -In this case explicitly naming the union doesn't help overall code -comprehension and clutters it. - -Signed-off-by: Nicolas Saenz Julienne -Reviewed-by: Takashi Iwai -Acked-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../bcm2835-audio/bcm2835-vchiq.c | 30 +++++++++---------- - .../bcm2835-audio/vc_vchi_audioserv_defs.h | 2 +- - 2 files changed, 16 insertions(+), 16 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -@@ -104,15 +104,15 @@ static void audio_vchi_callback(void *pa - status = vchi_msg_dequeue(instance->vchi_handle, - &m, sizeof(m), &msg_len, VCHI_FLAGS_NONE); - if (m.type == VC_AUDIO_MSG_TYPE_RESULT) { -- instance->result = m.u.result.success; -+ instance->result = m.result.success; - complete(&instance->msg_avail_comp); - } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) { -- if (m.u.complete.cookie1 != VC_AUDIO_WRITE_COOKIE1 || -- m.u.complete.cookie2 != VC_AUDIO_WRITE_COOKIE2) -+ if (m.complete.cookie1 != VC_AUDIO_WRITE_COOKIE1 || -+ m.complete.cookie2 != VC_AUDIO_WRITE_COOKIE2) - dev_err(instance->dev, "invalid cookie\n"); - else - bcm2835_playback_fifo(instance->alsa_stream, -- m.u.complete.count); -+ m.complete.count); - } else { - dev_err(instance->dev, "unexpected callback type=%d\n", m.type); - } -@@ -257,11 +257,11 @@ int bcm2835_audio_set_ctls(struct bcm283 - struct vc_audio_msg m = {}; - - m.type = VC_AUDIO_MSG_TYPE_CONTROL; -- m.u.control.dest = chip->dest; -+ m.control.dest = chip->dest; - if (!chip->mute) -- m.u.control.volume = CHIP_MIN_VOLUME; -+ m.control.volume = CHIP_MIN_VOLUME; - else -- m.u.control.volume = alsa2chip(chip->volume); -+ m.control.volume = alsa2chip(chip->volume); - - return bcm2835_audio_send_msg(alsa_stream->instance, &m, true); - } -@@ -272,9 +272,9 @@ int bcm2835_audio_set_params(struct bcm2 - { - struct vc_audio_msg m = { - .type = VC_AUDIO_MSG_TYPE_CONFIG, -- .u.config.channels = channels, -- .u.config.samplerate = samplerate, -- .u.config.bps = bps, -+ .config.channels = channels, -+ .config.samplerate = samplerate, -+ .config.bps = bps, - }; - int err; - -@@ -302,7 +302,7 @@ int bcm2835_audio_drain(struct bcm2835_a - { - struct vc_audio_msg m = { - .type = VC_AUDIO_MSG_TYPE_STOP, -- .u.stop.draining = 1, -+ .stop.draining = 1, - }; - - return bcm2835_audio_send_msg(alsa_stream->instance, &m, false); -@@ -330,10 +330,10 @@ int bcm2835_audio_write(struct bcm2835_a - struct bcm2835_audio_instance *instance = alsa_stream->instance; - struct vc_audio_msg m = { - .type = VC_AUDIO_MSG_TYPE_WRITE, -- .u.write.count = size, -- .u.write.max_packet = instance->max_packet, -- .u.write.cookie1 = VC_AUDIO_WRITE_COOKIE1, -- .u.write.cookie2 = VC_AUDIO_WRITE_COOKIE2, -+ .write.count = size, -+ .write.max_packet = instance->max_packet, -+ .write.cookie1 = VC_AUDIO_WRITE_COOKIE1, -+ .write.cookie2 = VC_AUDIO_WRITE_COOKIE2, - }; - unsigned int count; - int err, status; ---- a/drivers/staging/vc04_services/bcm2835-audio/vc_vchi_audioserv_defs.h -+++ b/drivers/staging/vc04_services/bcm2835-audio/vc_vchi_audioserv_defs.h -@@ -93,7 +93,7 @@ struct vc_audio_msg { - struct vc_audio_write write; - struct vc_audio_result result; - struct vc_audio_complete complete; -- } u; -+ }; - }; - - #endif /* _VC_AUDIO_DEFS_H_ */ diff --git a/target/linux/brcm2708/patches-4.19/950-0473-staging-bcm2835-audio-interpolate-audio-delay.patch b/target/linux/brcm2708/patches-4.19/950-0473-staging-bcm2835-audio-interpolate-audio-delay.patch new file mode 100644 index 0000000000..1c17f7afe8 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0473-staging-bcm2835-audio-interpolate-audio-delay.patch @@ -0,0 +1,82 @@ +From 3cd2b5a8d643c8e1d8ae0a63fc517ec7f47c6fb0 Mon Sep 17 00:00:00 2001 +From: Mike Brady +Date: Mon, 22 Oct 2018 20:17:08 +0100 +Subject: [PATCH 473/725] staging: bcm2835-audio: interpolate audio delay + +commit a105a3a72824e0ac685a0711a67e4dbe29de62d0 upstream. + +When the BCM2835 audio output is used, userspace sees a jitter up to 10ms +in the audio position, aka "delay" -- the number of frames that must +be output before a new frame would be played. +Make this a bit nicer for userspace by interpolating the position +using the CPU clock. +The overhead is small -- an extra ktime_get() every time a GPU message +is sent -- and another call and a few calculations whenever the delay +is sought from userland. +At 48,000 frames per second, i.e. approximately 20 microseconds per +frame, it would take a clock inaccuracy of +20 microseconds in 10 milliseconds -- 2,000 parts per million -- +to result in an inaccurate estimate, whereas +crystal- or resonator-based clocks typically have an +inaccuracy of 10s to 100s of parts per million. + +Signed-off-by: Mike Brady +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 20 +++++++++++++++++++ + .../vc04_services/bcm2835-audio/bcm2835.h | 1 + + 2 files changed, 21 insertions(+) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -74,6 +74,7 @@ void bcm2835_playback_fifo(struct bcm283 + atomic_set(&alsa_stream->pos, pos); + + alsa_stream->period_offset += bytes; ++ alsa_stream->interpolate_start = ktime_get(); + if (alsa_stream->period_offset >= alsa_stream->period_size) { + alsa_stream->period_offset %= alsa_stream->period_size; + snd_pcm_period_elapsed(substream); +@@ -237,6 +238,7 @@ static int snd_bcm2835_pcm_prepare(struc + atomic_set(&alsa_stream->pos, 0); + alsa_stream->period_offset = 0; + alsa_stream->draining = false; ++ alsa_stream->interpolate_start = ktime_get(); + + return 0; + } +@@ -286,6 +288,24 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_s + { + struct snd_pcm_runtime *runtime = substream->runtime; + struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; ++ ktime_t now = ktime_get(); ++ ++ /* Give userspace better delay reporting by interpolating between GPU ++ * notifications, assuming audio speed is close enough to the clock ++ * used for ktime ++ */ ++ ++ if ((ktime_to_ns(alsa_stream->interpolate_start)) && ++ (ktime_compare(alsa_stream->interpolate_start, now) < 0)) { ++ u64 interval = ++ (ktime_to_ns(ktime_sub(now, ++ alsa_stream->interpolate_start))); ++ u64 frames_output_in_interval = ++ div_u64((interval * runtime->rate), 1000000000); ++ snd_pcm_sframes_t frames_output_in_interval_sized = ++ -frames_output_in_interval; ++ runtime->delay = frames_output_in_interval_sized; ++ } + + return snd_pcm_indirect_playback_pointer(substream, + &alsa_stream->pcm_indirect, +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h +@@ -78,6 +78,7 @@ struct bcm2835_alsa_stream { + unsigned int period_offset; + unsigned int buffer_size; + unsigned int period_size; ++ ktime_t interpolate_start; + + struct bcm2835_audio_instance *instance; + int idx; diff --git a/target/linux/brcm2708/patches-4.19/950-0473-staging-bcm2835-audio-more-generic-probe-function-na.patch b/target/linux/brcm2708/patches-4.19/950-0473-staging-bcm2835-audio-more-generic-probe-function-na.patch deleted file mode 100644 index df728d56ef..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0473-staging-bcm2835-audio-more-generic-probe-function-na.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 7c0e6cbc1257861e011256fd78a713b8d308541d Mon Sep 17 00:00:00 2001 -From: Nicolas Saenz Julienne -Date: Wed, 17 Oct 2018 21:01:54 +0200 -Subject: [PATCH 473/703] staging: bcm2835-audio: more generic probe function - name - -commit 96f3bd8ae6516898c7b411ecb87064bb0dd25415 upstream. - -There will only be one probe function, there is no use for appendig -"_dt" the end of the name. - -Signed-off-by: Nicolas Saenz Julienne -Reviewed-by: Takashi Iwai -Acked-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/vc04_services/bcm2835-audio/bcm2835.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -291,7 +291,7 @@ static int snd_add_child_devices(struct - return 0; - } - --static int snd_bcm2835_alsa_probe_dt(struct platform_device *pdev) -+static int snd_bcm2835_alsa_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; - u32 numchans; -@@ -344,7 +344,7 @@ static const struct of_device_id snd_bcm - MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); - - static struct platform_driver bcm2835_alsa0_driver = { -- .probe = snd_bcm2835_alsa_probe_dt, -+ .probe = snd_bcm2835_alsa_probe, - #ifdef CONFIG_PM - .suspend = snd_bcm2835_alsa_suspend, - .resume = snd_bcm2835_alsa_resume, diff --git a/target/linux/brcm2708/patches-4.19/950-0474-staging-bcm2835-audio-Enable-compile-test.patch b/target/linux/brcm2708/patches-4.19/950-0474-staging-bcm2835-audio-Enable-compile-test.patch new file mode 100644 index 0000000000..23b1fcf8b9 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0474-staging-bcm2835-audio-Enable-compile-test.patch @@ -0,0 +1,27 @@ +From 68093eedc7ce6e023944cc1099810351ad3a21dd Mon Sep 17 00:00:00 2001 +From: Stefan Wahren +Date: Thu, 6 Dec 2018 19:28:56 +0100 +Subject: [PATCH 474/725] staging: bcm2835-audio: Enable compile test + +commit 458d4866a34d0c129ffc3bd56345b2166ba46d77 upstream. + +Enable the compilation test for bcm2835-audio to gain more build coverage. + +Signed-off-by: Stefan Wahren +Reviewed-by: Nicolas Saenz Julienne +Reviewed-by: Dan Carpenter +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/vc04_services/bcm2835-audio/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/Kconfig ++++ b/drivers/staging/vc04_services/bcm2835-audio/Kconfig +@@ -1,6 +1,6 @@ + config SND_BCM2835 + tristate "BCM2835 Audio" +- depends on ARCH_BCM2835 && SND ++ depends on (ARCH_BCM2835 || COMPILE_TEST) && SND + select SND_PCM + select BCM2835_VCHIQ + help diff --git a/target/linux/brcm2708/patches-4.19/950-0474-staging-bcm2835-audio-rename-platform_driver-structu.patch b/target/linux/brcm2708/patches-4.19/950-0474-staging-bcm2835-audio-rename-platform_driver-structu.patch deleted file mode 100644 index e324013c31..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0474-staging-bcm2835-audio-rename-platform_driver-structu.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 8766790884bfc46d8036a9da0dcf8d0cf291e42b Mon Sep 17 00:00:00 2001 -From: Nicolas Saenz Julienne -Date: Wed, 17 Oct 2018 21:01:55 +0200 -Subject: [PATCH 474/703] staging: bcm2835-audio: rename platform_driver - structure - -commit 82cdc0c6b6faf877e2aecb957cffa9cb578cc572 upstream. - -It was called bcm2835_alsa0_driver, that "0" didn't mean much. - -Suggested-by: Takashi Iwai -Signed-off-by: Nicolas Saenz Julienne -Acked-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/vc04_services/bcm2835-audio/bcm2835.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -343,7 +343,7 @@ static const struct of_device_id snd_bcm - }; - MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); - --static struct platform_driver bcm2835_alsa0_driver = { -+static struct platform_driver bcm2835_alsa_driver = { - .probe = snd_bcm2835_alsa_probe, - #ifdef CONFIG_PM - .suspend = snd_bcm2835_alsa_suspend, -@@ -359,7 +359,7 @@ static int bcm2835_alsa_device_init(void - { - int retval; - -- retval = platform_driver_register(&bcm2835_alsa0_driver); -+ retval = platform_driver_register(&bcm2835_alsa_driver); - if (retval) - pr_err("Error registering bcm2835_audio driver %d .\n", retval); - -@@ -368,7 +368,7 @@ static int bcm2835_alsa_device_init(void - - static void bcm2835_alsa_device_exit(void) - { -- platform_driver_unregister(&bcm2835_alsa0_driver); -+ platform_driver_unregister(&bcm2835_alsa_driver); - } - - late_initcall(bcm2835_alsa_device_init); diff --git a/target/linux/brcm2708/patches-4.19/950-0475-staging-bcm2835-audio-update-TODO.patch b/target/linux/brcm2708/patches-4.19/950-0475-staging-bcm2835-audio-update-TODO.patch deleted file mode 100644 index a9f6279f84..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0475-staging-bcm2835-audio-update-TODO.patch +++ /dev/null @@ -1,56 +0,0 @@ -From ab9ae6bfcca7033f0d6767e21076d82f4554ba99 Mon Sep 17 00:00:00 2001 -From: Nicolas Saenz Julienne -Date: Wed, 17 Oct 2018 21:01:56 +0200 -Subject: [PATCH 475/703] staging: bcm2835-audio: update TODO - -commit 01ec7398c56e8f1b903ecb3c5c75400e263eef43 upstream. - -The following tasks were completed or not the right solution: - -1/2- Not the proper solution, we should register a platform device in -vchiq the same way it's done with bcm2835-camera as commented here: -https://lkml.org/lkml/2018/10/16/1131 - -2/3- Fixed by Takashi Iwai here: https://lkml.org/lkml/2018/9/4/587 - -Also, adds a new task as per mailing list conversation. - -Signed-off-by: Nicolas Saenz Julienne -Acked-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../staging/vc04_services/bcm2835-audio/TODO | 25 +++---------------- - 1 file changed, 3 insertions(+), 22 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/TODO -+++ b/drivers/staging/vc04_services/bcm2835-audio/TODO -@@ -4,26 +4,7 @@ - * * - ***************************************************************************** - -+1) Revisit multi-cards options and PCM route mixer control (as per comment -+https://lkml.org/lkml/2018/9/8/200) - --1) Document the device tree node -- --The downstream tree(the tree that the driver was imported from) at --http://www.github.com/raspberrypi/linux uses this node: -- --audio: audio { -- compatible = "brcm,bcm2835-audio"; -- brcm,pwm-channels = <8>; --}; -- --Since the driver requires the use of VCHIQ, it may be useful to have a link --in the device tree to the VCHIQ driver. -- --2) Gracefully handle the case where VCHIQ is missing from the device tree or --it has not been initialized yet. -- --3) Review error handling and remove duplicate code. -- --4) Cleanup the logging mechanism. The driver should probably be using the --standard kernel logging mechanisms such as dev_info, dev_dbg, and friends. -- --5) Fix the remaining checkpatch.pl errors and warnings. -+2) Fix the remaining checkpatch.pl errors and warnings. diff --git a/target/linux/brcm2708/patches-4.19/950-0475-staging-bcm2835-audio-use-module_platform_driver-mac.patch b/target/linux/brcm2708/patches-4.19/950-0475-staging-bcm2835-audio-use-module_platform_driver-mac.patch new file mode 100644 index 0000000000..e856dbce05 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0475-staging-bcm2835-audio-use-module_platform_driver-mac.patch @@ -0,0 +1,48 @@ +From d84c50e6ccd6138d902da87d293ee6ae5855b611 Mon Sep 17 00:00:00 2001 +From: Stefan Wahren +Date: Thu, 6 Dec 2018 19:28:57 +0100 +Subject: [PATCH 475/725] staging: bcm2835-audio: use module_platform_driver() + macro + +commit 1e55d56344b0777d6cee9b9e4a813d53728ee798 upstream. + +There is not much value behind this boilerplate, so use +module_platform_driver() instead. + +Signed-off-by: Stefan Wahren +Reviewed-by: Nicolas Saenz Julienne +Reviewed-by: Dan Carpenter +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835.c | 20 +------------------ + 1 file changed, 1 insertion(+), 19 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +@@ -354,25 +354,7 @@ static struct platform_driver bcm2835_al + .of_match_table = snd_bcm2835_of_match_table, + }, + }; +- +-static int bcm2835_alsa_device_init(void) +-{ +- int retval; +- +- retval = platform_driver_register(&bcm2835_alsa_driver); +- if (retval) +- pr_err("Error registering bcm2835_audio driver %d .\n", retval); +- +- return retval; +-} +- +-static void bcm2835_alsa_device_exit(void) +-{ +- platform_driver_unregister(&bcm2835_alsa_driver); +-} +- +-late_initcall(bcm2835_alsa_device_init); +-module_exit(bcm2835_alsa_device_exit); ++module_platform_driver(bcm2835_alsa_driver); + + MODULE_AUTHOR("Dom Cobley"); + MODULE_DESCRIPTION("Alsa driver for BCM2835 chip"); diff --git a/target/linux/brcm2708/patches-4.19/950-0476-staging-bcm2835-audio-Drop-DT-dependency.patch b/target/linux/brcm2708/patches-4.19/950-0476-staging-bcm2835-audio-Drop-DT-dependency.patch new file mode 100644 index 0000000000..50d6630dc1 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0476-staging-bcm2835-audio-Drop-DT-dependency.patch @@ -0,0 +1,105 @@ +From e035b14b6608084e3276253cf477ecfc0f68fd18 Mon Sep 17 00:00:00 2001 +From: Stefan Wahren +Date: Thu, 6 Dec 2018 19:28:58 +0100 +Subject: [PATCH 476/725] staging: bcm2835-audio: Drop DT dependency + +commit 438fc48260a0afc4cee733e5bc20234ff2bbef56 upstream. + +Just like the bcm2835-video make this a platform driver which is probed +by vchiq. In order to change the number of channels use a module +parameter instead, but use the maximum as default. + +Signed-off-by: Stefan Wahren +Reviewed-by: Nicolas Saenz Julienne +Reviewed-by: Dan Carpenter +Signed-off-by: Greg Kroah-Hartman +--- + .../vc04_services/bcm2835-audio/bcm2835.c | 31 ++++++------------- + 1 file changed, 9 insertions(+), 22 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +@@ -6,13 +6,13 @@ + #include + #include + #include +-#include + + #include "bcm2835.h" + + static bool enable_hdmi; + static bool enable_headphones; + static bool enable_compat_alsa = true; ++static int num_channels = MAX_SUBSTREAMS; + + module_param(enable_hdmi, bool, 0444); + MODULE_PARM_DESC(enable_hdmi, "Enables HDMI virtual audio device"); +@@ -21,6 +21,8 @@ MODULE_PARM_DESC(enable_headphones, "Ena + module_param(enable_compat_alsa, bool, 0444); + MODULE_PARM_DESC(enable_compat_alsa, + "Enables ALSA compatibility virtual audio device"); ++module_param(num_channels, int, 0644); ++MODULE_PARM_DESC(num_channels, "Number of audio channels (default: 8)"); + + static void bcm2835_devm_free_vchi_ctx(struct device *dev, void *res) + { +@@ -294,28 +296,19 @@ static int snd_add_child_devices(struct + static int snd_bcm2835_alsa_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +- u32 numchans; + int err; + +- err = of_property_read_u32(dev->of_node, "brcm,pwm-channels", +- &numchans); +- if (err) { +- dev_err(dev, "Failed to get DT property 'brcm,pwm-channels'"); +- return err; +- } +- +- if (numchans == 0 || numchans > MAX_SUBSTREAMS) { +- numchans = MAX_SUBSTREAMS; +- dev_warn(dev, +- "Illegal 'brcm,pwm-channels' value, will use %u\n", +- numchans); ++ if (num_channels <= 0 || num_channels > MAX_SUBSTREAMS) { ++ num_channels = MAX_SUBSTREAMS; ++ dev_warn(dev, "Illegal num_channels value, will use %u\n", ++ num_channels); + } + + err = bcm2835_devm_add_vchi_ctx(dev); + if (err) + return err; + +- err = snd_add_child_devices(dev, numchans); ++ err = snd_add_child_devices(dev, num_channels); + if (err) + return err; + +@@ -337,12 +330,6 @@ static int snd_bcm2835_alsa_resume(struc + + #endif + +-static const struct of_device_id snd_bcm2835_of_match_table[] = { +- { .compatible = "brcm,bcm2835-audio",}, +- {}, +-}; +-MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); +- + static struct platform_driver bcm2835_alsa_driver = { + .probe = snd_bcm2835_alsa_probe, + #ifdef CONFIG_PM +@@ -351,7 +338,6 @@ static struct platform_driver bcm2835_al + #endif + .driver = { + .name = "bcm2835_audio", +- .of_match_table = snd_bcm2835_of_match_table, + }, + }; + module_platform_driver(bcm2835_alsa_driver); +@@ -359,3 +345,4 @@ module_platform_driver(bcm2835_alsa_driv + MODULE_AUTHOR("Dom Cobley"); + MODULE_DESCRIPTION("Alsa driver for BCM2835 chip"); + MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:bcm2835_audio"); diff --git a/target/linux/brcm2708/patches-4.19/950-0476-staging-bcm2835-audio-interpolate-audio-delay.patch b/target/linux/brcm2708/patches-4.19/950-0476-staging-bcm2835-audio-interpolate-audio-delay.patch deleted file mode 100644 index 7f1e326567..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0476-staging-bcm2835-audio-interpolate-audio-delay.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 798edea528f75fd95c0edc6967efce509969e8e9 Mon Sep 17 00:00:00 2001 -From: Mike Brady -Date: Mon, 22 Oct 2018 20:17:08 +0100 -Subject: [PATCH 476/703] staging: bcm2835-audio: interpolate audio delay - -commit a105a3a72824e0ac685a0711a67e4dbe29de62d0 upstream. - -When the BCM2835 audio output is used, userspace sees a jitter up to 10ms -in the audio position, aka "delay" -- the number of frames that must -be output before a new frame would be played. -Make this a bit nicer for userspace by interpolating the position -using the CPU clock. -The overhead is small -- an extra ktime_get() every time a GPU message -is sent -- and another call and a few calculations whenever the delay -is sought from userland. -At 48,000 frames per second, i.e. approximately 20 microseconds per -frame, it would take a clock inaccuracy of -20 microseconds in 10 milliseconds -- 2,000 parts per million -- -to result in an inaccurate estimate, whereas -crystal- or resonator-based clocks typically have an -inaccuracy of 10s to 100s of parts per million. - -Signed-off-by: Mike Brady -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 20 +++++++++++++++++++ - .../vc04_services/bcm2835-audio/bcm2835.h | 1 + - 2 files changed, 21 insertions(+) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -74,6 +74,7 @@ void bcm2835_playback_fifo(struct bcm283 - atomic_set(&alsa_stream->pos, pos); - - alsa_stream->period_offset += bytes; -+ alsa_stream->interpolate_start = ktime_get(); - if (alsa_stream->period_offset >= alsa_stream->period_size) { - alsa_stream->period_offset %= alsa_stream->period_size; - snd_pcm_period_elapsed(substream); -@@ -237,6 +238,7 @@ static int snd_bcm2835_pcm_prepare(struc - atomic_set(&alsa_stream->pos, 0); - alsa_stream->period_offset = 0; - alsa_stream->draining = false; -+ alsa_stream->interpolate_start = ktime_get(); - - return 0; - } -@@ -286,6 +288,24 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_s - { - struct snd_pcm_runtime *runtime = substream->runtime; - struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; -+ ktime_t now = ktime_get(); -+ -+ /* Give userspace better delay reporting by interpolating between GPU -+ * notifications, assuming audio speed is close enough to the clock -+ * used for ktime -+ */ -+ -+ if ((ktime_to_ns(alsa_stream->interpolate_start)) && -+ (ktime_compare(alsa_stream->interpolate_start, now) < 0)) { -+ u64 interval = -+ (ktime_to_ns(ktime_sub(now, -+ alsa_stream->interpolate_start))); -+ u64 frames_output_in_interval = -+ div_u64((interval * runtime->rate), 1000000000); -+ snd_pcm_sframes_t frames_output_in_interval_sized = -+ -frames_output_in_interval; -+ runtime->delay = frames_output_in_interval_sized; -+ } - - return snd_pcm_indirect_playback_pointer(substream, - &alsa_stream->pcm_indirect, ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -@@ -78,6 +78,7 @@ struct bcm2835_alsa_stream { - unsigned int period_offset; - unsigned int buffer_size; - unsigned int period_size; -+ ktime_t interpolate_start; - - struct bcm2835_audio_instance *instance; - int idx; diff --git a/target/linux/brcm2708/patches-4.19/950-0477-staging-bcm2835-audio-Enable-compile-test.patch b/target/linux/brcm2708/patches-4.19/950-0477-staging-bcm2835-audio-Enable-compile-test.patch deleted file mode 100644 index 956ed80c9b..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0477-staging-bcm2835-audio-Enable-compile-test.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 54b8fc1b2213a73f56a5ca9e098f420014f3c073 Mon Sep 17 00:00:00 2001 -From: Stefan Wahren -Date: Thu, 6 Dec 2018 19:28:56 +0100 -Subject: [PATCH 477/703] staging: bcm2835-audio: Enable compile test - -commit 458d4866a34d0c129ffc3bd56345b2166ba46d77 upstream. - -Enable the compilation test for bcm2835-audio to gain more build coverage. - -Signed-off-by: Stefan Wahren -Reviewed-by: Nicolas Saenz Julienne -Reviewed-by: Dan Carpenter -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/vc04_services/bcm2835-audio/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/Kconfig -+++ b/drivers/staging/vc04_services/bcm2835-audio/Kconfig -@@ -1,6 +1,6 @@ - config SND_BCM2835 - tristate "BCM2835 Audio" -- depends on ARCH_BCM2835 && SND -+ depends on (ARCH_BCM2835 || COMPILE_TEST) && SND - select SND_PCM - select BCM2835_VCHIQ - help diff --git a/target/linux/brcm2708/patches-4.19/950-0477-staging-bcm2835-audio-double-free-in-init-error-path.patch b/target/linux/brcm2708/patches-4.19/950-0477-staging-bcm2835-audio-double-free-in-init-error-path.patch new file mode 100644 index 0000000000..4c1db15c9e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0477-staging-bcm2835-audio-double-free-in-init-error-path.patch @@ -0,0 +1,30 @@ +From abba794012b78bca2bb90277ef088edf8f3b84ff Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Mon, 17 Dec 2018 10:08:54 +0300 +Subject: [PATCH 477/725] staging: bcm2835-audio: double free in init error + path + +commit 136ff5e49271c4c8fceeca5491c48e66b961564b upstream. + +We free instance here and in the caller. It should be only the caller +which handles it. + +Fixes: d7ca3a71545b ("staging: bcm2835-audio: Operate non-atomic PCM ops") +Signed-off-by: Dan Carpenter +Reviewed-by: Takashi Iwai +Cc: stable +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +@@ -145,7 +145,6 @@ vc_vchi_audio_init(VCHI_INSTANCE_T vchi_ + dev_err(instance->dev, + "failed to open VCHI service connection (status=%d)\n", + status); +- kfree(instance); + return -EPERM; + } + diff --git a/target/linux/brcm2708/patches-4.19/950-0478-dts-Increase-default-coherent-pool-size.patch b/target/linux/brcm2708/patches-4.19/950-0478-dts-Increase-default-coherent-pool-size.patch new file mode 100644 index 0000000000..384bcf5af4 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0478-dts-Increase-default-coherent-pool-size.patch @@ -0,0 +1,27 @@ +From 89102cfe2b789118442d9a0e9a0e42fcf29f8f58 Mon Sep 17 00:00:00 2001 +From: P33M +Date: Wed, 1 May 2019 15:00:05 +0100 +Subject: [PATCH 478/725] dts: Increase default coherent pool size + +dwc_otg allocates DMA-coherent buffers in atomic context for misaligned +transfer buffers. The pool that these allocations come from is set up +at boot-time but can be overridden by a commandline parameter - +increase this for now to prevent failures seen on 4.19 with multiple +USB Ethernet devices. + +see: https://github.com/raspberrypi/linux/issues/2924 +--- + arch/arm/boot/dts/bcm270x.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/bcm270x.dtsi ++++ b/arch/arm/boot/dts/bcm270x.dtsi +@@ -3,7 +3,7 @@ + + / { + chosen { +- bootargs = ""; ++ bootargs = "coherent_pool=1M"; + /delete-property/ stdout-path; + }; + diff --git a/target/linux/brcm2708/patches-4.19/950-0478-staging-bcm2835-audio-use-module_platform_driver-mac.patch b/target/linux/brcm2708/patches-4.19/950-0478-staging-bcm2835-audio-use-module_platform_driver-mac.patch deleted file mode 100644 index 05f1e063fb..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0478-staging-bcm2835-audio-use-module_platform_driver-mac.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 8981dcb58013f5e48b8657377018cb09896bab98 Mon Sep 17 00:00:00 2001 -From: Stefan Wahren -Date: Thu, 6 Dec 2018 19:28:57 +0100 -Subject: [PATCH 478/703] staging: bcm2835-audio: use module_platform_driver() - macro - -commit 1e55d56344b0777d6cee9b9e4a813d53728ee798 upstream. - -There is not much value behind this boilerplate, so use -module_platform_driver() instead. - -Signed-off-by: Stefan Wahren -Reviewed-by: Nicolas Saenz Julienne -Reviewed-by: Dan Carpenter -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835.c | 20 +------------------ - 1 file changed, 1 insertion(+), 19 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -354,25 +354,7 @@ static struct platform_driver bcm2835_al - .of_match_table = snd_bcm2835_of_match_table, - }, - }; -- --static int bcm2835_alsa_device_init(void) --{ -- int retval; -- -- retval = platform_driver_register(&bcm2835_alsa_driver); -- if (retval) -- pr_err("Error registering bcm2835_audio driver %d .\n", retval); -- -- return retval; --} -- --static void bcm2835_alsa_device_exit(void) --{ -- platform_driver_unregister(&bcm2835_alsa_driver); --} -- --late_initcall(bcm2835_alsa_device_init); --module_exit(bcm2835_alsa_device_exit); -+module_platform_driver(bcm2835_alsa_driver); - - MODULE_AUTHOR("Dom Cobley"); - MODULE_DESCRIPTION("Alsa driver for BCM2835 chip"); diff --git a/target/linux/brcm2708/patches-4.19/950-0479-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch b/target/linux/brcm2708/patches-4.19/950-0479-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch new file mode 100644 index 0000000000..76e87ec136 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0479-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch @@ -0,0 +1,96 @@ +From d9e9bfb28a22d9f1ed95e2dbe71bec9662717724 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 1 May 2019 14:23:39 +0100 +Subject: [PATCH 479/725] Revert "staging: bcm2835-audio: Drop DT dependency" + +This reverts commit 60a2e557a4f81480216066f22b84c3dda31b3470. +--- + .../vc04_services/bcm2835-audio/bcm2835.c | 31 +++++++++++++------ + 1 file changed, 22 insertions(+), 9 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +@@ -6,13 +6,13 @@ + #include + #include + #include ++#include + + #include "bcm2835.h" + + static bool enable_hdmi; + static bool enable_headphones; + static bool enable_compat_alsa = true; +-static int num_channels = MAX_SUBSTREAMS; + + module_param(enable_hdmi, bool, 0444); + MODULE_PARM_DESC(enable_hdmi, "Enables HDMI virtual audio device"); +@@ -21,8 +21,6 @@ MODULE_PARM_DESC(enable_headphones, "Ena + module_param(enable_compat_alsa, bool, 0444); + MODULE_PARM_DESC(enable_compat_alsa, + "Enables ALSA compatibility virtual audio device"); +-module_param(num_channels, int, 0644); +-MODULE_PARM_DESC(num_channels, "Number of audio channels (default: 8)"); + + static void bcm2835_devm_free_vchi_ctx(struct device *dev, void *res) + { +@@ -296,19 +294,28 @@ static int snd_add_child_devices(struct + static int snd_bcm2835_alsa_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; ++ u32 numchans; + int err; + +- if (num_channels <= 0 || num_channels > MAX_SUBSTREAMS) { +- num_channels = MAX_SUBSTREAMS; +- dev_warn(dev, "Illegal num_channels value, will use %u\n", +- num_channels); ++ err = of_property_read_u32(dev->of_node, "brcm,pwm-channels", ++ &numchans); ++ if (err) { ++ dev_err(dev, "Failed to get DT property 'brcm,pwm-channels'"); ++ return err; ++ } ++ ++ if (numchans == 0 || numchans > MAX_SUBSTREAMS) { ++ numchans = MAX_SUBSTREAMS; ++ dev_warn(dev, ++ "Illegal 'brcm,pwm-channels' value, will use %u\n", ++ numchans); + } + + err = bcm2835_devm_add_vchi_ctx(dev); + if (err) + return err; + +- err = snd_add_child_devices(dev, num_channels); ++ err = snd_add_child_devices(dev, numchans); + if (err) + return err; + +@@ -330,6 +337,12 @@ static int snd_bcm2835_alsa_resume(struc + + #endif + ++static const struct of_device_id snd_bcm2835_of_match_table[] = { ++ { .compatible = "brcm,bcm2835-audio",}, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); ++ + static struct platform_driver bcm2835_alsa_driver = { + .probe = snd_bcm2835_alsa_probe, + #ifdef CONFIG_PM +@@ -338,6 +351,7 @@ static struct platform_driver bcm2835_al + #endif + .driver = { + .name = "bcm2835_audio", ++ .of_match_table = snd_bcm2835_of_match_table, + }, + }; + module_platform_driver(bcm2835_alsa_driver); +@@ -345,4 +359,3 @@ module_platform_driver(bcm2835_alsa_driv + MODULE_AUTHOR("Dom Cobley"); + MODULE_DESCRIPTION("Alsa driver for BCM2835 chip"); + MODULE_LICENSE("GPL"); +-MODULE_ALIAS("platform:bcm2835_audio"); diff --git a/target/linux/brcm2708/patches-4.19/950-0479-staging-bcm2835-audio-Drop-DT-dependency.patch b/target/linux/brcm2708/patches-4.19/950-0479-staging-bcm2835-audio-Drop-DT-dependency.patch deleted file mode 100644 index dc8085c4cf..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0479-staging-bcm2835-audio-Drop-DT-dependency.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 2fa5b1611732fd522cbceaded4dad36e81b3d990 Mon Sep 17 00:00:00 2001 -From: Stefan Wahren -Date: Thu, 6 Dec 2018 19:28:58 +0100 -Subject: [PATCH 479/703] staging: bcm2835-audio: Drop DT dependency - -commit 438fc48260a0afc4cee733e5bc20234ff2bbef56 upstream. - -Just like the bcm2835-video make this a platform driver which is probed -by vchiq. In order to change the number of channels use a module -parameter instead, but use the maximum as default. - -Signed-off-by: Stefan Wahren -Reviewed-by: Nicolas Saenz Julienne -Reviewed-by: Dan Carpenter -Signed-off-by: Greg Kroah-Hartman ---- - .../vc04_services/bcm2835-audio/bcm2835.c | 31 ++++++------------- - 1 file changed, 9 insertions(+), 22 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -6,13 +6,13 @@ - #include - #include - #include --#include - - #include "bcm2835.h" - - static bool enable_hdmi; - static bool enable_headphones; - static bool enable_compat_alsa = true; -+static int num_channels = MAX_SUBSTREAMS; - - module_param(enable_hdmi, bool, 0444); - MODULE_PARM_DESC(enable_hdmi, "Enables HDMI virtual audio device"); -@@ -21,6 +21,8 @@ MODULE_PARM_DESC(enable_headphones, "Ena - module_param(enable_compat_alsa, bool, 0444); - MODULE_PARM_DESC(enable_compat_alsa, - "Enables ALSA compatibility virtual audio device"); -+module_param(num_channels, int, 0644); -+MODULE_PARM_DESC(num_channels, "Number of audio channels (default: 8)"); - - static void bcm2835_devm_free_vchi_ctx(struct device *dev, void *res) - { -@@ -294,28 +296,19 @@ static int snd_add_child_devices(struct - static int snd_bcm2835_alsa_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -- u32 numchans; - int err; - -- err = of_property_read_u32(dev->of_node, "brcm,pwm-channels", -- &numchans); -- if (err) { -- dev_err(dev, "Failed to get DT property 'brcm,pwm-channels'"); -- return err; -- } -- -- if (numchans == 0 || numchans > MAX_SUBSTREAMS) { -- numchans = MAX_SUBSTREAMS; -- dev_warn(dev, -- "Illegal 'brcm,pwm-channels' value, will use %u\n", -- numchans); -+ if (num_channels <= 0 || num_channels > MAX_SUBSTREAMS) { -+ num_channels = MAX_SUBSTREAMS; -+ dev_warn(dev, "Illegal num_channels value, will use %u\n", -+ num_channels); - } - - err = bcm2835_devm_add_vchi_ctx(dev); - if (err) - return err; - -- err = snd_add_child_devices(dev, numchans); -+ err = snd_add_child_devices(dev, num_channels); - if (err) - return err; - -@@ -337,12 +330,6 @@ static int snd_bcm2835_alsa_resume(struc - - #endif - --static const struct of_device_id snd_bcm2835_of_match_table[] = { -- { .compatible = "brcm,bcm2835-audio",}, -- {}, --}; --MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); -- - static struct platform_driver bcm2835_alsa_driver = { - .probe = snd_bcm2835_alsa_probe, - #ifdef CONFIG_PM -@@ -351,7 +338,6 @@ static struct platform_driver bcm2835_al - #endif - .driver = { - .name = "bcm2835_audio", -- .of_match_table = snd_bcm2835_of_match_table, - }, - }; - module_platform_driver(bcm2835_alsa_driver); -@@ -359,3 +345,4 @@ module_platform_driver(bcm2835_alsa_driv - MODULE_AUTHOR("Dom Cobley"); - MODULE_DESCRIPTION("Alsa driver for BCM2835 chip"); - MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:bcm2835_audio"); diff --git a/target/linux/brcm2708/patches-4.19/950-0480-configs-Enable-netdev-LED-trigger.patch b/target/linux/brcm2708/patches-4.19/950-0480-configs-Enable-netdev-LED-trigger.patch new file mode 100644 index 0000000000..f768d37f43 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0480-configs-Enable-netdev-LED-trigger.patch @@ -0,0 +1,42 @@ +From 964ee89545061f55bee90bae39b852db74607468 Mon Sep 17 00:00:00 2001 +From: Russell Joyce +Date: Wed, 1 May 2019 16:43:27 +0100 +Subject: [PATCH 480/725] configs: Enable netdev LED trigger + +Signed-off-by: Russell Joyce +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + arch/arm64/configs/bcmrpi3_defconfig | 1 + + 3 files changed, 3 insertions(+) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -1143,6 +1143,7 @@ CONFIG_LEDS_TRIGGER_TRANSIENT=m + CONFIG_LEDS_TRIGGER_CAMERA=m + CONFIG_LEDS_TRIGGER_INPUT=y + CONFIG_LEDS_TRIGGER_PANIC=y ++CONFIG_LEDS_TRIGGER_NETDEV=m + CONFIG_RTC_CLASS=y + # CONFIG_RTC_HCTOSYS is not set + CONFIG_RTC_DRV_ABX80X=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -1136,6 +1136,7 @@ CONFIG_LEDS_TRIGGER_TRANSIENT=m + CONFIG_LEDS_TRIGGER_CAMERA=m + CONFIG_LEDS_TRIGGER_INPUT=y + CONFIG_LEDS_TRIGGER_PANIC=y ++CONFIG_LEDS_TRIGGER_NETDEV=m + CONFIG_RTC_CLASS=y + # CONFIG_RTC_HCTOSYS is not set + CONFIG_RTC_DRV_ABX80X=m +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -1003,6 +1003,7 @@ CONFIG_LEDS_TRIGGER_TRANSIENT=m + CONFIG_LEDS_TRIGGER_CAMERA=m + CONFIG_LEDS_TRIGGER_INPUT=y + CONFIG_LEDS_TRIGGER_PANIC=y ++CONFIG_LEDS_TRIGGER_NETDEV=m + CONFIG_RTC_CLASS=y + # CONFIG_RTC_HCTOSYS is not set + CONFIG_RTC_DRV_ABX80X=m diff --git a/target/linux/brcm2708/patches-4.19/950-0480-staging-bcm2835-audio-double-free-in-init-error-path.patch b/target/linux/brcm2708/patches-4.19/950-0480-staging-bcm2835-audio-double-free-in-init-error-path.patch deleted file mode 100644 index f5a83bd1b9..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0480-staging-bcm2835-audio-double-free-in-init-error-path.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 9886534de7551e0a59e90677bd1bab0539102772 Mon Sep 17 00:00:00 2001 -From: Dan Carpenter -Date: Mon, 17 Dec 2018 10:08:54 +0300 -Subject: [PATCH 480/703] staging: bcm2835-audio: double free in init error - path - -commit 136ff5e49271c4c8fceeca5491c48e66b961564b upstream. - -We free instance here and in the caller. It should be only the caller -which handles it. - -Fixes: d7ca3a71545b ("staging: bcm2835-audio: Operate non-atomic PCM ops") -Signed-off-by: Dan Carpenter -Reviewed-by: Takashi Iwai -Cc: stable -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c -@@ -145,7 +145,6 @@ vc_vchi_audio_init(VCHI_INSTANCE_T vchi_ - dev_err(instance->dev, - "failed to open VCHI service connection (status=%d)\n", - status); -- kfree(instance); - return -EPERM; - } - diff --git a/target/linux/brcm2708/patches-4.19/950-0481-dts-Increase-default-coherent-pool-size.patch b/target/linux/brcm2708/patches-4.19/950-0481-dts-Increase-default-coherent-pool-size.patch deleted file mode 100644 index 8331777eea..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0481-dts-Increase-default-coherent-pool-size.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 451f65d34555dad7837da5f9502968f31284615b Mon Sep 17 00:00:00 2001 -From: P33M -Date: Wed, 1 May 2019 15:00:05 +0100 -Subject: [PATCH 481/703] dts: Increase default coherent pool size - -dwc_otg allocates DMA-coherent buffers in atomic context for misaligned -transfer buffers. The pool that these allocations come from is set up -at boot-time but can be overridden by a commandline parameter - -increase this for now to prevent failures seen on 4.19 with multiple -USB Ethernet devices. - -see: https://github.com/raspberrypi/linux/issues/2924 ---- - arch/arm/boot/dts/bcm270x.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/bcm270x.dtsi -+++ b/arch/arm/boot/dts/bcm270x.dtsi -@@ -3,7 +3,7 @@ - - / { - chosen { -- bootargs = ""; -+ bootargs = "coherent_pool=1M"; - /delete-property/ stdout-path; - }; - diff --git a/target/linux/brcm2708/patches-4.19/950-0481-smsc95xx-dynamically-fix-up-TX-buffer-alignment-with.patch b/target/linux/brcm2708/patches-4.19/950-0481-smsc95xx-dynamically-fix-up-TX-buffer-alignment-with.patch new file mode 100644 index 0000000000..db7d9a9318 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0481-smsc95xx-dynamically-fix-up-TX-buffer-alignment-with.patch @@ -0,0 +1,62 @@ +From 706a1636883d35b9399be0003d9e36d0f46fd6c5 Mon Sep 17 00:00:00 2001 +From: P33M +Date: Wed, 1 May 2019 17:04:32 +0100 +Subject: [PATCH 481/725] smsc95xx: dynamically fix up TX buffer alignment with + padding bytes + +dwc_otg requires a 32-bit aligned buffer start address, otherwise +expensive bounce buffers are used. The LAN951x hardware can skip up to +3 bytes between the TX header and the start of frame data, which can +be used to force alignment of the URB passed to dwc_otg. + +As found in https://github.com/raspberrypi/linux/issues/2924 +--- + drivers/net/usb/smsc95xx.c | 12 +++++++----- + drivers/net/usb/smsc95xx.h | 2 +- + 2 files changed, 8 insertions(+), 6 deletions(-) + +--- a/drivers/net/usb/smsc95xx.c ++++ b/drivers/net/usb/smsc95xx.c +@@ -2082,7 +2082,9 @@ static struct sk_buff *smsc95xx_tx_fixup + struct sk_buff *skb, gfp_t flags) + { + bool csum = skb->ip_summed == CHECKSUM_PARTIAL; +- int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM : SMSC95XX_TX_OVERHEAD; ++ unsigned int align_bytes = -((uintptr_t)skb->data) & 0x3; ++ int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM + align_bytes ++ : SMSC95XX_TX_OVERHEAD + align_bytes; + u32 tx_cmd_a, tx_cmd_b; + + /* We do not advertise SG, so skbs should be already linearized */ +@@ -2116,16 +2118,16 @@ static struct sk_buff *smsc95xx_tx_fixup + } + } + +- skb_push(skb, 4); +- tx_cmd_b = (u32)(skb->len - 4); ++ skb_push(skb, 4 + align_bytes); ++ tx_cmd_b = (u32)(skb->len - 4 - align_bytes); + if (csum) + tx_cmd_b |= TX_CMD_B_CSUM_ENABLE; + cpu_to_le32s(&tx_cmd_b); + memcpy(skb->data, &tx_cmd_b, 4); + + skb_push(skb, 4); +- tx_cmd_a = (u32)(skb->len - 8) | TX_CMD_A_FIRST_SEG_ | +- TX_CMD_A_LAST_SEG_; ++ tx_cmd_a = (u32)(skb->len - 8 - align_bytes) | TX_CMD_A_FIRST_SEG_ | ++ (align_bytes << 16) | TX_CMD_A_LAST_SEG_; + cpu_to_le32s(&tx_cmd_a); + memcpy(skb->data, &tx_cmd_a, 4); + +--- a/drivers/net/usb/smsc95xx.h ++++ b/drivers/net/usb/smsc95xx.h +@@ -21,7 +21,7 @@ + #define _SMSC95XX_H + + /* Tx command words */ +-#define TX_CMD_A_DATA_OFFSET_ (0x001F0000) /* Data Start Offset */ ++#define TX_CMD_A_DATA_OFFSET_ (0x00030000) /* Data Start Offset */ + #define TX_CMD_A_FIRST_SEG_ (0x00002000) /* First Segment */ + #define TX_CMD_A_LAST_SEG_ (0x00001000) /* Last Segment */ + #define TX_CMD_A_BUF_SIZE_ (0x000007FF) /* Buffer Size */ diff --git a/target/linux/brcm2708/patches-4.19/950-0482-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch b/target/linux/brcm2708/patches-4.19/950-0482-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch deleted file mode 100644 index 2b5928ef07..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0482-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 5a957250fdb0f0b45bd41569c754a676fa556225 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 1 May 2019 14:23:39 +0100 -Subject: [PATCH 482/703] Revert "staging: bcm2835-audio: Drop DT dependency" - -This reverts commit 60a2e557a4f81480216066f22b84c3dda31b3470. ---- - .../vc04_services/bcm2835-audio/bcm2835.c | 31 +++++++++++++------ - 1 file changed, 22 insertions(+), 9 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -6,13 +6,13 @@ - #include - #include - #include -+#include - - #include "bcm2835.h" - - static bool enable_hdmi; - static bool enable_headphones; - static bool enable_compat_alsa = true; --static int num_channels = MAX_SUBSTREAMS; - - module_param(enable_hdmi, bool, 0444); - MODULE_PARM_DESC(enable_hdmi, "Enables HDMI virtual audio device"); -@@ -21,8 +21,6 @@ MODULE_PARM_DESC(enable_headphones, "Ena - module_param(enable_compat_alsa, bool, 0444); - MODULE_PARM_DESC(enable_compat_alsa, - "Enables ALSA compatibility virtual audio device"); --module_param(num_channels, int, 0644); --MODULE_PARM_DESC(num_channels, "Number of audio channels (default: 8)"); - - static void bcm2835_devm_free_vchi_ctx(struct device *dev, void *res) - { -@@ -296,19 +294,28 @@ static int snd_add_child_devices(struct - static int snd_bcm2835_alsa_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -+ u32 numchans; - int err; - -- if (num_channels <= 0 || num_channels > MAX_SUBSTREAMS) { -- num_channels = MAX_SUBSTREAMS; -- dev_warn(dev, "Illegal num_channels value, will use %u\n", -- num_channels); -+ err = of_property_read_u32(dev->of_node, "brcm,pwm-channels", -+ &numchans); -+ if (err) { -+ dev_err(dev, "Failed to get DT property 'brcm,pwm-channels'"); -+ return err; -+ } -+ -+ if (numchans == 0 || numchans > MAX_SUBSTREAMS) { -+ numchans = MAX_SUBSTREAMS; -+ dev_warn(dev, -+ "Illegal 'brcm,pwm-channels' value, will use %u\n", -+ numchans); - } - - err = bcm2835_devm_add_vchi_ctx(dev); - if (err) - return err; - -- err = snd_add_child_devices(dev, num_channels); -+ err = snd_add_child_devices(dev, numchans); - if (err) - return err; - -@@ -330,6 +337,12 @@ static int snd_bcm2835_alsa_resume(struc - - #endif - -+static const struct of_device_id snd_bcm2835_of_match_table[] = { -+ { .compatible = "brcm,bcm2835-audio",}, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); -+ - static struct platform_driver bcm2835_alsa_driver = { - .probe = snd_bcm2835_alsa_probe, - #ifdef CONFIG_PM -@@ -338,6 +351,7 @@ static struct platform_driver bcm2835_al - #endif - .driver = { - .name = "bcm2835_audio", -+ .of_match_table = snd_bcm2835_of_match_table, - }, - }; - module_platform_driver(bcm2835_alsa_driver); -@@ -345,4 +359,3 @@ module_platform_driver(bcm2835_alsa_driv - MODULE_AUTHOR("Dom Cobley"); - MODULE_DESCRIPTION("Alsa driver for BCM2835 chip"); - MODULE_LICENSE("GPL"); --MODULE_ALIAS("platform:bcm2835_audio"); diff --git a/target/linux/brcm2708/patches-4.19/950-0482-lan78xx-use-default-alignment-for-rx-buffers.patch b/target/linux/brcm2708/patches-4.19/950-0482-lan78xx-use-default-alignment-for-rx-buffers.patch new file mode 100644 index 0000000000..b14c6394a6 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0482-lan78xx-use-default-alignment-for-rx-buffers.patch @@ -0,0 +1,23 @@ +From d57123651a91cf3896faf299614475225dcc88f0 Mon Sep 17 00:00:00 2001 +From: P33M +Date: Thu, 2 May 2019 11:53:45 +0100 +Subject: [PATCH 482/725] lan78xx: use default alignment for rx buffers + +The lan78xx uses a 12-byte hardware rx header, so there is no need +to allocate SKBs with NET_IP_ALIGN set. Removes alignment faults +in both dwc_otg and in ipv6 processing. +--- + drivers/net/usb/lan78xx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -3250,7 +3250,7 @@ static int rx_submit(struct lan78xx_net + size_t size = dev->rx_urb_size; + int ret = 0; + +- skb = netdev_alloc_skb_ip_align(dev->net, size); ++ skb = netdev_alloc_skb(dev->net, size); + if (!skb) { + usb_free_urb(urb); + return -ENOMEM; diff --git a/target/linux/brcm2708/patches-4.19/950-0483-configs-Enable-netdev-LED-trigger.patch b/target/linux/brcm2708/patches-4.19/950-0483-configs-Enable-netdev-LED-trigger.patch deleted file mode 100644 index 797e0b3879..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0483-configs-Enable-netdev-LED-trigger.patch +++ /dev/null @@ -1,42 +0,0 @@ -From dcf73f16faa51b4ff0fc25106e1b45f861ddd5b8 Mon Sep 17 00:00:00 2001 -From: Russell Joyce -Date: Wed, 1 May 2019 16:43:27 +0100 -Subject: [PATCH 483/703] configs: Enable netdev LED trigger - -Signed-off-by: Russell Joyce ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - arch/arm64/configs/bcmrpi3_defconfig | 1 + - 3 files changed, 3 insertions(+) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1143,6 +1143,7 @@ CONFIG_LEDS_TRIGGER_TRANSIENT=m - CONFIG_LEDS_TRIGGER_CAMERA=m - CONFIG_LEDS_TRIGGER_INPUT=y - CONFIG_LEDS_TRIGGER_PANIC=y -+CONFIG_LEDS_TRIGGER_NETDEV=m - CONFIG_RTC_CLASS=y - # CONFIG_RTC_HCTOSYS is not set - CONFIG_RTC_DRV_ABX80X=m ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1136,6 +1136,7 @@ CONFIG_LEDS_TRIGGER_TRANSIENT=m - CONFIG_LEDS_TRIGGER_CAMERA=m - CONFIG_LEDS_TRIGGER_INPUT=y - CONFIG_LEDS_TRIGGER_PANIC=y -+CONFIG_LEDS_TRIGGER_NETDEV=m - CONFIG_RTC_CLASS=y - # CONFIG_RTC_HCTOSYS is not set - CONFIG_RTC_DRV_ABX80X=m ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -1003,6 +1003,7 @@ CONFIG_LEDS_TRIGGER_TRANSIENT=m - CONFIG_LEDS_TRIGGER_CAMERA=m - CONFIG_LEDS_TRIGGER_INPUT=y - CONFIG_LEDS_TRIGGER_PANIC=y -+CONFIG_LEDS_TRIGGER_NETDEV=m - CONFIG_RTC_CLASS=y - # CONFIG_RTC_HCTOSYS is not set - CONFIG_RTC_DRV_ABX80X=m diff --git a/target/linux/brcm2708/patches-4.19/950-0483-staging-bcm2835-codec-Correct-port-width-calc-for-tr.patch b/target/linux/brcm2708/patches-4.19/950-0483-staging-bcm2835-codec-Correct-port-width-calc-for-tr.patch new file mode 100644 index 0000000000..8e13119378 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0483-staging-bcm2835-codec-Correct-port-width-calc-for-tr.patch @@ -0,0 +1,29 @@ +From 42b1168b921a0183da6754f43192f7090145feed Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 2 May 2019 14:30:24 +0100 +Subject: [PATCH 483/725] staging: bcm2835-codec: Correct port width calc for + truncation + +The calculation converting from V4L2 bytesperline to MMAL +width had an operator ordering issue that lead to Bayer raw 10 +(and 12 and 14) setting an incorrect stride for the buffer. +Correct this operation ordering issue. + +Signed-off-by: Dave Stevenson +--- + .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -605,8 +605,8 @@ static void setup_mmal_port_format(struc + + if (!(q_data->fmt->flags & V4L2_FMT_FLAG_COMPRESSED)) { + /* Raw image format - set width/height */ +- port->es.video.width = q_data->bytesperline / +- (q_data->fmt->depth >> 3); ++ port->es.video.width = (q_data->bytesperline << 3) / ++ q_data->fmt->depth; + port->es.video.height = q_data->height; + port->es.video.crop.width = q_data->crop_width; + port->es.video.crop.height = q_data->crop_height; diff --git a/target/linux/brcm2708/patches-4.19/950-0484-smsc95xx-dynamically-fix-up-TX-buffer-alignment-with.patch b/target/linux/brcm2708/patches-4.19/950-0484-smsc95xx-dynamically-fix-up-TX-buffer-alignment-with.patch deleted file mode 100644 index 5bb655967f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0484-smsc95xx-dynamically-fix-up-TX-buffer-alignment-with.patch +++ /dev/null @@ -1,62 +0,0 @@ -From e303bfb934b2a5adb549b43bbd51b1a0e33c33b3 Mon Sep 17 00:00:00 2001 -From: P33M -Date: Wed, 1 May 2019 17:04:32 +0100 -Subject: [PATCH 484/703] smsc95xx: dynamically fix up TX buffer alignment with - padding bytes - -dwc_otg requires a 32-bit aligned buffer start address, otherwise -expensive bounce buffers are used. The LAN951x hardware can skip up to -3 bytes between the TX header and the start of frame data, which can -be used to force alignment of the URB passed to dwc_otg. - -As found in https://github.com/raspberrypi/linux/issues/2924 ---- - drivers/net/usb/smsc95xx.c | 12 +++++++----- - drivers/net/usb/smsc95xx.h | 2 +- - 2 files changed, 8 insertions(+), 6 deletions(-) - ---- a/drivers/net/usb/smsc95xx.c -+++ b/drivers/net/usb/smsc95xx.c -@@ -2082,7 +2082,9 @@ static struct sk_buff *smsc95xx_tx_fixup - struct sk_buff *skb, gfp_t flags) - { - bool csum = skb->ip_summed == CHECKSUM_PARTIAL; -- int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM : SMSC95XX_TX_OVERHEAD; -+ unsigned int align_bytes = -((uintptr_t)skb->data) & 0x3; -+ int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM + align_bytes -+ : SMSC95XX_TX_OVERHEAD + align_bytes; - u32 tx_cmd_a, tx_cmd_b; - - /* We do not advertise SG, so skbs should be already linearized */ -@@ -2116,16 +2118,16 @@ static struct sk_buff *smsc95xx_tx_fixup - } - } - -- skb_push(skb, 4); -- tx_cmd_b = (u32)(skb->len - 4); -+ skb_push(skb, 4 + align_bytes); -+ tx_cmd_b = (u32)(skb->len - 4 - align_bytes); - if (csum) - tx_cmd_b |= TX_CMD_B_CSUM_ENABLE; - cpu_to_le32s(&tx_cmd_b); - memcpy(skb->data, &tx_cmd_b, 4); - - skb_push(skb, 4); -- tx_cmd_a = (u32)(skb->len - 8) | TX_CMD_A_FIRST_SEG_ | -- TX_CMD_A_LAST_SEG_; -+ tx_cmd_a = (u32)(skb->len - 8 - align_bytes) | TX_CMD_A_FIRST_SEG_ | -+ (align_bytes << 16) | TX_CMD_A_LAST_SEG_; - cpu_to_le32s(&tx_cmd_a); - memcpy(skb->data, &tx_cmd_a, 4); - ---- a/drivers/net/usb/smsc95xx.h -+++ b/drivers/net/usb/smsc95xx.h -@@ -21,7 +21,7 @@ - #define _SMSC95XX_H - - /* Tx command words */ --#define TX_CMD_A_DATA_OFFSET_ (0x001F0000) /* Data Start Offset */ -+#define TX_CMD_A_DATA_OFFSET_ (0x00030000) /* Data Start Offset */ - #define TX_CMD_A_FIRST_SEG_ (0x00002000) /* First Segment */ - #define TX_CMD_A_LAST_SEG_ (0x00001000) /* Last Segment */ - #define TX_CMD_A_BUF_SIZE_ (0x000007FF) /* Buffer Size */ diff --git a/target/linux/brcm2708/patches-4.19/950-0484-staging-bcm2835-codec-Remove-height-padding-for-ISP-.patch b/target/linux/brcm2708/patches-4.19/950-0484-staging-bcm2835-codec-Remove-height-padding-for-ISP-.patch new file mode 100644 index 0000000000..7948a3df99 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0484-staging-bcm2835-codec-Remove-height-padding-for-ISP-.patch @@ -0,0 +1,61 @@ +From 54f10f595339ee996e0ec0ac755b13a891f7ab92 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 2 May 2019 14:32:21 +0100 +Subject: [PATCH 484/725] staging: bcm2835-codec: Remove height padding for ISP + role + +The ISP has no need for heights to be a multiple of macroblock +sizes, therefore doesn't require the align on the height. +Remove it for the ISP role. (It is required for the codecs). + +Signed-off-by: Dave Stevenson +--- + .../bcm2835-codec/bcm2835-v4l2-codec.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -1015,7 +1015,8 @@ static int vidioc_g_fmt_vid_cap(struct f + return vidioc_g_fmt(file2ctx(file), f); + } + +-static int vidioc_try_fmt(struct v4l2_format *f, struct bcm2835_codec_fmt *fmt) ++static int vidioc_try_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f, ++ struct bcm2835_codec_fmt *fmt) + { + /* + * The V4L2 specification requires the driver to correct the format +@@ -1034,11 +1035,13 @@ static int vidioc_try_fmt(struct v4l2_fo + f->fmt.pix.height = MIN_H; + + /* +- * Buffer must have a vertical alignment of 16 lines. ++ * For codecs the buffer must have a vertical alignment of 16 ++ * lines. + * The selection will reflect any cropping rectangle when only + * some of the pixels are active. + */ +- f->fmt.pix.height = ALIGN(f->fmt.pix.height, 16); ++ if (ctx->dev->role != ISP) ++ f->fmt.pix.height = ALIGN(f->fmt.pix.height, 16); + } + f->fmt.pix.bytesperline = get_bytesperline(f->fmt.pix.width, + fmt); +@@ -1065,7 +1068,7 @@ static int vidioc_try_fmt_vid_cap(struct + fmt = find_format(f, ctx->dev, true); + } + +- return vidioc_try_fmt(f, fmt); ++ return vidioc_try_fmt(ctx, f, fmt); + } + + static int vidioc_try_fmt_vid_out(struct file *file, void *priv, +@@ -1084,7 +1087,7 @@ static int vidioc_try_fmt_vid_out(struct + if (!f->fmt.pix.colorspace) + f->fmt.pix.colorspace = ctx->colorspace; + +- return vidioc_try_fmt(f, fmt); ++ return vidioc_try_fmt(ctx, f, fmt); + } + + static int vidioc_s_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f, diff --git a/target/linux/brcm2708/patches-4.19/950-0485-lan78xx-use-default-alignment-for-rx-buffers.patch b/target/linux/brcm2708/patches-4.19/950-0485-lan78xx-use-default-alignment-for-rx-buffers.patch deleted file mode 100644 index e161945047..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0485-lan78xx-use-default-alignment-for-rx-buffers.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 877ede0851381694597771e1497ca7fc24cd23a6 Mon Sep 17 00:00:00 2001 -From: P33M -Date: Thu, 2 May 2019 11:53:45 +0100 -Subject: [PATCH 485/703] lan78xx: use default alignment for rx buffers - -The lan78xx uses a 12-byte hardware rx header, so there is no need -to allocate SKBs with NET_IP_ALIGN set. Removes alignment faults -in both dwc_otg and in ipv6 processing. ---- - drivers/net/usb/lan78xx.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/usb/lan78xx.c -+++ b/drivers/net/usb/lan78xx.c -@@ -3250,7 +3250,7 @@ static int rx_submit(struct lan78xx_net - size_t size = dev->rx_urb_size; - int ret = 0; - -- skb = netdev_alloc_skb_ip_align(dev->net, size); -+ skb = netdev_alloc_skb(dev->net, size); - if (!skb) { - usb_free_urb(urb); - return -ENOMEM; diff --git a/target/linux/brcm2708/patches-4.19/950-0485-staging-mmal-vchiq-Free-the-event-context-for-contro.patch b/target/linux/brcm2708/patches-4.19/950-0485-staging-mmal-vchiq-Free-the-event-context-for-contro.patch new file mode 100644 index 0000000000..e5c6214c89 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0485-staging-mmal-vchiq-Free-the-event-context-for-contro.patch @@ -0,0 +1,28 @@ +From 7b8bb1cd4c48b917888f80d22f789ad3896da20e Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 1 May 2019 13:27:23 +0100 +Subject: [PATCH 485/725] staging: mmal-vchiq: Free the event context for + control ports + +vchiq_mmal_component_init calls init_event_context for the +control port, but vchiq_mmal_component_finalise didn't free +it, causing a memory leak.. + +Add the free call. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +@@ -1982,6 +1982,8 @@ int vchiq_mmal_component_finalise(struct + for (idx = 0; idx < component->clocks; idx++) + free_event_context(&component->clock[idx]); + ++ free_event_context(&component->control); ++ + mutex_unlock(&instance->vchiq_mutex); + + return ret; diff --git a/target/linux/brcm2708/patches-4.19/950-0486-BCM270X_DT-Also-set-coherent_pool-1M-for-BT-Pis.patch b/target/linux/brcm2708/patches-4.19/950-0486-BCM270X_DT-Also-set-coherent_pool-1M-for-BT-Pis.patch new file mode 100644 index 0000000000..7e5d4bba7d --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0486-BCM270X_DT-Also-set-coherent_pool-1M-for-BT-Pis.patch @@ -0,0 +1,47 @@ +From 4c6084642e3682684dc10c6487c9aa4ae4a2651f Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 2 May 2019 22:14:34 +0100 +Subject: [PATCH 486/725] BCM270X_DT: Also set coherent_pool=1M for BT Pis + +See: https://github.com/raspberrypi/linux/issues/2924 + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/bcm2708-rpi-0-w.dts | 2 +- + arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 2 +- + arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/arm/boot/dts/bcm2708-rpi-0-w.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-0-w.dts +@@ -8,7 +8,7 @@ + model = "Raspberry Pi Zero W"; + + chosen { +- bootargs = "8250.nr_uarts=1"; ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1"; + }; + + aliases { +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts +@@ -9,7 +9,7 @@ + model = "Raspberry Pi 3 Model B+"; + + chosen { +- bootargs = "8250.nr_uarts=1"; ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1"; + }; + + aliases { +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +@@ -9,7 +9,7 @@ + model = "Raspberry Pi 3 Model B"; + + chosen { +- bootargs = "8250.nr_uarts=1"; ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1"; + }; + + aliases { diff --git a/target/linux/brcm2708/patches-4.19/950-0486-staging-bcm2835-codec-Correct-port-width-calc-for-tr.patch b/target/linux/brcm2708/patches-4.19/950-0486-staging-bcm2835-codec-Correct-port-width-calc-for-tr.patch deleted file mode 100644 index 29847b6002..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0486-staging-bcm2835-codec-Correct-port-width-calc-for-tr.patch +++ /dev/null @@ -1,29 +0,0 @@ -From f6e11e230a385a290e1a5890241f0ec4907f794c Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 2 May 2019 14:30:24 +0100 -Subject: [PATCH 486/703] staging: bcm2835-codec: Correct port width calc for - truncation - -The calculation converting from V4L2 bytesperline to MMAL -width had an operator ordering issue that lead to Bayer raw 10 -(and 12 and 14) setting an incorrect stride for the buffer. -Correct this operation ordering issue. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -605,8 +605,8 @@ static void setup_mmal_port_format(struc - - if (!(q_data->fmt->flags & V4L2_FMT_FLAG_COMPRESSED)) { - /* Raw image format - set width/height */ -- port->es.video.width = q_data->bytesperline / -- (q_data->fmt->depth >> 3); -+ port->es.video.width = (q_data->bytesperline << 3) / -+ q_data->fmt->depth; - port->es.video.height = q_data->height; - port->es.video.crop.width = q_data->crop_width; - port->es.video.crop.height = q_data->crop_height; diff --git a/target/linux/brcm2708/patches-4.19/950-0487-configs-Enable-ICS-43432-I2S-microphone-module.patch b/target/linux/brcm2708/patches-4.19/950-0487-configs-Enable-ICS-43432-I2S-microphone-module.patch new file mode 100644 index 0000000000..c59f345973 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0487-configs-Enable-ICS-43432-I2S-microphone-module.patch @@ -0,0 +1,42 @@ +From b8ed46bf8324dc44bf2e623e3ad78498fd7ae447 Mon Sep 17 00:00:00 2001 +From: Russell Joyce +Date: Thu, 2 May 2019 15:18:36 +0100 +Subject: [PATCH 487/725] configs: Enable ICS-43432 I2S microphone module + +Signed-off-by: Russell Joyce +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + arch/arm64/configs/bcmrpi3_defconfig | 1 + + 3 files changed, 3 insertions(+) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -943,6 +943,7 @@ CONFIG_SND_SOC_ADAU7002=m + CONFIG_SND_SOC_AK4554=m + CONFIG_SND_SOC_CS4265=m + CONFIG_SND_SOC_CS4271_I2C=m ++CONFIG_SND_SOC_ICS43432=m + CONFIG_SND_SOC_SPDIF=m + CONFIG_SND_SOC_WM8804_I2C=m + CONFIG_SND_SIMPLE_CARD=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -936,6 +936,7 @@ CONFIG_SND_SOC_ADAU7002=m + CONFIG_SND_SOC_AK4554=m + CONFIG_SND_SOC_CS4265=m + CONFIG_SND_SOC_CS4271_I2C=m ++CONFIG_SND_SOC_ICS43432=m + CONFIG_SND_SOC_SPDIF=m + CONFIG_SND_SOC_WM8804_I2C=m + CONFIG_SND_SIMPLE_CARD=m +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -822,6 +822,7 @@ CONFIG_SND_SOC_AD193X_I2C=m + CONFIG_SND_SOC_ADAU1701=m + CONFIG_SND_SOC_AK4554=m + CONFIG_SND_SOC_CS4271_I2C=m ++CONFIG_SND_SOC_ICS43432=m + CONFIG_SND_SOC_WM8804_I2C=m + CONFIG_SND_SIMPLE_CARD=m + CONFIG_HIDRAW=y diff --git a/target/linux/brcm2708/patches-4.19/950-0487-staging-bcm2835-codec-Remove-height-padding-for-ISP-.patch b/target/linux/brcm2708/patches-4.19/950-0487-staging-bcm2835-codec-Remove-height-padding-for-ISP-.patch deleted file mode 100644 index e0ab408a13..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0487-staging-bcm2835-codec-Remove-height-padding-for-ISP-.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 9b2ae5ee715a6dfc1d82b8ed0602a7221df6b641 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 2 May 2019 14:32:21 +0100 -Subject: [PATCH 487/703] staging: bcm2835-codec: Remove height padding for ISP - role - -The ISP has no need for heights to be a multiple of macroblock -sizes, therefore doesn't require the align on the height. -Remove it for the ISP role. (It is required for the codecs). - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 13 ++++++++----- - 1 file changed, 8 insertions(+), 5 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -1015,7 +1015,8 @@ static int vidioc_g_fmt_vid_cap(struct f - return vidioc_g_fmt(file2ctx(file), f); - } - --static int vidioc_try_fmt(struct v4l2_format *f, struct bcm2835_codec_fmt *fmt) -+static int vidioc_try_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f, -+ struct bcm2835_codec_fmt *fmt) - { - /* - * The V4L2 specification requires the driver to correct the format -@@ -1034,11 +1035,13 @@ static int vidioc_try_fmt(struct v4l2_fo - f->fmt.pix.height = MIN_H; - - /* -- * Buffer must have a vertical alignment of 16 lines. -+ * For codecs the buffer must have a vertical alignment of 16 -+ * lines. - * The selection will reflect any cropping rectangle when only - * some of the pixels are active. - */ -- f->fmt.pix.height = ALIGN(f->fmt.pix.height, 16); -+ if (ctx->dev->role != ISP) -+ f->fmt.pix.height = ALIGN(f->fmt.pix.height, 16); - } - f->fmt.pix.bytesperline = get_bytesperline(f->fmt.pix.width, - fmt); -@@ -1065,7 +1068,7 @@ static int vidioc_try_fmt_vid_cap(struct - fmt = find_format(f, ctx->dev, true); - } - -- return vidioc_try_fmt(f, fmt); -+ return vidioc_try_fmt(ctx, f, fmt); - } - - static int vidioc_try_fmt_vid_out(struct file *file, void *priv, -@@ -1084,7 +1087,7 @@ static int vidioc_try_fmt_vid_out(struct - if (!f->fmt.pix.colorspace) - f->fmt.pix.colorspace = ctx->colorspace; - -- return vidioc_try_fmt(f, fmt); -+ return vidioc_try_fmt(ctx, f, fmt); - } - - static int vidioc_s_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f, diff --git a/target/linux/brcm2708/patches-4.19/950-0488-arm-dts-overlays-rpi-sense-add-upstream-humidity-com.patch b/target/linux/brcm2708/patches-4.19/950-0488-arm-dts-overlays-rpi-sense-add-upstream-humidity-com.patch new file mode 100644 index 0000000000..821243b46e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0488-arm-dts-overlays-rpi-sense-add-upstream-humidity-com.patch @@ -0,0 +1,26 @@ +From 209b4058e447c11ce8db6b13123696db0cdd9c63 Mon Sep 17 00:00:00 2001 +From: Peter Robinson +Date: Sun, 5 May 2019 21:07:12 +0100 +Subject: [PATCH 488/725] arm: dts: overlays: rpi-sense: add upstream humidity + compatible + +The upstream humidiity driver uses "st,hts221" for the compatible +string so add that in as well so it will work with an unmodified +upstream kernel driver. We leave the downstream as the priority. + +Signed-off-by: Peter Robinson +--- + arch/arm/boot/dts/overlays/rpi-sense-overlay.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts ++++ b/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts +@@ -38,7 +38,7 @@ + }; + + hts221-humid@5f { +- compatible = "st,hts221-humid"; ++ compatible = "st,hts221-humid", "st,hts221"; + reg = <0x5f>; + status = "okay"; + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0488-staging-mmal-vchiq-Free-the-event-context-for-contro.patch b/target/linux/brcm2708/patches-4.19/950-0488-staging-mmal-vchiq-Free-the-event-context-for-contro.patch deleted file mode 100644 index e5489018ab..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0488-staging-mmal-vchiq-Free-the-event-context-for-contro.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 26f04aa97ca1c498f13e6c4dfea2e8ea436a9f83 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 1 May 2019 13:27:23 +0100 -Subject: [PATCH 488/703] staging: mmal-vchiq: Free the event context for - control ports - -vchiq_mmal_component_init calls init_event_context for the -control port, but vchiq_mmal_component_finalise didn't free -it, causing a memory leak.. - -Add the free call. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -1982,6 +1982,8 @@ int vchiq_mmal_component_finalise(struct - for (idx = 0; idx < component->clocks; idx++) - free_event_context(&component->clock[idx]); - -+ free_event_context(&component->control); -+ - mutex_unlock(&instance->vchiq_mutex); - - return ret; diff --git a/target/linux/brcm2708/patches-4.19/950-0489-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch b/target/linux/brcm2708/patches-4.19/950-0489-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch new file mode 100644 index 0000000000..3f86517f04 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0489-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch @@ -0,0 +1,67 @@ +From f538653f1307d7b3b2ebfbdef90dc18f23cc4863 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 2 May 2019 15:50:01 +0100 +Subject: [PATCH 489/725] staging: mmal-vchiq: Fix memory leak in error path + +On error, vchiq_mmal_component_init could leave the +event context allocated for ports. +Clean them up in the error path. + +Signed-off-by: Dave Stevenson +--- + .../vc04_services/vchiq-mmal/mmal-vchiq.c | 27 +++++++++++++------ + 1 file changed, 19 insertions(+), 8 deletions(-) + +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +@@ -1848,9 +1848,26 @@ static void free_event_context(struct vc + { + struct mmal_msg_context *ctx = port->event_context; + ++ if (!ctx) ++ return; ++ + kfree(ctx->u.bulk.buffer->buffer); + kfree(ctx->u.bulk.buffer); + release_msg_context(ctx); ++ port->event_context = NULL; ++} ++ ++static void release_all_event_contexts(struct vchiq_mmal_component *component) ++{ ++ int idx; ++ ++ for (idx = 0; idx < component->inputs; idx++) ++ free_event_context(&component->input[idx]); ++ for (idx = 0; idx < component->outputs; idx++) ++ free_event_context(&component->output[idx]); ++ for (idx = 0; idx < component->clocks; idx++) ++ free_event_context(&component->clock[idx]); ++ free_event_context(&component->control); + } + + /* Initialise a mmal component and its ports +@@ -1948,6 +1965,7 @@ int vchiq_mmal_component_init(struct vch + + release_component: + destroy_component(instance, component); ++ release_all_event_contexts(component); + unlock: + if (component) + component->in_use = 0; +@@ -1975,14 +1993,7 @@ int vchiq_mmal_component_finalise(struct + + component->in_use = 0; + +- for (idx = 0; idx < component->inputs; idx++) +- free_event_context(&component->input[idx]); +- for (idx = 0; idx < component->outputs; idx++) +- free_event_context(&component->output[idx]); +- for (idx = 0; idx < component->clocks; idx++) +- free_event_context(&component->clock[idx]); +- +- free_event_context(&component->control); ++ release_all_event_contexts(component); + + mutex_unlock(&instance->vchiq_mutex); + diff --git a/target/linux/brcm2708/patches-4.19/950-0490-BCM270X_DT-Also-set-coherent_pool-1M-for-BT-Pis.patch b/target/linux/brcm2708/patches-4.19/950-0490-BCM270X_DT-Also-set-coherent_pool-1M-for-BT-Pis.patch deleted file mode 100644 index 6a08a3a88a..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0490-BCM270X_DT-Also-set-coherent_pool-1M-for-BT-Pis.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0e6d5495da81b0f441a8e59156213907b170b085 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 2 May 2019 22:14:34 +0100 -Subject: [PATCH 490/703] BCM270X_DT: Also set coherent_pool=1M for BT Pis - -See: https://github.com/raspberrypi/linux/issues/2924 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2708-rpi-0-w.dts | 2 +- - arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 2 +- - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - ---- a/arch/arm/boot/dts/bcm2708-rpi-0-w.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-0-w.dts -@@ -8,7 +8,7 @@ - model = "Raspberry Pi Zero W"; - - chosen { -- bootargs = "8250.nr_uarts=1"; -+ bootargs = "coherent_pool=1M 8250.nr_uarts=1"; - }; - - aliases { ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts -@@ -9,7 +9,7 @@ - model = "Raspberry Pi 3 Model B+"; - - chosen { -- bootargs = "8250.nr_uarts=1"; -+ bootargs = "coherent_pool=1M 8250.nr_uarts=1"; - }; - - aliases { ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -9,7 +9,7 @@ - model = "Raspberry Pi 3 Model B"; - - chosen { -- bootargs = "8250.nr_uarts=1"; -+ bootargs = "coherent_pool=1M 8250.nr_uarts=1"; - }; - - aliases { diff --git a/target/linux/brcm2708/patches-4.19/950-0490-staging-vchiq-mmal-Fix-memory-leak-of-vchiq-instance.patch b/target/linux/brcm2708/patches-4.19/950-0490-staging-vchiq-mmal-Fix-memory-leak-of-vchiq-instance.patch new file mode 100644 index 0000000000..72958a8106 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0490-staging-vchiq-mmal-Fix-memory-leak-of-vchiq-instance.patch @@ -0,0 +1,62 @@ +From d9725f9881c55fdb8727301e45ce6b200c1d7633 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 3 May 2019 13:27:51 +0100 +Subject: [PATCH 490/725] staging: vchiq-mmal: Fix memory leak of vchiq + instance + +The vchiq instance was allocated from vchiq_mmal_init via +vchi_initialise, but was never released with vchi_disconnect. + +Retain the handle and release it from vchiq_mmal_finalise. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +@@ -176,6 +176,7 @@ struct mmal_msg_context { + }; + + struct vchiq_mmal_instance { ++ VCHI_INSTANCE_T vchi_instance; + VCHI_SERVICE_HANDLE_T handle; + + /* ensure serialised access to service */ +@@ -1981,7 +1982,7 @@ EXPORT_SYMBOL_GPL(vchiq_mmal_component_i + int vchiq_mmal_component_finalise(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_component *component) + { +- int ret, idx; ++ int ret; + + if (mutex_lock_interruptible(&instance->vchiq_mutex)) + return -EINTR; +@@ -2094,6 +2095,8 @@ int vchiq_mmal_finalise(struct vchiq_mma + + idr_destroy(&instance->context_map); + ++ vchi_disconnect(instance->vchi_instance); ++ + kfree(instance); + + return status; +@@ -2105,7 +2108,7 @@ int vchiq_mmal_init(struct vchiq_mmal_in + int status; + struct vchiq_mmal_instance *instance; + static VCHI_CONNECTION_T *vchi_connection; +- static VCHI_INSTANCE_T vchi_instance; ++ VCHI_INSTANCE_T vchi_instance; + SERVICE_CREATION_T params = { + .version = VCHI_VERSION_EX(VC_MMAL_VER, VC_MMAL_MIN_VER), + .service_id = VC_MMAL_SERVER_NAME, +@@ -2151,6 +2154,8 @@ int vchiq_mmal_init(struct vchiq_mmal_in + if (!instance) + return -ENOMEM; + ++ instance->vchi_instance = vchi_instance; ++ + mutex_init(&instance->vchiq_mutex); + + instance->bulk_scratch = vmalloc(PAGE_SIZE); diff --git a/target/linux/brcm2708/patches-4.19/950-0491-Revert-video-bcm2708_fb-Try-allocating-on-the-ARM-an.patch b/target/linux/brcm2708/patches-4.19/950-0491-Revert-video-bcm2708_fb-Try-allocating-on-the-ARM-an.patch new file mode 100644 index 0000000000..c4fb2141ba --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0491-Revert-video-bcm2708_fb-Try-allocating-on-the-ARM-an.patch @@ -0,0 +1,164 @@ +From 0c9e8983c1ab986a833e8b5fbe180f06957529ad Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 13 May 2019 17:34:29 +0100 +Subject: [PATCH 491/725] Revert "video: bcm2708_fb: Try allocating on the ARM + and passing to VPU" + +This reverts commit ca36c709fce57e8023d2b8b354376bf161601a49. + +The driver tries a cma_alloc to avoid using gpu_mem, but should +that fail the core code is logging an error with no easy way to +test whether it will succeed or fail first. + +Revert until we either totally give up on gpu_mem and increase +CMA always, or find a way to try an allocation. + +Signed-off-by: Dave Stevenson +--- + drivers/video/fbdev/bcm2708_fb.c | 102 +++------------------ + include/soc/bcm2835/raspberrypi-firmware.h | 1 - + 2 files changed, 12 insertions(+), 91 deletions(-) + +--- a/drivers/video/fbdev/bcm2708_fb.c ++++ b/drivers/video/fbdev/bcm2708_fb.c +@@ -98,11 +98,6 @@ struct bcm2708_fb { + struct bcm2708_fb_stats stats; + unsigned long fb_bus_address; + struct { u32 base, length; } gpu; +- +- bool disable_arm_alloc; +- unsigned int image_size; +- dma_addr_t dma_addr; +- void *cpuaddr; + }; + + #define to_bcm2708(info) container_of(info, struct bcm2708_fb, fb) +@@ -288,88 +283,23 @@ static int bcm2708_fb_set_par(struct fb_ + .xoffset = info->var.xoffset, + .yoffset = info->var.yoffset, + .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 }, +- /* base and screen_size will be initialised later */ +- .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH, 4, 0 }, +- /* pitch will be initialised later */ ++ .base = 0, ++ .screen_size = 0, ++ .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH, 4, 0 }, ++ .pitch = 0, + }; +- int ret, image_size; +- ++ int ret; + + print_debug("%s(%p) %dx%d (%dx%d), %d, %d\n", __func__, info, + info->var.xres, info->var.yres, info->var.xres_virtual, + info->var.yres_virtual, (int)info->screen_size, + info->var.bits_per_pixel); + +- /* Try allocating our own buffer. We can specify all the parameters */ +- image_size = ((info->var.xres * info->var.yres) * +- info->var.bits_per_pixel) >> 3; +- +- if (!fb->disable_arm_alloc && +- (image_size != fb->image_size || !fb->dma_addr)) { +- if (fb->dma_addr) { +- dma_free_coherent(info->device, fb->image_size, +- fb->cpuaddr, fb->dma_addr); +- fb->image_size = 0; +- fb->cpuaddr = NULL; +- fb->dma_addr = 0; +- } +- +- fb->cpuaddr = dma_alloc_coherent(info->device, image_size, +- &fb->dma_addr, GFP_KERNEL); +- +- if (!fb->cpuaddr) { +- fb->dma_addr = 0; +- fb->disable_arm_alloc = true; +- } else { +- fb->image_size = image_size; +- } +- } +- +- if (fb->cpuaddr) { +- fbinfo.base = fb->dma_addr; +- fbinfo.screen_size = image_size; +- fbinfo.pitch = (info->var.xres * info->var.bits_per_pixel) >> 3; +- +- ret = rpi_firmware_property_list(fb->fw, &fbinfo, +- sizeof(fbinfo)); +- if (ret || fbinfo.base != fb->dma_addr) { +- /* Firmware either failed, or assigned a different base +- * address (ie it doesn't support being passed an FB +- * allocation). +- * Destroy the allocation, and don't try again. +- */ +- dma_free_coherent(info->device, fb->image_size, +- fb->cpuaddr, fb->dma_addr); +- fb->image_size = 0; +- fb->cpuaddr = NULL; +- fb->dma_addr = 0; +- fb->disable_arm_alloc = true; +- } +- } else { +- /* Our allocation failed - drop into the old scheme of +- * allocation by the VPU. +- */ +- ret = -ENOMEM; +- } +- ++ ret = rpi_firmware_property_list(fb->fw, &fbinfo, sizeof(fbinfo)); + if (ret) { +- /* Old scheme: +- * - FRAMEBUFFER_ALLOCATE passes 0 for base and screen_size. +- * - GET_PITCH instead of SET_PITCH. +- */ +- fbinfo.base = 0; +- fbinfo.screen_size = 0; +- fbinfo.tag6.tag = RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH; +- fbinfo.pitch = 0; +- +- ret = rpi_firmware_property_list(fb->fw, &fbinfo, +- sizeof(fbinfo)); +- if (ret) { +- dev_err(info->device, +- "Failed to allocate GPU framebuffer (%d)\n", +- ret); +- return ret; +- } ++ dev_err(info->device, ++ "Failed to allocate GPU framebuffer (%d)\n", ret); ++ return ret; + } + + if (info->var.bits_per_pixel <= 8) +@@ -384,17 +314,9 @@ static int bcm2708_fb_set_par(struct fb_ + fb->fb.fix.smem_start = fbinfo.base; + fb->fb.fix.smem_len = fbinfo.pitch * fbinfo.yres_virtual; + fb->fb.screen_size = fbinfo.screen_size; +- +- if (!fb->dma_addr) { +- if (fb->fb.screen_base) +- iounmap(fb->fb.screen_base); +- +- fb->fb.screen_base = ioremap_wc(fbinfo.base, +- fb->fb.screen_size); +- } else { +- fb->fb.screen_base = fb->cpuaddr; +- } +- ++ if (fb->fb.screen_base) ++ iounmap(fb->fb.screen_base); ++ fb->fb.screen_base = ioremap_wc(fbinfo.base, fb->fb.screen_size); + if (!fb->fb.screen_base) { + /* the console may currently be locked */ + console_trylock(); +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -128,7 +128,6 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, + RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER = 0x00048006, + RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE = 0x00048007, +- RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH = 0x00048008, + RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, + RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, + RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, diff --git a/target/linux/brcm2708/patches-4.19/950-0491-configs-Enable-ICS-43432-I2S-microphone-module.patch b/target/linux/brcm2708/patches-4.19/950-0491-configs-Enable-ICS-43432-I2S-microphone-module.patch deleted file mode 100644 index a135c529a0..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0491-configs-Enable-ICS-43432-I2S-microphone-module.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 9618e38d927290bf174936756face014a37a93e6 Mon Sep 17 00:00:00 2001 -From: Russell Joyce -Date: Thu, 2 May 2019 15:18:36 +0100 -Subject: [PATCH 491/703] configs: Enable ICS-43432 I2S microphone module - -Signed-off-by: Russell Joyce ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - arch/arm64/configs/bcmrpi3_defconfig | 1 + - 3 files changed, 3 insertions(+) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -943,6 +943,7 @@ CONFIG_SND_SOC_ADAU7002=m - CONFIG_SND_SOC_AK4554=m - CONFIG_SND_SOC_CS4265=m - CONFIG_SND_SOC_CS4271_I2C=m -+CONFIG_SND_SOC_ICS43432=m - CONFIG_SND_SOC_SPDIF=m - CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -936,6 +936,7 @@ CONFIG_SND_SOC_ADAU7002=m - CONFIG_SND_SOC_AK4554=m - CONFIG_SND_SOC_CS4265=m - CONFIG_SND_SOC_CS4271_I2C=m -+CONFIG_SND_SOC_ICS43432=m - CONFIG_SND_SOC_SPDIF=m - CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -822,6 +822,7 @@ CONFIG_SND_SOC_AD193X_I2C=m - CONFIG_SND_SOC_ADAU1701=m - CONFIG_SND_SOC_AK4554=m - CONFIG_SND_SOC_CS4271_I2C=m -+CONFIG_SND_SOC_ICS43432=m - CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m - CONFIG_HIDRAW=y diff --git a/target/linux/brcm2708/patches-4.19/950-0492-Added-IQaudIO-Pi-Codec-board-support-2969.patch b/target/linux/brcm2708/patches-4.19/950-0492-Added-IQaudIO-Pi-Codec-board-support-2969.patch new file mode 100644 index 0000000000..3d99634b38 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0492-Added-IQaudIO-Pi-Codec-board-support-2969.patch @@ -0,0 +1,409 @@ +From f1735eca66ab19d14c3f77c0869d7378897aa13c Mon Sep 17 00:00:00 2001 +From: IQaudIO +Date: Mon, 13 May 2019 21:53:05 +0100 +Subject: [PATCH 492/725] Added IQaudIO Pi-Codec board support (#2969) + +Add support for the IQaudIO Pi-Codec board. + +Signed-off-by: Gordon +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 6 + + .../dts/overlays/iqaudio-codec-overlay.dts | 42 +++ + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + arch/arm64/configs/bcmrpi3_defconfig | 1 + + sound/soc/bcm/Kconfig | 7 + + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/iqaudio-codec.c | 250 ++++++++++++++++++ + 9 files changed, 311 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/iqaudio-codec-overlay.dts + create mode 100644 sound/soc/bcm/iqaudio-codec.c + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -68,6 +68,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + i2c1-bcm2708.dtbo \ + i2s-gpio28-31.dtbo \ + ilitek251x.dtbo \ ++ iqaudio-codec.dtbo \ + iqaudio-dac.dtbo \ + iqaudio-dacplus.dtbo \ + iqaudio-digi-wm8804-audio.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1160,6 +1160,12 @@ Params: interrupt GPIO use + touchscreen (in pixels) + + ++Name: iqaudio-codec ++Info: Configures the IQaudio Codec audio card ++Load: dtoverlay=iqaudio-codec ++Params: ++ ++ + Name: iqaudio-dac + Info: Configures the IQaudio DAC audio card + Load: dtoverlay=iqaudio-dac, +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/iqaudio-codec-overlay.dts +@@ -0,0 +1,42 @@ ++// Definitions for IQaudIO CODEC ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ da2713@1a { ++ #sound-dai-cells = <0>; ++ compatible = "dlg,da7213"; ++ reg = <0x1a>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&sound>; ++ iqaudio_dac: __overlay__ { ++ compatible = "iqaudio,iqaudio-codec"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ }; ++}; +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -919,6 +919,7 @@ CONFIG_SND_BCM2708_SOC_RPI_DAC=m + CONFIG_SND_BCM2708_SOC_RPI_PROTO=m + CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m + CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m ++CONFIG_SND_BCM2708_SOC_IQAUDIO_CODEC=m + CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m + CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m + CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -912,6 +912,7 @@ CONFIG_SND_BCM2708_SOC_RPI_DAC=m + CONFIG_SND_BCM2708_SOC_RPI_PROTO=m + CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m + CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m ++CONFIG_SND_BCM2708_SOC_IQAUDIO_CODEC=m + CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m + CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m + CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -807,6 +807,7 @@ CONFIG_SND_BCM2708_SOC_RPI_DAC=m + CONFIG_SND_BCM2708_SOC_RPI_PROTO=m + CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m + CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m ++CONFIG_SND_BCM2708_SOC_IQAUDIO_CODEC=m + CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m + CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m + CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -108,6 +108,13 @@ config SND_BCM2708_SOC_JUSTBOOM_DIGI + help + Say Y or M if you want to add support for JustBoom Digi. + ++config SND_BCM2708_SOC_IQAUDIO_CODEC ++ tristate "Support for IQaudIO-CODEC" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_DA7213 ++ help ++ Say Y or M if you want to add support for IQaudIO-CODEC. ++ + config SND_BCM2708_SOC_IQAUDIO_DAC + tristate "Support for IQaudIO-DAC" + 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-hifiberry-dacplusadc-objs := hif + snd-soc-justboom-dac-objs := justboom-dac.o + snd-soc-rpi-cirrus-objs := rpi-cirrus.o + snd-soc-rpi-proto-objs := rpi-proto.o ++snd-soc-iqaudio-codec-objs := iqaudio-codec.o + snd-soc-iqaudio-dac-objs := iqaudio-dac.o + snd-soc-i-sabre-q2m-objs := i-sabre-q2m.o + snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o +@@ -42,6 +43,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_D + obj-$(CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC) += snd-soc-justboom-dac.o + obj-$(CONFIG_SND_BCM2708_SOC_RPI_CIRRUS) += snd-soc-rpi-cirrus.o + obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o ++obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_CODEC) += snd-soc-iqaudio-codec.o + obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o + obj-$(CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M) += snd-soc-i-sabre-q2m.o + obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o +--- /dev/null ++++ b/sound/soc/bcm/iqaudio-codec.c +@@ -0,0 +1,250 @@ ++/* ++ * ASoC Driver for IQaudIO Raspberry Pi Codec board ++ * ++ * Author: Gordon Garrity ++ * (C) Copyright IQaudio Limited, 2017-2019 ++ * ++ * 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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include "../codecs/da7213.h" ++ ++static int pll_out = DA7213_PLL_FREQ_OUT_90316800; ++ ++static int snd_rpi_iqaudio_pll_control(struct snd_soc_dapm_widget *w, ++ struct snd_kcontrol *k, int event) ++{ ++ int ret = 0; ++ struct snd_soc_dapm_context *dapm = w->dapm; ++ struct snd_soc_card *card = dapm->card; ++ struct snd_soc_pcm_runtime *rtd = ++ snd_soc_get_pcm_runtime(card, card->dai_link[0].name); ++ struct snd_soc_dai *codec_dai = rtd->codec_dai; ++ ++ if (SND_SOC_DAPM_EVENT_OFF(event)) { ++ ret = snd_soc_dai_set_pll(codec_dai, 0, DA7213_SYSCLK_MCLK, 0, ++ 0); ++ if (ret) ++ dev_err(card->dev, "Failed to bypass PLL: %d\n", ret); ++ } else if (SND_SOC_DAPM_EVENT_ON(event)) { ++ ret = snd_soc_dai_set_pll(codec_dai, 0, DA7213_SYSCLK_PLL, 0, ++ pll_out); ++ if (ret) ++ dev_err(card->dev, "Failed to enable PLL: %d\n", ret); ++ } ++ ++ return ret; ++} ++ ++static int snd_rpi_iqaudio_post_dapm_event(struct snd_soc_dapm_widget *w, ++ struct snd_kcontrol *kcontrol, ++ int event) ++{ ++ switch (event) { ++ case SND_SOC_DAPM_POST_PMU: ++ /* Delay for mic bias ramp */ ++ msleep(1000); ++ break; ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++static const struct snd_soc_dapm_widget dapm_widgets[] = { ++ SND_SOC_DAPM_HP("HP Jack", NULL), ++ SND_SOC_DAPM_MIC("MIC Jack", NULL), ++ SND_SOC_DAPM_MIC("Onboard MIC", NULL), ++ SND_SOC_DAPM_LINE("AUX Jack", NULL), ++ SND_SOC_DAPM_SUPPLY("PLL Control", SND_SOC_NOPM, 0, 0, ++ snd_rpi_iqaudio_pll_control, ++ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), ++ SND_SOC_DAPM_POST("Post Power Up Event", snd_rpi_iqaudio_post_dapm_event), ++}; ++ ++static const struct snd_soc_dapm_route audio_map[] = { ++ {"HP Jack", NULL, "HPL"}, ++ {"HP Jack", NULL, "HPR"}, ++ {"HP Jack", NULL, "PLL Control"}, ++ ++ {"AUX Jack", NULL, "AUXR"}, ++ {"AUX Jack", NULL, "AUXL"}, ++ {"AUX Jack", NULL, "PLL Control"}, ++ ++ /* Assume Mic1 is linked to Headset and Mic2 to on-board mic */ ++ {"MIC Jack", NULL, "MIC1"}, ++ {"MIC Jack", NULL, "PLL Control"}, ++ {"Onboard MIC", NULL, "MIC2"}, ++ {"Onboard MIC", NULL, "PLL Control"}, ++}; ++ ++/* machine stream operations */ ++ ++static int snd_rpi_iqaudio_codec_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ struct snd_soc_dai *codec_dai = rtd->codec_dai; ++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; ++ int ret; ++ ++ /* Set bclk ratio to align with codec's BCLK rate */ ++ ret = snd_soc_dai_set_bclk_ratio(cpu_dai, 64); ++ if (ret) { ++ dev_err(rtd->dev, "Failed to set CPU BLCK ratio\n"); ++ return ret; ++ } ++ ++ /* Set MCLK frequency to codec, onboard 11.2896MHz clock */ ++ return snd_soc_dai_set_sysclk(codec_dai, DA7213_CLKSRC_MCLK, 11289600, ++ SND_SOC_CLOCK_OUT); ++} ++ ++static int snd_rpi_iqaudio_codec_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ unsigned int samplerate = params_rate(params); ++ ++ switch (samplerate) { ++ case 8000: ++ case 16000: ++ case 32000: ++ case 48000: ++ case 96000: ++ pll_out = DA7213_PLL_FREQ_OUT_98304000; ++ return 0; ++ case 44100: ++ case 88200: ++ pll_out = DA7213_PLL_FREQ_OUT_90316800; ++ return 0; ++ default: ++ dev_err(rtd->dev,"Unsupported samplerate %d\n", samplerate); ++ return -EINVAL; ++ } ++} ++ ++static const struct snd_soc_ops snd_rpi_iqaudio_codec_ops = { ++ .hw_params = snd_rpi_iqaudio_codec_hw_params, ++}; ++ ++ ++static struct snd_soc_dai_link snd_rpi_iqaudio_codec_dai[] = { ++{ ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "da7213-hifi", ++ .platform_name = "bmc2708-i2s.0", ++ .codec_name = "da7213.1-001a", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBM_CFM, ++ .init = snd_rpi_iqaudio_codec_init, ++ .ops = &snd_rpi_iqaudio_codec_ops, ++ .symmetric_rates = 1, ++ .symmetric_channels = 1, ++ .symmetric_samplebits = 1, ++}, ++}; ++ ++/* audio machine driver */ ++static struct snd_soc_card snd_rpi_iqaudio_codec = { ++ .owner = THIS_MODULE, ++ .dai_link = snd_rpi_iqaudio_codec_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_iqaudio_codec_dai), ++ .dapm_widgets = dapm_widgets, ++ .num_dapm_widgets = ARRAY_SIZE(dapm_widgets), ++ .dapm_routes = audio_map, ++ .num_dapm_routes = ARRAY_SIZE(audio_map), ++}; ++ ++static int snd_rpi_iqaudio_codec_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ snd_rpi_iqaudio_codec.dev = &pdev->dev; ++ ++ if (pdev->dev.of_node) { ++ struct device_node *i2s_node; ++ struct snd_soc_card *card = &snd_rpi_iqaudio_codec; ++ struct snd_soc_dai_link *dai = &snd_rpi_iqaudio_codec_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; ++ } ++ ++ if (of_property_read_string(pdev->dev.of_node, "card_name", ++ &card->name)) ++ card->name = "IQaudIOCODEC"; ++ ++ if (of_property_read_string(pdev->dev.of_node, "dai_name", ++ &dai->name)) ++ dai->name = "IQaudIO CODEC"; ++ ++ if (of_property_read_string(pdev->dev.of_node, ++ "dai_stream_name", &dai->stream_name)) ++ dai->stream_name = "IQaudIO CODEC HiFi v1.1"; ++ ++ } ++ ++ ret = snd_soc_register_card(&snd_rpi_iqaudio_codec); ++ if (ret) { ++ if (ret != -EPROBE_DEFER) ++ dev_err(&pdev->dev, ++ "snd_soc_register_card() failed: %d\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int snd_rpi_iqaudio_codec_remove(struct platform_device *pdev) ++{ ++ return snd_soc_unregister_card(&snd_rpi_iqaudio_codec); ++} ++ ++static const struct of_device_id iqaudio_of_match[] = { ++ { .compatible = "iqaudio,iqaudio-codec", }, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, iqaudio_of_match); ++ ++static struct platform_driver snd_rpi_iqaudio_codec_driver = { ++ .driver = { ++ .name = "snd-rpi-iqaudio-codec", ++ .owner = THIS_MODULE, ++ .of_match_table = iqaudio_of_match, ++ }, ++ .probe = snd_rpi_iqaudio_codec_probe, ++ .remove = snd_rpi_iqaudio_codec_remove, ++}; ++ ++ ++ ++module_platform_driver(snd_rpi_iqaudio_codec_driver); ++ ++MODULE_AUTHOR("Gordon Garrity "); ++MODULE_DESCRIPTION("ASoC Driver for IQaudIO CODEC"); ++MODULE_LICENSE("GPL v2"); diff --git a/target/linux/brcm2708/patches-4.19/950-0492-arm-dts-overlays-rpi-sense-add-upstream-humidity-com.patch b/target/linux/brcm2708/patches-4.19/950-0492-arm-dts-overlays-rpi-sense-add-upstream-humidity-com.patch deleted file mode 100644 index 8603b29eb4..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0492-arm-dts-overlays-rpi-sense-add-upstream-humidity-com.patch +++ /dev/null @@ -1,26 +0,0 @@ -From cecb1267b1b51025c6e54bb4ba05c84ff6e7e3c7 Mon Sep 17 00:00:00 2001 -From: Peter Robinson -Date: Sun, 5 May 2019 21:07:12 +0100 -Subject: [PATCH 492/703] arm: dts: overlays: rpi-sense: add upstream humidity - compatible - -The upstream humidiity driver uses "st,hts221" for the compatible -string so add that in as well so it will work with an unmodified -upstream kernel driver. We leave the downstream as the priority. - -Signed-off-by: Peter Robinson ---- - arch/arm/boot/dts/overlays/rpi-sense-overlay.dts | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts -@@ -38,7 +38,7 @@ - }; - - hts221-humid@5f { -- compatible = "st,hts221-humid"; -+ compatible = "st,hts221-humid", "st,hts221"; - reg = <0x5f>; - status = "okay"; - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0493-Revert-smsc95xx-dynamically-fix-up-TX-buffer-alignme.patch b/target/linux/brcm2708/patches-4.19/950-0493-Revert-smsc95xx-dynamically-fix-up-TX-buffer-alignme.patch new file mode 100644 index 0000000000..30e3592a4f --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0493-Revert-smsc95xx-dynamically-fix-up-TX-buffer-alignme.patch @@ -0,0 +1,60 @@ +From ac011573006f07da4a140f05e1ee8be0c441f3dc Mon Sep 17 00:00:00 2001 +From: P33M +Date: Tue, 14 May 2019 14:55:19 +0100 +Subject: [PATCH 493/725] Revert "smsc95xx: dynamically fix up TX buffer + alignment with padding bytes" + +As reported in https://github.com/raspberrypi/linux/issues/2964 this +commit causes a regression corrupting non-option TCP ack packets. + +This reverts commit 96b972dc736d943f371a16ccca452a053d83c65b. +--- + drivers/net/usb/smsc95xx.c | 12 +++++------- + drivers/net/usb/smsc95xx.h | 2 +- + 2 files changed, 6 insertions(+), 8 deletions(-) + +--- a/drivers/net/usb/smsc95xx.c ++++ b/drivers/net/usb/smsc95xx.c +@@ -2082,9 +2082,7 @@ static struct sk_buff *smsc95xx_tx_fixup + struct sk_buff *skb, gfp_t flags) + { + bool csum = skb->ip_summed == CHECKSUM_PARTIAL; +- unsigned int align_bytes = -((uintptr_t)skb->data) & 0x3; +- int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM + align_bytes +- : SMSC95XX_TX_OVERHEAD + align_bytes; ++ int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM : SMSC95XX_TX_OVERHEAD; + u32 tx_cmd_a, tx_cmd_b; + + /* We do not advertise SG, so skbs should be already linearized */ +@@ -2118,16 +2116,16 @@ static struct sk_buff *smsc95xx_tx_fixup + } + } + +- skb_push(skb, 4 + align_bytes); +- tx_cmd_b = (u32)(skb->len - 4 - align_bytes); ++ skb_push(skb, 4); ++ tx_cmd_b = (u32)(skb->len - 4); + if (csum) + tx_cmd_b |= TX_CMD_B_CSUM_ENABLE; + cpu_to_le32s(&tx_cmd_b); + memcpy(skb->data, &tx_cmd_b, 4); + + skb_push(skb, 4); +- tx_cmd_a = (u32)(skb->len - 8 - align_bytes) | TX_CMD_A_FIRST_SEG_ | +- (align_bytes << 16) | TX_CMD_A_LAST_SEG_; ++ tx_cmd_a = (u32)(skb->len - 8) | TX_CMD_A_FIRST_SEG_ | ++ TX_CMD_A_LAST_SEG_; + cpu_to_le32s(&tx_cmd_a); + memcpy(skb->data, &tx_cmd_a, 4); + +--- a/drivers/net/usb/smsc95xx.h ++++ b/drivers/net/usb/smsc95xx.h +@@ -21,7 +21,7 @@ + #define _SMSC95XX_H + + /* Tx command words */ +-#define TX_CMD_A_DATA_OFFSET_ (0x00030000) /* Data Start Offset */ ++#define TX_CMD_A_DATA_OFFSET_ (0x001F0000) /* Data Start Offset */ + #define TX_CMD_A_FIRST_SEG_ (0x00002000) /* First Segment */ + #define TX_CMD_A_LAST_SEG_ (0x00001000) /* Last Segment */ + #define TX_CMD_A_BUF_SIZE_ (0x000007FF) /* Buffer Size */ diff --git a/target/linux/brcm2708/patches-4.19/950-0493-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch b/target/linux/brcm2708/patches-4.19/950-0493-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch deleted file mode 100644 index c74fb93902..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0493-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch +++ /dev/null @@ -1,67 +0,0 @@ -From af1d0b04a35776cf36049b1549fcb33260a4e145 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 2 May 2019 15:50:01 +0100 -Subject: [PATCH 493/703] staging: mmal-vchiq: Fix memory leak in error path - -On error, vchiq_mmal_component_init could leave the -event context allocated for ports. -Clean them up in the error path. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/vchiq-mmal/mmal-vchiq.c | 27 +++++++++++++------ - 1 file changed, 19 insertions(+), 8 deletions(-) - ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -1848,9 +1848,26 @@ static void free_event_context(struct vc - { - struct mmal_msg_context *ctx = port->event_context; - -+ if (!ctx) -+ return; -+ - kfree(ctx->u.bulk.buffer->buffer); - kfree(ctx->u.bulk.buffer); - release_msg_context(ctx); -+ port->event_context = NULL; -+} -+ -+static void release_all_event_contexts(struct vchiq_mmal_component *component) -+{ -+ int idx; -+ -+ for (idx = 0; idx < component->inputs; idx++) -+ free_event_context(&component->input[idx]); -+ for (idx = 0; idx < component->outputs; idx++) -+ free_event_context(&component->output[idx]); -+ for (idx = 0; idx < component->clocks; idx++) -+ free_event_context(&component->clock[idx]); -+ free_event_context(&component->control); - } - - /* Initialise a mmal component and its ports -@@ -1948,6 +1965,7 @@ int vchiq_mmal_component_init(struct vch - - release_component: - destroy_component(instance, component); -+ release_all_event_contexts(component); - unlock: - if (component) - component->in_use = 0; -@@ -1975,14 +1993,7 @@ int vchiq_mmal_component_finalise(struct - - component->in_use = 0; - -- for (idx = 0; idx < component->inputs; idx++) -- free_event_context(&component->input[idx]); -- for (idx = 0; idx < component->outputs; idx++) -- free_event_context(&component->output[idx]); -- for (idx = 0; idx < component->clocks; idx++) -- free_event_context(&component->clock[idx]); -- -- free_event_context(&component->control); -+ release_all_event_contexts(component); - - mutex_unlock(&instance->vchiq_mutex); - diff --git a/target/linux/brcm2708/patches-4.19/950-0494-configs-Enable-PIDs-cgroup.patch b/target/linux/brcm2708/patches-4.19/950-0494-configs-Enable-PIDs-cgroup.patch new file mode 100644 index 0000000000..892ebe02ac --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0494-configs-Enable-PIDs-cgroup.patch @@ -0,0 +1,26 @@ +From 4398e1d8787c792a4451beb890d00fba313b6fa7 Mon Sep 17 00:00:00 2001 +From: Henrique Gontijo +Date: Sun, 12 May 2019 17:11:02 -0700 +Subject: [PATCH 494/725] configs: Enable PIDs cgroup + +My use case to is to allow Kubernetes master to run on Raspberry Pi 3. +Kubernetes introduced [Pid limiting](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/20190129-pid-limiting.md), +on v.1.14.0 which includes [Pod Pids Limit](https://github.com/kubernetes/kubernetes/commit/bce9d5f2043bd86964c9fec80d466e47776071bc) +and [Node Pids Limit](https://github.com/kubernetes/kubernetes/commit/2597a1d97ef4d8f54b1ca661453e32794b756909#diff-fa76bb6ae2d9b4bb3d023737fe5e6029R333) +that requires pids cgroup. + +See: https://github.com/raspberrypi/linux/pull/2968 +--- + arch/arm/configs/bcm2709_defconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -20,6 +20,7 @@ CONFIG_CGROUP_FREEZER=y + CONFIG_CPUSETS=y + CONFIG_CGROUP_DEVICE=y + CONFIG_CGROUP_CPUACCT=y ++CONFIG_CGROUP_PIDS=y + CONFIG_NAMESPACES=y + CONFIG_USER_NS=y + CONFIG_SCHED_AUTOGROUP=y diff --git a/target/linux/brcm2708/patches-4.19/950-0494-staging-vchiq-mmal-Fix-memory-leak-of-vchiq-instance.patch b/target/linux/brcm2708/patches-4.19/950-0494-staging-vchiq-mmal-Fix-memory-leak-of-vchiq-instance.patch deleted file mode 100644 index 7c9ac22610..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0494-staging-vchiq-mmal-Fix-memory-leak-of-vchiq-instance.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 123507714c5b2fd44d78f2eac3dc8ade39bb3018 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 3 May 2019 13:27:51 +0100 -Subject: [PATCH 494/703] staging: vchiq-mmal: Fix memory leak of vchiq - instance - -The vchiq instance was allocated from vchiq_mmal_init via -vchi_initialise, but was never released with vchi_disconnect. - -Retain the handle and release it from vchiq_mmal_finalise. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c -@@ -176,6 +176,7 @@ struct mmal_msg_context { - }; - - struct vchiq_mmal_instance { -+ VCHI_INSTANCE_T vchi_instance; - VCHI_SERVICE_HANDLE_T handle; - - /* ensure serialised access to service */ -@@ -1981,7 +1982,7 @@ EXPORT_SYMBOL_GPL(vchiq_mmal_component_i - int vchiq_mmal_component_finalise(struct vchiq_mmal_instance *instance, - struct vchiq_mmal_component *component) - { -- int ret, idx; -+ int ret; - - if (mutex_lock_interruptible(&instance->vchiq_mutex)) - return -EINTR; -@@ -2094,6 +2095,8 @@ int vchiq_mmal_finalise(struct vchiq_mma - - idr_destroy(&instance->context_map); - -+ vchi_disconnect(instance->vchi_instance); -+ - kfree(instance); - - return status; -@@ -2105,7 +2108,7 @@ int vchiq_mmal_init(struct vchiq_mmal_in - int status; - struct vchiq_mmal_instance *instance; - static VCHI_CONNECTION_T *vchi_connection; -- static VCHI_INSTANCE_T vchi_instance; -+ VCHI_INSTANCE_T vchi_instance; - SERVICE_CREATION_T params = { - .version = VCHI_VERSION_EX(VC_MMAL_VER, VC_MMAL_MIN_VER), - .service_id = VC_MMAL_SERVER_NAME, -@@ -2151,6 +2154,8 @@ int vchiq_mmal_init(struct vchiq_mmal_in - if (!instance) - return -ENOMEM; - -+ instance->vchi_instance = vchi_instance; -+ - mutex_init(&instance->vchiq_mutex); - - instance->bulk_scratch = vmalloc(PAGE_SIZE); diff --git a/target/linux/brcm2708/patches-4.19/950-0495-Revert-video-bcm2708_fb-Try-allocating-on-the-ARM-an.patch b/target/linux/brcm2708/patches-4.19/950-0495-Revert-video-bcm2708_fb-Try-allocating-on-the-ARM-an.patch deleted file mode 100644 index 743a2586c9..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0495-Revert-video-bcm2708_fb-Try-allocating-on-the-ARM-an.patch +++ /dev/null @@ -1,164 +0,0 @@ -From dfe9e42ef9bce3edba84cab22269995f8edd02a5 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 13 May 2019 17:34:29 +0100 -Subject: [PATCH 495/703] Revert "video: bcm2708_fb: Try allocating on the ARM - and passing to VPU" - -This reverts commit ca36c709fce57e8023d2b8b354376bf161601a49. - -The driver tries a cma_alloc to avoid using gpu_mem, but should -that fail the core code is logging an error with no easy way to -test whether it will succeed or fail first. - -Revert until we either totally give up on gpu_mem and increase -CMA always, or find a way to try an allocation. - -Signed-off-by: Dave Stevenson ---- - drivers/video/fbdev/bcm2708_fb.c | 102 +++------------------ - include/soc/bcm2835/raspberrypi-firmware.h | 1 - - 2 files changed, 12 insertions(+), 91 deletions(-) - ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -98,11 +98,6 @@ struct bcm2708_fb { - struct bcm2708_fb_stats stats; - unsigned long fb_bus_address; - struct { u32 base, length; } gpu; -- -- bool disable_arm_alloc; -- unsigned int image_size; -- dma_addr_t dma_addr; -- void *cpuaddr; - }; - - #define to_bcm2708(info) container_of(info, struct bcm2708_fb, fb) -@@ -288,88 +283,23 @@ static int bcm2708_fb_set_par(struct fb_ - .xoffset = info->var.xoffset, - .yoffset = info->var.yoffset, - .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 }, -- /* base and screen_size will be initialised later */ -- .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH, 4, 0 }, -- /* pitch will be initialised later */ -+ .base = 0, -+ .screen_size = 0, -+ .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH, 4, 0 }, -+ .pitch = 0, - }; -- int ret, image_size; -- -+ int ret; - - print_debug("%s(%p) %dx%d (%dx%d), %d, %d\n", __func__, info, - info->var.xres, info->var.yres, info->var.xres_virtual, - info->var.yres_virtual, (int)info->screen_size, - info->var.bits_per_pixel); - -- /* Try allocating our own buffer. We can specify all the parameters */ -- image_size = ((info->var.xres * info->var.yres) * -- info->var.bits_per_pixel) >> 3; -- -- if (!fb->disable_arm_alloc && -- (image_size != fb->image_size || !fb->dma_addr)) { -- if (fb->dma_addr) { -- dma_free_coherent(info->device, fb->image_size, -- fb->cpuaddr, fb->dma_addr); -- fb->image_size = 0; -- fb->cpuaddr = NULL; -- fb->dma_addr = 0; -- } -- -- fb->cpuaddr = dma_alloc_coherent(info->device, image_size, -- &fb->dma_addr, GFP_KERNEL); -- -- if (!fb->cpuaddr) { -- fb->dma_addr = 0; -- fb->disable_arm_alloc = true; -- } else { -- fb->image_size = image_size; -- } -- } -- -- if (fb->cpuaddr) { -- fbinfo.base = fb->dma_addr; -- fbinfo.screen_size = image_size; -- fbinfo.pitch = (info->var.xres * info->var.bits_per_pixel) >> 3; -- -- ret = rpi_firmware_property_list(fb->fw, &fbinfo, -- sizeof(fbinfo)); -- if (ret || fbinfo.base != fb->dma_addr) { -- /* Firmware either failed, or assigned a different base -- * address (ie it doesn't support being passed an FB -- * allocation). -- * Destroy the allocation, and don't try again. -- */ -- dma_free_coherent(info->device, fb->image_size, -- fb->cpuaddr, fb->dma_addr); -- fb->image_size = 0; -- fb->cpuaddr = NULL; -- fb->dma_addr = 0; -- fb->disable_arm_alloc = true; -- } -- } else { -- /* Our allocation failed - drop into the old scheme of -- * allocation by the VPU. -- */ -- ret = -ENOMEM; -- } -- -+ ret = rpi_firmware_property_list(fb->fw, &fbinfo, sizeof(fbinfo)); - if (ret) { -- /* Old scheme: -- * - FRAMEBUFFER_ALLOCATE passes 0 for base and screen_size. -- * - GET_PITCH instead of SET_PITCH. -- */ -- fbinfo.base = 0; -- fbinfo.screen_size = 0; -- fbinfo.tag6.tag = RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH; -- fbinfo.pitch = 0; -- -- ret = rpi_firmware_property_list(fb->fw, &fbinfo, -- sizeof(fbinfo)); -- if (ret) { -- dev_err(info->device, -- "Failed to allocate GPU framebuffer (%d)\n", -- ret); -- return ret; -- } -+ dev_err(info->device, -+ "Failed to allocate GPU framebuffer (%d)\n", ret); -+ return ret; - } - - if (info->var.bits_per_pixel <= 8) -@@ -384,17 +314,9 @@ static int bcm2708_fb_set_par(struct fb_ - fb->fb.fix.smem_start = fbinfo.base; - fb->fb.fix.smem_len = fbinfo.pitch * fbinfo.yres_virtual; - fb->fb.screen_size = fbinfo.screen_size; -- -- if (!fb->dma_addr) { -- if (fb->fb.screen_base) -- iounmap(fb->fb.screen_base); -- -- fb->fb.screen_base = ioremap_wc(fbinfo.base, -- fb->fb.screen_size); -- } else { -- fb->fb.screen_base = fb->cpuaddr; -- } -- -+ if (fb->fb.screen_base) -+ iounmap(fb->fb.screen_base); -+ fb->fb.screen_base = ioremap_wc(fbinfo.base, fb->fb.screen_size); - if (!fb->fb.screen_base) { - /* the console may currently be locked */ - console_trylock(); ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -128,7 +128,6 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, - RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER = 0x00048006, - RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE = 0x00048007, -- RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH = 0x00048008, - RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, - RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, - RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, diff --git a/target/linux/brcm2708/patches-4.19/950-0495-w1-ds2408-reset-on-output_write-retry-with-readback.patch b/target/linux/brcm2708/patches-4.19/950-0495-w1-ds2408-reset-on-output_write-retry-with-readback.patch new file mode 100644 index 0000000000..0028729815 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0495-w1-ds2408-reset-on-output_write-retry-with-readback.patch @@ -0,0 +1,140 @@ +From a059cb29f76396d640199026bd94ed654b31e70d Mon Sep 17 00:00:00 2001 +From: Jean-Francois Dagenais +Date: Thu, 28 Mar 2019 12:41:11 -0400 +Subject: [PATCH 495/725] w1: ds2408: reset on output_write retry with readback + +commit 49695ac46861180baf2b2b92c62da8619b6bf28f upstream. + +When we have success in 'Channel Access Write' but reading back latch +states fails, a write is retried without doing a proper slave reset. +This leads to protocol errors as the slave treats the next 'Channel +Access Write' as the continuation of previous command. + +This commit is fixing this by making sure if the retry loop re-runs, a +reset is performed, whatever the failure (CONFIRM_BYTE or the read +back). + +The loop was quite due for a cleanup and this change mandated it. By +isolating the CONFIG_W1_SLAVE_DS2408_READBACK case into it's own +function, we vastly reduce the visual and branching(runtime and +compile-time) noise. + +Reported-by: Mariusz Bialonczyk +Tested-by: Mariusz Bialonczyk +Signed-off-by: Jean-Francois Dagenais +Signed-off-by: Greg Kroah-Hartman +--- + drivers/w1/slaves/w1_ds2408.c | 76 ++++++++++++++++++----------------- + 1 file changed, 39 insertions(+), 37 deletions(-) + +--- a/drivers/w1/slaves/w1_ds2408.c ++++ b/drivers/w1/slaves/w1_ds2408.c +@@ -138,14 +138,37 @@ static ssize_t status_control_read(struc + W1_F29_REG_CONTROL_AND_STATUS, buf); + } + ++#ifdef fCONFIG_W1_SLAVE_DS2408_READBACK ++static bool optional_read_back_valid(struct w1_slave *sl, u8 expected) ++{ ++ u8 w1_buf[3]; ++ ++ if (w1_reset_resume_command(sl->master)) ++ return false; ++ ++ w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS; ++ w1_buf[1] = W1_F29_REG_OUTPUT_LATCH_STATE; ++ w1_buf[2] = 0; ++ ++ w1_write_block(sl->master, w1_buf, 3); ++ ++ return (w1_read_8(sl->master) == expected); ++} ++#else ++static bool optional_read_back_valid(struct w1_slave *sl, u8 expected) ++{ ++ return true; ++} ++#endif ++ + static ssize_t output_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) + { + struct w1_slave *sl = kobj_to_w1_slave(kobj); + u8 w1_buf[3]; +- u8 readBack; + unsigned int retries = W1_F29_RETRIES; ++ ssize_t bytes_written = -EIO; + + if (count != 1 || off != 0) + return -EFAULT; +@@ -155,54 +178,33 @@ static ssize_t output_write(struct file + dev_dbg(&sl->dev, "mutex locked"); + + if (w1_reset_select_slave(sl)) +- goto error; ++ goto out; + +- while (retries--) { ++ do { + w1_buf[0] = W1_F29_FUNC_CHANN_ACCESS_WRITE; + w1_buf[1] = *buf; + w1_buf[2] = ~(*buf); +- w1_write_block(sl->master, w1_buf, 3); + +- readBack = w1_read_8(sl->master); ++ w1_write_block(sl->master, w1_buf, 3); + +- if (readBack != W1_F29_SUCCESS_CONFIRM_BYTE) { +- if (w1_reset_resume_command(sl->master)) +- goto error; +- /* try again, the slave is ready for a command */ +- continue; ++ if (w1_read_8(sl->master) == W1_F29_SUCCESS_CONFIRM_BYTE && ++ optional_read_back_valid(sl, *buf)) { ++ bytes_written = 1; ++ goto out; + } + +-#ifdef CONFIG_W1_SLAVE_DS2408_READBACK +- /* here the master could read another byte which +- would be the PIO reg (the actual pin logic state) +- since in this driver we don't know which pins are +- in and outs, there's no value to read the state and +- compare. with (*buf) so end this command abruptly: */ + if (w1_reset_resume_command(sl->master)) +- goto error; ++ goto out; /* unrecoverable error */ ++ /* try again, the slave is ready for a command */ ++ } while (--retries); + +- /* go read back the output latches */ +- /* (the direct effect of the write above) */ +- w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS; +- w1_buf[1] = W1_F29_REG_OUTPUT_LATCH_STATE; +- w1_buf[2] = 0; +- w1_write_block(sl->master, w1_buf, 3); +- /* read the result of the READ_PIO_REGS command */ +- if (w1_read_8(sl->master) == *buf) +-#endif +- { +- /* success! */ +- mutex_unlock(&sl->master->bus_mutex); +- dev_dbg(&sl->dev, +- "mutex unlocked, retries:%d", retries); +- return 1; +- } +- } +-error: ++out: + mutex_unlock(&sl->master->bus_mutex); +- dev_dbg(&sl->dev, "mutex unlocked in error, retries:%d", retries); + +- return -EIO; ++ dev_dbg(&sl->dev, "%s, mutex unlocked retries:%d\n", ++ (bytes_written > 0) ? "succeeded" : "error", retries); ++ ++ return bytes_written; + } + + diff --git a/target/linux/brcm2708/patches-4.19/950-0496-Added-IQaudIO-Pi-Codec-board-support-2969.patch b/target/linux/brcm2708/patches-4.19/950-0496-Added-IQaudIO-Pi-Codec-board-support-2969.patch deleted file mode 100644 index 177d8900bd..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0496-Added-IQaudIO-Pi-Codec-board-support-2969.patch +++ /dev/null @@ -1,409 +0,0 @@ -From 7208ccb2165feb06eda3f04858d09388cd279c7d Mon Sep 17 00:00:00 2001 -From: IQaudIO -Date: Mon, 13 May 2019 21:53:05 +0100 -Subject: [PATCH 496/703] Added IQaudIO Pi-Codec board support (#2969) - -Add support for the IQaudIO Pi-Codec board. - -Signed-off-by: Gordon ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 6 + - .../dts/overlays/iqaudio-codec-overlay.dts | 42 +++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - arch/arm64/configs/bcmrpi3_defconfig | 1 + - sound/soc/bcm/Kconfig | 7 + - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/iqaudio-codec.c | 250 ++++++++++++++++++ - 9 files changed, 311 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/iqaudio-codec-overlay.dts - create mode 100644 sound/soc/bcm/iqaudio-codec.c - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -68,6 +68,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - i2c1-bcm2708.dtbo \ - i2s-gpio28-31.dtbo \ - ilitek251x.dtbo \ -+ iqaudio-codec.dtbo \ - iqaudio-dac.dtbo \ - iqaudio-dacplus.dtbo \ - iqaudio-digi-wm8804-audio.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1160,6 +1160,12 @@ Params: interrupt GPIO use - touchscreen (in pixels) - - -+Name: iqaudio-codec -+Info: Configures the IQaudio Codec audio card -+Load: dtoverlay=iqaudio-codec -+Params: -+ -+ - Name: iqaudio-dac - Info: Configures the IQaudio DAC audio card - Load: dtoverlay=iqaudio-dac, ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/iqaudio-codec-overlay.dts -@@ -0,0 +1,42 @@ -+// Definitions for IQaudIO CODEC -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ da2713@1a { -+ #sound-dai-cells = <0>; -+ compatible = "dlg,da7213"; -+ reg = <0x1a>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&sound>; -+ iqaudio_dac: __overlay__ { -+ compatible = "iqaudio,iqaudio-codec"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ __overrides__ { -+ }; -+}; ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -919,6 +919,7 @@ CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m - CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m -+CONFIG_SND_BCM2708_SOC_IQAUDIO_CODEC=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m - CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -912,6 +912,7 @@ CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m - CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m -+CONFIG_SND_BCM2708_SOC_IQAUDIO_CODEC=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m - CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -807,6 +807,7 @@ CONFIG_SND_BCM2708_SOC_RPI_DAC=m - CONFIG_SND_BCM2708_SOC_RPI_PROTO=m - CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m - CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m -+CONFIG_SND_BCM2708_SOC_IQAUDIO_CODEC=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m - CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -108,6 +108,13 @@ config SND_BCM2708_SOC_JUSTBOOM_DIGI - help - Say Y or M if you want to add support for JustBoom Digi. - -+config SND_BCM2708_SOC_IQAUDIO_CODEC -+ tristate "Support for IQaudIO-CODEC" -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S -+ select SND_SOC_DA7213 -+ help -+ Say Y or M if you want to add support for IQaudIO-CODEC. -+ - config SND_BCM2708_SOC_IQAUDIO_DAC - tristate "Support for IQaudIO-DAC" - 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-hifiberry-dacplusadc-objs := hif - snd-soc-justboom-dac-objs := justboom-dac.o - snd-soc-rpi-cirrus-objs := rpi-cirrus.o - snd-soc-rpi-proto-objs := rpi-proto.o -+snd-soc-iqaudio-codec-objs := iqaudio-codec.o - snd-soc-iqaudio-dac-objs := iqaudio-dac.o - snd-soc-i-sabre-q2m-objs := i-sabre-q2m.o - snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o -@@ -42,6 +43,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_D - obj-$(CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC) += snd-soc-justboom-dac.o - obj-$(CONFIG_SND_BCM2708_SOC_RPI_CIRRUS) += snd-soc-rpi-cirrus.o - obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o -+obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_CODEC) += snd-soc-iqaudio-codec.o - obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o - obj-$(CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M) += snd-soc-i-sabre-q2m.o - obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o ---- /dev/null -+++ b/sound/soc/bcm/iqaudio-codec.c -@@ -0,0 +1,250 @@ -+/* -+ * ASoC Driver for IQaudIO Raspberry Pi Codec board -+ * -+ * Author: Gordon Garrity -+ * (C) Copyright IQaudio Limited, 2017-2019 -+ * -+ * 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 -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include "../codecs/da7213.h" -+ -+static int pll_out = DA7213_PLL_FREQ_OUT_90316800; -+ -+static int snd_rpi_iqaudio_pll_control(struct snd_soc_dapm_widget *w, -+ struct snd_kcontrol *k, int event) -+{ -+ int ret = 0; -+ struct snd_soc_dapm_context *dapm = w->dapm; -+ struct snd_soc_card *card = dapm->card; -+ struct snd_soc_pcm_runtime *rtd = -+ snd_soc_get_pcm_runtime(card, card->dai_link[0].name); -+ struct snd_soc_dai *codec_dai = rtd->codec_dai; -+ -+ if (SND_SOC_DAPM_EVENT_OFF(event)) { -+ ret = snd_soc_dai_set_pll(codec_dai, 0, DA7213_SYSCLK_MCLK, 0, -+ 0); -+ if (ret) -+ dev_err(card->dev, "Failed to bypass PLL: %d\n", ret); -+ } else if (SND_SOC_DAPM_EVENT_ON(event)) { -+ ret = snd_soc_dai_set_pll(codec_dai, 0, DA7213_SYSCLK_PLL, 0, -+ pll_out); -+ if (ret) -+ dev_err(card->dev, "Failed to enable PLL: %d\n", ret); -+ } -+ -+ return ret; -+} -+ -+static int snd_rpi_iqaudio_post_dapm_event(struct snd_soc_dapm_widget *w, -+ struct snd_kcontrol *kcontrol, -+ int event) -+{ -+ switch (event) { -+ case SND_SOC_DAPM_POST_PMU: -+ /* Delay for mic bias ramp */ -+ msleep(1000); -+ break; -+ default: -+ break; -+ } -+ -+ return 0; -+} -+ -+static const struct snd_soc_dapm_widget dapm_widgets[] = { -+ SND_SOC_DAPM_HP("HP Jack", NULL), -+ SND_SOC_DAPM_MIC("MIC Jack", NULL), -+ SND_SOC_DAPM_MIC("Onboard MIC", NULL), -+ SND_SOC_DAPM_LINE("AUX Jack", NULL), -+ SND_SOC_DAPM_SUPPLY("PLL Control", SND_SOC_NOPM, 0, 0, -+ snd_rpi_iqaudio_pll_control, -+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), -+ SND_SOC_DAPM_POST("Post Power Up Event", snd_rpi_iqaudio_post_dapm_event), -+}; -+ -+static const struct snd_soc_dapm_route audio_map[] = { -+ {"HP Jack", NULL, "HPL"}, -+ {"HP Jack", NULL, "HPR"}, -+ {"HP Jack", NULL, "PLL Control"}, -+ -+ {"AUX Jack", NULL, "AUXR"}, -+ {"AUX Jack", NULL, "AUXL"}, -+ {"AUX Jack", NULL, "PLL Control"}, -+ -+ /* Assume Mic1 is linked to Headset and Mic2 to on-board mic */ -+ {"MIC Jack", NULL, "MIC1"}, -+ {"MIC Jack", NULL, "PLL Control"}, -+ {"Onboard MIC", NULL, "MIC2"}, -+ {"Onboard MIC", NULL, "PLL Control"}, -+}; -+ -+/* machine stream operations */ -+ -+static int snd_rpi_iqaudio_codec_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ struct snd_soc_dai *codec_dai = rtd->codec_dai; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ int ret; -+ -+ /* Set bclk ratio to align with codec's BCLK rate */ -+ ret = snd_soc_dai_set_bclk_ratio(cpu_dai, 64); -+ if (ret) { -+ dev_err(rtd->dev, "Failed to set CPU BLCK ratio\n"); -+ return ret; -+ } -+ -+ /* Set MCLK frequency to codec, onboard 11.2896MHz clock */ -+ return snd_soc_dai_set_sysclk(codec_dai, DA7213_CLKSRC_MCLK, 11289600, -+ SND_SOC_CLOCK_OUT); -+} -+ -+static int snd_rpi_iqaudio_codec_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ unsigned int samplerate = params_rate(params); -+ -+ switch (samplerate) { -+ case 8000: -+ case 16000: -+ case 32000: -+ case 48000: -+ case 96000: -+ pll_out = DA7213_PLL_FREQ_OUT_98304000; -+ return 0; -+ case 44100: -+ case 88200: -+ pll_out = DA7213_PLL_FREQ_OUT_90316800; -+ return 0; -+ default: -+ dev_err(rtd->dev,"Unsupported samplerate %d\n", samplerate); -+ return -EINVAL; -+ } -+} -+ -+static const struct snd_soc_ops snd_rpi_iqaudio_codec_ops = { -+ .hw_params = snd_rpi_iqaudio_codec_hw_params, -+}; -+ -+ -+static struct snd_soc_dai_link snd_rpi_iqaudio_codec_dai[] = { -+{ -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "da7213-hifi", -+ .platform_name = "bmc2708-i2s.0", -+ .codec_name = "da7213.1-001a", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBM_CFM, -+ .init = snd_rpi_iqaudio_codec_init, -+ .ops = &snd_rpi_iqaudio_codec_ops, -+ .symmetric_rates = 1, -+ .symmetric_channels = 1, -+ .symmetric_samplebits = 1, -+}, -+}; -+ -+/* audio machine driver */ -+static struct snd_soc_card snd_rpi_iqaudio_codec = { -+ .owner = THIS_MODULE, -+ .dai_link = snd_rpi_iqaudio_codec_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_iqaudio_codec_dai), -+ .dapm_widgets = dapm_widgets, -+ .num_dapm_widgets = ARRAY_SIZE(dapm_widgets), -+ .dapm_routes = audio_map, -+ .num_dapm_routes = ARRAY_SIZE(audio_map), -+}; -+ -+static int snd_rpi_iqaudio_codec_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_iqaudio_codec.dev = &pdev->dev; -+ -+ if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_card *card = &snd_rpi_iqaudio_codec; -+ struct snd_soc_dai_link *dai = &snd_rpi_iqaudio_codec_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; -+ } -+ -+ if (of_property_read_string(pdev->dev.of_node, "card_name", -+ &card->name)) -+ card->name = "IQaudIOCODEC"; -+ -+ if (of_property_read_string(pdev->dev.of_node, "dai_name", -+ &dai->name)) -+ dai->name = "IQaudIO CODEC"; -+ -+ if (of_property_read_string(pdev->dev.of_node, -+ "dai_stream_name", &dai->stream_name)) -+ dai->stream_name = "IQaudIO CODEC HiFi v1.1"; -+ -+ } -+ -+ ret = snd_soc_register_card(&snd_rpi_iqaudio_codec); -+ if (ret) { -+ if (ret != -EPROBE_DEFER) -+ dev_err(&pdev->dev, -+ "snd_soc_register_card() failed: %d\n", ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int snd_rpi_iqaudio_codec_remove(struct platform_device *pdev) -+{ -+ return snd_soc_unregister_card(&snd_rpi_iqaudio_codec); -+} -+ -+static const struct of_device_id iqaudio_of_match[] = { -+ { .compatible = "iqaudio,iqaudio-codec", }, -+ {}, -+}; -+ -+MODULE_DEVICE_TABLE(of, iqaudio_of_match); -+ -+static struct platform_driver snd_rpi_iqaudio_codec_driver = { -+ .driver = { -+ .name = "snd-rpi-iqaudio-codec", -+ .owner = THIS_MODULE, -+ .of_match_table = iqaudio_of_match, -+ }, -+ .probe = snd_rpi_iqaudio_codec_probe, -+ .remove = snd_rpi_iqaudio_codec_remove, -+}; -+ -+ -+ -+module_platform_driver(snd_rpi_iqaudio_codec_driver); -+ -+MODULE_AUTHOR("Gordon Garrity "); -+MODULE_DESCRIPTION("ASoC Driver for IQaudIO CODEC"); -+MODULE_LICENSE("GPL v2"); diff --git a/target/linux/brcm2708/patches-4.19/950-0496-w1-ds2482-cosmetic-fixes-after-54865314f5a1.patch b/target/linux/brcm2708/patches-4.19/950-0496-w1-ds2482-cosmetic-fixes-after-54865314f5a1.patch new file mode 100644 index 0000000000..67a01ee821 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0496-w1-ds2482-cosmetic-fixes-after-54865314f5a1.patch @@ -0,0 +1,91 @@ +From 5afe695ddcc560424d2b98984902a578ae8e416c Mon Sep 17 00:00:00 2001 +From: Mariusz Bialonczyk +Date: Mon, 4 Mar 2019 12:23:36 +0100 +Subject: [PATCH 496/725] w1: ds2482: cosmetic fixes after 54865314f5a1 + +commit 5cb27d30fc3a281e830a2099d520b469e2b82008 upstream. + +We have a helper function ds2482_calculate_config() which is calculating +the config value, so just use it instead of passing the same variable +in all calls to this function. + +Also fixes the placement of module parameters to match with: +50fa2951bd74 (w1: Organize driver source to natural/common order) +by Andrew F. Davis + +Signed-off-by: Mariusz Bialonczyk +Cc: Andrew Worsley +Cc: Andrew F. Davis +Signed-off-by: Greg Kroah-Hartman +--- + drivers/w1/masters/ds2482.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +--- a/drivers/w1/masters/ds2482.c ++++ b/drivers/w1/masters/ds2482.c +@@ -37,6 +37,11 @@ module_param_named(active_pullup, ds2482 + MODULE_PARM_DESC(active_pullup, "Active pullup (apply to all buses): " \ + "0-disable, 1-enable (default)"); + ++/* extra configurations - e.g. 1WS */ ++static int extra_config; ++module_param(extra_config, int, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(extra_config, "Extra Configuration settings 1=APU,2=PPM,3=SPU,8=1WS"); ++ + /** + * The DS2482 registers - there are 3 registers that are addressed by a read + * pointer. The read pointer is set by the last command executed. +@@ -70,8 +75,6 @@ MODULE_PARM_DESC(active_pullup, "Active + #define DS2482_REG_CFG_PPM 0x02 /* presence pulse masking */ + #define DS2482_REG_CFG_APU 0x01 /* active pull-up */ + +-/* extra configurations - e.g. 1WS */ +-static int extra_config; + + /** + * Write and verify codes for the CHANNEL_SELECT command (DS2482-800 only). +@@ -130,6 +133,8 @@ struct ds2482_data { + */ + static inline u8 ds2482_calculate_config(u8 conf) + { ++ conf |= extra_config; ++ + if (ds2482_active_pullup) + conf |= DS2482_REG_CFG_APU; + +@@ -405,7 +410,7 @@ static u8 ds2482_w1_reset_bus(void *data + /* If the chip did reset since detect, re-config it */ + if (err & DS2482_REG_STS_RST) + ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG, +- ds2482_calculate_config(extra_config)); ++ ds2482_calculate_config(0x00)); + } + + mutex_unlock(&pdev->access_lock); +@@ -431,7 +436,8 @@ static u8 ds2482_w1_set_pullup(void *dat + ds2482_wait_1wire_idle(pdev); + /* note: it seems like both SPU and APU have to be set! */ + retval = ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG, +- ds2482_calculate_config(extra_config|DS2482_REG_CFG_SPU|DS2482_REG_CFG_APU)); ++ ds2482_calculate_config(DS2482_REG_CFG_SPU | ++ DS2482_REG_CFG_APU)); + ds2482_wait_1wire_idle(pdev); + } + +@@ -484,7 +490,7 @@ static int ds2482_probe(struct i2c_clien + + /* Set all config items to 0 (off) */ + ds2482_send_cmd_data(data, DS2482_CMD_WRITE_CONFIG, +- ds2482_calculate_config(extra_config)); ++ ds2482_calculate_config(0x00)); + + mutex_init(&data->access_lock); + +@@ -559,7 +565,5 @@ module_i2c_driver(ds2482_driver); + + MODULE_AUTHOR("Ben Gardner "); + MODULE_DESCRIPTION("DS2482 driver"); +-module_param(extra_config, int, S_IRUGO | S_IWUSR); +-MODULE_PARM_DESC(extra_config, "Extra Configuration settings 1=APU,2=PPM,3=SPU,8=1WS"); + + MODULE_LICENSE("GPL"); diff --git a/target/linux/brcm2708/patches-4.19/950-0497-Revert-smsc95xx-dynamically-fix-up-TX-buffer-alignme.patch b/target/linux/brcm2708/patches-4.19/950-0497-Revert-smsc95xx-dynamically-fix-up-TX-buffer-alignme.patch deleted file mode 100644 index 08532bda58..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0497-Revert-smsc95xx-dynamically-fix-up-TX-buffer-alignme.patch +++ /dev/null @@ -1,60 +0,0 @@ -From fb13c1342c81bb0c06afdcfe1e8561e8a6e149d7 Mon Sep 17 00:00:00 2001 -From: P33M -Date: Tue, 14 May 2019 14:55:19 +0100 -Subject: [PATCH 497/703] Revert "smsc95xx: dynamically fix up TX buffer - alignment with padding bytes" - -As reported in https://github.com/raspberrypi/linux/issues/2964 this -commit causes a regression corrupting non-option TCP ack packets. - -This reverts commit 96b972dc736d943f371a16ccca452a053d83c65b. ---- - drivers/net/usb/smsc95xx.c | 12 +++++------- - drivers/net/usb/smsc95xx.h | 2 +- - 2 files changed, 6 insertions(+), 8 deletions(-) - ---- a/drivers/net/usb/smsc95xx.c -+++ b/drivers/net/usb/smsc95xx.c -@@ -2082,9 +2082,7 @@ static struct sk_buff *smsc95xx_tx_fixup - struct sk_buff *skb, gfp_t flags) - { - bool csum = skb->ip_summed == CHECKSUM_PARTIAL; -- unsigned int align_bytes = -((uintptr_t)skb->data) & 0x3; -- int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM + align_bytes -- : SMSC95XX_TX_OVERHEAD + align_bytes; -+ int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM : SMSC95XX_TX_OVERHEAD; - u32 tx_cmd_a, tx_cmd_b; - - /* We do not advertise SG, so skbs should be already linearized */ -@@ -2118,16 +2116,16 @@ static struct sk_buff *smsc95xx_tx_fixup - } - } - -- skb_push(skb, 4 + align_bytes); -- tx_cmd_b = (u32)(skb->len - 4 - align_bytes); -+ skb_push(skb, 4); -+ tx_cmd_b = (u32)(skb->len - 4); - if (csum) - tx_cmd_b |= TX_CMD_B_CSUM_ENABLE; - cpu_to_le32s(&tx_cmd_b); - memcpy(skb->data, &tx_cmd_b, 4); - - skb_push(skb, 4); -- tx_cmd_a = (u32)(skb->len - 8 - align_bytes) | TX_CMD_A_FIRST_SEG_ | -- (align_bytes << 16) | TX_CMD_A_LAST_SEG_; -+ tx_cmd_a = (u32)(skb->len - 8) | TX_CMD_A_FIRST_SEG_ | -+ TX_CMD_A_LAST_SEG_; - cpu_to_le32s(&tx_cmd_a); - memcpy(skb->data, &tx_cmd_a, 4); - ---- a/drivers/net/usb/smsc95xx.h -+++ b/drivers/net/usb/smsc95xx.h -@@ -21,7 +21,7 @@ - #define _SMSC95XX_H - - /* Tx command words */ --#define TX_CMD_A_DATA_OFFSET_ (0x00030000) /* Data Start Offset */ -+#define TX_CMD_A_DATA_OFFSET_ (0x001F0000) /* Data Start Offset */ - #define TX_CMD_A_FIRST_SEG_ (0x00002000) /* First Segment */ - #define TX_CMD_A_LAST_SEG_ (0x00001000) /* Last Segment */ - #define TX_CMD_A_BUF_SIZE_ (0x000007FF) /* Buffer Size */ diff --git a/target/linux/brcm2708/patches-4.19/950-0497-sound-pcm512x-codec-Adding-352.8kHz-samplerate-suppo.patch b/target/linux/brcm2708/patches-4.19/950-0497-sound-pcm512x-codec-Adding-352.8kHz-samplerate-suppo.patch new file mode 100644 index 0000000000..f0e8adf61a --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0497-sound-pcm512x-codec-Adding-352.8kHz-samplerate-suppo.patch @@ -0,0 +1,21 @@ +From 5989c694277724691de437691ea314fc8fad93b8 Mon Sep 17 00:00:00 2001 +From: Klaus Schulz +Date: Thu, 16 May 2019 13:35:32 +0200 +Subject: [PATCH 497/725] sound: pcm512x-codec: Adding 352.8kHz samplerate + support + +--- + sound/soc/codecs/pcm512x.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/soc/codecs/pcm512x.c ++++ b/sound/soc/codecs/pcm512x.c +@@ -542,7 +542,7 @@ static unsigned long pcm512x_ncp_target( + + static const u32 pcm512x_dai_rates[] = { + 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, +- 88200, 96000, 176400, 192000, 384000, ++ 88200, 96000, 176400, 192000, 352800, 384000, + }; + + static const struct snd_pcm_hw_constraint_list constraints_slave = { diff --git a/target/linux/brcm2708/patches-4.19/950-0498-ASoC-decommissioning-driver-for-3Dlab-Nano-soundcard.patch b/target/linux/brcm2708/patches-4.19/950-0498-ASoC-decommissioning-driver-for-3Dlab-Nano-soundcard.patch new file mode 100644 index 0000000000..935a0e822d --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0498-ASoC-decommissioning-driver-for-3Dlab-Nano-soundcard.patch @@ -0,0 +1,522 @@ +From 0a066a3f2e77c2d4d49a8d1f148b30a10a89de74 Mon Sep 17 00:00:00 2001 +From: GT +Date: Sat, 6 Apr 2019 21:16:39 +0100 +Subject: [PATCH 498/725] ASoC: decommissioning driver for 3Dlab Nano soundcard + +--- + .../overlays/3dlab-nano-player-overlay.dts | 32 -- + arch/arm/boot/dts/overlays/Makefile | 1 - + arch/arm/boot/dts/overlays/README | 6 - + arch/arm/configs/bcm2709_defconfig | 1 - + arch/arm/configs/bcmrpi_defconfig | 1 - + sound/soc/bcm/3dlab-nano-player.c | 370 ------------------ + sound/soc/bcm/Kconfig | 6 - + sound/soc/bcm/Makefile | 6 +- + 8 files changed, 2 insertions(+), 421 deletions(-) + delete mode 100644 arch/arm/boot/dts/overlays/3dlab-nano-player-overlay.dts + delete mode 100644 sound/soc/bcm/3dlab-nano-player.c + +--- a/arch/arm/boot/dts/overlays/3dlab-nano-player-overlay.dts ++++ /dev/null +@@ -1,32 +0,0 @@ +-// Definitions for 3Dlab Nano Player +-/dts-v1/; +-/plugin/; +- +-/ { +- compatible = "brcm,bcm2708"; +- +- fragment@0 { +- target = <&i2s>; +- __overlay__ { +- status = "okay"; +- }; +- }; +- +- fragment@1 { +- target = <&i2c>; +- __overlay__ { +- #address-cells = <1>; +- #size-cells = <0>; +- status = "okay"; +- +- nano-player@41 { +- compatible = "3dlab,nano-player"; +- reg = <0x41>; +- i2s-controller = <&i2s>; +- status = "okay"; +- }; +- }; +- }; +-}; +- +-// EOF +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -1,7 +1,6 @@ + # Overlays for the Raspberry Pi platform + + dtbo-$(CONFIG_ARCH_BCM2835) += \ +- 3dlab-nano-player.dtbo \ + adau1977-adc.dtbo \ + adau7002-simple.dtbo \ + ads1015.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -205,12 +205,6 @@ Params: + and the other i2c baudrate parameters. + + +-Name: 3dlab-nano-player +-Info: Configures the 3Dlab Nano Player +-Load: dtoverlay=3dlab-nano-player +-Params: +- +- + Name: adau1977-adc + Info: Overlay for activation of ADAU1977 ADC codec over I2C for control + and I2S for data. +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -908,7 +908,6 @@ CONFIG_SND_USB_6FIRE=m + CONFIG_SND_USB_HIFACE=m + CONFIG_SND_SOC=m + CONFIG_SND_BCM2835_SOC_I2S=m +-CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER=m + CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -900,7 +900,6 @@ CONFIG_SND_USB_6FIRE=m + CONFIG_SND_USB_HIFACE=m + CONFIG_SND_SOC=m + CONFIG_SND_BCM2835_SOC_I2S=m +-CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER=m + CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m +--- a/sound/soc/bcm/3dlab-nano-player.c ++++ /dev/null +@@ -1,370 +0,0 @@ +-/* +- * 3Dlab Nano Player ALSA SoC Audio driver. +- * +- * Copyright (C) 2018 3Dlab. +- * +- * Author: GT +- * +- * 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 +-#include +-#include +-#include +-#include +-#include +- +-#define NANO_ID 0x00 +-#define NANO_VER 0x01 +-#define NANO_CFG 0x02 +-#define NANO_STATUS 0x03 +-#define NANO_SPI_ADDR 0x04 +-#define NANO_SPI_DATA 0x05 +- +-#define NANO_ID_VAL 0x3D +-#define NANO_CFG_OFF 0x00 +-#define NANO_CFG_MULT1 0 +-#define NANO_CFG_MULT2 1 +-#define NANO_CFG_MULT4 2 +-#define NANO_CFG_MULT8 3 +-#define NANO_CFG_MULT16 4 +-#define NANO_CFG_CLK22 0 +-#define NANO_CFG_CLK24 BIT(3) +-#define NANO_CFG_DSD BIT(4) +-#define NANO_CFG_ENA BIT(5) +-#define NANO_CFG_BLINK BIT(6) +-#define NANO_STATUS_P1 BIT(0) +-#define NANO_STATUS_P2 BIT(1) +-#define NANO_STATUS_FLG BIT(2) +-#define NANO_STATUS_CLK BIT(3) +-#define NANO_SPI_READ 0 +-#define NANO_SPI_WRITE BIT(5) +- +-#define NANO_DAC_CTRL1 0x00 +-#define NANO_DAC_CTRL2 0x01 +-#define NANO_DAC_CTRL3 0x02 +-#define NANO_DAC_LATT 0x03 +-#define NANO_DAC_RATT 0x04 +- +-#define NANO_CTRL2_VAL 0x22 +- +-static int nano_player_spi_write(struct regmap *map, +- unsigned int reg, unsigned int val) +-{ +- /* indirect register access */ +- regmap_write(map, NANO_SPI_DATA, val); +- regmap_write(map, NANO_SPI_ADDR, reg | NANO_SPI_WRITE); +- return 0; +-} +- +-static int nano_player_ctrl_info(struct snd_kcontrol *kcontrol, +- struct snd_ctl_elem_info *uinfo) +-{ +- /* describe control element */ +- if (strstr(kcontrol->id.name, "Volume")) { +- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; +- uinfo->count = 1; +- uinfo->value.integer.min = 0; +- uinfo->value.integer.max = 100; +- } else { +- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; +- uinfo->count = 1; +- uinfo->value.integer.min = 0; +- uinfo->value.integer.max = 1; +- } +- +- return 0; +-} +- +-static int nano_player_ctrl_put(struct snd_kcontrol *kcontrol, +- struct snd_ctl_elem_value *ucontrol) +-{ +- /* program control value to hardware */ +- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); +- struct regmap *regmap = snd_soc_card_get_drvdata(card); +- +- if (strstr(kcontrol->id.name, "Volume")) { +- unsigned int vol = ucontrol->value.integer.value[0]; +- unsigned int att = 255 - (2 * (100 - vol)); +- +- nano_player_spi_write(regmap, NANO_DAC_LATT, att); +- nano_player_spi_write(regmap, NANO_DAC_RATT, att); +- kcontrol->private_value = vol; +- } else { +- unsigned int mute = ucontrol->value.integer.value[0]; +- unsigned int reg = NANO_CTRL2_VAL | mute; +- +- nano_player_spi_write(regmap, NANO_DAC_CTRL2, reg); +- kcontrol->private_value = mute; +- } +- return 0; +-} +- +-static int nano_player_ctrl_get(struct snd_kcontrol *kcontrol, +- struct snd_ctl_elem_value *ucontrol) +-{ +- /* return last programmed value */ +- ucontrol->value.integer.value[0] = kcontrol->private_value; +- return 0; +-} +- +-#define SOC_NANO_PLAYER_CTRL(xname) \ +-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ +- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ +- .info = nano_player_ctrl_info, \ +- .put = nano_player_ctrl_put, \ +- .get = nano_player_ctrl_get } +- +-static const struct snd_kcontrol_new nano_player_controls[] = { +- SOC_NANO_PLAYER_CTRL("Master Playback Volume"), +- SOC_NANO_PLAYER_CTRL("Master Playback Switch"), +-}; +- +-static const unsigned int nano_player_rates[] = { +- 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, +- 705600, 768000 /* only possible with fast clocks */ +-}; +- +-static struct snd_pcm_hw_constraint_list nano_player_constraint_rates = { +- .list = nano_player_rates, +- .count = ARRAY_SIZE(nano_player_rates), +-}; +- +-static int nano_player_init(struct snd_soc_pcm_runtime *rtd) +-{ +- struct snd_soc_card *card = rtd->card; +- struct regmap *regmap = snd_soc_card_get_drvdata(card); +- struct snd_soc_pcm_stream *cpu = &rtd->cpu_dai->driver->playback; +- struct snd_soc_pcm_stream *codec = &rtd->codec_dai->driver->playback; +- unsigned int sample_bits = 32; +- unsigned int val; +- +- /* configure cpu dai */ +- cpu->formats |= SNDRV_PCM_FMTBIT_DSD_U32_LE; +- cpu->rate_max = 768000; +- +- /* configure dummy codec dai */ +- codec->rate_min = 44100; +- codec->rates = SNDRV_PCM_RATE_KNOT; +- codec->formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_DSD_U32_LE; +- +- /* configure max supported rate */ +- regmap_read(regmap, NANO_STATUS, &val); +- if (val & NANO_STATUS_CLK) { +- dev_notice(card->dev, "Board with fast clocks installed\n"); +- codec->rate_max = 768000; +- } else { +- dev_notice(card->dev, "Board with normal clocks installed\n"); +- codec->rate_max = 384000; +- } +- +- /* frame length enforced by hardware */ +- return snd_soc_dai_set_bclk_ratio(rtd->cpu_dai, sample_bits * 2); +-} +- +-static int nano_player_startup(struct snd_pcm_substream *substream) +-{ +- return snd_pcm_hw_constraint_list(substream->runtime, 0, +- SNDRV_PCM_HW_PARAM_RATE, +- &nano_player_constraint_rates); +-} +- +-static int nano_player_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_card *card = rtd->card; +- struct regmap *regmap = snd_soc_card_get_drvdata(card); +- unsigned int config = NANO_CFG_ENA; +- struct snd_mask *fmt; +- +- /* configure PCM or DSD */ +- fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); +- if (snd_mask_test(fmt, SNDRV_PCM_FORMAT_DSD_U32_LE)) { +- /* embed DSD in PCM data */ +- snd_mask_none(fmt); +- snd_mask_set(fmt, SNDRV_PCM_FORMAT_S32_LE); +- /* enable DSD mode */ +- config |= NANO_CFG_DSD; +- } +- +- /* configure clocks */ +- switch (params_rate(params)) { +- case 44100: +- config |= NANO_CFG_MULT1 | NANO_CFG_CLK22; +- break; +- case 88200: +- config |= NANO_CFG_MULT2 | NANO_CFG_CLK22; +- break; +- case 176400: +- config |= NANO_CFG_MULT4 | NANO_CFG_CLK22; +- break; +- case 352800: +- config |= NANO_CFG_MULT8 | NANO_CFG_CLK22; +- break; +- case 705600: +- config |= NANO_CFG_MULT16 | NANO_CFG_CLK22; +- break; +- case 48000: +- config |= NANO_CFG_MULT1 | NANO_CFG_CLK24; +- break; +- case 96000: +- config |= NANO_CFG_MULT2 | NANO_CFG_CLK24; +- break; +- case 192000: +- config |= NANO_CFG_MULT4 | NANO_CFG_CLK24; +- break; +- case 384000: +- config |= NANO_CFG_MULT8 | NANO_CFG_CLK24; +- break; +- case 768000: +- config |= NANO_CFG_MULT16 | NANO_CFG_CLK24; +- break; +- default: +- return -EINVAL; +- } +- +- dev_dbg(card->dev, "Send CFG register 0x%02X\n", config); +- return regmap_write(regmap, NANO_CFG, config); +-} +- +-static struct snd_soc_ops nano_player_ops = { +- .startup = nano_player_startup, +- .hw_params = nano_player_hw_params, +-}; +- +-static struct snd_soc_dai_link nano_player_link = { +- .name = "3Dlab Nano Player", +- .stream_name = "3Dlab Nano Player HiFi", +- .platform_name = "bcm2708-i2s.0", +- .cpu_dai_name = "bcm2708-i2s.0", +- .codec_name = "snd-soc-dummy", +- .codec_dai_name = "snd-soc-dummy-dai", +- .dai_fmt = SND_SOC_DAIFMT_I2S | +- SND_SOC_DAIFMT_CONT | +- SND_SOC_DAIFMT_NB_NF | +- SND_SOC_DAIFMT_CBM_CFM, +- .init = nano_player_init, +- .ops = &nano_player_ops, +-}; +- +-static const struct regmap_config nano_player_regmap = { +- .reg_bits = 8, +- .val_bits = 8, +- .max_register = 128, +- .cache_type = REGCACHE_RBTREE, +-}; +- +-static int nano_player_card_probe(struct snd_soc_card *card) +-{ +- struct regmap *regmap = snd_soc_card_get_drvdata(card); +- unsigned int val; +- +- /* check hardware integrity */ +- regmap_read(regmap, NANO_ID, &val); +- if (val != NANO_ID_VAL) { +- dev_err(card->dev, "Invalid ID register 0x%02X\n", val); +- return -ENODEV; +- } +- +- /* report version to the user */ +- regmap_read(regmap, NANO_VER, &val); +- dev_notice(card->dev, "Started 3Dlab Nano Player driver (v%d)\n", val); +- +- /* enable internal audio bus and blink status LED */ +- return regmap_write(regmap, NANO_CFG, NANO_CFG_ENA | NANO_CFG_BLINK); +-} +- +-static int nano_player_card_remove(struct snd_soc_card *card) +-{ +- /* disable internal audio bus */ +- struct regmap *regmap = snd_soc_card_get_drvdata(card); +- +- return regmap_write(regmap, NANO_CFG, NANO_CFG_OFF); +-} +- +-static struct snd_soc_card nano_player_card = { +- .name = "3Dlab_Nano_Player", +- .owner = THIS_MODULE, +- .dai_link = &nano_player_link, +- .num_links = 1, +- .controls = nano_player_controls, +- .num_controls = ARRAY_SIZE(nano_player_controls), +- .probe = nano_player_card_probe, +- .remove = nano_player_card_remove, +-}; +- +-static int nano_player_i2c_probe(struct i2c_client *i2c, +- const struct i2c_device_id *id) +-{ +- struct regmap *regmap; +- int ret; +- +- regmap = devm_regmap_init_i2c(i2c, &nano_player_regmap); +- if (IS_ERR(regmap)) { +- ret = PTR_ERR(regmap); +- dev_err(&i2c->dev, "Failed to init regmap %d\n", ret); +- return ret; +- } +- +- if (i2c->dev.of_node) { +- struct snd_soc_dai_link *dai = &nano_player_link; +- struct device_node *node; +- +- /* cpu handle configured by device tree */ +- node = of_parse_phandle(i2c->dev.of_node, "i2s-controller", 0); +- if (node) { +- dai->platform_name = NULL; +- dai->platform_of_node = node; +- dai->cpu_dai_name = NULL; +- dai->cpu_of_node = node; +- } +- } +- +- nano_player_card.dev = &i2c->dev; +- snd_soc_card_set_drvdata(&nano_player_card, regmap); +- ret = devm_snd_soc_register_card(&i2c->dev, &nano_player_card); +- +- if (ret && ret != -EPROBE_DEFER) +- dev_err(&i2c->dev, "Failed to register card %d\n", ret); +- +- return ret; +-} +- +-static const struct of_device_id nano_player_of_match[] = { +- { .compatible = "3dlab,nano-player", }, +- { } +-}; +-MODULE_DEVICE_TABLE(of, nano_player_of_match); +- +-static const struct i2c_device_id nano_player_i2c_id[] = { +- { "nano-player", 0 }, +- { } +-}; +-MODULE_DEVICE_TABLE(i2c, nano_player_i2c_id); +- +-static struct i2c_driver nano_player_i2c_driver = { +- .probe = nano_player_i2c_probe, +- .id_table = nano_player_i2c_id, +- .driver = { +- .name = "nano-player", +- .owner = THIS_MODULE, +- .of_match_table = nano_player_of_match, +- }, +-}; +- +-module_i2c_driver(nano_player_i2c_driver); +- +-MODULE_DESCRIPTION("ASoC 3Dlab Nano Player driver"); +-MODULE_AUTHOR("GT "); +-MODULE_LICENSE("GPL v2"); +- +-/* EOF */ +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -17,12 +17,6 @@ config SND_SOC_CYGNUS + + If you don't know what to do here, say N. + +-config SND_BCM2708_SOC_3DLAB_NANO_PLAYER +- tristate "Support for 3Dlab Nano Player" +- depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +- help +- Say Y or M if you want to add support for 3Dlab Nano Player. +- + config SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD + tristate "Support for Google voiceHAT soundcard" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -12,7 +12,6 @@ obj-$(CONFIG_SND_SOC_CYGNUS) += snd-soc- + snd-soc-googlevoicehat-codec-objs := googlevoicehat-codec.o + + # BCM2708 Machine Support +-snd-soc-3dlab-nano-player-objs := 3dlab-nano-player.o + snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o + snd-soc-hifiberry-dacplusadc-objs := hifiberry_dacplusadc.o + snd-soc-justboom-dac-objs := justboom-dac.o +@@ -20,7 +19,7 @@ snd-soc-rpi-cirrus-objs := rpi-cirrus.o + snd-soc-rpi-proto-objs := rpi-proto.o + snd-soc-iqaudio-codec-objs := iqaudio-codec.o + snd-soc-iqaudio-dac-objs := iqaudio-dac.o +- snd-soc-i-sabre-q2m-objs := i-sabre-q2m.o ++snd-soc-i-sabre-q2m-objs := i-sabre-q2m.o + snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o + snd-soc-audioinjector-octo-soundcard-objs := audioinjector-octo-soundcard.o + snd-soc-audiosense-pi-objs := audiosense-pi.o +@@ -36,7 +35,6 @@ snd-soc-fe-pi-audio-objs := fe-pi-audio. + snd-soc-rpi-simple-soundcard-objs := rpi-simple-soundcard.o + snd-soc-rpi-wm8804-soundcard-objs := rpi-wm8804-soundcard.o + +-obj-$(CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER) += snd-soc-3dlab-nano-player.o + obj-$(CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD) += snd-soc-googlevoicehat-codec.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC) += snd-soc-hifiberry-dacplusadc.o +@@ -45,7 +43,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_RPI_CIRRUS) + obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o + obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_CODEC) += snd-soc-iqaudio-codec.o + obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o +- obj-$(CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M) += snd-soc-i-sabre-q2m.o ++obj-$(CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M) += snd-soc-i-sabre-q2m.o + obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o + obj-$(CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD) += snd-soc-audioinjector-octo-soundcard.o + obj-$(CONFIG_SND_AUDIOSENSE_PI) += snd-soc-audiosense-pi.o diff --git a/target/linux/brcm2708/patches-4.19/950-0498-configs-Enable-PIDs-cgroup.patch b/target/linux/brcm2708/patches-4.19/950-0498-configs-Enable-PIDs-cgroup.patch deleted file mode 100644 index 67c31a54b0..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0498-configs-Enable-PIDs-cgroup.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 8bf83aaaa40f140bc14521ac2f1dd08a8463cc87 Mon Sep 17 00:00:00 2001 -From: Henrique Gontijo -Date: Sun, 12 May 2019 17:11:02 -0700 -Subject: [PATCH 498/703] configs: Enable PIDs cgroup - -My use case to is to allow Kubernetes master to run on Raspberry Pi 3. -Kubernetes introduced [Pid limiting](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/20190129-pid-limiting.md), -on v.1.14.0 which includes [Pod Pids Limit](https://github.com/kubernetes/kubernetes/commit/bce9d5f2043bd86964c9fec80d466e47776071bc) -and [Node Pids Limit](https://github.com/kubernetes/kubernetes/commit/2597a1d97ef4d8f54b1ca661453e32794b756909#diff-fa76bb6ae2d9b4bb3d023737fe5e6029R333) -that requires pids cgroup. - -See: https://github.com/raspberrypi/linux/pull/2968 ---- - arch/arm/configs/bcm2709_defconfig | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -20,6 +20,7 @@ CONFIG_CGROUP_FREEZER=y - CONFIG_CPUSETS=y - CONFIG_CGROUP_DEVICE=y - CONFIG_CGROUP_CPUACCT=y -+CONFIG_CGROUP_PIDS=y - CONFIG_NAMESPACES=y - CONFIG_USER_NS=y - CONFIG_SCHED_AUTOGROUP=y diff --git a/target/linux/brcm2708/patches-4.19/950-0499-.gitignore-Add-.dtbo-explicitly.patch b/target/linux/brcm2708/patches-4.19/950-0499-.gitignore-Add-.dtbo-explicitly.patch new file mode 100644 index 0000000000..665aa71137 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0499-.gitignore-Add-.dtbo-explicitly.patch @@ -0,0 +1,22 @@ +From 08452889f1bd46f4b4f34b915a3095523de1758a Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Tue, 21 May 2019 15:17:33 +0100 +Subject: [PATCH 499/725] .gitignore: Add *.dtbo explicitly + +Signed-off-by: popcornmix +--- + .gitignore | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/.gitignore ++++ b/.gitignore +@@ -15,7 +15,8 @@ + *.bin + *.bz2 + *.c.[012]*.* +-*.dtb* ++*.dtb ++*.dtbo + *.dtb.S + *.dwo + *.elf diff --git a/target/linux/brcm2708/patches-4.19/950-0499-w1-ds2408-reset-on-output_write-retry-with-readback.patch b/target/linux/brcm2708/patches-4.19/950-0499-w1-ds2408-reset-on-output_write-retry-with-readback.patch deleted file mode 100644 index a767102b44..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0499-w1-ds2408-reset-on-output_write-retry-with-readback.patch +++ /dev/null @@ -1,140 +0,0 @@ -From cc87b27a07e5da8d072b3c4e80a3f92cda44e106 Mon Sep 17 00:00:00 2001 -From: Jean-Francois Dagenais -Date: Thu, 28 Mar 2019 12:41:11 -0400 -Subject: [PATCH 499/703] w1: ds2408: reset on output_write retry with readback - -commit 49695ac46861180baf2b2b92c62da8619b6bf28f upstream. - -When we have success in 'Channel Access Write' but reading back latch -states fails, a write is retried without doing a proper slave reset. -This leads to protocol errors as the slave treats the next 'Channel -Access Write' as the continuation of previous command. - -This commit is fixing this by making sure if the retry loop re-runs, a -reset is performed, whatever the failure (CONFIRM_BYTE or the read -back). - -The loop was quite due for a cleanup and this change mandated it. By -isolating the CONFIG_W1_SLAVE_DS2408_READBACK case into it's own -function, we vastly reduce the visual and branching(runtime and -compile-time) noise. - -Reported-by: Mariusz Bialonczyk -Tested-by: Mariusz Bialonczyk -Signed-off-by: Jean-Francois Dagenais -Signed-off-by: Greg Kroah-Hartman ---- - drivers/w1/slaves/w1_ds2408.c | 76 ++++++++++++++++++----------------- - 1 file changed, 39 insertions(+), 37 deletions(-) - ---- a/drivers/w1/slaves/w1_ds2408.c -+++ b/drivers/w1/slaves/w1_ds2408.c -@@ -138,14 +138,37 @@ static ssize_t status_control_read(struc - W1_F29_REG_CONTROL_AND_STATUS, buf); - } - -+#ifdef fCONFIG_W1_SLAVE_DS2408_READBACK -+static bool optional_read_back_valid(struct w1_slave *sl, u8 expected) -+{ -+ u8 w1_buf[3]; -+ -+ if (w1_reset_resume_command(sl->master)) -+ return false; -+ -+ w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS; -+ w1_buf[1] = W1_F29_REG_OUTPUT_LATCH_STATE; -+ w1_buf[2] = 0; -+ -+ w1_write_block(sl->master, w1_buf, 3); -+ -+ return (w1_read_8(sl->master) == expected); -+} -+#else -+static bool optional_read_back_valid(struct w1_slave *sl, u8 expected) -+{ -+ return true; -+} -+#endif -+ - static ssize_t output_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, char *buf, - loff_t off, size_t count) - { - struct w1_slave *sl = kobj_to_w1_slave(kobj); - u8 w1_buf[3]; -- u8 readBack; - unsigned int retries = W1_F29_RETRIES; -+ ssize_t bytes_written = -EIO; - - if (count != 1 || off != 0) - return -EFAULT; -@@ -155,54 +178,33 @@ static ssize_t output_write(struct file - dev_dbg(&sl->dev, "mutex locked"); - - if (w1_reset_select_slave(sl)) -- goto error; -+ goto out; - -- while (retries--) { -+ do { - w1_buf[0] = W1_F29_FUNC_CHANN_ACCESS_WRITE; - w1_buf[1] = *buf; - w1_buf[2] = ~(*buf); -- w1_write_block(sl->master, w1_buf, 3); - -- readBack = w1_read_8(sl->master); -+ w1_write_block(sl->master, w1_buf, 3); - -- if (readBack != W1_F29_SUCCESS_CONFIRM_BYTE) { -- if (w1_reset_resume_command(sl->master)) -- goto error; -- /* try again, the slave is ready for a command */ -- continue; -+ if (w1_read_8(sl->master) == W1_F29_SUCCESS_CONFIRM_BYTE && -+ optional_read_back_valid(sl, *buf)) { -+ bytes_written = 1; -+ goto out; - } - --#ifdef CONFIG_W1_SLAVE_DS2408_READBACK -- /* here the master could read another byte which -- would be the PIO reg (the actual pin logic state) -- since in this driver we don't know which pins are -- in and outs, there's no value to read the state and -- compare. with (*buf) so end this command abruptly: */ - if (w1_reset_resume_command(sl->master)) -- goto error; -+ goto out; /* unrecoverable error */ -+ /* try again, the slave is ready for a command */ -+ } while (--retries); - -- /* go read back the output latches */ -- /* (the direct effect of the write above) */ -- w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS; -- w1_buf[1] = W1_F29_REG_OUTPUT_LATCH_STATE; -- w1_buf[2] = 0; -- w1_write_block(sl->master, w1_buf, 3); -- /* read the result of the READ_PIO_REGS command */ -- if (w1_read_8(sl->master) == *buf) --#endif -- { -- /* success! */ -- mutex_unlock(&sl->master->bus_mutex); -- dev_dbg(&sl->dev, -- "mutex unlocked, retries:%d", retries); -- return 1; -- } -- } --error: -+out: - mutex_unlock(&sl->master->bus_mutex); -- dev_dbg(&sl->dev, "mutex unlocked in error, retries:%d", retries); - -- return -EIO; -+ dev_dbg(&sl->dev, "%s, mutex unlocked retries:%d\n", -+ (bytes_written > 0) ? "succeeded" : "error", retries); -+ -+ return bytes_written; - } - - diff --git a/target/linux/brcm2708/patches-4.19/950-0500-Bluetooth-Check-key-sizes-only-when-Secure-Simple-Pa.patch b/target/linux/brcm2708/patches-4.19/950-0500-Bluetooth-Check-key-sizes-only-when-Secure-Simple-Pa.patch new file mode 100644 index 0000000000..e733f16968 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0500-Bluetooth-Check-key-sizes-only-when-Secure-Simple-Pa.patch @@ -0,0 +1,39 @@ +From 6dec9b770df1f986091eb4e61e829f2d8b2031b1 Mon Sep 17 00:00:00 2001 +From: Marcel Holtmann +Date: Wed, 22 May 2019 09:05:40 +0200 +Subject: [PATCH 500/725] Bluetooth: Check key sizes only when Secure Simple + Pairing is enabled + +The encryption is only mandatory to be enforced when both sides are using +Secure Simple Pairing and this means the key size check makes only sense +in that case. + +On legacy Bluetooth 2.0 and earlier devices like mice the encryption was +optional and thus causing an issue if the key size check is not bound to +using Secure Simple Pairing. + +Fixes: d5bb334a8e17 ("Bluetooth: Align minimum encryption key size for LE and BR/EDR connections") +Signed-off-by: Marcel Holtmann +Cc: stable@vger.kernel.org +--- + net/bluetooth/hci_conn.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -1272,8 +1272,13 @@ int hci_conn_check_link_mode(struct hci_ + return 0; + } + +- if (hci_conn_ssp_enabled(conn) && +- !test_bit(HCI_CONN_ENCRYPT, &conn->flags)) ++ /* If Secure Simple Pairing is not enabled, then legacy connection ++ * setup is used and no encryption or key sizes can be enforced. ++ */ ++ if (!hci_conn_ssp_enabled(conn)) ++ return 1; ++ ++ if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags)) + return 0; + + return 1; diff --git a/target/linux/brcm2708/patches-4.19/950-0500-w1-ds2482-cosmetic-fixes-after-54865314f5a1.patch b/target/linux/brcm2708/patches-4.19/950-0500-w1-ds2482-cosmetic-fixes-after-54865314f5a1.patch deleted file mode 100644 index 6d8277a71f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0500-w1-ds2482-cosmetic-fixes-after-54865314f5a1.patch +++ /dev/null @@ -1,91 +0,0 @@ -From cf423c8b0d5d1fa5cc0c9427b5282aa888b5eaef Mon Sep 17 00:00:00 2001 -From: Mariusz Bialonczyk -Date: Mon, 4 Mar 2019 12:23:36 +0100 -Subject: [PATCH 500/703] w1: ds2482: cosmetic fixes after 54865314f5a1 - -commit 5cb27d30fc3a281e830a2099d520b469e2b82008 upstream. - -We have a helper function ds2482_calculate_config() which is calculating -the config value, so just use it instead of passing the same variable -in all calls to this function. - -Also fixes the placement of module parameters to match with: -50fa2951bd74 (w1: Organize driver source to natural/common order) -by Andrew F. Davis - -Signed-off-by: Mariusz Bialonczyk -Cc: Andrew Worsley -Cc: Andrew F. Davis -Signed-off-by: Greg Kroah-Hartman ---- - drivers/w1/masters/ds2482.c | 18 +++++++++++------- - 1 file changed, 11 insertions(+), 7 deletions(-) - ---- a/drivers/w1/masters/ds2482.c -+++ b/drivers/w1/masters/ds2482.c -@@ -37,6 +37,11 @@ module_param_named(active_pullup, ds2482 - MODULE_PARM_DESC(active_pullup, "Active pullup (apply to all buses): " \ - "0-disable, 1-enable (default)"); - -+/* extra configurations - e.g. 1WS */ -+static int extra_config; -+module_param(extra_config, int, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(extra_config, "Extra Configuration settings 1=APU,2=PPM,3=SPU,8=1WS"); -+ - /** - * The DS2482 registers - there are 3 registers that are addressed by a read - * pointer. The read pointer is set by the last command executed. -@@ -70,8 +75,6 @@ MODULE_PARM_DESC(active_pullup, "Active - #define DS2482_REG_CFG_PPM 0x02 /* presence pulse masking */ - #define DS2482_REG_CFG_APU 0x01 /* active pull-up */ - --/* extra configurations - e.g. 1WS */ --static int extra_config; - - /** - * Write and verify codes for the CHANNEL_SELECT command (DS2482-800 only). -@@ -130,6 +133,8 @@ struct ds2482_data { - */ - static inline u8 ds2482_calculate_config(u8 conf) - { -+ conf |= extra_config; -+ - if (ds2482_active_pullup) - conf |= DS2482_REG_CFG_APU; - -@@ -405,7 +410,7 @@ static u8 ds2482_w1_reset_bus(void *data - /* If the chip did reset since detect, re-config it */ - if (err & DS2482_REG_STS_RST) - ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG, -- ds2482_calculate_config(extra_config)); -+ ds2482_calculate_config(0x00)); - } - - mutex_unlock(&pdev->access_lock); -@@ -431,7 +436,8 @@ static u8 ds2482_w1_set_pullup(void *dat - ds2482_wait_1wire_idle(pdev); - /* note: it seems like both SPU and APU have to be set! */ - retval = ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG, -- ds2482_calculate_config(extra_config|DS2482_REG_CFG_SPU|DS2482_REG_CFG_APU)); -+ ds2482_calculate_config(DS2482_REG_CFG_SPU | -+ DS2482_REG_CFG_APU)); - ds2482_wait_1wire_idle(pdev); - } - -@@ -484,7 +490,7 @@ static int ds2482_probe(struct i2c_clien - - /* Set all config items to 0 (off) */ - ds2482_send_cmd_data(data, DS2482_CMD_WRITE_CONFIG, -- ds2482_calculate_config(extra_config)); -+ ds2482_calculate_config(0x00)); - - mutex_init(&data->access_lock); - -@@ -559,7 +565,5 @@ module_i2c_driver(ds2482_driver); - - MODULE_AUTHOR("Ben Gardner "); - MODULE_DESCRIPTION("DS2482 driver"); --module_param(extra_config, int, S_IRUGO | S_IWUSR); --MODULE_PARM_DESC(extra_config, "Extra Configuration settings 1=APU,2=PPM,3=SPU,8=1WS"); - - MODULE_LICENSE("GPL"); diff --git a/target/linux/brcm2708/patches-4.19/950-0501-sound-pcm512x-codec-Adding-352.8kHz-samplerate-suppo.patch b/target/linux/brcm2708/patches-4.19/950-0501-sound-pcm512x-codec-Adding-352.8kHz-samplerate-suppo.patch deleted file mode 100644 index 146b483938..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0501-sound-pcm512x-codec-Adding-352.8kHz-samplerate-suppo.patch +++ /dev/null @@ -1,21 +0,0 @@ -From d188a0a3472f80003d2558639ebeb41e190a4b9b Mon Sep 17 00:00:00 2001 -From: Klaus Schulz -Date: Thu, 16 May 2019 13:35:32 +0200 -Subject: [PATCH 501/703] sound: pcm512x-codec: Adding 352.8kHz samplerate - support - ---- - sound/soc/codecs/pcm512x.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/sound/soc/codecs/pcm512x.c -+++ b/sound/soc/codecs/pcm512x.c -@@ -542,7 +542,7 @@ static unsigned long pcm512x_ncp_target( - - static const u32 pcm512x_dai_rates[] = { - 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, -- 88200, 96000, 176400, 192000, 384000, -+ 88200, 96000, 176400, 192000, 352800, 384000, - }; - - static const struct snd_pcm_hw_constraint_list constraints_slave = { diff --git a/target/linux/brcm2708/patches-4.19/950-0501-usb-dwc_otg-Clean-up-interrupt-claiming-code.patch b/target/linux/brcm2708/patches-4.19/950-0501-usb-dwc_otg-Clean-up-interrupt-claiming-code.patch new file mode 100644 index 0000000000..85339f5663 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0501-usb-dwc_otg-Clean-up-interrupt-claiming-code.patch @@ -0,0 +1,157 @@ +From f37b215f0ea4180c8befba9fe48626ec8d5bfc41 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 7 May 2019 17:23:41 +0100 +Subject: [PATCH 501/725] usb: dwc_otg: Clean up interrupt claiming code + +The FIQ/IRQ interrupt number identification code is scattered through +the dwc_otg driver. Rationalise it, simplifying the code and solving +an existing issue. + +See: https://github.com/raspberrypi/linux/issues/2612 + +Signed-off-by: Phil Elwell +--- + drivers/usb/host/dwc_otg/dwc_otg_driver.c | 18 +++++++++----- + drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 10 +++----- + drivers/usb/host/dwc_otg/dwc_otg_os_dep.h | 6 +++++ + drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c | 26 +++----------------- + 4 files changed, 25 insertions(+), 35 deletions(-) + +--- a/drivers/usb/host/dwc_otg/dwc_otg_driver.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c +@@ -624,11 +624,7 @@ static int dwc_otg_driver_remove( + * Free the IRQ + */ + if (otg_dev->common_irq_installed) { +-#ifdef PLATFORM_INTERFACE +- free_irq(platform_get_irq(_dev, 0), otg_dev); +-#else +- free_irq(_dev->irq, otg_dev); +-#endif ++ free_irq(otg_dev->os_dep.irq_num, otg_dev); + } else { + DWC_DEBUGPL(DBG_ANY, "%s: There is no installed irq!\n", __func__); + return REM_RETVAL(-ENXIO); +@@ -905,7 +901,9 @@ static int dwc_otg_driver_probe( + */ + + #if defined(PLATFORM_INTERFACE) +- devirq = platform_get_irq(_dev, fiq_enable ? 0 : 1); ++ devirq = platform_get_irq_byname(_dev, fiq_enable ? "soft" : "usb"); ++ if (devirq < 0) ++ devirq = platform_get_irq(_dev, fiq_enable ? 0 : 1); + #else + devirq = _dev->irq; + #endif +@@ -922,6 +920,14 @@ static int dwc_otg_driver_probe( + } else { + dwc_otg_device->common_irq_installed = 1; + } ++ dwc_otg_device->os_dep.irq_num = devirq; ++ dwc_otg_device->os_dep.fiq_num = -EINVAL; ++ if (fiq_enable) { ++ int devfiq = platform_get_irq_byname(_dev, "usb"); ++ if (devfiq < 0) ++ devfiq = platform_get_irq(_dev, 1); ++ dwc_otg_device->os_dep.fiq_num = devfiq; ++ } + + #ifndef IRQF_TRIGGER_LOW + #if defined(LM_INTERFACE) || defined(PLATFORM_INTERFACE) +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c +@@ -492,7 +492,7 @@ static void hcd_init_fiq(void *cookie) + #endif + // Enable FIQ interrupt from USB peripheral + #ifdef CONFIG_ARM64 +- irq = platform_get_irq(otg_dev->os_dep.platformdev, 1); ++ irq = otg_dev->os_dep.fiq_num; + + if (irq < 0) { + DWC_ERROR("Can't get SIM-FIQ irq"); +@@ -509,7 +509,7 @@ static void hcd_init_fiq(void *cookie) + simfiq_irq = irq; + #else + #ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER +- irq = platform_get_irq(otg_dev->os_dep.platformdev, 1); ++ irq = otg_dev->os_dep.fiq_num; + #else + irq = INTERRUPT_VC_USB; + #endif +@@ -626,11 +626,7 @@ int hcd_init(dwc_bus_dev_t *_dev) + * allocates the DMA buffer pool, registers the USB bus, requests the + * IRQ line, and calls hcd_start method. + */ +-#ifdef PLATFORM_INTERFACE +- retval = usb_add_hcd(hcd, platform_get_irq(_dev, fiq_enable ? 0 : 1), IRQF_SHARED); +-#else +- retval = usb_add_hcd(hcd, _dev->irq, IRQF_SHARED); +-#endif ++ retval = usb_add_hcd(hcd, otg_dev->os_dep.irq_num, IRQF_SHARED); + if (retval < 0) { + goto error2; + } +--- a/drivers/usb/host/dwc_otg/dwc_otg_os_dep.h ++++ b/drivers/usb/host/dwc_otg/dwc_otg_os_dep.h +@@ -102,6 +102,12 @@ typedef struct os_dependent { + /** Base address for MPHI peripheral */ + void *mphi_base; + ++ /** IRQ number (<0 if not valid) */ ++ int irq_num; ++ ++ /** FIQ number (<0 if not valid) */ ++ int fiq_num; ++ + #ifdef LM_INTERFACE + struct lm_device *lmdev; + #elif defined(PCI_INTERFACE) +--- a/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c +@@ -1224,30 +1224,16 @@ int pcd_init(dwc_bus_dev_t *_dev) + /* + * Setup interupt handler + */ +-#ifdef PLATFORM_INTERFACE + DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", +- platform_get_irq(_dev, fiq_enable ? 0 : 1)); +- retval = request_irq(platform_get_irq(_dev, fiq_enable ? 0 : 1), dwc_otg_pcd_irq, ++ otg_dev->os_dep.irq_num); ++ retval = request_irq(otg_dev->os_dep.irq_num, dwc_otg_pcd_irq, + IRQF_SHARED, gadget_wrapper->gadget.name, + otg_dev->pcd); + if (retval != 0) { +- DWC_ERROR("request of irq%d failed\n", +- platform_get_irq(_dev, fiq_enable ? 0 : 1)); ++ DWC_ERROR("request of irq%d failed\n", otg_dev->os_dep.irq_num); + free_wrapper(gadget_wrapper); + return -EBUSY; + } +-#else +- DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", +- _dev->irq); +- retval = request_irq(_dev->irq, dwc_otg_pcd_irq, +- IRQF_SHARED | IRQF_DISABLED, +- gadget_wrapper->gadget.name, otg_dev->pcd); +- if (retval != 0) { +- DWC_ERROR("request of irq%d failed\n", _dev->irq); +- free_wrapper(gadget_wrapper); +- return -EBUSY; +- } +-#endif + + dwc_otg_pcd_start(gadget_wrapper->pcd, &fops); + +@@ -1267,11 +1253,7 @@ void pcd_remove(dwc_bus_dev_t *_dev) + /* + * Free the IRQ + */ +-#ifdef PLATFORM_INTERFACE +- free_irq(platform_get_irq(_dev, 0), pcd); +-#else +- free_irq(_dev->irq, pcd); +-#endif ++ free_irq(otg_dev->os_dep.irq_num, pcd); + dwc_otg_pcd_remove(otg_dev->pcd); + free_wrapper(gadget_wrapper); + otg_dev->pcd = 0; diff --git a/target/linux/brcm2708/patches-4.19/950-0502-ASoC-decommissioning-driver-for-3Dlab-Nano-soundcard.patch b/target/linux/brcm2708/patches-4.19/950-0502-ASoC-decommissioning-driver-for-3Dlab-Nano-soundcard.patch deleted file mode 100644 index af2c446285..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0502-ASoC-decommissioning-driver-for-3Dlab-Nano-soundcard.patch +++ /dev/null @@ -1,522 +0,0 @@ -From 4f8dc6c030b1d24c4bf270637eba452ad9b9dd9b Mon Sep 17 00:00:00 2001 -From: GT -Date: Sat, 6 Apr 2019 21:16:39 +0100 -Subject: [PATCH 502/703] ASoC: decommissioning driver for 3Dlab Nano soundcard - ---- - .../overlays/3dlab-nano-player-overlay.dts | 32 -- - arch/arm/boot/dts/overlays/Makefile | 1 - - arch/arm/boot/dts/overlays/README | 6 - - arch/arm/configs/bcm2709_defconfig | 1 - - arch/arm/configs/bcmrpi_defconfig | 1 - - sound/soc/bcm/3dlab-nano-player.c | 370 ------------------ - sound/soc/bcm/Kconfig | 6 - - sound/soc/bcm/Makefile | 6 +- - 8 files changed, 2 insertions(+), 421 deletions(-) - delete mode 100644 arch/arm/boot/dts/overlays/3dlab-nano-player-overlay.dts - delete mode 100644 sound/soc/bcm/3dlab-nano-player.c - ---- a/arch/arm/boot/dts/overlays/3dlab-nano-player-overlay.dts -+++ /dev/null -@@ -1,32 +0,0 @@ --// Definitions for 3Dlab Nano Player --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&i2s>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@1 { -- target = <&i2c>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- nano-player@41 { -- compatible = "3dlab,nano-player"; -- reg = <0x41>; -- i2s-controller = <&i2s>; -- status = "okay"; -- }; -- }; -- }; --}; -- --// EOF ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -1,7 +1,6 @@ - # Overlays for the Raspberry Pi platform - - dtbo-$(CONFIG_ARCH_BCM2835) += \ -- 3dlab-nano-player.dtbo \ - adau1977-adc.dtbo \ - adau7002-simple.dtbo \ - ads1015.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -205,12 +205,6 @@ Params: - and the other i2c baudrate parameters. - - --Name: 3dlab-nano-player --Info: Configures the 3Dlab Nano Player --Load: dtoverlay=3dlab-nano-player --Params: -- -- - Name: adau1977-adc - Info: Overlay for activation of ADAU1977 ADC codec over I2C for control - and I2S for data. ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -908,7 +908,6 @@ CONFIG_SND_USB_6FIRE=m - CONFIG_SND_USB_HIFACE=m - CONFIG_SND_SOC=m - CONFIG_SND_BCM2835_SOC_I2S=m --CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER=m - CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -900,7 +900,6 @@ CONFIG_SND_USB_6FIRE=m - CONFIG_SND_USB_HIFACE=m - CONFIG_SND_SOC=m - CONFIG_SND_BCM2835_SOC_I2S=m --CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER=m - CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m - CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m ---- a/sound/soc/bcm/3dlab-nano-player.c -+++ /dev/null -@@ -1,370 +0,0 @@ --/* -- * 3Dlab Nano Player ALSA SoC Audio driver. -- * -- * Copyright (C) 2018 3Dlab. -- * -- * Author: GT -- * -- * 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 --#include --#include --#include --#include --#include -- --#define NANO_ID 0x00 --#define NANO_VER 0x01 --#define NANO_CFG 0x02 --#define NANO_STATUS 0x03 --#define NANO_SPI_ADDR 0x04 --#define NANO_SPI_DATA 0x05 -- --#define NANO_ID_VAL 0x3D --#define NANO_CFG_OFF 0x00 --#define NANO_CFG_MULT1 0 --#define NANO_CFG_MULT2 1 --#define NANO_CFG_MULT4 2 --#define NANO_CFG_MULT8 3 --#define NANO_CFG_MULT16 4 --#define NANO_CFG_CLK22 0 --#define NANO_CFG_CLK24 BIT(3) --#define NANO_CFG_DSD BIT(4) --#define NANO_CFG_ENA BIT(5) --#define NANO_CFG_BLINK BIT(6) --#define NANO_STATUS_P1 BIT(0) --#define NANO_STATUS_P2 BIT(1) --#define NANO_STATUS_FLG BIT(2) --#define NANO_STATUS_CLK BIT(3) --#define NANO_SPI_READ 0 --#define NANO_SPI_WRITE BIT(5) -- --#define NANO_DAC_CTRL1 0x00 --#define NANO_DAC_CTRL2 0x01 --#define NANO_DAC_CTRL3 0x02 --#define NANO_DAC_LATT 0x03 --#define NANO_DAC_RATT 0x04 -- --#define NANO_CTRL2_VAL 0x22 -- --static int nano_player_spi_write(struct regmap *map, -- unsigned int reg, unsigned int val) --{ -- /* indirect register access */ -- regmap_write(map, NANO_SPI_DATA, val); -- regmap_write(map, NANO_SPI_ADDR, reg | NANO_SPI_WRITE); -- return 0; --} -- --static int nano_player_ctrl_info(struct snd_kcontrol *kcontrol, -- struct snd_ctl_elem_info *uinfo) --{ -- /* describe control element */ -- if (strstr(kcontrol->id.name, "Volume")) { -- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; -- uinfo->count = 1; -- uinfo->value.integer.min = 0; -- uinfo->value.integer.max = 100; -- } else { -- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; -- uinfo->count = 1; -- uinfo->value.integer.min = 0; -- uinfo->value.integer.max = 1; -- } -- -- return 0; --} -- --static int nano_player_ctrl_put(struct snd_kcontrol *kcontrol, -- struct snd_ctl_elem_value *ucontrol) --{ -- /* program control value to hardware */ -- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); -- struct regmap *regmap = snd_soc_card_get_drvdata(card); -- -- if (strstr(kcontrol->id.name, "Volume")) { -- unsigned int vol = ucontrol->value.integer.value[0]; -- unsigned int att = 255 - (2 * (100 - vol)); -- -- nano_player_spi_write(regmap, NANO_DAC_LATT, att); -- nano_player_spi_write(regmap, NANO_DAC_RATT, att); -- kcontrol->private_value = vol; -- } else { -- unsigned int mute = ucontrol->value.integer.value[0]; -- unsigned int reg = NANO_CTRL2_VAL | mute; -- -- nano_player_spi_write(regmap, NANO_DAC_CTRL2, reg); -- kcontrol->private_value = mute; -- } -- return 0; --} -- --static int nano_player_ctrl_get(struct snd_kcontrol *kcontrol, -- struct snd_ctl_elem_value *ucontrol) --{ -- /* return last programmed value */ -- ucontrol->value.integer.value[0] = kcontrol->private_value; -- return 0; --} -- --#define SOC_NANO_PLAYER_CTRL(xname) \ --{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ -- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ -- .info = nano_player_ctrl_info, \ -- .put = nano_player_ctrl_put, \ -- .get = nano_player_ctrl_get } -- --static const struct snd_kcontrol_new nano_player_controls[] = { -- SOC_NANO_PLAYER_CTRL("Master Playback Volume"), -- SOC_NANO_PLAYER_CTRL("Master Playback Switch"), --}; -- --static const unsigned int nano_player_rates[] = { -- 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, -- 705600, 768000 /* only possible with fast clocks */ --}; -- --static struct snd_pcm_hw_constraint_list nano_player_constraint_rates = { -- .list = nano_player_rates, -- .count = ARRAY_SIZE(nano_player_rates), --}; -- --static int nano_player_init(struct snd_soc_pcm_runtime *rtd) --{ -- struct snd_soc_card *card = rtd->card; -- struct regmap *regmap = snd_soc_card_get_drvdata(card); -- struct snd_soc_pcm_stream *cpu = &rtd->cpu_dai->driver->playback; -- struct snd_soc_pcm_stream *codec = &rtd->codec_dai->driver->playback; -- unsigned int sample_bits = 32; -- unsigned int val; -- -- /* configure cpu dai */ -- cpu->formats |= SNDRV_PCM_FMTBIT_DSD_U32_LE; -- cpu->rate_max = 768000; -- -- /* configure dummy codec dai */ -- codec->rate_min = 44100; -- codec->rates = SNDRV_PCM_RATE_KNOT; -- codec->formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_DSD_U32_LE; -- -- /* configure max supported rate */ -- regmap_read(regmap, NANO_STATUS, &val); -- if (val & NANO_STATUS_CLK) { -- dev_notice(card->dev, "Board with fast clocks installed\n"); -- codec->rate_max = 768000; -- } else { -- dev_notice(card->dev, "Board with normal clocks installed\n"); -- codec->rate_max = 384000; -- } -- -- /* frame length enforced by hardware */ -- return snd_soc_dai_set_bclk_ratio(rtd->cpu_dai, sample_bits * 2); --} -- --static int nano_player_startup(struct snd_pcm_substream *substream) --{ -- return snd_pcm_hw_constraint_list(substream->runtime, 0, -- SNDRV_PCM_HW_PARAM_RATE, -- &nano_player_constraint_rates); --} -- --static int nano_player_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_card *card = rtd->card; -- struct regmap *regmap = snd_soc_card_get_drvdata(card); -- unsigned int config = NANO_CFG_ENA; -- struct snd_mask *fmt; -- -- /* configure PCM or DSD */ -- fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); -- if (snd_mask_test(fmt, SNDRV_PCM_FORMAT_DSD_U32_LE)) { -- /* embed DSD in PCM data */ -- snd_mask_none(fmt); -- snd_mask_set(fmt, SNDRV_PCM_FORMAT_S32_LE); -- /* enable DSD mode */ -- config |= NANO_CFG_DSD; -- } -- -- /* configure clocks */ -- switch (params_rate(params)) { -- case 44100: -- config |= NANO_CFG_MULT1 | NANO_CFG_CLK22; -- break; -- case 88200: -- config |= NANO_CFG_MULT2 | NANO_CFG_CLK22; -- break; -- case 176400: -- config |= NANO_CFG_MULT4 | NANO_CFG_CLK22; -- break; -- case 352800: -- config |= NANO_CFG_MULT8 | NANO_CFG_CLK22; -- break; -- case 705600: -- config |= NANO_CFG_MULT16 | NANO_CFG_CLK22; -- break; -- case 48000: -- config |= NANO_CFG_MULT1 | NANO_CFG_CLK24; -- break; -- case 96000: -- config |= NANO_CFG_MULT2 | NANO_CFG_CLK24; -- break; -- case 192000: -- config |= NANO_CFG_MULT4 | NANO_CFG_CLK24; -- break; -- case 384000: -- config |= NANO_CFG_MULT8 | NANO_CFG_CLK24; -- break; -- case 768000: -- config |= NANO_CFG_MULT16 | NANO_CFG_CLK24; -- break; -- default: -- return -EINVAL; -- } -- -- dev_dbg(card->dev, "Send CFG register 0x%02X\n", config); -- return regmap_write(regmap, NANO_CFG, config); --} -- --static struct snd_soc_ops nano_player_ops = { -- .startup = nano_player_startup, -- .hw_params = nano_player_hw_params, --}; -- --static struct snd_soc_dai_link nano_player_link = { -- .name = "3Dlab Nano Player", -- .stream_name = "3Dlab Nano Player HiFi", -- .platform_name = "bcm2708-i2s.0", -- .cpu_dai_name = "bcm2708-i2s.0", -- .codec_name = "snd-soc-dummy", -- .codec_dai_name = "snd-soc-dummy-dai", -- .dai_fmt = SND_SOC_DAIFMT_I2S | -- SND_SOC_DAIFMT_CONT | -- SND_SOC_DAIFMT_NB_NF | -- SND_SOC_DAIFMT_CBM_CFM, -- .init = nano_player_init, -- .ops = &nano_player_ops, --}; -- --static const struct regmap_config nano_player_regmap = { -- .reg_bits = 8, -- .val_bits = 8, -- .max_register = 128, -- .cache_type = REGCACHE_RBTREE, --}; -- --static int nano_player_card_probe(struct snd_soc_card *card) --{ -- struct regmap *regmap = snd_soc_card_get_drvdata(card); -- unsigned int val; -- -- /* check hardware integrity */ -- regmap_read(regmap, NANO_ID, &val); -- if (val != NANO_ID_VAL) { -- dev_err(card->dev, "Invalid ID register 0x%02X\n", val); -- return -ENODEV; -- } -- -- /* report version to the user */ -- regmap_read(regmap, NANO_VER, &val); -- dev_notice(card->dev, "Started 3Dlab Nano Player driver (v%d)\n", val); -- -- /* enable internal audio bus and blink status LED */ -- return regmap_write(regmap, NANO_CFG, NANO_CFG_ENA | NANO_CFG_BLINK); --} -- --static int nano_player_card_remove(struct snd_soc_card *card) --{ -- /* disable internal audio bus */ -- struct regmap *regmap = snd_soc_card_get_drvdata(card); -- -- return regmap_write(regmap, NANO_CFG, NANO_CFG_OFF); --} -- --static struct snd_soc_card nano_player_card = { -- .name = "3Dlab_Nano_Player", -- .owner = THIS_MODULE, -- .dai_link = &nano_player_link, -- .num_links = 1, -- .controls = nano_player_controls, -- .num_controls = ARRAY_SIZE(nano_player_controls), -- .probe = nano_player_card_probe, -- .remove = nano_player_card_remove, --}; -- --static int nano_player_i2c_probe(struct i2c_client *i2c, -- const struct i2c_device_id *id) --{ -- struct regmap *regmap; -- int ret; -- -- regmap = devm_regmap_init_i2c(i2c, &nano_player_regmap); -- if (IS_ERR(regmap)) { -- ret = PTR_ERR(regmap); -- dev_err(&i2c->dev, "Failed to init regmap %d\n", ret); -- return ret; -- } -- -- if (i2c->dev.of_node) { -- struct snd_soc_dai_link *dai = &nano_player_link; -- struct device_node *node; -- -- /* cpu handle configured by device tree */ -- node = of_parse_phandle(i2c->dev.of_node, "i2s-controller", 0); -- if (node) { -- dai->platform_name = NULL; -- dai->platform_of_node = node; -- dai->cpu_dai_name = NULL; -- dai->cpu_of_node = node; -- } -- } -- -- nano_player_card.dev = &i2c->dev; -- snd_soc_card_set_drvdata(&nano_player_card, regmap); -- ret = devm_snd_soc_register_card(&i2c->dev, &nano_player_card); -- -- if (ret && ret != -EPROBE_DEFER) -- dev_err(&i2c->dev, "Failed to register card %d\n", ret); -- -- return ret; --} -- --static const struct of_device_id nano_player_of_match[] = { -- { .compatible = "3dlab,nano-player", }, -- { } --}; --MODULE_DEVICE_TABLE(of, nano_player_of_match); -- --static const struct i2c_device_id nano_player_i2c_id[] = { -- { "nano-player", 0 }, -- { } --}; --MODULE_DEVICE_TABLE(i2c, nano_player_i2c_id); -- --static struct i2c_driver nano_player_i2c_driver = { -- .probe = nano_player_i2c_probe, -- .id_table = nano_player_i2c_id, -- .driver = { -- .name = "nano-player", -- .owner = THIS_MODULE, -- .of_match_table = nano_player_of_match, -- }, --}; -- --module_i2c_driver(nano_player_i2c_driver); -- --MODULE_DESCRIPTION("ASoC 3Dlab Nano Player driver"); --MODULE_AUTHOR("GT "); --MODULE_LICENSE("GPL v2"); -- --/* EOF */ ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -17,12 +17,6 @@ config SND_SOC_CYGNUS - - If you don't know what to do here, say N. - --config SND_BCM2708_SOC_3DLAB_NANO_PLAYER -- tristate "Support for 3Dlab Nano Player" -- depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S -- help -- Say Y or M if you want to add support for 3Dlab Nano Player. -- - config SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD - tristate "Support for Google voiceHAT soundcard" - depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -12,7 +12,6 @@ obj-$(CONFIG_SND_SOC_CYGNUS) += snd-soc- - snd-soc-googlevoicehat-codec-objs := googlevoicehat-codec.o - - # BCM2708 Machine Support --snd-soc-3dlab-nano-player-objs := 3dlab-nano-player.o - snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o - snd-soc-hifiberry-dacplusadc-objs := hifiberry_dacplusadc.o - snd-soc-justboom-dac-objs := justboom-dac.o -@@ -20,7 +19,7 @@ snd-soc-rpi-cirrus-objs := rpi-cirrus.o - snd-soc-rpi-proto-objs := rpi-proto.o - snd-soc-iqaudio-codec-objs := iqaudio-codec.o - snd-soc-iqaudio-dac-objs := iqaudio-dac.o -- snd-soc-i-sabre-q2m-objs := i-sabre-q2m.o -+snd-soc-i-sabre-q2m-objs := i-sabre-q2m.o - snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o - snd-soc-audioinjector-octo-soundcard-objs := audioinjector-octo-soundcard.o - snd-soc-audiosense-pi-objs := audiosense-pi.o -@@ -36,7 +35,6 @@ snd-soc-fe-pi-audio-objs := fe-pi-audio. - snd-soc-rpi-simple-soundcard-objs := rpi-simple-soundcard.o - snd-soc-rpi-wm8804-soundcard-objs := rpi-wm8804-soundcard.o - --obj-$(CONFIG_SND_BCM2708_SOC_3DLAB_NANO_PLAYER) += snd-soc-3dlab-nano-player.o - obj-$(CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD) += snd-soc-googlevoicehat-codec.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC) += snd-soc-hifiberry-dacplusadc.o -@@ -45,7 +43,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_RPI_CIRRUS) - obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o - obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_CODEC) += snd-soc-iqaudio-codec.o - obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o -- obj-$(CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M) += snd-soc-i-sabre-q2m.o -+obj-$(CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M) += snd-soc-i-sabre-q2m.o - obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o - obj-$(CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD) += snd-soc-audioinjector-octo-soundcard.o - obj-$(CONFIG_SND_AUDIOSENSE_PI) += snd-soc-audiosense-pi.o diff --git a/target/linux/brcm2708/patches-4.19/950-0502-overlays-Delete-the-deprecated-sdio-1bit-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0502-overlays-Delete-the-deprecated-sdio-1bit-overlay.patch new file mode 100644 index 0000000000..67f35bcf53 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0502-overlays-Delete-the-deprecated-sdio-1bit-overlay.patch @@ -0,0 +1,90 @@ +From c8bf649a93e00e411c9d52d8ba7902b0984a7c3e Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 7 May 2019 14:27:35 +0100 +Subject: [PATCH 502/725] overlays: Delete the deprecated sdio-1bit overlay + +Use dtoverlay=sdio,bus_width=1,gpios_22_25 instead. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/Makefile | 1 - + .../boot/dts/overlays/sdio-1bit-overlay.dts | 63 ------------------- + 2 files changed, 64 deletions(-) + delete mode 100644 arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -126,7 +126,6 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + sc16is752-spi1.dtbo \ + sdhost.dtbo \ + sdio.dtbo \ +- sdio-1bit.dtbo \ + sdtweak.dtbo \ + smi.dtbo \ + smi-dev.dtbo \ +--- a/arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts ++++ /dev/null +@@ -1,63 +0,0 @@ +-/dts-v1/; +-/plugin/; +- +-/* Enable 1-bit SDIO from MMC interface via GPIOs 22-25. Includes sdhost overlay. */ +- +-/{ +- compatible = "brcm,bcm2708"; +- +- fragment@0 { +- target = <&mmc>; +- __overlay__ { +- status = "disabled"; +- }; +- }; +- +- fragment@1 { +- target = <&soc>; +- __overlay__ { +- #address-cells = <1>; +- #size-cells = <1>; +- +- sdio_1bit: sdio@7e300000 { +- compatible = "brcm,bcm2835-mmc", +- "brcm,bcm2835-sdhci"; +- reg = <0x7e300000 0x100>; +- interrupts = <2 30>; +- clocks = <&clocks 28/*BCM2835_CLOCK_EMMC*/>; +- dmas = <&dma 11>; +- dma-names = "rx-tx"; +- brcm,overclock-50 = <0>; +- status = "okay"; +- pinctrl-names = "default"; +- pinctrl-0 = <&sdio_1bit_pins>; +- non-removable; +- bus-width = <1>; +- }; +- }; +- }; +- +- fragment@2 { +- target = <&gpio>; +- __overlay__ { +- sdio_1bit_pins: sdio_1bit_pins { +- brcm,pins = <22 23 24 25>; +- brcm,function = <7>; /* ALT3 = SD1 */ +- brcm,pull = <0 2 2 2>; +- }; +- }; +- }; +- +- fragment@3 { +- target-path = "/aliases"; +- __overlay__ { +- mmc1 = "/soc/sdio@7e300000"; +- }; +- }; +- +- +- __overrides__ { +- poll_once = <&sdio_1bit>,"non-removable?"; +- sdio_overclock = <&sdio_1bit>,"brcm,overclock-50:0"; +- }; +-}; diff --git a/target/linux/brcm2708/patches-4.19/950-0503-.gitignore-Add-.dtbo-explicitly.patch b/target/linux/brcm2708/patches-4.19/950-0503-.gitignore-Add-.dtbo-explicitly.patch deleted file mode 100644 index 6131800835..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0503-.gitignore-Add-.dtbo-explicitly.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 44cadbedb79dbbae0cea7dd008bcf2583570e883 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 21 May 2019 15:17:33 +0100 -Subject: [PATCH 503/703] .gitignore: Add *.dtbo explicitly - -Signed-off-by: popcornmix ---- - .gitignore | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/.gitignore -+++ b/.gitignore -@@ -15,7 +15,8 @@ - *.bin - *.bz2 - *.c.[012]*.* --*.dtb* -+*.dtb -+*.dtbo - *.dtb.S - *.dwo - *.elf diff --git a/target/linux/brcm2708/patches-4.19/950-0503-overlays-Remove-upstream-aux-interrupt-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0503-overlays-Remove-upstream-aux-interrupt-overlay.patch new file mode 100644 index 0000000000..1d9e80fdf8 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0503-overlays-Remove-upstream-aux-interrupt-overlay.patch @@ -0,0 +1,97 @@ +From 23a2fa493ee4e0734e7cf7402527889a5752548b Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 7 May 2019 10:06:04 +0100 +Subject: [PATCH 503/725] overlays: Remove upstream-aux-interrupt overlay + +We no longer have a downstream-specific auxilliary interrupt +driver, so the overlay to disable it is no longer needed. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/Makefile | 1 - + arch/arm/boot/dts/overlays/README | 12 +++---- + .../upstream-aux-interrupt-overlay.dts | 33 ------------------- + .../boot/dts/overlays/upstream-overlay.dts | 2 +- + 4 files changed, 6 insertions(+), 42 deletions(-) + delete mode 100644 arch/arm/boot/dts/overlays/upstream-aux-interrupt-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -151,7 +151,6 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + uart1.dtbo \ + udrc.dtbo \ + upstream.dtbo \ +- upstream-aux-interrupt.dtbo \ + vc4-fkms-v3d.dtbo \ + vc4-kms-kippah-7inch.dtbo \ + vc4-kms-v3d.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -2206,18 +2206,16 @@ Params: alsaname Name of + + + Name: upstream +-Info: Allow usage of downstream .dtb with upstream kernel. Comprises +- vc4-kms-v3d, dwc2 and upstream-aux-interrupt overlays. ++Info: Allow usage of downstream .dtb with upstream kernel. Comprises the ++ vc4-kms-v3d and dwc2 overlays. + Load: dtoverlay=upstream + Params: + + + Name: upstream-aux-interrupt +-Info: Allow usage of downstream .dtb with upstream kernel by binding AUX +- devices directly to the shared AUX interrupt line. One of the parts +- of the 'upstream' overlay +-Load: dtoverlay=upstream-aux-interrupt +-Params: ++Info: This overlay has been deprecated and removed because it is no longer ++ necessary. ++Load: + + + Name: vc4-fkms-v3d +--- a/arch/arm/boot/dts/overlays/upstream-aux-interrupt-overlay.dts ++++ /dev/null +@@ -1,33 +0,0 @@ +-// Overlay for missing AUX interrupt controller +-// Instead we bind all AUX devices to the generic AUX interrupt line +-/dts-v1/; +-/plugin/; +- +-/ { +- compatible = "brcm,bcm2708"; +- +- fragment@0 { +- target = <&uart1>; +- __overlay__ { +- interrupt-parent = <&intc>; +- interrupts = <0x1 0x1d>; +- }; +- }; +- +- fragment@1 { +- target = <&spi1>; +- __overlay__ { +- interrupt-parent = <&intc>; +- interrupts = <0x1 0x1d>; +- }; +- }; +- +- fragment@2 { +- target = <&spi2>; +- __overlay__ { +- interrupt-parent = <&intc>; +- interrupts = <0x1 0x1d>; +- }; +- }; +-}; +- +--- a/arch/arm/boot/dts/overlays/upstream-overlay.dts ++++ b/arch/arm/boot/dts/overlays/upstream-overlay.dts +@@ -1,4 +1,4 @@ +-// redo: ovmerge -c vc4-kms-v3d-overlay.dts,cma-96 dwc2-overlay.dts,dr_mode=otg upstream-aux-interrupt-overlay.dts, ++// redo: ovmerge -c vc4-kms-v3d-overlay.dts,cma-96 dwc2-overlay.dts,dr_mode=otg + + /dts-v1/; + /plugin/; diff --git a/target/linux/brcm2708/patches-4.19/950-0504-Bluetooth-Check-key-sizes-only-when-Secure-Simple-Pa.patch b/target/linux/brcm2708/patches-4.19/950-0504-Bluetooth-Check-key-sizes-only-when-Secure-Simple-Pa.patch deleted file mode 100644 index 8e8fa07ad7..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0504-Bluetooth-Check-key-sizes-only-when-Secure-Simple-Pa.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0b83f023796a12b822191c29b4313b161d68fbe7 Mon Sep 17 00:00:00 2001 -From: Marcel Holtmann -Date: Wed, 22 May 2019 09:05:40 +0200 -Subject: [PATCH 504/703] Bluetooth: Check key sizes only when Secure Simple - Pairing is enabled - -The encryption is only mandatory to be enforced when both sides are using -Secure Simple Pairing and this means the key size check makes only sense -in that case. - -On legacy Bluetooth 2.0 and earlier devices like mice the encryption was -optional and thus causing an issue if the key size check is not bound to -using Secure Simple Pairing. - -Fixes: d5bb334a8e17 ("Bluetooth: Align minimum encryption key size for LE and BR/EDR connections") -Signed-off-by: Marcel Holtmann -Cc: stable@vger.kernel.org ---- - net/bluetooth/hci_conn.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - ---- a/net/bluetooth/hci_conn.c -+++ b/net/bluetooth/hci_conn.c -@@ -1272,8 +1272,13 @@ int hci_conn_check_link_mode(struct hci_ - return 0; - } - -- if (hci_conn_ssp_enabled(conn) && -- !test_bit(HCI_CONN_ENCRYPT, &conn->flags)) -+ /* If Secure Simple Pairing is not enabled, then legacy connection -+ * setup is used and no encryption or key sizes can be enforced. -+ */ -+ if (!hci_conn_ssp_enabled(conn)) -+ return 1; -+ -+ if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags)) - return 0; - - return 1; diff --git a/target/linux/brcm2708/patches-4.19/950-0504-overlays-Standardise-on-compatible-brcm-bcm2835.patch b/target/linux/brcm2708/patches-4.19/950-0504-overlays-Standardise-on-compatible-brcm-bcm2835.patch new file mode 100644 index 0000000000..89e5ad3884 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0504-overlays-Standardise-on-compatible-brcm-bcm2835.patch @@ -0,0 +1,1767 @@ +From d5c9e73f36c946e403d408b08d7360f227c75837 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 14 May 2019 13:33:05 +0100 +Subject: [PATCH 504/725] overlays: Standardise on compatible="brcm,bcm2835" + +Curb the proliferation of compatible string combinations by +standardising on "brcm,bcm2835" to denote BCM2835 and its descendants. + +As nothing in the firmware or kernel is checking overlay compatible +strings, this should be a purely cosmetic change. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/adau1977-adc-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/adau7002-simple-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/ads1015-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/ads1115-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/ads7846-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/adv7282m-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/adv728x-m-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts | 2 +- + .../boot/dts/overlays/allo-boss-dac-pcm512x-audio-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/allo-digione-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/allo-katana-dac-audio-overlay.dts | 2 +- + .../boot/dts/overlays/allo-piano-dac-pcm512x-audio-overlay.dts | 2 +- + .../dts/overlays/allo-piano-dac-plus-pcm512x-audio-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/applepi-dac-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/at86rf233-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/audioinjector-ultra-overlay.dts | 2 +- + .../boot/dts/overlays/audioinjector-wm8731-audio-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/audiosense-pi-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/audremap-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/balena-fin-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/dht11-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/dionaudio-loco-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/dpi18-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/dpi24-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/draws-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/dwc-otg-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/dwc2-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/enc28j60-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/enc28j60-spi2-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/exc3000-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/goodix-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/googlevoicehat-soundcard-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/gpio-fan-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/gpio-ir-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/gpio-ir-tx-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/gpio-key-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/gpio-shutdown-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/hifiberry-dacplusadc-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/hy28a-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/hy28b-2017-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/hy28b-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/i-sabre-q2m-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/i2c-bcm2708-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/i2c-mux-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/i2s-gpio28-31-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/ilitek251x-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts | 2 +- + .../arm/boot/dts/overlays/iqaudio-digi-wm8804-audio-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/jedec-spi-nor-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/justboom-dac-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/justboom-digi-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/max98357a-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/mbed-dac-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/mcp23017-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/mcp23s17-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/mcp3008-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/mcp3202-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/mcp342x-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/media-center-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/mmc-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/mpu6050-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/mz61581-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/ov5647-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/papirus-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/pibell-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/piglow-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/piscreen-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/piscreen2r-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/pisound-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/pitft22-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/pitft35-resistive-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/pps-gpio-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/pwm-ir-tx-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/qca7000-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/rotary-encoder-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/rpi-cirrus-wm5102-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/rpi-dac-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/rpi-poe-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/rpi-proto-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/rpi-sense-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/rpi-tv-overlay.dts | 2 +- + .../arm/boot/dts/overlays/rra-digidac1-wm8741-audio-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/sc16is752-spi1-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/sdhost-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/sdio-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/sdtweak-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/smi-nand-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/smi-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/spi-rtc-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/spi0-cs-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/spi0-hw-cs-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/ssd1306-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/superaudioboard-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/sx150x-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/tc358743-audio-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/tc358743-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/tpm-slb9670-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/uart0-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/uart1-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/udrc-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/upstream-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/vc4-fkms-v3d-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/vc4-kms-kippah-7inch-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/vga666-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/w1-gpio-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/wittypi-overlay.dts | 2 +- + 146 files changed, 146 insertions(+), 146 deletions(-) + +--- a/arch/arm/boot/dts/overlays/adau1977-adc-overlay.dts ++++ b/arch/arm/boot/dts/overlays/adau1977-adc-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c>; +--- a/arch/arm/boot/dts/overlays/adau7002-simple-overlay.dts ++++ b/arch/arm/boot/dts/overlays/adau7002-simple-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/ads1015-overlay.dts ++++ b/arch/arm/boot/dts/overlays/ads1015-overlay.dts +@@ -5,7 +5,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + /* ----------- ADS1015 ------------ */ + fragment@0 { + target = <&i2c_arm>; +--- a/arch/arm/boot/dts/overlays/ads1115-overlay.dts ++++ b/arch/arm/boot/dts/overlays/ads1115-overlay.dts +@@ -6,7 +6,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c_arm>; +--- a/arch/arm/boot/dts/overlays/ads7846-overlay.dts ++++ b/arch/arm/boot/dts/overlays/ads7846-overlay.dts +@@ -7,7 +7,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/adv7282m-overlay.dts ++++ b/arch/arm/boot/dts/overlays/adv7282m-overlay.dts +@@ -4,7 +4,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c_vc>; +--- a/arch/arm/boot/dts/overlays/adv728x-m-overlay.dts ++++ b/arch/arm/boot/dts/overlays/adv728x-m-overlay.dts +@@ -5,7 +5,7 @@ + #include "adv7282m-overlay.dts" + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + // Fragment numbers deliberately high to avoid conflicts with the + // included adv7282m overlay file. +--- a/arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts ++++ b/arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/allo-boss-dac-pcm512x-audio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/allo-boss-dac-pcm512x-audio-overlay.dts +@@ -6,7 +6,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/clocks"; +--- a/arch/arm/boot/dts/overlays/allo-digione-overlay.dts ++++ b/arch/arm/boot/dts/overlays/allo-digione-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/allo-katana-dac-audio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/allo-katana-dac-audio-overlay.dts +@@ -6,7 +6,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/allo-piano-dac-pcm512x-audio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/allo-piano-dac-pcm512x-audio-overlay.dts +@@ -13,7 +13,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/allo-piano-dac-plus-pcm512x-audio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/allo-piano-dac-plus-pcm512x-audio-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/applepi-dac-overlay.dts ++++ b/arch/arm/boot/dts/overlays/applepi-dac-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&sound>; +--- a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts ++++ b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts +@@ -4,7 +4,7 @@ + /* Overlay for Atmel AT86RF233 IEEE 802.15.4 WPAN transceiver on spi0.0 */ + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts ++++ b/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/audioinjector-ultra-overlay.dts ++++ b/arch/arm/boot/dts/overlays/audioinjector-ultra-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/audioinjector-wm8731-audio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/audioinjector-wm8731-audio-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/audiosense-pi-overlay.dts ++++ b/arch/arm/boot/dts/overlays/audiosense-pi-overlay.dts +@@ -5,7 +5,7 @@ + #include + + / { +- compatible = "brcm,bcm2837", "brcm,bcm2836", "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/audremap-overlay.dts ++++ b/arch/arm/boot/dts/overlays/audremap-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&audio_pins>; +--- a/arch/arm/boot/dts/overlays/balena-fin-overlay.dts ++++ b/arch/arm/boot/dts/overlays/balena-fin-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&mmc>; +--- a/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts ++++ b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c_arm>; +--- a/arch/arm/boot/dts/overlays/dht11-overlay.dts ++++ b/arch/arm/boot/dts/overlays/dht11-overlay.dts +@@ -5,7 +5,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/"; +--- a/arch/arm/boot/dts/overlays/dionaudio-loco-overlay.dts ++++ b/arch/arm/boot/dts/overlays/dionaudio-loco-overlay.dts +@@ -8,7 +8,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts ++++ b/arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts +@@ -9,7 +9,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&sound>; +--- a/arch/arm/boot/dts/overlays/dpi18-overlay.dts ++++ b/arch/arm/boot/dts/overlays/dpi18-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + // There is no DPI driver module, but we need a platform device + // node (that doesn't already use pinctrl) to hang the pinctrl +--- a/arch/arm/boot/dts/overlays/dpi24-overlay.dts ++++ b/arch/arm/boot/dts/overlays/dpi24-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + // There is no DPI driver module, but we need a platform device + // node (that doesn't already use pinctrl) to hang the pinctrl +--- a/arch/arm/boot/dts/overlays/draws-overlay.dts ++++ b/arch/arm/boot/dts/overlays/draws-overlay.dts +@@ -7,7 +7,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + fragment@0 { + target = <&i2s>; + __overlay__ { +--- a/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts ++++ b/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&usb>; +--- a/arch/arm/boot/dts/overlays/dwc2-overlay.dts ++++ b/arch/arm/boot/dts/overlays/dwc2-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&usb>; +--- a/arch/arm/boot/dts/overlays/enc28j60-overlay.dts ++++ b/arch/arm/boot/dts/overlays/enc28j60-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/enc28j60-spi2-overlay.dts ++++ b/arch/arm/boot/dts/overlays/enc28j60-spi2-overlay.dts +@@ -4,7 +4,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi2>; +--- a/arch/arm/boot/dts/overlays/exc3000-overlay.dts ++++ b/arch/arm/boot/dts/overlays/exc3000-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&gpio>; +--- a/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&clocks>; +--- a/arch/arm/boot/dts/overlays/goodix-overlay.dts ++++ b/arch/arm/boot/dts/overlays/goodix-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&gpio>; +--- a/arch/arm/boot/dts/overlays/googlevoicehat-soundcard-overlay.dts ++++ b/arch/arm/boot/dts/overlays/googlevoicehat-soundcard-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/gpio-fan-overlay.dts ++++ b/arch/arm/boot/dts/overlays/gpio-fan-overlay.dts +@@ -38,7 +38,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/"; +--- a/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts ++++ b/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/"; +--- a/arch/arm/boot/dts/overlays/gpio-ir-tx-overlay.dts ++++ b/arch/arm/boot/dts/overlays/gpio-ir-tx-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&gpio>; +--- a/arch/arm/boot/dts/overlays/gpio-key-overlay.dts ++++ b/arch/arm/boot/dts/overlays/gpio-key-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + // Configure the gpio pin controller +--- a/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts ++++ b/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/"; +--- a/arch/arm/boot/dts/overlays/gpio-shutdown-overlay.dts ++++ b/arch/arm/boot/dts/overlays/gpio-shutdown-overlay.dts +@@ -10,7 +10,7 @@ + // note that GPIO3 has an external pullup on at least some boards). + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + // Configure the gpio pin controller +--- a/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts ++++ b/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts ++++ b/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts ++++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/clocks"; +--- a/arch/arm/boot/dts/overlays/hifiberry-dacplusadc-overlay.dts ++++ b/arch/arm/boot/dts/overlays/hifiberry-dacplusadc-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/clocks"; +--- a/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts ++++ b/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts ++++ b/arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/hy28a-overlay.dts ++++ b/arch/arm/boot/dts/overlays/hy28a-overlay.dts +@@ -7,7 +7,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/hy28b-2017-overlay.dts ++++ b/arch/arm/boot/dts/overlays/hy28b-2017-overlay.dts +@@ -7,7 +7,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/hy28b-overlay.dts ++++ b/arch/arm/boot/dts/overlays/hy28b-overlay.dts +@@ -7,7 +7,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/i-sabre-q2m-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i-sabre-q2m-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&sound>; +--- a/arch/arm/boot/dts/overlays/i2c-bcm2708-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-bcm2708-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c_arm>; +--- a/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/"; +--- a/arch/arm/boot/dts/overlays/i2c-mux-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-mux-overlay.dts +@@ -4,7 +4,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c_arm>; +--- a/arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c_arm>; +--- a/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts +@@ -4,7 +4,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/"; +--- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c_arm>; +--- a/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c_arm>; +--- a/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts +@@ -9,7 +9,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c0>; +--- a/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts +@@ -9,7 +9,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c1>; +--- a/arch/arm/boot/dts/overlays/i2s-gpio28-31-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2s-gpio28-31-overlay.dts +@@ -6,7 +6,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s_pins>; +--- a/arch/arm/boot/dts/overlays/ilitek251x-overlay.dts ++++ b/arch/arm/boot/dts/overlays/ilitek251x-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&gpio>; +--- a/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts ++++ b/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts ++++ b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/iqaudio-digi-wm8804-audio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/iqaudio-digi-wm8804-audio-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/jedec-spi-nor-overlay.dts ++++ b/arch/arm/boot/dts/overlays/jedec-spi-nor-overlay.dts +@@ -13,7 +13,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + // disable spi-dev on spi0.0 + fragment@0 { +--- a/arch/arm/boot/dts/overlays/justboom-dac-overlay.dts ++++ b/arch/arm/boot/dts/overlays/justboom-dac-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/justboom-digi-overlay.dts ++++ b/arch/arm/boot/dts/overlays/justboom-digi-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/max98357a-overlay.dts ++++ b/arch/arm/boot/dts/overlays/max98357a-overlay.dts +@@ -8,7 +8,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + /* Enable I2S */ + fragment@0 { +--- a/arch/arm/boot/dts/overlays/mbed-dac-overlay.dts ++++ b/arch/arm/boot/dts/overlays/mbed-dac-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/mcp23017-overlay.dts ++++ b/arch/arm/boot/dts/overlays/mcp23017-overlay.dts +@@ -4,7 +4,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c1>; +--- a/arch/arm/boot/dts/overlays/mcp23s17-overlay.dts ++++ b/arch/arm/boot/dts/overlays/mcp23s17-overlay.dts +@@ -20,7 +20,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + // disable spi-dev on spi0.0 + fragment@0 { +--- a/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts ++++ b/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts +@@ -6,7 +6,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + /* disable spi-dev for spi0.0 */ + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts ++++ b/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts +@@ -6,7 +6,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + /* disable spi-dev for spi0.1 */ + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/mcp3008-overlay.dts ++++ b/arch/arm/boot/dts/overlays/mcp3008-overlay.dts +@@ -6,7 +6,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spidev0>; +--- a/arch/arm/boot/dts/overlays/mcp3202-overlay.dts ++++ b/arch/arm/boot/dts/overlays/mcp3202-overlay.dts +@@ -6,7 +6,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spidev0>; +--- a/arch/arm/boot/dts/overlays/mcp342x-overlay.dts ++++ b/arch/arm/boot/dts/overlays/mcp342x-overlay.dts +@@ -4,7 +4,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c1>; +--- a/arch/arm/boot/dts/overlays/media-center-overlay.dts ++++ b/arch/arm/boot/dts/overlays/media-center-overlay.dts +@@ -7,7 +7,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/mmc-overlay.dts ++++ b/arch/arm/boot/dts/overlays/mmc-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&mmc>; +--- a/arch/arm/boot/dts/overlays/mpu6050-overlay.dts ++++ b/arch/arm/boot/dts/overlays/mpu6050-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c1>; +--- a/arch/arm/boot/dts/overlays/mz61581-overlay.dts ++++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts +@@ -7,7 +7,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/ov5647-overlay.dts ++++ b/arch/arm/boot/dts/overlays/ov5647-overlay.dts +@@ -4,7 +4,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c_vc>; +--- a/arch/arm/boot/dts/overlays/papirus-overlay.dts ++++ b/arch/arm/boot/dts/overlays/papirus-overlay.dts +@@ -4,7 +4,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c_arm>; +--- a/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts ++++ b/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts +@@ -11,7 +11,7 @@ + */ + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&act_led>; +--- a/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts ++++ b/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts +@@ -9,7 +9,7 @@ + */ + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&uart1>; +--- a/arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts ++++ b/arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&mmc>; +--- a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts ++++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts +@@ -16,7 +16,7 @@ + */ + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&uart0>; +--- a/arch/arm/boot/dts/overlays/pibell-overlay.dts ++++ b/arch/arm/boot/dts/overlays/pibell-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/"; +--- a/arch/arm/boot/dts/overlays/piglow-overlay.dts ++++ b/arch/arm/boot/dts/overlays/piglow-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c_arm>; +--- a/arch/arm/boot/dts/overlays/piscreen-overlay.dts ++++ b/arch/arm/boot/dts/overlays/piscreen-overlay.dts +@@ -7,7 +7,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts ++++ b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts +@@ -7,7 +7,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/pisound-overlay.dts ++++ b/arch/arm/boot/dts/overlays/pisound-overlay.dts +@@ -23,7 +23,7 @@ + #include + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/pitft22-overlay.dts ++++ b/arch/arm/boot/dts/overlays/pitft22-overlay.dts +@@ -7,7 +7,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts ++++ b/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts +@@ -7,7 +7,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts ++++ b/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts +@@ -7,7 +7,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/pitft35-resistive-overlay.dts ++++ b/arch/arm/boot/dts/overlays/pitft35-resistive-overlay.dts +@@ -7,7 +7,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + fragment@0 { + target-path = "/"; + __overlay__ { +--- a/arch/arm/boot/dts/overlays/pwm-ir-tx-overlay.dts ++++ b/arch/arm/boot/dts/overlays/pwm-ir-tx-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&gpio>; +--- a/arch/arm/boot/dts/overlays/qca7000-overlay.dts ++++ b/arch/arm/boot/dts/overlays/qca7000-overlay.dts +@@ -5,7 +5,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spidev0>; +--- a/arch/arm/boot/dts/overlays/rotary-encoder-overlay.dts ++++ b/arch/arm/boot/dts/overlays/rotary-encoder-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&gpio>; +--- a/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts ++++ b/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts +@@ -6,7 +6,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/"; +--- a/arch/arm/boot/dts/overlays/rpi-cirrus-wm5102-overlay.dts ++++ b/arch/arm/boot/dts/overlays/rpi-cirrus-wm5102-overlay.dts +@@ -6,7 +6,7 @@ + #include + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts ++++ b/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/rpi-display-overlay.dts ++++ b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts +@@ -7,7 +7,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts ++++ b/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/"; +--- a/arch/arm/boot/dts/overlays/rpi-poe-overlay.dts ++++ b/arch/arm/boot/dts/overlays/rpi-poe-overlay.dts +@@ -5,7 +5,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/"; +--- a/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts ++++ b/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts ++++ b/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c1>; +--- a/arch/arm/boot/dts/overlays/rpi-tv-overlay.dts ++++ b/arch/arm/boot/dts/overlays/rpi-tv-overlay.dts +@@ -4,7 +4,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spidev0>; +--- a/arch/arm/boot/dts/overlays/rra-digidac1-wm8741-audio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/rra-digidac1-wm8741-audio-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c_arm>; +--- a/arch/arm/boot/dts/overlays/sc16is752-spi1-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sc16is752-spi1-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&gpio>; +--- a/arch/arm/boot/dts/overlays/sdhost-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts +@@ -4,7 +4,7 @@ + /* Provide backwards compatible aliases for the old sdhost dtparams. */ + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&sdhost>; +--- a/arch/arm/boot/dts/overlays/sdio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts +@@ -4,7 +4,7 @@ + /* Enable SDIO from MMC interface via GPIOs 22-27. Includes sdhost overlay. */ + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&mmc>; +--- a/arch/arm/boot/dts/overlays/sdtweak-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sdtweak-overlay.dts +@@ -4,7 +4,7 @@ + /* Provide backwards compatible aliases for the old sdhost dtparams. */ + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&sdhost>; +--- a/arch/arm/boot/dts/overlays/smi-nand-overlay.dts ++++ b/arch/arm/boot/dts/overlays/smi-nand-overlay.dts +@@ -6,7 +6,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&smi>; +--- a/arch/arm/boot/dts/overlays/smi-overlay.dts ++++ b/arch/arm/boot/dts/overlays/smi-overlay.dts +@@ -5,7 +5,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&smi>; +--- a/arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts ++++ b/arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts +@@ -6,7 +6,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/spi-rtc-overlay.dts ++++ b/arch/arm/boot/dts/overlays/spi-rtc-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spidev0>; +--- a/arch/arm/boot/dts/overlays/spi0-cs-overlay.dts ++++ b/arch/arm/boot/dts/overlays/spi0-cs-overlay.dts +@@ -3,7 +3,7 @@ + + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0_cs_pins>; +--- a/arch/arm/boot/dts/overlays/spi0-hw-cs-overlay.dts ++++ b/arch/arm/boot/dts/overlays/spi0-hw-cs-overlay.dts +@@ -6,7 +6,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts ++++ b/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts +@@ -3,7 +3,7 @@ + + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&gpio>; +--- a/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts ++++ b/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts +@@ -3,7 +3,7 @@ + + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&gpio>; +--- a/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts ++++ b/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts +@@ -3,7 +3,7 @@ + + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&gpio>; +--- a/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts ++++ b/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts +@@ -3,7 +3,7 @@ + + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&gpio>; +--- a/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts ++++ b/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts +@@ -3,7 +3,7 @@ + + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&gpio>; +--- a/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts ++++ b/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts +@@ -3,7 +3,7 @@ + + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&gpio>; +--- a/arch/arm/boot/dts/overlays/ssd1306-overlay.dts ++++ b/arch/arm/boot/dts/overlays/ssd1306-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2718"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c1>; +--- a/arch/arm/boot/dts/overlays/superaudioboard-overlay.dts ++++ b/arch/arm/boot/dts/overlays/superaudioboard-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&sound>; +--- a/arch/arm/boot/dts/overlays/sx150x-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sx150x-overlay.dts +@@ -22,7 +22,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + // Enable I2C#0 interface + fragment@0 { +--- a/arch/arm/boot/dts/overlays/tc358743-audio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/tc358743-audio-overlay.dts +@@ -5,7 +5,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2s>; +--- a/arch/arm/boot/dts/overlays/tc358743-overlay.dts ++++ b/arch/arm/boot/dts/overlays/tc358743-overlay.dts +@@ -4,7 +4,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&i2c_vc>; +--- a/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts ++++ b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts +@@ -24,7 +24,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/tpm-slb9670-overlay.dts ++++ b/arch/arm/boot/dts/overlays/tpm-slb9670-overlay.dts +@@ -8,7 +8,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&spi0>; +--- a/arch/arm/boot/dts/overlays/uart0-overlay.dts ++++ b/arch/arm/boot/dts/overlays/uart0-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&uart0>; +--- a/arch/arm/boot/dts/overlays/uart1-overlay.dts ++++ b/arch/arm/boot/dts/overlays/uart1-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&uart1>; +--- a/arch/arm/boot/dts/overlays/udrc-overlay.dts ++++ b/arch/arm/boot/dts/overlays/udrc-overlay.dts +@@ -7,7 +7,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + fragment@0 { + target = <&i2s>; + __overlay__ { +--- a/arch/arm/boot/dts/overlays/upstream-overlay.dts ++++ b/arch/arm/boot/dts/overlays/upstream-overlay.dts +@@ -6,7 +6,7 @@ + #include + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + fragment@0 { + target-path = "/chosen"; + __dormant__ { +--- a/arch/arm/boot/dts/overlays/vc4-fkms-v3d-overlay.dts ++++ b/arch/arm/boot/dts/overlays/vc4-fkms-v3d-overlay.dts +@@ -6,7 +6,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/chosen"; +--- a/arch/arm/boot/dts/overlays/vc4-kms-kippah-7inch-overlay.dts ++++ b/arch/arm/boot/dts/overlays/vc4-kms-kippah-7inch-overlay.dts +@@ -8,7 +8,7 @@ + #include + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/"; +--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts ++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts +@@ -8,7 +8,7 @@ + #include + + / { +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/chosen"; +--- a/arch/arm/boot/dts/overlays/vga666-overlay.dts ++++ b/arch/arm/boot/dts/overlays/vga666-overlay.dts +@@ -2,7 +2,7 @@ + /plugin/; + + /{ +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + // There is no VGA driver module, but we need a platform device + // node (that doesn't already use pinctrl) to hang the pinctrl +--- a/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/"; +--- a/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts ++++ b/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts +@@ -3,7 +3,7 @@ + /plugin/; + + / { +- compatible = "brcm,bcm2708"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target-path = "/"; +--- a/arch/arm/boot/dts/overlays/wittypi-overlay.dts ++++ b/arch/arm/boot/dts/overlays/wittypi-overlay.dts +@@ -8,7 +8,7 @@ + + / { + +- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ compatible = "brcm,bcm2835"; + + fragment@0 { + target = <&leds>; diff --git a/target/linux/brcm2708/patches-4.19/950-0505-usb-dwc_otg-Clean-up-interrupt-claiming-code.patch b/target/linux/brcm2708/patches-4.19/950-0505-usb-dwc_otg-Clean-up-interrupt-claiming-code.patch deleted file mode 100644 index e6795b4bf6..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0505-usb-dwc_otg-Clean-up-interrupt-claiming-code.patch +++ /dev/null @@ -1,157 +0,0 @@ -From 6ed82a6ca0e146b20e1d09dc7ec9d31706fc85c5 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 7 May 2019 17:23:41 +0100 -Subject: [PATCH 505/703] usb: dwc_otg: Clean up interrupt claiming code - -The FIQ/IRQ interrupt number identification code is scattered through -the dwc_otg driver. Rationalise it, simplifying the code and solving -an existing issue. - -See: https://github.com/raspberrypi/linux/issues/2612 - -Signed-off-by: Phil Elwell ---- - drivers/usb/host/dwc_otg/dwc_otg_driver.c | 18 +++++++++----- - drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 10 +++----- - drivers/usb/host/dwc_otg/dwc_otg_os_dep.h | 6 +++++ - drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c | 26 +++----------------- - 4 files changed, 25 insertions(+), 35 deletions(-) - ---- a/drivers/usb/host/dwc_otg/dwc_otg_driver.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -@@ -624,11 +624,7 @@ static int dwc_otg_driver_remove( - * Free the IRQ - */ - if (otg_dev->common_irq_installed) { --#ifdef PLATFORM_INTERFACE -- free_irq(platform_get_irq(_dev, 0), otg_dev); --#else -- free_irq(_dev->irq, otg_dev); --#endif -+ free_irq(otg_dev->os_dep.irq_num, otg_dev); - } else { - DWC_DEBUGPL(DBG_ANY, "%s: There is no installed irq!\n", __func__); - return REM_RETVAL(-ENXIO); -@@ -905,7 +901,9 @@ static int dwc_otg_driver_probe( - */ - - #if defined(PLATFORM_INTERFACE) -- devirq = platform_get_irq(_dev, fiq_enable ? 0 : 1); -+ devirq = platform_get_irq_byname(_dev, fiq_enable ? "soft" : "usb"); -+ if (devirq < 0) -+ devirq = platform_get_irq(_dev, fiq_enable ? 0 : 1); - #else - devirq = _dev->irq; - #endif -@@ -922,6 +920,14 @@ static int dwc_otg_driver_probe( - } else { - dwc_otg_device->common_irq_installed = 1; - } -+ dwc_otg_device->os_dep.irq_num = devirq; -+ dwc_otg_device->os_dep.fiq_num = -EINVAL; -+ if (fiq_enable) { -+ int devfiq = platform_get_irq_byname(_dev, "usb"); -+ if (devfiq < 0) -+ devfiq = platform_get_irq(_dev, 1); -+ dwc_otg_device->os_dep.fiq_num = devfiq; -+ } - - #ifndef IRQF_TRIGGER_LOW - #if defined(LM_INTERFACE) || defined(PLATFORM_INTERFACE) ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -@@ -492,7 +492,7 @@ static void hcd_init_fiq(void *cookie) - #endif - // Enable FIQ interrupt from USB peripheral - #ifdef CONFIG_ARM64 -- irq = platform_get_irq(otg_dev->os_dep.platformdev, 1); -+ irq = otg_dev->os_dep.fiq_num; - - if (irq < 0) { - DWC_ERROR("Can't get SIM-FIQ irq"); -@@ -509,7 +509,7 @@ static void hcd_init_fiq(void *cookie) - simfiq_irq = irq; - #else - #ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER -- irq = platform_get_irq(otg_dev->os_dep.platformdev, 1); -+ irq = otg_dev->os_dep.fiq_num; - #else - irq = INTERRUPT_VC_USB; - #endif -@@ -626,11 +626,7 @@ int hcd_init(dwc_bus_dev_t *_dev) - * allocates the DMA buffer pool, registers the USB bus, requests the - * IRQ line, and calls hcd_start method. - */ --#ifdef PLATFORM_INTERFACE -- retval = usb_add_hcd(hcd, platform_get_irq(_dev, fiq_enable ? 0 : 1), IRQF_SHARED); --#else -- retval = usb_add_hcd(hcd, _dev->irq, IRQF_SHARED); --#endif -+ retval = usb_add_hcd(hcd, otg_dev->os_dep.irq_num, IRQF_SHARED); - if (retval < 0) { - goto error2; - } ---- a/drivers/usb/host/dwc_otg/dwc_otg_os_dep.h -+++ b/drivers/usb/host/dwc_otg/dwc_otg_os_dep.h -@@ -102,6 +102,12 @@ typedef struct os_dependent { - /** Base address for MPHI peripheral */ - void *mphi_base; - -+ /** IRQ number (<0 if not valid) */ -+ int irq_num; -+ -+ /** FIQ number (<0 if not valid) */ -+ int fiq_num; -+ - #ifdef LM_INTERFACE - struct lm_device *lmdev; - #elif defined(PCI_INTERFACE) ---- a/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c -@@ -1224,30 +1224,16 @@ int pcd_init(dwc_bus_dev_t *_dev) - /* - * Setup interupt handler - */ --#ifdef PLATFORM_INTERFACE - DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", -- platform_get_irq(_dev, fiq_enable ? 0 : 1)); -- retval = request_irq(platform_get_irq(_dev, fiq_enable ? 0 : 1), dwc_otg_pcd_irq, -+ otg_dev->os_dep.irq_num); -+ retval = request_irq(otg_dev->os_dep.irq_num, dwc_otg_pcd_irq, - IRQF_SHARED, gadget_wrapper->gadget.name, - otg_dev->pcd); - if (retval != 0) { -- DWC_ERROR("request of irq%d failed\n", -- platform_get_irq(_dev, fiq_enable ? 0 : 1)); -+ DWC_ERROR("request of irq%d failed\n", otg_dev->os_dep.irq_num); - free_wrapper(gadget_wrapper); - return -EBUSY; - } --#else -- DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", -- _dev->irq); -- retval = request_irq(_dev->irq, dwc_otg_pcd_irq, -- IRQF_SHARED | IRQF_DISABLED, -- gadget_wrapper->gadget.name, otg_dev->pcd); -- if (retval != 0) { -- DWC_ERROR("request of irq%d failed\n", _dev->irq); -- free_wrapper(gadget_wrapper); -- return -EBUSY; -- } --#endif - - dwc_otg_pcd_start(gadget_wrapper->pcd, &fops); - -@@ -1267,11 +1253,7 @@ void pcd_remove(dwc_bus_dev_t *_dev) - /* - * Free the IRQ - */ --#ifdef PLATFORM_INTERFACE -- free_irq(platform_get_irq(_dev, 0), pcd); --#else -- free_irq(_dev->irq, pcd); --#endif -+ free_irq(otg_dev->os_dep.irq_num, pcd); - dwc_otg_pcd_remove(otg_dev->pcd); - free_wrapper(gadget_wrapper); - otg_dev->pcd = 0; diff --git a/target/linux/brcm2708/patches-4.19/950-0505-vc4-Remove-interrupt-and-DMA-trampling.patch b/target/linux/brcm2708/patches-4.19/950-0505-vc4-Remove-interrupt-and-DMA-trampling.patch new file mode 100644 index 0000000000..06aeabfeec --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0505-vc4-Remove-interrupt-and-DMA-trampling.patch @@ -0,0 +1,121 @@ +From 4014add8e56b0169d767f6feb99ab9387bdd1c2b Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 22 May 2019 12:58:47 +0100 +Subject: [PATCH 505/725] vc4: Remove interrupt and DMA trampling + +As part of the effort to clean up the overlays, remove the interrupt +and DMA mask declarations from the vc4 overlays which just duplicate +that which is in the base DTBs. + +Signed-off-by: Phil Elwell +--- + .../boot/dts/overlays/vc4-fkms-v3d-overlay.dts | 8 -------- + .../boot/dts/overlays/vc4-kms-v3d-overlay.dts | 18 ++---------------- + 2 files changed, 2 insertions(+), 24 deletions(-) + +--- a/arch/arm/boot/dts/overlays/vc4-fkms-v3d-overlay.dts ++++ b/arch/arm/boot/dts/overlays/vc4-fkms-v3d-overlay.dts +@@ -60,7 +60,6 @@ + fragment@7 { + target = <&v3d>; + __overlay__ { +- interrupts = <1 10>; + status = "okay"; + }; + }; +@@ -72,13 +71,6 @@ + }; + }; + +- fragment@9 { +- target-path = "/soc/dma"; +- __overlay__ { +- brcm,dma-channel-mask = <0x7f35>; +- }; +- }; +- + __overrides__ { + cma-256 = <0>,"+0-1-2-3-4"; + cma-192 = <0>,"-0+1-2-3-4"; +--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts ++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts +@@ -62,7 +62,6 @@ + fragment@7 { + target = <&pixelvalve0>; + __overlay__ { +- interrupts = <2 13>; /* pwa0 */ + status = "okay"; + }; + }; +@@ -70,7 +69,6 @@ + fragment@8 { + target = <&pixelvalve1>; + __overlay__ { +- interrupts = <2 14>; /* pwa1 */ + status = "okay"; + }; + }; +@@ -78,7 +76,6 @@ + fragment@9 { + target = <&pixelvalve2>; + __overlay__ { +- interrupts = <2 10>; /* pixelvalve */ + status = "okay"; + }; + }; +@@ -86,7 +83,6 @@ + fragment@10 { + target = <&hvs>; + __overlay__ { +- interrupts = <2 1>; + status = "okay"; + }; + }; +@@ -94,7 +90,6 @@ + fragment@11 { + target = <&hdmi>; + __overlay__ { +- interrupts = <2 8>, <2 9>; + status = "okay"; + }; + }; +@@ -102,7 +97,6 @@ + fragment@12 { + target = <&v3d>; + __overlay__ { +- interrupts = <1 10>; + status = "okay"; + }; + }; +@@ -115,14 +109,6 @@ + }; + + fragment@14 { +- target-path = "/soc/dma"; +- __overlay__ { +- brcm,dma-channel-mask = <0x7f35>; +- }; +- }; +- +- +- fragment@15 { + target = <&clocks>; + __overlay__ { + claim-clocks = < +@@ -134,14 +120,14 @@ + }; + }; + +- fragment@16 { ++ fragment@15 { + target = <&vec>; + __overlay__ { + status = "okay"; + }; + }; + +- fragment@17 { ++ fragment@16 { + target = <&txp>; + __overlay__ { + status = "okay"; diff --git a/target/linux/brcm2708/patches-4.19/950-0506-BCM270X_DT-Add-non-removable-clone-of-mmc-node.patch b/target/linux/brcm2708/patches-4.19/950-0506-BCM270X_DT-Add-non-removable-clone-of-mmc-node.patch new file mode 100644 index 0000000000..cd662f1539 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0506-BCM270X_DT-Add-non-removable-clone-of-mmc-node.patch @@ -0,0 +1,206 @@ +From 7530f75c6f8207751821a72a5da3ee8d275921f3 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 7 May 2019 14:29:38 +0100 +Subject: [PATCH 506/725] BCM270X_DT: Add non-removable clone of mmc node + +non-removable is a boolean property, and as such can't be unset by an +overlay if it is set in a base DTB. Until now the workaround for this +problem has been for overlays to clone non-removable nodes without +the offending property, but this involves a lot of unnecessary +replication. Instead, add a clone of the mmc node with non-removable +already set to the base DTB, selecting the required version using +the status properties. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/bcm2708-rpi-0-w.dts | 4 +-- + arch/arm/boot/dts/bcm2708-rpi.dtsi | 3 +- + arch/arm/boot/dts/bcm270x.dtsi | 13 ++++++++ + arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 5 ++-- + arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 5 ++-- + arch/arm/boot/dts/overlays/mmc-overlay.dts | 7 +++++ + arch/arm/boot/dts/overlays/sdio-overlay.dts | 33 +++++++-------------- + 7 files changed, 38 insertions(+), 32 deletions(-) + +--- a/arch/arm/boot/dts/bcm2708-rpi-0-w.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-0-w.dts +@@ -14,6 +14,7 @@ + aliases { + serial0 = &uart1; + serial1 = &uart0; ++ mmc1 = &mmcnr; + }; + }; + +@@ -73,10 +74,9 @@ + }; + }; + +-&mmc { ++&mmcnr { + pinctrl-names = "default"; + pinctrl-0 = <&sdio_pins>; +- non-removable; + bus-width = <4>; + status = "okay"; + }; +--- a/arch/arm/boot/dts/bcm2708-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2708-rpi.dtsi +@@ -118,7 +118,8 @@ + sd_force_pio = <&sdhost>,"brcm,force-pio?"; + sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; + sd_debug = <&sdhost>,"brcm,debug"; +- sdio_overclock = <&mmc>,"brcm,overclock-50:0"; ++ sdio_overclock = <&mmc>,"brcm,overclock-50:0", ++ <&mmcnr>,"brcm,overclock-50:0"; + axiperf = <&axiperf>,"status"; + }; + }; +--- a/arch/arm/boot/dts/bcm270x.dtsi ++++ b/arch/arm/boot/dts/bcm270x.dtsi +@@ -79,6 +79,19 @@ + status = "disabled"; + }; + ++ /* A clone of mmc but with non-removable set */ ++ mmcnr: mmcnr@7e300000 { ++ compatible = "brcm,bcm2835-mmc", "brcm,bcm2835-sdhci"; ++ reg = <0x7e300000 0x100>; ++ interrupts = <2 30>; ++ clocks = <&clocks BCM2835_CLOCK_EMMC>; ++ dmas = <&dma 11>; ++ dma-names = "rx-tx"; ++ brcm,overclock-50 = <0>; ++ non-removable; ++ status = "disabled"; ++ }; ++ + hvs: hvs@7e400000 { + /* Add alias */ + status = "disabled"; +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts +@@ -15,6 +15,7 @@ + aliases { + serial0 = &uart1; + serial1 = &uart0; ++ mmc1 = &mmcnr; + }; + }; + +@@ -74,13 +75,11 @@ + }; + }; + +-&mmc { ++&mmcnr { + pinctrl-names = "default"; + pinctrl-0 = <&sdio_pins>; +- non-removable; + bus-width = <4>; + status = "okay"; +- brcm,overclock-50 = <0>; + }; + + &firmware { +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +@@ -15,6 +15,7 @@ + aliases { + serial0 = &uart1; + serial1 = &uart0; ++ mmc1 = &mmcnr; + }; + }; + +@@ -74,13 +75,11 @@ + }; + }; + +-&mmc { ++&mmcnr { + pinctrl-names = "default"; + pinctrl-0 = <&sdio_pins>; +- non-removable; + bus-width = <4>; + status = "okay"; +- brcm,overclock-50 = <0>; + }; + + &soc { +--- a/arch/arm/boot/dts/overlays/mmc-overlay.dts ++++ b/arch/arm/boot/dts/overlays/mmc-overlay.dts +@@ -33,6 +33,13 @@ + }; + }; + ++ fragment@3 { ++ target = <&mmcnr>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ + __overrides__ { + overclock_50 = <&frag0>,"brcm,overclock-50:0"; + }; +--- a/arch/arm/boot/dts/overlays/sdio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts +@@ -1,39 +1,26 @@ + /dts-v1/; + /plugin/; + +-/* Enable SDIO from MMC interface via GPIOs 22-27. Includes sdhost overlay. */ ++/* Enable SDIO from MMC interface via various GPIO groups */ + + /{ + compatible = "brcm,bcm2835"; + + fragment@0 { +- target = <&mmc>; ++ target = <&mmcnr>; + __overlay__ { + status = "disabled"; + }; + }; + + fragment@1 { +- target = <&soc>; +- __overlay__ { +- #address-cells = <1>; +- #size-cells = <1>; +- +- sdio_ovl: sdio@7e300000 { +- compatible = "brcm,bcm2835-mmc", +- "brcm,bcm2835-sdhci"; +- reg = <0x7e300000 0x100>; +- interrupts = <2 30>; +- clocks = <&clocks 28/*BCM2835_CLOCK_EMMC*/>; +- dmas = <&dma 11>; +- dma-names = "rx-tx"; +- brcm,overclock-50 = <0>; +- status = "okay"; +- pinctrl-names = "default"; +- pinctrl-0 = <&sdio_ovl_pins>; +- non-removable; +- bus-width = <4>; +- }; ++ target = <&mmc>; ++ sdio_ovl: __overlay__ { ++ pinctrl-0 = <&sdio_ovl_pins>; ++ pinctrl-names = "default"; ++ non-removable; ++ bus-width = <4>; ++ status = "okay"; + }; + }; + +@@ -75,7 +62,7 @@ + fragment@6 { + target-path = "/aliases"; + __overlay__ { +- mmc1 = "/soc/sdio@7e300000"; ++ mmc1 = "/soc/mmc@7e300000"; + }; + }; + diff --git a/target/linux/brcm2708/patches-4.19/950-0506-overlays-Delete-the-deprecated-sdio-1bit-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0506-overlays-Delete-the-deprecated-sdio-1bit-overlay.patch deleted file mode 100644 index 23c02dba11..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0506-overlays-Delete-the-deprecated-sdio-1bit-overlay.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 039ab199d862424e77a9f5a8b431453a36d6af7c Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 7 May 2019 14:27:35 +0100 -Subject: [PATCH 506/703] overlays: Delete the deprecated sdio-1bit overlay - -Use dtoverlay=sdio,bus_width=1,gpios_22_25 instead. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/Makefile | 1 - - .../boot/dts/overlays/sdio-1bit-overlay.dts | 63 ------------------- - 2 files changed, 64 deletions(-) - delete mode 100644 arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -126,7 +126,6 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - sc16is752-spi1.dtbo \ - sdhost.dtbo \ - sdio.dtbo \ -- sdio-1bit.dtbo \ - sdtweak.dtbo \ - smi.dtbo \ - smi-dev.dtbo \ ---- a/arch/arm/boot/dts/overlays/sdio-1bit-overlay.dts -+++ /dev/null -@@ -1,63 +0,0 @@ --/dts-v1/; --/plugin/; -- --/* Enable 1-bit SDIO from MMC interface via GPIOs 22-25. Includes sdhost overlay. */ -- --/{ -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&mmc>; -- __overlay__ { -- status = "disabled"; -- }; -- }; -- -- fragment@1 { -- target = <&soc>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <1>; -- -- sdio_1bit: sdio@7e300000 { -- compatible = "brcm,bcm2835-mmc", -- "brcm,bcm2835-sdhci"; -- reg = <0x7e300000 0x100>; -- interrupts = <2 30>; -- clocks = <&clocks 28/*BCM2835_CLOCK_EMMC*/>; -- dmas = <&dma 11>; -- dma-names = "rx-tx"; -- brcm,overclock-50 = <0>; -- status = "okay"; -- pinctrl-names = "default"; -- pinctrl-0 = <&sdio_1bit_pins>; -- non-removable; -- bus-width = <1>; -- }; -- }; -- }; -- -- fragment@2 { -- target = <&gpio>; -- __overlay__ { -- sdio_1bit_pins: sdio_1bit_pins { -- brcm,pins = <22 23 24 25>; -- brcm,function = <7>; /* ALT3 = SD1 */ -- brcm,pull = <0 2 2 2>; -- }; -- }; -- }; -- -- fragment@3 { -- target-path = "/aliases"; -- __overlay__ { -- mmc1 = "/soc/sdio@7e300000"; -- }; -- }; -- -- -- __overrides__ { -- poll_once = <&sdio_1bit>,"non-removable?"; -- sdio_overclock = <&sdio_1bit>,"brcm,overclock-50:0"; -- }; --}; diff --git a/target/linux/brcm2708/patches-4.19/950-0507-BCM270X_DT-usb-Refactor-DTS-and-overlays.patch b/target/linux/brcm2708/patches-4.19/950-0507-BCM270X_DT-usb-Refactor-DTS-and-overlays.patch new file mode 100644 index 0000000000..4d662b6aff --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0507-BCM270X_DT-usb-Refactor-DTS-and-overlays.patch @@ -0,0 +1,60 @@ +From 7a56bb870785b5cb85a5902c32b23f956f1a1287 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 8 May 2019 10:08:31 +0100 +Subject: [PATCH 507/725] BCM270X_DT: usb: Refactor DTS and overlays + +Move the IRQ interrupt declaration in the usb node before the FIQ +declaration, so that the dwc2 driver will find it. Name the +interrupts appropriately so that the dwc_otg driver can still find +them. Then remove the interrupt rewriting from the overlays. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/bcm270x.dtsi | 6 ++++-- + arch/arm/boot/dts/overlays/dwc-otg-overlay.dts | 6 ------ + arch/arm/boot/dts/overlays/dwc2-overlay.dts | 2 -- + 3 files changed, 4 insertions(+), 10 deletions(-) + +--- a/arch/arm/boot/dts/bcm270x.dtsi ++++ b/arch/arm/boot/dts/bcm270x.dtsi +@@ -131,8 +131,10 @@ + compatible = "brcm,bcm2708-usb"; + reg = <0x7e980000 0x10000>, + <0x7e006000 0x1000>; +- interrupts = <2 0>, +- <1 9>; ++ interrupt-names = "usb", ++ "soft"; ++ interrupts = <1 9>, ++ <2 0>; + }; + + v3d@7ec00000 { /* vd3 */ +--- a/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts ++++ b/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts +@@ -6,14 +6,8 @@ + + fragment@0 { + target = <&usb>; +- #address-cells = <1>; +- #size-cells = <1>; + __overlay__ { + compatible = "brcm,bcm2708-usb"; +- reg = <0x7e980000 0x10000>, +- <0x7e006000 0x1000>; +- interrupts = <2 0>, +- <1 9>; + status = "okay"; + }; + }; +--- a/arch/arm/boot/dts/overlays/dwc2-overlay.dts ++++ b/arch/arm/boot/dts/overlays/dwc2-overlay.dts +@@ -10,8 +10,6 @@ + #size-cells = <1>; + dwc2_usb: __overlay__ { + compatible = "brcm,bcm2835-usb"; +- reg = <0x7e980000 0x10000>; +- interrupts = <1 9>; + dr_mode = "otg"; + g-np-tx-fifo-size = <32>; + g-rx-fifo-size = <256>; diff --git a/target/linux/brcm2708/patches-4.19/950-0507-overlays-Remove-upstream-aux-interrupt-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0507-overlays-Remove-upstream-aux-interrupt-overlay.patch deleted file mode 100644 index d1f2bb8fb2..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0507-overlays-Remove-upstream-aux-interrupt-overlay.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 1bb35a0debe9afff8113fe7727020e22a6160fd2 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 7 May 2019 10:06:04 +0100 -Subject: [PATCH 507/703] overlays: Remove upstream-aux-interrupt overlay - -We no longer have a downstream-specific auxilliary interrupt -driver, so the overlay to disable it is no longer needed. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/Makefile | 1 - - arch/arm/boot/dts/overlays/README | 12 +++---- - .../upstream-aux-interrupt-overlay.dts | 33 ------------------- - .../boot/dts/overlays/upstream-overlay.dts | 2 +- - 4 files changed, 6 insertions(+), 42 deletions(-) - delete mode 100644 arch/arm/boot/dts/overlays/upstream-aux-interrupt-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -151,7 +151,6 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - uart1.dtbo \ - udrc.dtbo \ - upstream.dtbo \ -- upstream-aux-interrupt.dtbo \ - vc4-fkms-v3d.dtbo \ - vc4-kms-kippah-7inch.dtbo \ - vc4-kms-v3d.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -2206,18 +2206,16 @@ Params: alsaname Name of - - - Name: upstream --Info: Allow usage of downstream .dtb with upstream kernel. Comprises -- vc4-kms-v3d, dwc2 and upstream-aux-interrupt overlays. -+Info: Allow usage of downstream .dtb with upstream kernel. Comprises the -+ vc4-kms-v3d and dwc2 overlays. - Load: dtoverlay=upstream - Params: - - - Name: upstream-aux-interrupt --Info: Allow usage of downstream .dtb with upstream kernel by binding AUX -- devices directly to the shared AUX interrupt line. One of the parts -- of the 'upstream' overlay --Load: dtoverlay=upstream-aux-interrupt --Params: -+Info: This overlay has been deprecated and removed because it is no longer -+ necessary. -+Load: - - - Name: vc4-fkms-v3d ---- a/arch/arm/boot/dts/overlays/upstream-aux-interrupt-overlay.dts -+++ /dev/null -@@ -1,33 +0,0 @@ --// Overlay for missing AUX interrupt controller --// Instead we bind all AUX devices to the generic AUX interrupt line --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&uart1>; -- __overlay__ { -- interrupt-parent = <&intc>; -- interrupts = <0x1 0x1d>; -- }; -- }; -- -- fragment@1 { -- target = <&spi1>; -- __overlay__ { -- interrupt-parent = <&intc>; -- interrupts = <0x1 0x1d>; -- }; -- }; -- -- fragment@2 { -- target = <&spi2>; -- __overlay__ { -- interrupt-parent = <&intc>; -- interrupts = <0x1 0x1d>; -- }; -- }; --}; -- ---- a/arch/arm/boot/dts/overlays/upstream-overlay.dts -+++ b/arch/arm/boot/dts/overlays/upstream-overlay.dts -@@ -1,4 +1,4 @@ --// redo: ovmerge -c vc4-kms-v3d-overlay.dts,cma-96 dwc2-overlay.dts,dr_mode=otg upstream-aux-interrupt-overlay.dts, -+// redo: ovmerge -c vc4-kms-v3d-overlay.dts,cma-96 dwc2-overlay.dts,dr_mode=otg - - /dts-v1/; - /plugin/; diff --git a/target/linux/brcm2708/patches-4.19/950-0508-overlays-Standardise-on-compatible-brcm-bcm2835.patch b/target/linux/brcm2708/patches-4.19/950-0508-overlays-Standardise-on-compatible-brcm-bcm2835.patch deleted file mode 100644 index 1afddc66ce..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0508-overlays-Standardise-on-compatible-brcm-bcm2835.patch +++ /dev/null @@ -1,1767 +0,0 @@ -From 72ce89af10e9f0d504f9c31a137928464b269cfb Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 14 May 2019 13:33:05 +0100 -Subject: [PATCH 508/703] overlays: Standardise on compatible="brcm,bcm2835" - -Curb the proliferation of compatible string combinations by -standardising on "brcm,bcm2835" to denote BCM2835 and its descendants. - -As nothing in the firmware or kernel is checking overlay compatible -strings, this should be a purely cosmetic change. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/adau1977-adc-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/adau7002-simple-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/ads1015-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/ads1115-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/ads7846-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/adv7282m-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/adv728x-m-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts | 2 +- - .../boot/dts/overlays/allo-boss-dac-pcm512x-audio-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/allo-digione-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/allo-katana-dac-audio-overlay.dts | 2 +- - .../boot/dts/overlays/allo-piano-dac-pcm512x-audio-overlay.dts | 2 +- - .../dts/overlays/allo-piano-dac-plus-pcm512x-audio-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/applepi-dac-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/at86rf233-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/audioinjector-ultra-overlay.dts | 2 +- - .../boot/dts/overlays/audioinjector-wm8731-audio-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/audiosense-pi-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/audremap-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/balena-fin-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/dht11-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/dionaudio-loco-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/dpi18-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/dpi24-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/draws-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/dwc-otg-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/dwc2-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/enc28j60-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/enc28j60-spi2-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/exc3000-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/goodix-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/googlevoicehat-soundcard-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/gpio-fan-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/gpio-ir-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/gpio-ir-tx-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/gpio-key-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/gpio-shutdown-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/hifiberry-dacplusadc-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/hy28a-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/hy28b-2017-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/hy28b-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/i-sabre-q2m-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/i2c-bcm2708-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/i2c-mux-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/i2s-gpio28-31-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/ilitek251x-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts | 2 +- - .../arm/boot/dts/overlays/iqaudio-digi-wm8804-audio-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/jedec-spi-nor-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/justboom-dac-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/justboom-digi-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/max98357a-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/mbed-dac-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/mcp23017-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/mcp23s17-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/mcp3008-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/mcp3202-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/mcp342x-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/media-center-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/mmc-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/mpu6050-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/mz61581-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/ov5647-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/papirus-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/pibell-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/piglow-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/piscreen-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/piscreen2r-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/pisound-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/pitft22-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/pitft35-resistive-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/pps-gpio-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/pwm-ir-tx-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/qca7000-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/rotary-encoder-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/rpi-cirrus-wm5102-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/rpi-dac-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/rpi-poe-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/rpi-proto-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/rpi-sense-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/rpi-tv-overlay.dts | 2 +- - .../arm/boot/dts/overlays/rra-digidac1-wm8741-audio-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/sc16is752-spi1-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/sdio-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/sdtweak-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/smi-nand-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/smi-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/spi-rtc-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/spi0-cs-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/spi0-hw-cs-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/ssd1306-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/superaudioboard-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/sx150x-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/tc358743-audio-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/tc358743-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/tpm-slb9670-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/uart0-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/uart1-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/udrc-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/upstream-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/vc4-fkms-v3d-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/vc4-kms-kippah-7inch-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/vga666-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/w1-gpio-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/wittypi-overlay.dts | 2 +- - 146 files changed, 146 insertions(+), 146 deletions(-) - ---- a/arch/arm/boot/dts/overlays/adau1977-adc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/adau1977-adc-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c>; ---- a/arch/arm/boot/dts/overlays/adau7002-simple-overlay.dts -+++ b/arch/arm/boot/dts/overlays/adau7002-simple-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/ads1015-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ads1015-overlay.dts -@@ -5,7 +5,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - /* ----------- ADS1015 ------------ */ - fragment@0 { - target = <&i2c_arm>; ---- a/arch/arm/boot/dts/overlays/ads1115-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ads1115-overlay.dts -@@ -6,7 +6,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c_arm>; ---- a/arch/arm/boot/dts/overlays/ads7846-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ads7846-overlay.dts -@@ -7,7 +7,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/adv7282m-overlay.dts -+++ b/arch/arm/boot/dts/overlays/adv7282m-overlay.dts -@@ -4,7 +4,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c_vc>; ---- a/arch/arm/boot/dts/overlays/adv728x-m-overlay.dts -+++ b/arch/arm/boot/dts/overlays/adv728x-m-overlay.dts -@@ -5,7 +5,7 @@ - #include "adv7282m-overlay.dts" - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - // Fragment numbers deliberately high to avoid conflicts with the - // included adv7282m overlay file. ---- a/arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts -+++ b/arch/arm/boot/dts/overlays/akkordion-iqdacplus-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/allo-boss-dac-pcm512x-audio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/allo-boss-dac-pcm512x-audio-overlay.dts -@@ -6,7 +6,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target-path = "/clocks"; ---- a/arch/arm/boot/dts/overlays/allo-digione-overlay.dts -+++ b/arch/arm/boot/dts/overlays/allo-digione-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/allo-katana-dac-audio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/allo-katana-dac-audio-overlay.dts -@@ -6,7 +6,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/allo-piano-dac-pcm512x-audio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/allo-piano-dac-pcm512x-audio-overlay.dts -@@ -13,7 +13,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/allo-piano-dac-plus-pcm512x-audio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/allo-piano-dac-plus-pcm512x-audio-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/applepi-dac-overlay.dts -+++ b/arch/arm/boot/dts/overlays/applepi-dac-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&sound>; ---- a/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -+++ b/arch/arm/boot/dts/overlays/at86rf233-overlay.dts -@@ -4,7 +4,7 @@ - /* Overlay for Atmel AT86RF233 IEEE 802.15.4 WPAN transceiver on spi0.0 */ - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts -+++ b/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/audioinjector-ultra-overlay.dts -+++ b/arch/arm/boot/dts/overlays/audioinjector-ultra-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/audioinjector-wm8731-audio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/audioinjector-wm8731-audio-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/audiosense-pi-overlay.dts -+++ b/arch/arm/boot/dts/overlays/audiosense-pi-overlay.dts -@@ -5,7 +5,7 @@ - #include - - / { -- compatible = "brcm,bcm2837", "brcm,bcm2836", "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/audremap-overlay.dts -+++ b/arch/arm/boot/dts/overlays/audremap-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&audio_pins>; ---- a/arch/arm/boot/dts/overlays/balena-fin-overlay.dts -+++ b/arch/arm/boot/dts/overlays/balena-fin-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&mmc>; ---- a/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts -+++ b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c_arm>; ---- a/arch/arm/boot/dts/overlays/dht11-overlay.dts -+++ b/arch/arm/boot/dts/overlays/dht11-overlay.dts -@@ -5,7 +5,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target-path = "/"; ---- a/arch/arm/boot/dts/overlays/dionaudio-loco-overlay.dts -+++ b/arch/arm/boot/dts/overlays/dionaudio-loco-overlay.dts -@@ -8,7 +8,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts -+++ b/arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts -@@ -9,7 +9,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&sound>; ---- a/arch/arm/boot/dts/overlays/dpi18-overlay.dts -+++ b/arch/arm/boot/dts/overlays/dpi18-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - // There is no DPI driver module, but we need a platform device - // node (that doesn't already use pinctrl) to hang the pinctrl ---- a/arch/arm/boot/dts/overlays/dpi24-overlay.dts -+++ b/arch/arm/boot/dts/overlays/dpi24-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - // There is no DPI driver module, but we need a platform device - // node (that doesn't already use pinctrl) to hang the pinctrl ---- a/arch/arm/boot/dts/overlays/draws-overlay.dts -+++ b/arch/arm/boot/dts/overlays/draws-overlay.dts -@@ -7,7 +7,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - fragment@0 { - target = <&i2s>; - __overlay__ { ---- a/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts -+++ b/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&usb>; ---- a/arch/arm/boot/dts/overlays/dwc2-overlay.dts -+++ b/arch/arm/boot/dts/overlays/dwc2-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&usb>; ---- a/arch/arm/boot/dts/overlays/enc28j60-overlay.dts -+++ b/arch/arm/boot/dts/overlays/enc28j60-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/enc28j60-spi2-overlay.dts -+++ b/arch/arm/boot/dts/overlays/enc28j60-spi2-overlay.dts -@@ -4,7 +4,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi2>; ---- a/arch/arm/boot/dts/overlays/exc3000-overlay.dts -+++ b/arch/arm/boot/dts/overlays/exc3000-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&gpio>; ---- a/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&clocks>; ---- a/arch/arm/boot/dts/overlays/goodix-overlay.dts -+++ b/arch/arm/boot/dts/overlays/goodix-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&gpio>; ---- a/arch/arm/boot/dts/overlays/googlevoicehat-soundcard-overlay.dts -+++ b/arch/arm/boot/dts/overlays/googlevoicehat-soundcard-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/gpio-fan-overlay.dts -+++ b/arch/arm/boot/dts/overlays/gpio-fan-overlay.dts -@@ -38,7 +38,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target-path = "/"; ---- a/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts -+++ b/arch/arm/boot/dts/overlays/gpio-ir-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target-path = "/"; ---- a/arch/arm/boot/dts/overlays/gpio-ir-tx-overlay.dts -+++ b/arch/arm/boot/dts/overlays/gpio-ir-tx-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&gpio>; ---- a/arch/arm/boot/dts/overlays/gpio-key-overlay.dts -+++ b/arch/arm/boot/dts/overlays/gpio-key-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - // Configure the gpio pin controller ---- a/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts -+++ b/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target-path = "/"; ---- a/arch/arm/boot/dts/overlays/gpio-shutdown-overlay.dts -+++ b/arch/arm/boot/dts/overlays/gpio-shutdown-overlay.dts -@@ -10,7 +10,7 @@ - // note that GPIO3 has an external pullup on at least some boards). - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - // Configure the gpio pin controller ---- a/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target-path = "/clocks"; ---- a/arch/arm/boot/dts/overlays/hifiberry-dacplusadc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hifiberry-dacplusadc-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target-path = "/clocks"; ---- a/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/hy28a-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hy28a-overlay.dts -@@ -7,7 +7,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/hy28b-2017-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hy28b-2017-overlay.dts -@@ -7,7 +7,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/hy28b-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hy28b-overlay.dts -@@ -7,7 +7,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/i-sabre-q2m-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i-sabre-q2m-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&sound>; ---- a/arch/arm/boot/dts/overlays/i2c-bcm2708-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-bcm2708-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c_arm>; ---- a/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target-path = "/"; ---- a/arch/arm/boot/dts/overlays/i2c-mux-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-mux-overlay.dts -@@ -4,7 +4,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c_arm>; ---- a/arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-pwm-pca9685a-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c_arm>; ---- a/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts -@@ -4,7 +4,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target-path = "/"; ---- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c_arm>; ---- a/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c_arm>; ---- a/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts -@@ -9,7 +9,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c0>; ---- a/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts -@@ -9,7 +9,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c1>; ---- a/arch/arm/boot/dts/overlays/i2s-gpio28-31-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2s-gpio28-31-overlay.dts -@@ -6,7 +6,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s_pins>; ---- a/arch/arm/boot/dts/overlays/ilitek251x-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ilitek251x-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&gpio>; ---- a/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts -+++ b/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts -+++ b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/iqaudio-digi-wm8804-audio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/iqaudio-digi-wm8804-audio-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/jedec-spi-nor-overlay.dts -+++ b/arch/arm/boot/dts/overlays/jedec-spi-nor-overlay.dts -@@ -13,7 +13,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - // disable spi-dev on spi0.0 - fragment@0 { ---- a/arch/arm/boot/dts/overlays/justboom-dac-overlay.dts -+++ b/arch/arm/boot/dts/overlays/justboom-dac-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/justboom-digi-overlay.dts -+++ b/arch/arm/boot/dts/overlays/justboom-digi-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/max98357a-overlay.dts -+++ b/arch/arm/boot/dts/overlays/max98357a-overlay.dts -@@ -8,7 +8,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - /* Enable I2S */ - fragment@0 { ---- a/arch/arm/boot/dts/overlays/mbed-dac-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mbed-dac-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/mcp23017-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mcp23017-overlay.dts -@@ -4,7 +4,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c1>; ---- a/arch/arm/boot/dts/overlays/mcp23s17-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mcp23s17-overlay.dts -@@ -20,7 +20,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - // disable spi-dev on spi0.0 - fragment@0 { ---- a/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts -@@ -6,7 +6,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - /* disable spi-dev for spi0.0 */ - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mcp2515-can1-overlay.dts -@@ -6,7 +6,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - /* disable spi-dev for spi0.1 */ - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/mcp3008-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mcp3008-overlay.dts -@@ -6,7 +6,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spidev0>; ---- a/arch/arm/boot/dts/overlays/mcp3202-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mcp3202-overlay.dts -@@ -6,7 +6,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spidev0>; ---- a/arch/arm/boot/dts/overlays/mcp342x-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mcp342x-overlay.dts -@@ -4,7 +4,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c1>; ---- a/arch/arm/boot/dts/overlays/media-center-overlay.dts -+++ b/arch/arm/boot/dts/overlays/media-center-overlay.dts -@@ -7,7 +7,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/mmc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mmc-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&mmc>; ---- a/arch/arm/boot/dts/overlays/mpu6050-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mpu6050-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c1>; ---- a/arch/arm/boot/dts/overlays/mz61581-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -@@ -7,7 +7,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/ov5647-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ov5647-overlay.dts -@@ -4,7 +4,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c_vc>; ---- a/arch/arm/boot/dts/overlays/papirus-overlay.dts -+++ b/arch/arm/boot/dts/overlays/papirus-overlay.dts -@@ -4,7 +4,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c_arm>; ---- a/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts -@@ -11,7 +11,7 @@ - */ - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&act_led>; ---- a/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts -@@ -9,7 +9,7 @@ - */ - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&uart1>; ---- a/arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&mmc>; ---- a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -@@ -16,7 +16,7 @@ - */ - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&uart0>; ---- a/arch/arm/boot/dts/overlays/pibell-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pibell-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target-path = "/"; ---- a/arch/arm/boot/dts/overlays/piglow-overlay.dts -+++ b/arch/arm/boot/dts/overlays/piglow-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c_arm>; ---- a/arch/arm/boot/dts/overlays/piscreen-overlay.dts -+++ b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -@@ -7,7 +7,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts -+++ b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts -@@ -7,7 +7,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/pisound-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pisound-overlay.dts -@@ -23,7 +23,7 @@ - #include - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/pitft22-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pitft22-overlay.dts -@@ -7,7 +7,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pitft28-capacitive-overlay.dts -@@ -7,7 +7,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts -@@ -7,7 +7,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/pitft35-resistive-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pitft35-resistive-overlay.dts -@@ -7,7 +7,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - fragment@0 { - target-path = "/"; - __overlay__ { ---- a/arch/arm/boot/dts/overlays/pwm-ir-tx-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pwm-ir-tx-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&gpio>; ---- a/arch/arm/boot/dts/overlays/qca7000-overlay.dts -+++ b/arch/arm/boot/dts/overlays/qca7000-overlay.dts -@@ -5,7 +5,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spidev0>; ---- a/arch/arm/boot/dts/overlays/rotary-encoder-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rotary-encoder-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&gpio>; ---- a/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-backlight-overlay.dts -@@ -6,7 +6,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target-path = "/"; ---- a/arch/arm/boot/dts/overlays/rpi-cirrus-wm5102-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-cirrus-wm5102-overlay.dts -@@ -6,7 +6,7 @@ - #include - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -@@ -7,7 +7,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target-path = "/"; ---- a/arch/arm/boot/dts/overlays/rpi-poe-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-poe-overlay.dts -@@ -5,7 +5,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target-path = "/"; ---- a/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-sense-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c1>; ---- a/arch/arm/boot/dts/overlays/rpi-tv-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-tv-overlay.dts -@@ -4,7 +4,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spidev0>; ---- a/arch/arm/boot/dts/overlays/rra-digidac1-wm8741-audio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rra-digidac1-wm8741-audio-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c_arm>; ---- a/arch/arm/boot/dts/overlays/sc16is752-spi1-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sc16is752-spi1-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&gpio>; ---- a/arch/arm/boot/dts/overlays/sdhost-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -4,7 +4,7 @@ - /* Provide backwards compatible aliases for the old sdhost dtparams. */ - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&sdhost>; ---- a/arch/arm/boot/dts/overlays/sdio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts -@@ -4,7 +4,7 @@ - /* Enable SDIO from MMC interface via GPIOs 22-27. Includes sdhost overlay. */ - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&mmc>; ---- a/arch/arm/boot/dts/overlays/sdtweak-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdtweak-overlay.dts -@@ -4,7 +4,7 @@ - /* Provide backwards compatible aliases for the old sdhost dtparams. */ - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&sdhost>; ---- a/arch/arm/boot/dts/overlays/smi-nand-overlay.dts -+++ b/arch/arm/boot/dts/overlays/smi-nand-overlay.dts -@@ -6,7 +6,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&smi>; ---- a/arch/arm/boot/dts/overlays/smi-overlay.dts -+++ b/arch/arm/boot/dts/overlays/smi-overlay.dts -@@ -5,7 +5,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&smi>; ---- a/arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts -+++ b/arch/arm/boot/dts/overlays/spi-gpio35-39-overlay.dts -@@ -6,7 +6,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/spi-rtc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/spi-rtc-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spidev0>; ---- a/arch/arm/boot/dts/overlays/spi0-cs-overlay.dts -+++ b/arch/arm/boot/dts/overlays/spi0-cs-overlay.dts -@@ -3,7 +3,7 @@ - - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0_cs_pins>; ---- a/arch/arm/boot/dts/overlays/spi0-hw-cs-overlay.dts -+++ b/arch/arm/boot/dts/overlays/spi0-hw-cs-overlay.dts -@@ -6,7 +6,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts -+++ b/arch/arm/boot/dts/overlays/spi1-1cs-overlay.dts -@@ -3,7 +3,7 @@ - - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&gpio>; ---- a/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts -+++ b/arch/arm/boot/dts/overlays/spi1-2cs-overlay.dts -@@ -3,7 +3,7 @@ - - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&gpio>; ---- a/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts -+++ b/arch/arm/boot/dts/overlays/spi1-3cs-overlay.dts -@@ -3,7 +3,7 @@ - - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&gpio>; ---- a/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts -+++ b/arch/arm/boot/dts/overlays/spi2-1cs-overlay.dts -@@ -3,7 +3,7 @@ - - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&gpio>; ---- a/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts -+++ b/arch/arm/boot/dts/overlays/spi2-2cs-overlay.dts -@@ -3,7 +3,7 @@ - - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&gpio>; ---- a/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts -+++ b/arch/arm/boot/dts/overlays/spi2-3cs-overlay.dts -@@ -3,7 +3,7 @@ - - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&gpio>; ---- a/arch/arm/boot/dts/overlays/ssd1306-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ssd1306-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2718"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c1>; ---- a/arch/arm/boot/dts/overlays/superaudioboard-overlay.dts -+++ b/arch/arm/boot/dts/overlays/superaudioboard-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&sound>; ---- a/arch/arm/boot/dts/overlays/sx150x-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sx150x-overlay.dts -@@ -22,7 +22,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - // Enable I2C#0 interface - fragment@0 { ---- a/arch/arm/boot/dts/overlays/tc358743-audio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/tc358743-audio-overlay.dts -@@ -5,7 +5,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2s>; ---- a/arch/arm/boot/dts/overlays/tc358743-overlay.dts -+++ b/arch/arm/boot/dts/overlays/tc358743-overlay.dts -@@ -4,7 +4,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&i2c_vc>; ---- a/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts -+++ b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts -@@ -24,7 +24,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/tpm-slb9670-overlay.dts -+++ b/arch/arm/boot/dts/overlays/tpm-slb9670-overlay.dts -@@ -8,7 +8,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&spi0>; ---- a/arch/arm/boot/dts/overlays/uart0-overlay.dts -+++ b/arch/arm/boot/dts/overlays/uart0-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&uart0>; ---- a/arch/arm/boot/dts/overlays/uart1-overlay.dts -+++ b/arch/arm/boot/dts/overlays/uart1-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&uart1>; ---- a/arch/arm/boot/dts/overlays/udrc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/udrc-overlay.dts -@@ -7,7 +7,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - fragment@0 { - target = <&i2s>; - __overlay__ { ---- a/arch/arm/boot/dts/overlays/upstream-overlay.dts -+++ b/arch/arm/boot/dts/overlays/upstream-overlay.dts -@@ -6,7 +6,7 @@ - #include - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - fragment@0 { - target-path = "/chosen"; - __dormant__ { ---- a/arch/arm/boot/dts/overlays/vc4-fkms-v3d-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-fkms-v3d-overlay.dts -@@ -6,7 +6,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target-path = "/chosen"; ---- a/arch/arm/boot/dts/overlays/vc4-kms-kippah-7inch-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-kms-kippah-7inch-overlay.dts -@@ -8,7 +8,7 @@ - #include - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target-path = "/"; ---- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts -@@ -8,7 +8,7 @@ - #include - - / { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target-path = "/chosen"; ---- a/arch/arm/boot/dts/overlays/vga666-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vga666-overlay.dts -@@ -2,7 +2,7 @@ - /plugin/; - - /{ -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - // There is no VGA driver module, but we need a platform device - // node (that doesn't already use pinctrl) to hang the pinctrl ---- a/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target-path = "/"; ---- a/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts -+++ b/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts -@@ -3,7 +3,7 @@ - /plugin/; - - / { -- compatible = "brcm,bcm2708"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target-path = "/"; ---- a/arch/arm/boot/dts/overlays/wittypi-overlay.dts -+++ b/arch/arm/boot/dts/overlays/wittypi-overlay.dts -@@ -8,7 +8,7 @@ - - / { - -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ compatible = "brcm,bcm2835"; - - fragment@0 { - target = <&leds>; diff --git a/target/linux/brcm2708/patches-4.19/950-0508-overlays-Update-upstream-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0508-overlays-Update-upstream-overlay.patch new file mode 100644 index 0000000000..4e60355556 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0508-overlays-Update-upstream-overlay.patch @@ -0,0 +1,126 @@ +From 9e3b138e750cddfd19e8463661e592fd14621c9c Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 22 May 2019 13:29:56 +0100 +Subject: [PATCH 508/725] overlays: Update upstream overlay + +The recent DT/overlay changes have had a corresponding effect on the +upstream overlay, which is a composite of the vc4-kms-v3d and dwc2 +overlays. + +Signed-off-by: Phil Elwell +--- + .../boot/dts/overlays/upstream-overlay.dts | 41 ++----------------- + 1 file changed, 3 insertions(+), 38 deletions(-) + +--- a/arch/arm/boot/dts/overlays/upstream-overlay.dts ++++ b/arch/arm/boot/dts/overlays/upstream-overlay.dts +@@ -52,42 +52,36 @@ + fragment@7 { + target = <&pixelvalve0>; + __overlay__ { +- interrupts = <2 13>; + status = "okay"; + }; + }; + fragment@8 { + target = <&pixelvalve1>; + __overlay__ { +- interrupts = <2 14>; + status = "okay"; + }; + }; + fragment@9 { + target = <&pixelvalve2>; + __overlay__ { +- interrupts = <2 10>; + status = "okay"; + }; + }; + fragment@10 { + target = <&hvs>; + __overlay__ { +- interrupts = <2 1>; + status = "okay"; + }; + }; + fragment@11 { + target = <&hdmi>; + __overlay__ { +- interrupts = <2 8>, <2 9>; + status = "okay"; + }; + }; + fragment@12 { + target = <&v3d>; + __overlay__ { +- interrupts = <1 10>; + status = "okay"; + }; + }; +@@ -98,37 +92,29 @@ + }; + }; + fragment@14 { +- target-path = "/soc/dma"; +- __overlay__ { +- brcm,dma-channel-mask = <0x7f35>; +- }; +- }; +- fragment@15 { + target = <&clocks>; + __overlay__ { + claim-clocks = ; + }; + }; +- fragment@16 { ++ fragment@15 { + target = <&vec>; + __overlay__ { + status = "okay"; + }; + }; +- fragment@17 { ++ fragment@16 { + target = <&txp>; + __overlay__ { + status = "okay"; + }; + }; +- fragment@18 { ++ fragment@17 { + target = <&usb>; + #address-cells = <1>; + #size-cells = <1>; + dwc2_usb: __overlay__ { + compatible = "brcm,bcm2835-usb"; +- reg = <0x7e980000 0x10000>; +- interrupts = <1 9>; + dr_mode = "otg"; + g-np-tx-fifo-size = <32>; + g-rx-fifo-size = <256>; +@@ -136,25 +122,4 @@ + status = "okay"; + }; + }; +- fragment@19 { +- target = <&uart1>; +- __overlay__ { +- interrupt-parent = <&intc>; +- interrupts = <0x1 0x1d>; +- }; +- }; +- fragment@20 { +- target = <&spi1>; +- __overlay__ { +- interrupt-parent = <&intc>; +- interrupts = <0x1 0x1d>; +- }; +- }; +- fragment@21 { +- target = <&spi2>; +- __overlay__ { +- interrupt-parent = <&intc>; +- interrupts = <0x1 0x1d>; +- }; +- }; + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0509-vc4-Remove-interrupt-and-DMA-trampling.patch b/target/linux/brcm2708/patches-4.19/950-0509-vc4-Remove-interrupt-and-DMA-trampling.patch deleted file mode 100644 index da3774ee10..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0509-vc4-Remove-interrupt-and-DMA-trampling.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 66ba94b1099ebc09bf82516499257165495c7c46 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 22 May 2019 12:58:47 +0100 -Subject: [PATCH 509/703] vc4: Remove interrupt and DMA trampling - -As part of the effort to clean up the overlays, remove the interrupt -and DMA mask declarations from the vc4 overlays which just duplicate -that which is in the base DTBs. - -Signed-off-by: Phil Elwell ---- - .../boot/dts/overlays/vc4-fkms-v3d-overlay.dts | 8 -------- - .../boot/dts/overlays/vc4-kms-v3d-overlay.dts | 18 ++---------------- - 2 files changed, 2 insertions(+), 24 deletions(-) - ---- a/arch/arm/boot/dts/overlays/vc4-fkms-v3d-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-fkms-v3d-overlay.dts -@@ -60,7 +60,6 @@ - fragment@7 { - target = <&v3d>; - __overlay__ { -- interrupts = <1 10>; - status = "okay"; - }; - }; -@@ -72,13 +71,6 @@ - }; - }; - -- fragment@9 { -- target-path = "/soc/dma"; -- __overlay__ { -- brcm,dma-channel-mask = <0x7f35>; -- }; -- }; -- - __overrides__ { - cma-256 = <0>,"+0-1-2-3-4"; - cma-192 = <0>,"-0+1-2-3-4"; ---- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts -@@ -62,7 +62,6 @@ - fragment@7 { - target = <&pixelvalve0>; - __overlay__ { -- interrupts = <2 13>; /* pwa0 */ - status = "okay"; - }; - }; -@@ -70,7 +69,6 @@ - fragment@8 { - target = <&pixelvalve1>; - __overlay__ { -- interrupts = <2 14>; /* pwa1 */ - status = "okay"; - }; - }; -@@ -78,7 +76,6 @@ - fragment@9 { - target = <&pixelvalve2>; - __overlay__ { -- interrupts = <2 10>; /* pixelvalve */ - status = "okay"; - }; - }; -@@ -86,7 +83,6 @@ - fragment@10 { - target = <&hvs>; - __overlay__ { -- interrupts = <2 1>; - status = "okay"; - }; - }; -@@ -94,7 +90,6 @@ - fragment@11 { - target = <&hdmi>; - __overlay__ { -- interrupts = <2 8>, <2 9>; - status = "okay"; - }; - }; -@@ -102,7 +97,6 @@ - fragment@12 { - target = <&v3d>; - __overlay__ { -- interrupts = <1 10>; - status = "okay"; - }; - }; -@@ -115,14 +109,6 @@ - }; - - fragment@14 { -- target-path = "/soc/dma"; -- __overlay__ { -- brcm,dma-channel-mask = <0x7f35>; -- }; -- }; -- -- -- fragment@15 { - target = <&clocks>; - __overlay__ { - claim-clocks = < -@@ -134,14 +120,14 @@ - }; - }; - -- fragment@16 { -+ fragment@15 { - target = <&vec>; - __overlay__ { - status = "okay"; - }; - }; - -- fragment@17 { -+ fragment@16 { - target = <&txp>; - __overlay__ { - status = "okay"; diff --git a/target/linux/brcm2708/patches-4.19/950-0509-w1-ds2408-Fix-typo-after-49695ac46861-reset-on-outpu.patch b/target/linux/brcm2708/patches-4.19/950-0509-w1-ds2408-Fix-typo-after-49695ac46861-reset-on-outpu.patch new file mode 100644 index 0000000000..28639300ad --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0509-w1-ds2408-Fix-typo-after-49695ac46861-reset-on-outpu.patch @@ -0,0 +1,31 @@ +From 04d76f91610d34088593cc128de8184d86240db4 Mon Sep 17 00:00:00 2001 +From: Mariusz Bialonczyk +Date: Thu, 16 May 2019 14:39:21 +0200 +Subject: [PATCH 509/725] w1: ds2408: Fix typo after 49695ac46861 (reset on + output_write retry with readback) + +commit 6660a04feb7ef648e50c792e19084d675fa6f3a2 upstream. + +Fix a typo in commit: +49695ac46861 w1: ds2408: reset on output_write retry with readback + +Fixes: 49695ac46861 ("w1: ds2408: reset on output_write retry with readback") +Reported-by: Phil Elwell +Cc: Jean-Francois Dagenais +Signed-off-by: Mariusz Bialonczyk +Signed-off-by: Greg Kroah-Hartman +--- + drivers/w1/slaves/w1_ds2408.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/w1/slaves/w1_ds2408.c ++++ b/drivers/w1/slaves/w1_ds2408.c +@@ -138,7 +138,7 @@ static ssize_t status_control_read(struc + W1_F29_REG_CONTROL_AND_STATUS, buf); + } + +-#ifdef fCONFIG_W1_SLAVE_DS2408_READBACK ++#ifdef CONFIG_W1_SLAVE_DS2408_READBACK + static bool optional_read_back_valid(struct w1_slave *sl, u8 expected) + { + u8 w1_buf[3]; diff --git a/target/linux/brcm2708/patches-4.19/950-0510-BCM270X_DT-Add-non-removable-clone-of-mmc-node.patch b/target/linux/brcm2708/patches-4.19/950-0510-BCM270X_DT-Add-non-removable-clone-of-mmc-node.patch deleted file mode 100644 index 061c437cd4..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0510-BCM270X_DT-Add-non-removable-clone-of-mmc-node.patch +++ /dev/null @@ -1,206 +0,0 @@ -From 5c9796882b256d149d9c9d9da6b374e4c4e7cbaa Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 7 May 2019 14:29:38 +0100 -Subject: [PATCH 510/703] BCM270X_DT: Add non-removable clone of mmc node - -non-removable is a boolean property, and as such can't be unset by an -overlay if it is set in a base DTB. Until now the workaround for this -problem has been for overlays to clone non-removable nodes without -the offending property, but this involves a lot of unnecessary -replication. Instead, add a clone of the mmc node with non-removable -already set to the base DTB, selecting the required version using -the status properties. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2708-rpi-0-w.dts | 4 +-- - arch/arm/boot/dts/bcm2708-rpi.dtsi | 3 +- - arch/arm/boot/dts/bcm270x.dtsi | 13 ++++++++ - arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 5 ++-- - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 5 ++-- - arch/arm/boot/dts/overlays/mmc-overlay.dts | 7 +++++ - arch/arm/boot/dts/overlays/sdio-overlay.dts | 33 +++++++-------------- - 7 files changed, 38 insertions(+), 32 deletions(-) - ---- a/arch/arm/boot/dts/bcm2708-rpi-0-w.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-0-w.dts -@@ -14,6 +14,7 @@ - aliases { - serial0 = &uart1; - serial1 = &uart0; -+ mmc1 = &mmcnr; - }; - }; - -@@ -73,10 +74,9 @@ - }; - }; - --&mmc { -+&mmcnr { - pinctrl-names = "default"; - pinctrl-0 = <&sdio_pins>; -- non-removable; - bus-width = <4>; - status = "okay"; - }; ---- a/arch/arm/boot/dts/bcm2708-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi.dtsi -@@ -118,7 +118,8 @@ - sd_force_pio = <&sdhost>,"brcm,force-pio?"; - sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; - sd_debug = <&sdhost>,"brcm,debug"; -- sdio_overclock = <&mmc>,"brcm,overclock-50:0"; -+ sdio_overclock = <&mmc>,"brcm,overclock-50:0", -+ <&mmcnr>,"brcm,overclock-50:0"; - axiperf = <&axiperf>,"status"; - }; - }; ---- a/arch/arm/boot/dts/bcm270x.dtsi -+++ b/arch/arm/boot/dts/bcm270x.dtsi -@@ -79,6 +79,19 @@ - status = "disabled"; - }; - -+ /* A clone of mmc but with non-removable set */ -+ mmcnr: mmcnr@7e300000 { -+ compatible = "brcm,bcm2835-mmc", "brcm,bcm2835-sdhci"; -+ reg = <0x7e300000 0x100>; -+ interrupts = <2 30>; -+ clocks = <&clocks BCM2835_CLOCK_EMMC>; -+ dmas = <&dma 11>; -+ dma-names = "rx-tx"; -+ brcm,overclock-50 = <0>; -+ non-removable; -+ status = "disabled"; -+ }; -+ - hvs: hvs@7e400000 { - /* Add alias */ - status = "disabled"; ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts -@@ -15,6 +15,7 @@ - aliases { - serial0 = &uart1; - serial1 = &uart0; -+ mmc1 = &mmcnr; - }; - }; - -@@ -74,13 +75,11 @@ - }; - }; - --&mmc { -+&mmcnr { - pinctrl-names = "default"; - pinctrl-0 = <&sdio_pins>; -- non-removable; - bus-width = <4>; - status = "okay"; -- brcm,overclock-50 = <0>; - }; - - &firmware { ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -15,6 +15,7 @@ - aliases { - serial0 = &uart1; - serial1 = &uart0; -+ mmc1 = &mmcnr; - }; - }; - -@@ -74,13 +75,11 @@ - }; - }; - --&mmc { -+&mmcnr { - pinctrl-names = "default"; - pinctrl-0 = <&sdio_pins>; -- non-removable; - bus-width = <4>; - status = "okay"; -- brcm,overclock-50 = <0>; - }; - - &soc { ---- a/arch/arm/boot/dts/overlays/mmc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/mmc-overlay.dts -@@ -33,6 +33,13 @@ - }; - }; - -+ fragment@3 { -+ target = <&mmcnr>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ - __overrides__ { - overclock_50 = <&frag0>,"brcm,overclock-50:0"; - }; ---- a/arch/arm/boot/dts/overlays/sdio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdio-overlay.dts -@@ -1,39 +1,26 @@ - /dts-v1/; - /plugin/; - --/* Enable SDIO from MMC interface via GPIOs 22-27. Includes sdhost overlay. */ -+/* Enable SDIO from MMC interface via various GPIO groups */ - - /{ - compatible = "brcm,bcm2835"; - - fragment@0 { -- target = <&mmc>; -+ target = <&mmcnr>; - __overlay__ { - status = "disabled"; - }; - }; - - fragment@1 { -- target = <&soc>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <1>; -- -- sdio_ovl: sdio@7e300000 { -- compatible = "brcm,bcm2835-mmc", -- "brcm,bcm2835-sdhci"; -- reg = <0x7e300000 0x100>; -- interrupts = <2 30>; -- clocks = <&clocks 28/*BCM2835_CLOCK_EMMC*/>; -- dmas = <&dma 11>; -- dma-names = "rx-tx"; -- brcm,overclock-50 = <0>; -- status = "okay"; -- pinctrl-names = "default"; -- pinctrl-0 = <&sdio_ovl_pins>; -- non-removable; -- bus-width = <4>; -- }; -+ target = <&mmc>; -+ sdio_ovl: __overlay__ { -+ pinctrl-0 = <&sdio_ovl_pins>; -+ pinctrl-names = "default"; -+ non-removable; -+ bus-width = <4>; -+ status = "okay"; - }; - }; - -@@ -75,7 +62,7 @@ - fragment@6 { - target-path = "/aliases"; - __overlay__ { -- mmc1 = "/soc/sdio@7e300000"; -+ mmc1 = "/soc/mmc@7e300000"; - }; - }; - diff --git a/target/linux/brcm2708/patches-4.19/950-0510-BCM270X_DT-Rename-Pi-Zero-W-DT-files.patch b/target/linux/brcm2708/patches-4.19/950-0510-BCM270X_DT-Rename-Pi-Zero-W-DT-files.patch new file mode 100644 index 0000000000..1b2633d0f7 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0510-BCM270X_DT-Rename-Pi-Zero-W-DT-files.patch @@ -0,0 +1,367 @@ +From c9858300591b9406b9b65e41da8d383d7cbd6826 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 28 May 2019 16:36:04 +0100 +Subject: [PATCH 510/725] BCM270X_DT: Rename Pi Zero W DT files + +The downtream Pi Zero W dts file uses the digit 0, whereas upstream +chose to spell it out - "zero-w". The firmware has, for a long time, +looked for bcm2708-rpi-zero-w.dtb first before falling back to the +numerical version. Therefore it is better to follow upstream and +make the switch to "bcm2708-rpi-zero-w". + +At the same time, remove some overrides that duplicate values +inherited from the shared .dtsi files. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/Makefile | 2 +- + .../boot/dts/{bcm2708-rpi-0-w.dts => bcm2708-rpi-zero-w.dts} | 5 ----- + 2 files changed, 1 insertion(+), 6 deletions(-) + rename arch/arm/boot/dts/{bcm2708-rpi-0-w.dts => bcm2708-rpi-zero-w.dts} (97%) + +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -4,7 +4,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ + bcm2708-rpi-b.dtb \ + bcm2708-rpi-b-plus.dtb \ + bcm2708-rpi-cm.dtb \ +- bcm2708-rpi-0-w.dtb \ ++ bcm2708-rpi-zero-w.dtb \ + bcm2709-rpi-2-b.dtb \ + bcm2710-rpi-3-b.dtb \ + bcm2710-rpi-3-b-plus.dtb \ +--- a/arch/arm/boot/dts/bcm2708-rpi-0-w.dts ++++ /dev/null +@@ -1,167 +0,0 @@ +-/dts-v1/; +- +-#include "bcm2708.dtsi" +-#include "bcm283x-rpi-csi1-2lane.dtsi" +- +-/ { +- compatible = "raspberrypi,model-zero-w", "brcm,bcm2835"; +- model = "Raspberry Pi Zero W"; +- +- chosen { +- bootargs = "coherent_pool=1M 8250.nr_uarts=1"; +- }; +- +- aliases { +- serial0 = &uart1; +- serial1 = &uart0; +- mmc1 = &mmcnr; +- }; +-}; +- +-&gpio { +- 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 = <>; +- }; +-}; +- +-&mmcnr { +- pinctrl-names = "default"; +- pinctrl-0 = <&sdio_pins>; +- bus-width = <4>; +- 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 = <125000000>; +- }; +- +- spidev1: spidev@1{ +- compatible = "spidev"; +- reg = <1>; /* CE1 */ +- #address-cells = <1>; +- #size-cells = <0>; +- spi-max-frequency = <125000000>; +- }; +-}; +- +-&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>; +-}; +- +-/ { +- __overrides__ { +- act_led_gpio = <&act_led>,"gpios:4"; +- act_led_activelow = <&act_led>,"gpios:8"; +- act_led_trigger = <&act_led>,"linux,default-trigger"; +- }; +-}; +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts +@@ -0,0 +1,162 @@ ++/dts-v1/; ++ ++#include "bcm2708.dtsi" ++#include "bcm283x-rpi-csi1-2lane.dtsi" ++ ++/ { ++ compatible = "raspberrypi,model-zero-w", "brcm,bcm2835"; ++ model = "Raspberry Pi Zero W"; ++ ++ chosen { ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1"; ++ }; ++ ++ aliases { ++ serial0 = &uart1; ++ serial1 = &uart0; ++ mmc1 = &mmcnr; ++ }; ++}; ++ ++&gpio { ++ 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 = <>; ++ }; ++}; ++ ++&mmcnr { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio_pins>; ++ bus-width = <4>; ++ 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 = <125000000>; ++ }; ++ ++ spidev1: spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ }; ++}; ++ ++&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 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++&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>; ++}; ++ ++/ { ++ __overrides__ { ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ }; ++}; diff --git a/target/linux/brcm2708/patches-4.19/950-0511-BCM270X_DT-Create-bcm2708-rpi-zero.dts.patch b/target/linux/brcm2708/patches-4.19/950-0511-BCM270X_DT-Create-bcm2708-rpi-zero.dts.patch new file mode 100644 index 0000000000..c2f5a78d74 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0511-BCM270X_DT-Create-bcm2708-rpi-zero.dts.patch @@ -0,0 +1,148 @@ +From b9a96a4b09c30803092ed4a9f730cb3573037cd6 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 28 May 2019 16:23:51 +0100 +Subject: [PATCH 511/725] BCM270X_DT: Create bcm2708-rpi-zero.dts + +The Pi Zero deserves a dedicated .dtb file - sharing the b-plus .dtb +has been observed to cause an issue with the MAC address of some +Ethernet dongles. + +See: https://github.com/raspberrypi/linux/issues/2990 + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/Makefile | 1 + + arch/arm/boot/dts/bcm2708-rpi-zero.dts | 117 +++++++++++++++++++++++++ + 2 files changed, 118 insertions(+) + create mode 100644 arch/arm/boot/dts/bcm2708-rpi-zero.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-zero.dtb \ + bcm2708-rpi-zero-w.dtb \ + bcm2709-rpi-2-b.dtb \ + bcm2710-rpi-3-b.dtb \ +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2708-rpi-zero.dts +@@ -0,0 +1,117 @@ ++/dts-v1/; ++ ++#include "bcm2708.dtsi" ++#include "bcm283x-rpi-csi1-2lane.dtsi" ++ ++/ { ++ compatible = "raspberrypi,model-zero", "brcm,bcm2835"; ++ model = "Raspberry Pi Zero"; ++ ++ chosen { ++ bootargs = "coherent_pool=1M"; ++ }; ++}; ++ ++&gpio { ++ 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 */ ++ }; ++ ++ audio_pins: audio_pins { ++ brcm,pins = <>; ++ brcm,function = <>; ++ }; ++}; ++ ++&uart0 { ++ 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 = <125000000>; ++ }; ++ ++ spidev1: spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ }; ++}; ++ ++&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 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++&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>; ++}; ++ ++/ { ++ __overrides__ { ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ }; ++}; diff --git a/target/linux/brcm2708/patches-4.19/950-0511-BCM270X_DT-usb-Refactor-DTS-and-overlays.patch b/target/linux/brcm2708/patches-4.19/950-0511-BCM270X_DT-usb-Refactor-DTS-and-overlays.patch deleted file mode 100644 index ed31c11ad7..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0511-BCM270X_DT-usb-Refactor-DTS-and-overlays.patch +++ /dev/null @@ -1,60 +0,0 @@ -From fdec17c9cd5cb9c52872e9669aca53d58c7f1eaf Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 8 May 2019 10:08:31 +0100 -Subject: [PATCH 511/703] BCM270X_DT: usb: Refactor DTS and overlays - -Move the IRQ interrupt declaration in the usb node before the FIQ -declaration, so that the dwc2 driver will find it. Name the -interrupts appropriately so that the dwc_otg driver can still find -them. Then remove the interrupt rewriting from the overlays. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm270x.dtsi | 6 ++++-- - arch/arm/boot/dts/overlays/dwc-otg-overlay.dts | 6 ------ - arch/arm/boot/dts/overlays/dwc2-overlay.dts | 2 -- - 3 files changed, 4 insertions(+), 10 deletions(-) - ---- a/arch/arm/boot/dts/bcm270x.dtsi -+++ b/arch/arm/boot/dts/bcm270x.dtsi -@@ -131,8 +131,10 @@ - compatible = "brcm,bcm2708-usb"; - reg = <0x7e980000 0x10000>, - <0x7e006000 0x1000>; -- interrupts = <2 0>, -- <1 9>; -+ interrupt-names = "usb", -+ "soft"; -+ interrupts = <1 9>, -+ <2 0>; - }; - - v3d@7ec00000 { /* vd3 */ ---- a/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts -+++ b/arch/arm/boot/dts/overlays/dwc-otg-overlay.dts -@@ -6,14 +6,8 @@ - - fragment@0 { - target = <&usb>; -- #address-cells = <1>; -- #size-cells = <1>; - __overlay__ { - compatible = "brcm,bcm2708-usb"; -- reg = <0x7e980000 0x10000>, -- <0x7e006000 0x1000>; -- interrupts = <2 0>, -- <1 9>; - status = "okay"; - }; - }; ---- a/arch/arm/boot/dts/overlays/dwc2-overlay.dts -+++ b/arch/arm/boot/dts/overlays/dwc2-overlay.dts -@@ -10,8 +10,6 @@ - #size-cells = <1>; - dwc2_usb: __overlay__ { - compatible = "brcm,bcm2835-usb"; -- reg = <0x7e980000 0x10000>; -- interrupts = <1 9>; - dr_mode = "otg"; - g-np-tx-fifo-size = <32>; - g-rx-fifo-size = <256>; diff --git a/target/linux/brcm2708/patches-4.19/950-0512-overlays-Fix-mmc-related-overlays-after-refactor.patch b/target/linux/brcm2708/patches-4.19/950-0512-overlays-Fix-mmc-related-overlays-after-refactor.patch new file mode 100644 index 0000000000..060cdfe59f --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0512-overlays-Fix-mmc-related-overlays-after-refactor.patch @@ -0,0 +1,73 @@ +From 4adf2465fe10714a159a2e9a885989d0ad46db13 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 30 May 2019 12:25:29 +0100 +Subject: [PATCH 512/725] overlays: Fix mmc-related overlays after refactor + +The addition of the mmcnr node to the base dtbs caused some overlays to +not work as they should. Patch up pi3-disable-wifi, balena-fin and +sdhost. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/balena-fin-overlay.dts | 7 ++++--- + arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts | 7 +++++++ + arch/arm/boot/dts/overlays/sdhost-overlay.dts | 7 +++++++ + 3 files changed, 18 insertions(+), 3 deletions(-) + +--- a/arch/arm/boot/dts/overlays/balena-fin-overlay.dts ++++ b/arch/arm/boot/dts/overlays/balena-fin-overlay.dts +@@ -5,13 +5,12 @@ + compatible = "brcm,bcm2835"; + + fragment@0 { +- target = <&mmc>; +- sdio_wifi: __overlay__ { ++ target = <&mmcnr>; ++ __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&sdio_pins>; + bus-width = <4>; + brcm,overclock-50 = <35>; +- non-removable; + status = "okay"; + }; + }; +@@ -43,6 +42,8 @@ + compatible = "gpio-poweroff"; + gpios = <&gpio 40 1>; + force; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&power_ctrl_pins>; + }; + + i2c_soft: i2c@0 { +--- a/arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts ++++ b/arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts +@@ -10,4 +10,11 @@ + status = "disabled"; + }; + }; ++ ++ fragment@1 { ++ target = <&mmcnr>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; + }; +--- a/arch/arm/boot/dts/overlays/sdhost-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts +@@ -22,6 +22,13 @@ + }; + }; + ++ fragment@2 { ++ target = <&mmcnr>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ + __overrides__ { + overclock_50 = <&frag0>,"brcm,overclock-50:0"; + force_pio = <&frag0>,"brcm,force-pio?"; diff --git a/target/linux/brcm2708/patches-4.19/950-0512-overlays-Update-upstream-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0512-overlays-Update-upstream-overlay.patch deleted file mode 100644 index d0eed03613..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0512-overlays-Update-upstream-overlay.patch +++ /dev/null @@ -1,126 +0,0 @@ -From a81bfae69a80e92852509118ff81f3485836b81e Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 22 May 2019 13:29:56 +0100 -Subject: [PATCH 512/703] overlays: Update upstream overlay - -The recent DT/overlay changes have had a corresponding effect on the -upstream overlay, which is a composite of the vc4-kms-v3d and dwc2 -overlays. - -Signed-off-by: Phil Elwell ---- - .../boot/dts/overlays/upstream-overlay.dts | 41 ++----------------- - 1 file changed, 3 insertions(+), 38 deletions(-) - ---- a/arch/arm/boot/dts/overlays/upstream-overlay.dts -+++ b/arch/arm/boot/dts/overlays/upstream-overlay.dts -@@ -52,42 +52,36 @@ - fragment@7 { - target = <&pixelvalve0>; - __overlay__ { -- interrupts = <2 13>; - status = "okay"; - }; - }; - fragment@8 { - target = <&pixelvalve1>; - __overlay__ { -- interrupts = <2 14>; - status = "okay"; - }; - }; - fragment@9 { - target = <&pixelvalve2>; - __overlay__ { -- interrupts = <2 10>; - status = "okay"; - }; - }; - fragment@10 { - target = <&hvs>; - __overlay__ { -- interrupts = <2 1>; - status = "okay"; - }; - }; - fragment@11 { - target = <&hdmi>; - __overlay__ { -- interrupts = <2 8>, <2 9>; - status = "okay"; - }; - }; - fragment@12 { - target = <&v3d>; - __overlay__ { -- interrupts = <1 10>; - status = "okay"; - }; - }; -@@ -98,37 +92,29 @@ - }; - }; - fragment@14 { -- target-path = "/soc/dma"; -- __overlay__ { -- brcm,dma-channel-mask = <0x7f35>; -- }; -- }; -- fragment@15 { - target = <&clocks>; - __overlay__ { - claim-clocks = ; - }; - }; -- fragment@16 { -+ fragment@15 { - target = <&vec>; - __overlay__ { - status = "okay"; - }; - }; -- fragment@17 { -+ fragment@16 { - target = <&txp>; - __overlay__ { - status = "okay"; - }; - }; -- fragment@18 { -+ fragment@17 { - target = <&usb>; - #address-cells = <1>; - #size-cells = <1>; - dwc2_usb: __overlay__ { - compatible = "brcm,bcm2835-usb"; -- reg = <0x7e980000 0x10000>; -- interrupts = <1 9>; - dr_mode = "otg"; - g-np-tx-fifo-size = <32>; - g-rx-fifo-size = <256>; -@@ -136,25 +122,4 @@ - status = "okay"; - }; - }; -- fragment@19 { -- target = <&uart1>; -- __overlay__ { -- interrupt-parent = <&intc>; -- interrupts = <0x1 0x1d>; -- }; -- }; -- fragment@20 { -- target = <&spi1>; -- __overlay__ { -- interrupt-parent = <&intc>; -- interrupts = <0x1 0x1d>; -- }; -- }; -- fragment@21 { -- target = <&spi2>; -- __overlay__ { -- interrupt-parent = <&intc>; -- interrupts = <0x1 0x1d>; -- }; -- }; - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0513-config-Add-NF_TABLES-support.patch b/target/linux/brcm2708/patches-4.19/950-0513-config-Add-NF_TABLES-support.patch new file mode 100644 index 0000000000..2eac5b9d87 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0513-config-Add-NF_TABLES-support.patch @@ -0,0 +1,166 @@ +From cc26d5547fc63f2cead8d51379cfd782b70832ba Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 3 Jun 2019 14:57:56 +0100 +Subject: [PATCH 513/725] config: Add NF_TABLES support + +--- + arch/arm/configs/bcm2709_defconfig | 48 ++++++++++++++++++++++++++++++ + arch/arm/configs/bcmrpi_defconfig | 48 ++++++++++++++++++++++++++++++ + 2 files changed, 96 insertions(+) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -136,6 +136,36 @@ CONFIG_NF_CONNTRACK_SANE=m + CONFIG_NF_CONNTRACK_SIP=m + CONFIG_NF_CONNTRACK_TFTP=m + CONFIG_NF_CT_NETLINK=m ++CONFIG_NF_TABLES=m ++CONFIG_NF_TABLES_SET=m ++CONFIG_NF_TABLES_INET=y ++CONFIG_NF_TABLES_NETDEV=y ++CONFIG_NFT_NUMGEN=m ++CONFIG_NFT_CT=m ++CONFIG_NFT_FLOW_OFFLOAD=m ++CONFIG_NFT_COUNTER=m ++CONFIG_NFT_CONNLIMIT=m ++CONFIG_NFT_LOG=m ++CONFIG_NFT_LIMIT=m ++CONFIG_NFT_MASQ=m ++CONFIG_NFT_REDIR=m ++CONFIG_NFT_NAT=m ++CONFIG_NFT_TUNNEL=m ++CONFIG_NFT_OBJREF=m ++CONFIG_NFT_QUEUE=m ++CONFIG_NFT_QUOTA=m ++CONFIG_NFT_REJECT=m ++CONFIG_NFT_COMPAT=m ++CONFIG_NFT_HASH=m ++CONFIG_NFT_FIB_INET=m ++CONFIG_NFT_SOCKET=m ++CONFIG_NFT_OSF=m ++CONFIG_NFT_TPROXY=m ++CONFIG_NFT_DUP_NETDEV=m ++CONFIG_NFT_FWD_NETDEV=m ++CONFIG_NFT_FIB_NETDEV=m ++CONFIG_NF_FLOW_TABLE_INET=m ++CONFIG_NF_FLOW_TABLE=m + CONFIG_NETFILTER_XT_SET=m + CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m + CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +@@ -224,6 +254,14 @@ CONFIG_IP_VS_SED=m + CONFIG_IP_VS_NQ=m + CONFIG_IP_VS_FTP=m + CONFIG_IP_VS_PE_SIP=m ++CONFIG_NFT_CHAIN_ROUTE_IPV4=m ++CONFIG_NFT_DUP_IPV4=m ++CONFIG_NFT_FIB_IPV4=m ++CONFIG_NF_TABLES_ARP=y ++CONFIG_NF_FLOW_TABLE_IPV4=m ++CONFIG_NFT_CHAIN_NAT_IPV4=m ++CONFIG_NFT_MASQ_IPV4=m ++CONFIG_NFT_REDIR_IPV4=m + CONFIG_IP_NF_IPTABLES=m + CONFIG_IP_NF_MATCH_AH=m + CONFIG_IP_NF_MATCH_ECN=m +@@ -243,6 +281,13 @@ CONFIG_IP_NF_RAW=m + CONFIG_IP_NF_ARPTABLES=m + CONFIG_IP_NF_ARPFILTER=m + CONFIG_IP_NF_ARP_MANGLE=m ++CONFIG_NFT_CHAIN_ROUTE_IPV6=m ++CONFIG_NFT_CHAIN_NAT_IPV6=m ++CONFIG_NFT_MASQ_IPV6=m ++CONFIG_NFT_REDIR_IPV6=m ++CONFIG_NFT_DUP_IPV6=m ++CONFIG_NFT_FIB_IPV6=m ++CONFIG_NF_FLOW_TABLE_IPV6=m + CONFIG_IP6_NF_IPTABLES=m + CONFIG_IP6_NF_MATCH_AH=m + CONFIG_IP6_NF_MATCH_EUI64=m +@@ -261,6 +306,9 @@ CONFIG_IP6_NF_RAW=m + CONFIG_IP6_NF_NAT=m + CONFIG_IP6_NF_TARGET_MASQUERADE=m + CONFIG_IP6_NF_TARGET_NPT=m ++CONFIG_NF_TABLES_BRIDGE=y ++CONFIG_NFT_BRIDGE_REJECT=m ++CONFIG_NF_LOG_BRIDGE=m + CONFIG_BRIDGE_NF_EBTABLES=m + CONFIG_BRIDGE_EBT_BROUTE=m + CONFIG_BRIDGE_EBT_T_FILTER=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -129,6 +129,36 @@ CONFIG_NF_CONNTRACK_SANE=m + CONFIG_NF_CONNTRACK_SIP=m + CONFIG_NF_CONNTRACK_TFTP=m + CONFIG_NF_CT_NETLINK=m ++CONFIG_NF_TABLES=m ++CONFIG_NF_TABLES_SET=m ++CONFIG_NF_TABLES_INET=y ++CONFIG_NF_TABLES_NETDEV=y ++CONFIG_NFT_NUMGEN=m ++CONFIG_NFT_CT=m ++CONFIG_NFT_FLOW_OFFLOAD=m ++CONFIG_NFT_COUNTER=m ++CONFIG_NFT_CONNLIMIT=m ++CONFIG_NFT_LOG=m ++CONFIG_NFT_LIMIT=m ++CONFIG_NFT_MASQ=m ++CONFIG_NFT_REDIR=m ++CONFIG_NFT_NAT=m ++CONFIG_NFT_TUNNEL=m ++CONFIG_NFT_OBJREF=m ++CONFIG_NFT_QUEUE=m ++CONFIG_NFT_QUOTA=m ++CONFIG_NFT_REJECT=m ++CONFIG_NFT_COMPAT=m ++CONFIG_NFT_HASH=m ++CONFIG_NFT_FIB_INET=m ++CONFIG_NFT_SOCKET=m ++CONFIG_NFT_OSF=m ++CONFIG_NFT_TPROXY=m ++CONFIG_NFT_DUP_NETDEV=m ++CONFIG_NFT_FWD_NETDEV=m ++CONFIG_NFT_FIB_NETDEV=m ++CONFIG_NF_FLOW_TABLE_INET=m ++CONFIG_NF_FLOW_TABLE=m + CONFIG_NETFILTER_XT_SET=m + CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m + CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +@@ -217,6 +247,14 @@ CONFIG_IP_VS_SED=m + CONFIG_IP_VS_NQ=m + CONFIG_IP_VS_FTP=m + CONFIG_IP_VS_PE_SIP=m ++CONFIG_NFT_CHAIN_ROUTE_IPV4=m ++CONFIG_NFT_DUP_IPV4=m ++CONFIG_NFT_FIB_IPV4=m ++CONFIG_NF_TABLES_ARP=y ++CONFIG_NF_FLOW_TABLE_IPV4=m ++CONFIG_NFT_CHAIN_NAT_IPV4=m ++CONFIG_NFT_MASQ_IPV4=m ++CONFIG_NFT_REDIR_IPV4=m + CONFIG_IP_NF_IPTABLES=m + CONFIG_IP_NF_MATCH_AH=m + CONFIG_IP_NF_MATCH_ECN=m +@@ -236,6 +274,13 @@ CONFIG_IP_NF_RAW=m + CONFIG_IP_NF_ARPTABLES=m + CONFIG_IP_NF_ARPFILTER=m + CONFIG_IP_NF_ARP_MANGLE=m ++CONFIG_NFT_CHAIN_ROUTE_IPV6=m ++CONFIG_NFT_CHAIN_NAT_IPV6=m ++CONFIG_NFT_MASQ_IPV6=m ++CONFIG_NFT_REDIR_IPV6=m ++CONFIG_NFT_DUP_IPV6=m ++CONFIG_NFT_FIB_IPV6=m ++CONFIG_NF_FLOW_TABLE_IPV6=m + CONFIG_IP6_NF_IPTABLES=m + CONFIG_IP6_NF_MATCH_AH=m + CONFIG_IP6_NF_MATCH_EUI64=m +@@ -254,6 +299,9 @@ CONFIG_IP6_NF_RAW=m + CONFIG_IP6_NF_NAT=m + CONFIG_IP6_NF_TARGET_MASQUERADE=m + CONFIG_IP6_NF_TARGET_NPT=m ++CONFIG_NF_TABLES_BRIDGE=y ++CONFIG_NFT_BRIDGE_REJECT=m ++CONFIG_NF_LOG_BRIDGE=m + CONFIG_BRIDGE_NF_EBTABLES=m + CONFIG_BRIDGE_EBT_BROUTE=m + CONFIG_BRIDGE_EBT_T_FILTER=m diff --git a/target/linux/brcm2708/patches-4.19/950-0513-w1-ds2408-Fix-typo-after-49695ac46861-reset-on-outpu.patch b/target/linux/brcm2708/patches-4.19/950-0513-w1-ds2408-Fix-typo-after-49695ac46861-reset-on-outpu.patch deleted file mode 100644 index a41de17380..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0513-w1-ds2408-Fix-typo-after-49695ac46861-reset-on-outpu.patch +++ /dev/null @@ -1,31 +0,0 @@ -From b7e76f445cec9a72c1f8f22cba1b2afe0e77f849 Mon Sep 17 00:00:00 2001 -From: Mariusz Bialonczyk -Date: Thu, 16 May 2019 14:39:21 +0200 -Subject: [PATCH 513/703] w1: ds2408: Fix typo after 49695ac46861 (reset on - output_write retry with readback) - -commit 6660a04feb7ef648e50c792e19084d675fa6f3a2 upstream. - -Fix a typo in commit: -49695ac46861 w1: ds2408: reset on output_write retry with readback - -Fixes: 49695ac46861 ("w1: ds2408: reset on output_write retry with readback") -Reported-by: Phil Elwell -Cc: Jean-Francois Dagenais -Signed-off-by: Mariusz Bialonczyk -Signed-off-by: Greg Kroah-Hartman ---- - drivers/w1/slaves/w1_ds2408.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/w1/slaves/w1_ds2408.c -+++ b/drivers/w1/slaves/w1_ds2408.c -@@ -138,7 +138,7 @@ static ssize_t status_control_read(struc - W1_F29_REG_CONTROL_AND_STATUS, buf); - } - --#ifdef fCONFIG_W1_SLAVE_DS2408_READBACK -+#ifdef CONFIG_W1_SLAVE_DS2408_READBACK - static bool optional_read_back_valid(struct w1_slave *sl, u8 expected) - { - u8 w1_buf[3]; diff --git a/target/linux/brcm2708/patches-4.19/950-0514-BCM270X_DT-Rename-Pi-Zero-W-DT-files.patch b/target/linux/brcm2708/patches-4.19/950-0514-BCM270X_DT-Rename-Pi-Zero-W-DT-files.patch deleted file mode 100644 index e3ab795700..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0514-BCM270X_DT-Rename-Pi-Zero-W-DT-files.patch +++ /dev/null @@ -1,367 +0,0 @@ -From 8daca09e4eea788e6fc2fdf3d8ab4c0976128d3d Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 28 May 2019 16:36:04 +0100 -Subject: [PATCH 514/703] BCM270X_DT: Rename Pi Zero W DT files - -The downtream Pi Zero W dts file uses the digit 0, whereas upstream -chose to spell it out - "zero-w". The firmware has, for a long time, -looked for bcm2708-rpi-zero-w.dtb first before falling back to the -numerical version. Therefore it is better to follow upstream and -make the switch to "bcm2708-rpi-zero-w". - -At the same time, remove some overrides that duplicate values -inherited from the shared .dtsi files. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/Makefile | 2 +- - .../boot/dts/{bcm2708-rpi-0-w.dts => bcm2708-rpi-zero-w.dts} | 5 ----- - 2 files changed, 1 insertion(+), 6 deletions(-) - rename arch/arm/boot/dts/{bcm2708-rpi-0-w.dts => bcm2708-rpi-zero-w.dts} (97%) - ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -4,7 +4,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ - bcm2708-rpi-b.dtb \ - bcm2708-rpi-b-plus.dtb \ - bcm2708-rpi-cm.dtb \ -- bcm2708-rpi-0-w.dtb \ -+ bcm2708-rpi-zero-w.dtb \ - bcm2709-rpi-2-b.dtb \ - bcm2710-rpi-3-b.dtb \ - bcm2710-rpi-3-b-plus.dtb \ ---- a/arch/arm/boot/dts/bcm2708-rpi-0-w.dts -+++ /dev/null -@@ -1,167 +0,0 @@ --/dts-v1/; -- --#include "bcm2708.dtsi" --#include "bcm283x-rpi-csi1-2lane.dtsi" -- --/ { -- compatible = "raspberrypi,model-zero-w", "brcm,bcm2835"; -- model = "Raspberry Pi Zero W"; -- -- chosen { -- bootargs = "coherent_pool=1M 8250.nr_uarts=1"; -- }; -- -- aliases { -- serial0 = &uart1; -- serial1 = &uart0; -- mmc1 = &mmcnr; -- }; --}; -- --&gpio { -- 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 = <>; -- }; --}; -- --&mmcnr { -- pinctrl-names = "default"; -- pinctrl-0 = <&sdio_pins>; -- bus-width = <4>; -- 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 = <125000000>; -- }; -- -- spidev1: spidev@1{ -- compatible = "spidev"; -- reg = <1>; /* CE1 */ -- #address-cells = <1>; -- #size-cells = <0>; -- spi-max-frequency = <125000000>; -- }; --}; -- --&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>; --}; -- --/ { -- __overrides__ { -- act_led_gpio = <&act_led>,"gpios:4"; -- act_led_activelow = <&act_led>,"gpios:8"; -- act_led_trigger = <&act_led>,"linux,default-trigger"; -- }; --}; ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts -@@ -0,0 +1,162 @@ -+/dts-v1/; -+ -+#include "bcm2708.dtsi" -+#include "bcm283x-rpi-csi1-2lane.dtsi" -+ -+/ { -+ compatible = "raspberrypi,model-zero-w", "brcm,bcm2835"; -+ model = "Raspberry Pi Zero W"; -+ -+ chosen { -+ bootargs = "coherent_pool=1M 8250.nr_uarts=1"; -+ }; -+ -+ aliases { -+ serial0 = &uart1; -+ serial1 = &uart0; -+ mmc1 = &mmcnr; -+ }; -+}; -+ -+&gpio { -+ 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 = <>; -+ }; -+}; -+ -+&mmcnr { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdio_pins>; -+ bus-width = <4>; -+ 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 = <125000000>; -+ }; -+ -+ spidev1: spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ }; -+}; -+ -+&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 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+&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>; -+}; -+ -+/ { -+ __overrides__ { -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; -+ }; -+}; diff --git a/target/linux/brcm2708/patches-4.19/950-0514-Fixed-48k-timing-issue.patch b/target/linux/brcm2708/patches-4.19/950-0514-Fixed-48k-timing-issue.patch new file mode 100644 index 0000000000..8d5e6d5ed1 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0514-Fixed-48k-timing-issue.patch @@ -0,0 +1,95 @@ +From 534eaba07cc9ffcf9ee74aeeeb9b2ab96b18ece5 Mon Sep 17 00:00:00 2001 +From: IQaudIO +Date: Thu, 6 Jun 2019 10:20:55 +0100 +Subject: [PATCH 514/725] Fixed 48k timing issue + +--- + sound/soc/bcm/iqaudio-codec.c | 33 ++++++++++++++++++++++++++++----- + 1 file changed, 28 insertions(+), 5 deletions(-) + +--- a/sound/soc/bcm/iqaudio-codec.c ++++ b/sound/soc/bcm/iqaudio-codec.c +@@ -45,11 +45,15 @@ static int snd_rpi_iqaudio_pll_control(s + 0); + if (ret) + dev_err(card->dev, "Failed to bypass PLL: %d\n", ret); ++ /* Allow PLL time to bypass */ ++ msleep(100); + } else if (SND_SOC_DAPM_EVENT_ON(event)) { + ret = snd_soc_dai_set_pll(codec_dai, 0, DA7213_SYSCLK_PLL, 0, + pll_out); + if (ret) + dev_err(card->dev, "Failed to enable PLL: %d\n", ret); ++ /* Allow PLL time to lock */ ++ msleep(100); + } + + return ret; +@@ -71,6 +75,13 @@ static int snd_rpi_iqaudio_post_dapm_eve + return 0; + } + ++static const struct snd_kcontrol_new dapm_controls[] = { ++ SOC_DAPM_PIN_SWITCH("HP Jack"), ++ SOC_DAPM_PIN_SWITCH("MIC Jack"), ++ SOC_DAPM_PIN_SWITCH("Onboard MIC"), ++ SOC_DAPM_PIN_SWITCH("AUX Jack"), ++}; ++ + static const struct snd_soc_dapm_widget dapm_widgets[] = { + SND_SOC_DAPM_HP("HP Jack", NULL), + SND_SOC_DAPM_MIC("MIC Jack", NULL), +@@ -87,14 +98,14 @@ static const struct snd_soc_dapm_route a + {"HP Jack", NULL, "HPR"}, + {"HP Jack", NULL, "PLL Control"}, + +- {"AUX Jack", NULL, "AUXR"}, +- {"AUX Jack", NULL, "AUXL"}, ++ {"AUXR", NULL, "AUX Jack"}, ++ {"AUXL", NULL, "AUX Jack"}, + {"AUX Jack", NULL, "PLL Control"}, + + /* Assume Mic1 is linked to Headset and Mic2 to on-board mic */ +- {"MIC Jack", NULL, "MIC1"}, ++ {"MIC1", NULL, "MIC Jack"}, + {"MIC Jack", NULL, "PLL Control"}, +- {"Onboard MIC", NULL, "MIC2"}, ++ {"MIC2", NULL, "Onboard MIC"}, + {"Onboard MIC", NULL, "PLL Control"}, + }; + +@@ -106,6 +117,16 @@ static int snd_rpi_iqaudio_codec_init(st + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret; + ++ /* ++ * Disable AUX Jack Pin by default to prevent PLL being enabled at ++ * startup. This avoids holding the PLL to a fixed SR config for ++ * subsequent streams. ++ * ++ * This pin can still be enabled later, as required by user-space. ++ */ ++ snd_soc_dapm_disable_pin(&rtd->card->dapm, "AUX Jack"); ++ snd_soc_dapm_sync(&rtd->card->dapm); ++ + /* Set bclk ratio to align with codec's BCLK rate */ + ret = snd_soc_dai_set_bclk_ratio(cpu_dai, 64); + if (ret) { +@@ -168,6 +189,8 @@ static struct snd_soc_card snd_rpi_iqaud + .owner = THIS_MODULE, + .dai_link = snd_rpi_iqaudio_codec_dai, + .num_links = ARRAY_SIZE(snd_rpi_iqaudio_codec_dai), ++ .controls = dapm_controls, ++ .num_controls = ARRAY_SIZE(dapm_controls), + .dapm_widgets = dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(dapm_widgets), + .dapm_routes = audio_map, +@@ -204,7 +227,7 @@ static int snd_rpi_iqaudio_codec_probe(s + + if (of_property_read_string(pdev->dev.of_node, + "dai_stream_name", &dai->stream_name)) +- dai->stream_name = "IQaudIO CODEC HiFi v1.1"; ++ dai->stream_name = "IQaudIO CODEC HiFi v1.2"; + + } + diff --git a/target/linux/brcm2708/patches-4.19/950-0515-BCM270X_DT-Create-bcm2708-rpi-zero.dts.patch b/target/linux/brcm2708/patches-4.19/950-0515-BCM270X_DT-Create-bcm2708-rpi-zero.dts.patch deleted file mode 100644 index 54d61650ca..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0515-BCM270X_DT-Create-bcm2708-rpi-zero.dts.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 926eb05f48f4c805075aa535a444127de6de0dbb Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 28 May 2019 16:23:51 +0100 -Subject: [PATCH 515/703] BCM270X_DT: Create bcm2708-rpi-zero.dts - -The Pi Zero deserves a dedicated .dtb file - sharing the b-plus .dtb -has been observed to cause an issue with the MAC address of some -Ethernet dongles. - -See: https://github.com/raspberrypi/linux/issues/2990 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/bcm2708-rpi-zero.dts | 117 +++++++++++++++++++++++++ - 2 files changed, 118 insertions(+) - create mode 100644 arch/arm/boot/dts/bcm2708-rpi-zero.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-zero.dtb \ - bcm2708-rpi-zero-w.dtb \ - bcm2709-rpi-2-b.dtb \ - bcm2710-rpi-3-b.dtb \ ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2708-rpi-zero.dts -@@ -0,0 +1,117 @@ -+/dts-v1/; -+ -+#include "bcm2708.dtsi" -+#include "bcm283x-rpi-csi1-2lane.dtsi" -+ -+/ { -+ compatible = "raspberrypi,model-zero", "brcm,bcm2835"; -+ model = "Raspberry Pi Zero"; -+ -+ chosen { -+ bootargs = "coherent_pool=1M"; -+ }; -+}; -+ -+&gpio { -+ 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 */ -+ }; -+ -+ audio_pins: audio_pins { -+ brcm,pins = <>; -+ brcm,function = <>; -+ }; -+}; -+ -+&uart0 { -+ 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 = <125000000>; -+ }; -+ -+ spidev1: spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ }; -+}; -+ -+&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 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+&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>; -+}; -+ -+/ { -+ __overrides__ { -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; -+ }; -+}; diff --git a/target/linux/brcm2708/patches-4.19/950-0515-staging-bcm2835-codec-Convert-V4L2-nsec-timestamps-t.patch b/target/linux/brcm2708/patches-4.19/950-0515-staging-bcm2835-codec-Convert-V4L2-nsec-timestamps-t.patch new file mode 100644 index 0000000000..9f1bd55868 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0515-staging-bcm2835-codec-Convert-V4L2-nsec-timestamps-t.patch @@ -0,0 +1,46 @@ +From 7b288978c69b614afbc4de50a2e68c8e26c988ef Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 10 May 2019 14:11:58 +0100 +Subject: [PATCH 515/725] staging: bcm2835-codec: Convert V4L2 nsec timestamps + to MMAL usec + +V4L2 uses nsecs, whilst MMAL uses usecs, but the code wasn't converting +between them. This upsets video encode rate control. + +Signed-off-by: Dave Stevenson +--- + .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -823,7 +823,8 @@ static void op_buffer_cb(struct vchiq_mm + vb2->flags |= V4L2_BUF_FLAG_LAST; + } + +- vb2->vb2_buf.timestamp = mmal_buf->pts; ++ /* vb2 timestamps in nsecs, mmal in usecs */ ++ vb2->vb2_buf.timestamp = mmal_buf->pts * 1000; + + vb2_set_plane_payload(&vb2->vb2_buf, 0, mmal_buf->length); + if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) +@@ -847,6 +848,7 @@ static void op_buffer_cb(struct vchiq_mm + static void vb2_to_mmal_buffer(struct m2m_mmal_buffer *buf, + struct vb2_v4l2_buffer *vb2) + { ++ u64 pts; + buf->mmal.mmal_flags = 0; + if (vb2->flags & V4L2_BUF_FLAG_KEYFRAME) + buf->mmal.mmal_flags |= MMAL_BUFFER_HEADER_FLAG_KEYFRAME; +@@ -869,7 +871,10 @@ static void vb2_to_mmal_buffer(struct m2 + if (!buf->mmal.length || vb2->flags & V4L2_BUF_FLAG_LAST) + buf->mmal.mmal_flags |= MMAL_BUFFER_HEADER_FLAG_EOS; + +- buf->mmal.pts = vb2->vb2_buf.timestamp; ++ /* vb2 timestamps in nsecs, mmal in usecs */ ++ pts = vb2->vb2_buf.timestamp; ++ do_div(pts, 1000); ++ buf->mmal.pts = pts; + buf->mmal.dts = MMAL_TIME_UNKNOWN; + } + diff --git a/target/linux/brcm2708/patches-4.19/950-0516-overlays-Fix-mmc-related-overlays-after-refactor.patch b/target/linux/brcm2708/patches-4.19/950-0516-overlays-Fix-mmc-related-overlays-after-refactor.patch deleted file mode 100644 index 850a07997f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0516-overlays-Fix-mmc-related-overlays-after-refactor.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 59ffffa03628f1df3dc63d8f2f1b61bce4b322c2 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 30 May 2019 12:25:29 +0100 -Subject: [PATCH 516/703] overlays: Fix mmc-related overlays after refactor - -The addition of the mmcnr node to the base dtbs caused some overlays to -not work as they should. Patch up pi3-disable-wifi, balena-fin and -sdhost. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/balena-fin-overlay.dts | 7 ++++--- - arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts | 7 +++++++ - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 7 +++++++ - 3 files changed, 18 insertions(+), 3 deletions(-) - ---- a/arch/arm/boot/dts/overlays/balena-fin-overlay.dts -+++ b/arch/arm/boot/dts/overlays/balena-fin-overlay.dts -@@ -5,13 +5,12 @@ - compatible = "brcm,bcm2835"; - - fragment@0 { -- target = <&mmc>; -- sdio_wifi: __overlay__ { -+ target = <&mmcnr>; -+ __overlay__ { - pinctrl-names = "default"; - pinctrl-0 = <&sdio_pins>; - bus-width = <4>; - brcm,overclock-50 = <35>; -- non-removable; - status = "okay"; - }; - }; -@@ -43,6 +42,8 @@ - compatible = "gpio-poweroff"; - gpios = <&gpio 40 1>; - force; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&power_ctrl_pins>; - }; - - i2c_soft: i2c@0 { ---- a/arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts -@@ -10,4 +10,11 @@ - status = "disabled"; - }; - }; -+ -+ fragment@1 { -+ target = <&mmcnr>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; - }; ---- a/arch/arm/boot/dts/overlays/sdhost-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -22,6 +22,13 @@ - }; - }; - -+ fragment@2 { -+ target = <&mmcnr>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ - __overrides__ { - overclock_50 = <&frag0>,"brcm,overclock-50:0"; - force_pio = <&frag0>,"brcm,force-pio?"; diff --git a/target/linux/brcm2708/patches-4.19/950-0516-staging-bcm2835-codec-Add-support-for-setting-S_PARM.patch b/target/linux/brcm2708/patches-4.19/950-0516-staging-bcm2835-codec-Add-support-for-setting-S_PARM.patch new file mode 100644 index 0000000000..6cba6c8000 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0516-staging-bcm2835-codec-Add-support-for-setting-S_PARM.patch @@ -0,0 +1,118 @@ +From 36a826c4ef3da5d893b44816692f9b77a4842536 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 10 May 2019 14:13:11 +0100 +Subject: [PATCH 516/725] staging: bcm2835-codec: Add support for setting + S_PARM and G_PARM + +Video encode can use the frame rate for rate control calculations, +therefore plumb it through from V4L2's [S|G]_PARM ioctl. + +Signed-off-by: Dave Stevenson +--- + .../bcm2835-codec/bcm2835-v4l2-codec.c | 52 +++++++++++++++++-- + 1 file changed, 48 insertions(+), 4 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -447,6 +447,8 @@ struct bcm2835_codec_ctx { + /* Source and destination queue data */ + struct bcm2835_codec_q_data q_data[2]; + s32 bitrate; ++ unsigned int framerate_num; ++ unsigned int framerate_denom; + + bool aborting; + int num_ip_buffers; +@@ -610,8 +612,8 @@ static void setup_mmal_port_format(struc + port->es.video.height = q_data->height; + port->es.video.crop.width = q_data->crop_width; + port->es.video.crop.height = q_data->crop_height; +- port->es.video.frame_rate.num = 0; +- port->es.video.frame_rate.den = 1; ++ port->es.video.frame_rate.num = ctx->framerate_num; ++ port->es.video.frame_rate.den = ctx->framerate_denom; + } else { + /* Compressed format - leave resolution as 0 for decode */ + if (ctx->dev->role == DECODE) { +@@ -625,9 +627,9 @@ static void setup_mmal_port_format(struc + port->es.video.crop.width = q_data->crop_width; + port->es.video.crop.height = q_data->crop_height; + port->format.bitrate = ctx->bitrate; ++ port->es.video.frame_rate.num = ctx->framerate_num; ++ port->es.video.frame_rate.den = ctx->framerate_denom; + } +- port->es.video.frame_rate.num = 0; +- port->es.video.frame_rate.den = 1; + } + port->es.video.crop.x = 0; + port->es.video.crop.y = 0; +@@ -1361,6 +1363,41 @@ static int vidioc_s_selection(struct fil + return 0; + } + ++static int vidioc_s_parm(struct file *file, void *priv, ++ struct v4l2_streamparm *parm) ++{ ++ struct bcm2835_codec_ctx *ctx = file2ctx(file); ++ ++ if (parm->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) ++ return -EINVAL; ++ ++ ctx->framerate_num = ++ parm->parm.output.timeperframe.denominator; ++ ctx->framerate_denom = ++ parm->parm.output.timeperframe.numerator; ++ ++ parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; ++ ++ return 0; ++} ++ ++static int vidioc_g_parm(struct file *file, void *priv, ++ struct v4l2_streamparm *parm) ++{ ++ struct bcm2835_codec_ctx *ctx = file2ctx(file); ++ ++ if (parm->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) ++ return -EINVAL; ++ ++ parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; ++ parm->parm.output.timeperframe.denominator = ++ ctx->framerate_num; ++ parm->parm.output.timeperframe.numerator = ++ ctx->framerate_denom; ++ ++ return 0; ++} ++ + static int vidioc_subscribe_evt(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) + { +@@ -1725,6 +1762,9 @@ static const struct v4l2_ioctl_ops bcm28 + .vidioc_g_selection = vidioc_g_selection, + .vidioc_s_selection = vidioc_s_selection, + ++ .vidioc_g_parm = vidioc_g_parm, ++ .vidioc_s_parm = vidioc_s_parm, ++ + .vidioc_subscribe_event = vidioc_subscribe_evt, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, + +@@ -2546,6 +2586,8 @@ static int bcm2835_codec_create(struct p + case DECODE: + v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD); + v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); ++ v4l2_disable_ioctl(vfd, VIDIOC_S_PARM); ++ v4l2_disable_ioctl(vfd, VIDIOC_G_PARM); + video_nr = decode_video_nr; + break; + case ENCODE: +@@ -2558,6 +2600,8 @@ static int bcm2835_codec_create(struct p + v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); + v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD); + v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD); ++ v4l2_disable_ioctl(vfd, VIDIOC_S_PARM); ++ v4l2_disable_ioctl(vfd, VIDIOC_G_PARM); + video_nr = isp_video_nr; + break; + default: diff --git a/target/linux/brcm2708/patches-4.19/950-0517-config-Add-NF_TABLES-support.patch b/target/linux/brcm2708/patches-4.19/950-0517-config-Add-NF_TABLES-support.patch deleted file mode 100644 index bebcd4efa7..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0517-config-Add-NF_TABLES-support.patch +++ /dev/null @@ -1,166 +0,0 @@ -From f022f74f85fa0871e650c1a2fe385d7a24d07d92 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 3 Jun 2019 14:57:56 +0100 -Subject: [PATCH 517/703] config: Add NF_TABLES support - ---- - arch/arm/configs/bcm2709_defconfig | 48 ++++++++++++++++++++++++++++++ - arch/arm/configs/bcmrpi_defconfig | 48 ++++++++++++++++++++++++++++++ - 2 files changed, 96 insertions(+) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -136,6 +136,36 @@ CONFIG_NF_CONNTRACK_SANE=m - CONFIG_NF_CONNTRACK_SIP=m - CONFIG_NF_CONNTRACK_TFTP=m - CONFIG_NF_CT_NETLINK=m -+CONFIG_NF_TABLES=m -+CONFIG_NF_TABLES_SET=m -+CONFIG_NF_TABLES_INET=y -+CONFIG_NF_TABLES_NETDEV=y -+CONFIG_NFT_NUMGEN=m -+CONFIG_NFT_CT=m -+CONFIG_NFT_FLOW_OFFLOAD=m -+CONFIG_NFT_COUNTER=m -+CONFIG_NFT_CONNLIMIT=m -+CONFIG_NFT_LOG=m -+CONFIG_NFT_LIMIT=m -+CONFIG_NFT_MASQ=m -+CONFIG_NFT_REDIR=m -+CONFIG_NFT_NAT=m -+CONFIG_NFT_TUNNEL=m -+CONFIG_NFT_OBJREF=m -+CONFIG_NFT_QUEUE=m -+CONFIG_NFT_QUOTA=m -+CONFIG_NFT_REJECT=m -+CONFIG_NFT_COMPAT=m -+CONFIG_NFT_HASH=m -+CONFIG_NFT_FIB_INET=m -+CONFIG_NFT_SOCKET=m -+CONFIG_NFT_OSF=m -+CONFIG_NFT_TPROXY=m -+CONFIG_NFT_DUP_NETDEV=m -+CONFIG_NFT_FWD_NETDEV=m -+CONFIG_NFT_FIB_NETDEV=m -+CONFIG_NF_FLOW_TABLE_INET=m -+CONFIG_NF_FLOW_TABLE=m - CONFIG_NETFILTER_XT_SET=m - CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m - CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -@@ -224,6 +254,14 @@ CONFIG_IP_VS_SED=m - CONFIG_IP_VS_NQ=m - CONFIG_IP_VS_FTP=m - CONFIG_IP_VS_PE_SIP=m -+CONFIG_NFT_CHAIN_ROUTE_IPV4=m -+CONFIG_NFT_DUP_IPV4=m -+CONFIG_NFT_FIB_IPV4=m -+CONFIG_NF_TABLES_ARP=y -+CONFIG_NF_FLOW_TABLE_IPV4=m -+CONFIG_NFT_CHAIN_NAT_IPV4=m -+CONFIG_NFT_MASQ_IPV4=m -+CONFIG_NFT_REDIR_IPV4=m - CONFIG_IP_NF_IPTABLES=m - CONFIG_IP_NF_MATCH_AH=m - CONFIG_IP_NF_MATCH_ECN=m -@@ -243,6 +281,13 @@ CONFIG_IP_NF_RAW=m - CONFIG_IP_NF_ARPTABLES=m - CONFIG_IP_NF_ARPFILTER=m - CONFIG_IP_NF_ARP_MANGLE=m -+CONFIG_NFT_CHAIN_ROUTE_IPV6=m -+CONFIG_NFT_CHAIN_NAT_IPV6=m -+CONFIG_NFT_MASQ_IPV6=m -+CONFIG_NFT_REDIR_IPV6=m -+CONFIG_NFT_DUP_IPV6=m -+CONFIG_NFT_FIB_IPV6=m -+CONFIG_NF_FLOW_TABLE_IPV6=m - CONFIG_IP6_NF_IPTABLES=m - CONFIG_IP6_NF_MATCH_AH=m - CONFIG_IP6_NF_MATCH_EUI64=m -@@ -261,6 +306,9 @@ CONFIG_IP6_NF_RAW=m - CONFIG_IP6_NF_NAT=m - CONFIG_IP6_NF_TARGET_MASQUERADE=m - CONFIG_IP6_NF_TARGET_NPT=m -+CONFIG_NF_TABLES_BRIDGE=y -+CONFIG_NFT_BRIDGE_REJECT=m -+CONFIG_NF_LOG_BRIDGE=m - CONFIG_BRIDGE_NF_EBTABLES=m - CONFIG_BRIDGE_EBT_BROUTE=m - CONFIG_BRIDGE_EBT_T_FILTER=m ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -129,6 +129,36 @@ CONFIG_NF_CONNTRACK_SANE=m - CONFIG_NF_CONNTRACK_SIP=m - CONFIG_NF_CONNTRACK_TFTP=m - CONFIG_NF_CT_NETLINK=m -+CONFIG_NF_TABLES=m -+CONFIG_NF_TABLES_SET=m -+CONFIG_NF_TABLES_INET=y -+CONFIG_NF_TABLES_NETDEV=y -+CONFIG_NFT_NUMGEN=m -+CONFIG_NFT_CT=m -+CONFIG_NFT_FLOW_OFFLOAD=m -+CONFIG_NFT_COUNTER=m -+CONFIG_NFT_CONNLIMIT=m -+CONFIG_NFT_LOG=m -+CONFIG_NFT_LIMIT=m -+CONFIG_NFT_MASQ=m -+CONFIG_NFT_REDIR=m -+CONFIG_NFT_NAT=m -+CONFIG_NFT_TUNNEL=m -+CONFIG_NFT_OBJREF=m -+CONFIG_NFT_QUEUE=m -+CONFIG_NFT_QUOTA=m -+CONFIG_NFT_REJECT=m -+CONFIG_NFT_COMPAT=m -+CONFIG_NFT_HASH=m -+CONFIG_NFT_FIB_INET=m -+CONFIG_NFT_SOCKET=m -+CONFIG_NFT_OSF=m -+CONFIG_NFT_TPROXY=m -+CONFIG_NFT_DUP_NETDEV=m -+CONFIG_NFT_FWD_NETDEV=m -+CONFIG_NFT_FIB_NETDEV=m -+CONFIG_NF_FLOW_TABLE_INET=m -+CONFIG_NF_FLOW_TABLE=m - CONFIG_NETFILTER_XT_SET=m - CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m - CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -@@ -217,6 +247,14 @@ CONFIG_IP_VS_SED=m - CONFIG_IP_VS_NQ=m - CONFIG_IP_VS_FTP=m - CONFIG_IP_VS_PE_SIP=m -+CONFIG_NFT_CHAIN_ROUTE_IPV4=m -+CONFIG_NFT_DUP_IPV4=m -+CONFIG_NFT_FIB_IPV4=m -+CONFIG_NF_TABLES_ARP=y -+CONFIG_NF_FLOW_TABLE_IPV4=m -+CONFIG_NFT_CHAIN_NAT_IPV4=m -+CONFIG_NFT_MASQ_IPV4=m -+CONFIG_NFT_REDIR_IPV4=m - CONFIG_IP_NF_IPTABLES=m - CONFIG_IP_NF_MATCH_AH=m - CONFIG_IP_NF_MATCH_ECN=m -@@ -236,6 +274,13 @@ CONFIG_IP_NF_RAW=m - CONFIG_IP_NF_ARPTABLES=m - CONFIG_IP_NF_ARPFILTER=m - CONFIG_IP_NF_ARP_MANGLE=m -+CONFIG_NFT_CHAIN_ROUTE_IPV6=m -+CONFIG_NFT_CHAIN_NAT_IPV6=m -+CONFIG_NFT_MASQ_IPV6=m -+CONFIG_NFT_REDIR_IPV6=m -+CONFIG_NFT_DUP_IPV6=m -+CONFIG_NFT_FIB_IPV6=m -+CONFIG_NF_FLOW_TABLE_IPV6=m - CONFIG_IP6_NF_IPTABLES=m - CONFIG_IP6_NF_MATCH_AH=m - CONFIG_IP6_NF_MATCH_EUI64=m -@@ -254,6 +299,9 @@ CONFIG_IP6_NF_RAW=m - CONFIG_IP6_NF_NAT=m - CONFIG_IP6_NF_TARGET_MASQUERADE=m - CONFIG_IP6_NF_TARGET_NPT=m -+CONFIG_NF_TABLES_BRIDGE=y -+CONFIG_NFT_BRIDGE_REJECT=m -+CONFIG_NF_LOG_BRIDGE=m - CONFIG_BRIDGE_NF_EBTABLES=m - CONFIG_BRIDGE_EBT_BROUTE=m - CONFIG_BRIDGE_EBT_T_FILTER=m diff --git a/target/linux/brcm2708/patches-4.19/950-0517-w1-w1-gpio-Make-GPIO-an-output-for-strong-pullup.patch b/target/linux/brcm2708/patches-4.19/950-0517-w1-w1-gpio-Make-GPIO-an-output-for-strong-pullup.patch new file mode 100644 index 0000000000..030ddb6a93 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0517-w1-w1-gpio-Make-GPIO-an-output-for-strong-pullup.patch @@ -0,0 +1,27 @@ +From bc6a43d8d2aabc061c407d6644f04b9c51b65280 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 12 Jun 2019 17:15:05 +0100 +Subject: [PATCH 517/725] w1: w1-gpio: Make GPIO an output for strong pullup + +The logic to drive the data line high to implement a strong pullup +assumed that the pin was already an output - setting a value does +not change an input. + +See: https://github.com/raspberrypi/firmware/issues/1143 + +Signed-off-by: Phil Elwell +--- + drivers/w1/masters/w1-gpio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/w1/masters/w1-gpio.c ++++ b/drivers/w1/masters/w1-gpio.c +@@ -33,7 +33,7 @@ static u8 w1_gpio_set_pullup(void *data, + * This will OVERRIDE open drain emulation and force-pull + * the line high for some time. + */ +- gpiod_set_raw_value(pdata->gpiod, 1); ++ gpiod_direction_output_raw(pdata->gpiod, 1); + msleep(pdata->pullup_duration); + /* + * This will simply set the line as input since we are doing diff --git a/target/linux/brcm2708/patches-4.19/950-0518-Fixed-48k-timing-issue.patch b/target/linux/brcm2708/patches-4.19/950-0518-Fixed-48k-timing-issue.patch deleted file mode 100644 index 55cf2dd72e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0518-Fixed-48k-timing-issue.patch +++ /dev/null @@ -1,95 +0,0 @@ -From a06ffe5daac9ef401c406a8aa28b5d20279e0cdb Mon Sep 17 00:00:00 2001 -From: IQaudIO -Date: Thu, 6 Jun 2019 10:20:55 +0100 -Subject: [PATCH 518/703] Fixed 48k timing issue - ---- - sound/soc/bcm/iqaudio-codec.c | 33 ++++++++++++++++++++++++++++----- - 1 file changed, 28 insertions(+), 5 deletions(-) - ---- a/sound/soc/bcm/iqaudio-codec.c -+++ b/sound/soc/bcm/iqaudio-codec.c -@@ -45,11 +45,15 @@ static int snd_rpi_iqaudio_pll_control(s - 0); - if (ret) - dev_err(card->dev, "Failed to bypass PLL: %d\n", ret); -+ /* Allow PLL time to bypass */ -+ msleep(100); - } else if (SND_SOC_DAPM_EVENT_ON(event)) { - ret = snd_soc_dai_set_pll(codec_dai, 0, DA7213_SYSCLK_PLL, 0, - pll_out); - if (ret) - dev_err(card->dev, "Failed to enable PLL: %d\n", ret); -+ /* Allow PLL time to lock */ -+ msleep(100); - } - - return ret; -@@ -71,6 +75,13 @@ static int snd_rpi_iqaudio_post_dapm_eve - return 0; - } - -+static const struct snd_kcontrol_new dapm_controls[] = { -+ SOC_DAPM_PIN_SWITCH("HP Jack"), -+ SOC_DAPM_PIN_SWITCH("MIC Jack"), -+ SOC_DAPM_PIN_SWITCH("Onboard MIC"), -+ SOC_DAPM_PIN_SWITCH("AUX Jack"), -+}; -+ - static const struct snd_soc_dapm_widget dapm_widgets[] = { - SND_SOC_DAPM_HP("HP Jack", NULL), - SND_SOC_DAPM_MIC("MIC Jack", NULL), -@@ -87,14 +98,14 @@ static const struct snd_soc_dapm_route a - {"HP Jack", NULL, "HPR"}, - {"HP Jack", NULL, "PLL Control"}, - -- {"AUX Jack", NULL, "AUXR"}, -- {"AUX Jack", NULL, "AUXL"}, -+ {"AUXR", NULL, "AUX Jack"}, -+ {"AUXL", NULL, "AUX Jack"}, - {"AUX Jack", NULL, "PLL Control"}, - - /* Assume Mic1 is linked to Headset and Mic2 to on-board mic */ -- {"MIC Jack", NULL, "MIC1"}, -+ {"MIC1", NULL, "MIC Jack"}, - {"MIC Jack", NULL, "PLL Control"}, -- {"Onboard MIC", NULL, "MIC2"}, -+ {"MIC2", NULL, "Onboard MIC"}, - {"Onboard MIC", NULL, "PLL Control"}, - }; - -@@ -106,6 +117,16 @@ static int snd_rpi_iqaudio_codec_init(st - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int ret; - -+ /* -+ * Disable AUX Jack Pin by default to prevent PLL being enabled at -+ * startup. This avoids holding the PLL to a fixed SR config for -+ * subsequent streams. -+ * -+ * This pin can still be enabled later, as required by user-space. -+ */ -+ snd_soc_dapm_disable_pin(&rtd->card->dapm, "AUX Jack"); -+ snd_soc_dapm_sync(&rtd->card->dapm); -+ - /* Set bclk ratio to align with codec's BCLK rate */ - ret = snd_soc_dai_set_bclk_ratio(cpu_dai, 64); - if (ret) { -@@ -168,6 +189,8 @@ static struct snd_soc_card snd_rpi_iqaud - .owner = THIS_MODULE, - .dai_link = snd_rpi_iqaudio_codec_dai, - .num_links = ARRAY_SIZE(snd_rpi_iqaudio_codec_dai), -+ .controls = dapm_controls, -+ .num_controls = ARRAY_SIZE(dapm_controls), - .dapm_widgets = dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(dapm_widgets), - .dapm_routes = audio_map, -@@ -204,7 +227,7 @@ static int snd_rpi_iqaudio_codec_probe(s - - if (of_property_read_string(pdev->dev.of_node, - "dai_stream_name", &dai->stream_name)) -- dai->stream_name = "IQaudIO CODEC HiFi v1.1"; -+ dai->stream_name = "IQaudIO CODEC HiFi v1.2"; - - } - diff --git a/target/linux/brcm2708/patches-4.19/950-0518-overlays-Update-w1-gpio-and-w1-gpio-pullup.patch b/target/linux/brcm2708/patches-4.19/950-0518-overlays-Update-w1-gpio-and-w1-gpio-pullup.patch new file mode 100644 index 0000000000..248b5239ea --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0518-overlays-Update-w1-gpio-and-w1-gpio-pullup.patch @@ -0,0 +1,78 @@ +From 62e3712d23602b04dd28340ea05643708d603241 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 12 Jun 2019 17:32:11 +0100 +Subject: [PATCH 518/725] overlays: Update w1-gpio and w1-gpio-pullup + +The parasitic power (power on data) feature is now enabled by +default in the w1-gpio driver, so update the README and make the +"pullup" parameter a no-op. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/README | 9 ++------- + arch/arm/boot/dts/overlays/w1-gpio-overlay.dts | 3 +-- + arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts | 3 +-- + 3 files changed, 4 insertions(+), 11 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -2261,9 +2261,7 @@ Info: Configures the w1-gpio Onewire i + Use this overlay if you *don't* need a GPIO to drive an external pullup. + Load: dtoverlay=w1-gpio,= + Params: gpiopin GPIO for I/O (default "4") +- +- pullup Non-zero, "on", or "y" to enable the parasitic +- power (2-wire, power-on-data) feature ++ pullup Now enabled by default (ignored) + + + Name: w1-gpio-pullup +@@ -2271,11 +2269,8 @@ Info: Configures the w1-gpio Onewire i + Use this overlay if you *do* need a GPIO to drive an external pullup. + Load: dtoverlay=w1-gpio-pullup,= + Params: gpiopin GPIO for I/O (default "4") +- +- pullup Non-zero, "on", or "y" to enable the parasitic +- power (2-wire, power-on-data) feature +- + extpullup GPIO for external pullup (default "5") ++ pullup Now enabled by default (ignored) + + + Name: wittypi +--- a/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts +@@ -14,7 +14,6 @@ + pinctrl-names = "default"; + pinctrl-0 = <&w1_pins>; + gpios = <&gpio 4 0>; +- rpi,parasitic-power = <0>; + status = "okay"; + }; + }; +@@ -36,6 +35,6 @@ + <&w1>,"reg:0", + <&w1_pins>,"brcm,pins:0", + <&w1_pins>,"reg:0"; +- pullup = <&w1>,"rpi,parasitic-power:0"; ++ pullup; // Silently ignore unneeded parameter + }; + }; +--- a/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts ++++ b/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts +@@ -14,7 +14,6 @@ + pinctrl-names = "default"; + pinctrl-0 = <&w1_pins>; + gpios = <&gpio 4 0>, <&gpio 5 1>; +- rpi,parasitic-power = <0>; + status = "okay"; + }; + }; +@@ -38,6 +37,6 @@ + <&w1_pins>,"reg:0"; + extpullup = <&w1>,"gpios:16", + <&w1_pins>,"brcm,pins:4"; +- pullup = <&w1>,"rpi,parasitic-power:0"; ++ pullup; // Silently ignore unneeded parameter + }; + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0519-bcm2835-sdhost-Fix-DMA-channel-leak-on-error-remove.patch b/target/linux/brcm2708/patches-4.19/950-0519-bcm2835-sdhost-Fix-DMA-channel-leak-on-error-remove.patch new file mode 100644 index 0000000000..8efa124589 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0519-bcm2835-sdhost-Fix-DMA-channel-leak-on-error-remove.patch @@ -0,0 +1,31 @@ +From f6ed43e4cef98ce5d000f809af5f03d57a5b2e34 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 12 Jun 2019 20:45:17 +0100 +Subject: [PATCH 519/725] bcm2835-sdhost: Fix DMA channel leak on error/remove + +Signed-off-by: Phil Elwell +--- + drivers/mmc/host/bcm2835-sdhost.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/mmc/host/bcm2835-sdhost.c ++++ b/drivers/mmc/host/bcm2835-sdhost.c +@@ -2154,6 +2154,8 @@ static int bcm2835_sdhost_probe(struct p + + err: + pr_debug("bcm2835_sdhost_probe -> err %d\n", ret); ++ if (host->dma_chan_rxtx) ++ dma_release_channel(host->dma_chan_rxtx); + mmc_free_host(mmc); + + return ret; +@@ -2174,7 +2176,8 @@ static int bcm2835_sdhost_remove(struct + del_timer_sync(&host->timer); + + tasklet_kill(&host->finish_tasklet); +- ++ if (host->dma_chan_rxtx) ++ dma_release_channel(host->dma_chan_rxtx); + mmc_free_host(host->mmc); + platform_set_drvdata(pdev, NULL); + diff --git a/target/linux/brcm2708/patches-4.19/950-0519-staging-bcm2835-codec-Convert-V4L2-nsec-timestamps-t.patch b/target/linux/brcm2708/patches-4.19/950-0519-staging-bcm2835-codec-Convert-V4L2-nsec-timestamps-t.patch deleted file mode 100644 index 5a2534df2b..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0519-staging-bcm2835-codec-Convert-V4L2-nsec-timestamps-t.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 58b048261814bb8763573cac6146079ed8813f65 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 10 May 2019 14:11:58 +0100 -Subject: [PATCH 519/703] staging: bcm2835-codec: Convert V4L2 nsec timestamps - to MMAL usec - -V4L2 uses nsecs, whilst MMAL uses usecs, but the code wasn't converting -between them. This upsets video encode rate control. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -823,7 +823,8 @@ static void op_buffer_cb(struct vchiq_mm - vb2->flags |= V4L2_BUF_FLAG_LAST; - } - -- vb2->vb2_buf.timestamp = mmal_buf->pts; -+ /* vb2 timestamps in nsecs, mmal in usecs */ -+ vb2->vb2_buf.timestamp = mmal_buf->pts * 1000; - - vb2_set_plane_payload(&vb2->vb2_buf, 0, mmal_buf->length); - if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) -@@ -847,6 +848,7 @@ static void op_buffer_cb(struct vchiq_mm - static void vb2_to_mmal_buffer(struct m2m_mmal_buffer *buf, - struct vb2_v4l2_buffer *vb2) - { -+ u64 pts; - buf->mmal.mmal_flags = 0; - if (vb2->flags & V4L2_BUF_FLAG_KEYFRAME) - buf->mmal.mmal_flags |= MMAL_BUFFER_HEADER_FLAG_KEYFRAME; -@@ -869,7 +871,10 @@ static void vb2_to_mmal_buffer(struct m2 - if (!buf->mmal.length || vb2->flags & V4L2_BUF_FLAG_LAST) - buf->mmal.mmal_flags |= MMAL_BUFFER_HEADER_FLAG_EOS; - -- buf->mmal.pts = vb2->vb2_buf.timestamp; -+ /* vb2 timestamps in nsecs, mmal in usecs */ -+ pts = vb2->vb2_buf.timestamp; -+ do_div(pts, 1000); -+ buf->mmal.pts = pts; - buf->mmal.dts = MMAL_TIME_UNKNOWN; - } - diff --git a/target/linux/brcm2708/patches-4.19/950-0520-i2c-bcm2835-Model-Divider-in-CCF.patch b/target/linux/brcm2708/patches-4.19/950-0520-i2c-bcm2835-Model-Divider-in-CCF.patch new file mode 100644 index 0000000000..4f1d114840 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0520-i2c-bcm2835-Model-Divider-in-CCF.patch @@ -0,0 +1,270 @@ +From 77a612fb674f924495a3a9a36ea60fb30d86644a Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Sat, 8 Jun 2019 10:14:43 -0700 +Subject: [PATCH 520/725] i2c: bcm2835: Model Divider in CCF + +Commit bebff81fb8b9216eb4fba22cf910553621ae3477 upstream. + +Model the I2C bus clock divider as a part of the Core Clock Framework. +Primarily this removes the clk_get_rate() call from each transfer. +This call causes problems for slave drivers that themselves have +internal clock components that are controlled by an I2C interface. +When the slave's internal clock component is prepared, the prepare +lock is obtained, and it makes calls to the I2C subsystem to +command the hardware to activate the clock. In order to perform +the I2C transfer, this driver sets the divider, which requires +it to get the parent clock rate, which it does with clk_get_rate(). +Unfortunately, this function will try to take the clock prepare +lock, which is already held by the slave's internal clock calls +creating a deadlock. + +Modeling the divider in the CCF natively removes this dependency +and the divider value is only set upon changing the bus clock +frequency or changes in the parent clock that cascade down to this +divisor. This obviates the need to set the divider with every +transfer and avoids the deadlock described above. It also should +provide better clock debugging and save a few cycles on each +transfer due to not having to recalcuate the divider value. + +Signed-off-by: Annaliese McDermond +Acked-by: Stefan Wahren +Reviewed-by: Eric Anholt +Signed-off-by: Wolfram Sang +--- + drivers/i2c/busses/i2c-bcm2835.c | 145 ++++++++++++++++++++++++------- + 1 file changed, 114 insertions(+), 31 deletions(-) + +--- a/drivers/i2c/busses/i2c-bcm2835.c ++++ b/drivers/i2c/busses/i2c-bcm2835.c +@@ -12,6 +12,8 @@ + */ + + #include ++#include ++#include + #include + #include + #include +@@ -71,9 +73,7 @@ struct bcm2835_debug { + struct bcm2835_i2c_dev { + struct device *dev; + void __iomem *regs; +- struct clk *clk; + int irq; +- u32 bus_clk_rate; + struct i2c_adapter adapter; + struct completion completion; + struct i2c_msg *curr_msg; +@@ -164,12 +164,17 @@ static inline u32 bcm2835_i2c_readl(stru + return readl(i2c_dev->regs + reg); + } + +-static int bcm2835_i2c_set_divider(struct bcm2835_i2c_dev *i2c_dev) ++#define to_clk_bcm2835_i2c(_hw) container_of(_hw, struct clk_bcm2835_i2c, hw) ++struct clk_bcm2835_i2c { ++ struct clk_hw hw; ++ struct bcm2835_i2c_dev *i2c_dev; ++}; ++ ++static int clk_bcm2835_i2c_calc_divider(unsigned long rate, ++ unsigned long parent_rate) + { +- u32 divider, redl, fedl; ++ u32 divider = DIV_ROUND_UP(parent_rate, rate); + +- divider = DIV_ROUND_UP(clk_get_rate(i2c_dev->clk), +- i2c_dev->bus_clk_rate); + /* + * Per the datasheet, the register is always interpreted as an even + * number, by rounding down. In other words, the LSB is ignored. So, +@@ -178,12 +183,23 @@ static int bcm2835_i2c_set_divider(struc + if (divider & 1) + divider++; + if ((divider < BCM2835_I2C_CDIV_MIN) || +- (divider > BCM2835_I2C_CDIV_MAX)) { +- dev_err_ratelimited(i2c_dev->dev, "Invalid clock-frequency\n"); ++ (divider > BCM2835_I2C_CDIV_MAX)) + return -EINVAL; +- } + +- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DIV, divider); ++ return divider; ++} ++ ++static int clk_bcm2835_i2c_set_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long parent_rate) ++{ ++ struct clk_bcm2835_i2c *div = to_clk_bcm2835_i2c(hw); ++ u32 redl, fedl; ++ u32 divider = clk_bcm2835_i2c_calc_divider(rate, parent_rate); ++ ++ if (divider == -EINVAL) ++ return -EINVAL; ++ ++ bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_DIV, divider); + + /* + * Number of core clocks to wait after falling edge before +@@ -198,12 +214,62 @@ static int bcm2835_i2c_set_divider(struc + */ + redl = max(divider / 4, 1u); + +- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DEL, ++ bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_DEL, + (fedl << BCM2835_I2C_FEDL_SHIFT) | + (redl << BCM2835_I2C_REDL_SHIFT)); + return 0; + } + ++static long clk_bcm2835_i2c_round_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long *parent_rate) ++{ ++ u32 divider = clk_bcm2835_i2c_calc_divider(rate, *parent_rate); ++ ++ return DIV_ROUND_UP(*parent_rate, divider); ++} ++ ++static unsigned long clk_bcm2835_i2c_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct clk_bcm2835_i2c *div = to_clk_bcm2835_i2c(hw); ++ u32 divider = bcm2835_i2c_readl(div->i2c_dev, BCM2835_I2C_DIV); ++ ++ return DIV_ROUND_UP(parent_rate, divider); ++} ++ ++static const struct clk_ops clk_bcm2835_i2c_ops = { ++ .set_rate = clk_bcm2835_i2c_set_rate, ++ .round_rate = clk_bcm2835_i2c_round_rate, ++ .recalc_rate = clk_bcm2835_i2c_recalc_rate, ++}; ++ ++static struct clk *bcm2835_i2c_register_div(struct device *dev, ++ const char *mclk_name, ++ struct bcm2835_i2c_dev *i2c_dev) ++{ ++ struct clk_init_data init; ++ struct clk_bcm2835_i2c *priv; ++ char name[32]; ++ ++ snprintf(name, sizeof(name), "%s_div", dev_name(dev)); ++ ++ init.ops = &clk_bcm2835_i2c_ops; ++ init.name = name; ++ init.parent_names = (const char* []) { mclk_name }; ++ init.num_parents = 1; ++ init.flags = 0; ++ ++ priv = devm_kzalloc(dev, sizeof(struct clk_bcm2835_i2c), GFP_KERNEL); ++ if (priv == NULL) ++ return ERR_PTR(-ENOMEM); ++ ++ priv->hw.init = &init; ++ priv->i2c_dev = i2c_dev; ++ ++ clk_hw_register_clkdev(&priv->hw, "div", dev_name(dev)); ++ return devm_clk_register(dev, &priv->hw); ++} ++ + static void bcm2835_fill_txfifo(struct bcm2835_i2c_dev *i2c_dev) + { + u32 val; +@@ -363,7 +429,7 @@ static int bcm2835_i2c_xfer(struct i2c_a + { + struct bcm2835_i2c_dev *i2c_dev = i2c_get_adapdata(adap); + unsigned long time_left; +- int i, ret; ++ int i; + + if (debug) + i2c_dev->debug_num_msgs = num; +@@ -379,10 +445,6 @@ static int bcm2835_i2c_xfer(struct i2c_a + return -EOPNOTSUPP; + } + +- ret = bcm2835_i2c_set_divider(i2c_dev); +- if (ret) +- return ret; +- + i2c_dev->curr_msg = msgs; + i2c_dev->num_msgs = num; + reinit_completion(&i2c_dev->completion); +@@ -443,6 +505,9 @@ static int bcm2835_i2c_probe(struct plat + struct resource *mem, *irq; + int ret; + struct i2c_adapter *adap; ++ const char *mclk_name; ++ struct clk *bus_clk; ++ u32 bus_clk_rate; + + i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); + if (!i2c_dev) +@@ -456,21 +521,6 @@ static int bcm2835_i2c_probe(struct plat + if (IS_ERR(i2c_dev->regs)) + return PTR_ERR(i2c_dev->regs); + +- i2c_dev->clk = devm_clk_get(&pdev->dev, NULL); +- if (IS_ERR(i2c_dev->clk)) { +- if (PTR_ERR(i2c_dev->clk) != -EPROBE_DEFER) +- dev_err(&pdev->dev, "Could not get clock\n"); +- return PTR_ERR(i2c_dev->clk); +- } +- +- ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency", +- &i2c_dev->bus_clk_rate); +- if (ret < 0) { +- dev_warn(&pdev->dev, +- "Could not read clock-frequency property\n"); +- i2c_dev->bus_clk_rate = 100000; +- } +- + irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!irq) { + dev_err(&pdev->dev, "No IRQ resource\n"); +@@ -485,6 +535,35 @@ static int bcm2835_i2c_probe(struct plat + return -ENODEV; + } + ++ mclk_name = of_clk_get_parent_name(pdev->dev.of_node, 0); ++ ++ bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk_name, i2c_dev); ++ ++ if (IS_ERR(bus_clk)) { ++ dev_err(&pdev->dev, "Could not register clock\n"); ++ return PTR_ERR(bus_clk); ++ } ++ ++ ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency", ++ &bus_clk_rate); ++ if (ret < 0) { ++ dev_warn(&pdev->dev, ++ "Could not read clock-frequency property\n"); ++ bus_clk_rate = 100000; ++ } ++ ++ ret = clk_set_rate_exclusive(bus_clk, bus_clk_rate); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "Could not set clock frequency\n"); ++ return ret; ++ } ++ ++ ret = clk_prepare_enable(bus_clk); ++ if (ret) { ++ dev_err(&pdev->dev, "Couldn't prepare clock"); ++ return ret; ++ } ++ + adap = &i2c_dev->adapter; + i2c_set_adapdata(adap, i2c_dev); + adap->owner = THIS_MODULE; +@@ -507,6 +586,10 @@ static int bcm2835_i2c_probe(struct plat + static int bcm2835_i2c_remove(struct platform_device *pdev) + { + struct bcm2835_i2c_dev *i2c_dev = platform_get_drvdata(pdev); ++ struct clk *bus_clk = devm_clk_get(i2c_dev->dev, "div"); ++ ++ clk_rate_exclusive_put(bus_clk); ++ clk_disable_unprepare(bus_clk); + + free_irq(i2c_dev->irq, i2c_dev); + i2c_del_adapter(&i2c_dev->adapter); diff --git a/target/linux/brcm2708/patches-4.19/950-0520-staging-bcm2835-codec-Add-support-for-setting-S_PARM.patch b/target/linux/brcm2708/patches-4.19/950-0520-staging-bcm2835-codec-Add-support-for-setting-S_PARM.patch deleted file mode 100644 index 94fb23c32e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0520-staging-bcm2835-codec-Add-support-for-setting-S_PARM.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 17100548de7995412237633c58c4e04a11a6d5ed Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 10 May 2019 14:13:11 +0100 -Subject: [PATCH 520/703] staging: bcm2835-codec: Add support for setting - S_PARM and G_PARM - -Video encode can use the frame rate for rate control calculations, -therefore plumb it through from V4L2's [S|G]_PARM ioctl. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 52 +++++++++++++++++-- - 1 file changed, 48 insertions(+), 4 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -447,6 +447,8 @@ struct bcm2835_codec_ctx { - /* Source and destination queue data */ - struct bcm2835_codec_q_data q_data[2]; - s32 bitrate; -+ unsigned int framerate_num; -+ unsigned int framerate_denom; - - bool aborting; - int num_ip_buffers; -@@ -610,8 +612,8 @@ static void setup_mmal_port_format(struc - port->es.video.height = q_data->height; - port->es.video.crop.width = q_data->crop_width; - port->es.video.crop.height = q_data->crop_height; -- port->es.video.frame_rate.num = 0; -- port->es.video.frame_rate.den = 1; -+ port->es.video.frame_rate.num = ctx->framerate_num; -+ port->es.video.frame_rate.den = ctx->framerate_denom; - } else { - /* Compressed format - leave resolution as 0 for decode */ - if (ctx->dev->role == DECODE) { -@@ -625,9 +627,9 @@ static void setup_mmal_port_format(struc - port->es.video.crop.width = q_data->crop_width; - port->es.video.crop.height = q_data->crop_height; - port->format.bitrate = ctx->bitrate; -+ port->es.video.frame_rate.num = ctx->framerate_num; -+ port->es.video.frame_rate.den = ctx->framerate_denom; - } -- port->es.video.frame_rate.num = 0; -- port->es.video.frame_rate.den = 1; - } - port->es.video.crop.x = 0; - port->es.video.crop.y = 0; -@@ -1361,6 +1363,41 @@ static int vidioc_s_selection(struct fil - return 0; - } - -+static int vidioc_s_parm(struct file *file, void *priv, -+ struct v4l2_streamparm *parm) -+{ -+ struct bcm2835_codec_ctx *ctx = file2ctx(file); -+ -+ if (parm->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) -+ return -EINVAL; -+ -+ ctx->framerate_num = -+ parm->parm.output.timeperframe.denominator; -+ ctx->framerate_denom = -+ parm->parm.output.timeperframe.numerator; -+ -+ parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; -+ -+ return 0; -+} -+ -+static int vidioc_g_parm(struct file *file, void *priv, -+ struct v4l2_streamparm *parm) -+{ -+ struct bcm2835_codec_ctx *ctx = file2ctx(file); -+ -+ if (parm->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) -+ return -EINVAL; -+ -+ parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; -+ parm->parm.output.timeperframe.denominator = -+ ctx->framerate_num; -+ parm->parm.output.timeperframe.numerator = -+ ctx->framerate_denom; -+ -+ return 0; -+} -+ - static int vidioc_subscribe_evt(struct v4l2_fh *fh, - const struct v4l2_event_subscription *sub) - { -@@ -1725,6 +1762,9 @@ static const struct v4l2_ioctl_ops bcm28 - .vidioc_g_selection = vidioc_g_selection, - .vidioc_s_selection = vidioc_s_selection, - -+ .vidioc_g_parm = vidioc_g_parm, -+ .vidioc_s_parm = vidioc_s_parm, -+ - .vidioc_subscribe_event = vidioc_subscribe_evt, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, - -@@ -2546,6 +2586,8 @@ static int bcm2835_codec_create(struct p - case DECODE: - v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD); - v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); -+ v4l2_disable_ioctl(vfd, VIDIOC_S_PARM); -+ v4l2_disable_ioctl(vfd, VIDIOC_G_PARM); - video_nr = decode_video_nr; - break; - case ENCODE: -@@ -2558,6 +2600,8 @@ static int bcm2835_codec_create(struct p - v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); - v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD); - v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD); -+ v4l2_disable_ioctl(vfd, VIDIOC_S_PARM); -+ v4l2_disable_ioctl(vfd, VIDIOC_G_PARM); - video_nr = isp_video_nr; - break; - default: diff --git a/target/linux/brcm2708/patches-4.19/950-0521-staging-vc04_services-Use-correct-cache-line-size.patch b/target/linux/brcm2708/patches-4.19/950-0521-staging-vc04_services-Use-correct-cache-line-size.patch new file mode 100644 index 0000000000..00e48bc220 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0521-staging-vc04_services-Use-correct-cache-line-size.patch @@ -0,0 +1,135 @@ +From 29fb40874924e09b1a1063ef8155fdf77df4b9fd Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 17 Sep 2018 09:22:21 +0100 +Subject: [PATCH 521/725] staging/vc04_services: Use correct cache line size + +Use the compatible string in the DTB to select the correct cache line +size for the SoC - 32 for BCM2835, and 64 for BCM2836 and BCM2837. + +Signed-off-by: Phil Elwell +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../interface/vchiq_arm/vchiq_2835_arm.c | 15 ++------ + .../interface/vchiq_arm/vchiq_arm.c | 35 +++++++++++++------ + .../interface/vchiq_arm/vchiq_arm.h | 5 +++ + 3 files changed, 33 insertions(+), 22 deletions(-) + +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +@@ -117,7 +117,8 @@ free_pagelist(struct vchiq_pagelist_info + int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) + { + struct device *dev = &pdev->dev; +- struct rpi_firmware *fw = platform_get_drvdata(pdev); ++ struct vchiq_drvdata *drvdata = platform_get_drvdata(pdev); ++ struct rpi_firmware *fw = drvdata->fw; + VCHIQ_SLOT_ZERO_T *vchiq_slot_zero; + struct resource *res; + void *slot_mem; +@@ -135,17 +136,7 @@ int vchiq_platform_init(struct platform_ + if (err < 0) + return err; + +- /* +- * The tempting L1_CACHE_BYTES macro doesn't work in the case of +- * a kernel built with bcm2835_defconfig running on a BCM2836/7 +- * processor, hence the need for a runtime check. The dcache line size +- * is encoded in one of the coprocessor registers, but there is no +- * convenient way to access it short of embedded assembler, hence +- * the use of read_cpuid_id(). The following test evaluates to true +- * on a BCM2835 showing that it is ARMv6-ish, whereas +- * cpu_architecture() will indicate that it is an ARMv7. +- */ +- g_cache_line_size = ((read_cpuid_id() & 0x7f000) == 0x7b000) ? 32 : 64; ++ g_cache_line_size = drvdata->cache_line_size; + g_fragments_size = 2 * g_cache_line_size; + + /* Allocate space for the channels in coherent memory */ +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +@@ -173,6 +173,14 @@ static struct platform_device *bcm2835_c + static struct platform_device *bcm2835_codec; + static struct platform_device *vcsm_cma; + ++static struct vchiq_drvdata bcm2835_drvdata = { ++ .cache_line_size = 32, ++}; ++ ++static struct vchiq_drvdata bcm2836_drvdata = { ++ .cache_line_size = 64, ++}; ++ + static const char *const ioctl_names[] = { + "CONNECT", + "SHUTDOWN", +@@ -3607,12 +3615,25 @@ vchiq_register_child(struct platform_dev + return new_dev; + } + ++static const struct of_device_id vchiq_of_match[] = { ++ { .compatible = "brcm,bcm2835-vchiq", .data = &bcm2835_drvdata }, ++ { .compatible = "brcm,bcm2836-vchiq", .data = &bcm2836_drvdata }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, vchiq_of_match); ++ + static int vchiq_probe(struct platform_device *pdev) + { + struct device_node *fw_node; +- struct rpi_firmware *fw; ++ const struct of_device_id *of_id; ++ struct vchiq_drvdata *drvdata; + int err; + ++ of_id = of_match_node(vchiq_of_match, pdev->dev.of_node); ++ drvdata = (struct vchiq_drvdata *)of_id->data; ++ if (!drvdata) ++ return -EINVAL; ++ + fw_node = of_find_compatible_node(NULL, NULL, + "raspberrypi,bcm2835-firmware"); + if (!fw_node) { +@@ -3620,12 +3641,12 @@ static int vchiq_probe(struct platform_d + return -ENOENT; + } + +- fw = rpi_firmware_get(fw_node); ++ drvdata->fw = rpi_firmware_get(fw_node); + of_node_put(fw_node); +- if (!fw) ++ if (!drvdata->fw) + return -EPROBE_DEFER; + +- platform_set_drvdata(pdev, fw); ++ platform_set_drvdata(pdev, drvdata); + + err = vchiq_platform_init(pdev, &g_state); + if (err != 0) +@@ -3703,12 +3724,6 @@ static int vchiq_remove(struct platform_ + return 0; + } + +-static const struct of_device_id vchiq_of_match[] = { +- { .compatible = "brcm,bcm2835-vchiq", }, +- {}, +-}; +-MODULE_DEVICE_TABLE(of, vchiq_of_match); +- + static struct platform_driver vchiq_driver = { + .driver = { + .name = "bcm2835_vchiq", +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h +@@ -123,6 +123,11 @@ typedef struct vchiq_arm_state_struct { + + } VCHIQ_ARM_STATE_T; + ++struct vchiq_drvdata { ++ const unsigned int cache_line_size; ++ struct rpi_firmware *fw; ++}; ++ + extern int vchiq_arm_log_level; + extern int vchiq_susp_log_level; + diff --git a/target/linux/brcm2708/patches-4.19/950-0521-w1-w1-gpio-Make-GPIO-an-output-for-strong-pullup.patch b/target/linux/brcm2708/patches-4.19/950-0521-w1-w1-gpio-Make-GPIO-an-output-for-strong-pullup.patch deleted file mode 100644 index 7cb7e88d7e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0521-w1-w1-gpio-Make-GPIO-an-output-for-strong-pullup.patch +++ /dev/null @@ -1,27 +0,0 @@ -From d4b6aeeb564bcc56316ba15eaa62d25400dde175 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 12 Jun 2019 17:15:05 +0100 -Subject: [PATCH 521/703] w1: w1-gpio: Make GPIO an output for strong pullup - -The logic to drive the data line high to implement a strong pullup -assumed that the pin was already an output - setting a value does -not change an input. - -See: https://github.com/raspberrypi/firmware/issues/1143 - -Signed-off-by: Phil Elwell ---- - drivers/w1/masters/w1-gpio.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/w1/masters/w1-gpio.c -+++ b/drivers/w1/masters/w1-gpio.c -@@ -33,7 +33,7 @@ static u8 w1_gpio_set_pullup(void *data, - * This will OVERRIDE open drain emulation and force-pull - * the line high for some time. - */ -- gpiod_set_raw_value(pdata->gpiod, 1); -+ gpiod_direction_output_raw(pdata->gpiod, 1); - msleep(pdata->pullup_duration); - /* - * This will simply set the line as input since we are doing diff --git a/target/linux/brcm2708/patches-4.19/950-0522-overlays-Update-w1-gpio-and-w1-gpio-pullup.patch b/target/linux/brcm2708/patches-4.19/950-0522-overlays-Update-w1-gpio-and-w1-gpio-pullup.patch deleted file mode 100644 index 66977ba674..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0522-overlays-Update-w1-gpio-and-w1-gpio-pullup.patch +++ /dev/null @@ -1,78 +0,0 @@ -From f182f8725cc6a5cccd7f513268e311e5037eca03 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 12 Jun 2019 17:32:11 +0100 -Subject: [PATCH 522/703] overlays: Update w1-gpio and w1-gpio-pullup - -The parasitic power (power on data) feature is now enabled by -default in the w1-gpio driver, so update the README and make the -"pullup" parameter a no-op. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/README | 9 ++------- - arch/arm/boot/dts/overlays/w1-gpio-overlay.dts | 3 +-- - arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts | 3 +-- - 3 files changed, 4 insertions(+), 11 deletions(-) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -2261,9 +2261,7 @@ Info: Configures the w1-gpio Onewire i - Use this overlay if you *don't* need a GPIO to drive an external pullup. - Load: dtoverlay=w1-gpio,= - Params: gpiopin GPIO for I/O (default "4") -- -- pullup Non-zero, "on", or "y" to enable the parasitic -- power (2-wire, power-on-data) feature -+ pullup Now enabled by default (ignored) - - - Name: w1-gpio-pullup -@@ -2271,11 +2269,8 @@ Info: Configures the w1-gpio Onewire i - Use this overlay if you *do* need a GPIO to drive an external pullup. - Load: dtoverlay=w1-gpio-pullup,= - Params: gpiopin GPIO for I/O (default "4") -- -- pullup Non-zero, "on", or "y" to enable the parasitic -- power (2-wire, power-on-data) feature -- - extpullup GPIO for external pullup (default "5") -+ pullup Now enabled by default (ignored) - - - Name: wittypi ---- a/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts -@@ -14,7 +14,6 @@ - pinctrl-names = "default"; - pinctrl-0 = <&w1_pins>; - gpios = <&gpio 4 0>; -- rpi,parasitic-power = <0>; - status = "okay"; - }; - }; -@@ -36,6 +35,6 @@ - <&w1>,"reg:0", - <&w1_pins>,"brcm,pins:0", - <&w1_pins>,"reg:0"; -- pullup = <&w1>,"rpi,parasitic-power:0"; -+ pullup; // Silently ignore unneeded parameter - }; - }; ---- a/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts -+++ b/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts -@@ -14,7 +14,6 @@ - pinctrl-names = "default"; - pinctrl-0 = <&w1_pins>; - gpios = <&gpio 4 0>, <&gpio 5 1>; -- rpi,parasitic-power = <0>; - status = "okay"; - }; - }; -@@ -38,6 +37,6 @@ - <&w1_pins>,"reg:0"; - extpullup = <&w1>,"gpios:16", - <&w1_pins>,"brcm,pins:4"; -- pullup = <&w1>,"rpi,parasitic-power:0"; -+ pullup; // Silently ignore unneeded parameter - }; - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0522-tty-amba-pl011-allow-shared-interrupt.patch b/target/linux/brcm2708/patches-4.19/950-0522-tty-amba-pl011-allow-shared-interrupt.patch new file mode 100644 index 0000000000..295b4d898b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0522-tty-amba-pl011-allow-shared-interrupt.patch @@ -0,0 +1,28 @@ +From e30c029a882170cfc57612129b4eebff56f7cd6b Mon Sep 17 00:00:00 2001 +From: Doug Berger +Date: Mon, 13 May 2019 20:59:45 +0200 +Subject: [PATCH 522/725] tty: amba-pl011: allow shared interrupt + +The PL011 register space includes all necessary status bits to +determine whether a device instance requires handling in response +to an interrupt. Therefore, multiple instances of the device could +be serviced by a single shared interrupt, which is the case on BCM7211. + +Signed-off-by: Doug Berger +Signed-off-by: Florian Fainelli +--- + drivers/tty/serial/amba-pl011.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -1735,7 +1735,8 @@ static int pl011_allocate_irq(struct uar + { + pl011_write(uap->im, uap, REG_IMSC); + +- return request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap); ++ return request_irq(uap->port.irq, pl011_int, IRQF_SHARED, "uart-pl011", ++ uap); + } + + /* diff --git a/target/linux/brcm2708/patches-4.19/950-0523-ARM-bcm283x-Reduce-register-ranges-for-UART-SPI-and-.patch b/target/linux/brcm2708/patches-4.19/950-0523-ARM-bcm283x-Reduce-register-ranges-for-UART-SPI-and-.patch new file mode 100644 index 0000000000..edf3020900 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0523-ARM-bcm283x-Reduce-register-ranges-for-UART-SPI-and-.patch @@ -0,0 +1,44 @@ +From 7739b8497c229fdac29640985e0dba9c8d6f04f1 Mon Sep 17 00:00:00 2001 +From: Stefan Wahren +Date: Sun, 19 May 2019 12:20:00 +0200 +Subject: [PATCH 523/725] ARM: bcm283x: Reduce register ranges for UART, SPI + and I2C + +The assigned register ranges for UART, SPI and I2C were too wasteful. +In order to avoid overlapping with the new functions on BCM2838 +reduce the ranges. + +Signed-off-by: Stefan Wahren +--- + arch/arm/boot/dts/bcm283x.dtsi | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/arm/boot/dts/bcm283x.dtsi ++++ b/arch/arm/boot/dts/bcm283x.dtsi +@@ -387,7 +387,7 @@ + + uart0: serial@7e201000 { + compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; +- reg = <0x7e201000 0x1000>; ++ reg = <0x7e201000 0x200>; + interrupts = <2 25>; + clocks = <&clocks BCM2835_CLOCK_UART>, + <&clocks BCM2835_CLOCK_VPU>; +@@ -418,7 +418,7 @@ + + spi: spi@7e204000 { + compatible = "brcm,bcm2835-spi"; +- reg = <0x7e204000 0x1000>; ++ reg = <0x7e204000 0x200>; + interrupts = <2 22>; + clocks = <&clocks BCM2835_CLOCK_VPU>; + #address-cells = <1>; +@@ -428,7 +428,7 @@ + + i2c0: i2c@7e205000 { + compatible = "brcm,bcm2835-i2c"; +- reg = <0x7e205000 0x1000>; ++ reg = <0x7e205000 0x200>; + interrupts = <2 21>; + clocks = <&clocks BCM2835_CLOCK_VPU>; + #address-cells = <1>; diff --git a/target/linux/brcm2708/patches-4.19/950-0523-bcm2835-sdhost-Fix-DMA-channel-leak-on-error-remove.patch b/target/linux/brcm2708/patches-4.19/950-0523-bcm2835-sdhost-Fix-DMA-channel-leak-on-error-remove.patch deleted file mode 100644 index 4ca216eaf1..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0523-bcm2835-sdhost-Fix-DMA-channel-leak-on-error-remove.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 578084fa26af562bc35db7175ea7784a01f87f87 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 12 Jun 2019 20:45:17 +0100 -Subject: [PATCH 523/703] bcm2835-sdhost: Fix DMA channel leak on error/remove - -Signed-off-by: Phil Elwell ---- - drivers/mmc/host/bcm2835-sdhost.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -2154,6 +2154,8 @@ static int bcm2835_sdhost_probe(struct p - - err: - pr_debug("bcm2835_sdhost_probe -> err %d\n", ret); -+ if (host->dma_chan_rxtx) -+ dma_release_channel(host->dma_chan_rxtx); - mmc_free_host(mmc); - - return ret; -@@ -2174,7 +2176,8 @@ static int bcm2835_sdhost_remove(struct - del_timer_sync(&host->timer); - - tasklet_kill(&host->finish_tasklet); -- -+ if (host->dma_chan_rxtx) -+ dma_release_channel(host->dma_chan_rxtx); - mmc_free_host(host->mmc); - platform_set_drvdata(pdev, NULL); - diff --git a/target/linux/brcm2708/patches-4.19/950-0524-ARM-bcm283x-Extend-the-WDT-DT-node-out-to-cover-the-.patch b/target/linux/brcm2708/patches-4.19/950-0524-ARM-bcm283x-Extend-the-WDT-DT-node-out-to-cover-the-.patch new file mode 100644 index 0000000000..0b57f3682d --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0524-ARM-bcm283x-Extend-the-WDT-DT-node-out-to-cover-the-.patch @@ -0,0 +1,45 @@ +From bd7335b5e204cf0dc88550497fbd12002a0f35d5 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 12 Dec 2018 15:51:49 -0800 +Subject: [PATCH 524/725] ARM: bcm283x: Extend the WDT DT node out to cover the + whole PM block. (v4) + +It was covering part of the PM block's range, up to the WDT regs. To +support the rest of the PM block's functionality, we need the full +register range plus the AXI Async Bridge regs for PM sequencing. + +This doesn't convert any of the consumers over to the new binding yet, +since we will need to be careful in coordinating our usage of firmware +services that might power domains on and off versus the bcm2835-pm +driver's access of those same domains. + +Signed-off-by: Eric Anholt +Acked-by: Stefan Wahren +Signed-off-by: Stefan Wahren +(cherry picked from commit 29abc92c1d93e28a8f4d55e6343eec4faf44025a) +--- + arch/arm/boot/dts/bcm283x.dtsi | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/bcm283x.dtsi ++++ b/arch/arm/boot/dts/bcm283x.dtsi +@@ -121,8 +121,17 @@ + }; + + watchdog@7e100000 { +- compatible = "brcm,bcm2835-pm-wdt"; +- reg = <0x7e100000 0x28>; ++ compatible = "brcm,bcm2835-pm", "brcm,bcm2835-pm-wdt"; ++ #power-domain-cells = <1>; ++ #reset-cells = <1>; ++ reg = <0x7e100000 0x114>, ++ <0x7e00a000 0x24>; ++ clocks = <&clocks BCM2835_CLOCK_V3D>, ++ <&clocks BCM2835_CLOCK_PERI_IMAGE>, ++ <&clocks BCM2835_CLOCK_H264>, ++ <&clocks BCM2835_CLOCK_ISP>; ++ clock-names = "v3d", "peri_image", "h264", "isp"; ++ system-power-controller; + }; + + clocks: cprman@7e101000 { diff --git a/target/linux/brcm2708/patches-4.19/950-0524-i2c-bcm2835-Model-Divider-in-CCF.patch b/target/linux/brcm2708/patches-4.19/950-0524-i2c-bcm2835-Model-Divider-in-CCF.patch deleted file mode 100644 index 08a8c90e74..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0524-i2c-bcm2835-Model-Divider-in-CCF.patch +++ /dev/null @@ -1,270 +0,0 @@ -From c86d0f6bfecc53a44e753f14238921ababae29d4 Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Sat, 8 Jun 2019 10:14:43 -0700 -Subject: [PATCH 524/703] i2c: bcm2835: Model Divider in CCF - -Commit bebff81fb8b9216eb4fba22cf910553621ae3477 upstream. - -Model the I2C bus clock divider as a part of the Core Clock Framework. -Primarily this removes the clk_get_rate() call from each transfer. -This call causes problems for slave drivers that themselves have -internal clock components that are controlled by an I2C interface. -When the slave's internal clock component is prepared, the prepare -lock is obtained, and it makes calls to the I2C subsystem to -command the hardware to activate the clock. In order to perform -the I2C transfer, this driver sets the divider, which requires -it to get the parent clock rate, which it does with clk_get_rate(). -Unfortunately, this function will try to take the clock prepare -lock, which is already held by the slave's internal clock calls -creating a deadlock. - -Modeling the divider in the CCF natively removes this dependency -and the divider value is only set upon changing the bus clock -frequency or changes in the parent clock that cascade down to this -divisor. This obviates the need to set the divider with every -transfer and avoids the deadlock described above. It also should -provide better clock debugging and save a few cycles on each -transfer due to not having to recalcuate the divider value. - -Signed-off-by: Annaliese McDermond -Acked-by: Stefan Wahren -Reviewed-by: Eric Anholt -Signed-off-by: Wolfram Sang ---- - drivers/i2c/busses/i2c-bcm2835.c | 145 ++++++++++++++++++++++++------- - 1 file changed, 114 insertions(+), 31 deletions(-) - ---- a/drivers/i2c/busses/i2c-bcm2835.c -+++ b/drivers/i2c/busses/i2c-bcm2835.c -@@ -12,6 +12,8 @@ - */ - - #include -+#include -+#include - #include - #include - #include -@@ -71,9 +73,7 @@ struct bcm2835_debug { - struct bcm2835_i2c_dev { - struct device *dev; - void __iomem *regs; -- struct clk *clk; - int irq; -- u32 bus_clk_rate; - struct i2c_adapter adapter; - struct completion completion; - struct i2c_msg *curr_msg; -@@ -164,12 +164,17 @@ static inline u32 bcm2835_i2c_readl(stru - return readl(i2c_dev->regs + reg); - } - --static int bcm2835_i2c_set_divider(struct bcm2835_i2c_dev *i2c_dev) -+#define to_clk_bcm2835_i2c(_hw) container_of(_hw, struct clk_bcm2835_i2c, hw) -+struct clk_bcm2835_i2c { -+ struct clk_hw hw; -+ struct bcm2835_i2c_dev *i2c_dev; -+}; -+ -+static int clk_bcm2835_i2c_calc_divider(unsigned long rate, -+ unsigned long parent_rate) - { -- u32 divider, redl, fedl; -+ u32 divider = DIV_ROUND_UP(parent_rate, rate); - -- divider = DIV_ROUND_UP(clk_get_rate(i2c_dev->clk), -- i2c_dev->bus_clk_rate); - /* - * Per the datasheet, the register is always interpreted as an even - * number, by rounding down. In other words, the LSB is ignored. So, -@@ -178,12 +183,23 @@ static int bcm2835_i2c_set_divider(struc - if (divider & 1) - divider++; - if ((divider < BCM2835_I2C_CDIV_MIN) || -- (divider > BCM2835_I2C_CDIV_MAX)) { -- dev_err_ratelimited(i2c_dev->dev, "Invalid clock-frequency\n"); -+ (divider > BCM2835_I2C_CDIV_MAX)) - return -EINVAL; -- } - -- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DIV, divider); -+ return divider; -+} -+ -+static int clk_bcm2835_i2c_set_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long parent_rate) -+{ -+ struct clk_bcm2835_i2c *div = to_clk_bcm2835_i2c(hw); -+ u32 redl, fedl; -+ u32 divider = clk_bcm2835_i2c_calc_divider(rate, parent_rate); -+ -+ if (divider == -EINVAL) -+ return -EINVAL; -+ -+ bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_DIV, divider); - - /* - * Number of core clocks to wait after falling edge before -@@ -198,12 +214,62 @@ static int bcm2835_i2c_set_divider(struc - */ - redl = max(divider / 4, 1u); - -- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DEL, -+ bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_DEL, - (fedl << BCM2835_I2C_FEDL_SHIFT) | - (redl << BCM2835_I2C_REDL_SHIFT)); - return 0; - } - -+static long clk_bcm2835_i2c_round_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long *parent_rate) -+{ -+ u32 divider = clk_bcm2835_i2c_calc_divider(rate, *parent_rate); -+ -+ return DIV_ROUND_UP(*parent_rate, divider); -+} -+ -+static unsigned long clk_bcm2835_i2c_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ struct clk_bcm2835_i2c *div = to_clk_bcm2835_i2c(hw); -+ u32 divider = bcm2835_i2c_readl(div->i2c_dev, BCM2835_I2C_DIV); -+ -+ return DIV_ROUND_UP(parent_rate, divider); -+} -+ -+static const struct clk_ops clk_bcm2835_i2c_ops = { -+ .set_rate = clk_bcm2835_i2c_set_rate, -+ .round_rate = clk_bcm2835_i2c_round_rate, -+ .recalc_rate = clk_bcm2835_i2c_recalc_rate, -+}; -+ -+static struct clk *bcm2835_i2c_register_div(struct device *dev, -+ const char *mclk_name, -+ struct bcm2835_i2c_dev *i2c_dev) -+{ -+ struct clk_init_data init; -+ struct clk_bcm2835_i2c *priv; -+ char name[32]; -+ -+ snprintf(name, sizeof(name), "%s_div", dev_name(dev)); -+ -+ init.ops = &clk_bcm2835_i2c_ops; -+ init.name = name; -+ init.parent_names = (const char* []) { mclk_name }; -+ init.num_parents = 1; -+ init.flags = 0; -+ -+ priv = devm_kzalloc(dev, sizeof(struct clk_bcm2835_i2c), GFP_KERNEL); -+ if (priv == NULL) -+ return ERR_PTR(-ENOMEM); -+ -+ priv->hw.init = &init; -+ priv->i2c_dev = i2c_dev; -+ -+ clk_hw_register_clkdev(&priv->hw, "div", dev_name(dev)); -+ return devm_clk_register(dev, &priv->hw); -+} -+ - static void bcm2835_fill_txfifo(struct bcm2835_i2c_dev *i2c_dev) - { - u32 val; -@@ -363,7 +429,7 @@ static int bcm2835_i2c_xfer(struct i2c_a - { - struct bcm2835_i2c_dev *i2c_dev = i2c_get_adapdata(adap); - unsigned long time_left; -- int i, ret; -+ int i; - - if (debug) - i2c_dev->debug_num_msgs = num; -@@ -379,10 +445,6 @@ static int bcm2835_i2c_xfer(struct i2c_a - return -EOPNOTSUPP; - } - -- ret = bcm2835_i2c_set_divider(i2c_dev); -- if (ret) -- return ret; -- - i2c_dev->curr_msg = msgs; - i2c_dev->num_msgs = num; - reinit_completion(&i2c_dev->completion); -@@ -443,6 +505,9 @@ static int bcm2835_i2c_probe(struct plat - struct resource *mem, *irq; - int ret; - struct i2c_adapter *adap; -+ const char *mclk_name; -+ struct clk *bus_clk; -+ u32 bus_clk_rate; - - i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); - if (!i2c_dev) -@@ -456,21 +521,6 @@ static int bcm2835_i2c_probe(struct plat - if (IS_ERR(i2c_dev->regs)) - return PTR_ERR(i2c_dev->regs); - -- i2c_dev->clk = devm_clk_get(&pdev->dev, NULL); -- if (IS_ERR(i2c_dev->clk)) { -- if (PTR_ERR(i2c_dev->clk) != -EPROBE_DEFER) -- dev_err(&pdev->dev, "Could not get clock\n"); -- return PTR_ERR(i2c_dev->clk); -- } -- -- ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency", -- &i2c_dev->bus_clk_rate); -- if (ret < 0) { -- dev_warn(&pdev->dev, -- "Could not read clock-frequency property\n"); -- i2c_dev->bus_clk_rate = 100000; -- } -- - irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!irq) { - dev_err(&pdev->dev, "No IRQ resource\n"); -@@ -485,6 +535,35 @@ static int bcm2835_i2c_probe(struct plat - return -ENODEV; - } - -+ mclk_name = of_clk_get_parent_name(pdev->dev.of_node, 0); -+ -+ bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk_name, i2c_dev); -+ -+ if (IS_ERR(bus_clk)) { -+ dev_err(&pdev->dev, "Could not register clock\n"); -+ return PTR_ERR(bus_clk); -+ } -+ -+ ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency", -+ &bus_clk_rate); -+ if (ret < 0) { -+ dev_warn(&pdev->dev, -+ "Could not read clock-frequency property\n"); -+ bus_clk_rate = 100000; -+ } -+ -+ ret = clk_set_rate_exclusive(bus_clk, bus_clk_rate); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "Could not set clock frequency\n"); -+ return ret; -+ } -+ -+ ret = clk_prepare_enable(bus_clk); -+ if (ret) { -+ dev_err(&pdev->dev, "Couldn't prepare clock"); -+ return ret; -+ } -+ - adap = &i2c_dev->adapter; - i2c_set_adapdata(adap, i2c_dev); - adap->owner = THIS_MODULE; -@@ -507,6 +586,10 @@ static int bcm2835_i2c_probe(struct plat - static int bcm2835_i2c_remove(struct platform_device *pdev) - { - struct bcm2835_i2c_dev *i2c_dev = platform_get_drvdata(pdev); -+ struct clk *bus_clk = devm_clk_get(i2c_dev->dev, "div"); -+ -+ clk_rate_exclusive_put(bus_clk); -+ clk_disable_unprepare(bus_clk); - - free_irq(i2c_dev->irq, i2c_dev); - i2c_del_adapter(&i2c_dev->adapter); diff --git a/target/linux/brcm2708/patches-4.19/950-0525-ARM-dts-Add-label-to-bcm2835-RNG.patch b/target/linux/brcm2708/patches-4.19/950-0525-ARM-dts-Add-label-to-bcm2835-RNG.patch new file mode 100644 index 0000000000..f15d69e49e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0525-ARM-dts-Add-label-to-bcm2835-RNG.patch @@ -0,0 +1,20 @@ +From 430a2bead0b7cf0100008189cad88213fcb6afb6 Mon Sep 17 00:00:00 2001 +From: Stefan Wahren +Date: Sat, 4 May 2019 17:06:54 +0200 +Subject: [PATCH 525/725] ARM: dts: Add label to bcm2835 RNG + +--- + arch/arm/boot/dts/bcm283x.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/bcm283x.dtsi ++++ b/arch/arm/boot/dts/bcm283x.dtsi +@@ -148,7 +148,7 @@ + <&dsi1 0>, <&dsi1 1>, <&dsi1 2>; + }; + +- rng@7e104000 { ++ rng: rng@7e104000 { + compatible = "brcm,bcm2835-rng"; + reg = <0x7e104000 0x10>; + interrupts = <2 29>; diff --git a/target/linux/brcm2708/patches-4.19/950-0525-staging-vc04_services-Use-correct-cache-line-size.patch b/target/linux/brcm2708/patches-4.19/950-0525-staging-vc04_services-Use-correct-cache-line-size.patch deleted file mode 100644 index d9dae4f0c7..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0525-staging-vc04_services-Use-correct-cache-line-size.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 75d0074312c7cb74c7a7c17f9cef7a071e209d79 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 17 Sep 2018 09:22:21 +0100 -Subject: [PATCH 525/703] staging/vc04_services: Use correct cache line size - -Use the compatible string in the DTB to select the correct cache line -size for the SoC - 32 for BCM2835, and 64 for BCM2836 and BCM2837. - -Signed-off-by: Phil Elwell -Tested-by: Stefan Wahren -Signed-off-by: Greg Kroah-Hartman ---- - .../interface/vchiq_arm/vchiq_2835_arm.c | 15 ++------ - .../interface/vchiq_arm/vchiq_arm.c | 35 +++++++++++++------ - .../interface/vchiq_arm/vchiq_arm.h | 5 +++ - 3 files changed, 33 insertions(+), 22 deletions(-) - ---- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -@@ -117,7 +117,8 @@ free_pagelist(struct vchiq_pagelist_info - int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) - { - struct device *dev = &pdev->dev; -- struct rpi_firmware *fw = platform_get_drvdata(pdev); -+ struct vchiq_drvdata *drvdata = platform_get_drvdata(pdev); -+ struct rpi_firmware *fw = drvdata->fw; - VCHIQ_SLOT_ZERO_T *vchiq_slot_zero; - struct resource *res; - void *slot_mem; -@@ -135,17 +136,7 @@ int vchiq_platform_init(struct platform_ - if (err < 0) - return err; - -- /* -- * The tempting L1_CACHE_BYTES macro doesn't work in the case of -- * a kernel built with bcm2835_defconfig running on a BCM2836/7 -- * processor, hence the need for a runtime check. The dcache line size -- * is encoded in one of the coprocessor registers, but there is no -- * convenient way to access it short of embedded assembler, hence -- * the use of read_cpuid_id(). The following test evaluates to true -- * on a BCM2835 showing that it is ARMv6-ish, whereas -- * cpu_architecture() will indicate that it is an ARMv7. -- */ -- g_cache_line_size = ((read_cpuid_id() & 0x7f000) == 0x7b000) ? 32 : 64; -+ g_cache_line_size = drvdata->cache_line_size; - g_fragments_size = 2 * g_cache_line_size; - - /* Allocate space for the channels in coherent memory */ ---- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -173,6 +173,14 @@ static struct platform_device *bcm2835_c - static struct platform_device *bcm2835_codec; - static struct platform_device *vcsm_cma; - -+static struct vchiq_drvdata bcm2835_drvdata = { -+ .cache_line_size = 32, -+}; -+ -+static struct vchiq_drvdata bcm2836_drvdata = { -+ .cache_line_size = 64, -+}; -+ - static const char *const ioctl_names[] = { - "CONNECT", - "SHUTDOWN", -@@ -3607,12 +3615,25 @@ vchiq_register_child(struct platform_dev - return new_dev; - } - -+static const struct of_device_id vchiq_of_match[] = { -+ { .compatible = "brcm,bcm2835-vchiq", .data = &bcm2835_drvdata }, -+ { .compatible = "brcm,bcm2836-vchiq", .data = &bcm2836_drvdata }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, vchiq_of_match); -+ - static int vchiq_probe(struct platform_device *pdev) - { - struct device_node *fw_node; -- struct rpi_firmware *fw; -+ const struct of_device_id *of_id; -+ struct vchiq_drvdata *drvdata; - int err; - -+ of_id = of_match_node(vchiq_of_match, pdev->dev.of_node); -+ drvdata = (struct vchiq_drvdata *)of_id->data; -+ if (!drvdata) -+ return -EINVAL; -+ - fw_node = of_find_compatible_node(NULL, NULL, - "raspberrypi,bcm2835-firmware"); - if (!fw_node) { -@@ -3620,12 +3641,12 @@ static int vchiq_probe(struct platform_d - return -ENOENT; - } - -- fw = rpi_firmware_get(fw_node); -+ drvdata->fw = rpi_firmware_get(fw_node); - of_node_put(fw_node); -- if (!fw) -+ if (!drvdata->fw) - return -EPROBE_DEFER; - -- platform_set_drvdata(pdev, fw); -+ platform_set_drvdata(pdev, drvdata); - - err = vchiq_platform_init(pdev, &g_state); - if (err != 0) -@@ -3703,12 +3724,6 @@ static int vchiq_remove(struct platform_ - return 0; - } - --static const struct of_device_id vchiq_of_match[] = { -- { .compatible = "brcm,bcm2835-vchiq", }, -- {}, --}; --MODULE_DEVICE_TABLE(of, vchiq_of_match); -- - static struct platform_driver vchiq_driver = { - .driver = { - .name = "bcm2835_vchiq", ---- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h -+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h -@@ -123,6 +123,11 @@ typedef struct vchiq_arm_state_struct { - - } VCHIQ_ARM_STATE_T; - -+struct vchiq_drvdata { -+ const unsigned int cache_line_size; -+ struct rpi_firmware *fw; -+}; -+ - extern int vchiq_arm_log_level; - extern int vchiq_susp_log_level; - diff --git a/target/linux/brcm2708/patches-4.19/950-0526-dts-Use-fb-rather-than-leds-for-dpi-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0526-dts-Use-fb-rather-than-leds-for-dpi-overlay.patch new file mode 100644 index 0000000000..b7552ff39f --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0526-dts-Use-fb-rather-than-leds-for-dpi-overlay.patch @@ -0,0 +1,32 @@ +From d907bff594e59457b42df94c8da1b34f1964b2ae Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Thu, 12 Oct 2017 18:11:32 +0100 +Subject: [PATCH 526/725] dts: Use fb rather than leds for dpi overlay + +--- + arch/arm/boot/dts/overlays/dpi18-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/dpi24-overlay.dts | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/overlays/dpi18-overlay.dts ++++ b/arch/arm/boot/dts/overlays/dpi18-overlay.dts +@@ -9,7 +9,7 @@ + // reference on - leds will do + + fragment@0 { +- target = <&leds>; ++ target = <&fb>; + __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&dpi18_pins>; +--- a/arch/arm/boot/dts/overlays/dpi24-overlay.dts ++++ b/arch/arm/boot/dts/overlays/dpi24-overlay.dts +@@ -9,7 +9,7 @@ + // reference on - leds will do + + fragment@0 { +- target = <&leds>; ++ target = <&fb>; + __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&dpi24_pins>; diff --git a/target/linux/brcm2708/patches-4.19/950-0526-tty-amba-pl011-allow-shared-interrupt.patch b/target/linux/brcm2708/patches-4.19/950-0526-tty-amba-pl011-allow-shared-interrupt.patch deleted file mode 100644 index d726ee31d9..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0526-tty-amba-pl011-allow-shared-interrupt.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 135b1563027fb8f30be1a9daae3db209166028af Mon Sep 17 00:00:00 2001 -From: Doug Berger -Date: Mon, 13 May 2019 20:59:45 +0200 -Subject: [PATCH 526/703] tty: amba-pl011: allow shared interrupt - -The PL011 register space includes all necessary status bits to -determine whether a device instance requires handling in response -to an interrupt. Therefore, multiple instances of the device could -be serviced by a single shared interrupt, which is the case on BCM7211. - -Signed-off-by: Doug Berger -Signed-off-by: Florian Fainelli ---- - drivers/tty/serial/amba-pl011.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/tty/serial/amba-pl011.c -+++ b/drivers/tty/serial/amba-pl011.c -@@ -1735,7 +1735,8 @@ static int pl011_allocate_irq(struct uar - { - pl011_write(uap->im, uap, REG_IMSC); - -- return request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap); -+ return request_irq(uap->port.irq, pl011_int, IRQF_SHARED, "uart-pl011", -+ uap); - } - - /* diff --git a/target/linux/brcm2708/patches-4.19/950-0527-ARM-bcm283x-Reduce-register-ranges-for-UART-SPI-and-.patch b/target/linux/brcm2708/patches-4.19/950-0527-ARM-bcm283x-Reduce-register-ranges-for-UART-SPI-and-.patch deleted file mode 100644 index 2fc2d163d8..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0527-ARM-bcm283x-Reduce-register-ranges-for-UART-SPI-and-.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 272132a1b67448ec6e72e431abe0ca00cc4e0554 Mon Sep 17 00:00:00 2001 -From: Stefan Wahren -Date: Sun, 19 May 2019 12:20:00 +0200 -Subject: [PATCH 527/703] ARM: bcm283x: Reduce register ranges for UART, SPI - and I2C - -The assigned register ranges for UART, SPI and I2C were too wasteful. -In order to avoid overlapping with the new functions on BCM2838 -reduce the ranges. - -Signed-off-by: Stefan Wahren ---- - arch/arm/boot/dts/bcm283x.dtsi | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/arch/arm/boot/dts/bcm283x.dtsi -+++ b/arch/arm/boot/dts/bcm283x.dtsi -@@ -387,7 +387,7 @@ - - uart0: serial@7e201000 { - compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; -- reg = <0x7e201000 0x1000>; -+ reg = <0x7e201000 0x200>; - interrupts = <2 25>; - clocks = <&clocks BCM2835_CLOCK_UART>, - <&clocks BCM2835_CLOCK_VPU>; -@@ -418,7 +418,7 @@ - - spi: spi@7e204000 { - compatible = "brcm,bcm2835-spi"; -- reg = <0x7e204000 0x1000>; -+ reg = <0x7e204000 0x200>; - interrupts = <2 22>; - clocks = <&clocks BCM2835_CLOCK_VPU>; - #address-cells = <1>; -@@ -428,7 +428,7 @@ - - i2c0: i2c@7e205000 { - compatible = "brcm,bcm2835-i2c"; -- reg = <0x7e205000 0x1000>; -+ reg = <0x7e205000 0x200>; - interrupts = <2 21>; - clocks = <&clocks BCM2835_CLOCK_VPU>; - #address-cells = <1>; diff --git a/target/linux/brcm2708/patches-4.19/950-0527-BCM270X_DT-Minor-tidy-up.patch b/target/linux/brcm2708/patches-4.19/950-0527-BCM270X_DT-Minor-tidy-up.patch new file mode 100644 index 0000000000..83e710efbf --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0527-BCM270X_DT-Minor-tidy-up.patch @@ -0,0 +1,95 @@ +From fb2ff9ebd588db603dc9df848203e2f764a3ae90 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 29 May 2019 15:19:21 +0100 +Subject: [PATCH 527/725] BCM270X_DT: Minor tidy up + +Move arm_pmu out of soc on bcm2710, and labels aren't aliases. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/bcm270x.dtsi | 14 +++++++------- + arch/arm/boot/dts/bcm2710.dtsi | 13 +++++-------- + 2 files changed, 12 insertions(+), 15 deletions(-) + +--- a/arch/arm/boot/dts/bcm270x.dtsi ++++ b/arch/arm/boot/dts/bcm270x.dtsi +@@ -10,11 +10,11 @@ + soc: soc { + + watchdog: watchdog@7e100000 { +- /* Add alias */ ++ /* Add label */ + }; + + random: rng@7e104000 { +- /* Add alias */ ++ /* Add label */ + }; + + gpio@7e200000 { /* gpio */ +@@ -40,18 +40,18 @@ + }; + + spi0: spi@7e204000 { +- /* Add alias */ ++ /* Add label */ + dmas = <&dma 6>, <&dma 7>; + dma-names = "tx", "rx"; + }; + + pixelvalve0: pixelvalve@7e206000 { +- /* Add alias */ ++ /* Add label */ + status = "disabled"; + }; + + pixelvalve1: pixelvalve@7e207000 { +- /* Add alias */ ++ /* Add label */ + status = "disabled"; + }; + +@@ -93,7 +93,7 @@ + }; + + hvs: hvs@7e400000 { +- /* Add alias */ ++ /* Add label */ + status = "disabled"; + }; + +@@ -119,7 +119,7 @@ + }; + + pixelvalve2: pixelvalve@7e807000 { +- /* Add alias */ ++ /* Add label */ + status = "disabled"; + }; + +--- a/arch/arm/boot/dts/bcm2710.dtsi ++++ b/arch/arm/boot/dts/bcm2710.dtsi +@@ -5,18 +5,15 @@ + / { + compatible = "brcm,bcm2837", "brcm,bcm2836"; + +- soc { +- +- arm-pmu { ++ arm-pmu { + #ifdef RPI364 +- compatible = "arm,armv8-pmuv3", "arm,cortex-a7-pmu"; ++ compatible = "arm,armv8-pmuv3", "arm,cortex-a7-pmu"; + #else +- compatible = "arm,cortex-a7-pmu"; ++ compatible = "arm,cortex-a7-pmu"; + #endif +- interrupt-parent = <&local_intc>; +- interrupts = <9 IRQ_TYPE_LEVEL_HIGH>; +- }; ++ }; + ++ soc { + /delete-node/ timer@7e003000; + }; + diff --git a/target/linux/brcm2708/patches-4.19/950-0528-ARM-bcm283x-Extend-the-WDT-DT-node-out-to-cover-the-.patch b/target/linux/brcm2708/patches-4.19/950-0528-ARM-bcm283x-Extend-the-WDT-DT-node-out-to-cover-the-.patch deleted file mode 100644 index 5a808b5ddd..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0528-ARM-bcm283x-Extend-the-WDT-DT-node-out-to-cover-the-.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 35c9dd5eb19625b5eba5373ca780eef9e4029e87 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Wed, 12 Dec 2018 15:51:49 -0800 -Subject: [PATCH 528/703] ARM: bcm283x: Extend the WDT DT node out to cover the - whole PM block. (v4) - -It was covering part of the PM block's range, up to the WDT regs. To -support the rest of the PM block's functionality, we need the full -register range plus the AXI Async Bridge regs for PM sequencing. - -This doesn't convert any of the consumers over to the new binding yet, -since we will need to be careful in coordinating our usage of firmware -services that might power domains on and off versus the bcm2835-pm -driver's access of those same domains. - -Signed-off-by: Eric Anholt -Acked-by: Stefan Wahren -Signed-off-by: Stefan Wahren -(cherry picked from commit 29abc92c1d93e28a8f4d55e6343eec4faf44025a) ---- - arch/arm/boot/dts/bcm283x.dtsi | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - ---- a/arch/arm/boot/dts/bcm283x.dtsi -+++ b/arch/arm/boot/dts/bcm283x.dtsi -@@ -121,8 +121,17 @@ - }; - - watchdog@7e100000 { -- compatible = "brcm,bcm2835-pm-wdt"; -- reg = <0x7e100000 0x28>; -+ compatible = "brcm,bcm2835-pm", "brcm,bcm2835-pm-wdt"; -+ #power-domain-cells = <1>; -+ #reset-cells = <1>; -+ reg = <0x7e100000 0x114>, -+ <0x7e00a000 0x24>; -+ clocks = <&clocks BCM2835_CLOCK_V3D>, -+ <&clocks BCM2835_CLOCK_PERI_IMAGE>, -+ <&clocks BCM2835_CLOCK_H264>, -+ <&clocks BCM2835_CLOCK_ISP>; -+ clock-names = "v3d", "peri_image", "h264", "isp"; -+ system-power-controller; - }; - - clocks: cprman@7e101000 { diff --git a/target/linux/brcm2708/patches-4.19/950-0528-arm-bcm2835-Fix-FIQ-early-ioremap.patch b/target/linux/brcm2708/patches-4.19/950-0528-arm-bcm2835-Fix-FIQ-early-ioremap.patch new file mode 100644 index 0000000000..f9f6167689 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0528-arm-bcm2835-Fix-FIQ-early-ioremap.patch @@ -0,0 +1,73 @@ +From 35a736173fb6404fe35467a8c4802f7cd060388a Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 20 Feb 2019 08:49:39 +0000 +Subject: [PATCH 528/725] arm: bcm2835: Fix FIQ early ioremap + +The ioremapping creates mappings within the vmalloc area. The +equivalent early function, create_mapping, now checks that the +requested explicit virtual address is between VMALLOC_START and +VMALLOC_END. As there is no reason to have any correlation between +the physical and virtual addresses, put the required mappings at +VMALLOC_START and above. + +Signed-off-by: Phil Elwell +--- + arch/arm/mach-bcm/board_bcm2835.c | 21 +++++++++++++++------ + 1 file changed, 15 insertions(+), 6 deletions(-) + +--- a/arch/arm/mach-bcm/board_bcm2835.c ++++ b/arch/arm/mach-bcm/board_bcm2835.c +@@ -14,17 +14,20 @@ + + #include + #include ++#include + #include + #include + #include + + #include + #include ++#include ++#include + + #include "platsmp.h" + +-#define BCM2835_USB_VIRT_BASE 0xf0980000 +-#define BCM2835_USB_VIRT_MPHI 0xf0006000 ++#define BCM2835_USB_VIRT_BASE (VMALLOC_START) ++#define BCM2835_USB_VIRT_MPHI (VMALLOC_START + 0x10000) + + static void __init bcm2835_init(void) + { +@@ -83,20 +86,26 @@ static int __init bcm2835_map_usb(unsign + + static void __init bcm2835_map_io(void) + { +- const __be32 *ranges; ++ const __be32 *ranges, *address_cells; ++ unsigned long root, addr_cells; + int soc, len; + unsigned long p2b_offset; + + debug_ll_io_init(); + ++ root = of_get_flat_dt_root(); + /* Find out how to map bus to physical address first from soc/ranges */ +- soc = of_get_flat_dt_subnode_by_name(of_get_flat_dt_root(), "soc"); ++ soc = of_get_flat_dt_subnode_by_name(root, "soc"); + if (soc < 0) + return; ++ address_cells = of_get_flat_dt_prop(root, "#address-cells", &len); ++ if (!address_cells || len < (sizeof(unsigned long))) ++ return; ++ addr_cells = be32_to_cpu(address_cells[0]); + ranges = of_get_flat_dt_prop(soc, "ranges", &len); +- if (!ranges || len < (sizeof(unsigned long) * 3)) ++ if (!ranges || len < (sizeof(unsigned long) * (2 + addr_cells))) + return; +- p2b_offset = be32_to_cpu(ranges[0]) - be32_to_cpu(ranges[1]); ++ p2b_offset = be32_to_cpu(ranges[0]) - be32_to_cpu(ranges[addr_cells]); + + /* Now search for bcm2708-usb node in device tree */ + of_scan_flat_dt(bcm2835_map_usb, &p2b_offset); diff --git a/target/linux/brcm2708/patches-4.19/950-0529-ARM-dts-Add-label-to-bcm2835-RNG.patch b/target/linux/brcm2708/patches-4.19/950-0529-ARM-dts-Add-label-to-bcm2835-RNG.patch deleted file mode 100644 index dfe6f5b3fb..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0529-ARM-dts-Add-label-to-bcm2835-RNG.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 381ffaf15617d63c898f3b70105dc42d17e4ed3b Mon Sep 17 00:00:00 2001 -From: Stefan Wahren -Date: Sat, 4 May 2019 17:06:54 +0200 -Subject: [PATCH 529/703] ARM: dts: Add label to bcm2835 RNG - ---- - arch/arm/boot/dts/bcm283x.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/bcm283x.dtsi -+++ b/arch/arm/boot/dts/bcm283x.dtsi -@@ -148,7 +148,7 @@ - <&dsi1 0>, <&dsi1 1>, <&dsi1 2>; - }; - -- rng@7e104000 { -+ rng: rng@7e104000 { - compatible = "brcm,bcm2835-rng"; - reg = <0x7e104000 0x10>; - interrupts = <2 29>; diff --git a/target/linux/brcm2708/patches-4.19/950-0529-Fix-copy_from_user-if-BCM2835_FAST_MEMCPY-n.patch b/target/linux/brcm2708/patches-4.19/950-0529-Fix-copy_from_user-if-BCM2835_FAST_MEMCPY-n.patch new file mode 100644 index 0000000000..6b6922ce22 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0529-Fix-copy_from_user-if-BCM2835_FAST_MEMCPY-n.patch @@ -0,0 +1,39 @@ +From 4006c9ee386c4b3f33e816130bad8dc44030a316 Mon Sep 17 00:00:00 2001 +From: Tim Gover +Date: Thu, 14 Mar 2019 10:16:02 +0000 +Subject: [PATCH 529/725] Fix copy_from_user if BCM2835_FAST_MEMCPY=n + +The change which introduced CONFIG_BCM2835_FAST_MEMCPY unconditionally +changed the behaviour of arm_copy_from_user. The page pinning code +is not safe on ARMv7 if LPAE & high memory is enabled and causes +crashes which look like PTE corruption. + +Make __copy_from_user_memcpy conditional on CONFIG_2835_FAST_MEMCPY=y +which is really an ARMv6 / Pi1 optimization and not necessary on newer +ARM processors. +--- + arch/arm/lib/uaccess_with_memcpy.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/arch/arm/lib/uaccess_with_memcpy.c ++++ b/arch/arm/lib/uaccess_with_memcpy.c +@@ -257,6 +257,7 @@ arm_copy_to_user(void __user *to, const + unsigned long __must_check + arm_copy_from_user(void *to, const void __user *from, unsigned long n) + { ++#ifdef CONFIG_BCM2835_FAST_MEMCPY + /* + * This test is stubbed out of the main function above to keep + * the overhead for small copies low by avoiding a large +@@ -271,6 +272,11 @@ arm_copy_from_user(void *to, const void + } else { + n = __copy_from_user_memcpy(to, from, n); + } ++#else ++ unsigned long ua_flags = uaccess_save_and_enable(); ++ n = __copy_from_user_std(to, from, n); ++ uaccess_restore(ua_flags); ++#endif + return n; + } + diff --git a/target/linux/brcm2708/patches-4.19/950-0530-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch b/target/linux/brcm2708/patches-4.19/950-0530-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch new file mode 100644 index 0000000000..1622195683 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0530-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch @@ -0,0 +1,1187 @@ +From 0677ac68d2063ba12ea08e847d08b7b25089a283 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 19 Feb 2019 22:06:59 +0000 +Subject: [PATCH 530/725] PCI: brcmstb: Add Broadcom STB PCIe host controller + driver + +This commit adds the basic Broadcom STB PCIe controller. Missing is +the ability to process MSI and also handle dma-ranges for inbound +memory accesses. These two functionalities are added in subsequent +commits. + +The PCIe block contains an MDIO interface. This is a local interface +only accessible by the PCIe controller. It cannot be used or shared +by any other HW. As such, the small amount of code for this +controller is included in this driver as there is little upside to put +it elsewhere. + +Signed-off-by: Jim Quinlan +--- + drivers/pci/controller/Kconfig | 9 + + drivers/pci/controller/Makefile | 2 +- + drivers/pci/controller/pcie-brcmstb.c | 1097 +++++++++++++++++++++++++ + include/soc/brcmstb/memory_api.h | 25 + + 4 files changed, 1132 insertions(+), 1 deletion(-) + create mode 100644 drivers/pci/controller/pcie-brcmstb.c + create mode 100644 include/soc/brcmstb/memory_api.h + +--- a/drivers/pci/controller/Kconfig ++++ b/drivers/pci/controller/Kconfig +@@ -278,5 +278,14 @@ config VMD + To compile this driver as a module, choose M here: the + module will be called vmd. + ++config PCIE_BRCMSTB ++ tristate "Broadcom Brcmstb PCIe platform host driver" ++ depends on ARCH_BRCMSTB || BMIPS_GENERIC ++ depends on OF ++ depends on SOC_BRCMSTB ++ default ARCH_BRCMSTB || BMIPS_GENERIC ++ help ++ Adds support for Broadcom Settop Box PCIe host controller. ++ + source "drivers/pci/controller/dwc/Kconfig" + endmenu +--- a/drivers/pci/controller/Makefile ++++ b/drivers/pci/controller/Makefile +@@ -28,11 +28,11 @@ obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcie + obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o + obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o + obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o ++obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o + obj-$(CONFIG_VMD) += vmd.o + # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW + obj-y += dwc/ + +- + # The following drivers are for devices that use the generic ACPI + # pci_root.c driver but don't support standard ECAM config access. + # They contain MCFG quirks to replace the generic ECAM accessors with +--- /dev/null ++++ b/drivers/pci/controller/pcie-brcmstb.c +@@ -0,0 +1,1097 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright (C) 2009 - 2017 Broadcom */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "../pci.h" ++ ++/* BRCM_PCIE_CAP_REGS - Offset for the mandatory capability config regs */ ++#define BRCM_PCIE_CAP_REGS 0x00ac ++ ++/* ++ * Broadcom Settop Box PCIe Register Offsets. The names are from ++ * the chip's RDB and we use them here so that a script can correlate ++ * this code and the RDB to prevent discrepancies. ++ */ ++#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1 0x0188 ++#define PCIE_RC_CFG_PRIV1_ID_VAL3 0x043c ++#define PCIE_RC_DL_MDIO_ADDR 0x1100 ++#define PCIE_RC_DL_MDIO_WR_DATA 0x1104 ++#define PCIE_RC_DL_MDIO_RD_DATA 0x1108 ++#define PCIE_MISC_MISC_CTRL 0x4008 ++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO 0x400c ++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI 0x4010 ++#define PCIE_MISC_RC_BAR1_CONFIG_LO 0x402c ++#define PCIE_MISC_RC_BAR2_CONFIG_LO 0x4034 ++#define PCIE_MISC_RC_BAR2_CONFIG_HI 0x4038 ++#define PCIE_MISC_RC_BAR3_CONFIG_LO 0x403c ++#define PCIE_MISC_PCIE_CTRL 0x4064 ++#define PCIE_MISC_PCIE_STATUS 0x4068 ++#define PCIE_MISC_REVISION 0x406c ++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT 0x4070 ++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI 0x4080 ++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI 0x4084 ++#define PCIE_MISC_HARD_PCIE_HARD_DEBUG 0x4204 ++#define PCIE_INTR2_CPU_BASE 0x4300 ++ ++/* ++ * Broadcom Settop Box PCIe Register Field shift and mask info. The ++ * names are from the chip's RDB and we use them here so that a script ++ * can correlate this code and the RDB to prevent discrepancies. ++ */ ++#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK 0xc ++#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_SHIFT 0x2 ++#define PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK 0xffffff ++#define PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_SHIFT 0x0 ++#define PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK 0x1000 ++#define PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_SHIFT 0xc ++#define PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK 0x2000 ++#define PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_SHIFT 0xd ++#define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK 0x300000 ++#define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_SHIFT 0x14 ++#define PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK 0xf8000000 ++#define PCIE_MISC_MISC_CTRL_SCB0_SIZE_SHIFT 0x1b ++#define PCIE_MISC_MISC_CTRL_SCB1_SIZE_MASK 0x7c00000 ++#define PCIE_MISC_MISC_CTRL_SCB1_SIZE_SHIFT 0x16 ++#define PCIE_MISC_MISC_CTRL_SCB2_SIZE_MASK 0x1f ++#define PCIE_MISC_MISC_CTRL_SCB2_SIZE_SHIFT 0x0 ++#define PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_MASK 0x1f ++#define PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_SHIFT 0x0 ++#define PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_MASK 0x1f ++#define PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_SHIFT 0x0 ++#define PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK 0x1f ++#define PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_SHIFT 0x0 ++#define PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_MASK 0x4 ++#define PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_SHIFT 0x2 ++#define PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_MASK 0x1 ++#define PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_SHIFT 0x0 ++#define PCIE_MISC_PCIE_STATUS_PCIE_PORT_MASK 0x80 ++#define PCIE_MISC_PCIE_STATUS_PCIE_PORT_SHIFT 0x7 ++#define PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK 0x20 ++#define PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_SHIFT 0x5 ++#define PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK 0x10 ++#define PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_SHIFT 0x4 ++#define PCIE_MISC_PCIE_STATUS_PCIE_LINK_IN_L23_MASK 0x40 ++#define PCIE_MISC_PCIE_STATUS_PCIE_LINK_IN_L23_SHIFT 0x6 ++#define PCIE_MISC_REVISION_MAJMIN_MASK 0xffff ++#define PCIE_MISC_REVISION_MAJMIN_SHIFT 0 ++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK 0xfff00000 ++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_SHIFT 0x14 ++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK 0xfff0 ++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_SHIFT 0x4 ++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_NUM_MASK_BITS 0xc ++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_MASK 0xff ++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_SHIFT 0x0 ++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK 0xff ++#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_SHIFT 0x0 ++#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2 ++#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_SHIFT 0x1 ++#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000 ++#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_SHIFT 0x1b ++#define PCIE_RGR1_SW_INIT_1_PERST_MASK 0x1 ++#define PCIE_RGR1_SW_INIT_1_PERST_SHIFT 0x0 ++ ++#define BRCM_NUM_PCIE_OUT_WINS 0x4 ++#define BRCM_MAX_SCB 0x4 ++ ++#define BRCM_MSI_TARGET_ADDR_LT_4GB 0x0fffffffcULL ++#define BRCM_MSI_TARGET_ADDR_GT_4GB 0xffffffffcULL ++ ++#define BURST_SIZE_128 0 ++#define BURST_SIZE_256 1 ++#define BURST_SIZE_512 2 ++ ++/* Offsets from PCIE_INTR2_CPU_BASE */ ++#define STATUS 0x0 ++#define SET 0x4 ++#define CLR 0x8 ++#define MASK_STATUS 0xc ++#define MASK_SET 0x10 ++#define MASK_CLR 0x14 ++ ++#define PCIE_BUSNUM_SHIFT 20 ++#define PCIE_SLOT_SHIFT 15 ++#define PCIE_FUNC_SHIFT 12 ++ ++#if defined(__BIG_ENDIAN) ++#define DATA_ENDIAN 2 /* PCIe->DDR inbound traffic */ ++#define MMIO_ENDIAN 2 /* CPU->PCIe outbound traffic */ ++#else ++#define DATA_ENDIAN 0 ++#define MMIO_ENDIAN 0 ++#endif ++ ++#define MDIO_PORT0 0x0 ++#define MDIO_DATA_MASK 0x7fffffff ++#define MDIO_DATA_SHIFT 0x0 ++#define MDIO_PORT_MASK 0xf0000 ++#define MDIO_PORT_SHIFT 0x16 ++#define MDIO_REGAD_MASK 0xffff ++#define MDIO_REGAD_SHIFT 0x0 ++#define MDIO_CMD_MASK 0xfff00000 ++#define MDIO_CMD_SHIFT 0x14 ++#define MDIO_CMD_READ 0x1 ++#define MDIO_CMD_WRITE 0x0 ++#define MDIO_DATA_DONE_MASK 0x80000000 ++#define MDIO_RD_DONE(x) (((x) & MDIO_DATA_DONE_MASK) ? 1 : 0) ++#define MDIO_WT_DONE(x) (((x) & MDIO_DATA_DONE_MASK) ? 0 : 1) ++#define SSC_REGS_ADDR 0x1100 ++#define SET_ADDR_OFFSET 0x1f ++#define SSC_CNTL_OFFSET 0x2 ++#define SSC_CNTL_OVRD_EN_MASK 0x8000 ++#define SSC_CNTL_OVRD_EN_SHIFT 0xf ++#define SSC_CNTL_OVRD_VAL_MASK 0x4000 ++#define SSC_CNTL_OVRD_VAL_SHIFT 0xe ++#define SSC_STATUS_OFFSET 0x1 ++#define SSC_STATUS_SSC_MASK 0x400 ++#define SSC_STATUS_SSC_SHIFT 0xa ++#define SSC_STATUS_PLL_LOCK_MASK 0x800 ++#define SSC_STATUS_PLL_LOCK_SHIFT 0xb ++ ++#define IDX_ADDR(pcie) \ ++ ((pcie)->reg_offsets[EXT_CFG_INDEX]) ++#define DATA_ADDR(pcie) \ ++ ((pcie)->reg_offsets[EXT_CFG_DATA]) ++#define PCIE_RGR1_SW_INIT_1(pcie) \ ++ ((pcie)->reg_offsets[RGR1_SW_INIT_1]) ++ ++enum { ++ RGR1_SW_INIT_1, ++ EXT_CFG_INDEX, ++ EXT_CFG_DATA, ++}; ++ ++enum { ++ RGR1_SW_INIT_1_INIT_MASK, ++ RGR1_SW_INIT_1_INIT_SHIFT, ++ RGR1_SW_INIT_1_PERST_MASK, ++ RGR1_SW_INIT_1_PERST_SHIFT, ++}; ++ ++enum pcie_type { ++ BCM7425, ++ BCM7435, ++ GENERIC, ++ BCM7278, ++}; ++ ++struct brcm_window { ++ dma_addr_t pcie_addr; ++ phys_addr_t cpu_addr; ++ dma_addr_t size; ++}; ++ ++/* Internal PCIe Host Controller Information.*/ ++struct brcm_pcie { ++ struct device *dev; ++ void __iomem *base; ++ struct list_head resources; ++ int irq; ++ struct clk *clk; ++ struct pci_bus *root_bus; ++ struct device_node *dn; ++ int id; ++ bool suspended; ++ int num_out_wins; ++ bool ssc; ++ int gen; ++ struct brcm_window out_wins[BRCM_NUM_PCIE_OUT_WINS]; ++ unsigned int rev; ++ const int *reg_offsets; ++ const int *reg_field_info; ++ enum pcie_type type; ++}; ++ ++struct pcie_cfg_data { ++ const int *reg_field_info; ++ const int *offsets; ++ const enum pcie_type type; ++}; ++ ++static const int pcie_reg_field_info[] = { ++ [RGR1_SW_INIT_1_INIT_MASK] = 0x2, ++ [RGR1_SW_INIT_1_INIT_SHIFT] = 0x1, ++}; ++ ++static const int pcie_reg_field_info_bcm7278[] = { ++ [RGR1_SW_INIT_1_INIT_MASK] = 0x1, ++ [RGR1_SW_INIT_1_INIT_SHIFT] = 0x0, ++}; ++ ++static const int pcie_offset_bcm7425[] = { ++ [RGR1_SW_INIT_1] = 0x8010, ++ [EXT_CFG_INDEX] = 0x8300, ++ [EXT_CFG_DATA] = 0x8304, ++}; ++ ++static const struct pcie_cfg_data bcm7425_cfg = { ++ .reg_field_info = pcie_reg_field_info, ++ .offsets = pcie_offset_bcm7425, ++ .type = BCM7425, ++}; ++ ++static const int pcie_offsets[] = { ++ [RGR1_SW_INIT_1] = 0x9210, ++ [EXT_CFG_INDEX] = 0x9000, ++ [EXT_CFG_DATA] = 0x9004, ++}; ++ ++static const struct pcie_cfg_data bcm7435_cfg = { ++ .reg_field_info = pcie_reg_field_info, ++ .offsets = pcie_offsets, ++ .type = BCM7435, ++}; ++ ++static const struct pcie_cfg_data generic_cfg = { ++ .reg_field_info = pcie_reg_field_info, ++ .offsets = pcie_offsets, ++ .type = GENERIC, ++}; ++ ++static const int pcie_offset_bcm7278[] = { ++ [RGR1_SW_INIT_1] = 0xc010, ++ [EXT_CFG_INDEX] = 0x9000, ++ [EXT_CFG_DATA] = 0x9004, ++}; ++ ++static const struct pcie_cfg_data bcm7278_cfg = { ++ .reg_field_info = pcie_reg_field_info_bcm7278, ++ .offsets = pcie_offset_bcm7278, ++ .type = BCM7278, ++}; ++ ++static void __iomem *brcm_pcie_map_conf(struct pci_bus *bus, unsigned int devfn, ++ int where); ++ ++static struct pci_ops brcm_pcie_ops = { ++ .map_bus = brcm_pcie_map_conf, ++ .read = pci_generic_config_read, ++ .write = pci_generic_config_write, ++}; ++ ++#if defined(CONFIG_MIPS) ++/* Broadcom MIPs HW implicitly does the swapping if necessary */ ++#define bcm_readl(a) __raw_readl(a) ++#define bcm_writel(d, a) __raw_writel(d, a) ++#define bcm_readw(a) __raw_readw(a) ++#define bcm_writew(d, a) __raw_writew(d, a) ++#else ++#define bcm_readl(a) readl(a) ++#define bcm_writel(d, a) writel(d, a) ++#define bcm_readw(a) readw(a) ++#define bcm_writew(d, a) writew(d, a) ++#endif ++ ++/* These macros extract/insert fields to host controller's register set. */ ++#define RD_FLD(base, reg, field) \ ++ rd_fld(base + reg, reg##_##field##_MASK, reg##_##field##_SHIFT) ++#define WR_FLD(base, reg, field, val) \ ++ wr_fld(base + reg, reg##_##field##_MASK, reg##_##field##_SHIFT, val) ++#define WR_FLD_RB(base, reg, field, val) \ ++ wr_fld_rb(base + reg, reg##_##field##_MASK, reg##_##field##_SHIFT, val) ++#define WR_FLD_WITH_OFFSET(base, off, reg, field, val) \ ++ wr_fld(base + reg + off, reg##_##field##_MASK, \ ++ reg##_##field##_SHIFT, val) ++#define EXTRACT_FIELD(val, reg, field) \ ++ ((val & reg##_##field##_MASK) >> reg##_##field##_SHIFT) ++#define INSERT_FIELD(val, reg, field, field_val) \ ++ ((val & ~reg##_##field##_MASK) | \ ++ (reg##_##field##_MASK & (field_val << reg##_##field##_SHIFT))) ++ ++static phys_addr_t scb_size[BRCM_MAX_SCB]; ++static int num_memc; ++static int num_pcie; ++static DEFINE_MUTEX(brcm_pcie_lock); ++ ++static u32 rd_fld(void __iomem *p, u32 mask, int shift) ++{ ++ return (bcm_readl(p) & mask) >> shift; ++} ++ ++static void wr_fld(void __iomem *p, u32 mask, int shift, u32 val) ++{ ++ u32 reg = bcm_readl(p); ++ ++ reg = (reg & ~mask) | ((val << shift) & mask); ++ bcm_writel(reg, p); ++} ++ ++static void wr_fld_rb(void __iomem *p, u32 mask, int shift, u32 val) ++{ ++ wr_fld(p, mask, shift, val); ++ (void)bcm_readl(p); ++} ++ ++static const char *link_speed_to_str(int s) ++{ ++ switch (s) { ++ case 1: ++ return "2.5"; ++ case 2: ++ return "5.0"; ++ case 3: ++ return "8.0"; ++ default: ++ break; ++ } ++ return "???"; ++} ++ ++/* ++ * The roundup_pow_of_two() from log2.h invokes ++ * __roundup_pow_of_two(unsigned long), but we really need a ++ * such a function to take a native u64 since unsigned long ++ * is 32 bits on some configurations. So we provide this helper ++ * function below. ++ */ ++static u64 roundup_pow_of_two_64(u64 n) ++{ ++ return 1ULL << fls64(n - 1); ++} ++ ++/* ++ * This is to convert the size of the inbound "BAR" region to the ++ * non-linear values of PCIE_X_MISC_RC_BAR[123]_CONFIG_LO.SIZE ++ */ ++int encode_ibar_size(u64 size) ++{ ++ int log2_in = ilog2(size); ++ ++ if (log2_in >= 12 && log2_in <= 15) ++ /* Covers 4KB to 32KB (inclusive) */ ++ return (log2_in - 12) + 0x1c; ++ else if (log2_in >= 16 && log2_in <= 37) ++ /* Covers 64KB to 32GB, (inclusive) */ ++ return log2_in - 15; ++ /* Something is awry so disable */ ++ return 0; ++} ++ ++static u32 mdio_form_pkt(int port, int regad, int cmd) ++{ ++ u32 pkt = 0; ++ ++ pkt |= (port << MDIO_PORT_SHIFT) & MDIO_PORT_MASK; ++ pkt |= (regad << MDIO_REGAD_SHIFT) & MDIO_REGAD_MASK; ++ pkt |= (cmd << MDIO_CMD_SHIFT) & MDIO_CMD_MASK; ++ ++ return pkt; ++} ++ ++/* negative return value indicates error */ ++static int mdio_read(void __iomem *base, u8 port, u8 regad) ++{ ++ int tries; ++ u32 data; ++ ++ bcm_writel(mdio_form_pkt(port, regad, MDIO_CMD_READ), ++ base + PCIE_RC_DL_MDIO_ADDR); ++ bcm_readl(base + PCIE_RC_DL_MDIO_ADDR); ++ ++ data = bcm_readl(base + PCIE_RC_DL_MDIO_RD_DATA); ++ for (tries = 0; !MDIO_RD_DONE(data) && tries < 10; tries++) { ++ udelay(10); ++ data = bcm_readl(base + PCIE_RC_DL_MDIO_RD_DATA); ++ } ++ ++ return MDIO_RD_DONE(data) ++ ? (data & MDIO_DATA_MASK) >> MDIO_DATA_SHIFT ++ : -EIO; ++} ++ ++/* negative return value indicates error */ ++static int mdio_write(void __iomem *base, u8 port, u8 regad, u16 wrdata) ++{ ++ int tries; ++ u32 data; ++ ++ bcm_writel(mdio_form_pkt(port, regad, MDIO_CMD_WRITE), ++ base + PCIE_RC_DL_MDIO_ADDR); ++ bcm_readl(base + PCIE_RC_DL_MDIO_ADDR); ++ bcm_writel(MDIO_DATA_DONE_MASK | wrdata, ++ base + PCIE_RC_DL_MDIO_WR_DATA); ++ ++ data = bcm_readl(base + PCIE_RC_DL_MDIO_WR_DATA); ++ for (tries = 0; !MDIO_WT_DONE(data) && tries < 10; tries++) { ++ udelay(10); ++ data = bcm_readl(base + PCIE_RC_DL_MDIO_WR_DATA); ++ } ++ ++ return MDIO_WT_DONE(data) ? 0 : -EIO; ++} ++ ++/* ++ * Configures device for Spread Spectrum Clocking (SSC) mode; a negative ++ * return value indicates error. ++ */ ++static int set_ssc(void __iomem *base) ++{ ++ int tmp; ++ u16 wrdata; ++ int pll, ssc; ++ ++ tmp = mdio_write(base, MDIO_PORT0, SET_ADDR_OFFSET, SSC_REGS_ADDR); ++ if (tmp < 0) ++ return tmp; ++ ++ tmp = mdio_read(base, MDIO_PORT0, SSC_CNTL_OFFSET); ++ if (tmp < 0) ++ return tmp; ++ ++ wrdata = INSERT_FIELD(tmp, SSC_CNTL_OVRD, EN, 1); ++ wrdata = INSERT_FIELD(wrdata, SSC_CNTL_OVRD, VAL, 1); ++ tmp = mdio_write(base, MDIO_PORT0, SSC_CNTL_OFFSET, wrdata); ++ if (tmp < 0) ++ return tmp; ++ ++ usleep_range(1000, 2000); ++ tmp = mdio_read(base, MDIO_PORT0, SSC_STATUS_OFFSET); ++ if (tmp < 0) ++ return tmp; ++ ++ ssc = EXTRACT_FIELD(tmp, SSC_STATUS, SSC); ++ pll = EXTRACT_FIELD(tmp, SSC_STATUS, PLL_LOCK); ++ ++ return (ssc && pll) ? 0 : -EIO; ++} ++ ++/* Limits operation to a specific generation (1, 2, or 3) */ ++static void set_gen(void __iomem *base, int gen) ++{ ++ u32 lnkcap = bcm_readl(base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCAP); ++ u16 lnkctl2 = bcm_readw(base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCTL2); ++ ++ lnkcap = (lnkcap & ~PCI_EXP_LNKCAP_SLS) | gen; ++ bcm_writel(lnkcap, base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCAP); ++ ++ lnkctl2 = (lnkctl2 & ~0xf) | gen; ++ bcm_writew(lnkctl2, base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCTL2); ++} ++ ++static void brcm_pcie_set_outbound_win(struct brcm_pcie *pcie, ++ unsigned int win, phys_addr_t cpu_addr, ++ dma_addr_t pcie_addr, dma_addr_t size) ++{ ++ void __iomem *base = pcie->base; ++ phys_addr_t cpu_addr_mb, limit_addr_mb; ++ u32 tmp; ++ ++ /* Set the base of the pcie_addr window */ ++ bcm_writel(lower_32_bits(pcie_addr) + MMIO_ENDIAN, ++ base + PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + (win * 8)); ++ bcm_writel(upper_32_bits(pcie_addr), ++ base + PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + (win * 8)); ++ ++ cpu_addr_mb = cpu_addr >> 20; ++ limit_addr_mb = (cpu_addr + size - 1) >> 20; ++ ++ /* Write the addr base low register */ ++ WR_FLD_WITH_OFFSET(base, (win * 4), ++ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT, ++ BASE, cpu_addr_mb); ++ /* Write the addr limit low register */ ++ WR_FLD_WITH_OFFSET(base, (win * 4), ++ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT, ++ LIMIT, limit_addr_mb); ++ ++ if (pcie->type != BCM7435 && pcie->type != BCM7425) { ++ /* Write the cpu addr high register */ ++ tmp = (u32)(cpu_addr_mb >> ++ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_NUM_MASK_BITS); ++ WR_FLD_WITH_OFFSET(base, (win * 8), ++ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI, ++ BASE, tmp); ++ /* Write the cpu limit high register */ ++ tmp = (u32)(limit_addr_mb >> ++ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_NUM_MASK_BITS); ++ WR_FLD_WITH_OFFSET(base, (win * 8), ++ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI, ++ LIMIT, tmp); ++ } ++} ++ ++/* Configuration space read/write support */ ++static int cfg_index(int busnr, int devfn, int reg) ++{ ++ return ((PCI_SLOT(devfn) & 0x1f) << PCIE_SLOT_SHIFT) ++ | ((PCI_FUNC(devfn) & 0x07) << PCIE_FUNC_SHIFT) ++ | (busnr << PCIE_BUSNUM_SHIFT) ++ | (reg & ~3); ++} ++ ++/* The controller is capable of serving in both RC and EP roles */ ++static bool brcm_pcie_rc_mode(struct brcm_pcie *pcie) ++{ ++ void __iomem *base = pcie->base; ++ u32 val = bcm_readl(base + PCIE_MISC_PCIE_STATUS); ++ ++ return !!EXTRACT_FIELD(val, PCIE_MISC_PCIE_STATUS, PCIE_PORT); ++} ++ ++static bool brcm_pcie_link_up(struct brcm_pcie *pcie) ++{ ++ void __iomem *base = pcie->base; ++ u32 val = bcm_readl(base + PCIE_MISC_PCIE_STATUS); ++ u32 dla = EXTRACT_FIELD(val, PCIE_MISC_PCIE_STATUS, PCIE_DL_ACTIVE); ++ u32 plu = EXTRACT_FIELD(val, PCIE_MISC_PCIE_STATUS, PCIE_PHYLINKUP); ++ ++ return (dla && plu) ? true : false; ++} ++ ++static void __iomem *brcm_pcie_map_conf(struct pci_bus *bus, unsigned int devfn, ++ int where) ++{ ++ struct brcm_pcie *pcie = bus->sysdata; ++ void __iomem *base = pcie->base; ++ int idx; ++ ++ /* Accesses to the RC go right to the RC registers if slot==0 */ ++ if (pci_is_root_bus(bus)) ++ return PCI_SLOT(devfn) ? NULL : base + where; ++ ++ /* For devices, write to the config space index register */ ++ idx = cfg_index(bus->number, devfn, where); ++ bcm_writel(idx, pcie->base + IDX_ADDR(pcie)); ++ return base + DATA_ADDR(pcie) + (where & 0x3); ++} ++ ++static inline void brcm_pcie_bridge_sw_init_set(struct brcm_pcie *pcie, ++ unsigned int val) ++{ ++ unsigned int shift = pcie->reg_field_info[RGR1_SW_INIT_1_INIT_SHIFT]; ++ u32 mask = pcie->reg_field_info[RGR1_SW_INIT_1_INIT_MASK]; ++ ++ wr_fld_rb(pcie->base + PCIE_RGR1_SW_INIT_1(pcie), mask, shift, val); ++} ++ ++static inline void brcm_pcie_perst_set(struct brcm_pcie *pcie, ++ unsigned int val) ++{ ++ if (pcie->type != BCM7278) ++ wr_fld_rb(pcie->base + PCIE_RGR1_SW_INIT_1(pcie), ++ PCIE_RGR1_SW_INIT_1_PERST_MASK, ++ PCIE_RGR1_SW_INIT_1_PERST_SHIFT, val); ++ else ++ /* Assert = 0, de-assert = 1 on 7278 */ ++ WR_FLD_RB(pcie->base, PCIE_MISC_PCIE_CTRL, PCIE_PERSTB, !val); ++} ++ ++static int brcm_pcie_add_controller(struct brcm_pcie *pcie) ++{ ++ int i, ret = 0; ++ ++ mutex_lock(&brcm_pcie_lock); ++ if (num_pcie > 0) { ++ num_pcie++; ++ goto done; ++ } ++ ++ /* Determine num_memc and their sizes */ ++ for (i = 0, num_memc = 0; i < BRCM_MAX_SCB; i++) { ++ u64 size = brcmstb_memory_memc_size(i); ++ ++ if (size == (u64)-1) { ++ dev_err(pcie->dev, "cannot get memc%d size\n", i); ++ ret = -EINVAL; ++ goto done; ++ } else if (size) { ++ scb_size[i] = roundup_pow_of_two_64(size); ++ num_memc++; ++ } else { ++ break; ++ } ++ } ++ if (!ret && num_memc == 0) { ++ ret = -EINVAL; ++ goto done; ++ } ++ ++ num_pcie++; ++done: ++ mutex_unlock(&brcm_pcie_lock); ++ return ret; ++} ++ ++static void brcm_pcie_remove_controller(struct brcm_pcie *pcie) ++{ ++ mutex_lock(&brcm_pcie_lock); ++ if (--num_pcie == 0) ++ num_memc = 0; ++ mutex_unlock(&brcm_pcie_lock); ++} ++ ++static int brcm_pcie_parse_request_of_pci_ranges(struct brcm_pcie *pcie) ++{ ++ struct resource_entry *win; ++ int ret; ++ ++ ret = devm_of_pci_get_host_bridge_resources(pcie->dev, 0, 0xff, ++ &pcie->resources, NULL); ++ if (ret) { ++ dev_err(pcie->dev, "failed to get host resources\n"); ++ return ret; ++ } ++ ++ resource_list_for_each_entry(win, &pcie->resources) { ++ struct resource *parent, *res = win->res; ++ dma_addr_t offset = (dma_addr_t)win->offset; ++ ++ if (resource_type(res) == IORESOURCE_IO) { ++ parent = &ioport_resource; ++ } else if (resource_type(res) == IORESOURCE_MEM) { ++ if (pcie->num_out_wins >= BRCM_NUM_PCIE_OUT_WINS) { ++ dev_err(pcie->dev, "too many outbound wins\n"); ++ return -EINVAL; ++ } ++ pcie->out_wins[pcie->num_out_wins].cpu_addr ++ = (phys_addr_t)res->start; ++ pcie->out_wins[pcie->num_out_wins].pcie_addr ++ = (dma_addr_t)(res->start ++ - (phys_addr_t)offset); ++ pcie->out_wins[pcie->num_out_wins].size ++ = (dma_addr_t)(res->end - res->start + 1); ++ pcie->num_out_wins++; ++ parent = &iomem_resource; ++ } else { ++ continue; ++ } ++ ++ ret = devm_request_resource(pcie->dev, parent, res); ++ if (ret) { ++ dev_err(pcie->dev, "failed to get res %pR\n", res); ++ return ret; ++ } ++ } ++ return 0; ++} ++ ++static int brcm_pcie_setup(struct brcm_pcie *pcie) ++{ ++ void __iomem *base = pcie->base; ++ unsigned int scb_size_val; ++ u64 rc_bar2_offset, rc_bar2_size, total_mem_size = 0; ++ u32 tmp, burst; ++ int i, j, ret, limit; ++ u16 nlw, cls, lnksta; ++ bool ssc_good = false; ++ struct device *dev = pcie->dev; ++ ++ /* Reset the bridge */ ++ brcm_pcie_bridge_sw_init_set(pcie, 1); ++ ++ /* ++ * Ensure that the fundamental reset is asserted, except for 7278, ++ * which fails if we do this. ++ */ ++ if (pcie->type != BCM7278) ++ brcm_pcie_perst_set(pcie, 1); ++ ++ usleep_range(100, 200); ++ ++ /* Take the bridge out of reset */ ++ brcm_pcie_bridge_sw_init_set(pcie, 0); ++ ++ WR_FLD_RB(base, PCIE_MISC_HARD_PCIE_HARD_DEBUG, SERDES_IDDQ, 0); ++ /* Wait for SerDes to be stable */ ++ usleep_range(100, 200); ++ ++ /* Grab the PCIe hw revision number */ ++ tmp = bcm_readl(base + PCIE_MISC_REVISION); ++ pcie->rev = EXTRACT_FIELD(tmp, PCIE_MISC_REVISION, MAJMIN); ++ ++ /* Set SCB_MAX_BURST_SIZE, CFG_READ_UR_MODE, SCB_ACCESS_EN */ ++ tmp = INSERT_FIELD(0, PCIE_MISC_MISC_CTRL, SCB_ACCESS_EN, 1); ++ tmp = INSERT_FIELD(tmp, PCIE_MISC_MISC_CTRL, CFG_READ_UR_MODE, 1); ++ burst = (pcie->type == GENERIC || pcie->type == BCM7278) ++ ? BURST_SIZE_512 : BURST_SIZE_256; ++ tmp = INSERT_FIELD(tmp, PCIE_MISC_MISC_CTRL, MAX_BURST_SIZE, burst); ++ bcm_writel(tmp, base + PCIE_MISC_MISC_CTRL); ++ ++ /* ++ * Set up inbound memory view for the EP (called RC_BAR2, ++ * not to be confused with the BARs that are advertised by ++ * the EP). ++ */ ++ for (i = 0; i < num_memc; i++) ++ total_mem_size += scb_size[i]; ++ ++ /* ++ * The PCIe host controller by design must set the inbound ++ * viewport to be a contiguous arrangement of all of the ++ * system's memory. In addition, its size mut be a power of ++ * two. To further complicate matters, the viewport must ++ * start on a pcie-address that is aligned on a multiple of its ++ * size. If a portion of the viewport does not represent ++ * system memory -- e.g. 3GB of memory requires a 4GB viewport ++ * -- we can map the outbound memory in or after 3GB and even ++ * though the viewport will overlap the outbound memory the ++ * controller will know to send outbound memory downstream and ++ * everything else upstream. ++ */ ++ rc_bar2_size = roundup_pow_of_two_64(total_mem_size); ++ ++ /* ++ * Set simple configuration based on memory sizes ++ * only. We always start the viewport at address 0. ++ */ ++ rc_bar2_offset = 0; ++ ++ tmp = lower_32_bits(rc_bar2_offset); ++ tmp = INSERT_FIELD(tmp, PCIE_MISC_RC_BAR2_CONFIG_LO, SIZE, ++ encode_ibar_size(rc_bar2_size)); ++ bcm_writel(tmp, base + PCIE_MISC_RC_BAR2_CONFIG_LO); ++ bcm_writel(upper_32_bits(rc_bar2_offset), ++ base + PCIE_MISC_RC_BAR2_CONFIG_HI); ++ ++ scb_size_val = scb_size[0] ++ ? ilog2(scb_size[0]) - 15 : 0xf; /* 0xf is 1GB */ ++ WR_FLD(base, PCIE_MISC_MISC_CTRL, SCB0_SIZE, scb_size_val); ++ ++ if (num_memc > 1) { ++ scb_size_val = scb_size[1] ++ ? ilog2(scb_size[1]) - 15 : 0xf; /* 0xf is 1GB */ ++ WR_FLD(base, PCIE_MISC_MISC_CTRL, SCB1_SIZE, scb_size_val); ++ } ++ ++ if (num_memc > 2) { ++ scb_size_val = scb_size[2] ++ ? ilog2(scb_size[2]) - 15 : 0xf; /* 0xf is 1GB */ ++ WR_FLD(base, PCIE_MISC_MISC_CTRL, SCB2_SIZE, scb_size_val); ++ } ++ ++ /* disable the PCIe->GISB memory window (RC_BAR1) */ ++ WR_FLD(base, PCIE_MISC_RC_BAR1_CONFIG_LO, SIZE, 0); ++ ++ /* disable the PCIe->SCB memory window (RC_BAR3) */ ++ WR_FLD(base, PCIE_MISC_RC_BAR3_CONFIG_LO, SIZE, 0); ++ ++ if (!pcie->suspended) { ++ /* clear any interrupts we find on boot */ ++ bcm_writel(0xffffffff, base + PCIE_INTR2_CPU_BASE + CLR); ++ (void)bcm_readl(base + PCIE_INTR2_CPU_BASE + CLR); ++ } ++ ++ /* Mask all interrupts since we are not handling any yet */ ++ bcm_writel(0xffffffff, base + PCIE_INTR2_CPU_BASE + MASK_SET); ++ (void)bcm_readl(base + PCIE_INTR2_CPU_BASE + MASK_SET); ++ ++ if (pcie->gen) ++ set_gen(base, pcie->gen); ++ ++ /* Unassert the fundamental reset */ ++ brcm_pcie_perst_set(pcie, 0); ++ ++ /* ++ * Give the RC/EP time to wake up, before trying to configure RC. ++ * Intermittently check status for link-up, up to a total of 100ms ++ * when we don't know if the device is there, and up to 1000ms if ++ * we do know the device is there. ++ */ ++ limit = pcie->suspended ? 1000 : 100; ++ for (i = 1, j = 0; j < limit && !brcm_pcie_link_up(pcie); ++ j += i, i = i * 2) ++ msleep(i + j > limit ? limit - j : i); ++ ++ if (!brcm_pcie_link_up(pcie)) { ++ dev_info(dev, "link down\n"); ++ return -ENODEV; ++ } ++ ++ if (!brcm_pcie_rc_mode(pcie)) { ++ dev_err(dev, "PCIe misconfigured; is in EP mode\n"); ++ return -EINVAL; ++ } ++ ++ for (i = 0; i < pcie->num_out_wins; i++) ++ brcm_pcie_set_outbound_win(pcie, i, pcie->out_wins[i].cpu_addr, ++ pcie->out_wins[i].pcie_addr, ++ pcie->out_wins[i].size); ++ ++ /* ++ * For config space accesses on the RC, show the right class for ++ * a PCIe-PCIe bridge (the default setting is to be EP mode). ++ */ ++ WR_FLD_RB(base, PCIE_RC_CFG_PRIV1_ID_VAL3, CLASS_CODE, 0x060400); ++ ++ if (pcie->ssc) { ++ ret = set_ssc(base); ++ if (ret == 0) ++ ssc_good = true; ++ else ++ dev_err(dev, "failed attempt to enter ssc mode\n"); ++ } ++ ++ lnksta = bcm_readw(base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKSTA); ++ cls = lnksta & PCI_EXP_LNKSTA_CLS; ++ nlw = (lnksta & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT; ++ dev_info(dev, "link up, %s Gbps x%u %s\n", link_speed_to_str(cls), ++ nlw, ssc_good ? "(SSC)" : "(!SSC)"); ++ ++ /* PCIe->SCB endian mode for BAR */ ++ /* field ENDIAN_MODE_BAR2 = DATA_ENDIAN */ ++ WR_FLD_RB(base, PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1, ++ ENDIAN_MODE_BAR2, DATA_ENDIAN); ++ ++ /* ++ * Refclk from RC should be gated with CLKREQ# input when ASPM L0s,L1 ++ * is enabled => setting the CLKREQ_DEBUG_ENABLE field to 1. ++ */ ++ WR_FLD_RB(base, PCIE_MISC_HARD_PCIE_HARD_DEBUG, CLKREQ_DEBUG_ENABLE, 1); ++ ++ return 0; ++} ++ ++/* L23 is a low-power PCIe link state */ ++static void enter_l23(struct brcm_pcie *pcie) ++{ ++ void __iomem *base = pcie->base; ++ int tries, l23; ++ ++ /* assert request for L23 */ ++ WR_FLD_RB(base, PCIE_MISC_PCIE_CTRL, PCIE_L23_REQUEST, 1); ++ /* poll L23 status */ ++ for (tries = 0, l23 = 0; tries < 1000 && !l23; tries++) ++ l23 = RD_FLD(base, PCIE_MISC_PCIE_STATUS, PCIE_LINK_IN_L23); ++ if (!l23) ++ dev_err(pcie->dev, "failed to enter L23\n"); ++} ++ ++static void turn_off(struct brcm_pcie *pcie) ++{ ++ void __iomem *base = pcie->base; ++ ++ if (brcm_pcie_link_up(pcie)) ++ enter_l23(pcie); ++ /* Assert fundamental reset */ ++ brcm_pcie_perst_set(pcie, 1); ++ /* Deassert request for L23 in case it was asserted */ ++ WR_FLD_RB(base, PCIE_MISC_PCIE_CTRL, PCIE_L23_REQUEST, 0); ++ /* Turn off SerDes */ ++ WR_FLD_RB(base, PCIE_MISC_HARD_PCIE_HARD_DEBUG, SERDES_IDDQ, 1); ++ /* Shutdown PCIe bridge */ ++ brcm_pcie_bridge_sw_init_set(pcie, 1); ++} ++ ++static int brcm_pcie_suspend(struct device *dev) ++{ ++ struct brcm_pcie *pcie = dev_get_drvdata(dev); ++ ++ turn_off(pcie); ++ clk_disable_unprepare(pcie->clk); ++ pcie->suspended = true; ++ ++ return 0; ++} ++ ++static int brcm_pcie_resume(struct device *dev) ++{ ++ struct brcm_pcie *pcie = dev_get_drvdata(dev); ++ void __iomem *base; ++ int ret; ++ ++ base = pcie->base; ++ clk_prepare_enable(pcie->clk); ++ ++ /* Take bridge out of reset so we can access the SerDes reg */ ++ brcm_pcie_bridge_sw_init_set(pcie, 0); ++ ++ /* Turn on SerDes */ ++ WR_FLD_RB(base, PCIE_MISC_HARD_PCIE_HARD_DEBUG, SERDES_IDDQ, 0); ++ /* Wait for SerDes to be stable */ ++ usleep_range(100, 200); ++ ++ ret = brcm_pcie_setup(pcie); ++ if (ret) ++ return ret; ++ ++ pcie->suspended = false; ++ ++ return 0; ++} ++ ++static void _brcm_pcie_remove(struct brcm_pcie *pcie) ++{ ++ turn_off(pcie); ++ clk_disable_unprepare(pcie->clk); ++ clk_put(pcie->clk); ++ brcm_pcie_remove_controller(pcie); ++} ++ ++static int brcm_pcie_remove(struct platform_device *pdev) ++{ ++ struct brcm_pcie *pcie = platform_get_drvdata(pdev); ++ ++ pci_stop_root_bus(pcie->root_bus); ++ pci_remove_root_bus(pcie->root_bus); ++ _brcm_pcie_remove(pcie); ++ ++ return 0; ++} ++ ++static const struct of_device_id brcm_pcie_match[] = { ++ { .compatible = "brcm,bcm7425-pcie", .data = &bcm7425_cfg }, ++ { .compatible = "brcm,bcm7435-pcie", .data = &bcm7435_cfg }, ++ { .compatible = "brcm,bcm7278-pcie", .data = &bcm7278_cfg }, ++ { .compatible = "brcm,bcm7445-pcie", .data = &generic_cfg }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, brcm_pcie_match); ++ ++static int brcm_pcie_probe(struct platform_device *pdev) ++{ ++ struct device_node *dn = pdev->dev.of_node; ++ const struct of_device_id *of_id; ++ const struct pcie_cfg_data *data; ++ int ret; ++ struct brcm_pcie *pcie; ++ struct resource *res; ++ void __iomem *base; ++ u32 tmp; ++ struct pci_host_bridge *bridge; ++ struct pci_bus *child; ++ ++ bridge = devm_pci_alloc_host_bridge(&pdev->dev, sizeof(*pcie)); ++ if (!bridge) ++ return -ENOMEM; ++ ++ pcie = pci_host_bridge_priv(bridge); ++ INIT_LIST_HEAD(&pcie->resources); ++ ++ of_id = of_match_node(brcm_pcie_match, dn); ++ if (!of_id) { ++ dev_err(&pdev->dev, "failed to look up compatible string\n"); ++ return -EINVAL; ++ } ++ ++ if (of_property_read_u32(dn, "dma-ranges", &tmp) == 0) { ++ dev_err(&pdev->dev, "cannot yet handle dma-ranges\n"); ++ return -EINVAL; ++ } ++ ++ data = of_id->data; ++ pcie->reg_offsets = data->offsets; ++ pcie->reg_field_info = data->reg_field_info; ++ pcie->type = data->type; ++ pcie->dn = dn; ++ pcie->dev = &pdev->dev; ++ ++ /* We use the domain number as our controller number */ ++ pcie->id = of_get_pci_domain_nr(dn); ++ if (pcie->id < 0) ++ return pcie->id; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) ++ return -EINVAL; ++ ++ base = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ pcie->clk = of_clk_get_by_name(dn, "sw_pcie"); ++ if (IS_ERR(pcie->clk)) { ++ dev_err(&pdev->dev, "could not get clock\n"); ++ pcie->clk = NULL; ++ } ++ pcie->base = base; ++ ++ ret = of_pci_get_max_link_speed(dn); ++ pcie->gen = (ret < 0) ? 0 : ret; ++ ++ pcie->ssc = of_property_read_bool(dn, "brcm,enable-ssc"); ++ ++ ret = irq_of_parse_and_map(pdev->dev.of_node, 0); ++ if (ret == 0) ++ /* keep going, as we don't use this intr yet */ ++ dev_warn(pcie->dev, "cannot get PCIe interrupt\n"); ++ else ++ pcie->irq = ret; ++ ++ ret = brcm_pcie_parse_request_of_pci_ranges(pcie); ++ if (ret) ++ return ret; ++ ++ ret = clk_prepare_enable(pcie->clk); ++ if (ret) { ++ dev_err(&pdev->dev, "could not enable clock\n"); ++ return ret; ++ } ++ ++ ret = brcm_pcie_add_controller(pcie); ++ if (ret) ++ return ret; ++ ++ ret = brcm_pcie_setup(pcie); ++ if (ret) ++ goto fail; ++ ++ list_splice_init(&pcie->resources, &bridge->windows); ++ bridge->dev.parent = &pdev->dev; ++ bridge->busnr = 0; ++ bridge->ops = &brcm_pcie_ops; ++ bridge->sysdata = pcie; ++ bridge->map_irq = of_irq_parse_and_map_pci; ++ bridge->swizzle_irq = pci_common_swizzle; ++ ++ ret = pci_scan_root_bus_bridge(bridge); ++ if (ret < 0) { ++ dev_err(pcie->dev, "Scanning root bridge failed\n"); ++ goto fail; ++ } ++ ++ pci_assign_unassigned_bus_resources(bridge->bus); ++ list_for_each_entry(child, &bridge->bus->children, node) ++ pcie_bus_configure_settings(child); ++ pci_bus_add_devices(bridge->bus); ++ platform_set_drvdata(pdev, pcie); ++ pcie->root_bus = bridge->bus; ++ ++ return 0; ++ ++fail: ++ _brcm_pcie_remove(pcie); ++ return ret; ++} ++ ++static const struct dev_pm_ops brcm_pcie_pm_ops = { ++ .suspend_noirq = brcm_pcie_suspend, ++ .resume_noirq = brcm_pcie_resume, ++}; ++ ++static struct platform_driver brcm_pcie_driver = { ++ .probe = brcm_pcie_probe, ++ .remove = brcm_pcie_remove, ++ .driver = { ++ .name = "brcm-pcie", ++ .owner = THIS_MODULE, ++ .of_match_table = brcm_pcie_match, ++ .pm = &brcm_pcie_pm_ops, ++ }, ++}; ++ ++module_platform_driver(brcm_pcie_driver); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("Broadcom STB PCIe RC driver"); ++MODULE_AUTHOR("Broadcom"); +--- /dev/null ++++ b/include/soc/brcmstb/memory_api.h +@@ -0,0 +1,25 @@ ++#ifndef __MEMORY_API_H ++#define __MEMORY_API_H ++ ++/* ++ * Bus Interface Unit control register setup, must happen early during boot, ++ * before SMP is brought up, called by machine entry point. ++ */ ++void brcmstb_biuctrl_init(void); ++ ++#ifdef CONFIG_SOC_BRCMSTB ++int brcmstb_memory_phys_addr_to_memc(phys_addr_t pa); ++u64 brcmstb_memory_memc_size(int memc); ++#else ++static inline int brcmstb_memory_phys_addr_to_memc(phys_addr_t pa) ++{ ++ return -EINVAL; ++} ++ ++static inline u64 brcmstb_memory_memc_size(int memc) ++{ ++ return -1; ++} ++#endif ++ ++#endif /* __MEMORY_API_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0530-dts-Use-fb-rather-than-leds-for-dpi-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0530-dts-Use-fb-rather-than-leds-for-dpi-overlay.patch deleted file mode 100644 index 8339d60d4f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0530-dts-Use-fb-rather-than-leds-for-dpi-overlay.patch +++ /dev/null @@ -1,32 +0,0 @@ -From ef4e6bd54e6b5d352eb62d245bf4354259812d05 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 12 Oct 2017 18:11:32 +0100 -Subject: [PATCH 530/703] dts: Use fb rather than leds for dpi overlay - ---- - arch/arm/boot/dts/overlays/dpi18-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/dpi24-overlay.dts | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - ---- a/arch/arm/boot/dts/overlays/dpi18-overlay.dts -+++ b/arch/arm/boot/dts/overlays/dpi18-overlay.dts -@@ -9,7 +9,7 @@ - // reference on - leds will do - - fragment@0 { -- target = <&leds>; -+ target = <&fb>; - __overlay__ { - pinctrl-names = "default"; - pinctrl-0 = <&dpi18_pins>; ---- a/arch/arm/boot/dts/overlays/dpi24-overlay.dts -+++ b/arch/arm/boot/dts/overlays/dpi24-overlay.dts -@@ -9,7 +9,7 @@ - // reference on - leds will do - - fragment@0 { -- target = <&leds>; -+ target = <&fb>; - __overlay__ { - pinctrl-names = "default"; - pinctrl-0 = <&dpi24_pins>; diff --git a/target/linux/brcm2708/patches-4.19/950-0531-BCM270X_DT-Minor-tidy-up.patch b/target/linux/brcm2708/patches-4.19/950-0531-BCM270X_DT-Minor-tidy-up.patch deleted file mode 100644 index 607f617581..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0531-BCM270X_DT-Minor-tidy-up.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 8b2b33292610a414d8cc3a7a78104fd375bf0cce Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 29 May 2019 15:19:21 +0100 -Subject: [PATCH 531/703] BCM270X_DT: Minor tidy up - -Move arm_pmu out of soc on bcm2710, and labels aren't aliases. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm270x.dtsi | 14 +++++++------- - arch/arm/boot/dts/bcm2710.dtsi | 13 +++++-------- - 2 files changed, 12 insertions(+), 15 deletions(-) - ---- a/arch/arm/boot/dts/bcm270x.dtsi -+++ b/arch/arm/boot/dts/bcm270x.dtsi -@@ -10,11 +10,11 @@ - soc: soc { - - watchdog: watchdog@7e100000 { -- /* Add alias */ -+ /* Add label */ - }; - - random: rng@7e104000 { -- /* Add alias */ -+ /* Add label */ - }; - - gpio@7e200000 { /* gpio */ -@@ -40,18 +40,18 @@ - }; - - spi0: spi@7e204000 { -- /* Add alias */ -+ /* Add label */ - dmas = <&dma 6>, <&dma 7>; - dma-names = "tx", "rx"; - }; - - pixelvalve0: pixelvalve@7e206000 { -- /* Add alias */ -+ /* Add label */ - status = "disabled"; - }; - - pixelvalve1: pixelvalve@7e207000 { -- /* Add alias */ -+ /* Add label */ - status = "disabled"; - }; - -@@ -93,7 +93,7 @@ - }; - - hvs: hvs@7e400000 { -- /* Add alias */ -+ /* Add label */ - status = "disabled"; - }; - -@@ -119,7 +119,7 @@ - }; - - pixelvalve2: pixelvalve@7e807000 { -- /* Add alias */ -+ /* Add label */ - status = "disabled"; - }; - ---- a/arch/arm/boot/dts/bcm2710.dtsi -+++ b/arch/arm/boot/dts/bcm2710.dtsi -@@ -5,18 +5,15 @@ - / { - compatible = "brcm,bcm2837", "brcm,bcm2836"; - -- soc { -- -- arm-pmu { -+ arm-pmu { - #ifdef RPI364 -- compatible = "arm,armv8-pmuv3", "arm,cortex-a7-pmu"; -+ compatible = "arm,armv8-pmuv3", "arm,cortex-a7-pmu"; - #else -- compatible = "arm,cortex-a7-pmu"; -+ compatible = "arm,cortex-a7-pmu"; - #endif -- interrupt-parent = <&local_intc>; -- interrupts = <9 IRQ_TYPE_LEVEL_HIGH>; -- }; -+ }; - -+ soc { - /delete-node/ timer@7e003000; - }; - diff --git a/target/linux/brcm2708/patches-4.19/950-0531-PCI-brcmstb-Add-dma-range-mapping-for-inbound-traffi.patch b/target/linux/brcm2708/patches-4.19/950-0531-PCI-brcmstb-Add-dma-range-mapping-for-inbound-traffi.patch new file mode 100644 index 0000000000..86f3384488 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0531-PCI-brcmstb-Add-dma-range-mapping-for-inbound-traffi.patch @@ -0,0 +1,569 @@ +From 155b86245f5c14317f41a0677ed78601fbe1f28b Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 19 Feb 2019 22:06:59 +0000 +Subject: [PATCH 531/725] PCI: brcmstb: Add dma-range mapping for inbound + traffic + +The Broadcom STB PCIe host controller is intimately related to the +memory subsystem. This close relationship adds complexity to how cpu +system memory is mapped to PCIe memory. Ideally, this mapping is an +identity mapping, or an identity mapping off by a constant. Not so in +this case. + +Consider the Broadcom reference board BCM97445LCC_4X8 which has 6 GB +of system memory. Here is how the PCIe controller maps the +system memory to PCIe memory: + + memc0-a@[ 0....3fffffff] <=> pci@[ 0....3fffffff] + memc0-b@[100000000...13fffffff] <=> pci@[ 40000000....7fffffff] + memc1-a@[ 40000000....7fffffff] <=> pci@[ 80000000....bfffffff] + memc1-b@[300000000...33fffffff] <=> pci@[ c0000000....ffffffff] + memc2-a@[ 80000000....bfffffff] <=> pci@[100000000...13fffffff] + memc2-b@[c00000000...c3fffffff] <=> pci@[140000000...17fffffff] + +Although there are some "gaps" that can be added between the +individual mappings by software, the permutation of memory regions for +the most part is fixed by HW. The solution of having something close +to an identity mapping is not possible. + +The idea behind this HW design is that the same PCIe module can +act as an RC or EP, and if it acts as an EP it concatenates all +of system memory into a BAR so anything can be accessed. Unfortunately, +when the PCIe block is in the role of an RC it also presents this +"BAR" to downstream PCIe devices, rather than offering an identity map +between its system memory and PCIe space. + +Suppose that an endpoint driver allocs some DMA memory. Suppose this +memory is located at 0x6000_0000, which is in the middle of memc1-a. +The driver wants a dma_addr_t value that it can pass on to the EP to +use. Without doing any custom mapping, the EP will use this value for +DMA: the driver will get a dma_addr_t equal to 0x6000_0000. But this +won't work; the device needs a dma_addr_t that reflects the PCIe space +address, namely 0xa000_0000. + +So, essentially the solution to this problem must modify the +dma_addr_t returned by the DMA routines routines. There are two +ways (I know of) of doing this: + +(a) overriding/redefining the dma_to_phys() and phys_to_dma() calls +that are used by the dma_ops routines. This is the approach of + + arch/mips/cavium-octeon/dma-octeon.c + +In ARM and ARM64 these two routines are defiend in asm/dma-mapping.h +as static inline functions. + +(b) Subscribe to a notifier that notifies when a device is added to a +bus. When this happens, set_dma_ops() can be called for the device. +This method is mentioned in: + + http://lxr.free-electrons.com/source/drivers/of/platform.c?v=3.16#L152 + +where it says as a comment + + "In case if platform code need to use own special DMA + configuration, it can use Platform bus notifier and + handle BUS_NOTIFY_ADD_DEVICE event to fix up DMA + configuration." + +Solution (b) is what this commit does. It uses its own set of +dma_ops which are wrappers around the arch_dma_ops. The +wrappers translate the dma addresses before/after invoking +the arch_dma_ops, as appropriate. + +Signed-off-by: Jim Quinlan +--- + drivers/pci/controller/pcie-brcmstb.c | 420 +++++++++++++++++++++++++- + 1 file changed, 411 insertions(+), 9 deletions(-) + +--- a/drivers/pci/controller/pcie-brcmstb.c ++++ b/drivers/pci/controller/pcie-brcmstb.c +@@ -4,6 +4,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -319,11 +320,307 @@ static struct pci_ops brcm_pcie_ops = { + ((val & ~reg##_##field##_MASK) | \ + (reg##_##field##_MASK & (field_val << reg##_##field##_SHIFT))) + ++static const struct dma_map_ops *arch_dma_ops; ++static const struct dma_map_ops *brcm_dma_ops_ptr; ++static struct of_pci_range *dma_ranges; ++static int num_dma_ranges; ++ + static phys_addr_t scb_size[BRCM_MAX_SCB]; + static int num_memc; + static int num_pcie; + static DEFINE_MUTEX(brcm_pcie_lock); + ++static dma_addr_t brcm_to_pci(dma_addr_t addr) ++{ ++ struct of_pci_range *p; ++ ++ if (!num_dma_ranges) ++ return addr; ++ ++ for (p = dma_ranges; p < &dma_ranges[num_dma_ranges]; p++) ++ if (addr >= p->cpu_addr && addr < (p->cpu_addr + p->size)) ++ return addr - p->cpu_addr + p->pci_addr; ++ ++ return addr; ++} ++ ++static dma_addr_t brcm_to_cpu(dma_addr_t addr) ++{ ++ struct of_pci_range *p; ++ ++ if (!num_dma_ranges) ++ return addr; ++ ++ for (p = dma_ranges; p < &dma_ranges[num_dma_ranges]; p++) ++ if (addr >= p->pci_addr && addr < (p->pci_addr + p->size)) ++ return addr - p->pci_addr + p->cpu_addr; ++ ++ return addr; ++} ++ ++static void *brcm_alloc(struct device *dev, size_t size, dma_addr_t *handle, ++ gfp_t gfp, unsigned long attrs) ++{ ++ void *ret; ++ ++ ret = arch_dma_ops->alloc(dev, size, handle, gfp, attrs); ++ if (ret) ++ *handle = brcm_to_pci(*handle); ++ return ret; ++} ++ ++static void brcm_free(struct device *dev, size_t size, void *cpu_addr, ++ dma_addr_t handle, unsigned long attrs) ++{ ++ handle = brcm_to_cpu(handle); ++ arch_dma_ops->free(dev, size, cpu_addr, handle, attrs); ++} ++ ++static int brcm_mmap(struct device *dev, struct vm_area_struct *vma, ++ void *cpu_addr, dma_addr_t dma_addr, size_t size, ++ unsigned long attrs) ++{ ++ dma_addr = brcm_to_cpu(dma_addr); ++ return arch_dma_ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs); ++} ++ ++static int brcm_get_sgtable(struct device *dev, struct sg_table *sgt, ++ void *cpu_addr, dma_addr_t handle, size_t size, ++ unsigned long attrs) ++{ ++ handle = brcm_to_cpu(handle); ++ return arch_dma_ops->get_sgtable(dev, sgt, cpu_addr, handle, size, ++ attrs); ++} ++ ++static dma_addr_t brcm_map_page(struct device *dev, struct page *page, ++ unsigned long offset, size_t size, ++ enum dma_data_direction dir, ++ unsigned long attrs) ++{ ++ return brcm_to_pci(arch_dma_ops->map_page(dev, page, offset, size, ++ dir, attrs)); ++} ++ ++static void brcm_unmap_page(struct device *dev, dma_addr_t handle, ++ size_t size, enum dma_data_direction dir, ++ unsigned long attrs) ++{ ++ handle = brcm_to_cpu(handle); ++ arch_dma_ops->unmap_page(dev, handle, size, dir, attrs); ++} ++ ++static int brcm_map_sg(struct device *dev, struct scatterlist *sgl, ++ int nents, enum dma_data_direction dir, ++ unsigned long attrs) ++{ ++ int i, j; ++ struct scatterlist *sg; ++ ++ for_each_sg(sgl, sg, nents, i) { ++#ifdef CONFIG_NEED_SG_DMA_LENGTH ++ sg->dma_length = sg->length; ++#endif ++ sg->dma_address = ++ brcm_dma_ops_ptr->map_page(dev, sg_page(sg), sg->offset, ++ sg->length, dir, attrs); ++ if (dma_mapping_error(dev, sg->dma_address)) ++ goto bad_mapping; ++ } ++ return nents; ++ ++bad_mapping: ++ for_each_sg(sgl, sg, i, j) ++ brcm_dma_ops_ptr->unmap_page(dev, sg_dma_address(sg), ++ sg_dma_len(sg), dir, attrs); ++ return 0; ++} ++ ++static void brcm_unmap_sg(struct device *dev, ++ struct scatterlist *sgl, int nents, ++ enum dma_data_direction dir, ++ unsigned long attrs) ++{ ++ int i; ++ struct scatterlist *sg; ++ ++ for_each_sg(sgl, sg, nents, i) ++ brcm_dma_ops_ptr->unmap_page(dev, sg_dma_address(sg), ++ sg_dma_len(sg), dir, attrs); ++} ++ ++static void brcm_sync_single_for_cpu(struct device *dev, ++ dma_addr_t handle, size_t size, ++ enum dma_data_direction dir) ++{ ++ handle = brcm_to_cpu(handle); ++ arch_dma_ops->sync_single_for_cpu(dev, handle, size, dir); ++} ++ ++static void brcm_sync_single_for_device(struct device *dev, ++ dma_addr_t handle, size_t size, ++ enum dma_data_direction dir) ++{ ++ handle = brcm_to_cpu(handle); ++ arch_dma_ops->sync_single_for_device(dev, handle, size, dir); ++} ++ ++static dma_addr_t brcm_map_resource(struct device *dev, phys_addr_t phys, ++ size_t size, ++ enum dma_data_direction dir, ++ unsigned long attrs) ++{ ++ if (arch_dma_ops->map_resource) ++ return brcm_to_pci(arch_dma_ops->map_resource ++ (dev, phys, size, dir, attrs)); ++ return brcm_to_pci((dma_addr_t)phys); ++} ++ ++static void brcm_unmap_resource(struct device *dev, dma_addr_t handle, ++ size_t size, enum dma_data_direction dir, ++ unsigned long attrs) ++{ ++ if (arch_dma_ops->unmap_resource) ++ arch_dma_ops->unmap_resource(dev, brcm_to_cpu(handle), size, ++ dir, attrs); ++} ++ ++void brcm_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl, ++ int nents, enum dma_data_direction dir) ++{ ++ struct scatterlist *sg; ++ int i; ++ ++ for_each_sg(sgl, sg, nents, i) ++ brcm_dma_ops_ptr->sync_single_for_cpu(dev, sg_dma_address(sg), ++ sg->length, dir); ++} ++ ++void brcm_sync_sg_for_device(struct device *dev, struct scatterlist *sgl, ++ int nents, enum dma_data_direction dir) ++{ ++ struct scatterlist *sg; ++ int i; ++ ++ for_each_sg(sgl, sg, nents, i) ++ brcm_dma_ops_ptr->sync_single_for_device(dev, ++ sg_dma_address(sg), ++ sg->length, dir); ++} ++ ++static int brcm_mapping_error(struct device *dev, dma_addr_t dma_addr) ++{ ++ return arch_dma_ops->mapping_error(dev, dma_addr); ++} ++ ++static int brcm_dma_supported(struct device *dev, u64 mask) ++{ ++ if (num_dma_ranges) { ++ /* ++ * It is our translated addresses that the EP will "see", so ++ * we check all of the ranges for the largest possible value. ++ */ ++ int i; ++ ++ for (i = 0; i < num_dma_ranges; i++) ++ if (dma_ranges[i].pci_addr + dma_ranges[i].size - 1 ++ > mask) ++ return 0; ++ return 1; ++ } ++ ++ return arch_dma_ops->dma_supported(dev, mask); ++} ++ ++#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK ++u64 brcm_get_required_mask)(struct device *dev) ++{ ++ return arch_dma_ops->get_required_mask(dev); ++} ++#endif ++ ++static const struct dma_map_ops brcm_dma_ops = { ++ .alloc = brcm_alloc, ++ .free = brcm_free, ++ .mmap = brcm_mmap, ++ .get_sgtable = brcm_get_sgtable, ++ .map_page = brcm_map_page, ++ .unmap_page = brcm_unmap_page, ++ .map_sg = brcm_map_sg, ++ .unmap_sg = brcm_unmap_sg, ++ .map_resource = brcm_map_resource, ++ .unmap_resource = brcm_unmap_resource, ++ .sync_single_for_cpu = brcm_sync_single_for_cpu, ++ .sync_single_for_device = brcm_sync_single_for_device, ++ .sync_sg_for_cpu = brcm_sync_sg_for_cpu, ++ .sync_sg_for_device = brcm_sync_sg_for_device, ++ .mapping_error = brcm_mapping_error, ++ .dma_supported = brcm_dma_supported, ++#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK ++ .get_required_mask = brcm_get_required_mask, ++#endif ++}; ++ ++static void brcm_set_dma_ops(struct device *dev) ++{ ++ int ret; ++ ++ if (IS_ENABLED(CONFIG_ARM64)) { ++ /* ++ * We are going to invoke get_dma_ops(). That ++ * function, at this point in time, invokes ++ * get_arch_dma_ops(), and for ARM64 that function ++ * returns a pointer to dummy_dma_ops. So then we'd ++ * like to call arch_setup_dma_ops(), but that isn't ++ * exported. Instead, we call of_dma_configure(), ++ * which is exported, and this calls ++ * arch_setup_dma_ops(). Once we do this the call to ++ * get_dma_ops() will work properly because ++ * dev->dma_ops will be set. ++ */ ++ ret = of_dma_configure(dev, dev->of_node, true); ++ if (ret) { ++ dev_err(dev, "of_dma_configure() failed: %d\n", ret); ++ return; ++ } ++ } ++ ++ arch_dma_ops = get_dma_ops(dev); ++ if (!arch_dma_ops) { ++ dev_err(dev, "failed to get arch_dma_ops\n"); ++ return; ++ } ++ ++ set_dma_ops(dev, &brcm_dma_ops); ++} ++ ++static int brcmstb_platform_notifier(struct notifier_block *nb, ++ unsigned long event, void *__dev) ++{ ++ struct device *dev = __dev; ++ ++ brcm_dma_ops_ptr = &brcm_dma_ops; ++ if (event != BUS_NOTIFY_ADD_DEVICE) ++ return NOTIFY_DONE; ++ ++ brcm_set_dma_ops(dev); ++ return NOTIFY_OK; ++} ++ ++static struct notifier_block brcmstb_platform_nb = { ++ .notifier_call = brcmstb_platform_notifier, ++}; ++ ++static int brcm_register_notifier(void) ++{ ++ return bus_register_notifier(&pci_bus_type, &brcmstb_platform_nb); ++} ++ ++static int brcm_unregister_notifier(void) ++{ ++ return bus_unregister_notifier(&pci_bus_type, &brcmstb_platform_nb); ++} ++ + static u32 rd_fld(void __iomem *p, u32 mask, int shift) + { + return (bcm_readl(p) & mask) >> shift; +@@ -597,9 +894,71 @@ static inline void brcm_pcie_perst_set(s + WR_FLD_RB(pcie->base, PCIE_MISC_PCIE_CTRL, PCIE_PERSTB, !val); + } + ++static int pci_dma_range_parser_init(struct of_pci_range_parser *parser, ++ struct device_node *node) ++{ ++ const int na = 3, ns = 2; ++ int rlen; ++ ++ parser->node = node; ++ parser->pna = of_n_addr_cells(node); ++ parser->np = parser->pna + na + ns; ++ ++ parser->range = of_get_property(node, "dma-ranges", &rlen); ++ if (!parser->range) ++ return -ENOENT; ++ ++ parser->end = parser->range + rlen / sizeof(__be32); ++ ++ return 0; ++} ++ ++static int brcm_pcie_parse_map_dma_ranges(struct brcm_pcie *pcie) ++{ ++ int i; ++ struct of_pci_range_parser parser; ++ struct device_node *dn = pcie->dn; ++ ++ /* ++ * Parse dma-ranges property if present. If there are multiple ++ * PCIe controllers, we only have to parse from one of them since ++ * the others will have an identical mapping. ++ */ ++ if (!pci_dma_range_parser_init(&parser, dn)) { ++ unsigned int max_ranges ++ = (parser.end - parser.range) / parser.np; ++ ++ dma_ranges = kcalloc(max_ranges, sizeof(struct of_pci_range), ++ GFP_KERNEL); ++ if (!dma_ranges) ++ return -ENOMEM; ++ ++ for (i = 0; of_pci_range_parser_one(&parser, dma_ranges + i); ++ i++) ++ num_dma_ranges++; ++ } ++ ++ for (i = 0, num_memc = 0; i < BRCM_MAX_SCB; i++) { ++ u64 size = brcmstb_memory_memc_size(i); ++ ++ if (size == (u64)-1) { ++ dev_err(pcie->dev, "cannot get memc%d size", i); ++ return -EINVAL; ++ } else if (size) { ++ scb_size[i] = roundup_pow_of_two_64(size); ++ num_memc++; ++ } else { ++ break; ++ } ++ } ++ ++ return 0; ++} ++ + static int brcm_pcie_add_controller(struct brcm_pcie *pcie) + { + int i, ret = 0; ++ struct device *dev = pcie->dev; + + mutex_lock(&brcm_pcie_lock); + if (num_pcie > 0) { +@@ -607,12 +966,21 @@ static int brcm_pcie_add_controller(stru + goto done; + } + ++ ret = brcm_register_notifier(); ++ if (ret) { ++ dev_err(dev, "failed to register pci bus notifier\n"); ++ goto done; ++ } ++ ret = brcm_pcie_parse_map_dma_ranges(pcie); ++ if (ret) ++ goto done; ++ + /* Determine num_memc and their sizes */ + for (i = 0, num_memc = 0; i < BRCM_MAX_SCB; i++) { + u64 size = brcmstb_memory_memc_size(i); + + if (size == (u64)-1) { +- dev_err(pcie->dev, "cannot get memc%d size\n", i); ++ dev_err(dev, "cannot get memc%d size\n", i); + ret = -EINVAL; + goto done; + } else if (size) { +@@ -636,8 +1004,16 @@ done: + static void brcm_pcie_remove_controller(struct brcm_pcie *pcie) + { + mutex_lock(&brcm_pcie_lock); +- if (--num_pcie == 0) +- num_memc = 0; ++ if (--num_pcie > 0) ++ goto out; ++ ++ if (brcm_unregister_notifier()) ++ dev_err(pcie->dev, "failed to unregister pci bus notifier\n"); ++ kfree(dma_ranges); ++ dma_ranges = NULL; ++ num_dma_ranges = 0; ++ num_memc = 0; ++out: + mutex_unlock(&brcm_pcie_lock); + } + +@@ -757,6 +1133,38 @@ static int brcm_pcie_setup(struct brcm_p + */ + rc_bar2_offset = 0; + ++ if (dma_ranges) { ++ /* ++ * The best-case scenario is to place the inbound ++ * region in the first 4GB of pci-space, as some ++ * legacy devices can only address 32bits. ++ * We would also like to put the MSI under 4GB ++ * as well, since some devices require a 32bit ++ * MSI target address. ++ */ ++ if (total_mem_size <= 0xc0000000ULL && ++ rc_bar2_size <= 0x100000000ULL) { ++ rc_bar2_offset = 0; ++ } else { ++ /* ++ * The system memory is 4GB or larger so we ++ * cannot start the inbound region at location ++ * 0 (since we have to allow some space for ++ * outbound memory @ 3GB). So instead we ++ * start it at the 1x multiple of its size ++ */ ++ rc_bar2_offset = rc_bar2_size; ++ } ++ ++ } else { ++ /* ++ * Set simple configuration based on memory sizes ++ * only. We always start the viewport at address 0, ++ * and set the MSI target address accordingly. ++ */ ++ rc_bar2_offset = 0; ++ } ++ + tmp = lower_32_bits(rc_bar2_offset); + tmp = INSERT_FIELD(tmp, PCIE_MISC_RC_BAR2_CONFIG_LO, SIZE, + encode_ibar_size(rc_bar2_size)); +@@ -967,7 +1375,6 @@ static int brcm_pcie_probe(struct platfo + struct brcm_pcie *pcie; + struct resource *res; + void __iomem *base; +- u32 tmp; + struct pci_host_bridge *bridge; + struct pci_bus *child; + +@@ -984,11 +1391,6 @@ static int brcm_pcie_probe(struct platfo + return -EINVAL; + } + +- if (of_property_read_u32(dn, "dma-ranges", &tmp) == 0) { +- dev_err(&pdev->dev, "cannot yet handle dma-ranges\n"); +- return -EINVAL; +- } +- + data = of_id->data; + pcie->reg_offsets = data->offsets; + pcie->reg_field_info = data->reg_field_info; diff --git a/target/linux/brcm2708/patches-4.19/950-0532-PCI-brcmstb-Add-MSI-capability.patch b/target/linux/brcm2708/patches-4.19/950-0532-PCI-brcmstb-Add-MSI-capability.patch new file mode 100644 index 0000000000..63985cab8b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0532-PCI-brcmstb-Add-MSI-capability.patch @@ -0,0 +1,543 @@ +From 2f802e11ea7ca4f7c688ecc64019bec25a5e62a1 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 19 Feb 2019 22:06:59 +0000 +Subject: [PATCH 532/725] PCI: brcmstb: Add MSI capability + +This commit adds MSI to the Broadcom STB PCIe host controller. It does +not add MSIX since that functionality is not in the HW. The MSI +controller is physically located within the PCIe block, however, there +is no reason why the MSI controller could not be moved elsewhere in +the future. + +Since the internal Brcmstb MSI controller is intertwined with the PCIe +controller, it is not its own platform device but rather part of the +PCIe platform device. + +Signed-off-by: Jim Quinlan +--- + drivers/pci/controller/pcie-brcmstb.c | 374 ++++++++++++++++++++++++-- + 1 file changed, 353 insertions(+), 21 deletions(-) + +--- a/drivers/pci/controller/pcie-brcmstb.c ++++ b/drivers/pci/controller/pcie-brcmstb.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + /* Copyright (C) 2009 - 2017 Broadcom */ + ++#include + #include + #include + #include +@@ -9,11 +10,13 @@ + #include + #include + #include ++#include + #include + #include + #include + #include + #include ++#include + #include + #include + #include +@@ -47,6 +50,9 @@ + #define PCIE_MISC_RC_BAR2_CONFIG_LO 0x4034 + #define PCIE_MISC_RC_BAR2_CONFIG_HI 0x4038 + #define PCIE_MISC_RC_BAR3_CONFIG_LO 0x403c ++#define PCIE_MISC_MSI_BAR_CONFIG_LO 0x4044 ++#define PCIE_MISC_MSI_BAR_CONFIG_HI 0x4048 ++#define PCIE_MISC_MSI_DATA_CONFIG 0x404c + #define PCIE_MISC_PCIE_CTRL 0x4064 + #define PCIE_MISC_PCIE_STATUS 0x4068 + #define PCIE_MISC_REVISION 0x406c +@@ -55,6 +61,7 @@ + #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI 0x4084 + #define PCIE_MISC_HARD_PCIE_HARD_DEBUG 0x4204 + #define PCIE_INTR2_CPU_BASE 0x4300 ++#define PCIE_MSI_INTR2_BASE 0x4500 + + /* + * Broadcom Settop Box PCIe Register Field shift and mask info. The +@@ -115,6 +122,8 @@ + + #define BRCM_NUM_PCIE_OUT_WINS 0x4 + #define BRCM_MAX_SCB 0x4 ++#define BRCM_INT_PCI_MSI_NR 32 ++#define BRCM_PCIE_HW_REV_33 0x0303 + + #define BRCM_MSI_TARGET_ADDR_LT_4GB 0x0fffffffcULL + #define BRCM_MSI_TARGET_ADDR_GT_4GB 0xffffffffcULL +@@ -203,6 +212,33 @@ struct brcm_window { + dma_addr_t size; + }; + ++struct brcm_msi { ++ struct device *dev; ++ void __iomem *base; ++ struct device_node *dn; ++ struct irq_domain *msi_domain; ++ struct irq_domain *inner_domain; ++ struct mutex lock; /* guards the alloc/free operations */ ++ u64 target_addr; ++ int irq; ++ ++ /* intr_base is the base pointer for interrupt status/set/clr regs */ ++ void __iomem *intr_base; ++ ++ /* intr_legacy_mask indicates how many bits are MSI interrupts */ ++ u32 intr_legacy_mask; ++ ++ /* ++ * intr_legacy_offset indicates bit position of MSI_01. It is ++ * to map the register bit position to a hwirq that starts at 0. ++ */ ++ u32 intr_legacy_offset; ++ ++ /* used indicates which MSI interrupts have been alloc'd */ ++ unsigned long used; ++ unsigned int rev; ++}; ++ + /* Internal PCIe Host Controller Information.*/ + struct brcm_pcie { + struct device *dev; +@@ -217,7 +253,10 @@ struct brcm_pcie { + int num_out_wins; + bool ssc; + int gen; ++ u64 msi_target_addr; + struct brcm_window out_wins[BRCM_NUM_PCIE_OUT_WINS]; ++ struct brcm_msi *msi; ++ bool msi_internal; + unsigned int rev; + const int *reg_offsets; + const int *reg_field_info; +@@ -225,9 +264,9 @@ struct brcm_pcie { + }; + + struct pcie_cfg_data { +- const int *reg_field_info; +- const int *offsets; +- const enum pcie_type type; ++ const int *reg_field_info; ++ const int *offsets; ++ const enum pcie_type type; + }; + + static const int pcie_reg_field_info[] = { +@@ -828,6 +867,267 @@ static void brcm_pcie_set_outbound_win(s + } + } + ++static struct irq_chip brcm_msi_irq_chip = { ++ .name = "Brcm_MSI", ++ .irq_mask = pci_msi_mask_irq, ++ .irq_unmask = pci_msi_unmask_irq, ++}; ++ ++static struct msi_domain_info brcm_msi_domain_info = { ++ .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | ++ MSI_FLAG_PCI_MSIX), ++ .chip = &brcm_msi_irq_chip, ++}; ++ ++static void brcm_pcie_msi_isr(struct irq_desc *desc) ++{ ++ struct irq_chip *chip = irq_desc_get_chip(desc); ++ struct brcm_msi *msi; ++ unsigned long status, virq; ++ u32 mask, bit, hwirq; ++ struct device *dev; ++ ++ chained_irq_enter(chip, desc); ++ msi = irq_desc_get_handler_data(desc); ++ mask = msi->intr_legacy_mask; ++ dev = msi->dev; ++ ++ while ((status = bcm_readl(msi->intr_base + STATUS) & mask)) { ++ for_each_set_bit(bit, &status, BRCM_INT_PCI_MSI_NR) { ++ /* clear the interrupt */ ++ bcm_writel(1 << bit, msi->intr_base + CLR); ++ ++ /* Account for legacy interrupt offset */ ++ hwirq = bit - msi->intr_legacy_offset; ++ ++ virq = irq_find_mapping(msi->inner_domain, hwirq); ++ if (virq) { ++ if (msi->used & (1 << hwirq)) ++ generic_handle_irq(virq); ++ else ++ dev_info(dev, "unhandled MSI %d\n", ++ hwirq); ++ } else { ++ /* Unknown MSI, just clear it */ ++ dev_dbg(dev, "unexpected MSI\n"); ++ } ++ } ++ } ++ chained_irq_exit(chip, desc); ++} ++ ++static void brcm_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) ++{ ++ struct brcm_msi *msi = irq_data_get_irq_chip_data(data); ++ u32 temp; ++ ++ msg->address_lo = lower_32_bits(msi->target_addr); ++ msg->address_hi = upper_32_bits(msi->target_addr); ++ temp = bcm_readl(msi->base + PCIE_MISC_MSI_DATA_CONFIG); ++ msg->data = ((temp >> 16) & (temp & 0xffff)) | data->hwirq; ++} ++ ++static int brcm_msi_set_affinity(struct irq_data *irq_data, ++ const struct cpumask *mask, bool force) ++{ ++ return -EINVAL; ++} ++ ++static struct irq_chip brcm_msi_bottom_irq_chip = { ++ .name = "Brcm_MSI", ++ .irq_compose_msi_msg = brcm_compose_msi_msg, ++ .irq_set_affinity = brcm_msi_set_affinity, ++}; ++ ++static int brcm_msi_alloc(struct brcm_msi *msi) ++{ ++ int bit, hwirq; ++ ++ mutex_lock(&msi->lock); ++ bit = ~msi->used ? ffz(msi->used) : -1; ++ ++ if (bit >= 0 && bit < BRCM_INT_PCI_MSI_NR) { ++ msi->used |= (1 << bit); ++ hwirq = bit - msi->intr_legacy_offset; ++ } else { ++ hwirq = -ENOSPC; ++ } ++ ++ mutex_unlock(&msi->lock); ++ return hwirq; ++} ++ ++static void brcm_msi_free(struct brcm_msi *msi, unsigned long hwirq) ++{ ++ mutex_lock(&msi->lock); ++ msi->used &= ~(1 << (hwirq + msi->intr_legacy_offset)); ++ mutex_unlock(&msi->lock); ++} ++ ++static int brcm_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, ++ unsigned int nr_irqs, void *args) ++{ ++ struct brcm_msi *msi = domain->host_data; ++ int hwirq; ++ ++ hwirq = brcm_msi_alloc(msi); ++ ++ if (hwirq < 0) ++ return hwirq; ++ ++ irq_domain_set_info(domain, virq, (irq_hw_number_t)hwirq, ++ &brcm_msi_bottom_irq_chip, domain->host_data, ++ handle_simple_irq, NULL, NULL); ++ return 0; ++} ++ ++static void brcm_irq_domain_free(struct irq_domain *domain, ++ unsigned int virq, unsigned int nr_irqs) ++{ ++ struct irq_data *d = irq_domain_get_irq_data(domain, virq); ++ struct brcm_msi *msi = irq_data_get_irq_chip_data(d); ++ ++ brcm_msi_free(msi, d->hwirq); ++} ++ ++static void brcm_msi_set_regs(struct brcm_msi *msi) ++{ ++ u32 data_val, msi_lo, msi_hi; ++ ++ if (msi->rev >= BRCM_PCIE_HW_REV_33) { ++ /* ++ * ffe0 -- least sig 5 bits are 0 indicating 32 msgs ++ * 6540 -- this is our arbitrary unique data value ++ */ ++ data_val = 0xffe06540; ++ } else { ++ /* ++ * fff8 -- least sig 3 bits are 0 indicating 8 msgs ++ * 6540 -- this is our arbitrary unique data value ++ */ ++ data_val = 0xfff86540; ++ } ++ ++ /* ++ * Make sure we are not masking MSIs. Note that MSIs can be masked, ++ * but that occurs on the PCIe EP device ++ */ ++ bcm_writel(0xffffffff & msi->intr_legacy_mask, ++ msi->intr_base + MASK_CLR); ++ ++ msi_lo = lower_32_bits(msi->target_addr); ++ msi_hi = upper_32_bits(msi->target_addr); ++ /* ++ * The 0 bit of PCIE_MISC_MSI_BAR_CONFIG_LO is repurposed to MSI ++ * enable, which we set to 1. ++ */ ++ bcm_writel(msi_lo | 1, msi->base + PCIE_MISC_MSI_BAR_CONFIG_LO); ++ bcm_writel(msi_hi, msi->base + PCIE_MISC_MSI_BAR_CONFIG_HI); ++ bcm_writel(data_val, msi->base + PCIE_MISC_MSI_DATA_CONFIG); ++} ++ ++static const struct irq_domain_ops msi_domain_ops = { ++ .alloc = brcm_irq_domain_alloc, ++ .free = brcm_irq_domain_free, ++}; ++ ++static int brcm_allocate_domains(struct brcm_msi *msi) ++{ ++ struct fwnode_handle *fwnode = of_node_to_fwnode(msi->dn); ++ struct device *dev = msi->dev; ++ ++ msi->inner_domain = irq_domain_add_linear(NULL, BRCM_INT_PCI_MSI_NR, ++ &msi_domain_ops, msi); ++ if (!msi->inner_domain) { ++ dev_err(dev, "failed to create IRQ domain\n"); ++ return -ENOMEM; ++ } ++ ++ msi->msi_domain = pci_msi_create_irq_domain(fwnode, ++ &brcm_msi_domain_info, ++ msi->inner_domain); ++ if (!msi->msi_domain) { ++ dev_err(dev, "failed to create MSI domain\n"); ++ irq_domain_remove(msi->inner_domain); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++static void brcm_free_domains(struct brcm_msi *msi) ++{ ++ irq_domain_remove(msi->msi_domain); ++ irq_domain_remove(msi->inner_domain); ++} ++ ++static void brcm_msi_remove(struct brcm_pcie *pcie) ++{ ++ struct brcm_msi *msi = pcie->msi; ++ ++ if (!msi) ++ return; ++ irq_set_chained_handler(msi->irq, NULL); ++ irq_set_handler_data(msi->irq, NULL); ++ brcm_free_domains(msi); ++} ++ ++static int brcm_pcie_enable_msi(struct brcm_pcie *pcie) ++{ ++ struct brcm_msi *msi; ++ int irq, ret; ++ struct device *dev = pcie->dev; ++ ++ irq = irq_of_parse_and_map(dev->of_node, 1); ++ if (irq <= 0) { ++ dev_err(dev, "cannot map msi intr\n"); ++ return -ENODEV; ++ } ++ ++ msi = devm_kzalloc(dev, sizeof(struct brcm_msi), GFP_KERNEL); ++ if (!msi) ++ return -ENOMEM; ++ ++ msi->dev = dev; ++ msi->base = pcie->base; ++ msi->rev = pcie->rev; ++ msi->dn = pcie->dn; ++ msi->target_addr = pcie->msi_target_addr; ++ msi->irq = irq; ++ ++ ret = brcm_allocate_domains(msi); ++ if (ret) ++ return ret; ++ ++ irq_set_chained_handler_and_data(msi->irq, brcm_pcie_msi_isr, msi); ++ ++ if (msi->rev >= BRCM_PCIE_HW_REV_33) { ++ msi->intr_base = msi->base + PCIE_MSI_INTR2_BASE; ++ /* ++ * This version of PCIe hw has only 32 intr bits ++ * starting at bit position 0. ++ */ ++ msi->intr_legacy_mask = 0xffffffff; ++ msi->intr_legacy_offset = 0x0; ++ msi->used = 0x0; ++ ++ } else { ++ msi->intr_base = msi->base + PCIE_INTR2_CPU_BASE; ++ /* ++ * This version of PCIe hw has only 8 intr bits starting ++ * at bit position 24. ++ */ ++ msi->intr_legacy_mask = 0xff000000; ++ msi->intr_legacy_offset = 24; ++ msi->used = 0x00ffffff; ++ } ++ ++ brcm_msi_set_regs(msi); ++ pcie->msi = msi; ++ ++ return 0; ++} ++ + /* Configuration space read/write support */ + static int cfg_index(int busnr, int devfn, int reg) + { +@@ -1072,6 +1372,7 @@ static int brcm_pcie_setup(struct brcm_p + u16 nlw, cls, lnksta; + bool ssc_good = false; + struct device *dev = pcie->dev; ++ u64 msi_target_addr; + + /* Reset the bridge */ + brcm_pcie_bridge_sw_init_set(pcie, 1); +@@ -1116,27 +1417,24 @@ static int brcm_pcie_setup(struct brcm_p + * The PCIe host controller by design must set the inbound + * viewport to be a contiguous arrangement of all of the + * system's memory. In addition, its size mut be a power of +- * two. To further complicate matters, the viewport must +- * start on a pcie-address that is aligned on a multiple of its +- * size. If a portion of the viewport does not represent +- * system memory -- e.g. 3GB of memory requires a 4GB viewport +- * -- we can map the outbound memory in or after 3GB and even +- * though the viewport will overlap the outbound memory the +- * controller will know to send outbound memory downstream and +- * everything else upstream. ++ * two. Further, the MSI target address must NOT be placed ++ * inside this region, as the decoding logic will consider its ++ * address to be inbound memory traffic. To further ++ * complicate matters, the viewport must start on a ++ * pcie-address that is aligned on a multiple of its size. ++ * If a portion of the viewport does not represent system ++ * memory -- e.g. 3GB of memory requires a 4GB viewport -- ++ * we can map the outbound memory in or after 3GB and even ++ * though the viewport will overlap the outbound memory ++ * the controller will know to send outbound memory downstream ++ * and everything else upstream. + */ + rc_bar2_size = roundup_pow_of_two_64(total_mem_size); + +- /* +- * Set simple configuration based on memory sizes +- * only. We always start the viewport at address 0. +- */ +- rc_bar2_offset = 0; +- + if (dma_ranges) { + /* + * The best-case scenario is to place the inbound +- * region in the first 4GB of pci-space, as some ++ * region in the first 4GB of pcie-space, as some + * legacy devices can only address 32bits. + * We would also like to put the MSI under 4GB + * as well, since some devices require a 32bit +@@ -1145,6 +1443,14 @@ static int brcm_pcie_setup(struct brcm_p + if (total_mem_size <= 0xc0000000ULL && + rc_bar2_size <= 0x100000000ULL) { + rc_bar2_offset = 0; ++ /* If the viewport is less then 4GB we can fit ++ * the MSI target address under 4GB. Otherwise ++ * put it right below 64GB. ++ */ ++ msi_target_addr = ++ (rc_bar2_size == 0x100000000ULL) ++ ? BRCM_MSI_TARGET_ADDR_GT_4GB ++ : BRCM_MSI_TARGET_ADDR_LT_4GB; + } else { + /* + * The system memory is 4GB or larger so we +@@ -1154,8 +1460,12 @@ static int brcm_pcie_setup(struct brcm_p + * start it at the 1x multiple of its size + */ + rc_bar2_offset = rc_bar2_size; +- } + ++ /* Since we are starting the viewport at 4GB or ++ * higher, put the MSI target address below 4GB ++ */ ++ msi_target_addr = BRCM_MSI_TARGET_ADDR_LT_4GB; ++ } + } else { + /* + * Set simple configuration based on memory sizes +@@ -1163,7 +1473,12 @@ static int brcm_pcie_setup(struct brcm_p + * and set the MSI target address accordingly. + */ + rc_bar2_offset = 0; ++ ++ msi_target_addr = (rc_bar2_size >= 0x100000000ULL) ++ ? BRCM_MSI_TARGET_ADDR_GT_4GB ++ : BRCM_MSI_TARGET_ADDR_LT_4GB; + } ++ pcie->msi_target_addr = msi_target_addr; + + tmp = lower_32_bits(rc_bar2_offset); + tmp = INSERT_FIELD(tmp, PCIE_MISC_RC_BAR2_CONFIG_LO, SIZE, +@@ -1333,6 +1648,9 @@ static int brcm_pcie_resume(struct devic + if (ret) + return ret; + ++ if (pcie->msi && pcie->msi_internal) ++ brcm_msi_set_regs(pcie->msi); ++ + pcie->suspended = false; + + return 0; +@@ -1340,6 +1658,7 @@ static int brcm_pcie_resume(struct devic + + static void _brcm_pcie_remove(struct brcm_pcie *pcie) + { ++ brcm_msi_remove(pcie); + turn_off(pcie); + clk_disable_unprepare(pcie->clk); + clk_put(pcie->clk); +@@ -1368,7 +1687,7 @@ MODULE_DEVICE_TABLE(of, brcm_pcie_match) + + static int brcm_pcie_probe(struct platform_device *pdev) + { +- struct device_node *dn = pdev->dev.of_node; ++ struct device_node *dn = pdev->dev.of_node, *msi_dn; + const struct of_device_id *of_id; + const struct pcie_cfg_data *data; + int ret; +@@ -1448,6 +1767,20 @@ static int brcm_pcie_probe(struct platfo + if (ret) + goto fail; + ++ msi_dn = of_parse_phandle(pcie->dn, "msi-parent", 0); ++ /* Use the internal MSI if no msi-parent property */ ++ if (!msi_dn) ++ msi_dn = pcie->dn; ++ ++ if (pci_msi_enabled() && msi_dn == pcie->dn) { ++ ret = brcm_pcie_enable_msi(pcie); ++ if (ret) ++ dev_err(pcie->dev, ++ "probe of internal MSI failed: %d)", ret); ++ else ++ pcie->msi_internal = true; ++ } ++ + list_splice_init(&pcie->resources, &bridge->windows); + bridge->dev.parent = &pdev->dev; + bridge->busnr = 0; +@@ -1470,7 +1803,6 @@ static int brcm_pcie_probe(struct platfo + pcie->root_bus = bridge->bus; + + return 0; +- + fail: + _brcm_pcie_remove(pcie); + return ret; diff --git a/target/linux/brcm2708/patches-4.19/950-0532-arm-bcm2835-Fix-FIQ-early-ioremap.patch b/target/linux/brcm2708/patches-4.19/950-0532-arm-bcm2835-Fix-FIQ-early-ioremap.patch deleted file mode 100644 index 7acf9d9537..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0532-arm-bcm2835-Fix-FIQ-early-ioremap.patch +++ /dev/null @@ -1,73 +0,0 @@ -From bd1c6d07ec4b1ddf087ad139c0164ab195244a55 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 20 Feb 2019 08:49:39 +0000 -Subject: [PATCH 532/703] arm: bcm2835: Fix FIQ early ioremap - -The ioremapping creates mappings within the vmalloc area. The -equivalent early function, create_mapping, now checks that the -requested explicit virtual address is between VMALLOC_START and -VMALLOC_END. As there is no reason to have any correlation between -the physical and virtual addresses, put the required mappings at -VMALLOC_START and above. - -Signed-off-by: Phil Elwell ---- - arch/arm/mach-bcm/board_bcm2835.c | 21 +++++++++++++++------ - 1 file changed, 15 insertions(+), 6 deletions(-) - ---- a/arch/arm/mach-bcm/board_bcm2835.c -+++ b/arch/arm/mach-bcm/board_bcm2835.c -@@ -14,17 +14,20 @@ - - #include - #include -+#include - #include - #include - #include - - #include - #include -+#include -+#include - - #include "platsmp.h" - --#define BCM2835_USB_VIRT_BASE 0xf0980000 --#define BCM2835_USB_VIRT_MPHI 0xf0006000 -+#define BCM2835_USB_VIRT_BASE (VMALLOC_START) -+#define BCM2835_USB_VIRT_MPHI (VMALLOC_START + 0x10000) - - static void __init bcm2835_init(void) - { -@@ -83,20 +86,26 @@ static int __init bcm2835_map_usb(unsign - - static void __init bcm2835_map_io(void) - { -- const __be32 *ranges; -+ const __be32 *ranges, *address_cells; -+ unsigned long root, addr_cells; - int soc, len; - unsigned long p2b_offset; - - debug_ll_io_init(); - -+ root = of_get_flat_dt_root(); - /* Find out how to map bus to physical address first from soc/ranges */ -- soc = of_get_flat_dt_subnode_by_name(of_get_flat_dt_root(), "soc"); -+ soc = of_get_flat_dt_subnode_by_name(root, "soc"); - if (soc < 0) - return; -+ address_cells = of_get_flat_dt_prop(root, "#address-cells", &len); -+ if (!address_cells || len < (sizeof(unsigned long))) -+ return; -+ addr_cells = be32_to_cpu(address_cells[0]); - ranges = of_get_flat_dt_prop(soc, "ranges", &len); -- if (!ranges || len < (sizeof(unsigned long) * 3)) -+ if (!ranges || len < (sizeof(unsigned long) * (2 + addr_cells))) - return; -- p2b_offset = be32_to_cpu(ranges[0]) - be32_to_cpu(ranges[1]); -+ p2b_offset = be32_to_cpu(ranges[0]) - be32_to_cpu(ranges[addr_cells]); - - /* Now search for bcm2708-usb node in device tree */ - of_scan_flat_dt(bcm2835_map_usb, &p2b_offset); diff --git a/target/linux/brcm2708/patches-4.19/950-0533-Fix-copy_from_user-if-BCM2835_FAST_MEMCPY-n.patch b/target/linux/brcm2708/patches-4.19/950-0533-Fix-copy_from_user-if-BCM2835_FAST_MEMCPY-n.patch deleted file mode 100644 index 91c3fcd37b..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0533-Fix-copy_from_user-if-BCM2835_FAST_MEMCPY-n.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 1f1c37d795048414202d1b097854ebb78df4b1fe Mon Sep 17 00:00:00 2001 -From: Tim Gover -Date: Thu, 14 Mar 2019 10:16:02 +0000 -Subject: [PATCH 533/703] Fix copy_from_user if BCM2835_FAST_MEMCPY=n - -The change which introduced CONFIG_BCM2835_FAST_MEMCPY unconditionally -changed the behaviour of arm_copy_from_user. The page pinning code -is not safe on ARMv7 if LPAE & high memory is enabled and causes -crashes which look like PTE corruption. - -Make __copy_from_user_memcpy conditional on CONFIG_2835_FAST_MEMCPY=y -which is really an ARMv6 / Pi1 optimization and not necessary on newer -ARM processors. ---- - arch/arm/lib/uaccess_with_memcpy.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/arch/arm/lib/uaccess_with_memcpy.c -+++ b/arch/arm/lib/uaccess_with_memcpy.c -@@ -257,6 +257,7 @@ arm_copy_to_user(void __user *to, const - unsigned long __must_check - arm_copy_from_user(void *to, const void __user *from, unsigned long n) - { -+#ifdef CONFIG_BCM2835_FAST_MEMCPY - /* - * This test is stubbed out of the main function above to keep - * the overhead for small copies low by avoiding a large -@@ -271,6 +272,11 @@ arm_copy_from_user(void *to, const void - } else { - n = __copy_from_user_memcpy(to, from, n); - } -+#else -+ unsigned long ua_flags = uaccess_save_and_enable(); -+ n = __copy_from_user_std(to, from, n); -+ uaccess_restore(ua_flags); -+#endif - return n; - } - diff --git a/target/linux/brcm2708/patches-4.19/950-0533-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch b/target/linux/brcm2708/patches-4.19/950-0533-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch new file mode 100644 index 0000000000..8813757402 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0533-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch @@ -0,0 +1,77 @@ +From 830343693fac9c7aa58e6a14f636e75d2fb3b2e5 Mon Sep 17 00:00:00 2001 +From: Jim Quinlan +Date: Mon, 15 Jan 2018 18:28:39 -0500 +Subject: [PATCH 533/725] dt-bindings: pci: Add DT docs for Brcmstb PCIe device + +The DT bindings description of the Brcmstb PCIe device is described. This +node can be used by almost all Broadcom settop box chips, using +ARM, ARM64, or MIPS CPU architectures. + +Signed-off-by: Jim Quinlan +--- + .../devicetree/bindings/pci/brcmstb-pcie.txt | 59 +++++++++++++++++++ + 1 file changed, 59 insertions(+) + create mode 100644 Documentation/devicetree/bindings/pci/brcmstb-pcie.txt + +--- /dev/null ++++ b/Documentation/devicetree/bindings/pci/brcmstb-pcie.txt +@@ -0,0 +1,59 @@ ++Brcmstb PCIe Host Controller Device Tree Bindings ++ ++Required Properties: ++- compatible ++ "brcm,bcm7425-pcie" -- for 7425 family MIPS-based SOCs. ++ "brcm,bcm7435-pcie" -- for 7435 family MIPS-based SOCs. ++ "brcm,bcm7445-pcie" -- for 7445 and later ARM based SOCs (not including ++ the 7278). ++ "brcm,bcm7278-pcie" -- for 7278 family ARM-based SOCs. ++ ++- reg -- the register start address and length for the PCIe reg block. ++- interrupts -- two interrupts are specified; the first interrupt is for ++ the PCI host controller and the second is for MSI if the built-in ++ MSI controller is to be used. ++- interrupt-names -- names of the interrupts (above): "pcie" and "msi". ++- #address-cells -- set to <3>. ++- #size-cells -- set to <2>. ++- #interrupt-cells: set to <1>. ++- interrupt-map-mask and interrupt-map, standard PCI properties to define the ++ mapping of the PCIe interface to interrupt numbers. ++- ranges: ranges for the PCI memory and I/O regions. ++- linux,pci-domain -- should be unique per host controller. ++ ++Optional Properties: ++- clocks -- phandle of pcie clock. ++- clock-names -- set to "sw_pcie" if clocks is used. ++- dma-ranges -- Specifies the inbound memory mapping regions when ++ an "identity map" is not possible. ++- msi-controller -- this property is typically specified to have the ++ PCIe controller use its internal MSI controller. ++- msi-parent -- set to use an external MSI interrupt controller. ++- brcm,enable-ssc -- (boolean) indicates usage of spread-spectrum clocking. ++- max-link-speed -- (integer) indicates desired generation of link: ++ 1 => 2.5 Gbps (gen1), 2 => 5.0 Gbps (gen2), 3 => 8.0 Gbps (gen3). ++ ++Example Node: ++ ++pcie0: pcie@f0460000 { ++ reg = <0x0 0xf0460000 0x0 0x9310>; ++ interrupts = <0x0 0x0 0x4>; ++ compatible = "brcm,bcm7445-pcie"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ ranges = <0x02000000 0x00000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x08000000 ++ 0x02000000 0x00000000 0x08000000 0x00000000 0xc8000000 0x00000000 0x08000000>; ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 7>; ++ interrupt-map = <0 0 0 1 &intc 0 47 3 ++ 0 0 0 2 &intc 0 48 3 ++ 0 0 0 3 &intc 0 49 3 ++ 0 0 0 4 &intc 0 50 3>; ++ clocks = <&sw_pcie0>; ++ clock-names = "sw_pcie"; ++ msi-parent = <&pcie0>; /* use PCIe's internal MSI controller */ ++ msi-controller; /* use PCIe's internal MSI controller */ ++ brcm,ssc; ++ max-link-speed = <1>; ++ linux,pci-domain = <0>; ++ }; diff --git a/target/linux/brcm2708/patches-4.19/950-0534-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch b/target/linux/brcm2708/patches-4.19/950-0534-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch deleted file mode 100644 index 536bc32fe4..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0534-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch +++ /dev/null @@ -1,1187 +0,0 @@ -From f44f216d79d668049e28f696840c7761017e3406 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 19 Feb 2019 22:06:59 +0000 -Subject: [PATCH 534/703] PCI: brcmstb: Add Broadcom STB PCIe host controller - driver - -This commit adds the basic Broadcom STB PCIe controller. Missing is -the ability to process MSI and also handle dma-ranges for inbound -memory accesses. These two functionalities are added in subsequent -commits. - -The PCIe block contains an MDIO interface. This is a local interface -only accessible by the PCIe controller. It cannot be used or shared -by any other HW. As such, the small amount of code for this -controller is included in this driver as there is little upside to put -it elsewhere. - -Signed-off-by: Jim Quinlan ---- - drivers/pci/controller/Kconfig | 9 + - drivers/pci/controller/Makefile | 2 +- - drivers/pci/controller/pcie-brcmstb.c | 1097 +++++++++++++++++++++++++ - include/soc/brcmstb/memory_api.h | 25 + - 4 files changed, 1132 insertions(+), 1 deletion(-) - create mode 100644 drivers/pci/controller/pcie-brcmstb.c - create mode 100644 include/soc/brcmstb/memory_api.h - ---- a/drivers/pci/controller/Kconfig -+++ b/drivers/pci/controller/Kconfig -@@ -278,5 +278,14 @@ config VMD - To compile this driver as a module, choose M here: the - module will be called vmd. - -+config PCIE_BRCMSTB -+ tristate "Broadcom Brcmstb PCIe platform host driver" -+ depends on ARCH_BRCMSTB || BMIPS_GENERIC -+ depends on OF -+ depends on SOC_BRCMSTB -+ default ARCH_BRCMSTB || BMIPS_GENERIC -+ help -+ Adds support for Broadcom Settop Box PCIe host controller. -+ - source "drivers/pci/controller/dwc/Kconfig" - endmenu ---- a/drivers/pci/controller/Makefile -+++ b/drivers/pci/controller/Makefile -@@ -28,11 +28,11 @@ obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcie - obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o - obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o - obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o -+obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o - obj-$(CONFIG_VMD) += vmd.o - # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW - obj-y += dwc/ - -- - # The following drivers are for devices that use the generic ACPI - # pci_root.c driver but don't support standard ECAM config access. - # They contain MCFG quirks to replace the generic ECAM accessors with ---- /dev/null -+++ b/drivers/pci/controller/pcie-brcmstb.c -@@ -0,0 +1,1097 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* Copyright (C) 2009 - 2017 Broadcom */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "../pci.h" -+ -+/* BRCM_PCIE_CAP_REGS - Offset for the mandatory capability config regs */ -+#define BRCM_PCIE_CAP_REGS 0x00ac -+ -+/* -+ * Broadcom Settop Box PCIe Register Offsets. The names are from -+ * the chip's RDB and we use them here so that a script can correlate -+ * this code and the RDB to prevent discrepancies. -+ */ -+#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1 0x0188 -+#define PCIE_RC_CFG_PRIV1_ID_VAL3 0x043c -+#define PCIE_RC_DL_MDIO_ADDR 0x1100 -+#define PCIE_RC_DL_MDIO_WR_DATA 0x1104 -+#define PCIE_RC_DL_MDIO_RD_DATA 0x1108 -+#define PCIE_MISC_MISC_CTRL 0x4008 -+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO 0x400c -+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI 0x4010 -+#define PCIE_MISC_RC_BAR1_CONFIG_LO 0x402c -+#define PCIE_MISC_RC_BAR2_CONFIG_LO 0x4034 -+#define PCIE_MISC_RC_BAR2_CONFIG_HI 0x4038 -+#define PCIE_MISC_RC_BAR3_CONFIG_LO 0x403c -+#define PCIE_MISC_PCIE_CTRL 0x4064 -+#define PCIE_MISC_PCIE_STATUS 0x4068 -+#define PCIE_MISC_REVISION 0x406c -+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT 0x4070 -+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI 0x4080 -+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI 0x4084 -+#define PCIE_MISC_HARD_PCIE_HARD_DEBUG 0x4204 -+#define PCIE_INTR2_CPU_BASE 0x4300 -+ -+/* -+ * Broadcom Settop Box PCIe Register Field shift and mask info. The -+ * names are from the chip's RDB and we use them here so that a script -+ * can correlate this code and the RDB to prevent discrepancies. -+ */ -+#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK 0xc -+#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_SHIFT 0x2 -+#define PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK 0xffffff -+#define PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_SHIFT 0x0 -+#define PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK 0x1000 -+#define PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_SHIFT 0xc -+#define PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK 0x2000 -+#define PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_SHIFT 0xd -+#define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK 0x300000 -+#define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_SHIFT 0x14 -+#define PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK 0xf8000000 -+#define PCIE_MISC_MISC_CTRL_SCB0_SIZE_SHIFT 0x1b -+#define PCIE_MISC_MISC_CTRL_SCB1_SIZE_MASK 0x7c00000 -+#define PCIE_MISC_MISC_CTRL_SCB1_SIZE_SHIFT 0x16 -+#define PCIE_MISC_MISC_CTRL_SCB2_SIZE_MASK 0x1f -+#define PCIE_MISC_MISC_CTRL_SCB2_SIZE_SHIFT 0x0 -+#define PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_MASK 0x1f -+#define PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_SHIFT 0x0 -+#define PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_MASK 0x1f -+#define PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_SHIFT 0x0 -+#define PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK 0x1f -+#define PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_SHIFT 0x0 -+#define PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_MASK 0x4 -+#define PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_SHIFT 0x2 -+#define PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_MASK 0x1 -+#define PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_SHIFT 0x0 -+#define PCIE_MISC_PCIE_STATUS_PCIE_PORT_MASK 0x80 -+#define PCIE_MISC_PCIE_STATUS_PCIE_PORT_SHIFT 0x7 -+#define PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK 0x20 -+#define PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_SHIFT 0x5 -+#define PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK 0x10 -+#define PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_SHIFT 0x4 -+#define PCIE_MISC_PCIE_STATUS_PCIE_LINK_IN_L23_MASK 0x40 -+#define PCIE_MISC_PCIE_STATUS_PCIE_LINK_IN_L23_SHIFT 0x6 -+#define PCIE_MISC_REVISION_MAJMIN_MASK 0xffff -+#define PCIE_MISC_REVISION_MAJMIN_SHIFT 0 -+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK 0xfff00000 -+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_SHIFT 0x14 -+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK 0xfff0 -+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_SHIFT 0x4 -+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_NUM_MASK_BITS 0xc -+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_MASK 0xff -+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_SHIFT 0x0 -+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK 0xff -+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_SHIFT 0x0 -+#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2 -+#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_SHIFT 0x1 -+#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000 -+#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_SHIFT 0x1b -+#define PCIE_RGR1_SW_INIT_1_PERST_MASK 0x1 -+#define PCIE_RGR1_SW_INIT_1_PERST_SHIFT 0x0 -+ -+#define BRCM_NUM_PCIE_OUT_WINS 0x4 -+#define BRCM_MAX_SCB 0x4 -+ -+#define BRCM_MSI_TARGET_ADDR_LT_4GB 0x0fffffffcULL -+#define BRCM_MSI_TARGET_ADDR_GT_4GB 0xffffffffcULL -+ -+#define BURST_SIZE_128 0 -+#define BURST_SIZE_256 1 -+#define BURST_SIZE_512 2 -+ -+/* Offsets from PCIE_INTR2_CPU_BASE */ -+#define STATUS 0x0 -+#define SET 0x4 -+#define CLR 0x8 -+#define MASK_STATUS 0xc -+#define MASK_SET 0x10 -+#define MASK_CLR 0x14 -+ -+#define PCIE_BUSNUM_SHIFT 20 -+#define PCIE_SLOT_SHIFT 15 -+#define PCIE_FUNC_SHIFT 12 -+ -+#if defined(__BIG_ENDIAN) -+#define DATA_ENDIAN 2 /* PCIe->DDR inbound traffic */ -+#define MMIO_ENDIAN 2 /* CPU->PCIe outbound traffic */ -+#else -+#define DATA_ENDIAN 0 -+#define MMIO_ENDIAN 0 -+#endif -+ -+#define MDIO_PORT0 0x0 -+#define MDIO_DATA_MASK 0x7fffffff -+#define MDIO_DATA_SHIFT 0x0 -+#define MDIO_PORT_MASK 0xf0000 -+#define MDIO_PORT_SHIFT 0x16 -+#define MDIO_REGAD_MASK 0xffff -+#define MDIO_REGAD_SHIFT 0x0 -+#define MDIO_CMD_MASK 0xfff00000 -+#define MDIO_CMD_SHIFT 0x14 -+#define MDIO_CMD_READ 0x1 -+#define MDIO_CMD_WRITE 0x0 -+#define MDIO_DATA_DONE_MASK 0x80000000 -+#define MDIO_RD_DONE(x) (((x) & MDIO_DATA_DONE_MASK) ? 1 : 0) -+#define MDIO_WT_DONE(x) (((x) & MDIO_DATA_DONE_MASK) ? 0 : 1) -+#define SSC_REGS_ADDR 0x1100 -+#define SET_ADDR_OFFSET 0x1f -+#define SSC_CNTL_OFFSET 0x2 -+#define SSC_CNTL_OVRD_EN_MASK 0x8000 -+#define SSC_CNTL_OVRD_EN_SHIFT 0xf -+#define SSC_CNTL_OVRD_VAL_MASK 0x4000 -+#define SSC_CNTL_OVRD_VAL_SHIFT 0xe -+#define SSC_STATUS_OFFSET 0x1 -+#define SSC_STATUS_SSC_MASK 0x400 -+#define SSC_STATUS_SSC_SHIFT 0xa -+#define SSC_STATUS_PLL_LOCK_MASK 0x800 -+#define SSC_STATUS_PLL_LOCK_SHIFT 0xb -+ -+#define IDX_ADDR(pcie) \ -+ ((pcie)->reg_offsets[EXT_CFG_INDEX]) -+#define DATA_ADDR(pcie) \ -+ ((pcie)->reg_offsets[EXT_CFG_DATA]) -+#define PCIE_RGR1_SW_INIT_1(pcie) \ -+ ((pcie)->reg_offsets[RGR1_SW_INIT_1]) -+ -+enum { -+ RGR1_SW_INIT_1, -+ EXT_CFG_INDEX, -+ EXT_CFG_DATA, -+}; -+ -+enum { -+ RGR1_SW_INIT_1_INIT_MASK, -+ RGR1_SW_INIT_1_INIT_SHIFT, -+ RGR1_SW_INIT_1_PERST_MASK, -+ RGR1_SW_INIT_1_PERST_SHIFT, -+}; -+ -+enum pcie_type { -+ BCM7425, -+ BCM7435, -+ GENERIC, -+ BCM7278, -+}; -+ -+struct brcm_window { -+ dma_addr_t pcie_addr; -+ phys_addr_t cpu_addr; -+ dma_addr_t size; -+}; -+ -+/* Internal PCIe Host Controller Information.*/ -+struct brcm_pcie { -+ struct device *dev; -+ void __iomem *base; -+ struct list_head resources; -+ int irq; -+ struct clk *clk; -+ struct pci_bus *root_bus; -+ struct device_node *dn; -+ int id; -+ bool suspended; -+ int num_out_wins; -+ bool ssc; -+ int gen; -+ struct brcm_window out_wins[BRCM_NUM_PCIE_OUT_WINS]; -+ unsigned int rev; -+ const int *reg_offsets; -+ const int *reg_field_info; -+ enum pcie_type type; -+}; -+ -+struct pcie_cfg_data { -+ const int *reg_field_info; -+ const int *offsets; -+ const enum pcie_type type; -+}; -+ -+static const int pcie_reg_field_info[] = { -+ [RGR1_SW_INIT_1_INIT_MASK] = 0x2, -+ [RGR1_SW_INIT_1_INIT_SHIFT] = 0x1, -+}; -+ -+static const int pcie_reg_field_info_bcm7278[] = { -+ [RGR1_SW_INIT_1_INIT_MASK] = 0x1, -+ [RGR1_SW_INIT_1_INIT_SHIFT] = 0x0, -+}; -+ -+static const int pcie_offset_bcm7425[] = { -+ [RGR1_SW_INIT_1] = 0x8010, -+ [EXT_CFG_INDEX] = 0x8300, -+ [EXT_CFG_DATA] = 0x8304, -+}; -+ -+static const struct pcie_cfg_data bcm7425_cfg = { -+ .reg_field_info = pcie_reg_field_info, -+ .offsets = pcie_offset_bcm7425, -+ .type = BCM7425, -+}; -+ -+static const int pcie_offsets[] = { -+ [RGR1_SW_INIT_1] = 0x9210, -+ [EXT_CFG_INDEX] = 0x9000, -+ [EXT_CFG_DATA] = 0x9004, -+}; -+ -+static const struct pcie_cfg_data bcm7435_cfg = { -+ .reg_field_info = pcie_reg_field_info, -+ .offsets = pcie_offsets, -+ .type = BCM7435, -+}; -+ -+static const struct pcie_cfg_data generic_cfg = { -+ .reg_field_info = pcie_reg_field_info, -+ .offsets = pcie_offsets, -+ .type = GENERIC, -+}; -+ -+static const int pcie_offset_bcm7278[] = { -+ [RGR1_SW_INIT_1] = 0xc010, -+ [EXT_CFG_INDEX] = 0x9000, -+ [EXT_CFG_DATA] = 0x9004, -+}; -+ -+static const struct pcie_cfg_data bcm7278_cfg = { -+ .reg_field_info = pcie_reg_field_info_bcm7278, -+ .offsets = pcie_offset_bcm7278, -+ .type = BCM7278, -+}; -+ -+static void __iomem *brcm_pcie_map_conf(struct pci_bus *bus, unsigned int devfn, -+ int where); -+ -+static struct pci_ops brcm_pcie_ops = { -+ .map_bus = brcm_pcie_map_conf, -+ .read = pci_generic_config_read, -+ .write = pci_generic_config_write, -+}; -+ -+#if defined(CONFIG_MIPS) -+/* Broadcom MIPs HW implicitly does the swapping if necessary */ -+#define bcm_readl(a) __raw_readl(a) -+#define bcm_writel(d, a) __raw_writel(d, a) -+#define bcm_readw(a) __raw_readw(a) -+#define bcm_writew(d, a) __raw_writew(d, a) -+#else -+#define bcm_readl(a) readl(a) -+#define bcm_writel(d, a) writel(d, a) -+#define bcm_readw(a) readw(a) -+#define bcm_writew(d, a) writew(d, a) -+#endif -+ -+/* These macros extract/insert fields to host controller's register set. */ -+#define RD_FLD(base, reg, field) \ -+ rd_fld(base + reg, reg##_##field##_MASK, reg##_##field##_SHIFT) -+#define WR_FLD(base, reg, field, val) \ -+ wr_fld(base + reg, reg##_##field##_MASK, reg##_##field##_SHIFT, val) -+#define WR_FLD_RB(base, reg, field, val) \ -+ wr_fld_rb(base + reg, reg##_##field##_MASK, reg##_##field##_SHIFT, val) -+#define WR_FLD_WITH_OFFSET(base, off, reg, field, val) \ -+ wr_fld(base + reg + off, reg##_##field##_MASK, \ -+ reg##_##field##_SHIFT, val) -+#define EXTRACT_FIELD(val, reg, field) \ -+ ((val & reg##_##field##_MASK) >> reg##_##field##_SHIFT) -+#define INSERT_FIELD(val, reg, field, field_val) \ -+ ((val & ~reg##_##field##_MASK) | \ -+ (reg##_##field##_MASK & (field_val << reg##_##field##_SHIFT))) -+ -+static phys_addr_t scb_size[BRCM_MAX_SCB]; -+static int num_memc; -+static int num_pcie; -+static DEFINE_MUTEX(brcm_pcie_lock); -+ -+static u32 rd_fld(void __iomem *p, u32 mask, int shift) -+{ -+ return (bcm_readl(p) & mask) >> shift; -+} -+ -+static void wr_fld(void __iomem *p, u32 mask, int shift, u32 val) -+{ -+ u32 reg = bcm_readl(p); -+ -+ reg = (reg & ~mask) | ((val << shift) & mask); -+ bcm_writel(reg, p); -+} -+ -+static void wr_fld_rb(void __iomem *p, u32 mask, int shift, u32 val) -+{ -+ wr_fld(p, mask, shift, val); -+ (void)bcm_readl(p); -+} -+ -+static const char *link_speed_to_str(int s) -+{ -+ switch (s) { -+ case 1: -+ return "2.5"; -+ case 2: -+ return "5.0"; -+ case 3: -+ return "8.0"; -+ default: -+ break; -+ } -+ return "???"; -+} -+ -+/* -+ * The roundup_pow_of_two() from log2.h invokes -+ * __roundup_pow_of_two(unsigned long), but we really need a -+ * such a function to take a native u64 since unsigned long -+ * is 32 bits on some configurations. So we provide this helper -+ * function below. -+ */ -+static u64 roundup_pow_of_two_64(u64 n) -+{ -+ return 1ULL << fls64(n - 1); -+} -+ -+/* -+ * This is to convert the size of the inbound "BAR" region to the -+ * non-linear values of PCIE_X_MISC_RC_BAR[123]_CONFIG_LO.SIZE -+ */ -+int encode_ibar_size(u64 size) -+{ -+ int log2_in = ilog2(size); -+ -+ if (log2_in >= 12 && log2_in <= 15) -+ /* Covers 4KB to 32KB (inclusive) */ -+ return (log2_in - 12) + 0x1c; -+ else if (log2_in >= 16 && log2_in <= 37) -+ /* Covers 64KB to 32GB, (inclusive) */ -+ return log2_in - 15; -+ /* Something is awry so disable */ -+ return 0; -+} -+ -+static u32 mdio_form_pkt(int port, int regad, int cmd) -+{ -+ u32 pkt = 0; -+ -+ pkt |= (port << MDIO_PORT_SHIFT) & MDIO_PORT_MASK; -+ pkt |= (regad << MDIO_REGAD_SHIFT) & MDIO_REGAD_MASK; -+ pkt |= (cmd << MDIO_CMD_SHIFT) & MDIO_CMD_MASK; -+ -+ return pkt; -+} -+ -+/* negative return value indicates error */ -+static int mdio_read(void __iomem *base, u8 port, u8 regad) -+{ -+ int tries; -+ u32 data; -+ -+ bcm_writel(mdio_form_pkt(port, regad, MDIO_CMD_READ), -+ base + PCIE_RC_DL_MDIO_ADDR); -+ bcm_readl(base + PCIE_RC_DL_MDIO_ADDR); -+ -+ data = bcm_readl(base + PCIE_RC_DL_MDIO_RD_DATA); -+ for (tries = 0; !MDIO_RD_DONE(data) && tries < 10; tries++) { -+ udelay(10); -+ data = bcm_readl(base + PCIE_RC_DL_MDIO_RD_DATA); -+ } -+ -+ return MDIO_RD_DONE(data) -+ ? (data & MDIO_DATA_MASK) >> MDIO_DATA_SHIFT -+ : -EIO; -+} -+ -+/* negative return value indicates error */ -+static int mdio_write(void __iomem *base, u8 port, u8 regad, u16 wrdata) -+{ -+ int tries; -+ u32 data; -+ -+ bcm_writel(mdio_form_pkt(port, regad, MDIO_CMD_WRITE), -+ base + PCIE_RC_DL_MDIO_ADDR); -+ bcm_readl(base + PCIE_RC_DL_MDIO_ADDR); -+ bcm_writel(MDIO_DATA_DONE_MASK | wrdata, -+ base + PCIE_RC_DL_MDIO_WR_DATA); -+ -+ data = bcm_readl(base + PCIE_RC_DL_MDIO_WR_DATA); -+ for (tries = 0; !MDIO_WT_DONE(data) && tries < 10; tries++) { -+ udelay(10); -+ data = bcm_readl(base + PCIE_RC_DL_MDIO_WR_DATA); -+ } -+ -+ return MDIO_WT_DONE(data) ? 0 : -EIO; -+} -+ -+/* -+ * Configures device for Spread Spectrum Clocking (SSC) mode; a negative -+ * return value indicates error. -+ */ -+static int set_ssc(void __iomem *base) -+{ -+ int tmp; -+ u16 wrdata; -+ int pll, ssc; -+ -+ tmp = mdio_write(base, MDIO_PORT0, SET_ADDR_OFFSET, SSC_REGS_ADDR); -+ if (tmp < 0) -+ return tmp; -+ -+ tmp = mdio_read(base, MDIO_PORT0, SSC_CNTL_OFFSET); -+ if (tmp < 0) -+ return tmp; -+ -+ wrdata = INSERT_FIELD(tmp, SSC_CNTL_OVRD, EN, 1); -+ wrdata = INSERT_FIELD(wrdata, SSC_CNTL_OVRD, VAL, 1); -+ tmp = mdio_write(base, MDIO_PORT0, SSC_CNTL_OFFSET, wrdata); -+ if (tmp < 0) -+ return tmp; -+ -+ usleep_range(1000, 2000); -+ tmp = mdio_read(base, MDIO_PORT0, SSC_STATUS_OFFSET); -+ if (tmp < 0) -+ return tmp; -+ -+ ssc = EXTRACT_FIELD(tmp, SSC_STATUS, SSC); -+ pll = EXTRACT_FIELD(tmp, SSC_STATUS, PLL_LOCK); -+ -+ return (ssc && pll) ? 0 : -EIO; -+} -+ -+/* Limits operation to a specific generation (1, 2, or 3) */ -+static void set_gen(void __iomem *base, int gen) -+{ -+ u32 lnkcap = bcm_readl(base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCAP); -+ u16 lnkctl2 = bcm_readw(base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCTL2); -+ -+ lnkcap = (lnkcap & ~PCI_EXP_LNKCAP_SLS) | gen; -+ bcm_writel(lnkcap, base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCAP); -+ -+ lnkctl2 = (lnkctl2 & ~0xf) | gen; -+ bcm_writew(lnkctl2, base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKCTL2); -+} -+ -+static void brcm_pcie_set_outbound_win(struct brcm_pcie *pcie, -+ unsigned int win, phys_addr_t cpu_addr, -+ dma_addr_t pcie_addr, dma_addr_t size) -+{ -+ void __iomem *base = pcie->base; -+ phys_addr_t cpu_addr_mb, limit_addr_mb; -+ u32 tmp; -+ -+ /* Set the base of the pcie_addr window */ -+ bcm_writel(lower_32_bits(pcie_addr) + MMIO_ENDIAN, -+ base + PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + (win * 8)); -+ bcm_writel(upper_32_bits(pcie_addr), -+ base + PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + (win * 8)); -+ -+ cpu_addr_mb = cpu_addr >> 20; -+ limit_addr_mb = (cpu_addr + size - 1) >> 20; -+ -+ /* Write the addr base low register */ -+ WR_FLD_WITH_OFFSET(base, (win * 4), -+ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT, -+ BASE, cpu_addr_mb); -+ /* Write the addr limit low register */ -+ WR_FLD_WITH_OFFSET(base, (win * 4), -+ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT, -+ LIMIT, limit_addr_mb); -+ -+ if (pcie->type != BCM7435 && pcie->type != BCM7425) { -+ /* Write the cpu addr high register */ -+ tmp = (u32)(cpu_addr_mb >> -+ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_NUM_MASK_BITS); -+ WR_FLD_WITH_OFFSET(base, (win * 8), -+ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI, -+ BASE, tmp); -+ /* Write the cpu limit high register */ -+ tmp = (u32)(limit_addr_mb >> -+ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_NUM_MASK_BITS); -+ WR_FLD_WITH_OFFSET(base, (win * 8), -+ PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI, -+ LIMIT, tmp); -+ } -+} -+ -+/* Configuration space read/write support */ -+static int cfg_index(int busnr, int devfn, int reg) -+{ -+ return ((PCI_SLOT(devfn) & 0x1f) << PCIE_SLOT_SHIFT) -+ | ((PCI_FUNC(devfn) & 0x07) << PCIE_FUNC_SHIFT) -+ | (busnr << PCIE_BUSNUM_SHIFT) -+ | (reg & ~3); -+} -+ -+/* The controller is capable of serving in both RC and EP roles */ -+static bool brcm_pcie_rc_mode(struct brcm_pcie *pcie) -+{ -+ void __iomem *base = pcie->base; -+ u32 val = bcm_readl(base + PCIE_MISC_PCIE_STATUS); -+ -+ return !!EXTRACT_FIELD(val, PCIE_MISC_PCIE_STATUS, PCIE_PORT); -+} -+ -+static bool brcm_pcie_link_up(struct brcm_pcie *pcie) -+{ -+ void __iomem *base = pcie->base; -+ u32 val = bcm_readl(base + PCIE_MISC_PCIE_STATUS); -+ u32 dla = EXTRACT_FIELD(val, PCIE_MISC_PCIE_STATUS, PCIE_DL_ACTIVE); -+ u32 plu = EXTRACT_FIELD(val, PCIE_MISC_PCIE_STATUS, PCIE_PHYLINKUP); -+ -+ return (dla && plu) ? true : false; -+} -+ -+static void __iomem *brcm_pcie_map_conf(struct pci_bus *bus, unsigned int devfn, -+ int where) -+{ -+ struct brcm_pcie *pcie = bus->sysdata; -+ void __iomem *base = pcie->base; -+ int idx; -+ -+ /* Accesses to the RC go right to the RC registers if slot==0 */ -+ if (pci_is_root_bus(bus)) -+ return PCI_SLOT(devfn) ? NULL : base + where; -+ -+ /* For devices, write to the config space index register */ -+ idx = cfg_index(bus->number, devfn, where); -+ bcm_writel(idx, pcie->base + IDX_ADDR(pcie)); -+ return base + DATA_ADDR(pcie) + (where & 0x3); -+} -+ -+static inline void brcm_pcie_bridge_sw_init_set(struct brcm_pcie *pcie, -+ unsigned int val) -+{ -+ unsigned int shift = pcie->reg_field_info[RGR1_SW_INIT_1_INIT_SHIFT]; -+ u32 mask = pcie->reg_field_info[RGR1_SW_INIT_1_INIT_MASK]; -+ -+ wr_fld_rb(pcie->base + PCIE_RGR1_SW_INIT_1(pcie), mask, shift, val); -+} -+ -+static inline void brcm_pcie_perst_set(struct brcm_pcie *pcie, -+ unsigned int val) -+{ -+ if (pcie->type != BCM7278) -+ wr_fld_rb(pcie->base + PCIE_RGR1_SW_INIT_1(pcie), -+ PCIE_RGR1_SW_INIT_1_PERST_MASK, -+ PCIE_RGR1_SW_INIT_1_PERST_SHIFT, val); -+ else -+ /* Assert = 0, de-assert = 1 on 7278 */ -+ WR_FLD_RB(pcie->base, PCIE_MISC_PCIE_CTRL, PCIE_PERSTB, !val); -+} -+ -+static int brcm_pcie_add_controller(struct brcm_pcie *pcie) -+{ -+ int i, ret = 0; -+ -+ mutex_lock(&brcm_pcie_lock); -+ if (num_pcie > 0) { -+ num_pcie++; -+ goto done; -+ } -+ -+ /* Determine num_memc and their sizes */ -+ for (i = 0, num_memc = 0; i < BRCM_MAX_SCB; i++) { -+ u64 size = brcmstb_memory_memc_size(i); -+ -+ if (size == (u64)-1) { -+ dev_err(pcie->dev, "cannot get memc%d size\n", i); -+ ret = -EINVAL; -+ goto done; -+ } else if (size) { -+ scb_size[i] = roundup_pow_of_two_64(size); -+ num_memc++; -+ } else { -+ break; -+ } -+ } -+ if (!ret && num_memc == 0) { -+ ret = -EINVAL; -+ goto done; -+ } -+ -+ num_pcie++; -+done: -+ mutex_unlock(&brcm_pcie_lock); -+ return ret; -+} -+ -+static void brcm_pcie_remove_controller(struct brcm_pcie *pcie) -+{ -+ mutex_lock(&brcm_pcie_lock); -+ if (--num_pcie == 0) -+ num_memc = 0; -+ mutex_unlock(&brcm_pcie_lock); -+} -+ -+static int brcm_pcie_parse_request_of_pci_ranges(struct brcm_pcie *pcie) -+{ -+ struct resource_entry *win; -+ int ret; -+ -+ ret = devm_of_pci_get_host_bridge_resources(pcie->dev, 0, 0xff, -+ &pcie->resources, NULL); -+ if (ret) { -+ dev_err(pcie->dev, "failed to get host resources\n"); -+ return ret; -+ } -+ -+ resource_list_for_each_entry(win, &pcie->resources) { -+ struct resource *parent, *res = win->res; -+ dma_addr_t offset = (dma_addr_t)win->offset; -+ -+ if (resource_type(res) == IORESOURCE_IO) { -+ parent = &ioport_resource; -+ } else if (resource_type(res) == IORESOURCE_MEM) { -+ if (pcie->num_out_wins >= BRCM_NUM_PCIE_OUT_WINS) { -+ dev_err(pcie->dev, "too many outbound wins\n"); -+ return -EINVAL; -+ } -+ pcie->out_wins[pcie->num_out_wins].cpu_addr -+ = (phys_addr_t)res->start; -+ pcie->out_wins[pcie->num_out_wins].pcie_addr -+ = (dma_addr_t)(res->start -+ - (phys_addr_t)offset); -+ pcie->out_wins[pcie->num_out_wins].size -+ = (dma_addr_t)(res->end - res->start + 1); -+ pcie->num_out_wins++; -+ parent = &iomem_resource; -+ } else { -+ continue; -+ } -+ -+ ret = devm_request_resource(pcie->dev, parent, res); -+ if (ret) { -+ dev_err(pcie->dev, "failed to get res %pR\n", res); -+ return ret; -+ } -+ } -+ return 0; -+} -+ -+static int brcm_pcie_setup(struct brcm_pcie *pcie) -+{ -+ void __iomem *base = pcie->base; -+ unsigned int scb_size_val; -+ u64 rc_bar2_offset, rc_bar2_size, total_mem_size = 0; -+ u32 tmp, burst; -+ int i, j, ret, limit; -+ u16 nlw, cls, lnksta; -+ bool ssc_good = false; -+ struct device *dev = pcie->dev; -+ -+ /* Reset the bridge */ -+ brcm_pcie_bridge_sw_init_set(pcie, 1); -+ -+ /* -+ * Ensure that the fundamental reset is asserted, except for 7278, -+ * which fails if we do this. -+ */ -+ if (pcie->type != BCM7278) -+ brcm_pcie_perst_set(pcie, 1); -+ -+ usleep_range(100, 200); -+ -+ /* Take the bridge out of reset */ -+ brcm_pcie_bridge_sw_init_set(pcie, 0); -+ -+ WR_FLD_RB(base, PCIE_MISC_HARD_PCIE_HARD_DEBUG, SERDES_IDDQ, 0); -+ /* Wait for SerDes to be stable */ -+ usleep_range(100, 200); -+ -+ /* Grab the PCIe hw revision number */ -+ tmp = bcm_readl(base + PCIE_MISC_REVISION); -+ pcie->rev = EXTRACT_FIELD(tmp, PCIE_MISC_REVISION, MAJMIN); -+ -+ /* Set SCB_MAX_BURST_SIZE, CFG_READ_UR_MODE, SCB_ACCESS_EN */ -+ tmp = INSERT_FIELD(0, PCIE_MISC_MISC_CTRL, SCB_ACCESS_EN, 1); -+ tmp = INSERT_FIELD(tmp, PCIE_MISC_MISC_CTRL, CFG_READ_UR_MODE, 1); -+ burst = (pcie->type == GENERIC || pcie->type == BCM7278) -+ ? BURST_SIZE_512 : BURST_SIZE_256; -+ tmp = INSERT_FIELD(tmp, PCIE_MISC_MISC_CTRL, MAX_BURST_SIZE, burst); -+ bcm_writel(tmp, base + PCIE_MISC_MISC_CTRL); -+ -+ /* -+ * Set up inbound memory view for the EP (called RC_BAR2, -+ * not to be confused with the BARs that are advertised by -+ * the EP). -+ */ -+ for (i = 0; i < num_memc; i++) -+ total_mem_size += scb_size[i]; -+ -+ /* -+ * The PCIe host controller by design must set the inbound -+ * viewport to be a contiguous arrangement of all of the -+ * system's memory. In addition, its size mut be a power of -+ * two. To further complicate matters, the viewport must -+ * start on a pcie-address that is aligned on a multiple of its -+ * size. If a portion of the viewport does not represent -+ * system memory -- e.g. 3GB of memory requires a 4GB viewport -+ * -- we can map the outbound memory in or after 3GB and even -+ * though the viewport will overlap the outbound memory the -+ * controller will know to send outbound memory downstream and -+ * everything else upstream. -+ */ -+ rc_bar2_size = roundup_pow_of_two_64(total_mem_size); -+ -+ /* -+ * Set simple configuration based on memory sizes -+ * only. We always start the viewport at address 0. -+ */ -+ rc_bar2_offset = 0; -+ -+ tmp = lower_32_bits(rc_bar2_offset); -+ tmp = INSERT_FIELD(tmp, PCIE_MISC_RC_BAR2_CONFIG_LO, SIZE, -+ encode_ibar_size(rc_bar2_size)); -+ bcm_writel(tmp, base + PCIE_MISC_RC_BAR2_CONFIG_LO); -+ bcm_writel(upper_32_bits(rc_bar2_offset), -+ base + PCIE_MISC_RC_BAR2_CONFIG_HI); -+ -+ scb_size_val = scb_size[0] -+ ? ilog2(scb_size[0]) - 15 : 0xf; /* 0xf is 1GB */ -+ WR_FLD(base, PCIE_MISC_MISC_CTRL, SCB0_SIZE, scb_size_val); -+ -+ if (num_memc > 1) { -+ scb_size_val = scb_size[1] -+ ? ilog2(scb_size[1]) - 15 : 0xf; /* 0xf is 1GB */ -+ WR_FLD(base, PCIE_MISC_MISC_CTRL, SCB1_SIZE, scb_size_val); -+ } -+ -+ if (num_memc > 2) { -+ scb_size_val = scb_size[2] -+ ? ilog2(scb_size[2]) - 15 : 0xf; /* 0xf is 1GB */ -+ WR_FLD(base, PCIE_MISC_MISC_CTRL, SCB2_SIZE, scb_size_val); -+ } -+ -+ /* disable the PCIe->GISB memory window (RC_BAR1) */ -+ WR_FLD(base, PCIE_MISC_RC_BAR1_CONFIG_LO, SIZE, 0); -+ -+ /* disable the PCIe->SCB memory window (RC_BAR3) */ -+ WR_FLD(base, PCIE_MISC_RC_BAR3_CONFIG_LO, SIZE, 0); -+ -+ if (!pcie->suspended) { -+ /* clear any interrupts we find on boot */ -+ bcm_writel(0xffffffff, base + PCIE_INTR2_CPU_BASE + CLR); -+ (void)bcm_readl(base + PCIE_INTR2_CPU_BASE + CLR); -+ } -+ -+ /* Mask all interrupts since we are not handling any yet */ -+ bcm_writel(0xffffffff, base + PCIE_INTR2_CPU_BASE + MASK_SET); -+ (void)bcm_readl(base + PCIE_INTR2_CPU_BASE + MASK_SET); -+ -+ if (pcie->gen) -+ set_gen(base, pcie->gen); -+ -+ /* Unassert the fundamental reset */ -+ brcm_pcie_perst_set(pcie, 0); -+ -+ /* -+ * Give the RC/EP time to wake up, before trying to configure RC. -+ * Intermittently check status for link-up, up to a total of 100ms -+ * when we don't know if the device is there, and up to 1000ms if -+ * we do know the device is there. -+ */ -+ limit = pcie->suspended ? 1000 : 100; -+ for (i = 1, j = 0; j < limit && !brcm_pcie_link_up(pcie); -+ j += i, i = i * 2) -+ msleep(i + j > limit ? limit - j : i); -+ -+ if (!brcm_pcie_link_up(pcie)) { -+ dev_info(dev, "link down\n"); -+ return -ENODEV; -+ } -+ -+ if (!brcm_pcie_rc_mode(pcie)) { -+ dev_err(dev, "PCIe misconfigured; is in EP mode\n"); -+ return -EINVAL; -+ } -+ -+ for (i = 0; i < pcie->num_out_wins; i++) -+ brcm_pcie_set_outbound_win(pcie, i, pcie->out_wins[i].cpu_addr, -+ pcie->out_wins[i].pcie_addr, -+ pcie->out_wins[i].size); -+ -+ /* -+ * For config space accesses on the RC, show the right class for -+ * a PCIe-PCIe bridge (the default setting is to be EP mode). -+ */ -+ WR_FLD_RB(base, PCIE_RC_CFG_PRIV1_ID_VAL3, CLASS_CODE, 0x060400); -+ -+ if (pcie->ssc) { -+ ret = set_ssc(base); -+ if (ret == 0) -+ ssc_good = true; -+ else -+ dev_err(dev, "failed attempt to enter ssc mode\n"); -+ } -+ -+ lnksta = bcm_readw(base + BRCM_PCIE_CAP_REGS + PCI_EXP_LNKSTA); -+ cls = lnksta & PCI_EXP_LNKSTA_CLS; -+ nlw = (lnksta & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT; -+ dev_info(dev, "link up, %s Gbps x%u %s\n", link_speed_to_str(cls), -+ nlw, ssc_good ? "(SSC)" : "(!SSC)"); -+ -+ /* PCIe->SCB endian mode for BAR */ -+ /* field ENDIAN_MODE_BAR2 = DATA_ENDIAN */ -+ WR_FLD_RB(base, PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1, -+ ENDIAN_MODE_BAR2, DATA_ENDIAN); -+ -+ /* -+ * Refclk from RC should be gated with CLKREQ# input when ASPM L0s,L1 -+ * is enabled => setting the CLKREQ_DEBUG_ENABLE field to 1. -+ */ -+ WR_FLD_RB(base, PCIE_MISC_HARD_PCIE_HARD_DEBUG, CLKREQ_DEBUG_ENABLE, 1); -+ -+ return 0; -+} -+ -+/* L23 is a low-power PCIe link state */ -+static void enter_l23(struct brcm_pcie *pcie) -+{ -+ void __iomem *base = pcie->base; -+ int tries, l23; -+ -+ /* assert request for L23 */ -+ WR_FLD_RB(base, PCIE_MISC_PCIE_CTRL, PCIE_L23_REQUEST, 1); -+ /* poll L23 status */ -+ for (tries = 0, l23 = 0; tries < 1000 && !l23; tries++) -+ l23 = RD_FLD(base, PCIE_MISC_PCIE_STATUS, PCIE_LINK_IN_L23); -+ if (!l23) -+ dev_err(pcie->dev, "failed to enter L23\n"); -+} -+ -+static void turn_off(struct brcm_pcie *pcie) -+{ -+ void __iomem *base = pcie->base; -+ -+ if (brcm_pcie_link_up(pcie)) -+ enter_l23(pcie); -+ /* Assert fundamental reset */ -+ brcm_pcie_perst_set(pcie, 1); -+ /* Deassert request for L23 in case it was asserted */ -+ WR_FLD_RB(base, PCIE_MISC_PCIE_CTRL, PCIE_L23_REQUEST, 0); -+ /* Turn off SerDes */ -+ WR_FLD_RB(base, PCIE_MISC_HARD_PCIE_HARD_DEBUG, SERDES_IDDQ, 1); -+ /* Shutdown PCIe bridge */ -+ brcm_pcie_bridge_sw_init_set(pcie, 1); -+} -+ -+static int brcm_pcie_suspend(struct device *dev) -+{ -+ struct brcm_pcie *pcie = dev_get_drvdata(dev); -+ -+ turn_off(pcie); -+ clk_disable_unprepare(pcie->clk); -+ pcie->suspended = true; -+ -+ return 0; -+} -+ -+static int brcm_pcie_resume(struct device *dev) -+{ -+ struct brcm_pcie *pcie = dev_get_drvdata(dev); -+ void __iomem *base; -+ int ret; -+ -+ base = pcie->base; -+ clk_prepare_enable(pcie->clk); -+ -+ /* Take bridge out of reset so we can access the SerDes reg */ -+ brcm_pcie_bridge_sw_init_set(pcie, 0); -+ -+ /* Turn on SerDes */ -+ WR_FLD_RB(base, PCIE_MISC_HARD_PCIE_HARD_DEBUG, SERDES_IDDQ, 0); -+ /* Wait for SerDes to be stable */ -+ usleep_range(100, 200); -+ -+ ret = brcm_pcie_setup(pcie); -+ if (ret) -+ return ret; -+ -+ pcie->suspended = false; -+ -+ return 0; -+} -+ -+static void _brcm_pcie_remove(struct brcm_pcie *pcie) -+{ -+ turn_off(pcie); -+ clk_disable_unprepare(pcie->clk); -+ clk_put(pcie->clk); -+ brcm_pcie_remove_controller(pcie); -+} -+ -+static int brcm_pcie_remove(struct platform_device *pdev) -+{ -+ struct brcm_pcie *pcie = platform_get_drvdata(pdev); -+ -+ pci_stop_root_bus(pcie->root_bus); -+ pci_remove_root_bus(pcie->root_bus); -+ _brcm_pcie_remove(pcie); -+ -+ return 0; -+} -+ -+static const struct of_device_id brcm_pcie_match[] = { -+ { .compatible = "brcm,bcm7425-pcie", .data = &bcm7425_cfg }, -+ { .compatible = "brcm,bcm7435-pcie", .data = &bcm7435_cfg }, -+ { .compatible = "brcm,bcm7278-pcie", .data = &bcm7278_cfg }, -+ { .compatible = "brcm,bcm7445-pcie", .data = &generic_cfg }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, brcm_pcie_match); -+ -+static int brcm_pcie_probe(struct platform_device *pdev) -+{ -+ struct device_node *dn = pdev->dev.of_node; -+ const struct of_device_id *of_id; -+ const struct pcie_cfg_data *data; -+ int ret; -+ struct brcm_pcie *pcie; -+ struct resource *res; -+ void __iomem *base; -+ u32 tmp; -+ struct pci_host_bridge *bridge; -+ struct pci_bus *child; -+ -+ bridge = devm_pci_alloc_host_bridge(&pdev->dev, sizeof(*pcie)); -+ if (!bridge) -+ return -ENOMEM; -+ -+ pcie = pci_host_bridge_priv(bridge); -+ INIT_LIST_HEAD(&pcie->resources); -+ -+ of_id = of_match_node(brcm_pcie_match, dn); -+ if (!of_id) { -+ dev_err(&pdev->dev, "failed to look up compatible string\n"); -+ return -EINVAL; -+ } -+ -+ if (of_property_read_u32(dn, "dma-ranges", &tmp) == 0) { -+ dev_err(&pdev->dev, "cannot yet handle dma-ranges\n"); -+ return -EINVAL; -+ } -+ -+ data = of_id->data; -+ pcie->reg_offsets = data->offsets; -+ pcie->reg_field_info = data->reg_field_info; -+ pcie->type = data->type; -+ pcie->dn = dn; -+ pcie->dev = &pdev->dev; -+ -+ /* We use the domain number as our controller number */ -+ pcie->id = of_get_pci_domain_nr(dn); -+ if (pcie->id < 0) -+ return pcie->id; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) -+ return -EINVAL; -+ -+ base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ pcie->clk = of_clk_get_by_name(dn, "sw_pcie"); -+ if (IS_ERR(pcie->clk)) { -+ dev_err(&pdev->dev, "could not get clock\n"); -+ pcie->clk = NULL; -+ } -+ pcie->base = base; -+ -+ ret = of_pci_get_max_link_speed(dn); -+ pcie->gen = (ret < 0) ? 0 : ret; -+ -+ pcie->ssc = of_property_read_bool(dn, "brcm,enable-ssc"); -+ -+ ret = irq_of_parse_and_map(pdev->dev.of_node, 0); -+ if (ret == 0) -+ /* keep going, as we don't use this intr yet */ -+ dev_warn(pcie->dev, "cannot get PCIe interrupt\n"); -+ else -+ pcie->irq = ret; -+ -+ ret = brcm_pcie_parse_request_of_pci_ranges(pcie); -+ if (ret) -+ return ret; -+ -+ ret = clk_prepare_enable(pcie->clk); -+ if (ret) { -+ dev_err(&pdev->dev, "could not enable clock\n"); -+ return ret; -+ } -+ -+ ret = brcm_pcie_add_controller(pcie); -+ if (ret) -+ return ret; -+ -+ ret = brcm_pcie_setup(pcie); -+ if (ret) -+ goto fail; -+ -+ list_splice_init(&pcie->resources, &bridge->windows); -+ bridge->dev.parent = &pdev->dev; -+ bridge->busnr = 0; -+ bridge->ops = &brcm_pcie_ops; -+ bridge->sysdata = pcie; -+ bridge->map_irq = of_irq_parse_and_map_pci; -+ bridge->swizzle_irq = pci_common_swizzle; -+ -+ ret = pci_scan_root_bus_bridge(bridge); -+ if (ret < 0) { -+ dev_err(pcie->dev, "Scanning root bridge failed\n"); -+ goto fail; -+ } -+ -+ pci_assign_unassigned_bus_resources(bridge->bus); -+ list_for_each_entry(child, &bridge->bus->children, node) -+ pcie_bus_configure_settings(child); -+ pci_bus_add_devices(bridge->bus); -+ platform_set_drvdata(pdev, pcie); -+ pcie->root_bus = bridge->bus; -+ -+ return 0; -+ -+fail: -+ _brcm_pcie_remove(pcie); -+ return ret; -+} -+ -+static const struct dev_pm_ops brcm_pcie_pm_ops = { -+ .suspend_noirq = brcm_pcie_suspend, -+ .resume_noirq = brcm_pcie_resume, -+}; -+ -+static struct platform_driver brcm_pcie_driver = { -+ .probe = brcm_pcie_probe, -+ .remove = brcm_pcie_remove, -+ .driver = { -+ .name = "brcm-pcie", -+ .owner = THIS_MODULE, -+ .of_match_table = brcm_pcie_match, -+ .pm = &brcm_pcie_pm_ops, -+ }, -+}; -+ -+module_platform_driver(brcm_pcie_driver); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_DESCRIPTION("Broadcom STB PCIe RC driver"); -+MODULE_AUTHOR("Broadcom"); ---- /dev/null -+++ b/include/soc/brcmstb/memory_api.h -@@ -0,0 +1,25 @@ -+#ifndef __MEMORY_API_H -+#define __MEMORY_API_H -+ -+/* -+ * Bus Interface Unit control register setup, must happen early during boot, -+ * before SMP is brought up, called by machine entry point. -+ */ -+void brcmstb_biuctrl_init(void); -+ -+#ifdef CONFIG_SOC_BRCMSTB -+int brcmstb_memory_phys_addr_to_memc(phys_addr_t pa); -+u64 brcmstb_memory_memc_size(int memc); -+#else -+static inline int brcmstb_memory_phys_addr_to_memc(phys_addr_t pa) -+{ -+ return -EINVAL; -+} -+ -+static inline u64 brcmstb_memory_memc_size(int memc) -+{ -+ return -1; -+} -+#endif -+ -+#endif /* __MEMORY_API_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0534-pcie-brcmstb-Changes-for-BCM2711.patch b/target/linux/brcm2708/patches-4.19/950-0534-pcie-brcmstb-Changes-for-BCM2711.patch new file mode 100644 index 0000000000..2f9585b45e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0534-pcie-brcmstb-Changes-for-BCM2711.patch @@ -0,0 +1,1411 @@ +From cbe53bb0428c1ae30fb7395fc8d8f507a6afbded Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 19 Feb 2019 22:06:59 +0000 +Subject: [PATCH 534/725] pcie-brcmstb: Changes for BCM2711 + +The initial brcmstb PCIe driver - originally taken from the V3(?) +patch set - has been modified significantly for the BCM2711. + +Signed-off-by: Phil Elwell +--- + drivers/dma/bcm2835-dma.c | 107 ++++ + drivers/pci/controller/Makefile | 4 + + drivers/pci/controller/pcie-brcmstb-bounce.c | 564 +++++++++++++++++++ + drivers/pci/controller/pcie-brcmstb-bounce.h | 32 ++ + drivers/pci/controller/pcie-brcmstb.c | 237 ++++---- + drivers/soc/bcm/brcmstb/Makefile | 2 +- + drivers/soc/bcm/brcmstb/memory.c | 158 ++++++ + 7 files changed, 996 insertions(+), 108 deletions(-) + create mode 100644 drivers/pci/controller/pcie-brcmstb-bounce.c + create mode 100644 drivers/pci/controller/pcie-brcmstb-bounce.h + create mode 100644 drivers/soc/bcm/brcmstb/memory.c + +--- a/drivers/dma/bcm2835-dma.c ++++ b/drivers/dma/bcm2835-dma.c +@@ -68,6 +68,17 @@ struct bcm2835_dma_cb { + uint32_t pad[2]; + }; + ++struct bcm2838_dma40_scb { ++ uint32_t ti; ++ uint32_t src; ++ uint32_t srci; ++ uint32_t dst; ++ uint32_t dsti; ++ uint32_t len; ++ uint32_t next_cb; ++ uint32_t rsvd; ++}; ++ + struct bcm2835_cb_entry { + struct bcm2835_dma_cb *cb; + dma_addr_t paddr; +@@ -185,6 +196,45 @@ struct bcm2835_desc { + #define MAX_DMA_LEN SZ_1G + #define MAX_LITE_DMA_LEN (SZ_64K - 4) + ++/* 40-bit DMA support */ ++#define BCM2838_DMA40_CS 0x00 ++#define BCM2838_DMA40_CB 0x04 ++#define BCM2838_DMA40_DEBUG 0x0c ++#define BCM2858_DMA40_TI 0x10 ++#define BCM2838_DMA40_SRC 0x14 ++#define BCM2838_DMA40_SRCI 0x18 ++#define BCM2838_DMA40_DEST 0x1c ++#define BCM2838_DMA40_DESTI 0x20 ++#define BCM2838_DMA40_LEN 0x24 ++#define BCM2838_DMA40_NEXT_CB 0x28 ++#define BCM2838_DMA40_DEBUG2 0x2c ++ ++#define BCM2838_DMA40_CS_ACTIVE BIT(0) ++#define BCM2838_DMA40_CS_END BIT(1) ++ ++#define BCM2838_DMA40_CS_QOS(x) (((x) & 0x1f) << 16) ++#define BCM2838_DMA40_CS_PANIC_QOS(x) (((x) & 0x1f) << 20) ++#define BCM2838_DMA40_CS_WRITE_WAIT BIT(28) ++ ++#define BCM2838_DMA40_BURST_LEN(x) ((((x) - 1) & 0xf) << 8) ++#define BCM2838_DMA40_INC BIT(12) ++#define BCM2838_DMA40_SIZE_128 (2 << 13) ++ ++#define BCM2838_DMA40_MEMCPY_QOS \ ++ (BCM2838_DMA40_CS_QOS(0x0) | \ ++ BCM2838_DMA40_CS_PANIC_QOS(0x0) | \ ++ BCM2838_DMA40_CS_WRITE_WAIT) ++ ++#define BCM2838_DMA40_MEMCPY_XFER_INFO \ ++ (BCM2838_DMA40_SIZE_128 | \ ++ BCM2838_DMA40_INC | \ ++ BCM2838_DMA40_BURST_LEN(16)) ++ ++static void __iomem *memcpy_chan; ++static struct bcm2838_dma40_scb *memcpy_scb; ++static dma_addr_t memcpy_scb_dma; ++DEFINE_SPINLOCK(memcpy_lock); ++ + static inline size_t bcm2835_dma_max_frame_length(struct bcm2835_chan *c) + { + /* lite and normal channels have different max frame length */ +@@ -868,6 +918,56 @@ static void bcm2835_dma_free(struct bcm2 + } + } + ++int bcm2838_dma40_memcpy_init(struct device *dev) ++{ ++ if (memcpy_scb) ++ return 0; ++ ++ memcpy_scb = dma_alloc_coherent(dev, sizeof(*memcpy_scb), ++ &memcpy_scb_dma, GFP_KERNEL); ++ ++ if (!memcpy_scb) { ++ pr_err("bcm2838_dma40_memcpy_init failed!\n"); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL(bcm2838_dma40_memcpy_init); ++ ++void bcm2838_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size) ++{ ++ struct bcm2838_dma40_scb *scb = memcpy_scb; ++ unsigned long flags; ++ ++ if (!scb) { ++ pr_err("bcm2838_dma40_memcpy not initialised!\n"); ++ return; ++ } ++ ++ spin_lock_irqsave(&memcpy_lock, flags); ++ ++ scb->ti = 0; ++ scb->src = lower_32_bits(src); ++ scb->srci = upper_32_bits(src) | BCM2838_DMA40_MEMCPY_XFER_INFO; ++ scb->dst = lower_32_bits(dst); ++ scb->dsti = upper_32_bits(dst) | BCM2838_DMA40_MEMCPY_XFER_INFO; ++ scb->len = size; ++ scb->next_cb = 0; ++ ++ writel((u32)(memcpy_scb_dma >> 5), memcpy_chan + BCM2838_DMA40_CB); ++ writel(BCM2838_DMA40_MEMCPY_QOS + BCM2838_DMA40_CS_ACTIVE, ++ memcpy_chan + BCM2838_DMA40_CS); ++ /* Poll for completion */ ++ while (!(readl(memcpy_chan + BCM2838_DMA40_CS) & BCM2838_DMA40_CS_END)) ++ cpu_relax(); ++ ++ writel(BCM2838_DMA40_CS_END, memcpy_chan + BCM2838_DMA40_CS); ++ ++ spin_unlock_irqrestore(&memcpy_lock, flags); ++} ++EXPORT_SYMBOL(bcm2838_dma40_memcpy); ++ + static const struct of_device_id bcm2835_dma_of_match[] = { + { .compatible = "brcm,bcm2835-dma", }, + {}, +@@ -964,6 +1064,13 @@ static int bcm2835_dma_probe(struct plat + /* Channel 0 is used by the legacy API */ + chans_available &= ~BCM2835_DMA_BULK_MASK; + ++ /* We can't use channels 11-13 yet */ ++ chans_available &= ~(BIT(11) | BIT(12) | BIT(13)); ++ ++ /* Grab channel 14 for the 40-bit DMA memcpy */ ++ chans_available &= ~BIT(14); ++ memcpy_chan = BCM2835_DMA_CHANIO(base, 14); ++ + /* get irqs for each channel that we support */ + for (i = 0; i <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; i++) { + /* skip masked out channels */ +--- a/drivers/pci/controller/Makefile ++++ b/drivers/pci/controller/Makefile +@@ -29,6 +29,10 @@ obj-$(CONFIG_PCIE_MEDIATEK) += pcie-medi + obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o + obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o + obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o ++ifdef CONFIG_ARM ++obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb-bounce.o ++endif ++ + obj-$(CONFIG_VMD) += vmd.o + # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW + obj-y += dwc/ +--- /dev/null ++++ b/drivers/pci/controller/pcie-brcmstb-bounce.c +@@ -0,0 +1,564 @@ ++/* ++ * This code started out as a version of arch/arm/common/dmabounce.c, ++ * modified to cope with highmem pages. Now it has been changed heavily - ++ * it now preallocates a large block (currently 4MB) and carves it up ++ * sequentially in ring fashion, and DMA is used to copy the data - to the ++ * point where very little of the original remains. ++ * ++ * Copyright (C) 2019 Raspberry Pi (Trading) Ltd. ++ * ++ * Original version by Brad Parker (brad@heeltoe.com) ++ * Re-written by Christopher Hoover ++ * Made generic by Deepak Saxena ++ * ++ * Copyright (C) 2002 Hewlett Packard Company. ++ * Copyright (C) 2004 MontaVista Software, Inc. ++ * ++ * 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. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define STATS ++ ++#ifdef STATS ++#define DO_STATS(X) do { X ; } while (0) ++#else ++#define DO_STATS(X) do { } while (0) ++#endif ++ ++/* ************************************************** */ ++ ++struct safe_buffer { ++ struct list_head node; ++ ++ /* original request */ ++ size_t size; ++ int direction; ++ ++ struct dmabounce_pool *pool; ++ void *safe; ++ dma_addr_t unsafe_dma_addr; ++ dma_addr_t safe_dma_addr; ++}; ++ ++struct dmabounce_pool { ++ unsigned long pages; ++ void *virt_addr; ++ dma_addr_t dma_addr; ++ unsigned long *alloc_map; ++ unsigned long alloc_pos; ++ spinlock_t lock; ++ struct device *dev; ++ unsigned long num_pages; ++#ifdef STATS ++ size_t max_size; ++ unsigned long num_bufs; ++ unsigned long max_bufs; ++ unsigned long max_pages; ++#endif ++}; ++ ++struct dmabounce_device_info { ++ struct device *dev; ++ dma_addr_t threshold; ++ struct list_head safe_buffers; ++ struct dmabounce_pool pool; ++ rwlock_t lock; ++#ifdef STATS ++ unsigned long map_count; ++ unsigned long unmap_count; ++ unsigned long sync_dev_count; ++ unsigned long sync_cpu_count; ++ unsigned long fail_count; ++ int attr_res; ++#endif ++}; ++ ++static struct dmabounce_device_info *g_dmabounce_device_info; ++ ++extern int bcm2838_dma40_memcpy_init(struct device *dev); ++extern void bcm2838_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size); ++ ++#ifdef STATS ++static ssize_t ++bounce_show(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct dmabounce_device_info *device_info = g_dmabounce_device_info; ++ return sprintf(buf, "m:%lu/%lu s:%lu/%lu f:%lu s:%zu b:%lu/%lu a:%lu/%lu\n", ++ device_info->map_count, ++ device_info->unmap_count, ++ device_info->sync_dev_count, ++ device_info->sync_cpu_count, ++ device_info->fail_count, ++ device_info->pool.max_size, ++ device_info->pool.num_bufs, ++ device_info->pool.max_bufs, ++ device_info->pool.num_pages * PAGE_SIZE, ++ device_info->pool.max_pages * PAGE_SIZE); ++} ++ ++static DEVICE_ATTR(dmabounce_stats, 0444, bounce_show, NULL); ++#endif ++ ++static int bounce_create(struct dmabounce_pool *pool, struct device *dev, ++ unsigned long buffer_size) ++{ ++ int ret = -ENOMEM; ++ pool->pages = (buffer_size + PAGE_SIZE - 1)/PAGE_SIZE; ++ pool->alloc_map = bitmap_zalloc(pool->pages, GFP_KERNEL); ++ if (!pool->alloc_map) ++ goto err_bitmap; ++ pool->virt_addr = dma_alloc_coherent(dev, pool->pages * PAGE_SIZE, ++ &pool->dma_addr, GFP_KERNEL); ++ if (!pool->virt_addr) ++ goto err_dmabuf; ++ ++ pool->alloc_pos = 0; ++ spin_lock_init(&pool->lock); ++ pool->dev = dev; ++ pool->num_pages = 0; ++ ++ DO_STATS(pool->max_size = 0); ++ DO_STATS(pool->num_bufs = 0); ++ DO_STATS(pool->max_bufs = 0); ++ DO_STATS(pool->max_pages = 0); ++ ++ return 0; ++ ++err_dmabuf: ++ bitmap_free(pool->alloc_map); ++err_bitmap: ++ return ret; ++} ++ ++static void bounce_destroy(struct dmabounce_pool *pool) ++{ ++ dma_free_coherent(pool->dev, pool->pages * PAGE_SIZE, pool->virt_addr, ++ pool->dma_addr); ++ ++ bitmap_free(pool->alloc_map); ++} ++ ++static void *bounce_alloc(struct dmabounce_pool *pool, size_t size, ++ dma_addr_t *dmaaddrp) ++{ ++ unsigned long pages; ++ unsigned long flags; ++ unsigned long pos; ++ ++ pages = (size + PAGE_SIZE - 1)/PAGE_SIZE; ++ ++ DO_STATS(pool->max_size = max(size, pool->max_size)); ++ ++ spin_lock_irqsave(&pool->lock, flags); ++ pos = bitmap_find_next_zero_area(pool->alloc_map, pool->pages, ++ pool->alloc_pos, pages, 0); ++ /* If not found, try from the start */ ++ if (pos >= pool->pages && pool->alloc_pos) ++ pos = bitmap_find_next_zero_area(pool->alloc_map, pool->pages, ++ 0, pages, 0); ++ ++ if (pos >= pool->pages) { ++ spin_unlock_irqrestore(&pool->lock, flags); ++ return NULL; ++ } ++ ++ bitmap_set(pool->alloc_map, pos, pages); ++ pool->alloc_pos = (pos + pages) % pool->pages; ++ pool->num_pages += pages; ++ ++ DO_STATS(pool->num_bufs++); ++ DO_STATS(pool->max_bufs = max(pool->num_bufs, pool->max_bufs)); ++ DO_STATS(pool->max_pages = max(pool->num_pages, pool->max_pages)); ++ ++ spin_unlock_irqrestore(&pool->lock, flags); ++ ++ *dmaaddrp = pool->dma_addr + pos * PAGE_SIZE; ++ ++ return pool->virt_addr + pos * PAGE_SIZE; ++} ++ ++static void ++bounce_free(struct dmabounce_pool *pool, void *buf, size_t size) ++{ ++ unsigned long pages; ++ unsigned long flags; ++ unsigned long pos; ++ ++ pages = (size + PAGE_SIZE - 1)/PAGE_SIZE; ++ pos = (buf - pool->virt_addr)/PAGE_SIZE; ++ ++ BUG_ON((buf - pool->virt_addr) & (PAGE_SIZE - 1)); ++ ++ spin_lock_irqsave(&pool->lock, flags); ++ bitmap_clear(pool->alloc_map, pos, pages); ++ pool->num_pages -= pages; ++ if (pool->num_pages == 0) ++ pool->alloc_pos = 0; ++ DO_STATS(pool->num_bufs--); ++ spin_unlock_irqrestore(&pool->lock, flags); ++} ++ ++/* allocate a 'safe' buffer and keep track of it */ ++static struct safe_buffer * ++alloc_safe_buffer(struct dmabounce_device_info *device_info, ++ dma_addr_t dma_addr, size_t size, enum dma_data_direction dir) ++{ ++ struct safe_buffer *buf; ++ struct dmabounce_pool *pool = &device_info->pool; ++ struct device *dev = device_info->dev; ++ unsigned long flags; ++ ++ /* ++ * Although one might expect this to be called in thread context, ++ * using GFP_KERNEL here leads to hard-to-debug lockups. in_atomic() ++ * was previously used to select the appropriate allocation mode, ++ * but this is unsafe. ++ */ ++ buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC); ++ if (!buf) { ++ dev_warn(dev, "%s: kmalloc failed\n", __func__); ++ return NULL; ++ } ++ ++ buf->unsafe_dma_addr = dma_addr; ++ buf->size = size; ++ buf->direction = dir; ++ buf->pool = pool; ++ ++ buf->safe = bounce_alloc(pool, size, &buf->safe_dma_addr); ++ ++ if (!buf->safe) { ++ dev_warn(dev, ++ "%s: could not alloc dma memory (size=%d)\n", ++ __func__, size); ++ kfree(buf); ++ return NULL; ++ } ++ ++ write_lock_irqsave(&device_info->lock, flags); ++ list_add(&buf->node, &device_info->safe_buffers); ++ write_unlock_irqrestore(&device_info->lock, flags); ++ ++ return buf; ++} ++ ++/* determine if a buffer is from our "safe" pool */ ++static struct safe_buffer * ++find_safe_buffer(struct dmabounce_device_info *device_info, ++ dma_addr_t safe_dma_addr) ++{ ++ struct safe_buffer *b, *rb = NULL; ++ unsigned long flags; ++ ++ read_lock_irqsave(&device_info->lock, flags); ++ ++ list_for_each_entry(b, &device_info->safe_buffers, node) ++ if (b->safe_dma_addr <= safe_dma_addr && ++ b->safe_dma_addr + b->size > safe_dma_addr) { ++ rb = b; ++ break; ++ } ++ ++ read_unlock_irqrestore(&device_info->lock, flags); ++ return rb; ++} ++ ++static void ++free_safe_buffer(struct dmabounce_device_info *device_info, ++ struct safe_buffer *buf) ++{ ++ unsigned long flags; ++ ++ write_lock_irqsave(&device_info->lock, flags); ++ list_del(&buf->node); ++ write_unlock_irqrestore(&device_info->lock, flags); ++ ++ bounce_free(buf->pool, buf->safe, buf->size); ++ ++ kfree(buf); ++} ++ ++/* ************************************************** */ ++ ++static struct safe_buffer * ++find_safe_buffer_dev(struct device *dev, dma_addr_t dma_addr, const char *where) ++{ ++ if (!dev || !g_dmabounce_device_info) ++ return NULL; ++ if (dma_mapping_error(dev, dma_addr)) { ++ dev_err(dev, "Trying to %s invalid mapping\n", where); ++ return NULL; ++ } ++ return find_safe_buffer(g_dmabounce_device_info, dma_addr); ++} ++ ++static dma_addr_t ++map_single(struct device *dev, struct safe_buffer *buf, size_t size, ++ enum dma_data_direction dir, unsigned long attrs) ++{ ++ BUG_ON(buf->size != size); ++ BUG_ON(buf->direction != dir); ++ ++ dev_dbg(dev, "map: %llx->%llx\n", (u64)buf->unsafe_dma_addr, ++ (u64)buf->safe_dma_addr); ++ ++ if ((dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) && ++ !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) ++ bcm2838_dma40_memcpy(buf->safe_dma_addr, buf->unsafe_dma_addr, ++ size); ++ ++ return buf->safe_dma_addr; ++} ++ ++static dma_addr_t ++unmap_single(struct device *dev, struct safe_buffer *buf, size_t size, ++ enum dma_data_direction dir, unsigned long attrs) ++{ ++ BUG_ON(buf->size != size); ++ BUG_ON(buf->direction != dir); ++ ++ if ((dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) && ++ !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) { ++ dev_dbg(dev, "unmap: %llx->%llx\n", (u64)buf->safe_dma_addr, ++ (u64)buf->unsafe_dma_addr); ++ ++ bcm2838_dma40_memcpy(buf->unsafe_dma_addr, buf->safe_dma_addr, ++ size); ++ } ++ return buf->unsafe_dma_addr; ++} ++ ++/* ************************************************** */ ++ ++/* ++ * see if a buffer address is in an 'unsafe' range. if it is ++ * allocate a 'safe' buffer and copy the unsafe buffer into it. ++ * substitute the safe buffer for the unsafe one. ++ * (basically move the buffer from an unsafe area to a safe one) ++ */ ++static dma_addr_t ++dmabounce_map_page(struct device *dev, struct page *page, unsigned long offset, ++ size_t size, enum dma_data_direction dir, ++ unsigned long attrs) ++{ ++ struct dmabounce_device_info *device_info = g_dmabounce_device_info; ++ dma_addr_t dma_addr; ++ ++ dma_addr = pfn_to_dma(dev, page_to_pfn(page)) + offset; ++ ++ arm_dma_ops.sync_single_for_device(dev, dma_addr, size, dir); ++ ++ if (device_info && (dma_addr + size) > device_info->threshold) { ++ struct safe_buffer *buf; ++ ++ buf = alloc_safe_buffer(device_info, dma_addr, size, dir); ++ if (!buf) { ++ DO_STATS(device_info->fail_count++); ++ return ARM_MAPPING_ERROR; ++ } ++ ++ DO_STATS(device_info->map_count++); ++ ++ dma_addr = map_single(dev, buf, size, dir, attrs); ++ } ++ ++ return dma_addr; ++} ++ ++/* ++ * see if a mapped address was really a "safe" buffer and if so, copy ++ * the data from the safe buffer back to the unsafe buffer and free up ++ * the safe buffer. (basically return things back to the way they ++ * should be) ++ */ ++static void ++dmabounce_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, ++ enum dma_data_direction dir, unsigned long attrs) ++{ ++ struct safe_buffer *buf; ++ ++ buf = find_safe_buffer_dev(dev, dma_addr, __func__); ++ if (buf) { ++ DO_STATS(g_dmabounce_device_info->unmap_count++); ++ dma_addr = unmap_single(dev, buf, size, dir, attrs); ++ free_safe_buffer(g_dmabounce_device_info, buf); ++ } ++ ++ arm_dma_ops.sync_single_for_cpu(dev, dma_addr, size, dir); ++} ++ ++/* ++ * A version of dmabounce_map_page that assumes the mapping has already ++ * been created - intended for streaming operation. ++ */ ++static void ++dmabounce_sync_for_device(struct device *dev, dma_addr_t dma_addr, size_t size, ++ enum dma_data_direction dir) ++{ ++ struct safe_buffer *buf; ++ ++ arm_dma_ops.sync_single_for_device(dev, dma_addr, size, dir); ++ ++ buf = find_safe_buffer_dev(dev, dma_addr, __func__); ++ if (buf) { ++ DO_STATS(g_dmabounce_device_info->sync_dev_count++); ++ map_single(dev, buf, size, dir, 0); ++ } ++} ++ ++/* ++ * A version of dmabounce_unmap_page that doesn't destroy the mapping - ++ * intended for streaming operation. ++ */ ++static void ++dmabounce_sync_for_cpu(struct device *dev, dma_addr_t dma_addr, ++ size_t size, enum dma_data_direction dir) ++{ ++ struct safe_buffer *buf; ++ ++ buf = find_safe_buffer_dev(dev, dma_addr, __func__); ++ if (buf) { ++ DO_STATS(g_dmabounce_device_info->sync_cpu_count++); ++ dma_addr = unmap_single(dev, buf, size, dir, 0); ++ } ++ ++ arm_dma_ops.sync_single_for_cpu(dev, dma_addr, size, dir); ++} ++ ++static int dmabounce_dma_supported(struct device *dev, u64 dma_mask) ++{ ++ if (g_dmabounce_device_info) ++ return 0; ++ ++ return arm_dma_ops.dma_supported(dev, dma_mask); ++} ++ ++static int dmabounce_mapping_error(struct device *dev, dma_addr_t dma_addr) ++{ ++ return arm_dma_ops.mapping_error(dev, dma_addr); ++} ++ ++static const struct dma_map_ops dmabounce_ops = { ++ .alloc = arm_dma_alloc, ++ .free = arm_dma_free, ++ .mmap = arm_dma_mmap, ++ .get_sgtable = arm_dma_get_sgtable, ++ .map_page = dmabounce_map_page, ++ .unmap_page = dmabounce_unmap_page, ++ .sync_single_for_cpu = dmabounce_sync_for_cpu, ++ .sync_single_for_device = dmabounce_sync_for_device, ++ .map_sg = arm_dma_map_sg, ++ .unmap_sg = arm_dma_unmap_sg, ++ .sync_sg_for_cpu = arm_dma_sync_sg_for_cpu, ++ .sync_sg_for_device = arm_dma_sync_sg_for_device, ++ .dma_supported = dmabounce_dma_supported, ++ .mapping_error = dmabounce_mapping_error, ++}; ++ ++int brcm_pcie_bounce_register_dev(struct device *dev, ++ unsigned long buffer_size, ++ dma_addr_t threshold) ++{ ++ struct dmabounce_device_info *device_info; ++ int ret; ++ ++ /* Only support a single client */ ++ if (g_dmabounce_device_info) ++ return -EBUSY; ++ ++ ret = bcm2838_dma40_memcpy_init(dev); ++ if (ret) ++ return ret; ++ ++ device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC); ++ if (!device_info) { ++ dev_err(dev, ++ "Could not allocated dmabounce_device_info\n"); ++ return -ENOMEM; ++ } ++ ++ ret = bounce_create(&device_info->pool, dev, buffer_size); ++ if (ret) { ++ dev_err(dev, ++ "dmabounce: could not allocate %ld byte DMA pool\n", ++ buffer_size); ++ goto err_bounce; ++ } ++ ++ device_info->dev = dev; ++ device_info->threshold = threshold; ++ INIT_LIST_HEAD(&device_info->safe_buffers); ++ rwlock_init(&device_info->lock); ++ ++ DO_STATS(device_info->map_count = 0); ++ DO_STATS(device_info->unmap_count = 0); ++ DO_STATS(device_info->sync_dev_count = 0); ++ DO_STATS(device_info->sync_cpu_count = 0); ++ DO_STATS(device_info->fail_count = 0); ++ DO_STATS(device_info->attr_res = ++ device_create_file(dev, &dev_attr_dmabounce_stats)); ++ ++ g_dmabounce_device_info = device_info; ++ set_dma_ops(dev, &dmabounce_ops); ++ ++ dev_info(dev, "dmabounce: registered device - %ld kB, threshold %pad\n", ++ buffer_size / 1024, &threshold); ++ ++ return 0; ++ ++ err_bounce: ++ kfree(device_info); ++ return ret; ++} ++EXPORT_SYMBOL(brcm_pcie_bounce_register_dev); ++ ++void brcm_pcie_bounce_unregister_dev(struct device *dev) ++{ ++ struct dmabounce_device_info *device_info = g_dmabounce_device_info; ++ ++ g_dmabounce_device_info = NULL; ++ set_dma_ops(dev, NULL); ++ ++ if (!device_info) { ++ dev_warn(dev, ++ "Never registered with dmabounce but attempting" ++ "to unregister!\n"); ++ return; ++ } ++ ++ if (!list_empty(&device_info->safe_buffers)) { ++ dev_err(dev, ++ "Removing from dmabounce with pending buffers!\n"); ++ BUG(); ++ } ++ ++ bounce_destroy(&device_info->pool); ++ ++ DO_STATS(if (device_info->attr_res == 0) ++ device_remove_file(dev, &dev_attr_dmabounce_stats)); ++ ++ kfree(device_info); ++ ++ dev_info(dev, "dmabounce: device unregistered\n"); ++} ++EXPORT_SYMBOL(brcm_pcie_bounce_unregister_dev); ++ ++MODULE_AUTHOR("Phil Elwell "); ++MODULE_DESCRIPTION("Dedicate DMA bounce support for pcie-brcmstb"); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ b/drivers/pci/controller/pcie-brcmstb-bounce.h +@@ -0,0 +1,32 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (C) 2019 Raspberry Pi (Trading) Ltd. ++ */ ++ ++#ifndef _PCIE_BRCMSTB_BOUNCE_H ++#define _PCIE_BRCMSTB_BOUNCE_H ++ ++#ifdef CONFIG_ARM ++ ++int brcm_pcie_bounce_register_dev(struct device *dev, unsigned long buffer_size, ++ dma_addr_t threshold); ++ ++int brcm_pcie_bounce_unregister_dev(struct device *dev); ++ ++#else ++ ++static inline int brcm_pcie_bounce_register_dev(struct device *dev, ++ unsigned long buffer_size, ++ dma_addr_t threshold) ++{ ++ return 0; ++} ++ ++static inline int brcm_pcie_bounce_unregister_dev(struct device *dev) ++{ ++ return 0; ++} ++ ++#endif ++ ++#endif /* _PCIE_BRCMSTB_BOUNCE_H */ +--- a/drivers/pci/controller/pcie-brcmstb.c ++++ b/drivers/pci/controller/pcie-brcmstb.c +@@ -29,6 +29,7 @@ + #include + #include + #include "../pci.h" ++#include "pcie-brcmstb-bounce.h" + + /* BRCM_PCIE_CAP_REGS - Offset for the mandatory capability config regs */ + #define BRCM_PCIE_CAP_REGS 0x00ac +@@ -53,6 +54,7 @@ + #define PCIE_MISC_MSI_BAR_CONFIG_LO 0x4044 + #define PCIE_MISC_MSI_BAR_CONFIG_HI 0x4048 + #define PCIE_MISC_MSI_DATA_CONFIG 0x404c ++#define PCIE_MISC_EOI_CTRL 0x4060 + #define PCIE_MISC_PCIE_CTRL 0x4064 + #define PCIE_MISC_PCIE_STATUS 0x4068 + #define PCIE_MISC_REVISION 0x406c +@@ -260,12 +262,14 @@ struct brcm_pcie { + unsigned int rev; + const int *reg_offsets; + const int *reg_field_info; ++ u32 max_burst_size; + enum pcie_type type; + }; + + struct pcie_cfg_data { + const int *reg_field_info; + const int *offsets; ++ const u32 max_burst_size; + const enum pcie_type type; + }; + +@@ -288,24 +292,27 @@ static const int pcie_offset_bcm7425[] = + static const struct pcie_cfg_data bcm7425_cfg = { + .reg_field_info = pcie_reg_field_info, + .offsets = pcie_offset_bcm7425, ++ .max_burst_size = BURST_SIZE_256, + .type = BCM7425, + }; + + static const int pcie_offsets[] = { + [RGR1_SW_INIT_1] = 0x9210, + [EXT_CFG_INDEX] = 0x9000, +- [EXT_CFG_DATA] = 0x9004, ++ [EXT_CFG_DATA] = 0x8000, + }; + + static const struct pcie_cfg_data bcm7435_cfg = { + .reg_field_info = pcie_reg_field_info, + .offsets = pcie_offsets, ++ .max_burst_size = BURST_SIZE_256, + .type = BCM7435, + }; + + static const struct pcie_cfg_data generic_cfg = { + .reg_field_info = pcie_reg_field_info, + .offsets = pcie_offsets, ++ .max_burst_size = BURST_SIZE_128, // before BURST_SIZE_512 + .type = GENERIC, + }; + +@@ -318,6 +325,7 @@ static const int pcie_offset_bcm7278[] = + static const struct pcie_cfg_data bcm7278_cfg = { + .reg_field_info = pcie_reg_field_info_bcm7278, + .offsets = pcie_offset_bcm7278, ++ .max_burst_size = BURST_SIZE_512, + .type = BCM7278, + }; + +@@ -360,7 +368,6 @@ static struct pci_ops brcm_pcie_ops = { + (reg##_##field##_MASK & (field_val << reg##_##field##_SHIFT))) + + static const struct dma_map_ops *arch_dma_ops; +-static const struct dma_map_ops *brcm_dma_ops_ptr; + static struct of_pci_range *dma_ranges; + static int num_dma_ranges; + +@@ -369,6 +376,16 @@ static int num_memc; + static int num_pcie; + static DEFINE_MUTEX(brcm_pcie_lock); + ++static unsigned int bounce_buffer = 32*1024*1024; ++module_param(bounce_buffer, uint, 0644); ++MODULE_PARM_DESC(bounce_buffer, "Size of bounce buffer"); ++ ++static unsigned int bounce_threshold = 0xc0000000; ++module_param(bounce_threshold, uint, 0644); ++MODULE_PARM_DESC(bounce_threshold, "Bounce threshold"); ++ ++static struct brcm_pcie *g_pcie; ++ + static dma_addr_t brcm_to_pci(dma_addr_t addr) + { + struct of_pci_range *p; +@@ -457,12 +474,10 @@ static int brcm_map_sg(struct device *de + struct scatterlist *sg; + + for_each_sg(sgl, sg, nents, i) { +-#ifdef CONFIG_NEED_SG_DMA_LENGTH +- sg->dma_length = sg->length; +-#endif ++ sg_dma_len(sg) = sg->length; + sg->dma_address = +- brcm_dma_ops_ptr->map_page(dev, sg_page(sg), sg->offset, +- sg->length, dir, attrs); ++ brcm_map_page(dev, sg_page(sg), sg->offset, ++ sg->length, dir, attrs); + if (dma_mapping_error(dev, sg->dma_address)) + goto bad_mapping; + } +@@ -470,8 +485,8 @@ static int brcm_map_sg(struct device *de + + bad_mapping: + for_each_sg(sgl, sg, i, j) +- brcm_dma_ops_ptr->unmap_page(dev, sg_dma_address(sg), +- sg_dma_len(sg), dir, attrs); ++ brcm_unmap_page(dev, sg_dma_address(sg), ++ sg_dma_len(sg), dir, attrs); + return 0; + } + +@@ -484,8 +499,8 @@ static void brcm_unmap_sg(struct device + struct scatterlist *sg; + + for_each_sg(sgl, sg, nents, i) +- brcm_dma_ops_ptr->unmap_page(dev, sg_dma_address(sg), +- sg_dma_len(sg), dir, attrs); ++ brcm_unmap_page(dev, sg_dma_address(sg), ++ sg_dma_len(sg), dir, attrs); + } + + static void brcm_sync_single_for_cpu(struct device *dev, +@@ -531,8 +546,8 @@ void brcm_sync_sg_for_cpu(struct device + int i; + + for_each_sg(sgl, sg, nents, i) +- brcm_dma_ops_ptr->sync_single_for_cpu(dev, sg_dma_address(sg), +- sg->length, dir); ++ brcm_sync_single_for_cpu(dev, sg_dma_address(sg), ++ sg->length, dir); + } + + void brcm_sync_sg_for_device(struct device *dev, struct scatterlist *sgl, +@@ -542,9 +557,9 @@ void brcm_sync_sg_for_device(struct devi + int i; + + for_each_sg(sgl, sg, nents, i) +- brcm_dma_ops_ptr->sync_single_for_device(dev, +- sg_dma_address(sg), +- sg->length, dir); ++ brcm_sync_single_for_device(dev, ++ sg_dma_address(sg), ++ sg->length, dir); + } + + static int brcm_mapping_error(struct device *dev, dma_addr_t dma_addr) +@@ -633,17 +648,47 @@ static void brcm_set_dma_ops(struct devi + set_dma_ops(dev, &brcm_dma_ops); + } + ++static inline void brcm_pcie_perst_set(struct brcm_pcie *pcie, ++ unsigned int val); + static int brcmstb_platform_notifier(struct notifier_block *nb, + unsigned long event, void *__dev) + { ++ extern unsigned long max_pfn; + struct device *dev = __dev; ++ const char *rc_name = "0000:00:00.0"; + +- brcm_dma_ops_ptr = &brcm_dma_ops; +- if (event != BUS_NOTIFY_ADD_DEVICE) +- return NOTIFY_DONE; ++ switch (event) { ++ case BUS_NOTIFY_ADD_DEVICE: ++ if (max_pfn > (bounce_threshold/PAGE_SIZE) && ++ strcmp(dev->kobj.name, rc_name)) { ++ int ret; ++ ++ ret = brcm_pcie_bounce_register_dev(dev, bounce_buffer, ++ (dma_addr_t)bounce_threshold); ++ if (ret) { ++ dev_err(dev, ++ "brcm_pcie_bounce_register_dev() failed: %d\n", ++ ret); ++ return ret; ++ } ++ } ++ brcm_set_dma_ops(dev); ++ return NOTIFY_OK; ++ ++ case BUS_NOTIFY_DEL_DEVICE: ++ if (!strcmp(dev->kobj.name, rc_name) && g_pcie) { ++ /* Force a bus reset */ ++ brcm_pcie_perst_set(g_pcie, 1); ++ msleep(100); ++ brcm_pcie_perst_set(g_pcie, 0); ++ } else if (max_pfn > (bounce_threshold/PAGE_SIZE)) { ++ brcm_pcie_bounce_unregister_dev(dev); ++ } ++ return NOTIFY_OK; + +- brcm_set_dma_ops(dev); +- return NOTIFY_OK; ++ default: ++ return NOTIFY_DONE; ++ } + } + + static struct notifier_block brcmstb_platform_nb = { +@@ -914,6 +959,7 @@ static void brcm_pcie_msi_isr(struct irq + } + } + chained_irq_exit(chip, desc); ++ bcm_writel(1, msi->base + PCIE_MISC_EOI_CTRL); + } + + static void brcm_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) +@@ -930,7 +976,8 @@ static void brcm_compose_msi_msg(struct + static int brcm_msi_set_affinity(struct irq_data *irq_data, + const struct cpumask *mask, bool force) + { +- return -EINVAL; ++ struct brcm_msi *msi = irq_data_get_irq_chip_data(irq_data); ++ return __irq_set_affinity(msi->irq, mask, force); + } + + static struct irq_chip brcm_msi_bottom_irq_chip = { +@@ -1168,9 +1215,9 @@ static void __iomem *brcm_pcie_map_conf( + return PCI_SLOT(devfn) ? NULL : base + where; + + /* For devices, write to the config space index register */ +- idx = cfg_index(bus->number, devfn, where); ++ idx = cfg_index(bus->number, devfn, 0); + bcm_writel(idx, pcie->base + IDX_ADDR(pcie)); +- return base + DATA_ADDR(pcie) + (where & 0x3); ++ return base + DATA_ADDR(pcie) + where; + } + + static inline void brcm_pcie_bridge_sw_init_set(struct brcm_pcie *pcie, +@@ -1238,20 +1285,6 @@ static int brcm_pcie_parse_map_dma_range + num_dma_ranges++; + } + +- for (i = 0, num_memc = 0; i < BRCM_MAX_SCB; i++) { +- u64 size = brcmstb_memory_memc_size(i); +- +- if (size == (u64)-1) { +- dev_err(pcie->dev, "cannot get memc%d size", i); +- return -EINVAL; +- } else if (size) { +- scb_size[i] = roundup_pow_of_two_64(size); +- num_memc++; +- } else { +- break; +- } +- } +- + return 0; + } + +@@ -1275,26 +1308,25 @@ static int brcm_pcie_add_controller(stru + if (ret) + goto done; + +- /* Determine num_memc and their sizes */ +- for (i = 0, num_memc = 0; i < BRCM_MAX_SCB; i++) { +- u64 size = brcmstb_memory_memc_size(i); +- +- if (size == (u64)-1) { +- dev_err(dev, "cannot get memc%d size\n", i); +- ret = -EINVAL; +- goto done; +- } else if (size) { +- scb_size[i] = roundup_pow_of_two_64(size); +- num_memc++; +- } else { +- break; ++ if (!num_dma_ranges) { ++ /* Determine num_memc and their sizes by other means */ ++ for (i = 0, num_memc = 0; i < BRCM_MAX_SCB; i++) { ++ u64 size = brcmstb_memory_memc_size(i); ++ ++ if (size == (u64)-1) { ++ dev_err(dev, "cannot get memc%d size\n", i); ++ ret = -EINVAL; ++ goto done; ++ } else if (size) { ++ scb_size[i] = roundup_pow_of_two_64(size); ++ } else { ++ break; ++ } + } +- } +- if (!ret && num_memc == 0) { +- ret = -EINVAL; +- goto done; ++ num_memc = i; + } + ++ g_pcie = pcie; + num_pcie++; + done: + mutex_unlock(&brcm_pcie_lock); +@@ -1307,6 +1339,7 @@ static void brcm_pcie_remove_controller( + if (--num_pcie > 0) + goto out; + ++ g_pcie = NULL; + if (brcm_unregister_notifier()) + dev_err(pcie->dev, "failed to unregister pci bus notifier\n"); + kfree(dma_ranges); +@@ -1367,7 +1400,7 @@ static int brcm_pcie_setup(struct brcm_p + void __iomem *base = pcie->base; + unsigned int scb_size_val; + u64 rc_bar2_offset, rc_bar2_size, total_mem_size = 0; +- u32 tmp, burst; ++ u32 tmp; + int i, j, ret, limit; + u16 nlw, cls, lnksta; + bool ssc_good = false; +@@ -1400,20 +1433,15 @@ static int brcm_pcie_setup(struct brcm_p + /* Set SCB_MAX_BURST_SIZE, CFG_READ_UR_MODE, SCB_ACCESS_EN */ + tmp = INSERT_FIELD(0, PCIE_MISC_MISC_CTRL, SCB_ACCESS_EN, 1); + tmp = INSERT_FIELD(tmp, PCIE_MISC_MISC_CTRL, CFG_READ_UR_MODE, 1); +- burst = (pcie->type == GENERIC || pcie->type == BCM7278) +- ? BURST_SIZE_512 : BURST_SIZE_256; +- tmp = INSERT_FIELD(tmp, PCIE_MISC_MISC_CTRL, MAX_BURST_SIZE, burst); ++ tmp = INSERT_FIELD(tmp, PCIE_MISC_MISC_CTRL, MAX_BURST_SIZE, ++ pcie->max_burst_size); + bcm_writel(tmp, base + PCIE_MISC_MISC_CTRL); + + /* + * Set up inbound memory view for the EP (called RC_BAR2, + * not to be confused with the BARs that are advertised by + * the EP). +- */ +- for (i = 0; i < num_memc; i++) +- total_mem_size += scb_size[i]; +- +- /* ++ * + * The PCIe host controller by design must set the inbound + * viewport to be a contiguous arrangement of all of the + * system's memory. In addition, its size mut be a power of +@@ -1429,55 +1457,49 @@ static int brcm_pcie_setup(struct brcm_p + * the controller will know to send outbound memory downstream + * and everything else upstream. + */ +- rc_bar2_size = roundup_pow_of_two_64(total_mem_size); + +- if (dma_ranges) { ++ if (num_dma_ranges) { + /* +- * The best-case scenario is to place the inbound +- * region in the first 4GB of pcie-space, as some +- * legacy devices can only address 32bits. +- * We would also like to put the MSI under 4GB +- * as well, since some devices require a 32bit +- * MSI target address. ++ * Use the base address and size(s) provided in the dma-ranges ++ * property. + */ +- if (total_mem_size <= 0xc0000000ULL && +- rc_bar2_size <= 0x100000000ULL) { +- rc_bar2_offset = 0; +- /* If the viewport is less then 4GB we can fit +- * the MSI target address under 4GB. Otherwise +- * put it right below 64GB. +- */ +- msi_target_addr = +- (rc_bar2_size == 0x100000000ULL) +- ? BRCM_MSI_TARGET_ADDR_GT_4GB +- : BRCM_MSI_TARGET_ADDR_LT_4GB; +- } else { +- /* +- * The system memory is 4GB or larger so we +- * cannot start the inbound region at location +- * 0 (since we have to allow some space for +- * outbound memory @ 3GB). So instead we +- * start it at the 1x multiple of its size +- */ +- rc_bar2_offset = rc_bar2_size; +- +- /* Since we are starting the viewport at 4GB or +- * higher, put the MSI target address below 4GB +- */ +- msi_target_addr = BRCM_MSI_TARGET_ADDR_LT_4GB; +- } +- } else { ++ for (i = 0; i < num_dma_ranges; i++) ++ scb_size[i] = roundup_pow_of_two_64(dma_ranges[i].size); ++ ++ num_memc = num_dma_ranges; ++ rc_bar2_offset = dma_ranges[0].pci_addr; ++ } else if (num_memc) { + /* + * Set simple configuration based on memory sizes +- * only. We always start the viewport at address 0, +- * and set the MSI target address accordingly. ++ * only. We always start the viewport at address 0. + */ + rc_bar2_offset = 0; ++ } else { ++ return -EINVAL; ++ } ++ ++ for (i = 0; i < num_memc; i++) ++ total_mem_size += scb_size[i]; ++ ++ rc_bar2_size = roundup_pow_of_two_64(total_mem_size); + +- msi_target_addr = (rc_bar2_size >= 0x100000000ULL) +- ? BRCM_MSI_TARGET_ADDR_GT_4GB +- : BRCM_MSI_TARGET_ADDR_LT_4GB; ++ /* Verify the alignment is correct */ ++ if (rc_bar2_offset & (rc_bar2_size - 1)) { ++ dev_err(dev, "inbound window is misaligned\n"); ++ return -EINVAL; + } ++ ++ /* ++ * Position the MSI target low if possible. ++ * ++ * TO DO: Consider outbound window when choosing MSI target and ++ * verifying configuration. ++ */ ++ msi_target_addr = BRCM_MSI_TARGET_ADDR_LT_4GB; ++ if (rc_bar2_offset <= msi_target_addr && ++ rc_bar2_offset + rc_bar2_size > msi_target_addr) ++ msi_target_addr = BRCM_MSI_TARGET_ADDR_GT_4GB; ++ + pcie->msi_target_addr = msi_target_addr; + + tmp = lower_32_bits(rc_bar2_offset); +@@ -1713,6 +1735,7 @@ static int brcm_pcie_probe(struct platfo + data = of_id->data; + pcie->reg_offsets = data->offsets; + pcie->reg_field_info = data->reg_field_info; ++ pcie->max_burst_size = data->max_burst_size; + pcie->type = data->type; + pcie->dn = dn; + pcie->dev = &pdev->dev; +@@ -1732,7 +1755,7 @@ static int brcm_pcie_probe(struct platfo + + pcie->clk = of_clk_get_by_name(dn, "sw_pcie"); + if (IS_ERR(pcie->clk)) { +- dev_err(&pdev->dev, "could not get clock\n"); ++ dev_warn(&pdev->dev, "could not get clock\n"); + pcie->clk = NULL; + } + pcie->base = base; +@@ -1755,7 +1778,8 @@ static int brcm_pcie_probe(struct platfo + + ret = clk_prepare_enable(pcie->clk); + if (ret) { +- dev_err(&pdev->dev, "could not enable clock\n"); ++ if (ret != -EPROBE_DEFER) ++ dev_err(&pdev->dev, "could not enable clock\n"); + return ret; + } + +@@ -1818,7 +1842,6 @@ static struct platform_driver brcm_pcie_ + .remove = brcm_pcie_remove, + .driver = { + .name = "brcm-pcie", +- .owner = THIS_MODULE, + .of_match_table = brcm_pcie_match, + .pm = &brcm_pcie_pm_ops, + }, +--- a/drivers/soc/bcm/brcmstb/Makefile ++++ b/drivers/soc/bcm/brcmstb/Makefile +@@ -1,2 +1,2 @@ +-obj-y += common.o biuctrl.o ++obj-y += common.o biuctrl.o memory.o + obj-$(CONFIG_BRCMSTB_PM) += pm/ +--- /dev/null ++++ b/drivers/soc/bcm/brcmstb/memory.c +@@ -0,0 +1,158 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright © 2015-2017 Broadcom */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Macro to help extract property data */ ++#define DT_PROP_DATA_TO_U32(b, offs) (fdt32_to_cpu(*(u32 *)(b + offs))) ++ ++/* Constants used when retrieving memc info */ ++#define NUM_BUS_RANGES 10 ++#define BUS_RANGE_ULIMIT_SHIFT 4 ++#define BUS_RANGE_LLIMIT_SHIFT 4 ++#define BUS_RANGE_PA_SHIFT 12 ++ ++enum { ++ BUSNUM_MCP0 = 0x4, ++ BUSNUM_MCP1 = 0x5, ++ BUSNUM_MCP2 = 0x6, ++}; ++ ++/* ++ * If the DT nodes are handy, determine which MEMC holds the specified ++ * physical address. ++ */ ++#ifdef CONFIG_ARCH_BRCMSTB ++int __brcmstb_memory_phys_addr_to_memc(phys_addr_t pa, void __iomem *base) ++{ ++ int memc = -1; ++ int i; ++ ++ for (i = 0; i < NUM_BUS_RANGES; i++, base += 8) { ++ const u64 ulimit_raw = readl(base); ++ const u64 llimit_raw = readl(base + 4); ++ const u64 ulimit = ++ ((ulimit_raw >> BUS_RANGE_ULIMIT_SHIFT) ++ << BUS_RANGE_PA_SHIFT) | 0xfff; ++ const u64 llimit = (llimit_raw >> BUS_RANGE_LLIMIT_SHIFT) ++ << BUS_RANGE_PA_SHIFT; ++ const u32 busnum = (u32)(ulimit_raw & 0xf); ++ ++ if (pa >= llimit && pa <= ulimit) { ++ if (busnum >= BUSNUM_MCP0 && busnum <= BUSNUM_MCP2) { ++ memc = busnum - BUSNUM_MCP0; ++ break; ++ } ++ } ++ } ++ ++ return memc; ++} ++ ++int brcmstb_memory_phys_addr_to_memc(phys_addr_t pa) ++{ ++ int memc = -1; ++ struct device_node *np; ++ void __iomem *cpubiuctrl; ++ ++ np = of_find_compatible_node(NULL, NULL, "brcm,brcmstb-cpu-biu-ctrl"); ++ if (!np) ++ return memc; ++ ++ cpubiuctrl = of_iomap(np, 0); ++ if (!cpubiuctrl) ++ goto cleanup; ++ ++ memc = __brcmstb_memory_phys_addr_to_memc(pa, cpubiuctrl); ++ iounmap(cpubiuctrl); ++ ++cleanup: ++ of_node_put(np); ++ ++ return memc; ++} ++ ++#elif defined(CONFIG_MIPS) ++int brcmstb_memory_phys_addr_to_memc(phys_addr_t pa) ++{ ++ /* The logic here is fairly simple and hardcoded: if pa <= 0x5000_0000, ++ * then this is MEMC0, else MEMC1. ++ * ++ * For systems with 2GB on MEMC0, MEMC1 starts at 9000_0000, with 1GB ++ * on MEMC0, MEMC1 starts at 6000_0000. ++ */ ++ if (pa >= 0x50000000ULL) ++ return 1; ++ else ++ return 0; ++} ++#endif ++ ++u64 brcmstb_memory_memc_size(int memc) ++{ ++ const void *fdt = initial_boot_params; ++ const int mem_offset = fdt_path_offset(fdt, "/memory"); ++ int addr_cells = 1, size_cells = 1; ++ const struct fdt_property *prop; ++ int proplen, cellslen; ++ u64 memc_size = 0; ++ int i; ++ ++ /* Get root size and address cells if specified */ ++ prop = fdt_get_property(fdt, 0, "#size-cells", &proplen); ++ if (prop) ++ size_cells = DT_PROP_DATA_TO_U32(prop->data, 0); ++ ++ prop = fdt_get_property(fdt, 0, "#address-cells", &proplen); ++ if (prop) ++ addr_cells = DT_PROP_DATA_TO_U32(prop->data, 0); ++ ++ if (mem_offset < 0) ++ return -1; ++ ++ prop = fdt_get_property(fdt, mem_offset, "reg", &proplen); ++ cellslen = (int)sizeof(u32) * (addr_cells + size_cells); ++ if ((proplen % cellslen) != 0) ++ return -1; ++ ++ for (i = 0; i < proplen / cellslen; ++i) { ++ u64 addr = 0; ++ u64 size = 0; ++ int memc_idx; ++ int j; ++ ++ for (j = 0; j < addr_cells; ++j) { ++ int offset = (cellslen * i) + (sizeof(u32) * j); ++ ++ addr |= (u64)DT_PROP_DATA_TO_U32(prop->data, offset) << ++ ((addr_cells - j - 1) * 32); ++ } ++ for (j = 0; j < size_cells; ++j) { ++ int offset = (cellslen * i) + ++ (sizeof(u32) * (j + addr_cells)); ++ ++ size |= (u64)DT_PROP_DATA_TO_U32(prop->data, offset) << ++ ((size_cells - j - 1) * 32); ++ } ++ ++ if ((phys_addr_t)addr != addr) { ++ pr_err("phys_addr_t is smaller than provided address 0x%llx!\n", ++ addr); ++ return -1; ++ } ++ ++ memc_idx = brcmstb_memory_phys_addr_to_memc((phys_addr_t)addr); ++ if (memc_idx == memc) ++ memc_size += size; ++ } ++ ++ return memc_size; ++} ++EXPORT_SYMBOL_GPL(brcmstb_memory_memc_size); ++ diff --git a/target/linux/brcm2708/patches-4.19/950-0535-PCI-brcmstb-Add-dma-range-mapping-for-inbound-traffi.patch b/target/linux/brcm2708/patches-4.19/950-0535-PCI-brcmstb-Add-dma-range-mapping-for-inbound-traffi.patch deleted file mode 100644 index aba4226047..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0535-PCI-brcmstb-Add-dma-range-mapping-for-inbound-traffi.patch +++ /dev/null @@ -1,569 +0,0 @@ -From 00dbba2f38e18a68e5dce8327ec91bdcb94d2bd1 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 19 Feb 2019 22:06:59 +0000 -Subject: [PATCH 535/703] PCI: brcmstb: Add dma-range mapping for inbound - traffic - -The Broadcom STB PCIe host controller is intimately related to the -memory subsystem. This close relationship adds complexity to how cpu -system memory is mapped to PCIe memory. Ideally, this mapping is an -identity mapping, or an identity mapping off by a constant. Not so in -this case. - -Consider the Broadcom reference board BCM97445LCC_4X8 which has 6 GB -of system memory. Here is how the PCIe controller maps the -system memory to PCIe memory: - - memc0-a@[ 0....3fffffff] <=> pci@[ 0....3fffffff] - memc0-b@[100000000...13fffffff] <=> pci@[ 40000000....7fffffff] - memc1-a@[ 40000000....7fffffff] <=> pci@[ 80000000....bfffffff] - memc1-b@[300000000...33fffffff] <=> pci@[ c0000000....ffffffff] - memc2-a@[ 80000000....bfffffff] <=> pci@[100000000...13fffffff] - memc2-b@[c00000000...c3fffffff] <=> pci@[140000000...17fffffff] - -Although there are some "gaps" that can be added between the -individual mappings by software, the permutation of memory regions for -the most part is fixed by HW. The solution of having something close -to an identity mapping is not possible. - -The idea behind this HW design is that the same PCIe module can -act as an RC or EP, and if it acts as an EP it concatenates all -of system memory into a BAR so anything can be accessed. Unfortunately, -when the PCIe block is in the role of an RC it also presents this -"BAR" to downstream PCIe devices, rather than offering an identity map -between its system memory and PCIe space. - -Suppose that an endpoint driver allocs some DMA memory. Suppose this -memory is located at 0x6000_0000, which is in the middle of memc1-a. -The driver wants a dma_addr_t value that it can pass on to the EP to -use. Without doing any custom mapping, the EP will use this value for -DMA: the driver will get a dma_addr_t equal to 0x6000_0000. But this -won't work; the device needs a dma_addr_t that reflects the PCIe space -address, namely 0xa000_0000. - -So, essentially the solution to this problem must modify the -dma_addr_t returned by the DMA routines routines. There are two -ways (I know of) of doing this: - -(a) overriding/redefining the dma_to_phys() and phys_to_dma() calls -that are used by the dma_ops routines. This is the approach of - - arch/mips/cavium-octeon/dma-octeon.c - -In ARM and ARM64 these two routines are defiend in asm/dma-mapping.h -as static inline functions. - -(b) Subscribe to a notifier that notifies when a device is added to a -bus. When this happens, set_dma_ops() can be called for the device. -This method is mentioned in: - - http://lxr.free-electrons.com/source/drivers/of/platform.c?v=3.16#L152 - -where it says as a comment - - "In case if platform code need to use own special DMA - configuration, it can use Platform bus notifier and - handle BUS_NOTIFY_ADD_DEVICE event to fix up DMA - configuration." - -Solution (b) is what this commit does. It uses its own set of -dma_ops which are wrappers around the arch_dma_ops. The -wrappers translate the dma addresses before/after invoking -the arch_dma_ops, as appropriate. - -Signed-off-by: Jim Quinlan ---- - drivers/pci/controller/pcie-brcmstb.c | 420 +++++++++++++++++++++++++- - 1 file changed, 411 insertions(+), 9 deletions(-) - ---- a/drivers/pci/controller/pcie-brcmstb.c -+++ b/drivers/pci/controller/pcie-brcmstb.c -@@ -4,6 +4,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -319,11 +320,307 @@ static struct pci_ops brcm_pcie_ops = { - ((val & ~reg##_##field##_MASK) | \ - (reg##_##field##_MASK & (field_val << reg##_##field##_SHIFT))) - -+static const struct dma_map_ops *arch_dma_ops; -+static const struct dma_map_ops *brcm_dma_ops_ptr; -+static struct of_pci_range *dma_ranges; -+static int num_dma_ranges; -+ - static phys_addr_t scb_size[BRCM_MAX_SCB]; - static int num_memc; - static int num_pcie; - static DEFINE_MUTEX(brcm_pcie_lock); - -+static dma_addr_t brcm_to_pci(dma_addr_t addr) -+{ -+ struct of_pci_range *p; -+ -+ if (!num_dma_ranges) -+ return addr; -+ -+ for (p = dma_ranges; p < &dma_ranges[num_dma_ranges]; p++) -+ if (addr >= p->cpu_addr && addr < (p->cpu_addr + p->size)) -+ return addr - p->cpu_addr + p->pci_addr; -+ -+ return addr; -+} -+ -+static dma_addr_t brcm_to_cpu(dma_addr_t addr) -+{ -+ struct of_pci_range *p; -+ -+ if (!num_dma_ranges) -+ return addr; -+ -+ for (p = dma_ranges; p < &dma_ranges[num_dma_ranges]; p++) -+ if (addr >= p->pci_addr && addr < (p->pci_addr + p->size)) -+ return addr - p->pci_addr + p->cpu_addr; -+ -+ return addr; -+} -+ -+static void *brcm_alloc(struct device *dev, size_t size, dma_addr_t *handle, -+ gfp_t gfp, unsigned long attrs) -+{ -+ void *ret; -+ -+ ret = arch_dma_ops->alloc(dev, size, handle, gfp, attrs); -+ if (ret) -+ *handle = brcm_to_pci(*handle); -+ return ret; -+} -+ -+static void brcm_free(struct device *dev, size_t size, void *cpu_addr, -+ dma_addr_t handle, unsigned long attrs) -+{ -+ handle = brcm_to_cpu(handle); -+ arch_dma_ops->free(dev, size, cpu_addr, handle, attrs); -+} -+ -+static int brcm_mmap(struct device *dev, struct vm_area_struct *vma, -+ void *cpu_addr, dma_addr_t dma_addr, size_t size, -+ unsigned long attrs) -+{ -+ dma_addr = brcm_to_cpu(dma_addr); -+ return arch_dma_ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs); -+} -+ -+static int brcm_get_sgtable(struct device *dev, struct sg_table *sgt, -+ void *cpu_addr, dma_addr_t handle, size_t size, -+ unsigned long attrs) -+{ -+ handle = brcm_to_cpu(handle); -+ return arch_dma_ops->get_sgtable(dev, sgt, cpu_addr, handle, size, -+ attrs); -+} -+ -+static dma_addr_t brcm_map_page(struct device *dev, struct page *page, -+ unsigned long offset, size_t size, -+ enum dma_data_direction dir, -+ unsigned long attrs) -+{ -+ return brcm_to_pci(arch_dma_ops->map_page(dev, page, offset, size, -+ dir, attrs)); -+} -+ -+static void brcm_unmap_page(struct device *dev, dma_addr_t handle, -+ size_t size, enum dma_data_direction dir, -+ unsigned long attrs) -+{ -+ handle = brcm_to_cpu(handle); -+ arch_dma_ops->unmap_page(dev, handle, size, dir, attrs); -+} -+ -+static int brcm_map_sg(struct device *dev, struct scatterlist *sgl, -+ int nents, enum dma_data_direction dir, -+ unsigned long attrs) -+{ -+ int i, j; -+ struct scatterlist *sg; -+ -+ for_each_sg(sgl, sg, nents, i) { -+#ifdef CONFIG_NEED_SG_DMA_LENGTH -+ sg->dma_length = sg->length; -+#endif -+ sg->dma_address = -+ brcm_dma_ops_ptr->map_page(dev, sg_page(sg), sg->offset, -+ sg->length, dir, attrs); -+ if (dma_mapping_error(dev, sg->dma_address)) -+ goto bad_mapping; -+ } -+ return nents; -+ -+bad_mapping: -+ for_each_sg(sgl, sg, i, j) -+ brcm_dma_ops_ptr->unmap_page(dev, sg_dma_address(sg), -+ sg_dma_len(sg), dir, attrs); -+ return 0; -+} -+ -+static void brcm_unmap_sg(struct device *dev, -+ struct scatterlist *sgl, int nents, -+ enum dma_data_direction dir, -+ unsigned long attrs) -+{ -+ int i; -+ struct scatterlist *sg; -+ -+ for_each_sg(sgl, sg, nents, i) -+ brcm_dma_ops_ptr->unmap_page(dev, sg_dma_address(sg), -+ sg_dma_len(sg), dir, attrs); -+} -+ -+static void brcm_sync_single_for_cpu(struct device *dev, -+ dma_addr_t handle, size_t size, -+ enum dma_data_direction dir) -+{ -+ handle = brcm_to_cpu(handle); -+ arch_dma_ops->sync_single_for_cpu(dev, handle, size, dir); -+} -+ -+static void brcm_sync_single_for_device(struct device *dev, -+ dma_addr_t handle, size_t size, -+ enum dma_data_direction dir) -+{ -+ handle = brcm_to_cpu(handle); -+ arch_dma_ops->sync_single_for_device(dev, handle, size, dir); -+} -+ -+static dma_addr_t brcm_map_resource(struct device *dev, phys_addr_t phys, -+ size_t size, -+ enum dma_data_direction dir, -+ unsigned long attrs) -+{ -+ if (arch_dma_ops->map_resource) -+ return brcm_to_pci(arch_dma_ops->map_resource -+ (dev, phys, size, dir, attrs)); -+ return brcm_to_pci((dma_addr_t)phys); -+} -+ -+static void brcm_unmap_resource(struct device *dev, dma_addr_t handle, -+ size_t size, enum dma_data_direction dir, -+ unsigned long attrs) -+{ -+ if (arch_dma_ops->unmap_resource) -+ arch_dma_ops->unmap_resource(dev, brcm_to_cpu(handle), size, -+ dir, attrs); -+} -+ -+void brcm_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl, -+ int nents, enum dma_data_direction dir) -+{ -+ struct scatterlist *sg; -+ int i; -+ -+ for_each_sg(sgl, sg, nents, i) -+ brcm_dma_ops_ptr->sync_single_for_cpu(dev, sg_dma_address(sg), -+ sg->length, dir); -+} -+ -+void brcm_sync_sg_for_device(struct device *dev, struct scatterlist *sgl, -+ int nents, enum dma_data_direction dir) -+{ -+ struct scatterlist *sg; -+ int i; -+ -+ for_each_sg(sgl, sg, nents, i) -+ brcm_dma_ops_ptr->sync_single_for_device(dev, -+ sg_dma_address(sg), -+ sg->length, dir); -+} -+ -+static int brcm_mapping_error(struct device *dev, dma_addr_t dma_addr) -+{ -+ return arch_dma_ops->mapping_error(dev, dma_addr); -+} -+ -+static int brcm_dma_supported(struct device *dev, u64 mask) -+{ -+ if (num_dma_ranges) { -+ /* -+ * It is our translated addresses that the EP will "see", so -+ * we check all of the ranges for the largest possible value. -+ */ -+ int i; -+ -+ for (i = 0; i < num_dma_ranges; i++) -+ if (dma_ranges[i].pci_addr + dma_ranges[i].size - 1 -+ > mask) -+ return 0; -+ return 1; -+ } -+ -+ return arch_dma_ops->dma_supported(dev, mask); -+} -+ -+#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK -+u64 brcm_get_required_mask)(struct device *dev) -+{ -+ return arch_dma_ops->get_required_mask(dev); -+} -+#endif -+ -+static const struct dma_map_ops brcm_dma_ops = { -+ .alloc = brcm_alloc, -+ .free = brcm_free, -+ .mmap = brcm_mmap, -+ .get_sgtable = brcm_get_sgtable, -+ .map_page = brcm_map_page, -+ .unmap_page = brcm_unmap_page, -+ .map_sg = brcm_map_sg, -+ .unmap_sg = brcm_unmap_sg, -+ .map_resource = brcm_map_resource, -+ .unmap_resource = brcm_unmap_resource, -+ .sync_single_for_cpu = brcm_sync_single_for_cpu, -+ .sync_single_for_device = brcm_sync_single_for_device, -+ .sync_sg_for_cpu = brcm_sync_sg_for_cpu, -+ .sync_sg_for_device = brcm_sync_sg_for_device, -+ .mapping_error = brcm_mapping_error, -+ .dma_supported = brcm_dma_supported, -+#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK -+ .get_required_mask = brcm_get_required_mask, -+#endif -+}; -+ -+static void brcm_set_dma_ops(struct device *dev) -+{ -+ int ret; -+ -+ if (IS_ENABLED(CONFIG_ARM64)) { -+ /* -+ * We are going to invoke get_dma_ops(). That -+ * function, at this point in time, invokes -+ * get_arch_dma_ops(), and for ARM64 that function -+ * returns a pointer to dummy_dma_ops. So then we'd -+ * like to call arch_setup_dma_ops(), but that isn't -+ * exported. Instead, we call of_dma_configure(), -+ * which is exported, and this calls -+ * arch_setup_dma_ops(). Once we do this the call to -+ * get_dma_ops() will work properly because -+ * dev->dma_ops will be set. -+ */ -+ ret = of_dma_configure(dev, dev->of_node, true); -+ if (ret) { -+ dev_err(dev, "of_dma_configure() failed: %d\n", ret); -+ return; -+ } -+ } -+ -+ arch_dma_ops = get_dma_ops(dev); -+ if (!arch_dma_ops) { -+ dev_err(dev, "failed to get arch_dma_ops\n"); -+ return; -+ } -+ -+ set_dma_ops(dev, &brcm_dma_ops); -+} -+ -+static int brcmstb_platform_notifier(struct notifier_block *nb, -+ unsigned long event, void *__dev) -+{ -+ struct device *dev = __dev; -+ -+ brcm_dma_ops_ptr = &brcm_dma_ops; -+ if (event != BUS_NOTIFY_ADD_DEVICE) -+ return NOTIFY_DONE; -+ -+ brcm_set_dma_ops(dev); -+ return NOTIFY_OK; -+} -+ -+static struct notifier_block brcmstb_platform_nb = { -+ .notifier_call = brcmstb_platform_notifier, -+}; -+ -+static int brcm_register_notifier(void) -+{ -+ return bus_register_notifier(&pci_bus_type, &brcmstb_platform_nb); -+} -+ -+static int brcm_unregister_notifier(void) -+{ -+ return bus_unregister_notifier(&pci_bus_type, &brcmstb_platform_nb); -+} -+ - static u32 rd_fld(void __iomem *p, u32 mask, int shift) - { - return (bcm_readl(p) & mask) >> shift; -@@ -597,9 +894,71 @@ static inline void brcm_pcie_perst_set(s - WR_FLD_RB(pcie->base, PCIE_MISC_PCIE_CTRL, PCIE_PERSTB, !val); - } - -+static int pci_dma_range_parser_init(struct of_pci_range_parser *parser, -+ struct device_node *node) -+{ -+ const int na = 3, ns = 2; -+ int rlen; -+ -+ parser->node = node; -+ parser->pna = of_n_addr_cells(node); -+ parser->np = parser->pna + na + ns; -+ -+ parser->range = of_get_property(node, "dma-ranges", &rlen); -+ if (!parser->range) -+ return -ENOENT; -+ -+ parser->end = parser->range + rlen / sizeof(__be32); -+ -+ return 0; -+} -+ -+static int brcm_pcie_parse_map_dma_ranges(struct brcm_pcie *pcie) -+{ -+ int i; -+ struct of_pci_range_parser parser; -+ struct device_node *dn = pcie->dn; -+ -+ /* -+ * Parse dma-ranges property if present. If there are multiple -+ * PCIe controllers, we only have to parse from one of them since -+ * the others will have an identical mapping. -+ */ -+ if (!pci_dma_range_parser_init(&parser, dn)) { -+ unsigned int max_ranges -+ = (parser.end - parser.range) / parser.np; -+ -+ dma_ranges = kcalloc(max_ranges, sizeof(struct of_pci_range), -+ GFP_KERNEL); -+ if (!dma_ranges) -+ return -ENOMEM; -+ -+ for (i = 0; of_pci_range_parser_one(&parser, dma_ranges + i); -+ i++) -+ num_dma_ranges++; -+ } -+ -+ for (i = 0, num_memc = 0; i < BRCM_MAX_SCB; i++) { -+ u64 size = brcmstb_memory_memc_size(i); -+ -+ if (size == (u64)-1) { -+ dev_err(pcie->dev, "cannot get memc%d size", i); -+ return -EINVAL; -+ } else if (size) { -+ scb_size[i] = roundup_pow_of_two_64(size); -+ num_memc++; -+ } else { -+ break; -+ } -+ } -+ -+ return 0; -+} -+ - static int brcm_pcie_add_controller(struct brcm_pcie *pcie) - { - int i, ret = 0; -+ struct device *dev = pcie->dev; - - mutex_lock(&brcm_pcie_lock); - if (num_pcie > 0) { -@@ -607,12 +966,21 @@ static int brcm_pcie_add_controller(stru - goto done; - } - -+ ret = brcm_register_notifier(); -+ if (ret) { -+ dev_err(dev, "failed to register pci bus notifier\n"); -+ goto done; -+ } -+ ret = brcm_pcie_parse_map_dma_ranges(pcie); -+ if (ret) -+ goto done; -+ - /* Determine num_memc and their sizes */ - for (i = 0, num_memc = 0; i < BRCM_MAX_SCB; i++) { - u64 size = brcmstb_memory_memc_size(i); - - if (size == (u64)-1) { -- dev_err(pcie->dev, "cannot get memc%d size\n", i); -+ dev_err(dev, "cannot get memc%d size\n", i); - ret = -EINVAL; - goto done; - } else if (size) { -@@ -636,8 +1004,16 @@ done: - static void brcm_pcie_remove_controller(struct brcm_pcie *pcie) - { - mutex_lock(&brcm_pcie_lock); -- if (--num_pcie == 0) -- num_memc = 0; -+ if (--num_pcie > 0) -+ goto out; -+ -+ if (brcm_unregister_notifier()) -+ dev_err(pcie->dev, "failed to unregister pci bus notifier\n"); -+ kfree(dma_ranges); -+ dma_ranges = NULL; -+ num_dma_ranges = 0; -+ num_memc = 0; -+out: - mutex_unlock(&brcm_pcie_lock); - } - -@@ -757,6 +1133,38 @@ static int brcm_pcie_setup(struct brcm_p - */ - rc_bar2_offset = 0; - -+ if (dma_ranges) { -+ /* -+ * The best-case scenario is to place the inbound -+ * region in the first 4GB of pci-space, as some -+ * legacy devices can only address 32bits. -+ * We would also like to put the MSI under 4GB -+ * as well, since some devices require a 32bit -+ * MSI target address. -+ */ -+ if (total_mem_size <= 0xc0000000ULL && -+ rc_bar2_size <= 0x100000000ULL) { -+ rc_bar2_offset = 0; -+ } else { -+ /* -+ * The system memory is 4GB or larger so we -+ * cannot start the inbound region at location -+ * 0 (since we have to allow some space for -+ * outbound memory @ 3GB). So instead we -+ * start it at the 1x multiple of its size -+ */ -+ rc_bar2_offset = rc_bar2_size; -+ } -+ -+ } else { -+ /* -+ * Set simple configuration based on memory sizes -+ * only. We always start the viewport at address 0, -+ * and set the MSI target address accordingly. -+ */ -+ rc_bar2_offset = 0; -+ } -+ - tmp = lower_32_bits(rc_bar2_offset); - tmp = INSERT_FIELD(tmp, PCIE_MISC_RC_BAR2_CONFIG_LO, SIZE, - encode_ibar_size(rc_bar2_size)); -@@ -967,7 +1375,6 @@ static int brcm_pcie_probe(struct platfo - struct brcm_pcie *pcie; - struct resource *res; - void __iomem *base; -- u32 tmp; - struct pci_host_bridge *bridge; - struct pci_bus *child; - -@@ -984,11 +1391,6 @@ static int brcm_pcie_probe(struct platfo - return -EINVAL; - } - -- if (of_property_read_u32(dn, "dma-ranges", &tmp) == 0) { -- dev_err(&pdev->dev, "cannot yet handle dma-ranges\n"); -- return -EINVAL; -- } -- - data = of_id->data; - pcie->reg_offsets = data->offsets; - pcie->reg_field_info = data->reg_field_info; diff --git a/target/linux/brcm2708/patches-4.19/950-0535-arm-bcm2835-DMA-can-only-address-1GB.patch b/target/linux/brcm2708/patches-4.19/950-0535-arm-bcm2835-DMA-can-only-address-1GB.patch new file mode 100644 index 0000000000..d589c43d34 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0535-arm-bcm2835-DMA-can-only-address-1GB.patch @@ -0,0 +1,25 @@ +From 873462f7e2a67c2683c916612716b447b2f8f7d7 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 29 May 2019 15:47:42 +0100 +Subject: [PATCH 535/725] arm: bcm2835: DMA can only address 1GB + +The legacy peripherals can only address the first gigabyte of RAM, so +ensure that DMA allocations are restricted to that region. + +Signed-off-by: Phil Elwell +--- + arch/arm/mach-bcm/board_bcm2835.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/arm/mach-bcm/board_bcm2835.c ++++ b/arch/arm/mach-bcm/board_bcm2835.c +@@ -123,6 +123,9 @@ static const char * const bcm2835_compat + }; + + DT_MACHINE_START(BCM2835, "BCM2835") ++#if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE) ++ .dma_zone_size = SZ_1G, ++#endif + .map_io = bcm2835_map_io, + .init_machine = bcm2835_init, + .dt_compat = bcm2835_compat, diff --git a/target/linux/brcm2708/patches-4.19/950-0536-PCI-brcmstb-Add-MSI-capability.patch b/target/linux/brcm2708/patches-4.19/950-0536-PCI-brcmstb-Add-MSI-capability.patch deleted file mode 100644 index f2ed3d8110..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0536-PCI-brcmstb-Add-MSI-capability.patch +++ /dev/null @@ -1,543 +0,0 @@ -From 17f152efa5b5c156df0ff918b38855a1b4efd1e9 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 19 Feb 2019 22:06:59 +0000 -Subject: [PATCH 536/703] PCI: brcmstb: Add MSI capability - -This commit adds MSI to the Broadcom STB PCIe host controller. It does -not add MSIX since that functionality is not in the HW. The MSI -controller is physically located within the PCIe block, however, there -is no reason why the MSI controller could not be moved elsewhere in -the future. - -Since the internal Brcmstb MSI controller is intertwined with the PCIe -controller, it is not its own platform device but rather part of the -PCIe platform device. - -Signed-off-by: Jim Quinlan ---- - drivers/pci/controller/pcie-brcmstb.c | 374 ++++++++++++++++++++++++-- - 1 file changed, 353 insertions(+), 21 deletions(-) - ---- a/drivers/pci/controller/pcie-brcmstb.c -+++ b/drivers/pci/controller/pcie-brcmstb.c -@@ -1,6 +1,7 @@ - // SPDX-License-Identifier: GPL-2.0 - /* Copyright (C) 2009 - 2017 Broadcom */ - -+#include - #include - #include - #include -@@ -9,11 +10,13 @@ - #include - #include - #include -+#include - #include - #include - #include - #include - #include -+#include - #include - #include - #include -@@ -47,6 +50,9 @@ - #define PCIE_MISC_RC_BAR2_CONFIG_LO 0x4034 - #define PCIE_MISC_RC_BAR2_CONFIG_HI 0x4038 - #define PCIE_MISC_RC_BAR3_CONFIG_LO 0x403c -+#define PCIE_MISC_MSI_BAR_CONFIG_LO 0x4044 -+#define PCIE_MISC_MSI_BAR_CONFIG_HI 0x4048 -+#define PCIE_MISC_MSI_DATA_CONFIG 0x404c - #define PCIE_MISC_PCIE_CTRL 0x4064 - #define PCIE_MISC_PCIE_STATUS 0x4068 - #define PCIE_MISC_REVISION 0x406c -@@ -55,6 +61,7 @@ - #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI 0x4084 - #define PCIE_MISC_HARD_PCIE_HARD_DEBUG 0x4204 - #define PCIE_INTR2_CPU_BASE 0x4300 -+#define PCIE_MSI_INTR2_BASE 0x4500 - - /* - * Broadcom Settop Box PCIe Register Field shift and mask info. The -@@ -115,6 +122,8 @@ - - #define BRCM_NUM_PCIE_OUT_WINS 0x4 - #define BRCM_MAX_SCB 0x4 -+#define BRCM_INT_PCI_MSI_NR 32 -+#define BRCM_PCIE_HW_REV_33 0x0303 - - #define BRCM_MSI_TARGET_ADDR_LT_4GB 0x0fffffffcULL - #define BRCM_MSI_TARGET_ADDR_GT_4GB 0xffffffffcULL -@@ -203,6 +212,33 @@ struct brcm_window { - dma_addr_t size; - }; - -+struct brcm_msi { -+ struct device *dev; -+ void __iomem *base; -+ struct device_node *dn; -+ struct irq_domain *msi_domain; -+ struct irq_domain *inner_domain; -+ struct mutex lock; /* guards the alloc/free operations */ -+ u64 target_addr; -+ int irq; -+ -+ /* intr_base is the base pointer for interrupt status/set/clr regs */ -+ void __iomem *intr_base; -+ -+ /* intr_legacy_mask indicates how many bits are MSI interrupts */ -+ u32 intr_legacy_mask; -+ -+ /* -+ * intr_legacy_offset indicates bit position of MSI_01. It is -+ * to map the register bit position to a hwirq that starts at 0. -+ */ -+ u32 intr_legacy_offset; -+ -+ /* used indicates which MSI interrupts have been alloc'd */ -+ unsigned long used; -+ unsigned int rev; -+}; -+ - /* Internal PCIe Host Controller Information.*/ - struct brcm_pcie { - struct device *dev; -@@ -217,7 +253,10 @@ struct brcm_pcie { - int num_out_wins; - bool ssc; - int gen; -+ u64 msi_target_addr; - struct brcm_window out_wins[BRCM_NUM_PCIE_OUT_WINS]; -+ struct brcm_msi *msi; -+ bool msi_internal; - unsigned int rev; - const int *reg_offsets; - const int *reg_field_info; -@@ -225,9 +264,9 @@ struct brcm_pcie { - }; - - struct pcie_cfg_data { -- const int *reg_field_info; -- const int *offsets; -- const enum pcie_type type; -+ const int *reg_field_info; -+ const int *offsets; -+ const enum pcie_type type; - }; - - static const int pcie_reg_field_info[] = { -@@ -828,6 +867,267 @@ static void brcm_pcie_set_outbound_win(s - } - } - -+static struct irq_chip brcm_msi_irq_chip = { -+ .name = "Brcm_MSI", -+ .irq_mask = pci_msi_mask_irq, -+ .irq_unmask = pci_msi_unmask_irq, -+}; -+ -+static struct msi_domain_info brcm_msi_domain_info = { -+ .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | -+ MSI_FLAG_PCI_MSIX), -+ .chip = &brcm_msi_irq_chip, -+}; -+ -+static void brcm_pcie_msi_isr(struct irq_desc *desc) -+{ -+ struct irq_chip *chip = irq_desc_get_chip(desc); -+ struct brcm_msi *msi; -+ unsigned long status, virq; -+ u32 mask, bit, hwirq; -+ struct device *dev; -+ -+ chained_irq_enter(chip, desc); -+ msi = irq_desc_get_handler_data(desc); -+ mask = msi->intr_legacy_mask; -+ dev = msi->dev; -+ -+ while ((status = bcm_readl(msi->intr_base + STATUS) & mask)) { -+ for_each_set_bit(bit, &status, BRCM_INT_PCI_MSI_NR) { -+ /* clear the interrupt */ -+ bcm_writel(1 << bit, msi->intr_base + CLR); -+ -+ /* Account for legacy interrupt offset */ -+ hwirq = bit - msi->intr_legacy_offset; -+ -+ virq = irq_find_mapping(msi->inner_domain, hwirq); -+ if (virq) { -+ if (msi->used & (1 << hwirq)) -+ generic_handle_irq(virq); -+ else -+ dev_info(dev, "unhandled MSI %d\n", -+ hwirq); -+ } else { -+ /* Unknown MSI, just clear it */ -+ dev_dbg(dev, "unexpected MSI\n"); -+ } -+ } -+ } -+ chained_irq_exit(chip, desc); -+} -+ -+static void brcm_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) -+{ -+ struct brcm_msi *msi = irq_data_get_irq_chip_data(data); -+ u32 temp; -+ -+ msg->address_lo = lower_32_bits(msi->target_addr); -+ msg->address_hi = upper_32_bits(msi->target_addr); -+ temp = bcm_readl(msi->base + PCIE_MISC_MSI_DATA_CONFIG); -+ msg->data = ((temp >> 16) & (temp & 0xffff)) | data->hwirq; -+} -+ -+static int brcm_msi_set_affinity(struct irq_data *irq_data, -+ const struct cpumask *mask, bool force) -+{ -+ return -EINVAL; -+} -+ -+static struct irq_chip brcm_msi_bottom_irq_chip = { -+ .name = "Brcm_MSI", -+ .irq_compose_msi_msg = brcm_compose_msi_msg, -+ .irq_set_affinity = brcm_msi_set_affinity, -+}; -+ -+static int brcm_msi_alloc(struct brcm_msi *msi) -+{ -+ int bit, hwirq; -+ -+ mutex_lock(&msi->lock); -+ bit = ~msi->used ? ffz(msi->used) : -1; -+ -+ if (bit >= 0 && bit < BRCM_INT_PCI_MSI_NR) { -+ msi->used |= (1 << bit); -+ hwirq = bit - msi->intr_legacy_offset; -+ } else { -+ hwirq = -ENOSPC; -+ } -+ -+ mutex_unlock(&msi->lock); -+ return hwirq; -+} -+ -+static void brcm_msi_free(struct brcm_msi *msi, unsigned long hwirq) -+{ -+ mutex_lock(&msi->lock); -+ msi->used &= ~(1 << (hwirq + msi->intr_legacy_offset)); -+ mutex_unlock(&msi->lock); -+} -+ -+static int brcm_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, -+ unsigned int nr_irqs, void *args) -+{ -+ struct brcm_msi *msi = domain->host_data; -+ int hwirq; -+ -+ hwirq = brcm_msi_alloc(msi); -+ -+ if (hwirq < 0) -+ return hwirq; -+ -+ irq_domain_set_info(domain, virq, (irq_hw_number_t)hwirq, -+ &brcm_msi_bottom_irq_chip, domain->host_data, -+ handle_simple_irq, NULL, NULL); -+ return 0; -+} -+ -+static void brcm_irq_domain_free(struct irq_domain *domain, -+ unsigned int virq, unsigned int nr_irqs) -+{ -+ struct irq_data *d = irq_domain_get_irq_data(domain, virq); -+ struct brcm_msi *msi = irq_data_get_irq_chip_data(d); -+ -+ brcm_msi_free(msi, d->hwirq); -+} -+ -+static void brcm_msi_set_regs(struct brcm_msi *msi) -+{ -+ u32 data_val, msi_lo, msi_hi; -+ -+ if (msi->rev >= BRCM_PCIE_HW_REV_33) { -+ /* -+ * ffe0 -- least sig 5 bits are 0 indicating 32 msgs -+ * 6540 -- this is our arbitrary unique data value -+ */ -+ data_val = 0xffe06540; -+ } else { -+ /* -+ * fff8 -- least sig 3 bits are 0 indicating 8 msgs -+ * 6540 -- this is our arbitrary unique data value -+ */ -+ data_val = 0xfff86540; -+ } -+ -+ /* -+ * Make sure we are not masking MSIs. Note that MSIs can be masked, -+ * but that occurs on the PCIe EP device -+ */ -+ bcm_writel(0xffffffff & msi->intr_legacy_mask, -+ msi->intr_base + MASK_CLR); -+ -+ msi_lo = lower_32_bits(msi->target_addr); -+ msi_hi = upper_32_bits(msi->target_addr); -+ /* -+ * The 0 bit of PCIE_MISC_MSI_BAR_CONFIG_LO is repurposed to MSI -+ * enable, which we set to 1. -+ */ -+ bcm_writel(msi_lo | 1, msi->base + PCIE_MISC_MSI_BAR_CONFIG_LO); -+ bcm_writel(msi_hi, msi->base + PCIE_MISC_MSI_BAR_CONFIG_HI); -+ bcm_writel(data_val, msi->base + PCIE_MISC_MSI_DATA_CONFIG); -+} -+ -+static const struct irq_domain_ops msi_domain_ops = { -+ .alloc = brcm_irq_domain_alloc, -+ .free = brcm_irq_domain_free, -+}; -+ -+static int brcm_allocate_domains(struct brcm_msi *msi) -+{ -+ struct fwnode_handle *fwnode = of_node_to_fwnode(msi->dn); -+ struct device *dev = msi->dev; -+ -+ msi->inner_domain = irq_domain_add_linear(NULL, BRCM_INT_PCI_MSI_NR, -+ &msi_domain_ops, msi); -+ if (!msi->inner_domain) { -+ dev_err(dev, "failed to create IRQ domain\n"); -+ return -ENOMEM; -+ } -+ -+ msi->msi_domain = pci_msi_create_irq_domain(fwnode, -+ &brcm_msi_domain_info, -+ msi->inner_domain); -+ if (!msi->msi_domain) { -+ dev_err(dev, "failed to create MSI domain\n"); -+ irq_domain_remove(msi->inner_domain); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+static void brcm_free_domains(struct brcm_msi *msi) -+{ -+ irq_domain_remove(msi->msi_domain); -+ irq_domain_remove(msi->inner_domain); -+} -+ -+static void brcm_msi_remove(struct brcm_pcie *pcie) -+{ -+ struct brcm_msi *msi = pcie->msi; -+ -+ if (!msi) -+ return; -+ irq_set_chained_handler(msi->irq, NULL); -+ irq_set_handler_data(msi->irq, NULL); -+ brcm_free_domains(msi); -+} -+ -+static int brcm_pcie_enable_msi(struct brcm_pcie *pcie) -+{ -+ struct brcm_msi *msi; -+ int irq, ret; -+ struct device *dev = pcie->dev; -+ -+ irq = irq_of_parse_and_map(dev->of_node, 1); -+ if (irq <= 0) { -+ dev_err(dev, "cannot map msi intr\n"); -+ return -ENODEV; -+ } -+ -+ msi = devm_kzalloc(dev, sizeof(struct brcm_msi), GFP_KERNEL); -+ if (!msi) -+ return -ENOMEM; -+ -+ msi->dev = dev; -+ msi->base = pcie->base; -+ msi->rev = pcie->rev; -+ msi->dn = pcie->dn; -+ msi->target_addr = pcie->msi_target_addr; -+ msi->irq = irq; -+ -+ ret = brcm_allocate_domains(msi); -+ if (ret) -+ return ret; -+ -+ irq_set_chained_handler_and_data(msi->irq, brcm_pcie_msi_isr, msi); -+ -+ if (msi->rev >= BRCM_PCIE_HW_REV_33) { -+ msi->intr_base = msi->base + PCIE_MSI_INTR2_BASE; -+ /* -+ * This version of PCIe hw has only 32 intr bits -+ * starting at bit position 0. -+ */ -+ msi->intr_legacy_mask = 0xffffffff; -+ msi->intr_legacy_offset = 0x0; -+ msi->used = 0x0; -+ -+ } else { -+ msi->intr_base = msi->base + PCIE_INTR2_CPU_BASE; -+ /* -+ * This version of PCIe hw has only 8 intr bits starting -+ * at bit position 24. -+ */ -+ msi->intr_legacy_mask = 0xff000000; -+ msi->intr_legacy_offset = 24; -+ msi->used = 0x00ffffff; -+ } -+ -+ brcm_msi_set_regs(msi); -+ pcie->msi = msi; -+ -+ return 0; -+} -+ - /* Configuration space read/write support */ - static int cfg_index(int busnr, int devfn, int reg) - { -@@ -1072,6 +1372,7 @@ static int brcm_pcie_setup(struct brcm_p - u16 nlw, cls, lnksta; - bool ssc_good = false; - struct device *dev = pcie->dev; -+ u64 msi_target_addr; - - /* Reset the bridge */ - brcm_pcie_bridge_sw_init_set(pcie, 1); -@@ -1116,27 +1417,24 @@ static int brcm_pcie_setup(struct brcm_p - * The PCIe host controller by design must set the inbound - * viewport to be a contiguous arrangement of all of the - * system's memory. In addition, its size mut be a power of -- * two. To further complicate matters, the viewport must -- * start on a pcie-address that is aligned on a multiple of its -- * size. If a portion of the viewport does not represent -- * system memory -- e.g. 3GB of memory requires a 4GB viewport -- * -- we can map the outbound memory in or after 3GB and even -- * though the viewport will overlap the outbound memory the -- * controller will know to send outbound memory downstream and -- * everything else upstream. -+ * two. Further, the MSI target address must NOT be placed -+ * inside this region, as the decoding logic will consider its -+ * address to be inbound memory traffic. To further -+ * complicate matters, the viewport must start on a -+ * pcie-address that is aligned on a multiple of its size. -+ * If a portion of the viewport does not represent system -+ * memory -- e.g. 3GB of memory requires a 4GB viewport -- -+ * we can map the outbound memory in or after 3GB and even -+ * though the viewport will overlap the outbound memory -+ * the controller will know to send outbound memory downstream -+ * and everything else upstream. - */ - rc_bar2_size = roundup_pow_of_two_64(total_mem_size); - -- /* -- * Set simple configuration based on memory sizes -- * only. We always start the viewport at address 0. -- */ -- rc_bar2_offset = 0; -- - if (dma_ranges) { - /* - * The best-case scenario is to place the inbound -- * region in the first 4GB of pci-space, as some -+ * region in the first 4GB of pcie-space, as some - * legacy devices can only address 32bits. - * We would also like to put the MSI under 4GB - * as well, since some devices require a 32bit -@@ -1145,6 +1443,14 @@ static int brcm_pcie_setup(struct brcm_p - if (total_mem_size <= 0xc0000000ULL && - rc_bar2_size <= 0x100000000ULL) { - rc_bar2_offset = 0; -+ /* If the viewport is less then 4GB we can fit -+ * the MSI target address under 4GB. Otherwise -+ * put it right below 64GB. -+ */ -+ msi_target_addr = -+ (rc_bar2_size == 0x100000000ULL) -+ ? BRCM_MSI_TARGET_ADDR_GT_4GB -+ : BRCM_MSI_TARGET_ADDR_LT_4GB; - } else { - /* - * The system memory is 4GB or larger so we -@@ -1154,8 +1460,12 @@ static int brcm_pcie_setup(struct brcm_p - * start it at the 1x multiple of its size - */ - rc_bar2_offset = rc_bar2_size; -- } - -+ /* Since we are starting the viewport at 4GB or -+ * higher, put the MSI target address below 4GB -+ */ -+ msi_target_addr = BRCM_MSI_TARGET_ADDR_LT_4GB; -+ } - } else { - /* - * Set simple configuration based on memory sizes -@@ -1163,7 +1473,12 @@ static int brcm_pcie_setup(struct brcm_p - * and set the MSI target address accordingly. - */ - rc_bar2_offset = 0; -+ -+ msi_target_addr = (rc_bar2_size >= 0x100000000ULL) -+ ? BRCM_MSI_TARGET_ADDR_GT_4GB -+ : BRCM_MSI_TARGET_ADDR_LT_4GB; - } -+ pcie->msi_target_addr = msi_target_addr; - - tmp = lower_32_bits(rc_bar2_offset); - tmp = INSERT_FIELD(tmp, PCIE_MISC_RC_BAR2_CONFIG_LO, SIZE, -@@ -1333,6 +1648,9 @@ static int brcm_pcie_resume(struct devic - if (ret) - return ret; - -+ if (pcie->msi && pcie->msi_internal) -+ brcm_msi_set_regs(pcie->msi); -+ - pcie->suspended = false; - - return 0; -@@ -1340,6 +1658,7 @@ static int brcm_pcie_resume(struct devic - - static void _brcm_pcie_remove(struct brcm_pcie *pcie) - { -+ brcm_msi_remove(pcie); - turn_off(pcie); - clk_disable_unprepare(pcie->clk); - clk_put(pcie->clk); -@@ -1368,7 +1687,7 @@ MODULE_DEVICE_TABLE(of, brcm_pcie_match) - - static int brcm_pcie_probe(struct platform_device *pdev) - { -- struct device_node *dn = pdev->dev.of_node; -+ struct device_node *dn = pdev->dev.of_node, *msi_dn; - const struct of_device_id *of_id; - const struct pcie_cfg_data *data; - int ret; -@@ -1448,6 +1767,20 @@ static int brcm_pcie_probe(struct platfo - if (ret) - goto fail; - -+ msi_dn = of_parse_phandle(pcie->dn, "msi-parent", 0); -+ /* Use the internal MSI if no msi-parent property */ -+ if (!msi_dn) -+ msi_dn = pcie->dn; -+ -+ if (pci_msi_enabled() && msi_dn == pcie->dn) { -+ ret = brcm_pcie_enable_msi(pcie); -+ if (ret) -+ dev_err(pcie->dev, -+ "probe of internal MSI failed: %d)", ret); -+ else -+ pcie->msi_internal = true; -+ } -+ - list_splice_init(&pcie->resources, &bridge->windows); - bridge->dev.parent = &pdev->dev; - bridge->busnr = 0; -@@ -1470,7 +1803,6 @@ static int brcm_pcie_probe(struct platfo - pcie->root_bus = bridge->bus; - - return 0; -- - fail: - _brcm_pcie_remove(pcie); - return ret; diff --git a/target/linux/brcm2708/patches-4.19/950-0536-mmc-bcm2835-sdhost-Support-64-bit-physical-addresses.patch b/target/linux/brcm2708/patches-4.19/950-0536-mmc-bcm2835-sdhost-Support-64-bit-physical-addresses.patch new file mode 100644 index 0000000000..5fe7a86496 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0536-mmc-bcm2835-sdhost-Support-64-bit-physical-addresses.patch @@ -0,0 +1,56 @@ +From beea04563e4d7df06d5cec9bae2171e7eca643b1 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 29 Aug 2018 09:05:15 +0100 +Subject: [PATCH 536/725] mmc: bcm2835-sdhost: Support 64-bit physical + addresses + +Signed-off-by: Phil Elwell +--- + drivers/mmc/host/bcm2835-sdhost.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/mmc/host/bcm2835-sdhost.c ++++ b/drivers/mmc/host/bcm2835-sdhost.c +@@ -148,7 +148,7 @@ struct bcm2835_host { + spinlock_t lock; + + void __iomem *ioaddr; +- u32 bus_addr; ++ phys_addr_t bus_addr; + + struct mmc_host *mmc; + +@@ -246,8 +246,8 @@ static void log_init(struct device *dev, + sdhost_log_buf = dma_zalloc_coherent(dev, LOG_SIZE, &sdhost_log_addr, + GFP_KERNEL); + if (sdhost_log_buf) { +- pr_info("sdhost: log_buf @ %p (%x)\n", +- sdhost_log_buf, (u32)sdhost_log_addr); ++ pr_info("sdhost: log_buf @ %p (%llx)\n", ++ sdhost_log_buf, (u64)sdhost_log_addr); + timer_base = ioremap_nocache(bus_to_phys + 0x7e003000, SZ_4K); + if (!timer_base) + pr_err("sdhost: failed to remap timer\n"); +@@ -2024,6 +2024,7 @@ static int bcm2835_sdhost_probe(struct p + struct mmc_host *mmc; + const __be32 *addr; + u32 msg[3]; ++ int na; + int ret; + + pr_debug("bcm2835_sdhost_probe\n"); +@@ -2047,12 +2048,13 @@ static int bcm2835_sdhost_probe(struct p + goto err; + } + ++ na = of_n_addr_cells(node); + addr = of_get_address(node, 0, NULL, NULL); + if (!addr) { + dev_err(dev, "could not get DMA-register address\n"); + return -ENODEV; + } +- host->bus_addr = be32_to_cpup(addr); ++ host->bus_addr = (phys_addr_t)of_read_number(addr, na); + pr_debug(" - ioaddr %lx, iomem->start %lx, bus_addr %lx\n", + (unsigned long)host->ioaddr, + (unsigned long)iomem->start, diff --git a/target/linux/brcm2708/patches-4.19/950-0537-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch b/target/linux/brcm2708/patches-4.19/950-0537-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch deleted file mode 100644 index fec88b7688..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0537-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch +++ /dev/null @@ -1,77 +0,0 @@ -From ed5b4725bde9d0067ac2a1098756ff5abfa13798 Mon Sep 17 00:00:00 2001 -From: Jim Quinlan -Date: Mon, 15 Jan 2018 18:28:39 -0500 -Subject: [PATCH 537/703] dt-bindings: pci: Add DT docs for Brcmstb PCIe device - -The DT bindings description of the Brcmstb PCIe device is described. This -node can be used by almost all Broadcom settop box chips, using -ARM, ARM64, or MIPS CPU architectures. - -Signed-off-by: Jim Quinlan ---- - .../devicetree/bindings/pci/brcmstb-pcie.txt | 59 +++++++++++++++++++ - 1 file changed, 59 insertions(+) - create mode 100644 Documentation/devicetree/bindings/pci/brcmstb-pcie.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/pci/brcmstb-pcie.txt -@@ -0,0 +1,59 @@ -+Brcmstb PCIe Host Controller Device Tree Bindings -+ -+Required Properties: -+- compatible -+ "brcm,bcm7425-pcie" -- for 7425 family MIPS-based SOCs. -+ "brcm,bcm7435-pcie" -- for 7435 family MIPS-based SOCs. -+ "brcm,bcm7445-pcie" -- for 7445 and later ARM based SOCs (not including -+ the 7278). -+ "brcm,bcm7278-pcie" -- for 7278 family ARM-based SOCs. -+ -+- reg -- the register start address and length for the PCIe reg block. -+- interrupts -- two interrupts are specified; the first interrupt is for -+ the PCI host controller and the second is for MSI if the built-in -+ MSI controller is to be used. -+- interrupt-names -- names of the interrupts (above): "pcie" and "msi". -+- #address-cells -- set to <3>. -+- #size-cells -- set to <2>. -+- #interrupt-cells: set to <1>. -+- interrupt-map-mask and interrupt-map, standard PCI properties to define the -+ mapping of the PCIe interface to interrupt numbers. -+- ranges: ranges for the PCI memory and I/O regions. -+- linux,pci-domain -- should be unique per host controller. -+ -+Optional Properties: -+- clocks -- phandle of pcie clock. -+- clock-names -- set to "sw_pcie" if clocks is used. -+- dma-ranges -- Specifies the inbound memory mapping regions when -+ an "identity map" is not possible. -+- msi-controller -- this property is typically specified to have the -+ PCIe controller use its internal MSI controller. -+- msi-parent -- set to use an external MSI interrupt controller. -+- brcm,enable-ssc -- (boolean) indicates usage of spread-spectrum clocking. -+- max-link-speed -- (integer) indicates desired generation of link: -+ 1 => 2.5 Gbps (gen1), 2 => 5.0 Gbps (gen2), 3 => 8.0 Gbps (gen3). -+ -+Example Node: -+ -+pcie0: pcie@f0460000 { -+ reg = <0x0 0xf0460000 0x0 0x9310>; -+ interrupts = <0x0 0x0 0x4>; -+ compatible = "brcm,bcm7445-pcie"; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ ranges = <0x02000000 0x00000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x08000000 -+ 0x02000000 0x00000000 0x08000000 0x00000000 0xc8000000 0x00000000 0x08000000>; -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 7>; -+ interrupt-map = <0 0 0 1 &intc 0 47 3 -+ 0 0 0 2 &intc 0 48 3 -+ 0 0 0 3 &intc 0 49 3 -+ 0 0 0 4 &intc 0 50 3>; -+ clocks = <&sw_pcie0>; -+ clock-names = "sw_pcie"; -+ msi-parent = <&pcie0>; /* use PCIe's internal MSI controller */ -+ msi-controller; /* use PCIe's internal MSI controller */ -+ brcm,ssc; -+ max-link-speed = <1>; -+ linux,pci-domain = <0>; -+ }; diff --git a/target/linux/brcm2708/patches-4.19/950-0537-mmc-sdhci-Mask-spurious-interrupts.patch b/target/linux/brcm2708/patches-4.19/950-0537-mmc-sdhci-Mask-spurious-interrupts.patch new file mode 100644 index 0000000000..ba5f5132fb --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0537-mmc-sdhci-Mask-spurious-interrupts.patch @@ -0,0 +1,29 @@ +From b0aa16d75f422fb369696520189c9fa7b0b12e60 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 28 Sep 2018 16:24:05 +0100 +Subject: [PATCH 537/725] mmc: sdhci: Mask "spurious" interrupts + +Add a filter for "spurious" Transfer Complete interrupts, attempting +to make it as specific as possible: +* INT_DATA_END (transfer complete) is set +* There is a stop command in progress +* There is no data transfer in progress + +Signed-off-by: Phil Elwell +--- + drivers/mmc/host/sdhci.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -2930,6 +2930,10 @@ static irqreturn_t sdhci_irq(int irq, vo + result = IRQ_WAKE_THREAD; + } + ++ if ((intmask & SDHCI_INT_DATA_END) && !host->data && ++ host->cmd && (host->cmd == host->cmd->mrq->stop)) ++ intmask &= ~SDHCI_INT_DATA_END; ++ + if (intmask & SDHCI_INT_CMD_MASK) + sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK, &intmask); + diff --git a/target/linux/brcm2708/patches-4.19/950-0538-mmc-sdhci-iproc-Add-support-for-emmc2-of-the-BCM2838.patch b/target/linux/brcm2708/patches-4.19/950-0538-mmc-sdhci-iproc-Add-support-for-emmc2-of-the-BCM2838.patch new file mode 100644 index 0000000000..5248a5d3bd --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0538-mmc-sdhci-iproc-Add-support-for-emmc2-of-the-BCM2838.patch @@ -0,0 +1,36 @@ +From 1224508f6ea00a9f730d394cf5f482acccbb9e88 Mon Sep 17 00:00:00 2001 +From: Stefan Wahren +Date: Sat, 27 Apr 2019 12:33:57 +0200 +Subject: [PATCH 538/725] mmc: sdhci-iproc: Add support for emmc2 of the + BCM2838 + +The emmc2 interface of the BCM2838 should be integrated in sdhci-iproc +to avoid code redundancy. Except 32 bit only access no other quirks are +known yet. Add an additional compatible string for upstream proposal. + +Signed-off-by: Stefan Wahren +--- + drivers/mmc/host/sdhci-iproc.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/mmc/host/sdhci-iproc.c ++++ b/drivers/mmc/host/sdhci-iproc.c +@@ -250,8 +250,18 @@ static const struct sdhci_iproc_data bcm + .mmc_caps = 0x00000000, + }; + ++static const struct sdhci_pltfm_data sdhci_bcm2838_pltfm_data = { ++ .ops = &sdhci_iproc_32only_ops, ++}; ++ ++static const struct sdhci_iproc_data bcm2838_data = { ++ .pdata = &sdhci_bcm2838_pltfm_data, ++}; ++ + static const struct of_device_id sdhci_iproc_of_match[] = { + { .compatible = "brcm,bcm2835-sdhci", .data = &bcm2835_data }, ++ { .compatible = "brcm,bcm2838-sdhci", .data = &bcm2838_data }, ++ { .compatible = "brcm,bcm2711-emmc2", .data = &bcm2838_data }, + { .compatible = "brcm,sdhci-iproc-cygnus", .data = &iproc_cygnus_data}, + { .compatible = "brcm,sdhci-iproc", .data = &iproc_data }, + { } diff --git a/target/linux/brcm2708/patches-4.19/950-0538-pcie-brcmstb-Changes-for-BCM2711.patch b/target/linux/brcm2708/patches-4.19/950-0538-pcie-brcmstb-Changes-for-BCM2711.patch deleted file mode 100644 index f622986dd7..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0538-pcie-brcmstb-Changes-for-BCM2711.patch +++ /dev/null @@ -1,1411 +0,0 @@ -From 20675667235d3f454db422f8fbc296605195647e Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 19 Feb 2019 22:06:59 +0000 -Subject: [PATCH 538/703] pcie-brcmstb: Changes for BCM2711 - -The initial brcmstb PCIe driver - originally taken from the V3(?) -patch set - has been modified significantly for the BCM2711. - -Signed-off-by: Phil Elwell ---- - drivers/dma/bcm2835-dma.c | 107 ++++ - drivers/pci/controller/Makefile | 4 + - drivers/pci/controller/pcie-brcmstb-bounce.c | 564 +++++++++++++++++++ - drivers/pci/controller/pcie-brcmstb-bounce.h | 32 ++ - drivers/pci/controller/pcie-brcmstb.c | 237 ++++---- - drivers/soc/bcm/brcmstb/Makefile | 2 +- - drivers/soc/bcm/brcmstb/memory.c | 158 ++++++ - 7 files changed, 996 insertions(+), 108 deletions(-) - create mode 100644 drivers/pci/controller/pcie-brcmstb-bounce.c - create mode 100644 drivers/pci/controller/pcie-brcmstb-bounce.h - create mode 100644 drivers/soc/bcm/brcmstb/memory.c - ---- a/drivers/dma/bcm2835-dma.c -+++ b/drivers/dma/bcm2835-dma.c -@@ -68,6 +68,17 @@ struct bcm2835_dma_cb { - uint32_t pad[2]; - }; - -+struct bcm2838_dma40_scb { -+ uint32_t ti; -+ uint32_t src; -+ uint32_t srci; -+ uint32_t dst; -+ uint32_t dsti; -+ uint32_t len; -+ uint32_t next_cb; -+ uint32_t rsvd; -+}; -+ - struct bcm2835_cb_entry { - struct bcm2835_dma_cb *cb; - dma_addr_t paddr; -@@ -185,6 +196,45 @@ struct bcm2835_desc { - #define MAX_DMA_LEN SZ_1G - #define MAX_LITE_DMA_LEN (SZ_64K - 4) - -+/* 40-bit DMA support */ -+#define BCM2838_DMA40_CS 0x00 -+#define BCM2838_DMA40_CB 0x04 -+#define BCM2838_DMA40_DEBUG 0x0c -+#define BCM2858_DMA40_TI 0x10 -+#define BCM2838_DMA40_SRC 0x14 -+#define BCM2838_DMA40_SRCI 0x18 -+#define BCM2838_DMA40_DEST 0x1c -+#define BCM2838_DMA40_DESTI 0x20 -+#define BCM2838_DMA40_LEN 0x24 -+#define BCM2838_DMA40_NEXT_CB 0x28 -+#define BCM2838_DMA40_DEBUG2 0x2c -+ -+#define BCM2838_DMA40_CS_ACTIVE BIT(0) -+#define BCM2838_DMA40_CS_END BIT(1) -+ -+#define BCM2838_DMA40_CS_QOS(x) (((x) & 0x1f) << 16) -+#define BCM2838_DMA40_CS_PANIC_QOS(x) (((x) & 0x1f) << 20) -+#define BCM2838_DMA40_CS_WRITE_WAIT BIT(28) -+ -+#define BCM2838_DMA40_BURST_LEN(x) ((((x) - 1) & 0xf) << 8) -+#define BCM2838_DMA40_INC BIT(12) -+#define BCM2838_DMA40_SIZE_128 (2 << 13) -+ -+#define BCM2838_DMA40_MEMCPY_QOS \ -+ (BCM2838_DMA40_CS_QOS(0x0) | \ -+ BCM2838_DMA40_CS_PANIC_QOS(0x0) | \ -+ BCM2838_DMA40_CS_WRITE_WAIT) -+ -+#define BCM2838_DMA40_MEMCPY_XFER_INFO \ -+ (BCM2838_DMA40_SIZE_128 | \ -+ BCM2838_DMA40_INC | \ -+ BCM2838_DMA40_BURST_LEN(16)) -+ -+static void __iomem *memcpy_chan; -+static struct bcm2838_dma40_scb *memcpy_scb; -+static dma_addr_t memcpy_scb_dma; -+DEFINE_SPINLOCK(memcpy_lock); -+ - static inline size_t bcm2835_dma_max_frame_length(struct bcm2835_chan *c) - { - /* lite and normal channels have different max frame length */ -@@ -868,6 +918,56 @@ static void bcm2835_dma_free(struct bcm2 - } - } - -+int bcm2838_dma40_memcpy_init(struct device *dev) -+{ -+ if (memcpy_scb) -+ return 0; -+ -+ memcpy_scb = dma_alloc_coherent(dev, sizeof(*memcpy_scb), -+ &memcpy_scb_dma, GFP_KERNEL); -+ -+ if (!memcpy_scb) { -+ pr_err("bcm2838_dma40_memcpy_init failed!\n"); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(bcm2838_dma40_memcpy_init); -+ -+void bcm2838_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size) -+{ -+ struct bcm2838_dma40_scb *scb = memcpy_scb; -+ unsigned long flags; -+ -+ if (!scb) { -+ pr_err("bcm2838_dma40_memcpy not initialised!\n"); -+ return; -+ } -+ -+ spin_lock_irqsave(&memcpy_lock, flags); -+ -+ scb->ti = 0; -+ scb->src = lower_32_bits(src); -+ scb->srci = upper_32_bits(src) | BCM2838_DMA40_MEMCPY_XFER_INFO; -+ scb->dst = lower_32_bits(dst); -+ scb->dsti = upper_32_bits(dst) | BCM2838_DMA40_MEMCPY_XFER_INFO; -+ scb->len = size; -+ scb->next_cb = 0; -+ -+ writel((u32)(memcpy_scb_dma >> 5), memcpy_chan + BCM2838_DMA40_CB); -+ writel(BCM2838_DMA40_MEMCPY_QOS + BCM2838_DMA40_CS_ACTIVE, -+ memcpy_chan + BCM2838_DMA40_CS); -+ /* Poll for completion */ -+ while (!(readl(memcpy_chan + BCM2838_DMA40_CS) & BCM2838_DMA40_CS_END)) -+ cpu_relax(); -+ -+ writel(BCM2838_DMA40_CS_END, memcpy_chan + BCM2838_DMA40_CS); -+ -+ spin_unlock_irqrestore(&memcpy_lock, flags); -+} -+EXPORT_SYMBOL(bcm2838_dma40_memcpy); -+ - static const struct of_device_id bcm2835_dma_of_match[] = { - { .compatible = "brcm,bcm2835-dma", }, - {}, -@@ -964,6 +1064,13 @@ static int bcm2835_dma_probe(struct plat - /* Channel 0 is used by the legacy API */ - chans_available &= ~BCM2835_DMA_BULK_MASK; - -+ /* We can't use channels 11-13 yet */ -+ chans_available &= ~(BIT(11) | BIT(12) | BIT(13)); -+ -+ /* Grab channel 14 for the 40-bit DMA memcpy */ -+ chans_available &= ~BIT(14); -+ memcpy_chan = BCM2835_DMA_CHANIO(base, 14); -+ - /* get irqs for each channel that we support */ - for (i = 0; i <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; i++) { - /* skip masked out channels */ ---- a/drivers/pci/controller/Makefile -+++ b/drivers/pci/controller/Makefile -@@ -29,6 +29,10 @@ obj-$(CONFIG_PCIE_MEDIATEK) += pcie-medi - obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o - obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o - obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o -+ifdef CONFIG_ARM -+obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb-bounce.o -+endif -+ - obj-$(CONFIG_VMD) += vmd.o - # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW - obj-y += dwc/ ---- /dev/null -+++ b/drivers/pci/controller/pcie-brcmstb-bounce.c -@@ -0,0 +1,564 @@ -+/* -+ * This code started out as a version of arch/arm/common/dmabounce.c, -+ * modified to cope with highmem pages. Now it has been changed heavily - -+ * it now preallocates a large block (currently 4MB) and carves it up -+ * sequentially in ring fashion, and DMA is used to copy the data - to the -+ * point where very little of the original remains. -+ * -+ * Copyright (C) 2019 Raspberry Pi (Trading) Ltd. -+ * -+ * Original version by Brad Parker (brad@heeltoe.com) -+ * Re-written by Christopher Hoover -+ * Made generic by Deepak Saxena -+ * -+ * Copyright (C) 2002 Hewlett Packard Company. -+ * Copyright (C) 2004 MontaVista Software, Inc. -+ * -+ * 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. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#define STATS -+ -+#ifdef STATS -+#define DO_STATS(X) do { X ; } while (0) -+#else -+#define DO_STATS(X) do { } while (0) -+#endif -+ -+/* ************************************************** */ -+ -+struct safe_buffer { -+ struct list_head node; -+ -+ /* original request */ -+ size_t size; -+ int direction; -+ -+ struct dmabounce_pool *pool; -+ void *safe; -+ dma_addr_t unsafe_dma_addr; -+ dma_addr_t safe_dma_addr; -+}; -+ -+struct dmabounce_pool { -+ unsigned long pages; -+ void *virt_addr; -+ dma_addr_t dma_addr; -+ unsigned long *alloc_map; -+ unsigned long alloc_pos; -+ spinlock_t lock; -+ struct device *dev; -+ unsigned long num_pages; -+#ifdef STATS -+ size_t max_size; -+ unsigned long num_bufs; -+ unsigned long max_bufs; -+ unsigned long max_pages; -+#endif -+}; -+ -+struct dmabounce_device_info { -+ struct device *dev; -+ dma_addr_t threshold; -+ struct list_head safe_buffers; -+ struct dmabounce_pool pool; -+ rwlock_t lock; -+#ifdef STATS -+ unsigned long map_count; -+ unsigned long unmap_count; -+ unsigned long sync_dev_count; -+ unsigned long sync_cpu_count; -+ unsigned long fail_count; -+ int attr_res; -+#endif -+}; -+ -+static struct dmabounce_device_info *g_dmabounce_device_info; -+ -+extern int bcm2838_dma40_memcpy_init(struct device *dev); -+extern void bcm2838_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size); -+ -+#ifdef STATS -+static ssize_t -+bounce_show(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ struct dmabounce_device_info *device_info = g_dmabounce_device_info; -+ return sprintf(buf, "m:%lu/%lu s:%lu/%lu f:%lu s:%zu b:%lu/%lu a:%lu/%lu\n", -+ device_info->map_count, -+ device_info->unmap_count, -+ device_info->sync_dev_count, -+ device_info->sync_cpu_count, -+ device_info->fail_count, -+ device_info->pool.max_size, -+ device_info->pool.num_bufs, -+ device_info->pool.max_bufs, -+ device_info->pool.num_pages * PAGE_SIZE, -+ device_info->pool.max_pages * PAGE_SIZE); -+} -+ -+static DEVICE_ATTR(dmabounce_stats, 0444, bounce_show, NULL); -+#endif -+ -+static int bounce_create(struct dmabounce_pool *pool, struct device *dev, -+ unsigned long buffer_size) -+{ -+ int ret = -ENOMEM; -+ pool->pages = (buffer_size + PAGE_SIZE - 1)/PAGE_SIZE; -+ pool->alloc_map = bitmap_zalloc(pool->pages, GFP_KERNEL); -+ if (!pool->alloc_map) -+ goto err_bitmap; -+ pool->virt_addr = dma_alloc_coherent(dev, pool->pages * PAGE_SIZE, -+ &pool->dma_addr, GFP_KERNEL); -+ if (!pool->virt_addr) -+ goto err_dmabuf; -+ -+ pool->alloc_pos = 0; -+ spin_lock_init(&pool->lock); -+ pool->dev = dev; -+ pool->num_pages = 0; -+ -+ DO_STATS(pool->max_size = 0); -+ DO_STATS(pool->num_bufs = 0); -+ DO_STATS(pool->max_bufs = 0); -+ DO_STATS(pool->max_pages = 0); -+ -+ return 0; -+ -+err_dmabuf: -+ bitmap_free(pool->alloc_map); -+err_bitmap: -+ return ret; -+} -+ -+static void bounce_destroy(struct dmabounce_pool *pool) -+{ -+ dma_free_coherent(pool->dev, pool->pages * PAGE_SIZE, pool->virt_addr, -+ pool->dma_addr); -+ -+ bitmap_free(pool->alloc_map); -+} -+ -+static void *bounce_alloc(struct dmabounce_pool *pool, size_t size, -+ dma_addr_t *dmaaddrp) -+{ -+ unsigned long pages; -+ unsigned long flags; -+ unsigned long pos; -+ -+ pages = (size + PAGE_SIZE - 1)/PAGE_SIZE; -+ -+ DO_STATS(pool->max_size = max(size, pool->max_size)); -+ -+ spin_lock_irqsave(&pool->lock, flags); -+ pos = bitmap_find_next_zero_area(pool->alloc_map, pool->pages, -+ pool->alloc_pos, pages, 0); -+ /* If not found, try from the start */ -+ if (pos >= pool->pages && pool->alloc_pos) -+ pos = bitmap_find_next_zero_area(pool->alloc_map, pool->pages, -+ 0, pages, 0); -+ -+ if (pos >= pool->pages) { -+ spin_unlock_irqrestore(&pool->lock, flags); -+ return NULL; -+ } -+ -+ bitmap_set(pool->alloc_map, pos, pages); -+ pool->alloc_pos = (pos + pages) % pool->pages; -+ pool->num_pages += pages; -+ -+ DO_STATS(pool->num_bufs++); -+ DO_STATS(pool->max_bufs = max(pool->num_bufs, pool->max_bufs)); -+ DO_STATS(pool->max_pages = max(pool->num_pages, pool->max_pages)); -+ -+ spin_unlock_irqrestore(&pool->lock, flags); -+ -+ *dmaaddrp = pool->dma_addr + pos * PAGE_SIZE; -+ -+ return pool->virt_addr + pos * PAGE_SIZE; -+} -+ -+static void -+bounce_free(struct dmabounce_pool *pool, void *buf, size_t size) -+{ -+ unsigned long pages; -+ unsigned long flags; -+ unsigned long pos; -+ -+ pages = (size + PAGE_SIZE - 1)/PAGE_SIZE; -+ pos = (buf - pool->virt_addr)/PAGE_SIZE; -+ -+ BUG_ON((buf - pool->virt_addr) & (PAGE_SIZE - 1)); -+ -+ spin_lock_irqsave(&pool->lock, flags); -+ bitmap_clear(pool->alloc_map, pos, pages); -+ pool->num_pages -= pages; -+ if (pool->num_pages == 0) -+ pool->alloc_pos = 0; -+ DO_STATS(pool->num_bufs--); -+ spin_unlock_irqrestore(&pool->lock, flags); -+} -+ -+/* allocate a 'safe' buffer and keep track of it */ -+static struct safe_buffer * -+alloc_safe_buffer(struct dmabounce_device_info *device_info, -+ dma_addr_t dma_addr, size_t size, enum dma_data_direction dir) -+{ -+ struct safe_buffer *buf; -+ struct dmabounce_pool *pool = &device_info->pool; -+ struct device *dev = device_info->dev; -+ unsigned long flags; -+ -+ /* -+ * Although one might expect this to be called in thread context, -+ * using GFP_KERNEL here leads to hard-to-debug lockups. in_atomic() -+ * was previously used to select the appropriate allocation mode, -+ * but this is unsafe. -+ */ -+ buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC); -+ if (!buf) { -+ dev_warn(dev, "%s: kmalloc failed\n", __func__); -+ return NULL; -+ } -+ -+ buf->unsafe_dma_addr = dma_addr; -+ buf->size = size; -+ buf->direction = dir; -+ buf->pool = pool; -+ -+ buf->safe = bounce_alloc(pool, size, &buf->safe_dma_addr); -+ -+ if (!buf->safe) { -+ dev_warn(dev, -+ "%s: could not alloc dma memory (size=%d)\n", -+ __func__, size); -+ kfree(buf); -+ return NULL; -+ } -+ -+ write_lock_irqsave(&device_info->lock, flags); -+ list_add(&buf->node, &device_info->safe_buffers); -+ write_unlock_irqrestore(&device_info->lock, flags); -+ -+ return buf; -+} -+ -+/* determine if a buffer is from our "safe" pool */ -+static struct safe_buffer * -+find_safe_buffer(struct dmabounce_device_info *device_info, -+ dma_addr_t safe_dma_addr) -+{ -+ struct safe_buffer *b, *rb = NULL; -+ unsigned long flags; -+ -+ read_lock_irqsave(&device_info->lock, flags); -+ -+ list_for_each_entry(b, &device_info->safe_buffers, node) -+ if (b->safe_dma_addr <= safe_dma_addr && -+ b->safe_dma_addr + b->size > safe_dma_addr) { -+ rb = b; -+ break; -+ } -+ -+ read_unlock_irqrestore(&device_info->lock, flags); -+ return rb; -+} -+ -+static void -+free_safe_buffer(struct dmabounce_device_info *device_info, -+ struct safe_buffer *buf) -+{ -+ unsigned long flags; -+ -+ write_lock_irqsave(&device_info->lock, flags); -+ list_del(&buf->node); -+ write_unlock_irqrestore(&device_info->lock, flags); -+ -+ bounce_free(buf->pool, buf->safe, buf->size); -+ -+ kfree(buf); -+} -+ -+/* ************************************************** */ -+ -+static struct safe_buffer * -+find_safe_buffer_dev(struct device *dev, dma_addr_t dma_addr, const char *where) -+{ -+ if (!dev || !g_dmabounce_device_info) -+ return NULL; -+ if (dma_mapping_error(dev, dma_addr)) { -+ dev_err(dev, "Trying to %s invalid mapping\n", where); -+ return NULL; -+ } -+ return find_safe_buffer(g_dmabounce_device_info, dma_addr); -+} -+ -+static dma_addr_t -+map_single(struct device *dev, struct safe_buffer *buf, size_t size, -+ enum dma_data_direction dir, unsigned long attrs) -+{ -+ BUG_ON(buf->size != size); -+ BUG_ON(buf->direction != dir); -+ -+ dev_dbg(dev, "map: %llx->%llx\n", (u64)buf->unsafe_dma_addr, -+ (u64)buf->safe_dma_addr); -+ -+ if ((dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) && -+ !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) -+ bcm2838_dma40_memcpy(buf->safe_dma_addr, buf->unsafe_dma_addr, -+ size); -+ -+ return buf->safe_dma_addr; -+} -+ -+static dma_addr_t -+unmap_single(struct device *dev, struct safe_buffer *buf, size_t size, -+ enum dma_data_direction dir, unsigned long attrs) -+{ -+ BUG_ON(buf->size != size); -+ BUG_ON(buf->direction != dir); -+ -+ if ((dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) && -+ !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) { -+ dev_dbg(dev, "unmap: %llx->%llx\n", (u64)buf->safe_dma_addr, -+ (u64)buf->unsafe_dma_addr); -+ -+ bcm2838_dma40_memcpy(buf->unsafe_dma_addr, buf->safe_dma_addr, -+ size); -+ } -+ return buf->unsafe_dma_addr; -+} -+ -+/* ************************************************** */ -+ -+/* -+ * see if a buffer address is in an 'unsafe' range. if it is -+ * allocate a 'safe' buffer and copy the unsafe buffer into it. -+ * substitute the safe buffer for the unsafe one. -+ * (basically move the buffer from an unsafe area to a safe one) -+ */ -+static dma_addr_t -+dmabounce_map_page(struct device *dev, struct page *page, unsigned long offset, -+ size_t size, enum dma_data_direction dir, -+ unsigned long attrs) -+{ -+ struct dmabounce_device_info *device_info = g_dmabounce_device_info; -+ dma_addr_t dma_addr; -+ -+ dma_addr = pfn_to_dma(dev, page_to_pfn(page)) + offset; -+ -+ arm_dma_ops.sync_single_for_device(dev, dma_addr, size, dir); -+ -+ if (device_info && (dma_addr + size) > device_info->threshold) { -+ struct safe_buffer *buf; -+ -+ buf = alloc_safe_buffer(device_info, dma_addr, size, dir); -+ if (!buf) { -+ DO_STATS(device_info->fail_count++); -+ return ARM_MAPPING_ERROR; -+ } -+ -+ DO_STATS(device_info->map_count++); -+ -+ dma_addr = map_single(dev, buf, size, dir, attrs); -+ } -+ -+ return dma_addr; -+} -+ -+/* -+ * see if a mapped address was really a "safe" buffer and if so, copy -+ * the data from the safe buffer back to the unsafe buffer and free up -+ * the safe buffer. (basically return things back to the way they -+ * should be) -+ */ -+static void -+dmabounce_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, -+ enum dma_data_direction dir, unsigned long attrs) -+{ -+ struct safe_buffer *buf; -+ -+ buf = find_safe_buffer_dev(dev, dma_addr, __func__); -+ if (buf) { -+ DO_STATS(g_dmabounce_device_info->unmap_count++); -+ dma_addr = unmap_single(dev, buf, size, dir, attrs); -+ free_safe_buffer(g_dmabounce_device_info, buf); -+ } -+ -+ arm_dma_ops.sync_single_for_cpu(dev, dma_addr, size, dir); -+} -+ -+/* -+ * A version of dmabounce_map_page that assumes the mapping has already -+ * been created - intended for streaming operation. -+ */ -+static void -+dmabounce_sync_for_device(struct device *dev, dma_addr_t dma_addr, size_t size, -+ enum dma_data_direction dir) -+{ -+ struct safe_buffer *buf; -+ -+ arm_dma_ops.sync_single_for_device(dev, dma_addr, size, dir); -+ -+ buf = find_safe_buffer_dev(dev, dma_addr, __func__); -+ if (buf) { -+ DO_STATS(g_dmabounce_device_info->sync_dev_count++); -+ map_single(dev, buf, size, dir, 0); -+ } -+} -+ -+/* -+ * A version of dmabounce_unmap_page that doesn't destroy the mapping - -+ * intended for streaming operation. -+ */ -+static void -+dmabounce_sync_for_cpu(struct device *dev, dma_addr_t dma_addr, -+ size_t size, enum dma_data_direction dir) -+{ -+ struct safe_buffer *buf; -+ -+ buf = find_safe_buffer_dev(dev, dma_addr, __func__); -+ if (buf) { -+ DO_STATS(g_dmabounce_device_info->sync_cpu_count++); -+ dma_addr = unmap_single(dev, buf, size, dir, 0); -+ } -+ -+ arm_dma_ops.sync_single_for_cpu(dev, dma_addr, size, dir); -+} -+ -+static int dmabounce_dma_supported(struct device *dev, u64 dma_mask) -+{ -+ if (g_dmabounce_device_info) -+ return 0; -+ -+ return arm_dma_ops.dma_supported(dev, dma_mask); -+} -+ -+static int dmabounce_mapping_error(struct device *dev, dma_addr_t dma_addr) -+{ -+ return arm_dma_ops.mapping_error(dev, dma_addr); -+} -+ -+static const struct dma_map_ops dmabounce_ops = { -+ .alloc = arm_dma_alloc, -+ .free = arm_dma_free, -+ .mmap = arm_dma_mmap, -+ .get_sgtable = arm_dma_get_sgtable, -+ .map_page = dmabounce_map_page, -+ .unmap_page = dmabounce_unmap_page, -+ .sync_single_for_cpu = dmabounce_sync_for_cpu, -+ .sync_single_for_device = dmabounce_sync_for_device, -+ .map_sg = arm_dma_map_sg, -+ .unmap_sg = arm_dma_unmap_sg, -+ .sync_sg_for_cpu = arm_dma_sync_sg_for_cpu, -+ .sync_sg_for_device = arm_dma_sync_sg_for_device, -+ .dma_supported = dmabounce_dma_supported, -+ .mapping_error = dmabounce_mapping_error, -+}; -+ -+int brcm_pcie_bounce_register_dev(struct device *dev, -+ unsigned long buffer_size, -+ dma_addr_t threshold) -+{ -+ struct dmabounce_device_info *device_info; -+ int ret; -+ -+ /* Only support a single client */ -+ if (g_dmabounce_device_info) -+ return -EBUSY; -+ -+ ret = bcm2838_dma40_memcpy_init(dev); -+ if (ret) -+ return ret; -+ -+ device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC); -+ if (!device_info) { -+ dev_err(dev, -+ "Could not allocated dmabounce_device_info\n"); -+ return -ENOMEM; -+ } -+ -+ ret = bounce_create(&device_info->pool, dev, buffer_size); -+ if (ret) { -+ dev_err(dev, -+ "dmabounce: could not allocate %ld byte DMA pool\n", -+ buffer_size); -+ goto err_bounce; -+ } -+ -+ device_info->dev = dev; -+ device_info->threshold = threshold; -+ INIT_LIST_HEAD(&device_info->safe_buffers); -+ rwlock_init(&device_info->lock); -+ -+ DO_STATS(device_info->map_count = 0); -+ DO_STATS(device_info->unmap_count = 0); -+ DO_STATS(device_info->sync_dev_count = 0); -+ DO_STATS(device_info->sync_cpu_count = 0); -+ DO_STATS(device_info->fail_count = 0); -+ DO_STATS(device_info->attr_res = -+ device_create_file(dev, &dev_attr_dmabounce_stats)); -+ -+ g_dmabounce_device_info = device_info; -+ set_dma_ops(dev, &dmabounce_ops); -+ -+ dev_info(dev, "dmabounce: registered device - %ld kB, threshold %pad\n", -+ buffer_size / 1024, &threshold); -+ -+ return 0; -+ -+ err_bounce: -+ kfree(device_info); -+ return ret; -+} -+EXPORT_SYMBOL(brcm_pcie_bounce_register_dev); -+ -+void brcm_pcie_bounce_unregister_dev(struct device *dev) -+{ -+ struct dmabounce_device_info *device_info = g_dmabounce_device_info; -+ -+ g_dmabounce_device_info = NULL; -+ set_dma_ops(dev, NULL); -+ -+ if (!device_info) { -+ dev_warn(dev, -+ "Never registered with dmabounce but attempting" -+ "to unregister!\n"); -+ return; -+ } -+ -+ if (!list_empty(&device_info->safe_buffers)) { -+ dev_err(dev, -+ "Removing from dmabounce with pending buffers!\n"); -+ BUG(); -+ } -+ -+ bounce_destroy(&device_info->pool); -+ -+ DO_STATS(if (device_info->attr_res == 0) -+ device_remove_file(dev, &dev_attr_dmabounce_stats)); -+ -+ kfree(device_info); -+ -+ dev_info(dev, "dmabounce: device unregistered\n"); -+} -+EXPORT_SYMBOL(brcm_pcie_bounce_unregister_dev); -+ -+MODULE_AUTHOR("Phil Elwell "); -+MODULE_DESCRIPTION("Dedicate DMA bounce support for pcie-brcmstb"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/drivers/pci/controller/pcie-brcmstb-bounce.h -@@ -0,0 +1,32 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2019 Raspberry Pi (Trading) Ltd. -+ */ -+ -+#ifndef _PCIE_BRCMSTB_BOUNCE_H -+#define _PCIE_BRCMSTB_BOUNCE_H -+ -+#ifdef CONFIG_ARM -+ -+int brcm_pcie_bounce_register_dev(struct device *dev, unsigned long buffer_size, -+ dma_addr_t threshold); -+ -+int brcm_pcie_bounce_unregister_dev(struct device *dev); -+ -+#else -+ -+static inline int brcm_pcie_bounce_register_dev(struct device *dev, -+ unsigned long buffer_size, -+ dma_addr_t threshold) -+{ -+ return 0; -+} -+ -+static inline int brcm_pcie_bounce_unregister_dev(struct device *dev) -+{ -+ return 0; -+} -+ -+#endif -+ -+#endif /* _PCIE_BRCMSTB_BOUNCE_H */ ---- a/drivers/pci/controller/pcie-brcmstb.c -+++ b/drivers/pci/controller/pcie-brcmstb.c -@@ -29,6 +29,7 @@ - #include - #include - #include "../pci.h" -+#include "pcie-brcmstb-bounce.h" - - /* BRCM_PCIE_CAP_REGS - Offset for the mandatory capability config regs */ - #define BRCM_PCIE_CAP_REGS 0x00ac -@@ -53,6 +54,7 @@ - #define PCIE_MISC_MSI_BAR_CONFIG_LO 0x4044 - #define PCIE_MISC_MSI_BAR_CONFIG_HI 0x4048 - #define PCIE_MISC_MSI_DATA_CONFIG 0x404c -+#define PCIE_MISC_EOI_CTRL 0x4060 - #define PCIE_MISC_PCIE_CTRL 0x4064 - #define PCIE_MISC_PCIE_STATUS 0x4068 - #define PCIE_MISC_REVISION 0x406c -@@ -260,12 +262,14 @@ struct brcm_pcie { - unsigned int rev; - const int *reg_offsets; - const int *reg_field_info; -+ u32 max_burst_size; - enum pcie_type type; - }; - - struct pcie_cfg_data { - const int *reg_field_info; - const int *offsets; -+ const u32 max_burst_size; - const enum pcie_type type; - }; - -@@ -288,24 +292,27 @@ static const int pcie_offset_bcm7425[] = - static const struct pcie_cfg_data bcm7425_cfg = { - .reg_field_info = pcie_reg_field_info, - .offsets = pcie_offset_bcm7425, -+ .max_burst_size = BURST_SIZE_256, - .type = BCM7425, - }; - - static const int pcie_offsets[] = { - [RGR1_SW_INIT_1] = 0x9210, - [EXT_CFG_INDEX] = 0x9000, -- [EXT_CFG_DATA] = 0x9004, -+ [EXT_CFG_DATA] = 0x8000, - }; - - static const struct pcie_cfg_data bcm7435_cfg = { - .reg_field_info = pcie_reg_field_info, - .offsets = pcie_offsets, -+ .max_burst_size = BURST_SIZE_256, - .type = BCM7435, - }; - - static const struct pcie_cfg_data generic_cfg = { - .reg_field_info = pcie_reg_field_info, - .offsets = pcie_offsets, -+ .max_burst_size = BURST_SIZE_128, // before BURST_SIZE_512 - .type = GENERIC, - }; - -@@ -318,6 +325,7 @@ static const int pcie_offset_bcm7278[] = - static const struct pcie_cfg_data bcm7278_cfg = { - .reg_field_info = pcie_reg_field_info_bcm7278, - .offsets = pcie_offset_bcm7278, -+ .max_burst_size = BURST_SIZE_512, - .type = BCM7278, - }; - -@@ -360,7 +368,6 @@ static struct pci_ops brcm_pcie_ops = { - (reg##_##field##_MASK & (field_val << reg##_##field##_SHIFT))) - - static const struct dma_map_ops *arch_dma_ops; --static const struct dma_map_ops *brcm_dma_ops_ptr; - static struct of_pci_range *dma_ranges; - static int num_dma_ranges; - -@@ -369,6 +376,16 @@ static int num_memc; - static int num_pcie; - static DEFINE_MUTEX(brcm_pcie_lock); - -+static unsigned int bounce_buffer = 32*1024*1024; -+module_param(bounce_buffer, uint, 0644); -+MODULE_PARM_DESC(bounce_buffer, "Size of bounce buffer"); -+ -+static unsigned int bounce_threshold = 0xc0000000; -+module_param(bounce_threshold, uint, 0644); -+MODULE_PARM_DESC(bounce_threshold, "Bounce threshold"); -+ -+static struct brcm_pcie *g_pcie; -+ - static dma_addr_t brcm_to_pci(dma_addr_t addr) - { - struct of_pci_range *p; -@@ -457,12 +474,10 @@ static int brcm_map_sg(struct device *de - struct scatterlist *sg; - - for_each_sg(sgl, sg, nents, i) { --#ifdef CONFIG_NEED_SG_DMA_LENGTH -- sg->dma_length = sg->length; --#endif -+ sg_dma_len(sg) = sg->length; - sg->dma_address = -- brcm_dma_ops_ptr->map_page(dev, sg_page(sg), sg->offset, -- sg->length, dir, attrs); -+ brcm_map_page(dev, sg_page(sg), sg->offset, -+ sg->length, dir, attrs); - if (dma_mapping_error(dev, sg->dma_address)) - goto bad_mapping; - } -@@ -470,8 +485,8 @@ static int brcm_map_sg(struct device *de - - bad_mapping: - for_each_sg(sgl, sg, i, j) -- brcm_dma_ops_ptr->unmap_page(dev, sg_dma_address(sg), -- sg_dma_len(sg), dir, attrs); -+ brcm_unmap_page(dev, sg_dma_address(sg), -+ sg_dma_len(sg), dir, attrs); - return 0; - } - -@@ -484,8 +499,8 @@ static void brcm_unmap_sg(struct device - struct scatterlist *sg; - - for_each_sg(sgl, sg, nents, i) -- brcm_dma_ops_ptr->unmap_page(dev, sg_dma_address(sg), -- sg_dma_len(sg), dir, attrs); -+ brcm_unmap_page(dev, sg_dma_address(sg), -+ sg_dma_len(sg), dir, attrs); - } - - static void brcm_sync_single_for_cpu(struct device *dev, -@@ -531,8 +546,8 @@ void brcm_sync_sg_for_cpu(struct device - int i; - - for_each_sg(sgl, sg, nents, i) -- brcm_dma_ops_ptr->sync_single_for_cpu(dev, sg_dma_address(sg), -- sg->length, dir); -+ brcm_sync_single_for_cpu(dev, sg_dma_address(sg), -+ sg->length, dir); - } - - void brcm_sync_sg_for_device(struct device *dev, struct scatterlist *sgl, -@@ -542,9 +557,9 @@ void brcm_sync_sg_for_device(struct devi - int i; - - for_each_sg(sgl, sg, nents, i) -- brcm_dma_ops_ptr->sync_single_for_device(dev, -- sg_dma_address(sg), -- sg->length, dir); -+ brcm_sync_single_for_device(dev, -+ sg_dma_address(sg), -+ sg->length, dir); - } - - static int brcm_mapping_error(struct device *dev, dma_addr_t dma_addr) -@@ -633,17 +648,47 @@ static void brcm_set_dma_ops(struct devi - set_dma_ops(dev, &brcm_dma_ops); - } - -+static inline void brcm_pcie_perst_set(struct brcm_pcie *pcie, -+ unsigned int val); - static int brcmstb_platform_notifier(struct notifier_block *nb, - unsigned long event, void *__dev) - { -+ extern unsigned long max_pfn; - struct device *dev = __dev; -+ const char *rc_name = "0000:00:00.0"; - -- brcm_dma_ops_ptr = &brcm_dma_ops; -- if (event != BUS_NOTIFY_ADD_DEVICE) -- return NOTIFY_DONE; -+ switch (event) { -+ case BUS_NOTIFY_ADD_DEVICE: -+ if (max_pfn > (bounce_threshold/PAGE_SIZE) && -+ strcmp(dev->kobj.name, rc_name)) { -+ int ret; -+ -+ ret = brcm_pcie_bounce_register_dev(dev, bounce_buffer, -+ (dma_addr_t)bounce_threshold); -+ if (ret) { -+ dev_err(dev, -+ "brcm_pcie_bounce_register_dev() failed: %d\n", -+ ret); -+ return ret; -+ } -+ } -+ brcm_set_dma_ops(dev); -+ return NOTIFY_OK; -+ -+ case BUS_NOTIFY_DEL_DEVICE: -+ if (!strcmp(dev->kobj.name, rc_name) && g_pcie) { -+ /* Force a bus reset */ -+ brcm_pcie_perst_set(g_pcie, 1); -+ msleep(100); -+ brcm_pcie_perst_set(g_pcie, 0); -+ } else if (max_pfn > (bounce_threshold/PAGE_SIZE)) { -+ brcm_pcie_bounce_unregister_dev(dev); -+ } -+ return NOTIFY_OK; - -- brcm_set_dma_ops(dev); -- return NOTIFY_OK; -+ default: -+ return NOTIFY_DONE; -+ } - } - - static struct notifier_block brcmstb_platform_nb = { -@@ -914,6 +959,7 @@ static void brcm_pcie_msi_isr(struct irq - } - } - chained_irq_exit(chip, desc); -+ bcm_writel(1, msi->base + PCIE_MISC_EOI_CTRL); - } - - static void brcm_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) -@@ -930,7 +976,8 @@ static void brcm_compose_msi_msg(struct - static int brcm_msi_set_affinity(struct irq_data *irq_data, - const struct cpumask *mask, bool force) - { -- return -EINVAL; -+ struct brcm_msi *msi = irq_data_get_irq_chip_data(irq_data); -+ return __irq_set_affinity(msi->irq, mask, force); - } - - static struct irq_chip brcm_msi_bottom_irq_chip = { -@@ -1168,9 +1215,9 @@ static void __iomem *brcm_pcie_map_conf( - return PCI_SLOT(devfn) ? NULL : base + where; - - /* For devices, write to the config space index register */ -- idx = cfg_index(bus->number, devfn, where); -+ idx = cfg_index(bus->number, devfn, 0); - bcm_writel(idx, pcie->base + IDX_ADDR(pcie)); -- return base + DATA_ADDR(pcie) + (where & 0x3); -+ return base + DATA_ADDR(pcie) + where; - } - - static inline void brcm_pcie_bridge_sw_init_set(struct brcm_pcie *pcie, -@@ -1238,20 +1285,6 @@ static int brcm_pcie_parse_map_dma_range - num_dma_ranges++; - } - -- for (i = 0, num_memc = 0; i < BRCM_MAX_SCB; i++) { -- u64 size = brcmstb_memory_memc_size(i); -- -- if (size == (u64)-1) { -- dev_err(pcie->dev, "cannot get memc%d size", i); -- return -EINVAL; -- } else if (size) { -- scb_size[i] = roundup_pow_of_two_64(size); -- num_memc++; -- } else { -- break; -- } -- } -- - return 0; - } - -@@ -1275,26 +1308,25 @@ static int brcm_pcie_add_controller(stru - if (ret) - goto done; - -- /* Determine num_memc and their sizes */ -- for (i = 0, num_memc = 0; i < BRCM_MAX_SCB; i++) { -- u64 size = brcmstb_memory_memc_size(i); -- -- if (size == (u64)-1) { -- dev_err(dev, "cannot get memc%d size\n", i); -- ret = -EINVAL; -- goto done; -- } else if (size) { -- scb_size[i] = roundup_pow_of_two_64(size); -- num_memc++; -- } else { -- break; -+ if (!num_dma_ranges) { -+ /* Determine num_memc and their sizes by other means */ -+ for (i = 0, num_memc = 0; i < BRCM_MAX_SCB; i++) { -+ u64 size = brcmstb_memory_memc_size(i); -+ -+ if (size == (u64)-1) { -+ dev_err(dev, "cannot get memc%d size\n", i); -+ ret = -EINVAL; -+ goto done; -+ } else if (size) { -+ scb_size[i] = roundup_pow_of_two_64(size); -+ } else { -+ break; -+ } - } -- } -- if (!ret && num_memc == 0) { -- ret = -EINVAL; -- goto done; -+ num_memc = i; - } - -+ g_pcie = pcie; - num_pcie++; - done: - mutex_unlock(&brcm_pcie_lock); -@@ -1307,6 +1339,7 @@ static void brcm_pcie_remove_controller( - if (--num_pcie > 0) - goto out; - -+ g_pcie = NULL; - if (brcm_unregister_notifier()) - dev_err(pcie->dev, "failed to unregister pci bus notifier\n"); - kfree(dma_ranges); -@@ -1367,7 +1400,7 @@ static int brcm_pcie_setup(struct brcm_p - void __iomem *base = pcie->base; - unsigned int scb_size_val; - u64 rc_bar2_offset, rc_bar2_size, total_mem_size = 0; -- u32 tmp, burst; -+ u32 tmp; - int i, j, ret, limit; - u16 nlw, cls, lnksta; - bool ssc_good = false; -@@ -1400,20 +1433,15 @@ static int brcm_pcie_setup(struct brcm_p - /* Set SCB_MAX_BURST_SIZE, CFG_READ_UR_MODE, SCB_ACCESS_EN */ - tmp = INSERT_FIELD(0, PCIE_MISC_MISC_CTRL, SCB_ACCESS_EN, 1); - tmp = INSERT_FIELD(tmp, PCIE_MISC_MISC_CTRL, CFG_READ_UR_MODE, 1); -- burst = (pcie->type == GENERIC || pcie->type == BCM7278) -- ? BURST_SIZE_512 : BURST_SIZE_256; -- tmp = INSERT_FIELD(tmp, PCIE_MISC_MISC_CTRL, MAX_BURST_SIZE, burst); -+ tmp = INSERT_FIELD(tmp, PCIE_MISC_MISC_CTRL, MAX_BURST_SIZE, -+ pcie->max_burst_size); - bcm_writel(tmp, base + PCIE_MISC_MISC_CTRL); - - /* - * Set up inbound memory view for the EP (called RC_BAR2, - * not to be confused with the BARs that are advertised by - * the EP). -- */ -- for (i = 0; i < num_memc; i++) -- total_mem_size += scb_size[i]; -- -- /* -+ * - * The PCIe host controller by design must set the inbound - * viewport to be a contiguous arrangement of all of the - * system's memory. In addition, its size mut be a power of -@@ -1429,55 +1457,49 @@ static int brcm_pcie_setup(struct brcm_p - * the controller will know to send outbound memory downstream - * and everything else upstream. - */ -- rc_bar2_size = roundup_pow_of_two_64(total_mem_size); - -- if (dma_ranges) { -+ if (num_dma_ranges) { - /* -- * The best-case scenario is to place the inbound -- * region in the first 4GB of pcie-space, as some -- * legacy devices can only address 32bits. -- * We would also like to put the MSI under 4GB -- * as well, since some devices require a 32bit -- * MSI target address. -+ * Use the base address and size(s) provided in the dma-ranges -+ * property. - */ -- if (total_mem_size <= 0xc0000000ULL && -- rc_bar2_size <= 0x100000000ULL) { -- rc_bar2_offset = 0; -- /* If the viewport is less then 4GB we can fit -- * the MSI target address under 4GB. Otherwise -- * put it right below 64GB. -- */ -- msi_target_addr = -- (rc_bar2_size == 0x100000000ULL) -- ? BRCM_MSI_TARGET_ADDR_GT_4GB -- : BRCM_MSI_TARGET_ADDR_LT_4GB; -- } else { -- /* -- * The system memory is 4GB or larger so we -- * cannot start the inbound region at location -- * 0 (since we have to allow some space for -- * outbound memory @ 3GB). So instead we -- * start it at the 1x multiple of its size -- */ -- rc_bar2_offset = rc_bar2_size; -- -- /* Since we are starting the viewport at 4GB or -- * higher, put the MSI target address below 4GB -- */ -- msi_target_addr = BRCM_MSI_TARGET_ADDR_LT_4GB; -- } -- } else { -+ for (i = 0; i < num_dma_ranges; i++) -+ scb_size[i] = roundup_pow_of_two_64(dma_ranges[i].size); -+ -+ num_memc = num_dma_ranges; -+ rc_bar2_offset = dma_ranges[0].pci_addr; -+ } else if (num_memc) { - /* - * Set simple configuration based on memory sizes -- * only. We always start the viewport at address 0, -- * and set the MSI target address accordingly. -+ * only. We always start the viewport at address 0. - */ - rc_bar2_offset = 0; -+ } else { -+ return -EINVAL; -+ } -+ -+ for (i = 0; i < num_memc; i++) -+ total_mem_size += scb_size[i]; -+ -+ rc_bar2_size = roundup_pow_of_two_64(total_mem_size); - -- msi_target_addr = (rc_bar2_size >= 0x100000000ULL) -- ? BRCM_MSI_TARGET_ADDR_GT_4GB -- : BRCM_MSI_TARGET_ADDR_LT_4GB; -+ /* Verify the alignment is correct */ -+ if (rc_bar2_offset & (rc_bar2_size - 1)) { -+ dev_err(dev, "inbound window is misaligned\n"); -+ return -EINVAL; - } -+ -+ /* -+ * Position the MSI target low if possible. -+ * -+ * TO DO: Consider outbound window when choosing MSI target and -+ * verifying configuration. -+ */ -+ msi_target_addr = BRCM_MSI_TARGET_ADDR_LT_4GB; -+ if (rc_bar2_offset <= msi_target_addr && -+ rc_bar2_offset + rc_bar2_size > msi_target_addr) -+ msi_target_addr = BRCM_MSI_TARGET_ADDR_GT_4GB; -+ - pcie->msi_target_addr = msi_target_addr; - - tmp = lower_32_bits(rc_bar2_offset); -@@ -1713,6 +1735,7 @@ static int brcm_pcie_probe(struct platfo - data = of_id->data; - pcie->reg_offsets = data->offsets; - pcie->reg_field_info = data->reg_field_info; -+ pcie->max_burst_size = data->max_burst_size; - pcie->type = data->type; - pcie->dn = dn; - pcie->dev = &pdev->dev; -@@ -1732,7 +1755,7 @@ static int brcm_pcie_probe(struct platfo - - pcie->clk = of_clk_get_by_name(dn, "sw_pcie"); - if (IS_ERR(pcie->clk)) { -- dev_err(&pdev->dev, "could not get clock\n"); -+ dev_warn(&pdev->dev, "could not get clock\n"); - pcie->clk = NULL; - } - pcie->base = base; -@@ -1755,7 +1778,8 @@ static int brcm_pcie_probe(struct platfo - - ret = clk_prepare_enable(pcie->clk); - if (ret) { -- dev_err(&pdev->dev, "could not enable clock\n"); -+ if (ret != -EPROBE_DEFER) -+ dev_err(&pdev->dev, "could not enable clock\n"); - return ret; - } - -@@ -1818,7 +1842,6 @@ static struct platform_driver brcm_pcie_ - .remove = brcm_pcie_remove, - .driver = { - .name = "brcm-pcie", -- .owner = THIS_MODULE, - .of_match_table = brcm_pcie_match, - .pm = &brcm_pcie_pm_ops, - }, ---- a/drivers/soc/bcm/brcmstb/Makefile -+++ b/drivers/soc/bcm/brcmstb/Makefile -@@ -1,2 +1,2 @@ --obj-y += common.o biuctrl.o -+obj-y += common.o biuctrl.o memory.o - obj-$(CONFIG_BRCMSTB_PM) += pm/ ---- /dev/null -+++ b/drivers/soc/bcm/brcmstb/memory.c -@@ -0,0 +1,158 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* Copyright © 2015-2017 Broadcom */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Macro to help extract property data */ -+#define DT_PROP_DATA_TO_U32(b, offs) (fdt32_to_cpu(*(u32 *)(b + offs))) -+ -+/* Constants used when retrieving memc info */ -+#define NUM_BUS_RANGES 10 -+#define BUS_RANGE_ULIMIT_SHIFT 4 -+#define BUS_RANGE_LLIMIT_SHIFT 4 -+#define BUS_RANGE_PA_SHIFT 12 -+ -+enum { -+ BUSNUM_MCP0 = 0x4, -+ BUSNUM_MCP1 = 0x5, -+ BUSNUM_MCP2 = 0x6, -+}; -+ -+/* -+ * If the DT nodes are handy, determine which MEMC holds the specified -+ * physical address. -+ */ -+#ifdef CONFIG_ARCH_BRCMSTB -+int __brcmstb_memory_phys_addr_to_memc(phys_addr_t pa, void __iomem *base) -+{ -+ int memc = -1; -+ int i; -+ -+ for (i = 0; i < NUM_BUS_RANGES; i++, base += 8) { -+ const u64 ulimit_raw = readl(base); -+ const u64 llimit_raw = readl(base + 4); -+ const u64 ulimit = -+ ((ulimit_raw >> BUS_RANGE_ULIMIT_SHIFT) -+ << BUS_RANGE_PA_SHIFT) | 0xfff; -+ const u64 llimit = (llimit_raw >> BUS_RANGE_LLIMIT_SHIFT) -+ << BUS_RANGE_PA_SHIFT; -+ const u32 busnum = (u32)(ulimit_raw & 0xf); -+ -+ if (pa >= llimit && pa <= ulimit) { -+ if (busnum >= BUSNUM_MCP0 && busnum <= BUSNUM_MCP2) { -+ memc = busnum - BUSNUM_MCP0; -+ break; -+ } -+ } -+ } -+ -+ return memc; -+} -+ -+int brcmstb_memory_phys_addr_to_memc(phys_addr_t pa) -+{ -+ int memc = -1; -+ struct device_node *np; -+ void __iomem *cpubiuctrl; -+ -+ np = of_find_compatible_node(NULL, NULL, "brcm,brcmstb-cpu-biu-ctrl"); -+ if (!np) -+ return memc; -+ -+ cpubiuctrl = of_iomap(np, 0); -+ if (!cpubiuctrl) -+ goto cleanup; -+ -+ memc = __brcmstb_memory_phys_addr_to_memc(pa, cpubiuctrl); -+ iounmap(cpubiuctrl); -+ -+cleanup: -+ of_node_put(np); -+ -+ return memc; -+} -+ -+#elif defined(CONFIG_MIPS) -+int brcmstb_memory_phys_addr_to_memc(phys_addr_t pa) -+{ -+ /* The logic here is fairly simple and hardcoded: if pa <= 0x5000_0000, -+ * then this is MEMC0, else MEMC1. -+ * -+ * For systems with 2GB on MEMC0, MEMC1 starts at 9000_0000, with 1GB -+ * on MEMC0, MEMC1 starts at 6000_0000. -+ */ -+ if (pa >= 0x50000000ULL) -+ return 1; -+ else -+ return 0; -+} -+#endif -+ -+u64 brcmstb_memory_memc_size(int memc) -+{ -+ const void *fdt = initial_boot_params; -+ const int mem_offset = fdt_path_offset(fdt, "/memory"); -+ int addr_cells = 1, size_cells = 1; -+ const struct fdt_property *prop; -+ int proplen, cellslen; -+ u64 memc_size = 0; -+ int i; -+ -+ /* Get root size and address cells if specified */ -+ prop = fdt_get_property(fdt, 0, "#size-cells", &proplen); -+ if (prop) -+ size_cells = DT_PROP_DATA_TO_U32(prop->data, 0); -+ -+ prop = fdt_get_property(fdt, 0, "#address-cells", &proplen); -+ if (prop) -+ addr_cells = DT_PROP_DATA_TO_U32(prop->data, 0); -+ -+ if (mem_offset < 0) -+ return -1; -+ -+ prop = fdt_get_property(fdt, mem_offset, "reg", &proplen); -+ cellslen = (int)sizeof(u32) * (addr_cells + size_cells); -+ if ((proplen % cellslen) != 0) -+ return -1; -+ -+ for (i = 0; i < proplen / cellslen; ++i) { -+ u64 addr = 0; -+ u64 size = 0; -+ int memc_idx; -+ int j; -+ -+ for (j = 0; j < addr_cells; ++j) { -+ int offset = (cellslen * i) + (sizeof(u32) * j); -+ -+ addr |= (u64)DT_PROP_DATA_TO_U32(prop->data, offset) << -+ ((addr_cells - j - 1) * 32); -+ } -+ for (j = 0; j < size_cells; ++j) { -+ int offset = (cellslen * i) + -+ (sizeof(u32) * (j + addr_cells)); -+ -+ size |= (u64)DT_PROP_DATA_TO_U32(prop->data, offset) << -+ ((size_cells - j - 1) * 32); -+ } -+ -+ if ((phys_addr_t)addr != addr) { -+ pr_err("phys_addr_t is smaller than provided address 0x%llx!\n", -+ addr); -+ return -1; -+ } -+ -+ memc_idx = brcmstb_memory_phys_addr_to_memc((phys_addr_t)addr); -+ if (memc_idx == memc) -+ memc_size += size; -+ } -+ -+ return memc_size; -+} -+EXPORT_SYMBOL_GPL(brcmstb_memory_memc_size); -+ diff --git a/target/linux/brcm2708/patches-4.19/950-0539-arm-bcm2835-DMA-can-only-address-1GB.patch b/target/linux/brcm2708/patches-4.19/950-0539-arm-bcm2835-DMA-can-only-address-1GB.patch deleted file mode 100644 index 17a7524944..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0539-arm-bcm2835-DMA-can-only-address-1GB.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 4f8fa14b05198c3d145d72d47ad9adfc25601842 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 29 May 2019 15:47:42 +0100 -Subject: [PATCH 539/703] arm: bcm2835: DMA can only address 1GB - -The legacy peripherals can only address the first gigabyte of RAM, so -ensure that DMA allocations are restricted to that region. - -Signed-off-by: Phil Elwell ---- - arch/arm/mach-bcm/board_bcm2835.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/arch/arm/mach-bcm/board_bcm2835.c -+++ b/arch/arm/mach-bcm/board_bcm2835.c -@@ -123,6 +123,9 @@ static const char * const bcm2835_compat - }; - - DT_MACHINE_START(BCM2835, "BCM2835") -+#if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE) -+ .dma_zone_size = SZ_1G, -+#endif - .map_io = bcm2835_map_io, - .init_machine = bcm2835_init, - .dt_compat = bcm2835_compat, diff --git a/target/linux/brcm2708/patches-4.19/950-0539-hwrng-iproc-rng200-Add-BCM2838-support.patch b/target/linux/brcm2708/patches-4.19/950-0539-hwrng-iproc-rng200-Add-BCM2838-support.patch new file mode 100644 index 0000000000..9e090355f7 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0539-hwrng-iproc-rng200-Add-BCM2838-support.patch @@ -0,0 +1,158 @@ +From c1a3581a5637d096c40456e22edf7f846ca24ad4 Mon Sep 17 00:00:00 2001 +From: Stefan Wahren +Date: Sat, 4 May 2019 17:06:15 +0200 +Subject: [PATCH 539/725] hwrng: iproc-rng200: Add BCM2838 support + +The HWRNG on the BCM2838 is compatible to iproc-rng200, so add the +support to this driver instead of bcm2835-rng. + +Signed-off-by: Stefan Wahren +--- + drivers/char/hw_random/Kconfig | 4 +- + drivers/char/hw_random/iproc-rng200.c | 81 +++++++++++++++++++++++++-- + 2 files changed, 79 insertions(+), 6 deletions(-) + +--- a/drivers/char/hw_random/Kconfig ++++ b/drivers/char/hw_random/Kconfig +@@ -89,11 +89,11 @@ config HW_RANDOM_BCM2835 + + config HW_RANDOM_IPROC_RNG200 + tristate "Broadcom iProc/STB RNG200 support" +- depends on ARCH_BCM_IPROC || ARCH_BRCMSTB ++ depends on ARCH_BCM_IPROC || ARCH_BCM2835 || ARCH_BRCMSTB + default HW_RANDOM + ---help--- + This driver provides kernel-side support for the RNG200 +- hardware found on the Broadcom iProc and STB SoCs. ++ hardware found on the Broadcom iProc, BCM2838 and STB SoCs. + + To compile this driver as a module, choose M here: the + module will be called iproc-rng200 +--- a/drivers/char/hw_random/iproc-rng200.c ++++ b/drivers/char/hw_random/iproc-rng200.c +@@ -29,6 +29,7 @@ + #define RNG_CTRL_RNG_RBGEN_MASK 0x00001FFF + #define RNG_CTRL_RNG_RBGEN_ENABLE 0x00000001 + #define RNG_CTRL_RNG_RBGEN_DISABLE 0x00000000 ++#define RNG_CTRL_RNG_DIV_CTRL_SHIFT 13 + + #define RNG_SOFT_RESET_OFFSET 0x04 + #define RNG_SOFT_RESET 0x00000001 +@@ -36,16 +37,23 @@ + #define RBG_SOFT_RESET_OFFSET 0x08 + #define RBG_SOFT_RESET 0x00000001 + ++#define RNG_TOTAL_BIT_COUNT_OFFSET 0x0C ++ ++#define RNG_TOTAL_BIT_COUNT_THRESHOLD_OFFSET 0x10 ++ + #define RNG_INT_STATUS_OFFSET 0x18 + #define RNG_INT_STATUS_MASTER_FAIL_LOCKOUT_IRQ_MASK 0x80000000 + #define RNG_INT_STATUS_STARTUP_TRANSITIONS_MET_IRQ_MASK 0x00020000 + #define RNG_INT_STATUS_NIST_FAIL_IRQ_MASK 0x00000020 + #define RNG_INT_STATUS_TOTAL_BITS_COUNT_IRQ_MASK 0x00000001 + ++#define RNG_INT_ENABLE_OFFSET 0x1C ++ + #define RNG_FIFO_DATA_OFFSET 0x20 + + #define RNG_FIFO_COUNT_OFFSET 0x24 + #define RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK 0x000000FF ++#define RNG_FIFO_COUNT_RNG_FIFO_THRESHOLD_SHIFT 8 + + struct iproc_rng200_dev { + struct hwrng rng; +@@ -166,6 +174,64 @@ static int iproc_rng200_init(struct hwrn + return 0; + } + ++static int bcm2838_rng200_read(struct hwrng *rng, void *buf, size_t max, ++ bool wait) ++{ ++ struct iproc_rng200_dev *priv = to_rng_priv(rng); ++ u32 max_words = max / sizeof(u32); ++ u32 num_words, count, val; ++ ++ /* ensure warm up period has elapsed */ ++ while (1) { ++ val = ioread32(priv->base + RNG_TOTAL_BIT_COUNT_OFFSET); ++ if (val > 16) ++ break; ++ cpu_relax(); ++ } ++ ++ /* ensure fifo is not empty */ ++ while (1) { ++ num_words = ioread32(priv->base + RNG_FIFO_COUNT_OFFSET) & ++ RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK; ++ if (num_words) ++ break; ++ if (!wait) ++ return 0; ++ cpu_relax(); ++ } ++ ++ if (num_words > max_words) ++ num_words = max_words; ++ ++ for (count = 0; count < num_words; count++) { ++ ((u32 *)buf)[count] = ioread32(priv->base + ++ RNG_FIFO_DATA_OFFSET); ++ } ++ ++ return num_words * sizeof(u32); ++} ++ ++static int bcm2838_rng200_init(struct hwrng *rng) ++{ ++ struct iproc_rng200_dev *priv = to_rng_priv(rng); ++ uint32_t val; ++ ++ if (ioread32(priv->base + RNG_CTRL_OFFSET) & RNG_CTRL_RNG_RBGEN_MASK) ++ return 0; ++ ++ /* initial numbers generated are "less random" so will be discarded */ ++ val = 0x40000; ++ iowrite32(val, priv->base + RNG_TOTAL_BIT_COUNT_THRESHOLD_OFFSET); ++ /* min fifo count to generate full interrupt */ ++ val = 2 << RNG_FIFO_COUNT_RNG_FIFO_THRESHOLD_SHIFT; ++ iowrite32(val, priv->base + RNG_FIFO_COUNT_OFFSET); ++ /* enable the rng - 1Mhz sample rate */ ++ val = (0x3 << RNG_CTRL_RNG_DIV_CTRL_SHIFT) | RNG_CTRL_RNG_RBGEN_MASK; ++ iowrite32(val, priv->base + RNG_CTRL_OFFSET); ++ ++ return 0; ++} ++ + static void iproc_rng200_cleanup(struct hwrng *rng) + { + struct iproc_rng200_dev *priv = to_rng_priv(rng); +@@ -202,10 +268,16 @@ static int iproc_rng200_probe(struct pla + return PTR_ERR(priv->base); + } + +- priv->rng.name = "iproc-rng200", +- priv->rng.read = iproc_rng200_read, +- priv->rng.init = iproc_rng200_init, +- priv->rng.cleanup = iproc_rng200_cleanup, ++ priv->rng.name = pdev->name; ++ priv->rng.cleanup = iproc_rng200_cleanup; ++ ++ if (of_device_is_compatible(dev->of_node, "brcm,bcm2838-rng200")) { ++ priv->rng.init = bcm2838_rng200_init; ++ priv->rng.read = bcm2838_rng200_read; ++ } else { ++ priv->rng.init = iproc_rng200_init; ++ priv->rng.read = iproc_rng200_read; ++ } + + /* Register driver */ + ret = devm_hwrng_register(dev, &priv->rng); +@@ -222,6 +294,7 @@ static int iproc_rng200_probe(struct pla + static const struct of_device_id iproc_rng200_of_match[] = { + { .compatible = "brcm,bcm7278-rng200", }, + { .compatible = "brcm,iproc-rng200", }, ++ { .compatible = "brcm,bcm2838-rng200"}, + {}, + }; + MODULE_DEVICE_TABLE(of, iproc_rng200_of_match); diff --git a/target/linux/brcm2708/patches-4.19/950-0540-mmc-bcm2835-sdhost-Support-64-bit-physical-addresses.patch b/target/linux/brcm2708/patches-4.19/950-0540-mmc-bcm2835-sdhost-Support-64-bit-physical-addresses.patch deleted file mode 100644 index 7a3e71cff9..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0540-mmc-bcm2835-sdhost-Support-64-bit-physical-addresses.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 6178ee953f25002e50b63af4b77b1f2a58ce17d6 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 29 Aug 2018 09:05:15 +0100 -Subject: [PATCH 540/703] mmc: bcm2835-sdhost: Support 64-bit physical - addresses - -Signed-off-by: Phil Elwell ---- - drivers/mmc/host/bcm2835-sdhost.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -148,7 +148,7 @@ struct bcm2835_host { - spinlock_t lock; - - void __iomem *ioaddr; -- u32 bus_addr; -+ phys_addr_t bus_addr; - - struct mmc_host *mmc; - -@@ -246,8 +246,8 @@ static void log_init(struct device *dev, - sdhost_log_buf = dma_zalloc_coherent(dev, LOG_SIZE, &sdhost_log_addr, - GFP_KERNEL); - if (sdhost_log_buf) { -- pr_info("sdhost: log_buf @ %p (%x)\n", -- sdhost_log_buf, (u32)sdhost_log_addr); -+ pr_info("sdhost: log_buf @ %p (%llx)\n", -+ sdhost_log_buf, (u64)sdhost_log_addr); - timer_base = ioremap_nocache(bus_to_phys + 0x7e003000, SZ_4K); - if (!timer_base) - pr_err("sdhost: failed to remap timer\n"); -@@ -2024,6 +2024,7 @@ static int bcm2835_sdhost_probe(struct p - struct mmc_host *mmc; - const __be32 *addr; - u32 msg[3]; -+ int na; - int ret; - - pr_debug("bcm2835_sdhost_probe\n"); -@@ -2047,12 +2048,13 @@ static int bcm2835_sdhost_probe(struct p - goto err; - } - -+ na = of_n_addr_cells(node); - addr = of_get_address(node, 0, NULL, NULL); - if (!addr) { - dev_err(dev, "could not get DMA-register address\n"); - return -ENODEV; - } -- host->bus_addr = be32_to_cpup(addr); -+ host->bus_addr = (phys_addr_t)of_read_number(addr, na); - pr_debug(" - ioaddr %lx, iomem->start %lx, bus_addr %lx\n", - (unsigned long)host->ioaddr, - (unsigned long)iomem->start, diff --git a/target/linux/brcm2708/patches-4.19/950-0540-thermal-brcmstb_thermal-Add-BCM2838-support.patch b/target/linux/brcm2708/patches-4.19/950-0540-thermal-brcmstb_thermal-Add-BCM2838-support.patch new file mode 100644 index 0000000000..1dcc822b86 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0540-thermal-brcmstb_thermal-Add-BCM2838-support.patch @@ -0,0 +1,162 @@ +From fa0113f19ec808428cad9d92a17d13f17bfbd07e Mon Sep 17 00:00:00 2001 +From: Stefan Wahren +Date: Sat, 18 May 2019 12:26:11 +0200 +Subject: [PATCH 540/725] thermal: brcmstb_thermal: Add BCM2838 support + +The BCM2838 has an AVS TMON hardware block. This adds the necessary +support to the brcmstb_thermal driver ( no trip handling ). + +Signed-off-by: Stefan Wahren +--- + drivers/thermal/broadcom/Kconfig | 2 +- + drivers/thermal/broadcom/brcmstb_thermal.c | 65 +++++++++++++++++++--- + 2 files changed, 58 insertions(+), 9 deletions(-) + +--- a/drivers/thermal/broadcom/Kconfig ++++ b/drivers/thermal/broadcom/Kconfig +@@ -8,7 +8,7 @@ config BCM2835_THERMAL + + config BRCMSTB_THERMAL + tristate "Broadcom STB AVS TMON thermal driver" +- depends on ARCH_BRCMSTB || COMPILE_TEST ++ depends on ARCH_BRCMSTB || ARCH_BCM2835 || COMPILE_TEST + help + Enable this driver if you have a Broadcom STB SoC and would like + thermal framework support. +--- a/drivers/thermal/broadcom/brcmstb_thermal.c ++++ b/drivers/thermal/broadcom/brcmstb_thermal.c +@@ -19,6 +19,7 @@ + #define pr_fmt(fmt) DRV_NAME ": " fmt + + #include ++#include + #include + #include + #include +@@ -31,9 +32,6 @@ + #include + + #define AVS_TMON_STATUS 0x00 +- #define AVS_TMON_STATUS_valid_msk BIT(11) +- #define AVS_TMON_STATUS_data_msk GENMASK(10, 1) +- #define AVS_TMON_STATUS_data_shift 1 + + #define AVS_TMON_EN_OVERTEMP_RESET 0x04 + #define AVS_TMON_EN_OVERTEMP_RESET_msk BIT(0) +@@ -111,10 +109,19 @@ static struct avs_tmon_trip avs_tmon_tri + }, + }; + ++struct brcmstb_thermal_of_data { ++ const struct thermal_zone_of_device_ops *of_ops; ++ u32 status_valid_mask; ++ u32 status_data_mask; ++ u32 status_data_shift; ++}; ++ + struct brcmstb_thermal_priv { + void __iomem *tmon_base; + struct device *dev; + struct thermal_zone_device *thermal; ++ struct clk *clk; ++ const struct brcmstb_thermal_of_data *socdata; + }; + + static void avs_tmon_get_coeffs(struct thermal_zone_device *tz, int *slope, +@@ -164,17 +171,18 @@ static inline u32 avs_tmon_temp_to_code( + static int brcmstb_get_temp(void *data, int *temp) + { + struct brcmstb_thermal_priv *priv = data; ++ const struct brcmstb_thermal_of_data *socdata = priv->socdata; + u32 val; + long t; + + val = __raw_readl(priv->tmon_base + AVS_TMON_STATUS); + +- if (!(val & AVS_TMON_STATUS_valid_msk)) { ++ if (!(val & socdata->status_valid_mask)) { + dev_err(priv->dev, "reading not valid\n"); + return -EIO; + } + +- val = (val & AVS_TMON_STATUS_data_msk) >> AVS_TMON_STATUS_data_shift; ++ val = (val & socdata->status_data_mask) >> socdata->status_data_shift; + + t = avs_tmon_code_to_temp(priv->thermal, val); + if (t < 0) +@@ -299,13 +307,34 @@ static int brcmstb_set_trips(void *data, + return 0; + } + +-static struct thermal_zone_of_device_ops of_ops = { ++static const struct thermal_zone_of_device_ops bcm7445_thermal_of_ops = { + .get_temp = brcmstb_get_temp, + .set_trips = brcmstb_set_trips, + }; + ++static const struct thermal_zone_of_device_ops bcm2838_thermal_of_ops = { ++ .get_temp = brcmstb_get_temp, ++}; ++ ++static const struct brcmstb_thermal_of_data bcm7445_thermal_of_data = { ++ .of_ops = &bcm7445_thermal_of_ops, ++ .status_valid_mask = BIT(11), ++ .status_data_mask = GENMASK(10, 1), ++ .status_data_shift = 1, ++}; ++ ++static const struct brcmstb_thermal_of_data bcm2838_thermal_of_data = { ++ .of_ops = &bcm2838_thermal_of_ops, ++ .status_valid_mask = BIT(10), ++ .status_data_mask = GENMASK(9, 0), ++ .status_data_shift = 0, ++}; ++ + static const struct of_device_id brcmstb_thermal_id_table[] = { +- { .compatible = "brcm,avs-tmon" }, ++ { .compatible = "brcm,avs-tmon", ++ .data = &bcm7445_thermal_of_data }, ++ { .compatible = "brcm,avs-tmon-bcm2838", ++ .data = &bcm2838_thermal_of_data }, + {}, + }; + MODULE_DEVICE_TABLE(of, brcmstb_thermal_id_table); +@@ -326,10 +355,27 @@ static int brcmstb_thermal_probe(struct + if (IS_ERR(priv->tmon_base)) + return PTR_ERR(priv->tmon_base); + ++ priv->socdata = of_device_get_match_data(&pdev->dev); ++ if (!priv->socdata) { ++ dev_err(&pdev->dev, "no device match found\n"); ++ return -ENODEV; ++ } ++ ++ priv->clk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(priv->clk) && PTR_ERR(priv->clk) == -EPROBE_DEFER) ++ return -EPROBE_DEFER; ++ ++ if (!IS_ERR(priv->clk)) { ++ ret = clk_prepare_enable(priv->clk); ++ if (ret) ++ return ret; ++ } ++ + priv->dev = &pdev->dev; + platform_set_drvdata(pdev, priv); + +- thermal = thermal_zone_of_sensor_register(&pdev->dev, 0, priv, &of_ops); ++ thermal = thermal_zone_of_sensor_register(&pdev->dev, 0, priv, ++ priv->socdata->of_ops); + if (IS_ERR(thermal)) { + ret = PTR_ERR(thermal); + dev_err(&pdev->dev, "could not register sensor: %d\n", ret); +@@ -369,6 +415,9 @@ static int brcmstb_thermal_exit(struct p + if (thermal) + thermal_zone_of_sensor_unregister(&pdev->dev, priv->thermal); + ++ if (!IS_ERR(priv->clk)) ++ clk_disable_unprepare(priv->clk); ++ + return 0; + } + diff --git a/target/linux/brcm2708/patches-4.19/950-0541-mmc-sdhci-Mask-spurious-interrupts.patch b/target/linux/brcm2708/patches-4.19/950-0541-mmc-sdhci-Mask-spurious-interrupts.patch deleted file mode 100644 index db2166d4e7..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0541-mmc-sdhci-Mask-spurious-interrupts.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 80e4525509000d3f7faebbc9ea403c9776aab2c5 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 28 Sep 2018 16:24:05 +0100 -Subject: [PATCH 541/703] mmc: sdhci: Mask "spurious" interrupts - -Add a filter for "spurious" Transfer Complete interrupts, attempting -to make it as specific as possible: -* INT_DATA_END (transfer complete) is set -* There is a stop command in progress -* There is no data transfer in progress - -Signed-off-by: Phil Elwell ---- - drivers/mmc/host/sdhci.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/mmc/host/sdhci.c -+++ b/drivers/mmc/host/sdhci.c -@@ -2930,6 +2930,10 @@ static irqreturn_t sdhci_irq(int irq, vo - result = IRQ_WAKE_THREAD; - } - -+ if ((intmask & SDHCI_INT_DATA_END) && !host->data && -+ host->cmd && (host->cmd == host->cmd->mrq->stop)) -+ intmask &= ~SDHCI_INT_DATA_END; -+ - if (intmask & SDHCI_INT_CMD_MASK) - sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK, &intmask); - diff --git a/target/linux/brcm2708/patches-4.19/950-0541-vchiq-Add-36-bit-address-support.patch b/target/linux/brcm2708/patches-4.19/950-0541-vchiq-Add-36-bit-address-support.patch new file mode 100644 index 0000000000..d19059ae57 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0541-vchiq-Add-36-bit-address-support.patch @@ -0,0 +1,196 @@ +From 2d12aba4b1475c04f247b96075ad1a7f65152a23 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 1 Nov 2018 17:31:37 +0000 +Subject: [PATCH 541/725] vchiq: Add 36-bit address support + +Conditional on a new compatible string, change the pagelist encoding +such that the top 24 bits are the pfn, leaving 8 bits for run length +(-1). + +Signed-off-by: Phil Elwell +--- + .../interface/vchiq_arm/vchiq_2835_arm.c | 90 ++++++++++++++----- + .../interface/vchiq_arm/vchiq_arm.c | 6 ++ + .../interface/vchiq_arm/vchiq_arm.h | 1 + + 3 files changed, 75 insertions(+), 22 deletions(-) + +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +@@ -47,6 +47,8 @@ + #include + + #define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) ++#define VC_SAFE(x) (g_use_36bit_addrs ? ((u32)(x) | 0xc0000000) : (u32)(x)) ++#define IS_VC_SAFE(x) (g_use_36bit_addrs ? !((x) & ~0x3fffffffull) : 1) + + #include "vchiq_arm.h" + #include "vchiq_connected.h" +@@ -96,6 +98,7 @@ static void __iomem *g_regs; + */ + static unsigned int g_cache_line_size; + static struct dma_pool *g_dma_pool; ++static unsigned int g_use_36bit_addrs = 0; + static unsigned int g_fragments_size; + static char *g_fragments_base; + static char *g_free_fragments; +@@ -139,6 +142,8 @@ int vchiq_platform_init(struct platform_ + g_cache_line_size = drvdata->cache_line_size; + g_fragments_size = 2 * g_cache_line_size; + ++ g_use_36bit_addrs = (dev->dma_pfn_offset == 0); ++ + /* Allocate space for the channels in coherent memory */ + slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); + frag_mem_size = PAGE_ALIGN(g_fragments_size * MAX_FRAGMENTS); +@@ -150,14 +155,21 @@ int vchiq_platform_init(struct platform_ + return -ENOMEM; + } + ++ if (!IS_VC_SAFE(slot_phys)) { ++ dev_err(dev, "allocated DMA memory %pad is not VC-safe\n", ++ &slot_phys); ++ return -ENOMEM; ++ } ++ + WARN_ON(((unsigned long)slot_mem & (PAGE_SIZE - 1)) != 0); ++ channelbase = VC_SAFE(slot_phys); + + vchiq_slot_zero = vchiq_init_slots(slot_mem, slot_mem_size); + if (!vchiq_slot_zero) + return -EINVAL; + + vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX] = +- (int)slot_phys + slot_mem_size; ++ channelbase + slot_mem_size; + vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] = + MAX_FRAGMENTS; + +@@ -193,7 +205,6 @@ int vchiq_platform_init(struct platform_ + } + + /* Send the base address of the slots to VideoCore */ +- channelbase = slot_phys; + err = rpi_firmware_property(fw, RPI_FIRMWARE_VCHIQ_INIT, + &channelbase, sizeof(channelbase)); + if (err || channelbase) { +@@ -282,7 +293,7 @@ vchiq_prepare_bulk_data(VCHIQ_BULK_T *bu + return VCHIQ_ERROR; + + bulk->handle = memhandle; +- bulk->data = (void *)(unsigned long)pagelistinfo->dma_addr; ++ bulk->data = (void *)VC_SAFE(pagelistinfo->dma_addr); + + /* + * Store the pagelistinfo address in remote_data, +@@ -570,25 +581,60 @@ create_pagelist(char __user *buf, size_t + + /* Combine adjacent blocks for performance */ + k = 0; +- for_each_sg(scatterlist, sg, dma_buffers, i) { +- u32 len = sg_dma_len(sg); +- u32 addr = sg_dma_address(sg); +- +- /* Note: addrs is the address + page_count - 1 +- * The firmware expects blocks after the first to be page- +- * aligned and a multiple of the page size +- */ +- WARN_ON(len == 0); +- WARN_ON(i && (i != (dma_buffers - 1)) && (len & ~PAGE_MASK)); +- WARN_ON(i && (addr & ~PAGE_MASK)); +- if (k > 0 && +- ((addrs[k - 1] & PAGE_MASK) + +- (((addrs[k - 1] & ~PAGE_MASK) + 1) << PAGE_SHIFT)) +- == (addr & PAGE_MASK)) +- addrs[k - 1] += ((len + PAGE_SIZE - 1) >> PAGE_SHIFT); +- else +- addrs[k++] = (addr & PAGE_MASK) | +- (((len + PAGE_SIZE - 1) >> PAGE_SHIFT) - 1); ++ if (g_use_36bit_addrs) { ++ for_each_sg(scatterlist, sg, dma_buffers, i) { ++ u32 len = sg_dma_len(sg); ++ u64 addr = sg_dma_address(sg); ++ u32 page_id = (u32)((addr >> 4) & ~0xff); ++ u32 sg_pages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ ++ /* Note: addrs is the address + page_count - 1 ++ * The firmware expects blocks after the first to be page- ++ * aligned and a multiple of the page size ++ */ ++ WARN_ON(len == 0); ++ WARN_ON(i && ++ (i != (dma_buffers - 1)) && (len & ~PAGE_MASK)); ++ WARN_ON(i && (addr & ~PAGE_MASK)); ++ WARN_ON(upper_32_bits(addr) > 0xf); ++ if (k > 0 && ++ ((addrs[k - 1] & ~0xff) + ++ (((addrs[k - 1] & 0xff) + 1) << 8) ++ == page_id)) { ++ u32 inc_pages = min(sg_pages, ++ 0xff - (addrs[k - 1] & 0xff)); ++ addrs[k - 1] += inc_pages; ++ page_id += inc_pages << 8; ++ sg_pages -= inc_pages; ++ } ++ while (sg_pages) { ++ u32 inc_pages = min(sg_pages, 0x100u); ++ addrs[k++] = page_id | (inc_pages - 1); ++ page_id += inc_pages << 8; ++ sg_pages -= inc_pages; ++ } ++ } ++ } else { ++ for_each_sg(scatterlist, sg, dma_buffers, i) { ++ u32 len = sg_dma_len(sg); ++ u32 addr = VC_SAFE(sg_dma_address(sg)); ++ u32 new_pages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ ++ /* Note: addrs is the address + page_count - 1 ++ * The firmware expects blocks after the first to be page- ++ * aligned and a multiple of the page size ++ */ ++ WARN_ON(len == 0); ++ WARN_ON(i && (i != (dma_buffers - 1)) && (len & ~PAGE_MASK)); ++ WARN_ON(i && (addr & ~PAGE_MASK)); ++ if (k > 0 && ++ ((addrs[k - 1] & PAGE_MASK) + ++ (((addrs[k - 1] & ~PAGE_MASK) + 1) << PAGE_SHIFT)) ++ == (addr & PAGE_MASK)) ++ addrs[k - 1] += new_pages; ++ else ++ addrs[k++] = (addr & PAGE_MASK) | (new_pages - 1); ++ } + } + + /* Partial cache lines (fragments) require special measures */ +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +@@ -181,6 +181,11 @@ static struct vchiq_drvdata bcm2836_drvd + .cache_line_size = 64, + }; + ++static struct vchiq_drvdata bcm2838_drvdata = { ++ .cache_line_size = 64, ++ .use_36bit_addrs = true, ++}; ++ + static const char *const ioctl_names[] = { + "CONNECT", + "SHUTDOWN", +@@ -3618,6 +3623,7 @@ vchiq_register_child(struct platform_dev + static const struct of_device_id vchiq_of_match[] = { + { .compatible = "brcm,bcm2835-vchiq", .data = &bcm2835_drvdata }, + { .compatible = "brcm,bcm2836-vchiq", .data = &bcm2836_drvdata }, ++ { .compatible = "brcm,bcm2838-vchiq", .data = &bcm2838_drvdata }, + {}, + }; + MODULE_DEVICE_TABLE(of, vchiq_of_match); +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h +@@ -125,6 +125,7 @@ typedef struct vchiq_arm_state_struct { + + struct vchiq_drvdata { + const unsigned int cache_line_size; ++ const bool use_36bit_addrs; + struct rpi_firmware *fw; + }; + diff --git a/target/linux/brcm2708/patches-4.19/950-0542-bcm2835-pcm.c-Support-multichannel-audio.patch b/target/linux/brcm2708/patches-4.19/950-0542-bcm2835-pcm.c-Support-multichannel-audio.patch new file mode 100644 index 0000000000..20fa7d9ef8 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0542-bcm2835-pcm.c-Support-multichannel-audio.patch @@ -0,0 +1,46 @@ +From 23793b5dcab413aaf7f7551aaa9473670b111832 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Tue, 30 Apr 2019 19:15:30 +0100 +Subject: [PATCH 542/725] bcm2835-pcm.c: Support multichannel audio + +--- + .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -14,9 +14,9 @@ static const struct snd_pcm_hardware snd + SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_DRAIN_TRIGGER | SNDRV_PCM_INFO_SYNC_APPLPTR), + .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, +- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, ++ .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000, + .rate_min = 8000, +- .rate_max = 48000, ++ .rate_max = 192000, + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = 128 * 1024, +@@ -31,15 +31,16 @@ static const struct snd_pcm_hardware snd + SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_DRAIN_TRIGGER | SNDRV_PCM_INFO_SYNC_APPLPTR), + .formats = SNDRV_PCM_FMTBIT_S16_LE, +- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 | +- SNDRV_PCM_RATE_48000, ++ .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | ++ SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | ++ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, + .rate_min = 44100, +- .rate_max = 48000, ++ .rate_max = 192000, + .channels_min = 2, +- .channels_max = 2, +- .buffer_bytes_max = 128 * 1024, ++ .channels_max = 8, ++ .buffer_bytes_max = 512 * 1024, + .period_bytes_min = 1 * 1024, +- .period_bytes_max = 128 * 1024, ++ .period_bytes_max = 512 * 1024, + .periods_min = 1, + .periods_max = 128, + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0542-mmc-sdhci-iproc-Add-support-for-emmc2-of-the-BCM2838.patch b/target/linux/brcm2708/patches-4.19/950-0542-mmc-sdhci-iproc-Add-support-for-emmc2-of-the-BCM2838.patch deleted file mode 100644 index 148fe99eb5..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0542-mmc-sdhci-iproc-Add-support-for-emmc2-of-the-BCM2838.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 8433b9112a42c8f7b0fefeac50e2f3ebb3ab956c Mon Sep 17 00:00:00 2001 -From: Stefan Wahren -Date: Sat, 27 Apr 2019 12:33:57 +0200 -Subject: [PATCH 542/703] mmc: sdhci-iproc: Add support for emmc2 of the - BCM2838 - -The emmc2 interface of the BCM2838 should be integrated in sdhci-iproc -to avoid code redundancy. Except 32 bit only access no other quirks are -known yet. Add an additional compatible string for upstream proposal. - -Signed-off-by: Stefan Wahren ---- - drivers/mmc/host/sdhci-iproc.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/drivers/mmc/host/sdhci-iproc.c -+++ b/drivers/mmc/host/sdhci-iproc.c -@@ -250,8 +250,18 @@ static const struct sdhci_iproc_data bcm - .mmc_caps = 0x00000000, - }; - -+static const struct sdhci_pltfm_data sdhci_bcm2838_pltfm_data = { -+ .ops = &sdhci_iproc_32only_ops, -+}; -+ -+static const struct sdhci_iproc_data bcm2838_data = { -+ .pdata = &sdhci_bcm2838_pltfm_data, -+}; -+ - static const struct of_device_id sdhci_iproc_of_match[] = { - { .compatible = "brcm,bcm2835-sdhci", .data = &bcm2835_data }, -+ { .compatible = "brcm,bcm2838-sdhci", .data = &bcm2838_data }, -+ { .compatible = "brcm,bcm2711-emmc2", .data = &bcm2838_data }, - { .compatible = "brcm,sdhci-iproc-cygnus", .data = &iproc_cygnus_data}, - { .compatible = "brcm,sdhci-iproc", .data = &iproc_data }, - { } diff --git a/target/linux/brcm2708/patches-4.19/950-0543-bcmgenet-constrain-max-DMA-burst-length.patch b/target/linux/brcm2708/patches-4.19/950-0543-bcmgenet-constrain-max-DMA-burst-length.patch new file mode 100644 index 0000000000..5f9f54247c --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0543-bcmgenet-constrain-max-DMA-burst-length.patch @@ -0,0 +1,20 @@ +From 99f79579e704a5fa56238e8c650289fda6a67071 Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Wed, 12 Sep 2018 14:44:53 +0100 +Subject: [PATCH 543/725] bcmgenet: constrain max DMA burst length + +--- + drivers/net/ethernet/broadcom/genet/bcmgenet.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h +@@ -31,7 +31,7 @@ + #define ENET_PAD 8 + #define ENET_MAX_MTU_SIZE (ETH_DATA_LEN + ETH_HLEN + VLAN_HLEN + \ + ENET_BRCM_TAG_LEN + ETH_FCS_LEN + ENET_PAD) +-#define DMA_MAX_BURST_LENGTH 0x10 ++#define DMA_MAX_BURST_LENGTH 0x08 + + /* misc. configuration */ + #define CLEAR_ALL_HFB 0xFF diff --git a/target/linux/brcm2708/patches-4.19/950-0543-hwrng-iproc-rng200-Add-BCM2838-support.patch b/target/linux/brcm2708/patches-4.19/950-0543-hwrng-iproc-rng200-Add-BCM2838-support.patch deleted file mode 100644 index ae846de43a..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0543-hwrng-iproc-rng200-Add-BCM2838-support.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 60dfcaef2e9fb7fd79b7a87c25cd520b82c6dd02 Mon Sep 17 00:00:00 2001 -From: Stefan Wahren -Date: Sat, 4 May 2019 17:06:15 +0200 -Subject: [PATCH 543/703] hwrng: iproc-rng200: Add BCM2838 support - -The HWRNG on the BCM2838 is compatible to iproc-rng200, so add the -support to this driver instead of bcm2835-rng. - -Signed-off-by: Stefan Wahren ---- - drivers/char/hw_random/Kconfig | 4 +- - drivers/char/hw_random/iproc-rng200.c | 81 +++++++++++++++++++++++++-- - 2 files changed, 79 insertions(+), 6 deletions(-) - ---- a/drivers/char/hw_random/Kconfig -+++ b/drivers/char/hw_random/Kconfig -@@ -89,11 +89,11 @@ config HW_RANDOM_BCM2835 - - config HW_RANDOM_IPROC_RNG200 - tristate "Broadcom iProc/STB RNG200 support" -- depends on ARCH_BCM_IPROC || ARCH_BRCMSTB -+ depends on ARCH_BCM_IPROC || ARCH_BCM2835 || ARCH_BRCMSTB - default HW_RANDOM - ---help--- - This driver provides kernel-side support for the RNG200 -- hardware found on the Broadcom iProc and STB SoCs. -+ hardware found on the Broadcom iProc, BCM2838 and STB SoCs. - - To compile this driver as a module, choose M here: the - module will be called iproc-rng200 ---- a/drivers/char/hw_random/iproc-rng200.c -+++ b/drivers/char/hw_random/iproc-rng200.c -@@ -29,6 +29,7 @@ - #define RNG_CTRL_RNG_RBGEN_MASK 0x00001FFF - #define RNG_CTRL_RNG_RBGEN_ENABLE 0x00000001 - #define RNG_CTRL_RNG_RBGEN_DISABLE 0x00000000 -+#define RNG_CTRL_RNG_DIV_CTRL_SHIFT 13 - - #define RNG_SOFT_RESET_OFFSET 0x04 - #define RNG_SOFT_RESET 0x00000001 -@@ -36,16 +37,23 @@ - #define RBG_SOFT_RESET_OFFSET 0x08 - #define RBG_SOFT_RESET 0x00000001 - -+#define RNG_TOTAL_BIT_COUNT_OFFSET 0x0C -+ -+#define RNG_TOTAL_BIT_COUNT_THRESHOLD_OFFSET 0x10 -+ - #define RNG_INT_STATUS_OFFSET 0x18 - #define RNG_INT_STATUS_MASTER_FAIL_LOCKOUT_IRQ_MASK 0x80000000 - #define RNG_INT_STATUS_STARTUP_TRANSITIONS_MET_IRQ_MASK 0x00020000 - #define RNG_INT_STATUS_NIST_FAIL_IRQ_MASK 0x00000020 - #define RNG_INT_STATUS_TOTAL_BITS_COUNT_IRQ_MASK 0x00000001 - -+#define RNG_INT_ENABLE_OFFSET 0x1C -+ - #define RNG_FIFO_DATA_OFFSET 0x20 - - #define RNG_FIFO_COUNT_OFFSET 0x24 - #define RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK 0x000000FF -+#define RNG_FIFO_COUNT_RNG_FIFO_THRESHOLD_SHIFT 8 - - struct iproc_rng200_dev { - struct hwrng rng; -@@ -166,6 +174,64 @@ static int iproc_rng200_init(struct hwrn - return 0; - } - -+static int bcm2838_rng200_read(struct hwrng *rng, void *buf, size_t max, -+ bool wait) -+{ -+ struct iproc_rng200_dev *priv = to_rng_priv(rng); -+ u32 max_words = max / sizeof(u32); -+ u32 num_words, count, val; -+ -+ /* ensure warm up period has elapsed */ -+ while (1) { -+ val = ioread32(priv->base + RNG_TOTAL_BIT_COUNT_OFFSET); -+ if (val > 16) -+ break; -+ cpu_relax(); -+ } -+ -+ /* ensure fifo is not empty */ -+ while (1) { -+ num_words = ioread32(priv->base + RNG_FIFO_COUNT_OFFSET) & -+ RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK; -+ if (num_words) -+ break; -+ if (!wait) -+ return 0; -+ cpu_relax(); -+ } -+ -+ if (num_words > max_words) -+ num_words = max_words; -+ -+ for (count = 0; count < num_words; count++) { -+ ((u32 *)buf)[count] = ioread32(priv->base + -+ RNG_FIFO_DATA_OFFSET); -+ } -+ -+ return num_words * sizeof(u32); -+} -+ -+static int bcm2838_rng200_init(struct hwrng *rng) -+{ -+ struct iproc_rng200_dev *priv = to_rng_priv(rng); -+ uint32_t val; -+ -+ if (ioread32(priv->base + RNG_CTRL_OFFSET) & RNG_CTRL_RNG_RBGEN_MASK) -+ return 0; -+ -+ /* initial numbers generated are "less random" so will be discarded */ -+ val = 0x40000; -+ iowrite32(val, priv->base + RNG_TOTAL_BIT_COUNT_THRESHOLD_OFFSET); -+ /* min fifo count to generate full interrupt */ -+ val = 2 << RNG_FIFO_COUNT_RNG_FIFO_THRESHOLD_SHIFT; -+ iowrite32(val, priv->base + RNG_FIFO_COUNT_OFFSET); -+ /* enable the rng - 1Mhz sample rate */ -+ val = (0x3 << RNG_CTRL_RNG_DIV_CTRL_SHIFT) | RNG_CTRL_RNG_RBGEN_MASK; -+ iowrite32(val, priv->base + RNG_CTRL_OFFSET); -+ -+ return 0; -+} -+ - static void iproc_rng200_cleanup(struct hwrng *rng) - { - struct iproc_rng200_dev *priv = to_rng_priv(rng); -@@ -202,10 +268,16 @@ static int iproc_rng200_probe(struct pla - return PTR_ERR(priv->base); - } - -- priv->rng.name = "iproc-rng200", -- priv->rng.read = iproc_rng200_read, -- priv->rng.init = iproc_rng200_init, -- priv->rng.cleanup = iproc_rng200_cleanup, -+ priv->rng.name = pdev->name; -+ priv->rng.cleanup = iproc_rng200_cleanup; -+ -+ if (of_device_is_compatible(dev->of_node, "brcm,bcm2838-rng200")) { -+ priv->rng.init = bcm2838_rng200_init; -+ priv->rng.read = bcm2838_rng200_read; -+ } else { -+ priv->rng.init = iproc_rng200_init; -+ priv->rng.read = iproc_rng200_read; -+ } - - /* Register driver */ - ret = devm_hwrng_register(dev, &priv->rng); -@@ -222,6 +294,7 @@ static int iproc_rng200_probe(struct pla - static const struct of_device_id iproc_rng200_of_match[] = { - { .compatible = "brcm,bcm7278-rng200", }, - { .compatible = "brcm,iproc-rng200", }, -+ { .compatible = "brcm,bcm2838-rng200"}, - {}, - }; - MODULE_DEVICE_TABLE(of, iproc_rng200_of_match); diff --git a/target/linux/brcm2708/patches-4.19/950-0544-bcmgenet-Better-coalescing-parameter-defaults.patch b/target/linux/brcm2708/patches-4.19/950-0544-bcmgenet-Better-coalescing-parameter-defaults.patch new file mode 100644 index 0000000000..8802d60348 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0544-bcmgenet-Better-coalescing-parameter-defaults.patch @@ -0,0 +1,43 @@ +From 9e374c8058f9fc6dc4069f2cf878ca941f5836d3 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 27 Mar 2019 13:45:46 +0000 +Subject: [PATCH 544/725] bcmgenet: Better coalescing parameter defaults + +Set defaults for TX and RX packet coalescing to be equivalent to: + + # ethtool -C eth0 tx-frames 10 + # ethtool -C eth0 rx-usecs 50 + +This may be something we want to set via DT parameters in the +future. + +Signed-off-by: Phil Elwell +--- + drivers/net/ethernet/broadcom/genet/bcmgenet.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +@@ -2147,7 +2147,7 @@ static void bcmgenet_init_tx_ring(struct + + bcmgenet_tdma_ring_writel(priv, index, 0, TDMA_PROD_INDEX); + bcmgenet_tdma_ring_writel(priv, index, 0, TDMA_CONS_INDEX); +- bcmgenet_tdma_ring_writel(priv, index, 1, DMA_MBUF_DONE_THRESH); ++ bcmgenet_tdma_ring_writel(priv, index, 10, DMA_MBUF_DONE_THRESH); + /* Disable rate control for now */ + bcmgenet_tdma_ring_writel(priv, index, flow_period_val, + TDMA_FLOW_PERIOD); +@@ -3571,9 +3571,12 @@ static int bcmgenet_probe(struct platfor + netif_set_real_num_rx_queues(priv->dev, priv->hw_params->rx_queues + 1); + + /* Set default coalescing parameters */ +- for (i = 0; i < priv->hw_params->rx_queues; i++) ++ for (i = 0; i < priv->hw_params->rx_queues; i++) { + priv->rx_rings[i].rx_max_coalesced_frames = 1; ++ priv->rx_rings[i].rx_coalesce_usecs = 50; ++ } + priv->rx_rings[DESC_INDEX].rx_max_coalesced_frames = 1; ++ priv->rx_rings[DESC_INDEX].rx_coalesce_usecs = 50; + + /* libphy will determine the link state */ + netif_carrier_off(dev); diff --git a/target/linux/brcm2708/patches-4.19/950-0544-thermal-brcmstb_thermal-Add-BCM2838-support.patch b/target/linux/brcm2708/patches-4.19/950-0544-thermal-brcmstb_thermal-Add-BCM2838-support.patch deleted file mode 100644 index 740da70ecf..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0544-thermal-brcmstb_thermal-Add-BCM2838-support.patch +++ /dev/null @@ -1,162 +0,0 @@ -From bbb17da9724f068cc4cd7620c6d75b09a3d76a96 Mon Sep 17 00:00:00 2001 -From: Stefan Wahren -Date: Sat, 18 May 2019 12:26:11 +0200 -Subject: [PATCH 544/703] thermal: brcmstb_thermal: Add BCM2838 support - -The BCM2838 has an AVS TMON hardware block. This adds the necessary -support to the brcmstb_thermal driver ( no trip handling ). - -Signed-off-by: Stefan Wahren ---- - drivers/thermal/broadcom/Kconfig | 2 +- - drivers/thermal/broadcom/brcmstb_thermal.c | 65 +++++++++++++++++++--- - 2 files changed, 58 insertions(+), 9 deletions(-) - ---- a/drivers/thermal/broadcom/Kconfig -+++ b/drivers/thermal/broadcom/Kconfig -@@ -8,7 +8,7 @@ config BCM2835_THERMAL - - config BRCMSTB_THERMAL - tristate "Broadcom STB AVS TMON thermal driver" -- depends on ARCH_BRCMSTB || COMPILE_TEST -+ depends on ARCH_BRCMSTB || ARCH_BCM2835 || COMPILE_TEST - help - Enable this driver if you have a Broadcom STB SoC and would like - thermal framework support. ---- a/drivers/thermal/broadcom/brcmstb_thermal.c -+++ b/drivers/thermal/broadcom/brcmstb_thermal.c -@@ -19,6 +19,7 @@ - #define pr_fmt(fmt) DRV_NAME ": " fmt - - #include -+#include - #include - #include - #include -@@ -31,9 +32,6 @@ - #include - - #define AVS_TMON_STATUS 0x00 -- #define AVS_TMON_STATUS_valid_msk BIT(11) -- #define AVS_TMON_STATUS_data_msk GENMASK(10, 1) -- #define AVS_TMON_STATUS_data_shift 1 - - #define AVS_TMON_EN_OVERTEMP_RESET 0x04 - #define AVS_TMON_EN_OVERTEMP_RESET_msk BIT(0) -@@ -111,10 +109,19 @@ static struct avs_tmon_trip avs_tmon_tri - }, - }; - -+struct brcmstb_thermal_of_data { -+ const struct thermal_zone_of_device_ops *of_ops; -+ u32 status_valid_mask; -+ u32 status_data_mask; -+ u32 status_data_shift; -+}; -+ - struct brcmstb_thermal_priv { - void __iomem *tmon_base; - struct device *dev; - struct thermal_zone_device *thermal; -+ struct clk *clk; -+ const struct brcmstb_thermal_of_data *socdata; - }; - - static void avs_tmon_get_coeffs(struct thermal_zone_device *tz, int *slope, -@@ -164,17 +171,18 @@ static inline u32 avs_tmon_temp_to_code( - static int brcmstb_get_temp(void *data, int *temp) - { - struct brcmstb_thermal_priv *priv = data; -+ const struct brcmstb_thermal_of_data *socdata = priv->socdata; - u32 val; - long t; - - val = __raw_readl(priv->tmon_base + AVS_TMON_STATUS); - -- if (!(val & AVS_TMON_STATUS_valid_msk)) { -+ if (!(val & socdata->status_valid_mask)) { - dev_err(priv->dev, "reading not valid\n"); - return -EIO; - } - -- val = (val & AVS_TMON_STATUS_data_msk) >> AVS_TMON_STATUS_data_shift; -+ val = (val & socdata->status_data_mask) >> socdata->status_data_shift; - - t = avs_tmon_code_to_temp(priv->thermal, val); - if (t < 0) -@@ -299,13 +307,34 @@ static int brcmstb_set_trips(void *data, - return 0; - } - --static struct thermal_zone_of_device_ops of_ops = { -+static const struct thermal_zone_of_device_ops bcm7445_thermal_of_ops = { - .get_temp = brcmstb_get_temp, - .set_trips = brcmstb_set_trips, - }; - -+static const struct thermal_zone_of_device_ops bcm2838_thermal_of_ops = { -+ .get_temp = brcmstb_get_temp, -+}; -+ -+static const struct brcmstb_thermal_of_data bcm7445_thermal_of_data = { -+ .of_ops = &bcm7445_thermal_of_ops, -+ .status_valid_mask = BIT(11), -+ .status_data_mask = GENMASK(10, 1), -+ .status_data_shift = 1, -+}; -+ -+static const struct brcmstb_thermal_of_data bcm2838_thermal_of_data = { -+ .of_ops = &bcm2838_thermal_of_ops, -+ .status_valid_mask = BIT(10), -+ .status_data_mask = GENMASK(9, 0), -+ .status_data_shift = 0, -+}; -+ - static const struct of_device_id brcmstb_thermal_id_table[] = { -- { .compatible = "brcm,avs-tmon" }, -+ { .compatible = "brcm,avs-tmon", -+ .data = &bcm7445_thermal_of_data }, -+ { .compatible = "brcm,avs-tmon-bcm2838", -+ .data = &bcm2838_thermal_of_data }, - {}, - }; - MODULE_DEVICE_TABLE(of, brcmstb_thermal_id_table); -@@ -326,10 +355,27 @@ static int brcmstb_thermal_probe(struct - if (IS_ERR(priv->tmon_base)) - return PTR_ERR(priv->tmon_base); - -+ priv->socdata = of_device_get_match_data(&pdev->dev); -+ if (!priv->socdata) { -+ dev_err(&pdev->dev, "no device match found\n"); -+ return -ENODEV; -+ } -+ -+ priv->clk = devm_clk_get(&pdev->dev, NULL); -+ if (IS_ERR(priv->clk) && PTR_ERR(priv->clk) == -EPROBE_DEFER) -+ return -EPROBE_DEFER; -+ -+ if (!IS_ERR(priv->clk)) { -+ ret = clk_prepare_enable(priv->clk); -+ if (ret) -+ return ret; -+ } -+ - priv->dev = &pdev->dev; - platform_set_drvdata(pdev, priv); - -- thermal = thermal_zone_of_sensor_register(&pdev->dev, 0, priv, &of_ops); -+ thermal = thermal_zone_of_sensor_register(&pdev->dev, 0, priv, -+ priv->socdata->of_ops); - if (IS_ERR(thermal)) { - ret = PTR_ERR(thermal); - dev_err(&pdev->dev, "could not register sensor: %d\n", ret); -@@ -369,6 +415,9 @@ static int brcmstb_thermal_exit(struct p - if (thermal) - thermal_zone_of_sensor_unregister(&pdev->dev, priv->thermal); - -+ if (!IS_ERR(priv->clk)) -+ clk_disable_unprepare(priv->clk); -+ - return 0; - } - diff --git a/target/linux/brcm2708/patches-4.19/950-0545-net-genet-enable-link-energy-detect-powerdown-for-ex.patch b/target/linux/brcm2708/patches-4.19/950-0545-net-genet-enable-link-energy-detect-powerdown-for-ex.patch new file mode 100644 index 0000000000..44b62f1979 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0545-net-genet-enable-link-energy-detect-powerdown-for-ex.patch @@ -0,0 +1,34 @@ +From fd72c4f7da285c5dee66f01cdec075a5d863a3a3 Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Tue, 14 May 2019 17:17:59 +0100 +Subject: [PATCH 545/725] net: genet: enable link energy detect powerdown for + external PHYs + +There are several warts surrounding bcmgenet_mii_probe() as this +function is called from ndo_open, but it's calling registration-type +functions. The probe should be called at probe time and refactored +such that the PHY device data can be extracted to limit the scope +of this flag to Broadcom PHYs. + +For now, pass this flag in as it puts our attached PHY into a low-power +state when disconnected. + +Signed-off-by: Jonathan Bell +--- + drivers/net/ethernet/broadcom/genet/bcmmii.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c +@@ -280,7 +280,10 @@ int bcmgenet_mii_probe(struct net_device + int ret; + + /* Communicate the integrated PHY revision */ +- phy_flags = priv->gphy_rev; ++ if (priv->internal_phy) ++ phy_flags = priv->gphy_rev; ++ else ++ phy_flags = PHY_BRCM_AUTO_PWRDWN_ENABLE; + + /* Initialize link state variables that bcmgenet_mii_setup() uses */ + priv->old_link = -1; diff --git a/target/linux/brcm2708/patches-4.19/950-0545-vchiq-Add-36-bit-address-support.patch b/target/linux/brcm2708/patches-4.19/950-0545-vchiq-Add-36-bit-address-support.patch deleted file mode 100644 index eeb53b4e86..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0545-vchiq-Add-36-bit-address-support.patch +++ /dev/null @@ -1,196 +0,0 @@ -From f9625d8ee77e57593af378a1d60708fc8d43db46 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 1 Nov 2018 17:31:37 +0000 -Subject: [PATCH 545/703] vchiq: Add 36-bit address support - -Conditional on a new compatible string, change the pagelist encoding -such that the top 24 bits are the pfn, leaving 8 bits for run length -(-1). - -Signed-off-by: Phil Elwell ---- - .../interface/vchiq_arm/vchiq_2835_arm.c | 90 ++++++++++++++----- - .../interface/vchiq_arm/vchiq_arm.c | 6 ++ - .../interface/vchiq_arm/vchiq_arm.h | 1 + - 3 files changed, 75 insertions(+), 22 deletions(-) - ---- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -@@ -47,6 +47,8 @@ - #include - - #define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) -+#define VC_SAFE(x) (g_use_36bit_addrs ? ((u32)(x) | 0xc0000000) : (u32)(x)) -+#define IS_VC_SAFE(x) (g_use_36bit_addrs ? !((x) & ~0x3fffffffull) : 1) - - #include "vchiq_arm.h" - #include "vchiq_connected.h" -@@ -96,6 +98,7 @@ static void __iomem *g_regs; - */ - static unsigned int g_cache_line_size; - static struct dma_pool *g_dma_pool; -+static unsigned int g_use_36bit_addrs = 0; - static unsigned int g_fragments_size; - static char *g_fragments_base; - static char *g_free_fragments; -@@ -139,6 +142,8 @@ int vchiq_platform_init(struct platform_ - g_cache_line_size = drvdata->cache_line_size; - g_fragments_size = 2 * g_cache_line_size; - -+ g_use_36bit_addrs = (dev->dma_pfn_offset == 0); -+ - /* Allocate space for the channels in coherent memory */ - slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); - frag_mem_size = PAGE_ALIGN(g_fragments_size * MAX_FRAGMENTS); -@@ -150,14 +155,21 @@ int vchiq_platform_init(struct platform_ - return -ENOMEM; - } - -+ if (!IS_VC_SAFE(slot_phys)) { -+ dev_err(dev, "allocated DMA memory %pad is not VC-safe\n", -+ &slot_phys); -+ return -ENOMEM; -+ } -+ - WARN_ON(((unsigned long)slot_mem & (PAGE_SIZE - 1)) != 0); -+ channelbase = VC_SAFE(slot_phys); - - vchiq_slot_zero = vchiq_init_slots(slot_mem, slot_mem_size); - if (!vchiq_slot_zero) - return -EINVAL; - - vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX] = -- (int)slot_phys + slot_mem_size; -+ channelbase + slot_mem_size; - vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] = - MAX_FRAGMENTS; - -@@ -193,7 +205,6 @@ int vchiq_platform_init(struct platform_ - } - - /* Send the base address of the slots to VideoCore */ -- channelbase = slot_phys; - err = rpi_firmware_property(fw, RPI_FIRMWARE_VCHIQ_INIT, - &channelbase, sizeof(channelbase)); - if (err || channelbase) { -@@ -282,7 +293,7 @@ vchiq_prepare_bulk_data(VCHIQ_BULK_T *bu - return VCHIQ_ERROR; - - bulk->handle = memhandle; -- bulk->data = (void *)(unsigned long)pagelistinfo->dma_addr; -+ bulk->data = (void *)VC_SAFE(pagelistinfo->dma_addr); - - /* - * Store the pagelistinfo address in remote_data, -@@ -570,25 +581,60 @@ create_pagelist(char __user *buf, size_t - - /* Combine adjacent blocks for performance */ - k = 0; -- for_each_sg(scatterlist, sg, dma_buffers, i) { -- u32 len = sg_dma_len(sg); -- u32 addr = sg_dma_address(sg); -- -- /* Note: addrs is the address + page_count - 1 -- * The firmware expects blocks after the first to be page- -- * aligned and a multiple of the page size -- */ -- WARN_ON(len == 0); -- WARN_ON(i && (i != (dma_buffers - 1)) && (len & ~PAGE_MASK)); -- WARN_ON(i && (addr & ~PAGE_MASK)); -- if (k > 0 && -- ((addrs[k - 1] & PAGE_MASK) + -- (((addrs[k - 1] & ~PAGE_MASK) + 1) << PAGE_SHIFT)) -- == (addr & PAGE_MASK)) -- addrs[k - 1] += ((len + PAGE_SIZE - 1) >> PAGE_SHIFT); -- else -- addrs[k++] = (addr & PAGE_MASK) | -- (((len + PAGE_SIZE - 1) >> PAGE_SHIFT) - 1); -+ if (g_use_36bit_addrs) { -+ for_each_sg(scatterlist, sg, dma_buffers, i) { -+ u32 len = sg_dma_len(sg); -+ u64 addr = sg_dma_address(sg); -+ u32 page_id = (u32)((addr >> 4) & ~0xff); -+ u32 sg_pages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ -+ /* Note: addrs is the address + page_count - 1 -+ * The firmware expects blocks after the first to be page- -+ * aligned and a multiple of the page size -+ */ -+ WARN_ON(len == 0); -+ WARN_ON(i && -+ (i != (dma_buffers - 1)) && (len & ~PAGE_MASK)); -+ WARN_ON(i && (addr & ~PAGE_MASK)); -+ WARN_ON(upper_32_bits(addr) > 0xf); -+ if (k > 0 && -+ ((addrs[k - 1] & ~0xff) + -+ (((addrs[k - 1] & 0xff) + 1) << 8) -+ == page_id)) { -+ u32 inc_pages = min(sg_pages, -+ 0xff - (addrs[k - 1] & 0xff)); -+ addrs[k - 1] += inc_pages; -+ page_id += inc_pages << 8; -+ sg_pages -= inc_pages; -+ } -+ while (sg_pages) { -+ u32 inc_pages = min(sg_pages, 0x100u); -+ addrs[k++] = page_id | (inc_pages - 1); -+ page_id += inc_pages << 8; -+ sg_pages -= inc_pages; -+ } -+ } -+ } else { -+ for_each_sg(scatterlist, sg, dma_buffers, i) { -+ u32 len = sg_dma_len(sg); -+ u32 addr = VC_SAFE(sg_dma_address(sg)); -+ u32 new_pages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ -+ /* Note: addrs is the address + page_count - 1 -+ * The firmware expects blocks after the first to be page- -+ * aligned and a multiple of the page size -+ */ -+ WARN_ON(len == 0); -+ WARN_ON(i && (i != (dma_buffers - 1)) && (len & ~PAGE_MASK)); -+ WARN_ON(i && (addr & ~PAGE_MASK)); -+ if (k > 0 && -+ ((addrs[k - 1] & PAGE_MASK) + -+ (((addrs[k - 1] & ~PAGE_MASK) + 1) << PAGE_SHIFT)) -+ == (addr & PAGE_MASK)) -+ addrs[k - 1] += new_pages; -+ else -+ addrs[k++] = (addr & PAGE_MASK) | (new_pages - 1); -+ } - } - - /* Partial cache lines (fragments) require special measures */ ---- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -181,6 +181,11 @@ static struct vchiq_drvdata bcm2836_drvd - .cache_line_size = 64, - }; - -+static struct vchiq_drvdata bcm2838_drvdata = { -+ .cache_line_size = 64, -+ .use_36bit_addrs = true, -+}; -+ - static const char *const ioctl_names[] = { - "CONNECT", - "SHUTDOWN", -@@ -3618,6 +3623,7 @@ vchiq_register_child(struct platform_dev - static const struct of_device_id vchiq_of_match[] = { - { .compatible = "brcm,bcm2835-vchiq", .data = &bcm2835_drvdata }, - { .compatible = "brcm,bcm2836-vchiq", .data = &bcm2836_drvdata }, -+ { .compatible = "brcm,bcm2838-vchiq", .data = &bcm2838_drvdata }, - {}, - }; - MODULE_DEVICE_TABLE(of, vchiq_of_match); ---- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h -+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h -@@ -125,6 +125,7 @@ typedef struct vchiq_arm_state_struct { - - struct vchiq_drvdata { - const unsigned int cache_line_size; -+ const bool use_36bit_addrs; - struct rpi_firmware *fw; - }; - diff --git a/target/linux/brcm2708/patches-4.19/950-0546-bcm2835-pcm.c-Support-multichannel-audio.patch b/target/linux/brcm2708/patches-4.19/950-0546-bcm2835-pcm.c-Support-multichannel-audio.patch deleted file mode 100644 index e79433f152..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0546-bcm2835-pcm.c-Support-multichannel-audio.patch +++ /dev/null @@ -1,46 +0,0 @@ -From d1712d177a85f00eaf359d9b479841bb21239adb Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 30 Apr 2019 19:15:30 +0100 -Subject: [PATCH 546/703] bcm2835-pcm.c: Support multichannel audio - ---- - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 17 +++++++++-------- - 1 file changed, 9 insertions(+), 8 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -14,9 +14,9 @@ static const struct snd_pcm_hardware snd - SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_DRAIN_TRIGGER | SNDRV_PCM_INFO_SYNC_APPLPTR), - .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, -- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, -+ .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000, - .rate_min = 8000, -- .rate_max = 48000, -+ .rate_max = 192000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = 128 * 1024, -@@ -31,15 +31,16 @@ static const struct snd_pcm_hardware snd - SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_DRAIN_TRIGGER | SNDRV_PCM_INFO_SYNC_APPLPTR), - .formats = SNDRV_PCM_FMTBIT_S16_LE, -- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 | -- SNDRV_PCM_RATE_48000, -+ .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | -+ SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | -+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, - .rate_min = 44100, -- .rate_max = 48000, -+ .rate_max = 192000, - .channels_min = 2, -- .channels_max = 2, -- .buffer_bytes_max = 128 * 1024, -+ .channels_max = 8, -+ .buffer_bytes_max = 512 * 1024, - .period_bytes_min = 1 * 1024, -- .period_bytes_max = 128 * 1024, -+ .period_bytes_max = 512 * 1024, - .periods_min = 1, - .periods_max = 128, - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0546-phy-broadcom-split-out-the-BCM54213PE-from-the-BCM54.patch b/target/linux/brcm2708/patches-4.19/950-0546-phy-broadcom-split-out-the-BCM54213PE-from-the-BCM54.patch new file mode 100644 index 0000000000..ce80672775 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0546-phy-broadcom-split-out-the-BCM54213PE-from-the-BCM54.patch @@ -0,0 +1,73 @@ +From 21e3d91c32f71881ca5d8fba428a2ebe55398760 Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Tue, 14 May 2019 17:00:41 +0100 +Subject: [PATCH 546/725] phy: broadcom: split out the BCM54213PE from the + BCM54210E IDs + +The last nibble is a revision ID, and the 54213pe is a later rev +than the 54210e. Running the 54210e setup code on a 54213pe results +in a broken RGMII interface. + +Signed-off-by: Jonathan Bell +--- + drivers/net/phy/broadcom.c | 17 ++++++++++++++--- + include/linux/brcmphy.h | 1 + + 2 files changed, 15 insertions(+), 3 deletions(-) + +--- a/drivers/net/phy/broadcom.c ++++ b/drivers/net/phy/broadcom.c +@@ -222,7 +222,8 @@ static void bcm54xx_adjust_rxrefclk(stru + /* Abort if we are using an untested phy. */ + if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 && + BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 && +- BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M) ++ BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M && ++ BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54213PE) + return; + + val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR3); +@@ -604,7 +605,7 @@ static struct phy_driver broadcom_driver + .config_intr = bcm_phy_config_intr, + }, { + .phy_id = PHY_ID_BCM54210E, +- .phy_id_mask = 0xfffffff0, ++ .phy_id_mask = 0xffffffff, + .name = "Broadcom BCM54210E", + .features = PHY_GBIT_FEATURES, + .flags = PHY_HAS_INTERRUPT, +@@ -612,6 +613,15 @@ static struct phy_driver broadcom_driver + .ack_interrupt = bcm_phy_ack_intr, + .config_intr = bcm_phy_config_intr, + }, { ++ .phy_id = PHY_ID_BCM54213PE, ++ .phy_id_mask = 0xffffffff, ++ .name = "Broadcom BCM54213PE", ++ .features = PHY_GBIT_FEATURES, ++ .flags = PHY_HAS_INTERRUPT, ++ .config_init = bcm54xx_config_init, ++ .ack_interrupt = bcm_phy_ack_intr, ++ .config_intr = bcm_phy_config_intr, ++}, { + .phy_id = PHY_ID_BCM5461, + .phy_id_mask = 0xfffffff0, + .name = "Broadcom BCM5461", +@@ -748,7 +758,8 @@ module_phy_driver(broadcom_drivers); + static struct mdio_device_id __maybe_unused broadcom_tbl[] = { + { PHY_ID_BCM5411, 0xfffffff0 }, + { PHY_ID_BCM5421, 0xfffffff0 }, +- { PHY_ID_BCM54210E, 0xfffffff0 }, ++ { PHY_ID_BCM54210E, 0xffffffff }, ++ { PHY_ID_BCM54213PE, 0xffffffff }, + { PHY_ID_BCM5461, 0xfffffff0 }, + { PHY_ID_BCM54612E, 0xfffffff0 }, + { PHY_ID_BCM54616S, 0xfffffff0 }, +--- a/include/linux/brcmphy.h ++++ b/include/linux/brcmphy.h +@@ -20,6 +20,7 @@ + #define PHY_ID_BCM5411 0x00206070 + #define PHY_ID_BCM5421 0x002060e0 + #define PHY_ID_BCM54210E 0x600d84a0 ++#define PHY_ID_BCM54213PE 0x600d84a2 + #define PHY_ID_BCM5464 0x002060b0 + #define PHY_ID_BCM5461 0x002060c0 + #define PHY_ID_BCM54612E 0x03625e60 diff --git a/target/linux/brcm2708/patches-4.19/950-0547-bcmgenet-constrain-max-DMA-burst-length.patch b/target/linux/brcm2708/patches-4.19/950-0547-bcmgenet-constrain-max-DMA-burst-length.patch deleted file mode 100644 index 8cc5acc63e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0547-bcmgenet-constrain-max-DMA-burst-length.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 9c341c10cd2ad2a61f084dc222fd380ed1687f50 Mon Sep 17 00:00:00 2001 -From: Jonathan Bell -Date: Wed, 12 Sep 2018 14:44:53 +0100 -Subject: [PATCH 547/703] bcmgenet: constrain max DMA burst length - ---- - drivers/net/ethernet/broadcom/genet/bcmgenet.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h -+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h -@@ -31,7 +31,7 @@ - #define ENET_PAD 8 - #define ENET_MAX_MTU_SIZE (ETH_DATA_LEN + ETH_HLEN + VLAN_HLEN + \ - ENET_BRCM_TAG_LEN + ETH_FCS_LEN + ENET_PAD) --#define DMA_MAX_BURST_LENGTH 0x10 -+#define DMA_MAX_BURST_LENGTH 0x08 - - /* misc. configuration */ - #define CLEAR_ALL_HFB 0xFF diff --git a/target/linux/brcm2708/patches-4.19/950-0547-phy-bcm54213pe-configure-the-LED-outputs-to-be-more-.patch b/target/linux/brcm2708/patches-4.19/950-0547-phy-bcm54213pe-configure-the-LED-outputs-to-be-more-.patch new file mode 100644 index 0000000000..cb28cf29f9 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0547-phy-bcm54213pe-configure-the-LED-outputs-to-be-more-.patch @@ -0,0 +1,64 @@ +From 6873c605ba15e36bbc5efffd3b86caab09c9ce5a Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Fri, 17 May 2019 13:31:21 +0100 +Subject: [PATCH 547/725] phy: bcm54213pe: configure the LED outputs to be more + user-friendly + +The default state was both LEDs indicating link speed. + +Change the default configuration to +- Amber: 1000/100 link speed indication +- Green: link present + activity indication + +Signed-off-by: Jonathan Bell +--- + drivers/net/phy/broadcom.c | 17 +++++++++++++++++ + include/linux/brcmphy.h | 4 ++++ + 2 files changed, 21 insertions(+) + +--- a/drivers/net/phy/broadcom.c ++++ b/drivers/net/phy/broadcom.c +@@ -52,6 +52,21 @@ static int bcm54210e_config_init(struct + return 0; + } + ++static void bcm54213pe_config_init(struct phy_device *phydev) ++{ ++ u16 val; ++ ++ /* Enable ACT+LINK indication on ACTIVITY trigger */ ++ val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_LEDCTL); ++ val |= BCM54XX_SHD_LEDCTL_ACTLINK_EN; ++ bcm_phy_write_shadow(phydev, BCM54XX_SHD_LEDCTL, val); ++ ++ /* Set ACTIVITY on LED "1" output, LINKSPD[1] on LED "3" output */ ++ val = BCM5482_SHD_LEDS1_LED1(BCM_LED_SRC_ACTIVITYLED) | ++ BCM5482_SHD_LEDS1_LED3(BCM_LED_SRC_LINKSPD1); ++ bcm_phy_write_shadow(phydev, BCM5482_SHD_LEDS1, val); ++} ++ + static int bcm54612e_config_init(struct phy_device *phydev) + { + int reg; +@@ -310,6 +325,8 @@ static int bcm54xx_config_init(struct ph + err = bcm54210e_config_init(phydev); + if (err) + return err; ++ } else if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54213PE) { ++ bcm54213pe_config_init(phydev); + } else if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54612E) { + err = bcm54612e_config_init(phydev); + if (err) +--- a/include/linux/brcmphy.h ++++ b/include/linux/brcmphy.h +@@ -168,6 +168,10 @@ + #define BCM54XX_SHD_SCR3_DLLAPD_DIS 0x0002 + #define BCM54XX_SHD_SCR3_TRDDAPD 0x0004 + ++/* 01001: Additional LED trigger options */ ++#define BCM54XX_SHD_LEDCTL 0x09 ++#define BCM54XX_SHD_LEDCTL_ACTLINK_EN 0x0010 ++ + /* 01010: Auto Power-Down */ + #define BCM54XX_SHD_APD 0x0a + #define BCM_APD_CLR_MASK 0xFE9F /* clear bits 5, 6 & 8 */ diff --git a/target/linux/brcm2708/patches-4.19/950-0548-bcmgenet-Better-coalescing-parameter-defaults.patch b/target/linux/brcm2708/patches-4.19/950-0548-bcmgenet-Better-coalescing-parameter-defaults.patch deleted file mode 100644 index 3577fcdb5b..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0548-bcmgenet-Better-coalescing-parameter-defaults.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 8d30a996253c537f4978910aabf1e098bac8fa1a Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 27 Mar 2019 13:45:46 +0000 -Subject: [PATCH 548/703] bcmgenet: Better coalescing parameter defaults - -Set defaults for TX and RX packet coalescing to be equivalent to: - - # ethtool -C eth0 tx-frames 10 - # ethtool -C eth0 rx-usecs 50 - -This may be something we want to set via DT parameters in the -future. - -Signed-off-by: Phil Elwell ---- - drivers/net/ethernet/broadcom/genet/bcmgenet.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c -+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c -@@ -2147,7 +2147,7 @@ static void bcmgenet_init_tx_ring(struct - - bcmgenet_tdma_ring_writel(priv, index, 0, TDMA_PROD_INDEX); - bcmgenet_tdma_ring_writel(priv, index, 0, TDMA_CONS_INDEX); -- bcmgenet_tdma_ring_writel(priv, index, 1, DMA_MBUF_DONE_THRESH); -+ bcmgenet_tdma_ring_writel(priv, index, 10, DMA_MBUF_DONE_THRESH); - /* Disable rate control for now */ - bcmgenet_tdma_ring_writel(priv, index, flow_period_val, - TDMA_FLOW_PERIOD); -@@ -3571,9 +3571,12 @@ static int bcmgenet_probe(struct platfor - netif_set_real_num_rx_queues(priv->dev, priv->hw_params->rx_queues + 1); - - /* Set default coalescing parameters */ -- for (i = 0; i < priv->hw_params->rx_queues; i++) -+ for (i = 0; i < priv->hw_params->rx_queues; i++) { - priv->rx_rings[i].rx_max_coalesced_frames = 1; -+ priv->rx_rings[i].rx_coalesce_usecs = 50; -+ } - priv->rx_rings[DESC_INDEX].rx_max_coalesced_frames = 1; -+ priv->rx_rings[DESC_INDEX].rx_coalesce_usecs = 50; - - /* libphy will determine the link state */ - netif_carrier_off(dev); diff --git a/target/linux/brcm2708/patches-4.19/950-0548-dwc_otg-Choose-appropriate-IRQ-handover-strategy.patch b/target/linux/brcm2708/patches-4.19/950-0548-dwc_otg-Choose-appropriate-IRQ-handover-strategy.patch new file mode 100644 index 0000000000..06b8032356 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0548-dwc_otg-Choose-appropriate-IRQ-handover-strategy.patch @@ -0,0 +1,181 @@ +From 1fa7016f17e440f19a7895b795384f105772dbfe Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 21 May 2019 13:36:52 +0100 +Subject: [PATCH 548/725] dwc_otg: Choose appropriate IRQ handover strategy + +2711 has no MPHI peripheral, but the ARM Control block can fake +interrupts. Use the size of the DTB "mphi" reg block to determine +which is required. + +Signed-off-by: Phil Elwell +--- + drivers/usb/host/dwc_otg/dwc_otg_driver.c | 9 +++-- + drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 21 ++++++---- + drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h | 2 + + drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 12 ++++-- + drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 41 +++++++++++++------- + drivers/usb/host/dwc_otg/dwc_otg_os_dep.h | 3 ++ + 6 files changed, 60 insertions(+), 28 deletions(-) + +--- a/drivers/usb/host/dwc_otg/dwc_otg_driver.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c +@@ -806,14 +806,15 @@ static int dwc_otg_driver_probe( + if (!request_mem_region(_dev->resource[1].start, + _dev->resource[1].end - _dev->resource[1].start + 1, + "dwc_otg")) { +- dev_dbg(&_dev->dev, "error reserving mapped memory\n"); +- retval = -EFAULT; +- goto fail; +- } ++ dev_dbg(&_dev->dev, "error reserving mapped memory\n"); ++ retval = -EFAULT; ++ goto fail; ++ } + + dwc_otg_device->os_dep.mphi_base = ioremap_nocache(_dev->resource[1].start, + _dev->resource[1].end - + _dev->resource[1].start + 1); ++ dwc_otg_device->os_dep.use_swirq = (_dev->resource[1].end - _dev->resource[1].start) == 0x200; + } + + #else +--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c +@@ -1347,8 +1347,12 @@ void notrace dwc_otg_fiq_fsm(struct fiq_ + /* We got an interrupt, didn't handle it. */ + if (kick_irq) { + state->mphi_int_count++; +- FIQ_WRITE(state->mphi_regs.outdda, state->dummy_send_dma); +- FIQ_WRITE(state->mphi_regs.outddb, (1<<29)); ++ if (state->mphi_regs.swirq_set) { ++ FIQ_WRITE(state->mphi_regs.swirq_set, 1); ++ } else { ++ FIQ_WRITE(state->mphi_regs.outdda, state->dummy_send_dma); ++ FIQ_WRITE(state->mphi_regs.outddb, (1<<29)); ++ } + + } + state->fiq_done++; +@@ -1406,11 +1410,14 @@ void notrace dwc_otg_fiq_nop(struct fiq_ + state->mphi_int_count++; + gintmsk.d32 &= state->gintmsk_saved.d32; + FIQ_WRITE(state->dwc_regs_base + GINTMSK, gintmsk.d32); +- /* Force a clear before another dummy send */ +- FIQ_WRITE(state->mphi_regs.intstat, (1<<29)); +- FIQ_WRITE(state->mphi_regs.outdda, state->dummy_send_dma); +- FIQ_WRITE(state->mphi_regs.outddb, (1<<29)); +- ++ if (state->mphi_regs.swirq_set) { ++ FIQ_WRITE(state->mphi_regs.swirq_set, 1); ++ } else { ++ /* Force a clear before another dummy send */ ++ FIQ_WRITE(state->mphi_regs.intstat, (1<<29)); ++ FIQ_WRITE(state->mphi_regs.outdda, state->dummy_send_dma); ++ FIQ_WRITE(state->mphi_regs.outddb, (1<<29)); ++ } + } + state->fiq_done++; + mb(); +--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h ++++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h +@@ -118,6 +118,8 @@ typedef struct { + volatile void* outdda; + volatile void* outddb; + volatile void* intstat; ++ volatile void* swirq_set; ++ volatile void* swirq_clr; + } mphi_regs_t; + + enum fiq_debug_level { +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c +@@ -220,16 +220,20 @@ exit_handler_routine: + + /* The FIQ could have sneaked another interrupt in. If so, don't clear MPHI */ + if ((gintmsk_new.d32 == ~0) && (haintmsk_new.d32 == 0x0000FFFF)) { ++ if (dwc_otg_hcd->fiq_state->mphi_regs.swirq_clr) { ++ DWC_WRITE_REG32(dwc_otg_hcd->fiq_state->mphi_regs.swirq_clr, 1); ++ } else { + DWC_WRITE_REG32(dwc_otg_hcd->fiq_state->mphi_regs.intstat, (1<<16)); +- if (dwc_otg_hcd->fiq_state->mphi_int_count >= 50) { +- fiq_print(FIQDBG_INT, dwc_otg_hcd->fiq_state, "MPHI CLR"); ++ } ++ if (dwc_otg_hcd->fiq_state->mphi_int_count >= 50) { ++ fiq_print(FIQDBG_INT, dwc_otg_hcd->fiq_state, "MPHI CLR"); + DWC_WRITE_REG32(dwc_otg_hcd->fiq_state->mphi_regs.ctrl, ((1<<31) + (1<<16))); + while (!(DWC_READ_REG32(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & (1 << 17))) + ; + DWC_WRITE_REG32(dwc_otg_hcd->fiq_state->mphi_regs.ctrl, (1<<31)); + dwc_otg_hcd->fiq_state->mphi_int_count = 0; +- } +- int_done++; ++ } ++ int_done++; + } + haintmsk.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->haintmsk); + /* Re-enable interrupts that the FIQ masked (first time round) */ +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c +@@ -474,22 +474,37 @@ static void hcd_init_fiq(void *cookie) + set_fiq_regs(®s); + #endif + +- //Set the mphi periph to the required registers +- dwc_otg_hcd->fiq_state->mphi_regs.base = otg_dev->os_dep.mphi_base; +- dwc_otg_hcd->fiq_state->mphi_regs.ctrl = otg_dev->os_dep.mphi_base + 0x4c; +- dwc_otg_hcd->fiq_state->mphi_regs.outdda = otg_dev->os_dep.mphi_base + 0x28; +- dwc_otg_hcd->fiq_state->mphi_regs.outddb = otg_dev->os_dep.mphi_base + 0x2c; +- dwc_otg_hcd->fiq_state->mphi_regs.intstat = otg_dev->os_dep.mphi_base + 0x50; + dwc_otg_hcd->fiq_state->dwc_regs_base = otg_dev->os_dep.base; +- DWC_WARN("MPHI regs_base at %px", dwc_otg_hcd->fiq_state->mphi_regs.base); +- //Enable mphi peripheral +- writel((1<<31),dwc_otg_hcd->fiq_state->mphi_regs.ctrl); ++ //Set the mphi periph to the required registers ++ dwc_otg_hcd->fiq_state->mphi_regs.base = otg_dev->os_dep.mphi_base; ++ if (otg_dev->os_dep.use_swirq) { ++ dwc_otg_hcd->fiq_state->mphi_regs.swirq_set = ++ otg_dev->os_dep.mphi_base + 0x1f0; ++ dwc_otg_hcd->fiq_state->mphi_regs.swirq_clr = ++ otg_dev->os_dep.mphi_base + 0x1f4; ++ DWC_WARN("Fake MPHI regs_base at 0x%08x", ++ (int)dwc_otg_hcd->fiq_state->mphi_regs.base); ++ } else { ++ dwc_otg_hcd->fiq_state->mphi_regs.ctrl = ++ otg_dev->os_dep.mphi_base + 0x4c; ++ dwc_otg_hcd->fiq_state->mphi_regs.outdda ++ = otg_dev->os_dep.mphi_base + 0x28; ++ dwc_otg_hcd->fiq_state->mphi_regs.outddb ++ = otg_dev->os_dep.mphi_base + 0x2c; ++ dwc_otg_hcd->fiq_state->mphi_regs.intstat ++ = otg_dev->os_dep.mphi_base + 0x50; ++ DWC_WARN("MPHI regs_base at %px", ++ dwc_otg_hcd->fiq_state->mphi_regs.base); ++ ++ //Enable mphi peripheral ++ writel((1<<31),dwc_otg_hcd->fiq_state->mphi_regs.ctrl); + #ifdef DEBUG +- if (readl(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & 0x80000000) +- DWC_WARN("MPHI periph has been enabled"); +- else +- DWC_WARN("MPHI periph has NOT been enabled"); ++ if (readl(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & 0x80000000) ++ DWC_WARN("MPHI periph has been enabled"); ++ else ++ DWC_WARN("MPHI periph has NOT been enabled"); + #endif ++ } + // Enable FIQ interrupt from USB peripheral + #ifdef CONFIG_ARM64 + irq = otg_dev->os_dep.fiq_num; +--- a/drivers/usb/host/dwc_otg/dwc_otg_os_dep.h ++++ b/drivers/usb/host/dwc_otg/dwc_otg_os_dep.h +@@ -102,6 +102,9 @@ typedef struct os_dependent { + /** Base address for MPHI peripheral */ + void *mphi_base; + ++ /** mphi_base actually points to the SWIRQ block */ ++ bool use_swirq; ++ + /** IRQ number (<0 if not valid) */ + int irq_num; + diff --git a/target/linux/brcm2708/patches-4.19/950-0549-net-genet-enable-link-energy-detect-powerdown-for-ex.patch b/target/linux/brcm2708/patches-4.19/950-0549-net-genet-enable-link-energy-detect-powerdown-for-ex.patch deleted file mode 100644 index bd8a0278e0..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0549-net-genet-enable-link-energy-detect-powerdown-for-ex.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 03bd32474bf378c1537775970b35c7081779aec4 Mon Sep 17 00:00:00 2001 -From: Jonathan Bell -Date: Tue, 14 May 2019 17:17:59 +0100 -Subject: [PATCH 549/703] net: genet: enable link energy detect powerdown for - external PHYs - -There are several warts surrounding bcmgenet_mii_probe() as this -function is called from ndo_open, but it's calling registration-type -functions. The probe should be called at probe time and refactored -such that the PHY device data can be extracted to limit the scope -of this flag to Broadcom PHYs. - -For now, pass this flag in as it puts our attached PHY into a low-power -state when disconnected. - -Signed-off-by: Jonathan Bell ---- - drivers/net/ethernet/broadcom/genet/bcmmii.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/broadcom/genet/bcmmii.c -+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c -@@ -280,7 +280,10 @@ int bcmgenet_mii_probe(struct net_device - int ret; - - /* Communicate the integrated PHY revision */ -- phy_flags = priv->gphy_rev; -+ if (priv->internal_phy) -+ phy_flags = priv->gphy_rev; -+ else -+ phy_flags = PHY_BRCM_AUTO_PWRDWN_ENABLE; - - /* Initialize link state variables that bcmgenet_mii_setup() uses */ - priv->old_link = -1; diff --git a/target/linux/brcm2708/patches-4.19/950-0549-usb-xhci-Disable-the-XHCI-5-second-timeout.patch b/target/linux/brcm2708/patches-4.19/950-0549-usb-xhci-Disable-the-XHCI-5-second-timeout.patch new file mode 100644 index 0000000000..3f62d3adb5 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0549-usb-xhci-Disable-the-XHCI-5-second-timeout.patch @@ -0,0 +1,29 @@ +From 4f8e73f79d01049ab47e4984f8df63cd92a4da5c Mon Sep 17 00:00:00 2001 +From: Tim Gover +Date: Fri, 22 Mar 2019 09:47:14 +0000 +Subject: [PATCH 549/725] usb: xhci: Disable the XHCI 5 second timeout + +If the VL805 EEPROM has not been programmed then boot will hang for five +seconds. The timeout seems to be arbitrary and is an unecessary +delay on the first boot. Remove the timeout. + +This is common code and probably can't be upstreamed unless the timeout +can be configurable somehow or perhaps the XHCI driver can be skipped +on the first boot. +--- + drivers/usb/host/xhci.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -196,8 +196,9 @@ int xhci_reset(struct xhci_hcd *xhci) + if (xhci->quirks & XHCI_INTEL_HOST) + udelay(1000); + ++ // Hack: reduce handshake timeout from 10s 0.5s due to unprogrammed vl805 + ret = xhci_handshake(&xhci->op_regs->command, +- CMD_RESET, 0, 10 * 1000 * 1000); ++ CMD_RESET, 0, 500 * 1000); + if (ret) + return ret; + diff --git a/target/linux/brcm2708/patches-4.19/950-0550-phy-broadcom-split-out-the-BCM54213PE-from-the-BCM54.patch b/target/linux/brcm2708/patches-4.19/950-0550-phy-broadcom-split-out-the-BCM54213PE-from-the-BCM54.patch deleted file mode 100644 index ebb636efd5..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0550-phy-broadcom-split-out-the-BCM54213PE-from-the-BCM54.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 845295c21d9123f24a33bcb683f02fa7f3c7648e Mon Sep 17 00:00:00 2001 -From: Jonathan Bell -Date: Tue, 14 May 2019 17:00:41 +0100 -Subject: [PATCH 550/703] phy: broadcom: split out the BCM54213PE from the - BCM54210E IDs - -The last nibble is a revision ID, and the 54213pe is a later rev -than the 54210e. Running the 54210e setup code on a 54213pe results -in a broken RGMII interface. - -Signed-off-by: Jonathan Bell ---- - drivers/net/phy/broadcom.c | 17 ++++++++++++++--- - include/linux/brcmphy.h | 1 + - 2 files changed, 15 insertions(+), 3 deletions(-) - ---- a/drivers/net/phy/broadcom.c -+++ b/drivers/net/phy/broadcom.c -@@ -222,7 +222,8 @@ static void bcm54xx_adjust_rxrefclk(stru - /* Abort if we are using an untested phy. */ - if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 && - BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 && -- BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M) -+ BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M && -+ BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54213PE) - return; - - val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR3); -@@ -604,7 +605,7 @@ static struct phy_driver broadcom_driver - .config_intr = bcm_phy_config_intr, - }, { - .phy_id = PHY_ID_BCM54210E, -- .phy_id_mask = 0xfffffff0, -+ .phy_id_mask = 0xffffffff, - .name = "Broadcom BCM54210E", - .features = PHY_GBIT_FEATURES, - .flags = PHY_HAS_INTERRUPT, -@@ -612,6 +613,15 @@ static struct phy_driver broadcom_driver - .ack_interrupt = bcm_phy_ack_intr, - .config_intr = bcm_phy_config_intr, - }, { -+ .phy_id = PHY_ID_BCM54213PE, -+ .phy_id_mask = 0xffffffff, -+ .name = "Broadcom BCM54213PE", -+ .features = PHY_GBIT_FEATURES, -+ .flags = PHY_HAS_INTERRUPT, -+ .config_init = bcm54xx_config_init, -+ .ack_interrupt = bcm_phy_ack_intr, -+ .config_intr = bcm_phy_config_intr, -+}, { - .phy_id = PHY_ID_BCM5461, - .phy_id_mask = 0xfffffff0, - .name = "Broadcom BCM5461", -@@ -748,7 +758,8 @@ module_phy_driver(broadcom_drivers); - static struct mdio_device_id __maybe_unused broadcom_tbl[] = { - { PHY_ID_BCM5411, 0xfffffff0 }, - { PHY_ID_BCM5421, 0xfffffff0 }, -- { PHY_ID_BCM54210E, 0xfffffff0 }, -+ { PHY_ID_BCM54210E, 0xffffffff }, -+ { PHY_ID_BCM54213PE, 0xffffffff }, - { PHY_ID_BCM5461, 0xfffffff0 }, - { PHY_ID_BCM54612E, 0xfffffff0 }, - { PHY_ID_BCM54616S, 0xfffffff0 }, ---- a/include/linux/brcmphy.h -+++ b/include/linux/brcmphy.h -@@ -20,6 +20,7 @@ - #define PHY_ID_BCM5411 0x00206070 - #define PHY_ID_BCM5421 0x002060e0 - #define PHY_ID_BCM54210E 0x600d84a0 -+#define PHY_ID_BCM54213PE 0x600d84a2 - #define PHY_ID_BCM5464 0x002060b0 - #define PHY_ID_BCM5461 0x002060c0 - #define PHY_ID_BCM54612E 0x03625e60 diff --git a/target/linux/brcm2708/patches-4.19/950-0550-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch b/target/linux/brcm2708/patches-4.19/950-0550-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch new file mode 100644 index 0000000000..a74818cc3a --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0550-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch @@ -0,0 +1,23 @@ +From 66cba59420caaf4fd1123e7aa4ef87de34cca440 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 23 May 2019 15:08:30 +0100 +Subject: [PATCH 550/725] usb: xhci: Show that the VIA VL805 supports LPM + +Signed-off-by: Phil Elwell +--- + drivers/usb/host/xhci-pci.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -222,6 +222,10 @@ static void xhci_pci_quirks(struct devic + pdev->device == 0x3432) + xhci->quirks |= XHCI_BROKEN_STREAMS; + ++ if (pdev->vendor == PCI_VENDOR_ID_VIA && ++ pdev->device == 0x3483) ++ xhci->quirks |= XHCI_LPM_SUPPORT; ++ + if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && + pdev->device == 0x1042) + xhci->quirks |= XHCI_BROKEN_STREAMS; diff --git a/target/linux/brcm2708/patches-4.19/950-0551-phy-bcm54213pe-configure-the-LED-outputs-to-be-more-.patch b/target/linux/brcm2708/patches-4.19/950-0551-phy-bcm54213pe-configure-the-LED-outputs-to-be-more-.patch deleted file mode 100644 index e60d125cda..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0551-phy-bcm54213pe-configure-the-LED-outputs-to-be-more-.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 5353102f2d7e2f61cca4014aacfa3ac9a71aaeea Mon Sep 17 00:00:00 2001 -From: Jonathan Bell -Date: Fri, 17 May 2019 13:31:21 +0100 -Subject: [PATCH 551/703] phy: bcm54213pe: configure the LED outputs to be more - user-friendly - -The default state was both LEDs indicating link speed. - -Change the default configuration to -- Amber: 1000/100 link speed indication -- Green: link present + activity indication - -Signed-off-by: Jonathan Bell ---- - drivers/net/phy/broadcom.c | 17 +++++++++++++++++ - include/linux/brcmphy.h | 4 ++++ - 2 files changed, 21 insertions(+) - ---- a/drivers/net/phy/broadcom.c -+++ b/drivers/net/phy/broadcom.c -@@ -52,6 +52,21 @@ static int bcm54210e_config_init(struct - return 0; - } - -+static void bcm54213pe_config_init(struct phy_device *phydev) -+{ -+ u16 val; -+ -+ /* Enable ACT+LINK indication on ACTIVITY trigger */ -+ val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_LEDCTL); -+ val |= BCM54XX_SHD_LEDCTL_ACTLINK_EN; -+ bcm_phy_write_shadow(phydev, BCM54XX_SHD_LEDCTL, val); -+ -+ /* Set ACTIVITY on LED "1" output, LINKSPD[1] on LED "3" output */ -+ val = BCM5482_SHD_LEDS1_LED1(BCM_LED_SRC_ACTIVITYLED) | -+ BCM5482_SHD_LEDS1_LED3(BCM_LED_SRC_LINKSPD1); -+ bcm_phy_write_shadow(phydev, BCM5482_SHD_LEDS1, val); -+} -+ - static int bcm54612e_config_init(struct phy_device *phydev) - { - int reg; -@@ -310,6 +325,8 @@ static int bcm54xx_config_init(struct ph - err = bcm54210e_config_init(phydev); - if (err) - return err; -+ } else if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54213PE) { -+ bcm54213pe_config_init(phydev); - } else if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54612E) { - err = bcm54612e_config_init(phydev); - if (err) ---- a/include/linux/brcmphy.h -+++ b/include/linux/brcmphy.h -@@ -168,6 +168,10 @@ - #define BCM54XX_SHD_SCR3_DLLAPD_DIS 0x0002 - #define BCM54XX_SHD_SCR3_TRDDAPD 0x0004 - -+/* 01001: Additional LED trigger options */ -+#define BCM54XX_SHD_LEDCTL 0x09 -+#define BCM54XX_SHD_LEDCTL_ACTLINK_EN 0x0010 -+ - /* 01010: Auto Power-Down */ - #define BCM54XX_SHD_APD 0x0a - #define BCM_APD_CLR_MASK 0xFE9F /* clear bits 5, 6 & 8 */ diff --git a/target/linux/brcm2708/patches-4.19/950-0551-usb-xhci-hack-xhci_urb_enqueue-to-support-hid.mousep.patch b/target/linux/brcm2708/patches-4.19/950-0551-usb-xhci-hack-xhci_urb_enqueue-to-support-hid.mousep.patch new file mode 100644 index 0000000000..a8056287a7 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0551-usb-xhci-hack-xhci_urb_enqueue-to-support-hid.mousep.patch @@ -0,0 +1,122 @@ +From ebd33389465183268879eb8c3eefe9e7e5363cf3 Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Thu, 30 May 2019 10:38:40 +0100 +Subject: [PATCH 551/725] usb: xhci: hack xhci_urb_enqueue to support + hid.mousepoll behaviour + +xHCI creates endpoint contexts directly from the device's endpoint +data, so submitting URBs with urb->interval different from the hardware +interval has no effect. + +Add an explicit reconfiguration of the endpoint context when requested, +which will happen only when the interval is different from the cached +value. In practice, the reconfiguration only happens on the first URB +submitted for the endpoint. + +Signed-off-by: Jonathan Bell +--- + drivers/usb/host/xhci.c | 86 +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 86 insertions(+) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -1416,6 +1416,87 @@ command_cleanup: + } + + /* ++ * RPI: Fixup endpoint intervals when requested ++ * - Check interval versus the (cached) endpoint context ++ * - set the endpoint interval to the new value ++ * - force an endpoint configure command ++ */ ++static void xhci_fixup_interval(struct xhci_hcd *xhci, struct urb *urb, ++ unsigned int slot_id, unsigned int ep_index) ++{ ++ struct xhci_ep_ctx *ep_ctx_out, *ep_ctx_in; ++ struct xhci_command *command; ++ struct xhci_input_control_ctx *ctrl_ctx; ++ struct xhci_virt_device *vdev; ++ int xhci_interval, ep_interval; ++ int ret; ++ unsigned long flags; ++ u32 ep_info_tmp; ++ ++ spin_lock_irqsave(&xhci->lock, flags); ++ ++ vdev = xhci->devs[slot_id]; ++ /* Get context-derived endpoint interval */ ++ ep_ctx_out = xhci_get_ep_ctx(xhci, vdev->out_ctx, ep_index); ++ ep_ctx_in = xhci_get_ep_ctx(xhci, vdev->in_ctx, ep_index); ++ xhci_interval = EP_INTERVAL_TO_UFRAMES(le32_to_cpu(ep_ctx_out->ep_info)); ++ ep_interval = urb->interval * 8; ++ ++ if (ep_interval == xhci_interval) { ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ return; ++ } ++ ++ xhci_dbg(xhci, "Fixup interval ep_interval=%d xhci_interval=%d\n", ++ ep_interval, xhci_interval); ++ command = xhci_alloc_command_with_ctx(xhci, true, GFP_ATOMIC); ++ if (!command) { ++ /* Failure here is benign, poll at the original rate */ ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ return; ++ } ++ ++ /* xHCI uses exponents for intervals... */ ++ xhci_interval = fls(ep_interval) - 1; ++ xhci_interval = clamp_val(xhci_interval, 3, 10); ++ ep_info_tmp = le32_to_cpu(ep_ctx_out->ep_info); ++ ep_info_tmp &= ~EP_INTERVAL(255); ++ ep_info_tmp |= EP_INTERVAL(xhci_interval); ++ ++ /* Keep the endpoint context up-to-date while issuing the command. */ ++ xhci_endpoint_copy(xhci, vdev->in_ctx, ++ vdev->out_ctx, ep_index); ++ ep_ctx_in->ep_info = cpu_to_le32(ep_info_tmp); ++ ++ /* ++ * We need to drop the lock, so take an explicit copy ++ * of the ep context. ++ */ ++ xhci_endpoint_copy(xhci, command->in_ctx, vdev->in_ctx, ep_index); ++ ++ ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); ++ if (!ctrl_ctx) { ++ xhci_warn(xhci, ++ "%s: Could not get input context, bad type.\n", ++ __func__); ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ xhci_free_command(xhci, command); ++ return; ++ } ++ ctrl_ctx->add_flags = xhci_get_endpoint_flag_from_index(ep_index); ++ ctrl_ctx->drop_flags = 0; ++ ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ ++ ret = xhci_configure_endpoint(xhci, urb->dev, command, ++ false, false); ++ if (ret) ++ xhci_warn(xhci, "%s: Configure endpoint failed: %d\n", ++ __func__, ret); ++ xhci_free_command(xhci, command); ++} ++ ++/* + * non-error returns are a promise to giveback() the urb later + * we drop ownership so next owner (or urb unlink) can get it + */ +@@ -1483,6 +1564,11 @@ static int xhci_urb_enqueue(struct usb_h + } + } + ++ if (usb_endpoint_xfer_int(&urb->ep->desc) && ++ (urb->dev->speed == USB_SPEED_FULL || ++ urb->dev->speed == USB_SPEED_LOW)) ++ xhci_fixup_interval(xhci, urb, slot_id, ep_index); ++ + spin_lock_irqsave(&xhci->lock, flags); + + if (xhci->xhc_state & XHCI_STATE_DYING) { diff --git a/target/linux/brcm2708/patches-4.19/950-0552-dwc_otg-Choose-appropriate-IRQ-handover-strategy.patch b/target/linux/brcm2708/patches-4.19/950-0552-dwc_otg-Choose-appropriate-IRQ-handover-strategy.patch deleted file mode 100644 index 54e0679a53..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0552-dwc_otg-Choose-appropriate-IRQ-handover-strategy.patch +++ /dev/null @@ -1,181 +0,0 @@ -From 9a7fd87f8f2a28cee05a847266a5a168a3d8c0dd Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 21 May 2019 13:36:52 +0100 -Subject: [PATCH 552/703] dwc_otg: Choose appropriate IRQ handover strategy - -2711 has no MPHI peripheral, but the ARM Control block can fake -interrupts. Use the size of the DTB "mphi" reg block to determine -which is required. - -Signed-off-by: Phil Elwell ---- - drivers/usb/host/dwc_otg/dwc_otg_driver.c | 9 +++-- - drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 21 ++++++---- - drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h | 2 + - drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 12 ++++-- - drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 41 +++++++++++++------- - drivers/usb/host/dwc_otg/dwc_otg_os_dep.h | 3 ++ - 6 files changed, 60 insertions(+), 28 deletions(-) - ---- a/drivers/usb/host/dwc_otg/dwc_otg_driver.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -@@ -806,14 +806,15 @@ static int dwc_otg_driver_probe( - if (!request_mem_region(_dev->resource[1].start, - _dev->resource[1].end - _dev->resource[1].start + 1, - "dwc_otg")) { -- dev_dbg(&_dev->dev, "error reserving mapped memory\n"); -- retval = -EFAULT; -- goto fail; -- } -+ dev_dbg(&_dev->dev, "error reserving mapped memory\n"); -+ retval = -EFAULT; -+ goto fail; -+ } - - dwc_otg_device->os_dep.mphi_base = ioremap_nocache(_dev->resource[1].start, - _dev->resource[1].end - - _dev->resource[1].start + 1); -+ dwc_otg_device->os_dep.use_swirq = (_dev->resource[1].end - _dev->resource[1].start) == 0x200; - } - - #else ---- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c -@@ -1347,8 +1347,12 @@ void notrace dwc_otg_fiq_fsm(struct fiq_ - /* We got an interrupt, didn't handle it. */ - if (kick_irq) { - state->mphi_int_count++; -- FIQ_WRITE(state->mphi_regs.outdda, state->dummy_send_dma); -- FIQ_WRITE(state->mphi_regs.outddb, (1<<29)); -+ if (state->mphi_regs.swirq_set) { -+ FIQ_WRITE(state->mphi_regs.swirq_set, 1); -+ } else { -+ FIQ_WRITE(state->mphi_regs.outdda, state->dummy_send_dma); -+ FIQ_WRITE(state->mphi_regs.outddb, (1<<29)); -+ } - - } - state->fiq_done++; -@@ -1406,11 +1410,14 @@ void notrace dwc_otg_fiq_nop(struct fiq_ - state->mphi_int_count++; - gintmsk.d32 &= state->gintmsk_saved.d32; - FIQ_WRITE(state->dwc_regs_base + GINTMSK, gintmsk.d32); -- /* Force a clear before another dummy send */ -- FIQ_WRITE(state->mphi_regs.intstat, (1<<29)); -- FIQ_WRITE(state->mphi_regs.outdda, state->dummy_send_dma); -- FIQ_WRITE(state->mphi_regs.outddb, (1<<29)); -- -+ if (state->mphi_regs.swirq_set) { -+ FIQ_WRITE(state->mphi_regs.swirq_set, 1); -+ } else { -+ /* Force a clear before another dummy send */ -+ FIQ_WRITE(state->mphi_regs.intstat, (1<<29)); -+ FIQ_WRITE(state->mphi_regs.outdda, state->dummy_send_dma); -+ FIQ_WRITE(state->mphi_regs.outddb, (1<<29)); -+ } - } - state->fiq_done++; - mb(); ---- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h -+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h -@@ -118,6 +118,8 @@ typedef struct { - volatile void* outdda; - volatile void* outddb; - volatile void* intstat; -+ volatile void* swirq_set; -+ volatile void* swirq_clr; - } mphi_regs_t; - - enum fiq_debug_level { ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -@@ -220,16 +220,20 @@ exit_handler_routine: - - /* The FIQ could have sneaked another interrupt in. If so, don't clear MPHI */ - if ((gintmsk_new.d32 == ~0) && (haintmsk_new.d32 == 0x0000FFFF)) { -+ if (dwc_otg_hcd->fiq_state->mphi_regs.swirq_clr) { -+ DWC_WRITE_REG32(dwc_otg_hcd->fiq_state->mphi_regs.swirq_clr, 1); -+ } else { - DWC_WRITE_REG32(dwc_otg_hcd->fiq_state->mphi_regs.intstat, (1<<16)); -- if (dwc_otg_hcd->fiq_state->mphi_int_count >= 50) { -- fiq_print(FIQDBG_INT, dwc_otg_hcd->fiq_state, "MPHI CLR"); -+ } -+ if (dwc_otg_hcd->fiq_state->mphi_int_count >= 50) { -+ fiq_print(FIQDBG_INT, dwc_otg_hcd->fiq_state, "MPHI CLR"); - DWC_WRITE_REG32(dwc_otg_hcd->fiq_state->mphi_regs.ctrl, ((1<<31) + (1<<16))); - while (!(DWC_READ_REG32(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & (1 << 17))) - ; - DWC_WRITE_REG32(dwc_otg_hcd->fiq_state->mphi_regs.ctrl, (1<<31)); - dwc_otg_hcd->fiq_state->mphi_int_count = 0; -- } -- int_done++; -+ } -+ int_done++; - } - haintmsk.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->haintmsk); - /* Re-enable interrupts that the FIQ masked (first time round) */ ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -@@ -474,22 +474,37 @@ static void hcd_init_fiq(void *cookie) - set_fiq_regs(®s); - #endif - -- //Set the mphi periph to the required registers -- dwc_otg_hcd->fiq_state->mphi_regs.base = otg_dev->os_dep.mphi_base; -- dwc_otg_hcd->fiq_state->mphi_regs.ctrl = otg_dev->os_dep.mphi_base + 0x4c; -- dwc_otg_hcd->fiq_state->mphi_regs.outdda = otg_dev->os_dep.mphi_base + 0x28; -- dwc_otg_hcd->fiq_state->mphi_regs.outddb = otg_dev->os_dep.mphi_base + 0x2c; -- dwc_otg_hcd->fiq_state->mphi_regs.intstat = otg_dev->os_dep.mphi_base + 0x50; - dwc_otg_hcd->fiq_state->dwc_regs_base = otg_dev->os_dep.base; -- DWC_WARN("MPHI regs_base at %px", dwc_otg_hcd->fiq_state->mphi_regs.base); -- //Enable mphi peripheral -- writel((1<<31),dwc_otg_hcd->fiq_state->mphi_regs.ctrl); -+ //Set the mphi periph to the required registers -+ dwc_otg_hcd->fiq_state->mphi_regs.base = otg_dev->os_dep.mphi_base; -+ if (otg_dev->os_dep.use_swirq) { -+ dwc_otg_hcd->fiq_state->mphi_regs.swirq_set = -+ otg_dev->os_dep.mphi_base + 0x1f0; -+ dwc_otg_hcd->fiq_state->mphi_regs.swirq_clr = -+ otg_dev->os_dep.mphi_base + 0x1f4; -+ DWC_WARN("Fake MPHI regs_base at 0x%08x", -+ (int)dwc_otg_hcd->fiq_state->mphi_regs.base); -+ } else { -+ dwc_otg_hcd->fiq_state->mphi_regs.ctrl = -+ otg_dev->os_dep.mphi_base + 0x4c; -+ dwc_otg_hcd->fiq_state->mphi_regs.outdda -+ = otg_dev->os_dep.mphi_base + 0x28; -+ dwc_otg_hcd->fiq_state->mphi_regs.outddb -+ = otg_dev->os_dep.mphi_base + 0x2c; -+ dwc_otg_hcd->fiq_state->mphi_regs.intstat -+ = otg_dev->os_dep.mphi_base + 0x50; -+ DWC_WARN("MPHI regs_base at %px", -+ dwc_otg_hcd->fiq_state->mphi_regs.base); -+ -+ //Enable mphi peripheral -+ writel((1<<31),dwc_otg_hcd->fiq_state->mphi_regs.ctrl); - #ifdef DEBUG -- if (readl(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & 0x80000000) -- DWC_WARN("MPHI periph has been enabled"); -- else -- DWC_WARN("MPHI periph has NOT been enabled"); -+ if (readl(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & 0x80000000) -+ DWC_WARN("MPHI periph has been enabled"); -+ else -+ DWC_WARN("MPHI periph has NOT been enabled"); - #endif -+ } - // Enable FIQ interrupt from USB peripheral - #ifdef CONFIG_ARM64 - irq = otg_dev->os_dep.fiq_num; ---- a/drivers/usb/host/dwc_otg/dwc_otg_os_dep.h -+++ b/drivers/usb/host/dwc_otg/dwc_otg_os_dep.h -@@ -102,6 +102,9 @@ typedef struct os_dependent { - /** Base address for MPHI peripheral */ - void *mphi_base; - -+ /** mphi_base actually points to the SWIRQ block */ -+ bool use_swirq; -+ - /** IRQ number (<0 if not valid) */ - int irq_num; - diff --git a/target/linux/brcm2708/patches-4.19/950-0552-pinctrl-bcm2835-Add-support-for-BCM2838.patch b/target/linux/brcm2708/patches-4.19/950-0552-pinctrl-bcm2835-Add-support-for-BCM2838.patch new file mode 100644 index 0000000000..47d72bf0c7 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0552-pinctrl-bcm2835-Add-support-for-BCM2838.patch @@ -0,0 +1,90 @@ +From 40c0d670970e7896a0be03ab0f884bdcd718660d Mon Sep 17 00:00:00 2001 +From: Tim Gover +Date: Wed, 9 Jan 2019 14:43:36 +0000 +Subject: [PATCH 552/725] pinctrl-bcm2835: Add support for BCM2838 + +GPIO configuration on BCM2838 is largely the same as BCM2835 except for +the pull up/down configuration. The old mechanism has been replaced +by new registers which don't require the fixed delay. + +Detect BCN2838 at run-time and use the new mechanism. Backwards +compatibility for the device-tree configuration has been retained. +--- + drivers/pinctrl/bcm/pinctrl-bcm2835.c | 58 ++++++++++++++++++++------- + 1 file changed, 44 insertions(+), 14 deletions(-) + +--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c ++++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +@@ -67,6 +67,12 @@ + #define GPPUD 0x94 /* Pin Pull-up/down Enable */ + #define GPPUDCLK0 0x98 /* Pin Pull-up/down Enable Clock */ + ++/* 2711 has a different mechanism for pin pull-up/down/enable */ ++#define GPPUPPDN0 0xe4 /* Pin pull-up/down for pins 15:0 */ ++#define GPPUPPDN1 0xe8 /* Pin pull-up/down for pins 31:16 */ ++#define GPPUPPDN2 0xec /* Pin pull-up/down for pins 47:32 */ ++#define GPPUPPDN3 0xf0 /* Pin pull-up/down for pins 57:48 */ ++ + #define FSEL_REG(p) (GPFSEL0 + (((p) / 10) * 4)) + #define FSEL_SHIFT(p) (((p) % 10) * 3) + #define GPIO_REG_OFFSET(p) ((p) / 32) +@@ -917,21 +923,45 @@ static void bcm2835_pull_config_set(stru + unsigned int pin, unsigned int arg) + { + u32 off, bit; ++ /* BCM2835, BCM2836 & BCM2837 return 'gpio' for this unused register */ ++ int is_2835 = bcm2835_gpio_rd(pc, GPPUPPDN3) == 0x6770696f; + +- off = GPIO_REG_OFFSET(pin); +- bit = GPIO_REG_SHIFT(pin); +- +- bcm2835_gpio_wr(pc, GPPUD, arg & 3); +- /* +- * BCM2835 datasheet say to wait 150 cycles, but not of what. +- * But the VideoCore firmware delay for this operation +- * based nearly on the same amount of VPU cycles and this clock +- * runs at 250 MHz. +- */ +- udelay(1); +- bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit)); +- udelay(1); +- bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0); ++ if (is_2835) { ++ off = GPIO_REG_OFFSET(pin); ++ bit = GPIO_REG_SHIFT(pin); ++ /* ++ * BCM2835 datasheet say to wait 150 cycles, but not of what. ++ * But the VideoCore firmware delay for this operation ++ * based nearly on the same amount of VPU cycles and this clock ++ * runs at 250 MHz. ++ */ ++ bcm2835_gpio_wr(pc, GPPUD, arg & 3); ++ udelay(1); ++ bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit)); ++ udelay(1); ++ bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0); ++ } else { ++ u32 reg; ++ int lsb; ++ ++ off = (pin >> 4); ++ if (off > 3) ++ return; ++ lsb = (pin & 0xf) << 1; ++ ++ /* The up/down semantics are reversed compared to BCM2835. ++ * Instead of updating all the device tree files, translate the ++ * values here. ++ */ ++ if (arg == 2) ++ arg = 1; ++ else if (arg == 1) ++ arg = 2; ++ reg = bcm2835_gpio_rd(pc, GPPUPPDN0 + (off *4)); ++ reg &= ~(0x3 << lsb); ++ reg |= (arg & 3) << lsb; ++ bcm2835_gpio_wr(pc, GPPUPPDN0 + (off * 4), reg); ++ } + } + + static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev, diff --git a/target/linux/brcm2708/patches-4.19/950-0553-spi-bcm2835-enable-shared-interrupt-support.patch b/target/linux/brcm2708/patches-4.19/950-0553-spi-bcm2835-enable-shared-interrupt-support.patch new file mode 100644 index 0000000000..9fd6608542 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0553-spi-bcm2835-enable-shared-interrupt-support.patch @@ -0,0 +1,35 @@ +From bca62369ca063a66ab3bfb3d129d76da88a3b99b Mon Sep 17 00:00:00 2001 +From: Martin Sperl +Date: Mon, 13 May 2019 11:05:27 +0000 +Subject: [PATCH 553/725] spi: bcm2835: enable shared interrupt support + +Add shared interrupt support for this driver. + +Signed-off-by: Martin Sperl +--- + drivers/spi/spi-bcm2835.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/spi/spi-bcm2835.c ++++ b/drivers/spi/spi-bcm2835.c +@@ -150,6 +150,10 @@ static irqreturn_t bcm2835_spi_interrupt + struct spi_master *master = dev_id; + struct bcm2835_spi *bs = spi_master_get_devdata(master); + ++ /* check if we got interrupt enabled */ ++ if (!(bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_INTR)) ++ return IRQ_NONE; ++ + /* Read as many bytes as possible from FIFO */ + bcm2835_rd_fifo(bs); + /* Write as many bytes as possible to FIFO */ +@@ -755,7 +759,8 @@ static int bcm2835_spi_probe(struct plat + bcm2835_wr(bs, BCM2835_SPI_CS, + BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); + +- err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, 0, ++ err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, ++ IRQF_SHARED, + dev_name(&pdev->dev), master); + if (err) { + dev_err(&pdev->dev, "could not request IRQ: %d\n", err); diff --git a/target/linux/brcm2708/patches-4.19/950-0553-usb-xhci-Disable-the-XHCI-5-second-timeout.patch b/target/linux/brcm2708/patches-4.19/950-0553-usb-xhci-Disable-the-XHCI-5-second-timeout.patch deleted file mode 100644 index c5d4e6bf98..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0553-usb-xhci-Disable-the-XHCI-5-second-timeout.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 2957990a8291f860ca5bbbc58d2b28aaf6acd28e Mon Sep 17 00:00:00 2001 -From: Tim Gover -Date: Fri, 22 Mar 2019 09:47:14 +0000 -Subject: [PATCH 553/703] usb: xhci: Disable the XHCI 5 second timeout - -If the VL805 EEPROM has not been programmed then boot will hang for five -seconds. The timeout seems to be arbitrary and is an unecessary -delay on the first boot. Remove the timeout. - -This is common code and probably can't be upstreamed unless the timeout -can be configurable somehow or perhaps the XHCI driver can be skipped -on the first boot. ---- - drivers/usb/host/xhci.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/usb/host/xhci.c -+++ b/drivers/usb/host/xhci.c -@@ -196,8 +196,9 @@ int xhci_reset(struct xhci_hcd *xhci) - if (xhci->quirks & XHCI_INTEL_HOST) - udelay(1000); - -+ // Hack: reduce handshake timeout from 10s 0.5s due to unprogrammed vl805 - ret = xhci_handshake(&xhci->op_regs->command, -- CMD_RESET, 0, 10 * 1000 * 1000); -+ CMD_RESET, 0, 500 * 1000); - if (ret) - return ret; - diff --git a/target/linux/brcm2708/patches-4.19/950-0554-drivers-char-add-chardev-for-mmap-ing-Argon-control-.patch b/target/linux/brcm2708/patches-4.19/950-0554-drivers-char-add-chardev-for-mmap-ing-Argon-control-.patch new file mode 100644 index 0000000000..6baac9d76c --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0554-drivers-char-add-chardev-for-mmap-ing-Argon-control-.patch @@ -0,0 +1,320 @@ +From b64f3dadd338591992edcadfa064920de997d058 Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Thu, 9 May 2019 14:30:37 +0100 +Subject: [PATCH 554/725] drivers: char: add chardev for mmap'ing Argon control + registers + +Based on the gpiomem driver, allow mapping of the decoder register +spaces such that userspace can access control/status registers. +This driver is intended for use with a custom ffmpeg backend accelerator +prior to a v4l2 driver being written. + +Signed-off-by: Jonathan Bell +--- + drivers/char/broadcom/Kconfig | 8 + + drivers/char/broadcom/Makefile | 1 + + drivers/char/broadcom/argon-mem.c | 277 ++++++++++++++++++++++++++++++ + 3 files changed, 286 insertions(+) + create mode 100644 drivers/char/broadcom/argon-mem.c + +--- a/drivers/char/broadcom/Kconfig ++++ b/drivers/char/broadcom/Kconfig +@@ -49,3 +49,11 @@ config BCM2835_SMI_DEV + This driver provides a character device interface (ioctl + read/write) to + Broadcom's Secondary Memory interface. The low-level functionality is provided + by the SMI driver itself. ++ ++config ARGON_MEM ++ tristate "Character device driver for the Argon decoder hardware" ++ default n ++ help ++ This driver provides a character device interface for memory-map operations ++ so userspace tools can access the control and status registers of the Argon ++ video decoder hardware. +--- a/drivers/char/broadcom/Makefile ++++ b/drivers/char/broadcom/Makefile +@@ -4,3 +4,4 @@ obj-$(CONFIG_BCM_VC_SM) += vc_sm + + obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o + obj-$(CONFIG_BCM2835_SMI_DEV) += bcm2835_smi_dev.o ++obj-$(CONFIG_ARGON_MEM) += argon-mem.o +--- /dev/null ++++ b/drivers/char/broadcom/argon-mem.c +@@ -0,0 +1,277 @@ ++/** ++ * argon-mem.c - character device access to the Argon decoder registers ++ * ++ * Based on bcm2835-gpiomem.c. Provides IO memory access to the decoder ++ * register blocks such that ffmpeg plugins can access the hardware. ++ * ++ * Jonathan Bell ++ * Copyright (c) 2019, Raspberry Pi (Trading) Ltd. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the above-listed copyright holders may not be used ++ * to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * ALTERNATIVELY, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2, as published by the Free ++ * Software Foundation. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ++ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ++ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR ++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DRIVER_NAME "argon-mem" ++#define DEVICE_MINOR 0 ++ ++struct argon_mem_priv { ++ dev_t devid; ++ struct class *class; ++ struct cdev argon_mem_cdev; ++ unsigned long regs_phys; ++ unsigned long mem_window_len; ++ struct device *dev; ++ const char *name; ++}; ++ ++static int argon_mem_open(struct inode *inode, struct file *file) ++{ ++ int dev = iminor(inode); ++ int ret = 0; ++ struct argon_mem_priv *priv; ++ if (dev != DEVICE_MINOR) ++ ret = -ENXIO; ++ ++ priv = container_of(inode->i_cdev, struct argon_mem_priv, ++ argon_mem_cdev); ++ if (!priv) ++ return -EINVAL; ++ file->private_data = priv; ++ return ret; ++} ++ ++static int argon_mem_release(struct inode *inode, struct file *file) ++{ ++ int dev = iminor(inode); ++ int ret = 0; ++ ++ if (dev != DEVICE_MINOR) ++ ret = -ENXIO; ++ ++ return ret; ++} ++ ++static const struct vm_operations_struct argon_mem_vm_ops = { ++#ifdef CONFIG_HAVE_IOREMAP_PROT ++ .access = generic_access_phys ++#endif ++}; ++ ++static int argon_mem_mmap(struct file *file, struct vm_area_struct *vma) ++{ ++ struct argon_mem_priv *priv; ++ unsigned long pages; ++ ++ priv = file->private_data; ++ pages = priv->regs_phys >> PAGE_SHIFT; ++ /* ++ * The address decode is far larger than the actual number of registers. ++ * Just map the whole lot in. ++ */ ++ vma->vm_page_prot = phys_mem_access_prot(file, pages, ++ priv->mem_window_len, ++ vma->vm_page_prot); ++ vma->vm_ops = &argon_mem_vm_ops; ++ if (remap_pfn_range(vma, vma->vm_start, ++ pages, ++ priv->mem_window_len, ++ vma->vm_page_prot)) { ++ return -EAGAIN; ++ } ++ return 0; ++} ++ ++static const struct file_operations ++argon_mem_fops = { ++ .owner = THIS_MODULE, ++ .open = argon_mem_open, ++ .release = argon_mem_release, ++ .mmap = argon_mem_mmap, ++}; ++ ++static const struct of_device_id argon_mem_of_match[]; ++static int argon_mem_probe(struct platform_device *pdev) ++{ ++ int err; ++ void *ptr_err; ++ const struct of_device_id *id; ++ struct device *dev = &pdev->dev; ++ struct device *argon_mem_dev; ++ struct resource *ioresource; ++ struct argon_mem_priv *priv; ++ ++ ++ /* Allocate buffers and instance data */ ++ ++ priv = kzalloc(sizeof(struct argon_mem_priv), GFP_KERNEL); ++ ++ if (!priv) { ++ err = -ENOMEM; ++ goto failed_inst_alloc; ++ } ++ platform_set_drvdata(pdev, priv); ++ ++ priv->dev = dev; ++ id = of_match_device(argon_mem_of_match, dev); ++ if (!id) ++ return -EINVAL; ++ priv->name = id->data; ++ ++ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (ioresource) { ++ priv->regs_phys = ioresource->start; ++ priv->mem_window_len = ioresource->end - ioresource->start; ++ } else { ++ dev_err(priv->dev, "failed to get IO resource"); ++ err = -ENOENT; ++ goto failed_get_resource; ++ } ++ ++ /* Create character device entries */ ++ ++ err = alloc_chrdev_region(&priv->devid, ++ DEVICE_MINOR, 1, priv->name); ++ if (err != 0) { ++ dev_err(priv->dev, "unable to allocate device number"); ++ goto failed_alloc_chrdev; ++ } ++ cdev_init(&priv->argon_mem_cdev, &argon_mem_fops); ++ priv->argon_mem_cdev.owner = THIS_MODULE; ++ err = cdev_add(&priv->argon_mem_cdev, priv->devid, 1); ++ if (err != 0) { ++ dev_err(priv->dev, "unable to register device"); ++ goto failed_cdev_add; ++ } ++ ++ /* Create sysfs entries */ ++ ++ priv->class = class_create(THIS_MODULE, priv->name); ++ ptr_err = priv->class; ++ if (IS_ERR(ptr_err)) ++ goto failed_class_create; ++ ++ argon_mem_dev = device_create(priv->class, NULL, ++ priv->devid, NULL, ++ priv->name); ++ ptr_err = argon_mem_dev; ++ if (IS_ERR(ptr_err)) ++ goto failed_device_create; ++ ++ dev_info(priv->dev, "%s initialised: Registers at 0x%08lx length 0x%08lx", ++ priv->name, priv->regs_phys, priv->mem_window_len); ++ ++ return 0; ++ ++failed_device_create: ++ class_destroy(priv->class); ++failed_class_create: ++ cdev_del(&priv->argon_mem_cdev); ++ err = PTR_ERR(ptr_err); ++failed_cdev_add: ++ unregister_chrdev_region(priv->devid, 1); ++failed_alloc_chrdev: ++failed_get_resource: ++ kfree(priv); ++failed_inst_alloc: ++ dev_err(priv->dev, "could not load argon_mem"); ++ return err; ++} ++ ++static int argon_mem_remove(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct argon_mem_priv *priv = platform_get_drvdata(pdev); ++ ++ device_destroy(priv->class, priv->devid); ++ class_destroy(priv->class); ++ cdev_del(&priv->argon_mem_cdev); ++ unregister_chrdev_region(priv->devid, 1); ++ kfree(priv); ++ ++ dev_info(dev, "%s driver removed - OK", priv->name); ++ return 0; ++} ++ ++static const char argon_hevc_name[] = "argon-hevcmem"; ++static const char argon_h264_name[] = "argon-h264mem"; ++static const char argon_vp9_name[] = "argon-vp9mem"; ++static const char argon_intc_name[] = "argon-intcmem"; ++ ++static const struct of_device_id argon_mem_of_match[] = { ++ { ++ .compatible = "raspberrypi,argon-hevc-decoder", ++ .data = &argon_hevc_name, ++ }, ++ { ++ .compatible = "raspberrypi,argon-h264-decoder", ++ .data = &argon_h264_name, ++ }, ++ { ++ .compatible = "raspberrypi,argon-vp9-decoder", ++ .data = &argon_vp9_name, ++ }, ++ /* The "intc" is included as this block of hardware contains the ++ * "frame done" status flags. ++ */ ++ { ++ .compatible = "raspberrypi,argon-local-intc", ++ .data = &argon_intc_name, ++ }, ++ { /* sentinel */ }, ++}; ++ ++MODULE_DEVICE_TABLE(of, argon_mem_of_match); ++ ++static struct platform_driver argon_mem_driver = { ++ .probe = argon_mem_probe, ++ .remove = argon_mem_remove, ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = argon_mem_of_match, ++ }, ++}; ++ ++module_platform_driver(argon_mem_driver); ++ ++MODULE_ALIAS("platform:argon-mem"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("Driver for accessing Argon decoder registers from userspace"); ++MODULE_AUTHOR("Jonathan Bell "); diff --git a/target/linux/brcm2708/patches-4.19/950-0554-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch b/target/linux/brcm2708/patches-4.19/950-0554-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch deleted file mode 100644 index d4065fb322..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0554-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 42738c082b40c372dcaebfae4dcbd3b3251cb37f Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 23 May 2019 15:08:30 +0100 -Subject: [PATCH 554/703] usb: xhci: Show that the VIA VL805 supports LPM - -Signed-off-by: Phil Elwell ---- - drivers/usb/host/xhci-pci.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/usb/host/xhci-pci.c -+++ b/drivers/usb/host/xhci-pci.c -@@ -222,6 +222,10 @@ static void xhci_pci_quirks(struct devic - pdev->device == 0x3432) - xhci->quirks |= XHCI_BROKEN_STREAMS; - -+ if (pdev->vendor == PCI_VENDOR_ID_VIA && -+ pdev->device == 0x3483) -+ xhci->quirks |= XHCI_LPM_SUPPORT; -+ - if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && - pdev->device == 0x1042) - xhci->quirks |= XHCI_BROKEN_STREAMS; diff --git a/target/linux/brcm2708/patches-4.19/950-0555-clk-bcm2835-Don-t-wait-for-pllh-lock.patch b/target/linux/brcm2708/patches-4.19/950-0555-clk-bcm2835-Don-t-wait-for-pllh-lock.patch new file mode 100644 index 0000000000..ed6cfcdeb4 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0555-clk-bcm2835-Don-t-wait-for-pllh-lock.patch @@ -0,0 +1,38 @@ +From 3ac14a916d67071cd0311de9cf420e5a649c7517 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 23 Jan 2019 16:11:50 +0000 +Subject: [PATCH 555/725] clk-bcm2835: Don't wait for pllh lock + +Signed-off-by: Phil Elwell +--- + drivers/clk/bcm/clk-bcm2835.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -627,15 +627,17 @@ static int bcm2835_pll_on(struct clk_hw + spin_unlock(&cprman->regs_lock); + + /* Wait for the PLL to lock. */ +- timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS); +- while (!(cprman_read(cprman, CM_LOCK) & data->lock_mask)) { +- if (ktime_after(ktime_get(), timeout)) { +- dev_err(cprman->dev, "%s: couldn't lock PLL\n", +- clk_hw_get_name(hw)); +- return -ETIMEDOUT; +- } ++ if (strcmp(data->name, "pllh")) { ++ timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS); ++ while (!(cprman_read(cprman, CM_LOCK) & data->lock_mask)) { ++ if (ktime_after(ktime_get(), timeout)) { ++ dev_err(cprman->dev, "%s: couldn't lock PLL\n", ++ clk_hw_get_name(hw)); ++ return -ETIMEDOUT; ++ } + +- cpu_relax(); ++ cpu_relax(); ++ } + } + + cprman_write(cprman, data->a2w_ctrl_reg, diff --git a/target/linux/brcm2708/patches-4.19/950-0555-usb-xhci-hack-xhci_urb_enqueue-to-support-hid.mousep.patch b/target/linux/brcm2708/patches-4.19/950-0555-usb-xhci-hack-xhci_urb_enqueue-to-support-hid.mousep.patch deleted file mode 100644 index efb83ac32d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0555-usb-xhci-hack-xhci_urb_enqueue-to-support-hid.mousep.patch +++ /dev/null @@ -1,122 +0,0 @@ -From dd2f4acbdd9731757fe9aedd11164d67a785e25c Mon Sep 17 00:00:00 2001 -From: Jonathan Bell -Date: Thu, 30 May 2019 10:38:40 +0100 -Subject: [PATCH 555/703] usb: xhci: hack xhci_urb_enqueue to support - hid.mousepoll behaviour - -xHCI creates endpoint contexts directly from the device's endpoint -data, so submitting URBs with urb->interval different from the hardware -interval has no effect. - -Add an explicit reconfiguration of the endpoint context when requested, -which will happen only when the interval is different from the cached -value. In practice, the reconfiguration only happens on the first URB -submitted for the endpoint. - -Signed-off-by: Jonathan Bell ---- - drivers/usb/host/xhci.c | 86 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 86 insertions(+) - ---- a/drivers/usb/host/xhci.c -+++ b/drivers/usb/host/xhci.c -@@ -1416,6 +1416,87 @@ command_cleanup: - } - - /* -+ * RPI: Fixup endpoint intervals when requested -+ * - Check interval versus the (cached) endpoint context -+ * - set the endpoint interval to the new value -+ * - force an endpoint configure command -+ */ -+static void xhci_fixup_interval(struct xhci_hcd *xhci, struct urb *urb, -+ unsigned int slot_id, unsigned int ep_index) -+{ -+ struct xhci_ep_ctx *ep_ctx_out, *ep_ctx_in; -+ struct xhci_command *command; -+ struct xhci_input_control_ctx *ctrl_ctx; -+ struct xhci_virt_device *vdev; -+ int xhci_interval, ep_interval; -+ int ret; -+ unsigned long flags; -+ u32 ep_info_tmp; -+ -+ spin_lock_irqsave(&xhci->lock, flags); -+ -+ vdev = xhci->devs[slot_id]; -+ /* Get context-derived endpoint interval */ -+ ep_ctx_out = xhci_get_ep_ctx(xhci, vdev->out_ctx, ep_index); -+ ep_ctx_in = xhci_get_ep_ctx(xhci, vdev->in_ctx, ep_index); -+ xhci_interval = EP_INTERVAL_TO_UFRAMES(le32_to_cpu(ep_ctx_out->ep_info)); -+ ep_interval = urb->interval * 8; -+ -+ if (ep_interval == xhci_interval) { -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ return; -+ } -+ -+ xhci_dbg(xhci, "Fixup interval ep_interval=%d xhci_interval=%d\n", -+ ep_interval, xhci_interval); -+ command = xhci_alloc_command_with_ctx(xhci, true, GFP_ATOMIC); -+ if (!command) { -+ /* Failure here is benign, poll at the original rate */ -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ return; -+ } -+ -+ /* xHCI uses exponents for intervals... */ -+ xhci_interval = fls(ep_interval) - 1; -+ xhci_interval = clamp_val(xhci_interval, 3, 10); -+ ep_info_tmp = le32_to_cpu(ep_ctx_out->ep_info); -+ ep_info_tmp &= ~EP_INTERVAL(255); -+ ep_info_tmp |= EP_INTERVAL(xhci_interval); -+ -+ /* Keep the endpoint context up-to-date while issuing the command. */ -+ xhci_endpoint_copy(xhci, vdev->in_ctx, -+ vdev->out_ctx, ep_index); -+ ep_ctx_in->ep_info = cpu_to_le32(ep_info_tmp); -+ -+ /* -+ * We need to drop the lock, so take an explicit copy -+ * of the ep context. -+ */ -+ xhci_endpoint_copy(xhci, command->in_ctx, vdev->in_ctx, ep_index); -+ -+ ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); -+ if (!ctrl_ctx) { -+ xhci_warn(xhci, -+ "%s: Could not get input context, bad type.\n", -+ __func__); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ xhci_free_command(xhci, command); -+ return; -+ } -+ ctrl_ctx->add_flags = xhci_get_endpoint_flag_from_index(ep_index); -+ ctrl_ctx->drop_flags = 0; -+ -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ -+ ret = xhci_configure_endpoint(xhci, urb->dev, command, -+ false, false); -+ if (ret) -+ xhci_warn(xhci, "%s: Configure endpoint failed: %d\n", -+ __func__, ret); -+ xhci_free_command(xhci, command); -+} -+ -+/* - * non-error returns are a promise to giveback() the urb later - * we drop ownership so next owner (or urb unlink) can get it - */ -@@ -1483,6 +1564,11 @@ static int xhci_urb_enqueue(struct usb_h - } - } - -+ if (usb_endpoint_xfer_int(&urb->ep->desc) && -+ (urb->dev->speed == USB_SPEED_FULL || -+ urb->dev->speed == USB_SPEED_LOW)) -+ xhci_fixup_interval(xhci, urb, slot_id, ep_index); -+ - spin_lock_irqsave(&xhci->lock, flags); - - if (xhci->xhc_state & XHCI_STATE_DYING) { diff --git a/target/linux/brcm2708/patches-4.19/950-0556-bcm2835-pm-Move-bcm2835-watchdog-s-DT-probe-to-an-MF.patch b/target/linux/brcm2708/patches-4.19/950-0556-bcm2835-pm-Move-bcm2835-watchdog-s-DT-probe-to-an-MF.patch new file mode 100644 index 0000000000..36681c52fb --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0556-bcm2835-pm-Move-bcm2835-watchdog-s-DT-probe-to-an-MF.patch @@ -0,0 +1,200 @@ +From 6b41815e23a72453b859e245cad9fcd6a5f0ef31 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 12 Dec 2018 15:51:47 -0800 +Subject: [PATCH 556/725] bcm2835-pm: Move bcm2835-watchdog's DT probe to an + MFD. + +The PM block that the wdt driver was binding to actually has multiple +features we want to expose (power domains, reset, watchdog). Move the +DT attachment to a MFD driver and make WDT probe against MFD. + +Signed-off-by: Eric Anholt +Reviewed-by: Guenter Roeck +Acked-by: Stefan Wahren +Signed-off-by: Stefan Wahren +(cherry picked from commit 5e6acc3e678ed3db746ab4fb53a980861cd711b6) +--- + drivers/mfd/Makefile | 1 + + drivers/mfd/bcm2835-pm.c | 64 ++++++++++++++++++++++++++++++++++ + drivers/watchdog/bcm2835_wdt.c | 26 +++++--------- + include/linux/mfd/bcm2835-pm.h | 13 +++++++ + 4 files changed, 87 insertions(+), 17 deletions(-) + create mode 100644 drivers/mfd/bcm2835-pm.c + create mode 100644 include/linux/mfd/bcm2835-pm.h + +--- a/drivers/mfd/Makefile ++++ b/drivers/mfd/Makefile +@@ -10,6 +10,7 @@ obj-$(CONFIG_MFD_88PM805) += 88pm805.o 8 + obj-$(CONFIG_MFD_ACT8945A) += act8945a.o + obj-$(CONFIG_MFD_SM501) += sm501.o + obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o ++obj-$(CONFIG_ARCH_BCM2835) += bcm2835-pm.o + obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o + obj-$(CONFIG_MFD_BD9571MWV) += bd9571mwv.o + cros_ec_core-objs := cros_ec.o +--- /dev/null ++++ b/drivers/mfd/bcm2835-pm.c +@@ -0,0 +1,64 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * PM MFD driver for Broadcom BCM2835 ++ * ++ * This driver binds to the PM block and creates the MFD device for ++ * the WDT driver. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static const struct mfd_cell bcm2835_pm_devs[] = { ++ { .name = "bcm2835-wdt" }, ++}; ++ ++static int bcm2835_pm_probe(struct platform_device *pdev) ++{ ++ struct resource *res; ++ struct device *dev = &pdev->dev; ++ struct bcm2835_pm *pm; ++ ++ pm = devm_kzalloc(dev, sizeof(*pm), GFP_KERNEL); ++ if (!pm) ++ return -ENOMEM; ++ platform_set_drvdata(pdev, pm); ++ ++ pm->dev = dev; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ pm->base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(pm->base)) ++ return PTR_ERR(pm->base); ++ ++ return devm_mfd_add_devices(dev, -1, ++ bcm2835_pm_devs, ARRAY_SIZE(bcm2835_pm_devs), ++ NULL, 0, NULL); ++} ++ ++static const struct of_device_id bcm2835_pm_of_match[] = { ++ { .compatible = "brcm,bcm2835-pm-wdt", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, bcm2835_pm_of_match); ++ ++static struct platform_driver bcm2835_pm_driver = { ++ .probe = bcm2835_pm_probe, ++ .driver = { ++ .name = "bcm2835-pm", ++ .of_match_table = bcm2835_pm_of_match, ++ }, ++}; ++module_platform_driver(bcm2835_pm_driver); ++ ++MODULE_AUTHOR("Eric Anholt "); ++MODULE_DESCRIPTION("Driver for Broadcom BCM2835 PM MFD"); ++MODULE_LICENSE("GPL"); +--- a/drivers/watchdog/bcm2835_wdt.c ++++ b/drivers/watchdog/bcm2835_wdt.c +@@ -12,6 +12,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -41,6 +42,8 @@ struct bcm2835_wdt { + spinlock_t lock; + }; + ++static struct bcm2835_wdt *bcm2835_power_off_wdt; ++ + static unsigned int heartbeat; + static bool nowayout = WATCHDOG_NOWAYOUT; + +@@ -163,10 +166,7 @@ static struct watchdog_device bcm2835_wd + */ + static void bcm2835_power_off(void) + { +- struct device_node *np = +- of_find_compatible_node(NULL, NULL, "brcm,bcm2835-pm-wdt"); +- struct platform_device *pdev = of_find_device_by_node(np); +- struct bcm2835_wdt *wdt = platform_get_drvdata(pdev); ++ struct bcm2835_wdt *wdt = bcm2835_power_off_wdt; + + /* Partition 63 tells the firmware that this is a halt */ + __bcm2835_restart(wdt, 63); +@@ -174,7 +174,7 @@ static void bcm2835_power_off(void) + + static int bcm2835_wdt_probe(struct platform_device *pdev) + { +- struct resource *res; ++ struct bcm2835_pm *pm = dev_get_drvdata(pdev->dev.parent); + struct device *dev = &pdev->dev; + struct bcm2835_wdt *wdt; + int err; +@@ -186,10 +186,7 @@ static int bcm2835_wdt_probe(struct plat + + spin_lock_init(&wdt->lock); + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- wdt->base = devm_ioremap_resource(dev, res); +- if (IS_ERR(wdt->base)) +- return PTR_ERR(wdt->base); ++ wdt->base = pm->base; + + watchdog_set_drvdata(&bcm2835_wdt_wdd, wdt); + watchdog_init_timeout(&bcm2835_wdt_wdd, heartbeat, dev); +@@ -216,8 +213,10 @@ static int bcm2835_wdt_probe(struct plat + return err; + } + +- if (pm_power_off == NULL) ++ if (pm_power_off == NULL) { + pm_power_off = bcm2835_power_off; ++ bcm2835_power_off_wdt = wdt; ++ } + + dev_info(dev, "Broadcom BCM2835 watchdog timer"); + return 0; +@@ -231,18 +230,11 @@ static int bcm2835_wdt_remove(struct pla + return 0; + } + +-static const struct of_device_id bcm2835_wdt_of_match[] = { +- { .compatible = "brcm,bcm2835-pm-wdt", }, +- {}, +-}; +-MODULE_DEVICE_TABLE(of, bcm2835_wdt_of_match); +- + static struct platform_driver bcm2835_wdt_driver = { + .probe = bcm2835_wdt_probe, + .remove = bcm2835_wdt_remove, + .driver = { + .name = "bcm2835-wdt", +- .of_match_table = bcm2835_wdt_of_match, + }, + }; + module_platform_driver(bcm2835_wdt_driver); +--- /dev/null ++++ b/include/linux/mfd/bcm2835-pm.h +@@ -0,0 +1,13 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++ ++#ifndef BCM2835_MFD_PM_H ++#define BCM2835_MFD_PM_H ++ ++#include ++ ++struct bcm2835_pm { ++ struct device *dev; ++ void __iomem *base; ++}; ++ ++#endif /* BCM2835_MFD_PM_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0556-pinctrl-bcm2835-Add-support-for-BCM2838.patch b/target/linux/brcm2708/patches-4.19/950-0556-pinctrl-bcm2835-Add-support-for-BCM2838.patch deleted file mode 100644 index 617f3fe9b9..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0556-pinctrl-bcm2835-Add-support-for-BCM2838.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 9d0c6b7b815e9c8d578299446a28c3ed54700464 Mon Sep 17 00:00:00 2001 -From: Tim Gover -Date: Wed, 9 Jan 2019 14:43:36 +0000 -Subject: [PATCH 556/703] pinctrl-bcm2835: Add support for BCM2838 - -GPIO configuration on BCM2838 is largely the same as BCM2835 except for -the pull up/down configuration. The old mechanism has been replaced -by new registers which don't require the fixed delay. - -Detect BCN2838 at run-time and use the new mechanism. Backwards -compatibility for the device-tree configuration has been retained. ---- - drivers/pinctrl/bcm/pinctrl-bcm2835.c | 58 ++++++++++++++++++++------- - 1 file changed, 44 insertions(+), 14 deletions(-) - ---- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c -+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c -@@ -67,6 +67,12 @@ - #define GPPUD 0x94 /* Pin Pull-up/down Enable */ - #define GPPUDCLK0 0x98 /* Pin Pull-up/down Enable Clock */ - -+/* 2711 has a different mechanism for pin pull-up/down/enable */ -+#define GPPUPPDN0 0xe4 /* Pin pull-up/down for pins 15:0 */ -+#define GPPUPPDN1 0xe8 /* Pin pull-up/down for pins 31:16 */ -+#define GPPUPPDN2 0xec /* Pin pull-up/down for pins 47:32 */ -+#define GPPUPPDN3 0xf0 /* Pin pull-up/down for pins 57:48 */ -+ - #define FSEL_REG(p) (GPFSEL0 + (((p) / 10) * 4)) - #define FSEL_SHIFT(p) (((p) % 10) * 3) - #define GPIO_REG_OFFSET(p) ((p) / 32) -@@ -917,21 +923,45 @@ static void bcm2835_pull_config_set(stru - unsigned int pin, unsigned int arg) - { - u32 off, bit; -+ /* BCM2835, BCM2836 & BCM2837 return 'gpio' for this unused register */ -+ int is_2835 = bcm2835_gpio_rd(pc, GPPUPPDN3) == 0x6770696f; - -- off = GPIO_REG_OFFSET(pin); -- bit = GPIO_REG_SHIFT(pin); -- -- bcm2835_gpio_wr(pc, GPPUD, arg & 3); -- /* -- * BCM2835 datasheet say to wait 150 cycles, but not of what. -- * But the VideoCore firmware delay for this operation -- * based nearly on the same amount of VPU cycles and this clock -- * runs at 250 MHz. -- */ -- udelay(1); -- bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit)); -- udelay(1); -- bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0); -+ if (is_2835) { -+ off = GPIO_REG_OFFSET(pin); -+ bit = GPIO_REG_SHIFT(pin); -+ /* -+ * BCM2835 datasheet say to wait 150 cycles, but not of what. -+ * But the VideoCore firmware delay for this operation -+ * based nearly on the same amount of VPU cycles and this clock -+ * runs at 250 MHz. -+ */ -+ bcm2835_gpio_wr(pc, GPPUD, arg & 3); -+ udelay(1); -+ bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit)); -+ udelay(1); -+ bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0); -+ } else { -+ u32 reg; -+ int lsb; -+ -+ off = (pin >> 4); -+ if (off > 3) -+ return; -+ lsb = (pin & 0xf) << 1; -+ -+ /* The up/down semantics are reversed compared to BCM2835. -+ * Instead of updating all the device tree files, translate the -+ * values here. -+ */ -+ if (arg == 2) -+ arg = 1; -+ else if (arg == 1) -+ arg = 2; -+ reg = bcm2835_gpio_rd(pc, GPPUPPDN0 + (off *4)); -+ reg &= ~(0x3 << lsb); -+ reg |= (arg & 3) << lsb; -+ bcm2835_gpio_wr(pc, GPPUPPDN0 + (off * 4), reg); -+ } - } - - static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev, diff --git a/target/linux/brcm2708/patches-4.19/950-0557-soc-bcm-bcm2835-pm-Add-support-for-power-domains-und.patch b/target/linux/brcm2708/patches-4.19/950-0557-soc-bcm-bcm2835-pm-Add-support-for-power-domains-und.patch new file mode 100644 index 0000000000..0e718666d9 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0557-soc-bcm-bcm2835-pm-Add-support-for-power-domains-und.patch @@ -0,0 +1,825 @@ +From 25b7b6863a8dd292fa88309f70c980265b076c4e Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 12 Dec 2018 15:51:48 -0800 +Subject: [PATCH 557/725] soc: bcm: bcm2835-pm: Add support for power domains + under a new binding. + +This provides a free software alternative to raspberrypi-power.c's +firmware calls to manage power domains. It also exposes a reset line, +where previously the vc4 driver had to try to force power off the +domain in order to trigger a reset. + +Signed-off-by: Eric Anholt +Acked-by: Rob Herring +Acked-by: Stefan Wahren +Signed-off-by: Stefan Wahren +(cherry picked from commit 670c672608a1ffcbc7ac0f872734843593bb8b15) +--- + drivers/mfd/bcm2835-pm.c | 36 +- + drivers/soc/bcm/Kconfig | 11 + + drivers/soc/bcm/Makefile | 1 + + drivers/soc/bcm/bcm2835-power.c | 661 +++++++++++++++++++++++++++ + include/dt-bindings/soc/bcm2835-pm.h | 28 ++ + include/linux/mfd/bcm2835-pm.h | 1 + + 6 files changed, 734 insertions(+), 4 deletions(-) + create mode 100644 drivers/soc/bcm/bcm2835-power.c + create mode 100644 include/dt-bindings/soc/bcm2835-pm.h + +--- a/drivers/mfd/bcm2835-pm.c ++++ b/drivers/mfd/bcm2835-pm.c +@@ -3,7 +3,7 @@ + * PM MFD driver for Broadcom BCM2835 + * + * This driver binds to the PM block and creates the MFD device for +- * the WDT driver. ++ * the WDT and power drivers. + */ + + #include +@@ -21,11 +21,16 @@ static const struct mfd_cell bcm2835_pm_ + { .name = "bcm2835-wdt" }, + }; + ++static const struct mfd_cell bcm2835_power_devs[] = { ++ { .name = "bcm2835-power" }, ++}; ++ + static int bcm2835_pm_probe(struct platform_device *pdev) + { + struct resource *res; + struct device *dev = &pdev->dev; + struct bcm2835_pm *pm; ++ int ret; + + pm = devm_kzalloc(dev, sizeof(*pm), GFP_KERNEL); + if (!pm) +@@ -39,13 +44,36 @@ static int bcm2835_pm_probe(struct platf + if (IS_ERR(pm->base)) + return PTR_ERR(pm->base); + +- return devm_mfd_add_devices(dev, -1, +- bcm2835_pm_devs, ARRAY_SIZE(bcm2835_pm_devs), +- NULL, 0, NULL); ++ ret = devm_mfd_add_devices(dev, -1, ++ bcm2835_pm_devs, ARRAY_SIZE(bcm2835_pm_devs), ++ NULL, 0, NULL); ++ if (ret) ++ return ret; ++ ++ /* We'll use the presence of the AXI ASB regs in the ++ * bcm2835-pm binding as the key for whether we can reference ++ * the full PM register range and support power domains. ++ */ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ if (res) { ++ pm->asb = devm_ioremap_resource(dev, res); ++ if (IS_ERR(pm->asb)) ++ return PTR_ERR(pm->asb); ++ ++ ret = devm_mfd_add_devices(dev, -1, ++ bcm2835_power_devs, ++ ARRAY_SIZE(bcm2835_power_devs), ++ NULL, 0, NULL); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; + } + + static const struct of_device_id bcm2835_pm_of_match[] = { + { .compatible = "brcm,bcm2835-pm-wdt", }, ++ { .compatible = "brcm,bcm2835-pm", }, + {}, + }; + MODULE_DEVICE_TABLE(of, bcm2835_pm_of_match); +--- a/drivers/soc/bcm/Kconfig ++++ b/drivers/soc/bcm/Kconfig +@@ -1,5 +1,16 @@ + menu "Broadcom SoC drivers" + ++config BCM2835_POWER ++ bool "BCM2835 power domain driver" ++ depends on ARCH_BCM2835 || (COMPILE_TEST && OF) ++ select PM_GENERIC_DOMAINS if PM ++ select RESET_CONTROLLER ++ help ++ This enables support for the BCM2835 power domains and reset ++ controller. Any usage of power domains by the Raspberry Pi ++ firmware means that Linux usage of the same power domain ++ must be accessed using the RASPBERRYPI_POWER driver ++ + config RASPBERRYPI_POWER + bool "Raspberry Pi power domain driver" + depends on ARCH_BCM2835 || (COMPILE_TEST && OF) +--- a/drivers/soc/bcm/Makefile ++++ b/drivers/soc/bcm/Makefile +@@ -1,2 +1,3 @@ ++obj-$(CONFIG_BCM2835_POWER) += bcm2835-power.o + obj-$(CONFIG_RASPBERRYPI_POWER) += raspberrypi-power.o + obj-$(CONFIG_SOC_BRCMSTB) += brcmstb/ +--- /dev/null ++++ b/drivers/soc/bcm/bcm2835-power.c +@@ -0,0 +1,661 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Power domain driver for Broadcom BCM2835 ++ * ++ * Copyright (C) 2018 Broadcom ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define PM_GNRIC 0x00 ++#define PM_AUDIO 0x04 ++#define PM_STATUS 0x18 ++#define PM_RSTC 0x1c ++#define PM_RSTS 0x20 ++#define PM_WDOG 0x24 ++#define PM_PADS0 0x28 ++#define PM_PADS2 0x2c ++#define PM_PADS3 0x30 ++#define PM_PADS4 0x34 ++#define PM_PADS5 0x38 ++#define PM_PADS6 0x3c ++#define PM_CAM0 0x44 ++#define PM_CAM0_LDOHPEN BIT(2) ++#define PM_CAM0_LDOLPEN BIT(1) ++#define PM_CAM0_CTRLEN BIT(0) ++ ++#define PM_CAM1 0x48 ++#define PM_CAM1_LDOHPEN BIT(2) ++#define PM_CAM1_LDOLPEN BIT(1) ++#define PM_CAM1_CTRLEN BIT(0) ++ ++#define PM_CCP2TX 0x4c ++#define PM_CCP2TX_LDOEN BIT(1) ++#define PM_CCP2TX_CTRLEN BIT(0) ++ ++#define PM_DSI0 0x50 ++#define PM_DSI0_LDOHPEN BIT(2) ++#define PM_DSI0_LDOLPEN BIT(1) ++#define PM_DSI0_CTRLEN BIT(0) ++ ++#define PM_DSI1 0x54 ++#define PM_DSI1_LDOHPEN BIT(2) ++#define PM_DSI1_LDOLPEN BIT(1) ++#define PM_DSI1_CTRLEN BIT(0) ++ ++#define PM_HDMI 0x58 ++#define PM_HDMI_RSTDR BIT(19) ++#define PM_HDMI_LDOPD BIT(1) ++#define PM_HDMI_CTRLEN BIT(0) ++ ++#define PM_USB 0x5c ++/* The power gates must be enabled with this bit before enabling the LDO in the ++ * USB block. ++ */ ++#define PM_USB_CTRLEN BIT(0) ++ ++#define PM_PXLDO 0x60 ++#define PM_PXBG 0x64 ++#define PM_DFT 0x68 ++#define PM_SMPS 0x6c ++#define PM_XOSC 0x70 ++#define PM_SPAREW 0x74 ++#define PM_SPARER 0x78 ++#define PM_AVS_RSTDR 0x7c ++#define PM_AVS_STAT 0x80 ++#define PM_AVS_EVENT 0x84 ++#define PM_AVS_INTEN 0x88 ++#define PM_DUMMY 0xfc ++ ++#define PM_IMAGE 0x108 ++#define PM_GRAFX 0x10c ++#define PM_PROC 0x110 ++#define PM_ENAB BIT(12) ++#define PM_ISPRSTN BIT(8) ++#define PM_H264RSTN BIT(7) ++#define PM_PERIRSTN BIT(6) ++#define PM_V3DRSTN BIT(6) ++#define PM_ISFUNC BIT(5) ++#define PM_MRDONE BIT(4) ++#define PM_MEMREP BIT(3) ++#define PM_ISPOW BIT(2) ++#define PM_POWOK BIT(1) ++#define PM_POWUP BIT(0) ++#define PM_INRUSH_SHIFT 13 ++#define PM_INRUSH_3_5_MA 0 ++#define PM_INRUSH_5_MA 1 ++#define PM_INRUSH_10_MA 2 ++#define PM_INRUSH_20_MA 3 ++#define PM_INRUSH_MASK (3 << PM_INRUSH_SHIFT) ++ ++#define PM_PASSWORD 0x5a000000 ++ ++#define PM_WDOG_TIME_SET 0x000fffff ++#define PM_RSTC_WRCFG_CLR 0xffffffcf ++#define PM_RSTS_HADWRH_SET 0x00000040 ++#define PM_RSTC_WRCFG_SET 0x00000030 ++#define PM_RSTC_WRCFG_FULL_RESET 0x00000020 ++#define PM_RSTC_RESET 0x00000102 ++ ++#define PM_READ(reg) readl(power->base + (reg)) ++#define PM_WRITE(reg, val) writel(PM_PASSWORD | (val), power->base + (reg)) ++ ++#define ASB_BRDG_VERSION 0x00 ++#define ASB_CPR_CTRL 0x04 ++ ++#define ASB_V3D_S_CTRL 0x08 ++#define ASB_V3D_M_CTRL 0x0c ++#define ASB_ISP_S_CTRL 0x10 ++#define ASB_ISP_M_CTRL 0x14 ++#define ASB_H264_S_CTRL 0x18 ++#define ASB_H264_M_CTRL 0x1c ++ ++#define ASB_REQ_STOP BIT(0) ++#define ASB_ACK BIT(1) ++#define ASB_EMPTY BIT(2) ++#define ASB_FULL BIT(3) ++ ++#define ASB_AXI_BRDG_ID 0x20 ++ ++#define ASB_READ(reg) readl(power->asb + (reg)) ++#define ASB_WRITE(reg, val) writel(PM_PASSWORD | (val), power->asb + (reg)) ++ ++struct bcm2835_power_domain { ++ struct generic_pm_domain base; ++ struct bcm2835_power *power; ++ u32 domain; ++ struct clk *clk; ++}; ++ ++struct bcm2835_power { ++ struct device *dev; ++ /* PM registers. */ ++ void __iomem *base; ++ /* AXI Async bridge registers. */ ++ void __iomem *asb; ++ ++ struct genpd_onecell_data pd_xlate; ++ struct bcm2835_power_domain domains[BCM2835_POWER_DOMAIN_COUNT]; ++ struct reset_controller_dev reset; ++}; ++ ++static int bcm2835_asb_enable(struct bcm2835_power *power, u32 reg) ++{ ++ u64 start = ktime_get_ns(); ++ ++ /* Enable the module's async AXI bridges. */ ++ ASB_WRITE(reg, ASB_READ(reg) & ~ASB_REQ_STOP); ++ while (ASB_READ(reg) & ASB_ACK) { ++ cpu_relax(); ++ if (ktime_get_ns() - start >= 1000) ++ return -ETIMEDOUT; ++ } ++ ++ return 0; ++} ++ ++static int bcm2835_asb_disable(struct bcm2835_power *power, u32 reg) ++{ ++ u64 start = ktime_get_ns(); ++ ++ /* Enable the module's async AXI bridges. */ ++ ASB_WRITE(reg, ASB_READ(reg) | ASB_REQ_STOP); ++ while (!(ASB_READ(reg) & ASB_ACK)) { ++ cpu_relax(); ++ if (ktime_get_ns() - start >= 1000) ++ return -ETIMEDOUT; ++ } ++ ++ return 0; ++} ++ ++static int bcm2835_power_power_off(struct bcm2835_power_domain *pd, u32 pm_reg) ++{ ++ struct bcm2835_power *power = pd->power; ++ ++ /* Enable functional isolation */ ++ PM_WRITE(pm_reg, PM_READ(pm_reg) & ~PM_ISFUNC); ++ ++ /* Enable electrical isolation */ ++ PM_WRITE(pm_reg, PM_READ(pm_reg) & ~PM_ISPOW); ++ ++ /* Open the power switches. */ ++ PM_WRITE(pm_reg, PM_READ(pm_reg) & ~PM_POWUP); ++ ++ return 0; ++} ++ ++static int bcm2835_power_power_on(struct bcm2835_power_domain *pd, u32 pm_reg) ++{ ++ struct bcm2835_power *power = pd->power; ++ struct device *dev = power->dev; ++ u64 start; ++ int ret; ++ int inrush; ++ bool powok; ++ ++ /* If it was already powered on by the fw, leave it that way. */ ++ if (PM_READ(pm_reg) & PM_POWUP) ++ return 0; ++ ++ /* Enable power. Allowing too much current at once may result ++ * in POWOK never getting set, so start low and ramp it up as ++ * necessary to succeed. ++ */ ++ powok = false; ++ for (inrush = PM_INRUSH_3_5_MA; inrush <= PM_INRUSH_20_MA; inrush++) { ++ PM_WRITE(pm_reg, ++ (PM_READ(pm_reg) & ~PM_INRUSH_MASK) | ++ (inrush << PM_INRUSH_SHIFT) | ++ PM_POWUP); ++ ++ start = ktime_get_ns(); ++ while (!(powok = !!(PM_READ(pm_reg) & PM_POWOK))) { ++ cpu_relax(); ++ if (ktime_get_ns() - start >= 3000) ++ break; ++ } ++ } ++ if (!powok) { ++ dev_err(dev, "Timeout waiting for %s power OK\n", ++ pd->base.name); ++ ret = -ETIMEDOUT; ++ goto err_disable_powup; ++ } ++ ++ /* Disable electrical isolation */ ++ PM_WRITE(pm_reg, PM_READ(pm_reg) | PM_ISPOW); ++ ++ /* Repair memory */ ++ PM_WRITE(pm_reg, PM_READ(pm_reg) | PM_MEMREP); ++ start = ktime_get_ns(); ++ while (!(PM_READ(pm_reg) & PM_MRDONE)) { ++ cpu_relax(); ++ if (ktime_get_ns() - start >= 1000) { ++ dev_err(dev, "Timeout waiting for %s memory repair\n", ++ pd->base.name); ++ ret = -ETIMEDOUT; ++ goto err_disable_ispow; ++ } ++ } ++ ++ /* Disable functional isolation */ ++ PM_WRITE(pm_reg, PM_READ(pm_reg) | PM_ISFUNC); ++ ++ return 0; ++ ++err_disable_ispow: ++ PM_WRITE(pm_reg, PM_READ(pm_reg) & ~PM_ISPOW); ++err_disable_powup: ++ PM_WRITE(pm_reg, PM_READ(pm_reg) & ~(PM_POWUP | PM_INRUSH_MASK)); ++ return ret; ++} ++ ++static int bcm2835_asb_power_on(struct bcm2835_power_domain *pd, ++ u32 pm_reg, ++ u32 asb_m_reg, ++ u32 asb_s_reg, ++ u32 reset_flags) ++{ ++ struct bcm2835_power *power = pd->power; ++ int ret; ++ ++ ret = clk_prepare_enable(pd->clk); ++ if (ret) { ++ dev_err(power->dev, "Failed to enable clock for %s\n", ++ pd->base.name); ++ return ret; ++ } ++ ++ /* Wait 32 clocks for reset to propagate, 1 us will be enough */ ++ udelay(1); ++ ++ clk_disable_unprepare(pd->clk); ++ ++ /* Deassert the resets. */ ++ PM_WRITE(pm_reg, PM_READ(pm_reg) | reset_flags); ++ ++ ret = clk_prepare_enable(pd->clk); ++ if (ret) { ++ dev_err(power->dev, "Failed to enable clock for %s\n", ++ pd->base.name); ++ goto err_enable_resets; ++ } ++ ++ ret = bcm2835_asb_enable(power, asb_m_reg); ++ if (ret) { ++ dev_err(power->dev, "Failed to enable ASB master for %s\n", ++ pd->base.name); ++ goto err_disable_clk; ++ } ++ ret = bcm2835_asb_enable(power, asb_s_reg); ++ if (ret) { ++ dev_err(power->dev, "Failed to enable ASB slave for %s\n", ++ pd->base.name); ++ goto err_disable_asb_master; ++ } ++ ++ return 0; ++ ++err_disable_asb_master: ++ bcm2835_asb_disable(power, asb_m_reg); ++err_disable_clk: ++ clk_disable_unprepare(pd->clk); ++err_enable_resets: ++ PM_WRITE(pm_reg, PM_READ(pm_reg) & ~reset_flags); ++ return ret; ++} ++ ++static int bcm2835_asb_power_off(struct bcm2835_power_domain *pd, ++ u32 pm_reg, ++ u32 asb_m_reg, ++ u32 asb_s_reg, ++ u32 reset_flags) ++{ ++ struct bcm2835_power *power = pd->power; ++ int ret; ++ ++ ret = bcm2835_asb_disable(power, asb_s_reg); ++ if (ret) { ++ dev_warn(power->dev, "Failed to disable ASB slave for %s\n", ++ pd->base.name); ++ return ret; ++ } ++ ret = bcm2835_asb_disable(power, asb_m_reg); ++ if (ret) { ++ dev_warn(power->dev, "Failed to disable ASB master for %s\n", ++ pd->base.name); ++ bcm2835_asb_enable(power, asb_s_reg); ++ return ret; ++ } ++ ++ clk_disable_unprepare(pd->clk); ++ ++ /* Assert the resets. */ ++ PM_WRITE(pm_reg, PM_READ(pm_reg) & ~reset_flags); ++ ++ return 0; ++} ++ ++static int bcm2835_power_pd_power_on(struct generic_pm_domain *domain) ++{ ++ struct bcm2835_power_domain *pd = ++ container_of(domain, struct bcm2835_power_domain, base); ++ struct bcm2835_power *power = pd->power; ++ ++ switch (pd->domain) { ++ case BCM2835_POWER_DOMAIN_GRAFX: ++ return bcm2835_power_power_on(pd, PM_GRAFX); ++ ++ case BCM2835_POWER_DOMAIN_GRAFX_V3D: ++ return bcm2835_asb_power_on(pd, PM_GRAFX, ++ ASB_V3D_M_CTRL, ASB_V3D_S_CTRL, ++ PM_V3DRSTN); ++ ++ case BCM2835_POWER_DOMAIN_IMAGE: ++ return bcm2835_power_power_on(pd, PM_IMAGE); ++ ++ case BCM2835_POWER_DOMAIN_IMAGE_PERI: ++ return bcm2835_asb_power_on(pd, PM_IMAGE, ++ 0, 0, ++ PM_PERIRSTN); ++ ++ case BCM2835_POWER_DOMAIN_IMAGE_ISP: ++ return bcm2835_asb_power_on(pd, PM_IMAGE, ++ ASB_ISP_M_CTRL, ASB_ISP_S_CTRL, ++ PM_ISPRSTN); ++ ++ case BCM2835_POWER_DOMAIN_IMAGE_H264: ++ return bcm2835_asb_power_on(pd, PM_IMAGE, ++ ASB_H264_M_CTRL, ASB_H264_S_CTRL, ++ PM_H264RSTN); ++ ++ case BCM2835_POWER_DOMAIN_USB: ++ PM_WRITE(PM_USB, PM_USB_CTRLEN); ++ return 0; ++ ++ case BCM2835_POWER_DOMAIN_DSI0: ++ PM_WRITE(PM_DSI0, PM_DSI0_CTRLEN); ++ PM_WRITE(PM_DSI0, PM_DSI0_CTRLEN | PM_DSI0_LDOHPEN); ++ return 0; ++ ++ case BCM2835_POWER_DOMAIN_DSI1: ++ PM_WRITE(PM_DSI1, PM_DSI1_CTRLEN); ++ PM_WRITE(PM_DSI1, PM_DSI1_CTRLEN | PM_DSI1_LDOHPEN); ++ return 0; ++ ++ case BCM2835_POWER_DOMAIN_CCP2TX: ++ PM_WRITE(PM_CCP2TX, PM_CCP2TX_CTRLEN); ++ PM_WRITE(PM_CCP2TX, PM_CCP2TX_CTRLEN | PM_CCP2TX_LDOEN); ++ return 0; ++ ++ case BCM2835_POWER_DOMAIN_HDMI: ++ PM_WRITE(PM_HDMI, PM_READ(PM_HDMI) | PM_HDMI_RSTDR); ++ PM_WRITE(PM_HDMI, PM_READ(PM_HDMI) | PM_HDMI_CTRLEN); ++ PM_WRITE(PM_HDMI, PM_READ(PM_HDMI) & ~PM_HDMI_LDOPD); ++ usleep_range(100, 200); ++ PM_WRITE(PM_HDMI, PM_READ(PM_HDMI) & ~PM_HDMI_RSTDR); ++ return 0; ++ ++ default: ++ dev_err(power->dev, "Invalid domain %d\n", pd->domain); ++ return -EINVAL; ++ } ++} ++ ++static int bcm2835_power_pd_power_off(struct generic_pm_domain *domain) ++{ ++ struct bcm2835_power_domain *pd = ++ container_of(domain, struct bcm2835_power_domain, base); ++ struct bcm2835_power *power = pd->power; ++ ++ switch (pd->domain) { ++ case BCM2835_POWER_DOMAIN_GRAFX: ++ return bcm2835_power_power_off(pd, PM_GRAFX); ++ ++ case BCM2835_POWER_DOMAIN_GRAFX_V3D: ++ return bcm2835_asb_power_off(pd, PM_GRAFX, ++ ASB_V3D_M_CTRL, ASB_V3D_S_CTRL, ++ PM_V3DRSTN); ++ ++ case BCM2835_POWER_DOMAIN_IMAGE: ++ return bcm2835_power_power_off(pd, PM_IMAGE); ++ ++ case BCM2835_POWER_DOMAIN_IMAGE_PERI: ++ return bcm2835_asb_power_off(pd, PM_IMAGE, ++ 0, 0, ++ PM_PERIRSTN); ++ ++ case BCM2835_POWER_DOMAIN_IMAGE_ISP: ++ return bcm2835_asb_power_off(pd, PM_IMAGE, ++ ASB_ISP_M_CTRL, ASB_ISP_S_CTRL, ++ PM_ISPRSTN); ++ ++ case BCM2835_POWER_DOMAIN_IMAGE_H264: ++ return bcm2835_asb_power_off(pd, PM_IMAGE, ++ ASB_H264_M_CTRL, ASB_H264_S_CTRL, ++ PM_H264RSTN); ++ ++ case BCM2835_POWER_DOMAIN_USB: ++ PM_WRITE(PM_USB, 0); ++ return 0; ++ ++ case BCM2835_POWER_DOMAIN_DSI0: ++ PM_WRITE(PM_DSI0, PM_DSI0_CTRLEN); ++ PM_WRITE(PM_DSI0, 0); ++ return 0; ++ ++ case BCM2835_POWER_DOMAIN_DSI1: ++ PM_WRITE(PM_DSI1, PM_DSI1_CTRLEN); ++ PM_WRITE(PM_DSI1, 0); ++ return 0; ++ ++ case BCM2835_POWER_DOMAIN_CCP2TX: ++ PM_WRITE(PM_CCP2TX, PM_CCP2TX_CTRLEN); ++ PM_WRITE(PM_CCP2TX, 0); ++ return 0; ++ ++ case BCM2835_POWER_DOMAIN_HDMI: ++ PM_WRITE(PM_HDMI, PM_READ(PM_HDMI) | PM_HDMI_LDOPD); ++ PM_WRITE(PM_HDMI, PM_READ(PM_HDMI) & ~PM_HDMI_CTRLEN); ++ return 0; ++ ++ default: ++ dev_err(power->dev, "Invalid domain %d\n", pd->domain); ++ return -EINVAL; ++ } ++} ++ ++static void ++bcm2835_init_power_domain(struct bcm2835_power *power, ++ int pd_xlate_index, const char *name) ++{ ++ struct device *dev = power->dev; ++ struct bcm2835_power_domain *dom = &power->domains[pd_xlate_index]; ++ ++ dom->clk = devm_clk_get(dev->parent, name); ++ ++ dom->base.name = name; ++ dom->base.power_on = bcm2835_power_pd_power_on; ++ dom->base.power_off = bcm2835_power_pd_power_off; ++ ++ dom->domain = pd_xlate_index; ++ dom->power = power; ++ ++ /* XXX: on/off at boot? */ ++ pm_genpd_init(&dom->base, NULL, true); ++ ++ power->pd_xlate.domains[pd_xlate_index] = &dom->base; ++} ++ ++/** bcm2835_reset_reset - Resets a block that has a reset line in the ++ * PM block. ++ * ++ * The consumer of the reset controller must have the power domain up ++ * -- there's no reset ability with the power domain down. To reset ++ * the sub-block, we just disable its access to memory through the ++ * ASB, reset, and re-enable. ++ */ ++static int bcm2835_reset_reset(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct bcm2835_power *power = container_of(rcdev, struct bcm2835_power, ++ reset); ++ struct bcm2835_power_domain *pd; ++ int ret; ++ ++ switch (id) { ++ case BCM2835_RESET_V3D: ++ pd = &power->domains[BCM2835_POWER_DOMAIN_GRAFX_V3D]; ++ break; ++ case BCM2835_RESET_H264: ++ pd = &power->domains[BCM2835_POWER_DOMAIN_IMAGE_H264]; ++ break; ++ case BCM2835_RESET_ISP: ++ pd = &power->domains[BCM2835_POWER_DOMAIN_IMAGE_ISP]; ++ break; ++ default: ++ dev_err(power->dev, "Bad reset id %ld\n", id); ++ return -EINVAL; ++ } ++ ++ ret = bcm2835_power_pd_power_off(&pd->base); ++ if (ret) ++ return ret; ++ ++ return bcm2835_power_pd_power_on(&pd->base); ++} ++ ++static int bcm2835_reset_status(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct bcm2835_power *power = container_of(rcdev, struct bcm2835_power, ++ reset); ++ ++ switch (id) { ++ case BCM2835_RESET_V3D: ++ return !PM_READ(PM_GRAFX & PM_V3DRSTN); ++ case BCM2835_RESET_H264: ++ return !PM_READ(PM_IMAGE & PM_H264RSTN); ++ case BCM2835_RESET_ISP: ++ return !PM_READ(PM_IMAGE & PM_ISPRSTN); ++ default: ++ return -EINVAL; ++ } ++} ++ ++const struct reset_control_ops bcm2835_reset_ops = { ++ .reset = bcm2835_reset_reset, ++ .status = bcm2835_reset_status, ++}; ++ ++static const char *const power_domain_names[] = { ++ [BCM2835_POWER_DOMAIN_GRAFX] = "grafx", ++ [BCM2835_POWER_DOMAIN_GRAFX_V3D] = "v3d", ++ ++ [BCM2835_POWER_DOMAIN_IMAGE] = "image", ++ [BCM2835_POWER_DOMAIN_IMAGE_PERI] = "peri_image", ++ [BCM2835_POWER_DOMAIN_IMAGE_H264] = "h264", ++ [BCM2835_POWER_DOMAIN_IMAGE_ISP] = "isp", ++ ++ [BCM2835_POWER_DOMAIN_USB] = "usb", ++ [BCM2835_POWER_DOMAIN_DSI0] = "dsi0", ++ [BCM2835_POWER_DOMAIN_DSI1] = "dsi1", ++ [BCM2835_POWER_DOMAIN_CAM0] = "cam0", ++ [BCM2835_POWER_DOMAIN_CAM1] = "cam1", ++ [BCM2835_POWER_DOMAIN_CCP2TX] = "ccp2tx", ++ [BCM2835_POWER_DOMAIN_HDMI] = "hdmi", ++}; ++ ++static int bcm2835_power_probe(struct platform_device *pdev) ++{ ++ struct bcm2835_pm *pm = dev_get_drvdata(pdev->dev.parent); ++ struct device *dev = &pdev->dev; ++ struct bcm2835_power *power; ++ static const struct { ++ int parent, child; ++ } domain_deps[] = { ++ { BCM2835_POWER_DOMAIN_GRAFX, BCM2835_POWER_DOMAIN_GRAFX_V3D }, ++ { BCM2835_POWER_DOMAIN_IMAGE, BCM2835_POWER_DOMAIN_IMAGE_PERI }, ++ { BCM2835_POWER_DOMAIN_IMAGE, BCM2835_POWER_DOMAIN_IMAGE_H264 }, ++ { BCM2835_POWER_DOMAIN_IMAGE, BCM2835_POWER_DOMAIN_IMAGE_ISP }, ++ { BCM2835_POWER_DOMAIN_IMAGE_PERI, BCM2835_POWER_DOMAIN_USB }, ++ { BCM2835_POWER_DOMAIN_IMAGE_PERI, BCM2835_POWER_DOMAIN_CAM0 }, ++ { BCM2835_POWER_DOMAIN_IMAGE_PERI, BCM2835_POWER_DOMAIN_CAM1 }, ++ }; ++ int ret, i; ++ u32 id; ++ ++ power = devm_kzalloc(dev, sizeof(*power), GFP_KERNEL); ++ if (!power) ++ return -ENOMEM; ++ platform_set_drvdata(pdev, power); ++ ++ power->dev = dev; ++ power->base = pm->base; ++ power->asb = pm->asb; ++ ++ id = ASB_READ(ASB_AXI_BRDG_ID); ++ if (id != 0x62726467 /* "BRDG" */) { ++ dev_err(dev, "ASB register ID returned 0x%08x\n", id); ++ return -ENODEV; ++ } ++ ++ power->pd_xlate.domains = devm_kcalloc(dev, ++ ARRAY_SIZE(power_domain_names), ++ sizeof(*power->pd_xlate.domains), ++ GFP_KERNEL); ++ if (!power->pd_xlate.domains) ++ return -ENOMEM; ++ ++ power->pd_xlate.num_domains = ARRAY_SIZE(power_domain_names); ++ ++ for (i = 0; i < ARRAY_SIZE(power_domain_names); i++) ++ bcm2835_init_power_domain(power, i, power_domain_names[i]); ++ ++ for (i = 0; i < ARRAY_SIZE(domain_deps); i++) { ++ pm_genpd_add_subdomain(&power->domains[domain_deps[i].parent].base, ++ &power->domains[domain_deps[i].child].base); ++ } ++ ++ power->reset.owner = THIS_MODULE; ++ power->reset.nr_resets = BCM2835_RESET_COUNT; ++ power->reset.ops = &bcm2835_reset_ops; ++ power->reset.of_node = dev->parent->of_node; ++ ++ ret = devm_reset_controller_register(dev, &power->reset); ++ if (ret) ++ return ret; ++ ++ of_genpd_add_provider_onecell(dev->parent->of_node, &power->pd_xlate); ++ ++ dev_info(dev, "Broadcom BCM2835 power domains driver"); ++ return 0; ++} ++ ++static int bcm2835_power_remove(struct platform_device *pdev) ++{ ++ return 0; ++} ++ ++static struct platform_driver bcm2835_power_driver = { ++ .probe = bcm2835_power_probe, ++ .remove = bcm2835_power_remove, ++ .driver = { ++ .name = "bcm2835-power", ++ }, ++}; ++module_platform_driver(bcm2835_power_driver); ++ ++MODULE_AUTHOR("Eric Anholt "); ++MODULE_DESCRIPTION("Driver for Broadcom BCM2835 PM power domains and reset"); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ b/include/dt-bindings/soc/bcm2835-pm.h +@@ -0,0 +1,28 @@ ++/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ ++ ++#ifndef _DT_BINDINGS_ARM_BCM2835_PM_H ++#define _DT_BINDINGS_ARM_BCM2835_PM_H ++ ++#define BCM2835_POWER_DOMAIN_GRAFX 0 ++#define BCM2835_POWER_DOMAIN_GRAFX_V3D 1 ++#define BCM2835_POWER_DOMAIN_IMAGE 2 ++#define BCM2835_POWER_DOMAIN_IMAGE_PERI 3 ++#define BCM2835_POWER_DOMAIN_IMAGE_ISP 4 ++#define BCM2835_POWER_DOMAIN_IMAGE_H264 5 ++#define BCM2835_POWER_DOMAIN_USB 6 ++#define BCM2835_POWER_DOMAIN_DSI0 7 ++#define BCM2835_POWER_DOMAIN_DSI1 8 ++#define BCM2835_POWER_DOMAIN_CAM0 9 ++#define BCM2835_POWER_DOMAIN_CAM1 10 ++#define BCM2835_POWER_DOMAIN_CCP2TX 11 ++#define BCM2835_POWER_DOMAIN_HDMI 12 ++ ++#define BCM2835_POWER_DOMAIN_COUNT 13 ++ ++#define BCM2835_RESET_V3D 0 ++#define BCM2835_RESET_ISP 1 ++#define BCM2835_RESET_H264 2 ++ ++#define BCM2835_RESET_COUNT 3 ++ ++#endif /* _DT_BINDINGS_ARM_BCM2835_PM_H */ +--- a/include/linux/mfd/bcm2835-pm.h ++++ b/include/linux/mfd/bcm2835-pm.h +@@ -8,6 +8,7 @@ + struct bcm2835_pm { + struct device *dev; + void __iomem *base; ++ void __iomem *asb; + }; + + #endif /* BCM2835_MFD_PM_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0557-spi-bcm2835-enable-shared-interrupt-support.patch b/target/linux/brcm2708/patches-4.19/950-0557-spi-bcm2835-enable-shared-interrupt-support.patch deleted file mode 100644 index 698134562d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0557-spi-bcm2835-enable-shared-interrupt-support.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 6dc0f30ee18404547a2ca94fd11914ea0d75841f Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Mon, 13 May 2019 11:05:27 +0000 -Subject: [PATCH 557/703] spi: bcm2835: enable shared interrupt support - -Add shared interrupt support for this driver. - -Signed-off-by: Martin Sperl ---- - drivers/spi/spi-bcm2835.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -150,6 +150,10 @@ static irqreturn_t bcm2835_spi_interrupt - struct spi_master *master = dev_id; - struct bcm2835_spi *bs = spi_master_get_devdata(master); - -+ /* check if we got interrupt enabled */ -+ if (!(bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_INTR)) -+ return IRQ_NONE; -+ - /* Read as many bytes as possible from FIFO */ - bcm2835_rd_fifo(bs); - /* Write as many bytes as possible to FIFO */ -@@ -755,7 +759,8 @@ static int bcm2835_spi_probe(struct plat - bcm2835_wr(bs, BCM2835_SPI_CS, - BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); - -- err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, 0, -+ err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, -+ IRQF_SHARED, - dev_name(&pdev->dev), master); - if (err) { - dev_err(&pdev->dev, "could not request IRQ: %d\n", err); diff --git a/target/linux/brcm2708/patches-4.19/950-0558-drivers-char-add-chardev-for-mmap-ing-Argon-control-.patch b/target/linux/brcm2708/patches-4.19/950-0558-drivers-char-add-chardev-for-mmap-ing-Argon-control-.patch deleted file mode 100644 index 2b3ea32548..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0558-drivers-char-add-chardev-for-mmap-ing-Argon-control-.patch +++ /dev/null @@ -1,320 +0,0 @@ -From 0a0ebc37b25830162918aa31278b2f7857b8032b Mon Sep 17 00:00:00 2001 -From: Jonathan Bell -Date: Thu, 9 May 2019 14:30:37 +0100 -Subject: [PATCH 558/703] drivers: char: add chardev for mmap'ing Argon control - registers - -Based on the gpiomem driver, allow mapping of the decoder register -spaces such that userspace can access control/status registers. -This driver is intended for use with a custom ffmpeg backend accelerator -prior to a v4l2 driver being written. - -Signed-off-by: Jonathan Bell ---- - drivers/char/broadcom/Kconfig | 8 + - drivers/char/broadcom/Makefile | 1 + - drivers/char/broadcom/argon-mem.c | 277 ++++++++++++++++++++++++++++++ - 3 files changed, 286 insertions(+) - create mode 100644 drivers/char/broadcom/argon-mem.c - ---- a/drivers/char/broadcom/Kconfig -+++ b/drivers/char/broadcom/Kconfig -@@ -49,3 +49,11 @@ config BCM2835_SMI_DEV - This driver provides a character device interface (ioctl + read/write) to - Broadcom's Secondary Memory interface. The low-level functionality is provided - by the SMI driver itself. -+ -+config ARGON_MEM -+ tristate "Character device driver for the Argon decoder hardware" -+ default n -+ help -+ This driver provides a character device interface for memory-map operations -+ so userspace tools can access the control and status registers of the Argon -+ video decoder hardware. ---- a/drivers/char/broadcom/Makefile -+++ b/drivers/char/broadcom/Makefile -@@ -4,3 +4,4 @@ obj-$(CONFIG_BCM_VC_SM) += vc_sm - - obj-$(CONFIG_BCM2835_DEVGPIOMEM)+= bcm2835-gpiomem.o - obj-$(CONFIG_BCM2835_SMI_DEV) += bcm2835_smi_dev.o -+obj-$(CONFIG_ARGON_MEM) += argon-mem.o ---- /dev/null -+++ b/drivers/char/broadcom/argon-mem.c -@@ -0,0 +1,277 @@ -+/** -+ * argon-mem.c - character device access to the Argon decoder registers -+ * -+ * Based on bcm2835-gpiomem.c. Provides IO memory access to the decoder -+ * register blocks such that ffmpeg plugins can access the hardware. -+ * -+ * Jonathan Bell -+ * Copyright (c) 2019, Raspberry Pi (Trading) Ltd. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions, and the following disclaimer, -+ * without modification. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. The names of the above-listed copyright holders may not be used -+ * to endorse or promote products derived from this software without -+ * specific prior written permission. -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") version 2, as published by the Free -+ * Software Foundation. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DRIVER_NAME "argon-mem" -+#define DEVICE_MINOR 0 -+ -+struct argon_mem_priv { -+ dev_t devid; -+ struct class *class; -+ struct cdev argon_mem_cdev; -+ unsigned long regs_phys; -+ unsigned long mem_window_len; -+ struct device *dev; -+ const char *name; -+}; -+ -+static int argon_mem_open(struct inode *inode, struct file *file) -+{ -+ int dev = iminor(inode); -+ int ret = 0; -+ struct argon_mem_priv *priv; -+ if (dev != DEVICE_MINOR) -+ ret = -ENXIO; -+ -+ priv = container_of(inode->i_cdev, struct argon_mem_priv, -+ argon_mem_cdev); -+ if (!priv) -+ return -EINVAL; -+ file->private_data = priv; -+ return ret; -+} -+ -+static int argon_mem_release(struct inode *inode, struct file *file) -+{ -+ int dev = iminor(inode); -+ int ret = 0; -+ -+ if (dev != DEVICE_MINOR) -+ ret = -ENXIO; -+ -+ return ret; -+} -+ -+static const struct vm_operations_struct argon_mem_vm_ops = { -+#ifdef CONFIG_HAVE_IOREMAP_PROT -+ .access = generic_access_phys -+#endif -+}; -+ -+static int argon_mem_mmap(struct file *file, struct vm_area_struct *vma) -+{ -+ struct argon_mem_priv *priv; -+ unsigned long pages; -+ -+ priv = file->private_data; -+ pages = priv->regs_phys >> PAGE_SHIFT; -+ /* -+ * The address decode is far larger than the actual number of registers. -+ * Just map the whole lot in. -+ */ -+ vma->vm_page_prot = phys_mem_access_prot(file, pages, -+ priv->mem_window_len, -+ vma->vm_page_prot); -+ vma->vm_ops = &argon_mem_vm_ops; -+ if (remap_pfn_range(vma, vma->vm_start, -+ pages, -+ priv->mem_window_len, -+ vma->vm_page_prot)) { -+ return -EAGAIN; -+ } -+ return 0; -+} -+ -+static const struct file_operations -+argon_mem_fops = { -+ .owner = THIS_MODULE, -+ .open = argon_mem_open, -+ .release = argon_mem_release, -+ .mmap = argon_mem_mmap, -+}; -+ -+static const struct of_device_id argon_mem_of_match[]; -+static int argon_mem_probe(struct platform_device *pdev) -+{ -+ int err; -+ void *ptr_err; -+ const struct of_device_id *id; -+ struct device *dev = &pdev->dev; -+ struct device *argon_mem_dev; -+ struct resource *ioresource; -+ struct argon_mem_priv *priv; -+ -+ -+ /* Allocate buffers and instance data */ -+ -+ priv = kzalloc(sizeof(struct argon_mem_priv), GFP_KERNEL); -+ -+ if (!priv) { -+ err = -ENOMEM; -+ goto failed_inst_alloc; -+ } -+ platform_set_drvdata(pdev, priv); -+ -+ priv->dev = dev; -+ id = of_match_device(argon_mem_of_match, dev); -+ if (!id) -+ return -EINVAL; -+ priv->name = id->data; -+ -+ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (ioresource) { -+ priv->regs_phys = ioresource->start; -+ priv->mem_window_len = ioresource->end - ioresource->start; -+ } else { -+ dev_err(priv->dev, "failed to get IO resource"); -+ err = -ENOENT; -+ goto failed_get_resource; -+ } -+ -+ /* Create character device entries */ -+ -+ err = alloc_chrdev_region(&priv->devid, -+ DEVICE_MINOR, 1, priv->name); -+ if (err != 0) { -+ dev_err(priv->dev, "unable to allocate device number"); -+ goto failed_alloc_chrdev; -+ } -+ cdev_init(&priv->argon_mem_cdev, &argon_mem_fops); -+ priv->argon_mem_cdev.owner = THIS_MODULE; -+ err = cdev_add(&priv->argon_mem_cdev, priv->devid, 1); -+ if (err != 0) { -+ dev_err(priv->dev, "unable to register device"); -+ goto failed_cdev_add; -+ } -+ -+ /* Create sysfs entries */ -+ -+ priv->class = class_create(THIS_MODULE, priv->name); -+ ptr_err = priv->class; -+ if (IS_ERR(ptr_err)) -+ goto failed_class_create; -+ -+ argon_mem_dev = device_create(priv->class, NULL, -+ priv->devid, NULL, -+ priv->name); -+ ptr_err = argon_mem_dev; -+ if (IS_ERR(ptr_err)) -+ goto failed_device_create; -+ -+ dev_info(priv->dev, "%s initialised: Registers at 0x%08lx length 0x%08lx", -+ priv->name, priv->regs_phys, priv->mem_window_len); -+ -+ return 0; -+ -+failed_device_create: -+ class_destroy(priv->class); -+failed_class_create: -+ cdev_del(&priv->argon_mem_cdev); -+ err = PTR_ERR(ptr_err); -+failed_cdev_add: -+ unregister_chrdev_region(priv->devid, 1); -+failed_alloc_chrdev: -+failed_get_resource: -+ kfree(priv); -+failed_inst_alloc: -+ dev_err(priv->dev, "could not load argon_mem"); -+ return err; -+} -+ -+static int argon_mem_remove(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct argon_mem_priv *priv = platform_get_drvdata(pdev); -+ -+ device_destroy(priv->class, priv->devid); -+ class_destroy(priv->class); -+ cdev_del(&priv->argon_mem_cdev); -+ unregister_chrdev_region(priv->devid, 1); -+ kfree(priv); -+ -+ dev_info(dev, "%s driver removed - OK", priv->name); -+ return 0; -+} -+ -+static const char argon_hevc_name[] = "argon-hevcmem"; -+static const char argon_h264_name[] = "argon-h264mem"; -+static const char argon_vp9_name[] = "argon-vp9mem"; -+static const char argon_intc_name[] = "argon-intcmem"; -+ -+static const struct of_device_id argon_mem_of_match[] = { -+ { -+ .compatible = "raspberrypi,argon-hevc-decoder", -+ .data = &argon_hevc_name, -+ }, -+ { -+ .compatible = "raspberrypi,argon-h264-decoder", -+ .data = &argon_h264_name, -+ }, -+ { -+ .compatible = "raspberrypi,argon-vp9-decoder", -+ .data = &argon_vp9_name, -+ }, -+ /* The "intc" is included as this block of hardware contains the -+ * "frame done" status flags. -+ */ -+ { -+ .compatible = "raspberrypi,argon-local-intc", -+ .data = &argon_intc_name, -+ }, -+ { /* sentinel */ }, -+}; -+ -+MODULE_DEVICE_TABLE(of, argon_mem_of_match); -+ -+static struct platform_driver argon_mem_driver = { -+ .probe = argon_mem_probe, -+ .remove = argon_mem_remove, -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = argon_mem_of_match, -+ }, -+}; -+ -+module_platform_driver(argon_mem_driver); -+ -+MODULE_ALIAS("platform:argon-mem"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Driver for accessing Argon decoder registers from userspace"); -+MODULE_AUTHOR("Jonathan Bell "); diff --git a/target/linux/brcm2708/patches-4.19/950-0558-soc-bcm-bcm2835-pm-Fix-PM_IMAGE_PERI-power-domain-su.patch b/target/linux/brcm2708/patches-4.19/950-0558-soc-bcm-bcm2835-pm-Fix-PM_IMAGE_PERI-power-domain-su.patch new file mode 100644 index 0000000000..8d5059b8af --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0558-soc-bcm-bcm2835-pm-Fix-PM_IMAGE_PERI-power-domain-su.patch @@ -0,0 +1,45 @@ +From 3cd53598cdb1749d6d5ed03e378276be22fc6e8d Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Fri, 11 Jan 2019 17:29:10 -0800 +Subject: [PATCH 558/725] soc: bcm: bcm2835-pm: Fix PM_IMAGE_PERI power domain + support. + +We don't have ASB master/slave regs for this domain, so just skip that +step. + +Signed-off-by: Eric Anholt +Fixes: 670c672608a1 ("soc: bcm: bcm2835-pm: Add support for power domains under a new binding.") +--- + drivers/soc/bcm/bcm2835-power.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/drivers/soc/bcm/bcm2835-power.c ++++ b/drivers/soc/bcm/bcm2835-power.c +@@ -150,7 +150,12 @@ struct bcm2835_power { + + static int bcm2835_asb_enable(struct bcm2835_power *power, u32 reg) + { +- u64 start = ktime_get_ns(); ++ u64 start; ++ ++ if (!reg) ++ return 0; ++ ++ start = ktime_get_ns(); + + /* Enable the module's async AXI bridges. */ + ASB_WRITE(reg, ASB_READ(reg) & ~ASB_REQ_STOP); +@@ -165,7 +170,12 @@ static int bcm2835_asb_enable(struct bcm + + static int bcm2835_asb_disable(struct bcm2835_power *power, u32 reg) + { +- u64 start = ktime_get_ns(); ++ u64 start; ++ ++ if (!reg) ++ return 0; ++ ++ start = ktime_get_ns(); + + /* Enable the module's async AXI bridges. */ + ASB_WRITE(reg, ASB_READ(reg) | ASB_REQ_STOP); diff --git a/target/linux/brcm2708/patches-4.19/950-0559-clk-bcm2835-Don-t-wait-for-pllh-lock.patch b/target/linux/brcm2708/patches-4.19/950-0559-clk-bcm2835-Don-t-wait-for-pllh-lock.patch deleted file mode 100644 index b4c7afd870..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0559-clk-bcm2835-Don-t-wait-for-pllh-lock.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 258c43d5303a3afe7c416b4fa9875bdbd3470131 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 23 Jan 2019 16:11:50 +0000 -Subject: [PATCH 559/703] clk-bcm2835: Don't wait for pllh lock - -Signed-off-by: Phil Elwell ---- - drivers/clk/bcm/clk-bcm2835.c | 18 ++++++++++-------- - 1 file changed, 10 insertions(+), 8 deletions(-) - ---- a/drivers/clk/bcm/clk-bcm2835.c -+++ b/drivers/clk/bcm/clk-bcm2835.c -@@ -627,15 +627,17 @@ static int bcm2835_pll_on(struct clk_hw - spin_unlock(&cprman->regs_lock); - - /* Wait for the PLL to lock. */ -- timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS); -- while (!(cprman_read(cprman, CM_LOCK) & data->lock_mask)) { -- if (ktime_after(ktime_get(), timeout)) { -- dev_err(cprman->dev, "%s: couldn't lock PLL\n", -- clk_hw_get_name(hw)); -- return -ETIMEDOUT; -- } -+ if (strcmp(data->name, "pllh")) { -+ timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS); -+ while (!(cprman_read(cprman, CM_LOCK) & data->lock_mask)) { -+ if (ktime_after(ktime_get(), timeout)) { -+ dev_err(cprman->dev, "%s: couldn't lock PLL\n", -+ clk_hw_get_name(hw)); -+ return -ETIMEDOUT; -+ } - -- cpu_relax(); -+ cpu_relax(); -+ } - } - - cprman_write(cprman, data->a2w_ctrl_reg, diff --git a/target/linux/brcm2708/patches-4.19/950-0559-soc-bcm-bcm2835-pm-Fix-error-paths-of-initialization.patch b/target/linux/brcm2708/patches-4.19/950-0559-soc-bcm-bcm2835-pm-Fix-error-paths-of-initialization.patch new file mode 100644 index 0000000000..0259a5e8bb --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0559-soc-bcm-bcm2835-pm-Fix-error-paths-of-initialization.patch @@ -0,0 +1,103 @@ +From b1b13630de7806f63b4e10cd90f91ad4bc3d1247 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Sat, 12 Jan 2019 08:07:43 -0800 +Subject: [PATCH 559/725] soc: bcm: bcm2835-pm: Fix error paths of + initialization. + +The clock driver may probe after ours and so we need to pass the +-EPROBE_DEFER out. Fix the other error path while we're here. + +v2: Use dom->name instead of dom->gov as the flag for initialized + domains, since we aren't setting up a governor. Make sure to + clear ->clk when no clk is present in the DT. + +Signed-off-by: Eric Anholt +Fixes: 670c672608a1 ("soc: bcm: bcm2835-pm: Add support for power domains under a new binding.") +--- + drivers/soc/bcm/bcm2835-power.c | 35 ++++++++++++++++++++++++++++----- + 1 file changed, 30 insertions(+), 5 deletions(-) + +--- a/drivers/soc/bcm/bcm2835-power.c ++++ b/drivers/soc/bcm/bcm2835-power.c +@@ -485,7 +485,7 @@ static int bcm2835_power_pd_power_off(st + } + } + +-static void ++static int + bcm2835_init_power_domain(struct bcm2835_power *power, + int pd_xlate_index, const char *name) + { +@@ -493,6 +493,17 @@ bcm2835_init_power_domain(struct bcm2835 + struct bcm2835_power_domain *dom = &power->domains[pd_xlate_index]; + + dom->clk = devm_clk_get(dev->parent, name); ++ if (IS_ERR(dom->clk)) { ++ int ret = PTR_ERR(dom->clk); ++ ++ if (ret == -EPROBE_DEFER) ++ return ret; ++ ++ /* Some domains don't have a clk, so make sure that we ++ * don't deref an error pointer later. ++ */ ++ dom->clk = NULL; ++ } + + dom->base.name = name; + dom->base.power_on = bcm2835_power_pd_power_on; +@@ -505,6 +516,8 @@ bcm2835_init_power_domain(struct bcm2835 + pm_genpd_init(&dom->base, NULL, true); + + power->pd_xlate.domains[pd_xlate_index] = &dom->base; ++ ++ return 0; + } + + /** bcm2835_reset_reset - Resets a block that has a reset line in the +@@ -602,7 +615,7 @@ static int bcm2835_power_probe(struct pl + { BCM2835_POWER_DOMAIN_IMAGE_PERI, BCM2835_POWER_DOMAIN_CAM0 }, + { BCM2835_POWER_DOMAIN_IMAGE_PERI, BCM2835_POWER_DOMAIN_CAM1 }, + }; +- int ret, i; ++ int ret = 0, i; + u32 id; + + power = devm_kzalloc(dev, sizeof(*power), GFP_KERNEL); +@@ -629,8 +642,11 @@ static int bcm2835_power_probe(struct pl + + power->pd_xlate.num_domains = ARRAY_SIZE(power_domain_names); + +- for (i = 0; i < ARRAY_SIZE(power_domain_names); i++) +- bcm2835_init_power_domain(power, i, power_domain_names[i]); ++ for (i = 0; i < ARRAY_SIZE(power_domain_names); i++) { ++ ret = bcm2835_init_power_domain(power, i, power_domain_names[i]); ++ if (ret) ++ goto fail; ++ } + + for (i = 0; i < ARRAY_SIZE(domain_deps); i++) { + pm_genpd_add_subdomain(&power->domains[domain_deps[i].parent].base, +@@ -644,12 +660,21 @@ static int bcm2835_power_probe(struct pl + + ret = devm_reset_controller_register(dev, &power->reset); + if (ret) +- return ret; ++ goto fail; + + of_genpd_add_provider_onecell(dev->parent->of_node, &power->pd_xlate); + + dev_info(dev, "Broadcom BCM2835 power domains driver"); + return 0; ++ ++fail: ++ for (i = 0; i < ARRAY_SIZE(power_domain_names); i++) { ++ struct generic_pm_domain *dom = &power->domains[i].base; ++ ++ if (dom->name) ++ pm_genpd_remove(dom); ++ } ++ return ret; + } + + static int bcm2835_power_remove(struct platform_device *pdev) diff --git a/target/linux/brcm2708/patches-4.19/950-0560-bcm2835-pm-Move-bcm2835-watchdog-s-DT-probe-to-an-MF.patch b/target/linux/brcm2708/patches-4.19/950-0560-bcm2835-pm-Move-bcm2835-watchdog-s-DT-probe-to-an-MF.patch deleted file mode 100644 index 8953ef8ec0..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0560-bcm2835-pm-Move-bcm2835-watchdog-s-DT-probe-to-an-MF.patch +++ /dev/null @@ -1,200 +0,0 @@ -From 2dbc6987e9ef3130c9a72422f3f06b8edd06d88a Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Wed, 12 Dec 2018 15:51:47 -0800 -Subject: [PATCH 560/703] bcm2835-pm: Move bcm2835-watchdog's DT probe to an - MFD. - -The PM block that the wdt driver was binding to actually has multiple -features we want to expose (power domains, reset, watchdog). Move the -DT attachment to a MFD driver and make WDT probe against MFD. - -Signed-off-by: Eric Anholt -Reviewed-by: Guenter Roeck -Acked-by: Stefan Wahren -Signed-off-by: Stefan Wahren -(cherry picked from commit 5e6acc3e678ed3db746ab4fb53a980861cd711b6) ---- - drivers/mfd/Makefile | 1 + - drivers/mfd/bcm2835-pm.c | 64 ++++++++++++++++++++++++++++++++++ - drivers/watchdog/bcm2835_wdt.c | 26 +++++--------- - include/linux/mfd/bcm2835-pm.h | 13 +++++++ - 4 files changed, 87 insertions(+), 17 deletions(-) - create mode 100644 drivers/mfd/bcm2835-pm.c - create mode 100644 include/linux/mfd/bcm2835-pm.h - ---- a/drivers/mfd/Makefile -+++ b/drivers/mfd/Makefile -@@ -10,6 +10,7 @@ obj-$(CONFIG_MFD_88PM805) += 88pm805.o 8 - obj-$(CONFIG_MFD_ACT8945A) += act8945a.o - obj-$(CONFIG_MFD_SM501) += sm501.o - obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o -+obj-$(CONFIG_ARCH_BCM2835) += bcm2835-pm.o - obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o - obj-$(CONFIG_MFD_BD9571MWV) += bd9571mwv.o - cros_ec_core-objs := cros_ec.o ---- /dev/null -+++ b/drivers/mfd/bcm2835-pm.c -@@ -0,0 +1,64 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * PM MFD driver for Broadcom BCM2835 -+ * -+ * This driver binds to the PM block and creates the MFD device for -+ * the WDT driver. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static const struct mfd_cell bcm2835_pm_devs[] = { -+ { .name = "bcm2835-wdt" }, -+}; -+ -+static int bcm2835_pm_probe(struct platform_device *pdev) -+{ -+ struct resource *res; -+ struct device *dev = &pdev->dev; -+ struct bcm2835_pm *pm; -+ -+ pm = devm_kzalloc(dev, sizeof(*pm), GFP_KERNEL); -+ if (!pm) -+ return -ENOMEM; -+ platform_set_drvdata(pdev, pm); -+ -+ pm->dev = dev; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ pm->base = devm_ioremap_resource(dev, res); -+ if (IS_ERR(pm->base)) -+ return PTR_ERR(pm->base); -+ -+ return devm_mfd_add_devices(dev, -1, -+ bcm2835_pm_devs, ARRAY_SIZE(bcm2835_pm_devs), -+ NULL, 0, NULL); -+} -+ -+static const struct of_device_id bcm2835_pm_of_match[] = { -+ { .compatible = "brcm,bcm2835-pm-wdt", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm2835_pm_of_match); -+ -+static struct platform_driver bcm2835_pm_driver = { -+ .probe = bcm2835_pm_probe, -+ .driver = { -+ .name = "bcm2835-pm", -+ .of_match_table = bcm2835_pm_of_match, -+ }, -+}; -+module_platform_driver(bcm2835_pm_driver); -+ -+MODULE_AUTHOR("Eric Anholt "); -+MODULE_DESCRIPTION("Driver for Broadcom BCM2835 PM MFD"); -+MODULE_LICENSE("GPL"); ---- a/drivers/watchdog/bcm2835_wdt.c -+++ b/drivers/watchdog/bcm2835_wdt.c -@@ -12,6 +12,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -41,6 +42,8 @@ struct bcm2835_wdt { - spinlock_t lock; - }; - -+static struct bcm2835_wdt *bcm2835_power_off_wdt; -+ - static unsigned int heartbeat; - static bool nowayout = WATCHDOG_NOWAYOUT; - -@@ -163,10 +166,7 @@ static struct watchdog_device bcm2835_wd - */ - static void bcm2835_power_off(void) - { -- struct device_node *np = -- of_find_compatible_node(NULL, NULL, "brcm,bcm2835-pm-wdt"); -- struct platform_device *pdev = of_find_device_by_node(np); -- struct bcm2835_wdt *wdt = platform_get_drvdata(pdev); -+ struct bcm2835_wdt *wdt = bcm2835_power_off_wdt; - - /* Partition 63 tells the firmware that this is a halt */ - __bcm2835_restart(wdt, 63); -@@ -174,7 +174,7 @@ static void bcm2835_power_off(void) - - static int bcm2835_wdt_probe(struct platform_device *pdev) - { -- struct resource *res; -+ struct bcm2835_pm *pm = dev_get_drvdata(pdev->dev.parent); - struct device *dev = &pdev->dev; - struct bcm2835_wdt *wdt; - int err; -@@ -186,10 +186,7 @@ static int bcm2835_wdt_probe(struct plat - - spin_lock_init(&wdt->lock); - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- wdt->base = devm_ioremap_resource(dev, res); -- if (IS_ERR(wdt->base)) -- return PTR_ERR(wdt->base); -+ wdt->base = pm->base; - - watchdog_set_drvdata(&bcm2835_wdt_wdd, wdt); - watchdog_init_timeout(&bcm2835_wdt_wdd, heartbeat, dev); -@@ -216,8 +213,10 @@ static int bcm2835_wdt_probe(struct plat - return err; - } - -- if (pm_power_off == NULL) -+ if (pm_power_off == NULL) { - pm_power_off = bcm2835_power_off; -+ bcm2835_power_off_wdt = wdt; -+ } - - dev_info(dev, "Broadcom BCM2835 watchdog timer"); - return 0; -@@ -231,18 +230,11 @@ static int bcm2835_wdt_remove(struct pla - return 0; - } - --static const struct of_device_id bcm2835_wdt_of_match[] = { -- { .compatible = "brcm,bcm2835-pm-wdt", }, -- {}, --}; --MODULE_DEVICE_TABLE(of, bcm2835_wdt_of_match); -- - static struct platform_driver bcm2835_wdt_driver = { - .probe = bcm2835_wdt_probe, - .remove = bcm2835_wdt_remove, - .driver = { - .name = "bcm2835-wdt", -- .of_match_table = bcm2835_wdt_of_match, - }, - }; - module_platform_driver(bcm2835_wdt_driver); ---- /dev/null -+++ b/include/linux/mfd/bcm2835-pm.h -@@ -0,0 +1,13 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ -+ -+#ifndef BCM2835_MFD_PM_H -+#define BCM2835_MFD_PM_H -+ -+#include -+ -+struct bcm2835_pm { -+ struct device *dev; -+ void __iomem *base; -+}; -+ -+#endif /* BCM2835_MFD_PM_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0560-soc-bcm-bcm2835-pm-Add-support-for-2711.patch b/target/linux/brcm2708/patches-4.19/950-0560-soc-bcm-bcm2835-pm-Add-support-for-2711.patch new file mode 100644 index 0000000000..82e714103e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0560-soc-bcm-bcm2835-pm-Add-support-for-2711.patch @@ -0,0 +1,102 @@ +From d3c6eea95890c539b24ae16bd508f3b631985516 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Fri, 11 Jan 2019 17:31:07 -0800 +Subject: [PATCH 560/725] soc: bcm: bcm2835-pm: Add support for 2711. + +Without the actual power management part any more, there's a lot less +to set up for V3D. We just need to clear the RSTN field for the power +domain, and expose the reset controller for toggling it again. + +This is definitely incomplete -- the old ISP and H264 is in the old +bridge, but since we have no consumers of it I've just done the +minimum to get V3D working. + +Signed-off-by: Eric Anholt +--- + drivers/mfd/bcm2835-pm.c | 11 +++++++++++ + drivers/soc/bcm/bcm2835-power.c | 22 ++++++++++++++++++++++ + include/linux/mfd/bcm2835-pm.h | 1 + + 3 files changed, 34 insertions(+) + +--- a/drivers/mfd/bcm2835-pm.c ++++ b/drivers/mfd/bcm2835-pm.c +@@ -50,6 +50,17 @@ static int bcm2835_pm_probe(struct platf + if (ret) + return ret; + ++ /* Map the ARGON ASB regs if present. */ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 2); ++ if (res) { ++ pm->arg_asb = devm_ioremap_resource(dev, res); ++ if (IS_ERR(pm->arg_asb)) { ++ dev_err(dev, "Failed to map ARGON ASB: %ld\n", ++ PTR_ERR(pm->arg_asb)); ++ return PTR_ERR(pm->arg_asb); ++ } ++ } ++ + /* We'll use the presence of the AXI ASB regs in the + * bcm2835-pm binding as the key for whether we can reference + * the full PM register range and support power domains. +--- a/drivers/soc/bcm/bcm2835-power.c ++++ b/drivers/soc/bcm/bcm2835-power.c +@@ -143,6 +143,8 @@ struct bcm2835_power { + /* AXI Async bridge registers. */ + void __iomem *asb; + ++ bool is_2711; ++ + struct genpd_onecell_data pd_xlate; + struct bcm2835_power_domain domains[BCM2835_POWER_DOMAIN_COUNT]; + struct reset_controller_dev reset; +@@ -192,6 +194,10 @@ static int bcm2835_power_power_off(struc + { + struct bcm2835_power *power = pd->power; + ++ /* 2711 has no power domains above the reset controller. */ ++ if (power->is_2711) ++ return 0; ++ + /* Enable functional isolation */ + PM_WRITE(pm_reg, PM_READ(pm_reg) & ~PM_ISFUNC); + +@@ -213,6 +219,10 @@ static int bcm2835_power_power_on(struct + int inrush; + bool powok; + ++ /* 2711 has no power domains above the reset controller. */ ++ if (power->is_2711) ++ return 0; ++ + /* If it was already powered on by the fw, leave it that way. */ + if (PM_READ(pm_reg) & PM_POWUP) + return 0; +@@ -627,6 +637,18 @@ static int bcm2835_power_probe(struct pl + power->base = pm->base; + power->asb = pm->asb; + ++ /* 2711 hack: the new ARGON ASB took over V3D, which is our ++ * only consumer of this driver so far. The old ASB seems to ++ * still be present with ISP and H264 bits but no V3D, but I ++ * don't know if that's real or not. The V3D is in the same ++ * place in the new ASB as the old one, so just poke the new ++ * one for now. ++ */ ++ if (pm->arg_asb) { ++ power->asb = pm->arg_asb; ++ power->is_2711 = true; ++ } ++ + id = ASB_READ(ASB_AXI_BRDG_ID); + if (id != 0x62726467 /* "BRDG" */) { + dev_err(dev, "ASB register ID returned 0x%08x\n", id); +--- a/include/linux/mfd/bcm2835-pm.h ++++ b/include/linux/mfd/bcm2835-pm.h +@@ -9,6 +9,7 @@ struct bcm2835_pm { + struct device *dev; + void __iomem *base; + void __iomem *asb; ++ void __iomem *arg_asb; + }; + + #endif /* BCM2835_MFD_PM_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0561-drm-expand-drm_syncobj_find_fence-to-support-timelin.patch b/target/linux/brcm2708/patches-4.19/950-0561-drm-expand-drm_syncobj_find_fence-to-support-timelin.patch new file mode 100644 index 0000000000..297d2b7217 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0561-drm-expand-drm_syncobj_find_fence-to-support-timelin.patch @@ -0,0 +1,104 @@ +From f4645265e2dffcbc729a510aed85637b5519d8af Mon Sep 17 00:00:00 2001 +From: Chunming Zhou +Date: Thu, 30 Aug 2018 14:48:29 +0800 +Subject: [PATCH 561/725] drm: expand drm_syncobj_find_fence to support + timeline point v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +we can fetch timeline point fence after expanded. +v2: The parameter fence is the result of the function and should come last. + +Signed-off-by: Chunming Zhou +Reviewed-by: Christian König +Signed-off-by: Christian König +Link: https://patchwork.freedesktop.org/patch/246541/ +(cherry picked from commit 0a6730ea27b68c7ac4171c29a816c29d26a9637a) +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- + drivers/gpu/drm/drm_syncobj.c | 5 +++-- + drivers/gpu/drm/v3d/v3d_gem.c | 4 ++-- + drivers/gpu/drm/vc4/vc4_gem.c | 2 +- + include/drm/drm_syncobj.h | 2 +- + 5 files changed, 8 insertions(+), 7 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +@@ -1105,7 +1105,7 @@ static int amdgpu_syncobj_lookup_and_add + { + int r; + struct dma_fence *fence; +- r = drm_syncobj_find_fence(p->filp, handle, &fence); ++ r = drm_syncobj_find_fence(p->filp, handle, 0, &fence); + if (r) + return r; + +--- a/drivers/gpu/drm/drm_syncobj.c ++++ b/drivers/gpu/drm/drm_syncobj.c +@@ -235,6 +235,7 @@ static int drm_syncobj_assign_null_handl + * drm_syncobj_find_fence - lookup and reference the fence in a sync object + * @file_private: drm file private pointer + * @handle: sync object handle to lookup. ++ * @point: timeline point + * @fence: out parameter for the fence + * + * This is just a convenience function that combines drm_syncobj_find() and +@@ -245,7 +246,7 @@ static int drm_syncobj_assign_null_handl + * dma_fence_put(). + */ + int drm_syncobj_find_fence(struct drm_file *file_private, +- u32 handle, ++ u32 handle, u64 point, + struct dma_fence **fence) + { + struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle); +@@ -516,7 +517,7 @@ static int drm_syncobj_export_sync_file( + if (fd < 0) + return fd; + +- ret = drm_syncobj_find_fence(file_private, handle, &fence); ++ ret = drm_syncobj_find_fence(file_private, handle, 0, &fence); + if (ret) + goto err_put_fd; + +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -521,12 +521,12 @@ v3d_submit_cl_ioctl(struct drm_device *d + kref_init(&exec->refcount); + + ret = drm_syncobj_find_fence(file_priv, args->in_sync_bcl, +- &exec->bin.in_fence); ++ 0, &exec->bin.in_fence); + if (ret == -EINVAL) + goto fail; + + ret = drm_syncobj_find_fence(file_priv, args->in_sync_rcl, +- &exec->render.in_fence); ++ 0, &exec->render.in_fence); + if (ret == -EINVAL) + goto fail; + +--- a/drivers/gpu/drm/vc4/vc4_gem.c ++++ b/drivers/gpu/drm/vc4/vc4_gem.c +@@ -1173,7 +1173,7 @@ vc4_submit_cl_ioctl(struct drm_device *d + + if (args->in_sync) { + ret = drm_syncobj_find_fence(file_priv, args->in_sync, +- &in_fence); ++ 0, &in_fence); + if (ret) + goto fail; + +--- a/include/drm/drm_syncobj.h ++++ b/include/drm/drm_syncobj.h +@@ -139,7 +139,7 @@ void drm_syncobj_remove_callback(struct + void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, + struct dma_fence *fence); + int drm_syncobj_find_fence(struct drm_file *file_private, +- u32 handle, ++ u32 handle, u64 point, + struct dma_fence **fence); + void drm_syncobj_free(struct kref *kref); + int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags, diff --git a/target/linux/brcm2708/patches-4.19/950-0561-soc-bcm-bcm2835-pm-Add-support-for-power-domains-und.patch b/target/linux/brcm2708/patches-4.19/950-0561-soc-bcm-bcm2835-pm-Add-support-for-power-domains-und.patch deleted file mode 100644 index db6a8d0c6e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0561-soc-bcm-bcm2835-pm-Add-support-for-power-domains-und.patch +++ /dev/null @@ -1,825 +0,0 @@ -From c3005e0dbe1f7f6d93833d5a43b12866873a312f Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Wed, 12 Dec 2018 15:51:48 -0800 -Subject: [PATCH 561/703] soc: bcm: bcm2835-pm: Add support for power domains - under a new binding. - -This provides a free software alternative to raspberrypi-power.c's -firmware calls to manage power domains. It also exposes a reset line, -where previously the vc4 driver had to try to force power off the -domain in order to trigger a reset. - -Signed-off-by: Eric Anholt -Acked-by: Rob Herring -Acked-by: Stefan Wahren -Signed-off-by: Stefan Wahren -(cherry picked from commit 670c672608a1ffcbc7ac0f872734843593bb8b15) ---- - drivers/mfd/bcm2835-pm.c | 36 +- - drivers/soc/bcm/Kconfig | 11 + - drivers/soc/bcm/Makefile | 1 + - drivers/soc/bcm/bcm2835-power.c | 661 +++++++++++++++++++++++++++ - include/dt-bindings/soc/bcm2835-pm.h | 28 ++ - include/linux/mfd/bcm2835-pm.h | 1 + - 6 files changed, 734 insertions(+), 4 deletions(-) - create mode 100644 drivers/soc/bcm/bcm2835-power.c - create mode 100644 include/dt-bindings/soc/bcm2835-pm.h - ---- a/drivers/mfd/bcm2835-pm.c -+++ b/drivers/mfd/bcm2835-pm.c -@@ -3,7 +3,7 @@ - * PM MFD driver for Broadcom BCM2835 - * - * This driver binds to the PM block and creates the MFD device for -- * the WDT driver. -+ * the WDT and power drivers. - */ - - #include -@@ -21,11 +21,16 @@ static const struct mfd_cell bcm2835_pm_ - { .name = "bcm2835-wdt" }, - }; - -+static const struct mfd_cell bcm2835_power_devs[] = { -+ { .name = "bcm2835-power" }, -+}; -+ - static int bcm2835_pm_probe(struct platform_device *pdev) - { - struct resource *res; - struct device *dev = &pdev->dev; - struct bcm2835_pm *pm; -+ int ret; - - pm = devm_kzalloc(dev, sizeof(*pm), GFP_KERNEL); - if (!pm) -@@ -39,13 +44,36 @@ static int bcm2835_pm_probe(struct platf - if (IS_ERR(pm->base)) - return PTR_ERR(pm->base); - -- return devm_mfd_add_devices(dev, -1, -- bcm2835_pm_devs, ARRAY_SIZE(bcm2835_pm_devs), -- NULL, 0, NULL); -+ ret = devm_mfd_add_devices(dev, -1, -+ bcm2835_pm_devs, ARRAY_SIZE(bcm2835_pm_devs), -+ NULL, 0, NULL); -+ if (ret) -+ return ret; -+ -+ /* We'll use the presence of the AXI ASB regs in the -+ * bcm2835-pm binding as the key for whether we can reference -+ * the full PM register range and support power domains. -+ */ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ if (res) { -+ pm->asb = devm_ioremap_resource(dev, res); -+ if (IS_ERR(pm->asb)) -+ return PTR_ERR(pm->asb); -+ -+ ret = devm_mfd_add_devices(dev, -1, -+ bcm2835_power_devs, -+ ARRAY_SIZE(bcm2835_power_devs), -+ NULL, 0, NULL); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; - } - - static const struct of_device_id bcm2835_pm_of_match[] = { - { .compatible = "brcm,bcm2835-pm-wdt", }, -+ { .compatible = "brcm,bcm2835-pm", }, - {}, - }; - MODULE_DEVICE_TABLE(of, bcm2835_pm_of_match); ---- a/drivers/soc/bcm/Kconfig -+++ b/drivers/soc/bcm/Kconfig -@@ -1,5 +1,16 @@ - menu "Broadcom SoC drivers" - -+config BCM2835_POWER -+ bool "BCM2835 power domain driver" -+ depends on ARCH_BCM2835 || (COMPILE_TEST && OF) -+ select PM_GENERIC_DOMAINS if PM -+ select RESET_CONTROLLER -+ help -+ This enables support for the BCM2835 power domains and reset -+ controller. Any usage of power domains by the Raspberry Pi -+ firmware means that Linux usage of the same power domain -+ must be accessed using the RASPBERRYPI_POWER driver -+ - config RASPBERRYPI_POWER - bool "Raspberry Pi power domain driver" - depends on ARCH_BCM2835 || (COMPILE_TEST && OF) ---- a/drivers/soc/bcm/Makefile -+++ b/drivers/soc/bcm/Makefile -@@ -1,2 +1,3 @@ -+obj-$(CONFIG_BCM2835_POWER) += bcm2835-power.o - obj-$(CONFIG_RASPBERRYPI_POWER) += raspberrypi-power.o - obj-$(CONFIG_SOC_BRCMSTB) += brcmstb/ ---- /dev/null -+++ b/drivers/soc/bcm/bcm2835-power.c -@@ -0,0 +1,661 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Power domain driver for Broadcom BCM2835 -+ * -+ * Copyright (C) 2018 Broadcom -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define PM_GNRIC 0x00 -+#define PM_AUDIO 0x04 -+#define PM_STATUS 0x18 -+#define PM_RSTC 0x1c -+#define PM_RSTS 0x20 -+#define PM_WDOG 0x24 -+#define PM_PADS0 0x28 -+#define PM_PADS2 0x2c -+#define PM_PADS3 0x30 -+#define PM_PADS4 0x34 -+#define PM_PADS5 0x38 -+#define PM_PADS6 0x3c -+#define PM_CAM0 0x44 -+#define PM_CAM0_LDOHPEN BIT(2) -+#define PM_CAM0_LDOLPEN BIT(1) -+#define PM_CAM0_CTRLEN BIT(0) -+ -+#define PM_CAM1 0x48 -+#define PM_CAM1_LDOHPEN BIT(2) -+#define PM_CAM1_LDOLPEN BIT(1) -+#define PM_CAM1_CTRLEN BIT(0) -+ -+#define PM_CCP2TX 0x4c -+#define PM_CCP2TX_LDOEN BIT(1) -+#define PM_CCP2TX_CTRLEN BIT(0) -+ -+#define PM_DSI0 0x50 -+#define PM_DSI0_LDOHPEN BIT(2) -+#define PM_DSI0_LDOLPEN BIT(1) -+#define PM_DSI0_CTRLEN BIT(0) -+ -+#define PM_DSI1 0x54 -+#define PM_DSI1_LDOHPEN BIT(2) -+#define PM_DSI1_LDOLPEN BIT(1) -+#define PM_DSI1_CTRLEN BIT(0) -+ -+#define PM_HDMI 0x58 -+#define PM_HDMI_RSTDR BIT(19) -+#define PM_HDMI_LDOPD BIT(1) -+#define PM_HDMI_CTRLEN BIT(0) -+ -+#define PM_USB 0x5c -+/* The power gates must be enabled with this bit before enabling the LDO in the -+ * USB block. -+ */ -+#define PM_USB_CTRLEN BIT(0) -+ -+#define PM_PXLDO 0x60 -+#define PM_PXBG 0x64 -+#define PM_DFT 0x68 -+#define PM_SMPS 0x6c -+#define PM_XOSC 0x70 -+#define PM_SPAREW 0x74 -+#define PM_SPARER 0x78 -+#define PM_AVS_RSTDR 0x7c -+#define PM_AVS_STAT 0x80 -+#define PM_AVS_EVENT 0x84 -+#define PM_AVS_INTEN 0x88 -+#define PM_DUMMY 0xfc -+ -+#define PM_IMAGE 0x108 -+#define PM_GRAFX 0x10c -+#define PM_PROC 0x110 -+#define PM_ENAB BIT(12) -+#define PM_ISPRSTN BIT(8) -+#define PM_H264RSTN BIT(7) -+#define PM_PERIRSTN BIT(6) -+#define PM_V3DRSTN BIT(6) -+#define PM_ISFUNC BIT(5) -+#define PM_MRDONE BIT(4) -+#define PM_MEMREP BIT(3) -+#define PM_ISPOW BIT(2) -+#define PM_POWOK BIT(1) -+#define PM_POWUP BIT(0) -+#define PM_INRUSH_SHIFT 13 -+#define PM_INRUSH_3_5_MA 0 -+#define PM_INRUSH_5_MA 1 -+#define PM_INRUSH_10_MA 2 -+#define PM_INRUSH_20_MA 3 -+#define PM_INRUSH_MASK (3 << PM_INRUSH_SHIFT) -+ -+#define PM_PASSWORD 0x5a000000 -+ -+#define PM_WDOG_TIME_SET 0x000fffff -+#define PM_RSTC_WRCFG_CLR 0xffffffcf -+#define PM_RSTS_HADWRH_SET 0x00000040 -+#define PM_RSTC_WRCFG_SET 0x00000030 -+#define PM_RSTC_WRCFG_FULL_RESET 0x00000020 -+#define PM_RSTC_RESET 0x00000102 -+ -+#define PM_READ(reg) readl(power->base + (reg)) -+#define PM_WRITE(reg, val) writel(PM_PASSWORD | (val), power->base + (reg)) -+ -+#define ASB_BRDG_VERSION 0x00 -+#define ASB_CPR_CTRL 0x04 -+ -+#define ASB_V3D_S_CTRL 0x08 -+#define ASB_V3D_M_CTRL 0x0c -+#define ASB_ISP_S_CTRL 0x10 -+#define ASB_ISP_M_CTRL 0x14 -+#define ASB_H264_S_CTRL 0x18 -+#define ASB_H264_M_CTRL 0x1c -+ -+#define ASB_REQ_STOP BIT(0) -+#define ASB_ACK BIT(1) -+#define ASB_EMPTY BIT(2) -+#define ASB_FULL BIT(3) -+ -+#define ASB_AXI_BRDG_ID 0x20 -+ -+#define ASB_READ(reg) readl(power->asb + (reg)) -+#define ASB_WRITE(reg, val) writel(PM_PASSWORD | (val), power->asb + (reg)) -+ -+struct bcm2835_power_domain { -+ struct generic_pm_domain base; -+ struct bcm2835_power *power; -+ u32 domain; -+ struct clk *clk; -+}; -+ -+struct bcm2835_power { -+ struct device *dev; -+ /* PM registers. */ -+ void __iomem *base; -+ /* AXI Async bridge registers. */ -+ void __iomem *asb; -+ -+ struct genpd_onecell_data pd_xlate; -+ struct bcm2835_power_domain domains[BCM2835_POWER_DOMAIN_COUNT]; -+ struct reset_controller_dev reset; -+}; -+ -+static int bcm2835_asb_enable(struct bcm2835_power *power, u32 reg) -+{ -+ u64 start = ktime_get_ns(); -+ -+ /* Enable the module's async AXI bridges. */ -+ ASB_WRITE(reg, ASB_READ(reg) & ~ASB_REQ_STOP); -+ while (ASB_READ(reg) & ASB_ACK) { -+ cpu_relax(); -+ if (ktime_get_ns() - start >= 1000) -+ return -ETIMEDOUT; -+ } -+ -+ return 0; -+} -+ -+static int bcm2835_asb_disable(struct bcm2835_power *power, u32 reg) -+{ -+ u64 start = ktime_get_ns(); -+ -+ /* Enable the module's async AXI bridges. */ -+ ASB_WRITE(reg, ASB_READ(reg) | ASB_REQ_STOP); -+ while (!(ASB_READ(reg) & ASB_ACK)) { -+ cpu_relax(); -+ if (ktime_get_ns() - start >= 1000) -+ return -ETIMEDOUT; -+ } -+ -+ return 0; -+} -+ -+static int bcm2835_power_power_off(struct bcm2835_power_domain *pd, u32 pm_reg) -+{ -+ struct bcm2835_power *power = pd->power; -+ -+ /* Enable functional isolation */ -+ PM_WRITE(pm_reg, PM_READ(pm_reg) & ~PM_ISFUNC); -+ -+ /* Enable electrical isolation */ -+ PM_WRITE(pm_reg, PM_READ(pm_reg) & ~PM_ISPOW); -+ -+ /* Open the power switches. */ -+ PM_WRITE(pm_reg, PM_READ(pm_reg) & ~PM_POWUP); -+ -+ return 0; -+} -+ -+static int bcm2835_power_power_on(struct bcm2835_power_domain *pd, u32 pm_reg) -+{ -+ struct bcm2835_power *power = pd->power; -+ struct device *dev = power->dev; -+ u64 start; -+ int ret; -+ int inrush; -+ bool powok; -+ -+ /* If it was already powered on by the fw, leave it that way. */ -+ if (PM_READ(pm_reg) & PM_POWUP) -+ return 0; -+ -+ /* Enable power. Allowing too much current at once may result -+ * in POWOK never getting set, so start low and ramp it up as -+ * necessary to succeed. -+ */ -+ powok = false; -+ for (inrush = PM_INRUSH_3_5_MA; inrush <= PM_INRUSH_20_MA; inrush++) { -+ PM_WRITE(pm_reg, -+ (PM_READ(pm_reg) & ~PM_INRUSH_MASK) | -+ (inrush << PM_INRUSH_SHIFT) | -+ PM_POWUP); -+ -+ start = ktime_get_ns(); -+ while (!(powok = !!(PM_READ(pm_reg) & PM_POWOK))) { -+ cpu_relax(); -+ if (ktime_get_ns() - start >= 3000) -+ break; -+ } -+ } -+ if (!powok) { -+ dev_err(dev, "Timeout waiting for %s power OK\n", -+ pd->base.name); -+ ret = -ETIMEDOUT; -+ goto err_disable_powup; -+ } -+ -+ /* Disable electrical isolation */ -+ PM_WRITE(pm_reg, PM_READ(pm_reg) | PM_ISPOW); -+ -+ /* Repair memory */ -+ PM_WRITE(pm_reg, PM_READ(pm_reg) | PM_MEMREP); -+ start = ktime_get_ns(); -+ while (!(PM_READ(pm_reg) & PM_MRDONE)) { -+ cpu_relax(); -+ if (ktime_get_ns() - start >= 1000) { -+ dev_err(dev, "Timeout waiting for %s memory repair\n", -+ pd->base.name); -+ ret = -ETIMEDOUT; -+ goto err_disable_ispow; -+ } -+ } -+ -+ /* Disable functional isolation */ -+ PM_WRITE(pm_reg, PM_READ(pm_reg) | PM_ISFUNC); -+ -+ return 0; -+ -+err_disable_ispow: -+ PM_WRITE(pm_reg, PM_READ(pm_reg) & ~PM_ISPOW); -+err_disable_powup: -+ PM_WRITE(pm_reg, PM_READ(pm_reg) & ~(PM_POWUP | PM_INRUSH_MASK)); -+ return ret; -+} -+ -+static int bcm2835_asb_power_on(struct bcm2835_power_domain *pd, -+ u32 pm_reg, -+ u32 asb_m_reg, -+ u32 asb_s_reg, -+ u32 reset_flags) -+{ -+ struct bcm2835_power *power = pd->power; -+ int ret; -+ -+ ret = clk_prepare_enable(pd->clk); -+ if (ret) { -+ dev_err(power->dev, "Failed to enable clock for %s\n", -+ pd->base.name); -+ return ret; -+ } -+ -+ /* Wait 32 clocks for reset to propagate, 1 us will be enough */ -+ udelay(1); -+ -+ clk_disable_unprepare(pd->clk); -+ -+ /* Deassert the resets. */ -+ PM_WRITE(pm_reg, PM_READ(pm_reg) | reset_flags); -+ -+ ret = clk_prepare_enable(pd->clk); -+ if (ret) { -+ dev_err(power->dev, "Failed to enable clock for %s\n", -+ pd->base.name); -+ goto err_enable_resets; -+ } -+ -+ ret = bcm2835_asb_enable(power, asb_m_reg); -+ if (ret) { -+ dev_err(power->dev, "Failed to enable ASB master for %s\n", -+ pd->base.name); -+ goto err_disable_clk; -+ } -+ ret = bcm2835_asb_enable(power, asb_s_reg); -+ if (ret) { -+ dev_err(power->dev, "Failed to enable ASB slave for %s\n", -+ pd->base.name); -+ goto err_disable_asb_master; -+ } -+ -+ return 0; -+ -+err_disable_asb_master: -+ bcm2835_asb_disable(power, asb_m_reg); -+err_disable_clk: -+ clk_disable_unprepare(pd->clk); -+err_enable_resets: -+ PM_WRITE(pm_reg, PM_READ(pm_reg) & ~reset_flags); -+ return ret; -+} -+ -+static int bcm2835_asb_power_off(struct bcm2835_power_domain *pd, -+ u32 pm_reg, -+ u32 asb_m_reg, -+ u32 asb_s_reg, -+ u32 reset_flags) -+{ -+ struct bcm2835_power *power = pd->power; -+ int ret; -+ -+ ret = bcm2835_asb_disable(power, asb_s_reg); -+ if (ret) { -+ dev_warn(power->dev, "Failed to disable ASB slave for %s\n", -+ pd->base.name); -+ return ret; -+ } -+ ret = bcm2835_asb_disable(power, asb_m_reg); -+ if (ret) { -+ dev_warn(power->dev, "Failed to disable ASB master for %s\n", -+ pd->base.name); -+ bcm2835_asb_enable(power, asb_s_reg); -+ return ret; -+ } -+ -+ clk_disable_unprepare(pd->clk); -+ -+ /* Assert the resets. */ -+ PM_WRITE(pm_reg, PM_READ(pm_reg) & ~reset_flags); -+ -+ return 0; -+} -+ -+static int bcm2835_power_pd_power_on(struct generic_pm_domain *domain) -+{ -+ struct bcm2835_power_domain *pd = -+ container_of(domain, struct bcm2835_power_domain, base); -+ struct bcm2835_power *power = pd->power; -+ -+ switch (pd->domain) { -+ case BCM2835_POWER_DOMAIN_GRAFX: -+ return bcm2835_power_power_on(pd, PM_GRAFX); -+ -+ case BCM2835_POWER_DOMAIN_GRAFX_V3D: -+ return bcm2835_asb_power_on(pd, PM_GRAFX, -+ ASB_V3D_M_CTRL, ASB_V3D_S_CTRL, -+ PM_V3DRSTN); -+ -+ case BCM2835_POWER_DOMAIN_IMAGE: -+ return bcm2835_power_power_on(pd, PM_IMAGE); -+ -+ case BCM2835_POWER_DOMAIN_IMAGE_PERI: -+ return bcm2835_asb_power_on(pd, PM_IMAGE, -+ 0, 0, -+ PM_PERIRSTN); -+ -+ case BCM2835_POWER_DOMAIN_IMAGE_ISP: -+ return bcm2835_asb_power_on(pd, PM_IMAGE, -+ ASB_ISP_M_CTRL, ASB_ISP_S_CTRL, -+ PM_ISPRSTN); -+ -+ case BCM2835_POWER_DOMAIN_IMAGE_H264: -+ return bcm2835_asb_power_on(pd, PM_IMAGE, -+ ASB_H264_M_CTRL, ASB_H264_S_CTRL, -+ PM_H264RSTN); -+ -+ case BCM2835_POWER_DOMAIN_USB: -+ PM_WRITE(PM_USB, PM_USB_CTRLEN); -+ return 0; -+ -+ case BCM2835_POWER_DOMAIN_DSI0: -+ PM_WRITE(PM_DSI0, PM_DSI0_CTRLEN); -+ PM_WRITE(PM_DSI0, PM_DSI0_CTRLEN | PM_DSI0_LDOHPEN); -+ return 0; -+ -+ case BCM2835_POWER_DOMAIN_DSI1: -+ PM_WRITE(PM_DSI1, PM_DSI1_CTRLEN); -+ PM_WRITE(PM_DSI1, PM_DSI1_CTRLEN | PM_DSI1_LDOHPEN); -+ return 0; -+ -+ case BCM2835_POWER_DOMAIN_CCP2TX: -+ PM_WRITE(PM_CCP2TX, PM_CCP2TX_CTRLEN); -+ PM_WRITE(PM_CCP2TX, PM_CCP2TX_CTRLEN | PM_CCP2TX_LDOEN); -+ return 0; -+ -+ case BCM2835_POWER_DOMAIN_HDMI: -+ PM_WRITE(PM_HDMI, PM_READ(PM_HDMI) | PM_HDMI_RSTDR); -+ PM_WRITE(PM_HDMI, PM_READ(PM_HDMI) | PM_HDMI_CTRLEN); -+ PM_WRITE(PM_HDMI, PM_READ(PM_HDMI) & ~PM_HDMI_LDOPD); -+ usleep_range(100, 200); -+ PM_WRITE(PM_HDMI, PM_READ(PM_HDMI) & ~PM_HDMI_RSTDR); -+ return 0; -+ -+ default: -+ dev_err(power->dev, "Invalid domain %d\n", pd->domain); -+ return -EINVAL; -+ } -+} -+ -+static int bcm2835_power_pd_power_off(struct generic_pm_domain *domain) -+{ -+ struct bcm2835_power_domain *pd = -+ container_of(domain, struct bcm2835_power_domain, base); -+ struct bcm2835_power *power = pd->power; -+ -+ switch (pd->domain) { -+ case BCM2835_POWER_DOMAIN_GRAFX: -+ return bcm2835_power_power_off(pd, PM_GRAFX); -+ -+ case BCM2835_POWER_DOMAIN_GRAFX_V3D: -+ return bcm2835_asb_power_off(pd, PM_GRAFX, -+ ASB_V3D_M_CTRL, ASB_V3D_S_CTRL, -+ PM_V3DRSTN); -+ -+ case BCM2835_POWER_DOMAIN_IMAGE: -+ return bcm2835_power_power_off(pd, PM_IMAGE); -+ -+ case BCM2835_POWER_DOMAIN_IMAGE_PERI: -+ return bcm2835_asb_power_off(pd, PM_IMAGE, -+ 0, 0, -+ PM_PERIRSTN); -+ -+ case BCM2835_POWER_DOMAIN_IMAGE_ISP: -+ return bcm2835_asb_power_off(pd, PM_IMAGE, -+ ASB_ISP_M_CTRL, ASB_ISP_S_CTRL, -+ PM_ISPRSTN); -+ -+ case BCM2835_POWER_DOMAIN_IMAGE_H264: -+ return bcm2835_asb_power_off(pd, PM_IMAGE, -+ ASB_H264_M_CTRL, ASB_H264_S_CTRL, -+ PM_H264RSTN); -+ -+ case BCM2835_POWER_DOMAIN_USB: -+ PM_WRITE(PM_USB, 0); -+ return 0; -+ -+ case BCM2835_POWER_DOMAIN_DSI0: -+ PM_WRITE(PM_DSI0, PM_DSI0_CTRLEN); -+ PM_WRITE(PM_DSI0, 0); -+ return 0; -+ -+ case BCM2835_POWER_DOMAIN_DSI1: -+ PM_WRITE(PM_DSI1, PM_DSI1_CTRLEN); -+ PM_WRITE(PM_DSI1, 0); -+ return 0; -+ -+ case BCM2835_POWER_DOMAIN_CCP2TX: -+ PM_WRITE(PM_CCP2TX, PM_CCP2TX_CTRLEN); -+ PM_WRITE(PM_CCP2TX, 0); -+ return 0; -+ -+ case BCM2835_POWER_DOMAIN_HDMI: -+ PM_WRITE(PM_HDMI, PM_READ(PM_HDMI) | PM_HDMI_LDOPD); -+ PM_WRITE(PM_HDMI, PM_READ(PM_HDMI) & ~PM_HDMI_CTRLEN); -+ return 0; -+ -+ default: -+ dev_err(power->dev, "Invalid domain %d\n", pd->domain); -+ return -EINVAL; -+ } -+} -+ -+static void -+bcm2835_init_power_domain(struct bcm2835_power *power, -+ int pd_xlate_index, const char *name) -+{ -+ struct device *dev = power->dev; -+ struct bcm2835_power_domain *dom = &power->domains[pd_xlate_index]; -+ -+ dom->clk = devm_clk_get(dev->parent, name); -+ -+ dom->base.name = name; -+ dom->base.power_on = bcm2835_power_pd_power_on; -+ dom->base.power_off = bcm2835_power_pd_power_off; -+ -+ dom->domain = pd_xlate_index; -+ dom->power = power; -+ -+ /* XXX: on/off at boot? */ -+ pm_genpd_init(&dom->base, NULL, true); -+ -+ power->pd_xlate.domains[pd_xlate_index] = &dom->base; -+} -+ -+/** bcm2835_reset_reset - Resets a block that has a reset line in the -+ * PM block. -+ * -+ * The consumer of the reset controller must have the power domain up -+ * -- there's no reset ability with the power domain down. To reset -+ * the sub-block, we just disable its access to memory through the -+ * ASB, reset, and re-enable. -+ */ -+static int bcm2835_reset_reset(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ struct bcm2835_power *power = container_of(rcdev, struct bcm2835_power, -+ reset); -+ struct bcm2835_power_domain *pd; -+ int ret; -+ -+ switch (id) { -+ case BCM2835_RESET_V3D: -+ pd = &power->domains[BCM2835_POWER_DOMAIN_GRAFX_V3D]; -+ break; -+ case BCM2835_RESET_H264: -+ pd = &power->domains[BCM2835_POWER_DOMAIN_IMAGE_H264]; -+ break; -+ case BCM2835_RESET_ISP: -+ pd = &power->domains[BCM2835_POWER_DOMAIN_IMAGE_ISP]; -+ break; -+ default: -+ dev_err(power->dev, "Bad reset id %ld\n", id); -+ return -EINVAL; -+ } -+ -+ ret = bcm2835_power_pd_power_off(&pd->base); -+ if (ret) -+ return ret; -+ -+ return bcm2835_power_pd_power_on(&pd->base); -+} -+ -+static int bcm2835_reset_status(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ struct bcm2835_power *power = container_of(rcdev, struct bcm2835_power, -+ reset); -+ -+ switch (id) { -+ case BCM2835_RESET_V3D: -+ return !PM_READ(PM_GRAFX & PM_V3DRSTN); -+ case BCM2835_RESET_H264: -+ return !PM_READ(PM_IMAGE & PM_H264RSTN); -+ case BCM2835_RESET_ISP: -+ return !PM_READ(PM_IMAGE & PM_ISPRSTN); -+ default: -+ return -EINVAL; -+ } -+} -+ -+const struct reset_control_ops bcm2835_reset_ops = { -+ .reset = bcm2835_reset_reset, -+ .status = bcm2835_reset_status, -+}; -+ -+static const char *const power_domain_names[] = { -+ [BCM2835_POWER_DOMAIN_GRAFX] = "grafx", -+ [BCM2835_POWER_DOMAIN_GRAFX_V3D] = "v3d", -+ -+ [BCM2835_POWER_DOMAIN_IMAGE] = "image", -+ [BCM2835_POWER_DOMAIN_IMAGE_PERI] = "peri_image", -+ [BCM2835_POWER_DOMAIN_IMAGE_H264] = "h264", -+ [BCM2835_POWER_DOMAIN_IMAGE_ISP] = "isp", -+ -+ [BCM2835_POWER_DOMAIN_USB] = "usb", -+ [BCM2835_POWER_DOMAIN_DSI0] = "dsi0", -+ [BCM2835_POWER_DOMAIN_DSI1] = "dsi1", -+ [BCM2835_POWER_DOMAIN_CAM0] = "cam0", -+ [BCM2835_POWER_DOMAIN_CAM1] = "cam1", -+ [BCM2835_POWER_DOMAIN_CCP2TX] = "ccp2tx", -+ [BCM2835_POWER_DOMAIN_HDMI] = "hdmi", -+}; -+ -+static int bcm2835_power_probe(struct platform_device *pdev) -+{ -+ struct bcm2835_pm *pm = dev_get_drvdata(pdev->dev.parent); -+ struct device *dev = &pdev->dev; -+ struct bcm2835_power *power; -+ static const struct { -+ int parent, child; -+ } domain_deps[] = { -+ { BCM2835_POWER_DOMAIN_GRAFX, BCM2835_POWER_DOMAIN_GRAFX_V3D }, -+ { BCM2835_POWER_DOMAIN_IMAGE, BCM2835_POWER_DOMAIN_IMAGE_PERI }, -+ { BCM2835_POWER_DOMAIN_IMAGE, BCM2835_POWER_DOMAIN_IMAGE_H264 }, -+ { BCM2835_POWER_DOMAIN_IMAGE, BCM2835_POWER_DOMAIN_IMAGE_ISP }, -+ { BCM2835_POWER_DOMAIN_IMAGE_PERI, BCM2835_POWER_DOMAIN_USB }, -+ { BCM2835_POWER_DOMAIN_IMAGE_PERI, BCM2835_POWER_DOMAIN_CAM0 }, -+ { BCM2835_POWER_DOMAIN_IMAGE_PERI, BCM2835_POWER_DOMAIN_CAM1 }, -+ }; -+ int ret, i; -+ u32 id; -+ -+ power = devm_kzalloc(dev, sizeof(*power), GFP_KERNEL); -+ if (!power) -+ return -ENOMEM; -+ platform_set_drvdata(pdev, power); -+ -+ power->dev = dev; -+ power->base = pm->base; -+ power->asb = pm->asb; -+ -+ id = ASB_READ(ASB_AXI_BRDG_ID); -+ if (id != 0x62726467 /* "BRDG" */) { -+ dev_err(dev, "ASB register ID returned 0x%08x\n", id); -+ return -ENODEV; -+ } -+ -+ power->pd_xlate.domains = devm_kcalloc(dev, -+ ARRAY_SIZE(power_domain_names), -+ sizeof(*power->pd_xlate.domains), -+ GFP_KERNEL); -+ if (!power->pd_xlate.domains) -+ return -ENOMEM; -+ -+ power->pd_xlate.num_domains = ARRAY_SIZE(power_domain_names); -+ -+ for (i = 0; i < ARRAY_SIZE(power_domain_names); i++) -+ bcm2835_init_power_domain(power, i, power_domain_names[i]); -+ -+ for (i = 0; i < ARRAY_SIZE(domain_deps); i++) { -+ pm_genpd_add_subdomain(&power->domains[domain_deps[i].parent].base, -+ &power->domains[domain_deps[i].child].base); -+ } -+ -+ power->reset.owner = THIS_MODULE; -+ power->reset.nr_resets = BCM2835_RESET_COUNT; -+ power->reset.ops = &bcm2835_reset_ops; -+ power->reset.of_node = dev->parent->of_node; -+ -+ ret = devm_reset_controller_register(dev, &power->reset); -+ if (ret) -+ return ret; -+ -+ of_genpd_add_provider_onecell(dev->parent->of_node, &power->pd_xlate); -+ -+ dev_info(dev, "Broadcom BCM2835 power domains driver"); -+ return 0; -+} -+ -+static int bcm2835_power_remove(struct platform_device *pdev) -+{ -+ return 0; -+} -+ -+static struct platform_driver bcm2835_power_driver = { -+ .probe = bcm2835_power_probe, -+ .remove = bcm2835_power_remove, -+ .driver = { -+ .name = "bcm2835-power", -+ }, -+}; -+module_platform_driver(bcm2835_power_driver); -+ -+MODULE_AUTHOR("Eric Anholt "); -+MODULE_DESCRIPTION("Driver for Broadcom BCM2835 PM power domains and reset"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/include/dt-bindings/soc/bcm2835-pm.h -@@ -0,0 +1,28 @@ -+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ -+ -+#ifndef _DT_BINDINGS_ARM_BCM2835_PM_H -+#define _DT_BINDINGS_ARM_BCM2835_PM_H -+ -+#define BCM2835_POWER_DOMAIN_GRAFX 0 -+#define BCM2835_POWER_DOMAIN_GRAFX_V3D 1 -+#define BCM2835_POWER_DOMAIN_IMAGE 2 -+#define BCM2835_POWER_DOMAIN_IMAGE_PERI 3 -+#define BCM2835_POWER_DOMAIN_IMAGE_ISP 4 -+#define BCM2835_POWER_DOMAIN_IMAGE_H264 5 -+#define BCM2835_POWER_DOMAIN_USB 6 -+#define BCM2835_POWER_DOMAIN_DSI0 7 -+#define BCM2835_POWER_DOMAIN_DSI1 8 -+#define BCM2835_POWER_DOMAIN_CAM0 9 -+#define BCM2835_POWER_DOMAIN_CAM1 10 -+#define BCM2835_POWER_DOMAIN_CCP2TX 11 -+#define BCM2835_POWER_DOMAIN_HDMI 12 -+ -+#define BCM2835_POWER_DOMAIN_COUNT 13 -+ -+#define BCM2835_RESET_V3D 0 -+#define BCM2835_RESET_ISP 1 -+#define BCM2835_RESET_H264 2 -+ -+#define BCM2835_RESET_COUNT 3 -+ -+#endif /* _DT_BINDINGS_ARM_BCM2835_PM_H */ ---- a/include/linux/mfd/bcm2835-pm.h -+++ b/include/linux/mfd/bcm2835-pm.h -@@ -8,6 +8,7 @@ - struct bcm2835_pm { - struct device *dev; - void __iomem *base; -+ void __iomem *asb; - }; - - #endif /* BCM2835_MFD_PM_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0562-drm-v3d-Fix-a-use-after-free-race-accessing-the-sche.patch b/target/linux/brcm2708/patches-4.19/950-0562-drm-v3d-Fix-a-use-after-free-race-accessing-the-sche.patch new file mode 100644 index 0000000000..7fd6b28d2c --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0562-drm-v3d-Fix-a-use-after-free-race-accessing-the-sche.patch @@ -0,0 +1,73 @@ +From 29fd99cb6bccda2b084b7a78824294075aafcc27 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Fri, 28 Sep 2018 16:21:23 -0700 +Subject: [PATCH 562/725] drm/v3d: Fix a use-after-free race accessing the + scheduler's fences. + +Once we push the job, the scheduler could run it and free it. So, if +we want to reference their fences, we need to grab them before then. +I haven't seen this happen in many days of conformance test runtime, +but let's still close the race. + +Signed-off-by: Eric Anholt +Fixes: 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D V3.x+") +Link: https://patchwork.freedesktop.org/patch/254119/ +Reviewed-by: Boris Brezillon +(cherry picked from commit 34c2c4f632f232ed2fdb66d4e42cc72d322273fe) +--- + drivers/gpu/drm/v3d/v3d_drv.h | 5 +++++ + drivers/gpu/drm/v3d/v3d_gem.c | 8 ++++++-- + 2 files changed, 11 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_drv.h ++++ b/drivers/gpu/drm/v3d/v3d_drv.h +@@ -198,6 +198,11 @@ struct v3d_exec_info { + */ + struct dma_fence *bin_done_fence; + ++ /* Fence for when the scheduler considers the render to be ++ * done, for when the BOs reservations should be complete. ++ */ ++ struct dma_fence *render_done_fence; ++ + struct kref refcount; + + /* This is the array of BOs that were looked up at the start of exec. */ +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -209,7 +209,7 @@ v3d_flush_caches(struct v3d_dev *v3d) + static void + v3d_attach_object_fences(struct v3d_exec_info *exec) + { +- struct dma_fence *out_fence = &exec->render.base.s_fence->finished; ++ struct dma_fence *out_fence = exec->render_done_fence; + struct v3d_bo *bo; + int i; + +@@ -409,6 +409,7 @@ v3d_exec_cleanup(struct kref *ref) + dma_fence_put(exec->render.done_fence); + + dma_fence_put(exec->bin_done_fence); ++ dma_fence_put(exec->render_done_fence); + + for (i = 0; i < exec->bo_count; i++) + drm_gem_object_put_unlocked(&exec->bo[i]->base); +@@ -572,6 +573,9 @@ v3d_submit_cl_ioctl(struct drm_device *d + if (ret) + goto fail_unreserve; + ++ exec->render_done_fence = ++ dma_fence_get(&exec->render.base.s_fence->finished); ++ + kref_get(&exec->refcount); /* put by scheduler job completion */ + drm_sched_entity_push_job(&exec->render.base, + &v3d_priv->sched_entity[V3D_RENDER]); +@@ -585,7 +589,7 @@ v3d_submit_cl_ioctl(struct drm_device *d + sync_out = drm_syncobj_find(file_priv, args->out_sync); + if (sync_out) { + drm_syncobj_replace_fence(sync_out, +- &exec->render.base.s_fence->finished); ++ exec->render_done_fence); + drm_syncobj_put(sync_out); + } + diff --git a/target/linux/brcm2708/patches-4.19/950-0562-soc-bcm-bcm2835-pm-Fix-PM_IMAGE_PERI-power-domain-su.patch b/target/linux/brcm2708/patches-4.19/950-0562-soc-bcm-bcm2835-pm-Fix-PM_IMAGE_PERI-power-domain-su.patch deleted file mode 100644 index 6399db88e9..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0562-soc-bcm-bcm2835-pm-Fix-PM_IMAGE_PERI-power-domain-su.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 81f47bb7d51490b62ba2fad6c0be42bf0e4e13a2 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 11 Jan 2019 17:29:10 -0800 -Subject: [PATCH 562/703] soc: bcm: bcm2835-pm: Fix PM_IMAGE_PERI power domain - support. - -We don't have ASB master/slave regs for this domain, so just skip that -step. - -Signed-off-by: Eric Anholt -Fixes: 670c672608a1 ("soc: bcm: bcm2835-pm: Add support for power domains under a new binding.") ---- - drivers/soc/bcm/bcm2835-power.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - ---- a/drivers/soc/bcm/bcm2835-power.c -+++ b/drivers/soc/bcm/bcm2835-power.c -@@ -150,7 +150,12 @@ struct bcm2835_power { - - static int bcm2835_asb_enable(struct bcm2835_power *power, u32 reg) - { -- u64 start = ktime_get_ns(); -+ u64 start; -+ -+ if (!reg) -+ return 0; -+ -+ start = ktime_get_ns(); - - /* Enable the module's async AXI bridges. */ - ASB_WRITE(reg, ASB_READ(reg) & ~ASB_REQ_STOP); -@@ -165,7 +170,12 @@ static int bcm2835_asb_enable(struct bcm - - static int bcm2835_asb_disable(struct bcm2835_power *power, u32 reg) - { -- u64 start = ktime_get_ns(); -+ u64 start; -+ -+ if (!reg) -+ return 0; -+ -+ start = ktime_get_ns(); - - /* Enable the module's async AXI bridges. */ - ASB_WRITE(reg, ASB_READ(reg) | ASB_REQ_STOP); diff --git a/target/linux/brcm2708/patches-4.19/950-0563-drm-v3d-Add-a-little-debugfs-entry-for-measuring-the.patch b/target/linux/brcm2708/patches-4.19/950-0563-drm-v3d-Add-a-little-debugfs-entry-for-measuring-the.patch new file mode 100644 index 0000000000..268982638d --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0563-drm-v3d-Add-a-little-debugfs-entry-for-measuring-the.patch @@ -0,0 +1,106 @@ +From d38e39d32a5df364c46416e25a5ee07756f8991e Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Fri, 28 Sep 2018 16:21:24 -0700 +Subject: [PATCH 563/725] drm/v3d: Add a little debugfs entry for measuring the + core clock. + +This adds just enough performance counter support to measure the +clock. We don't have linux kernel drivers for the clock driving the +HW, and this was useful for determining that the V3D HW is running on +a slow clock, not that the driver was slow. + +Signed-off-by: Eric Anholt +Link: https://patchwork.freedesktop.org/patch/msgid/20180928232126.4332-2-eric@anholt.net +Reviewed-by: Boris Brezillon +(cherry picked from commit 6915c9a525e575732429c22b28eb11871a29374b) +--- + drivers/gpu/drm/v3d/v3d_debugfs.c | 35 +++++++++++++++++++++++++++++++ + drivers/gpu/drm/v3d/v3d_regs.h | 30 ++++++++++++++++++++++++++ + 2 files changed, 65 insertions(+) + +--- a/drivers/gpu/drm/v3d/v3d_debugfs.c ++++ b/drivers/gpu/drm/v3d/v3d_debugfs.c +@@ -179,9 +179,44 @@ static int v3d_debugfs_bo_stats(struct s + return 0; + } + ++static int v3d_measure_clock(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 v3d_dev *v3d = to_v3d_dev(dev); ++ uint32_t cycles; ++ int core = 0; ++ int measure_ms = 1000; ++ ++ if (v3d->ver >= 40) { ++ V3D_CORE_WRITE(core, V3D_V4_PCTR_0_SRC_0_3, ++ V3D_SET_FIELD(V3D_PCTR_CYCLE_COUNT, ++ V3D_PCTR_S0)); ++ V3D_CORE_WRITE(core, V3D_V4_PCTR_0_CLR, 1); ++ V3D_CORE_WRITE(core, V3D_V4_PCTR_0_EN, 1); ++ } else { ++ V3D_CORE_WRITE(core, V3D_V3_PCTR_0_PCTRS0, ++ V3D_PCTR_CYCLE_COUNT); ++ V3D_CORE_WRITE(core, V3D_V3_PCTR_0_CLR, 1); ++ V3D_CORE_WRITE(core, V3D_V3_PCTR_0_EN, ++ V3D_V3_PCTR_0_EN_ENABLE | ++ 1); ++ } ++ msleep(measure_ms); ++ cycles = V3D_CORE_READ(core, V3D_PCTR_0_PCTR0); ++ ++ seq_printf(m, "cycles: %d (%d.%d Mhz)\n", ++ cycles, ++ cycles / (measure_ms * 1000), ++ (cycles / (measure_ms * 100)) % 10); ++ ++ return 0; ++} ++ + static const struct drm_info_list v3d_debugfs_list[] = { + {"v3d_ident", v3d_v3d_debugfs_ident, 0}, + {"v3d_regs", v3d_v3d_debugfs_regs, 0}, ++ {"measure_clock", v3d_measure_clock, 0}, + {"bo_stats", v3d_debugfs_bo_stats, 0}, + }; + +--- a/drivers/gpu/drm/v3d/v3d_regs.h ++++ b/drivers/gpu/drm/v3d/v3d_regs.h +@@ -267,6 +267,36 @@ + # define V3D_PTB_BXCF_RWORDERDISA BIT(1) + # define V3D_PTB_BXCF_CLIPDISA BIT(0) + ++#define V3D_V3_PCTR_0_EN 0x00674 ++#define V3D_V3_PCTR_0_EN_ENABLE BIT(31) ++#define V3D_V4_PCTR_0_EN 0x00650 ++/* When a bit is set, resets the counter to 0. */ ++#define V3D_V3_PCTR_0_CLR 0x00670 ++#define V3D_V4_PCTR_0_CLR 0x00654 ++#define V3D_PCTR_0_OVERFLOW 0x00658 ++ ++#define V3D_V3_PCTR_0_PCTRS0 0x00684 ++#define V3D_V3_PCTR_0_PCTRS15 0x00660 ++#define V3D_V3_PCTR_0_PCTRSX(x) (V3D_V3_PCTR_0_PCTRS0 + \ ++ 4 * (x)) ++/* Each src reg muxes four counters each. */ ++#define V3D_V4_PCTR_0_SRC_0_3 0x00660 ++#define V3D_V4_PCTR_0_SRC_28_31 0x0067c ++# define V3D_PCTR_S0_MASK V3D_MASK(6, 0) ++# define V3D_PCTR_S0_SHIFT 0 ++# define V3D_PCTR_S1_MASK V3D_MASK(14, 8) ++# define V3D_PCTR_S1_SHIFT 8 ++# define V3D_PCTR_S2_MASK V3D_MASK(22, 16) ++# define V3D_PCTR_S2_SHIFT 16 ++# define V3D_PCTR_S3_MASK V3D_MASK(30, 24) ++# define V3D_PCTR_S3_SHIFT 24 ++# define V3D_PCTR_CYCLE_COUNT 32 ++ ++/* Output values of the counters. */ ++#define V3D_PCTR_0_PCTR0 0x00680 ++#define V3D_PCTR_0_PCTR31 0x006fc ++#define V3D_PCTR_0_PCTRX(x) (V3D_PCTR_0_PCTR0 + \ ++ 4 * (x)) + #define V3D_GMP_STATUS 0x00800 + # define V3D_GMP_STATUS_GMPRST BIT(31) + # define V3D_GMP_STATUS_WR_COUNT_MASK V3D_MASK(30, 24) diff --git a/target/linux/brcm2708/patches-4.19/950-0563-soc-bcm-bcm2835-pm-Fix-error-paths-of-initialization.patch b/target/linux/brcm2708/patches-4.19/950-0563-soc-bcm-bcm2835-pm-Fix-error-paths-of-initialization.patch deleted file mode 100644 index 3dec4e59bd..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0563-soc-bcm-bcm2835-pm-Fix-error-paths-of-initialization.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 03ca911deca660a85ff285b53b1431350c77b246 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Sat, 12 Jan 2019 08:07:43 -0800 -Subject: [PATCH 563/703] soc: bcm: bcm2835-pm: Fix error paths of - initialization. - -The clock driver may probe after ours and so we need to pass the --EPROBE_DEFER out. Fix the other error path while we're here. - -v2: Use dom->name instead of dom->gov as the flag for initialized - domains, since we aren't setting up a governor. Make sure to - clear ->clk when no clk is present in the DT. - -Signed-off-by: Eric Anholt -Fixes: 670c672608a1 ("soc: bcm: bcm2835-pm: Add support for power domains under a new binding.") ---- - drivers/soc/bcm/bcm2835-power.c | 35 ++++++++++++++++++++++++++++----- - 1 file changed, 30 insertions(+), 5 deletions(-) - ---- a/drivers/soc/bcm/bcm2835-power.c -+++ b/drivers/soc/bcm/bcm2835-power.c -@@ -485,7 +485,7 @@ static int bcm2835_power_pd_power_off(st - } - } - --static void -+static int - bcm2835_init_power_domain(struct bcm2835_power *power, - int pd_xlate_index, const char *name) - { -@@ -493,6 +493,17 @@ bcm2835_init_power_domain(struct bcm2835 - struct bcm2835_power_domain *dom = &power->domains[pd_xlate_index]; - - dom->clk = devm_clk_get(dev->parent, name); -+ if (IS_ERR(dom->clk)) { -+ int ret = PTR_ERR(dom->clk); -+ -+ if (ret == -EPROBE_DEFER) -+ return ret; -+ -+ /* Some domains don't have a clk, so make sure that we -+ * don't deref an error pointer later. -+ */ -+ dom->clk = NULL; -+ } - - dom->base.name = name; - dom->base.power_on = bcm2835_power_pd_power_on; -@@ -505,6 +516,8 @@ bcm2835_init_power_domain(struct bcm2835 - pm_genpd_init(&dom->base, NULL, true); - - power->pd_xlate.domains[pd_xlate_index] = &dom->base; -+ -+ return 0; - } - - /** bcm2835_reset_reset - Resets a block that has a reset line in the -@@ -602,7 +615,7 @@ static int bcm2835_power_probe(struct pl - { BCM2835_POWER_DOMAIN_IMAGE_PERI, BCM2835_POWER_DOMAIN_CAM0 }, - { BCM2835_POWER_DOMAIN_IMAGE_PERI, BCM2835_POWER_DOMAIN_CAM1 }, - }; -- int ret, i; -+ int ret = 0, i; - u32 id; - - power = devm_kzalloc(dev, sizeof(*power), GFP_KERNEL); -@@ -629,8 +642,11 @@ static int bcm2835_power_probe(struct pl - - power->pd_xlate.num_domains = ARRAY_SIZE(power_domain_names); - -- for (i = 0; i < ARRAY_SIZE(power_domain_names); i++) -- bcm2835_init_power_domain(power, i, power_domain_names[i]); -+ for (i = 0; i < ARRAY_SIZE(power_domain_names); i++) { -+ ret = bcm2835_init_power_domain(power, i, power_domain_names[i]); -+ if (ret) -+ goto fail; -+ } - - for (i = 0; i < ARRAY_SIZE(domain_deps); i++) { - pm_genpd_add_subdomain(&power->domains[domain_deps[i].parent].base, -@@ -644,12 +660,21 @@ static int bcm2835_power_probe(struct pl - - ret = devm_reset_controller_register(dev, &power->reset); - if (ret) -- return ret; -+ goto fail; - - of_genpd_add_provider_onecell(dev->parent->of_node, &power->pd_xlate); - - dev_info(dev, "Broadcom BCM2835 power domains driver"); - return 0; -+ -+fail: -+ for (i = 0; i < ARRAY_SIZE(power_domain_names); i++) { -+ struct generic_pm_domain *dom = &power->domains[i].base; -+ -+ if (dom->name) -+ pm_genpd_remove(dom); -+ } -+ return ret; - } - - static int bcm2835_power_remove(struct platform_device *pdev) diff --git a/target/linux/brcm2708/patches-4.19/950-0564-drm-v3d-Update-a-comment-about-what-uses-v3d_job_dep.patch b/target/linux/brcm2708/patches-4.19/950-0564-drm-v3d-Update-a-comment-about-what-uses-v3d_job_dep.patch new file mode 100644 index 0000000000..16e6e254df --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0564-drm-v3d-Update-a-comment-about-what-uses-v3d_job_dep.patch @@ -0,0 +1,27 @@ +From fe38ab422b824e2e1f4b010a7b48c820ff302c8d Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 8 Nov 2018 08:16:52 -0800 +Subject: [PATCH 564/725] drm/v3d: Update a comment about what uses + v3d_job_dependency(). + +I merged bin and render's paths in a late refactoring. + +Signed-off-by: Eric Anholt +Link: https://patchwork.freedesktop.org/patch/msgid/20181108161654.19888-3-eric@anholt.net +Reviewed-by: Boris Brezillon +(cherry picked from commit e90e45f6bd45cc494a6f4cd1853c5e7cd4be7f68) +--- + drivers/gpu/drm/v3d/v3d_sched.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/v3d/v3d_sched.c ++++ b/drivers/gpu/drm/v3d/v3d_sched.c +@@ -39,7 +39,7 @@ v3d_job_free(struct drm_sched_job *sched + } + + /** +- * Returns the fences that the bin job depends on, one by one. ++ * Returns the fences that the bin or render job depends on, one by one. + * v3d_job_run() won't be called until all of them have been signaled. + */ + static struct dma_fence * diff --git a/target/linux/brcm2708/patches-4.19/950-0564-soc-bcm-bcm2835-pm-Add-support-for-2711.patch b/target/linux/brcm2708/patches-4.19/950-0564-soc-bcm-bcm2835-pm-Add-support-for-2711.patch deleted file mode 100644 index 41fc298382..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0564-soc-bcm-bcm2835-pm-Add-support-for-2711.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 4c3762f3ef917c00708650cdd532dd857ca75f04 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 11 Jan 2019 17:31:07 -0800 -Subject: [PATCH 564/703] soc: bcm: bcm2835-pm: Add support for 2711. - -Without the actual power management part any more, there's a lot less -to set up for V3D. We just need to clear the RSTN field for the power -domain, and expose the reset controller for toggling it again. - -This is definitely incomplete -- the old ISP and H264 is in the old -bridge, but since we have no consumers of it I've just done the -minimum to get V3D working. - -Signed-off-by: Eric Anholt ---- - drivers/mfd/bcm2835-pm.c | 11 +++++++++++ - drivers/soc/bcm/bcm2835-power.c | 22 ++++++++++++++++++++++ - include/linux/mfd/bcm2835-pm.h | 1 + - 3 files changed, 34 insertions(+) - ---- a/drivers/mfd/bcm2835-pm.c -+++ b/drivers/mfd/bcm2835-pm.c -@@ -50,6 +50,17 @@ static int bcm2835_pm_probe(struct platf - if (ret) - return ret; - -+ /* Map the ARGON ASB regs if present. */ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 2); -+ if (res) { -+ pm->arg_asb = devm_ioremap_resource(dev, res); -+ if (IS_ERR(pm->arg_asb)) { -+ dev_err(dev, "Failed to map ARGON ASB: %ld\n", -+ PTR_ERR(pm->arg_asb)); -+ return PTR_ERR(pm->arg_asb); -+ } -+ } -+ - /* We'll use the presence of the AXI ASB regs in the - * bcm2835-pm binding as the key for whether we can reference - * the full PM register range and support power domains. ---- a/drivers/soc/bcm/bcm2835-power.c -+++ b/drivers/soc/bcm/bcm2835-power.c -@@ -143,6 +143,8 @@ struct bcm2835_power { - /* AXI Async bridge registers. */ - void __iomem *asb; - -+ bool is_2711; -+ - struct genpd_onecell_data pd_xlate; - struct bcm2835_power_domain domains[BCM2835_POWER_DOMAIN_COUNT]; - struct reset_controller_dev reset; -@@ -192,6 +194,10 @@ static int bcm2835_power_power_off(struc - { - struct bcm2835_power *power = pd->power; - -+ /* 2711 has no power domains above the reset controller. */ -+ if (power->is_2711) -+ return 0; -+ - /* Enable functional isolation */ - PM_WRITE(pm_reg, PM_READ(pm_reg) & ~PM_ISFUNC); - -@@ -213,6 +219,10 @@ static int bcm2835_power_power_on(struct - int inrush; - bool powok; - -+ /* 2711 has no power domains above the reset controller. */ -+ if (power->is_2711) -+ return 0; -+ - /* If it was already powered on by the fw, leave it that way. */ - if (PM_READ(pm_reg) & PM_POWUP) - return 0; -@@ -627,6 +637,18 @@ static int bcm2835_power_probe(struct pl - power->base = pm->base; - power->asb = pm->asb; - -+ /* 2711 hack: the new ARGON ASB took over V3D, which is our -+ * only consumer of this driver so far. The old ASB seems to -+ * still be present with ISP and H264 bits but no V3D, but I -+ * don't know if that's real or not. The V3D is in the same -+ * place in the new ASB as the old one, so just poke the new -+ * one for now. -+ */ -+ if (pm->arg_asb) { -+ power->asb = pm->arg_asb; -+ power->is_2711 = true; -+ } -+ - id = ASB_READ(ASB_AXI_BRDG_ID); - if (id != 0x62726467 /* "BRDG" */) { - dev_err(dev, "ASB register ID returned 0x%08x\n", id); ---- a/include/linux/mfd/bcm2835-pm.h -+++ b/include/linux/mfd/bcm2835-pm.h -@@ -9,6 +9,7 @@ struct bcm2835_pm { - struct device *dev; - void __iomem *base; - void __iomem *asb; -+ void __iomem *arg_asb; - }; - - #endif /* BCM2835_MFD_PM_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0565-drm-expand-drm_syncobj_find_fence-to-support-timelin.patch b/target/linux/brcm2708/patches-4.19/950-0565-drm-expand-drm_syncobj_find_fence-to-support-timelin.patch deleted file mode 100644 index d4358efd38..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0565-drm-expand-drm_syncobj_find_fence-to-support-timelin.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 2593714309aa6f7fb3b06ffac7ca195a50543252 Mon Sep 17 00:00:00 2001 -From: Chunming Zhou -Date: Thu, 30 Aug 2018 14:48:29 +0800 -Subject: [PATCH 565/703] drm: expand drm_syncobj_find_fence to support - timeline point v2 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -we can fetch timeline point fence after expanded. -v2: The parameter fence is the result of the function and should come last. - -Signed-off-by: Chunming Zhou -Reviewed-by: Christian König -Signed-off-by: Christian König -Link: https://patchwork.freedesktop.org/patch/246541/ -(cherry picked from commit 0a6730ea27b68c7ac4171c29a816c29d26a9637a) -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- - drivers/gpu/drm/drm_syncobj.c | 5 +++-- - drivers/gpu/drm/v3d/v3d_gem.c | 4 ++-- - drivers/gpu/drm/vc4/vc4_gem.c | 2 +- - include/drm/drm_syncobj.h | 2 +- - 5 files changed, 8 insertions(+), 7 deletions(-) - ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c -@@ -1105,7 +1105,7 @@ static int amdgpu_syncobj_lookup_and_add - { - int r; - struct dma_fence *fence; -- r = drm_syncobj_find_fence(p->filp, handle, &fence); -+ r = drm_syncobj_find_fence(p->filp, handle, 0, &fence); - if (r) - return r; - ---- a/drivers/gpu/drm/drm_syncobj.c -+++ b/drivers/gpu/drm/drm_syncobj.c -@@ -235,6 +235,7 @@ static int drm_syncobj_assign_null_handl - * drm_syncobj_find_fence - lookup and reference the fence in a sync object - * @file_private: drm file private pointer - * @handle: sync object handle to lookup. -+ * @point: timeline point - * @fence: out parameter for the fence - * - * This is just a convenience function that combines drm_syncobj_find() and -@@ -245,7 +246,7 @@ static int drm_syncobj_assign_null_handl - * dma_fence_put(). - */ - int drm_syncobj_find_fence(struct drm_file *file_private, -- u32 handle, -+ u32 handle, u64 point, - struct dma_fence **fence) - { - struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle); -@@ -516,7 +517,7 @@ static int drm_syncobj_export_sync_file( - if (fd < 0) - return fd; - -- ret = drm_syncobj_find_fence(file_private, handle, &fence); -+ ret = drm_syncobj_find_fence(file_private, handle, 0, &fence); - if (ret) - goto err_put_fd; - ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -521,12 +521,12 @@ v3d_submit_cl_ioctl(struct drm_device *d - kref_init(&exec->refcount); - - ret = drm_syncobj_find_fence(file_priv, args->in_sync_bcl, -- &exec->bin.in_fence); -+ 0, &exec->bin.in_fence); - if (ret == -EINVAL) - goto fail; - - ret = drm_syncobj_find_fence(file_priv, args->in_sync_rcl, -- &exec->render.in_fence); -+ 0, &exec->render.in_fence); - if (ret == -EINVAL) - goto fail; - ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -1173,7 +1173,7 @@ vc4_submit_cl_ioctl(struct drm_device *d - - if (args->in_sync) { - ret = drm_syncobj_find_fence(file_priv, args->in_sync, -- &in_fence); -+ 0, &in_fence); - if (ret) - goto fail; - ---- a/include/drm/drm_syncobj.h -+++ b/include/drm/drm_syncobj.h -@@ -139,7 +139,7 @@ void drm_syncobj_remove_callback(struct - void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, - struct dma_fence *fence); - int drm_syncobj_find_fence(struct drm_file *file_private, -- u32 handle, -+ u32 handle, u64 point, - struct dma_fence **fence); - void drm_syncobj_free(struct kref *kref); - int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags, diff --git a/target/linux/brcm2708/patches-4.19/950-0565-drm-v3d-Clean-up-the-reservation-object-setup.patch b/target/linux/brcm2708/patches-4.19/950-0565-drm-v3d-Clean-up-the-reservation-object-setup.patch new file mode 100644 index 0000000000..ffddd3c2c5 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0565-drm-v3d-Clean-up-the-reservation-object-setup.patch @@ -0,0 +1,102 @@ +From bf9bb521ac3c5d18ed4a8e8e5004f015c2b2a818 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 8 Nov 2018 08:16:53 -0800 +Subject: [PATCH 565/725] drm/v3d: Clean up the reservation object setup. + +The extra to_v3d_bo() calls came from copying this from the vc4 +driver, which stored the cma gem object in the structs. + +v2: Fix an unused var warning + +Signed-off-by: Eric Anholt +Link: https://patchwork.freedesktop.org/patch/msgid/20181108161654.19888-4-eric@anholt.net +Reviewed-by: Boris Brezillon (v1) +(cherry picked from commit 8f1cd826641d677d0f7494253ecfc3335f0bcd4e) +--- + drivers/gpu/drm/v3d/v3d_gem.c | 33 +++++++++++---------------------- + 1 file changed, 11 insertions(+), 22 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -210,14 +210,11 @@ static void + v3d_attach_object_fences(struct v3d_exec_info *exec) + { + struct dma_fence *out_fence = exec->render_done_fence; +- struct v3d_bo *bo; + int i; + + for (i = 0; i < exec->bo_count; i++) { +- bo = to_v3d_bo(&exec->bo[i]->base); +- + /* XXX: Use shared fences for read-only objects. */ +- reservation_object_add_excl_fence(bo->resv, out_fence); ++ reservation_object_add_excl_fence(exec->bo[i]->resv, out_fence); + } + } + +@@ -228,11 +225,8 @@ v3d_unlock_bo_reservations(struct drm_de + { + int i; + +- for (i = 0; i < exec->bo_count; i++) { +- struct v3d_bo *bo = to_v3d_bo(&exec->bo[i]->base); +- +- ww_mutex_unlock(&bo->resv->lock); +- } ++ for (i = 0; i < exec->bo_count; i++) ++ ww_mutex_unlock(&exec->bo[i]->resv->lock); + + ww_acquire_fini(acquire_ctx); + } +@@ -251,13 +245,13 @@ v3d_lock_bo_reservations(struct drm_devi + { + int contended_lock = -1; + int i, ret; +- struct v3d_bo *bo; + + ww_acquire_init(acquire_ctx, &reservation_ww_class); + + retry: + if (contended_lock != -1) { +- bo = to_v3d_bo(&exec->bo[contended_lock]->base); ++ struct v3d_bo *bo = exec->bo[contended_lock]; ++ + ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock, + acquire_ctx); + if (ret) { +@@ -270,19 +264,16 @@ retry: + if (i == contended_lock) + continue; + +- bo = to_v3d_bo(&exec->bo[i]->base); +- +- ret = ww_mutex_lock_interruptible(&bo->resv->lock, acquire_ctx); ++ ret = ww_mutex_lock_interruptible(&exec->bo[i]->resv->lock, ++ acquire_ctx); + if (ret) { + int j; + +- for (j = 0; j < i; j++) { +- bo = to_v3d_bo(&exec->bo[j]->base); +- ww_mutex_unlock(&bo->resv->lock); +- } ++ for (j = 0; j < i; j++) ++ ww_mutex_unlock(&exec->bo[j]->resv->lock); + + if (contended_lock != -1 && contended_lock >= i) { +- bo = to_v3d_bo(&exec->bo[contended_lock]->base); ++ struct v3d_bo *bo = exec->bo[contended_lock]; + + ww_mutex_unlock(&bo->resv->lock); + } +@@ -303,9 +294,7 @@ retry: + * before we commit the CL to the hardware. + */ + for (i = 0; i < exec->bo_count; i++) { +- bo = to_v3d_bo(&exec->bo[i]->base); +- +- ret = reservation_object_reserve_shared(bo->resv); ++ ret = reservation_object_reserve_shared(exec->bo[i]->resv); + if (ret) { + v3d_unlock_bo_reservations(dev, exec, acquire_ctx); + return ret; diff --git a/target/linux/brcm2708/patches-4.19/950-0566-drm-v3d-Add-support-for-submitting-jobs-to-the-TFU.patch b/target/linux/brcm2708/patches-4.19/950-0566-drm-v3d-Add-support-for-submitting-jobs-to-the-TFU.patch new file mode 100644 index 0000000000..da1187cf16 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0566-drm-v3d-Add-support-for-submitting-jobs-to-the-TFU.patch @@ -0,0 +1,802 @@ +From 5d80273397b13617211ac6dd1e0e9759fff0470d Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 28 Nov 2018 15:09:25 -0800 +Subject: [PATCH 566/725] drm/v3d: Add support for submitting jobs to the TFU. + +The TFU can copy from raster, UIF, and SAND input images to UIF output +images, with optional mipmap generation. This will certainly be +useful for media EGL image input, but is also useful immediately for +mipmap generation without bogging the V3D core down. + +For now we only run the queue 1 job deep, and don't have any hang +recovery (though I don't think we should need it, with TFU). Queuing +multiple jobs in the HW will require synchronizing the YUV coefficient +regs updates since they don't get FIFOed with the job. + +v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain + why TFU is AUTH, clarify the syncing docs, drop the unused TFU + interrupt regs (you're expected to use the hub's), don't take + &bo->base for NULL bos. +v3: Fix a little whitespace alignment (noticed by checkpatch), rebase + on drm_sched_job_cleanup() changes. + +Signed-off-by: Eric Anholt +Reviewed-by: Dave Emett (v2) +Link: https://patchwork.freedesktop.org/patch/264607/ +(cherry picked from commit 1584f16ca96ef124aad79efa3303cff5f3530e2c) +--- + drivers/gpu/drm/v3d/v3d_drv.c | 15 ++- + drivers/gpu/drm/v3d/v3d_drv.h | 32 +++++- + drivers/gpu/drm/v3d/v3d_gem.c | 178 ++++++++++++++++++++++++++++---- + drivers/gpu/drm/v3d/v3d_irq.c | 12 ++- + drivers/gpu/drm/v3d/v3d_regs.h | 49 +++++++++ + drivers/gpu/drm/v3d/v3d_sched.c | 148 ++++++++++++++++++++++---- + drivers/gpu/drm/v3d/v3d_trace.h | 20 ++++ + include/uapi/drm/v3d_drm.h | 25 +++++ + 8 files changed, 426 insertions(+), 53 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_drv.c ++++ b/drivers/gpu/drm/v3d/v3d_drv.c +@@ -112,10 +112,15 @@ static int v3d_get_param_ioctl(struct dr + return 0; + } + +- /* Any params that aren't just register reads would go here. */ + +- DRM_DEBUG("Unknown parameter %d\n", args->param); +- return -EINVAL; ++ switch (args->param) { ++ case DRM_V3D_PARAM_SUPPORTS_TFU: ++ args->value = 1; ++ return 0; ++ default: ++ DRM_DEBUG("Unknown parameter %d\n", args->param); ++ return -EINVAL; ++ } + } + + static int +@@ -170,7 +175,8 @@ static const struct file_operations v3d_ + /* DRM_AUTH is required on SUBMIT_CL for now, while we don't have GMP + * protection between clients. Note that render nodes would be be + * able to submit CLs that could access BOs from clients authenticated +- * with the master node. ++ * with the master node. The TFU doesn't use the GMP, so it would ++ * need to stay DRM_AUTH until we do buffer size/offset validation. + */ + static const struct drm_ioctl_desc v3d_drm_ioctls[] = { + DRM_IOCTL_DEF_DRV(V3D_SUBMIT_CL, v3d_submit_cl_ioctl, DRM_RENDER_ALLOW | DRM_AUTH), +@@ -179,6 +185,7 @@ static const struct drm_ioctl_desc v3d_d + DRM_IOCTL_DEF_DRV(V3D_MMAP_BO, v3d_mmap_bo_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(V3D_GET_PARAM, v3d_get_param_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(V3D_GET_BO_OFFSET, v3d_get_bo_offset_ioctl, DRM_RENDER_ALLOW), ++ DRM_IOCTL_DEF_DRV(V3D_SUBMIT_TFU, v3d_submit_tfu_ioctl, DRM_RENDER_ALLOW | DRM_AUTH), + }; + + static const struct vm_operations_struct v3d_vm_ops = { +--- a/drivers/gpu/drm/v3d/v3d_drv.h ++++ b/drivers/gpu/drm/v3d/v3d_drv.h +@@ -7,19 +7,18 @@ + #include + #include + #include ++#include "uapi/drm/v3d_drm.h" + + #define GMP_GRANULARITY (128 * 1024) + +-/* Enum for each of the V3D queues. We maintain various queue +- * tracking as an array because at some point we'll want to support +- * the TFU (texture formatting unit) as another queue. +- */ ++/* Enum for each of the V3D queues. */ + enum v3d_queue { + V3D_BIN, + V3D_RENDER, ++ V3D_TFU, + }; + +-#define V3D_MAX_QUEUES (V3D_RENDER + 1) ++#define V3D_MAX_QUEUES (V3D_TFU + 1) + + struct v3d_queue_state { + struct drm_gpu_scheduler sched; +@@ -68,6 +67,7 @@ struct v3d_dev { + + struct v3d_exec_info *bin_job; + struct v3d_exec_info *render_job; ++ struct v3d_tfu_job *tfu_job; + + struct v3d_queue_state queue[V3D_MAX_QUEUES]; + +@@ -218,6 +218,25 @@ struct v3d_exec_info { + u32 qma, qms, qts; + }; + ++struct v3d_tfu_job { ++ struct drm_sched_job base; ++ ++ struct drm_v3d_submit_tfu args; ++ ++ /* An optional fence userspace can pass in for the job to depend on. */ ++ struct dma_fence *in_fence; ++ ++ /* v3d fence to be signaled by IRQ handler when the job is complete. */ ++ struct dma_fence *done_fence; ++ ++ struct v3d_dev *v3d; ++ ++ struct kref refcount; ++ ++ /* This is the array of BOs that were looked up at the start of exec. */ ++ struct v3d_bo *bo[4]; ++}; ++ + /** + * _wait_for - magic (register) wait macro + * +@@ -281,9 +300,12 @@ int v3d_gem_init(struct drm_device *dev) + void v3d_gem_destroy(struct drm_device *dev); + int v3d_submit_cl_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); ++int v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); + int v3d_wait_bo_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + void v3d_exec_put(struct v3d_exec_info *exec); ++void v3d_tfu_job_put(struct v3d_tfu_job *exec); + void v3d_reset(struct v3d_dev *v3d); + void v3d_invalidate_caches(struct v3d_dev *v3d); + void v3d_flush_caches(struct v3d_dev *v3d); +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -207,26 +207,27 @@ v3d_flush_caches(struct v3d_dev *v3d) + } + + static void +-v3d_attach_object_fences(struct v3d_exec_info *exec) ++v3d_attach_object_fences(struct v3d_bo **bos, int bo_count, ++ struct dma_fence *fence) + { +- struct dma_fence *out_fence = exec->render_done_fence; + int i; + +- for (i = 0; i < exec->bo_count; i++) { ++ for (i = 0; i < bo_count; i++) { + /* XXX: Use shared fences for read-only objects. */ +- reservation_object_add_excl_fence(exec->bo[i]->resv, out_fence); ++ reservation_object_add_excl_fence(bos[i]->resv, fence); + } + } + + static void + v3d_unlock_bo_reservations(struct drm_device *dev, +- struct v3d_exec_info *exec, ++ struct v3d_bo **bos, ++ int bo_count, + struct ww_acquire_ctx *acquire_ctx) + { + int i; + +- for (i = 0; i < exec->bo_count; i++) +- ww_mutex_unlock(&exec->bo[i]->resv->lock); ++ for (i = 0; i < bo_count; i++) ++ ww_mutex_unlock(&bos[i]->resv->lock); + + ww_acquire_fini(acquire_ctx); + } +@@ -240,7 +241,8 @@ v3d_unlock_bo_reservations(struct drm_de + */ + static int + v3d_lock_bo_reservations(struct drm_device *dev, +- struct v3d_exec_info *exec, ++ struct v3d_bo **bos, ++ int bo_count, + struct ww_acquire_ctx *acquire_ctx) + { + int contended_lock = -1; +@@ -250,7 +252,7 @@ v3d_lock_bo_reservations(struct drm_devi + + retry: + if (contended_lock != -1) { +- struct v3d_bo *bo = exec->bo[contended_lock]; ++ struct v3d_bo *bo = bos[contended_lock]; + + ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock, + acquire_ctx); +@@ -260,20 +262,20 @@ retry: + } + } + +- for (i = 0; i < exec->bo_count; i++) { ++ for (i = 0; i < bo_count; i++) { + if (i == contended_lock) + continue; + +- ret = ww_mutex_lock_interruptible(&exec->bo[i]->resv->lock, ++ ret = ww_mutex_lock_interruptible(&bos[i]->resv->lock, + acquire_ctx); + if (ret) { + int j; + + for (j = 0; j < i; j++) +- ww_mutex_unlock(&exec->bo[j]->resv->lock); ++ ww_mutex_unlock(&bos[j]->resv->lock); + + if (contended_lock != -1 && contended_lock >= i) { +- struct v3d_bo *bo = exec->bo[contended_lock]; ++ struct v3d_bo *bo = bos[contended_lock]; + + ww_mutex_unlock(&bo->resv->lock); + } +@@ -293,10 +295,11 @@ retry: + /* Reserve space for our shared (read-only) fence references, + * before we commit the CL to the hardware. + */ +- for (i = 0; i < exec->bo_count; i++) { +- ret = reservation_object_reserve_shared(exec->bo[i]->resv); ++ for (i = 0; i < bo_count; i++) { ++ ret = reservation_object_reserve_shared(bos[i]->resv); + if (ret) { +- v3d_unlock_bo_reservations(dev, exec, acquire_ctx); ++ v3d_unlock_bo_reservations(dev, bos, bo_count, ++ acquire_ctx); + return ret; + } + } +@@ -419,6 +422,33 @@ void v3d_exec_put(struct v3d_exec_info * + kref_put(&exec->refcount, v3d_exec_cleanup); + } + ++static void ++v3d_tfu_job_cleanup(struct kref *ref) ++{ ++ struct v3d_tfu_job *job = container_of(ref, struct v3d_tfu_job, ++ refcount); ++ struct v3d_dev *v3d = job->v3d; ++ unsigned int i; ++ ++ dma_fence_put(job->in_fence); ++ dma_fence_put(job->done_fence); ++ ++ for (i = 0; i < ARRAY_SIZE(job->bo); i++) { ++ if (job->bo[i]) ++ drm_gem_object_put_unlocked(&job->bo[i]->base); ++ } ++ ++ pm_runtime_mark_last_busy(v3d->dev); ++ pm_runtime_put_autosuspend(v3d->dev); ++ ++ kfree(job); ++} ++ ++void v3d_tfu_job_put(struct v3d_tfu_job *job) ++{ ++ kref_put(&job->refcount, v3d_tfu_job_cleanup); ++} ++ + int + v3d_wait_bo_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +@@ -536,7 +566,8 @@ v3d_submit_cl_ioctl(struct drm_device *d + if (ret) + goto fail; + +- ret = v3d_lock_bo_reservations(dev, exec, &acquire_ctx); ++ ret = v3d_lock_bo_reservations(dev, exec->bo, exec->bo_count, ++ &acquire_ctx); + if (ret) + goto fail; + +@@ -570,9 +601,10 @@ v3d_submit_cl_ioctl(struct drm_device *d + &v3d_priv->sched_entity[V3D_RENDER]); + mutex_unlock(&v3d->sched_lock); + +- v3d_attach_object_fences(exec); ++ v3d_attach_object_fences(exec->bo, exec->bo_count, ++ exec->render_done_fence); + +- v3d_unlock_bo_reservations(dev, exec, &acquire_ctx); ++ v3d_unlock_bo_reservations(dev, exec->bo, exec->bo_count, &acquire_ctx); + + /* Update the return sync object for the */ + sync_out = drm_syncobj_find(file_priv, args->out_sync); +@@ -588,12 +620,118 @@ v3d_submit_cl_ioctl(struct drm_device *d + + fail_unreserve: + mutex_unlock(&v3d->sched_lock); +- v3d_unlock_bo_reservations(dev, exec, &acquire_ctx); ++ v3d_unlock_bo_reservations(dev, exec->bo, exec->bo_count, &acquire_ctx); + fail: + v3d_exec_put(exec); + + return ret; + } ++ ++/** ++ * v3d_submit_tfu_ioctl() - Submits a TFU (texture formatting) job to the V3D. ++ * @dev: DRM device ++ * @data: ioctl argument ++ * @file_priv: DRM file for this fd ++ * ++ * Userspace provides the register setup for the TFU, which we don't ++ * need to validate since the TFU is behind the MMU. ++ */ ++int ++v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct v3d_dev *v3d = to_v3d_dev(dev); ++ struct v3d_file_priv *v3d_priv = file_priv->driver_priv; ++ struct drm_v3d_submit_tfu *args = data; ++ struct v3d_tfu_job *job; ++ struct ww_acquire_ctx acquire_ctx; ++ struct drm_syncobj *sync_out; ++ struct dma_fence *sched_done_fence; ++ int ret = 0; ++ int bo_count; ++ ++ job = kcalloc(1, sizeof(*job), GFP_KERNEL); ++ if (!job) ++ return -ENOMEM; ++ ++ ret = pm_runtime_get_sync(v3d->dev); ++ if (ret < 0) { ++ kfree(job); ++ return ret; ++ } ++ ++ kref_init(&job->refcount); ++ ++ ret = drm_syncobj_find_fence(file_priv, args->in_sync, ++ 0, &job->in_fence); ++ if (ret == -EINVAL) ++ goto fail; ++ ++ job->args = *args; ++ job->v3d = v3d; ++ ++ spin_lock(&file_priv->table_lock); ++ for (bo_count = 0; bo_count < ARRAY_SIZE(job->bo); bo_count++) { ++ struct drm_gem_object *bo; ++ ++ if (!args->bo_handles[bo_count]) ++ break; ++ ++ bo = idr_find(&file_priv->object_idr, ++ args->bo_handles[bo_count]); ++ if (!bo) { ++ DRM_DEBUG("Failed to look up GEM BO %d: %d\n", ++ bo_count, args->bo_handles[bo_count]); ++ ret = -ENOENT; ++ spin_unlock(&file_priv->table_lock); ++ goto fail; ++ } ++ drm_gem_object_get(bo); ++ job->bo[bo_count] = to_v3d_bo(bo); ++ } ++ spin_unlock(&file_priv->table_lock); ++ ++ ret = v3d_lock_bo_reservations(dev, job->bo, bo_count, &acquire_ctx); ++ if (ret) ++ goto fail; ++ ++ mutex_lock(&v3d->sched_lock); ++ ret = drm_sched_job_init(&job->base, ++ &v3d_priv->sched_entity[V3D_TFU], ++ v3d_priv); ++ if (ret) ++ goto fail_unreserve; ++ ++ sched_done_fence = dma_fence_get(&job->base.s_fence->finished); ++ ++ kref_get(&job->refcount); /* put by scheduler job completion */ ++ drm_sched_entity_push_job(&job->base, &v3d_priv->sched_entity[V3D_TFU]); ++ mutex_unlock(&v3d->sched_lock); ++ ++ v3d_attach_object_fences(job->bo, bo_count, sched_done_fence); ++ ++ v3d_unlock_bo_reservations(dev, job->bo, bo_count, &acquire_ctx); ++ ++ /* Update the return sync object */ ++ sync_out = drm_syncobj_find(file_priv, args->out_sync); ++ if (sync_out) { ++ drm_syncobj_replace_fence(sync_out, sched_done_fence); ++ drm_syncobj_put(sync_out); ++ } ++ dma_fence_put(sched_done_fence); ++ ++ v3d_tfu_job_put(job); ++ ++ return 0; ++ ++fail_unreserve: ++ mutex_unlock(&v3d->sched_lock); ++ v3d_unlock_bo_reservations(dev, job->bo, bo_count, &acquire_ctx); ++fail: ++ v3d_tfu_job_put(job); ++ ++ return ret; ++} + + int + v3d_gem_init(struct drm_device *dev) +--- a/drivers/gpu/drm/v3d/v3d_irq.c ++++ b/drivers/gpu/drm/v3d/v3d_irq.c +@@ -4,8 +4,8 @@ + /** + * DOC: Interrupt management for the V3D engine + * +- * When we take a binning or rendering flush done interrupt, we need +- * to signal the fence for that job so that the scheduler can queue up ++ * When we take a bin, render, or TFU done interrupt, we need to ++ * signal the fence for that job so that the scheduler can queue up + * the next one and unblock any waiters. + * + * When we take the binner out of memory interrupt, we need to +@@ -23,7 +23,8 @@ + + #define V3D_HUB_IRQS ((u32)(V3D_HUB_INT_MMU_WRV | \ + V3D_HUB_INT_MMU_PTI | \ +- V3D_HUB_INT_MMU_CAP)) ++ V3D_HUB_INT_MMU_CAP | \ ++ V3D_HUB_INT_TFUC)) + + static void + v3d_overflow_mem_work(struct work_struct *work) +@@ -117,6 +118,11 @@ v3d_hub_irq(int irq, void *arg) + /* Acknowledge the interrupts we're handling here. */ + V3D_WRITE(V3D_HUB_INT_CLR, intsts); + ++ if (intsts & V3D_HUB_INT_TFUC) { ++ dma_fence_signal(v3d->tfu_job->done_fence); ++ status = IRQ_HANDLED; ++ } ++ + if (intsts & (V3D_HUB_INT_MMU_WRV | + V3D_HUB_INT_MMU_PTI | + V3D_HUB_INT_MMU_CAP)) { +--- a/drivers/gpu/drm/v3d/v3d_regs.h ++++ b/drivers/gpu/drm/v3d/v3d_regs.h +@@ -86,6 +86,55 @@ + # define V3D_TOP_GR_BRIDGE_SW_INIT_1 0x0000c + # define V3D_TOP_GR_BRIDGE_SW_INIT_1_V3D_CLK_108_SW_INIT BIT(0) + ++#define V3D_TFU_CS 0x00400 ++/* Stops current job, empties input fifo. */ ++# define V3D_TFU_CS_TFURST BIT(31) ++# define V3D_TFU_CS_CVTCT_MASK V3D_MASK(23, 16) ++# define V3D_TFU_CS_CVTCT_SHIFT 16 ++# define V3D_TFU_CS_NFREE_MASK V3D_MASK(13, 8) ++# define V3D_TFU_CS_NFREE_SHIFT 8 ++# define V3D_TFU_CS_BUSY BIT(0) ++ ++#define V3D_TFU_SU 0x00404 ++/* Interrupt when FINTTHR input slots are free (0 = disabled) */ ++# define V3D_TFU_SU_FINTTHR_MASK V3D_MASK(13, 8) ++# define V3D_TFU_SU_FINTTHR_SHIFT 8 ++/* Skips resetting the CRC at the start of CRC generation. */ ++# define V3D_TFU_SU_CRCCHAIN BIT(4) ++/* skips writes, computes CRC of the image. miplevels must be 0. */ ++# define V3D_TFU_SU_CRC BIT(3) ++# define V3D_TFU_SU_THROTTLE_MASK V3D_MASK(1, 0) ++# define V3D_TFU_SU_THROTTLE_SHIFT 0 ++ ++#define V3D_TFU_ICFG 0x00408 ++/* Interrupt when the conversion is complete. */ ++# define V3D_TFU_ICFG_IOC BIT(0) ++ ++/* Input Image Address */ ++#define V3D_TFU_IIA 0x0040c ++/* Input Chroma Address */ ++#define V3D_TFU_ICA 0x00410 ++/* Input Image Stride */ ++#define V3D_TFU_IIS 0x00414 ++/* Input Image U-Plane Address */ ++#define V3D_TFU_IUA 0x00418 ++/* Output Image Address */ ++#define V3D_TFU_IOA 0x0041c ++/* Image Output Size */ ++#define V3D_TFU_IOS 0x00420 ++/* TFU YUV Coefficient 0 */ ++#define V3D_TFU_COEF0 0x00424 ++/* Use these regs instead of the defaults. */ ++# define V3D_TFU_COEF0_USECOEF BIT(31) ++/* TFU YUV Coefficient 1 */ ++#define V3D_TFU_COEF1 0x00428 ++/* TFU YUV Coefficient 2 */ ++#define V3D_TFU_COEF2 0x0042c ++/* TFU YUV Coefficient 3 */ ++#define V3D_TFU_COEF3 0x00430 ++ ++#define V3D_TFU_CRC 0x00434 ++ + /* Per-MMU registers. */ + + #define V3D_MMUC_CONTROL 0x01000 +--- a/drivers/gpu/drm/v3d/v3d_sched.c ++++ b/drivers/gpu/drm/v3d/v3d_sched.c +@@ -30,6 +30,12 @@ to_v3d_job(struct drm_sched_job *sched_j + return container_of(sched_job, struct v3d_job, base); + } + ++static struct v3d_tfu_job * ++to_tfu_job(struct drm_sched_job *sched_job) ++{ ++ return container_of(sched_job, struct v3d_tfu_job, base); ++} ++ + static void + v3d_job_free(struct drm_sched_job *sched_job) + { +@@ -38,6 +44,14 @@ v3d_job_free(struct drm_sched_job *sched + v3d_exec_put(job->exec); + } + ++static void ++v3d_tfu_job_free(struct drm_sched_job *sched_job) ++{ ++ struct v3d_tfu_job *job = to_tfu_job(sched_job); ++ ++ v3d_tfu_job_put(job); ++} ++ + /** + * Returns the fences that the bin or render job depends on, one by one. + * v3d_job_run() won't be called until all of them have been signaled. +@@ -76,6 +90,27 @@ v3d_job_dependency(struct drm_sched_job + return fence; + } + ++/** ++ * Returns the fences that the TFU job depends on, one by one. ++ * v3d_tfu_job_run() won't be called until all of them have been ++ * signaled. ++ */ ++static struct dma_fence * ++v3d_tfu_job_dependency(struct drm_sched_job *sched_job, ++ struct drm_sched_entity *s_entity) ++{ ++ struct v3d_tfu_job *job = to_tfu_job(sched_job); ++ struct dma_fence *fence; ++ ++ fence = job->in_fence; ++ if (fence) { ++ job->in_fence = NULL; ++ return fence; ++ } ++ ++ return NULL; ++} ++ + static struct dma_fence *v3d_job_run(struct drm_sched_job *sched_job) + { + struct v3d_job *job = to_v3d_job(sched_job); +@@ -147,31 +182,47 @@ static struct dma_fence *v3d_job_run(str + return fence; + } + +-static void +-v3d_job_timedout(struct drm_sched_job *sched_job) ++static struct dma_fence * ++v3d_tfu_job_run(struct drm_sched_job *sched_job) + { +- struct v3d_job *job = to_v3d_job(sched_job); +- struct v3d_exec_info *exec = job->exec; +- struct v3d_dev *v3d = exec->v3d; +- enum v3d_queue job_q = job == &exec->bin ? V3D_BIN : V3D_RENDER; +- enum v3d_queue q; +- u32 ctca = V3D_CORE_READ(0, V3D_CLE_CTNCA(job_q)); +- u32 ctra = V3D_CORE_READ(0, V3D_CLE_CTNRA(job_q)); ++ struct v3d_tfu_job *job = to_tfu_job(sched_job); ++ struct v3d_dev *v3d = job->v3d; ++ struct drm_device *dev = &v3d->drm; ++ struct dma_fence *fence; + +- /* If the current address or return address have changed, then +- * the GPU has probably made progress and we should delay the +- * reset. This could fail if the GPU got in an infinite loop +- * in the CL, but that is pretty unlikely outside of an i-g-t +- * testcase. +- */ +- if (job->timedout_ctca != ctca || job->timedout_ctra != ctra) { +- job->timedout_ctca = ctca; +- job->timedout_ctra = ctra; ++ fence = v3d_fence_create(v3d, V3D_TFU); ++ if (IS_ERR(fence)) ++ return NULL; + +- schedule_delayed_work(&job->base.work_tdr, +- job->base.sched->timeout); +- return; ++ v3d->tfu_job = job; ++ if (job->done_fence) ++ dma_fence_put(job->done_fence); ++ job->done_fence = dma_fence_get(fence); ++ ++ trace_v3d_submit_tfu(dev, to_v3d_fence(fence)->seqno); ++ ++ V3D_WRITE(V3D_TFU_IIA, job->args.iia); ++ V3D_WRITE(V3D_TFU_IIS, job->args.iis); ++ V3D_WRITE(V3D_TFU_ICA, job->args.ica); ++ V3D_WRITE(V3D_TFU_IUA, job->args.iua); ++ V3D_WRITE(V3D_TFU_IOA, job->args.ioa); ++ V3D_WRITE(V3D_TFU_IOS, job->args.ios); ++ V3D_WRITE(V3D_TFU_COEF0, job->args.coef[0]); ++ if (job->args.coef[0] & V3D_TFU_COEF0_USECOEF) { ++ V3D_WRITE(V3D_TFU_COEF1, job->args.coef[1]); ++ V3D_WRITE(V3D_TFU_COEF2, job->args.coef[2]); ++ V3D_WRITE(V3D_TFU_COEF3, job->args.coef[3]); + } ++ /* ICFG kicks off the job. */ ++ V3D_WRITE(V3D_TFU_ICFG, job->args.icfg | V3D_TFU_ICFG_IOC); ++ ++ return fence; ++} ++ ++static void ++v3d_gpu_reset_for_timeout(struct v3d_dev *v3d, struct drm_sched_job *sched_job) ++{ ++ enum v3d_queue q; + + mutex_lock(&v3d->reset_lock); + +@@ -196,6 +247,41 @@ v3d_job_timedout(struct drm_sched_job *s + mutex_unlock(&v3d->reset_lock); + } + ++static void ++v3d_job_timedout(struct drm_sched_job *sched_job) ++{ ++ struct v3d_job *job = to_v3d_job(sched_job); ++ struct v3d_exec_info *exec = job->exec; ++ struct v3d_dev *v3d = exec->v3d; ++ enum v3d_queue job_q = job == &exec->bin ? V3D_BIN : V3D_RENDER; ++ u32 ctca = V3D_CORE_READ(0, V3D_CLE_CTNCA(job_q)); ++ u32 ctra = V3D_CORE_READ(0, V3D_CLE_CTNRA(job_q)); ++ ++ /* If the current address or return address have changed, then ++ * the GPU has probably made progress and we should delay the ++ * reset. This could fail if the GPU got in an infinite loop ++ * in the CL, but that is pretty unlikely outside of an i-g-t ++ * testcase. ++ */ ++ if (job->timedout_ctca != ctca || job->timedout_ctra != ctra) { ++ job->timedout_ctca = ctca; ++ job->timedout_ctra = ctra; ++ schedule_delayed_work(&job->base.work_tdr, ++ job->base.sched->timeout); ++ return; ++ } ++ ++ v3d_gpu_reset_for_timeout(v3d, sched_job); ++} ++ ++static void ++v3d_tfu_job_timedout(struct drm_sched_job *sched_job) ++{ ++ struct v3d_tfu_job *job = to_tfu_job(sched_job); ++ ++ v3d_gpu_reset_for_timeout(job->v3d, sched_job); ++} ++ + static const struct drm_sched_backend_ops v3d_sched_ops = { + .dependency = v3d_job_dependency, + .run_job = v3d_job_run, +@@ -203,6 +289,13 @@ static const struct drm_sched_backend_op + .free_job = v3d_job_free + }; + ++static const struct drm_sched_backend_ops v3d_tfu_sched_ops = { ++ .dependency = v3d_tfu_job_dependency, ++ .run_job = v3d_tfu_job_run, ++ .timedout_job = v3d_tfu_job_timedout, ++ .free_job = v3d_tfu_job_free ++}; ++ + int + v3d_sched_init(struct v3d_dev *v3d) + { +@@ -232,6 +325,19 @@ v3d_sched_init(struct v3d_dev *v3d) + drm_sched_fini(&v3d->queue[V3D_BIN].sched); + return ret; + } ++ ++ ret = drm_sched_init(&v3d->queue[V3D_TFU].sched, ++ &v3d_tfu_sched_ops, ++ hw_jobs_limit, job_hang_limit, ++ msecs_to_jiffies(hang_limit_ms), ++ "v3d_tfu"); ++ if (ret) { ++ dev_err(v3d->dev, "Failed to create TFU scheduler: %d.", ++ ret); ++ drm_sched_fini(&v3d->queue[V3D_RENDER].sched); ++ drm_sched_fini(&v3d->queue[V3D_BIN].sched); ++ return ret; ++ } + + return 0; + } +--- a/drivers/gpu/drm/v3d/v3d_trace.h ++++ b/drivers/gpu/drm/v3d/v3d_trace.h +@@ -42,6 +42,26 @@ TRACE_EVENT(v3d_submit_cl, + __entry->ctnqea) + ); + ++TRACE_EVENT(v3d_submit_tfu, ++ TP_PROTO(struct drm_device *dev, ++ uint64_t seqno), ++ TP_ARGS(dev, seqno), ++ ++ TP_STRUCT__entry( ++ __field(u32, dev) ++ __field(u64, seqno) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev->primary->index; ++ __entry->seqno = seqno; ++ ), ++ ++ TP_printk("dev=%u, seqno=%llu", ++ __entry->dev, ++ __entry->seqno) ++); ++ + TRACE_EVENT(v3d_reset_begin, + TP_PROTO(struct drm_device *dev), + TP_ARGS(dev), +--- a/include/uapi/drm/v3d_drm.h ++++ b/include/uapi/drm/v3d_drm.h +@@ -36,6 +36,7 @@ extern "C" { + #define DRM_V3D_MMAP_BO 0x03 + #define DRM_V3D_GET_PARAM 0x04 + #define DRM_V3D_GET_BO_OFFSET 0x05 ++#define DRM_V3D_SUBMIT_TFU 0x06 + + #define DRM_IOCTL_V3D_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CL, struct drm_v3d_submit_cl) + #define DRM_IOCTL_V3D_WAIT_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_WAIT_BO, struct drm_v3d_wait_bo) +@@ -43,6 +44,7 @@ extern "C" { + #define DRM_IOCTL_V3D_MMAP_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_MMAP_BO, struct drm_v3d_mmap_bo) + #define DRM_IOCTL_V3D_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_GET_PARAM, struct drm_v3d_get_param) + #define DRM_IOCTL_V3D_GET_BO_OFFSET DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_GET_BO_OFFSET, struct drm_v3d_get_bo_offset) ++#define DRM_IOCTL_V3D_SUBMIT_TFU DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_TFU, struct drm_v3d_submit_tfu) + + /** + * struct drm_v3d_submit_cl - ioctl argument for submitting commands to the 3D +@@ -169,6 +171,7 @@ enum drm_v3d_param { + DRM_V3D_PARAM_V3D_CORE0_IDENT0, + DRM_V3D_PARAM_V3D_CORE0_IDENT1, + DRM_V3D_PARAM_V3D_CORE0_IDENT2, ++ DRM_V3D_PARAM_SUPPORTS_TFU, + }; + + struct drm_v3d_get_param { +@@ -187,6 +190,28 @@ struct drm_v3d_get_bo_offset { + __u32 offset; + }; + ++struct drm_v3d_submit_tfu { ++ __u32 icfg; ++ __u32 iia; ++ __u32 iis; ++ __u32 ica; ++ __u32 iua; ++ __u32 ioa; ++ __u32 ios; ++ __u32 coef[4]; ++ /* First handle is the output BO, following are other inputs. ++ * 0 for unused. ++ */ ++ __u32 bo_handles[4]; ++ /* sync object to block on before running the TFU job. Each TFU ++ * job will execute in the order submitted to its FD. Synchronization ++ * against rendering jobs requires using sync objects. ++ */ ++ __u32 in_sync; ++ /* Sync object to signal when the TFU job is done. */ ++ __u32 out_sync; ++}; ++ + #if defined(__cplusplus) + } + #endif diff --git a/target/linux/brcm2708/patches-4.19/950-0566-drm-v3d-Fix-a-use-after-free-race-accessing-the-sche.patch b/target/linux/brcm2708/patches-4.19/950-0566-drm-v3d-Fix-a-use-after-free-race-accessing-the-sche.patch deleted file mode 100644 index f93ed3af5f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0566-drm-v3d-Fix-a-use-after-free-race-accessing-the-sche.patch +++ /dev/null @@ -1,73 +0,0 @@ -From d66b36c8443b24eab7512467095f7395d01f77de Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 28 Sep 2018 16:21:23 -0700 -Subject: [PATCH 566/703] drm/v3d: Fix a use-after-free race accessing the - scheduler's fences. - -Once we push the job, the scheduler could run it and free it. So, if -we want to reference their fences, we need to grab them before then. -I haven't seen this happen in many days of conformance test runtime, -but let's still close the race. - -Signed-off-by: Eric Anholt -Fixes: 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D V3.x+") -Link: https://patchwork.freedesktop.org/patch/254119/ -Reviewed-by: Boris Brezillon -(cherry picked from commit 34c2c4f632f232ed2fdb66d4e42cc72d322273fe) ---- - drivers/gpu/drm/v3d/v3d_drv.h | 5 +++++ - drivers/gpu/drm/v3d/v3d_gem.c | 8 ++++++-- - 2 files changed, 11 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_drv.h -+++ b/drivers/gpu/drm/v3d/v3d_drv.h -@@ -198,6 +198,11 @@ struct v3d_exec_info { - */ - struct dma_fence *bin_done_fence; - -+ /* Fence for when the scheduler considers the render to be -+ * done, for when the BOs reservations should be complete. -+ */ -+ struct dma_fence *render_done_fence; -+ - struct kref refcount; - - /* This is the array of BOs that were looked up at the start of exec. */ ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -209,7 +209,7 @@ v3d_flush_caches(struct v3d_dev *v3d) - static void - v3d_attach_object_fences(struct v3d_exec_info *exec) - { -- struct dma_fence *out_fence = &exec->render.base.s_fence->finished; -+ struct dma_fence *out_fence = exec->render_done_fence; - struct v3d_bo *bo; - int i; - -@@ -409,6 +409,7 @@ v3d_exec_cleanup(struct kref *ref) - dma_fence_put(exec->render.done_fence); - - dma_fence_put(exec->bin_done_fence); -+ dma_fence_put(exec->render_done_fence); - - for (i = 0; i < exec->bo_count; i++) - drm_gem_object_put_unlocked(&exec->bo[i]->base); -@@ -572,6 +573,9 @@ v3d_submit_cl_ioctl(struct drm_device *d - if (ret) - goto fail_unreserve; - -+ exec->render_done_fence = -+ dma_fence_get(&exec->render.base.s_fence->finished); -+ - kref_get(&exec->refcount); /* put by scheduler job completion */ - drm_sched_entity_push_job(&exec->render.base, - &v3d_priv->sched_entity[V3D_RENDER]); -@@ -585,7 +589,7 @@ v3d_submit_cl_ioctl(struct drm_device *d - sync_out = drm_syncobj_find(file_priv, args->out_sync); - if (sync_out) { - drm_syncobj_replace_fence(sync_out, -- &exec->render.base.s_fence->finished); -+ exec->render_done_fence); - drm_syncobj_put(sync_out); - } - diff --git a/target/linux/brcm2708/patches-4.19/950-0567-drm-v3d-Add-a-little-debugfs-entry-for-measuring-the.patch b/target/linux/brcm2708/patches-4.19/950-0567-drm-v3d-Add-a-little-debugfs-entry-for-measuring-the.patch deleted file mode 100644 index eb87107d4c..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0567-drm-v3d-Add-a-little-debugfs-entry-for-measuring-the.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 50ecde652603895b0b0e22de62be36be47b83ab2 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 28 Sep 2018 16:21:24 -0700 -Subject: [PATCH 567/703] drm/v3d: Add a little debugfs entry for measuring the - core clock. - -This adds just enough performance counter support to measure the -clock. We don't have linux kernel drivers for the clock driving the -HW, and this was useful for determining that the V3D HW is running on -a slow clock, not that the driver was slow. - -Signed-off-by: Eric Anholt -Link: https://patchwork.freedesktop.org/patch/msgid/20180928232126.4332-2-eric@anholt.net -Reviewed-by: Boris Brezillon -(cherry picked from commit 6915c9a525e575732429c22b28eb11871a29374b) ---- - drivers/gpu/drm/v3d/v3d_debugfs.c | 35 +++++++++++++++++++++++++++++++ - drivers/gpu/drm/v3d/v3d_regs.h | 30 ++++++++++++++++++++++++++ - 2 files changed, 65 insertions(+) - ---- a/drivers/gpu/drm/v3d/v3d_debugfs.c -+++ b/drivers/gpu/drm/v3d/v3d_debugfs.c -@@ -179,9 +179,44 @@ static int v3d_debugfs_bo_stats(struct s - return 0; - } - -+static int v3d_measure_clock(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 v3d_dev *v3d = to_v3d_dev(dev); -+ uint32_t cycles; -+ int core = 0; -+ int measure_ms = 1000; -+ -+ if (v3d->ver >= 40) { -+ V3D_CORE_WRITE(core, V3D_V4_PCTR_0_SRC_0_3, -+ V3D_SET_FIELD(V3D_PCTR_CYCLE_COUNT, -+ V3D_PCTR_S0)); -+ V3D_CORE_WRITE(core, V3D_V4_PCTR_0_CLR, 1); -+ V3D_CORE_WRITE(core, V3D_V4_PCTR_0_EN, 1); -+ } else { -+ V3D_CORE_WRITE(core, V3D_V3_PCTR_0_PCTRS0, -+ V3D_PCTR_CYCLE_COUNT); -+ V3D_CORE_WRITE(core, V3D_V3_PCTR_0_CLR, 1); -+ V3D_CORE_WRITE(core, V3D_V3_PCTR_0_EN, -+ V3D_V3_PCTR_0_EN_ENABLE | -+ 1); -+ } -+ msleep(measure_ms); -+ cycles = V3D_CORE_READ(core, V3D_PCTR_0_PCTR0); -+ -+ seq_printf(m, "cycles: %d (%d.%d Mhz)\n", -+ cycles, -+ cycles / (measure_ms * 1000), -+ (cycles / (measure_ms * 100)) % 10); -+ -+ return 0; -+} -+ - static const struct drm_info_list v3d_debugfs_list[] = { - {"v3d_ident", v3d_v3d_debugfs_ident, 0}, - {"v3d_regs", v3d_v3d_debugfs_regs, 0}, -+ {"measure_clock", v3d_measure_clock, 0}, - {"bo_stats", v3d_debugfs_bo_stats, 0}, - }; - ---- a/drivers/gpu/drm/v3d/v3d_regs.h -+++ b/drivers/gpu/drm/v3d/v3d_regs.h -@@ -267,6 +267,36 @@ - # define V3D_PTB_BXCF_RWORDERDISA BIT(1) - # define V3D_PTB_BXCF_CLIPDISA BIT(0) - -+#define V3D_V3_PCTR_0_EN 0x00674 -+#define V3D_V3_PCTR_0_EN_ENABLE BIT(31) -+#define V3D_V4_PCTR_0_EN 0x00650 -+/* When a bit is set, resets the counter to 0. */ -+#define V3D_V3_PCTR_0_CLR 0x00670 -+#define V3D_V4_PCTR_0_CLR 0x00654 -+#define V3D_PCTR_0_OVERFLOW 0x00658 -+ -+#define V3D_V3_PCTR_0_PCTRS0 0x00684 -+#define V3D_V3_PCTR_0_PCTRS15 0x00660 -+#define V3D_V3_PCTR_0_PCTRSX(x) (V3D_V3_PCTR_0_PCTRS0 + \ -+ 4 * (x)) -+/* Each src reg muxes four counters each. */ -+#define V3D_V4_PCTR_0_SRC_0_3 0x00660 -+#define V3D_V4_PCTR_0_SRC_28_31 0x0067c -+# define V3D_PCTR_S0_MASK V3D_MASK(6, 0) -+# define V3D_PCTR_S0_SHIFT 0 -+# define V3D_PCTR_S1_MASK V3D_MASK(14, 8) -+# define V3D_PCTR_S1_SHIFT 8 -+# define V3D_PCTR_S2_MASK V3D_MASK(22, 16) -+# define V3D_PCTR_S2_SHIFT 16 -+# define V3D_PCTR_S3_MASK V3D_MASK(30, 24) -+# define V3D_PCTR_S3_SHIFT 24 -+# define V3D_PCTR_CYCLE_COUNT 32 -+ -+/* Output values of the counters. */ -+#define V3D_PCTR_0_PCTR0 0x00680 -+#define V3D_PCTR_0_PCTR31 0x006fc -+#define V3D_PCTR_0_PCTRX(x) (V3D_PCTR_0_PCTR0 + \ -+ 4 * (x)) - #define V3D_GMP_STATUS 0x00800 - # define V3D_GMP_STATUS_GMPRST BIT(31) - # define V3D_GMP_STATUS_WR_COUNT_MASK V3D_MASK(30, 24) diff --git a/target/linux/brcm2708/patches-4.19/950-0567-drm-v3d-Drop-the-dev-argument-to-lock-unlock-of-BO-r.patch b/target/linux/brcm2708/patches-4.19/950-0567-drm-v3d-Drop-the-dev-argument-to-lock-unlock-of-BO-r.patch new file mode 100644 index 0000000000..a9f87f706d --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0567-drm-v3d-Drop-the-dev-argument-to-lock-unlock-of-BO-r.patch @@ -0,0 +1,102 @@ +From bf4cf0eca83106426162a548d788b1e2102e72bd Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 28 Nov 2018 15:09:26 -0800 +Subject: [PATCH 567/725] drm/v3d: Drop the "dev" argument to lock/unlock of BO + reservations. + +They were unused, as Dave Emett noticed in TFU review. + +Signed-off-by: Eric Anholt +Cc: Dave Emett +Link: https://patchwork.freedesktop.org/patch/msgid/20181128230927.10951-2-eric@anholt.net +Reviewed-by: Daniel Vetter +(cherry picked from commit e14a07fc4b961a75f6c275d6bd670ba54fbdae14) +--- + drivers/gpu/drm/v3d/v3d_gem.c | 20 +++++++++----------- + 1 file changed, 9 insertions(+), 11 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -219,8 +219,7 @@ v3d_attach_object_fences(struct v3d_bo * + } + + static void +-v3d_unlock_bo_reservations(struct drm_device *dev, +- struct v3d_bo **bos, ++v3d_unlock_bo_reservations(struct v3d_bo **bos, + int bo_count, + struct ww_acquire_ctx *acquire_ctx) + { +@@ -240,8 +239,7 @@ v3d_unlock_bo_reservations(struct drm_de + * to v3d, so we don't attach dma-buf fences to them. + */ + static int +-v3d_lock_bo_reservations(struct drm_device *dev, +- struct v3d_bo **bos, ++v3d_lock_bo_reservations(struct v3d_bo **bos, + int bo_count, + struct ww_acquire_ctx *acquire_ctx) + { +@@ -298,7 +296,7 @@ retry: + for (i = 0; i < bo_count; i++) { + ret = reservation_object_reserve_shared(bos[i]->resv); + if (ret) { +- v3d_unlock_bo_reservations(dev, bos, bo_count, ++ v3d_unlock_bo_reservations(bos, bo_count, + acquire_ctx); + return ret; + } +@@ -566,7 +564,7 @@ v3d_submit_cl_ioctl(struct drm_device *d + if (ret) + goto fail; + +- ret = v3d_lock_bo_reservations(dev, exec->bo, exec->bo_count, ++ ret = v3d_lock_bo_reservations(exec->bo, exec->bo_count, + &acquire_ctx); + if (ret) + goto fail; +@@ -604,7 +602,7 @@ v3d_submit_cl_ioctl(struct drm_device *d + v3d_attach_object_fences(exec->bo, exec->bo_count, + exec->render_done_fence); + +- v3d_unlock_bo_reservations(dev, exec->bo, exec->bo_count, &acquire_ctx); ++ v3d_unlock_bo_reservations(exec->bo, exec->bo_count, &acquire_ctx); + + /* Update the return sync object for the */ + sync_out = drm_syncobj_find(file_priv, args->out_sync); +@@ -620,7 +618,7 @@ v3d_submit_cl_ioctl(struct drm_device *d + + fail_unreserve: + mutex_unlock(&v3d->sched_lock); +- v3d_unlock_bo_reservations(dev, exec->bo, exec->bo_count, &acquire_ctx); ++ v3d_unlock_bo_reservations(exec->bo, exec->bo_count, &acquire_ctx); + fail: + v3d_exec_put(exec); + +@@ -691,7 +689,7 @@ v3d_submit_tfu_ioctl(struct drm_device * + } + spin_unlock(&file_priv->table_lock); + +- ret = v3d_lock_bo_reservations(dev, job->bo, bo_count, &acquire_ctx); ++ ret = v3d_lock_bo_reservations(job->bo, bo_count, &acquire_ctx); + if (ret) + goto fail; + +@@ -710,7 +708,7 @@ v3d_submit_tfu_ioctl(struct drm_device * + + v3d_attach_object_fences(job->bo, bo_count, sched_done_fence); + +- v3d_unlock_bo_reservations(dev, job->bo, bo_count, &acquire_ctx); ++ v3d_unlock_bo_reservations(job->bo, bo_count, &acquire_ctx); + + /* Update the return sync object */ + sync_out = drm_syncobj_find(file_priv, args->out_sync); +@@ -726,7 +724,7 @@ v3d_submit_tfu_ioctl(struct drm_device * + + fail_unreserve: + mutex_unlock(&v3d->sched_lock); +- v3d_unlock_bo_reservations(dev, job->bo, bo_count, &acquire_ctx); ++ v3d_unlock_bo_reservations(job->bo, bo_count, &acquire_ctx); + fail: + v3d_tfu_job_put(job); + diff --git a/target/linux/brcm2708/patches-4.19/950-0568-drm-v3d-Add-missing-fence-timeline-name-for-TFU.patch b/target/linux/brcm2708/patches-4.19/950-0568-drm-v3d-Add-missing-fence-timeline-name-for-TFU.patch new file mode 100644 index 0000000000..8277aa9327 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0568-drm-v3d-Add-missing-fence-timeline-name-for-TFU.patch @@ -0,0 +1,37 @@ +From 14952ee8c73b05a062d1b7682a5919c5f0833a54 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Fri, 30 Nov 2018 16:57:59 -0800 +Subject: [PATCH 568/725] drm/v3d: Add missing fence timeline name for TFU. + +We shouldn't be returning v3d-render for our new queue. + +Signed-off-by: Eric Anholt +Fixes: 83d5139982db ("drm/v3d: Add support for submitting jobs to the TFU.") +Link: https://patchwork.freedesktop.org/patch/msgid/20181201005759.28093-6-eric@anholt.net +Reviewed-by: Dave Emett +(cherry picked from commit db176f6ba1da39ad0016c77b9775a6bb3d0ce88a) +--- + drivers/gpu/drm/v3d/v3d_fence.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_fence.c ++++ b/drivers/gpu/drm/v3d/v3d_fence.c +@@ -29,10 +29,16 @@ static const char *v3d_fence_get_timelin + { + struct v3d_fence *f = to_v3d_fence(fence); + +- if (f->queue == V3D_BIN) ++ switch (f->queue) { ++ case V3D_BIN: + return "v3d-bin"; +- else ++ case V3D_RENDER: + return "v3d-render"; ++ case V3D_TFU: ++ return "v3d-tfu"; ++ default: ++ return NULL; ++ } + } + + const struct dma_fence_ops v3d_fence_ops = { diff --git a/target/linux/brcm2708/patches-4.19/950-0568-drm-v3d-Update-a-comment-about-what-uses-v3d_job_dep.patch b/target/linux/brcm2708/patches-4.19/950-0568-drm-v3d-Update-a-comment-about-what-uses-v3d_job_dep.patch deleted file mode 100644 index 71228de3da..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0568-drm-v3d-Update-a-comment-about-what-uses-v3d_job_dep.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 1ab9b7689ae0ba9d1f31c5da609004aa8c61a9ed Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 8 Nov 2018 08:16:52 -0800 -Subject: [PATCH 568/703] drm/v3d: Update a comment about what uses - v3d_job_dependency(). - -I merged bin and render's paths in a late refactoring. - -Signed-off-by: Eric Anholt -Link: https://patchwork.freedesktop.org/patch/msgid/20181108161654.19888-3-eric@anholt.net -Reviewed-by: Boris Brezillon -(cherry picked from commit e90e45f6bd45cc494a6f4cd1853c5e7cd4be7f68) ---- - drivers/gpu/drm/v3d/v3d_sched.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/gpu/drm/v3d/v3d_sched.c -+++ b/drivers/gpu/drm/v3d/v3d_sched.c -@@ -39,7 +39,7 @@ v3d_job_free(struct drm_sched_job *sched - } - - /** -- * Returns the fences that the bin job depends on, one by one. -+ * Returns the fences that the bin or render job depends on, one by one. - * v3d_job_run() won't be called until all of them have been signaled. - */ - static struct dma_fence * diff --git a/target/linux/brcm2708/patches-4.19/950-0569-drm-v3d-Add-more-tracepoints-for-V3D-GPU-rendering.patch b/target/linux/brcm2708/patches-4.19/950-0569-drm-v3d-Add-more-tracepoints-for-V3D-GPU-rendering.patch new file mode 100644 index 0000000000..57c21150b8 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0569-drm-v3d-Add-more-tracepoints-for-V3D-GPU-rendering.patch @@ -0,0 +1,205 @@ +From 5a2fcd01c138ce8bca696ca5c785290121cd4f93 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Fri, 30 Nov 2018 16:57:58 -0800 +Subject: [PATCH 569/725] drm/v3d: Add more tracepoints for V3D GPU rendering. + +The core scheduler tells us when the job is pushed to the scheduler's +queue, and I had the job_run functions saying when they actually queue +the job to the hardware. By adding tracepoints for the very top of +the ioctls and the IRQs signaling job completion, "perf record -a -e +v3d:.\* -e gpu_scheduler:.\* ; perf script" gets you a pretty +decent timeline. + +Signed-off-by: Eric Anholt +Link: https://patchwork.freedesktop.org/patch/msgid/20181201005759.28093-5-eric@anholt.net +Reviewed-by: Dave Emett +(cherry picked from commit 55a9b74846ed5e6219c7d81a8e1bf96f25d8ad5e) +--- + drivers/gpu/drm/v3d/v3d_gem.c | 4 ++ + drivers/gpu/drm/v3d/v3d_irq.c | 19 +++++- + drivers/gpu/drm/v3d/v3d_trace.h | 101 ++++++++++++++++++++++++++++++++ + 3 files changed, 121 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -521,6 +521,8 @@ v3d_submit_cl_ioctl(struct drm_device *d + struct drm_syncobj *sync_out; + int ret = 0; + ++ trace_v3d_submit_cl_ioctl(&v3d->drm, args->rcl_start, args->rcl_end); ++ + if (args->pad != 0) { + DRM_INFO("pad must be zero: %d\n", args->pad); + return -EINVAL; +@@ -648,6 +650,8 @@ v3d_submit_tfu_ioctl(struct drm_device * + int ret = 0; + int bo_count; + ++ trace_v3d_submit_tfu_ioctl(&v3d->drm, args->iia); ++ + job = kcalloc(1, sizeof(*job), GFP_KERNEL); + if (!job) + return -ENOMEM; +--- a/drivers/gpu/drm/v3d/v3d_irq.c ++++ b/drivers/gpu/drm/v3d/v3d_irq.c +@@ -15,6 +15,7 @@ + + #include "v3d_drv.h" + #include "v3d_regs.h" ++#include "v3d_trace.h" + + #define V3D_CORE_IRQS ((u32)(V3D_INT_OUTOMEM | \ + V3D_INT_FLDONE | \ +@@ -88,12 +89,20 @@ v3d_irq(int irq, void *arg) + } + + if (intsts & V3D_INT_FLDONE) { +- dma_fence_signal(v3d->bin_job->bin.done_fence); ++ struct v3d_fence *fence = ++ to_v3d_fence(v3d->bin_job->bin.done_fence); ++ ++ trace_v3d_bcl_irq(&v3d->drm, fence->seqno); ++ dma_fence_signal(&fence->base); + status = IRQ_HANDLED; + } + + if (intsts & V3D_INT_FRDONE) { +- dma_fence_signal(v3d->render_job->render.done_fence); ++ struct v3d_fence *fence = ++ to_v3d_fence(v3d->render_job->render.done_fence); ++ ++ trace_v3d_rcl_irq(&v3d->drm, fence->seqno); ++ dma_fence_signal(&fence->base); + status = IRQ_HANDLED; + } + +@@ -119,7 +128,11 @@ v3d_hub_irq(int irq, void *arg) + V3D_WRITE(V3D_HUB_INT_CLR, intsts); + + if (intsts & V3D_HUB_INT_TFUC) { +- dma_fence_signal(v3d->tfu_job->done_fence); ++ struct v3d_fence *fence = ++ to_v3d_fence(v3d->tfu_job->done_fence); ++ ++ trace_v3d_tfu_irq(&v3d->drm, fence->seqno); ++ dma_fence_signal(&fence->base); + status = IRQ_HANDLED; + } + +--- a/drivers/gpu/drm/v3d/v3d_trace.h ++++ b/drivers/gpu/drm/v3d/v3d_trace.h +@@ -12,6 +12,28 @@ + #define TRACE_SYSTEM v3d + #define TRACE_INCLUDE_FILE v3d_trace + ++TRACE_EVENT(v3d_submit_cl_ioctl, ++ TP_PROTO(struct drm_device *dev, u32 ct1qba, u32 ct1qea), ++ TP_ARGS(dev, ct1qba, ct1qea), ++ ++ TP_STRUCT__entry( ++ __field(u32, dev) ++ __field(u32, ct1qba) ++ __field(u32, ct1qea) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev->primary->index; ++ __entry->ct1qba = ct1qba; ++ __entry->ct1qea = ct1qea; ++ ), ++ ++ TP_printk("dev=%u, RCL 0x%08x..0x%08x", ++ __entry->dev, ++ __entry->ct1qba, ++ __entry->ct1qea) ++); ++ + TRACE_EVENT(v3d_submit_cl, + TP_PROTO(struct drm_device *dev, bool is_render, + uint64_t seqno, +@@ -42,6 +64,85 @@ TRACE_EVENT(v3d_submit_cl, + __entry->ctnqea) + ); + ++TRACE_EVENT(v3d_bcl_irq, ++ TP_PROTO(struct drm_device *dev, ++ uint64_t seqno), ++ TP_ARGS(dev, seqno), ++ ++ TP_STRUCT__entry( ++ __field(u32, dev) ++ __field(u64, seqno) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev->primary->index; ++ __entry->seqno = seqno; ++ ), ++ ++ TP_printk("dev=%u, seqno=%llu", ++ __entry->dev, ++ __entry->seqno) ++); ++ ++TRACE_EVENT(v3d_rcl_irq, ++ TP_PROTO(struct drm_device *dev, ++ uint64_t seqno), ++ TP_ARGS(dev, seqno), ++ ++ TP_STRUCT__entry( ++ __field(u32, dev) ++ __field(u64, seqno) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev->primary->index; ++ __entry->seqno = seqno; ++ ), ++ ++ TP_printk("dev=%u, seqno=%llu", ++ __entry->dev, ++ __entry->seqno) ++); ++ ++TRACE_EVENT(v3d_tfu_irq, ++ TP_PROTO(struct drm_device *dev, ++ uint64_t seqno), ++ TP_ARGS(dev, seqno), ++ ++ TP_STRUCT__entry( ++ __field(u32, dev) ++ __field(u64, seqno) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev->primary->index; ++ __entry->seqno = seqno; ++ ), ++ ++ TP_printk("dev=%u, seqno=%llu", ++ __entry->dev, ++ __entry->seqno) ++); ++ ++TRACE_EVENT(v3d_submit_tfu_ioctl, ++ TP_PROTO(struct drm_device *dev, u32 iia), ++ TP_ARGS(dev, iia), ++ ++ TP_STRUCT__entry( ++ __field(u32, dev) ++ __field(u32, iia) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev->primary->index; ++ __entry->iia = iia; ++ ), ++ ++ TP_printk("dev=%u, IIA 0x%08x", ++ __entry->dev, ++ __entry->iia) ++); ++ + TRACE_EVENT(v3d_submit_tfu, + TP_PROTO(struct drm_device *dev, + uint64_t seqno), diff --git a/target/linux/brcm2708/patches-4.19/950-0569-drm-v3d-Clean-up-the-reservation-object-setup.patch b/target/linux/brcm2708/patches-4.19/950-0569-drm-v3d-Clean-up-the-reservation-object-setup.patch deleted file mode 100644 index 4333ac3e7b..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0569-drm-v3d-Clean-up-the-reservation-object-setup.patch +++ /dev/null @@ -1,102 +0,0 @@ -From cdc1e8a4116661a965c1021cd153a8a4fa8eee82 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 8 Nov 2018 08:16:53 -0800 -Subject: [PATCH 569/703] drm/v3d: Clean up the reservation object setup. - -The extra to_v3d_bo() calls came from copying this from the vc4 -driver, which stored the cma gem object in the structs. - -v2: Fix an unused var warning - -Signed-off-by: Eric Anholt -Link: https://patchwork.freedesktop.org/patch/msgid/20181108161654.19888-4-eric@anholt.net -Reviewed-by: Boris Brezillon (v1) -(cherry picked from commit 8f1cd826641d677d0f7494253ecfc3335f0bcd4e) ---- - drivers/gpu/drm/v3d/v3d_gem.c | 33 +++++++++++---------------------- - 1 file changed, 11 insertions(+), 22 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -210,14 +210,11 @@ static void - v3d_attach_object_fences(struct v3d_exec_info *exec) - { - struct dma_fence *out_fence = exec->render_done_fence; -- struct v3d_bo *bo; - int i; - - for (i = 0; i < exec->bo_count; i++) { -- bo = to_v3d_bo(&exec->bo[i]->base); -- - /* XXX: Use shared fences for read-only objects. */ -- reservation_object_add_excl_fence(bo->resv, out_fence); -+ reservation_object_add_excl_fence(exec->bo[i]->resv, out_fence); - } - } - -@@ -228,11 +225,8 @@ v3d_unlock_bo_reservations(struct drm_de - { - int i; - -- for (i = 0; i < exec->bo_count; i++) { -- struct v3d_bo *bo = to_v3d_bo(&exec->bo[i]->base); -- -- ww_mutex_unlock(&bo->resv->lock); -- } -+ for (i = 0; i < exec->bo_count; i++) -+ ww_mutex_unlock(&exec->bo[i]->resv->lock); - - ww_acquire_fini(acquire_ctx); - } -@@ -251,13 +245,13 @@ v3d_lock_bo_reservations(struct drm_devi - { - int contended_lock = -1; - int i, ret; -- struct v3d_bo *bo; - - ww_acquire_init(acquire_ctx, &reservation_ww_class); - - retry: - if (contended_lock != -1) { -- bo = to_v3d_bo(&exec->bo[contended_lock]->base); -+ struct v3d_bo *bo = exec->bo[contended_lock]; -+ - ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock, - acquire_ctx); - if (ret) { -@@ -270,19 +264,16 @@ retry: - if (i == contended_lock) - continue; - -- bo = to_v3d_bo(&exec->bo[i]->base); -- -- ret = ww_mutex_lock_interruptible(&bo->resv->lock, acquire_ctx); -+ ret = ww_mutex_lock_interruptible(&exec->bo[i]->resv->lock, -+ acquire_ctx); - if (ret) { - int j; - -- for (j = 0; j < i; j++) { -- bo = to_v3d_bo(&exec->bo[j]->base); -- ww_mutex_unlock(&bo->resv->lock); -- } -+ for (j = 0; j < i; j++) -+ ww_mutex_unlock(&exec->bo[j]->resv->lock); - - if (contended_lock != -1 && contended_lock >= i) { -- bo = to_v3d_bo(&exec->bo[contended_lock]->base); -+ struct v3d_bo *bo = exec->bo[contended_lock]; - - ww_mutex_unlock(&bo->resv->lock); - } -@@ -303,9 +294,7 @@ retry: - * before we commit the CL to the hardware. - */ - for (i = 0; i < exec->bo_count; i++) { -- bo = to_v3d_bo(&exec->bo[i]->base); -- -- ret = reservation_object_reserve_shared(bo->resv); -+ ret = reservation_object_reserve_shared(exec->bo[i]->resv); - if (ret) { - v3d_unlock_bo_reservations(dev, exec, acquire_ctx); - return ret; diff --git a/target/linux/brcm2708/patches-4.19/950-0570-drm-v3d-Add-support-for-submitting-jobs-to-the-TFU.patch b/target/linux/brcm2708/patches-4.19/950-0570-drm-v3d-Add-support-for-submitting-jobs-to-the-TFU.patch deleted file mode 100644 index 53c760c4f0..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0570-drm-v3d-Add-support-for-submitting-jobs-to-the-TFU.patch +++ /dev/null @@ -1,802 +0,0 @@ -From 60c65dc612663be7136a19a117cee5d194530600 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Wed, 28 Nov 2018 15:09:25 -0800 -Subject: [PATCH 570/703] drm/v3d: Add support for submitting jobs to the TFU. - -The TFU can copy from raster, UIF, and SAND input images to UIF output -images, with optional mipmap generation. This will certainly be -useful for media EGL image input, but is also useful immediately for -mipmap generation without bogging the V3D core down. - -For now we only run the queue 1 job deep, and don't have any hang -recovery (though I don't think we should need it, with TFU). Queuing -multiple jobs in the HW will require synchronizing the YUV coefficient -regs updates since they don't get FIFOed with the job. - -v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain - why TFU is AUTH, clarify the syncing docs, drop the unused TFU - interrupt regs (you're expected to use the hub's), don't take - &bo->base for NULL bos. -v3: Fix a little whitespace alignment (noticed by checkpatch), rebase - on drm_sched_job_cleanup() changes. - -Signed-off-by: Eric Anholt -Reviewed-by: Dave Emett (v2) -Link: https://patchwork.freedesktop.org/patch/264607/ -(cherry picked from commit 1584f16ca96ef124aad79efa3303cff5f3530e2c) ---- - drivers/gpu/drm/v3d/v3d_drv.c | 15 ++- - drivers/gpu/drm/v3d/v3d_drv.h | 32 +++++- - drivers/gpu/drm/v3d/v3d_gem.c | 178 ++++++++++++++++++++++++++++---- - drivers/gpu/drm/v3d/v3d_irq.c | 12 ++- - drivers/gpu/drm/v3d/v3d_regs.h | 49 +++++++++ - drivers/gpu/drm/v3d/v3d_sched.c | 148 ++++++++++++++++++++++---- - drivers/gpu/drm/v3d/v3d_trace.h | 20 ++++ - include/uapi/drm/v3d_drm.h | 25 +++++ - 8 files changed, 426 insertions(+), 53 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_drv.c -+++ b/drivers/gpu/drm/v3d/v3d_drv.c -@@ -112,10 +112,15 @@ static int v3d_get_param_ioctl(struct dr - return 0; - } - -- /* Any params that aren't just register reads would go here. */ - -- DRM_DEBUG("Unknown parameter %d\n", args->param); -- return -EINVAL; -+ switch (args->param) { -+ case DRM_V3D_PARAM_SUPPORTS_TFU: -+ args->value = 1; -+ return 0; -+ default: -+ DRM_DEBUG("Unknown parameter %d\n", args->param); -+ return -EINVAL; -+ } - } - - static int -@@ -170,7 +175,8 @@ static const struct file_operations v3d_ - /* DRM_AUTH is required on SUBMIT_CL for now, while we don't have GMP - * protection between clients. Note that render nodes would be be - * able to submit CLs that could access BOs from clients authenticated -- * with the master node. -+ * with the master node. The TFU doesn't use the GMP, so it would -+ * need to stay DRM_AUTH until we do buffer size/offset validation. - */ - static const struct drm_ioctl_desc v3d_drm_ioctls[] = { - DRM_IOCTL_DEF_DRV(V3D_SUBMIT_CL, v3d_submit_cl_ioctl, DRM_RENDER_ALLOW | DRM_AUTH), -@@ -179,6 +185,7 @@ static const struct drm_ioctl_desc v3d_d - DRM_IOCTL_DEF_DRV(V3D_MMAP_BO, v3d_mmap_bo_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(V3D_GET_PARAM, v3d_get_param_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(V3D_GET_BO_OFFSET, v3d_get_bo_offset_ioctl, DRM_RENDER_ALLOW), -+ DRM_IOCTL_DEF_DRV(V3D_SUBMIT_TFU, v3d_submit_tfu_ioctl, DRM_RENDER_ALLOW | DRM_AUTH), - }; - - static const struct vm_operations_struct v3d_vm_ops = { ---- a/drivers/gpu/drm/v3d/v3d_drv.h -+++ b/drivers/gpu/drm/v3d/v3d_drv.h -@@ -7,19 +7,18 @@ - #include - #include - #include -+#include "uapi/drm/v3d_drm.h" - - #define GMP_GRANULARITY (128 * 1024) - --/* Enum for each of the V3D queues. We maintain various queue -- * tracking as an array because at some point we'll want to support -- * the TFU (texture formatting unit) as another queue. -- */ -+/* Enum for each of the V3D queues. */ - enum v3d_queue { - V3D_BIN, - V3D_RENDER, -+ V3D_TFU, - }; - --#define V3D_MAX_QUEUES (V3D_RENDER + 1) -+#define V3D_MAX_QUEUES (V3D_TFU + 1) - - struct v3d_queue_state { - struct drm_gpu_scheduler sched; -@@ -68,6 +67,7 @@ struct v3d_dev { - - struct v3d_exec_info *bin_job; - struct v3d_exec_info *render_job; -+ struct v3d_tfu_job *tfu_job; - - struct v3d_queue_state queue[V3D_MAX_QUEUES]; - -@@ -218,6 +218,25 @@ struct v3d_exec_info { - u32 qma, qms, qts; - }; - -+struct v3d_tfu_job { -+ struct drm_sched_job base; -+ -+ struct drm_v3d_submit_tfu args; -+ -+ /* An optional fence userspace can pass in for the job to depend on. */ -+ struct dma_fence *in_fence; -+ -+ /* v3d fence to be signaled by IRQ handler when the job is complete. */ -+ struct dma_fence *done_fence; -+ -+ struct v3d_dev *v3d; -+ -+ struct kref refcount; -+ -+ /* This is the array of BOs that were looked up at the start of exec. */ -+ struct v3d_bo *bo[4]; -+}; -+ - /** - * _wait_for - magic (register) wait macro - * -@@ -281,9 +300,12 @@ int v3d_gem_init(struct drm_device *dev) - void v3d_gem_destroy(struct drm_device *dev); - int v3d_submit_cl_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -+int v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv); - int v3d_wait_bo_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - void v3d_exec_put(struct v3d_exec_info *exec); -+void v3d_tfu_job_put(struct v3d_tfu_job *exec); - void v3d_reset(struct v3d_dev *v3d); - void v3d_invalidate_caches(struct v3d_dev *v3d); - void v3d_flush_caches(struct v3d_dev *v3d); ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -207,26 +207,27 @@ v3d_flush_caches(struct v3d_dev *v3d) - } - - static void --v3d_attach_object_fences(struct v3d_exec_info *exec) -+v3d_attach_object_fences(struct v3d_bo **bos, int bo_count, -+ struct dma_fence *fence) - { -- struct dma_fence *out_fence = exec->render_done_fence; - int i; - -- for (i = 0; i < exec->bo_count; i++) { -+ for (i = 0; i < bo_count; i++) { - /* XXX: Use shared fences for read-only objects. */ -- reservation_object_add_excl_fence(exec->bo[i]->resv, out_fence); -+ reservation_object_add_excl_fence(bos[i]->resv, fence); - } - } - - static void - v3d_unlock_bo_reservations(struct drm_device *dev, -- struct v3d_exec_info *exec, -+ struct v3d_bo **bos, -+ int bo_count, - struct ww_acquire_ctx *acquire_ctx) - { - int i; - -- for (i = 0; i < exec->bo_count; i++) -- ww_mutex_unlock(&exec->bo[i]->resv->lock); -+ for (i = 0; i < bo_count; i++) -+ ww_mutex_unlock(&bos[i]->resv->lock); - - ww_acquire_fini(acquire_ctx); - } -@@ -240,7 +241,8 @@ v3d_unlock_bo_reservations(struct drm_de - */ - static int - v3d_lock_bo_reservations(struct drm_device *dev, -- struct v3d_exec_info *exec, -+ struct v3d_bo **bos, -+ int bo_count, - struct ww_acquire_ctx *acquire_ctx) - { - int contended_lock = -1; -@@ -250,7 +252,7 @@ v3d_lock_bo_reservations(struct drm_devi - - retry: - if (contended_lock != -1) { -- struct v3d_bo *bo = exec->bo[contended_lock]; -+ struct v3d_bo *bo = bos[contended_lock]; - - ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock, - acquire_ctx); -@@ -260,20 +262,20 @@ retry: - } - } - -- for (i = 0; i < exec->bo_count; i++) { -+ for (i = 0; i < bo_count; i++) { - if (i == contended_lock) - continue; - -- ret = ww_mutex_lock_interruptible(&exec->bo[i]->resv->lock, -+ ret = ww_mutex_lock_interruptible(&bos[i]->resv->lock, - acquire_ctx); - if (ret) { - int j; - - for (j = 0; j < i; j++) -- ww_mutex_unlock(&exec->bo[j]->resv->lock); -+ ww_mutex_unlock(&bos[j]->resv->lock); - - if (contended_lock != -1 && contended_lock >= i) { -- struct v3d_bo *bo = exec->bo[contended_lock]; -+ struct v3d_bo *bo = bos[contended_lock]; - - ww_mutex_unlock(&bo->resv->lock); - } -@@ -293,10 +295,11 @@ retry: - /* Reserve space for our shared (read-only) fence references, - * before we commit the CL to the hardware. - */ -- for (i = 0; i < exec->bo_count; i++) { -- ret = reservation_object_reserve_shared(exec->bo[i]->resv); -+ for (i = 0; i < bo_count; i++) { -+ ret = reservation_object_reserve_shared(bos[i]->resv); - if (ret) { -- v3d_unlock_bo_reservations(dev, exec, acquire_ctx); -+ v3d_unlock_bo_reservations(dev, bos, bo_count, -+ acquire_ctx); - return ret; - } - } -@@ -419,6 +422,33 @@ void v3d_exec_put(struct v3d_exec_info * - kref_put(&exec->refcount, v3d_exec_cleanup); - } - -+static void -+v3d_tfu_job_cleanup(struct kref *ref) -+{ -+ struct v3d_tfu_job *job = container_of(ref, struct v3d_tfu_job, -+ refcount); -+ struct v3d_dev *v3d = job->v3d; -+ unsigned int i; -+ -+ dma_fence_put(job->in_fence); -+ dma_fence_put(job->done_fence); -+ -+ for (i = 0; i < ARRAY_SIZE(job->bo); i++) { -+ if (job->bo[i]) -+ drm_gem_object_put_unlocked(&job->bo[i]->base); -+ } -+ -+ pm_runtime_mark_last_busy(v3d->dev); -+ pm_runtime_put_autosuspend(v3d->dev); -+ -+ kfree(job); -+} -+ -+void v3d_tfu_job_put(struct v3d_tfu_job *job) -+{ -+ kref_put(&job->refcount, v3d_tfu_job_cleanup); -+} -+ - int - v3d_wait_bo_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -@@ -536,7 +566,8 @@ v3d_submit_cl_ioctl(struct drm_device *d - if (ret) - goto fail; - -- ret = v3d_lock_bo_reservations(dev, exec, &acquire_ctx); -+ ret = v3d_lock_bo_reservations(dev, exec->bo, exec->bo_count, -+ &acquire_ctx); - if (ret) - goto fail; - -@@ -570,9 +601,10 @@ v3d_submit_cl_ioctl(struct drm_device *d - &v3d_priv->sched_entity[V3D_RENDER]); - mutex_unlock(&v3d->sched_lock); - -- v3d_attach_object_fences(exec); -+ v3d_attach_object_fences(exec->bo, exec->bo_count, -+ exec->render_done_fence); - -- v3d_unlock_bo_reservations(dev, exec, &acquire_ctx); -+ v3d_unlock_bo_reservations(dev, exec->bo, exec->bo_count, &acquire_ctx); - - /* Update the return sync object for the */ - sync_out = drm_syncobj_find(file_priv, args->out_sync); -@@ -588,12 +620,118 @@ v3d_submit_cl_ioctl(struct drm_device *d - - fail_unreserve: - mutex_unlock(&v3d->sched_lock); -- v3d_unlock_bo_reservations(dev, exec, &acquire_ctx); -+ v3d_unlock_bo_reservations(dev, exec->bo, exec->bo_count, &acquire_ctx); - fail: - v3d_exec_put(exec); - - return ret; - } -+ -+/** -+ * v3d_submit_tfu_ioctl() - Submits a TFU (texture formatting) job to the V3D. -+ * @dev: DRM device -+ * @data: ioctl argument -+ * @file_priv: DRM file for this fd -+ * -+ * Userspace provides the register setup for the TFU, which we don't -+ * need to validate since the TFU is behind the MMU. -+ */ -+int -+v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) -+{ -+ struct v3d_dev *v3d = to_v3d_dev(dev); -+ struct v3d_file_priv *v3d_priv = file_priv->driver_priv; -+ struct drm_v3d_submit_tfu *args = data; -+ struct v3d_tfu_job *job; -+ struct ww_acquire_ctx acquire_ctx; -+ struct drm_syncobj *sync_out; -+ struct dma_fence *sched_done_fence; -+ int ret = 0; -+ int bo_count; -+ -+ job = kcalloc(1, sizeof(*job), GFP_KERNEL); -+ if (!job) -+ return -ENOMEM; -+ -+ ret = pm_runtime_get_sync(v3d->dev); -+ if (ret < 0) { -+ kfree(job); -+ return ret; -+ } -+ -+ kref_init(&job->refcount); -+ -+ ret = drm_syncobj_find_fence(file_priv, args->in_sync, -+ 0, &job->in_fence); -+ if (ret == -EINVAL) -+ goto fail; -+ -+ job->args = *args; -+ job->v3d = v3d; -+ -+ spin_lock(&file_priv->table_lock); -+ for (bo_count = 0; bo_count < ARRAY_SIZE(job->bo); bo_count++) { -+ struct drm_gem_object *bo; -+ -+ if (!args->bo_handles[bo_count]) -+ break; -+ -+ bo = idr_find(&file_priv->object_idr, -+ args->bo_handles[bo_count]); -+ if (!bo) { -+ DRM_DEBUG("Failed to look up GEM BO %d: %d\n", -+ bo_count, args->bo_handles[bo_count]); -+ ret = -ENOENT; -+ spin_unlock(&file_priv->table_lock); -+ goto fail; -+ } -+ drm_gem_object_get(bo); -+ job->bo[bo_count] = to_v3d_bo(bo); -+ } -+ spin_unlock(&file_priv->table_lock); -+ -+ ret = v3d_lock_bo_reservations(dev, job->bo, bo_count, &acquire_ctx); -+ if (ret) -+ goto fail; -+ -+ mutex_lock(&v3d->sched_lock); -+ ret = drm_sched_job_init(&job->base, -+ &v3d_priv->sched_entity[V3D_TFU], -+ v3d_priv); -+ if (ret) -+ goto fail_unreserve; -+ -+ sched_done_fence = dma_fence_get(&job->base.s_fence->finished); -+ -+ kref_get(&job->refcount); /* put by scheduler job completion */ -+ drm_sched_entity_push_job(&job->base, &v3d_priv->sched_entity[V3D_TFU]); -+ mutex_unlock(&v3d->sched_lock); -+ -+ v3d_attach_object_fences(job->bo, bo_count, sched_done_fence); -+ -+ v3d_unlock_bo_reservations(dev, job->bo, bo_count, &acquire_ctx); -+ -+ /* Update the return sync object */ -+ sync_out = drm_syncobj_find(file_priv, args->out_sync); -+ if (sync_out) { -+ drm_syncobj_replace_fence(sync_out, sched_done_fence); -+ drm_syncobj_put(sync_out); -+ } -+ dma_fence_put(sched_done_fence); -+ -+ v3d_tfu_job_put(job); -+ -+ return 0; -+ -+fail_unreserve: -+ mutex_unlock(&v3d->sched_lock); -+ v3d_unlock_bo_reservations(dev, job->bo, bo_count, &acquire_ctx); -+fail: -+ v3d_tfu_job_put(job); -+ -+ return ret; -+} - - int - v3d_gem_init(struct drm_device *dev) ---- a/drivers/gpu/drm/v3d/v3d_irq.c -+++ b/drivers/gpu/drm/v3d/v3d_irq.c -@@ -4,8 +4,8 @@ - /** - * DOC: Interrupt management for the V3D engine - * -- * When we take a binning or rendering flush done interrupt, we need -- * to signal the fence for that job so that the scheduler can queue up -+ * When we take a bin, render, or TFU done interrupt, we need to -+ * signal the fence for that job so that the scheduler can queue up - * the next one and unblock any waiters. - * - * When we take the binner out of memory interrupt, we need to -@@ -23,7 +23,8 @@ - - #define V3D_HUB_IRQS ((u32)(V3D_HUB_INT_MMU_WRV | \ - V3D_HUB_INT_MMU_PTI | \ -- V3D_HUB_INT_MMU_CAP)) -+ V3D_HUB_INT_MMU_CAP | \ -+ V3D_HUB_INT_TFUC)) - - static void - v3d_overflow_mem_work(struct work_struct *work) -@@ -117,6 +118,11 @@ v3d_hub_irq(int irq, void *arg) - /* Acknowledge the interrupts we're handling here. */ - V3D_WRITE(V3D_HUB_INT_CLR, intsts); - -+ if (intsts & V3D_HUB_INT_TFUC) { -+ dma_fence_signal(v3d->tfu_job->done_fence); -+ status = IRQ_HANDLED; -+ } -+ - if (intsts & (V3D_HUB_INT_MMU_WRV | - V3D_HUB_INT_MMU_PTI | - V3D_HUB_INT_MMU_CAP)) { ---- a/drivers/gpu/drm/v3d/v3d_regs.h -+++ b/drivers/gpu/drm/v3d/v3d_regs.h -@@ -86,6 +86,55 @@ - # define V3D_TOP_GR_BRIDGE_SW_INIT_1 0x0000c - # define V3D_TOP_GR_BRIDGE_SW_INIT_1_V3D_CLK_108_SW_INIT BIT(0) - -+#define V3D_TFU_CS 0x00400 -+/* Stops current job, empties input fifo. */ -+# define V3D_TFU_CS_TFURST BIT(31) -+# define V3D_TFU_CS_CVTCT_MASK V3D_MASK(23, 16) -+# define V3D_TFU_CS_CVTCT_SHIFT 16 -+# define V3D_TFU_CS_NFREE_MASK V3D_MASK(13, 8) -+# define V3D_TFU_CS_NFREE_SHIFT 8 -+# define V3D_TFU_CS_BUSY BIT(0) -+ -+#define V3D_TFU_SU 0x00404 -+/* Interrupt when FINTTHR input slots are free (0 = disabled) */ -+# define V3D_TFU_SU_FINTTHR_MASK V3D_MASK(13, 8) -+# define V3D_TFU_SU_FINTTHR_SHIFT 8 -+/* Skips resetting the CRC at the start of CRC generation. */ -+# define V3D_TFU_SU_CRCCHAIN BIT(4) -+/* skips writes, computes CRC of the image. miplevels must be 0. */ -+# define V3D_TFU_SU_CRC BIT(3) -+# define V3D_TFU_SU_THROTTLE_MASK V3D_MASK(1, 0) -+# define V3D_TFU_SU_THROTTLE_SHIFT 0 -+ -+#define V3D_TFU_ICFG 0x00408 -+/* Interrupt when the conversion is complete. */ -+# define V3D_TFU_ICFG_IOC BIT(0) -+ -+/* Input Image Address */ -+#define V3D_TFU_IIA 0x0040c -+/* Input Chroma Address */ -+#define V3D_TFU_ICA 0x00410 -+/* Input Image Stride */ -+#define V3D_TFU_IIS 0x00414 -+/* Input Image U-Plane Address */ -+#define V3D_TFU_IUA 0x00418 -+/* Output Image Address */ -+#define V3D_TFU_IOA 0x0041c -+/* Image Output Size */ -+#define V3D_TFU_IOS 0x00420 -+/* TFU YUV Coefficient 0 */ -+#define V3D_TFU_COEF0 0x00424 -+/* Use these regs instead of the defaults. */ -+# define V3D_TFU_COEF0_USECOEF BIT(31) -+/* TFU YUV Coefficient 1 */ -+#define V3D_TFU_COEF1 0x00428 -+/* TFU YUV Coefficient 2 */ -+#define V3D_TFU_COEF2 0x0042c -+/* TFU YUV Coefficient 3 */ -+#define V3D_TFU_COEF3 0x00430 -+ -+#define V3D_TFU_CRC 0x00434 -+ - /* Per-MMU registers. */ - - #define V3D_MMUC_CONTROL 0x01000 ---- a/drivers/gpu/drm/v3d/v3d_sched.c -+++ b/drivers/gpu/drm/v3d/v3d_sched.c -@@ -30,6 +30,12 @@ to_v3d_job(struct drm_sched_job *sched_j - return container_of(sched_job, struct v3d_job, base); - } - -+static struct v3d_tfu_job * -+to_tfu_job(struct drm_sched_job *sched_job) -+{ -+ return container_of(sched_job, struct v3d_tfu_job, base); -+} -+ - static void - v3d_job_free(struct drm_sched_job *sched_job) - { -@@ -38,6 +44,14 @@ v3d_job_free(struct drm_sched_job *sched - v3d_exec_put(job->exec); - } - -+static void -+v3d_tfu_job_free(struct drm_sched_job *sched_job) -+{ -+ struct v3d_tfu_job *job = to_tfu_job(sched_job); -+ -+ v3d_tfu_job_put(job); -+} -+ - /** - * Returns the fences that the bin or render job depends on, one by one. - * v3d_job_run() won't be called until all of them have been signaled. -@@ -76,6 +90,27 @@ v3d_job_dependency(struct drm_sched_job - return fence; - } - -+/** -+ * Returns the fences that the TFU job depends on, one by one. -+ * v3d_tfu_job_run() won't be called until all of them have been -+ * signaled. -+ */ -+static struct dma_fence * -+v3d_tfu_job_dependency(struct drm_sched_job *sched_job, -+ struct drm_sched_entity *s_entity) -+{ -+ struct v3d_tfu_job *job = to_tfu_job(sched_job); -+ struct dma_fence *fence; -+ -+ fence = job->in_fence; -+ if (fence) { -+ job->in_fence = NULL; -+ return fence; -+ } -+ -+ return NULL; -+} -+ - static struct dma_fence *v3d_job_run(struct drm_sched_job *sched_job) - { - struct v3d_job *job = to_v3d_job(sched_job); -@@ -147,31 +182,47 @@ static struct dma_fence *v3d_job_run(str - return fence; - } - --static void --v3d_job_timedout(struct drm_sched_job *sched_job) -+static struct dma_fence * -+v3d_tfu_job_run(struct drm_sched_job *sched_job) - { -- struct v3d_job *job = to_v3d_job(sched_job); -- struct v3d_exec_info *exec = job->exec; -- struct v3d_dev *v3d = exec->v3d; -- enum v3d_queue job_q = job == &exec->bin ? V3D_BIN : V3D_RENDER; -- enum v3d_queue q; -- u32 ctca = V3D_CORE_READ(0, V3D_CLE_CTNCA(job_q)); -- u32 ctra = V3D_CORE_READ(0, V3D_CLE_CTNRA(job_q)); -+ struct v3d_tfu_job *job = to_tfu_job(sched_job); -+ struct v3d_dev *v3d = job->v3d; -+ struct drm_device *dev = &v3d->drm; -+ struct dma_fence *fence; - -- /* If the current address or return address have changed, then -- * the GPU has probably made progress and we should delay the -- * reset. This could fail if the GPU got in an infinite loop -- * in the CL, but that is pretty unlikely outside of an i-g-t -- * testcase. -- */ -- if (job->timedout_ctca != ctca || job->timedout_ctra != ctra) { -- job->timedout_ctca = ctca; -- job->timedout_ctra = ctra; -+ fence = v3d_fence_create(v3d, V3D_TFU); -+ if (IS_ERR(fence)) -+ return NULL; - -- schedule_delayed_work(&job->base.work_tdr, -- job->base.sched->timeout); -- return; -+ v3d->tfu_job = job; -+ if (job->done_fence) -+ dma_fence_put(job->done_fence); -+ job->done_fence = dma_fence_get(fence); -+ -+ trace_v3d_submit_tfu(dev, to_v3d_fence(fence)->seqno); -+ -+ V3D_WRITE(V3D_TFU_IIA, job->args.iia); -+ V3D_WRITE(V3D_TFU_IIS, job->args.iis); -+ V3D_WRITE(V3D_TFU_ICA, job->args.ica); -+ V3D_WRITE(V3D_TFU_IUA, job->args.iua); -+ V3D_WRITE(V3D_TFU_IOA, job->args.ioa); -+ V3D_WRITE(V3D_TFU_IOS, job->args.ios); -+ V3D_WRITE(V3D_TFU_COEF0, job->args.coef[0]); -+ if (job->args.coef[0] & V3D_TFU_COEF0_USECOEF) { -+ V3D_WRITE(V3D_TFU_COEF1, job->args.coef[1]); -+ V3D_WRITE(V3D_TFU_COEF2, job->args.coef[2]); -+ V3D_WRITE(V3D_TFU_COEF3, job->args.coef[3]); - } -+ /* ICFG kicks off the job. */ -+ V3D_WRITE(V3D_TFU_ICFG, job->args.icfg | V3D_TFU_ICFG_IOC); -+ -+ return fence; -+} -+ -+static void -+v3d_gpu_reset_for_timeout(struct v3d_dev *v3d, struct drm_sched_job *sched_job) -+{ -+ enum v3d_queue q; - - mutex_lock(&v3d->reset_lock); - -@@ -196,6 +247,41 @@ v3d_job_timedout(struct drm_sched_job *s - mutex_unlock(&v3d->reset_lock); - } - -+static void -+v3d_job_timedout(struct drm_sched_job *sched_job) -+{ -+ struct v3d_job *job = to_v3d_job(sched_job); -+ struct v3d_exec_info *exec = job->exec; -+ struct v3d_dev *v3d = exec->v3d; -+ enum v3d_queue job_q = job == &exec->bin ? V3D_BIN : V3D_RENDER; -+ u32 ctca = V3D_CORE_READ(0, V3D_CLE_CTNCA(job_q)); -+ u32 ctra = V3D_CORE_READ(0, V3D_CLE_CTNRA(job_q)); -+ -+ /* If the current address or return address have changed, then -+ * the GPU has probably made progress and we should delay the -+ * reset. This could fail if the GPU got in an infinite loop -+ * in the CL, but that is pretty unlikely outside of an i-g-t -+ * testcase. -+ */ -+ if (job->timedout_ctca != ctca || job->timedout_ctra != ctra) { -+ job->timedout_ctca = ctca; -+ job->timedout_ctra = ctra; -+ schedule_delayed_work(&job->base.work_tdr, -+ job->base.sched->timeout); -+ return; -+ } -+ -+ v3d_gpu_reset_for_timeout(v3d, sched_job); -+} -+ -+static void -+v3d_tfu_job_timedout(struct drm_sched_job *sched_job) -+{ -+ struct v3d_tfu_job *job = to_tfu_job(sched_job); -+ -+ v3d_gpu_reset_for_timeout(job->v3d, sched_job); -+} -+ - static const struct drm_sched_backend_ops v3d_sched_ops = { - .dependency = v3d_job_dependency, - .run_job = v3d_job_run, -@@ -203,6 +289,13 @@ static const struct drm_sched_backend_op - .free_job = v3d_job_free - }; - -+static const struct drm_sched_backend_ops v3d_tfu_sched_ops = { -+ .dependency = v3d_tfu_job_dependency, -+ .run_job = v3d_tfu_job_run, -+ .timedout_job = v3d_tfu_job_timedout, -+ .free_job = v3d_tfu_job_free -+}; -+ - int - v3d_sched_init(struct v3d_dev *v3d) - { -@@ -232,6 +325,19 @@ v3d_sched_init(struct v3d_dev *v3d) - drm_sched_fini(&v3d->queue[V3D_BIN].sched); - return ret; - } -+ -+ ret = drm_sched_init(&v3d->queue[V3D_TFU].sched, -+ &v3d_tfu_sched_ops, -+ hw_jobs_limit, job_hang_limit, -+ msecs_to_jiffies(hang_limit_ms), -+ "v3d_tfu"); -+ if (ret) { -+ dev_err(v3d->dev, "Failed to create TFU scheduler: %d.", -+ ret); -+ drm_sched_fini(&v3d->queue[V3D_RENDER].sched); -+ drm_sched_fini(&v3d->queue[V3D_BIN].sched); -+ return ret; -+ } - - return 0; - } ---- a/drivers/gpu/drm/v3d/v3d_trace.h -+++ b/drivers/gpu/drm/v3d/v3d_trace.h -@@ -42,6 +42,26 @@ TRACE_EVENT(v3d_submit_cl, - __entry->ctnqea) - ); - -+TRACE_EVENT(v3d_submit_tfu, -+ TP_PROTO(struct drm_device *dev, -+ uint64_t seqno), -+ TP_ARGS(dev, seqno), -+ -+ TP_STRUCT__entry( -+ __field(u32, dev) -+ __field(u64, seqno) -+ ), -+ -+ TP_fast_assign( -+ __entry->dev = dev->primary->index; -+ __entry->seqno = seqno; -+ ), -+ -+ TP_printk("dev=%u, seqno=%llu", -+ __entry->dev, -+ __entry->seqno) -+); -+ - TRACE_EVENT(v3d_reset_begin, - TP_PROTO(struct drm_device *dev), - TP_ARGS(dev), ---- a/include/uapi/drm/v3d_drm.h -+++ b/include/uapi/drm/v3d_drm.h -@@ -36,6 +36,7 @@ extern "C" { - #define DRM_V3D_MMAP_BO 0x03 - #define DRM_V3D_GET_PARAM 0x04 - #define DRM_V3D_GET_BO_OFFSET 0x05 -+#define DRM_V3D_SUBMIT_TFU 0x06 - - #define DRM_IOCTL_V3D_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CL, struct drm_v3d_submit_cl) - #define DRM_IOCTL_V3D_WAIT_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_WAIT_BO, struct drm_v3d_wait_bo) -@@ -43,6 +44,7 @@ extern "C" { - #define DRM_IOCTL_V3D_MMAP_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_MMAP_BO, struct drm_v3d_mmap_bo) - #define DRM_IOCTL_V3D_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_GET_PARAM, struct drm_v3d_get_param) - #define DRM_IOCTL_V3D_GET_BO_OFFSET DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_GET_BO_OFFSET, struct drm_v3d_get_bo_offset) -+#define DRM_IOCTL_V3D_SUBMIT_TFU DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_TFU, struct drm_v3d_submit_tfu) - - /** - * struct drm_v3d_submit_cl - ioctl argument for submitting commands to the 3D -@@ -169,6 +171,7 @@ enum drm_v3d_param { - DRM_V3D_PARAM_V3D_CORE0_IDENT0, - DRM_V3D_PARAM_V3D_CORE0_IDENT1, - DRM_V3D_PARAM_V3D_CORE0_IDENT2, -+ DRM_V3D_PARAM_SUPPORTS_TFU, - }; - - struct drm_v3d_get_param { -@@ -187,6 +190,28 @@ struct drm_v3d_get_bo_offset { - __u32 offset; - }; - -+struct drm_v3d_submit_tfu { -+ __u32 icfg; -+ __u32 iia; -+ __u32 iis; -+ __u32 ica; -+ __u32 iua; -+ __u32 ioa; -+ __u32 ios; -+ __u32 coef[4]; -+ /* First handle is the output BO, following are other inputs. -+ * 0 for unused. -+ */ -+ __u32 bo_handles[4]; -+ /* sync object to block on before running the TFU job. Each TFU -+ * job will execute in the order submitted to its FD. Synchronization -+ * against rendering jobs requires using sync objects. -+ */ -+ __u32 in_sync; -+ /* Sync object to signal when the TFU job is done. */ -+ __u32 out_sync; -+}; -+ - #if defined(__cplusplus) - } - #endif diff --git a/target/linux/brcm2708/patches-4.19/950-0570-drm-v3d-Drop-unused-v3d_flush_caches.patch b/target/linux/brcm2708/patches-4.19/950-0570-drm-v3d-Drop-unused-v3d_flush_caches.patch new file mode 100644 index 0000000000..92d739eb08 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0570-drm-v3d-Drop-unused-v3d_flush_caches.patch @@ -0,0 +1,64 @@ +From e8fb9a84012e6c866d1143acf04ca855b05f4241 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 3 Dec 2018 14:24:34 -0800 +Subject: [PATCH 570/725] drm/v3d: Drop unused v3d_flush_caches(). + +Now that I've specified how the end-of-pipeline flushing should work, +we're never going to use this function. + +Signed-off-by: Eric Anholt +Reviewed-by: Dave Emett +Link: https://patchwork.freedesktop.org/patch/msgid/20181203222438.25417-2-eric@anholt.net +(cherry picked from commit 2aa34fd5c7754824cf5488b61ac644f30d3c5c85) +--- + drivers/gpu/drm/v3d/v3d_drv.h | 1 - + drivers/gpu/drm/v3d/v3d_gem.c | 21 --------------------- + 2 files changed, 22 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_drv.h ++++ b/drivers/gpu/drm/v3d/v3d_drv.h +@@ -308,7 +308,6 @@ void v3d_exec_put(struct v3d_exec_info * + void v3d_tfu_job_put(struct v3d_tfu_job *exec); + void v3d_reset(struct v3d_dev *v3d); + void v3d_invalidate_caches(struct v3d_dev *v3d); +-void v3d_flush_caches(struct v3d_dev *v3d); + + /* v3d_irq.c */ + int v3d_irq_init(struct v3d_dev *v3d); +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -175,20 +175,6 @@ v3d_invalidate_slices(struct v3d_dev *v3 + V3D_SET_FIELD(0xf, V3D_SLCACTL_ICC)); + } + +-/* Invalidates texture L2 cachelines */ +-static void +-v3d_invalidate_l2t(struct v3d_dev *v3d, int core) +-{ +- V3D_CORE_WRITE(core, +- V3D_CTL_L2TCACTL, +- V3D_L2TCACTL_L2TFLS | +- V3D_SET_FIELD(V3D_L2TCACTL_FLM_CLEAR, V3D_L2TCACTL_FLM)); +- if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) & +- V3D_L2TCACTL_L2TFLS), 100)) { +- DRM_ERROR("Timeout waiting for L2T invalidate\n"); +- } +-} +- + void + v3d_invalidate_caches(struct v3d_dev *v3d) + { +@@ -199,13 +185,6 @@ v3d_invalidate_caches(struct v3d_dev *v3 + v3d_flush_l2t(v3d, 0); + } + +-void +-v3d_flush_caches(struct v3d_dev *v3d) +-{ +- v3d_invalidate_l1td(v3d, 0); +- v3d_invalidate_l2t(v3d, 0); +-} +- + static void + v3d_attach_object_fences(struct v3d_bo **bos, int bo_count, + struct dma_fence *fence) diff --git a/target/linux/brcm2708/patches-4.19/950-0571-drm-v3d-Don-t-bother-flushing-L1TD-at-job-start.patch b/target/linux/brcm2708/patches-4.19/950-0571-drm-v3d-Don-t-bother-flushing-L1TD-at-job-start.patch new file mode 100644 index 0000000000..37d2fcf37a --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0571-drm-v3d-Don-t-bother-flushing-L1TD-at-job-start.patch @@ -0,0 +1,43 @@ +From d11e738a810d653444f24b81f681cd336e4c9f70 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 3 Dec 2018 14:24:35 -0800 +Subject: [PATCH 571/725] drm/v3d: Don't bother flushing L1TD at job start. + +This is the write combiner for TMU writes. You're supposed to flush +that at job end if you had dirtied any cachelines. Flushing it at job +start then doesn't make any sense. + +Signed-off-by: Eric Anholt +Fixes: 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D V3.x+") +Reviewed-by: Dave Emett +Link: https://patchwork.freedesktop.org/patch/msgid/20181203222438.25417-3-eric@anholt.net +(cherry picked from commit 2e6dc3bd80478212e84addf1cafd6ec60674b884) +--- + drivers/gpu/drm/v3d/v3d_gem.c | 12 ------------ + 1 file changed, 12 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -139,22 +139,10 @@ v3d_invalidate_l2(struct v3d_dev *v3d, i + V3D_L2CACTL_L2CENA); + } + +-static void +-v3d_invalidate_l1td(struct v3d_dev *v3d, int core) +-{ +- V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, V3D_L2TCACTL_TMUWCF); +- if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) & +- V3D_L2TCACTL_L2TFLS), 100)) { +- DRM_ERROR("Timeout waiting for L1T write combiner flush\n"); +- } +-} +- + /* Invalidates texture L2 cachelines */ + static void + v3d_flush_l2t(struct v3d_dev *v3d, int core) + { +- v3d_invalidate_l1td(v3d, core); +- + V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, + V3D_L2TCACTL_L2TFLS | + V3D_SET_FIELD(V3D_L2TCACTL_FLM_FLUSH, V3D_L2TCACTL_FLM)); diff --git a/target/linux/brcm2708/patches-4.19/950-0571-drm-v3d-Drop-the-dev-argument-to-lock-unlock-of-BO-r.patch b/target/linux/brcm2708/patches-4.19/950-0571-drm-v3d-Drop-the-dev-argument-to-lock-unlock-of-BO-r.patch deleted file mode 100644 index 58d9dba4f4..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0571-drm-v3d-Drop-the-dev-argument-to-lock-unlock-of-BO-r.patch +++ /dev/null @@ -1,102 +0,0 @@ -From ee1ef747ef5c088504b541e461d94feadac03bfa Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Wed, 28 Nov 2018 15:09:26 -0800 -Subject: [PATCH 571/703] drm/v3d: Drop the "dev" argument to lock/unlock of BO - reservations. - -They were unused, as Dave Emett noticed in TFU review. - -Signed-off-by: Eric Anholt -Cc: Dave Emett -Link: https://patchwork.freedesktop.org/patch/msgid/20181128230927.10951-2-eric@anholt.net -Reviewed-by: Daniel Vetter -(cherry picked from commit e14a07fc4b961a75f6c275d6bd670ba54fbdae14) ---- - drivers/gpu/drm/v3d/v3d_gem.c | 20 +++++++++----------- - 1 file changed, 9 insertions(+), 11 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -219,8 +219,7 @@ v3d_attach_object_fences(struct v3d_bo * - } - - static void --v3d_unlock_bo_reservations(struct drm_device *dev, -- struct v3d_bo **bos, -+v3d_unlock_bo_reservations(struct v3d_bo **bos, - int bo_count, - struct ww_acquire_ctx *acquire_ctx) - { -@@ -240,8 +239,7 @@ v3d_unlock_bo_reservations(struct drm_de - * to v3d, so we don't attach dma-buf fences to them. - */ - static int --v3d_lock_bo_reservations(struct drm_device *dev, -- struct v3d_bo **bos, -+v3d_lock_bo_reservations(struct v3d_bo **bos, - int bo_count, - struct ww_acquire_ctx *acquire_ctx) - { -@@ -298,7 +296,7 @@ retry: - for (i = 0; i < bo_count; i++) { - ret = reservation_object_reserve_shared(bos[i]->resv); - if (ret) { -- v3d_unlock_bo_reservations(dev, bos, bo_count, -+ v3d_unlock_bo_reservations(bos, bo_count, - acquire_ctx); - return ret; - } -@@ -566,7 +564,7 @@ v3d_submit_cl_ioctl(struct drm_device *d - if (ret) - goto fail; - -- ret = v3d_lock_bo_reservations(dev, exec->bo, exec->bo_count, -+ ret = v3d_lock_bo_reservations(exec->bo, exec->bo_count, - &acquire_ctx); - if (ret) - goto fail; -@@ -604,7 +602,7 @@ v3d_submit_cl_ioctl(struct drm_device *d - v3d_attach_object_fences(exec->bo, exec->bo_count, - exec->render_done_fence); - -- v3d_unlock_bo_reservations(dev, exec->bo, exec->bo_count, &acquire_ctx); -+ v3d_unlock_bo_reservations(exec->bo, exec->bo_count, &acquire_ctx); - - /* Update the return sync object for the */ - sync_out = drm_syncobj_find(file_priv, args->out_sync); -@@ -620,7 +618,7 @@ v3d_submit_cl_ioctl(struct drm_device *d - - fail_unreserve: - mutex_unlock(&v3d->sched_lock); -- v3d_unlock_bo_reservations(dev, exec->bo, exec->bo_count, &acquire_ctx); -+ v3d_unlock_bo_reservations(exec->bo, exec->bo_count, &acquire_ctx); - fail: - v3d_exec_put(exec); - -@@ -691,7 +689,7 @@ v3d_submit_tfu_ioctl(struct drm_device * - } - spin_unlock(&file_priv->table_lock); - -- ret = v3d_lock_bo_reservations(dev, job->bo, bo_count, &acquire_ctx); -+ ret = v3d_lock_bo_reservations(job->bo, bo_count, &acquire_ctx); - if (ret) - goto fail; - -@@ -710,7 +708,7 @@ v3d_submit_tfu_ioctl(struct drm_device * - - v3d_attach_object_fences(job->bo, bo_count, sched_done_fence); - -- v3d_unlock_bo_reservations(dev, job->bo, bo_count, &acquire_ctx); -+ v3d_unlock_bo_reservations(job->bo, bo_count, &acquire_ctx); - - /* Update the return sync object */ - sync_out = drm_syncobj_find(file_priv, args->out_sync); -@@ -726,7 +724,7 @@ v3d_submit_tfu_ioctl(struct drm_device * - - fail_unreserve: - mutex_unlock(&v3d->sched_lock); -- v3d_unlock_bo_reservations(dev, job->bo, bo_count, &acquire_ctx); -+ v3d_unlock_bo_reservations(job->bo, bo_count, &acquire_ctx); - fail: - v3d_tfu_job_put(job); - diff --git a/target/linux/brcm2708/patches-4.19/950-0572-drm-v3d-Add-missing-fence-timeline-name-for-TFU.patch b/target/linux/brcm2708/patches-4.19/950-0572-drm-v3d-Add-missing-fence-timeline-name-for-TFU.patch deleted file mode 100644 index 1253c8b499..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0572-drm-v3d-Add-missing-fence-timeline-name-for-TFU.patch +++ /dev/null @@ -1,37 +0,0 @@ -From ffc2056239de0353374d8eb9d3022542e4ec5208 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 30 Nov 2018 16:57:59 -0800 -Subject: [PATCH 572/703] drm/v3d: Add missing fence timeline name for TFU. - -We shouldn't be returning v3d-render for our new queue. - -Signed-off-by: Eric Anholt -Fixes: 83d5139982db ("drm/v3d: Add support for submitting jobs to the TFU.") -Link: https://patchwork.freedesktop.org/patch/msgid/20181201005759.28093-6-eric@anholt.net -Reviewed-by: Dave Emett -(cherry picked from commit db176f6ba1da39ad0016c77b9775a6bb3d0ce88a) ---- - drivers/gpu/drm/v3d/v3d_fence.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_fence.c -+++ b/drivers/gpu/drm/v3d/v3d_fence.c -@@ -29,10 +29,16 @@ static const char *v3d_fence_get_timelin - { - struct v3d_fence *f = to_v3d_fence(fence); - -- if (f->queue == V3D_BIN) -+ switch (f->queue) { -+ case V3D_BIN: - return "v3d-bin"; -- else -+ case V3D_RENDER: - return "v3d-render"; -+ case V3D_TFU: -+ return "v3d-tfu"; -+ default: -+ return NULL; -+ } - } - - const struct dma_fence_ops v3d_fence_ops = { diff --git a/target/linux/brcm2708/patches-4.19/950-0572-drm-v3d-Drop-the-wait-for-L2T-flush-to-complete.patch b/target/linux/brcm2708/patches-4.19/950-0572-drm-v3d-Drop-the-wait-for-L2T-flush-to-complete.patch new file mode 100644 index 0000000000..30f708f31e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0572-drm-v3d-Drop-the-wait-for-L2T-flush-to-complete.patch @@ -0,0 +1,41 @@ +From be7e9e3b29166df5f2e5a06fc94c2aa07c414c4e Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 3 Dec 2018 14:24:36 -0800 +Subject: [PATCH 572/725] drm/v3d: Drop the wait for L2T flush to complete. + +According to Dave, once you've started an L2T flush, all L2T accesses +will be blocked until the flush completes. This fixes a consistent +3-4ms stall between the ioctl and running the job, and 3DMMES Taiji +goes from 27fps to 110fps. + +v2: Leave a note about why we don't need to wait for completion. + +Signed-off-by: Eric Anholt +Fixes: 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D V3.x+") +Reviewed-by: Dave Emett +Link: https://patchwork.freedesktop.org/patch/msgid/20181203222438.25417-4-eric@anholt.net +(cherry picked from commit 51c1b6f9eb3dbdec91b0e3c89f623e634c996bbb) +--- + drivers/gpu/drm/v3d/v3d_gem.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -143,13 +143,13 @@ v3d_invalidate_l2(struct v3d_dev *v3d, i + static void + v3d_flush_l2t(struct v3d_dev *v3d, int core) + { ++ /* While there is a busy bit (V3D_L2TCACTL_L2TFLS), we don't ++ * need to wait for completion before dispatching the job -- ++ * L2T accesses will be stalled until the flush has completed. ++ */ + V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, + V3D_L2TCACTL_L2TFLS | + V3D_SET_FIELD(V3D_L2TCACTL_FLM_FLUSH, V3D_L2TCACTL_FLM)); +- if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) & +- V3D_L2TCACTL_L2TFLS), 100)) { +- DRM_ERROR("Timeout waiting for L2T flush\n"); +- } + } + + /* Invalidates the slice caches. These are read-only caches. */ diff --git a/target/linux/brcm2708/patches-4.19/950-0573-drm-v3d-Add-more-tracepoints-for-V3D-GPU-rendering.patch b/target/linux/brcm2708/patches-4.19/950-0573-drm-v3d-Add-more-tracepoints-for-V3D-GPU-rendering.patch deleted file mode 100644 index e65066c552..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0573-drm-v3d-Add-more-tracepoints-for-V3D-GPU-rendering.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 5d505c19fc3fce8c17711a53287081e61418a776 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 30 Nov 2018 16:57:58 -0800 -Subject: [PATCH 573/703] drm/v3d: Add more tracepoints for V3D GPU rendering. - -The core scheduler tells us when the job is pushed to the scheduler's -queue, and I had the job_run functions saying when they actually queue -the job to the hardware. By adding tracepoints for the very top of -the ioctls and the IRQs signaling job completion, "perf record -a -e -v3d:.\* -e gpu_scheduler:.\* ; perf script" gets you a pretty -decent timeline. - -Signed-off-by: Eric Anholt -Link: https://patchwork.freedesktop.org/patch/msgid/20181201005759.28093-5-eric@anholt.net -Reviewed-by: Dave Emett -(cherry picked from commit 55a9b74846ed5e6219c7d81a8e1bf96f25d8ad5e) ---- - drivers/gpu/drm/v3d/v3d_gem.c | 4 ++ - drivers/gpu/drm/v3d/v3d_irq.c | 19 +++++- - drivers/gpu/drm/v3d/v3d_trace.h | 101 ++++++++++++++++++++++++++++++++ - 3 files changed, 121 insertions(+), 3 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -521,6 +521,8 @@ v3d_submit_cl_ioctl(struct drm_device *d - struct drm_syncobj *sync_out; - int ret = 0; - -+ trace_v3d_submit_cl_ioctl(&v3d->drm, args->rcl_start, args->rcl_end); -+ - if (args->pad != 0) { - DRM_INFO("pad must be zero: %d\n", args->pad); - return -EINVAL; -@@ -648,6 +650,8 @@ v3d_submit_tfu_ioctl(struct drm_device * - int ret = 0; - int bo_count; - -+ trace_v3d_submit_tfu_ioctl(&v3d->drm, args->iia); -+ - job = kcalloc(1, sizeof(*job), GFP_KERNEL); - if (!job) - return -ENOMEM; ---- a/drivers/gpu/drm/v3d/v3d_irq.c -+++ b/drivers/gpu/drm/v3d/v3d_irq.c -@@ -15,6 +15,7 @@ - - #include "v3d_drv.h" - #include "v3d_regs.h" -+#include "v3d_trace.h" - - #define V3D_CORE_IRQS ((u32)(V3D_INT_OUTOMEM | \ - V3D_INT_FLDONE | \ -@@ -88,12 +89,20 @@ v3d_irq(int irq, void *arg) - } - - if (intsts & V3D_INT_FLDONE) { -- dma_fence_signal(v3d->bin_job->bin.done_fence); -+ struct v3d_fence *fence = -+ to_v3d_fence(v3d->bin_job->bin.done_fence); -+ -+ trace_v3d_bcl_irq(&v3d->drm, fence->seqno); -+ dma_fence_signal(&fence->base); - status = IRQ_HANDLED; - } - - if (intsts & V3D_INT_FRDONE) { -- dma_fence_signal(v3d->render_job->render.done_fence); -+ struct v3d_fence *fence = -+ to_v3d_fence(v3d->render_job->render.done_fence); -+ -+ trace_v3d_rcl_irq(&v3d->drm, fence->seqno); -+ dma_fence_signal(&fence->base); - status = IRQ_HANDLED; - } - -@@ -119,7 +128,11 @@ v3d_hub_irq(int irq, void *arg) - V3D_WRITE(V3D_HUB_INT_CLR, intsts); - - if (intsts & V3D_HUB_INT_TFUC) { -- dma_fence_signal(v3d->tfu_job->done_fence); -+ struct v3d_fence *fence = -+ to_v3d_fence(v3d->tfu_job->done_fence); -+ -+ trace_v3d_tfu_irq(&v3d->drm, fence->seqno); -+ dma_fence_signal(&fence->base); - status = IRQ_HANDLED; - } - ---- a/drivers/gpu/drm/v3d/v3d_trace.h -+++ b/drivers/gpu/drm/v3d/v3d_trace.h -@@ -12,6 +12,28 @@ - #define TRACE_SYSTEM v3d - #define TRACE_INCLUDE_FILE v3d_trace - -+TRACE_EVENT(v3d_submit_cl_ioctl, -+ TP_PROTO(struct drm_device *dev, u32 ct1qba, u32 ct1qea), -+ TP_ARGS(dev, ct1qba, ct1qea), -+ -+ TP_STRUCT__entry( -+ __field(u32, dev) -+ __field(u32, ct1qba) -+ __field(u32, ct1qea) -+ ), -+ -+ TP_fast_assign( -+ __entry->dev = dev->primary->index; -+ __entry->ct1qba = ct1qba; -+ __entry->ct1qea = ct1qea; -+ ), -+ -+ TP_printk("dev=%u, RCL 0x%08x..0x%08x", -+ __entry->dev, -+ __entry->ct1qba, -+ __entry->ct1qea) -+); -+ - TRACE_EVENT(v3d_submit_cl, - TP_PROTO(struct drm_device *dev, bool is_render, - uint64_t seqno, -@@ -42,6 +64,85 @@ TRACE_EVENT(v3d_submit_cl, - __entry->ctnqea) - ); - -+TRACE_EVENT(v3d_bcl_irq, -+ TP_PROTO(struct drm_device *dev, -+ uint64_t seqno), -+ TP_ARGS(dev, seqno), -+ -+ TP_STRUCT__entry( -+ __field(u32, dev) -+ __field(u64, seqno) -+ ), -+ -+ TP_fast_assign( -+ __entry->dev = dev->primary->index; -+ __entry->seqno = seqno; -+ ), -+ -+ TP_printk("dev=%u, seqno=%llu", -+ __entry->dev, -+ __entry->seqno) -+); -+ -+TRACE_EVENT(v3d_rcl_irq, -+ TP_PROTO(struct drm_device *dev, -+ uint64_t seqno), -+ TP_ARGS(dev, seqno), -+ -+ TP_STRUCT__entry( -+ __field(u32, dev) -+ __field(u64, seqno) -+ ), -+ -+ TP_fast_assign( -+ __entry->dev = dev->primary->index; -+ __entry->seqno = seqno; -+ ), -+ -+ TP_printk("dev=%u, seqno=%llu", -+ __entry->dev, -+ __entry->seqno) -+); -+ -+TRACE_EVENT(v3d_tfu_irq, -+ TP_PROTO(struct drm_device *dev, -+ uint64_t seqno), -+ TP_ARGS(dev, seqno), -+ -+ TP_STRUCT__entry( -+ __field(u32, dev) -+ __field(u64, seqno) -+ ), -+ -+ TP_fast_assign( -+ __entry->dev = dev->primary->index; -+ __entry->seqno = seqno; -+ ), -+ -+ TP_printk("dev=%u, seqno=%llu", -+ __entry->dev, -+ __entry->seqno) -+); -+ -+TRACE_EVENT(v3d_submit_tfu_ioctl, -+ TP_PROTO(struct drm_device *dev, u32 iia), -+ TP_ARGS(dev, iia), -+ -+ TP_STRUCT__entry( -+ __field(u32, dev) -+ __field(u32, iia) -+ ), -+ -+ TP_fast_assign( -+ __entry->dev = dev->primary->index; -+ __entry->iia = iia; -+ ), -+ -+ TP_printk("dev=%u, IIA 0x%08x", -+ __entry->dev, -+ __entry->iia) -+); -+ - TRACE_EVENT(v3d_submit_tfu, - TP_PROTO(struct drm_device *dev, - uint64_t seqno), diff --git a/target/linux/brcm2708/patches-4.19/950-0573-drm-v3d-Stop-trying-to-flush-L2C-on-V3D-3.3.patch b/target/linux/brcm2708/patches-4.19/950-0573-drm-v3d-Stop-trying-to-flush-L2C-on-V3D-3.3.patch new file mode 100644 index 0000000000..4a6086fce4 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0573-drm-v3d-Stop-trying-to-flush-L2C-on-V3D-3.3.patch @@ -0,0 +1,45 @@ +From af6319dd15fd5ec3dac4345136ccfb07eb151c63 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 3 Dec 2018 14:24:37 -0800 +Subject: [PATCH 573/725] drm/v3d: Stop trying to flush L2C on V3D 3.3+ + +This cache was replaced with the slice accessing the L2T in the newer +generations. Noted by Dave during review. + +Signed-off-by: Eric Anholt +Link: https://patchwork.freedesktop.org/patch/msgid/20181203222438.25417-5-eric@anholt.net +Reviewed-by: Dave Emett +(cherry picked from commit 7b9d2fe4350a9c12f66ad8cc78c1098226f6c3c2) +--- + drivers/gpu/drm/v3d/v3d_gem.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -130,10 +130,15 @@ v3d_flush_l3(struct v3d_dev *v3d) + } + } + +-/* Invalidates the (read-only) L2 cache. */ ++/* Invalidates the (read-only) L2C cache. This was the L2 cache for ++ * uniforms and instructions on V3D 3.2. ++ */ + static void +-v3d_invalidate_l2(struct v3d_dev *v3d, int core) ++v3d_invalidate_l2c(struct v3d_dev *v3d, int core) + { ++ if (v3d->ver > 32) ++ return; ++ + V3D_CORE_WRITE(core, V3D_CTL_L2CACTL, + V3D_L2CACTL_L2CCLR | + V3D_L2CACTL_L2CENA); +@@ -168,7 +173,7 @@ v3d_invalidate_caches(struct v3d_dev *v3 + { + v3d_flush_l3(v3d); + +- v3d_invalidate_l2(v3d, 0); ++ v3d_invalidate_l2c(v3d, 0); + v3d_invalidate_slices(v3d, 0); + v3d_flush_l2t(v3d, 0); + } diff --git a/target/linux/brcm2708/patches-4.19/950-0574-drm-v3d-Drop-unused-v3d_flush_caches.patch b/target/linux/brcm2708/patches-4.19/950-0574-drm-v3d-Drop-unused-v3d_flush_caches.patch deleted file mode 100644 index 74d060a3e8..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0574-drm-v3d-Drop-unused-v3d_flush_caches.patch +++ /dev/null @@ -1,64 +0,0 @@ -From b9b60a044a52d5de6e9bc6c6703e2ac8cb7cc9c5 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 3 Dec 2018 14:24:34 -0800 -Subject: [PATCH 574/703] drm/v3d: Drop unused v3d_flush_caches(). - -Now that I've specified how the end-of-pipeline flushing should work, -we're never going to use this function. - -Signed-off-by: Eric Anholt -Reviewed-by: Dave Emett -Link: https://patchwork.freedesktop.org/patch/msgid/20181203222438.25417-2-eric@anholt.net -(cherry picked from commit 2aa34fd5c7754824cf5488b61ac644f30d3c5c85) ---- - drivers/gpu/drm/v3d/v3d_drv.h | 1 - - drivers/gpu/drm/v3d/v3d_gem.c | 21 --------------------- - 2 files changed, 22 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_drv.h -+++ b/drivers/gpu/drm/v3d/v3d_drv.h -@@ -308,7 +308,6 @@ void v3d_exec_put(struct v3d_exec_info * - void v3d_tfu_job_put(struct v3d_tfu_job *exec); - void v3d_reset(struct v3d_dev *v3d); - void v3d_invalidate_caches(struct v3d_dev *v3d); --void v3d_flush_caches(struct v3d_dev *v3d); - - /* v3d_irq.c */ - int v3d_irq_init(struct v3d_dev *v3d); ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -175,20 +175,6 @@ v3d_invalidate_slices(struct v3d_dev *v3 - V3D_SET_FIELD(0xf, V3D_SLCACTL_ICC)); - } - --/* Invalidates texture L2 cachelines */ --static void --v3d_invalidate_l2t(struct v3d_dev *v3d, int core) --{ -- V3D_CORE_WRITE(core, -- V3D_CTL_L2TCACTL, -- V3D_L2TCACTL_L2TFLS | -- V3D_SET_FIELD(V3D_L2TCACTL_FLM_CLEAR, V3D_L2TCACTL_FLM)); -- if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) & -- V3D_L2TCACTL_L2TFLS), 100)) { -- DRM_ERROR("Timeout waiting for L2T invalidate\n"); -- } --} -- - void - v3d_invalidate_caches(struct v3d_dev *v3d) - { -@@ -199,13 +185,6 @@ v3d_invalidate_caches(struct v3d_dev *v3 - v3d_flush_l2t(v3d, 0); - } - --void --v3d_flush_caches(struct v3d_dev *v3d) --{ -- v3d_invalidate_l1td(v3d, 0); -- v3d_invalidate_l2t(v3d, 0); --} -- - static void - v3d_attach_object_fences(struct v3d_bo **bos, int bo_count, - struct dma_fence *fence) diff --git a/target/linux/brcm2708/patches-4.19/950-0574-drm-v3d-Invalidate-the-caches-from-the-outside-in.patch b/target/linux/brcm2708/patches-4.19/950-0574-drm-v3d-Invalidate-the-caches-from-the-outside-in.patch new file mode 100644 index 0000000000..9a6114a983 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0574-drm-v3d-Invalidate-the-caches-from-the-outside-in.patch @@ -0,0 +1,36 @@ +From 1b56cdcccd969ef80f4bf87ca0ef637ca5afc6cc Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 3 Dec 2018 14:24:38 -0800 +Subject: [PATCH 574/725] drm/v3d: Invalidate the caches from the outside in. + +This would be a fairly obscure race, but let's make sure we don't ever +lose it. + +Signed-off-by: Eric Anholt +Link: https://patchwork.freedesktop.org/patch/msgid/20181203222438.25417-6-eric@anholt.net +Reviewed-by: Dave Emett +(cherry picked from commit aa5beec32e8b78bfcf621e3c3daebfb1644b6365) +--- + drivers/gpu/drm/v3d/v3d_gem.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -171,11 +171,15 @@ v3d_invalidate_slices(struct v3d_dev *v3 + void + v3d_invalidate_caches(struct v3d_dev *v3d) + { ++ /* Invalidate the caches from the outside in. That way if ++ * another CL's concurrent use of nearby memory were to pull ++ * an invalidated cacheline back in, we wouldn't leave stale ++ * data in the inner cache. ++ */ + v3d_flush_l3(v3d); +- + v3d_invalidate_l2c(v3d, 0); +- v3d_invalidate_slices(v3d, 0); + v3d_flush_l2t(v3d, 0); ++ v3d_invalidate_slices(v3d, 0); + } + + static void diff --git a/target/linux/brcm2708/patches-4.19/950-0575-drm-v3d-Don-t-bother-flushing-L1TD-at-job-start.patch b/target/linux/brcm2708/patches-4.19/950-0575-drm-v3d-Don-t-bother-flushing-L1TD-at-job-start.patch deleted file mode 100644 index 2070a71863..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0575-drm-v3d-Don-t-bother-flushing-L1TD-at-job-start.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 7b8186de594a27954c909cd8a9ad1ac2cc27a526 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 3 Dec 2018 14:24:35 -0800 -Subject: [PATCH 575/703] drm/v3d: Don't bother flushing L1TD at job start. - -This is the write combiner for TMU writes. You're supposed to flush -that at job end if you had dirtied any cachelines. Flushing it at job -start then doesn't make any sense. - -Signed-off-by: Eric Anholt -Fixes: 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D V3.x+") -Reviewed-by: Dave Emett -Link: https://patchwork.freedesktop.org/patch/msgid/20181203222438.25417-3-eric@anholt.net -(cherry picked from commit 2e6dc3bd80478212e84addf1cafd6ec60674b884) ---- - drivers/gpu/drm/v3d/v3d_gem.c | 12 ------------ - 1 file changed, 12 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -139,22 +139,10 @@ v3d_invalidate_l2(struct v3d_dev *v3d, i - V3D_L2CACTL_L2CENA); - } - --static void --v3d_invalidate_l1td(struct v3d_dev *v3d, int core) --{ -- V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, V3D_L2TCACTL_TMUWCF); -- if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) & -- V3D_L2TCACTL_L2TFLS), 100)) { -- DRM_ERROR("Timeout waiting for L1T write combiner flush\n"); -- } --} -- - /* Invalidates texture L2 cachelines */ - static void - v3d_flush_l2t(struct v3d_dev *v3d, int core) - { -- v3d_invalidate_l1td(v3d, core); -- - V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, - V3D_L2TCACTL_L2TFLS | - V3D_SET_FIELD(V3D_L2TCACTL_FLM_FLUSH, V3D_L2TCACTL_FLM)); diff --git a/target/linux/brcm2708/patches-4.19/950-0575-drm-v3d-Fix-BO-stats-accounting-for-dma-buf-imported.patch b/target/linux/brcm2708/patches-4.19/950-0575-drm-v3d-Fix-BO-stats-accounting-for-dma-buf-imported.patch new file mode 100644 index 0000000000..b369c337ef --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0575-drm-v3d-Fix-BO-stats-accounting-for-dma-buf-imported.patch @@ -0,0 +1,40 @@ +From 8a757f0cafacc0549aa333882060999b4465ac0c Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 7 Feb 2019 15:26:13 -0800 +Subject: [PATCH 575/725] drm/v3d: Fix BO stats accounting for dma-buf-imported + buffers. + +We always decrement at GEM free, so make sure we increment at GEM +creation for dma-bufs. + +Signed-off-by: Eric Anholt +Link: https://patchwork.freedesktop.org/patch/msgid/20190207232613.24981-1-eric@anholt.net +Reviewed-by: Daniel Vetter +Signed-off-by: Maxime Ripard +(cherry picked from commit cc3f60cfd4f2752f1bad7eaa3839855c15347abc) +--- + drivers/gpu/drm/v3d/v3d_bo.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/gpu/drm/v3d/v3d_bo.c ++++ b/drivers/gpu/drm/v3d/v3d_bo.c +@@ -282,6 +282,7 @@ v3d_prime_import_sg_table(struct drm_dev + struct dma_buf_attachment *attach, + struct sg_table *sgt) + { ++ struct v3d_dev *v3d = to_v3d_dev(dev); + struct drm_gem_object *obj; + struct v3d_bo *bo; + +@@ -296,6 +297,11 @@ v3d_prime_import_sg_table(struct drm_dev + obj->import_attach = attach; + v3d_bo_get_pages(bo); + ++ mutex_lock(&v3d->bo_lock); ++ v3d->bo_stats.num_allocated++; ++ v3d->bo_stats.pages_allocated += obj->size >> PAGE_SHIFT; ++ mutex_unlock(&v3d->bo_lock); ++ + v3d_mmu_insert_ptes(bo); + + return obj; diff --git a/target/linux/brcm2708/patches-4.19/950-0576-drm-v3d-Drop-the-wait-for-L2T-flush-to-complete.patch b/target/linux/brcm2708/patches-4.19/950-0576-drm-v3d-Drop-the-wait-for-L2T-flush-to-complete.patch deleted file mode 100644 index 12da8c5daf..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0576-drm-v3d-Drop-the-wait-for-L2T-flush-to-complete.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 6820b2b01d69ac316786570a592cc32efc559a0e Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 3 Dec 2018 14:24:36 -0800 -Subject: [PATCH 576/703] drm/v3d: Drop the wait for L2T flush to complete. - -According to Dave, once you've started an L2T flush, all L2T accesses -will be blocked until the flush completes. This fixes a consistent -3-4ms stall between the ioctl and running the job, and 3DMMES Taiji -goes from 27fps to 110fps. - -v2: Leave a note about why we don't need to wait for completion. - -Signed-off-by: Eric Anholt -Fixes: 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D V3.x+") -Reviewed-by: Dave Emett -Link: https://patchwork.freedesktop.org/patch/msgid/20181203222438.25417-4-eric@anholt.net -(cherry picked from commit 51c1b6f9eb3dbdec91b0e3c89f623e634c996bbb) ---- - drivers/gpu/drm/v3d/v3d_gem.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -143,13 +143,13 @@ v3d_invalidate_l2(struct v3d_dev *v3d, i - static void - v3d_flush_l2t(struct v3d_dev *v3d, int core) - { -+ /* While there is a busy bit (V3D_L2TCACTL_L2TFLS), we don't -+ * need to wait for completion before dispatching the job -- -+ * L2T accesses will be stalled until the flush has completed. -+ */ - V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, - V3D_L2TCACTL_L2TFLS | - V3D_SET_FIELD(V3D_L2TCACTL_FLM_FLUSH, V3D_L2TCACTL_FLM)); -- if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) & -- V3D_L2TCACTL_L2TFLS), 100)) { -- DRM_ERROR("Timeout waiting for L2T flush\n"); -- } - } - - /* Invalidates the slice caches. These are read-only caches. */ diff --git a/target/linux/brcm2708/patches-4.19/950-0576-drm-v3d-Update-top-level-kerneldoc-for-the-addition-.patch b/target/linux/brcm2708/patches-4.19/950-0576-drm-v3d-Update-top-level-kerneldoc-for-the-addition-.patch new file mode 100644 index 0000000000..56e726cd53 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0576-drm-v3d-Update-top-level-kerneldoc-for-the-addition-.patch @@ -0,0 +1,30 @@ +From e984884708d1777866cd8aba8de60eb9927f1628 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 7 Feb 2019 12:09:58 -0800 +Subject: [PATCH 576/725] drm/v3d: Update top-level kerneldoc for the addition + of TFU. + +Signed-off-by: Eric Anholt +Link: https://patchwork.freedesktop.org/patch/msgid/20190207201001.5730-1-eric@anholt.net +Reviewed-by: Thomas Spurden +Signed-off-by: Maxime Ripard +(cherry picked from commit fd347df16d4ed2eef565344b8f16a1134bddf185) +--- + drivers/gpu/drm/v3d/v3d_drv.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_drv.c ++++ b/drivers/gpu/drm/v3d/v3d_drv.c +@@ -7,9 +7,9 @@ + * This driver supports the Broadcom V3D 3.3 and 4.1 OpenGL ES GPUs. + * For V3D 2.x support, see the VC4 driver. + * +- * Currently only single-core rendering using the binner and renderer +- * is supported. The TFU (texture formatting unit) and V3D 4.x's CSD +- * (compute shader dispatch) are not yet supported. ++ * Currently only single-core rendering using the binner and renderer, ++ * along with TFU (texture formatting unit) rendering is supported. ++ * V3D 4.x's CSD (compute shader dispatch) is not yet supported. + */ + + #include diff --git a/target/linux/brcm2708/patches-4.19/950-0577-drm-v3d-Stop-trying-to-flush-L2C-on-V3D-3.3.patch b/target/linux/brcm2708/patches-4.19/950-0577-drm-v3d-Stop-trying-to-flush-L2C-on-V3D-3.3.patch deleted file mode 100644 index e07738c368..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0577-drm-v3d-Stop-trying-to-flush-L2C-on-V3D-3.3.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 861449c481eaa203998a4298d81b2fba6b34f543 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 3 Dec 2018 14:24:37 -0800 -Subject: [PATCH 577/703] drm/v3d: Stop trying to flush L2C on V3D 3.3+ - -This cache was replaced with the slice accessing the L2T in the newer -generations. Noted by Dave during review. - -Signed-off-by: Eric Anholt -Link: https://patchwork.freedesktop.org/patch/msgid/20181203222438.25417-5-eric@anholt.net -Reviewed-by: Dave Emett -(cherry picked from commit 7b9d2fe4350a9c12f66ad8cc78c1098226f6c3c2) ---- - drivers/gpu/drm/v3d/v3d_gem.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -130,10 +130,15 @@ v3d_flush_l3(struct v3d_dev *v3d) - } - } - --/* Invalidates the (read-only) L2 cache. */ -+/* Invalidates the (read-only) L2C cache. This was the L2 cache for -+ * uniforms and instructions on V3D 3.2. -+ */ - static void --v3d_invalidate_l2(struct v3d_dev *v3d, int core) -+v3d_invalidate_l2c(struct v3d_dev *v3d, int core) - { -+ if (v3d->ver > 32) -+ return; -+ - V3D_CORE_WRITE(core, V3D_CTL_L2CACTL, - V3D_L2CACTL_L2CCLR | - V3D_L2CACTL_L2CENA); -@@ -168,7 +173,7 @@ v3d_invalidate_caches(struct v3d_dev *v3 - { - v3d_flush_l3(v3d); - -- v3d_invalidate_l2(v3d, 0); -+ v3d_invalidate_l2c(v3d, 0); - v3d_invalidate_slices(v3d, 0); - v3d_flush_l2t(v3d, 0); - } diff --git a/target/linux/brcm2708/patches-4.19/950-0577-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch b/target/linux/brcm2708/patches-4.19/950-0577-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch new file mode 100644 index 0000000000..923cd9fbbc --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0577-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch @@ -0,0 +1,22 @@ +From 7551fad9f71e9228df091897d61b2d3df7c96ab1 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 4 Mar 2019 11:59:34 -0800 +Subject: [PATCH 577/725] drm/vc4: Fix oops at boot with firmwarekms on 4.19. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_kms.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/gpu/drm/vc4/vc4_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_kms.c +@@ -107,6 +107,9 @@ vc4_ctm_commit(struct vc4_dev *vc4, stru + struct vc4_ctm_state *ctm_state = to_vc4_ctm_state(vc4->ctm_manager.state); + struct drm_color_ctm *ctm = ctm_state->ctm; + ++ if (vc4->firmware_kms) ++ return; ++ + if (ctm_state->fifo) { + HVS_WRITE(SCALER_OLEDCOEF2, + VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[0]), diff --git a/target/linux/brcm2708/patches-4.19/950-0578-drm-v3d-Invalidate-the-caches-from-the-outside-in.patch b/target/linux/brcm2708/patches-4.19/950-0578-drm-v3d-Invalidate-the-caches-from-the-outside-in.patch deleted file mode 100644 index cb9d8411bc..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0578-drm-v3d-Invalidate-the-caches-from-the-outside-in.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 022131a879deb883f4fbbbd7b5887ae6b2738172 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 3 Dec 2018 14:24:38 -0800 -Subject: [PATCH 578/703] drm/v3d: Invalidate the caches from the outside in. - -This would be a fairly obscure race, but let's make sure we don't ever -lose it. - -Signed-off-by: Eric Anholt -Link: https://patchwork.freedesktop.org/patch/msgid/20181203222438.25417-6-eric@anholt.net -Reviewed-by: Dave Emett -(cherry picked from commit aa5beec32e8b78bfcf621e3c3daebfb1644b6365) ---- - drivers/gpu/drm/v3d/v3d_gem.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -171,11 +171,15 @@ v3d_invalidate_slices(struct v3d_dev *v3 - void - v3d_invalidate_caches(struct v3d_dev *v3d) - { -+ /* Invalidate the caches from the outside in. That way if -+ * another CL's concurrent use of nearby memory were to pull -+ * an invalidated cacheline back in, we wouldn't leave stale -+ * data in the inner cache. -+ */ - v3d_flush_l3(v3d); -- - v3d_invalidate_l2c(v3d, 0); -- v3d_invalidate_slices(v3d, 0); - v3d_flush_l2t(v3d, 0); -+ v3d_invalidate_slices(v3d, 0); - } - - static void diff --git a/target/linux/brcm2708/patches-4.19/950-0578-drm-vc4-Disable-V3D-interactions-if-the-v3d-componen.patch b/target/linux/brcm2708/patches-4.19/950-0578-drm-vc4-Disable-V3D-interactions-if-the-v3d-componen.patch new file mode 100644 index 0000000000..863cba6463 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0578-drm-vc4-Disable-V3D-interactions-if-the-v3d-componen.patch @@ -0,0 +1,167 @@ +From ef816cd2c04e82d3b923cbb407025609fecd1205 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 20 Feb 2019 13:03:41 -0800 +Subject: [PATCH 578/725] drm/vc4: Disable V3D interactions if the v3d + component didn't probe. + +One might want to use the VC4 display stack without using Mesa. +Similar to the debugfs fixes for not having all of the possible +display bits enabled, make sure you can't oops in vc4 if v3d isn't +enabled. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_drv.c | 11 +++++++++++ + drivers/gpu/drm/vc4/vc4_gem.c | 10 ++++++++++ + drivers/gpu/drm/vc4/vc4_irq.c | 9 +++++++++ + drivers/gpu/drm/vc4/vc4_perfmon.c | 18 ++++++++++++++++++ + 4 files changed, 48 insertions(+) + +--- a/drivers/gpu/drm/vc4/vc4_drv.c ++++ b/drivers/gpu/drm/vc4/vc4_drv.c +@@ -71,6 +71,9 @@ static int vc4_get_param_ioctl(struct dr + if (args->pad != 0) + return -EINVAL; + ++ if (!vc4->v3d) ++ return -EINVAL; ++ + switch (args->param) { + case DRM_VC4_PARAM_V3D_IDENT0: + ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev); +@@ -271,6 +274,7 @@ static int vc4_drm_bind(struct device *d + struct platform_device *pdev = to_platform_device(dev); + struct drm_device *drm; + struct vc4_dev *vc4; ++ struct device_node *node; + int ret = 0; + + dev->coherent_dma_mask = DMA_BIT_MASK(32); +@@ -279,6 +283,13 @@ static int vc4_drm_bind(struct device *d + if (!vc4) + return -ENOMEM; + ++ /* If VC4 V3D is missing, don't advertise render nodes. */ ++ node = of_find_compatible_node(NULL, NULL, "brcm,bcm2835-v3d"); ++ if (node) ++ of_node_put(node); ++ else ++ vc4_drm_driver.driver_features &= ~DRIVER_RENDER; ++ + drm = drm_dev_alloc(&vc4_drm_driver, dev); + if (IS_ERR(drm)) + return PTR_ERR(drm); +--- a/drivers/gpu/drm/vc4/vc4_gem.c ++++ b/drivers/gpu/drm/vc4/vc4_gem.c +@@ -74,6 +74,11 @@ vc4_get_hang_state_ioctl(struct drm_devi + u32 i; + int ret = 0; + ++ if (!vc4->v3d) { ++ DRM_DEBUG("VC4_GET_HANG_STATE with no VC4 V3D probed\n"); ++ return -EINVAL; ++ } ++ + spin_lock_irqsave(&vc4->job_lock, irqflags); + kernel_state = vc4->hang_state; + if (!kernel_state) { +@@ -1124,6 +1129,11 @@ vc4_submit_cl_ioctl(struct drm_device *d + struct dma_fence *in_fence; + int ret = 0; + ++ if (!vc4->v3d) { ++ DRM_DEBUG("VC4_SUBMIT_CL with no VC4 V3D probed\n"); ++ return -EINVAL; ++ } ++ + if ((args->flags & ~(VC4_SUBMIT_CL_USE_CLEAR_COLOR | + VC4_SUBMIT_CL_FIXED_RCL_ORDER | + VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X | +--- a/drivers/gpu/drm/vc4/vc4_irq.c ++++ b/drivers/gpu/drm/vc4/vc4_irq.c +@@ -229,6 +229,9 @@ vc4_irq_preinstall(struct drm_device *de + { + struct vc4_dev *vc4 = to_vc4_dev(dev); + ++ if (!vc4->v3d) ++ return; ++ + init_waitqueue_head(&vc4->job_wait_queue); + INIT_WORK(&vc4->overflow_mem_work, vc4_overflow_mem_work); + +@@ -243,6 +246,9 @@ vc4_irq_postinstall(struct drm_device *d + { + struct vc4_dev *vc4 = to_vc4_dev(dev); + ++ if (!vc4->v3d) ++ return 0; ++ + /* Enable both the render done and out of memory interrupts. */ + V3D_WRITE(V3D_INTENA, V3D_DRIVER_IRQS); + +@@ -254,6 +260,9 @@ vc4_irq_uninstall(struct drm_device *dev + { + struct vc4_dev *vc4 = to_vc4_dev(dev); + ++ if (!vc4->v3d) ++ return; ++ + /* Disable sending interrupts for our driver's IRQs. */ + V3D_WRITE(V3D_INTDIS, V3D_DRIVER_IRQS); + +--- a/drivers/gpu/drm/vc4/vc4_perfmon.c ++++ b/drivers/gpu/drm/vc4/vc4_perfmon.c +@@ -100,12 +100,18 @@ void vc4_perfmon_close_file(struct vc4_f + int vc4_perfmon_create_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) + { ++ struct vc4_dev *vc4 = to_vc4_dev(dev); + struct vc4_file *vc4file = file_priv->driver_priv; + struct drm_vc4_perfmon_create *req = data; + struct vc4_perfmon *perfmon; + unsigned int i; + int ret; + ++ if (!vc4->v3d) { ++ DRM_DEBUG("Creating perfmon no VC4 V3D probed\n"); ++ return -EINVAL; ++ } ++ + /* Number of monitored counters cannot exceed HW limits. */ + if (req->ncounters > DRM_VC4_MAX_PERF_COUNTERS || + !req->ncounters) +@@ -146,10 +152,16 @@ int vc4_perfmon_create_ioctl(struct drm_ + int vc4_perfmon_destroy_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) + { ++ struct vc4_dev *vc4 = to_vc4_dev(dev); + struct vc4_file *vc4file = file_priv->driver_priv; + struct drm_vc4_perfmon_destroy *req = data; + struct vc4_perfmon *perfmon; + ++ if (!vc4->v3d) { ++ DRM_DEBUG("Destroying perfmon no VC4 V3D probed\n"); ++ return -EINVAL; ++ } ++ + mutex_lock(&vc4file->perfmon.lock); + perfmon = idr_remove(&vc4file->perfmon.idr, req->id); + mutex_unlock(&vc4file->perfmon.lock); +@@ -164,11 +176,17 @@ int vc4_perfmon_destroy_ioctl(struct drm + int vc4_perfmon_get_values_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) + { ++ struct vc4_dev *vc4 = to_vc4_dev(dev); + struct vc4_file *vc4file = file_priv->driver_priv; + struct drm_vc4_perfmon_get_values *req = data; + struct vc4_perfmon *perfmon; + int ret; + ++ if (!vc4->v3d) { ++ DRM_DEBUG("Getting perfmon no VC4 V3D probed\n"); ++ return -EINVAL; ++ } ++ + mutex_lock(&vc4file->perfmon.lock); + perfmon = idr_find(&vc4file->perfmon.idr, req->id); + vc4_perfmon_get(perfmon); diff --git a/target/linux/brcm2708/patches-4.19/950-0579-drm-v3d-Add-support-for-V3D-v4.2.patch b/target/linux/brcm2708/patches-4.19/950-0579-drm-v3d-Add-support-for-V3D-v4.2.patch new file mode 100644 index 0000000000..eed4d0c274 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0579-drm-v3d-Add-support-for-V3D-v4.2.patch @@ -0,0 +1,207 @@ +From 6c378699bbc94d0f4e13fa5df43c8e2c7b9c1480 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 4 Oct 2018 17:22:43 -0700 +Subject: [PATCH 579/725] drm/v3d: Add support for V3D v4.2. + +No compatible string for it yet, just the version-dependent changes. +They've now tied the hub and the core interrupt lines into a single +interrupt line coming out of the block. It also turns out I made a +mistake in modeling the V3D v3.3 and v4.1 bridge as a part of V3D +itself -- the bridge is going away in favor of an external reset +controller in a larger HW module. + +v2: Use consistent checks for whether we're on 4.2, and fix a leak in + an error path. +v3: Use more general means of determining if the current 4.2 changes + are in place, as apparently other platforms may switch back (noted + by Dave). Update the binding doc. + +Signed-off-by: Eric Anholt +--- + .../devicetree/bindings/gpu/brcm,bcm-v3d.txt | 11 ++++-- + drivers/gpu/drm/v3d/v3d_drv.c | 21 +++++++++--- + drivers/gpu/drm/v3d/v3d_drv.h | 2 ++ + drivers/gpu/drm/v3d/v3d_gem.c | 12 ++++++- + drivers/gpu/drm/v3d/v3d_irq.c | 34 ++++++++++++++----- + 5 files changed, 63 insertions(+), 17 deletions(-) + +--- a/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.txt ++++ b/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.txt +@@ -6,15 +6,20 @@ For V3D 2.x, see brcm,bcm-vc4.txt. + Required properties: + - compatible: Should be "brcm,7268-v3d" or "brcm,7278-v3d" + - reg: Physical base addresses and lengths of the register areas +-- reg-names: Names for the register areas. The "hub", "bridge", and "core0" ++- reg-names: Names for the register areas. The "hub" and "core0" + register areas are always required. The "gca" register area +- is required if the GCA cache controller is present. ++ is required if the GCA cache controller is present. The ++ "bridge" register area is required if an external reset ++ controller is not present. + - interrupts: The interrupt numbers. The first interrupt is for the hub, +- while the following interrupts are for the cores. ++ while the following interrupts are separate interrupt lines ++ for the cores (if they don't share the hub's interrupt). + See bindings/interrupt-controller/interrupts.txt + + Optional properties: + - clocks: The core clock the unit runs on ++- resets: The reset line for v3d, if not using a mapping of the bridge ++ See bindings/reset/reset.txt + + v3d { + compatible = "brcm,7268-v3d"; +--- a/drivers/gpu/drm/v3d/v3d_drv.c ++++ b/drivers/gpu/drm/v3d/v3d_drv.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -265,10 +266,6 @@ static int v3d_platform_drm_probe(struct + v3d->pdev = pdev; + drm = &v3d->drm; + +- ret = map_regs(v3d, &v3d->bridge_regs, "bridge"); +- if (ret) +- goto dev_free; +- + ret = map_regs(v3d, &v3d->hub_regs, "hub"); + if (ret) + goto dev_free; +@@ -283,6 +280,22 @@ static int v3d_platform_drm_probe(struct + v3d->cores = V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_NCORES); + WARN_ON(v3d->cores > 1); /* multicore not yet implemented */ + ++ v3d->reset = devm_reset_control_get_exclusive(dev, NULL); ++ if (IS_ERR(v3d->reset)) { ++ ret = PTR_ERR(v3d->reset); ++ ++ if (ret == -EPROBE_DEFER) ++ goto dev_free; ++ ++ v3d->reset = NULL; ++ ret = map_regs(v3d, &v3d->bridge_regs, "bridge"); ++ if (ret) { ++ dev_err(dev, ++ "Failed to get reset control or bridge regs\n"); ++ goto dev_free; ++ } ++ } ++ + if (v3d->ver < 41) { + ret = map_regs(v3d, &v3d->gca_regs, "gca"); + if (ret) +--- a/drivers/gpu/drm/v3d/v3d_drv.h ++++ b/drivers/gpu/drm/v3d/v3d_drv.h +@@ -34,6 +34,7 @@ struct v3d_dev { + * and revision. + */ + int ver; ++ bool single_irq_line; + + struct device *dev; + struct platform_device *pdev; +@@ -42,6 +43,7 @@ struct v3d_dev { + void __iomem *bridge_regs; + void __iomem *gca_regs; + struct clk *clk; ++ struct reset_control *reset; + + /* Virtual and DMA addresses of the single shared page table. */ + volatile u32 *pt; +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -69,7 +70,7 @@ v3d_idle_gca(struct v3d_dev *v3d) + } + + static void +-v3d_reset_v3d(struct v3d_dev *v3d) ++v3d_reset_by_bridge(struct v3d_dev *v3d) + { + int version = V3D_BRIDGE_READ(V3D_TOP_GR_BRIDGE_REVISION); + +@@ -89,6 +90,15 @@ v3d_reset_v3d(struct v3d_dev *v3d) + V3D_TOP_GR_BRIDGE_SW_INIT_1_V3D_CLK_108_SW_INIT); + V3D_BRIDGE_WRITE(V3D_TOP_GR_BRIDGE_SW_INIT_1, 0); + } ++} ++ ++static void ++v3d_reset_v3d(struct v3d_dev *v3d) ++{ ++ if (v3d->reset) ++ reset_control_reset(v3d->reset); ++ else ++ v3d_reset_by_bridge(v3d); + + v3d_init_hw_state(v3d); + } +--- a/drivers/gpu/drm/v3d/v3d_irq.c ++++ b/drivers/gpu/drm/v3d/v3d_irq.c +@@ -27,6 +27,9 @@ + V3D_HUB_INT_MMU_CAP | \ + V3D_HUB_INT_TFUC)) + ++static irqreturn_t ++v3d_hub_irq(int irq, void *arg); ++ + static void + v3d_overflow_mem_work(struct work_struct *work) + { +@@ -112,6 +115,12 @@ v3d_irq(int irq, void *arg) + if (intsts & V3D_INT_GMPV) + dev_err(v3d->dev, "GMP violation\n"); + ++ /* V3D 4.2 wires the hub and core IRQs together, so if we & ++ * didn't see the common one then check hub for MMU IRQs. ++ */ ++ if (v3d->single_irq_line && status == IRQ_NONE) ++ return v3d_hub_irq(irq, arg); ++ + return status; + } + +@@ -170,15 +179,22 @@ v3d_irq_init(struct v3d_dev *v3d) + V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS); + V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS); + +- ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0), +- v3d_hub_irq, IRQF_SHARED, +- "v3d_hub", v3d); +- if (ret) +- goto fail; +- +- ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 1), +- v3d_irq, IRQF_SHARED, +- "v3d_core0", v3d); ++ if (platform_get_irq(v3d->pdev, 1) < 0) { ++ ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0), ++ v3d_irq, IRQF_SHARED, ++ "v3d", v3d); ++ v3d->single_irq_line = true; ++ } else { ++ ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0), ++ v3d_hub_irq, IRQF_SHARED, ++ "v3d_hub", v3d); ++ if (ret) ++ goto fail; ++ ++ ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 1), ++ v3d_irq, IRQF_SHARED, ++ "v3d_core0", v3d); ++ } + if (ret) + goto fail; + diff --git a/target/linux/brcm2708/patches-4.19/950-0579-drm-v3d-Fix-BO-stats-accounting-for-dma-buf-imported.patch b/target/linux/brcm2708/patches-4.19/950-0579-drm-v3d-Fix-BO-stats-accounting-for-dma-buf-imported.patch deleted file mode 100644 index 9928042936..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0579-drm-v3d-Fix-BO-stats-accounting-for-dma-buf-imported.patch +++ /dev/null @@ -1,40 +0,0 @@ -From cc4f39930d6d1cf396c3a1f6fa45696582247ee6 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 7 Feb 2019 15:26:13 -0800 -Subject: [PATCH 579/703] drm/v3d: Fix BO stats accounting for dma-buf-imported - buffers. - -We always decrement at GEM free, so make sure we increment at GEM -creation for dma-bufs. - -Signed-off-by: Eric Anholt -Link: https://patchwork.freedesktop.org/patch/msgid/20190207232613.24981-1-eric@anholt.net -Reviewed-by: Daniel Vetter -Signed-off-by: Maxime Ripard -(cherry picked from commit cc3f60cfd4f2752f1bad7eaa3839855c15347abc) ---- - drivers/gpu/drm/v3d/v3d_bo.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/gpu/drm/v3d/v3d_bo.c -+++ b/drivers/gpu/drm/v3d/v3d_bo.c -@@ -282,6 +282,7 @@ v3d_prime_import_sg_table(struct drm_dev - struct dma_buf_attachment *attach, - struct sg_table *sgt) - { -+ struct v3d_dev *v3d = to_v3d_dev(dev); - struct drm_gem_object *obj; - struct v3d_bo *bo; - -@@ -296,6 +297,11 @@ v3d_prime_import_sg_table(struct drm_dev - obj->import_attach = attach; - v3d_bo_get_pages(bo); - -+ mutex_lock(&v3d->bo_lock); -+ v3d->bo_stats.num_allocated++; -+ v3d->bo_stats.pages_allocated += obj->size >> PAGE_SHIFT; -+ mutex_unlock(&v3d->bo_lock); -+ - v3d_mmu_insert_ptes(bo); - - return obj; diff --git a/target/linux/brcm2708/patches-4.19/950-0580-drm-v3d-Don-t-try-to-set-OVRTMUOUT-on-V3D-4.x.patch b/target/linux/brcm2708/patches-4.19/950-0580-drm-v3d-Don-t-try-to-set-OVRTMUOUT-on-V3D-4.x.patch new file mode 100644 index 0000000000..b61ee8a534 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0580-drm-v3d-Don-t-try-to-set-OVRTMUOUT-on-V3D-4.x.patch @@ -0,0 +1,42 @@ +From 10a571a91a1d34cd89bb45a562aafc625dd6e738 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Tue, 16 Oct 2018 10:13:41 -0700 +Subject: [PATCH 580/725] drm/v3d: Don't try to set OVRTMUOUT on V3D 4.x. + +The old field is gone and the register now has a different field, +QRMAXCNT for how many TMU requests get serviced before thread switch. +We were accidentally reducing it from its default of 0x3 (4 requests) +to 0x0 (1). + +v2: Skip setting the reg at all on 4.x, instead of trying to update + only the old field. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/v3d/v3d_gem.c | 3 ++- + drivers/gpu/drm/v3d/v3d_regs.h | 2 ++ + 2 files changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -25,7 +25,8 @@ v3d_init_core(struct v3d_dev *v3d, int c + * type. If you want the default behavior, you can still put + * "2" in the indirect texture state's output_type field. + */ +- V3D_CORE_WRITE(core, V3D_CTL_MISCCFG, V3D_MISCCFG_OVRTMUOUT); ++ if (v3d->ver < 40) ++ V3D_CORE_WRITE(core, V3D_CTL_MISCCFG, V3D_MISCCFG_OVRTMUOUT); + + /* Whenever we flush the L2T cache, we always want to flush + * the whole thing. +--- a/drivers/gpu/drm/v3d/v3d_regs.h ++++ b/drivers/gpu/drm/v3d/v3d_regs.h +@@ -216,6 +216,8 @@ + # define V3D_IDENT2_BCG_INT BIT(28) + + #define V3D_CTL_MISCCFG 0x00018 ++# define V3D_CTL_MISCCFG_QRMAXCNT_MASK V3D_MASK(3, 1) ++# define V3D_CTL_MISCCFG_QRMAXCNT_SHIFT 1 + # define V3D_MISCCFG_OVRTMUOUT BIT(0) + + #define V3D_CTL_L2CACTL 0x00020 diff --git a/target/linux/brcm2708/patches-4.19/950-0580-drm-v3d-Update-top-level-kerneldoc-for-the-addition-.patch b/target/linux/brcm2708/patches-4.19/950-0580-drm-v3d-Update-top-level-kerneldoc-for-the-addition-.patch deleted file mode 100644 index e9f8299d9e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0580-drm-v3d-Update-top-level-kerneldoc-for-the-addition-.patch +++ /dev/null @@ -1,30 +0,0 @@ -From e4759dbb9968baee8a35bf2f165f6096be6aac00 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 7 Feb 2019 12:09:58 -0800 -Subject: [PATCH 580/703] drm/v3d: Update top-level kerneldoc for the addition - of TFU. - -Signed-off-by: Eric Anholt -Link: https://patchwork.freedesktop.org/patch/msgid/20190207201001.5730-1-eric@anholt.net -Reviewed-by: Thomas Spurden -Signed-off-by: Maxime Ripard -(cherry picked from commit fd347df16d4ed2eef565344b8f16a1134bddf185) ---- - drivers/gpu/drm/v3d/v3d_drv.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_drv.c -+++ b/drivers/gpu/drm/v3d/v3d_drv.c -@@ -7,9 +7,9 @@ - * This driver supports the Broadcom V3D 3.3 and 4.1 OpenGL ES GPUs. - * For V3D 2.x support, see the VC4 driver. - * -- * Currently only single-core rendering using the binner and renderer -- * is supported. The TFU (texture formatting unit) and V3D 4.x's CSD -- * (compute shader dispatch) are not yet supported. -+ * Currently only single-core rendering using the binner and renderer, -+ * along with TFU (texture formatting unit) rendering is supported. -+ * V3D 4.x's CSD (compute shader dispatch) is not yet supported. - */ - - #include diff --git a/target/linux/brcm2708/patches-4.19/950-0581-drm-v3d-Make-sure-the-GPU-is-on-when-measuring-clock.patch b/target/linux/brcm2708/patches-4.19/950-0581-drm-v3d-Make-sure-the-GPU-is-on-when-measuring-clock.patch new file mode 100644 index 0000000000..67f4c4813f --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0581-drm-v3d-Make-sure-the-GPU-is-on-when-measuring-clock.patch @@ -0,0 +1,38 @@ +From cf9082f5c2ae9b9a85329cbb5a0651bcc36205a3 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 14 Jan 2019 17:26:04 -0800 +Subject: [PATCH 581/725] drm/v3d: Make sure the GPU is on when measuring + clocks. + +You'll get garbage measurements if the registers always read back +0xdeadbeef + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/v3d/v3d_debugfs.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/gpu/drm/v3d/v3d_debugfs.c ++++ b/drivers/gpu/drm/v3d/v3d_debugfs.c +@@ -187,6 +187,11 @@ static int v3d_measure_clock(struct seq_ + uint32_t cycles; + int core = 0; + int measure_ms = 1000; ++ int ret; ++ ++ ret = pm_runtime_get_sync(v3d->dev); ++ if (ret < 0) ++ return ret; + + if (v3d->ver >= 40) { + V3D_CORE_WRITE(core, V3D_V4_PCTR_0_SRC_0_3, +@@ -210,6 +215,9 @@ static int v3d_measure_clock(struct seq_ + cycles / (measure_ms * 1000), + (cycles / (measure_ms * 100)) % 10); + ++ pm_runtime_mark_last_busy(v3d->dev); ++ pm_runtime_put_autosuspend(v3d->dev); ++ + return 0; + } + diff --git a/target/linux/brcm2708/patches-4.19/950-0581-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch b/target/linux/brcm2708/patches-4.19/950-0581-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch deleted file mode 100644 index 624177db93..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0581-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 88066d8b4bd16fb094b74447684f474dd84092a9 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 4 Mar 2019 11:59:34 -0800 -Subject: [PATCH 581/703] drm/vc4: Fix oops at boot with firmwarekms on 4.19. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_kms.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -107,6 +107,9 @@ vc4_ctm_commit(struct vc4_dev *vc4, stru - struct vc4_ctm_state *ctm_state = to_vc4_ctm_state(vc4->ctm_manager.state); - struct drm_color_ctm *ctm = ctm_state->ctm; - -+ if (vc4->firmware_kms) -+ return; -+ - if (ctm_state->fifo) { - HVS_WRITE(SCALER_OLEDCOEF2, - VC4_SET_FIELD(vc4_ctm_s31_32_to_s0_9(ctm->matrix[0]), diff --git a/target/linux/brcm2708/patches-4.19/950-0582-drm-v3d-Add-support-for-2711.patch b/target/linux/brcm2708/patches-4.19/950-0582-drm-v3d-Add-support-for-2711.patch new file mode 100644 index 0000000000..894efc7b9b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0582-drm-v3d-Add-support-for-2711.patch @@ -0,0 +1,20 @@ +From c0584debae6e08806a3136b96e4378fe6ed8c908 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 4 Oct 2018 17:22:43 -0700 +Subject: [PATCH 582/725] drm/v3d: Add support for 2711. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/v3d/v3d_drv.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpu/drm/v3d/v3d_drv.c ++++ b/drivers/gpu/drm/v3d/v3d_drv.c +@@ -235,6 +235,7 @@ static struct drm_driver v3d_drm_driver + static const struct of_device_id v3d_of_match[] = { + { .compatible = "brcm,7268-v3d" }, + { .compatible = "brcm,7278-v3d" }, ++ { .compatible = "brcm,2711-v3d" }, + {}, + }; + MODULE_DEVICE_TABLE(of, v3d_of_match); diff --git a/target/linux/brcm2708/patches-4.19/950-0582-drm-vc4-Disable-V3D-interactions-if-the-v3d-componen.patch b/target/linux/brcm2708/patches-4.19/950-0582-drm-vc4-Disable-V3D-interactions-if-the-v3d-componen.patch deleted file mode 100644 index e7afa725b8..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0582-drm-vc4-Disable-V3D-interactions-if-the-v3d-componen.patch +++ /dev/null @@ -1,167 +0,0 @@ -From 00f06424b180f1f6a3f52df718eae07c36fc72e5 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Wed, 20 Feb 2019 13:03:41 -0800 -Subject: [PATCH 582/703] drm/vc4: Disable V3D interactions if the v3d - component didn't probe. - -One might want to use the VC4 display stack without using Mesa. -Similar to the debugfs fixes for not having all of the possible -display bits enabled, make sure you can't oops in vc4 if v3d isn't -enabled. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_drv.c | 11 +++++++++++ - drivers/gpu/drm/vc4/vc4_gem.c | 10 ++++++++++ - drivers/gpu/drm/vc4/vc4_irq.c | 9 +++++++++ - drivers/gpu/drm/vc4/vc4_perfmon.c | 18 ++++++++++++++++++ - 4 files changed, 48 insertions(+) - ---- a/drivers/gpu/drm/vc4/vc4_drv.c -+++ b/drivers/gpu/drm/vc4/vc4_drv.c -@@ -71,6 +71,9 @@ static int vc4_get_param_ioctl(struct dr - if (args->pad != 0) - return -EINVAL; - -+ if (!vc4->v3d) -+ return -EINVAL; -+ - switch (args->param) { - case DRM_VC4_PARAM_V3D_IDENT0: - ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev); -@@ -271,6 +274,7 @@ static int vc4_drm_bind(struct device *d - struct platform_device *pdev = to_platform_device(dev); - struct drm_device *drm; - struct vc4_dev *vc4; -+ struct device_node *node; - int ret = 0; - - dev->coherent_dma_mask = DMA_BIT_MASK(32); -@@ -279,6 +283,13 @@ static int vc4_drm_bind(struct device *d - if (!vc4) - return -ENOMEM; - -+ /* If VC4 V3D is missing, don't advertise render nodes. */ -+ node = of_find_compatible_node(NULL, NULL, "brcm,bcm2835-v3d"); -+ if (node) -+ of_node_put(node); -+ else -+ vc4_drm_driver.driver_features &= ~DRIVER_RENDER; -+ - drm = drm_dev_alloc(&vc4_drm_driver, dev); - if (IS_ERR(drm)) - return PTR_ERR(drm); ---- a/drivers/gpu/drm/vc4/vc4_gem.c -+++ b/drivers/gpu/drm/vc4/vc4_gem.c -@@ -74,6 +74,11 @@ vc4_get_hang_state_ioctl(struct drm_devi - u32 i; - int ret = 0; - -+ if (!vc4->v3d) { -+ DRM_DEBUG("VC4_GET_HANG_STATE with no VC4 V3D probed\n"); -+ return -EINVAL; -+ } -+ - spin_lock_irqsave(&vc4->job_lock, irqflags); - kernel_state = vc4->hang_state; - if (!kernel_state) { -@@ -1124,6 +1129,11 @@ vc4_submit_cl_ioctl(struct drm_device *d - struct dma_fence *in_fence; - int ret = 0; - -+ if (!vc4->v3d) { -+ DRM_DEBUG("VC4_SUBMIT_CL with no VC4 V3D probed\n"); -+ return -EINVAL; -+ } -+ - if ((args->flags & ~(VC4_SUBMIT_CL_USE_CLEAR_COLOR | - VC4_SUBMIT_CL_FIXED_RCL_ORDER | - VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X | ---- a/drivers/gpu/drm/vc4/vc4_irq.c -+++ b/drivers/gpu/drm/vc4/vc4_irq.c -@@ -229,6 +229,9 @@ vc4_irq_preinstall(struct drm_device *de - { - struct vc4_dev *vc4 = to_vc4_dev(dev); - -+ if (!vc4->v3d) -+ return; -+ - init_waitqueue_head(&vc4->job_wait_queue); - INIT_WORK(&vc4->overflow_mem_work, vc4_overflow_mem_work); - -@@ -243,6 +246,9 @@ vc4_irq_postinstall(struct drm_device *d - { - struct vc4_dev *vc4 = to_vc4_dev(dev); - -+ if (!vc4->v3d) -+ return 0; -+ - /* Enable both the render done and out of memory interrupts. */ - V3D_WRITE(V3D_INTENA, V3D_DRIVER_IRQS); - -@@ -254,6 +260,9 @@ vc4_irq_uninstall(struct drm_device *dev - { - struct vc4_dev *vc4 = to_vc4_dev(dev); - -+ if (!vc4->v3d) -+ return; -+ - /* Disable sending interrupts for our driver's IRQs. */ - V3D_WRITE(V3D_INTDIS, V3D_DRIVER_IRQS); - ---- a/drivers/gpu/drm/vc4/vc4_perfmon.c -+++ b/drivers/gpu/drm/vc4/vc4_perfmon.c -@@ -100,12 +100,18 @@ void vc4_perfmon_close_file(struct vc4_f - int vc4_perfmon_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) - { -+ struct vc4_dev *vc4 = to_vc4_dev(dev); - struct vc4_file *vc4file = file_priv->driver_priv; - struct drm_vc4_perfmon_create *req = data; - struct vc4_perfmon *perfmon; - unsigned int i; - int ret; - -+ if (!vc4->v3d) { -+ DRM_DEBUG("Creating perfmon no VC4 V3D probed\n"); -+ return -EINVAL; -+ } -+ - /* Number of monitored counters cannot exceed HW limits. */ - if (req->ncounters > DRM_VC4_MAX_PERF_COUNTERS || - !req->ncounters) -@@ -146,10 +152,16 @@ int vc4_perfmon_create_ioctl(struct drm_ - int vc4_perfmon_destroy_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) - { -+ struct vc4_dev *vc4 = to_vc4_dev(dev); - struct vc4_file *vc4file = file_priv->driver_priv; - struct drm_vc4_perfmon_destroy *req = data; - struct vc4_perfmon *perfmon; - -+ if (!vc4->v3d) { -+ DRM_DEBUG("Destroying perfmon no VC4 V3D probed\n"); -+ return -EINVAL; -+ } -+ - mutex_lock(&vc4file->perfmon.lock); - perfmon = idr_remove(&vc4file->perfmon.idr, req->id); - mutex_unlock(&vc4file->perfmon.lock); -@@ -164,11 +176,17 @@ int vc4_perfmon_destroy_ioctl(struct drm - int vc4_perfmon_get_values_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) - { -+ struct vc4_dev *vc4 = to_vc4_dev(dev); - struct vc4_file *vc4file = file_priv->driver_priv; - struct drm_vc4_perfmon_get_values *req = data; - struct vc4_perfmon *perfmon; - int ret; - -+ if (!vc4->v3d) { -+ DRM_DEBUG("Getting perfmon no VC4 V3D probed\n"); -+ return -EINVAL; -+ } -+ - mutex_lock(&vc4file->perfmon.lock); - perfmon = idr_find(&vc4file->perfmon.idr, req->id); - vc4_perfmon_get(perfmon); diff --git a/target/linux/brcm2708/patches-4.19/950-0583-drm-v3d-Add-support-for-V3D-v4.2.patch b/target/linux/brcm2708/patches-4.19/950-0583-drm-v3d-Add-support-for-V3D-v4.2.patch deleted file mode 100644 index b84f333b43..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0583-drm-v3d-Add-support-for-V3D-v4.2.patch +++ /dev/null @@ -1,207 +0,0 @@ -From 8169ec547bf6719c89c3ed88f9884bb9dd84479d Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 4 Oct 2018 17:22:43 -0700 -Subject: [PATCH 583/703] drm/v3d: Add support for V3D v4.2. - -No compatible string for it yet, just the version-dependent changes. -They've now tied the hub and the core interrupt lines into a single -interrupt line coming out of the block. It also turns out I made a -mistake in modeling the V3D v3.3 and v4.1 bridge as a part of V3D -itself -- the bridge is going away in favor of an external reset -controller in a larger HW module. - -v2: Use consistent checks for whether we're on 4.2, and fix a leak in - an error path. -v3: Use more general means of determining if the current 4.2 changes - are in place, as apparently other platforms may switch back (noted - by Dave). Update the binding doc. - -Signed-off-by: Eric Anholt ---- - .../devicetree/bindings/gpu/brcm,bcm-v3d.txt | 11 ++++-- - drivers/gpu/drm/v3d/v3d_drv.c | 21 +++++++++--- - drivers/gpu/drm/v3d/v3d_drv.h | 2 ++ - drivers/gpu/drm/v3d/v3d_gem.c | 12 ++++++- - drivers/gpu/drm/v3d/v3d_irq.c | 34 ++++++++++++++----- - 5 files changed, 63 insertions(+), 17 deletions(-) - ---- a/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.txt -+++ b/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.txt -@@ -6,15 +6,20 @@ For V3D 2.x, see brcm,bcm-vc4.txt. - Required properties: - - compatible: Should be "brcm,7268-v3d" or "brcm,7278-v3d" - - reg: Physical base addresses and lengths of the register areas --- reg-names: Names for the register areas. The "hub", "bridge", and "core0" -+- reg-names: Names for the register areas. The "hub" and "core0" - register areas are always required. The "gca" register area -- is required if the GCA cache controller is present. -+ is required if the GCA cache controller is present. The -+ "bridge" register area is required if an external reset -+ controller is not present. - - interrupts: The interrupt numbers. The first interrupt is for the hub, -- while the following interrupts are for the cores. -+ while the following interrupts are separate interrupt lines -+ for the cores (if they don't share the hub's interrupt). - See bindings/interrupt-controller/interrupts.txt - - Optional properties: - - clocks: The core clock the unit runs on -+- resets: The reset line for v3d, if not using a mapping of the bridge -+ See bindings/reset/reset.txt - - v3d { - compatible = "brcm,7268-v3d"; ---- a/drivers/gpu/drm/v3d/v3d_drv.c -+++ b/drivers/gpu/drm/v3d/v3d_drv.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -265,10 +266,6 @@ static int v3d_platform_drm_probe(struct - v3d->pdev = pdev; - drm = &v3d->drm; - -- ret = map_regs(v3d, &v3d->bridge_regs, "bridge"); -- if (ret) -- goto dev_free; -- - ret = map_regs(v3d, &v3d->hub_regs, "hub"); - if (ret) - goto dev_free; -@@ -283,6 +280,22 @@ static int v3d_platform_drm_probe(struct - v3d->cores = V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_NCORES); - WARN_ON(v3d->cores > 1); /* multicore not yet implemented */ - -+ v3d->reset = devm_reset_control_get_exclusive(dev, NULL); -+ if (IS_ERR(v3d->reset)) { -+ ret = PTR_ERR(v3d->reset); -+ -+ if (ret == -EPROBE_DEFER) -+ goto dev_free; -+ -+ v3d->reset = NULL; -+ ret = map_regs(v3d, &v3d->bridge_regs, "bridge"); -+ if (ret) { -+ dev_err(dev, -+ "Failed to get reset control or bridge regs\n"); -+ goto dev_free; -+ } -+ } -+ - if (v3d->ver < 41) { - ret = map_regs(v3d, &v3d->gca_regs, "gca"); - if (ret) ---- a/drivers/gpu/drm/v3d/v3d_drv.h -+++ b/drivers/gpu/drm/v3d/v3d_drv.h -@@ -34,6 +34,7 @@ struct v3d_dev { - * and revision. - */ - int ver; -+ bool single_irq_line; - - struct device *dev; - struct platform_device *pdev; -@@ -42,6 +43,7 @@ struct v3d_dev { - void __iomem *bridge_regs; - void __iomem *gca_regs; - struct clk *clk; -+ struct reset_control *reset; - - /* Virtual and DMA addresses of the single shared page table. */ - volatile u32 *pt; ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -6,6 +6,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -69,7 +70,7 @@ v3d_idle_gca(struct v3d_dev *v3d) - } - - static void --v3d_reset_v3d(struct v3d_dev *v3d) -+v3d_reset_by_bridge(struct v3d_dev *v3d) - { - int version = V3D_BRIDGE_READ(V3D_TOP_GR_BRIDGE_REVISION); - -@@ -89,6 +90,15 @@ v3d_reset_v3d(struct v3d_dev *v3d) - V3D_TOP_GR_BRIDGE_SW_INIT_1_V3D_CLK_108_SW_INIT); - V3D_BRIDGE_WRITE(V3D_TOP_GR_BRIDGE_SW_INIT_1, 0); - } -+} -+ -+static void -+v3d_reset_v3d(struct v3d_dev *v3d) -+{ -+ if (v3d->reset) -+ reset_control_reset(v3d->reset); -+ else -+ v3d_reset_by_bridge(v3d); - - v3d_init_hw_state(v3d); - } ---- a/drivers/gpu/drm/v3d/v3d_irq.c -+++ b/drivers/gpu/drm/v3d/v3d_irq.c -@@ -27,6 +27,9 @@ - V3D_HUB_INT_MMU_CAP | \ - V3D_HUB_INT_TFUC)) - -+static irqreturn_t -+v3d_hub_irq(int irq, void *arg); -+ - static void - v3d_overflow_mem_work(struct work_struct *work) - { -@@ -112,6 +115,12 @@ v3d_irq(int irq, void *arg) - if (intsts & V3D_INT_GMPV) - dev_err(v3d->dev, "GMP violation\n"); - -+ /* V3D 4.2 wires the hub and core IRQs together, so if we & -+ * didn't see the common one then check hub for MMU IRQs. -+ */ -+ if (v3d->single_irq_line && status == IRQ_NONE) -+ return v3d_hub_irq(irq, arg); -+ - return status; - } - -@@ -170,15 +179,22 @@ v3d_irq_init(struct v3d_dev *v3d) - V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS); - V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS); - -- ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0), -- v3d_hub_irq, IRQF_SHARED, -- "v3d_hub", v3d); -- if (ret) -- goto fail; -- -- ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 1), -- v3d_irq, IRQF_SHARED, -- "v3d_core0", v3d); -+ if (platform_get_irq(v3d->pdev, 1) < 0) { -+ ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0), -+ v3d_irq, IRQF_SHARED, -+ "v3d", v3d); -+ v3d->single_irq_line = true; -+ } else { -+ ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0), -+ v3d_hub_irq, IRQF_SHARED, -+ "v3d_hub", v3d); -+ if (ret) -+ goto fail; -+ -+ ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 1), -+ v3d_irq, IRQF_SHARED, -+ "v3d_core0", v3d); -+ } - if (ret) - goto fail; - diff --git a/target/linux/brcm2708/patches-4.19/950-0583-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch b/target/linux/brcm2708/patches-4.19/950-0583-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch new file mode 100644 index 0000000000..92ee960203 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0583-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch @@ -0,0 +1,52 @@ +From 7cfea1be1c757c983e632f56dc8f9dde42c9170d Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 14 Jan 2019 12:35:43 -0800 +Subject: [PATCH 583/725] drm/v3d: Skip MMU flush if the device is currently + off. + +If it's off, we know it will be reset on poweron, so the MMU won't +have any TLB cached from before this point. Avoids failed waits for +MMU flush to reply. + +Signed-off-by: Eric Anholt +(cherry picked from commit 3ee4e2e0a9e9587eacbb69b067bbc72ab2cdc47b) +--- + drivers/gpu/drm/v3d/v3d_mmu.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/drivers/gpu/drm/v3d/v3d_mmu.c ++++ b/drivers/gpu/drm/v3d/v3d_mmu.c +@@ -18,6 +18,8 @@ + * each client. This is not yet implemented. + */ + ++#include ++ + #include "v3d_drv.h" + #include "v3d_regs.h" + +@@ -34,6 +36,14 @@ static int v3d_mmu_flush_all(struct v3d_ + { + int ret; + ++ /* Keep power on the device on until we're done with this ++ * call, but skip the flush if the device is off and will be ++ * reset when powered back on. ++ */ ++ ret = pm_runtime_get_if_in_use(v3d->dev); ++ if (ret == 0) ++ return 0; ++ + /* Make sure that another flush isn't already running when we + * start this one. + */ +@@ -61,6 +71,9 @@ static int v3d_mmu_flush_all(struct v3d_ + if (ret) + dev_err(v3d->dev, "MMUC flush wait idle failed\n"); + ++ pm_runtime_mark_last_busy(v3d->dev); ++ pm_runtime_put_autosuspend(v3d->dev); ++ + return ret; + } + diff --git a/target/linux/brcm2708/patches-4.19/950-0584-drm-v3d-Don-t-try-to-set-OVRTMUOUT-on-V3D-4.x.patch b/target/linux/brcm2708/patches-4.19/950-0584-drm-v3d-Don-t-try-to-set-OVRTMUOUT-on-V3D-4.x.patch deleted file mode 100644 index d65ffb926a..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0584-drm-v3d-Don-t-try-to-set-OVRTMUOUT-on-V3D-4.x.patch +++ /dev/null @@ -1,42 +0,0 @@ -From d4b98e9e78d87fe34b89077b9776a66f19d23856 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Tue, 16 Oct 2018 10:13:41 -0700 -Subject: [PATCH 584/703] drm/v3d: Don't try to set OVRTMUOUT on V3D 4.x. - -The old field is gone and the register now has a different field, -QRMAXCNT for how many TMU requests get serviced before thread switch. -We were accidentally reducing it from its default of 0x3 (4 requests) -to 0x0 (1). - -v2: Skip setting the reg at all on 4.x, instead of trying to update - only the old field. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/v3d/v3d_gem.c | 3 ++- - drivers/gpu/drm/v3d/v3d_regs.h | 2 ++ - 2 files changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -25,7 +25,8 @@ v3d_init_core(struct v3d_dev *v3d, int c - * type. If you want the default behavior, you can still put - * "2" in the indirect texture state's output_type field. - */ -- V3D_CORE_WRITE(core, V3D_CTL_MISCCFG, V3D_MISCCFG_OVRTMUOUT); -+ if (v3d->ver < 40) -+ V3D_CORE_WRITE(core, V3D_CTL_MISCCFG, V3D_MISCCFG_OVRTMUOUT); - - /* Whenever we flush the L2T cache, we always want to flush - * the whole thing. ---- a/drivers/gpu/drm/v3d/v3d_regs.h -+++ b/drivers/gpu/drm/v3d/v3d_regs.h -@@ -216,6 +216,8 @@ - # define V3D_IDENT2_BCG_INT BIT(28) - - #define V3D_CTL_MISCCFG 0x00018 -+# define V3D_CTL_MISCCFG_QRMAXCNT_MASK V3D_MASK(3, 1) -+# define V3D_CTL_MISCCFG_QRMAXCNT_SHIFT 1 - # define V3D_MISCCFG_OVRTMUOUT BIT(0) - - #define V3D_CTL_L2CACTL 0x00020 diff --git a/target/linux/brcm2708/patches-4.19/950-0584-drm-v3d-Hook-up-the-runtime-PM-ops.patch b/target/linux/brcm2708/patches-4.19/950-0584-drm-v3d-Hook-up-the-runtime-PM-ops.patch new file mode 100644 index 0000000000..86a490ef6d --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0584-drm-v3d-Hook-up-the-runtime-PM-ops.patch @@ -0,0 +1,34 @@ +From f436620c2c61e76adcd2d4d694ad9f4d87f301e3 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 14 Jan 2019 14:47:57 -0800 +Subject: [PATCH 584/725] drm/v3d: Hook up the runtime PM ops. + +In translating the runtime PM code from vc4, I missed the ".pm" +assignment to actually connect them up. Fixes missing MMU setup if +runtime PM resets V3D. + +Signed-off-by: Eric Anholt +(cherry picked from commit ca197699af29baa8236c74c53d4904ca8957ee06) +--- + drivers/gpu/drm/v3d/v3d_drv.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/v3d/v3d_drv.c ++++ b/drivers/gpu/drm/v3d/v3d_drv.c +@@ -66,7 +66,7 @@ static int v3d_runtime_resume(struct dev + } + #endif + +-static const struct dev_pm_ops v3d_v3d_pm_ops = { ++static const struct dev_pm_ops v3d_pm_ops = { + SET_RUNTIME_PM_OPS(v3d_runtime_suspend, v3d_runtime_resume, NULL) + }; + +@@ -371,6 +371,7 @@ static struct platform_driver v3d_platfo + .driver = { + .name = "v3d", + .of_match_table = v3d_of_match, ++ .pm = &v3d_pm_ops, + }, + }; + diff --git a/target/linux/brcm2708/patches-4.19/950-0585-drm-v3d-HACK-gut-runtime-pm-for-now.patch b/target/linux/brcm2708/patches-4.19/950-0585-drm-v3d-HACK-gut-runtime-pm-for-now.patch new file mode 100644 index 0000000000..1b4dcd038d --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0585-drm-v3d-HACK-gut-runtime-pm-for-now.patch @@ -0,0 +1,172 @@ +From f9ed79254b9bc0063bd65ebc1ef0b5b789e81e17 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 14 Jan 2019 15:13:17 -0800 +Subject: [PATCH 585/725] drm/v3d: HACK: gut runtime pm for now. + +Something is still unstable -- on starting a new glxgears from an idle +X11, I get an MMU violation in high addresses. The CTS also failed +quite quickly. With this, CTS progresses for an hour before OOMing +(allocating some big buffers when my board only has 600MB available to +Linux) + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/v3d/v3d_debugfs.c | 16 +--------------- + drivers/gpu/drm/v3d/v3d_drv.c | 7 ------- + drivers/gpu/drm/v3d/v3d_gem.c | 20 -------------------- + 3 files changed, 1 insertion(+), 42 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_debugfs.c ++++ b/drivers/gpu/drm/v3d/v3d_debugfs.c +@@ -4,7 +4,6 @@ + #include + #include + #include +-#include + #include + #include + +@@ -100,11 +99,8 @@ static int v3d_v3d_debugfs_ident(struct + struct drm_device *dev = node->minor->dev; + struct v3d_dev *v3d = to_v3d_dev(dev); + u32 ident0, ident1, ident2, ident3, cores; +- int ret, core; ++ int core; + +- ret = pm_runtime_get_sync(v3d->dev); +- if (ret < 0) +- return ret; + + ident0 = V3D_READ(V3D_HUB_IDENT0); + ident1 = V3D_READ(V3D_HUB_IDENT1); +@@ -157,9 +153,6 @@ static int v3d_v3d_debugfs_ident(struct + (misccfg & V3D_MISCCFG_OVRTMUOUT) != 0); + } + +- pm_runtime_mark_last_busy(v3d->dev); +- pm_runtime_put_autosuspend(v3d->dev); +- + return 0; + } + +@@ -187,11 +180,6 @@ static int v3d_measure_clock(struct seq_ + uint32_t cycles; + int core = 0; + int measure_ms = 1000; +- int ret; +- +- ret = pm_runtime_get_sync(v3d->dev); +- if (ret < 0) +- return ret; + + if (v3d->ver >= 40) { + V3D_CORE_WRITE(core, V3D_V4_PCTR_0_SRC_0_3, +@@ -215,8 +203,6 @@ static int v3d_measure_clock(struct seq_ + cycles / (measure_ms * 1000), + (cycles / (measure_ms * 100)) % 10); + +- pm_runtime_mark_last_busy(v3d->dev); +- pm_runtime_put_autosuspend(v3d->dev); + + return 0; + } +--- a/drivers/gpu/drm/v3d/v3d_drv.c ++++ b/drivers/gpu/drm/v3d/v3d_drv.c +@@ -75,7 +75,6 @@ static int v3d_get_param_ioctl(struct dr + { + struct v3d_dev *v3d = to_v3d_dev(dev); + struct drm_v3d_get_param *args = data; +- int ret; + static const u32 reg_map[] = { + [DRM_V3D_PARAM_V3D_UIFCFG] = V3D_HUB_UIFCFG, + [DRM_V3D_PARAM_V3D_HUB_IDENT1] = V3D_HUB_IDENT1, +@@ -101,15 +100,12 @@ static int v3d_get_param_ioctl(struct dr + if (args->value != 0) + return -EINVAL; + +- ret = pm_runtime_get_sync(v3d->dev); + if (args->param >= DRM_V3D_PARAM_V3D_CORE0_IDENT0 && + args->param <= DRM_V3D_PARAM_V3D_CORE0_IDENT2) { + args->value = V3D_CORE_READ(0, offset); + } else { + args->value = V3D_READ(offset); + } +- pm_runtime_mark_last_busy(v3d->dev); +- pm_runtime_put_autosuspend(v3d->dev); + return 0; + } + +@@ -311,9 +307,6 @@ static int v3d_platform_drm_probe(struct + goto dev_free; + } + +- pm_runtime_use_autosuspend(dev); +- pm_runtime_set_autosuspend_delay(dev, 50); +- pm_runtime_enable(dev); + + ret = drm_dev_init(&v3d->drm, &v3d_drm_driver, dev); + if (ret) +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -375,7 +375,6 @@ v3d_exec_cleanup(struct kref *ref) + { + struct v3d_exec_info *exec = container_of(ref, struct v3d_exec_info, + refcount); +- struct v3d_dev *v3d = exec->v3d; + unsigned int i; + struct v3d_bo *bo, *save; + +@@ -396,9 +395,6 @@ v3d_exec_cleanup(struct kref *ref) + drm_gem_object_put_unlocked(&bo->base); + } + +- pm_runtime_mark_last_busy(v3d->dev); +- pm_runtime_put_autosuspend(v3d->dev); +- + kfree(exec); + } + +@@ -412,7 +408,6 @@ v3d_tfu_job_cleanup(struct kref *ref) + { + struct v3d_tfu_job *job = container_of(ref, struct v3d_tfu_job, + refcount); +- struct v3d_dev *v3d = job->v3d; + unsigned int i; + + dma_fence_put(job->in_fence); +@@ -423,9 +418,6 @@ v3d_tfu_job_cleanup(struct kref *ref) + drm_gem_object_put_unlocked(&job->bo[i]->base); + } + +- pm_runtime_mark_last_busy(v3d->dev); +- pm_runtime_put_autosuspend(v3d->dev); +- + kfree(job); + } + +@@ -519,12 +511,6 @@ v3d_submit_cl_ioctl(struct drm_device *d + if (!exec) + return -ENOMEM; + +- ret = pm_runtime_get_sync(v3d->dev); +- if (ret < 0) { +- kfree(exec); +- return ret; +- } +- + kref_init(&exec->refcount); + + ret = drm_syncobj_find_fence(file_priv, args->in_sync_bcl, +@@ -643,12 +629,6 @@ v3d_submit_tfu_ioctl(struct drm_device * + if (!job) + return -ENOMEM; + +- ret = pm_runtime_get_sync(v3d->dev); +- if (ret < 0) { +- kfree(job); +- return ret; +- } +- + kref_init(&job->refcount); + + ret = drm_syncobj_find_fence(file_priv, args->in_sync, diff --git a/target/linux/brcm2708/patches-4.19/950-0585-drm-v3d-Make-sure-the-GPU-is-on-when-measuring-clock.patch b/target/linux/brcm2708/patches-4.19/950-0585-drm-v3d-Make-sure-the-GPU-is-on-when-measuring-clock.patch deleted file mode 100644 index 7daa2043f7..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0585-drm-v3d-Make-sure-the-GPU-is-on-when-measuring-clock.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 51a1e9604fdd215581d7974a185809b1ac93adac Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 14 Jan 2019 17:26:04 -0800 -Subject: [PATCH 585/703] drm/v3d: Make sure the GPU is on when measuring - clocks. - -You'll get garbage measurements if the registers always read back -0xdeadbeef - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/v3d/v3d_debugfs.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/gpu/drm/v3d/v3d_debugfs.c -+++ b/drivers/gpu/drm/v3d/v3d_debugfs.c -@@ -187,6 +187,11 @@ static int v3d_measure_clock(struct seq_ - uint32_t cycles; - int core = 0; - int measure_ms = 1000; -+ int ret; -+ -+ ret = pm_runtime_get_sync(v3d->dev); -+ if (ret < 0) -+ return ret; - - if (v3d->ver >= 40) { - V3D_CORE_WRITE(core, V3D_V4_PCTR_0_SRC_0_3, -@@ -210,6 +215,9 @@ static int v3d_measure_clock(struct seq_ - cycles / (measure_ms * 1000), - (cycles / (measure_ms * 100)) % 10); - -+ pm_runtime_mark_last_busy(v3d->dev); -+ pm_runtime_put_autosuspend(v3d->dev); -+ - return 0; - } - diff --git a/target/linux/brcm2708/patches-4.19/950-0586-drm-v3d-Add-support-for-2711.patch b/target/linux/brcm2708/patches-4.19/950-0586-drm-v3d-Add-support-for-2711.patch deleted file mode 100644 index ad1ef90c31..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0586-drm-v3d-Add-support-for-2711.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 2990828736d42f8308e9ef4e5ca0e8165c952eea Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 4 Oct 2018 17:22:43 -0700 -Subject: [PATCH 586/703] drm/v3d: Add support for 2711. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/v3d/v3d_drv.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/gpu/drm/v3d/v3d_drv.c -+++ b/drivers/gpu/drm/v3d/v3d_drv.c -@@ -235,6 +235,7 @@ static struct drm_driver v3d_drm_driver - static const struct of_device_id v3d_of_match[] = { - { .compatible = "brcm,7268-v3d" }, - { .compatible = "brcm,7278-v3d" }, -+ { .compatible = "brcm,2711-v3d" }, - {}, - }; - MODULE_DEVICE_TABLE(of, v3d_of_match); diff --git a/target/linux/brcm2708/patches-4.19/950-0586-drm-v3d-Update-to-upstream-IRQ-code.patch b/target/linux/brcm2708/patches-4.19/950-0586-drm-v3d-Update-to-upstream-IRQ-code.patch new file mode 100644 index 0000000000..5f4115d8c4 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0586-drm-v3d-Update-to-upstream-IRQ-code.patch @@ -0,0 +1,59 @@ +From 1e3a40ffdfe1bafc7e0a0dcbeeff92a1f2a6655b Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Tue, 12 Mar 2019 09:08:10 -0700 +Subject: [PATCH 586/725] drm/v3d: Update to upstream IRQ code. + +--- + drivers/gpu/drm/v3d/v3d_irq.c | 25 +++++++++++++++---------- + 1 file changed, 15 insertions(+), 10 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_irq.c ++++ b/drivers/gpu/drm/v3d/v3d_irq.c +@@ -168,7 +168,7 @@ v3d_hub_irq(int irq, void *arg) + int + v3d_irq_init(struct v3d_dev *v3d) + { +- int ret, core; ++ int irq1, ret, core; + + INIT_WORK(&v3d->overflow_mem_work, v3d_overflow_mem_work); + +@@ -179,24 +179,29 @@ v3d_irq_init(struct v3d_dev *v3d) + V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS); + V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS); + +- if (platform_get_irq(v3d->pdev, 1) < 0) { +- ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0), ++ irq1 = platform_get_irq(v3d->pdev, 1); ++ if (irq1 == -EPROBE_DEFER) ++ return irq1; ++ if (irq1 > 0) { ++ ret = devm_request_irq(v3d->dev, irq1, + v3d_irq, IRQF_SHARED, +- "v3d", v3d); +- v3d->single_irq_line = true; +- } else { ++ "v3d_core0", v3d); ++ if (ret) ++ goto fail; + ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0), + v3d_hub_irq, IRQF_SHARED, + "v3d_hub", v3d); + if (ret) + goto fail; ++ } else { ++ v3d->single_irq_line = true; + +- ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 1), ++ ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0), + v3d_irq, IRQF_SHARED, +- "v3d_core0", v3d); ++ "v3d", v3d); ++ if (ret) ++ goto fail; + } +- if (ret) +- goto fail; + + v3d_irq_enable(v3d); + return 0; diff --git a/target/linux/brcm2708/patches-4.19/950-0587-drm-v3d-Rename-the-fence-signaled-from-IRQs-to-irq_f.patch b/target/linux/brcm2708/patches-4.19/950-0587-drm-v3d-Rename-the-fence-signaled-from-IRQs-to-irq_f.patch new file mode 100644 index 0000000000..a96f769d07 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0587-drm-v3d-Rename-the-fence-signaled-from-IRQs-to-irq_f.patch @@ -0,0 +1,117 @@ +From 17b0b9ba33df31ade992e46501f1b03296b758c7 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 27 Dec 2018 14:04:44 -0800 +Subject: [PATCH 587/725] drm/v3d: Rename the fence signaled from IRQs to + "irq_fence". + +We have another thing called the "done fence" that tracks when the +scheduler considers the job done, and having the shared name was +confusing. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/v3d/v3d_drv.h | 4 ++-- + drivers/gpu/drm/v3d/v3d_gem.c | 6 +++--- + drivers/gpu/drm/v3d/v3d_irq.c | 6 +++--- + drivers/gpu/drm/v3d/v3d_sched.c | 12 ++++++------ + 4 files changed, 14 insertions(+), 14 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_drv.h ++++ b/drivers/gpu/drm/v3d/v3d_drv.h +@@ -182,7 +182,7 @@ struct v3d_job { + struct dma_fence *in_fence; + + /* v3d fence to be signaled by IRQ handler when the job is complete. */ +- struct dma_fence *done_fence; ++ struct dma_fence *irq_fence; + + /* GPU virtual addresses of the start/end of the CL job. */ + u32 start, end; +@@ -229,7 +229,7 @@ struct v3d_tfu_job { + struct dma_fence *in_fence; + + /* v3d fence to be signaled by IRQ handler when the job is complete. */ +- struct dma_fence *done_fence; ++ struct dma_fence *irq_fence; + + struct v3d_dev *v3d; + +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -381,8 +381,8 @@ v3d_exec_cleanup(struct kref *ref) + dma_fence_put(exec->bin.in_fence); + dma_fence_put(exec->render.in_fence); + +- dma_fence_put(exec->bin.done_fence); +- dma_fence_put(exec->render.done_fence); ++ dma_fence_put(exec->bin.irq_fence); ++ dma_fence_put(exec->render.irq_fence); + + dma_fence_put(exec->bin_done_fence); + dma_fence_put(exec->render_done_fence); +@@ -411,7 +411,7 @@ v3d_tfu_job_cleanup(struct kref *ref) + unsigned int i; + + dma_fence_put(job->in_fence); +- dma_fence_put(job->done_fence); ++ dma_fence_put(job->irq_fence); + + for (i = 0; i < ARRAY_SIZE(job->bo); i++) { + if (job->bo[i]) +--- a/drivers/gpu/drm/v3d/v3d_irq.c ++++ b/drivers/gpu/drm/v3d/v3d_irq.c +@@ -93,7 +93,7 @@ v3d_irq(int irq, void *arg) + + if (intsts & V3D_INT_FLDONE) { + struct v3d_fence *fence = +- to_v3d_fence(v3d->bin_job->bin.done_fence); ++ to_v3d_fence(v3d->bin_job->bin.irq_fence); + + trace_v3d_bcl_irq(&v3d->drm, fence->seqno); + dma_fence_signal(&fence->base); +@@ -102,7 +102,7 @@ v3d_irq(int irq, void *arg) + + if (intsts & V3D_INT_FRDONE) { + struct v3d_fence *fence = +- to_v3d_fence(v3d->render_job->render.done_fence); ++ to_v3d_fence(v3d->render_job->render.irq_fence); + + trace_v3d_rcl_irq(&v3d->drm, fence->seqno); + dma_fence_signal(&fence->base); +@@ -138,7 +138,7 @@ v3d_hub_irq(int irq, void *arg) + + if (intsts & V3D_HUB_INT_TFUC) { + struct v3d_fence *fence = +- to_v3d_fence(v3d->tfu_job->done_fence); ++ to_v3d_fence(v3d->tfu_job->irq_fence); + + trace_v3d_tfu_irq(&v3d->drm, fence->seqno); + dma_fence_signal(&fence->base); +--- a/drivers/gpu/drm/v3d/v3d_sched.c ++++ b/drivers/gpu/drm/v3d/v3d_sched.c +@@ -152,9 +152,9 @@ static struct dma_fence *v3d_job_run(str + if (IS_ERR(fence)) + return NULL; + +- if (job->done_fence) +- dma_fence_put(job->done_fence); +- job->done_fence = dma_fence_get(fence); ++ if (job->irq_fence) ++ dma_fence_put(job->irq_fence); ++ job->irq_fence = dma_fence_get(fence); + + trace_v3d_submit_cl(dev, q == V3D_RENDER, to_v3d_fence(fence)->seqno, + job->start, job->end); +@@ -195,9 +195,9 @@ v3d_tfu_job_run(struct drm_sched_job *sc + return NULL; + + v3d->tfu_job = job; +- if (job->done_fence) +- dma_fence_put(job->done_fence); +- job->done_fence = dma_fence_get(fence); ++ if (job->irq_fence) ++ dma_fence_put(job->irq_fence); ++ job->irq_fence = dma_fence_get(fence); + + trace_v3d_submit_tfu(dev, to_v3d_fence(fence)->seqno); + diff --git a/target/linux/brcm2708/patches-4.19/950-0587-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch b/target/linux/brcm2708/patches-4.19/950-0587-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch deleted file mode 100644 index 01c64d2c45..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0587-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 2e3f1f0991163004ea441307ab52ce4ea3e068d7 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 14 Jan 2019 12:35:43 -0800 -Subject: [PATCH 587/703] drm/v3d: Skip MMU flush if the device is currently - off. - -If it's off, we know it will be reset on poweron, so the MMU won't -have any TLB cached from before this point. Avoids failed waits for -MMU flush to reply. - -Signed-off-by: Eric Anholt -(cherry picked from commit 3ee4e2e0a9e9587eacbb69b067bbc72ab2cdc47b) ---- - drivers/gpu/drm/v3d/v3d_mmu.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - ---- a/drivers/gpu/drm/v3d/v3d_mmu.c -+++ b/drivers/gpu/drm/v3d/v3d_mmu.c -@@ -18,6 +18,8 @@ - * each client. This is not yet implemented. - */ - -+#include -+ - #include "v3d_drv.h" - #include "v3d_regs.h" - -@@ -34,6 +36,14 @@ static int v3d_mmu_flush_all(struct v3d_ - { - int ret; - -+ /* Keep power on the device on until we're done with this -+ * call, but skip the flush if the device is off and will be -+ * reset when powered back on. -+ */ -+ ret = pm_runtime_get_if_in_use(v3d->dev); -+ if (ret == 0) -+ return 0; -+ - /* Make sure that another flush isn't already running when we - * start this one. - */ -@@ -61,6 +71,9 @@ static int v3d_mmu_flush_all(struct v3d_ - if (ret) - dev_err(v3d->dev, "MMUC flush wait idle failed\n"); - -+ pm_runtime_mark_last_busy(v3d->dev); -+ pm_runtime_put_autosuspend(v3d->dev); -+ - return ret; - } - diff --git a/target/linux/brcm2708/patches-4.19/950-0588-drm-v3d-Hook-up-the-runtime-PM-ops.patch b/target/linux/brcm2708/patches-4.19/950-0588-drm-v3d-Hook-up-the-runtime-PM-ops.patch deleted file mode 100644 index 8c0cdf4966..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0588-drm-v3d-Hook-up-the-runtime-PM-ops.patch +++ /dev/null @@ -1,34 +0,0 @@ -From ee17d7708bdf44fb3e04045c661b317245d90c1a Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 14 Jan 2019 14:47:57 -0800 -Subject: [PATCH 588/703] drm/v3d: Hook up the runtime PM ops. - -In translating the runtime PM code from vc4, I missed the ".pm" -assignment to actually connect them up. Fixes missing MMU setup if -runtime PM resets V3D. - -Signed-off-by: Eric Anholt -(cherry picked from commit ca197699af29baa8236c74c53d4904ca8957ee06) ---- - drivers/gpu/drm/v3d/v3d_drv.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/v3d/v3d_drv.c -+++ b/drivers/gpu/drm/v3d/v3d_drv.c -@@ -66,7 +66,7 @@ static int v3d_runtime_resume(struct dev - } - #endif - --static const struct dev_pm_ops v3d_v3d_pm_ops = { -+static const struct dev_pm_ops v3d_pm_ops = { - SET_RUNTIME_PM_OPS(v3d_runtime_suspend, v3d_runtime_resume, NULL) - }; - -@@ -371,6 +371,7 @@ static struct platform_driver v3d_platfo - .driver = { - .name = "v3d", - .of_match_table = v3d_of_match, -+ .pm = &v3d_pm_ops, - }, - }; - diff --git a/target/linux/brcm2708/patches-4.19/950-0588-drm-v3d-Refactor-job-management.patch b/target/linux/brcm2708/patches-4.19/950-0588-drm-v3d-Refactor-job-management.patch new file mode 100644 index 0000000000..4600798d5a --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0588-drm-v3d-Refactor-job-management.patch @@ -0,0 +1,1104 @@ +From 83e671a4dbca6b0a1d2fad326f6cb8316d25e9e0 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 27 Dec 2018 12:11:52 -0800 +Subject: [PATCH 588/725] drm/v3d: Refactor job management. + +The CL submission had two jobs embedded in an exec struct. When I +added TFU support, I had to replicate some of the exec stuff and some +of the job stuff. As I went to add CSD, it became clear that actually +what was in exec should just be in the two CL jobs, and it would let +us share a lot more code between the 4 queues. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/v3d/v3d_drv.h | 77 ++++---- + drivers/gpu/drm/v3d/v3d_gem.c | 331 +++++++++++++++++--------------- + drivers/gpu/drm/v3d/v3d_irq.c | 8 +- + drivers/gpu/drm/v3d/v3d_sched.c | 264 ++++++++++++++----------- + 4 files changed, 373 insertions(+), 307 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_drv.h ++++ b/drivers/gpu/drm/v3d/v3d_drv.h +@@ -67,8 +67,8 @@ struct v3d_dev { + + struct work_struct overflow_mem_work; + +- struct v3d_exec_info *bin_job; +- struct v3d_exec_info *render_job; ++ struct v3d_bin_job *bin_job; ++ struct v3d_render_job *render_job; + struct v3d_tfu_job *tfu_job; + + struct v3d_queue_state queue[V3D_MAX_QUEUES]; +@@ -132,7 +132,7 @@ struct v3d_bo { + struct list_head vmas; /* list of v3d_vma */ + + /* List entry for the BO's position in +- * v3d_exec_info->unref_list ++ * v3d_render_job->unref_list + */ + struct list_head unref_head; + +@@ -176,7 +176,15 @@ to_v3d_fence(struct dma_fence *fence) + struct v3d_job { + struct drm_sched_job base; + +- struct v3d_exec_info *exec; ++ struct kref refcount; ++ ++ struct v3d_dev *v3d; ++ ++ /* This is the array of BOs that were looked up at the start ++ * of submission. ++ */ ++ struct v3d_bo **bo; ++ u32 bo_count; + + /* An optional fence userspace can pass in for the job to depend on. */ + struct dma_fence *in_fence; +@@ -184,59 +192,53 @@ struct v3d_job { + /* v3d fence to be signaled by IRQ handler when the job is complete. */ + struct dma_fence *irq_fence; + ++ /* scheduler fence for when the job is considered complete and ++ * the BO reservations can be released. ++ */ ++ struct dma_fence *done_fence; ++ ++ /* Callback for the freeing of the job on refcount going to 0. */ ++ void (*free)(struct kref *ref); ++}; ++ ++struct v3d_bin_job { ++ struct v3d_job base; ++ + /* GPU virtual addresses of the start/end of the CL job. */ + u32 start, end; + + u32 timedout_ctca, timedout_ctra; +-}; + +-struct v3d_exec_info { +- struct v3d_dev *v3d; ++ /* Corresponding render job, for attaching our overflow memory. */ ++ struct v3d_render_job *render; ++ ++ /* Submitted tile memory allocation start/size, tile state. */ ++ u32 qma, qms, qts; ++}; + +- struct v3d_job bin, render; ++struct v3d_render_job { ++ struct v3d_job base; + +- /* Fence for when the scheduler considers the binner to be +- * done, for render to depend on. ++ /* Optional fence for the binner, to depend on before starting ++ * our job. + */ + struct dma_fence *bin_done_fence; + +- /* Fence for when the scheduler considers the render to be +- * done, for when the BOs reservations should be complete. +- */ +- struct dma_fence *render_done_fence; +- +- struct kref refcount; ++ /* GPU virtual addresses of the start/end of the CL job. */ ++ u32 start, end; + +- /* This is the array of BOs that were looked up at the start of exec. */ +- struct v3d_bo **bo; +- u32 bo_count; ++ u32 timedout_ctca, timedout_ctra; + + /* List of overflow BOs used in the job that need to be + * released once the job is complete. + */ + struct list_head unref_list; +- +- /* Submitted tile memory allocation start/size, tile state. */ +- u32 qma, qms, qts; + }; + + struct v3d_tfu_job { +- struct drm_sched_job base; ++ struct v3d_job base; + + struct drm_v3d_submit_tfu args; +- +- /* An optional fence userspace can pass in for the job to depend on. */ +- struct dma_fence *in_fence; +- +- /* v3d fence to be signaled by IRQ handler when the job is complete. */ +- struct dma_fence *irq_fence; +- +- struct v3d_dev *v3d; +- +- struct kref refcount; +- +- /* This is the array of BOs that were looked up at the start of exec. */ +- struct v3d_bo *bo[4]; + }; + + /** +@@ -306,8 +308,7 @@ int v3d_submit_tfu_ioctl(struct drm_devi + struct drm_file *file_priv); + int v3d_wait_bo_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +-void v3d_exec_put(struct v3d_exec_info *exec); +-void v3d_tfu_job_put(struct v3d_tfu_job *exec); ++void v3d_job_put(struct v3d_job *job); + void v3d_reset(struct v3d_dev *v3d); + void v3d_invalidate_caches(struct v3d_dev *v3d); + +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -293,11 +293,11 @@ retry: + } + + /** +- * v3d_cl_lookup_bos() - Sets up exec->bo[] with the GEM objects ++ * v3d_lookup_bos() - Sets up job->bo[] with the GEM objects + * referenced by the job. + * @dev: DRM device + * @file_priv: DRM file for this fd +- * @exec: V3D job being set up ++ * @job: V3D job being set up + * + * The command validator needs to reference BOs by their index within + * the submitted job's BO list. This does the validation of the job's +@@ -307,18 +307,19 @@ retry: + * failure, because that will happen at v3d_exec_cleanup() time. + */ + static int +-v3d_cl_lookup_bos(struct drm_device *dev, +- struct drm_file *file_priv, +- struct drm_v3d_submit_cl *args, +- struct v3d_exec_info *exec) ++v3d_lookup_bos(struct drm_device *dev, ++ struct drm_file *file_priv, ++ struct v3d_job *job, ++ u64 bo_handles, ++ u32 bo_count) + { + u32 *handles; + int ret = 0; + int i; + +- exec->bo_count = args->bo_handle_count; ++ job->bo_count = bo_count; + +- if (!exec->bo_count) { ++ if (!job->bo_count) { + /* See comment on bo_index for why we have to check + * this. + */ +@@ -326,15 +327,15 @@ v3d_cl_lookup_bos(struct drm_device *dev + return -EINVAL; + } + +- exec->bo = kvmalloc_array(exec->bo_count, +- sizeof(struct drm_gem_cma_object *), +- GFP_KERNEL | __GFP_ZERO); +- if (!exec->bo) { ++ job->bo = kvmalloc_array(job->bo_count, ++ sizeof(struct drm_gem_cma_object *), ++ GFP_KERNEL | __GFP_ZERO); ++ if (!job->bo) { + DRM_DEBUG("Failed to allocate validated BO pointers\n"); + return -ENOMEM; + } + +- handles = kvmalloc_array(exec->bo_count, sizeof(u32), GFP_KERNEL); ++ handles = kvmalloc_array(job->bo_count, sizeof(u32), GFP_KERNEL); + if (!handles) { + ret = -ENOMEM; + DRM_DEBUG("Failed to allocate incoming GEM handles\n"); +@@ -342,15 +343,15 @@ v3d_cl_lookup_bos(struct drm_device *dev + } + + if (copy_from_user(handles, +- (void __user *)(uintptr_t)args->bo_handles, +- exec->bo_count * sizeof(u32))) { ++ (void __user *)(uintptr_t)bo_handles, ++ job->bo_count * sizeof(u32))) { + ret = -EFAULT; + DRM_DEBUG("Failed to copy in GEM handles\n"); + goto fail; + } + + spin_lock(&file_priv->table_lock); +- for (i = 0; i < exec->bo_count; i++) { ++ for (i = 0; i < job->bo_count; i++) { + struct drm_gem_object *bo = idr_find(&file_priv->object_idr, + handles[i]); + if (!bo) { +@@ -361,7 +362,7 @@ v3d_cl_lookup_bos(struct drm_device *dev + goto fail; + } + drm_gem_object_get(bo); +- exec->bo[i] = to_v3d_bo(bo); ++ job->bo[i] = to_v3d_bo(bo); + } + spin_unlock(&file_priv->table_lock); + +@@ -371,59 +372,41 @@ fail: + } + + static void +-v3d_exec_cleanup(struct kref *ref) ++v3d_job_free(struct kref *ref) + { +- struct v3d_exec_info *exec = container_of(ref, struct v3d_exec_info, +- refcount); +- unsigned int i; +- struct v3d_bo *bo, *save; +- +- dma_fence_put(exec->bin.in_fence); +- dma_fence_put(exec->render.in_fence); +- +- dma_fence_put(exec->bin.irq_fence); +- dma_fence_put(exec->render.irq_fence); +- +- dma_fence_put(exec->bin_done_fence); +- dma_fence_put(exec->render_done_fence); +- +- for (i = 0; i < exec->bo_count; i++) +- drm_gem_object_put_unlocked(&exec->bo[i]->base); +- kvfree(exec->bo); ++ struct v3d_job *job = container_of(ref, struct v3d_job, refcount); ++ int i; + +- list_for_each_entry_safe(bo, save, &exec->unref_list, unref_head) { +- drm_gem_object_put_unlocked(&bo->base); ++ for (i = 0; i < job->bo_count; i++) { ++ if (job->bo[i]) ++ drm_gem_object_put_unlocked(&job->bo[i]->base); + } ++ kvfree(job->bo); + +- kfree(exec); +-} ++ dma_fence_put(job->in_fence); ++ dma_fence_put(job->irq_fence); ++ dma_fence_put(job->done_fence); + +-void v3d_exec_put(struct v3d_exec_info *exec) +-{ +- kref_put(&exec->refcount, v3d_exec_cleanup); ++ kfree(job); + } + + static void +-v3d_tfu_job_cleanup(struct kref *ref) ++v3d_render_job_free(struct kref *ref) + { +- struct v3d_tfu_job *job = container_of(ref, struct v3d_tfu_job, +- refcount); +- unsigned int i; +- +- dma_fence_put(job->in_fence); +- dma_fence_put(job->irq_fence); ++ struct v3d_render_job *job = container_of(ref, struct v3d_render_job, ++ base.refcount); ++ struct v3d_bo *bo, *save; + +- for (i = 0; i < ARRAY_SIZE(job->bo); i++) { +- if (job->bo[i]) +- drm_gem_object_put_unlocked(&job->bo[i]->base); ++ list_for_each_entry_safe(bo, save, &job->unref_list, unref_head) { ++ drm_gem_object_put_unlocked(&bo->base); + } + +- kfree(job); ++ v3d_job_free(ref); + } + +-void v3d_tfu_job_put(struct v3d_tfu_job *job) ++void v3d_job_put(struct v3d_job *job) + { +- kref_put(&job->refcount, v3d_tfu_job_cleanup); ++ kref_put(&job->refcount, job->free); + } + + int +@@ -476,6 +459,65 @@ v3d_wait_bo_ioctl(struct drm_device *dev + return ret; + } + ++static int ++v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv, ++ struct v3d_job *job, void (*free)(struct kref *ref), ++ u32 in_sync) ++{ ++ int ret; ++ ++ job->v3d = v3d; ++ job->free = free; ++ ++ ret = drm_syncobj_find_fence(file_priv, in_sync, 0, &job->in_fence); ++ if (ret == -EINVAL) ++ return ret; ++ ++ kref_init(&job->refcount); ++ ++ return 0; ++} ++ ++static int ++v3d_push_job(struct v3d_file_priv *v3d_priv, ++ struct v3d_job *job, enum v3d_queue queue) ++{ ++ int ret; ++ ++ ret = drm_sched_job_init(&job->base, &v3d_priv->sched_entity[queue], ++ v3d_priv); ++ if (ret) ++ return ret; ++ ++ job->done_fence = dma_fence_get(&job->base.s_fence->finished); ++ ++ /* put by scheduler job completion */ ++ kref_get(&job->refcount); ++ ++ drm_sched_entity_push_job(&job->base, &v3d_priv->sched_entity[queue]); ++ ++ return 0; ++} ++ ++static void ++v3d_attach_fences_and_unlock_reservation(struct drm_file *file_priv, ++ struct v3d_job *job, ++ struct ww_acquire_ctx *acquire_ctx, ++ u32 out_sync) ++{ ++ struct drm_syncobj *sync_out; ++ ++ v3d_attach_object_fences(job->bo, job->bo_count, job->done_fence); ++ v3d_unlock_bo_reservations(job->bo, job->bo_count, acquire_ctx); ++ ++ /* Update the return sync object for the job */ ++ sync_out = drm_syncobj_find(file_priv, out_sync); ++ if (sync_out) { ++ drm_syncobj_replace_fence(sync_out, job->done_fence); ++ drm_syncobj_put(sync_out); ++ } ++} ++ + /** + * v3d_submit_cl_ioctl() - Submits a job (frame) to the V3D. + * @dev: DRM device +@@ -495,9 +537,9 @@ v3d_submit_cl_ioctl(struct drm_device *d + struct v3d_dev *v3d = to_v3d_dev(dev); + struct v3d_file_priv *v3d_priv = file_priv->driver_priv; + struct drm_v3d_submit_cl *args = data; +- struct v3d_exec_info *exec; ++ struct v3d_bin_job *bin = NULL; ++ struct v3d_render_job *render; + struct ww_acquire_ctx acquire_ctx; +- struct drm_syncobj *sync_out; + int ret = 0; + + trace_v3d_submit_cl_ioctl(&v3d->drm, args->rcl_start, args->rcl_end); +@@ -507,95 +549,84 @@ v3d_submit_cl_ioctl(struct drm_device *d + return -EINVAL; + } + +- exec = kcalloc(1, sizeof(*exec), GFP_KERNEL); +- if (!exec) ++ render = kcalloc(1, sizeof(*render), GFP_KERNEL); ++ if (!render) + return -ENOMEM; + +- kref_init(&exec->refcount); ++ render->start = args->rcl_start; ++ render->end = args->rcl_end; ++ INIT_LIST_HEAD(&render->unref_list); + +- ret = drm_syncobj_find_fence(file_priv, args->in_sync_bcl, +- 0, &exec->bin.in_fence); +- if (ret == -EINVAL) +- goto fail; ++ ret = v3d_job_init(v3d, file_priv, &render->base, ++ v3d_render_job_free, args->in_sync_rcl); ++ if (ret) { ++ kfree(bin); ++ kfree(render); ++ return ret; ++ } + +- ret = drm_syncobj_find_fence(file_priv, args->in_sync_rcl, +- 0, &exec->render.in_fence); +- if (ret == -EINVAL) +- goto fail; ++ if (args->bcl_start != args->bcl_end) { ++ bin = kcalloc(1, sizeof(*bin), GFP_KERNEL); ++ if (!bin) ++ return -ENOMEM; ++ ++ ret = v3d_job_init(v3d, file_priv, &bin->base, ++ v3d_job_free, args->in_sync_bcl); ++ if (ret) { ++ v3d_job_put(&render->base); ++ return ret; ++ } + +- exec->qma = args->qma; +- exec->qms = args->qms; +- exec->qts = args->qts; +- exec->bin.exec = exec; +- exec->bin.start = args->bcl_start; +- exec->bin.end = args->bcl_end; +- exec->render.exec = exec; +- exec->render.start = args->rcl_start; +- exec->render.end = args->rcl_end; +- exec->v3d = v3d; +- INIT_LIST_HEAD(&exec->unref_list); ++ bin->start = args->bcl_start; ++ bin->end = args->bcl_end; ++ bin->qma = args->qma; ++ bin->qms = args->qms; ++ bin->qts = args->qts; ++ bin->render = render; ++ } + +- ret = v3d_cl_lookup_bos(dev, file_priv, args, exec); ++ ret = v3d_lookup_bos(dev, file_priv, &render->base, ++ args->bo_handles, args->bo_handle_count); + if (ret) + goto fail; + +- ret = v3d_lock_bo_reservations(exec->bo, exec->bo_count, ++ ret = v3d_lock_bo_reservations(render->base.bo, render->base.bo_count, + &acquire_ctx); + if (ret) + goto fail; + + mutex_lock(&v3d->sched_lock); +- if (exec->bin.start != exec->bin.end) { +- ret = drm_sched_job_init(&exec->bin.base, +- &v3d_priv->sched_entity[V3D_BIN], +- v3d_priv); ++ if (bin) { ++ ret = v3d_push_job(v3d_priv, &bin->base, V3D_BIN); + if (ret) + goto fail_unreserve; + +- exec->bin_done_fence = +- dma_fence_get(&exec->bin.base.s_fence->finished); +- +- kref_get(&exec->refcount); /* put by scheduler job completion */ +- drm_sched_entity_push_job(&exec->bin.base, +- &v3d_priv->sched_entity[V3D_BIN]); ++ render->bin_done_fence = dma_fence_get(bin->base.done_fence); + } + +- ret = drm_sched_job_init(&exec->render.base, +- &v3d_priv->sched_entity[V3D_RENDER], +- v3d_priv); ++ ret = v3d_push_job(v3d_priv, &render->base, V3D_RENDER); + if (ret) + goto fail_unreserve; +- +- exec->render_done_fence = +- dma_fence_get(&exec->render.base.s_fence->finished); +- +- kref_get(&exec->refcount); /* put by scheduler job completion */ +- drm_sched_entity_push_job(&exec->render.base, +- &v3d_priv->sched_entity[V3D_RENDER]); + mutex_unlock(&v3d->sched_lock); + +- v3d_attach_object_fences(exec->bo, exec->bo_count, +- exec->render_done_fence); +- +- v3d_unlock_bo_reservations(exec->bo, exec->bo_count, &acquire_ctx); +- +- /* Update the return sync object for the */ +- sync_out = drm_syncobj_find(file_priv, args->out_sync); +- if (sync_out) { +- drm_syncobj_replace_fence(sync_out, +- exec->render_done_fence); +- drm_syncobj_put(sync_out); +- } +- +- v3d_exec_put(exec); ++ v3d_attach_fences_and_unlock_reservation(file_priv, ++ &render->base, &acquire_ctx, ++ args->out_sync); ++ ++ if (bin) ++ v3d_job_put(&bin->base); ++ v3d_job_put(&render->base); + + return 0; + + fail_unreserve: + mutex_unlock(&v3d->sched_lock); +- v3d_unlock_bo_reservations(exec->bo, exec->bo_count, &acquire_ctx); ++ v3d_unlock_bo_reservations(render->base.bo, ++ render->base.bo_count, &acquire_ctx); + fail: +- v3d_exec_put(exec); ++ if (bin) ++ v3d_job_put(&bin->base); ++ v3d_job_put(&render->base); + + return ret; + } +@@ -618,10 +649,7 @@ v3d_submit_tfu_ioctl(struct drm_device * + struct drm_v3d_submit_tfu *args = data; + struct v3d_tfu_job *job; + struct ww_acquire_ctx acquire_ctx; +- struct drm_syncobj *sync_out; +- struct dma_fence *sched_done_fence; + int ret = 0; +- int bo_count; + + trace_v3d_submit_tfu_ioctl(&v3d->drm, args->iia); + +@@ -629,75 +657,66 @@ v3d_submit_tfu_ioctl(struct drm_device * + if (!job) + return -ENOMEM; + +- kref_init(&job->refcount); +- +- ret = drm_syncobj_find_fence(file_priv, args->in_sync, +- 0, &job->in_fence); +- if (ret == -EINVAL) +- goto fail; ++ ret = v3d_job_init(v3d, file_priv, &job->base, ++ v3d_job_free, args->in_sync); ++ if (ret) { ++ kfree(job); ++ return ret; ++ } + ++ job->base.bo = kcalloc(ARRAY_SIZE(args->bo_handles), ++ sizeof(*job->base.bo), GFP_KERNEL); + job->args = *args; +- job->v3d = v3d; + + spin_lock(&file_priv->table_lock); +- for (bo_count = 0; bo_count < ARRAY_SIZE(job->bo); bo_count++) { ++ for (job->base.bo_count = 0; ++ job->base.bo_count < ARRAY_SIZE(args->bo_handles); ++ job->base.bo_count++) { + struct drm_gem_object *bo; + +- if (!args->bo_handles[bo_count]) ++ if (!args->bo_handles[job->base.bo_count]) + break; + + bo = idr_find(&file_priv->object_idr, +- args->bo_handles[bo_count]); ++ args->bo_handles[job->base.bo_count]); + if (!bo) { + DRM_DEBUG("Failed to look up GEM BO %d: %d\n", +- bo_count, args->bo_handles[bo_count]); ++ job->base.bo_count, ++ args->bo_handles[job->base.bo_count]); + ret = -ENOENT; + spin_unlock(&file_priv->table_lock); + goto fail; + } + drm_gem_object_get(bo); +- job->bo[bo_count] = to_v3d_bo(bo); ++ job->base.bo[job->base.bo_count] = to_v3d_bo(bo); + } + spin_unlock(&file_priv->table_lock); + +- ret = v3d_lock_bo_reservations(job->bo, bo_count, &acquire_ctx); ++ ret = v3d_lock_bo_reservations(job->base.bo, job->base.bo_count, ++ &acquire_ctx); + if (ret) + goto fail; + + mutex_lock(&v3d->sched_lock); +- ret = drm_sched_job_init(&job->base, +- &v3d_priv->sched_entity[V3D_TFU], +- v3d_priv); ++ ret = v3d_push_job(v3d_priv, &job->base, V3D_TFU); + if (ret) + goto fail_unreserve; +- +- sched_done_fence = dma_fence_get(&job->base.s_fence->finished); +- +- kref_get(&job->refcount); /* put by scheduler job completion */ +- drm_sched_entity_push_job(&job->base, &v3d_priv->sched_entity[V3D_TFU]); + mutex_unlock(&v3d->sched_lock); + +- v3d_attach_object_fences(job->bo, bo_count, sched_done_fence); +- +- v3d_unlock_bo_reservations(job->bo, bo_count, &acquire_ctx); +- +- /* Update the return sync object */ +- sync_out = drm_syncobj_find(file_priv, args->out_sync); +- if (sync_out) { +- drm_syncobj_replace_fence(sync_out, sched_done_fence); +- drm_syncobj_put(sync_out); +- } +- dma_fence_put(sched_done_fence); ++ v3d_attach_fences_and_unlock_reservation(file_priv, ++ &job->base, &acquire_ctx, ++ args->out_sync); + +- v3d_tfu_job_put(job); ++ v3d_job_put(&job->base); + + return 0; + + fail_unreserve: + mutex_unlock(&v3d->sched_lock); +- v3d_unlock_bo_reservations(job->bo, bo_count, &acquire_ctx); ++ v3d_unlock_bo_reservations(job->base.bo, job->base.bo_count, ++ &acquire_ctx); + fail: +- v3d_tfu_job_put(job); ++ v3d_job_put(&job->base); + + return ret; + } +@@ -755,7 +774,7 @@ v3d_gem_destroy(struct drm_device *dev) + + v3d_sched_fini(v3d); + +- /* Waiting for exec to finish would need to be done before ++ /* Waiting for jobs to finish would need to be done before + * unregistering V3D. + */ + WARN_ON(v3d->bin_job); +--- a/drivers/gpu/drm/v3d/v3d_irq.c ++++ b/drivers/gpu/drm/v3d/v3d_irq.c +@@ -60,7 +60,7 @@ v3d_overflow_mem_work(struct work_struct + } + + drm_gem_object_get(&bo->base); +- list_add_tail(&bo->unref_head, &v3d->bin_job->unref_list); ++ list_add_tail(&bo->unref_head, &v3d->bin_job->render->unref_list); + spin_unlock_irqrestore(&v3d->job_lock, irqflags); + + V3D_CORE_WRITE(0, V3D_PTB_BPOA, bo->node.start << PAGE_SHIFT); +@@ -93,7 +93,7 @@ v3d_irq(int irq, void *arg) + + if (intsts & V3D_INT_FLDONE) { + struct v3d_fence *fence = +- to_v3d_fence(v3d->bin_job->bin.irq_fence); ++ to_v3d_fence(v3d->bin_job->base.irq_fence); + + trace_v3d_bcl_irq(&v3d->drm, fence->seqno); + dma_fence_signal(&fence->base); +@@ -102,7 +102,7 @@ v3d_irq(int irq, void *arg) + + if (intsts & V3D_INT_FRDONE) { + struct v3d_fence *fence = +- to_v3d_fence(v3d->render_job->render.irq_fence); ++ to_v3d_fence(v3d->render_job->base.irq_fence); + + trace_v3d_rcl_irq(&v3d->drm, fence->seqno); + dma_fence_signal(&fence->base); +@@ -138,7 +138,7 @@ v3d_hub_irq(int irq, void *arg) + + if (intsts & V3D_HUB_INT_TFUC) { + struct v3d_fence *fence = +- to_v3d_fence(v3d->tfu_job->irq_fence); ++ to_v3d_fence(v3d->tfu_job->base.irq_fence); + + trace_v3d_tfu_irq(&v3d->drm, fence->seqno); + dma_fence_signal(&fence->base); +--- a/drivers/gpu/drm/v3d/v3d_sched.c ++++ b/drivers/gpu/drm/v3d/v3d_sched.c +@@ -30,39 +30,43 @@ to_v3d_job(struct drm_sched_job *sched_j + return container_of(sched_job, struct v3d_job, base); + } + +-static struct v3d_tfu_job * +-to_tfu_job(struct drm_sched_job *sched_job) ++static struct v3d_bin_job * ++to_bin_job(struct drm_sched_job *sched_job) + { +- return container_of(sched_job, struct v3d_tfu_job, base); ++ return container_of(sched_job, struct v3d_bin_job, base.base); + } + +-static void +-v3d_job_free(struct drm_sched_job *sched_job) ++static struct v3d_render_job * ++to_render_job(struct drm_sched_job *sched_job) + { +- struct v3d_job *job = to_v3d_job(sched_job); ++ return container_of(sched_job, struct v3d_render_job, base.base); ++} + +- v3d_exec_put(job->exec); ++static struct v3d_tfu_job * ++to_tfu_job(struct drm_sched_job *sched_job) ++{ ++ return container_of(sched_job, struct v3d_tfu_job, base.base); + } + + static void +-v3d_tfu_job_free(struct drm_sched_job *sched_job) ++v3d_job_free(struct drm_sched_job *sched_job) + { +- struct v3d_tfu_job *job = to_tfu_job(sched_job); ++ struct v3d_job *job = to_v3d_job(sched_job); + +- v3d_tfu_job_put(job); ++ v3d_job_put(job); + } + + /** +- * Returns the fences that the bin or render job depends on, one by one. +- * v3d_job_run() won't be called until all of them have been signaled. ++ * Returns the fences that the job depends on, one by one. ++ * ++ * If placed in the scheduler's .dependency method, the corresponding ++ * .run_job won't be called until all of them have been signaled. + */ + static struct dma_fence * + v3d_job_dependency(struct drm_sched_job *sched_job, + struct drm_sched_entity *s_entity) + { + struct v3d_job *job = to_v3d_job(sched_job); +- struct v3d_exec_info *exec = job->exec; +- enum v3d_queue q = job == &exec->bin ? V3D_BIN : V3D_RENDER; + struct dma_fence *fence; + + fence = job->in_fence; +@@ -71,113 +75,132 @@ v3d_job_dependency(struct drm_sched_job + return fence; + } + +- if (q == V3D_RENDER) { +- /* If we had a bin job, the render job definitely depends on +- * it. We first have to wait for bin to be scheduled, so that +- * its done_fence is created. +- */ +- fence = exec->bin_done_fence; +- if (fence) { +- exec->bin_done_fence = NULL; +- return fence; +- } +- } +- +- /* XXX: Wait on a fence for switching the GMP if necessary, +- * and then do so. +- */ +- +- return fence; ++ return NULL; + } + + /** +- * Returns the fences that the TFU job depends on, one by one. +- * v3d_tfu_job_run() won't be called until all of them have been +- * signaled. ++ * Returns the fences that the render job depends on, one by one. ++ * v3d_job_run() won't be called until all of them have been signaled. + */ + static struct dma_fence * +-v3d_tfu_job_dependency(struct drm_sched_job *sched_job, +- struct drm_sched_entity *s_entity) ++v3d_render_job_dependency(struct drm_sched_job *sched_job, ++ struct drm_sched_entity *s_entity) + { +- struct v3d_tfu_job *job = to_tfu_job(sched_job); ++ struct v3d_render_job *job = to_render_job(sched_job); + struct dma_fence *fence; + +- fence = job->in_fence; ++ fence = v3d_job_dependency(sched_job, s_entity); ++ if (fence) ++ return fence; ++ ++ /* If we had a bin job, the render job definitely depends on ++ * it. We first have to wait for bin to be scheduled, so that ++ * its done_fence is created. ++ */ ++ fence = job->bin_done_fence; + if (fence) { +- job->in_fence = NULL; ++ job->bin_done_fence = NULL; + return fence; + } + +- return NULL; ++ /* XXX: Wait on a fence for switching the GMP if necessary, ++ * and then do so. ++ */ ++ ++ return fence; + } + +-static struct dma_fence *v3d_job_run(struct drm_sched_job *sched_job) ++static struct dma_fence *v3d_bin_job_run(struct drm_sched_job *sched_job) + { +- struct v3d_job *job = to_v3d_job(sched_job); +- struct v3d_exec_info *exec = job->exec; +- enum v3d_queue q = job == &exec->bin ? V3D_BIN : V3D_RENDER; +- struct v3d_dev *v3d = exec->v3d; ++ struct v3d_bin_job *job = to_bin_job(sched_job); ++ struct v3d_dev *v3d = job->base.v3d; + struct drm_device *dev = &v3d->drm; + struct dma_fence *fence; + unsigned long irqflags; + +- if (unlikely(job->base.s_fence->finished.error)) ++ if (unlikely(job->base.base.s_fence->finished.error)) + return NULL; + + /* Lock required around bin_job update vs + * v3d_overflow_mem_work(). + */ + spin_lock_irqsave(&v3d->job_lock, irqflags); +- if (q == V3D_BIN) { +- v3d->bin_job = job->exec; ++ v3d->bin_job = job; ++ /* Clear out the overflow allocation, so we don't ++ * reuse the overflow attached to a previous job. ++ */ ++ V3D_CORE_WRITE(0, V3D_PTB_BPOS, 0); ++ spin_unlock_irqrestore(&v3d->job_lock, irqflags); ++ ++ v3d_invalidate_caches(v3d); + +- /* Clear out the overflow allocation, so we don't +- * reuse the overflow attached to a previous job. +- */ +- V3D_CORE_WRITE(0, V3D_PTB_BPOS, 0); +- } else { +- v3d->render_job = job->exec; ++ fence = v3d_fence_create(v3d, V3D_BIN); ++ if (IS_ERR(fence)) ++ return NULL; ++ ++ if (job->base.irq_fence) ++ dma_fence_put(job->base.irq_fence); ++ job->base.irq_fence = dma_fence_get(fence); ++ ++ trace_v3d_submit_cl(dev, false, to_v3d_fence(fence)->seqno, ++ job->start, job->end); ++ ++ /* Set the current and end address of the control list. ++ * Writing the end register is what starts the job. ++ */ ++ if (job->qma) { ++ V3D_CORE_WRITE(0, V3D_CLE_CT0QMA, job->qma); ++ V3D_CORE_WRITE(0, V3D_CLE_CT0QMS, job->qms); + } +- spin_unlock_irqrestore(&v3d->job_lock, irqflags); ++ if (job->qts) { ++ V3D_CORE_WRITE(0, V3D_CLE_CT0QTS, ++ V3D_CLE_CT0QTS_ENABLE | ++ job->qts); ++ } ++ V3D_CORE_WRITE(0, V3D_CLE_CT0QBA, job->start); ++ V3D_CORE_WRITE(0, V3D_CLE_CT0QEA, job->end); ++ ++ return fence; ++} ++ ++static struct dma_fence *v3d_render_job_run(struct drm_sched_job *sched_job) ++{ ++ struct v3d_render_job *job = to_render_job(sched_job); ++ struct v3d_dev *v3d = job->base.v3d; ++ struct drm_device *dev = &v3d->drm; ++ struct dma_fence *fence; ++ ++ if (unlikely(job->base.base.s_fence->finished.error)) ++ return NULL; + +- /* Can we avoid this flush when q==RENDER? We need to be +- * careful of scheduling, though -- imagine job0 rendering to +- * texture and job1 reading, and them being executed as bin0, +- * bin1, render0, render1, so that render1's flush at bin time ++ v3d->render_job = job; ++ ++ /* Can we avoid this flush? We need to be careful of ++ * scheduling, though -- imagine job0 rendering to texture and ++ * job1 reading, and them being executed as bin0, bin1, ++ * render0, render1, so that render1's flush at bin time + * wasn't enough. + */ + v3d_invalidate_caches(v3d); + +- fence = v3d_fence_create(v3d, q); ++ fence = v3d_fence_create(v3d, V3D_RENDER); + if (IS_ERR(fence)) + return NULL; + +- if (job->irq_fence) +- dma_fence_put(job->irq_fence); +- job->irq_fence = dma_fence_get(fence); ++ if (job->base.irq_fence) ++ dma_fence_put(job->base.irq_fence); ++ job->base.irq_fence = dma_fence_get(fence); + +- trace_v3d_submit_cl(dev, q == V3D_RENDER, to_v3d_fence(fence)->seqno, ++ trace_v3d_submit_cl(dev, true, to_v3d_fence(fence)->seqno, + job->start, job->end); + +- if (q == V3D_BIN) { +- if (exec->qma) { +- V3D_CORE_WRITE(0, V3D_CLE_CT0QMA, exec->qma); +- V3D_CORE_WRITE(0, V3D_CLE_CT0QMS, exec->qms); +- } +- if (exec->qts) { +- V3D_CORE_WRITE(0, V3D_CLE_CT0QTS, +- V3D_CLE_CT0QTS_ENABLE | +- exec->qts); +- } +- } else { +- /* XXX: Set the QCFG */ +- } ++ /* XXX: Set the QCFG */ + + /* Set the current and end address of the control list. + * Writing the end register is what starts the job. + */ +- V3D_CORE_WRITE(0, V3D_CLE_CTNQBA(q), job->start); +- V3D_CORE_WRITE(0, V3D_CLE_CTNQEA(q), job->end); ++ V3D_CORE_WRITE(0, V3D_CLE_CT1QBA, job->start); ++ V3D_CORE_WRITE(0, V3D_CLE_CT1QEA, job->end); + + return fence; + } +@@ -186,7 +209,7 @@ static struct dma_fence * + v3d_tfu_job_run(struct drm_sched_job *sched_job) + { + struct v3d_tfu_job *job = to_tfu_job(sched_job); +- struct v3d_dev *v3d = job->v3d; ++ struct v3d_dev *v3d = job->base.v3d; + struct drm_device *dev = &v3d->drm; + struct dma_fence *fence; + +@@ -195,9 +218,9 @@ v3d_tfu_job_run(struct drm_sched_job *sc + return NULL; + + v3d->tfu_job = job; +- if (job->irq_fence) +- dma_fence_put(job->irq_fence); +- job->irq_fence = dma_fence_get(fence); ++ if (job->base.irq_fence) ++ dma_fence_put(job->base.irq_fence); ++ job->base.irq_fence = dma_fence_get(fence); + + trace_v3d_submit_tfu(dev, to_v3d_fence(fence)->seqno); + +@@ -247,25 +270,23 @@ v3d_gpu_reset_for_timeout(struct v3d_dev + mutex_unlock(&v3d->reset_lock); + } + ++/* If the current address or return address have changed, then the GPU ++ * has probably made progress and we should delay the reset. This ++ * could fail if the GPU got in an infinite loop in the CL, but that ++ * is pretty unlikely outside of an i-g-t testcase. ++ */ + static void +-v3d_job_timedout(struct drm_sched_job *sched_job) ++v3d_cl_job_timedout(struct drm_sched_job *sched_job, enum v3d_queue q, ++ u32 *timedout_ctca, u32 *timedout_ctra) + { + struct v3d_job *job = to_v3d_job(sched_job); +- struct v3d_exec_info *exec = job->exec; +- struct v3d_dev *v3d = exec->v3d; +- enum v3d_queue job_q = job == &exec->bin ? V3D_BIN : V3D_RENDER; +- u32 ctca = V3D_CORE_READ(0, V3D_CLE_CTNCA(job_q)); +- u32 ctra = V3D_CORE_READ(0, V3D_CLE_CTNRA(job_q)); +- +- /* If the current address or return address have changed, then +- * the GPU has probably made progress and we should delay the +- * reset. This could fail if the GPU got in an infinite loop +- * in the CL, but that is pretty unlikely outside of an i-g-t +- * testcase. +- */ +- if (job->timedout_ctca != ctca || job->timedout_ctra != ctra) { +- job->timedout_ctca = ctca; +- job->timedout_ctra = ctra; ++ struct v3d_dev *v3d = job->v3d; ++ u32 ctca = V3D_CORE_READ(0, V3D_CLE_CTNCA(q)); ++ u32 ctra = V3D_CORE_READ(0, V3D_CLE_CTNRA(q)); ++ ++ if (*timedout_ctca != ctca || *timedout_ctra != ctra) { ++ *timedout_ctca = ctca; ++ *timedout_ctra = ctra; + schedule_delayed_work(&job->base.work_tdr, + job->base.sched->timeout); + return; +@@ -275,25 +296,50 @@ v3d_job_timedout(struct drm_sched_job *s + } + + static void ++v3d_bin_job_timedout(struct drm_sched_job *sched_job) ++{ ++ struct v3d_bin_job *job = to_bin_job(sched_job); ++ ++ v3d_cl_job_timedout(sched_job, V3D_BIN, ++ &job->timedout_ctca, &job->timedout_ctra); ++} ++ ++static void ++v3d_render_job_timedout(struct drm_sched_job *sched_job) ++{ ++ struct v3d_render_job *job = to_render_job(sched_job); ++ ++ v3d_cl_job_timedout(sched_job, V3D_RENDER, ++ &job->timedout_ctca, &job->timedout_ctra); ++} ++ ++static void + v3d_tfu_job_timedout(struct drm_sched_job *sched_job) + { +- struct v3d_tfu_job *job = to_tfu_job(sched_job); ++ struct v3d_job *job = to_v3d_job(sched_job); + + v3d_gpu_reset_for_timeout(job->v3d, sched_job); + } + +-static const struct drm_sched_backend_ops v3d_sched_ops = { ++static const struct drm_sched_backend_ops v3d_bin_sched_ops = { + .dependency = v3d_job_dependency, +- .run_job = v3d_job_run, +- .timedout_job = v3d_job_timedout, +- .free_job = v3d_job_free ++ .run_job = v3d_bin_job_run, ++ .timedout_job = v3d_bin_job_timedout, ++ .free_job = v3d_job_free, ++}; ++ ++static const struct drm_sched_backend_ops v3d_render_sched_ops = { ++ .dependency = v3d_render_job_dependency, ++ .run_job = v3d_render_job_run, ++ .timedout_job = v3d_render_job_timedout, ++ .free_job = v3d_job_free, + }; + + static const struct drm_sched_backend_ops v3d_tfu_sched_ops = { +- .dependency = v3d_tfu_job_dependency, ++ .dependency = v3d_job_dependency, + .run_job = v3d_tfu_job_run, + .timedout_job = v3d_tfu_job_timedout, +- .free_job = v3d_tfu_job_free ++ .free_job = v3d_job_free, + }; + + int +@@ -305,7 +351,7 @@ v3d_sched_init(struct v3d_dev *v3d) + int ret; + + ret = drm_sched_init(&v3d->queue[V3D_BIN].sched, +- &v3d_sched_ops, ++ &v3d_bin_sched_ops, + hw_jobs_limit, job_hang_limit, + msecs_to_jiffies(hang_limit_ms), + "v3d_bin"); +@@ -315,7 +361,7 @@ v3d_sched_init(struct v3d_dev *v3d) + } + + ret = drm_sched_init(&v3d->queue[V3D_RENDER].sched, +- &v3d_sched_ops, ++ &v3d_render_sched_ops, + hw_jobs_limit, job_hang_limit, + msecs_to_jiffies(hang_limit_ms), + "v3d_render"); diff --git a/target/linux/brcm2708/patches-4.19/950-0589-drm-v3d-Add-missing-implicit-synchronization.patch b/target/linux/brcm2708/patches-4.19/950-0589-drm-v3d-Add-missing-implicit-synchronization.patch new file mode 100644 index 0000000000..a465130c26 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0589-drm-v3d-Add-missing-implicit-synchronization.patch @@ -0,0 +1,279 @@ +From 55757fd208de69d0701ac9d6e368d9647549d74f Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 27 Mar 2019 17:44:40 -0700 +Subject: [PATCH 589/725] drm/v3d: Add missing implicit synchronization. + +It is the expectation of existing userspace (X11 + Mesa, in +particular) that jobs submitted to the kernel against a shared BO will +get implicitly synchronized by their submission order. If we want to +allow clever userspace to disable implicit synchronization, we should +do that under its own submit flag (as amdgpu and lima do). + +Note that we currently only implicitly sync for the rendering pass, +not binning -- if you texture-from-pixmap in the binning vertex shader +(vertex coordinate generation), you'll miss out on synchronization. + +Fixes flickering when multiple clients are running in parallel, +particularly GL apps and compositors. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/v3d/v3d_drv.h | 10 +--- + drivers/gpu/drm/v3d/v3d_gem.c | 98 ++++++++++++++++++++++++++++++--- + drivers/gpu/drm/v3d/v3d_sched.c | 45 ++------------- + 3 files changed, 96 insertions(+), 57 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_drv.h ++++ b/drivers/gpu/drm/v3d/v3d_drv.h +@@ -186,8 +186,9 @@ struct v3d_job { + struct v3d_bo **bo; + u32 bo_count; + +- /* An optional fence userspace can pass in for the job to depend on. */ +- struct dma_fence *in_fence; ++ struct dma_fence **deps; ++ int deps_count; ++ int deps_size; + + /* v3d fence to be signaled by IRQ handler when the job is complete. */ + struct dma_fence *irq_fence; +@@ -219,11 +220,6 @@ struct v3d_bin_job { + struct v3d_render_job { + struct v3d_job base; + +- /* Optional fence for the binner, to depend on before starting +- * our job. +- */ +- struct dma_fence *bin_done_fence; +- + /* GPU virtual addresses of the start/end of the CL job. */ + u32 start, end; + +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -218,6 +218,71 @@ v3d_unlock_bo_reservations(struct v3d_bo + ww_acquire_fini(acquire_ctx); + } + ++static int ++v3d_add_dep(struct v3d_job *job, struct dma_fence *fence) ++{ ++ if (!fence) ++ return 0; ++ ++ if (job->deps_size == job->deps_count) { ++ int new_deps_size = max(job->deps_size * 2, 4); ++ struct dma_fence **new_deps = ++ krealloc(job->deps, new_deps_size * sizeof(*new_deps), ++ GFP_KERNEL); ++ if (!new_deps) { ++ dma_fence_put(fence); ++ return -ENOMEM; ++ } ++ ++ job->deps = new_deps; ++ job->deps_size = new_deps_size; ++ } ++ ++ job->deps[job->deps_count++] = fence; ++ ++ return 0; ++} ++ ++/** ++ * Adds the required implicit fences before executing the job ++ * ++ * Userspace (X11 + Mesa) requires that a job submitted against a shared BO ++ * from one fd will implicitly synchronize against previous jobs submitted ++ * against that BO from other fds. ++ * ++ * Currently we don't bother trying to track the shared BOs, and instead just ++ * sync everything. However, our synchronization is only for the render pass ++ * -- the binning stage (VS coordinate calculations) ignores implicit sync, ++ * since using shared buffers for texture coordinates seems unlikely, and ++ * implicitly syncing them would break bin/render parallelism. If we want to ++ * fix that, we should introduce a flag when VS texturing has been used in the ++ * binning stage, or a set of flags for which BOs are sampled during binning. ++ */ ++static int ++v3d_add_implicit_fences(struct v3d_job *job, struct v3d_bo *bo) ++{ ++ int i, ret, nr_fences; ++ struct dma_fence **fences; ++ ++ ret = reservation_object_get_fences_rcu(bo->resv, NULL, ++ &nr_fences, &fences); ++ if (ret || !nr_fences) ++ return ret; ++ ++ for (i = 0; i < nr_fences; i++) { ++ ret = v3d_add_dep(job, fences[i]); ++ if (ret) ++ break; ++ } ++ ++ /* Free any remaining fences after error. */ ++ for (; i < nr_fences; i++) ++ dma_fence_put(fences[i]); ++ kfree(fences); ++ ++ return ret; ++} ++ + /* Takes the reservation lock on all the BOs being referenced, so that + * at queue submit time we can update the reservations. + * +@@ -226,10 +291,11 @@ v3d_unlock_bo_reservations(struct v3d_bo + * to v3d, so we don't attach dma-buf fences to them. + */ + static int +-v3d_lock_bo_reservations(struct v3d_bo **bos, +- int bo_count, ++v3d_lock_bo_reservations(struct v3d_job *job, + struct ww_acquire_ctx *acquire_ctx) + { ++ struct v3d_bo **bos = job->bo; ++ int bo_count = job->bo_count; + int contended_lock = -1; + int i, ret; + +@@ -281,6 +347,13 @@ retry: + * before we commit the CL to the hardware. + */ + for (i = 0; i < bo_count; i++) { ++ ret = v3d_add_implicit_fences(job, bos[i]); ++ if (ret) { ++ v3d_unlock_bo_reservations(bos, bo_count, ++ acquire_ctx); ++ return ret; ++ } ++ + ret = reservation_object_reserve_shared(bos[i]->resv); + if (ret) { + v3d_unlock_bo_reservations(bos, bo_count, +@@ -383,7 +456,10 @@ v3d_job_free(struct kref *ref) + } + kvfree(job->bo); + +- dma_fence_put(job->in_fence); ++ for (i = 0; i < job->deps_count; i++) ++ dma_fence_put(job->deps[i]); ++ kfree(job->deps); ++ + dma_fence_put(job->irq_fence); + dma_fence_put(job->done_fence); + +@@ -464,15 +540,20 @@ v3d_job_init(struct v3d_dev *v3d, struct + struct v3d_job *job, void (*free)(struct kref *ref), + u32 in_sync) + { ++ struct dma_fence *in_fence = NULL; + int ret; + + job->v3d = v3d; + job->free = free; + +- ret = drm_syncobj_find_fence(file_priv, in_sync, 0, &job->in_fence); ++ ret = drm_syncobj_find_fence(file_priv, in_sync, 0, &in_fence); + if (ret == -EINVAL) + return ret; + ++ ret = v3d_add_dep(job, in_fence); ++ if (ret) ++ return ret; ++ + kref_init(&job->refcount); + + return 0; +@@ -590,8 +671,7 @@ v3d_submit_cl_ioctl(struct drm_device *d + if (ret) + goto fail; + +- ret = v3d_lock_bo_reservations(render->base.bo, render->base.bo_count, +- &acquire_ctx); ++ ret = v3d_lock_bo_reservations(&render->base, &acquire_ctx); + if (ret) + goto fail; + +@@ -601,7 +681,8 @@ v3d_submit_cl_ioctl(struct drm_device *d + if (ret) + goto fail_unreserve; + +- render->bin_done_fence = dma_fence_get(bin->base.done_fence); ++ ret = v3d_add_dep(&render->base, ++ dma_fence_get(bin->base.done_fence)); + } + + ret = v3d_push_job(v3d_priv, &render->base, V3D_RENDER); +@@ -692,8 +773,7 @@ v3d_submit_tfu_ioctl(struct drm_device * + } + spin_unlock(&file_priv->table_lock); + +- ret = v3d_lock_bo_reservations(job->base.bo, job->base.bo_count, +- &acquire_ctx); ++ ret = v3d_lock_bo_reservations(&job->base, &acquire_ctx); + if (ret) + goto fail; + +--- a/drivers/gpu/drm/v3d/v3d_sched.c ++++ b/drivers/gpu/drm/v3d/v3d_sched.c +@@ -67,47 +67,10 @@ v3d_job_dependency(struct drm_sched_job + struct drm_sched_entity *s_entity) + { + struct v3d_job *job = to_v3d_job(sched_job); +- struct dma_fence *fence; +- +- fence = job->in_fence; +- if (fence) { +- job->in_fence = NULL; +- return fence; +- } +- +- return NULL; +-} + +-/** +- * Returns the fences that the render job depends on, one by one. +- * v3d_job_run() won't be called until all of them have been signaled. +- */ +-static struct dma_fence * +-v3d_render_job_dependency(struct drm_sched_job *sched_job, +- struct drm_sched_entity *s_entity) +-{ +- struct v3d_render_job *job = to_render_job(sched_job); +- struct dma_fence *fence; +- +- fence = v3d_job_dependency(sched_job, s_entity); +- if (fence) +- return fence; +- +- /* If we had a bin job, the render job definitely depends on +- * it. We first have to wait for bin to be scheduled, so that +- * its done_fence is created. +- */ +- fence = job->bin_done_fence; +- if (fence) { +- job->bin_done_fence = NULL; +- return fence; +- } +- +- /* XXX: Wait on a fence for switching the GMP if necessary, +- * and then do so. +- */ +- +- return fence; ++ if (!job->deps_count) ++ return NULL; ++ return job->deps[--job->deps_count]; + } + + static struct dma_fence *v3d_bin_job_run(struct drm_sched_job *sched_job) +@@ -329,7 +292,7 @@ static const struct drm_sched_backend_op + }; + + static const struct drm_sched_backend_ops v3d_render_sched_ops = { +- .dependency = v3d_render_job_dependency, ++ .dependency = v3d_job_dependency, + .run_job = v3d_render_job_run, + .timedout_job = v3d_render_job_timedout, + .free_job = v3d_job_free, diff --git a/target/linux/brcm2708/patches-4.19/950-0589-drm-v3d-HACK-gut-runtime-pm-for-now.patch b/target/linux/brcm2708/patches-4.19/950-0589-drm-v3d-HACK-gut-runtime-pm-for-now.patch deleted file mode 100644 index e87e3ba46f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0589-drm-v3d-HACK-gut-runtime-pm-for-now.patch +++ /dev/null @@ -1,172 +0,0 @@ -From f5ba2c027e3f21bafcbff13ec513d6a10c8dc585 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 14 Jan 2019 15:13:17 -0800 -Subject: [PATCH 589/703] drm/v3d: HACK: gut runtime pm for now. - -Something is still unstable -- on starting a new glxgears from an idle -X11, I get an MMU violation in high addresses. The CTS also failed -quite quickly. With this, CTS progresses for an hour before OOMing -(allocating some big buffers when my board only has 600MB available to -Linux) - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/v3d/v3d_debugfs.c | 16 +--------------- - drivers/gpu/drm/v3d/v3d_drv.c | 7 ------- - drivers/gpu/drm/v3d/v3d_gem.c | 20 -------------------- - 3 files changed, 1 insertion(+), 42 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_debugfs.c -+++ b/drivers/gpu/drm/v3d/v3d_debugfs.c -@@ -4,7 +4,6 @@ - #include - #include - #include --#include - #include - #include - -@@ -100,11 +99,8 @@ static int v3d_v3d_debugfs_ident(struct - struct drm_device *dev = node->minor->dev; - struct v3d_dev *v3d = to_v3d_dev(dev); - u32 ident0, ident1, ident2, ident3, cores; -- int ret, core; -+ int core; - -- ret = pm_runtime_get_sync(v3d->dev); -- if (ret < 0) -- return ret; - - ident0 = V3D_READ(V3D_HUB_IDENT0); - ident1 = V3D_READ(V3D_HUB_IDENT1); -@@ -157,9 +153,6 @@ static int v3d_v3d_debugfs_ident(struct - (misccfg & V3D_MISCCFG_OVRTMUOUT) != 0); - } - -- pm_runtime_mark_last_busy(v3d->dev); -- pm_runtime_put_autosuspend(v3d->dev); -- - return 0; - } - -@@ -187,11 +180,6 @@ static int v3d_measure_clock(struct seq_ - uint32_t cycles; - int core = 0; - int measure_ms = 1000; -- int ret; -- -- ret = pm_runtime_get_sync(v3d->dev); -- if (ret < 0) -- return ret; - - if (v3d->ver >= 40) { - V3D_CORE_WRITE(core, V3D_V4_PCTR_0_SRC_0_3, -@@ -215,8 +203,6 @@ static int v3d_measure_clock(struct seq_ - cycles / (measure_ms * 1000), - (cycles / (measure_ms * 100)) % 10); - -- pm_runtime_mark_last_busy(v3d->dev); -- pm_runtime_put_autosuspend(v3d->dev); - - return 0; - } ---- a/drivers/gpu/drm/v3d/v3d_drv.c -+++ b/drivers/gpu/drm/v3d/v3d_drv.c -@@ -75,7 +75,6 @@ static int v3d_get_param_ioctl(struct dr - { - struct v3d_dev *v3d = to_v3d_dev(dev); - struct drm_v3d_get_param *args = data; -- int ret; - static const u32 reg_map[] = { - [DRM_V3D_PARAM_V3D_UIFCFG] = V3D_HUB_UIFCFG, - [DRM_V3D_PARAM_V3D_HUB_IDENT1] = V3D_HUB_IDENT1, -@@ -101,15 +100,12 @@ static int v3d_get_param_ioctl(struct dr - if (args->value != 0) - return -EINVAL; - -- ret = pm_runtime_get_sync(v3d->dev); - if (args->param >= DRM_V3D_PARAM_V3D_CORE0_IDENT0 && - args->param <= DRM_V3D_PARAM_V3D_CORE0_IDENT2) { - args->value = V3D_CORE_READ(0, offset); - } else { - args->value = V3D_READ(offset); - } -- pm_runtime_mark_last_busy(v3d->dev); -- pm_runtime_put_autosuspend(v3d->dev); - return 0; - } - -@@ -311,9 +307,6 @@ static int v3d_platform_drm_probe(struct - goto dev_free; - } - -- pm_runtime_use_autosuspend(dev); -- pm_runtime_set_autosuspend_delay(dev, 50); -- pm_runtime_enable(dev); - - ret = drm_dev_init(&v3d->drm, &v3d_drm_driver, dev); - if (ret) ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -375,7 +375,6 @@ v3d_exec_cleanup(struct kref *ref) - { - struct v3d_exec_info *exec = container_of(ref, struct v3d_exec_info, - refcount); -- struct v3d_dev *v3d = exec->v3d; - unsigned int i; - struct v3d_bo *bo, *save; - -@@ -396,9 +395,6 @@ v3d_exec_cleanup(struct kref *ref) - drm_gem_object_put_unlocked(&bo->base); - } - -- pm_runtime_mark_last_busy(v3d->dev); -- pm_runtime_put_autosuspend(v3d->dev); -- - kfree(exec); - } - -@@ -412,7 +408,6 @@ v3d_tfu_job_cleanup(struct kref *ref) - { - struct v3d_tfu_job *job = container_of(ref, struct v3d_tfu_job, - refcount); -- struct v3d_dev *v3d = job->v3d; - unsigned int i; - - dma_fence_put(job->in_fence); -@@ -423,9 +418,6 @@ v3d_tfu_job_cleanup(struct kref *ref) - drm_gem_object_put_unlocked(&job->bo[i]->base); - } - -- pm_runtime_mark_last_busy(v3d->dev); -- pm_runtime_put_autosuspend(v3d->dev); -- - kfree(job); - } - -@@ -519,12 +511,6 @@ v3d_submit_cl_ioctl(struct drm_device *d - if (!exec) - return -ENOMEM; - -- ret = pm_runtime_get_sync(v3d->dev); -- if (ret < 0) { -- kfree(exec); -- return ret; -- } -- - kref_init(&exec->refcount); - - ret = drm_syncobj_find_fence(file_priv, args->in_sync_bcl, -@@ -643,12 +629,6 @@ v3d_submit_tfu_ioctl(struct drm_device * - if (!job) - return -ENOMEM; - -- ret = pm_runtime_get_sync(v3d->dev); -- if (ret < 0) { -- kfree(job); -- return ret; -- } -- - kref_init(&job->refcount); - - ret = drm_syncobj_find_fence(file_priv, args->in_sync, diff --git a/target/linux/brcm2708/patches-4.19/950-0590-drm-v3d-Update-to-upstream-IRQ-code.patch b/target/linux/brcm2708/patches-4.19/950-0590-drm-v3d-Update-to-upstream-IRQ-code.patch deleted file mode 100644 index 2cb16a97e6..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0590-drm-v3d-Update-to-upstream-IRQ-code.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 97f75af520bb5c124641b0704ebbd171f80d0bfb Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Tue, 12 Mar 2019 09:08:10 -0700 -Subject: [PATCH 590/703] drm/v3d: Update to upstream IRQ code. - ---- - drivers/gpu/drm/v3d/v3d_irq.c | 25 +++++++++++++++---------- - 1 file changed, 15 insertions(+), 10 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_irq.c -+++ b/drivers/gpu/drm/v3d/v3d_irq.c -@@ -168,7 +168,7 @@ v3d_hub_irq(int irq, void *arg) - int - v3d_irq_init(struct v3d_dev *v3d) - { -- int ret, core; -+ int irq1, ret, core; - - INIT_WORK(&v3d->overflow_mem_work, v3d_overflow_mem_work); - -@@ -179,24 +179,29 @@ v3d_irq_init(struct v3d_dev *v3d) - V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS); - V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS); - -- if (platform_get_irq(v3d->pdev, 1) < 0) { -- ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0), -+ irq1 = platform_get_irq(v3d->pdev, 1); -+ if (irq1 == -EPROBE_DEFER) -+ return irq1; -+ if (irq1 > 0) { -+ ret = devm_request_irq(v3d->dev, irq1, - v3d_irq, IRQF_SHARED, -- "v3d", v3d); -- v3d->single_irq_line = true; -- } else { -+ "v3d_core0", v3d); -+ if (ret) -+ goto fail; - ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0), - v3d_hub_irq, IRQF_SHARED, - "v3d_hub", v3d); - if (ret) - goto fail; -+ } else { -+ v3d->single_irq_line = true; - -- ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 1), -+ ret = devm_request_irq(v3d->dev, platform_get_irq(v3d->pdev, 0), - v3d_irq, IRQF_SHARED, -- "v3d_core0", v3d); -+ "v3d", v3d); -+ if (ret) -+ goto fail; - } -- if (ret) -- goto fail; - - v3d_irq_enable(v3d); - return 0; diff --git a/target/linux/brcm2708/patches-4.19/950-0590-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch b/target/linux/brcm2708/patches-4.19/950-0590-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch new file mode 100644 index 0000000000..d81386b239 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0590-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch @@ -0,0 +1,44 @@ +From 4d3b9226dfa79720e200af46474b2e6f3158d40c Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 28 Mar 2019 11:58:51 -0700 +Subject: [PATCH 590/725] drm/vc4: Fix synchronization firmwarekms against GL + rendering. + +We would present the framebuffer immediately without waiting for +rendering to finish first, resulting in stuttering and flickering as a +window was dragged around when the GPU was busy enough to not just win +the race. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -15,6 +15,7 @@ + */ + + #include "drm/drm_atomic_helper.h" ++#include "drm/drm_gem_framebuffer_helper.h" + #include "drm/drm_plane_helper.h" + #include "drm/drm_crtc_helper.h" + #include "drm/drm_fourcc.h" +@@ -291,7 +292,7 @@ static const struct drm_plane_funcs vc4_ + }; + + static const struct drm_plane_helper_funcs vc4_primary_plane_helper_funcs = { +- .prepare_fb = NULL, ++ .prepare_fb = drm_gem_fb_prepare_fb, + .cleanup_fb = NULL, + .atomic_check = vc4_plane_atomic_check, + .atomic_update = vc4_primary_plane_atomic_update, +@@ -299,7 +300,7 @@ static const struct drm_plane_helper_fun + }; + + static const struct drm_plane_helper_funcs vc4_cursor_plane_helper_funcs = { +- .prepare_fb = NULL, ++ .prepare_fb = drm_gem_fb_prepare_fb, + .cleanup_fb = NULL, + .atomic_check = vc4_plane_atomic_check, + .atomic_update = vc4_cursor_plane_atomic_update, diff --git a/target/linux/brcm2708/patches-4.19/950-0591-drm-v3d-Rename-the-fence-signaled-from-IRQs-to-irq_f.patch b/target/linux/brcm2708/patches-4.19/950-0591-drm-v3d-Rename-the-fence-signaled-from-IRQs-to-irq_f.patch deleted file mode 100644 index c77ec0b1aa..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0591-drm-v3d-Rename-the-fence-signaled-from-IRQs-to-irq_f.patch +++ /dev/null @@ -1,117 +0,0 @@ -From ee870243ebbf7a8a7c5a8c24259a8c37be16b507 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 27 Dec 2018 14:04:44 -0800 -Subject: [PATCH 591/703] drm/v3d: Rename the fence signaled from IRQs to - "irq_fence". - -We have another thing called the "done fence" that tracks when the -scheduler considers the job done, and having the shared name was -confusing. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/v3d/v3d_drv.h | 4 ++-- - drivers/gpu/drm/v3d/v3d_gem.c | 6 +++--- - drivers/gpu/drm/v3d/v3d_irq.c | 6 +++--- - drivers/gpu/drm/v3d/v3d_sched.c | 12 ++++++------ - 4 files changed, 14 insertions(+), 14 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_drv.h -+++ b/drivers/gpu/drm/v3d/v3d_drv.h -@@ -182,7 +182,7 @@ struct v3d_job { - struct dma_fence *in_fence; - - /* v3d fence to be signaled by IRQ handler when the job is complete. */ -- struct dma_fence *done_fence; -+ struct dma_fence *irq_fence; - - /* GPU virtual addresses of the start/end of the CL job. */ - u32 start, end; -@@ -229,7 +229,7 @@ struct v3d_tfu_job { - struct dma_fence *in_fence; - - /* v3d fence to be signaled by IRQ handler when the job is complete. */ -- struct dma_fence *done_fence; -+ struct dma_fence *irq_fence; - - struct v3d_dev *v3d; - ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -381,8 +381,8 @@ v3d_exec_cleanup(struct kref *ref) - dma_fence_put(exec->bin.in_fence); - dma_fence_put(exec->render.in_fence); - -- dma_fence_put(exec->bin.done_fence); -- dma_fence_put(exec->render.done_fence); -+ dma_fence_put(exec->bin.irq_fence); -+ dma_fence_put(exec->render.irq_fence); - - dma_fence_put(exec->bin_done_fence); - dma_fence_put(exec->render_done_fence); -@@ -411,7 +411,7 @@ v3d_tfu_job_cleanup(struct kref *ref) - unsigned int i; - - dma_fence_put(job->in_fence); -- dma_fence_put(job->done_fence); -+ dma_fence_put(job->irq_fence); - - for (i = 0; i < ARRAY_SIZE(job->bo); i++) { - if (job->bo[i]) ---- a/drivers/gpu/drm/v3d/v3d_irq.c -+++ b/drivers/gpu/drm/v3d/v3d_irq.c -@@ -93,7 +93,7 @@ v3d_irq(int irq, void *arg) - - if (intsts & V3D_INT_FLDONE) { - struct v3d_fence *fence = -- to_v3d_fence(v3d->bin_job->bin.done_fence); -+ to_v3d_fence(v3d->bin_job->bin.irq_fence); - - trace_v3d_bcl_irq(&v3d->drm, fence->seqno); - dma_fence_signal(&fence->base); -@@ -102,7 +102,7 @@ v3d_irq(int irq, void *arg) - - if (intsts & V3D_INT_FRDONE) { - struct v3d_fence *fence = -- to_v3d_fence(v3d->render_job->render.done_fence); -+ to_v3d_fence(v3d->render_job->render.irq_fence); - - trace_v3d_rcl_irq(&v3d->drm, fence->seqno); - dma_fence_signal(&fence->base); -@@ -138,7 +138,7 @@ v3d_hub_irq(int irq, void *arg) - - if (intsts & V3D_HUB_INT_TFUC) { - struct v3d_fence *fence = -- to_v3d_fence(v3d->tfu_job->done_fence); -+ to_v3d_fence(v3d->tfu_job->irq_fence); - - trace_v3d_tfu_irq(&v3d->drm, fence->seqno); - dma_fence_signal(&fence->base); ---- a/drivers/gpu/drm/v3d/v3d_sched.c -+++ b/drivers/gpu/drm/v3d/v3d_sched.c -@@ -152,9 +152,9 @@ static struct dma_fence *v3d_job_run(str - if (IS_ERR(fence)) - return NULL; - -- if (job->done_fence) -- dma_fence_put(job->done_fence); -- job->done_fence = dma_fence_get(fence); -+ if (job->irq_fence) -+ dma_fence_put(job->irq_fence); -+ job->irq_fence = dma_fence_get(fence); - - trace_v3d_submit_cl(dev, q == V3D_RENDER, to_v3d_fence(fence)->seqno, - job->start, job->end); -@@ -195,9 +195,9 @@ v3d_tfu_job_run(struct drm_sched_job *sc - return NULL; - - v3d->tfu_job = job; -- if (job->done_fence) -- dma_fence_put(job->done_fence); -- job->done_fence = dma_fence_get(fence); -+ if (job->irq_fence) -+ dma_fence_put(job->irq_fence); -+ job->irq_fence = dma_fence_get(fence); - - trace_v3d_submit_tfu(dev, to_v3d_fence(fence)->seqno); - diff --git a/target/linux/brcm2708/patches-4.19/950-0591-drm-vc4-Make-sure-that-vblank-waits-work-without-v3d.patch b/target/linux/brcm2708/patches-4.19/950-0591-drm-vc4-Make-sure-that-vblank-waits-work-without-v3d.patch new file mode 100644 index 0000000000..9e3631d2a5 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0591-drm-vc4-Make-sure-that-vblank-waits-work-without-v3d.patch @@ -0,0 +1,27 @@ +From 0ce577f34c986e0d3e42aecd3a7a3407d5d52f1b Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Fri, 29 Mar 2019 12:04:36 -0700 +Subject: [PATCH 591/725] drm/vc4: Make sure that vblank waits work without v3d + loaded. + +This flag exists to protect legacy drivers, but when vc4's v3d doesn't +probe, it doesn't get set up by vc4_v3d.c's call of drm_irq_install. +This resulted in applications running as fast as possible, and laggy +performance from compton as it had to wait for the latest rendering by +the application for its presentation. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_kms.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpu/drm/vc4/vc4_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_kms.c +@@ -422,6 +422,7 @@ int vc4_kms_load(struct drm_device *dev) + /* Set support for vblank irq fast disable, before drm_vblank_init() */ + dev->vblank_disable_immediate = true; + ++ dev->irq_enabled = true; + ret = drm_vblank_init(dev, dev->mode_config.num_crtc); + if (ret < 0) { + dev_err(dev->dev, "failed to initialize vblank\n"); diff --git a/target/linux/brcm2708/patches-4.19/950-0592-drm-v3d-Refactor-job-management.patch b/target/linux/brcm2708/patches-4.19/950-0592-drm-v3d-Refactor-job-management.patch deleted file mode 100644 index 355509ba63..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0592-drm-v3d-Refactor-job-management.patch +++ /dev/null @@ -1,1104 +0,0 @@ -From fe5b0a576fd25f7929e553cd11d98959af808525 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 27 Dec 2018 12:11:52 -0800 -Subject: [PATCH 592/703] drm/v3d: Refactor job management. - -The CL submission had two jobs embedded in an exec struct. When I -added TFU support, I had to replicate some of the exec stuff and some -of the job stuff. As I went to add CSD, it became clear that actually -what was in exec should just be in the two CL jobs, and it would let -us share a lot more code between the 4 queues. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/v3d/v3d_drv.h | 77 ++++---- - drivers/gpu/drm/v3d/v3d_gem.c | 331 +++++++++++++++++--------------- - drivers/gpu/drm/v3d/v3d_irq.c | 8 +- - drivers/gpu/drm/v3d/v3d_sched.c | 264 ++++++++++++++----------- - 4 files changed, 373 insertions(+), 307 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_drv.h -+++ b/drivers/gpu/drm/v3d/v3d_drv.h -@@ -67,8 +67,8 @@ struct v3d_dev { - - struct work_struct overflow_mem_work; - -- struct v3d_exec_info *bin_job; -- struct v3d_exec_info *render_job; -+ struct v3d_bin_job *bin_job; -+ struct v3d_render_job *render_job; - struct v3d_tfu_job *tfu_job; - - struct v3d_queue_state queue[V3D_MAX_QUEUES]; -@@ -132,7 +132,7 @@ struct v3d_bo { - struct list_head vmas; /* list of v3d_vma */ - - /* List entry for the BO's position in -- * v3d_exec_info->unref_list -+ * v3d_render_job->unref_list - */ - struct list_head unref_head; - -@@ -176,7 +176,15 @@ to_v3d_fence(struct dma_fence *fence) - struct v3d_job { - struct drm_sched_job base; - -- struct v3d_exec_info *exec; -+ struct kref refcount; -+ -+ struct v3d_dev *v3d; -+ -+ /* This is the array of BOs that were looked up at the start -+ * of submission. -+ */ -+ struct v3d_bo **bo; -+ u32 bo_count; - - /* An optional fence userspace can pass in for the job to depend on. */ - struct dma_fence *in_fence; -@@ -184,59 +192,53 @@ struct v3d_job { - /* v3d fence to be signaled by IRQ handler when the job is complete. */ - struct dma_fence *irq_fence; - -+ /* scheduler fence for when the job is considered complete and -+ * the BO reservations can be released. -+ */ -+ struct dma_fence *done_fence; -+ -+ /* Callback for the freeing of the job on refcount going to 0. */ -+ void (*free)(struct kref *ref); -+}; -+ -+struct v3d_bin_job { -+ struct v3d_job base; -+ - /* GPU virtual addresses of the start/end of the CL job. */ - u32 start, end; - - u32 timedout_ctca, timedout_ctra; --}; - --struct v3d_exec_info { -- struct v3d_dev *v3d; -+ /* Corresponding render job, for attaching our overflow memory. */ -+ struct v3d_render_job *render; -+ -+ /* Submitted tile memory allocation start/size, tile state. */ -+ u32 qma, qms, qts; -+}; - -- struct v3d_job bin, render; -+struct v3d_render_job { -+ struct v3d_job base; - -- /* Fence for when the scheduler considers the binner to be -- * done, for render to depend on. -+ /* Optional fence for the binner, to depend on before starting -+ * our job. - */ - struct dma_fence *bin_done_fence; - -- /* Fence for when the scheduler considers the render to be -- * done, for when the BOs reservations should be complete. -- */ -- struct dma_fence *render_done_fence; -- -- struct kref refcount; -+ /* GPU virtual addresses of the start/end of the CL job. */ -+ u32 start, end; - -- /* This is the array of BOs that were looked up at the start of exec. */ -- struct v3d_bo **bo; -- u32 bo_count; -+ u32 timedout_ctca, timedout_ctra; - - /* List of overflow BOs used in the job that need to be - * released once the job is complete. - */ - struct list_head unref_list; -- -- /* Submitted tile memory allocation start/size, tile state. */ -- u32 qma, qms, qts; - }; - - struct v3d_tfu_job { -- struct drm_sched_job base; -+ struct v3d_job base; - - struct drm_v3d_submit_tfu args; -- -- /* An optional fence userspace can pass in for the job to depend on. */ -- struct dma_fence *in_fence; -- -- /* v3d fence to be signaled by IRQ handler when the job is complete. */ -- struct dma_fence *irq_fence; -- -- struct v3d_dev *v3d; -- -- struct kref refcount; -- -- /* This is the array of BOs that were looked up at the start of exec. */ -- struct v3d_bo *bo[4]; - }; - - /** -@@ -306,8 +308,7 @@ int v3d_submit_tfu_ioctl(struct drm_devi - struct drm_file *file_priv); - int v3d_wait_bo_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); --void v3d_exec_put(struct v3d_exec_info *exec); --void v3d_tfu_job_put(struct v3d_tfu_job *exec); -+void v3d_job_put(struct v3d_job *job); - void v3d_reset(struct v3d_dev *v3d); - void v3d_invalidate_caches(struct v3d_dev *v3d); - ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -293,11 +293,11 @@ retry: - } - - /** -- * v3d_cl_lookup_bos() - Sets up exec->bo[] with the GEM objects -+ * v3d_lookup_bos() - Sets up job->bo[] with the GEM objects - * referenced by the job. - * @dev: DRM device - * @file_priv: DRM file for this fd -- * @exec: V3D job being set up -+ * @job: V3D job being set up - * - * The command validator needs to reference BOs by their index within - * the submitted job's BO list. This does the validation of the job's -@@ -307,18 +307,19 @@ retry: - * failure, because that will happen at v3d_exec_cleanup() time. - */ - static int --v3d_cl_lookup_bos(struct drm_device *dev, -- struct drm_file *file_priv, -- struct drm_v3d_submit_cl *args, -- struct v3d_exec_info *exec) -+v3d_lookup_bos(struct drm_device *dev, -+ struct drm_file *file_priv, -+ struct v3d_job *job, -+ u64 bo_handles, -+ u32 bo_count) - { - u32 *handles; - int ret = 0; - int i; - -- exec->bo_count = args->bo_handle_count; -+ job->bo_count = bo_count; - -- if (!exec->bo_count) { -+ if (!job->bo_count) { - /* See comment on bo_index for why we have to check - * this. - */ -@@ -326,15 +327,15 @@ v3d_cl_lookup_bos(struct drm_device *dev - return -EINVAL; - } - -- exec->bo = kvmalloc_array(exec->bo_count, -- sizeof(struct drm_gem_cma_object *), -- GFP_KERNEL | __GFP_ZERO); -- if (!exec->bo) { -+ job->bo = kvmalloc_array(job->bo_count, -+ sizeof(struct drm_gem_cma_object *), -+ GFP_KERNEL | __GFP_ZERO); -+ if (!job->bo) { - DRM_DEBUG("Failed to allocate validated BO pointers\n"); - return -ENOMEM; - } - -- handles = kvmalloc_array(exec->bo_count, sizeof(u32), GFP_KERNEL); -+ handles = kvmalloc_array(job->bo_count, sizeof(u32), GFP_KERNEL); - if (!handles) { - ret = -ENOMEM; - DRM_DEBUG("Failed to allocate incoming GEM handles\n"); -@@ -342,15 +343,15 @@ v3d_cl_lookup_bos(struct drm_device *dev - } - - if (copy_from_user(handles, -- (void __user *)(uintptr_t)args->bo_handles, -- exec->bo_count * sizeof(u32))) { -+ (void __user *)(uintptr_t)bo_handles, -+ job->bo_count * sizeof(u32))) { - ret = -EFAULT; - DRM_DEBUG("Failed to copy in GEM handles\n"); - goto fail; - } - - spin_lock(&file_priv->table_lock); -- for (i = 0; i < exec->bo_count; i++) { -+ for (i = 0; i < job->bo_count; i++) { - struct drm_gem_object *bo = idr_find(&file_priv->object_idr, - handles[i]); - if (!bo) { -@@ -361,7 +362,7 @@ v3d_cl_lookup_bos(struct drm_device *dev - goto fail; - } - drm_gem_object_get(bo); -- exec->bo[i] = to_v3d_bo(bo); -+ job->bo[i] = to_v3d_bo(bo); - } - spin_unlock(&file_priv->table_lock); - -@@ -371,59 +372,41 @@ fail: - } - - static void --v3d_exec_cleanup(struct kref *ref) -+v3d_job_free(struct kref *ref) - { -- struct v3d_exec_info *exec = container_of(ref, struct v3d_exec_info, -- refcount); -- unsigned int i; -- struct v3d_bo *bo, *save; -- -- dma_fence_put(exec->bin.in_fence); -- dma_fence_put(exec->render.in_fence); -- -- dma_fence_put(exec->bin.irq_fence); -- dma_fence_put(exec->render.irq_fence); -- -- dma_fence_put(exec->bin_done_fence); -- dma_fence_put(exec->render_done_fence); -- -- for (i = 0; i < exec->bo_count; i++) -- drm_gem_object_put_unlocked(&exec->bo[i]->base); -- kvfree(exec->bo); -+ struct v3d_job *job = container_of(ref, struct v3d_job, refcount); -+ int i; - -- list_for_each_entry_safe(bo, save, &exec->unref_list, unref_head) { -- drm_gem_object_put_unlocked(&bo->base); -+ for (i = 0; i < job->bo_count; i++) { -+ if (job->bo[i]) -+ drm_gem_object_put_unlocked(&job->bo[i]->base); - } -+ kvfree(job->bo); - -- kfree(exec); --} -+ dma_fence_put(job->in_fence); -+ dma_fence_put(job->irq_fence); -+ dma_fence_put(job->done_fence); - --void v3d_exec_put(struct v3d_exec_info *exec) --{ -- kref_put(&exec->refcount, v3d_exec_cleanup); -+ kfree(job); - } - - static void --v3d_tfu_job_cleanup(struct kref *ref) -+v3d_render_job_free(struct kref *ref) - { -- struct v3d_tfu_job *job = container_of(ref, struct v3d_tfu_job, -- refcount); -- unsigned int i; -- -- dma_fence_put(job->in_fence); -- dma_fence_put(job->irq_fence); -+ struct v3d_render_job *job = container_of(ref, struct v3d_render_job, -+ base.refcount); -+ struct v3d_bo *bo, *save; - -- for (i = 0; i < ARRAY_SIZE(job->bo); i++) { -- if (job->bo[i]) -- drm_gem_object_put_unlocked(&job->bo[i]->base); -+ list_for_each_entry_safe(bo, save, &job->unref_list, unref_head) { -+ drm_gem_object_put_unlocked(&bo->base); - } - -- kfree(job); -+ v3d_job_free(ref); - } - --void v3d_tfu_job_put(struct v3d_tfu_job *job) -+void v3d_job_put(struct v3d_job *job) - { -- kref_put(&job->refcount, v3d_tfu_job_cleanup); -+ kref_put(&job->refcount, job->free); - } - - int -@@ -476,6 +459,65 @@ v3d_wait_bo_ioctl(struct drm_device *dev - return ret; - } - -+static int -+v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv, -+ struct v3d_job *job, void (*free)(struct kref *ref), -+ u32 in_sync) -+{ -+ int ret; -+ -+ job->v3d = v3d; -+ job->free = free; -+ -+ ret = drm_syncobj_find_fence(file_priv, in_sync, 0, &job->in_fence); -+ if (ret == -EINVAL) -+ return ret; -+ -+ kref_init(&job->refcount); -+ -+ return 0; -+} -+ -+static int -+v3d_push_job(struct v3d_file_priv *v3d_priv, -+ struct v3d_job *job, enum v3d_queue queue) -+{ -+ int ret; -+ -+ ret = drm_sched_job_init(&job->base, &v3d_priv->sched_entity[queue], -+ v3d_priv); -+ if (ret) -+ return ret; -+ -+ job->done_fence = dma_fence_get(&job->base.s_fence->finished); -+ -+ /* put by scheduler job completion */ -+ kref_get(&job->refcount); -+ -+ drm_sched_entity_push_job(&job->base, &v3d_priv->sched_entity[queue]); -+ -+ return 0; -+} -+ -+static void -+v3d_attach_fences_and_unlock_reservation(struct drm_file *file_priv, -+ struct v3d_job *job, -+ struct ww_acquire_ctx *acquire_ctx, -+ u32 out_sync) -+{ -+ struct drm_syncobj *sync_out; -+ -+ v3d_attach_object_fences(job->bo, job->bo_count, job->done_fence); -+ v3d_unlock_bo_reservations(job->bo, job->bo_count, acquire_ctx); -+ -+ /* Update the return sync object for the job */ -+ sync_out = drm_syncobj_find(file_priv, out_sync); -+ if (sync_out) { -+ drm_syncobj_replace_fence(sync_out, job->done_fence); -+ drm_syncobj_put(sync_out); -+ } -+} -+ - /** - * v3d_submit_cl_ioctl() - Submits a job (frame) to the V3D. - * @dev: DRM device -@@ -495,9 +537,9 @@ v3d_submit_cl_ioctl(struct drm_device *d - struct v3d_dev *v3d = to_v3d_dev(dev); - struct v3d_file_priv *v3d_priv = file_priv->driver_priv; - struct drm_v3d_submit_cl *args = data; -- struct v3d_exec_info *exec; -+ struct v3d_bin_job *bin = NULL; -+ struct v3d_render_job *render; - struct ww_acquire_ctx acquire_ctx; -- struct drm_syncobj *sync_out; - int ret = 0; - - trace_v3d_submit_cl_ioctl(&v3d->drm, args->rcl_start, args->rcl_end); -@@ -507,95 +549,84 @@ v3d_submit_cl_ioctl(struct drm_device *d - return -EINVAL; - } - -- exec = kcalloc(1, sizeof(*exec), GFP_KERNEL); -- if (!exec) -+ render = kcalloc(1, sizeof(*render), GFP_KERNEL); -+ if (!render) - return -ENOMEM; - -- kref_init(&exec->refcount); -+ render->start = args->rcl_start; -+ render->end = args->rcl_end; -+ INIT_LIST_HEAD(&render->unref_list); - -- ret = drm_syncobj_find_fence(file_priv, args->in_sync_bcl, -- 0, &exec->bin.in_fence); -- if (ret == -EINVAL) -- goto fail; -+ ret = v3d_job_init(v3d, file_priv, &render->base, -+ v3d_render_job_free, args->in_sync_rcl); -+ if (ret) { -+ kfree(bin); -+ kfree(render); -+ return ret; -+ } - -- ret = drm_syncobj_find_fence(file_priv, args->in_sync_rcl, -- 0, &exec->render.in_fence); -- if (ret == -EINVAL) -- goto fail; -+ if (args->bcl_start != args->bcl_end) { -+ bin = kcalloc(1, sizeof(*bin), GFP_KERNEL); -+ if (!bin) -+ return -ENOMEM; -+ -+ ret = v3d_job_init(v3d, file_priv, &bin->base, -+ v3d_job_free, args->in_sync_bcl); -+ if (ret) { -+ v3d_job_put(&render->base); -+ return ret; -+ } - -- exec->qma = args->qma; -- exec->qms = args->qms; -- exec->qts = args->qts; -- exec->bin.exec = exec; -- exec->bin.start = args->bcl_start; -- exec->bin.end = args->bcl_end; -- exec->render.exec = exec; -- exec->render.start = args->rcl_start; -- exec->render.end = args->rcl_end; -- exec->v3d = v3d; -- INIT_LIST_HEAD(&exec->unref_list); -+ bin->start = args->bcl_start; -+ bin->end = args->bcl_end; -+ bin->qma = args->qma; -+ bin->qms = args->qms; -+ bin->qts = args->qts; -+ bin->render = render; -+ } - -- ret = v3d_cl_lookup_bos(dev, file_priv, args, exec); -+ ret = v3d_lookup_bos(dev, file_priv, &render->base, -+ args->bo_handles, args->bo_handle_count); - if (ret) - goto fail; - -- ret = v3d_lock_bo_reservations(exec->bo, exec->bo_count, -+ ret = v3d_lock_bo_reservations(render->base.bo, render->base.bo_count, - &acquire_ctx); - if (ret) - goto fail; - - mutex_lock(&v3d->sched_lock); -- if (exec->bin.start != exec->bin.end) { -- ret = drm_sched_job_init(&exec->bin.base, -- &v3d_priv->sched_entity[V3D_BIN], -- v3d_priv); -+ if (bin) { -+ ret = v3d_push_job(v3d_priv, &bin->base, V3D_BIN); - if (ret) - goto fail_unreserve; - -- exec->bin_done_fence = -- dma_fence_get(&exec->bin.base.s_fence->finished); -- -- kref_get(&exec->refcount); /* put by scheduler job completion */ -- drm_sched_entity_push_job(&exec->bin.base, -- &v3d_priv->sched_entity[V3D_BIN]); -+ render->bin_done_fence = dma_fence_get(bin->base.done_fence); - } - -- ret = drm_sched_job_init(&exec->render.base, -- &v3d_priv->sched_entity[V3D_RENDER], -- v3d_priv); -+ ret = v3d_push_job(v3d_priv, &render->base, V3D_RENDER); - if (ret) - goto fail_unreserve; -- -- exec->render_done_fence = -- dma_fence_get(&exec->render.base.s_fence->finished); -- -- kref_get(&exec->refcount); /* put by scheduler job completion */ -- drm_sched_entity_push_job(&exec->render.base, -- &v3d_priv->sched_entity[V3D_RENDER]); - mutex_unlock(&v3d->sched_lock); - -- v3d_attach_object_fences(exec->bo, exec->bo_count, -- exec->render_done_fence); -- -- v3d_unlock_bo_reservations(exec->bo, exec->bo_count, &acquire_ctx); -- -- /* Update the return sync object for the */ -- sync_out = drm_syncobj_find(file_priv, args->out_sync); -- if (sync_out) { -- drm_syncobj_replace_fence(sync_out, -- exec->render_done_fence); -- drm_syncobj_put(sync_out); -- } -- -- v3d_exec_put(exec); -+ v3d_attach_fences_and_unlock_reservation(file_priv, -+ &render->base, &acquire_ctx, -+ args->out_sync); -+ -+ if (bin) -+ v3d_job_put(&bin->base); -+ v3d_job_put(&render->base); - - return 0; - - fail_unreserve: - mutex_unlock(&v3d->sched_lock); -- v3d_unlock_bo_reservations(exec->bo, exec->bo_count, &acquire_ctx); -+ v3d_unlock_bo_reservations(render->base.bo, -+ render->base.bo_count, &acquire_ctx); - fail: -- v3d_exec_put(exec); -+ if (bin) -+ v3d_job_put(&bin->base); -+ v3d_job_put(&render->base); - - return ret; - } -@@ -618,10 +649,7 @@ v3d_submit_tfu_ioctl(struct drm_device * - struct drm_v3d_submit_tfu *args = data; - struct v3d_tfu_job *job; - struct ww_acquire_ctx acquire_ctx; -- struct drm_syncobj *sync_out; -- struct dma_fence *sched_done_fence; - int ret = 0; -- int bo_count; - - trace_v3d_submit_tfu_ioctl(&v3d->drm, args->iia); - -@@ -629,75 +657,66 @@ v3d_submit_tfu_ioctl(struct drm_device * - if (!job) - return -ENOMEM; - -- kref_init(&job->refcount); -- -- ret = drm_syncobj_find_fence(file_priv, args->in_sync, -- 0, &job->in_fence); -- if (ret == -EINVAL) -- goto fail; -+ ret = v3d_job_init(v3d, file_priv, &job->base, -+ v3d_job_free, args->in_sync); -+ if (ret) { -+ kfree(job); -+ return ret; -+ } - -+ job->base.bo = kcalloc(ARRAY_SIZE(args->bo_handles), -+ sizeof(*job->base.bo), GFP_KERNEL); - job->args = *args; -- job->v3d = v3d; - - spin_lock(&file_priv->table_lock); -- for (bo_count = 0; bo_count < ARRAY_SIZE(job->bo); bo_count++) { -+ for (job->base.bo_count = 0; -+ job->base.bo_count < ARRAY_SIZE(args->bo_handles); -+ job->base.bo_count++) { - struct drm_gem_object *bo; - -- if (!args->bo_handles[bo_count]) -+ if (!args->bo_handles[job->base.bo_count]) - break; - - bo = idr_find(&file_priv->object_idr, -- args->bo_handles[bo_count]); -+ args->bo_handles[job->base.bo_count]); - if (!bo) { - DRM_DEBUG("Failed to look up GEM BO %d: %d\n", -- bo_count, args->bo_handles[bo_count]); -+ job->base.bo_count, -+ args->bo_handles[job->base.bo_count]); - ret = -ENOENT; - spin_unlock(&file_priv->table_lock); - goto fail; - } - drm_gem_object_get(bo); -- job->bo[bo_count] = to_v3d_bo(bo); -+ job->base.bo[job->base.bo_count] = to_v3d_bo(bo); - } - spin_unlock(&file_priv->table_lock); - -- ret = v3d_lock_bo_reservations(job->bo, bo_count, &acquire_ctx); -+ ret = v3d_lock_bo_reservations(job->base.bo, job->base.bo_count, -+ &acquire_ctx); - if (ret) - goto fail; - - mutex_lock(&v3d->sched_lock); -- ret = drm_sched_job_init(&job->base, -- &v3d_priv->sched_entity[V3D_TFU], -- v3d_priv); -+ ret = v3d_push_job(v3d_priv, &job->base, V3D_TFU); - if (ret) - goto fail_unreserve; -- -- sched_done_fence = dma_fence_get(&job->base.s_fence->finished); -- -- kref_get(&job->refcount); /* put by scheduler job completion */ -- drm_sched_entity_push_job(&job->base, &v3d_priv->sched_entity[V3D_TFU]); - mutex_unlock(&v3d->sched_lock); - -- v3d_attach_object_fences(job->bo, bo_count, sched_done_fence); -- -- v3d_unlock_bo_reservations(job->bo, bo_count, &acquire_ctx); -- -- /* Update the return sync object */ -- sync_out = drm_syncobj_find(file_priv, args->out_sync); -- if (sync_out) { -- drm_syncobj_replace_fence(sync_out, sched_done_fence); -- drm_syncobj_put(sync_out); -- } -- dma_fence_put(sched_done_fence); -+ v3d_attach_fences_and_unlock_reservation(file_priv, -+ &job->base, &acquire_ctx, -+ args->out_sync); - -- v3d_tfu_job_put(job); -+ v3d_job_put(&job->base); - - return 0; - - fail_unreserve: - mutex_unlock(&v3d->sched_lock); -- v3d_unlock_bo_reservations(job->bo, bo_count, &acquire_ctx); -+ v3d_unlock_bo_reservations(job->base.bo, job->base.bo_count, -+ &acquire_ctx); - fail: -- v3d_tfu_job_put(job); -+ v3d_job_put(&job->base); - - return ret; - } -@@ -755,7 +774,7 @@ v3d_gem_destroy(struct drm_device *dev) - - v3d_sched_fini(v3d); - -- /* Waiting for exec to finish would need to be done before -+ /* Waiting for jobs to finish would need to be done before - * unregistering V3D. - */ - WARN_ON(v3d->bin_job); ---- a/drivers/gpu/drm/v3d/v3d_irq.c -+++ b/drivers/gpu/drm/v3d/v3d_irq.c -@@ -60,7 +60,7 @@ v3d_overflow_mem_work(struct work_struct - } - - drm_gem_object_get(&bo->base); -- list_add_tail(&bo->unref_head, &v3d->bin_job->unref_list); -+ list_add_tail(&bo->unref_head, &v3d->bin_job->render->unref_list); - spin_unlock_irqrestore(&v3d->job_lock, irqflags); - - V3D_CORE_WRITE(0, V3D_PTB_BPOA, bo->node.start << PAGE_SHIFT); -@@ -93,7 +93,7 @@ v3d_irq(int irq, void *arg) - - if (intsts & V3D_INT_FLDONE) { - struct v3d_fence *fence = -- to_v3d_fence(v3d->bin_job->bin.irq_fence); -+ to_v3d_fence(v3d->bin_job->base.irq_fence); - - trace_v3d_bcl_irq(&v3d->drm, fence->seqno); - dma_fence_signal(&fence->base); -@@ -102,7 +102,7 @@ v3d_irq(int irq, void *arg) - - if (intsts & V3D_INT_FRDONE) { - struct v3d_fence *fence = -- to_v3d_fence(v3d->render_job->render.irq_fence); -+ to_v3d_fence(v3d->render_job->base.irq_fence); - - trace_v3d_rcl_irq(&v3d->drm, fence->seqno); - dma_fence_signal(&fence->base); -@@ -138,7 +138,7 @@ v3d_hub_irq(int irq, void *arg) - - if (intsts & V3D_HUB_INT_TFUC) { - struct v3d_fence *fence = -- to_v3d_fence(v3d->tfu_job->irq_fence); -+ to_v3d_fence(v3d->tfu_job->base.irq_fence); - - trace_v3d_tfu_irq(&v3d->drm, fence->seqno); - dma_fence_signal(&fence->base); ---- a/drivers/gpu/drm/v3d/v3d_sched.c -+++ b/drivers/gpu/drm/v3d/v3d_sched.c -@@ -30,39 +30,43 @@ to_v3d_job(struct drm_sched_job *sched_j - return container_of(sched_job, struct v3d_job, base); - } - --static struct v3d_tfu_job * --to_tfu_job(struct drm_sched_job *sched_job) -+static struct v3d_bin_job * -+to_bin_job(struct drm_sched_job *sched_job) - { -- return container_of(sched_job, struct v3d_tfu_job, base); -+ return container_of(sched_job, struct v3d_bin_job, base.base); - } - --static void --v3d_job_free(struct drm_sched_job *sched_job) -+static struct v3d_render_job * -+to_render_job(struct drm_sched_job *sched_job) - { -- struct v3d_job *job = to_v3d_job(sched_job); -+ return container_of(sched_job, struct v3d_render_job, base.base); -+} - -- v3d_exec_put(job->exec); -+static struct v3d_tfu_job * -+to_tfu_job(struct drm_sched_job *sched_job) -+{ -+ return container_of(sched_job, struct v3d_tfu_job, base.base); - } - - static void --v3d_tfu_job_free(struct drm_sched_job *sched_job) -+v3d_job_free(struct drm_sched_job *sched_job) - { -- struct v3d_tfu_job *job = to_tfu_job(sched_job); -+ struct v3d_job *job = to_v3d_job(sched_job); - -- v3d_tfu_job_put(job); -+ v3d_job_put(job); - } - - /** -- * Returns the fences that the bin or render job depends on, one by one. -- * v3d_job_run() won't be called until all of them have been signaled. -+ * Returns the fences that the job depends on, one by one. -+ * -+ * If placed in the scheduler's .dependency method, the corresponding -+ * .run_job won't be called until all of them have been signaled. - */ - static struct dma_fence * - v3d_job_dependency(struct drm_sched_job *sched_job, - struct drm_sched_entity *s_entity) - { - struct v3d_job *job = to_v3d_job(sched_job); -- struct v3d_exec_info *exec = job->exec; -- enum v3d_queue q = job == &exec->bin ? V3D_BIN : V3D_RENDER; - struct dma_fence *fence; - - fence = job->in_fence; -@@ -71,113 +75,132 @@ v3d_job_dependency(struct drm_sched_job - return fence; - } - -- if (q == V3D_RENDER) { -- /* If we had a bin job, the render job definitely depends on -- * it. We first have to wait for bin to be scheduled, so that -- * its done_fence is created. -- */ -- fence = exec->bin_done_fence; -- if (fence) { -- exec->bin_done_fence = NULL; -- return fence; -- } -- } -- -- /* XXX: Wait on a fence for switching the GMP if necessary, -- * and then do so. -- */ -- -- return fence; -+ return NULL; - } - - /** -- * Returns the fences that the TFU job depends on, one by one. -- * v3d_tfu_job_run() won't be called until all of them have been -- * signaled. -+ * Returns the fences that the render job depends on, one by one. -+ * v3d_job_run() won't be called until all of them have been signaled. - */ - static struct dma_fence * --v3d_tfu_job_dependency(struct drm_sched_job *sched_job, -- struct drm_sched_entity *s_entity) -+v3d_render_job_dependency(struct drm_sched_job *sched_job, -+ struct drm_sched_entity *s_entity) - { -- struct v3d_tfu_job *job = to_tfu_job(sched_job); -+ struct v3d_render_job *job = to_render_job(sched_job); - struct dma_fence *fence; - -- fence = job->in_fence; -+ fence = v3d_job_dependency(sched_job, s_entity); -+ if (fence) -+ return fence; -+ -+ /* If we had a bin job, the render job definitely depends on -+ * it. We first have to wait for bin to be scheduled, so that -+ * its done_fence is created. -+ */ -+ fence = job->bin_done_fence; - if (fence) { -- job->in_fence = NULL; -+ job->bin_done_fence = NULL; - return fence; - } - -- return NULL; -+ /* XXX: Wait on a fence for switching the GMP if necessary, -+ * and then do so. -+ */ -+ -+ return fence; - } - --static struct dma_fence *v3d_job_run(struct drm_sched_job *sched_job) -+static struct dma_fence *v3d_bin_job_run(struct drm_sched_job *sched_job) - { -- struct v3d_job *job = to_v3d_job(sched_job); -- struct v3d_exec_info *exec = job->exec; -- enum v3d_queue q = job == &exec->bin ? V3D_BIN : V3D_RENDER; -- struct v3d_dev *v3d = exec->v3d; -+ struct v3d_bin_job *job = to_bin_job(sched_job); -+ struct v3d_dev *v3d = job->base.v3d; - struct drm_device *dev = &v3d->drm; - struct dma_fence *fence; - unsigned long irqflags; - -- if (unlikely(job->base.s_fence->finished.error)) -+ if (unlikely(job->base.base.s_fence->finished.error)) - return NULL; - - /* Lock required around bin_job update vs - * v3d_overflow_mem_work(). - */ - spin_lock_irqsave(&v3d->job_lock, irqflags); -- if (q == V3D_BIN) { -- v3d->bin_job = job->exec; -+ v3d->bin_job = job; -+ /* Clear out the overflow allocation, so we don't -+ * reuse the overflow attached to a previous job. -+ */ -+ V3D_CORE_WRITE(0, V3D_PTB_BPOS, 0); -+ spin_unlock_irqrestore(&v3d->job_lock, irqflags); -+ -+ v3d_invalidate_caches(v3d); - -- /* Clear out the overflow allocation, so we don't -- * reuse the overflow attached to a previous job. -- */ -- V3D_CORE_WRITE(0, V3D_PTB_BPOS, 0); -- } else { -- v3d->render_job = job->exec; -+ fence = v3d_fence_create(v3d, V3D_BIN); -+ if (IS_ERR(fence)) -+ return NULL; -+ -+ if (job->base.irq_fence) -+ dma_fence_put(job->base.irq_fence); -+ job->base.irq_fence = dma_fence_get(fence); -+ -+ trace_v3d_submit_cl(dev, false, to_v3d_fence(fence)->seqno, -+ job->start, job->end); -+ -+ /* Set the current and end address of the control list. -+ * Writing the end register is what starts the job. -+ */ -+ if (job->qma) { -+ V3D_CORE_WRITE(0, V3D_CLE_CT0QMA, job->qma); -+ V3D_CORE_WRITE(0, V3D_CLE_CT0QMS, job->qms); - } -- spin_unlock_irqrestore(&v3d->job_lock, irqflags); -+ if (job->qts) { -+ V3D_CORE_WRITE(0, V3D_CLE_CT0QTS, -+ V3D_CLE_CT0QTS_ENABLE | -+ job->qts); -+ } -+ V3D_CORE_WRITE(0, V3D_CLE_CT0QBA, job->start); -+ V3D_CORE_WRITE(0, V3D_CLE_CT0QEA, job->end); -+ -+ return fence; -+} -+ -+static struct dma_fence *v3d_render_job_run(struct drm_sched_job *sched_job) -+{ -+ struct v3d_render_job *job = to_render_job(sched_job); -+ struct v3d_dev *v3d = job->base.v3d; -+ struct drm_device *dev = &v3d->drm; -+ struct dma_fence *fence; -+ -+ if (unlikely(job->base.base.s_fence->finished.error)) -+ return NULL; - -- /* Can we avoid this flush when q==RENDER? We need to be -- * careful of scheduling, though -- imagine job0 rendering to -- * texture and job1 reading, and them being executed as bin0, -- * bin1, render0, render1, so that render1's flush at bin time -+ v3d->render_job = job; -+ -+ /* Can we avoid this flush? We need to be careful of -+ * scheduling, though -- imagine job0 rendering to texture and -+ * job1 reading, and them being executed as bin0, bin1, -+ * render0, render1, so that render1's flush at bin time - * wasn't enough. - */ - v3d_invalidate_caches(v3d); - -- fence = v3d_fence_create(v3d, q); -+ fence = v3d_fence_create(v3d, V3D_RENDER); - if (IS_ERR(fence)) - return NULL; - -- if (job->irq_fence) -- dma_fence_put(job->irq_fence); -- job->irq_fence = dma_fence_get(fence); -+ if (job->base.irq_fence) -+ dma_fence_put(job->base.irq_fence); -+ job->base.irq_fence = dma_fence_get(fence); - -- trace_v3d_submit_cl(dev, q == V3D_RENDER, to_v3d_fence(fence)->seqno, -+ trace_v3d_submit_cl(dev, true, to_v3d_fence(fence)->seqno, - job->start, job->end); - -- if (q == V3D_BIN) { -- if (exec->qma) { -- V3D_CORE_WRITE(0, V3D_CLE_CT0QMA, exec->qma); -- V3D_CORE_WRITE(0, V3D_CLE_CT0QMS, exec->qms); -- } -- if (exec->qts) { -- V3D_CORE_WRITE(0, V3D_CLE_CT0QTS, -- V3D_CLE_CT0QTS_ENABLE | -- exec->qts); -- } -- } else { -- /* XXX: Set the QCFG */ -- } -+ /* XXX: Set the QCFG */ - - /* Set the current and end address of the control list. - * Writing the end register is what starts the job. - */ -- V3D_CORE_WRITE(0, V3D_CLE_CTNQBA(q), job->start); -- V3D_CORE_WRITE(0, V3D_CLE_CTNQEA(q), job->end); -+ V3D_CORE_WRITE(0, V3D_CLE_CT1QBA, job->start); -+ V3D_CORE_WRITE(0, V3D_CLE_CT1QEA, job->end); - - return fence; - } -@@ -186,7 +209,7 @@ static struct dma_fence * - v3d_tfu_job_run(struct drm_sched_job *sched_job) - { - struct v3d_tfu_job *job = to_tfu_job(sched_job); -- struct v3d_dev *v3d = job->v3d; -+ struct v3d_dev *v3d = job->base.v3d; - struct drm_device *dev = &v3d->drm; - struct dma_fence *fence; - -@@ -195,9 +218,9 @@ v3d_tfu_job_run(struct drm_sched_job *sc - return NULL; - - v3d->tfu_job = job; -- if (job->irq_fence) -- dma_fence_put(job->irq_fence); -- job->irq_fence = dma_fence_get(fence); -+ if (job->base.irq_fence) -+ dma_fence_put(job->base.irq_fence); -+ job->base.irq_fence = dma_fence_get(fence); - - trace_v3d_submit_tfu(dev, to_v3d_fence(fence)->seqno); - -@@ -247,25 +270,23 @@ v3d_gpu_reset_for_timeout(struct v3d_dev - mutex_unlock(&v3d->reset_lock); - } - -+/* If the current address or return address have changed, then the GPU -+ * has probably made progress and we should delay the reset. This -+ * could fail if the GPU got in an infinite loop in the CL, but that -+ * is pretty unlikely outside of an i-g-t testcase. -+ */ - static void --v3d_job_timedout(struct drm_sched_job *sched_job) -+v3d_cl_job_timedout(struct drm_sched_job *sched_job, enum v3d_queue q, -+ u32 *timedout_ctca, u32 *timedout_ctra) - { - struct v3d_job *job = to_v3d_job(sched_job); -- struct v3d_exec_info *exec = job->exec; -- struct v3d_dev *v3d = exec->v3d; -- enum v3d_queue job_q = job == &exec->bin ? V3D_BIN : V3D_RENDER; -- u32 ctca = V3D_CORE_READ(0, V3D_CLE_CTNCA(job_q)); -- u32 ctra = V3D_CORE_READ(0, V3D_CLE_CTNRA(job_q)); -- -- /* If the current address or return address have changed, then -- * the GPU has probably made progress and we should delay the -- * reset. This could fail if the GPU got in an infinite loop -- * in the CL, but that is pretty unlikely outside of an i-g-t -- * testcase. -- */ -- if (job->timedout_ctca != ctca || job->timedout_ctra != ctra) { -- job->timedout_ctca = ctca; -- job->timedout_ctra = ctra; -+ struct v3d_dev *v3d = job->v3d; -+ u32 ctca = V3D_CORE_READ(0, V3D_CLE_CTNCA(q)); -+ u32 ctra = V3D_CORE_READ(0, V3D_CLE_CTNRA(q)); -+ -+ if (*timedout_ctca != ctca || *timedout_ctra != ctra) { -+ *timedout_ctca = ctca; -+ *timedout_ctra = ctra; - schedule_delayed_work(&job->base.work_tdr, - job->base.sched->timeout); - return; -@@ -275,25 +296,50 @@ v3d_job_timedout(struct drm_sched_job *s - } - - static void -+v3d_bin_job_timedout(struct drm_sched_job *sched_job) -+{ -+ struct v3d_bin_job *job = to_bin_job(sched_job); -+ -+ v3d_cl_job_timedout(sched_job, V3D_BIN, -+ &job->timedout_ctca, &job->timedout_ctra); -+} -+ -+static void -+v3d_render_job_timedout(struct drm_sched_job *sched_job) -+{ -+ struct v3d_render_job *job = to_render_job(sched_job); -+ -+ v3d_cl_job_timedout(sched_job, V3D_RENDER, -+ &job->timedout_ctca, &job->timedout_ctra); -+} -+ -+static void - v3d_tfu_job_timedout(struct drm_sched_job *sched_job) - { -- struct v3d_tfu_job *job = to_tfu_job(sched_job); -+ struct v3d_job *job = to_v3d_job(sched_job); - - v3d_gpu_reset_for_timeout(job->v3d, sched_job); - } - --static const struct drm_sched_backend_ops v3d_sched_ops = { -+static const struct drm_sched_backend_ops v3d_bin_sched_ops = { - .dependency = v3d_job_dependency, -- .run_job = v3d_job_run, -- .timedout_job = v3d_job_timedout, -- .free_job = v3d_job_free -+ .run_job = v3d_bin_job_run, -+ .timedout_job = v3d_bin_job_timedout, -+ .free_job = v3d_job_free, -+}; -+ -+static const struct drm_sched_backend_ops v3d_render_sched_ops = { -+ .dependency = v3d_render_job_dependency, -+ .run_job = v3d_render_job_run, -+ .timedout_job = v3d_render_job_timedout, -+ .free_job = v3d_job_free, - }; - - static const struct drm_sched_backend_ops v3d_tfu_sched_ops = { -- .dependency = v3d_tfu_job_dependency, -+ .dependency = v3d_job_dependency, - .run_job = v3d_tfu_job_run, - .timedout_job = v3d_tfu_job_timedout, -- .free_job = v3d_tfu_job_free -+ .free_job = v3d_job_free, - }; - - int -@@ -305,7 +351,7 @@ v3d_sched_init(struct v3d_dev *v3d) - int ret; - - ret = drm_sched_init(&v3d->queue[V3D_BIN].sched, -- &v3d_sched_ops, -+ &v3d_bin_sched_ops, - hw_jobs_limit, job_hang_limit, - msecs_to_jiffies(hang_limit_ms), - "v3d_bin"); -@@ -315,7 +361,7 @@ v3d_sched_init(struct v3d_dev *v3d) - } - - ret = drm_sched_init(&v3d->queue[V3D_RENDER].sched, -- &v3d_sched_ops, -+ &v3d_render_sched_ops, - hw_jobs_limit, job_hang_limit, - msecs_to_jiffies(hang_limit_ms), - "v3d_render"); diff --git a/target/linux/brcm2708/patches-4.19/950-0592-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch b/target/linux/brcm2708/patches-4.19/950-0592-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch new file mode 100644 index 0000000000..73611b8a7c --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0592-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch @@ -0,0 +1,80 @@ +From 32964196c5dd171ac78f692faba460ae1229b995 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 18 Mar 2019 16:38:32 -0700 +Subject: [PATCH 592/725] drm/vc4: Expose the format modifiers for firmware + kms. + +This should technically not expose VC4_T_TILED on pi4. However, if we +don't expose anything, then userspace will assume that display can +handle whatever modifiers 3d can do (UIF on 2711). By exposing a +list, that will get intersected with what 3D can do so that we get T +tiling for display on 2710 and linear on 2711. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 33 +++++++++++++++++++++++++- + 1 file changed, 32 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -281,6 +281,27 @@ static void vc4_plane_destroy(struct drm + drm_plane_cleanup(plane); + } + ++static bool vc4_fkms_format_mod_supported(struct drm_plane *plane, ++ uint32_t format, ++ uint64_t modifier) ++{ ++ /* Support T_TILING for RGB formats only. */ ++ switch (format) { ++ case DRM_FORMAT_XRGB8888: ++ case DRM_FORMAT_ARGB8888: ++ switch (modifier) { ++ case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: ++ case DRM_FORMAT_MOD_LINEAR: ++ case DRM_FORMAT_MOD_BROADCOM_UIF: ++ return true; ++ default: ++ return false; ++ } ++ default: ++ return false; ++ } ++} ++ + static const struct drm_plane_funcs vc4_plane_funcs = { + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, +@@ -289,6 +310,7 @@ static const struct drm_plane_funcs vc4_ + .reset = drm_atomic_helper_plane_reset, + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, ++ .format_mod_supported = vc4_fkms_format_mod_supported, + }; + + static const struct drm_plane_helper_funcs vc4_primary_plane_helper_funcs = { +@@ -316,6 +338,14 @@ static struct drm_plane *vc4_fkms_plane_ + u32 argb8888 = DRM_FORMAT_ARGB8888; + int ret = 0; + bool primary = (type == DRM_PLANE_TYPE_PRIMARY); ++ static const uint64_t modifiers[] = { ++ DRM_FORMAT_MOD_LINEAR, ++ /* VC4_T_TILED should come after linear, because we ++ * would prefer to scan out linear (less bus traffic). ++ */ ++ DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED, ++ DRM_FORMAT_MOD_INVALID, ++ }; + + vc4_plane = devm_kzalloc(dev->dev, sizeof(*vc4_plane), + GFP_KERNEL); +@@ -327,7 +357,8 @@ static struct drm_plane *vc4_fkms_plane_ + plane = &vc4_plane->base; + ret = drm_universal_plane_init(dev, plane, 0xff, + &vc4_plane_funcs, +- primary ? &xrgb8888 : &argb8888, 1, NULL, ++ primary ? &xrgb8888 : &argb8888, 1, ++ modifiers, + type, primary ? "primary" : "cursor"); + + if (type == DRM_PLANE_TYPE_PRIMARY) { diff --git a/target/linux/brcm2708/patches-4.19/950-0593-drm-v3d-Add-missing-implicit-synchronization.patch b/target/linux/brcm2708/patches-4.19/950-0593-drm-v3d-Add-missing-implicit-synchronization.patch deleted file mode 100644 index 00c8d32984..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0593-drm-v3d-Add-missing-implicit-synchronization.patch +++ /dev/null @@ -1,279 +0,0 @@ -From 50482167989066e0fb9597fe37146a0ee5bc4067 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Wed, 27 Mar 2019 17:44:40 -0700 -Subject: [PATCH 593/703] drm/v3d: Add missing implicit synchronization. - -It is the expectation of existing userspace (X11 + Mesa, in -particular) that jobs submitted to the kernel against a shared BO will -get implicitly synchronized by their submission order. If we want to -allow clever userspace to disable implicit synchronization, we should -do that under its own submit flag (as amdgpu and lima do). - -Note that we currently only implicitly sync for the rendering pass, -not binning -- if you texture-from-pixmap in the binning vertex shader -(vertex coordinate generation), you'll miss out on synchronization. - -Fixes flickering when multiple clients are running in parallel, -particularly GL apps and compositors. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/v3d/v3d_drv.h | 10 +--- - drivers/gpu/drm/v3d/v3d_gem.c | 98 ++++++++++++++++++++++++++++++--- - drivers/gpu/drm/v3d/v3d_sched.c | 45 ++------------- - 3 files changed, 96 insertions(+), 57 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_drv.h -+++ b/drivers/gpu/drm/v3d/v3d_drv.h -@@ -186,8 +186,9 @@ struct v3d_job { - struct v3d_bo **bo; - u32 bo_count; - -- /* An optional fence userspace can pass in for the job to depend on. */ -- struct dma_fence *in_fence; -+ struct dma_fence **deps; -+ int deps_count; -+ int deps_size; - - /* v3d fence to be signaled by IRQ handler when the job is complete. */ - struct dma_fence *irq_fence; -@@ -219,11 +220,6 @@ struct v3d_bin_job { - struct v3d_render_job { - struct v3d_job base; - -- /* Optional fence for the binner, to depend on before starting -- * our job. -- */ -- struct dma_fence *bin_done_fence; -- - /* GPU virtual addresses of the start/end of the CL job. */ - u32 start, end; - ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -218,6 +218,71 @@ v3d_unlock_bo_reservations(struct v3d_bo - ww_acquire_fini(acquire_ctx); - } - -+static int -+v3d_add_dep(struct v3d_job *job, struct dma_fence *fence) -+{ -+ if (!fence) -+ return 0; -+ -+ if (job->deps_size == job->deps_count) { -+ int new_deps_size = max(job->deps_size * 2, 4); -+ struct dma_fence **new_deps = -+ krealloc(job->deps, new_deps_size * sizeof(*new_deps), -+ GFP_KERNEL); -+ if (!new_deps) { -+ dma_fence_put(fence); -+ return -ENOMEM; -+ } -+ -+ job->deps = new_deps; -+ job->deps_size = new_deps_size; -+ } -+ -+ job->deps[job->deps_count++] = fence; -+ -+ return 0; -+} -+ -+/** -+ * Adds the required implicit fences before executing the job -+ * -+ * Userspace (X11 + Mesa) requires that a job submitted against a shared BO -+ * from one fd will implicitly synchronize against previous jobs submitted -+ * against that BO from other fds. -+ * -+ * Currently we don't bother trying to track the shared BOs, and instead just -+ * sync everything. However, our synchronization is only for the render pass -+ * -- the binning stage (VS coordinate calculations) ignores implicit sync, -+ * since using shared buffers for texture coordinates seems unlikely, and -+ * implicitly syncing them would break bin/render parallelism. If we want to -+ * fix that, we should introduce a flag when VS texturing has been used in the -+ * binning stage, or a set of flags for which BOs are sampled during binning. -+ */ -+static int -+v3d_add_implicit_fences(struct v3d_job *job, struct v3d_bo *bo) -+{ -+ int i, ret, nr_fences; -+ struct dma_fence **fences; -+ -+ ret = reservation_object_get_fences_rcu(bo->resv, NULL, -+ &nr_fences, &fences); -+ if (ret || !nr_fences) -+ return ret; -+ -+ for (i = 0; i < nr_fences; i++) { -+ ret = v3d_add_dep(job, fences[i]); -+ if (ret) -+ break; -+ } -+ -+ /* Free any remaining fences after error. */ -+ for (; i < nr_fences; i++) -+ dma_fence_put(fences[i]); -+ kfree(fences); -+ -+ return ret; -+} -+ - /* Takes the reservation lock on all the BOs being referenced, so that - * at queue submit time we can update the reservations. - * -@@ -226,10 +291,11 @@ v3d_unlock_bo_reservations(struct v3d_bo - * to v3d, so we don't attach dma-buf fences to them. - */ - static int --v3d_lock_bo_reservations(struct v3d_bo **bos, -- int bo_count, -+v3d_lock_bo_reservations(struct v3d_job *job, - struct ww_acquire_ctx *acquire_ctx) - { -+ struct v3d_bo **bos = job->bo; -+ int bo_count = job->bo_count; - int contended_lock = -1; - int i, ret; - -@@ -281,6 +347,13 @@ retry: - * before we commit the CL to the hardware. - */ - for (i = 0; i < bo_count; i++) { -+ ret = v3d_add_implicit_fences(job, bos[i]); -+ if (ret) { -+ v3d_unlock_bo_reservations(bos, bo_count, -+ acquire_ctx); -+ return ret; -+ } -+ - ret = reservation_object_reserve_shared(bos[i]->resv); - if (ret) { - v3d_unlock_bo_reservations(bos, bo_count, -@@ -383,7 +456,10 @@ v3d_job_free(struct kref *ref) - } - kvfree(job->bo); - -- dma_fence_put(job->in_fence); -+ for (i = 0; i < job->deps_count; i++) -+ dma_fence_put(job->deps[i]); -+ kfree(job->deps); -+ - dma_fence_put(job->irq_fence); - dma_fence_put(job->done_fence); - -@@ -464,15 +540,20 @@ v3d_job_init(struct v3d_dev *v3d, struct - struct v3d_job *job, void (*free)(struct kref *ref), - u32 in_sync) - { -+ struct dma_fence *in_fence = NULL; - int ret; - - job->v3d = v3d; - job->free = free; - -- ret = drm_syncobj_find_fence(file_priv, in_sync, 0, &job->in_fence); -+ ret = drm_syncobj_find_fence(file_priv, in_sync, 0, &in_fence); - if (ret == -EINVAL) - return ret; - -+ ret = v3d_add_dep(job, in_fence); -+ if (ret) -+ return ret; -+ - kref_init(&job->refcount); - - return 0; -@@ -590,8 +671,7 @@ v3d_submit_cl_ioctl(struct drm_device *d - if (ret) - goto fail; - -- ret = v3d_lock_bo_reservations(render->base.bo, render->base.bo_count, -- &acquire_ctx); -+ ret = v3d_lock_bo_reservations(&render->base, &acquire_ctx); - if (ret) - goto fail; - -@@ -601,7 +681,8 @@ v3d_submit_cl_ioctl(struct drm_device *d - if (ret) - goto fail_unreserve; - -- render->bin_done_fence = dma_fence_get(bin->base.done_fence); -+ ret = v3d_add_dep(&render->base, -+ dma_fence_get(bin->base.done_fence)); - } - - ret = v3d_push_job(v3d_priv, &render->base, V3D_RENDER); -@@ -692,8 +773,7 @@ v3d_submit_tfu_ioctl(struct drm_device * - } - spin_unlock(&file_priv->table_lock); - -- ret = v3d_lock_bo_reservations(job->base.bo, job->base.bo_count, -- &acquire_ctx); -+ ret = v3d_lock_bo_reservations(&job->base, &acquire_ctx); - if (ret) - goto fail; - ---- a/drivers/gpu/drm/v3d/v3d_sched.c -+++ b/drivers/gpu/drm/v3d/v3d_sched.c -@@ -67,47 +67,10 @@ v3d_job_dependency(struct drm_sched_job - struct drm_sched_entity *s_entity) - { - struct v3d_job *job = to_v3d_job(sched_job); -- struct dma_fence *fence; -- -- fence = job->in_fence; -- if (fence) { -- job->in_fence = NULL; -- return fence; -- } -- -- return NULL; --} - --/** -- * Returns the fences that the render job depends on, one by one. -- * v3d_job_run() won't be called until all of them have been signaled. -- */ --static struct dma_fence * --v3d_render_job_dependency(struct drm_sched_job *sched_job, -- struct drm_sched_entity *s_entity) --{ -- struct v3d_render_job *job = to_render_job(sched_job); -- struct dma_fence *fence; -- -- fence = v3d_job_dependency(sched_job, s_entity); -- if (fence) -- return fence; -- -- /* If we had a bin job, the render job definitely depends on -- * it. We first have to wait for bin to be scheduled, so that -- * its done_fence is created. -- */ -- fence = job->bin_done_fence; -- if (fence) { -- job->bin_done_fence = NULL; -- return fence; -- } -- -- /* XXX: Wait on a fence for switching the GMP if necessary, -- * and then do so. -- */ -- -- return fence; -+ if (!job->deps_count) -+ return NULL; -+ return job->deps[--job->deps_count]; - } - - static struct dma_fence *v3d_bin_job_run(struct drm_sched_job *sched_job) -@@ -329,7 +292,7 @@ static const struct drm_sched_backend_op - }; - - static const struct drm_sched_backend_ops v3d_render_sched_ops = { -- .dependency = v3d_render_job_dependency, -+ .dependency = v3d_job_dependency, - .run_job = v3d_render_job_run, - .timedout_job = v3d_render_job_timedout, - .free_job = v3d_job_free, diff --git a/target/linux/brcm2708/patches-4.19/950-0593-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch b/target/linux/brcm2708/patches-4.19/950-0593-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch new file mode 100644 index 0000000000..3f87ea7377 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0593-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch @@ -0,0 +1,45 @@ +From 347a871c771ab3682febed0cc5011618234c2b9e Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Tue, 2 Apr 2019 13:29:00 -0700 +Subject: [PATCH 593/725] drm/vc4: Fix vblank timestamping for firmwarekms. + +The core doesn't expect a false return from the scanoutpos function in +normal usage, so we were doing the precise vblank timestamping path +and thus "immediate" vblank disables (even though firmwarekms can't +actually disable vblanks interrupts, sigh), and the kernel would get +confused when getting timestamp info when also turning vblanks back +on. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_crtc.c | 3 --- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 6 ++++++ + 2 files changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_crtc.c ++++ b/drivers/gpu/drm/vc4/vc4_crtc.c +@@ -133,9 +133,6 @@ bool vc4_crtc_get_scanoutpos(struct drm_ + int vblank_lines; + bool ret = false; + +- if (vc4->firmware_kms) +- return 0; +- + /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ + + /* Get optional system timestamp before query. */ +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -673,6 +673,12 @@ static int vc4_fkms_bind(struct device * + + vc4->firmware_kms = true; + ++ /* firmware kms doesn't have precise a scanoutpos implementation, so ++ * we can't do the precise vblank timestamp mode. ++ */ ++ drm->driver->get_scanout_position = NULL; ++ drm->driver->get_vblank_timestamp = NULL; ++ + vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL); + if (!vc4_crtc) + return -ENOMEM; diff --git a/target/linux/brcm2708/patches-4.19/950-0594-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch b/target/linux/brcm2708/patches-4.19/950-0594-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch deleted file mode 100644 index a79426c73e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0594-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch +++ /dev/null @@ -1,44 +0,0 @@ -From a7b923e660e71a2d2b13a7aac36f11b9dcec9295 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 28 Mar 2019 11:58:51 -0700 -Subject: [PATCH 594/703] drm/vc4: Fix synchronization firmwarekms against GL - rendering. - -We would present the framebuffer immediately without waiting for -rendering to finish first, resulting in stuttering and flickering as a -window was dragged around when the GPU was busy enough to not just win -the race. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -15,6 +15,7 @@ - */ - - #include "drm/drm_atomic_helper.h" -+#include "drm/drm_gem_framebuffer_helper.h" - #include "drm/drm_plane_helper.h" - #include "drm/drm_crtc_helper.h" - #include "drm/drm_fourcc.h" -@@ -291,7 +292,7 @@ static const struct drm_plane_funcs vc4_ - }; - - static const struct drm_plane_helper_funcs vc4_primary_plane_helper_funcs = { -- .prepare_fb = NULL, -+ .prepare_fb = drm_gem_fb_prepare_fb, - .cleanup_fb = NULL, - .atomic_check = vc4_plane_atomic_check, - .atomic_update = vc4_primary_plane_atomic_update, -@@ -299,7 +300,7 @@ static const struct drm_plane_helper_fun - }; - - static const struct drm_plane_helper_funcs vc4_cursor_plane_helper_funcs = { -- .prepare_fb = NULL, -+ .prepare_fb = drm_gem_fb_prepare_fb, - .cleanup_fb = NULL, - .atomic_check = vc4_plane_atomic_check, - .atomic_update = vc4_cursor_plane_atomic_update, diff --git a/target/linux/brcm2708/patches-4.19/950-0594-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch b/target/linux/brcm2708/patches-4.19/950-0594-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch new file mode 100644 index 0000000000..96d600c47f --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0594-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch @@ -0,0 +1,216 @@ +From 55e1b4a94b6ea98ad4c170b79b30e2ed39855535 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 26 Mar 2019 14:43:06 +0000 +Subject: [PATCH 594/725] gpu: vc4-fkms: Switch to the newer mailbox frame + buffer API. + +The old mailbox FB API was ideally deprecated but still used by +the FKMS driver. +Update to the newer API. + +NB This needs current firmware that accepts ARM allocated buffers +through the newer API. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 109 +++++++++++---------- + include/soc/bcm2835/raspberrypi-firmware.h | 10 ++ + 2 files changed, 67 insertions(+), 52 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -28,6 +28,25 @@ + #include "vc4_regs.h" + #include + ++struct fb_alloc_tags { ++ struct rpi_firmware_property_tag_header tag1; ++ u32 xres, yres; ++ struct rpi_firmware_property_tag_header tag2; ++ u32 xres_virtual, yres_virtual; ++ struct rpi_firmware_property_tag_header tag3; ++ u32 bpp; ++ struct rpi_firmware_property_tag_header tag4; ++ u32 xoffset, yoffset; ++ struct rpi_firmware_property_tag_header tag5; ++ u32 base, screen_size; ++ struct rpi_firmware_property_tag_header tag6; ++ u32 pitch; ++ struct rpi_firmware_property_tag_header tag7; ++ u32 alpha_mode; ++ struct rpi_firmware_property_tag_header tag8; ++ u32 layer; ++}; ++ + /* The firmware delivers a vblank interrupt to us through the SMI + * hardware, which has only this one register. + */ +@@ -121,45 +140,39 @@ static void vc4_primary_plane_atomic_upd + struct drm_plane_state *old_state) + { + struct vc4_dev *vc4 = to_vc4_dev(plane->dev); +- struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane); + struct drm_plane_state *state = plane->state; + struct drm_framebuffer *fb = state->fb; + struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); +- volatile struct fbinfo_s *fbinfo = vc4_plane->fbinfo; ++ u32 format = fb->format->format; ++ struct fb_alloc_tags fbinfo = { ++ .tag1 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT, ++ 8, 0, }, ++ .xres = state->crtc_w, ++ .yres = state->crtc_h, ++ .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT, ++ 8, 0, }, ++ .xres_virtual = state->crtc_w, ++ .yres_virtual = state->crtc_h, ++ .tag3 = { RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH, 4, 0 }, ++ .bpp = 32, ++ .tag4 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET, 8, 0 }, ++ .xoffset = 0, ++ .yoffset = 0, ++ .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 }, ++ .base = bo->paddr + fb->offsets[0], ++ .screen_size = state->crtc_w * state->crtc_h * 4, ++ .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH, 4, 0 }, ++ .pitch = fb->pitches[0], ++ .tag7 = { RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE, 4, 0 }, ++ .alpha_mode = format == DRM_FORMAT_ARGB8888 ? 0 : 2, ++ .tag8 = { RPI_FIRMWARE_FRAMEBUFFER_SET_LAYER, 4, 0 }, ++ .layer = -127, ++ }; + u32 bpp = 32; + int ret; + +- fbinfo->xres = state->crtc_w; +- fbinfo->yres = state->crtc_h; +- fbinfo->xres_virtual = state->crtc_w; +- fbinfo->yres_virtual = state->crtc_h; +- fbinfo->bpp = bpp; +- fbinfo->xoffset = state->crtc_x; +- fbinfo->yoffset = state->crtc_y; +- fbinfo->base = bo->paddr + fb->offsets[0]; +- fbinfo->pitch = fb->pitches[0]; +- + if (fb->modifier == DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED) +- fbinfo->bpp |= BIT(31); +- +- /* A bug in the firmware makes it so that if the fb->base is +- * set to nonzero, the configured pitch gets overwritten with +- * the previous pitch. So, to get the configured pitch +- * recomputed, we have to make it allocate itself a new buffer +- * in VC memory, first. +- */ +- if (vc4_plane->pitch != fb->pitches[0]) { +- u32 saved_base = fbinfo->base; +- fbinfo->base = 0; +- +- ret = rpi_firmware_transaction(vc4->firmware, +- RPI_FIRMWARE_CHAN_FB, +- vc4_plane->fbinfo_bus_addr); +- fbinfo->base = saved_base; +- +- vc4_plane->pitch = fbinfo->pitch; +- WARN_ON_ONCE(vc4_plane->pitch != fb->pitches[0]); +- } ++ fbinfo.bpp |= BIT(31); + + DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary update %dx%d@%d +%d,%d 0x%pad/%d\n", + plane->base.id, plane->name, +@@ -168,14 +181,13 @@ static void vc4_primary_plane_atomic_upd + bpp, + state->crtc_x, + state->crtc_y, +- &fbinfo->base, ++ &fbinfo.base, + fb->pitches[0]); + +- ret = rpi_firmware_transaction(vc4->firmware, +- RPI_FIRMWARE_CHAN_FB, +- vc4_plane->fbinfo_bus_addr); +- WARN_ON_ONCE(fbinfo->pitch != fb->pitches[0]); +- WARN_ON_ONCE(fbinfo->base != bo->paddr + fb->offsets[0]); ++ ret = rpi_firmware_property_list(vc4->firmware, &fbinfo, ++ sizeof(fbinfo)); ++ WARN_ON_ONCE(fbinfo.pitch != fb->pitches[0]); ++ WARN_ON_ONCE(fbinfo.base != bo->paddr + fb->offsets[0]); + + /* If the CRTC is on (or going to be on) and we're enabled, + * then unblank. Otherwise, stay blank until CRTC enable. +@@ -332,10 +344,10 @@ static const struct drm_plane_helper_fun + static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev, + enum drm_plane_type type) + { ++ /* Primary and cursor planes only */ + struct drm_plane *plane = NULL; + struct vc4_fkms_plane *vc4_plane; +- u32 xrgb8888 = DRM_FORMAT_XRGB8888; +- u32 argb8888 = DRM_FORMAT_ARGB8888; ++ u32 formats[] = {DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888}; + int ret = 0; + bool primary = (type == DRM_PLANE_TYPE_PRIMARY); + static const uint64_t modifiers[] = { +@@ -357,22 +369,15 @@ static struct drm_plane *vc4_fkms_plane_ + plane = &vc4_plane->base; + ret = drm_universal_plane_init(dev, plane, 0xff, + &vc4_plane_funcs, +- primary ? &xrgb8888 : &argb8888, 1, +- modifiers, ++ formats, primary ? 2 : 1, modifiers, + type, primary ? "primary" : "cursor"); + +- if (type == DRM_PLANE_TYPE_PRIMARY) { +- vc4_plane->fbinfo = +- dma_alloc_coherent(dev->dev, +- sizeof(*vc4_plane->fbinfo), +- &vc4_plane->fbinfo_bus_addr, +- GFP_KERNEL); +- memset(vc4_plane->fbinfo, 0, sizeof(*vc4_plane->fbinfo)); +- ++ if (type == DRM_PLANE_TYPE_PRIMARY) + drm_plane_helper_add(plane, &vc4_primary_plane_helper_funcs); +- } else { ++ else + drm_plane_helper_add(plane, &vc4_cursor_plane_helper_funcs); +- } ++ ++ drm_plane_create_alpha_property(plane); + + return plane; + fail: +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -111,9 +111,15 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009, + RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a, + RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_LAYER = 0x0004000c, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_TRANSFORM = 0x0004000d, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_VSYNC = 0x0004000e, + RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f, + RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF = 0x00040010, + RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM = 0x00048013, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS = 0x00040013, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_SETTINGS = 0x00040014, + RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, + RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, + RPI_FIRMWARE_FRAMEBUFFER_TEST_DEPTH = 0x00044005, +@@ -122,6 +128,8 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009, + RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a, + RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_LAYER = 0x0004400c, ++ RPI_FIRMWARE_FRAMEBUFFER_TEST_TRANSFORM = 0x0004400d, + RPI_FIRMWARE_FRAMEBUFFER_TEST_VSYNC = 0x0004400e, + RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, + RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, +@@ -134,6 +142,8 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF = 0x0004801f, + RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF = 0x00048020, + RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_LAYER = 0x0004800c, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_TRANSFORM = 0x0004800d, + RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f, + + RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, diff --git a/target/linux/brcm2708/patches-4.19/950-0595-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch b/target/linux/brcm2708/patches-4.19/950-0595-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch new file mode 100644 index 0000000000..ede0b8e053 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0595-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch @@ -0,0 +1,853 @@ +From 58da9f30e54c4fe6b3ca17afad492d3c156a1503 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 27 Mar 2019 17:45:01 +0000 +Subject: [PATCH 595/725] drm: vc4: Add an overlay plane to vc4-firmware-kms + +This uses a new API that is exposed via the mailbox service +to stick an element straight on the screen using DispmanX. + +The primary and cursor planes have also been switched to using +the new plane API, and it supports layering based on the DRM +zpos parameter. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 518 ++++++++++++++------- + drivers/gpu/drm/vc4/vc4_kms.c | 1 + + drivers/gpu/drm/vc4/vc_image_types.h | 143 ++++++ + include/soc/bcm2835/raspberrypi-firmware.h | 2 + + 4 files changed, 495 insertions(+), 169 deletions(-) + create mode 100644 drivers/gpu/drm/vc4/vc_image_types.h + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -26,8 +26,46 @@ + #include "linux/of_device.h" + #include "vc4_drv.h" + #include "vc4_regs.h" ++#include "vc_image_types.h" + #include + ++struct set_plane { ++ u8 display; ++ u8 plane_id; ++ u8 vc_image_type; ++ s8 layer; ++ ++ u16 width; ++ u16 height; ++ ++ u16 pitch; ++ u16 vpitch; ++ ++ u32 src_x; /* 16p16 */ ++ u32 src_y; /* 16p16 */ ++ ++ u32 src_w; /* 16p16 */ ++ u32 src_h; /* 16p16 */ ++ ++ s16 dst_x; ++ s16 dst_y; ++ ++ u16 dst_w; ++ u16 dst_h; ++ ++ u8 alpha; ++ u8 num_planes; ++ u8 is_vu; ++ u8 padding; ++ ++ u32 planes[4]; /* DMA address of each plane */ ++}; ++ ++struct mailbox_set_plane { ++ struct rpi_firmware_property_tag_header tag; ++ struct set_plane plane; ++}; ++ + struct fb_alloc_tags { + struct rpi_firmware_property_tag_header tag1; + u32 xres, yres; +@@ -47,6 +85,79 @@ struct fb_alloc_tags { + u32 layer; + }; + ++static const struct vc_image_format { ++ u32 drm; /* DRM_FORMAT_* */ ++ u32 vc_image; /* VC_IMAGE_* */ ++ u32 is_vu; ++} vc_image_formats[] = { ++ { ++ .drm = DRM_FORMAT_XRGB8888, ++ .vc_image = VC_IMAGE_XRGB8888, ++ }, ++ { ++ .drm = DRM_FORMAT_ARGB8888, ++ .vc_image = VC_IMAGE_ARGB8888, ++ }, ++/* ++ * FIXME: Need to resolve which DRM format goes to which vc_image format ++ * for the remaining RGBA and RGBX formats. ++ * { ++ * .drm = DRM_FORMAT_ABGR8888, ++ * .vc_image = VC_IMAGE_RGBA8888, ++ * }, ++ * { ++ * .drm = DRM_FORMAT_XBGR8888, ++ * .vc_image = VC_IMAGE_RGBA8888, ++ * }, ++ */ ++ { ++ .drm = DRM_FORMAT_RGB565, ++ .vc_image = VC_IMAGE_RGB565, ++ }, ++ { ++ .drm = DRM_FORMAT_RGB888, ++ .vc_image = VC_IMAGE_BGR888, ++ }, ++ { ++ .drm = DRM_FORMAT_BGR888, ++ .vc_image = VC_IMAGE_RGB888, ++ }, ++ { ++ .drm = DRM_FORMAT_YUV422, ++ .vc_image = VC_IMAGE_YUV422PLANAR, ++ }, ++ { ++ .drm = DRM_FORMAT_YUV420, ++ .vc_image = VC_IMAGE_YUV420, ++ }, ++ { ++ .drm = DRM_FORMAT_YVU420, ++ .vc_image = VC_IMAGE_YUV420, ++ .is_vu = 1, ++ }, ++ { ++ .drm = DRM_FORMAT_NV12, ++ .vc_image = VC_IMAGE_YUV420SP, ++ }, ++ { ++ .drm = DRM_FORMAT_NV21, ++ .vc_image = VC_IMAGE_YUV420SP, ++ .is_vu = 1, ++ }, ++}; ++ ++static const struct vc_image_format *vc4_get_vc_image_fmt(u32 drm_format) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(vc_image_formats); i++) { ++ if (vc_image_formats[i].drm == drm_format) ++ return &vc_image_formats[i]; ++ } ++ ++ return NULL; ++} ++ + /* The firmware delivers a vblank interrupt to us through the SMI + * hardware, which has only this one register. + */ +@@ -113,6 +224,7 @@ struct vc4_fkms_plane { + struct fbinfo_s *fbinfo; + dma_addr_t fbinfo_bus_addr; + u32 pitch; ++ struct mailbox_set_plane mb; + }; + + static inline struct vc4_fkms_plane *to_vc4_fkms_plane(struct drm_plane *plane) +@@ -120,165 +232,183 @@ static inline struct vc4_fkms_plane *to_ + return (struct vc4_fkms_plane *)plane; + } + +-/* Turns the display on/off. */ +-static int vc4_plane_set_primary_blank(struct drm_plane *plane, bool blank) ++static int vc4_plane_set_blank(struct drm_plane *plane, bool blank) + { + struct vc4_dev *vc4 = to_vc4_dev(plane->dev); ++ struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane); ++ struct mailbox_set_plane blank_mb = { ++ .tag = { RPI_FIRMWARE_SET_PLANE, sizeof(struct set_plane), 0 }, ++ .plane = { ++ .display = vc4_plane->mb.plane.display, ++ .plane_id = vc4_plane->mb.plane.plane_id, ++ } ++ }; ++ int ret; + +- u32 packet = blank; +- +- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary plane %s", ++ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] overlay plane %s", + plane->base.id, plane->name, + blank ? "blank" : "unblank"); + +- return rpi_firmware_property(vc4->firmware, +- RPI_FIRMWARE_FRAMEBUFFER_BLANK, +- &packet, sizeof(packet)); ++ if (blank) ++ ret = rpi_firmware_property_list(vc4->firmware, &blank_mb, ++ sizeof(blank_mb)); ++ else ++ ret = rpi_firmware_property_list(vc4->firmware, &vc4_plane->mb, ++ sizeof(vc4_plane->mb)); ++ ++ WARN_ONCE(ret, "%s: firmware call failed. Please update your firmware", ++ __func__); ++ return ret; + } + +-static void vc4_primary_plane_atomic_update(struct drm_plane *plane, +- struct drm_plane_state *old_state) ++static void vc4_plane_atomic_update(struct drm_plane *plane, ++ struct drm_plane_state *old_state) + { +- struct vc4_dev *vc4 = to_vc4_dev(plane->dev); + struct drm_plane_state *state = plane->state; + struct drm_framebuffer *fb = state->fb; + struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); +- u32 format = fb->format->format; +- struct fb_alloc_tags fbinfo = { +- .tag1 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT, +- 8, 0, }, +- .xres = state->crtc_w, +- .yres = state->crtc_h, +- .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT, +- 8, 0, }, +- .xres_virtual = state->crtc_w, +- .yres_virtual = state->crtc_h, +- .tag3 = { RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH, 4, 0 }, +- .bpp = 32, +- .tag4 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET, 8, 0 }, +- .xoffset = 0, +- .yoffset = 0, +- .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 }, +- .base = bo->paddr + fb->offsets[0], +- .screen_size = state->crtc_w * state->crtc_h * 4, +- .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH, 4, 0 }, +- .pitch = fb->pitches[0], +- .tag7 = { RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE, 4, 0 }, +- .alpha_mode = format == DRM_FORMAT_ARGB8888 ? 0 : 2, +- .tag8 = { RPI_FIRMWARE_FRAMEBUFFER_SET_LAYER, 4, 0 }, +- .layer = -127, +- }; +- u32 bpp = 32; +- int ret; ++ const struct drm_format_info *drm_fmt = fb->format; ++ const struct vc_image_format *vc_fmt = ++ vc4_get_vc_image_fmt(drm_fmt->format); ++ struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane); ++ struct mailbox_set_plane *mb = &vc4_plane->mb; ++ struct vc4_crtc *vc4_crtc = to_vc4_crtc(state->crtc); ++ int num_planes = fb->format->num_planes; ++ struct drm_display_mode *mode = &state->crtc->mode; + +- if (fb->modifier == DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED) +- fbinfo.bpp |= BIT(31); ++ mb->plane.vc_image_type = vc_fmt->vc_image; ++ mb->plane.width = fb->width; ++ mb->plane.height = fb->height; ++ mb->plane.pitch = fb->pitches[0]; ++ mb->plane.src_w = state->src_w; ++ mb->plane.src_h = state->src_h; ++ mb->plane.src_x = state->src_x; ++ mb->plane.src_y = state->src_y; ++ mb->plane.dst_w = state->crtc_w; ++ mb->plane.dst_h = state->crtc_h; ++ mb->plane.dst_x = state->crtc_x; ++ mb->plane.dst_y = state->crtc_y; ++ mb->plane.alpha = state->alpha >> 8; ++ mb->plane.layer = state->normalized_zpos ? ++ state->normalized_zpos : -127; ++ mb->plane.num_planes = num_planes; ++ mb->plane.is_vu = vc_fmt->is_vu; ++ mb->plane.planes[0] = bo->paddr + fb->offsets[0]; + +- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary update %dx%d@%d +%d,%d 0x%pad/%d\n", ++ /* FIXME: If the dest rect goes off screen then clip the src rect so we ++ * don't have off-screen pixels. ++ */ ++ if (plane->type == DRM_PLANE_TYPE_CURSOR) { ++ /* There is no scaling on the cursor plane, therefore the calcs ++ * to alter the source crop as the cursor goes off the screen ++ * are simple. ++ */ ++ if (mb->plane.dst_x + mb->plane.dst_w > mode->hdisplay) { ++ mb->plane.dst_w = mode->hdisplay - mb->plane.dst_x; ++ mb->plane.src_w = (mode->hdisplay - mb->plane.dst_x) ++ << 16; ++ } ++ if (mb->plane.dst_y + mb->plane.dst_h > mode->vdisplay) { ++ mb->plane.dst_h = mode->vdisplay - mb->plane.dst_y; ++ mb->plane.src_h = (mode->vdisplay - mb->plane.dst_y) ++ << 16; ++ } ++ } ++ ++ if (num_planes > 1) { ++ /* Assume this must be YUV */ ++ /* Makes assumptions on the stride for the chroma planes as we ++ * can't easily plumb in non-standard pitches. ++ */ ++ mb->plane.planes[1] = bo->paddr + fb->offsets[1]; ++ if (num_planes > 2) ++ mb->plane.planes[2] = bo->paddr + fb->offsets[2]; ++ else ++ mb->plane.planes[2] = 0; ++ ++ /* Special case the YUV420 with U and V as line interleaved ++ * planes as we have special handling for that case. ++ */ ++ if (num_planes == 3 && ++ (fb->offsets[2] - fb->offsets[1]) == fb->pitches[1]) ++ mb->plane.vc_image_type = VC_IMAGE_YUV420_S; ++ } else { ++ mb->plane.planes[1] = 0; ++ mb->plane.planes[2] = 0; ++ } ++ mb->plane.planes[3] = 0; ++ ++ switch (fb->modifier) { ++ case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: ++ switch (mb->plane.vc_image_type) { ++ case VC_IMAGE_RGBX32: ++ mb->plane.vc_image_type = VC_IMAGE_TF_RGBX32; ++ break; ++ case VC_IMAGE_RGBA32: ++ mb->plane.vc_image_type = VC_IMAGE_TF_RGBA32; ++ break; ++ case VC_IMAGE_RGB565: ++ mb->plane.vc_image_type = VC_IMAGE_TF_RGB565; ++ break; ++ } ++ break; ++ case DRM_FORMAT_MOD_BROADCOM_SAND128: ++ mb->plane.vc_image_type = VC_IMAGE_YUV_UV; ++ mb->plane.pitch = fourcc_mod_broadcom_param(fb->modifier); ++ break; ++ } ++ ++ if (vc4_crtc) { ++ mb->plane.dst_x += vc4_crtc->overscan[0]; ++ mb->plane.dst_y += vc4_crtc->overscan[1]; ++ } ++ ++ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] plane update %dx%d@%d +dst(%d,%d, %d,%d) +src(%d,%d, %d,%d) 0x%08x/%08x/%08x/%d, alpha %u zpos %u\n", + plane->base.id, plane->name, +- state->crtc_w, +- state->crtc_h, +- bpp, ++ mb->plane.width, ++ mb->plane.height, ++ mb->plane.vc_image_type, + state->crtc_x, + state->crtc_y, +- &fbinfo.base, +- fb->pitches[0]); +- +- ret = rpi_firmware_property_list(vc4->firmware, &fbinfo, +- sizeof(fbinfo)); +- WARN_ON_ONCE(fbinfo.pitch != fb->pitches[0]); +- WARN_ON_ONCE(fbinfo.base != bo->paddr + fb->offsets[0]); +- +- /* If the CRTC is on (or going to be on) and we're enabled, ++ state->crtc_w, ++ state->crtc_h, ++ mb->plane.src_x, ++ mb->plane.src_y, ++ mb->plane.src_w, ++ mb->plane.src_h, ++ mb->plane.planes[0], ++ mb->plane.planes[1], ++ mb->plane.planes[2], ++ fb->pitches[0], ++ state->alpha, ++ state->normalized_zpos); ++ ++ /* ++ * Do NOT set now, as we haven't checked if the crtc is active or not. ++ * Set from vc4_plane_set_blank instead. ++ * ++ * If the CRTC is on (or going to be on) and we're enabled, + * then unblank. Otherwise, stay blank until CRTC enable. +- */ ++ */ + if (state->crtc->state->active) +- vc4_plane_set_primary_blank(plane, false); ++ vc4_plane_set_blank(plane, false); + } + +-static void vc4_primary_plane_atomic_disable(struct drm_plane *plane, +- struct drm_plane_state *old_state) ++static void vc4_plane_atomic_disable(struct drm_plane *plane, ++ struct drm_plane_state *old_state) + { +- vc4_plane_set_primary_blank(plane, true); +-} +- +-static void vc4_cursor_plane_atomic_update(struct drm_plane *plane, +- struct drm_plane_state *old_state) +-{ +- struct vc4_dev *vc4 = to_vc4_dev(plane->dev); ++ //struct vc4_dev *vc4 = to_vc4_dev(plane->dev); + struct drm_plane_state *state = plane->state; +- struct vc4_crtc *vc4_crtc = to_vc4_crtc(state->crtc); +- struct drm_framebuffer *fb = state->fb; +- struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); +- dma_addr_t addr = bo->paddr + fb->offsets[0]; +- int ret; +- u32 packet_state[] = { +- state->crtc->state->active, +- state->crtc_x, +- state->crtc_y, +- 0 +- }; +- WARN_ON_ONCE(fb->pitches[0] != state->crtc_w * 4); ++ struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane); + +- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] update %dx%d cursor at %d,%d (0x%pad/%d)", ++ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] plane disable %dx%d@%d +%d,%d\n", + plane->base.id, plane->name, + state->crtc_w, + state->crtc_h, ++ vc4_plane->mb.plane.vc_image_type, + state->crtc_x, +- state->crtc_y, +- &addr, +- fb->pitches[0]); +- +- /* add on the top/left offsets when overscan is active */ +- if (vc4_crtc) { +- packet_state[1] += vc4_crtc->overscan[0]; +- packet_state[2] += vc4_crtc->overscan[1]; +- } +- +- ret = rpi_firmware_property(vc4->firmware, +- RPI_FIRMWARE_SET_CURSOR_STATE, +- &packet_state, +- sizeof(packet_state)); +- if (ret || packet_state[0] != 0) +- DRM_ERROR("Failed to set cursor state: 0x%08x\n", packet_state[0]); +- +- /* Note: When the cursor contents change, the modesetting +- * driver calls drm_mode_cursor_univeral() with +- * DRM_MODE_CURSOR_BO, which means a new fb will be allocated. +- */ +- if (!old_state || +- state->crtc_w != old_state->crtc_w || +- state->crtc_h != old_state->crtc_h || +- fb != old_state->fb) { +- u32 packet_info[] = { state->crtc_w, state->crtc_h, +- 0, /* unused */ +- addr, +- 0, 0, /* hotx, hoty */}; +- +- ret = rpi_firmware_property(vc4->firmware, +- RPI_FIRMWARE_SET_CURSOR_INFO, +- &packet_info, +- sizeof(packet_info)); +- if (ret || packet_info[0] != 0) +- DRM_ERROR("Failed to set cursor info: 0x%08x\n", packet_info[0]); +- } +-} +- +-static void vc4_cursor_plane_atomic_disable(struct drm_plane *plane, +- struct drm_plane_state *old_state) +-{ +- struct vc4_dev *vc4 = to_vc4_dev(plane->dev); +- 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, +- sizeof(packet_state)); +- if (ret || packet_state[0] != 0) +- DRM_ERROR("Failed to set cursor state: 0x%08x\n", packet_state[0]); ++ state->crtc_y); ++ vc4_plane_set_blank(plane, true); + } + + static int vc4_plane_atomic_check(struct drm_plane *plane, +@@ -301,6 +431,7 @@ static bool vc4_fkms_format_mod_supporte + switch (format) { + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ARGB8888: ++ case DRM_FORMAT_RGB565: + switch (modifier) { + case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: + case DRM_FORMAT_MOD_LINEAR: +@@ -309,8 +440,22 @@ static bool vc4_fkms_format_mod_supporte + default: + return false; + } ++ case DRM_FORMAT_NV12: ++ case DRM_FORMAT_NV21: ++ switch (fourcc_mod_broadcom_mod(modifier)) { ++ case DRM_FORMAT_MOD_LINEAR: ++ case DRM_FORMAT_MOD_BROADCOM_SAND128: ++ return true; ++ default: ++ return false; ++ } ++ case DRM_FORMAT_RGB888: ++ case DRM_FORMAT_BGR888: ++ case DRM_FORMAT_YUV422: ++ case DRM_FORMAT_YUV420: ++ case DRM_FORMAT_YVU420: + default: +- return false; ++ return (modifier == DRM_FORMAT_MOD_LINEAR); + } + } + +@@ -325,31 +470,24 @@ static const struct drm_plane_funcs vc4_ + .format_mod_supported = vc4_fkms_format_mod_supported, + }; + +-static const struct drm_plane_helper_funcs vc4_primary_plane_helper_funcs = { +- .prepare_fb = drm_gem_fb_prepare_fb, +- .cleanup_fb = NULL, +- .atomic_check = vc4_plane_atomic_check, +- .atomic_update = vc4_primary_plane_atomic_update, +- .atomic_disable = vc4_primary_plane_atomic_disable, +-}; +- +-static const struct drm_plane_helper_funcs vc4_cursor_plane_helper_funcs = { ++static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = { + .prepare_fb = drm_gem_fb_prepare_fb, + .cleanup_fb = NULL, + .atomic_check = vc4_plane_atomic_check, +- .atomic_update = vc4_cursor_plane_atomic_update, +- .atomic_disable = vc4_cursor_plane_atomic_disable, ++ .atomic_update = vc4_plane_atomic_update, ++ .atomic_disable = vc4_plane_atomic_disable, + }; + + static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev, +- enum drm_plane_type type) ++ enum drm_plane_type type, ++ u8 plane_id) + { +- /* Primary and cursor planes only */ + struct drm_plane *plane = NULL; + struct vc4_fkms_plane *vc4_plane; +- u32 formats[] = {DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888}; ++ u32 formats[ARRAY_SIZE(vc_image_formats)]; ++ unsigned int default_zpos; ++ u32 num_formats = 0; + int ret = 0; +- bool primary = (type == DRM_PLANE_TYPE_PRIMARY); + static const uint64_t modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + /* VC4_T_TILED should come after linear, because we +@@ -358,6 +496,7 @@ static struct drm_plane *vc4_fkms_plane_ + DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED, + DRM_FORMAT_MOD_INVALID, + }; ++ int i; + + vc4_plane = devm_kzalloc(dev->dev, sizeof(*vc4_plane), + GFP_KERNEL); +@@ -366,19 +505,48 @@ static struct drm_plane *vc4_fkms_plane_ + goto fail; + } + ++ for (i = 0; i < ARRAY_SIZE(vc_image_formats); i++) ++ formats[num_formats++] = vc_image_formats[i].drm; ++ + plane = &vc4_plane->base; + ret = drm_universal_plane_init(dev, plane, 0xff, + &vc4_plane_funcs, +- formats, primary ? 2 : 1, modifiers, +- type, primary ? "primary" : "cursor"); ++ formats, num_formats, modifiers, ++ type, NULL); + +- if (type == DRM_PLANE_TYPE_PRIMARY) +- drm_plane_helper_add(plane, &vc4_primary_plane_helper_funcs); +- else +- drm_plane_helper_add(plane, &vc4_cursor_plane_helper_funcs); ++ drm_plane_helper_add(plane, &vc4_plane_helper_funcs); + + drm_plane_create_alpha_property(plane); + ++ /* ++ * Default frame buffer setup is with FB on -127, and raspistill etc ++ * tend to drop overlays on layer 2. Cursor plane was on layer +127. ++ * ++ * For F-KMS the mailbox call allows for a s8. ++ * Remap zpos 0 to -127 for the background layer, but leave all the ++ * other layers as requested by KMS. ++ */ ++ switch (type) { ++ case DRM_PLANE_TYPE_PRIMARY: ++ default_zpos = 0; ++ break; ++ case DRM_PLANE_TYPE_OVERLAY: ++ default_zpos = 1; ++ break; ++ case DRM_PLANE_TYPE_CURSOR: ++ default_zpos = 2; ++ break; ++ } ++ drm_plane_create_zpos_property(plane, default_zpos, 0, 127); ++ ++ /* Prepare the static elements of the mailbox structure */ ++ vc4_plane->mb.tag.tag = RPI_FIRMWARE_SET_PLANE; ++ vc4_plane->mb.tag.buf_size = sizeof(struct set_plane); ++ vc4_plane->mb.tag.req_resp_size = 0; ++ vc4_plane->mb.plane.display = 0; ++ vc4_plane->mb.plane.plane_id = plane_id; ++ vc4_plane->mb.plane.layer = default_zpos ? default_zpos : -127; ++ + return plane; + fail: + if (plane) +@@ -400,19 +568,23 @@ static void vc4_crtc_disable(struct drm_ + * whether anything scans out at all, but the firmware doesn't + * give us a CRTC-level control for that. + */ +- vc4_cursor_plane_atomic_disable(crtc->cursor, crtc->cursor->state); +- vc4_plane_set_primary_blank(crtc->primary, true); ++ ++ vc4_plane_atomic_disable(crtc->cursor, crtc->cursor->state); ++ vc4_plane_atomic_disable(crtc->primary, crtc->primary->state); ++ ++ /* FIXME: Disable overlay planes */ + } + + static void vc4_crtc_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) + { + /* Unblank the planes (if they're supposed to be displayed). */ ++ + if (crtc->primary->state->fb) +- vc4_plane_set_primary_blank(crtc->primary, false); +- if (crtc->cursor->state->fb) { +- vc4_cursor_plane_atomic_update(crtc->cursor, +- crtc->cursor->state); +- } ++ vc4_plane_set_blank(crtc->primary, false); ++ if (crtc->cursor->state->fb) ++ vc4_plane_set_blank(crtc->cursor, crtc->cursor->state); ++ ++ /* FIXME: Enable overlay planes */ + } + + static int vc4_crtc_atomic_check(struct drm_crtc *crtc, +@@ -672,8 +844,10 @@ static int vc4_fkms_bind(struct device * + struct vc4_crtc *vc4_crtc; + struct vc4_fkms_encoder *vc4_encoder; + struct drm_crtc *crtc; +- struct drm_plane *primary_plane, *cursor_plane, *destroy_plane, *temp; ++ struct drm_plane *primary_plane, *overlay_plane, *cursor_plane; ++ struct drm_plane *destroy_plane, *temp; + struct device_node *firmware_node; ++ u32 blank = 1; + int ret; + + vc4->firmware_kms = true; +@@ -702,20 +876,26 @@ static int vc4_fkms_bind(struct device * + if (IS_ERR(vc4_crtc->regs)) + return PTR_ERR(vc4_crtc->regs); + +- /* For now, we create just the primary and the legacy cursor +- * planes. We should be able to stack more planes on easily, +- * but to do that we would need to compute the bandwidth +- * requirement of the plane configuration, and reject ones +- * that will take too much. +- */ +- primary_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_PRIMARY); ++ /* Blank the firmware provided framebuffer */ ++ rpi_firmware_property(vc4->firmware, ++ RPI_FIRMWARE_FRAMEBUFFER_BLANK, ++ &blank, sizeof(blank)); ++ ++ primary_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_PRIMARY, 0); + if (IS_ERR(primary_plane)) { + dev_err(dev, "failed to construct primary plane\n"); + ret = PTR_ERR(primary_plane); + goto err; + } + +- cursor_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_CURSOR); ++ overlay_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_OVERLAY, 1); ++ if (IS_ERR(overlay_plane)) { ++ dev_err(dev, "failed to construct overlay plane\n"); ++ ret = PTR_ERR(overlay_plane); ++ goto err; ++ } ++ ++ cursor_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_CURSOR, 2); + if (IS_ERR(cursor_plane)) { + dev_err(dev, "failed to construct cursor plane\n"); + ret = PTR_ERR(cursor_plane); +--- a/drivers/gpu/drm/vc4/vc4_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_kms.c +@@ -435,6 +435,7 @@ int vc4_kms_load(struct drm_device *dev) + dev->mode_config.preferred_depth = 24; + dev->mode_config.async_page_flip = true; + dev->mode_config.allow_fb_modifiers = true; ++ dev->mode_config.normalize_zpos = true; + + drm_modeset_lock_init(&vc4->ctm_state_lock); + +--- /dev/null ++++ b/drivers/gpu/drm/vc4/vc_image_types.h +@@ -0,0 +1,143 @@ ++ ++/* ++ * Copyright (c) 2012, Broadcom Europe Ltd ++ * ++ * Values taken from vc_image_types.h released by Broadcom at ++ * https://github.com/raspberrypi/userland/blob/master/interface/vctypes/vc_image_types.h ++ * ++ * 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. ++ */ ++ ++enum { ++ VC_IMAGE_MIN = 0, //bounds for error checking ++ ++ VC_IMAGE_RGB565 = 1, ++ VC_IMAGE_1BPP, ++ VC_IMAGE_YUV420, ++ VC_IMAGE_48BPP, ++ VC_IMAGE_RGB888, ++ VC_IMAGE_8BPP, ++ /* 4bpp palettised image */ ++ VC_IMAGE_4BPP, ++ /* A separated format of 16 colour/light shorts followed by 16 z ++ * values ++ */ ++ VC_IMAGE_3D32, ++ /* 16 colours followed by 16 z values */ ++ VC_IMAGE_3D32B, ++ /* A separated format of 16 material/colour/light shorts followed by ++ * 16 z values ++ */ ++ VC_IMAGE_3D32MAT, ++ /* 32 bit format containing 18 bits of 6.6.6 RGB, 9 bits per short */ ++ VC_IMAGE_RGB2X9, ++ /* 32-bit format holding 18 bits of 6.6.6 RGB */ ++ VC_IMAGE_RGB666, ++ /* 4bpp palettised image with embedded palette */ ++ VC_IMAGE_PAL4_OBSOLETE, ++ /* 8bpp palettised image with embedded palette */ ++ VC_IMAGE_PAL8_OBSOLETE, ++ /* RGB888 with an alpha byte after each pixel */ ++ VC_IMAGE_RGBA32, ++ /* a line of Y (32-byte padded), a line of U (16-byte padded), and a ++ * line of V (16-byte padded) ++ */ ++ VC_IMAGE_YUV422, ++ /* RGB565 with a transparent patch */ ++ VC_IMAGE_RGBA565, ++ /* Compressed (4444) version of RGBA32 */ ++ VC_IMAGE_RGBA16, ++ /* VCIII codec format */ ++ VC_IMAGE_YUV_UV, ++ /* VCIII T-format RGBA8888 */ ++ VC_IMAGE_TF_RGBA32, ++ /* VCIII T-format RGBx8888 */ ++ VC_IMAGE_TF_RGBX32, ++ /* VCIII T-format float */ ++ VC_IMAGE_TF_FLOAT, ++ /* VCIII T-format RGBA4444 */ ++ VC_IMAGE_TF_RGBA16, ++ /* VCIII T-format RGB5551 */ ++ VC_IMAGE_TF_RGBA5551, ++ /* VCIII T-format RGB565 */ ++ VC_IMAGE_TF_RGB565, ++ /* VCIII T-format 8-bit luma and 8-bit alpha */ ++ VC_IMAGE_TF_YA88, ++ /* VCIII T-format 8 bit generic sample */ ++ VC_IMAGE_TF_BYTE, ++ /* VCIII T-format 8-bit palette */ ++ VC_IMAGE_TF_PAL8, ++ /* VCIII T-format 4-bit palette */ ++ VC_IMAGE_TF_PAL4, ++ /* VCIII T-format Ericsson Texture Compressed */ ++ VC_IMAGE_TF_ETC1, ++ /* RGB888 with R & B swapped */ ++ VC_IMAGE_BGR888, ++ /* RGB888 with R & B swapped, but with no pitch, i.e. no padding after ++ * each row of pixels ++ */ ++ VC_IMAGE_BGR888_NP, ++ /* Bayer image, extra defines which variant is being used */ ++ VC_IMAGE_BAYER, ++ /* General wrapper for codec images e.g. JPEG from camera */ ++ VC_IMAGE_CODEC, ++ /* VCIII codec format */ ++ VC_IMAGE_YUV_UV32, ++ /* VCIII T-format 8-bit luma */ ++ VC_IMAGE_TF_Y8, ++ /* VCIII T-format 8-bit alpha */ ++ VC_IMAGE_TF_A8, ++ /* VCIII T-format 16-bit generic sample */ ++ VC_IMAGE_TF_SHORT, ++ /* VCIII T-format 1bpp black/white */ ++ VC_IMAGE_TF_1BPP, ++ VC_IMAGE_OPENGL, ++ /* VCIII-B0 HVS YUV 4:4:4 interleaved samples */ ++ VC_IMAGE_YUV444I, ++ /* Y, U, & V planes separately (VC_IMAGE_YUV422 has them interleaved on ++ * a per line basis) ++ */ ++ VC_IMAGE_YUV422PLANAR, ++ /* 32bpp with 8bit alpha at MS byte, with R, G, B (LS byte) */ ++ VC_IMAGE_ARGB8888, ++ /* 32bpp with 8bit unused at MS byte, with R, G, B (LS byte) */ ++ VC_IMAGE_XRGB8888, ++ ++ /* interleaved 8 bit samples of Y, U, Y, V (4 flavours) */ ++ VC_IMAGE_YUV422YUYV, ++ VC_IMAGE_YUV422YVYU, ++ VC_IMAGE_YUV422UYVY, ++ VC_IMAGE_YUV422VYUY, ++ ++ /* 32bpp like RGBA32 but with unused alpha */ ++ VC_IMAGE_RGBX32, ++ /* 32bpp, corresponding to RGBA with unused alpha */ ++ VC_IMAGE_RGBX8888, ++ /* 32bpp, corresponding to BGRA with unused alpha */ ++ VC_IMAGE_BGRX8888, ++ ++ /* Y as a plane, then UV byte interleaved in plane with with same pitch, ++ * half height ++ */ ++ VC_IMAGE_YUV420SP, ++ ++ /* Y, U, & V planes separately 4:4:4 */ ++ VC_IMAGE_YUV444PLANAR, ++ ++ /* T-format 8-bit U - same as TF_Y8 buf from U plane */ ++ VC_IMAGE_TF_U8, ++ /* T-format 8-bit U - same as TF_Y8 buf from V plane */ ++ VC_IMAGE_TF_V8, ++ ++ /* YUV4:2:0 planar, 16bit values */ ++ VC_IMAGE_YUV420_16, ++ /* YUV4:2:0 codec format, 16bit values */ ++ VC_IMAGE_YUV_UV_16, ++ /* YUV4:2:0 with U,V in side-by-side format */ ++ VC_IMAGE_YUV420_S, ++ ++ VC_IMAGE_MAX, /* bounds for error checking */ ++ VC_IMAGE_FORCE_ENUM_16BIT = 0xffff, ++}; +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -148,6 +148,8 @@ enum rpi_firmware_property_tag { + + RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, + ++ RPI_FIRMWARE_SET_PLANE = 0x00048015, ++ + RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, + RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0595-drm-vc4-Make-sure-that-vblank-waits-work-without-v3d.patch b/target/linux/brcm2708/patches-4.19/950-0595-drm-vc4-Make-sure-that-vblank-waits-work-without-v3d.patch deleted file mode 100644 index 1663787f99..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0595-drm-vc4-Make-sure-that-vblank-waits-work-without-v3d.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 53fb5e2a9834ead04a432c266831e5fd77f96983 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 29 Mar 2019 12:04:36 -0700 -Subject: [PATCH 595/703] drm/vc4: Make sure that vblank waits work without v3d - loaded. - -This flag exists to protect legacy drivers, but when vc4's v3d doesn't -probe, it doesn't get set up by vc4_v3d.c's call of drm_irq_install. -This resulted in applications running as fast as possible, and laggy -performance from compton as it had to wait for the latest rendering by -the application for its presentation. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_kms.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -422,6 +422,7 @@ int vc4_kms_load(struct drm_device *dev) - /* Set support for vblank irq fast disable, before drm_vblank_init() */ - dev->vblank_disable_immediate = true; - -+ dev->irq_enabled = true; - ret = drm_vblank_init(dev, dev->mode_config.num_crtc); - if (ret < 0) { - dev_err(dev->dev, "failed to initialize vblank\n"); diff --git a/target/linux/brcm2708/patches-4.19/950-0596-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch b/target/linux/brcm2708/patches-4.19/950-0596-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch deleted file mode 100644 index c33d4f2287..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0596-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 3d8b2b7adbec2ea7bf9012300c5e381cb60c270e Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 18 Mar 2019 16:38:32 -0700 -Subject: [PATCH 596/703] drm/vc4: Expose the format modifiers for firmware - kms. - -This should technically not expose VC4_T_TILED on pi4. However, if we -don't expose anything, then userspace will assume that display can -handle whatever modifiers 3d can do (UIF on 2711). By exposing a -list, that will get intersected with what 3D can do so that we get T -tiling for display on 2710 and linear on 2711. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 33 +++++++++++++++++++++++++- - 1 file changed, 32 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -281,6 +281,27 @@ static void vc4_plane_destroy(struct drm - drm_plane_cleanup(plane); - } - -+static bool vc4_fkms_format_mod_supported(struct drm_plane *plane, -+ uint32_t format, -+ uint64_t modifier) -+{ -+ /* Support T_TILING for RGB formats only. */ -+ switch (format) { -+ case DRM_FORMAT_XRGB8888: -+ case DRM_FORMAT_ARGB8888: -+ switch (modifier) { -+ case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: -+ case DRM_FORMAT_MOD_LINEAR: -+ case DRM_FORMAT_MOD_BROADCOM_UIF: -+ return true; -+ default: -+ return false; -+ } -+ default: -+ return false; -+ } -+} -+ - static const struct drm_plane_funcs vc4_plane_funcs = { - .update_plane = drm_atomic_helper_update_plane, - .disable_plane = drm_atomic_helper_disable_plane, -@@ -289,6 +310,7 @@ static const struct drm_plane_funcs vc4_ - .reset = drm_atomic_helper_plane_reset, - .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, -+ .format_mod_supported = vc4_fkms_format_mod_supported, - }; - - static const struct drm_plane_helper_funcs vc4_primary_plane_helper_funcs = { -@@ -316,6 +338,14 @@ static struct drm_plane *vc4_fkms_plane_ - u32 argb8888 = DRM_FORMAT_ARGB8888; - int ret = 0; - bool primary = (type == DRM_PLANE_TYPE_PRIMARY); -+ static const uint64_t modifiers[] = { -+ DRM_FORMAT_MOD_LINEAR, -+ /* VC4_T_TILED should come after linear, because we -+ * would prefer to scan out linear (less bus traffic). -+ */ -+ DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED, -+ DRM_FORMAT_MOD_INVALID, -+ }; - - vc4_plane = devm_kzalloc(dev->dev, sizeof(*vc4_plane), - GFP_KERNEL); -@@ -327,7 +357,8 @@ static struct drm_plane *vc4_fkms_plane_ - plane = &vc4_plane->base; - ret = drm_universal_plane_init(dev, plane, 0xff, - &vc4_plane_funcs, -- primary ? &xrgb8888 : &argb8888, 1, NULL, -+ primary ? &xrgb8888 : &argb8888, 1, -+ modifiers, - type, primary ? "primary" : "cursor"); - - if (type == DRM_PLANE_TYPE_PRIMARY) { diff --git a/target/linux/brcm2708/patches-4.19/950-0596-drm-vc4-Increase-max-screen-size-to-4096x4096.patch b/target/linux/brcm2708/patches-4.19/950-0596-drm-vc4-Increase-max-screen-size-to-4096x4096.patch new file mode 100644 index 0000000000..98a3a87010 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0596-drm-vc4-Increase-max-screen-size-to-4096x4096.patch @@ -0,0 +1,26 @@ +From fe4fbbfe9e5cba10f41c116441fea1dc30c28291 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 3 Apr 2019 15:20:05 +0100 +Subject: [PATCH 596/725] drm: vc4: Increase max screen size to 4096x4096. + +We now should support 4k screens, therefore this limit needs to +be increased. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_kms.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_kms.c +@@ -429,8 +429,8 @@ int vc4_kms_load(struct drm_device *dev) + return ret; + } + +- dev->mode_config.max_width = 2048; +- dev->mode_config.max_height = 2048; ++ dev->mode_config.max_width = 4096; ++ dev->mode_config.max_height = 4096; + dev->mode_config.funcs = &vc4_mode_funcs; + dev->mode_config.preferred_depth = 24; + dev->mode_config.async_page_flip = true; diff --git a/target/linux/brcm2708/patches-4.19/950-0597-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch b/target/linux/brcm2708/patches-4.19/950-0597-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch new file mode 100644 index 0000000000..aad29298da --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0597-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch @@ -0,0 +1,280 @@ +From c933118b00cb40f4c9fa8f6470ef9a33ea046c4d Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 3 Apr 2019 17:15:45 +0100 +Subject: [PATCH 597/725] drm: vc4: Add support for multiple displays to fkms + +There is a slightly nasty hack in that all crtcs share the +same SMI interrupt from the firmware. This seems to currently +work well enough, but ought to be fixed at a later date. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 160 +++++++++++++++++-------- + 1 file changed, 113 insertions(+), 47 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -29,6 +29,8 @@ + #include "vc_image_types.h" + #include + ++#define PLANES_PER_CRTC 3 ++ + struct set_plane { + u8 display; + u8 plane_id; +@@ -175,6 +177,7 @@ struct vc4_crtc { + struct drm_pending_vblank_event *event; + u32 overscan[4]; + bool vblank_enabled; ++ u32 display_number; + }; + + static inline struct vc4_crtc *to_vc4_crtc(struct drm_crtc *crtc) +@@ -480,6 +483,7 @@ static const struct drm_plane_helper_fun + + static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev, + enum drm_plane_type type, ++ u8 display_num, + u8 plane_id) + { + struct drm_plane *plane = NULL; +@@ -543,7 +547,7 @@ static struct drm_plane *vc4_fkms_plane_ + vc4_plane->mb.tag.tag = RPI_FIRMWARE_SET_PLANE; + vc4_plane->mb.tag.buf_size = sizeof(struct set_plane); + vc4_plane->mb.tag.req_resp_size = 0; +- vc4_plane->mb.plane.display = 0; ++ vc4_plane->mb.plane.display = display_num; + vc4_plane->mb.plane.plane_id = plane_id; + vc4_plane->mb.plane.layer = default_zpos ? default_zpos : -127; + +@@ -630,16 +634,20 @@ static void vc4_crtc_handle_page_flip(st + + static irqreturn_t vc4_crtc_irq_handler(int irq, void *data) + { +- struct vc4_crtc *vc4_crtc = data; +- u32 stat = readl(vc4_crtc->regs + SMICS); ++ struct vc4_crtc **crtc_list = data; ++ int i; ++ u32 stat = readl(crtc_list[0]->regs + SMICS); + irqreturn_t ret = IRQ_NONE; + + if (stat & SMICS_INTERRUPTS) { +- writel(0, vc4_crtc->regs + SMICS); +- if (vc4_crtc->vblank_enabled) +- drm_crtc_handle_vblank(&vc4_crtc->base); +- vc4_crtc_handle_page_flip(vc4_crtc); +- ret = IRQ_HANDLED; ++ writel(0, crtc_list[0]->regs + SMICS); ++ ++ for (i = 0; crtc_list[i]; i++) { ++ if (crtc_list[i]->vblank_enabled) ++ drm_crtc_handle_vblank(&crtc_list[i]->base); ++ vc4_crtc_handle_page_flip(crtc_list[i]); ++ ret = IRQ_HANDLED; ++ } + } + + return ret; +@@ -836,66 +844,55 @@ static const struct drm_encoder_helper_f + .disable = vc4_fkms_encoder_disable, + }; + +-static int vc4_fkms_bind(struct device *dev, struct device *master, void *data) ++static int vc4_fkms_create_screen(struct device *dev, struct drm_device *drm, ++ int display_idx, int display_ref, ++ struct vc4_crtc **ret_crtc) + { +- 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_crtc *vc4_crtc; + struct vc4_fkms_encoder *vc4_encoder; + struct drm_crtc *crtc; + struct drm_plane *primary_plane, *overlay_plane, *cursor_plane; + struct drm_plane *destroy_plane, *temp; +- struct device_node *firmware_node; + u32 blank = 1; + int ret; + +- vc4->firmware_kms = true; +- +- /* firmware kms doesn't have precise a scanoutpos implementation, so +- * we can't do the precise vblank timestamp mode. +- */ +- drm->driver->get_scanout_position = NULL; +- drm->driver->get_vblank_timestamp = NULL; +- + vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL); + if (!vc4_crtc) + return -ENOMEM; + crtc = &vc4_crtc->base; + +- firmware_node = of_parse_phandle(dev->of_node, "brcm,firmware", 0); +- vc4->firmware = rpi_firmware_get(firmware_node); +- if (!vc4->firmware) { +- DRM_DEBUG("Failed to get Raspberry Pi firmware reference.\n"); +- return -EPROBE_DEFER; +- } +- of_node_put(firmware_node); +- +- /* Map the SMI interrupt reg */ +- vc4_crtc->regs = vc4_ioremap_regs(pdev, 0); +- if (IS_ERR(vc4_crtc->regs)) +- return PTR_ERR(vc4_crtc->regs); ++ vc4_crtc->display_number = display_ref; + + /* Blank the firmware provided framebuffer */ + rpi_firmware_property(vc4->firmware, + RPI_FIRMWARE_FRAMEBUFFER_BLANK, + &blank, sizeof(blank)); + +- primary_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_PRIMARY, 0); ++ primary_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_PRIMARY, ++ display_ref, ++ 0 + (display_idx * PLANES_PER_CRTC) ++ ); + if (IS_ERR(primary_plane)) { + dev_err(dev, "failed to construct primary plane\n"); + ret = PTR_ERR(primary_plane); + goto err; + } + +- overlay_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_OVERLAY, 1); ++ overlay_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_OVERLAY, ++ display_ref, ++ 1 + (display_idx * PLANES_PER_CRTC) ++ ); + if (IS_ERR(overlay_plane)) { + dev_err(dev, "failed to construct overlay plane\n"); + ret = PTR_ERR(overlay_plane); + goto err; + } + +- cursor_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_CURSOR, 2); ++ cursor_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_CURSOR, ++ display_ref, ++ 2 + (display_idx * PLANES_PER_CRTC) ++ ); + if (IS_ERR(cursor_plane)) { + dev_err(dev, "failed to construct cursor plane\n"); + ret = PTR_ERR(cursor_plane); +@@ -922,13 +919,6 @@ static int vc4_fkms_bind(struct device * + goto err_destroy_encoder; + } + +- writel(0, vc4_crtc->regs + SMICS); +- ret = devm_request_irq(dev, platform_get_irq(pdev, 0), +- vc4_crtc_irq_handler, 0, "vc4 firmware kms", +- vc4_crtc); +- if (ret) +- goto err_destroy_connector; +- + ret = rpi_firmware_property(vc4->firmware, + RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN, + &vc4_crtc->overscan, +@@ -938,7 +928,7 @@ static int vc4_fkms_bind(struct device * + memset(&vc4_crtc->overscan, 0, sizeof(vc4_crtc->overscan)); + } + +- platform_set_drvdata(pdev, vc4_crtc); ++ *ret_crtc = vc4_crtc; + + return 0; + +@@ -955,15 +945,91 @@ err: + return ret; + } + ++static int vc4_fkms_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 device_node *firmware_node; ++ struct vc4_crtc **crtc_list; ++ u32 num_displays, display_num; ++ int ret; ++ const u32 display_num_lookup[] = {2, 7, 1}; ++ ++ vc4->firmware_kms = true; ++ ++ /* firmware kms doesn't have precise a scanoutpos implementation, so ++ * we can't do the precise vblank timestamp mode. ++ */ ++ drm->driver->get_scanout_position = NULL; ++ drm->driver->get_vblank_timestamp = NULL; ++ ++ firmware_node = of_parse_phandle(dev->of_node, "brcm,firmware", 0); ++ vc4->firmware = rpi_firmware_get(firmware_node); ++ if (!vc4->firmware) { ++ DRM_DEBUG("Failed to get Raspberry Pi firmware reference.\n"); ++ return -EPROBE_DEFER; ++ } ++ of_node_put(firmware_node); ++ ++ ret = rpi_firmware_property(vc4->firmware, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS, ++ &num_displays, sizeof(u32)); ++ ++ /* If we fail to get the number of displays, or it returns 0, then ++ * assume old firmware that doesn't have the mailbox call, so just ++ * set one display ++ */ ++ if (ret || num_displays == 0) { ++ num_displays = 1; ++ DRM_WARN("Unable to determine number of displays's. Assuming 1\n"); ++ ret = 0; ++ } ++ ++ /* Allocate a list, with space for a NULL on the end */ ++ crtc_list = devm_kzalloc(dev, sizeof(crtc_list) * (num_displays + 1), ++ GFP_KERNEL); ++ if (!crtc_list) ++ return -ENOMEM; ++ ++ for (display_num = 0; display_num < num_displays; display_num++) { ++ ret = vc4_fkms_create_screen(dev, drm, display_num, ++ display_num_lookup[display_num], ++ &crtc_list[display_num]); ++ if (ret) ++ DRM_ERROR("Oh dear, failed to create display %u\n", ++ display_num); ++ } ++ ++ /* Map the SMI interrupt reg */ ++ crtc_list[0]->regs = vc4_ioremap_regs(pdev, 0); ++ if (IS_ERR(crtc_list[0]->regs)) ++ DRM_ERROR("Oh dear, failed to map registers\n"); ++ ++ writel(0, crtc_list[0]->regs + SMICS); ++ ret = devm_request_irq(dev, platform_get_irq(pdev, 0), ++ vc4_crtc_irq_handler, 0, "vc4 firmware kms", ++ crtc_list); ++ if (ret) ++ DRM_ERROR("Oh dear, failed to register IRQ\n"); ++ ++ platform_set_drvdata(pdev, crtc_list); ++ ++ return 0; ++} ++ + static void vc4_fkms_unbind(struct device *dev, struct device *master, + void *data) + { + struct platform_device *pdev = to_platform_device(dev); +- struct vc4_crtc *vc4_crtc = dev_get_drvdata(dev); ++ struct vc4_crtc **crtc_list = dev_get_drvdata(dev); ++ int i; + +- vc4_fkms_connector_destroy(vc4_crtc->connector); +- vc4_fkms_encoder_destroy(vc4_crtc->encoder); +- drm_crtc_cleanup(&vc4_crtc->base); ++ for (i = 0; crtc_list[i]; i++) { ++ vc4_fkms_connector_destroy(crtc_list[i]->connector); ++ vc4_fkms_encoder_destroy(crtc_list[i]->encoder); ++ drm_crtc_cleanup(&crtc_list[i]->base); ++ } + + platform_set_drvdata(pdev, NULL); + } diff --git a/target/linux/brcm2708/patches-4.19/950-0597-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch b/target/linux/brcm2708/patches-4.19/950-0597-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch deleted file mode 100644 index a2c66828fc..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0597-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 3b341544a3dae555d48ece948c44b3b434543077 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Tue, 2 Apr 2019 13:29:00 -0700 -Subject: [PATCH 597/703] drm/vc4: Fix vblank timestamping for firmwarekms. - -The core doesn't expect a false return from the scanoutpos function in -normal usage, so we were doing the precise vblank timestamping path -and thus "immediate" vblank disables (even though firmwarekms can't -actually disable vblanks interrupts, sigh), and the kernel would get -confused when getting timestamp info when also turning vblanks back -on. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/vc4/vc4_crtc.c | 3 --- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 6 ++++++ - 2 files changed, 6 insertions(+), 3 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_crtc.c -+++ b/drivers/gpu/drm/vc4/vc4_crtc.c -@@ -133,9 +133,6 @@ bool vc4_crtc_get_scanoutpos(struct drm_ - int vblank_lines; - bool ret = false; - -- if (vc4->firmware_kms) -- return 0; -- - /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ - - /* Get optional system timestamp before query. */ ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -673,6 +673,12 @@ static int vc4_fkms_bind(struct device * - - vc4->firmware_kms = true; - -+ /* firmware kms doesn't have precise a scanoutpos implementation, so -+ * we can't do the precise vblank timestamp mode. -+ */ -+ drm->driver->get_scanout_position = NULL; -+ drm->driver->get_vblank_timestamp = NULL; -+ - vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL); - if (!vc4_crtc) - return -ENOMEM; diff --git a/target/linux/brcm2708/patches-4.19/950-0598-drm-vc4-Fix-build-warning.patch b/target/linux/brcm2708/patches-4.19/950-0598-drm-vc4-Fix-build-warning.patch new file mode 100644 index 0000000000..d786d72264 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0598-drm-vc4-Fix-build-warning.patch @@ -0,0 +1,21 @@ +From 407f6a2ad0168c3385d9d015aac2af70532ecd4a Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 5 Apr 2019 17:21:56 +0100 +Subject: [PATCH 598/725] drm: vc4: Fix build warning + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -932,8 +932,6 @@ static int vc4_fkms_create_screen(struct + + return 0; + +-err_destroy_connector: +- vc4_fkms_connector_destroy(vc4_crtc->connector); + err_destroy_encoder: + vc4_fkms_encoder_destroy(vc4_crtc->encoder); + list_for_each_entry_safe(destroy_plane, temp, diff --git a/target/linux/brcm2708/patches-4.19/950-0598-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch b/target/linux/brcm2708/patches-4.19/950-0598-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch deleted file mode 100644 index 8d295de75d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0598-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch +++ /dev/null @@ -1,216 +0,0 @@ -From e4aadf5daae0b3f544e5ade7ee27a5e0f83af1b0 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 26 Mar 2019 14:43:06 +0000 -Subject: [PATCH 598/703] gpu: vc4-fkms: Switch to the newer mailbox frame - buffer API. - -The old mailbox FB API was ideally deprecated but still used by -the FKMS driver. -Update to the newer API. - -NB This needs current firmware that accepts ARM allocated buffers -through the newer API. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 109 +++++++++++---------- - include/soc/bcm2835/raspberrypi-firmware.h | 10 ++ - 2 files changed, 67 insertions(+), 52 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -28,6 +28,25 @@ - #include "vc4_regs.h" - #include - -+struct fb_alloc_tags { -+ struct rpi_firmware_property_tag_header tag1; -+ u32 xres, yres; -+ struct rpi_firmware_property_tag_header tag2; -+ u32 xres_virtual, yres_virtual; -+ struct rpi_firmware_property_tag_header tag3; -+ u32 bpp; -+ struct rpi_firmware_property_tag_header tag4; -+ u32 xoffset, yoffset; -+ struct rpi_firmware_property_tag_header tag5; -+ u32 base, screen_size; -+ struct rpi_firmware_property_tag_header tag6; -+ u32 pitch; -+ struct rpi_firmware_property_tag_header tag7; -+ u32 alpha_mode; -+ struct rpi_firmware_property_tag_header tag8; -+ u32 layer; -+}; -+ - /* The firmware delivers a vblank interrupt to us through the SMI - * hardware, which has only this one register. - */ -@@ -121,45 +140,39 @@ static void vc4_primary_plane_atomic_upd - struct drm_plane_state *old_state) - { - struct vc4_dev *vc4 = to_vc4_dev(plane->dev); -- struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane); - struct drm_plane_state *state = plane->state; - struct drm_framebuffer *fb = state->fb; - struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); -- volatile struct fbinfo_s *fbinfo = vc4_plane->fbinfo; -+ u32 format = fb->format->format; -+ struct fb_alloc_tags fbinfo = { -+ .tag1 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT, -+ 8, 0, }, -+ .xres = state->crtc_w, -+ .yres = state->crtc_h, -+ .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT, -+ 8, 0, }, -+ .xres_virtual = state->crtc_w, -+ .yres_virtual = state->crtc_h, -+ .tag3 = { RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH, 4, 0 }, -+ .bpp = 32, -+ .tag4 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET, 8, 0 }, -+ .xoffset = 0, -+ .yoffset = 0, -+ .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 }, -+ .base = bo->paddr + fb->offsets[0], -+ .screen_size = state->crtc_w * state->crtc_h * 4, -+ .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH, 4, 0 }, -+ .pitch = fb->pitches[0], -+ .tag7 = { RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE, 4, 0 }, -+ .alpha_mode = format == DRM_FORMAT_ARGB8888 ? 0 : 2, -+ .tag8 = { RPI_FIRMWARE_FRAMEBUFFER_SET_LAYER, 4, 0 }, -+ .layer = -127, -+ }; - u32 bpp = 32; - int ret; - -- fbinfo->xres = state->crtc_w; -- fbinfo->yres = state->crtc_h; -- fbinfo->xres_virtual = state->crtc_w; -- fbinfo->yres_virtual = state->crtc_h; -- fbinfo->bpp = bpp; -- fbinfo->xoffset = state->crtc_x; -- fbinfo->yoffset = state->crtc_y; -- fbinfo->base = bo->paddr + fb->offsets[0]; -- fbinfo->pitch = fb->pitches[0]; -- - if (fb->modifier == DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED) -- fbinfo->bpp |= BIT(31); -- -- /* A bug in the firmware makes it so that if the fb->base is -- * set to nonzero, the configured pitch gets overwritten with -- * the previous pitch. So, to get the configured pitch -- * recomputed, we have to make it allocate itself a new buffer -- * in VC memory, first. -- */ -- if (vc4_plane->pitch != fb->pitches[0]) { -- u32 saved_base = fbinfo->base; -- fbinfo->base = 0; -- -- ret = rpi_firmware_transaction(vc4->firmware, -- RPI_FIRMWARE_CHAN_FB, -- vc4_plane->fbinfo_bus_addr); -- fbinfo->base = saved_base; -- -- vc4_plane->pitch = fbinfo->pitch; -- WARN_ON_ONCE(vc4_plane->pitch != fb->pitches[0]); -- } -+ fbinfo.bpp |= BIT(31); - - DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary update %dx%d@%d +%d,%d 0x%pad/%d\n", - plane->base.id, plane->name, -@@ -168,14 +181,13 @@ static void vc4_primary_plane_atomic_upd - bpp, - state->crtc_x, - state->crtc_y, -- &fbinfo->base, -+ &fbinfo.base, - fb->pitches[0]); - -- ret = rpi_firmware_transaction(vc4->firmware, -- RPI_FIRMWARE_CHAN_FB, -- vc4_plane->fbinfo_bus_addr); -- WARN_ON_ONCE(fbinfo->pitch != fb->pitches[0]); -- WARN_ON_ONCE(fbinfo->base != bo->paddr + fb->offsets[0]); -+ ret = rpi_firmware_property_list(vc4->firmware, &fbinfo, -+ sizeof(fbinfo)); -+ WARN_ON_ONCE(fbinfo.pitch != fb->pitches[0]); -+ WARN_ON_ONCE(fbinfo.base != bo->paddr + fb->offsets[0]); - - /* If the CRTC is on (or going to be on) and we're enabled, - * then unblank. Otherwise, stay blank until CRTC enable. -@@ -332,10 +344,10 @@ static const struct drm_plane_helper_fun - static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev, - enum drm_plane_type type) - { -+ /* Primary and cursor planes only */ - struct drm_plane *plane = NULL; - struct vc4_fkms_plane *vc4_plane; -- u32 xrgb8888 = DRM_FORMAT_XRGB8888; -- u32 argb8888 = DRM_FORMAT_ARGB8888; -+ u32 formats[] = {DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888}; - int ret = 0; - bool primary = (type == DRM_PLANE_TYPE_PRIMARY); - static const uint64_t modifiers[] = { -@@ -357,22 +369,15 @@ static struct drm_plane *vc4_fkms_plane_ - plane = &vc4_plane->base; - ret = drm_universal_plane_init(dev, plane, 0xff, - &vc4_plane_funcs, -- primary ? &xrgb8888 : &argb8888, 1, -- modifiers, -+ formats, primary ? 2 : 1, modifiers, - type, primary ? "primary" : "cursor"); - -- if (type == DRM_PLANE_TYPE_PRIMARY) { -- vc4_plane->fbinfo = -- dma_alloc_coherent(dev->dev, -- sizeof(*vc4_plane->fbinfo), -- &vc4_plane->fbinfo_bus_addr, -- GFP_KERNEL); -- memset(vc4_plane->fbinfo, 0, sizeof(*vc4_plane->fbinfo)); -- -+ if (type == DRM_PLANE_TYPE_PRIMARY) - drm_plane_helper_add(plane, &vc4_primary_plane_helper_funcs); -- } else { -+ else - drm_plane_helper_add(plane, &vc4_cursor_plane_helper_funcs); -- } -+ -+ drm_plane_create_alpha_property(plane); - - return plane; - fail: ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -111,9 +111,15 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009, - RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a, - RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_LAYER = 0x0004000c, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_TRANSFORM = 0x0004000d, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_VSYNC = 0x0004000e, - RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f, - RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF = 0x00040010, - RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM = 0x00048013, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS = 0x00040013, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_SETTINGS = 0x00040014, - RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, - RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, - RPI_FIRMWARE_FRAMEBUFFER_TEST_DEPTH = 0x00044005, -@@ -122,6 +128,8 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009, - RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a, - RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_LAYER = 0x0004400c, -+ RPI_FIRMWARE_FRAMEBUFFER_TEST_TRANSFORM = 0x0004400d, - RPI_FIRMWARE_FRAMEBUFFER_TEST_VSYNC = 0x0004400e, - RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, - RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, -@@ -134,6 +142,8 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF = 0x0004801f, - RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF = 0x00048020, - RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_LAYER = 0x0004800c, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_TRANSFORM = 0x0004800d, - RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f, - - RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, diff --git a/target/linux/brcm2708/patches-4.19/950-0599-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch b/target/linux/brcm2708/patches-4.19/950-0599-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch deleted file mode 100644 index e80a25cf96..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0599-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch +++ /dev/null @@ -1,853 +0,0 @@ -From 36b8b81762806952c524da6539b76771266d79c5 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 27 Mar 2019 17:45:01 +0000 -Subject: [PATCH 599/703] drm: vc4: Add an overlay plane to vc4-firmware-kms - -This uses a new API that is exposed via the mailbox service -to stick an element straight on the screen using DispmanX. - -The primary and cursor planes have also been switched to using -the new plane API, and it supports layering based on the DRM -zpos parameter. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 518 ++++++++++++++------- - drivers/gpu/drm/vc4/vc4_kms.c | 1 + - drivers/gpu/drm/vc4/vc_image_types.h | 143 ++++++ - include/soc/bcm2835/raspberrypi-firmware.h | 2 + - 4 files changed, 495 insertions(+), 169 deletions(-) - create mode 100644 drivers/gpu/drm/vc4/vc_image_types.h - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -26,8 +26,46 @@ - #include "linux/of_device.h" - #include "vc4_drv.h" - #include "vc4_regs.h" -+#include "vc_image_types.h" - #include - -+struct set_plane { -+ u8 display; -+ u8 plane_id; -+ u8 vc_image_type; -+ s8 layer; -+ -+ u16 width; -+ u16 height; -+ -+ u16 pitch; -+ u16 vpitch; -+ -+ u32 src_x; /* 16p16 */ -+ u32 src_y; /* 16p16 */ -+ -+ u32 src_w; /* 16p16 */ -+ u32 src_h; /* 16p16 */ -+ -+ s16 dst_x; -+ s16 dst_y; -+ -+ u16 dst_w; -+ u16 dst_h; -+ -+ u8 alpha; -+ u8 num_planes; -+ u8 is_vu; -+ u8 padding; -+ -+ u32 planes[4]; /* DMA address of each plane */ -+}; -+ -+struct mailbox_set_plane { -+ struct rpi_firmware_property_tag_header tag; -+ struct set_plane plane; -+}; -+ - struct fb_alloc_tags { - struct rpi_firmware_property_tag_header tag1; - u32 xres, yres; -@@ -47,6 +85,79 @@ struct fb_alloc_tags { - u32 layer; - }; - -+static const struct vc_image_format { -+ u32 drm; /* DRM_FORMAT_* */ -+ u32 vc_image; /* VC_IMAGE_* */ -+ u32 is_vu; -+} vc_image_formats[] = { -+ { -+ .drm = DRM_FORMAT_XRGB8888, -+ .vc_image = VC_IMAGE_XRGB8888, -+ }, -+ { -+ .drm = DRM_FORMAT_ARGB8888, -+ .vc_image = VC_IMAGE_ARGB8888, -+ }, -+/* -+ * FIXME: Need to resolve which DRM format goes to which vc_image format -+ * for the remaining RGBA and RGBX formats. -+ * { -+ * .drm = DRM_FORMAT_ABGR8888, -+ * .vc_image = VC_IMAGE_RGBA8888, -+ * }, -+ * { -+ * .drm = DRM_FORMAT_XBGR8888, -+ * .vc_image = VC_IMAGE_RGBA8888, -+ * }, -+ */ -+ { -+ .drm = DRM_FORMAT_RGB565, -+ .vc_image = VC_IMAGE_RGB565, -+ }, -+ { -+ .drm = DRM_FORMAT_RGB888, -+ .vc_image = VC_IMAGE_BGR888, -+ }, -+ { -+ .drm = DRM_FORMAT_BGR888, -+ .vc_image = VC_IMAGE_RGB888, -+ }, -+ { -+ .drm = DRM_FORMAT_YUV422, -+ .vc_image = VC_IMAGE_YUV422PLANAR, -+ }, -+ { -+ .drm = DRM_FORMAT_YUV420, -+ .vc_image = VC_IMAGE_YUV420, -+ }, -+ { -+ .drm = DRM_FORMAT_YVU420, -+ .vc_image = VC_IMAGE_YUV420, -+ .is_vu = 1, -+ }, -+ { -+ .drm = DRM_FORMAT_NV12, -+ .vc_image = VC_IMAGE_YUV420SP, -+ }, -+ { -+ .drm = DRM_FORMAT_NV21, -+ .vc_image = VC_IMAGE_YUV420SP, -+ .is_vu = 1, -+ }, -+}; -+ -+static const struct vc_image_format *vc4_get_vc_image_fmt(u32 drm_format) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < ARRAY_SIZE(vc_image_formats); i++) { -+ if (vc_image_formats[i].drm == drm_format) -+ return &vc_image_formats[i]; -+ } -+ -+ return NULL; -+} -+ - /* The firmware delivers a vblank interrupt to us through the SMI - * hardware, which has only this one register. - */ -@@ -113,6 +224,7 @@ struct vc4_fkms_plane { - struct fbinfo_s *fbinfo; - dma_addr_t fbinfo_bus_addr; - u32 pitch; -+ struct mailbox_set_plane mb; - }; - - static inline struct vc4_fkms_plane *to_vc4_fkms_plane(struct drm_plane *plane) -@@ -120,165 +232,183 @@ static inline struct vc4_fkms_plane *to_ - return (struct vc4_fkms_plane *)plane; - } - --/* Turns the display on/off. */ --static int vc4_plane_set_primary_blank(struct drm_plane *plane, bool blank) -+static int vc4_plane_set_blank(struct drm_plane *plane, bool blank) - { - struct vc4_dev *vc4 = to_vc4_dev(plane->dev); -+ struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane); -+ struct mailbox_set_plane blank_mb = { -+ .tag = { RPI_FIRMWARE_SET_PLANE, sizeof(struct set_plane), 0 }, -+ .plane = { -+ .display = vc4_plane->mb.plane.display, -+ .plane_id = vc4_plane->mb.plane.plane_id, -+ } -+ }; -+ int ret; - -- u32 packet = blank; -- -- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary plane %s", -+ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] overlay plane %s", - plane->base.id, plane->name, - blank ? "blank" : "unblank"); - -- return rpi_firmware_property(vc4->firmware, -- RPI_FIRMWARE_FRAMEBUFFER_BLANK, -- &packet, sizeof(packet)); -+ if (blank) -+ ret = rpi_firmware_property_list(vc4->firmware, &blank_mb, -+ sizeof(blank_mb)); -+ else -+ ret = rpi_firmware_property_list(vc4->firmware, &vc4_plane->mb, -+ sizeof(vc4_plane->mb)); -+ -+ WARN_ONCE(ret, "%s: firmware call failed. Please update your firmware", -+ __func__); -+ return ret; - } - --static void vc4_primary_plane_atomic_update(struct drm_plane *plane, -- struct drm_plane_state *old_state) -+static void vc4_plane_atomic_update(struct drm_plane *plane, -+ struct drm_plane_state *old_state) - { -- struct vc4_dev *vc4 = to_vc4_dev(plane->dev); - struct drm_plane_state *state = plane->state; - struct drm_framebuffer *fb = state->fb; - struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); -- u32 format = fb->format->format; -- struct fb_alloc_tags fbinfo = { -- .tag1 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT, -- 8, 0, }, -- .xres = state->crtc_w, -- .yres = state->crtc_h, -- .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT, -- 8, 0, }, -- .xres_virtual = state->crtc_w, -- .yres_virtual = state->crtc_h, -- .tag3 = { RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH, 4, 0 }, -- .bpp = 32, -- .tag4 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET, 8, 0 }, -- .xoffset = 0, -- .yoffset = 0, -- .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 }, -- .base = bo->paddr + fb->offsets[0], -- .screen_size = state->crtc_w * state->crtc_h * 4, -- .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH, 4, 0 }, -- .pitch = fb->pitches[0], -- .tag7 = { RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE, 4, 0 }, -- .alpha_mode = format == DRM_FORMAT_ARGB8888 ? 0 : 2, -- .tag8 = { RPI_FIRMWARE_FRAMEBUFFER_SET_LAYER, 4, 0 }, -- .layer = -127, -- }; -- u32 bpp = 32; -- int ret; -+ const struct drm_format_info *drm_fmt = fb->format; -+ const struct vc_image_format *vc_fmt = -+ vc4_get_vc_image_fmt(drm_fmt->format); -+ struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane); -+ struct mailbox_set_plane *mb = &vc4_plane->mb; -+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(state->crtc); -+ int num_planes = fb->format->num_planes; -+ struct drm_display_mode *mode = &state->crtc->mode; - -- if (fb->modifier == DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED) -- fbinfo.bpp |= BIT(31); -+ mb->plane.vc_image_type = vc_fmt->vc_image; -+ mb->plane.width = fb->width; -+ mb->plane.height = fb->height; -+ mb->plane.pitch = fb->pitches[0]; -+ mb->plane.src_w = state->src_w; -+ mb->plane.src_h = state->src_h; -+ mb->plane.src_x = state->src_x; -+ mb->plane.src_y = state->src_y; -+ mb->plane.dst_w = state->crtc_w; -+ mb->plane.dst_h = state->crtc_h; -+ mb->plane.dst_x = state->crtc_x; -+ mb->plane.dst_y = state->crtc_y; -+ mb->plane.alpha = state->alpha >> 8; -+ mb->plane.layer = state->normalized_zpos ? -+ state->normalized_zpos : -127; -+ mb->plane.num_planes = num_planes; -+ mb->plane.is_vu = vc_fmt->is_vu; -+ mb->plane.planes[0] = bo->paddr + fb->offsets[0]; - -- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary update %dx%d@%d +%d,%d 0x%pad/%d\n", -+ /* FIXME: If the dest rect goes off screen then clip the src rect so we -+ * don't have off-screen pixels. -+ */ -+ if (plane->type == DRM_PLANE_TYPE_CURSOR) { -+ /* There is no scaling on the cursor plane, therefore the calcs -+ * to alter the source crop as the cursor goes off the screen -+ * are simple. -+ */ -+ if (mb->plane.dst_x + mb->plane.dst_w > mode->hdisplay) { -+ mb->plane.dst_w = mode->hdisplay - mb->plane.dst_x; -+ mb->plane.src_w = (mode->hdisplay - mb->plane.dst_x) -+ << 16; -+ } -+ if (mb->plane.dst_y + mb->plane.dst_h > mode->vdisplay) { -+ mb->plane.dst_h = mode->vdisplay - mb->plane.dst_y; -+ mb->plane.src_h = (mode->vdisplay - mb->plane.dst_y) -+ << 16; -+ } -+ } -+ -+ if (num_planes > 1) { -+ /* Assume this must be YUV */ -+ /* Makes assumptions on the stride for the chroma planes as we -+ * can't easily plumb in non-standard pitches. -+ */ -+ mb->plane.planes[1] = bo->paddr + fb->offsets[1]; -+ if (num_planes > 2) -+ mb->plane.planes[2] = bo->paddr + fb->offsets[2]; -+ else -+ mb->plane.planes[2] = 0; -+ -+ /* Special case the YUV420 with U and V as line interleaved -+ * planes as we have special handling for that case. -+ */ -+ if (num_planes == 3 && -+ (fb->offsets[2] - fb->offsets[1]) == fb->pitches[1]) -+ mb->plane.vc_image_type = VC_IMAGE_YUV420_S; -+ } else { -+ mb->plane.planes[1] = 0; -+ mb->plane.planes[2] = 0; -+ } -+ mb->plane.planes[3] = 0; -+ -+ switch (fb->modifier) { -+ case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: -+ switch (mb->plane.vc_image_type) { -+ case VC_IMAGE_RGBX32: -+ mb->plane.vc_image_type = VC_IMAGE_TF_RGBX32; -+ break; -+ case VC_IMAGE_RGBA32: -+ mb->plane.vc_image_type = VC_IMAGE_TF_RGBA32; -+ break; -+ case VC_IMAGE_RGB565: -+ mb->plane.vc_image_type = VC_IMAGE_TF_RGB565; -+ break; -+ } -+ break; -+ case DRM_FORMAT_MOD_BROADCOM_SAND128: -+ mb->plane.vc_image_type = VC_IMAGE_YUV_UV; -+ mb->plane.pitch = fourcc_mod_broadcom_param(fb->modifier); -+ break; -+ } -+ -+ if (vc4_crtc) { -+ mb->plane.dst_x += vc4_crtc->overscan[0]; -+ mb->plane.dst_y += vc4_crtc->overscan[1]; -+ } -+ -+ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] plane update %dx%d@%d +dst(%d,%d, %d,%d) +src(%d,%d, %d,%d) 0x%08x/%08x/%08x/%d, alpha %u zpos %u\n", - plane->base.id, plane->name, -- state->crtc_w, -- state->crtc_h, -- bpp, -+ mb->plane.width, -+ mb->plane.height, -+ mb->plane.vc_image_type, - state->crtc_x, - state->crtc_y, -- &fbinfo.base, -- fb->pitches[0]); -- -- ret = rpi_firmware_property_list(vc4->firmware, &fbinfo, -- sizeof(fbinfo)); -- WARN_ON_ONCE(fbinfo.pitch != fb->pitches[0]); -- WARN_ON_ONCE(fbinfo.base != bo->paddr + fb->offsets[0]); -- -- /* If the CRTC is on (or going to be on) and we're enabled, -+ state->crtc_w, -+ state->crtc_h, -+ mb->plane.src_x, -+ mb->plane.src_y, -+ mb->plane.src_w, -+ mb->plane.src_h, -+ mb->plane.planes[0], -+ mb->plane.planes[1], -+ mb->plane.planes[2], -+ fb->pitches[0], -+ state->alpha, -+ state->normalized_zpos); -+ -+ /* -+ * Do NOT set now, as we haven't checked if the crtc is active or not. -+ * Set from vc4_plane_set_blank instead. -+ * -+ * If the CRTC is on (or going to be on) and we're enabled, - * then unblank. Otherwise, stay blank until CRTC enable. -- */ -+ */ - if (state->crtc->state->active) -- vc4_plane_set_primary_blank(plane, false); -+ vc4_plane_set_blank(plane, false); - } - --static void vc4_primary_plane_atomic_disable(struct drm_plane *plane, -- struct drm_plane_state *old_state) -+static void vc4_plane_atomic_disable(struct drm_plane *plane, -+ struct drm_plane_state *old_state) - { -- vc4_plane_set_primary_blank(plane, true); --} -- --static void vc4_cursor_plane_atomic_update(struct drm_plane *plane, -- struct drm_plane_state *old_state) --{ -- struct vc4_dev *vc4 = to_vc4_dev(plane->dev); -+ //struct vc4_dev *vc4 = to_vc4_dev(plane->dev); - struct drm_plane_state *state = plane->state; -- struct vc4_crtc *vc4_crtc = to_vc4_crtc(state->crtc); -- struct drm_framebuffer *fb = state->fb; -- struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); -- dma_addr_t addr = bo->paddr + fb->offsets[0]; -- int ret; -- u32 packet_state[] = { -- state->crtc->state->active, -- state->crtc_x, -- state->crtc_y, -- 0 -- }; -- WARN_ON_ONCE(fb->pitches[0] != state->crtc_w * 4); -+ struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane); - -- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] update %dx%d cursor at %d,%d (0x%pad/%d)", -+ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] plane disable %dx%d@%d +%d,%d\n", - plane->base.id, plane->name, - state->crtc_w, - state->crtc_h, -+ vc4_plane->mb.plane.vc_image_type, - state->crtc_x, -- state->crtc_y, -- &addr, -- fb->pitches[0]); -- -- /* add on the top/left offsets when overscan is active */ -- if (vc4_crtc) { -- packet_state[1] += vc4_crtc->overscan[0]; -- packet_state[2] += vc4_crtc->overscan[1]; -- } -- -- ret = rpi_firmware_property(vc4->firmware, -- RPI_FIRMWARE_SET_CURSOR_STATE, -- &packet_state, -- sizeof(packet_state)); -- if (ret || packet_state[0] != 0) -- DRM_ERROR("Failed to set cursor state: 0x%08x\n", packet_state[0]); -- -- /* Note: When the cursor contents change, the modesetting -- * driver calls drm_mode_cursor_univeral() with -- * DRM_MODE_CURSOR_BO, which means a new fb will be allocated. -- */ -- if (!old_state || -- state->crtc_w != old_state->crtc_w || -- state->crtc_h != old_state->crtc_h || -- fb != old_state->fb) { -- u32 packet_info[] = { state->crtc_w, state->crtc_h, -- 0, /* unused */ -- addr, -- 0, 0, /* hotx, hoty */}; -- -- ret = rpi_firmware_property(vc4->firmware, -- RPI_FIRMWARE_SET_CURSOR_INFO, -- &packet_info, -- sizeof(packet_info)); -- if (ret || packet_info[0] != 0) -- DRM_ERROR("Failed to set cursor info: 0x%08x\n", packet_info[0]); -- } --} -- --static void vc4_cursor_plane_atomic_disable(struct drm_plane *plane, -- struct drm_plane_state *old_state) --{ -- struct vc4_dev *vc4 = to_vc4_dev(plane->dev); -- 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, -- sizeof(packet_state)); -- if (ret || packet_state[0] != 0) -- DRM_ERROR("Failed to set cursor state: 0x%08x\n", packet_state[0]); -+ state->crtc_y); -+ vc4_plane_set_blank(plane, true); - } - - static int vc4_plane_atomic_check(struct drm_plane *plane, -@@ -301,6 +431,7 @@ static bool vc4_fkms_format_mod_supporte - switch (format) { - case DRM_FORMAT_XRGB8888: - case DRM_FORMAT_ARGB8888: -+ case DRM_FORMAT_RGB565: - switch (modifier) { - case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: - case DRM_FORMAT_MOD_LINEAR: -@@ -309,8 +440,22 @@ static bool vc4_fkms_format_mod_supporte - default: - return false; - } -+ case DRM_FORMAT_NV12: -+ case DRM_FORMAT_NV21: -+ switch (fourcc_mod_broadcom_mod(modifier)) { -+ case DRM_FORMAT_MOD_LINEAR: -+ case DRM_FORMAT_MOD_BROADCOM_SAND128: -+ return true; -+ default: -+ return false; -+ } -+ case DRM_FORMAT_RGB888: -+ case DRM_FORMAT_BGR888: -+ case DRM_FORMAT_YUV422: -+ case DRM_FORMAT_YUV420: -+ case DRM_FORMAT_YVU420: - default: -- return false; -+ return (modifier == DRM_FORMAT_MOD_LINEAR); - } - } - -@@ -325,31 +470,24 @@ static const struct drm_plane_funcs vc4_ - .format_mod_supported = vc4_fkms_format_mod_supported, - }; - --static const struct drm_plane_helper_funcs vc4_primary_plane_helper_funcs = { -- .prepare_fb = drm_gem_fb_prepare_fb, -- .cleanup_fb = NULL, -- .atomic_check = vc4_plane_atomic_check, -- .atomic_update = vc4_primary_plane_atomic_update, -- .atomic_disable = vc4_primary_plane_atomic_disable, --}; -- --static const struct drm_plane_helper_funcs vc4_cursor_plane_helper_funcs = { -+static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = { - .prepare_fb = drm_gem_fb_prepare_fb, - .cleanup_fb = NULL, - .atomic_check = vc4_plane_atomic_check, -- .atomic_update = vc4_cursor_plane_atomic_update, -- .atomic_disable = vc4_cursor_plane_atomic_disable, -+ .atomic_update = vc4_plane_atomic_update, -+ .atomic_disable = vc4_plane_atomic_disable, - }; - - static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev, -- enum drm_plane_type type) -+ enum drm_plane_type type, -+ u8 plane_id) - { -- /* Primary and cursor planes only */ - struct drm_plane *plane = NULL; - struct vc4_fkms_plane *vc4_plane; -- u32 formats[] = {DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888}; -+ u32 formats[ARRAY_SIZE(vc_image_formats)]; -+ unsigned int default_zpos; -+ u32 num_formats = 0; - int ret = 0; -- bool primary = (type == DRM_PLANE_TYPE_PRIMARY); - static const uint64_t modifiers[] = { - DRM_FORMAT_MOD_LINEAR, - /* VC4_T_TILED should come after linear, because we -@@ -358,6 +496,7 @@ static struct drm_plane *vc4_fkms_plane_ - DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED, - DRM_FORMAT_MOD_INVALID, - }; -+ int i; - - vc4_plane = devm_kzalloc(dev->dev, sizeof(*vc4_plane), - GFP_KERNEL); -@@ -366,19 +505,48 @@ static struct drm_plane *vc4_fkms_plane_ - goto fail; - } - -+ for (i = 0; i < ARRAY_SIZE(vc_image_formats); i++) -+ formats[num_formats++] = vc_image_formats[i].drm; -+ - plane = &vc4_plane->base; - ret = drm_universal_plane_init(dev, plane, 0xff, - &vc4_plane_funcs, -- formats, primary ? 2 : 1, modifiers, -- type, primary ? "primary" : "cursor"); -+ formats, num_formats, modifiers, -+ type, NULL); - -- if (type == DRM_PLANE_TYPE_PRIMARY) -- drm_plane_helper_add(plane, &vc4_primary_plane_helper_funcs); -- else -- drm_plane_helper_add(plane, &vc4_cursor_plane_helper_funcs); -+ drm_plane_helper_add(plane, &vc4_plane_helper_funcs); - - drm_plane_create_alpha_property(plane); - -+ /* -+ * Default frame buffer setup is with FB on -127, and raspistill etc -+ * tend to drop overlays on layer 2. Cursor plane was on layer +127. -+ * -+ * For F-KMS the mailbox call allows for a s8. -+ * Remap zpos 0 to -127 for the background layer, but leave all the -+ * other layers as requested by KMS. -+ */ -+ switch (type) { -+ case DRM_PLANE_TYPE_PRIMARY: -+ default_zpos = 0; -+ break; -+ case DRM_PLANE_TYPE_OVERLAY: -+ default_zpos = 1; -+ break; -+ case DRM_PLANE_TYPE_CURSOR: -+ default_zpos = 2; -+ break; -+ } -+ drm_plane_create_zpos_property(plane, default_zpos, 0, 127); -+ -+ /* Prepare the static elements of the mailbox structure */ -+ vc4_plane->mb.tag.tag = RPI_FIRMWARE_SET_PLANE; -+ vc4_plane->mb.tag.buf_size = sizeof(struct set_plane); -+ vc4_plane->mb.tag.req_resp_size = 0; -+ vc4_plane->mb.plane.display = 0; -+ vc4_plane->mb.plane.plane_id = plane_id; -+ vc4_plane->mb.plane.layer = default_zpos ? default_zpos : -127; -+ - return plane; - fail: - if (plane) -@@ -400,19 +568,23 @@ static void vc4_crtc_disable(struct drm_ - * whether anything scans out at all, but the firmware doesn't - * give us a CRTC-level control for that. - */ -- vc4_cursor_plane_atomic_disable(crtc->cursor, crtc->cursor->state); -- vc4_plane_set_primary_blank(crtc->primary, true); -+ -+ vc4_plane_atomic_disable(crtc->cursor, crtc->cursor->state); -+ vc4_plane_atomic_disable(crtc->primary, crtc->primary->state); -+ -+ /* FIXME: Disable overlay planes */ - } - - static void vc4_crtc_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) - { - /* Unblank the planes (if they're supposed to be displayed). */ -+ - if (crtc->primary->state->fb) -- vc4_plane_set_primary_blank(crtc->primary, false); -- if (crtc->cursor->state->fb) { -- vc4_cursor_plane_atomic_update(crtc->cursor, -- crtc->cursor->state); -- } -+ vc4_plane_set_blank(crtc->primary, false); -+ if (crtc->cursor->state->fb) -+ vc4_plane_set_blank(crtc->cursor, crtc->cursor->state); -+ -+ /* FIXME: Enable overlay planes */ - } - - static int vc4_crtc_atomic_check(struct drm_crtc *crtc, -@@ -672,8 +844,10 @@ static int vc4_fkms_bind(struct device * - struct vc4_crtc *vc4_crtc; - struct vc4_fkms_encoder *vc4_encoder; - struct drm_crtc *crtc; -- struct drm_plane *primary_plane, *cursor_plane, *destroy_plane, *temp; -+ struct drm_plane *primary_plane, *overlay_plane, *cursor_plane; -+ struct drm_plane *destroy_plane, *temp; - struct device_node *firmware_node; -+ u32 blank = 1; - int ret; - - vc4->firmware_kms = true; -@@ -702,20 +876,26 @@ static int vc4_fkms_bind(struct device * - if (IS_ERR(vc4_crtc->regs)) - return PTR_ERR(vc4_crtc->regs); - -- /* For now, we create just the primary and the legacy cursor -- * planes. We should be able to stack more planes on easily, -- * but to do that we would need to compute the bandwidth -- * requirement of the plane configuration, and reject ones -- * that will take too much. -- */ -- primary_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_PRIMARY); -+ /* Blank the firmware provided framebuffer */ -+ rpi_firmware_property(vc4->firmware, -+ RPI_FIRMWARE_FRAMEBUFFER_BLANK, -+ &blank, sizeof(blank)); -+ -+ primary_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_PRIMARY, 0); - if (IS_ERR(primary_plane)) { - dev_err(dev, "failed to construct primary plane\n"); - ret = PTR_ERR(primary_plane); - goto err; - } - -- cursor_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_CURSOR); -+ overlay_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_OVERLAY, 1); -+ if (IS_ERR(overlay_plane)) { -+ dev_err(dev, "failed to construct overlay plane\n"); -+ ret = PTR_ERR(overlay_plane); -+ goto err; -+ } -+ -+ cursor_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_CURSOR, 2); - if (IS_ERR(cursor_plane)) { - dev_err(dev, "failed to construct cursor plane\n"); - ret = PTR_ERR(cursor_plane); ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -435,6 +435,7 @@ int vc4_kms_load(struct drm_device *dev) - dev->mode_config.preferred_depth = 24; - dev->mode_config.async_page_flip = true; - dev->mode_config.allow_fb_modifiers = true; -+ dev->mode_config.normalize_zpos = true; - - drm_modeset_lock_init(&vc4->ctm_state_lock); - ---- /dev/null -+++ b/drivers/gpu/drm/vc4/vc_image_types.h -@@ -0,0 +1,143 @@ -+ -+/* -+ * Copyright (c) 2012, Broadcom Europe Ltd -+ * -+ * Values taken from vc_image_types.h released by Broadcom at -+ * https://github.com/raspberrypi/userland/blob/master/interface/vctypes/vc_image_types.h -+ * -+ * 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. -+ */ -+ -+enum { -+ VC_IMAGE_MIN = 0, //bounds for error checking -+ -+ VC_IMAGE_RGB565 = 1, -+ VC_IMAGE_1BPP, -+ VC_IMAGE_YUV420, -+ VC_IMAGE_48BPP, -+ VC_IMAGE_RGB888, -+ VC_IMAGE_8BPP, -+ /* 4bpp palettised image */ -+ VC_IMAGE_4BPP, -+ /* A separated format of 16 colour/light shorts followed by 16 z -+ * values -+ */ -+ VC_IMAGE_3D32, -+ /* 16 colours followed by 16 z values */ -+ VC_IMAGE_3D32B, -+ /* A separated format of 16 material/colour/light shorts followed by -+ * 16 z values -+ */ -+ VC_IMAGE_3D32MAT, -+ /* 32 bit format containing 18 bits of 6.6.6 RGB, 9 bits per short */ -+ VC_IMAGE_RGB2X9, -+ /* 32-bit format holding 18 bits of 6.6.6 RGB */ -+ VC_IMAGE_RGB666, -+ /* 4bpp palettised image with embedded palette */ -+ VC_IMAGE_PAL4_OBSOLETE, -+ /* 8bpp palettised image with embedded palette */ -+ VC_IMAGE_PAL8_OBSOLETE, -+ /* RGB888 with an alpha byte after each pixel */ -+ VC_IMAGE_RGBA32, -+ /* a line of Y (32-byte padded), a line of U (16-byte padded), and a -+ * line of V (16-byte padded) -+ */ -+ VC_IMAGE_YUV422, -+ /* RGB565 with a transparent patch */ -+ VC_IMAGE_RGBA565, -+ /* Compressed (4444) version of RGBA32 */ -+ VC_IMAGE_RGBA16, -+ /* VCIII codec format */ -+ VC_IMAGE_YUV_UV, -+ /* VCIII T-format RGBA8888 */ -+ VC_IMAGE_TF_RGBA32, -+ /* VCIII T-format RGBx8888 */ -+ VC_IMAGE_TF_RGBX32, -+ /* VCIII T-format float */ -+ VC_IMAGE_TF_FLOAT, -+ /* VCIII T-format RGBA4444 */ -+ VC_IMAGE_TF_RGBA16, -+ /* VCIII T-format RGB5551 */ -+ VC_IMAGE_TF_RGBA5551, -+ /* VCIII T-format RGB565 */ -+ VC_IMAGE_TF_RGB565, -+ /* VCIII T-format 8-bit luma and 8-bit alpha */ -+ VC_IMAGE_TF_YA88, -+ /* VCIII T-format 8 bit generic sample */ -+ VC_IMAGE_TF_BYTE, -+ /* VCIII T-format 8-bit palette */ -+ VC_IMAGE_TF_PAL8, -+ /* VCIII T-format 4-bit palette */ -+ VC_IMAGE_TF_PAL4, -+ /* VCIII T-format Ericsson Texture Compressed */ -+ VC_IMAGE_TF_ETC1, -+ /* RGB888 with R & B swapped */ -+ VC_IMAGE_BGR888, -+ /* RGB888 with R & B swapped, but with no pitch, i.e. no padding after -+ * each row of pixels -+ */ -+ VC_IMAGE_BGR888_NP, -+ /* Bayer image, extra defines which variant is being used */ -+ VC_IMAGE_BAYER, -+ /* General wrapper for codec images e.g. JPEG from camera */ -+ VC_IMAGE_CODEC, -+ /* VCIII codec format */ -+ VC_IMAGE_YUV_UV32, -+ /* VCIII T-format 8-bit luma */ -+ VC_IMAGE_TF_Y8, -+ /* VCIII T-format 8-bit alpha */ -+ VC_IMAGE_TF_A8, -+ /* VCIII T-format 16-bit generic sample */ -+ VC_IMAGE_TF_SHORT, -+ /* VCIII T-format 1bpp black/white */ -+ VC_IMAGE_TF_1BPP, -+ VC_IMAGE_OPENGL, -+ /* VCIII-B0 HVS YUV 4:4:4 interleaved samples */ -+ VC_IMAGE_YUV444I, -+ /* Y, U, & V planes separately (VC_IMAGE_YUV422 has them interleaved on -+ * a per line basis) -+ */ -+ VC_IMAGE_YUV422PLANAR, -+ /* 32bpp with 8bit alpha at MS byte, with R, G, B (LS byte) */ -+ VC_IMAGE_ARGB8888, -+ /* 32bpp with 8bit unused at MS byte, with R, G, B (LS byte) */ -+ VC_IMAGE_XRGB8888, -+ -+ /* interleaved 8 bit samples of Y, U, Y, V (4 flavours) */ -+ VC_IMAGE_YUV422YUYV, -+ VC_IMAGE_YUV422YVYU, -+ VC_IMAGE_YUV422UYVY, -+ VC_IMAGE_YUV422VYUY, -+ -+ /* 32bpp like RGBA32 but with unused alpha */ -+ VC_IMAGE_RGBX32, -+ /* 32bpp, corresponding to RGBA with unused alpha */ -+ VC_IMAGE_RGBX8888, -+ /* 32bpp, corresponding to BGRA with unused alpha */ -+ VC_IMAGE_BGRX8888, -+ -+ /* Y as a plane, then UV byte interleaved in plane with with same pitch, -+ * half height -+ */ -+ VC_IMAGE_YUV420SP, -+ -+ /* Y, U, & V planes separately 4:4:4 */ -+ VC_IMAGE_YUV444PLANAR, -+ -+ /* T-format 8-bit U - same as TF_Y8 buf from U plane */ -+ VC_IMAGE_TF_U8, -+ /* T-format 8-bit U - same as TF_Y8 buf from V plane */ -+ VC_IMAGE_TF_V8, -+ -+ /* YUV4:2:0 planar, 16bit values */ -+ VC_IMAGE_YUV420_16, -+ /* YUV4:2:0 codec format, 16bit values */ -+ VC_IMAGE_YUV_UV_16, -+ /* YUV4:2:0 with U,V in side-by-side format */ -+ VC_IMAGE_YUV420_S, -+ -+ VC_IMAGE_MAX, /* bounds for error checking */ -+ VC_IMAGE_FORCE_ENUM_16BIT = 0xffff, -+}; ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -148,6 +148,8 @@ enum rpi_firmware_property_tag { - - RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, - -+ RPI_FIRMWARE_SET_PLANE = 0x00048015, -+ - RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, - RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0599-drm-vc4-Select-display-to-blank-during-initialisatio.patch b/target/linux/brcm2708/patches-4.19/950-0599-drm-vc4-Select-display-to-blank-during-initialisatio.patch new file mode 100644 index 0000000000..3d4ac07d10 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0599-drm-vc4-Select-display-to-blank-during-initialisatio.patch @@ -0,0 +1,54 @@ +From afb2fb1c99cefdd0dc95a944bd3506658b31768b Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 5 Apr 2019 17:23:15 +0100 +Subject: [PATCH 599/725] drm: vc4: Select display to blank during + initialisation + +Otherwise the rainbow splash screen remained in the display list + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -87,6 +87,13 @@ struct fb_alloc_tags { + u32 layer; + }; + ++struct mailbox_blank_display { ++ struct rpi_firmware_property_tag_header tag1; ++ u32 display; ++ struct rpi_firmware_property_tag_header tag2; ++ u32 blank; ++}; ++ + static const struct vc_image_format { + u32 drm; /* DRM_FORMAT_* */ + u32 vc_image; /* VC_IMAGE_* */ +@@ -854,7 +861,12 @@ static int vc4_fkms_create_screen(struct + struct drm_crtc *crtc; + struct drm_plane *primary_plane, *overlay_plane, *cursor_plane; + struct drm_plane *destroy_plane, *temp; +- u32 blank = 1; ++ struct mailbox_blank_display blank = { ++ .tag1 = {RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM, 4, 0, }, ++ .display = display_idx, ++ .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_BLANK, 4, 0, }, ++ .blank = 1, ++ }; + int ret; + + vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL); +@@ -865,9 +877,7 @@ static int vc4_fkms_create_screen(struct + vc4_crtc->display_number = display_ref; + + /* Blank the firmware provided framebuffer */ +- rpi_firmware_property(vc4->firmware, +- RPI_FIRMWARE_FRAMEBUFFER_BLANK, +- &blank, sizeof(blank)); ++ rpi_firmware_property_list(vc4->firmware, &blank, sizeof(blank)); + + primary_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_PRIMARY, + display_ref, diff --git a/target/linux/brcm2708/patches-4.19/950-0600-drm-vc4-Increase-max-screen-size-to-4096x4096.patch b/target/linux/brcm2708/patches-4.19/950-0600-drm-vc4-Increase-max-screen-size-to-4096x4096.patch deleted file mode 100644 index e004c477b3..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0600-drm-vc4-Increase-max-screen-size-to-4096x4096.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 519f7cae9e7120bb3abc13d33ace4f7438d140bc Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 3 Apr 2019 15:20:05 +0100 -Subject: [PATCH 600/703] drm: vc4: Increase max screen size to 4096x4096. - -We now should support 4k screens, therefore this limit needs to -be increased. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_kms.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -429,8 +429,8 @@ int vc4_kms_load(struct drm_device *dev) - return ret; - } - -- dev->mode_config.max_width = 2048; -- dev->mode_config.max_height = 2048; -+ dev->mode_config.max_width = 4096; -+ dev->mode_config.max_height = 4096; - dev->mode_config.funcs = &vc4_mode_funcs; - dev->mode_config.preferred_depth = 24; - dev->mode_config.async_page_flip = true; diff --git a/target/linux/brcm2708/patches-4.19/950-0600-drm-vc4-Remove-now-unused-structure.patch b/target/linux/brcm2708/patches-4.19/950-0600-drm-vc4-Remove-now-unused-structure.patch new file mode 100644 index 0000000000..73683863c6 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0600-drm-vc4-Remove-now-unused-structure.patch @@ -0,0 +1,41 @@ +From d4ab5b715c6d52e7135849924d2de08eccd28106 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 5 Apr 2019 17:24:20 +0100 +Subject: [PATCH 600/725] drm: vc4: Remove now unused structure. + +Cleaning up structure that was unused after +fbb59a2 drm: vc4: Add an overlay plane to vc4-firmware-kms + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 19 ------------------- + 1 file changed, 19 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -68,25 +68,6 @@ struct mailbox_set_plane { + struct set_plane plane; + }; + +-struct fb_alloc_tags { +- struct rpi_firmware_property_tag_header tag1; +- u32 xres, yres; +- struct rpi_firmware_property_tag_header tag2; +- u32 xres_virtual, yres_virtual; +- struct rpi_firmware_property_tag_header tag3; +- u32 bpp; +- struct rpi_firmware_property_tag_header tag4; +- u32 xoffset, yoffset; +- struct rpi_firmware_property_tag_header tag5; +- u32 base, screen_size; +- struct rpi_firmware_property_tag_header tag6; +- u32 pitch; +- struct rpi_firmware_property_tag_header tag7; +- u32 alpha_mode; +- struct rpi_firmware_property_tag_header tag8; +- u32 layer; +-}; +- + struct mailbox_blank_display { + struct rpi_firmware_property_tag_header tag1; + u32 display; diff --git a/target/linux/brcm2708/patches-4.19/950-0601-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch b/target/linux/brcm2708/patches-4.19/950-0601-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch deleted file mode 100644 index ff69f4eb98..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0601-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch +++ /dev/null @@ -1,280 +0,0 @@ -From f4dee6e8ddab28130160a4dba535dca167e69f13 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 3 Apr 2019 17:15:45 +0100 -Subject: [PATCH 601/703] drm: vc4: Add support for multiple displays to fkms - -There is a slightly nasty hack in that all crtcs share the -same SMI interrupt from the firmware. This seems to currently -work well enough, but ought to be fixed at a later date. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 160 +++++++++++++++++-------- - 1 file changed, 113 insertions(+), 47 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -29,6 +29,8 @@ - #include "vc_image_types.h" - #include - -+#define PLANES_PER_CRTC 3 -+ - struct set_plane { - u8 display; - u8 plane_id; -@@ -175,6 +177,7 @@ struct vc4_crtc { - struct drm_pending_vblank_event *event; - u32 overscan[4]; - bool vblank_enabled; -+ u32 display_number; - }; - - static inline struct vc4_crtc *to_vc4_crtc(struct drm_crtc *crtc) -@@ -480,6 +483,7 @@ static const struct drm_plane_helper_fun - - static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev, - enum drm_plane_type type, -+ u8 display_num, - u8 plane_id) - { - struct drm_plane *plane = NULL; -@@ -543,7 +547,7 @@ static struct drm_plane *vc4_fkms_plane_ - vc4_plane->mb.tag.tag = RPI_FIRMWARE_SET_PLANE; - vc4_plane->mb.tag.buf_size = sizeof(struct set_plane); - vc4_plane->mb.tag.req_resp_size = 0; -- vc4_plane->mb.plane.display = 0; -+ vc4_plane->mb.plane.display = display_num; - vc4_plane->mb.plane.plane_id = plane_id; - vc4_plane->mb.plane.layer = default_zpos ? default_zpos : -127; - -@@ -630,16 +634,20 @@ static void vc4_crtc_handle_page_flip(st - - static irqreturn_t vc4_crtc_irq_handler(int irq, void *data) - { -- struct vc4_crtc *vc4_crtc = data; -- u32 stat = readl(vc4_crtc->regs + SMICS); -+ struct vc4_crtc **crtc_list = data; -+ int i; -+ u32 stat = readl(crtc_list[0]->regs + SMICS); - irqreturn_t ret = IRQ_NONE; - - if (stat & SMICS_INTERRUPTS) { -- writel(0, vc4_crtc->regs + SMICS); -- if (vc4_crtc->vblank_enabled) -- drm_crtc_handle_vblank(&vc4_crtc->base); -- vc4_crtc_handle_page_flip(vc4_crtc); -- ret = IRQ_HANDLED; -+ writel(0, crtc_list[0]->regs + SMICS); -+ -+ for (i = 0; crtc_list[i]; i++) { -+ if (crtc_list[i]->vblank_enabled) -+ drm_crtc_handle_vblank(&crtc_list[i]->base); -+ vc4_crtc_handle_page_flip(crtc_list[i]); -+ ret = IRQ_HANDLED; -+ } - } - - return ret; -@@ -836,66 +844,55 @@ static const struct drm_encoder_helper_f - .disable = vc4_fkms_encoder_disable, - }; - --static int vc4_fkms_bind(struct device *dev, struct device *master, void *data) -+static int vc4_fkms_create_screen(struct device *dev, struct drm_device *drm, -+ int display_idx, int display_ref, -+ struct vc4_crtc **ret_crtc) - { -- 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_crtc *vc4_crtc; - struct vc4_fkms_encoder *vc4_encoder; - struct drm_crtc *crtc; - struct drm_plane *primary_plane, *overlay_plane, *cursor_plane; - struct drm_plane *destroy_plane, *temp; -- struct device_node *firmware_node; - u32 blank = 1; - int ret; - -- vc4->firmware_kms = true; -- -- /* firmware kms doesn't have precise a scanoutpos implementation, so -- * we can't do the precise vblank timestamp mode. -- */ -- drm->driver->get_scanout_position = NULL; -- drm->driver->get_vblank_timestamp = NULL; -- - vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL); - if (!vc4_crtc) - return -ENOMEM; - crtc = &vc4_crtc->base; - -- firmware_node = of_parse_phandle(dev->of_node, "brcm,firmware", 0); -- vc4->firmware = rpi_firmware_get(firmware_node); -- if (!vc4->firmware) { -- DRM_DEBUG("Failed to get Raspberry Pi firmware reference.\n"); -- return -EPROBE_DEFER; -- } -- of_node_put(firmware_node); -- -- /* Map the SMI interrupt reg */ -- vc4_crtc->regs = vc4_ioremap_regs(pdev, 0); -- if (IS_ERR(vc4_crtc->regs)) -- return PTR_ERR(vc4_crtc->regs); -+ vc4_crtc->display_number = display_ref; - - /* Blank the firmware provided framebuffer */ - rpi_firmware_property(vc4->firmware, - RPI_FIRMWARE_FRAMEBUFFER_BLANK, - &blank, sizeof(blank)); - -- primary_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_PRIMARY, 0); -+ primary_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_PRIMARY, -+ display_ref, -+ 0 + (display_idx * PLANES_PER_CRTC) -+ ); - if (IS_ERR(primary_plane)) { - dev_err(dev, "failed to construct primary plane\n"); - ret = PTR_ERR(primary_plane); - goto err; - } - -- overlay_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_OVERLAY, 1); -+ overlay_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_OVERLAY, -+ display_ref, -+ 1 + (display_idx * PLANES_PER_CRTC) -+ ); - if (IS_ERR(overlay_plane)) { - dev_err(dev, "failed to construct overlay plane\n"); - ret = PTR_ERR(overlay_plane); - goto err; - } - -- cursor_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_CURSOR, 2); -+ cursor_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_CURSOR, -+ display_ref, -+ 2 + (display_idx * PLANES_PER_CRTC) -+ ); - if (IS_ERR(cursor_plane)) { - dev_err(dev, "failed to construct cursor plane\n"); - ret = PTR_ERR(cursor_plane); -@@ -922,13 +919,6 @@ static int vc4_fkms_bind(struct device * - goto err_destroy_encoder; - } - -- writel(0, vc4_crtc->regs + SMICS); -- ret = devm_request_irq(dev, platform_get_irq(pdev, 0), -- vc4_crtc_irq_handler, 0, "vc4 firmware kms", -- vc4_crtc); -- if (ret) -- goto err_destroy_connector; -- - ret = rpi_firmware_property(vc4->firmware, - RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN, - &vc4_crtc->overscan, -@@ -938,7 +928,7 @@ static int vc4_fkms_bind(struct device * - memset(&vc4_crtc->overscan, 0, sizeof(vc4_crtc->overscan)); - } - -- platform_set_drvdata(pdev, vc4_crtc); -+ *ret_crtc = vc4_crtc; - - return 0; - -@@ -955,15 +945,91 @@ err: - return ret; - } - -+static int vc4_fkms_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 device_node *firmware_node; -+ struct vc4_crtc **crtc_list; -+ u32 num_displays, display_num; -+ int ret; -+ const u32 display_num_lookup[] = {2, 7, 1}; -+ -+ vc4->firmware_kms = true; -+ -+ /* firmware kms doesn't have precise a scanoutpos implementation, so -+ * we can't do the precise vblank timestamp mode. -+ */ -+ drm->driver->get_scanout_position = NULL; -+ drm->driver->get_vblank_timestamp = NULL; -+ -+ firmware_node = of_parse_phandle(dev->of_node, "brcm,firmware", 0); -+ vc4->firmware = rpi_firmware_get(firmware_node); -+ if (!vc4->firmware) { -+ DRM_DEBUG("Failed to get Raspberry Pi firmware reference.\n"); -+ return -EPROBE_DEFER; -+ } -+ of_node_put(firmware_node); -+ -+ ret = rpi_firmware_property(vc4->firmware, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS, -+ &num_displays, sizeof(u32)); -+ -+ /* If we fail to get the number of displays, or it returns 0, then -+ * assume old firmware that doesn't have the mailbox call, so just -+ * set one display -+ */ -+ if (ret || num_displays == 0) { -+ num_displays = 1; -+ DRM_WARN("Unable to determine number of displays's. Assuming 1\n"); -+ ret = 0; -+ } -+ -+ /* Allocate a list, with space for a NULL on the end */ -+ crtc_list = devm_kzalloc(dev, sizeof(crtc_list) * (num_displays + 1), -+ GFP_KERNEL); -+ if (!crtc_list) -+ return -ENOMEM; -+ -+ for (display_num = 0; display_num < num_displays; display_num++) { -+ ret = vc4_fkms_create_screen(dev, drm, display_num, -+ display_num_lookup[display_num], -+ &crtc_list[display_num]); -+ if (ret) -+ DRM_ERROR("Oh dear, failed to create display %u\n", -+ display_num); -+ } -+ -+ /* Map the SMI interrupt reg */ -+ crtc_list[0]->regs = vc4_ioremap_regs(pdev, 0); -+ if (IS_ERR(crtc_list[0]->regs)) -+ DRM_ERROR("Oh dear, failed to map registers\n"); -+ -+ writel(0, crtc_list[0]->regs + SMICS); -+ ret = devm_request_irq(dev, platform_get_irq(pdev, 0), -+ vc4_crtc_irq_handler, 0, "vc4 firmware kms", -+ crtc_list); -+ if (ret) -+ DRM_ERROR("Oh dear, failed to register IRQ\n"); -+ -+ platform_set_drvdata(pdev, crtc_list); -+ -+ return 0; -+} -+ - static void vc4_fkms_unbind(struct device *dev, struct device *master, - void *data) - { - struct platform_device *pdev = to_platform_device(dev); -- struct vc4_crtc *vc4_crtc = dev_get_drvdata(dev); -+ struct vc4_crtc **crtc_list = dev_get_drvdata(dev); -+ int i; - -- vc4_fkms_connector_destroy(vc4_crtc->connector); -- vc4_fkms_encoder_destroy(vc4_crtc->encoder); -- drm_crtc_cleanup(&vc4_crtc->base); -+ for (i = 0; crtc_list[i]; i++) { -+ vc4_fkms_connector_destroy(crtc_list[i]->connector); -+ vc4_fkms_encoder_destroy(crtc_list[i]->encoder); -+ drm_crtc_cleanup(&crtc_list[i]->base); -+ } - - platform_set_drvdata(pdev, NULL); - } diff --git a/target/linux/brcm2708/patches-4.19/950-0601-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch b/target/linux/brcm2708/patches-4.19/950-0601-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch new file mode 100644 index 0000000000..f1867562d7 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0601-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch @@ -0,0 +1,58 @@ +From 65367a8d30161871007aa14e62644f62fc5d102b Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 9 Apr 2019 12:37:28 +0100 +Subject: [PATCH 601/725] drm: vc4: Query the display ID for each display in + FKMS + +Replace the hard coded list of display IDs for a mailbox call +that returns the display ID for each display that has been +detected. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 16 +++++++++++++--- + include/soc/bcm2835/raspberrypi-firmware.h | 1 + + 2 files changed, 14 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -943,7 +943,7 @@ static int vc4_fkms_bind(struct device * + struct vc4_crtc **crtc_list; + u32 num_displays, display_num; + int ret; +- const u32 display_num_lookup[] = {2, 7, 1}; ++ u32 display_id; + + vc4->firmware_kms = true; + +@@ -982,8 +982,18 @@ static int vc4_fkms_bind(struct device * + return -ENOMEM; + + for (display_num = 0; display_num < num_displays; display_num++) { +- ret = vc4_fkms_create_screen(dev, drm, display_num, +- display_num_lookup[display_num], ++ display_id = display_num; ++ ret = rpi_firmware_property(vc4->firmware, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_ID, ++ &display_id, sizeof(display_id)); ++ /* FIXME: Determine the correct error handling here. ++ * Should we fail to create the one "screen" but keep the ++ * others, or fail the whole thing? ++ */ ++ if (ret) ++ DRM_ERROR("Failed to get display id %u\n", display_num); ++ ++ ret = vc4_fkms_create_screen(dev, drm, display_num, display_id, + &crtc_list[display_num]); + if (ret) + DRM_ERROR("Oh dear, failed to create display %u\n", +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -117,6 +117,7 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f, + RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF = 0x00040010, + RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_ID = 0x00040016, + RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM = 0x00048013, + RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS = 0x00040013, + RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_SETTINGS = 0x00040014, diff --git a/target/linux/brcm2708/patches-4.19/950-0602-drm-vc4-Fix-build-warning.patch b/target/linux/brcm2708/patches-4.19/950-0602-drm-vc4-Fix-build-warning.patch deleted file mode 100644 index 05fd757b78..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0602-drm-vc4-Fix-build-warning.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 56ac34a516982f51f7a0678f185bcb80f5070a0e Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 5 Apr 2019 17:21:56 +0100 -Subject: [PATCH 602/703] drm: vc4: Fix build warning - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -932,8 +932,6 @@ static int vc4_fkms_create_screen(struct - - return 0; - --err_destroy_connector: -- vc4_fkms_connector_destroy(vc4_crtc->connector); - err_destroy_encoder: - vc4_fkms_encoder_destroy(vc4_crtc->encoder); - list_for_each_entry_safe(destroy_plane, temp, diff --git a/target/linux/brcm2708/patches-4.19/950-0602-drm-vc4-Set-the-display-number-when-querying-the-dis.patch b/target/linux/brcm2708/patches-4.19/950-0602-drm-vc4-Set-the-display-number-when-querying-the-dis.patch new file mode 100644 index 0000000000..5197a380f9 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0602-drm-vc4-Set-the-display-number-when-querying-the-dis.patch @@ -0,0 +1,103 @@ +From 753eb8bb53189b0e9c81454739e02fffdc5ec319 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 9 Apr 2019 14:00:07 +0100 +Subject: [PATCH 602/725] drm/vc4: Set the display number when querying the + display resolution + +Without this the two displays got set to the same resolution. +(Requires a firmware bug fix to work). + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 37 +++++++++++++++++++------- + 1 file changed, 27 insertions(+), 10 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -75,6 +75,13 @@ struct mailbox_blank_display { + u32 blank; + }; + ++struct mailbox_get_width_height { ++ struct rpi_firmware_property_tag_header tag1; ++ u32 display; ++ struct rpi_firmware_property_tag_header tag2; ++ u32 wh[2]; ++}; ++ + static const struct vc_image_format { + u32 drm; /* DRM_FORMAT_* */ + u32 vc_image; /* VC_IMAGE_* */ +@@ -192,6 +199,7 @@ struct vc4_fkms_connector { + * hook. + */ + struct drm_encoder *encoder; ++ u32 display_idx; + }; + + static inline struct vc4_fkms_connector * +@@ -723,21 +731,27 @@ vc4_fkms_connector_detect(struct drm_con + static int vc4_fkms_connector_get_modes(struct drm_connector *connector) + { + struct drm_device *dev = connector->dev; ++ struct vc4_fkms_connector *fkms_connector = ++ to_vc4_fkms_connector(connector); + struct vc4_dev *vc4 = to_vc4_dev(dev); +- u32 wh[2] = {0, 0}; +- int ret; + struct drm_display_mode *mode; ++ struct mailbox_get_width_height wh = { ++ .tag1 = {RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM, 4, 0, }, ++ .display = fkms_connector->display_idx, ++ .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT, ++ 8, 0, }, ++ }; ++ int ret; ++ ++ ret = rpi_firmware_property_list(vc4->firmware, &wh, sizeof(wh)); + +- ret = rpi_firmware_property(vc4->firmware, +- RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT, +- &wh, sizeof(wh)); + if (ret) { + DRM_ERROR("Failed to get screen size: %d (0x%08x 0x%08x)\n", +- ret, wh[0], wh[1]); ++ ret, wh.wh[0], wh.wh[1]); + return 0; + } + +- mode = drm_cvt_mode(dev, wh[0], wh[1], 60 /* vrefresh */, ++ mode = drm_cvt_mode(dev, wh.wh[0], wh.wh[1], 60 /* vrefresh */, + 0, 0, false); + drm_mode_probed_add(connector, mode); + +@@ -772,8 +786,9 @@ static const struct drm_connector_helper + .best_encoder = vc4_fkms_connector_best_encoder, + }; + +-static struct drm_connector *vc4_fkms_connector_init(struct drm_device *dev, +- struct drm_encoder *encoder) ++static struct drm_connector * ++vc4_fkms_connector_init(struct drm_device *dev, struct drm_encoder *encoder, ++ u32 display_idx) + { + struct drm_connector *connector = NULL; + struct vc4_fkms_connector *fkms_connector; +@@ -788,6 +803,7 @@ static struct drm_connector *vc4_fkms_co + connector = &fkms_connector->base; + + fkms_connector->encoder = encoder; ++ fkms_connector->display_idx = display_idx; + + drm_connector_init(dev, connector, &vc4_fkms_connector_funcs, + DRM_MODE_CONNECTOR_HDMIA); +@@ -904,7 +920,8 @@ static int vc4_fkms_create_screen(struct + drm_encoder_helper_add(&vc4_encoder->base, + &vc4_fkms_encoder_helper_funcs); + +- vc4_crtc->connector = vc4_fkms_connector_init(drm, &vc4_encoder->base); ++ vc4_crtc->connector = vc4_fkms_connector_init(drm, &vc4_encoder->base, ++ display_idx); + if (IS_ERR(vc4_crtc->connector)) { + ret = PTR_ERR(vc4_crtc->connector); + goto err_destroy_encoder; diff --git a/target/linux/brcm2708/patches-4.19/950-0603-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch b/target/linux/brcm2708/patches-4.19/950-0603-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch new file mode 100644 index 0000000000..07e9ba85cb --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0603-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch @@ -0,0 +1,46 @@ +From ed17deed1d56073de5733383e7897837e6f1e975 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 9 Apr 2019 18:14:44 +0100 +Subject: [PATCH 603/725] drm: vc4: Need to call drm_crtc_vblank_[on|off] from + vc4_crtc_[en|dis]able + +vblank needs to be enabled and disabled by the driver to avoid the +DRM framework complaining in the kernel log. + +vc4_fkms_disable_vblank needs to signal that we don't want vblank +callbacks too. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -562,6 +562,8 @@ static void vc4_crtc_mode_set_nofb(struc + + static void vc4_crtc_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) + { ++ drm_crtc_vblank_off(crtc); ++ + /* Always turn the planes off on CRTC disable. In DRM, planes + * are enabled/disabled through the update/disable hooks + * above, and the CRTC enable/disable independently controls +@@ -577,6 +579,7 @@ static void vc4_crtc_disable(struct drm_ + + static void vc4_crtc_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) + { ++ drm_crtc_vblank_on(crtc); + /* Unblank the planes (if they're supposed to be displayed). */ + + if (crtc->primary->state->fb) +@@ -673,6 +676,9 @@ static int vc4_fkms_enable_vblank(struct + + static void vc4_fkms_disable_vblank(struct drm_crtc *crtc) + { ++ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); ++ ++ vc4_crtc->vblank_enabled = false; + } + + static const struct drm_crtc_funcs vc4_crtc_funcs = { diff --git a/target/linux/brcm2708/patches-4.19/950-0603-drm-vc4-Select-display-to-blank-during-initialisatio.patch b/target/linux/brcm2708/patches-4.19/950-0603-drm-vc4-Select-display-to-blank-during-initialisatio.patch deleted file mode 100644 index 0c40f8824d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0603-drm-vc4-Select-display-to-blank-during-initialisatio.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 2ec4f853916551a57f574b988162b589e3331359 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 5 Apr 2019 17:23:15 +0100 -Subject: [PATCH 603/703] drm: vc4: Select display to blank during - initialisation - -Otherwise the rainbow splash screen remained in the display list - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 18 ++++++++++++++---- - 1 file changed, 14 insertions(+), 4 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -87,6 +87,13 @@ struct fb_alloc_tags { - u32 layer; - }; - -+struct mailbox_blank_display { -+ struct rpi_firmware_property_tag_header tag1; -+ u32 display; -+ struct rpi_firmware_property_tag_header tag2; -+ u32 blank; -+}; -+ - static const struct vc_image_format { - u32 drm; /* DRM_FORMAT_* */ - u32 vc_image; /* VC_IMAGE_* */ -@@ -854,7 +861,12 @@ static int vc4_fkms_create_screen(struct - struct drm_crtc *crtc; - struct drm_plane *primary_plane, *overlay_plane, *cursor_plane; - struct drm_plane *destroy_plane, *temp; -- u32 blank = 1; -+ struct mailbox_blank_display blank = { -+ .tag1 = {RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM, 4, 0, }, -+ .display = display_idx, -+ .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_BLANK, 4, 0, }, -+ .blank = 1, -+ }; - int ret; - - vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL); -@@ -865,9 +877,7 @@ static int vc4_fkms_create_screen(struct - vc4_crtc->display_number = display_ref; - - /* Blank the firmware provided framebuffer */ -- rpi_firmware_property(vc4->firmware, -- RPI_FIRMWARE_FRAMEBUFFER_BLANK, -- &blank, sizeof(blank)); -+ rpi_firmware_property_list(vc4->firmware, &blank, sizeof(blank)); - - primary_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_PRIMARY, - display_ref, diff --git a/target/linux/brcm2708/patches-4.19/950-0604-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch b/target/linux/brcm2708/patches-4.19/950-0604-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch new file mode 100644 index 0000000000..cf51d0f170 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0604-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch @@ -0,0 +1,86 @@ +From 566c87d4ab55a10a4a4c929e1ad00ddca2294af2 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 9 Apr 2019 17:19:51 +0100 +Subject: [PATCH 604/725] drm: vc4: Add support for H & V flips on each plane + for FKMS + +They are near zero cost options for the HVS, therefore they +may as well be implemented, and it allows us to invert the +DSI display. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 36 ++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -61,8 +61,21 @@ struct set_plane { + u8 padding; + + u32 planes[4]; /* DMA address of each plane */ ++ ++ u32 transform; + }; + ++/* Values for the transform field */ ++#define TRANSFORM_NO_ROTATE 0 ++#define TRANSFORM_ROTATE_180 BIT(1) ++#define TRANSFORM_FLIP_HRIZ BIT(16) ++#define TRANSFORM_FLIP_VERT BIT(17) ++ ++#define SUPPORTED_ROTATIONS (DRM_MODE_ROTATE_0 | \ ++ DRM_MODE_ROTATE_180 | \ ++ DRM_MODE_REFLECT_X | \ ++ DRM_MODE_REFLECT_Y) ++ + struct mailbox_set_plane { + struct rpi_firmware_property_tag_header tag; + struct set_plane plane; +@@ -274,6 +287,7 @@ static void vc4_plane_atomic_update(stru + struct vc4_crtc *vc4_crtc = to_vc4_crtc(state->crtc); + int num_planes = fb->format->num_planes; + struct drm_display_mode *mode = &state->crtc->mode; ++ unsigned int rotation = SUPPORTED_ROTATIONS; + + mb->plane.vc_image_type = vc_fmt->vc_image; + mb->plane.width = fb->width; +@@ -294,6 +308,24 @@ static void vc4_plane_atomic_update(stru + mb->plane.is_vu = vc_fmt->is_vu; + mb->plane.planes[0] = bo->paddr + fb->offsets[0]; + ++ rotation = drm_rotation_simplify(state->rotation, rotation); ++ ++ switch (rotation) { ++ default: ++ case DRM_MODE_ROTATE_0: ++ mb->plane.transform = TRANSFORM_NO_ROTATE; ++ break; ++ case DRM_MODE_ROTATE_180: ++ mb->plane.transform = TRANSFORM_ROTATE_180; ++ break; ++ case DRM_MODE_REFLECT_X: ++ mb->plane.transform = TRANSFORM_FLIP_HRIZ; ++ break; ++ case DRM_MODE_REFLECT_Y: ++ mb->plane.transform = TRANSFORM_FLIP_VERT; ++ break; ++ } ++ + /* FIXME: If the dest rect goes off screen then clip the src rect so we + * don't have off-screen pixels. + */ +@@ -514,9 +546,13 @@ static struct drm_plane *vc4_fkms_plane_ + formats, num_formats, modifiers, + type, NULL); + ++ /* FIXME: Do we need to be checking return values from all these calls? ++ */ + drm_plane_helper_add(plane, &vc4_plane_helper_funcs); + + drm_plane_create_alpha_property(plane); ++ drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0, ++ SUPPORTED_ROTATIONS); + + /* + * Default frame buffer setup is with FB on -127, and raspistill etc diff --git a/target/linux/brcm2708/patches-4.19/950-0604-drm-vc4-Remove-now-unused-structure.patch b/target/linux/brcm2708/patches-4.19/950-0604-drm-vc4-Remove-now-unused-structure.patch deleted file mode 100644 index fa75bc4d1a..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0604-drm-vc4-Remove-now-unused-structure.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 8b4aa15c2c83d84b3f8e94412af3a03061c8878d Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 5 Apr 2019 17:24:20 +0100 -Subject: [PATCH 604/703] drm: vc4: Remove now unused structure. - -Cleaning up structure that was unused after -fbb59a2 drm: vc4: Add an overlay plane to vc4-firmware-kms - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 19 ------------------- - 1 file changed, 19 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -68,25 +68,6 @@ struct mailbox_set_plane { - struct set_plane plane; - }; - --struct fb_alloc_tags { -- struct rpi_firmware_property_tag_header tag1; -- u32 xres, yres; -- struct rpi_firmware_property_tag_header tag2; -- u32 xres_virtual, yres_virtual; -- struct rpi_firmware_property_tag_header tag3; -- u32 bpp; -- struct rpi_firmware_property_tag_header tag4; -- u32 xoffset, yoffset; -- struct rpi_firmware_property_tag_header tag5; -- u32 base, screen_size; -- struct rpi_firmware_property_tag_header tag6; -- u32 pitch; -- struct rpi_firmware_property_tag_header tag7; -- u32 alpha_mode; -- struct rpi_firmware_property_tag_header tag8; -- u32 layer; --}; -- - struct mailbox_blank_display { - struct rpi_firmware_property_tag_header tag1; - u32 display; diff --git a/target/linux/brcm2708/patches-4.19/950-0605-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch b/target/linux/brcm2708/patches-4.19/950-0605-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch deleted file mode 100644 index b470a3bf6d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0605-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 9b3747e9bdce9beb84bec50e7ad06af365e50173 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 9 Apr 2019 12:37:28 +0100 -Subject: [PATCH 605/703] drm: vc4: Query the display ID for each display in - FKMS - -Replace the hard coded list of display IDs for a mailbox call -that returns the display ID for each display that has been -detected. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 16 +++++++++++++--- - include/soc/bcm2835/raspberrypi-firmware.h | 1 + - 2 files changed, 14 insertions(+), 3 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -943,7 +943,7 @@ static int vc4_fkms_bind(struct device * - struct vc4_crtc **crtc_list; - u32 num_displays, display_num; - int ret; -- const u32 display_num_lookup[] = {2, 7, 1}; -+ u32 display_id; - - vc4->firmware_kms = true; - -@@ -982,8 +982,18 @@ static int vc4_fkms_bind(struct device * - return -ENOMEM; - - for (display_num = 0; display_num < num_displays; display_num++) { -- ret = vc4_fkms_create_screen(dev, drm, display_num, -- display_num_lookup[display_num], -+ display_id = display_num; -+ ret = rpi_firmware_property(vc4->firmware, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_ID, -+ &display_id, sizeof(display_id)); -+ /* FIXME: Determine the correct error handling here. -+ * Should we fail to create the one "screen" but keep the -+ * others, or fail the whole thing? -+ */ -+ if (ret) -+ DRM_ERROR("Failed to get display id %u\n", display_num); -+ -+ ret = vc4_fkms_create_screen(dev, drm, display_num, display_id, - &crtc_list[display_num]); - if (ret) - DRM_ERROR("Oh dear, failed to create display %u\n", ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -117,6 +117,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f, - RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF = 0x00040010, - RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_ID = 0x00040016, - RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM = 0x00048013, - RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS = 0x00040013, - RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_SETTINGS = 0x00040014, diff --git a/target/linux/brcm2708/patches-4.19/950-0605-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch b/target/linux/brcm2708/patches-4.19/950-0605-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch new file mode 100644 index 0000000000..2e8df3a3c6 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0605-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch @@ -0,0 +1,56 @@ +From e413b9a87e5b559fd66ff867333d64dedf95fe4c Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 10 Apr 2019 17:35:05 +0100 +Subject: [PATCH 605/725] drm: vc4: Remove unused vc4_fkms_cancel_page_flip + function + +"32a3dbe drm/vc4: Nuke preclose hook" removed vc4_cancel_page_flip, +but vc4_fkms_cancel_page_flip was still be added to with the +fkms driver, even though it was never called. +Nuke it too. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_drv.h | 1 - + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 20 -------------------- + 2 files changed, 21 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_drv.h ++++ b/drivers/gpu/drm/vc4/vc4_drv.h +@@ -724,7 +724,6 @@ extern const struct dma_fence_ops vc4_fe + + /* 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); + + /* vc4_gem.c */ + void vc4_gem_init(struct drm_device *dev); +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -739,26 +739,6 @@ static const struct drm_crtc_helper_func + .atomic_flush = vc4_crtc_atomic_flush, + }; + +-/* Frees the page flip event when the DRM device is closed with the +- * event still outstanding. +- */ +-void vc4_fkms_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file) +-{ +- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); +- struct drm_device *dev = crtc->dev; +- unsigned long flags; +- +- spin_lock_irqsave(&dev->event_lock, flags); +- +- if (vc4_crtc->event && vc4_crtc->event->base.file_priv == file) { +- kfree(&vc4_crtc->event->base); +- drm_crtc_vblank_put(crtc); +- vc4_crtc->event = NULL; +- } +- +- spin_unlock_irqrestore(&dev->event_lock, flags); +-} +- + static const struct of_device_id vc4_firmware_kms_dt_match[] = { + { .compatible = "raspberrypi,rpi-firmware-kms" }, + {} diff --git a/target/linux/brcm2708/patches-4.19/950-0606-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch b/target/linux/brcm2708/patches-4.19/950-0606-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch new file mode 100644 index 0000000000..c5cd27e7f1 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0606-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch @@ -0,0 +1,57 @@ +From 6196e905883945a65a8316d9d08725c6b64ec211 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 10 Apr 2019 17:42:37 +0100 +Subject: [PATCH 606/725] drm: vc4: Iterate over all planes in + vc4_crtc_[dis|en]able + +Fixes a FIXME where the overlay plane wouldn't be restored. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -598,6 +598,8 @@ static void vc4_crtc_mode_set_nofb(struc + + static void vc4_crtc_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) + { ++ struct drm_plane *plane; ++ + drm_crtc_vblank_off(crtc); + + /* Always turn the planes off on CRTC disable. In DRM, planes +@@ -607,23 +609,23 @@ static void vc4_crtc_disable(struct drm_ + * give us a CRTC-level control for that. + */ + +- vc4_plane_atomic_disable(crtc->cursor, crtc->cursor->state); +- vc4_plane_atomic_disable(crtc->primary, crtc->primary->state); +- +- /* FIXME: Disable overlay planes */ ++ drm_atomic_crtc_for_each_plane(plane, crtc) ++ vc4_plane_atomic_disable(plane, plane->state); + } + + static void vc4_crtc_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) + { ++ struct drm_plane *plane; ++ + drm_crtc_vblank_on(crtc); ++ + /* Unblank the planes (if they're supposed to be displayed). */ ++ drm_atomic_crtc_for_each_plane(plane, crtc) ++ if (plane->state->fb) ++ vc4_plane_set_blank(plane, plane->state->visible); ++} + +- if (crtc->primary->state->fb) +- vc4_plane_set_blank(crtc->primary, false); +- if (crtc->cursor->state->fb) +- vc4_plane_set_blank(crtc->cursor, crtc->cursor->state); + +- /* FIXME: Enable overlay planes */ + } + + static int vc4_crtc_atomic_check(struct drm_crtc *crtc, diff --git a/target/linux/brcm2708/patches-4.19/950-0606-drm-vc4-Set-the-display-number-when-querying-the-dis.patch b/target/linux/brcm2708/patches-4.19/950-0606-drm-vc4-Set-the-display-number-when-querying-the-dis.patch deleted file mode 100644 index 36c5081ace..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0606-drm-vc4-Set-the-display-number-when-querying-the-dis.patch +++ /dev/null @@ -1,103 +0,0 @@ -From d00d0711df4da66465ba5086e99c5936ea3b9577 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 9 Apr 2019 14:00:07 +0100 -Subject: [PATCH 606/703] drm/vc4: Set the display number when querying the - display resolution - -Without this the two displays got set to the same resolution. -(Requires a firmware bug fix to work). - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 37 +++++++++++++++++++------- - 1 file changed, 27 insertions(+), 10 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -75,6 +75,13 @@ struct mailbox_blank_display { - u32 blank; - }; - -+struct mailbox_get_width_height { -+ struct rpi_firmware_property_tag_header tag1; -+ u32 display; -+ struct rpi_firmware_property_tag_header tag2; -+ u32 wh[2]; -+}; -+ - static const struct vc_image_format { - u32 drm; /* DRM_FORMAT_* */ - u32 vc_image; /* VC_IMAGE_* */ -@@ -192,6 +199,7 @@ struct vc4_fkms_connector { - * hook. - */ - struct drm_encoder *encoder; -+ u32 display_idx; - }; - - static inline struct vc4_fkms_connector * -@@ -723,21 +731,27 @@ vc4_fkms_connector_detect(struct drm_con - static int vc4_fkms_connector_get_modes(struct drm_connector *connector) - { - struct drm_device *dev = connector->dev; -+ struct vc4_fkms_connector *fkms_connector = -+ to_vc4_fkms_connector(connector); - struct vc4_dev *vc4 = to_vc4_dev(dev); -- u32 wh[2] = {0, 0}; -- int ret; - struct drm_display_mode *mode; -+ struct mailbox_get_width_height wh = { -+ .tag1 = {RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM, 4, 0, }, -+ .display = fkms_connector->display_idx, -+ .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT, -+ 8, 0, }, -+ }; -+ int ret; -+ -+ ret = rpi_firmware_property_list(vc4->firmware, &wh, sizeof(wh)); - -- ret = rpi_firmware_property(vc4->firmware, -- RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT, -- &wh, sizeof(wh)); - if (ret) { - DRM_ERROR("Failed to get screen size: %d (0x%08x 0x%08x)\n", -- ret, wh[0], wh[1]); -+ ret, wh.wh[0], wh.wh[1]); - return 0; - } - -- mode = drm_cvt_mode(dev, wh[0], wh[1], 60 /* vrefresh */, -+ mode = drm_cvt_mode(dev, wh.wh[0], wh.wh[1], 60 /* vrefresh */, - 0, 0, false); - drm_mode_probed_add(connector, mode); - -@@ -772,8 +786,9 @@ static const struct drm_connector_helper - .best_encoder = vc4_fkms_connector_best_encoder, - }; - --static struct drm_connector *vc4_fkms_connector_init(struct drm_device *dev, -- struct drm_encoder *encoder) -+static struct drm_connector * -+vc4_fkms_connector_init(struct drm_device *dev, struct drm_encoder *encoder, -+ u32 display_idx) - { - struct drm_connector *connector = NULL; - struct vc4_fkms_connector *fkms_connector; -@@ -788,6 +803,7 @@ static struct drm_connector *vc4_fkms_co - connector = &fkms_connector->base; - - fkms_connector->encoder = encoder; -+ fkms_connector->display_idx = display_idx; - - drm_connector_init(dev, connector, &vc4_fkms_connector_funcs, - DRM_MODE_CONNECTOR_HDMIA); -@@ -904,7 +920,8 @@ static int vc4_fkms_create_screen(struct - drm_encoder_helper_add(&vc4_encoder->base, - &vc4_fkms_encoder_helper_funcs); - -- vc4_crtc->connector = vc4_fkms_connector_init(drm, &vc4_encoder->base); -+ vc4_crtc->connector = vc4_fkms_connector_init(drm, &vc4_encoder->base, -+ display_idx); - if (IS_ERR(vc4_crtc->connector)) { - ret = PTR_ERR(vc4_crtc->connector); - goto err_destroy_encoder; diff --git a/target/linux/brcm2708/patches-4.19/950-0607-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch b/target/linux/brcm2708/patches-4.19/950-0607-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch new file mode 100644 index 0000000000..ec76ebe9d9 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0607-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch @@ -0,0 +1,47 @@ +From fc819de185dd2a0c7ff1846ee3ec64668f9163cc Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 10 Apr 2019 17:43:57 +0100 +Subject: [PATCH 607/725] drm: vc4: Bring fkms into line with kms in blocking + doublescan modes + +Implement vc4_crtc_mode_valid so that it blocks doublescan modes + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -625,7 +625,17 @@ static void vc4_crtc_enable(struct drm_c + vc4_plane_set_blank(plane, plane->state->visible); + } + ++static enum drm_mode_status ++vc4_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode) ++{ ++ /* Do not allow doublescan modes from user space */ ++ if (mode->flags & DRM_MODE_FLAG_DBLSCAN) { ++ DRM_DEBUG_KMS("[CRTC:%d] Doublescan mode rejected.\n", ++ crtc->base.id); ++ return MODE_NO_DBLESCAN; ++ } + ++ return MODE_OK; + } + + static int vc4_crtc_atomic_check(struct drm_crtc *crtc, +@@ -735,10 +745,11 @@ static const struct drm_crtc_funcs vc4_c + + static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = { + .mode_set_nofb = vc4_crtc_mode_set_nofb, +- .atomic_disable = vc4_crtc_disable, +- .atomic_enable = vc4_crtc_enable, ++ .mode_valid = vc4_crtc_mode_valid, + .atomic_check = vc4_crtc_atomic_check, + .atomic_flush = vc4_crtc_atomic_flush, ++ .atomic_enable = vc4_crtc_enable, ++ .atomic_disable = vc4_crtc_disable, + }; + + static const struct of_device_id vc4_firmware_kms_dt_match[] = { diff --git a/target/linux/brcm2708/patches-4.19/950-0607-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch b/target/linux/brcm2708/patches-4.19/950-0607-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch deleted file mode 100644 index a504012792..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0607-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 7129a308f4716a416f3e0fdd5f565457ed3bde03 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 9 Apr 2019 18:14:44 +0100 -Subject: [PATCH 607/703] drm: vc4: Need to call drm_crtc_vblank_[on|off] from - vc4_crtc_[en|dis]able - -vblank needs to be enabled and disabled by the driver to avoid the -DRM framework complaining in the kernel log. - -vc4_fkms_disable_vblank needs to signal that we don't want vblank -callbacks too. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -562,6 +562,8 @@ static void vc4_crtc_mode_set_nofb(struc - - static void vc4_crtc_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) - { -+ drm_crtc_vblank_off(crtc); -+ - /* Always turn the planes off on CRTC disable. In DRM, planes - * are enabled/disabled through the update/disable hooks - * above, and the CRTC enable/disable independently controls -@@ -577,6 +579,7 @@ static void vc4_crtc_disable(struct drm_ - - static void vc4_crtc_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) - { -+ drm_crtc_vblank_on(crtc); - /* Unblank the planes (if they're supposed to be displayed). */ - - if (crtc->primary->state->fb) -@@ -673,6 +676,9 @@ static int vc4_fkms_enable_vblank(struct - - static void vc4_fkms_disable_vblank(struct drm_crtc *crtc) - { -+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); -+ -+ vc4_crtc->vblank_enabled = false; - } - - static const struct drm_crtc_funcs vc4_crtc_funcs = { diff --git a/target/linux/brcm2708/patches-4.19/950-0608-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch b/target/linux/brcm2708/patches-4.19/950-0608-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch deleted file mode 100644 index 6d789b0893..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0608-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 9887c3c6ada2620592687b520e778980bc32c256 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 9 Apr 2019 17:19:51 +0100 -Subject: [PATCH 608/703] drm: vc4: Add support for H & V flips on each plane - for FKMS - -They are near zero cost options for the HVS, therefore they -may as well be implemented, and it allows us to invert the -DSI display. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 36 ++++++++++++++++++++++++++ - 1 file changed, 36 insertions(+) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -61,8 +61,21 @@ struct set_plane { - u8 padding; - - u32 planes[4]; /* DMA address of each plane */ -+ -+ u32 transform; - }; - -+/* Values for the transform field */ -+#define TRANSFORM_NO_ROTATE 0 -+#define TRANSFORM_ROTATE_180 BIT(1) -+#define TRANSFORM_FLIP_HRIZ BIT(16) -+#define TRANSFORM_FLIP_VERT BIT(17) -+ -+#define SUPPORTED_ROTATIONS (DRM_MODE_ROTATE_0 | \ -+ DRM_MODE_ROTATE_180 | \ -+ DRM_MODE_REFLECT_X | \ -+ DRM_MODE_REFLECT_Y) -+ - struct mailbox_set_plane { - struct rpi_firmware_property_tag_header tag; - struct set_plane plane; -@@ -274,6 +287,7 @@ static void vc4_plane_atomic_update(stru - struct vc4_crtc *vc4_crtc = to_vc4_crtc(state->crtc); - int num_planes = fb->format->num_planes; - struct drm_display_mode *mode = &state->crtc->mode; -+ unsigned int rotation = SUPPORTED_ROTATIONS; - - mb->plane.vc_image_type = vc_fmt->vc_image; - mb->plane.width = fb->width; -@@ -294,6 +308,24 @@ static void vc4_plane_atomic_update(stru - mb->plane.is_vu = vc_fmt->is_vu; - mb->plane.planes[0] = bo->paddr + fb->offsets[0]; - -+ rotation = drm_rotation_simplify(state->rotation, rotation); -+ -+ switch (rotation) { -+ default: -+ case DRM_MODE_ROTATE_0: -+ mb->plane.transform = TRANSFORM_NO_ROTATE; -+ break; -+ case DRM_MODE_ROTATE_180: -+ mb->plane.transform = TRANSFORM_ROTATE_180; -+ break; -+ case DRM_MODE_REFLECT_X: -+ mb->plane.transform = TRANSFORM_FLIP_HRIZ; -+ break; -+ case DRM_MODE_REFLECT_Y: -+ mb->plane.transform = TRANSFORM_FLIP_VERT; -+ break; -+ } -+ - /* FIXME: If the dest rect goes off screen then clip the src rect so we - * don't have off-screen pixels. - */ -@@ -514,9 +546,13 @@ static struct drm_plane *vc4_fkms_plane_ - formats, num_formats, modifiers, - type, NULL); - -+ /* FIXME: Do we need to be checking return values from all these calls? -+ */ - drm_plane_helper_add(plane, &vc4_plane_helper_funcs); - - drm_plane_create_alpha_property(plane); -+ drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0, -+ SUPPORTED_ROTATIONS); - - /* - * Default frame buffer setup is with FB on -127, and raspistill etc diff --git a/target/linux/brcm2708/patches-4.19/950-0608-drm-vc4-Increase-max_width-height-to-7680.patch b/target/linux/brcm2708/patches-4.19/950-0608-drm-vc4-Increase-max_width-height-to-7680.patch new file mode 100644 index 0000000000..44c7237ac4 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0608-drm-vc4-Increase-max_width-height-to-7680.patch @@ -0,0 +1,27 @@ +From f47b844c77068b837566f74e8872972ef880f834 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 29 Apr 2019 18:45:00 +0100 +Subject: [PATCH 608/725] drm: vc4: Increase max_width/height to 7680. + +There are some limits still being investigated that stop +us going up to 8192, but 7680 is sufficient for dual 4k +displays. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_kms.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_kms.c +@@ -429,8 +429,8 @@ int vc4_kms_load(struct drm_device *dev) + return ret; + } + +- dev->mode_config.max_width = 4096; +- dev->mode_config.max_height = 4096; ++ dev->mode_config.max_width = 7680; ++ dev->mode_config.max_height = 7680; + dev->mode_config.funcs = &vc4_mode_funcs; + dev->mode_config.preferred_depth = 24; + dev->mode_config.async_page_flip = true; diff --git a/target/linux/brcm2708/patches-4.19/950-0609-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch b/target/linux/brcm2708/patches-4.19/950-0609-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch new file mode 100644 index 0000000000..1b8315fcec --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0609-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch @@ -0,0 +1,557 @@ +From bd09766537994059c1d4a20762a6552dc0a62dae Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 9 Apr 2019 18:23:41 +0100 +Subject: [PATCH 609/725] drm: vc4: FKMS reads the EDID from fw, and supports + mode setting + +This extends FKMS to read the EDID from the display, and support +requesting a particular mode via KMS. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 334 ++++++++++++++++++--- + include/soc/bcm2835/raspberrypi-firmware.h | 2 + + 2 files changed, 302 insertions(+), 34 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -88,11 +88,60 @@ struct mailbox_blank_display { + u32 blank; + }; + +-struct mailbox_get_width_height { ++struct mailbox_get_edid { + struct rpi_firmware_property_tag_header tag1; +- u32 display; +- struct rpi_firmware_property_tag_header tag2; +- u32 wh[2]; ++ u32 block; ++ u32 display_number; ++ u8 edid[128]; ++}; ++ ++struct set_timings { ++ u8 display; ++ u8 padding; ++ u16 video_id_code; ++ ++ u32 clock; /* in kHz */ ++ ++ u16 hdisplay; ++ u16 hsync_start; ++ ++ u16 hsync_end; ++ u16 htotal; ++ ++ u16 hskew; ++ u16 vdisplay; ++ ++ u16 vsync_start; ++ u16 vsync_end; ++ ++ u16 vtotal; ++ u16 vscan; ++ ++ u16 vrefresh; ++ u16 padding2; ++ ++ u32 flags; ++#define TIMINGS_FLAGS_H_SYNC_POS BIT(0) ++#define TIMINGS_FLAGS_H_SYNC_NEG 0 ++#define TIMINGS_FLAGS_V_SYNC_POS BIT(1) ++#define TIMINGS_FLAGS_V_SYNC_NEG 0 ++ ++#define TIMINGS_FLAGS_ASPECT_MASK GENMASK(7, 4) ++#define TIMINGS_FLAGS_ASPECT_NONE (0 << 4) ++#define TIMINGS_FLAGS_ASPECT_4_3 (1 << 4) ++#define TIMINGS_FLAGS_ASPECT_16_9 (2 << 4) ++#define TIMINGS_FLAGS_ASPECT_64_27 (3 << 4) ++#define TIMINGS_FLAGS_ASPECT_256_135 (4 << 4) ++ ++/* Limited range RGB flag. Not set corresponds to full range. */ ++#define TIMINGS_FLAGS_RGB_LIMITED BIT(8) ++/* DVI monitor, therefore disable infoframes. Not set corresponds to HDMI. */ ++#define TIMINGS_FLAGS_DVI BIT(9) ++}; ++ ++struct mailbox_set_mode { ++ struct rpi_firmware_property_tag_header tag1; ++ struct set_timings timings; + }; + + static const struct vc_image_format { +@@ -186,6 +235,7 @@ struct vc4_crtc { + u32 overscan[4]; + bool vblank_enabled; + u32 display_number; ++ u32 display_type; + }; + + static inline struct vc4_crtc *to_vc4_crtc(struct drm_crtc *crtc) +@@ -195,6 +245,8 @@ static inline struct vc4_crtc *to_vc4_cr + + struct vc4_fkms_encoder { + struct drm_encoder base; ++ bool hdmi_monitor; ++ bool rgb_range_selectable; + }; + + static inline struct vc4_fkms_encoder * +@@ -212,7 +264,9 @@ struct vc4_fkms_connector { + * hook. + */ + struct drm_encoder *encoder; +- u32 display_idx; ++ struct vc4_dev *vc4_dev; ++ u32 display_number; ++ u32 display_type; + }; + + static inline struct vc4_fkms_connector * +@@ -221,6 +275,26 @@ to_vc4_fkms_connector(struct drm_connect + return container_of(connector, struct vc4_fkms_connector, base); + } + ++static u32 vc4_get_display_type(u32 display_number) ++{ ++ const u32 display_types[] = { ++ /* The firmware display (DispmanX) IDs map to specific types in ++ * a fixed manner. ++ */ ++ DRM_MODE_ENCODER_DSI, /* MAIN_LCD */ ++ DRM_MODE_ENCODER_DSI, /* AUX_LCD */ ++ DRM_MODE_ENCODER_TMDS, /* HDMI0 */ ++ DRM_MODE_ENCODER_TVDAC, /* VEC */ ++ DRM_MODE_ENCODER_NONE, /* FORCE_LCD */ ++ DRM_MODE_ENCODER_NONE, /* FORCE_TV */ ++ DRM_MODE_ENCODER_NONE, /* FORCE_OTHER */ ++ DRM_MODE_ENCODER_TMDS, /* HDMI1 */ ++ DRM_MODE_ENCODER_NONE, /* FORCE_TV2 */ ++ }; ++ return display_number > ARRAY_SIZE(display_types) - 1 ? ++ DRM_MODE_ENCODER_NONE : display_types[display_number]; ++} ++ + /* Firmware's structure for making an FB mbox call. */ + struct fbinfo_s { + u32 xres, yres, xres_virtual, yres_virtual; +@@ -255,10 +329,15 @@ static int vc4_plane_set_blank(struct dr + .plane_id = vc4_plane->mb.plane.plane_id, + } + }; ++ static const char * const plane_types[] = { ++ "overlay", ++ "primary", ++ "cursor" ++ }; + int ret; + +- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] overlay plane %s", +- plane->base.id, plane->name, ++ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] %s plane %s", ++ plane->base.id, plane->name, plane_types[plane->type], + blank ? "blank" : "unblank"); + + if (blank) +@@ -593,13 +672,102 @@ fail: + + static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc) + { +- /* Everyting is handled in the planes. */ ++ struct drm_device *dev = crtc->dev; ++ struct vc4_dev *vc4 = to_vc4_dev(dev); ++ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); ++ struct drm_display_mode *mode = &crtc->state->adjusted_mode; ++ struct vc4_fkms_encoder *vc4_encoder = ++ to_vc4_fkms_encoder(vc4_crtc->encoder); ++ struct mailbox_set_mode mb = { ++ .tag1 = { RPI_FIRMWARE_SET_TIMING, ++ sizeof(struct set_timings), 0}, ++ }; ++ union hdmi_infoframe frame; ++ int ret; ++ ++ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false); ++ if (ret < 0) { ++ DRM_ERROR("couldn't fill AVI infoframe\n"); ++ return; ++ } ++ ++ DRM_DEBUG_KMS("Setting mode for display num %u mode name %s, clk %d, h(disp %d, start %d, end %d, total %d, skew %d) v(disp %d, start %d, end %d, total %d, scan %d), vrefresh %d, par %u\n", ++ vc4_crtc->display_number, mode->name, mode->clock, ++ mode->hdisplay, mode->hsync_start, mode->hsync_end, ++ mode->htotal, mode->hskew, mode->vdisplay, ++ mode->vsync_start, mode->vsync_end, mode->vtotal, ++ mode->vscan, mode->vrefresh, mode->picture_aspect_ratio); ++ mb.timings.display = vc4_crtc->display_number; ++ ++ mb.timings.video_id_code = frame.avi.video_code; ++ ++ mb.timings.clock = mode->clock; ++ mb.timings.hdisplay = mode->hdisplay; ++ mb.timings.hsync_start = mode->hsync_start; ++ mb.timings.hsync_end = mode->hsync_end; ++ mb.timings.htotal = mode->htotal; ++ mb.timings.hskew = mode->hskew; ++ mb.timings.vdisplay = mode->vdisplay; ++ mb.timings.vsync_start = mode->vsync_start; ++ mb.timings.vsync_end = mode->vsync_end; ++ mb.timings.vtotal = mode->vtotal; ++ mb.timings.vscan = mode->vscan; ++ mb.timings.vrefresh = 0; ++ mb.timings.flags = 0; ++ if (mode->flags & DRM_MODE_FLAG_PHSYNC) ++ mb.timings.flags |= TIMINGS_FLAGS_H_SYNC_POS; ++ if (mode->flags & DRM_MODE_FLAG_PVSYNC) ++ mb.timings.flags |= TIMINGS_FLAGS_V_SYNC_POS; ++ ++ switch (frame.avi.picture_aspect) { ++ default: ++ case HDMI_PICTURE_ASPECT_NONE: ++ mode->flags |= TIMINGS_FLAGS_ASPECT_NONE; ++ break; ++ case HDMI_PICTURE_ASPECT_4_3: ++ mode->flags |= TIMINGS_FLAGS_ASPECT_4_3; ++ break; ++ case HDMI_PICTURE_ASPECT_16_9: ++ mode->flags |= TIMINGS_FLAGS_ASPECT_16_9; ++ break; ++ case HDMI_PICTURE_ASPECT_64_27: ++ mode->flags |= TIMINGS_FLAGS_ASPECT_64_27; ++ break; ++ case HDMI_PICTURE_ASPECT_256_135: ++ mode->flags |= TIMINGS_FLAGS_ASPECT_256_135; ++ break; ++ } ++ ++ if (!vc4_encoder->hdmi_monitor) ++ mb.timings.flags |= TIMINGS_FLAGS_DVI; ++ else if (drm_default_rgb_quant_range(mode) == ++ HDMI_QUANTIZATION_RANGE_LIMITED) ++ mb.timings.flags |= TIMINGS_FLAGS_RGB_LIMITED; ++ ++ /* ++ FIXME: To implement ++ switch(mode->flag & DRM_MODE_FLAG_3D_MASK) { ++ case DRM_MODE_FLAG_3D_NONE: ++ case DRM_MODE_FLAG_3D_FRAME_PACKING: ++ case DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE: ++ case DRM_MODE_FLAG_3D_LINE_ALTERNATIVE: ++ case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL: ++ case DRM_MODE_FLAG_3D_L_DEPTH: ++ case DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH: ++ case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM: ++ case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF: ++ } ++ */ ++ ++ ret = rpi_firmware_property_list(vc4->firmware, &mb, sizeof(mb)); + } + + static void vc4_crtc_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) + { + struct drm_plane *plane; + ++ DRM_DEBUG_KMS("[CRTC:%d] vblanks off.\n", ++ crtc->base.id); + drm_crtc_vblank_off(crtc); + + /* Always turn the planes off on CRTC disable. In DRM, planes +@@ -617,6 +785,8 @@ static void vc4_crtc_enable(struct drm_c + { + struct drm_plane *plane; + ++ DRM_DEBUG_KMS("[CRTC:%d] vblanks on.\n", ++ crtc->base.id); + drm_crtc_vblank_on(crtc); + + /* Unblank the planes (if they're supposed to be displayed). */ +@@ -635,12 +805,20 @@ vc4_crtc_mode_valid(struct drm_crtc *crt + return MODE_NO_DBLESCAN; + } + ++ /* Limit the pixel clock until we can get dynamic HDMI 2.0 scrambling ++ * working. ++ */ ++ if (mode->clock > 340000) ++ return MODE_CLOCK_HIGH; ++ + return MODE_OK; + } + + static int vc4_crtc_atomic_check(struct drm_crtc *crtc, + struct drm_crtc_state *state) + { ++ DRM_DEBUG_KMS("[CRTC:%d] crtc_atomic_check.\n", ++ crtc->base.id); + return 0; + } + +@@ -650,6 +828,8 @@ static void vc4_crtc_atomic_flush(struct + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); + struct drm_device *dev = crtc->dev; + ++ DRM_DEBUG_KMS("[CRTC:%d] crtc_atomic_flush.\n", ++ crtc->base.id); + if (crtc->state->event) { + unsigned long flags; + +@@ -717,6 +897,8 @@ static int vc4_fkms_enable_vblank(struct + { + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); + ++ DRM_DEBUG_KMS("[CRTC:%d] enable_vblank.\n", ++ crtc->base.id); + vc4_crtc->vblank_enabled = true; + + return 0; +@@ -726,6 +908,8 @@ static void vc4_fkms_disable_vblank(stru + { + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); + ++ DRM_DEBUG_KMS("[CRTC:%d] disable_vblank.\n", ++ crtc->base.id); + vc4_crtc->vblank_enabled = false; + } + +@@ -760,36 +944,92 @@ static const struct of_device_id vc4_fir + static enum drm_connector_status + vc4_fkms_connector_detect(struct drm_connector *connector, bool force) + { ++ DRM_DEBUG_KMS("connector detect.\n"); + return connector_status_connected; + } + +-static int vc4_fkms_connector_get_modes(struct drm_connector *connector) ++static int vc4_fkms_get_edid_block(void *data, u8 *buf, unsigned int block, ++ size_t len) + { +- struct drm_device *dev = connector->dev; + struct vc4_fkms_connector *fkms_connector = +- to_vc4_fkms_connector(connector); +- struct vc4_dev *vc4 = to_vc4_dev(dev); +- struct drm_display_mode *mode; +- struct mailbox_get_width_height wh = { +- .tag1 = {RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM, 4, 0, }, +- .display = fkms_connector->display_idx, +- .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT, +- 8, 0, }, ++ (struct vc4_fkms_connector *)data; ++ struct vc4_dev *vc4 = fkms_connector->vc4_dev; ++ struct mailbox_get_edid mb = { ++ .tag1 = { RPI_FIRMWARE_GET_EDID_BLOCK_DISPLAY, ++ 128 + 8, 0 }, ++ .block = block, ++ .display_number = fkms_connector->display_number, + }; +- int ret; ++ int ret = 0; ++ ++ ret = rpi_firmware_property_list(vc4->firmware, &mb, sizeof(mb)); ++ ++ if (!ret) ++ memcpy(buf, mb.edid, len); ++ ++ return ret; ++} ++ ++static int vc4_fkms_connector_get_modes(struct drm_connector *connector) ++{ ++ struct vc4_fkms_connector *fkms_connector = ++ to_vc4_fkms_connector(connector); ++ struct drm_encoder *encoder = fkms_connector->encoder; ++ struct vc4_fkms_encoder *vc4_encoder = to_vc4_fkms_encoder(encoder); ++ int ret = 0; ++ struct edid *edid; ++ ++ edid = drm_do_get_edid(connector, vc4_fkms_get_edid_block, ++ fkms_connector); ++ ++ /* FIXME: Can we do CEC? ++ * cec_s_phys_addr_from_edid(vc4->hdmi->cec_adap, edid); ++ * if (!edid) ++ * return -ENODEV; ++ */ ++ ++ vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid); + +- ret = rpi_firmware_property_list(vc4->firmware, &wh, sizeof(wh)); ++ if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) { ++ vc4_encoder->rgb_range_selectable = ++ drm_rgb_quant_range_selectable(edid); ++ } ++ ++ drm_connector_update_edid_property(connector, edid); ++ ret = drm_add_edid_modes(connector, edid); ++ kfree(edid); ++ ++ return ret; ++} ++ ++/* FIXME: Read LCD mode from the firmware. This is the DSI panel resolution. */ ++static const struct drm_display_mode lcd_mode = { ++ DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, ++ 25979400 / 1000, ++ 800, 800 + 1, 800 + 1 + 2, 800 + 1 + 2 + 46, 0, ++ 480, 480 + 7, 480 + 7 + 2, 480 + 7 + 2 + 21, 0, ++ DRM_MODE_FLAG_INTERLACE) ++}; ++ ++static int vc4_fkms_lcd_connector_get_modes(struct drm_connector *connector) ++{ ++ //struct vc4_fkms_connector *fkms_connector = ++ // to_vc4_fkms_connector(connector); ++ //struct drm_encoder *encoder = fkms_connector->encoder; ++ //struct vc4_fkms_encoder *vc4_encoder = to_vc4_fkms_encoder(encoder); ++ struct drm_display_mode *mode; ++ //int ret = 0; + +- if (ret) { +- DRM_ERROR("Failed to get screen size: %d (0x%08x 0x%08x)\n", +- ret, wh.wh[0], wh.wh[1]); +- return 0; ++ mode = drm_mode_duplicate(connector->dev, ++ &lcd_mode); ++ if (!mode) { ++ DRM_ERROR("Failed to create a new display mode\n"); ++ return -ENOMEM; + } + +- mode = drm_cvt_mode(dev, wh.wh[0], wh.wh[1], 60 /* vrefresh */, +- 0, 0, false); + drm_mode_probed_add(connector, mode); + ++ /* We have one mode */ + return 1; + } + +@@ -798,11 +1038,14 @@ vc4_fkms_connector_best_encoder(struct d + { + struct vc4_fkms_connector *fkms_connector = + to_vc4_fkms_connector(connector); ++ DRM_DEBUG_KMS("best_connector.\n"); + return fkms_connector->encoder; + } + + static void vc4_fkms_connector_destroy(struct drm_connector *connector) + { ++ DRM_DEBUG_KMS("[CONNECTOR:%d] destroy.\n", ++ connector->base.id); + drm_connector_unregister(connector); + drm_connector_cleanup(connector); + } +@@ -821,14 +1064,22 @@ static const struct drm_connector_helper + .best_encoder = vc4_fkms_connector_best_encoder, + }; + ++static const struct drm_connector_helper_funcs vc4_fkms_lcd_conn_helper_funcs = { ++ .get_modes = vc4_fkms_lcd_connector_get_modes, ++ .best_encoder = vc4_fkms_connector_best_encoder, ++}; ++ + static struct drm_connector * + vc4_fkms_connector_init(struct drm_device *dev, struct drm_encoder *encoder, +- u32 display_idx) ++ u32 display_num) + { + struct drm_connector *connector = NULL; + struct vc4_fkms_connector *fkms_connector; ++ struct vc4_dev *vc4_dev = to_vc4_dev(dev); + int ret = 0; + ++ DRM_DEBUG_KMS("connector_init, display_num %u\n", display_num); ++ + fkms_connector = devm_kzalloc(dev->dev, sizeof(*fkms_connector), + GFP_KERNEL); + if (!fkms_connector) { +@@ -838,11 +1089,21 @@ vc4_fkms_connector_init(struct drm_devic + connector = &fkms_connector->base; + + fkms_connector->encoder = encoder; +- fkms_connector->display_idx = display_idx; +- +- drm_connector_init(dev, connector, &vc4_fkms_connector_funcs, +- DRM_MODE_CONNECTOR_HDMIA); +- drm_connector_helper_add(connector, &vc4_fkms_connector_helper_funcs); ++ fkms_connector->display_number = display_num; ++ fkms_connector->display_type = vc4_get_display_type(display_num); ++ fkms_connector->vc4_dev = vc4_dev; ++ ++ if (fkms_connector->display_type == DRM_MODE_ENCODER_DSI) { ++ drm_connector_init(dev, connector, &vc4_fkms_connector_funcs, ++ DRM_MODE_CONNECTOR_DSI); ++ drm_connector_helper_add(connector, ++ &vc4_fkms_lcd_conn_helper_funcs); ++ } else { ++ drm_connector_init(dev, connector, &vc4_fkms_connector_funcs, ++ DRM_MODE_CONNECTOR_HDMIA); ++ drm_connector_helper_add(connector, ++ &vc4_fkms_connector_helper_funcs); ++ } + + connector->polled = (DRM_CONNECTOR_POLL_CONNECT | + DRM_CONNECTOR_POLL_DISCONNECT); +@@ -863,6 +1124,7 @@ vc4_fkms_connector_init(struct drm_devic + + static void vc4_fkms_encoder_destroy(struct drm_encoder *encoder) + { ++ DRM_DEBUG_KMS("Encoder_destroy\n"); + drm_encoder_cleanup(encoder); + } + +@@ -872,10 +1134,12 @@ static const struct drm_encoder_funcs vc + + static void vc4_fkms_encoder_enable(struct drm_encoder *encoder) + { ++ DRM_DEBUG_KMS("Encoder_enable\n"); + } + + static void vc4_fkms_encoder_disable(struct drm_encoder *encoder) + { ++ DRM_DEBUG_KMS("Encoder_disable\n"); + } + + static const struct drm_encoder_helper_funcs vc4_fkms_encoder_helper_funcs = { +@@ -907,6 +1171,7 @@ static int vc4_fkms_create_screen(struct + crtc = &vc4_crtc->base; + + vc4_crtc->display_number = display_ref; ++ vc4_crtc->display_type = vc4_get_display_type(display_ref); + + /* Blank the firmware provided framebuffer */ + rpi_firmware_property_list(vc4->firmware, &blank, sizeof(blank)); +@@ -950,13 +1215,14 @@ static int vc4_fkms_create_screen(struct + return -ENOMEM; + vc4_crtc->encoder = &vc4_encoder->base; + vc4_encoder->base.possible_crtcs |= drm_crtc_mask(crtc) ; ++ + drm_encoder_init(drm, &vc4_encoder->base, &vc4_fkms_encoder_funcs, +- DRM_MODE_ENCODER_TMDS, NULL); ++ vc4_crtc->display_type, NULL); + drm_encoder_helper_add(&vc4_encoder->base, + &vc4_fkms_encoder_helper_funcs); + + vc4_crtc->connector = vc4_fkms_connector_init(drm, &vc4_encoder->base, +- display_idx); ++ display_ref); + if (IS_ERR(vc4_crtc->connector)) { + ret = PTR_ERR(vc4_crtc->connector); + goto err_destroy_encoder; +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -78,6 +78,7 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014, + RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020, + RPI_FIRMWARE_GET_CUSTOMER_OTP = 0x00030021, ++ RPI_FIRMWARE_GET_EDID_BLOCK_DISPLAY = 0x00030023, + RPI_FIRMWARE_GET_DOMAIN_STATE = 0x00030030, + RPI_FIRMWARE_GET_THROTTLED = 0x00030046, + RPI_FIRMWARE_GET_CLOCK_MEASURED = 0x00030047, +@@ -150,6 +151,7 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, + + RPI_FIRMWARE_SET_PLANE = 0x00048015, ++ RPI_FIRMWARE_SET_TIMING = 0x00048017, + + RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, + RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, diff --git a/target/linux/brcm2708/patches-4.19/950-0609-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch b/target/linux/brcm2708/patches-4.19/950-0609-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch deleted file mode 100644 index 2443c04d4b..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0609-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 335909eb24aba8b42738895ae2fe7d24c67ec466 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 10 Apr 2019 17:35:05 +0100 -Subject: [PATCH 609/703] drm: vc4: Remove unused vc4_fkms_cancel_page_flip - function - -"32a3dbe drm/vc4: Nuke preclose hook" removed vc4_cancel_page_flip, -but vc4_fkms_cancel_page_flip was still be added to with the -fkms driver, even though it was never called. -Nuke it too. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_drv.h | 1 - - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 20 -------------------- - 2 files changed, 21 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -724,7 +724,6 @@ extern const struct dma_fence_ops vc4_fe - - /* 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); - - /* vc4_gem.c */ - void vc4_gem_init(struct drm_device *dev); ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -739,26 +739,6 @@ static const struct drm_crtc_helper_func - .atomic_flush = vc4_crtc_atomic_flush, - }; - --/* Frees the page flip event when the DRM device is closed with the -- * event still outstanding. -- */ --void vc4_fkms_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file) --{ -- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); -- struct drm_device *dev = crtc->dev; -- unsigned long flags; -- -- spin_lock_irqsave(&dev->event_lock, flags); -- -- if (vc4_crtc->event && vc4_crtc->event->base.file_priv == file) { -- kfree(&vc4_crtc->event->base); -- drm_crtc_vblank_put(crtc); -- vc4_crtc->event = NULL; -- } -- -- spin_unlock_irqrestore(&dev->event_lock, flags); --} -- - static const struct of_device_id vc4_firmware_kms_dt_match[] = { - { .compatible = "raspberrypi,rpi-firmware-kms" }, - {} diff --git a/target/linux/brcm2708/patches-4.19/950-0610-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch b/target/linux/brcm2708/patches-4.19/950-0610-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch new file mode 100644 index 0000000000..fb33e0e12b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0610-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch @@ -0,0 +1,53 @@ +From acf164cd389fb272e51d90a381927e9bca67a113 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 2 May 2019 15:11:05 -0700 +Subject: [PATCH 610/725] clk: bcm2835: Add support for setting leaf clock + rates while running. + +As long as you wait for !BUSY, you can do glitch-free updates of clock +rate while the clock is running. + +Signed-off-by: Eric Anholt +--- + drivers/clk/bcm/clk-bcm2835.c | 22 +++++++++++++--------- + 1 file changed, 13 insertions(+), 9 deletions(-) + +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -1097,15 +1097,19 @@ static int bcm2835_clock_set_rate(struct + + spin_lock(&cprman->regs_lock); + +- /* +- * Setting up frac support +- * +- * In principle it is recommended to stop/start the clock first, +- * but as we set CLK_SET_RATE_GATE during registration of the +- * clock this requirement should be take care of by the +- * clk-framework. ++ ctl = cprman_read(cprman, data->ctl_reg); ++ ++ /* If the clock is running, we have to pause clock generation while ++ * updating the control and div regs. This is glitchless (no clock ++ * signals generated faster than the rate) but each reg access is two ++ * OSC cycles so the clock will slow down for a moment. + */ +- ctl = cprman_read(cprman, data->ctl_reg) & ~CM_FRAC; ++ if (ctl & CM_ENABLE) { ++ cprman_write(cprman, data->ctl_reg, ctl & ~CM_ENABLE); ++ bcm2835_clock_wait_busy(clock); ++ } ++ ++ ctl &= ~CM_FRAC; + ctl |= (div & CM_DIV_FRAC_MASK) ? CM_FRAC : 0; + cprman_write(cprman, data->ctl_reg, ctl); + +@@ -1475,7 +1479,7 @@ static struct clk_hw *bcm2835_register_c + init.ops = &bcm2835_vpu_clock_clk_ops; + } else { + init.ops = &bcm2835_clock_clk_ops; +- init.flags |= CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; ++ init.flags |= CLK_SET_PARENT_GATE; + + /* If the clock wasn't actually enabled at boot, it's not + * critical. diff --git a/target/linux/brcm2708/patches-4.19/950-0610-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch b/target/linux/brcm2708/patches-4.19/950-0610-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch deleted file mode 100644 index 42c1a93f65..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0610-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 1aadf149d0be5b0cab5425845a21cbfd35618119 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 10 Apr 2019 17:42:37 +0100 -Subject: [PATCH 610/703] drm: vc4: Iterate over all planes in - vc4_crtc_[dis|en]able - -Fixes a FIXME where the overlay plane wouldn't be restored. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 20 +++++++++++--------- - 1 file changed, 11 insertions(+), 9 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -598,6 +598,8 @@ static void vc4_crtc_mode_set_nofb(struc - - static void vc4_crtc_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) - { -+ struct drm_plane *plane; -+ - drm_crtc_vblank_off(crtc); - - /* Always turn the planes off on CRTC disable. In DRM, planes -@@ -607,23 +609,23 @@ static void vc4_crtc_disable(struct drm_ - * give us a CRTC-level control for that. - */ - -- vc4_plane_atomic_disable(crtc->cursor, crtc->cursor->state); -- vc4_plane_atomic_disable(crtc->primary, crtc->primary->state); -- -- /* FIXME: Disable overlay planes */ -+ drm_atomic_crtc_for_each_plane(plane, crtc) -+ vc4_plane_atomic_disable(plane, plane->state); - } - - static void vc4_crtc_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) - { -+ struct drm_plane *plane; -+ - drm_crtc_vblank_on(crtc); -+ - /* Unblank the planes (if they're supposed to be displayed). */ -+ drm_atomic_crtc_for_each_plane(plane, crtc) -+ if (plane->state->fb) -+ vc4_plane_set_blank(plane, plane->state->visible); -+} - -- if (crtc->primary->state->fb) -- vc4_plane_set_blank(crtc->primary, false); -- if (crtc->cursor->state->fb) -- vc4_plane_set_blank(crtc->cursor, crtc->cursor->state); - -- /* FIXME: Enable overlay planes */ - } - - static int vc4_crtc_atomic_check(struct drm_crtc *crtc, diff --git a/target/linux/brcm2708/patches-4.19/950-0611-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch b/target/linux/brcm2708/patches-4.19/950-0611-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch new file mode 100644 index 0000000000..90e6c4223b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0611-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch @@ -0,0 +1,71 @@ +From 356d46e6eb84700f12fa2d0a56c5c60dddbed67a Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 2 May 2019 15:24:04 -0700 +Subject: [PATCH 611/725] clk: bcm2835: Allow reparenting leaf clocks while + they're running. + +This falls under the same "we can reprogram glitch-free as long as we +pause generation" rule as updating the div/frac fields. This can be +used for runtime reclocking of V3D to manage power leakage. + +Signed-off-by: Eric Anholt +--- + drivers/clk/bcm/clk-bcm2835.c | 19 ++++++++++++++++--- + 1 file changed, 16 insertions(+), 3 deletions(-) + +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -1086,8 +1086,10 @@ static int bcm2835_clock_on(struct clk_h + return 0; + } + +-static int bcm2835_clock_set_rate(struct clk_hw *hw, +- unsigned long rate, unsigned long parent_rate) ++static int bcm2835_clock_set_rate_and_parent(struct clk_hw *hw, ++ unsigned long rate, ++ unsigned long parent_rate, ++ u8 parent) + { + struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); + struct bcm2835_cprman *cprman = clock->cprman; +@@ -1109,6 +1111,11 @@ static int bcm2835_clock_set_rate(struct + bcm2835_clock_wait_busy(clock); + } + ++ if (parent != 0xff) { ++ ctl &= ~(CM_SRC_MASK << CM_SRC_SHIFT); ++ ctl |= parent << CM_SRC_SHIFT; ++ } ++ + ctl &= ~CM_FRAC; + ctl |= (div & CM_DIV_FRAC_MASK) ? CM_FRAC : 0; + cprman_write(cprman, data->ctl_reg, ctl); +@@ -1120,6 +1127,12 @@ static int bcm2835_clock_set_rate(struct + return 0; + } + ++static int bcm2835_clock_set_rate(struct clk_hw *hw, ++ unsigned long rate, unsigned long parent_rate) ++{ ++ return bcm2835_clock_set_rate_and_parent(hw, rate, parent_rate, 0xff); ++} ++ + static bool + bcm2835_clk_is_pllc(struct clk_hw *hw) + { +@@ -1303,6 +1316,7 @@ static const struct clk_ops bcm2835_cloc + .unprepare = bcm2835_clock_off, + .recalc_rate = bcm2835_clock_get_rate, + .set_rate = bcm2835_clock_set_rate, ++ .set_rate_and_parent = bcm2835_clock_set_rate_and_parent, + .determine_rate = bcm2835_clock_determine_rate, + .set_parent = bcm2835_clock_set_parent, + .get_parent = bcm2835_clock_get_parent, +@@ -1479,7 +1493,6 @@ static struct clk_hw *bcm2835_register_c + init.ops = &bcm2835_vpu_clock_clk_ops; + } else { + init.ops = &bcm2835_clock_clk_ops; +- init.flags |= CLK_SET_PARENT_GATE; + + /* If the clock wasn't actually enabled at boot, it's not + * critical. diff --git a/target/linux/brcm2708/patches-4.19/950-0611-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch b/target/linux/brcm2708/patches-4.19/950-0611-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch deleted file mode 100644 index 54f44f0c3d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0611-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 6b36249bd9c3399d4b8552c7557406586dc31521 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 10 Apr 2019 17:43:57 +0100 -Subject: [PATCH 611/703] drm: vc4: Bring fkms into line with kms in blocking - doublescan modes - -Implement vc4_crtc_mode_valid so that it blocks doublescan modes - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 15 +++++++++++++-- - 1 file changed, 13 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -625,7 +625,17 @@ static void vc4_crtc_enable(struct drm_c - vc4_plane_set_blank(plane, plane->state->visible); - } - -+static enum drm_mode_status -+vc4_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode) -+{ -+ /* Do not allow doublescan modes from user space */ -+ if (mode->flags & DRM_MODE_FLAG_DBLSCAN) { -+ DRM_DEBUG_KMS("[CRTC:%d] Doublescan mode rejected.\n", -+ crtc->base.id); -+ return MODE_NO_DBLESCAN; -+ } - -+ return MODE_OK; - } - - static int vc4_crtc_atomic_check(struct drm_crtc *crtc, -@@ -735,10 +745,11 @@ static const struct drm_crtc_funcs vc4_c - - static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = { - .mode_set_nofb = vc4_crtc_mode_set_nofb, -- .atomic_disable = vc4_crtc_disable, -- .atomic_enable = vc4_crtc_enable, -+ .mode_valid = vc4_crtc_mode_valid, - .atomic_check = vc4_crtc_atomic_check, - .atomic_flush = vc4_crtc_atomic_flush, -+ .atomic_enable = vc4_crtc_enable, -+ .atomic_disable = vc4_crtc_disable, - }; - - static const struct of_device_id vc4_firmware_kms_dt_match[] = { diff --git a/target/linux/brcm2708/patches-4.19/950-0612-drm-v3d-Add-support-for-compute-shader-dispatch.patch b/target/linux/brcm2708/patches-4.19/950-0612-drm-v3d-Add-support-for-compute-shader-dispatch.patch new file mode 100644 index 0000000000..a26f7fcc77 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0612-drm-v3d-Add-support-for-compute-shader-dispatch.patch @@ -0,0 +1,897 @@ +From c1d46fee0b1f4711ffa9b6517a460cf5411aa0fc Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Tue, 16 Apr 2019 15:58:54 -0700 +Subject: [PATCH 612/725] drm/v3d: Add support for compute shader dispatch. + +The compute shader dispatch interface is pretty simple -- just pass in +the regs that userspace has passed us, with no CLs to run. However, +with no CL to run it means that we need to do manual cache flushing of +the L2 after the HW execution completes (for SSBO, atomic, and +image_load_store writes that are the output of compute shaders). + +This doesn't yet expose the L2 cache's ability to have a region of the +address space not write back to memory (which could be used for +shared_var storage). + +So far, the Mesa side has been tested on V3D v4.2 simpenrose (passing +the ES31 tests), and on the kernel side on 7278 (failing atomic +compswap tests in a way that doesn't reproduce on simpenrose). + +v2: Fix excessive allocation for the clean_job (reported by Dan + Carpenter). Keep refs on jobs until clean_job is finished, to + avoid spurious MMU errors if the output BOs are freed by userspace + before L2 cleaning is finished. + +Signed-off-by: Eric Anholt +Link: https://patchwork.freedesktop.org/patch/msgid/20190416225856.20264-4-eric@anholt.net +Acked-by: Rob Clark +--- + drivers/gpu/drm/v3d/v3d_debugfs.c | 22 +++++ + drivers/gpu/drm/v3d/v3d_drv.c | 10 +- + drivers/gpu/drm/v3d/v3d_drv.h | 28 +++++- + drivers/gpu/drm/v3d/v3d_fence.c | 2 + + drivers/gpu/drm/v3d/v3d_gem.c | 156 +++++++++++++++++++++++++++++- + drivers/gpu/drm/v3d/v3d_irq.c | 16 ++- + drivers/gpu/drm/v3d/v3d_regs.h | 73 ++++++++++++++ + drivers/gpu/drm/v3d/v3d_sched.c | 121 +++++++++++++++++++++-- + drivers/gpu/drm/v3d/v3d_trace.h | 94 ++++++++++++++++++ + include/uapi/drm/v3d_drm.h | 28 ++++++ + 10 files changed, 531 insertions(+), 19 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_debugfs.c ++++ b/drivers/gpu/drm/v3d/v3d_debugfs.c +@@ -57,6 +57,17 @@ static const struct v3d_reg_def v3d_core + REGDEF(V3D_GMP_VIO_ADDR), + }; + ++static const struct v3d_reg_def v3d_csd_reg_defs[] = { ++ REGDEF(V3D_CSD_STATUS), ++ REGDEF(V3D_CSD_CURRENT_CFG0), ++ REGDEF(V3D_CSD_CURRENT_CFG1), ++ REGDEF(V3D_CSD_CURRENT_CFG2), ++ REGDEF(V3D_CSD_CURRENT_CFG3), ++ REGDEF(V3D_CSD_CURRENT_CFG4), ++ REGDEF(V3D_CSD_CURRENT_CFG5), ++ REGDEF(V3D_CSD_CURRENT_CFG6), ++}; ++ + static int v3d_v3d_debugfs_regs(struct seq_file *m, void *unused) + { + struct drm_info_node *node = (struct drm_info_node *)m->private; +@@ -88,6 +99,17 @@ static int v3d_v3d_debugfs_regs(struct s + V3D_CORE_READ(core, + v3d_core_reg_defs[i].reg)); + } ++ ++ if (v3d_has_csd(v3d)) { ++ for (i = 0; i < ARRAY_SIZE(v3d_csd_reg_defs); i++) { ++ seq_printf(m, "core %d %s (0x%04x): 0x%08x\n", ++ core, ++ v3d_csd_reg_defs[i].name, ++ v3d_csd_reg_defs[i].reg, ++ V3D_CORE_READ(core, ++ v3d_csd_reg_defs[i].reg)); ++ } ++ } + } + + return 0; +--- a/drivers/gpu/drm/v3d/v3d_drv.c ++++ b/drivers/gpu/drm/v3d/v3d_drv.c +@@ -7,9 +7,9 @@ + * This driver supports the Broadcom V3D 3.3 and 4.1 OpenGL ES GPUs. + * For V3D 2.x support, see the VC4 driver. + * +- * Currently only single-core rendering using the binner and renderer, +- * along with TFU (texture formatting unit) rendering is supported. +- * V3D 4.x's CSD (compute shader dispatch) is not yet supported. ++ * The V3D GPU includes a tiled render (composed of a bin and render ++ * pipelines), the TFU (texture formatting unit), and the CSD (compute ++ * shader dispatch). + */ + + #include +@@ -114,6 +114,9 @@ static int v3d_get_param_ioctl(struct dr + case DRM_V3D_PARAM_SUPPORTS_TFU: + args->value = 1; + return 0; ++ case DRM_V3D_PARAM_SUPPORTS_CSD: ++ args->value = v3d_has_csd(v3d); ++ return 0; + default: + DRM_DEBUG("Unknown parameter %d\n", args->param); + return -EINVAL; +@@ -183,6 +186,7 @@ static const struct drm_ioctl_desc v3d_d + DRM_IOCTL_DEF_DRV(V3D_GET_PARAM, v3d_get_param_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(V3D_GET_BO_OFFSET, v3d_get_bo_offset_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(V3D_SUBMIT_TFU, v3d_submit_tfu_ioctl, DRM_RENDER_ALLOW | DRM_AUTH), ++ DRM_IOCTL_DEF_DRV(V3D_SUBMIT_CSD, v3d_submit_csd_ioctl, DRM_RENDER_ALLOW | DRM_AUTH), + }; + + static const struct vm_operations_struct v3d_vm_ops = { +--- a/drivers/gpu/drm/v3d/v3d_drv.h ++++ b/drivers/gpu/drm/v3d/v3d_drv.h +@@ -16,9 +16,11 @@ enum v3d_queue { + V3D_BIN, + V3D_RENDER, + V3D_TFU, ++ V3D_CSD, ++ V3D_CACHE_CLEAN, + }; + +-#define V3D_MAX_QUEUES (V3D_TFU + 1) ++#define V3D_MAX_QUEUES (V3D_CACHE_CLEAN + 1) + + struct v3d_queue_state { + struct drm_gpu_scheduler sched; +@@ -70,6 +72,7 @@ struct v3d_dev { + struct v3d_bin_job *bin_job; + struct v3d_render_job *render_job; + struct v3d_tfu_job *tfu_job; ++ struct v3d_csd_job *csd_job; + + struct v3d_queue_state queue[V3D_MAX_QUEUES]; + +@@ -92,6 +95,12 @@ struct v3d_dev { + */ + struct mutex sched_lock; + ++ /* Lock taken during a cache clean and when initiating an L2 ++ * flush, to keep L2 flushes from interfering with the ++ * synchronous L2 cleans. ++ */ ++ struct mutex cache_clean_lock; ++ + struct { + u32 num_allocated; + u32 pages_allocated; +@@ -104,6 +113,12 @@ to_v3d_dev(struct drm_device *dev) + return (struct v3d_dev *)dev->dev_private; + } + ++static inline bool ++v3d_has_csd(struct v3d_dev *v3d) ++{ ++ return v3d->ver >= 41; ++} ++ + /* The per-fd struct, which tracks the MMU mappings. */ + struct v3d_file_priv { + struct v3d_dev *v3d; +@@ -237,6 +252,14 @@ struct v3d_tfu_job { + struct drm_v3d_submit_tfu args; + }; + ++struct v3d_csd_job { ++ struct v3d_job base; ++ ++ u32 timedout_batches; ++ ++ struct drm_v3d_submit_csd args; ++}; ++ + /** + * _wait_for - magic (register) wait macro + * +@@ -302,11 +325,14 @@ int v3d_submit_cl_ioctl(struct drm_devic + struct drm_file *file_priv); + int v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); ++int v3d_submit_csd_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); + int v3d_wait_bo_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + void v3d_job_put(struct v3d_job *job); + void v3d_reset(struct v3d_dev *v3d); + void v3d_invalidate_caches(struct v3d_dev *v3d); ++void v3d_clean_caches(struct v3d_dev *v3d); + + /* v3d_irq.c */ + int v3d_irq_init(struct v3d_dev *v3d); +--- a/drivers/gpu/drm/v3d/v3d_fence.c ++++ b/drivers/gpu/drm/v3d/v3d_fence.c +@@ -36,6 +36,8 @@ static const char *v3d_fence_get_timelin + return "v3d-render"; + case V3D_TFU: + return "v3d-tfu"; ++ case V3D_CSD: ++ return "v3d-csd"; + default: + return NULL; + } +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -162,10 +162,52 @@ v3d_flush_l2t(struct v3d_dev *v3d, int c + /* While there is a busy bit (V3D_L2TCACTL_L2TFLS), we don't + * need to wait for completion before dispatching the job -- + * L2T accesses will be stalled until the flush has completed. ++ * However, we do need to make sure we don't try to trigger a ++ * new flush while the L2_CLEAN queue is trying to ++ * synchronously clean after a job. + */ ++ mutex_lock(&v3d->cache_clean_lock); + V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, + V3D_L2TCACTL_L2TFLS | + V3D_SET_FIELD(V3D_L2TCACTL_FLM_FLUSH, V3D_L2TCACTL_FLM)); ++ mutex_unlock(&v3d->cache_clean_lock); ++} ++ ++/* Cleans texture L1 and L2 cachelines (writing back dirty data). ++ * ++ * For cleaning, which happens from the CACHE_CLEAN queue after CSD has ++ * executed, we need to make sure that the clean is done before ++ * signaling job completion. So, we synchronously wait before ++ * returning, and we make sure that L2 invalidates don't happen in the ++ * meantime to confuse our are-we-done checks. ++ */ ++void ++v3d_clean_caches(struct v3d_dev *v3d) ++{ ++ struct drm_device *dev = &v3d->drm; ++ int core = 0; ++ ++ trace_v3d_cache_clean_begin(dev); ++ ++ V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, V3D_L2TCACTL_TMUWCF); ++ if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) & ++ V3D_L2TCACTL_L2TFLS), 100)) { ++ DRM_ERROR("Timeout waiting for L1T write combiner flush\n"); ++ } ++ ++ mutex_lock(&v3d->cache_clean_lock); ++ V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, ++ V3D_L2TCACTL_L2TFLS | ++ V3D_SET_FIELD(V3D_L2TCACTL_FLM_CLEAN, V3D_L2TCACTL_FLM)); ++ ++ if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) & ++ V3D_L2TCACTL_L2TFLS), 100)) { ++ DRM_ERROR("Timeout waiting for L2T clean\n"); ++ } ++ ++ mutex_unlock(&v3d->cache_clean_lock); ++ ++ trace_v3d_cache_clean_end(dev); + } + + /* Invalidates the slice caches. These are read-only caches. */ +@@ -584,7 +626,8 @@ static void + v3d_attach_fences_and_unlock_reservation(struct drm_file *file_priv, + struct v3d_job *job, + struct ww_acquire_ctx *acquire_ctx, +- u32 out_sync) ++ u32 out_sync, ++ struct dma_fence *done_fence) + { + struct drm_syncobj *sync_out; + +@@ -594,7 +637,7 @@ v3d_attach_fences_and_unlock_reservation + /* Update the return sync object for the job */ + sync_out = drm_syncobj_find(file_priv, out_sync); + if (sync_out) { +- drm_syncobj_replace_fence(sync_out, job->done_fence); ++ drm_syncobj_replace_fence(sync_out, done_fence); + drm_syncobj_put(sync_out); + } + } +@@ -691,8 +734,10 @@ v3d_submit_cl_ioctl(struct drm_device *d + mutex_unlock(&v3d->sched_lock); + + v3d_attach_fences_and_unlock_reservation(file_priv, +- &render->base, &acquire_ctx, +- args->out_sync); ++ &render->base, ++ &acquire_ctx, ++ args->out_sync, ++ render->base.done_fence); + + if (bin) + v3d_job_put(&bin->base); +@@ -785,7 +830,8 @@ v3d_submit_tfu_ioctl(struct drm_device * + + v3d_attach_fences_and_unlock_reservation(file_priv, + &job->base, &acquire_ctx, +- args->out_sync); ++ args->out_sync, ++ job->base.done_fence); + + v3d_job_put(&job->base); + +@@ -801,6 +847,105 @@ fail: + return ret; + } + ++/** ++ * v3d_submit_csd_ioctl() - Submits a CSD (texture formatting) job to the V3D. ++ * @dev: DRM device ++ * @data: ioctl argument ++ * @file_priv: DRM file for this fd ++ * ++ * Userspace provides the register setup for the CSD, which we don't ++ * need to validate since the CSD is behind the MMU. ++ */ ++int ++v3d_submit_csd_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct v3d_dev *v3d = to_v3d_dev(dev); ++ struct v3d_file_priv *v3d_priv = file_priv->driver_priv; ++ struct drm_v3d_submit_csd *args = data; ++ struct v3d_csd_job *job; ++ struct v3d_job *clean_job; ++ struct ww_acquire_ctx acquire_ctx; ++ int ret; ++ ++ trace_v3d_submit_csd_ioctl(&v3d->drm, args->cfg[5], args->cfg[6]); ++ ++ if (!v3d_has_csd(v3d)) { ++ DRM_DEBUG("Attempting CSD submit on non-CSD hardware\n"); ++ return -EINVAL; ++ } ++ ++ job = kcalloc(1, sizeof(*job), GFP_KERNEL); ++ if (!job) ++ return -ENOMEM; ++ ++ ret = v3d_job_init(v3d, file_priv, &job->base, ++ v3d_job_free, args->in_sync); ++ if (ret) { ++ kfree(job); ++ return ret; ++ } ++ ++ clean_job = kcalloc(1, sizeof(*clean_job), GFP_KERNEL); ++ if (!clean_job) { ++ v3d_job_put(&job->base); ++ kfree(job); ++ return -ENOMEM; ++ } ++ ++ ret = v3d_job_init(v3d, file_priv, clean_job, v3d_job_free, 0); ++ if (ret) { ++ v3d_job_put(&job->base); ++ kfree(clean_job); ++ return ret; ++ } ++ ++ job->args = *args; ++ ++ ret = v3d_lookup_bos(dev, file_priv, clean_job, ++ args->bo_handles, args->bo_handle_count); ++ if (ret) ++ goto fail; ++ ++ ret = v3d_lock_bo_reservations(clean_job, &acquire_ctx); ++ if (ret) ++ goto fail; ++ ++ mutex_lock(&v3d->sched_lock); ++ ret = v3d_push_job(v3d_priv, &job->base, V3D_CSD); ++ if (ret) ++ goto fail_unreserve; ++ ++ ret = v3d_add_dep(clean_job, dma_fence_get(job->base.done_fence)); ++ if (ret) ++ goto fail_unreserve; ++ ret = v3d_push_job(v3d_priv, clean_job, V3D_CACHE_CLEAN); ++ if (ret) ++ goto fail_unreserve; ++ mutex_unlock(&v3d->sched_lock); ++ ++ v3d_attach_fences_and_unlock_reservation(file_priv, ++ clean_job, ++ &acquire_ctx, ++ args->out_sync, ++ clean_job->done_fence); ++ ++ v3d_job_put(&job->base); ++ v3d_job_put(clean_job); ++ ++ return 0; ++ ++fail_unreserve: ++ mutex_unlock(&v3d->sched_lock); ++ v3d_unlock_bo_reservations(clean_job->bo, clean_job->bo_count, ++ &acquire_ctx); ++fail: ++ v3d_job_put(&job->base); ++ v3d_job_put(clean_job); ++ ++ return ret; ++} ++ + int + v3d_gem_init(struct drm_device *dev) + { +@@ -816,6 +961,7 @@ v3d_gem_init(struct drm_device *dev) + mutex_init(&v3d->bo_lock); + mutex_init(&v3d->reset_lock); + mutex_init(&v3d->sched_lock); ++ mutex_init(&v3d->cache_clean_lock); + + /* Note: We don't allocate address 0. Various bits of HW + * treat 0 as special, such as the occlusion query counters +--- a/drivers/gpu/drm/v3d/v3d_irq.c ++++ b/drivers/gpu/drm/v3d/v3d_irq.c +@@ -4,9 +4,9 @@ + /** + * DOC: Interrupt management for the V3D engine + * +- * When we take a bin, render, or TFU done interrupt, we need to +- * signal the fence for that job so that the scheduler can queue up +- * the next one and unblock any waiters. ++ * When we take a bin, render, TFU done, or CSD done interrupt, we ++ * need to signal the fence for that job so that the scheduler can ++ * queue up the next one and unblock any waiters. + * + * When we take the binner out of memory interrupt, we need to + * allocate some new memory and pass it to the binner so that the +@@ -20,6 +20,7 @@ + #define V3D_CORE_IRQS ((u32)(V3D_INT_OUTOMEM | \ + V3D_INT_FLDONE | \ + V3D_INT_FRDONE | \ ++ V3D_INT_CSDDONE | \ + V3D_INT_GMPV)) + + #define V3D_HUB_IRQS ((u32)(V3D_HUB_INT_MMU_WRV | \ +@@ -108,6 +109,15 @@ v3d_irq(int irq, void *arg) + dma_fence_signal(&fence->base); + status = IRQ_HANDLED; + } ++ ++ if (intsts & V3D_INT_CSDDONE) { ++ struct v3d_fence *fence = ++ to_v3d_fence(v3d->csd_job->base.irq_fence); ++ ++ trace_v3d_csd_irq(&v3d->drm, fence->seqno); ++ dma_fence_signal(&fence->base); ++ status = IRQ_HANDLED; ++ } + + /* We shouldn't be triggering these if we have GMP in + * always-allowed mode. +--- a/drivers/gpu/drm/v3d/v3d_regs.h ++++ b/drivers/gpu/drm/v3d/v3d_regs.h +@@ -238,8 +238,11 @@ + #define V3D_CTL_L2TCACTL 0x00030 + # define V3D_L2TCACTL_TMUWCF BIT(8) + # define V3D_L2TCACTL_L2T_NO_WM BIT(4) ++/* Invalidates cache lines. */ + # define V3D_L2TCACTL_FLM_FLUSH 0 ++/* Removes cachelines without writing dirty lines back. */ + # define V3D_L2TCACTL_FLM_CLEAR 1 ++/* Writes out dirty cachelines and marks them clean, but doesn't invalidate. */ + # define V3D_L2TCACTL_FLM_CLEAN 2 + # define V3D_L2TCACTL_FLM_MASK V3D_MASK(2, 1) + # define V3D_L2TCACTL_FLM_SHIFT 1 +@@ -255,6 +258,8 @@ + #define V3D_CTL_INT_MSK_CLR 0x00064 + # define V3D_INT_QPU_MASK V3D_MASK(27, 16) + # define V3D_INT_QPU_SHIFT 16 ++# define V3D_INT_CSDDONE BIT(7) ++# define V3D_INT_PCTR BIT(6) + # define V3D_INT_GMPV BIT(5) + # define V3D_INT_TRFB BIT(4) + # define V3D_INT_SPILLUSE BIT(3) +@@ -374,4 +379,72 @@ + #define V3D_GMP_PRESERVE_LOAD 0x00818 + #define V3D_GMP_VALID_LINES 0x00820 + ++#define V3D_CSD_STATUS 0x00900 ++# define V3D_CSD_STATUS_NUM_COMPLETED_MASK V3D_MASK(11, 4) ++# define V3D_CSD_STATUS_NUM_COMPLETED_SHIFT 4 ++# define V3D_CSD_STATUS_NUM_ACTIVE_MASK V3D_MASK(3, 2) ++# define V3D_CSD_STATUS_NUM_ACTIVE_SHIFT 2 ++# define V3D_CSD_STATUS_HAVE_CURRENT_DISPATCH BIT(1) ++# define V3D_CSD_STATUS_HAVE_QUEUED_DISPATCH BIT(0) ++ ++#define V3D_CSD_QUEUED_CFG0 0x00904 ++# define V3D_CSD_QUEUED_CFG0_NUM_WGS_X_MASK V3D_MASK(31, 16) ++# define V3D_CSD_QUEUED_CFG0_NUM_WGS_X_SHIFT 16 ++# define V3D_CSD_QUEUED_CFG0_WG_X_OFFSET_MASK V3D_MASK(15, 0) ++# define V3D_CSD_QUEUED_CFG0_WG_X_OFFSET_SHIFT 0 ++ ++#define V3D_CSD_QUEUED_CFG1 0x00908 ++# define V3D_CSD_QUEUED_CFG1_NUM_WGS_Y_MASK V3D_MASK(31, 16) ++# define V3D_CSD_QUEUED_CFG1_NUM_WGS_Y_SHIFT 16 ++# define V3D_CSD_QUEUED_CFG1_WG_Y_OFFSET_MASK V3D_MASK(15, 0) ++# define V3D_CSD_QUEUED_CFG1_WG_Y_OFFSET_SHIFT 0 ++ ++#define V3D_CSD_QUEUED_CFG2 0x0090c ++# define V3D_CSD_QUEUED_CFG2_NUM_WGS_Z_MASK V3D_MASK(31, 16) ++# define V3D_CSD_QUEUED_CFG2_NUM_WGS_Z_SHIFT 16 ++# define V3D_CSD_QUEUED_CFG2_WG_Z_OFFSET_MASK V3D_MASK(15, 0) ++# define V3D_CSD_QUEUED_CFG2_WG_Z_OFFSET_SHIFT 0 ++ ++#define V3D_CSD_QUEUED_CFG3 0x00910 ++# define V3D_CSD_QUEUED_CFG3_OVERLAP_WITH_PREV BIT(26) ++# define V3D_CSD_QUEUED_CFG3_MAX_SG_ID_MASK V3D_MASK(25, 20) ++# define V3D_CSD_QUEUED_CFG3_MAX_SG_ID_SHIFT 20 ++# define V3D_CSD_QUEUED_CFG3_BATCHES_PER_SG_M1_MASK V3D_MASK(19, 12) ++# define V3D_CSD_QUEUED_CFG3_BATCHES_PER_SG_M1_SHIFT 12 ++# define V3D_CSD_QUEUED_CFG3_WGS_PER_SG_MASK V3D_MASK(11, 8) ++# define V3D_CSD_QUEUED_CFG3_WGS_PER_SG_SHIFT 8 ++# define V3D_CSD_QUEUED_CFG3_WG_SIZE_MASK V3D_MASK(7, 0) ++# define V3D_CSD_QUEUED_CFG3_WG_SIZE_SHIFT 0 ++ ++/* Number of batches, minus 1 */ ++#define V3D_CSD_QUEUED_CFG4 0x00914 ++ ++/* Shader address, pnan, singleseg, threading, like a shader record. */ ++#define V3D_CSD_QUEUED_CFG5 0x00918 ++ ++/* Uniforms address (4 byte aligned) */ ++#define V3D_CSD_QUEUED_CFG6 0x0091c ++ ++#define V3D_CSD_CURRENT_CFG0 0x00920 ++#define V3D_CSD_CURRENT_CFG1 0x00924 ++#define V3D_CSD_CURRENT_CFG2 0x00928 ++#define V3D_CSD_CURRENT_CFG3 0x0092c ++#define V3D_CSD_CURRENT_CFG4 0x00930 ++#define V3D_CSD_CURRENT_CFG5 0x00934 ++#define V3D_CSD_CURRENT_CFG6 0x00938 ++ ++#define V3D_CSD_CURRENT_ID0 0x0093c ++# define V3D_CSD_CURRENT_ID0_WG_X_MASK V3D_MASK(31, 16) ++# define V3D_CSD_CURRENT_ID0_WG_X_SHIFT 16 ++# define V3D_CSD_CURRENT_ID0_WG_IN_SG_MASK V3D_MASK(11, 8) ++# define V3D_CSD_CURRENT_ID0_WG_IN_SG_SHIFT 8 ++# define V3D_CSD_CURRENT_ID0_L_IDX_MASK V3D_MASK(7, 0) ++# define V3D_CSD_CURRENT_ID0_L_IDX_SHIFT 0 ++ ++#define V3D_CSD_CURRENT_ID1 0x00940 ++# define V3D_CSD_CURRENT_ID0_WG_Z_MASK V3D_MASK(31, 16) ++# define V3D_CSD_CURRENT_ID0_WG_Z_SHIFT 16 ++# define V3D_CSD_CURRENT_ID0_WG_Y_MASK V3D_MASK(15, 0) ++# define V3D_CSD_CURRENT_ID0_WG_Y_SHIFT 0 ++ + #endif /* V3D_REGS_H */ +--- a/drivers/gpu/drm/v3d/v3d_sched.c ++++ b/drivers/gpu/drm/v3d/v3d_sched.c +@@ -48,6 +48,12 @@ to_tfu_job(struct drm_sched_job *sched_j + return container_of(sched_job, struct v3d_tfu_job, base.base); + } + ++static struct v3d_csd_job * ++to_csd_job(struct drm_sched_job *sched_job) ++{ ++ return container_of(sched_job, struct v3d_csd_job, base.base); ++} ++ + static void + v3d_job_free(struct drm_sched_job *sched_job) + { +@@ -205,6 +211,48 @@ v3d_tfu_job_run(struct drm_sched_job *sc + return fence; + } + ++static struct dma_fence * ++v3d_csd_job_run(struct drm_sched_job *sched_job) ++{ ++ struct v3d_csd_job *job = to_csd_job(sched_job); ++ struct v3d_dev *v3d = job->base.v3d; ++ struct drm_device *dev = &v3d->drm; ++ struct dma_fence *fence; ++ int i; ++ ++ v3d->csd_job = job; ++ ++ v3d_invalidate_caches(v3d); ++ ++ fence = v3d_fence_create(v3d, V3D_CSD); ++ if (IS_ERR(fence)) ++ return NULL; ++ ++ if (job->base.irq_fence) ++ dma_fence_put(job->base.irq_fence); ++ job->base.irq_fence = dma_fence_get(fence); ++ ++ trace_v3d_submit_csd(dev, to_v3d_fence(fence)->seqno); ++ ++ for (i = 1; i <= 6; i++) ++ V3D_CORE_WRITE(0, V3D_CSD_QUEUED_CFG0 + 4 * i, job->args.cfg[i]); ++ /* CFG0 write kicks off the job. */ ++ V3D_CORE_WRITE(0, V3D_CSD_QUEUED_CFG0, job->args.cfg[0]); ++ ++ return fence; ++} ++ ++static struct dma_fence * ++v3d_cache_clean_job_run(struct drm_sched_job *sched_job) ++{ ++ struct v3d_job *job = to_v3d_job(sched_job); ++ struct v3d_dev *v3d = job->v3d; ++ ++ v3d_clean_caches(v3d); ++ ++ return NULL; ++} ++ + static void + v3d_gpu_reset_for_timeout(struct v3d_dev *v3d, struct drm_sched_job *sched_job) + { +@@ -277,13 +325,31 @@ v3d_render_job_timedout(struct drm_sched + } + + static void +-v3d_tfu_job_timedout(struct drm_sched_job *sched_job) ++v3d_generic_job_timedout(struct drm_sched_job *sched_job) + { + struct v3d_job *job = to_v3d_job(sched_job); + + v3d_gpu_reset_for_timeout(job->v3d, sched_job); + } + ++static void ++v3d_csd_job_timedout(struct drm_sched_job *sched_job) ++{ ++ struct v3d_csd_job *job = to_csd_job(sched_job); ++ struct v3d_dev *v3d = job->base.v3d; ++ u32 batches = V3D_CORE_READ(0, V3D_CSD_CURRENT_CFG4); ++ ++ /* If we've made progress, skip reset and let the timer get ++ * rearmed. ++ */ ++ if (job->timedout_batches != batches) { ++ job->timedout_batches = batches; ++ return; ++ } ++ ++ v3d_gpu_reset_for_timeout(v3d, sched_job); ++} ++ + static const struct drm_sched_backend_ops v3d_bin_sched_ops = { + .dependency = v3d_job_dependency, + .run_job = v3d_bin_job_run, +@@ -301,10 +367,24 @@ static const struct drm_sched_backend_op + static const struct drm_sched_backend_ops v3d_tfu_sched_ops = { + .dependency = v3d_job_dependency, + .run_job = v3d_tfu_job_run, +- .timedout_job = v3d_tfu_job_timedout, ++ .timedout_job = v3d_generic_job_timedout, + .free_job = v3d_job_free, + }; + ++static const struct drm_sched_backend_ops v3d_csd_sched_ops = { ++ .dependency = v3d_job_dependency, ++ .run_job = v3d_csd_job_run, ++ .timedout_job = v3d_csd_job_timedout, ++ .free_job = v3d_job_free ++}; ++ ++static const struct drm_sched_backend_ops v3d_cache_clean_sched_ops = { ++ .dependency = v3d_job_dependency, ++ .run_job = v3d_cache_clean_job_run, ++ .timedout_job = v3d_generic_job_timedout, ++ .free_job = v3d_job_free ++}; ++ + int + v3d_sched_init(struct v3d_dev *v3d) + { +@@ -331,7 +411,7 @@ v3d_sched_init(struct v3d_dev *v3d) + if (ret) { + dev_err(v3d->dev, "Failed to create render scheduler: %d.", + ret); +- drm_sched_fini(&v3d->queue[V3D_BIN].sched); ++ v3d_sched_fini(v3d); + return ret; + } + +@@ -343,11 +423,36 @@ v3d_sched_init(struct v3d_dev *v3d) + if (ret) { + dev_err(v3d->dev, "Failed to create TFU scheduler: %d.", + ret); +- drm_sched_fini(&v3d->queue[V3D_RENDER].sched); +- drm_sched_fini(&v3d->queue[V3D_BIN].sched); ++ v3d_sched_fini(v3d); + return ret; + } + ++ if (v3d_has_csd(v3d)) { ++ ret = drm_sched_init(&v3d->queue[V3D_CSD].sched, ++ &v3d_csd_sched_ops, ++ hw_jobs_limit, job_hang_limit, ++ msecs_to_jiffies(hang_limit_ms), ++ "v3d_csd"); ++ if (ret) { ++ dev_err(v3d->dev, "Failed to create CSD scheduler: %d.", ++ ret); ++ v3d_sched_fini(v3d); ++ return ret; ++ } ++ ++ ret = drm_sched_init(&v3d->queue[V3D_CACHE_CLEAN].sched, ++ &v3d_cache_clean_sched_ops, ++ hw_jobs_limit, job_hang_limit, ++ msecs_to_jiffies(hang_limit_ms), ++ "v3d_cache_clean"); ++ if (ret) { ++ dev_err(v3d->dev, "Failed to create CACHE_CLEAN scheduler: %d.", ++ ret); ++ v3d_sched_fini(v3d); ++ return ret; ++ } ++ } ++ + return 0; + } + +@@ -356,6 +461,8 @@ v3d_sched_fini(struct v3d_dev *v3d) + { + enum v3d_queue q; + +- for (q = 0; q < V3D_MAX_QUEUES; q++) +- drm_sched_fini(&v3d->queue[q].sched); ++ for (q = 0; q < V3D_MAX_QUEUES; q++) { ++ if (v3d->queue[q].sched.ops) ++ drm_sched_fini(&v3d->queue[q].sched); ++ } + } +--- a/drivers/gpu/drm/v3d/v3d_trace.h ++++ b/drivers/gpu/drm/v3d/v3d_trace.h +@@ -124,6 +124,26 @@ TRACE_EVENT(v3d_tfu_irq, + __entry->seqno) + ); + ++TRACE_EVENT(v3d_csd_irq, ++ TP_PROTO(struct drm_device *dev, ++ uint64_t seqno), ++ TP_ARGS(dev, seqno), ++ ++ TP_STRUCT__entry( ++ __field(u32, dev) ++ __field(u64, seqno) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev->primary->index; ++ __entry->seqno = seqno; ++ ), ++ ++ TP_printk("dev=%u, seqno=%llu", ++ __entry->dev, ++ __entry->seqno) ++); ++ + TRACE_EVENT(v3d_submit_tfu_ioctl, + TP_PROTO(struct drm_device *dev, u32 iia), + TP_ARGS(dev, iia), +@@ -163,6 +183,80 @@ TRACE_EVENT(v3d_submit_tfu, + __entry->seqno) + ); + ++TRACE_EVENT(v3d_submit_csd_ioctl, ++ TP_PROTO(struct drm_device *dev, u32 cfg5, u32 cfg6), ++ TP_ARGS(dev, cfg5, cfg6), ++ ++ TP_STRUCT__entry( ++ __field(u32, dev) ++ __field(u32, cfg5) ++ __field(u32, cfg6) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev->primary->index; ++ __entry->cfg5 = cfg5; ++ __entry->cfg6 = cfg6; ++ ), ++ ++ TP_printk("dev=%u, CFG5 0x%08x, CFG6 0x%08x", ++ __entry->dev, ++ __entry->cfg5, ++ __entry->cfg6) ++); ++ ++TRACE_EVENT(v3d_submit_csd, ++ TP_PROTO(struct drm_device *dev, ++ uint64_t seqno), ++ TP_ARGS(dev, seqno), ++ ++ TP_STRUCT__entry( ++ __field(u32, dev) ++ __field(u64, seqno) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev->primary->index; ++ __entry->seqno = seqno; ++ ), ++ ++ TP_printk("dev=%u, seqno=%llu", ++ __entry->dev, ++ __entry->seqno) ++); ++ ++TRACE_EVENT(v3d_cache_clean_begin, ++ TP_PROTO(struct drm_device *dev), ++ TP_ARGS(dev), ++ ++ TP_STRUCT__entry( ++ __field(u32, dev) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev->primary->index; ++ ), ++ ++ TP_printk("dev=%u", ++ __entry->dev) ++); ++ ++TRACE_EVENT(v3d_cache_clean_end, ++ TP_PROTO(struct drm_device *dev), ++ TP_ARGS(dev), ++ ++ TP_STRUCT__entry( ++ __field(u32, dev) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev->primary->index; ++ ), ++ ++ TP_printk("dev=%u", ++ __entry->dev) ++); ++ + TRACE_EVENT(v3d_reset_begin, + TP_PROTO(struct drm_device *dev), + TP_ARGS(dev), +--- a/include/uapi/drm/v3d_drm.h ++++ b/include/uapi/drm/v3d_drm.h +@@ -37,6 +37,7 @@ extern "C" { + #define DRM_V3D_GET_PARAM 0x04 + #define DRM_V3D_GET_BO_OFFSET 0x05 + #define DRM_V3D_SUBMIT_TFU 0x06 ++#define DRM_V3D_SUBMIT_CSD 0x07 + + #define DRM_IOCTL_V3D_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CL, struct drm_v3d_submit_cl) + #define DRM_IOCTL_V3D_WAIT_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_WAIT_BO, struct drm_v3d_wait_bo) +@@ -45,6 +46,7 @@ extern "C" { + #define DRM_IOCTL_V3D_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_GET_PARAM, struct drm_v3d_get_param) + #define DRM_IOCTL_V3D_GET_BO_OFFSET DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_GET_BO_OFFSET, struct drm_v3d_get_bo_offset) + #define DRM_IOCTL_V3D_SUBMIT_TFU DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_TFU, struct drm_v3d_submit_tfu) ++#define DRM_IOCTL_V3D_SUBMIT_CSD DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CSD, struct drm_v3d_submit_csd) + + /** + * struct drm_v3d_submit_cl - ioctl argument for submitting commands to the 3D +@@ -172,6 +174,7 @@ enum drm_v3d_param { + DRM_V3D_PARAM_V3D_CORE0_IDENT1, + DRM_V3D_PARAM_V3D_CORE0_IDENT2, + DRM_V3D_PARAM_SUPPORTS_TFU, ++ DRM_V3D_PARAM_SUPPORTS_CSD, + }; + + struct drm_v3d_get_param { +@@ -212,6 +215,31 @@ struct drm_v3d_submit_tfu { + __u32 out_sync; + }; + ++/* Submits a compute shader for dispatch. This job will block on any ++ * previous compute shaders submitted on this fd, and any other ++ * synchronization must be performed with in_sync/out_sync. ++ */ ++struct drm_v3d_submit_csd { ++ __u32 cfg[7]; ++ __u32 coef[4]; ++ ++ /* Pointer to a u32 array of the BOs that are referenced by the job. ++ */ ++ __u64 bo_handles; ++ ++ /* Number of BO handles passed in (size is that times 4). */ ++ __u32 bo_handle_count; ++ ++ /* sync object to block on before running the CSD job. Each ++ * CSD job will execute in the order submitted to its FD. ++ * Synchronization against rendering/TFU jobs or CSD from ++ * other fds requires using sync objects. ++ */ ++ __u32 in_sync; ++ /* Sync object to signal when the CSD job is done. */ ++ __u32 out_sync; ++}; ++ + #if defined(__cplusplus) + } + #endif diff --git a/target/linux/brcm2708/patches-4.19/950-0612-drm-vc4-Increase-max_width-height-to-7680.patch b/target/linux/brcm2708/patches-4.19/950-0612-drm-vc4-Increase-max_width-height-to-7680.patch deleted file mode 100644 index 8bf6ff91c7..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0612-drm-vc4-Increase-max_width-height-to-7680.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 64a1a6d813cea64ee9dafca163e62542dce04399 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 29 Apr 2019 18:45:00 +0100 -Subject: [PATCH 612/703] drm: vc4: Increase max_width/height to 7680. - -There are some limits still being investigated that stop -us going up to 8192, but 7680 is sufficient for dual 4k -displays. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_kms.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -429,8 +429,8 @@ int vc4_kms_load(struct drm_device *dev) - return ret; - } - -- dev->mode_config.max_width = 4096; -- dev->mode_config.max_height = 4096; -+ dev->mode_config.max_width = 7680; -+ dev->mode_config.max_height = 7680; - dev->mode_config.funcs = &vc4_mode_funcs; - dev->mode_config.preferred_depth = 24; - dev->mode_config.async_page_flip = true; diff --git a/target/linux/brcm2708/patches-4.19/950-0613-drm-v3d-Clock-V3D-down-when-not-in-use.patch b/target/linux/brcm2708/patches-4.19/950-0613-drm-v3d-Clock-V3D-down-when-not-in-use.patch new file mode 100644 index 0000000000..3cc27ba360 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0613-drm-v3d-Clock-V3D-down-when-not-in-use.patch @@ -0,0 +1,157 @@ +From 78981e59b011aa5d21ccedf124c0af9b445d279f Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 2 May 2019 13:22:53 -0700 +Subject: [PATCH 613/725] drm/v3d: Clock V3D down when not in use. + +My various attempts at re-enabling runtime PM have failed, so just +crank the clock down when V3D is idle to reduce power consumption. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/v3d/v3d_drv.c | 18 +++++++++++++ + drivers/gpu/drm/v3d/v3d_drv.h | 6 +++++ + drivers/gpu/drm/v3d/v3d_gem.c | 49 +++++++++++++++++++++++++++++++++++ + 3 files changed, 73 insertions(+) + +--- a/drivers/gpu/drm/v3d/v3d_drv.c ++++ b/drivers/gpu/drm/v3d/v3d_drv.c +@@ -297,6 +297,21 @@ static int v3d_platform_drm_probe(struct + } + } + ++ v3d->clk = devm_clk_get(dev, NULL); ++ if (IS_ERR(v3d->clk)) { ++ if (ret != -EPROBE_DEFER) ++ dev_err(dev, "Failed to get clock\n"); ++ goto dev_free; ++ } ++ v3d->clk_up_rate = clk_get_rate(v3d->clk); ++ /* For downclocking, drop it to the minimum frequency we can get from ++ * the CPRMAN clock generator dividing off our parent. The divider is ++ * 4 bits, but ask for just higher than that so that rounding doesn't ++ * make cprman reject our rate. ++ */ ++ v3d->clk_down_rate = ++ (clk_get_rate(clk_get_parent(v3d->clk)) / (1 << 4)) + 10000; ++ + if (v3d->ver < 41) { + ret = map_regs(v3d, &v3d->gca_regs, "gca"); + if (ret) +@@ -331,6 +346,9 @@ static int v3d_platform_drm_probe(struct + if (ret) + goto irq_disable; + ++ ret = clk_set_rate(v3d->clk, v3d->clk_down_rate); ++ WARN_ON_ONCE(ret != 0); ++ + return 0; + + irq_disable: +--- a/drivers/gpu/drm/v3d/v3d_drv.h ++++ b/drivers/gpu/drm/v3d/v3d_drv.h +@@ -45,6 +45,12 @@ struct v3d_dev { + void __iomem *bridge_regs; + void __iomem *gca_regs; + struct clk *clk; ++ struct delayed_work clk_down_work; ++ unsigned long clk_up_rate, clk_down_rate; ++ struct mutex clk_lock; ++ u32 clk_refcount; ++ bool clk_up; ++ + struct reset_control *reset; + + /* Virtual and DMA addresses of the single shared page table. */ +--- a/drivers/gpu/drm/v3d/v3d_gem.c ++++ b/drivers/gpu/drm/v3d/v3d_gem.c +@@ -3,6 +3,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -17,6 +18,47 @@ + #include "v3d_trace.h" + + static void ++v3d_clock_down_work(struct work_struct *work) ++{ ++ struct v3d_dev *v3d = ++ container_of(work, struct v3d_dev, clk_down_work.work); ++ int ret; ++ ++ ret = clk_set_rate(v3d->clk, v3d->clk_down_rate); ++ v3d->clk_up = false; ++ WARN_ON_ONCE(ret != 0); ++} ++ ++static void ++v3d_clock_up_get(struct v3d_dev *v3d) ++{ ++ mutex_lock(&v3d->clk_lock); ++ if (v3d->clk_refcount++ == 0) { ++ cancel_delayed_work_sync(&v3d->clk_down_work); ++ if (!v3d->clk_up) { ++ int ret; ++ ++ ret = clk_set_rate(v3d->clk, v3d->clk_up_rate); ++ WARN_ON_ONCE(ret != 0); ++ v3d->clk_up = true; ++ } ++ } ++ mutex_unlock(&v3d->clk_lock); ++} ++ ++static void ++v3d_clock_up_put(struct v3d_dev *v3d) ++{ ++ mutex_lock(&v3d->clk_lock); ++ if (--v3d->clk_refcount == 0) { ++ schedule_delayed_work(&v3d->clk_down_work, ++ msecs_to_jiffies(100)); ++ } ++ mutex_unlock(&v3d->clk_lock); ++} ++ ++ ++static void + v3d_init_core(struct v3d_dev *v3d, int core) + { + /* Set OVRTMUOUT, which means that the texture sampler uniform +@@ -490,6 +532,7 @@ static void + v3d_job_free(struct kref *ref) + { + struct v3d_job *job = container_of(ref, struct v3d_job, refcount); ++ struct v3d_dev *v3d = job->v3d; + int i; + + for (i = 0; i < job->bo_count; i++) { +@@ -505,6 +548,8 @@ v3d_job_free(struct kref *ref) + dma_fence_put(job->irq_fence); + dma_fence_put(job->done_fence); + ++ v3d_clock_up_put(v3d); ++ + kfree(job); + } + +@@ -596,6 +641,7 @@ v3d_job_init(struct v3d_dev *v3d, struct + if (ret) + return ret; + ++ v3d_clock_up_get(v3d); + kref_init(&job->refcount); + + return 0; +@@ -963,6 +1009,9 @@ v3d_gem_init(struct drm_device *dev) + mutex_init(&v3d->sched_lock); + mutex_init(&v3d->cache_clean_lock); + ++ mutex_init(&v3d->clk_lock); ++ INIT_DELAYED_WORK(&v3d->clk_down_work, v3d_clock_down_work); ++ + /* Note: We don't allocate address 0. Various bits of HW + * treat 0 as special, such as the occlusion query counters + * where 0 means "disabled". diff --git a/target/linux/brcm2708/patches-4.19/950-0613-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch b/target/linux/brcm2708/patches-4.19/950-0613-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch deleted file mode 100644 index 3e4e9e7c1f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0613-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch +++ /dev/null @@ -1,557 +0,0 @@ -From 9dccdfcd48e7adb46af440cec26df2d8146afefb Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 9 Apr 2019 18:23:41 +0100 -Subject: [PATCH 613/703] drm: vc4: FKMS reads the EDID from fw, and supports - mode setting - -This extends FKMS to read the EDID from the display, and support -requesting a particular mode via KMS. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 334 ++++++++++++++++++--- - include/soc/bcm2835/raspberrypi-firmware.h | 2 + - 2 files changed, 302 insertions(+), 34 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -88,11 +88,60 @@ struct mailbox_blank_display { - u32 blank; - }; - --struct mailbox_get_width_height { -+struct mailbox_get_edid { - struct rpi_firmware_property_tag_header tag1; -- u32 display; -- struct rpi_firmware_property_tag_header tag2; -- u32 wh[2]; -+ u32 block; -+ u32 display_number; -+ u8 edid[128]; -+}; -+ -+struct set_timings { -+ u8 display; -+ u8 padding; -+ u16 video_id_code; -+ -+ u32 clock; /* in kHz */ -+ -+ u16 hdisplay; -+ u16 hsync_start; -+ -+ u16 hsync_end; -+ u16 htotal; -+ -+ u16 hskew; -+ u16 vdisplay; -+ -+ u16 vsync_start; -+ u16 vsync_end; -+ -+ u16 vtotal; -+ u16 vscan; -+ -+ u16 vrefresh; -+ u16 padding2; -+ -+ u32 flags; -+#define TIMINGS_FLAGS_H_SYNC_POS BIT(0) -+#define TIMINGS_FLAGS_H_SYNC_NEG 0 -+#define TIMINGS_FLAGS_V_SYNC_POS BIT(1) -+#define TIMINGS_FLAGS_V_SYNC_NEG 0 -+ -+#define TIMINGS_FLAGS_ASPECT_MASK GENMASK(7, 4) -+#define TIMINGS_FLAGS_ASPECT_NONE (0 << 4) -+#define TIMINGS_FLAGS_ASPECT_4_3 (1 << 4) -+#define TIMINGS_FLAGS_ASPECT_16_9 (2 << 4) -+#define TIMINGS_FLAGS_ASPECT_64_27 (3 << 4) -+#define TIMINGS_FLAGS_ASPECT_256_135 (4 << 4) -+ -+/* Limited range RGB flag. Not set corresponds to full range. */ -+#define TIMINGS_FLAGS_RGB_LIMITED BIT(8) -+/* DVI monitor, therefore disable infoframes. Not set corresponds to HDMI. */ -+#define TIMINGS_FLAGS_DVI BIT(9) -+}; -+ -+struct mailbox_set_mode { -+ struct rpi_firmware_property_tag_header tag1; -+ struct set_timings timings; - }; - - static const struct vc_image_format { -@@ -186,6 +235,7 @@ struct vc4_crtc { - u32 overscan[4]; - bool vblank_enabled; - u32 display_number; -+ u32 display_type; - }; - - static inline struct vc4_crtc *to_vc4_crtc(struct drm_crtc *crtc) -@@ -195,6 +245,8 @@ static inline struct vc4_crtc *to_vc4_cr - - struct vc4_fkms_encoder { - struct drm_encoder base; -+ bool hdmi_monitor; -+ bool rgb_range_selectable; - }; - - static inline struct vc4_fkms_encoder * -@@ -212,7 +264,9 @@ struct vc4_fkms_connector { - * hook. - */ - struct drm_encoder *encoder; -- u32 display_idx; -+ struct vc4_dev *vc4_dev; -+ u32 display_number; -+ u32 display_type; - }; - - static inline struct vc4_fkms_connector * -@@ -221,6 +275,26 @@ to_vc4_fkms_connector(struct drm_connect - return container_of(connector, struct vc4_fkms_connector, base); - } - -+static u32 vc4_get_display_type(u32 display_number) -+{ -+ const u32 display_types[] = { -+ /* The firmware display (DispmanX) IDs map to specific types in -+ * a fixed manner. -+ */ -+ DRM_MODE_ENCODER_DSI, /* MAIN_LCD */ -+ DRM_MODE_ENCODER_DSI, /* AUX_LCD */ -+ DRM_MODE_ENCODER_TMDS, /* HDMI0 */ -+ DRM_MODE_ENCODER_TVDAC, /* VEC */ -+ DRM_MODE_ENCODER_NONE, /* FORCE_LCD */ -+ DRM_MODE_ENCODER_NONE, /* FORCE_TV */ -+ DRM_MODE_ENCODER_NONE, /* FORCE_OTHER */ -+ DRM_MODE_ENCODER_TMDS, /* HDMI1 */ -+ DRM_MODE_ENCODER_NONE, /* FORCE_TV2 */ -+ }; -+ return display_number > ARRAY_SIZE(display_types) - 1 ? -+ DRM_MODE_ENCODER_NONE : display_types[display_number]; -+} -+ - /* Firmware's structure for making an FB mbox call. */ - struct fbinfo_s { - u32 xres, yres, xres_virtual, yres_virtual; -@@ -255,10 +329,15 @@ static int vc4_plane_set_blank(struct dr - .plane_id = vc4_plane->mb.plane.plane_id, - } - }; -+ static const char * const plane_types[] = { -+ "overlay", -+ "primary", -+ "cursor" -+ }; - int ret; - -- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] overlay plane %s", -- plane->base.id, plane->name, -+ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] %s plane %s", -+ plane->base.id, plane->name, plane_types[plane->type], - blank ? "blank" : "unblank"); - - if (blank) -@@ -593,13 +672,102 @@ fail: - - static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc) - { -- /* Everyting is handled in the planes. */ -+ struct drm_device *dev = crtc->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); -+ struct drm_display_mode *mode = &crtc->state->adjusted_mode; -+ struct vc4_fkms_encoder *vc4_encoder = -+ to_vc4_fkms_encoder(vc4_crtc->encoder); -+ struct mailbox_set_mode mb = { -+ .tag1 = { RPI_FIRMWARE_SET_TIMING, -+ sizeof(struct set_timings), 0}, -+ }; -+ union hdmi_infoframe frame; -+ int ret; -+ -+ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false); -+ if (ret < 0) { -+ DRM_ERROR("couldn't fill AVI infoframe\n"); -+ return; -+ } -+ -+ DRM_DEBUG_KMS("Setting mode for display num %u mode name %s, clk %d, h(disp %d, start %d, end %d, total %d, skew %d) v(disp %d, start %d, end %d, total %d, scan %d), vrefresh %d, par %u\n", -+ vc4_crtc->display_number, mode->name, mode->clock, -+ mode->hdisplay, mode->hsync_start, mode->hsync_end, -+ mode->htotal, mode->hskew, mode->vdisplay, -+ mode->vsync_start, mode->vsync_end, mode->vtotal, -+ mode->vscan, mode->vrefresh, mode->picture_aspect_ratio); -+ mb.timings.display = vc4_crtc->display_number; -+ -+ mb.timings.video_id_code = frame.avi.video_code; -+ -+ mb.timings.clock = mode->clock; -+ mb.timings.hdisplay = mode->hdisplay; -+ mb.timings.hsync_start = mode->hsync_start; -+ mb.timings.hsync_end = mode->hsync_end; -+ mb.timings.htotal = mode->htotal; -+ mb.timings.hskew = mode->hskew; -+ mb.timings.vdisplay = mode->vdisplay; -+ mb.timings.vsync_start = mode->vsync_start; -+ mb.timings.vsync_end = mode->vsync_end; -+ mb.timings.vtotal = mode->vtotal; -+ mb.timings.vscan = mode->vscan; -+ mb.timings.vrefresh = 0; -+ mb.timings.flags = 0; -+ if (mode->flags & DRM_MODE_FLAG_PHSYNC) -+ mb.timings.flags |= TIMINGS_FLAGS_H_SYNC_POS; -+ if (mode->flags & DRM_MODE_FLAG_PVSYNC) -+ mb.timings.flags |= TIMINGS_FLAGS_V_SYNC_POS; -+ -+ switch (frame.avi.picture_aspect) { -+ default: -+ case HDMI_PICTURE_ASPECT_NONE: -+ mode->flags |= TIMINGS_FLAGS_ASPECT_NONE; -+ break; -+ case HDMI_PICTURE_ASPECT_4_3: -+ mode->flags |= TIMINGS_FLAGS_ASPECT_4_3; -+ break; -+ case HDMI_PICTURE_ASPECT_16_9: -+ mode->flags |= TIMINGS_FLAGS_ASPECT_16_9; -+ break; -+ case HDMI_PICTURE_ASPECT_64_27: -+ mode->flags |= TIMINGS_FLAGS_ASPECT_64_27; -+ break; -+ case HDMI_PICTURE_ASPECT_256_135: -+ mode->flags |= TIMINGS_FLAGS_ASPECT_256_135; -+ break; -+ } -+ -+ if (!vc4_encoder->hdmi_monitor) -+ mb.timings.flags |= TIMINGS_FLAGS_DVI; -+ else if (drm_default_rgb_quant_range(mode) == -+ HDMI_QUANTIZATION_RANGE_LIMITED) -+ mb.timings.flags |= TIMINGS_FLAGS_RGB_LIMITED; -+ -+ /* -+ FIXME: To implement -+ switch(mode->flag & DRM_MODE_FLAG_3D_MASK) { -+ case DRM_MODE_FLAG_3D_NONE: -+ case DRM_MODE_FLAG_3D_FRAME_PACKING: -+ case DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE: -+ case DRM_MODE_FLAG_3D_LINE_ALTERNATIVE: -+ case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL: -+ case DRM_MODE_FLAG_3D_L_DEPTH: -+ case DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH: -+ case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM: -+ case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF: -+ } -+ */ -+ -+ ret = rpi_firmware_property_list(vc4->firmware, &mb, sizeof(mb)); - } - - static void vc4_crtc_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) - { - struct drm_plane *plane; - -+ DRM_DEBUG_KMS("[CRTC:%d] vblanks off.\n", -+ crtc->base.id); - drm_crtc_vblank_off(crtc); - - /* Always turn the planes off on CRTC disable. In DRM, planes -@@ -617,6 +785,8 @@ static void vc4_crtc_enable(struct drm_c - { - struct drm_plane *plane; - -+ DRM_DEBUG_KMS("[CRTC:%d] vblanks on.\n", -+ crtc->base.id); - drm_crtc_vblank_on(crtc); - - /* Unblank the planes (if they're supposed to be displayed). */ -@@ -635,12 +805,20 @@ vc4_crtc_mode_valid(struct drm_crtc *crt - return MODE_NO_DBLESCAN; - } - -+ /* Limit the pixel clock until we can get dynamic HDMI 2.0 scrambling -+ * working. -+ */ -+ if (mode->clock > 340000) -+ return MODE_CLOCK_HIGH; -+ - return MODE_OK; - } - - static int vc4_crtc_atomic_check(struct drm_crtc *crtc, - struct drm_crtc_state *state) - { -+ DRM_DEBUG_KMS("[CRTC:%d] crtc_atomic_check.\n", -+ crtc->base.id); - return 0; - } - -@@ -650,6 +828,8 @@ static void vc4_crtc_atomic_flush(struct - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); - struct drm_device *dev = crtc->dev; - -+ DRM_DEBUG_KMS("[CRTC:%d] crtc_atomic_flush.\n", -+ crtc->base.id); - if (crtc->state->event) { - unsigned long flags; - -@@ -717,6 +897,8 @@ static int vc4_fkms_enable_vblank(struct - { - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); - -+ DRM_DEBUG_KMS("[CRTC:%d] enable_vblank.\n", -+ crtc->base.id); - vc4_crtc->vblank_enabled = true; - - return 0; -@@ -726,6 +908,8 @@ static void vc4_fkms_disable_vblank(stru - { - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); - -+ DRM_DEBUG_KMS("[CRTC:%d] disable_vblank.\n", -+ crtc->base.id); - vc4_crtc->vblank_enabled = false; - } - -@@ -760,36 +944,92 @@ static const struct of_device_id vc4_fir - static enum drm_connector_status - vc4_fkms_connector_detect(struct drm_connector *connector, bool force) - { -+ DRM_DEBUG_KMS("connector detect.\n"); - return connector_status_connected; - } - --static int vc4_fkms_connector_get_modes(struct drm_connector *connector) -+static int vc4_fkms_get_edid_block(void *data, u8 *buf, unsigned int block, -+ size_t len) - { -- struct drm_device *dev = connector->dev; - struct vc4_fkms_connector *fkms_connector = -- to_vc4_fkms_connector(connector); -- struct vc4_dev *vc4 = to_vc4_dev(dev); -- struct drm_display_mode *mode; -- struct mailbox_get_width_height wh = { -- .tag1 = {RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM, 4, 0, }, -- .display = fkms_connector->display_idx, -- .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT, -- 8, 0, }, -+ (struct vc4_fkms_connector *)data; -+ struct vc4_dev *vc4 = fkms_connector->vc4_dev; -+ struct mailbox_get_edid mb = { -+ .tag1 = { RPI_FIRMWARE_GET_EDID_BLOCK_DISPLAY, -+ 128 + 8, 0 }, -+ .block = block, -+ .display_number = fkms_connector->display_number, - }; -- int ret; -+ int ret = 0; -+ -+ ret = rpi_firmware_property_list(vc4->firmware, &mb, sizeof(mb)); -+ -+ if (!ret) -+ memcpy(buf, mb.edid, len); -+ -+ return ret; -+} -+ -+static int vc4_fkms_connector_get_modes(struct drm_connector *connector) -+{ -+ struct vc4_fkms_connector *fkms_connector = -+ to_vc4_fkms_connector(connector); -+ struct drm_encoder *encoder = fkms_connector->encoder; -+ struct vc4_fkms_encoder *vc4_encoder = to_vc4_fkms_encoder(encoder); -+ int ret = 0; -+ struct edid *edid; -+ -+ edid = drm_do_get_edid(connector, vc4_fkms_get_edid_block, -+ fkms_connector); -+ -+ /* FIXME: Can we do CEC? -+ * cec_s_phys_addr_from_edid(vc4->hdmi->cec_adap, edid); -+ * if (!edid) -+ * return -ENODEV; -+ */ -+ -+ vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid); - -- ret = rpi_firmware_property_list(vc4->firmware, &wh, sizeof(wh)); -+ if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) { -+ vc4_encoder->rgb_range_selectable = -+ drm_rgb_quant_range_selectable(edid); -+ } -+ -+ drm_connector_update_edid_property(connector, edid); -+ ret = drm_add_edid_modes(connector, edid); -+ kfree(edid); -+ -+ return ret; -+} -+ -+/* FIXME: Read LCD mode from the firmware. This is the DSI panel resolution. */ -+static const struct drm_display_mode lcd_mode = { -+ DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, -+ 25979400 / 1000, -+ 800, 800 + 1, 800 + 1 + 2, 800 + 1 + 2 + 46, 0, -+ 480, 480 + 7, 480 + 7 + 2, 480 + 7 + 2 + 21, 0, -+ DRM_MODE_FLAG_INTERLACE) -+}; -+ -+static int vc4_fkms_lcd_connector_get_modes(struct drm_connector *connector) -+{ -+ //struct vc4_fkms_connector *fkms_connector = -+ // to_vc4_fkms_connector(connector); -+ //struct drm_encoder *encoder = fkms_connector->encoder; -+ //struct vc4_fkms_encoder *vc4_encoder = to_vc4_fkms_encoder(encoder); -+ struct drm_display_mode *mode; -+ //int ret = 0; - -- if (ret) { -- DRM_ERROR("Failed to get screen size: %d (0x%08x 0x%08x)\n", -- ret, wh.wh[0], wh.wh[1]); -- return 0; -+ mode = drm_mode_duplicate(connector->dev, -+ &lcd_mode); -+ if (!mode) { -+ DRM_ERROR("Failed to create a new display mode\n"); -+ return -ENOMEM; - } - -- mode = drm_cvt_mode(dev, wh.wh[0], wh.wh[1], 60 /* vrefresh */, -- 0, 0, false); - drm_mode_probed_add(connector, mode); - -+ /* We have one mode */ - return 1; - } - -@@ -798,11 +1038,14 @@ vc4_fkms_connector_best_encoder(struct d - { - struct vc4_fkms_connector *fkms_connector = - to_vc4_fkms_connector(connector); -+ DRM_DEBUG_KMS("best_connector.\n"); - return fkms_connector->encoder; - } - - static void vc4_fkms_connector_destroy(struct drm_connector *connector) - { -+ DRM_DEBUG_KMS("[CONNECTOR:%d] destroy.\n", -+ connector->base.id); - drm_connector_unregister(connector); - drm_connector_cleanup(connector); - } -@@ -821,14 +1064,22 @@ static const struct drm_connector_helper - .best_encoder = vc4_fkms_connector_best_encoder, - }; - -+static const struct drm_connector_helper_funcs vc4_fkms_lcd_conn_helper_funcs = { -+ .get_modes = vc4_fkms_lcd_connector_get_modes, -+ .best_encoder = vc4_fkms_connector_best_encoder, -+}; -+ - static struct drm_connector * - vc4_fkms_connector_init(struct drm_device *dev, struct drm_encoder *encoder, -- u32 display_idx) -+ u32 display_num) - { - struct drm_connector *connector = NULL; - struct vc4_fkms_connector *fkms_connector; -+ struct vc4_dev *vc4_dev = to_vc4_dev(dev); - int ret = 0; - -+ DRM_DEBUG_KMS("connector_init, display_num %u\n", display_num); -+ - fkms_connector = devm_kzalloc(dev->dev, sizeof(*fkms_connector), - GFP_KERNEL); - if (!fkms_connector) { -@@ -838,11 +1089,21 @@ vc4_fkms_connector_init(struct drm_devic - connector = &fkms_connector->base; - - fkms_connector->encoder = encoder; -- fkms_connector->display_idx = display_idx; -- -- drm_connector_init(dev, connector, &vc4_fkms_connector_funcs, -- DRM_MODE_CONNECTOR_HDMIA); -- drm_connector_helper_add(connector, &vc4_fkms_connector_helper_funcs); -+ fkms_connector->display_number = display_num; -+ fkms_connector->display_type = vc4_get_display_type(display_num); -+ fkms_connector->vc4_dev = vc4_dev; -+ -+ if (fkms_connector->display_type == DRM_MODE_ENCODER_DSI) { -+ drm_connector_init(dev, connector, &vc4_fkms_connector_funcs, -+ DRM_MODE_CONNECTOR_DSI); -+ drm_connector_helper_add(connector, -+ &vc4_fkms_lcd_conn_helper_funcs); -+ } else { -+ drm_connector_init(dev, connector, &vc4_fkms_connector_funcs, -+ DRM_MODE_CONNECTOR_HDMIA); -+ drm_connector_helper_add(connector, -+ &vc4_fkms_connector_helper_funcs); -+ } - - connector->polled = (DRM_CONNECTOR_POLL_CONNECT | - DRM_CONNECTOR_POLL_DISCONNECT); -@@ -863,6 +1124,7 @@ vc4_fkms_connector_init(struct drm_devic - - static void vc4_fkms_encoder_destroy(struct drm_encoder *encoder) - { -+ DRM_DEBUG_KMS("Encoder_destroy\n"); - drm_encoder_cleanup(encoder); - } - -@@ -872,10 +1134,12 @@ static const struct drm_encoder_funcs vc - - static void vc4_fkms_encoder_enable(struct drm_encoder *encoder) - { -+ DRM_DEBUG_KMS("Encoder_enable\n"); - } - - static void vc4_fkms_encoder_disable(struct drm_encoder *encoder) - { -+ DRM_DEBUG_KMS("Encoder_disable\n"); - } - - static const struct drm_encoder_helper_funcs vc4_fkms_encoder_helper_funcs = { -@@ -907,6 +1171,7 @@ static int vc4_fkms_create_screen(struct - crtc = &vc4_crtc->base; - - vc4_crtc->display_number = display_ref; -+ vc4_crtc->display_type = vc4_get_display_type(display_ref); - - /* Blank the firmware provided framebuffer */ - rpi_firmware_property_list(vc4->firmware, &blank, sizeof(blank)); -@@ -950,13 +1215,14 @@ static int vc4_fkms_create_screen(struct - return -ENOMEM; - vc4_crtc->encoder = &vc4_encoder->base; - vc4_encoder->base.possible_crtcs |= drm_crtc_mask(crtc) ; -+ - drm_encoder_init(drm, &vc4_encoder->base, &vc4_fkms_encoder_funcs, -- DRM_MODE_ENCODER_TMDS, NULL); -+ vc4_crtc->display_type, NULL); - drm_encoder_helper_add(&vc4_encoder->base, - &vc4_fkms_encoder_helper_funcs); - - vc4_crtc->connector = vc4_fkms_connector_init(drm, &vc4_encoder->base, -- display_idx); -+ display_ref); - if (IS_ERR(vc4_crtc->connector)) { - ret = PTR_ERR(vc4_crtc->connector); - goto err_destroy_encoder; ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -78,6 +78,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014, - RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020, - RPI_FIRMWARE_GET_CUSTOMER_OTP = 0x00030021, -+ RPI_FIRMWARE_GET_EDID_BLOCK_DISPLAY = 0x00030023, - RPI_FIRMWARE_GET_DOMAIN_STATE = 0x00030030, - RPI_FIRMWARE_GET_THROTTLED = 0x00030046, - RPI_FIRMWARE_GET_CLOCK_MEASURED = 0x00030047, -@@ -150,6 +151,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, - - RPI_FIRMWARE_SET_PLANE = 0x00048015, -+ RPI_FIRMWARE_SET_TIMING = 0x00048017, - - RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, - RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, diff --git a/target/linux/brcm2708/patches-4.19/950-0614-HACK-clk-bcm2835-Add-BCM2838_CLOCK_EMMC2-support.patch b/target/linux/brcm2708/patches-4.19/950-0614-HACK-clk-bcm2835-Add-BCM2838_CLOCK_EMMC2-support.patch new file mode 100644 index 0000000000..97c7a65fef --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0614-HACK-clk-bcm2835-Add-BCM2838_CLOCK_EMMC2-support.patch @@ -0,0 +1,72 @@ +From ea2e0086511bc2e61c58b7f298bcb558f1fc48b4 Mon Sep 17 00:00:00 2001 +From: Stefan Wahren +Date: Thu, 2 May 2019 23:42:29 +0200 +Subject: [PATCH 614/725] HACK: clk-bcm2835: Add BCM2838_CLOCK_EMMC2 support + +The new BCM2838 supports an additional emmc2 clock. So add a new +compatible to register this clock only for BCM2838. + +Signed-off-by: Stefan Wahren +--- + drivers/clk/bcm/clk-bcm2835.c | 20 ++++++++++++++++++-- + include/dt-bindings/clock/bcm2835.h | 2 ++ + 2 files changed, 20 insertions(+), 2 deletions(-) + +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -124,6 +124,8 @@ + #define CM_AVEODIV 0x1bc + #define CM_EMMCCTL 0x1c0 + #define CM_EMMCDIV 0x1c4 ++#define CM_EMMC2CTL 0x1d0 ++#define CM_EMMC2DIV 0x1d4 + + /* General bits for the CM_*CTL regs */ + # define CM_ENABLE BIT(4) +@@ -2047,6 +2049,15 @@ static const struct bcm2835_clk_desc clk + .frac_bits = 8, + .tcnt_mux = 39), + ++ /* EMMC2 clock (only available for BCM2838) */ ++ [BCM2838_CLOCK_EMMC2] = REGISTER_PER_CLK( ++ .name = "emmc2", ++ .ctl_reg = CM_EMMC2CTL, ++ .div_reg = CM_EMMC2DIV, ++ .int_bits = 4, ++ .frac_bits = 8, ++ .tcnt_mux = 42), ++ + /* General purpose (GPIO) clocks */ + [BCM2835_CLOCK_GP0] = REGISTER_PER_CLK( + .name = "gp0", +@@ -2276,8 +2287,12 @@ static int bcm2835_clk_probe(struct plat + + for (i = 0; i < asize; i++) { + desc = &clk_desc_array[i]; +- if (desc->clk_register && desc->data) +- hws[i] = desc->clk_register(cprman, desc->data); ++ if (desc->clk_register && desc->data) { ++ if ((i != BCM2838_CLOCK_EMMC2) || ++ of_device_is_compatible(fw_node, "brcm,bcm2838-cprman")) { ++ hws[i] = desc->clk_register(cprman, desc->data); ++ } ++ } + } + + ret = bcm2835_mark_sdc_parent_critical(hws[BCM2835_CLOCK_SDRAM]->clk); +@@ -2297,6 +2312,7 @@ static int bcm2835_clk_probe(struct plat + + static const struct of_device_id bcm2835_clk_of_match[] = { + { .compatible = "brcm,bcm2835-cprman", }, ++ { .compatible = "brcm,bcm2838-cprman", }, + {} + }; + MODULE_DEVICE_TABLE(of, bcm2835_clk_of_match); +--- a/include/dt-bindings/clock/bcm2835.h ++++ b/include/dt-bindings/clock/bcm2835.h +@@ -66,3 +66,5 @@ + #define BCM2835_CLOCK_DSI1E 48 + #define BCM2835_CLOCK_DSI0P 49 + #define BCM2835_CLOCK_DSI1P 50 ++ ++#define BCM2838_CLOCK_EMMC2 51 diff --git a/target/linux/brcm2708/patches-4.19/950-0614-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch b/target/linux/brcm2708/patches-4.19/950-0614-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch deleted file mode 100644 index f4780aecf1..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0614-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch +++ /dev/null @@ -1,53 +0,0 @@ -From ace78bef08082eb8971b87b28525926cd86b68c1 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 2 May 2019 15:11:05 -0700 -Subject: [PATCH 614/703] clk: bcm2835: Add support for setting leaf clock - rates while running. - -As long as you wait for !BUSY, you can do glitch-free updates of clock -rate while the clock is running. - -Signed-off-by: Eric Anholt ---- - drivers/clk/bcm/clk-bcm2835.c | 22 +++++++++++++--------- - 1 file changed, 13 insertions(+), 9 deletions(-) - ---- a/drivers/clk/bcm/clk-bcm2835.c -+++ b/drivers/clk/bcm/clk-bcm2835.c -@@ -1097,15 +1097,19 @@ static int bcm2835_clock_set_rate(struct - - spin_lock(&cprman->regs_lock); - -- /* -- * Setting up frac support -- * -- * In principle it is recommended to stop/start the clock first, -- * but as we set CLK_SET_RATE_GATE during registration of the -- * clock this requirement should be take care of by the -- * clk-framework. -+ ctl = cprman_read(cprman, data->ctl_reg); -+ -+ /* If the clock is running, we have to pause clock generation while -+ * updating the control and div regs. This is glitchless (no clock -+ * signals generated faster than the rate) but each reg access is two -+ * OSC cycles so the clock will slow down for a moment. - */ -- ctl = cprman_read(cprman, data->ctl_reg) & ~CM_FRAC; -+ if (ctl & CM_ENABLE) { -+ cprman_write(cprman, data->ctl_reg, ctl & ~CM_ENABLE); -+ bcm2835_clock_wait_busy(clock); -+ } -+ -+ ctl &= ~CM_FRAC; - ctl |= (div & CM_DIV_FRAC_MASK) ? CM_FRAC : 0; - cprman_write(cprman, data->ctl_reg, ctl); - -@@ -1475,7 +1479,7 @@ static struct clk_hw *bcm2835_register_c - init.ops = &bcm2835_vpu_clock_clk_ops; - } else { - init.ops = &bcm2835_clock_clk_ops; -- init.flags |= CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; -+ init.flags |= CLK_SET_PARENT_GATE; - - /* If the clock wasn't actually enabled at boot, it's not - * critical. diff --git a/target/linux/brcm2708/patches-4.19/950-0615-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch b/target/linux/brcm2708/patches-4.19/950-0615-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch deleted file mode 100644 index a8e32fd73a..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0615-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch +++ /dev/null @@ -1,71 +0,0 @@ -From bfdd7752d7503203300ce8359103b11b961611cf Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 2 May 2019 15:24:04 -0700 -Subject: [PATCH 615/703] clk: bcm2835: Allow reparenting leaf clocks while - they're running. - -This falls under the same "we can reprogram glitch-free as long as we -pause generation" rule as updating the div/frac fields. This can be -used for runtime reclocking of V3D to manage power leakage. - -Signed-off-by: Eric Anholt ---- - drivers/clk/bcm/clk-bcm2835.c | 19 ++++++++++++++++--- - 1 file changed, 16 insertions(+), 3 deletions(-) - ---- a/drivers/clk/bcm/clk-bcm2835.c -+++ b/drivers/clk/bcm/clk-bcm2835.c -@@ -1086,8 +1086,10 @@ static int bcm2835_clock_on(struct clk_h - return 0; - } - --static int bcm2835_clock_set_rate(struct clk_hw *hw, -- unsigned long rate, unsigned long parent_rate) -+static int bcm2835_clock_set_rate_and_parent(struct clk_hw *hw, -+ unsigned long rate, -+ unsigned long parent_rate, -+ u8 parent) - { - struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); - struct bcm2835_cprman *cprman = clock->cprman; -@@ -1109,6 +1111,11 @@ static int bcm2835_clock_set_rate(struct - bcm2835_clock_wait_busy(clock); - } - -+ if (parent != 0xff) { -+ ctl &= ~(CM_SRC_MASK << CM_SRC_SHIFT); -+ ctl |= parent << CM_SRC_SHIFT; -+ } -+ - ctl &= ~CM_FRAC; - ctl |= (div & CM_DIV_FRAC_MASK) ? CM_FRAC : 0; - cprman_write(cprman, data->ctl_reg, ctl); -@@ -1120,6 +1127,12 @@ static int bcm2835_clock_set_rate(struct - return 0; - } - -+static int bcm2835_clock_set_rate(struct clk_hw *hw, -+ unsigned long rate, unsigned long parent_rate) -+{ -+ return bcm2835_clock_set_rate_and_parent(hw, rate, parent_rate, 0xff); -+} -+ - static bool - bcm2835_clk_is_pllc(struct clk_hw *hw) - { -@@ -1303,6 +1316,7 @@ static const struct clk_ops bcm2835_cloc - .unprepare = bcm2835_clock_off, - .recalc_rate = bcm2835_clock_get_rate, - .set_rate = bcm2835_clock_set_rate, -+ .set_rate_and_parent = bcm2835_clock_set_rate_and_parent, - .determine_rate = bcm2835_clock_determine_rate, - .set_parent = bcm2835_clock_set_parent, - .get_parent = bcm2835_clock_get_parent, -@@ -1479,7 +1493,6 @@ static struct clk_hw *bcm2835_register_c - init.ops = &bcm2835_vpu_clock_clk_ops; - } else { - init.ops = &bcm2835_clock_clk_ops; -- init.flags |= CLK_SET_PARENT_GATE; - - /* If the clock wasn't actually enabled at boot, it's not - * critical. diff --git a/target/linux/brcm2708/patches-4.19/950-0615-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch b/target/linux/brcm2708/patches-4.19/950-0615-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch new file mode 100644 index 0000000000..9e365a5275 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0615-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch @@ -0,0 +1,55 @@ +From 670f61146f51a0fcfc75c9c5920922f94c662f59 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 3 May 2019 13:58:03 +0100 +Subject: [PATCH 615/725] drm: vc4-firmware-kms: Remove incorrect overscan + support. + +The overscan support was required for the old mailbox API +in order to match up the cursor and frame buffer planes. +With the newer API directly talking to dispmanx there is no +difference, therefore FKMS does not need to make any +adjustments. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 15 --------------- + 1 file changed, 15 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -232,7 +232,6 @@ struct vc4_crtc { + void __iomem *regs; + + struct drm_pending_vblank_event *event; +- u32 overscan[4]; + bool vblank_enabled; + u32 display_number; + u32 display_type; +@@ -468,11 +467,6 @@ static void vc4_plane_atomic_update(stru + break; + } + +- if (vc4_crtc) { +- mb->plane.dst_x += vc4_crtc->overscan[0]; +- mb->plane.dst_y += vc4_crtc->overscan[1]; +- } +- + DRM_DEBUG_ATOMIC("[PLANE:%d:%s] plane update %dx%d@%d +dst(%d,%d, %d,%d) +src(%d,%d, %d,%d) 0x%08x/%08x/%08x/%d, alpha %u zpos %u\n", + plane->base.id, plane->name, + mb->plane.width, +@@ -1228,15 +1222,6 @@ static int vc4_fkms_create_screen(struct + goto err_destroy_encoder; + } + +- ret = rpi_firmware_property(vc4->firmware, +- RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN, +- &vc4_crtc->overscan, +- sizeof(vc4_crtc->overscan)); +- if (ret) { +- DRM_ERROR("Failed to get overscan state: 0x%08x\n", vc4_crtc->overscan[0]); +- memset(&vc4_crtc->overscan, 0, sizeof(vc4_crtc->overscan)); +- } +- + *ret_crtc = vc4_crtc; + + return 0; diff --git a/target/linux/brcm2708/patches-4.19/950-0616-drm-v3d-Add-support-for-compute-shader-dispatch.patch b/target/linux/brcm2708/patches-4.19/950-0616-drm-v3d-Add-support-for-compute-shader-dispatch.patch deleted file mode 100644 index 48bbddb42e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0616-drm-v3d-Add-support-for-compute-shader-dispatch.patch +++ /dev/null @@ -1,897 +0,0 @@ -From d607c1cfefb38ae7a75ac057afff275e89cff691 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Tue, 16 Apr 2019 15:58:54 -0700 -Subject: [PATCH 616/703] drm/v3d: Add support for compute shader dispatch. - -The compute shader dispatch interface is pretty simple -- just pass in -the regs that userspace has passed us, with no CLs to run. However, -with no CL to run it means that we need to do manual cache flushing of -the L2 after the HW execution completes (for SSBO, atomic, and -image_load_store writes that are the output of compute shaders). - -This doesn't yet expose the L2 cache's ability to have a region of the -address space not write back to memory (which could be used for -shared_var storage). - -So far, the Mesa side has been tested on V3D v4.2 simpenrose (passing -the ES31 tests), and on the kernel side on 7278 (failing atomic -compswap tests in a way that doesn't reproduce on simpenrose). - -v2: Fix excessive allocation for the clean_job (reported by Dan - Carpenter). Keep refs on jobs until clean_job is finished, to - avoid spurious MMU errors if the output BOs are freed by userspace - before L2 cleaning is finished. - -Signed-off-by: Eric Anholt -Link: https://patchwork.freedesktop.org/patch/msgid/20190416225856.20264-4-eric@anholt.net -Acked-by: Rob Clark ---- - drivers/gpu/drm/v3d/v3d_debugfs.c | 22 +++++ - drivers/gpu/drm/v3d/v3d_drv.c | 10 +- - drivers/gpu/drm/v3d/v3d_drv.h | 28 +++++- - drivers/gpu/drm/v3d/v3d_fence.c | 2 + - drivers/gpu/drm/v3d/v3d_gem.c | 156 +++++++++++++++++++++++++++++- - drivers/gpu/drm/v3d/v3d_irq.c | 16 ++- - drivers/gpu/drm/v3d/v3d_regs.h | 73 ++++++++++++++ - drivers/gpu/drm/v3d/v3d_sched.c | 121 +++++++++++++++++++++-- - drivers/gpu/drm/v3d/v3d_trace.h | 94 ++++++++++++++++++ - include/uapi/drm/v3d_drm.h | 28 ++++++ - 10 files changed, 531 insertions(+), 19 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_debugfs.c -+++ b/drivers/gpu/drm/v3d/v3d_debugfs.c -@@ -57,6 +57,17 @@ static const struct v3d_reg_def v3d_core - REGDEF(V3D_GMP_VIO_ADDR), - }; - -+static const struct v3d_reg_def v3d_csd_reg_defs[] = { -+ REGDEF(V3D_CSD_STATUS), -+ REGDEF(V3D_CSD_CURRENT_CFG0), -+ REGDEF(V3D_CSD_CURRENT_CFG1), -+ REGDEF(V3D_CSD_CURRENT_CFG2), -+ REGDEF(V3D_CSD_CURRENT_CFG3), -+ REGDEF(V3D_CSD_CURRENT_CFG4), -+ REGDEF(V3D_CSD_CURRENT_CFG5), -+ REGDEF(V3D_CSD_CURRENT_CFG6), -+}; -+ - static int v3d_v3d_debugfs_regs(struct seq_file *m, void *unused) - { - struct drm_info_node *node = (struct drm_info_node *)m->private; -@@ -88,6 +99,17 @@ static int v3d_v3d_debugfs_regs(struct s - V3D_CORE_READ(core, - v3d_core_reg_defs[i].reg)); - } -+ -+ if (v3d_has_csd(v3d)) { -+ for (i = 0; i < ARRAY_SIZE(v3d_csd_reg_defs); i++) { -+ seq_printf(m, "core %d %s (0x%04x): 0x%08x\n", -+ core, -+ v3d_csd_reg_defs[i].name, -+ v3d_csd_reg_defs[i].reg, -+ V3D_CORE_READ(core, -+ v3d_csd_reg_defs[i].reg)); -+ } -+ } - } - - return 0; ---- a/drivers/gpu/drm/v3d/v3d_drv.c -+++ b/drivers/gpu/drm/v3d/v3d_drv.c -@@ -7,9 +7,9 @@ - * This driver supports the Broadcom V3D 3.3 and 4.1 OpenGL ES GPUs. - * For V3D 2.x support, see the VC4 driver. - * -- * Currently only single-core rendering using the binner and renderer, -- * along with TFU (texture formatting unit) rendering is supported. -- * V3D 4.x's CSD (compute shader dispatch) is not yet supported. -+ * The V3D GPU includes a tiled render (composed of a bin and render -+ * pipelines), the TFU (texture formatting unit), and the CSD (compute -+ * shader dispatch). - */ - - #include -@@ -114,6 +114,9 @@ static int v3d_get_param_ioctl(struct dr - case DRM_V3D_PARAM_SUPPORTS_TFU: - args->value = 1; - return 0; -+ case DRM_V3D_PARAM_SUPPORTS_CSD: -+ args->value = v3d_has_csd(v3d); -+ return 0; - default: - DRM_DEBUG("Unknown parameter %d\n", args->param); - return -EINVAL; -@@ -183,6 +186,7 @@ static const struct drm_ioctl_desc v3d_d - DRM_IOCTL_DEF_DRV(V3D_GET_PARAM, v3d_get_param_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(V3D_GET_BO_OFFSET, v3d_get_bo_offset_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(V3D_SUBMIT_TFU, v3d_submit_tfu_ioctl, DRM_RENDER_ALLOW | DRM_AUTH), -+ DRM_IOCTL_DEF_DRV(V3D_SUBMIT_CSD, v3d_submit_csd_ioctl, DRM_RENDER_ALLOW | DRM_AUTH), - }; - - static const struct vm_operations_struct v3d_vm_ops = { ---- a/drivers/gpu/drm/v3d/v3d_drv.h -+++ b/drivers/gpu/drm/v3d/v3d_drv.h -@@ -16,9 +16,11 @@ enum v3d_queue { - V3D_BIN, - V3D_RENDER, - V3D_TFU, -+ V3D_CSD, -+ V3D_CACHE_CLEAN, - }; - --#define V3D_MAX_QUEUES (V3D_TFU + 1) -+#define V3D_MAX_QUEUES (V3D_CACHE_CLEAN + 1) - - struct v3d_queue_state { - struct drm_gpu_scheduler sched; -@@ -70,6 +72,7 @@ struct v3d_dev { - struct v3d_bin_job *bin_job; - struct v3d_render_job *render_job; - struct v3d_tfu_job *tfu_job; -+ struct v3d_csd_job *csd_job; - - struct v3d_queue_state queue[V3D_MAX_QUEUES]; - -@@ -92,6 +95,12 @@ struct v3d_dev { - */ - struct mutex sched_lock; - -+ /* Lock taken during a cache clean and when initiating an L2 -+ * flush, to keep L2 flushes from interfering with the -+ * synchronous L2 cleans. -+ */ -+ struct mutex cache_clean_lock; -+ - struct { - u32 num_allocated; - u32 pages_allocated; -@@ -104,6 +113,12 @@ to_v3d_dev(struct drm_device *dev) - return (struct v3d_dev *)dev->dev_private; - } - -+static inline bool -+v3d_has_csd(struct v3d_dev *v3d) -+{ -+ return v3d->ver >= 41; -+} -+ - /* The per-fd struct, which tracks the MMU mappings. */ - struct v3d_file_priv { - struct v3d_dev *v3d; -@@ -237,6 +252,14 @@ struct v3d_tfu_job { - struct drm_v3d_submit_tfu args; - }; - -+struct v3d_csd_job { -+ struct v3d_job base; -+ -+ u32 timedout_batches; -+ -+ struct drm_v3d_submit_csd args; -+}; -+ - /** - * _wait_for - magic (register) wait macro - * -@@ -302,11 +325,14 @@ int v3d_submit_cl_ioctl(struct drm_devic - struct drm_file *file_priv); - int v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -+int v3d_submit_csd_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv); - int v3d_wait_bo_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - void v3d_job_put(struct v3d_job *job); - void v3d_reset(struct v3d_dev *v3d); - void v3d_invalidate_caches(struct v3d_dev *v3d); -+void v3d_clean_caches(struct v3d_dev *v3d); - - /* v3d_irq.c */ - int v3d_irq_init(struct v3d_dev *v3d); ---- a/drivers/gpu/drm/v3d/v3d_fence.c -+++ b/drivers/gpu/drm/v3d/v3d_fence.c -@@ -36,6 +36,8 @@ static const char *v3d_fence_get_timelin - return "v3d-render"; - case V3D_TFU: - return "v3d-tfu"; -+ case V3D_CSD: -+ return "v3d-csd"; - default: - return NULL; - } ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -162,10 +162,52 @@ v3d_flush_l2t(struct v3d_dev *v3d, int c - /* While there is a busy bit (V3D_L2TCACTL_L2TFLS), we don't - * need to wait for completion before dispatching the job -- - * L2T accesses will be stalled until the flush has completed. -+ * However, we do need to make sure we don't try to trigger a -+ * new flush while the L2_CLEAN queue is trying to -+ * synchronously clean after a job. - */ -+ mutex_lock(&v3d->cache_clean_lock); - V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, - V3D_L2TCACTL_L2TFLS | - V3D_SET_FIELD(V3D_L2TCACTL_FLM_FLUSH, V3D_L2TCACTL_FLM)); -+ mutex_unlock(&v3d->cache_clean_lock); -+} -+ -+/* Cleans texture L1 and L2 cachelines (writing back dirty data). -+ * -+ * For cleaning, which happens from the CACHE_CLEAN queue after CSD has -+ * executed, we need to make sure that the clean is done before -+ * signaling job completion. So, we synchronously wait before -+ * returning, and we make sure that L2 invalidates don't happen in the -+ * meantime to confuse our are-we-done checks. -+ */ -+void -+v3d_clean_caches(struct v3d_dev *v3d) -+{ -+ struct drm_device *dev = &v3d->drm; -+ int core = 0; -+ -+ trace_v3d_cache_clean_begin(dev); -+ -+ V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, V3D_L2TCACTL_TMUWCF); -+ if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) & -+ V3D_L2TCACTL_L2TFLS), 100)) { -+ DRM_ERROR("Timeout waiting for L1T write combiner flush\n"); -+ } -+ -+ mutex_lock(&v3d->cache_clean_lock); -+ V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, -+ V3D_L2TCACTL_L2TFLS | -+ V3D_SET_FIELD(V3D_L2TCACTL_FLM_CLEAN, V3D_L2TCACTL_FLM)); -+ -+ if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) & -+ V3D_L2TCACTL_L2TFLS), 100)) { -+ DRM_ERROR("Timeout waiting for L2T clean\n"); -+ } -+ -+ mutex_unlock(&v3d->cache_clean_lock); -+ -+ trace_v3d_cache_clean_end(dev); - } - - /* Invalidates the slice caches. These are read-only caches. */ -@@ -584,7 +626,8 @@ static void - v3d_attach_fences_and_unlock_reservation(struct drm_file *file_priv, - struct v3d_job *job, - struct ww_acquire_ctx *acquire_ctx, -- u32 out_sync) -+ u32 out_sync, -+ struct dma_fence *done_fence) - { - struct drm_syncobj *sync_out; - -@@ -594,7 +637,7 @@ v3d_attach_fences_and_unlock_reservation - /* Update the return sync object for the job */ - sync_out = drm_syncobj_find(file_priv, out_sync); - if (sync_out) { -- drm_syncobj_replace_fence(sync_out, job->done_fence); -+ drm_syncobj_replace_fence(sync_out, done_fence); - drm_syncobj_put(sync_out); - } - } -@@ -691,8 +734,10 @@ v3d_submit_cl_ioctl(struct drm_device *d - mutex_unlock(&v3d->sched_lock); - - v3d_attach_fences_and_unlock_reservation(file_priv, -- &render->base, &acquire_ctx, -- args->out_sync); -+ &render->base, -+ &acquire_ctx, -+ args->out_sync, -+ render->base.done_fence); - - if (bin) - v3d_job_put(&bin->base); -@@ -785,7 +830,8 @@ v3d_submit_tfu_ioctl(struct drm_device * - - v3d_attach_fences_and_unlock_reservation(file_priv, - &job->base, &acquire_ctx, -- args->out_sync); -+ args->out_sync, -+ job->base.done_fence); - - v3d_job_put(&job->base); - -@@ -801,6 +847,105 @@ fail: - return ret; - } - -+/** -+ * v3d_submit_csd_ioctl() - Submits a CSD (texture formatting) job to the V3D. -+ * @dev: DRM device -+ * @data: ioctl argument -+ * @file_priv: DRM file for this fd -+ * -+ * Userspace provides the register setup for the CSD, which we don't -+ * need to validate since the CSD is behind the MMU. -+ */ -+int -+v3d_submit_csd_ioctl(struct drm_device *dev, void *data, -+ struct drm_file *file_priv) -+{ -+ struct v3d_dev *v3d = to_v3d_dev(dev); -+ struct v3d_file_priv *v3d_priv = file_priv->driver_priv; -+ struct drm_v3d_submit_csd *args = data; -+ struct v3d_csd_job *job; -+ struct v3d_job *clean_job; -+ struct ww_acquire_ctx acquire_ctx; -+ int ret; -+ -+ trace_v3d_submit_csd_ioctl(&v3d->drm, args->cfg[5], args->cfg[6]); -+ -+ if (!v3d_has_csd(v3d)) { -+ DRM_DEBUG("Attempting CSD submit on non-CSD hardware\n"); -+ return -EINVAL; -+ } -+ -+ job = kcalloc(1, sizeof(*job), GFP_KERNEL); -+ if (!job) -+ return -ENOMEM; -+ -+ ret = v3d_job_init(v3d, file_priv, &job->base, -+ v3d_job_free, args->in_sync); -+ if (ret) { -+ kfree(job); -+ return ret; -+ } -+ -+ clean_job = kcalloc(1, sizeof(*clean_job), GFP_KERNEL); -+ if (!clean_job) { -+ v3d_job_put(&job->base); -+ kfree(job); -+ return -ENOMEM; -+ } -+ -+ ret = v3d_job_init(v3d, file_priv, clean_job, v3d_job_free, 0); -+ if (ret) { -+ v3d_job_put(&job->base); -+ kfree(clean_job); -+ return ret; -+ } -+ -+ job->args = *args; -+ -+ ret = v3d_lookup_bos(dev, file_priv, clean_job, -+ args->bo_handles, args->bo_handle_count); -+ if (ret) -+ goto fail; -+ -+ ret = v3d_lock_bo_reservations(clean_job, &acquire_ctx); -+ if (ret) -+ goto fail; -+ -+ mutex_lock(&v3d->sched_lock); -+ ret = v3d_push_job(v3d_priv, &job->base, V3D_CSD); -+ if (ret) -+ goto fail_unreserve; -+ -+ ret = v3d_add_dep(clean_job, dma_fence_get(job->base.done_fence)); -+ if (ret) -+ goto fail_unreserve; -+ ret = v3d_push_job(v3d_priv, clean_job, V3D_CACHE_CLEAN); -+ if (ret) -+ goto fail_unreserve; -+ mutex_unlock(&v3d->sched_lock); -+ -+ v3d_attach_fences_and_unlock_reservation(file_priv, -+ clean_job, -+ &acquire_ctx, -+ args->out_sync, -+ clean_job->done_fence); -+ -+ v3d_job_put(&job->base); -+ v3d_job_put(clean_job); -+ -+ return 0; -+ -+fail_unreserve: -+ mutex_unlock(&v3d->sched_lock); -+ v3d_unlock_bo_reservations(clean_job->bo, clean_job->bo_count, -+ &acquire_ctx); -+fail: -+ v3d_job_put(&job->base); -+ v3d_job_put(clean_job); -+ -+ return ret; -+} -+ - int - v3d_gem_init(struct drm_device *dev) - { -@@ -816,6 +961,7 @@ v3d_gem_init(struct drm_device *dev) - mutex_init(&v3d->bo_lock); - mutex_init(&v3d->reset_lock); - mutex_init(&v3d->sched_lock); -+ mutex_init(&v3d->cache_clean_lock); - - /* Note: We don't allocate address 0. Various bits of HW - * treat 0 as special, such as the occlusion query counters ---- a/drivers/gpu/drm/v3d/v3d_irq.c -+++ b/drivers/gpu/drm/v3d/v3d_irq.c -@@ -4,9 +4,9 @@ - /** - * DOC: Interrupt management for the V3D engine - * -- * When we take a bin, render, or TFU done interrupt, we need to -- * signal the fence for that job so that the scheduler can queue up -- * the next one and unblock any waiters. -+ * When we take a bin, render, TFU done, or CSD done interrupt, we -+ * need to signal the fence for that job so that the scheduler can -+ * queue up the next one and unblock any waiters. - * - * When we take the binner out of memory interrupt, we need to - * allocate some new memory and pass it to the binner so that the -@@ -20,6 +20,7 @@ - #define V3D_CORE_IRQS ((u32)(V3D_INT_OUTOMEM | \ - V3D_INT_FLDONE | \ - V3D_INT_FRDONE | \ -+ V3D_INT_CSDDONE | \ - V3D_INT_GMPV)) - - #define V3D_HUB_IRQS ((u32)(V3D_HUB_INT_MMU_WRV | \ -@@ -108,6 +109,15 @@ v3d_irq(int irq, void *arg) - dma_fence_signal(&fence->base); - status = IRQ_HANDLED; - } -+ -+ if (intsts & V3D_INT_CSDDONE) { -+ struct v3d_fence *fence = -+ to_v3d_fence(v3d->csd_job->base.irq_fence); -+ -+ trace_v3d_csd_irq(&v3d->drm, fence->seqno); -+ dma_fence_signal(&fence->base); -+ status = IRQ_HANDLED; -+ } - - /* We shouldn't be triggering these if we have GMP in - * always-allowed mode. ---- a/drivers/gpu/drm/v3d/v3d_regs.h -+++ b/drivers/gpu/drm/v3d/v3d_regs.h -@@ -238,8 +238,11 @@ - #define V3D_CTL_L2TCACTL 0x00030 - # define V3D_L2TCACTL_TMUWCF BIT(8) - # define V3D_L2TCACTL_L2T_NO_WM BIT(4) -+/* Invalidates cache lines. */ - # define V3D_L2TCACTL_FLM_FLUSH 0 -+/* Removes cachelines without writing dirty lines back. */ - # define V3D_L2TCACTL_FLM_CLEAR 1 -+/* Writes out dirty cachelines and marks them clean, but doesn't invalidate. */ - # define V3D_L2TCACTL_FLM_CLEAN 2 - # define V3D_L2TCACTL_FLM_MASK V3D_MASK(2, 1) - # define V3D_L2TCACTL_FLM_SHIFT 1 -@@ -255,6 +258,8 @@ - #define V3D_CTL_INT_MSK_CLR 0x00064 - # define V3D_INT_QPU_MASK V3D_MASK(27, 16) - # define V3D_INT_QPU_SHIFT 16 -+# define V3D_INT_CSDDONE BIT(7) -+# define V3D_INT_PCTR BIT(6) - # define V3D_INT_GMPV BIT(5) - # define V3D_INT_TRFB BIT(4) - # define V3D_INT_SPILLUSE BIT(3) -@@ -374,4 +379,72 @@ - #define V3D_GMP_PRESERVE_LOAD 0x00818 - #define V3D_GMP_VALID_LINES 0x00820 - -+#define V3D_CSD_STATUS 0x00900 -+# define V3D_CSD_STATUS_NUM_COMPLETED_MASK V3D_MASK(11, 4) -+# define V3D_CSD_STATUS_NUM_COMPLETED_SHIFT 4 -+# define V3D_CSD_STATUS_NUM_ACTIVE_MASK V3D_MASK(3, 2) -+# define V3D_CSD_STATUS_NUM_ACTIVE_SHIFT 2 -+# define V3D_CSD_STATUS_HAVE_CURRENT_DISPATCH BIT(1) -+# define V3D_CSD_STATUS_HAVE_QUEUED_DISPATCH BIT(0) -+ -+#define V3D_CSD_QUEUED_CFG0 0x00904 -+# define V3D_CSD_QUEUED_CFG0_NUM_WGS_X_MASK V3D_MASK(31, 16) -+# define V3D_CSD_QUEUED_CFG0_NUM_WGS_X_SHIFT 16 -+# define V3D_CSD_QUEUED_CFG0_WG_X_OFFSET_MASK V3D_MASK(15, 0) -+# define V3D_CSD_QUEUED_CFG0_WG_X_OFFSET_SHIFT 0 -+ -+#define V3D_CSD_QUEUED_CFG1 0x00908 -+# define V3D_CSD_QUEUED_CFG1_NUM_WGS_Y_MASK V3D_MASK(31, 16) -+# define V3D_CSD_QUEUED_CFG1_NUM_WGS_Y_SHIFT 16 -+# define V3D_CSD_QUEUED_CFG1_WG_Y_OFFSET_MASK V3D_MASK(15, 0) -+# define V3D_CSD_QUEUED_CFG1_WG_Y_OFFSET_SHIFT 0 -+ -+#define V3D_CSD_QUEUED_CFG2 0x0090c -+# define V3D_CSD_QUEUED_CFG2_NUM_WGS_Z_MASK V3D_MASK(31, 16) -+# define V3D_CSD_QUEUED_CFG2_NUM_WGS_Z_SHIFT 16 -+# define V3D_CSD_QUEUED_CFG2_WG_Z_OFFSET_MASK V3D_MASK(15, 0) -+# define V3D_CSD_QUEUED_CFG2_WG_Z_OFFSET_SHIFT 0 -+ -+#define V3D_CSD_QUEUED_CFG3 0x00910 -+# define V3D_CSD_QUEUED_CFG3_OVERLAP_WITH_PREV BIT(26) -+# define V3D_CSD_QUEUED_CFG3_MAX_SG_ID_MASK V3D_MASK(25, 20) -+# define V3D_CSD_QUEUED_CFG3_MAX_SG_ID_SHIFT 20 -+# define V3D_CSD_QUEUED_CFG3_BATCHES_PER_SG_M1_MASK V3D_MASK(19, 12) -+# define V3D_CSD_QUEUED_CFG3_BATCHES_PER_SG_M1_SHIFT 12 -+# define V3D_CSD_QUEUED_CFG3_WGS_PER_SG_MASK V3D_MASK(11, 8) -+# define V3D_CSD_QUEUED_CFG3_WGS_PER_SG_SHIFT 8 -+# define V3D_CSD_QUEUED_CFG3_WG_SIZE_MASK V3D_MASK(7, 0) -+# define V3D_CSD_QUEUED_CFG3_WG_SIZE_SHIFT 0 -+ -+/* Number of batches, minus 1 */ -+#define V3D_CSD_QUEUED_CFG4 0x00914 -+ -+/* Shader address, pnan, singleseg, threading, like a shader record. */ -+#define V3D_CSD_QUEUED_CFG5 0x00918 -+ -+/* Uniforms address (4 byte aligned) */ -+#define V3D_CSD_QUEUED_CFG6 0x0091c -+ -+#define V3D_CSD_CURRENT_CFG0 0x00920 -+#define V3D_CSD_CURRENT_CFG1 0x00924 -+#define V3D_CSD_CURRENT_CFG2 0x00928 -+#define V3D_CSD_CURRENT_CFG3 0x0092c -+#define V3D_CSD_CURRENT_CFG4 0x00930 -+#define V3D_CSD_CURRENT_CFG5 0x00934 -+#define V3D_CSD_CURRENT_CFG6 0x00938 -+ -+#define V3D_CSD_CURRENT_ID0 0x0093c -+# define V3D_CSD_CURRENT_ID0_WG_X_MASK V3D_MASK(31, 16) -+# define V3D_CSD_CURRENT_ID0_WG_X_SHIFT 16 -+# define V3D_CSD_CURRENT_ID0_WG_IN_SG_MASK V3D_MASK(11, 8) -+# define V3D_CSD_CURRENT_ID0_WG_IN_SG_SHIFT 8 -+# define V3D_CSD_CURRENT_ID0_L_IDX_MASK V3D_MASK(7, 0) -+# define V3D_CSD_CURRENT_ID0_L_IDX_SHIFT 0 -+ -+#define V3D_CSD_CURRENT_ID1 0x00940 -+# define V3D_CSD_CURRENT_ID0_WG_Z_MASK V3D_MASK(31, 16) -+# define V3D_CSD_CURRENT_ID0_WG_Z_SHIFT 16 -+# define V3D_CSD_CURRENT_ID0_WG_Y_MASK V3D_MASK(15, 0) -+# define V3D_CSD_CURRENT_ID0_WG_Y_SHIFT 0 -+ - #endif /* V3D_REGS_H */ ---- a/drivers/gpu/drm/v3d/v3d_sched.c -+++ b/drivers/gpu/drm/v3d/v3d_sched.c -@@ -48,6 +48,12 @@ to_tfu_job(struct drm_sched_job *sched_j - return container_of(sched_job, struct v3d_tfu_job, base.base); - } - -+static struct v3d_csd_job * -+to_csd_job(struct drm_sched_job *sched_job) -+{ -+ return container_of(sched_job, struct v3d_csd_job, base.base); -+} -+ - static void - v3d_job_free(struct drm_sched_job *sched_job) - { -@@ -205,6 +211,48 @@ v3d_tfu_job_run(struct drm_sched_job *sc - return fence; - } - -+static struct dma_fence * -+v3d_csd_job_run(struct drm_sched_job *sched_job) -+{ -+ struct v3d_csd_job *job = to_csd_job(sched_job); -+ struct v3d_dev *v3d = job->base.v3d; -+ struct drm_device *dev = &v3d->drm; -+ struct dma_fence *fence; -+ int i; -+ -+ v3d->csd_job = job; -+ -+ v3d_invalidate_caches(v3d); -+ -+ fence = v3d_fence_create(v3d, V3D_CSD); -+ if (IS_ERR(fence)) -+ return NULL; -+ -+ if (job->base.irq_fence) -+ dma_fence_put(job->base.irq_fence); -+ job->base.irq_fence = dma_fence_get(fence); -+ -+ trace_v3d_submit_csd(dev, to_v3d_fence(fence)->seqno); -+ -+ for (i = 1; i <= 6; i++) -+ V3D_CORE_WRITE(0, V3D_CSD_QUEUED_CFG0 + 4 * i, job->args.cfg[i]); -+ /* CFG0 write kicks off the job. */ -+ V3D_CORE_WRITE(0, V3D_CSD_QUEUED_CFG0, job->args.cfg[0]); -+ -+ return fence; -+} -+ -+static struct dma_fence * -+v3d_cache_clean_job_run(struct drm_sched_job *sched_job) -+{ -+ struct v3d_job *job = to_v3d_job(sched_job); -+ struct v3d_dev *v3d = job->v3d; -+ -+ v3d_clean_caches(v3d); -+ -+ return NULL; -+} -+ - static void - v3d_gpu_reset_for_timeout(struct v3d_dev *v3d, struct drm_sched_job *sched_job) - { -@@ -277,13 +325,31 @@ v3d_render_job_timedout(struct drm_sched - } - - static void --v3d_tfu_job_timedout(struct drm_sched_job *sched_job) -+v3d_generic_job_timedout(struct drm_sched_job *sched_job) - { - struct v3d_job *job = to_v3d_job(sched_job); - - v3d_gpu_reset_for_timeout(job->v3d, sched_job); - } - -+static void -+v3d_csd_job_timedout(struct drm_sched_job *sched_job) -+{ -+ struct v3d_csd_job *job = to_csd_job(sched_job); -+ struct v3d_dev *v3d = job->base.v3d; -+ u32 batches = V3D_CORE_READ(0, V3D_CSD_CURRENT_CFG4); -+ -+ /* If we've made progress, skip reset and let the timer get -+ * rearmed. -+ */ -+ if (job->timedout_batches != batches) { -+ job->timedout_batches = batches; -+ return; -+ } -+ -+ v3d_gpu_reset_for_timeout(v3d, sched_job); -+} -+ - static const struct drm_sched_backend_ops v3d_bin_sched_ops = { - .dependency = v3d_job_dependency, - .run_job = v3d_bin_job_run, -@@ -301,10 +367,24 @@ static const struct drm_sched_backend_op - static const struct drm_sched_backend_ops v3d_tfu_sched_ops = { - .dependency = v3d_job_dependency, - .run_job = v3d_tfu_job_run, -- .timedout_job = v3d_tfu_job_timedout, -+ .timedout_job = v3d_generic_job_timedout, - .free_job = v3d_job_free, - }; - -+static const struct drm_sched_backend_ops v3d_csd_sched_ops = { -+ .dependency = v3d_job_dependency, -+ .run_job = v3d_csd_job_run, -+ .timedout_job = v3d_csd_job_timedout, -+ .free_job = v3d_job_free -+}; -+ -+static const struct drm_sched_backend_ops v3d_cache_clean_sched_ops = { -+ .dependency = v3d_job_dependency, -+ .run_job = v3d_cache_clean_job_run, -+ .timedout_job = v3d_generic_job_timedout, -+ .free_job = v3d_job_free -+}; -+ - int - v3d_sched_init(struct v3d_dev *v3d) - { -@@ -331,7 +411,7 @@ v3d_sched_init(struct v3d_dev *v3d) - if (ret) { - dev_err(v3d->dev, "Failed to create render scheduler: %d.", - ret); -- drm_sched_fini(&v3d->queue[V3D_BIN].sched); -+ v3d_sched_fini(v3d); - return ret; - } - -@@ -343,11 +423,36 @@ v3d_sched_init(struct v3d_dev *v3d) - if (ret) { - dev_err(v3d->dev, "Failed to create TFU scheduler: %d.", - ret); -- drm_sched_fini(&v3d->queue[V3D_RENDER].sched); -- drm_sched_fini(&v3d->queue[V3D_BIN].sched); -+ v3d_sched_fini(v3d); - return ret; - } - -+ if (v3d_has_csd(v3d)) { -+ ret = drm_sched_init(&v3d->queue[V3D_CSD].sched, -+ &v3d_csd_sched_ops, -+ hw_jobs_limit, job_hang_limit, -+ msecs_to_jiffies(hang_limit_ms), -+ "v3d_csd"); -+ if (ret) { -+ dev_err(v3d->dev, "Failed to create CSD scheduler: %d.", -+ ret); -+ v3d_sched_fini(v3d); -+ return ret; -+ } -+ -+ ret = drm_sched_init(&v3d->queue[V3D_CACHE_CLEAN].sched, -+ &v3d_cache_clean_sched_ops, -+ hw_jobs_limit, job_hang_limit, -+ msecs_to_jiffies(hang_limit_ms), -+ "v3d_cache_clean"); -+ if (ret) { -+ dev_err(v3d->dev, "Failed to create CACHE_CLEAN scheduler: %d.", -+ ret); -+ v3d_sched_fini(v3d); -+ return ret; -+ } -+ } -+ - return 0; - } - -@@ -356,6 +461,8 @@ v3d_sched_fini(struct v3d_dev *v3d) - { - enum v3d_queue q; - -- for (q = 0; q < V3D_MAX_QUEUES; q++) -- drm_sched_fini(&v3d->queue[q].sched); -+ for (q = 0; q < V3D_MAX_QUEUES; q++) { -+ if (v3d->queue[q].sched.ops) -+ drm_sched_fini(&v3d->queue[q].sched); -+ } - } ---- a/drivers/gpu/drm/v3d/v3d_trace.h -+++ b/drivers/gpu/drm/v3d/v3d_trace.h -@@ -124,6 +124,26 @@ TRACE_EVENT(v3d_tfu_irq, - __entry->seqno) - ); - -+TRACE_EVENT(v3d_csd_irq, -+ TP_PROTO(struct drm_device *dev, -+ uint64_t seqno), -+ TP_ARGS(dev, seqno), -+ -+ TP_STRUCT__entry( -+ __field(u32, dev) -+ __field(u64, seqno) -+ ), -+ -+ TP_fast_assign( -+ __entry->dev = dev->primary->index; -+ __entry->seqno = seqno; -+ ), -+ -+ TP_printk("dev=%u, seqno=%llu", -+ __entry->dev, -+ __entry->seqno) -+); -+ - TRACE_EVENT(v3d_submit_tfu_ioctl, - TP_PROTO(struct drm_device *dev, u32 iia), - TP_ARGS(dev, iia), -@@ -163,6 +183,80 @@ TRACE_EVENT(v3d_submit_tfu, - __entry->seqno) - ); - -+TRACE_EVENT(v3d_submit_csd_ioctl, -+ TP_PROTO(struct drm_device *dev, u32 cfg5, u32 cfg6), -+ TP_ARGS(dev, cfg5, cfg6), -+ -+ TP_STRUCT__entry( -+ __field(u32, dev) -+ __field(u32, cfg5) -+ __field(u32, cfg6) -+ ), -+ -+ TP_fast_assign( -+ __entry->dev = dev->primary->index; -+ __entry->cfg5 = cfg5; -+ __entry->cfg6 = cfg6; -+ ), -+ -+ TP_printk("dev=%u, CFG5 0x%08x, CFG6 0x%08x", -+ __entry->dev, -+ __entry->cfg5, -+ __entry->cfg6) -+); -+ -+TRACE_EVENT(v3d_submit_csd, -+ TP_PROTO(struct drm_device *dev, -+ uint64_t seqno), -+ TP_ARGS(dev, seqno), -+ -+ TP_STRUCT__entry( -+ __field(u32, dev) -+ __field(u64, seqno) -+ ), -+ -+ TP_fast_assign( -+ __entry->dev = dev->primary->index; -+ __entry->seqno = seqno; -+ ), -+ -+ TP_printk("dev=%u, seqno=%llu", -+ __entry->dev, -+ __entry->seqno) -+); -+ -+TRACE_EVENT(v3d_cache_clean_begin, -+ TP_PROTO(struct drm_device *dev), -+ TP_ARGS(dev), -+ -+ TP_STRUCT__entry( -+ __field(u32, dev) -+ ), -+ -+ TP_fast_assign( -+ __entry->dev = dev->primary->index; -+ ), -+ -+ TP_printk("dev=%u", -+ __entry->dev) -+); -+ -+TRACE_EVENT(v3d_cache_clean_end, -+ TP_PROTO(struct drm_device *dev), -+ TP_ARGS(dev), -+ -+ TP_STRUCT__entry( -+ __field(u32, dev) -+ ), -+ -+ TP_fast_assign( -+ __entry->dev = dev->primary->index; -+ ), -+ -+ TP_printk("dev=%u", -+ __entry->dev) -+); -+ - TRACE_EVENT(v3d_reset_begin, - TP_PROTO(struct drm_device *dev), - TP_ARGS(dev), ---- a/include/uapi/drm/v3d_drm.h -+++ b/include/uapi/drm/v3d_drm.h -@@ -37,6 +37,7 @@ extern "C" { - #define DRM_V3D_GET_PARAM 0x04 - #define DRM_V3D_GET_BO_OFFSET 0x05 - #define DRM_V3D_SUBMIT_TFU 0x06 -+#define DRM_V3D_SUBMIT_CSD 0x07 - - #define DRM_IOCTL_V3D_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CL, struct drm_v3d_submit_cl) - #define DRM_IOCTL_V3D_WAIT_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_WAIT_BO, struct drm_v3d_wait_bo) -@@ -45,6 +46,7 @@ extern "C" { - #define DRM_IOCTL_V3D_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_GET_PARAM, struct drm_v3d_get_param) - #define DRM_IOCTL_V3D_GET_BO_OFFSET DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_GET_BO_OFFSET, struct drm_v3d_get_bo_offset) - #define DRM_IOCTL_V3D_SUBMIT_TFU DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_TFU, struct drm_v3d_submit_tfu) -+#define DRM_IOCTL_V3D_SUBMIT_CSD DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CSD, struct drm_v3d_submit_csd) - - /** - * struct drm_v3d_submit_cl - ioctl argument for submitting commands to the 3D -@@ -172,6 +174,7 @@ enum drm_v3d_param { - DRM_V3D_PARAM_V3D_CORE0_IDENT1, - DRM_V3D_PARAM_V3D_CORE0_IDENT2, - DRM_V3D_PARAM_SUPPORTS_TFU, -+ DRM_V3D_PARAM_SUPPORTS_CSD, - }; - - struct drm_v3d_get_param { -@@ -212,6 +215,31 @@ struct drm_v3d_submit_tfu { - __u32 out_sync; - }; - -+/* Submits a compute shader for dispatch. This job will block on any -+ * previous compute shaders submitted on this fd, and any other -+ * synchronization must be performed with in_sync/out_sync. -+ */ -+struct drm_v3d_submit_csd { -+ __u32 cfg[7]; -+ __u32 coef[4]; -+ -+ /* Pointer to a u32 array of the BOs that are referenced by the job. -+ */ -+ __u64 bo_handles; -+ -+ /* Number of BO handles passed in (size is that times 4). */ -+ __u32 bo_handle_count; -+ -+ /* sync object to block on before running the CSD job. Each -+ * CSD job will execute in the order submitted to its FD. -+ * Synchronization against rendering/TFU jobs or CSD from -+ * other fds requires using sync objects. -+ */ -+ __u32 in_sync; -+ /* Sync object to signal when the CSD job is done. */ -+ __u32 out_sync; -+}; -+ - #if defined(__cplusplus) - } - #endif diff --git a/target/linux/brcm2708/patches-4.19/950-0616-drm-vc4-Log-flags-in-fkms-mode-set.patch b/target/linux/brcm2708/patches-4.19/950-0616-drm-vc4-Log-flags-in-fkms-mode-set.patch new file mode 100644 index 0000000000..ed4b24e1c3 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0616-drm-vc4-Log-flags-in-fkms-mode-set.patch @@ -0,0 +1,31 @@ +From 8a35a7bb6b1a0182adf1e92d138b7d88f93abbb6 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 7 May 2019 12:13:34 +0100 +Subject: [PATCH 616/725] drm: vc4: Log flags in fkms mode set + +The flags contain info such as limited/full range RGB, aspect +ratio, and a fwe other useful things. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -685,12 +685,13 @@ static void vc4_crtc_mode_set_nofb(struc + return; + } + +- DRM_DEBUG_KMS("Setting mode for display num %u mode name %s, clk %d, h(disp %d, start %d, end %d, total %d, skew %d) v(disp %d, start %d, end %d, total %d, scan %d), vrefresh %d, par %u\n", ++ DRM_DEBUG_KMS("Setting mode for display num %u mode name %s, clk %d, h(disp %d, start %d, end %d, total %d, skew %d) v(disp %d, start %d, end %d, total %d, scan %d), vrefresh %d, par %u, flags 0x%04x\n", + vc4_crtc->display_number, mode->name, mode->clock, + mode->hdisplay, mode->hsync_start, mode->hsync_end, + mode->htotal, mode->hskew, mode->vdisplay, + mode->vsync_start, mode->vsync_end, mode->vtotal, +- mode->vscan, mode->vrefresh, mode->picture_aspect_ratio); ++ mode->vscan, mode->vrefresh, mode->picture_aspect_ratio, ++ mode->flags); + mb.timings.display = vc4_crtc->display_number; + + mb.timings.video_id_code = frame.avi.video_code; diff --git a/target/linux/brcm2708/patches-4.19/950-0617-drm-v3d-Clock-V3D-down-when-not-in-use.patch b/target/linux/brcm2708/patches-4.19/950-0617-drm-v3d-Clock-V3D-down-when-not-in-use.patch deleted file mode 100644 index 7472b69156..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0617-drm-v3d-Clock-V3D-down-when-not-in-use.patch +++ /dev/null @@ -1,157 +0,0 @@ -From 167429373da6ab4f3f498013277eb5545d6f0c64 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 2 May 2019 13:22:53 -0700 -Subject: [PATCH 617/703] drm/v3d: Clock V3D down when not in use. - -My various attempts at re-enabling runtime PM have failed, so just -crank the clock down when V3D is idle to reduce power consumption. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/v3d/v3d_drv.c | 18 +++++++++++++ - drivers/gpu/drm/v3d/v3d_drv.h | 6 +++++ - drivers/gpu/drm/v3d/v3d_gem.c | 49 +++++++++++++++++++++++++++++++++++ - 3 files changed, 73 insertions(+) - ---- a/drivers/gpu/drm/v3d/v3d_drv.c -+++ b/drivers/gpu/drm/v3d/v3d_drv.c -@@ -297,6 +297,21 @@ static int v3d_platform_drm_probe(struct - } - } - -+ v3d->clk = devm_clk_get(dev, NULL); -+ if (IS_ERR(v3d->clk)) { -+ if (ret != -EPROBE_DEFER) -+ dev_err(dev, "Failed to get clock\n"); -+ goto dev_free; -+ } -+ v3d->clk_up_rate = clk_get_rate(v3d->clk); -+ /* For downclocking, drop it to the minimum frequency we can get from -+ * the CPRMAN clock generator dividing off our parent. The divider is -+ * 4 bits, but ask for just higher than that so that rounding doesn't -+ * make cprman reject our rate. -+ */ -+ v3d->clk_down_rate = -+ (clk_get_rate(clk_get_parent(v3d->clk)) / (1 << 4)) + 10000; -+ - if (v3d->ver < 41) { - ret = map_regs(v3d, &v3d->gca_regs, "gca"); - if (ret) -@@ -331,6 +346,9 @@ static int v3d_platform_drm_probe(struct - if (ret) - goto irq_disable; - -+ ret = clk_set_rate(v3d->clk, v3d->clk_down_rate); -+ WARN_ON_ONCE(ret != 0); -+ - return 0; - - irq_disable: ---- a/drivers/gpu/drm/v3d/v3d_drv.h -+++ b/drivers/gpu/drm/v3d/v3d_drv.h -@@ -45,6 +45,12 @@ struct v3d_dev { - void __iomem *bridge_regs; - void __iomem *gca_regs; - struct clk *clk; -+ struct delayed_work clk_down_work; -+ unsigned long clk_up_rate, clk_down_rate; -+ struct mutex clk_lock; -+ u32 clk_refcount; -+ bool clk_up; -+ - struct reset_control *reset; - - /* Virtual and DMA addresses of the single shared page table. */ ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -3,6 +3,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -17,6 +18,47 @@ - #include "v3d_trace.h" - - static void -+v3d_clock_down_work(struct work_struct *work) -+{ -+ struct v3d_dev *v3d = -+ container_of(work, struct v3d_dev, clk_down_work.work); -+ int ret; -+ -+ ret = clk_set_rate(v3d->clk, v3d->clk_down_rate); -+ v3d->clk_up = false; -+ WARN_ON_ONCE(ret != 0); -+} -+ -+static void -+v3d_clock_up_get(struct v3d_dev *v3d) -+{ -+ mutex_lock(&v3d->clk_lock); -+ if (v3d->clk_refcount++ == 0) { -+ cancel_delayed_work_sync(&v3d->clk_down_work); -+ if (!v3d->clk_up) { -+ int ret; -+ -+ ret = clk_set_rate(v3d->clk, v3d->clk_up_rate); -+ WARN_ON_ONCE(ret != 0); -+ v3d->clk_up = true; -+ } -+ } -+ mutex_unlock(&v3d->clk_lock); -+} -+ -+static void -+v3d_clock_up_put(struct v3d_dev *v3d) -+{ -+ mutex_lock(&v3d->clk_lock); -+ if (--v3d->clk_refcount == 0) { -+ schedule_delayed_work(&v3d->clk_down_work, -+ msecs_to_jiffies(100)); -+ } -+ mutex_unlock(&v3d->clk_lock); -+} -+ -+ -+static void - v3d_init_core(struct v3d_dev *v3d, int core) - { - /* Set OVRTMUOUT, which means that the texture sampler uniform -@@ -490,6 +532,7 @@ static void - v3d_job_free(struct kref *ref) - { - struct v3d_job *job = container_of(ref, struct v3d_job, refcount); -+ struct v3d_dev *v3d = job->v3d; - int i; - - for (i = 0; i < job->bo_count; i++) { -@@ -505,6 +548,8 @@ v3d_job_free(struct kref *ref) - dma_fence_put(job->irq_fence); - dma_fence_put(job->done_fence); - -+ v3d_clock_up_put(v3d); -+ - kfree(job); - } - -@@ -596,6 +641,7 @@ v3d_job_init(struct v3d_dev *v3d, struct - if (ret) - return ret; - -+ v3d_clock_up_get(v3d); - kref_init(&job->refcount); - - return 0; -@@ -963,6 +1009,9 @@ v3d_gem_init(struct drm_device *dev) - mutex_init(&v3d->sched_lock); - mutex_init(&v3d->cache_clean_lock); - -+ mutex_init(&v3d->clk_lock); -+ INIT_DELAYED_WORK(&v3d->clk_down_work, v3d_clock_down_work); -+ - /* Note: We don't allocate address 0. Various bits of HW - * treat 0 as special, such as the occlusion query counters - * where 0 means "disabled". diff --git a/target/linux/brcm2708/patches-4.19/950-0617-drm-vc4-firmware-kms-Fix-DSI-display-support.patch b/target/linux/brcm2708/patches-4.19/950-0617-drm-vc4-firmware-kms-Fix-DSI-display-support.patch new file mode 100644 index 0000000000..fc6fb4bc90 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0617-drm-vc4-firmware-kms-Fix-DSI-display-support.patch @@ -0,0 +1,25 @@ +From aee8bec6a1a39eb97dd5af86b4126d5e1ced2ac6 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 16 May 2019 17:49:42 +0100 +Subject: [PATCH 617/725] drm: vc4-firmware-kms: Fix DSI display support + +The mode was incorrectly listed as interlaced, which was then +rejected. +Correct this and FKMS works with the DSI display. + +Signed-off-by: Dave Stevenson +--- + 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 +@@ -1003,7 +1003,7 @@ static const struct drm_display_mode lcd + 25979400 / 1000, + 800, 800 + 1, 800 + 1 + 2, 800 + 1 + 2 + 46, 0, + 480, 480 + 7, 480 + 7 + 2, 480 + 7 + 2 + 21, 0, +- DRM_MODE_FLAG_INTERLACE) ++ 0) + }; + + static int vc4_fkms_lcd_connector_get_modes(struct drm_connector *connector) diff --git a/target/linux/brcm2708/patches-4.19/950-0618-HACK-clk-bcm2835-Add-BCM2838_CLOCK_EMMC2-support.patch b/target/linux/brcm2708/patches-4.19/950-0618-HACK-clk-bcm2835-Add-BCM2838_CLOCK_EMMC2-support.patch deleted file mode 100644 index 8fcc570c0f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0618-HACK-clk-bcm2835-Add-BCM2838_CLOCK_EMMC2-support.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 00f31bede51da02552b235fc93d35f357f13378a Mon Sep 17 00:00:00 2001 -From: Stefan Wahren -Date: Thu, 2 May 2019 23:42:29 +0200 -Subject: [PATCH 618/703] HACK: clk-bcm2835: Add BCM2838_CLOCK_EMMC2 support - -The new BCM2838 supports an additional emmc2 clock. So add a new -compatible to register this clock only for BCM2838. - -Signed-off-by: Stefan Wahren ---- - drivers/clk/bcm/clk-bcm2835.c | 20 ++++++++++++++++++-- - include/dt-bindings/clock/bcm2835.h | 2 ++ - 2 files changed, 20 insertions(+), 2 deletions(-) - ---- a/drivers/clk/bcm/clk-bcm2835.c -+++ b/drivers/clk/bcm/clk-bcm2835.c -@@ -124,6 +124,8 @@ - #define CM_AVEODIV 0x1bc - #define CM_EMMCCTL 0x1c0 - #define CM_EMMCDIV 0x1c4 -+#define CM_EMMC2CTL 0x1d0 -+#define CM_EMMC2DIV 0x1d4 - - /* General bits for the CM_*CTL regs */ - # define CM_ENABLE BIT(4) -@@ -2047,6 +2049,15 @@ static const struct bcm2835_clk_desc clk - .frac_bits = 8, - .tcnt_mux = 39), - -+ /* EMMC2 clock (only available for BCM2838) */ -+ [BCM2838_CLOCK_EMMC2] = REGISTER_PER_CLK( -+ .name = "emmc2", -+ .ctl_reg = CM_EMMC2CTL, -+ .div_reg = CM_EMMC2DIV, -+ .int_bits = 4, -+ .frac_bits = 8, -+ .tcnt_mux = 42), -+ - /* General purpose (GPIO) clocks */ - [BCM2835_CLOCK_GP0] = REGISTER_PER_CLK( - .name = "gp0", -@@ -2276,8 +2287,12 @@ static int bcm2835_clk_probe(struct plat - - for (i = 0; i < asize; i++) { - desc = &clk_desc_array[i]; -- if (desc->clk_register && desc->data) -- hws[i] = desc->clk_register(cprman, desc->data); -+ if (desc->clk_register && desc->data) { -+ if ((i != BCM2838_CLOCK_EMMC2) || -+ of_device_is_compatible(fw_node, "brcm,bcm2838-cprman")) { -+ hws[i] = desc->clk_register(cprman, desc->data); -+ } -+ } - } - - ret = bcm2835_mark_sdc_parent_critical(hws[BCM2835_CLOCK_SDRAM]->clk); -@@ -2297,6 +2312,7 @@ static int bcm2835_clk_probe(struct plat - - static const struct of_device_id bcm2835_clk_of_match[] = { - { .compatible = "brcm,bcm2835-cprman", }, -+ { .compatible = "brcm,bcm2838-cprman", }, - {} - }; - MODULE_DEVICE_TABLE(of, bcm2835_clk_of_match); ---- a/include/dt-bindings/clock/bcm2835.h -+++ b/include/dt-bindings/clock/bcm2835.h -@@ -66,3 +66,5 @@ - #define BCM2835_CLOCK_DSI1E 48 - #define BCM2835_CLOCK_DSI0P 49 - #define BCM2835_CLOCK_DSI1P 50 -+ -+#define BCM2838_CLOCK_EMMC2 51 diff --git a/target/linux/brcm2708/patches-4.19/950-0618-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch b/target/linux/brcm2708/patches-4.19/950-0618-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch new file mode 100644 index 0000000000..9849a95c46 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0618-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch @@ -0,0 +1,120 @@ +From f77057c81999f0cf6da1c4eab08ce57189279a14 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 21 May 2019 11:50:00 +0100 +Subject: [PATCH 618/725] drm: vc4: Probe DPI/DSI timings from the firmware + +For DPI and DSI displays query the firmware as to the configuration +and add it as the only mode for DRM. + +In theory we can add plumbing for setting the DPI/DSI mode from +KMS, but this is not being added at present as the support frameworks +aren't present in the firmware. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 60 ++++++++++++++++++---- + include/soc/bcm2835/raspberrypi-firmware.h | 1 + + 2 files changed, 51 insertions(+), 10 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -280,7 +280,7 @@ static u32 vc4_get_display_type(u32 disp + /* The firmware display (DispmanX) IDs map to specific types in + * a fixed manner. + */ +- DRM_MODE_ENCODER_DSI, /* MAIN_LCD */ ++ DRM_MODE_ENCODER_DSI, /* MAIN_LCD - DSI or DPI */ + DRM_MODE_ENCODER_DSI, /* AUX_LCD */ + DRM_MODE_ENCODER_TMDS, /* HDMI0 */ + DRM_MODE_ENCODER_TVDAC, /* VEC */ +@@ -362,7 +362,6 @@ static void vc4_plane_atomic_update(stru + vc4_get_vc_image_fmt(drm_fmt->format); + struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane); + struct mailbox_set_plane *mb = &vc4_plane->mb; +- struct vc4_crtc *vc4_crtc = to_vc4_crtc(state->crtc); + int num_planes = fb->format->num_planes; + struct drm_display_mode *mode = &state->crtc->mode; + unsigned int rotation = SUPPORTED_ROTATIONS; +@@ -997,7 +996,9 @@ static int vc4_fkms_connector_get_modes( + return ret; + } + +-/* FIXME: Read LCD mode from the firmware. This is the DSI panel resolution. */ ++/* This is the DSI panel resolution. Use this as a default should the firmware ++ * not respond to our request for the timings. ++ */ + static const struct drm_display_mode lcd_mode = { + DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, + 25979400 / 1000, +@@ -1008,15 +1009,54 @@ static const struct drm_display_mode lcd + + static int vc4_fkms_lcd_connector_get_modes(struct drm_connector *connector) + { +- //struct vc4_fkms_connector *fkms_connector = +- // to_vc4_fkms_connector(connector); +- //struct drm_encoder *encoder = fkms_connector->encoder; +- //struct vc4_fkms_encoder *vc4_encoder = to_vc4_fkms_encoder(encoder); ++ struct vc4_fkms_connector *fkms_connector = ++ to_vc4_fkms_connector(connector); ++ struct vc4_dev *vc4 = fkms_connector->vc4_dev; + struct drm_display_mode *mode; +- //int ret = 0; ++ struct mailbox_set_mode mb = { ++ .tag1 = { RPI_FIRMWARE_GET_DISPLAY_TIMING, ++ sizeof(struct set_timings), 0}, ++ .timings = { .display = fkms_connector->display_number }, ++ }; ++ struct drm_display_mode fw_mode; ++ int ret = 0; ++ ++ ret = rpi_firmware_property_list(vc4->firmware, &mb, sizeof(mb)); ++ if (!ret) { ++ /* Equivalent to DRM_MODE macro. */ ++ memset(&fw_mode, 0, sizeof(fw_mode)); ++ strncpy(fw_mode.name, "LCD_MODE", sizeof(fw_mode.name)); ++ fw_mode.status = 0; ++ fw_mode.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; ++ fw_mode.clock = mb.timings.clock; ++ fw_mode.hdisplay = mb.timings.hdisplay; ++ fw_mode.hsync_start = mb.timings.hsync_start; ++ fw_mode.hsync_end = mb.timings.hsync_end; ++ fw_mode.htotal = mb.timings.htotal; ++ fw_mode.hskew = 0; ++ fw_mode.vdisplay = mb.timings.vdisplay; ++ fw_mode.vsync_start = mb.timings.vsync_start; ++ fw_mode.vsync_end = mb.timings.vsync_end; ++ fw_mode.vtotal = mb.timings.vtotal; ++ fw_mode.vscan = mb.timings.vscan; ++ if (mb.timings.flags & TIMINGS_FLAGS_H_SYNC_POS) ++ fw_mode.flags |= DRM_MODE_FLAG_PHSYNC; ++ else ++ fw_mode.flags |= DRM_MODE_FLAG_NHSYNC; ++ if (mb.timings.flags & TIMINGS_FLAGS_V_SYNC_POS) ++ fw_mode.flags |= DRM_MODE_FLAG_PVSYNC; ++ else ++ fw_mode.flags |= DRM_MODE_FLAG_NVSYNC; ++ ++ fw_mode.base.type = DRM_MODE_OBJECT_MODE; ++ ++ mode = drm_mode_duplicate(connector->dev, ++ &fw_mode); ++ } else { ++ mode = drm_mode_duplicate(connector->dev, ++ &lcd_mode); ++ } + +- mode = drm_mode_duplicate(connector->dev, +- &lcd_mode); + if (!mode) { + DRM_ERROR("Failed to create a new display mode\n"); + return -ENOMEM; +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -151,6 +151,7 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, + + RPI_FIRMWARE_SET_PLANE = 0x00048015, ++ RPI_FIRMWARE_GET_DISPLAY_TIMING = 0x00040017, + RPI_FIRMWARE_SET_TIMING = 0x00048017, + + RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, diff --git a/target/linux/brcm2708/patches-4.19/950-0619-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch b/target/linux/brcm2708/patches-4.19/950-0619-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch deleted file mode 100644 index 09b93e505d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0619-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 7e50ab877c14dff56f0836d6b79d9f6964b5e8b1 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 3 May 2019 13:58:03 +0100 -Subject: [PATCH 619/703] drm: vc4-firmware-kms: Remove incorrect overscan - support. - -The overscan support was required for the old mailbox API -in order to match up the cursor and frame buffer planes. -With the newer API directly talking to dispmanx there is no -difference, therefore FKMS does not need to make any -adjustments. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 15 --------------- - 1 file changed, 15 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -232,7 +232,6 @@ struct vc4_crtc { - void __iomem *regs; - - struct drm_pending_vblank_event *event; -- u32 overscan[4]; - bool vblank_enabled; - u32 display_number; - u32 display_type; -@@ -468,11 +467,6 @@ static void vc4_plane_atomic_update(stru - break; - } - -- if (vc4_crtc) { -- mb->plane.dst_x += vc4_crtc->overscan[0]; -- mb->plane.dst_y += vc4_crtc->overscan[1]; -- } -- - DRM_DEBUG_ATOMIC("[PLANE:%d:%s] plane update %dx%d@%d +dst(%d,%d, %d,%d) +src(%d,%d, %d,%d) 0x%08x/%08x/%08x/%d, alpha %u zpos %u\n", - plane->base.id, plane->name, - mb->plane.width, -@@ -1228,15 +1222,6 @@ static int vc4_fkms_create_screen(struct - goto err_destroy_encoder; - } - -- ret = rpi_firmware_property(vc4->firmware, -- RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN, -- &vc4_crtc->overscan, -- sizeof(vc4_crtc->overscan)); -- if (ret) { -- DRM_ERROR("Failed to get overscan state: 0x%08x\n", vc4_crtc->overscan[0]); -- memset(&vc4_crtc->overscan, 0, sizeof(vc4_crtc->overscan)); -- } -- - *ret_crtc = vc4_crtc; - - return 0; diff --git a/target/linux/brcm2708/patches-4.19/950-0619-drm-vc4-handle-the-case-where-there-are-no-available.patch b/target/linux/brcm2708/patches-4.19/950-0619-drm-vc4-handle-the-case-where-there-are-no-available.patch new file mode 100644 index 0000000000..9f302c2e5e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0619-drm-vc4-handle-the-case-where-there-are-no-available.patch @@ -0,0 +1,67 @@ +From 234c55d9e6bb7fa68466a599bd1665bcd89a99d2 Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Tue, 28 May 2019 13:56:06 +0100 +Subject: [PATCH 619/725] drm: vc4: handle the case where there are no + available displays + +It's reasonable for the firmware to return zero as the number of +attached displays. Handle this case as otherwise drm thinks that +the DSI panel is attached, which is nonsense. + +Signed-off-by: Jonathan Bell +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 32 +++++++++++++++----------- + 1 file changed, 18 insertions(+), 14 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -1309,13 +1309,13 @@ static int vc4_fkms_bind(struct device * + RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS, + &num_displays, sizeof(u32)); + +- /* If we fail to get the number of displays, or it returns 0, then ++ /* If we fail to get the number of displays, then + * assume old firmware that doesn't have the mailbox call, so just + * set one display + */ +- if (ret || num_displays == 0) { ++ if (ret) { + num_displays = 1; +- DRM_WARN("Unable to determine number of displays's. Assuming 1\n"); ++ DRM_WARN("Unable to determine number of displays - assuming 1\n"); + ret = 0; + } + +@@ -1344,17 +1344,21 @@ static int vc4_fkms_bind(struct device * + display_num); + } + +- /* Map the SMI interrupt reg */ +- crtc_list[0]->regs = vc4_ioremap_regs(pdev, 0); +- if (IS_ERR(crtc_list[0]->regs)) +- DRM_ERROR("Oh dear, failed to map registers\n"); +- +- writel(0, crtc_list[0]->regs + SMICS); +- ret = devm_request_irq(dev, platform_get_irq(pdev, 0), +- vc4_crtc_irq_handler, 0, "vc4 firmware kms", +- crtc_list); +- if (ret) +- DRM_ERROR("Oh dear, failed to register IRQ\n"); ++ if (num_displays > 0) { ++ /* Map the SMI interrupt reg */ ++ crtc_list[0]->regs = vc4_ioremap_regs(pdev, 0); ++ if (IS_ERR(crtc_list[0]->regs)) ++ DRM_ERROR("Oh dear, failed to map registers\n"); ++ ++ writel(0, crtc_list[0]->regs + SMICS); ++ ret = devm_request_irq(dev, platform_get_irq(pdev, 0), ++ vc4_crtc_irq_handler, 0, ++ "vc4 firmware kms", crtc_list); ++ if (ret) ++ DRM_ERROR("Oh dear, failed to register IRQ\n"); ++ } else { ++ DRM_WARN("No displays found. Consider forcing hotplug if HDMI is attached\n"); ++ } + + platform_set_drvdata(pdev, crtc_list); + diff --git a/target/linux/brcm2708/patches-4.19/950-0620-drm-vc4-Log-flags-in-fkms-mode-set.patch b/target/linux/brcm2708/patches-4.19/950-0620-drm-vc4-Log-flags-in-fkms-mode-set.patch deleted file mode 100644 index 2f342df007..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0620-drm-vc4-Log-flags-in-fkms-mode-set.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 5ab2c06953f0ef6da029ced94ca7468057e7ecb3 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 7 May 2019 12:13:34 +0100 -Subject: [PATCH 620/703] drm: vc4: Log flags in fkms mode set - -The flags contain info such as limited/full range RGB, aspect -ratio, and a fwe other useful things. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -685,12 +685,13 @@ static void vc4_crtc_mode_set_nofb(struc - return; - } - -- DRM_DEBUG_KMS("Setting mode for display num %u mode name %s, clk %d, h(disp %d, start %d, end %d, total %d, skew %d) v(disp %d, start %d, end %d, total %d, scan %d), vrefresh %d, par %u\n", -+ DRM_DEBUG_KMS("Setting mode for display num %u mode name %s, clk %d, h(disp %d, start %d, end %d, total %d, skew %d) v(disp %d, start %d, end %d, total %d, scan %d), vrefresh %d, par %u, flags 0x%04x\n", - vc4_crtc->display_number, mode->name, mode->clock, - mode->hdisplay, mode->hsync_start, mode->hsync_end, - mode->htotal, mode->hskew, mode->vdisplay, - mode->vsync_start, mode->vsync_end, mode->vtotal, -- mode->vscan, mode->vrefresh, mode->picture_aspect_ratio); -+ mode->vscan, mode->vrefresh, mode->picture_aspect_ratio, -+ mode->flags); - mb.timings.display = vc4_crtc->display_number; - - mb.timings.video_id_code = frame.avi.video_code; diff --git a/target/linux/brcm2708/patches-4.19/950-0620-drm-vc4-Support-the-VEC-in-FKMS.patch b/target/linux/brcm2708/patches-4.19/950-0620-drm-vc4-Support-the-VEC-in-FKMS.patch new file mode 100644 index 0000000000..77a0938c58 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0620-drm-vc4-Support-the-VEC-in-FKMS.patch @@ -0,0 +1,62 @@ +From e2e439eb235a75c4719d52b5c7c60ed782727010 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 24 May 2019 17:59:01 +0100 +Subject: [PATCH 620/725] drm/vc4: Support the VEC in FKMS + +Extends the DPI/DSI support to also report the VEC output +which supports interlacing too. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -125,6 +125,7 @@ struct set_timings { + #define TIMINGS_FLAGS_H_SYNC_NEG 0 + #define TIMINGS_FLAGS_V_SYNC_POS BIT(1) + #define TIMINGS_FLAGS_V_SYNC_NEG 0 ++#define TIMINGS_FLAGS_INTERLACE BIT(2) + + #define TIMINGS_FLAGS_ASPECT_MASK GENMASK(7, 4) + #define TIMINGS_FLAGS_ASPECT_NONE (0 << 4) +@@ -1047,6 +1048,12 @@ static int vc4_fkms_lcd_connector_get_mo + fw_mode.flags |= DRM_MODE_FLAG_PVSYNC; + else + fw_mode.flags |= DRM_MODE_FLAG_NVSYNC; ++ if (mb.timings.flags & TIMINGS_FLAGS_V_SYNC_POS) ++ fw_mode.flags |= DRM_MODE_FLAG_PVSYNC; ++ else ++ fw_mode.flags |= DRM_MODE_FLAG_NVSYNC; ++ if (mb.timings.flags & TIMINGS_FLAGS_INTERLACE) ++ fw_mode.flags |= DRM_MODE_FLAG_INTERLACE; + + fw_mode.base.type = DRM_MODE_OBJECT_MODE; + +@@ -1133,17 +1140,24 @@ vc4_fkms_connector_init(struct drm_devic + DRM_MODE_CONNECTOR_DSI); + drm_connector_helper_add(connector, + &vc4_fkms_lcd_conn_helper_funcs); ++ connector->interlace_allowed = 0; ++ } else if (fkms_connector->display_type == DRM_MODE_ENCODER_TVDAC) { ++ drm_connector_init(dev, connector, &vc4_fkms_connector_funcs, ++ DRM_MODE_CONNECTOR_Composite); ++ drm_connector_helper_add(connector, ++ &vc4_fkms_lcd_conn_helper_funcs); ++ connector->interlace_allowed = 1; + } else { + drm_connector_init(dev, connector, &vc4_fkms_connector_funcs, + DRM_MODE_CONNECTOR_HDMIA); + drm_connector_helper_add(connector, + &vc4_fkms_connector_helper_funcs); ++ connector->interlace_allowed = 0; + } + + connector->polled = (DRM_CONNECTOR_POLL_CONNECT | + DRM_CONNECTOR_POLL_DISCONNECT); + +- connector->interlace_allowed = 0; + connector->doublescan_allowed = 0; + + drm_connector_attach_encoder(connector, encoder); diff --git a/target/linux/brcm2708/patches-4.19/950-0621-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch b/target/linux/brcm2708/patches-4.19/950-0621-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch new file mode 100644 index 0000000000..047f15288a --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0621-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch @@ -0,0 +1,39 @@ +From 6019920db110cd6c181d7843794a71b8736c2697 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 7 May 2019 15:00:02 +0100 +Subject: [PATCH 621/725] drm: vc4: Fixup typo when setting HDMI aspect ratio + +Assignment was to the wrong structure. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -717,19 +717,19 @@ static void vc4_crtc_mode_set_nofb(struc + switch (frame.avi.picture_aspect) { + default: + case HDMI_PICTURE_ASPECT_NONE: +- mode->flags |= TIMINGS_FLAGS_ASPECT_NONE; ++ mb.timings.flags |= TIMINGS_FLAGS_ASPECT_NONE; + break; + case HDMI_PICTURE_ASPECT_4_3: +- mode->flags |= TIMINGS_FLAGS_ASPECT_4_3; ++ mb.timings.flags |= TIMINGS_FLAGS_ASPECT_4_3; + break; + case HDMI_PICTURE_ASPECT_16_9: +- mode->flags |= TIMINGS_FLAGS_ASPECT_16_9; ++ mb.timings.flags |= TIMINGS_FLAGS_ASPECT_16_9; + break; + case HDMI_PICTURE_ASPECT_64_27: +- mode->flags |= TIMINGS_FLAGS_ASPECT_64_27; ++ mb.timings.flags |= TIMINGS_FLAGS_ASPECT_64_27; + break; + case HDMI_PICTURE_ASPECT_256_135: +- mode->flags |= TIMINGS_FLAGS_ASPECT_256_135; ++ mb.timings.flags |= TIMINGS_FLAGS_ASPECT_256_135; + break; + } + diff --git a/target/linux/brcm2708/patches-4.19/950-0621-drm-vc4-firmware-kms-Fix-DSI-display-support.patch b/target/linux/brcm2708/patches-4.19/950-0621-drm-vc4-firmware-kms-Fix-DSI-display-support.patch deleted file mode 100644 index c878270a72..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0621-drm-vc4-firmware-kms-Fix-DSI-display-support.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 5812f56a56140b70c110c22824d196c6abb866be Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 16 May 2019 17:49:42 +0100 -Subject: [PATCH 621/703] drm: vc4-firmware-kms: Fix DSI display support - -The mode was incorrectly listed as interlaced, which was then -rejected. -Correct this and FKMS works with the DSI display. - -Signed-off-by: Dave Stevenson ---- - 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 -@@ -1003,7 +1003,7 @@ static const struct drm_display_mode lcd - 25979400 / 1000, - 800, 800 + 1, 800 + 1 + 2, 800 + 1 + 2 + 46, 0, - 480, 480 + 7, 480 + 7 + 2, 480 + 7 + 2 + 21, 0, -- DRM_MODE_FLAG_INTERLACE) -+ 0) - }; - - static int vc4_fkms_lcd_connector_get_modes(struct drm_connector *connector) diff --git a/target/linux/brcm2708/patches-4.19/950-0622-drm-vc4-Correct-SAND-support-for-FKMS.patch b/target/linux/brcm2708/patches-4.19/950-0622-drm-vc4-Correct-SAND-support-for-FKMS.patch new file mode 100644 index 0000000000..c6ebaeef4d --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0622-drm-vc4-Correct-SAND-support-for-FKMS.patch @@ -0,0 +1,40 @@ +From a8ff82f4ae5871be6632d231692d5149976c0eeb Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 29 May 2019 15:44:11 +0100 +Subject: [PATCH 622/725] drm/vc4: Correct SAND support for FKMS. + +It was accepting NV21 which doesn't map through, but +also wasn't advertising the modifier so nothing would know +to request it. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -545,7 +545,6 @@ static bool vc4_fkms_format_mod_supporte + return false; + } + case DRM_FORMAT_NV12: +- case DRM_FORMAT_NV21: + switch (fourcc_mod_broadcom_mod(modifier)) { + case DRM_FORMAT_MOD_LINEAR: + case DRM_FORMAT_MOD_BROADCOM_SAND128: +@@ -553,6 +552,7 @@ static bool vc4_fkms_format_mod_supporte + default: + return false; + } ++ case DRM_FORMAT_NV21: + case DRM_FORMAT_RGB888: + case DRM_FORMAT_BGR888: + case DRM_FORMAT_YUV422: +@@ -599,6 +599,7 @@ static struct drm_plane *vc4_fkms_plane_ + * would prefer to scan out linear (less bus traffic). + */ + DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED, ++ DRM_FORMAT_MOD_BROADCOM_SAND128, + DRM_FORMAT_MOD_INVALID, + }; + int i; diff --git a/target/linux/brcm2708/patches-4.19/950-0622-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch b/target/linux/brcm2708/patches-4.19/950-0622-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch deleted file mode 100644 index 5c4eb0d32f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0622-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch +++ /dev/null @@ -1,120 +0,0 @@ -From d5db7a4a6af4b3281ac2ef1023de68e4f6250516 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 21 May 2019 11:50:00 +0100 -Subject: [PATCH 622/703] drm: vc4: Probe DPI/DSI timings from the firmware - -For DPI and DSI displays query the firmware as to the configuration -and add it as the only mode for DRM. - -In theory we can add plumbing for setting the DPI/DSI mode from -KMS, but this is not being added at present as the support frameworks -aren't present in the firmware. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 60 ++++++++++++++++++---- - include/soc/bcm2835/raspberrypi-firmware.h | 1 + - 2 files changed, 51 insertions(+), 10 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -280,7 +280,7 @@ static u32 vc4_get_display_type(u32 disp - /* The firmware display (DispmanX) IDs map to specific types in - * a fixed manner. - */ -- DRM_MODE_ENCODER_DSI, /* MAIN_LCD */ -+ DRM_MODE_ENCODER_DSI, /* MAIN_LCD - DSI or DPI */ - DRM_MODE_ENCODER_DSI, /* AUX_LCD */ - DRM_MODE_ENCODER_TMDS, /* HDMI0 */ - DRM_MODE_ENCODER_TVDAC, /* VEC */ -@@ -362,7 +362,6 @@ static void vc4_plane_atomic_update(stru - vc4_get_vc_image_fmt(drm_fmt->format); - struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane); - struct mailbox_set_plane *mb = &vc4_plane->mb; -- struct vc4_crtc *vc4_crtc = to_vc4_crtc(state->crtc); - int num_planes = fb->format->num_planes; - struct drm_display_mode *mode = &state->crtc->mode; - unsigned int rotation = SUPPORTED_ROTATIONS; -@@ -997,7 +996,9 @@ static int vc4_fkms_connector_get_modes( - return ret; - } - --/* FIXME: Read LCD mode from the firmware. This is the DSI panel resolution. */ -+/* This is the DSI panel resolution. Use this as a default should the firmware -+ * not respond to our request for the timings. -+ */ - static const struct drm_display_mode lcd_mode = { - DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, - 25979400 / 1000, -@@ -1008,15 +1009,54 @@ static const struct drm_display_mode lcd - - static int vc4_fkms_lcd_connector_get_modes(struct drm_connector *connector) - { -- //struct vc4_fkms_connector *fkms_connector = -- // to_vc4_fkms_connector(connector); -- //struct drm_encoder *encoder = fkms_connector->encoder; -- //struct vc4_fkms_encoder *vc4_encoder = to_vc4_fkms_encoder(encoder); -+ struct vc4_fkms_connector *fkms_connector = -+ to_vc4_fkms_connector(connector); -+ struct vc4_dev *vc4 = fkms_connector->vc4_dev; - struct drm_display_mode *mode; -- //int ret = 0; -+ struct mailbox_set_mode mb = { -+ .tag1 = { RPI_FIRMWARE_GET_DISPLAY_TIMING, -+ sizeof(struct set_timings), 0}, -+ .timings = { .display = fkms_connector->display_number }, -+ }; -+ struct drm_display_mode fw_mode; -+ int ret = 0; -+ -+ ret = rpi_firmware_property_list(vc4->firmware, &mb, sizeof(mb)); -+ if (!ret) { -+ /* Equivalent to DRM_MODE macro. */ -+ memset(&fw_mode, 0, sizeof(fw_mode)); -+ strncpy(fw_mode.name, "LCD_MODE", sizeof(fw_mode.name)); -+ fw_mode.status = 0; -+ fw_mode.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; -+ fw_mode.clock = mb.timings.clock; -+ fw_mode.hdisplay = mb.timings.hdisplay; -+ fw_mode.hsync_start = mb.timings.hsync_start; -+ fw_mode.hsync_end = mb.timings.hsync_end; -+ fw_mode.htotal = mb.timings.htotal; -+ fw_mode.hskew = 0; -+ fw_mode.vdisplay = mb.timings.vdisplay; -+ fw_mode.vsync_start = mb.timings.vsync_start; -+ fw_mode.vsync_end = mb.timings.vsync_end; -+ fw_mode.vtotal = mb.timings.vtotal; -+ fw_mode.vscan = mb.timings.vscan; -+ if (mb.timings.flags & TIMINGS_FLAGS_H_SYNC_POS) -+ fw_mode.flags |= DRM_MODE_FLAG_PHSYNC; -+ else -+ fw_mode.flags |= DRM_MODE_FLAG_NHSYNC; -+ if (mb.timings.flags & TIMINGS_FLAGS_V_SYNC_POS) -+ fw_mode.flags |= DRM_MODE_FLAG_PVSYNC; -+ else -+ fw_mode.flags |= DRM_MODE_FLAG_NVSYNC; -+ -+ fw_mode.base.type = DRM_MODE_OBJECT_MODE; -+ -+ mode = drm_mode_duplicate(connector->dev, -+ &fw_mode); -+ } else { -+ mode = drm_mode_duplicate(connector->dev, -+ &lcd_mode); -+ } - -- mode = drm_mode_duplicate(connector->dev, -- &lcd_mode); - if (!mode) { - DRM_ERROR("Failed to create a new display mode\n"); - return -ENOMEM; ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -151,6 +151,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, - - RPI_FIRMWARE_SET_PLANE = 0x00048015, -+ RPI_FIRMWARE_GET_DISPLAY_TIMING = 0x00040017, - RPI_FIRMWARE_SET_TIMING = 0x00048017, - - RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, diff --git a/target/linux/brcm2708/patches-4.19/950-0623-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch b/target/linux/brcm2708/patches-4.19/950-0623-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch new file mode 100644 index 0000000000..afc9898511 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0623-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch @@ -0,0 +1,134 @@ +From a1a297d0fd4b5ec427be523ed73afc5762f83595 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 30 May 2019 13:56:15 +0100 +Subject: [PATCH 623/725] drm/vc4: fkms to query the VPU for HDMI clock limits + +The VPU has configured clocks for 4k (or not) via config.txt, +and will limit the choice of video modes based on that. +Make fkms query it for these limits too to avoid selecting modes +that can not be handled by the current clock setup. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_drv.h | 1 + + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 48 ++++++++++++++++++++++ + include/soc/bcm2835/raspberrypi-firmware.h | 1 + + 3 files changed, 50 insertions(+) + +--- a/drivers/gpu/drm/vc4/vc4_drv.h ++++ b/drivers/gpu/drm/vc4/vc4_drv.h +@@ -77,6 +77,7 @@ struct vc4_dev { + struct vc4_dsi *dsi1; + struct vc4_vec *vec; + struct vc4_txp *txp; ++ struct vc4_fkms *fkms; + + struct vc4_hang_state *hang_state; + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -29,6 +29,14 @@ + #include "vc_image_types.h" + #include + ++struct get_display_cfg { ++ u32 max_pixel_clock[2]; //Max pixel clock for each display ++}; ++ ++struct vc4_fkms { ++ struct get_display_cfg cfg; ++}; ++ + #define PLANES_PER_CRTC 3 + + struct set_plane { +@@ -794,6 +802,11 @@ static void vc4_crtc_enable(struct drm_c + static enum drm_mode_status + vc4_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode) + { ++ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); ++ struct drm_device *dev = crtc->dev; ++ struct vc4_dev *vc4 = to_vc4_dev(dev); ++ struct vc4_fkms *fkms = vc4->fkms; ++ + /* Do not allow doublescan modes from user space */ + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) { + DRM_DEBUG_KMS("[CRTC:%d] Doublescan mode rejected.\n", +@@ -801,6 +814,22 @@ vc4_crtc_mode_valid(struct drm_crtc *crt + return MODE_NO_DBLESCAN; + } + ++ /* Limit the pixel clock based on the HDMI clock limits from the ++ * firmware ++ */ ++ switch (vc4_crtc->display_number) { ++ case 2: /* HDMI0 */ ++ if (fkms->cfg.max_pixel_clock[0] && ++ mode->clock > fkms->cfg.max_pixel_clock[0]) ++ return MODE_CLOCK_HIGH; ++ break; ++ case 7: /* HDMI1 */ ++ if (fkms->cfg.max_pixel_clock[1] && ++ mode->clock > fkms->cfg.max_pixel_clock[1]) ++ return MODE_CLOCK_HIGH; ++ break; ++ } ++ + /* Limit the pixel clock until we can get dynamic HDMI 2.0 scrambling + * working. + */ +@@ -1301,11 +1330,16 @@ static int vc4_fkms_bind(struct device * + struct device_node *firmware_node; + struct vc4_crtc **crtc_list; + u32 num_displays, display_num; ++ struct vc4_fkms *fkms; + int ret; + u32 display_id; + + vc4->firmware_kms = true; + ++ fkms = devm_kzalloc(dev, sizeof(*fkms), GFP_KERNEL); ++ if (!fkms) ++ return -ENOMEM; ++ + /* firmware kms doesn't have precise a scanoutpos implementation, so + * we can't do the precise vblank timestamp mode. + */ +@@ -1334,6 +1368,18 @@ static int vc4_fkms_bind(struct device * + ret = 0; + } + ++ ret = rpi_firmware_property(vc4->firmware, ++ RPI_FIRMWARE_GET_DISPLAY_CFG, ++ &fkms->cfg, sizeof(fkms->cfg)); ++ ++ if (ret) ++ return -EINVAL; ++ /* The firmware works in Hz. This will be compared against kHz, so div ++ * 1000 now rather than multiple times later. ++ */ ++ fkms->cfg.max_pixel_clock[0] /= 1000; ++ fkms->cfg.max_pixel_clock[1] /= 1000; ++ + /* Allocate a list, with space for a NULL on the end */ + crtc_list = devm_kzalloc(dev, sizeof(crtc_list) * (num_displays + 1), + GFP_KERNEL); +@@ -1375,6 +1421,8 @@ static int vc4_fkms_bind(struct device * + DRM_WARN("No displays found. Consider forcing hotplug if HDMI is attached\n"); + } + ++ vc4->fkms = fkms; ++ + platform_set_drvdata(pdev, crtc_list); + + return 0; +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -153,6 +153,7 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_SET_PLANE = 0x00048015, + RPI_FIRMWARE_GET_DISPLAY_TIMING = 0x00040017, + RPI_FIRMWARE_SET_TIMING = 0x00048017, ++ RPI_FIRMWARE_GET_DISPLAY_CFG = 0x00040018, + + RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, + RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, diff --git a/target/linux/brcm2708/patches-4.19/950-0623-drm-vc4-handle-the-case-where-there-are-no-available.patch b/target/linux/brcm2708/patches-4.19/950-0623-drm-vc4-handle-the-case-where-there-are-no-available.patch deleted file mode 100644 index d54a78f564..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0623-drm-vc4-handle-the-case-where-there-are-no-available.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 124d768ec6f79f42bdcde24801e2315c4d2d7632 Mon Sep 17 00:00:00 2001 -From: Jonathan Bell -Date: Tue, 28 May 2019 13:56:06 +0100 -Subject: [PATCH 623/703] drm: vc4: handle the case where there are no - available displays - -It's reasonable for the firmware to return zero as the number of -attached displays. Handle this case as otherwise drm thinks that -the DSI panel is attached, which is nonsense. - -Signed-off-by: Jonathan Bell ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 32 +++++++++++++++----------- - 1 file changed, 18 insertions(+), 14 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -1309,13 +1309,13 @@ static int vc4_fkms_bind(struct device * - RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS, - &num_displays, sizeof(u32)); - -- /* If we fail to get the number of displays, or it returns 0, then -+ /* If we fail to get the number of displays, then - * assume old firmware that doesn't have the mailbox call, so just - * set one display - */ -- if (ret || num_displays == 0) { -+ if (ret) { - num_displays = 1; -- DRM_WARN("Unable to determine number of displays's. Assuming 1\n"); -+ DRM_WARN("Unable to determine number of displays - assuming 1\n"); - ret = 0; - } - -@@ -1344,17 +1344,21 @@ static int vc4_fkms_bind(struct device * - display_num); - } - -- /* Map the SMI interrupt reg */ -- crtc_list[0]->regs = vc4_ioremap_regs(pdev, 0); -- if (IS_ERR(crtc_list[0]->regs)) -- DRM_ERROR("Oh dear, failed to map registers\n"); -- -- writel(0, crtc_list[0]->regs + SMICS); -- ret = devm_request_irq(dev, platform_get_irq(pdev, 0), -- vc4_crtc_irq_handler, 0, "vc4 firmware kms", -- crtc_list); -- if (ret) -- DRM_ERROR("Oh dear, failed to register IRQ\n"); -+ if (num_displays > 0) { -+ /* Map the SMI interrupt reg */ -+ crtc_list[0]->regs = vc4_ioremap_regs(pdev, 0); -+ if (IS_ERR(crtc_list[0]->regs)) -+ DRM_ERROR("Oh dear, failed to map registers\n"); -+ -+ writel(0, crtc_list[0]->regs + SMICS); -+ ret = devm_request_irq(dev, platform_get_irq(pdev, 0), -+ vc4_crtc_irq_handler, 0, -+ "vc4 firmware kms", crtc_list); -+ if (ret) -+ DRM_ERROR("Oh dear, failed to register IRQ\n"); -+ } else { -+ DRM_WARN("No displays found. Consider forcing hotplug if HDMI is attached\n"); -+ } - - platform_set_drvdata(pdev, crtc_list); - diff --git a/target/linux/brcm2708/patches-4.19/950-0624-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch b/target/linux/brcm2708/patches-4.19/950-0624-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch new file mode 100644 index 0000000000..fe66e944f9 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0624-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch @@ -0,0 +1,38 @@ +From aad4f4253c65b20796a1b472d1599149062f169c Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 30 May 2019 15:55:15 +0100 +Subject: [PATCH 624/725] drm/vc4: Max resolution of 7680 is conditional on + being Pi4 + +The max resolution had been increased from 2048 to 7680 for all +platforms. This code is common with Pi0-3 which have a max render +target for GL of 2048, therefore the increased resolution has to +be conditional on the platform. +Switch based on whether the bcm2835-v3d node is found, as that is +not present on Pi4. (There is a potential configuration on Pi0-3 +with no v3d, but this is very unlikely). + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_kms.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_kms.c +@@ -429,8 +429,14 @@ int vc4_kms_load(struct drm_device *dev) + return ret; + } + +- dev->mode_config.max_width = 7680; +- dev->mode_config.max_height = 7680; ++ if (!drm_core_check_feature(dev, DRIVER_RENDER)) { ++ /* No V3D as part of vc4. Assume this is Pi4. */ ++ dev->mode_config.max_width = 7680; ++ dev->mode_config.max_height = 7680; ++ } else { ++ dev->mode_config.max_width = 2048; ++ dev->mode_config.max_height = 2048; ++ } + dev->mode_config.funcs = &vc4_mode_funcs; + dev->mode_config.preferred_depth = 24; + dev->mode_config.async_page_flip = true; diff --git a/target/linux/brcm2708/patches-4.19/950-0624-drm-vc4-Support-the-VEC-in-FKMS.patch b/target/linux/brcm2708/patches-4.19/950-0624-drm-vc4-Support-the-VEC-in-FKMS.patch deleted file mode 100644 index 8ca3e91d1b..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0624-drm-vc4-Support-the-VEC-in-FKMS.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 1627c1be944a27b3b2f06d8d2b9dacf917c0ff67 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 24 May 2019 17:59:01 +0100 -Subject: [PATCH 624/703] drm/vc4: Support the VEC in FKMS - -Extends the DPI/DSI support to also report the VEC output -which supports interlacing too. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 16 +++++++++++++++- - 1 file changed, 15 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -125,6 +125,7 @@ struct set_timings { - #define TIMINGS_FLAGS_H_SYNC_NEG 0 - #define TIMINGS_FLAGS_V_SYNC_POS BIT(1) - #define TIMINGS_FLAGS_V_SYNC_NEG 0 -+#define TIMINGS_FLAGS_INTERLACE BIT(2) - - #define TIMINGS_FLAGS_ASPECT_MASK GENMASK(7, 4) - #define TIMINGS_FLAGS_ASPECT_NONE (0 << 4) -@@ -1047,6 +1048,12 @@ static int vc4_fkms_lcd_connector_get_mo - fw_mode.flags |= DRM_MODE_FLAG_PVSYNC; - else - fw_mode.flags |= DRM_MODE_FLAG_NVSYNC; -+ if (mb.timings.flags & TIMINGS_FLAGS_V_SYNC_POS) -+ fw_mode.flags |= DRM_MODE_FLAG_PVSYNC; -+ else -+ fw_mode.flags |= DRM_MODE_FLAG_NVSYNC; -+ if (mb.timings.flags & TIMINGS_FLAGS_INTERLACE) -+ fw_mode.flags |= DRM_MODE_FLAG_INTERLACE; - - fw_mode.base.type = DRM_MODE_OBJECT_MODE; - -@@ -1133,17 +1140,24 @@ vc4_fkms_connector_init(struct drm_devic - DRM_MODE_CONNECTOR_DSI); - drm_connector_helper_add(connector, - &vc4_fkms_lcd_conn_helper_funcs); -+ connector->interlace_allowed = 0; -+ } else if (fkms_connector->display_type == DRM_MODE_ENCODER_TVDAC) { -+ drm_connector_init(dev, connector, &vc4_fkms_connector_funcs, -+ DRM_MODE_CONNECTOR_Composite); -+ drm_connector_helper_add(connector, -+ &vc4_fkms_lcd_conn_helper_funcs); -+ connector->interlace_allowed = 1; - } else { - drm_connector_init(dev, connector, &vc4_fkms_connector_funcs, - DRM_MODE_CONNECTOR_HDMIA); - drm_connector_helper_add(connector, - &vc4_fkms_connector_helper_funcs); -+ connector->interlace_allowed = 0; - } - - connector->polled = (DRM_CONNECTOR_POLL_CONNECT | - DRM_CONNECTOR_POLL_DISCONNECT); - -- connector->interlace_allowed = 0; - connector->doublescan_allowed = 0; - - drm_connector_attach_encoder(connector, encoder); diff --git a/target/linux/brcm2708/patches-4.19/950-0625-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch b/target/linux/brcm2708/patches-4.19/950-0625-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch deleted file mode 100644 index 35fab4ce7e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0625-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 8fa80c9aeab3fac843be81d1dda0e87042367d34 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 7 May 2019 15:00:02 +0100 -Subject: [PATCH 625/703] drm: vc4: Fixup typo when setting HDMI aspect ratio - -Assignment was to the wrong structure. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -717,19 +717,19 @@ static void vc4_crtc_mode_set_nofb(struc - switch (frame.avi.picture_aspect) { - default: - case HDMI_PICTURE_ASPECT_NONE: -- mode->flags |= TIMINGS_FLAGS_ASPECT_NONE; -+ mb.timings.flags |= TIMINGS_FLAGS_ASPECT_NONE; - break; - case HDMI_PICTURE_ASPECT_4_3: -- mode->flags |= TIMINGS_FLAGS_ASPECT_4_3; -+ mb.timings.flags |= TIMINGS_FLAGS_ASPECT_4_3; - break; - case HDMI_PICTURE_ASPECT_16_9: -- mode->flags |= TIMINGS_FLAGS_ASPECT_16_9; -+ mb.timings.flags |= TIMINGS_FLAGS_ASPECT_16_9; - break; - case HDMI_PICTURE_ASPECT_64_27: -- mode->flags |= TIMINGS_FLAGS_ASPECT_64_27; -+ mb.timings.flags |= TIMINGS_FLAGS_ASPECT_64_27; - break; - case HDMI_PICTURE_ASPECT_256_135: -- mode->flags |= TIMINGS_FLAGS_ASPECT_256_135; -+ mb.timings.flags |= TIMINGS_FLAGS_ASPECT_256_135; - break; - } - diff --git a/target/linux/brcm2708/patches-4.19/950-0625-staging-vc-sm-cma-Remove-obsolete-comment-and-make-f.patch b/target/linux/brcm2708/patches-4.19/950-0625-staging-vc-sm-cma-Remove-obsolete-comment-and-make-f.patch new file mode 100644 index 0000000000..c5d461931a --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0625-staging-vc-sm-cma-Remove-obsolete-comment-and-make-f.patch @@ -0,0 +1,28 @@ +From aca9059632595f34dcd03b17f2396bbd47b1406b Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 10 Dec 2018 17:35:58 +0000 +Subject: [PATCH 625/725] staging: vc-sm-cma: Remove obsolete comment and make + function static + +Removes obsolete comment about wanting to pass a function +pointer into mmal-vchiq as we now do. +As the function is passed as a function pointer, the function itself +can be static. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -594,8 +594,7 @@ error: + return ret; + } + +-/* FIXME: Pass a function pointer to this into vc_vchi_sm.c */ +-void ++static void + vc_sm_vpu_event(struct sm_instance *instance, struct vc_sm_result_t *reply, + int reply_len) + { diff --git a/target/linux/brcm2708/patches-4.19/950-0626-drm-vc4-Correct-SAND-support-for-FKMS.patch b/target/linux/brcm2708/patches-4.19/950-0626-drm-vc4-Correct-SAND-support-for-FKMS.patch deleted file mode 100644 index 9e6aa3c180..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0626-drm-vc4-Correct-SAND-support-for-FKMS.patch +++ /dev/null @@ -1,40 +0,0 @@ -From b974397afb8ba0a0e11146886686163dfd4a3664 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 29 May 2019 15:44:11 +0100 -Subject: [PATCH 626/703] drm/vc4: Correct SAND support for FKMS. - -It was accepting NV21 which doesn't map through, but -also wasn't advertising the modifier so nothing would know -to request it. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -545,7 +545,6 @@ static bool vc4_fkms_format_mod_supporte - return false; - } - case DRM_FORMAT_NV12: -- case DRM_FORMAT_NV21: - switch (fourcc_mod_broadcom_mod(modifier)) { - case DRM_FORMAT_MOD_LINEAR: - case DRM_FORMAT_MOD_BROADCOM_SAND128: -@@ -553,6 +552,7 @@ static bool vc4_fkms_format_mod_supporte - default: - return false; - } -+ case DRM_FORMAT_NV21: - case DRM_FORMAT_RGB888: - case DRM_FORMAT_BGR888: - case DRM_FORMAT_YUV422: -@@ -599,6 +599,7 @@ static struct drm_plane *vc4_fkms_plane_ - * would prefer to scan out linear (less bus traffic). - */ - DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED, -+ DRM_FORMAT_MOD_BROADCOM_SAND128, - DRM_FORMAT_MOD_INVALID, - }; - int i; diff --git a/target/linux/brcm2708/patches-4.19/950-0626-staging-vc-sm-cma-Add-in-allocation-for-VPU-requests.patch b/target/linux/brcm2708/patches-4.19/950-0626-staging-vc-sm-cma-Add-in-allocation-for-VPU-requests.patch new file mode 100644 index 0000000000..986e702a0e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0626-staging-vc-sm-cma-Add-in-allocation-for-VPU-requests.patch @@ -0,0 +1,1206 @@ +From ff6f3a7725d91cc9a793923e569b6ea08675d037 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 21 Dec 2018 16:50:53 +0000 +Subject: [PATCH 626/725] staging: vc-sm-cma: Add in allocation for VPU + requests. + +Module has to change from tristate to bool as all CMA functions +are boolean. + +Signed-off-by: Dave Stevenson +--- + .../staging/vc04_services/vc-sm-cma/Kconfig | 4 +- + .../staging/vc04_services/vc-sm-cma/Makefile | 2 +- + .../staging/vc04_services/vc-sm-cma/vc_sm.c | 642 +++++++++++++++--- + .../staging/vc04_services/vc-sm-cma/vc_sm.h | 30 +- + .../vc04_services/vc-sm-cma/vc_sm_cma.c | 99 +++ + .../vc04_services/vc-sm-cma/vc_sm_cma.h | 39 ++ + .../vc04_services/vc-sm-cma/vc_sm_cma_vchi.c | 10 + + .../vc04_services/vc-sm-cma/vc_sm_cma_vchi.h | 4 + + .../vc04_services/vc-sm-cma/vc_sm_defs.h | 2 + + 9 files changed, 723 insertions(+), 109 deletions(-) + create mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.c + create mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.h + +--- a/drivers/staging/vc04_services/vc-sm-cma/Kconfig ++++ b/drivers/staging/vc04_services/vc-sm-cma/Kconfig +@@ -1,6 +1,6 @@ + config BCM_VC_SM_CMA +- tristate "VideoCore Shared Memory (CMA) driver" +- depends on BCM2835_VCHIQ ++ bool "VideoCore Shared Memory (CMA) driver" ++ depends on BCM2835_VCHIQ && DMA_CMA + select RBTREE + select DMA_SHARED_BUFFER + help +--- a/drivers/staging/vc04_services/vc-sm-cma/Makefile ++++ b/drivers/staging/vc04_services/vc-sm-cma/Makefile +@@ -3,6 +3,6 @@ ccflags-y += -Idrivers/staging/vc04_serv + ccflags-y += -D__VCCOREVER__=0 + + vc-sm-cma-$(CONFIG_BCM_VC_SM_CMA) := \ +- vc_sm.o vc_sm_cma_vchi.o ++ vc_sm.o vc_sm_cma_vchi.o vc_sm_cma.o + + obj-$(CONFIG_BCM_VC_SM_CMA) += vc-sm-cma.o +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -9,10 +9,21 @@ + * and taking some code for CMA/dmabuf handling from the Android Ion + * driver (Google/Linaro). + * +- * This is cut down version to only support import of dma_bufs from +- * other kernel drivers. A more complete implementation of the old +- * vmcs_sm functionality can follow later. + * ++ * This driver has 3 main uses: ++ * 1) Allocating buffers for the kernel or userspace that can be shared with the ++ * VPU. ++ * 2) Importing dmabufs from elsewhere for sharing with the VPU. ++ * 3) Allocating buffers for use by the VPU. ++ * ++ * In the first and second cases the native handle is a dmabuf. Releasing the ++ * resource inherently comes from releasing the dmabuf, and this will trigger ++ * unmapping on the VPU. The underlying allocation and our buffer structure are ++ * retained until the VPU has confirmed that it has finished with it. ++ * ++ * For the VPU allocations the VPU is responsible for triggering the release, ++ * and therefore the released message decrements the dma_buf refcount (with the ++ * VPU mapping having already been marked as released). + */ + + /* ---- Include Files ----------------------------------------------------- */ +@@ -39,6 +50,7 @@ + #include "vc_sm_cma_vchi.h" + + #include "vc_sm.h" ++#include "vc_sm_cma.h" + #include "vc_sm_knl.h" + + /* ---- Private Constants and Types --------------------------------------- */ +@@ -72,6 +84,7 @@ struct sm_state_t { + struct platform_device *pdev; + + struct sm_instance *sm_handle; /* Handle for videocore service. */ ++ struct cma *cma_heap; + + spinlock_t kernelid_map_lock; /* Spinlock protecting kernelid_map */ + struct idr kernelid_map; +@@ -80,6 +93,7 @@ struct sm_state_t { + struct list_head buffer_list; /* List of buffer. */ + + struct vc_sm_privdata_t *data_knl; /* Kernel internal data tracking. */ ++ struct vc_sm_privdata_t *vpu_allocs; /* All allocations from the VPU */ + struct dentry *dir_root; /* Debug fs entries root. */ + struct sm_pde_t dir_state; /* Debug fs entries state sub-tree. */ + +@@ -89,6 +103,12 @@ struct sm_state_t { + u32 int_trans_id; /* Interrupted transaction. */ + }; + ++struct vc_sm_dma_buf_attachment { ++ struct device *dev; ++ struct sg_table *table; ++ struct list_head list; ++}; ++ + /* ---- Private Variables ----------------------------------------------- */ + + static struct sm_state_t *sm_state; +@@ -172,12 +192,14 @@ static int vc_sm_cma_global_state_show(s + resource->size); + seq_printf(s, " DMABUF %p\n", + resource->dma_buf); +- seq_printf(s, " ATTACH %p\n", +- resource->attach); ++ if (resource->imported) { ++ seq_printf(s, " ATTACH %p\n", ++ resource->import.attach); ++ seq_printf(s, " SGT %p\n", ++ resource->import.sgt); ++ } + seq_printf(s, " SG_TABLE %p\n", + resource->sg_table); +- seq_printf(s, " SGT %p\n", +- resource->sgt); + seq_printf(s, " DMA_ADDR %pad\n", + &resource->dma_addr); + seq_printf(s, " VC_HANDLE %08x\n", +@@ -209,17 +231,33 @@ static void vc_sm_add_resource(struct vc + } + + /* +- * Release an allocation. +- * All refcounting is done via the dma buf object. ++ * Cleans up imported dmabuf. + */ +-static void vc_sm_release_resource(struct vc_sm_buffer *buffer, int force) ++static void vc_sm_clean_up_dmabuf(struct vc_sm_buffer *buffer) + { +- mutex_lock(&sm_state->map_lock); +- mutex_lock(&buffer->lock); ++ if (!buffer->imported) ++ return; + +- pr_debug("[%s]: buffer %p (name %s, size %zu)\n", +- __func__, buffer, buffer->name, buffer->size); ++ /* Handle cleaning up imported dmabufs */ ++ mutex_lock(&buffer->lock); ++ if (buffer->import.sgt) { ++ dma_buf_unmap_attachment(buffer->import.attach, ++ buffer->import.sgt, ++ DMA_BIDIRECTIONAL); ++ buffer->import.sgt = NULL; ++ } ++ if (buffer->import.attach) { ++ dma_buf_detach(buffer->dma_buf, buffer->import.attach); ++ buffer->import.attach = NULL; ++ } ++ mutex_unlock(&buffer->lock); ++} + ++/* ++ * Instructs VPU to decrement the refcount on a buffer. ++ */ ++static void vc_sm_vpu_free(struct vc_sm_buffer *buffer) ++{ + if (buffer->vc_handle && buffer->vpu_state == VPU_MAPPED) { + struct vc_sm_free_t free = { buffer->vc_handle, 0 }; + int status = vc_sm_cma_vchi_free(sm_state->sm_handle, &free, +@@ -230,17 +268,32 @@ static void vc_sm_release_resource(struc + } + + if (sm_state->require_released_callback) { +- /* Need to wait for the VPU to confirm the free */ ++ /* Need to wait for the VPU to confirm the free. */ + + /* Retain a reference on this until the VPU has + * released it + */ + buffer->vpu_state = VPU_UNMAPPING; +- goto defer; ++ } else { ++ buffer->vpu_state = VPU_NOT_MAPPED; ++ buffer->vc_handle = 0; + } +- buffer->vpu_state = VPU_NOT_MAPPED; +- buffer->vc_handle = 0; + } ++} ++ ++/* ++ * Release an allocation. ++ * All refcounting is done via the dma buf object. ++ * ++ * Must be called with the mutex held. The function will either release the ++ * mutex (if defering the release) or destroy it. The caller must therefore not ++ * reuse the buffer on return. ++ */ ++static void vc_sm_release_resource(struct vc_sm_buffer *buffer) ++{ ++ pr_debug("[%s]: buffer %p (name %s, size %zu)\n", ++ __func__, buffer, buffer->name, buffer->size); ++ + if (buffer->vc_handle) { + /* We've sent the unmap request but not had the response. */ + pr_err("[%s]: Waiting for VPU unmap response on %p\n", +@@ -248,45 +301,43 @@ static void vc_sm_release_resource(struc + goto defer; + } + if (buffer->in_use) { +- /* Don't release dmabuf here - we await the release */ ++ /* dmabuf still in use - we await the release */ + pr_err("[%s]: buffer %p is still in use\n", + __func__, buffer); + goto defer; + } + +- /* Handle cleaning up imported dmabufs */ +- if (buffer->sgt) { +- dma_buf_unmap_attachment(buffer->attach, buffer->sgt, +- DMA_BIDIRECTIONAL); +- buffer->sgt = NULL; +- } +- if (buffer->attach) { +- dma_buf_detach(buffer->dma_buf, buffer->attach); +- buffer->attach = NULL; +- } +- +- /* Release the dma_buf (whether ours or imported) */ +- if (buffer->import_dma_buf) { +- dma_buf_put(buffer->import_dma_buf); +- buffer->import_dma_buf = NULL; +- buffer->dma_buf = NULL; +- } else if (buffer->dma_buf) { +- dma_buf_put(buffer->dma_buf); +- buffer->dma_buf = NULL; ++ /* Release the allocation (whether imported dmabuf or CMA allocation) */ ++ if (buffer->imported) { ++ pr_debug("%s: Release imported dmabuf %p\n", __func__, ++ buffer->import.dma_buf); ++ if (buffer->import.dma_buf) ++ dma_buf_put(buffer->import.dma_buf); ++ else ++ pr_err("%s: Imported dmabuf already been put for buf %p\n", ++ __func__, buffer); ++ buffer->import.dma_buf = NULL; ++ } else { ++ if (buffer->sg_table) { ++ /* Our own allocation that we need to dma_unmap_sg */ ++ dma_unmap_sg(&sm_state->pdev->dev, ++ buffer->sg_table->sgl, ++ buffer->sg_table->nents, ++ DMA_BIDIRECTIONAL); ++ } ++ pr_debug("%s: Release our allocation\n", __func__); ++ vc_sm_cma_buffer_free(&buffer->alloc); ++ pr_debug("%s: Release our allocation - done\n", __func__); + } + +- if (buffer->sg_table && !buffer->import_dma_buf) { +- /* Our own allocation that we need to dma_unmap_sg */ +- dma_unmap_sg(&sm_state->pdev->dev, buffer->sg_table->sgl, +- buffer->sg_table->nents, DMA_BIDIRECTIONAL); +- } + +- /* Free the local resource. Start by removing it from the list */ +- buffer->private = NULL; ++ /* Free our buffer. Start by removing it from the list */ ++ mutex_lock(&sm_state->map_lock); + list_del(&buffer->global_buffer_list); ++ mutex_unlock(&sm_state->map_lock); + ++ pr_debug("%s: Release our allocation - done\n", __func__); + mutex_unlock(&buffer->lock); +- mutex_unlock(&sm_state->map_lock); + + mutex_destroy(&buffer->lock); + +@@ -295,7 +346,7 @@ static void vc_sm_release_resource(struc + + defer: + mutex_unlock(&buffer->lock); +- mutex_unlock(&sm_state->map_lock); ++ return; + } + + /* Create support for private data tracking. */ +@@ -317,16 +368,267 @@ static struct vc_sm_privdata_t *vc_sm_cm + return file_data; + } + ++static struct sg_table *dup_sg_table(struct sg_table *table) ++{ ++ struct sg_table *new_table; ++ int ret, i; ++ struct scatterlist *sg, *new_sg; ++ ++ new_table = kzalloc(sizeof(*new_table), GFP_KERNEL); ++ if (!new_table) ++ return ERR_PTR(-ENOMEM); ++ ++ ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL); ++ if (ret) { ++ kfree(new_table); ++ return ERR_PTR(-ENOMEM); ++ } ++ ++ new_sg = new_table->sgl; ++ for_each_sg(table->sgl, sg, table->nents, i) { ++ memcpy(new_sg, sg, sizeof(*sg)); ++ sg->dma_address = 0; ++ new_sg = sg_next(new_sg); ++ } ++ ++ return new_table; ++} ++ ++static void free_duped_table(struct sg_table *table) ++{ ++ sg_free_table(table); ++ kfree(table); ++} ++ ++/* Dma buf operations for use with our own allocations */ ++ ++static int vc_sm_dma_buf_attach(struct dma_buf *dmabuf, ++ struct dma_buf_attachment *attachment) ++ ++{ ++ struct vc_sm_dma_buf_attachment *a; ++ struct sg_table *table; ++ struct vc_sm_buffer *buf = dmabuf->priv; ++ ++ a = kzalloc(sizeof(*a), GFP_KERNEL); ++ if (!a) ++ return -ENOMEM; ++ ++ table = dup_sg_table(buf->sg_table); ++ if (IS_ERR(table)) { ++ kfree(a); ++ return -ENOMEM; ++ } ++ ++ a->table = table; ++ INIT_LIST_HEAD(&a->list); ++ ++ attachment->priv = a; ++ ++ mutex_lock(&buf->lock); ++ list_add(&a->list, &buf->attachments); ++ mutex_unlock(&buf->lock); ++ pr_debug("%s dmabuf %p attachment %p\n", __func__, dmabuf, attachment); ++ ++ return 0; ++} ++ ++static void vc_sm_dma_buf_detatch(struct dma_buf *dmabuf, ++ struct dma_buf_attachment *attachment) ++{ ++ struct vc_sm_dma_buf_attachment *a = attachment->priv; ++ struct vc_sm_buffer *buf = dmabuf->priv; ++ ++ pr_debug("%s dmabuf %p attachment %p\n", __func__, dmabuf, attachment); ++ free_duped_table(a->table); ++ mutex_lock(&buf->lock); ++ list_del(&a->list); ++ mutex_unlock(&buf->lock); ++ ++ kfree(a); ++} ++ ++static struct sg_table *vc_sm_map_dma_buf(struct dma_buf_attachment *attachment, ++ enum dma_data_direction direction) ++{ ++ struct vc_sm_dma_buf_attachment *a = attachment->priv; ++ struct sg_table *table; ++ ++ table = a->table; ++ ++ if (!dma_map_sg(attachment->dev, table->sgl, table->nents, ++ direction)) ++ return ERR_PTR(-ENOMEM); ++ ++ pr_debug("%s attachment %p\n", __func__, attachment); ++ return table; ++} ++ ++static void vc_sm_unmap_dma_buf(struct dma_buf_attachment *attachment, ++ struct sg_table *table, ++ enum dma_data_direction direction) ++{ ++ pr_debug("%s attachment %p\n", __func__, attachment); ++ dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction); ++} ++ ++static int vc_sm_dmabuf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) ++{ ++ struct vc_sm_buffer *buf = dmabuf->priv; ++ struct sg_table *table = buf->sg_table; ++ unsigned long addr = vma->vm_start; ++ unsigned long offset = vma->vm_pgoff * PAGE_SIZE; ++ struct scatterlist *sg; ++ int i; ++ int ret = 0; ++ ++ pr_debug("%s dmabuf %p, buf %p, vm_start %08lX\n", __func__, dmabuf, ++ buf, addr); ++ ++ mutex_lock(&buf->lock); ++ ++ /* now map it to userspace */ ++ for_each_sg(table->sgl, sg, table->nents, i) { ++ struct page *page = sg_page(sg); ++ unsigned long remainder = vma->vm_end - addr; ++ unsigned long len = sg->length; ++ ++ if (offset >= sg->length) { ++ offset -= sg->length; ++ continue; ++ } else if (offset) { ++ page += offset / PAGE_SIZE; ++ len = sg->length - offset; ++ offset = 0; ++ } ++ len = min(len, remainder); ++ ret = remap_pfn_range(vma, addr, page_to_pfn(page), len, ++ vma->vm_page_prot); ++ if (ret) ++ break; ++ addr += len; ++ if (addr >= vma->vm_end) ++ break; ++ } ++ mutex_unlock(&buf->lock); ++ ++ if (ret) ++ pr_err("%s: failure mapping buffer to userspace\n", ++ __func__); ++ ++ return ret; ++} ++ ++static void vc_sm_dma_buf_release(struct dma_buf *dmabuf) ++{ ++ struct vc_sm_buffer *buffer; ++ ++ if (!dmabuf) ++ return; ++ ++ buffer = (struct vc_sm_buffer *)dmabuf->priv; ++ ++ mutex_lock(&buffer->lock); ++ ++ pr_debug("%s dmabuf %p, buffer %p\n", __func__, dmabuf, buffer); ++ ++ buffer->in_use = 0; ++ ++ /* Unmap on the VPU */ ++ vc_sm_vpu_free(buffer); ++ pr_debug("%s vpu_free done\n", __func__); ++ ++ /* Unmap our dma_buf object (the vc_sm_buffer remains until released ++ * on the VPU). ++ */ ++ vc_sm_clean_up_dmabuf(buffer); ++ pr_debug("%s clean_up dmabuf done\n", __func__); ++ ++ vc_sm_release_resource(buffer); ++ pr_debug("%s done\n", __func__); ++} ++ ++static int vc_sm_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, ++ enum dma_data_direction direction) ++{ ++ struct vc_sm_buffer *buf; ++ struct vc_sm_dma_buf_attachment *a; ++ ++ if (!dmabuf) ++ return -EFAULT; ++ ++ buf = dmabuf->priv; ++ if (!buf) ++ return -EFAULT; ++ ++ mutex_lock(&buf->lock); ++ ++ list_for_each_entry(a, &buf->attachments, list) { ++ dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents, ++ direction); ++ } ++ mutex_unlock(&buf->lock); ++ ++ return 0; ++} ++ ++static int vc_sm_dma_buf_end_cpu_access(struct dma_buf *dmabuf, ++ enum dma_data_direction direction) ++{ ++ struct vc_sm_buffer *buf; ++ struct vc_sm_dma_buf_attachment *a; ++ ++ if (!dmabuf) ++ return -EFAULT; ++ buf = dmabuf->priv; ++ if (!buf) ++ return -EFAULT; ++ ++ mutex_lock(&buf->lock); ++ ++ list_for_each_entry(a, &buf->attachments, list) { ++ dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents, ++ direction); ++ } ++ mutex_unlock(&buf->lock); ++ ++ return 0; ++} ++ ++static void *vc_sm_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset) ++{ ++ /* FIXME */ ++ return NULL; ++} ++ ++static void vc_sm_dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long offset, ++ void *ptr) ++{ ++ /* FIXME */ ++} ++ ++static const struct dma_buf_ops dma_buf_ops = { ++ .map_dma_buf = vc_sm_map_dma_buf, ++ .unmap_dma_buf = vc_sm_unmap_dma_buf, ++ .mmap = vc_sm_dmabuf_mmap, ++ .release = vc_sm_dma_buf_release, ++ .attach = vc_sm_dma_buf_attach, ++ .detach = vc_sm_dma_buf_detatch, ++ .begin_cpu_access = vc_sm_dma_buf_begin_cpu_access, ++ .end_cpu_access = vc_sm_dma_buf_end_cpu_access, ++ .map = vc_sm_dma_buf_kmap, ++ .unmap = vc_sm_dma_buf_kunmap, ++}; + /* Dma_buf operations for chaining through to an imported dma_buf */ + static + int vc_sm_import_dma_buf_attach(struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment) + { +- struct vc_sm_buffer *res = dmabuf->priv; ++ struct vc_sm_buffer *buf = dmabuf->priv; + +- if (!res->import_dma_buf) ++ if (!buf->imported) + return -EINVAL; +- return res->import_dma_buf->ops->attach(res->import_dma_buf, ++ return buf->import.dma_buf->ops->attach(buf->import.dma_buf, + attachment); + } + +@@ -334,22 +636,23 @@ static + void vc_sm_import_dma_buf_detatch(struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment) + { +- struct vc_sm_buffer *res = dmabuf->priv; ++ struct vc_sm_buffer *buf = dmabuf->priv; + +- if (!res->import_dma_buf) ++ if (!buf->imported) + return; +- res->import_dma_buf->ops->detach(res->import_dma_buf, attachment); ++ buf->import.dma_buf->ops->detach(buf->import.dma_buf, attachment); + } + + static + struct sg_table *vc_sm_import_map_dma_buf(struct dma_buf_attachment *attachment, + enum dma_data_direction direction) + { +- struct vc_sm_buffer *res = attachment->dmabuf->priv; ++ struct vc_sm_buffer *buf = attachment->dmabuf->priv; + +- if (!res->import_dma_buf) ++ if (!buf->imported) + return NULL; +- return res->import_dma_buf->ops->map_dma_buf(attachment, direction); ++ return buf->import.dma_buf->ops->map_dma_buf(attachment, ++ direction); + } + + static +@@ -357,87 +660,88 @@ void vc_sm_import_unmap_dma_buf(struct d + struct sg_table *table, + enum dma_data_direction direction) + { +- struct vc_sm_buffer *res = attachment->dmabuf->priv; ++ struct vc_sm_buffer *buf = attachment->dmabuf->priv; + +- if (!res->import_dma_buf) ++ if (!buf->imported) + return; +- res->import_dma_buf->ops->unmap_dma_buf(attachment, table, direction); ++ buf->import.dma_buf->ops->unmap_dma_buf(attachment, table, direction); + } + + static + int vc_sm_import_dmabuf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) + { +- struct vc_sm_buffer *res = dmabuf->priv; ++ struct vc_sm_buffer *buf = dmabuf->priv; + +- pr_debug("%s: mmap dma_buf %p, res %p, imported db %p\n", __func__, +- dmabuf, res, res->import_dma_buf); +- if (!res->import_dma_buf) { ++ pr_debug("%s: mmap dma_buf %p, buf %p, imported db %p\n", __func__, ++ dmabuf, buf, buf->import.dma_buf); ++ if (!buf->imported) { + pr_err("%s: mmap dma_buf %p- not an imported buffer\n", + __func__, dmabuf); + return -EINVAL; + } +- return res->import_dma_buf->ops->mmap(res->import_dma_buf, vma); ++ return buf->import.dma_buf->ops->mmap(buf->import.dma_buf, vma); + } + + static + void vc_sm_import_dma_buf_release(struct dma_buf *dmabuf) + { +- struct vc_sm_buffer *res = dmabuf->priv; ++ struct vc_sm_buffer *buf = dmabuf->priv; + + pr_debug("%s: Relasing dma_buf %p\n", __func__, dmabuf); +- if (!res->import_dma_buf) ++ mutex_lock(&buf->lock); ++ if (!buf->imported) + return; + +- res->in_use = 0; ++ buf->in_use = 0; + +- vc_sm_release_resource(res, 0); ++ vc_sm_vpu_free(buf); ++ ++ vc_sm_release_resource(buf); + } + + static + void *vc_sm_import_dma_buf_kmap(struct dma_buf *dmabuf, + unsigned long offset) + { +- struct vc_sm_buffer *res = dmabuf->priv; ++ struct vc_sm_buffer *buf = dmabuf->priv; + +- if (!res->import_dma_buf) ++ if (!buf->imported) + return NULL; +- return res->import_dma_buf->ops->map(res->import_dma_buf, +- offset); ++ return buf->import.dma_buf->ops->map(buf->import.dma_buf, offset); + } + + static + void vc_sm_import_dma_buf_kunmap(struct dma_buf *dmabuf, + unsigned long offset, void *ptr) + { +- struct vc_sm_buffer *res = dmabuf->priv; ++ struct vc_sm_buffer *buf = dmabuf->priv; + +- if (!res->import_dma_buf) ++ if (!buf->imported) + return; +- res->import_dma_buf->ops->unmap(res->import_dma_buf, +- offset, ptr); ++ buf->import.dma_buf->ops->unmap(buf->import.dma_buf, offset, ptr); + } + + static + int vc_sm_import_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, + enum dma_data_direction direction) + { +- struct vc_sm_buffer *res = dmabuf->priv; ++ struct vc_sm_buffer *buf = dmabuf->priv; + +- if (!res->import_dma_buf) ++ if (!buf->imported) + return -EINVAL; +- return res->import_dma_buf->ops->begin_cpu_access(res->import_dma_buf, +- direction); ++ return buf->import.dma_buf->ops->begin_cpu_access(buf->import.dma_buf, ++ direction); + } + + static + int vc_sm_import_dma_buf_end_cpu_access(struct dma_buf *dmabuf, + enum dma_data_direction direction) + { +- struct vc_sm_buffer *res = dmabuf->priv; ++ struct vc_sm_buffer *buf = dmabuf->priv; + +- if (!res->import_dma_buf) ++ if (!buf->imported) + return -EINVAL; +- return res->import_dma_buf->ops->end_cpu_access(res->import_dma_buf, ++ return buf->import.dma_buf->ops->end_cpu_access(buf->import.dma_buf, + direction); + } + +@@ -516,9 +820,8 @@ vc_sm_cma_import_dmabuf_internal(struct + memcpy(import.name, VC_SM_RESOURCE_NAME_DEFAULT, + sizeof(VC_SM_RESOURCE_NAME_DEFAULT)); + +- pr_debug("[%s]: attempt to import \"%s\" data - type %u, addr %pad, size %u\n", +- __func__, import.name, import.type, &dma_addr, +- import.size); ++ pr_debug("[%s]: attempt to import \"%s\" data - type %u, addr %pad, size %u.\n", ++ __func__, import.name, import.type, &dma_addr, import.size); + + /* Allocate the videocore buffer. */ + status = vc_sm_cma_vchi_import(sm_state->sm_handle, &import, &result, +@@ -548,12 +851,14 @@ vc_sm_cma_import_dmabuf_internal(struct + buffer->size = import.size; + buffer->vpu_state = VPU_MAPPED; + +- buffer->import_dma_buf = dma_buf; ++ buffer->imported = 1; ++ buffer->import.dma_buf = dma_buf; + +- buffer->attach = attach; +- buffer->sgt = sgt; ++ buffer->import.attach = attach; ++ buffer->import.sgt = sgt; + buffer->dma_addr = dma_addr; + buffer->in_use = 1; ++ buffer->kernel_id = import.kernel_id; + + /* + * We're done - we need to export a new dmabuf chaining through most +@@ -594,6 +899,91 @@ error: + return ret; + } + ++static int vc_sm_cma_vpu_alloc(u32 size, uint32_t align, const char *name, ++ u32 mem_handle, struct vc_sm_buffer **ret_buffer) ++{ ++ DEFINE_DMA_BUF_EXPORT_INFO(exp_info); ++ struct vc_sm_buffer *buffer = NULL; ++ int aligned_size; ++ int ret = 0; ++ ++ /* Align to the user requested align */ ++ aligned_size = ALIGN(size, align); ++ /* and then to a page boundary */ ++ aligned_size = PAGE_ALIGN(aligned_size); ++ ++ if (!aligned_size) ++ return -EINVAL; ++ ++ /* Allocate local buffer to track this allocation. */ ++ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); ++ if (!buffer) ++ return -ENOMEM; ++ ++ mutex_init(&buffer->lock); ++ ++ if (vc_sm_cma_buffer_allocate(sm_state->cma_heap, &buffer->alloc, ++ aligned_size)) { ++ pr_err("[%s]: cma alloc of %d bytes failed\n", ++ __func__, aligned_size); ++ ret = -ENOMEM; ++ goto error; ++ } ++ buffer->sg_table = buffer->alloc.sg_table; ++ ++ pr_debug("[%s]: cma alloc of %d bytes success\n", ++ __func__, aligned_size); ++ ++ if (dma_map_sg(&sm_state->pdev->dev, buffer->sg_table->sgl, ++ buffer->sg_table->nents, DMA_BIDIRECTIONAL) <= 0) { ++ pr_err("[%s]: dma_map_sg failed\n", __func__); ++ goto error; ++ } ++ ++ INIT_LIST_HEAD(&buffer->attachments); ++ ++ memcpy(buffer->name, name, ++ min(sizeof(buffer->name), strlen(name))); ++ ++ exp_info.ops = &dma_buf_ops; ++ exp_info.size = aligned_size; ++ exp_info.flags = O_RDWR; ++ exp_info.priv = buffer; ++ ++ buffer->dma_buf = dma_buf_export(&exp_info); ++ if (IS_ERR(buffer->dma_buf)) { ++ ret = PTR_ERR(buffer->dma_buf); ++ goto error; ++ } ++ buffer->dma_addr = (uint32_t)sg_dma_address(buffer->sg_table->sgl); ++ if ((buffer->dma_addr & 0xC0000000) != 0xC0000000) { ++ pr_err("%s: Expecting an uncached alias for dma_addr %pad\n", ++ __func__, &buffer->dma_addr); ++ buffer->dma_addr |= 0xC0000000; ++ } ++ buffer->private = sm_state->vpu_allocs; ++ ++ buffer->vc_handle = mem_handle; ++ buffer->vpu_state = VPU_MAPPED; ++ buffer->vpu_allocated = 1; ++ buffer->size = size; ++ /* ++ * Create an ID that will be passed along with our message so ++ * that when we service the release reply, we can look up which ++ * resource is being released. ++ */ ++ buffer->kernel_id = get_kernel_id(buffer); ++ ++ vc_sm_add_resource(sm_state->vpu_allocs, buffer); ++ ++ *ret_buffer = buffer; ++ return 0; ++error: ++ if (buffer) ++ vc_sm_release_resource(buffer); ++ return ret; ++} ++ + static void + vc_sm_vpu_event(struct sm_instance *instance, struct vc_sm_result_t *reply, + int reply_len) +@@ -612,21 +1002,61 @@ vc_sm_vpu_event(struct sm_instance *inst + struct vc_sm_released *release = (struct vc_sm_released *)reply; + struct vc_sm_buffer *buffer = + lookup_kernel_id(release->kernel_id); ++ if (!buffer) { ++ pr_err("%s: VC released a buffer that is already released, kernel_id %d\n", ++ __func__, release->kernel_id); ++ break; ++ } ++ mutex_lock(&buffer->lock); + +- /* +- * FIXME: Need to check buffer is still valid and allocated +- * before continuing +- */ + pr_debug("%s: Released addr %08x, size %u, id %08x, mem_handle %08x\n", + __func__, release->addr, release->size, + release->kernel_id, release->vc_handle); +- mutex_lock(&buffer->lock); ++ + buffer->vc_handle = 0; + buffer->vpu_state = VPU_NOT_MAPPED; +- mutex_unlock(&buffer->lock); + free_kernel_id(release->kernel_id); + +- vc_sm_release_resource(buffer, 0); ++ if (buffer->vpu_allocated) { ++ /* VPU allocation, so release the dmabuf which will ++ * trigger the clean up. ++ */ ++ mutex_unlock(&buffer->lock); ++ dma_buf_put(buffer->dma_buf); ++ } else { ++ vc_sm_release_resource(buffer); ++ } ++ } ++ break; ++ case VC_SM_MSG_TYPE_VC_MEM_REQUEST: ++ { ++ struct vc_sm_buffer *buffer = NULL; ++ struct vc_sm_vc_mem_request *req = ++ (struct vc_sm_vc_mem_request *)reply; ++ struct vc_sm_vc_mem_request_result reply; ++ int ret; ++ ++ pr_debug("%s: Request %u bytes of memory, align %d name %s, trans_id %08x\n", ++ __func__, req->size, req->align, req->name, ++ req->trans_id); ++ ret = vc_sm_cma_vpu_alloc(req->size, req->align, req->name, ++ req->vc_handle, &buffer); ++ ++ reply.trans_id = req->trans_id; ++ if (!ret) { ++ reply.addr = buffer->dma_addr; ++ reply.kernel_id = buffer->kernel_id; ++ pr_debug("%s: Allocated resource buffer %p, addr %pad\n", ++ __func__, buffer, &buffer->dma_addr); ++ } else { ++ pr_err("%s: Allocation failed size %u, name %s, vc_handle %u\n", ++ __func__, req->size, req->name, req->vc_handle); ++ reply.addr = 0; ++ reply.kernel_id = 0; ++ } ++ vc_sm_vchi_client_vc_mem_req_reply(sm_state->sm_handle, &reply, ++ &sm_state->int_trans_id); ++ break; + } + break; + default: +@@ -645,6 +1075,14 @@ static void vc_sm_connected_init(void) + + pr_info("[%s]: start\n", __func__); + ++ if (vc_sm_cma_add_heaps(&sm_state->cma_heap) || ++ !sm_state->cma_heap) { ++ pr_err("[%s]: failed to initialise CMA heaps\n", ++ __func__); ++ ret = -EIO; ++ goto err_free_mem; ++ } ++ + /* + * Initialize and create a VCHI connection for the shared memory service + * running on videocore. +@@ -696,7 +1134,7 @@ static void vc_sm_connected_init(void) + goto err_remove_shared_memory; + } + +- version.version = 1; ++ version.version = 2; + ret = vc_sm_cma_vchi_client_version(sm_state->sm_handle, &version, + &version_result, + &sm_state->int_trans_id); +@@ -768,7 +1206,7 @@ static int bcm2835_vc_sm_cma_remove(stru + int vc_sm_cma_int_handle(void *handle) + { + struct dma_buf *dma_buf = (struct dma_buf *)handle; +- struct vc_sm_buffer *res; ++ struct vc_sm_buffer *buf; + + /* Validate we can work with this device. */ + if (!sm_state || !handle) { +@@ -776,8 +1214,8 @@ int vc_sm_cma_int_handle(void *handle) + return 0; + } + +- res = (struct vc_sm_buffer *)dma_buf->priv; +- return res->vc_handle; ++ buf = (struct vc_sm_buffer *)dma_buf->priv; ++ return buf->vc_handle; + } + EXPORT_SYMBOL_GPL(vc_sm_cma_int_handle); + +@@ -804,7 +1242,7 @@ EXPORT_SYMBOL_GPL(vc_sm_cma_free); + int vc_sm_cma_import_dmabuf(struct dma_buf *src_dmabuf, void **handle) + { + struct dma_buf *new_dma_buf; +- struct vc_sm_buffer *res; ++ struct vc_sm_buffer *buf; + int ret; + + /* Validate we can work with this device. */ +@@ -818,7 +1256,7 @@ int vc_sm_cma_import_dmabuf(struct dma_b + + if (!ret) { + pr_debug("%s: imported to ptr %p\n", __func__, new_dma_buf); +- res = (struct vc_sm_buffer *)new_dma_buf->priv; ++ buf = (struct vc_sm_buffer *)new_dma_buf->priv; + + /* Assign valid handle at this time.*/ + *handle = new_dma_buf; +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.h ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.h +@@ -21,6 +21,8 @@ + #include + #include + ++#include "vc_sm_cma.h" ++ + #define VC_SM_MAX_NAME_LEN 32 + + enum vc_sm_vpu_mapping_state { +@@ -29,31 +31,51 @@ enum vc_sm_vpu_mapping_state { + VPU_UNMAPPING + }; + ++struct vc_sm_imported { ++ struct dma_buf *dma_buf; ++ struct dma_buf_attachment *attach; ++ struct sg_table *sgt; ++}; ++ + struct vc_sm_buffer { + struct list_head global_buffer_list; /* Global list of buffers. */ + ++ /* Index in the kernel_id idr so that we can find the ++ * mmal_msg_context again when servicing the VCHI reply. ++ */ ++ int kernel_id; ++ + size_t size; + + /* Lock over all the following state for this buffer */ + struct mutex lock; +- struct sg_table *sg_table; + struct list_head attachments; + + char name[VC_SM_MAX_NAME_LEN]; + + int in_use:1; /* Kernel is still using this resource */ ++ int imported:1; /* Imported dmabuf */ ++ ++ struct sg_table *sg_table; + + enum vc_sm_vpu_mapping_state vpu_state; + u32 vc_handle; /* VideoCore handle for this buffer */ ++ int vpu_allocated; /* ++ * The VPU made this allocation. Release the ++ * local dma_buf when the VPU releases the ++ * resource. ++ */ + + /* DMABUF related fields */ +- struct dma_buf *import_dma_buf; + struct dma_buf *dma_buf; +- struct dma_buf_attachment *attach; +- struct sg_table *sgt; + dma_addr_t dma_addr; + + struct vc_sm_privdata_t *private; ++ ++ union { ++ struct vc_sm_cma_alloc_data alloc; ++ struct vc_sm_imported import; ++ }; + }; + + #endif +--- /dev/null ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.c +@@ -0,0 +1,99 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * VideoCore Shared Memory CMA allocator ++ * ++ * Copyright: 2018, Raspberry Pi (Trading) Ltd ++ * ++ * Based on the Android ION allocator ++ * Copyright (C) Linaro 2012 ++ * Author: for ST-Ericsson. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "vc_sm_cma.h" ++ ++/* CMA heap operations functions */ ++int vc_sm_cma_buffer_allocate(struct cma *cma_heap, ++ struct vc_sm_cma_alloc_data *buffer, ++ unsigned long len) ++{ ++ /* len should already be page aligned */ ++ unsigned long num_pages = len / PAGE_SIZE; ++ struct sg_table *table; ++ struct page *pages; ++ int ret; ++ ++ pages = cma_alloc(cma_heap, num_pages, 0, GFP_KERNEL); ++ if (!pages) ++ return -ENOMEM; ++ ++ table = kmalloc(sizeof(*table), GFP_KERNEL); ++ if (!table) ++ goto err; ++ ++ ret = sg_alloc_table(table, 1, GFP_KERNEL); ++ if (ret) ++ goto free_mem; ++ ++ sg_set_page(table->sgl, pages, len, 0); ++ ++ buffer->priv_virt = pages; ++ buffer->sg_table = table; ++ buffer->cma_heap = cma_heap; ++ buffer->num_pages = num_pages; ++ return 0; ++ ++free_mem: ++ kfree(table); ++err: ++ cma_release(cma_heap, pages, num_pages); ++ return -ENOMEM; ++} ++ ++void vc_sm_cma_buffer_free(struct vc_sm_cma_alloc_data *buffer) ++{ ++ struct cma *cma_heap = buffer->cma_heap; ++ struct page *pages = buffer->priv_virt; ++ ++ /* release memory */ ++ if (cma_heap) ++ cma_release(cma_heap, pages, buffer->num_pages); ++ ++ /* release sg table */ ++ if (buffer->sg_table) { ++ sg_free_table(buffer->sg_table); ++ kfree(buffer->sg_table); ++ buffer->sg_table = NULL; ++ } ++} ++ ++int __vc_sm_cma_add_heaps(struct cma *cma, void *priv) ++{ ++ struct cma **heap = (struct cma **)priv; ++ const char *name = cma_get_name(cma); ++ ++ if (!(*heap)) { ++ phys_addr_t phys_addr = cma_get_base(cma); ++ ++ pr_debug("%s: Adding cma heap %s (start %pap, size %lu) for use by vcsm\n", ++ __func__, name, &phys_addr, cma_get_size(cma)); ++ *heap = cma; ++ } else { ++ pr_err("%s: Ignoring heap %s as already set\n", ++ __func__, name); ++ } ++ ++ return 0; ++} ++ ++int vc_sm_cma_add_heaps(struct cma **cma_heap) ++{ ++ cma_for_each_area(__vc_sm_cma_add_heaps, cma_heap); ++ return 0; ++} +--- /dev/null ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.h +@@ -0,0 +1,39 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++ ++/* ++ * VideoCore Shared Memory CMA allocator ++ * ++ * Copyright: 2018, Raspberry Pi (Trading) Ltd ++ * ++ * Based on the Android ION allocator ++ * Copyright (C) Linaro 2012 ++ * Author: for ST-Ericsson. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * 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 VC_SM_CMA_H ++#define VC_SM_CMA_H ++ ++struct vc_sm_cma_alloc_data { ++ struct cma *cma_heap; ++ unsigned long num_pages; ++ void *priv_virt; ++ struct sg_table *sg_table; ++}; ++ ++int vc_sm_cma_buffer_allocate(struct cma *cma_heap, ++ struct vc_sm_cma_alloc_data *buffer, ++ unsigned long len); ++void vc_sm_cma_buffer_free(struct vc_sm_cma_alloc_data *buffer); ++ ++int vc_sm_cma_add_heaps(struct cma **cma_heap); ++ ++#endif +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c +@@ -500,3 +500,13 @@ int vc_sm_cma_vchi_client_version(struct + msg, sizeof(*msg), NULL, 0, + cur_trans_id, 0); + } ++ ++int vc_sm_vchi_client_vc_mem_req_reply(struct sm_instance *handle, ++ struct vc_sm_vc_mem_request_result *msg, ++ uint32_t *cur_trans_id) ++{ ++ return vc_sm_cma_vchi_send_msg(handle, ++ VC_SM_MSG_TYPE_VC_MEM_REQUEST_REPLY, ++ msg, sizeof(*msg), 0, 0, cur_trans_id, ++ 0); ++} +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.h ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.h +@@ -56,4 +56,8 @@ int vc_sm_cma_vchi_client_version(struct + struct vc_sm_result_t *result, + u32 *cur_trans_id); + ++int vc_sm_vchi_client_vc_mem_req_reply(struct sm_instance *handle, ++ struct vc_sm_vc_mem_request_result *msg, ++ uint32_t *cur_trans_id); ++ + #endif /* __VC_SM_CMA_VCHI_H__INCLUDED__ */ +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_defs.h ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_defs.h +@@ -264,6 +264,8 @@ struct vc_sm_vc_mem_request { + u32 align; + /* resource name (for easier tracking) */ + char name[VC_SM_RESOURCE_NAME]; ++ /* VPU handle for the resource */ ++ u32 vc_handle; + }; + + /* Response from the kernel to provide the VPU with some memory */ diff --git a/target/linux/brcm2708/patches-4.19/950-0627-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch b/target/linux/brcm2708/patches-4.19/950-0627-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch deleted file mode 100644 index b5111db67c..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0627-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch +++ /dev/null @@ -1,134 +0,0 @@ -From 4a720b86a1ef014dcaa6e55deec883312ca3afce Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 30 May 2019 13:56:15 +0100 -Subject: [PATCH 627/703] drm/vc4: fkms to query the VPU for HDMI clock limits - -The VPU has configured clocks for 4k (or not) via config.txt, -and will limit the choice of video modes based on that. -Make fkms query it for these limits too to avoid selecting modes -that can not be handled by the current clock setup. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_drv.h | 1 + - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 48 ++++++++++++++++++++++ - include/soc/bcm2835/raspberrypi-firmware.h | 1 + - 3 files changed, 50 insertions(+) - ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -77,6 +77,7 @@ struct vc4_dev { - struct vc4_dsi *dsi1; - struct vc4_vec *vec; - struct vc4_txp *txp; -+ struct vc4_fkms *fkms; - - struct vc4_hang_state *hang_state; - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -29,6 +29,14 @@ - #include "vc_image_types.h" - #include - -+struct get_display_cfg { -+ u32 max_pixel_clock[2]; //Max pixel clock for each display -+}; -+ -+struct vc4_fkms { -+ struct get_display_cfg cfg; -+}; -+ - #define PLANES_PER_CRTC 3 - - struct set_plane { -@@ -794,6 +802,11 @@ static void vc4_crtc_enable(struct drm_c - static enum drm_mode_status - vc4_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode) - { -+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); -+ struct drm_device *dev = crtc->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_fkms *fkms = vc4->fkms; -+ - /* Do not allow doublescan modes from user space */ - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) { - DRM_DEBUG_KMS("[CRTC:%d] Doublescan mode rejected.\n", -@@ -801,6 +814,22 @@ vc4_crtc_mode_valid(struct drm_crtc *crt - return MODE_NO_DBLESCAN; - } - -+ /* Limit the pixel clock based on the HDMI clock limits from the -+ * firmware -+ */ -+ switch (vc4_crtc->display_number) { -+ case 2: /* HDMI0 */ -+ if (fkms->cfg.max_pixel_clock[0] && -+ mode->clock > fkms->cfg.max_pixel_clock[0]) -+ return MODE_CLOCK_HIGH; -+ break; -+ case 7: /* HDMI1 */ -+ if (fkms->cfg.max_pixel_clock[1] && -+ mode->clock > fkms->cfg.max_pixel_clock[1]) -+ return MODE_CLOCK_HIGH; -+ break; -+ } -+ - /* Limit the pixel clock until we can get dynamic HDMI 2.0 scrambling - * working. - */ -@@ -1301,11 +1330,16 @@ static int vc4_fkms_bind(struct device * - struct device_node *firmware_node; - struct vc4_crtc **crtc_list; - u32 num_displays, display_num; -+ struct vc4_fkms *fkms; - int ret; - u32 display_id; - - vc4->firmware_kms = true; - -+ fkms = devm_kzalloc(dev, sizeof(*fkms), GFP_KERNEL); -+ if (!fkms) -+ return -ENOMEM; -+ - /* firmware kms doesn't have precise a scanoutpos implementation, so - * we can't do the precise vblank timestamp mode. - */ -@@ -1334,6 +1368,18 @@ static int vc4_fkms_bind(struct device * - ret = 0; - } - -+ ret = rpi_firmware_property(vc4->firmware, -+ RPI_FIRMWARE_GET_DISPLAY_CFG, -+ &fkms->cfg, sizeof(fkms->cfg)); -+ -+ if (ret) -+ return -EINVAL; -+ /* The firmware works in Hz. This will be compared against kHz, so div -+ * 1000 now rather than multiple times later. -+ */ -+ fkms->cfg.max_pixel_clock[0] /= 1000; -+ fkms->cfg.max_pixel_clock[1] /= 1000; -+ - /* Allocate a list, with space for a NULL on the end */ - crtc_list = devm_kzalloc(dev, sizeof(crtc_list) * (num_displays + 1), - GFP_KERNEL); -@@ -1375,6 +1421,8 @@ static int vc4_fkms_bind(struct device * - DRM_WARN("No displays found. Consider forcing hotplug if HDMI is attached\n"); - } - -+ vc4->fkms = fkms; -+ - platform_set_drvdata(pdev, crtc_list); - - return 0; ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -153,6 +153,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_SET_PLANE = 0x00048015, - RPI_FIRMWARE_GET_DISPLAY_TIMING = 0x00040017, - RPI_FIRMWARE_SET_TIMING = 0x00048017, -+ RPI_FIRMWARE_GET_DISPLAY_CFG = 0x00040018, - - RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, - RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, diff --git a/target/linux/brcm2708/patches-4.19/950-0627-staging-vc-sm-cma-Update-TODO.patch b/target/linux/brcm2708/patches-4.19/950-0627-staging-vc-sm-cma-Update-TODO.patch new file mode 100644 index 0000000000..1f3e26e281 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0627-staging-vc-sm-cma-Update-TODO.patch @@ -0,0 +1,20 @@ +From 010e6c5fe89059edff82fdbc05726e26e6a0b2b0 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 11 Mar 2019 16:38:32 +0000 +Subject: [PATCH 627/725] staging: vc-sm-cma: Update TODO. + +The driver is already a platform driver, so that can be +deleted from the TODO. +There are no known issues that need to be resolved. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vc-sm-cma/TODO | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/vc-sm-cma/TODO ++++ b/drivers/staging/vc04_services/vc-sm-cma/TODO +@@ -1,2 +1 @@ +-1) Convert to a platform driver. +- ++No currently outstanding tasks except some clean-up. diff --git a/target/linux/brcm2708/patches-4.19/950-0628-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch b/target/linux/brcm2708/patches-4.19/950-0628-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch deleted file mode 100644 index 56e17a4285..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0628-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 78bd1c0169850a388fd7a45af6dd566613403a8e Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 30 May 2019 15:55:15 +0100 -Subject: [PATCH 628/703] drm/vc4: Max resolution of 7680 is conditional on - being Pi4 - -The max resolution had been increased from 2048 to 7680 for all -platforms. This code is common with Pi0-3 which have a max render -target for GL of 2048, therefore the increased resolution has to -be conditional on the platform. -Switch based on whether the bcm2835-v3d node is found, as that is -not present on Pi4. (There is a potential configuration on Pi0-3 -with no v3d, but this is very unlikely). - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_kms.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -429,8 +429,14 @@ int vc4_kms_load(struct drm_device *dev) - return ret; - } - -- dev->mode_config.max_width = 7680; -- dev->mode_config.max_height = 7680; -+ if (!drm_core_check_feature(dev, DRIVER_RENDER)) { -+ /* No V3D as part of vc4. Assume this is Pi4. */ -+ dev->mode_config.max_width = 7680; -+ dev->mode_config.max_height = 7680; -+ } else { -+ dev->mode_config.max_width = 2048; -+ dev->mode_config.max_height = 2048; -+ } - dev->mode_config.funcs = &vc4_mode_funcs; - dev->mode_config.preferred_depth = 24; - dev->mode_config.async_page_flip = true; diff --git a/target/linux/brcm2708/patches-4.19/950-0628-staging-vc-sm-cma-Add-in-userspace-allocation-API.patch b/target/linux/brcm2708/patches-4.19/950-0628-staging-vc-sm-cma-Add-in-userspace-allocation-API.patch new file mode 100644 index 0000000000..a251de6753 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0628-staging-vc-sm-cma-Add-in-userspace-allocation-API.patch @@ -0,0 +1,675 @@ +From 0f56a2c03c3255d27bd8ee1c5cb32cc132b8c523 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 11 Mar 2019 16:35:23 +0000 +Subject: [PATCH 628/725] staging: vc-sm-cma: Add in userspace allocation API + +Replacing the functionality from the older vc-sm driver, +add in a userspace API that allows allocation of buffers, +and importing of dma-bufs. +The driver hands out dma-buf fds, therefore much of the +handling around lifespan and odd mmaps from the old driver +goes away. + +Signed-off-by: Dave Stevenson +--- + .../staging/vc04_services/vc-sm-cma/vc_sm.c | 371 ++++++++++++++++-- + .../vc04_services/vc-sm-cma/vc_sm_cma.c | 3 +- + .../vc04_services/vc-sm-cma/vc_sm_cma.h | 2 +- + include/linux/broadcom/vc_sm_cma_ioctl.h | 87 ++++ + 4 files changed, 435 insertions(+), 28 deletions(-) + create mode 100644 include/linux/broadcom/vc_sm_cma_ioctl.h + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -52,6 +53,7 @@ + #include "vc_sm.h" + #include "vc_sm_cma.h" + #include "vc_sm_knl.h" ++#include + + /* ---- Private Constants and Types --------------------------------------- */ + +@@ -83,6 +85,8 @@ struct sm_pde_t { + struct sm_state_t { + struct platform_device *pdev; + ++ struct miscdevice misc_dev; ++ + struct sm_instance *sm_handle; /* Handle for videocore service. */ + struct cma *cma_heap; + +@@ -346,7 +350,6 @@ static void vc_sm_release_resource(struc + + defer: + mutex_unlock(&buffer->lock); +- return; + } + + /* Create support for private data tracking. */ +@@ -381,7 +384,7 @@ static struct sg_table *dup_sg_table(str + ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL); + if (ret) { + kfree(new_table); +- return ERR_PTR(-ENOMEM); ++ return ERR_PTR(ret); + } + + new_sg = new_table->sgl; +@@ -417,7 +420,7 @@ static int vc_sm_dma_buf_attach(struct d + table = dup_sg_table(buf->sg_table); + if (IS_ERR(table)) { + kfree(a); +- return -ENOMEM; ++ return PTR_ERR(table); + } + + a->table = table; +@@ -433,8 +436,8 @@ static int vc_sm_dma_buf_attach(struct d + return 0; + } + +-static void vc_sm_dma_buf_detatch(struct dma_buf *dmabuf, +- struct dma_buf_attachment *attachment) ++static void vc_sm_dma_buf_detach(struct dma_buf *dmabuf, ++ struct dma_buf_attachment *attachment) + { + struct vc_sm_dma_buf_attachment *a = attachment->priv; + struct vc_sm_buffer *buf = dmabuf->priv; +@@ -544,6 +547,9 @@ static void vc_sm_dma_buf_release(struct + vc_sm_clean_up_dmabuf(buffer); + pr_debug("%s clean_up dmabuf done\n", __func__); + ++ /* buffer->lock will be destroyed by vc_sm_release_resource if finished ++ * with, otherwise unlocked. Do NOT unlock here. ++ */ + vc_sm_release_resource(buffer); + pr_debug("%s done\n", __func__); + } +@@ -613,7 +619,7 @@ static const struct dma_buf_ops dma_buf_ + .mmap = vc_sm_dmabuf_mmap, + .release = vc_sm_dma_buf_release, + .attach = vc_sm_dma_buf_attach, +- .detach = vc_sm_dma_buf_detatch, ++ .detach = vc_sm_dma_buf_detach, + .begin_cpu_access = vc_sm_dma_buf_begin_cpu_access, + .end_cpu_access = vc_sm_dma_buf_end_cpu_access, + .map = vc_sm_dma_buf_kmap, +@@ -762,6 +768,7 @@ static const struct dma_buf_ops dma_buf_ + int + vc_sm_cma_import_dmabuf_internal(struct vc_sm_privdata_t *private, + struct dma_buf *dma_buf, ++ int fd, + struct dma_buf **imported_buf) + { + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); +@@ -775,10 +782,15 @@ vc_sm_cma_import_dmabuf_internal(struct + int status; + + /* Setup our allocation parameters */ +- pr_debug("%s: importing dma_buf %p\n", __func__, dma_buf); ++ pr_debug("%s: importing dma_buf %p/fd %d\n", __func__, dma_buf, fd); + +- get_dma_buf(dma_buf); +- dma_buf = dma_buf; ++ if (fd < 0) ++ get_dma_buf(dma_buf); ++ else ++ dma_buf = dma_buf_get(fd); ++ ++ if (!dma_buf) ++ return -EINVAL; + + attach = dma_buf_attach(dma_buf, &sm_state->pdev->dev); + if (IS_ERR(attach)) { +@@ -921,6 +933,10 @@ static int vc_sm_cma_vpu_alloc(u32 size, + return -ENOMEM; + + mutex_init(&buffer->lock); ++ /* Acquire the mutex as vc_sm_release_resource will release it in the ++ * error path. ++ */ ++ mutex_lock(&buffer->lock); + + if (vc_sm_cma_buffer_allocate(sm_state->cma_heap, &buffer->alloc, + aligned_size)) { +@@ -976,6 +992,8 @@ static int vc_sm_cma_vpu_alloc(u32 size, + + vc_sm_add_resource(sm_state->vpu_allocs, buffer); + ++ mutex_unlock(&buffer->lock); ++ + *ret_buffer = buffer; + return 0; + error: +@@ -1065,6 +1083,297 @@ vc_sm_vpu_event(struct sm_instance *inst + } + } + ++/* Userspace handling */ ++/* ++ * Open the device. Creates a private state to help track all allocation ++ * associated with this device. ++ */ ++static int vc_sm_cma_open(struct inode *inode, struct file *file) ++{ ++ /* Make sure the device was started properly. */ ++ if (!sm_state) { ++ pr_err("[%s]: invalid device\n", __func__); ++ return -EPERM; ++ } ++ ++ file->private_data = vc_sm_cma_create_priv_data(current->tgid); ++ if (!file->private_data) { ++ pr_err("[%s]: failed to create data tracker\n", __func__); ++ ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++/* ++ * Close the vcsm-cma device. ++ * All allocations are file descriptors to the dmabuf objects, so we will get ++ * the clean up request on those as those are cleaned up. ++ */ ++static int vc_sm_cma_release(struct inode *inode, struct file *file) ++{ ++ struct vc_sm_privdata_t *file_data = ++ (struct vc_sm_privdata_t *)file->private_data; ++ int ret = 0; ++ ++ /* Make sure the device was started properly. */ ++ if (!sm_state || !file_data) { ++ pr_err("[%s]: invalid device\n", __func__); ++ ret = -EPERM; ++ goto out; ++ } ++ ++ pr_debug("[%s]: using private data %p\n", __func__, file_data); ++ ++ /* Terminate the private data. */ ++ kfree(file_data); ++ ++out: ++ return ret; ++} ++ ++/* ++ * Allocate a shared memory handle and block. ++ * Allocation is from CMA, and then imported into the VPU mappings. ++ */ ++int vc_sm_cma_ioctl_alloc(struct vc_sm_privdata_t *private, ++ struct vc_sm_cma_ioctl_alloc *ioparam) ++{ ++ DEFINE_DMA_BUF_EXPORT_INFO(exp_info); ++ struct vc_sm_buffer *buffer = NULL; ++ struct vc_sm_import import = { 0 }; ++ struct vc_sm_import_result result = { 0 }; ++ struct dma_buf *dmabuf = NULL; ++ int aligned_size; ++ int ret = 0; ++ int status; ++ int fd = -1; ++ ++ aligned_size = PAGE_ALIGN(ioparam->size); ++ ++ if (!aligned_size) ++ return -EINVAL; ++ ++ /* Allocate local buffer to track this allocation. */ ++ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); ++ if (!buffer) { ++ ret = -ENOMEM; ++ goto error; ++ } ++ ++ if (vc_sm_cma_buffer_allocate(sm_state->cma_heap, &buffer->alloc, ++ aligned_size)) { ++ pr_err("[%s]: cma alloc of %d bytes failed\n", ++ __func__, aligned_size); ++ kfree(buffer); ++ return -ENOMEM; ++ } ++ buffer->sg_table = buffer->alloc.sg_table; ++ ++ if (dma_map_sg(&sm_state->pdev->dev, buffer->sg_table->sgl, ++ buffer->sg_table->nents, DMA_BIDIRECTIONAL) <= 0) { ++ pr_err("[%s]: dma_map_sg failed\n", __func__); ++ ret = -ENOMEM; ++ goto error; ++ } ++ ++ import.type = VC_SM_ALLOC_NON_CACHED; ++ import.allocator = current->tgid; ++ ++ if (*ioparam->name) ++ memcpy(import.name, ioparam->name, sizeof(import.name) - 1); ++ else ++ memcpy(import.name, VC_SM_RESOURCE_NAME_DEFAULT, ++ sizeof(VC_SM_RESOURCE_NAME_DEFAULT)); ++ ++ mutex_init(&buffer->lock); ++ INIT_LIST_HEAD(&buffer->attachments); ++ memcpy(buffer->name, import.name, ++ min(sizeof(buffer->name), sizeof(import.name) - 1)); ++ ++ exp_info.ops = &dma_buf_ops; ++ exp_info.size = aligned_size; ++ exp_info.flags = O_RDWR; ++ exp_info.priv = buffer; ++ ++ dmabuf = dma_buf_export(&exp_info); ++ if (IS_ERR(dmabuf)) { ++ ret = PTR_ERR(dmabuf); ++ goto error; ++ } ++ buffer->dma_buf = dmabuf; ++ ++ import.addr = (uint32_t)sg_dma_address(buffer->sg_table->sgl); ++ import.size = aligned_size; ++ import.kernel_id = (uint32_t)buffer; ++ ++ /* Wrap it into a videocore buffer. */ ++ status = vc_sm_cma_vchi_import(sm_state->sm_handle, &import, &result, ++ &sm_state->int_trans_id); ++ if (status == -EINTR) { ++ pr_debug("[%s]: requesting import memory action restart (trans_id: %u)\n", ++ __func__, sm_state->int_trans_id); ++ ret = -ERESTARTSYS; ++ private->restart_sys = -EINTR; ++ private->int_action = VC_SM_MSG_TYPE_IMPORT; ++ goto error; ++ } else if (status || !result.res_handle) { ++ pr_err("[%s]: failed to import memory on videocore (status: %u, trans_id: %u)\n", ++ __func__, status, sm_state->int_trans_id); ++ ret = -ENOMEM; ++ goto error; ++ } ++ ++ /* Keep track of the buffer we created. */ ++ buffer->private = private; ++ buffer->vc_handle = result.res_handle; ++ buffer->size = import.size; ++ buffer->dma_addr = import.addr; ++ buffer->vpu_state = VPU_MAPPED; ++ //buffer->res_cached = ioparam->cached; ++ ++ fd = dma_buf_fd(dmabuf, O_CLOEXEC); ++ if (fd < 0) ++ goto error; ++ ++ vc_sm_add_resource(private, buffer); ++ ++ pr_debug("[%s]: Added resource as fd %d, buffer %p, private %p, dma_addr %pad\n", ++ __func__, fd, buffer, private, &buffer->dma_addr); ++ ++ /* We're done */ ++ ioparam->handle = fd; ++ ioparam->vc_handle = buffer->vc_handle; ++ ioparam->dma_addr = buffer->dma_addr; ++ return 0; ++ ++error: ++ if (buffer) { ++ pr_err("[%s]: something failed - cleanup. ret %d\n", __func__, ++ ret); ++ ++ dma_buf_put(dmabuf); ++ } ++ return ret; ++} ++ ++static long vc_sm_cma_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ int ret = 0; ++ unsigned int cmdnr = _IOC_NR(cmd); ++ struct vc_sm_privdata_t *file_data = ++ (struct vc_sm_privdata_t *)file->private_data; ++ ++ /* Validate we can work with this device. */ ++ if (!sm_state || !file_data) { ++ pr_err("[%s]: invalid device\n", __func__); ++ return -EPERM; ++ } ++ ++ pr_debug("[%s]: cmd %x tgid %u, owner %u\n", __func__, cmdnr, ++ current->tgid, file_data->pid); ++ ++ /* Action is a re-post of a previously interrupted action? */ ++ if (file_data->restart_sys == -EINTR) { ++ struct vc_sm_action_clean_t action_clean; ++ ++ pr_debug("[%s]: clean up of action %u (trans_id: %u) following EINTR\n", ++ __func__, file_data->int_action, ++ file_data->int_trans_id); ++ ++ action_clean.res_action = file_data->int_action; ++ action_clean.action_trans_id = file_data->int_trans_id; ++ ++ file_data->restart_sys = 0; ++ } ++ ++ /* Now process the command. */ ++ switch (cmdnr) { ++ /* New memory allocation. ++ */ ++ case VC_SM_CMA_CMD_ALLOC: ++ { ++ struct vc_sm_cma_ioctl_alloc ioparam; ++ ++ /* Get the parameter data. */ ++ if (copy_from_user ++ (&ioparam, (void *)arg, sizeof(ioparam)) != 0) { ++ pr_err("[%s]: failed to copy-from-user for cmd %x\n", ++ __func__, cmdnr); ++ ret = -EFAULT; ++ break; ++ } ++ ++ ret = vc_sm_cma_ioctl_alloc(file_data, &ioparam); ++ if (!ret && ++ (copy_to_user((void *)arg, &ioparam, ++ sizeof(ioparam)) != 0)) { ++ /* FIXME: Release allocation */ ++ pr_err("[%s]: failed to copy-to-user for cmd %x\n", ++ __func__, cmdnr); ++ ret = -EFAULT; ++ } ++ break; ++ } ++ ++ case VC_SM_CMA_CMD_IMPORT_DMABUF: ++ { ++ struct vc_sm_cma_ioctl_import_dmabuf ioparam; ++ struct dma_buf *new_dmabuf; ++ ++ /* Get the parameter data. */ ++ if (copy_from_user ++ (&ioparam, (void *)arg, sizeof(ioparam)) != 0) { ++ pr_err("[%s]: failed to copy-from-user for cmd %x\n", ++ __func__, cmdnr); ++ ret = -EFAULT; ++ break; ++ } ++ ++ ret = vc_sm_cma_import_dmabuf_internal(file_data, ++ NULL, ++ ioparam.dmabuf_fd, ++ &new_dmabuf); ++ ++ if (!ret) { ++ struct vc_sm_buffer *buf = new_dmabuf->priv; ++ ++ ioparam.size = buf->size; ++ ioparam.handle = dma_buf_fd(new_dmabuf, ++ O_CLOEXEC); ++ ioparam.vc_handle = buf->vc_handle; ++ ioparam.dma_addr = buf->dma_addr; ++ ++ if (ioparam.handle < 0 || ++ (copy_to_user((void *)arg, &ioparam, ++ sizeof(ioparam)) != 0)) { ++ dma_buf_put(new_dmabuf); ++ /* FIXME: Release allocation */ ++ ret = -EFAULT; ++ } ++ } ++ break; ++ } ++ ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ ++ return ret; ++} ++ ++/* Device operations that we managed in this driver. */ ++static const struct file_operations vc_sm_ops = { ++ .owner = THIS_MODULE, ++ .unlocked_ioctl = vc_sm_cma_ioctl, ++ .open = vc_sm_cma_open, ++ .release = vc_sm_cma_release, ++}; ++ ++/* Driver load/unload functions */ + /* Videocore connected. */ + static void vc_sm_connected_init(void) + { +@@ -1075,12 +1384,11 @@ static void vc_sm_connected_init(void) + + pr_info("[%s]: start\n", __func__); + +- if (vc_sm_cma_add_heaps(&sm_state->cma_heap) || +- !sm_state->cma_heap) { +- pr_err("[%s]: failed to initialise CMA heaps\n", ++ vc_sm_cma_add_heaps(&sm_state->cma_heap); ++ if (!sm_state->cma_heap) { ++ pr_err("[%s]: failed to initialise CMA heap\n", + __func__); +- ret = -EIO; +- goto err_free_mem; ++ return; + } + + /* +@@ -1092,8 +1400,7 @@ static void vc_sm_connected_init(void) + pr_err("[%s]: failed to initialise VCHI instance (ret=%d)\n", + __func__, ret); + +- ret = -EIO; +- goto err_failed; ++ return; + } + + ret = vchi_connect(NULL, 0, vchi_instance); +@@ -1101,8 +1408,7 @@ static void vc_sm_connected_init(void) + pr_err("[%s]: failed to connect VCHI instance (ret=%d)\n", + __func__, ret); + +- ret = -EIO; +- goto err_failed; ++ return; + } + + /* Initialize an instance of the shared memory service. */ +@@ -1112,8 +1418,7 @@ static void vc_sm_connected_init(void) + pr_err("[%s]: failed to initialize shared memory service\n", + __func__); + +- ret = -EPERM; +- goto err_failed; ++ return; + } + + /* Create a debug fs directory entry (root). */ +@@ -1127,11 +1432,22 @@ static void vc_sm_connected_init(void) + + INIT_LIST_HEAD(&sm_state->buffer_list); + ++ /* Create a shared memory device. */ ++ sm_state->misc_dev.minor = MISC_DYNAMIC_MINOR; ++ sm_state->misc_dev.name = DEVICE_NAME; ++ sm_state->misc_dev.fops = &vc_sm_ops; ++ sm_state->misc_dev.parent = NULL; ++ ret = misc_register(&sm_state->misc_dev); ++ if (ret) { ++ pr_err("vcsm-cma: failed to register misc device.\n"); ++ goto err_remove_debugfs; ++ } ++ + sm_state->data_knl = vc_sm_cma_create_priv_data(0); + if (!sm_state->data_knl) { + pr_err("[%s]: failed to create kernel private data tracker\n", + __func__); +- goto err_remove_shared_memory; ++ goto err_remove_misc_dev; + } + + version.version = 2; +@@ -1148,11 +1464,13 @@ static void vc_sm_connected_init(void) + pr_info("[%s]: installed successfully\n", __func__); + return; + +-err_remove_shared_memory: ++err_remove_misc_dev: ++ misc_deregister(&sm_state->misc_dev); ++err_remove_debugfs: + debugfs_remove_recursive(sm_state->dir_root); + vc_sm_cma_vchi_stop(&sm_state->sm_handle); +-err_failed: +- pr_info("[%s]: failed, ret %d\n", __func__, ret); ++ ++ return; + } + + /* Driver loading. */ +@@ -1184,6 +1502,8 @@ static int bcm2835_vc_sm_cma_remove(stru + { + pr_debug("[%s]: start\n", __func__); + if (sm_inited) { ++ misc_deregister(&sm_state->misc_dev); ++ + /* Remove all proc entries. */ + debugfs_remove_recursive(sm_state->dir_root); + +@@ -1202,6 +1522,7 @@ static int bcm2835_vc_sm_cma_remove(stru + return 0; + } + ++/* Kernel API calls */ + /* Get an internal resource handle mapped from the external one. */ + int vc_sm_cma_int_handle(void *handle) + { +@@ -1252,7 +1573,7 @@ int vc_sm_cma_import_dmabuf(struct dma_b + } + + ret = vc_sm_cma_import_dmabuf_internal(sm_state->data_knl, src_dmabuf, +- &new_dma_buf); ++ -1, &new_dma_buf); + + if (!ret) { + pr_debug("%s: imported to ptr %p\n", __func__, new_dma_buf); +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.c +@@ -92,8 +92,7 @@ int __vc_sm_cma_add_heaps(struct cma *cm + return 0; + } + +-int vc_sm_cma_add_heaps(struct cma **cma_heap) ++void vc_sm_cma_add_heaps(struct cma **cma_heap) + { + cma_for_each_area(__vc_sm_cma_add_heaps, cma_heap); +- return 0; + } +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.h ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.h +@@ -34,6 +34,6 @@ int vc_sm_cma_buffer_allocate(struct cma + unsigned long len); + void vc_sm_cma_buffer_free(struct vc_sm_cma_alloc_data *buffer); + +-int vc_sm_cma_add_heaps(struct cma **cma_heap); ++void vc_sm_cma_add_heaps(struct cma **cma_heap); + + #endif +--- /dev/null ++++ b/include/linux/broadcom/vc_sm_cma_ioctl.h +@@ -0,0 +1,87 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++ ++/* ++ * Copyright 2019 Raspberry Pi (Trading) Ltd. All rights reserved. ++ * ++ * Based on vmcs_sm_ioctl.h Copyright Broadcom Corporation. ++ */ ++ ++#ifndef __VC_SM_CMA_IOCTL_H ++#define __VC_SM_CMA_IOCTL_H ++ ++/* ---- Include Files ---------------------------------------------------- */ ++ ++#if defined(__KERNEL__) ++#include /* Needed for standard types */ ++#else ++#include ++#endif ++ ++#include ++ ++/* ---- Constants and Types ---------------------------------------------- */ ++ ++#define VC_SM_CMA_RESOURCE_NAME 32 ++#define VC_SM_CMA_RESOURCE_NAME_DEFAULT "sm-host-resource" ++ ++/* Type define used to create unique IOCTL number */ ++#define VC_SM_CMA_MAGIC_TYPE 'J' ++ ++/* IOCTL commands on /dev/vc-sm-cma */ ++enum vc_sm_cma_cmd_e { ++ VC_SM_CMA_CMD_ALLOC = 0x5A, /* Start at 0x5A arbitrarily */ ++ ++ VC_SM_CMA_CMD_IMPORT_DMABUF, ++ ++ VC_SM_CMA_CMD_LAST /* Do not delete */ ++}; ++ ++/* Cache type supported, conveniently matches the user space definition in ++ * user-vcsm.h. ++ */ ++enum vc_sm_cma_cache_e { ++ VC_SM_CMA_CACHE_NONE, ++ VC_SM_CMA_CACHE_HOST, ++ VC_SM_CMA_CACHE_VC, ++ VC_SM_CMA_CACHE_BOTH, ++}; ++ ++/* IOCTL Data structures */ ++struct vc_sm_cma_ioctl_alloc { ++ /* user -> kernel */ ++ __u32 size; ++ __u32 num; ++ __u32 cached; /* enum vc_sm_cma_cache_e */ ++ __u32 pad; ++ __u8 name[VC_SM_CMA_RESOURCE_NAME]; ++ ++ /* kernel -> user */ ++ __s32 handle; ++ __u32 vc_handle; ++ __u64 dma_addr; ++}; ++ ++struct vc_sm_cma_ioctl_import_dmabuf { ++ /* user -> kernel */ ++ __s32 dmabuf_fd; ++ __u32 cached; /* enum vc_sm_cma_cache_e */ ++ __u8 name[VC_SM_CMA_RESOURCE_NAME]; ++ ++ /* kernel -> user */ ++ __s32 handle; ++ __u32 vc_handle; ++ __u32 size; ++ __u32 pad; ++ __u64 dma_addr; ++}; ++ ++/* IOCTL numbers */ ++#define VC_SM_CMA_IOCTL_MEM_ALLOC\ ++ _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_ALLOC,\ ++ struct vc_sm_cma_ioctl_alloc) ++ ++#define VC_SM_CMA_IOCTL_MEM_IMPORT_DMABUF\ ++ _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_IMPORT_DMABUF,\ ++ struct vc_sm_cma_ioctl_import_dmabuf) ++ ++#endif /* __VC_SM_CMA_IOCTL_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0629-staging-vc-sm-cma-Remove-obsolete-comment-and-make-f.patch b/target/linux/brcm2708/patches-4.19/950-0629-staging-vc-sm-cma-Remove-obsolete-comment-and-make-f.patch deleted file mode 100644 index 92f3682b5c..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0629-staging-vc-sm-cma-Remove-obsolete-comment-and-make-f.patch +++ /dev/null @@ -1,28 +0,0 @@ -From a493861ab01161aedb611793c87456dc1394bec6 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 10 Dec 2018 17:35:58 +0000 -Subject: [PATCH 629/703] staging: vc-sm-cma: Remove obsolete comment and make - function static - -Removes obsolete comment about wanting to pass a function -pointer into mmal-vchiq as we now do. -As the function is passed as a function pointer, the function itself -can be static. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -594,8 +594,7 @@ error: - return ret; - } - --/* FIXME: Pass a function pointer to this into vc_vchi_sm.c */ --void -+static void - vc_sm_vpu_event(struct sm_instance *instance, struct vc_sm_result_t *reply, - int reply_len) - { diff --git a/target/linux/brcm2708/patches-4.19/950-0629-staging-vcsm-cma-Add-cache-control-ioctls.patch b/target/linux/brcm2708/patches-4.19/950-0629-staging-vcsm-cma-Add-cache-control-ioctls.patch new file mode 100644 index 0000000000..e4d29c8e6c --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0629-staging-vcsm-cma-Add-cache-control-ioctls.patch @@ -0,0 +1,245 @@ +From 495a11dc216b24bfde79e61b2335be6da6c86945 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 20 Mar 2019 10:40:00 +0000 +Subject: [PATCH 629/725] staging: vcsm-cma: Add cache control ioctls + +The old driver allowed for direct cache manipulation and that +was used by various clients. Replicate here. + +Signed-off-by: Dave Stevenson +--- + .../staging/vc04_services/vc-sm-cma/vc_sm.c | 141 +++++++++++++++++- + include/linux/broadcom/vc_sm_cma_ioctl.h | 27 ++++ + 2 files changed, 165 insertions(+), 3 deletions(-) + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -46,6 +46,7 @@ + #include + #include + #include ++#include + + #include "vchiq_connected.h" + #include "vc_sm_cma_vchi.h" +@@ -1258,6 +1259,99 @@ error: + return ret; + } + ++/* Converts VCSM_CACHE_OP_* to an operating function. */ ++static void (*cache_op_to_func(const unsigned int cache_op)) ++ (const void*, const void*) ++{ ++ switch (cache_op) { ++ case VC_SM_CACHE_OP_NOP: ++ return NULL; ++ ++ case VC_SM_CACHE_OP_INV: ++ return dmac_inv_range; ++ ++ case VC_SM_CACHE_OP_CLEAN: ++ return dmac_clean_range; ++ ++ case VC_SM_CACHE_OP_FLUSH: ++ return dmac_flush_range; ++ ++ default: ++ pr_err("[%s]: Invalid cache_op: 0x%08x\n", __func__, cache_op); ++ return NULL; ++ } ++} ++ ++/* ++ * Clean/invalid/flush cache of which buffer is already pinned (i.e. accessed). ++ */ ++static int clean_invalid_contig_2d(const void __user *addr, ++ const size_t block_count, ++ const size_t block_size, ++ const size_t stride, ++ const unsigned int cache_op) ++{ ++ size_t i; ++ void (*op_fn)(const void *start, const void *end); ++ ++ if (!block_size) { ++ pr_err("[%s]: size cannot be 0\n", __func__); ++ return -EINVAL; ++ } ++ ++ op_fn = cache_op_to_func(cache_op); ++ if (!op_fn) ++ return -EINVAL; ++ ++ for (i = 0; i < block_count; i ++, addr += stride) ++ op_fn(addr, addr + block_size); ++ ++ return 0; ++} ++ ++static int vc_sm_cma_clean_invalid2(unsigned int cmdnr, unsigned long arg) ++{ ++ struct vc_sm_cma_ioctl_clean_invalid2 ioparam; ++ struct vc_sm_cma_ioctl_clean_invalid_block *block = NULL; ++ int i, ret = 0; ++ ++ /* Get parameter data. */ ++ if (copy_from_user(&ioparam, (void *)arg, sizeof(ioparam))) { ++ pr_err("[%s]: failed to copy-from-user header for cmd %x\n", ++ __func__, cmdnr); ++ return -EFAULT; ++ } ++ block = kmalloc(ioparam.op_count * sizeof(*block), GFP_KERNEL); ++ if (!block) ++ return -EFAULT; ++ ++ if (copy_from_user(block, (void *)(arg + sizeof(ioparam)), ++ ioparam.op_count * sizeof(*block)) != 0) { ++ pr_err("[%s]: failed to copy-from-user payload for cmd %x\n", ++ __func__, cmdnr); ++ ret = -EFAULT; ++ goto out; ++ } ++ ++ for (i = 0; i < ioparam.op_count; i++) { ++ const struct vc_sm_cma_ioctl_clean_invalid_block * const op = block + i; ++ ++ if (op->invalidate_mode == VC_SM_CACHE_OP_NOP) ++ continue; ++ ++ ret = clean_invalid_contig_2d((void __user *)op->start_address, ++ op->block_count, op->block_size, ++ op->inter_block_stride, ++ op->invalidate_mode); ++ if (ret) ++ break; ++ } ++out: ++ kfree(block); ++ ++ return ret; ++} ++ + static long vc_sm_cma_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) + { +@@ -1272,9 +1366,6 @@ static long vc_sm_cma_ioctl(struct file + return -EPERM; + } + +- pr_debug("[%s]: cmd %x tgid %u, owner %u\n", __func__, cmdnr, +- current->tgid, file_data->pid); +- + /* Action is a re-post of a previously interrupted action? */ + if (file_data->restart_sys == -EINTR) { + struct vc_sm_action_clean_t action_clean; +@@ -1357,7 +1448,18 @@ static long vc_sm_cma_ioctl(struct file + break; + } + ++ /* ++ * Flush/Invalidate the cache for a given mapping. ++ * Blocks must be pinned (i.e. accessed) before this call. ++ */ ++ case VC_SM_CMA_CMD_CLEAN_INVALID2: ++ ret = vc_sm_cma_clean_invalid2(cmdnr, arg); ++ break; ++ + default: ++ pr_debug("[%s]: cmd %x tgid %u, owner %u\n", __func__, cmdnr, ++ current->tgid, file_data->pid); ++ + ret = -EINVAL; + break; + } +@@ -1365,10 +1467,43 @@ static long vc_sm_cma_ioctl(struct file + return ret; + } + ++#ifdef CONFIG_COMPAT ++struct vc_sm_cma_ioctl_clean_invalid2_32 { ++ u32 op_count; ++ struct vc_sm_cma_ioctl_clean_invalid_block { ++ u16 invalidate_mode; ++ u16 block_count; ++ compat_uptr_t start_address; ++ u32 block_size; ++ u32 inter_block_stride; ++ } s[0]; ++}; ++ ++#define VC_SM_CMA_CMD_CLEAN_INVALID2_32\ ++ _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_CLEAN_INVALID2,\ ++ struct vc_sm_cma_ioctl_clean_invalid2) ++ ++static long vc_sm_cma_compat_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ switch (cmd) { ++ case VC_SM_CMA_CMD_CLEAN_INVALID2_32: ++ /* FIXME */ ++ break; ++ ++ default: ++ return vc_sm_cma_compat_ioctl(file, cmd, arg); ++ } ++} ++#endif ++ + /* Device operations that we managed in this driver. */ + static const struct file_operations vc_sm_ops = { + .owner = THIS_MODULE, + .unlocked_ioctl = vc_sm_cma_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = vc_sm_cma_compat_ioctl, ++#endif + .open = vc_sm_cma_open, + .release = vc_sm_cma_release, + }; +--- a/include/linux/broadcom/vc_sm_cma_ioctl.h ++++ b/include/linux/broadcom/vc_sm_cma_ioctl.h +@@ -33,6 +33,8 @@ enum vc_sm_cma_cmd_e { + + VC_SM_CMA_CMD_IMPORT_DMABUF, + ++ VC_SM_CMA_CMD_CLEAN_INVALID2, ++ + VC_SM_CMA_CMD_LAST /* Do not delete */ + }; + +@@ -75,6 +77,27 @@ struct vc_sm_cma_ioctl_import_dmabuf { + __u64 dma_addr; + }; + ++/* ++ * Cache functions to be set to struct vc_sm_cma_ioctl_clean_invalid2 ++ * invalidate_mode. ++ */ ++#define VC_SM_CACHE_OP_NOP 0x00 ++#define VC_SM_CACHE_OP_INV 0x01 ++#define VC_SM_CACHE_OP_CLEAN 0x02 ++#define VC_SM_CACHE_OP_FLUSH 0x03 ++ ++struct vc_sm_cma_ioctl_clean_invalid2 { ++ __u32 op_count; ++ __u32 pad; ++ struct vc_sm_cma_ioctl_clean_invalid_block { ++ __u32 invalidate_mode; ++ __u32 block_count; ++ void * __user start_address; ++ __u32 block_size; ++ __u32 inter_block_stride; ++ } s[0]; ++}; ++ + /* IOCTL numbers */ + #define VC_SM_CMA_IOCTL_MEM_ALLOC\ + _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_ALLOC,\ +@@ -84,4 +107,8 @@ struct vc_sm_cma_ioctl_import_dmabuf { + _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_IMPORT_DMABUF,\ + struct vc_sm_cma_ioctl_import_dmabuf) + ++#define VC_SM_CMA_IOCTL_MEM_CLEAN_INVALID2\ ++ _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_CLEAN_INVALID2,\ ++ struct vc_sm_cma_ioctl_clean_invalid2) ++ + #endif /* __VC_SM_CMA_IOCTL_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0630-staging-vc-sm-cma-Add-in-allocation-for-VPU-requests.patch b/target/linux/brcm2708/patches-4.19/950-0630-staging-vc-sm-cma-Add-in-allocation-for-VPU-requests.patch deleted file mode 100644 index 3c4c3d6e4a..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0630-staging-vc-sm-cma-Add-in-allocation-for-VPU-requests.patch +++ /dev/null @@ -1,1206 +0,0 @@ -From 904c0d6a47b181b134a3626bfd93b456ec6b411d Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 21 Dec 2018 16:50:53 +0000 -Subject: [PATCH 630/703] staging: vc-sm-cma: Add in allocation for VPU - requests. - -Module has to change from tristate to bool as all CMA functions -are boolean. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/vc-sm-cma/Kconfig | 4 +- - .../staging/vc04_services/vc-sm-cma/Makefile | 2 +- - .../staging/vc04_services/vc-sm-cma/vc_sm.c | 642 +++++++++++++++--- - .../staging/vc04_services/vc-sm-cma/vc_sm.h | 30 +- - .../vc04_services/vc-sm-cma/vc_sm_cma.c | 99 +++ - .../vc04_services/vc-sm-cma/vc_sm_cma.h | 39 ++ - .../vc04_services/vc-sm-cma/vc_sm_cma_vchi.c | 10 + - .../vc04_services/vc-sm-cma/vc_sm_cma_vchi.h | 4 + - .../vc04_services/vc-sm-cma/vc_sm_defs.h | 2 + - 9 files changed, 723 insertions(+), 109 deletions(-) - create mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.c - create mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.h - ---- a/drivers/staging/vc04_services/vc-sm-cma/Kconfig -+++ b/drivers/staging/vc04_services/vc-sm-cma/Kconfig -@@ -1,6 +1,6 @@ - config BCM_VC_SM_CMA -- tristate "VideoCore Shared Memory (CMA) driver" -- depends on BCM2835_VCHIQ -+ bool "VideoCore Shared Memory (CMA) driver" -+ depends on BCM2835_VCHIQ && DMA_CMA - select RBTREE - select DMA_SHARED_BUFFER - help ---- a/drivers/staging/vc04_services/vc-sm-cma/Makefile -+++ b/drivers/staging/vc04_services/vc-sm-cma/Makefile -@@ -3,6 +3,6 @@ ccflags-y += -Idrivers/staging/vc04_serv - ccflags-y += -D__VCCOREVER__=0 - - vc-sm-cma-$(CONFIG_BCM_VC_SM_CMA) := \ -- vc_sm.o vc_sm_cma_vchi.o -+ vc_sm.o vc_sm_cma_vchi.o vc_sm_cma.o - - obj-$(CONFIG_BCM_VC_SM_CMA) += vc-sm-cma.o ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -9,10 +9,21 @@ - * and taking some code for CMA/dmabuf handling from the Android Ion - * driver (Google/Linaro). - * -- * This is cut down version to only support import of dma_bufs from -- * other kernel drivers. A more complete implementation of the old -- * vmcs_sm functionality can follow later. - * -+ * This driver has 3 main uses: -+ * 1) Allocating buffers for the kernel or userspace that can be shared with the -+ * VPU. -+ * 2) Importing dmabufs from elsewhere for sharing with the VPU. -+ * 3) Allocating buffers for use by the VPU. -+ * -+ * In the first and second cases the native handle is a dmabuf. Releasing the -+ * resource inherently comes from releasing the dmabuf, and this will trigger -+ * unmapping on the VPU. The underlying allocation and our buffer structure are -+ * retained until the VPU has confirmed that it has finished with it. -+ * -+ * For the VPU allocations the VPU is responsible for triggering the release, -+ * and therefore the released message decrements the dma_buf refcount (with the -+ * VPU mapping having already been marked as released). - */ - - /* ---- Include Files ----------------------------------------------------- */ -@@ -39,6 +50,7 @@ - #include "vc_sm_cma_vchi.h" - - #include "vc_sm.h" -+#include "vc_sm_cma.h" - #include "vc_sm_knl.h" - - /* ---- Private Constants and Types --------------------------------------- */ -@@ -72,6 +84,7 @@ struct sm_state_t { - struct platform_device *pdev; - - struct sm_instance *sm_handle; /* Handle for videocore service. */ -+ struct cma *cma_heap; - - spinlock_t kernelid_map_lock; /* Spinlock protecting kernelid_map */ - struct idr kernelid_map; -@@ -80,6 +93,7 @@ struct sm_state_t { - struct list_head buffer_list; /* List of buffer. */ - - struct vc_sm_privdata_t *data_knl; /* Kernel internal data tracking. */ -+ struct vc_sm_privdata_t *vpu_allocs; /* All allocations from the VPU */ - struct dentry *dir_root; /* Debug fs entries root. */ - struct sm_pde_t dir_state; /* Debug fs entries state sub-tree. */ - -@@ -89,6 +103,12 @@ struct sm_state_t { - u32 int_trans_id; /* Interrupted transaction. */ - }; - -+struct vc_sm_dma_buf_attachment { -+ struct device *dev; -+ struct sg_table *table; -+ struct list_head list; -+}; -+ - /* ---- Private Variables ----------------------------------------------- */ - - static struct sm_state_t *sm_state; -@@ -172,12 +192,14 @@ static int vc_sm_cma_global_state_show(s - resource->size); - seq_printf(s, " DMABUF %p\n", - resource->dma_buf); -- seq_printf(s, " ATTACH %p\n", -- resource->attach); -+ if (resource->imported) { -+ seq_printf(s, " ATTACH %p\n", -+ resource->import.attach); -+ seq_printf(s, " SGT %p\n", -+ resource->import.sgt); -+ } - seq_printf(s, " SG_TABLE %p\n", - resource->sg_table); -- seq_printf(s, " SGT %p\n", -- resource->sgt); - seq_printf(s, " DMA_ADDR %pad\n", - &resource->dma_addr); - seq_printf(s, " VC_HANDLE %08x\n", -@@ -209,17 +231,33 @@ static void vc_sm_add_resource(struct vc - } - - /* -- * Release an allocation. -- * All refcounting is done via the dma buf object. -+ * Cleans up imported dmabuf. - */ --static void vc_sm_release_resource(struct vc_sm_buffer *buffer, int force) -+static void vc_sm_clean_up_dmabuf(struct vc_sm_buffer *buffer) - { -- mutex_lock(&sm_state->map_lock); -- mutex_lock(&buffer->lock); -+ if (!buffer->imported) -+ return; - -- pr_debug("[%s]: buffer %p (name %s, size %zu)\n", -- __func__, buffer, buffer->name, buffer->size); -+ /* Handle cleaning up imported dmabufs */ -+ mutex_lock(&buffer->lock); -+ if (buffer->import.sgt) { -+ dma_buf_unmap_attachment(buffer->import.attach, -+ buffer->import.sgt, -+ DMA_BIDIRECTIONAL); -+ buffer->import.sgt = NULL; -+ } -+ if (buffer->import.attach) { -+ dma_buf_detach(buffer->dma_buf, buffer->import.attach); -+ buffer->import.attach = NULL; -+ } -+ mutex_unlock(&buffer->lock); -+} - -+/* -+ * Instructs VPU to decrement the refcount on a buffer. -+ */ -+static void vc_sm_vpu_free(struct vc_sm_buffer *buffer) -+{ - if (buffer->vc_handle && buffer->vpu_state == VPU_MAPPED) { - struct vc_sm_free_t free = { buffer->vc_handle, 0 }; - int status = vc_sm_cma_vchi_free(sm_state->sm_handle, &free, -@@ -230,17 +268,32 @@ static void vc_sm_release_resource(struc - } - - if (sm_state->require_released_callback) { -- /* Need to wait for the VPU to confirm the free */ -+ /* Need to wait for the VPU to confirm the free. */ - - /* Retain a reference on this until the VPU has - * released it - */ - buffer->vpu_state = VPU_UNMAPPING; -- goto defer; -+ } else { -+ buffer->vpu_state = VPU_NOT_MAPPED; -+ buffer->vc_handle = 0; - } -- buffer->vpu_state = VPU_NOT_MAPPED; -- buffer->vc_handle = 0; - } -+} -+ -+/* -+ * Release an allocation. -+ * All refcounting is done via the dma buf object. -+ * -+ * Must be called with the mutex held. The function will either release the -+ * mutex (if defering the release) or destroy it. The caller must therefore not -+ * reuse the buffer on return. -+ */ -+static void vc_sm_release_resource(struct vc_sm_buffer *buffer) -+{ -+ pr_debug("[%s]: buffer %p (name %s, size %zu)\n", -+ __func__, buffer, buffer->name, buffer->size); -+ - if (buffer->vc_handle) { - /* We've sent the unmap request but not had the response. */ - pr_err("[%s]: Waiting for VPU unmap response on %p\n", -@@ -248,45 +301,43 @@ static void vc_sm_release_resource(struc - goto defer; - } - if (buffer->in_use) { -- /* Don't release dmabuf here - we await the release */ -+ /* dmabuf still in use - we await the release */ - pr_err("[%s]: buffer %p is still in use\n", - __func__, buffer); - goto defer; - } - -- /* Handle cleaning up imported dmabufs */ -- if (buffer->sgt) { -- dma_buf_unmap_attachment(buffer->attach, buffer->sgt, -- DMA_BIDIRECTIONAL); -- buffer->sgt = NULL; -- } -- if (buffer->attach) { -- dma_buf_detach(buffer->dma_buf, buffer->attach); -- buffer->attach = NULL; -- } -- -- /* Release the dma_buf (whether ours or imported) */ -- if (buffer->import_dma_buf) { -- dma_buf_put(buffer->import_dma_buf); -- buffer->import_dma_buf = NULL; -- buffer->dma_buf = NULL; -- } else if (buffer->dma_buf) { -- dma_buf_put(buffer->dma_buf); -- buffer->dma_buf = NULL; -+ /* Release the allocation (whether imported dmabuf or CMA allocation) */ -+ if (buffer->imported) { -+ pr_debug("%s: Release imported dmabuf %p\n", __func__, -+ buffer->import.dma_buf); -+ if (buffer->import.dma_buf) -+ dma_buf_put(buffer->import.dma_buf); -+ else -+ pr_err("%s: Imported dmabuf already been put for buf %p\n", -+ __func__, buffer); -+ buffer->import.dma_buf = NULL; -+ } else { -+ if (buffer->sg_table) { -+ /* Our own allocation that we need to dma_unmap_sg */ -+ dma_unmap_sg(&sm_state->pdev->dev, -+ buffer->sg_table->sgl, -+ buffer->sg_table->nents, -+ DMA_BIDIRECTIONAL); -+ } -+ pr_debug("%s: Release our allocation\n", __func__); -+ vc_sm_cma_buffer_free(&buffer->alloc); -+ pr_debug("%s: Release our allocation - done\n", __func__); - } - -- if (buffer->sg_table && !buffer->import_dma_buf) { -- /* Our own allocation that we need to dma_unmap_sg */ -- dma_unmap_sg(&sm_state->pdev->dev, buffer->sg_table->sgl, -- buffer->sg_table->nents, DMA_BIDIRECTIONAL); -- } - -- /* Free the local resource. Start by removing it from the list */ -- buffer->private = NULL; -+ /* Free our buffer. Start by removing it from the list */ -+ mutex_lock(&sm_state->map_lock); - list_del(&buffer->global_buffer_list); -+ mutex_unlock(&sm_state->map_lock); - -+ pr_debug("%s: Release our allocation - done\n", __func__); - mutex_unlock(&buffer->lock); -- mutex_unlock(&sm_state->map_lock); - - mutex_destroy(&buffer->lock); - -@@ -295,7 +346,7 @@ static void vc_sm_release_resource(struc - - defer: - mutex_unlock(&buffer->lock); -- mutex_unlock(&sm_state->map_lock); -+ return; - } - - /* Create support for private data tracking. */ -@@ -317,16 +368,267 @@ static struct vc_sm_privdata_t *vc_sm_cm - return file_data; - } - -+static struct sg_table *dup_sg_table(struct sg_table *table) -+{ -+ struct sg_table *new_table; -+ int ret, i; -+ struct scatterlist *sg, *new_sg; -+ -+ new_table = kzalloc(sizeof(*new_table), GFP_KERNEL); -+ if (!new_table) -+ return ERR_PTR(-ENOMEM); -+ -+ ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL); -+ if (ret) { -+ kfree(new_table); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ new_sg = new_table->sgl; -+ for_each_sg(table->sgl, sg, table->nents, i) { -+ memcpy(new_sg, sg, sizeof(*sg)); -+ sg->dma_address = 0; -+ new_sg = sg_next(new_sg); -+ } -+ -+ return new_table; -+} -+ -+static void free_duped_table(struct sg_table *table) -+{ -+ sg_free_table(table); -+ kfree(table); -+} -+ -+/* Dma buf operations for use with our own allocations */ -+ -+static int vc_sm_dma_buf_attach(struct dma_buf *dmabuf, -+ struct dma_buf_attachment *attachment) -+ -+{ -+ struct vc_sm_dma_buf_attachment *a; -+ struct sg_table *table; -+ struct vc_sm_buffer *buf = dmabuf->priv; -+ -+ a = kzalloc(sizeof(*a), GFP_KERNEL); -+ if (!a) -+ return -ENOMEM; -+ -+ table = dup_sg_table(buf->sg_table); -+ if (IS_ERR(table)) { -+ kfree(a); -+ return -ENOMEM; -+ } -+ -+ a->table = table; -+ INIT_LIST_HEAD(&a->list); -+ -+ attachment->priv = a; -+ -+ mutex_lock(&buf->lock); -+ list_add(&a->list, &buf->attachments); -+ mutex_unlock(&buf->lock); -+ pr_debug("%s dmabuf %p attachment %p\n", __func__, dmabuf, attachment); -+ -+ return 0; -+} -+ -+static void vc_sm_dma_buf_detatch(struct dma_buf *dmabuf, -+ struct dma_buf_attachment *attachment) -+{ -+ struct vc_sm_dma_buf_attachment *a = attachment->priv; -+ struct vc_sm_buffer *buf = dmabuf->priv; -+ -+ pr_debug("%s dmabuf %p attachment %p\n", __func__, dmabuf, attachment); -+ free_duped_table(a->table); -+ mutex_lock(&buf->lock); -+ list_del(&a->list); -+ mutex_unlock(&buf->lock); -+ -+ kfree(a); -+} -+ -+static struct sg_table *vc_sm_map_dma_buf(struct dma_buf_attachment *attachment, -+ enum dma_data_direction direction) -+{ -+ struct vc_sm_dma_buf_attachment *a = attachment->priv; -+ struct sg_table *table; -+ -+ table = a->table; -+ -+ if (!dma_map_sg(attachment->dev, table->sgl, table->nents, -+ direction)) -+ return ERR_PTR(-ENOMEM); -+ -+ pr_debug("%s attachment %p\n", __func__, attachment); -+ return table; -+} -+ -+static void vc_sm_unmap_dma_buf(struct dma_buf_attachment *attachment, -+ struct sg_table *table, -+ enum dma_data_direction direction) -+{ -+ pr_debug("%s attachment %p\n", __func__, attachment); -+ dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction); -+} -+ -+static int vc_sm_dmabuf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) -+{ -+ struct vc_sm_buffer *buf = dmabuf->priv; -+ struct sg_table *table = buf->sg_table; -+ unsigned long addr = vma->vm_start; -+ unsigned long offset = vma->vm_pgoff * PAGE_SIZE; -+ struct scatterlist *sg; -+ int i; -+ int ret = 0; -+ -+ pr_debug("%s dmabuf %p, buf %p, vm_start %08lX\n", __func__, dmabuf, -+ buf, addr); -+ -+ mutex_lock(&buf->lock); -+ -+ /* now map it to userspace */ -+ for_each_sg(table->sgl, sg, table->nents, i) { -+ struct page *page = sg_page(sg); -+ unsigned long remainder = vma->vm_end - addr; -+ unsigned long len = sg->length; -+ -+ if (offset >= sg->length) { -+ offset -= sg->length; -+ continue; -+ } else if (offset) { -+ page += offset / PAGE_SIZE; -+ len = sg->length - offset; -+ offset = 0; -+ } -+ len = min(len, remainder); -+ ret = remap_pfn_range(vma, addr, page_to_pfn(page), len, -+ vma->vm_page_prot); -+ if (ret) -+ break; -+ addr += len; -+ if (addr >= vma->vm_end) -+ break; -+ } -+ mutex_unlock(&buf->lock); -+ -+ if (ret) -+ pr_err("%s: failure mapping buffer to userspace\n", -+ __func__); -+ -+ return ret; -+} -+ -+static void vc_sm_dma_buf_release(struct dma_buf *dmabuf) -+{ -+ struct vc_sm_buffer *buffer; -+ -+ if (!dmabuf) -+ return; -+ -+ buffer = (struct vc_sm_buffer *)dmabuf->priv; -+ -+ mutex_lock(&buffer->lock); -+ -+ pr_debug("%s dmabuf %p, buffer %p\n", __func__, dmabuf, buffer); -+ -+ buffer->in_use = 0; -+ -+ /* Unmap on the VPU */ -+ vc_sm_vpu_free(buffer); -+ pr_debug("%s vpu_free done\n", __func__); -+ -+ /* Unmap our dma_buf object (the vc_sm_buffer remains until released -+ * on the VPU). -+ */ -+ vc_sm_clean_up_dmabuf(buffer); -+ pr_debug("%s clean_up dmabuf done\n", __func__); -+ -+ vc_sm_release_resource(buffer); -+ pr_debug("%s done\n", __func__); -+} -+ -+static int vc_sm_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, -+ enum dma_data_direction direction) -+{ -+ struct vc_sm_buffer *buf; -+ struct vc_sm_dma_buf_attachment *a; -+ -+ if (!dmabuf) -+ return -EFAULT; -+ -+ buf = dmabuf->priv; -+ if (!buf) -+ return -EFAULT; -+ -+ mutex_lock(&buf->lock); -+ -+ list_for_each_entry(a, &buf->attachments, list) { -+ dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents, -+ direction); -+ } -+ mutex_unlock(&buf->lock); -+ -+ return 0; -+} -+ -+static int vc_sm_dma_buf_end_cpu_access(struct dma_buf *dmabuf, -+ enum dma_data_direction direction) -+{ -+ struct vc_sm_buffer *buf; -+ struct vc_sm_dma_buf_attachment *a; -+ -+ if (!dmabuf) -+ return -EFAULT; -+ buf = dmabuf->priv; -+ if (!buf) -+ return -EFAULT; -+ -+ mutex_lock(&buf->lock); -+ -+ list_for_each_entry(a, &buf->attachments, list) { -+ dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents, -+ direction); -+ } -+ mutex_unlock(&buf->lock); -+ -+ return 0; -+} -+ -+static void *vc_sm_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset) -+{ -+ /* FIXME */ -+ return NULL; -+} -+ -+static void vc_sm_dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long offset, -+ void *ptr) -+{ -+ /* FIXME */ -+} -+ -+static const struct dma_buf_ops dma_buf_ops = { -+ .map_dma_buf = vc_sm_map_dma_buf, -+ .unmap_dma_buf = vc_sm_unmap_dma_buf, -+ .mmap = vc_sm_dmabuf_mmap, -+ .release = vc_sm_dma_buf_release, -+ .attach = vc_sm_dma_buf_attach, -+ .detach = vc_sm_dma_buf_detatch, -+ .begin_cpu_access = vc_sm_dma_buf_begin_cpu_access, -+ .end_cpu_access = vc_sm_dma_buf_end_cpu_access, -+ .map = vc_sm_dma_buf_kmap, -+ .unmap = vc_sm_dma_buf_kunmap, -+}; - /* Dma_buf operations for chaining through to an imported dma_buf */ - static - int vc_sm_import_dma_buf_attach(struct dma_buf *dmabuf, - struct dma_buf_attachment *attachment) - { -- struct vc_sm_buffer *res = dmabuf->priv; -+ struct vc_sm_buffer *buf = dmabuf->priv; - -- if (!res->import_dma_buf) -+ if (!buf->imported) - return -EINVAL; -- return res->import_dma_buf->ops->attach(res->import_dma_buf, -+ return buf->import.dma_buf->ops->attach(buf->import.dma_buf, - attachment); - } - -@@ -334,22 +636,23 @@ static - void vc_sm_import_dma_buf_detatch(struct dma_buf *dmabuf, - struct dma_buf_attachment *attachment) - { -- struct vc_sm_buffer *res = dmabuf->priv; -+ struct vc_sm_buffer *buf = dmabuf->priv; - -- if (!res->import_dma_buf) -+ if (!buf->imported) - return; -- res->import_dma_buf->ops->detach(res->import_dma_buf, attachment); -+ buf->import.dma_buf->ops->detach(buf->import.dma_buf, attachment); - } - - static - struct sg_table *vc_sm_import_map_dma_buf(struct dma_buf_attachment *attachment, - enum dma_data_direction direction) - { -- struct vc_sm_buffer *res = attachment->dmabuf->priv; -+ struct vc_sm_buffer *buf = attachment->dmabuf->priv; - -- if (!res->import_dma_buf) -+ if (!buf->imported) - return NULL; -- return res->import_dma_buf->ops->map_dma_buf(attachment, direction); -+ return buf->import.dma_buf->ops->map_dma_buf(attachment, -+ direction); - } - - static -@@ -357,87 +660,88 @@ void vc_sm_import_unmap_dma_buf(struct d - struct sg_table *table, - enum dma_data_direction direction) - { -- struct vc_sm_buffer *res = attachment->dmabuf->priv; -+ struct vc_sm_buffer *buf = attachment->dmabuf->priv; - -- if (!res->import_dma_buf) -+ if (!buf->imported) - return; -- res->import_dma_buf->ops->unmap_dma_buf(attachment, table, direction); -+ buf->import.dma_buf->ops->unmap_dma_buf(attachment, table, direction); - } - - static - int vc_sm_import_dmabuf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) - { -- struct vc_sm_buffer *res = dmabuf->priv; -+ struct vc_sm_buffer *buf = dmabuf->priv; - -- pr_debug("%s: mmap dma_buf %p, res %p, imported db %p\n", __func__, -- dmabuf, res, res->import_dma_buf); -- if (!res->import_dma_buf) { -+ pr_debug("%s: mmap dma_buf %p, buf %p, imported db %p\n", __func__, -+ dmabuf, buf, buf->import.dma_buf); -+ if (!buf->imported) { - pr_err("%s: mmap dma_buf %p- not an imported buffer\n", - __func__, dmabuf); - return -EINVAL; - } -- return res->import_dma_buf->ops->mmap(res->import_dma_buf, vma); -+ return buf->import.dma_buf->ops->mmap(buf->import.dma_buf, vma); - } - - static - void vc_sm_import_dma_buf_release(struct dma_buf *dmabuf) - { -- struct vc_sm_buffer *res = dmabuf->priv; -+ struct vc_sm_buffer *buf = dmabuf->priv; - - pr_debug("%s: Relasing dma_buf %p\n", __func__, dmabuf); -- if (!res->import_dma_buf) -+ mutex_lock(&buf->lock); -+ if (!buf->imported) - return; - -- res->in_use = 0; -+ buf->in_use = 0; - -- vc_sm_release_resource(res, 0); -+ vc_sm_vpu_free(buf); -+ -+ vc_sm_release_resource(buf); - } - - static - void *vc_sm_import_dma_buf_kmap(struct dma_buf *dmabuf, - unsigned long offset) - { -- struct vc_sm_buffer *res = dmabuf->priv; -+ struct vc_sm_buffer *buf = dmabuf->priv; - -- if (!res->import_dma_buf) -+ if (!buf->imported) - return NULL; -- return res->import_dma_buf->ops->map(res->import_dma_buf, -- offset); -+ return buf->import.dma_buf->ops->map(buf->import.dma_buf, offset); - } - - static - void vc_sm_import_dma_buf_kunmap(struct dma_buf *dmabuf, - unsigned long offset, void *ptr) - { -- struct vc_sm_buffer *res = dmabuf->priv; -+ struct vc_sm_buffer *buf = dmabuf->priv; - -- if (!res->import_dma_buf) -+ if (!buf->imported) - return; -- res->import_dma_buf->ops->unmap(res->import_dma_buf, -- offset, ptr); -+ buf->import.dma_buf->ops->unmap(buf->import.dma_buf, offset, ptr); - } - - static - int vc_sm_import_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, - enum dma_data_direction direction) - { -- struct vc_sm_buffer *res = dmabuf->priv; -+ struct vc_sm_buffer *buf = dmabuf->priv; - -- if (!res->import_dma_buf) -+ if (!buf->imported) - return -EINVAL; -- return res->import_dma_buf->ops->begin_cpu_access(res->import_dma_buf, -- direction); -+ return buf->import.dma_buf->ops->begin_cpu_access(buf->import.dma_buf, -+ direction); - } - - static - int vc_sm_import_dma_buf_end_cpu_access(struct dma_buf *dmabuf, - enum dma_data_direction direction) - { -- struct vc_sm_buffer *res = dmabuf->priv; -+ struct vc_sm_buffer *buf = dmabuf->priv; - -- if (!res->import_dma_buf) -+ if (!buf->imported) - return -EINVAL; -- return res->import_dma_buf->ops->end_cpu_access(res->import_dma_buf, -+ return buf->import.dma_buf->ops->end_cpu_access(buf->import.dma_buf, - direction); - } - -@@ -516,9 +820,8 @@ vc_sm_cma_import_dmabuf_internal(struct - memcpy(import.name, VC_SM_RESOURCE_NAME_DEFAULT, - sizeof(VC_SM_RESOURCE_NAME_DEFAULT)); - -- pr_debug("[%s]: attempt to import \"%s\" data - type %u, addr %pad, size %u\n", -- __func__, import.name, import.type, &dma_addr, -- import.size); -+ pr_debug("[%s]: attempt to import \"%s\" data - type %u, addr %pad, size %u.\n", -+ __func__, import.name, import.type, &dma_addr, import.size); - - /* Allocate the videocore buffer. */ - status = vc_sm_cma_vchi_import(sm_state->sm_handle, &import, &result, -@@ -548,12 +851,14 @@ vc_sm_cma_import_dmabuf_internal(struct - buffer->size = import.size; - buffer->vpu_state = VPU_MAPPED; - -- buffer->import_dma_buf = dma_buf; -+ buffer->imported = 1; -+ buffer->import.dma_buf = dma_buf; - -- buffer->attach = attach; -- buffer->sgt = sgt; -+ buffer->import.attach = attach; -+ buffer->import.sgt = sgt; - buffer->dma_addr = dma_addr; - buffer->in_use = 1; -+ buffer->kernel_id = import.kernel_id; - - /* - * We're done - we need to export a new dmabuf chaining through most -@@ -594,6 +899,91 @@ error: - return ret; - } - -+static int vc_sm_cma_vpu_alloc(u32 size, uint32_t align, const char *name, -+ u32 mem_handle, struct vc_sm_buffer **ret_buffer) -+{ -+ DEFINE_DMA_BUF_EXPORT_INFO(exp_info); -+ struct vc_sm_buffer *buffer = NULL; -+ int aligned_size; -+ int ret = 0; -+ -+ /* Align to the user requested align */ -+ aligned_size = ALIGN(size, align); -+ /* and then to a page boundary */ -+ aligned_size = PAGE_ALIGN(aligned_size); -+ -+ if (!aligned_size) -+ return -EINVAL; -+ -+ /* Allocate local buffer to track this allocation. */ -+ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); -+ if (!buffer) -+ return -ENOMEM; -+ -+ mutex_init(&buffer->lock); -+ -+ if (vc_sm_cma_buffer_allocate(sm_state->cma_heap, &buffer->alloc, -+ aligned_size)) { -+ pr_err("[%s]: cma alloc of %d bytes failed\n", -+ __func__, aligned_size); -+ ret = -ENOMEM; -+ goto error; -+ } -+ buffer->sg_table = buffer->alloc.sg_table; -+ -+ pr_debug("[%s]: cma alloc of %d bytes success\n", -+ __func__, aligned_size); -+ -+ if (dma_map_sg(&sm_state->pdev->dev, buffer->sg_table->sgl, -+ buffer->sg_table->nents, DMA_BIDIRECTIONAL) <= 0) { -+ pr_err("[%s]: dma_map_sg failed\n", __func__); -+ goto error; -+ } -+ -+ INIT_LIST_HEAD(&buffer->attachments); -+ -+ memcpy(buffer->name, name, -+ min(sizeof(buffer->name), strlen(name))); -+ -+ exp_info.ops = &dma_buf_ops; -+ exp_info.size = aligned_size; -+ exp_info.flags = O_RDWR; -+ exp_info.priv = buffer; -+ -+ buffer->dma_buf = dma_buf_export(&exp_info); -+ if (IS_ERR(buffer->dma_buf)) { -+ ret = PTR_ERR(buffer->dma_buf); -+ goto error; -+ } -+ buffer->dma_addr = (uint32_t)sg_dma_address(buffer->sg_table->sgl); -+ if ((buffer->dma_addr & 0xC0000000) != 0xC0000000) { -+ pr_err("%s: Expecting an uncached alias for dma_addr %pad\n", -+ __func__, &buffer->dma_addr); -+ buffer->dma_addr |= 0xC0000000; -+ } -+ buffer->private = sm_state->vpu_allocs; -+ -+ buffer->vc_handle = mem_handle; -+ buffer->vpu_state = VPU_MAPPED; -+ buffer->vpu_allocated = 1; -+ buffer->size = size; -+ /* -+ * Create an ID that will be passed along with our message so -+ * that when we service the release reply, we can look up which -+ * resource is being released. -+ */ -+ buffer->kernel_id = get_kernel_id(buffer); -+ -+ vc_sm_add_resource(sm_state->vpu_allocs, buffer); -+ -+ *ret_buffer = buffer; -+ return 0; -+error: -+ if (buffer) -+ vc_sm_release_resource(buffer); -+ return ret; -+} -+ - static void - vc_sm_vpu_event(struct sm_instance *instance, struct vc_sm_result_t *reply, - int reply_len) -@@ -612,21 +1002,61 @@ vc_sm_vpu_event(struct sm_instance *inst - struct vc_sm_released *release = (struct vc_sm_released *)reply; - struct vc_sm_buffer *buffer = - lookup_kernel_id(release->kernel_id); -+ if (!buffer) { -+ pr_err("%s: VC released a buffer that is already released, kernel_id %d\n", -+ __func__, release->kernel_id); -+ break; -+ } -+ mutex_lock(&buffer->lock); - -- /* -- * FIXME: Need to check buffer is still valid and allocated -- * before continuing -- */ - pr_debug("%s: Released addr %08x, size %u, id %08x, mem_handle %08x\n", - __func__, release->addr, release->size, - release->kernel_id, release->vc_handle); -- mutex_lock(&buffer->lock); -+ - buffer->vc_handle = 0; - buffer->vpu_state = VPU_NOT_MAPPED; -- mutex_unlock(&buffer->lock); - free_kernel_id(release->kernel_id); - -- vc_sm_release_resource(buffer, 0); -+ if (buffer->vpu_allocated) { -+ /* VPU allocation, so release the dmabuf which will -+ * trigger the clean up. -+ */ -+ mutex_unlock(&buffer->lock); -+ dma_buf_put(buffer->dma_buf); -+ } else { -+ vc_sm_release_resource(buffer); -+ } -+ } -+ break; -+ case VC_SM_MSG_TYPE_VC_MEM_REQUEST: -+ { -+ struct vc_sm_buffer *buffer = NULL; -+ struct vc_sm_vc_mem_request *req = -+ (struct vc_sm_vc_mem_request *)reply; -+ struct vc_sm_vc_mem_request_result reply; -+ int ret; -+ -+ pr_debug("%s: Request %u bytes of memory, align %d name %s, trans_id %08x\n", -+ __func__, req->size, req->align, req->name, -+ req->trans_id); -+ ret = vc_sm_cma_vpu_alloc(req->size, req->align, req->name, -+ req->vc_handle, &buffer); -+ -+ reply.trans_id = req->trans_id; -+ if (!ret) { -+ reply.addr = buffer->dma_addr; -+ reply.kernel_id = buffer->kernel_id; -+ pr_debug("%s: Allocated resource buffer %p, addr %pad\n", -+ __func__, buffer, &buffer->dma_addr); -+ } else { -+ pr_err("%s: Allocation failed size %u, name %s, vc_handle %u\n", -+ __func__, req->size, req->name, req->vc_handle); -+ reply.addr = 0; -+ reply.kernel_id = 0; -+ } -+ vc_sm_vchi_client_vc_mem_req_reply(sm_state->sm_handle, &reply, -+ &sm_state->int_trans_id); -+ break; - } - break; - default: -@@ -645,6 +1075,14 @@ static void vc_sm_connected_init(void) - - pr_info("[%s]: start\n", __func__); - -+ if (vc_sm_cma_add_heaps(&sm_state->cma_heap) || -+ !sm_state->cma_heap) { -+ pr_err("[%s]: failed to initialise CMA heaps\n", -+ __func__); -+ ret = -EIO; -+ goto err_free_mem; -+ } -+ - /* - * Initialize and create a VCHI connection for the shared memory service - * running on videocore. -@@ -696,7 +1134,7 @@ static void vc_sm_connected_init(void) - goto err_remove_shared_memory; - } - -- version.version = 1; -+ version.version = 2; - ret = vc_sm_cma_vchi_client_version(sm_state->sm_handle, &version, - &version_result, - &sm_state->int_trans_id); -@@ -768,7 +1206,7 @@ static int bcm2835_vc_sm_cma_remove(stru - int vc_sm_cma_int_handle(void *handle) - { - struct dma_buf *dma_buf = (struct dma_buf *)handle; -- struct vc_sm_buffer *res; -+ struct vc_sm_buffer *buf; - - /* Validate we can work with this device. */ - if (!sm_state || !handle) { -@@ -776,8 +1214,8 @@ int vc_sm_cma_int_handle(void *handle) - return 0; - } - -- res = (struct vc_sm_buffer *)dma_buf->priv; -- return res->vc_handle; -+ buf = (struct vc_sm_buffer *)dma_buf->priv; -+ return buf->vc_handle; - } - EXPORT_SYMBOL_GPL(vc_sm_cma_int_handle); - -@@ -804,7 +1242,7 @@ EXPORT_SYMBOL_GPL(vc_sm_cma_free); - int vc_sm_cma_import_dmabuf(struct dma_buf *src_dmabuf, void **handle) - { - struct dma_buf *new_dma_buf; -- struct vc_sm_buffer *res; -+ struct vc_sm_buffer *buf; - int ret; - - /* Validate we can work with this device. */ -@@ -818,7 +1256,7 @@ int vc_sm_cma_import_dmabuf(struct dma_b - - if (!ret) { - pr_debug("%s: imported to ptr %p\n", __func__, new_dma_buf); -- res = (struct vc_sm_buffer *)new_dma_buf->priv; -+ buf = (struct vc_sm_buffer *)new_dma_buf->priv; - - /* Assign valid handle at this time.*/ - *handle = new_dma_buf; ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.h -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.h -@@ -21,6 +21,8 @@ - #include - #include - -+#include "vc_sm_cma.h" -+ - #define VC_SM_MAX_NAME_LEN 32 - - enum vc_sm_vpu_mapping_state { -@@ -29,31 +31,51 @@ enum vc_sm_vpu_mapping_state { - VPU_UNMAPPING - }; - -+struct vc_sm_imported { -+ struct dma_buf *dma_buf; -+ struct dma_buf_attachment *attach; -+ struct sg_table *sgt; -+}; -+ - struct vc_sm_buffer { - struct list_head global_buffer_list; /* Global list of buffers. */ - -+ /* Index in the kernel_id idr so that we can find the -+ * mmal_msg_context again when servicing the VCHI reply. -+ */ -+ int kernel_id; -+ - size_t size; - - /* Lock over all the following state for this buffer */ - struct mutex lock; -- struct sg_table *sg_table; - struct list_head attachments; - - char name[VC_SM_MAX_NAME_LEN]; - - int in_use:1; /* Kernel is still using this resource */ -+ int imported:1; /* Imported dmabuf */ -+ -+ struct sg_table *sg_table; - - enum vc_sm_vpu_mapping_state vpu_state; - u32 vc_handle; /* VideoCore handle for this buffer */ -+ int vpu_allocated; /* -+ * The VPU made this allocation. Release the -+ * local dma_buf when the VPU releases the -+ * resource. -+ */ - - /* DMABUF related fields */ -- struct dma_buf *import_dma_buf; - struct dma_buf *dma_buf; -- struct dma_buf_attachment *attach; -- struct sg_table *sgt; - dma_addr_t dma_addr; - - struct vc_sm_privdata_t *private; -+ -+ union { -+ struct vc_sm_cma_alloc_data alloc; -+ struct vc_sm_imported import; -+ }; - }; - - #endif ---- /dev/null -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.c -@@ -0,0 +1,99 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * VideoCore Shared Memory CMA allocator -+ * -+ * Copyright: 2018, Raspberry Pi (Trading) Ltd -+ * -+ * Based on the Android ION allocator -+ * Copyright (C) Linaro 2012 -+ * Author: for ST-Ericsson. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "vc_sm_cma.h" -+ -+/* CMA heap operations functions */ -+int vc_sm_cma_buffer_allocate(struct cma *cma_heap, -+ struct vc_sm_cma_alloc_data *buffer, -+ unsigned long len) -+{ -+ /* len should already be page aligned */ -+ unsigned long num_pages = len / PAGE_SIZE; -+ struct sg_table *table; -+ struct page *pages; -+ int ret; -+ -+ pages = cma_alloc(cma_heap, num_pages, 0, GFP_KERNEL); -+ if (!pages) -+ return -ENOMEM; -+ -+ table = kmalloc(sizeof(*table), GFP_KERNEL); -+ if (!table) -+ goto err; -+ -+ ret = sg_alloc_table(table, 1, GFP_KERNEL); -+ if (ret) -+ goto free_mem; -+ -+ sg_set_page(table->sgl, pages, len, 0); -+ -+ buffer->priv_virt = pages; -+ buffer->sg_table = table; -+ buffer->cma_heap = cma_heap; -+ buffer->num_pages = num_pages; -+ return 0; -+ -+free_mem: -+ kfree(table); -+err: -+ cma_release(cma_heap, pages, num_pages); -+ return -ENOMEM; -+} -+ -+void vc_sm_cma_buffer_free(struct vc_sm_cma_alloc_data *buffer) -+{ -+ struct cma *cma_heap = buffer->cma_heap; -+ struct page *pages = buffer->priv_virt; -+ -+ /* release memory */ -+ if (cma_heap) -+ cma_release(cma_heap, pages, buffer->num_pages); -+ -+ /* release sg table */ -+ if (buffer->sg_table) { -+ sg_free_table(buffer->sg_table); -+ kfree(buffer->sg_table); -+ buffer->sg_table = NULL; -+ } -+} -+ -+int __vc_sm_cma_add_heaps(struct cma *cma, void *priv) -+{ -+ struct cma **heap = (struct cma **)priv; -+ const char *name = cma_get_name(cma); -+ -+ if (!(*heap)) { -+ phys_addr_t phys_addr = cma_get_base(cma); -+ -+ pr_debug("%s: Adding cma heap %s (start %pap, size %lu) for use by vcsm\n", -+ __func__, name, &phys_addr, cma_get_size(cma)); -+ *heap = cma; -+ } else { -+ pr_err("%s: Ignoring heap %s as already set\n", -+ __func__, name); -+ } -+ -+ return 0; -+} -+ -+int vc_sm_cma_add_heaps(struct cma **cma_heap) -+{ -+ cma_for_each_area(__vc_sm_cma_add_heaps, cma_heap); -+ return 0; -+} ---- /dev/null -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.h -@@ -0,0 +1,39 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+ -+/* -+ * VideoCore Shared Memory CMA allocator -+ * -+ * Copyright: 2018, Raspberry Pi (Trading) Ltd -+ * -+ * Based on the Android ION allocator -+ * Copyright (C) Linaro 2012 -+ * Author: for ST-Ericsson. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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 VC_SM_CMA_H -+#define VC_SM_CMA_H -+ -+struct vc_sm_cma_alloc_data { -+ struct cma *cma_heap; -+ unsigned long num_pages; -+ void *priv_virt; -+ struct sg_table *sg_table; -+}; -+ -+int vc_sm_cma_buffer_allocate(struct cma *cma_heap, -+ struct vc_sm_cma_alloc_data *buffer, -+ unsigned long len); -+void vc_sm_cma_buffer_free(struct vc_sm_cma_alloc_data *buffer); -+ -+int vc_sm_cma_add_heaps(struct cma **cma_heap); -+ -+#endif ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c -@@ -500,3 +500,13 @@ int vc_sm_cma_vchi_client_version(struct - msg, sizeof(*msg), NULL, 0, - cur_trans_id, 0); - } -+ -+int vc_sm_vchi_client_vc_mem_req_reply(struct sm_instance *handle, -+ struct vc_sm_vc_mem_request_result *msg, -+ uint32_t *cur_trans_id) -+{ -+ return vc_sm_cma_vchi_send_msg(handle, -+ VC_SM_MSG_TYPE_VC_MEM_REQUEST_REPLY, -+ msg, sizeof(*msg), 0, 0, cur_trans_id, -+ 0); -+} ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.h -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.h -@@ -56,4 +56,8 @@ int vc_sm_cma_vchi_client_version(struct - struct vc_sm_result_t *result, - u32 *cur_trans_id); - -+int vc_sm_vchi_client_vc_mem_req_reply(struct sm_instance *handle, -+ struct vc_sm_vc_mem_request_result *msg, -+ uint32_t *cur_trans_id); -+ - #endif /* __VC_SM_CMA_VCHI_H__INCLUDED__ */ ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_defs.h -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_defs.h -@@ -264,6 +264,8 @@ struct vc_sm_vc_mem_request { - u32 align; - /* resource name (for easier tracking) */ - char name[VC_SM_RESOURCE_NAME]; -+ /* VPU handle for the resource */ -+ u32 vc_handle; - }; - - /* Response from the kernel to provide the VPU with some memory */ diff --git a/target/linux/brcm2708/patches-4.19/950-0630-staging-vcsm-cma-Alter-dev-node-permissions-to-0666.patch b/target/linux/brcm2708/patches-4.19/950-0630-staging-vcsm-cma-Alter-dev-node-permissions-to-0666.patch new file mode 100644 index 0000000000..bc73546040 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0630-staging-vcsm-cma-Alter-dev-node-permissions-to-0666.patch @@ -0,0 +1,24 @@ +From d21247010c8e885916908e641481d1d915d8a690 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 13 May 2019 16:47:54 +0100 +Subject: [PATCH 630/725] staging: vcsm-cma: Alter dev node permissions to 0666 + +Until the udev rules are updated, open up access to this node by +default. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -1572,6 +1572,8 @@ static void vc_sm_connected_init(void) + sm_state->misc_dev.name = DEVICE_NAME; + sm_state->misc_dev.fops = &vc_sm_ops; + sm_state->misc_dev.parent = NULL; ++ /* Temporarily set as 666 until udev rules have been sorted */ ++ sm_state->misc_dev.mode = 0666; + ret = misc_register(&sm_state->misc_dev); + if (ret) { + pr_err("vcsm-cma: failed to register misc device.\n"); diff --git a/target/linux/brcm2708/patches-4.19/950-0631-staging-vc-sm-cma-Update-TODO.patch b/target/linux/brcm2708/patches-4.19/950-0631-staging-vc-sm-cma-Update-TODO.patch deleted file mode 100644 index f5937b29cc..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0631-staging-vc-sm-cma-Update-TODO.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 2de0580b775aa8ff923d70ca84e8688b28dd2ced Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 11 Mar 2019 16:38:32 +0000 -Subject: [PATCH 631/703] staging: vc-sm-cma: Update TODO. - -The driver is already a platform driver, so that can be -deleted from the TODO. -There are no known issues that need to be resolved. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vc-sm-cma/TODO | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/vc-sm-cma/TODO -+++ b/drivers/staging/vc04_services/vc-sm-cma/TODO -@@ -1,2 +1 @@ --1) Convert to a platform driver. -- -+No currently outstanding tasks except some clean-up. diff --git a/target/linux/brcm2708/patches-4.19/950-0631-staging-vcsm-cma-Drop-logging-level-on-messages-in-v.patch b/target/linux/brcm2708/patches-4.19/950-0631-staging-vcsm-cma-Drop-logging-level-on-messages-in-v.patch new file mode 100644 index 0000000000..3b2fbc980b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0631-staging-vcsm-cma-Drop-logging-level-on-messages-in-v.patch @@ -0,0 +1,33 @@ +From e31bdb189cc74c8bcba855bd617f9a663d794fe4 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 16 May 2019 15:17:19 +0100 +Subject: [PATCH 631/725] staging: vcsm-cma: Drop logging level on messages in + vc_sm_release_resource + +They weren't errors but were logged as such. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -301,14 +301,13 @@ static void vc_sm_release_resource(struc + + if (buffer->vc_handle) { + /* We've sent the unmap request but not had the response. */ +- pr_err("[%s]: Waiting for VPU unmap response on %p\n", +- __func__, buffer); ++ pr_debug("[%s]: Waiting for VPU unmap response on %p\n", ++ __func__, buffer); + goto defer; + } + if (buffer->in_use) { + /* dmabuf still in use - we await the release */ +- pr_err("[%s]: buffer %p is still in use\n", +- __func__, buffer); ++ pr_debug("[%s]: buffer %p is still in use\n", __func__, buffer); + goto defer; + } + diff --git a/target/linux/brcm2708/patches-4.19/950-0632-staging-vc-sm-cma-Add-in-userspace-allocation-API.patch b/target/linux/brcm2708/patches-4.19/950-0632-staging-vc-sm-cma-Add-in-userspace-allocation-API.patch deleted file mode 100644 index 8125fe7b23..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0632-staging-vc-sm-cma-Add-in-userspace-allocation-API.patch +++ /dev/null @@ -1,675 +0,0 @@ -From 2cd18cda345cadbc702520602cbf41dee0774cc0 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 11 Mar 2019 16:35:23 +0000 -Subject: [PATCH 632/703] staging: vc-sm-cma: Add in userspace allocation API - -Replacing the functionality from the older vc-sm driver, -add in a userspace API that allows allocation of buffers, -and importing of dma-bufs. -The driver hands out dma-buf fds, therefore much of the -handling around lifespan and odd mmaps from the old driver -goes away. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/vc-sm-cma/vc_sm.c | 371 ++++++++++++++++-- - .../vc04_services/vc-sm-cma/vc_sm_cma.c | 3 +- - .../vc04_services/vc-sm-cma/vc_sm_cma.h | 2 +- - include/linux/broadcom/vc_sm_cma_ioctl.h | 87 ++++ - 4 files changed, 435 insertions(+), 28 deletions(-) - create mode 100644 include/linux/broadcom/vc_sm_cma_ioctl.h - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -52,6 +53,7 @@ - #include "vc_sm.h" - #include "vc_sm_cma.h" - #include "vc_sm_knl.h" -+#include - - /* ---- Private Constants and Types --------------------------------------- */ - -@@ -83,6 +85,8 @@ struct sm_pde_t { - struct sm_state_t { - struct platform_device *pdev; - -+ struct miscdevice misc_dev; -+ - struct sm_instance *sm_handle; /* Handle for videocore service. */ - struct cma *cma_heap; - -@@ -346,7 +350,6 @@ static void vc_sm_release_resource(struc - - defer: - mutex_unlock(&buffer->lock); -- return; - } - - /* Create support for private data tracking. */ -@@ -381,7 +384,7 @@ static struct sg_table *dup_sg_table(str - ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL); - if (ret) { - kfree(new_table); -- return ERR_PTR(-ENOMEM); -+ return ERR_PTR(ret); - } - - new_sg = new_table->sgl; -@@ -417,7 +420,7 @@ static int vc_sm_dma_buf_attach(struct d - table = dup_sg_table(buf->sg_table); - if (IS_ERR(table)) { - kfree(a); -- return -ENOMEM; -+ return PTR_ERR(table); - } - - a->table = table; -@@ -433,8 +436,8 @@ static int vc_sm_dma_buf_attach(struct d - return 0; - } - --static void vc_sm_dma_buf_detatch(struct dma_buf *dmabuf, -- struct dma_buf_attachment *attachment) -+static void vc_sm_dma_buf_detach(struct dma_buf *dmabuf, -+ struct dma_buf_attachment *attachment) - { - struct vc_sm_dma_buf_attachment *a = attachment->priv; - struct vc_sm_buffer *buf = dmabuf->priv; -@@ -544,6 +547,9 @@ static void vc_sm_dma_buf_release(struct - vc_sm_clean_up_dmabuf(buffer); - pr_debug("%s clean_up dmabuf done\n", __func__); - -+ /* buffer->lock will be destroyed by vc_sm_release_resource if finished -+ * with, otherwise unlocked. Do NOT unlock here. -+ */ - vc_sm_release_resource(buffer); - pr_debug("%s done\n", __func__); - } -@@ -613,7 +619,7 @@ static const struct dma_buf_ops dma_buf_ - .mmap = vc_sm_dmabuf_mmap, - .release = vc_sm_dma_buf_release, - .attach = vc_sm_dma_buf_attach, -- .detach = vc_sm_dma_buf_detatch, -+ .detach = vc_sm_dma_buf_detach, - .begin_cpu_access = vc_sm_dma_buf_begin_cpu_access, - .end_cpu_access = vc_sm_dma_buf_end_cpu_access, - .map = vc_sm_dma_buf_kmap, -@@ -762,6 +768,7 @@ static const struct dma_buf_ops dma_buf_ - int - vc_sm_cma_import_dmabuf_internal(struct vc_sm_privdata_t *private, - struct dma_buf *dma_buf, -+ int fd, - struct dma_buf **imported_buf) - { - DEFINE_DMA_BUF_EXPORT_INFO(exp_info); -@@ -775,10 +782,15 @@ vc_sm_cma_import_dmabuf_internal(struct - int status; - - /* Setup our allocation parameters */ -- pr_debug("%s: importing dma_buf %p\n", __func__, dma_buf); -+ pr_debug("%s: importing dma_buf %p/fd %d\n", __func__, dma_buf, fd); - -- get_dma_buf(dma_buf); -- dma_buf = dma_buf; -+ if (fd < 0) -+ get_dma_buf(dma_buf); -+ else -+ dma_buf = dma_buf_get(fd); -+ -+ if (!dma_buf) -+ return -EINVAL; - - attach = dma_buf_attach(dma_buf, &sm_state->pdev->dev); - if (IS_ERR(attach)) { -@@ -921,6 +933,10 @@ static int vc_sm_cma_vpu_alloc(u32 size, - return -ENOMEM; - - mutex_init(&buffer->lock); -+ /* Acquire the mutex as vc_sm_release_resource will release it in the -+ * error path. -+ */ -+ mutex_lock(&buffer->lock); - - if (vc_sm_cma_buffer_allocate(sm_state->cma_heap, &buffer->alloc, - aligned_size)) { -@@ -976,6 +992,8 @@ static int vc_sm_cma_vpu_alloc(u32 size, - - vc_sm_add_resource(sm_state->vpu_allocs, buffer); - -+ mutex_unlock(&buffer->lock); -+ - *ret_buffer = buffer; - return 0; - error: -@@ -1065,6 +1083,297 @@ vc_sm_vpu_event(struct sm_instance *inst - } - } - -+/* Userspace handling */ -+/* -+ * Open the device. Creates a private state to help track all allocation -+ * associated with this device. -+ */ -+static int vc_sm_cma_open(struct inode *inode, struct file *file) -+{ -+ /* Make sure the device was started properly. */ -+ if (!sm_state) { -+ pr_err("[%s]: invalid device\n", __func__); -+ return -EPERM; -+ } -+ -+ file->private_data = vc_sm_cma_create_priv_data(current->tgid); -+ if (!file->private_data) { -+ pr_err("[%s]: failed to create data tracker\n", __func__); -+ -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+/* -+ * Close the vcsm-cma device. -+ * All allocations are file descriptors to the dmabuf objects, so we will get -+ * the clean up request on those as those are cleaned up. -+ */ -+static int vc_sm_cma_release(struct inode *inode, struct file *file) -+{ -+ struct vc_sm_privdata_t *file_data = -+ (struct vc_sm_privdata_t *)file->private_data; -+ int ret = 0; -+ -+ /* Make sure the device was started properly. */ -+ if (!sm_state || !file_data) { -+ pr_err("[%s]: invalid device\n", __func__); -+ ret = -EPERM; -+ goto out; -+ } -+ -+ pr_debug("[%s]: using private data %p\n", __func__, file_data); -+ -+ /* Terminate the private data. */ -+ kfree(file_data); -+ -+out: -+ return ret; -+} -+ -+/* -+ * Allocate a shared memory handle and block. -+ * Allocation is from CMA, and then imported into the VPU mappings. -+ */ -+int vc_sm_cma_ioctl_alloc(struct vc_sm_privdata_t *private, -+ struct vc_sm_cma_ioctl_alloc *ioparam) -+{ -+ DEFINE_DMA_BUF_EXPORT_INFO(exp_info); -+ struct vc_sm_buffer *buffer = NULL; -+ struct vc_sm_import import = { 0 }; -+ struct vc_sm_import_result result = { 0 }; -+ struct dma_buf *dmabuf = NULL; -+ int aligned_size; -+ int ret = 0; -+ int status; -+ int fd = -1; -+ -+ aligned_size = PAGE_ALIGN(ioparam->size); -+ -+ if (!aligned_size) -+ return -EINVAL; -+ -+ /* Allocate local buffer to track this allocation. */ -+ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); -+ if (!buffer) { -+ ret = -ENOMEM; -+ goto error; -+ } -+ -+ if (vc_sm_cma_buffer_allocate(sm_state->cma_heap, &buffer->alloc, -+ aligned_size)) { -+ pr_err("[%s]: cma alloc of %d bytes failed\n", -+ __func__, aligned_size); -+ kfree(buffer); -+ return -ENOMEM; -+ } -+ buffer->sg_table = buffer->alloc.sg_table; -+ -+ if (dma_map_sg(&sm_state->pdev->dev, buffer->sg_table->sgl, -+ buffer->sg_table->nents, DMA_BIDIRECTIONAL) <= 0) { -+ pr_err("[%s]: dma_map_sg failed\n", __func__); -+ ret = -ENOMEM; -+ goto error; -+ } -+ -+ import.type = VC_SM_ALLOC_NON_CACHED; -+ import.allocator = current->tgid; -+ -+ if (*ioparam->name) -+ memcpy(import.name, ioparam->name, sizeof(import.name) - 1); -+ else -+ memcpy(import.name, VC_SM_RESOURCE_NAME_DEFAULT, -+ sizeof(VC_SM_RESOURCE_NAME_DEFAULT)); -+ -+ mutex_init(&buffer->lock); -+ INIT_LIST_HEAD(&buffer->attachments); -+ memcpy(buffer->name, import.name, -+ min(sizeof(buffer->name), sizeof(import.name) - 1)); -+ -+ exp_info.ops = &dma_buf_ops; -+ exp_info.size = aligned_size; -+ exp_info.flags = O_RDWR; -+ exp_info.priv = buffer; -+ -+ dmabuf = dma_buf_export(&exp_info); -+ if (IS_ERR(dmabuf)) { -+ ret = PTR_ERR(dmabuf); -+ goto error; -+ } -+ buffer->dma_buf = dmabuf; -+ -+ import.addr = (uint32_t)sg_dma_address(buffer->sg_table->sgl); -+ import.size = aligned_size; -+ import.kernel_id = (uint32_t)buffer; -+ -+ /* Wrap it into a videocore buffer. */ -+ status = vc_sm_cma_vchi_import(sm_state->sm_handle, &import, &result, -+ &sm_state->int_trans_id); -+ if (status == -EINTR) { -+ pr_debug("[%s]: requesting import memory action restart (trans_id: %u)\n", -+ __func__, sm_state->int_trans_id); -+ ret = -ERESTARTSYS; -+ private->restart_sys = -EINTR; -+ private->int_action = VC_SM_MSG_TYPE_IMPORT; -+ goto error; -+ } else if (status || !result.res_handle) { -+ pr_err("[%s]: failed to import memory on videocore (status: %u, trans_id: %u)\n", -+ __func__, status, sm_state->int_trans_id); -+ ret = -ENOMEM; -+ goto error; -+ } -+ -+ /* Keep track of the buffer we created. */ -+ buffer->private = private; -+ buffer->vc_handle = result.res_handle; -+ buffer->size = import.size; -+ buffer->dma_addr = import.addr; -+ buffer->vpu_state = VPU_MAPPED; -+ //buffer->res_cached = ioparam->cached; -+ -+ fd = dma_buf_fd(dmabuf, O_CLOEXEC); -+ if (fd < 0) -+ goto error; -+ -+ vc_sm_add_resource(private, buffer); -+ -+ pr_debug("[%s]: Added resource as fd %d, buffer %p, private %p, dma_addr %pad\n", -+ __func__, fd, buffer, private, &buffer->dma_addr); -+ -+ /* We're done */ -+ ioparam->handle = fd; -+ ioparam->vc_handle = buffer->vc_handle; -+ ioparam->dma_addr = buffer->dma_addr; -+ return 0; -+ -+error: -+ if (buffer) { -+ pr_err("[%s]: something failed - cleanup. ret %d\n", __func__, -+ ret); -+ -+ dma_buf_put(dmabuf); -+ } -+ return ret; -+} -+ -+static long vc_sm_cma_ioctl(struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ int ret = 0; -+ unsigned int cmdnr = _IOC_NR(cmd); -+ struct vc_sm_privdata_t *file_data = -+ (struct vc_sm_privdata_t *)file->private_data; -+ -+ /* Validate we can work with this device. */ -+ if (!sm_state || !file_data) { -+ pr_err("[%s]: invalid device\n", __func__); -+ return -EPERM; -+ } -+ -+ pr_debug("[%s]: cmd %x tgid %u, owner %u\n", __func__, cmdnr, -+ current->tgid, file_data->pid); -+ -+ /* Action is a re-post of a previously interrupted action? */ -+ if (file_data->restart_sys == -EINTR) { -+ struct vc_sm_action_clean_t action_clean; -+ -+ pr_debug("[%s]: clean up of action %u (trans_id: %u) following EINTR\n", -+ __func__, file_data->int_action, -+ file_data->int_trans_id); -+ -+ action_clean.res_action = file_data->int_action; -+ action_clean.action_trans_id = file_data->int_trans_id; -+ -+ file_data->restart_sys = 0; -+ } -+ -+ /* Now process the command. */ -+ switch (cmdnr) { -+ /* New memory allocation. -+ */ -+ case VC_SM_CMA_CMD_ALLOC: -+ { -+ struct vc_sm_cma_ioctl_alloc ioparam; -+ -+ /* Get the parameter data. */ -+ if (copy_from_user -+ (&ioparam, (void *)arg, sizeof(ioparam)) != 0) { -+ pr_err("[%s]: failed to copy-from-user for cmd %x\n", -+ __func__, cmdnr); -+ ret = -EFAULT; -+ break; -+ } -+ -+ ret = vc_sm_cma_ioctl_alloc(file_data, &ioparam); -+ if (!ret && -+ (copy_to_user((void *)arg, &ioparam, -+ sizeof(ioparam)) != 0)) { -+ /* FIXME: Release allocation */ -+ pr_err("[%s]: failed to copy-to-user for cmd %x\n", -+ __func__, cmdnr); -+ ret = -EFAULT; -+ } -+ break; -+ } -+ -+ case VC_SM_CMA_CMD_IMPORT_DMABUF: -+ { -+ struct vc_sm_cma_ioctl_import_dmabuf ioparam; -+ struct dma_buf *new_dmabuf; -+ -+ /* Get the parameter data. */ -+ if (copy_from_user -+ (&ioparam, (void *)arg, sizeof(ioparam)) != 0) { -+ pr_err("[%s]: failed to copy-from-user for cmd %x\n", -+ __func__, cmdnr); -+ ret = -EFAULT; -+ break; -+ } -+ -+ ret = vc_sm_cma_import_dmabuf_internal(file_data, -+ NULL, -+ ioparam.dmabuf_fd, -+ &new_dmabuf); -+ -+ if (!ret) { -+ struct vc_sm_buffer *buf = new_dmabuf->priv; -+ -+ ioparam.size = buf->size; -+ ioparam.handle = dma_buf_fd(new_dmabuf, -+ O_CLOEXEC); -+ ioparam.vc_handle = buf->vc_handle; -+ ioparam.dma_addr = buf->dma_addr; -+ -+ if (ioparam.handle < 0 || -+ (copy_to_user((void *)arg, &ioparam, -+ sizeof(ioparam)) != 0)) { -+ dma_buf_put(new_dmabuf); -+ /* FIXME: Release allocation */ -+ ret = -EFAULT; -+ } -+ } -+ break; -+ } -+ -+ default: -+ ret = -EINVAL; -+ break; -+ } -+ -+ return ret; -+} -+ -+/* Device operations that we managed in this driver. */ -+static const struct file_operations vc_sm_ops = { -+ .owner = THIS_MODULE, -+ .unlocked_ioctl = vc_sm_cma_ioctl, -+ .open = vc_sm_cma_open, -+ .release = vc_sm_cma_release, -+}; -+ -+/* Driver load/unload functions */ - /* Videocore connected. */ - static void vc_sm_connected_init(void) - { -@@ -1075,12 +1384,11 @@ static void vc_sm_connected_init(void) - - pr_info("[%s]: start\n", __func__); - -- if (vc_sm_cma_add_heaps(&sm_state->cma_heap) || -- !sm_state->cma_heap) { -- pr_err("[%s]: failed to initialise CMA heaps\n", -+ vc_sm_cma_add_heaps(&sm_state->cma_heap); -+ if (!sm_state->cma_heap) { -+ pr_err("[%s]: failed to initialise CMA heap\n", - __func__); -- ret = -EIO; -- goto err_free_mem; -+ return; - } - - /* -@@ -1092,8 +1400,7 @@ static void vc_sm_connected_init(void) - pr_err("[%s]: failed to initialise VCHI instance (ret=%d)\n", - __func__, ret); - -- ret = -EIO; -- goto err_failed; -+ return; - } - - ret = vchi_connect(NULL, 0, vchi_instance); -@@ -1101,8 +1408,7 @@ static void vc_sm_connected_init(void) - pr_err("[%s]: failed to connect VCHI instance (ret=%d)\n", - __func__, ret); - -- ret = -EIO; -- goto err_failed; -+ return; - } - - /* Initialize an instance of the shared memory service. */ -@@ -1112,8 +1418,7 @@ static void vc_sm_connected_init(void) - pr_err("[%s]: failed to initialize shared memory service\n", - __func__); - -- ret = -EPERM; -- goto err_failed; -+ return; - } - - /* Create a debug fs directory entry (root). */ -@@ -1127,11 +1432,22 @@ static void vc_sm_connected_init(void) - - INIT_LIST_HEAD(&sm_state->buffer_list); - -+ /* Create a shared memory device. */ -+ sm_state->misc_dev.minor = MISC_DYNAMIC_MINOR; -+ sm_state->misc_dev.name = DEVICE_NAME; -+ sm_state->misc_dev.fops = &vc_sm_ops; -+ sm_state->misc_dev.parent = NULL; -+ ret = misc_register(&sm_state->misc_dev); -+ if (ret) { -+ pr_err("vcsm-cma: failed to register misc device.\n"); -+ goto err_remove_debugfs; -+ } -+ - sm_state->data_knl = vc_sm_cma_create_priv_data(0); - if (!sm_state->data_knl) { - pr_err("[%s]: failed to create kernel private data tracker\n", - __func__); -- goto err_remove_shared_memory; -+ goto err_remove_misc_dev; - } - - version.version = 2; -@@ -1148,11 +1464,13 @@ static void vc_sm_connected_init(void) - pr_info("[%s]: installed successfully\n", __func__); - return; - --err_remove_shared_memory: -+err_remove_misc_dev: -+ misc_deregister(&sm_state->misc_dev); -+err_remove_debugfs: - debugfs_remove_recursive(sm_state->dir_root); - vc_sm_cma_vchi_stop(&sm_state->sm_handle); --err_failed: -- pr_info("[%s]: failed, ret %d\n", __func__, ret); -+ -+ return; - } - - /* Driver loading. */ -@@ -1184,6 +1502,8 @@ static int bcm2835_vc_sm_cma_remove(stru - { - pr_debug("[%s]: start\n", __func__); - if (sm_inited) { -+ misc_deregister(&sm_state->misc_dev); -+ - /* Remove all proc entries. */ - debugfs_remove_recursive(sm_state->dir_root); - -@@ -1202,6 +1522,7 @@ static int bcm2835_vc_sm_cma_remove(stru - return 0; - } - -+/* Kernel API calls */ - /* Get an internal resource handle mapped from the external one. */ - int vc_sm_cma_int_handle(void *handle) - { -@@ -1252,7 +1573,7 @@ int vc_sm_cma_import_dmabuf(struct dma_b - } - - ret = vc_sm_cma_import_dmabuf_internal(sm_state->data_knl, src_dmabuf, -- &new_dma_buf); -+ -1, &new_dma_buf); - - if (!ret) { - pr_debug("%s: imported to ptr %p\n", __func__, new_dma_buf); ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.c -@@ -92,8 +92,7 @@ int __vc_sm_cma_add_heaps(struct cma *cm - return 0; - } - --int vc_sm_cma_add_heaps(struct cma **cma_heap) -+void vc_sm_cma_add_heaps(struct cma **cma_heap) - { - cma_for_each_area(__vc_sm_cma_add_heaps, cma_heap); -- return 0; - } ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.h -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.h -@@ -34,6 +34,6 @@ int vc_sm_cma_buffer_allocate(struct cma - unsigned long len); - void vc_sm_cma_buffer_free(struct vc_sm_cma_alloc_data *buffer); - --int vc_sm_cma_add_heaps(struct cma **cma_heap); -+void vc_sm_cma_add_heaps(struct cma **cma_heap); - - #endif ---- /dev/null -+++ b/include/linux/broadcom/vc_sm_cma_ioctl.h -@@ -0,0 +1,87 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+ -+/* -+ * Copyright 2019 Raspberry Pi (Trading) Ltd. All rights reserved. -+ * -+ * Based on vmcs_sm_ioctl.h Copyright Broadcom Corporation. -+ */ -+ -+#ifndef __VC_SM_CMA_IOCTL_H -+#define __VC_SM_CMA_IOCTL_H -+ -+/* ---- Include Files ---------------------------------------------------- */ -+ -+#if defined(__KERNEL__) -+#include /* Needed for standard types */ -+#else -+#include -+#endif -+ -+#include -+ -+/* ---- Constants and Types ---------------------------------------------- */ -+ -+#define VC_SM_CMA_RESOURCE_NAME 32 -+#define VC_SM_CMA_RESOURCE_NAME_DEFAULT "sm-host-resource" -+ -+/* Type define used to create unique IOCTL number */ -+#define VC_SM_CMA_MAGIC_TYPE 'J' -+ -+/* IOCTL commands on /dev/vc-sm-cma */ -+enum vc_sm_cma_cmd_e { -+ VC_SM_CMA_CMD_ALLOC = 0x5A, /* Start at 0x5A arbitrarily */ -+ -+ VC_SM_CMA_CMD_IMPORT_DMABUF, -+ -+ VC_SM_CMA_CMD_LAST /* Do not delete */ -+}; -+ -+/* Cache type supported, conveniently matches the user space definition in -+ * user-vcsm.h. -+ */ -+enum vc_sm_cma_cache_e { -+ VC_SM_CMA_CACHE_NONE, -+ VC_SM_CMA_CACHE_HOST, -+ VC_SM_CMA_CACHE_VC, -+ VC_SM_CMA_CACHE_BOTH, -+}; -+ -+/* IOCTL Data structures */ -+struct vc_sm_cma_ioctl_alloc { -+ /* user -> kernel */ -+ __u32 size; -+ __u32 num; -+ __u32 cached; /* enum vc_sm_cma_cache_e */ -+ __u32 pad; -+ __u8 name[VC_SM_CMA_RESOURCE_NAME]; -+ -+ /* kernel -> user */ -+ __s32 handle; -+ __u32 vc_handle; -+ __u64 dma_addr; -+}; -+ -+struct vc_sm_cma_ioctl_import_dmabuf { -+ /* user -> kernel */ -+ __s32 dmabuf_fd; -+ __u32 cached; /* enum vc_sm_cma_cache_e */ -+ __u8 name[VC_SM_CMA_RESOURCE_NAME]; -+ -+ /* kernel -> user */ -+ __s32 handle; -+ __u32 vc_handle; -+ __u32 size; -+ __u32 pad; -+ __u64 dma_addr; -+}; -+ -+/* IOCTL numbers */ -+#define VC_SM_CMA_IOCTL_MEM_ALLOC\ -+ _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_ALLOC,\ -+ struct vc_sm_cma_ioctl_alloc) -+ -+#define VC_SM_CMA_IOCTL_MEM_IMPORT_DMABUF\ -+ _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_IMPORT_DMABUF,\ -+ struct vc_sm_cma_ioctl_import_dmabuf) -+ -+#endif /* __VC_SM_CMA_IOCTL_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0632-staging-vcsm-cma-Fixup-the-alloc-code-handling-of-ke.patch b/target/linux/brcm2708/patches-4.19/950-0632-staging-vcsm-cma-Fixup-the-alloc-code-handling-of-ke.patch new file mode 100644 index 0000000000..9c87d7a692 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0632-staging-vcsm-cma-Fixup-the-alloc-code-handling-of-ke.patch @@ -0,0 +1,35 @@ +From 69e50a6fc060432f4d7802d116a4086e3a0df600 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 22 May 2019 15:40:37 +0100 +Subject: [PATCH 632/725] staging: vcsm-cma: Fixup the alloc code handling of + kernel_id + +The allocation code had been copied in from an old branch prior +to having added the IDR for 64bit support. It was therefore pushing +a pointer into the kernel_id field instead of an IDR handle, the +lookup therefore failed, and we never released the buffer. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -1206,7 +1206,7 @@ int vc_sm_cma_ioctl_alloc(struct vc_sm_p + + import.addr = (uint32_t)sg_dma_address(buffer->sg_table->sgl); + import.size = aligned_size; +- import.kernel_id = (uint32_t)buffer; ++ import.kernel_id = get_kernel_id(buffer); + + /* Wrap it into a videocore buffer. */ + status = vc_sm_cma_vchi_import(sm_state->sm_handle, &import, &result, +@@ -1231,6 +1231,7 @@ int vc_sm_cma_ioctl_alloc(struct vc_sm_p + buffer->size = import.size; + buffer->dma_addr = import.addr; + buffer->vpu_state = VPU_MAPPED; ++ buffer->kernel_id = import.kernel_id; + //buffer->res_cached = ioparam->cached; + + fd = dma_buf_fd(dmabuf, O_CLOEXEC); diff --git a/target/linux/brcm2708/patches-4.19/950-0633-Pulled-in-the-multi-frame-buffer-support-from-the-Pi.patch b/target/linux/brcm2708/patches-4.19/950-0633-Pulled-in-the-multi-frame-buffer-support-from-the-Pi.patch new file mode 100644 index 0000000000..b11eaf9dbf --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0633-Pulled-in-the-multi-frame-buffer-support-from-the-Pi.patch @@ -0,0 +1,925 @@ +From bc982ce2b2d37e03cb023a66b932301bcb6b3e78 Mon Sep 17 00:00:00 2001 +From: James Hughes +Date: Thu, 14 Mar 2019 13:27:54 +0000 +Subject: [PATCH 633/725] Pulled in the multi frame buffer support from the Pi3 + repo + +--- + drivers/video/fbdev/bcm2708_fb.c | 580 +++++++++++++++------ + include/soc/bcm2835/raspberrypi-firmware.h | 4 + + 2 files changed, 432 insertions(+), 152 deletions(-) + +--- a/drivers/video/fbdev/bcm2708_fb.c ++++ b/drivers/video/fbdev/bcm2708_fb.c +@@ -2,6 +2,7 @@ + * linux/drivers/video/bcm2708_fb.c + * + * Copyright (C) 2010 Broadcom ++ * Copyright (C) 2018 Raspberry Pi (Trading) Ltd + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive +@@ -13,6 +14,7 @@ + * Copyright 1999-2001 Jeff Garzik + * + */ ++ + #include + #include + #include +@@ -36,6 +38,7 @@ + #include + #include + #include ++#include + + //#define BCM2708_FB_DEBUG + #define MODULE_NAME "bcm2708_fb" +@@ -82,62 +85,139 @@ struct bcm2708_fb_stats { + u32 dma_irqs; + }; + ++struct vc4_display_settings_t { ++ u32 display_num; ++ u32 width; ++ u32 height; ++ u32 pitch; ++ u32 depth; ++ u32 virtual_width; ++ u32 virtual_height; ++ u32 virtual_width_offset; ++ u32 virtual_height_offset; ++ unsigned long fb_bus_address; ++}; ++ ++struct bcm2708_fb_dev; ++ + struct bcm2708_fb { + struct fb_info fb; + struct platform_device *dev; +- struct rpi_firmware *fw; + u32 cmap[16]; + u32 gpu_cmap[256]; ++ struct dentry *debugfs_dir; ++ struct dentry *debugfs_subdir; ++ unsigned long fb_bus_address; ++ struct { u32 base, length; } gpu; ++ struct vc4_display_settings_t display_settings; ++ struct debugfs_regset32 screeninfo_regset; ++ struct bcm2708_fb_dev *fbdev; ++ unsigned int image_size; ++ dma_addr_t dma_addr; ++ void *cpuaddr; ++}; ++ ++#define MAX_FRAMEBUFFERS 3 ++ ++struct bcm2708_fb_dev { ++ int firmware_supports_multifb; ++ /* Protects the DMA system from multiple FB access */ ++ struct mutex dma_mutex; + int dma_chan; + int dma_irq; + void __iomem *dma_chan_base; +- void *cb_base; /* DMA control blocks */ +- dma_addr_t cb_handle; +- struct dentry *debugfs_dir; + wait_queue_head_t dma_waitq; +- struct bcm2708_fb_stats stats; +- unsigned long fb_bus_address; +- struct { u32 base, length; } gpu; ++ bool disable_arm_alloc; ++ struct bcm2708_fb_stats dma_stats; ++ void *cb_base; /* DMA control blocks */ ++ dma_addr_t cb_handle; ++ int instance_count; ++ int num_displays; ++ struct rpi_firmware *fw; ++ struct bcm2708_fb displays[MAX_FRAMEBUFFERS]; + }; + + #define to_bcm2708(info) container_of(info, struct bcm2708_fb, fb) + + static void bcm2708_fb_debugfs_deinit(struct bcm2708_fb *fb) + { +- debugfs_remove_recursive(fb->debugfs_dir); +- fb->debugfs_dir = NULL; ++ debugfs_remove_recursive(fb->debugfs_subdir); ++ fb->debugfs_subdir = NULL; ++ ++ fb->fbdev->instance_count--; ++ ++ if (!fb->fbdev->instance_count) { ++ debugfs_remove_recursive(fb->debugfs_dir); ++ fb->debugfs_dir = NULL; ++ } + } + + static int bcm2708_fb_debugfs_init(struct bcm2708_fb *fb) + { ++ char buf[3]; ++ struct bcm2708_fb_dev *fbdev = fb->fbdev; ++ + static struct debugfs_reg32 stats_registers[] = { +- { +- "dma_copies", +- offsetof(struct bcm2708_fb_stats, dma_copies) +- }, +- { +- "dma_irqs", +- offsetof(struct bcm2708_fb_stats, dma_irqs) +- }, ++ {"dma_copies", offsetof(struct bcm2708_fb_stats, dma_copies)}, ++ {"dma_irqs", offsetof(struct bcm2708_fb_stats, dma_irqs)}, + }; + +- fb->debugfs_dir = debugfs_create_dir(DRIVER_NAME, NULL); ++ static struct debugfs_reg32 screeninfo[] = { ++ {"width", offsetof(struct fb_var_screeninfo, xres)}, ++ {"height", offsetof(struct fb_var_screeninfo, yres)}, ++ {"bpp", offsetof(struct fb_var_screeninfo, bits_per_pixel)}, ++ {"xres_virtual", offsetof(struct fb_var_screeninfo, xres_virtual)}, ++ {"yres_virtual", offsetof(struct fb_var_screeninfo, yres_virtual)}, ++ {"xoffset", offsetof(struct fb_var_screeninfo, xoffset)}, ++ {"yoffset", offsetof(struct fb_var_screeninfo, yoffset)}, ++ }; ++ ++ fb->debugfs_dir = debugfs_lookup(DRIVER_NAME, NULL); ++ ++ if (!fb->debugfs_dir) ++ fb->debugfs_dir = debugfs_create_dir(DRIVER_NAME, NULL); ++ + if (!fb->debugfs_dir) { +- pr_warn("%s: could not create debugfs entry\n", +- __func__); ++ dev_warn(fb->fb.dev, "%s: could not create debugfs folder\n", ++ __func__); ++ return -EFAULT; ++ } ++ ++ snprintf(buf, sizeof(buf), "%u", fb->display_settings.display_num); ++ ++ fb->debugfs_subdir = debugfs_create_dir(buf, fb->debugfs_dir); ++ ++ if (!fb->debugfs_subdir) { ++ dev_warn(fb->fb.dev, "%s: could not create debugfs entry %u\n", ++ __func__, fb->display_settings.display_num); + return -EFAULT; + } + +- fb->stats.regset.regs = stats_registers; +- fb->stats.regset.nregs = ARRAY_SIZE(stats_registers); +- fb->stats.regset.base = &fb->stats; +- +- if (!debugfs_create_regset32("stats", 0444, fb->debugfs_dir, +- &fb->stats.regset)) { +- pr_warn("%s: could not create statistics registers\n", +- __func__); ++ fbdev->dma_stats.regset.regs = stats_registers; ++ fbdev->dma_stats.regset.nregs = ARRAY_SIZE(stats_registers); ++ fbdev->dma_stats.regset.base = &fbdev->dma_stats; ++ ++ if (!debugfs_create_regset32("dma_stats", 0444, fb->debugfs_subdir, ++ &fbdev->dma_stats.regset)) { ++ dev_warn(fb->fb.dev, "%s: could not create statistics registers\n", ++ __func__); ++ goto fail; ++ } ++ ++ fb->screeninfo_regset.regs = screeninfo; ++ fb->screeninfo_regset.nregs = ARRAY_SIZE(screeninfo); ++ fb->screeninfo_regset.base = &fb->fb.var; ++ ++ if (!debugfs_create_regset32("screeninfo", 0444, fb->debugfs_subdir, ++ &fb->screeninfo_regset)) { ++ dev_warn(fb->fb.dev, ++ "%s: could not create dimensions registers\n", ++ __func__); + goto fail; + } ++ ++ fbdev->instance_count++; ++ + return 0; + + fail: +@@ -145,6 +225,20 @@ fail: + return -EFAULT; + } + ++static void set_display_num(struct bcm2708_fb *fb) ++{ ++ if (fb && fb->fbdev && fb->fbdev->firmware_supports_multifb) { ++ u32 tmp = fb->display_settings.display_num; ++ ++ if (rpi_firmware_property(fb->fbdev->fw, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM, ++ &tmp, ++ sizeof(tmp))) ++ dev_warn_once(fb->fb.dev, ++ "Set display number call failed. Old GPU firmware?"); ++ } ++} ++ + static int bcm2708_fb_set_bitfields(struct fb_var_screeninfo *var) + { + int ret = 0; +@@ -222,11 +316,11 @@ static int bcm2708_fb_check_var(struct f + struct fb_info *info) + { + /* info input, var output */ +- print_debug("%s(%p) %dx%d (%dx%d), %d, %d\n", ++ print_debug("%s(%p) %ux%u (%ux%u), %ul, %u\n", + __func__, info, info->var.xres, info->var.yres, + info->var.xres_virtual, info->var.yres_virtual, +- (int)info->screen_size, info->var.bits_per_pixel); +- print_debug("%s(%p) %dx%d (%dx%d), %d\n", __func__, var, var->xres, ++ info->screen_size, info->var.bits_per_pixel); ++ print_debug("%s(%p) %ux%u (%ux%u), %u\n", __func__, var, var->xres, + var->yres, var->xres_virtual, var->yres_virtual, + var->bits_per_pixel); + +@@ -283,23 +377,96 @@ static int bcm2708_fb_set_par(struct fb_ + .xoffset = info->var.xoffset, + .yoffset = info->var.yoffset, + .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 }, +- .base = 0, +- .screen_size = 0, +- .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH, 4, 0 }, +- .pitch = 0, ++ /* base and screen_size will be initialised later */ ++ .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH, 4, 0 }, ++ /* pitch will be initialised later */ + }; +- int ret; ++ int ret, image_size; ++ + +- print_debug("%s(%p) %dx%d (%dx%d), %d, %d\n", __func__, info, ++ print_debug("%s(%p) %dx%d (%dx%d), %d, %d (display %d)\n", __func__, ++ info, + info->var.xres, info->var.yres, info->var.xres_virtual, + info->var.yres_virtual, (int)info->screen_size, +- info->var.bits_per_pixel); ++ info->var.bits_per_pixel, value); ++ ++ /* Need to set the display number to act on first ++ * Cannot do it in the tag list because on older firmware the call ++ * will fail and stop the rest of the list being executed. ++ * We can ignore this call failing as the default at other end is 0 ++ */ ++ set_display_num(fb); ++ ++ /* Try allocating our own buffer. We can specify all the parameters */ ++ image_size = ((info->var.xres * info->var.yres) * ++ info->var.bits_per_pixel) >> 3; ++ ++ if (!fb->fbdev->disable_arm_alloc && ++ (image_size != fb->image_size || !fb->dma_addr)) { ++ if (fb->dma_addr) { ++ dma_free_coherent(info->device, fb->image_size, ++ fb->cpuaddr, fb->dma_addr); ++ fb->image_size = 0; ++ fb->cpuaddr = NULL; ++ fb->dma_addr = 0; ++ } ++ ++ fb->cpuaddr = dma_alloc_coherent(info->device, image_size, ++ &fb->dma_addr, GFP_KERNEL); ++ ++ if (!fb->cpuaddr) { ++ fb->dma_addr = 0; ++ fb->fbdev->disable_arm_alloc = true; ++ } else { ++ fb->image_size = image_size; ++ } ++ } ++ ++ if (fb->cpuaddr) { ++ fbinfo.base = fb->dma_addr; ++ fbinfo.screen_size = image_size; ++ fbinfo.pitch = (info->var.xres * info->var.bits_per_pixel) >> 3; ++ ++ ret = rpi_firmware_property_list(fb->fbdev->fw, &fbinfo, ++ sizeof(fbinfo)); ++ if (ret || fbinfo.base != fb->dma_addr) { ++ /* Firmware either failed, or assigned a different base ++ * address (ie it doesn't support being passed an FB ++ * allocation). ++ * Destroy the allocation, and don't try again. ++ */ ++ dma_free_coherent(info->device, fb->image_size, ++ fb->cpuaddr, fb->dma_addr); ++ fb->image_size = 0; ++ fb->cpuaddr = NULL; ++ fb->dma_addr = 0; ++ fb->fbdev->disable_arm_alloc = true; ++ } ++ } else { ++ /* Our allocation failed - drop into the old scheme of ++ * allocation by the VPU. ++ */ ++ ret = -ENOMEM; ++ } + +- ret = rpi_firmware_property_list(fb->fw, &fbinfo, sizeof(fbinfo)); + if (ret) { +- dev_err(info->device, +- "Failed to allocate GPU framebuffer (%d)\n", ret); +- return ret; ++ /* Old scheme: ++ * - FRAMEBUFFER_ALLOCATE passes 0 for base and screen_size. ++ * - GET_PITCH instead of SET_PITCH. ++ */ ++ fbinfo.base = 0; ++ fbinfo.screen_size = 0; ++ fbinfo.tag6.tag = RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH; ++ fbinfo.pitch = 0; ++ ++ ret = rpi_firmware_property_list(fb->fbdev->fw, &fbinfo, ++ sizeof(fbinfo)); ++ if (ret) { ++ dev_err(info->device, ++ "Failed to allocate GPU framebuffer (%d)\n", ++ ret); ++ return ret; ++ } + } + + if (info->var.bits_per_pixel <= 8) +@@ -314,9 +481,17 @@ static int bcm2708_fb_set_par(struct fb_ + fb->fb.fix.smem_start = fbinfo.base; + fb->fb.fix.smem_len = fbinfo.pitch * fbinfo.yres_virtual; + fb->fb.screen_size = fbinfo.screen_size; +- if (fb->fb.screen_base) +- iounmap(fb->fb.screen_base); +- fb->fb.screen_base = ioremap_wc(fbinfo.base, fb->fb.screen_size); ++ ++ if (!fb->dma_addr) { ++ if (fb->fb.screen_base) ++ iounmap(fb->fb.screen_base); ++ ++ fb->fb.screen_base = ioremap_wc(fbinfo.base, ++ fb->fb.screen_size); ++ } else { ++ fb->fb.screen_base = fb->cpuaddr; ++ } ++ + if (!fb->fb.screen_base) { + /* the console may currently be locked */ + console_trylock(); +@@ -374,7 +549,10 @@ static int bcm2708_fb_setcolreg(unsigned + packet->length = regno + 1; + memcpy(packet->cmap, fb->gpu_cmap, + sizeof(packet->cmap)); +- ret = rpi_firmware_property(fb->fw, ++ ++ set_display_num(fb); ++ ++ ret = rpi_firmware_property(fb->fbdev->fw, + RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE, + packet, + (2 + packet->length) * sizeof(u32)); +@@ -413,8 +591,11 @@ static int bcm2708_fb_blank(int blank_mo + return -EINVAL; + } + +- ret = rpi_firmware_property(fb->fw, RPI_FIRMWARE_FRAMEBUFFER_BLANK, ++ set_display_num(fb); ++ ++ ret = rpi_firmware_property(fb->fbdev->fw, RPI_FIRMWARE_FRAMEBUFFER_BLANK, + &value, sizeof(value)); ++ + if (ret) + dev_err(info->device, "%s(%d) failed: %d\n", __func__, + blank_mode, ret); +@@ -431,7 +612,7 @@ static int bcm2708_fb_pan_display(struct + info->var.yoffset = var->yoffset; + result = bcm2708_fb_set_par(info); + if (result != 0) +- pr_err("%s(%d,%d) returns=%d\n", __func__, var->xoffset, ++ pr_err("%s(%u,%u) returns=%d\n", __func__, var->xoffset, + var->yoffset, result); + return result; + } +@@ -439,8 +620,9 @@ static int bcm2708_fb_pan_display(struct + static void dma_memcpy(struct bcm2708_fb *fb, dma_addr_t dst, dma_addr_t src, + int size) + { +- int burst_size = (fb->dma_chan == 0) ? 8 : 2; +- struct bcm2708_dma_cb *cb = fb->cb_base; ++ struct bcm2708_fb_dev *fbdev = fb->fbdev; ++ struct bcm2708_dma_cb *cb = fbdev->cb_base; ++ int burst_size = (fbdev->dma_chan == 0) ? 8 : 2; + + cb->info = BCM2708_DMA_BURST(burst_size) | BCM2708_DMA_S_WIDTH | + BCM2708_DMA_S_INC | BCM2708_DMA_D_WIDTH | +@@ -453,21 +635,27 @@ static void dma_memcpy(struct bcm2708_fb + cb->pad[1] = 0; + cb->next = 0; + ++ // Not sure what to do if this gets a signal whilst waiting ++ if (mutex_lock_interruptible(&fbdev->dma_mutex)) ++ return; ++ + if (size < dma_busy_wait_threshold) { +- bcm_dma_start(fb->dma_chan_base, fb->cb_handle); +- bcm_dma_wait_idle(fb->dma_chan_base); ++ bcm_dma_start(fbdev->dma_chan_base, fbdev->cb_handle); ++ bcm_dma_wait_idle(fbdev->dma_chan_base); + } else { +- void __iomem *dma_chan = fb->dma_chan_base; ++ void __iomem *local_dma_chan = fbdev->dma_chan_base; + + cb->info |= BCM2708_DMA_INT_EN; +- bcm_dma_start(fb->dma_chan_base, fb->cb_handle); +- while (bcm_dma_is_busy(dma_chan)) { +- wait_event_interruptible(fb->dma_waitq, +- !bcm_dma_is_busy(dma_chan)); ++ bcm_dma_start(fbdev->dma_chan_base, fbdev->cb_handle); ++ while (bcm_dma_is_busy(local_dma_chan)) { ++ wait_event_interruptible(fbdev->dma_waitq, ++ !bcm_dma_is_busy(local_dma_chan)); + } +- fb->stats.dma_irqs++; ++ fbdev->dma_stats.dma_irqs++; + } +- fb->stats.dma_copies++; ++ fbdev->dma_stats.dma_copies++; ++ ++ mutex_unlock(&fbdev->dma_mutex); + } + + /* address with no aliases */ +@@ -542,10 +730,13 @@ static int bcm2708_ioctl(struct fb_info + + switch (cmd) { + case FBIO_WAITFORVSYNC: +- ret = rpi_firmware_property(fb->fw, ++ set_display_num(fb); ++ ++ ret = rpi_firmware_property(fb->fbdev->fw, + RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC, + &dummy, sizeof(dummy)); + break; ++ + case FBIODMACOPY: + { + struct fb_dmacopy ioparam; +@@ -615,23 +806,22 @@ static int bcm2708_compat_ioctl(struct f + static void bcm2708_fb_fillrect(struct fb_info *info, + const struct fb_fillrect *rect) + { +- /* (is called) print_debug("bcm2708_fb_fillrect\n"); */ + cfb_fillrect(info, rect); + } + + /* A helper function for configuring dma control block */ + static void set_dma_cb(struct bcm2708_dma_cb *cb, +- int burst_size, +- dma_addr_t dst, +- int dst_stride, +- dma_addr_t src, +- int src_stride, +- int w, +- int h) ++ int burst_size, ++ dma_addr_t dst, ++ int dst_stride, ++ dma_addr_t src, ++ int src_stride, ++ int w, ++ int h) + { + cb->info = BCM2708_DMA_BURST(burst_size) | BCM2708_DMA_S_WIDTH | +- BCM2708_DMA_S_INC | BCM2708_DMA_D_WIDTH | +- BCM2708_DMA_D_INC | BCM2708_DMA_TDMODE; ++ BCM2708_DMA_S_INC | BCM2708_DMA_D_WIDTH | ++ BCM2708_DMA_D_INC | BCM2708_DMA_TDMODE; + cb->dst = dst; + cb->src = src; + /* +@@ -649,15 +839,19 @@ static void bcm2708_fb_copyarea(struct f + const struct fb_copyarea *region) + { + struct bcm2708_fb *fb = to_bcm2708(info); +- struct bcm2708_dma_cb *cb = fb->cb_base; ++ struct bcm2708_fb_dev *fbdev = fb->fbdev; ++ struct bcm2708_dma_cb *cb = fbdev->cb_base; + int bytes_per_pixel = (info->var.bits_per_pixel + 7) >> 3; + + /* Channel 0 supports larger bursts and is a bit faster */ +- int burst_size = (fb->dma_chan == 0) ? 8 : 2; ++ int burst_size = (fbdev->dma_chan == 0) ? 8 : 2; + int pixels = region->width * region->height; + +- /* Fallback to cfb_copyarea() if we don't like something */ +- if (bytes_per_pixel > 4 || ++ /* If DMA is currently in use (ie being used on another FB), then ++ * rather than wait for it to finish, just use the cfb_copyarea ++ */ ++ if (!mutex_trylock(&fbdev->dma_mutex) || ++ bytes_per_pixel > 4 || + info->var.xres * info->var.yres > 1920 * 1200 || + region->width <= 0 || region->width > info->var.xres || + region->height <= 0 || region->height > info->var.yres || +@@ -684,8 +878,8 @@ static void bcm2708_fb_copyarea(struct f + * 1920x1200 resolution at 32bpp pixel depth. + */ + int y; +- dma_addr_t control_block_pa = fb->cb_handle; +- dma_addr_t scratchbuf = fb->cb_handle + 16 * 1024; ++ dma_addr_t control_block_pa = fbdev->cb_handle; ++ dma_addr_t scratchbuf = fbdev->cb_handle + 16 * 1024; + int scanline_size = bytes_per_pixel * region->width; + int scanlines_per_cb = (64 * 1024 - 16 * 1024) / scanline_size; + +@@ -735,10 +929,10 @@ static void bcm2708_fb_copyarea(struct f + } + set_dma_cb(cb, burst_size, + fb->fb_bus_address + dy * fb->fb.fix.line_length + +- bytes_per_pixel * region->dx, ++ bytes_per_pixel * region->dx, + stride, + fb->fb_bus_address + sy * fb->fb.fix.line_length + +- bytes_per_pixel * region->sx, ++ bytes_per_pixel * region->sx, + stride, + region->width * bytes_per_pixel, + region->height); +@@ -748,32 +942,33 @@ static void bcm2708_fb_copyarea(struct f + cb->next = 0; + + if (pixels < dma_busy_wait_threshold) { +- bcm_dma_start(fb->dma_chan_base, fb->cb_handle); +- bcm_dma_wait_idle(fb->dma_chan_base); ++ bcm_dma_start(fbdev->dma_chan_base, fbdev->cb_handle); ++ bcm_dma_wait_idle(fbdev->dma_chan_base); + } else { +- void __iomem *dma_chan = fb->dma_chan_base; ++ void __iomem *local_dma_chan = fbdev->dma_chan_base; + + cb->info |= BCM2708_DMA_INT_EN; +- bcm_dma_start(fb->dma_chan_base, fb->cb_handle); +- while (bcm_dma_is_busy(dma_chan)) { +- wait_event_interruptible(fb->dma_waitq, +- !bcm_dma_is_busy(dma_chan)); ++ bcm_dma_start(fbdev->dma_chan_base, fbdev->cb_handle); ++ while (bcm_dma_is_busy(local_dma_chan)) { ++ wait_event_interruptible(fbdev->dma_waitq, ++ !bcm_dma_is_busy(local_dma_chan)); + } +- fb->stats.dma_irqs++; ++ fbdev->dma_stats.dma_irqs++; + } +- fb->stats.dma_copies++; ++ fbdev->dma_stats.dma_copies++; ++ ++ mutex_unlock(&fbdev->dma_mutex); + } + + static void bcm2708_fb_imageblit(struct fb_info *info, + const struct fb_image *image) + { +- /* (is called) print_debug("bcm2708_fb_imageblit\n"); */ + cfb_imageblit(info, image); + } + + static irqreturn_t bcm2708_fb_dma_irq(int irq, void *cxt) + { +- struct bcm2708_fb *fb = cxt; ++ struct bcm2708_fb_dev *fbdev = cxt; + + /* FIXME: should read status register to check if this is + * actually interrupting us or not, in case this interrupt +@@ -783,9 +978,9 @@ static irqreturn_t bcm2708_fb_dma_irq(in + */ + + /* acknowledge the interrupt */ +- writel(BCM2708_DMA_INT, fb->dma_chan_base + BCM2708_DMA_CS); ++ writel(BCM2708_DMA_INT, fbdev->dma_chan_base + BCM2708_DMA_CS); + +- wake_up(&fb->dma_waitq); ++ wake_up(&fbdev->dma_waitq); + return IRQ_HANDLED; + } + +@@ -821,11 +1016,23 @@ static int bcm2708_fb_register(struct bc + fb->fb.fix.ywrapstep = 0; + fb->fb.fix.accel = FB_ACCEL_NONE; + +- fb->fb.var.xres = fbwidth; +- fb->fb.var.yres = fbheight; +- fb->fb.var.xres_virtual = fbwidth; +- fb->fb.var.yres_virtual = fbheight; +- fb->fb.var.bits_per_pixel = fbdepth; ++ /* If we have data from the VC4 on FB's, use that, otherwise use the ++ * module parameters ++ */ ++ if (fb->display_settings.width) { ++ fb->fb.var.xres = fb->display_settings.width; ++ fb->fb.var.yres = fb->display_settings.height; ++ fb->fb.var.xres_virtual = fb->fb.var.xres; ++ fb->fb.var.yres_virtual = fb->fb.var.yres; ++ fb->fb.var.bits_per_pixel = fb->display_settings.depth; ++ } else { ++ fb->fb.var.xres = fbwidth; ++ fb->fb.var.yres = fbheight; ++ fb->fb.var.xres_virtual = fbwidth; ++ fb->fb.var.yres_virtual = fbheight; ++ fb->fb.var.bits_per_pixel = fbdepth; ++ } ++ + fb->fb.var.vmode = FB_VMODE_NONINTERLACED; + fb->fb.var.activate = FB_ACTIVATE_NOW; + fb->fb.var.nonstd = 0; +@@ -841,26 +1048,23 @@ static int bcm2708_fb_register(struct bc + fb->fb.monspecs.dclkmax = 100000000; + + bcm2708_fb_set_bitfields(&fb->fb.var); +- init_waitqueue_head(&fb->dma_waitq); + + /* + * Allocate colourmap. + */ +- + fb_set_var(&fb->fb, &fb->fb.var); ++ + ret = bcm2708_fb_set_par(&fb->fb); ++ + if (ret) + return ret; + +- print_debug("BCM2708FB: registering framebuffer (%dx%d@%d) (%d)\n", +- fbwidth, fbheight, fbdepth, fbswap); +- + ret = register_framebuffer(&fb->fb); +- print_debug("BCM2708FB: register framebuffer (%d)\n", ret); ++ + if (ret == 0) + goto out; + +- print_debug("BCM2708FB: cannot register framebuffer (%d)\n", ret); ++ dev_warn(fb->fb.dev, "Unable to register framebuffer (%d)\n", ret); + out: + return ret; + } +@@ -869,10 +1073,18 @@ static int bcm2708_fb_probe(struct platf + { + struct device_node *fw_np; + struct rpi_firmware *fw; +- struct bcm2708_fb *fb; +- int ret; ++ int ret, i; ++ u32 num_displays; ++ struct bcm2708_fb_dev *fbdev; ++ struct { u32 base, length; } gpu_mem; ++ ++ fbdev = devm_kzalloc(&dev->dev, sizeof(*fbdev), GFP_KERNEL); ++ ++ if (!fbdev) ++ return -ENOMEM; + + fw_np = of_parse_phandle(dev->dev.of_node, "firmware", 0); ++ + /* Remove comment when booting without Device Tree is no longer supported + * if (!fw_np) { + * dev_err(&dev->dev, "Missing firmware node\n"); +@@ -880,90 +1092,154 @@ static int bcm2708_fb_probe(struct platf + * } + */ + fw = rpi_firmware_get(fw_np); ++ fbdev->fw = fw; ++ + if (!fw) + return -EPROBE_DEFER; + +- fb = kzalloc(sizeof(*fb), GFP_KERNEL); +- if (!fb) { +- ret = -ENOMEM; +- goto free_region; ++ ret = rpi_firmware_property(fw, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS, ++ &num_displays, sizeof(u32)); ++ ++ /* If we fail to get the number of displays, or it returns 0, then ++ * assume old firmware that doesn't have the mailbox call, so just ++ * set one display ++ */ ++ if (ret || num_displays == 0) { ++ num_displays = 1; ++ dev_err(&dev->dev, ++ "Unable to determine number of FB's. Assuming 1\n"); ++ ret = 0; ++ } else { ++ fbdev->firmware_supports_multifb = 1; + } + +- fb->fw = fw; +- bcm2708_fb_debugfs_init(fb); ++ if (num_displays > MAX_FRAMEBUFFERS) { ++ dev_warn(&dev->dev, ++ "More displays reported from firmware than supported in driver (%u vs %u)", ++ num_displays, MAX_FRAMEBUFFERS); ++ num_displays = MAX_FRAMEBUFFERS; ++ } + +- fb->cb_base = dma_alloc_writecombine(&dev->dev, SZ_64K, +- &fb->cb_handle, GFP_KERNEL); +- if (!fb->cb_base) { ++ dev_info(&dev->dev, "FB found %d display(s)\n", num_displays); ++ ++ /* Set up the DMA information. Note we have just one set of DMA ++ * parameters to work with all the FB's so requires synchronising when ++ * being used ++ */ ++ ++ mutex_init(&fbdev->dma_mutex); ++ ++ fbdev->cb_base = dma_alloc_writecombine(&dev->dev, SZ_64K, ++ &fbdev->cb_handle, ++ GFP_KERNEL); ++ if (!fbdev->cb_base) { + dev_err(&dev->dev, "cannot allocate DMA CBs\n"); + ret = -ENOMEM; + goto free_fb; + } + +- pr_info("BCM2708FB: allocated DMA memory %pad\n", &fb->cb_handle); +- + ret = bcm_dma_chan_alloc(BCM_DMA_FEATURE_BULK, +- &fb->dma_chan_base, &fb->dma_irq); ++ &fbdev->dma_chan_base, ++ &fbdev->dma_irq); + if (ret < 0) { +- dev_err(&dev->dev, "couldn't allocate a DMA channel\n"); ++ dev_err(&dev->dev, "Couldn't allocate a DMA channel\n"); + goto free_cb; + } +- fb->dma_chan = ret; ++ fbdev->dma_chan = ret; + +- ret = request_irq(fb->dma_irq, bcm2708_fb_dma_irq, +- 0, "bcm2708_fb dma", fb); ++ ret = request_irq(fbdev->dma_irq, bcm2708_fb_dma_irq, ++ 0, "bcm2708_fb DMA", fbdev); + if (ret) { +- pr_err("%s: failed to request DMA irq\n", __func__); ++ dev_err(&dev->dev, ++ "Failed to request DMA irq\n"); + goto free_dma_chan; + } + +- pr_info("BCM2708FB: allocated DMA channel %d\n", fb->dma_chan); ++ rpi_firmware_property(fbdev->fw, ++ RPI_FIRMWARE_GET_VC_MEMORY, ++ &gpu_mem, sizeof(gpu_mem)); ++ ++ for (i = 0; i < num_displays; i++) { ++ struct bcm2708_fb *fb = &fbdev->displays[i]; ++ ++ fb->display_settings.display_num = i; ++ fb->dev = dev; ++ fb->fb.device = &dev->dev; ++ fb->fbdev = fbdev; ++ ++ fb->gpu.base = gpu_mem.base; ++ fb->gpu.length = gpu_mem.length; ++ ++ if (fbdev->firmware_supports_multifb) { ++ ret = rpi_firmware_property(fw, ++ RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_SETTINGS, ++ &fb->display_settings, ++ GET_DISPLAY_SETTINGS_PAYLOAD_SIZE); ++ } else { ++ memset(&fb->display_settings, 0, ++ sizeof(fb->display_settings)); ++ } ++ ++ ret = bcm2708_fb_register(fb); + +- fb->dev = dev; +- fb->fb.device = &dev->dev; ++ if (ret == 0) { ++ bcm2708_fb_debugfs_init(fb); + +- /* failure here isn't fatal, but we'll fail in vc_mem_copy if +- * fb->gpu is not valid +- */ +- rpi_firmware_property(fb->fw, RPI_FIRMWARE_GET_VC_MEMORY, &fb->gpu, +- sizeof(fb->gpu)); ++ fbdev->num_displays++; + +- ret = bcm2708_fb_register(fb); +- if (ret == 0) { +- platform_set_drvdata(dev, fb); +- goto out; ++ dev_info(&dev->dev, ++ "Registered framebuffer for display %u, size %ux%u\n", ++ fb->display_settings.display_num, ++ fb->fb.var.xres, ++ fb->fb.var.yres); ++ } else { ++ // Use this to flag if this FB entry is in use. ++ fb->fbdev = NULL; ++ } ++ } ++ ++ // Did we actually successfully create any FB's? ++ if (fbdev->num_displays) { ++ init_waitqueue_head(&fbdev->dma_waitq); ++ platform_set_drvdata(dev, fbdev); ++ return ret; + } + + free_dma_chan: +- bcm_dma_chan_free(fb->dma_chan); ++ bcm_dma_chan_free(fbdev->dma_chan); + free_cb: +- dma_free_writecombine(&dev->dev, SZ_64K, fb->cb_base, fb->cb_handle); ++ dma_free_writecombine(&dev->dev, SZ_64K, fbdev->cb_base, ++ fbdev->cb_handle); + free_fb: +- kfree(fb); +-free_region: + dev_err(&dev->dev, "probe failed, err %d\n", ret); +-out: ++ + return ret; + } + + static int bcm2708_fb_remove(struct platform_device *dev) + { +- struct bcm2708_fb *fb = platform_get_drvdata(dev); ++ struct bcm2708_fb_dev *fbdev = platform_get_drvdata(dev); ++ int i; + + platform_set_drvdata(dev, NULL); + +- if (fb->fb.screen_base) +- iounmap(fb->fb.screen_base); +- unregister_framebuffer(&fb->fb); +- +- dma_free_writecombine(&dev->dev, SZ_64K, fb->cb_base, fb->cb_handle); +- bcm_dma_chan_free(fb->dma_chan); +- +- bcm2708_fb_debugfs_deinit(fb); ++ for (i = 0; i < fbdev->num_displays; i++) { ++ if (fbdev->displays[i].fb.screen_base) ++ iounmap(fbdev->displays[i].fb.screen_base); ++ ++ if (fbdev->displays[i].fbdev) { ++ unregister_framebuffer(&fbdev->displays[i].fb); ++ bcm2708_fb_debugfs_deinit(&fbdev->displays[i]); ++ } ++ } + +- free_irq(fb->dma_irq, fb); ++ dma_free_writecombine(&dev->dev, SZ_64K, fbdev->cb_base, ++ fbdev->cb_handle); ++ bcm_dma_chan_free(fbdev->dma_chan); ++ free_irq(fbdev->dma_irq, fbdev); + +- kfree(fb); ++ mutex_destroy(&fbdev->dma_mutex); + + return 0; + } +@@ -978,10 +1254,10 @@ static struct platform_driver bcm2708_fb + .probe = bcm2708_fb_probe, + .remove = bcm2708_fb_remove, + .driver = { +- .name = DRIVER_NAME, +- .owner = THIS_MODULE, +- .of_match_table = bcm2708_fb_of_match_table, +- }, ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = bcm2708_fb_of_match_table, ++ }, + }; + + static int __init bcm2708_fb_init(void) +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -138,9 +138,11 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, + RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER = 0x00048006, + RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE = 0x00048007, ++ RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH = 0x00048008, + RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, + RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, + RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, ++ + RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF = 0x0004801f, + RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF = 0x00048020, + RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e, +@@ -159,6 +161,8 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, + }; + ++#define GET_DISPLAY_SETTINGS_PAYLOAD_SIZE 64 ++ + #if IS_ENABLED(CONFIG_RASPBERRYPI_FIRMWARE) + int rpi_firmware_property(struct rpi_firmware *fw, + u32 tag, void *data, size_t len); diff --git a/target/linux/brcm2708/patches-4.19/950-0633-staging-vcsm-cma-Add-cache-control-ioctls.patch b/target/linux/brcm2708/patches-4.19/950-0633-staging-vcsm-cma-Add-cache-control-ioctls.patch deleted file mode 100644 index b795635130..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0633-staging-vcsm-cma-Add-cache-control-ioctls.patch +++ /dev/null @@ -1,245 +0,0 @@ -From 8859e85097f9e1bbc86b8818e24abc3c36c45b15 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 20 Mar 2019 10:40:00 +0000 -Subject: [PATCH 633/703] staging: vcsm-cma: Add cache control ioctls - -The old driver allowed for direct cache manipulation and that -was used by various clients. Replicate here. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/vc-sm-cma/vc_sm.c | 141 +++++++++++++++++- - include/linux/broadcom/vc_sm_cma_ioctl.h | 27 ++++ - 2 files changed, 165 insertions(+), 3 deletions(-) - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -46,6 +46,7 @@ - #include - #include - #include -+#include - - #include "vchiq_connected.h" - #include "vc_sm_cma_vchi.h" -@@ -1258,6 +1259,99 @@ error: - return ret; - } - -+/* Converts VCSM_CACHE_OP_* to an operating function. */ -+static void (*cache_op_to_func(const unsigned int cache_op)) -+ (const void*, const void*) -+{ -+ switch (cache_op) { -+ case VC_SM_CACHE_OP_NOP: -+ return NULL; -+ -+ case VC_SM_CACHE_OP_INV: -+ return dmac_inv_range; -+ -+ case VC_SM_CACHE_OP_CLEAN: -+ return dmac_clean_range; -+ -+ case VC_SM_CACHE_OP_FLUSH: -+ return dmac_flush_range; -+ -+ default: -+ pr_err("[%s]: Invalid cache_op: 0x%08x\n", __func__, cache_op); -+ return NULL; -+ } -+} -+ -+/* -+ * Clean/invalid/flush cache of which buffer is already pinned (i.e. accessed). -+ */ -+static int clean_invalid_contig_2d(const void __user *addr, -+ const size_t block_count, -+ const size_t block_size, -+ const size_t stride, -+ const unsigned int cache_op) -+{ -+ size_t i; -+ void (*op_fn)(const void *start, const void *end); -+ -+ if (!block_size) { -+ pr_err("[%s]: size cannot be 0\n", __func__); -+ return -EINVAL; -+ } -+ -+ op_fn = cache_op_to_func(cache_op); -+ if (!op_fn) -+ return -EINVAL; -+ -+ for (i = 0; i < block_count; i ++, addr += stride) -+ op_fn(addr, addr + block_size); -+ -+ return 0; -+} -+ -+static int vc_sm_cma_clean_invalid2(unsigned int cmdnr, unsigned long arg) -+{ -+ struct vc_sm_cma_ioctl_clean_invalid2 ioparam; -+ struct vc_sm_cma_ioctl_clean_invalid_block *block = NULL; -+ int i, ret = 0; -+ -+ /* Get parameter data. */ -+ if (copy_from_user(&ioparam, (void *)arg, sizeof(ioparam))) { -+ pr_err("[%s]: failed to copy-from-user header for cmd %x\n", -+ __func__, cmdnr); -+ return -EFAULT; -+ } -+ block = kmalloc(ioparam.op_count * sizeof(*block), GFP_KERNEL); -+ if (!block) -+ return -EFAULT; -+ -+ if (copy_from_user(block, (void *)(arg + sizeof(ioparam)), -+ ioparam.op_count * sizeof(*block)) != 0) { -+ pr_err("[%s]: failed to copy-from-user payload for cmd %x\n", -+ __func__, cmdnr); -+ ret = -EFAULT; -+ goto out; -+ } -+ -+ for (i = 0; i < ioparam.op_count; i++) { -+ const struct vc_sm_cma_ioctl_clean_invalid_block * const op = block + i; -+ -+ if (op->invalidate_mode == VC_SM_CACHE_OP_NOP) -+ continue; -+ -+ ret = clean_invalid_contig_2d((void __user *)op->start_address, -+ op->block_count, op->block_size, -+ op->inter_block_stride, -+ op->invalidate_mode); -+ if (ret) -+ break; -+ } -+out: -+ kfree(block); -+ -+ return ret; -+} -+ - static long vc_sm_cma_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) - { -@@ -1272,9 +1366,6 @@ static long vc_sm_cma_ioctl(struct file - return -EPERM; - } - -- pr_debug("[%s]: cmd %x tgid %u, owner %u\n", __func__, cmdnr, -- current->tgid, file_data->pid); -- - /* Action is a re-post of a previously interrupted action? */ - if (file_data->restart_sys == -EINTR) { - struct vc_sm_action_clean_t action_clean; -@@ -1357,7 +1448,18 @@ static long vc_sm_cma_ioctl(struct file - break; - } - -+ /* -+ * Flush/Invalidate the cache for a given mapping. -+ * Blocks must be pinned (i.e. accessed) before this call. -+ */ -+ case VC_SM_CMA_CMD_CLEAN_INVALID2: -+ ret = vc_sm_cma_clean_invalid2(cmdnr, arg); -+ break; -+ - default: -+ pr_debug("[%s]: cmd %x tgid %u, owner %u\n", __func__, cmdnr, -+ current->tgid, file_data->pid); -+ - ret = -EINVAL; - break; - } -@@ -1365,10 +1467,43 @@ static long vc_sm_cma_ioctl(struct file - return ret; - } - -+#ifdef CONFIG_COMPAT -+struct vc_sm_cma_ioctl_clean_invalid2_32 { -+ u32 op_count; -+ struct vc_sm_cma_ioctl_clean_invalid_block { -+ u16 invalidate_mode; -+ u16 block_count; -+ compat_uptr_t start_address; -+ u32 block_size; -+ u32 inter_block_stride; -+ } s[0]; -+}; -+ -+#define VC_SM_CMA_CMD_CLEAN_INVALID2_32\ -+ _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_CLEAN_INVALID2,\ -+ struct vc_sm_cma_ioctl_clean_invalid2) -+ -+static long vc_sm_cma_compat_ioctl(struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ switch (cmd) { -+ case VC_SM_CMA_CMD_CLEAN_INVALID2_32: -+ /* FIXME */ -+ break; -+ -+ default: -+ return vc_sm_cma_compat_ioctl(file, cmd, arg); -+ } -+} -+#endif -+ - /* Device operations that we managed in this driver. */ - static const struct file_operations vc_sm_ops = { - .owner = THIS_MODULE, - .unlocked_ioctl = vc_sm_cma_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = vc_sm_cma_compat_ioctl, -+#endif - .open = vc_sm_cma_open, - .release = vc_sm_cma_release, - }; ---- a/include/linux/broadcom/vc_sm_cma_ioctl.h -+++ b/include/linux/broadcom/vc_sm_cma_ioctl.h -@@ -33,6 +33,8 @@ enum vc_sm_cma_cmd_e { - - VC_SM_CMA_CMD_IMPORT_DMABUF, - -+ VC_SM_CMA_CMD_CLEAN_INVALID2, -+ - VC_SM_CMA_CMD_LAST /* Do not delete */ - }; - -@@ -75,6 +77,27 @@ struct vc_sm_cma_ioctl_import_dmabuf { - __u64 dma_addr; - }; - -+/* -+ * Cache functions to be set to struct vc_sm_cma_ioctl_clean_invalid2 -+ * invalidate_mode. -+ */ -+#define VC_SM_CACHE_OP_NOP 0x00 -+#define VC_SM_CACHE_OP_INV 0x01 -+#define VC_SM_CACHE_OP_CLEAN 0x02 -+#define VC_SM_CACHE_OP_FLUSH 0x03 -+ -+struct vc_sm_cma_ioctl_clean_invalid2 { -+ __u32 op_count; -+ __u32 pad; -+ struct vc_sm_cma_ioctl_clean_invalid_block { -+ __u32 invalidate_mode; -+ __u32 block_count; -+ void * __user start_address; -+ __u32 block_size; -+ __u32 inter_block_stride; -+ } s[0]; -+}; -+ - /* IOCTL numbers */ - #define VC_SM_CMA_IOCTL_MEM_ALLOC\ - _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_ALLOC,\ -@@ -84,4 +107,8 @@ struct vc_sm_cma_ioctl_import_dmabuf { - _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_IMPORT_DMABUF,\ - struct vc_sm_cma_ioctl_import_dmabuf) - -+#define VC_SM_CMA_IOCTL_MEM_CLEAN_INVALID2\ -+ _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_CLEAN_INVALID2,\ -+ struct vc_sm_cma_ioctl_clean_invalid2) -+ - #endif /* __VC_SM_CMA_IOCTL_H */ diff --git a/target/linux/brcm2708/patches-4.19/950-0634-ARM-dts-bcm283x-Move-BCM2835-6-7-specific-to-bcm2835.patch b/target/linux/brcm2708/patches-4.19/950-0634-ARM-dts-bcm283x-Move-BCM2835-6-7-specific-to-bcm2835.patch new file mode 100644 index 0000000000..914dc532a0 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0634-ARM-dts-bcm283x-Move-BCM2835-6-7-specific-to-bcm2835.patch @@ -0,0 +1,189 @@ +From 655d142ec4bcf46f10c4e09099f9a9846e078454 Mon Sep 17 00:00:00 2001 +From: Stefan Wahren +Date: Sun, 19 May 2019 12:26:21 +0200 +Subject: [PATCH 634/725] ARM: dts: bcm283x: Move BCM2835/6/7 specific to + bcm2835-common.dtsi + +We want all common BCM2835/6/7/8 functions in bcm283x.dtsi and all +BCM2835/6/7 specific in the new bcm2835-common.dtsi. + +Signed-off-by: Stefan Wahren +--- + arch/arm/boot/dts/bcm2835-common.dtsi | 53 +++++++++++++++++++++++++++ + arch/arm/boot/dts/bcm2835.dtsi | 1 + + arch/arm/boot/dts/bcm2836.dtsi | 1 + + arch/arm/boot/dts/bcm2837.dtsi | 1 + + arch/arm/boot/dts/bcm283x.dtsi | 43 +--------------------- + 5 files changed, 57 insertions(+), 42 deletions(-) + create mode 100644 arch/arm/boot/dts/bcm2835-common.dtsi + +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2835-common.dtsi +@@ -0,0 +1,53 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++/* This include file covers the common peripherals and configuration between ++ * bcm2835, bcm2836 and bcm2837 implementations. ++ */ ++ ++/ { ++ soc { ++ timer@7e003000 { ++ compatible = "brcm,bcm2835-system-timer"; ++ reg = <0x7e003000 0x1000>; ++ interrupts = <1 0>, <1 1>, <1 2>, <1 3>; ++ /* This could be a reference to BCM2835_CLOCK_TIMER, ++ * but we don't have the driver using the common clock ++ * support yet. ++ */ ++ clock-frequency = <1000000>; ++ }; ++ ++ intc: interrupt-controller@7e00b200 { ++ compatible = "brcm,bcm2835-armctrl-ic"; ++ reg = <0x7e00b200 0x200>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ thermal: thermal@7e212000 { ++ compatible = "brcm,bcm2835-thermal"; ++ reg = <0x7e212000 0x8>; ++ clocks = <&clocks BCM2835_CLOCK_TSENS>; ++ #thermal-sensor-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ v3d: v3d@7ec00000 { ++ compatible = "brcm,bcm2835-v3d"; ++ reg = <0x7ec00000 0x1000>; ++ interrupts = <1 10>; ++ }; ++ }; ++}; ++ ++&gpio { ++ i2c_slave_gpio18: i2c_slave_gpio18 { ++ brcm,pins = <18 19 20 21>; ++ brcm,function = ; ++ }; ++ ++ jtag_gpio4: jtag_gpio4 { ++ brcm,pins = <4 5 6 12 13>; ++ brcm,function = ; ++ }; ++}; +--- a/arch/arm/boot/dts/bcm2835.dtsi ++++ b/arch/arm/boot/dts/bcm2835.dtsi +@@ -1,5 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 + #include "bcm283x.dtsi" ++#include "bcm2835-common.dtsi" + + / { + compatible = "brcm,bcm2835"; +--- a/arch/arm/boot/dts/bcm2836.dtsi ++++ b/arch/arm/boot/dts/bcm2836.dtsi +@@ -1,5 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 + #include "bcm283x.dtsi" ++#include "bcm2835-common.dtsi" + + / { + compatible = "brcm,bcm2836"; +--- a/arch/arm/boot/dts/bcm2837.dtsi ++++ b/arch/arm/boot/dts/bcm2837.dtsi +@@ -1,4 +1,5 @@ + #include "bcm283x.dtsi" ++#include "bcm2835-common.dtsi" + + / { + compatible = "brcm,bcm2837"; +--- a/arch/arm/boot/dts/bcm283x.dtsi ++++ b/arch/arm/boot/dts/bcm283x.dtsi +@@ -55,17 +55,6 @@ + #address-cells = <1>; + #size-cells = <1>; + +- timer@7e003000 { +- compatible = "brcm,bcm2835-system-timer"; +- reg = <0x7e003000 0x1000>; +- interrupts = <1 0>, <1 1>, <1 2>, <1 3>; +- /* This could be a reference to BCM2835_CLOCK_TIMER, +- * but we don't have the driver using the common clock +- * support yet. +- */ +- clock-frequency = <1000000>; +- }; +- + txp@7e004000 { + compatible = "brcm,bcm2835-txp"; + reg = <0x7e004000 0x20>; +@@ -113,13 +102,6 @@ + brcm,dma-channel-mask = <0x7f35>; + }; + +- intc: interrupt-controller@7e00b200 { +- compatible = "brcm,bcm2835-armctrl-ic"; +- reg = <0x7e00b200 0x200>; +- interrupt-controller; +- #interrupt-cells = <2>; +- }; +- + watchdog@7e100000 { + compatible = "brcm,bcm2835-pm", "brcm,bcm2835-pm-wdt"; + #power-domain-cells = <1>; +@@ -183,8 +165,7 @@ + interrupt-controller; + #interrupt-cells = <2>; + +- /* Defines pin muxing groups according to +- * BCM2835-ARM-Peripherals.pdf page 102. ++ /* Defines common pin muxing groups + * + * While each pin can have its mux selected + * for various functions individually, some +@@ -262,15 +243,7 @@ + brcm,pins = <44 45>; + brcm,function = ; + }; +- i2c_slave_gpio18: i2c_slave_gpio18 { +- brcm,pins = <18 19 20 21>; +- brcm,function = ; +- }; + +- jtag_gpio4: jtag_gpio4 { +- brcm,pins = <4 5 6 12 13>; +- brcm,function = ; +- }; + jtag_gpio22: jtag_gpio22 { + brcm,pins = <22 23 24 25 26 27>; + brcm,function = ; +@@ -487,14 +460,6 @@ + + }; + +- thermal: thermal@7e212000 { +- compatible = "brcm,bcm2835-thermal"; +- reg = <0x7e212000 0x8>; +- clocks = <&clocks BCM2835_CLOCK_TSENS>; +- #thermal-sensor-cells = <0>; +- status = "disabled"; +- }; +- + aux: aux@7e215000 { + compatible = "brcm,bcm2835-aux"; + #clock-cells = <1>; +@@ -660,12 +625,6 @@ + phy-names = "usb2-phy"; + }; + +- v3d: v3d@7ec00000 { +- compatible = "brcm,bcm2835-v3d"; +- reg = <0x7ec00000 0x1000>; +- interrupts = <1 10>; +- }; +- + vc4: gpu { + compatible = "brcm,bcm2835-vc4"; + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0634-staging-vcsm-cma-Alter-dev-node-permissions-to-0666.patch b/target/linux/brcm2708/patches-4.19/950-0634-staging-vcsm-cma-Alter-dev-node-permissions-to-0666.patch deleted file mode 100644 index ee794465bf..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0634-staging-vcsm-cma-Alter-dev-node-permissions-to-0666.patch +++ /dev/null @@ -1,24 +0,0 @@ -From efb4b8384a21a1542bc4c26063752180dda79c0b Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 13 May 2019 16:47:54 +0100 -Subject: [PATCH 634/703] staging: vcsm-cma: Alter dev node permissions to 0666 - -Until the udev rules are updated, open up access to this node by -default. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -1572,6 +1572,8 @@ static void vc_sm_connected_init(void) - sm_state->misc_dev.name = DEVICE_NAME; - sm_state->misc_dev.fops = &vc_sm_ops; - sm_state->misc_dev.parent = NULL; -+ /* Temporarily set as 666 until udev rules have been sorted */ -+ sm_state->misc_dev.mode = 0666; - ret = misc_register(&sm_state->misc_dev); - if (ret) { - pr_err("vcsm-cma: failed to register misc device.\n"); diff --git a/target/linux/brcm2708/patches-4.19/950-0635-ARM-dts-Add-bcm2711-rpi-4-b.dts-and-components.patch b/target/linux/brcm2708/patches-4.19/950-0635-ARM-dts-Add-bcm2711-rpi-4-b.dts-and-components.patch new file mode 100644 index 0000000000..b024b7fd6c --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0635-ARM-dts-Add-bcm2711-rpi-4-b.dts-and-components.patch @@ -0,0 +1,1129 @@ +From 8e0de1503575a5cb6810089b8fe40ad2309ac717 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 29 May 2019 13:54:21 +0100 +Subject: [PATCH 635/725] ARM: dts: Add bcm2711-rpi-4-b.dts and components + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/Makefile | 1 + + arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 320 ++++++++++++ + arch/arm/boot/dts/bcm2711.dtsi | 50 ++ + arch/arm/boot/dts/bcm2838.dtsi | 724 ++++++++++++++++++++++++++ + 4 files changed, 1095 insertions(+) + create mode 100644 arch/arm/boot/dts/bcm2711-rpi-4-b.dts + create mode 100644 arch/arm/boot/dts/bcm2711.dtsi + create mode 100644 arch/arm/boot/dts/bcm2838.dtsi + +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -8,6 +8,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ + bcm2708-rpi-zero-w.dtb \ + bcm2709-rpi-2-b.dtb \ + bcm2710-rpi-3-b.dtb \ ++ bcm2711-rpi-4-b.dtb \ + bcm2710-rpi-3-b-plus.dtb \ + bcm2710-rpi-cm3.dtb + +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts +@@ -0,0 +1,320 @@ ++/dts-v1/; ++ ++#include "bcm2711.dtsi" ++ ++/ { ++ compatible = "raspberrypi,4-model-b", "brcm,bcm2838", "brcm,bcm2837"; ++ model = "Raspberry Pi 4 Model B"; ++ #address-cells = <2>; ++ #size-cells = <1>; ++ ++ memory { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0>; ++ }; ++ ++ chosen { ++ bootargs = "8250.nr_uarts=1 cma=64M"; ++ }; ++ ++ aliases { ++ serial0 = &uart1; ++ serial1 = &uart0; ++ mmc0 = &emmc2; ++ mmc1 = &mmcnr; ++ mmc2 = &sdhost; ++ /delete-property/ ethernet; ++ /delete-property/ intc; ++ ethernet0 = &genet; ++ }; ++}; ++ ++&soc { ++ virtgpio: virtgpio { ++ compatible = "brcm,bcm2835-virtgpio"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ firmware = <&firmware>; ++ status = "okay"; ++ }; ++}; ++ ++&mmcnr { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&firmware { ++ expgpio: expgpio { ++ compatible = "raspberrypi,firmware-gpio"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ 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 = <125000000>; ++ }; ++ ++ spidev1: spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ }; ++}; ++ ++// ============================================= ++// Board specific stuff here ++ ++/ { ++ ++ sd_io_1v8_reg: sd_io_1v8_reg { ++ status = "okay"; ++ compatible = "regulator-gpio"; ++ vin-supply = <&vdd_5v0_reg>; ++ regulator-name = "vdd-sd-io"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-settling-time-us = <5000>; ++ ++ gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>; ++ states = <1800000 0x1 ++ 3300000 0x0>; ++ }; ++}; ++ ++&sdhost { ++ status = "disabled"; ++}; ++ ++&emmc2 { ++ status = "okay"; ++ broken-cd; ++ vqmmc-supply = <&sd_io_1v8_reg>; ++}; ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; ++ gpios = <&gpio 42 0>; ++ }; ++ ++ pwr_led: pwr { ++ label = "led1"; ++ linux,default-trigger = "input"; ++ gpios = <&expgpio 2 0>; ++ }; ++}; ++ ++&audio { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&audio_pins>; ++}; ++ ++&sdhost_gpio48 { ++ brcm,pins = <22 23 24 25 26 27>; ++ brcm,function = ; ++}; ++ ++&gpio { ++ spi0_pins: spi0_pins { ++ brcm,pins = <9 10 11>; ++ brcm,function = ; ++ }; ++ ++ spi0_cs_pins: spi0_cs_pins { ++ brcm,pins = <8 7>; ++ brcm,function = ; ++ }; ++ ++ spi3_pins: spi3_pins { ++ brcm,pins = <1 2 3>; ++ brcm,function = ; ++ }; ++ ++ spi3_cs_pins: spi3_cs_pins { ++ brcm,pins = <0 24>; ++ brcm,function = ; ++ }; ++ ++ spi4_pins: spi4_pins { ++ brcm,pins = <5 6 7>; ++ brcm,function = ; ++ }; ++ ++ spi4_cs_pins: spi4_cs_pins { ++ brcm,pins = <4 25>; ++ brcm,function = ; ++ }; ++ ++ spi5_pins: spi5_pins { ++ brcm,pins = <13 14 15>; ++ brcm,function = ; ++ }; ++ ++ spi5_cs_pins: spi5_cs_pins { ++ brcm,pins = <12 26>; ++ brcm,function = ; ++ }; ++ ++ spi6_pins: spi6_pins { ++ brcm,pins = <19 20 21>; ++ brcm,function = ; ++ }; ++ ++ spi6_cs_pins: spi6_cs_pins { ++ brcm,pins = <18 27>; ++ brcm,function = ; ++ }; ++ ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = ; ++ }; ++ ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = ; ++ }; ++ ++ i2c3_pins: i2c3 { ++ brcm,pins = <4 5>; ++ brcm,function = ; ++ }; ++ ++ i2c4_pins: i2c4 { ++ brcm,pins = <8 9>; ++ brcm,function = ; ++ }; ++ ++ i2c5_pins: i2c5 { ++ brcm,pins = <12 13>; ++ brcm,function = ; ++ }; ++ ++ i2c6_pins: i2c6 { ++ brcm,pins = <22 23>; ++ brcm,function = ; ++ }; ++ ++ i2s_pins: i2s { ++ brcm,pins = <18 19 20 21>; ++ brcm,function = ; ++ }; ++ ++ sdio_pins: sdio_pins { ++ brcm,pins = <34 35 36 37 38 39>; ++ brcm,function = ; // alt3 = SD1 ++ brcm,pull = <0 2 2 2 2 2>; ++ }; ++ ++ bt_pins: bt_pins { ++ brcm,pins = "-"; // non-empty to keep btuart happy, //4 = 0 ++ // to fool pinctrl ++ brcm,function = <0>; ++ brcm,pull = <2>; ++ }; ++ ++ uart0_pins: uart0_pins { ++ brcm,pins = <32 33>; ++ brcm,function = ; ++ brcm,pull = <0 2>; ++ }; ++ ++ uart1_pins: uart1_pins { ++ brcm,pins; ++ brcm,function; ++ brcm,pull; ++ }; ++ ++ uart2_pins: uart2_pins { ++ brcm,pins = <0 1>; ++ brcm,function = ; ++ brcm,pull = <0 2>; ++ }; ++ ++ uart3_pins: uart3_pins { ++ brcm,pins = <4 5>; ++ brcm,function = ; ++ brcm,pull = <0 2>; ++ }; ++ ++ uart4_pins: uart4_pins { ++ brcm,pins = <8 9>; ++ brcm,function = ; ++ brcm,pull = <0 2>; ++ }; ++ ++ uart5_pins: uart5_pins { ++ brcm,pins = <12 13>; ++ brcm,function = ; ++ brcm,pull = <0 2>; ++ }; ++ ++ audio_pins: audio_pins { ++ brcm,pins = <40 41>; ++ brcm,function = <4>; ++ }; ++}; ++ ++&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 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++/ { ++ __overrides__ { ++ act_led_gpio = <&act_led>,"gpios:4"; ++ 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"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2711.dtsi +@@ -0,0 +1,50 @@ ++#include "bcm2838.dtsi" ++#include "bcm270x.dtsi" ++#include "bcm2708-rpi.dtsi" ++ ++/ { ++ soc { ++ /delete-node/ mailbox@7e00b840; ++ /delete-node/ v3d@7ec00000; ++ }; ++ ++ __overrides__ { ++ arm_freq; ++ }; ++}; ++ ++&dma { ++ brcm,dma-channel-mask = <0x7ef5>; ++}; ++ ++&txp { ++ interrupts = ; ++}; ++ ++&firmwarekms { ++ interrupts = ; ++}; ++ ++&smi { ++ interrupts = ; ++}; ++ ++&mmc { ++ interrupts = ; ++}; ++ ++&mmcnr { ++ interrupts = ; ++}; ++ ++&usb { ++ reg = <0x7e980000 0x10000>, ++ <0x7e00b200 0x200>; ++ interrupts = , ++ ; ++}; ++ ++&gpio { ++ interrupts = , ++ ; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2838.dtsi +@@ -0,0 +1,724 @@ ++// SPDX-License-Identifier: GPL-2.0 ++#include "bcm283x.dtsi" ++ ++#include ++#include ++ ++/ { ++ compatible = "brcm,bcm2838", "brcm,bcm2837"; ++ ++ interrupt-parent = <&gicv2>; ++ ++ soc { ++ ranges = <0x7e000000 0x0 0xfe000000 0x01800000>, ++ <0x7c000000 0x0 0xfc000000 0x02000000>, ++ <0x40000000 0x0 0xff800000 0x00800000>; ++ /* Emulate a contiguous 30-bit address range for DMA */ ++ dma-ranges = <0xc0000000 0x0 0x00000000 0x3c000000>; ++ ++ /delete-node/ mailbox@7e00b840; ++ /delete-node/ interrupt-controller@7e00f300; ++ ++ local_intc: local_intc@40000000 { ++ compatible = "brcm,bcm2836-l1-intc"; ++ reg = <0x40000000 0x100>; ++ }; ++ ++ gicv2: gic400@40041000 { ++ interrupt-controller; ++ #interrupt-cells = <3>; ++ compatible = "arm,gic-400"; ++ reg = <0x40041000 0x1000>, ++ <0x40042000 0x2000>, ++ <0x40046000 0x2000>, ++ <0x40048000 0x2000>; ++ }; ++ ++ thermal: thermal@7d5d2200 { ++ compatible = "brcm,avs-tmon-bcm2838"; ++ reg = <0x7d5d2200 0x2c>; ++ interrupts = ; ++ interrupt-names = "tmon"; ++ clocks = <&clocks BCM2835_CLOCK_TSENS>; ++ #thermal-sensor-cells = <0>; ++ status = "okay"; ++ }; ++ ++ pm: watchdog@7e100000 { ++ reg = <0x7e100000 0x114>, ++ <0x7e00a000 0x24>, ++ <0x7ec11000 0x20>; ++ }; ++ ++ rng@7e104000 { ++ interrupts = ; ++ }; ++ ++ uart2: serial@7e201400 { ++ compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; ++ reg = <0x7e201400 0x200>; ++ interrupts = ; ++ clocks = <&clocks BCM2835_CLOCK_UART>, ++ <&clocks BCM2835_CLOCK_VPU>; ++ clock-names = "uartclk", "apb_pclk"; ++ arm,primecell-periphid = <0x00241011>; ++ status = "disabled"; ++ }; ++ ++ uart3: serial@7e201600 { ++ compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; ++ reg = <0x7e201600 0x200>; ++ interrupts = ; ++ clocks = <&clocks BCM2835_CLOCK_UART>, ++ <&clocks BCM2835_CLOCK_VPU>; ++ clock-names = "uartclk", "apb_pclk"; ++ arm,primecell-periphid = <0x00241011>; ++ status = "disabled"; ++ }; ++ ++ uart4: serial@7e201800 { ++ compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; ++ reg = <0x7e201800 0x200>; ++ interrupts = ; ++ clocks = <&clocks BCM2835_CLOCK_UART>, ++ <&clocks BCM2835_CLOCK_VPU>; ++ clock-names = "uartclk", "apb_pclk"; ++ arm,primecell-periphid = <0x00241011>; ++ status = "disabled"; ++ }; ++ ++ uart5: serial@7e201a00 { ++ compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; ++ reg = <0x7e201a00 0x200>; ++ interrupts = ; ++ clocks = <&clocks BCM2835_CLOCK_UART>, ++ <&clocks BCM2835_CLOCK_VPU>; ++ clock-names = "uartclk", "apb_pclk"; ++ arm,primecell-periphid = <0x00241011>; ++ status = "disabled"; ++ }; ++ ++ spi@7e204000 { ++ reg = <0x7e204000 0x0200>; ++ interrupts = ; ++ }; ++ ++ spi3: spi@7e204600 { ++ compatible = "brcm,bcm2835-spi"; ++ reg = <0x7e204600 0x0200>; ++ interrupts = ; ++ clocks = <&clocks BCM2835_CLOCK_VPU>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ spi4: spi@7e204800 { ++ compatible = "brcm,bcm2835-spi"; ++ reg = <0x7e204800 0x0200>; ++ interrupts = ; ++ clocks = <&clocks BCM2835_CLOCK_VPU>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ spi5: spi@7e204a00 { ++ compatible = "brcm,bcm2835-spi"; ++ reg = <0x7e204a00 0x0200>; ++ interrupts = ; ++ clocks = <&clocks BCM2835_CLOCK_VPU>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ spi6: spi@7e204c00 { ++ compatible = "brcm,bcm2835-spi"; ++ reg = <0x7e204c00 0x0200>; ++ interrupts = ; ++ clocks = <&clocks BCM2835_CLOCK_VPU>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ i2c3: i2c@7e205600 { ++ compatible = "brcm,bcm2835-i2c"; ++ reg = <0x7e205600 0x200>; ++ interrupts = ; ++ clocks = <&clocks BCM2835_CLOCK_VPU>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ i2c4: i2c@7e205800 { ++ compatible = "brcm,bcm2835-i2c"; ++ reg = <0x7e205800 0x200>; ++ interrupts = ; ++ clocks = <&clocks BCM2835_CLOCK_VPU>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ i2c5: i2c@7e205a00 { ++ compatible = "brcm,bcm2835-i2c"; ++ reg = <0x7e205a00 0x200>; ++ interrupts = ; ++ clocks = <&clocks BCM2835_CLOCK_VPU>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ i2c6: i2c@7e205c00 { ++ compatible = "brcm,bcm2835-i2c"; ++ reg = <0x7e205c00 0x200>; ++ interrupts = ; ++ clocks = <&clocks BCM2835_CLOCK_VPU>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ pixelvalve@7e206000 { ++ interrupts = ; ++ }; ++ ++ pixelvalve@7e207000 { ++ interrupts = ; ++ }; ++ ++ emmc2: emmc2@7e340000 { ++ compatible = "brcm,bcm2711-emmc2"; ++ status = "okay"; ++ interrupts = ; ++ clocks = <&clocks BCM2838_CLOCK_EMMC2>; ++ reg = <0x7e340000 0x100>; ++ }; ++ ++ hvs@7e400000 { ++ interrupts = ; ++ }; ++ ++ pixelvalve@7e807000 { ++ interrupts = ; ++ }; ++ }; ++ ++ arm-pmu { ++ /* ++ * N.B. the A72 PMU support only exists in arch/arm64, hence ++ * the fallback to the A53 version. ++ */ ++ compatible = "arm,cortex-a72-pmu", "arm,cortex-a53-pmu"; ++ interrupts = , ++ , ++ , ++ ; ++ }; ++ ++ timer { ++ compatible = "arm,armv7-timer"; ++ interrupts = , ++ , ++ , ++ ; ++ arm,cpu-registers-not-fw-configured; ++ always-on; ++ }; ++ ++ cpus: cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ enable-method = "brcm,bcm2836-smp"; // for ARM 32-bit ++ ++ cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a72"; ++ reg = <0>; ++ enable-method = "spin-table"; ++ cpu-release-addr = <0x0 0x000000d8>; ++ }; ++ ++ cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a72"; ++ reg = <1>; ++ enable-method = "spin-table"; ++ cpu-release-addr = <0x0 0x000000e0>; ++ }; ++ ++ cpu2: cpu@2 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a72"; ++ reg = <2>; ++ enable-method = "spin-table"; ++ cpu-release-addr = <0x0 0x000000e8>; ++ }; ++ ++ cpu3: cpu@3 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a72"; ++ reg = <3>; ++ enable-method = "spin-table"; ++ cpu-release-addr = <0x0 0x000000f0>; ++ }; ++ }; ++ ++ v3dbus { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0x7c500000 0x0 0xfc500000 0x03300000>, ++ <0x40000000 0x0 0xff800000 0x00800000>; ++ dma-ranges = <0x00000000 0x0 0x00000000 0x3c000000>; ++ ++ v3d: v3d@7ec04000 { ++ compatible = "brcm,2711-v3d"; ++ reg = ++ <0x7ec00000 0x4000>, ++ <0x7ec04000 0x4000>; ++ reg-names = "hub", "core0"; ++ ++ power-domains = <&pm BCM2835_POWER_DOMAIN_GRAFX_V3D>; ++ resets = <&pm BCM2835_RESET_V3D>; ++ clocks = <&clocks BCM2835_CLOCK_V3D>; ++ interrupts = ; ++ status = "okay"; ++ }; ++ }; ++ ++ scb: scb { ++ compatible = "simple-bus"; ++ #address-cells = <2>; ++ #size-cells = <1>; ++ ++ ranges = <0x0 0x7c000000 0x0 0xfc000000 0x03800000>, ++ <0x0 0x40000000 0x0 0xff800000 0x00800000>, ++ <0x6 0x00000000 0x6 0x00000000 0x40000000>, ++ <0x0 0x00000000 0x0 0x00000000 0xfc000000>; ++ dma-ranges = <0x0 0x00000000 0x0 0x00000000 0xfc000000>; ++ ++ pcie_0: pcie@7d500000 { ++ reg = <0x0 0x7d500000 0x9310>, ++ <0x0 0x7e00f300 0x20>; ++ msi-controller; ++ msi-parent = <&pcie_0>; ++ #address-cells = <3>; ++ #interrupt-cells = <1>; ++ #size-cells = <2>; ++ bus-range = <0x0 0x01>; ++ compatible = "brcm,bcm7211-pcie", "brcm,bcm7445-pcie", ++ "brcm,pci-plat-dev"; ++ max-link-speed = <2>; ++ tot-num-pcie = <1>; ++ linux,pci-domain = <0>; ++ interrupts = , ++ ; ++ interrupt-names = "pcie", "msi"; ++ interrupt-map-mask = <0x0 0x0 0x0 0x7>; ++ interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 143 ++ IRQ_TYPE_LEVEL_HIGH ++ 0 0 0 2 &gicv2 GIC_SPI 144 ++ IRQ_TYPE_LEVEL_HIGH ++ 0 0 0 3 &gicv2 GIC_SPI 145 ++ IRQ_TYPE_LEVEL_HIGH ++ 0 0 0 4 &gicv2 GIC_SPI 146 ++ IRQ_TYPE_LEVEL_HIGH>; ++ ++ /* Map outbound accesses from scb:0x6_00000000-03ffffff ++ * to pci:0x0_f8000000-fbffffff ++ */ ++ ranges = <0x02000000 0x0 0xf8000000 0x6 0x00000000 ++ 0x0 0x04000000>; ++ /* Map inbound accesses from pci:0x0_00000000..ffffffff ++ * to scb:0x0_00000000-ffffffff ++ */ ++ dma-ranges = <0x02000000 0x0 0x00000000 0x0 0x00000000 ++ 0x1 0x00000000>; ++ status = "okay"; ++ }; ++ ++ genet: genet@7d580000 { ++ compatible = "brcm,genet-v5"; ++ reg = <0x0 0x7d580000 0x10000>; ++ status = "okay"; ++ #address-cells = <0x1>; ++ #size-cells = <0x1>; ++ interrupts = , ++ ; ++ phy-handle = <&phy1>; ++ phy-mode = "rgmii"; ++ mdio@e14 { ++ #address-cells = <0x0>; ++ #size-cells = <0x1>; ++ compatible = "brcm,genet-mdio-v5"; ++ reg = <0xe14 0x8>; ++ reg-names = "mdio"; ++ phy1: genet-phy@0 { ++ compatible = ++ "ethernet-phy-ieee802.3-c22"; ++ /* No interrupts - use PHY_POLL */ ++ max-speed = <1000>; ++ reg = <0x1>; ++ }; ++ }; ++ }; ++ ++ xhci: xhci@7e9c0000 { ++ compatible = "generic-xhci"; ++ status = "disabled"; ++ reg = <0x0 0x7e9c0000 0x100000>; ++ interrupts = ; ++ }; ++ ++ vchiq: mailbox@7e00b840 { ++ compatible = "brcm,bcm2838-vchiq"; ++ reg = <0 0x7e00b840 0x3c>; ++ interrupts = ; ++ }; ++ ++ hevc-decoder@7eb00000 { ++ compatible = "raspberrypi,argon-hevc-decoder"; ++ reg = <0x0 0x7eb00000 0x10000>; ++ status = "okay"; ++ }; ++ ++ argon-local-intc@7eb10000 { ++ compatible = "raspberrypi,argon-local-intc"; ++ reg = <0x0 0x7eb10000 0x1000>; ++ status = "okay"; ++ interrupts = ; ++ }; ++ ++ h264-decoder@7eb20000 { ++ compatible = "raspberrypi,argon-h264-decoder"; ++ reg = <0x0 0x7eb20000 0x10000>; ++ status = "okay"; ++ }; ++ ++ vp9-decoder@7eb30000 { ++ compatible = "raspberrypi,argon-vp9-decoder"; ++ reg = <0x0 0x7eb30000 0x10000>; ++ status = "okay"; ++ }; ++ }; ++}; ++ ++&clk_osc { ++ clock-frequency = <54000000>; ++}; ++ ++&clocks { ++ compatible = "brcm,bcm2838-cprman"; ++}; ++ ++&cpu_thermal { ++ coefficients = <(-487) 410040>; ++}; ++ ++&dsi0 { ++ interrupts = ; ++}; ++ ++&dsi1 { ++ interrupts = ; ++}; ++ ++&gpio { ++ gpclk0_gpio49: gpclk0_gpio49 { ++ brcm,pins = <49>; ++ brcm,function = ; ++ brcm,pull = ; ++ }; ++ gpclk1_gpio50: gpclk1_gpio50 { ++ brcm,pins = <50>; ++ brcm,function = ; ++ brcm,pull = ; ++ }; ++ gpclk2_gpio51: gpclk2_gpio51 { ++ brcm,pins = <51>; ++ brcm,function = ; ++ brcm,pull = ; ++ }; ++ ++ i2c0_gpio46: i2c0_gpio46 { ++ brcm,pins = <46 47>; ++ brcm,function = ; ++ }; ++ i2c1_gpio46: i2c1_gpio46 { ++ brcm,pins = <46 47>; ++ brcm,function = ; ++ }; ++ i2c3_gpio2: i2c3_gpio2 { ++ brcm,pins = <2 3>; ++ brcm,function = ; ++ }; ++ i2c3_gpio4: i2c3_gpio4 { ++ brcm,pins = <4 5>; ++ brcm,function = ; ++ }; ++ i2c4_gpio6: i2c4_gpio6 { ++ brcm,pins = <6 7>; ++ brcm,function = ; ++ }; ++ i2c4_gpio8: i2c4_gpio8 { ++ brcm,pins = <8 9>; ++ brcm,function = ; ++ }; ++ i2c5_gpio10: i2c5_gpio10 { ++ brcm,pins = <10 11>; ++ brcm,function = ; ++ }; ++ i2c5_gpio12: i2c5_gpio12 { ++ brcm,pins = <12 13>; ++ brcm,function = ; ++ }; ++ i2c6_gpio0: i2c6_gpio0 { ++ brcm,pins = <0 1>; ++ brcm,function = ; ++ }; ++ i2c6_gpio22: i2c6_gpio22 { ++ brcm,pins = <22 23>; ++ brcm,function = ; ++ }; ++ i2c_slave_gpio8: i2c_slave_gpio8 { ++ brcm,pins = <8 9 10 11>; ++ brcm,function = ; ++ }; ++ ++ jtag_gpio48: jtag_gpio48 { ++ brcm,pins = <48 49 50 51 52 53>; ++ brcm,function = ; ++ }; ++ ++ mii_gpio28: mii_gpio28 { ++ brcm,pins = <28 29 30 31>; ++ brcm,function = ; ++ }; ++ mii_gpio36: mii_gpio36 { ++ brcm,pins = <36 37 38 39>; ++ brcm,function = ; ++ }; ++ ++ pcm_gpio50: pcm_gpio50 { ++ brcm,pins = <50 51 52 53>; ++ brcm,function = ; ++ }; ++ ++ pwm0_gpio52: pwm0_gpio52 { ++ brcm,pins = <52>; ++ brcm,function = ; ++ brcm,pull = ; ++ }; ++ pwm1_gpio53: pwm1_gpio53 { ++ brcm,pins = <53>; ++ brcm,function = ; ++ brcm,pull = ; ++ }; ++ ++ /* The following group consists of: ++ * RGMII_START_STOP ++ * RGMII_RX_OK ++ */ ++ rgmii_gpio35: rgmii_gpio35 { ++ brcm,pins = <35 36>; ++ brcm,function = ; ++ }; ++ rgmii_irq_gpio34: rgmii_irq_gpio34 { ++ brcm,pins = <34>; ++ brcm,function = ; ++ }; ++ rgmii_irq_gpio39: rgmii_irq_gpio39 { ++ brcm,pins = <39>; ++ brcm,function = ; ++ }; ++ rgmii_mdio_gpio28: rgmii_mdio_gpio28 { ++ brcm,pins = <28 29>; ++ brcm,function = ; ++ }; ++ rgmii_mdio_gpio37: rgmii_mdio_gpio37 { ++ brcm,pins = <37 38>; ++ brcm,function = ; ++ }; ++ ++ spi0_gpio46: spi0_gpio46 { ++ brcm,pins = <46 47 48 49>; ++ brcm,function = ; ++ }; ++ spi2_gpio46: spi2_gpio46 { ++ brcm,pins = <46 47 48 49 50>; ++ brcm,function = ; ++ }; ++ spi3_gpio0: spi3_gpio0 { ++ brcm,pins = <0 1 2 3>; ++ brcm,function = ; ++ }; ++ spi4_gpio4: spi4_gpio4 { ++ brcm,pins = <4 5 6 7>; ++ brcm,function = ; ++ }; ++ spi5_gpio12: spi5_gpio12 { ++ brcm,pins = <12 13 14 15>; ++ brcm,function = ; ++ }; ++ spi6_gpio18: spi6_gpio18 { ++ brcm,pins = <18 19 20 21>; ++ brcm,function = ; ++ }; ++ ++ uart2_gpio0: uart2_gpio0 { ++ brcm,pins = <0 1>; ++ brcm,function = ; ++ brcm,pull = ; ++ }; ++ uart2_ctsrts_gpio2: uart2_ctsrts_gpio2 { ++ brcm,pins = <2 3>; ++ brcm,function = ; ++ brcm,pull = ; ++ }; ++ uart3_gpio4: uart3_gpio4 { ++ brcm,pins = <4 5>; ++ brcm,function = ; ++ brcm,pull = ; ++ }; ++ uart3_ctsrts_gpio6: uart3_ctsrts_gpio6 { ++ brcm,pins = <6 7>; ++ brcm,function = ; ++ brcm,pull = ; ++ }; ++ uart4_gpio8: uart4_gpio8 { ++ brcm,pins = <8 9>; ++ brcm,function = ; ++ brcm,pull = ; ++ }; ++ uart4_ctsrts_gpio10: uart4_ctsrts_gpio10 { ++ brcm,pins = <10 11>; ++ brcm,function = ; ++ brcm,pull = ; ++ }; ++ uart5_gpio12: uart5_gpio12 { ++ brcm,pins = <12 13>; ++ brcm,function = ; ++ brcm,pull = ; ++ }; ++ uart5_ctsrts_gpio14: uart5_ctsrts_gpio14 { ++ brcm,pins = <14 15>; ++ brcm,function = ; ++ brcm,pull = ; ++ }; ++}; ++ ++&vec { ++ interrupts = ; ++}; ++ ++&usb { ++ interrupts = ; ++}; ++ ++&hdmi { ++ interrupts = , ++ ; ++}; ++ ++&uart1 { ++ interrupts = ; ++}; ++ ++&spi1 { ++ interrupts = ; ++}; ++ ++&spi2 { ++ interrupts = ; ++}; ++ ++&csi0 { ++ interrupts = ; ++}; ++ ++&csi1 { ++ interrupts = ; ++}; ++ ++&sdhci { ++ interrupts = ; ++}; ++ ++&i2c0 { ++ interrupts = ; ++}; ++ ++&i2c1 { ++ interrupts = ; ++}; ++ ++&i2c2 { ++ interrupts = ; ++}; ++ ++&gpio { ++ interrupts = , ++ , ++ , ++ ; ++}; ++ ++&mailbox { ++ interrupts = ; ++}; ++ ++&rng { ++ compatible = "brcm,bcm2838-rng200"; ++}; ++ ++&sdhost { ++ interrupts = ; ++}; ++ ++&uart0 { ++ interrupts = ; ++}; ++ ++&dma { ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , /* dmalite 7 */ ++ , /* dmalite 8 */ ++ , /* dmalite 9 */ ++ , /* dmalite 10 */ ++ /* DMA4 - 40 bit DMA engines */ ++ , /* dma4 11 */ ++ , /* dma4 12 */ ++ , /* dma4 13 */ ++ ; /* dma4 14 */ ++ interrupt-names = "dma0", ++ "dma1", ++ "dma2", ++ "dma3", ++ "dma4", ++ "dma5", ++ "dma6", ++ "dma7", ++ "dma8", ++ "dma9", ++ "dma10", ++ "dma11", ++ "dma12", ++ "dma13", ++ "dma14"; ++ brcm,dma-channel-mask = <0x7ef5>; ++}; diff --git a/target/linux/brcm2708/patches-4.19/950-0635-staging-vcsm-cma-Drop-logging-level-on-messages-in-v.patch b/target/linux/brcm2708/patches-4.19/950-0635-staging-vcsm-cma-Drop-logging-level-on-messages-in-v.patch deleted file mode 100644 index 113289b3ad..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0635-staging-vcsm-cma-Drop-logging-level-on-messages-in-v.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 800cd6716ba60faf5f1782935c12b12943237de4 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 16 May 2019 15:17:19 +0100 -Subject: [PATCH 635/703] staging: vcsm-cma: Drop logging level on messages in - vc_sm_release_resource - -They weren't errors but were logged as such. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -301,14 +301,13 @@ static void vc_sm_release_resource(struc - - if (buffer->vc_handle) { - /* We've sent the unmap request but not had the response. */ -- pr_err("[%s]: Waiting for VPU unmap response on %p\n", -- __func__, buffer); -+ pr_debug("[%s]: Waiting for VPU unmap response on %p\n", -+ __func__, buffer); - goto defer; - } - if (buffer->in_use) { - /* dmabuf still in use - we await the release */ -- pr_err("[%s]: buffer %p is still in use\n", -- __func__, buffer); -+ pr_debug("[%s]: buffer %p is still in use\n", __func__, buffer); - goto defer; - } - diff --git a/target/linux/brcm2708/patches-4.19/950-0636-overlays-Add-i2c3-6-and-uart2-5-overlays.patch b/target/linux/brcm2708/patches-4.19/950-0636-overlays-Add-i2c3-6-and-uart2-5-overlays.patch new file mode 100644 index 0000000000..901e309b8b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0636-overlays-Add-i2c3-6-and-uart2-5-overlays.patch @@ -0,0 +1,359 @@ +From 9bb7aa6a108469e331bc46513c317f088b720880 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 30 May 2019 16:44:24 +0100 +Subject: [PATCH 636/725] overlays: Add i2c3-6 and uart2-5 overlays + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/Makefile | 8 +++ + arch/arm/boot/dts/overlays/README | 52 ++++++++++++++++++++ + arch/arm/boot/dts/overlays/i2c3-overlay.dts | 27 ++++++++++ + arch/arm/boot/dts/overlays/i2c4-overlay.dts | 27 ++++++++++ + arch/arm/boot/dts/overlays/i2c5-overlay.dts | 27 ++++++++++ + arch/arm/boot/dts/overlays/i2c6-overlay.dts | 27 ++++++++++ + arch/arm/boot/dts/overlays/uart2-overlay.dts | 27 ++++++++++ + arch/arm/boot/dts/overlays/uart3-overlay.dts | 27 ++++++++++ + arch/arm/boot/dts/overlays/uart4-overlay.dts | 27 ++++++++++ + arch/arm/boot/dts/overlays/uart5-overlay.dts | 27 ++++++++++ + 10 files changed, 276 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/i2c3-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/i2c4-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/i2c5-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/i2c6-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/uart2-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/uart3-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/uart4-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/uart5-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -65,6 +65,10 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + i2c-sensor.dtbo \ + i2c0-bcm2708.dtbo \ + i2c1-bcm2708.dtbo \ ++ i2c3.dtbo \ ++ i2c4.dtbo \ ++ i2c5.dtbo \ ++ i2c6.dtbo \ + i2s-gpio28-31.dtbo \ + ilitek251x.dtbo \ + iqaudio-codec.dtbo \ +@@ -149,6 +153,10 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + tpm-slb9670.dtbo \ + uart0.dtbo \ + uart1.dtbo \ ++ uart2.dtbo \ ++ uart3.dtbo \ ++ uart4.dtbo \ ++ uart5.dtbo \ + udrc.dtbo \ + upstream.dtbo \ + vc4-fkms-v3d.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1137,6 +1137,34 @@ Params: sda1_pin GPIO pin + "yes") + + ++Name: i2c3 ++Info: Enable the i2c3 bus ++Load: dtoverlay=i2c3, ++Params: pins_2_3 Use GPIOs 2 and 3 ++ pins_4_5 Use GPIOs 4 and 5 (default) ++ ++ ++Name: i2c4 ++Info: Enable the i2c4 bus ++Load: dtoverlay=i2c4, ++Params: pins_6_7 Use GPIOs 6 and 7 ++ pins_8_9 Use GPIOs 8 and 9 (default) ++ ++ ++Name: i2c5 ++Info: Enable the i2c5 bus ++Load: dtoverlay=i2c5, ++Params: pins_10_11 Use GPIOs 10 and 11 ++ pins_12_13 Use GPIOs 12 and 13 (default) ++ ++ ++Name: i2c6 ++Info: Enable the i2c6 bus ++Load: dtoverlay=i2c6, ++Params: pins_0_1 Use GPIOs 0 and 1 ++ pins_22_23 Use GPIOs 22 and 23 (default) ++ ++ + Name: i2s-gpio28-31 + Info: move I2S function block to GPIO 28 to 31 + Load: dtoverlay=i2s-gpio28-31 +@@ -2199,6 +2227,30 @@ Params: txd1_pin GPIO pin + rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) + + ++Name: uart2 ++Info: Enable uart 2 on GPIOs 0-3 ++Load: dtoverlay=uart2, ++Params: ctsrts Enable CTS/RTS on GPIOs 2-3 (default off) ++ ++ ++Name: uart3 ++Info: Enable uart 3 on GPIOs 4-7 ++Load: dtoverlay=uart3, ++Params: ctsrts Enable CTS/RTS on GPIOs 6-7 (default off) ++ ++ ++Name: uart4 ++Info: Enable uart 4 on GPIOs 8-11 ++Load: dtoverlay=uart4, ++Params: ctsrts Enable CTS/RTS on GPIOs 10-11 (default off) ++ ++ ++Name: uart5 ++Info: Enable uart 5 on GPIOs 12-15 ++Load: dtoverlay=uart5, ++Params: ctsrts Enable CTS/RTS on GPIOs 14-15 (default off) ++ ++ + Name: udrc + Info: Configures the NW Digital Radio UDRC Hat + Load: dtoverlay=udrc,= +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2c3-overlay.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2838"; ++ ++ fragment@0 { ++ target = <&i2c3>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c3_pins>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c3_pins>; ++ __dormant__ { ++ brcm,pins = <2 3>; ++ }; ++ }; ++ ++ __overrides__ { ++ pins_2_3 = <0>,"=1"; ++ pins_4_5 = <0>,"!1"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2c4-overlay.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2838"; ++ ++ fragment@0 { ++ target = <&i2c4>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c4_pins>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c4_pins>; ++ __dormant__ { ++ brcm,pins = <6 7>; ++ }; ++ }; ++ ++ __overrides__ { ++ pins_6_7 = <0>,"=1"; ++ pins_8_9 = <0>,"!1"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2c5-overlay.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2838"; ++ ++ fragment@0 { ++ target = <&i2c5>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c5_pins>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c5_pins>; ++ __dormant__ { ++ brcm,pins = <10 11>; ++ }; ++ }; ++ ++ __overrides__ { ++ pins_10_11 = <0>,"=1"; ++ pins_12_13 = <0>,"!1"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2c6-overlay.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2838"; ++ ++ fragment@0 { ++ target = <&i2c6>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c6_pins>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c6_pins>; ++ __dormant__ { ++ brcm,pins = <0 1>; ++ }; ++ }; ++ ++ __overrides__ { ++ pins_0_1 = <0>,"=1"; ++ pins_22_23 = <0>,"!1"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/uart2-overlay.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2838"; ++ ++ fragment@0 { ++ target = <&uart2>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart2_pins>; ++ __dormant__ { ++ brcm,pins = <0 1 2 3>; ++ brcm,pull = <0 2 2 0>; ++ }; ++ }; ++ ++ __overrides__ { ++ ctsrts = <0>,"=1"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/uart3-overlay.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2838"; ++ ++ fragment@0 { ++ target = <&uart3>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart3_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart3_pins>; ++ __dormant__ { ++ brcm,pins = <4 5 6 7>; ++ brcm,pull = <0 2 2 0>; ++ }; ++ }; ++ ++ __overrides__ { ++ ctsrts = <0>,"=1"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/uart4-overlay.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2838"; ++ ++ fragment@0 { ++ target = <&uart4>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart4_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart4_pins>; ++ __dormant__ { ++ brcm,pins = <8 9 10 11>; ++ brcm,pull = <0 2 2 0>; ++ }; ++ }; ++ ++ __overrides__ { ++ ctsrts = <0>,"=1"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/uart5-overlay.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2838"; ++ ++ fragment@0 { ++ target = <&uart5>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart5_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart5_pins>; ++ __dormant__ { ++ brcm,pins = <12 13 14 15>; ++ brcm,pull = <0 2 2 0>; ++ }; ++ }; ++ ++ __overrides__ { ++ ctsrts = <0>,"=1"; ++ }; ++}; diff --git a/target/linux/brcm2708/patches-4.19/950-0636-staging-vcsm-cma-Fixup-the-alloc-code-handling-of-ke.patch b/target/linux/brcm2708/patches-4.19/950-0636-staging-vcsm-cma-Fixup-the-alloc-code-handling-of-ke.patch deleted file mode 100644 index ba334b5af5..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0636-staging-vcsm-cma-Fixup-the-alloc-code-handling-of-ke.patch +++ /dev/null @@ -1,35 +0,0 @@ -From bc7d2e33c324c77c13ecc7699342a72f52cf0789 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 22 May 2019 15:40:37 +0100 -Subject: [PATCH 636/703] staging: vcsm-cma: Fixup the alloc code handling of - kernel_id - -The allocation code had been copied in from an old branch prior -to having added the IDR for 64bit support. It was therefore pushing -a pointer into the kernel_id field instead of an IDR handle, the -lookup therefore failed, and we never released the buffer. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -1206,7 +1206,7 @@ int vc_sm_cma_ioctl_alloc(struct vc_sm_p - - import.addr = (uint32_t)sg_dma_address(buffer->sg_table->sgl); - import.size = aligned_size; -- import.kernel_id = (uint32_t)buffer; -+ import.kernel_id = get_kernel_id(buffer); - - /* Wrap it into a videocore buffer. */ - status = vc_sm_cma_vchi_import(sm_state->sm_handle, &import, &result, -@@ -1231,6 +1231,7 @@ int vc_sm_cma_ioctl_alloc(struct vc_sm_p - buffer->size = import.size; - buffer->dma_addr = import.addr; - buffer->vpu_state = VPU_MAPPED; -+ buffer->kernel_id = import.kernel_id; - //buffer->res_cached = ioparam->cached; - - fd = dma_buf_fd(dmabuf, O_CLOEXEC); diff --git a/target/linux/brcm2708/patches-4.19/950-0637-Pulled-in-the-multi-frame-buffer-support-from-the-Pi.patch b/target/linux/brcm2708/patches-4.19/950-0637-Pulled-in-the-multi-frame-buffer-support-from-the-Pi.patch deleted file mode 100644 index 3dfcca4083..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0637-Pulled-in-the-multi-frame-buffer-support-from-the-Pi.patch +++ /dev/null @@ -1,925 +0,0 @@ -From 03f6bc683489b9652491d981b83448863230068c Mon Sep 17 00:00:00 2001 -From: James Hughes -Date: Thu, 14 Mar 2019 13:27:54 +0000 -Subject: [PATCH 637/703] Pulled in the multi frame buffer support from the Pi3 - repo - ---- - drivers/video/fbdev/bcm2708_fb.c | 580 +++++++++++++++------ - include/soc/bcm2835/raspberrypi-firmware.h | 4 + - 2 files changed, 432 insertions(+), 152 deletions(-) - ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -2,6 +2,7 @@ - * linux/drivers/video/bcm2708_fb.c - * - * Copyright (C) 2010 Broadcom -+ * Copyright (C) 2018 Raspberry Pi (Trading) Ltd - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive -@@ -13,6 +14,7 @@ - * Copyright 1999-2001 Jeff Garzik - * - */ -+ - #include - #include - #include -@@ -36,6 +38,7 @@ - #include - #include - #include -+#include - - //#define BCM2708_FB_DEBUG - #define MODULE_NAME "bcm2708_fb" -@@ -82,62 +85,139 @@ struct bcm2708_fb_stats { - u32 dma_irqs; - }; - -+struct vc4_display_settings_t { -+ u32 display_num; -+ u32 width; -+ u32 height; -+ u32 pitch; -+ u32 depth; -+ u32 virtual_width; -+ u32 virtual_height; -+ u32 virtual_width_offset; -+ u32 virtual_height_offset; -+ unsigned long fb_bus_address; -+}; -+ -+struct bcm2708_fb_dev; -+ - struct bcm2708_fb { - struct fb_info fb; - struct platform_device *dev; -- struct rpi_firmware *fw; - u32 cmap[16]; - u32 gpu_cmap[256]; -+ struct dentry *debugfs_dir; -+ struct dentry *debugfs_subdir; -+ unsigned long fb_bus_address; -+ struct { u32 base, length; } gpu; -+ struct vc4_display_settings_t display_settings; -+ struct debugfs_regset32 screeninfo_regset; -+ struct bcm2708_fb_dev *fbdev; -+ unsigned int image_size; -+ dma_addr_t dma_addr; -+ void *cpuaddr; -+}; -+ -+#define MAX_FRAMEBUFFERS 3 -+ -+struct bcm2708_fb_dev { -+ int firmware_supports_multifb; -+ /* Protects the DMA system from multiple FB access */ -+ struct mutex dma_mutex; - int dma_chan; - int dma_irq; - void __iomem *dma_chan_base; -- void *cb_base; /* DMA control blocks */ -- dma_addr_t cb_handle; -- struct dentry *debugfs_dir; - wait_queue_head_t dma_waitq; -- struct bcm2708_fb_stats stats; -- unsigned long fb_bus_address; -- struct { u32 base, length; } gpu; -+ bool disable_arm_alloc; -+ struct bcm2708_fb_stats dma_stats; -+ void *cb_base; /* DMA control blocks */ -+ dma_addr_t cb_handle; -+ int instance_count; -+ int num_displays; -+ struct rpi_firmware *fw; -+ struct bcm2708_fb displays[MAX_FRAMEBUFFERS]; - }; - - #define to_bcm2708(info) container_of(info, struct bcm2708_fb, fb) - - static void bcm2708_fb_debugfs_deinit(struct bcm2708_fb *fb) - { -- debugfs_remove_recursive(fb->debugfs_dir); -- fb->debugfs_dir = NULL; -+ debugfs_remove_recursive(fb->debugfs_subdir); -+ fb->debugfs_subdir = NULL; -+ -+ fb->fbdev->instance_count--; -+ -+ if (!fb->fbdev->instance_count) { -+ debugfs_remove_recursive(fb->debugfs_dir); -+ fb->debugfs_dir = NULL; -+ } - } - - static int bcm2708_fb_debugfs_init(struct bcm2708_fb *fb) - { -+ char buf[3]; -+ struct bcm2708_fb_dev *fbdev = fb->fbdev; -+ - static struct debugfs_reg32 stats_registers[] = { -- { -- "dma_copies", -- offsetof(struct bcm2708_fb_stats, dma_copies) -- }, -- { -- "dma_irqs", -- offsetof(struct bcm2708_fb_stats, dma_irqs) -- }, -+ {"dma_copies", offsetof(struct bcm2708_fb_stats, dma_copies)}, -+ {"dma_irqs", offsetof(struct bcm2708_fb_stats, dma_irqs)}, - }; - -- fb->debugfs_dir = debugfs_create_dir(DRIVER_NAME, NULL); -+ static struct debugfs_reg32 screeninfo[] = { -+ {"width", offsetof(struct fb_var_screeninfo, xres)}, -+ {"height", offsetof(struct fb_var_screeninfo, yres)}, -+ {"bpp", offsetof(struct fb_var_screeninfo, bits_per_pixel)}, -+ {"xres_virtual", offsetof(struct fb_var_screeninfo, xres_virtual)}, -+ {"yres_virtual", offsetof(struct fb_var_screeninfo, yres_virtual)}, -+ {"xoffset", offsetof(struct fb_var_screeninfo, xoffset)}, -+ {"yoffset", offsetof(struct fb_var_screeninfo, yoffset)}, -+ }; -+ -+ fb->debugfs_dir = debugfs_lookup(DRIVER_NAME, NULL); -+ -+ if (!fb->debugfs_dir) -+ fb->debugfs_dir = debugfs_create_dir(DRIVER_NAME, NULL); -+ - if (!fb->debugfs_dir) { -- pr_warn("%s: could not create debugfs entry\n", -- __func__); -+ dev_warn(fb->fb.dev, "%s: could not create debugfs folder\n", -+ __func__); -+ return -EFAULT; -+ } -+ -+ snprintf(buf, sizeof(buf), "%u", fb->display_settings.display_num); -+ -+ fb->debugfs_subdir = debugfs_create_dir(buf, fb->debugfs_dir); -+ -+ if (!fb->debugfs_subdir) { -+ dev_warn(fb->fb.dev, "%s: could not create debugfs entry %u\n", -+ __func__, fb->display_settings.display_num); - return -EFAULT; - } - -- fb->stats.regset.regs = stats_registers; -- fb->stats.regset.nregs = ARRAY_SIZE(stats_registers); -- fb->stats.regset.base = &fb->stats; -- -- if (!debugfs_create_regset32("stats", 0444, fb->debugfs_dir, -- &fb->stats.regset)) { -- pr_warn("%s: could not create statistics registers\n", -- __func__); -+ fbdev->dma_stats.regset.regs = stats_registers; -+ fbdev->dma_stats.regset.nregs = ARRAY_SIZE(stats_registers); -+ fbdev->dma_stats.regset.base = &fbdev->dma_stats; -+ -+ if (!debugfs_create_regset32("dma_stats", 0444, fb->debugfs_subdir, -+ &fbdev->dma_stats.regset)) { -+ dev_warn(fb->fb.dev, "%s: could not create statistics registers\n", -+ __func__); -+ goto fail; -+ } -+ -+ fb->screeninfo_regset.regs = screeninfo; -+ fb->screeninfo_regset.nregs = ARRAY_SIZE(screeninfo); -+ fb->screeninfo_regset.base = &fb->fb.var; -+ -+ if (!debugfs_create_regset32("screeninfo", 0444, fb->debugfs_subdir, -+ &fb->screeninfo_regset)) { -+ dev_warn(fb->fb.dev, -+ "%s: could not create dimensions registers\n", -+ __func__); - goto fail; - } -+ -+ fbdev->instance_count++; -+ - return 0; - - fail: -@@ -145,6 +225,20 @@ fail: - return -EFAULT; - } - -+static void set_display_num(struct bcm2708_fb *fb) -+{ -+ if (fb && fb->fbdev && fb->fbdev->firmware_supports_multifb) { -+ u32 tmp = fb->display_settings.display_num; -+ -+ if (rpi_firmware_property(fb->fbdev->fw, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM, -+ &tmp, -+ sizeof(tmp))) -+ dev_warn_once(fb->fb.dev, -+ "Set display number call failed. Old GPU firmware?"); -+ } -+} -+ - static int bcm2708_fb_set_bitfields(struct fb_var_screeninfo *var) - { - int ret = 0; -@@ -222,11 +316,11 @@ static int bcm2708_fb_check_var(struct f - struct fb_info *info) - { - /* info input, var output */ -- print_debug("%s(%p) %dx%d (%dx%d), %d, %d\n", -+ print_debug("%s(%p) %ux%u (%ux%u), %ul, %u\n", - __func__, info, info->var.xres, info->var.yres, - info->var.xres_virtual, info->var.yres_virtual, -- (int)info->screen_size, info->var.bits_per_pixel); -- print_debug("%s(%p) %dx%d (%dx%d), %d\n", __func__, var, var->xres, -+ info->screen_size, info->var.bits_per_pixel); -+ print_debug("%s(%p) %ux%u (%ux%u), %u\n", __func__, var, var->xres, - var->yres, var->xres_virtual, var->yres_virtual, - var->bits_per_pixel); - -@@ -283,23 +377,96 @@ static int bcm2708_fb_set_par(struct fb_ - .xoffset = info->var.xoffset, - .yoffset = info->var.yoffset, - .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 }, -- .base = 0, -- .screen_size = 0, -- .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH, 4, 0 }, -- .pitch = 0, -+ /* base and screen_size will be initialised later */ -+ .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH, 4, 0 }, -+ /* pitch will be initialised later */ - }; -- int ret; -+ int ret, image_size; -+ - -- print_debug("%s(%p) %dx%d (%dx%d), %d, %d\n", __func__, info, -+ print_debug("%s(%p) %dx%d (%dx%d), %d, %d (display %d)\n", __func__, -+ info, - info->var.xres, info->var.yres, info->var.xres_virtual, - info->var.yres_virtual, (int)info->screen_size, -- info->var.bits_per_pixel); -+ info->var.bits_per_pixel, value); -+ -+ /* Need to set the display number to act on first -+ * Cannot do it in the tag list because on older firmware the call -+ * will fail and stop the rest of the list being executed. -+ * We can ignore this call failing as the default at other end is 0 -+ */ -+ set_display_num(fb); -+ -+ /* Try allocating our own buffer. We can specify all the parameters */ -+ image_size = ((info->var.xres * info->var.yres) * -+ info->var.bits_per_pixel) >> 3; -+ -+ if (!fb->fbdev->disable_arm_alloc && -+ (image_size != fb->image_size || !fb->dma_addr)) { -+ if (fb->dma_addr) { -+ dma_free_coherent(info->device, fb->image_size, -+ fb->cpuaddr, fb->dma_addr); -+ fb->image_size = 0; -+ fb->cpuaddr = NULL; -+ fb->dma_addr = 0; -+ } -+ -+ fb->cpuaddr = dma_alloc_coherent(info->device, image_size, -+ &fb->dma_addr, GFP_KERNEL); -+ -+ if (!fb->cpuaddr) { -+ fb->dma_addr = 0; -+ fb->fbdev->disable_arm_alloc = true; -+ } else { -+ fb->image_size = image_size; -+ } -+ } -+ -+ if (fb->cpuaddr) { -+ fbinfo.base = fb->dma_addr; -+ fbinfo.screen_size = image_size; -+ fbinfo.pitch = (info->var.xres * info->var.bits_per_pixel) >> 3; -+ -+ ret = rpi_firmware_property_list(fb->fbdev->fw, &fbinfo, -+ sizeof(fbinfo)); -+ if (ret || fbinfo.base != fb->dma_addr) { -+ /* Firmware either failed, or assigned a different base -+ * address (ie it doesn't support being passed an FB -+ * allocation). -+ * Destroy the allocation, and don't try again. -+ */ -+ dma_free_coherent(info->device, fb->image_size, -+ fb->cpuaddr, fb->dma_addr); -+ fb->image_size = 0; -+ fb->cpuaddr = NULL; -+ fb->dma_addr = 0; -+ fb->fbdev->disable_arm_alloc = true; -+ } -+ } else { -+ /* Our allocation failed - drop into the old scheme of -+ * allocation by the VPU. -+ */ -+ ret = -ENOMEM; -+ } - -- ret = rpi_firmware_property_list(fb->fw, &fbinfo, sizeof(fbinfo)); - if (ret) { -- dev_err(info->device, -- "Failed to allocate GPU framebuffer (%d)\n", ret); -- return ret; -+ /* Old scheme: -+ * - FRAMEBUFFER_ALLOCATE passes 0 for base and screen_size. -+ * - GET_PITCH instead of SET_PITCH. -+ */ -+ fbinfo.base = 0; -+ fbinfo.screen_size = 0; -+ fbinfo.tag6.tag = RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH; -+ fbinfo.pitch = 0; -+ -+ ret = rpi_firmware_property_list(fb->fbdev->fw, &fbinfo, -+ sizeof(fbinfo)); -+ if (ret) { -+ dev_err(info->device, -+ "Failed to allocate GPU framebuffer (%d)\n", -+ ret); -+ return ret; -+ } - } - - if (info->var.bits_per_pixel <= 8) -@@ -314,9 +481,17 @@ static int bcm2708_fb_set_par(struct fb_ - fb->fb.fix.smem_start = fbinfo.base; - fb->fb.fix.smem_len = fbinfo.pitch * fbinfo.yres_virtual; - fb->fb.screen_size = fbinfo.screen_size; -- if (fb->fb.screen_base) -- iounmap(fb->fb.screen_base); -- fb->fb.screen_base = ioremap_wc(fbinfo.base, fb->fb.screen_size); -+ -+ if (!fb->dma_addr) { -+ if (fb->fb.screen_base) -+ iounmap(fb->fb.screen_base); -+ -+ fb->fb.screen_base = ioremap_wc(fbinfo.base, -+ fb->fb.screen_size); -+ } else { -+ fb->fb.screen_base = fb->cpuaddr; -+ } -+ - if (!fb->fb.screen_base) { - /* the console may currently be locked */ - console_trylock(); -@@ -374,7 +549,10 @@ static int bcm2708_fb_setcolreg(unsigned - packet->length = regno + 1; - memcpy(packet->cmap, fb->gpu_cmap, - sizeof(packet->cmap)); -- ret = rpi_firmware_property(fb->fw, -+ -+ set_display_num(fb); -+ -+ ret = rpi_firmware_property(fb->fbdev->fw, - RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE, - packet, - (2 + packet->length) * sizeof(u32)); -@@ -413,8 +591,11 @@ static int bcm2708_fb_blank(int blank_mo - return -EINVAL; - } - -- ret = rpi_firmware_property(fb->fw, RPI_FIRMWARE_FRAMEBUFFER_BLANK, -+ set_display_num(fb); -+ -+ ret = rpi_firmware_property(fb->fbdev->fw, RPI_FIRMWARE_FRAMEBUFFER_BLANK, - &value, sizeof(value)); -+ - if (ret) - dev_err(info->device, "%s(%d) failed: %d\n", __func__, - blank_mode, ret); -@@ -431,7 +612,7 @@ static int bcm2708_fb_pan_display(struct - info->var.yoffset = var->yoffset; - result = bcm2708_fb_set_par(info); - if (result != 0) -- pr_err("%s(%d,%d) returns=%d\n", __func__, var->xoffset, -+ pr_err("%s(%u,%u) returns=%d\n", __func__, var->xoffset, - var->yoffset, result); - return result; - } -@@ -439,8 +620,9 @@ static int bcm2708_fb_pan_display(struct - static void dma_memcpy(struct bcm2708_fb *fb, dma_addr_t dst, dma_addr_t src, - int size) - { -- int burst_size = (fb->dma_chan == 0) ? 8 : 2; -- struct bcm2708_dma_cb *cb = fb->cb_base; -+ struct bcm2708_fb_dev *fbdev = fb->fbdev; -+ struct bcm2708_dma_cb *cb = fbdev->cb_base; -+ int burst_size = (fbdev->dma_chan == 0) ? 8 : 2; - - cb->info = BCM2708_DMA_BURST(burst_size) | BCM2708_DMA_S_WIDTH | - BCM2708_DMA_S_INC | BCM2708_DMA_D_WIDTH | -@@ -453,21 +635,27 @@ static void dma_memcpy(struct bcm2708_fb - cb->pad[1] = 0; - cb->next = 0; - -+ // Not sure what to do if this gets a signal whilst waiting -+ if (mutex_lock_interruptible(&fbdev->dma_mutex)) -+ return; -+ - if (size < dma_busy_wait_threshold) { -- bcm_dma_start(fb->dma_chan_base, fb->cb_handle); -- bcm_dma_wait_idle(fb->dma_chan_base); -+ bcm_dma_start(fbdev->dma_chan_base, fbdev->cb_handle); -+ bcm_dma_wait_idle(fbdev->dma_chan_base); - } else { -- void __iomem *dma_chan = fb->dma_chan_base; -+ void __iomem *local_dma_chan = fbdev->dma_chan_base; - - cb->info |= BCM2708_DMA_INT_EN; -- bcm_dma_start(fb->dma_chan_base, fb->cb_handle); -- while (bcm_dma_is_busy(dma_chan)) { -- wait_event_interruptible(fb->dma_waitq, -- !bcm_dma_is_busy(dma_chan)); -+ bcm_dma_start(fbdev->dma_chan_base, fbdev->cb_handle); -+ while (bcm_dma_is_busy(local_dma_chan)) { -+ wait_event_interruptible(fbdev->dma_waitq, -+ !bcm_dma_is_busy(local_dma_chan)); - } -- fb->stats.dma_irqs++; -+ fbdev->dma_stats.dma_irqs++; - } -- fb->stats.dma_copies++; -+ fbdev->dma_stats.dma_copies++; -+ -+ mutex_unlock(&fbdev->dma_mutex); - } - - /* address with no aliases */ -@@ -542,10 +730,13 @@ static int bcm2708_ioctl(struct fb_info - - switch (cmd) { - case FBIO_WAITFORVSYNC: -- ret = rpi_firmware_property(fb->fw, -+ set_display_num(fb); -+ -+ ret = rpi_firmware_property(fb->fbdev->fw, - RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC, - &dummy, sizeof(dummy)); - break; -+ - case FBIODMACOPY: - { - struct fb_dmacopy ioparam; -@@ -615,23 +806,22 @@ static int bcm2708_compat_ioctl(struct f - static void bcm2708_fb_fillrect(struct fb_info *info, - const struct fb_fillrect *rect) - { -- /* (is called) print_debug("bcm2708_fb_fillrect\n"); */ - cfb_fillrect(info, rect); - } - - /* A helper function for configuring dma control block */ - static void set_dma_cb(struct bcm2708_dma_cb *cb, -- int burst_size, -- dma_addr_t dst, -- int dst_stride, -- dma_addr_t src, -- int src_stride, -- int w, -- int h) -+ int burst_size, -+ dma_addr_t dst, -+ int dst_stride, -+ dma_addr_t src, -+ int src_stride, -+ int w, -+ int h) - { - cb->info = BCM2708_DMA_BURST(burst_size) | BCM2708_DMA_S_WIDTH | -- BCM2708_DMA_S_INC | BCM2708_DMA_D_WIDTH | -- BCM2708_DMA_D_INC | BCM2708_DMA_TDMODE; -+ BCM2708_DMA_S_INC | BCM2708_DMA_D_WIDTH | -+ BCM2708_DMA_D_INC | BCM2708_DMA_TDMODE; - cb->dst = dst; - cb->src = src; - /* -@@ -649,15 +839,19 @@ static void bcm2708_fb_copyarea(struct f - const struct fb_copyarea *region) - { - struct bcm2708_fb *fb = to_bcm2708(info); -- struct bcm2708_dma_cb *cb = fb->cb_base; -+ struct bcm2708_fb_dev *fbdev = fb->fbdev; -+ struct bcm2708_dma_cb *cb = fbdev->cb_base; - int bytes_per_pixel = (info->var.bits_per_pixel + 7) >> 3; - - /* Channel 0 supports larger bursts and is a bit faster */ -- int burst_size = (fb->dma_chan == 0) ? 8 : 2; -+ int burst_size = (fbdev->dma_chan == 0) ? 8 : 2; - int pixels = region->width * region->height; - -- /* Fallback to cfb_copyarea() if we don't like something */ -- if (bytes_per_pixel > 4 || -+ /* If DMA is currently in use (ie being used on another FB), then -+ * rather than wait for it to finish, just use the cfb_copyarea -+ */ -+ if (!mutex_trylock(&fbdev->dma_mutex) || -+ bytes_per_pixel > 4 || - info->var.xres * info->var.yres > 1920 * 1200 || - region->width <= 0 || region->width > info->var.xres || - region->height <= 0 || region->height > info->var.yres || -@@ -684,8 +878,8 @@ static void bcm2708_fb_copyarea(struct f - * 1920x1200 resolution at 32bpp pixel depth. - */ - int y; -- dma_addr_t control_block_pa = fb->cb_handle; -- dma_addr_t scratchbuf = fb->cb_handle + 16 * 1024; -+ dma_addr_t control_block_pa = fbdev->cb_handle; -+ dma_addr_t scratchbuf = fbdev->cb_handle + 16 * 1024; - int scanline_size = bytes_per_pixel * region->width; - int scanlines_per_cb = (64 * 1024 - 16 * 1024) / scanline_size; - -@@ -735,10 +929,10 @@ static void bcm2708_fb_copyarea(struct f - } - set_dma_cb(cb, burst_size, - fb->fb_bus_address + dy * fb->fb.fix.line_length + -- bytes_per_pixel * region->dx, -+ bytes_per_pixel * region->dx, - stride, - fb->fb_bus_address + sy * fb->fb.fix.line_length + -- bytes_per_pixel * region->sx, -+ bytes_per_pixel * region->sx, - stride, - region->width * bytes_per_pixel, - region->height); -@@ -748,32 +942,33 @@ static void bcm2708_fb_copyarea(struct f - cb->next = 0; - - if (pixels < dma_busy_wait_threshold) { -- bcm_dma_start(fb->dma_chan_base, fb->cb_handle); -- bcm_dma_wait_idle(fb->dma_chan_base); -+ bcm_dma_start(fbdev->dma_chan_base, fbdev->cb_handle); -+ bcm_dma_wait_idle(fbdev->dma_chan_base); - } else { -- void __iomem *dma_chan = fb->dma_chan_base; -+ void __iomem *local_dma_chan = fbdev->dma_chan_base; - - cb->info |= BCM2708_DMA_INT_EN; -- bcm_dma_start(fb->dma_chan_base, fb->cb_handle); -- while (bcm_dma_is_busy(dma_chan)) { -- wait_event_interruptible(fb->dma_waitq, -- !bcm_dma_is_busy(dma_chan)); -+ bcm_dma_start(fbdev->dma_chan_base, fbdev->cb_handle); -+ while (bcm_dma_is_busy(local_dma_chan)) { -+ wait_event_interruptible(fbdev->dma_waitq, -+ !bcm_dma_is_busy(local_dma_chan)); - } -- fb->stats.dma_irqs++; -+ fbdev->dma_stats.dma_irqs++; - } -- fb->stats.dma_copies++; -+ fbdev->dma_stats.dma_copies++; -+ -+ mutex_unlock(&fbdev->dma_mutex); - } - - static void bcm2708_fb_imageblit(struct fb_info *info, - const struct fb_image *image) - { -- /* (is called) print_debug("bcm2708_fb_imageblit\n"); */ - cfb_imageblit(info, image); - } - - static irqreturn_t bcm2708_fb_dma_irq(int irq, void *cxt) - { -- struct bcm2708_fb *fb = cxt; -+ struct bcm2708_fb_dev *fbdev = cxt; - - /* FIXME: should read status register to check if this is - * actually interrupting us or not, in case this interrupt -@@ -783,9 +978,9 @@ static irqreturn_t bcm2708_fb_dma_irq(in - */ - - /* acknowledge the interrupt */ -- writel(BCM2708_DMA_INT, fb->dma_chan_base + BCM2708_DMA_CS); -+ writel(BCM2708_DMA_INT, fbdev->dma_chan_base + BCM2708_DMA_CS); - -- wake_up(&fb->dma_waitq); -+ wake_up(&fbdev->dma_waitq); - return IRQ_HANDLED; - } - -@@ -821,11 +1016,23 @@ static int bcm2708_fb_register(struct bc - fb->fb.fix.ywrapstep = 0; - fb->fb.fix.accel = FB_ACCEL_NONE; - -- fb->fb.var.xres = fbwidth; -- fb->fb.var.yres = fbheight; -- fb->fb.var.xres_virtual = fbwidth; -- fb->fb.var.yres_virtual = fbheight; -- fb->fb.var.bits_per_pixel = fbdepth; -+ /* If we have data from the VC4 on FB's, use that, otherwise use the -+ * module parameters -+ */ -+ if (fb->display_settings.width) { -+ fb->fb.var.xres = fb->display_settings.width; -+ fb->fb.var.yres = fb->display_settings.height; -+ fb->fb.var.xres_virtual = fb->fb.var.xres; -+ fb->fb.var.yres_virtual = fb->fb.var.yres; -+ fb->fb.var.bits_per_pixel = fb->display_settings.depth; -+ } else { -+ fb->fb.var.xres = fbwidth; -+ fb->fb.var.yres = fbheight; -+ fb->fb.var.xres_virtual = fbwidth; -+ fb->fb.var.yres_virtual = fbheight; -+ fb->fb.var.bits_per_pixel = fbdepth; -+ } -+ - fb->fb.var.vmode = FB_VMODE_NONINTERLACED; - fb->fb.var.activate = FB_ACTIVATE_NOW; - fb->fb.var.nonstd = 0; -@@ -841,26 +1048,23 @@ static int bcm2708_fb_register(struct bc - fb->fb.monspecs.dclkmax = 100000000; - - bcm2708_fb_set_bitfields(&fb->fb.var); -- init_waitqueue_head(&fb->dma_waitq); - - /* - * Allocate colourmap. - */ -- - fb_set_var(&fb->fb, &fb->fb.var); -+ - ret = bcm2708_fb_set_par(&fb->fb); -+ - if (ret) - return ret; - -- print_debug("BCM2708FB: registering framebuffer (%dx%d@%d) (%d)\n", -- fbwidth, fbheight, fbdepth, fbswap); -- - ret = register_framebuffer(&fb->fb); -- print_debug("BCM2708FB: register framebuffer (%d)\n", ret); -+ - if (ret == 0) - goto out; - -- print_debug("BCM2708FB: cannot register framebuffer (%d)\n", ret); -+ dev_warn(fb->fb.dev, "Unable to register framebuffer (%d)\n", ret); - out: - return ret; - } -@@ -869,10 +1073,18 @@ static int bcm2708_fb_probe(struct platf - { - struct device_node *fw_np; - struct rpi_firmware *fw; -- struct bcm2708_fb *fb; -- int ret; -+ int ret, i; -+ u32 num_displays; -+ struct bcm2708_fb_dev *fbdev; -+ struct { u32 base, length; } gpu_mem; -+ -+ fbdev = devm_kzalloc(&dev->dev, sizeof(*fbdev), GFP_KERNEL); -+ -+ if (!fbdev) -+ return -ENOMEM; - - fw_np = of_parse_phandle(dev->dev.of_node, "firmware", 0); -+ - /* Remove comment when booting without Device Tree is no longer supported - * if (!fw_np) { - * dev_err(&dev->dev, "Missing firmware node\n"); -@@ -880,90 +1092,154 @@ static int bcm2708_fb_probe(struct platf - * } - */ - fw = rpi_firmware_get(fw_np); -+ fbdev->fw = fw; -+ - if (!fw) - return -EPROBE_DEFER; - -- fb = kzalloc(sizeof(*fb), GFP_KERNEL); -- if (!fb) { -- ret = -ENOMEM; -- goto free_region; -+ ret = rpi_firmware_property(fw, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS, -+ &num_displays, sizeof(u32)); -+ -+ /* If we fail to get the number of displays, or it returns 0, then -+ * assume old firmware that doesn't have the mailbox call, so just -+ * set one display -+ */ -+ if (ret || num_displays == 0) { -+ num_displays = 1; -+ dev_err(&dev->dev, -+ "Unable to determine number of FB's. Assuming 1\n"); -+ ret = 0; -+ } else { -+ fbdev->firmware_supports_multifb = 1; - } - -- fb->fw = fw; -- bcm2708_fb_debugfs_init(fb); -+ if (num_displays > MAX_FRAMEBUFFERS) { -+ dev_warn(&dev->dev, -+ "More displays reported from firmware than supported in driver (%u vs %u)", -+ num_displays, MAX_FRAMEBUFFERS); -+ num_displays = MAX_FRAMEBUFFERS; -+ } - -- fb->cb_base = dma_alloc_writecombine(&dev->dev, SZ_64K, -- &fb->cb_handle, GFP_KERNEL); -- if (!fb->cb_base) { -+ dev_info(&dev->dev, "FB found %d display(s)\n", num_displays); -+ -+ /* Set up the DMA information. Note we have just one set of DMA -+ * parameters to work with all the FB's so requires synchronising when -+ * being used -+ */ -+ -+ mutex_init(&fbdev->dma_mutex); -+ -+ fbdev->cb_base = dma_alloc_writecombine(&dev->dev, SZ_64K, -+ &fbdev->cb_handle, -+ GFP_KERNEL); -+ if (!fbdev->cb_base) { - dev_err(&dev->dev, "cannot allocate DMA CBs\n"); - ret = -ENOMEM; - goto free_fb; - } - -- pr_info("BCM2708FB: allocated DMA memory %pad\n", &fb->cb_handle); -- - ret = bcm_dma_chan_alloc(BCM_DMA_FEATURE_BULK, -- &fb->dma_chan_base, &fb->dma_irq); -+ &fbdev->dma_chan_base, -+ &fbdev->dma_irq); - if (ret < 0) { -- dev_err(&dev->dev, "couldn't allocate a DMA channel\n"); -+ dev_err(&dev->dev, "Couldn't allocate a DMA channel\n"); - goto free_cb; - } -- fb->dma_chan = ret; -+ fbdev->dma_chan = ret; - -- ret = request_irq(fb->dma_irq, bcm2708_fb_dma_irq, -- 0, "bcm2708_fb dma", fb); -+ ret = request_irq(fbdev->dma_irq, bcm2708_fb_dma_irq, -+ 0, "bcm2708_fb DMA", fbdev); - if (ret) { -- pr_err("%s: failed to request DMA irq\n", __func__); -+ dev_err(&dev->dev, -+ "Failed to request DMA irq\n"); - goto free_dma_chan; - } - -- pr_info("BCM2708FB: allocated DMA channel %d\n", fb->dma_chan); -+ rpi_firmware_property(fbdev->fw, -+ RPI_FIRMWARE_GET_VC_MEMORY, -+ &gpu_mem, sizeof(gpu_mem)); -+ -+ for (i = 0; i < num_displays; i++) { -+ struct bcm2708_fb *fb = &fbdev->displays[i]; -+ -+ fb->display_settings.display_num = i; -+ fb->dev = dev; -+ fb->fb.device = &dev->dev; -+ fb->fbdev = fbdev; -+ -+ fb->gpu.base = gpu_mem.base; -+ fb->gpu.length = gpu_mem.length; -+ -+ if (fbdev->firmware_supports_multifb) { -+ ret = rpi_firmware_property(fw, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_SETTINGS, -+ &fb->display_settings, -+ GET_DISPLAY_SETTINGS_PAYLOAD_SIZE); -+ } else { -+ memset(&fb->display_settings, 0, -+ sizeof(fb->display_settings)); -+ } -+ -+ ret = bcm2708_fb_register(fb); - -- fb->dev = dev; -- fb->fb.device = &dev->dev; -+ if (ret == 0) { -+ bcm2708_fb_debugfs_init(fb); - -- /* failure here isn't fatal, but we'll fail in vc_mem_copy if -- * fb->gpu is not valid -- */ -- rpi_firmware_property(fb->fw, RPI_FIRMWARE_GET_VC_MEMORY, &fb->gpu, -- sizeof(fb->gpu)); -+ fbdev->num_displays++; - -- ret = bcm2708_fb_register(fb); -- if (ret == 0) { -- platform_set_drvdata(dev, fb); -- goto out; -+ dev_info(&dev->dev, -+ "Registered framebuffer for display %u, size %ux%u\n", -+ fb->display_settings.display_num, -+ fb->fb.var.xres, -+ fb->fb.var.yres); -+ } else { -+ // Use this to flag if this FB entry is in use. -+ fb->fbdev = NULL; -+ } -+ } -+ -+ // Did we actually successfully create any FB's? -+ if (fbdev->num_displays) { -+ init_waitqueue_head(&fbdev->dma_waitq); -+ platform_set_drvdata(dev, fbdev); -+ return ret; - } - - free_dma_chan: -- bcm_dma_chan_free(fb->dma_chan); -+ bcm_dma_chan_free(fbdev->dma_chan); - free_cb: -- dma_free_writecombine(&dev->dev, SZ_64K, fb->cb_base, fb->cb_handle); -+ dma_free_writecombine(&dev->dev, SZ_64K, fbdev->cb_base, -+ fbdev->cb_handle); - free_fb: -- kfree(fb); --free_region: - dev_err(&dev->dev, "probe failed, err %d\n", ret); --out: -+ - return ret; - } - - static int bcm2708_fb_remove(struct platform_device *dev) - { -- struct bcm2708_fb *fb = platform_get_drvdata(dev); -+ struct bcm2708_fb_dev *fbdev = platform_get_drvdata(dev); -+ int i; - - platform_set_drvdata(dev, NULL); - -- if (fb->fb.screen_base) -- iounmap(fb->fb.screen_base); -- unregister_framebuffer(&fb->fb); -- -- dma_free_writecombine(&dev->dev, SZ_64K, fb->cb_base, fb->cb_handle); -- bcm_dma_chan_free(fb->dma_chan); -- -- bcm2708_fb_debugfs_deinit(fb); -+ for (i = 0; i < fbdev->num_displays; i++) { -+ if (fbdev->displays[i].fb.screen_base) -+ iounmap(fbdev->displays[i].fb.screen_base); -+ -+ if (fbdev->displays[i].fbdev) { -+ unregister_framebuffer(&fbdev->displays[i].fb); -+ bcm2708_fb_debugfs_deinit(&fbdev->displays[i]); -+ } -+ } - -- free_irq(fb->dma_irq, fb); -+ dma_free_writecombine(&dev->dev, SZ_64K, fbdev->cb_base, -+ fbdev->cb_handle); -+ bcm_dma_chan_free(fbdev->dma_chan); -+ free_irq(fbdev->dma_irq, fbdev); - -- kfree(fb); -+ mutex_destroy(&fbdev->dma_mutex); - - return 0; - } -@@ -978,10 +1254,10 @@ static struct platform_driver bcm2708_fb - .probe = bcm2708_fb_probe, - .remove = bcm2708_fb_remove, - .driver = { -- .name = DRIVER_NAME, -- .owner = THIS_MODULE, -- .of_match_table = bcm2708_fb_of_match_table, -- }, -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = bcm2708_fb_of_match_table, -+ }, - }; - - static int __init bcm2708_fb_init(void) ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -138,9 +138,11 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, - RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER = 0x00048006, - RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE = 0x00048007, -+ RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH = 0x00048008, - RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, - RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, - RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, -+ - RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF = 0x0004801f, - RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF = 0x00048020, - RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e, -@@ -159,6 +161,8 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, - }; - -+#define GET_DISPLAY_SETTINGS_PAYLOAD_SIZE 64 -+ - #if IS_ENABLED(CONFIG_RASPBERRYPI_FIRMWARE) - int rpi_firmware_property(struct rpi_firmware *fw, - u32 tag, void *data, size_t len); diff --git a/target/linux/brcm2708/patches-4.19/950-0637-spi-devicetree-add-overlays-for-spi-3-to-6.patch b/target/linux/brcm2708/patches-4.19/950-0637-spi-devicetree-add-overlays-for-spi-3-to-6.patch new file mode 100644 index 0000000000..450016e617 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0637-spi-devicetree-add-overlays-for-spi-3-to-6.patch @@ -0,0 +1,581 @@ +From 2965d0b1d0b91c199d7468aa89874a9b462fd924 Mon Sep 17 00:00:00 2001 +From: Martin Sperl +Date: Sun, 12 May 2019 16:17:08 +0000 +Subject: [PATCH 637/725] spi: devicetree: add overlays for spi 3 to 6 + +Signed-off-by: Martin Sperl +--- + arch/arm/boot/dts/overlays/Makefile | 8 ++ + arch/arm/boot/dts/overlays/README | 104 ++++++++++++++++++ + .../boot/dts/overlays/spi3-1cs-overlay.dts | 44 ++++++++ + .../boot/dts/overlays/spi3-2cs-overlay.dts | 56 ++++++++++ + .../boot/dts/overlays/spi4-1cs-overlay.dts | 44 ++++++++ + .../boot/dts/overlays/spi4-2cs-overlay.dts | 56 ++++++++++ + .../boot/dts/overlays/spi5-1cs-overlay.dts | 44 ++++++++ + .../boot/dts/overlays/spi5-2cs-overlay.dts | 56 ++++++++++ + .../boot/dts/overlays/spi6-1cs-overlay.dts | 44 ++++++++ + .../boot/dts/overlays/spi6-2cs-overlay.dts | 56 ++++++++++ + 10 files changed, 512 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/spi3-1cs-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi3-2cs-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi4-1cs-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi4-2cs-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi5-1cs-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi5-2cs-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi6-1cs-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi6-2cs-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -144,6 +144,14 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + spi2-1cs.dtbo \ + spi2-2cs.dtbo \ + spi2-3cs.dtbo \ ++ spi3-1cs.dtbo \ ++ spi3-2cs.dtbo \ ++ spi4-1cs.dtbo \ ++ spi4-2cs.dtbo \ ++ spi5-1cs.dtbo \ ++ spi5-2cs.dtbo \ ++ spi6-1cs.dtbo \ ++ spi6-2cs.dtbo \ + ssd1306.dtbo \ + superaudioboard.dtbo \ + sx150x.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -2085,6 +2085,110 @@ Params: cs0_pin GPIO pin + is 'okay' or enabled). + + ++Name: spi3-1cs ++Info: Enables spi3 with a single chip select (CS) line and associated spidev ++ dev node. The gpio pin number for the CS line and spidev device node ++ creation are configurable. ++Load: dtoverlay=spi3-1cs,= ++Params: cs0_pin GPIO pin for CS0 (default 0 - BCM SPI3_CE0). ++ cs0_spidev Set to 'off' to prevent the creation of a ++ userspace device node /dev/spidev3.0 (default ++ is 'on' or enabled). ++ ++ ++Name: spi3-2cs ++Info: Enables spi3 with two chip select (CS) lines and associated spidev ++ dev nodes. The gpio pin numbers for the CS lines and spidev device node ++ creation are configurable. ++Load: dtoverlay=spi3-2cs,= ++Params: cs0_pin GPIO pin for CS0 (default 0 - BCM SPI3_CE0). ++ cs1_pin GPIO pin for CS1 (default 24 - BCM SPI3_CE1). ++ cs0_spidev Set to 'off' to prevent the creation of a ++ userspace device node /dev/spidev3.0 (default ++ is 'on' or enabled). ++ cs1_spidev Set to 'off' to prevent the creation of a ++ userspace device node /dev/spidev3.1 (default ++ is 'on' or enabled). ++ ++ ++Name: spi4-1cs ++Info: Enables spi4 with a single chip select (CS) line and associated spidev ++ dev node. The gpio pin number for the CS line and spidev device node ++ creation are configurable. ++Load: dtoverlay=spi4-1cs,= ++Params: cs0_pin GPIO pin for CS0 (default 4 - BCM SPI4_CE0). ++ cs0_spidev Set to 'off' to prevent the creation of a ++ userspace device node /dev/spidev4.0 (default ++ is 'on' or enabled). ++ ++ ++Name: spi4-2cs ++Info: Enables spi4 with two chip select (CS) lines and associated spidev ++ dev nodes. The gpio pin numbers for the CS lines and spidev device node ++ creation are configurable. ++Load: dtoverlay=spi4-2cs,= ++Params: cs0_pin GPIO pin for CS0 (default 4 - BCM SPI4_CE0). ++ cs1_pin GPIO pin for CS1 (default 25 - BCM SPI4_CE1). ++ cs0_spidev Set to 'off' to prevent the creation of a ++ userspace device node /dev/spidev4.0 (default ++ is 'on' or enabled). ++ cs1_spidev Set to 'off' to prevent the creation of a ++ userspace device node /dev/spidev4.1 (default ++ is 'on' or enabled). ++ ++ ++Name: spi5-1cs ++Info: Enables spi5 with a single chip select (CS) line and associated spidev ++ dev node. The gpio pin numbers for the CS lines and spidev device node ++ creation are configurable. ++Load: dtoverlay=spi5-1cs,= ++Params: cs0_pin GPIO pin for CS0 (default 12 - BCM SPI5_CE0). ++ cs0_spidev Set to 'off' to prevent the creation of a ++ userspace device node /dev/spidev5.0 (default ++ is 'on' or enabled). ++ ++ ++Name: spi5-2cs ++Info: Enables spi5 with two chip select (CS) lines and associated spidev ++ dev nodes. The gpio pin numbers for the CS lines and spidev device node ++ creation are configurable. ++Load: dtoverlay=spi5-2cs,= ++Params: cs0_pin GPIO pin for CS0 (default 12 - BCM SPI5_CE0). ++ cs1_pin GPIO pin for CS1 (default 26 - BCM SPI5_CE1). ++ cs0_spidev Set to 'off' to prevent the creation of a ++ userspace device node /dev/spidev5.0 (default ++ is 'on' or enabled). ++ cs1_spidev Set to 'off' to prevent the creation of a ++ userspace device node /dev/spidev5.1 (default ++ is 'on' or enabled). ++ ++ ++Name: spi6-1cs ++Info: Enables spi6 with a single chip select (CS) line and associated spidev ++ dev node. The gpio pin number for the CS line and spidev device node ++ creation are configurable. ++Load: dtoverlay=spi6-1cs,= ++Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI6_CE0). ++ cs0_spidev Set to 'off' to prevent the creation of a ++ userspace device node /dev/spidev6.0 (default ++ is 'on' or enabled). ++ ++ ++Name: spi6-2cs ++Info: Enables spi6 with two chip select (CS) lines and associated spidev ++ dev nodes. The gpio pin numbers for the CS lines and spidev device node ++ creation are configurable. ++Load: dtoverlay=spi6-2cs,= ++Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI6_CE0). ++ cs1_pin GPIO pin for CS1 (default 27 - BCM SPI6_CE1). ++ cs0_spidev Set to 'off' to prevent the creation of a ++ userspace device node /dev/spidev6.0 (default ++ is 'on' or enabled). ++ cs1_spidev Set to 'off' to prevent the creation of a ++ userspace device node /dev/spidev6.1 (default ++ is 'on' or enabled). ++ ++ + Name: ssd1306 + Info: Overlay for activation of SSD1306 over I2C OLED display framebuffer. + Load: dtoverlay=ssd1306,= +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi3-1cs-overlay.dts +@@ -0,0 +1,44 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2838"; ++ ++ fragment@0 { ++ target = <&spi3_cs_pins>; ++ frag0: __overlay__ { ++ brcm,pins = <0>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi3>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi3_pins &spi3_cs_pins>; ++ cs-gpios = <&gpio 0 1>; ++ status = "okay"; ++ ++ spidev3_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&frag0>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs0_spidev = <&spidev3_0>,"status"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi3-2cs-overlay.dts +@@ -0,0 +1,56 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2838"; ++ ++ fragment@0 { ++ target = <&spi3_cs_pins>; ++ frag0: __overlay__ { ++ brcm,pins = <0 24>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi3>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi3_pins &spi3_cs_pins>; ++ cs-gpios = <&gpio 0 1>, <&gpio 24 1>; ++ status = "okay"; ++ ++ spidev3_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ status = "okay"; ++ }; ++ ++ spidev3_1: spidev@1 { ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&frag0>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs1_pin = <&frag0>,"brcm,pins:4", ++ <&frag1>,"cs-gpios:16"; ++ cs0_spidev = <&spidev3_0>,"status"; ++ cs1_spidev = <&spidev3_1>,"status"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi4-1cs-overlay.dts +@@ -0,0 +1,44 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2838"; ++ ++ fragment@0 { ++ target = <&spi4_cs_pins>; ++ frag0: __overlay__ { ++ brcm,pins = <4>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi4>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi4_pins &spi4_cs_pins>; ++ cs-gpios = <&gpio 4 1>; ++ status = "okay"; ++ ++ spidev4_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&frag0>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs0_spidev = <&spidev4_0>,"status"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi4-2cs-overlay.dts +@@ -0,0 +1,56 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2838"; ++ ++ fragment@0 { ++ target = <&spi4_cs_pins>; ++ frag0: __overlay__ { ++ brcm,pins = <4 25>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi4>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi4_pins &spi4_cs_pins>; ++ cs-gpios = <&gpio 4 1>, <&gpio 25 1>; ++ status = "okay"; ++ ++ spidev4_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ status = "okay"; ++ }; ++ ++ spidev4_1: spidev@1 { ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&frag0>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs1_pin = <&frag0>,"brcm,pins:4", ++ <&frag1>,"cs-gpios:16"; ++ cs0_spidev = <&spidev4_0>,"status"; ++ cs1_spidev = <&spidev4_1>,"status"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi5-1cs-overlay.dts +@@ -0,0 +1,44 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2838"; ++ ++ fragment@0 { ++ target = <&spi5_cs_pins>; ++ frag0: __overlay__ { ++ brcm,pins = <12>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi5>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi5_pins &spi5_cs_pins>; ++ cs-gpios = <&gpio 12 1>; ++ status = "okay"; ++ ++ spidev5_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&frag0>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs0_spidev = <&spidev5_0>,"status"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi5-2cs-overlay.dts +@@ -0,0 +1,56 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2838"; ++ ++ fragment@0 { ++ target = <&spi5_cs_pins>; ++ frag0: __overlay__ { ++ brcm,pins = <12 26>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi5>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi5_pins &spi5_cs_pins>; ++ cs-gpios = <&gpio 12 1>, <&gpio 26 1>; ++ status = "okay"; ++ ++ spidev5_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ status = "okay"; ++ }; ++ ++ spidev5_1: spidev@1 { ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&frag0>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs1_pin = <&frag0>,"brcm,pins:4", ++ <&frag1>,"cs-gpios:16"; ++ cs0_spidev = <&spidev5_0>,"status"; ++ cs1_spidev = <&spidev5_1>,"status"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi6-1cs-overlay.dts +@@ -0,0 +1,44 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2838"; ++ ++ fragment@0 { ++ target = <&spi6_cs_pins>; ++ frag0: __overlay__ { ++ brcm,pins = <18>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi6>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi6_pins &spi6_cs_pins>; ++ cs-gpios = <&gpio 18 1>; ++ status = "okay"; ++ ++ spidev6_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&frag0>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs0_spidev = <&spidev6_0>,"status"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi6-2cs-overlay.dts +@@ -0,0 +1,56 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2838"; ++ ++ fragment@0 { ++ target = <&spi6_cs_pins>; ++ frag0: __overlay__ { ++ brcm,pins = <18 27>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi6>; ++ frag1: __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi6_pins &spi6_cs_pins>; ++ cs-gpios = <&gpio 18 1>, <&gpio 27 1>; ++ status = "okay"; ++ ++ spidev6_0: spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ status = "okay"; ++ }; ++ ++ spidev6_1: spidev@1 { ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&frag0>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs1_pin = <&frag0>,"brcm,pins:4", ++ <&frag1>,"cs-gpios:16"; ++ cs0_spidev = <&spidev6_0>,"status"; ++ cs1_spidev = <&spidev6_1>,"status"; ++ }; ++}; diff --git a/target/linux/brcm2708/patches-4.19/950-0638-ARM-dts-bcm283x-Move-BCM2835-6-7-specific-to-bcm2835.patch b/target/linux/brcm2708/patches-4.19/950-0638-ARM-dts-bcm283x-Move-BCM2835-6-7-specific-to-bcm2835.patch deleted file mode 100644 index 3ab4a8cf4f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0638-ARM-dts-bcm283x-Move-BCM2835-6-7-specific-to-bcm2835.patch +++ /dev/null @@ -1,189 +0,0 @@ -From ba24f07c814a4d0527fa5821834cded70ac705be Mon Sep 17 00:00:00 2001 -From: Stefan Wahren -Date: Sun, 19 May 2019 12:26:21 +0200 -Subject: [PATCH 638/703] ARM: dts: bcm283x: Move BCM2835/6/7 specific to - bcm2835-common.dtsi - -We want all common BCM2835/6/7/8 functions in bcm283x.dtsi and all -BCM2835/6/7 specific in the new bcm2835-common.dtsi. - -Signed-off-by: Stefan Wahren ---- - arch/arm/boot/dts/bcm2835-common.dtsi | 53 +++++++++++++++++++++++++++ - arch/arm/boot/dts/bcm2835.dtsi | 1 + - arch/arm/boot/dts/bcm2836.dtsi | 1 + - arch/arm/boot/dts/bcm2837.dtsi | 1 + - arch/arm/boot/dts/bcm283x.dtsi | 43 +--------------------- - 5 files changed, 57 insertions(+), 42 deletions(-) - create mode 100644 arch/arm/boot/dts/bcm2835-common.dtsi - ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2835-common.dtsi -@@ -0,0 +1,53 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+/* This include file covers the common peripherals and configuration between -+ * bcm2835, bcm2836 and bcm2837 implementations. -+ */ -+ -+/ { -+ soc { -+ timer@7e003000 { -+ compatible = "brcm,bcm2835-system-timer"; -+ reg = <0x7e003000 0x1000>; -+ interrupts = <1 0>, <1 1>, <1 2>, <1 3>; -+ /* This could be a reference to BCM2835_CLOCK_TIMER, -+ * but we don't have the driver using the common clock -+ * support yet. -+ */ -+ clock-frequency = <1000000>; -+ }; -+ -+ intc: interrupt-controller@7e00b200 { -+ compatible = "brcm,bcm2835-armctrl-ic"; -+ reg = <0x7e00b200 0x200>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ }; -+ -+ thermal: thermal@7e212000 { -+ compatible = "brcm,bcm2835-thermal"; -+ reg = <0x7e212000 0x8>; -+ clocks = <&clocks BCM2835_CLOCK_TSENS>; -+ #thermal-sensor-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ v3d: v3d@7ec00000 { -+ compatible = "brcm,bcm2835-v3d"; -+ reg = <0x7ec00000 0x1000>; -+ interrupts = <1 10>; -+ }; -+ }; -+}; -+ -+&gpio { -+ i2c_slave_gpio18: i2c_slave_gpio18 { -+ brcm,pins = <18 19 20 21>; -+ brcm,function = ; -+ }; -+ -+ jtag_gpio4: jtag_gpio4 { -+ brcm,pins = <4 5 6 12 13>; -+ brcm,function = ; -+ }; -+}; ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -1,5 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0 - #include "bcm283x.dtsi" -+#include "bcm2835-common.dtsi" - - / { - compatible = "brcm,bcm2835"; ---- a/arch/arm/boot/dts/bcm2836.dtsi -+++ b/arch/arm/boot/dts/bcm2836.dtsi -@@ -1,5 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0 - #include "bcm283x.dtsi" -+#include "bcm2835-common.dtsi" - - / { - compatible = "brcm,bcm2836"; ---- a/arch/arm/boot/dts/bcm2837.dtsi -+++ b/arch/arm/boot/dts/bcm2837.dtsi -@@ -1,4 +1,5 @@ - #include "bcm283x.dtsi" -+#include "bcm2835-common.dtsi" - - / { - compatible = "brcm,bcm2837"; ---- a/arch/arm/boot/dts/bcm283x.dtsi -+++ b/arch/arm/boot/dts/bcm283x.dtsi -@@ -55,17 +55,6 @@ - #address-cells = <1>; - #size-cells = <1>; - -- timer@7e003000 { -- compatible = "brcm,bcm2835-system-timer"; -- reg = <0x7e003000 0x1000>; -- interrupts = <1 0>, <1 1>, <1 2>, <1 3>; -- /* This could be a reference to BCM2835_CLOCK_TIMER, -- * but we don't have the driver using the common clock -- * support yet. -- */ -- clock-frequency = <1000000>; -- }; -- - txp@7e004000 { - compatible = "brcm,bcm2835-txp"; - reg = <0x7e004000 0x20>; -@@ -113,13 +102,6 @@ - brcm,dma-channel-mask = <0x7f35>; - }; - -- intc: interrupt-controller@7e00b200 { -- compatible = "brcm,bcm2835-armctrl-ic"; -- reg = <0x7e00b200 0x200>; -- interrupt-controller; -- #interrupt-cells = <2>; -- }; -- - watchdog@7e100000 { - compatible = "brcm,bcm2835-pm", "brcm,bcm2835-pm-wdt"; - #power-domain-cells = <1>; -@@ -183,8 +165,7 @@ - interrupt-controller; - #interrupt-cells = <2>; - -- /* Defines pin muxing groups according to -- * BCM2835-ARM-Peripherals.pdf page 102. -+ /* Defines common pin muxing groups - * - * While each pin can have its mux selected - * for various functions individually, some -@@ -262,15 +243,7 @@ - brcm,pins = <44 45>; - brcm,function = ; - }; -- i2c_slave_gpio18: i2c_slave_gpio18 { -- brcm,pins = <18 19 20 21>; -- brcm,function = ; -- }; - -- jtag_gpio4: jtag_gpio4 { -- brcm,pins = <4 5 6 12 13>; -- brcm,function = ; -- }; - jtag_gpio22: jtag_gpio22 { - brcm,pins = <22 23 24 25 26 27>; - brcm,function = ; -@@ -487,14 +460,6 @@ - - }; - -- thermal: thermal@7e212000 { -- compatible = "brcm,bcm2835-thermal"; -- reg = <0x7e212000 0x8>; -- clocks = <&clocks BCM2835_CLOCK_TSENS>; -- #thermal-sensor-cells = <0>; -- status = "disabled"; -- }; -- - aux: aux@7e215000 { - compatible = "brcm,bcm2835-aux"; - #clock-cells = <1>; -@@ -660,12 +625,6 @@ - phy-names = "usb2-phy"; - }; - -- v3d: v3d@7ec00000 { -- compatible = "brcm,bcm2835-v3d"; -- reg = <0x7ec00000 0x1000>; -- interrupts = <1 10>; -- }; -- - vc4: gpu { - compatible = "brcm,bcm2835-vc4"; - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0638-overlays-Add-the-spi-gpio40-45-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0638-overlays-Add-the-spi-gpio40-45-overlay.patch new file mode 100644 index 0000000000..f6a9e39da2 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0638-overlays-Add-the-spi-gpio40-45-overlay.patch @@ -0,0 +1,80 @@ +From 8ebd5065611e9ffc833d7da8018c787a533b1231 Mon Sep 17 00:00:00 2001 +From: Tim Gover +Date: Tue, 22 Jan 2019 10:49:41 +0000 +Subject: [PATCH 638/725] overlays: Add the spi-gpio40-45 overlay + +The 2711 B0 boot EEPROM is programmed via SPI0 on GPIO +pins 40-43 CS0. Add a device tree overlay to optionally +change the SPI0 pinmux from the external GPIO pins to +the boot EEPROM pins. +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 6 ++++ + .../dts/overlays/spi-gpio40-45-overlay.dts | 36 +++++++++++++++++++ + 3 files changed, 43 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/spi-gpio40-45-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -135,6 +135,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + smi-dev.dtbo \ + smi-nand.dtbo \ + spi-gpio35-39.dtbo \ ++ spi-gpio40-45.dtbo \ + spi-rtc.dtbo \ + spi0-cs.dtbo \ + spi0-hw-cs.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1967,6 +1967,12 @@ Load: dtoverlay=spi-gpio35-39 + Params: + + ++Name: spi-gpio40-45 ++Info: Move SPI function block to GPIOs 40 to 45 ++Load: dtoverlay=spi-gpio40-45 ++Params: ++ ++ + Name: spi-rtc + Info: Adds support for a number of SPI Real Time Clock devices + Load: dtoverlay=spi-rtc,= +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi-gpio40-45-overlay.dts +@@ -0,0 +1,36 @@ ++/* ++ * Boot EEPROM overlay ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ cs-gpios = <&gpio 43 1>, <&gpio 44 1>, <&gpio 45 1>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0_cs_pins>; ++ __overlay__ { ++ brcm,pins = <45 44 43>; ++ brcm,function = <1>; /* output */ ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0_pins>; ++ __overlay__ { ++ brcm,pins = <40 41 42>; ++ brcm,function = <3>; /* alt4 */ ++ status = "okay"; ++ }; ++ }; ++}; diff --git a/target/linux/brcm2708/patches-4.19/950-0639-ARM-dts-Add-bcm2711-rpi-4-b.dts-and-components.patch b/target/linux/brcm2708/patches-4.19/950-0639-ARM-dts-Add-bcm2711-rpi-4-b.dts-and-components.patch deleted file mode 100644 index 66643563d7..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0639-ARM-dts-Add-bcm2711-rpi-4-b.dts-and-components.patch +++ /dev/null @@ -1,1129 +0,0 @@ -From 4671029bae38c2057890e60ac26263f982775152 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 29 May 2019 13:54:21 +0100 -Subject: [PATCH 639/703] ARM: dts: Add bcm2711-rpi-4-b.dts and components - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 320 ++++++++++++ - arch/arm/boot/dts/bcm2711.dtsi | 50 ++ - arch/arm/boot/dts/bcm2838.dtsi | 724 ++++++++++++++++++++++++++ - 4 files changed, 1095 insertions(+) - create mode 100644 arch/arm/boot/dts/bcm2711-rpi-4-b.dts - create mode 100644 arch/arm/boot/dts/bcm2711.dtsi - create mode 100644 arch/arm/boot/dts/bcm2838.dtsi - ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -8,6 +8,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ - bcm2708-rpi-zero-w.dtb \ - bcm2709-rpi-2-b.dtb \ - bcm2710-rpi-3-b.dtb \ -+ bcm2711-rpi-4-b.dtb \ - bcm2710-rpi-3-b-plus.dtb \ - bcm2710-rpi-cm3.dtb - ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts -@@ -0,0 +1,320 @@ -+/dts-v1/; -+ -+#include "bcm2711.dtsi" -+ -+/ { -+ compatible = "raspberrypi,4-model-b", "brcm,bcm2838", "brcm,bcm2837"; -+ model = "Raspberry Pi 4 Model B"; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0x0 0x0 0x0>; -+ }; -+ -+ chosen { -+ bootargs = "8250.nr_uarts=1 cma=64M"; -+ }; -+ -+ aliases { -+ serial0 = &uart1; -+ serial1 = &uart0; -+ mmc0 = &emmc2; -+ mmc1 = &mmcnr; -+ mmc2 = &sdhost; -+ /delete-property/ ethernet; -+ /delete-property/ intc; -+ ethernet0 = &genet; -+ }; -+}; -+ -+&soc { -+ virtgpio: virtgpio { -+ compatible = "brcm,bcm2835-virtgpio"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ firmware = <&firmware>; -+ status = "okay"; -+ }; -+}; -+ -+&mmcnr { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdio_pins>; -+ bus-width = <4>; -+ status = "okay"; -+}; -+ -+&firmware { -+ expgpio: expgpio { -+ compatible = "raspberrypi,firmware-gpio"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ 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 = <125000000>; -+ }; -+ -+ spidev1: spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ }; -+}; -+ -+// ============================================= -+// Board specific stuff here -+ -+/ { -+ -+ sd_io_1v8_reg: sd_io_1v8_reg { -+ status = "okay"; -+ compatible = "regulator-gpio"; -+ vin-supply = <&vdd_5v0_reg>; -+ regulator-name = "vdd-sd-io"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-settling-time-us = <5000>; -+ -+ gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>; -+ states = <1800000 0x1 -+ 3300000 0x0>; -+ }; -+}; -+ -+&sdhost { -+ status = "disabled"; -+}; -+ -+&emmc2 { -+ status = "okay"; -+ broken-cd; -+ vqmmc-supply = <&sd_io_1v8_reg>; -+}; -+ -+&leds { -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; -+ gpios = <&gpio 42 0>; -+ }; -+ -+ pwr_led: pwr { -+ label = "led1"; -+ linux,default-trigger = "input"; -+ gpios = <&expgpio 2 0>; -+ }; -+}; -+ -+&audio { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&audio_pins>; -+}; -+ -+&sdhost_gpio48 { -+ brcm,pins = <22 23 24 25 26 27>; -+ brcm,function = ; -+}; -+ -+&gpio { -+ spi0_pins: spi0_pins { -+ brcm,pins = <9 10 11>; -+ brcm,function = ; -+ }; -+ -+ spi0_cs_pins: spi0_cs_pins { -+ brcm,pins = <8 7>; -+ brcm,function = ; -+ }; -+ -+ spi3_pins: spi3_pins { -+ brcm,pins = <1 2 3>; -+ brcm,function = ; -+ }; -+ -+ spi3_cs_pins: spi3_cs_pins { -+ brcm,pins = <0 24>; -+ brcm,function = ; -+ }; -+ -+ spi4_pins: spi4_pins { -+ brcm,pins = <5 6 7>; -+ brcm,function = ; -+ }; -+ -+ spi4_cs_pins: spi4_cs_pins { -+ brcm,pins = <4 25>; -+ brcm,function = ; -+ }; -+ -+ spi5_pins: spi5_pins { -+ brcm,pins = <13 14 15>; -+ brcm,function = ; -+ }; -+ -+ spi5_cs_pins: spi5_cs_pins { -+ brcm,pins = <12 26>; -+ brcm,function = ; -+ }; -+ -+ spi6_pins: spi6_pins { -+ brcm,pins = <19 20 21>; -+ brcm,function = ; -+ }; -+ -+ spi6_cs_pins: spi6_cs_pins { -+ brcm,pins = <18 27>; -+ brcm,function = ; -+ }; -+ -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = ; -+ }; -+ -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = ; -+ }; -+ -+ i2c3_pins: i2c3 { -+ brcm,pins = <4 5>; -+ brcm,function = ; -+ }; -+ -+ i2c4_pins: i2c4 { -+ brcm,pins = <8 9>; -+ brcm,function = ; -+ }; -+ -+ i2c5_pins: i2c5 { -+ brcm,pins = <12 13>; -+ brcm,function = ; -+ }; -+ -+ i2c6_pins: i2c6 { -+ brcm,pins = <22 23>; -+ brcm,function = ; -+ }; -+ -+ i2s_pins: i2s { -+ brcm,pins = <18 19 20 21>; -+ brcm,function = ; -+ }; -+ -+ sdio_pins: sdio_pins { -+ brcm,pins = <34 35 36 37 38 39>; -+ brcm,function = ; // alt3 = SD1 -+ brcm,pull = <0 2 2 2 2 2>; -+ }; -+ -+ bt_pins: bt_pins { -+ brcm,pins = "-"; // non-empty to keep btuart happy, //4 = 0 -+ // to fool pinctrl -+ brcm,function = <0>; -+ brcm,pull = <2>; -+ }; -+ -+ uart0_pins: uart0_pins { -+ brcm,pins = <32 33>; -+ brcm,function = ; -+ brcm,pull = <0 2>; -+ }; -+ -+ uart1_pins: uart1_pins { -+ brcm,pins; -+ brcm,function; -+ brcm,pull; -+ }; -+ -+ uart2_pins: uart2_pins { -+ brcm,pins = <0 1>; -+ brcm,function = ; -+ brcm,pull = <0 2>; -+ }; -+ -+ uart3_pins: uart3_pins { -+ brcm,pins = <4 5>; -+ brcm,function = ; -+ brcm,pull = <0 2>; -+ }; -+ -+ uart4_pins: uart4_pins { -+ brcm,pins = <8 9>; -+ brcm,function = ; -+ brcm,pull = <0 2>; -+ }; -+ -+ uart5_pins: uart5_pins { -+ brcm,pins = <12 13>; -+ brcm,function = ; -+ brcm,pull = <0 2>; -+ }; -+ -+ audio_pins: audio_pins { -+ brcm,pins = <40 41>; -+ brcm,function = <4>; -+ }; -+}; -+ -+&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 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+/ { -+ __overrides__ { -+ act_led_gpio = <&act_led>,"gpios:4"; -+ 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"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2711.dtsi -@@ -0,0 +1,50 @@ -+#include "bcm2838.dtsi" -+#include "bcm270x.dtsi" -+#include "bcm2708-rpi.dtsi" -+ -+/ { -+ soc { -+ /delete-node/ mailbox@7e00b840; -+ /delete-node/ v3d@7ec00000; -+ }; -+ -+ __overrides__ { -+ arm_freq; -+ }; -+}; -+ -+&dma { -+ brcm,dma-channel-mask = <0x7ef5>; -+}; -+ -+&txp { -+ interrupts = ; -+}; -+ -+&firmwarekms { -+ interrupts = ; -+}; -+ -+&smi { -+ interrupts = ; -+}; -+ -+&mmc { -+ interrupts = ; -+}; -+ -+&mmcnr { -+ interrupts = ; -+}; -+ -+&usb { -+ reg = <0x7e980000 0x10000>, -+ <0x7e00b200 0x200>; -+ interrupts = , -+ ; -+}; -+ -+&gpio { -+ interrupts = , -+ ; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2838.dtsi -@@ -0,0 +1,724 @@ -+// SPDX-License-Identifier: GPL-2.0 -+#include "bcm283x.dtsi" -+ -+#include -+#include -+ -+/ { -+ compatible = "brcm,bcm2838", "brcm,bcm2837"; -+ -+ interrupt-parent = <&gicv2>; -+ -+ soc { -+ ranges = <0x7e000000 0x0 0xfe000000 0x01800000>, -+ <0x7c000000 0x0 0xfc000000 0x02000000>, -+ <0x40000000 0x0 0xff800000 0x00800000>; -+ /* Emulate a contiguous 30-bit address range for DMA */ -+ dma-ranges = <0xc0000000 0x0 0x00000000 0x3c000000>; -+ -+ /delete-node/ mailbox@7e00b840; -+ /delete-node/ interrupt-controller@7e00f300; -+ -+ local_intc: local_intc@40000000 { -+ compatible = "brcm,bcm2836-l1-intc"; -+ reg = <0x40000000 0x100>; -+ }; -+ -+ gicv2: gic400@40041000 { -+ interrupt-controller; -+ #interrupt-cells = <3>; -+ compatible = "arm,gic-400"; -+ reg = <0x40041000 0x1000>, -+ <0x40042000 0x2000>, -+ <0x40046000 0x2000>, -+ <0x40048000 0x2000>; -+ }; -+ -+ thermal: thermal@7d5d2200 { -+ compatible = "brcm,avs-tmon-bcm2838"; -+ reg = <0x7d5d2200 0x2c>; -+ interrupts = ; -+ interrupt-names = "tmon"; -+ clocks = <&clocks BCM2835_CLOCK_TSENS>; -+ #thermal-sensor-cells = <0>; -+ status = "okay"; -+ }; -+ -+ pm: watchdog@7e100000 { -+ reg = <0x7e100000 0x114>, -+ <0x7e00a000 0x24>, -+ <0x7ec11000 0x20>; -+ }; -+ -+ rng@7e104000 { -+ interrupts = ; -+ }; -+ -+ uart2: serial@7e201400 { -+ compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; -+ reg = <0x7e201400 0x200>; -+ interrupts = ; -+ clocks = <&clocks BCM2835_CLOCK_UART>, -+ <&clocks BCM2835_CLOCK_VPU>; -+ clock-names = "uartclk", "apb_pclk"; -+ arm,primecell-periphid = <0x00241011>; -+ status = "disabled"; -+ }; -+ -+ uart3: serial@7e201600 { -+ compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; -+ reg = <0x7e201600 0x200>; -+ interrupts = ; -+ clocks = <&clocks BCM2835_CLOCK_UART>, -+ <&clocks BCM2835_CLOCK_VPU>; -+ clock-names = "uartclk", "apb_pclk"; -+ arm,primecell-periphid = <0x00241011>; -+ status = "disabled"; -+ }; -+ -+ uart4: serial@7e201800 { -+ compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; -+ reg = <0x7e201800 0x200>; -+ interrupts = ; -+ clocks = <&clocks BCM2835_CLOCK_UART>, -+ <&clocks BCM2835_CLOCK_VPU>; -+ clock-names = "uartclk", "apb_pclk"; -+ arm,primecell-periphid = <0x00241011>; -+ status = "disabled"; -+ }; -+ -+ uart5: serial@7e201a00 { -+ compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; -+ reg = <0x7e201a00 0x200>; -+ interrupts = ; -+ clocks = <&clocks BCM2835_CLOCK_UART>, -+ <&clocks BCM2835_CLOCK_VPU>; -+ clock-names = "uartclk", "apb_pclk"; -+ arm,primecell-periphid = <0x00241011>; -+ status = "disabled"; -+ }; -+ -+ spi@7e204000 { -+ reg = <0x7e204000 0x0200>; -+ interrupts = ; -+ }; -+ -+ spi3: spi@7e204600 { -+ compatible = "brcm,bcm2835-spi"; -+ reg = <0x7e204600 0x0200>; -+ interrupts = ; -+ clocks = <&clocks BCM2835_CLOCK_VPU>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ spi4: spi@7e204800 { -+ compatible = "brcm,bcm2835-spi"; -+ reg = <0x7e204800 0x0200>; -+ interrupts = ; -+ clocks = <&clocks BCM2835_CLOCK_VPU>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ spi5: spi@7e204a00 { -+ compatible = "brcm,bcm2835-spi"; -+ reg = <0x7e204a00 0x0200>; -+ interrupts = ; -+ clocks = <&clocks BCM2835_CLOCK_VPU>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ spi6: spi@7e204c00 { -+ compatible = "brcm,bcm2835-spi"; -+ reg = <0x7e204c00 0x0200>; -+ interrupts = ; -+ clocks = <&clocks BCM2835_CLOCK_VPU>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ i2c3: i2c@7e205600 { -+ compatible = "brcm,bcm2835-i2c"; -+ reg = <0x7e205600 0x200>; -+ interrupts = ; -+ clocks = <&clocks BCM2835_CLOCK_VPU>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ i2c4: i2c@7e205800 { -+ compatible = "brcm,bcm2835-i2c"; -+ reg = <0x7e205800 0x200>; -+ interrupts = ; -+ clocks = <&clocks BCM2835_CLOCK_VPU>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ i2c5: i2c@7e205a00 { -+ compatible = "brcm,bcm2835-i2c"; -+ reg = <0x7e205a00 0x200>; -+ interrupts = ; -+ clocks = <&clocks BCM2835_CLOCK_VPU>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ i2c6: i2c@7e205c00 { -+ compatible = "brcm,bcm2835-i2c"; -+ reg = <0x7e205c00 0x200>; -+ interrupts = ; -+ clocks = <&clocks BCM2835_CLOCK_VPU>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ pixelvalve@7e206000 { -+ interrupts = ; -+ }; -+ -+ pixelvalve@7e207000 { -+ interrupts = ; -+ }; -+ -+ emmc2: emmc2@7e340000 { -+ compatible = "brcm,bcm2711-emmc2"; -+ status = "okay"; -+ interrupts = ; -+ clocks = <&clocks BCM2838_CLOCK_EMMC2>; -+ reg = <0x7e340000 0x100>; -+ }; -+ -+ hvs@7e400000 { -+ interrupts = ; -+ }; -+ -+ pixelvalve@7e807000 { -+ interrupts = ; -+ }; -+ }; -+ -+ arm-pmu { -+ /* -+ * N.B. the A72 PMU support only exists in arch/arm64, hence -+ * the fallback to the A53 version. -+ */ -+ compatible = "arm,cortex-a72-pmu", "arm,cortex-a53-pmu"; -+ interrupts = , -+ , -+ , -+ ; -+ }; -+ -+ timer { -+ compatible = "arm,armv7-timer"; -+ interrupts = , -+ , -+ , -+ ; -+ arm,cpu-registers-not-fw-configured; -+ always-on; -+ }; -+ -+ cpus: cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ enable-method = "brcm,bcm2836-smp"; // for ARM 32-bit -+ -+ cpu0: cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a72"; -+ reg = <0>; -+ enable-method = "spin-table"; -+ cpu-release-addr = <0x0 0x000000d8>; -+ }; -+ -+ cpu1: cpu@1 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a72"; -+ reg = <1>; -+ enable-method = "spin-table"; -+ cpu-release-addr = <0x0 0x000000e0>; -+ }; -+ -+ cpu2: cpu@2 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a72"; -+ reg = <2>; -+ enable-method = "spin-table"; -+ cpu-release-addr = <0x0 0x000000e8>; -+ }; -+ -+ cpu3: cpu@3 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a72"; -+ reg = <3>; -+ enable-method = "spin-table"; -+ cpu-release-addr = <0x0 0x000000f0>; -+ }; -+ }; -+ -+ v3dbus { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0x7c500000 0x0 0xfc500000 0x03300000>, -+ <0x40000000 0x0 0xff800000 0x00800000>; -+ dma-ranges = <0x00000000 0x0 0x00000000 0x3c000000>; -+ -+ v3d: v3d@7ec04000 { -+ compatible = "brcm,2711-v3d"; -+ reg = -+ <0x7ec00000 0x4000>, -+ <0x7ec04000 0x4000>; -+ reg-names = "hub", "core0"; -+ -+ power-domains = <&pm BCM2835_POWER_DOMAIN_GRAFX_V3D>; -+ resets = <&pm BCM2835_RESET_V3D>; -+ clocks = <&clocks BCM2835_CLOCK_V3D>; -+ interrupts = ; -+ status = "okay"; -+ }; -+ }; -+ -+ scb: scb { -+ compatible = "simple-bus"; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ -+ ranges = <0x0 0x7c000000 0x0 0xfc000000 0x03800000>, -+ <0x0 0x40000000 0x0 0xff800000 0x00800000>, -+ <0x6 0x00000000 0x6 0x00000000 0x40000000>, -+ <0x0 0x00000000 0x0 0x00000000 0xfc000000>; -+ dma-ranges = <0x0 0x00000000 0x0 0x00000000 0xfc000000>; -+ -+ pcie_0: pcie@7d500000 { -+ reg = <0x0 0x7d500000 0x9310>, -+ <0x0 0x7e00f300 0x20>; -+ msi-controller; -+ msi-parent = <&pcie_0>; -+ #address-cells = <3>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ bus-range = <0x0 0x01>; -+ compatible = "brcm,bcm7211-pcie", "brcm,bcm7445-pcie", -+ "brcm,pci-plat-dev"; -+ max-link-speed = <2>; -+ tot-num-pcie = <1>; -+ linux,pci-domain = <0>; -+ interrupts = , -+ ; -+ interrupt-names = "pcie", "msi"; -+ interrupt-map-mask = <0x0 0x0 0x0 0x7>; -+ interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 143 -+ IRQ_TYPE_LEVEL_HIGH -+ 0 0 0 2 &gicv2 GIC_SPI 144 -+ IRQ_TYPE_LEVEL_HIGH -+ 0 0 0 3 &gicv2 GIC_SPI 145 -+ IRQ_TYPE_LEVEL_HIGH -+ 0 0 0 4 &gicv2 GIC_SPI 146 -+ IRQ_TYPE_LEVEL_HIGH>; -+ -+ /* Map outbound accesses from scb:0x6_00000000-03ffffff -+ * to pci:0x0_f8000000-fbffffff -+ */ -+ ranges = <0x02000000 0x0 0xf8000000 0x6 0x00000000 -+ 0x0 0x04000000>; -+ /* Map inbound accesses from pci:0x0_00000000..ffffffff -+ * to scb:0x0_00000000-ffffffff -+ */ -+ dma-ranges = <0x02000000 0x0 0x00000000 0x0 0x00000000 -+ 0x1 0x00000000>; -+ status = "okay"; -+ }; -+ -+ genet: genet@7d580000 { -+ compatible = "brcm,genet-v5"; -+ reg = <0x0 0x7d580000 0x10000>; -+ status = "okay"; -+ #address-cells = <0x1>; -+ #size-cells = <0x1>; -+ interrupts = , -+ ; -+ phy-handle = <&phy1>; -+ phy-mode = "rgmii"; -+ mdio@e14 { -+ #address-cells = <0x0>; -+ #size-cells = <0x1>; -+ compatible = "brcm,genet-mdio-v5"; -+ reg = <0xe14 0x8>; -+ reg-names = "mdio"; -+ phy1: genet-phy@0 { -+ compatible = -+ "ethernet-phy-ieee802.3-c22"; -+ /* No interrupts - use PHY_POLL */ -+ max-speed = <1000>; -+ reg = <0x1>; -+ }; -+ }; -+ }; -+ -+ xhci: xhci@7e9c0000 { -+ compatible = "generic-xhci"; -+ status = "disabled"; -+ reg = <0x0 0x7e9c0000 0x100000>; -+ interrupts = ; -+ }; -+ -+ vchiq: mailbox@7e00b840 { -+ compatible = "brcm,bcm2838-vchiq"; -+ reg = <0 0x7e00b840 0x3c>; -+ interrupts = ; -+ }; -+ -+ hevc-decoder@7eb00000 { -+ compatible = "raspberrypi,argon-hevc-decoder"; -+ reg = <0x0 0x7eb00000 0x10000>; -+ status = "okay"; -+ }; -+ -+ argon-local-intc@7eb10000 { -+ compatible = "raspberrypi,argon-local-intc"; -+ reg = <0x0 0x7eb10000 0x1000>; -+ status = "okay"; -+ interrupts = ; -+ }; -+ -+ h264-decoder@7eb20000 { -+ compatible = "raspberrypi,argon-h264-decoder"; -+ reg = <0x0 0x7eb20000 0x10000>; -+ status = "okay"; -+ }; -+ -+ vp9-decoder@7eb30000 { -+ compatible = "raspberrypi,argon-vp9-decoder"; -+ reg = <0x0 0x7eb30000 0x10000>; -+ status = "okay"; -+ }; -+ }; -+}; -+ -+&clk_osc { -+ clock-frequency = <54000000>; -+}; -+ -+&clocks { -+ compatible = "brcm,bcm2838-cprman"; -+}; -+ -+&cpu_thermal { -+ coefficients = <(-487) 410040>; -+}; -+ -+&dsi0 { -+ interrupts = ; -+}; -+ -+&dsi1 { -+ interrupts = ; -+}; -+ -+&gpio { -+ gpclk0_gpio49: gpclk0_gpio49 { -+ brcm,pins = <49>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ gpclk1_gpio50: gpclk1_gpio50 { -+ brcm,pins = <50>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ gpclk2_gpio51: gpclk2_gpio51 { -+ brcm,pins = <51>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ -+ i2c0_gpio46: i2c0_gpio46 { -+ brcm,pins = <46 47>; -+ brcm,function = ; -+ }; -+ i2c1_gpio46: i2c1_gpio46 { -+ brcm,pins = <46 47>; -+ brcm,function = ; -+ }; -+ i2c3_gpio2: i2c3_gpio2 { -+ brcm,pins = <2 3>; -+ brcm,function = ; -+ }; -+ i2c3_gpio4: i2c3_gpio4 { -+ brcm,pins = <4 5>; -+ brcm,function = ; -+ }; -+ i2c4_gpio6: i2c4_gpio6 { -+ brcm,pins = <6 7>; -+ brcm,function = ; -+ }; -+ i2c4_gpio8: i2c4_gpio8 { -+ brcm,pins = <8 9>; -+ brcm,function = ; -+ }; -+ i2c5_gpio10: i2c5_gpio10 { -+ brcm,pins = <10 11>; -+ brcm,function = ; -+ }; -+ i2c5_gpio12: i2c5_gpio12 { -+ brcm,pins = <12 13>; -+ brcm,function = ; -+ }; -+ i2c6_gpio0: i2c6_gpio0 { -+ brcm,pins = <0 1>; -+ brcm,function = ; -+ }; -+ i2c6_gpio22: i2c6_gpio22 { -+ brcm,pins = <22 23>; -+ brcm,function = ; -+ }; -+ i2c_slave_gpio8: i2c_slave_gpio8 { -+ brcm,pins = <8 9 10 11>; -+ brcm,function = ; -+ }; -+ -+ jtag_gpio48: jtag_gpio48 { -+ brcm,pins = <48 49 50 51 52 53>; -+ brcm,function = ; -+ }; -+ -+ mii_gpio28: mii_gpio28 { -+ brcm,pins = <28 29 30 31>; -+ brcm,function = ; -+ }; -+ mii_gpio36: mii_gpio36 { -+ brcm,pins = <36 37 38 39>; -+ brcm,function = ; -+ }; -+ -+ pcm_gpio50: pcm_gpio50 { -+ brcm,pins = <50 51 52 53>; -+ brcm,function = ; -+ }; -+ -+ pwm0_gpio52: pwm0_gpio52 { -+ brcm,pins = <52>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ pwm1_gpio53: pwm1_gpio53 { -+ brcm,pins = <53>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ -+ /* The following group consists of: -+ * RGMII_START_STOP -+ * RGMII_RX_OK -+ */ -+ rgmii_gpio35: rgmii_gpio35 { -+ brcm,pins = <35 36>; -+ brcm,function = ; -+ }; -+ rgmii_irq_gpio34: rgmii_irq_gpio34 { -+ brcm,pins = <34>; -+ brcm,function = ; -+ }; -+ rgmii_irq_gpio39: rgmii_irq_gpio39 { -+ brcm,pins = <39>; -+ brcm,function = ; -+ }; -+ rgmii_mdio_gpio28: rgmii_mdio_gpio28 { -+ brcm,pins = <28 29>; -+ brcm,function = ; -+ }; -+ rgmii_mdio_gpio37: rgmii_mdio_gpio37 { -+ brcm,pins = <37 38>; -+ brcm,function = ; -+ }; -+ -+ spi0_gpio46: spi0_gpio46 { -+ brcm,pins = <46 47 48 49>; -+ brcm,function = ; -+ }; -+ spi2_gpio46: spi2_gpio46 { -+ brcm,pins = <46 47 48 49 50>; -+ brcm,function = ; -+ }; -+ spi3_gpio0: spi3_gpio0 { -+ brcm,pins = <0 1 2 3>; -+ brcm,function = ; -+ }; -+ spi4_gpio4: spi4_gpio4 { -+ brcm,pins = <4 5 6 7>; -+ brcm,function = ; -+ }; -+ spi5_gpio12: spi5_gpio12 { -+ brcm,pins = <12 13 14 15>; -+ brcm,function = ; -+ }; -+ spi6_gpio18: spi6_gpio18 { -+ brcm,pins = <18 19 20 21>; -+ brcm,function = ; -+ }; -+ -+ uart2_gpio0: uart2_gpio0 { -+ brcm,pins = <0 1>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ uart2_ctsrts_gpio2: uart2_ctsrts_gpio2 { -+ brcm,pins = <2 3>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ uart3_gpio4: uart3_gpio4 { -+ brcm,pins = <4 5>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ uart3_ctsrts_gpio6: uart3_ctsrts_gpio6 { -+ brcm,pins = <6 7>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ uart4_gpio8: uart4_gpio8 { -+ brcm,pins = <8 9>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ uart4_ctsrts_gpio10: uart4_ctsrts_gpio10 { -+ brcm,pins = <10 11>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ uart5_gpio12: uart5_gpio12 { -+ brcm,pins = <12 13>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ uart5_ctsrts_gpio14: uart5_ctsrts_gpio14 { -+ brcm,pins = <14 15>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+}; -+ -+&vec { -+ interrupts = ; -+}; -+ -+&usb { -+ interrupts = ; -+}; -+ -+&hdmi { -+ interrupts = , -+ ; -+}; -+ -+&uart1 { -+ interrupts = ; -+}; -+ -+&spi1 { -+ interrupts = ; -+}; -+ -+&spi2 { -+ interrupts = ; -+}; -+ -+&csi0 { -+ interrupts = ; -+}; -+ -+&csi1 { -+ interrupts = ; -+}; -+ -+&sdhci { -+ interrupts = ; -+}; -+ -+&i2c0 { -+ interrupts = ; -+}; -+ -+&i2c1 { -+ interrupts = ; -+}; -+ -+&i2c2 { -+ interrupts = ; -+}; -+ -+&gpio { -+ interrupts = , -+ , -+ , -+ ; -+}; -+ -+&mailbox { -+ interrupts = ; -+}; -+ -+&rng { -+ compatible = "brcm,bcm2838-rng200"; -+}; -+ -+&sdhost { -+ interrupts = ; -+}; -+ -+&uart0 { -+ interrupts = ; -+}; -+ -+&dma { -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , /* dmalite 7 */ -+ , /* dmalite 8 */ -+ , /* dmalite 9 */ -+ , /* dmalite 10 */ -+ /* DMA4 - 40 bit DMA engines */ -+ , /* dma4 11 */ -+ , /* dma4 12 */ -+ , /* dma4 13 */ -+ ; /* dma4 14 */ -+ interrupt-names = "dma0", -+ "dma1", -+ "dma2", -+ "dma3", -+ "dma4", -+ "dma5", -+ "dma6", -+ "dma7", -+ "dma8", -+ "dma9", -+ "dma10", -+ "dma11", -+ "dma12", -+ "dma13", -+ "dma14"; -+ brcm,dma-channel-mask = <0x7ef5>; -+}; diff --git a/target/linux/brcm2708/patches-4.19/950-0639-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch b/target/linux/brcm2708/patches-4.19/950-0639-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch new file mode 100644 index 0000000000..ca0ee61fbd --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0639-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch @@ -0,0 +1,44 @@ +From 313e17bef58a02b4cb37f8be66b4f66267d46205 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 4 Sep 2018 11:50:25 +0100 +Subject: [PATCH 639/725] config: Permit LPAE and PCIE_BRCMSTB on BCM2835 + +--- + arch/arm/mach-bcm/Kconfig | 4 ++++ + drivers/pci/controller/Kconfig | 4 ++-- + 2 files changed, 6 insertions(+), 2 deletions(-) + +--- a/arch/arm/mach-bcm/Kconfig ++++ b/arch/arm/mach-bcm/Kconfig +@@ -161,6 +161,7 @@ config ARCH_BCM2835 + select GPIOLIB + select ARM_AMBA + select ARM_ERRATA_411920 if ARCH_MULTI_V6 ++ select ARM_GIC + select ARM_TIMER_SP804 + select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7 + select TIMER_OF +@@ -169,6 +170,9 @@ config ARCH_BCM2835 + select PINCTRL + select PINCTRL_BCM2835 + select MFD_SYSCON if ARCH_MULTI_V7 ++ select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE ++ select ZONE_DMA if ARM_LPAE ++ select MFD_CORE + help + This enables support for the Broadcom BCM2835 and BCM2836 SoCs. + This SoC is used in the Raspberry Pi and Roku 2 devices. +--- a/drivers/pci/controller/Kconfig ++++ b/drivers/pci/controller/Kconfig +@@ -280,9 +280,9 @@ config VMD + + config PCIE_BRCMSTB + tristate "Broadcom Brcmstb PCIe platform host driver" +- depends on ARCH_BRCMSTB || BMIPS_GENERIC ++ depends on ARCH_BRCMSTB || BMIPS_GENERIC || ARCH_BCM2835 + depends on OF +- depends on SOC_BRCMSTB ++ depends on SOC_BRCMSTB || ARCH_BCM2835 + default ARCH_BRCMSTB || BMIPS_GENERIC + help + Adds support for Broadcom Settop Box PCIe host controller. diff --git a/target/linux/brcm2708/patches-4.19/950-0640-configs-Add-bcm2711_defconfig.patch b/target/linux/brcm2708/patches-4.19/950-0640-configs-Add-bcm2711_defconfig.patch new file mode 100644 index 0000000000..5490bdc867 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0640-configs-Add-bcm2711_defconfig.patch @@ -0,0 +1,1343 @@ +From 2caac63444825448e0b588af6adae8d80365bbed Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 29 May 2019 15:40:21 +0100 +Subject: [PATCH 640/725] configs: Add bcm2711_defconfig + +--- + arch/arm/configs/bcm2711_defconfig | 1330 ++++++++++++++++++++++++++++ + 1 file changed, 1330 insertions(+) + create mode 100644 arch/arm/configs/bcm2711_defconfig + +--- /dev/null ++++ b/arch/arm/configs/bcm2711_defconfig +@@ -0,0 +1,1330 @@ ++CONFIG_LOCALVERSION="-v7l" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SYSVIPC=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_GENERIC_IRQ_DEBUGFS=y ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_PREEMPT_VOLUNTARY=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_TASKSTATS=y ++CONFIG_TASK_DELAY_ACCT=y ++CONFIG_TASK_XACCT=y ++CONFIG_TASK_IO_ACCOUNTING=y ++CONFIG_IKCONFIG=m ++CONFIG_IKCONFIG_PROC=y ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CPUSETS=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_NAMESPACES=y ++CONFIG_USER_NS=y ++CONFIG_SCHED_AUTOGROUP=y ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_EMBEDDED=y ++# CONFIG_COMPAT_BRK is not set ++CONFIG_PROFILING=y ++CONFIG_ARCH_BCM=y ++CONFIG_ARCH_BCM2835=y ++CONFIG_ARM_LPAE=y ++# CONFIG_CACHE_L2X0 is not set ++CONFIG_PCI=y ++CONFIG_PCI_MSI=y ++CONFIG_PCIE_BRCMSTB=y ++CONFIG_SMP=y ++CONFIG_HIGHMEM=y ++CONFIG_UACCESS_WITH_MEMCPY=y ++CONFIG_SECCOMP=y ++# CONFIG_ATAGS is not set ++CONFIG_ZBOOT_ROM_TEXT=0x0 ++CONFIG_ZBOOT_ROM_BSS=0x0 ++CONFIG_CMDLINE="console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait" ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_STAT=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y ++CONFIG_CPU_FREQ_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_GOV_ONDEMAND=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y ++CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y ++CONFIG_VFP=y ++CONFIG_NEON=y ++CONFIG_KERNEL_MODE_NEON=y ++# CONFIG_SUSPEND is not set ++CONFIG_PM=y ++CONFIG_RASPBERRYPI_FIRMWARE=y ++CONFIG_ARM_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM_NEON=m ++CONFIG_CRYPTO_AES_ARM=m ++CONFIG_CRYPTO_AES_ARM_BS=m ++CONFIG_OPROFILE=m ++CONFIG_KPROBES=y ++CONFIG_JUMP_LABEL=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++CONFIG_MODULE_SRCVERSION_ALL=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_MAC_PARTITION=y ++CONFIG_BINFMT_MISC=m ++CONFIG_CLEANCACHE=y ++CONFIG_FRONTSWAP=y ++CONFIG_CMA=y ++CONFIG_ZSMALLOC=m ++CONFIG_PGTABLE_MAPPING=y ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_XFRM_USER=y ++CONFIG_NET_KEY=m ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_RARP=y ++CONFIG_NET_IPIP=m ++CONFIG_NET_IPGRE_DEMUX=m ++CONFIG_NET_IPGRE=m ++CONFIG_IP_MROUTE=y ++CONFIG_IP_MROUTE_MULTIPLE_TABLES=y ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++CONFIG_SYN_COOKIES=y ++CONFIG_INET_AH=m ++CONFIG_INET_ESP=m ++CONFIG_INET_IPCOMP=m ++CONFIG_INET_XFRM_MODE_TRANSPORT=m ++CONFIG_INET_XFRM_MODE_TUNNEL=m ++CONFIG_INET_XFRM_MODE_BEET=m ++CONFIG_INET_DIAG=m ++CONFIG_TCP_CONG_ADVANCED=y ++CONFIG_TCP_CONG_BBR=m ++CONFIG_IPV6=m ++CONFIG_IPV6_ROUTER_PREF=y ++CONFIG_IPV6_ROUTE_INFO=y ++CONFIG_INET6_AH=m ++CONFIG_INET6_ESP=m ++CONFIG_INET6_IPCOMP=m ++CONFIG_IPV6_SIT_6RD=y ++CONFIG_IPV6_TUNNEL=m ++CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_IPV6_SUBTREES=y ++CONFIG_IPV6_MROUTE=y ++CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y ++CONFIG_IPV6_PIMSM_V2=y ++CONFIG_NETFILTER=y ++CONFIG_NF_CONNTRACK=m ++CONFIG_NF_CONNTRACK_ZONES=y ++CONFIG_NF_CONNTRACK_EVENTS=y ++CONFIG_NF_CONNTRACK_TIMESTAMP=y ++CONFIG_NF_CONNTRACK_AMANDA=m ++CONFIG_NF_CONNTRACK_FTP=m ++CONFIG_NF_CONNTRACK_H323=m ++CONFIG_NF_CONNTRACK_IRC=m ++CONFIG_NF_CONNTRACK_NETBIOS_NS=m ++CONFIG_NF_CONNTRACK_SNMP=m ++CONFIG_NF_CONNTRACK_PPTP=m ++CONFIG_NF_CONNTRACK_SANE=m ++CONFIG_NF_CONNTRACK_SIP=m ++CONFIG_NF_CONNTRACK_TFTP=m ++CONFIG_NF_CT_NETLINK=m ++CONFIG_NETFILTER_XT_SET=m ++CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m ++CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m ++CONFIG_NETFILTER_XT_TARGET_CONNMARK=m ++CONFIG_NETFILTER_XT_TARGET_DSCP=m ++CONFIG_NETFILTER_XT_TARGET_HMARK=m ++CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m ++CONFIG_NETFILTER_XT_TARGET_LED=m ++CONFIG_NETFILTER_XT_TARGET_LOG=m ++CONFIG_NETFILTER_XT_TARGET_MARK=m ++CONFIG_NETFILTER_XT_TARGET_NFLOG=m ++CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m ++CONFIG_NETFILTER_XT_TARGET_NOTRACK=m ++CONFIG_NETFILTER_XT_TARGET_TEE=m ++CONFIG_NETFILTER_XT_TARGET_TPROXY=m ++CONFIG_NETFILTER_XT_TARGET_TRACE=m ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=m ++CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m ++CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m ++CONFIG_NETFILTER_XT_MATCH_BPF=m ++CONFIG_NETFILTER_XT_MATCH_CLUSTER=m ++CONFIG_NETFILTER_XT_MATCH_COMMENT=m ++CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m ++CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m ++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=m ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m ++CONFIG_NETFILTER_XT_MATCH_CPU=m ++CONFIG_NETFILTER_XT_MATCH_DCCP=m ++CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m ++CONFIG_NETFILTER_XT_MATCH_DSCP=m ++CONFIG_NETFILTER_XT_MATCH_ESP=m ++CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m ++CONFIG_NETFILTER_XT_MATCH_HELPER=m ++CONFIG_NETFILTER_XT_MATCH_IPRANGE=m ++CONFIG_NETFILTER_XT_MATCH_IPVS=m ++CONFIG_NETFILTER_XT_MATCH_LENGTH=m ++CONFIG_NETFILTER_XT_MATCH_LIMIT=m ++CONFIG_NETFILTER_XT_MATCH_MAC=m ++CONFIG_NETFILTER_XT_MATCH_MARK=m ++CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m ++CONFIG_NETFILTER_XT_MATCH_NFACCT=m ++CONFIG_NETFILTER_XT_MATCH_OSF=m ++CONFIG_NETFILTER_XT_MATCH_OWNER=m ++CONFIG_NETFILTER_XT_MATCH_POLICY=m ++CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m ++CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m ++CONFIG_NETFILTER_XT_MATCH_QUOTA=m ++CONFIG_NETFILTER_XT_MATCH_RATEEST=m ++CONFIG_NETFILTER_XT_MATCH_REALM=m ++CONFIG_NETFILTER_XT_MATCH_RECENT=m ++CONFIG_NETFILTER_XT_MATCH_STATE=m ++CONFIG_NETFILTER_XT_MATCH_STATISTIC=m ++CONFIG_NETFILTER_XT_MATCH_STRING=m ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=m ++CONFIG_NETFILTER_XT_MATCH_TIME=m ++CONFIG_NETFILTER_XT_MATCH_U32=m ++CONFIG_IP_SET=m ++CONFIG_IP_SET_BITMAP_IP=m ++CONFIG_IP_SET_BITMAP_IPMAC=m ++CONFIG_IP_SET_BITMAP_PORT=m ++CONFIG_IP_SET_HASH_IP=m ++CONFIG_IP_SET_HASH_IPPORT=m ++CONFIG_IP_SET_HASH_IPPORTIP=m ++CONFIG_IP_SET_HASH_IPPORTNET=m ++CONFIG_IP_SET_HASH_NET=m ++CONFIG_IP_SET_HASH_NETPORT=m ++CONFIG_IP_SET_HASH_NETIFACE=m ++CONFIG_IP_SET_LIST_SET=m ++CONFIG_IP_VS=m ++CONFIG_IP_VS_PROTO_TCP=y ++CONFIG_IP_VS_PROTO_UDP=y ++CONFIG_IP_VS_PROTO_ESP=y ++CONFIG_IP_VS_PROTO_AH=y ++CONFIG_IP_VS_PROTO_SCTP=y ++CONFIG_IP_VS_RR=m ++CONFIG_IP_VS_WRR=m ++CONFIG_IP_VS_LC=m ++CONFIG_IP_VS_WLC=m ++CONFIG_IP_VS_LBLC=m ++CONFIG_IP_VS_LBLCR=m ++CONFIG_IP_VS_DH=m ++CONFIG_IP_VS_SH=m ++CONFIG_IP_VS_SED=m ++CONFIG_IP_VS_NQ=m ++CONFIG_IP_VS_FTP=m ++CONFIG_IP_VS_PE_SIP=m ++CONFIG_IP_NF_IPTABLES=m ++CONFIG_IP_NF_MATCH_AH=m ++CONFIG_IP_NF_MATCH_ECN=m ++CONFIG_IP_NF_MATCH_RPFILTER=m ++CONFIG_IP_NF_MATCH_TTL=m ++CONFIG_IP_NF_FILTER=m ++CONFIG_IP_NF_TARGET_REJECT=m ++CONFIG_IP_NF_NAT=m ++CONFIG_IP_NF_TARGET_MASQUERADE=m ++CONFIG_IP_NF_TARGET_NETMAP=m ++CONFIG_IP_NF_TARGET_REDIRECT=m ++CONFIG_IP_NF_MANGLE=m ++CONFIG_IP_NF_TARGET_CLUSTERIP=m ++CONFIG_IP_NF_TARGET_ECN=m ++CONFIG_IP_NF_TARGET_TTL=m ++CONFIG_IP_NF_RAW=m ++CONFIG_IP_NF_ARPTABLES=m ++CONFIG_IP_NF_ARPFILTER=m ++CONFIG_IP_NF_ARP_MANGLE=m ++CONFIG_IP6_NF_IPTABLES=m ++CONFIG_IP6_NF_MATCH_AH=m ++CONFIG_IP6_NF_MATCH_EUI64=m ++CONFIG_IP6_NF_MATCH_FRAG=m ++CONFIG_IP6_NF_MATCH_OPTS=m ++CONFIG_IP6_NF_MATCH_HL=m ++CONFIG_IP6_NF_MATCH_IPV6HEADER=m ++CONFIG_IP6_NF_MATCH_MH=m ++CONFIG_IP6_NF_MATCH_RPFILTER=m ++CONFIG_IP6_NF_MATCH_RT=m ++CONFIG_IP6_NF_TARGET_HL=m ++CONFIG_IP6_NF_FILTER=m ++CONFIG_IP6_NF_TARGET_REJECT=m ++CONFIG_IP6_NF_MANGLE=m ++CONFIG_IP6_NF_RAW=m ++CONFIG_IP6_NF_NAT=m ++CONFIG_IP6_NF_TARGET_MASQUERADE=m ++CONFIG_IP6_NF_TARGET_NPT=m ++CONFIG_BRIDGE_NF_EBTABLES=m ++CONFIG_BRIDGE_EBT_BROUTE=m ++CONFIG_BRIDGE_EBT_T_FILTER=m ++CONFIG_BRIDGE_EBT_T_NAT=m ++CONFIG_BRIDGE_EBT_802_3=m ++CONFIG_BRIDGE_EBT_AMONG=m ++CONFIG_BRIDGE_EBT_ARP=m ++CONFIG_BRIDGE_EBT_IP=m ++CONFIG_BRIDGE_EBT_IP6=m ++CONFIG_BRIDGE_EBT_LIMIT=m ++CONFIG_BRIDGE_EBT_MARK=m ++CONFIG_BRIDGE_EBT_PKTTYPE=m ++CONFIG_BRIDGE_EBT_STP=m ++CONFIG_BRIDGE_EBT_VLAN=m ++CONFIG_BRIDGE_EBT_ARPREPLY=m ++CONFIG_BRIDGE_EBT_DNAT=m ++CONFIG_BRIDGE_EBT_MARK_T=m ++CONFIG_BRIDGE_EBT_REDIRECT=m ++CONFIG_BRIDGE_EBT_SNAT=m ++CONFIG_BRIDGE_EBT_LOG=m ++CONFIG_BRIDGE_EBT_NFLOG=m ++CONFIG_SCTP_COOKIE_HMAC_SHA1=y ++CONFIG_ATM=m ++CONFIG_L2TP=m ++CONFIG_L2TP_V3=y ++CONFIG_L2TP_IP=m ++CONFIG_L2TP_ETH=m ++CONFIG_BRIDGE=m ++CONFIG_VLAN_8021Q=m ++CONFIG_VLAN_8021Q_GVRP=y ++CONFIG_ATALK=m ++CONFIG_6LOWPAN=m ++CONFIG_IEEE802154=m ++CONFIG_IEEE802154_6LOWPAN=m ++CONFIG_MAC802154=m ++CONFIG_NET_SCHED=y ++CONFIG_NET_SCH_CBQ=m ++CONFIG_NET_SCH_HTB=m ++CONFIG_NET_SCH_HFSC=m ++CONFIG_NET_SCH_ATM=m ++CONFIG_NET_SCH_PRIO=m ++CONFIG_NET_SCH_MULTIQ=m ++CONFIG_NET_SCH_RED=m ++CONFIG_NET_SCH_SFB=m ++CONFIG_NET_SCH_SFQ=m ++CONFIG_NET_SCH_TEQL=m ++CONFIG_NET_SCH_TBF=m ++CONFIG_NET_SCH_GRED=m ++CONFIG_NET_SCH_DSMARK=m ++CONFIG_NET_SCH_NETEM=m ++CONFIG_NET_SCH_DRR=m ++CONFIG_NET_SCH_MQPRIO=m ++CONFIG_NET_SCH_CHOKE=m ++CONFIG_NET_SCH_QFQ=m ++CONFIG_NET_SCH_CODEL=m ++CONFIG_NET_SCH_FQ_CODEL=m ++CONFIG_NET_SCH_FQ=m ++CONFIG_NET_SCH_HHF=m ++CONFIG_NET_SCH_PIE=m ++CONFIG_NET_SCH_INGRESS=m ++CONFIG_NET_SCH_PLUG=m ++CONFIG_NET_CLS_BASIC=m ++CONFIG_NET_CLS_TCINDEX=m ++CONFIG_NET_CLS_ROUTE4=m ++CONFIG_NET_CLS_FW=m ++CONFIG_NET_CLS_U32=m ++CONFIG_CLS_U32_MARK=y ++CONFIG_NET_CLS_RSVP=m ++CONFIG_NET_CLS_RSVP6=m ++CONFIG_NET_CLS_FLOW=m ++CONFIG_NET_CLS_CGROUP=m ++CONFIG_NET_EMATCH=y ++CONFIG_NET_EMATCH_CMP=m ++CONFIG_NET_EMATCH_NBYTE=m ++CONFIG_NET_EMATCH_U32=m ++CONFIG_NET_EMATCH_META=m ++CONFIG_NET_EMATCH_TEXT=m ++CONFIG_NET_EMATCH_IPSET=m ++CONFIG_NET_CLS_ACT=y ++CONFIG_NET_ACT_POLICE=m ++CONFIG_NET_ACT_GACT=m ++CONFIG_GACT_PROB=y ++CONFIG_NET_ACT_MIRRED=m ++CONFIG_NET_ACT_IPT=m ++CONFIG_NET_ACT_NAT=m ++CONFIG_NET_ACT_PEDIT=m ++CONFIG_NET_ACT_SIMP=m ++CONFIG_NET_ACT_SKBEDIT=m ++CONFIG_NET_ACT_CSUM=m ++CONFIG_BATMAN_ADV=m ++CONFIG_OPENVSWITCH=m ++CONFIG_NET_PKTGEN=m ++CONFIG_HAMRADIO=y ++CONFIG_AX25=m ++CONFIG_NETROM=m ++CONFIG_ROSE=m ++CONFIG_MKISS=m ++CONFIG_6PACK=m ++CONFIG_BPQETHER=m ++CONFIG_BAYCOM_SER_FDX=m ++CONFIG_BAYCOM_SER_HDX=m ++CONFIG_YAM=m ++CONFIG_CAN=m ++CONFIG_CAN_VCAN=m ++CONFIG_CAN_SLCAN=m ++CONFIG_CAN_MCP251X=m ++CONFIG_CAN_GS_USB=m ++CONFIG_BT=m ++CONFIG_BT_RFCOMM=m ++CONFIG_BT_RFCOMM_TTY=y ++CONFIG_BT_BNEP=m ++CONFIG_BT_BNEP_MC_FILTER=y ++CONFIG_BT_BNEP_PROTO_FILTER=y ++CONFIG_BT_HIDP=m ++CONFIG_BT_6LOWPAN=m ++CONFIG_BT_HCIBTUSB=m ++CONFIG_BT_HCIUART=m ++CONFIG_BT_HCIUART_3WIRE=y ++CONFIG_BT_HCIUART_BCM=y ++CONFIG_BT_HCIBCM203X=m ++CONFIG_BT_HCIBPA10X=m ++CONFIG_BT_HCIBFUSB=m ++CONFIG_BT_HCIVHCI=m ++CONFIG_BT_MRVL=m ++CONFIG_BT_MRVL_SDIO=m ++CONFIG_BT_ATH3K=m ++CONFIG_BT_WILINK=m ++CONFIG_CFG80211=m ++CONFIG_MAC80211=m ++CONFIG_MAC80211_MESH=y ++CONFIG_WIMAX=m ++CONFIG_RFKILL=m ++CONFIG_RFKILL_INPUT=y ++CONFIG_NET_9P=m ++CONFIG_NFC=m ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=5 ++CONFIG_MTD=m ++CONFIG_MTD_BLOCK=m ++CONFIG_MTD_M25P80=m ++CONFIG_MTD_BLOCK2MTD=m ++CONFIG_MTD_NAND=m ++CONFIG_MTD_SPI_NOR=m ++CONFIG_MTD_UBI=m ++CONFIG_OF_CONFIGFS=y ++CONFIG_ZRAM=m ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_CRYPTOLOOP=m ++CONFIG_BLK_DEV_DRBD=m ++CONFIG_BLK_DEV_NBD=m ++CONFIG_BLK_DEV_RAM=y ++CONFIG_CDROM_PKTCDVD=m ++CONFIG_ATA_OVER_ETH=m ++CONFIG_EEPROM_AT24=m ++CONFIG_TI_ST=m ++CONFIG_SCSI=y ++# CONFIG_SCSI_PROC_FS is not set ++CONFIG_BLK_DEV_SD=y ++CONFIG_CHR_DEV_ST=m ++CONFIG_CHR_DEV_OSST=m ++CONFIG_BLK_DEV_SR=m ++CONFIG_CHR_DEV_SG=m ++CONFIG_SCSI_ISCSI_ATTRS=y ++CONFIG_ISCSI_TCP=m ++CONFIG_ISCSI_BOOT_SYSFS=m ++CONFIG_MD=y ++CONFIG_MD_LINEAR=m ++CONFIG_BLK_DEV_DM=m ++CONFIG_DM_CRYPT=m ++CONFIG_DM_SNAPSHOT=m ++CONFIG_DM_THIN_PROVISIONING=m ++CONFIG_DM_CACHE=m ++CONFIG_DM_MIRROR=m ++CONFIG_DM_LOG_USERSPACE=m ++CONFIG_DM_RAID=m ++CONFIG_DM_ZERO=m ++CONFIG_DM_DELAY=m ++CONFIG_NETDEVICES=y ++CONFIG_BONDING=m ++CONFIG_DUMMY=m ++CONFIG_IFB=m ++CONFIG_MACVLAN=m ++CONFIG_IPVLAN=m ++CONFIG_VXLAN=m ++CONFIG_NETCONSOLE=m ++CONFIG_TUN=m ++CONFIG_VETH=m ++CONFIG_BCMGENET=y ++CONFIG_ENC28J60=m ++CONFIG_QCA7000_SPI=m ++CONFIG_MDIO_BITBANG=m ++CONFIG_BROADCOM_PHY=y ++CONFIG_PPP=m ++CONFIG_PPP_BSDCOMP=m ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_FILTER=y ++CONFIG_PPP_MPPE=m ++CONFIG_PPP_MULTILINK=y ++CONFIG_PPPOATM=m ++CONFIG_PPPOE=m ++CONFIG_PPPOL2TP=m ++CONFIG_PPP_ASYNC=m ++CONFIG_PPP_SYNC_TTY=m ++CONFIG_SLIP=m ++CONFIG_SLIP_COMPRESSED=y ++CONFIG_SLIP_SMART=y ++CONFIG_USB_CATC=m ++CONFIG_USB_KAWETH=m ++CONFIG_USB_PEGASUS=m ++CONFIG_USB_RTL8150=m ++CONFIG_USB_RTL8152=y ++CONFIG_USB_LAN78XX=y ++CONFIG_USB_USBNET=y ++CONFIG_USB_NET_AX88179_178A=m ++CONFIG_USB_NET_CDCETHER=m ++CONFIG_USB_NET_CDC_EEM=m ++CONFIG_USB_NET_CDC_NCM=m ++CONFIG_USB_NET_HUAWEI_CDC_NCM=m ++CONFIG_USB_NET_CDC_MBIM=m ++CONFIG_USB_NET_DM9601=m ++CONFIG_USB_NET_SR9700=m ++CONFIG_USB_NET_SR9800=m ++CONFIG_USB_NET_SMSC75XX=m ++CONFIG_USB_NET_SMSC95XX=y ++CONFIG_USB_NET_GL620A=m ++CONFIG_USB_NET_NET1080=m ++CONFIG_USB_NET_PLUSB=m ++CONFIG_USB_NET_MCS7830=m ++CONFIG_USB_NET_CDC_SUBSET=m ++CONFIG_USB_ALI_M5632=y ++CONFIG_USB_AN2720=y ++CONFIG_USB_EPSON2888=y ++CONFIG_USB_KC2190=y ++CONFIG_USB_NET_ZAURUS=m ++CONFIG_USB_NET_CX82310_ETH=m ++CONFIG_USB_NET_KALMIA=m ++CONFIG_USB_NET_QMI_WWAN=m ++CONFIG_USB_HSO=m ++CONFIG_USB_NET_INT51X1=m ++CONFIG_USB_IPHETH=m ++CONFIG_USB_SIERRA_NET=m ++CONFIG_USB_VL600=m ++CONFIG_ATH9K=m ++CONFIG_ATH9K_HTC=m ++CONFIG_CARL9170=m ++CONFIG_ATH6KL=m ++CONFIG_ATH6KL_USB=m ++CONFIG_AR5523=m ++CONFIG_AT76C50X_USB=m ++CONFIG_B43=m ++# CONFIG_B43_PHY_N is not set ++CONFIG_B43LEGACY=m ++CONFIG_BRCMFMAC=m ++CONFIG_BRCMFMAC_USB=y ++CONFIG_BRCMDBG=y ++CONFIG_HOSTAP=m ++CONFIG_P54_COMMON=m ++CONFIG_P54_USB=m ++CONFIG_LIBERTAS=m ++CONFIG_LIBERTAS_USB=m ++CONFIG_LIBERTAS_SDIO=m ++CONFIG_LIBERTAS_THINFIRM=m ++CONFIG_LIBERTAS_THINFIRM_USB=m ++CONFIG_MWIFIEX=m ++CONFIG_MWIFIEX_SDIO=m ++CONFIG_MT7601U=m ++CONFIG_RT2X00=m ++CONFIG_RT2500USB=m ++CONFIG_RT73USB=m ++CONFIG_RT2800USB=m ++CONFIG_RT2800USB_RT3573=y ++CONFIG_RT2800USB_RT53XX=y ++CONFIG_RT2800USB_RT55XX=y ++CONFIG_RT2800USB_UNKNOWN=y ++CONFIG_RTL8187=m ++CONFIG_RTL8192CU=m ++CONFIG_RTL8XXXU=m ++CONFIG_USB_ZD1201=m ++CONFIG_ZD1211RW=m ++CONFIG_MAC80211_HWSIM=m ++CONFIG_USB_NET_RNDIS_WLAN=m ++CONFIG_WIMAX_I2400M_USB=m ++CONFIG_IEEE802154_AT86RF230=m ++CONFIG_IEEE802154_MRF24J40=m ++CONFIG_IEEE802154_CC2520=m ++CONFIG_INPUT_MOUSEDEV=y ++CONFIG_INPUT_JOYDEV=m ++CONFIG_INPUT_EVDEV=m ++# CONFIG_KEYBOARD_ATKBD is not set ++CONFIG_KEYBOARD_GPIO=m ++CONFIG_KEYBOARD_MATRIX=m ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_JOYSTICK=y ++CONFIG_JOYSTICK_IFORCE=m ++CONFIG_JOYSTICK_IFORCE_USB=y ++CONFIG_JOYSTICK_XPAD=m ++CONFIG_JOYSTICK_XPAD_FF=y ++CONFIG_JOYSTICK_XPAD_LEDS=y ++CONFIG_JOYSTICK_PSXPAD_SPI=m ++CONFIG_JOYSTICK_PSXPAD_SPI_FF=y ++CONFIG_JOYSTICK_RPISENSE=m ++CONFIG_INPUT_TOUCHSCREEN=y ++CONFIG_TOUCHSCREEN_ADS7846=m ++CONFIG_TOUCHSCREEN_EGALAX=m ++CONFIG_TOUCHSCREEN_EXC3000=m ++CONFIG_TOUCHSCREEN_GOODIX=m ++CONFIG_TOUCHSCREEN_EDT_FT5X06=m ++CONFIG_TOUCHSCREEN_RPI_FT5406=m ++CONFIG_TOUCHSCREEN_USB_COMPOSITE=m ++CONFIG_TOUCHSCREEN_STMPE=m ++CONFIG_INPUT_MISC=y ++CONFIG_INPUT_AD714X=m ++CONFIG_INPUT_ATI_REMOTE2=m ++CONFIG_INPUT_KEYSPAN_REMOTE=m ++CONFIG_INPUT_POWERMATE=m ++CONFIG_INPUT_YEALINK=m ++CONFIG_INPUT_CM109=m ++CONFIG_INPUT_UINPUT=m ++CONFIG_INPUT_GPIO_ROTARY_ENCODER=m ++CONFIG_INPUT_ADXL34X=m ++CONFIG_INPUT_CMA3000=m ++CONFIG_SERIO=m ++CONFIG_SERIO_RAW=m ++CONFIG_GAMEPORT=m ++CONFIG_GAMEPORT_NS558=m ++CONFIG_GAMEPORT_L4=m ++CONFIG_BRCM_CHAR_DRIVERS=y ++CONFIG_BCM_VCIO=y ++CONFIG_BCM_VC_SM=y ++CONFIG_BCM2835_DEVGPIOMEM=y ++CONFIG_ARGON_MEM=m ++# CONFIG_LEGACY_PTYS is not set ++CONFIG_SERIAL_8250=y ++# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set ++CONFIG_SERIAL_8250_CONSOLE=y ++# CONFIG_SERIAL_8250_DMA is not set ++CONFIG_SERIAL_8250_NR_UARTS=1 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=0 ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_8250_BCM2835AUX=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++CONFIG_SERIAL_SC16IS7XX=m ++CONFIG_SERIAL_SC16IS7XX_SPI=y ++CONFIG_SERIAL_DEV_BUS=m ++CONFIG_TTY_PRINTK=y ++CONFIG_HW_RANDOM=y ++CONFIG_RAW_DRIVER=y ++CONFIG_I2C=y ++CONFIG_I2C_CHARDEV=m ++CONFIG_I2C_BCM2708=m ++CONFIG_I2C_BCM2835=m ++CONFIG_I2C_GPIO=m ++CONFIG_I2C_ROBOTFUZZ_OSIF=m ++CONFIG_I2C_TINY_USB=m ++CONFIG_SPI=y ++CONFIG_SPI_BCM2835=m ++CONFIG_SPI_BCM2835AUX=m ++CONFIG_SPI_SPIDEV=m ++CONFIG_SPI_SLAVE=y ++CONFIG_PPS=m ++CONFIG_PPS_CLIENT_LDISC=m ++CONFIG_PPS_CLIENT_GPIO=m ++CONFIG_PINCTRL_MCP23S08=m ++CONFIG_GPIO_BCM_VIRT=y ++CONFIG_GPIO_MOCKUP=m ++CONFIG_GPIO_PCF857X=m ++CONFIG_GPIO_ARIZONA=m ++CONFIG_GPIO_STMPE=y ++CONFIG_W1=m ++CONFIG_W1_MASTER_DS2490=m ++CONFIG_W1_MASTER_DS2482=m ++CONFIG_W1_MASTER_DS1WM=m ++CONFIG_W1_MASTER_GPIO=m ++CONFIG_W1_SLAVE_THERM=m ++CONFIG_W1_SLAVE_SMEM=m ++CONFIG_W1_SLAVE_DS2408=m ++CONFIG_W1_SLAVE_DS2413=m ++CONFIG_W1_SLAVE_DS2406=m ++CONFIG_W1_SLAVE_DS2423=m ++CONFIG_W1_SLAVE_DS2431=m ++CONFIG_W1_SLAVE_DS2433=m ++CONFIG_W1_SLAVE_DS2438=m ++CONFIG_W1_SLAVE_DS2780=m ++CONFIG_W1_SLAVE_DS2781=m ++CONFIG_W1_SLAVE_DS28E04=m ++CONFIG_POWER_RESET=y ++CONFIG_POWER_RESET_GPIO=y ++CONFIG_BATTERY_DS2760=m ++CONFIG_BATTERY_GAUGE_LTC2941=m ++CONFIG_HWMON=m ++CONFIG_SENSORS_DS1621=m ++CONFIG_SENSORS_JC42=m ++CONFIG_SENSORS_LM75=m ++CONFIG_SENSORS_RPI_POE_FAN=m ++CONFIG_SENSORS_SHT21=m ++CONFIG_SENSORS_SHT3x=m ++CONFIG_SENSORS_SHTC1=m ++CONFIG_SENSORS_ADS1015=m ++CONFIG_SENSORS_INA2XX=m ++CONFIG_SENSORS_TMP102=m ++CONFIG_THERMAL=y ++CONFIG_BCM2835_THERMAL=y ++CONFIG_BRCMSTB_THERMAL=y ++CONFIG_WATCHDOG=y ++CONFIG_GPIO_WATCHDOG=m ++CONFIG_BCM2835_WDT=y ++CONFIG_MFD_STMPE=y ++CONFIG_STMPE_SPI=y ++CONFIG_MFD_ARIZONA_I2C=m ++CONFIG_MFD_ARIZONA_SPI=m ++CONFIG_MFD_WM5102=y ++CONFIG_REGULATOR=y ++CONFIG_REGULATOR_FIXED_VOLTAGE=m ++CONFIG_REGULATOR_ARIZONA_LDO1=m ++CONFIG_REGULATOR_ARIZONA_MICSUPP=m ++CONFIG_REGULATOR_GPIO=y ++CONFIG_MEDIA_SUPPORT=m ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++CONFIG_MEDIA_ANALOG_TV_SUPPORT=y ++CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y ++CONFIG_MEDIA_RADIO_SUPPORT=y ++CONFIG_MEDIA_CONTROLLER=y ++CONFIG_VIDEO_V4L2_SUBDEV_API=y ++CONFIG_MEDIA_USB_SUPPORT=y ++CONFIG_USB_VIDEO_CLASS=m ++CONFIG_USB_M5602=m ++CONFIG_USB_STV06XX=m ++CONFIG_USB_GL860=m ++CONFIG_USB_GSPCA_BENQ=m ++CONFIG_USB_GSPCA_CONEX=m ++CONFIG_USB_GSPCA_CPIA1=m ++CONFIG_USB_GSPCA_DTCS033=m ++CONFIG_USB_GSPCA_ETOMS=m ++CONFIG_USB_GSPCA_FINEPIX=m ++CONFIG_USB_GSPCA_JEILINJ=m ++CONFIG_USB_GSPCA_JL2005BCD=m ++CONFIG_USB_GSPCA_KINECT=m ++CONFIG_USB_GSPCA_KONICA=m ++CONFIG_USB_GSPCA_MARS=m ++CONFIG_USB_GSPCA_MR97310A=m ++CONFIG_USB_GSPCA_NW80X=m ++CONFIG_USB_GSPCA_OV519=m ++CONFIG_USB_GSPCA_OV534=m ++CONFIG_USB_GSPCA_OV534_9=m ++CONFIG_USB_GSPCA_PAC207=m ++CONFIG_USB_GSPCA_PAC7302=m ++CONFIG_USB_GSPCA_PAC7311=m ++CONFIG_USB_GSPCA_SE401=m ++CONFIG_USB_GSPCA_SN9C2028=m ++CONFIG_USB_GSPCA_SN9C20X=m ++CONFIG_USB_GSPCA_SONIXB=m ++CONFIG_USB_GSPCA_SONIXJ=m ++CONFIG_USB_GSPCA_SPCA500=m ++CONFIG_USB_GSPCA_SPCA501=m ++CONFIG_USB_GSPCA_SPCA505=m ++CONFIG_USB_GSPCA_SPCA506=m ++CONFIG_USB_GSPCA_SPCA508=m ++CONFIG_USB_GSPCA_SPCA561=m ++CONFIG_USB_GSPCA_SPCA1528=m ++CONFIG_USB_GSPCA_SQ905=m ++CONFIG_USB_GSPCA_SQ905C=m ++CONFIG_USB_GSPCA_SQ930X=m ++CONFIG_USB_GSPCA_STK014=m ++CONFIG_USB_GSPCA_STK1135=m ++CONFIG_USB_GSPCA_STV0680=m ++CONFIG_USB_GSPCA_SUNPLUS=m ++CONFIG_USB_GSPCA_T613=m ++CONFIG_USB_GSPCA_TOPRO=m ++CONFIG_USB_GSPCA_TV8532=m ++CONFIG_USB_GSPCA_VC032X=m ++CONFIG_USB_GSPCA_VICAM=m ++CONFIG_USB_GSPCA_XIRLINK_CIT=m ++CONFIG_USB_GSPCA_ZC3XX=m ++CONFIG_USB_PWC=m ++CONFIG_VIDEO_CPIA2=m ++CONFIG_USB_ZR364XX=m ++CONFIG_USB_STKWEBCAM=m ++CONFIG_USB_S2255=m ++CONFIG_VIDEO_USBTV=m ++CONFIG_VIDEO_PVRUSB2=m ++CONFIG_VIDEO_HDPVR=m ++CONFIG_VIDEO_USBVISION=m ++CONFIG_VIDEO_STK1160_COMMON=m ++CONFIG_VIDEO_GO7007=m ++CONFIG_VIDEO_GO7007_USB=m ++CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m ++CONFIG_VIDEO_AU0828=m ++CONFIG_DVB_USB_V2=m ++CONFIG_DVB_USB_AF9035=m ++CONFIG_DVB_USB_ANYSEE=m ++CONFIG_DVB_USB_AU6610=m ++CONFIG_DVB_USB_AZ6007=m ++CONFIG_DVB_USB_CE6230=m ++CONFIG_DVB_USB_EC168=m ++CONFIG_DVB_USB_GL861=m ++CONFIG_DVB_USB_MXL111SF=m ++CONFIG_DVB_USB_DVBSKY=m ++CONFIG_SMS_USB_DRV=m ++CONFIG_DVB_B2C2_FLEXCOP_USB=m ++CONFIG_DVB_AS102=m ++CONFIG_VIDEO_EM28XX=m ++CONFIG_VIDEO_EM28XX_V4L2=m ++CONFIG_VIDEO_EM28XX_ALSA=m ++CONFIG_VIDEO_EM28XX_DVB=m ++CONFIG_V4L_PLATFORM_DRIVERS=y ++CONFIG_VIDEO_BCM2835_UNICAM=m ++CONFIG_RADIO_SI470X=m ++CONFIG_USB_SI470X=m ++CONFIG_I2C_SI470X=m ++CONFIG_RADIO_SI4713=m ++CONFIG_I2C_SI4713=m ++CONFIG_USB_MR800=m ++CONFIG_USB_DSBR=m ++CONFIG_RADIO_SHARK=m ++CONFIG_RADIO_SHARK2=m ++CONFIG_USB_KEENE=m ++CONFIG_USB_MA901=m ++CONFIG_RADIO_TEA5764=m ++CONFIG_RADIO_SAA7706H=m ++CONFIG_RADIO_TEF6862=m ++CONFIG_RADIO_WL1273=m ++CONFIG_RADIO_WL128X=m ++# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set ++CONFIG_VIDEO_UDA1342=m ++CONFIG_VIDEO_SONY_BTF_MPX=m ++CONFIG_VIDEO_ADV7180=m ++CONFIG_VIDEO_TC358743=m ++CONFIG_VIDEO_TVP5150=m ++CONFIG_VIDEO_TW2804=m ++CONFIG_VIDEO_TW9903=m ++CONFIG_VIDEO_TW9906=m ++CONFIG_VIDEO_OV5647=m ++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_V3D=m ++CONFIG_DRM_VC4=m ++CONFIG_DRM_TINYDRM=m ++CONFIG_TINYDRM_MI0283QT=m ++CONFIG_TINYDRM_REPAPER=m ++CONFIG_FB=y ++CONFIG_FB_BCM2708=y ++CONFIG_FB_UDL=m ++CONFIG_FB_SIMPLE=y ++CONFIG_FB_SSD1307=m ++CONFIG_FB_RPISENSE=m ++# CONFIG_BACKLIGHT_GENERIC is not set ++CONFIG_BACKLIGHT_RPI=m ++CONFIG_BACKLIGHT_GPIO=m ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_LOGO=y ++# CONFIG_LOGO_LINUX_MONO is not set ++# CONFIG_LOGO_LINUX_VGA16 is not set ++CONFIG_SOUND=y ++CONFIG_SND=m ++CONFIG_SND_HRTIMER=m ++CONFIG_SND_SEQUENCER=m ++CONFIG_SND_SEQ_DUMMY=m ++CONFIG_SND_DUMMY=m ++CONFIG_SND_ALOOP=m ++CONFIG_SND_VIRMIDI=m ++CONFIG_SND_MTPAV=m ++CONFIG_SND_SERIAL_U16550=m ++CONFIG_SND_MPU401=m ++CONFIG_SND_USB_AUDIO=m ++CONFIG_SND_USB_UA101=m ++CONFIG_SND_USB_CAIAQ=m ++CONFIG_SND_USB_CAIAQ_INPUT=y ++CONFIG_SND_USB_6FIRE=m ++CONFIG_SND_USB_HIFACE=m ++CONFIG_SND_SOC=m ++CONFIG_SND_BCM2835_SOC_I2S=m ++CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m ++CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=m ++CONFIG_SND_BCM2708_SOC_RPI_DAC=m ++CONFIG_SND_BCM2708_SOC_RPI_PROTO=m ++CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m ++CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m ++CONFIG_SND_BCM2708_SOC_IQAUDIO_CODEC=m ++CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m ++CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m ++CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m ++CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m ++CONFIG_SND_AUDIOINJECTOR_OCTO_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_BCM2708_SOC_ALLO_PIANO_DAC_PLUS=m ++CONFIG_SND_BCM2708_SOC_ALLO_BOSS_DAC=m ++CONFIG_SND_BCM2708_SOC_ALLO_DIGIONE=m ++CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC=m ++CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m ++CONFIG_SND_PISOUND=m ++CONFIG_SND_SOC_ADAU1701=m ++CONFIG_SND_SOC_ADAU7002=m ++CONFIG_SND_SOC_AK4554=m ++CONFIG_SND_SOC_CS4271_I2C=m ++CONFIG_SND_SOC_SPDIF=m ++CONFIG_SND_SOC_WM8804_I2C=m ++CONFIG_SND_SIMPLE_CARD=m ++CONFIG_HID_BATTERY_STRENGTH=y ++CONFIG_HIDRAW=y ++CONFIG_UHID=m ++CONFIG_HID_A4TECH=m ++CONFIG_HID_ACRUX=m ++CONFIG_HID_APPLE=m ++CONFIG_HID_ASUS=m ++CONFIG_HID_BELKIN=m ++CONFIG_HID_BETOP_FF=m ++CONFIG_HID_CHERRY=m ++CONFIG_HID_CHICONY=m ++CONFIG_HID_CYPRESS=m ++CONFIG_HID_DRAGONRISE=m ++CONFIG_HID_EMS_FF=m ++CONFIG_HID_ELECOM=m ++CONFIG_HID_ELO=m ++CONFIG_HID_EZKEY=m ++CONFIG_HID_GEMBIRD=m ++CONFIG_HID_HOLTEK=m ++CONFIG_HID_KEYTOUCH=m ++CONFIG_HID_KYE=m ++CONFIG_HID_UCLOGIC=m ++CONFIG_HID_WALTOP=m ++CONFIG_HID_GYRATION=m ++CONFIG_HID_TWINHAN=m ++CONFIG_HID_KENSINGTON=m ++CONFIG_HID_LCPOWER=m ++CONFIG_HID_LOGITECH=m ++CONFIG_HID_LOGITECH_DJ=m ++CONFIG_LOGITECH_FF=y ++CONFIG_LOGIRUMBLEPAD2_FF=y ++CONFIG_LOGIG940_FF=y ++CONFIG_HID_MAGICMOUSE=m ++CONFIG_HID_MICROSOFT=m ++CONFIG_HID_MONTEREY=m ++CONFIG_HID_MULTITOUCH=m ++CONFIG_HID_NTRIG=m ++CONFIG_HID_ORTEK=m ++CONFIG_HID_PANTHERLORD=m ++CONFIG_HID_PETALYNX=m ++CONFIG_HID_PICOLCD=m ++CONFIG_HID_ROCCAT=m ++CONFIG_HID_SAMSUNG=m ++CONFIG_HID_SONY=m ++CONFIG_SONY_FF=y ++CONFIG_HID_SPEEDLINK=m ++CONFIG_HID_SUNPLUS=m ++CONFIG_HID_GREENASIA=m ++CONFIG_HID_SMARTJOYPLUS=m ++CONFIG_HID_TOPSEED=m ++CONFIG_HID_THINGM=m ++CONFIG_HID_THRUSTMASTER=m ++CONFIG_HID_WACOM=m ++CONFIG_HID_WIIMOTE=m ++CONFIG_HID_XINMO=m ++CONFIG_HID_ZEROPLUS=m ++CONFIG_HID_ZYDACRON=m ++CONFIG_HID_PID=y ++CONFIG_USB_HIDDEV=y ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_MON=m ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_DWCOTG=y ++CONFIG_USB_PRINTER=m ++CONFIG_USB_STORAGE=y ++CONFIG_USB_STORAGE_REALTEK=m ++CONFIG_USB_STORAGE_DATAFAB=m ++CONFIG_USB_STORAGE_FREECOM=m ++CONFIG_USB_STORAGE_ISD200=m ++CONFIG_USB_STORAGE_USBAT=m ++CONFIG_USB_STORAGE_SDDR09=m ++CONFIG_USB_STORAGE_SDDR55=m ++CONFIG_USB_STORAGE_JUMPSHOT=m ++CONFIG_USB_STORAGE_ALAUDA=m ++CONFIG_USB_STORAGE_ONETOUCH=m ++CONFIG_USB_STORAGE_KARMA=m ++CONFIG_USB_STORAGE_CYPRESS_ATACB=m ++CONFIG_USB_STORAGE_ENE_UB6250=m ++CONFIG_USB_UAS=y ++CONFIG_USB_MDC800=m ++CONFIG_USB_MICROTEK=m ++CONFIG_USBIP_CORE=m ++CONFIG_USBIP_VHCI_HCD=m ++CONFIG_USBIP_HOST=m ++CONFIG_USB_DWC2=m ++CONFIG_USB_SERIAL=m ++CONFIG_USB_SERIAL_GENERIC=y ++CONFIG_USB_SERIAL_AIRCABLE=m ++CONFIG_USB_SERIAL_ARK3116=m ++CONFIG_USB_SERIAL_BELKIN=m ++CONFIG_USB_SERIAL_CH341=m ++CONFIG_USB_SERIAL_WHITEHEAT=m ++CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m ++CONFIG_USB_SERIAL_CP210X=m ++CONFIG_USB_SERIAL_CYPRESS_M8=m ++CONFIG_USB_SERIAL_EMPEG=m ++CONFIG_USB_SERIAL_FTDI_SIO=m ++CONFIG_USB_SERIAL_VISOR=m ++CONFIG_USB_SERIAL_IPAQ=m ++CONFIG_USB_SERIAL_IR=m ++CONFIG_USB_SERIAL_EDGEPORT=m ++CONFIG_USB_SERIAL_EDGEPORT_TI=m ++CONFIG_USB_SERIAL_F81232=m ++CONFIG_USB_SERIAL_GARMIN=m ++CONFIG_USB_SERIAL_IPW=m ++CONFIG_USB_SERIAL_IUU=m ++CONFIG_USB_SERIAL_KEYSPAN_PDA=m ++CONFIG_USB_SERIAL_KEYSPAN=m ++CONFIG_USB_SERIAL_KLSI=m ++CONFIG_USB_SERIAL_KOBIL_SCT=m ++CONFIG_USB_SERIAL_MCT_U232=m ++CONFIG_USB_SERIAL_METRO=m ++CONFIG_USB_SERIAL_MOS7720=m ++CONFIG_USB_SERIAL_MOS7840=m ++CONFIG_USB_SERIAL_NAVMAN=m ++CONFIG_USB_SERIAL_PL2303=m ++CONFIG_USB_SERIAL_OTI6858=m ++CONFIG_USB_SERIAL_QCAUX=m ++CONFIG_USB_SERIAL_QUALCOMM=m ++CONFIG_USB_SERIAL_SPCP8X5=m ++CONFIG_USB_SERIAL_SAFE=m ++CONFIG_USB_SERIAL_SIERRAWIRELESS=m ++CONFIG_USB_SERIAL_SYMBOL=m ++CONFIG_USB_SERIAL_TI=m ++CONFIG_USB_SERIAL_CYBERJACK=m ++CONFIG_USB_SERIAL_XIRCOM=m ++CONFIG_USB_SERIAL_OPTION=m ++CONFIG_USB_SERIAL_OMNINET=m ++CONFIG_USB_SERIAL_OPTICON=m ++CONFIG_USB_SERIAL_XSENS_MT=m ++CONFIG_USB_SERIAL_WISHBONE=m ++CONFIG_USB_SERIAL_SSU100=m ++CONFIG_USB_SERIAL_QT2=m ++CONFIG_USB_SERIAL_DEBUG=m ++CONFIG_USB_EMI62=m ++CONFIG_USB_EMI26=m ++CONFIG_USB_ADUTUX=m ++CONFIG_USB_SEVSEG=m ++CONFIG_USB_RIO500=m ++CONFIG_USB_LEGOTOWER=m ++CONFIG_USB_LCD=m ++CONFIG_USB_CYPRESS_CY7C63=m ++CONFIG_USB_CYTHERM=m ++CONFIG_USB_IDMOUSE=m ++CONFIG_USB_FTDI_ELAN=m ++CONFIG_USB_APPLEDISPLAY=m ++CONFIG_USB_LD=m ++CONFIG_USB_TRANCEVIBRATOR=m ++CONFIG_USB_IOWARRIOR=m ++CONFIG_USB_TEST=m ++CONFIG_USB_ISIGHTFW=m ++CONFIG_USB_YUREX=m ++CONFIG_USB_ATM=m ++CONFIG_USB_SPEEDTOUCH=m ++CONFIG_USB_CXACRU=m ++CONFIG_USB_UEAGLEATM=m ++CONFIG_USB_XUSBATM=m ++CONFIG_USB_GADGET=m ++CONFIG_USB_CONFIGFS=m ++CONFIG_USB_CONFIGFS_SERIAL=y ++CONFIG_USB_CONFIGFS_ACM=y ++CONFIG_USB_CONFIGFS_OBEX=y ++CONFIG_USB_CONFIGFS_NCM=y ++CONFIG_USB_CONFIGFS_ECM=y ++CONFIG_USB_CONFIGFS_ECM_SUBSET=y ++CONFIG_USB_CONFIGFS_RNDIS=y ++CONFIG_USB_CONFIGFS_EEM=y ++CONFIG_USB_CONFIGFS_MASS_STORAGE=y ++CONFIG_USB_CONFIGFS_F_LB_SS=y ++CONFIG_USB_CONFIGFS_F_FS=y ++CONFIG_USB_CONFIGFS_F_UAC1=y ++CONFIG_USB_CONFIGFS_F_UAC2=y ++CONFIG_USB_CONFIGFS_F_MIDI=y ++CONFIG_USB_CONFIGFS_F_HID=y ++CONFIG_USB_CONFIGFS_F_UVC=y ++CONFIG_USB_CONFIGFS_F_PRINTER=y ++CONFIG_USB_ZERO=m ++CONFIG_USB_AUDIO=m ++CONFIG_USB_ETH=m ++CONFIG_USB_GADGETFS=m ++CONFIG_USB_MASS_STORAGE=m ++CONFIG_USB_G_SERIAL=m ++CONFIG_USB_MIDI_GADGET=m ++CONFIG_USB_G_PRINTER=m ++CONFIG_USB_CDC_COMPOSITE=m ++CONFIG_USB_G_ACM_MS=m ++CONFIG_USB_G_MULTI=m ++CONFIG_USB_G_HID=m ++CONFIG_USB_G_WEBCAM=m ++CONFIG_MMC=y ++CONFIG_MMC_BLOCK_MINORS=32 ++CONFIG_MMC_BCM2835_MMC=y ++CONFIG_MMC_BCM2835_DMA=y ++CONFIG_MMC_BCM2835_SDHOST=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SDHCI_IPROC=y ++CONFIG_MMC_SPI=m ++CONFIG_LEDS_CLASS=y ++CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_TRIGGER_TIMER=y ++CONFIG_LEDS_TRIGGER_ONESHOT=y ++CONFIG_LEDS_TRIGGER_HEARTBEAT=y ++CONFIG_LEDS_TRIGGER_BACKLIGHT=y ++CONFIG_LEDS_TRIGGER_CPU=y ++CONFIG_LEDS_TRIGGER_GPIO=y ++CONFIG_LEDS_TRIGGER_DEFAULT_ON=y ++CONFIG_LEDS_TRIGGER_TRANSIENT=m ++CONFIG_LEDS_TRIGGER_CAMERA=m ++CONFIG_LEDS_TRIGGER_INPUT=y ++CONFIG_LEDS_TRIGGER_PANIC=y ++CONFIG_RTC_CLASS=y ++# CONFIG_RTC_HCTOSYS is not set ++CONFIG_RTC_DRV_ABX80X=m ++CONFIG_RTC_DRV_DS1307=m ++CONFIG_RTC_DRV_DS1374=m ++CONFIG_RTC_DRV_DS1672=m ++CONFIG_RTC_DRV_MAX6900=m ++CONFIG_RTC_DRV_RS5C372=m ++CONFIG_RTC_DRV_ISL1208=m ++CONFIG_RTC_DRV_ISL12022=m ++CONFIG_RTC_DRV_X1205=m ++CONFIG_RTC_DRV_PCF8523=m ++CONFIG_RTC_DRV_PCF8563=m ++CONFIG_RTC_DRV_PCF8583=m ++CONFIG_RTC_DRV_M41T80=m ++CONFIG_RTC_DRV_BQ32K=m ++CONFIG_RTC_DRV_S35390A=m ++CONFIG_RTC_DRV_FM3130=m ++CONFIG_RTC_DRV_RX8581=m ++CONFIG_RTC_DRV_RX8025=m ++CONFIG_RTC_DRV_EM3027=m ++CONFIG_RTC_DRV_M41T93=m ++CONFIG_RTC_DRV_M41T94=m ++CONFIG_RTC_DRV_DS1302=m ++CONFIG_RTC_DRV_DS1305=m ++CONFIG_RTC_DRV_DS1390=m ++CONFIG_RTC_DRV_R9701=m ++CONFIG_RTC_DRV_RX4581=m ++CONFIG_RTC_DRV_RS5C348=m ++CONFIG_RTC_DRV_MAX6902=m ++CONFIG_RTC_DRV_PCF2123=m ++CONFIG_RTC_DRV_DS3232=m ++CONFIG_RTC_DRV_PCF2127=m ++CONFIG_RTC_DRV_RV3029C2=m ++CONFIG_DMADEVICES=y ++CONFIG_DMA_BCM2835=y ++CONFIG_DMA_BCM2708=y ++CONFIG_UIO=m ++CONFIG_UIO_PDRV_GENIRQ=m ++CONFIG_STAGING=y ++CONFIG_PRISM2_USB=m ++CONFIG_R8712U=m ++CONFIG_R8188EU=m ++CONFIG_VT6656=m ++CONFIG_SPEAKUP=m ++CONFIG_SPEAKUP_SYNTH_SOFT=m ++CONFIG_STAGING_MEDIA=y ++CONFIG_FB_TFT=m ++CONFIG_FB_TFT_AGM1264K_FL=m ++CONFIG_FB_TFT_BD663474=m ++CONFIG_FB_TFT_HX8340BN=m ++CONFIG_FB_TFT_HX8347D=m ++CONFIG_FB_TFT_HX8353D=m ++CONFIG_FB_TFT_HX8357D=m ++CONFIG_FB_TFT_ILI9163=m ++CONFIG_FB_TFT_ILI9320=m ++CONFIG_FB_TFT_ILI9325=m ++CONFIG_FB_TFT_ILI9340=m ++CONFIG_FB_TFT_ILI9341=m ++CONFIG_FB_TFT_ILI9481=m ++CONFIG_FB_TFT_ILI9486=m ++CONFIG_FB_TFT_PCD8544=m ++CONFIG_FB_TFT_RA8875=m ++CONFIG_FB_TFT_S6D02A1=m ++CONFIG_FB_TFT_S6D1121=m ++CONFIG_FB_TFT_SSD1289=m ++CONFIG_FB_TFT_SSD1306=m ++CONFIG_FB_TFT_SSD1331=m ++CONFIG_FB_TFT_SSD1351=m ++CONFIG_FB_TFT_ST7735R=m ++CONFIG_FB_TFT_ST7789V=m ++CONFIG_FB_TFT_TINYLCD=m ++CONFIG_FB_TFT_TLS8204=m ++CONFIG_FB_TFT_UC1701=m ++CONFIG_FB_TFT_UPD161704=m ++CONFIG_FB_TFT_WATTEROTT=m ++CONFIG_FB_FLEX=m ++CONFIG_FB_TFT_FBTFT_DEVICE=m ++CONFIG_BCM2835_VCHIQ=y ++CONFIG_SND_BCM2835=m ++CONFIG_VIDEO_BCM2835=m ++CONFIG_VIDEO_CODEC_BCM2835=m ++CONFIG_MAILBOX=y ++CONFIG_BCM2835_MBOX=y ++# CONFIG_IOMMU_SUPPORT is not set ++CONFIG_BCM2835_POWER=y ++CONFIG_RASPBERRYPI_POWER=y ++CONFIG_EXTCON=m ++CONFIG_EXTCON_ARIZONA=m ++CONFIG_IIO=m ++CONFIG_IIO_BUFFER_CB=m ++CONFIG_MCP320X=m ++CONFIG_MCP3422=m ++CONFIG_DHT11=m ++CONFIG_HDC100X=m ++CONFIG_HTU21=m ++CONFIG_TSL4531=m ++CONFIG_VEML6070=m ++CONFIG_BMP280=m ++CONFIG_PWM_BCM2835=m ++CONFIG_PWM_PCA9685=m ++CONFIG_GENERIC_PHY=y ++CONFIG_RPI_AXIPERF=m ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_REISERFS_FS=m ++CONFIG_REISERFS_FS_XATTR=y ++CONFIG_REISERFS_FS_POSIX_ACL=y ++CONFIG_REISERFS_FS_SECURITY=y ++CONFIG_JFS_FS=m ++CONFIG_JFS_POSIX_ACL=y ++CONFIG_JFS_SECURITY=y ++CONFIG_JFS_STATISTICS=y ++CONFIG_XFS_FS=m ++CONFIG_XFS_QUOTA=y ++CONFIG_XFS_POSIX_ACL=y ++CONFIG_XFS_RT=y ++CONFIG_GFS2_FS=m ++CONFIG_OCFS2_FS=m ++CONFIG_BTRFS_FS=m ++CONFIG_BTRFS_FS_POSIX_ACL=y ++CONFIG_NILFS2_FS=m ++CONFIG_F2FS_FS=y ++CONFIG_FANOTIFY=y ++CONFIG_QFMT_V1=m ++CONFIG_QFMT_V2=m ++CONFIG_AUTOFS4_FS=y ++CONFIG_FUSE_FS=m ++CONFIG_CUSE=m ++CONFIG_OVERLAY_FS=m ++CONFIG_FSCACHE=y ++CONFIG_FSCACHE_STATS=y ++CONFIG_FSCACHE_HISTOGRAM=y ++CONFIG_CACHEFILES=y ++CONFIG_ISO9660_FS=m ++CONFIG_JOLIET=y ++CONFIG_ZISOFS=y ++CONFIG_UDF_FS=m ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_IOCHARSET="ascii" ++CONFIG_NTFS_FS=m ++CONFIG_NTFS_RW=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_ECRYPT_FS=m ++CONFIG_HFS_FS=m ++CONFIG_HFSPLUS_FS=m ++CONFIG_JFFS2_FS=m ++CONFIG_JFFS2_SUMMARY=y ++CONFIG_UBIFS_FS=m ++CONFIG_SQUASHFS=m ++CONFIG_SQUASHFS_XATTR=y ++CONFIG_SQUASHFS_LZO=y ++CONFIG_SQUASHFS_XZ=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_NFS_V4_1=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFS_FSCACHE=y ++CONFIG_NFSD=m ++CONFIG_NFSD_V3_ACL=y ++CONFIG_NFSD_V4=y ++CONFIG_CIFS=m ++CONFIG_CIFS_WEAK_PW_HASH=y ++CONFIG_CIFS_UPCALL=y ++CONFIG_CIFS_XATTR=y ++CONFIG_CIFS_POSIX=y ++CONFIG_CIFS_ACL=y ++CONFIG_CIFS_DFS_UPCALL=y ++CONFIG_CIFS_FSCACHE=y ++CONFIG_9P_FS=m ++CONFIG_9P_FS_POSIX_ACL=y ++CONFIG_NLS_DEFAULT="utf8" ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_737=m ++CONFIG_NLS_CODEPAGE_775=m ++CONFIG_NLS_CODEPAGE_850=m ++CONFIG_NLS_CODEPAGE_852=m ++CONFIG_NLS_CODEPAGE_855=m ++CONFIG_NLS_CODEPAGE_857=m ++CONFIG_NLS_CODEPAGE_860=m ++CONFIG_NLS_CODEPAGE_861=m ++CONFIG_NLS_CODEPAGE_862=m ++CONFIG_NLS_CODEPAGE_863=m ++CONFIG_NLS_CODEPAGE_864=m ++CONFIG_NLS_CODEPAGE_865=m ++CONFIG_NLS_CODEPAGE_866=m ++CONFIG_NLS_CODEPAGE_869=m ++CONFIG_NLS_CODEPAGE_936=m ++CONFIG_NLS_CODEPAGE_950=m ++CONFIG_NLS_CODEPAGE_932=m ++CONFIG_NLS_CODEPAGE_949=m ++CONFIG_NLS_CODEPAGE_874=m ++CONFIG_NLS_ISO8859_8=m ++CONFIG_NLS_CODEPAGE_1250=m ++CONFIG_NLS_CODEPAGE_1251=m ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=m ++CONFIG_NLS_ISO8859_2=m ++CONFIG_NLS_ISO8859_3=m ++CONFIG_NLS_ISO8859_4=m ++CONFIG_NLS_ISO8859_5=m ++CONFIG_NLS_ISO8859_6=m ++CONFIG_NLS_ISO8859_7=m ++CONFIG_NLS_ISO8859_9=m ++CONFIG_NLS_ISO8859_13=m ++CONFIG_NLS_ISO8859_14=m ++CONFIG_NLS_ISO8859_15=m ++CONFIG_NLS_KOI8_R=m ++CONFIG_NLS_KOI8_U=m ++CONFIG_DLM=m ++CONFIG_CRYPTO_USER=m ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_CTS=m ++CONFIG_CRYPTO_XTS=m ++CONFIG_CRYPTO_XCBC=m ++CONFIG_CRYPTO_TGR192=m ++CONFIG_CRYPTO_WP512=m ++CONFIG_CRYPTO_CAST5=m ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_LZ4=m ++CONFIG_CRYPTO_USER_API_SKCIPHER=m ++# CONFIG_CRYPTO_HW is not set ++CONFIG_CRC_ITU_T=y ++CONFIG_LIBCRC32C=y ++CONFIG_PRINTK_TIME=y ++CONFIG_BOOT_PRINTK_DELAY=y ++CONFIG_DEBUG_MEMORY_INIT=y ++CONFIG_DETECT_HUNG_TASK=y ++# CONFIG_RCU_TRACE is not set ++CONFIG_LATENCYTOP=y ++CONFIG_IRQSOFF_TRACER=y ++CONFIG_SCHED_TRACER=y ++CONFIG_STACK_TRACER=y ++CONFIG_BLK_DEV_IO_TRACE=y ++# CONFIG_UPROBE_EVENTS is not set ++CONFIG_FUNCTION_PROFILER=y ++CONFIG_KGDB=y ++CONFIG_KGDB_KDB=y ++CONFIG_KDB_KEYBOARD=y diff --git a/target/linux/brcm2708/patches-4.19/950-0640-overlays-Add-i2c3-6-and-uart2-5-overlays.patch b/target/linux/brcm2708/patches-4.19/950-0640-overlays-Add-i2c3-6-and-uart2-5-overlays.patch deleted file mode 100644 index a08074597e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0640-overlays-Add-i2c3-6-and-uart2-5-overlays.patch +++ /dev/null @@ -1,359 +0,0 @@ -From 3f7bbc703820266e75c079e5553289d969fe0ed7 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 30 May 2019 16:44:24 +0100 -Subject: [PATCH 640/703] overlays: Add i2c3-6 and uart2-5 overlays - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/Makefile | 8 +++ - arch/arm/boot/dts/overlays/README | 52 ++++++++++++++++++++ - arch/arm/boot/dts/overlays/i2c3-overlay.dts | 27 ++++++++++ - arch/arm/boot/dts/overlays/i2c4-overlay.dts | 27 ++++++++++ - arch/arm/boot/dts/overlays/i2c5-overlay.dts | 27 ++++++++++ - arch/arm/boot/dts/overlays/i2c6-overlay.dts | 27 ++++++++++ - arch/arm/boot/dts/overlays/uart2-overlay.dts | 27 ++++++++++ - arch/arm/boot/dts/overlays/uart3-overlay.dts | 27 ++++++++++ - arch/arm/boot/dts/overlays/uart4-overlay.dts | 27 ++++++++++ - arch/arm/boot/dts/overlays/uart5-overlay.dts | 27 ++++++++++ - 10 files changed, 276 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/i2c3-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/i2c4-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/i2c5-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/i2c6-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/uart2-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/uart3-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/uart4-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/uart5-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -65,6 +65,10 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - i2c-sensor.dtbo \ - i2c0-bcm2708.dtbo \ - i2c1-bcm2708.dtbo \ -+ i2c3.dtbo \ -+ i2c4.dtbo \ -+ i2c5.dtbo \ -+ i2c6.dtbo \ - i2s-gpio28-31.dtbo \ - ilitek251x.dtbo \ - iqaudio-codec.dtbo \ -@@ -149,6 +153,10 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - tpm-slb9670.dtbo \ - uart0.dtbo \ - uart1.dtbo \ -+ uart2.dtbo \ -+ uart3.dtbo \ -+ uart4.dtbo \ -+ uart5.dtbo \ - udrc.dtbo \ - upstream.dtbo \ - vc4-fkms-v3d.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1137,6 +1137,34 @@ Params: sda1_pin GPIO pin - "yes") - - -+Name: i2c3 -+Info: Enable the i2c3 bus -+Load: dtoverlay=i2c3, -+Params: pins_2_3 Use GPIOs 2 and 3 -+ pins_4_5 Use GPIOs 4 and 5 (default) -+ -+ -+Name: i2c4 -+Info: Enable the i2c4 bus -+Load: dtoverlay=i2c4, -+Params: pins_6_7 Use GPIOs 6 and 7 -+ pins_8_9 Use GPIOs 8 and 9 (default) -+ -+ -+Name: i2c5 -+Info: Enable the i2c5 bus -+Load: dtoverlay=i2c5, -+Params: pins_10_11 Use GPIOs 10 and 11 -+ pins_12_13 Use GPIOs 12 and 13 (default) -+ -+ -+Name: i2c6 -+Info: Enable the i2c6 bus -+Load: dtoverlay=i2c6, -+Params: pins_0_1 Use GPIOs 0 and 1 -+ pins_22_23 Use GPIOs 22 and 23 (default) -+ -+ - Name: i2s-gpio28-31 - Info: move I2S function block to GPIO 28 to 31 - Load: dtoverlay=i2s-gpio28-31 -@@ -2199,6 +2227,30 @@ Params: txd1_pin GPIO pin - rxd1_pin GPIO pin for RXD1 (15, 33 or 41 - default 15) - - -+Name: uart2 -+Info: Enable uart 2 on GPIOs 0-3 -+Load: dtoverlay=uart2, -+Params: ctsrts Enable CTS/RTS on GPIOs 2-3 (default off) -+ -+ -+Name: uart3 -+Info: Enable uart 3 on GPIOs 4-7 -+Load: dtoverlay=uart3, -+Params: ctsrts Enable CTS/RTS on GPIOs 6-7 (default off) -+ -+ -+Name: uart4 -+Info: Enable uart 4 on GPIOs 8-11 -+Load: dtoverlay=uart4, -+Params: ctsrts Enable CTS/RTS on GPIOs 10-11 (default off) -+ -+ -+Name: uart5 -+Info: Enable uart 5 on GPIOs 12-15 -+Load: dtoverlay=uart5, -+Params: ctsrts Enable CTS/RTS on GPIOs 14-15 (default off) -+ -+ - Name: udrc - Info: Configures the NW Digital Radio UDRC Hat - Load: dtoverlay=udrc,= ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/i2c3-overlay.dts -@@ -0,0 +1,27 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2838"; -+ -+ fragment@0 { -+ target = <&i2c3>; -+ __overlay__ { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c3_pins>; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2c3_pins>; -+ __dormant__ { -+ brcm,pins = <2 3>; -+ }; -+ }; -+ -+ __overrides__ { -+ pins_2_3 = <0>,"=1"; -+ pins_4_5 = <0>,"!1"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/i2c4-overlay.dts -@@ -0,0 +1,27 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2838"; -+ -+ fragment@0 { -+ target = <&i2c4>; -+ __overlay__ { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c4_pins>; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2c4_pins>; -+ __dormant__ { -+ brcm,pins = <6 7>; -+ }; -+ }; -+ -+ __overrides__ { -+ pins_6_7 = <0>,"=1"; -+ pins_8_9 = <0>,"!1"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/i2c5-overlay.dts -@@ -0,0 +1,27 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2838"; -+ -+ fragment@0 { -+ target = <&i2c5>; -+ __overlay__ { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c5_pins>; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2c5_pins>; -+ __dormant__ { -+ brcm,pins = <10 11>; -+ }; -+ }; -+ -+ __overrides__ { -+ pins_10_11 = <0>,"=1"; -+ pins_12_13 = <0>,"!1"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/i2c6-overlay.dts -@@ -0,0 +1,27 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2838"; -+ -+ fragment@0 { -+ target = <&i2c6>; -+ __overlay__ { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c6_pins>; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2c6_pins>; -+ __dormant__ { -+ brcm,pins = <0 1>; -+ }; -+ }; -+ -+ __overrides__ { -+ pins_0_1 = <0>,"=1"; -+ pins_22_23 = <0>,"!1"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/uart2-overlay.dts -@@ -0,0 +1,27 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2838"; -+ -+ fragment@0 { -+ target = <&uart2>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart2_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&uart2_pins>; -+ __dormant__ { -+ brcm,pins = <0 1 2 3>; -+ brcm,pull = <0 2 2 0>; -+ }; -+ }; -+ -+ __overrides__ { -+ ctsrts = <0>,"=1"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/uart3-overlay.dts -@@ -0,0 +1,27 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2838"; -+ -+ fragment@0 { -+ target = <&uart3>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart3_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&uart3_pins>; -+ __dormant__ { -+ brcm,pins = <4 5 6 7>; -+ brcm,pull = <0 2 2 0>; -+ }; -+ }; -+ -+ __overrides__ { -+ ctsrts = <0>,"=1"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/uart4-overlay.dts -@@ -0,0 +1,27 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2838"; -+ -+ fragment@0 { -+ target = <&uart4>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart4_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&uart4_pins>; -+ __dormant__ { -+ brcm,pins = <8 9 10 11>; -+ brcm,pull = <0 2 2 0>; -+ }; -+ }; -+ -+ __overrides__ { -+ ctsrts = <0>,"=1"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/uart5-overlay.dts -@@ -0,0 +1,27 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2838"; -+ -+ fragment@0 { -+ target = <&uart5>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart5_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&uart5_pins>; -+ __dormant__ { -+ brcm,pins = <12 13 14 15>; -+ brcm,pull = <0 2 2 0>; -+ }; -+ }; -+ -+ __overrides__ { -+ ctsrts = <0>,"=1"; -+ }; -+}; diff --git a/target/linux/brcm2708/patches-4.19/950-0641-2711-Add-basic-64-bit-support.patch b/target/linux/brcm2708/patches-4.19/950-0641-2711-Add-basic-64-bit-support.patch new file mode 100644 index 0000000000..cefaf59614 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0641-2711-Add-basic-64-bit-support.patch @@ -0,0 +1,1329 @@ +From 3b0307fedd80a85daae89d0346c165d3b3ce6687 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 8 Mar 2019 21:12:39 +0000 +Subject: [PATCH 641/725] 2711: Add basic 64-bit support + +This commit adds initial support for 64-bit 2711 builds. However, +it will only work as much as it does if the Pi4 RAM is limited to +1GB - more than that and several things break (SD card, coherent +allocations, etc.) + +Signed-off-by: Phil Elwell +--- + arch/arm64/boot/dts/broadcom/Makefile | 1 + + .../boot/dts/broadcom/bcm2711-rpi-4-b.dts | 3 + + arch/arm64/configs/bcm2711_defconfig | 1291 +++++++++++++++++ + 3 files changed, 1295 insertions(+) + create mode 100644 arch/arm64/boot/dts/broadcom/bcm2711-rpi-4-b.dts + create mode 100644 arch/arm64/configs/bcm2711_defconfig + +--- a/arch/arm64/boot/dts/broadcom/Makefile ++++ b/arch/arm64/boot/dts/broadcom/Makefile +@@ -3,6 +3,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rp + bcm2837-rpi-3-b-plus.dtb + dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-3-b.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b.dtb ++dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-4-b.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b-plus.dtb + dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-cm3.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-cm3.dtb +--- /dev/null ++++ b/arch/arm64/boot/dts/broadcom/bcm2711-rpi-4-b.dts +@@ -0,0 +1,3 @@ ++#define RPI364 ++ ++#include "../../../../arm/boot/dts/bcm2711-rpi-4-b.dts" +--- /dev/null ++++ b/arch/arm64/configs/bcm2711_defconfig +@@ -0,0 +1,1291 @@ ++CONFIG_LOCALVERSION="-v8" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SYSVIPC=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_GENERIC_IRQ_DEBUGFS=y ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_PREEMPT=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_TASKSTATS=y ++CONFIG_TASK_DELAY_ACCT=y ++CONFIG_TASK_XACCT=y ++CONFIG_TASK_IO_ACCOUNTING=y ++CONFIG_IKCONFIG=m ++CONFIG_IKCONFIG_PROC=y ++CONFIG_MEMCG=y ++CONFIG_BLK_CGROUP=y ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CPUSETS=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_NAMESPACES=y ++CONFIG_USER_NS=y ++CONFIG_SCHED_AUTOGROUP=y ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_EMBEDDED=y ++# CONFIG_COMPAT_BRK is not set ++CONFIG_PROFILING=y ++CONFIG_ARCH_BCM2835=y ++CONFIG_PCI=y ++CONFIG_PCIE_BRCMSTB=y ++# CONFIG_CAVIUM_ERRATUM_22375 is not set ++# CONFIG_CAVIUM_ERRATUM_23154 is not set ++# CONFIG_CAVIUM_ERRATUM_27456 is not set ++CONFIG_SECCOMP=y ++CONFIG_ARMV8_DEPRECATED=y ++CONFIG_SWP_EMULATION=y ++CONFIG_CP15_BARRIER_EMULATION=y ++CONFIG_SETEND_EMULATION=y ++CONFIG_CMDLINE="console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait" ++CONFIG_COMPAT=y ++# CONFIG_SUSPEND is not set ++CONFIG_PM=y ++CONFIG_CPU_IDLE=y ++CONFIG_ARM_CPUIDLE=y ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_STAT=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y ++CONFIG_CPU_FREQ_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_GOV_ONDEMAND=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y ++CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y ++CONFIG_RASPBERRYPI_FIRMWARE=y ++CONFIG_ARM64_CRYPTO=y ++CONFIG_CRYPTO_AES_ARM64_BS=m ++CONFIG_KPROBES=y ++CONFIG_JUMP_LABEL=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++CONFIG_MODULE_SRCVERSION_ALL=y ++CONFIG_BLK_DEV_THROTTLING=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_MAC_PARTITION=y ++CONFIG_CFQ_GROUP_IOSCHED=y ++CONFIG_BINFMT_MISC=m ++CONFIG_CLEANCACHE=y ++CONFIG_FRONTSWAP=y ++CONFIG_CMA=y ++CONFIG_ZSMALLOC=m ++CONFIG_PGTABLE_MAPPING=y ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_XFRM_USER=y ++CONFIG_NET_KEY=m ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_RARP=y ++CONFIG_NET_IPIP=m ++CONFIG_NET_IPGRE_DEMUX=m ++CONFIG_NET_IPGRE=m ++CONFIG_IP_MROUTE=y ++CONFIG_IP_MROUTE_MULTIPLE_TABLES=y ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++CONFIG_SYN_COOKIES=y ++CONFIG_INET_AH=m ++CONFIG_INET_ESP=m ++CONFIG_INET_IPCOMP=m ++CONFIG_INET_XFRM_MODE_TRANSPORT=m ++CONFIG_INET_XFRM_MODE_TUNNEL=m ++CONFIG_INET_XFRM_MODE_BEET=m ++CONFIG_INET_DIAG=m ++CONFIG_TCP_CONG_ADVANCED=y ++CONFIG_TCP_CONG_BBR=m ++CONFIG_IPV6=m ++CONFIG_IPV6_ROUTER_PREF=y ++CONFIG_IPV6_ROUTE_INFO=y ++CONFIG_INET6_AH=m ++CONFIG_INET6_ESP=m ++CONFIG_INET6_IPCOMP=m ++CONFIG_IPV6_SIT_6RD=y ++CONFIG_IPV6_TUNNEL=m ++CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_IPV6_SUBTREES=y ++CONFIG_IPV6_MROUTE=y ++CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y ++CONFIG_IPV6_PIMSM_V2=y ++CONFIG_NETFILTER=y ++CONFIG_NF_CONNTRACK=m ++CONFIG_NF_CONNTRACK_ZONES=y ++CONFIG_NF_CONNTRACK_EVENTS=y ++CONFIG_NF_CONNTRACK_TIMESTAMP=y ++CONFIG_NF_CONNTRACK_AMANDA=m ++CONFIG_NF_CONNTRACK_FTP=m ++CONFIG_NF_CONNTRACK_H323=m ++CONFIG_NF_CONNTRACK_IRC=m ++CONFIG_NF_CONNTRACK_NETBIOS_NS=m ++CONFIG_NF_CONNTRACK_SNMP=m ++CONFIG_NF_CONNTRACK_PPTP=m ++CONFIG_NF_CONNTRACK_SANE=m ++CONFIG_NF_CONNTRACK_SIP=m ++CONFIG_NF_CONNTRACK_TFTP=m ++CONFIG_NF_CT_NETLINK=m ++CONFIG_NETFILTER_XT_SET=m ++CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m ++CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m ++CONFIG_NETFILTER_XT_TARGET_CONNMARK=m ++CONFIG_NETFILTER_XT_TARGET_DSCP=m ++CONFIG_NETFILTER_XT_TARGET_HMARK=m ++CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m ++CONFIG_NETFILTER_XT_TARGET_LED=m ++CONFIG_NETFILTER_XT_TARGET_LOG=m ++CONFIG_NETFILTER_XT_TARGET_MARK=m ++CONFIG_NETFILTER_XT_TARGET_NFLOG=m ++CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m ++CONFIG_NETFILTER_XT_TARGET_NOTRACK=m ++CONFIG_NETFILTER_XT_TARGET_TEE=m ++CONFIG_NETFILTER_XT_TARGET_TPROXY=m ++CONFIG_NETFILTER_XT_TARGET_TRACE=m ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=m ++CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m ++CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m ++CONFIG_NETFILTER_XT_MATCH_BPF=m ++CONFIG_NETFILTER_XT_MATCH_CLUSTER=m ++CONFIG_NETFILTER_XT_MATCH_COMMENT=m ++CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m ++CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m ++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=m ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m ++CONFIG_NETFILTER_XT_MATCH_CPU=m ++CONFIG_NETFILTER_XT_MATCH_DCCP=m ++CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m ++CONFIG_NETFILTER_XT_MATCH_DSCP=m ++CONFIG_NETFILTER_XT_MATCH_ESP=m ++CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m ++CONFIG_NETFILTER_XT_MATCH_HELPER=m ++CONFIG_NETFILTER_XT_MATCH_IPRANGE=m ++CONFIG_NETFILTER_XT_MATCH_IPVS=m ++CONFIG_NETFILTER_XT_MATCH_LENGTH=m ++CONFIG_NETFILTER_XT_MATCH_LIMIT=m ++CONFIG_NETFILTER_XT_MATCH_MAC=m ++CONFIG_NETFILTER_XT_MATCH_MARK=m ++CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m ++CONFIG_NETFILTER_XT_MATCH_NFACCT=m ++CONFIG_NETFILTER_XT_MATCH_OSF=m ++CONFIG_NETFILTER_XT_MATCH_OWNER=m ++CONFIG_NETFILTER_XT_MATCH_POLICY=m ++CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m ++CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m ++CONFIG_NETFILTER_XT_MATCH_QUOTA=m ++CONFIG_NETFILTER_XT_MATCH_RATEEST=m ++CONFIG_NETFILTER_XT_MATCH_REALM=m ++CONFIG_NETFILTER_XT_MATCH_RECENT=m ++CONFIG_NETFILTER_XT_MATCH_STATE=m ++CONFIG_NETFILTER_XT_MATCH_STATISTIC=m ++CONFIG_NETFILTER_XT_MATCH_STRING=m ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=m ++CONFIG_NETFILTER_XT_MATCH_TIME=m ++CONFIG_NETFILTER_XT_MATCH_U32=m ++CONFIG_IP_SET=m ++CONFIG_IP_SET_BITMAP_IP=m ++CONFIG_IP_SET_BITMAP_IPMAC=m ++CONFIG_IP_SET_BITMAP_PORT=m ++CONFIG_IP_SET_HASH_IP=m ++CONFIG_IP_SET_HASH_IPPORT=m ++CONFIG_IP_SET_HASH_IPPORTIP=m ++CONFIG_IP_SET_HASH_IPPORTNET=m ++CONFIG_IP_SET_HASH_NET=m ++CONFIG_IP_SET_HASH_NETPORT=m ++CONFIG_IP_SET_HASH_NETIFACE=m ++CONFIG_IP_SET_LIST_SET=m ++CONFIG_IP_VS=m ++CONFIG_IP_VS_PROTO_TCP=y ++CONFIG_IP_VS_PROTO_UDP=y ++CONFIG_IP_VS_PROTO_ESP=y ++CONFIG_IP_VS_PROTO_AH=y ++CONFIG_IP_VS_PROTO_SCTP=y ++CONFIG_IP_VS_RR=m ++CONFIG_IP_VS_WRR=m ++CONFIG_IP_VS_LC=m ++CONFIG_IP_VS_WLC=m ++CONFIG_IP_VS_LBLC=m ++CONFIG_IP_VS_LBLCR=m ++CONFIG_IP_VS_DH=m ++CONFIG_IP_VS_SH=m ++CONFIG_IP_VS_SED=m ++CONFIG_IP_VS_NQ=m ++CONFIG_IP_VS_FTP=m ++CONFIG_IP_VS_PE_SIP=m ++CONFIG_IP_NF_IPTABLES=m ++CONFIG_IP_NF_MATCH_AH=m ++CONFIG_IP_NF_MATCH_ECN=m ++CONFIG_IP_NF_MATCH_RPFILTER=m ++CONFIG_IP_NF_MATCH_TTL=m ++CONFIG_IP_NF_FILTER=m ++CONFIG_IP_NF_TARGET_REJECT=m ++CONFIG_IP_NF_NAT=m ++CONFIG_IP_NF_TARGET_MASQUERADE=m ++CONFIG_IP_NF_TARGET_NETMAP=m ++CONFIG_IP_NF_TARGET_REDIRECT=m ++CONFIG_IP_NF_MANGLE=m ++CONFIG_IP_NF_TARGET_CLUSTERIP=m ++CONFIG_IP_NF_TARGET_ECN=m ++CONFIG_IP_NF_TARGET_TTL=m ++CONFIG_IP_NF_RAW=m ++CONFIG_IP_NF_ARPTABLES=m ++CONFIG_IP_NF_ARPFILTER=m ++CONFIG_IP_NF_ARP_MANGLE=m ++CONFIG_IP6_NF_IPTABLES=m ++CONFIG_IP6_NF_MATCH_AH=m ++CONFIG_IP6_NF_MATCH_EUI64=m ++CONFIG_IP6_NF_MATCH_FRAG=m ++CONFIG_IP6_NF_MATCH_OPTS=m ++CONFIG_IP6_NF_MATCH_HL=m ++CONFIG_IP6_NF_MATCH_IPV6HEADER=m ++CONFIG_IP6_NF_MATCH_MH=m ++CONFIG_IP6_NF_MATCH_RPFILTER=m ++CONFIG_IP6_NF_MATCH_RT=m ++CONFIG_IP6_NF_TARGET_HL=m ++CONFIG_IP6_NF_FILTER=m ++CONFIG_IP6_NF_TARGET_REJECT=m ++CONFIG_IP6_NF_MANGLE=m ++CONFIG_IP6_NF_RAW=m ++CONFIG_IP6_NF_NAT=m ++CONFIG_IP6_NF_TARGET_MASQUERADE=m ++CONFIG_IP6_NF_TARGET_NPT=m ++CONFIG_BRIDGE_NF_EBTABLES=m ++CONFIG_BRIDGE_EBT_BROUTE=m ++CONFIG_BRIDGE_EBT_T_FILTER=m ++CONFIG_BRIDGE_EBT_T_NAT=m ++CONFIG_BRIDGE_EBT_802_3=m ++CONFIG_BRIDGE_EBT_AMONG=m ++CONFIG_BRIDGE_EBT_ARP=m ++CONFIG_BRIDGE_EBT_IP=m ++CONFIG_BRIDGE_EBT_IP6=m ++CONFIG_BRIDGE_EBT_LIMIT=m ++CONFIG_BRIDGE_EBT_MARK=m ++CONFIG_BRIDGE_EBT_PKTTYPE=m ++CONFIG_BRIDGE_EBT_STP=m ++CONFIG_BRIDGE_EBT_VLAN=m ++CONFIG_BRIDGE_EBT_ARPREPLY=m ++CONFIG_BRIDGE_EBT_DNAT=m ++CONFIG_BRIDGE_EBT_MARK_T=m ++CONFIG_BRIDGE_EBT_REDIRECT=m ++CONFIG_BRIDGE_EBT_SNAT=m ++CONFIG_BRIDGE_EBT_LOG=m ++CONFIG_BRIDGE_EBT_NFLOG=m ++CONFIG_SCTP_COOKIE_HMAC_SHA1=y ++CONFIG_ATM=m ++CONFIG_L2TP=m ++CONFIG_L2TP_V3=y ++CONFIG_L2TP_IP=m ++CONFIG_L2TP_ETH=m ++CONFIG_BRIDGE=m ++CONFIG_VLAN_8021Q=m ++CONFIG_VLAN_8021Q_GVRP=y ++CONFIG_ATALK=m ++CONFIG_6LOWPAN=m ++CONFIG_IEEE802154=m ++CONFIG_IEEE802154_6LOWPAN=m ++CONFIG_MAC802154=m ++CONFIG_NET_SCHED=y ++CONFIG_NET_SCH_CBQ=m ++CONFIG_NET_SCH_HTB=m ++CONFIG_NET_SCH_HFSC=m ++CONFIG_NET_SCH_ATM=m ++CONFIG_NET_SCH_PRIO=m ++CONFIG_NET_SCH_MULTIQ=m ++CONFIG_NET_SCH_RED=m ++CONFIG_NET_SCH_SFB=m ++CONFIG_NET_SCH_SFQ=m ++CONFIG_NET_SCH_TEQL=m ++CONFIG_NET_SCH_TBF=m ++CONFIG_NET_SCH_GRED=m ++CONFIG_NET_SCH_DSMARK=m ++CONFIG_NET_SCH_NETEM=m ++CONFIG_NET_SCH_DRR=m ++CONFIG_NET_SCH_MQPRIO=m ++CONFIG_NET_SCH_CHOKE=m ++CONFIG_NET_SCH_QFQ=m ++CONFIG_NET_SCH_CODEL=m ++CONFIG_NET_SCH_FQ_CODEL=m ++CONFIG_NET_SCH_FQ=m ++CONFIG_NET_SCH_HHF=m ++CONFIG_NET_SCH_PIE=m ++CONFIG_NET_SCH_INGRESS=m ++CONFIG_NET_SCH_PLUG=m ++CONFIG_NET_CLS_BASIC=m ++CONFIG_NET_CLS_TCINDEX=m ++CONFIG_NET_CLS_ROUTE4=m ++CONFIG_NET_CLS_FW=m ++CONFIG_NET_CLS_U32=m ++CONFIG_CLS_U32_MARK=y ++CONFIG_NET_CLS_RSVP=m ++CONFIG_NET_CLS_RSVP6=m ++CONFIG_NET_CLS_FLOW=m ++CONFIG_NET_CLS_CGROUP=m ++CONFIG_NET_EMATCH=y ++CONFIG_NET_EMATCH_CMP=m ++CONFIG_NET_EMATCH_NBYTE=m ++CONFIG_NET_EMATCH_U32=m ++CONFIG_NET_EMATCH_META=m ++CONFIG_NET_EMATCH_TEXT=m ++CONFIG_NET_EMATCH_IPSET=m ++CONFIG_NET_CLS_ACT=y ++CONFIG_NET_ACT_POLICE=m ++CONFIG_NET_ACT_GACT=m ++CONFIG_GACT_PROB=y ++CONFIG_NET_ACT_MIRRED=m ++CONFIG_NET_ACT_IPT=m ++CONFIG_NET_ACT_NAT=m ++CONFIG_NET_ACT_PEDIT=m ++CONFIG_NET_ACT_SIMP=m ++CONFIG_NET_ACT_SKBEDIT=m ++CONFIG_NET_ACT_CSUM=m ++CONFIG_BATMAN_ADV=m ++CONFIG_OPENVSWITCH=m ++CONFIG_NET_PKTGEN=m ++CONFIG_HAMRADIO=y ++CONFIG_AX25=m ++CONFIG_NETROM=m ++CONFIG_ROSE=m ++CONFIG_MKISS=m ++CONFIG_6PACK=m ++CONFIG_BPQETHER=m ++CONFIG_BAYCOM_SER_FDX=m ++CONFIG_BAYCOM_SER_HDX=m ++CONFIG_YAM=m ++CONFIG_CAN=m ++CONFIG_CAN_VCAN=m ++CONFIG_CAN_SLCAN=m ++CONFIG_CAN_MCP251X=m ++CONFIG_CAN_GS_USB=m ++CONFIG_BT=m ++CONFIG_BT_RFCOMM=m ++CONFIG_BT_RFCOMM_TTY=y ++CONFIG_BT_BNEP=m ++CONFIG_BT_BNEP_MC_FILTER=y ++CONFIG_BT_BNEP_PROTO_FILTER=y ++CONFIG_BT_HIDP=m ++CONFIG_BT_6LOWPAN=m ++CONFIG_BT_HCIBTUSB=m ++CONFIG_BT_HCIUART=m ++CONFIG_BT_HCIUART_3WIRE=y ++CONFIG_BT_HCIUART_BCM=y ++CONFIG_BT_HCIBCM203X=m ++CONFIG_BT_HCIBPA10X=m ++CONFIG_BT_HCIBFUSB=m ++CONFIG_BT_HCIVHCI=m ++CONFIG_BT_MRVL=m ++CONFIG_BT_MRVL_SDIO=m ++CONFIG_BT_ATH3K=m ++CONFIG_BT_WILINK=m ++CONFIG_CFG80211=m ++CONFIG_MAC80211=m ++CONFIG_MAC80211_MESH=y ++CONFIG_WIMAX=m ++CONFIG_RFKILL=m ++CONFIG_RFKILL_INPUT=y ++CONFIG_NET_9P=m ++CONFIG_NFC=m ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=5 ++CONFIG_MTD=m ++CONFIG_MTD_BLOCK=m ++CONFIG_MTD_M25P80=m ++CONFIG_MTD_BLOCK2MTD=m ++CONFIG_MTD_NAND=m ++CONFIG_MTD_SPI_NOR=m ++CONFIG_MTD_UBI=m ++CONFIG_OF_CONFIGFS=y ++CONFIG_ZRAM=m ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_CRYPTOLOOP=m ++CONFIG_BLK_DEV_DRBD=m ++CONFIG_BLK_DEV_NBD=m ++CONFIG_BLK_DEV_RAM=y ++CONFIG_CDROM_PKTCDVD=m ++CONFIG_ATA_OVER_ETH=m ++CONFIG_EEPROM_AT24=m ++CONFIG_TI_ST=m ++CONFIG_SCSI=y ++# CONFIG_SCSI_PROC_FS is not set ++CONFIG_BLK_DEV_SD=y ++CONFIG_CHR_DEV_ST=m ++CONFIG_CHR_DEV_OSST=m ++CONFIG_BLK_DEV_SR=m ++CONFIG_CHR_DEV_SG=m ++CONFIG_SCSI_ISCSI_ATTRS=y ++CONFIG_ISCSI_TCP=m ++CONFIG_ISCSI_BOOT_SYSFS=m ++CONFIG_MD=y ++CONFIG_MD_LINEAR=m ++CONFIG_BLK_DEV_DM=m ++CONFIG_DM_CRYPT=m ++CONFIG_DM_SNAPSHOT=m ++CONFIG_DM_THIN_PROVISIONING=m ++CONFIG_DM_CACHE=m ++CONFIG_DM_MIRROR=m ++CONFIG_DM_LOG_USERSPACE=m ++CONFIG_DM_RAID=m ++CONFIG_DM_ZERO=m ++CONFIG_DM_DELAY=m ++CONFIG_NETDEVICES=y ++CONFIG_BONDING=m ++CONFIG_DUMMY=m ++CONFIG_IFB=m ++CONFIG_MACVLAN=m ++CONFIG_IPVLAN=m ++CONFIG_VXLAN=m ++CONFIG_NETCONSOLE=m ++CONFIG_TUN=m ++CONFIG_VETH=m ++CONFIG_BCMGENET=y ++CONFIG_ENC28J60=m ++CONFIG_QCA7000_SPI=m ++CONFIG_MDIO_BITBANG=m ++CONFIG_BROADCOM_PHY=y ++CONFIG_PPP=m ++CONFIG_PPP_BSDCOMP=m ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_FILTER=y ++CONFIG_PPP_MPPE=m ++CONFIG_PPP_MULTILINK=y ++CONFIG_PPPOATM=m ++CONFIG_PPPOE=m ++CONFIG_PPPOL2TP=m ++CONFIG_PPP_ASYNC=m ++CONFIG_PPP_SYNC_TTY=m ++CONFIG_SLIP=m ++CONFIG_SLIP_COMPRESSED=y ++CONFIG_SLIP_SMART=y ++CONFIG_USB_CATC=m ++CONFIG_USB_KAWETH=m ++CONFIG_USB_PEGASUS=m ++CONFIG_USB_RTL8150=m ++CONFIG_USB_RTL8152=y ++CONFIG_USB_LAN78XX=y ++CONFIG_USB_USBNET=y ++CONFIG_USB_NET_AX88179_178A=m ++CONFIG_USB_NET_CDCETHER=m ++CONFIG_USB_NET_CDC_EEM=m ++CONFIG_USB_NET_CDC_NCM=m ++CONFIG_USB_NET_HUAWEI_CDC_NCM=m ++CONFIG_USB_NET_CDC_MBIM=m ++CONFIG_USB_NET_DM9601=m ++CONFIG_USB_NET_SR9700=m ++CONFIG_USB_NET_SR9800=m ++CONFIG_USB_NET_SMSC75XX=m ++CONFIG_USB_NET_SMSC95XX=y ++CONFIG_USB_NET_GL620A=m ++CONFIG_USB_NET_NET1080=m ++CONFIG_USB_NET_PLUSB=m ++CONFIG_USB_NET_MCS7830=m ++CONFIG_USB_NET_CDC_SUBSET=m ++CONFIG_USB_ALI_M5632=y ++CONFIG_USB_AN2720=y ++CONFIG_USB_EPSON2888=y ++CONFIG_USB_KC2190=y ++CONFIG_USB_NET_ZAURUS=m ++CONFIG_USB_NET_CX82310_ETH=m ++CONFIG_USB_NET_KALMIA=m ++CONFIG_USB_NET_QMI_WWAN=m ++CONFIG_USB_HSO=m ++CONFIG_USB_NET_INT51X1=m ++CONFIG_USB_IPHETH=m ++CONFIG_USB_SIERRA_NET=m ++CONFIG_USB_VL600=m ++CONFIG_ATH9K=m ++CONFIG_ATH9K_HTC=m ++CONFIG_CARL9170=m ++CONFIG_ATH6KL=m ++CONFIG_ATH6KL_USB=m ++CONFIG_AR5523=m ++CONFIG_AT76C50X_USB=m ++CONFIG_B43=m ++# CONFIG_B43_PHY_N is not set ++CONFIG_B43LEGACY=m ++CONFIG_BRCMFMAC=m ++CONFIG_BRCMFMAC_USB=y ++CONFIG_BRCMDBG=y ++CONFIG_HOSTAP=m ++CONFIG_P54_COMMON=m ++CONFIG_P54_USB=m ++CONFIG_LIBERTAS=m ++CONFIG_LIBERTAS_USB=m ++CONFIG_LIBERTAS_SDIO=m ++CONFIG_LIBERTAS_THINFIRM=m ++CONFIG_LIBERTAS_THINFIRM_USB=m ++CONFIG_MWIFIEX=m ++CONFIG_MWIFIEX_SDIO=m ++CONFIG_MT7601U=m ++CONFIG_RT2X00=m ++CONFIG_RT2500USB=m ++CONFIG_RT73USB=m ++CONFIG_RT2800USB=m ++CONFIG_RT2800USB_RT3573=y ++CONFIG_RT2800USB_RT53XX=y ++CONFIG_RT2800USB_RT55XX=y ++CONFIG_RT2800USB_UNKNOWN=y ++CONFIG_RTL8187=m ++CONFIG_RTL8192CU=m ++CONFIG_RTL8XXXU=m ++CONFIG_USB_ZD1201=m ++CONFIG_ZD1211RW=m ++CONFIG_MAC80211_HWSIM=m ++CONFIG_USB_NET_RNDIS_WLAN=m ++CONFIG_WIMAX_I2400M_USB=m ++CONFIG_IEEE802154_AT86RF230=m ++CONFIG_IEEE802154_MRF24J40=m ++CONFIG_IEEE802154_CC2520=m ++CONFIG_INPUT_MOUSEDEV=y ++CONFIG_INPUT_JOYDEV=m ++CONFIG_INPUT_EVDEV=m ++# CONFIG_KEYBOARD_ATKBD is not set ++CONFIG_KEYBOARD_GPIO=m ++CONFIG_KEYBOARD_MATRIX=m ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_JOYSTICK=y ++CONFIG_JOYSTICK_IFORCE=m ++CONFIG_JOYSTICK_IFORCE_USB=y ++CONFIG_JOYSTICK_XPAD=m ++CONFIG_JOYSTICK_XPAD_FF=y ++CONFIG_JOYSTICK_XPAD_LEDS=y ++CONFIG_JOYSTICK_PSXPAD_SPI=m ++CONFIG_JOYSTICK_PSXPAD_SPI_FF=y ++CONFIG_JOYSTICK_RPISENSE=m ++CONFIG_INPUT_TOUCHSCREEN=y ++CONFIG_TOUCHSCREEN_ADS7846=m ++CONFIG_TOUCHSCREEN_EGALAX=m ++CONFIG_TOUCHSCREEN_EXC3000=m ++CONFIG_TOUCHSCREEN_GOODIX=m ++CONFIG_TOUCHSCREEN_EDT_FT5X06=m ++CONFIG_TOUCHSCREEN_RPI_FT5406=m ++CONFIG_TOUCHSCREEN_USB_COMPOSITE=m ++CONFIG_TOUCHSCREEN_STMPE=m ++CONFIG_INPUT_MISC=y ++CONFIG_INPUT_AD714X=m ++CONFIG_INPUT_ATI_REMOTE2=m ++CONFIG_INPUT_KEYSPAN_REMOTE=m ++CONFIG_INPUT_POWERMATE=m ++CONFIG_INPUT_YEALINK=m ++CONFIG_INPUT_CM109=m ++CONFIG_INPUT_UINPUT=m ++CONFIG_INPUT_GPIO_ROTARY_ENCODER=m ++CONFIG_INPUT_ADXL34X=m ++CONFIG_INPUT_CMA3000=m ++CONFIG_SERIO=m ++CONFIG_SERIO_RAW=m ++CONFIG_GAMEPORT=m ++CONFIG_GAMEPORT_NS558=m ++CONFIG_GAMEPORT_L4=m ++CONFIG_BRCM_CHAR_DRIVERS=y ++CONFIG_BCM_VCIO=y ++CONFIG_BCM2835_DEVGPIOMEM=y ++# CONFIG_BCM2835_SMI_DEV is not set ++# CONFIG_LEGACY_PTYS is not set ++CONFIG_SERIAL_8250=y ++# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set ++CONFIG_SERIAL_8250_CONSOLE=y ++# CONFIG_SERIAL_8250_DMA is not set ++CONFIG_SERIAL_8250_NR_UARTS=1 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=0 ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_8250_BCM2835AUX=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++CONFIG_SERIAL_SC16IS7XX=m ++CONFIG_SERIAL_SC16IS7XX_SPI=y ++CONFIG_SERIAL_DEV_BUS=m ++CONFIG_TTY_PRINTK=y ++CONFIG_HW_RANDOM=y ++# CONFIG_HW_RANDOM_BCM2835 is not set ++CONFIG_RAW_DRIVER=y ++CONFIG_I2C=y ++CONFIG_I2C_CHARDEV=m ++CONFIG_I2C_BCM2708=m ++CONFIG_I2C_BCM2835=m ++CONFIG_I2C_GPIO=m ++CONFIG_I2C_ROBOTFUZZ_OSIF=m ++CONFIG_I2C_TINY_USB=m ++CONFIG_SPI=y ++CONFIG_SPI_BCM2835=m ++CONFIG_SPI_BCM2835AUX=m ++CONFIG_SPI_SPIDEV=m ++CONFIG_SPI_SLAVE=y ++CONFIG_PPS_CLIENT_LDISC=m ++CONFIG_PPS_CLIENT_GPIO=m ++CONFIG_PINCTRL_MCP23S08=m ++CONFIG_GPIO_BCM_VIRT=y ++CONFIG_GPIO_MOCKUP=m ++CONFIG_GPIO_PCF857X=m ++CONFIG_GPIO_ARIZONA=m ++CONFIG_GPIO_STMPE=y ++CONFIG_W1=m ++CONFIG_W1_MASTER_DS2490=m ++CONFIG_W1_MASTER_DS2482=m ++CONFIG_W1_MASTER_DS1WM=m ++CONFIG_W1_MASTER_GPIO=m ++CONFIG_W1_SLAVE_THERM=m ++CONFIG_W1_SLAVE_SMEM=m ++CONFIG_W1_SLAVE_DS2408=m ++CONFIG_W1_SLAVE_DS2413=m ++CONFIG_W1_SLAVE_DS2406=m ++CONFIG_W1_SLAVE_DS2423=m ++CONFIG_W1_SLAVE_DS2431=m ++CONFIG_W1_SLAVE_DS2433=m ++CONFIG_W1_SLAVE_DS2438=m ++CONFIG_W1_SLAVE_DS2780=m ++CONFIG_W1_SLAVE_DS2781=m ++CONFIG_W1_SLAVE_DS28E04=m ++CONFIG_POWER_RESET_GPIO=y ++CONFIG_BATTERY_DS2760=m ++CONFIG_BATTERY_GAUGE_LTC2941=m ++CONFIG_HWMON=m ++CONFIG_SENSORS_DS1621=m ++CONFIG_SENSORS_JC42=m ++CONFIG_SENSORS_LM75=m ++CONFIG_SENSORS_SHT21=m ++CONFIG_SENSORS_SHT3x=m ++CONFIG_SENSORS_SHTC1=m ++CONFIG_SENSORS_ADS1015=m ++CONFIG_SENSORS_INA2XX=m ++CONFIG_SENSORS_TMP102=m ++CONFIG_THERMAL=y ++CONFIG_BCM2835_THERMAL=y ++CONFIG_WATCHDOG=y ++CONFIG_GPIO_WATCHDOG=m ++CONFIG_BCM2835_WDT=y ++CONFIG_MFD_STMPE=y ++CONFIG_STMPE_SPI=y ++CONFIG_MFD_ARIZONA_I2C=m ++CONFIG_MFD_ARIZONA_SPI=m ++CONFIG_MFD_WM5102=y ++CONFIG_REGULATOR=y ++CONFIG_REGULATOR_FIXED_VOLTAGE=m ++CONFIG_REGULATOR_ARIZONA_LDO1=m ++CONFIG_REGULATOR_ARIZONA_MICSUPP=m ++CONFIG_REGULATOR_GPIO=y ++CONFIG_MEDIA_SUPPORT=m ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++CONFIG_MEDIA_ANALOG_TV_SUPPORT=y ++CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y ++CONFIG_MEDIA_RADIO_SUPPORT=y ++CONFIG_MEDIA_CONTROLLER=y ++CONFIG_MEDIA_USB_SUPPORT=y ++CONFIG_USB_VIDEO_CLASS=m ++CONFIG_USB_M5602=m ++CONFIG_USB_STV06XX=m ++CONFIG_USB_GL860=m ++CONFIG_USB_GSPCA_BENQ=m ++CONFIG_USB_GSPCA_CONEX=m ++CONFIG_USB_GSPCA_CPIA1=m ++CONFIG_USB_GSPCA_DTCS033=m ++CONFIG_USB_GSPCA_ETOMS=m ++CONFIG_USB_GSPCA_FINEPIX=m ++CONFIG_USB_GSPCA_JEILINJ=m ++CONFIG_USB_GSPCA_JL2005BCD=m ++CONFIG_USB_GSPCA_KINECT=m ++CONFIG_USB_GSPCA_KONICA=m ++CONFIG_USB_GSPCA_MARS=m ++CONFIG_USB_GSPCA_MR97310A=m ++CONFIG_USB_GSPCA_NW80X=m ++CONFIG_USB_GSPCA_OV519=m ++CONFIG_USB_GSPCA_OV534=m ++CONFIG_USB_GSPCA_OV534_9=m ++CONFIG_USB_GSPCA_PAC207=m ++CONFIG_USB_GSPCA_PAC7302=m ++CONFIG_USB_GSPCA_PAC7311=m ++CONFIG_USB_GSPCA_SE401=m ++CONFIG_USB_GSPCA_SN9C2028=m ++CONFIG_USB_GSPCA_SN9C20X=m ++CONFIG_USB_GSPCA_SONIXB=m ++CONFIG_USB_GSPCA_SONIXJ=m ++CONFIG_USB_GSPCA_SPCA500=m ++CONFIG_USB_GSPCA_SPCA501=m ++CONFIG_USB_GSPCA_SPCA505=m ++CONFIG_USB_GSPCA_SPCA506=m ++CONFIG_USB_GSPCA_SPCA508=m ++CONFIG_USB_GSPCA_SPCA561=m ++CONFIG_USB_GSPCA_SPCA1528=m ++CONFIG_USB_GSPCA_SQ905=m ++CONFIG_USB_GSPCA_SQ905C=m ++CONFIG_USB_GSPCA_SQ930X=m ++CONFIG_USB_GSPCA_STK014=m ++CONFIG_USB_GSPCA_STK1135=m ++CONFIG_USB_GSPCA_STV0680=m ++CONFIG_USB_GSPCA_SUNPLUS=m ++CONFIG_USB_GSPCA_T613=m ++CONFIG_USB_GSPCA_TOPRO=m ++CONFIG_USB_GSPCA_TV8532=m ++CONFIG_USB_GSPCA_VC032X=m ++CONFIG_USB_GSPCA_VICAM=m ++CONFIG_USB_GSPCA_XIRLINK_CIT=m ++CONFIG_USB_GSPCA_ZC3XX=m ++CONFIG_USB_PWC=m ++CONFIG_VIDEO_CPIA2=m ++CONFIG_USB_ZR364XX=m ++CONFIG_USB_STKWEBCAM=m ++CONFIG_USB_S2255=m ++CONFIG_VIDEO_USBTV=m ++CONFIG_VIDEO_PVRUSB2=m ++CONFIG_VIDEO_HDPVR=m ++CONFIG_VIDEO_USBVISION=m ++CONFIG_VIDEO_STK1160_COMMON=m ++CONFIG_VIDEO_GO7007=m ++CONFIG_VIDEO_GO7007_USB=m ++CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m ++CONFIG_VIDEO_AU0828=m ++CONFIG_DVB_USB_V2=m ++CONFIG_DVB_USB_AF9035=m ++CONFIG_DVB_USB_ANYSEE=m ++CONFIG_DVB_USB_AU6610=m ++CONFIG_DVB_USB_AZ6007=m ++CONFIG_DVB_USB_CE6230=m ++CONFIG_DVB_USB_EC168=m ++CONFIG_DVB_USB_GL861=m ++CONFIG_DVB_USB_MXL111SF=m ++CONFIG_DVB_USB_DVBSKY=m ++CONFIG_SMS_USB_DRV=m ++CONFIG_DVB_B2C2_FLEXCOP_USB=m ++CONFIG_DVB_AS102=m ++CONFIG_VIDEO_EM28XX=m ++CONFIG_VIDEO_EM28XX_V4L2=m ++CONFIG_VIDEO_EM28XX_ALSA=m ++CONFIG_VIDEO_EM28XX_DVB=m ++CONFIG_V4L_PLATFORM_DRIVERS=y ++CONFIG_RADIO_SI470X=m ++CONFIG_USB_SI470X=m ++CONFIG_I2C_SI470X=m ++CONFIG_RADIO_SI4713=m ++CONFIG_I2C_SI4713=m ++CONFIG_USB_MR800=m ++CONFIG_USB_DSBR=m ++CONFIG_RADIO_SHARK=m ++CONFIG_RADIO_SHARK2=m ++CONFIG_USB_KEENE=m ++CONFIG_USB_MA901=m ++CONFIG_RADIO_TEA5764=m ++CONFIG_RADIO_SAA7706H=m ++CONFIG_RADIO_TEF6862=m ++CONFIG_RADIO_WL1273=m ++CONFIG_RADIO_WL128X=m ++# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set ++CONFIG_VIDEO_UDA1342=m ++CONFIG_VIDEO_SONY_BTF_MPX=m ++CONFIG_VIDEO_TVP5150=m ++CONFIG_VIDEO_TW2804=m ++CONFIG_VIDEO_TW9903=m ++CONFIG_VIDEO_TW9906=m ++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_VC4=m ++CONFIG_DRM_TINYDRM=m ++CONFIG_TINYDRM_MI0283QT=m ++CONFIG_TINYDRM_REPAPER=m ++CONFIG_FB=y ++CONFIG_FB_BCM2708=y ++CONFIG_FB_UDL=m ++CONFIG_FB_SSD1307=m ++CONFIG_FB_RPISENSE=m ++# CONFIG_BACKLIGHT_GENERIC is not set ++CONFIG_BACKLIGHT_RPI=m ++CONFIG_BACKLIGHT_GPIO=m ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_LOGO=y ++# CONFIG_LOGO_LINUX_MONO is not set ++# CONFIG_LOGO_LINUX_VGA16 is not set ++CONFIG_SOUND=y ++CONFIG_SND=m ++CONFIG_SND_HRTIMER=m ++CONFIG_SND_SEQUENCER=m ++CONFIG_SND_SEQ_DUMMY=m ++CONFIG_SND_DUMMY=m ++CONFIG_SND_ALOOP=m ++CONFIG_SND_VIRMIDI=m ++CONFIG_SND_MTPAV=m ++CONFIG_SND_SERIAL_U16550=m ++CONFIG_SND_MPU401=m ++CONFIG_SND_USB_AUDIO=m ++CONFIG_SND_USB_UA101=m ++CONFIG_SND_USB_CAIAQ=m ++CONFIG_SND_USB_CAIAQ_INPUT=y ++CONFIG_SND_USB_6FIRE=m ++CONFIG_SND_USB_HIFACE=m ++CONFIG_SND_SOC=m ++CONFIG_SND_BCM2835_SOC_I2S=m ++CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m ++CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=m ++CONFIG_SND_BCM2708_SOC_RPI_DAC=m ++CONFIG_SND_BCM2708_SOC_RPI_PROTO=m ++CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m ++CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m ++CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m ++CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m ++CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m ++CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m ++CONFIG_SND_AUDIOINJECTOR_OCTO_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_BCM2708_SOC_ALLO_PIANO_DAC_PLUS=m ++CONFIG_SND_BCM2708_SOC_ALLO_BOSS_DAC=m ++CONFIG_SND_BCM2708_SOC_ALLO_DIGIONE=m ++CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC=m ++CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m ++CONFIG_SND_PISOUND=m ++CONFIG_SND_SOC_ADAU1701=m ++CONFIG_SND_SOC_ADAU7002=m ++CONFIG_SND_SOC_AK4554=m ++CONFIG_SND_SOC_CS4271_I2C=m ++CONFIG_SND_SOC_SPDIF=m ++CONFIG_SND_SOC_WM8804_I2C=m ++CONFIG_SND_SIMPLE_CARD=m ++CONFIG_HID_BATTERY_STRENGTH=y ++CONFIG_HIDRAW=y ++CONFIG_UHID=m ++CONFIG_HID_A4TECH=m ++CONFIG_HID_ACRUX=m ++CONFIG_HID_APPLE=m ++CONFIG_HID_ASUS=m ++CONFIG_HID_BELKIN=m ++CONFIG_HID_BETOP_FF=m ++CONFIG_HID_CHERRY=m ++CONFIG_HID_CHICONY=m ++CONFIG_HID_CYPRESS=m ++CONFIG_HID_DRAGONRISE=m ++CONFIG_HID_EMS_FF=m ++CONFIG_HID_ELECOM=m ++CONFIG_HID_ELO=m ++CONFIG_HID_EZKEY=m ++CONFIG_HID_GEMBIRD=m ++CONFIG_HID_HOLTEK=m ++CONFIG_HID_KEYTOUCH=m ++CONFIG_HID_KYE=m ++CONFIG_HID_UCLOGIC=m ++CONFIG_HID_WALTOP=m ++CONFIG_HID_GYRATION=m ++CONFIG_HID_TWINHAN=m ++CONFIG_HID_KENSINGTON=m ++CONFIG_HID_LCPOWER=m ++CONFIG_HID_LOGITECH=m ++CONFIG_HID_LOGITECH_DJ=m ++CONFIG_LOGITECH_FF=y ++CONFIG_LOGIRUMBLEPAD2_FF=y ++CONFIG_LOGIG940_FF=y ++CONFIG_HID_MAGICMOUSE=m ++CONFIG_HID_MICROSOFT=m ++CONFIG_HID_MONTEREY=m ++CONFIG_HID_MULTITOUCH=m ++CONFIG_HID_NTRIG=m ++CONFIG_HID_ORTEK=m ++CONFIG_HID_PANTHERLORD=m ++CONFIG_HID_PETALYNX=m ++CONFIG_HID_PICOLCD=m ++CONFIG_HID_ROCCAT=m ++CONFIG_HID_SAMSUNG=m ++CONFIG_HID_SONY=m ++CONFIG_SONY_FF=y ++CONFIG_HID_SPEEDLINK=m ++CONFIG_HID_SUNPLUS=m ++CONFIG_HID_GREENASIA=m ++CONFIG_HID_SMARTJOYPLUS=m ++CONFIG_HID_TOPSEED=m ++CONFIG_HID_THINGM=m ++CONFIG_HID_THRUSTMASTER=m ++CONFIG_HID_WACOM=m ++CONFIG_HID_WIIMOTE=m ++CONFIG_HID_XINMO=m ++CONFIG_HID_ZEROPLUS=m ++CONFIG_HID_ZYDACRON=m ++CONFIG_HID_PID=y ++CONFIG_USB_HIDDEV=y ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_MON=m ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_DWCOTG=y ++CONFIG_USB_PRINTER=m ++CONFIG_USB_STORAGE=y ++CONFIG_USB_STORAGE_REALTEK=m ++CONFIG_USB_STORAGE_DATAFAB=m ++CONFIG_USB_STORAGE_FREECOM=m ++CONFIG_USB_STORAGE_ISD200=m ++CONFIG_USB_STORAGE_USBAT=m ++CONFIG_USB_STORAGE_SDDR09=m ++CONFIG_USB_STORAGE_SDDR55=m ++CONFIG_USB_STORAGE_JUMPSHOT=m ++CONFIG_USB_STORAGE_ALAUDA=m ++CONFIG_USB_STORAGE_ONETOUCH=m ++CONFIG_USB_STORAGE_KARMA=m ++CONFIG_USB_STORAGE_CYPRESS_ATACB=m ++CONFIG_USB_STORAGE_ENE_UB6250=m ++CONFIG_USB_MDC800=m ++CONFIG_USB_MICROTEK=m ++CONFIG_USBIP_CORE=m ++CONFIG_USBIP_VHCI_HCD=m ++CONFIG_USBIP_HOST=m ++CONFIG_USB_DWC2=m ++CONFIG_USB_SERIAL=m ++CONFIG_USB_SERIAL_GENERIC=y ++CONFIG_USB_SERIAL_AIRCABLE=m ++CONFIG_USB_SERIAL_ARK3116=m ++CONFIG_USB_SERIAL_BELKIN=m ++CONFIG_USB_SERIAL_CH341=m ++CONFIG_USB_SERIAL_WHITEHEAT=m ++CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m ++CONFIG_USB_SERIAL_CP210X=m ++CONFIG_USB_SERIAL_CYPRESS_M8=m ++CONFIG_USB_SERIAL_EMPEG=m ++CONFIG_USB_SERIAL_FTDI_SIO=m ++CONFIG_USB_SERIAL_VISOR=m ++CONFIG_USB_SERIAL_IPAQ=m ++CONFIG_USB_SERIAL_IR=m ++CONFIG_USB_SERIAL_EDGEPORT=m ++CONFIG_USB_SERIAL_EDGEPORT_TI=m ++CONFIG_USB_SERIAL_F81232=m ++CONFIG_USB_SERIAL_GARMIN=m ++CONFIG_USB_SERIAL_IPW=m ++CONFIG_USB_SERIAL_IUU=m ++CONFIG_USB_SERIAL_KEYSPAN_PDA=m ++CONFIG_USB_SERIAL_KEYSPAN=m ++CONFIG_USB_SERIAL_KLSI=m ++CONFIG_USB_SERIAL_KOBIL_SCT=m ++CONFIG_USB_SERIAL_MCT_U232=m ++CONFIG_USB_SERIAL_METRO=m ++CONFIG_USB_SERIAL_MOS7720=m ++CONFIG_USB_SERIAL_MOS7840=m ++CONFIG_USB_SERIAL_NAVMAN=m ++CONFIG_USB_SERIAL_PL2303=m ++CONFIG_USB_SERIAL_OTI6858=m ++CONFIG_USB_SERIAL_QCAUX=m ++CONFIG_USB_SERIAL_QUALCOMM=m ++CONFIG_USB_SERIAL_SPCP8X5=m ++CONFIG_USB_SERIAL_SAFE=m ++CONFIG_USB_SERIAL_SIERRAWIRELESS=m ++CONFIG_USB_SERIAL_SYMBOL=m ++CONFIG_USB_SERIAL_TI=m ++CONFIG_USB_SERIAL_CYBERJACK=m ++CONFIG_USB_SERIAL_XIRCOM=m ++CONFIG_USB_SERIAL_OPTION=m ++CONFIG_USB_SERIAL_OMNINET=m ++CONFIG_USB_SERIAL_OPTICON=m ++CONFIG_USB_SERIAL_XSENS_MT=m ++CONFIG_USB_SERIAL_WISHBONE=m ++CONFIG_USB_SERIAL_SSU100=m ++CONFIG_USB_SERIAL_QT2=m ++CONFIG_USB_SERIAL_DEBUG=m ++CONFIG_USB_EMI62=m ++CONFIG_USB_EMI26=m ++CONFIG_USB_ADUTUX=m ++CONFIG_USB_SEVSEG=m ++CONFIG_USB_RIO500=m ++CONFIG_USB_LEGOTOWER=m ++CONFIG_USB_LCD=m ++CONFIG_USB_CYPRESS_CY7C63=m ++CONFIG_USB_CYTHERM=m ++CONFIG_USB_IDMOUSE=m ++CONFIG_USB_FTDI_ELAN=m ++CONFIG_USB_APPLEDISPLAY=m ++CONFIG_USB_LD=m ++CONFIG_USB_TRANCEVIBRATOR=m ++CONFIG_USB_IOWARRIOR=m ++CONFIG_USB_TEST=m ++CONFIG_USB_ISIGHTFW=m ++CONFIG_USB_YUREX=m ++CONFIG_USB_ATM=m ++CONFIG_USB_SPEEDTOUCH=m ++CONFIG_USB_CXACRU=m ++CONFIG_USB_UEAGLEATM=m ++CONFIG_USB_XUSBATM=m ++CONFIG_USB_GADGET=m ++CONFIG_USB_ZERO=m ++CONFIG_USB_AUDIO=m ++CONFIG_USB_ETH=m ++CONFIG_USB_GADGETFS=m ++CONFIG_USB_MASS_STORAGE=m ++CONFIG_USB_G_SERIAL=m ++CONFIG_USB_MIDI_GADGET=m ++CONFIG_USB_G_PRINTER=m ++CONFIG_USB_CDC_COMPOSITE=m ++CONFIG_USB_G_ACM_MS=m ++CONFIG_USB_G_MULTI=m ++CONFIG_USB_G_HID=m ++CONFIG_USB_G_WEBCAM=m ++CONFIG_MMC=y ++CONFIG_MMC_BLOCK_MINORS=32 ++CONFIG_MMC_SDHCI_BCM2711=y ++CONFIG_MMC_BCM2835_MMC=y ++CONFIG_MMC_BCM2835_DMA=y ++CONFIG_MMC_BCM2835_SDHOST=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SPI=m ++CONFIG_LEDS_CLASS=y ++CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_TRIGGER_TIMER=y ++CONFIG_LEDS_TRIGGER_ONESHOT=y ++CONFIG_LEDS_TRIGGER_HEARTBEAT=y ++CONFIG_LEDS_TRIGGER_BACKLIGHT=y ++CONFIG_LEDS_TRIGGER_CPU=y ++CONFIG_LEDS_TRIGGER_GPIO=y ++CONFIG_LEDS_TRIGGER_DEFAULT_ON=y ++CONFIG_LEDS_TRIGGER_TRANSIENT=m ++CONFIG_LEDS_TRIGGER_CAMERA=m ++CONFIG_LEDS_TRIGGER_INPUT=y ++CONFIG_LEDS_TRIGGER_PANIC=y ++CONFIG_RTC_CLASS=y ++# CONFIG_RTC_HCTOSYS is not set ++CONFIG_RTC_DRV_ABX80X=m ++CONFIG_RTC_DRV_DS1307=m ++CONFIG_RTC_DRV_DS1374=m ++CONFIG_RTC_DRV_DS1672=m ++CONFIG_RTC_DRV_MAX6900=m ++CONFIG_RTC_DRV_RS5C372=m ++CONFIG_RTC_DRV_ISL1208=m ++CONFIG_RTC_DRV_ISL12022=m ++CONFIG_RTC_DRV_X1205=m ++CONFIG_RTC_DRV_PCF8523=m ++CONFIG_RTC_DRV_PCF8563=m ++CONFIG_RTC_DRV_PCF8583=m ++CONFIG_RTC_DRV_M41T80=m ++CONFIG_RTC_DRV_BQ32K=m ++CONFIG_RTC_DRV_S35390A=m ++CONFIG_RTC_DRV_FM3130=m ++CONFIG_RTC_DRV_RX8581=m ++CONFIG_RTC_DRV_RX8025=m ++CONFIG_RTC_DRV_EM3027=m ++CONFIG_RTC_DRV_M41T93=m ++CONFIG_RTC_DRV_M41T94=m ++CONFIG_RTC_DRV_DS1302=m ++CONFIG_RTC_DRV_DS1305=m ++CONFIG_RTC_DRV_DS1390=m ++CONFIG_RTC_DRV_R9701=m ++CONFIG_RTC_DRV_RX4581=m ++CONFIG_RTC_DRV_RS5C348=m ++CONFIG_RTC_DRV_MAX6902=m ++CONFIG_RTC_DRV_PCF2123=m ++CONFIG_RTC_DRV_DS3232=m ++CONFIG_RTC_DRV_PCF2127=m ++CONFIG_RTC_DRV_RV3029C2=m ++CONFIG_DMADEVICES=y ++CONFIG_DMA_BCM2835=y ++CONFIG_DMA_BCM2708=y ++CONFIG_UIO=m ++CONFIG_UIO_PDRV_GENIRQ=m ++CONFIG_STAGING=y ++CONFIG_PRISM2_USB=m ++CONFIG_R8712U=m ++CONFIG_R8188EU=m ++CONFIG_VT6656=m ++CONFIG_SPEAKUP=m ++CONFIG_SPEAKUP_SYNTH_SOFT=m ++CONFIG_STAGING_MEDIA=y ++CONFIG_FB_TFT=m ++CONFIG_FB_TFT_AGM1264K_FL=m ++CONFIG_FB_TFT_BD663474=m ++CONFIG_FB_TFT_HX8340BN=m ++CONFIG_FB_TFT_HX8347D=m ++CONFIG_FB_TFT_HX8353D=m ++CONFIG_FB_TFT_HX8357D=m ++CONFIG_FB_TFT_ILI9163=m ++CONFIG_FB_TFT_ILI9320=m ++CONFIG_FB_TFT_ILI9325=m ++CONFIG_FB_TFT_ILI9340=m ++CONFIG_FB_TFT_ILI9341=m ++CONFIG_FB_TFT_ILI9481=m ++CONFIG_FB_TFT_ILI9486=m ++CONFIG_FB_TFT_PCD8544=m ++CONFIG_FB_TFT_RA8875=m ++CONFIG_FB_TFT_S6D02A1=m ++CONFIG_FB_TFT_S6D1121=m ++CONFIG_FB_TFT_SSD1289=m ++CONFIG_FB_TFT_SSD1306=m ++CONFIG_FB_TFT_SSD1331=m ++CONFIG_FB_TFT_SSD1351=m ++CONFIG_FB_TFT_ST7735R=m ++CONFIG_FB_TFT_ST7789V=m ++CONFIG_FB_TFT_TINYLCD=m ++CONFIG_FB_TFT_TLS8204=m ++CONFIG_FB_TFT_UC1701=m ++CONFIG_FB_TFT_UPD161704=m ++CONFIG_FB_TFT_WATTEROTT=m ++CONFIG_FB_FLEX=m ++CONFIG_FB_TFT_FBTFT_DEVICE=m ++CONFIG_SND_BCM2835=m ++CONFIG_VIDEO_BCM2835=m ++CONFIG_MAILBOX=y ++CONFIG_BCM2835_MBOX=y ++# CONFIG_IOMMU_SUPPORT is not set ++CONFIG_RASPBERRYPI_POWER=y ++CONFIG_EXTCON=m ++CONFIG_EXTCON_ARIZONA=m ++CONFIG_IIO=m ++CONFIG_IIO_BUFFER_CB=m ++CONFIG_MCP320X=m ++CONFIG_MCP3422=m ++CONFIG_DHT11=m ++CONFIG_HDC100X=m ++CONFIG_HTU21=m ++CONFIG_TSL4531=m ++CONFIG_VEML6070=m ++CONFIG_BMP280=m ++CONFIG_PWM_BCM2835=m ++CONFIG_PWM_PCA9685=m ++CONFIG_GENERIC_PHY=y ++CONFIG_RPI_AXIPERF=m ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_REISERFS_FS=m ++CONFIG_REISERFS_FS_XATTR=y ++CONFIG_REISERFS_FS_POSIX_ACL=y ++CONFIG_REISERFS_FS_SECURITY=y ++CONFIG_JFS_FS=m ++CONFIG_JFS_POSIX_ACL=y ++CONFIG_JFS_SECURITY=y ++CONFIG_JFS_STATISTICS=y ++CONFIG_XFS_FS=m ++CONFIG_XFS_QUOTA=y ++CONFIG_XFS_POSIX_ACL=y ++CONFIG_XFS_RT=y ++CONFIG_GFS2_FS=m ++CONFIG_OCFS2_FS=m ++CONFIG_BTRFS_FS=m ++CONFIG_BTRFS_FS_POSIX_ACL=y ++CONFIG_NILFS2_FS=m ++CONFIG_F2FS_FS=y ++CONFIG_FANOTIFY=y ++CONFIG_QFMT_V1=m ++CONFIG_QFMT_V2=m ++CONFIG_AUTOFS4_FS=y ++CONFIG_FUSE_FS=m ++CONFIG_CUSE=m ++CONFIG_OVERLAY_FS=m ++CONFIG_FSCACHE=y ++CONFIG_FSCACHE_STATS=y ++CONFIG_FSCACHE_HISTOGRAM=y ++CONFIG_CACHEFILES=y ++CONFIG_ISO9660_FS=m ++CONFIG_JOLIET=y ++CONFIG_ZISOFS=y ++CONFIG_UDF_FS=m ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_IOCHARSET="ascii" ++CONFIG_NTFS_FS=m ++CONFIG_NTFS_RW=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_ECRYPT_FS=m ++CONFIG_HFS_FS=m ++CONFIG_HFSPLUS_FS=m ++CONFIG_JFFS2_FS=m ++CONFIG_JFFS2_SUMMARY=y ++CONFIG_UBIFS_FS=m ++CONFIG_SQUASHFS=m ++CONFIG_SQUASHFS_XATTR=y ++CONFIG_SQUASHFS_LZO=y ++CONFIG_SQUASHFS_XZ=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_NFS_V4_1=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFS_FSCACHE=y ++CONFIG_NFSD=m ++CONFIG_NFSD_V3_ACL=y ++CONFIG_NFSD_V4=y ++CONFIG_CIFS=m ++CONFIG_CIFS_WEAK_PW_HASH=y ++CONFIG_CIFS_UPCALL=y ++CONFIG_CIFS_XATTR=y ++CONFIG_CIFS_POSIX=y ++CONFIG_CIFS_ACL=y ++CONFIG_CIFS_DFS_UPCALL=y ++CONFIG_CIFS_FSCACHE=y ++CONFIG_9P_FS=m ++CONFIG_9P_FS_POSIX_ACL=y ++CONFIG_NLS_DEFAULT="utf8" ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_737=m ++CONFIG_NLS_CODEPAGE_775=m ++CONFIG_NLS_CODEPAGE_850=m ++CONFIG_NLS_CODEPAGE_852=m ++CONFIG_NLS_CODEPAGE_855=m ++CONFIG_NLS_CODEPAGE_857=m ++CONFIG_NLS_CODEPAGE_860=m ++CONFIG_NLS_CODEPAGE_861=m ++CONFIG_NLS_CODEPAGE_862=m ++CONFIG_NLS_CODEPAGE_863=m ++CONFIG_NLS_CODEPAGE_864=m ++CONFIG_NLS_CODEPAGE_865=m ++CONFIG_NLS_CODEPAGE_866=m ++CONFIG_NLS_CODEPAGE_869=m ++CONFIG_NLS_CODEPAGE_936=m ++CONFIG_NLS_CODEPAGE_950=m ++CONFIG_NLS_CODEPAGE_932=m ++CONFIG_NLS_CODEPAGE_949=m ++CONFIG_NLS_CODEPAGE_874=m ++CONFIG_NLS_ISO8859_8=m ++CONFIG_NLS_CODEPAGE_1250=m ++CONFIG_NLS_CODEPAGE_1251=m ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=m ++CONFIG_NLS_ISO8859_2=m ++CONFIG_NLS_ISO8859_3=m ++CONFIG_NLS_ISO8859_4=m ++CONFIG_NLS_ISO8859_5=m ++CONFIG_NLS_ISO8859_6=m ++CONFIG_NLS_ISO8859_7=m ++CONFIG_NLS_ISO8859_9=m ++CONFIG_NLS_ISO8859_13=m ++CONFIG_NLS_ISO8859_14=m ++CONFIG_NLS_ISO8859_15=m ++CONFIG_NLS_KOI8_R=m ++CONFIG_NLS_KOI8_U=m ++CONFIG_DLM=m ++CONFIG_CRYPTO_USER=m ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_CTS=m ++CONFIG_CRYPTO_XTS=m ++CONFIG_CRYPTO_XCBC=m ++CONFIG_CRYPTO_TGR192=m ++CONFIG_CRYPTO_WP512=m ++CONFIG_CRYPTO_CAST5=m ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_LZ4=m ++CONFIG_CRYPTO_USER_API_SKCIPHER=m ++CONFIG_CRC_ITU_T=y ++CONFIG_LIBCRC32C=y ++CONFIG_PRINTK_TIME=y ++CONFIG_BOOT_PRINTK_DELAY=y ++CONFIG_DEBUG_MEMORY_INIT=y ++CONFIG_DETECT_HUNG_TASK=y ++CONFIG_LATENCYTOP=y ++CONFIG_IRQSOFF_TRACER=y ++CONFIG_SCHED_TRACER=y ++CONFIG_STACK_TRACER=y ++CONFIG_BLK_DEV_IO_TRACE=y ++CONFIG_FUNCTION_PROFILER=y ++CONFIG_KGDB=y ++CONFIG_KGDB_KDB=y ++CONFIG_KDB_KEYBOARD=y diff --git a/target/linux/brcm2708/patches-4.19/950-0641-spi-devicetree-add-overlays-for-spi-3-to-6.patch b/target/linux/brcm2708/patches-4.19/950-0641-spi-devicetree-add-overlays-for-spi-3-to-6.patch deleted file mode 100644 index f20cd10d39..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0641-spi-devicetree-add-overlays-for-spi-3-to-6.patch +++ /dev/null @@ -1,581 +0,0 @@ -From 075cb9a202526c4d4e712fda5db598c28ae74e4a Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Sun, 12 May 2019 16:17:08 +0000 -Subject: [PATCH 641/703] spi: devicetree: add overlays for spi 3 to 6 - -Signed-off-by: Martin Sperl ---- - arch/arm/boot/dts/overlays/Makefile | 8 ++ - arch/arm/boot/dts/overlays/README | 104 ++++++++++++++++++ - .../boot/dts/overlays/spi3-1cs-overlay.dts | 44 ++++++++ - .../boot/dts/overlays/spi3-2cs-overlay.dts | 56 ++++++++++ - .../boot/dts/overlays/spi4-1cs-overlay.dts | 44 ++++++++ - .../boot/dts/overlays/spi4-2cs-overlay.dts | 56 ++++++++++ - .../boot/dts/overlays/spi5-1cs-overlay.dts | 44 ++++++++ - .../boot/dts/overlays/spi5-2cs-overlay.dts | 56 ++++++++++ - .../boot/dts/overlays/spi6-1cs-overlay.dts | 44 ++++++++ - .../boot/dts/overlays/spi6-2cs-overlay.dts | 56 ++++++++++ - 10 files changed, 512 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/spi3-1cs-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi3-2cs-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi4-1cs-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi4-2cs-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi5-1cs-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi5-2cs-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi6-1cs-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi6-2cs-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -144,6 +144,14 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - spi2-1cs.dtbo \ - spi2-2cs.dtbo \ - spi2-3cs.dtbo \ -+ spi3-1cs.dtbo \ -+ spi3-2cs.dtbo \ -+ spi4-1cs.dtbo \ -+ spi4-2cs.dtbo \ -+ spi5-1cs.dtbo \ -+ spi5-2cs.dtbo \ -+ spi6-1cs.dtbo \ -+ spi6-2cs.dtbo \ - ssd1306.dtbo \ - superaudioboard.dtbo \ - sx150x.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -2085,6 +2085,110 @@ Params: cs0_pin GPIO pin - is 'okay' or enabled). - - -+Name: spi3-1cs -+Info: Enables spi3 with a single chip select (CS) line and associated spidev -+ dev node. The gpio pin number for the CS line and spidev device node -+ creation are configurable. -+Load: dtoverlay=spi3-1cs,= -+Params: cs0_pin GPIO pin for CS0 (default 0 - BCM SPI3_CE0). -+ cs0_spidev Set to 'off' to prevent the creation of a -+ userspace device node /dev/spidev3.0 (default -+ is 'on' or enabled). -+ -+ -+Name: spi3-2cs -+Info: Enables spi3 with two chip select (CS) lines and associated spidev -+ dev nodes. The gpio pin numbers for the CS lines and spidev device node -+ creation are configurable. -+Load: dtoverlay=spi3-2cs,= -+Params: cs0_pin GPIO pin for CS0 (default 0 - BCM SPI3_CE0). -+ cs1_pin GPIO pin for CS1 (default 24 - BCM SPI3_CE1). -+ cs0_spidev Set to 'off' to prevent the creation of a -+ userspace device node /dev/spidev3.0 (default -+ is 'on' or enabled). -+ cs1_spidev Set to 'off' to prevent the creation of a -+ userspace device node /dev/spidev3.1 (default -+ is 'on' or enabled). -+ -+ -+Name: spi4-1cs -+Info: Enables spi4 with a single chip select (CS) line and associated spidev -+ dev node. The gpio pin number for the CS line and spidev device node -+ creation are configurable. -+Load: dtoverlay=spi4-1cs,= -+Params: cs0_pin GPIO pin for CS0 (default 4 - BCM SPI4_CE0). -+ cs0_spidev Set to 'off' to prevent the creation of a -+ userspace device node /dev/spidev4.0 (default -+ is 'on' or enabled). -+ -+ -+Name: spi4-2cs -+Info: Enables spi4 with two chip select (CS) lines and associated spidev -+ dev nodes. The gpio pin numbers for the CS lines and spidev device node -+ creation are configurable. -+Load: dtoverlay=spi4-2cs,= -+Params: cs0_pin GPIO pin for CS0 (default 4 - BCM SPI4_CE0). -+ cs1_pin GPIO pin for CS1 (default 25 - BCM SPI4_CE1). -+ cs0_spidev Set to 'off' to prevent the creation of a -+ userspace device node /dev/spidev4.0 (default -+ is 'on' or enabled). -+ cs1_spidev Set to 'off' to prevent the creation of a -+ userspace device node /dev/spidev4.1 (default -+ is 'on' or enabled). -+ -+ -+Name: spi5-1cs -+Info: Enables spi5 with a single chip select (CS) line and associated spidev -+ dev node. The gpio pin numbers for the CS lines and spidev device node -+ creation are configurable. -+Load: dtoverlay=spi5-1cs,= -+Params: cs0_pin GPIO pin for CS0 (default 12 - BCM SPI5_CE0). -+ cs0_spidev Set to 'off' to prevent the creation of a -+ userspace device node /dev/spidev5.0 (default -+ is 'on' or enabled). -+ -+ -+Name: spi5-2cs -+Info: Enables spi5 with two chip select (CS) lines and associated spidev -+ dev nodes. The gpio pin numbers for the CS lines and spidev device node -+ creation are configurable. -+Load: dtoverlay=spi5-2cs,= -+Params: cs0_pin GPIO pin for CS0 (default 12 - BCM SPI5_CE0). -+ cs1_pin GPIO pin for CS1 (default 26 - BCM SPI5_CE1). -+ cs0_spidev Set to 'off' to prevent the creation of a -+ userspace device node /dev/spidev5.0 (default -+ is 'on' or enabled). -+ cs1_spidev Set to 'off' to prevent the creation of a -+ userspace device node /dev/spidev5.1 (default -+ is 'on' or enabled). -+ -+ -+Name: spi6-1cs -+Info: Enables spi6 with a single chip select (CS) line and associated spidev -+ dev node. The gpio pin number for the CS line and spidev device node -+ creation are configurable. -+Load: dtoverlay=spi6-1cs,= -+Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI6_CE0). -+ cs0_spidev Set to 'off' to prevent the creation of a -+ userspace device node /dev/spidev6.0 (default -+ is 'on' or enabled). -+ -+ -+Name: spi6-2cs -+Info: Enables spi6 with two chip select (CS) lines and associated spidev -+ dev nodes. The gpio pin numbers for the CS lines and spidev device node -+ creation are configurable. -+Load: dtoverlay=spi6-2cs,= -+Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI6_CE0). -+ cs1_pin GPIO pin for CS1 (default 27 - BCM SPI6_CE1). -+ cs0_spidev Set to 'off' to prevent the creation of a -+ userspace device node /dev/spidev6.0 (default -+ is 'on' or enabled). -+ cs1_spidev Set to 'off' to prevent the creation of a -+ userspace device node /dev/spidev6.1 (default -+ is 'on' or enabled). -+ -+ - Name: ssd1306 - Info: Overlay for activation of SSD1306 over I2C OLED display framebuffer. - Load: dtoverlay=ssd1306,= ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi3-1cs-overlay.dts -@@ -0,0 +1,44 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2838"; -+ -+ fragment@0 { -+ target = <&spi3_cs_pins>; -+ frag0: __overlay__ { -+ brcm,pins = <0>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi3>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi3_pins &spi3_cs_pins>; -+ cs-gpios = <&gpio 0 1>; -+ status = "okay"; -+ -+ spidev3_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&frag0>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs0_spidev = <&spidev3_0>,"status"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi3-2cs-overlay.dts -@@ -0,0 +1,56 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2838"; -+ -+ fragment@0 { -+ target = <&spi3_cs_pins>; -+ frag0: __overlay__ { -+ brcm,pins = <0 24>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi3>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi3_pins &spi3_cs_pins>; -+ cs-gpios = <&gpio 0 1>, <&gpio 24 1>; -+ status = "okay"; -+ -+ spidev3_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ status = "okay"; -+ }; -+ -+ spidev3_1: spidev@1 { -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&frag0>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs1_pin = <&frag0>,"brcm,pins:4", -+ <&frag1>,"cs-gpios:16"; -+ cs0_spidev = <&spidev3_0>,"status"; -+ cs1_spidev = <&spidev3_1>,"status"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi4-1cs-overlay.dts -@@ -0,0 +1,44 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2838"; -+ -+ fragment@0 { -+ target = <&spi4_cs_pins>; -+ frag0: __overlay__ { -+ brcm,pins = <4>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi4>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi4_pins &spi4_cs_pins>; -+ cs-gpios = <&gpio 4 1>; -+ status = "okay"; -+ -+ spidev4_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&frag0>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs0_spidev = <&spidev4_0>,"status"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi4-2cs-overlay.dts -@@ -0,0 +1,56 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2838"; -+ -+ fragment@0 { -+ target = <&spi4_cs_pins>; -+ frag0: __overlay__ { -+ brcm,pins = <4 25>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi4>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi4_pins &spi4_cs_pins>; -+ cs-gpios = <&gpio 4 1>, <&gpio 25 1>; -+ status = "okay"; -+ -+ spidev4_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ status = "okay"; -+ }; -+ -+ spidev4_1: spidev@1 { -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&frag0>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs1_pin = <&frag0>,"brcm,pins:4", -+ <&frag1>,"cs-gpios:16"; -+ cs0_spidev = <&spidev4_0>,"status"; -+ cs1_spidev = <&spidev4_1>,"status"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi5-1cs-overlay.dts -@@ -0,0 +1,44 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2838"; -+ -+ fragment@0 { -+ target = <&spi5_cs_pins>; -+ frag0: __overlay__ { -+ brcm,pins = <12>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi5>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi5_pins &spi5_cs_pins>; -+ cs-gpios = <&gpio 12 1>; -+ status = "okay"; -+ -+ spidev5_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&frag0>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs0_spidev = <&spidev5_0>,"status"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi5-2cs-overlay.dts -@@ -0,0 +1,56 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2838"; -+ -+ fragment@0 { -+ target = <&spi5_cs_pins>; -+ frag0: __overlay__ { -+ brcm,pins = <12 26>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi5>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi5_pins &spi5_cs_pins>; -+ cs-gpios = <&gpio 12 1>, <&gpio 26 1>; -+ status = "okay"; -+ -+ spidev5_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ status = "okay"; -+ }; -+ -+ spidev5_1: spidev@1 { -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&frag0>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs1_pin = <&frag0>,"brcm,pins:4", -+ <&frag1>,"cs-gpios:16"; -+ cs0_spidev = <&spidev5_0>,"status"; -+ cs1_spidev = <&spidev5_1>,"status"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi6-1cs-overlay.dts -@@ -0,0 +1,44 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2838"; -+ -+ fragment@0 { -+ target = <&spi6_cs_pins>; -+ frag0: __overlay__ { -+ brcm,pins = <18>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi6>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi6_pins &spi6_cs_pins>; -+ cs-gpios = <&gpio 18 1>; -+ status = "okay"; -+ -+ spidev6_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&frag0>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs0_spidev = <&spidev6_0>,"status"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi6-2cs-overlay.dts -@@ -0,0 +1,56 @@ -+/dts-v1/; -+/plugin/; -+ -+ -+/ { -+ compatible = "brcm,bcm2838"; -+ -+ fragment@0 { -+ target = <&spi6_cs_pins>; -+ frag0: __overlay__ { -+ brcm,pins = <18 27>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi6>; -+ frag1: __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi6_pins &spi6_cs_pins>; -+ cs-gpios = <&gpio 18 1>, <&gpio 27 1>; -+ status = "okay"; -+ -+ spidev6_0: spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ status = "okay"; -+ }; -+ -+ spidev6_1: spidev@1 { -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ cs0_pin = <&frag0>,"brcm,pins:0", -+ <&frag1>,"cs-gpios:4"; -+ cs1_pin = <&frag0>,"brcm,pins:4", -+ <&frag1>,"cs-gpios:16"; -+ cs0_spidev = <&spidev6_0>,"status"; -+ cs1_spidev = <&spidev6_1>,"status"; -+ }; -+}; diff --git a/target/linux/brcm2708/patches-4.19/950-0642-config-Add-NF_TABLES-support.patch b/target/linux/brcm2708/patches-4.19/950-0642-config-Add-NF_TABLES-support.patch new file mode 100644 index 0000000000..7be7e07c3e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0642-config-Add-NF_TABLES-support.patch @@ -0,0 +1,87 @@ +From ab6bac248c5cd5950b5658be31e7484b1eac9333 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 3 Jun 2019 14:57:56 +0100 +Subject: [PATCH 642/725] config: Add NF_TABLES support + +--- + arch/arm/configs/bcm2711_defconfig | 48 ++++++++++++++++++++++++++++++ + 1 file changed, 48 insertions(+) + +--- a/arch/arm/configs/bcm2711_defconfig ++++ b/arch/arm/configs/bcm2711_defconfig +@@ -133,6 +133,36 @@ CONFIG_NF_CONNTRACK_SANE=m + CONFIG_NF_CONNTRACK_SIP=m + CONFIG_NF_CONNTRACK_TFTP=m + CONFIG_NF_CT_NETLINK=m ++CONFIG_NF_TABLES=m ++CONFIG_NF_TABLES_SET=m ++CONFIG_NF_TABLES_INET=y ++CONFIG_NF_TABLES_NETDEV=y ++CONFIG_NFT_NUMGEN=m ++CONFIG_NFT_CT=m ++CONFIG_NFT_FLOW_OFFLOAD=m ++CONFIG_NFT_COUNTER=m ++CONFIG_NFT_CONNLIMIT=m ++CONFIG_NFT_LOG=m ++CONFIG_NFT_LIMIT=m ++CONFIG_NFT_MASQ=m ++CONFIG_NFT_REDIR=m ++CONFIG_NFT_NAT=m ++CONFIG_NFT_TUNNEL=m ++CONFIG_NFT_OBJREF=m ++CONFIG_NFT_QUEUE=m ++CONFIG_NFT_QUOTA=m ++CONFIG_NFT_REJECT=m ++CONFIG_NFT_COMPAT=m ++CONFIG_NFT_HASH=m ++CONFIG_NFT_FIB_INET=m ++CONFIG_NFT_SOCKET=m ++CONFIG_NFT_OSF=m ++CONFIG_NFT_TPROXY=m ++CONFIG_NFT_DUP_NETDEV=m ++CONFIG_NFT_FWD_NETDEV=m ++CONFIG_NFT_FIB_NETDEV=m ++CONFIG_NF_FLOW_TABLE_INET=m ++CONFIG_NF_FLOW_TABLE=m + CONFIG_NETFILTER_XT_SET=m + CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m + CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +@@ -220,6 +250,14 @@ CONFIG_IP_VS_SED=m + CONFIG_IP_VS_NQ=m + CONFIG_IP_VS_FTP=m + CONFIG_IP_VS_PE_SIP=m ++CONFIG_NFT_CHAIN_ROUTE_IPV4=m ++CONFIG_NFT_DUP_IPV4=m ++CONFIG_NFT_FIB_IPV4=m ++CONFIG_NF_TABLES_ARP=y ++CONFIG_NF_FLOW_TABLE_IPV4=m ++CONFIG_NFT_CHAIN_NAT_IPV4=m ++CONFIG_NFT_MASQ_IPV4=m ++CONFIG_NFT_REDIR_IPV4=m + CONFIG_IP_NF_IPTABLES=m + CONFIG_IP_NF_MATCH_AH=m + CONFIG_IP_NF_MATCH_ECN=m +@@ -239,6 +277,13 @@ CONFIG_IP_NF_RAW=m + CONFIG_IP_NF_ARPTABLES=m + CONFIG_IP_NF_ARPFILTER=m + CONFIG_IP_NF_ARP_MANGLE=m ++CONFIG_NFT_CHAIN_ROUTE_IPV6=m ++CONFIG_NFT_CHAIN_NAT_IPV6=m ++CONFIG_NFT_MASQ_IPV6=m ++CONFIG_NFT_REDIR_IPV6=m ++CONFIG_NFT_DUP_IPV6=m ++CONFIG_NFT_FIB_IPV6=m ++CONFIG_NF_FLOW_TABLE_IPV6=m + CONFIG_IP6_NF_IPTABLES=m + CONFIG_IP6_NF_MATCH_AH=m + CONFIG_IP6_NF_MATCH_EUI64=m +@@ -257,6 +302,9 @@ CONFIG_IP6_NF_RAW=m + CONFIG_IP6_NF_NAT=m + CONFIG_IP6_NF_TARGET_MASQUERADE=m + CONFIG_IP6_NF_TARGET_NPT=m ++CONFIG_NF_TABLES_BRIDGE=y ++CONFIG_NFT_BRIDGE_REJECT=m ++CONFIG_NF_LOG_BRIDGE=m + CONFIG_BRIDGE_NF_EBTABLES=m + CONFIG_BRIDGE_EBT_BROUTE=m + CONFIG_BRIDGE_EBT_T_FILTER=m diff --git a/target/linux/brcm2708/patches-4.19/950-0642-overlays-Add-the-spi-gpio40-45-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0642-overlays-Add-the-spi-gpio40-45-overlay.patch deleted file mode 100644 index 53508b2608..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0642-overlays-Add-the-spi-gpio40-45-overlay.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 14cd6256f49abbf230edc0c7a963f5e780255e98 Mon Sep 17 00:00:00 2001 -From: Tim Gover -Date: Tue, 22 Jan 2019 10:49:41 +0000 -Subject: [PATCH 642/703] overlays: Add the spi-gpio40-45 overlay - -The 2711 B0 boot EEPROM is programmed via SPI0 on GPIO -pins 40-43 CS0. Add a device tree overlay to optionally -change the SPI0 pinmux from the external GPIO pins to -the boot EEPROM pins. ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 6 ++++ - .../dts/overlays/spi-gpio40-45-overlay.dts | 36 +++++++++++++++++++ - 3 files changed, 43 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/spi-gpio40-45-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -135,6 +135,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - smi-dev.dtbo \ - smi-nand.dtbo \ - spi-gpio35-39.dtbo \ -+ spi-gpio40-45.dtbo \ - spi-rtc.dtbo \ - spi0-cs.dtbo \ - spi0-hw-cs.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1967,6 +1967,12 @@ Load: dtoverlay=spi-gpio35-39 - Params: - - -+Name: spi-gpio40-45 -+Info: Move SPI function block to GPIOs 40 to 45 -+Load: dtoverlay=spi-gpio40-45 -+Params: -+ -+ - Name: spi-rtc - Info: Adds support for a number of SPI Real Time Clock devices - Load: dtoverlay=spi-rtc,= ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi-gpio40-45-overlay.dts -@@ -0,0 +1,36 @@ -+/* -+ * Boot EEPROM overlay -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ cs-gpios = <&gpio 43 1>, <&gpio 44 1>, <&gpio 45 1>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi0_cs_pins>; -+ __overlay__ { -+ brcm,pins = <45 44 43>; -+ brcm,function = <1>; /* output */ -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0_pins>; -+ __overlay__ { -+ brcm,pins = <40 41 42>; -+ brcm,function = <3>; /* alt4 */ -+ status = "okay"; -+ }; -+ }; -+}; diff --git a/target/linux/brcm2708/patches-4.19/950-0643-bcm2711_defconfig-add-xhci-platform-support.patch b/target/linux/brcm2708/patches-4.19/950-0643-bcm2711_defconfig-add-xhci-platform-support.patch new file mode 100644 index 0000000000..b7ecfd0ae5 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0643-bcm2711_defconfig-add-xhci-platform-support.patch @@ -0,0 +1,20 @@ +From 7c68e81f33c801e539baece66f4d4b7e2c129557 Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Mon, 3 Jun 2019 15:33:02 +0100 +Subject: [PATCH 643/725] bcm2711_defconfig: add xhci platform support + +Signed-off-by: Jonathan Bell +--- + arch/arm/configs/bcm2711_defconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm/configs/bcm2711_defconfig ++++ b/arch/arm/configs/bcm2711_defconfig +@@ -983,6 +983,7 @@ CONFIG_USB=y + CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + CONFIG_USB_MON=m + CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_PLATFORM=y + CONFIG_USB_DWCOTG=y + CONFIG_USB_PRINTER=m + CONFIG_USB_STORAGE=y diff --git a/target/linux/brcm2708/patches-4.19/950-0643-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch b/target/linux/brcm2708/patches-4.19/950-0643-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch deleted file mode 100644 index aa8bd77866..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0643-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch +++ /dev/null @@ -1,44 +0,0 @@ -From fde90a0d1ca0b9a7dc0a7beec2ef60ec71b5cc7d Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 4 Sep 2018 11:50:25 +0100 -Subject: [PATCH 643/703] config: Permit LPAE and PCIE_BRCMSTB on BCM2835 - ---- - arch/arm/mach-bcm/Kconfig | 4 ++++ - drivers/pci/controller/Kconfig | 4 ++-- - 2 files changed, 6 insertions(+), 2 deletions(-) - ---- a/arch/arm/mach-bcm/Kconfig -+++ b/arch/arm/mach-bcm/Kconfig -@@ -161,6 +161,7 @@ config ARCH_BCM2835 - select GPIOLIB - select ARM_AMBA - select ARM_ERRATA_411920 if ARCH_MULTI_V6 -+ select ARM_GIC - select ARM_TIMER_SP804 - select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7 - select TIMER_OF -@@ -169,6 +170,9 @@ config ARCH_BCM2835 - select PINCTRL - select PINCTRL_BCM2835 - select MFD_SYSCON if ARCH_MULTI_V7 -+ select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE -+ select ZONE_DMA if ARM_LPAE -+ select MFD_CORE - help - This enables support for the Broadcom BCM2835 and BCM2836 SoCs. - This SoC is used in the Raspberry Pi and Roku 2 devices. ---- a/drivers/pci/controller/Kconfig -+++ b/drivers/pci/controller/Kconfig -@@ -280,9 +280,9 @@ config VMD - - config PCIE_BRCMSTB - tristate "Broadcom Brcmstb PCIe platform host driver" -- depends on ARCH_BRCMSTB || BMIPS_GENERIC -+ depends on ARCH_BRCMSTB || BMIPS_GENERIC || ARCH_BCM2835 - depends on OF -- depends on SOC_BRCMSTB -+ depends on SOC_BRCMSTB || ARCH_BCM2835 - default ARCH_BRCMSTB || BMIPS_GENERIC - help - Adds support for Broadcom Settop Box PCIe host controller. diff --git a/target/linux/brcm2708/patches-4.19/950-0644-ARM-dts-bcm283x-Correct-vchiq-compatible-string-2840.patch b/target/linux/brcm2708/patches-4.19/950-0644-ARM-dts-bcm283x-Correct-vchiq-compatible-string-2840.patch new file mode 100644 index 0000000000..7e2130353c --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0644-ARM-dts-bcm283x-Correct-vchiq-compatible-string-2840.patch @@ -0,0 +1,76 @@ +From 267eeb807da04f60d94b8355858926e8aad65a38 Mon Sep 17 00:00:00 2001 +From: 6by9 <6by9@users.noreply.github.com> +Date: Wed, 30 Jan 2019 14:22:03 +0000 +Subject: [PATCH 644/725] ARM: dts: bcm283x: Correct vchiq compatible string + (#2840) + +commit 499770ede3f829e80539f46b59b5f460dc327aa6 upstream. + +To allow VCHIQ to determine the correct cache line size, use the new +"brcm,bcm2836-vchiq" compatible string on BCM2836 and BCM2837. + +Signed-off-by: Phil Elwell +Acked-by: Stefan Wahren +Signed-off-by: Stefan Wahren +--- + arch/arm/boot/dts/bcm2835-rpi.dtsi | 2 +- + arch/arm/boot/dts/bcm2836-rpi-2-b.dts | 2 +- + arch/arm/boot/dts/bcm2836-rpi.dtsi | 6 ++++++ + arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 2 +- + arch/arm/boot/dts/bcm2837-rpi-3-b.dts | 2 +- + 5 files changed, 10 insertions(+), 4 deletions(-) + create mode 100644 arch/arm/boot/dts/bcm2836-rpi.dtsi + +--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi +@@ -30,7 +30,7 @@ + #power-domain-cells = <1>; + }; + +- mailbox@7e00b840 { ++ vchiq: mailbox@7e00b840 { + compatible = "brcm,bcm2835-vchiq"; + reg = <0x7e00b840 0x3c>; + interrupts = <0 2>; +--- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts ++++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + /dts-v1/; + #include "bcm2836.dtsi" +-#include "bcm2835-rpi.dtsi" ++#include "bcm2836-rpi.dtsi" + #include "bcm283x-rpi-smsc9514.dtsi" + #include "bcm283x-rpi-usb-host.dtsi" + #include "bcm283x-rpi-csi1-2lane.dtsi" +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2836-rpi.dtsi +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: GPL-2.0 ++#include "bcm2835-rpi.dtsi" ++ ++&vchiq { ++ compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq"; ++}; +--- a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + /dts-v1/; + #include "bcm2837.dtsi" +-#include "bcm2835-rpi.dtsi" ++#include "bcm2836-rpi.dtsi" + #include "bcm283x-rpi-lan7515.dtsi" + #include "bcm283x-rpi-usb-host.dtsi" + +--- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + /dts-v1/; + #include "bcm2837.dtsi" +-#include "bcm2835-rpi.dtsi" ++#include "bcm2836-rpi.dtsi" + #include "bcm283x-rpi-smsc9514.dtsi" + #include "bcm283x-rpi-usb-host.dtsi" + #include "bcm283x-rpi-csi1-2lane.dtsi" diff --git a/target/linux/brcm2708/patches-4.19/950-0644-configs-Add-bcm2711_defconfig.patch b/target/linux/brcm2708/patches-4.19/950-0644-configs-Add-bcm2711_defconfig.patch deleted file mode 100644 index a81354df7e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0644-configs-Add-bcm2711_defconfig.patch +++ /dev/null @@ -1,1343 +0,0 @@ -From 5ae8b0086763f26a25da24133eca8ecd3e5ef5a5 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 29 May 2019 15:40:21 +0100 -Subject: [PATCH 644/703] configs: Add bcm2711_defconfig - ---- - arch/arm/configs/bcm2711_defconfig | 1330 ++++++++++++++++++++++++++++ - 1 file changed, 1330 insertions(+) - create mode 100644 arch/arm/configs/bcm2711_defconfig - ---- /dev/null -+++ b/arch/arm/configs/bcm2711_defconfig -@@ -0,0 +1,1330 @@ -+CONFIG_LOCALVERSION="-v7l" -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_SYSVIPC=y -+CONFIG_POSIX_MQUEUE=y -+CONFIG_GENERIC_IRQ_DEBUGFS=y -+CONFIG_NO_HZ=y -+CONFIG_HIGH_RES_TIMERS=y -+CONFIG_PREEMPT_VOLUNTARY=y -+CONFIG_BSD_PROCESS_ACCT=y -+CONFIG_BSD_PROCESS_ACCT_V3=y -+CONFIG_TASKSTATS=y -+CONFIG_TASK_DELAY_ACCT=y -+CONFIG_TASK_XACCT=y -+CONFIG_TASK_IO_ACCOUNTING=y -+CONFIG_IKCONFIG=m -+CONFIG_IKCONFIG_PROC=y -+CONFIG_CGROUP_FREEZER=y -+CONFIG_CPUSETS=y -+CONFIG_CGROUP_DEVICE=y -+CONFIG_CGROUP_CPUACCT=y -+CONFIG_NAMESPACES=y -+CONFIG_USER_NS=y -+CONFIG_SCHED_AUTOGROUP=y -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_EMBEDDED=y -+# CONFIG_COMPAT_BRK is not set -+CONFIG_PROFILING=y -+CONFIG_ARCH_BCM=y -+CONFIG_ARCH_BCM2835=y -+CONFIG_ARM_LPAE=y -+# CONFIG_CACHE_L2X0 is not set -+CONFIG_PCI=y -+CONFIG_PCI_MSI=y -+CONFIG_PCIE_BRCMSTB=y -+CONFIG_SMP=y -+CONFIG_HIGHMEM=y -+CONFIG_UACCESS_WITH_MEMCPY=y -+CONFIG_SECCOMP=y -+# CONFIG_ATAGS is not set -+CONFIG_ZBOOT_ROM_TEXT=0x0 -+CONFIG_ZBOOT_ROM_BSS=0x0 -+CONFIG_CMDLINE="console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait" -+CONFIG_CPU_FREQ=y -+CONFIG_CPU_FREQ_STAT=y -+CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y -+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -+CONFIG_CPU_FREQ_GOV_USERSPACE=y -+CONFIG_CPU_FREQ_GOV_ONDEMAND=y -+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y -+CONFIG_VFP=y -+CONFIG_NEON=y -+CONFIG_KERNEL_MODE_NEON=y -+# CONFIG_SUSPEND is not set -+CONFIG_PM=y -+CONFIG_RASPBERRYPI_FIRMWARE=y -+CONFIG_ARM_CRYPTO=y -+CONFIG_CRYPTO_SHA1_ARM_NEON=m -+CONFIG_CRYPTO_AES_ARM=m -+CONFIG_CRYPTO_AES_ARM_BS=m -+CONFIG_OPROFILE=m -+CONFIG_KPROBES=y -+CONFIG_JUMP_LABEL=y -+CONFIG_MODULES=y -+CONFIG_MODULE_UNLOAD=y -+CONFIG_MODVERSIONS=y -+CONFIG_MODULE_SRCVERSION_ALL=y -+CONFIG_PARTITION_ADVANCED=y -+CONFIG_MAC_PARTITION=y -+CONFIG_BINFMT_MISC=m -+CONFIG_CLEANCACHE=y -+CONFIG_FRONTSWAP=y -+CONFIG_CMA=y -+CONFIG_ZSMALLOC=m -+CONFIG_PGTABLE_MAPPING=y -+CONFIG_NET=y -+CONFIG_PACKET=y -+CONFIG_UNIX=y -+CONFIG_XFRM_USER=y -+CONFIG_NET_KEY=m -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_ADVANCED_ROUTER=y -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_ROUTE_MULTIPATH=y -+CONFIG_IP_ROUTE_VERBOSE=y -+CONFIG_IP_PNP=y -+CONFIG_IP_PNP_DHCP=y -+CONFIG_IP_PNP_RARP=y -+CONFIG_NET_IPIP=m -+CONFIG_NET_IPGRE_DEMUX=m -+CONFIG_NET_IPGRE=m -+CONFIG_IP_MROUTE=y -+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IP_PIMSM_V1=y -+CONFIG_IP_PIMSM_V2=y -+CONFIG_SYN_COOKIES=y -+CONFIG_INET_AH=m -+CONFIG_INET_ESP=m -+CONFIG_INET_IPCOMP=m -+CONFIG_INET_XFRM_MODE_TRANSPORT=m -+CONFIG_INET_XFRM_MODE_TUNNEL=m -+CONFIG_INET_XFRM_MODE_BEET=m -+CONFIG_INET_DIAG=m -+CONFIG_TCP_CONG_ADVANCED=y -+CONFIG_TCP_CONG_BBR=m -+CONFIG_IPV6=m -+CONFIG_IPV6_ROUTER_PREF=y -+CONFIG_IPV6_ROUTE_INFO=y -+CONFIG_INET6_AH=m -+CONFIG_INET6_ESP=m -+CONFIG_INET6_IPCOMP=m -+CONFIG_IPV6_SIT_6RD=y -+CONFIG_IPV6_TUNNEL=m -+CONFIG_IPV6_MULTIPLE_TABLES=y -+CONFIG_IPV6_SUBTREES=y -+CONFIG_IPV6_MROUTE=y -+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IPV6_PIMSM_V2=y -+CONFIG_NETFILTER=y -+CONFIG_NF_CONNTRACK=m -+CONFIG_NF_CONNTRACK_ZONES=y -+CONFIG_NF_CONNTRACK_EVENTS=y -+CONFIG_NF_CONNTRACK_TIMESTAMP=y -+CONFIG_NF_CONNTRACK_AMANDA=m -+CONFIG_NF_CONNTRACK_FTP=m -+CONFIG_NF_CONNTRACK_H323=m -+CONFIG_NF_CONNTRACK_IRC=m -+CONFIG_NF_CONNTRACK_NETBIOS_NS=m -+CONFIG_NF_CONNTRACK_SNMP=m -+CONFIG_NF_CONNTRACK_PPTP=m -+CONFIG_NF_CONNTRACK_SANE=m -+CONFIG_NF_CONNTRACK_SIP=m -+CONFIG_NF_CONNTRACK_TFTP=m -+CONFIG_NF_CT_NETLINK=m -+CONFIG_NETFILTER_XT_SET=m -+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m -+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -+CONFIG_NETFILTER_XT_TARGET_DSCP=m -+CONFIG_NETFILTER_XT_TARGET_HMARK=m -+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m -+CONFIG_NETFILTER_XT_TARGET_LED=m -+CONFIG_NETFILTER_XT_TARGET_LOG=m -+CONFIG_NETFILTER_XT_TARGET_MARK=m -+CONFIG_NETFILTER_XT_TARGET_NFLOG=m -+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m -+CONFIG_NETFILTER_XT_TARGET_TEE=m -+CONFIG_NETFILTER_XT_TARGET_TPROXY=m -+CONFIG_NETFILTER_XT_TARGET_TRACE=m -+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m -+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m -+CONFIG_NETFILTER_XT_MATCH_BPF=m -+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m -+CONFIG_NETFILTER_XT_MATCH_COMMENT=m -+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m -+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -+CONFIG_NETFILTER_XT_MATCH_CPU=m -+CONFIG_NETFILTER_XT_MATCH_DCCP=m -+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m -+CONFIG_NETFILTER_XT_MATCH_DSCP=m -+CONFIG_NETFILTER_XT_MATCH_ESP=m -+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_HELPER=m -+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m -+CONFIG_NETFILTER_XT_MATCH_IPVS=m -+CONFIG_NETFILTER_XT_MATCH_LENGTH=m -+CONFIG_NETFILTER_XT_MATCH_LIMIT=m -+CONFIG_NETFILTER_XT_MATCH_MAC=m -+CONFIG_NETFILTER_XT_MATCH_MARK=m -+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -+CONFIG_NETFILTER_XT_MATCH_NFACCT=m -+CONFIG_NETFILTER_XT_MATCH_OSF=m -+CONFIG_NETFILTER_XT_MATCH_OWNER=m -+CONFIG_NETFILTER_XT_MATCH_POLICY=m -+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m -+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -+CONFIG_NETFILTER_XT_MATCH_QUOTA=m -+CONFIG_NETFILTER_XT_MATCH_RATEEST=m -+CONFIG_NETFILTER_XT_MATCH_REALM=m -+CONFIG_NETFILTER_XT_MATCH_RECENT=m -+CONFIG_NETFILTER_XT_MATCH_STATE=m -+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -+CONFIG_NETFILTER_XT_MATCH_STRING=m -+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -+CONFIG_NETFILTER_XT_MATCH_TIME=m -+CONFIG_NETFILTER_XT_MATCH_U32=m -+CONFIG_IP_SET=m -+CONFIG_IP_SET_BITMAP_IP=m -+CONFIG_IP_SET_BITMAP_IPMAC=m -+CONFIG_IP_SET_BITMAP_PORT=m -+CONFIG_IP_SET_HASH_IP=m -+CONFIG_IP_SET_HASH_IPPORT=m -+CONFIG_IP_SET_HASH_IPPORTIP=m -+CONFIG_IP_SET_HASH_IPPORTNET=m -+CONFIG_IP_SET_HASH_NET=m -+CONFIG_IP_SET_HASH_NETPORT=m -+CONFIG_IP_SET_HASH_NETIFACE=m -+CONFIG_IP_SET_LIST_SET=m -+CONFIG_IP_VS=m -+CONFIG_IP_VS_PROTO_TCP=y -+CONFIG_IP_VS_PROTO_UDP=y -+CONFIG_IP_VS_PROTO_ESP=y -+CONFIG_IP_VS_PROTO_AH=y -+CONFIG_IP_VS_PROTO_SCTP=y -+CONFIG_IP_VS_RR=m -+CONFIG_IP_VS_WRR=m -+CONFIG_IP_VS_LC=m -+CONFIG_IP_VS_WLC=m -+CONFIG_IP_VS_LBLC=m -+CONFIG_IP_VS_LBLCR=m -+CONFIG_IP_VS_DH=m -+CONFIG_IP_VS_SH=m -+CONFIG_IP_VS_SED=m -+CONFIG_IP_VS_NQ=m -+CONFIG_IP_VS_FTP=m -+CONFIG_IP_VS_PE_SIP=m -+CONFIG_IP_NF_IPTABLES=m -+CONFIG_IP_NF_MATCH_AH=m -+CONFIG_IP_NF_MATCH_ECN=m -+CONFIG_IP_NF_MATCH_RPFILTER=m -+CONFIG_IP_NF_MATCH_TTL=m -+CONFIG_IP_NF_FILTER=m -+CONFIG_IP_NF_TARGET_REJECT=m -+CONFIG_IP_NF_NAT=m -+CONFIG_IP_NF_TARGET_MASQUERADE=m -+CONFIG_IP_NF_TARGET_NETMAP=m -+CONFIG_IP_NF_TARGET_REDIRECT=m -+CONFIG_IP_NF_MANGLE=m -+CONFIG_IP_NF_TARGET_CLUSTERIP=m -+CONFIG_IP_NF_TARGET_ECN=m -+CONFIG_IP_NF_TARGET_TTL=m -+CONFIG_IP_NF_RAW=m -+CONFIG_IP_NF_ARPTABLES=m -+CONFIG_IP_NF_ARPFILTER=m -+CONFIG_IP_NF_ARP_MANGLE=m -+CONFIG_IP6_NF_IPTABLES=m -+CONFIG_IP6_NF_MATCH_AH=m -+CONFIG_IP6_NF_MATCH_EUI64=m -+CONFIG_IP6_NF_MATCH_FRAG=m -+CONFIG_IP6_NF_MATCH_OPTS=m -+CONFIG_IP6_NF_MATCH_HL=m -+CONFIG_IP6_NF_MATCH_IPV6HEADER=m -+CONFIG_IP6_NF_MATCH_MH=m -+CONFIG_IP6_NF_MATCH_RPFILTER=m -+CONFIG_IP6_NF_MATCH_RT=m -+CONFIG_IP6_NF_TARGET_HL=m -+CONFIG_IP6_NF_FILTER=m -+CONFIG_IP6_NF_TARGET_REJECT=m -+CONFIG_IP6_NF_MANGLE=m -+CONFIG_IP6_NF_RAW=m -+CONFIG_IP6_NF_NAT=m -+CONFIG_IP6_NF_TARGET_MASQUERADE=m -+CONFIG_IP6_NF_TARGET_NPT=m -+CONFIG_BRIDGE_NF_EBTABLES=m -+CONFIG_BRIDGE_EBT_BROUTE=m -+CONFIG_BRIDGE_EBT_T_FILTER=m -+CONFIG_BRIDGE_EBT_T_NAT=m -+CONFIG_BRIDGE_EBT_802_3=m -+CONFIG_BRIDGE_EBT_AMONG=m -+CONFIG_BRIDGE_EBT_ARP=m -+CONFIG_BRIDGE_EBT_IP=m -+CONFIG_BRIDGE_EBT_IP6=m -+CONFIG_BRIDGE_EBT_LIMIT=m -+CONFIG_BRIDGE_EBT_MARK=m -+CONFIG_BRIDGE_EBT_PKTTYPE=m -+CONFIG_BRIDGE_EBT_STP=m -+CONFIG_BRIDGE_EBT_VLAN=m -+CONFIG_BRIDGE_EBT_ARPREPLY=m -+CONFIG_BRIDGE_EBT_DNAT=m -+CONFIG_BRIDGE_EBT_MARK_T=m -+CONFIG_BRIDGE_EBT_REDIRECT=m -+CONFIG_BRIDGE_EBT_SNAT=m -+CONFIG_BRIDGE_EBT_LOG=m -+CONFIG_BRIDGE_EBT_NFLOG=m -+CONFIG_SCTP_COOKIE_HMAC_SHA1=y -+CONFIG_ATM=m -+CONFIG_L2TP=m -+CONFIG_L2TP_V3=y -+CONFIG_L2TP_IP=m -+CONFIG_L2TP_ETH=m -+CONFIG_BRIDGE=m -+CONFIG_VLAN_8021Q=m -+CONFIG_VLAN_8021Q_GVRP=y -+CONFIG_ATALK=m -+CONFIG_6LOWPAN=m -+CONFIG_IEEE802154=m -+CONFIG_IEEE802154_6LOWPAN=m -+CONFIG_MAC802154=m -+CONFIG_NET_SCHED=y -+CONFIG_NET_SCH_CBQ=m -+CONFIG_NET_SCH_HTB=m -+CONFIG_NET_SCH_HFSC=m -+CONFIG_NET_SCH_ATM=m -+CONFIG_NET_SCH_PRIO=m -+CONFIG_NET_SCH_MULTIQ=m -+CONFIG_NET_SCH_RED=m -+CONFIG_NET_SCH_SFB=m -+CONFIG_NET_SCH_SFQ=m -+CONFIG_NET_SCH_TEQL=m -+CONFIG_NET_SCH_TBF=m -+CONFIG_NET_SCH_GRED=m -+CONFIG_NET_SCH_DSMARK=m -+CONFIG_NET_SCH_NETEM=m -+CONFIG_NET_SCH_DRR=m -+CONFIG_NET_SCH_MQPRIO=m -+CONFIG_NET_SCH_CHOKE=m -+CONFIG_NET_SCH_QFQ=m -+CONFIG_NET_SCH_CODEL=m -+CONFIG_NET_SCH_FQ_CODEL=m -+CONFIG_NET_SCH_FQ=m -+CONFIG_NET_SCH_HHF=m -+CONFIG_NET_SCH_PIE=m -+CONFIG_NET_SCH_INGRESS=m -+CONFIG_NET_SCH_PLUG=m -+CONFIG_NET_CLS_BASIC=m -+CONFIG_NET_CLS_TCINDEX=m -+CONFIG_NET_CLS_ROUTE4=m -+CONFIG_NET_CLS_FW=m -+CONFIG_NET_CLS_U32=m -+CONFIG_CLS_U32_MARK=y -+CONFIG_NET_CLS_RSVP=m -+CONFIG_NET_CLS_RSVP6=m -+CONFIG_NET_CLS_FLOW=m -+CONFIG_NET_CLS_CGROUP=m -+CONFIG_NET_EMATCH=y -+CONFIG_NET_EMATCH_CMP=m -+CONFIG_NET_EMATCH_NBYTE=m -+CONFIG_NET_EMATCH_U32=m -+CONFIG_NET_EMATCH_META=m -+CONFIG_NET_EMATCH_TEXT=m -+CONFIG_NET_EMATCH_IPSET=m -+CONFIG_NET_CLS_ACT=y -+CONFIG_NET_ACT_POLICE=m -+CONFIG_NET_ACT_GACT=m -+CONFIG_GACT_PROB=y -+CONFIG_NET_ACT_MIRRED=m -+CONFIG_NET_ACT_IPT=m -+CONFIG_NET_ACT_NAT=m -+CONFIG_NET_ACT_PEDIT=m -+CONFIG_NET_ACT_SIMP=m -+CONFIG_NET_ACT_SKBEDIT=m -+CONFIG_NET_ACT_CSUM=m -+CONFIG_BATMAN_ADV=m -+CONFIG_OPENVSWITCH=m -+CONFIG_NET_PKTGEN=m -+CONFIG_HAMRADIO=y -+CONFIG_AX25=m -+CONFIG_NETROM=m -+CONFIG_ROSE=m -+CONFIG_MKISS=m -+CONFIG_6PACK=m -+CONFIG_BPQETHER=m -+CONFIG_BAYCOM_SER_FDX=m -+CONFIG_BAYCOM_SER_HDX=m -+CONFIG_YAM=m -+CONFIG_CAN=m -+CONFIG_CAN_VCAN=m -+CONFIG_CAN_SLCAN=m -+CONFIG_CAN_MCP251X=m -+CONFIG_CAN_GS_USB=m -+CONFIG_BT=m -+CONFIG_BT_RFCOMM=m -+CONFIG_BT_RFCOMM_TTY=y -+CONFIG_BT_BNEP=m -+CONFIG_BT_BNEP_MC_FILTER=y -+CONFIG_BT_BNEP_PROTO_FILTER=y -+CONFIG_BT_HIDP=m -+CONFIG_BT_6LOWPAN=m -+CONFIG_BT_HCIBTUSB=m -+CONFIG_BT_HCIUART=m -+CONFIG_BT_HCIUART_3WIRE=y -+CONFIG_BT_HCIUART_BCM=y -+CONFIG_BT_HCIBCM203X=m -+CONFIG_BT_HCIBPA10X=m -+CONFIG_BT_HCIBFUSB=m -+CONFIG_BT_HCIVHCI=m -+CONFIG_BT_MRVL=m -+CONFIG_BT_MRVL_SDIO=m -+CONFIG_BT_ATH3K=m -+CONFIG_BT_WILINK=m -+CONFIG_CFG80211=m -+CONFIG_MAC80211=m -+CONFIG_MAC80211_MESH=y -+CONFIG_WIMAX=m -+CONFIG_RFKILL=m -+CONFIG_RFKILL_INPUT=y -+CONFIG_NET_9P=m -+CONFIG_NFC=m -+CONFIG_DEVTMPFS=y -+CONFIG_DEVTMPFS_MOUNT=y -+CONFIG_DMA_CMA=y -+CONFIG_CMA_SIZE_MBYTES=5 -+CONFIG_MTD=m -+CONFIG_MTD_BLOCK=m -+CONFIG_MTD_M25P80=m -+CONFIG_MTD_BLOCK2MTD=m -+CONFIG_MTD_NAND=m -+CONFIG_MTD_SPI_NOR=m -+CONFIG_MTD_UBI=m -+CONFIG_OF_CONFIGFS=y -+CONFIG_ZRAM=m -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_CRYPTOLOOP=m -+CONFIG_BLK_DEV_DRBD=m -+CONFIG_BLK_DEV_NBD=m -+CONFIG_BLK_DEV_RAM=y -+CONFIG_CDROM_PKTCDVD=m -+CONFIG_ATA_OVER_ETH=m -+CONFIG_EEPROM_AT24=m -+CONFIG_TI_ST=m -+CONFIG_SCSI=y -+# CONFIG_SCSI_PROC_FS is not set -+CONFIG_BLK_DEV_SD=y -+CONFIG_CHR_DEV_ST=m -+CONFIG_CHR_DEV_OSST=m -+CONFIG_BLK_DEV_SR=m -+CONFIG_CHR_DEV_SG=m -+CONFIG_SCSI_ISCSI_ATTRS=y -+CONFIG_ISCSI_TCP=m -+CONFIG_ISCSI_BOOT_SYSFS=m -+CONFIG_MD=y -+CONFIG_MD_LINEAR=m -+CONFIG_BLK_DEV_DM=m -+CONFIG_DM_CRYPT=m -+CONFIG_DM_SNAPSHOT=m -+CONFIG_DM_THIN_PROVISIONING=m -+CONFIG_DM_CACHE=m -+CONFIG_DM_MIRROR=m -+CONFIG_DM_LOG_USERSPACE=m -+CONFIG_DM_RAID=m -+CONFIG_DM_ZERO=m -+CONFIG_DM_DELAY=m -+CONFIG_NETDEVICES=y -+CONFIG_BONDING=m -+CONFIG_DUMMY=m -+CONFIG_IFB=m -+CONFIG_MACVLAN=m -+CONFIG_IPVLAN=m -+CONFIG_VXLAN=m -+CONFIG_NETCONSOLE=m -+CONFIG_TUN=m -+CONFIG_VETH=m -+CONFIG_BCMGENET=y -+CONFIG_ENC28J60=m -+CONFIG_QCA7000_SPI=m -+CONFIG_MDIO_BITBANG=m -+CONFIG_BROADCOM_PHY=y -+CONFIG_PPP=m -+CONFIG_PPP_BSDCOMP=m -+CONFIG_PPP_DEFLATE=m -+CONFIG_PPP_FILTER=y -+CONFIG_PPP_MPPE=m -+CONFIG_PPP_MULTILINK=y -+CONFIG_PPPOATM=m -+CONFIG_PPPOE=m -+CONFIG_PPPOL2TP=m -+CONFIG_PPP_ASYNC=m -+CONFIG_PPP_SYNC_TTY=m -+CONFIG_SLIP=m -+CONFIG_SLIP_COMPRESSED=y -+CONFIG_SLIP_SMART=y -+CONFIG_USB_CATC=m -+CONFIG_USB_KAWETH=m -+CONFIG_USB_PEGASUS=m -+CONFIG_USB_RTL8150=m -+CONFIG_USB_RTL8152=y -+CONFIG_USB_LAN78XX=y -+CONFIG_USB_USBNET=y -+CONFIG_USB_NET_AX88179_178A=m -+CONFIG_USB_NET_CDCETHER=m -+CONFIG_USB_NET_CDC_EEM=m -+CONFIG_USB_NET_CDC_NCM=m -+CONFIG_USB_NET_HUAWEI_CDC_NCM=m -+CONFIG_USB_NET_CDC_MBIM=m -+CONFIG_USB_NET_DM9601=m -+CONFIG_USB_NET_SR9700=m -+CONFIG_USB_NET_SR9800=m -+CONFIG_USB_NET_SMSC75XX=m -+CONFIG_USB_NET_SMSC95XX=y -+CONFIG_USB_NET_GL620A=m -+CONFIG_USB_NET_NET1080=m -+CONFIG_USB_NET_PLUSB=m -+CONFIG_USB_NET_MCS7830=m -+CONFIG_USB_NET_CDC_SUBSET=m -+CONFIG_USB_ALI_M5632=y -+CONFIG_USB_AN2720=y -+CONFIG_USB_EPSON2888=y -+CONFIG_USB_KC2190=y -+CONFIG_USB_NET_ZAURUS=m -+CONFIG_USB_NET_CX82310_ETH=m -+CONFIG_USB_NET_KALMIA=m -+CONFIG_USB_NET_QMI_WWAN=m -+CONFIG_USB_HSO=m -+CONFIG_USB_NET_INT51X1=m -+CONFIG_USB_IPHETH=m -+CONFIG_USB_SIERRA_NET=m -+CONFIG_USB_VL600=m -+CONFIG_ATH9K=m -+CONFIG_ATH9K_HTC=m -+CONFIG_CARL9170=m -+CONFIG_ATH6KL=m -+CONFIG_ATH6KL_USB=m -+CONFIG_AR5523=m -+CONFIG_AT76C50X_USB=m -+CONFIG_B43=m -+# CONFIG_B43_PHY_N is not set -+CONFIG_B43LEGACY=m -+CONFIG_BRCMFMAC=m -+CONFIG_BRCMFMAC_USB=y -+CONFIG_BRCMDBG=y -+CONFIG_HOSTAP=m -+CONFIG_P54_COMMON=m -+CONFIG_P54_USB=m -+CONFIG_LIBERTAS=m -+CONFIG_LIBERTAS_USB=m -+CONFIG_LIBERTAS_SDIO=m -+CONFIG_LIBERTAS_THINFIRM=m -+CONFIG_LIBERTAS_THINFIRM_USB=m -+CONFIG_MWIFIEX=m -+CONFIG_MWIFIEX_SDIO=m -+CONFIG_MT7601U=m -+CONFIG_RT2X00=m -+CONFIG_RT2500USB=m -+CONFIG_RT73USB=m -+CONFIG_RT2800USB=m -+CONFIG_RT2800USB_RT3573=y -+CONFIG_RT2800USB_RT53XX=y -+CONFIG_RT2800USB_RT55XX=y -+CONFIG_RT2800USB_UNKNOWN=y -+CONFIG_RTL8187=m -+CONFIG_RTL8192CU=m -+CONFIG_RTL8XXXU=m -+CONFIG_USB_ZD1201=m -+CONFIG_ZD1211RW=m -+CONFIG_MAC80211_HWSIM=m -+CONFIG_USB_NET_RNDIS_WLAN=m -+CONFIG_WIMAX_I2400M_USB=m -+CONFIG_IEEE802154_AT86RF230=m -+CONFIG_IEEE802154_MRF24J40=m -+CONFIG_IEEE802154_CC2520=m -+CONFIG_INPUT_MOUSEDEV=y -+CONFIG_INPUT_JOYDEV=m -+CONFIG_INPUT_EVDEV=m -+# CONFIG_KEYBOARD_ATKBD is not set -+CONFIG_KEYBOARD_GPIO=m -+CONFIG_KEYBOARD_MATRIX=m -+# CONFIG_INPUT_MOUSE is not set -+CONFIG_INPUT_JOYSTICK=y -+CONFIG_JOYSTICK_IFORCE=m -+CONFIG_JOYSTICK_IFORCE_USB=y -+CONFIG_JOYSTICK_XPAD=m -+CONFIG_JOYSTICK_XPAD_FF=y -+CONFIG_JOYSTICK_XPAD_LEDS=y -+CONFIG_JOYSTICK_PSXPAD_SPI=m -+CONFIG_JOYSTICK_PSXPAD_SPI_FF=y -+CONFIG_JOYSTICK_RPISENSE=m -+CONFIG_INPUT_TOUCHSCREEN=y -+CONFIG_TOUCHSCREEN_ADS7846=m -+CONFIG_TOUCHSCREEN_EGALAX=m -+CONFIG_TOUCHSCREEN_EXC3000=m -+CONFIG_TOUCHSCREEN_GOODIX=m -+CONFIG_TOUCHSCREEN_EDT_FT5X06=m -+CONFIG_TOUCHSCREEN_RPI_FT5406=m -+CONFIG_TOUCHSCREEN_USB_COMPOSITE=m -+CONFIG_TOUCHSCREEN_STMPE=m -+CONFIG_INPUT_MISC=y -+CONFIG_INPUT_AD714X=m -+CONFIG_INPUT_ATI_REMOTE2=m -+CONFIG_INPUT_KEYSPAN_REMOTE=m -+CONFIG_INPUT_POWERMATE=m -+CONFIG_INPUT_YEALINK=m -+CONFIG_INPUT_CM109=m -+CONFIG_INPUT_UINPUT=m -+CONFIG_INPUT_GPIO_ROTARY_ENCODER=m -+CONFIG_INPUT_ADXL34X=m -+CONFIG_INPUT_CMA3000=m -+CONFIG_SERIO=m -+CONFIG_SERIO_RAW=m -+CONFIG_GAMEPORT=m -+CONFIG_GAMEPORT_NS558=m -+CONFIG_GAMEPORT_L4=m -+CONFIG_BRCM_CHAR_DRIVERS=y -+CONFIG_BCM_VCIO=y -+CONFIG_BCM_VC_SM=y -+CONFIG_BCM2835_DEVGPIOMEM=y -+CONFIG_ARGON_MEM=m -+# CONFIG_LEGACY_PTYS is not set -+CONFIG_SERIAL_8250=y -+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -+CONFIG_SERIAL_8250_CONSOLE=y -+# CONFIG_SERIAL_8250_DMA is not set -+CONFIG_SERIAL_8250_NR_UARTS=1 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=0 -+CONFIG_SERIAL_8250_EXTENDED=y -+CONFIG_SERIAL_8250_SHARE_IRQ=y -+CONFIG_SERIAL_8250_BCM2835AUX=y -+CONFIG_SERIAL_OF_PLATFORM=y -+CONFIG_SERIAL_AMBA_PL011=y -+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+CONFIG_SERIAL_SC16IS7XX=m -+CONFIG_SERIAL_SC16IS7XX_SPI=y -+CONFIG_SERIAL_DEV_BUS=m -+CONFIG_TTY_PRINTK=y -+CONFIG_HW_RANDOM=y -+CONFIG_RAW_DRIVER=y -+CONFIG_I2C=y -+CONFIG_I2C_CHARDEV=m -+CONFIG_I2C_BCM2708=m -+CONFIG_I2C_BCM2835=m -+CONFIG_I2C_GPIO=m -+CONFIG_I2C_ROBOTFUZZ_OSIF=m -+CONFIG_I2C_TINY_USB=m -+CONFIG_SPI=y -+CONFIG_SPI_BCM2835=m -+CONFIG_SPI_BCM2835AUX=m -+CONFIG_SPI_SPIDEV=m -+CONFIG_SPI_SLAVE=y -+CONFIG_PPS=m -+CONFIG_PPS_CLIENT_LDISC=m -+CONFIG_PPS_CLIENT_GPIO=m -+CONFIG_PINCTRL_MCP23S08=m -+CONFIG_GPIO_BCM_VIRT=y -+CONFIG_GPIO_MOCKUP=m -+CONFIG_GPIO_PCF857X=m -+CONFIG_GPIO_ARIZONA=m -+CONFIG_GPIO_STMPE=y -+CONFIG_W1=m -+CONFIG_W1_MASTER_DS2490=m -+CONFIG_W1_MASTER_DS2482=m -+CONFIG_W1_MASTER_DS1WM=m -+CONFIG_W1_MASTER_GPIO=m -+CONFIG_W1_SLAVE_THERM=m -+CONFIG_W1_SLAVE_SMEM=m -+CONFIG_W1_SLAVE_DS2408=m -+CONFIG_W1_SLAVE_DS2413=m -+CONFIG_W1_SLAVE_DS2406=m -+CONFIG_W1_SLAVE_DS2423=m -+CONFIG_W1_SLAVE_DS2431=m -+CONFIG_W1_SLAVE_DS2433=m -+CONFIG_W1_SLAVE_DS2438=m -+CONFIG_W1_SLAVE_DS2780=m -+CONFIG_W1_SLAVE_DS2781=m -+CONFIG_W1_SLAVE_DS28E04=m -+CONFIG_POWER_RESET=y -+CONFIG_POWER_RESET_GPIO=y -+CONFIG_BATTERY_DS2760=m -+CONFIG_BATTERY_GAUGE_LTC2941=m -+CONFIG_HWMON=m -+CONFIG_SENSORS_DS1621=m -+CONFIG_SENSORS_JC42=m -+CONFIG_SENSORS_LM75=m -+CONFIG_SENSORS_RPI_POE_FAN=m -+CONFIG_SENSORS_SHT21=m -+CONFIG_SENSORS_SHT3x=m -+CONFIG_SENSORS_SHTC1=m -+CONFIG_SENSORS_ADS1015=m -+CONFIG_SENSORS_INA2XX=m -+CONFIG_SENSORS_TMP102=m -+CONFIG_THERMAL=y -+CONFIG_BCM2835_THERMAL=y -+CONFIG_BRCMSTB_THERMAL=y -+CONFIG_WATCHDOG=y -+CONFIG_GPIO_WATCHDOG=m -+CONFIG_BCM2835_WDT=y -+CONFIG_MFD_STMPE=y -+CONFIG_STMPE_SPI=y -+CONFIG_MFD_ARIZONA_I2C=m -+CONFIG_MFD_ARIZONA_SPI=m -+CONFIG_MFD_WM5102=y -+CONFIG_REGULATOR=y -+CONFIG_REGULATOR_FIXED_VOLTAGE=m -+CONFIG_REGULATOR_ARIZONA_LDO1=m -+CONFIG_REGULATOR_ARIZONA_MICSUPP=m -+CONFIG_REGULATOR_GPIO=y -+CONFIG_MEDIA_SUPPORT=m -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+CONFIG_MEDIA_ANALOG_TV_SUPPORT=y -+CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y -+CONFIG_MEDIA_RADIO_SUPPORT=y -+CONFIG_MEDIA_CONTROLLER=y -+CONFIG_VIDEO_V4L2_SUBDEV_API=y -+CONFIG_MEDIA_USB_SUPPORT=y -+CONFIG_USB_VIDEO_CLASS=m -+CONFIG_USB_M5602=m -+CONFIG_USB_STV06XX=m -+CONFIG_USB_GL860=m -+CONFIG_USB_GSPCA_BENQ=m -+CONFIG_USB_GSPCA_CONEX=m -+CONFIG_USB_GSPCA_CPIA1=m -+CONFIG_USB_GSPCA_DTCS033=m -+CONFIG_USB_GSPCA_ETOMS=m -+CONFIG_USB_GSPCA_FINEPIX=m -+CONFIG_USB_GSPCA_JEILINJ=m -+CONFIG_USB_GSPCA_JL2005BCD=m -+CONFIG_USB_GSPCA_KINECT=m -+CONFIG_USB_GSPCA_KONICA=m -+CONFIG_USB_GSPCA_MARS=m -+CONFIG_USB_GSPCA_MR97310A=m -+CONFIG_USB_GSPCA_NW80X=m -+CONFIG_USB_GSPCA_OV519=m -+CONFIG_USB_GSPCA_OV534=m -+CONFIG_USB_GSPCA_OV534_9=m -+CONFIG_USB_GSPCA_PAC207=m -+CONFIG_USB_GSPCA_PAC7302=m -+CONFIG_USB_GSPCA_PAC7311=m -+CONFIG_USB_GSPCA_SE401=m -+CONFIG_USB_GSPCA_SN9C2028=m -+CONFIG_USB_GSPCA_SN9C20X=m -+CONFIG_USB_GSPCA_SONIXB=m -+CONFIG_USB_GSPCA_SONIXJ=m -+CONFIG_USB_GSPCA_SPCA500=m -+CONFIG_USB_GSPCA_SPCA501=m -+CONFIG_USB_GSPCA_SPCA505=m -+CONFIG_USB_GSPCA_SPCA506=m -+CONFIG_USB_GSPCA_SPCA508=m -+CONFIG_USB_GSPCA_SPCA561=m -+CONFIG_USB_GSPCA_SPCA1528=m -+CONFIG_USB_GSPCA_SQ905=m -+CONFIG_USB_GSPCA_SQ905C=m -+CONFIG_USB_GSPCA_SQ930X=m -+CONFIG_USB_GSPCA_STK014=m -+CONFIG_USB_GSPCA_STK1135=m -+CONFIG_USB_GSPCA_STV0680=m -+CONFIG_USB_GSPCA_SUNPLUS=m -+CONFIG_USB_GSPCA_T613=m -+CONFIG_USB_GSPCA_TOPRO=m -+CONFIG_USB_GSPCA_TV8532=m -+CONFIG_USB_GSPCA_VC032X=m -+CONFIG_USB_GSPCA_VICAM=m -+CONFIG_USB_GSPCA_XIRLINK_CIT=m -+CONFIG_USB_GSPCA_ZC3XX=m -+CONFIG_USB_PWC=m -+CONFIG_VIDEO_CPIA2=m -+CONFIG_USB_ZR364XX=m -+CONFIG_USB_STKWEBCAM=m -+CONFIG_USB_S2255=m -+CONFIG_VIDEO_USBTV=m -+CONFIG_VIDEO_PVRUSB2=m -+CONFIG_VIDEO_HDPVR=m -+CONFIG_VIDEO_USBVISION=m -+CONFIG_VIDEO_STK1160_COMMON=m -+CONFIG_VIDEO_GO7007=m -+CONFIG_VIDEO_GO7007_USB=m -+CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m -+CONFIG_VIDEO_AU0828=m -+CONFIG_DVB_USB_V2=m -+CONFIG_DVB_USB_AF9035=m -+CONFIG_DVB_USB_ANYSEE=m -+CONFIG_DVB_USB_AU6610=m -+CONFIG_DVB_USB_AZ6007=m -+CONFIG_DVB_USB_CE6230=m -+CONFIG_DVB_USB_EC168=m -+CONFIG_DVB_USB_GL861=m -+CONFIG_DVB_USB_MXL111SF=m -+CONFIG_DVB_USB_DVBSKY=m -+CONFIG_SMS_USB_DRV=m -+CONFIG_DVB_B2C2_FLEXCOP_USB=m -+CONFIG_DVB_AS102=m -+CONFIG_VIDEO_EM28XX=m -+CONFIG_VIDEO_EM28XX_V4L2=m -+CONFIG_VIDEO_EM28XX_ALSA=m -+CONFIG_VIDEO_EM28XX_DVB=m -+CONFIG_V4L_PLATFORM_DRIVERS=y -+CONFIG_VIDEO_BCM2835_UNICAM=m -+CONFIG_RADIO_SI470X=m -+CONFIG_USB_SI470X=m -+CONFIG_I2C_SI470X=m -+CONFIG_RADIO_SI4713=m -+CONFIG_I2C_SI4713=m -+CONFIG_USB_MR800=m -+CONFIG_USB_DSBR=m -+CONFIG_RADIO_SHARK=m -+CONFIG_RADIO_SHARK2=m -+CONFIG_USB_KEENE=m -+CONFIG_USB_MA901=m -+CONFIG_RADIO_TEA5764=m -+CONFIG_RADIO_SAA7706H=m -+CONFIG_RADIO_TEF6862=m -+CONFIG_RADIO_WL1273=m -+CONFIG_RADIO_WL128X=m -+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set -+CONFIG_VIDEO_UDA1342=m -+CONFIG_VIDEO_SONY_BTF_MPX=m -+CONFIG_VIDEO_ADV7180=m -+CONFIG_VIDEO_TC358743=m -+CONFIG_VIDEO_TVP5150=m -+CONFIG_VIDEO_TW2804=m -+CONFIG_VIDEO_TW9903=m -+CONFIG_VIDEO_TW9906=m -+CONFIG_VIDEO_OV5647=m -+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_V3D=m -+CONFIG_DRM_VC4=m -+CONFIG_DRM_TINYDRM=m -+CONFIG_TINYDRM_MI0283QT=m -+CONFIG_TINYDRM_REPAPER=m -+CONFIG_FB=y -+CONFIG_FB_BCM2708=y -+CONFIG_FB_UDL=m -+CONFIG_FB_SIMPLE=y -+CONFIG_FB_SSD1307=m -+CONFIG_FB_RPISENSE=m -+# CONFIG_BACKLIGHT_GENERIC is not set -+CONFIG_BACKLIGHT_RPI=m -+CONFIG_BACKLIGHT_GPIO=m -+CONFIG_FRAMEBUFFER_CONSOLE=y -+CONFIG_LOGO=y -+# CONFIG_LOGO_LINUX_MONO is not set -+# CONFIG_LOGO_LINUX_VGA16 is not set -+CONFIG_SOUND=y -+CONFIG_SND=m -+CONFIG_SND_HRTIMER=m -+CONFIG_SND_SEQUENCER=m -+CONFIG_SND_SEQ_DUMMY=m -+CONFIG_SND_DUMMY=m -+CONFIG_SND_ALOOP=m -+CONFIG_SND_VIRMIDI=m -+CONFIG_SND_MTPAV=m -+CONFIG_SND_SERIAL_U16550=m -+CONFIG_SND_MPU401=m -+CONFIG_SND_USB_AUDIO=m -+CONFIG_SND_USB_UA101=m -+CONFIG_SND_USB_CAIAQ=m -+CONFIG_SND_USB_CAIAQ_INPUT=y -+CONFIG_SND_USB_6FIRE=m -+CONFIG_SND_USB_HIFACE=m -+CONFIG_SND_SOC=m -+CONFIG_SND_BCM2835_SOC_I2S=m -+CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m -+CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=m -+CONFIG_SND_BCM2708_SOC_RPI_DAC=m -+CONFIG_SND_BCM2708_SOC_RPI_PROTO=m -+CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m -+CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m -+CONFIG_SND_BCM2708_SOC_IQAUDIO_CODEC=m -+CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -+CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m -+CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m -+CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m -+CONFIG_SND_AUDIOINJECTOR_OCTO_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_BCM2708_SOC_ALLO_PIANO_DAC_PLUS=m -+CONFIG_SND_BCM2708_SOC_ALLO_BOSS_DAC=m -+CONFIG_SND_BCM2708_SOC_ALLO_DIGIONE=m -+CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC=m -+CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m -+CONFIG_SND_PISOUND=m -+CONFIG_SND_SOC_ADAU1701=m -+CONFIG_SND_SOC_ADAU7002=m -+CONFIG_SND_SOC_AK4554=m -+CONFIG_SND_SOC_CS4271_I2C=m -+CONFIG_SND_SOC_SPDIF=m -+CONFIG_SND_SOC_WM8804_I2C=m -+CONFIG_SND_SIMPLE_CARD=m -+CONFIG_HID_BATTERY_STRENGTH=y -+CONFIG_HIDRAW=y -+CONFIG_UHID=m -+CONFIG_HID_A4TECH=m -+CONFIG_HID_ACRUX=m -+CONFIG_HID_APPLE=m -+CONFIG_HID_ASUS=m -+CONFIG_HID_BELKIN=m -+CONFIG_HID_BETOP_FF=m -+CONFIG_HID_CHERRY=m -+CONFIG_HID_CHICONY=m -+CONFIG_HID_CYPRESS=m -+CONFIG_HID_DRAGONRISE=m -+CONFIG_HID_EMS_FF=m -+CONFIG_HID_ELECOM=m -+CONFIG_HID_ELO=m -+CONFIG_HID_EZKEY=m -+CONFIG_HID_GEMBIRD=m -+CONFIG_HID_HOLTEK=m -+CONFIG_HID_KEYTOUCH=m -+CONFIG_HID_KYE=m -+CONFIG_HID_UCLOGIC=m -+CONFIG_HID_WALTOP=m -+CONFIG_HID_GYRATION=m -+CONFIG_HID_TWINHAN=m -+CONFIG_HID_KENSINGTON=m -+CONFIG_HID_LCPOWER=m -+CONFIG_HID_LOGITECH=m -+CONFIG_HID_LOGITECH_DJ=m -+CONFIG_LOGITECH_FF=y -+CONFIG_LOGIRUMBLEPAD2_FF=y -+CONFIG_LOGIG940_FF=y -+CONFIG_HID_MAGICMOUSE=m -+CONFIG_HID_MICROSOFT=m -+CONFIG_HID_MONTEREY=m -+CONFIG_HID_MULTITOUCH=m -+CONFIG_HID_NTRIG=m -+CONFIG_HID_ORTEK=m -+CONFIG_HID_PANTHERLORD=m -+CONFIG_HID_PETALYNX=m -+CONFIG_HID_PICOLCD=m -+CONFIG_HID_ROCCAT=m -+CONFIG_HID_SAMSUNG=m -+CONFIG_HID_SONY=m -+CONFIG_SONY_FF=y -+CONFIG_HID_SPEEDLINK=m -+CONFIG_HID_SUNPLUS=m -+CONFIG_HID_GREENASIA=m -+CONFIG_HID_SMARTJOYPLUS=m -+CONFIG_HID_TOPSEED=m -+CONFIG_HID_THINGM=m -+CONFIG_HID_THRUSTMASTER=m -+CONFIG_HID_WACOM=m -+CONFIG_HID_WIIMOTE=m -+CONFIG_HID_XINMO=m -+CONFIG_HID_ZEROPLUS=m -+CONFIG_HID_ZYDACRON=m -+CONFIG_HID_PID=y -+CONFIG_USB_HIDDEV=y -+CONFIG_USB=y -+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -+CONFIG_USB_MON=m -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_DWCOTG=y -+CONFIG_USB_PRINTER=m -+CONFIG_USB_STORAGE=y -+CONFIG_USB_STORAGE_REALTEK=m -+CONFIG_USB_STORAGE_DATAFAB=m -+CONFIG_USB_STORAGE_FREECOM=m -+CONFIG_USB_STORAGE_ISD200=m -+CONFIG_USB_STORAGE_USBAT=m -+CONFIG_USB_STORAGE_SDDR09=m -+CONFIG_USB_STORAGE_SDDR55=m -+CONFIG_USB_STORAGE_JUMPSHOT=m -+CONFIG_USB_STORAGE_ALAUDA=m -+CONFIG_USB_STORAGE_ONETOUCH=m -+CONFIG_USB_STORAGE_KARMA=m -+CONFIG_USB_STORAGE_CYPRESS_ATACB=m -+CONFIG_USB_STORAGE_ENE_UB6250=m -+CONFIG_USB_UAS=y -+CONFIG_USB_MDC800=m -+CONFIG_USB_MICROTEK=m -+CONFIG_USBIP_CORE=m -+CONFIG_USBIP_VHCI_HCD=m -+CONFIG_USBIP_HOST=m -+CONFIG_USB_DWC2=m -+CONFIG_USB_SERIAL=m -+CONFIG_USB_SERIAL_GENERIC=y -+CONFIG_USB_SERIAL_AIRCABLE=m -+CONFIG_USB_SERIAL_ARK3116=m -+CONFIG_USB_SERIAL_BELKIN=m -+CONFIG_USB_SERIAL_CH341=m -+CONFIG_USB_SERIAL_WHITEHEAT=m -+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m -+CONFIG_USB_SERIAL_CP210X=m -+CONFIG_USB_SERIAL_CYPRESS_M8=m -+CONFIG_USB_SERIAL_EMPEG=m -+CONFIG_USB_SERIAL_FTDI_SIO=m -+CONFIG_USB_SERIAL_VISOR=m -+CONFIG_USB_SERIAL_IPAQ=m -+CONFIG_USB_SERIAL_IR=m -+CONFIG_USB_SERIAL_EDGEPORT=m -+CONFIG_USB_SERIAL_EDGEPORT_TI=m -+CONFIG_USB_SERIAL_F81232=m -+CONFIG_USB_SERIAL_GARMIN=m -+CONFIG_USB_SERIAL_IPW=m -+CONFIG_USB_SERIAL_IUU=m -+CONFIG_USB_SERIAL_KEYSPAN_PDA=m -+CONFIG_USB_SERIAL_KEYSPAN=m -+CONFIG_USB_SERIAL_KLSI=m -+CONFIG_USB_SERIAL_KOBIL_SCT=m -+CONFIG_USB_SERIAL_MCT_U232=m -+CONFIG_USB_SERIAL_METRO=m -+CONFIG_USB_SERIAL_MOS7720=m -+CONFIG_USB_SERIAL_MOS7840=m -+CONFIG_USB_SERIAL_NAVMAN=m -+CONFIG_USB_SERIAL_PL2303=m -+CONFIG_USB_SERIAL_OTI6858=m -+CONFIG_USB_SERIAL_QCAUX=m -+CONFIG_USB_SERIAL_QUALCOMM=m -+CONFIG_USB_SERIAL_SPCP8X5=m -+CONFIG_USB_SERIAL_SAFE=m -+CONFIG_USB_SERIAL_SIERRAWIRELESS=m -+CONFIG_USB_SERIAL_SYMBOL=m -+CONFIG_USB_SERIAL_TI=m -+CONFIG_USB_SERIAL_CYBERJACK=m -+CONFIG_USB_SERIAL_XIRCOM=m -+CONFIG_USB_SERIAL_OPTION=m -+CONFIG_USB_SERIAL_OMNINET=m -+CONFIG_USB_SERIAL_OPTICON=m -+CONFIG_USB_SERIAL_XSENS_MT=m -+CONFIG_USB_SERIAL_WISHBONE=m -+CONFIG_USB_SERIAL_SSU100=m -+CONFIG_USB_SERIAL_QT2=m -+CONFIG_USB_SERIAL_DEBUG=m -+CONFIG_USB_EMI62=m -+CONFIG_USB_EMI26=m -+CONFIG_USB_ADUTUX=m -+CONFIG_USB_SEVSEG=m -+CONFIG_USB_RIO500=m -+CONFIG_USB_LEGOTOWER=m -+CONFIG_USB_LCD=m -+CONFIG_USB_CYPRESS_CY7C63=m -+CONFIG_USB_CYTHERM=m -+CONFIG_USB_IDMOUSE=m -+CONFIG_USB_FTDI_ELAN=m -+CONFIG_USB_APPLEDISPLAY=m -+CONFIG_USB_LD=m -+CONFIG_USB_TRANCEVIBRATOR=m -+CONFIG_USB_IOWARRIOR=m -+CONFIG_USB_TEST=m -+CONFIG_USB_ISIGHTFW=m -+CONFIG_USB_YUREX=m -+CONFIG_USB_ATM=m -+CONFIG_USB_SPEEDTOUCH=m -+CONFIG_USB_CXACRU=m -+CONFIG_USB_UEAGLEATM=m -+CONFIG_USB_XUSBATM=m -+CONFIG_USB_GADGET=m -+CONFIG_USB_CONFIGFS=m -+CONFIG_USB_CONFIGFS_SERIAL=y -+CONFIG_USB_CONFIGFS_ACM=y -+CONFIG_USB_CONFIGFS_OBEX=y -+CONFIG_USB_CONFIGFS_NCM=y -+CONFIG_USB_CONFIGFS_ECM=y -+CONFIG_USB_CONFIGFS_ECM_SUBSET=y -+CONFIG_USB_CONFIGFS_RNDIS=y -+CONFIG_USB_CONFIGFS_EEM=y -+CONFIG_USB_CONFIGFS_MASS_STORAGE=y -+CONFIG_USB_CONFIGFS_F_LB_SS=y -+CONFIG_USB_CONFIGFS_F_FS=y -+CONFIG_USB_CONFIGFS_F_UAC1=y -+CONFIG_USB_CONFIGFS_F_UAC2=y -+CONFIG_USB_CONFIGFS_F_MIDI=y -+CONFIG_USB_CONFIGFS_F_HID=y -+CONFIG_USB_CONFIGFS_F_UVC=y -+CONFIG_USB_CONFIGFS_F_PRINTER=y -+CONFIG_USB_ZERO=m -+CONFIG_USB_AUDIO=m -+CONFIG_USB_ETH=m -+CONFIG_USB_GADGETFS=m -+CONFIG_USB_MASS_STORAGE=m -+CONFIG_USB_G_SERIAL=m -+CONFIG_USB_MIDI_GADGET=m -+CONFIG_USB_G_PRINTER=m -+CONFIG_USB_CDC_COMPOSITE=m -+CONFIG_USB_G_ACM_MS=m -+CONFIG_USB_G_MULTI=m -+CONFIG_USB_G_HID=m -+CONFIG_USB_G_WEBCAM=m -+CONFIG_MMC=y -+CONFIG_MMC_BLOCK_MINORS=32 -+CONFIG_MMC_BCM2835_MMC=y -+CONFIG_MMC_BCM2835_DMA=y -+CONFIG_MMC_BCM2835_SDHOST=y -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_PLTFM=y -+CONFIG_MMC_SDHCI_IPROC=y -+CONFIG_MMC_SPI=m -+CONFIG_LEDS_CLASS=y -+CONFIG_LEDS_GPIO=y -+CONFIG_LEDS_TRIGGER_TIMER=y -+CONFIG_LEDS_TRIGGER_ONESHOT=y -+CONFIG_LEDS_TRIGGER_HEARTBEAT=y -+CONFIG_LEDS_TRIGGER_BACKLIGHT=y -+CONFIG_LEDS_TRIGGER_CPU=y -+CONFIG_LEDS_TRIGGER_GPIO=y -+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y -+CONFIG_LEDS_TRIGGER_TRANSIENT=m -+CONFIG_LEDS_TRIGGER_CAMERA=m -+CONFIG_LEDS_TRIGGER_INPUT=y -+CONFIG_LEDS_TRIGGER_PANIC=y -+CONFIG_RTC_CLASS=y -+# CONFIG_RTC_HCTOSYS is not set -+CONFIG_RTC_DRV_ABX80X=m -+CONFIG_RTC_DRV_DS1307=m -+CONFIG_RTC_DRV_DS1374=m -+CONFIG_RTC_DRV_DS1672=m -+CONFIG_RTC_DRV_MAX6900=m -+CONFIG_RTC_DRV_RS5C372=m -+CONFIG_RTC_DRV_ISL1208=m -+CONFIG_RTC_DRV_ISL12022=m -+CONFIG_RTC_DRV_X1205=m -+CONFIG_RTC_DRV_PCF8523=m -+CONFIG_RTC_DRV_PCF8563=m -+CONFIG_RTC_DRV_PCF8583=m -+CONFIG_RTC_DRV_M41T80=m -+CONFIG_RTC_DRV_BQ32K=m -+CONFIG_RTC_DRV_S35390A=m -+CONFIG_RTC_DRV_FM3130=m -+CONFIG_RTC_DRV_RX8581=m -+CONFIG_RTC_DRV_RX8025=m -+CONFIG_RTC_DRV_EM3027=m -+CONFIG_RTC_DRV_M41T93=m -+CONFIG_RTC_DRV_M41T94=m -+CONFIG_RTC_DRV_DS1302=m -+CONFIG_RTC_DRV_DS1305=m -+CONFIG_RTC_DRV_DS1390=m -+CONFIG_RTC_DRV_R9701=m -+CONFIG_RTC_DRV_RX4581=m -+CONFIG_RTC_DRV_RS5C348=m -+CONFIG_RTC_DRV_MAX6902=m -+CONFIG_RTC_DRV_PCF2123=m -+CONFIG_RTC_DRV_DS3232=m -+CONFIG_RTC_DRV_PCF2127=m -+CONFIG_RTC_DRV_RV3029C2=m -+CONFIG_DMADEVICES=y -+CONFIG_DMA_BCM2835=y -+CONFIG_DMA_BCM2708=y -+CONFIG_UIO=m -+CONFIG_UIO_PDRV_GENIRQ=m -+CONFIG_STAGING=y -+CONFIG_PRISM2_USB=m -+CONFIG_R8712U=m -+CONFIG_R8188EU=m -+CONFIG_VT6656=m -+CONFIG_SPEAKUP=m -+CONFIG_SPEAKUP_SYNTH_SOFT=m -+CONFIG_STAGING_MEDIA=y -+CONFIG_FB_TFT=m -+CONFIG_FB_TFT_AGM1264K_FL=m -+CONFIG_FB_TFT_BD663474=m -+CONFIG_FB_TFT_HX8340BN=m -+CONFIG_FB_TFT_HX8347D=m -+CONFIG_FB_TFT_HX8353D=m -+CONFIG_FB_TFT_HX8357D=m -+CONFIG_FB_TFT_ILI9163=m -+CONFIG_FB_TFT_ILI9320=m -+CONFIG_FB_TFT_ILI9325=m -+CONFIG_FB_TFT_ILI9340=m -+CONFIG_FB_TFT_ILI9341=m -+CONFIG_FB_TFT_ILI9481=m -+CONFIG_FB_TFT_ILI9486=m -+CONFIG_FB_TFT_PCD8544=m -+CONFIG_FB_TFT_RA8875=m -+CONFIG_FB_TFT_S6D02A1=m -+CONFIG_FB_TFT_S6D1121=m -+CONFIG_FB_TFT_SSD1289=m -+CONFIG_FB_TFT_SSD1306=m -+CONFIG_FB_TFT_SSD1331=m -+CONFIG_FB_TFT_SSD1351=m -+CONFIG_FB_TFT_ST7735R=m -+CONFIG_FB_TFT_ST7789V=m -+CONFIG_FB_TFT_TINYLCD=m -+CONFIG_FB_TFT_TLS8204=m -+CONFIG_FB_TFT_UC1701=m -+CONFIG_FB_TFT_UPD161704=m -+CONFIG_FB_TFT_WATTEROTT=m -+CONFIG_FB_FLEX=m -+CONFIG_FB_TFT_FBTFT_DEVICE=m -+CONFIG_BCM2835_VCHIQ=y -+CONFIG_SND_BCM2835=m -+CONFIG_VIDEO_BCM2835=m -+CONFIG_VIDEO_CODEC_BCM2835=m -+CONFIG_MAILBOX=y -+CONFIG_BCM2835_MBOX=y -+# CONFIG_IOMMU_SUPPORT is not set -+CONFIG_BCM2835_POWER=y -+CONFIG_RASPBERRYPI_POWER=y -+CONFIG_EXTCON=m -+CONFIG_EXTCON_ARIZONA=m -+CONFIG_IIO=m -+CONFIG_IIO_BUFFER_CB=m -+CONFIG_MCP320X=m -+CONFIG_MCP3422=m -+CONFIG_DHT11=m -+CONFIG_HDC100X=m -+CONFIG_HTU21=m -+CONFIG_TSL4531=m -+CONFIG_VEML6070=m -+CONFIG_BMP280=m -+CONFIG_PWM_BCM2835=m -+CONFIG_PWM_PCA9685=m -+CONFIG_GENERIC_PHY=y -+CONFIG_RPI_AXIPERF=m -+CONFIG_EXT4_FS=y -+CONFIG_EXT4_FS_POSIX_ACL=y -+CONFIG_EXT4_FS_SECURITY=y -+CONFIG_REISERFS_FS=m -+CONFIG_REISERFS_FS_XATTR=y -+CONFIG_REISERFS_FS_POSIX_ACL=y -+CONFIG_REISERFS_FS_SECURITY=y -+CONFIG_JFS_FS=m -+CONFIG_JFS_POSIX_ACL=y -+CONFIG_JFS_SECURITY=y -+CONFIG_JFS_STATISTICS=y -+CONFIG_XFS_FS=m -+CONFIG_XFS_QUOTA=y -+CONFIG_XFS_POSIX_ACL=y -+CONFIG_XFS_RT=y -+CONFIG_GFS2_FS=m -+CONFIG_OCFS2_FS=m -+CONFIG_BTRFS_FS=m -+CONFIG_BTRFS_FS_POSIX_ACL=y -+CONFIG_NILFS2_FS=m -+CONFIG_F2FS_FS=y -+CONFIG_FANOTIFY=y -+CONFIG_QFMT_V1=m -+CONFIG_QFMT_V2=m -+CONFIG_AUTOFS4_FS=y -+CONFIG_FUSE_FS=m -+CONFIG_CUSE=m -+CONFIG_OVERLAY_FS=m -+CONFIG_FSCACHE=y -+CONFIG_FSCACHE_STATS=y -+CONFIG_FSCACHE_HISTOGRAM=y -+CONFIG_CACHEFILES=y -+CONFIG_ISO9660_FS=m -+CONFIG_JOLIET=y -+CONFIG_ZISOFS=y -+CONFIG_UDF_FS=m -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+CONFIG_FAT_DEFAULT_IOCHARSET="ascii" -+CONFIG_NTFS_FS=m -+CONFIG_NTFS_RW=y -+CONFIG_TMPFS=y -+CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_ECRYPT_FS=m -+CONFIG_HFS_FS=m -+CONFIG_HFSPLUS_FS=m -+CONFIG_JFFS2_FS=m -+CONFIG_JFFS2_SUMMARY=y -+CONFIG_UBIFS_FS=m -+CONFIG_SQUASHFS=m -+CONFIG_SQUASHFS_XATTR=y -+CONFIG_SQUASHFS_LZO=y -+CONFIG_SQUASHFS_XZ=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+CONFIG_NFS_SWAP=y -+CONFIG_NFS_V4_1=y -+CONFIG_ROOT_NFS=y -+CONFIG_NFS_FSCACHE=y -+CONFIG_NFSD=m -+CONFIG_NFSD_V3_ACL=y -+CONFIG_NFSD_V4=y -+CONFIG_CIFS=m -+CONFIG_CIFS_WEAK_PW_HASH=y -+CONFIG_CIFS_UPCALL=y -+CONFIG_CIFS_XATTR=y -+CONFIG_CIFS_POSIX=y -+CONFIG_CIFS_ACL=y -+CONFIG_CIFS_DFS_UPCALL=y -+CONFIG_CIFS_FSCACHE=y -+CONFIG_9P_FS=m -+CONFIG_9P_FS_POSIX_ACL=y -+CONFIG_NLS_DEFAULT="utf8" -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_CODEPAGE_737=m -+CONFIG_NLS_CODEPAGE_775=m -+CONFIG_NLS_CODEPAGE_850=m -+CONFIG_NLS_CODEPAGE_852=m -+CONFIG_NLS_CODEPAGE_855=m -+CONFIG_NLS_CODEPAGE_857=m -+CONFIG_NLS_CODEPAGE_860=m -+CONFIG_NLS_CODEPAGE_861=m -+CONFIG_NLS_CODEPAGE_862=m -+CONFIG_NLS_CODEPAGE_863=m -+CONFIG_NLS_CODEPAGE_864=m -+CONFIG_NLS_CODEPAGE_865=m -+CONFIG_NLS_CODEPAGE_866=m -+CONFIG_NLS_CODEPAGE_869=m -+CONFIG_NLS_CODEPAGE_936=m -+CONFIG_NLS_CODEPAGE_950=m -+CONFIG_NLS_CODEPAGE_932=m -+CONFIG_NLS_CODEPAGE_949=m -+CONFIG_NLS_CODEPAGE_874=m -+CONFIG_NLS_ISO8859_8=m -+CONFIG_NLS_CODEPAGE_1250=m -+CONFIG_NLS_CODEPAGE_1251=m -+CONFIG_NLS_ASCII=y -+CONFIG_NLS_ISO8859_1=m -+CONFIG_NLS_ISO8859_2=m -+CONFIG_NLS_ISO8859_3=m -+CONFIG_NLS_ISO8859_4=m -+CONFIG_NLS_ISO8859_5=m -+CONFIG_NLS_ISO8859_6=m -+CONFIG_NLS_ISO8859_7=m -+CONFIG_NLS_ISO8859_9=m -+CONFIG_NLS_ISO8859_13=m -+CONFIG_NLS_ISO8859_14=m -+CONFIG_NLS_ISO8859_15=m -+CONFIG_NLS_KOI8_R=m -+CONFIG_NLS_KOI8_U=m -+CONFIG_DLM=m -+CONFIG_CRYPTO_USER=m -+CONFIG_CRYPTO_CBC=y -+CONFIG_CRYPTO_CTS=m -+CONFIG_CRYPTO_XTS=m -+CONFIG_CRYPTO_XCBC=m -+CONFIG_CRYPTO_TGR192=m -+CONFIG_CRYPTO_WP512=m -+CONFIG_CRYPTO_CAST5=m -+CONFIG_CRYPTO_DES=y -+CONFIG_CRYPTO_LZ4=m -+CONFIG_CRYPTO_USER_API_SKCIPHER=m -+# CONFIG_CRYPTO_HW is not set -+CONFIG_CRC_ITU_T=y -+CONFIG_LIBCRC32C=y -+CONFIG_PRINTK_TIME=y -+CONFIG_BOOT_PRINTK_DELAY=y -+CONFIG_DEBUG_MEMORY_INIT=y -+CONFIG_DETECT_HUNG_TASK=y -+# CONFIG_RCU_TRACE is not set -+CONFIG_LATENCYTOP=y -+CONFIG_IRQSOFF_TRACER=y -+CONFIG_SCHED_TRACER=y -+CONFIG_STACK_TRACER=y -+CONFIG_BLK_DEV_IO_TRACE=y -+# CONFIG_UPROBE_EVENTS is not set -+CONFIG_FUNCTION_PROFILER=y -+CONFIG_KGDB=y -+CONFIG_KGDB_KDB=y -+CONFIG_KDB_KEYBOARD=y diff --git a/target/linux/brcm2708/patches-4.19/950-0645-2711-Add-basic-64-bit-support.patch b/target/linux/brcm2708/patches-4.19/950-0645-2711-Add-basic-64-bit-support.patch deleted file mode 100644 index c82eef6908..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0645-2711-Add-basic-64-bit-support.patch +++ /dev/null @@ -1,1329 +0,0 @@ -From 45c6bd73ebe19c29ccdd6f56b52b0f03c9aed562 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 8 Mar 2019 21:12:39 +0000 -Subject: [PATCH 645/703] 2711: Add basic 64-bit support - -This commit adds initial support for 64-bit 2711 builds. However, -it will only work as much as it does if the Pi4 RAM is limited to -1GB - more than that and several things break (SD card, coherent -allocations, etc.) - -Signed-off-by: Phil Elwell ---- - arch/arm64/boot/dts/broadcom/Makefile | 1 + - .../boot/dts/broadcom/bcm2711-rpi-4-b.dts | 3 + - arch/arm64/configs/bcm2711_defconfig | 1291 +++++++++++++++++ - 3 files changed, 1295 insertions(+) - create mode 100644 arch/arm64/boot/dts/broadcom/bcm2711-rpi-4-b.dts - create mode 100644 arch/arm64/configs/bcm2711_defconfig - ---- a/arch/arm64/boot/dts/broadcom/Makefile -+++ b/arch/arm64/boot/dts/broadcom/Makefile -@@ -3,6 +3,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rp - bcm2837-rpi-3-b-plus.dtb - dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-3-b.dtb - dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b.dtb -+dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-4-b.dtb - dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b-plus.dtb - dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-cm3.dtb - dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-cm3.dtb ---- /dev/null -+++ b/arch/arm64/boot/dts/broadcom/bcm2711-rpi-4-b.dts -@@ -0,0 +1,3 @@ -+#define RPI364 -+ -+#include "../../../../arm/boot/dts/bcm2711-rpi-4-b.dts" ---- /dev/null -+++ b/arch/arm64/configs/bcm2711_defconfig -@@ -0,0 +1,1291 @@ -+CONFIG_LOCALVERSION="-v8" -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_SYSVIPC=y -+CONFIG_POSIX_MQUEUE=y -+CONFIG_GENERIC_IRQ_DEBUGFS=y -+CONFIG_NO_HZ=y -+CONFIG_HIGH_RES_TIMERS=y -+CONFIG_PREEMPT=y -+CONFIG_BSD_PROCESS_ACCT=y -+CONFIG_BSD_PROCESS_ACCT_V3=y -+CONFIG_TASKSTATS=y -+CONFIG_TASK_DELAY_ACCT=y -+CONFIG_TASK_XACCT=y -+CONFIG_TASK_IO_ACCOUNTING=y -+CONFIG_IKCONFIG=m -+CONFIG_IKCONFIG_PROC=y -+CONFIG_MEMCG=y -+CONFIG_BLK_CGROUP=y -+CONFIG_CGROUP_FREEZER=y -+CONFIG_CPUSETS=y -+CONFIG_CGROUP_DEVICE=y -+CONFIG_CGROUP_CPUACCT=y -+CONFIG_NAMESPACES=y -+CONFIG_USER_NS=y -+CONFIG_SCHED_AUTOGROUP=y -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_EMBEDDED=y -+# CONFIG_COMPAT_BRK is not set -+CONFIG_PROFILING=y -+CONFIG_ARCH_BCM2835=y -+CONFIG_PCI=y -+CONFIG_PCIE_BRCMSTB=y -+# CONFIG_CAVIUM_ERRATUM_22375 is not set -+# CONFIG_CAVIUM_ERRATUM_23154 is not set -+# CONFIG_CAVIUM_ERRATUM_27456 is not set -+CONFIG_SECCOMP=y -+CONFIG_ARMV8_DEPRECATED=y -+CONFIG_SWP_EMULATION=y -+CONFIG_CP15_BARRIER_EMULATION=y -+CONFIG_SETEND_EMULATION=y -+CONFIG_CMDLINE="console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait" -+CONFIG_COMPAT=y -+# CONFIG_SUSPEND is not set -+CONFIG_PM=y -+CONFIG_CPU_IDLE=y -+CONFIG_ARM_CPUIDLE=y -+CONFIG_CPU_FREQ=y -+CONFIG_CPU_FREQ_STAT=y -+CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y -+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -+CONFIG_CPU_FREQ_GOV_USERSPACE=y -+CONFIG_CPU_FREQ_GOV_ONDEMAND=y -+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y -+CONFIG_RASPBERRYPI_FIRMWARE=y -+CONFIG_ARM64_CRYPTO=y -+CONFIG_CRYPTO_AES_ARM64_BS=m -+CONFIG_KPROBES=y -+CONFIG_JUMP_LABEL=y -+CONFIG_MODULES=y -+CONFIG_MODULE_UNLOAD=y -+CONFIG_MODVERSIONS=y -+CONFIG_MODULE_SRCVERSION_ALL=y -+CONFIG_BLK_DEV_THROTTLING=y -+CONFIG_PARTITION_ADVANCED=y -+CONFIG_MAC_PARTITION=y -+CONFIG_CFQ_GROUP_IOSCHED=y -+CONFIG_BINFMT_MISC=m -+CONFIG_CLEANCACHE=y -+CONFIG_FRONTSWAP=y -+CONFIG_CMA=y -+CONFIG_ZSMALLOC=m -+CONFIG_PGTABLE_MAPPING=y -+CONFIG_NET=y -+CONFIG_PACKET=y -+CONFIG_UNIX=y -+CONFIG_XFRM_USER=y -+CONFIG_NET_KEY=m -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_ADVANCED_ROUTER=y -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_ROUTE_MULTIPATH=y -+CONFIG_IP_ROUTE_VERBOSE=y -+CONFIG_IP_PNP=y -+CONFIG_IP_PNP_DHCP=y -+CONFIG_IP_PNP_RARP=y -+CONFIG_NET_IPIP=m -+CONFIG_NET_IPGRE_DEMUX=m -+CONFIG_NET_IPGRE=m -+CONFIG_IP_MROUTE=y -+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IP_PIMSM_V1=y -+CONFIG_IP_PIMSM_V2=y -+CONFIG_SYN_COOKIES=y -+CONFIG_INET_AH=m -+CONFIG_INET_ESP=m -+CONFIG_INET_IPCOMP=m -+CONFIG_INET_XFRM_MODE_TRANSPORT=m -+CONFIG_INET_XFRM_MODE_TUNNEL=m -+CONFIG_INET_XFRM_MODE_BEET=m -+CONFIG_INET_DIAG=m -+CONFIG_TCP_CONG_ADVANCED=y -+CONFIG_TCP_CONG_BBR=m -+CONFIG_IPV6=m -+CONFIG_IPV6_ROUTER_PREF=y -+CONFIG_IPV6_ROUTE_INFO=y -+CONFIG_INET6_AH=m -+CONFIG_INET6_ESP=m -+CONFIG_INET6_IPCOMP=m -+CONFIG_IPV6_SIT_6RD=y -+CONFIG_IPV6_TUNNEL=m -+CONFIG_IPV6_MULTIPLE_TABLES=y -+CONFIG_IPV6_SUBTREES=y -+CONFIG_IPV6_MROUTE=y -+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IPV6_PIMSM_V2=y -+CONFIG_NETFILTER=y -+CONFIG_NF_CONNTRACK=m -+CONFIG_NF_CONNTRACK_ZONES=y -+CONFIG_NF_CONNTRACK_EVENTS=y -+CONFIG_NF_CONNTRACK_TIMESTAMP=y -+CONFIG_NF_CONNTRACK_AMANDA=m -+CONFIG_NF_CONNTRACK_FTP=m -+CONFIG_NF_CONNTRACK_H323=m -+CONFIG_NF_CONNTRACK_IRC=m -+CONFIG_NF_CONNTRACK_NETBIOS_NS=m -+CONFIG_NF_CONNTRACK_SNMP=m -+CONFIG_NF_CONNTRACK_PPTP=m -+CONFIG_NF_CONNTRACK_SANE=m -+CONFIG_NF_CONNTRACK_SIP=m -+CONFIG_NF_CONNTRACK_TFTP=m -+CONFIG_NF_CT_NETLINK=m -+CONFIG_NETFILTER_XT_SET=m -+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m -+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -+CONFIG_NETFILTER_XT_TARGET_DSCP=m -+CONFIG_NETFILTER_XT_TARGET_HMARK=m -+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m -+CONFIG_NETFILTER_XT_TARGET_LED=m -+CONFIG_NETFILTER_XT_TARGET_LOG=m -+CONFIG_NETFILTER_XT_TARGET_MARK=m -+CONFIG_NETFILTER_XT_TARGET_NFLOG=m -+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m -+CONFIG_NETFILTER_XT_TARGET_TEE=m -+CONFIG_NETFILTER_XT_TARGET_TPROXY=m -+CONFIG_NETFILTER_XT_TARGET_TRACE=m -+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m -+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m -+CONFIG_NETFILTER_XT_MATCH_BPF=m -+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m -+CONFIG_NETFILTER_XT_MATCH_COMMENT=m -+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m -+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -+CONFIG_NETFILTER_XT_MATCH_CPU=m -+CONFIG_NETFILTER_XT_MATCH_DCCP=m -+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m -+CONFIG_NETFILTER_XT_MATCH_DSCP=m -+CONFIG_NETFILTER_XT_MATCH_ESP=m -+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_HELPER=m -+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m -+CONFIG_NETFILTER_XT_MATCH_IPVS=m -+CONFIG_NETFILTER_XT_MATCH_LENGTH=m -+CONFIG_NETFILTER_XT_MATCH_LIMIT=m -+CONFIG_NETFILTER_XT_MATCH_MAC=m -+CONFIG_NETFILTER_XT_MATCH_MARK=m -+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -+CONFIG_NETFILTER_XT_MATCH_NFACCT=m -+CONFIG_NETFILTER_XT_MATCH_OSF=m -+CONFIG_NETFILTER_XT_MATCH_OWNER=m -+CONFIG_NETFILTER_XT_MATCH_POLICY=m -+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m -+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -+CONFIG_NETFILTER_XT_MATCH_QUOTA=m -+CONFIG_NETFILTER_XT_MATCH_RATEEST=m -+CONFIG_NETFILTER_XT_MATCH_REALM=m -+CONFIG_NETFILTER_XT_MATCH_RECENT=m -+CONFIG_NETFILTER_XT_MATCH_STATE=m -+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -+CONFIG_NETFILTER_XT_MATCH_STRING=m -+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -+CONFIG_NETFILTER_XT_MATCH_TIME=m -+CONFIG_NETFILTER_XT_MATCH_U32=m -+CONFIG_IP_SET=m -+CONFIG_IP_SET_BITMAP_IP=m -+CONFIG_IP_SET_BITMAP_IPMAC=m -+CONFIG_IP_SET_BITMAP_PORT=m -+CONFIG_IP_SET_HASH_IP=m -+CONFIG_IP_SET_HASH_IPPORT=m -+CONFIG_IP_SET_HASH_IPPORTIP=m -+CONFIG_IP_SET_HASH_IPPORTNET=m -+CONFIG_IP_SET_HASH_NET=m -+CONFIG_IP_SET_HASH_NETPORT=m -+CONFIG_IP_SET_HASH_NETIFACE=m -+CONFIG_IP_SET_LIST_SET=m -+CONFIG_IP_VS=m -+CONFIG_IP_VS_PROTO_TCP=y -+CONFIG_IP_VS_PROTO_UDP=y -+CONFIG_IP_VS_PROTO_ESP=y -+CONFIG_IP_VS_PROTO_AH=y -+CONFIG_IP_VS_PROTO_SCTP=y -+CONFIG_IP_VS_RR=m -+CONFIG_IP_VS_WRR=m -+CONFIG_IP_VS_LC=m -+CONFIG_IP_VS_WLC=m -+CONFIG_IP_VS_LBLC=m -+CONFIG_IP_VS_LBLCR=m -+CONFIG_IP_VS_DH=m -+CONFIG_IP_VS_SH=m -+CONFIG_IP_VS_SED=m -+CONFIG_IP_VS_NQ=m -+CONFIG_IP_VS_FTP=m -+CONFIG_IP_VS_PE_SIP=m -+CONFIG_IP_NF_IPTABLES=m -+CONFIG_IP_NF_MATCH_AH=m -+CONFIG_IP_NF_MATCH_ECN=m -+CONFIG_IP_NF_MATCH_RPFILTER=m -+CONFIG_IP_NF_MATCH_TTL=m -+CONFIG_IP_NF_FILTER=m -+CONFIG_IP_NF_TARGET_REJECT=m -+CONFIG_IP_NF_NAT=m -+CONFIG_IP_NF_TARGET_MASQUERADE=m -+CONFIG_IP_NF_TARGET_NETMAP=m -+CONFIG_IP_NF_TARGET_REDIRECT=m -+CONFIG_IP_NF_MANGLE=m -+CONFIG_IP_NF_TARGET_CLUSTERIP=m -+CONFIG_IP_NF_TARGET_ECN=m -+CONFIG_IP_NF_TARGET_TTL=m -+CONFIG_IP_NF_RAW=m -+CONFIG_IP_NF_ARPTABLES=m -+CONFIG_IP_NF_ARPFILTER=m -+CONFIG_IP_NF_ARP_MANGLE=m -+CONFIG_IP6_NF_IPTABLES=m -+CONFIG_IP6_NF_MATCH_AH=m -+CONFIG_IP6_NF_MATCH_EUI64=m -+CONFIG_IP6_NF_MATCH_FRAG=m -+CONFIG_IP6_NF_MATCH_OPTS=m -+CONFIG_IP6_NF_MATCH_HL=m -+CONFIG_IP6_NF_MATCH_IPV6HEADER=m -+CONFIG_IP6_NF_MATCH_MH=m -+CONFIG_IP6_NF_MATCH_RPFILTER=m -+CONFIG_IP6_NF_MATCH_RT=m -+CONFIG_IP6_NF_TARGET_HL=m -+CONFIG_IP6_NF_FILTER=m -+CONFIG_IP6_NF_TARGET_REJECT=m -+CONFIG_IP6_NF_MANGLE=m -+CONFIG_IP6_NF_RAW=m -+CONFIG_IP6_NF_NAT=m -+CONFIG_IP6_NF_TARGET_MASQUERADE=m -+CONFIG_IP6_NF_TARGET_NPT=m -+CONFIG_BRIDGE_NF_EBTABLES=m -+CONFIG_BRIDGE_EBT_BROUTE=m -+CONFIG_BRIDGE_EBT_T_FILTER=m -+CONFIG_BRIDGE_EBT_T_NAT=m -+CONFIG_BRIDGE_EBT_802_3=m -+CONFIG_BRIDGE_EBT_AMONG=m -+CONFIG_BRIDGE_EBT_ARP=m -+CONFIG_BRIDGE_EBT_IP=m -+CONFIG_BRIDGE_EBT_IP6=m -+CONFIG_BRIDGE_EBT_LIMIT=m -+CONFIG_BRIDGE_EBT_MARK=m -+CONFIG_BRIDGE_EBT_PKTTYPE=m -+CONFIG_BRIDGE_EBT_STP=m -+CONFIG_BRIDGE_EBT_VLAN=m -+CONFIG_BRIDGE_EBT_ARPREPLY=m -+CONFIG_BRIDGE_EBT_DNAT=m -+CONFIG_BRIDGE_EBT_MARK_T=m -+CONFIG_BRIDGE_EBT_REDIRECT=m -+CONFIG_BRIDGE_EBT_SNAT=m -+CONFIG_BRIDGE_EBT_LOG=m -+CONFIG_BRIDGE_EBT_NFLOG=m -+CONFIG_SCTP_COOKIE_HMAC_SHA1=y -+CONFIG_ATM=m -+CONFIG_L2TP=m -+CONFIG_L2TP_V3=y -+CONFIG_L2TP_IP=m -+CONFIG_L2TP_ETH=m -+CONFIG_BRIDGE=m -+CONFIG_VLAN_8021Q=m -+CONFIG_VLAN_8021Q_GVRP=y -+CONFIG_ATALK=m -+CONFIG_6LOWPAN=m -+CONFIG_IEEE802154=m -+CONFIG_IEEE802154_6LOWPAN=m -+CONFIG_MAC802154=m -+CONFIG_NET_SCHED=y -+CONFIG_NET_SCH_CBQ=m -+CONFIG_NET_SCH_HTB=m -+CONFIG_NET_SCH_HFSC=m -+CONFIG_NET_SCH_ATM=m -+CONFIG_NET_SCH_PRIO=m -+CONFIG_NET_SCH_MULTIQ=m -+CONFIG_NET_SCH_RED=m -+CONFIG_NET_SCH_SFB=m -+CONFIG_NET_SCH_SFQ=m -+CONFIG_NET_SCH_TEQL=m -+CONFIG_NET_SCH_TBF=m -+CONFIG_NET_SCH_GRED=m -+CONFIG_NET_SCH_DSMARK=m -+CONFIG_NET_SCH_NETEM=m -+CONFIG_NET_SCH_DRR=m -+CONFIG_NET_SCH_MQPRIO=m -+CONFIG_NET_SCH_CHOKE=m -+CONFIG_NET_SCH_QFQ=m -+CONFIG_NET_SCH_CODEL=m -+CONFIG_NET_SCH_FQ_CODEL=m -+CONFIG_NET_SCH_FQ=m -+CONFIG_NET_SCH_HHF=m -+CONFIG_NET_SCH_PIE=m -+CONFIG_NET_SCH_INGRESS=m -+CONFIG_NET_SCH_PLUG=m -+CONFIG_NET_CLS_BASIC=m -+CONFIG_NET_CLS_TCINDEX=m -+CONFIG_NET_CLS_ROUTE4=m -+CONFIG_NET_CLS_FW=m -+CONFIG_NET_CLS_U32=m -+CONFIG_CLS_U32_MARK=y -+CONFIG_NET_CLS_RSVP=m -+CONFIG_NET_CLS_RSVP6=m -+CONFIG_NET_CLS_FLOW=m -+CONFIG_NET_CLS_CGROUP=m -+CONFIG_NET_EMATCH=y -+CONFIG_NET_EMATCH_CMP=m -+CONFIG_NET_EMATCH_NBYTE=m -+CONFIG_NET_EMATCH_U32=m -+CONFIG_NET_EMATCH_META=m -+CONFIG_NET_EMATCH_TEXT=m -+CONFIG_NET_EMATCH_IPSET=m -+CONFIG_NET_CLS_ACT=y -+CONFIG_NET_ACT_POLICE=m -+CONFIG_NET_ACT_GACT=m -+CONFIG_GACT_PROB=y -+CONFIG_NET_ACT_MIRRED=m -+CONFIG_NET_ACT_IPT=m -+CONFIG_NET_ACT_NAT=m -+CONFIG_NET_ACT_PEDIT=m -+CONFIG_NET_ACT_SIMP=m -+CONFIG_NET_ACT_SKBEDIT=m -+CONFIG_NET_ACT_CSUM=m -+CONFIG_BATMAN_ADV=m -+CONFIG_OPENVSWITCH=m -+CONFIG_NET_PKTGEN=m -+CONFIG_HAMRADIO=y -+CONFIG_AX25=m -+CONFIG_NETROM=m -+CONFIG_ROSE=m -+CONFIG_MKISS=m -+CONFIG_6PACK=m -+CONFIG_BPQETHER=m -+CONFIG_BAYCOM_SER_FDX=m -+CONFIG_BAYCOM_SER_HDX=m -+CONFIG_YAM=m -+CONFIG_CAN=m -+CONFIG_CAN_VCAN=m -+CONFIG_CAN_SLCAN=m -+CONFIG_CAN_MCP251X=m -+CONFIG_CAN_GS_USB=m -+CONFIG_BT=m -+CONFIG_BT_RFCOMM=m -+CONFIG_BT_RFCOMM_TTY=y -+CONFIG_BT_BNEP=m -+CONFIG_BT_BNEP_MC_FILTER=y -+CONFIG_BT_BNEP_PROTO_FILTER=y -+CONFIG_BT_HIDP=m -+CONFIG_BT_6LOWPAN=m -+CONFIG_BT_HCIBTUSB=m -+CONFIG_BT_HCIUART=m -+CONFIG_BT_HCIUART_3WIRE=y -+CONFIG_BT_HCIUART_BCM=y -+CONFIG_BT_HCIBCM203X=m -+CONFIG_BT_HCIBPA10X=m -+CONFIG_BT_HCIBFUSB=m -+CONFIG_BT_HCIVHCI=m -+CONFIG_BT_MRVL=m -+CONFIG_BT_MRVL_SDIO=m -+CONFIG_BT_ATH3K=m -+CONFIG_BT_WILINK=m -+CONFIG_CFG80211=m -+CONFIG_MAC80211=m -+CONFIG_MAC80211_MESH=y -+CONFIG_WIMAX=m -+CONFIG_RFKILL=m -+CONFIG_RFKILL_INPUT=y -+CONFIG_NET_9P=m -+CONFIG_NFC=m -+CONFIG_DEVTMPFS=y -+CONFIG_DEVTMPFS_MOUNT=y -+CONFIG_DMA_CMA=y -+CONFIG_CMA_SIZE_MBYTES=5 -+CONFIG_MTD=m -+CONFIG_MTD_BLOCK=m -+CONFIG_MTD_M25P80=m -+CONFIG_MTD_BLOCK2MTD=m -+CONFIG_MTD_NAND=m -+CONFIG_MTD_SPI_NOR=m -+CONFIG_MTD_UBI=m -+CONFIG_OF_CONFIGFS=y -+CONFIG_ZRAM=m -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_CRYPTOLOOP=m -+CONFIG_BLK_DEV_DRBD=m -+CONFIG_BLK_DEV_NBD=m -+CONFIG_BLK_DEV_RAM=y -+CONFIG_CDROM_PKTCDVD=m -+CONFIG_ATA_OVER_ETH=m -+CONFIG_EEPROM_AT24=m -+CONFIG_TI_ST=m -+CONFIG_SCSI=y -+# CONFIG_SCSI_PROC_FS is not set -+CONFIG_BLK_DEV_SD=y -+CONFIG_CHR_DEV_ST=m -+CONFIG_CHR_DEV_OSST=m -+CONFIG_BLK_DEV_SR=m -+CONFIG_CHR_DEV_SG=m -+CONFIG_SCSI_ISCSI_ATTRS=y -+CONFIG_ISCSI_TCP=m -+CONFIG_ISCSI_BOOT_SYSFS=m -+CONFIG_MD=y -+CONFIG_MD_LINEAR=m -+CONFIG_BLK_DEV_DM=m -+CONFIG_DM_CRYPT=m -+CONFIG_DM_SNAPSHOT=m -+CONFIG_DM_THIN_PROVISIONING=m -+CONFIG_DM_CACHE=m -+CONFIG_DM_MIRROR=m -+CONFIG_DM_LOG_USERSPACE=m -+CONFIG_DM_RAID=m -+CONFIG_DM_ZERO=m -+CONFIG_DM_DELAY=m -+CONFIG_NETDEVICES=y -+CONFIG_BONDING=m -+CONFIG_DUMMY=m -+CONFIG_IFB=m -+CONFIG_MACVLAN=m -+CONFIG_IPVLAN=m -+CONFIG_VXLAN=m -+CONFIG_NETCONSOLE=m -+CONFIG_TUN=m -+CONFIG_VETH=m -+CONFIG_BCMGENET=y -+CONFIG_ENC28J60=m -+CONFIG_QCA7000_SPI=m -+CONFIG_MDIO_BITBANG=m -+CONFIG_BROADCOM_PHY=y -+CONFIG_PPP=m -+CONFIG_PPP_BSDCOMP=m -+CONFIG_PPP_DEFLATE=m -+CONFIG_PPP_FILTER=y -+CONFIG_PPP_MPPE=m -+CONFIG_PPP_MULTILINK=y -+CONFIG_PPPOATM=m -+CONFIG_PPPOE=m -+CONFIG_PPPOL2TP=m -+CONFIG_PPP_ASYNC=m -+CONFIG_PPP_SYNC_TTY=m -+CONFIG_SLIP=m -+CONFIG_SLIP_COMPRESSED=y -+CONFIG_SLIP_SMART=y -+CONFIG_USB_CATC=m -+CONFIG_USB_KAWETH=m -+CONFIG_USB_PEGASUS=m -+CONFIG_USB_RTL8150=m -+CONFIG_USB_RTL8152=y -+CONFIG_USB_LAN78XX=y -+CONFIG_USB_USBNET=y -+CONFIG_USB_NET_AX88179_178A=m -+CONFIG_USB_NET_CDCETHER=m -+CONFIG_USB_NET_CDC_EEM=m -+CONFIG_USB_NET_CDC_NCM=m -+CONFIG_USB_NET_HUAWEI_CDC_NCM=m -+CONFIG_USB_NET_CDC_MBIM=m -+CONFIG_USB_NET_DM9601=m -+CONFIG_USB_NET_SR9700=m -+CONFIG_USB_NET_SR9800=m -+CONFIG_USB_NET_SMSC75XX=m -+CONFIG_USB_NET_SMSC95XX=y -+CONFIG_USB_NET_GL620A=m -+CONFIG_USB_NET_NET1080=m -+CONFIG_USB_NET_PLUSB=m -+CONFIG_USB_NET_MCS7830=m -+CONFIG_USB_NET_CDC_SUBSET=m -+CONFIG_USB_ALI_M5632=y -+CONFIG_USB_AN2720=y -+CONFIG_USB_EPSON2888=y -+CONFIG_USB_KC2190=y -+CONFIG_USB_NET_ZAURUS=m -+CONFIG_USB_NET_CX82310_ETH=m -+CONFIG_USB_NET_KALMIA=m -+CONFIG_USB_NET_QMI_WWAN=m -+CONFIG_USB_HSO=m -+CONFIG_USB_NET_INT51X1=m -+CONFIG_USB_IPHETH=m -+CONFIG_USB_SIERRA_NET=m -+CONFIG_USB_VL600=m -+CONFIG_ATH9K=m -+CONFIG_ATH9K_HTC=m -+CONFIG_CARL9170=m -+CONFIG_ATH6KL=m -+CONFIG_ATH6KL_USB=m -+CONFIG_AR5523=m -+CONFIG_AT76C50X_USB=m -+CONFIG_B43=m -+# CONFIG_B43_PHY_N is not set -+CONFIG_B43LEGACY=m -+CONFIG_BRCMFMAC=m -+CONFIG_BRCMFMAC_USB=y -+CONFIG_BRCMDBG=y -+CONFIG_HOSTAP=m -+CONFIG_P54_COMMON=m -+CONFIG_P54_USB=m -+CONFIG_LIBERTAS=m -+CONFIG_LIBERTAS_USB=m -+CONFIG_LIBERTAS_SDIO=m -+CONFIG_LIBERTAS_THINFIRM=m -+CONFIG_LIBERTAS_THINFIRM_USB=m -+CONFIG_MWIFIEX=m -+CONFIG_MWIFIEX_SDIO=m -+CONFIG_MT7601U=m -+CONFIG_RT2X00=m -+CONFIG_RT2500USB=m -+CONFIG_RT73USB=m -+CONFIG_RT2800USB=m -+CONFIG_RT2800USB_RT3573=y -+CONFIG_RT2800USB_RT53XX=y -+CONFIG_RT2800USB_RT55XX=y -+CONFIG_RT2800USB_UNKNOWN=y -+CONFIG_RTL8187=m -+CONFIG_RTL8192CU=m -+CONFIG_RTL8XXXU=m -+CONFIG_USB_ZD1201=m -+CONFIG_ZD1211RW=m -+CONFIG_MAC80211_HWSIM=m -+CONFIG_USB_NET_RNDIS_WLAN=m -+CONFIG_WIMAX_I2400M_USB=m -+CONFIG_IEEE802154_AT86RF230=m -+CONFIG_IEEE802154_MRF24J40=m -+CONFIG_IEEE802154_CC2520=m -+CONFIG_INPUT_MOUSEDEV=y -+CONFIG_INPUT_JOYDEV=m -+CONFIG_INPUT_EVDEV=m -+# CONFIG_KEYBOARD_ATKBD is not set -+CONFIG_KEYBOARD_GPIO=m -+CONFIG_KEYBOARD_MATRIX=m -+# CONFIG_INPUT_MOUSE is not set -+CONFIG_INPUT_JOYSTICK=y -+CONFIG_JOYSTICK_IFORCE=m -+CONFIG_JOYSTICK_IFORCE_USB=y -+CONFIG_JOYSTICK_XPAD=m -+CONFIG_JOYSTICK_XPAD_FF=y -+CONFIG_JOYSTICK_XPAD_LEDS=y -+CONFIG_JOYSTICK_PSXPAD_SPI=m -+CONFIG_JOYSTICK_PSXPAD_SPI_FF=y -+CONFIG_JOYSTICK_RPISENSE=m -+CONFIG_INPUT_TOUCHSCREEN=y -+CONFIG_TOUCHSCREEN_ADS7846=m -+CONFIG_TOUCHSCREEN_EGALAX=m -+CONFIG_TOUCHSCREEN_EXC3000=m -+CONFIG_TOUCHSCREEN_GOODIX=m -+CONFIG_TOUCHSCREEN_EDT_FT5X06=m -+CONFIG_TOUCHSCREEN_RPI_FT5406=m -+CONFIG_TOUCHSCREEN_USB_COMPOSITE=m -+CONFIG_TOUCHSCREEN_STMPE=m -+CONFIG_INPUT_MISC=y -+CONFIG_INPUT_AD714X=m -+CONFIG_INPUT_ATI_REMOTE2=m -+CONFIG_INPUT_KEYSPAN_REMOTE=m -+CONFIG_INPUT_POWERMATE=m -+CONFIG_INPUT_YEALINK=m -+CONFIG_INPUT_CM109=m -+CONFIG_INPUT_UINPUT=m -+CONFIG_INPUT_GPIO_ROTARY_ENCODER=m -+CONFIG_INPUT_ADXL34X=m -+CONFIG_INPUT_CMA3000=m -+CONFIG_SERIO=m -+CONFIG_SERIO_RAW=m -+CONFIG_GAMEPORT=m -+CONFIG_GAMEPORT_NS558=m -+CONFIG_GAMEPORT_L4=m -+CONFIG_BRCM_CHAR_DRIVERS=y -+CONFIG_BCM_VCIO=y -+CONFIG_BCM2835_DEVGPIOMEM=y -+# CONFIG_BCM2835_SMI_DEV is not set -+# CONFIG_LEGACY_PTYS is not set -+CONFIG_SERIAL_8250=y -+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -+CONFIG_SERIAL_8250_CONSOLE=y -+# CONFIG_SERIAL_8250_DMA is not set -+CONFIG_SERIAL_8250_NR_UARTS=1 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=0 -+CONFIG_SERIAL_8250_EXTENDED=y -+CONFIG_SERIAL_8250_SHARE_IRQ=y -+CONFIG_SERIAL_8250_BCM2835AUX=y -+CONFIG_SERIAL_OF_PLATFORM=y -+CONFIG_SERIAL_AMBA_PL011=y -+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+CONFIG_SERIAL_SC16IS7XX=m -+CONFIG_SERIAL_SC16IS7XX_SPI=y -+CONFIG_SERIAL_DEV_BUS=m -+CONFIG_TTY_PRINTK=y -+CONFIG_HW_RANDOM=y -+# CONFIG_HW_RANDOM_BCM2835 is not set -+CONFIG_RAW_DRIVER=y -+CONFIG_I2C=y -+CONFIG_I2C_CHARDEV=m -+CONFIG_I2C_BCM2708=m -+CONFIG_I2C_BCM2835=m -+CONFIG_I2C_GPIO=m -+CONFIG_I2C_ROBOTFUZZ_OSIF=m -+CONFIG_I2C_TINY_USB=m -+CONFIG_SPI=y -+CONFIG_SPI_BCM2835=m -+CONFIG_SPI_BCM2835AUX=m -+CONFIG_SPI_SPIDEV=m -+CONFIG_SPI_SLAVE=y -+CONFIG_PPS_CLIENT_LDISC=m -+CONFIG_PPS_CLIENT_GPIO=m -+CONFIG_PINCTRL_MCP23S08=m -+CONFIG_GPIO_BCM_VIRT=y -+CONFIG_GPIO_MOCKUP=m -+CONFIG_GPIO_PCF857X=m -+CONFIG_GPIO_ARIZONA=m -+CONFIG_GPIO_STMPE=y -+CONFIG_W1=m -+CONFIG_W1_MASTER_DS2490=m -+CONFIG_W1_MASTER_DS2482=m -+CONFIG_W1_MASTER_DS1WM=m -+CONFIG_W1_MASTER_GPIO=m -+CONFIG_W1_SLAVE_THERM=m -+CONFIG_W1_SLAVE_SMEM=m -+CONFIG_W1_SLAVE_DS2408=m -+CONFIG_W1_SLAVE_DS2413=m -+CONFIG_W1_SLAVE_DS2406=m -+CONFIG_W1_SLAVE_DS2423=m -+CONFIG_W1_SLAVE_DS2431=m -+CONFIG_W1_SLAVE_DS2433=m -+CONFIG_W1_SLAVE_DS2438=m -+CONFIG_W1_SLAVE_DS2780=m -+CONFIG_W1_SLAVE_DS2781=m -+CONFIG_W1_SLAVE_DS28E04=m -+CONFIG_POWER_RESET_GPIO=y -+CONFIG_BATTERY_DS2760=m -+CONFIG_BATTERY_GAUGE_LTC2941=m -+CONFIG_HWMON=m -+CONFIG_SENSORS_DS1621=m -+CONFIG_SENSORS_JC42=m -+CONFIG_SENSORS_LM75=m -+CONFIG_SENSORS_SHT21=m -+CONFIG_SENSORS_SHT3x=m -+CONFIG_SENSORS_SHTC1=m -+CONFIG_SENSORS_ADS1015=m -+CONFIG_SENSORS_INA2XX=m -+CONFIG_SENSORS_TMP102=m -+CONFIG_THERMAL=y -+CONFIG_BCM2835_THERMAL=y -+CONFIG_WATCHDOG=y -+CONFIG_GPIO_WATCHDOG=m -+CONFIG_BCM2835_WDT=y -+CONFIG_MFD_STMPE=y -+CONFIG_STMPE_SPI=y -+CONFIG_MFD_ARIZONA_I2C=m -+CONFIG_MFD_ARIZONA_SPI=m -+CONFIG_MFD_WM5102=y -+CONFIG_REGULATOR=y -+CONFIG_REGULATOR_FIXED_VOLTAGE=m -+CONFIG_REGULATOR_ARIZONA_LDO1=m -+CONFIG_REGULATOR_ARIZONA_MICSUPP=m -+CONFIG_REGULATOR_GPIO=y -+CONFIG_MEDIA_SUPPORT=m -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+CONFIG_MEDIA_ANALOG_TV_SUPPORT=y -+CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y -+CONFIG_MEDIA_RADIO_SUPPORT=y -+CONFIG_MEDIA_CONTROLLER=y -+CONFIG_MEDIA_USB_SUPPORT=y -+CONFIG_USB_VIDEO_CLASS=m -+CONFIG_USB_M5602=m -+CONFIG_USB_STV06XX=m -+CONFIG_USB_GL860=m -+CONFIG_USB_GSPCA_BENQ=m -+CONFIG_USB_GSPCA_CONEX=m -+CONFIG_USB_GSPCA_CPIA1=m -+CONFIG_USB_GSPCA_DTCS033=m -+CONFIG_USB_GSPCA_ETOMS=m -+CONFIG_USB_GSPCA_FINEPIX=m -+CONFIG_USB_GSPCA_JEILINJ=m -+CONFIG_USB_GSPCA_JL2005BCD=m -+CONFIG_USB_GSPCA_KINECT=m -+CONFIG_USB_GSPCA_KONICA=m -+CONFIG_USB_GSPCA_MARS=m -+CONFIG_USB_GSPCA_MR97310A=m -+CONFIG_USB_GSPCA_NW80X=m -+CONFIG_USB_GSPCA_OV519=m -+CONFIG_USB_GSPCA_OV534=m -+CONFIG_USB_GSPCA_OV534_9=m -+CONFIG_USB_GSPCA_PAC207=m -+CONFIG_USB_GSPCA_PAC7302=m -+CONFIG_USB_GSPCA_PAC7311=m -+CONFIG_USB_GSPCA_SE401=m -+CONFIG_USB_GSPCA_SN9C2028=m -+CONFIG_USB_GSPCA_SN9C20X=m -+CONFIG_USB_GSPCA_SONIXB=m -+CONFIG_USB_GSPCA_SONIXJ=m -+CONFIG_USB_GSPCA_SPCA500=m -+CONFIG_USB_GSPCA_SPCA501=m -+CONFIG_USB_GSPCA_SPCA505=m -+CONFIG_USB_GSPCA_SPCA506=m -+CONFIG_USB_GSPCA_SPCA508=m -+CONFIG_USB_GSPCA_SPCA561=m -+CONFIG_USB_GSPCA_SPCA1528=m -+CONFIG_USB_GSPCA_SQ905=m -+CONFIG_USB_GSPCA_SQ905C=m -+CONFIG_USB_GSPCA_SQ930X=m -+CONFIG_USB_GSPCA_STK014=m -+CONFIG_USB_GSPCA_STK1135=m -+CONFIG_USB_GSPCA_STV0680=m -+CONFIG_USB_GSPCA_SUNPLUS=m -+CONFIG_USB_GSPCA_T613=m -+CONFIG_USB_GSPCA_TOPRO=m -+CONFIG_USB_GSPCA_TV8532=m -+CONFIG_USB_GSPCA_VC032X=m -+CONFIG_USB_GSPCA_VICAM=m -+CONFIG_USB_GSPCA_XIRLINK_CIT=m -+CONFIG_USB_GSPCA_ZC3XX=m -+CONFIG_USB_PWC=m -+CONFIG_VIDEO_CPIA2=m -+CONFIG_USB_ZR364XX=m -+CONFIG_USB_STKWEBCAM=m -+CONFIG_USB_S2255=m -+CONFIG_VIDEO_USBTV=m -+CONFIG_VIDEO_PVRUSB2=m -+CONFIG_VIDEO_HDPVR=m -+CONFIG_VIDEO_USBVISION=m -+CONFIG_VIDEO_STK1160_COMMON=m -+CONFIG_VIDEO_GO7007=m -+CONFIG_VIDEO_GO7007_USB=m -+CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m -+CONFIG_VIDEO_AU0828=m -+CONFIG_DVB_USB_V2=m -+CONFIG_DVB_USB_AF9035=m -+CONFIG_DVB_USB_ANYSEE=m -+CONFIG_DVB_USB_AU6610=m -+CONFIG_DVB_USB_AZ6007=m -+CONFIG_DVB_USB_CE6230=m -+CONFIG_DVB_USB_EC168=m -+CONFIG_DVB_USB_GL861=m -+CONFIG_DVB_USB_MXL111SF=m -+CONFIG_DVB_USB_DVBSKY=m -+CONFIG_SMS_USB_DRV=m -+CONFIG_DVB_B2C2_FLEXCOP_USB=m -+CONFIG_DVB_AS102=m -+CONFIG_VIDEO_EM28XX=m -+CONFIG_VIDEO_EM28XX_V4L2=m -+CONFIG_VIDEO_EM28XX_ALSA=m -+CONFIG_VIDEO_EM28XX_DVB=m -+CONFIG_V4L_PLATFORM_DRIVERS=y -+CONFIG_RADIO_SI470X=m -+CONFIG_USB_SI470X=m -+CONFIG_I2C_SI470X=m -+CONFIG_RADIO_SI4713=m -+CONFIG_I2C_SI4713=m -+CONFIG_USB_MR800=m -+CONFIG_USB_DSBR=m -+CONFIG_RADIO_SHARK=m -+CONFIG_RADIO_SHARK2=m -+CONFIG_USB_KEENE=m -+CONFIG_USB_MA901=m -+CONFIG_RADIO_TEA5764=m -+CONFIG_RADIO_SAA7706H=m -+CONFIG_RADIO_TEF6862=m -+CONFIG_RADIO_WL1273=m -+CONFIG_RADIO_WL128X=m -+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set -+CONFIG_VIDEO_UDA1342=m -+CONFIG_VIDEO_SONY_BTF_MPX=m -+CONFIG_VIDEO_TVP5150=m -+CONFIG_VIDEO_TW2804=m -+CONFIG_VIDEO_TW9903=m -+CONFIG_VIDEO_TW9906=m -+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_VC4=m -+CONFIG_DRM_TINYDRM=m -+CONFIG_TINYDRM_MI0283QT=m -+CONFIG_TINYDRM_REPAPER=m -+CONFIG_FB=y -+CONFIG_FB_BCM2708=y -+CONFIG_FB_UDL=m -+CONFIG_FB_SSD1307=m -+CONFIG_FB_RPISENSE=m -+# CONFIG_BACKLIGHT_GENERIC is not set -+CONFIG_BACKLIGHT_RPI=m -+CONFIG_BACKLIGHT_GPIO=m -+CONFIG_FRAMEBUFFER_CONSOLE=y -+CONFIG_LOGO=y -+# CONFIG_LOGO_LINUX_MONO is not set -+# CONFIG_LOGO_LINUX_VGA16 is not set -+CONFIG_SOUND=y -+CONFIG_SND=m -+CONFIG_SND_HRTIMER=m -+CONFIG_SND_SEQUENCER=m -+CONFIG_SND_SEQ_DUMMY=m -+CONFIG_SND_DUMMY=m -+CONFIG_SND_ALOOP=m -+CONFIG_SND_VIRMIDI=m -+CONFIG_SND_MTPAV=m -+CONFIG_SND_SERIAL_U16550=m -+CONFIG_SND_MPU401=m -+CONFIG_SND_USB_AUDIO=m -+CONFIG_SND_USB_UA101=m -+CONFIG_SND_USB_CAIAQ=m -+CONFIG_SND_USB_CAIAQ_INPUT=y -+CONFIG_SND_USB_6FIRE=m -+CONFIG_SND_USB_HIFACE=m -+CONFIG_SND_SOC=m -+CONFIG_SND_BCM2835_SOC_I2S=m -+CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m -+CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=m -+CONFIG_SND_BCM2708_SOC_RPI_DAC=m -+CONFIG_SND_BCM2708_SOC_RPI_PROTO=m -+CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m -+CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m -+CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -+CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m -+CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m -+CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m -+CONFIG_SND_AUDIOINJECTOR_OCTO_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_BCM2708_SOC_ALLO_PIANO_DAC_PLUS=m -+CONFIG_SND_BCM2708_SOC_ALLO_BOSS_DAC=m -+CONFIG_SND_BCM2708_SOC_ALLO_DIGIONE=m -+CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC=m -+CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m -+CONFIG_SND_PISOUND=m -+CONFIG_SND_SOC_ADAU1701=m -+CONFIG_SND_SOC_ADAU7002=m -+CONFIG_SND_SOC_AK4554=m -+CONFIG_SND_SOC_CS4271_I2C=m -+CONFIG_SND_SOC_SPDIF=m -+CONFIG_SND_SOC_WM8804_I2C=m -+CONFIG_SND_SIMPLE_CARD=m -+CONFIG_HID_BATTERY_STRENGTH=y -+CONFIG_HIDRAW=y -+CONFIG_UHID=m -+CONFIG_HID_A4TECH=m -+CONFIG_HID_ACRUX=m -+CONFIG_HID_APPLE=m -+CONFIG_HID_ASUS=m -+CONFIG_HID_BELKIN=m -+CONFIG_HID_BETOP_FF=m -+CONFIG_HID_CHERRY=m -+CONFIG_HID_CHICONY=m -+CONFIG_HID_CYPRESS=m -+CONFIG_HID_DRAGONRISE=m -+CONFIG_HID_EMS_FF=m -+CONFIG_HID_ELECOM=m -+CONFIG_HID_ELO=m -+CONFIG_HID_EZKEY=m -+CONFIG_HID_GEMBIRD=m -+CONFIG_HID_HOLTEK=m -+CONFIG_HID_KEYTOUCH=m -+CONFIG_HID_KYE=m -+CONFIG_HID_UCLOGIC=m -+CONFIG_HID_WALTOP=m -+CONFIG_HID_GYRATION=m -+CONFIG_HID_TWINHAN=m -+CONFIG_HID_KENSINGTON=m -+CONFIG_HID_LCPOWER=m -+CONFIG_HID_LOGITECH=m -+CONFIG_HID_LOGITECH_DJ=m -+CONFIG_LOGITECH_FF=y -+CONFIG_LOGIRUMBLEPAD2_FF=y -+CONFIG_LOGIG940_FF=y -+CONFIG_HID_MAGICMOUSE=m -+CONFIG_HID_MICROSOFT=m -+CONFIG_HID_MONTEREY=m -+CONFIG_HID_MULTITOUCH=m -+CONFIG_HID_NTRIG=m -+CONFIG_HID_ORTEK=m -+CONFIG_HID_PANTHERLORD=m -+CONFIG_HID_PETALYNX=m -+CONFIG_HID_PICOLCD=m -+CONFIG_HID_ROCCAT=m -+CONFIG_HID_SAMSUNG=m -+CONFIG_HID_SONY=m -+CONFIG_SONY_FF=y -+CONFIG_HID_SPEEDLINK=m -+CONFIG_HID_SUNPLUS=m -+CONFIG_HID_GREENASIA=m -+CONFIG_HID_SMARTJOYPLUS=m -+CONFIG_HID_TOPSEED=m -+CONFIG_HID_THINGM=m -+CONFIG_HID_THRUSTMASTER=m -+CONFIG_HID_WACOM=m -+CONFIG_HID_WIIMOTE=m -+CONFIG_HID_XINMO=m -+CONFIG_HID_ZEROPLUS=m -+CONFIG_HID_ZYDACRON=m -+CONFIG_HID_PID=y -+CONFIG_USB_HIDDEV=y -+CONFIG_USB=y -+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -+CONFIG_USB_MON=m -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_DWCOTG=y -+CONFIG_USB_PRINTER=m -+CONFIG_USB_STORAGE=y -+CONFIG_USB_STORAGE_REALTEK=m -+CONFIG_USB_STORAGE_DATAFAB=m -+CONFIG_USB_STORAGE_FREECOM=m -+CONFIG_USB_STORAGE_ISD200=m -+CONFIG_USB_STORAGE_USBAT=m -+CONFIG_USB_STORAGE_SDDR09=m -+CONFIG_USB_STORAGE_SDDR55=m -+CONFIG_USB_STORAGE_JUMPSHOT=m -+CONFIG_USB_STORAGE_ALAUDA=m -+CONFIG_USB_STORAGE_ONETOUCH=m -+CONFIG_USB_STORAGE_KARMA=m -+CONFIG_USB_STORAGE_CYPRESS_ATACB=m -+CONFIG_USB_STORAGE_ENE_UB6250=m -+CONFIG_USB_MDC800=m -+CONFIG_USB_MICROTEK=m -+CONFIG_USBIP_CORE=m -+CONFIG_USBIP_VHCI_HCD=m -+CONFIG_USBIP_HOST=m -+CONFIG_USB_DWC2=m -+CONFIG_USB_SERIAL=m -+CONFIG_USB_SERIAL_GENERIC=y -+CONFIG_USB_SERIAL_AIRCABLE=m -+CONFIG_USB_SERIAL_ARK3116=m -+CONFIG_USB_SERIAL_BELKIN=m -+CONFIG_USB_SERIAL_CH341=m -+CONFIG_USB_SERIAL_WHITEHEAT=m -+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m -+CONFIG_USB_SERIAL_CP210X=m -+CONFIG_USB_SERIAL_CYPRESS_M8=m -+CONFIG_USB_SERIAL_EMPEG=m -+CONFIG_USB_SERIAL_FTDI_SIO=m -+CONFIG_USB_SERIAL_VISOR=m -+CONFIG_USB_SERIAL_IPAQ=m -+CONFIG_USB_SERIAL_IR=m -+CONFIG_USB_SERIAL_EDGEPORT=m -+CONFIG_USB_SERIAL_EDGEPORT_TI=m -+CONFIG_USB_SERIAL_F81232=m -+CONFIG_USB_SERIAL_GARMIN=m -+CONFIG_USB_SERIAL_IPW=m -+CONFIG_USB_SERIAL_IUU=m -+CONFIG_USB_SERIAL_KEYSPAN_PDA=m -+CONFIG_USB_SERIAL_KEYSPAN=m -+CONFIG_USB_SERIAL_KLSI=m -+CONFIG_USB_SERIAL_KOBIL_SCT=m -+CONFIG_USB_SERIAL_MCT_U232=m -+CONFIG_USB_SERIAL_METRO=m -+CONFIG_USB_SERIAL_MOS7720=m -+CONFIG_USB_SERIAL_MOS7840=m -+CONFIG_USB_SERIAL_NAVMAN=m -+CONFIG_USB_SERIAL_PL2303=m -+CONFIG_USB_SERIAL_OTI6858=m -+CONFIG_USB_SERIAL_QCAUX=m -+CONFIG_USB_SERIAL_QUALCOMM=m -+CONFIG_USB_SERIAL_SPCP8X5=m -+CONFIG_USB_SERIAL_SAFE=m -+CONFIG_USB_SERIAL_SIERRAWIRELESS=m -+CONFIG_USB_SERIAL_SYMBOL=m -+CONFIG_USB_SERIAL_TI=m -+CONFIG_USB_SERIAL_CYBERJACK=m -+CONFIG_USB_SERIAL_XIRCOM=m -+CONFIG_USB_SERIAL_OPTION=m -+CONFIG_USB_SERIAL_OMNINET=m -+CONFIG_USB_SERIAL_OPTICON=m -+CONFIG_USB_SERIAL_XSENS_MT=m -+CONFIG_USB_SERIAL_WISHBONE=m -+CONFIG_USB_SERIAL_SSU100=m -+CONFIG_USB_SERIAL_QT2=m -+CONFIG_USB_SERIAL_DEBUG=m -+CONFIG_USB_EMI62=m -+CONFIG_USB_EMI26=m -+CONFIG_USB_ADUTUX=m -+CONFIG_USB_SEVSEG=m -+CONFIG_USB_RIO500=m -+CONFIG_USB_LEGOTOWER=m -+CONFIG_USB_LCD=m -+CONFIG_USB_CYPRESS_CY7C63=m -+CONFIG_USB_CYTHERM=m -+CONFIG_USB_IDMOUSE=m -+CONFIG_USB_FTDI_ELAN=m -+CONFIG_USB_APPLEDISPLAY=m -+CONFIG_USB_LD=m -+CONFIG_USB_TRANCEVIBRATOR=m -+CONFIG_USB_IOWARRIOR=m -+CONFIG_USB_TEST=m -+CONFIG_USB_ISIGHTFW=m -+CONFIG_USB_YUREX=m -+CONFIG_USB_ATM=m -+CONFIG_USB_SPEEDTOUCH=m -+CONFIG_USB_CXACRU=m -+CONFIG_USB_UEAGLEATM=m -+CONFIG_USB_XUSBATM=m -+CONFIG_USB_GADGET=m -+CONFIG_USB_ZERO=m -+CONFIG_USB_AUDIO=m -+CONFIG_USB_ETH=m -+CONFIG_USB_GADGETFS=m -+CONFIG_USB_MASS_STORAGE=m -+CONFIG_USB_G_SERIAL=m -+CONFIG_USB_MIDI_GADGET=m -+CONFIG_USB_G_PRINTER=m -+CONFIG_USB_CDC_COMPOSITE=m -+CONFIG_USB_G_ACM_MS=m -+CONFIG_USB_G_MULTI=m -+CONFIG_USB_G_HID=m -+CONFIG_USB_G_WEBCAM=m -+CONFIG_MMC=y -+CONFIG_MMC_BLOCK_MINORS=32 -+CONFIG_MMC_SDHCI_BCM2711=y -+CONFIG_MMC_BCM2835_MMC=y -+CONFIG_MMC_BCM2835_DMA=y -+CONFIG_MMC_BCM2835_SDHOST=y -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_PLTFM=y -+CONFIG_MMC_SPI=m -+CONFIG_LEDS_CLASS=y -+CONFIG_LEDS_GPIO=y -+CONFIG_LEDS_TRIGGER_TIMER=y -+CONFIG_LEDS_TRIGGER_ONESHOT=y -+CONFIG_LEDS_TRIGGER_HEARTBEAT=y -+CONFIG_LEDS_TRIGGER_BACKLIGHT=y -+CONFIG_LEDS_TRIGGER_CPU=y -+CONFIG_LEDS_TRIGGER_GPIO=y -+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y -+CONFIG_LEDS_TRIGGER_TRANSIENT=m -+CONFIG_LEDS_TRIGGER_CAMERA=m -+CONFIG_LEDS_TRIGGER_INPUT=y -+CONFIG_LEDS_TRIGGER_PANIC=y -+CONFIG_RTC_CLASS=y -+# CONFIG_RTC_HCTOSYS is not set -+CONFIG_RTC_DRV_ABX80X=m -+CONFIG_RTC_DRV_DS1307=m -+CONFIG_RTC_DRV_DS1374=m -+CONFIG_RTC_DRV_DS1672=m -+CONFIG_RTC_DRV_MAX6900=m -+CONFIG_RTC_DRV_RS5C372=m -+CONFIG_RTC_DRV_ISL1208=m -+CONFIG_RTC_DRV_ISL12022=m -+CONFIG_RTC_DRV_X1205=m -+CONFIG_RTC_DRV_PCF8523=m -+CONFIG_RTC_DRV_PCF8563=m -+CONFIG_RTC_DRV_PCF8583=m -+CONFIG_RTC_DRV_M41T80=m -+CONFIG_RTC_DRV_BQ32K=m -+CONFIG_RTC_DRV_S35390A=m -+CONFIG_RTC_DRV_FM3130=m -+CONFIG_RTC_DRV_RX8581=m -+CONFIG_RTC_DRV_RX8025=m -+CONFIG_RTC_DRV_EM3027=m -+CONFIG_RTC_DRV_M41T93=m -+CONFIG_RTC_DRV_M41T94=m -+CONFIG_RTC_DRV_DS1302=m -+CONFIG_RTC_DRV_DS1305=m -+CONFIG_RTC_DRV_DS1390=m -+CONFIG_RTC_DRV_R9701=m -+CONFIG_RTC_DRV_RX4581=m -+CONFIG_RTC_DRV_RS5C348=m -+CONFIG_RTC_DRV_MAX6902=m -+CONFIG_RTC_DRV_PCF2123=m -+CONFIG_RTC_DRV_DS3232=m -+CONFIG_RTC_DRV_PCF2127=m -+CONFIG_RTC_DRV_RV3029C2=m -+CONFIG_DMADEVICES=y -+CONFIG_DMA_BCM2835=y -+CONFIG_DMA_BCM2708=y -+CONFIG_UIO=m -+CONFIG_UIO_PDRV_GENIRQ=m -+CONFIG_STAGING=y -+CONFIG_PRISM2_USB=m -+CONFIG_R8712U=m -+CONFIG_R8188EU=m -+CONFIG_VT6656=m -+CONFIG_SPEAKUP=m -+CONFIG_SPEAKUP_SYNTH_SOFT=m -+CONFIG_STAGING_MEDIA=y -+CONFIG_FB_TFT=m -+CONFIG_FB_TFT_AGM1264K_FL=m -+CONFIG_FB_TFT_BD663474=m -+CONFIG_FB_TFT_HX8340BN=m -+CONFIG_FB_TFT_HX8347D=m -+CONFIG_FB_TFT_HX8353D=m -+CONFIG_FB_TFT_HX8357D=m -+CONFIG_FB_TFT_ILI9163=m -+CONFIG_FB_TFT_ILI9320=m -+CONFIG_FB_TFT_ILI9325=m -+CONFIG_FB_TFT_ILI9340=m -+CONFIG_FB_TFT_ILI9341=m -+CONFIG_FB_TFT_ILI9481=m -+CONFIG_FB_TFT_ILI9486=m -+CONFIG_FB_TFT_PCD8544=m -+CONFIG_FB_TFT_RA8875=m -+CONFIG_FB_TFT_S6D02A1=m -+CONFIG_FB_TFT_S6D1121=m -+CONFIG_FB_TFT_SSD1289=m -+CONFIG_FB_TFT_SSD1306=m -+CONFIG_FB_TFT_SSD1331=m -+CONFIG_FB_TFT_SSD1351=m -+CONFIG_FB_TFT_ST7735R=m -+CONFIG_FB_TFT_ST7789V=m -+CONFIG_FB_TFT_TINYLCD=m -+CONFIG_FB_TFT_TLS8204=m -+CONFIG_FB_TFT_UC1701=m -+CONFIG_FB_TFT_UPD161704=m -+CONFIG_FB_TFT_WATTEROTT=m -+CONFIG_FB_FLEX=m -+CONFIG_FB_TFT_FBTFT_DEVICE=m -+CONFIG_SND_BCM2835=m -+CONFIG_VIDEO_BCM2835=m -+CONFIG_MAILBOX=y -+CONFIG_BCM2835_MBOX=y -+# CONFIG_IOMMU_SUPPORT is not set -+CONFIG_RASPBERRYPI_POWER=y -+CONFIG_EXTCON=m -+CONFIG_EXTCON_ARIZONA=m -+CONFIG_IIO=m -+CONFIG_IIO_BUFFER_CB=m -+CONFIG_MCP320X=m -+CONFIG_MCP3422=m -+CONFIG_DHT11=m -+CONFIG_HDC100X=m -+CONFIG_HTU21=m -+CONFIG_TSL4531=m -+CONFIG_VEML6070=m -+CONFIG_BMP280=m -+CONFIG_PWM_BCM2835=m -+CONFIG_PWM_PCA9685=m -+CONFIG_GENERIC_PHY=y -+CONFIG_RPI_AXIPERF=m -+CONFIG_EXT4_FS=y -+CONFIG_EXT4_FS_POSIX_ACL=y -+CONFIG_EXT4_FS_SECURITY=y -+CONFIG_REISERFS_FS=m -+CONFIG_REISERFS_FS_XATTR=y -+CONFIG_REISERFS_FS_POSIX_ACL=y -+CONFIG_REISERFS_FS_SECURITY=y -+CONFIG_JFS_FS=m -+CONFIG_JFS_POSIX_ACL=y -+CONFIG_JFS_SECURITY=y -+CONFIG_JFS_STATISTICS=y -+CONFIG_XFS_FS=m -+CONFIG_XFS_QUOTA=y -+CONFIG_XFS_POSIX_ACL=y -+CONFIG_XFS_RT=y -+CONFIG_GFS2_FS=m -+CONFIG_OCFS2_FS=m -+CONFIG_BTRFS_FS=m -+CONFIG_BTRFS_FS_POSIX_ACL=y -+CONFIG_NILFS2_FS=m -+CONFIG_F2FS_FS=y -+CONFIG_FANOTIFY=y -+CONFIG_QFMT_V1=m -+CONFIG_QFMT_V2=m -+CONFIG_AUTOFS4_FS=y -+CONFIG_FUSE_FS=m -+CONFIG_CUSE=m -+CONFIG_OVERLAY_FS=m -+CONFIG_FSCACHE=y -+CONFIG_FSCACHE_STATS=y -+CONFIG_FSCACHE_HISTOGRAM=y -+CONFIG_CACHEFILES=y -+CONFIG_ISO9660_FS=m -+CONFIG_JOLIET=y -+CONFIG_ZISOFS=y -+CONFIG_UDF_FS=m -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+CONFIG_FAT_DEFAULT_IOCHARSET="ascii" -+CONFIG_NTFS_FS=m -+CONFIG_NTFS_RW=y -+CONFIG_TMPFS=y -+CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_ECRYPT_FS=m -+CONFIG_HFS_FS=m -+CONFIG_HFSPLUS_FS=m -+CONFIG_JFFS2_FS=m -+CONFIG_JFFS2_SUMMARY=y -+CONFIG_UBIFS_FS=m -+CONFIG_SQUASHFS=m -+CONFIG_SQUASHFS_XATTR=y -+CONFIG_SQUASHFS_LZO=y -+CONFIG_SQUASHFS_XZ=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+CONFIG_NFS_SWAP=y -+CONFIG_NFS_V4_1=y -+CONFIG_ROOT_NFS=y -+CONFIG_NFS_FSCACHE=y -+CONFIG_NFSD=m -+CONFIG_NFSD_V3_ACL=y -+CONFIG_NFSD_V4=y -+CONFIG_CIFS=m -+CONFIG_CIFS_WEAK_PW_HASH=y -+CONFIG_CIFS_UPCALL=y -+CONFIG_CIFS_XATTR=y -+CONFIG_CIFS_POSIX=y -+CONFIG_CIFS_ACL=y -+CONFIG_CIFS_DFS_UPCALL=y -+CONFIG_CIFS_FSCACHE=y -+CONFIG_9P_FS=m -+CONFIG_9P_FS_POSIX_ACL=y -+CONFIG_NLS_DEFAULT="utf8" -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_CODEPAGE_737=m -+CONFIG_NLS_CODEPAGE_775=m -+CONFIG_NLS_CODEPAGE_850=m -+CONFIG_NLS_CODEPAGE_852=m -+CONFIG_NLS_CODEPAGE_855=m -+CONFIG_NLS_CODEPAGE_857=m -+CONFIG_NLS_CODEPAGE_860=m -+CONFIG_NLS_CODEPAGE_861=m -+CONFIG_NLS_CODEPAGE_862=m -+CONFIG_NLS_CODEPAGE_863=m -+CONFIG_NLS_CODEPAGE_864=m -+CONFIG_NLS_CODEPAGE_865=m -+CONFIG_NLS_CODEPAGE_866=m -+CONFIG_NLS_CODEPAGE_869=m -+CONFIG_NLS_CODEPAGE_936=m -+CONFIG_NLS_CODEPAGE_950=m -+CONFIG_NLS_CODEPAGE_932=m -+CONFIG_NLS_CODEPAGE_949=m -+CONFIG_NLS_CODEPAGE_874=m -+CONFIG_NLS_ISO8859_8=m -+CONFIG_NLS_CODEPAGE_1250=m -+CONFIG_NLS_CODEPAGE_1251=m -+CONFIG_NLS_ASCII=y -+CONFIG_NLS_ISO8859_1=m -+CONFIG_NLS_ISO8859_2=m -+CONFIG_NLS_ISO8859_3=m -+CONFIG_NLS_ISO8859_4=m -+CONFIG_NLS_ISO8859_5=m -+CONFIG_NLS_ISO8859_6=m -+CONFIG_NLS_ISO8859_7=m -+CONFIG_NLS_ISO8859_9=m -+CONFIG_NLS_ISO8859_13=m -+CONFIG_NLS_ISO8859_14=m -+CONFIG_NLS_ISO8859_15=m -+CONFIG_NLS_KOI8_R=m -+CONFIG_NLS_KOI8_U=m -+CONFIG_DLM=m -+CONFIG_CRYPTO_USER=m -+CONFIG_CRYPTO_CBC=y -+CONFIG_CRYPTO_CTS=m -+CONFIG_CRYPTO_XTS=m -+CONFIG_CRYPTO_XCBC=m -+CONFIG_CRYPTO_TGR192=m -+CONFIG_CRYPTO_WP512=m -+CONFIG_CRYPTO_CAST5=m -+CONFIG_CRYPTO_DES=y -+CONFIG_CRYPTO_LZ4=m -+CONFIG_CRYPTO_USER_API_SKCIPHER=m -+CONFIG_CRC_ITU_T=y -+CONFIG_LIBCRC32C=y -+CONFIG_PRINTK_TIME=y -+CONFIG_BOOT_PRINTK_DELAY=y -+CONFIG_DEBUG_MEMORY_INIT=y -+CONFIG_DETECT_HUNG_TASK=y -+CONFIG_LATENCYTOP=y -+CONFIG_IRQSOFF_TRACER=y -+CONFIG_SCHED_TRACER=y -+CONFIG_STACK_TRACER=y -+CONFIG_BLK_DEV_IO_TRACE=y -+CONFIG_FUNCTION_PROFILER=y -+CONFIG_KGDB=y -+CONFIG_KGDB_KDB=y -+CONFIG_KDB_KEYBOARD=y diff --git a/target/linux/brcm2708/patches-4.19/950-0645-arm-dts-Change-downstream-vchiq-compatible-string.patch b/target/linux/brcm2708/patches-4.19/950-0645-arm-dts-Change-downstream-vchiq-compatible-string.patch new file mode 100644 index 0000000000..93d5385396 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0645-arm-dts-Change-downstream-vchiq-compatible-string.patch @@ -0,0 +1,59 @@ +From 9cef5f2288b06b4c3caa157e33345c2938c57a15 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 6 Feb 2019 20:45:16 +0000 +Subject: [PATCH 645/725] arm: dts: Change downstream vchiq compatible string + +The new cache line size mechanism requires a different vchiq compatible +string on BCM2836 and BCM2837, but the downstream dts files didn't +inherit the upstream changes. + +See: https://github.com/raspberrypi/linux/issues/2643 + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/bcm2708-rpi.dtsi | 2 +- + arch/arm/boot/dts/bcm2709-rpi.dtsi | 5 +++++ + arch/arm/boot/dts/bcm2709.dtsi | 2 +- + arch/arm/boot/dts/bcm2710.dtsi | 2 +- + 4 files changed, 8 insertions(+), 3 deletions(-) + create mode 100644 arch/arm/boot/dts/bcm2709-rpi.dtsi + +--- a/arch/arm/boot/dts/bcm2708-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2708-rpi.dtsi +@@ -68,7 +68,7 @@ + status = "disabled"; + }; + +- mailbox@7e00b840 { ++ vchiq: mailbox@7e00b840 { + compatible = "brcm,bcm2835-vchiq"; + reg = <0x7e00b840 0x3c>; + interrupts = <0 2>; +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2709-rpi.dtsi +@@ -0,0 +1,5 @@ ++#include "bcm2708-rpi.dtsi" ++ ++&vchiq { ++ compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq"; ++}; +--- a/arch/arm/boot/dts/bcm2709.dtsi ++++ b/arch/arm/boot/dts/bcm2709.dtsi +@@ -1,6 +1,6 @@ + #include "bcm2836.dtsi" + #include "bcm270x.dtsi" +-#include "bcm2708-rpi.dtsi" ++#include "bcm2709-rpi.dtsi" + + / { + soc { +--- a/arch/arm/boot/dts/bcm2710.dtsi ++++ b/arch/arm/boot/dts/bcm2710.dtsi +@@ -1,6 +1,6 @@ + #include "bcm2837.dtsi" + #include "bcm270x.dtsi" +-#include "bcm2708-rpi.dtsi" ++#include "bcm2709-rpi.dtsi" + + / { + compatible = "brcm,bcm2837", "brcm,bcm2836"; diff --git a/target/linux/brcm2708/patches-4.19/950-0646-bcm2835-dma-Add-proper-40-bit-DMA-support.patch b/target/linux/brcm2708/patches-4.19/950-0646-bcm2835-dma-Add-proper-40-bit-DMA-support.patch new file mode 100644 index 0000000000..544c674c2c --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0646-bcm2835-dma-Add-proper-40-bit-DMA-support.patch @@ -0,0 +1,1018 @@ +From 41cb4ad3f7327869dabc733cceb3a9273eda346d Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 4 Apr 2019 13:33:47 +0100 +Subject: [PATCH 646/725] bcm2835-dma: Add proper 40-bit DMA support + +The 40-bit additions are not fully tested, but it should be +capable of supporting both 40-bit memcpy on BCM2711 and regular +Lite channels on BCM2835. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/bcm2838.dtsi | 33 +- + drivers/dma/bcm2835-dma.c | 426 ++++++++++++++----- + drivers/pci/controller/pcie-brcmstb-bounce.c | 30 +- + drivers/pci/controller/pcie-brcmstb-bounce.h | 21 +- + drivers/pci/controller/pcie-brcmstb.c | 23 +- + 5 files changed, 395 insertions(+), 138 deletions(-) + +--- a/arch/arm/boot/dts/bcm2838.dtsi ++++ b/arch/arm/boot/dts/bcm2838.dtsi +@@ -372,6 +372,23 @@ + }; + }; + ++ dma40: dma@7e007b00 { ++ compatible = "brcm,bcm2838-dma"; ++ reg = <0x0 0x7e007b00 0x400>; ++ interrupts = ++ , /* dma4 11 */ ++ , /* dma4 12 */ ++ , /* dma4 13 */ ++ ; /* dma4 14 */ ++ interrupt-names = "dma11", ++ "dma12", ++ "dma13", ++ "dma14"; ++ #dma-cells = <1>; ++ brcm,dma-channel-mask = <0x7000>; ++ }; ++ /* DMA4 - 40 bit DMA engines */ ++ + xhci: xhci@7e9c0000 { + compatible = "generic-xhci"; + status = "disabled"; +@@ -689,6 +706,7 @@ + }; + + &dma { ++ reg = <0x7e007000 0xb00>; + interrupts = , + , + , +@@ -699,12 +717,7 @@ + , /* dmalite 7 */ + , /* dmalite 8 */ + , /* dmalite 9 */ +- , /* dmalite 10 */ +- /* DMA4 - 40 bit DMA engines */ +- , /* dma4 11 */ +- , /* dma4 12 */ +- , /* dma4 13 */ +- ; /* dma4 14 */ ++ ; /* dmalite 10 */ + interrupt-names = "dma0", + "dma1", + "dma2", +@@ -715,10 +728,6 @@ + "dma7", + "dma8", + "dma9", +- "dma10", +- "dma11", +- "dma12", +- "dma13", +- "dma14"; +- brcm,dma-channel-mask = <0x7ef5>; ++ "dma10"; ++ brcm,dma-channel-mask = <0x01f5>; + }; +--- a/drivers/dma/bcm2835-dma.c ++++ b/drivers/dma/bcm2835-dma.c +@@ -50,12 +50,18 @@ + #define BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED 14 + #define BCM2835_DMA_CHAN_NAME_SIZE 8 + #define BCM2835_DMA_BULK_MASK BIT(0) ++#define BCM2838_DMA_MEMCPY_CHAN 14 ++ ++struct bcm2835_dma_cfg_data { ++ u32 chan_40bit_mask; ++}; + + struct bcm2835_dmadev { + struct dma_device ddev; + spinlock_t lock; + void __iomem *base; + struct device_dma_parameters dma_parms; ++ const struct bcm2835_dma_cfg_data *cfg_data; + }; + + struct bcm2835_dma_cb { +@@ -100,6 +106,7 @@ struct bcm2835_chan { + unsigned int irq_flags; + + bool is_lite_channel; ++ bool is_40bit_channel; + }; + + struct bcm2835_desc { +@@ -189,7 +196,8 @@ struct bcm2835_desc { + #define BCM2835_DMA_DATA_TYPE_S128 16 + + /* Valid only for channels 0 - 14, 15 has its own base address */ +-#define BCM2835_DMA_CHAN(n) ((n) << 8) /* Base address */ ++#define BCM2835_DMA_CHAN_SIZE 0x100 ++#define BCM2835_DMA_CHAN(n) ((n) * BCM2835_DMA_CHAN_SIZE) /* Base address */ + #define BCM2835_DMA_CHANIO(base, n) ((base) + BCM2835_DMA_CHAN(n)) + + /* the max dma length for different channels */ +@@ -200,7 +208,7 @@ struct bcm2835_desc { + #define BCM2838_DMA40_CS 0x00 + #define BCM2838_DMA40_CB 0x04 + #define BCM2838_DMA40_DEBUG 0x0c +-#define BCM2858_DMA40_TI 0x10 ++#define BCM2838_DMA40_TI 0x10 + #define BCM2838_DMA40_SRC 0x14 + #define BCM2838_DMA40_SRCI 0x18 + #define BCM2838_DMA40_DEST 0x1c +@@ -209,32 +217,97 @@ struct bcm2835_desc { + #define BCM2838_DMA40_NEXT_CB 0x28 + #define BCM2838_DMA40_DEBUG2 0x2c + +-#define BCM2838_DMA40_CS_ACTIVE BIT(0) +-#define BCM2838_DMA40_CS_END BIT(1) ++#define BCM2838_DMA40_ACTIVE BIT(0) ++#define BCM2838_DMA40_END BIT(1) ++#define BCM2838_DMA40_INT BIT(2) ++#define BCM2838_DMA40_DREQ BIT(3) /* DREQ state */ ++#define BCM2838_DMA40_RD_PAUSED BIT(4) /* Reading is paused */ ++#define BCM2838_DMA40_WR_PAUSED BIT(5) /* Writing is paused */ ++#define BCM2838_DMA40_DREQ_PAUSED BIT(6) /* Is paused by DREQ flow control */ ++#define BCM2838_DMA40_WAITING_FOR_WRITES BIT(7) /* Waiting for last write */ ++#define BCM2838_DMA40_ERR BIT(10) ++#define BCM2838_DMA40_QOS(x) (((x) & 0x1f) << 16) ++#define BCM2838_DMA40_PANIC_QOS(x) (((x) & 0x1f) << 20) ++#define BCM2838_DMA40_WAIT_FOR_WRITES BIT(28) ++#define BCM2838_DMA40_DISDEBUG BIT(29) ++#define BCM2838_DMA40_ABORT BIT(30) ++#define BCM2838_DMA40_HALT BIT(31) ++#define BCM2838_DMA40_CS_FLAGS(x) (x & (BCM2838_DMA40_QOS(15) | \ ++ BCM2838_DMA40_PANIC_QOS(15) | \ ++ BCM2838_DMA40_WAIT_FOR_WRITES | \ ++ BCM2838_DMA40_DISDEBUG)) ++ ++/* Transfer information bits */ ++#define BCM2838_DMA40_INTEN BIT(0) ++#define BCM2838_DMA40_TDMODE BIT(1) /* 2D-Mode */ ++#define BCM2838_DMA40_WAIT_RESP BIT(2) /* wait for AXI write to be acked */ ++#define BCM2838_DMA40_WAIT_RD_RESP BIT(3) /* wait for AXI read to complete */ ++#define BCM2838_DMA40_PER_MAP(x) ((x & 31) << 9) /* REQ source */ ++#define BCM2838_DMA40_S_DREQ BIT(14) /* enable SREQ for source */ ++#define BCM2838_DMA40_D_DREQ BIT(15) /* enable DREQ for destination */ ++#define BCM2838_DMA40_S_WAIT(x) ((x & 0xff) << 16) /* add DMA read-wait cycles */ ++#define BCM2838_DMA40_D_WAIT(x) ((x & 0xff) << 24) /* add DMA write-wait cycles */ + +-#define BCM2838_DMA40_CS_QOS(x) (((x) & 0x1f) << 16) +-#define BCM2838_DMA40_CS_PANIC_QOS(x) (((x) & 0x1f) << 20) +-#define BCM2838_DMA40_CS_WRITE_WAIT BIT(28) ++/* debug register bits */ ++#define BCM2838_DMA40_DEBUG_WRITE_ERR BIT(0) ++#define BCM2838_DMA40_DEBUG_FIFO_ERR BIT(1) ++#define BCM2838_DMA40_DEBUG_READ_ERR BIT(2) ++#define BCM2838_DMA40_DEBUG_READ_CB_ERR BIT(3) ++#define BCM2838_DMA40_DEBUG_IN_ON_ERR BIT(8) ++#define BCM2838_DMA40_DEBUG_ABORT_ON_ERR BIT(9) ++#define BCM2838_DMA40_DEBUG_HALT_ON_ERR BIT(10) ++#define BCM2838_DMA40_DEBUG_DISABLE_CLK_GATE BIT(11) ++#define BCM2838_DMA40_DEBUG_RSTATE_SHIFT 14 ++#define BCM2838_DMA40_DEBUG_RSTATE_BITS 4 ++#define BCM2838_DMA40_DEBUG_WSTATE_SHIFT 18 ++#define BCM2838_DMA40_DEBUG_WSTATE_BITS 4 ++#define BCM2838_DMA40_DEBUG_RESET BIT(23) ++#define BCM2838_DMA40_DEBUG_ID_SHIFT 24 ++#define BCM2838_DMA40_DEBUG_ID_BITS 4 ++#define BCM2838_DMA40_DEBUG_VERSION_SHIFT 28 ++#define BCM2838_DMA40_DEBUG_VERSION_BITS 4 ++ ++/* Valid only for channels 0 - 3 (11 - 14) */ ++#define BCM2838_DMA40_CHAN(n) (((n) + 11) << 8) /* Base address */ ++#define BCM2838_DMA40_CHANIO(base, n) ((base) + BCM2838_DMA_CHAN(n)) + +-#define BCM2838_DMA40_BURST_LEN(x) ((((x) - 1) & 0xf) << 8) +-#define BCM2838_DMA40_INC BIT(12) +-#define BCM2838_DMA40_SIZE_128 (2 << 13) ++/* the max dma length for different channels */ ++#define MAX_DMA40_LEN SZ_1G + +-#define BCM2838_DMA40_MEMCPY_QOS \ +- (BCM2838_DMA40_CS_QOS(0x0) | \ +- BCM2838_DMA40_CS_PANIC_QOS(0x0) | \ +- BCM2838_DMA40_CS_WRITE_WAIT) ++#define BCM2838_DMA40_BURST_LEN(x) ((min(x,16) - 1) << 8) ++#define BCM2838_DMA40_INC BIT(12) ++#define BCM2838_DMA40_SIZE_32 (0 << 13) ++#define BCM2838_DMA40_SIZE_64 (1 << 13) ++#define BCM2838_DMA40_SIZE_128 (2 << 13) ++#define BCM2838_DMA40_SIZE_256 (3 << 13) ++#define BCM2838_DMA40_IGNORE BIT(15) ++#define BCM2838_DMA40_STRIDE(x) ((x) << 16) /* For 2D mode */ ++ ++#define BCM2838_DMA40_MEMCPY_FLAGS \ ++ (BCM2838_DMA40_QOS(0) | \ ++ BCM2838_DMA40_PANIC_QOS(0) | \ ++ BCM2838_DMA40_WAIT_FOR_WRITES | \ ++ BCM2838_DMA40_DISDEBUG) + + #define BCM2838_DMA40_MEMCPY_XFER_INFO \ + (BCM2838_DMA40_SIZE_128 | \ + BCM2838_DMA40_INC | \ + BCM2838_DMA40_BURST_LEN(16)) + ++struct bcm2835_dmadev *memcpy_parent; + static void __iomem *memcpy_chan; + static struct bcm2838_dma40_scb *memcpy_scb; + static dma_addr_t memcpy_scb_dma; + DEFINE_SPINLOCK(memcpy_lock); + ++static const struct bcm2835_dma_cfg_data bcm2835_dma_cfg = { ++ .chan_40bit_mask = 0, ++}; ++ ++static const struct bcm2835_dma_cfg_data bcm2838_dma_cfg = { ++ .chan_40bit_mask = BIT(11) | BIT(12) | BIT(13) | BIT(14), ++}; ++ + static inline size_t bcm2835_dma_max_frame_length(struct bcm2835_chan *c) + { + /* lite and normal channels have different max frame length */ +@@ -264,6 +337,32 @@ static inline struct bcm2835_desc *to_bc + return container_of(t, struct bcm2835_desc, vd.tx); + } + ++static inline uint32_t to_bcm2838_ti(uint32_t info) ++{ ++ return ((info & BCM2835_DMA_INT_EN) ? BCM2838_DMA40_INTEN : 0) | ++ ((info & BCM2835_DMA_WAIT_RESP) ? BCM2838_DMA40_WAIT_RESP : 0) | ++ ((info & BCM2835_DMA_S_DREQ) ? ++ (BCM2838_DMA40_S_DREQ | BCM2838_DMA40_WAIT_RD_RESP) : 0) | ++ ((info & BCM2835_DMA_D_DREQ) ? BCM2838_DMA40_D_DREQ : 0) | ++ BCM2838_DMA40_PER_MAP((info >> 16) & 0x1f); ++} ++ ++static inline uint32_t to_bcm2838_srci(uint32_t info) ++{ ++ return ((info & BCM2835_DMA_S_INC) ? BCM2838_DMA40_INC : 0); ++} ++ ++static inline uint32_t to_bcm2838_dsti(uint32_t info) ++{ ++ return ((info & BCM2835_DMA_D_INC) ? BCM2838_DMA40_INC : 0); ++} ++ ++static inline uint32_t to_bcm2838_cbaddr(dma_addr_t addr) ++{ ++ BUG_ON(addr & 0x1f); ++ return (addr >> 5); ++} ++ + static void bcm2835_dma_free_cb_chain(struct bcm2835_desc *desc) + { + size_t i; +@@ -282,45 +381,53 @@ static void bcm2835_dma_desc_free(struct + } + + static void bcm2835_dma_create_cb_set_length( +- struct bcm2835_chan *chan, ++ struct bcm2835_chan *c, + struct bcm2835_dma_cb *control_block, + size_t len, + size_t period_len, + size_t *total_len, + u32 finalextrainfo) + { +- size_t max_len = bcm2835_dma_max_frame_length(chan); ++ size_t max_len = bcm2835_dma_max_frame_length(c); ++ uint32_t cb_len; + + /* set the length taking lite-channel limitations into account */ +- control_block->length = min_t(u32, len, max_len); ++ cb_len = min_t(u32, len, max_len); + +- /* finished if we have no period_length */ +- if (!period_len) +- return; ++ if (period_len) { ++ /* ++ * period_len means: that we need to generate ++ * transfers that are terminating at every ++ * multiple of period_len - this is typically ++ * used to set the interrupt flag in info ++ * which is required during cyclic transfers ++ */ + +- /* +- * period_len means: that we need to generate +- * transfers that are terminating at every +- * multiple of period_len - this is typically +- * used to set the interrupt flag in info +- * which is required during cyclic transfers +- */ ++ /* have we filled in period_length yet? */ ++ if (*total_len + cb_len < period_len) { ++ /* update number of bytes in this period so far */ ++ *total_len += cb_len; ++ } else { ++ /* calculate the length that remains to reach period_len */ ++ cb_len = period_len - *total_len; + +- /* have we filled in period_length yet? */ +- if (*total_len + control_block->length < period_len) { +- /* update number of bytes in this period so far */ +- *total_len += control_block->length; +- return; ++ /* reset total_length for next period */ ++ *total_len = 0; ++ } + } + +- /* calculate the length that remains to reach period_length */ +- control_block->length = period_len - *total_len; +- +- /* reset total_length for next period */ +- *total_len = 0; +- +- /* add extrainfo bits in info */ +- control_block->info |= finalextrainfo; ++ if (c->is_40bit_channel) { ++ struct bcm2838_dma40_scb *scb = ++ (struct bcm2838_dma40_scb *)control_block; ++ ++ scb->len = cb_len; ++ /* add extrainfo bits to ti */ ++ scb->ti |= to_bcm2838_ti(finalextrainfo); ++ } else { ++ control_block->length = cb_len; ++ /* add extrainfo bits to info */ ++ control_block->info |= finalextrainfo; ++ } + } + + static inline size_t bcm2835_dma_count_frames_for_sg( +@@ -343,7 +450,7 @@ static inline size_t bcm2835_dma_count_f + /** + * bcm2835_dma_create_cb_chain - create a control block and fills data in + * +- * @chan: the @dma_chan for which we run this ++ * @c: the @bcm2835_chan for which we run this + * @direction: the direction in which we transfer + * @cyclic: it is a cyclic transfer + * @info: the default info bits to apply per controlblock +@@ -361,12 +468,11 @@ static inline size_t bcm2835_dma_count_f + * @gfp: the GFP flag to use for allocation + */ + static struct bcm2835_desc *bcm2835_dma_create_cb_chain( +- struct dma_chan *chan, enum dma_transfer_direction direction, ++ struct bcm2835_chan *c, enum dma_transfer_direction direction, + bool cyclic, u32 info, u32 finalextrainfo, size_t frames, + dma_addr_t src, dma_addr_t dst, size_t buf_len, + size_t period_len, gfp_t gfp) + { +- struct bcm2835_chan *c = to_bcm2835_dma_chan(chan); + size_t len = buf_len, total_len; + size_t frame; + struct bcm2835_desc *d; +@@ -399,11 +505,23 @@ static struct bcm2835_desc *bcm2835_dma_ + + /* fill in the control block */ + control_block = cb_entry->cb; +- control_block->info = info; +- control_block->src = src; +- control_block->dst = dst; +- control_block->stride = 0; +- control_block->next = 0; ++ if (c->is_40bit_channel) { ++ struct bcm2838_dma40_scb *scb = ++ (struct bcm2838_dma40_scb *)control_block; ++ scb->ti = to_bcm2838_ti(info); ++ scb->src = lower_32_bits(src); ++ scb->srci= upper_32_bits(src) | to_bcm2838_srci(info); ++ scb->dst = lower_32_bits(dst); ++ scb->dsti = upper_32_bits(dst) | to_bcm2838_dsti(info); ++ scb->next_cb = 0; ++ } else { ++ control_block->info = info; ++ control_block->src = src; ++ control_block->dst = dst; ++ control_block->stride = 0; ++ control_block->next = 0; ++ } ++ + /* set up length in control_block if requested */ + if (buf_len) { + /* calculate length honoring period_length */ +@@ -417,7 +535,10 @@ static struct bcm2835_desc *bcm2835_dma_ + } + + /* link this the last controlblock */ +- if (frame) ++ if (frame && c->is_40bit_channel) ++ d->cb_list[frame - 1].cb->next = ++ to_bcm2838_cbaddr(cb_entry->paddr); ++ if (frame && !c->is_40bit_channel) + d->cb_list[frame - 1].cb->next = cb_entry->paddr; + + /* update src and dst and length */ +@@ -431,7 +552,14 @@ static struct bcm2835_desc *bcm2835_dma_ + } + + /* the last frame requires extra flags */ +- d->cb_list[d->frames - 1].cb->info |= finalextrainfo; ++ if (c->is_40bit_channel) { ++ struct bcm2838_dma40_scb *scb = ++ (struct bcm2838_dma40_scb *)d->cb_list[d->frames-1].cb; ++ ++ scb->ti |= to_bcm2838_ti(finalextrainfo); ++ } else { ++ d->cb_list[d->frames - 1].cb->info |= finalextrainfo; ++ } + + /* detect a size missmatch */ + if (buf_len && (d->size != buf_len)) +@@ -445,28 +573,51 @@ error_cb: + } + + static void bcm2835_dma_fill_cb_chain_with_sg( +- struct dma_chan *chan, ++ struct bcm2835_chan *c, + enum dma_transfer_direction direction, + struct bcm2835_cb_entry *cb, + struct scatterlist *sgl, + unsigned int sg_len) + { +- struct bcm2835_chan *c = to_bcm2835_dma_chan(chan); + size_t len, max_len; + unsigned int i; + dma_addr_t addr; + struct scatterlist *sgent; + ++ pr_err("dma_fill_chain_with_sg(ch %d, dir %d):\n", c->ch, direction); ++ + max_len = bcm2835_dma_max_frame_length(c); + for_each_sg(sgl, sgent, sg_len, i) { +- for (addr = sg_dma_address(sgent), len = sg_dma_len(sgent); +- len > 0; +- addr += cb->cb->length, len -= cb->cb->length, cb++) { +- if (direction == DMA_DEV_TO_MEM) +- cb->cb->dst = addr; +- else +- cb->cb->src = addr; +- cb->cb->length = min(len, max_len); ++ if (c->is_40bit_channel) { ++ struct bcm2838_dma40_scb *scb = ++ (struct bcm2838_dma40_scb *)cb->cb; ++ for (addr = sg_dma_address(sgent), ++ len = sg_dma_len(sgent); ++ len > 0; ++ addr += scb->len, len -= scb->len, scb++) { ++ if (direction == DMA_DEV_TO_MEM) { ++ scb->dst = lower_32_bits(addr); ++ scb->dsti = upper_32_bits(addr) | BCM2838_DMA40_INC; ++ } else { ++ scb->src = lower_32_bits(addr); ++ scb->srci = upper_32_bits(addr) | BCM2838_DMA40_INC; ++ } ++ scb->len = min(len, max_len); ++ pr_err(" %llx, %x\n", (u64)addr, scb->len); ++ } ++ } else { ++ for (addr = sg_dma_address(sgent), ++ len = sg_dma_len(sgent); ++ len > 0; ++ addr += cb->cb->length, len -= cb->cb->length, ++ cb++) { ++ if (direction == DMA_DEV_TO_MEM) ++ cb->cb->dst = addr; ++ else ++ cb->cb->src = addr; ++ cb->cb->length = min(len, max_len); ++ pr_err(" %llx, %x\n", (u64)addr, cb->cb->length); ++ } + } + } + } +@@ -475,6 +626,10 @@ static int bcm2835_dma_abort(struct bcm2 + { + void __iomem *chan_base = c->chan_base; + long int timeout = 10000; ++ u32 wait_mask = BCM2835_DMA_WAITING_FOR_WRITES; ++ ++ if (c->is_40bit_channel) ++ wait_mask = BCM2838_DMA40_WAITING_FOR_WRITES; + + /* + * A zero control block address means the channel is idle. +@@ -487,8 +642,7 @@ static int bcm2835_dma_abort(struct bcm2 + writel(0, chan_base + BCM2835_DMA_CS); + + /* Wait for any current AXI transfer to complete */ +- while ((readl(chan_base + BCM2835_DMA_CS) & +- BCM2835_DMA_WAITING_FOR_WRITES) && --timeout) ++ while ((readl(chan_base + BCM2835_DMA_CS) & wait_mask) && --timeout) + cpu_relax(); + + /* Peripheral might be stuck and fail to signal AXI write responses */ +@@ -505,6 +659,7 @@ static void bcm2835_dma_start_desc(struc + struct virt_dma_desc *vd = vchan_next_desc(&c->vc); + struct bcm2835_desc *d; + ++ pr_err("dma_start_desc(%px)\n", vd); + if (!vd) { + c->desc = NULL; + return; +@@ -514,9 +669,16 @@ static void bcm2835_dma_start_desc(struc + + c->desc = d = to_bcm2835_dma_desc(&vd->tx); + +- writel(d->cb_list[0].paddr, c->chan_base + BCM2835_DMA_ADDR); +- writel(BCM2835_DMA_ACTIVE | BCM2835_DMA_CS_FLAGS(c->dreq), +- c->chan_base + BCM2835_DMA_CS); ++ if (c->is_40bit_channel) { ++ writel(to_bcm2838_cbaddr(d->cb_list[0].paddr), ++ c->chan_base + BCM2838_DMA40_CB); ++ writel(BCM2838_DMA40_ACTIVE | BCM2838_DMA40_CS_FLAGS(c->dreq), ++ c->chan_base + BCM2838_DMA40_CS); ++ } else { ++ writel(d->cb_list[0].paddr, c->chan_base + BCM2835_DMA_ADDR); ++ writel(BCM2835_DMA_ACTIVE | BCM2835_DMA_CS_FLAGS(c->dreq), ++ c->chan_base + BCM2835_DMA_CS); ++ } + } + + static irqreturn_t bcm2835_dma_callback(int irq, void *data) +@@ -544,7 +706,8 @@ static irqreturn_t bcm2835_dma_callback( + * will remain idle despite the ACTIVE flag being set. + */ + writel(BCM2835_DMA_INT | BCM2835_DMA_ACTIVE | +- BCM2835_DMA_CS_FLAGS(c->dreq), ++ (c->is_40bit_channel ? BCM2838_DMA40_CS_FLAGS(c->dreq) : ++ BCM2835_DMA_CS_FLAGS(c->dreq)), + c->chan_base + BCM2835_DMA_CS); + + d = c->desc; +@@ -643,9 +806,17 @@ static enum dma_status bcm2835_dma_tx_st + struct bcm2835_desc *d = c->desc; + dma_addr_t pos; + +- if (d->dir == DMA_MEM_TO_DEV) ++ if (d->dir == DMA_MEM_TO_DEV && c->is_40bit_channel) ++ pos = readl(c->chan_base + BCM2838_DMA40_SRC) + ++ ((readl(c->chan_base + BCM2838_DMA40_SRCI) & ++ 0xff) << 8); ++ else if (d->dir == DMA_MEM_TO_DEV && !c->is_40bit_channel) + pos = readl(c->chan_base + BCM2835_DMA_SOURCE_AD); +- else if (d->dir == DMA_DEV_TO_MEM) ++ else if (d->dir == DMA_DEV_TO_MEM && c->is_40bit_channel) ++ pos = readl(c->chan_base + BCM2838_DMA40_DEST) + ++ ((readl(c->chan_base + BCM2838_DMA40_DESTI) & ++ 0xff) << 8); ++ else if (d->dir == DMA_DEV_TO_MEM && !c->is_40bit_channel) + pos = readl(c->chan_base + BCM2835_DMA_DEST_AD); + else + pos = 0; +@@ -691,7 +862,7 @@ static struct dma_async_tx_descriptor *b + frames = bcm2835_dma_frames_for_length(len, max_len); + + /* allocate the CB chain - this also fills in the pointers */ +- d = bcm2835_dma_create_cb_chain(chan, DMA_MEM_TO_MEM, false, ++ d = bcm2835_dma_create_cb_chain(c, DMA_MEM_TO_MEM, false, + info, extra, frames, + src, dst, len, 0, GFP_KERNEL); + if (!d) +@@ -726,11 +897,21 @@ static struct dma_async_tx_descriptor *b + if (c->cfg.src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES) + return NULL; + src = c->cfg.src_addr; ++ /* ++ * One would think it ought to be possible to get the physical ++ * to dma address mapping information from the dma-ranges DT ++ * property, but I've not found a way yet that doesn't involve ++ * open-coding the whole thing. ++ */ ++ if (c->is_40bit_channel) ++ src |= 0x400000000ull; + info |= BCM2835_DMA_S_DREQ | BCM2835_DMA_D_INC; + } else { + if (c->cfg.dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES) + return NULL; + dst = c->cfg.dst_addr; ++ if (c->is_40bit_channel) ++ dst |= 0x400000000ull; + info |= BCM2835_DMA_D_DREQ | BCM2835_DMA_S_INC; + } + +@@ -738,7 +919,7 @@ static struct dma_async_tx_descriptor *b + frames = bcm2835_dma_count_frames_for_sg(c, sgl, sg_len); + + /* allocate the CB chain */ +- d = bcm2835_dma_create_cb_chain(chan, direction, false, ++ d = bcm2835_dma_create_cb_chain(c, direction, false, + info, extra, + frames, src, dst, 0, 0, + GFP_KERNEL); +@@ -746,7 +927,7 @@ static struct dma_async_tx_descriptor *b + return NULL; + + /* fill in frames with scatterlist pointers */ +- bcm2835_dma_fill_cb_chain_with_sg(chan, direction, d->cb_list, ++ bcm2835_dma_fill_cb_chain_with_sg(c, direction, d->cb_list, + sgl, sg_len); + + return vchan_tx_prep(&c->vc, &d->vd, flags); +@@ -815,7 +996,7 @@ static struct dma_async_tx_descriptor *b + * note that we need to use GFP_NOWAIT, as the ALSA i2s dmaengine + * implementation calls prep_dma_cyclic with interrupts disabled. + */ +- d = bcm2835_dma_create_cb_chain(chan, direction, true, ++ d = bcm2835_dma_create_cb_chain(c, direction, true, + info, extra, + frames, src, dst, buf_len, + period_len, GFP_NOWAIT); +@@ -823,7 +1004,8 @@ static struct dma_async_tx_descriptor *b + return NULL; + + /* wrap around into a loop */ +- d->cb_list[d->frames - 1].cb->next = d->cb_list[0].paddr; ++ d->cb_list[d->frames - 1].cb->next = c->is_40bit_channel ? ++ to_bcm2838_cbaddr(d->cb_list[0].paddr) : d->cb_list[0].paddr; + + return vchan_tx_prep(&c->vc, &d->vd, flags); + } +@@ -899,9 +1081,11 @@ static int bcm2835_dma_chan_init(struct + c->irq_number = irq; + c->irq_flags = irq_flags; + +- /* check in DEBUG register if this is a LITE channel */ +- if (readl(c->chan_base + BCM2835_DMA_DEBUG) & +- BCM2835_DMA_DEBUG_LITE) ++ /* check for 40bit and lite channels */ ++ if (d->cfg_data->chan_40bit_mask & BIT(chan_id)) ++ c->is_40bit_channel = true; ++ else if (readl(c->chan_base + BCM2835_DMA_DEBUG) & ++ BCM2835_DMA_DEBUG_LITE) + c->is_lite_channel = true; + + return 0; +@@ -918,18 +1102,16 @@ static void bcm2835_dma_free(struct bcm2 + } + } + +-int bcm2838_dma40_memcpy_init(struct device *dev) ++int bcm2838_dma40_memcpy_init(void) + { +- if (memcpy_scb) +- return 0; ++ if (!memcpy_parent) ++ return -EPROBE_DEFER; + +- memcpy_scb = dma_alloc_coherent(dev, sizeof(*memcpy_scb), +- &memcpy_scb_dma, GFP_KERNEL); ++ if (!memcpy_chan) ++ return -EINVAL; + +- if (!memcpy_scb) { +- pr_err("bcm2838_dma40_memcpy_init failed!\n"); ++ if (!memcpy_scb) + return -ENOMEM; +- } + + return 0; + } +@@ -956,20 +1138,22 @@ void bcm2838_dma40_memcpy(dma_addr_t dst + scb->next_cb = 0; + + writel((u32)(memcpy_scb_dma >> 5), memcpy_chan + BCM2838_DMA40_CB); +- writel(BCM2838_DMA40_MEMCPY_QOS + BCM2838_DMA40_CS_ACTIVE, ++ writel(BCM2838_DMA40_MEMCPY_FLAGS + BCM2838_DMA40_ACTIVE, + memcpy_chan + BCM2838_DMA40_CS); ++ + /* Poll for completion */ +- while (!(readl(memcpy_chan + BCM2838_DMA40_CS) & BCM2838_DMA40_CS_END)) ++ while (!(readl(memcpy_chan + BCM2838_DMA40_CS) & BCM2838_DMA40_END)) + cpu_relax(); + +- writel(BCM2838_DMA40_CS_END, memcpy_chan + BCM2838_DMA40_CS); ++ writel(BCM2838_DMA40_END, memcpy_chan + BCM2838_DMA40_CS); + + spin_unlock_irqrestore(&memcpy_lock, flags); + } + EXPORT_SYMBOL(bcm2838_dma40_memcpy); + + static const struct of_device_id bcm2835_dma_of_match[] = { +- { .compatible = "brcm,bcm2835-dma", }, ++ { .compatible = "brcm,bcm2835-dma", .data = &bcm2835_dma_cfg }, ++ { .compatible = "brcm,bcm2838-dma", .data = &bcm2838_dma_cfg }, + {}, + }; + MODULE_DEVICE_TABLE(of, bcm2835_dma_of_match); +@@ -1001,6 +1185,8 @@ static int bcm2835_dma_probe(struct plat + int irq_flags; + uint32_t chans_available; + char chan_name[BCM2835_DMA_CHAN_NAME_SIZE]; ++ const struct of_device_id *of_id; ++ int chan_count, chan_start, chan_end; + + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; +@@ -1020,9 +1206,13 @@ static int bcm2835_dma_probe(struct plat + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); +- rc = bcm_dmaman_probe(pdev, base, BCM2835_DMA_BULK_MASK); +- if (rc) +- dev_err(&pdev->dev, "Failed to initialize the legacy API\n"); ++ ++ /* The set of channels can be split across multiple instances. */ ++ chan_start = ((u32)base / BCM2835_DMA_CHAN_SIZE) & 0xf; ++ base -= BCM2835_DMA_CHAN(chan_start); ++ chan_count = resource_size(res) / BCM2835_DMA_CHAN_SIZE; ++ chan_end = min(chan_start + chan_count, ++ BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED + 1); + + od->base = base; + +@@ -1052,6 +1242,14 @@ static int bcm2835_dma_probe(struct plat + + platform_set_drvdata(pdev, od); + ++ of_id = of_match_node(bcm2835_dma_of_match, pdev->dev.of_node); ++ if (!of_id) { ++ dev_err(&pdev->dev, "Failed to match compatible string\n"); ++ return -EINVAL; ++ } ++ ++ od->cfg_data = of_id->data; ++ + /* Request DMA channel mask from device tree */ + if (of_property_read_u32(pdev->dev.of_node, + "brcm,dma-channel-mask", +@@ -1061,18 +1259,34 @@ static int bcm2835_dma_probe(struct plat + goto err_no_dma; + } + +- /* Channel 0 is used by the legacy API */ +- chans_available &= ~BCM2835_DMA_BULK_MASK; ++ /* One channel is reserved for the legacy API */ ++ if (chans_available & BCM2835_DMA_BULK_MASK) { ++ rc = bcm_dmaman_probe(pdev, base, ++ chans_available & BCM2835_DMA_BULK_MASK); ++ if (rc) ++ dev_err(&pdev->dev, ++ "Failed to initialize the legacy API\n"); ++ ++ chans_available &= ~BCM2835_DMA_BULK_MASK; ++ } + +- /* We can't use channels 11-13 yet */ +- chans_available &= ~(BIT(11) | BIT(12) | BIT(13)); ++ /* And possibly one for the 40-bit DMA memcpy API */ ++ if (chans_available & od->cfg_data->chan_40bit_mask & ++ BIT(BCM2838_DMA_MEMCPY_CHAN)) { ++ memcpy_parent = od; ++ memcpy_chan = BCM2835_DMA_CHANIO(base, BCM2838_DMA_MEMCPY_CHAN); ++ memcpy_scb = dma_alloc_coherent(memcpy_parent->ddev.dev, ++ sizeof(*memcpy_scb), ++ &memcpy_scb_dma, GFP_KERNEL); ++ if (!memcpy_scb) ++ dev_warn(&pdev->dev, ++ "Failed to allocated memcpy scb\n"); + +- /* Grab channel 14 for the 40-bit DMA memcpy */ +- chans_available &= ~BIT(14); +- memcpy_chan = BCM2835_DMA_CHANIO(base, 14); ++ chans_available &= ~BIT(BCM2838_DMA_MEMCPY_CHAN); ++ } + + /* get irqs for each channel that we support */ +- for (i = 0; i <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; i++) { ++ for (i = chan_start; i < chan_end; i++) { + /* skip masked out channels */ + if (!(chans_available & (1 << i))) { + irq[i] = -1; +@@ -1095,13 +1309,17 @@ static int bcm2835_dma_probe(struct plat + irq[i] = platform_get_irq(pdev, i < 11 ? i : 11); + } + ++ chan_count = 0; ++ + /* get irqs for each channel */ +- for (i = 0; i <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; i++) { ++ for (i = chan_start; i < chan_end; i++) { + /* skip channels without irq */ + if (irq[i] < 0) + continue; + + /* check if there are other channels that also use this irq */ ++ /* FIXME: This will fail if interrupts are shared across ++ instances */ + irq_flags = 0; + for (j = 0; j <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; j++) + if ((i != j) && (irq[j] == irq[i])) { +@@ -1113,9 +1331,10 @@ static int bcm2835_dma_probe(struct plat + rc = bcm2835_dma_chan_init(od, i, irq[i], irq_flags); + if (rc) + goto err_no_dma; ++ chan_count++; + } + +- dev_dbg(&pdev->dev, "Initialized %i DMA channels\n", i); ++ dev_dbg(&pdev->dev, "Initialized %i DMA channels\n", chan_count); + + /* Device-tree DMA controller registration */ + rc = of_dma_controller_register(pdev->dev.of_node, +@@ -1147,6 +1366,13 @@ static int bcm2835_dma_remove(struct pla + + bcm_dmaman_remove(pdev); + dma_async_device_unregister(&od->ddev); ++ if (memcpy_parent == od) { ++ dma_free_coherent(&pdev->dev, sizeof(*memcpy_scb), memcpy_scb, ++ memcpy_scb_dma); ++ memcpy_parent = NULL; ++ memcpy_scb = NULL; ++ memcpy_chan = NULL; ++ } + bcm2835_dma_free(od); + + return 0; +--- a/drivers/pci/controller/pcie-brcmstb-bounce.c ++++ b/drivers/pci/controller/pcie-brcmstb-bounce.c +@@ -91,7 +91,7 @@ struct dmabounce_device_info { + + static struct dmabounce_device_info *g_dmabounce_device_info; + +-extern int bcm2838_dma40_memcpy_init(struct device *dev); ++extern int bcm2838_dma40_memcpy_init(void); + extern void bcm2838_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size); + + #ifdef STATS +@@ -471,9 +471,9 @@ static const struct dma_map_ops dmabounc + .mapping_error = dmabounce_mapping_error, + }; + +-int brcm_pcie_bounce_register_dev(struct device *dev, +- unsigned long buffer_size, +- dma_addr_t threshold) ++int brcm_pcie_bounce_init(struct device *dev, ++ unsigned long buffer_size, ++ dma_addr_t threshold) + { + struct dmabounce_device_info *device_info; + int ret; +@@ -482,9 +482,9 @@ int brcm_pcie_bounce_register_dev(struct + if (g_dmabounce_device_info) + return -EBUSY; + +- ret = bcm2838_dma40_memcpy_init(dev); ++ ret = bcm2838_dma40_memcpy_init(); + if (ret) +- return ret; ++ return ret; + + device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC); + if (!device_info) { +@@ -515,9 +515,8 @@ int brcm_pcie_bounce_register_dev(struct + device_create_file(dev, &dev_attr_dmabounce_stats)); + + g_dmabounce_device_info = device_info; +- set_dma_ops(dev, &dmabounce_ops); + +- dev_info(dev, "dmabounce: registered device - %ld kB, threshold %pad\n", ++ dev_info(dev, "dmabounce: initialised - %ld kB, threshold %pad\n", + buffer_size / 1024, &threshold); + + return 0; +@@ -526,14 +525,13 @@ int brcm_pcie_bounce_register_dev(struct + kfree(device_info); + return ret; + } +-EXPORT_SYMBOL(brcm_pcie_bounce_register_dev); ++EXPORT_SYMBOL(brcm_pcie_bounce_init); + +-void brcm_pcie_bounce_unregister_dev(struct device *dev) ++void brcm_pcie_bounce_uninit(struct device *dev) + { + struct dmabounce_device_info *device_info = g_dmabounce_device_info; + + g_dmabounce_device_info = NULL; +- set_dma_ops(dev, NULL); + + if (!device_info) { + dev_warn(dev, +@@ -554,10 +552,16 @@ void brcm_pcie_bounce_unregister_dev(str + device_remove_file(dev, &dev_attr_dmabounce_stats)); + + kfree(device_info); ++} ++EXPORT_SYMBOL(brcm_pcie_bounce_uninit); ++ ++int brcm_pcie_bounce_register_dev(struct device *dev) ++{ ++ set_dma_ops(dev, &dmabounce_ops); + +- dev_info(dev, "dmabounce: device unregistered\n"); ++ return 0; + } +-EXPORT_SYMBOL(brcm_pcie_bounce_unregister_dev); ++EXPORT_SYMBOL(brcm_pcie_bounce_register_dev); + + MODULE_AUTHOR("Phil Elwell "); + MODULE_DESCRIPTION("Dedicate DMA bounce support for pcie-brcmstb"); +--- a/drivers/pci/controller/pcie-brcmstb-bounce.h ++++ b/drivers/pci/controller/pcie-brcmstb-bounce.h +@@ -8,21 +8,26 @@ + + #ifdef CONFIG_ARM + +-int brcm_pcie_bounce_register_dev(struct device *dev, unsigned long buffer_size, +- dma_addr_t threshold); +- +-int brcm_pcie_bounce_unregister_dev(struct device *dev); ++int brcm_pcie_bounce_init(struct device *dev, unsigned long buffer_size, ++ dma_addr_t threshold); ++int brcm_pcie_bounce_uninit(struct device *dev); ++int brcm_pcie_bounce_register_dev(struct device *dev); + + #else + +-static inline int brcm_pcie_bounce_register_dev(struct device *dev, +- unsigned long buffer_size, +- dma_addr_t threshold) ++static inline int brcm_pcie_bounce_init(struct device *dev, ++ unsigned long buffer_size, ++ dma_addr_t threshold) ++{ ++ return 0; ++} ++ ++static inline int brcm_pcie_bounce_uninit(struct device *dev) + { + return 0; + } + +-static inline int brcm_pcie_bounce_unregister_dev(struct device *dev) ++static inline int brcm_pcie_bounce_register_dev(struct device *dev) + { + return 0; + } +--- a/drivers/pci/controller/pcie-brcmstb.c ++++ b/drivers/pci/controller/pcie-brcmstb.c +@@ -650,6 +650,7 @@ static void brcm_set_dma_ops(struct devi + + static inline void brcm_pcie_perst_set(struct brcm_pcie *pcie, + unsigned int val); ++ + static int brcmstb_platform_notifier(struct notifier_block *nb, + unsigned long event, void *__dev) + { +@@ -663,12 +664,11 @@ static int brcmstb_platform_notifier(str + strcmp(dev->kobj.name, rc_name)) { + int ret; + +- ret = brcm_pcie_bounce_register_dev(dev, bounce_buffer, +- (dma_addr_t)bounce_threshold); ++ ret = brcm_pcie_bounce_register_dev(dev); + if (ret) { + dev_err(dev, + "brcm_pcie_bounce_register_dev() failed: %d\n", +- ret); ++ ret); + return ret; + } + } +@@ -681,8 +681,6 @@ static int brcmstb_platform_notifier(str + brcm_pcie_perst_set(g_pcie, 1); + msleep(100); + brcm_pcie_perst_set(g_pcie, 0); +- } else if (max_pfn > (bounce_threshold/PAGE_SIZE)) { +- brcm_pcie_bounce_unregister_dev(dev); + } + return NOTIFY_OK; + +@@ -1718,6 +1716,7 @@ static int brcm_pcie_probe(struct platfo + void __iomem *base; + struct pci_host_bridge *bridge; + struct pci_bus *child; ++ extern unsigned long max_pfn; + + bridge = devm_pci_alloc_host_bridge(&pdev->dev, sizeof(*pcie)); + if (!bridge) +@@ -1753,6 +1752,20 @@ static int brcm_pcie_probe(struct platfo + if (IS_ERR(base)) + return PTR_ERR(base); + ++ /* To Do: Add hardware check if this ever gets fixed */ ++ if (max_pfn > (bounce_threshold/PAGE_SIZE)) { ++ int ret; ++ ret = brcm_pcie_bounce_init(&pdev->dev, bounce_buffer, ++ (dma_addr_t)bounce_threshold); ++ if (ret) { ++ if (ret != -EPROBE_DEFER) ++ dev_err(&pdev->dev, ++ "could not init bounce buffers: %d\n", ++ ret); ++ return ret; ++ } ++ } ++ + pcie->clk = of_clk_get_by_name(dn, "sw_pcie"); + if (IS_ERR(pcie->clk)) { + dev_warn(&pdev->dev, "could not get clock\n"); diff --git a/target/linux/brcm2708/patches-4.19/950-0646-config-Add-NF_TABLES-support.patch b/target/linux/brcm2708/patches-4.19/950-0646-config-Add-NF_TABLES-support.patch deleted file mode 100644 index efbf2b9b24..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0646-config-Add-NF_TABLES-support.patch +++ /dev/null @@ -1,87 +0,0 @@ -From d5a3a06dce60efe829fd644448bbab8c10368f8a Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 3 Jun 2019 14:57:56 +0100 -Subject: [PATCH 646/703] config: Add NF_TABLES support - ---- - arch/arm/configs/bcm2711_defconfig | 48 ++++++++++++++++++++++++++++++ - 1 file changed, 48 insertions(+) - ---- a/arch/arm/configs/bcm2711_defconfig -+++ b/arch/arm/configs/bcm2711_defconfig -@@ -133,6 +133,36 @@ CONFIG_NF_CONNTRACK_SANE=m - CONFIG_NF_CONNTRACK_SIP=m - CONFIG_NF_CONNTRACK_TFTP=m - CONFIG_NF_CT_NETLINK=m -+CONFIG_NF_TABLES=m -+CONFIG_NF_TABLES_SET=m -+CONFIG_NF_TABLES_INET=y -+CONFIG_NF_TABLES_NETDEV=y -+CONFIG_NFT_NUMGEN=m -+CONFIG_NFT_CT=m -+CONFIG_NFT_FLOW_OFFLOAD=m -+CONFIG_NFT_COUNTER=m -+CONFIG_NFT_CONNLIMIT=m -+CONFIG_NFT_LOG=m -+CONFIG_NFT_LIMIT=m -+CONFIG_NFT_MASQ=m -+CONFIG_NFT_REDIR=m -+CONFIG_NFT_NAT=m -+CONFIG_NFT_TUNNEL=m -+CONFIG_NFT_OBJREF=m -+CONFIG_NFT_QUEUE=m -+CONFIG_NFT_QUOTA=m -+CONFIG_NFT_REJECT=m -+CONFIG_NFT_COMPAT=m -+CONFIG_NFT_HASH=m -+CONFIG_NFT_FIB_INET=m -+CONFIG_NFT_SOCKET=m -+CONFIG_NFT_OSF=m -+CONFIG_NFT_TPROXY=m -+CONFIG_NFT_DUP_NETDEV=m -+CONFIG_NFT_FWD_NETDEV=m -+CONFIG_NFT_FIB_NETDEV=m -+CONFIG_NF_FLOW_TABLE_INET=m -+CONFIG_NF_FLOW_TABLE=m - CONFIG_NETFILTER_XT_SET=m - CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m - CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -@@ -220,6 +250,14 @@ CONFIG_IP_VS_SED=m - CONFIG_IP_VS_NQ=m - CONFIG_IP_VS_FTP=m - CONFIG_IP_VS_PE_SIP=m -+CONFIG_NFT_CHAIN_ROUTE_IPV4=m -+CONFIG_NFT_DUP_IPV4=m -+CONFIG_NFT_FIB_IPV4=m -+CONFIG_NF_TABLES_ARP=y -+CONFIG_NF_FLOW_TABLE_IPV4=m -+CONFIG_NFT_CHAIN_NAT_IPV4=m -+CONFIG_NFT_MASQ_IPV4=m -+CONFIG_NFT_REDIR_IPV4=m - CONFIG_IP_NF_IPTABLES=m - CONFIG_IP_NF_MATCH_AH=m - CONFIG_IP_NF_MATCH_ECN=m -@@ -239,6 +277,13 @@ CONFIG_IP_NF_RAW=m - CONFIG_IP_NF_ARPTABLES=m - CONFIG_IP_NF_ARPFILTER=m - CONFIG_IP_NF_ARP_MANGLE=m -+CONFIG_NFT_CHAIN_ROUTE_IPV6=m -+CONFIG_NFT_CHAIN_NAT_IPV6=m -+CONFIG_NFT_MASQ_IPV6=m -+CONFIG_NFT_REDIR_IPV6=m -+CONFIG_NFT_DUP_IPV6=m -+CONFIG_NFT_FIB_IPV6=m -+CONFIG_NF_FLOW_TABLE_IPV6=m - CONFIG_IP6_NF_IPTABLES=m - CONFIG_IP6_NF_MATCH_AH=m - CONFIG_IP6_NF_MATCH_EUI64=m -@@ -257,6 +302,9 @@ CONFIG_IP6_NF_RAW=m - CONFIG_IP6_NF_NAT=m - CONFIG_IP6_NF_TARGET_MASQUERADE=m - CONFIG_IP6_NF_TARGET_NPT=m -+CONFIG_NF_TABLES_BRIDGE=y -+CONFIG_NFT_BRIDGE_REJECT=m -+CONFIG_NF_LOG_BRIDGE=m - CONFIG_BRIDGE_NF_EBTABLES=m - CONFIG_BRIDGE_EBT_BROUTE=m - CONFIG_BRIDGE_EBT_T_FILTER=m diff --git a/target/linux/brcm2708/patches-4.19/950-0647-BCM270X_DT-Leave-bulk-channel-in-dma-channel-mask.patch b/target/linux/brcm2708/patches-4.19/950-0647-BCM270X_DT-Leave-bulk-channel-in-dma-channel-mask.patch new file mode 100644 index 0000000000..0a0002b1fd --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0647-BCM270X_DT-Leave-bulk-channel-in-dma-channel-mask.patch @@ -0,0 +1,27 @@ +From 38e3b7d8f4443fd366afc4d20bbd36aa350e68a1 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 5 Jun 2019 21:32:03 +0100 +Subject: [PATCH 647/725] BCM270X_DT: Leave bulk channel in dma channel mask + +The updated bcm2835-dma driver does not require the BULK channel +to be removed from the set of available channels, as provided by +dma-channel-mask. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/bcm2708-rpi.dtsi | 4 ---- + 1 file changed, 4 deletions(-) + +--- a/arch/arm/boot/dts/bcm2708-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2708-rpi.dtsi +@@ -124,10 +124,6 @@ + }; + }; + +-&dma { +- brcm,dma-channel-mask = <0x7f34>; +-}; +- + &hdmi { + power-domains = <&power RPI_POWER_DOMAIN_HDMI>; + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0647-bcm2711_defconfig-add-xhci-platform-support.patch b/target/linux/brcm2708/patches-4.19/950-0647-bcm2711_defconfig-add-xhci-platform-support.patch deleted file mode 100644 index 8ba5dab055..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0647-bcm2711_defconfig-add-xhci-platform-support.patch +++ /dev/null @@ -1,20 +0,0 @@ -From ad2c4e0c73a9de7f06e891faf57ebf868fde6b24 Mon Sep 17 00:00:00 2001 -From: Jonathan Bell -Date: Mon, 3 Jun 2019 15:33:02 +0100 -Subject: [PATCH 647/703] bcm2711_defconfig: add xhci platform support - -Signed-off-by: Jonathan Bell ---- - arch/arm/configs/bcm2711_defconfig | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm/configs/bcm2711_defconfig -+++ b/arch/arm/configs/bcm2711_defconfig -@@ -983,6 +983,7 @@ CONFIG_USB=y - CONFIG_USB_ANNOUNCE_NEW_DEVICES=y - CONFIG_USB_MON=m - CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_XHCI_PLATFORM=y - CONFIG_USB_DWCOTG=y - CONFIG_USB_PRINTER=m - CONFIG_USB_STORAGE=y diff --git a/target/linux/brcm2708/patches-4.19/950-0648-ARM-dts-bcm283x-Correct-vchiq-compatible-string-2840.patch b/target/linux/brcm2708/patches-4.19/950-0648-ARM-dts-bcm283x-Correct-vchiq-compatible-string-2840.patch deleted file mode 100644 index 6a1bae2bb2..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0648-ARM-dts-bcm283x-Correct-vchiq-compatible-string-2840.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 99c805aa346cf88fba8b26eb1093192bcc822986 Mon Sep 17 00:00:00 2001 -From: 6by9 <6by9@users.noreply.github.com> -Date: Wed, 30 Jan 2019 14:22:03 +0000 -Subject: [PATCH 648/703] ARM: dts: bcm283x: Correct vchiq compatible string - (#2840) - -commit 499770ede3f829e80539f46b59b5f460dc327aa6 upstream. - -To allow VCHIQ to determine the correct cache line size, use the new -"brcm,bcm2836-vchiq" compatible string on BCM2836 and BCM2837. - -Signed-off-by: Phil Elwell -Acked-by: Stefan Wahren -Signed-off-by: Stefan Wahren ---- - arch/arm/boot/dts/bcm2835-rpi.dtsi | 2 +- - arch/arm/boot/dts/bcm2836-rpi-2-b.dts | 2 +- - arch/arm/boot/dts/bcm2836-rpi.dtsi | 6 ++++++ - arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 2 +- - arch/arm/boot/dts/bcm2837-rpi-3-b.dts | 2 +- - 5 files changed, 10 insertions(+), 4 deletions(-) - create mode 100644 arch/arm/boot/dts/bcm2836-rpi.dtsi - ---- a/arch/arm/boot/dts/bcm2835-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi -@@ -30,7 +30,7 @@ - #power-domain-cells = <1>; - }; - -- mailbox@7e00b840 { -+ vchiq: mailbox@7e00b840 { - compatible = "brcm,bcm2835-vchiq"; - reg = <0x7e00b840 0x3c>; - interrupts = <0 2>; ---- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts -@@ -1,7 +1,7 @@ - // SPDX-License-Identifier: GPL-2.0 - /dts-v1/; - #include "bcm2836.dtsi" --#include "bcm2835-rpi.dtsi" -+#include "bcm2836-rpi.dtsi" - #include "bcm283x-rpi-smsc9514.dtsi" - #include "bcm283x-rpi-usb-host.dtsi" - #include "bcm283x-rpi-csi1-2lane.dtsi" ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2836-rpi.dtsi -@@ -0,0 +1,6 @@ -+// SPDX-License-Identifier: GPL-2.0 -+#include "bcm2835-rpi.dtsi" -+ -+&vchiq { -+ compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq"; -+}; ---- a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts -@@ -1,7 +1,7 @@ - // SPDX-License-Identifier: GPL-2.0 - /dts-v1/; - #include "bcm2837.dtsi" --#include "bcm2835-rpi.dtsi" -+#include "bcm2836-rpi.dtsi" - #include "bcm283x-rpi-lan7515.dtsi" - #include "bcm283x-rpi-usb-host.dtsi" - ---- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts -@@ -1,7 +1,7 @@ - // SPDX-License-Identifier: GPL-2.0 - /dts-v1/; - #include "bcm2837.dtsi" --#include "bcm2835-rpi.dtsi" -+#include "bcm2836-rpi.dtsi" - #include "bcm283x-rpi-smsc9514.dtsi" - #include "bcm283x-rpi-usb-host.dtsi" - #include "bcm283x-rpi-csi1-2lane.dtsi" diff --git a/target/linux/brcm2708/patches-4.19/950-0648-SQUASH-bcm2835-dma-Remove-debugging.patch b/target/linux/brcm2708/patches-4.19/950-0648-SQUASH-bcm2835-dma-Remove-debugging.patch new file mode 100644 index 0000000000..5d948f3537 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0648-SQUASH-bcm2835-dma-Remove-debugging.patch @@ -0,0 +1,45 @@ +From 2abf4cf9870fcd57e614cb39b95e6e2a4462a828 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 6 Jun 2019 09:35:08 +0100 +Subject: [PATCH 648/725] SQUASH: bcm2835-dma: Remove debugging + +Signed-off-by: Phil Elwell +--- + drivers/dma/bcm2835-dma.c | 5 ----- + 1 file changed, 5 deletions(-) + +--- a/drivers/dma/bcm2835-dma.c ++++ b/drivers/dma/bcm2835-dma.c +@@ -584,8 +584,6 @@ static void bcm2835_dma_fill_cb_chain_wi + dma_addr_t addr; + struct scatterlist *sgent; + +- pr_err("dma_fill_chain_with_sg(ch %d, dir %d):\n", c->ch, direction); +- + max_len = bcm2835_dma_max_frame_length(c); + for_each_sg(sgl, sgent, sg_len, i) { + if (c->is_40bit_channel) { +@@ -603,7 +601,6 @@ static void bcm2835_dma_fill_cb_chain_wi + scb->srci = upper_32_bits(addr) | BCM2838_DMA40_INC; + } + scb->len = min(len, max_len); +- pr_err(" %llx, %x\n", (u64)addr, scb->len); + } + } else { + for (addr = sg_dma_address(sgent), +@@ -616,7 +613,6 @@ static void bcm2835_dma_fill_cb_chain_wi + else + cb->cb->src = addr; + cb->cb->length = min(len, max_len); +- pr_err(" %llx, %x\n", (u64)addr, cb->cb->length); + } + } + } +@@ -659,7 +655,6 @@ static void bcm2835_dma_start_desc(struc + struct virt_dma_desc *vd = vchan_next_desc(&c->vc); + struct bcm2835_desc *d; + +- pr_err("dma_start_desc(%px)\n", vd); + if (!vd) { + c->desc = NULL; + return; diff --git a/target/linux/brcm2708/patches-4.19/950-0649-arm-dts-Change-downstream-vchiq-compatible-string.patch b/target/linux/brcm2708/patches-4.19/950-0649-arm-dts-Change-downstream-vchiq-compatible-string.patch deleted file mode 100644 index ca71d01a88..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0649-arm-dts-Change-downstream-vchiq-compatible-string.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 4ef78a596dcde685022fde07c4cb5bc993ce7aa3 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 6 Feb 2019 20:45:16 +0000 -Subject: [PATCH 649/703] arm: dts: Change downstream vchiq compatible string - -The new cache line size mechanism requires a different vchiq compatible -string on BCM2836 and BCM2837, but the downstream dts files didn't -inherit the upstream changes. - -See: https://github.com/raspberrypi/linux/issues/2643 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2708-rpi.dtsi | 2 +- - arch/arm/boot/dts/bcm2709-rpi.dtsi | 5 +++++ - arch/arm/boot/dts/bcm2709.dtsi | 2 +- - arch/arm/boot/dts/bcm2710.dtsi | 2 +- - 4 files changed, 8 insertions(+), 3 deletions(-) - create mode 100644 arch/arm/boot/dts/bcm2709-rpi.dtsi - ---- a/arch/arm/boot/dts/bcm2708-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi.dtsi -@@ -68,7 +68,7 @@ - status = "disabled"; - }; - -- mailbox@7e00b840 { -+ vchiq: mailbox@7e00b840 { - compatible = "brcm,bcm2835-vchiq"; - reg = <0x7e00b840 0x3c>; - interrupts = <0 2>; ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2709-rpi.dtsi -@@ -0,0 +1,5 @@ -+#include "bcm2708-rpi.dtsi" -+ -+&vchiq { -+ compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq"; -+}; ---- a/arch/arm/boot/dts/bcm2709.dtsi -+++ b/arch/arm/boot/dts/bcm2709.dtsi -@@ -1,6 +1,6 @@ - #include "bcm2836.dtsi" - #include "bcm270x.dtsi" --#include "bcm2708-rpi.dtsi" -+#include "bcm2709-rpi.dtsi" - - / { - soc { ---- a/arch/arm/boot/dts/bcm2710.dtsi -+++ b/arch/arm/boot/dts/bcm2710.dtsi -@@ -1,6 +1,6 @@ - #include "bcm2837.dtsi" - #include "bcm270x.dtsi" --#include "bcm2708-rpi.dtsi" -+#include "bcm2709-rpi.dtsi" - - / { - compatible = "brcm,bcm2837", "brcm,bcm2836"; diff --git a/target/linux/brcm2708/patches-4.19/950-0649-defconfig-Update-bcm2711-to-match-bcm2709-on-extra-m.patch b/target/linux/brcm2708/patches-4.19/950-0649-defconfig-Update-bcm2711-to-match-bcm2709-on-extra-m.patch new file mode 100644 index 0000000000..b31ca9d876 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0649-defconfig-Update-bcm2711-to-match-bcm2709-on-extra-m.patch @@ -0,0 +1,300 @@ +From 1f08e6a6f4210e44d77b40f45ec6cea9e364abe1 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 6 Jun 2019 15:22:29 +0100 +Subject: [PATCH 649/725] defconfig: Update bcm2711 to match bcm2709 on extra + modules + +Lots of things like USB DVB tuners were missing from the +defconfig. +Resync it with bcm2709_defconfig + +Signed-off-by: Dave Stevenson +--- + arch/arm/configs/bcm2711_defconfig | 97 ++++++++++++++++++++++++++++++ + 1 file changed, 97 insertions(+) + +--- a/arch/arm/configs/bcm2711_defconfig ++++ b/arch/arm/configs/bcm2711_defconfig +@@ -14,6 +14,9 @@ CONFIG_TASK_XACCT=y + CONFIG_TASK_IO_ACCOUNTING=y + CONFIG_IKCONFIG=m + CONFIG_IKCONFIG_PROC=y ++CONFIG_MEMCG=y ++CONFIG_BLK_CGROUP=y ++CONFIG_CGROUP_PIDS=y + CONFIG_CGROUP_FREEZER=y + CONFIG_CPUSETS=y + CONFIG_CGROUP_DEVICE=y +@@ -65,8 +68,10 @@ CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + CONFIG_MODVERSIONS=y + CONFIG_MODULE_SRCVERSION_ALL=y ++CONFIG_BLK_DEV_THROTTLING=y + CONFIG_PARTITION_ADVANCED=y + CONFIG_MAC_PARTITION=y ++CONFIG_CFQ_GROUP_IOSCHED=y + CONFIG_BINFMT_MISC=m + CONFIG_CLEANCACHE=y + CONFIG_FRONTSWAP=y +@@ -95,6 +100,7 @@ CONFIG_IP_MROUTE_MULTIPLE_TABLES=y + CONFIG_IP_PIMSM_V1=y + CONFIG_IP_PIMSM_V2=y + CONFIG_SYN_COOKIES=y ++CONFIG_NET_IPVTI=m + CONFIG_INET_AH=m + CONFIG_INET_ESP=m + CONFIG_INET_IPCOMP=m +@@ -214,6 +220,7 @@ CONFIG_NETFILTER_XT_MATCH_QUOTA=m + CONFIG_NETFILTER_XT_MATCH_RATEEST=m + CONFIG_NETFILTER_XT_MATCH_REALM=m + CONFIG_NETFILTER_XT_MATCH_RECENT=m ++CONFIG_NETFILTER_XT_MATCH_SOCKET=m + CONFIG_NETFILTER_XT_MATCH_STATE=m + CONFIG_NETFILTER_XT_MATCH_STATISTIC=m + CONFIG_NETFILTER_XT_MATCH_STRING=m +@@ -520,6 +527,7 @@ CONFIG_USB_RTL8150=m + CONFIG_USB_RTL8152=y + CONFIG_USB_LAN78XX=y + CONFIG_USB_USBNET=y ++CONFIG_USB_NET_AX8817X=m + CONFIG_USB_NET_AX88179_178A=m + CONFIG_USB_NET_CDCETHER=m + CONFIG_USB_NET_CDC_EEM=m +@@ -573,6 +581,8 @@ CONFIG_LIBERTAS_THINFIRM_USB=m + CONFIG_MWIFIEX=m + CONFIG_MWIFIEX_SDIO=m + CONFIG_MT7601U=m ++CONFIG_MT76x0U=m ++CONFIG_MT76x2U=m + CONFIG_RT2X00=m + CONFIG_RT2500USB=m + CONFIG_RT73USB=m +@@ -613,6 +623,7 @@ CONFIG_TOUCHSCREEN_ADS7846=m + CONFIG_TOUCHSCREEN_EGALAX=m + CONFIG_TOUCHSCREEN_EXC3000=m + CONFIG_TOUCHSCREEN_GOODIX=m ++CONFIG_TOUCHSCREEN_ILI210X=m + CONFIG_TOUCHSCREEN_EDT_FT5X06=m + CONFIG_TOUCHSCREEN_RPI_FT5406=m + CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +@@ -657,8 +668,13 @@ CONFIG_SERIAL_DEV_BUS=m + CONFIG_TTY_PRINTK=y + CONFIG_HW_RANDOM=y + CONFIG_RAW_DRIVER=y ++CONFIG_TCG_TPM=m ++CONFIG_TCG_TIS_SPI=m + CONFIG_I2C=y + CONFIG_I2C_CHARDEV=m ++CONFIG_I2C_MUX=m ++CONFIG_I2C_MUX_GPMUX=m ++CONFIG_I2C_MUX_PCA954x=m + CONFIG_I2C_BCM2708=m + CONFIG_I2C_BCM2835=m + CONFIG_I2C_GPIO=m +@@ -667,6 +683,7 @@ CONFIG_I2C_TINY_USB=m + CONFIG_SPI=y + CONFIG_SPI_BCM2835=m + CONFIG_SPI_BCM2835AUX=m ++CONFIG_SPI_GPIO=m + CONFIG_SPI_SPIDEV=m + CONFIG_SPI_SLAVE=y + CONFIG_PPS=m +@@ -698,11 +715,14 @@ CONFIG_W1_SLAVE_DS28E04=m + CONFIG_POWER_RESET=y + CONFIG_POWER_RESET_GPIO=y + CONFIG_BATTERY_DS2760=m ++CONFIG_BATTERY_MAX17040=m + CONFIG_BATTERY_GAUGE_LTC2941=m + CONFIG_HWMON=m + CONFIG_SENSORS_DS1621=m ++CONFIG_SENSORS_GPIO_FAN=m + CONFIG_SENSORS_JC42=m + CONFIG_SENSORS_LM75=m ++CONFIG_SENSORS_RASPBERRYPI_HWMON=m + CONFIG_SENSORS_RPI_POE_FAN=m + CONFIG_SENSORS_SHT21=m + CONFIG_SENSORS_SHT3x=m +@@ -726,6 +746,31 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=m + CONFIG_REGULATOR_ARIZONA_LDO1=m + CONFIG_REGULATOR_ARIZONA_MICSUPP=m + CONFIG_REGULATOR_GPIO=y ++CONFIG_RC_CORE=y ++CONFIG_LIRC=y ++CONFIG_RC_DECODERS=y ++CONFIG_IR_NEC_DECODER=m ++CONFIG_IR_RC5_DECODER=m ++CONFIG_IR_RC6_DECODER=m ++CONFIG_IR_JVC_DECODER=m ++CONFIG_IR_SONY_DECODER=m ++CONFIG_IR_SANYO_DECODER=m ++CONFIG_IR_SHARP_DECODER=m ++CONFIG_IR_MCE_KBD_DECODER=m ++CONFIG_IR_XMP_DECODER=m ++CONFIG_IR_IMON_DECODER=m ++CONFIG_RC_DEVICES=y ++CONFIG_RC_ATI_REMOTE=m ++CONFIG_IR_IMON=m ++CONFIG_IR_MCEUSB=m ++CONFIG_IR_REDRAT3=m ++CONFIG_IR_STREAMZAP=m ++CONFIG_IR_IGUANA=m ++CONFIG_IR_TTUSBIR=m ++CONFIG_RC_LOOPBACK=m ++CONFIG_IR_GPIO_CIR=m ++CONFIG_IR_GPIO_TX=m ++CONFIG_IR_PWM_TX=m + CONFIG_MEDIA_SUPPORT=m + CONFIG_MEDIA_CAMERA_SUPPORT=y + CONFIG_MEDIA_ANALOG_TV_SUPPORT=y +@@ -797,7 +842,40 @@ CONFIG_VIDEO_GO7007=m + CONFIG_VIDEO_GO7007_USB=m + CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m + CONFIG_VIDEO_AU0828=m ++CONFIG_VIDEO_AU0828_RC=y ++CONFIG_VIDEO_CX231XX=m ++CONFIG_VIDEO_CX231XX_ALSA=m ++CONFIG_VIDEO_CX231XX_DVB=m ++CONFIG_VIDEO_TM6000=m ++CONFIG_VIDEO_TM6000_ALSA=m ++CONFIG_VIDEO_TM6000_DVB=m ++CONFIG_DVB_USB=m ++CONFIG_DVB_USB_A800=m ++CONFIG_DVB_USB_DIBUSB_MB=m ++CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y ++CONFIG_DVB_USB_DIBUSB_MC=m ++CONFIG_DVB_USB_DIB0700=m ++CONFIG_DVB_USB_UMT_010=m ++CONFIG_DVB_USB_CXUSB=m ++CONFIG_DVB_USB_M920X=m ++CONFIG_DVB_USB_DIGITV=m ++CONFIG_DVB_USB_VP7045=m ++CONFIG_DVB_USB_VP702X=m ++CONFIG_DVB_USB_GP8PSK=m ++CONFIG_DVB_USB_NOVA_T_USB2=m ++CONFIG_DVB_USB_TTUSB2=m ++CONFIG_DVB_USB_DTT200U=m ++CONFIG_DVB_USB_OPERA1=m ++CONFIG_DVB_USB_AF9005=m ++CONFIG_DVB_USB_AF9005_REMOTE=m ++CONFIG_DVB_USB_PCTV452E=m ++CONFIG_DVB_USB_DW2102=m ++CONFIG_DVB_USB_CINERGY_T2=m ++CONFIG_DVB_USB_DTV5100=m ++CONFIG_DVB_USB_AZ6027=m ++CONFIG_DVB_USB_TECHNISAT_USB2=m + CONFIG_DVB_USB_V2=m ++CONFIG_DVB_USB_AF9015=m + CONFIG_DVB_USB_AF9035=m + CONFIG_DVB_USB_ANYSEE=m + CONFIG_DVB_USB_AU6610=m +@@ -805,7 +883,9 @@ CONFIG_DVB_USB_AZ6007=m + CONFIG_DVB_USB_CE6230=m + CONFIG_DVB_USB_EC168=m + CONFIG_DVB_USB_GL861=m ++CONFIG_DVB_USB_LME2510=m + CONFIG_DVB_USB_MXL111SF=m ++CONFIG_DVB_USB_RTL28XXU=m + CONFIG_DVB_USB_DVBSKY=m + CONFIG_SMS_USB_DRV=m + CONFIG_DVB_B2C2_FLEXCOP_USB=m +@@ -900,9 +980,11 @@ CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m + CONFIG_SND_BCM2708_SOC_IQAUDIO_CODEC=m + CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m + CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m ++CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m + CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m + CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m + CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m ++CONFIG_SND_AUDIOSENSE_PI=m + CONFIG_SND_DIGIDAC1_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m +@@ -913,10 +995,14 @@ CONFIG_SND_BCM2708_SOC_ALLO_DIGIONE=m + CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC=m + CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m + CONFIG_SND_PISOUND=m ++CONFIG_SND_SOC_AD193X_SPI=m ++CONFIG_SND_SOC_AD193X_I2C=m + CONFIG_SND_SOC_ADAU1701=m + CONFIG_SND_SOC_ADAU7002=m + CONFIG_SND_SOC_AK4554=m ++CONFIG_SND_SOC_CS4265=m + CONFIG_SND_SOC_CS4271_I2C=m ++CONFIG_SND_SOC_ICS43432=m + CONFIG_SND_SOC_SPDIF=m + CONFIG_SND_SOC_WM8804_I2C=m + CONFIG_SND_SIMPLE_CARD=m +@@ -929,6 +1015,7 @@ CONFIG_HID_APPLE=m + CONFIG_HID_ASUS=m + CONFIG_HID_BELKIN=m + CONFIG_HID_BETOP_FF=m ++CONFIG_HID_BIGBEN_FF=m + CONFIG_HID_CHERRY=m + CONFIG_HID_CHICONY=m + CONFIG_HID_CYPRESS=m +@@ -986,6 +1073,7 @@ CONFIG_USB_XHCI_HCD=y + CONFIG_USB_XHCI_PLATFORM=y + CONFIG_USB_DWCOTG=y + CONFIG_USB_PRINTER=m ++CONFIG_USB_TMC=m + CONFIG_USB_STORAGE=y + CONFIG_USB_STORAGE_REALTEK=m + CONFIG_USB_STORAGE_DATAFAB=m +@@ -1006,6 +1094,7 @@ CONFIG_USB_MICROTEK=m + CONFIG_USBIP_CORE=m + CONFIG_USBIP_VHCI_HCD=m + CONFIG_USBIP_HOST=m ++CONFIG_USBIP_VUDC=m + CONFIG_USB_DWC2=m + CONFIG_USB_SERIAL=m + CONFIG_USB_SERIAL_GENERIC=y +@@ -1122,6 +1211,8 @@ CONFIG_MMC_SDHCI_IPROC=y + CONFIG_MMC_SPI=m + CONFIG_LEDS_CLASS=y + CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_PCA963X=m ++CONFIG_LEDS_IS31FL32XX=m + CONFIG_LEDS_TRIGGER_TIMER=y + CONFIG_LEDS_TRIGGER_ONESHOT=y + CONFIG_LEDS_TRIGGER_HEARTBEAT=y +@@ -1133,6 +1224,7 @@ CONFIG_LEDS_TRIGGER_TRANSIENT=m + CONFIG_LEDS_TRIGGER_CAMERA=m + CONFIG_LEDS_TRIGGER_INPUT=y + CONFIG_LEDS_TRIGGER_PANIC=y ++CONFIG_LEDS_TRIGGER_NETDEV=m + CONFIG_RTC_CLASS=y + # CONFIG_RTC_HCTOSYS is not set + CONFIG_RTC_DRV_ABX80X=m +@@ -1154,6 +1246,7 @@ CONFIG_RTC_DRV_FM3130=m + CONFIG_RTC_DRV_RX8581=m + CONFIG_RTC_DRV_RX8025=m + CONFIG_RTC_DRV_EM3027=m ++CONFIG_RTC_DRV_RV3028=m + CONFIG_RTC_DRV_M41T93=m + CONFIG_RTC_DRV_M41T94=m + CONFIG_RTC_DRV_DS1302=m +@@ -1170,6 +1263,8 @@ CONFIG_RTC_DRV_RV3029C2=m + CONFIG_DMADEVICES=y + CONFIG_DMA_BCM2835=y + CONFIG_DMA_BCM2708=y ++CONFIG_AUXDISPLAY=y ++CONFIG_HD44780=m + CONFIG_UIO=m + CONFIG_UIO_PDRV_GENIRQ=m + CONFIG_STAGING=y +@@ -1198,6 +1293,7 @@ CONFIG_FB_TFT_PCD8544=m + CONFIG_FB_TFT_RA8875=m + CONFIG_FB_TFT_S6D02A1=m + CONFIG_FB_TFT_S6D1121=m ++CONFIG_FB_TFT_SH1106=m + CONFIG_FB_TFT_SSD1289=m + CONFIG_FB_TFT_SSD1306=m + CONFIG_FB_TFT_SSD1331=m +@@ -1229,6 +1325,7 @@ CONFIG_MCP3422=m + CONFIG_DHT11=m + CONFIG_HDC100X=m + CONFIG_HTU21=m ++CONFIG_INV_MPU6050_I2C=m + CONFIG_TSL4531=m + CONFIG_VEML6070=m + CONFIG_BMP280=m diff --git a/target/linux/brcm2708/patches-4.19/950-0650-bcm2835-dma-Add-proper-40-bit-DMA-support.patch b/target/linux/brcm2708/patches-4.19/950-0650-bcm2835-dma-Add-proper-40-bit-DMA-support.patch deleted file mode 100644 index 0f50f33529..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0650-bcm2835-dma-Add-proper-40-bit-DMA-support.patch +++ /dev/null @@ -1,1018 +0,0 @@ -From 511ed7aad02f375c8a5cc3c847e6b5fc4bf4a620 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 4 Apr 2019 13:33:47 +0100 -Subject: [PATCH 650/703] bcm2835-dma: Add proper 40-bit DMA support - -The 40-bit additions are not fully tested, but it should be -capable of supporting both 40-bit memcpy on BCM2711 and regular -Lite channels on BCM2835. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2838.dtsi | 33 +- - drivers/dma/bcm2835-dma.c | 426 ++++++++++++++----- - drivers/pci/controller/pcie-brcmstb-bounce.c | 30 +- - drivers/pci/controller/pcie-brcmstb-bounce.h | 21 +- - drivers/pci/controller/pcie-brcmstb.c | 23 +- - 5 files changed, 395 insertions(+), 138 deletions(-) - ---- a/arch/arm/boot/dts/bcm2838.dtsi -+++ b/arch/arm/boot/dts/bcm2838.dtsi -@@ -372,6 +372,23 @@ - }; - }; - -+ dma40: dma@7e007b00 { -+ compatible = "brcm,bcm2838-dma"; -+ reg = <0x0 0x7e007b00 0x400>; -+ interrupts = -+ , /* dma4 11 */ -+ , /* dma4 12 */ -+ , /* dma4 13 */ -+ ; /* dma4 14 */ -+ interrupt-names = "dma11", -+ "dma12", -+ "dma13", -+ "dma14"; -+ #dma-cells = <1>; -+ brcm,dma-channel-mask = <0x7000>; -+ }; -+ /* DMA4 - 40 bit DMA engines */ -+ - xhci: xhci@7e9c0000 { - compatible = "generic-xhci"; - status = "disabled"; -@@ -689,6 +706,7 @@ - }; - - &dma { -+ reg = <0x7e007000 0xb00>; - interrupts = , - , - , -@@ -699,12 +717,7 @@ - , /* dmalite 7 */ - , /* dmalite 8 */ - , /* dmalite 9 */ -- , /* dmalite 10 */ -- /* DMA4 - 40 bit DMA engines */ -- , /* dma4 11 */ -- , /* dma4 12 */ -- , /* dma4 13 */ -- ; /* dma4 14 */ -+ ; /* dmalite 10 */ - interrupt-names = "dma0", - "dma1", - "dma2", -@@ -715,10 +728,6 @@ - "dma7", - "dma8", - "dma9", -- "dma10", -- "dma11", -- "dma12", -- "dma13", -- "dma14"; -- brcm,dma-channel-mask = <0x7ef5>; -+ "dma10"; -+ brcm,dma-channel-mask = <0x01f5>; - }; ---- a/drivers/dma/bcm2835-dma.c -+++ b/drivers/dma/bcm2835-dma.c -@@ -50,12 +50,18 @@ - #define BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED 14 - #define BCM2835_DMA_CHAN_NAME_SIZE 8 - #define BCM2835_DMA_BULK_MASK BIT(0) -+#define BCM2838_DMA_MEMCPY_CHAN 14 -+ -+struct bcm2835_dma_cfg_data { -+ u32 chan_40bit_mask; -+}; - - struct bcm2835_dmadev { - struct dma_device ddev; - spinlock_t lock; - void __iomem *base; - struct device_dma_parameters dma_parms; -+ const struct bcm2835_dma_cfg_data *cfg_data; - }; - - struct bcm2835_dma_cb { -@@ -100,6 +106,7 @@ struct bcm2835_chan { - unsigned int irq_flags; - - bool is_lite_channel; -+ bool is_40bit_channel; - }; - - struct bcm2835_desc { -@@ -189,7 +196,8 @@ struct bcm2835_desc { - #define BCM2835_DMA_DATA_TYPE_S128 16 - - /* Valid only for channels 0 - 14, 15 has its own base address */ --#define BCM2835_DMA_CHAN(n) ((n) << 8) /* Base address */ -+#define BCM2835_DMA_CHAN_SIZE 0x100 -+#define BCM2835_DMA_CHAN(n) ((n) * BCM2835_DMA_CHAN_SIZE) /* Base address */ - #define BCM2835_DMA_CHANIO(base, n) ((base) + BCM2835_DMA_CHAN(n)) - - /* the max dma length for different channels */ -@@ -200,7 +208,7 @@ struct bcm2835_desc { - #define BCM2838_DMA40_CS 0x00 - #define BCM2838_DMA40_CB 0x04 - #define BCM2838_DMA40_DEBUG 0x0c --#define BCM2858_DMA40_TI 0x10 -+#define BCM2838_DMA40_TI 0x10 - #define BCM2838_DMA40_SRC 0x14 - #define BCM2838_DMA40_SRCI 0x18 - #define BCM2838_DMA40_DEST 0x1c -@@ -209,32 +217,97 @@ struct bcm2835_desc { - #define BCM2838_DMA40_NEXT_CB 0x28 - #define BCM2838_DMA40_DEBUG2 0x2c - --#define BCM2838_DMA40_CS_ACTIVE BIT(0) --#define BCM2838_DMA40_CS_END BIT(1) -+#define BCM2838_DMA40_ACTIVE BIT(0) -+#define BCM2838_DMA40_END BIT(1) -+#define BCM2838_DMA40_INT BIT(2) -+#define BCM2838_DMA40_DREQ BIT(3) /* DREQ state */ -+#define BCM2838_DMA40_RD_PAUSED BIT(4) /* Reading is paused */ -+#define BCM2838_DMA40_WR_PAUSED BIT(5) /* Writing is paused */ -+#define BCM2838_DMA40_DREQ_PAUSED BIT(6) /* Is paused by DREQ flow control */ -+#define BCM2838_DMA40_WAITING_FOR_WRITES BIT(7) /* Waiting for last write */ -+#define BCM2838_DMA40_ERR BIT(10) -+#define BCM2838_DMA40_QOS(x) (((x) & 0x1f) << 16) -+#define BCM2838_DMA40_PANIC_QOS(x) (((x) & 0x1f) << 20) -+#define BCM2838_DMA40_WAIT_FOR_WRITES BIT(28) -+#define BCM2838_DMA40_DISDEBUG BIT(29) -+#define BCM2838_DMA40_ABORT BIT(30) -+#define BCM2838_DMA40_HALT BIT(31) -+#define BCM2838_DMA40_CS_FLAGS(x) (x & (BCM2838_DMA40_QOS(15) | \ -+ BCM2838_DMA40_PANIC_QOS(15) | \ -+ BCM2838_DMA40_WAIT_FOR_WRITES | \ -+ BCM2838_DMA40_DISDEBUG)) -+ -+/* Transfer information bits */ -+#define BCM2838_DMA40_INTEN BIT(0) -+#define BCM2838_DMA40_TDMODE BIT(1) /* 2D-Mode */ -+#define BCM2838_DMA40_WAIT_RESP BIT(2) /* wait for AXI write to be acked */ -+#define BCM2838_DMA40_WAIT_RD_RESP BIT(3) /* wait for AXI read to complete */ -+#define BCM2838_DMA40_PER_MAP(x) ((x & 31) << 9) /* REQ source */ -+#define BCM2838_DMA40_S_DREQ BIT(14) /* enable SREQ for source */ -+#define BCM2838_DMA40_D_DREQ BIT(15) /* enable DREQ for destination */ -+#define BCM2838_DMA40_S_WAIT(x) ((x & 0xff) << 16) /* add DMA read-wait cycles */ -+#define BCM2838_DMA40_D_WAIT(x) ((x & 0xff) << 24) /* add DMA write-wait cycles */ - --#define BCM2838_DMA40_CS_QOS(x) (((x) & 0x1f) << 16) --#define BCM2838_DMA40_CS_PANIC_QOS(x) (((x) & 0x1f) << 20) --#define BCM2838_DMA40_CS_WRITE_WAIT BIT(28) -+/* debug register bits */ -+#define BCM2838_DMA40_DEBUG_WRITE_ERR BIT(0) -+#define BCM2838_DMA40_DEBUG_FIFO_ERR BIT(1) -+#define BCM2838_DMA40_DEBUG_READ_ERR BIT(2) -+#define BCM2838_DMA40_DEBUG_READ_CB_ERR BIT(3) -+#define BCM2838_DMA40_DEBUG_IN_ON_ERR BIT(8) -+#define BCM2838_DMA40_DEBUG_ABORT_ON_ERR BIT(9) -+#define BCM2838_DMA40_DEBUG_HALT_ON_ERR BIT(10) -+#define BCM2838_DMA40_DEBUG_DISABLE_CLK_GATE BIT(11) -+#define BCM2838_DMA40_DEBUG_RSTATE_SHIFT 14 -+#define BCM2838_DMA40_DEBUG_RSTATE_BITS 4 -+#define BCM2838_DMA40_DEBUG_WSTATE_SHIFT 18 -+#define BCM2838_DMA40_DEBUG_WSTATE_BITS 4 -+#define BCM2838_DMA40_DEBUG_RESET BIT(23) -+#define BCM2838_DMA40_DEBUG_ID_SHIFT 24 -+#define BCM2838_DMA40_DEBUG_ID_BITS 4 -+#define BCM2838_DMA40_DEBUG_VERSION_SHIFT 28 -+#define BCM2838_DMA40_DEBUG_VERSION_BITS 4 -+ -+/* Valid only for channels 0 - 3 (11 - 14) */ -+#define BCM2838_DMA40_CHAN(n) (((n) + 11) << 8) /* Base address */ -+#define BCM2838_DMA40_CHANIO(base, n) ((base) + BCM2838_DMA_CHAN(n)) - --#define BCM2838_DMA40_BURST_LEN(x) ((((x) - 1) & 0xf) << 8) --#define BCM2838_DMA40_INC BIT(12) --#define BCM2838_DMA40_SIZE_128 (2 << 13) -+/* the max dma length for different channels */ -+#define MAX_DMA40_LEN SZ_1G - --#define BCM2838_DMA40_MEMCPY_QOS \ -- (BCM2838_DMA40_CS_QOS(0x0) | \ -- BCM2838_DMA40_CS_PANIC_QOS(0x0) | \ -- BCM2838_DMA40_CS_WRITE_WAIT) -+#define BCM2838_DMA40_BURST_LEN(x) ((min(x,16) - 1) << 8) -+#define BCM2838_DMA40_INC BIT(12) -+#define BCM2838_DMA40_SIZE_32 (0 << 13) -+#define BCM2838_DMA40_SIZE_64 (1 << 13) -+#define BCM2838_DMA40_SIZE_128 (2 << 13) -+#define BCM2838_DMA40_SIZE_256 (3 << 13) -+#define BCM2838_DMA40_IGNORE BIT(15) -+#define BCM2838_DMA40_STRIDE(x) ((x) << 16) /* For 2D mode */ -+ -+#define BCM2838_DMA40_MEMCPY_FLAGS \ -+ (BCM2838_DMA40_QOS(0) | \ -+ BCM2838_DMA40_PANIC_QOS(0) | \ -+ BCM2838_DMA40_WAIT_FOR_WRITES | \ -+ BCM2838_DMA40_DISDEBUG) - - #define BCM2838_DMA40_MEMCPY_XFER_INFO \ - (BCM2838_DMA40_SIZE_128 | \ - BCM2838_DMA40_INC | \ - BCM2838_DMA40_BURST_LEN(16)) - -+struct bcm2835_dmadev *memcpy_parent; - static void __iomem *memcpy_chan; - static struct bcm2838_dma40_scb *memcpy_scb; - static dma_addr_t memcpy_scb_dma; - DEFINE_SPINLOCK(memcpy_lock); - -+static const struct bcm2835_dma_cfg_data bcm2835_dma_cfg = { -+ .chan_40bit_mask = 0, -+}; -+ -+static const struct bcm2835_dma_cfg_data bcm2838_dma_cfg = { -+ .chan_40bit_mask = BIT(11) | BIT(12) | BIT(13) | BIT(14), -+}; -+ - static inline size_t bcm2835_dma_max_frame_length(struct bcm2835_chan *c) - { - /* lite and normal channels have different max frame length */ -@@ -264,6 +337,32 @@ static inline struct bcm2835_desc *to_bc - return container_of(t, struct bcm2835_desc, vd.tx); - } - -+static inline uint32_t to_bcm2838_ti(uint32_t info) -+{ -+ return ((info & BCM2835_DMA_INT_EN) ? BCM2838_DMA40_INTEN : 0) | -+ ((info & BCM2835_DMA_WAIT_RESP) ? BCM2838_DMA40_WAIT_RESP : 0) | -+ ((info & BCM2835_DMA_S_DREQ) ? -+ (BCM2838_DMA40_S_DREQ | BCM2838_DMA40_WAIT_RD_RESP) : 0) | -+ ((info & BCM2835_DMA_D_DREQ) ? BCM2838_DMA40_D_DREQ : 0) | -+ BCM2838_DMA40_PER_MAP((info >> 16) & 0x1f); -+} -+ -+static inline uint32_t to_bcm2838_srci(uint32_t info) -+{ -+ return ((info & BCM2835_DMA_S_INC) ? BCM2838_DMA40_INC : 0); -+} -+ -+static inline uint32_t to_bcm2838_dsti(uint32_t info) -+{ -+ return ((info & BCM2835_DMA_D_INC) ? BCM2838_DMA40_INC : 0); -+} -+ -+static inline uint32_t to_bcm2838_cbaddr(dma_addr_t addr) -+{ -+ BUG_ON(addr & 0x1f); -+ return (addr >> 5); -+} -+ - static void bcm2835_dma_free_cb_chain(struct bcm2835_desc *desc) - { - size_t i; -@@ -282,45 +381,53 @@ static void bcm2835_dma_desc_free(struct - } - - static void bcm2835_dma_create_cb_set_length( -- struct bcm2835_chan *chan, -+ struct bcm2835_chan *c, - struct bcm2835_dma_cb *control_block, - size_t len, - size_t period_len, - size_t *total_len, - u32 finalextrainfo) - { -- size_t max_len = bcm2835_dma_max_frame_length(chan); -+ size_t max_len = bcm2835_dma_max_frame_length(c); -+ uint32_t cb_len; - - /* set the length taking lite-channel limitations into account */ -- control_block->length = min_t(u32, len, max_len); -+ cb_len = min_t(u32, len, max_len); - -- /* finished if we have no period_length */ -- if (!period_len) -- return; -+ if (period_len) { -+ /* -+ * period_len means: that we need to generate -+ * transfers that are terminating at every -+ * multiple of period_len - this is typically -+ * used to set the interrupt flag in info -+ * which is required during cyclic transfers -+ */ - -- /* -- * period_len means: that we need to generate -- * transfers that are terminating at every -- * multiple of period_len - this is typically -- * used to set the interrupt flag in info -- * which is required during cyclic transfers -- */ -+ /* have we filled in period_length yet? */ -+ if (*total_len + cb_len < period_len) { -+ /* update number of bytes in this period so far */ -+ *total_len += cb_len; -+ } else { -+ /* calculate the length that remains to reach period_len */ -+ cb_len = period_len - *total_len; - -- /* have we filled in period_length yet? */ -- if (*total_len + control_block->length < period_len) { -- /* update number of bytes in this period so far */ -- *total_len += control_block->length; -- return; -+ /* reset total_length for next period */ -+ *total_len = 0; -+ } - } - -- /* calculate the length that remains to reach period_length */ -- control_block->length = period_len - *total_len; -- -- /* reset total_length for next period */ -- *total_len = 0; -- -- /* add extrainfo bits in info */ -- control_block->info |= finalextrainfo; -+ if (c->is_40bit_channel) { -+ struct bcm2838_dma40_scb *scb = -+ (struct bcm2838_dma40_scb *)control_block; -+ -+ scb->len = cb_len; -+ /* add extrainfo bits to ti */ -+ scb->ti |= to_bcm2838_ti(finalextrainfo); -+ } else { -+ control_block->length = cb_len; -+ /* add extrainfo bits to info */ -+ control_block->info |= finalextrainfo; -+ } - } - - static inline size_t bcm2835_dma_count_frames_for_sg( -@@ -343,7 +450,7 @@ static inline size_t bcm2835_dma_count_f - /** - * bcm2835_dma_create_cb_chain - create a control block and fills data in - * -- * @chan: the @dma_chan for which we run this -+ * @c: the @bcm2835_chan for which we run this - * @direction: the direction in which we transfer - * @cyclic: it is a cyclic transfer - * @info: the default info bits to apply per controlblock -@@ -361,12 +468,11 @@ static inline size_t bcm2835_dma_count_f - * @gfp: the GFP flag to use for allocation - */ - static struct bcm2835_desc *bcm2835_dma_create_cb_chain( -- struct dma_chan *chan, enum dma_transfer_direction direction, -+ struct bcm2835_chan *c, enum dma_transfer_direction direction, - bool cyclic, u32 info, u32 finalextrainfo, size_t frames, - dma_addr_t src, dma_addr_t dst, size_t buf_len, - size_t period_len, gfp_t gfp) - { -- struct bcm2835_chan *c = to_bcm2835_dma_chan(chan); - size_t len = buf_len, total_len; - size_t frame; - struct bcm2835_desc *d; -@@ -399,11 +505,23 @@ static struct bcm2835_desc *bcm2835_dma_ - - /* fill in the control block */ - control_block = cb_entry->cb; -- control_block->info = info; -- control_block->src = src; -- control_block->dst = dst; -- control_block->stride = 0; -- control_block->next = 0; -+ if (c->is_40bit_channel) { -+ struct bcm2838_dma40_scb *scb = -+ (struct bcm2838_dma40_scb *)control_block; -+ scb->ti = to_bcm2838_ti(info); -+ scb->src = lower_32_bits(src); -+ scb->srci= upper_32_bits(src) | to_bcm2838_srci(info); -+ scb->dst = lower_32_bits(dst); -+ scb->dsti = upper_32_bits(dst) | to_bcm2838_dsti(info); -+ scb->next_cb = 0; -+ } else { -+ control_block->info = info; -+ control_block->src = src; -+ control_block->dst = dst; -+ control_block->stride = 0; -+ control_block->next = 0; -+ } -+ - /* set up length in control_block if requested */ - if (buf_len) { - /* calculate length honoring period_length */ -@@ -417,7 +535,10 @@ static struct bcm2835_desc *bcm2835_dma_ - } - - /* link this the last controlblock */ -- if (frame) -+ if (frame && c->is_40bit_channel) -+ d->cb_list[frame - 1].cb->next = -+ to_bcm2838_cbaddr(cb_entry->paddr); -+ if (frame && !c->is_40bit_channel) - d->cb_list[frame - 1].cb->next = cb_entry->paddr; - - /* update src and dst and length */ -@@ -431,7 +552,14 @@ static struct bcm2835_desc *bcm2835_dma_ - } - - /* the last frame requires extra flags */ -- d->cb_list[d->frames - 1].cb->info |= finalextrainfo; -+ if (c->is_40bit_channel) { -+ struct bcm2838_dma40_scb *scb = -+ (struct bcm2838_dma40_scb *)d->cb_list[d->frames-1].cb; -+ -+ scb->ti |= to_bcm2838_ti(finalextrainfo); -+ } else { -+ d->cb_list[d->frames - 1].cb->info |= finalextrainfo; -+ } - - /* detect a size missmatch */ - if (buf_len && (d->size != buf_len)) -@@ -445,28 +573,51 @@ error_cb: - } - - static void bcm2835_dma_fill_cb_chain_with_sg( -- struct dma_chan *chan, -+ struct bcm2835_chan *c, - enum dma_transfer_direction direction, - struct bcm2835_cb_entry *cb, - struct scatterlist *sgl, - unsigned int sg_len) - { -- struct bcm2835_chan *c = to_bcm2835_dma_chan(chan); - size_t len, max_len; - unsigned int i; - dma_addr_t addr; - struct scatterlist *sgent; - -+ pr_err("dma_fill_chain_with_sg(ch %d, dir %d):\n", c->ch, direction); -+ - max_len = bcm2835_dma_max_frame_length(c); - for_each_sg(sgl, sgent, sg_len, i) { -- for (addr = sg_dma_address(sgent), len = sg_dma_len(sgent); -- len > 0; -- addr += cb->cb->length, len -= cb->cb->length, cb++) { -- if (direction == DMA_DEV_TO_MEM) -- cb->cb->dst = addr; -- else -- cb->cb->src = addr; -- cb->cb->length = min(len, max_len); -+ if (c->is_40bit_channel) { -+ struct bcm2838_dma40_scb *scb = -+ (struct bcm2838_dma40_scb *)cb->cb; -+ for (addr = sg_dma_address(sgent), -+ len = sg_dma_len(sgent); -+ len > 0; -+ addr += scb->len, len -= scb->len, scb++) { -+ if (direction == DMA_DEV_TO_MEM) { -+ scb->dst = lower_32_bits(addr); -+ scb->dsti = upper_32_bits(addr) | BCM2838_DMA40_INC; -+ } else { -+ scb->src = lower_32_bits(addr); -+ scb->srci = upper_32_bits(addr) | BCM2838_DMA40_INC; -+ } -+ scb->len = min(len, max_len); -+ pr_err(" %llx, %x\n", (u64)addr, scb->len); -+ } -+ } else { -+ for (addr = sg_dma_address(sgent), -+ len = sg_dma_len(sgent); -+ len > 0; -+ addr += cb->cb->length, len -= cb->cb->length, -+ cb++) { -+ if (direction == DMA_DEV_TO_MEM) -+ cb->cb->dst = addr; -+ else -+ cb->cb->src = addr; -+ cb->cb->length = min(len, max_len); -+ pr_err(" %llx, %x\n", (u64)addr, cb->cb->length); -+ } - } - } - } -@@ -475,6 +626,10 @@ static int bcm2835_dma_abort(struct bcm2 - { - void __iomem *chan_base = c->chan_base; - long int timeout = 10000; -+ u32 wait_mask = BCM2835_DMA_WAITING_FOR_WRITES; -+ -+ if (c->is_40bit_channel) -+ wait_mask = BCM2838_DMA40_WAITING_FOR_WRITES; - - /* - * A zero control block address means the channel is idle. -@@ -487,8 +642,7 @@ static int bcm2835_dma_abort(struct bcm2 - writel(0, chan_base + BCM2835_DMA_CS); - - /* Wait for any current AXI transfer to complete */ -- while ((readl(chan_base + BCM2835_DMA_CS) & -- BCM2835_DMA_WAITING_FOR_WRITES) && --timeout) -+ while ((readl(chan_base + BCM2835_DMA_CS) & wait_mask) && --timeout) - cpu_relax(); - - /* Peripheral might be stuck and fail to signal AXI write responses */ -@@ -505,6 +659,7 @@ static void bcm2835_dma_start_desc(struc - struct virt_dma_desc *vd = vchan_next_desc(&c->vc); - struct bcm2835_desc *d; - -+ pr_err("dma_start_desc(%px)\n", vd); - if (!vd) { - c->desc = NULL; - return; -@@ -514,9 +669,16 @@ static void bcm2835_dma_start_desc(struc - - c->desc = d = to_bcm2835_dma_desc(&vd->tx); - -- writel(d->cb_list[0].paddr, c->chan_base + BCM2835_DMA_ADDR); -- writel(BCM2835_DMA_ACTIVE | BCM2835_DMA_CS_FLAGS(c->dreq), -- c->chan_base + BCM2835_DMA_CS); -+ if (c->is_40bit_channel) { -+ writel(to_bcm2838_cbaddr(d->cb_list[0].paddr), -+ c->chan_base + BCM2838_DMA40_CB); -+ writel(BCM2838_DMA40_ACTIVE | BCM2838_DMA40_CS_FLAGS(c->dreq), -+ c->chan_base + BCM2838_DMA40_CS); -+ } else { -+ writel(d->cb_list[0].paddr, c->chan_base + BCM2835_DMA_ADDR); -+ writel(BCM2835_DMA_ACTIVE | BCM2835_DMA_CS_FLAGS(c->dreq), -+ c->chan_base + BCM2835_DMA_CS); -+ } - } - - static irqreturn_t bcm2835_dma_callback(int irq, void *data) -@@ -544,7 +706,8 @@ static irqreturn_t bcm2835_dma_callback( - * will remain idle despite the ACTIVE flag being set. - */ - writel(BCM2835_DMA_INT | BCM2835_DMA_ACTIVE | -- BCM2835_DMA_CS_FLAGS(c->dreq), -+ (c->is_40bit_channel ? BCM2838_DMA40_CS_FLAGS(c->dreq) : -+ BCM2835_DMA_CS_FLAGS(c->dreq)), - c->chan_base + BCM2835_DMA_CS); - - d = c->desc; -@@ -643,9 +806,17 @@ static enum dma_status bcm2835_dma_tx_st - struct bcm2835_desc *d = c->desc; - dma_addr_t pos; - -- if (d->dir == DMA_MEM_TO_DEV) -+ if (d->dir == DMA_MEM_TO_DEV && c->is_40bit_channel) -+ pos = readl(c->chan_base + BCM2838_DMA40_SRC) + -+ ((readl(c->chan_base + BCM2838_DMA40_SRCI) & -+ 0xff) << 8); -+ else if (d->dir == DMA_MEM_TO_DEV && !c->is_40bit_channel) - pos = readl(c->chan_base + BCM2835_DMA_SOURCE_AD); -- else if (d->dir == DMA_DEV_TO_MEM) -+ else if (d->dir == DMA_DEV_TO_MEM && c->is_40bit_channel) -+ pos = readl(c->chan_base + BCM2838_DMA40_DEST) + -+ ((readl(c->chan_base + BCM2838_DMA40_DESTI) & -+ 0xff) << 8); -+ else if (d->dir == DMA_DEV_TO_MEM && !c->is_40bit_channel) - pos = readl(c->chan_base + BCM2835_DMA_DEST_AD); - else - pos = 0; -@@ -691,7 +862,7 @@ static struct dma_async_tx_descriptor *b - frames = bcm2835_dma_frames_for_length(len, max_len); - - /* allocate the CB chain - this also fills in the pointers */ -- d = bcm2835_dma_create_cb_chain(chan, DMA_MEM_TO_MEM, false, -+ d = bcm2835_dma_create_cb_chain(c, DMA_MEM_TO_MEM, false, - info, extra, frames, - src, dst, len, 0, GFP_KERNEL); - if (!d) -@@ -726,11 +897,21 @@ static struct dma_async_tx_descriptor *b - if (c->cfg.src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES) - return NULL; - src = c->cfg.src_addr; -+ /* -+ * One would think it ought to be possible to get the physical -+ * to dma address mapping information from the dma-ranges DT -+ * property, but I've not found a way yet that doesn't involve -+ * open-coding the whole thing. -+ */ -+ if (c->is_40bit_channel) -+ src |= 0x400000000ull; - info |= BCM2835_DMA_S_DREQ | BCM2835_DMA_D_INC; - } else { - if (c->cfg.dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES) - return NULL; - dst = c->cfg.dst_addr; -+ if (c->is_40bit_channel) -+ dst |= 0x400000000ull; - info |= BCM2835_DMA_D_DREQ | BCM2835_DMA_S_INC; - } - -@@ -738,7 +919,7 @@ static struct dma_async_tx_descriptor *b - frames = bcm2835_dma_count_frames_for_sg(c, sgl, sg_len); - - /* allocate the CB chain */ -- d = bcm2835_dma_create_cb_chain(chan, direction, false, -+ d = bcm2835_dma_create_cb_chain(c, direction, false, - info, extra, - frames, src, dst, 0, 0, - GFP_KERNEL); -@@ -746,7 +927,7 @@ static struct dma_async_tx_descriptor *b - return NULL; - - /* fill in frames with scatterlist pointers */ -- bcm2835_dma_fill_cb_chain_with_sg(chan, direction, d->cb_list, -+ bcm2835_dma_fill_cb_chain_with_sg(c, direction, d->cb_list, - sgl, sg_len); - - return vchan_tx_prep(&c->vc, &d->vd, flags); -@@ -815,7 +996,7 @@ static struct dma_async_tx_descriptor *b - * note that we need to use GFP_NOWAIT, as the ALSA i2s dmaengine - * implementation calls prep_dma_cyclic with interrupts disabled. - */ -- d = bcm2835_dma_create_cb_chain(chan, direction, true, -+ d = bcm2835_dma_create_cb_chain(c, direction, true, - info, extra, - frames, src, dst, buf_len, - period_len, GFP_NOWAIT); -@@ -823,7 +1004,8 @@ static struct dma_async_tx_descriptor *b - return NULL; - - /* wrap around into a loop */ -- d->cb_list[d->frames - 1].cb->next = d->cb_list[0].paddr; -+ d->cb_list[d->frames - 1].cb->next = c->is_40bit_channel ? -+ to_bcm2838_cbaddr(d->cb_list[0].paddr) : d->cb_list[0].paddr; - - return vchan_tx_prep(&c->vc, &d->vd, flags); - } -@@ -899,9 +1081,11 @@ static int bcm2835_dma_chan_init(struct - c->irq_number = irq; - c->irq_flags = irq_flags; - -- /* check in DEBUG register if this is a LITE channel */ -- if (readl(c->chan_base + BCM2835_DMA_DEBUG) & -- BCM2835_DMA_DEBUG_LITE) -+ /* check for 40bit and lite channels */ -+ if (d->cfg_data->chan_40bit_mask & BIT(chan_id)) -+ c->is_40bit_channel = true; -+ else if (readl(c->chan_base + BCM2835_DMA_DEBUG) & -+ BCM2835_DMA_DEBUG_LITE) - c->is_lite_channel = true; - - return 0; -@@ -918,18 +1102,16 @@ static void bcm2835_dma_free(struct bcm2 - } - } - --int bcm2838_dma40_memcpy_init(struct device *dev) -+int bcm2838_dma40_memcpy_init(void) - { -- if (memcpy_scb) -- return 0; -+ if (!memcpy_parent) -+ return -EPROBE_DEFER; - -- memcpy_scb = dma_alloc_coherent(dev, sizeof(*memcpy_scb), -- &memcpy_scb_dma, GFP_KERNEL); -+ if (!memcpy_chan) -+ return -EINVAL; - -- if (!memcpy_scb) { -- pr_err("bcm2838_dma40_memcpy_init failed!\n"); -+ if (!memcpy_scb) - return -ENOMEM; -- } - - return 0; - } -@@ -956,20 +1138,22 @@ void bcm2838_dma40_memcpy(dma_addr_t dst - scb->next_cb = 0; - - writel((u32)(memcpy_scb_dma >> 5), memcpy_chan + BCM2838_DMA40_CB); -- writel(BCM2838_DMA40_MEMCPY_QOS + BCM2838_DMA40_CS_ACTIVE, -+ writel(BCM2838_DMA40_MEMCPY_FLAGS + BCM2838_DMA40_ACTIVE, - memcpy_chan + BCM2838_DMA40_CS); -+ - /* Poll for completion */ -- while (!(readl(memcpy_chan + BCM2838_DMA40_CS) & BCM2838_DMA40_CS_END)) -+ while (!(readl(memcpy_chan + BCM2838_DMA40_CS) & BCM2838_DMA40_END)) - cpu_relax(); - -- writel(BCM2838_DMA40_CS_END, memcpy_chan + BCM2838_DMA40_CS); -+ writel(BCM2838_DMA40_END, memcpy_chan + BCM2838_DMA40_CS); - - spin_unlock_irqrestore(&memcpy_lock, flags); - } - EXPORT_SYMBOL(bcm2838_dma40_memcpy); - - static const struct of_device_id bcm2835_dma_of_match[] = { -- { .compatible = "brcm,bcm2835-dma", }, -+ { .compatible = "brcm,bcm2835-dma", .data = &bcm2835_dma_cfg }, -+ { .compatible = "brcm,bcm2838-dma", .data = &bcm2838_dma_cfg }, - {}, - }; - MODULE_DEVICE_TABLE(of, bcm2835_dma_of_match); -@@ -1001,6 +1185,8 @@ static int bcm2835_dma_probe(struct plat - int irq_flags; - uint32_t chans_available; - char chan_name[BCM2835_DMA_CHAN_NAME_SIZE]; -+ const struct of_device_id *of_id; -+ int chan_count, chan_start, chan_end; - - if (!pdev->dev.dma_mask) - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; -@@ -1020,9 +1206,13 @@ static int bcm2835_dma_probe(struct plat - base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(base)) - return PTR_ERR(base); -- rc = bcm_dmaman_probe(pdev, base, BCM2835_DMA_BULK_MASK); -- if (rc) -- dev_err(&pdev->dev, "Failed to initialize the legacy API\n"); -+ -+ /* The set of channels can be split across multiple instances. */ -+ chan_start = ((u32)base / BCM2835_DMA_CHAN_SIZE) & 0xf; -+ base -= BCM2835_DMA_CHAN(chan_start); -+ chan_count = resource_size(res) / BCM2835_DMA_CHAN_SIZE; -+ chan_end = min(chan_start + chan_count, -+ BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED + 1); - - od->base = base; - -@@ -1052,6 +1242,14 @@ static int bcm2835_dma_probe(struct plat - - platform_set_drvdata(pdev, od); - -+ of_id = of_match_node(bcm2835_dma_of_match, pdev->dev.of_node); -+ if (!of_id) { -+ dev_err(&pdev->dev, "Failed to match compatible string\n"); -+ return -EINVAL; -+ } -+ -+ od->cfg_data = of_id->data; -+ - /* Request DMA channel mask from device tree */ - if (of_property_read_u32(pdev->dev.of_node, - "brcm,dma-channel-mask", -@@ -1061,18 +1259,34 @@ static int bcm2835_dma_probe(struct plat - goto err_no_dma; - } - -- /* Channel 0 is used by the legacy API */ -- chans_available &= ~BCM2835_DMA_BULK_MASK; -+ /* One channel is reserved for the legacy API */ -+ if (chans_available & BCM2835_DMA_BULK_MASK) { -+ rc = bcm_dmaman_probe(pdev, base, -+ chans_available & BCM2835_DMA_BULK_MASK); -+ if (rc) -+ dev_err(&pdev->dev, -+ "Failed to initialize the legacy API\n"); -+ -+ chans_available &= ~BCM2835_DMA_BULK_MASK; -+ } - -- /* We can't use channels 11-13 yet */ -- chans_available &= ~(BIT(11) | BIT(12) | BIT(13)); -+ /* And possibly one for the 40-bit DMA memcpy API */ -+ if (chans_available & od->cfg_data->chan_40bit_mask & -+ BIT(BCM2838_DMA_MEMCPY_CHAN)) { -+ memcpy_parent = od; -+ memcpy_chan = BCM2835_DMA_CHANIO(base, BCM2838_DMA_MEMCPY_CHAN); -+ memcpy_scb = dma_alloc_coherent(memcpy_parent->ddev.dev, -+ sizeof(*memcpy_scb), -+ &memcpy_scb_dma, GFP_KERNEL); -+ if (!memcpy_scb) -+ dev_warn(&pdev->dev, -+ "Failed to allocated memcpy scb\n"); - -- /* Grab channel 14 for the 40-bit DMA memcpy */ -- chans_available &= ~BIT(14); -- memcpy_chan = BCM2835_DMA_CHANIO(base, 14); -+ chans_available &= ~BIT(BCM2838_DMA_MEMCPY_CHAN); -+ } - - /* get irqs for each channel that we support */ -- for (i = 0; i <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; i++) { -+ for (i = chan_start; i < chan_end; i++) { - /* skip masked out channels */ - if (!(chans_available & (1 << i))) { - irq[i] = -1; -@@ -1095,13 +1309,17 @@ static int bcm2835_dma_probe(struct plat - irq[i] = platform_get_irq(pdev, i < 11 ? i : 11); - } - -+ chan_count = 0; -+ - /* get irqs for each channel */ -- for (i = 0; i <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; i++) { -+ for (i = chan_start; i < chan_end; i++) { - /* skip channels without irq */ - if (irq[i] < 0) - continue; - - /* check if there are other channels that also use this irq */ -+ /* FIXME: This will fail if interrupts are shared across -+ instances */ - irq_flags = 0; - for (j = 0; j <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; j++) - if ((i != j) && (irq[j] == irq[i])) { -@@ -1113,9 +1331,10 @@ static int bcm2835_dma_probe(struct plat - rc = bcm2835_dma_chan_init(od, i, irq[i], irq_flags); - if (rc) - goto err_no_dma; -+ chan_count++; - } - -- dev_dbg(&pdev->dev, "Initialized %i DMA channels\n", i); -+ dev_dbg(&pdev->dev, "Initialized %i DMA channels\n", chan_count); - - /* Device-tree DMA controller registration */ - rc = of_dma_controller_register(pdev->dev.of_node, -@@ -1147,6 +1366,13 @@ static int bcm2835_dma_remove(struct pla - - bcm_dmaman_remove(pdev); - dma_async_device_unregister(&od->ddev); -+ if (memcpy_parent == od) { -+ dma_free_coherent(&pdev->dev, sizeof(*memcpy_scb), memcpy_scb, -+ memcpy_scb_dma); -+ memcpy_parent = NULL; -+ memcpy_scb = NULL; -+ memcpy_chan = NULL; -+ } - bcm2835_dma_free(od); - - return 0; ---- a/drivers/pci/controller/pcie-brcmstb-bounce.c -+++ b/drivers/pci/controller/pcie-brcmstb-bounce.c -@@ -91,7 +91,7 @@ struct dmabounce_device_info { - - static struct dmabounce_device_info *g_dmabounce_device_info; - --extern int bcm2838_dma40_memcpy_init(struct device *dev); -+extern int bcm2838_dma40_memcpy_init(void); - extern void bcm2838_dma40_memcpy(dma_addr_t dst, dma_addr_t src, size_t size); - - #ifdef STATS -@@ -471,9 +471,9 @@ static const struct dma_map_ops dmabounc - .mapping_error = dmabounce_mapping_error, - }; - --int brcm_pcie_bounce_register_dev(struct device *dev, -- unsigned long buffer_size, -- dma_addr_t threshold) -+int brcm_pcie_bounce_init(struct device *dev, -+ unsigned long buffer_size, -+ dma_addr_t threshold) - { - struct dmabounce_device_info *device_info; - int ret; -@@ -482,9 +482,9 @@ int brcm_pcie_bounce_register_dev(struct - if (g_dmabounce_device_info) - return -EBUSY; - -- ret = bcm2838_dma40_memcpy_init(dev); -+ ret = bcm2838_dma40_memcpy_init(); - if (ret) -- return ret; -+ return ret; - - device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC); - if (!device_info) { -@@ -515,9 +515,8 @@ int brcm_pcie_bounce_register_dev(struct - device_create_file(dev, &dev_attr_dmabounce_stats)); - - g_dmabounce_device_info = device_info; -- set_dma_ops(dev, &dmabounce_ops); - -- dev_info(dev, "dmabounce: registered device - %ld kB, threshold %pad\n", -+ dev_info(dev, "dmabounce: initialised - %ld kB, threshold %pad\n", - buffer_size / 1024, &threshold); - - return 0; -@@ -526,14 +525,13 @@ int brcm_pcie_bounce_register_dev(struct - kfree(device_info); - return ret; - } --EXPORT_SYMBOL(brcm_pcie_bounce_register_dev); -+EXPORT_SYMBOL(brcm_pcie_bounce_init); - --void brcm_pcie_bounce_unregister_dev(struct device *dev) -+void brcm_pcie_bounce_uninit(struct device *dev) - { - struct dmabounce_device_info *device_info = g_dmabounce_device_info; - - g_dmabounce_device_info = NULL; -- set_dma_ops(dev, NULL); - - if (!device_info) { - dev_warn(dev, -@@ -554,10 +552,16 @@ void brcm_pcie_bounce_unregister_dev(str - device_remove_file(dev, &dev_attr_dmabounce_stats)); - - kfree(device_info); -+} -+EXPORT_SYMBOL(brcm_pcie_bounce_uninit); -+ -+int brcm_pcie_bounce_register_dev(struct device *dev) -+{ -+ set_dma_ops(dev, &dmabounce_ops); - -- dev_info(dev, "dmabounce: device unregistered\n"); -+ return 0; - } --EXPORT_SYMBOL(brcm_pcie_bounce_unregister_dev); -+EXPORT_SYMBOL(brcm_pcie_bounce_register_dev); - - MODULE_AUTHOR("Phil Elwell "); - MODULE_DESCRIPTION("Dedicate DMA bounce support for pcie-brcmstb"); ---- a/drivers/pci/controller/pcie-brcmstb-bounce.h -+++ b/drivers/pci/controller/pcie-brcmstb-bounce.h -@@ -8,21 +8,26 @@ - - #ifdef CONFIG_ARM - --int brcm_pcie_bounce_register_dev(struct device *dev, unsigned long buffer_size, -- dma_addr_t threshold); -- --int brcm_pcie_bounce_unregister_dev(struct device *dev); -+int brcm_pcie_bounce_init(struct device *dev, unsigned long buffer_size, -+ dma_addr_t threshold); -+int brcm_pcie_bounce_uninit(struct device *dev); -+int brcm_pcie_bounce_register_dev(struct device *dev); - - #else - --static inline int brcm_pcie_bounce_register_dev(struct device *dev, -- unsigned long buffer_size, -- dma_addr_t threshold) -+static inline int brcm_pcie_bounce_init(struct device *dev, -+ unsigned long buffer_size, -+ dma_addr_t threshold) -+{ -+ return 0; -+} -+ -+static inline int brcm_pcie_bounce_uninit(struct device *dev) - { - return 0; - } - --static inline int brcm_pcie_bounce_unregister_dev(struct device *dev) -+static inline int brcm_pcie_bounce_register_dev(struct device *dev) - { - return 0; - } ---- a/drivers/pci/controller/pcie-brcmstb.c -+++ b/drivers/pci/controller/pcie-brcmstb.c -@@ -650,6 +650,7 @@ static void brcm_set_dma_ops(struct devi - - static inline void brcm_pcie_perst_set(struct brcm_pcie *pcie, - unsigned int val); -+ - static int brcmstb_platform_notifier(struct notifier_block *nb, - unsigned long event, void *__dev) - { -@@ -663,12 +664,11 @@ static int brcmstb_platform_notifier(str - strcmp(dev->kobj.name, rc_name)) { - int ret; - -- ret = brcm_pcie_bounce_register_dev(dev, bounce_buffer, -- (dma_addr_t)bounce_threshold); -+ ret = brcm_pcie_bounce_register_dev(dev); - if (ret) { - dev_err(dev, - "brcm_pcie_bounce_register_dev() failed: %d\n", -- ret); -+ ret); - return ret; - } - } -@@ -681,8 +681,6 @@ static int brcmstb_platform_notifier(str - brcm_pcie_perst_set(g_pcie, 1); - msleep(100); - brcm_pcie_perst_set(g_pcie, 0); -- } else if (max_pfn > (bounce_threshold/PAGE_SIZE)) { -- brcm_pcie_bounce_unregister_dev(dev); - } - return NOTIFY_OK; - -@@ -1718,6 +1716,7 @@ static int brcm_pcie_probe(struct platfo - void __iomem *base; - struct pci_host_bridge *bridge; - struct pci_bus *child; -+ extern unsigned long max_pfn; - - bridge = devm_pci_alloc_host_bridge(&pdev->dev, sizeof(*pcie)); - if (!bridge) -@@ -1753,6 +1752,20 @@ static int brcm_pcie_probe(struct platfo - if (IS_ERR(base)) - return PTR_ERR(base); - -+ /* To Do: Add hardware check if this ever gets fixed */ -+ if (max_pfn > (bounce_threshold/PAGE_SIZE)) { -+ int ret; -+ ret = brcm_pcie_bounce_init(&pdev->dev, bounce_buffer, -+ (dma_addr_t)bounce_threshold); -+ if (ret) { -+ if (ret != -EPROBE_DEFER) -+ dev_err(&pdev->dev, -+ "could not init bounce buffers: %d\n", -+ ret); -+ return ret; -+ } -+ } -+ - pcie->clk = of_clk_get_by_name(dn, "sw_pcie"); - if (IS_ERR(pcie->clk)) { - dev_warn(&pdev->dev, "could not get clock\n"); diff --git a/target/linux/brcm2708/patches-4.19/950-0650-dts-Include-CSI-lane-config-for-csi1.patch b/target/linux/brcm2708/patches-4.19/950-0650-dts-Include-CSI-lane-config-for-csi1.patch new file mode 100644 index 0000000000..eddef8dca1 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0650-dts-Include-CSI-lane-config-for-csi1.patch @@ -0,0 +1,23 @@ +From 8d2aeaf1d4eecfd8b11c2ba5dcf33d228dd76a6a Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 31 May 2019 17:57:26 +0100 +Subject: [PATCH 650/725] dts: Include CSI lane config for csi1 + +Without the include the peripheral is configured to have 0 +data lanes, which doesn't allow much data to be passed. + +Signed-off-by: Dave Stevenson +--- + arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts +@@ -1,6 +1,7 @@ + /dts-v1/; + + #include "bcm2711.dtsi" ++#include "bcm283x-rpi-csi1-2lane.dtsi" + + / { + compatible = "raspberrypi,4-model-b", "brcm,bcm2838", "brcm,bcm2837"; diff --git a/target/linux/brcm2708/patches-4.19/950-0651-BCM270X_DT-Leave-bulk-channel-in-dma-channel-mask.patch b/target/linux/brcm2708/patches-4.19/950-0651-BCM270X_DT-Leave-bulk-channel-in-dma-channel-mask.patch deleted file mode 100644 index cc306b1427..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0651-BCM270X_DT-Leave-bulk-channel-in-dma-channel-mask.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 9f8ebf6f517f48041ccb16b80493537eb8522738 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 5 Jun 2019 21:32:03 +0100 -Subject: [PATCH 651/703] BCM270X_DT: Leave bulk channel in dma channel mask - -The updated bcm2835-dma driver does not require the BULK channel -to be removed from the set of available channels, as provided by -dma-channel-mask. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2708-rpi.dtsi | 4 ---- - 1 file changed, 4 deletions(-) - ---- a/arch/arm/boot/dts/bcm2708-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi.dtsi -@@ -124,10 +124,6 @@ - }; - }; - --&dma { -- brcm,dma-channel-mask = <0x7f34>; --}; -- - &hdmi { - power-domains = <&power RPI_POWER_DOMAIN_HDMI>; - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0651-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch b/target/linux/brcm2708/patches-4.19/950-0651-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch new file mode 100644 index 0000000000..33b96f7c37 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0651-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch @@ -0,0 +1,28 @@ +From cc761034521f5c47193a8c2f6ac48a7961f85761 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 7 Jun 2019 11:31:21 +0100 +Subject: [PATCH 651/725] drm/vc4: Fix T-format modifiers in FKMS. + +The wrong vc_image formats were being checked for in the switch +statement. Correct these. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -458,10 +458,10 @@ static void vc4_plane_atomic_update(stru + switch (fb->modifier) { + case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: + switch (mb->plane.vc_image_type) { +- case VC_IMAGE_RGBX32: ++ case VC_IMAGE_XRGB8888: + mb->plane.vc_image_type = VC_IMAGE_TF_RGBX32; + break; +- case VC_IMAGE_RGBA32: ++ case VC_IMAGE_ARGB8888: + mb->plane.vc_image_type = VC_IMAGE_TF_RGBA32; + break; + case VC_IMAGE_RGB565: diff --git a/target/linux/brcm2708/patches-4.19/950-0652-SQUASH-bcm2835-dma-Remove-debugging.patch b/target/linux/brcm2708/patches-4.19/950-0652-SQUASH-bcm2835-dma-Remove-debugging.patch deleted file mode 100644 index ec2f7c9a1d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0652-SQUASH-bcm2835-dma-Remove-debugging.patch +++ /dev/null @@ -1,45 +0,0 @@ -From b7780ddb8e7f651f247dfccba05bdc75727abc3c Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 6 Jun 2019 09:35:08 +0100 -Subject: [PATCH 652/703] SQUASH: bcm2835-dma: Remove debugging - -Signed-off-by: Phil Elwell ---- - drivers/dma/bcm2835-dma.c | 5 ----- - 1 file changed, 5 deletions(-) - ---- a/drivers/dma/bcm2835-dma.c -+++ b/drivers/dma/bcm2835-dma.c -@@ -584,8 +584,6 @@ static void bcm2835_dma_fill_cb_chain_wi - dma_addr_t addr; - struct scatterlist *sgent; - -- pr_err("dma_fill_chain_with_sg(ch %d, dir %d):\n", c->ch, direction); -- - max_len = bcm2835_dma_max_frame_length(c); - for_each_sg(sgl, sgent, sg_len, i) { - if (c->is_40bit_channel) { -@@ -603,7 +601,6 @@ static void bcm2835_dma_fill_cb_chain_wi - scb->srci = upper_32_bits(addr) | BCM2838_DMA40_INC; - } - scb->len = min(len, max_len); -- pr_err(" %llx, %x\n", (u64)addr, scb->len); - } - } else { - for (addr = sg_dma_address(sgent), -@@ -616,7 +613,6 @@ static void bcm2835_dma_fill_cb_chain_wi - else - cb->cb->src = addr; - cb->cb->length = min(len, max_len); -- pr_err(" %llx, %x\n", (u64)addr, cb->cb->length); - } - } - } -@@ -659,7 +655,6 @@ static void bcm2835_dma_start_desc(struc - struct virt_dma_desc *vd = vchan_next_desc(&c->vc); - struct bcm2835_desc *d; - -- pr_err("dma_start_desc(%px)\n", vd); - if (!vd) { - c->desc = NULL; - return; diff --git a/target/linux/brcm2708/patches-4.19/950-0652-defconfigs-Add-FB_SIMPLE-to-both-bcmrpi-and-bcm2709-.patch b/target/linux/brcm2708/patches-4.19/950-0652-defconfigs-Add-FB_SIMPLE-to-both-bcmrpi-and-bcm2709-.patch new file mode 100644 index 0000000000..481dd933ec --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0652-defconfigs-Add-FB_SIMPLE-to-both-bcmrpi-and-bcm2709-.patch @@ -0,0 +1,36 @@ +From d2b90294279c1479a650f85256275624908033bf Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 7 Jun 2019 11:35:01 +0100 +Subject: [PATCH 652/725] defconfigs: Add FB_SIMPLE to both bcmrpi and bcm2709 + configs + +The firmware sets up simple fb should one of the KMS drivers +be enabled, but the driver isn't being built. +Add it to the build. + +Signed-off-by: Dave Stevenson +--- + 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 +@@ -928,6 +928,7 @@ CONFIG_TINYDRM_REPAPER=m + CONFIG_FB=y + CONFIG_FB_BCM2708=y + CONFIG_FB_UDL=m ++CONFIG_FB_SIMPLE=y + CONFIG_FB_SSD1307=m + CONFIG_FB_RPISENSE=m + # CONFIG_BACKLIGHT_GENERIC is not set +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -920,6 +920,7 @@ CONFIG_TINYDRM_REPAPER=m + CONFIG_FB=y + CONFIG_FB_BCM2708=y + CONFIG_FB_UDL=m ++CONFIG_FB_SIMPLE=y + CONFIG_FB_SSD1307=m + CONFIG_FB_RPISENSE=m + # CONFIG_BACKLIGHT_GENERIC is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0653-bcm2711-dts-Disable-the-v3d-node-by-default.patch b/target/linux/brcm2708/patches-4.19/950-0653-bcm2711-dts-Disable-the-v3d-node-by-default.patch new file mode 100644 index 0000000000..ebc6451a93 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0653-bcm2711-dts-Disable-the-v3d-node-by-default.patch @@ -0,0 +1,23 @@ +From bf7cf5876d809d13cbab812b10c7549edbd20990 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 10 Jun 2019 17:22:44 +0100 +Subject: [PATCH 653/725] bcm2711 dts: Disable the v3d node by default + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/bcm2711.dtsi | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/arch/arm/boot/dts/bcm2711.dtsi ++++ b/arch/arm/boot/dts/bcm2711.dtsi +@@ -13,6 +13,10 @@ + }; + }; + ++&v3d { ++ status = "disabled"; ++}; ++ + &dma { + brcm,dma-channel-mask = <0x7ef5>; + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0653-defconfig-Update-bcm2711-to-match-bcm2709-on-extra-m.patch b/target/linux/brcm2708/patches-4.19/950-0653-defconfig-Update-bcm2711-to-match-bcm2709-on-extra-m.patch deleted file mode 100644 index 31f70e2b07..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0653-defconfig-Update-bcm2711-to-match-bcm2709-on-extra-m.patch +++ /dev/null @@ -1,300 +0,0 @@ -From 72ea8706ae509fb2d85c3eac6190e3fb43a6dc0f Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 6 Jun 2019 15:22:29 +0100 -Subject: [PATCH 653/703] defconfig: Update bcm2711 to match bcm2709 on extra - modules - -Lots of things like USB DVB tuners were missing from the -defconfig. -Resync it with bcm2709_defconfig - -Signed-off-by: Dave Stevenson ---- - arch/arm/configs/bcm2711_defconfig | 97 ++++++++++++++++++++++++++++++ - 1 file changed, 97 insertions(+) - ---- a/arch/arm/configs/bcm2711_defconfig -+++ b/arch/arm/configs/bcm2711_defconfig -@@ -14,6 +14,9 @@ CONFIG_TASK_XACCT=y - CONFIG_TASK_IO_ACCOUNTING=y - CONFIG_IKCONFIG=m - CONFIG_IKCONFIG_PROC=y -+CONFIG_MEMCG=y -+CONFIG_BLK_CGROUP=y -+CONFIG_CGROUP_PIDS=y - CONFIG_CGROUP_FREEZER=y - CONFIG_CPUSETS=y - CONFIG_CGROUP_DEVICE=y -@@ -65,8 +68,10 @@ CONFIG_MODULES=y - CONFIG_MODULE_UNLOAD=y - CONFIG_MODVERSIONS=y - CONFIG_MODULE_SRCVERSION_ALL=y -+CONFIG_BLK_DEV_THROTTLING=y - CONFIG_PARTITION_ADVANCED=y - CONFIG_MAC_PARTITION=y -+CONFIG_CFQ_GROUP_IOSCHED=y - CONFIG_BINFMT_MISC=m - CONFIG_CLEANCACHE=y - CONFIG_FRONTSWAP=y -@@ -95,6 +100,7 @@ CONFIG_IP_MROUTE_MULTIPLE_TABLES=y - CONFIG_IP_PIMSM_V1=y - CONFIG_IP_PIMSM_V2=y - CONFIG_SYN_COOKIES=y -+CONFIG_NET_IPVTI=m - CONFIG_INET_AH=m - CONFIG_INET_ESP=m - CONFIG_INET_IPCOMP=m -@@ -214,6 +220,7 @@ CONFIG_NETFILTER_XT_MATCH_QUOTA=m - CONFIG_NETFILTER_XT_MATCH_RATEEST=m - CONFIG_NETFILTER_XT_MATCH_REALM=m - CONFIG_NETFILTER_XT_MATCH_RECENT=m -+CONFIG_NETFILTER_XT_MATCH_SOCKET=m - CONFIG_NETFILTER_XT_MATCH_STATE=m - CONFIG_NETFILTER_XT_MATCH_STATISTIC=m - CONFIG_NETFILTER_XT_MATCH_STRING=m -@@ -520,6 +527,7 @@ CONFIG_USB_RTL8150=m - CONFIG_USB_RTL8152=y - CONFIG_USB_LAN78XX=y - CONFIG_USB_USBNET=y -+CONFIG_USB_NET_AX8817X=m - CONFIG_USB_NET_AX88179_178A=m - CONFIG_USB_NET_CDCETHER=m - CONFIG_USB_NET_CDC_EEM=m -@@ -573,6 +581,8 @@ CONFIG_LIBERTAS_THINFIRM_USB=m - CONFIG_MWIFIEX=m - CONFIG_MWIFIEX_SDIO=m - CONFIG_MT7601U=m -+CONFIG_MT76x0U=m -+CONFIG_MT76x2U=m - CONFIG_RT2X00=m - CONFIG_RT2500USB=m - CONFIG_RT73USB=m -@@ -613,6 +623,7 @@ CONFIG_TOUCHSCREEN_ADS7846=m - CONFIG_TOUCHSCREEN_EGALAX=m - CONFIG_TOUCHSCREEN_EXC3000=m - CONFIG_TOUCHSCREEN_GOODIX=m -+CONFIG_TOUCHSCREEN_ILI210X=m - CONFIG_TOUCHSCREEN_EDT_FT5X06=m - CONFIG_TOUCHSCREEN_RPI_FT5406=m - CONFIG_TOUCHSCREEN_USB_COMPOSITE=m -@@ -657,8 +668,13 @@ CONFIG_SERIAL_DEV_BUS=m - CONFIG_TTY_PRINTK=y - CONFIG_HW_RANDOM=y - CONFIG_RAW_DRIVER=y -+CONFIG_TCG_TPM=m -+CONFIG_TCG_TIS_SPI=m - CONFIG_I2C=y - CONFIG_I2C_CHARDEV=m -+CONFIG_I2C_MUX=m -+CONFIG_I2C_MUX_GPMUX=m -+CONFIG_I2C_MUX_PCA954x=m - CONFIG_I2C_BCM2708=m - CONFIG_I2C_BCM2835=m - CONFIG_I2C_GPIO=m -@@ -667,6 +683,7 @@ CONFIG_I2C_TINY_USB=m - CONFIG_SPI=y - CONFIG_SPI_BCM2835=m - CONFIG_SPI_BCM2835AUX=m -+CONFIG_SPI_GPIO=m - CONFIG_SPI_SPIDEV=m - CONFIG_SPI_SLAVE=y - CONFIG_PPS=m -@@ -698,11 +715,14 @@ CONFIG_W1_SLAVE_DS28E04=m - CONFIG_POWER_RESET=y - CONFIG_POWER_RESET_GPIO=y - CONFIG_BATTERY_DS2760=m -+CONFIG_BATTERY_MAX17040=m - CONFIG_BATTERY_GAUGE_LTC2941=m - CONFIG_HWMON=m - CONFIG_SENSORS_DS1621=m -+CONFIG_SENSORS_GPIO_FAN=m - CONFIG_SENSORS_JC42=m - CONFIG_SENSORS_LM75=m -+CONFIG_SENSORS_RASPBERRYPI_HWMON=m - CONFIG_SENSORS_RPI_POE_FAN=m - CONFIG_SENSORS_SHT21=m - CONFIG_SENSORS_SHT3x=m -@@ -726,6 +746,31 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=m - CONFIG_REGULATOR_ARIZONA_LDO1=m - CONFIG_REGULATOR_ARIZONA_MICSUPP=m - CONFIG_REGULATOR_GPIO=y -+CONFIG_RC_CORE=y -+CONFIG_LIRC=y -+CONFIG_RC_DECODERS=y -+CONFIG_IR_NEC_DECODER=m -+CONFIG_IR_RC5_DECODER=m -+CONFIG_IR_RC6_DECODER=m -+CONFIG_IR_JVC_DECODER=m -+CONFIG_IR_SONY_DECODER=m -+CONFIG_IR_SANYO_DECODER=m -+CONFIG_IR_SHARP_DECODER=m -+CONFIG_IR_MCE_KBD_DECODER=m -+CONFIG_IR_XMP_DECODER=m -+CONFIG_IR_IMON_DECODER=m -+CONFIG_RC_DEVICES=y -+CONFIG_RC_ATI_REMOTE=m -+CONFIG_IR_IMON=m -+CONFIG_IR_MCEUSB=m -+CONFIG_IR_REDRAT3=m -+CONFIG_IR_STREAMZAP=m -+CONFIG_IR_IGUANA=m -+CONFIG_IR_TTUSBIR=m -+CONFIG_RC_LOOPBACK=m -+CONFIG_IR_GPIO_CIR=m -+CONFIG_IR_GPIO_TX=m -+CONFIG_IR_PWM_TX=m - CONFIG_MEDIA_SUPPORT=m - CONFIG_MEDIA_CAMERA_SUPPORT=y - CONFIG_MEDIA_ANALOG_TV_SUPPORT=y -@@ -797,7 +842,40 @@ CONFIG_VIDEO_GO7007=m - CONFIG_VIDEO_GO7007_USB=m - CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m - CONFIG_VIDEO_AU0828=m -+CONFIG_VIDEO_AU0828_RC=y -+CONFIG_VIDEO_CX231XX=m -+CONFIG_VIDEO_CX231XX_ALSA=m -+CONFIG_VIDEO_CX231XX_DVB=m -+CONFIG_VIDEO_TM6000=m -+CONFIG_VIDEO_TM6000_ALSA=m -+CONFIG_VIDEO_TM6000_DVB=m -+CONFIG_DVB_USB=m -+CONFIG_DVB_USB_A800=m -+CONFIG_DVB_USB_DIBUSB_MB=m -+CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y -+CONFIG_DVB_USB_DIBUSB_MC=m -+CONFIG_DVB_USB_DIB0700=m -+CONFIG_DVB_USB_UMT_010=m -+CONFIG_DVB_USB_CXUSB=m -+CONFIG_DVB_USB_M920X=m -+CONFIG_DVB_USB_DIGITV=m -+CONFIG_DVB_USB_VP7045=m -+CONFIG_DVB_USB_VP702X=m -+CONFIG_DVB_USB_GP8PSK=m -+CONFIG_DVB_USB_NOVA_T_USB2=m -+CONFIG_DVB_USB_TTUSB2=m -+CONFIG_DVB_USB_DTT200U=m -+CONFIG_DVB_USB_OPERA1=m -+CONFIG_DVB_USB_AF9005=m -+CONFIG_DVB_USB_AF9005_REMOTE=m -+CONFIG_DVB_USB_PCTV452E=m -+CONFIG_DVB_USB_DW2102=m -+CONFIG_DVB_USB_CINERGY_T2=m -+CONFIG_DVB_USB_DTV5100=m -+CONFIG_DVB_USB_AZ6027=m -+CONFIG_DVB_USB_TECHNISAT_USB2=m - CONFIG_DVB_USB_V2=m -+CONFIG_DVB_USB_AF9015=m - CONFIG_DVB_USB_AF9035=m - CONFIG_DVB_USB_ANYSEE=m - CONFIG_DVB_USB_AU6610=m -@@ -805,7 +883,9 @@ CONFIG_DVB_USB_AZ6007=m - CONFIG_DVB_USB_CE6230=m - CONFIG_DVB_USB_EC168=m - CONFIG_DVB_USB_GL861=m -+CONFIG_DVB_USB_LME2510=m - CONFIG_DVB_USB_MXL111SF=m -+CONFIG_DVB_USB_RTL28XXU=m - CONFIG_DVB_USB_DVBSKY=m - CONFIG_SMS_USB_DRV=m - CONFIG_DVB_B2C2_FLEXCOP_USB=m -@@ -900,9 +980,11 @@ CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_CODEC=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m - CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m -+CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m - CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m - CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m - CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m -+CONFIG_SND_AUDIOSENSE_PI=m - CONFIG_SND_DIGIDAC1_SOUNDCARD=m - CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m - CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m -@@ -913,10 +995,14 @@ CONFIG_SND_BCM2708_SOC_ALLO_DIGIONE=m - CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC=m - CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m - CONFIG_SND_PISOUND=m -+CONFIG_SND_SOC_AD193X_SPI=m -+CONFIG_SND_SOC_AD193X_I2C=m - CONFIG_SND_SOC_ADAU1701=m - CONFIG_SND_SOC_ADAU7002=m - CONFIG_SND_SOC_AK4554=m -+CONFIG_SND_SOC_CS4265=m - CONFIG_SND_SOC_CS4271_I2C=m -+CONFIG_SND_SOC_ICS43432=m - CONFIG_SND_SOC_SPDIF=m - CONFIG_SND_SOC_WM8804_I2C=m - CONFIG_SND_SIMPLE_CARD=m -@@ -929,6 +1015,7 @@ CONFIG_HID_APPLE=m - CONFIG_HID_ASUS=m - CONFIG_HID_BELKIN=m - CONFIG_HID_BETOP_FF=m -+CONFIG_HID_BIGBEN_FF=m - CONFIG_HID_CHERRY=m - CONFIG_HID_CHICONY=m - CONFIG_HID_CYPRESS=m -@@ -986,6 +1073,7 @@ CONFIG_USB_XHCI_HCD=y - CONFIG_USB_XHCI_PLATFORM=y - CONFIG_USB_DWCOTG=y - CONFIG_USB_PRINTER=m -+CONFIG_USB_TMC=m - CONFIG_USB_STORAGE=y - CONFIG_USB_STORAGE_REALTEK=m - CONFIG_USB_STORAGE_DATAFAB=m -@@ -1006,6 +1094,7 @@ CONFIG_USB_MICROTEK=m - CONFIG_USBIP_CORE=m - CONFIG_USBIP_VHCI_HCD=m - CONFIG_USBIP_HOST=m -+CONFIG_USBIP_VUDC=m - CONFIG_USB_DWC2=m - CONFIG_USB_SERIAL=m - CONFIG_USB_SERIAL_GENERIC=y -@@ -1122,6 +1211,8 @@ CONFIG_MMC_SDHCI_IPROC=y - CONFIG_MMC_SPI=m - CONFIG_LEDS_CLASS=y - CONFIG_LEDS_GPIO=y -+CONFIG_LEDS_PCA963X=m -+CONFIG_LEDS_IS31FL32XX=m - CONFIG_LEDS_TRIGGER_TIMER=y - CONFIG_LEDS_TRIGGER_ONESHOT=y - CONFIG_LEDS_TRIGGER_HEARTBEAT=y -@@ -1133,6 +1224,7 @@ CONFIG_LEDS_TRIGGER_TRANSIENT=m - CONFIG_LEDS_TRIGGER_CAMERA=m - CONFIG_LEDS_TRIGGER_INPUT=y - CONFIG_LEDS_TRIGGER_PANIC=y -+CONFIG_LEDS_TRIGGER_NETDEV=m - CONFIG_RTC_CLASS=y - # CONFIG_RTC_HCTOSYS is not set - CONFIG_RTC_DRV_ABX80X=m -@@ -1154,6 +1246,7 @@ CONFIG_RTC_DRV_FM3130=m - CONFIG_RTC_DRV_RX8581=m - CONFIG_RTC_DRV_RX8025=m - CONFIG_RTC_DRV_EM3027=m -+CONFIG_RTC_DRV_RV3028=m - CONFIG_RTC_DRV_M41T93=m - CONFIG_RTC_DRV_M41T94=m - CONFIG_RTC_DRV_DS1302=m -@@ -1170,6 +1263,8 @@ CONFIG_RTC_DRV_RV3029C2=m - CONFIG_DMADEVICES=y - CONFIG_DMA_BCM2835=y - CONFIG_DMA_BCM2708=y -+CONFIG_AUXDISPLAY=y -+CONFIG_HD44780=m - CONFIG_UIO=m - CONFIG_UIO_PDRV_GENIRQ=m - CONFIG_STAGING=y -@@ -1198,6 +1293,7 @@ CONFIG_FB_TFT_PCD8544=m - CONFIG_FB_TFT_RA8875=m - CONFIG_FB_TFT_S6D02A1=m - CONFIG_FB_TFT_S6D1121=m -+CONFIG_FB_TFT_SH1106=m - CONFIG_FB_TFT_SSD1289=m - CONFIG_FB_TFT_SSD1306=m - CONFIG_FB_TFT_SSD1331=m -@@ -1229,6 +1325,7 @@ CONFIG_MCP3422=m - CONFIG_DHT11=m - CONFIG_HDC100X=m - CONFIG_HTU21=m -+CONFIG_INV_MPU6050_I2C=m - CONFIG_TSL4531=m - CONFIG_VEML6070=m - CONFIG_BMP280=m diff --git a/target/linux/brcm2708/patches-4.19/950-0654-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch b/target/linux/brcm2708/patches-4.19/950-0654-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch new file mode 100644 index 0000000000..e42e1d8916 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0654-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch @@ -0,0 +1,29 @@ +From 33a9109c32beaf418bd72165d598db1c792051f5 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 10 Jun 2019 16:32:51 +0100 +Subject: [PATCH 654/725] drm/vc4: Remove 340MHz clock limit from FKMS now + scrambling issues resolved + +Firmware TMDS scrambling is now being correctly configured, so +we can use it. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 6 ------ + 1 file changed, 6 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -830,12 +830,6 @@ vc4_crtc_mode_valid(struct drm_crtc *crt + break; + } + +- /* Limit the pixel clock until we can get dynamic HDMI 2.0 scrambling +- * working. +- */ +- if (mode->clock > 340000) +- return MODE_CLOCK_HIGH; +- + return MODE_OK; + } + diff --git a/target/linux/brcm2708/patches-4.19/950-0654-dts-Include-CSI-lane-config-for-csi1.patch b/target/linux/brcm2708/patches-4.19/950-0654-dts-Include-CSI-lane-config-for-csi1.patch deleted file mode 100644 index a18c59d86a..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0654-dts-Include-CSI-lane-config-for-csi1.patch +++ /dev/null @@ -1,23 +0,0 @@ -From e38baaa7198fc28f746a6b72c5cb125920d5145b Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 31 May 2019 17:57:26 +0100 -Subject: [PATCH 654/703] dts: Include CSI lane config for csi1 - -Without the include the peripheral is configured to have 0 -data lanes, which doesn't allow much data to be passed. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts -+++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts -@@ -1,6 +1,7 @@ - /dts-v1/; - - #include "bcm2711.dtsi" -+#include "bcm283x-rpi-csi1-2lane.dtsi" - - / { - compatible = "raspberrypi,4-model-b", "brcm,bcm2838", "brcm,bcm2837"; diff --git a/target/linux/brcm2708/patches-4.19/950-0655-Revert-usb-xhci-hack-xhci_urb_enqueue-to-support-hid.patch b/target/linux/brcm2708/patches-4.19/950-0655-Revert-usb-xhci-hack-xhci_urb_enqueue-to-support-hid.patch new file mode 100644 index 0000000000..1b40339581 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0655-Revert-usb-xhci-hack-xhci_urb_enqueue-to-support-hid.patch @@ -0,0 +1,113 @@ +From 255fb8869fe765f8ee9dbdad61ddfab333ff45ae Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Fri, 7 Jun 2019 14:50:12 +0100 +Subject: [PATCH 655/725] Revert "usb: xhci: hack xhci_urb_enqueue to support + hid.mousepoll behaviour" + +This reverts commit 1cf1071a79f320bc4497a3ade77431f04442eb17. +--- + drivers/usb/host/xhci.c | 86 ----------------------------------------- + 1 file changed, 86 deletions(-) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -1416,87 +1416,6 @@ command_cleanup: + } + + /* +- * RPI: Fixup endpoint intervals when requested +- * - Check interval versus the (cached) endpoint context +- * - set the endpoint interval to the new value +- * - force an endpoint configure command +- */ +-static void xhci_fixup_interval(struct xhci_hcd *xhci, struct urb *urb, +- unsigned int slot_id, unsigned int ep_index) +-{ +- struct xhci_ep_ctx *ep_ctx_out, *ep_ctx_in; +- struct xhci_command *command; +- struct xhci_input_control_ctx *ctrl_ctx; +- struct xhci_virt_device *vdev; +- int xhci_interval, ep_interval; +- int ret; +- unsigned long flags; +- u32 ep_info_tmp; +- +- spin_lock_irqsave(&xhci->lock, flags); +- +- vdev = xhci->devs[slot_id]; +- /* Get context-derived endpoint interval */ +- ep_ctx_out = xhci_get_ep_ctx(xhci, vdev->out_ctx, ep_index); +- ep_ctx_in = xhci_get_ep_ctx(xhci, vdev->in_ctx, ep_index); +- xhci_interval = EP_INTERVAL_TO_UFRAMES(le32_to_cpu(ep_ctx_out->ep_info)); +- ep_interval = urb->interval * 8; +- +- if (ep_interval == xhci_interval) { +- spin_unlock_irqrestore(&xhci->lock, flags); +- return; +- } +- +- xhci_dbg(xhci, "Fixup interval ep_interval=%d xhci_interval=%d\n", +- ep_interval, xhci_interval); +- command = xhci_alloc_command_with_ctx(xhci, true, GFP_ATOMIC); +- if (!command) { +- /* Failure here is benign, poll at the original rate */ +- spin_unlock_irqrestore(&xhci->lock, flags); +- return; +- } +- +- /* xHCI uses exponents for intervals... */ +- xhci_interval = fls(ep_interval) - 1; +- xhci_interval = clamp_val(xhci_interval, 3, 10); +- ep_info_tmp = le32_to_cpu(ep_ctx_out->ep_info); +- ep_info_tmp &= ~EP_INTERVAL(255); +- ep_info_tmp |= EP_INTERVAL(xhci_interval); +- +- /* Keep the endpoint context up-to-date while issuing the command. */ +- xhci_endpoint_copy(xhci, vdev->in_ctx, +- vdev->out_ctx, ep_index); +- ep_ctx_in->ep_info = cpu_to_le32(ep_info_tmp); +- +- /* +- * We need to drop the lock, so take an explicit copy +- * of the ep context. +- */ +- xhci_endpoint_copy(xhci, command->in_ctx, vdev->in_ctx, ep_index); +- +- ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); +- if (!ctrl_ctx) { +- xhci_warn(xhci, +- "%s: Could not get input context, bad type.\n", +- __func__); +- spin_unlock_irqrestore(&xhci->lock, flags); +- xhci_free_command(xhci, command); +- return; +- } +- ctrl_ctx->add_flags = xhci_get_endpoint_flag_from_index(ep_index); +- ctrl_ctx->drop_flags = 0; +- +- spin_unlock_irqrestore(&xhci->lock, flags); +- +- ret = xhci_configure_endpoint(xhci, urb->dev, command, +- false, false); +- if (ret) +- xhci_warn(xhci, "%s: Configure endpoint failed: %d\n", +- __func__, ret); +- xhci_free_command(xhci, command); +-} +- +-/* + * non-error returns are a promise to giveback() the urb later + * we drop ownership so next owner (or urb unlink) can get it + */ +@@ -1564,11 +1483,6 @@ static int xhci_urb_enqueue(struct usb_h + } + } + +- if (usb_endpoint_xfer_int(&urb->ep->desc) && +- (urb->dev->speed == USB_SPEED_FULL || +- urb->dev->speed == USB_SPEED_LOW)) +- xhci_fixup_interval(xhci, urb, slot_id, ep_index); +- + spin_lock_irqsave(&xhci->lock, flags); + + if (xhci->xhc_state & XHCI_STATE_DYING) { diff --git a/target/linux/brcm2708/patches-4.19/950-0655-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch b/target/linux/brcm2708/patches-4.19/950-0655-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch deleted file mode 100644 index 9f24da54b4..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0655-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 07455c93159c15c8838f53716210713376db7065 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 7 Jun 2019 11:31:21 +0100 -Subject: [PATCH 655/703] drm/vc4: Fix T-format modifiers in FKMS. - -The wrong vc_image formats were being checked for in the switch -statement. Correct these. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -458,10 +458,10 @@ static void vc4_plane_atomic_update(stru - switch (fb->modifier) { - case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: - switch (mb->plane.vc_image_type) { -- case VC_IMAGE_RGBX32: -+ case VC_IMAGE_XRGB8888: - mb->plane.vc_image_type = VC_IMAGE_TF_RGBX32; - break; -- case VC_IMAGE_RGBA32: -+ case VC_IMAGE_ARGB8888: - mb->plane.vc_image_type = VC_IMAGE_TF_RGBA32; - break; - case VC_IMAGE_RGB565: diff --git a/target/linux/brcm2708/patches-4.19/950-0656-defconfigs-Add-FB_SIMPLE-to-both-bcmrpi-and-bcm2709-.patch b/target/linux/brcm2708/patches-4.19/950-0656-defconfigs-Add-FB_SIMPLE-to-both-bcmrpi-and-bcm2709-.patch deleted file mode 100644 index 2702717ffd..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0656-defconfigs-Add-FB_SIMPLE-to-both-bcmrpi-and-bcm2709-.patch +++ /dev/null @@ -1,36 +0,0 @@ -From db56c3edb3b30f3884537bca47019e7a715a4333 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 7 Jun 2019 11:35:01 +0100 -Subject: [PATCH 656/703] defconfigs: Add FB_SIMPLE to both bcmrpi and bcm2709 - configs - -The firmware sets up simple fb should one of the KMS drivers -be enabled, but the driver isn't being built. -Add it to the build. - -Signed-off-by: Dave Stevenson ---- - 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 -@@ -928,6 +928,7 @@ CONFIG_TINYDRM_REPAPER=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y - CONFIG_FB_UDL=m -+CONFIG_FB_SIMPLE=y - CONFIG_FB_SSD1307=m - CONFIG_FB_RPISENSE=m - # CONFIG_BACKLIGHT_GENERIC is not set ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -920,6 +920,7 @@ CONFIG_TINYDRM_REPAPER=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y - CONFIG_FB_UDL=m -+CONFIG_FB_SIMPLE=y - CONFIG_FB_SSD1307=m - CONFIG_FB_RPISENSE=m - # CONFIG_BACKLIGHT_GENERIC is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0656-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch b/target/linux/brcm2708/patches-4.19/950-0656-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch new file mode 100644 index 0000000000..d413349ad1 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0656-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch @@ -0,0 +1,104 @@ +From fbb878b2370c655ea989191167b338fff636687a Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Tue, 11 Jun 2019 10:55:00 +0100 +Subject: [PATCH 656/725] usb: add plumbing for updating interrupt endpoint + interval state + +xHCI caches device and endpoint data after the interface is configured, +so an explicit command needs to be issued for any device driver wanting +to alter the polling interval of an endpoint. + +Add usb_fixup_endpoint() to allow drivers to do this. The fixup must be +called after calculating endpoint bandwidth requirements but before any +URBs are submitted. + +If polling intervals are shortened, any bandwidth reservations are no +longer valid but in practice polling intervals are only ever relaxed. + +Limit the scope to interrupt transfers for now. + +Signed-off-by: Jonathan Bell +--- + drivers/usb/core/hcd.c | 10 ++++++++++ + drivers/usb/core/message.c | 15 +++++++++++++++ + include/linux/usb.h | 2 ++ + include/linux/usb/hcd.h | 7 +++++++ + 4 files changed, 34 insertions(+) + +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -2071,6 +2071,16 @@ reset: + return ret; + } + ++void usb_hcd_fixup_endpoint(struct usb_device *udev, ++ struct usb_host_endpoint *ep, int interval) ++{ ++ struct usb_hcd *hcd; ++ ++ hcd = bus_to_hcd(udev->bus); ++ if (hcd->driver->fixup_endpoint) ++ hcd->driver->fixup_endpoint(hcd, udev, ep, interval); ++} ++ + /* Disables the endpoint: synchronizes with the hcd to make sure all + * endpoint state is gone from hardware. usb_hcd_flush_endpoint() must + * have been called previously. Use for set_configuration, set_interface, +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -1113,6 +1113,21 @@ static void remove_intf_ep_devs(struct u + intf->ep_devs_created = 0; + } + ++void usb_fixup_endpoint(struct usb_device *dev, int epaddr, int interval) ++{ ++ unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK; ++ struct usb_host_endpoint *ep; ++ ++ if (usb_endpoint_out(epaddr)) ++ ep = dev->ep_out[epnum]; ++ else ++ ep = dev->ep_in[epnum]; ++ ++ if (ep && usb_endpoint_xfer_int(&ep->desc)) ++ usb_hcd_fixup_endpoint(dev, ep, interval); ++} ++EXPORT_SYMBOL_GPL(usb_fixup_endpoint); ++ + /** + * usb_disable_endpoint -- Disable an endpoint by address + * @dev: the device whose endpoint is being disabled +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -1809,6 +1809,8 @@ extern int usb_clear_halt(struct usb_dev + extern int usb_reset_configuration(struct usb_device *dev); + extern int usb_set_interface(struct usb_device *dev, int ifnum, int alternate); + extern void usb_reset_endpoint(struct usb_device *dev, unsigned int epaddr); ++extern void usb_fixup_endpoint(struct usb_device *dev, int epaddr, ++ int interval); + + /* this request isn't really synchronous, but it belongs with the others */ + extern int usb_driver_set_configuration(struct usb_device *udev, int config); +--- a/include/linux/usb/hcd.h ++++ b/include/linux/usb/hcd.h +@@ -379,6 +379,11 @@ struct hc_driver { + * or bandwidth constraints. + */ + void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *); ++ /* Override the endpoint-derived interval ++ * (if there is any cached hardware state). ++ */ ++ void (*fixup_endpoint)(struct usb_hcd *hcd, struct usb_device *udev, ++ struct usb_host_endpoint *ep, int interval); + /* Returns the hardware-chosen device address */ + int (*address_device)(struct usb_hcd *, struct usb_device *udev); + /* prepares the hardware to send commands to the device */ +@@ -435,6 +440,8 @@ extern void usb_hcd_unmap_urb_setup_for_ + extern void usb_hcd_unmap_urb_for_dma(struct usb_hcd *, struct urb *); + extern void usb_hcd_flush_endpoint(struct usb_device *udev, + struct usb_host_endpoint *ep); ++extern void usb_hcd_fixup_endpoint(struct usb_device *udev, ++ struct usb_host_endpoint *ep, int interval); + extern void usb_hcd_disable_endpoint(struct usb_device *udev, + struct usb_host_endpoint *ep); + extern void usb_hcd_reset_endpoint(struct usb_device *udev, diff --git a/target/linux/brcm2708/patches-4.19/950-0657-bcm2711-dts-Disable-the-v3d-node-by-default.patch b/target/linux/brcm2708/patches-4.19/950-0657-bcm2711-dts-Disable-the-v3d-node-by-default.patch deleted file mode 100644 index 45a095844f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0657-bcm2711-dts-Disable-the-v3d-node-by-default.patch +++ /dev/null @@ -1,23 +0,0 @@ -From cacc213626d0435a7c9dd1192e0757c082ed048b Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 10 Jun 2019 17:22:44 +0100 -Subject: [PATCH 657/703] bcm2711 dts: Disable the v3d node by default - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2711.dtsi | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/arch/arm/boot/dts/bcm2711.dtsi -+++ b/arch/arm/boot/dts/bcm2711.dtsi -@@ -13,6 +13,10 @@ - }; - }; - -+&v3d { -+ status = "disabled"; -+}; -+ - &dma { - brcm,dma-channel-mask = <0x7ef5>; - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0657-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch b/target/linux/brcm2708/patches-4.19/950-0657-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch new file mode 100644 index 0000000000..1fd71c5a90 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0657-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch @@ -0,0 +1,129 @@ +From 3328d995046331f734b44a5f03471efd8682c8dd Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Tue, 11 Jun 2019 11:33:39 +0100 +Subject: [PATCH 657/725] xhci: implement xhci_fixup_endpoint for interval + adjustments + +Must be called in a non-atomic context, after the endpoint +has been registered with the hardware via xhci_add_endpoint +and before the first URB is submitted for the endpoint. + +Signed-off-by: Jonathan Bell +--- + drivers/usb/host/xhci.c | 98 +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 98 insertions(+) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -1416,6 +1416,103 @@ command_cleanup: + } + + /* ++ * RPI: Fixup endpoint intervals when requested ++ * - Check interval versus the (cached) endpoint context ++ * - set the endpoint interval to the new value ++ * - force an endpoint configure command ++ * XXX: bandwidth is not recalculated. We should probably do that. ++ */ ++static void xhci_fixup_endpoint(struct usb_hcd *hcd, struct usb_device *udev, ++ struct usb_host_endpoint *ep, int interval) ++{ ++ struct xhci_hcd *xhci; ++ struct xhci_ep_ctx *ep_ctx_out, *ep_ctx_in; ++ struct xhci_command *command; ++ struct xhci_input_control_ctx *ctrl_ctx; ++ struct xhci_virt_device *vdev; ++ int xhci_interval; ++ int ret; ++ int ep_index; ++ unsigned long flags; ++ u32 ep_info_tmp; ++ ++ xhci = hcd_to_xhci(hcd); ++ ep_index = xhci_get_endpoint_index(&ep->desc); ++ ++ /* FS/LS interval translations */ ++ if ((udev->speed == USB_SPEED_FULL || ++ udev->speed == USB_SPEED_LOW)) ++ interval *= 8; ++ ++ mutex_lock(&xhci->mutex); ++ ++ spin_lock_irqsave(&xhci->lock, flags); ++ ++ vdev = xhci->devs[udev->slot_id]; ++ /* Get context-derived endpoint interval */ ++ ep_ctx_out = xhci_get_ep_ctx(xhci, vdev->out_ctx, ep_index); ++ ep_ctx_in = xhci_get_ep_ctx(xhci, vdev->in_ctx, ep_index); ++ xhci_interval = EP_INTERVAL_TO_UFRAMES(le32_to_cpu(ep_ctx_out->ep_info)); ++ ++ if (interval == xhci_interval) { ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ mutex_unlock(&xhci->mutex); ++ return; ++ } ++ ++ xhci_dbg(xhci, "Fixup interval=%d xhci_interval=%d\n", ++ interval, xhci_interval); ++ command = xhci_alloc_command_with_ctx(xhci, true, GFP_ATOMIC); ++ if (!command) { ++ /* Failure here is benign, poll at the original rate */ ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ mutex_unlock(&xhci->mutex); ++ return; ++ } ++ ++ /* xHCI uses exponents for intervals... */ ++ xhci_interval = fls(interval) - 1; ++ xhci_interval = clamp_val(xhci_interval, 3, 10); ++ ep_info_tmp = le32_to_cpu(ep_ctx_out->ep_info); ++ ep_info_tmp &= ~EP_INTERVAL(255); ++ ep_info_tmp |= EP_INTERVAL(xhci_interval); ++ ++ /* Keep the endpoint context up-to-date while issuing the command. */ ++ xhci_endpoint_copy(xhci, vdev->in_ctx, ++ vdev->out_ctx, ep_index); ++ ep_ctx_in->ep_info = cpu_to_le32(ep_info_tmp); ++ ++ /* ++ * We need to drop the lock, so take an explicit copy ++ * of the ep context. ++ */ ++ xhci_endpoint_copy(xhci, command->in_ctx, vdev->in_ctx, ep_index); ++ ++ ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); ++ if (!ctrl_ctx) { ++ xhci_warn(xhci, ++ "%s: Could not get input context, bad type.\n", ++ __func__); ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ xhci_free_command(xhci, command); ++ mutex_unlock(&xhci->mutex); ++ return; ++ } ++ ctrl_ctx->add_flags = xhci_get_endpoint_flag_from_index(ep_index); ++ ctrl_ctx->drop_flags = 0; ++ ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ ++ ret = xhci_configure_endpoint(xhci, udev, command, ++ false, false); ++ if (ret) ++ xhci_warn(xhci, "%s: Configure endpoint failed: %d\n", ++ __func__, ret); ++ xhci_free_command(xhci, command); ++ mutex_unlock(&xhci->mutex); ++} ++ ++/* + * non-error returns are a promise to giveback() the urb later + * we drop ownership so next owner (or urb unlink) can get it + */ +@@ -5180,6 +5277,7 @@ static const struct hc_driver xhci_hc_dr + .endpoint_reset = xhci_endpoint_reset, + .check_bandwidth = xhci_check_bandwidth, + .reset_bandwidth = xhci_reset_bandwidth, ++ .fixup_endpoint = xhci_fixup_endpoint, + .address_device = xhci_address_device, + .enable_device = xhci_enable_device, + .update_hub_device = xhci_update_hub_device, diff --git a/target/linux/brcm2708/patches-4.19/950-0658-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch b/target/linux/brcm2708/patches-4.19/950-0658-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch deleted file mode 100644 index 24173b98e1..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0658-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch +++ /dev/null @@ -1,29 +0,0 @@ -From e63e050360bfe8d06552ed5fb0f037d8f18b61bc Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 10 Jun 2019 16:32:51 +0100 -Subject: [PATCH 658/703] drm/vc4: Remove 340MHz clock limit from FKMS now - scrambling issues resolved - -Firmware TMDS scrambling is now being correctly configured, so -we can use it. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 6 ------ - 1 file changed, 6 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -830,12 +830,6 @@ vc4_crtc_mode_valid(struct drm_crtc *crt - break; - } - -- /* Limit the pixel clock until we can get dynamic HDMI 2.0 scrambling -- * working. -- */ -- if (mode->clock > 340000) -- return MODE_CLOCK_HIGH; -- - return MODE_OK; - } - diff --git a/target/linux/brcm2708/patches-4.19/950-0658-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch b/target/linux/brcm2708/patches-4.19/950-0658-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch new file mode 100644 index 0000000000..ac2a2b13db --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0658-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch @@ -0,0 +1,23 @@ +From bc52b79141e51a6cbd1b5def5c300dee3c6d0b84 Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Tue, 11 Jun 2019 11:42:03 +0100 +Subject: [PATCH 658/725] usbhid: call usb_fixup_endpoint after mangling + intervals + +Lets the mousepoll override mechanism work with xhci. + +Signed-off-by: Jonathan Bell +--- + drivers/hid/usbhid/hid-core.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/hid/usbhid/hid-core.c ++++ b/drivers/hid/usbhid/hid-core.c +@@ -1118,6 +1118,7 @@ static int usbhid_start(struct hid_devic + interval = hid_kbpoll_interval; + break; + } ++ usb_fixup_endpoint(dev, endpoint->bEndpointAddress, interval); + + ret = -ENOMEM; + if (usb_endpoint_dir_in(endpoint)) { diff --git a/target/linux/brcm2708/patches-4.19/950-0659-Revert-usb-xhci-hack-xhci_urb_enqueue-to-support-hid.patch b/target/linux/brcm2708/patches-4.19/950-0659-Revert-usb-xhci-hack-xhci_urb_enqueue-to-support-hid.patch deleted file mode 100644 index c4e3d0fef5..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0659-Revert-usb-xhci-hack-xhci_urb_enqueue-to-support-hid.patch +++ /dev/null @@ -1,113 +0,0 @@ -From e019f0ccbfab3caccd5c5a8434c48e0a3b8e12cc Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 7 Jun 2019 14:50:12 +0100 -Subject: [PATCH 659/703] Revert "usb: xhci: hack xhci_urb_enqueue to support - hid.mousepoll behaviour" - -This reverts commit 1cf1071a79f320bc4497a3ade77431f04442eb17. ---- - drivers/usb/host/xhci.c | 86 ----------------------------------------- - 1 file changed, 86 deletions(-) - ---- a/drivers/usb/host/xhci.c -+++ b/drivers/usb/host/xhci.c -@@ -1416,87 +1416,6 @@ command_cleanup: - } - - /* -- * RPI: Fixup endpoint intervals when requested -- * - Check interval versus the (cached) endpoint context -- * - set the endpoint interval to the new value -- * - force an endpoint configure command -- */ --static void xhci_fixup_interval(struct xhci_hcd *xhci, struct urb *urb, -- unsigned int slot_id, unsigned int ep_index) --{ -- struct xhci_ep_ctx *ep_ctx_out, *ep_ctx_in; -- struct xhci_command *command; -- struct xhci_input_control_ctx *ctrl_ctx; -- struct xhci_virt_device *vdev; -- int xhci_interval, ep_interval; -- int ret; -- unsigned long flags; -- u32 ep_info_tmp; -- -- spin_lock_irqsave(&xhci->lock, flags); -- -- vdev = xhci->devs[slot_id]; -- /* Get context-derived endpoint interval */ -- ep_ctx_out = xhci_get_ep_ctx(xhci, vdev->out_ctx, ep_index); -- ep_ctx_in = xhci_get_ep_ctx(xhci, vdev->in_ctx, ep_index); -- xhci_interval = EP_INTERVAL_TO_UFRAMES(le32_to_cpu(ep_ctx_out->ep_info)); -- ep_interval = urb->interval * 8; -- -- if (ep_interval == xhci_interval) { -- spin_unlock_irqrestore(&xhci->lock, flags); -- return; -- } -- -- xhci_dbg(xhci, "Fixup interval ep_interval=%d xhci_interval=%d\n", -- ep_interval, xhci_interval); -- command = xhci_alloc_command_with_ctx(xhci, true, GFP_ATOMIC); -- if (!command) { -- /* Failure here is benign, poll at the original rate */ -- spin_unlock_irqrestore(&xhci->lock, flags); -- return; -- } -- -- /* xHCI uses exponents for intervals... */ -- xhci_interval = fls(ep_interval) - 1; -- xhci_interval = clamp_val(xhci_interval, 3, 10); -- ep_info_tmp = le32_to_cpu(ep_ctx_out->ep_info); -- ep_info_tmp &= ~EP_INTERVAL(255); -- ep_info_tmp |= EP_INTERVAL(xhci_interval); -- -- /* Keep the endpoint context up-to-date while issuing the command. */ -- xhci_endpoint_copy(xhci, vdev->in_ctx, -- vdev->out_ctx, ep_index); -- ep_ctx_in->ep_info = cpu_to_le32(ep_info_tmp); -- -- /* -- * We need to drop the lock, so take an explicit copy -- * of the ep context. -- */ -- xhci_endpoint_copy(xhci, command->in_ctx, vdev->in_ctx, ep_index); -- -- ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); -- if (!ctrl_ctx) { -- xhci_warn(xhci, -- "%s: Could not get input context, bad type.\n", -- __func__); -- spin_unlock_irqrestore(&xhci->lock, flags); -- xhci_free_command(xhci, command); -- return; -- } -- ctrl_ctx->add_flags = xhci_get_endpoint_flag_from_index(ep_index); -- ctrl_ctx->drop_flags = 0; -- -- spin_unlock_irqrestore(&xhci->lock, flags); -- -- ret = xhci_configure_endpoint(xhci, urb->dev, command, -- false, false); -- if (ret) -- xhci_warn(xhci, "%s: Configure endpoint failed: %d\n", -- __func__, ret); -- xhci_free_command(xhci, command); --} -- --/* - * non-error returns are a promise to giveback() the urb later - * we drop ownership so next owner (or urb unlink) can get it - */ -@@ -1564,11 +1483,6 @@ static int xhci_urb_enqueue(struct usb_h - } - } - -- if (usb_endpoint_xfer_int(&urb->ep->desc) && -- (urb->dev->speed == USB_SPEED_FULL || -- urb->dev->speed == USB_SPEED_LOW)) -- xhci_fixup_interval(xhci, urb, slot_id, ep_index); -- - spin_lock_irqsave(&xhci->lock, flags); - - if (xhci->xhc_state & XHCI_STATE_DYING) { diff --git a/target/linux/brcm2708/patches-4.19/950-0659-drm-vc4-Add-status-of-which-display-is-updated-throu.patch b/target/linux/brcm2708/patches-4.19/950-0659-drm-vc4-Add-status-of-which-display-is-updated-throu.patch new file mode 100644 index 0000000000..2b6f45e0c8 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0659-drm-vc4-Add-status-of-which-display-is-updated-throu.patch @@ -0,0 +1,85 @@ +From 779fbe67ca1737d5450d393a6e893dcda8111786 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 4 Jun 2019 12:14:30 +0100 +Subject: [PATCH 659/725] drm: vc4: Add status of which display is updated + through vblank + +Previously multiple displays were slaved off the same SMI +interrupt, triggered by HVS channel 1 (HDMI0). +This doesn't work if you only have a DPI or DSI screen (HVS channel +0), and gives slightly erroneous results with dual HDMI as the +events for HDMI1 are incorrect. + +Use SMIDSW0 and SMIDSW1 registers to denote which display has +triggered the vblank. +Handling should be backwards compatible with older firmware. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 41 ++++++++++++++++++++++---- + 1 file changed, 36 insertions(+), 5 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -230,8 +230,13 @@ static const struct vc_image_format *vc4 + * hardware, which has only this one register. + */ + #define SMICS 0x0 ++#define SMIDSW0 0x14 ++#define SMIDSW1 0x1C + #define SMICS_INTERRUPTS (BIT(9) | BIT(10) | BIT(11)) + ++/* Flag to denote that the firmware is giving multiple display callbacks */ ++#define SMI_NEW 0xabcd0000 ++ + #define vc4_crtc vc4_kms_crtc + #define to_vc4_crtc to_vc4_kms_crtc + struct vc4_crtc { +@@ -884,16 +889,42 @@ static irqreturn_t vc4_crtc_irq_handler( + int i; + u32 stat = readl(crtc_list[0]->regs + SMICS); + irqreturn_t ret = IRQ_NONE; ++ u32 chan; + + if (stat & SMICS_INTERRUPTS) { + writel(0, crtc_list[0]->regs + SMICS); + +- for (i = 0; crtc_list[i]; i++) { +- if (crtc_list[i]->vblank_enabled) +- drm_crtc_handle_vblank(&crtc_list[i]->base); +- vc4_crtc_handle_page_flip(crtc_list[i]); +- ret = IRQ_HANDLED; ++ chan = readl(crtc_list[0]->regs + SMIDSW0); ++ ++ if ((chan & 0xFFFF0000) != SMI_NEW) { ++ /* Older firmware. Treat the one interrupt as vblank/ ++ * complete for all crtcs. ++ */ ++ for (i = 0; crtc_list[i]; i++) { ++ if (crtc_list[i]->vblank_enabled) ++ drm_crtc_handle_vblank(&crtc_list[i]->base); ++ vc4_crtc_handle_page_flip(crtc_list[i]); ++ } ++ } else { ++ if (chan & 1) { ++ writel(SMI_NEW, crtc_list[0]->regs + SMIDSW0); ++ if (crtc_list[0]->vblank_enabled) ++ drm_crtc_handle_vblank(&crtc_list[0]->base); ++ vc4_crtc_handle_page_flip(crtc_list[0]); ++ } ++ ++ /* Check for the secondary display too */ ++ chan = readl(crtc_list[0]->regs + SMIDSW1); ++ ++ if (chan & 1) { ++ writel(SMI_NEW, crtc_list[0]->regs + SMIDSW1); ++ if (crtc_list[1]->vblank_enabled) ++ drm_crtc_handle_vblank(&crtc_list[1]->base); ++ vc4_crtc_handle_page_flip(crtc_list[1]); ++ } + } ++ ++ ret = IRQ_HANDLED; + } + + return ret; diff --git a/target/linux/brcm2708/patches-4.19/950-0660-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch b/target/linux/brcm2708/patches-4.19/950-0660-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch new file mode 100644 index 0000000000..5da8452f70 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0660-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch @@ -0,0 +1,36 @@ +From 06467a053320efedf24a7facbd58873b22106992 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 12 Jun 2019 17:13:21 +0100 +Subject: [PATCH 660/725] drm/vc4: In FKMS look at the modifiers correctly for + SAND + +Incorrect masking was used in the switch for the modifier, +therefore for SAND (which puts the column pitch in the +modifier) it didn't match. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -460,7 +460,7 @@ static void vc4_plane_atomic_update(stru + } + mb->plane.planes[3] = 0; + +- switch (fb->modifier) { ++ switch (fourcc_mod_broadcom_mod(fb->modifier)) { + case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: + switch (mb->plane.vc_image_type) { + case VC_IMAGE_XRGB8888: +@@ -476,6 +476,9 @@ static void vc4_plane_atomic_update(stru + break; + case DRM_FORMAT_MOD_BROADCOM_SAND128: + mb->plane.vc_image_type = VC_IMAGE_YUV_UV; ++ /* Note that the column pitch is passed across in lines, not ++ * bytes. ++ */ + mb->plane.pitch = fourcc_mod_broadcom_param(fb->modifier); + break; + } diff --git a/target/linux/brcm2708/patches-4.19/950-0660-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch b/target/linux/brcm2708/patches-4.19/950-0660-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch deleted file mode 100644 index 714377e90e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0660-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 8a6b7be03aaf91419a6dbc91dba10cf6e7f6eb73 Mon Sep 17 00:00:00 2001 -From: Jonathan Bell -Date: Tue, 11 Jun 2019 10:55:00 +0100 -Subject: [PATCH 660/703] usb: add plumbing for updating interrupt endpoint - interval state - -xHCI caches device and endpoint data after the interface is configured, -so an explicit command needs to be issued for any device driver wanting -to alter the polling interval of an endpoint. - -Add usb_fixup_endpoint() to allow drivers to do this. The fixup must be -called after calculating endpoint bandwidth requirements but before any -URBs are submitted. - -If polling intervals are shortened, any bandwidth reservations are no -longer valid but in practice polling intervals are only ever relaxed. - -Limit the scope to interrupt transfers for now. - -Signed-off-by: Jonathan Bell ---- - drivers/usb/core/hcd.c | 10 ++++++++++ - drivers/usb/core/message.c | 15 +++++++++++++++ - include/linux/usb.h | 2 ++ - include/linux/usb/hcd.h | 7 +++++++ - 4 files changed, 34 insertions(+) - ---- a/drivers/usb/core/hcd.c -+++ b/drivers/usb/core/hcd.c -@@ -2071,6 +2071,16 @@ reset: - return ret; - } - -+void usb_hcd_fixup_endpoint(struct usb_device *udev, -+ struct usb_host_endpoint *ep, int interval) -+{ -+ struct usb_hcd *hcd; -+ -+ hcd = bus_to_hcd(udev->bus); -+ if (hcd->driver->fixup_endpoint) -+ hcd->driver->fixup_endpoint(hcd, udev, ep, interval); -+} -+ - /* Disables the endpoint: synchronizes with the hcd to make sure all - * endpoint state is gone from hardware. usb_hcd_flush_endpoint() must - * have been called previously. Use for set_configuration, set_interface, ---- a/drivers/usb/core/message.c -+++ b/drivers/usb/core/message.c -@@ -1113,6 +1113,21 @@ static void remove_intf_ep_devs(struct u - intf->ep_devs_created = 0; - } - -+void usb_fixup_endpoint(struct usb_device *dev, int epaddr, int interval) -+{ -+ unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK; -+ struct usb_host_endpoint *ep; -+ -+ if (usb_endpoint_out(epaddr)) -+ ep = dev->ep_out[epnum]; -+ else -+ ep = dev->ep_in[epnum]; -+ -+ if (ep && usb_endpoint_xfer_int(&ep->desc)) -+ usb_hcd_fixup_endpoint(dev, ep, interval); -+} -+EXPORT_SYMBOL_GPL(usb_fixup_endpoint); -+ - /** - * usb_disable_endpoint -- Disable an endpoint by address - * @dev: the device whose endpoint is being disabled ---- a/include/linux/usb.h -+++ b/include/linux/usb.h -@@ -1809,6 +1809,8 @@ extern int usb_clear_halt(struct usb_dev - extern int usb_reset_configuration(struct usb_device *dev); - extern int usb_set_interface(struct usb_device *dev, int ifnum, int alternate); - extern void usb_reset_endpoint(struct usb_device *dev, unsigned int epaddr); -+extern void usb_fixup_endpoint(struct usb_device *dev, int epaddr, -+ int interval); - - /* this request isn't really synchronous, but it belongs with the others */ - extern int usb_driver_set_configuration(struct usb_device *udev, int config); ---- a/include/linux/usb/hcd.h -+++ b/include/linux/usb/hcd.h -@@ -379,6 +379,11 @@ struct hc_driver { - * or bandwidth constraints. - */ - void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *); -+ /* Override the endpoint-derived interval -+ * (if there is any cached hardware state). -+ */ -+ void (*fixup_endpoint)(struct usb_hcd *hcd, struct usb_device *udev, -+ struct usb_host_endpoint *ep, int interval); - /* Returns the hardware-chosen device address */ - int (*address_device)(struct usb_hcd *, struct usb_device *udev); - /* prepares the hardware to send commands to the device */ -@@ -435,6 +440,8 @@ extern void usb_hcd_unmap_urb_setup_for_ - extern void usb_hcd_unmap_urb_for_dma(struct usb_hcd *, struct urb *); - extern void usb_hcd_flush_endpoint(struct usb_device *udev, - struct usb_host_endpoint *ep); -+extern void usb_hcd_fixup_endpoint(struct usb_device *udev, -+ struct usb_host_endpoint *ep, int interval); - extern void usb_hcd_disable_endpoint(struct usb_device *udev, - struct usb_host_endpoint *ep); - extern void usb_hcd_reset_endpoint(struct usb_device *udev, diff --git a/target/linux/brcm2708/patches-4.19/950-0661-arm-dts-Fix-Pi4-PWR-LED-configuration.patch b/target/linux/brcm2708/patches-4.19/950-0661-arm-dts-Fix-Pi4-PWR-LED-configuration.patch new file mode 100644 index 0000000000..8f296a3e35 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0661-arm-dts-Fix-Pi4-PWR-LED-configuration.patch @@ -0,0 +1,29 @@ +From 497f21437f6203798657467ffbc5d9e1f80c8cbb Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 17 Jun 2019 10:06:55 +0100 +Subject: [PATCH 661/725] arm: dts: Fix Pi4 PWR LED configuration + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts +@@ -126,13 +126,13 @@ + act_led: act { + label = "led0"; + linux,default-trigger = "mmc0"; +- gpios = <&gpio 42 0>; ++ gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; + }; + + pwr_led: pwr { + label = "led1"; +- linux,default-trigger = "input"; +- gpios = <&expgpio 2 0>; ++ linux,default-trigger = "default-on"; ++ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; + }; + }; + diff --git a/target/linux/brcm2708/patches-4.19/950-0661-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch b/target/linux/brcm2708/patches-4.19/950-0661-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch deleted file mode 100644 index 6b3e4e1619..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0661-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch +++ /dev/null @@ -1,129 +0,0 @@ -From ef57358754e9ab16429739d0ea1e479967ad4a40 Mon Sep 17 00:00:00 2001 -From: Jonathan Bell -Date: Tue, 11 Jun 2019 11:33:39 +0100 -Subject: [PATCH 661/703] xhci: implement xhci_fixup_endpoint for interval - adjustments - -Must be called in a non-atomic context, after the endpoint -has been registered with the hardware via xhci_add_endpoint -and before the first URB is submitted for the endpoint. - -Signed-off-by: Jonathan Bell ---- - drivers/usb/host/xhci.c | 98 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 98 insertions(+) - ---- a/drivers/usb/host/xhci.c -+++ b/drivers/usb/host/xhci.c -@@ -1416,6 +1416,103 @@ command_cleanup: - } - - /* -+ * RPI: Fixup endpoint intervals when requested -+ * - Check interval versus the (cached) endpoint context -+ * - set the endpoint interval to the new value -+ * - force an endpoint configure command -+ * XXX: bandwidth is not recalculated. We should probably do that. -+ */ -+static void xhci_fixup_endpoint(struct usb_hcd *hcd, struct usb_device *udev, -+ struct usb_host_endpoint *ep, int interval) -+{ -+ struct xhci_hcd *xhci; -+ struct xhci_ep_ctx *ep_ctx_out, *ep_ctx_in; -+ struct xhci_command *command; -+ struct xhci_input_control_ctx *ctrl_ctx; -+ struct xhci_virt_device *vdev; -+ int xhci_interval; -+ int ret; -+ int ep_index; -+ unsigned long flags; -+ u32 ep_info_tmp; -+ -+ xhci = hcd_to_xhci(hcd); -+ ep_index = xhci_get_endpoint_index(&ep->desc); -+ -+ /* FS/LS interval translations */ -+ if ((udev->speed == USB_SPEED_FULL || -+ udev->speed == USB_SPEED_LOW)) -+ interval *= 8; -+ -+ mutex_lock(&xhci->mutex); -+ -+ spin_lock_irqsave(&xhci->lock, flags); -+ -+ vdev = xhci->devs[udev->slot_id]; -+ /* Get context-derived endpoint interval */ -+ ep_ctx_out = xhci_get_ep_ctx(xhci, vdev->out_ctx, ep_index); -+ ep_ctx_in = xhci_get_ep_ctx(xhci, vdev->in_ctx, ep_index); -+ xhci_interval = EP_INTERVAL_TO_UFRAMES(le32_to_cpu(ep_ctx_out->ep_info)); -+ -+ if (interval == xhci_interval) { -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ mutex_unlock(&xhci->mutex); -+ return; -+ } -+ -+ xhci_dbg(xhci, "Fixup interval=%d xhci_interval=%d\n", -+ interval, xhci_interval); -+ command = xhci_alloc_command_with_ctx(xhci, true, GFP_ATOMIC); -+ if (!command) { -+ /* Failure here is benign, poll at the original rate */ -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ mutex_unlock(&xhci->mutex); -+ return; -+ } -+ -+ /* xHCI uses exponents for intervals... */ -+ xhci_interval = fls(interval) - 1; -+ xhci_interval = clamp_val(xhci_interval, 3, 10); -+ ep_info_tmp = le32_to_cpu(ep_ctx_out->ep_info); -+ ep_info_tmp &= ~EP_INTERVAL(255); -+ ep_info_tmp |= EP_INTERVAL(xhci_interval); -+ -+ /* Keep the endpoint context up-to-date while issuing the command. */ -+ xhci_endpoint_copy(xhci, vdev->in_ctx, -+ vdev->out_ctx, ep_index); -+ ep_ctx_in->ep_info = cpu_to_le32(ep_info_tmp); -+ -+ /* -+ * We need to drop the lock, so take an explicit copy -+ * of the ep context. -+ */ -+ xhci_endpoint_copy(xhci, command->in_ctx, vdev->in_ctx, ep_index); -+ -+ ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); -+ if (!ctrl_ctx) { -+ xhci_warn(xhci, -+ "%s: Could not get input context, bad type.\n", -+ __func__); -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ xhci_free_command(xhci, command); -+ mutex_unlock(&xhci->mutex); -+ return; -+ } -+ ctrl_ctx->add_flags = xhci_get_endpoint_flag_from_index(ep_index); -+ ctrl_ctx->drop_flags = 0; -+ -+ spin_unlock_irqrestore(&xhci->lock, flags); -+ -+ ret = xhci_configure_endpoint(xhci, udev, command, -+ false, false); -+ if (ret) -+ xhci_warn(xhci, "%s: Configure endpoint failed: %d\n", -+ __func__, ret); -+ xhci_free_command(xhci, command); -+ mutex_unlock(&xhci->mutex); -+} -+ -+/* - * non-error returns are a promise to giveback() the urb later - * we drop ownership so next owner (or urb unlink) can get it - */ -@@ -5180,6 +5277,7 @@ static const struct hc_driver xhci_hc_dr - .endpoint_reset = xhci_endpoint_reset, - .check_bandwidth = xhci_check_bandwidth, - .reset_bandwidth = xhci_reset_bandwidth, -+ .fixup_endpoint = xhci_fixup_endpoint, - .address_device = xhci_address_device, - .enable_device = xhci_enable_device, - .update_hub_device = xhci_update_hub_device, diff --git a/target/linux/brcm2708/patches-4.19/950-0662-bcm2838.dtsi-Correct-gic400-memory-address-ranges.patch b/target/linux/brcm2708/patches-4.19/950-0662-bcm2838.dtsi-Correct-gic400-memory-address-ranges.patch new file mode 100644 index 0000000000..a6e2349d11 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0662-bcm2838.dtsi-Correct-gic400-memory-address-ranges.patch @@ -0,0 +1,23 @@ +From 734c5130809cf1df460c80ef1c3805d4d56d89cb Mon Sep 17 00:00:00 2001 +From: dp111 +Date: Sat, 15 Jun 2019 18:19:50 +0100 +Subject: [PATCH 662/725] bcm2838.dtsi : Correct gic400 memory address ranges + +It appears to me the addresses for the gic400 are slightly wrong . See section 3.2 https://static.docs.arm.com/ddi0471/a/DDI0471A_gic400_r0p0_trm.pdf +--- + arch/arm/boot/dts/bcm2838.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/bcm2838.dtsi ++++ b/arch/arm/boot/dts/bcm2838.dtsi +@@ -30,8 +30,8 @@ + compatible = "arm,gic-400"; + reg = <0x40041000 0x1000>, + <0x40042000 0x2000>, +- <0x40046000 0x2000>, +- <0x40048000 0x2000>; ++ <0x40044000 0x2000>, ++ <0x40046000 0x2000>; + }; + + thermal: thermal@7d5d2200 { diff --git a/target/linux/brcm2708/patches-4.19/950-0662-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch b/target/linux/brcm2708/patches-4.19/950-0662-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch deleted file mode 100644 index 31e06f5a92..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0662-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch +++ /dev/null @@ -1,23 +0,0 @@ -From df99e61b9b0ce2018cb796f1b7b3298fd583c196 Mon Sep 17 00:00:00 2001 -From: Jonathan Bell -Date: Tue, 11 Jun 2019 11:42:03 +0100 -Subject: [PATCH 662/703] usbhid: call usb_fixup_endpoint after mangling - intervals - -Lets the mousepoll override mechanism work with xhci. - -Signed-off-by: Jonathan Bell ---- - drivers/hid/usbhid/hid-core.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/hid/usbhid/hid-core.c -+++ b/drivers/hid/usbhid/hid-core.c -@@ -1118,6 +1118,7 @@ static int usbhid_start(struct hid_devic - interval = hid_kbpoll_interval; - break; - } -+ usb_fixup_endpoint(dev, endpoint->bEndpointAddress, interval); - - ret = -ENOMEM; - if (usb_endpoint_dir_in(endpoint)) { diff --git a/target/linux/brcm2708/patches-4.19/950-0663-drm-vc4-Add-status-of-which-display-is-updated-throu.patch b/target/linux/brcm2708/patches-4.19/950-0663-drm-vc4-Add-status-of-which-display-is-updated-throu.patch deleted file mode 100644 index fbc037648a..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0663-drm-vc4-Add-status-of-which-display-is-updated-throu.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 6d90716cd7eac0219310ec8ba8a07e585db05932 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 4 Jun 2019 12:14:30 +0100 -Subject: [PATCH 663/703] drm: vc4: Add status of which display is updated - through vblank - -Previously multiple displays were slaved off the same SMI -interrupt, triggered by HVS channel 1 (HDMI0). -This doesn't work if you only have a DPI or DSI screen (HVS channel -0), and gives slightly erroneous results with dual HDMI as the -events for HDMI1 are incorrect. - -Use SMIDSW0 and SMIDSW1 registers to denote which display has -triggered the vblank. -Handling should be backwards compatible with older firmware. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 41 ++++++++++++++++++++++---- - 1 file changed, 36 insertions(+), 5 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -230,8 +230,13 @@ static const struct vc_image_format *vc4 - * hardware, which has only this one register. - */ - #define SMICS 0x0 -+#define SMIDSW0 0x14 -+#define SMIDSW1 0x1C - #define SMICS_INTERRUPTS (BIT(9) | BIT(10) | BIT(11)) - -+/* Flag to denote that the firmware is giving multiple display callbacks */ -+#define SMI_NEW 0xabcd0000 -+ - #define vc4_crtc vc4_kms_crtc - #define to_vc4_crtc to_vc4_kms_crtc - struct vc4_crtc { -@@ -884,16 +889,42 @@ static irqreturn_t vc4_crtc_irq_handler( - int i; - u32 stat = readl(crtc_list[0]->regs + SMICS); - irqreturn_t ret = IRQ_NONE; -+ u32 chan; - - if (stat & SMICS_INTERRUPTS) { - writel(0, crtc_list[0]->regs + SMICS); - -- for (i = 0; crtc_list[i]; i++) { -- if (crtc_list[i]->vblank_enabled) -- drm_crtc_handle_vblank(&crtc_list[i]->base); -- vc4_crtc_handle_page_flip(crtc_list[i]); -- ret = IRQ_HANDLED; -+ chan = readl(crtc_list[0]->regs + SMIDSW0); -+ -+ if ((chan & 0xFFFF0000) != SMI_NEW) { -+ /* Older firmware. Treat the one interrupt as vblank/ -+ * complete for all crtcs. -+ */ -+ for (i = 0; crtc_list[i]; i++) { -+ if (crtc_list[i]->vblank_enabled) -+ drm_crtc_handle_vblank(&crtc_list[i]->base); -+ vc4_crtc_handle_page_flip(crtc_list[i]); -+ } -+ } else { -+ if (chan & 1) { -+ writel(SMI_NEW, crtc_list[0]->regs + SMIDSW0); -+ if (crtc_list[0]->vblank_enabled) -+ drm_crtc_handle_vblank(&crtc_list[0]->base); -+ vc4_crtc_handle_page_flip(crtc_list[0]); -+ } -+ -+ /* Check for the secondary display too */ -+ chan = readl(crtc_list[0]->regs + SMIDSW1); -+ -+ if (chan & 1) { -+ writel(SMI_NEW, crtc_list[0]->regs + SMIDSW1); -+ if (crtc_list[1]->vblank_enabled) -+ drm_crtc_handle_vblank(&crtc_list[1]->base); -+ vc4_crtc_handle_page_flip(crtc_list[1]); -+ } - } -+ -+ ret = IRQ_HANDLED; - } - - return ret; diff --git a/target/linux/brcm2708/patches-4.19/950-0663-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch b/target/linux/brcm2708/patches-4.19/950-0663-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch new file mode 100644 index 0000000000..2378811686 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0663-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch @@ -0,0 +1,51 @@ +From 2d7cb00a7971c8384aacd0455a6d5e50abedb1e9 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 18 Jun 2019 12:15:50 +0100 +Subject: [PATCH 663/725] staging: vchiq: Use the old dma controller for OF + config on platform devices + +vchiq on Pi4 is no longer under the soc node, therefore it +doesn't get the dma-ranges for the VPU. + +Switch to using the configuration of the old dma controller as +that will set the dma-ranges correctly. + +Signed-off-by: Dave Stevenson +--- + .../interface/vchiq_arm/vchiq_arm.c | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +@@ -3599,6 +3599,7 @@ vchiq_register_child(struct platform_dev + { + struct platform_device_info pdevinfo; + struct platform_device *new_dev; ++ struct device_node *np; + + memset(&pdevinfo, 0, sizeof(pdevinfo)); + +@@ -3612,10 +3613,20 @@ vchiq_register_child(struct platform_dev + return NULL; + + /* +- * We want the dma-ranges etc to be copied from the parent VCHIQ device +- * to be passed on to the children too. ++ * We want the dma-ranges etc to be copied from a device with the ++ * correct dma-ranges for the VPU. ++ * VCHIQ on Pi4 is now under scb which doesn't get those dma-ranges. ++ * Take the "dma" node as going to be suitable as it sees the world ++ * through the same eyes as the VPU. + */ +- of_dma_configure(&new_dev->dev, pdev->dev.of_node, true); ++ np = of_find_node_by_path("dma"); ++ if (!np) ++ np = pdev->dev.of_node; ++ ++ of_dma_configure(&new_dev->dev, np, true); ++ ++ if (np != pdev->dev.of_node) ++ of_node_put(np); + + return new_dev; + } diff --git a/target/linux/brcm2708/patches-4.19/950-0664-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch b/target/linux/brcm2708/patches-4.19/950-0664-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch deleted file mode 100644 index cd2f7bd04f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0664-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch +++ /dev/null @@ -1,36 +0,0 @@ -From da7972664ce5c26a876d092d8161901985f9fa8f Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 12 Jun 2019 17:13:21 +0100 -Subject: [PATCH 664/703] drm/vc4: In FKMS look at the modifiers correctly for - SAND - -Incorrect masking was used in the switch for the modifier, -therefore for SAND (which puts the column pitch in the -modifier) it didn't match. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -460,7 +460,7 @@ static void vc4_plane_atomic_update(stru - } - mb->plane.planes[3] = 0; - -- switch (fb->modifier) { -+ switch (fourcc_mod_broadcom_mod(fb->modifier)) { - case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: - switch (mb->plane.vc_image_type) { - case VC_IMAGE_XRGB8888: -@@ -476,6 +476,9 @@ static void vc4_plane_atomic_update(stru - break; - case DRM_FORMAT_MOD_BROADCOM_SAND128: - mb->plane.vc_image_type = VC_IMAGE_YUV_UV; -+ /* Note that the column pitch is passed across in lines, not -+ * bytes. -+ */ - mb->plane.pitch = fourcc_mod_broadcom_param(fb->modifier); - break; - } diff --git a/target/linux/brcm2708/patches-4.19/950-0664-drm-vc4-Limit-fkms-to-modes-85Hz.patch b/target/linux/brcm2708/patches-4.19/950-0664-drm-vc4-Limit-fkms-to-modes-85Hz.patch new file mode 100644 index 0000000000..c86381607c --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0664-drm-vc4-Limit-fkms-to-modes-85Hz.patch @@ -0,0 +1,26 @@ +From 9fef544e7d4981b5611b857609e18a20dea246e8 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 18 Jun 2019 21:37:45 +0100 +Subject: [PATCH 664/725] drm/vc4: Limit fkms to modes <= 85Hz + +Selecting 1080p100 and 120 has very limited gain, but don't want +to block VGA85 and similar. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -822,6 +822,10 @@ vc4_crtc_mode_valid(struct drm_crtc *crt + return MODE_NO_DBLESCAN; + } + ++ /* Disable refresh rates > 85Hz as limited gain from them */ ++ if (drm_mode_vrefresh(mode) > 85) ++ return MODE_BAD_VVALUE; ++ + /* Limit the pixel clock based on the HDMI clock limits from the + * firmware + */ diff --git a/target/linux/brcm2708/patches-4.19/950-0665-arm-bcm2835-Add-bcm2838-compatible-string.patch b/target/linux/brcm2708/patches-4.19/950-0665-arm-bcm2835-Add-bcm2838-compatible-string.patch new file mode 100644 index 0000000000..1685297457 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0665-arm-bcm2835-Add-bcm2838-compatible-string.patch @@ -0,0 +1,20 @@ +From 9c89497bb48601b3b1cbf8b868840da3091cc00f Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 11 Jun 2019 17:38:28 +0100 +Subject: [PATCH 665/725] arm: bcm2835: Add bcm2838 compatible string. + +Signed-off-by: Phil Elwell +--- + arch/arm/mach-bcm/board_bcm2835.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm/mach-bcm/board_bcm2835.c ++++ b/arch/arm/mach-bcm/board_bcm2835.c +@@ -118,6 +118,7 @@ static const char * const bcm2835_compat + #ifdef CONFIG_ARCH_MULTI_V7 + "brcm,bcm2836", + "brcm,bcm2837", ++ "brcm,bcm2838", + #endif + NULL + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0665-arm-dts-Fix-Pi4-PWR-LED-configuration.patch b/target/linux/brcm2708/patches-4.19/950-0665-arm-dts-Fix-Pi4-PWR-LED-configuration.patch deleted file mode 100644 index e3b343f6cc..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0665-arm-dts-Fix-Pi4-PWR-LED-configuration.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 119a795378e218aef556999cdeb7ebb44e5fa106 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 17 Jun 2019 10:06:55 +0100 -Subject: [PATCH 665/703] arm: dts: Fix Pi4 PWR LED configuration - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts -+++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts -@@ -126,13 +126,13 @@ - act_led: act { - label = "led0"; - linux,default-trigger = "mmc0"; -- gpios = <&gpio 42 0>; -+ gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; - }; - - pwr_led: pwr { - label = "led1"; -- linux,default-trigger = "input"; -- gpios = <&expgpio 2 0>; -+ linux,default-trigger = "default-on"; -+ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; - }; - }; - diff --git a/target/linux/brcm2708/patches-4.19/950-0666-arm-dts-Improve-the-bcm27xx-inclusion-hierarchy.patch b/target/linux/brcm2708/patches-4.19/950-0666-arm-dts-Improve-the-bcm27xx-inclusion-hierarchy.patch new file mode 100644 index 0000000000..206ce6d287 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0666-arm-dts-Improve-the-bcm27xx-inclusion-hierarchy.patch @@ -0,0 +1,490 @@ +From 22742682cf7b7840f50006022350b40b9b095902 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 4 Jun 2019 16:22:22 +0100 +Subject: [PATCH 666/725] arm: dts: Improve the bcm27xx inclusion hierarchy + +1) The top-level .dts files now include parallel chains of bcm27xx.dtsi + and bcm27xx-rpi.dtsi files, with no cross-inclusion between the two + chains. + +2) Move definitions and deletions to the point of maximum commonality + to reduce redundancy. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 1 + + arch/arm/boot/dts/bcm2708-rpi-b.dts | 1 + + arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 1 + + arch/arm/boot/dts/bcm2708-rpi-zero-w.dts | 1 + + arch/arm/boot/dts/bcm2708-rpi-zero.dts | 1 + + arch/arm/boot/dts/bcm2708-rpi.dtsi | 63 +++++++--------------- + arch/arm/boot/dts/bcm2708.dtsi | 1 - + arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 1 + + arch/arm/boot/dts/bcm2709.dtsi | 1 - + arch/arm/boot/dts/bcm270x.dtsi | 18 +------ + arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 1 + + arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 1 + + arch/arm/boot/dts/bcm2710-rpi-cm3.dts | 1 + + arch/arm/boot/dts/bcm2710.dtsi | 1 - + arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 15 ++++-- + arch/arm/boot/dts/bcm2711-rpi.dtsi | 7 +++ + arch/arm/boot/dts/bcm2711.dtsi | 10 ---- + arch/arm/boot/dts/bcm2835-rpi.dtsi | 16 ++++++ + arch/arm/boot/dts/bcm2838.dtsi | 33 ++++++++---- + arch/arm/boot/dts/bcm283x.dtsi | 2 +- + 20 files changed, 86 insertions(+), 90 deletions(-) + create mode 100644 arch/arm/boot/dts/bcm2711-rpi.dtsi + +--- 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 "bcm2708-rpi.dtsi" + #include "bcm283x-rpi-smsc9514.dtsi" + #include "bcm283x-rpi-csi1-2lane.dtsi" + +--- 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 "bcm2708-rpi.dtsi" + #include "bcm283x-rpi-smsc9512.dtsi" + #include "bcm283x-rpi-csi1-2lane.dtsi" + +--- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi ++++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi +@@ -1,4 +1,5 @@ + #include "bcm2708.dtsi" ++#include "bcm2708-rpi.dtsi" + + &leds { + act_led: act { +--- a/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts +@@ -1,6 +1,7 @@ + /dts-v1/; + + #include "bcm2708.dtsi" ++#include "bcm2708-rpi.dtsi" + #include "bcm283x-rpi-csi1-2lane.dtsi" + + / { +--- a/arch/arm/boot/dts/bcm2708-rpi-zero.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-zero.dts +@@ -1,6 +1,7 @@ + /dts-v1/; + + #include "bcm2708.dtsi" ++#include "bcm2708-rpi.dtsi" + #include "bcm283x-rpi-csi1-2lane.dtsi" + + / { +--- a/arch/arm/boot/dts/bcm2708-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2708-rpi.dtsi +@@ -1,6 +1,6 @@ +-/* Downstream version of bcm2835-rpi.dtsi */ ++/* Downstream modifications to bcm2835-rpi.dtsi */ + +-#include ++#include "bcm2835-rpi.dtsi" + + / { + memory { +@@ -49,29 +49,10 @@ + reg = <0x7e200000 0x1000>; + }; + +- firmware: firmware { +- compatible = "raspberrypi,bcm2835-firmware", "simple-bus"; +- #address-cells = <0>; +- #size-cells = <0>; +- mboxes = <&mailbox>; +- }; +- +- power: power { +- compatible = "raspberrypi,bcm2835-power"; +- firmware = <&firmware>; +- #power-domain-cells = <1>; +- }; +- + fb: fb { + compatible = "brcm,bcm2708-fb"; + firmware = <&firmware>; +- status = "disabled"; +- }; +- +- vchiq: mailbox@7e00b840 { +- compatible = "brcm,bcm2835-vchiq"; +- reg = <0x7e00b840 0x3c>; +- interrupts = <0 2>; ++ status = "okay"; + }; + + vcsm: vcsm { +@@ -91,10 +72,6 @@ + sound: sound { + status = "disabled"; + }; +- +- txp: txp@7e004000 { +- status = "disabled"; +- }; + }; + + __overrides__ { +@@ -125,11 +102,23 @@ + }; + + &hdmi { +- power-domains = <&power RPI_POWER_DOMAIN_HDMI>; ++ status = "disabled"; + }; + +-&usb { +- power-domains = <&power RPI_POWER_DOMAIN_USB>; ++&txp { ++ status = "disabled"; ++}; ++ ++&i2c0 { ++ status = "disabled"; ++}; ++ ++&i2c1 { ++ status = "disabled"; ++}; ++ ++&i2c2 { ++ status = "disabled"; + }; + + &clocks { +@@ -141,16 +130,8 @@ sdhost_pins: &sdhost_gpio48 { + }; + + &sdhost { +- pinctrl-names = "default"; +- pinctrl-0 = <&sdhost_gpio48>; +- bus-width = <4>; + brcm,overclock-50 = <0>; + brcm,pio-limit = <1>; +- status = "okay"; +-}; +- +-&fb { +- status = "okay"; + }; + + &cpu_thermal { +@@ -160,11 +141,3 @@ sdhost_pins: &sdhost_gpio48 { + &vec { + status = "disabled"; + }; +- +-&csi0 { +- power-domains = <&power RPI_POWER_DOMAIN_UNICAM0>; +-}; +- +-&csi1 { +- power-domains = <&power RPI_POWER_DOMAIN_UNICAM1>; +-}; +--- a/arch/arm/boot/dts/bcm2708.dtsi ++++ b/arch/arm/boot/dts/bcm2708.dtsi +@@ -1,6 +1,5 @@ + #include "bcm2835.dtsi" + #include "bcm270x.dtsi" +-#include "bcm2708-rpi.dtsi" + + / { + /delete-node/ cpus; +--- 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 "bcm2709-rpi.dtsi" + #include "bcm283x-rpi-smsc9514.dtsi" + #include "bcm283x-rpi-csi1-2lane.dtsi" + +--- a/arch/arm/boot/dts/bcm2709.dtsi ++++ b/arch/arm/boot/dts/bcm2709.dtsi +@@ -1,6 +1,5 @@ + #include "bcm2836.dtsi" + #include "bcm270x.dtsi" +-#include "bcm2709-rpi.dtsi" + + / { + soc { +--- a/arch/arm/boot/dts/bcm270x.dtsi ++++ b/arch/arm/boot/dts/bcm270x.dtsi +@@ -68,7 +68,7 @@ + + /delete-node/ sdhci@7e300000; + +- mmc: mmc@7e300000 { ++ sdhci: mmc: mmc@7e300000 { + compatible = "brcm,bcm2835-mmc", "brcm,bcm2835-sdhci"; + reg = <0x7e300000 0x100>; + interrupts = <2 30>; +@@ -152,22 +152,6 @@ + }; + }; + +- vdd_5v0_reg: fixedregulator_5v0 { +- compatible = "regulator-fixed"; +- regulator-name = "5v0"; +- regulator-min-microvolt = <5000000>; +- regulator-max-microvolt = <5000000>; +- regulator-always-on; +- }; +- +- vdd_3v3_reg: fixedregulator_3v3 { +- compatible = "regulator-fixed"; +- regulator-name = "3v3"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- regulator-always-on; +- }; +- + __overrides__ { + cam0-pwdn-ctrl; + cam0-pwdn; +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts +@@ -1,6 +1,7 @@ + /dts-v1/; + + #include "bcm2710.dtsi" ++#include "bcm2709-rpi.dtsi" + #include "bcm283x-rpi-lan7515.dtsi" + #include "bcm283x-rpi-csi1-2lane.dtsi" + +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +@@ -1,6 +1,7 @@ + /dts-v1/; + + #include "bcm2710.dtsi" ++#include "bcm2709-rpi.dtsi" + #include "bcm283x-rpi-smsc9514.dtsi" + #include "bcm283x-rpi-csi1-2lane.dtsi" + +--- a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts +@@ -1,6 +1,7 @@ + /dts-v1/; + + #include "bcm2710.dtsi" ++#include "bcm2709-rpi.dtsi" + #include "bcm283x-rpi-csi0-2lane.dtsi" + #include "bcm283x-rpi-csi1-4lane.dtsi" + +--- a/arch/arm/boot/dts/bcm2710.dtsi ++++ b/arch/arm/boot/dts/bcm2710.dtsi +@@ -1,6 +1,5 @@ + #include "bcm2837.dtsi" + #include "bcm270x.dtsi" +-#include "bcm2709-rpi.dtsi" + + / { + compatible = "brcm,bcm2837", "brcm,bcm2836"; +--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts +@@ -1,13 +1,12 @@ + /dts-v1/; + + #include "bcm2711.dtsi" ++#include "bcm2711-rpi.dtsi" + #include "bcm283x-rpi-csi1-2lane.dtsi" + + / { +- compatible = "raspberrypi,4-model-b", "brcm,bcm2838", "brcm,bcm2837"; ++ compatible = "raspberrypi,4-model-b", "brcm,bcm2838"; + model = "Raspberry Pi 4 Model B"; +- #address-cells = <2>; +- #size-cells = <1>; + + memory { + device_type = "memory"; +@@ -48,10 +47,18 @@ + }; + + &firmware { +- expgpio: expgpio { ++ expgpio: gpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; + #gpio-cells = <2>; ++ gpio-line-names = "BT_ON", ++ "WL_ON", ++ "PWR_LED_OFF", ++ "GLOBAL_RESET", ++ "VDD_SD_IO_SEL", ++ "CAM_GPIO", ++ "", ++ ""; + status = "okay"; + }; + }; +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi +@@ -0,0 +1,7 @@ ++#include "bcm2708-rpi.dtsi" ++#include "bcm2838-rpi.dtsi" ++ ++&v3d { ++ /* Undo the overwriting by bcm270x.dtsi */ ++ power-domains = <&pm BCM2835_POWER_DOMAIN_GRAFX_V3D>; ++}; +--- a/arch/arm/boot/dts/bcm2711.dtsi ++++ b/arch/arm/boot/dts/bcm2711.dtsi +@@ -1,10 +1,8 @@ + #include "bcm2838.dtsi" + #include "bcm270x.dtsi" +-#include "bcm2708-rpi.dtsi" + + / { + soc { +- /delete-node/ mailbox@7e00b840; + /delete-node/ v3d@7ec00000; + }; + +@@ -17,14 +15,6 @@ + status = "disabled"; + }; + +-&dma { +- brcm,dma-channel-mask = <0x7ef5>; +-}; +- +-&txp { +- interrupts = ; +-}; +- + &firmwarekms { + interrupts = ; + }; +--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi +@@ -36,6 +36,22 @@ + interrupts = <0 2>; + }; + }; ++ ++ vdd_3v3_reg: fixedregulator_3v3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "3v3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ }; ++ ++ vdd_5v0_reg: fixedregulator_5v0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "5v0"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ }; + }; + + &gpio { +--- a/arch/arm/boot/dts/bcm2838.dtsi ++++ b/arch/arm/boot/dts/bcm2838.dtsi +@@ -5,7 +5,10 @@ + #include + + / { +- compatible = "brcm,bcm2838", "brcm,bcm2837"; ++ compatible = "brcm,bcm2838"; ++ ++ #address-cells = <2>; ++ #size-cells = <1>; + + interrupt-parent = <&gicv2>; + +@@ -16,8 +19,8 @@ + /* Emulate a contiguous 30-bit address range for DMA */ + dma-ranges = <0xc0000000 0x0 0x00000000 0x3c000000>; + +- /delete-node/ mailbox@7e00b840; + /delete-node/ interrupt-controller@7e00f300; ++ /delete-node/ v3d@7ec00000; + + local_intc: local_intc@40000000 { + compatible = "brcm,bcm2836-l1-intc"; +@@ -191,6 +194,16 @@ + interrupts = ; + }; + ++ pwm1: pwm@7e20c800 { ++ compatible = "brcm,bcm2835-pwm"; ++ reg = <0x7e20c800 0x28>; ++ clocks = <&clocks BCM2835_CLOCK_PWM>; ++ assigned-clocks = <&clocks BCM2835_CLOCK_PWM>; ++ assigned-clock-rates = <10000000>; ++ #pwm-cells = <2>; ++ status = "disabled"; ++ }; ++ + emmc2: emmc2@7e340000 { + compatible = "brcm,bcm2711-emmc2"; + status = "okay"; +@@ -385,7 +398,7 @@ + "dma13", + "dma14"; + #dma-cells = <1>; +- brcm,dma-channel-mask = <0x7000>; ++ brcm,dma-channel-mask = <0x7800>; + }; + /* DMA4 - 40 bit DMA engines */ + +@@ -396,12 +409,6 @@ + interrupts = ; + }; + +- vchiq: mailbox@7e00b840 { +- compatible = "brcm,bcm2838-vchiq"; +- reg = <0 0x7e00b840 0x3c>; +- interrupts = ; +- }; +- + hevc-decoder@7eb00000 { + compatible = "raspberrypi,argon-hevc-decoder"; + reg = <0x0 0x7eb00000 0x10000>; +@@ -450,6 +457,8 @@ + }; + + &gpio { ++ compatible = "brcm,bcm2838-gpio", "brcm,bcm2835-gpio"; ++ + gpclk0_gpio49: gpclk0_gpio49 { + brcm,pins = <49>; + brcm,function = ; +@@ -729,5 +738,9 @@ + "dma8", + "dma9", + "dma10"; +- brcm,dma-channel-mask = <0x01f5>; ++ brcm,dma-channel-mask = <0x07f5>; ++}; ++ ++&txp { ++ interrupts = ; + }; +--- a/arch/arm/boot/dts/bcm283x.dtsi ++++ b/arch/arm/boot/dts/bcm283x.dtsi +@@ -55,7 +55,7 @@ + #address-cells = <1>; + #size-cells = <1>; + +- txp@7e004000 { ++ txp: txp@7e004000 { + compatible = "brcm,bcm2835-txp"; + reg = <0x7e004000 0x20>; + interrupts = <1 11>; diff --git a/target/linux/brcm2708/patches-4.19/950-0666-bcm2838.dtsi-Correct-gic400-memory-address-ranges.patch b/target/linux/brcm2708/patches-4.19/950-0666-bcm2838.dtsi-Correct-gic400-memory-address-ranges.patch deleted file mode 100644 index 6946235d35..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0666-bcm2838.dtsi-Correct-gic400-memory-address-ranges.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 8514b037813eddea0ecc044978a36fe815a29b01 Mon Sep 17 00:00:00 2001 -From: dp111 -Date: Sat, 15 Jun 2019 18:19:50 +0100 -Subject: [PATCH 666/703] bcm2838.dtsi : Correct gic400 memory address ranges - -It appears to me the addresses for the gic400 are slightly wrong . See section 3.2 https://static.docs.arm.com/ddi0471/a/DDI0471A_gic400_r0p0_trm.pdf ---- - arch/arm/boot/dts/bcm2838.dtsi | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/arch/arm/boot/dts/bcm2838.dtsi -+++ b/arch/arm/boot/dts/bcm2838.dtsi -@@ -30,8 +30,8 @@ - compatible = "arm,gic-400"; - reg = <0x40041000 0x1000>, - <0x40042000 0x2000>, -- <0x40046000 0x2000>, -- <0x40048000 0x2000>; -+ <0x40044000 0x2000>, -+ <0x40046000 0x2000>; - }; - - thermal: thermal@7d5d2200 { diff --git a/target/linux/brcm2708/patches-4.19/950-0667-arm-dts-First-draft-of-upstream-Pi4-DTS.patch b/target/linux/brcm2708/patches-4.19/950-0667-arm-dts-First-draft-of-upstream-Pi4-DTS.patch new file mode 100644 index 0000000000..6762d8b959 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0667-arm-dts-First-draft-of-upstream-Pi4-DTS.patch @@ -0,0 +1,176 @@ +From 3183783f2a7db515671c6c612988627f946b4a36 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 11 Jun 2019 18:08:05 +0100 +Subject: [PATCH 667/725] arm: dts: First draft of upstream Pi4 DTS + +I've attempted to follow the upstream conventions in the DT commits, +but this is just presented here initially as a talking point. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/Makefile | 1 + + arch/arm/boot/dts/bcm2838-rpi-4-b.dts | 118 ++++++++++++++++++++++++++ + arch/arm/boot/dts/bcm2838-rpi.dtsi | 25 ++++++ + 3 files changed, 144 insertions(+) + create mode 100644 arch/arm/boot/dts/bcm2838-rpi-4-b.dts + create mode 100644 arch/arm/boot/dts/bcm2838-rpi.dtsi + +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -94,6 +94,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ + bcm2836-rpi-2-b.dtb \ + bcm2837-rpi-3-b.dtb \ + bcm2837-rpi-3-b-plus.dtb \ ++ bcm2838-rpi-4-b.dtb \ + bcm2835-rpi-zero.dtb \ + bcm2835-rpi-zero-w.dtb + dtb-$(CONFIG_ARCH_BCM_5301X) += \ +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2838-rpi-4-b.dts +@@ -0,0 +1,118 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/dts-v1/; ++#include "bcm2838.dtsi" ++#include "bcm2835-rpi.dtsi" ++#include "bcm2838-rpi.dtsi" ++ ++/ { ++ compatible = "raspberrypi,4-model-b", "brcm,bcm2838"; ++ model = "Raspberry Pi 4 Model B"; ++ ++ chosen { ++ /* 8250 auxiliary UART instead of pl011 */ ++ stdout-path = "serial1:115200n8"; ++ }; ++ ++ memory { ++ reg = <0 0 0x40000000>; ++ }; ++ ++ leds { ++ act { ++ gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ pwr { ++ label = "PWR"; ++ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ wifi_pwrseq: wifi-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>; ++ }; ++ ++ sd_io_1v8_reg: sd_io_1v8_reg { ++ status = "okay"; ++ compatible = "regulator-gpio"; ++ vin-supply = <&vdd_5v0_reg>; ++ regulator-name = "vdd-sd-io"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-settling-time-us = <5000>; ++ ++ gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>; ++ states = <1800000 0x1 ++ 3300000 0x0>; ++ }; ++}; ++ ++&firmware { ++ expgpio: gpio { ++ compatible = "raspberrypi,firmware-gpio"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ gpio-line-names = "BT_ON", ++ "WL_ON", ++ "PWR_LED_OFF", ++ "GLOBAL_RESET", ++ "VDD_SD_IO_SEL", ++ "CAM_GPIO", ++ "", ++ ""; ++ status = "okay"; ++ }; ++}; ++ ++&pwm1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm0_gpio40 &pwm1_gpio41>; ++ status = "okay"; ++}; ++ ++/* SDHCI is used to control the SDIO for wireless */ ++&sdhci { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_gpio34>; ++ status = "okay"; ++ bus-width = <4>; ++ non-removable; ++ mmc-pwrseq = <&wifi_pwrseq>; ++ ++ brcmf: wifi@1 { ++ reg = <1>; ++ compatible = "brcm,bcm4329-fmac"; ++ }; ++}; ++ ++/* EMMC2 is used to drive the SD card */ ++&emmc2 { ++ status = "okay"; ++ broken-cd; ++ vqmmc-supply = <&sd_io_1v8_reg>; ++}; ++ ++/* uart0 communicates with the BT module */ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32 &gpclk2_gpio43>; ++ status = "okay"; ++ ++ bluetooth { ++ compatible = "brcm,bcm43438-bt"; ++ max-speed = <2000000>; ++ shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++/* uart1 is mapped to the pin header */ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_gpio14>; ++ status = "okay"; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2838-rpi.dtsi +@@ -0,0 +1,25 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++/ { ++ soc { ++ /delete-node/ mailbox@7e00b840; ++ }; ++}; ++ ++&scb { ++ vchiq: mailbox@7e00b840 { ++ compatible = "brcm,bcm2838-vchiq"; ++ reg = <0 0x7e00b840 0x3c>; ++ interrupts = ; ++ }; ++}; ++ ++&dma { ++ /* The VPU firmware uses DMA channel 11 for VCHIQ */ ++ brcm,dma-channel-mask = <0x1f5>; ++}; ++ ++&dma40 { ++ /* The VPU firmware DMA channel 11 for VCHIQ */ ++ brcm,dma-channel-mask = <0x7000>; ++}; diff --git a/target/linux/brcm2708/patches-4.19/950-0667-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch b/target/linux/brcm2708/patches-4.19/950-0667-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch deleted file mode 100644 index 19d8d33057..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0667-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 9d6d168d99226d7f31cb1ba56ada37913ebd690a Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 18 Jun 2019 12:15:50 +0100 -Subject: [PATCH 667/703] staging: vchiq: Use the old dma controller for OF - config on platform devices - -vchiq on Pi4 is no longer under the soc node, therefore it -doesn't get the dma-ranges for the VPU. - -Switch to using the configuration of the old dma controller as -that will set the dma-ranges correctly. - -Signed-off-by: Dave Stevenson ---- - .../interface/vchiq_arm/vchiq_arm.c | 17 ++++++++++++++--- - 1 file changed, 14 insertions(+), 3 deletions(-) - ---- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -3599,6 +3599,7 @@ vchiq_register_child(struct platform_dev - { - struct platform_device_info pdevinfo; - struct platform_device *new_dev; -+ struct device_node *np; - - memset(&pdevinfo, 0, sizeof(pdevinfo)); - -@@ -3612,10 +3613,20 @@ vchiq_register_child(struct platform_dev - return NULL; - - /* -- * We want the dma-ranges etc to be copied from the parent VCHIQ device -- * to be passed on to the children too. -+ * We want the dma-ranges etc to be copied from a device with the -+ * correct dma-ranges for the VPU. -+ * VCHIQ on Pi4 is now under scb which doesn't get those dma-ranges. -+ * Take the "dma" node as going to be suitable as it sees the world -+ * through the same eyes as the VPU. - */ -- of_dma_configure(&new_dev->dev, pdev->dev.of_node, true); -+ np = of_find_node_by_path("dma"); -+ if (!np) -+ np = pdev->dev.of_node; -+ -+ of_dma_configure(&new_dev->dev, np, true); -+ -+ if (np != pdev->dev.of_node) -+ of_node_put(np); - - return new_dev; - } diff --git a/target/linux/brcm2708/patches-4.19/950-0668-drm-vc4-Limit-fkms-to-modes-85Hz.patch b/target/linux/brcm2708/patches-4.19/950-0668-drm-vc4-Limit-fkms-to-modes-85Hz.patch deleted file mode 100644 index 314357e4ce..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0668-drm-vc4-Limit-fkms-to-modes-85Hz.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 912084a11b3b27c771dddfaf670fdf35433c969f Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 18 Jun 2019 21:37:45 +0100 -Subject: [PATCH 668/703] drm/vc4: Limit fkms to modes <= 85Hz - -Selecting 1080p100 and 120 has very limited gain, but don't want -to block VGA85 and similar. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -822,6 +822,10 @@ vc4_crtc_mode_valid(struct drm_crtc *crt - return MODE_NO_DBLESCAN; - } - -+ /* Disable refresh rates > 85Hz as limited gain from them */ -+ if (drm_mode_vrefresh(mode) > 85) -+ return MODE_BAD_VVALUE; -+ - /* Limit the pixel clock based on the HDMI clock limits from the - * firmware - */ diff --git a/target/linux/brcm2708/patches-4.19/950-0668-overlays-Fix-compatible-string-for-ds1307-RTC.patch b/target/linux/brcm2708/patches-4.19/950-0668-overlays-Fix-compatible-string-for-ds1307-RTC.patch new file mode 100644 index 0000000000..d25284435a --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0668-overlays-Fix-compatible-string-for-ds1307-RTC.patch @@ -0,0 +1,28 @@ +From 6c53b393a82affcdb32ca7a81871130db5ec149b Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 17 Jun 2019 14:36:12 +0100 +Subject: [PATCH 668/725] overlays: Fix compatible string for ds1307 RTC + +Kernels since 4.19 have required the correct manufacture name in the +compatible string for I2C devices, and unfortunately the one for the +Dallas/Maxim DS1307 should have been "dallas,ds1307" and not +"maxim,ds1307". + +See: https://github.com/raspberrypi/linux/issues/3013 + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts +@@ -30,7 +30,7 @@ + status = "okay"; + + ds1307: ds1307@68 { +- compatible = "maxim,ds1307"; ++ compatible = "dallas,ds1307"; + reg = <0x68>; + status = "okay"; + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0669-arm-bcm2835-Add-bcm2838-compatible-string.patch b/target/linux/brcm2708/patches-4.19/950-0669-arm-bcm2835-Add-bcm2838-compatible-string.patch deleted file mode 100644 index 364d8b517e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0669-arm-bcm2835-Add-bcm2838-compatible-string.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 7142fbe9edf1c608d788569cb399aa075f2ee837 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 11 Jun 2019 17:38:28 +0100 -Subject: [PATCH 669/703] arm: bcm2835: Add bcm2838 compatible string. - -Signed-off-by: Phil Elwell ---- - arch/arm/mach-bcm/board_bcm2835.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm/mach-bcm/board_bcm2835.c -+++ b/arch/arm/mach-bcm/board_bcm2835.c -@@ -118,6 +118,7 @@ static const char * const bcm2835_compat - #ifdef CONFIG_ARCH_MULTI_V7 - "brcm,bcm2836", - "brcm,bcm2837", -+ "brcm,bcm2838", - #endif - NULL - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0669-overlays-Fix-further-maxim-ds1307-references.patch b/target/linux/brcm2708/patches-4.19/950-0669-overlays-Fix-further-maxim-ds1307-references.patch new file mode 100644 index 0000000000..74a75ff4f3 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0669-overlays-Fix-further-maxim-ds1307-references.patch @@ -0,0 +1,47 @@ +From a0a581e7019049be7f62f9251bdbe4f9e09485a0 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 18 Jun 2019 11:16:13 +0100 +Subject: [PATCH 669/725] overlays: Fix further maxim,ds1307 references + +See: https://github.com/raspberrypi/linux/issues/3013 + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/balena-fin-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/arm/boot/dts/overlays/balena-fin-overlay.dts ++++ b/arch/arm/boot/dts/overlays/balena-fin-overlay.dts +@@ -84,7 +84,7 @@ + + // rtc clock + ds1307: ds1307@68 { +- compatible = "maxim,ds1307"; ++ compatible = "dallas,ds1307"; + reg = <0x68>; + status = "okay"; + }; +--- a/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts +@@ -46,7 +46,7 @@ + status = "okay"; + + ds1307: ds1307@68 { +- compatible = "maxim,ds1307"; ++ compatible = "dallas,ds1307"; + reg = <0x68>; + status = "okay"; + }; +--- a/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts ++++ b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts +@@ -155,7 +155,7 @@ + status = "okay"; + + ds1307: ds1307@68 { +- compatible = "maxim,ds1307"; ++ compatible = "dallas,ds1307"; + reg = <0x68>; + status = "okay"; + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0670-arm-dts-Improve-the-bcm27xx-inclusion-hierarchy.patch b/target/linux/brcm2708/patches-4.19/950-0670-arm-dts-Improve-the-bcm27xx-inclusion-hierarchy.patch deleted file mode 100644 index 74fd795a01..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0670-arm-dts-Improve-the-bcm27xx-inclusion-hierarchy.patch +++ /dev/null @@ -1,490 +0,0 @@ -From c0cff263c6927ed494f81fcde6bf6fe00e33271b Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 4 Jun 2019 16:22:22 +0100 -Subject: [PATCH 670/703] arm: dts: Improve the bcm27xx inclusion hierarchy - -1) The top-level .dts files now include parallel chains of bcm27xx.dtsi - and bcm27xx-rpi.dtsi files, with no cross-inclusion between the two - chains. - -2) Move definitions and deletions to the point of maximum commonality - to reduce redundancy. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-b.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 1 + - arch/arm/boot/dts/bcm2708-rpi-zero-w.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-zero.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi.dtsi | 63 +++++++--------------- - arch/arm/boot/dts/bcm2708.dtsi | 1 - - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 1 + - arch/arm/boot/dts/bcm2709.dtsi | 1 - - arch/arm/boot/dts/bcm270x.dtsi | 18 +------ - arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 1 + - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 1 + - arch/arm/boot/dts/bcm2710-rpi-cm3.dts | 1 + - arch/arm/boot/dts/bcm2710.dtsi | 1 - - arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 15 ++++-- - arch/arm/boot/dts/bcm2711-rpi.dtsi | 7 +++ - arch/arm/boot/dts/bcm2711.dtsi | 10 ---- - arch/arm/boot/dts/bcm2835-rpi.dtsi | 16 ++++++ - arch/arm/boot/dts/bcm2838.dtsi | 33 ++++++++---- - arch/arm/boot/dts/bcm283x.dtsi | 2 +- - 20 files changed, 86 insertions(+), 90 deletions(-) - create mode 100644 arch/arm/boot/dts/bcm2711-rpi.dtsi - ---- 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 "bcm2708-rpi.dtsi" - #include "bcm283x-rpi-smsc9514.dtsi" - #include "bcm283x-rpi-csi1-2lane.dtsi" - ---- 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 "bcm2708-rpi.dtsi" - #include "bcm283x-rpi-smsc9512.dtsi" - #include "bcm283x-rpi-csi1-2lane.dtsi" - ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -1,4 +1,5 @@ - #include "bcm2708.dtsi" -+#include "bcm2708-rpi.dtsi" - - &leds { - act_led: act { ---- a/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts -@@ -1,6 +1,7 @@ - /dts-v1/; - - #include "bcm2708.dtsi" -+#include "bcm2708-rpi.dtsi" - #include "bcm283x-rpi-csi1-2lane.dtsi" - - / { ---- a/arch/arm/boot/dts/bcm2708-rpi-zero.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-zero.dts -@@ -1,6 +1,7 @@ - /dts-v1/; - - #include "bcm2708.dtsi" -+#include "bcm2708-rpi.dtsi" - #include "bcm283x-rpi-csi1-2lane.dtsi" - - / { ---- a/arch/arm/boot/dts/bcm2708-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi.dtsi -@@ -1,6 +1,6 @@ --/* Downstream version of bcm2835-rpi.dtsi */ -+/* Downstream modifications to bcm2835-rpi.dtsi */ - --#include -+#include "bcm2835-rpi.dtsi" - - / { - memory { -@@ -49,29 +49,10 @@ - reg = <0x7e200000 0x1000>; - }; - -- firmware: firmware { -- compatible = "raspberrypi,bcm2835-firmware", "simple-bus"; -- #address-cells = <0>; -- #size-cells = <0>; -- mboxes = <&mailbox>; -- }; -- -- power: power { -- compatible = "raspberrypi,bcm2835-power"; -- firmware = <&firmware>; -- #power-domain-cells = <1>; -- }; -- - fb: fb { - compatible = "brcm,bcm2708-fb"; - firmware = <&firmware>; -- status = "disabled"; -- }; -- -- vchiq: mailbox@7e00b840 { -- compatible = "brcm,bcm2835-vchiq"; -- reg = <0x7e00b840 0x3c>; -- interrupts = <0 2>; -+ status = "okay"; - }; - - vcsm: vcsm { -@@ -91,10 +72,6 @@ - sound: sound { - status = "disabled"; - }; -- -- txp: txp@7e004000 { -- status = "disabled"; -- }; - }; - - __overrides__ { -@@ -125,11 +102,23 @@ - }; - - &hdmi { -- power-domains = <&power RPI_POWER_DOMAIN_HDMI>; -+ status = "disabled"; - }; - --&usb { -- power-domains = <&power RPI_POWER_DOMAIN_USB>; -+&txp { -+ status = "disabled"; -+}; -+ -+&i2c0 { -+ status = "disabled"; -+}; -+ -+&i2c1 { -+ status = "disabled"; -+}; -+ -+&i2c2 { -+ status = "disabled"; - }; - - &clocks { -@@ -141,16 +130,8 @@ sdhost_pins: &sdhost_gpio48 { - }; - - &sdhost { -- pinctrl-names = "default"; -- pinctrl-0 = <&sdhost_gpio48>; -- bus-width = <4>; - brcm,overclock-50 = <0>; - brcm,pio-limit = <1>; -- status = "okay"; --}; -- --&fb { -- status = "okay"; - }; - - &cpu_thermal { -@@ -160,11 +141,3 @@ sdhost_pins: &sdhost_gpio48 { - &vec { - status = "disabled"; - }; -- --&csi0 { -- power-domains = <&power RPI_POWER_DOMAIN_UNICAM0>; --}; -- --&csi1 { -- power-domains = <&power RPI_POWER_DOMAIN_UNICAM1>; --}; ---- a/arch/arm/boot/dts/bcm2708.dtsi -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -1,6 +1,5 @@ - #include "bcm2835.dtsi" - #include "bcm270x.dtsi" --#include "bcm2708-rpi.dtsi" - - / { - /delete-node/ cpus; ---- 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 "bcm2709-rpi.dtsi" - #include "bcm283x-rpi-smsc9514.dtsi" - #include "bcm283x-rpi-csi1-2lane.dtsi" - ---- a/arch/arm/boot/dts/bcm2709.dtsi -+++ b/arch/arm/boot/dts/bcm2709.dtsi -@@ -1,6 +1,5 @@ - #include "bcm2836.dtsi" - #include "bcm270x.dtsi" --#include "bcm2709-rpi.dtsi" - - / { - soc { ---- a/arch/arm/boot/dts/bcm270x.dtsi -+++ b/arch/arm/boot/dts/bcm270x.dtsi -@@ -68,7 +68,7 @@ - - /delete-node/ sdhci@7e300000; - -- mmc: mmc@7e300000 { -+ sdhci: mmc: mmc@7e300000 { - compatible = "brcm,bcm2835-mmc", "brcm,bcm2835-sdhci"; - reg = <0x7e300000 0x100>; - interrupts = <2 30>; -@@ -152,22 +152,6 @@ - }; - }; - -- vdd_5v0_reg: fixedregulator_5v0 { -- compatible = "regulator-fixed"; -- regulator-name = "5v0"; -- regulator-min-microvolt = <5000000>; -- regulator-max-microvolt = <5000000>; -- regulator-always-on; -- }; -- -- vdd_3v3_reg: fixedregulator_3v3 { -- compatible = "regulator-fixed"; -- regulator-name = "3v3"; -- regulator-min-microvolt = <3300000>; -- regulator-max-microvolt = <3300000>; -- regulator-always-on; -- }; -- - __overrides__ { - cam0-pwdn-ctrl; - cam0-pwdn; ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts -@@ -1,6 +1,7 @@ - /dts-v1/; - - #include "bcm2710.dtsi" -+#include "bcm2709-rpi.dtsi" - #include "bcm283x-rpi-lan7515.dtsi" - #include "bcm283x-rpi-csi1-2lane.dtsi" - ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -1,6 +1,7 @@ - /dts-v1/; - - #include "bcm2710.dtsi" -+#include "bcm2709-rpi.dtsi" - #include "bcm283x-rpi-smsc9514.dtsi" - #include "bcm283x-rpi-csi1-2lane.dtsi" - ---- a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts -@@ -1,6 +1,7 @@ - /dts-v1/; - - #include "bcm2710.dtsi" -+#include "bcm2709-rpi.dtsi" - #include "bcm283x-rpi-csi0-2lane.dtsi" - #include "bcm283x-rpi-csi1-4lane.dtsi" - ---- a/arch/arm/boot/dts/bcm2710.dtsi -+++ b/arch/arm/boot/dts/bcm2710.dtsi -@@ -1,6 +1,5 @@ - #include "bcm2837.dtsi" - #include "bcm270x.dtsi" --#include "bcm2709-rpi.dtsi" - - / { - compatible = "brcm,bcm2837", "brcm,bcm2836"; ---- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts -+++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts -@@ -1,13 +1,12 @@ - /dts-v1/; - - #include "bcm2711.dtsi" -+#include "bcm2711-rpi.dtsi" - #include "bcm283x-rpi-csi1-2lane.dtsi" - - / { -- compatible = "raspberrypi,4-model-b", "brcm,bcm2838", "brcm,bcm2837"; -+ compatible = "raspberrypi,4-model-b", "brcm,bcm2838"; - model = "Raspberry Pi 4 Model B"; -- #address-cells = <2>; -- #size-cells = <1>; - - memory { - device_type = "memory"; -@@ -48,10 +47,18 @@ - }; - - &firmware { -- expgpio: expgpio { -+ expgpio: gpio { - compatible = "raspberrypi,firmware-gpio"; - gpio-controller; - #gpio-cells = <2>; -+ gpio-line-names = "BT_ON", -+ "WL_ON", -+ "PWR_LED_OFF", -+ "GLOBAL_RESET", -+ "VDD_SD_IO_SEL", -+ "CAM_GPIO", -+ "", -+ ""; - status = "okay"; - }; - }; ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi -@@ -0,0 +1,7 @@ -+#include "bcm2708-rpi.dtsi" -+#include "bcm2838-rpi.dtsi" -+ -+&v3d { -+ /* Undo the overwriting by bcm270x.dtsi */ -+ power-domains = <&pm BCM2835_POWER_DOMAIN_GRAFX_V3D>; -+}; ---- a/arch/arm/boot/dts/bcm2711.dtsi -+++ b/arch/arm/boot/dts/bcm2711.dtsi -@@ -1,10 +1,8 @@ - #include "bcm2838.dtsi" - #include "bcm270x.dtsi" --#include "bcm2708-rpi.dtsi" - - / { - soc { -- /delete-node/ mailbox@7e00b840; - /delete-node/ v3d@7ec00000; - }; - -@@ -17,14 +15,6 @@ - status = "disabled"; - }; - --&dma { -- brcm,dma-channel-mask = <0x7ef5>; --}; -- --&txp { -- interrupts = ; --}; -- - &firmwarekms { - interrupts = ; - }; ---- a/arch/arm/boot/dts/bcm2835-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi -@@ -36,6 +36,22 @@ - interrupts = <0 2>; - }; - }; -+ -+ vdd_3v3_reg: fixedregulator_3v3 { -+ compatible = "regulator-fixed"; -+ regulator-name = "3v3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ }; -+ -+ vdd_5v0_reg: fixedregulator_5v0 { -+ compatible = "regulator-fixed"; -+ regulator-name = "5v0"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-always-on; -+ }; - }; - - &gpio { ---- a/arch/arm/boot/dts/bcm2838.dtsi -+++ b/arch/arm/boot/dts/bcm2838.dtsi -@@ -5,7 +5,10 @@ - #include - - / { -- compatible = "brcm,bcm2838", "brcm,bcm2837"; -+ compatible = "brcm,bcm2838"; -+ -+ #address-cells = <2>; -+ #size-cells = <1>; - - interrupt-parent = <&gicv2>; - -@@ -16,8 +19,8 @@ - /* Emulate a contiguous 30-bit address range for DMA */ - dma-ranges = <0xc0000000 0x0 0x00000000 0x3c000000>; - -- /delete-node/ mailbox@7e00b840; - /delete-node/ interrupt-controller@7e00f300; -+ /delete-node/ v3d@7ec00000; - - local_intc: local_intc@40000000 { - compatible = "brcm,bcm2836-l1-intc"; -@@ -191,6 +194,16 @@ - interrupts = ; - }; - -+ pwm1: pwm@7e20c800 { -+ compatible = "brcm,bcm2835-pwm"; -+ reg = <0x7e20c800 0x28>; -+ clocks = <&clocks BCM2835_CLOCK_PWM>; -+ assigned-clocks = <&clocks BCM2835_CLOCK_PWM>; -+ assigned-clock-rates = <10000000>; -+ #pwm-cells = <2>; -+ status = "disabled"; -+ }; -+ - emmc2: emmc2@7e340000 { - compatible = "brcm,bcm2711-emmc2"; - status = "okay"; -@@ -385,7 +398,7 @@ - "dma13", - "dma14"; - #dma-cells = <1>; -- brcm,dma-channel-mask = <0x7000>; -+ brcm,dma-channel-mask = <0x7800>; - }; - /* DMA4 - 40 bit DMA engines */ - -@@ -396,12 +409,6 @@ - interrupts = ; - }; - -- vchiq: mailbox@7e00b840 { -- compatible = "brcm,bcm2838-vchiq"; -- reg = <0 0x7e00b840 0x3c>; -- interrupts = ; -- }; -- - hevc-decoder@7eb00000 { - compatible = "raspberrypi,argon-hevc-decoder"; - reg = <0x0 0x7eb00000 0x10000>; -@@ -450,6 +457,8 @@ - }; - - &gpio { -+ compatible = "brcm,bcm2838-gpio", "brcm,bcm2835-gpio"; -+ - gpclk0_gpio49: gpclk0_gpio49 { - brcm,pins = <49>; - brcm,function = ; -@@ -729,5 +738,9 @@ - "dma8", - "dma9", - "dma10"; -- brcm,dma-channel-mask = <0x01f5>; -+ brcm,dma-channel-mask = <0x07f5>; -+}; -+ -+&txp { -+ interrupts = ; - }; ---- a/arch/arm/boot/dts/bcm283x.dtsi -+++ b/arch/arm/boot/dts/bcm283x.dtsi -@@ -55,7 +55,7 @@ - #address-cells = <1>; - #size-cells = <1>; - -- txp@7e004000 { -+ txp: txp@7e004000 { - compatible = "brcm,bcm2835-txp"; - reg = <0x7e004000 0x20>; - interrupts = <1 11>; diff --git a/target/linux/brcm2708/patches-4.19/950-0670-overlays-Cosmetic-change-to-upstream-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0670-overlays-Cosmetic-change-to-upstream-overlay.patch new file mode 100644 index 0000000000..6c1d253d69 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0670-overlays-Cosmetic-change-to-upstream-overlay.patch @@ -0,0 +1,25 @@ +From 0794b3c523e484608cfd87db2ce8ee7cd30e5e43 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 18 Jun 2019 11:19:59 +0100 +Subject: [PATCH 670/725] overlays: Cosmetic change to upstream overlay + +The dwc2 overlay no longer uses the dwc2_usb label, and the latest +ovmerge (which generates the upstream overlay) removes unused labels. +Update the checked-in version to match. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/upstream-overlay.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/overlays/upstream-overlay.dts ++++ b/arch/arm/boot/dts/overlays/upstream-overlay.dts +@@ -113,7 +113,7 @@ + target = <&usb>; + #address-cells = <1>; + #size-cells = <1>; +- dwc2_usb: __overlay__ { ++ __overlay__ { + compatible = "brcm,bcm2835-usb"; + dr_mode = "otg"; + g-np-tx-fifo-size = <32>; diff --git a/target/linux/brcm2708/patches-4.19/950-0671-arm-dts-First-draft-of-upstream-Pi4-DTS.patch b/target/linux/brcm2708/patches-4.19/950-0671-arm-dts-First-draft-of-upstream-Pi4-DTS.patch deleted file mode 100644 index fe71dd1e16..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0671-arm-dts-First-draft-of-upstream-Pi4-DTS.patch +++ /dev/null @@ -1,176 +0,0 @@ -From 575145094f904ca3c50e07f69a4ffaea902eadd7 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 11 Jun 2019 18:08:05 +0100 -Subject: [PATCH 671/703] arm: dts: First draft of upstream Pi4 DTS - -I've attempted to follow the upstream conventions in the DT commits, -but this is just presented here initially as a talking point. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/bcm2838-rpi-4-b.dts | 118 ++++++++++++++++++++++++++ - arch/arm/boot/dts/bcm2838-rpi.dtsi | 25 ++++++ - 3 files changed, 144 insertions(+) - create mode 100644 arch/arm/boot/dts/bcm2838-rpi-4-b.dts - create mode 100644 arch/arm/boot/dts/bcm2838-rpi.dtsi - ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -94,6 +94,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ - bcm2836-rpi-2-b.dtb \ - bcm2837-rpi-3-b.dtb \ - bcm2837-rpi-3-b-plus.dtb \ -+ bcm2838-rpi-4-b.dtb \ - bcm2835-rpi-zero.dtb \ - bcm2835-rpi-zero-w.dtb - dtb-$(CONFIG_ARCH_BCM_5301X) += \ ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2838-rpi-4-b.dts -@@ -0,0 +1,118 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/dts-v1/; -+#include "bcm2838.dtsi" -+#include "bcm2835-rpi.dtsi" -+#include "bcm2838-rpi.dtsi" -+ -+/ { -+ compatible = "raspberrypi,4-model-b", "brcm,bcm2838"; -+ model = "Raspberry Pi 4 Model B"; -+ -+ chosen { -+ /* 8250 auxiliary UART instead of pl011 */ -+ stdout-path = "serial1:115200n8"; -+ }; -+ -+ memory { -+ reg = <0 0 0x40000000>; -+ }; -+ -+ leds { -+ act { -+ gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; -+ }; -+ -+ pwr { -+ label = "PWR"; -+ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; -+ }; -+ }; -+ -+ wifi_pwrseq: wifi-pwrseq { -+ compatible = "mmc-pwrseq-simple"; -+ reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>; -+ }; -+ -+ sd_io_1v8_reg: sd_io_1v8_reg { -+ status = "okay"; -+ compatible = "regulator-gpio"; -+ vin-supply = <&vdd_5v0_reg>; -+ regulator-name = "vdd-sd-io"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-settling-time-us = <5000>; -+ -+ gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>; -+ states = <1800000 0x1 -+ 3300000 0x0>; -+ }; -+}; -+ -+&firmware { -+ expgpio: gpio { -+ compatible = "raspberrypi,firmware-gpio"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ gpio-line-names = "BT_ON", -+ "WL_ON", -+ "PWR_LED_OFF", -+ "GLOBAL_RESET", -+ "VDD_SD_IO_SEL", -+ "CAM_GPIO", -+ "", -+ ""; -+ status = "okay"; -+ }; -+}; -+ -+&pwm1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwm0_gpio40 &pwm1_gpio41>; -+ status = "okay"; -+}; -+ -+/* SDHCI is used to control the SDIO for wireless */ -+&sdhci { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_gpio34>; -+ status = "okay"; -+ bus-width = <4>; -+ non-removable; -+ mmc-pwrseq = <&wifi_pwrseq>; -+ -+ brcmf: wifi@1 { -+ reg = <1>; -+ compatible = "brcm,bcm4329-fmac"; -+ }; -+}; -+ -+/* EMMC2 is used to drive the SD card */ -+&emmc2 { -+ status = "okay"; -+ broken-cd; -+ vqmmc-supply = <&sd_io_1v8_reg>; -+}; -+ -+/* uart0 communicates with the BT module */ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32 &gpclk2_gpio43>; -+ status = "okay"; -+ -+ bluetooth { -+ compatible = "brcm,bcm43438-bt"; -+ max-speed = <2000000>; -+ shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>; -+ }; -+}; -+ -+/* uart1 is mapped to the pin header */ -+&uart1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart1_gpio14>; -+ status = "okay"; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2838-rpi.dtsi -@@ -0,0 +1,25 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+/ { -+ soc { -+ /delete-node/ mailbox@7e00b840; -+ }; -+}; -+ -+&scb { -+ vchiq: mailbox@7e00b840 { -+ compatible = "brcm,bcm2838-vchiq"; -+ reg = <0 0x7e00b840 0x3c>; -+ interrupts = ; -+ }; -+}; -+ -+&dma { -+ /* The VPU firmware uses DMA channel 11 for VCHIQ */ -+ brcm,dma-channel-mask = <0x1f5>; -+}; -+ -+&dma40 { -+ /* The VPU firmware DMA channel 11 for VCHIQ */ -+ brcm,dma-channel-mask = <0x7000>; -+}; diff --git a/target/linux/brcm2708/patches-4.19/950-0671-w1-ds2805-rename-w1_family-struct-fixing-c-p-typo.patch b/target/linux/brcm2708/patches-4.19/950-0671-w1-ds2805-rename-w1_family-struct-fixing-c-p-typo.patch new file mode 100644 index 0000000000..7ad721fbc5 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0671-w1-ds2805-rename-w1_family-struct-fixing-c-p-typo.patch @@ -0,0 +1,44 @@ +From 0d91e3b824bb24692b50bf7f31f07adb8f2370c6 Mon Sep 17 00:00:00 2001 +From: Mariusz Bialonczyk +Date: Sat, 25 May 2019 10:45:38 +0200 +Subject: [PATCH 671/725] w1: ds2805: rename w1_family struct, fixing c-p typo + +commit 0e3743d870711ae4daf1e7170c8d9381564e244d upstream. + +The ds2805 has a structure named: w1_family_2d, which surely +comes from a w1_ds2431 module. This commit fixes this name to +prevent confusion and mark a correct family name. + +Signed-off-by: Mariusz Bialonczyk +Signed-off-by: Greg Kroah-Hartman +--- + drivers/w1/slaves/w1_ds2805.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/w1/slaves/w1_ds2805.c ++++ b/drivers/w1/slaves/w1_ds2805.c +@@ -288,7 +288,7 @@ static struct w1_family_ops w1_f0d_fops + .remove_slave = w1_f0d_remove_slave, + }; + +-static struct w1_family w1_family_2d = { ++static struct w1_family w1_family_0d = { + .fid = W1_EEPROM_DS2805, + .fops = &w1_f0d_fops, + }; +@@ -296,13 +296,13 @@ static struct w1_family w1_family_2d = { + static int __init w1_f0d_init(void) + { + pr_info("%s()\n", __func__); +- return w1_register_family(&w1_family_2d); ++ return w1_register_family(&w1_family_0d); + } + + static void __exit w1_f0d_fini(void) + { + pr_info("%s()\n", __func__); +- w1_unregister_family(&w1_family_2d); ++ w1_unregister_family(&w1_family_0d); + } + + module_init(w1_f0d_init); diff --git a/target/linux/brcm2708/patches-4.19/950-0672-overlays-Fix-compatible-string-for-ds1307-RTC.patch b/target/linux/brcm2708/patches-4.19/950-0672-overlays-Fix-compatible-string-for-ds1307-RTC.patch deleted file mode 100644 index bab6d34493..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0672-overlays-Fix-compatible-string-for-ds1307-RTC.patch +++ /dev/null @@ -1,28 +0,0 @@ -From c39c0e9e9c90dc39b5190d3673b88af7cb126e75 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 17 Jun 2019 14:36:12 +0100 -Subject: [PATCH 672/703] overlays: Fix compatible string for ds1307 RTC - -Kernels since 4.19 have required the correct manufacture name in the -compatible string for I2C devices, and unfortunately the one for the -Dallas/Maxim DS1307 should have been "dallas,ds1307" and not -"maxim,ds1307". - -See: https://github.com/raspberrypi/linux/issues/3013 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -@@ -30,7 +30,7 @@ - status = "okay"; - - ds1307: ds1307@68 { -- compatible = "maxim,ds1307"; -+ compatible = "dallas,ds1307"; - reg = <0x68>; - status = "okay"; - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0672-w1-ds2413-output_write-cosmetic-fixes-simplify.patch b/target/linux/brcm2708/patches-4.19/950-0672-w1-ds2413-output_write-cosmetic-fixes-simplify.patch new file mode 100644 index 0000000000..5bf8d89b23 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0672-w1-ds2413-output_write-cosmetic-fixes-simplify.patch @@ -0,0 +1,64 @@ +From 8cebfa181f4bead15fb2dd73756a4d139339c83b Mon Sep 17 00:00:00 2001 +From: Mariusz Bialonczyk +Date: Mon, 20 May 2019 09:05:55 +0200 +Subject: [PATCH 672/725] w1: ds2413: output_write() cosmetic fixes / simplify + +commit ae2ee27aa985232f66421d7cd1c7f4b87c7dba7d upstream. + +Make the output_write simpler. +Based on Jean-Francois Dagenais code from: +49695ac46861 ("w1: ds2408: reset on output_write retry with readback") + +Signed-off-by: Mariusz Bialonczyk +Signed-off-by: Greg Kroah-Hartman +--- + drivers/w1/slaves/w1_ds2413.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +--- a/drivers/w1/slaves/w1_ds2413.c ++++ b/drivers/w1/slaves/w1_ds2413.c +@@ -69,6 +69,7 @@ static ssize_t output_write(struct file + struct w1_slave *sl = kobj_to_w1_slave(kobj); + u8 w1_buf[3]; + unsigned int retries = W1_F3A_RETRIES; ++ ssize_t bytes_written = -EIO; + + if (count != 1 || off != 0) + return -EFAULT; +@@ -78,7 +79,7 @@ static ssize_t output_write(struct file + dev_dbg(&sl->dev, "mutex locked"); + + if (w1_reset_select_slave(sl)) +- goto error; ++ goto out; + + /* according to the DS2413 datasheet the most significant 6 bits + should be set to "1"s, so do it now */ +@@ -91,18 +92,20 @@ static ssize_t output_write(struct file + w1_write_block(sl->master, w1_buf, 3); + + if (w1_read_8(sl->master) == W1_F3A_SUCCESS_CONFIRM_BYTE) { +- mutex_unlock(&sl->master->bus_mutex); +- dev_dbg(&sl->dev, "mutex unlocked, retries:%d", retries); +- return 1; ++ bytes_written = 1; ++ goto out; + } + if (w1_reset_resume_command(sl->master)) +- goto error; ++ goto out; /* unrecoverable error */ ++ ++ dev_warn(&sl->dev, "PIO_ACCESS_WRITE error, retries left: %d\n", retries); + } + +-error: ++out: + mutex_unlock(&sl->master->bus_mutex); +- dev_dbg(&sl->dev, "mutex unlocked in error, retries:%d", retries); +- return -EIO; ++ dev_dbg(&sl->dev, "%s, mutex unlocked, retries: %d\n", ++ (bytes_written > 0) ? "succeeded" : "error", retries); ++ return bytes_written; + } + + static BIN_ATTR(output, S_IRUGO | S_IWUSR | S_IWGRP, NULL, output_write, 1); diff --git a/target/linux/brcm2708/patches-4.19/950-0673-overlays-Fix-further-maxim-ds1307-references.patch b/target/linux/brcm2708/patches-4.19/950-0673-overlays-Fix-further-maxim-ds1307-references.patch deleted file mode 100644 index 4a7601d567..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0673-overlays-Fix-further-maxim-ds1307-references.patch +++ /dev/null @@ -1,47 +0,0 @@ -From c29c9843fd16b4df1dc21ff7e1243f680f41e2a9 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 18 Jun 2019 11:16:13 +0100 -Subject: [PATCH 673/703] overlays: Fix further maxim,ds1307 references - -See: https://github.com/raspberrypi/linux/issues/3013 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/balena-fin-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - ---- a/arch/arm/boot/dts/overlays/balena-fin-overlay.dts -+++ b/arch/arm/boot/dts/overlays/balena-fin-overlay.dts -@@ -84,7 +84,7 @@ - - // rtc clock - ds1307: ds1307@68 { -- compatible = "maxim,ds1307"; -+ compatible = "dallas,ds1307"; - reg = <0x68>; - status = "okay"; - }; ---- a/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts -@@ -46,7 +46,7 @@ - status = "okay"; - - ds1307: ds1307@68 { -- compatible = "maxim,ds1307"; -+ compatible = "dallas,ds1307"; - reg = <0x68>; - status = "okay"; - }; ---- a/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts -+++ b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts -@@ -155,7 +155,7 @@ - status = "okay"; - - ds1307: ds1307@68 { -- compatible = "maxim,ds1307"; -+ compatible = "dallas,ds1307"; - reg = <0x68>; - status = "okay"; - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0673-w1-ds2413-add-retry-support-to-state_read.patch b/target/linux/brcm2708/patches-4.19/950-0673-w1-ds2413-add-retry-support-to-state_read.patch new file mode 100644 index 0000000000..7ead26a3fc --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0673-w1-ds2413-add-retry-support-to-state_read.patch @@ -0,0 +1,74 @@ +From 37dfb88eed2cb32e7c2a704d0d4b590c68175ae1 Mon Sep 17 00:00:00 2001 +From: Mariusz Bialonczyk +Date: Mon, 20 May 2019 09:05:56 +0200 +Subject: [PATCH 673/725] w1: ds2413: add retry support to state_read() + +commit c50d09a86172073f55ebac0b92ad5a75907d64e7 upstream. + +The state_read() was calling PIO_ACCESS_READ once and bail out if it +failed for this first time. +This commit is improving this to trying more times before it give up, +similarly as the write call is currently doing. + +Signed-off-by: Mariusz Bialonczyk +Signed-off-by: Greg Kroah-Hartman +--- + drivers/w1/slaves/w1_ds2413.c | 37 +++++++++++++++++++++++------------ + 1 file changed, 24 insertions(+), 13 deletions(-) + +--- a/drivers/w1/slaves/w1_ds2413.c ++++ b/drivers/w1/slaves/w1_ds2413.c +@@ -30,6 +30,9 @@ static ssize_t state_read(struct file *f + size_t count) + { + struct w1_slave *sl = kobj_to_w1_slave(kobj); ++ unsigned int retries = W1_F3A_RETRIES; ++ ssize_t bytes_read = -EIO; ++ + dev_dbg(&sl->dev, + "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", + bin_attr->attr.name, kobj, (unsigned int)off, count, buf); +@@ -42,22 +45,30 @@ static ssize_t state_read(struct file *f + mutex_lock(&sl->master->bus_mutex); + dev_dbg(&sl->dev, "mutex locked"); + +- if (w1_reset_select_slave(sl)) { +- mutex_unlock(&sl->master->bus_mutex); +- return -EIO; +- } ++ if (w1_reset_select_slave(sl)) ++ goto out; + +- w1_write_8(sl->master, W1_F3A_FUNC_PIO_ACCESS_READ); +- *buf = w1_read_8(sl->master); ++ while (retries--) { ++ w1_write_8(sl->master, W1_F3A_FUNC_PIO_ACCESS_READ); + +- mutex_unlock(&sl->master->bus_mutex); +- dev_dbg(&sl->dev, "mutex unlocked"); ++ *buf = w1_read_8(sl->master); ++ /* check for correct complement */ ++ if ((*buf & 0x0F) == ((~*buf >> 4) & 0x0F)) { ++ bytes_read = 1; ++ goto out; ++ } ++ ++ if (w1_reset_resume_command(sl->master)) ++ goto out; /* unrecoverable error */ + +- /* check for correct complement */ +- if ((*buf & 0x0F) != ((~*buf >> 4) & 0x0F)) +- return -EIO; +- else +- return 1; ++ dev_warn(&sl->dev, "PIO_ACCESS_READ error, retries left: %d\n", retries); ++ } ++ ++out: ++ mutex_unlock(&sl->master->bus_mutex); ++ dev_dbg(&sl->dev, "%s, mutex unlocked, retries: %d\n", ++ (bytes_read > 0) ? "succeeded" : "error", retries); ++ return bytes_read; + } + + static BIN_ATTR_RO(state, 1); diff --git a/target/linux/brcm2708/patches-4.19/950-0674-overlays-Cosmetic-change-to-upstream-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0674-overlays-Cosmetic-change-to-upstream-overlay.patch deleted file mode 100644 index 5e6f18ca19..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0674-overlays-Cosmetic-change-to-upstream-overlay.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 7ab24b7d5ceb098af03e95c0cd261fa89d077cd3 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 18 Jun 2019 11:19:59 +0100 -Subject: [PATCH 674/703] overlays: Cosmetic change to upstream overlay - -The dwc2 overlay no longer uses the dwc2_usb label, and the latest -ovmerge (which generates the upstream overlay) removes unused labels. -Update the checked-in version to match. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/upstream-overlay.dts | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/overlays/upstream-overlay.dts -+++ b/arch/arm/boot/dts/overlays/upstream-overlay.dts -@@ -113,7 +113,7 @@ - target = <&usb>; - #address-cells = <1>; - #size-cells = <1>; -- dwc2_usb: __overlay__ { -+ __overlay__ { - compatible = "brcm,bcm2835-usb"; - dr_mode = "otg"; - g-np-tx-fifo-size = <32>; diff --git a/target/linux/brcm2708/patches-4.19/950-0674-w1-ds2413-when-the-slave-is-not-responding-during-re.patch b/target/linux/brcm2708/patches-4.19/950-0674-w1-ds2413-when-the-slave-is-not-responding-during-re.patch new file mode 100644 index 0000000000..70ae0c08a5 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0674-w1-ds2413-when-the-slave-is-not-responding-during-re.patch @@ -0,0 +1,56 @@ +From 4dba5d66cc91bf70b6bafd1a14b7db411d588745 Mon Sep 17 00:00:00 2001 +From: Mariusz Bialonczyk +Date: Wed, 22 May 2019 12:40:53 +0200 +Subject: [PATCH 674/725] w1: ds2413: when the slave is not responding during + read, select it again + +commit 3856032a0628e6b94badb9131a706dda185e071d upstream. + +The protocol is not allowing to obtain a byte of 0xff for PIO_ACCESS_READ +call. It is very likely that the slave was not addressed properly and +it is just not respoding (leaving the bus in logic high state) during +the read of sampled PIO value. +We cannot just call w1_reset_resume_command() because the problem will +persist, instead try selecting (addressing) the slave again. + +Signed-off-by: Mariusz Bialonczyk +Signed-off-by: Greg Kroah-Hartman +--- + drivers/w1/slaves/w1_ds2413.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/w1/slaves/w1_ds2413.c ++++ b/drivers/w1/slaves/w1_ds2413.c +@@ -24,6 +24,7 @@ + #define W1_F3A_FUNC_PIO_ACCESS_READ 0xF5 + #define W1_F3A_FUNC_PIO_ACCESS_WRITE 0x5A + #define W1_F3A_SUCCESS_CONFIRM_BYTE 0xAA ++#define W1_F3A_INVALID_PIO_STATE 0xFF + + static ssize_t state_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, loff_t off, +@@ -45,6 +46,7 @@ static ssize_t state_read(struct file *f + mutex_lock(&sl->master->bus_mutex); + dev_dbg(&sl->dev, "mutex locked"); + ++next: + if (w1_reset_select_slave(sl)) + goto out; + +@@ -52,10 +54,15 @@ static ssize_t state_read(struct file *f + w1_write_8(sl->master, W1_F3A_FUNC_PIO_ACCESS_READ); + + *buf = w1_read_8(sl->master); +- /* check for correct complement */ + if ((*buf & 0x0F) == ((~*buf >> 4) & 0x0F)) { ++ /* complement is correct */ + bytes_read = 1; + goto out; ++ } else if (*buf == W1_F3A_INVALID_PIO_STATE) { ++ /* slave didn't respond, try to select it again */ ++ dev_warn(&sl->dev, "slave device did not respond to PIO_ACCESS_READ, " \ ++ "reselecting, retries left: %d\n", retries); ++ goto next; + } + + if (w1_reset_resume_command(sl->master)) diff --git a/target/linux/brcm2708/patches-4.19/950-0675-w1-ds2413-fix-state-byte-comparision.patch b/target/linux/brcm2708/patches-4.19/950-0675-w1-ds2413-fix-state-byte-comparision.patch new file mode 100644 index 0000000000..bf868cd089 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0675-w1-ds2413-fix-state-byte-comparision.patch @@ -0,0 +1,48 @@ +From 8604b2fb9843248b9bc792c52393cb05b7a29836 Mon Sep 17 00:00:00 2001 +From: Mariusz Bialonczyk +Date: Thu, 30 May 2019 09:51:25 +0200 +Subject: [PATCH 675/725] w1: ds2413: fix state byte comparision + +commit aacd152ecd7b18af5d2d96dea9e7284c1c93abea upstream. + +This commit is fixing a smatch warning: +drivers/w1/slaves/w1_ds2413.c:61 state_read() warn: impossible condition '(*buf == 255) => ((-128)-127 == 255)' +by creating additional u8 variable for the bus reading and comparision + +Reported-by: kbuild test robot +Reported-by: Dan Carpenter +Cc: Dan Carpenter +Fixes: 3856032a0628 ("w1: ds2413: when the slave is not responding during read, select it again") +Signed-off-by: Mariusz Bialonczyk +Signed-off-by: Greg Kroah-Hartman +--- + drivers/w1/slaves/w1_ds2413.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/w1/slaves/w1_ds2413.c ++++ b/drivers/w1/slaves/w1_ds2413.c +@@ -33,6 +33,7 @@ static ssize_t state_read(struct file *f + struct w1_slave *sl = kobj_to_w1_slave(kobj); + unsigned int retries = W1_F3A_RETRIES; + ssize_t bytes_read = -EIO; ++ u8 state; + + dev_dbg(&sl->dev, + "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", +@@ -53,12 +54,13 @@ next: + while (retries--) { + w1_write_8(sl->master, W1_F3A_FUNC_PIO_ACCESS_READ); + +- *buf = w1_read_8(sl->master); +- if ((*buf & 0x0F) == ((~*buf >> 4) & 0x0F)) { ++ state = w1_read_8(sl->master); ++ if ((state & 0x0F) == ((~state >> 4) & 0x0F)) { + /* complement is correct */ ++ *buf = state; + bytes_read = 1; + goto out; +- } else if (*buf == W1_F3A_INVALID_PIO_STATE) { ++ } else if (state == W1_F3A_INVALID_PIO_STATE) { + /* slave didn't respond, try to select it again */ + dev_warn(&sl->dev, "slave device did not respond to PIO_ACCESS_READ, " \ + "reselecting, retries left: %d\n", retries); diff --git a/target/linux/brcm2708/patches-4.19/950-0675-w1-ds2805-rename-w1_family-struct-fixing-c-p-typo.patch b/target/linux/brcm2708/patches-4.19/950-0675-w1-ds2805-rename-w1_family-struct-fixing-c-p-typo.patch deleted file mode 100644 index ff0d8f1131..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0675-w1-ds2805-rename-w1_family-struct-fixing-c-p-typo.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 5b1cc85a28180a73cbe56be7913ae03ea9a42d2f Mon Sep 17 00:00:00 2001 -From: Mariusz Bialonczyk -Date: Sat, 25 May 2019 10:45:38 +0200 -Subject: [PATCH 675/703] w1: ds2805: rename w1_family struct, fixing c-p typo - -commit 0e3743d870711ae4daf1e7170c8d9381564e244d upstream. - -The ds2805 has a structure named: w1_family_2d, which surely -comes from a w1_ds2431 module. This commit fixes this name to -prevent confusion and mark a correct family name. - -Signed-off-by: Mariusz Bialonczyk -Signed-off-by: Greg Kroah-Hartman ---- - drivers/w1/slaves/w1_ds2805.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/w1/slaves/w1_ds2805.c -+++ b/drivers/w1/slaves/w1_ds2805.c -@@ -288,7 +288,7 @@ static struct w1_family_ops w1_f0d_fops - .remove_slave = w1_f0d_remove_slave, - }; - --static struct w1_family w1_family_2d = { -+static struct w1_family w1_family_0d = { - .fid = W1_EEPROM_DS2805, - .fops = &w1_f0d_fops, - }; -@@ -296,13 +296,13 @@ static struct w1_family w1_family_2d = { - static int __init w1_f0d_init(void) - { - pr_info("%s()\n", __func__); -- return w1_register_family(&w1_family_2d); -+ return w1_register_family(&w1_family_0d); - } - - static void __exit w1_f0d_fini(void) - { - pr_info("%s()\n", __func__); -- w1_unregister_family(&w1_family_2d); -+ w1_unregister_family(&w1_family_0d); - } - - module_init(w1_f0d_init); diff --git a/target/linux/brcm2708/patches-4.19/950-0676-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch b/target/linux/brcm2708/patches-4.19/950-0676-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch new file mode 100644 index 0000000000..3384a2a5aa --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0676-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch @@ -0,0 +1,135 @@ +From bf56ee503a31864237c40aac90fe338bbca6d5a0 Mon Sep 17 00:00:00 2001 +From: Chris Miller +Date: Wed, 26 Jun 2019 10:40:30 +0100 +Subject: [PATCH 676/725] drm: vc4_dsi: Fix DMA channel and memory leak in vc4 + (#3012) + +Signed-off-by: Chris G Miller +--- + drivers/gpu/drm/vc4/vc4_dsi.c | 35 ++++++++++++++++++++++++----------- + 1 file changed, 24 insertions(+), 11 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_dsi.c ++++ b/drivers/gpu/drm/vc4/vc4_dsi.c +@@ -1536,9 +1536,11 @@ static int vc4_dsi_bind(struct device *d + /* 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. ++ * Where possible managed resource providers are used, but the DMA channel ++ * must - if acquired - be explicitly released prior to taking an error exit path. + */ + if (dsi->port == 1) { +- dsi->reg_dma_mem = dma_alloc_coherent(dev, 4, ++ dsi->reg_dma_mem = dmam_alloc_coherent(dev, 4, + &dsi->reg_dma_paddr, + GFP_KERNEL); + if (!dsi->reg_dma_mem) { +@@ -1557,6 +1559,8 @@ static int vc4_dsi_bind(struct device *d + return ret; + } + ++ /* From here on, any error exits must release the dma channel */ ++ + /* Get the physical address of the device's registers. The + * struct resource for the regs gives us the bus address + * instead. +@@ -1583,7 +1587,7 @@ static int vc4_dsi_bind(struct device *d + if (ret) { + if (ret != -EPROBE_DEFER) + dev_err(dev, "Failed to get interrupt: %d\n", ret); +- return ret; ++ goto rel_dma_exit; + } + + dsi->escape_clock = devm_clk_get(dev, "escape"); +@@ -1591,7 +1595,7 @@ static int vc4_dsi_bind(struct device *d + ret = PTR_ERR(dsi->escape_clock); + if (ret != -EPROBE_DEFER) + dev_err(dev, "Failed to get escape clock: %d\n", ret); +- return ret; ++ goto rel_dma_exit; + } + + dsi->pll_phy_clock = devm_clk_get(dev, "phy"); +@@ -1599,7 +1603,7 @@ static int vc4_dsi_bind(struct device *d + ret = PTR_ERR(dsi->pll_phy_clock); + if (ret != -EPROBE_DEFER) + dev_err(dev, "Failed to get phy clock: %d\n", ret); +- return ret; ++ goto rel_dma_exit; + } + + dsi->pixel_clock = devm_clk_get(dev, "pixel"); +@@ -1607,7 +1611,7 @@ static int vc4_dsi_bind(struct device *d + ret = PTR_ERR(dsi->pixel_clock); + if (ret != -EPROBE_DEFER) + dev_err(dev, "Failed to get pixel clock: %d\n", ret); +- return ret; ++ goto rel_dma_exit; + } + + ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, +@@ -1622,26 +1626,28 @@ static int vc4_dsi_bind(struct device *d + if (ret == -ENODEV) + return 0; + +- return ret; ++ goto rel_dma_exit; + } + + if (panel) { + dsi->bridge = devm_drm_panel_bridge_add(dev, panel, + DRM_MODE_CONNECTOR_DSI); +- if (IS_ERR(dsi->bridge)) +- return PTR_ERR(dsi->bridge); ++ if (IS_ERR(dsi->bridge)){ ++ ret = PTR_ERR(dsi->bridge); ++ goto rel_dma_exit; ++ } + } + + /* 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; ++ goto rel_dma_exit; + } + + ret = vc4_dsi_init_phy_clocks(dsi); + if (ret) +- return ret; ++ goto rel_dma_exit; + + if (dsi->port == 1) + vc4->dsi1 = dsi; +@@ -1653,7 +1659,7 @@ static int vc4_dsi_bind(struct device *d + ret = drm_bridge_attach(dsi->encoder, dsi->bridge, NULL); + if (ret) { + dev_err(dev, "bridge attach failed: %d\n", ret); +- return ret; ++ goto rel_dma_exit; + } + /* Disable the atomic helper calls into the bridge. We + * manually call the bridge pre_enable / enable / etc. calls +@@ -1665,6 +1671,11 @@ static int vc4_dsi_bind(struct device *d + pm_runtime_enable(dev); + + return 0; ++ ++rel_dma_exit: ++ dma_release_channel(dsi->reg_dma_chan); ++ ++ return ret; + } + + static void vc4_dsi_unbind(struct device *dev, struct device *master, +@@ -1679,6 +1690,8 @@ static void vc4_dsi_unbind(struct device + + vc4_dsi_encoder_destroy(dsi->encoder); + ++ dma_release_channel(dsi->reg_dma_chan); ++ + if (dsi->port == 1) + vc4->dsi1 = NULL; + } diff --git a/target/linux/brcm2708/patches-4.19/950-0676-w1-ds2413-output_write-cosmetic-fixes-simplify.patch b/target/linux/brcm2708/patches-4.19/950-0676-w1-ds2413-output_write-cosmetic-fixes-simplify.patch deleted file mode 100644 index 83158746f8..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0676-w1-ds2413-output_write-cosmetic-fixes-simplify.patch +++ /dev/null @@ -1,64 +0,0 @@ -From b6d4c7b839620c8d955b1887ed71c3911df90684 Mon Sep 17 00:00:00 2001 -From: Mariusz Bialonczyk -Date: Mon, 20 May 2019 09:05:55 +0200 -Subject: [PATCH 676/703] w1: ds2413: output_write() cosmetic fixes / simplify - -commit ae2ee27aa985232f66421d7cd1c7f4b87c7dba7d upstream. - -Make the output_write simpler. -Based on Jean-Francois Dagenais code from: -49695ac46861 ("w1: ds2408: reset on output_write retry with readback") - -Signed-off-by: Mariusz Bialonczyk -Signed-off-by: Greg Kroah-Hartman ---- - drivers/w1/slaves/w1_ds2413.c | 19 +++++++++++-------- - 1 file changed, 11 insertions(+), 8 deletions(-) - ---- a/drivers/w1/slaves/w1_ds2413.c -+++ b/drivers/w1/slaves/w1_ds2413.c -@@ -69,6 +69,7 @@ static ssize_t output_write(struct file - struct w1_slave *sl = kobj_to_w1_slave(kobj); - u8 w1_buf[3]; - unsigned int retries = W1_F3A_RETRIES; -+ ssize_t bytes_written = -EIO; - - if (count != 1 || off != 0) - return -EFAULT; -@@ -78,7 +79,7 @@ static ssize_t output_write(struct file - dev_dbg(&sl->dev, "mutex locked"); - - if (w1_reset_select_slave(sl)) -- goto error; -+ goto out; - - /* according to the DS2413 datasheet the most significant 6 bits - should be set to "1"s, so do it now */ -@@ -91,18 +92,20 @@ static ssize_t output_write(struct file - w1_write_block(sl->master, w1_buf, 3); - - if (w1_read_8(sl->master) == W1_F3A_SUCCESS_CONFIRM_BYTE) { -- mutex_unlock(&sl->master->bus_mutex); -- dev_dbg(&sl->dev, "mutex unlocked, retries:%d", retries); -- return 1; -+ bytes_written = 1; -+ goto out; - } - if (w1_reset_resume_command(sl->master)) -- goto error; -+ goto out; /* unrecoverable error */ -+ -+ dev_warn(&sl->dev, "PIO_ACCESS_WRITE error, retries left: %d\n", retries); - } - --error: -+out: - mutex_unlock(&sl->master->bus_mutex); -- dev_dbg(&sl->dev, "mutex unlocked in error, retries:%d", retries); -- return -EIO; -+ dev_dbg(&sl->dev, "%s, mutex unlocked, retries: %d\n", -+ (bytes_written > 0) ? "succeeded" : "error", retries); -+ return bytes_written; - } - - static BIN_ATTR(output, S_IRUGO | S_IWUSR | S_IWGRP, NULL, output_write, 1); diff --git a/target/linux/brcm2708/patches-4.19/950-0677-video-bcm2708_fb-Revert-cma-allocation-attempt.patch b/target/linux/brcm2708/patches-4.19/950-0677-video-bcm2708_fb-Revert-cma-allocation-attempt.patch new file mode 100644 index 0000000000..dcce81d559 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0677-video-bcm2708_fb-Revert-cma-allocation-attempt.patch @@ -0,0 +1,159 @@ +From 8f0ceec888aaa21d703dc9b16bca77d57104b7cf Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 19 Jun 2019 03:55:50 +0100 +Subject: [PATCH 677/725] video/bcm2708_fb: Revert cma allocation attempt + +"4600e91 Pulled in the multi frame buffer support from the Pi3 repo" +pulled back in the code for allocating the framebuffer from the CMA +heap. +Revert it again. + +Signed-off-by: Dave Stevenson +--- + drivers/video/fbdev/bcm2708_fb.c | 101 +++------------------ + include/soc/bcm2835/raspberrypi-firmware.h | 1 - + 2 files changed, 13 insertions(+), 89 deletions(-) + +--- a/drivers/video/fbdev/bcm2708_fb.c ++++ b/drivers/video/fbdev/bcm2708_fb.c +@@ -112,9 +112,6 @@ struct bcm2708_fb { + struct vc4_display_settings_t display_settings; + struct debugfs_regset32 screeninfo_regset; + struct bcm2708_fb_dev *fbdev; +- unsigned int image_size; +- dma_addr_t dma_addr; +- void *cpuaddr; + }; + + #define MAX_FRAMEBUFFERS 3 +@@ -377,12 +374,12 @@ static int bcm2708_fb_set_par(struct fb_ + .xoffset = info->var.xoffset, + .yoffset = info->var.yoffset, + .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 }, +- /* base and screen_size will be initialised later */ +- .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH, 4, 0 }, +- /* pitch will be initialised later */ ++ .base = 0, ++ .screen_size = 0, ++ .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH, 4, 0 }, ++ .pitch = 0, + }; +- int ret, image_size; +- ++ int ret; + + print_debug("%s(%p) %dx%d (%dx%d), %d, %d (display %d)\n", __func__, + info, +@@ -397,76 +394,12 @@ static int bcm2708_fb_set_par(struct fb_ + */ + set_display_num(fb); + +- /* Try allocating our own buffer. We can specify all the parameters */ +- image_size = ((info->var.xres * info->var.yres) * +- info->var.bits_per_pixel) >> 3; +- +- if (!fb->fbdev->disable_arm_alloc && +- (image_size != fb->image_size || !fb->dma_addr)) { +- if (fb->dma_addr) { +- dma_free_coherent(info->device, fb->image_size, +- fb->cpuaddr, fb->dma_addr); +- fb->image_size = 0; +- fb->cpuaddr = NULL; +- fb->dma_addr = 0; +- } +- +- fb->cpuaddr = dma_alloc_coherent(info->device, image_size, +- &fb->dma_addr, GFP_KERNEL); +- +- if (!fb->cpuaddr) { +- fb->dma_addr = 0; +- fb->fbdev->disable_arm_alloc = true; +- } else { +- fb->image_size = image_size; +- } +- } +- +- if (fb->cpuaddr) { +- fbinfo.base = fb->dma_addr; +- fbinfo.screen_size = image_size; +- fbinfo.pitch = (info->var.xres * info->var.bits_per_pixel) >> 3; +- +- ret = rpi_firmware_property_list(fb->fbdev->fw, &fbinfo, +- sizeof(fbinfo)); +- if (ret || fbinfo.base != fb->dma_addr) { +- /* Firmware either failed, or assigned a different base +- * address (ie it doesn't support being passed an FB +- * allocation). +- * Destroy the allocation, and don't try again. +- */ +- dma_free_coherent(info->device, fb->image_size, +- fb->cpuaddr, fb->dma_addr); +- fb->image_size = 0; +- fb->cpuaddr = NULL; +- fb->dma_addr = 0; +- fb->fbdev->disable_arm_alloc = true; +- } +- } else { +- /* Our allocation failed - drop into the old scheme of +- * allocation by the VPU. +- */ +- ret = -ENOMEM; +- } +- ++ ret = rpi_firmware_property_list(fb->fbdev->fw, &fbinfo, ++ sizeof(fbinfo)); + if (ret) { +- /* Old scheme: +- * - FRAMEBUFFER_ALLOCATE passes 0 for base and screen_size. +- * - GET_PITCH instead of SET_PITCH. +- */ +- fbinfo.base = 0; +- fbinfo.screen_size = 0; +- fbinfo.tag6.tag = RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH; +- fbinfo.pitch = 0; +- +- ret = rpi_firmware_property_list(fb->fbdev->fw, &fbinfo, +- sizeof(fbinfo)); +- if (ret) { +- dev_err(info->device, +- "Failed to allocate GPU framebuffer (%d)\n", +- ret); +- return ret; +- } ++ dev_err(info->device, ++ "Failed to allocate GPU framebuffer (%d)\n", ret); ++ return ret; + } + + if (info->var.bits_per_pixel <= 8) +@@ -481,17 +414,9 @@ static int bcm2708_fb_set_par(struct fb_ + fb->fb.fix.smem_start = fbinfo.base; + fb->fb.fix.smem_len = fbinfo.pitch * fbinfo.yres_virtual; + fb->fb.screen_size = fbinfo.screen_size; +- +- if (!fb->dma_addr) { +- if (fb->fb.screen_base) +- iounmap(fb->fb.screen_base); +- +- fb->fb.screen_base = ioremap_wc(fbinfo.base, +- fb->fb.screen_size); +- } else { +- fb->fb.screen_base = fb->cpuaddr; +- } +- ++ if (fb->fb.screen_base) ++ iounmap(fb->fb.screen_base); ++ fb->fb.screen_base = ioremap_wc(fbinfo.base, fb->fb.screen_size); + if (!fb->fb.screen_base) { + /* the console may currently be locked */ + console_trylock(); +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -138,7 +138,6 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, + RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER = 0x00048006, + RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE = 0x00048007, +- RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH = 0x00048008, + RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, + RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, + RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, diff --git a/target/linux/brcm2708/patches-4.19/950-0677-w1-ds2413-add-retry-support-to-state_read.patch b/target/linux/brcm2708/patches-4.19/950-0677-w1-ds2413-add-retry-support-to-state_read.patch deleted file mode 100644 index 9bcca00f80..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0677-w1-ds2413-add-retry-support-to-state_read.patch +++ /dev/null @@ -1,74 +0,0 @@ -From f88a22ce466ccac98bf4aa1c38d36b0e0bb52adb Mon Sep 17 00:00:00 2001 -From: Mariusz Bialonczyk -Date: Mon, 20 May 2019 09:05:56 +0200 -Subject: [PATCH 677/703] w1: ds2413: add retry support to state_read() - -commit c50d09a86172073f55ebac0b92ad5a75907d64e7 upstream. - -The state_read() was calling PIO_ACCESS_READ once and bail out if it -failed for this first time. -This commit is improving this to trying more times before it give up, -similarly as the write call is currently doing. - -Signed-off-by: Mariusz Bialonczyk -Signed-off-by: Greg Kroah-Hartman ---- - drivers/w1/slaves/w1_ds2413.c | 37 +++++++++++++++++++++++------------ - 1 file changed, 24 insertions(+), 13 deletions(-) - ---- a/drivers/w1/slaves/w1_ds2413.c -+++ b/drivers/w1/slaves/w1_ds2413.c -@@ -30,6 +30,9 @@ static ssize_t state_read(struct file *f - size_t count) - { - struct w1_slave *sl = kobj_to_w1_slave(kobj); -+ unsigned int retries = W1_F3A_RETRIES; -+ ssize_t bytes_read = -EIO; -+ - dev_dbg(&sl->dev, - "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", - bin_attr->attr.name, kobj, (unsigned int)off, count, buf); -@@ -42,22 +45,30 @@ static ssize_t state_read(struct file *f - mutex_lock(&sl->master->bus_mutex); - dev_dbg(&sl->dev, "mutex locked"); - -- if (w1_reset_select_slave(sl)) { -- mutex_unlock(&sl->master->bus_mutex); -- return -EIO; -- } -+ if (w1_reset_select_slave(sl)) -+ goto out; - -- w1_write_8(sl->master, W1_F3A_FUNC_PIO_ACCESS_READ); -- *buf = w1_read_8(sl->master); -+ while (retries--) { -+ w1_write_8(sl->master, W1_F3A_FUNC_PIO_ACCESS_READ); - -- mutex_unlock(&sl->master->bus_mutex); -- dev_dbg(&sl->dev, "mutex unlocked"); -+ *buf = w1_read_8(sl->master); -+ /* check for correct complement */ -+ if ((*buf & 0x0F) == ((~*buf >> 4) & 0x0F)) { -+ bytes_read = 1; -+ goto out; -+ } -+ -+ if (w1_reset_resume_command(sl->master)) -+ goto out; /* unrecoverable error */ - -- /* check for correct complement */ -- if ((*buf & 0x0F) != ((~*buf >> 4) & 0x0F)) -- return -EIO; -- else -- return 1; -+ dev_warn(&sl->dev, "PIO_ACCESS_READ error, retries left: %d\n", retries); -+ } -+ -+out: -+ mutex_unlock(&sl->master->bus_mutex); -+ dev_dbg(&sl->dev, "%s, mutex unlocked, retries: %d\n", -+ (bytes_read > 0) ? "succeeded" : "error", retries); -+ return bytes_read; - } - - static BIN_ATTR_RO(state, 1); diff --git a/target/linux/brcm2708/patches-4.19/950-0678-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch b/target/linux/brcm2708/patches-4.19/950-0678-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch new file mode 100644 index 0000000000..36e6d23f26 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0678-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch @@ -0,0 +1,110 @@ +From a79005b13c374c78f6d96f5ab2cd12377357d82f Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 24 Jun 2019 02:29:40 +0100 +Subject: [PATCH 678/725] drm/vc4: Add support for color encoding on YUV planes + +Adds signalling for BT601/709/2020, and limited/full range +(on BT601). + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 32 +++++++++++++++++++++++++- + drivers/gpu/drm/vc4/vc_image_types.h | 28 ++++++++++++++++++++++ + 2 files changed, 59 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -66,7 +66,7 @@ struct set_plane { + u8 alpha; + u8 num_planes; + u8 is_vu; +- u8 padding; ++ u8 color_encoding; + + u32 planes[4]; /* DMA address of each plane */ + +@@ -454,6 +454,28 @@ static void vc4_plane_atomic_update(stru + if (num_planes == 3 && + (fb->offsets[2] - fb->offsets[1]) == fb->pitches[1]) + mb->plane.vc_image_type = VC_IMAGE_YUV420_S; ++ ++ switch (state->color_encoding) { ++ default: ++ case DRM_COLOR_YCBCR_BT601: ++ if (state->color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) ++ mb->plane.color_encoding = ++ VC_IMAGE_YUVINFO_CSC_ITUR_BT601; ++ else ++ mb->plane.color_encoding = ++ VC_IMAGE_YUVINFO_CSC_JPEG_JFIF; ++ break; ++ case DRM_COLOR_YCBCR_BT709: ++ /* Currently no support for a full range BT709 */ ++ mb->plane.color_encoding = ++ VC_IMAGE_YUVINFO_CSC_ITUR_BT709; ++ break; ++ case DRM_COLOR_YCBCR_BT2020: ++ /* Currently no support for a full range BT2020 */ ++ mb->plane.color_encoding = ++ VC_IMAGE_YUVINFO_CSC_REC_2020; ++ break; ++ } + } else { + mb->plane.planes[1] = 0; + mb->plane.planes[2] = 0; +@@ -643,6 +665,14 @@ static struct drm_plane *vc4_fkms_plane_ + drm_plane_create_alpha_property(plane); + drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0, + SUPPORTED_ROTATIONS); ++ drm_plane_create_color_properties(plane, ++ BIT(DRM_COLOR_YCBCR_BT601) | ++ BIT(DRM_COLOR_YCBCR_BT709) | ++ BIT(DRM_COLOR_YCBCR_BT2020), ++ BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | ++ BIT(DRM_COLOR_YCBCR_FULL_RANGE), ++ DRM_COLOR_YCBCR_BT709, ++ DRM_COLOR_YCBCR_LIMITED_RANGE); + + /* + * Default frame buffer setup is with FB on -127, and raspistill etc +--- a/drivers/gpu/drm/vc4/vc_image_types.h ++++ b/drivers/gpu/drm/vc4/vc_image_types.h +@@ -4,6 +4,8 @@ + * + * Values taken from vc_image_types.h released by Broadcom at + * https://github.com/raspberrypi/userland/blob/master/interface/vctypes/vc_image_types.h ++ * and vc_image_structs.h at ++ * https://github.com/raspberrypi/userland/blob/master/interface/vctypes/vc_image_structs.h + * + * 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 +@@ -141,3 +143,29 @@ enum { + VC_IMAGE_MAX, /* bounds for error checking */ + VC_IMAGE_FORCE_ENUM_16BIT = 0xffff, + }; ++ ++enum { ++ /* Unknown or unset - defaults to BT601 interstitial */ ++ VC_IMAGE_YUVINFO_UNSPECIFIED = 0, ++ ++ /* colour-space conversions data [4 bits] */ ++ ++ /* ITU-R BT.601-5 [SDTV] (compatible with VideoCore-II) */ ++ VC_IMAGE_YUVINFO_CSC_ITUR_BT601 = 1, ++ /* ITU-R BT.709-3 [HDTV] */ ++ VC_IMAGE_YUVINFO_CSC_ITUR_BT709 = 2, ++ /* JPEG JFIF */ ++ VC_IMAGE_YUVINFO_CSC_JPEG_JFIF = 3, ++ /* Title 47 Code of Federal Regulations (2003) 73.682 (a) (20) */ ++ VC_IMAGE_YUVINFO_CSC_FCC = 4, ++ /* Society of Motion Picture and Television Engineers 240M (1999) */ ++ VC_IMAGE_YUVINFO_CSC_SMPTE_240M = 5, ++ /* ITU-R BT.470-2 System M */ ++ VC_IMAGE_YUVINFO_CSC_ITUR_BT470_2_M = 6, ++ /* ITU-R BT.470-2 System B,G */ ++ VC_IMAGE_YUVINFO_CSC_ITUR_BT470_2_BG = 7, ++ /* JPEG JFIF, but with 16..255 luma */ ++ VC_IMAGE_YUVINFO_CSC_JPEG_JFIF_Y16_255 = 8, ++ /* Rec 2020 */ ++ VC_IMAGE_YUVINFO_CSC_REC_2020 = 9, ++}; diff --git a/target/linux/brcm2708/patches-4.19/950-0678-w1-ds2413-when-the-slave-is-not-responding-during-re.patch b/target/linux/brcm2708/patches-4.19/950-0678-w1-ds2413-when-the-slave-is-not-responding-during-re.patch deleted file mode 100644 index c3b0c5d308..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0678-w1-ds2413-when-the-slave-is-not-responding-during-re.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 1808665b2b2e06d6f14762eb0ab82d65e3af3e2b Mon Sep 17 00:00:00 2001 -From: Mariusz Bialonczyk -Date: Wed, 22 May 2019 12:40:53 +0200 -Subject: [PATCH 678/703] w1: ds2413: when the slave is not responding during - read, select it again - -commit 3856032a0628e6b94badb9131a706dda185e071d upstream. - -The protocol is not allowing to obtain a byte of 0xff for PIO_ACCESS_READ -call. It is very likely that the slave was not addressed properly and -it is just not respoding (leaving the bus in logic high state) during -the read of sampled PIO value. -We cannot just call w1_reset_resume_command() because the problem will -persist, instead try selecting (addressing) the slave again. - -Signed-off-by: Mariusz Bialonczyk -Signed-off-by: Greg Kroah-Hartman ---- - drivers/w1/slaves/w1_ds2413.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - ---- a/drivers/w1/slaves/w1_ds2413.c -+++ b/drivers/w1/slaves/w1_ds2413.c -@@ -24,6 +24,7 @@ - #define W1_F3A_FUNC_PIO_ACCESS_READ 0xF5 - #define W1_F3A_FUNC_PIO_ACCESS_WRITE 0x5A - #define W1_F3A_SUCCESS_CONFIRM_BYTE 0xAA -+#define W1_F3A_INVALID_PIO_STATE 0xFF - - static ssize_t state_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, char *buf, loff_t off, -@@ -45,6 +46,7 @@ static ssize_t state_read(struct file *f - mutex_lock(&sl->master->bus_mutex); - dev_dbg(&sl->dev, "mutex locked"); - -+next: - if (w1_reset_select_slave(sl)) - goto out; - -@@ -52,10 +54,15 @@ static ssize_t state_read(struct file *f - w1_write_8(sl->master, W1_F3A_FUNC_PIO_ACCESS_READ); - - *buf = w1_read_8(sl->master); -- /* check for correct complement */ - if ((*buf & 0x0F) == ((~*buf >> 4) & 0x0F)) { -+ /* complement is correct */ - bytes_read = 1; - goto out; -+ } else if (*buf == W1_F3A_INVALID_PIO_STATE) { -+ /* slave didn't respond, try to select it again */ -+ dev_warn(&sl->dev, "slave device did not respond to PIO_ACCESS_READ, " \ -+ "reselecting, retries left: %d\n", retries); -+ goto next; - } - - if (w1_reset_resume_command(sl->master)) diff --git a/target/linux/brcm2708/patches-4.19/950-0679-configs-Drop-V4L2-camera-and-codec-drivers-from-bcmr.patch b/target/linux/brcm2708/patches-4.19/950-0679-configs-Drop-V4L2-camera-and-codec-drivers-from-bcmr.patch new file mode 100644 index 0000000000..9fa609cb0e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0679-configs-Drop-V4L2-camera-and-codec-drivers-from-bcmr.patch @@ -0,0 +1,25 @@ +From 4798e87ece1dbf90c42f4def09401ee4c051e003 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 28 Jun 2019 16:05:25 +0100 +Subject: [PATCH 679/725] configs: Drop V4L2 camera and codec drivers from + bcmrpi3_defconfig + +They rely on mmal_vchiq, which in turn wants vc-sm-cma. +vc-sm-cma needs some attention for 64 bit, so drop it for now. + +Signed-off-by: Dave Stevenson +--- + arch/arm64/configs/bcmrpi3_defconfig | 2 -- + 1 file changed, 2 deletions(-) + +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -1086,8 +1086,6 @@ CONFIG_FB_TFT_WATTEROTT=m + CONFIG_FB_FLEX=m + CONFIG_FB_TFT_FBTFT_DEVICE=m + CONFIG_SND_BCM2835=m +-CONFIG_VIDEO_BCM2835=m +-CONFIG_VIDEO_CODEC_BCM2835=m + CONFIG_MAILBOX=y + CONFIG_BCM2835_MBOX=y + # CONFIG_IOMMU_SUPPORT is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0679-w1-ds2413-fix-state-byte-comparision.patch b/target/linux/brcm2708/patches-4.19/950-0679-w1-ds2413-fix-state-byte-comparision.patch deleted file mode 100644 index 154a60c9a4..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0679-w1-ds2413-fix-state-byte-comparision.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 7a5972e019d1f4cef5ea50b9077b43f097b23084 Mon Sep 17 00:00:00 2001 -From: Mariusz Bialonczyk -Date: Thu, 30 May 2019 09:51:25 +0200 -Subject: [PATCH 679/703] w1: ds2413: fix state byte comparision - -commit aacd152ecd7b18af5d2d96dea9e7284c1c93abea upstream. - -This commit is fixing a smatch warning: -drivers/w1/slaves/w1_ds2413.c:61 state_read() warn: impossible condition '(*buf == 255) => ((-128)-127 == 255)' -by creating additional u8 variable for the bus reading and comparision - -Reported-by: kbuild test robot -Reported-by: Dan Carpenter -Cc: Dan Carpenter -Fixes: 3856032a0628 ("w1: ds2413: when the slave is not responding during read, select it again") -Signed-off-by: Mariusz Bialonczyk -Signed-off-by: Greg Kroah-Hartman ---- - drivers/w1/slaves/w1_ds2413.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - ---- a/drivers/w1/slaves/w1_ds2413.c -+++ b/drivers/w1/slaves/w1_ds2413.c -@@ -33,6 +33,7 @@ static ssize_t state_read(struct file *f - struct w1_slave *sl = kobj_to_w1_slave(kobj); - unsigned int retries = W1_F3A_RETRIES; - ssize_t bytes_read = -EIO; -+ u8 state; - - dev_dbg(&sl->dev, - "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", -@@ -53,12 +54,13 @@ next: - while (retries--) { - w1_write_8(sl->master, W1_F3A_FUNC_PIO_ACCESS_READ); - -- *buf = w1_read_8(sl->master); -- if ((*buf & 0x0F) == ((~*buf >> 4) & 0x0F)) { -+ state = w1_read_8(sl->master); -+ if ((state & 0x0F) == ((~state >> 4) & 0x0F)) { - /* complement is correct */ -+ *buf = state; - bytes_read = 1; - goto out; -- } else if (*buf == W1_F3A_INVALID_PIO_STATE) { -+ } else if (state == W1_F3A_INVALID_PIO_STATE) { - /* slave didn't respond, try to select it again */ - dev_warn(&sl->dev, "slave device did not respond to PIO_ACCESS_READ, " \ - "reselecting, retries left: %d\n", retries); diff --git a/target/linux/brcm2708/patches-4.19/950-0680-configs-arm64-bcm2711-Remove-CONFIG_VIDEO_BCM2835.patch b/target/linux/brcm2708/patches-4.19/950-0680-configs-arm64-bcm2711-Remove-CONFIG_VIDEO_BCM2835.patch new file mode 100644 index 0000000000..816a23a2d0 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0680-configs-arm64-bcm2711-Remove-CONFIG_VIDEO_BCM2835.patch @@ -0,0 +1,49 @@ +From 6dadf48ceed847ed814d9fa3ab3cf902c4ce6e25 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 28 Jun 2019 22:44:09 +0100 +Subject: [PATCH 680/725] configs: arm64/bcm2711: Remove CONFIG_VIDEO_BCM2835 + +Undefine CONFIG_VIDEO_BCM2835 until it builds for arm64. + +See: https://github.com/raspberrypi/linux/issues/3024 +See: https://github.com/raspberrypi/linux/pull/3030 + +Signed-off-by: Phil Elwell +--- + arch/arm/configs/bcm2709_defconfig | 2 +- + arch/arm64/configs/bcm2711_defconfig | 2 -- + 2 files changed, 1 insertion(+), 3 deletions(-) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -16,11 +16,11 @@ CONFIG_IKCONFIG=m + CONFIG_IKCONFIG_PROC=y + CONFIG_MEMCG=y + CONFIG_BLK_CGROUP=y ++CONFIG_CGROUP_PIDS=y + CONFIG_CGROUP_FREEZER=y + CONFIG_CPUSETS=y + CONFIG_CGROUP_DEVICE=y + CONFIG_CGROUP_CPUACCT=y +-CONFIG_CGROUP_PIDS=y + CONFIG_NAMESPACES=y + CONFIG_USER_NS=y + CONFIG_SCHED_AUTOGROUP=y +--- a/arch/arm64/configs/bcm2711_defconfig ++++ b/arch/arm64/configs/bcm2711_defconfig +@@ -1031,7 +1031,6 @@ CONFIG_USB_G_HID=m + CONFIG_USB_G_WEBCAM=m + CONFIG_MMC=y + CONFIG_MMC_BLOCK_MINORS=32 +-CONFIG_MMC_SDHCI_BCM2711=y + CONFIG_MMC_BCM2835_MMC=y + CONFIG_MMC_BCM2835_DMA=y + CONFIG_MMC_BCM2835_SDHOST=y +@@ -1130,7 +1129,6 @@ CONFIG_FB_TFT_WATTEROTT=m + CONFIG_FB_FLEX=m + CONFIG_FB_TFT_FBTFT_DEVICE=m + CONFIG_SND_BCM2835=m +-CONFIG_VIDEO_BCM2835=m + CONFIG_MAILBOX=y + CONFIG_BCM2835_MBOX=y + # CONFIG_IOMMU_SUPPORT is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0680-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch b/target/linux/brcm2708/patches-4.19/950-0680-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch deleted file mode 100644 index 2b87deca80..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0680-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 47ac9aac7067b0415ed2ffe7251a5bfc05114b41 Mon Sep 17 00:00:00 2001 -From: Chris Miller -Date: Wed, 26 Jun 2019 10:40:30 +0100 -Subject: [PATCH 680/703] drm: vc4_dsi: Fix DMA channel and memory leak in vc4 - (#3012) - -Signed-off-by: Chris G Miller ---- - drivers/gpu/drm/vc4/vc4_dsi.c | 35 ++++++++++++++++++++++++----------- - 1 file changed, 24 insertions(+), 11 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_dsi.c -+++ b/drivers/gpu/drm/vc4/vc4_dsi.c -@@ -1536,9 +1536,11 @@ static int vc4_dsi_bind(struct device *d - /* 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. -+ * Where possible managed resource providers are used, but the DMA channel -+ * must - if acquired - be explicitly released prior to taking an error exit path. - */ - if (dsi->port == 1) { -- dsi->reg_dma_mem = dma_alloc_coherent(dev, 4, -+ dsi->reg_dma_mem = dmam_alloc_coherent(dev, 4, - &dsi->reg_dma_paddr, - GFP_KERNEL); - if (!dsi->reg_dma_mem) { -@@ -1557,6 +1559,8 @@ static int vc4_dsi_bind(struct device *d - return ret; - } - -+ /* From here on, any error exits must release the dma channel */ -+ - /* Get the physical address of the device's registers. The - * struct resource for the regs gives us the bus address - * instead. -@@ -1583,7 +1587,7 @@ static int vc4_dsi_bind(struct device *d - if (ret) { - if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to get interrupt: %d\n", ret); -- return ret; -+ goto rel_dma_exit; - } - - dsi->escape_clock = devm_clk_get(dev, "escape"); -@@ -1591,7 +1595,7 @@ static int vc4_dsi_bind(struct device *d - ret = PTR_ERR(dsi->escape_clock); - if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to get escape clock: %d\n", ret); -- return ret; -+ goto rel_dma_exit; - } - - dsi->pll_phy_clock = devm_clk_get(dev, "phy"); -@@ -1599,7 +1603,7 @@ static int vc4_dsi_bind(struct device *d - ret = PTR_ERR(dsi->pll_phy_clock); - if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to get phy clock: %d\n", ret); -- return ret; -+ goto rel_dma_exit; - } - - dsi->pixel_clock = devm_clk_get(dev, "pixel"); -@@ -1607,7 +1611,7 @@ static int vc4_dsi_bind(struct device *d - ret = PTR_ERR(dsi->pixel_clock); - if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to get pixel clock: %d\n", ret); -- return ret; -+ goto rel_dma_exit; - } - - ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, -@@ -1622,26 +1626,28 @@ static int vc4_dsi_bind(struct device *d - if (ret == -ENODEV) - return 0; - -- return ret; -+ goto rel_dma_exit; - } - - if (panel) { - dsi->bridge = devm_drm_panel_bridge_add(dev, panel, - DRM_MODE_CONNECTOR_DSI); -- if (IS_ERR(dsi->bridge)) -- return PTR_ERR(dsi->bridge); -+ if (IS_ERR(dsi->bridge)){ -+ ret = PTR_ERR(dsi->bridge); -+ goto rel_dma_exit; -+ } - } - - /* 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; -+ goto rel_dma_exit; - } - - ret = vc4_dsi_init_phy_clocks(dsi); - if (ret) -- return ret; -+ goto rel_dma_exit; - - if (dsi->port == 1) - vc4->dsi1 = dsi; -@@ -1653,7 +1659,7 @@ static int vc4_dsi_bind(struct device *d - ret = drm_bridge_attach(dsi->encoder, dsi->bridge, NULL); - if (ret) { - dev_err(dev, "bridge attach failed: %d\n", ret); -- return ret; -+ goto rel_dma_exit; - } - /* Disable the atomic helper calls into the bridge. We - * manually call the bridge pre_enable / enable / etc. calls -@@ -1665,6 +1671,11 @@ static int vc4_dsi_bind(struct device *d - pm_runtime_enable(dev); - - return 0; -+ -+rel_dma_exit: -+ dma_release_channel(dsi->reg_dma_chan); -+ -+ return ret; - } - - static void vc4_dsi_unbind(struct device *dev, struct device *master, -@@ -1679,6 +1690,8 @@ static void vc4_dsi_unbind(struct device - - vc4_dsi_encoder_destroy(dsi->encoder); - -+ dma_release_channel(dsi->reg_dma_chan); -+ - if (dsi->port == 1) - vc4->dsi1 = NULL; - } diff --git a/target/linux/brcm2708/patches-4.19/950-0681-arm-dts-Add-coherent_pool-1M-to-Pi-4-bootargs.patch b/target/linux/brcm2708/patches-4.19/950-0681-arm-dts-Add-coherent_pool-1M-to-Pi-4-bootargs.patch new file mode 100644 index 0000000000..acd39fb53f --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0681-arm-dts-Add-coherent_pool-1M-to-Pi-4-bootargs.patch @@ -0,0 +1,28 @@ +From 626e81656bc5a27656180d8faf6173e9bcd7e512 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 2 Jul 2019 17:13:05 +0100 +Subject: [PATCH 681/725] arm: dts: Add coherent_pool=1M to Pi 4 bootargs + +Downstream Raspberry Pi dts files add "coherent_pool=1M" to the kernel +command line to aid the dwc_otg driver, but this excluded Pi 4 which +uses a new XCHI interface instead. UAS also benefits from a larger +coherent_pool value, so replicate the addition in bcm2711-rpi-4-b.dts. + +See: https://github.com/raspberrypi/linux/pull/3040 + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts +@@ -14,7 +14,7 @@ + }; + + chosen { +- bootargs = "8250.nr_uarts=1 cma=64M"; ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 cma=64M"; + }; + + aliases { diff --git a/target/linux/brcm2708/patches-4.19/950-0681-video-bcm2708_fb-Revert-cma-allocation-attempt.patch b/target/linux/brcm2708/patches-4.19/950-0681-video-bcm2708_fb-Revert-cma-allocation-attempt.patch deleted file mode 100644 index d34736362e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0681-video-bcm2708_fb-Revert-cma-allocation-attempt.patch +++ /dev/null @@ -1,159 +0,0 @@ -From d14f0987d0a03c122f6a713df8969109a6213333 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 19 Jun 2019 03:55:50 +0100 -Subject: [PATCH 681/703] video/bcm2708_fb: Revert cma allocation attempt - -"4600e91 Pulled in the multi frame buffer support from the Pi3 repo" -pulled back in the code for allocating the framebuffer from the CMA -heap. -Revert it again. - -Signed-off-by: Dave Stevenson ---- - drivers/video/fbdev/bcm2708_fb.c | 101 +++------------------ - include/soc/bcm2835/raspberrypi-firmware.h | 1 - - 2 files changed, 13 insertions(+), 89 deletions(-) - ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -112,9 +112,6 @@ struct bcm2708_fb { - struct vc4_display_settings_t display_settings; - struct debugfs_regset32 screeninfo_regset; - struct bcm2708_fb_dev *fbdev; -- unsigned int image_size; -- dma_addr_t dma_addr; -- void *cpuaddr; - }; - - #define MAX_FRAMEBUFFERS 3 -@@ -377,12 +374,12 @@ static int bcm2708_fb_set_par(struct fb_ - .xoffset = info->var.xoffset, - .yoffset = info->var.yoffset, - .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 }, -- /* base and screen_size will be initialised later */ -- .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH, 4, 0 }, -- /* pitch will be initialised later */ -+ .base = 0, -+ .screen_size = 0, -+ .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH, 4, 0 }, -+ .pitch = 0, - }; -- int ret, image_size; -- -+ int ret; - - print_debug("%s(%p) %dx%d (%dx%d), %d, %d (display %d)\n", __func__, - info, -@@ -397,76 +394,12 @@ static int bcm2708_fb_set_par(struct fb_ - */ - set_display_num(fb); - -- /* Try allocating our own buffer. We can specify all the parameters */ -- image_size = ((info->var.xres * info->var.yres) * -- info->var.bits_per_pixel) >> 3; -- -- if (!fb->fbdev->disable_arm_alloc && -- (image_size != fb->image_size || !fb->dma_addr)) { -- if (fb->dma_addr) { -- dma_free_coherent(info->device, fb->image_size, -- fb->cpuaddr, fb->dma_addr); -- fb->image_size = 0; -- fb->cpuaddr = NULL; -- fb->dma_addr = 0; -- } -- -- fb->cpuaddr = dma_alloc_coherent(info->device, image_size, -- &fb->dma_addr, GFP_KERNEL); -- -- if (!fb->cpuaddr) { -- fb->dma_addr = 0; -- fb->fbdev->disable_arm_alloc = true; -- } else { -- fb->image_size = image_size; -- } -- } -- -- if (fb->cpuaddr) { -- fbinfo.base = fb->dma_addr; -- fbinfo.screen_size = image_size; -- fbinfo.pitch = (info->var.xres * info->var.bits_per_pixel) >> 3; -- -- ret = rpi_firmware_property_list(fb->fbdev->fw, &fbinfo, -- sizeof(fbinfo)); -- if (ret || fbinfo.base != fb->dma_addr) { -- /* Firmware either failed, or assigned a different base -- * address (ie it doesn't support being passed an FB -- * allocation). -- * Destroy the allocation, and don't try again. -- */ -- dma_free_coherent(info->device, fb->image_size, -- fb->cpuaddr, fb->dma_addr); -- fb->image_size = 0; -- fb->cpuaddr = NULL; -- fb->dma_addr = 0; -- fb->fbdev->disable_arm_alloc = true; -- } -- } else { -- /* Our allocation failed - drop into the old scheme of -- * allocation by the VPU. -- */ -- ret = -ENOMEM; -- } -- -+ ret = rpi_firmware_property_list(fb->fbdev->fw, &fbinfo, -+ sizeof(fbinfo)); - if (ret) { -- /* Old scheme: -- * - FRAMEBUFFER_ALLOCATE passes 0 for base and screen_size. -- * - GET_PITCH instead of SET_PITCH. -- */ -- fbinfo.base = 0; -- fbinfo.screen_size = 0; -- fbinfo.tag6.tag = RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH; -- fbinfo.pitch = 0; -- -- ret = rpi_firmware_property_list(fb->fbdev->fw, &fbinfo, -- sizeof(fbinfo)); -- if (ret) { -- dev_err(info->device, -- "Failed to allocate GPU framebuffer (%d)\n", -- ret); -- return ret; -- } -+ dev_err(info->device, -+ "Failed to allocate GPU framebuffer (%d)\n", ret); -+ return ret; - } - - if (info->var.bits_per_pixel <= 8) -@@ -481,17 +414,9 @@ static int bcm2708_fb_set_par(struct fb_ - fb->fb.fix.smem_start = fbinfo.base; - fb->fb.fix.smem_len = fbinfo.pitch * fbinfo.yres_virtual; - fb->fb.screen_size = fbinfo.screen_size; -- -- if (!fb->dma_addr) { -- if (fb->fb.screen_base) -- iounmap(fb->fb.screen_base); -- -- fb->fb.screen_base = ioremap_wc(fbinfo.base, -- fb->fb.screen_size); -- } else { -- fb->fb.screen_base = fb->cpuaddr; -- } -- -+ if (fb->fb.screen_base) -+ iounmap(fb->fb.screen_base); -+ fb->fb.screen_base = ioremap_wc(fbinfo.base, fb->fb.screen_size); - if (!fb->fb.screen_base) { - /* the console may currently be locked */ - console_trylock(); ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -138,7 +138,6 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, - RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER = 0x00048006, - RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE = 0x00048007, -- RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH = 0x00048008, - RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, - RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, - RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, diff --git a/target/linux/brcm2708/patches-4.19/950-0682-configs-Enable-USB_CONFIGFS-m-in-bcmrpi_defconfig.patch b/target/linux/brcm2708/patches-4.19/950-0682-configs-Enable-USB_CONFIGFS-m-in-bcmrpi_defconfig.patch new file mode 100644 index 0000000000..9597256c85 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0682-configs-Enable-USB_CONFIGFS-m-in-bcmrpi_defconfig.patch @@ -0,0 +1,22 @@ +From d7e89477b16559fc407ad5cc001244346aa8f733 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 2 Jul 2019 21:25:59 +0100 +Subject: [PATCH 682/725] configs: Enable USB_CONFIGFS=m in bcmrpi_defconfig + +See: https://github.com/raspberrypi/linux/issues/3042 + +Signed-off-by: Phil Elwell +--- + arch/arm/configs/bcmrpi_defconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -1150,6 +1150,7 @@ CONFIG_USB_CXACRU=m + CONFIG_USB_UEAGLEATM=m + CONFIG_USB_XUSBATM=m + CONFIG_USB_GADGET=m ++CONFIG_USB_CONFIGFS=m + CONFIG_USB_ZERO=m + CONFIG_USB_AUDIO=m + CONFIG_USB_ETH=m diff --git a/target/linux/brcm2708/patches-4.19/950-0682-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch b/target/linux/brcm2708/patches-4.19/950-0682-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch deleted file mode 100644 index ca0124bab7..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0682-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 5edffe06ee9b72d3fb56853d0652dd9cdc02e44d Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 24 Jun 2019 02:29:40 +0100 -Subject: [PATCH 682/703] drm/vc4: Add support for color encoding on YUV planes - -Adds signalling for BT601/709/2020, and limited/full range -(on BT601). - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 32 +++++++++++++++++++++++++- - drivers/gpu/drm/vc4/vc_image_types.h | 28 ++++++++++++++++++++++ - 2 files changed, 59 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -66,7 +66,7 @@ struct set_plane { - u8 alpha; - u8 num_planes; - u8 is_vu; -- u8 padding; -+ u8 color_encoding; - - u32 planes[4]; /* DMA address of each plane */ - -@@ -454,6 +454,28 @@ static void vc4_plane_atomic_update(stru - if (num_planes == 3 && - (fb->offsets[2] - fb->offsets[1]) == fb->pitches[1]) - mb->plane.vc_image_type = VC_IMAGE_YUV420_S; -+ -+ switch (state->color_encoding) { -+ default: -+ case DRM_COLOR_YCBCR_BT601: -+ if (state->color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) -+ mb->plane.color_encoding = -+ VC_IMAGE_YUVINFO_CSC_ITUR_BT601; -+ else -+ mb->plane.color_encoding = -+ VC_IMAGE_YUVINFO_CSC_JPEG_JFIF; -+ break; -+ case DRM_COLOR_YCBCR_BT709: -+ /* Currently no support for a full range BT709 */ -+ mb->plane.color_encoding = -+ VC_IMAGE_YUVINFO_CSC_ITUR_BT709; -+ break; -+ case DRM_COLOR_YCBCR_BT2020: -+ /* Currently no support for a full range BT2020 */ -+ mb->plane.color_encoding = -+ VC_IMAGE_YUVINFO_CSC_REC_2020; -+ break; -+ } - } else { - mb->plane.planes[1] = 0; - mb->plane.planes[2] = 0; -@@ -643,6 +665,14 @@ static struct drm_plane *vc4_fkms_plane_ - drm_plane_create_alpha_property(plane); - drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0, - SUPPORTED_ROTATIONS); -+ drm_plane_create_color_properties(plane, -+ BIT(DRM_COLOR_YCBCR_BT601) | -+ BIT(DRM_COLOR_YCBCR_BT709) | -+ BIT(DRM_COLOR_YCBCR_BT2020), -+ BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | -+ BIT(DRM_COLOR_YCBCR_FULL_RANGE), -+ DRM_COLOR_YCBCR_BT709, -+ DRM_COLOR_YCBCR_LIMITED_RANGE); - - /* - * Default frame buffer setup is with FB on -127, and raspistill etc ---- a/drivers/gpu/drm/vc4/vc_image_types.h -+++ b/drivers/gpu/drm/vc4/vc_image_types.h -@@ -4,6 +4,8 @@ - * - * Values taken from vc_image_types.h released by Broadcom at - * https://github.com/raspberrypi/userland/blob/master/interface/vctypes/vc_image_types.h -+ * and vc_image_structs.h at -+ * https://github.com/raspberrypi/userland/blob/master/interface/vctypes/vc_image_structs.h - * - * 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 -@@ -141,3 +143,29 @@ enum { - VC_IMAGE_MAX, /* bounds for error checking */ - VC_IMAGE_FORCE_ENUM_16BIT = 0xffff, - }; -+ -+enum { -+ /* Unknown or unset - defaults to BT601 interstitial */ -+ VC_IMAGE_YUVINFO_UNSPECIFIED = 0, -+ -+ /* colour-space conversions data [4 bits] */ -+ -+ /* ITU-R BT.601-5 [SDTV] (compatible with VideoCore-II) */ -+ VC_IMAGE_YUVINFO_CSC_ITUR_BT601 = 1, -+ /* ITU-R BT.709-3 [HDTV] */ -+ VC_IMAGE_YUVINFO_CSC_ITUR_BT709 = 2, -+ /* JPEG JFIF */ -+ VC_IMAGE_YUVINFO_CSC_JPEG_JFIF = 3, -+ /* Title 47 Code of Federal Regulations (2003) 73.682 (a) (20) */ -+ VC_IMAGE_YUVINFO_CSC_FCC = 4, -+ /* Society of Motion Picture and Television Engineers 240M (1999) */ -+ VC_IMAGE_YUVINFO_CSC_SMPTE_240M = 5, -+ /* ITU-R BT.470-2 System M */ -+ VC_IMAGE_YUVINFO_CSC_ITUR_BT470_2_M = 6, -+ /* ITU-R BT.470-2 System B,G */ -+ VC_IMAGE_YUVINFO_CSC_ITUR_BT470_2_BG = 7, -+ /* JPEG JFIF, but with 16..255 luma */ -+ VC_IMAGE_YUVINFO_CSC_JPEG_JFIF_Y16_255 = 8, -+ /* Rec 2020 */ -+ VC_IMAGE_YUVINFO_CSC_REC_2020 = 9, -+}; diff --git a/target/linux/brcm2708/patches-4.19/950-0683-configs-And-all-the-other-USB_CONFIGFS-options.patch b/target/linux/brcm2708/patches-4.19/950-0683-configs-And-all-the-other-USB_CONFIGFS-options.patch new file mode 100644 index 0000000000..951b58d864 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0683-configs-And-all-the-other-USB_CONFIGFS-options.patch @@ -0,0 +1,40 @@ +From 8320deccc7df04c3a094f4c8361b3afc0f85215c Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 2 Jul 2019 21:43:13 +0100 +Subject: [PATCH 683/725] configs: And all the other USB_CONFIGFS options + +And all Rabbit's friends-and-relations. + +See: https://github.com/raspberrypi/linux/issues/3042 + +Signed-off-by: Phil Elwell +--- + arch/arm/configs/bcmrpi_defconfig | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -1151,6 +1151,23 @@ CONFIG_USB_UEAGLEATM=m + CONFIG_USB_XUSBATM=m + CONFIG_USB_GADGET=m + CONFIG_USB_CONFIGFS=m ++CONFIG_USB_CONFIGFS_SERIAL=y ++CONFIG_USB_CONFIGFS_ACM=y ++CONFIG_USB_CONFIGFS_OBEX=y ++CONFIG_USB_CONFIGFS_NCM=y ++CONFIG_USB_CONFIGFS_ECM=y ++CONFIG_USB_CONFIGFS_ECM_SUBSET=y ++CONFIG_USB_CONFIGFS_RNDIS=y ++CONFIG_USB_CONFIGFS_EEM=y ++CONFIG_USB_CONFIGFS_MASS_STORAGE=y ++CONFIG_USB_CONFIGFS_F_LB_SS=y ++CONFIG_USB_CONFIGFS_F_FS=y ++CONFIG_USB_CONFIGFS_F_UAC1=y ++CONFIG_USB_CONFIGFS_F_UAC2=y ++CONFIG_USB_CONFIGFS_F_MIDI=y ++CONFIG_USB_CONFIGFS_F_HID=y ++CONFIG_USB_CONFIGFS_F_UVC=y ++CONFIG_USB_CONFIGFS_F_PRINTER=y + CONFIG_USB_ZERO=m + CONFIG_USB_AUDIO=m + CONFIG_USB_ETH=m diff --git a/target/linux/brcm2708/patches-4.19/950-0683-configs-Drop-V4L2-camera-and-codec-drivers-from-bcmr.patch b/target/linux/brcm2708/patches-4.19/950-0683-configs-Drop-V4L2-camera-and-codec-drivers-from-bcmr.patch deleted file mode 100644 index 9755ccd594..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0683-configs-Drop-V4L2-camera-and-codec-drivers-from-bcmr.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 3467b4cfdf72b5b6f4c5a493be9c3d632aa72211 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 28 Jun 2019 16:05:25 +0100 -Subject: [PATCH 683/703] configs: Drop V4L2 camera and codec drivers from - bcmrpi3_defconfig - -They rely on mmal_vchiq, which in turn wants vc-sm-cma. -vc-sm-cma needs some attention for 64 bit, so drop it for now. - -Signed-off-by: Dave Stevenson ---- - arch/arm64/configs/bcmrpi3_defconfig | 2 -- - 1 file changed, 2 deletions(-) - ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -1086,8 +1086,6 @@ CONFIG_FB_TFT_WATTEROTT=m - CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_SND_BCM2835=m --CONFIG_VIDEO_BCM2835=m --CONFIG_VIDEO_CODEC_BCM2835=m - CONFIG_MAILBOX=y - CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0684-configs-arm64-bcm2711-Add-MMC_SDHCI_IPROC.patch b/target/linux/brcm2708/patches-4.19/950-0684-configs-arm64-bcm2711-Add-MMC_SDHCI_IPROC.patch new file mode 100644 index 0000000000..41fde9b4ce --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0684-configs-arm64-bcm2711-Add-MMC_SDHCI_IPROC.patch @@ -0,0 +1,24 @@ +From ccf319da9985453198ecbc34e7ea490584cc9398 Mon Sep 17 00:00:00 2001 +From: Andrei Gherzan +Date: Wed, 3 Jul 2019 13:53:29 +0100 +Subject: [PATCH 684/725] configs: arm64/bcm2711: Add MMC_SDHCI_IPROC + +This driver is used in the device tree for the emmc2 node. + +See #3032 + +Signed-off-by: Andrei Gherzan +--- + arch/arm64/configs/bcm2711_defconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm64/configs/bcm2711_defconfig ++++ b/arch/arm64/configs/bcm2711_defconfig +@@ -1036,6 +1036,7 @@ CONFIG_MMC_BCM2835_DMA=y + CONFIG_MMC_BCM2835_SDHOST=y + CONFIG_MMC_SDHCI=y + CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SDHCI_IPROC=y + CONFIG_MMC_SPI=m + CONFIG_LEDS_CLASS=y + CONFIG_LEDS_GPIO=y diff --git a/target/linux/brcm2708/patches-4.19/950-0684-configs-arm64-bcm2711-Remove-CONFIG_VIDEO_BCM2835.patch b/target/linux/brcm2708/patches-4.19/950-0684-configs-arm64-bcm2711-Remove-CONFIG_VIDEO_BCM2835.patch deleted file mode 100644 index b30cce42dd..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0684-configs-arm64-bcm2711-Remove-CONFIG_VIDEO_BCM2835.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 548a9808b61de74ad57e904d4952bfbfaabf89a7 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 28 Jun 2019 22:44:09 +0100 -Subject: [PATCH 684/703] configs: arm64/bcm2711: Remove CONFIG_VIDEO_BCM2835 - -Undefine CONFIG_VIDEO_BCM2835 until it builds for arm64. - -See: https://github.com/raspberrypi/linux/issues/3024 -See: https://github.com/raspberrypi/linux/pull/3030 - -Signed-off-by: Phil Elwell ---- - arch/arm/configs/bcm2709_defconfig | 2 +- - arch/arm64/configs/bcm2711_defconfig | 2 -- - 2 files changed, 1 insertion(+), 3 deletions(-) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -16,11 +16,11 @@ CONFIG_IKCONFIG=m - CONFIG_IKCONFIG_PROC=y - CONFIG_MEMCG=y - CONFIG_BLK_CGROUP=y -+CONFIG_CGROUP_PIDS=y - CONFIG_CGROUP_FREEZER=y - CONFIG_CPUSETS=y - CONFIG_CGROUP_DEVICE=y - CONFIG_CGROUP_CPUACCT=y --CONFIG_CGROUP_PIDS=y - CONFIG_NAMESPACES=y - CONFIG_USER_NS=y - CONFIG_SCHED_AUTOGROUP=y ---- a/arch/arm64/configs/bcm2711_defconfig -+++ b/arch/arm64/configs/bcm2711_defconfig -@@ -1031,7 +1031,6 @@ CONFIG_USB_G_HID=m - CONFIG_USB_G_WEBCAM=m - CONFIG_MMC=y - CONFIG_MMC_BLOCK_MINORS=32 --CONFIG_MMC_SDHCI_BCM2711=y - CONFIG_MMC_BCM2835_MMC=y - CONFIG_MMC_BCM2835_DMA=y - CONFIG_MMC_BCM2835_SDHOST=y -@@ -1130,7 +1129,6 @@ CONFIG_FB_TFT_WATTEROTT=m - CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_SND_BCM2835=m --CONFIG_VIDEO_BCM2835=m - CONFIG_MAILBOX=y - CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0685-arm-dts-Add-coherent_pool-1M-to-Pi-4-bootargs.patch b/target/linux/brcm2708/patches-4.19/950-0685-arm-dts-Add-coherent_pool-1M-to-Pi-4-bootargs.patch deleted file mode 100644 index e08928ba8e..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0685-arm-dts-Add-coherent_pool-1M-to-Pi-4-bootargs.patch +++ /dev/null @@ -1,28 +0,0 @@ -From bce3d83c8d1b9e2cab6001f079287ca79912a2fa Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 2 Jul 2019 17:13:05 +0100 -Subject: [PATCH 685/703] arm: dts: Add coherent_pool=1M to Pi 4 bootargs - -Downstream Raspberry Pi dts files add "coherent_pool=1M" to the kernel -command line to aid the dwc_otg driver, but this excluded Pi 4 which -uses a new XCHI interface instead. UAS also benefits from a larger -coherent_pool value, so replicate the addition in bcm2711-rpi-4-b.dts. - -See: https://github.com/raspberrypi/linux/pull/3040 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts -+++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts -@@ -14,7 +14,7 @@ - }; - - chosen { -- bootargs = "8250.nr_uarts=1 cma=64M"; -+ bootargs = "coherent_pool=1M 8250.nr_uarts=1 cma=64M"; - }; - - aliases { diff --git a/target/linux/brcm2708/patches-4.19/950-0685-overlays-Correct-gpio-fan-gpio-flags-for-4.19.patch b/target/linux/brcm2708/patches-4.19/950-0685-overlays-Correct-gpio-fan-gpio-flags-for-4.19.patch new file mode 100644 index 0000000000..4569aaf8da --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0685-overlays-Correct-gpio-fan-gpio-flags-for-4.19.patch @@ -0,0 +1,30 @@ +From ccf4542628ee44ac6acf62361a531ac9479b7872 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 3 Jul 2019 20:37:14 +0100 +Subject: [PATCH 685/725] overlays: Correct gpio-fan gpio flags for 4.19 + +The gpio-fan overlay was submitted for the 4.14 kernel where the second +value in the Device Tree gpios declaration was ignored (thanks to an +old-style driver), allowing the fan-control output to be active-high +even though the declaration appears to request it be active-low. +The gpio-fan driver in 4.19 uses GPIO descriptors and honours the +active-low flag that the overlay (accidentally?) supplies. + +Change/correct the flags field to mark the GPIO as active-high. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/gpio-fan-overlay.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/overlays/gpio-fan-overlay.dts ++++ b/arch/arm/boot/dts/overlays/gpio-fan-overlay.dts +@@ -45,7 +45,7 @@ + __overlay__ { + fan0: gpio-fan@0 { + compatible = "gpio-fan"; +- gpios = <&gpio 12 1>; ++ gpios = <&gpio 12 0>; + gpio-fan,speed-map = <0 0>, + <5000 1>; + #cooling-cells = <2>; diff --git a/target/linux/brcm2708/patches-4.19/950-0686-configs-Enable-USB_CONFIGFS-m-in-bcmrpi_defconfig.patch b/target/linux/brcm2708/patches-4.19/950-0686-configs-Enable-USB_CONFIGFS-m-in-bcmrpi_defconfig.patch deleted file mode 100644 index 9c9f076fc5..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0686-configs-Enable-USB_CONFIGFS-m-in-bcmrpi_defconfig.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 31ddd6caf3ac6c77b6b2e30acc2551c8597a969b Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 2 Jul 2019 21:25:59 +0100 -Subject: [PATCH 686/703] configs: Enable USB_CONFIGFS=m in bcmrpi_defconfig - -See: https://github.com/raspberrypi/linux/issues/3042 - -Signed-off-by: Phil Elwell ---- - arch/arm/configs/bcmrpi_defconfig | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1150,6 +1150,7 @@ CONFIG_USB_CXACRU=m - CONFIG_USB_UEAGLEATM=m - CONFIG_USB_XUSBATM=m - CONFIG_USB_GADGET=m -+CONFIG_USB_CONFIGFS=m - CONFIG_USB_ZERO=m - CONFIG_USB_AUDIO=m - CONFIG_USB_ETH=m diff --git a/target/linux/brcm2708/patches-4.19/950-0686-staging-vcsm-cma-Remove-cache-manipulation-ioctl-fro.patch b/target/linux/brcm2708/patches-4.19/950-0686-staging-vcsm-cma-Remove-cache-manipulation-ioctl-fro.patch new file mode 100644 index 0000000000..1c23bc0dcc --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0686-staging-vcsm-cma-Remove-cache-manipulation-ioctl-fro.patch @@ -0,0 +1,78 @@ +From ced45257bef9255fda33051f882c83623d9e0699 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 25 Jun 2019 00:29:44 +0100 +Subject: [PATCH 686/725] staging: vcsm-cma: Remove cache manipulation ioctl + from ARM64 + +The cache flushing ioctls are used by the Pi3 HEVC hw-assisted +decoder as it needs finer grained flushing control than dma_ops +allow. +These cache calls are not present for ARM64, therefore disable +them. We are not actively supporting 64bit kernels at present, +and the use case of the HEVC decoder is fairly limited. + +Signed-off-by: Dave Stevenson +--- + drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -1259,6 +1259,7 @@ error: + return ret; + } + ++#ifndef CONFIG_ARM64 + /* Converts VCSM_CACHE_OP_* to an operating function. */ + static void (*cache_op_to_func(const unsigned int cache_op)) + (const void*, const void*) +@@ -1351,6 +1352,7 @@ out: + + return ret; + } ++#endif + + static long vc_sm_cma_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +@@ -1448,6 +1450,7 @@ static long vc_sm_cma_ioctl(struct file + break; + } + ++#ifndef CONFIG_ARM64 + /* + * Flush/Invalidate the cache for a given mapping. + * Blocks must be pinned (i.e. accessed) before this call. +@@ -1455,6 +1458,7 @@ static long vc_sm_cma_ioctl(struct file + case VC_SM_CMA_CMD_CLEAN_INVALID2: + ret = vc_sm_cma_clean_invalid2(cmdnr, arg); + break; ++#endif + + default: + pr_debug("[%s]: cmd %x tgid %u, owner %u\n", __func__, cmdnr, +@@ -1467,6 +1471,7 @@ static long vc_sm_cma_ioctl(struct file + return ret; + } + ++#ifndef CONFIG_ARM64 + #ifdef CONFIG_COMPAT + struct vc_sm_cma_ioctl_clean_invalid2_32 { + u32 op_count; +@@ -1496,14 +1501,17 @@ static long vc_sm_cma_compat_ioctl(struc + } + } + #endif ++#endif + + /* Device operations that we managed in this driver. */ + static const struct file_operations vc_sm_ops = { + .owner = THIS_MODULE, + .unlocked_ioctl = vc_sm_cma_ioctl, ++#ifndef CONFIG_ARM64 + #ifdef CONFIG_COMPAT + .compat_ioctl = vc_sm_cma_compat_ioctl, + #endif ++#endif + .open = vc_sm_cma_open, + .release = vc_sm_cma_release, + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0687-configs-And-all-the-other-USB_CONFIGFS-options.patch b/target/linux/brcm2708/patches-4.19/950-0687-configs-And-all-the-other-USB_CONFIGFS-options.patch deleted file mode 100644 index b511bf2630..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0687-configs-And-all-the-other-USB_CONFIGFS-options.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 04958bf394a778098ead8eedb27c51c44f58ef21 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 2 Jul 2019 21:43:13 +0100 -Subject: [PATCH 687/703] configs: And all the other USB_CONFIGFS options - -And all Rabbit's friends-and-relations. - -See: https://github.com/raspberrypi/linux/issues/3042 - -Signed-off-by: Phil Elwell ---- - arch/arm/configs/bcmrpi_defconfig | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1151,6 +1151,23 @@ CONFIG_USB_UEAGLEATM=m - CONFIG_USB_XUSBATM=m - CONFIG_USB_GADGET=m - CONFIG_USB_CONFIGFS=m -+CONFIG_USB_CONFIGFS_SERIAL=y -+CONFIG_USB_CONFIGFS_ACM=y -+CONFIG_USB_CONFIGFS_OBEX=y -+CONFIG_USB_CONFIGFS_NCM=y -+CONFIG_USB_CONFIGFS_ECM=y -+CONFIG_USB_CONFIGFS_ECM_SUBSET=y -+CONFIG_USB_CONFIGFS_RNDIS=y -+CONFIG_USB_CONFIGFS_EEM=y -+CONFIG_USB_CONFIGFS_MASS_STORAGE=y -+CONFIG_USB_CONFIGFS_F_LB_SS=y -+CONFIG_USB_CONFIGFS_F_FS=y -+CONFIG_USB_CONFIGFS_F_UAC1=y -+CONFIG_USB_CONFIGFS_F_UAC2=y -+CONFIG_USB_CONFIGFS_F_MIDI=y -+CONFIG_USB_CONFIGFS_F_HID=y -+CONFIG_USB_CONFIGFS_F_UVC=y -+CONFIG_USB_CONFIGFS_F_PRINTER=y - CONFIG_USB_ZERO=m - CONFIG_USB_AUDIO=m - CONFIG_USB_ETH=m diff --git a/target/linux/brcm2708/patches-4.19/950-0687-staging-vcsm-cma-Rework-to-use-dma-APIs-not-CMA.patch b/target/linux/brcm2708/patches-4.19/950-0687-staging-vcsm-cma-Rework-to-use-dma-APIs-not-CMA.patch new file mode 100644 index 0000000000..0af7973327 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0687-staging-vcsm-cma-Rework-to-use-dma-APIs-not-CMA.patch @@ -0,0 +1,758 @@ +From 03d574236ca07cd6ffec88a8124426e5e42722e1 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 1 Jul 2019 11:57:25 +0100 +Subject: [PATCH 687/725] staging: vcsm-cma: Rework to use dma APIs, not CMA + +Due to a misunderstanding of the DMA mapping APIs, I made +the wrong decision on how to implement this. + +Rework to use dma_alloc_coherent instead of the CMA +API. This also allows it to be built as a module easily. + +Signed-off-by: Dave Stevenson +--- + .../staging/vc04_services/vc-sm-cma/Kconfig | 4 +- + .../staging/vc04_services/vc-sm-cma/Makefile | 2 +- + .../staging/vc04_services/vc-sm-cma/vc_sm.c | 291 ++++++++++-------- + .../staging/vc04_services/vc-sm-cma/vc_sm.h | 13 +- + .../vc04_services/vc-sm-cma/vc_sm_cma.c | 98 ------ + .../vc04_services/vc-sm-cma/vc_sm_cma.h | 39 --- + 6 files changed, 168 insertions(+), 279 deletions(-) + delete mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.c + delete mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.h + +--- a/drivers/staging/vc04_services/vc-sm-cma/Kconfig ++++ b/drivers/staging/vc04_services/vc-sm-cma/Kconfig +@@ -1,6 +1,6 @@ + config BCM_VC_SM_CMA +- bool "VideoCore Shared Memory (CMA) driver" +- depends on BCM2835_VCHIQ && DMA_CMA ++ tristate "VideoCore Shared Memory (CMA) driver" ++ depends on BCM2835_VCHIQ + select RBTREE + select DMA_SHARED_BUFFER + help +--- a/drivers/staging/vc04_services/vc-sm-cma/Makefile ++++ b/drivers/staging/vc04_services/vc-sm-cma/Makefile +@@ -3,6 +3,6 @@ ccflags-y += -Idrivers/staging/vc04_serv + ccflags-y += -D__VCCOREVER__=0 + + vc-sm-cma-$(CONFIG_BCM_VC_SM_CMA) := \ +- vc_sm.o vc_sm_cma_vchi.o vc_sm_cma.o ++ vc_sm.o vc_sm_cma_vchi.o + + obj-$(CONFIG_BCM_VC_SM_CMA) += vc-sm-cma.o +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -6,8 +6,8 @@ + * Dave Stevenson + * + * Based on vmcs_sm driver from Broadcom Corporation for some API, +- * and taking some code for CMA/dmabuf handling from the Android Ion +- * driver (Google/Linaro). ++ * and taking some code for buffer allocation and dmabuf handling from ++ * videobuf2. + * + * + * This driver has 3 main uses: +@@ -52,7 +52,6 @@ + #include "vc_sm_cma_vchi.h" + + #include "vc_sm.h" +-#include "vc_sm_cma.h" + #include "vc_sm_knl.h" + #include + +@@ -89,7 +88,6 @@ struct sm_state_t { + struct miscdevice misc_dev; + + struct sm_instance *sm_handle; /* Handle for videocore service. */ +- struct cma *cma_heap; + + spinlock_t kernelid_map_lock; /* Spinlock protecting kernelid_map */ + struct idr kernelid_map; +@@ -110,8 +108,9 @@ struct sm_state_t { + + struct vc_sm_dma_buf_attachment { + struct device *dev; +- struct sg_table *table; ++ struct sg_table sg_table; + struct list_head list; ++ enum dma_data_direction dma_dir; + }; + + /* ---- Private Variables ----------------------------------------------- */ +@@ -202,9 +201,10 @@ static int vc_sm_cma_global_state_show(s + resource->import.attach); + seq_printf(s, " SGT %p\n", + resource->import.sgt); ++ } else { ++ seq_printf(s, " SGT %p\n", ++ resource->alloc.sg_table); + } +- seq_printf(s, " SG_TABLE %p\n", +- resource->sg_table); + seq_printf(s, " DMA_ADDR %pad\n", + &resource->dma_addr); + seq_printf(s, " VC_HANDLE %08x\n", +@@ -296,8 +296,9 @@ static void vc_sm_vpu_free(struct vc_sm_ + */ + static void vc_sm_release_resource(struct vc_sm_buffer *buffer) + { +- pr_debug("[%s]: buffer %p (name %s, size %zu)\n", +- __func__, buffer, buffer->name, buffer->size); ++ pr_debug("[%s]: buffer %p (name %s, size %zu), imported %u\n", ++ __func__, buffer, buffer->name, buffer->size, ++ buffer->imported); + + if (buffer->vc_handle) { + /* We've sent the unmap request but not had the response. */ +@@ -313,8 +314,6 @@ static void vc_sm_release_resource(struc + + /* Release the allocation (whether imported dmabuf or CMA allocation) */ + if (buffer->imported) { +- pr_debug("%s: Release imported dmabuf %p\n", __func__, +- buffer->import.dma_buf); + if (buffer->import.dma_buf) + dma_buf_put(buffer->import.dma_buf); + else +@@ -322,16 +321,8 @@ static void vc_sm_release_resource(struc + __func__, buffer); + buffer->import.dma_buf = NULL; + } else { +- if (buffer->sg_table) { +- /* Our own allocation that we need to dma_unmap_sg */ +- dma_unmap_sg(&sm_state->pdev->dev, +- buffer->sg_table->sgl, +- buffer->sg_table->nents, +- DMA_BIDIRECTIONAL); +- } +- pr_debug("%s: Release our allocation\n", __func__); +- vc_sm_cma_buffer_free(&buffer->alloc); +- pr_debug("%s: Release our allocation - done\n", __func__); ++ dma_free_coherent(&sm_state->pdev->dev, buffer->size, ++ buffer->cookie, buffer->dma_addr); + } + + +@@ -371,38 +362,6 @@ static struct vc_sm_privdata_t *vc_sm_cm + return file_data; + } + +-static struct sg_table *dup_sg_table(struct sg_table *table) +-{ +- struct sg_table *new_table; +- int ret, i; +- struct scatterlist *sg, *new_sg; +- +- new_table = kzalloc(sizeof(*new_table), GFP_KERNEL); +- if (!new_table) +- return ERR_PTR(-ENOMEM); +- +- ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL); +- if (ret) { +- kfree(new_table); +- return ERR_PTR(ret); +- } +- +- new_sg = new_table->sgl; +- for_each_sg(table->sgl, sg, table->nents, i) { +- memcpy(new_sg, sg, sizeof(*sg)); +- sg->dma_address = 0; +- new_sg = sg_next(new_sg); +- } +- +- return new_table; +-} +- +-static void free_duped_table(struct sg_table *table) +-{ +- sg_free_table(table); +- kfree(table); +-} +- + /* Dma buf operations for use with our own allocations */ + + static int vc_sm_dma_buf_attach(struct dma_buf *dmabuf, +@@ -410,28 +369,45 @@ static int vc_sm_dma_buf_attach(struct d + + { + struct vc_sm_dma_buf_attachment *a; +- struct sg_table *table; ++ struct sg_table *sgt; + struct vc_sm_buffer *buf = dmabuf->priv; ++ struct scatterlist *rd, *wr; ++ int ret, i; + + a = kzalloc(sizeof(*a), GFP_KERNEL); + if (!a) + return -ENOMEM; + +- table = dup_sg_table(buf->sg_table); +- if (IS_ERR(table)) { ++ pr_debug("%s dmabuf %p attachment %p\n", __func__, dmabuf, attachment); ++ ++ mutex_lock(&buf->lock); ++ ++ INIT_LIST_HEAD(&a->list); ++ ++ sgt = &a->sg_table; ++ ++ /* Copy the buf->base_sgt scatter list to the attachment, as we can't ++ * map the same scatter list to multiple attachments at the same time. ++ */ ++ ret = sg_alloc_table(sgt, buf->alloc.sg_table->orig_nents, GFP_KERNEL); ++ if (ret) { + kfree(a); +- return PTR_ERR(table); ++ return -ENOMEM; + } + +- a->table = table; +- INIT_LIST_HEAD(&a->list); ++ rd = buf->alloc.sg_table->sgl; ++ wr = sgt->sgl; ++ for (i = 0; i < sgt->orig_nents; ++i) { ++ sg_set_page(wr, sg_page(rd), rd->length, rd->offset); ++ rd = sg_next(rd); ++ wr = sg_next(wr); ++ } + ++ a->dma_dir = DMA_NONE; + attachment->priv = a; + +- mutex_lock(&buf->lock); + list_add(&a->list, &buf->attachments); + mutex_unlock(&buf->lock); +- pr_debug("%s dmabuf %p attachment %p\n", __func__, dmabuf, attachment); + + return 0; + } +@@ -441,9 +417,20 @@ static void vc_sm_dma_buf_detach(struct + { + struct vc_sm_dma_buf_attachment *a = attachment->priv; + struct vc_sm_buffer *buf = dmabuf->priv; ++ struct sg_table *sgt; + + pr_debug("%s dmabuf %p attachment %p\n", __func__, dmabuf, attachment); +- free_duped_table(a->table); ++ if (!a) ++ return; ++ ++ sgt = &a->sg_table; ++ ++ /* release the scatterlist cache */ ++ if (a->dma_dir != DMA_NONE) ++ dma_unmap_sg(attachment->dev, sgt->sgl, sgt->orig_nents, ++ a->dma_dir); ++ sg_free_table(sgt); ++ + mutex_lock(&buf->lock); + list_del(&a->list); + mutex_unlock(&buf->lock); +@@ -455,13 +442,38 @@ static struct sg_table *vc_sm_map_dma_bu + enum dma_data_direction direction) + { + struct vc_sm_dma_buf_attachment *a = attachment->priv; ++ /* stealing dmabuf mutex to serialize map/unmap operations */ ++ struct mutex *lock = &attachment->dmabuf->lock; + struct sg_table *table; + +- table = a->table; ++ mutex_lock(lock); ++ pr_debug("%s attachment %p\n", __func__, attachment); ++ table = &a->sg_table; ++ ++ /* return previously mapped sg table */ ++ if (a->dma_dir == direction) { ++ mutex_unlock(lock); ++ return table; ++ } ++ ++ /* release any previous cache */ ++ if (a->dma_dir != DMA_NONE) { ++ dma_unmap_sg(attachment->dev, table->sgl, table->orig_nents, ++ a->dma_dir); ++ a->dma_dir = DMA_NONE; ++ } ++ ++ /* mapping to the client with new direction */ ++ table->nents = dma_map_sg(attachment->dev, table->sgl, ++ table->orig_nents, direction); ++ if (!table->nents) { ++ pr_err("failed to map scatterlist\n"); ++ mutex_unlock(lock); ++ return ERR_PTR(-EIO); ++ } + +- if (!dma_map_sg(attachment->dev, table->sgl, table->nents, +- direction)) +- return ERR_PTR(-ENOMEM); ++ a->dma_dir = direction; ++ mutex_unlock(lock); + + pr_debug("%s attachment %p\n", __func__, attachment); + return table; +@@ -478,41 +490,26 @@ static void vc_sm_unmap_dma_buf(struct d + static int vc_sm_dmabuf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) + { + struct vc_sm_buffer *buf = dmabuf->priv; +- struct sg_table *table = buf->sg_table; +- unsigned long addr = vma->vm_start; +- unsigned long offset = vma->vm_pgoff * PAGE_SIZE; +- struct scatterlist *sg; +- int i; +- int ret = 0; ++ int ret; + + pr_debug("%s dmabuf %p, buf %p, vm_start %08lX\n", __func__, dmabuf, +- buf, addr); ++ buf, vma->vm_start); + + mutex_lock(&buf->lock); + + /* now map it to userspace */ +- for_each_sg(table->sgl, sg, table->nents, i) { +- struct page *page = sg_page(sg); +- unsigned long remainder = vma->vm_end - addr; +- unsigned long len = sg->length; ++ vma->vm_pgoff = 0; + +- if (offset >= sg->length) { +- offset -= sg->length; +- continue; +- } else if (offset) { +- page += offset / PAGE_SIZE; +- len = sg->length - offset; +- offset = 0; +- } +- len = min(len, remainder); +- ret = remap_pfn_range(vma, addr, page_to_pfn(page), len, +- vma->vm_page_prot); +- if (ret) +- break; +- addr += len; +- if (addr >= vma->vm_end) +- break; ++ ret = dma_mmap_coherent(&sm_state->pdev->dev, vma, buf->cookie, ++ buf->dma_addr, buf->size); ++ ++ if (ret) { ++ pr_err("Remapping memory failed, error: %d\n", ret); ++ return ret; + } ++ ++ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; ++ + mutex_unlock(&buf->lock); + + if (ret) +@@ -570,8 +567,8 @@ static int vc_sm_dma_buf_begin_cpu_acces + mutex_lock(&buf->lock); + + list_for_each_entry(a, &buf->attachments, list) { +- dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents, +- direction); ++ dma_sync_sg_for_cpu(a->dev, a->sg_table.sgl, ++ a->sg_table.nents, direction); + } + mutex_unlock(&buf->lock); + +@@ -593,8 +590,8 @@ static int vc_sm_dma_buf_end_cpu_access( + mutex_lock(&buf->lock); + + list_for_each_entry(a, &buf->attachments, list) { +- dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents, +- direction); ++ dma_sync_sg_for_device(a->dev, a->sg_table.sgl, ++ a->sg_table.nents, direction); + } + mutex_unlock(&buf->lock); + +@@ -625,7 +622,9 @@ static const struct dma_buf_ops dma_buf_ + .map = vc_sm_dma_buf_kmap, + .unmap = vc_sm_dma_buf_kunmap, + }; ++ + /* Dma_buf operations for chaining through to an imported dma_buf */ ++ + static + int vc_sm_import_dma_buf_attach(struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment) +@@ -819,7 +818,7 @@ vc_sm_cma_import_dmabuf_internal(struct + + import.type = VC_SM_ALLOC_NON_CACHED; + dma_addr = sg_dma_address(sgt->sgl); +- import.addr = (uint32_t)dma_addr; ++ import.addr = (u32)dma_addr; + if ((import.addr & 0xC0000000) != 0xC0000000) { + pr_err("%s: Expecting an uncached alias for dma_addr %pad\n", + __func__, &dma_addr); +@@ -911,11 +910,12 @@ error: + return ret; + } + +-static int vc_sm_cma_vpu_alloc(u32 size, uint32_t align, const char *name, ++static int vc_sm_cma_vpu_alloc(u32 size, u32 align, const char *name, + u32 mem_handle, struct vc_sm_buffer **ret_buffer) + { + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + struct vc_sm_buffer *buffer = NULL; ++ struct sg_table *sgt; + int aligned_size; + int ret = 0; + +@@ -938,23 +938,34 @@ static int vc_sm_cma_vpu_alloc(u32 size, + */ + mutex_lock(&buffer->lock); + +- if (vc_sm_cma_buffer_allocate(sm_state->cma_heap, &buffer->alloc, +- aligned_size)) { +- pr_err("[%s]: cma alloc of %d bytes failed\n", ++ buffer->cookie = dma_alloc_coherent(&sm_state->pdev->dev, ++ aligned_size, &buffer->dma_addr, ++ GFP_KERNEL); ++ if (!buffer->cookie) { ++ pr_err("[%s]: dma_alloc_coherent alloc of %d bytes failed\n", + __func__, aligned_size); + ret = -ENOMEM; + goto error; + } +- buffer->sg_table = buffer->alloc.sg_table; + +- pr_debug("[%s]: cma alloc of %d bytes success\n", ++ pr_debug("[%s]: alloc of %d bytes success\n", + __func__, aligned_size); + +- if (dma_map_sg(&sm_state->pdev->dev, buffer->sg_table->sgl, +- buffer->sg_table->nents, DMA_BIDIRECTIONAL) <= 0) { +- pr_err("[%s]: dma_map_sg failed\n", __func__); ++ sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); ++ if (!sgt) { ++ ret = -ENOMEM; ++ goto error; ++ } ++ ++ ret = dma_get_sgtable(&sm_state->pdev->dev, sgt, buffer->cookie, ++ buffer->dma_addr, buffer->size); ++ if (ret < 0) { ++ pr_err("failed to get scatterlist from DMA API\n"); ++ kfree(sgt); ++ ret = -ENOMEM; + goto error; + } ++ buffer->alloc.sg_table = sgt; + + INIT_LIST_HEAD(&buffer->attachments); + +@@ -971,10 +982,10 @@ static int vc_sm_cma_vpu_alloc(u32 size, + ret = PTR_ERR(buffer->dma_buf); + goto error; + } +- buffer->dma_addr = (uint32_t)sg_dma_address(buffer->sg_table->sgl); ++ buffer->dma_addr = (u32)sg_dma_address(buffer->alloc.sg_table->sgl); + if ((buffer->dma_addr & 0xC0000000) != 0xC0000000) { +- pr_err("%s: Expecting an uncached alias for dma_addr %pad\n", +- __func__, &buffer->dma_addr); ++ pr_warn_once("%s: Expecting an uncached alias for dma_addr %pad\n", ++ __func__, &buffer->dma_addr); + buffer->dma_addr |= 0xC0000000; + } + buffer->private = sm_state->vpu_allocs; +@@ -1145,6 +1156,7 @@ int vc_sm_cma_ioctl_alloc(struct vc_sm_p + struct vc_sm_import import = { 0 }; + struct vc_sm_import_result result = { 0 }; + struct dma_buf *dmabuf = NULL; ++ struct sg_table *sgt; + int aligned_size; + int ret = 0; + int status; +@@ -1162,18 +1174,13 @@ int vc_sm_cma_ioctl_alloc(struct vc_sm_p + goto error; + } + +- if (vc_sm_cma_buffer_allocate(sm_state->cma_heap, &buffer->alloc, +- aligned_size)) { +- pr_err("[%s]: cma alloc of %d bytes failed\n", ++ buffer->cookie = dma_alloc_coherent(&sm_state->pdev->dev, ++ aligned_size, ++ &buffer->dma_addr, ++ GFP_KERNEL); ++ if (!buffer->cookie) { ++ pr_err("[%s]: dma_alloc_coherent alloc of %d bytes failed\n", + __func__, aligned_size); +- kfree(buffer); +- return -ENOMEM; +- } +- buffer->sg_table = buffer->alloc.sg_table; +- +- if (dma_map_sg(&sm_state->pdev->dev, buffer->sg_table->sgl, +- buffer->sg_table->nents, DMA_BIDIRECTIONAL) <= 0) { +- pr_err("[%s]: dma_map_sg failed\n", __func__); + ret = -ENOMEM; + goto error; + } +@@ -1204,7 +1211,7 @@ int vc_sm_cma_ioctl_alloc(struct vc_sm_p + } + buffer->dma_buf = dmabuf; + +- import.addr = (uint32_t)sg_dma_address(buffer->sg_table->sgl); ++ import.addr = buffer->dma_addr; + import.size = aligned_size; + import.kernel_id = get_kernel_id(buffer); + +@@ -1229,10 +1236,25 @@ int vc_sm_cma_ioctl_alloc(struct vc_sm_p + buffer->private = private; + buffer->vc_handle = result.res_handle; + buffer->size = import.size; +- buffer->dma_addr = import.addr; + buffer->vpu_state = VPU_MAPPED; + buffer->kernel_id = import.kernel_id; +- //buffer->res_cached = ioparam->cached; ++ ++ sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); ++ if (!sgt) { ++ ret = -ENOMEM; ++ goto error; ++ } ++ ++ ret = dma_get_sgtable(&sm_state->pdev->dev, sgt, buffer->cookie, ++ buffer->dma_addr, buffer->size); ++ if (ret < 0) { ++ /* FIXME: error handling */ ++ pr_err("failed to get scatterlist from DMA API\n"); ++ kfree(sgt); ++ ret = -ENOMEM; ++ goto error; ++ } ++ buffer->alloc.sg_table = sgt; + + fd = dma_buf_fd(dmabuf, O_CLOEXEC); + if (fd < 0) +@@ -1250,11 +1272,19 @@ int vc_sm_cma_ioctl_alloc(struct vc_sm_p + return 0; + + error: +- if (buffer) { +- pr_err("[%s]: something failed - cleanup. ret %d\n", __func__, +- ret); ++ pr_err("[%s]: something failed - cleanup. ret %d\n", __func__, ret); + ++ if (dmabuf) { ++ /* dmabuf has been exported, therefore allow dmabuf cleanup to ++ * deal with this ++ */ + dma_buf_put(dmabuf); ++ } else { ++ /* No dmabuf, therefore just free the buffer here */ ++ if (buffer->cookie) ++ dma_free_coherent(&sm_state->pdev->dev, buffer->size, ++ buffer->cookie, buffer->dma_addr); ++ kfree(buffer); + } + return ret; + } +@@ -1527,13 +1557,6 @@ static void vc_sm_connected_init(void) + + pr_info("[%s]: start\n", __func__); + +- vc_sm_cma_add_heaps(&sm_state->cma_heap); +- if (!sm_state->cma_heap) { +- pr_err("[%s]: failed to initialise CMA heap\n", +- __func__); +- return; +- } +- + /* + * Initialize and create a VCHI connection for the shared memory service + * running on videocore. +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.h ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.h +@@ -21,8 +21,6 @@ + #include + #include + +-#include "vc_sm_cma.h" +- + #define VC_SM_MAX_NAME_LEN 32 + + enum vc_sm_vpu_mapping_state { +@@ -31,6 +29,12 @@ enum vc_sm_vpu_mapping_state { + VPU_UNMAPPING + }; + ++struct vc_sm_alloc_data { ++ unsigned long num_pages; ++ void *priv_virt; ++ struct sg_table *sg_table; ++}; ++ + struct vc_sm_imported { + struct dma_buf *dma_buf; + struct dma_buf_attachment *attach; +@@ -56,8 +60,6 @@ struct vc_sm_buffer { + int in_use:1; /* Kernel is still using this resource */ + int imported:1; /* Imported dmabuf */ + +- struct sg_table *sg_table; +- + enum vc_sm_vpu_mapping_state vpu_state; + u32 vc_handle; /* VideoCore handle for this buffer */ + int vpu_allocated; /* +@@ -69,11 +71,12 @@ struct vc_sm_buffer { + /* DMABUF related fields */ + struct dma_buf *dma_buf; + dma_addr_t dma_addr; ++ void *cookie; + + struct vc_sm_privdata_t *private; + + union { +- struct vc_sm_cma_alloc_data alloc; ++ struct vc_sm_alloc_data alloc; + struct vc_sm_imported import; + }; + }; +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.c ++++ /dev/null +@@ -1,98 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +-/* +- * VideoCore Shared Memory CMA allocator +- * +- * Copyright: 2018, Raspberry Pi (Trading) Ltd +- * +- * Based on the Android ION allocator +- * Copyright (C) Linaro 2012 +- * Author: for ST-Ericsson. +- * +- */ +- +-#include +-#include +-#include +-#include +-#include +- +-#include "vc_sm_cma.h" +- +-/* CMA heap operations functions */ +-int vc_sm_cma_buffer_allocate(struct cma *cma_heap, +- struct vc_sm_cma_alloc_data *buffer, +- unsigned long len) +-{ +- /* len should already be page aligned */ +- unsigned long num_pages = len / PAGE_SIZE; +- struct sg_table *table; +- struct page *pages; +- int ret; +- +- pages = cma_alloc(cma_heap, num_pages, 0, GFP_KERNEL); +- if (!pages) +- return -ENOMEM; +- +- table = kmalloc(sizeof(*table), GFP_KERNEL); +- if (!table) +- goto err; +- +- ret = sg_alloc_table(table, 1, GFP_KERNEL); +- if (ret) +- goto free_mem; +- +- sg_set_page(table->sgl, pages, len, 0); +- +- buffer->priv_virt = pages; +- buffer->sg_table = table; +- buffer->cma_heap = cma_heap; +- buffer->num_pages = num_pages; +- return 0; +- +-free_mem: +- kfree(table); +-err: +- cma_release(cma_heap, pages, num_pages); +- return -ENOMEM; +-} +- +-void vc_sm_cma_buffer_free(struct vc_sm_cma_alloc_data *buffer) +-{ +- struct cma *cma_heap = buffer->cma_heap; +- struct page *pages = buffer->priv_virt; +- +- /* release memory */ +- if (cma_heap) +- cma_release(cma_heap, pages, buffer->num_pages); +- +- /* release sg table */ +- if (buffer->sg_table) { +- sg_free_table(buffer->sg_table); +- kfree(buffer->sg_table); +- buffer->sg_table = NULL; +- } +-} +- +-int __vc_sm_cma_add_heaps(struct cma *cma, void *priv) +-{ +- struct cma **heap = (struct cma **)priv; +- const char *name = cma_get_name(cma); +- +- if (!(*heap)) { +- phys_addr_t phys_addr = cma_get_base(cma); +- +- pr_debug("%s: Adding cma heap %s (start %pap, size %lu) for use by vcsm\n", +- __func__, name, &phys_addr, cma_get_size(cma)); +- *heap = cma; +- } else { +- pr_err("%s: Ignoring heap %s as already set\n", +- __func__, name); +- } +- +- return 0; +-} +- +-void vc_sm_cma_add_heaps(struct cma **cma_heap) +-{ +- cma_for_each_area(__vc_sm_cma_add_heaps, cma_heap); +-} +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.h ++++ /dev/null +@@ -1,39 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ +- +-/* +- * VideoCore Shared Memory CMA allocator +- * +- * Copyright: 2018, Raspberry Pi (Trading) Ltd +- * +- * Based on the Android ION allocator +- * Copyright (C) Linaro 2012 +- * Author: for ST-Ericsson. +- * +- * This software is licensed under the terms of the GNU General Public +- * License version 2, as published by the Free Software Foundation, and +- * may be copied, distributed, and modified under those terms. +- * +- * 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 VC_SM_CMA_H +-#define VC_SM_CMA_H +- +-struct vc_sm_cma_alloc_data { +- struct cma *cma_heap; +- unsigned long num_pages; +- void *priv_virt; +- struct sg_table *sg_table; +-}; +- +-int vc_sm_cma_buffer_allocate(struct cma *cma_heap, +- struct vc_sm_cma_alloc_data *buffer, +- unsigned long len); +-void vc_sm_cma_buffer_free(struct vc_sm_cma_alloc_data *buffer); +- +-void vc_sm_cma_add_heaps(struct cma **cma_heap); +- +-#endif diff --git a/target/linux/brcm2708/patches-4.19/950-0688-Revert-configs-Drop-V4L2-camera-and-codec-drivers-fr.patch b/target/linux/brcm2708/patches-4.19/950-0688-Revert-configs-Drop-V4L2-camera-and-codec-drivers-fr.patch new file mode 100644 index 0000000000..26bbc579ec --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0688-Revert-configs-Drop-V4L2-camera-and-codec-drivers-fr.patch @@ -0,0 +1,26 @@ +From 9c2c5607d3210f9d582547465aae6c9883daf0d9 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 1 Jul 2019 12:00:27 +0100 +Subject: [PATCH 688/725] Revert "configs: Drop V4L2 camera and codec drivers + from bcmrpi3_defconfig" + +This reverts commit e8a66b4f610b3a20bae8f706256d230135916c26. + +The issues are now resolved. + +Signed-off-by: Dave Stevenson +--- + arch/arm64/configs/bcmrpi3_defconfig | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -1086,6 +1086,8 @@ CONFIG_FB_TFT_WATTEROTT=m + CONFIG_FB_FLEX=m + CONFIG_FB_TFT_FBTFT_DEVICE=m + CONFIG_SND_BCM2835=m ++CONFIG_VIDEO_BCM2835=m ++CONFIG_VIDEO_CODEC_BCM2835=m + CONFIG_MAILBOX=y + CONFIG_BCM2835_MBOX=y + # CONFIG_IOMMU_SUPPORT is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0688-configs-arm64-bcm2711-Add-MMC_SDHCI_IPROC.patch b/target/linux/brcm2708/patches-4.19/950-0688-configs-arm64-bcm2711-Add-MMC_SDHCI_IPROC.patch deleted file mode 100644 index 3dc471956f..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0688-configs-arm64-bcm2711-Add-MMC_SDHCI_IPROC.patch +++ /dev/null @@ -1,24 +0,0 @@ -From efdc8dd4cb2e2d607f2c1cc0689faa6590c164f2 Mon Sep 17 00:00:00 2001 -From: Andrei Gherzan -Date: Wed, 3 Jul 2019 13:53:29 +0100 -Subject: [PATCH 688/703] configs: arm64/bcm2711: Add MMC_SDHCI_IPROC - -This driver is used in the device tree for the emmc2 node. - -See #3032 - -Signed-off-by: Andrei Gherzan ---- - arch/arm64/configs/bcm2711_defconfig | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm64/configs/bcm2711_defconfig -+++ b/arch/arm64/configs/bcm2711_defconfig -@@ -1036,6 +1036,7 @@ CONFIG_MMC_BCM2835_DMA=y - CONFIG_MMC_BCM2835_SDHOST=y - CONFIG_MMC_SDHCI=y - CONFIG_MMC_SDHCI_PLTFM=y -+CONFIG_MMC_SDHCI_IPROC=y - CONFIG_MMC_SPI=m - CONFIG_LEDS_CLASS=y - CONFIG_LEDS_GPIO=y diff --git a/target/linux/brcm2708/patches-4.19/950-0689-Revert-configs-arm64-bcm2711-Remove-CONFIG_VIDEO_BCM.patch b/target/linux/brcm2708/patches-4.19/950-0689-Revert-configs-arm64-bcm2711-Remove-CONFIG_VIDEO_BCM.patch new file mode 100644 index 0000000000..1f8d7b581e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0689-Revert-configs-arm64-bcm2711-Remove-CONFIG_VIDEO_BCM.patch @@ -0,0 +1,49 @@ +From c113d9a69caa55d8b0d5bd4bfbb7fdf502565edb Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 1 Jul 2019 12:06:54 +0100 +Subject: [PATCH 689/725] Revert "configs: arm64/bcm2711: Remove + CONFIG_VIDEO_BCM2835" + +This reverts commit 9d1deec93fa8b1b4953ff5e9210349f3c85b9a8d. + +The issues are resolved, so reenable. + +Signed-off-by: Dave Stevenson +--- + arch/arm/configs/bcm2709_defconfig | 2 +- + arch/arm64/configs/bcm2711_defconfig | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -16,11 +16,11 @@ CONFIG_IKCONFIG=m + CONFIG_IKCONFIG_PROC=y + CONFIG_MEMCG=y + CONFIG_BLK_CGROUP=y +-CONFIG_CGROUP_PIDS=y + CONFIG_CGROUP_FREEZER=y + CONFIG_CPUSETS=y + CONFIG_CGROUP_DEVICE=y + CONFIG_CGROUP_CPUACCT=y ++CONFIG_CGROUP_PIDS=y + CONFIG_NAMESPACES=y + CONFIG_USER_NS=y + CONFIG_SCHED_AUTOGROUP=y +--- a/arch/arm64/configs/bcm2711_defconfig ++++ b/arch/arm64/configs/bcm2711_defconfig +@@ -1031,6 +1031,7 @@ CONFIG_USB_G_HID=m + CONFIG_USB_G_WEBCAM=m + CONFIG_MMC=y + CONFIG_MMC_BLOCK_MINORS=32 ++CONFIG_MMC_SDHCI_BCM2711=y + CONFIG_MMC_BCM2835_MMC=y + CONFIG_MMC_BCM2835_DMA=y + CONFIG_MMC_BCM2835_SDHOST=y +@@ -1130,6 +1131,7 @@ CONFIG_FB_TFT_WATTEROTT=m + CONFIG_FB_FLEX=m + CONFIG_FB_TFT_FBTFT_DEVICE=m + CONFIG_SND_BCM2835=m ++CONFIG_VIDEO_BCM2835=m + CONFIG_MAILBOX=y + CONFIG_BCM2835_MBOX=y + # CONFIG_IOMMU_SUPPORT is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0689-overlays-Correct-gpio-fan-gpio-flags-for-4.19.patch b/target/linux/brcm2708/patches-4.19/950-0689-overlays-Correct-gpio-fan-gpio-flags-for-4.19.patch deleted file mode 100644 index ad8eb7aafa..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0689-overlays-Correct-gpio-fan-gpio-flags-for-4.19.patch +++ /dev/null @@ -1,30 +0,0 @@ -From feace5977af2dc38e4b089b52f6915e538cdf9e9 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 3 Jul 2019 20:37:14 +0100 -Subject: [PATCH 689/703] overlays: Correct gpio-fan gpio flags for 4.19 - -The gpio-fan overlay was submitted for the 4.14 kernel where the second -value in the Device Tree gpios declaration was ignored (thanks to an -old-style driver), allowing the fan-control output to be active-high -even though the declaration appears to request it be active-low. -The gpio-fan driver in 4.19 uses GPIO descriptors and honours the -active-low flag that the overlay (accidentally?) supplies. - -Change/correct the flags field to mark the GPIO as active-high. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/gpio-fan-overlay.dts | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/overlays/gpio-fan-overlay.dts -+++ b/arch/arm/boot/dts/overlays/gpio-fan-overlay.dts -@@ -45,7 +45,7 @@ - __overlay__ { - fan0: gpio-fan@0 { - compatible = "gpio-fan"; -- gpios = <&gpio 12 1>; -+ gpios = <&gpio 12 0>; - gpio-fan,speed-map = <0 0>, - <5000 1>; - #cooling-cells = <2>; diff --git a/target/linux/brcm2708/patches-4.19/950-0690-staging-vc-sm-cma-Fix-the-few-remaining-coding-style.patch b/target/linux/brcm2708/patches-4.19/950-0690-staging-vc-sm-cma-Fix-the-few-remaining-coding-style.patch new file mode 100644 index 0000000000..b0ceabeb45 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0690-staging-vc-sm-cma-Fix-the-few-remaining-coding-style.patch @@ -0,0 +1,188 @@ +From c6293ea00d55c0d48fd723da6072212f896a74b1 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 2 Jul 2019 17:19:04 +0100 +Subject: [PATCH 690/725] staging: vc-sm-cma: Fix the few remaining coding + style issues + +Fix a few minor checkpatch complaints to make the driver clean + +Signed-off-by: Dave Stevenson +--- + .../staging/vc04_services/vc-sm-cma/vc_sm.c | 6 +- + .../vc04_services/vc-sm-cma/vc_sm_cma_vchi.c | 128 +++++++++--------- + 2 files changed, 65 insertions(+), 69 deletions(-) + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -325,7 +325,6 @@ static void vc_sm_release_resource(struc + buffer->cookie, buffer->dma_addr); + } + +- + /* Free our buffer. Start by removing it from the list */ + mutex_lock(&sm_state->map_lock); + list_del(&buffer->global_buffer_list); +@@ -1365,7 +1364,8 @@ static int vc_sm_cma_clean_invalid2(unsi + } + + for (i = 0; i < ioparam.op_count; i++) { +- const struct vc_sm_cma_ioctl_clean_invalid_block * const op = block + i; ++ const struct vc_sm_cma_ioctl_clean_invalid_block * const op = ++ block + i; + + if (op->invalidate_mode == VC_SM_CACHE_OP_NOP) + continue; +@@ -1637,8 +1637,6 @@ err_remove_misc_dev: + err_remove_debugfs: + debugfs_remove_recursive(sm_state->dir_root); + vc_sm_cma_vchi_stop(&sm_state->sm_handle); +- +- return; + } + + /* Driver loading. */ +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c +@@ -188,79 +188,77 @@ static int vc_sm_cma_vchi_videocore_io(v + if (svc_use) + vchi_service_release(instance->vchi_handle[0]); + svc_use = 0; +- if (!wait_for_completion_interruptible(&instance->io_cmplt)) { +- vchi_service_use(instance->vchi_handle[0]); +- svc_use = 1; +- +- do { +- /* +- * Get new command and move it to response list +- */ +- mutex_lock(&instance->lock); +- if (list_empty(&instance->cmd_list)) { +- /* no more commands to process */ +- mutex_unlock(&instance->lock); +- break; +- } +- cmd = +- list_first_entry(&instance->cmd_list, +- struct sm_cmd_rsp_blk, +- head); +- list_move(&cmd->head, &instance->rsp_list); +- cmd->sent = 1; +- mutex_unlock(&instance->lock); + +- /* Send the command */ +- status = bcm2835_vchi_msg_queue( +- instance->vchi_handle[0], +- cmd->msg, cmd->length); +- if (status) { +- pr_err("%s: failed to queue message (%d)", +- __func__, status); +- } +- +- /* If no reply is needed then we're done */ +- if (!cmd->wait) { +- mutex_lock(&instance->lock); +- list_del(&cmd->head); +- mutex_unlock(&instance->lock); +- vc_vchi_cmd_delete(instance, cmd); +- continue; +- } +- +- if (status) { +- complete(&cmd->cmplt); +- continue; +- } +- +- } while (1); +- +- while (!vchi_msg_peek(instance->vchi_handle[0], +- (void **)&reply, &reply_len, +- VCHI_FLAGS_NONE)) { +- if (reply->trans_id & 0x80000000) { +- /* Async event or cmd from the VPU */ +- if (instance->vpu_event) +- instance->vpu_event( +- instance, reply, +- reply_len); +- } else { +- vc_sm_cma_vchi_rx_ack(instance, cmd, +- reply, reply_len); +- } ++ if (wait_for_completion_interruptible(&instance->io_cmplt)) ++ continue; + +- vchi_msg_remove(instance->vchi_handle[0]); +- } ++ vchi_service_use(instance->vchi_handle[0]); ++ svc_use = 1; + +- /* Go through the dead list and free them */ ++ do { ++ /* ++ * Get new command and move it to response list ++ */ + mutex_lock(&instance->lock); +- list_for_each_entry_safe(cmd, cmd_tmp, +- &instance->dead_list, head) { ++ if (list_empty(&instance->cmd_list)) { ++ /* no more commands to process */ ++ mutex_unlock(&instance->lock); ++ break; ++ } ++ cmd = list_first_entry(&instance->cmd_list, ++ struct sm_cmd_rsp_blk, head); ++ list_move(&cmd->head, &instance->rsp_list); ++ cmd->sent = 1; ++ mutex_unlock(&instance->lock); ++ ++ /* Send the command */ ++ status = ++ bcm2835_vchi_msg_queue(instance->vchi_handle[0], ++ cmd->msg, cmd->length); ++ if (status) { ++ pr_err("%s: failed to queue message (%d)", ++ __func__, status); ++ } ++ ++ /* If no reply is needed then we're done */ ++ if (!cmd->wait) { ++ mutex_lock(&instance->lock); + list_del(&cmd->head); ++ mutex_unlock(&instance->lock); + vc_vchi_cmd_delete(instance, cmd); ++ continue; + } +- mutex_unlock(&instance->lock); ++ ++ if (status) { ++ complete(&cmd->cmplt); ++ continue; ++ } ++ ++ } while (1); ++ ++ while (!vchi_msg_peek(instance->vchi_handle[0], (void **)&reply, ++ &reply_len, VCHI_FLAGS_NONE)) { ++ if (reply->trans_id & 0x80000000) { ++ /* Async event or cmd from the VPU */ ++ if (instance->vpu_event) ++ instance->vpu_event(instance, reply, ++ reply_len); ++ } else { ++ vc_sm_cma_vchi_rx_ack(instance, cmd, reply, ++ reply_len); ++ } ++ ++ vchi_msg_remove(instance->vchi_handle[0]); ++ } ++ ++ /* Go through the dead list and free them */ ++ mutex_lock(&instance->lock); ++ list_for_each_entry_safe(cmd, cmd_tmp, &instance->dead_list, ++ head) { ++ list_del(&cmd->head); ++ vc_vchi_cmd_delete(instance, cmd); + } ++ mutex_unlock(&instance->lock); + } + + return 0; diff --git a/target/linux/brcm2708/patches-4.19/950-0690-staging-vcsm-cma-Remove-cache-manipulation-ioctl-fro.patch b/target/linux/brcm2708/patches-4.19/950-0690-staging-vcsm-cma-Remove-cache-manipulation-ioctl-fro.patch deleted file mode 100644 index 1918916794..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0690-staging-vcsm-cma-Remove-cache-manipulation-ioctl-fro.patch +++ /dev/null @@ -1,78 +0,0 @@ -From fbcf72909974b3dda42a292013c349647bcfa945 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 25 Jun 2019 00:29:44 +0100 -Subject: [PATCH 690/703] staging: vcsm-cma: Remove cache manipulation ioctl - from ARM64 - -The cache flushing ioctls are used by the Pi3 HEVC hw-assisted -decoder as it needs finer grained flushing control than dma_ops -allow. -These cache calls are not present for ARM64, therefore disable -them. We are not actively supporting 64bit kernels at present, -and the use case of the HEVC decoder is fairly limited. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -1259,6 +1259,7 @@ error: - return ret; - } - -+#ifndef CONFIG_ARM64 - /* Converts VCSM_CACHE_OP_* to an operating function. */ - static void (*cache_op_to_func(const unsigned int cache_op)) - (const void*, const void*) -@@ -1351,6 +1352,7 @@ out: - - return ret; - } -+#endif - - static long vc_sm_cma_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -@@ -1448,6 +1450,7 @@ static long vc_sm_cma_ioctl(struct file - break; - } - -+#ifndef CONFIG_ARM64 - /* - * Flush/Invalidate the cache for a given mapping. - * Blocks must be pinned (i.e. accessed) before this call. -@@ -1455,6 +1458,7 @@ static long vc_sm_cma_ioctl(struct file - case VC_SM_CMA_CMD_CLEAN_INVALID2: - ret = vc_sm_cma_clean_invalid2(cmdnr, arg); - break; -+#endif - - default: - pr_debug("[%s]: cmd %x tgid %u, owner %u\n", __func__, cmdnr, -@@ -1467,6 +1471,7 @@ static long vc_sm_cma_ioctl(struct file - return ret; - } - -+#ifndef CONFIG_ARM64 - #ifdef CONFIG_COMPAT - struct vc_sm_cma_ioctl_clean_invalid2_32 { - u32 op_count; -@@ -1496,14 +1501,17 @@ static long vc_sm_cma_compat_ioctl(struc - } - } - #endif -+#endif - - /* Device operations that we managed in this driver. */ - static const struct file_operations vc_sm_ops = { - .owner = THIS_MODULE, - .unlocked_ioctl = vc_sm_cma_ioctl, -+#ifndef CONFIG_ARM64 - #ifdef CONFIG_COMPAT - .compat_ioctl = vc_sm_cma_compat_ioctl, - #endif -+#endif - .open = vc_sm_cma_open, - .release = vc_sm_cma_release, - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0691-configs-Drop-MMC_SDHCI_BCM2711-from-arm64-bcm2711_de.patch b/target/linux/brcm2708/patches-4.19/950-0691-configs-Drop-MMC_SDHCI_BCM2711-from-arm64-bcm2711_de.patch new file mode 100644 index 0000000000..c508a9004e --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0691-configs-Drop-MMC_SDHCI_BCM2711-from-arm64-bcm2711_de.patch @@ -0,0 +1,23 @@ +From a8d9b98abf93405b56ad420c2337b9c16d443555 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 4 Jul 2019 11:52:43 +0100 +Subject: [PATCH 691/725] configs: Drop MMC_SDHCI_BCM2711 from + arm64/bcm2711_defconfig + +Apparently this is a vestigial setting and should be removed. + +Signed-off-by: Dave Stevenson +--- + arch/arm64/configs/bcm2711_defconfig | 1 - + 1 file changed, 1 deletion(-) + +--- a/arch/arm64/configs/bcm2711_defconfig ++++ b/arch/arm64/configs/bcm2711_defconfig +@@ -1031,7 +1031,6 @@ CONFIG_USB_G_HID=m + CONFIG_USB_G_WEBCAM=m + CONFIG_MMC=y + CONFIG_MMC_BLOCK_MINORS=32 +-CONFIG_MMC_SDHCI_BCM2711=y + CONFIG_MMC_BCM2835_MMC=y + CONFIG_MMC_BCM2835_DMA=y + CONFIG_MMC_BCM2835_SDHOST=y diff --git a/target/linux/brcm2708/patches-4.19/950-0691-staging-vcsm-cma-Rework-to-use-dma-APIs-not-CMA.patch b/target/linux/brcm2708/patches-4.19/950-0691-staging-vcsm-cma-Rework-to-use-dma-APIs-not-CMA.patch deleted file mode 100644 index 84ab727f67..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0691-staging-vcsm-cma-Rework-to-use-dma-APIs-not-CMA.patch +++ /dev/null @@ -1,758 +0,0 @@ -From 6c3a3d85c8877cb506d8a646fea01a97695fab14 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 1 Jul 2019 11:57:25 +0100 -Subject: [PATCH 691/703] staging: vcsm-cma: Rework to use dma APIs, not CMA - -Due to a misunderstanding of the DMA mapping APIs, I made -the wrong decision on how to implement this. - -Rework to use dma_alloc_coherent instead of the CMA -API. This also allows it to be built as a module easily. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/vc-sm-cma/Kconfig | 4 +- - .../staging/vc04_services/vc-sm-cma/Makefile | 2 +- - .../staging/vc04_services/vc-sm-cma/vc_sm.c | 291 ++++++++++-------- - .../staging/vc04_services/vc-sm-cma/vc_sm.h | 13 +- - .../vc04_services/vc-sm-cma/vc_sm_cma.c | 98 ------ - .../vc04_services/vc-sm-cma/vc_sm_cma.h | 39 --- - 6 files changed, 168 insertions(+), 279 deletions(-) - delete mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.c - delete mode 100644 drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.h - ---- a/drivers/staging/vc04_services/vc-sm-cma/Kconfig -+++ b/drivers/staging/vc04_services/vc-sm-cma/Kconfig -@@ -1,6 +1,6 @@ - config BCM_VC_SM_CMA -- bool "VideoCore Shared Memory (CMA) driver" -- depends on BCM2835_VCHIQ && DMA_CMA -+ tristate "VideoCore Shared Memory (CMA) driver" -+ depends on BCM2835_VCHIQ - select RBTREE - select DMA_SHARED_BUFFER - help ---- a/drivers/staging/vc04_services/vc-sm-cma/Makefile -+++ b/drivers/staging/vc04_services/vc-sm-cma/Makefile -@@ -3,6 +3,6 @@ ccflags-y += -Idrivers/staging/vc04_serv - ccflags-y += -D__VCCOREVER__=0 - - vc-sm-cma-$(CONFIG_BCM_VC_SM_CMA) := \ -- vc_sm.o vc_sm_cma_vchi.o vc_sm_cma.o -+ vc_sm.o vc_sm_cma_vchi.o - - obj-$(CONFIG_BCM_VC_SM_CMA) += vc-sm-cma.o ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -6,8 +6,8 @@ - * Dave Stevenson - * - * Based on vmcs_sm driver from Broadcom Corporation for some API, -- * and taking some code for CMA/dmabuf handling from the Android Ion -- * driver (Google/Linaro). -+ * and taking some code for buffer allocation and dmabuf handling from -+ * videobuf2. - * - * - * This driver has 3 main uses: -@@ -52,7 +52,6 @@ - #include "vc_sm_cma_vchi.h" - - #include "vc_sm.h" --#include "vc_sm_cma.h" - #include "vc_sm_knl.h" - #include - -@@ -89,7 +88,6 @@ struct sm_state_t { - struct miscdevice misc_dev; - - struct sm_instance *sm_handle; /* Handle for videocore service. */ -- struct cma *cma_heap; - - spinlock_t kernelid_map_lock; /* Spinlock protecting kernelid_map */ - struct idr kernelid_map; -@@ -110,8 +108,9 @@ struct sm_state_t { - - struct vc_sm_dma_buf_attachment { - struct device *dev; -- struct sg_table *table; -+ struct sg_table sg_table; - struct list_head list; -+ enum dma_data_direction dma_dir; - }; - - /* ---- Private Variables ----------------------------------------------- */ -@@ -202,9 +201,10 @@ static int vc_sm_cma_global_state_show(s - resource->import.attach); - seq_printf(s, " SGT %p\n", - resource->import.sgt); -+ } else { -+ seq_printf(s, " SGT %p\n", -+ resource->alloc.sg_table); - } -- seq_printf(s, " SG_TABLE %p\n", -- resource->sg_table); - seq_printf(s, " DMA_ADDR %pad\n", - &resource->dma_addr); - seq_printf(s, " VC_HANDLE %08x\n", -@@ -296,8 +296,9 @@ static void vc_sm_vpu_free(struct vc_sm_ - */ - static void vc_sm_release_resource(struct vc_sm_buffer *buffer) - { -- pr_debug("[%s]: buffer %p (name %s, size %zu)\n", -- __func__, buffer, buffer->name, buffer->size); -+ pr_debug("[%s]: buffer %p (name %s, size %zu), imported %u\n", -+ __func__, buffer, buffer->name, buffer->size, -+ buffer->imported); - - if (buffer->vc_handle) { - /* We've sent the unmap request but not had the response. */ -@@ -313,8 +314,6 @@ static void vc_sm_release_resource(struc - - /* Release the allocation (whether imported dmabuf or CMA allocation) */ - if (buffer->imported) { -- pr_debug("%s: Release imported dmabuf %p\n", __func__, -- buffer->import.dma_buf); - if (buffer->import.dma_buf) - dma_buf_put(buffer->import.dma_buf); - else -@@ -322,16 +321,8 @@ static void vc_sm_release_resource(struc - __func__, buffer); - buffer->import.dma_buf = NULL; - } else { -- if (buffer->sg_table) { -- /* Our own allocation that we need to dma_unmap_sg */ -- dma_unmap_sg(&sm_state->pdev->dev, -- buffer->sg_table->sgl, -- buffer->sg_table->nents, -- DMA_BIDIRECTIONAL); -- } -- pr_debug("%s: Release our allocation\n", __func__); -- vc_sm_cma_buffer_free(&buffer->alloc); -- pr_debug("%s: Release our allocation - done\n", __func__); -+ dma_free_coherent(&sm_state->pdev->dev, buffer->size, -+ buffer->cookie, buffer->dma_addr); - } - - -@@ -371,38 +362,6 @@ static struct vc_sm_privdata_t *vc_sm_cm - return file_data; - } - --static struct sg_table *dup_sg_table(struct sg_table *table) --{ -- struct sg_table *new_table; -- int ret, i; -- struct scatterlist *sg, *new_sg; -- -- new_table = kzalloc(sizeof(*new_table), GFP_KERNEL); -- if (!new_table) -- return ERR_PTR(-ENOMEM); -- -- ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL); -- if (ret) { -- kfree(new_table); -- return ERR_PTR(ret); -- } -- -- new_sg = new_table->sgl; -- for_each_sg(table->sgl, sg, table->nents, i) { -- memcpy(new_sg, sg, sizeof(*sg)); -- sg->dma_address = 0; -- new_sg = sg_next(new_sg); -- } -- -- return new_table; --} -- --static void free_duped_table(struct sg_table *table) --{ -- sg_free_table(table); -- kfree(table); --} -- - /* Dma buf operations for use with our own allocations */ - - static int vc_sm_dma_buf_attach(struct dma_buf *dmabuf, -@@ -410,28 +369,45 @@ static int vc_sm_dma_buf_attach(struct d - - { - struct vc_sm_dma_buf_attachment *a; -- struct sg_table *table; -+ struct sg_table *sgt; - struct vc_sm_buffer *buf = dmabuf->priv; -+ struct scatterlist *rd, *wr; -+ int ret, i; - - a = kzalloc(sizeof(*a), GFP_KERNEL); - if (!a) - return -ENOMEM; - -- table = dup_sg_table(buf->sg_table); -- if (IS_ERR(table)) { -+ pr_debug("%s dmabuf %p attachment %p\n", __func__, dmabuf, attachment); -+ -+ mutex_lock(&buf->lock); -+ -+ INIT_LIST_HEAD(&a->list); -+ -+ sgt = &a->sg_table; -+ -+ /* Copy the buf->base_sgt scatter list to the attachment, as we can't -+ * map the same scatter list to multiple attachments at the same time. -+ */ -+ ret = sg_alloc_table(sgt, buf->alloc.sg_table->orig_nents, GFP_KERNEL); -+ if (ret) { - kfree(a); -- return PTR_ERR(table); -+ return -ENOMEM; - } - -- a->table = table; -- INIT_LIST_HEAD(&a->list); -+ rd = buf->alloc.sg_table->sgl; -+ wr = sgt->sgl; -+ for (i = 0; i < sgt->orig_nents; ++i) { -+ sg_set_page(wr, sg_page(rd), rd->length, rd->offset); -+ rd = sg_next(rd); -+ wr = sg_next(wr); -+ } - -+ a->dma_dir = DMA_NONE; - attachment->priv = a; - -- mutex_lock(&buf->lock); - list_add(&a->list, &buf->attachments); - mutex_unlock(&buf->lock); -- pr_debug("%s dmabuf %p attachment %p\n", __func__, dmabuf, attachment); - - return 0; - } -@@ -441,9 +417,20 @@ static void vc_sm_dma_buf_detach(struct - { - struct vc_sm_dma_buf_attachment *a = attachment->priv; - struct vc_sm_buffer *buf = dmabuf->priv; -+ struct sg_table *sgt; - - pr_debug("%s dmabuf %p attachment %p\n", __func__, dmabuf, attachment); -- free_duped_table(a->table); -+ if (!a) -+ return; -+ -+ sgt = &a->sg_table; -+ -+ /* release the scatterlist cache */ -+ if (a->dma_dir != DMA_NONE) -+ dma_unmap_sg(attachment->dev, sgt->sgl, sgt->orig_nents, -+ a->dma_dir); -+ sg_free_table(sgt); -+ - mutex_lock(&buf->lock); - list_del(&a->list); - mutex_unlock(&buf->lock); -@@ -455,13 +442,38 @@ static struct sg_table *vc_sm_map_dma_bu - enum dma_data_direction direction) - { - struct vc_sm_dma_buf_attachment *a = attachment->priv; -+ /* stealing dmabuf mutex to serialize map/unmap operations */ -+ struct mutex *lock = &attachment->dmabuf->lock; - struct sg_table *table; - -- table = a->table; -+ mutex_lock(lock); -+ pr_debug("%s attachment %p\n", __func__, attachment); -+ table = &a->sg_table; -+ -+ /* return previously mapped sg table */ -+ if (a->dma_dir == direction) { -+ mutex_unlock(lock); -+ return table; -+ } -+ -+ /* release any previous cache */ -+ if (a->dma_dir != DMA_NONE) { -+ dma_unmap_sg(attachment->dev, table->sgl, table->orig_nents, -+ a->dma_dir); -+ a->dma_dir = DMA_NONE; -+ } -+ -+ /* mapping to the client with new direction */ -+ table->nents = dma_map_sg(attachment->dev, table->sgl, -+ table->orig_nents, direction); -+ if (!table->nents) { -+ pr_err("failed to map scatterlist\n"); -+ mutex_unlock(lock); -+ return ERR_PTR(-EIO); -+ } - -- if (!dma_map_sg(attachment->dev, table->sgl, table->nents, -- direction)) -- return ERR_PTR(-ENOMEM); -+ a->dma_dir = direction; -+ mutex_unlock(lock); - - pr_debug("%s attachment %p\n", __func__, attachment); - return table; -@@ -478,41 +490,26 @@ static void vc_sm_unmap_dma_buf(struct d - static int vc_sm_dmabuf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) - { - struct vc_sm_buffer *buf = dmabuf->priv; -- struct sg_table *table = buf->sg_table; -- unsigned long addr = vma->vm_start; -- unsigned long offset = vma->vm_pgoff * PAGE_SIZE; -- struct scatterlist *sg; -- int i; -- int ret = 0; -+ int ret; - - pr_debug("%s dmabuf %p, buf %p, vm_start %08lX\n", __func__, dmabuf, -- buf, addr); -+ buf, vma->vm_start); - - mutex_lock(&buf->lock); - - /* now map it to userspace */ -- for_each_sg(table->sgl, sg, table->nents, i) { -- struct page *page = sg_page(sg); -- unsigned long remainder = vma->vm_end - addr; -- unsigned long len = sg->length; -+ vma->vm_pgoff = 0; - -- if (offset >= sg->length) { -- offset -= sg->length; -- continue; -- } else if (offset) { -- page += offset / PAGE_SIZE; -- len = sg->length - offset; -- offset = 0; -- } -- len = min(len, remainder); -- ret = remap_pfn_range(vma, addr, page_to_pfn(page), len, -- vma->vm_page_prot); -- if (ret) -- break; -- addr += len; -- if (addr >= vma->vm_end) -- break; -+ ret = dma_mmap_coherent(&sm_state->pdev->dev, vma, buf->cookie, -+ buf->dma_addr, buf->size); -+ -+ if (ret) { -+ pr_err("Remapping memory failed, error: %d\n", ret); -+ return ret; - } -+ -+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; -+ - mutex_unlock(&buf->lock); - - if (ret) -@@ -570,8 +567,8 @@ static int vc_sm_dma_buf_begin_cpu_acces - mutex_lock(&buf->lock); - - list_for_each_entry(a, &buf->attachments, list) { -- dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents, -- direction); -+ dma_sync_sg_for_cpu(a->dev, a->sg_table.sgl, -+ a->sg_table.nents, direction); - } - mutex_unlock(&buf->lock); - -@@ -593,8 +590,8 @@ static int vc_sm_dma_buf_end_cpu_access( - mutex_lock(&buf->lock); - - list_for_each_entry(a, &buf->attachments, list) { -- dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents, -- direction); -+ dma_sync_sg_for_device(a->dev, a->sg_table.sgl, -+ a->sg_table.nents, direction); - } - mutex_unlock(&buf->lock); - -@@ -625,7 +622,9 @@ static const struct dma_buf_ops dma_buf_ - .map = vc_sm_dma_buf_kmap, - .unmap = vc_sm_dma_buf_kunmap, - }; -+ - /* Dma_buf operations for chaining through to an imported dma_buf */ -+ - static - int vc_sm_import_dma_buf_attach(struct dma_buf *dmabuf, - struct dma_buf_attachment *attachment) -@@ -819,7 +818,7 @@ vc_sm_cma_import_dmabuf_internal(struct - - import.type = VC_SM_ALLOC_NON_CACHED; - dma_addr = sg_dma_address(sgt->sgl); -- import.addr = (uint32_t)dma_addr; -+ import.addr = (u32)dma_addr; - if ((import.addr & 0xC0000000) != 0xC0000000) { - pr_err("%s: Expecting an uncached alias for dma_addr %pad\n", - __func__, &dma_addr); -@@ -911,11 +910,12 @@ error: - return ret; - } - --static int vc_sm_cma_vpu_alloc(u32 size, uint32_t align, const char *name, -+static int vc_sm_cma_vpu_alloc(u32 size, u32 align, const char *name, - u32 mem_handle, struct vc_sm_buffer **ret_buffer) - { - DEFINE_DMA_BUF_EXPORT_INFO(exp_info); - struct vc_sm_buffer *buffer = NULL; -+ struct sg_table *sgt; - int aligned_size; - int ret = 0; - -@@ -938,23 +938,34 @@ static int vc_sm_cma_vpu_alloc(u32 size, - */ - mutex_lock(&buffer->lock); - -- if (vc_sm_cma_buffer_allocate(sm_state->cma_heap, &buffer->alloc, -- aligned_size)) { -- pr_err("[%s]: cma alloc of %d bytes failed\n", -+ buffer->cookie = dma_alloc_coherent(&sm_state->pdev->dev, -+ aligned_size, &buffer->dma_addr, -+ GFP_KERNEL); -+ if (!buffer->cookie) { -+ pr_err("[%s]: dma_alloc_coherent alloc of %d bytes failed\n", - __func__, aligned_size); - ret = -ENOMEM; - goto error; - } -- buffer->sg_table = buffer->alloc.sg_table; - -- pr_debug("[%s]: cma alloc of %d bytes success\n", -+ pr_debug("[%s]: alloc of %d bytes success\n", - __func__, aligned_size); - -- if (dma_map_sg(&sm_state->pdev->dev, buffer->sg_table->sgl, -- buffer->sg_table->nents, DMA_BIDIRECTIONAL) <= 0) { -- pr_err("[%s]: dma_map_sg failed\n", __func__); -+ sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); -+ if (!sgt) { -+ ret = -ENOMEM; -+ goto error; -+ } -+ -+ ret = dma_get_sgtable(&sm_state->pdev->dev, sgt, buffer->cookie, -+ buffer->dma_addr, buffer->size); -+ if (ret < 0) { -+ pr_err("failed to get scatterlist from DMA API\n"); -+ kfree(sgt); -+ ret = -ENOMEM; - goto error; - } -+ buffer->alloc.sg_table = sgt; - - INIT_LIST_HEAD(&buffer->attachments); - -@@ -971,10 +982,10 @@ static int vc_sm_cma_vpu_alloc(u32 size, - ret = PTR_ERR(buffer->dma_buf); - goto error; - } -- buffer->dma_addr = (uint32_t)sg_dma_address(buffer->sg_table->sgl); -+ buffer->dma_addr = (u32)sg_dma_address(buffer->alloc.sg_table->sgl); - if ((buffer->dma_addr & 0xC0000000) != 0xC0000000) { -- pr_err("%s: Expecting an uncached alias for dma_addr %pad\n", -- __func__, &buffer->dma_addr); -+ pr_warn_once("%s: Expecting an uncached alias for dma_addr %pad\n", -+ __func__, &buffer->dma_addr); - buffer->dma_addr |= 0xC0000000; - } - buffer->private = sm_state->vpu_allocs; -@@ -1145,6 +1156,7 @@ int vc_sm_cma_ioctl_alloc(struct vc_sm_p - struct vc_sm_import import = { 0 }; - struct vc_sm_import_result result = { 0 }; - struct dma_buf *dmabuf = NULL; -+ struct sg_table *sgt; - int aligned_size; - int ret = 0; - int status; -@@ -1162,18 +1174,13 @@ int vc_sm_cma_ioctl_alloc(struct vc_sm_p - goto error; - } - -- if (vc_sm_cma_buffer_allocate(sm_state->cma_heap, &buffer->alloc, -- aligned_size)) { -- pr_err("[%s]: cma alloc of %d bytes failed\n", -+ buffer->cookie = dma_alloc_coherent(&sm_state->pdev->dev, -+ aligned_size, -+ &buffer->dma_addr, -+ GFP_KERNEL); -+ if (!buffer->cookie) { -+ pr_err("[%s]: dma_alloc_coherent alloc of %d bytes failed\n", - __func__, aligned_size); -- kfree(buffer); -- return -ENOMEM; -- } -- buffer->sg_table = buffer->alloc.sg_table; -- -- if (dma_map_sg(&sm_state->pdev->dev, buffer->sg_table->sgl, -- buffer->sg_table->nents, DMA_BIDIRECTIONAL) <= 0) { -- pr_err("[%s]: dma_map_sg failed\n", __func__); - ret = -ENOMEM; - goto error; - } -@@ -1204,7 +1211,7 @@ int vc_sm_cma_ioctl_alloc(struct vc_sm_p - } - buffer->dma_buf = dmabuf; - -- import.addr = (uint32_t)sg_dma_address(buffer->sg_table->sgl); -+ import.addr = buffer->dma_addr; - import.size = aligned_size; - import.kernel_id = get_kernel_id(buffer); - -@@ -1229,10 +1236,25 @@ int vc_sm_cma_ioctl_alloc(struct vc_sm_p - buffer->private = private; - buffer->vc_handle = result.res_handle; - buffer->size = import.size; -- buffer->dma_addr = import.addr; - buffer->vpu_state = VPU_MAPPED; - buffer->kernel_id = import.kernel_id; -- //buffer->res_cached = ioparam->cached; -+ -+ sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); -+ if (!sgt) { -+ ret = -ENOMEM; -+ goto error; -+ } -+ -+ ret = dma_get_sgtable(&sm_state->pdev->dev, sgt, buffer->cookie, -+ buffer->dma_addr, buffer->size); -+ if (ret < 0) { -+ /* FIXME: error handling */ -+ pr_err("failed to get scatterlist from DMA API\n"); -+ kfree(sgt); -+ ret = -ENOMEM; -+ goto error; -+ } -+ buffer->alloc.sg_table = sgt; - - fd = dma_buf_fd(dmabuf, O_CLOEXEC); - if (fd < 0) -@@ -1250,11 +1272,19 @@ int vc_sm_cma_ioctl_alloc(struct vc_sm_p - return 0; - - error: -- if (buffer) { -- pr_err("[%s]: something failed - cleanup. ret %d\n", __func__, -- ret); -+ pr_err("[%s]: something failed - cleanup. ret %d\n", __func__, ret); - -+ if (dmabuf) { -+ /* dmabuf has been exported, therefore allow dmabuf cleanup to -+ * deal with this -+ */ - dma_buf_put(dmabuf); -+ } else { -+ /* No dmabuf, therefore just free the buffer here */ -+ if (buffer->cookie) -+ dma_free_coherent(&sm_state->pdev->dev, buffer->size, -+ buffer->cookie, buffer->dma_addr); -+ kfree(buffer); - } - return ret; - } -@@ -1527,13 +1557,6 @@ static void vc_sm_connected_init(void) - - pr_info("[%s]: start\n", __func__); - -- vc_sm_cma_add_heaps(&sm_state->cma_heap); -- if (!sm_state->cma_heap) { -- pr_err("[%s]: failed to initialise CMA heap\n", -- __func__); -- return; -- } -- - /* - * Initialize and create a VCHI connection for the shared memory service - * running on videocore. ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.h -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.h -@@ -21,8 +21,6 @@ - #include - #include - --#include "vc_sm_cma.h" -- - #define VC_SM_MAX_NAME_LEN 32 - - enum vc_sm_vpu_mapping_state { -@@ -31,6 +29,12 @@ enum vc_sm_vpu_mapping_state { - VPU_UNMAPPING - }; - -+struct vc_sm_alloc_data { -+ unsigned long num_pages; -+ void *priv_virt; -+ struct sg_table *sg_table; -+}; -+ - struct vc_sm_imported { - struct dma_buf *dma_buf; - struct dma_buf_attachment *attach; -@@ -56,8 +60,6 @@ struct vc_sm_buffer { - int in_use:1; /* Kernel is still using this resource */ - int imported:1; /* Imported dmabuf */ - -- struct sg_table *sg_table; -- - enum vc_sm_vpu_mapping_state vpu_state; - u32 vc_handle; /* VideoCore handle for this buffer */ - int vpu_allocated; /* -@@ -69,11 +71,12 @@ struct vc_sm_buffer { - /* DMABUF related fields */ - struct dma_buf *dma_buf; - dma_addr_t dma_addr; -+ void *cookie; - - struct vc_sm_privdata_t *private; - - union { -- struct vc_sm_cma_alloc_data alloc; -+ struct vc_sm_alloc_data alloc; - struct vc_sm_imported import; - }; - }; ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.c -+++ /dev/null -@@ -1,98 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * VideoCore Shared Memory CMA allocator -- * -- * Copyright: 2018, Raspberry Pi (Trading) Ltd -- * -- * Based on the Android ION allocator -- * Copyright (C) Linaro 2012 -- * Author: for ST-Ericsson. -- * -- */ -- --#include --#include --#include --#include --#include -- --#include "vc_sm_cma.h" -- --/* CMA heap operations functions */ --int vc_sm_cma_buffer_allocate(struct cma *cma_heap, -- struct vc_sm_cma_alloc_data *buffer, -- unsigned long len) --{ -- /* len should already be page aligned */ -- unsigned long num_pages = len / PAGE_SIZE; -- struct sg_table *table; -- struct page *pages; -- int ret; -- -- pages = cma_alloc(cma_heap, num_pages, 0, GFP_KERNEL); -- if (!pages) -- return -ENOMEM; -- -- table = kmalloc(sizeof(*table), GFP_KERNEL); -- if (!table) -- goto err; -- -- ret = sg_alloc_table(table, 1, GFP_KERNEL); -- if (ret) -- goto free_mem; -- -- sg_set_page(table->sgl, pages, len, 0); -- -- buffer->priv_virt = pages; -- buffer->sg_table = table; -- buffer->cma_heap = cma_heap; -- buffer->num_pages = num_pages; -- return 0; -- --free_mem: -- kfree(table); --err: -- cma_release(cma_heap, pages, num_pages); -- return -ENOMEM; --} -- --void vc_sm_cma_buffer_free(struct vc_sm_cma_alloc_data *buffer) --{ -- struct cma *cma_heap = buffer->cma_heap; -- struct page *pages = buffer->priv_virt; -- -- /* release memory */ -- if (cma_heap) -- cma_release(cma_heap, pages, buffer->num_pages); -- -- /* release sg table */ -- if (buffer->sg_table) { -- sg_free_table(buffer->sg_table); -- kfree(buffer->sg_table); -- buffer->sg_table = NULL; -- } --} -- --int __vc_sm_cma_add_heaps(struct cma *cma, void *priv) --{ -- struct cma **heap = (struct cma **)priv; -- const char *name = cma_get_name(cma); -- -- if (!(*heap)) { -- phys_addr_t phys_addr = cma_get_base(cma); -- -- pr_debug("%s: Adding cma heap %s (start %pap, size %lu) for use by vcsm\n", -- __func__, name, &phys_addr, cma_get_size(cma)); -- *heap = cma; -- } else { -- pr_err("%s: Ignoring heap %s as already set\n", -- __func__, name); -- } -- -- return 0; --} -- --void vc_sm_cma_add_heaps(struct cma **cma_heap) --{ -- cma_for_each_area(__vc_sm_cma_add_heaps, cma_heap); --} ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.h -+++ /dev/null -@@ -1,39 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ -- --/* -- * VideoCore Shared Memory CMA allocator -- * -- * Copyright: 2018, Raspberry Pi (Trading) Ltd -- * -- * Based on the Android ION allocator -- * Copyright (C) Linaro 2012 -- * Author: for ST-Ericsson. -- * -- * This software is licensed under the terms of the GNU General Public -- * License version 2, as published by the Free Software Foundation, and -- * may be copied, distributed, and modified under those terms. -- * -- * 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 VC_SM_CMA_H --#define VC_SM_CMA_H -- --struct vc_sm_cma_alloc_data { -- struct cma *cma_heap; -- unsigned long num_pages; -- void *priv_virt; -- struct sg_table *sg_table; --}; -- --int vc_sm_cma_buffer_allocate(struct cma *cma_heap, -- struct vc_sm_cma_alloc_data *buffer, -- unsigned long len); --void vc_sm_cma_buffer_free(struct vc_sm_cma_alloc_data *buffer); -- --void vc_sm_cma_add_heaps(struct cma **cma_heap); -- --#endif diff --git a/target/linux/brcm2708/patches-4.19/950-0692-Revert-configs-Drop-V4L2-camera-and-codec-drivers-fr.patch b/target/linux/brcm2708/patches-4.19/950-0692-Revert-configs-Drop-V4L2-camera-and-codec-drivers-fr.patch deleted file mode 100644 index 39c7e5505c..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0692-Revert-configs-Drop-V4L2-camera-and-codec-drivers-fr.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 5268102a3b9f7fc36e18e4cc913f42218a578487 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 1 Jul 2019 12:00:27 +0100 -Subject: [PATCH 692/703] Revert "configs: Drop V4L2 camera and codec drivers - from bcmrpi3_defconfig" - -This reverts commit e8a66b4f610b3a20bae8f706256d230135916c26. - -The issues are now resolved. - -Signed-off-by: Dave Stevenson ---- - arch/arm64/configs/bcmrpi3_defconfig | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/arch/arm64/configs/bcmrpi3_defconfig -+++ b/arch/arm64/configs/bcmrpi3_defconfig -@@ -1086,6 +1086,8 @@ CONFIG_FB_TFT_WATTEROTT=m - CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_SND_BCM2835=m -+CONFIG_VIDEO_BCM2835=m -+CONFIG_VIDEO_CODEC_BCM2835=m - CONFIG_MAILBOX=y - CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0692-Revert-media-vb2-Allow-reqbufs-0-with-in-use-MMAP-bu.patch b/target/linux/brcm2708/patches-4.19/950-0692-Revert-media-vb2-Allow-reqbufs-0-with-in-use-MMAP-bu.patch new file mode 100644 index 0000000000..bbe776f354 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0692-Revert-media-vb2-Allow-reqbufs-0-with-in-use-MMAP-bu.patch @@ -0,0 +1,55 @@ +From 2a099853599054a17621463365f7bd48223e0e4c Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 28 Jun 2019 11:30:49 +0100 +Subject: [PATCH 692/725] Revert "media: vb2: Allow reqbufs(0) with "in use" + MMAP buffers" + +This reverts commit a2c73e18c1f657de6d654f51effa0a94863abbd8. +An alternative version was accepted upstream. Revert this patch to +apply that one. + +Signed-off-by: Dave Stevenson +--- + .../media/common/videobuf2/videobuf2-core.c | 23 +++++++++++++++++++ + 1 file changed, 23 insertions(+) + +--- a/drivers/media/common/videobuf2/videobuf2-core.c ++++ b/drivers/media/common/videobuf2/videobuf2-core.c +@@ -554,6 +554,20 @@ bool vb2_buffer_in_use(struct vb2_queue + } + EXPORT_SYMBOL(vb2_buffer_in_use); + ++/* ++ * __buffers_in_use() - return true if any buffers on the queue are in use and ++ * the queue cannot be freed (by the means of REQBUFS(0)) call ++ */ ++static bool __buffers_in_use(struct vb2_queue *q) ++{ ++ unsigned int buffer; ++ for (buffer = 0; buffer < q->num_buffers; ++buffer) { ++ if (vb2_buffer_in_use(q, q->bufs[buffer])) ++ return true; ++ } ++ return false; ++} ++ + void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb) + { + call_void_bufop(q, fill_user_buffer, q->bufs[index], pb); +@@ -665,7 +679,16 @@ int vb2_core_reqbufs(struct vb2_queue *q + + if (*count == 0 || q->num_buffers != 0 || + (q->memory != VB2_MEMORY_UNKNOWN && q->memory != memory)) { ++ /* ++ * We already have buffers allocated, so first check if they ++ * are not in use and can be freed. ++ */ + mutex_lock(&q->mmap_lock); ++ if (q->memory == VB2_MEMORY_MMAP && __buffers_in_use(q)) { ++ mutex_unlock(&q->mmap_lock); ++ dprintk(1, "memory in use, cannot free\n"); ++ return -EBUSY; ++ } + + /* + * Call queue_cancel to clean up any buffers in the PREPARED or diff --git a/target/linux/brcm2708/patches-4.19/950-0693-Revert-configs-arm64-bcm2711-Remove-CONFIG_VIDEO_BCM.patch b/target/linux/brcm2708/patches-4.19/950-0693-Revert-configs-arm64-bcm2711-Remove-CONFIG_VIDEO_BCM.patch deleted file mode 100644 index af326ce9b0..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0693-Revert-configs-arm64-bcm2711-Remove-CONFIG_VIDEO_BCM.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0e02c0b0f706a76e117298e7d4c6b730eeeed80c Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 1 Jul 2019 12:06:54 +0100 -Subject: [PATCH 693/703] Revert "configs: arm64/bcm2711: Remove - CONFIG_VIDEO_BCM2835" - -This reverts commit 9d1deec93fa8b1b4953ff5e9210349f3c85b9a8d. - -The issues are resolved, so reenable. - -Signed-off-by: Dave Stevenson ---- - arch/arm/configs/bcm2709_defconfig | 2 +- - arch/arm64/configs/bcm2711_defconfig | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -16,11 +16,11 @@ CONFIG_IKCONFIG=m - CONFIG_IKCONFIG_PROC=y - CONFIG_MEMCG=y - CONFIG_BLK_CGROUP=y --CONFIG_CGROUP_PIDS=y - CONFIG_CGROUP_FREEZER=y - CONFIG_CPUSETS=y - CONFIG_CGROUP_DEVICE=y - CONFIG_CGROUP_CPUACCT=y -+CONFIG_CGROUP_PIDS=y - CONFIG_NAMESPACES=y - CONFIG_USER_NS=y - CONFIG_SCHED_AUTOGROUP=y ---- a/arch/arm64/configs/bcm2711_defconfig -+++ b/arch/arm64/configs/bcm2711_defconfig -@@ -1031,6 +1031,7 @@ CONFIG_USB_G_HID=m - CONFIG_USB_G_WEBCAM=m - CONFIG_MMC=y - CONFIG_MMC_BLOCK_MINORS=32 -+CONFIG_MMC_SDHCI_BCM2711=y - CONFIG_MMC_BCM2835_MMC=y - CONFIG_MMC_BCM2835_DMA=y - CONFIG_MMC_BCM2835_SDHOST=y -@@ -1130,6 +1131,7 @@ CONFIG_FB_TFT_WATTEROTT=m - CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_SND_BCM2835=m -+CONFIG_VIDEO_BCM2835=m - CONFIG_MAILBOX=y - CONFIG_BCM2835_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set diff --git a/target/linux/brcm2708/patches-4.19/950-0693-media-videodev2.h-add-new-capabilities-for-buffer-ty.patch b/target/linux/brcm2708/patches-4.19/950-0693-media-videodev2.h-add-new-capabilities-for-buffer-ty.patch new file mode 100644 index 0000000000..c44cff399b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0693-media-videodev2.h-add-new-capabilities-for-buffer-ty.patch @@ -0,0 +1,136 @@ +From 237e15f3caec01b144b2409829a731b734972539 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Thu, 23 Aug 2018 09:56:22 -0400 +Subject: [PATCH 693/725] media: videodev2.h: add new capabilities for buffer + types + +Upstream commit f35f5d72e70e6b91389eb98fcabf43b79f40587f + +VIDIOC_REQBUFS and VIDIOC_CREATE_BUFFERS will return capabilities +telling userspace what the given buffer type is capable of. + +Signed-off-by: Hans Verkuil +Reviewed-by: Tomasz Figa +Acked-by: Sakari Ailus +Signed-off-by: Mauro Carvalho Chehab +--- + .../media/uapi/v4l/vidioc-create-bufs.rst | 14 ++++++- + .../media/uapi/v4l/vidioc-reqbufs.rst | 42 ++++++++++++++++++- + include/uapi/linux/videodev2.h | 13 +++++- + 3 files changed, 65 insertions(+), 4 deletions(-) + +--- a/Documentation/media/uapi/v4l/vidioc-create-bufs.rst ++++ b/Documentation/media/uapi/v4l/vidioc-create-bufs.rst +@@ -102,7 +102,19 @@ than the number requested. + - ``format`` + - Filled in by the application, preserved by the driver. + * - __u32 +- - ``reserved``\ [8] ++ - ``capabilities`` ++ - Set by the driver. If 0, then the driver doesn't support ++ capabilities. In that case all you know is that the driver is ++ guaranteed to support ``V4L2_MEMORY_MMAP`` and *might* support ++ other :c:type:`v4l2_memory` types. It will not support any others ++ capabilities. See :ref:`here ` for a list of the ++ capabilities. ++ ++ If you want to just query the capabilities without making any ++ other changes, then set ``count`` to 0, ``memory`` to ++ ``V4L2_MEMORY_MMAP`` and ``format.type`` to the buffer type. ++ * - __u32 ++ - ``reserved``\ [7] + - A place holder for future extensions. Drivers and applications + must set the array to zero. + +--- a/Documentation/media/uapi/v4l/vidioc-reqbufs.rst ++++ b/Documentation/media/uapi/v4l/vidioc-reqbufs.rst +@@ -88,10 +88,50 @@ any DMA in progress, an implicit + ``V4L2_MEMORY_DMABUF`` or ``V4L2_MEMORY_USERPTR``. See + :c:type:`v4l2_memory`. + * - __u32 +- - ``reserved``\ [2] ++ - ``capabilities`` ++ - Set by the driver. If 0, then the driver doesn't support ++ capabilities. In that case all you know is that the driver is ++ guaranteed to support ``V4L2_MEMORY_MMAP`` and *might* support ++ other :c:type:`v4l2_memory` types. It will not support any others ++ capabilities. ++ ++ If you want to query the capabilities with a minimum of side-effects, ++ then this can be called with ``count`` set to 0, ``memory`` set to ++ ``V4L2_MEMORY_MMAP`` and ``type`` set to the buffer type. This will ++ free any previously allocated buffers, so this is typically something ++ that will be done at the start of the application. ++ * - __u32 ++ - ``reserved``\ [1] + - A place holder for future extensions. Drivers and applications + must set the array to zero. + ++.. tabularcolumns:: |p{6.1cm}|p{2.2cm}|p{8.7cm}| ++ ++.. _v4l2-buf-capabilities: ++.. _V4L2-BUF-CAP-SUPPORTS-MMAP: ++.. _V4L2-BUF-CAP-SUPPORTS-USERPTR: ++.. _V4L2-BUF-CAP-SUPPORTS-DMABUF: ++.. _V4L2-BUF-CAP-SUPPORTS-REQUESTS: ++ ++.. cssclass:: longtable ++ ++.. flat-table:: V4L2 Buffer Capabilities Flags ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 3 1 4 ++ ++ * - ``V4L2_BUF_CAP_SUPPORTS_MMAP`` ++ - 0x00000001 ++ - This buffer type supports the ``V4L2_MEMORY_MMAP`` streaming mode. ++ * - ``V4L2_BUF_CAP_SUPPORTS_USERPTR`` ++ - 0x00000002 ++ - This buffer type supports the ``V4L2_MEMORY_USERPTR`` streaming mode. ++ * - ``V4L2_BUF_CAP_SUPPORTS_DMABUF`` ++ - 0x00000004 ++ - This buffer type supports the ``V4L2_MEMORY_DMABUF`` streaming mode. ++ * - ``V4L2_BUF_CAP_SUPPORTS_REQUESTS`` ++ - 0x00000008 ++ - This buffer type supports :ref:`requests `. + + Return Value + ============ +--- a/include/uapi/linux/videodev2.h ++++ b/include/uapi/linux/videodev2.h +@@ -872,9 +872,16 @@ struct v4l2_requestbuffers { + __u32 count; + __u32 type; /* enum v4l2_buf_type */ + __u32 memory; /* enum v4l2_memory */ +- __u32 reserved[2]; ++ __u32 capabilities; ++ __u32 reserved[1]; + }; + ++/* capabilities for struct v4l2_requestbuffers and v4l2_create_buffers */ ++#define V4L2_BUF_CAP_SUPPORTS_MMAP (1 << 0) ++#define V4L2_BUF_CAP_SUPPORTS_USERPTR (1 << 1) ++#define V4L2_BUF_CAP_SUPPORTS_DMABUF (1 << 2) ++#define V4L2_BUF_CAP_SUPPORTS_REQUESTS (1 << 3) ++ + /** + * struct v4l2_plane - plane info for multi-planar buffers + * @bytesused: number of bytes occupied by data in the plane (payload) +@@ -2318,6 +2325,7 @@ struct v4l2_dbg_chip_info { + * return: number of created buffers + * @memory: enum v4l2_memory; buffer memory type + * @format: frame format, for which buffers are requested ++ * @capabilities: capabilities of this buffer type. + * @reserved: future extensions + */ + struct v4l2_create_buffers { +@@ -2325,7 +2333,8 @@ struct v4l2_create_buffers { + __u32 count; + __u32 memory; + struct v4l2_format format; +- __u32 reserved[8]; ++ __u32 capabilities; ++ __u32 reserved[7]; + }; + + /* diff --git a/target/linux/brcm2708/patches-4.19/950-0694-media-vb2-set-reqbufs-create_bufs-capabilities.patch b/target/linux/brcm2708/patches-4.19/950-0694-media-vb2-set-reqbufs-create_bufs-capabilities.patch new file mode 100644 index 0000000000..6e44d22a36 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0694-media-vb2-set-reqbufs-create_bufs-capabilities.patch @@ -0,0 +1,190 @@ +From b1da554db18a08164e0f4490e1b290d02dc8a042 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Thu, 23 Aug 2018 10:18:35 -0400 +Subject: [PATCH 694/725] media: vb2: set reqbufs/create_bufs capabilities + +Upstream commit e5079cf11373e4cc98be8b1072aece429eb2d4d2. + +Set the capabilities field of v4l2_requestbuffers and v4l2_create_buffers. + +The various mapping modes were easy, but for signaling the request capability +a new 'supports_requests' bitfield was added to videobuf2-core.h (and set in +vim2m and vivid). Drivers have to set this bitfield for any queue where +requests are supported. + +Signed-off-by: Hans Verkuil +Reviewed-by: Tomasz Figa +Acked-by: Sakari Ailus +Signed-off-by: Mauro Carvalho Chehab + +Minor modifications required on the backport +--- + drivers/media/common/videobuf2/videobuf2-v4l2.c | 17 +++++++++++++++++ + drivers/media/platform/vim2m.c | 1 + + drivers/media/platform/vivid/vivid-core.c | 5 +++++ + drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 4 +++- + drivers/media/v4l2-core/v4l2-ioctl.c | 4 ++-- + include/media/videobuf2-core.h | 2 ++ + 6 files changed, 30 insertions(+), 3 deletions(-) + +--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c ++++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c +@@ -482,10 +482,24 @@ int vb2_querybuf(struct vb2_queue *q, st + } + EXPORT_SYMBOL(vb2_querybuf); + ++static void fill_buf_caps(struct vb2_queue *q, u32 *caps) ++{ ++ *caps = 0; ++ if (q->io_modes & VB2_MMAP) ++ *caps |= V4L2_BUF_CAP_SUPPORTS_MMAP; ++ if (q->io_modes & VB2_USERPTR) ++ *caps |= V4L2_BUF_CAP_SUPPORTS_USERPTR; ++ if (q->io_modes & VB2_DMABUF) ++ *caps |= V4L2_BUF_CAP_SUPPORTS_DMABUF; ++ if (q->supports_requests) ++ *caps |= V4L2_BUF_CAP_SUPPORTS_REQUESTS; ++} ++ + int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) + { + int ret = vb2_verify_memory_type(q, req->memory, req->type); + ++ fill_buf_caps(q, &req->capabilities); + return ret ? ret : vb2_core_reqbufs(q, req->memory, &req->count); + } + EXPORT_SYMBOL_GPL(vb2_reqbufs); +@@ -513,6 +527,7 @@ int vb2_create_bufs(struct vb2_queue *q, + int ret = vb2_verify_memory_type(q, create->memory, f->type); + unsigned i; + ++ fill_buf_caps(q, &create->capabilities); + create->index = q->num_buffers; + if (create->count == 0) + return ret != -EBUSY ? ret : 0; +@@ -713,6 +728,7 @@ int vb2_ioctl_reqbufs(struct file *file, + struct video_device *vdev = video_devdata(file); + int res = vb2_verify_memory_type(vdev->queue, p->memory, p->type); + ++ fill_buf_caps(vdev->queue, &p->capabilities); + if (res) + return res; + if (vb2_queue_is_busy(vdev, file)) +@@ -734,6 +750,7 @@ int vb2_ioctl_create_bufs(struct file *f + p->format.type); + + p->index = vdev->queue->num_buffers; ++ fill_buf_caps(vdev->queue, &p->capabilities); + /* + * If count == 0, then just check if memory and type are valid. + * Any -EBUSY result from vb2_verify_memory_type can be mapped to 0. +--- a/drivers/media/platform/vim2m.c ++++ b/drivers/media/platform/vim2m.c +@@ -841,6 +841,7 @@ static int queue_init(void *priv, struct + src_vq->mem_ops = &vb2_vmalloc_memops; + src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + src_vq->lock = &ctx->dev->dev_mutex; ++ src_vq->supports_requests = true; + + ret = vb2_queue_init(src_vq); + if (ret) +--- a/drivers/media/platform/vivid/vivid-core.c ++++ b/drivers/media/platform/vivid/vivid-core.c +@@ -1060,6 +1060,7 @@ static int vivid_create_instance(struct + q->min_buffers_needed = 2; + q->lock = &dev->mutex; + q->dev = dev->v4l2_dev.dev; ++ q->supports_requests = true; + + ret = vb2_queue_init(q); + if (ret) +@@ -1080,6 +1081,7 @@ static int vivid_create_instance(struct + q->min_buffers_needed = 2; + q->lock = &dev->mutex; + q->dev = dev->v4l2_dev.dev; ++ q->supports_requests = true; + + ret = vb2_queue_init(q); + if (ret) +@@ -1100,6 +1102,7 @@ static int vivid_create_instance(struct + q->min_buffers_needed = 2; + q->lock = &dev->mutex; + q->dev = dev->v4l2_dev.dev; ++ q->supports_requests = true; + + ret = vb2_queue_init(q); + if (ret) +@@ -1120,6 +1123,7 @@ static int vivid_create_instance(struct + q->min_buffers_needed = 2; + q->lock = &dev->mutex; + q->dev = dev->v4l2_dev.dev; ++ q->supports_requests = true; + + ret = vb2_queue_init(q); + if (ret) +@@ -1139,6 +1143,7 @@ static int vivid_create_instance(struct + q->min_buffers_needed = 8; + q->lock = &dev->mutex; + q->dev = dev->v4l2_dev.dev; ++ q->supports_requests = true; + + ret = vb2_queue_init(q); + if (ret) +--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c ++++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +@@ -251,7 +251,8 @@ struct v4l2_create_buffers32 { + __u32 count; + __u32 memory; /* enum v4l2_memory */ + struct v4l2_format32 format; +- __u32 reserved[8]; ++ __u32 capabilities; ++ __u32 reserved[7]; + }; + + static int __bufsize_v4l2_format(struct v4l2_format32 __user *p32, u32 *size) +@@ -411,6 +412,7 @@ static int put_v4l2_create32(struct v4l2 + if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) || + copy_in_user(p32, p64, + offsetof(struct v4l2_create_buffers32, format)) || ++ assign_in_user(&p32->capabilities, &p64->capabilities) || + copy_in_user(p32->reserved, p64->reserved, sizeof(p64->reserved))) + return -EFAULT; + return __put_v4l2_format32(&p64->format, &p32->format); +--- a/drivers/media/v4l2-core/v4l2-ioctl.c ++++ b/drivers/media/v4l2-core/v4l2-ioctl.c +@@ -1879,7 +1879,7 @@ static int v4l_reqbufs(const struct v4l2 + if (ret) + return ret; + +- CLEAR_AFTER_FIELD(p, memory); ++ CLEAR_AFTER_FIELD(p, capabilities); + + return ops->vidioc_reqbufs(file, fh, p); + } +@@ -1920,7 +1920,7 @@ static int v4l_create_bufs(const struct + if (ret) + return ret; + +- CLEAR_AFTER_FIELD(create, format); ++ CLEAR_AFTER_FIELD(create, capabilities); + + v4l_sanitize_format(&create->format); + +--- a/include/media/videobuf2-core.h ++++ b/include/media/videobuf2-core.h +@@ -449,6 +449,7 @@ struct vb2_buf_ops { + * @quirk_poll_must_check_waiting_for_buffers: Return %EPOLLERR at poll when QBUF + * has not been called. This is a vb1 idiom that has been adopted + * also by vb2. ++ * @supports_requests: this queue supports the Request API. + * @lock: pointer to a mutex that protects the &struct vb2_queue. The + * driver can set this to a mutex to let the v4l2 core serialize + * the queuing ioctls. If the driver wants to handle locking +@@ -516,6 +517,7 @@ struct vb2_queue { + unsigned fileio_write_immediately:1; + unsigned allow_zero_bytesused:1; + unsigned quirk_poll_must_check_waiting_for_buffers:1; ++ unsigned supports_requests:1; + + struct mutex *lock; + void *owner; diff --git a/target/linux/brcm2708/patches-4.19/950-0694-staging-vc-sm-cma-Fix-the-few-remaining-coding-style.patch b/target/linux/brcm2708/patches-4.19/950-0694-staging-vc-sm-cma-Fix-the-few-remaining-coding-style.patch deleted file mode 100644 index 8cbdc42108..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0694-staging-vc-sm-cma-Fix-the-few-remaining-coding-style.patch +++ /dev/null @@ -1,188 +0,0 @@ -From af55660301d90af33724086223cd1c005c6af4ec Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 2 Jul 2019 17:19:04 +0100 -Subject: [PATCH 694/703] staging: vc-sm-cma: Fix the few remaining coding - style issues - -Fix a few minor checkpatch complaints to make the driver clean - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/vc-sm-cma/vc_sm.c | 6 +- - .../vc04_services/vc-sm-cma/vc_sm_cma_vchi.c | 128 +++++++++--------- - 2 files changed, 65 insertions(+), 69 deletions(-) - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -325,7 +325,6 @@ static void vc_sm_release_resource(struc - buffer->cookie, buffer->dma_addr); - } - -- - /* Free our buffer. Start by removing it from the list */ - mutex_lock(&sm_state->map_lock); - list_del(&buffer->global_buffer_list); -@@ -1365,7 +1364,8 @@ static int vc_sm_cma_clean_invalid2(unsi - } - - for (i = 0; i < ioparam.op_count; i++) { -- const struct vc_sm_cma_ioctl_clean_invalid_block * const op = block + i; -+ const struct vc_sm_cma_ioctl_clean_invalid_block * const op = -+ block + i; - - if (op->invalidate_mode == VC_SM_CACHE_OP_NOP) - continue; -@@ -1637,8 +1637,6 @@ err_remove_misc_dev: - err_remove_debugfs: - debugfs_remove_recursive(sm_state->dir_root); - vc_sm_cma_vchi_stop(&sm_state->sm_handle); -- -- return; - } - - /* Driver loading. */ ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma_vchi.c -@@ -188,79 +188,77 @@ static int vc_sm_cma_vchi_videocore_io(v - if (svc_use) - vchi_service_release(instance->vchi_handle[0]); - svc_use = 0; -- if (!wait_for_completion_interruptible(&instance->io_cmplt)) { -- vchi_service_use(instance->vchi_handle[0]); -- svc_use = 1; -- -- do { -- /* -- * Get new command and move it to response list -- */ -- mutex_lock(&instance->lock); -- if (list_empty(&instance->cmd_list)) { -- /* no more commands to process */ -- mutex_unlock(&instance->lock); -- break; -- } -- cmd = -- list_first_entry(&instance->cmd_list, -- struct sm_cmd_rsp_blk, -- head); -- list_move(&cmd->head, &instance->rsp_list); -- cmd->sent = 1; -- mutex_unlock(&instance->lock); - -- /* Send the command */ -- status = bcm2835_vchi_msg_queue( -- instance->vchi_handle[0], -- cmd->msg, cmd->length); -- if (status) { -- pr_err("%s: failed to queue message (%d)", -- __func__, status); -- } -- -- /* If no reply is needed then we're done */ -- if (!cmd->wait) { -- mutex_lock(&instance->lock); -- list_del(&cmd->head); -- mutex_unlock(&instance->lock); -- vc_vchi_cmd_delete(instance, cmd); -- continue; -- } -- -- if (status) { -- complete(&cmd->cmplt); -- continue; -- } -- -- } while (1); -- -- while (!vchi_msg_peek(instance->vchi_handle[0], -- (void **)&reply, &reply_len, -- VCHI_FLAGS_NONE)) { -- if (reply->trans_id & 0x80000000) { -- /* Async event or cmd from the VPU */ -- if (instance->vpu_event) -- instance->vpu_event( -- instance, reply, -- reply_len); -- } else { -- vc_sm_cma_vchi_rx_ack(instance, cmd, -- reply, reply_len); -- } -+ if (wait_for_completion_interruptible(&instance->io_cmplt)) -+ continue; - -- vchi_msg_remove(instance->vchi_handle[0]); -- } -+ vchi_service_use(instance->vchi_handle[0]); -+ svc_use = 1; - -- /* Go through the dead list and free them */ -+ do { -+ /* -+ * Get new command and move it to response list -+ */ - mutex_lock(&instance->lock); -- list_for_each_entry_safe(cmd, cmd_tmp, -- &instance->dead_list, head) { -+ if (list_empty(&instance->cmd_list)) { -+ /* no more commands to process */ -+ mutex_unlock(&instance->lock); -+ break; -+ } -+ cmd = list_first_entry(&instance->cmd_list, -+ struct sm_cmd_rsp_blk, head); -+ list_move(&cmd->head, &instance->rsp_list); -+ cmd->sent = 1; -+ mutex_unlock(&instance->lock); -+ -+ /* Send the command */ -+ status = -+ bcm2835_vchi_msg_queue(instance->vchi_handle[0], -+ cmd->msg, cmd->length); -+ if (status) { -+ pr_err("%s: failed to queue message (%d)", -+ __func__, status); -+ } -+ -+ /* If no reply is needed then we're done */ -+ if (!cmd->wait) { -+ mutex_lock(&instance->lock); - list_del(&cmd->head); -+ mutex_unlock(&instance->lock); - vc_vchi_cmd_delete(instance, cmd); -+ continue; - } -- mutex_unlock(&instance->lock); -+ -+ if (status) { -+ complete(&cmd->cmplt); -+ continue; -+ } -+ -+ } while (1); -+ -+ while (!vchi_msg_peek(instance->vchi_handle[0], (void **)&reply, -+ &reply_len, VCHI_FLAGS_NONE)) { -+ if (reply->trans_id & 0x80000000) { -+ /* Async event or cmd from the VPU */ -+ if (instance->vpu_event) -+ instance->vpu_event(instance, reply, -+ reply_len); -+ } else { -+ vc_sm_cma_vchi_rx_ack(instance, cmd, reply, -+ reply_len); -+ } -+ -+ vchi_msg_remove(instance->vchi_handle[0]); -+ } -+ -+ /* Go through the dead list and free them */ -+ mutex_lock(&instance->lock); -+ list_for_each_entry_safe(cmd, cmd_tmp, &instance->dead_list, -+ head) { -+ list_del(&cmd->head); -+ vc_vchi_cmd_delete(instance, cmd); - } -+ mutex_unlock(&instance->lock); - } - - return 0; diff --git a/target/linux/brcm2708/patches-4.19/950-0695-configs-Drop-MMC_SDHCI_BCM2711-from-arm64-bcm2711_de.patch b/target/linux/brcm2708/patches-4.19/950-0695-configs-Drop-MMC_SDHCI_BCM2711-from-arm64-bcm2711_de.patch deleted file mode 100644 index ba0de643ea..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0695-configs-Drop-MMC_SDHCI_BCM2711-from-arm64-bcm2711_de.patch +++ /dev/null @@ -1,23 +0,0 @@ -From ba55985a050750483553584ebf6b587f4e6b7f91 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 4 Jul 2019 11:52:43 +0100 -Subject: [PATCH 695/703] configs: Drop MMC_SDHCI_BCM2711 from - arm64/bcm2711_defconfig - -Apparently this is a vestigial setting and should be removed. - -Signed-off-by: Dave Stevenson ---- - arch/arm64/configs/bcm2711_defconfig | 1 - - 1 file changed, 1 deletion(-) - ---- a/arch/arm64/configs/bcm2711_defconfig -+++ b/arch/arm64/configs/bcm2711_defconfig -@@ -1031,7 +1031,6 @@ CONFIG_USB_G_HID=m - CONFIG_USB_G_WEBCAM=m - CONFIG_MMC=y - CONFIG_MMC_BLOCK_MINORS=32 --CONFIG_MMC_SDHCI_BCM2711=y - CONFIG_MMC_BCM2835_MMC=y - CONFIG_MMC_BCM2835_DMA=y - CONFIG_MMC_BCM2835_SDHOST=y diff --git a/target/linux/brcm2708/patches-4.19/950-0695-media-vb2-Allow-reqbufs-0-with-in-use-MMAP-buffers.patch b/target/linux/brcm2708/patches-4.19/950-0695-media-vb2-Allow-reqbufs-0-with-in-use-MMAP-buffers.patch new file mode 100644 index 0000000000..b6bde57f38 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0695-media-vb2-Allow-reqbufs-0-with-in-use-MMAP-buffers.patch @@ -0,0 +1,130 @@ +From b7f5e21034ac7af2b8ceee726151f4635435694f Mon Sep 17 00:00:00 2001 +From: John Sheu +Date: Thu, 15 Nov 2018 10:57:16 -0500 +Subject: [PATCH 695/725] media: vb2: Allow reqbufs(0) with "in use" MMAP + buffers + +Upstream commit d644cca50f366cd109845ae92e37c09ed79adf81 + +Videobuf2 presently does not allow VIDIOC_REQBUFS to destroy outstanding +buffers if the queue is of type V4L2_MEMORY_MMAP, and if the buffers are +considered "in use". This is different behavior than for other memory +types and prevents us from deallocating buffers in following two cases: + +1) There are outstanding mmap()ed views on the buffer. However even if + we put the buffer in reqbufs(0), there will be remaining references, + due to vma .open/close() adjusting vb2 buffer refcount appropriately. + This means that the buffer will be in fact freed only when the last + mmap()ed view is unmapped. + +2) Buffer has been exported as a DMABUF. Refcount of the vb2 buffer + is managed properly by VB2 DMABUF ops, i.e. incremented on DMABUF + get and decremented on DMABUF release. This means that the buffer + will be alive until all importers release it. + +Considering both cases above, there does not seem to be any need to +prevent reqbufs(0) operation, because buffer lifetime is already +properly managed by both mmap() and DMABUF code paths. Let's remove it +and allow userspace freeing the queue (and potentially allocating a new +one) even though old buffers might be still in processing. + +To let userspace know that the kernel now supports orphaning buffers +that are still in use, add a new V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS +to be set by reqbufs and create_bufs. + +[p.zabel@pengutronix.de: added V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS, + updated documentation, and added back debug message] + +Signed-off-by: John Sheu +Reviewed-by: Pawel Osciak +Signed-off-by: Tomasz Figa +Signed-off-by: Philipp Zabel +Acked-by: Sakari Ailus +Signed-off-by: Hans Verkuil +[hverkuil-cisco@xs4all.nl: added V4L2-BUF-CAP-SUPPORTS-ORPHANED-BUFS ref] +Signed-off-by: Mauro Carvalho Chehab +--- + Documentation/media/uapi/v4l/vidioc-reqbufs.rst | 17 ++++++++++++++--- + drivers/media/common/videobuf2/videobuf2-core.c | 8 +++----- + drivers/media/common/videobuf2/videobuf2-v4l2.c | 2 +- + include/uapi/linux/videodev2.h | 1 + + 4 files changed, 19 insertions(+), 9 deletions(-) + +--- a/Documentation/media/uapi/v4l/vidioc-reqbufs.rst ++++ b/Documentation/media/uapi/v4l/vidioc-reqbufs.rst +@@ -59,9 +59,14 @@ When the I/O method is not supported the + code. + + Applications can call :ref:`VIDIOC_REQBUFS` again to change the number of +-buffers, however this cannot succeed when any buffers are still mapped. +-A ``count`` value of zero frees all buffers, after aborting or finishing +-any DMA in progress, an implicit ++buffers. Note that if any buffers are still mapped or exported via DMABUF, ++then :ref:`VIDIOC_REQBUFS` can only succeed if the ++``V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS`` capability is set. Otherwise ++:ref:`VIDIOC_REQBUFS` will return the ``EBUSY`` error code. ++If ``V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS`` is set, then these buffers are ++orphaned and will be freed when they are unmapped or when the exported DMABUF ++fds are closed. A ``count`` value of zero frees or orphans all buffers, after ++aborting or finishing any DMA in progress, an implicit + :ref:`VIDIOC_STREAMOFF `. + + +@@ -112,6 +117,7 @@ any DMA in progress, an implicit + .. _V4L2-BUF-CAP-SUPPORTS-USERPTR: + .. _V4L2-BUF-CAP-SUPPORTS-DMABUF: + .. _V4L2-BUF-CAP-SUPPORTS-REQUESTS: ++.. _V4L2-BUF-CAP-SUPPORTS-ORPHANED-BUFS: + + .. cssclass:: longtable + +@@ -132,6 +138,11 @@ any DMA in progress, an implicit + * - ``V4L2_BUF_CAP_SUPPORTS_REQUESTS`` + - 0x00000008 + - This buffer type supports :ref:`requests `. ++ * - ``V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS`` ++ - 0x00000010 ++ - The kernel allows calling :ref:`VIDIOC_REQBUFS` while buffers are still ++ mapped or exported via DMABUF. These orphaned buffers will be freed ++ when they are unmapped or when the exported DMABUF fds are closed. + + Return Value + ============ +--- a/drivers/media/common/videobuf2/videobuf2-core.c ++++ b/drivers/media/common/videobuf2/videobuf2-core.c +@@ -684,11 +684,9 @@ int vb2_core_reqbufs(struct vb2_queue *q + * are not in use and can be freed. + */ + mutex_lock(&q->mmap_lock); +- if (q->memory == VB2_MEMORY_MMAP && __buffers_in_use(q)) { +- mutex_unlock(&q->mmap_lock); +- dprintk(1, "memory in use, cannot free\n"); +- return -EBUSY; +- } ++ if (debug && q->memory == VB2_MEMORY_MMAP && ++ __buffers_in_use(q)) ++ dprintk(1, "memory in use, orphaning buffers\n"); + + /* + * Call queue_cancel to clean up any buffers in the PREPARED or +--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c ++++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c +@@ -484,7 +484,7 @@ EXPORT_SYMBOL(vb2_querybuf); + + static void fill_buf_caps(struct vb2_queue *q, u32 *caps) + { +- *caps = 0; ++ *caps = V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS; + if (q->io_modes & VB2_MMAP) + *caps |= V4L2_BUF_CAP_SUPPORTS_MMAP; + if (q->io_modes & VB2_USERPTR) +--- a/include/uapi/linux/videodev2.h ++++ b/include/uapi/linux/videodev2.h +@@ -881,6 +881,7 @@ struct v4l2_requestbuffers { + #define V4L2_BUF_CAP_SUPPORTS_USERPTR (1 << 1) + #define V4L2_BUF_CAP_SUPPORTS_DMABUF (1 << 2) + #define V4L2_BUF_CAP_SUPPORTS_REQUESTS (1 << 3) ++#define V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS (1 << 4) + + /** + * struct v4l2_plane - plane info for multi-planar buffers diff --git a/target/linux/brcm2708/patches-4.19/950-0696-Revert-media-vb2-Allow-reqbufs-0-with-in-use-MMAP-bu.patch b/target/linux/brcm2708/patches-4.19/950-0696-Revert-media-vb2-Allow-reqbufs-0-with-in-use-MMAP-bu.patch deleted file mode 100644 index 2731d46136..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0696-Revert-media-vb2-Allow-reqbufs-0-with-in-use-MMAP-bu.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 41079f8602ae082b78e33e7d326ff5f57b7d76e8 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 28 Jun 2019 11:30:49 +0100 -Subject: [PATCH 696/703] Revert "media: vb2: Allow reqbufs(0) with "in use" - MMAP buffers" - -This reverts commit a2c73e18c1f657de6d654f51effa0a94863abbd8. -An alternative version was accepted upstream. Revert this patch to -apply that one. - -Signed-off-by: Dave Stevenson ---- - .../media/common/videobuf2/videobuf2-core.c | 23 +++++++++++++++++++ - 1 file changed, 23 insertions(+) - ---- a/drivers/media/common/videobuf2/videobuf2-core.c -+++ b/drivers/media/common/videobuf2/videobuf2-core.c -@@ -554,6 +554,20 @@ bool vb2_buffer_in_use(struct vb2_queue - } - EXPORT_SYMBOL(vb2_buffer_in_use); - -+/* -+ * __buffers_in_use() - return true if any buffers on the queue are in use and -+ * the queue cannot be freed (by the means of REQBUFS(0)) call -+ */ -+static bool __buffers_in_use(struct vb2_queue *q) -+{ -+ unsigned int buffer; -+ for (buffer = 0; buffer < q->num_buffers; ++buffer) { -+ if (vb2_buffer_in_use(q, q->bufs[buffer])) -+ return true; -+ } -+ return false; -+} -+ - void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb) - { - call_void_bufop(q, fill_user_buffer, q->bufs[index], pb); -@@ -665,7 +679,16 @@ int vb2_core_reqbufs(struct vb2_queue *q - - if (*count == 0 || q->num_buffers != 0 || - (q->memory != VB2_MEMORY_UNKNOWN && q->memory != memory)) { -+ /* -+ * We already have buffers allocated, so first check if they -+ * are not in use and can be freed. -+ */ - mutex_lock(&q->mmap_lock); -+ if (q->memory == VB2_MEMORY_MMAP && __buffers_in_use(q)) { -+ mutex_unlock(&q->mmap_lock); -+ dprintk(1, "memory in use, cannot free\n"); -+ return -EBUSY; -+ } - - /* - * Call queue_cancel to clean up any buffers in the PREPARED or diff --git a/target/linux/brcm2708/patches-4.19/950-0696-overlays-Add-real-parameters-to-the-rpi-poe-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0696-overlays-Add-real-parameters-to-the-rpi-poe-overlay.patch new file mode 100644 index 0000000000..08a266f1cf --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0696-overlays-Add-real-parameters-to-the-rpi-poe-overlay.patch @@ -0,0 +1,33 @@ +From 21cb98ad5ea375032112a5d7ee92acd4196de5fb Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 5 Jul 2019 09:22:10 +0100 +Subject: [PATCH 696/725] overlays: Add real parameters to the rpi-poe overlay + +As a result of being loaded by the POE HAT EEPROM, the rpi-poe overlay +doesn't expose parameters in the usual way; instead it adds them to +the base Device Tree, and the user is expected to use "dtparam=..." +to access them. + +To make the documentation correct and to protect users who load the +overlay explicitly, expecting to be able to use the parameters, add +real parameters to the overlay as well. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/rpi-poe-overlay.dts | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/arch/arm/boot/dts/overlays/rpi-poe-overlay.dts ++++ b/arch/arm/boot/dts/overlays/rpi-poe-overlay.dts +@@ -60,4 +60,11 @@ + poe_fan_temp1_hyst = <&trip1>,"hysteresis:0"; + }; + }; ++ ++ __overrides__ { ++ poe_fan_temp0 = <&trip0>,"temperature:0"; ++ poe_fan_temp0_hyst = <&trip0>,"hysteresis:0"; ++ poe_fan_temp1 = <&trip1>,"temperature:0"; ++ poe_fan_temp1_hyst = <&trip1>,"hysteresis:0"; ++ }; + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0697-media-videodev2.h-add-new-capabilities-for-buffer-ty.patch b/target/linux/brcm2708/patches-4.19/950-0697-media-videodev2.h-add-new-capabilities-for-buffer-ty.patch deleted file mode 100644 index e313ace895..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0697-media-videodev2.h-add-new-capabilities-for-buffer-ty.patch +++ /dev/null @@ -1,136 +0,0 @@ -From e9ec6de11c358ff3bc389cfa0003544c60f859ef Mon Sep 17 00:00:00 2001 -From: Hans Verkuil -Date: Thu, 23 Aug 2018 09:56:22 -0400 -Subject: [PATCH 697/703] media: videodev2.h: add new capabilities for buffer - types - -Upstream commit f35f5d72e70e6b91389eb98fcabf43b79f40587f - -VIDIOC_REQBUFS and VIDIOC_CREATE_BUFFERS will return capabilities -telling userspace what the given buffer type is capable of. - -Signed-off-by: Hans Verkuil -Reviewed-by: Tomasz Figa -Acked-by: Sakari Ailus -Signed-off-by: Mauro Carvalho Chehab ---- - .../media/uapi/v4l/vidioc-create-bufs.rst | 14 ++++++- - .../media/uapi/v4l/vidioc-reqbufs.rst | 42 ++++++++++++++++++- - include/uapi/linux/videodev2.h | 13 +++++- - 3 files changed, 65 insertions(+), 4 deletions(-) - ---- a/Documentation/media/uapi/v4l/vidioc-create-bufs.rst -+++ b/Documentation/media/uapi/v4l/vidioc-create-bufs.rst -@@ -102,7 +102,19 @@ than the number requested. - - ``format`` - - Filled in by the application, preserved by the driver. - * - __u32 -- - ``reserved``\ [8] -+ - ``capabilities`` -+ - Set by the driver. If 0, then the driver doesn't support -+ capabilities. In that case all you know is that the driver is -+ guaranteed to support ``V4L2_MEMORY_MMAP`` and *might* support -+ other :c:type:`v4l2_memory` types. It will not support any others -+ capabilities. See :ref:`here ` for a list of the -+ capabilities. -+ -+ If you want to just query the capabilities without making any -+ other changes, then set ``count`` to 0, ``memory`` to -+ ``V4L2_MEMORY_MMAP`` and ``format.type`` to the buffer type. -+ * - __u32 -+ - ``reserved``\ [7] - - A place holder for future extensions. Drivers and applications - must set the array to zero. - ---- a/Documentation/media/uapi/v4l/vidioc-reqbufs.rst -+++ b/Documentation/media/uapi/v4l/vidioc-reqbufs.rst -@@ -88,10 +88,50 @@ any DMA in progress, an implicit - ``V4L2_MEMORY_DMABUF`` or ``V4L2_MEMORY_USERPTR``. See - :c:type:`v4l2_memory`. - * - __u32 -- - ``reserved``\ [2] -+ - ``capabilities`` -+ - Set by the driver. If 0, then the driver doesn't support -+ capabilities. In that case all you know is that the driver is -+ guaranteed to support ``V4L2_MEMORY_MMAP`` and *might* support -+ other :c:type:`v4l2_memory` types. It will not support any others -+ capabilities. -+ -+ If you want to query the capabilities with a minimum of side-effects, -+ then this can be called with ``count`` set to 0, ``memory`` set to -+ ``V4L2_MEMORY_MMAP`` and ``type`` set to the buffer type. This will -+ free any previously allocated buffers, so this is typically something -+ that will be done at the start of the application. -+ * - __u32 -+ - ``reserved``\ [1] - - A place holder for future extensions. Drivers and applications - must set the array to zero. - -+.. tabularcolumns:: |p{6.1cm}|p{2.2cm}|p{8.7cm}| -+ -+.. _v4l2-buf-capabilities: -+.. _V4L2-BUF-CAP-SUPPORTS-MMAP: -+.. _V4L2-BUF-CAP-SUPPORTS-USERPTR: -+.. _V4L2-BUF-CAP-SUPPORTS-DMABUF: -+.. _V4L2-BUF-CAP-SUPPORTS-REQUESTS: -+ -+.. cssclass:: longtable -+ -+.. flat-table:: V4L2 Buffer Capabilities Flags -+ :header-rows: 0 -+ :stub-columns: 0 -+ :widths: 3 1 4 -+ -+ * - ``V4L2_BUF_CAP_SUPPORTS_MMAP`` -+ - 0x00000001 -+ - This buffer type supports the ``V4L2_MEMORY_MMAP`` streaming mode. -+ * - ``V4L2_BUF_CAP_SUPPORTS_USERPTR`` -+ - 0x00000002 -+ - This buffer type supports the ``V4L2_MEMORY_USERPTR`` streaming mode. -+ * - ``V4L2_BUF_CAP_SUPPORTS_DMABUF`` -+ - 0x00000004 -+ - This buffer type supports the ``V4L2_MEMORY_DMABUF`` streaming mode. -+ * - ``V4L2_BUF_CAP_SUPPORTS_REQUESTS`` -+ - 0x00000008 -+ - This buffer type supports :ref:`requests `. - - Return Value - ============ ---- a/include/uapi/linux/videodev2.h -+++ b/include/uapi/linux/videodev2.h -@@ -872,9 +872,16 @@ struct v4l2_requestbuffers { - __u32 count; - __u32 type; /* enum v4l2_buf_type */ - __u32 memory; /* enum v4l2_memory */ -- __u32 reserved[2]; -+ __u32 capabilities; -+ __u32 reserved[1]; - }; - -+/* capabilities for struct v4l2_requestbuffers and v4l2_create_buffers */ -+#define V4L2_BUF_CAP_SUPPORTS_MMAP (1 << 0) -+#define V4L2_BUF_CAP_SUPPORTS_USERPTR (1 << 1) -+#define V4L2_BUF_CAP_SUPPORTS_DMABUF (1 << 2) -+#define V4L2_BUF_CAP_SUPPORTS_REQUESTS (1 << 3) -+ - /** - * struct v4l2_plane - plane info for multi-planar buffers - * @bytesused: number of bytes occupied by data in the plane (payload) -@@ -2318,6 +2325,7 @@ struct v4l2_dbg_chip_info { - * return: number of created buffers - * @memory: enum v4l2_memory; buffer memory type - * @format: frame format, for which buffers are requested -+ * @capabilities: capabilities of this buffer type. - * @reserved: future extensions - */ - struct v4l2_create_buffers { -@@ -2325,7 +2333,8 @@ struct v4l2_create_buffers { - __u32 count; - __u32 memory; - struct v4l2_format format; -- __u32 reserved[8]; -+ __u32 capabilities; -+ __u32 reserved[7]; - }; - - /* diff --git a/target/linux/brcm2708/patches-4.19/950-0697-overlays-Rename-pi3-overlays-to-be-less-model-specif.patch b/target/linux/brcm2708/patches-4.19/950-0697-overlays-Rename-pi3-overlays-to-be-less-model-specif.patch new file mode 100644 index 0000000000..01d0dafaad --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0697-overlays-Rename-pi3-overlays-to-be-less-model-specif.patch @@ -0,0 +1,587 @@ +From 75036ddc7b3ea2f1366cef40491d690396f34bdc Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 5 Jul 2019 14:49:22 +0100 +Subject: [PATCH 697/725] overlays: Rename pi3- overlays to be less + model-specific (#3052) + +Rename the various pi3- overlays to be more generic, listing +the devices they apply to in the README. The original names are +retained for backwards compatibility as files that just include +the new versions - the README marks them as being deprecated. + +See: https://github.com/raspberrypi/firmware/issues/1174 + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/Makefile | 4 + + arch/arm/boot/dts/overlays/README | 97 ++++++++++++------- + .../arm/boot/dts/overlays/act-led-overlay.dts | 27 ++++++ + .../boot/dts/overlays/disable-bt-overlay.dts | 55 +++++++++++ + .../dts/overlays/disable-wifi-overlay.dts | 20 ++++ + .../boot/dts/overlays/miniuart-bt-overlay.dts | 74 ++++++++++++++ + .../boot/dts/overlays/pi3-act-led-overlay.dts | 28 +----- + .../dts/overlays/pi3-disable-bt-overlay.dts | 56 +---------- + .../dts/overlays/pi3-disable-wifi-overlay.dts | 21 +--- + .../dts/overlays/pi3-miniuart-bt-overlay.dts | 75 +------------- + 10 files changed, 246 insertions(+), 211 deletions(-) + create mode 100644 arch/arm/boot/dts/overlays/act-led-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/disable-bt-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/disable-wifi-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/miniuart-bt-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -1,6 +1,7 @@ + # Overlays for the Raspberry Pi platform + + dtbo-$(CONFIG_ARCH_BCM2835) += \ ++ act-led.dtbo \ + adau1977-adc.dtbo \ + adau7002-simple.dtbo \ + ads1015.dtbo \ +@@ -26,6 +27,8 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + dht11.dtbo \ + dionaudio-loco.dtbo \ + dionaudio-loco-v2.dtbo \ ++ disable-bt.dtbo \ ++ disable-wifi.dtbo \ + dpi18.dtbo \ + dpi24.dtbo \ + draws.dtbo \ +@@ -91,6 +94,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + media-center.dtbo \ + midi-uart0.dtbo \ + midi-uart1.dtbo \ ++ miniuart-bt.dtbo \ + mmc.dtbo \ + mpu6050.dtbo \ + mz61581.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -180,14 +180,16 @@ Params: + + act_led_activelow Set to "on" to invert the sense of the LED + (default "off") +- N.B. For Pi3 see pi3-act-led overlay. ++ N.B. For Pi 3B, 3B+, 3A+ and 4B, use the act-led ++ overlay. + + act_led_gpio Set which GPIO to use for the activity LED + (in case you want to connect it to an external + device) + (default "16" on a non-Plus board, "47" on a + Plus or Pi 2) +- N.B. For Pi3 see pi3-act-led overlay. ++ N.B. For Pi 3B, 3B+, 3A+ and 4B, use the act-led ++ overlay. + + pwr_led_trigger + pwr_led_activelow +@@ -205,6 +207,23 @@ Params: + and the other i2c baudrate parameters. + + ++Name: act-led ++Info: Pi 3B, 3B+, 3A+ and 4B use a GPIO expander to drive the LEDs which can ++ only be accessed from the VPU. There is a special driver for this with a ++ separate DT node, which has the unfortunate consequence of breaking the ++ act_led_gpio and act_led_activelow dtparams. ++ This overlay changes the GPIO controller back to the standard one and ++ restores the dtparams. ++Load: dtoverlay=act-led,= ++Params: activelow Set to "on" to invert the sense of the LED ++ (default "off") ++ ++ gpio Set which GPIO to use for the activity LED ++ (in case you want to connect it to an external ++ device) ++ REQUIRED ++ ++ + Name: adau1977-adc + Info: Overlay for activation of ADAU1977 ADC codec over I2C for control + and I2S for data. +@@ -509,6 +528,21 @@ Params: 24db_digital_gain Allow ga + that does not result in clipping/distortion!) + + ++Name: disable-bt ++Info: Disable onboard Bluetooth on Pi 3B, 3B+, 3A+, 4B and Zero W, restoring ++ UART0/ttyAMA0 over GPIOs 14 & 15. ++ N.B. To disable the systemd service that initialises the modem so it ++ doesn't use the UART, use 'sudo systemctl disable hciuart'. ++Load: dtoverlay=disable-bt ++Params: ++ ++ ++Name: disable-wifi ++Info: Disable onboard WiFi on Pi 3B, 3B+, 3A+, 4B and Zero W. ++Load: dtoverlay=disable-wifi ++Params: ++ ++ + 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 +@@ -1447,6 +1481,20 @@ Load: dtoverlay=midi-uart1 + Params: + + ++Name: miniuart-bt ++Info: Switch the onboard Bluetooth function on Pi 3B, 3B+, 3A+, 4B and Zero W ++ to use the mini-UART (ttyS0) and restore UART0/ttyAMA0 over GPIOs 14 & ++ 15. Note that this may reduce the maximum usable baudrate. ++ N.B. It is also necessary to edit /lib/systemd/system/hciuart.service ++ and replace ttyAMA0 with ttyS0, unless using Raspbian or another ++ distribution with udev rules that create /dev/serial0 and /dev/serial1, ++ in which case use /dev/serial1 instead because it will always be ++ correct. Furthermore, you must also set core_freq and core_freq_min to ++ the same value in config.txt or the miniuart will not work. ++Load: dtoverlay=miniuart-bt ++Params: ++ ++ + Name: mmc + Info: Selects the bcm2835-mmc SD/MMC driver, optionally with overclock + Load: dtoverlay=mmc,= +@@ -1509,48 +1557,27 @@ Params: panel Display + + + Name: pi3-act-led +-Info: Pi3 uses a GPIO expander to drive the LEDs which can only be accessed +- from the VPU. There is a special driver for this with a separate DT +- node, which has the unfortunate consequence of breaking the +- act_led_gpio and act_led_activelow dtparams. +- This overlay changes the GPIO controller back to the standard one and +- restores the dtparams. +-Load: dtoverlay=pi3-act-led,= +-Params: activelow Set to "on" to invert the sense of the LED +- (default "off") +- +- gpio Set which GPIO to use for the activity LED +- (in case you want to connect it to an external +- device) +- REQUIRED ++Info: This overlay has been renamed act-led, keeping pi3-act-led as an alias ++ for backwards compatibility. ++Load: + + + Name: pi3-disable-bt +-Info: Disable Pi3 Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15 +- N.B. To disable the systemd service that initialises the modem so it +- doesn't use the UART, use 'sudo systemctl disable hciuart'. +-Load: dtoverlay=pi3-disable-bt +-Params: ++Info: This overlay has been renamed disable-bt, keeping pi3-disable-bt as an ++ alias for backwards compatibility. ++Load: + + + Name: pi3-disable-wifi +-Info: Disable Pi3 onboard WiFi +-Load: dtoverlay=pi3-disable-wifi +-Params: ++Info: This overlay has been renamed disable-wifi, keeping pi3-disable-wifi as ++ an alias for backwards compatibility. ++Load: + + + Name: pi3-miniuart-bt +-Info: Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore +- UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum +- usable baudrate. +- N.B. It is also necessary to edit /lib/systemd/system/hciuart.service +- and replace ttyAMA0 with ttyS0, unless you have a system with udev rules +- that create /dev/serial0 and /dev/serial1, in which case use +- /dev/serial1 instead because it will always be correct. Furthermore, +- you must also set core_freq=250 in config.txt or the miniuart will not +- work. +-Load: dtoverlay=pi3-miniuart-bt +-Params: ++Info: This overlay has been renamed miniuart-bt, keeping pi3-miniuart-bt as ++ an alias for backwards compatibility. ++Load: + + + Name: pibell +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/act-led-overlay.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/* Pi3 uses a GPIO expander to drive the LEDs which can only be accessed ++ from the VPU. There is a special driver for this with a separate DT node, ++ which has the unfortunate consequence of breaking the act_led_gpio and ++ act_led_activelow dtparams. ++ ++ This overlay changes the GPIO controller back to the standard one and ++ restores the dtparams. ++*/ ++ ++/{ ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&act_led>; ++ frag0: __overlay__ { ++ gpios = <&gpio 0 0>; ++ }; ++ }; ++ ++ __overrides__ { ++ gpio = <&frag0>,"gpios:4"; ++ activelow = <&frag0>,"gpios:8"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/disable-bt-overlay.dts +@@ -0,0 +1,55 @@ ++/dts-v1/; ++/plugin/; ++ ++/* Disable Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15. ++ To disable the systemd service that initialises the modem so it doesn't use ++ the UART: ++ ++ sudo systemctl disable hciuart ++*/ ++ ++/{ ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&uart1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart0>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart0_pins>; ++ __overlay__ { ++ brcm,pins; ++ brcm,function; ++ brcm,pull; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&bt_pins>; ++ __overlay__ { ++ brcm,pins; ++ brcm,function; ++ brcm,pull; ++ }; ++ }; ++ ++ fragment@4 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial0 = "/soc/serial@7e201000"; ++ serial1 = "/soc/serial@7e215040"; ++ }; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/disable-wifi-overlay.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&mmc>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&mmcnr>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/miniuart-bt-overlay.dts +@@ -0,0 +1,74 @@ ++/dts-v1/; ++/plugin/; ++ ++/* Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore ++ UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum ++ usable baudrate. ++ ++ It is also necessary to edit /lib/systemd/system/hciuart.service and ++ replace ttyAMA0 with ttyS0, unless you have a system with udev rules ++ that create /dev/serial0 and /dev/serial1, in which case use /dev/serial1 ++ instead because it will always be correct. ++ ++ If cmdline.txt uses the alias serial0 to refer to the user-accessable port ++ then the firmware will replace with the appropriate port whether or not ++ this overlay is used. ++*/ ++ ++/{ ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&uart0>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart1>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins &bt_pins &fake_bt_cts>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart0_pins>; ++ __overlay__ { ++ brcm,pins; ++ brcm,function; ++ brcm,pull; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&uart1_pins>; ++ __overlay__ { ++ brcm,pins = <32 33>; ++ brcm,function = <2>; /* alt5=UART1 */ ++ brcm,pull = <0 2>; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&gpio>; ++ __overlay__ { ++ fake_bt_cts: fake_bt_cts { ++ brcm,pins = <31>; ++ brcm,function = <1>; /* output */ ++ }; ++ }; ++ }; ++ ++ fragment@5 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial0 = "/soc/serial@7e201000"; ++ serial1 = "/soc/serial@7e215040"; ++ }; ++ }; ++}; +--- a/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts ++++ b/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts +@@ -1,27 +1 @@ +-/dts-v1/; +-/plugin/; +- +-/* Pi3 uses a GPIO expander to drive the LEDs which can only be accessed +- from the VPU. There is a special driver for this with a separate DT node, +- which has the unfortunate consequence of breaking the act_led_gpio and +- act_led_activelow dtparams. +- +- This overlay changes the GPIO controller back to the standard one and +- restores the dtparams. +-*/ +- +-/{ +- compatible = "brcm,bcm2835"; +- +- fragment@0 { +- target = <&act_led>; +- frag0: __overlay__ { +- gpios = <&gpio 0 0>; +- }; +- }; +- +- __overrides__ { +- gpio = <&frag0>,"gpios:4"; +- activelow = <&frag0>,"gpios:8"; +- }; +-}; ++#include "act-led-overlay.dts" +--- a/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts ++++ b/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts +@@ -1,55 +1 @@ +-/dts-v1/; +-/plugin/; +- +-/* Disable Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15. +- To disable the systemd service that initialises the modem so it doesn't use +- the UART: +- +- sudo systemctl disable hciuart +-*/ +- +-/{ +- compatible = "brcm,bcm2835"; +- +- fragment@0 { +- target = <&uart1>; +- __overlay__ { +- status = "disabled"; +- }; +- }; +- +- fragment@1 { +- target = <&uart0>; +- __overlay__ { +- pinctrl-names = "default"; +- pinctrl-0 = <&uart0_pins>; +- status = "okay"; +- }; +- }; +- +- fragment@2 { +- target = <&uart0_pins>; +- __overlay__ { +- brcm,pins; +- brcm,function; +- brcm,pull; +- }; +- }; +- +- fragment@3 { +- target = <&bt_pins>; +- __overlay__ { +- brcm,pins; +- brcm,function; +- brcm,pull; +- }; +- }; +- +- fragment@4 { +- target-path = "/aliases"; +- __overlay__ { +- serial0 = "/soc/serial@7e201000"; +- serial1 = "/soc/serial@7e215040"; +- }; +- }; +-}; ++#include "disable-bt-overlay.dts" +--- a/arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts ++++ b/arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts +@@ -1,20 +1 @@ +-/dts-v1/; +-/plugin/; +- +-/{ +- compatible = "brcm,bcm2835"; +- +- fragment@0 { +- target = <&mmc>; +- __overlay__ { +- status = "disabled"; +- }; +- }; +- +- fragment@1 { +- target = <&mmcnr>; +- __overlay__ { +- status = "disabled"; +- }; +- }; +-}; ++#include "disable-wifi-overlay.dts" +--- a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts ++++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts +@@ -1,74 +1 @@ +-/dts-v1/; +-/plugin/; +- +-/* Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore +- UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum +- usable baudrate. +- +- It is also necessary to edit /lib/systemd/system/hciuart.service and +- replace ttyAMA0 with ttyS0, unless you have a system with udev rules +- that create /dev/serial0 and /dev/serial1, in which case use /dev/serial1 +- instead because it will always be correct. +- +- If cmdline.txt uses the alias serial0 to refer to the user-accessable port +- then the firmware will replace with the appropriate port whether or not +- this overlay is used. +-*/ +- +-/{ +- compatible = "brcm,bcm2835"; +- +- fragment@0 { +- target = <&uart0>; +- __overlay__ { +- pinctrl-names = "default"; +- pinctrl-0 = <&uart0_pins>; +- status = "okay"; +- }; +- }; +- +- fragment@1 { +- target = <&uart1>; +- __overlay__ { +- pinctrl-names = "default"; +- pinctrl-0 = <&uart1_pins &bt_pins &fake_bt_cts>; +- status = "okay"; +- }; +- }; +- +- fragment@2 { +- target = <&uart0_pins>; +- __overlay__ { +- brcm,pins; +- brcm,function; +- brcm,pull; +- }; +- }; +- +- fragment@3 { +- target = <&uart1_pins>; +- __overlay__ { +- brcm,pins = <32 33>; +- brcm,function = <2>; /* alt5=UART1 */ +- brcm,pull = <0 2>; +- }; +- }; +- +- fragment@4 { +- target = <&gpio>; +- __overlay__ { +- fake_bt_cts: fake_bt_cts { +- brcm,pins = <31>; +- brcm,function = <1>; /* output */ +- }; +- }; +- }; +- +- fragment@5 { +- target-path = "/aliases"; +- __overlay__ { +- serial0 = "/soc/serial@7e201000"; +- serial1 = "/soc/serial@7e215040"; +- }; +- }; +-}; ++#include "miniuart-bt-overlay.dts" diff --git a/target/linux/brcm2708/patches-4.19/950-0698-i2c-bcm2835-Move-IRQ-request-after-clock-code-in-pro.patch b/target/linux/brcm2708/patches-4.19/950-0698-i2c-bcm2835-Move-IRQ-request-after-clock-code-in-pro.patch new file mode 100644 index 0000000000..4590aa7607 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0698-i2c-bcm2835-Move-IRQ-request-after-clock-code-in-pro.patch @@ -0,0 +1,66 @@ +From bd66036c354e430b73ac9c0113ad6a0a787d66c1 Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Fri, 21 Jun 2019 03:52:49 -0700 +Subject: [PATCH 698/725] i2c: bcm2835: Move IRQ request after clock code in + probe + +Commit 4a5cfa39465cad25dd736d7ceba8a5d32eea4ecc upstream. + +If any of the clock code in the probe fails and returns, the IRQ +will not be freed. Moving the IRQ request to last allows it to +be freed on any errors further up in the probe function. devm_ +calls can apparently not be used because there are some potential +race conditions that will arise. + +Fixes: bebff81fb8b9 ("i2c: bcm2835: Model Divider in CCF") +Signed-off-by: Annaliese McDermond +Acked-by: Stefan Wahren +Signed-off-by: Wolfram Sang +--- + drivers/i2c/busses/i2c-bcm2835.c | 28 ++++++++++++++-------------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +--- a/drivers/i2c/busses/i2c-bcm2835.c ++++ b/drivers/i2c/busses/i2c-bcm2835.c +@@ -521,20 +521,6 @@ static int bcm2835_i2c_probe(struct plat + if (IS_ERR(i2c_dev->regs)) + return PTR_ERR(i2c_dev->regs); + +- irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); +- if (!irq) { +- dev_err(&pdev->dev, "No IRQ resource\n"); +- return -ENODEV; +- } +- i2c_dev->irq = irq->start; +- +- ret = request_irq(i2c_dev->irq, bcm2835_i2c_isr, IRQF_SHARED, +- dev_name(&pdev->dev), i2c_dev); +- if (ret) { +- dev_err(&pdev->dev, "Could not request IRQ\n"); +- return -ENODEV; +- } +- + mclk_name = of_clk_get_parent_name(pdev->dev.of_node, 0); + + bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk_name, i2c_dev); +@@ -564,6 +550,20 @@ static int bcm2835_i2c_probe(struct plat + return ret; + } + ++ irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); ++ if (!irq) { ++ dev_err(&pdev->dev, "No IRQ resource\n"); ++ return -ENODEV; ++ } ++ i2c_dev->irq = irq->start; ++ ++ ret = request_irq(i2c_dev->irq, bcm2835_i2c_isr, IRQF_SHARED, ++ dev_name(&pdev->dev), i2c_dev); ++ if (ret) { ++ dev_err(&pdev->dev, "Could not request IRQ\n"); ++ return -ENODEV; ++ } ++ + adap = &i2c_dev->adapter; + i2c_set_adapdata(adap, i2c_dev); + adap->owner = THIS_MODULE; diff --git a/target/linux/brcm2708/patches-4.19/950-0698-media-vb2-set-reqbufs-create_bufs-capabilities.patch b/target/linux/brcm2708/patches-4.19/950-0698-media-vb2-set-reqbufs-create_bufs-capabilities.patch deleted file mode 100644 index 9f46b93075..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0698-media-vb2-set-reqbufs-create_bufs-capabilities.patch +++ /dev/null @@ -1,190 +0,0 @@ -From af748ce92996933030288a0f85ca4775ad71edb0 Mon Sep 17 00:00:00 2001 -From: Hans Verkuil -Date: Thu, 23 Aug 2018 10:18:35 -0400 -Subject: [PATCH 698/703] media: vb2: set reqbufs/create_bufs capabilities - -Upstream commit e5079cf11373e4cc98be8b1072aece429eb2d4d2. - -Set the capabilities field of v4l2_requestbuffers and v4l2_create_buffers. - -The various mapping modes were easy, but for signaling the request capability -a new 'supports_requests' bitfield was added to videobuf2-core.h (and set in -vim2m and vivid). Drivers have to set this bitfield for any queue where -requests are supported. - -Signed-off-by: Hans Verkuil -Reviewed-by: Tomasz Figa -Acked-by: Sakari Ailus -Signed-off-by: Mauro Carvalho Chehab - -Minor modifications required on the backport ---- - drivers/media/common/videobuf2/videobuf2-v4l2.c | 17 +++++++++++++++++ - drivers/media/platform/vim2m.c | 1 + - drivers/media/platform/vivid/vivid-core.c | 5 +++++ - drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 4 +++- - drivers/media/v4l2-core/v4l2-ioctl.c | 4 ++-- - include/media/videobuf2-core.h | 2 ++ - 6 files changed, 30 insertions(+), 3 deletions(-) - ---- a/drivers/media/common/videobuf2/videobuf2-v4l2.c -+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c -@@ -482,10 +482,24 @@ int vb2_querybuf(struct vb2_queue *q, st - } - EXPORT_SYMBOL(vb2_querybuf); - -+static void fill_buf_caps(struct vb2_queue *q, u32 *caps) -+{ -+ *caps = 0; -+ if (q->io_modes & VB2_MMAP) -+ *caps |= V4L2_BUF_CAP_SUPPORTS_MMAP; -+ if (q->io_modes & VB2_USERPTR) -+ *caps |= V4L2_BUF_CAP_SUPPORTS_USERPTR; -+ if (q->io_modes & VB2_DMABUF) -+ *caps |= V4L2_BUF_CAP_SUPPORTS_DMABUF; -+ if (q->supports_requests) -+ *caps |= V4L2_BUF_CAP_SUPPORTS_REQUESTS; -+} -+ - int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) - { - int ret = vb2_verify_memory_type(q, req->memory, req->type); - -+ fill_buf_caps(q, &req->capabilities); - return ret ? ret : vb2_core_reqbufs(q, req->memory, &req->count); - } - EXPORT_SYMBOL_GPL(vb2_reqbufs); -@@ -513,6 +527,7 @@ int vb2_create_bufs(struct vb2_queue *q, - int ret = vb2_verify_memory_type(q, create->memory, f->type); - unsigned i; - -+ fill_buf_caps(q, &create->capabilities); - create->index = q->num_buffers; - if (create->count == 0) - return ret != -EBUSY ? ret : 0; -@@ -713,6 +728,7 @@ int vb2_ioctl_reqbufs(struct file *file, - struct video_device *vdev = video_devdata(file); - int res = vb2_verify_memory_type(vdev->queue, p->memory, p->type); - -+ fill_buf_caps(vdev->queue, &p->capabilities); - if (res) - return res; - if (vb2_queue_is_busy(vdev, file)) -@@ -734,6 +750,7 @@ int vb2_ioctl_create_bufs(struct file *f - p->format.type); - - p->index = vdev->queue->num_buffers; -+ fill_buf_caps(vdev->queue, &p->capabilities); - /* - * If count == 0, then just check if memory and type are valid. - * Any -EBUSY result from vb2_verify_memory_type can be mapped to 0. ---- a/drivers/media/platform/vim2m.c -+++ b/drivers/media/platform/vim2m.c -@@ -841,6 +841,7 @@ static int queue_init(void *priv, struct - src_vq->mem_ops = &vb2_vmalloc_memops; - src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; - src_vq->lock = &ctx->dev->dev_mutex; -+ src_vq->supports_requests = true; - - ret = vb2_queue_init(src_vq); - if (ret) ---- a/drivers/media/platform/vivid/vivid-core.c -+++ b/drivers/media/platform/vivid/vivid-core.c -@@ -1060,6 +1060,7 @@ static int vivid_create_instance(struct - q->min_buffers_needed = 2; - q->lock = &dev->mutex; - q->dev = dev->v4l2_dev.dev; -+ q->supports_requests = true; - - ret = vb2_queue_init(q); - if (ret) -@@ -1080,6 +1081,7 @@ static int vivid_create_instance(struct - q->min_buffers_needed = 2; - q->lock = &dev->mutex; - q->dev = dev->v4l2_dev.dev; -+ q->supports_requests = true; - - ret = vb2_queue_init(q); - if (ret) -@@ -1100,6 +1102,7 @@ static int vivid_create_instance(struct - q->min_buffers_needed = 2; - q->lock = &dev->mutex; - q->dev = dev->v4l2_dev.dev; -+ q->supports_requests = true; - - ret = vb2_queue_init(q); - if (ret) -@@ -1120,6 +1123,7 @@ static int vivid_create_instance(struct - q->min_buffers_needed = 2; - q->lock = &dev->mutex; - q->dev = dev->v4l2_dev.dev; -+ q->supports_requests = true; - - ret = vb2_queue_init(q); - if (ret) -@@ -1139,6 +1143,7 @@ static int vivid_create_instance(struct - q->min_buffers_needed = 8; - q->lock = &dev->mutex; - q->dev = dev->v4l2_dev.dev; -+ q->supports_requests = true; - - ret = vb2_queue_init(q); - if (ret) ---- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c -+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c -@@ -251,7 +251,8 @@ struct v4l2_create_buffers32 { - __u32 count; - __u32 memory; /* enum v4l2_memory */ - struct v4l2_format32 format; -- __u32 reserved[8]; -+ __u32 capabilities; -+ __u32 reserved[7]; - }; - - static int __bufsize_v4l2_format(struct v4l2_format32 __user *p32, u32 *size) -@@ -411,6 +412,7 @@ static int put_v4l2_create32(struct v4l2 - if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) || - copy_in_user(p32, p64, - offsetof(struct v4l2_create_buffers32, format)) || -+ assign_in_user(&p32->capabilities, &p64->capabilities) || - copy_in_user(p32->reserved, p64->reserved, sizeof(p64->reserved))) - return -EFAULT; - return __put_v4l2_format32(&p64->format, &p32->format); ---- a/drivers/media/v4l2-core/v4l2-ioctl.c -+++ b/drivers/media/v4l2-core/v4l2-ioctl.c -@@ -1879,7 +1879,7 @@ static int v4l_reqbufs(const struct v4l2 - if (ret) - return ret; - -- CLEAR_AFTER_FIELD(p, memory); -+ CLEAR_AFTER_FIELD(p, capabilities); - - return ops->vidioc_reqbufs(file, fh, p); - } -@@ -1920,7 +1920,7 @@ static int v4l_create_bufs(const struct - if (ret) - return ret; - -- CLEAR_AFTER_FIELD(create, format); -+ CLEAR_AFTER_FIELD(create, capabilities); - - v4l_sanitize_format(&create->format); - ---- a/include/media/videobuf2-core.h -+++ b/include/media/videobuf2-core.h -@@ -449,6 +449,7 @@ struct vb2_buf_ops { - * @quirk_poll_must_check_waiting_for_buffers: Return %EPOLLERR at poll when QBUF - * has not been called. This is a vb1 idiom that has been adopted - * also by vb2. -+ * @supports_requests: this queue supports the Request API. - * @lock: pointer to a mutex that protects the &struct vb2_queue. The - * driver can set this to a mutex to let the v4l2 core serialize - * the queuing ioctls. If the driver wants to handle locking -@@ -516,6 +517,7 @@ struct vb2_queue { - unsigned fileio_write_immediately:1; - unsigned allow_zero_bytesused:1; - unsigned quirk_poll_must_check_waiting_for_buffers:1; -+ unsigned supports_requests:1; - - struct mutex *lock; - void *owner; diff --git a/target/linux/brcm2708/patches-4.19/950-0699-i2c-bcm2835-Ensure-clock-exists-when-probing.patch b/target/linux/brcm2708/patches-4.19/950-0699-i2c-bcm2835-Ensure-clock-exists-when-probing.patch new file mode 100644 index 0000000000..b0653e14a8 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0699-i2c-bcm2835-Ensure-clock-exists-when-probing.patch @@ -0,0 +1,72 @@ +From 7da0d7cd3ee9b9e178873f380c47dda170fed67e Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond +Date: Fri, 21 Jun 2019 03:52:50 -0700 +Subject: [PATCH 699/725] i2c: bcm2835: Ensure clock exists when probing + +Commit 9de93b04df16b055824e3f1f13fedb90fbcf2e4f upstream. + +Probe function fails to recognize that upstream clock actually +doesn't yet exist because clock driver has not been initialized. +Actually try to go get the clock and test for its existence +before trying to set up a downstream clock based upon it. + +This fixes a bug that causes the i2c driver not to work with +monolithic kernels. + +Fixes: bebff81fb8b9 ("i2c: bcm2835: Model Divider in CCF") +Signed-off-by: Annaliese McDermond +Acked-by: Stefan Wahren +Signed-off-by: Wolfram Sang +--- + drivers/i2c/busses/i2c-bcm2835.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +--- a/drivers/i2c/busses/i2c-bcm2835.c ++++ b/drivers/i2c/busses/i2c-bcm2835.c +@@ -244,15 +244,18 @@ static const struct clk_ops clk_bcm2835_ + }; + + static struct clk *bcm2835_i2c_register_div(struct device *dev, +- const char *mclk_name, ++ struct clk *mclk, + struct bcm2835_i2c_dev *i2c_dev) + { + struct clk_init_data init; + struct clk_bcm2835_i2c *priv; + char name[32]; ++ const char *mclk_name; + + snprintf(name, sizeof(name), "%s_div", dev_name(dev)); + ++ mclk_name = __clk_get_name(mclk); ++ + init.ops = &clk_bcm2835_i2c_ops; + init.name = name; + init.parent_names = (const char* []) { mclk_name }; +@@ -505,8 +508,8 @@ static int bcm2835_i2c_probe(struct plat + struct resource *mem, *irq; + int ret; + struct i2c_adapter *adap; +- const char *mclk_name; + struct clk *bus_clk; ++ struct clk *mclk; + u32 bus_clk_rate; + + i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); +@@ -521,9 +524,14 @@ static int bcm2835_i2c_probe(struct plat + if (IS_ERR(i2c_dev->regs)) + return PTR_ERR(i2c_dev->regs); + +- mclk_name = of_clk_get_parent_name(pdev->dev.of_node, 0); ++ mclk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(mclk)) { ++ if (PTR_ERR(mclk) != -EPROBE_DEFER) ++ dev_err(&pdev->dev, "Could not get clock\n"); ++ return PTR_ERR(mclk); ++ } + +- bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk_name, i2c_dev); ++ bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk, i2c_dev); + + if (IS_ERR(bus_clk)) { + dev_err(&pdev->dev, "Could not register clock\n"); diff --git a/target/linux/brcm2708/patches-4.19/950-0699-media-vb2-Allow-reqbufs-0-with-in-use-MMAP-buffers.patch b/target/linux/brcm2708/patches-4.19/950-0699-media-vb2-Allow-reqbufs-0-with-in-use-MMAP-buffers.patch deleted file mode 100644 index 145fd71a09..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0699-media-vb2-Allow-reqbufs-0-with-in-use-MMAP-buffers.patch +++ /dev/null @@ -1,130 +0,0 @@ -From b0102490b31330eb694a7956e1874e172ad07ec1 Mon Sep 17 00:00:00 2001 -From: John Sheu -Date: Thu, 15 Nov 2018 10:57:16 -0500 -Subject: [PATCH 699/703] media: vb2: Allow reqbufs(0) with "in use" MMAP - buffers - -Upstream commit d644cca50f366cd109845ae92e37c09ed79adf81 - -Videobuf2 presently does not allow VIDIOC_REQBUFS to destroy outstanding -buffers if the queue is of type V4L2_MEMORY_MMAP, and if the buffers are -considered "in use". This is different behavior than for other memory -types and prevents us from deallocating buffers in following two cases: - -1) There are outstanding mmap()ed views on the buffer. However even if - we put the buffer in reqbufs(0), there will be remaining references, - due to vma .open/close() adjusting vb2 buffer refcount appropriately. - This means that the buffer will be in fact freed only when the last - mmap()ed view is unmapped. - -2) Buffer has been exported as a DMABUF. Refcount of the vb2 buffer - is managed properly by VB2 DMABUF ops, i.e. incremented on DMABUF - get and decremented on DMABUF release. This means that the buffer - will be alive until all importers release it. - -Considering both cases above, there does not seem to be any need to -prevent reqbufs(0) operation, because buffer lifetime is already -properly managed by both mmap() and DMABUF code paths. Let's remove it -and allow userspace freeing the queue (and potentially allocating a new -one) even though old buffers might be still in processing. - -To let userspace know that the kernel now supports orphaning buffers -that are still in use, add a new V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS -to be set by reqbufs and create_bufs. - -[p.zabel@pengutronix.de: added V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS, - updated documentation, and added back debug message] - -Signed-off-by: John Sheu -Reviewed-by: Pawel Osciak -Signed-off-by: Tomasz Figa -Signed-off-by: Philipp Zabel -Acked-by: Sakari Ailus -Signed-off-by: Hans Verkuil -[hverkuil-cisco@xs4all.nl: added V4L2-BUF-CAP-SUPPORTS-ORPHANED-BUFS ref] -Signed-off-by: Mauro Carvalho Chehab ---- - Documentation/media/uapi/v4l/vidioc-reqbufs.rst | 17 ++++++++++++++--- - drivers/media/common/videobuf2/videobuf2-core.c | 8 +++----- - drivers/media/common/videobuf2/videobuf2-v4l2.c | 2 +- - include/uapi/linux/videodev2.h | 1 + - 4 files changed, 19 insertions(+), 9 deletions(-) - ---- a/Documentation/media/uapi/v4l/vidioc-reqbufs.rst -+++ b/Documentation/media/uapi/v4l/vidioc-reqbufs.rst -@@ -59,9 +59,14 @@ When the I/O method is not supported the - code. - - Applications can call :ref:`VIDIOC_REQBUFS` again to change the number of --buffers, however this cannot succeed when any buffers are still mapped. --A ``count`` value of zero frees all buffers, after aborting or finishing --any DMA in progress, an implicit -+buffers. Note that if any buffers are still mapped or exported via DMABUF, -+then :ref:`VIDIOC_REQBUFS` can only succeed if the -+``V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS`` capability is set. Otherwise -+:ref:`VIDIOC_REQBUFS` will return the ``EBUSY`` error code. -+If ``V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS`` is set, then these buffers are -+orphaned and will be freed when they are unmapped or when the exported DMABUF -+fds are closed. A ``count`` value of zero frees or orphans all buffers, after -+aborting or finishing any DMA in progress, an implicit - :ref:`VIDIOC_STREAMOFF `. - - -@@ -112,6 +117,7 @@ any DMA in progress, an implicit - .. _V4L2-BUF-CAP-SUPPORTS-USERPTR: - .. _V4L2-BUF-CAP-SUPPORTS-DMABUF: - .. _V4L2-BUF-CAP-SUPPORTS-REQUESTS: -+.. _V4L2-BUF-CAP-SUPPORTS-ORPHANED-BUFS: - - .. cssclass:: longtable - -@@ -132,6 +138,11 @@ any DMA in progress, an implicit - * - ``V4L2_BUF_CAP_SUPPORTS_REQUESTS`` - - 0x00000008 - - This buffer type supports :ref:`requests `. -+ * - ``V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS`` -+ - 0x00000010 -+ - The kernel allows calling :ref:`VIDIOC_REQBUFS` while buffers are still -+ mapped or exported via DMABUF. These orphaned buffers will be freed -+ when they are unmapped or when the exported DMABUF fds are closed. - - Return Value - ============ ---- a/drivers/media/common/videobuf2/videobuf2-core.c -+++ b/drivers/media/common/videobuf2/videobuf2-core.c -@@ -684,11 +684,9 @@ int vb2_core_reqbufs(struct vb2_queue *q - * are not in use and can be freed. - */ - mutex_lock(&q->mmap_lock); -- if (q->memory == VB2_MEMORY_MMAP && __buffers_in_use(q)) { -- mutex_unlock(&q->mmap_lock); -- dprintk(1, "memory in use, cannot free\n"); -- return -EBUSY; -- } -+ if (debug && q->memory == VB2_MEMORY_MMAP && -+ __buffers_in_use(q)) -+ dprintk(1, "memory in use, orphaning buffers\n"); - - /* - * Call queue_cancel to clean up any buffers in the PREPARED or ---- a/drivers/media/common/videobuf2/videobuf2-v4l2.c -+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c -@@ -484,7 +484,7 @@ EXPORT_SYMBOL(vb2_querybuf); - - static void fill_buf_caps(struct vb2_queue *q, u32 *caps) - { -- *caps = 0; -+ *caps = V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS; - if (q->io_modes & VB2_MMAP) - *caps |= V4L2_BUF_CAP_SUPPORTS_MMAP; - if (q->io_modes & VB2_USERPTR) ---- a/include/uapi/linux/videodev2.h -+++ b/include/uapi/linux/videodev2.h -@@ -881,6 +881,7 @@ struct v4l2_requestbuffers { - #define V4L2_BUF_CAP_SUPPORTS_USERPTR (1 << 1) - #define V4L2_BUF_CAP_SUPPORTS_DMABUF (1 << 2) - #define V4L2_BUF_CAP_SUPPORTS_REQUESTS (1 << 3) -+#define V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS (1 << 4) - - /** - * struct v4l2_plane - plane info for multi-planar buffers diff --git a/target/linux/brcm2708/patches-4.19/950-0700-overlays-Add-real-parameters-to-the-rpi-poe-overlay.patch b/target/linux/brcm2708/patches-4.19/950-0700-overlays-Add-real-parameters-to-the-rpi-poe-overlay.patch deleted file mode 100644 index e899312514..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0700-overlays-Add-real-parameters-to-the-rpi-poe-overlay.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 3476202ad0c40d466df8c82798b0ccb0a5e6ed8f Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 5 Jul 2019 09:22:10 +0100 -Subject: [PATCH 700/703] overlays: Add real parameters to the rpi-poe overlay - -As a result of being loaded by the POE HAT EEPROM, the rpi-poe overlay -doesn't expose parameters in the usual way; instead it adds them to -the base Device Tree, and the user is expected to use "dtparam=..." -to access them. - -To make the documentation correct and to protect users who load the -overlay explicitly, expecting to be able to use the parameters, add -real parameters to the overlay as well. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/rpi-poe-overlay.dts | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/arch/arm/boot/dts/overlays/rpi-poe-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-poe-overlay.dts -@@ -60,4 +60,11 @@ - poe_fan_temp1_hyst = <&trip1>,"hysteresis:0"; - }; - }; -+ -+ __overrides__ { -+ poe_fan_temp0 = <&trip0>,"temperature:0"; -+ poe_fan_temp0_hyst = <&trip0>,"hysteresis:0"; -+ poe_fan_temp1 = <&trip1>,"temperature:0"; -+ poe_fan_temp1_hyst = <&trip1>,"hysteresis:0"; -+ }; - }; diff --git a/target/linux/brcm2708/patches-4.19/950-0700-overlays-i2c-gpio-Fix-the-bus-parameter.patch b/target/linux/brcm2708/patches-4.19/950-0700-overlays-i2c-gpio-Fix-the-bus-parameter.patch new file mode 100644 index 0000000000..81b9c71a52 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0700-overlays-i2c-gpio-Fix-the-bus-parameter.patch @@ -0,0 +1,35 @@ +From 55672983dee952815d614651a92f76044785ca46 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 9 Jul 2019 10:32:40 +0100 +Subject: [PATCH 700/725] overlays: i2c-gpio: Fix the "bus" parameter + +The "bus" parameter has two functions - providing unique names for +multiple instances of the overlay, and allowing the number of the bus +(i.e. "i2c-") to be specified. The second function hasn't worked +as intended because the overlay doesn't include a "reg" property and +the firmware intentionally won't create a "reg" property if one doesn't +already exist. + +Allow the bus numbering scheme to work as intended by providing a "reg" +with a default value that means "the next available one". + +See: https://github.com/raspberrypi/linux/issues/3062 + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts +@@ -7,8 +7,10 @@ + + fragment@0 { + target-path = "/"; ++ + __overlay__ { + i2c_gpio: i2c@0 { ++ reg = <0xffffffff>; + compatible = "i2c-gpio"; + gpios = <&gpio 23 0 /* sda */ + &gpio 24 0 /* scl */ diff --git a/target/linux/brcm2708/patches-4.19/950-0701-overlays-Rename-pi3-overlays-to-be-less-model-specif.patch b/target/linux/brcm2708/patches-4.19/950-0701-overlays-Rename-pi3-overlays-to-be-less-model-specif.patch deleted file mode 100644 index ef614a4eee..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0701-overlays-Rename-pi3-overlays-to-be-less-model-specif.patch +++ /dev/null @@ -1,587 +0,0 @@ -From 2683773c8d2092083bafbc64fe7e6a25c48b8f5f Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 5 Jul 2019 14:49:22 +0100 -Subject: [PATCH 701/703] overlays: Rename pi3- overlays to be less - model-specific (#3052) - -Rename the various pi3- overlays to be more generic, listing -the devices they apply to in the README. The original names are -retained for backwards compatibility as files that just include -the new versions - the README marks them as being deprecated. - -See: https://github.com/raspberrypi/firmware/issues/1174 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/Makefile | 4 + - arch/arm/boot/dts/overlays/README | 97 ++++++++++++------- - .../arm/boot/dts/overlays/act-led-overlay.dts | 27 ++++++ - .../boot/dts/overlays/disable-bt-overlay.dts | 55 +++++++++++ - .../dts/overlays/disable-wifi-overlay.dts | 20 ++++ - .../boot/dts/overlays/miniuart-bt-overlay.dts | 74 ++++++++++++++ - .../boot/dts/overlays/pi3-act-led-overlay.dts | 28 +----- - .../dts/overlays/pi3-disable-bt-overlay.dts | 56 +---------- - .../dts/overlays/pi3-disable-wifi-overlay.dts | 21 +--- - .../dts/overlays/pi3-miniuart-bt-overlay.dts | 75 +------------- - 10 files changed, 246 insertions(+), 211 deletions(-) - create mode 100644 arch/arm/boot/dts/overlays/act-led-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/disable-bt-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/disable-wifi-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/miniuart-bt-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -1,6 +1,7 @@ - # Overlays for the Raspberry Pi platform - - dtbo-$(CONFIG_ARCH_BCM2835) += \ -+ act-led.dtbo \ - adau1977-adc.dtbo \ - adau7002-simple.dtbo \ - ads1015.dtbo \ -@@ -26,6 +27,8 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - dht11.dtbo \ - dionaudio-loco.dtbo \ - dionaudio-loco-v2.dtbo \ -+ disable-bt.dtbo \ -+ disable-wifi.dtbo \ - dpi18.dtbo \ - dpi24.dtbo \ - draws.dtbo \ -@@ -91,6 +94,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - media-center.dtbo \ - midi-uart0.dtbo \ - midi-uart1.dtbo \ -+ miniuart-bt.dtbo \ - mmc.dtbo \ - mpu6050.dtbo \ - mz61581.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -180,14 +180,16 @@ Params: - - act_led_activelow Set to "on" to invert the sense of the LED - (default "off") -- N.B. For Pi3 see pi3-act-led overlay. -+ N.B. For Pi 3B, 3B+, 3A+ and 4B, use the act-led -+ overlay. - - act_led_gpio Set which GPIO to use for the activity LED - (in case you want to connect it to an external - device) - (default "16" on a non-Plus board, "47" on a - Plus or Pi 2) -- N.B. For Pi3 see pi3-act-led overlay. -+ N.B. For Pi 3B, 3B+, 3A+ and 4B, use the act-led -+ overlay. - - pwr_led_trigger - pwr_led_activelow -@@ -205,6 +207,23 @@ Params: - and the other i2c baudrate parameters. - - -+Name: act-led -+Info: Pi 3B, 3B+, 3A+ and 4B use a GPIO expander to drive the LEDs which can -+ only be accessed from the VPU. There is a special driver for this with a -+ separate DT node, which has the unfortunate consequence of breaking the -+ act_led_gpio and act_led_activelow dtparams. -+ This overlay changes the GPIO controller back to the standard one and -+ restores the dtparams. -+Load: dtoverlay=act-led,= -+Params: activelow Set to "on" to invert the sense of the LED -+ (default "off") -+ -+ gpio Set which GPIO to use for the activity LED -+ (in case you want to connect it to an external -+ device) -+ REQUIRED -+ -+ - Name: adau1977-adc - Info: Overlay for activation of ADAU1977 ADC codec over I2C for control - and I2S for data. -@@ -509,6 +528,21 @@ Params: 24db_digital_gain Allow ga - that does not result in clipping/distortion!) - - -+Name: disable-bt -+Info: Disable onboard Bluetooth on Pi 3B, 3B+, 3A+, 4B and Zero W, restoring -+ UART0/ttyAMA0 over GPIOs 14 & 15. -+ N.B. To disable the systemd service that initialises the modem so it -+ doesn't use the UART, use 'sudo systemctl disable hciuart'. -+Load: dtoverlay=disable-bt -+Params: -+ -+ -+Name: disable-wifi -+Info: Disable onboard WiFi on Pi 3B, 3B+, 3A+, 4B and Zero W. -+Load: dtoverlay=disable-wifi -+Params: -+ -+ - 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 -@@ -1447,6 +1481,20 @@ Load: dtoverlay=midi-uart1 - Params: - - -+Name: miniuart-bt -+Info: Switch the onboard Bluetooth function on Pi 3B, 3B+, 3A+, 4B and Zero W -+ to use the mini-UART (ttyS0) and restore UART0/ttyAMA0 over GPIOs 14 & -+ 15. Note that this may reduce the maximum usable baudrate. -+ N.B. It is also necessary to edit /lib/systemd/system/hciuart.service -+ and replace ttyAMA0 with ttyS0, unless using Raspbian or another -+ distribution with udev rules that create /dev/serial0 and /dev/serial1, -+ in which case use /dev/serial1 instead because it will always be -+ correct. Furthermore, you must also set core_freq and core_freq_min to -+ the same value in config.txt or the miniuart will not work. -+Load: dtoverlay=miniuart-bt -+Params: -+ -+ - Name: mmc - Info: Selects the bcm2835-mmc SD/MMC driver, optionally with overclock - Load: dtoverlay=mmc,= -@@ -1509,48 +1557,27 @@ Params: panel Display - - - Name: pi3-act-led --Info: Pi3 uses a GPIO expander to drive the LEDs which can only be accessed -- from the VPU. There is a special driver for this with a separate DT -- node, which has the unfortunate consequence of breaking the -- act_led_gpio and act_led_activelow dtparams. -- This overlay changes the GPIO controller back to the standard one and -- restores the dtparams. --Load: dtoverlay=pi3-act-led,= --Params: activelow Set to "on" to invert the sense of the LED -- (default "off") -- -- gpio Set which GPIO to use for the activity LED -- (in case you want to connect it to an external -- device) -- REQUIRED -+Info: This overlay has been renamed act-led, keeping pi3-act-led as an alias -+ for backwards compatibility. -+Load: - - - Name: pi3-disable-bt --Info: Disable Pi3 Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15 -- N.B. To disable the systemd service that initialises the modem so it -- doesn't use the UART, use 'sudo systemctl disable hciuart'. --Load: dtoverlay=pi3-disable-bt --Params: -+Info: This overlay has been renamed disable-bt, keeping pi3-disable-bt as an -+ alias for backwards compatibility. -+Load: - - - Name: pi3-disable-wifi --Info: Disable Pi3 onboard WiFi --Load: dtoverlay=pi3-disable-wifi --Params: -+Info: This overlay has been renamed disable-wifi, keeping pi3-disable-wifi as -+ an alias for backwards compatibility. -+Load: - - - Name: pi3-miniuart-bt --Info: Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore -- UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum -- usable baudrate. -- N.B. It is also necessary to edit /lib/systemd/system/hciuart.service -- and replace ttyAMA0 with ttyS0, unless you have a system with udev rules -- that create /dev/serial0 and /dev/serial1, in which case use -- /dev/serial1 instead because it will always be correct. Furthermore, -- you must also set core_freq=250 in config.txt or the miniuart will not -- work. --Load: dtoverlay=pi3-miniuart-bt --Params: -+Info: This overlay has been renamed miniuart-bt, keeping pi3-miniuart-bt as -+ an alias for backwards compatibility. -+Load: - - - Name: pibell ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/act-led-overlay.dts -@@ -0,0 +1,27 @@ -+/dts-v1/; -+/plugin/; -+ -+/* Pi3 uses a GPIO expander to drive the LEDs which can only be accessed -+ from the VPU. There is a special driver for this with a separate DT node, -+ which has the unfortunate consequence of breaking the act_led_gpio and -+ act_led_activelow dtparams. -+ -+ This overlay changes the GPIO controller back to the standard one and -+ restores the dtparams. -+*/ -+ -+/{ -+ compatible = "brcm,bcm2835"; -+ -+ fragment@0 { -+ target = <&act_led>; -+ frag0: __overlay__ { -+ gpios = <&gpio 0 0>; -+ }; -+ }; -+ -+ __overrides__ { -+ gpio = <&frag0>,"gpios:4"; -+ activelow = <&frag0>,"gpios:8"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/disable-bt-overlay.dts -@@ -0,0 +1,55 @@ -+/dts-v1/; -+/plugin/; -+ -+/* Disable Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15. -+ To disable the systemd service that initialises the modem so it doesn't use -+ the UART: -+ -+ sudo systemctl disable hciuart -+*/ -+ -+/{ -+ compatible = "brcm,bcm2835"; -+ -+ fragment@0 { -+ target = <&uart1>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&uart0>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&uart0_pins>; -+ __overlay__ { -+ brcm,pins; -+ brcm,function; -+ brcm,pull; -+ }; -+ }; -+ -+ fragment@3 { -+ target = <&bt_pins>; -+ __overlay__ { -+ brcm,pins; -+ brcm,function; -+ brcm,pull; -+ }; -+ }; -+ -+ fragment@4 { -+ target-path = "/aliases"; -+ __overlay__ { -+ serial0 = "/soc/serial@7e201000"; -+ serial1 = "/soc/serial@7e215040"; -+ }; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/disable-wifi-overlay.dts -@@ -0,0 +1,20 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2835"; -+ -+ fragment@0 { -+ target = <&mmc>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&mmcnr>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/miniuart-bt-overlay.dts -@@ -0,0 +1,74 @@ -+/dts-v1/; -+/plugin/; -+ -+/* Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore -+ UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum -+ usable baudrate. -+ -+ It is also necessary to edit /lib/systemd/system/hciuart.service and -+ replace ttyAMA0 with ttyS0, unless you have a system with udev rules -+ that create /dev/serial0 and /dev/serial1, in which case use /dev/serial1 -+ instead because it will always be correct. -+ -+ If cmdline.txt uses the alias serial0 to refer to the user-accessable port -+ then the firmware will replace with the appropriate port whether or not -+ this overlay is used. -+*/ -+ -+/{ -+ compatible = "brcm,bcm2835"; -+ -+ fragment@0 { -+ target = <&uart0>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&uart1>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart1_pins &bt_pins &fake_bt_cts>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&uart0_pins>; -+ __overlay__ { -+ brcm,pins; -+ brcm,function; -+ brcm,pull; -+ }; -+ }; -+ -+ fragment@3 { -+ target = <&uart1_pins>; -+ __overlay__ { -+ brcm,pins = <32 33>; -+ brcm,function = <2>; /* alt5=UART1 */ -+ brcm,pull = <0 2>; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&gpio>; -+ __overlay__ { -+ fake_bt_cts: fake_bt_cts { -+ brcm,pins = <31>; -+ brcm,function = <1>; /* output */ -+ }; -+ }; -+ }; -+ -+ fragment@5 { -+ target-path = "/aliases"; -+ __overlay__ { -+ serial0 = "/soc/serial@7e201000"; -+ serial1 = "/soc/serial@7e215040"; -+ }; -+ }; -+}; ---- a/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-act-led-overlay.dts -@@ -1,27 +1 @@ --/dts-v1/; --/plugin/; -- --/* Pi3 uses a GPIO expander to drive the LEDs which can only be accessed -- from the VPU. There is a special driver for this with a separate DT node, -- which has the unfortunate consequence of breaking the act_led_gpio and -- act_led_activelow dtparams. -- -- This overlay changes the GPIO controller back to the standard one and -- restores the dtparams. --*/ -- --/{ -- compatible = "brcm,bcm2835"; -- -- fragment@0 { -- target = <&act_led>; -- frag0: __overlay__ { -- gpios = <&gpio 0 0>; -- }; -- }; -- -- __overrides__ { -- gpio = <&frag0>,"gpios:4"; -- activelow = <&frag0>,"gpios:8"; -- }; --}; -+#include "act-led-overlay.dts" ---- a/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-disable-bt-overlay.dts -@@ -1,55 +1 @@ --/dts-v1/; --/plugin/; -- --/* Disable Bluetooth and restore UART0/ttyAMA0 over GPIOs 14 & 15. -- To disable the systemd service that initialises the modem so it doesn't use -- the UART: -- -- sudo systemctl disable hciuart --*/ -- --/{ -- compatible = "brcm,bcm2835"; -- -- fragment@0 { -- target = <&uart1>; -- __overlay__ { -- status = "disabled"; -- }; -- }; -- -- fragment@1 { -- target = <&uart0>; -- __overlay__ { -- pinctrl-names = "default"; -- pinctrl-0 = <&uart0_pins>; -- status = "okay"; -- }; -- }; -- -- fragment@2 { -- target = <&uart0_pins>; -- __overlay__ { -- brcm,pins; -- brcm,function; -- brcm,pull; -- }; -- }; -- -- fragment@3 { -- target = <&bt_pins>; -- __overlay__ { -- brcm,pins; -- brcm,function; -- brcm,pull; -- }; -- }; -- -- fragment@4 { -- target-path = "/aliases"; -- __overlay__ { -- serial0 = "/soc/serial@7e201000"; -- serial1 = "/soc/serial@7e215040"; -- }; -- }; --}; -+#include "disable-bt-overlay.dts" ---- a/arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-disable-wifi-overlay.dts -@@ -1,20 +1 @@ --/dts-v1/; --/plugin/; -- --/{ -- compatible = "brcm,bcm2835"; -- -- fragment@0 { -- target = <&mmc>; -- __overlay__ { -- status = "disabled"; -- }; -- }; -- -- fragment@1 { -- target = <&mmcnr>; -- __overlay__ { -- status = "disabled"; -- }; -- }; --}; -+#include "disable-wifi-overlay.dts" ---- a/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pi3-miniuart-bt-overlay.dts -@@ -1,74 +1 @@ --/dts-v1/; --/plugin/; -- --/* Switch Pi3 Bluetooth function to use the mini-UART (ttyS0) and restore -- UART0/ttyAMA0 over GPIOs 14 & 15. Note that this may reduce the maximum -- usable baudrate. -- -- It is also necessary to edit /lib/systemd/system/hciuart.service and -- replace ttyAMA0 with ttyS0, unless you have a system with udev rules -- that create /dev/serial0 and /dev/serial1, in which case use /dev/serial1 -- instead because it will always be correct. -- -- If cmdline.txt uses the alias serial0 to refer to the user-accessable port -- then the firmware will replace with the appropriate port whether or not -- this overlay is used. --*/ -- --/{ -- compatible = "brcm,bcm2835"; -- -- fragment@0 { -- target = <&uart0>; -- __overlay__ { -- pinctrl-names = "default"; -- pinctrl-0 = <&uart0_pins>; -- status = "okay"; -- }; -- }; -- -- fragment@1 { -- target = <&uart1>; -- __overlay__ { -- pinctrl-names = "default"; -- pinctrl-0 = <&uart1_pins &bt_pins &fake_bt_cts>; -- status = "okay"; -- }; -- }; -- -- fragment@2 { -- target = <&uart0_pins>; -- __overlay__ { -- brcm,pins; -- brcm,function; -- brcm,pull; -- }; -- }; -- -- fragment@3 { -- target = <&uart1_pins>; -- __overlay__ { -- brcm,pins = <32 33>; -- brcm,function = <2>; /* alt5=UART1 */ -- brcm,pull = <0 2>; -- }; -- }; -- -- fragment@4 { -- target = <&gpio>; -- __overlay__ { -- fake_bt_cts: fake_bt_cts { -- brcm,pins = <31>; -- brcm,function = <1>; /* output */ -- }; -- }; -- }; -- -- fragment@5 { -- target-path = "/aliases"; -- __overlay__ { -- serial0 = "/soc/serial@7e201000"; -- serial1 = "/soc/serial@7e215040"; -- }; -- }; --}; -+#include "miniuart-bt-overlay.dts" diff --git a/target/linux/brcm2708/patches-4.19/950-0701-tty-amba-pl011-Make-TX-optimisation-conditional.patch b/target/linux/brcm2708/patches-4.19/950-0701-tty-amba-pl011-Make-TX-optimisation-conditional.patch new file mode 100644 index 0000000000..add8140f7d --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0701-tty-amba-pl011-Make-TX-optimisation-conditional.patch @@ -0,0 +1,85 @@ +From e70cb8a67901499d75f4ed4d5bd120a1ceace698 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 11 Jul 2019 13:13:39 +0100 +Subject: [PATCH 701/725] tty: amba-pl011: Make TX optimisation conditional + +pl011_tx_chars takes a "from_irq" parameter to reduce the number of +register accesses. When from_irq is true the function assumes that the +FIFO is half empty and writes up to half a FIFO's worth of bytes +without polling the FIFO status register, the reasoning being that +the function is being called as a result of the TX interrupt being +raised. This logic would work were it not for the fact that +pl011_rx_chars, called from pl011_int before pl011_tx_chars, releases +the spinlock before calling tty_flip_buffer_push. + +A user thread writing to the UART claims the spinlock and ultimately +calls pl011_tx_chars with from_irq set to false. This reverts to the +older logic that polls the FIFO status register before sending every +byte. If this happen on an SMP system during the section of the IRQ +handler where the spinlock has been released, then by the time the TX +interrupt handler is called, the FIFO may already be full, and any +further writes are likely to be lost. + +The fix involves adding a per-port flag that is true iff running from +within the interrupt handler and the spinlock has not yet been released. +This flag is then used as the value for the from_irq parameter of +pl011_tx_chars, causing polling to be used in the unsafe case. + +Fixes: 1e84d22322ce ("serial/amba-pl011: Refactor and simplify TX FIFO handling") + +Signed-off-by: Phil Elwell +--- + drivers/tty/serial/amba-pl011.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -270,6 +270,7 @@ struct uart_amba_port { + unsigned int old_cr; /* state during shutdown */ + unsigned int fixed_baud; /* vendor-set fixed baud rate */ + char type[12]; ++ bool irq_locked; /* in irq, unreleased lock */ + #ifdef CONFIG_DMA_ENGINE + /* DMA stuff */ + bool using_tx_dma; +@@ -814,6 +815,7 @@ __acquires(&uap->port.lock) + return; + + /* Avoid deadlock with the DMA engine callback */ ++ uap->irq_locked = 0; + spin_unlock(&uap->port.lock); + dmaengine_terminate_all(uap->dmatx.chan); + spin_lock(&uap->port.lock); +@@ -941,6 +943,7 @@ static void pl011_dma_rx_chars(struct ua + fifotaken = pl011_fifo_to_tty(uap); + } + ++ uap->irq_locked = 0; + spin_unlock(&uap->port.lock); + dev_vdbg(uap->port.dev, + "Took %d chars from DMA buffer and %d chars from the FIFO\n", +@@ -1349,6 +1352,7 @@ __acquires(&uap->port.lock) + { + pl011_fifo_to_tty(uap); + ++ uap->irq_locked = 0; + spin_unlock(&uap->port.lock); + tty_flip_buffer_push(&uap->port.state->port); + /* +@@ -1484,6 +1488,7 @@ static irqreturn_t pl011_int(int irq, vo + int handled = 0; + + spin_lock_irqsave(&uap->port.lock, flags); ++ uap->irq_locked = 1; + status = pl011_read(uap, REG_RIS) & uap->im; + if (status) { + do { +@@ -1503,7 +1508,7 @@ static irqreturn_t pl011_int(int irq, vo + UART011_CTSMIS|UART011_RIMIS)) + pl011_modem_status(uap); + if (status & UART011_TXIS) +- pl011_tx_chars(uap, true); ++ pl011_tx_chars(uap, uap->irq_locked); + + if (pass_counter-- == 0) + break; diff --git a/target/linux/brcm2708/patches-4.19/950-0702-i2c-bcm2835-Move-IRQ-request-after-clock-code-in-pro.patch b/target/linux/brcm2708/patches-4.19/950-0702-i2c-bcm2835-Move-IRQ-request-after-clock-code-in-pro.patch deleted file mode 100644 index 6215f3e6eb..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0702-i2c-bcm2835-Move-IRQ-request-after-clock-code-in-pro.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 4baf16fc6d22fd948a597993d858d4de0c5b3bcc Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Fri, 21 Jun 2019 03:52:49 -0700 -Subject: [PATCH 702/703] i2c: bcm2835: Move IRQ request after clock code in - probe - -Commit 4a5cfa39465cad25dd736d7ceba8a5d32eea4ecc upstream. - -If any of the clock code in the probe fails and returns, the IRQ -will not be freed. Moving the IRQ request to last allows it to -be freed on any errors further up in the probe function. devm_ -calls can apparently not be used because there are some potential -race conditions that will arise. - -Fixes: bebff81fb8b9 ("i2c: bcm2835: Model Divider in CCF") -Signed-off-by: Annaliese McDermond -Acked-by: Stefan Wahren -Signed-off-by: Wolfram Sang ---- - drivers/i2c/busses/i2c-bcm2835.c | 28 ++++++++++++++-------------- - 1 file changed, 14 insertions(+), 14 deletions(-) - ---- a/drivers/i2c/busses/i2c-bcm2835.c -+++ b/drivers/i2c/busses/i2c-bcm2835.c -@@ -521,20 +521,6 @@ static int bcm2835_i2c_probe(struct plat - if (IS_ERR(i2c_dev->regs)) - return PTR_ERR(i2c_dev->regs); - -- irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); -- if (!irq) { -- dev_err(&pdev->dev, "No IRQ resource\n"); -- return -ENODEV; -- } -- i2c_dev->irq = irq->start; -- -- ret = request_irq(i2c_dev->irq, bcm2835_i2c_isr, IRQF_SHARED, -- dev_name(&pdev->dev), i2c_dev); -- if (ret) { -- dev_err(&pdev->dev, "Could not request IRQ\n"); -- return -ENODEV; -- } -- - mclk_name = of_clk_get_parent_name(pdev->dev.of_node, 0); - - bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk_name, i2c_dev); -@@ -564,6 +550,20 @@ static int bcm2835_i2c_probe(struct plat - return ret; - } - -+ irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); -+ if (!irq) { -+ dev_err(&pdev->dev, "No IRQ resource\n"); -+ return -ENODEV; -+ } -+ i2c_dev->irq = irq->start; -+ -+ ret = request_irq(i2c_dev->irq, bcm2835_i2c_isr, IRQF_SHARED, -+ dev_name(&pdev->dev), i2c_dev); -+ if (ret) { -+ dev_err(&pdev->dev, "Could not request IRQ\n"); -+ return -ENODEV; -+ } -+ - adap = &i2c_dev->adapter; - i2c_set_adapdata(adap, i2c_dev); - adap->owner = THIS_MODULE; diff --git a/target/linux/brcm2708/patches-4.19/950-0702-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch b/target/linux/brcm2708/patches-4.19/950-0702-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch new file mode 100644 index 0000000000..7a71acd78c --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0702-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch @@ -0,0 +1,90 @@ +From 92900af9134a2e5435ee68d69cdd23d1f8cb4980 Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Thu, 11 Jul 2019 17:55:43 +0100 +Subject: [PATCH 702/725] xhci: add quirk for host controllers that don't + update endpoint DCS + +Seen on a VLI VL805 PCIe to USB controller. For non-stream endpoints +at least, if the xHC halts on a particular TRB due to an error then +the DCS field in the Out Endpoint Context maintained by the hardware +is not updated with the current cycle state. + +Using the quirk XHCI_EP_CTX_BROKEN_DCS and instead fetch the DCS bit +from the TRB that the xHC stopped on. + +See: https://github.com/raspberrypi/linux/issues/3060 + +Signed-off-by: Jonathan Bell +--- + drivers/usb/host/xhci-pci.c | 4 +++- + drivers/usb/host/xhci-ring.c | 26 +++++++++++++++++++++++++- + drivers/usb/host/xhci.h | 1 + + 3 files changed, 29 insertions(+), 2 deletions(-) + +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -223,8 +223,10 @@ static void xhci_pci_quirks(struct devic + xhci->quirks |= XHCI_BROKEN_STREAMS; + + if (pdev->vendor == PCI_VENDOR_ID_VIA && +- pdev->device == 0x3483) ++ pdev->device == 0x3483) { + xhci->quirks |= XHCI_LPM_SUPPORT; ++ xhci->quirks |= XHCI_EP_CTX_BROKEN_DCS; ++ } + + if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && + pdev->device == 0x1042) +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -520,7 +520,10 @@ void xhci_find_new_dequeue_state(struct + struct xhci_virt_ep *ep = &dev->eps[ep_index]; + struct xhci_ring *ep_ring; + struct xhci_segment *new_seg; ++ struct xhci_segment *halted_seg = NULL; + union xhci_trb *new_deq; ++ union xhci_trb *halted_trb; ++ int index = 0; + dma_addr_t addr; + u64 hw_dequeue; + bool cycle_found = false; +@@ -541,7 +544,28 @@ void xhci_find_new_dequeue_state(struct + hw_dequeue = xhci_get_hw_deq(xhci, dev, ep_index, stream_id); + new_seg = ep_ring->deq_seg; + new_deq = ep_ring->dequeue; +- state->new_cycle_state = hw_dequeue & 0x1; ++ ++ /* ++ * Quirk: xHC write-back of the DCS field in the hardware dequeue ++ * pointer is wrong - use the cycle state of the TRB pointed to by ++ * the dequeue pointer. ++ */ ++ if (xhci->quirks & XHCI_EP_CTX_BROKEN_DCS && ++ !(ep->ep_state & EP_HAS_STREAMS)) ++ halted_seg = trb_in_td(xhci, cur_td->start_seg, ++ cur_td->first_trb, cur_td->last_trb, ++ hw_dequeue & ~0xf, false); ++ if (halted_seg) { ++ index = ((dma_addr_t)(hw_dequeue & ~0xf) - halted_seg->dma) / ++ sizeof(*halted_trb); ++ halted_trb = &halted_seg->trbs[index]; ++ state->new_cycle_state = halted_trb->generic.field[3] & 0x1; ++ xhci_dbg(xhci, "Endpoint DCS = %d TRB index = %d cycle = %d\n", ++ (u8)(hw_dequeue & 0x1), index, ++ state->new_cycle_state); ++ } else { ++ state->new_cycle_state = hw_dequeue & 0x1; ++ } + state->stream_id = stream_id; + + /* +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1865,6 +1865,7 @@ struct xhci_hcd { + #define XHCI_ZERO_64B_REGS BIT_ULL(32) + #define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(34) + #define XHCI_SNPS_BROKEN_SUSPEND BIT_ULL(35) ++#define XHCI_EP_CTX_BROKEN_DCS BIT_ULL(36) + + unsigned int num_active_eps; + unsigned int limit_active_eps; diff --git a/target/linux/brcm2708/patches-4.19/950-0703-i2c-bcm2835-Ensure-clock-exists-when-probing.patch b/target/linux/brcm2708/patches-4.19/950-0703-i2c-bcm2835-Ensure-clock-exists-when-probing.patch deleted file mode 100644 index 9748e434f5..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0703-i2c-bcm2835-Ensure-clock-exists-when-probing.patch +++ /dev/null @@ -1,72 +0,0 @@ -From c08dfc37750b965a410c11eb157c0c0d75a13b88 Mon Sep 17 00:00:00 2001 -From: Annaliese McDermond -Date: Fri, 21 Jun 2019 03:52:50 -0700 -Subject: [PATCH 703/703] i2c: bcm2835: Ensure clock exists when probing - -Commit 9de93b04df16b055824e3f1f13fedb90fbcf2e4f upstream. - -Probe function fails to recognize that upstream clock actually -doesn't yet exist because clock driver has not been initialized. -Actually try to go get the clock and test for its existence -before trying to set up a downstream clock based upon it. - -This fixes a bug that causes the i2c driver not to work with -monolithic kernels. - -Fixes: bebff81fb8b9 ("i2c: bcm2835: Model Divider in CCF") -Signed-off-by: Annaliese McDermond -Acked-by: Stefan Wahren -Signed-off-by: Wolfram Sang ---- - drivers/i2c/busses/i2c-bcm2835.c | 16 ++++++++++++---- - 1 file changed, 12 insertions(+), 4 deletions(-) - ---- a/drivers/i2c/busses/i2c-bcm2835.c -+++ b/drivers/i2c/busses/i2c-bcm2835.c -@@ -244,15 +244,18 @@ static const struct clk_ops clk_bcm2835_ - }; - - static struct clk *bcm2835_i2c_register_div(struct device *dev, -- const char *mclk_name, -+ struct clk *mclk, - struct bcm2835_i2c_dev *i2c_dev) - { - struct clk_init_data init; - struct clk_bcm2835_i2c *priv; - char name[32]; -+ const char *mclk_name; - - snprintf(name, sizeof(name), "%s_div", dev_name(dev)); - -+ mclk_name = __clk_get_name(mclk); -+ - init.ops = &clk_bcm2835_i2c_ops; - init.name = name; - init.parent_names = (const char* []) { mclk_name }; -@@ -505,8 +508,8 @@ static int bcm2835_i2c_probe(struct plat - struct resource *mem, *irq; - int ret; - struct i2c_adapter *adap; -- const char *mclk_name; - struct clk *bus_clk; -+ struct clk *mclk; - u32 bus_clk_rate; - - i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); -@@ -521,9 +524,14 @@ static int bcm2835_i2c_probe(struct plat - if (IS_ERR(i2c_dev->regs)) - return PTR_ERR(i2c_dev->regs); - -- mclk_name = of_clk_get_parent_name(pdev->dev.of_node, 0); -+ mclk = devm_clk_get(&pdev->dev, NULL); -+ if (IS_ERR(mclk)) { -+ if (PTR_ERR(mclk) != -EPROBE_DEFER) -+ dev_err(&pdev->dev, "Could not get clock\n"); -+ return PTR_ERR(mclk); -+ } - -- bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk_name, i2c_dev); -+ bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk, i2c_dev); - - if (IS_ERR(bus_clk)) { - dev_err(&pdev->dev, "Could not register clock\n"); diff --git a/target/linux/brcm2708/patches-4.19/950-0703-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch b/target/linux/brcm2708/patches-4.19/950-0703-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch new file mode 100644 index 0000000000..6d4448dbc6 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0703-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch @@ -0,0 +1,47 @@ +From 74cd0c8293ad0a05c45eaa29d986f840227867f8 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 12 Jul 2019 15:38:35 +0100 +Subject: [PATCH 703/725] i2c: bcm2835: Set clock-stretch timeout to 35ms + +The BCM2835 I2C blocks have a register to set the clock-stretch +timeout - how long the device is allowed to hold SCL low - in bus +cycles. The current driver doesn't write to the register, therefore +the default value of 64 cycles is being used for all devices. + +Set the timeout to the value recommended for SMBus - 35ms. + +See: https://github.com/raspberrypi/linux/issues/3064 + +Signed-off-by: Phil Elwell +--- + drivers/i2c/busses/i2c-bcm2835.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/i2c/busses/i2c-bcm2835.c ++++ b/drivers/i2c/busses/i2c-bcm2835.c +@@ -194,6 +194,7 @@ static int clk_bcm2835_i2c_set_rate(stru + { + struct clk_bcm2835_i2c *div = to_clk_bcm2835_i2c(hw); + u32 redl, fedl; ++ u32 clk_tout; + u32 divider = clk_bcm2835_i2c_calc_divider(rate, parent_rate); + + if (divider == -EINVAL) +@@ -217,6 +218,17 @@ static int clk_bcm2835_i2c_set_rate(stru + bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_DEL, + (fedl << BCM2835_I2C_FEDL_SHIFT) | + (redl << BCM2835_I2C_REDL_SHIFT)); ++ ++ /* ++ * Set the clock stretch timeout to the SMBUs-recommended 35ms. ++ */ ++ if (rate > 0xffff*1000/35) ++ clk_tout = 0xffff; ++ else ++ clk_tout = 35*rate/1000; ++ ++ bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_CLKT, clk_tout); ++ + return 0; + } + diff --git a/target/linux/brcm2708/patches-4.19/950-0704-arm64-bcm2835-Add-missing-dependency-on-MFD_CORE.patch b/target/linux/brcm2708/patches-4.19/950-0704-arm64-bcm2835-Add-missing-dependency-on-MFD_CORE.patch new file mode 100644 index 0000000000..2a1ad35563 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0704-arm64-bcm2835-Add-missing-dependency-on-MFD_CORE.patch @@ -0,0 +1,28 @@ +From d836c37cd387c438a86054bd52f82141513cfa19 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Fri, 8 Mar 2019 13:02:16 -0800 +Subject: [PATCH 704/725] arm64: bcm2835: Add missing dependency on MFD_CORE. + +commit 7a9b6be9fe58194d9a349159176e8cc0d8f10ef8 upstream. + +When adding the MFD dependency for power domains and WDT in bcm2835, I +added it only on the arm32 side and missed it for arm64. + +Fixes: 5e6acc3e678e ("bcm2835-pm: Move bcm2835-watchdog's DT probe to an MFD.") +Signed-off-by: Eric Anholt +Reported-by: Stefan Wahren +Acked-by: Stefan Wahren +--- + arch/arm64/Kconfig.platforms | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm64/Kconfig.platforms ++++ b/arch/arm64/Kconfig.platforms +@@ -20,6 +20,7 @@ config ARCH_BCM2835 + bool "Broadcom BCM2835 family" + select TIMER_OF + select GPIOLIB ++ select MFD_CORE + select PINCTRL + select PINCTRL_BCM2835 + select ARM_AMBA diff --git a/target/linux/brcm2708/patches-4.19/950-0705-overlays-Add-PCF2129-RTC.patch b/target/linux/brcm2708/patches-4.19/950-0705-overlays-Add-PCF2129-RTC.patch new file mode 100644 index 0000000000..f4f5e69b9b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0705-overlays-Add-PCF2129-RTC.patch @@ -0,0 +1,187 @@ +From 4e534a6c926bee4a9e65c59ac81208ac0a7d280c Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 15 Jul 2019 10:39:05 +0100 +Subject: [PATCH 705/725] overlays: Add PCF2129 RTC + +Add support for the PCF2129 RTC to i2c-rtc and i2c-rtc-gpio overlays. +Also add rv3028 to i2c-rtc-gpio (it was missed previously), and don't +attempt to set an alternate address for the PCF2127. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/README | 11 ++++- + .../dts/overlays/i2c-rtc-gpio-overlay.dts | 41 +++++++++++++++++-- + .../arm/boot/dts/overlays/i2c-rtc-overlay.dts | 19 ++++++++- + 3 files changed, 64 insertions(+), 7 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1022,6 +1022,8 @@ Params: abx80x Select o + + pcf2127 Select the PCF2127 device + ++ pcf2129 Select the PCF2129 device ++ + pcf8523 Select the PCF8523 device + + pcf8563 Select the PCF8563 device +@@ -1067,10 +1069,14 @@ Params: abx80x Select o + + pcf2127 Select the PCF2127 device + ++ pcf2129 Select the PCF2129 device ++ + pcf8523 Select the PCF8523 device + + pcf8563 Select the PCF8563 device + ++ rv3028 Select the Micro Crystal RV3028 device ++ + addr Sets the address for the RTC. Note that the + device must be configured to use the specified + address. +@@ -1079,11 +1085,14 @@ Params: abx80x Select o + "schottky" (ABx80x only) + + trickle-resistor-ohms Resistor value for trickle charge (DS1339, +- ABx80x) ++ ABx80x, RV3028) + + wakeup-source Specify that the RTC can be used as a wakeup + source + ++ backup-switchover-mode Backup power supply switch mode. Must be 0 for ++ off or 1 for Vdd < VBackup (RV3028 only) ++ + i2c_gpio_sda GPIO used for I2C data (default "23") + + i2c_gpio_scl GPIO used for I2C clock (default "24") +--- a/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts +@@ -121,7 +121,7 @@ + #size-cells = <0>; + status = "okay"; + +- pcf2127: pcf2127@51 { ++ pcf2127@51 { + compatible = "nxp,pcf2127"; + reg = <0x51>; + status = "okay"; +@@ -174,6 +174,36 @@ + }; + }; + ++ fragment@11 { ++ target = <&i2c_gpio>; ++ __dormant__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ rv3028: rv3028@52 { ++ compatible = "microcrystal,rv3028"; ++ reg = <0x52>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@12 { ++ target = <&i2c_gpio>; ++ __dormant__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pcf2129@51 { ++ compatible = "nxp,pcf2129"; ++ reg = <0x51>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ + __overrides__ { + abx80x = <0>,"+1"; + ds1307 = <0>,"+2"; +@@ -185,6 +215,8 @@ + pcf8523 = <0>,"+8"; + pcf8563 = <0>,"+9"; + m41t62 = <0>,"+10"; ++ rv3028 = <0>,"+11"; ++ pcf2129 = <0>,"+12"; + + addr = <&abx80x>, "reg:0", + <&ds1307>, "reg:0", +@@ -192,18 +224,19 @@ + <&ds3231>, "reg:0", + <&mcp7940x>, "reg:0", + <&mcp7941x>, "reg:0", +- <&pcf2127>, "reg:0", + <&pcf8523>, "reg:0", + <&pcf8563>, "reg:0", + <&m41t62>, "reg:0"; + + trickle-diode-type = <&abx80x>,"abracon,tc-diode"; + trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0", +- <&abx80x>,"abracon,tc-resistor"; ++ <&abx80x>,"abracon,tc-resistor", ++ <&rv3028>,"trickle-resistor-ohms:0"; ++ backup-switchover-mode = <&rv3028>,"backup-switchover-mode:0"; + wakeup-source = <&ds1339>,"wakeup-source?", + <&ds3231>,"wakeup-source?", + <&mcp7940x>,"wakeup-source?", +- <&mcp7941x>,"wakeup-source?"; ++ <&mcp7941x>,"wakeup-source?"; + i2c_gpio_sda = <&i2c_gpio>,"gpios:4"; + i2c_gpio_scl = <&i2c_gpio>,"gpios:16"; + i2c_gpio_delay_us = <&i2c_gpio>,"i2c-gpio,delay-us:0"; +--- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts +@@ -105,7 +105,7 @@ + #size-cells = <0>; + status = "okay"; + +- pcf2127: pcf2127@51 { ++ pcf2127@51 { + compatible = "nxp,pcf2127"; + reg = <0x51>; + status = "okay"; +@@ -173,6 +173,21 @@ + }; + }; + ++ fragment@11 { ++ target = <&i2c_arm>; ++ __dormant__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pcf2129@51 { ++ compatible = "nxp,pcf2129"; ++ reg = <0x51>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ + __overrides__ { + abx80x = <0>,"+0"; + ds1307 = <0>,"+1"; +@@ -185,6 +200,7 @@ + pcf8563 = <0>,"+8"; + m41t62 = <0>,"+9"; + rv3028 = <0>,"+10"; ++ pcf2129 = <0>,"+11"; + + addr = <&abx80x>, "reg:0", + <&ds1307>, "reg:0", +@@ -192,7 +208,6 @@ + <&ds3231>, "reg:0", + <&mcp7940x>, "reg:0", + <&mcp7941x>, "reg:0", +- <&pcf2127>, "reg:0", + <&pcf8523>, "reg:0", + <&pcf8563>, "reg:0", + <&m41t62>, "reg:0"; diff --git a/target/linux/brcm2708/patches-4.19/950-0706-configs-arm64-bcm2711-Use-CONFIG_BRCMSTB_THERMAL-ins.patch b/target/linux/brcm2708/patches-4.19/950-0706-configs-arm64-bcm2711-Use-CONFIG_BRCMSTB_THERMAL-ins.patch new file mode 100644 index 0000000000..5cd596d6be --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0706-configs-arm64-bcm2711-Use-CONFIG_BRCMSTB_THERMAL-ins.patch @@ -0,0 +1,29 @@ +From 04f2cfb2130c52d8e01c5c2fddf1c0f5d0f3583c Mon Sep 17 00:00:00 2001 +From: Allen Wild +Date: Sat, 13 Jul 2019 11:14:02 -0400 +Subject: [PATCH 706/725] configs: arm64/bcm2711: Use CONFIG_BRCMSTB_THERMAL + instead of CONFIG_BCM2835_THERMAL + +The Raspberry Pi 4 uses the brcmstb thermal driver rather than brcm2835, +based on the device tree compatible string 'brcm,avs-tmon-bcm2838'. With +CONFIG_BRCMSTB_THERMAL enabled, reading temperature from +/sys/class/thermal/thermal_zone0/temp works as expected instead of +returning EINVAL. + +Fixes: https://github.com/raspberrypi/linux/issues/3071 +Signed-off-by: Allen Wild +--- + arch/arm64/configs/bcm2711_defconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm64/configs/bcm2711_defconfig ++++ b/arch/arm64/configs/bcm2711_defconfig +@@ -658,7 +658,7 @@ CONFIG_SENSORS_ADS1015=m + CONFIG_SENSORS_INA2XX=m + CONFIG_SENSORS_TMP102=m + CONFIG_THERMAL=y +-CONFIG_BCM2835_THERMAL=y ++CONFIG_BRCMSTB_THERMAL=y + CONFIG_WATCHDOG=y + CONFIG_GPIO_WATCHDOG=m + CONFIG_BCM2835_WDT=y diff --git a/target/linux/brcm2708/patches-4.19/950-0707-overlays-dpi18-and-dpi24-vc4-compatibility.patch b/target/linux/brcm2708/patches-4.19/950-0707-overlays-dpi18-and-dpi24-vc4-compatibility.patch new file mode 100644 index 0000000000..2a46358575 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0707-overlays-dpi18-and-dpi24-vc4-compatibility.patch @@ -0,0 +1,52 @@ +From a3dd548da9a2900eafb337eab2a3124f543ddc31 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 16 Jul 2019 15:24:12 +0100 +Subject: [PATCH 707/725] overlays: dpi18 and dpi24 vc4 compatibility + +The dpi overlays use the fb device tree node as a place to hang the +necessary pinctrl changes. With one of the VC4 overlays loaded, the +fb node is disabled so the changes have no effect. + +Modify the overlays to also use the vc4 node, to cover both use +cases. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/dpi18-overlay.dts | 8 ++++++++ + arch/arm/boot/dts/overlays/dpi24-overlay.dts | 8 ++++++++ + 2 files changed, 16 insertions(+) + +--- a/arch/arm/boot/dts/overlays/dpi18-overlay.dts ++++ b/arch/arm/boot/dts/overlays/dpi18-overlay.dts +@@ -17,6 +17,14 @@ + }; + + fragment@1 { ++ target = <&vc4>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&dpi18_pins>; ++ }; ++ }; ++ ++ fragment@2 { + target = <&gpio>; + __overlay__ { + dpi18_pins: dpi18_pins { +--- a/arch/arm/boot/dts/overlays/dpi24-overlay.dts ++++ b/arch/arm/boot/dts/overlays/dpi24-overlay.dts +@@ -17,6 +17,14 @@ + }; + + fragment@1 { ++ target = <&vc4>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&dpi24_pins>; ++ }; ++ }; ++ ++ fragment@2 { + target = <&gpio>; + __overlay__ { + dpi24_pins: dpi24_pins { diff --git a/target/linux/brcm2708/patches-4.19/950-0708-overlays-Add-i2c0-and-i2c1-for-regularity.patch b/target/linux/brcm2708/patches-4.19/950-0708-overlays-Add-i2c0-and-i2c1-for-regularity.patch new file mode 100644 index 0000000000..db937300ae --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0708-overlays-Add-i2c0-and-i2c1-for-regularity.patch @@ -0,0 +1,340 @@ +From b61cc000ad6ee771f471a126dc80b7c083730a94 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 17 Jul 2019 10:08:55 +0100 +Subject: [PATCH 708/725] overlays: Add i2c0 and i2c1 for regularity + +The new i2c overlays for pi4 (i2c3, i2c4, i2c5, i2c6) have a +standardised interface that allows pin groups to be chosen +atomically rather than as individual pins. Add i2c0 and i2c1 +overlays to fit the naming scheme and parameter usage, deprecating +i2c0-bcm2708 and i2c1-bcm2708. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/Makefile | 2 + + arch/arm/boot/dts/overlays/README | 33 +++++--- + .../dts/overlays/i2c0-bcm2708-overlay.dts | 77 +++---------------- + arch/arm/boot/dts/overlays/i2c0-overlay.dts | 61 +++++++++++++++ + .../dts/overlays/i2c1-bcm2708-overlay.dts | 46 ++--------- + arch/arm/boot/dts/overlays/i2c1-overlay.dts | 44 +++++++++++ + 6 files changed, 147 insertions(+), 116 deletions(-) + create mode 100644 arch/arm/boot/dts/overlays/i2c0-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/i2c1-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -66,7 +66,9 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + i2c-rtc.dtbo \ + i2c-rtc-gpio.dtbo \ + i2c-sensor.dtbo \ ++ i2c0.dtbo \ + i2c0-bcm2708.dtbo \ ++ i2c1.dtbo \ + i2c1-bcm2708.dtbo \ + i2c3.dtbo \ + i2c4.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1151,14 +1151,12 @@ Params: addr Set the + sensor + + +-Name: i2c0-bcm2708 ++Name: i2c0 + Info: Change i2c0 pin usage. Not all pin combinations are usable on all + platforms - platforms other then Compute Modules can only use this + to disable transaction combining. +-Load: dtoverlay=i2c0-bcm2708,= +-Params: sda0_pin GPIO pin for SDA0 (deprecated - use pins_*) +- scl0_pin GPIO pin for SCL0 (deprecated - use pins_*) +- pins_0_1 Use pins 0 and 1 (default) ++Load: dtoverlay=i2c0,= ++Params: pins_0_1 Use pins 0 and 1 (default) + pins_28_29 Use pins 28 and 29 + pins_44_45 Use pins 44 and 45 + pins_46_47 Use pins 46 and 47 +@@ -1166,18 +1164,33 @@ Params: sda0_pin GPIO pin + "yes") + + +-Name: i2c1-bcm2708 ++Name: i2c0-bcm2708 ++Info: Deprecated, legacy version of i2c0, from which it inherits its ++ parameters, just adding the explicit individual pin specifiers. ++Load: ++Params: sda0_pin GPIO pin for SDA0 (deprecated - use pins_*) ++ scl0_pin GPIO pin for SCL0 (deprecated - use pins_*) ++ ++ ++Name: i2c1 + Info: Change i2c1 pin usage. Not all pin combinations are usable on all + platforms - platforms other then Compute Modules can only use this + to disable transaction combining. +-Info: Enable the i2c_bcm2708 driver for the i2c1 bus +-Load: dtoverlay=i2c1-bcm2708,= ++Load: dtoverlay=i2c1,= ++Params: pins_2_3 Use pins 2 and 3 (default) ++ pins_44_45 Use pins 44 and 45 ++ combine Allow transactions to be combined (default ++ "yes") ++ ++ ++Name: i2c1-bcm2708 ++Info: Deprecated, legacy version of i2c1, from which it inherits its ++ parameters, just adding the explicit individual pin specifiers. ++Load: + Params: sda1_pin GPIO pin for SDA1 (2 or 44 - default 2) + scl1_pin GPIO pin for SCL1 (3 or 45 - default 3) + pin_func Alternative pin function (4 (alt0), 6 (alt2) - + default 4) +- combine Allow transactions to be combined (default +- "yes") + + + Name: i2c3 +--- a/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c0-bcm2708-overlay.dts +@@ -1,69 +1,14 @@ +-/* +- * Device tree overlay for i2c_bcm2708, i2c0 bus +- * +- * Compile: +- * dtc -@ -I dts -O dtb -o i2c0-bcm2708-overlay.dtb i2c0-bcm2708-overlay.dts +- */ +- +-/dts-v1/; +-/plugin/; ++#include "i2c0-overlay.dts" + + /{ +- compatible = "brcm,bcm2835"; +- +- fragment@0 { +- target = <&i2c0>; +- __overlay__ { +- status = "okay"; +- }; +- }; +- +- fragment@1 { +- target = <&i2c0_pins>; +- frag1: __overlay__ { +- brcm,pins = <0 1>; +- brcm,function = <4>; /* alt0 */ +- }; +- }; +- +- fragment@2 { +- target = <&i2c0_pins>; +- __dormant__ { +- brcm,pins = <28 29>; +- brcm,function = <4>; /* alt0 */ +- }; +- }; +- +- fragment@3 { +- target = <&i2c0_pins>; +- __dormant__ { +- brcm,pins = <44 45>; +- brcm,function = <5>; /* alt1 */ +- }; +- }; +- +- fragment@4 { +- target = <&i2c0_pins>; +- __dormant__ { +- brcm,pins = <46 47>; +- brcm,function = <4>; /* alt0 */ +- }; +- }; +- +- fragment@5 { +- target = <&i2c0>; +- __dormant__ { +- compatible = "brcm,bcm2708-i2c"; +- }; +- }; +- +- __overrides__ { +- sda0_pin = <&frag1>,"brcm,pins:0"; +- scl0_pin = <&frag1>,"brcm,pins:4"; +- pins_0_1 = <0>,"+1-2-3-4"; +- pins_28_29 = <0>,"-1+2-3-4"; +- pins_44_45 = <0>,"-1-2+3-4"; +- pins_46_47 = <0>,"-1-2-3+4"; +- combine = <0>, "!5"; +- }; ++ __overrides__ { ++ sda0_pin = <&pins1>,"brcm,pins:0", ++ <&pins2>,"brcm,pins:0", ++ <&pins3>,"brcm,pins:0", ++ <&pins4>,"brcm,pins:0"; ++ scl0_pin = <&pins1>,"brcm,pins:4", ++ <&pins2>,"brcm,pins:4", ++ <&pins3>,"brcm,pins:4", ++ <&pins4>,"brcm,pins:4"; ++ }; + }; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2c0-overlay.dts +@@ -0,0 +1,61 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&i2c0>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-0 = <&i2c0_pins>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c0_pins>; ++ pins1: __overlay__ { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c0_pins>; ++ pins2: __dormant__ { ++ brcm,pins = <28 29>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&i2c0_pins>; ++ pins3: __dormant__ { ++ brcm,pins = <44 45>; ++ brcm,function = <5>; /* alt1 */ ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&i2c0_pins>; ++ pins4: __dormant__ { ++ brcm,pins = <46 47>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ }; ++ ++ fragment@5 { ++ target = <&i2c0>; ++ __dormant__ { ++ compatible = "brcm,bcm2708-i2c"; ++ }; ++ }; ++ ++ __overrides__ { ++ pins_0_1 = <0>,"+1-2-3-4"; ++ pins_28_29 = <0>,"-1+2-3-4"; ++ pins_44_45 = <0>,"-1-2+3-4"; ++ pins_46_47 = <0>,"-1-2-3+4"; ++ combine = <0>, "!5"; ++ }; ++}; +--- a/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c1-bcm2708-overlay.dts +@@ -1,43 +1,9 @@ +-/* +- * Device tree overlay for i2c_bcm2708, i2c1 bus +- * +- * Compile: +- * dtc -@ -I dts -O dtb -o i2c1-bcm2708-overlay.dtb i2c1-bcm2708-overlay.dts +- */ +- +-/dts-v1/; +-/plugin/; ++#include "i2c1-overlay.dts" + + /{ +- compatible = "brcm,bcm2835"; +- +- fragment@0 { +- target = <&i2c1>; +- __overlay__ { +- pinctrl-0 = <&i2c1_pins>; +- status = "okay"; +- }; +- }; +- +- fragment@1 { +- target = <&i2c1_pins>; +- pins: __overlay__ { +- brcm,pins = <2 3>; +- brcm,function = <4>; /* alt 0 */ +- }; +- }; +- +- fragment@2 { +- target = <&i2c1>; +- __dormant__ { +- compatible = "brcm,bcm2708-i2c"; +- }; +- }; +- +- __overrides__ { +- sda1_pin = <&pins>,"brcm,pins:0"; +- scl1_pin = <&pins>,"brcm,pins:4"; +- pin_func = <&pins>,"brcm,function:0"; +- combine = <0>, "!2"; +- }; ++ __overrides__ { ++ sda1_pin = <&pins1>,"brcm,pins:0", <&pins2>,"brcm,pins:0"; ++ scl1_pin = <&pins1>,"brcm,pins:4", <&pins1>,"brcm,pins:4"; ++ pin_func = <&pins1>,"brcm,function:0", <&pins2>,"brcm,function:0"; ++ }; + }; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2c1-overlay.dts +@@ -0,0 +1,44 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&i2c1>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c1_pins>; ++ pins1: __overlay__ { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; /* alt 0 */ ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1_pins>; ++ pins2: __dormant__ { ++ brcm,pins = <44 45>; ++ brcm,function = <6>; /* alt 2 */ ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&i2c1>; ++ __dormant__ { ++ compatible = "brcm,bcm2708-i2c"; ++ }; ++ }; ++ ++ __overrides__ { ++ pins_2_3 = <0>,"=1!2"; ++ pins_44_45 = <0>,"!1=2"; ++ combine = <0>, "!3"; ++ }; ++}; diff --git a/target/linux/brcm2708/patches-4.19/950-0709-Pisound-Remove-spinlock-usage-around-spi_sync.patch b/target/linux/brcm2708/patches-4.19/950-0709-Pisound-Remove-spinlock-usage-around-spi_sync.patch new file mode 100644 index 0000000000..c47f10575b --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0709-Pisound-Remove-spinlock-usage-around-spi_sync.patch @@ -0,0 +1,31 @@ +From e7efd5c5b3e6e7f900eca6323fb593f80471a380 Mon Sep 17 00:00:00 2001 +From: Giedrius +Date: Fri, 12 Jul 2019 17:45:55 +0300 +Subject: [PATCH 709/725] Pisound: Remove spinlock usage around spi_sync + +--- + sound/soc/bcm/pisound.c | 5 ----- + 1 file changed, 5 deletions(-) + +--- a/sound/soc/bcm/pisound.c ++++ b/sound/soc/bcm/pisound.c +@@ -286,9 +286,6 @@ static irqreturn_t data_available_interr + return IRQ_HANDLED; + } + +-static DEFINE_SPINLOCK(spilock); +-static unsigned long spilockflags; +- + static uint16_t spi_transfer16(uint16_t val) + { + uint8_t txbuf[2]; +@@ -333,9 +330,7 @@ static void spi_transfer(const uint8_t * + transfer.delay_usecs = 10; + spi_message_add_tail(&transfer, &msg); + +- spin_lock_irqsave(&spilock, spilockflags); + err = spi_sync(pisnd_spi_device, &msg); +- spin_unlock_irqrestore(&spilock, spilockflags); + + if (err < 0) { + printe("spi_sync error %d\n", err); diff --git a/target/linux/brcm2708/patches-4.19/950-0710-arm64-mm-Limit-the-DMA-zone-for-arm64.patch b/target/linux/brcm2708/patches-4.19/950-0710-arm64-mm-Limit-the-DMA-zone-for-arm64.patch new file mode 100644 index 0000000000..a1b8817980 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0710-arm64-mm-Limit-the-DMA-zone-for-arm64.patch @@ -0,0 +1,25 @@ +From 804767a8871d01153c7a6e974730eda806fdbef6 Mon Sep 17 00:00:00 2001 +From: Andrei Gherzan +Date: Tue, 16 Jul 2019 13:28:22 +0100 +Subject: [PATCH 710/725] arm64/mm: Limit the DMA zone for arm64 + +On RaspberryPi, only the first 1Gb can be used for DMA[1]. + +[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2019-July/665986.html + +Signed-off-by: Andrei Gherzan +--- + arch/arm64/mm/init.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm64/mm/init.c ++++ b/arch/arm64/mm/init.c +@@ -224,7 +224,7 @@ static void __init reserve_elfcorehdr(vo + static phys_addr_t __init max_zone_dma_phys(void) + { + phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, 32); +- return min(offset + (1ULL << 32), memblock_end_of_DRAM()); ++ return min(offset + (1ULL << 30), memblock_end_of_DRAM()); + } + + #ifdef CONFIG_NUMA diff --git a/target/linux/brcm2708/patches-4.19/950-0711-configs-Enable-iio-driver-for-TI-ADS1015.patch b/target/linux/brcm2708/patches-4.19/950-0711-configs-Enable-iio-driver-for-TI-ADS1015.patch new file mode 100644 index 0000000000..bfa8415e00 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0711-configs-Enable-iio-driver-for-TI-ADS1015.patch @@ -0,0 +1,42 @@ +From f3fe10334b7073f38eb3e36441a5313e1d9b2324 Mon Sep 17 00:00:00 2001 +From: Aapo Vienamo +Date: Wed, 17 Jul 2019 11:05:20 +0300 +Subject: [PATCH 711/725] configs: Enable iio driver for TI ADS1015 + +Signed-off-by: Aapo Vienamo +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcm2711_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + 3 files changed, 3 insertions(+) + +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -1291,6 +1291,7 @@ CONFIG_IIO=m + CONFIG_IIO_BUFFER_CB=m + CONFIG_MCP320X=m + CONFIG_MCP3422=m ++CONFIG_TI_ADS1015=m + CONFIG_DHT11=m + CONFIG_HDC100X=m + CONFIG_HTU21=m +--- a/arch/arm/configs/bcm2711_defconfig ++++ b/arch/arm/configs/bcm2711_defconfig +@@ -1322,6 +1322,7 @@ CONFIG_IIO=m + CONFIG_IIO_BUFFER_CB=m + CONFIG_MCP320X=m + CONFIG_MCP3422=m ++CONFIG_TI_ADS1015=m + CONFIG_DHT11=m + CONFIG_HDC100X=m + CONFIG_HTU21=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -1301,6 +1301,7 @@ CONFIG_IIO=m + CONFIG_IIO_BUFFER_CB=m + CONFIG_MCP320X=m + CONFIG_MCP3422=m ++CONFIG_TI_ADS1015=m + CONFIG_DHT11=m + CONFIG_HDC100X=m + CONFIG_HTU21=m diff --git a/target/linux/brcm2708/patches-4.19/950-0712-bcm2711_defconfig-enable-PCI-portbus-support-and-imp.patch b/target/linux/brcm2708/patches-4.19/950-0712-bcm2711_defconfig-enable-PCI-portbus-support-and-imp.patch new file mode 100644 index 0000000000..7bf2b4d774 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0712-bcm2711_defconfig-enable-PCI-portbus-support-and-imp.patch @@ -0,0 +1,25 @@ +From 6c46cf889cfd831ecce288005f85c7a254a64cb1 Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Thu, 18 Jul 2019 13:05:35 +0100 +Subject: [PATCH 712/725] bcm2711_defconfig: enable PCI portbus support (and + implicitly, PCIe AER) + +PCIe advanced error reporting is supported by the root complex, so make +use of it. + +Signed-off-by: Jonathan Bell +--- + arch/arm/configs/bcm2711_defconfig | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/arm/configs/bcm2711_defconfig ++++ b/arch/arm/configs/bcm2711_defconfig +@@ -33,6 +33,8 @@ CONFIG_ARCH_BCM2835=y + CONFIG_ARM_LPAE=y + # CONFIG_CACHE_L2X0 is not set + CONFIG_PCI=y ++CONFIG_PCIEPORTBUS=y ++# CONFIG_PCIEASPM is not set + CONFIG_PCI_MSI=y + CONFIG_PCIE_BRCMSTB=y + CONFIG_SMP=y diff --git a/target/linux/brcm2708/patches-4.19/950-0713-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch b/target/linux/brcm2708/patches-4.19/950-0713-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch new file mode 100644 index 0000000000..c1e04c06ed --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0713-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch @@ -0,0 +1,194 @@ +From 9288f45112f6381ef5697d451b7f44b306e61f8e Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 3 Jul 2019 17:44:53 +0100 +Subject: [PATCH 713/725] drm/vc4: Query firmware for custom HDMI mode + +Allow custom HDMI modes to be specified from config.txt, +and these then override EDID parsing. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 142 ++++++++++++++----------- + 1 file changed, 81 insertions(+), 61 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -1035,6 +1035,58 @@ vc4_fkms_connector_detect(struct drm_con + return connector_status_connected; + } + ++/* Queries the firmware to populate a drm_mode structure for this display */ ++static int vc4_fkms_get_fw_mode(struct vc4_fkms_connector *fkms_connector, ++ struct drm_display_mode *mode) ++{ ++ struct vc4_dev *vc4 = fkms_connector->vc4_dev; ++ struct set_timings timings = { 0 }; ++ int ret; ++ ++ timings.display = fkms_connector->display_number; ++ ++ ret = rpi_firmware_property(vc4->firmware, ++ RPI_FIRMWARE_GET_DISPLAY_TIMING, &timings, ++ sizeof(timings)); ++ if (ret || !timings.clock) ++ /* No mode returned - abort */ ++ return -1; ++ ++ /* Equivalent to DRM_MODE macro. */ ++ memset(mode, 0, sizeof(*mode)); ++ strncpy(mode->name, "FIXED_MODE", sizeof(mode->name)); ++ mode->status = 0; ++ mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; ++ mode->clock = timings.clock; ++ mode->hdisplay = timings.hdisplay; ++ mode->hsync_start = timings.hsync_start; ++ mode->hsync_end = timings.hsync_end; ++ mode->htotal = timings.htotal; ++ mode->hskew = 0; ++ mode->vdisplay = timings.vdisplay; ++ mode->vsync_start = timings.vsync_start; ++ mode->vsync_end = timings.vsync_end; ++ mode->vtotal = timings.vtotal; ++ mode->vscan = timings.vscan; ++ ++ if (timings.flags & TIMINGS_FLAGS_H_SYNC_POS) ++ mode->flags |= DRM_MODE_FLAG_PHSYNC; ++ else ++ mode->flags |= DRM_MODE_FLAG_NHSYNC; ++ ++ if (timings.flags & TIMINGS_FLAGS_V_SYNC_POS) ++ mode->flags |= DRM_MODE_FLAG_PVSYNC; ++ else ++ mode->flags |= DRM_MODE_FLAG_NVSYNC; ++ ++ if (timings.flags & TIMINGS_FLAGS_INTERLACE) ++ mode->flags |= DRM_MODE_FLAG_INTERLACE; ++ ++ mode->base.type = DRM_MODE_OBJECT_MODE; ++ ++ return 0; ++} ++ + static int vc4_fkms_get_edid_block(void *data, u8 *buf, unsigned int block, + size_t len) + { +@@ -1063,30 +1115,40 @@ static int vc4_fkms_connector_get_modes( + to_vc4_fkms_connector(connector); + struct drm_encoder *encoder = fkms_connector->encoder; + struct vc4_fkms_encoder *vc4_encoder = to_vc4_fkms_encoder(encoder); +- int ret = 0; ++ struct drm_display_mode fw_mode; ++ struct drm_display_mode *mode; + struct edid *edid; ++ int num_modes; + +- edid = drm_do_get_edid(connector, vc4_fkms_get_edid_block, +- fkms_connector); ++ if (!vc4_fkms_get_fw_mode(fkms_connector, &fw_mode)) { ++ drm_mode_debug_printmodeline(&fw_mode); ++ mode = drm_mode_duplicate(connector->dev, ++ &fw_mode); ++ drm_mode_probed_add(connector, mode); ++ num_modes = 1; /* 1 mode */ ++ } else { ++ edid = drm_do_get_edid(connector, vc4_fkms_get_edid_block, ++ fkms_connector); + +- /* FIXME: Can we do CEC? +- * cec_s_phys_addr_from_edid(vc4->hdmi->cec_adap, edid); +- * if (!edid) +- * return -ENODEV; +- */ +- +- vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid); +- +- if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) { +- vc4_encoder->rgb_range_selectable = +- drm_rgb_quant_range_selectable(edid); ++ /* FIXME: Can we do CEC? ++ * cec_s_phys_addr_from_edid(vc4->hdmi->cec_adap, edid); ++ * if (!edid) ++ * return -ENODEV; ++ */ ++ ++ vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid); ++ ++ if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) { ++ vc4_encoder->rgb_range_selectable = ++ drm_rgb_quant_range_selectable(edid); ++ } ++ ++ drm_connector_update_edid_property(connector, edid); ++ num_modes = drm_add_edid_modes(connector, edid); ++ kfree(edid); + } + +- drm_connector_update_edid_property(connector, edid); +- ret = drm_add_edid_modes(connector, edid); +- kfree(edid); +- +- return ret; ++ return num_modes; + } + + /* This is the DSI panel resolution. Use this as a default should the firmware +@@ -1104,57 +1166,15 @@ static int vc4_fkms_lcd_connector_get_mo + { + struct vc4_fkms_connector *fkms_connector = + to_vc4_fkms_connector(connector); +- struct vc4_dev *vc4 = fkms_connector->vc4_dev; + struct drm_display_mode *mode; +- struct mailbox_set_mode mb = { +- .tag1 = { RPI_FIRMWARE_GET_DISPLAY_TIMING, +- sizeof(struct set_timings), 0}, +- .timings = { .display = fkms_connector->display_number }, +- }; + struct drm_display_mode fw_mode; +- int ret = 0; +- +- ret = rpi_firmware_property_list(vc4->firmware, &mb, sizeof(mb)); +- if (!ret) { +- /* Equivalent to DRM_MODE macro. */ +- memset(&fw_mode, 0, sizeof(fw_mode)); +- strncpy(fw_mode.name, "LCD_MODE", sizeof(fw_mode.name)); +- fw_mode.status = 0; +- fw_mode.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; +- fw_mode.clock = mb.timings.clock; +- fw_mode.hdisplay = mb.timings.hdisplay; +- fw_mode.hsync_start = mb.timings.hsync_start; +- fw_mode.hsync_end = mb.timings.hsync_end; +- fw_mode.htotal = mb.timings.htotal; +- fw_mode.hskew = 0; +- fw_mode.vdisplay = mb.timings.vdisplay; +- fw_mode.vsync_start = mb.timings.vsync_start; +- fw_mode.vsync_end = mb.timings.vsync_end; +- fw_mode.vtotal = mb.timings.vtotal; +- fw_mode.vscan = mb.timings.vscan; +- if (mb.timings.flags & TIMINGS_FLAGS_H_SYNC_POS) +- fw_mode.flags |= DRM_MODE_FLAG_PHSYNC; +- else +- fw_mode.flags |= DRM_MODE_FLAG_NHSYNC; +- if (mb.timings.flags & TIMINGS_FLAGS_V_SYNC_POS) +- fw_mode.flags |= DRM_MODE_FLAG_PVSYNC; +- else +- fw_mode.flags |= DRM_MODE_FLAG_NVSYNC; +- if (mb.timings.flags & TIMINGS_FLAGS_V_SYNC_POS) +- fw_mode.flags |= DRM_MODE_FLAG_PVSYNC; +- else +- fw_mode.flags |= DRM_MODE_FLAG_NVSYNC; +- if (mb.timings.flags & TIMINGS_FLAGS_INTERLACE) +- fw_mode.flags |= DRM_MODE_FLAG_INTERLACE; +- +- fw_mode.base.type = DRM_MODE_OBJECT_MODE; + ++ if (!vc4_fkms_get_fw_mode(fkms_connector, &fw_mode) && fw_mode.clock) + mode = drm_mode_duplicate(connector->dev, + &fw_mode); +- } else { ++ else + mode = drm_mode_duplicate(connector->dev, + &lcd_mode); +- } + + if (!mode) { + DRM_ERROR("Failed to create a new display mode\n"); diff --git a/target/linux/brcm2708/patches-4.19/950-0714-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch b/target/linux/brcm2708/patches-4.19/950-0714-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch new file mode 100644 index 0000000000..7c7b85060f --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0714-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch @@ -0,0 +1,37 @@ +From 0dd10ab858ea90d6b8477c0ad54247b105e316b9 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Thu, 11 Jul 2019 15:12:05 +0100 +Subject: [PATCH 714/725] drm/vc4: Pass the drm vrefresh to the firmware on + mode set + +More for completeness than need, but use drm_mode_vrefresh +to compute the vrefresh value, and pass that down to the +firmware on mode set. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -737,8 +737,8 @@ static void vc4_crtc_mode_set_nofb(struc + mode->hdisplay, mode->hsync_start, mode->hsync_end, + mode->htotal, mode->hskew, mode->vdisplay, + mode->vsync_start, mode->vsync_end, mode->vtotal, +- mode->vscan, mode->vrefresh, mode->picture_aspect_ratio, +- mode->flags); ++ mode->vscan, drm_mode_vrefresh(mode), ++ mode->picture_aspect_ratio, mode->flags); + mb.timings.display = vc4_crtc->display_number; + + mb.timings.video_id_code = frame.avi.video_code; +@@ -754,7 +754,7 @@ static void vc4_crtc_mode_set_nofb(struc + mb.timings.vsync_end = mode->vsync_end; + mb.timings.vtotal = mode->vtotal; + mb.timings.vscan = mode->vscan; +- mb.timings.vrefresh = 0; ++ mb.timings.vrefresh = drm_mode_vrefresh(mode); + mb.timings.flags = 0; + if (mode->flags & DRM_MODE_FLAG_PHSYNC) + mb.timings.flags |= TIMINGS_FLAGS_H_SYNC_POS; diff --git a/target/linux/brcm2708/patches-4.19/950-0715-overlays-audremap-Support-GPIOs-18-19.patch b/target/linux/brcm2708/patches-4.19/950-0715-overlays-audremap-Support-GPIOs-18-19.patch new file mode 100644 index 0000000000..14437d7ca0 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0715-overlays-audremap-Support-GPIOs-18-19.patch @@ -0,0 +1,68 @@ +From abd2aaea7bbe687aadff3f1dad14ea5458be2d00 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 23 Jul 2019 12:55:07 +0100 +Subject: [PATCH 715/725] overlays: audremap: Support GPIOs 18 & 19 + +PWM audio can also be used on GPIOs 18 and 19, so add the pins_18_19 +parameter to select that location. pins_12_13 explicitly chooses GPIOs +12 and 13, although this is the default behaviour so is there only for +completeness. + +See: https://github.com/raspberrypi/firmware/issues/1178 + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/overlays/README | 4 +++- + arch/arm/boot/dts/overlays/audremap-overlay.dts | 16 ++++++++++++++++ + 2 files changed, 19 insertions(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -475,12 +475,14 @@ Params: + + + Name: audremap +-Info: Switches PWM sound output to pins 12 (Right) & 13 (Left) ++Info: Switches PWM sound output to GPIOs on the 40-pin header + Load: dtoverlay=audremap,= + Params: swap_lr Reverse the channel allocation, which will also + swap the audio jack outputs (default off) + enable_jack Don't switch off the audio jack output + (default off) ++ pins_12_13 Select GPIOs 12 & 13 (default) ++ pins_18_19 Select GPIOs 18 & 19 + + + Name: balena-fin +--- a/arch/arm/boot/dts/overlays/audremap-overlay.dts ++++ b/arch/arm/boot/dts/overlays/audremap-overlay.dts +@@ -7,13 +7,29 @@ + fragment@0 { + target = <&audio_pins>; + frag0: __overlay__ { ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&audio_pins>; ++ __overlay__ { + brcm,pins = < 12 13 >; + brcm,function = < 4 >; /* alt0 alt0 */ + }; + }; + ++ fragment@2 { ++ target = <&audio_pins>; ++ __dormant__ { ++ brcm,pins = < 18 19 >; ++ brcm,function = < 2 >; /* alt5 alt5 */ ++ }; ++ }; ++ + __overrides__ { + swap_lr = <&frag0>, "swap_lr?"; + enable_jack = <&frag0>, "enable_jack?"; ++ pins_12_13 = <0>,"+1-2"; ++ pins_18_19 = <0>,"-1+2"; + }; + }; diff --git a/target/linux/brcm2708/patches-4.19/950-0716-drm-connector-Fix-drm_mode_create_tv_properties-doc.patch b/target/linux/brcm2708/patches-4.19/950-0716-drm-connector-Fix-drm_mode_create_tv_properties-doc.patch new file mode 100644 index 0000000000..3ecb2d86b2 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0716-drm-connector-Fix-drm_mode_create_tv_properties-doc.patch @@ -0,0 +1,29 @@ +From 522215d35cc376e452584dfc9d78aa68600861b8 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Thu, 6 Dec 2018 15:24:35 +0100 +Subject: [PATCH 716/725] drm/connector: Fix drm_mode_create_tv_properties() + doc + +Commit eda6887f1961e0d2fb866b1a520b2de5b3828de5 upstream. + +The in the kernel-doc header did not match the function name. + +Signed-off-by: Boris Brezillon +Reviewed-by: Eric Anholt +Acked-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/20181206142439.10441-2-boris.brezillon@bootlin.com +--- + drivers/gpu/drm/drm_connector.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/drm_connector.c ++++ b/drivers/gpu/drm/drm_connector.c +@@ -1110,7 +1110,7 @@ void drm_hdmi_avi_infoframe_content_type + EXPORT_SYMBOL(drm_hdmi_avi_infoframe_content_type); + + /** +- * drm_create_tv_properties - create TV specific connector properties ++ * drm_mode_create_tv_properties - create TV specific connector properties + * @dev: DRM device + * @num_modes: number of different TV formats (modes) supported + * @modes: array of pointers to strings containing name of each format diff --git a/target/linux/brcm2708/patches-4.19/950-0717-drm-connector-Clarify-the-unit-of-TV-margins.patch b/target/linux/brcm2708/patches-4.19/950-0717-drm-connector-Clarify-the-unit-of-TV-margins.patch new file mode 100644 index 0000000000..9116976bd0 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0717-drm-connector-Clarify-the-unit-of-TV-margins.patch @@ -0,0 +1,58 @@ +From ef59d7d000bea6755a9e57bd0d7b6558172dad22 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Thu, 6 Dec 2018 15:24:36 +0100 +Subject: [PATCH 717/725] drm/connector: Clarify the unit of TV margins + +Commit 56406e15b5e83256151ef74eb1a219cbf13d91c8 upstream. + +All margins are expressed in pixels. Clarify that in the doc. + +Signed-off-by: Boris Brezillon +Reviewed-by: Eric Anholt +Acked-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/20181206142439.10441-3-boris.brezillon@bootlin.com +--- + include/drm/drm_connector.h | 2 +- + include/drm/drm_mode_config.h | 8 ++++---- + 2 files changed, 5 insertions(+), 5 deletions(-) + +--- a/include/drm/drm_connector.h ++++ b/include/drm/drm_connector.h +@@ -346,7 +346,7 @@ int drm_display_info_set_bus_formats(str + /** + * struct drm_tv_connector_state - TV connector related states + * @subconnector: selected subconnector +- * @margins: margins ++ * @margins: margins (all margins are expressed in pixels) + * @margins.left: left margin + * @margins.right: right margin + * @margins.top: top margin +--- a/include/drm/drm_mode_config.h ++++ b/include/drm/drm_mode_config.h +@@ -668,22 +668,22 @@ struct drm_mode_config { + struct drm_property *tv_mode_property; + /** + * @tv_left_margin_property: Optional TV property to set the left +- * margin. ++ * margin (expressed in pixels). + */ + struct drm_property *tv_left_margin_property; + /** + * @tv_right_margin_property: Optional TV property to set the right +- * margin. ++ * margin (expressed in pixels). + */ + struct drm_property *tv_right_margin_property; + /** + * @tv_top_margin_property: Optional TV property to set the right +- * margin. ++ * margin (expressed in pixels). + */ + struct drm_property *tv_top_margin_property; + /** + * @tv_bottom_margin_property: Optional TV property to set the right +- * margin. ++ * margin (expressed in pixels). + */ + struct drm_property *tv_bottom_margin_property; + /** diff --git a/target/linux/brcm2708/patches-4.19/950-0718-drm-connector-Allow-creation-of-margin-props-alone.patch b/target/linux/brcm2708/patches-4.19/950-0718-drm-connector-Allow-creation-of-margin-props-alone.patch new file mode 100644 index 0000000000..36f5076451 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0718-drm-connector-Allow-creation-of-margin-props-alone.patch @@ -0,0 +1,136 @@ +From 551ce8969f5b671760523202b4af7e059389917e Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Thu, 6 Dec 2018 15:24:37 +0100 +Subject: [PATCH 718/725] drm/connector: Allow creation of margin props alone + +Commit 6c4f52dca36f5e3e2354c30591d38e92f4657ed9 upstream. + +TV margins properties can only be added as part of the SDTV TV +connector properties creation, but we might need those props for HDMI +TVs too, so let's move the margins props creation in a separate +function and expose it to drivers. + +We also add an helper to attach margins props to a connector. + +Signed-off-by: Boris Brezillon +Reviewed-by: Eric Anholt +Acked-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/20181206142439.10441-4-boris.brezillon@bootlin.com +--- + drivers/gpu/drm/drm_connector.c | 83 ++++++++++++++++++++++++++------- + include/drm/drm_connector.h | 2 + + 2 files changed, 67 insertions(+), 18 deletions(-) + +--- a/drivers/gpu/drm/drm_connector.c ++++ b/drivers/gpu/drm/drm_connector.c +@@ -1110,6 +1110,70 @@ void drm_hdmi_avi_infoframe_content_type + EXPORT_SYMBOL(drm_hdmi_avi_infoframe_content_type); + + /** ++ * drm_mode_attach_tv_margin_properties - attach TV connector margin properties ++ * @connector: DRM connector ++ * ++ * Called by a driver when it needs to attach TV margin props to a connector. ++ * Typically used on SDTV and HDMI connectors. ++ */ ++void drm_connector_attach_tv_margin_properties(struct drm_connector *connector) ++{ ++ struct drm_device *dev = connector->dev; ++ ++ drm_object_attach_property(&connector->base, ++ dev->mode_config.tv_left_margin_property, ++ 0); ++ drm_object_attach_property(&connector->base, ++ dev->mode_config.tv_right_margin_property, ++ 0); ++ drm_object_attach_property(&connector->base, ++ dev->mode_config.tv_top_margin_property, ++ 0); ++ drm_object_attach_property(&connector->base, ++ dev->mode_config.tv_bottom_margin_property, ++ 0); ++} ++EXPORT_SYMBOL(drm_connector_attach_tv_margin_properties); ++ ++/** ++ * drm_mode_create_tv_margin_properties - create TV connector margin properties ++ * @dev: DRM device ++ * ++ * Called by a driver's HDMI connector initialization routine, this function ++ * creates the TV margin properties for a given device. No need to call this ++ * function for an SDTV connector, it's already called from ++ * drm_mode_create_tv_properties(). ++ */ ++int drm_mode_create_tv_margin_properties(struct drm_device *dev) ++{ ++ if (dev->mode_config.tv_left_margin_property) ++ return 0; ++ ++ dev->mode_config.tv_left_margin_property = ++ drm_property_create_range(dev, 0, "left margin", 0, 100); ++ if (!dev->mode_config.tv_left_margin_property) ++ return -ENOMEM; ++ ++ dev->mode_config.tv_right_margin_property = ++ drm_property_create_range(dev, 0, "right margin", 0, 100); ++ if (!dev->mode_config.tv_right_margin_property) ++ return -ENOMEM; ++ ++ dev->mode_config.tv_top_margin_property = ++ drm_property_create_range(dev, 0, "top margin", 0, 100); ++ if (!dev->mode_config.tv_top_margin_property) ++ return -ENOMEM; ++ ++ dev->mode_config.tv_bottom_margin_property = ++ drm_property_create_range(dev, 0, "bottom margin", 0, 100); ++ if (!dev->mode_config.tv_bottom_margin_property) ++ return -ENOMEM; ++ ++ return 0; ++} ++EXPORT_SYMBOL(drm_mode_create_tv_margin_properties); ++ ++/** + * drm_mode_create_tv_properties - create TV specific connector properties + * @dev: DRM device + * @num_modes: number of different TV formats (modes) supported +@@ -1155,24 +1219,7 @@ int drm_mode_create_tv_properties(struct + /* + * Other, TV specific properties: margins & TV modes. + */ +- dev->mode_config.tv_left_margin_property = +- drm_property_create_range(dev, 0, "left margin", 0, 100); +- if (!dev->mode_config.tv_left_margin_property) +- goto nomem; +- +- dev->mode_config.tv_right_margin_property = +- drm_property_create_range(dev, 0, "right margin", 0, 100); +- if (!dev->mode_config.tv_right_margin_property) +- goto nomem; +- +- dev->mode_config.tv_top_margin_property = +- drm_property_create_range(dev, 0, "top margin", 0, 100); +- if (!dev->mode_config.tv_top_margin_property) +- goto nomem; +- +- dev->mode_config.tv_bottom_margin_property = +- drm_property_create_range(dev, 0, "bottom margin", 0, 100); +- if (!dev->mode_config.tv_bottom_margin_property) ++ if (drm_mode_create_tv_margin_properties(dev)) + goto nomem; + + dev->mode_config.tv_mode_property = +--- a/include/drm/drm_connector.h ++++ b/include/drm/drm_connector.h +@@ -1175,9 +1175,11 @@ const char *drm_get_tv_select_name(int v + const char *drm_get_content_protection_name(int val); + + int drm_mode_create_dvi_i_properties(struct drm_device *dev); ++int drm_mode_create_tv_margin_properties(struct drm_device *dev); + int drm_mode_create_tv_properties(struct drm_device *dev, + unsigned int num_modes, + const char * const modes[]); ++void drm_connector_attach_tv_margin_properties(struct drm_connector *conn); + int drm_mode_create_scaling_mode_property(struct drm_device *dev); + int drm_connector_attach_content_type_property(struct drm_connector *dev); + int drm_connector_attach_scaling_mode_property(struct drm_connector *connector, diff --git a/target/linux/brcm2708/patches-4.19/950-0719-drm-vc4-Take-margin-setup-into-account-when-updating.patch b/target/linux/brcm2708/patches-4.19/950-0719-drm-vc4-Take-margin-setup-into-account-when-updating.patch new file mode 100644 index 0000000000..fc124f6f7c --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0719-drm-vc4-Take-margin-setup-into-account-when-updating.patch @@ -0,0 +1,185 @@ +From 4ede5cbb2dffb6c2d5a29a1da8daa851b8351c55 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Thu, 6 Dec 2018 15:24:38 +0100 +Subject: [PATCH 719/725] drm/vc4: Take margin setup into account when updating + planes + +Commit 666e73587f90f42d90385c1bea1009a650bf73f4 upstream. + +Applyin margins is just a matter of scaling all planes appropriately +and adjusting the CRTC X/Y offset to account for the +left/right/top/bottom borders. + +Create a vc4_plane_margins_adj() function doing that and call it from +vc4_plane_setup_clipping_and_scaling() so that we are ready to attach +margins properties to the HDMI connector. + +Signed-off-by: Boris Brezillon +Reviewed-by: Eric Anholt +Acked-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/20181206142439.10441-5-boris.brezillon@bootlin.com +--- + drivers/gpu/drm/vc4/vc4_crtc.c | 43 +++++++++++++++++++++++++++ + drivers/gpu/drm/vc4/vc4_drv.h | 3 ++ + drivers/gpu/drm/vc4/vc4_plane.c | 51 +++++++++++++++++++++++++++++++++ + 3 files changed, 97 insertions(+) + +--- a/drivers/gpu/drm/vc4/vc4_crtc.c ++++ b/drivers/gpu/drm/vc4/vc4_crtc.c +@@ -48,6 +48,13 @@ struct vc4_crtc_state { + struct drm_mm_node mm; + bool feed_txp; + bool txp_armed; ++ ++ struct { ++ unsigned int left; ++ unsigned int right; ++ unsigned int top; ++ unsigned int bottom; ++ } margins; + }; + + static inline struct vc4_crtc_state * +@@ -623,6 +630,37 @@ static enum drm_mode_status vc4_crtc_mod + return MODE_OK; + } + ++void vc4_crtc_get_margins(struct drm_crtc_state *state, ++ unsigned int *left, unsigned int *right, ++ unsigned int *top, unsigned int *bottom) ++{ ++ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state); ++ struct drm_connector_state *conn_state; ++ struct drm_connector *conn; ++ int i; ++ ++ *left = vc4_state->margins.left; ++ *right = vc4_state->margins.right; ++ *top = vc4_state->margins.top; ++ *bottom = vc4_state->margins.bottom; ++ ++ /* We have to interate over all new connector states because ++ * vc4_crtc_get_margins() might be called before ++ * vc4_crtc_atomic_check() which means margins info in vc4_crtc_state ++ * might be outdated. ++ */ ++ for_each_new_connector_in_state(state->state, conn, conn_state, i) { ++ if (conn_state->crtc != state->crtc) ++ continue; ++ ++ *left = conn_state->tv.margins.left; ++ *right = conn_state->tv.margins.right; ++ *top = conn_state->tv.margins.top; ++ *bottom = conn_state->tv.margins.bottom; ++ break; ++ } ++} ++ + static int vc4_crtc_atomic_check(struct drm_crtc *crtc, + struct drm_crtc_state *state) + { +@@ -670,6 +708,10 @@ static int vc4_crtc_atomic_check(struct + vc4_state->feed_txp = false; + } + ++ vc4_state->margins.left = conn_state->tv.margins.left; ++ vc4_state->margins.right = conn_state->tv.margins.right; ++ vc4_state->margins.top = conn_state->tv.margins.top; ++ vc4_state->margins.bottom = conn_state->tv.margins.bottom; + break; + } + +@@ -971,6 +1013,7 @@ static struct drm_crtc_state *vc4_crtc_d + + old_vc4_state = to_vc4_crtc_state(crtc->state); + vc4_state->feed_txp = old_vc4_state->feed_txp; ++ vc4_state->margins = old_vc4_state->margins; + + __drm_atomic_helper_crtc_duplicate_state(crtc, &vc4_state->base); + return &vc4_state->base; +--- a/drivers/gpu/drm/vc4/vc4_drv.h ++++ b/drivers/gpu/drm/vc4/vc4_drv.h +@@ -705,6 +705,9 @@ bool vc4_crtc_get_scanoutpos(struct drm_ + const struct drm_display_mode *mode); + void vc4_crtc_handle_vblank(struct vc4_crtc *crtc); + void vc4_crtc_txp_armed(struct drm_crtc_state *state); ++void vc4_crtc_get_margins(struct drm_crtc_state *state, ++ unsigned int *right, unsigned int *left, ++ unsigned int *top, unsigned int *bottom); + + /* vc4_debugfs.c */ + int vc4_debugfs_init(struct drm_minor *minor); +--- a/drivers/gpu/drm/vc4/vc4_plane.c ++++ b/drivers/gpu/drm/vc4/vc4_plane.c +@@ -258,6 +258,52 @@ static u32 vc4_get_scl_field(struct drm_ + } + } + ++static int vc4_plane_margins_adj(struct drm_plane_state *pstate) ++{ ++ struct vc4_plane_state *vc4_pstate = to_vc4_plane_state(pstate); ++ unsigned int left, right, top, bottom, adjhdisplay, adjvdisplay; ++ struct drm_crtc_state *crtc_state; ++ ++ crtc_state = drm_atomic_get_new_crtc_state(pstate->state, ++ pstate->crtc); ++ ++ vc4_crtc_get_margins(crtc_state, &left, &right, &top, &bottom); ++ if (!left && !right && !top && !bottom) ++ return 0; ++ ++ if (left + right >= crtc_state->mode.hdisplay || ++ top + bottom >= crtc_state->mode.vdisplay) ++ return -EINVAL; ++ ++ adjhdisplay = crtc_state->mode.hdisplay - (left + right); ++ vc4_pstate->crtc_x = DIV_ROUND_CLOSEST(vc4_pstate->crtc_x * ++ adjhdisplay, ++ crtc_state->mode.hdisplay); ++ vc4_pstate->crtc_x += left; ++ if (vc4_pstate->crtc_x > crtc_state->mode.hdisplay - left) ++ vc4_pstate->crtc_x = crtc_state->mode.hdisplay - left; ++ ++ adjvdisplay = crtc_state->mode.vdisplay - (top + bottom); ++ vc4_pstate->crtc_y = DIV_ROUND_CLOSEST(vc4_pstate->crtc_y * ++ adjvdisplay, ++ crtc_state->mode.vdisplay); ++ vc4_pstate->crtc_y += top; ++ if (vc4_pstate->crtc_y > crtc_state->mode.vdisplay - top) ++ vc4_pstate->crtc_y = crtc_state->mode.vdisplay - top; ++ ++ vc4_pstate->crtc_w = DIV_ROUND_CLOSEST(vc4_pstate->crtc_w * ++ adjhdisplay, ++ crtc_state->mode.hdisplay); ++ vc4_pstate->crtc_h = DIV_ROUND_CLOSEST(vc4_pstate->crtc_h * ++ adjvdisplay, ++ crtc_state->mode.vdisplay); ++ ++ if (!vc4_pstate->crtc_w || !vc4_pstate->crtc_h) ++ return -EINVAL; ++ ++ return 0; ++} ++ + static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state) + { + struct drm_plane *plane = state->plane; +@@ -269,6 +315,7 @@ static int vc4_plane_setup_clipping_and_ + int num_planes = fb->format->num_planes; + u32 h_subsample = 1; + u32 v_subsample = 1; ++ int ret; + int i; + + for (i = 0; i < num_planes; i++) +@@ -292,6 +339,10 @@ static int vc4_plane_setup_clipping_and_ + vc4_state->crtc_w = state->crtc_w; + vc4_state->crtc_h = state->crtc_h; + ++ ret = vc4_plane_margins_adj(state); ++ if (ret) ++ return ret; ++ + vc4_state->x_scaling[0] = vc4_get_scaling_mode(vc4_state->src_w[0], + vc4_state->crtc_w); + vc4_state->y_scaling[0] = vc4_get_scaling_mode(vc4_state->src_h[0], diff --git a/target/linux/brcm2708/patches-4.19/950-0720-drm-vc4-Attach-margin-props-to-the-HDMI-connector.patch b/target/linux/brcm2708/patches-4.19/950-0720-drm-vc4-Attach-margin-props-to-the-HDMI-connector.patch new file mode 100644 index 0000000000..10827939c1 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0720-drm-vc4-Attach-margin-props-to-the-HDMI-connector.patch @@ -0,0 +1,71 @@ +From c0f966a04d5ff984a33d7d7b9c3cdc32514ebc14 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Thu, 6 Dec 2018 15:24:39 +0100 +Subject: [PATCH 720/725] drm/vc4: Attach margin props to the HDMI connector + +Commit db999538fdb0679629d90652f8a1437df1e85a7d upstream. + +Now that the plane code takes the margins setup into account, we can +safely attach margin props to the HDMI connector. + +We also take care of filling AVI infoframes correctly to expose the +top/botton/left/right bar. + +Note that those margin props match pretty well the +overscan_{left,right,top,bottom} properties defined in config.txt and +parsed by the VC4 firmware. + +Signed-off-by: Boris Brezillon +Reviewed-by: Eric Anholt +Acked-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/20181206142439.10441-6-boris.brezillon@bootlin.com +--- + drivers/gpu/drm/vc4/vc4_hdmi.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -310,6 +310,7 @@ static struct drm_connector *vc4_hdmi_co + { + struct drm_connector *connector; + struct vc4_hdmi_connector *hdmi_connector; ++ int ret; + + hdmi_connector = devm_kzalloc(dev->dev, sizeof(*hdmi_connector), + GFP_KERNEL); +@@ -323,6 +324,13 @@ static struct drm_connector *vc4_hdmi_co + DRM_MODE_CONNECTOR_HDMIA); + drm_connector_helper_add(connector, &vc4_hdmi_connector_helper_funcs); + ++ /* Create and attach TV margin props to this connector. */ ++ ret = drm_mode_create_tv_margin_properties(dev); ++ if (ret) ++ return ERR_PTR(ret); ++ ++ drm_connector_attach_tv_margin_properties(connector); ++ + connector->polled = (DRM_CONNECTOR_POLL_CONNECT | + DRM_CONNECTOR_POLL_DISCONNECT); + +@@ -408,6 +416,9 @@ static void vc4_hdmi_write_infoframe(str + static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder) + { + struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder); ++ struct vc4_dev *vc4 = encoder->dev->dev_private; ++ struct vc4_hdmi *hdmi = vc4->hdmi; ++ struct drm_connector_state *cstate = hdmi->connector->state; + struct drm_crtc *crtc = encoder->crtc; + const struct drm_display_mode *mode = &crtc->state->adjusted_mode; + union hdmi_infoframe frame; +@@ -426,6 +437,11 @@ static void vc4_hdmi_set_avi_infoframe(s + vc4_encoder->rgb_range_selectable, + false); + ++ frame.avi.right_bar = cstate->tv.margins.right; ++ frame.avi.left_bar = cstate->tv.margins.left; ++ frame.avi.top_bar = cstate->tv.margins.top; ++ frame.avi.bottom_bar = cstate->tv.margins.bottom; ++ + vc4_hdmi_write_infoframe(encoder, &frame); + } + diff --git a/target/linux/brcm2708/patches-4.19/950-0721-drm-vc4-Add-support-for-margins-to-fkms.patch b/target/linux/brcm2708/patches-4.19/950-0721-drm-vc4-Add-support-for-margins-to-fkms.patch new file mode 100644 index 0000000000..7b2077f650 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0721-drm-vc4-Add-support-for-margins-to-fkms.patch @@ -0,0 +1,328 @@ +From c72b6c3836cf40b2a72e613db2d4a225b75e2e92 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 19 Jul 2019 15:35:13 +0100 +Subject: [PATCH 721/725] drm/vc4: Add support for margins to fkms + +Allows for overscan to be configured under FKMS. +NB This is rescaling the planes, not reducing the size of the +display mode. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 241 +++++++++++++++++++------ + 1 file changed, 190 insertions(+), 51 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -256,6 +256,23 @@ static inline struct vc4_crtc *to_vc4_cr + return container_of(crtc, struct vc4_crtc, base); + } + ++struct vc4_crtc_state { ++ struct drm_crtc_state base; ++ ++ struct { ++ unsigned int left; ++ unsigned int right; ++ unsigned int top; ++ unsigned int bottom; ++ } margins; ++}; ++ ++static inline struct vc4_crtc_state * ++to_vc4_crtc_state(struct drm_crtc_state *crtc_state) ++{ ++ return (struct vc4_crtc_state *)crtc_state; ++} ++ + struct vc4_fkms_encoder { + struct drm_encoder base; + bool hdmi_monitor; +@@ -365,17 +382,127 @@ static int vc4_plane_set_blank(struct dr + return ret; + } + ++static void vc4_fkms_crtc_get_margins(struct drm_crtc_state *state, ++ unsigned int *left, unsigned int *right, ++ unsigned int *top, unsigned int *bottom) ++{ ++ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state); ++ struct drm_connector_state *conn_state; ++ struct drm_connector *conn; ++ int i; ++ ++ *left = vc4_state->margins.left; ++ *right = vc4_state->margins.right; ++ *top = vc4_state->margins.top; ++ *bottom = vc4_state->margins.bottom; ++ ++ /* We have to interate over all new connector states because ++ * vc4_fkms_crtc_get_margins() might be called before ++ * vc4_fkms_crtc_atomic_check() which means margins info in ++ * vc4_crtc_state might be outdated. ++ */ ++ for_each_new_connector_in_state(state->state, conn, conn_state, i) { ++ if (conn_state->crtc != state->crtc) ++ continue; ++ ++ *left = conn_state->tv.margins.left; ++ *right = conn_state->tv.margins.right; ++ *top = conn_state->tv.margins.top; ++ *bottom = conn_state->tv.margins.bottom; ++ break; ++ } ++} ++ ++static int vc4_fkms_margins_adj(struct drm_plane_state *pstate, ++ struct set_plane *plane) ++{ ++ unsigned int left, right, top, bottom; ++ int adjhdisplay, adjvdisplay; ++ struct drm_crtc_state *crtc_state; ++ ++ crtc_state = drm_atomic_get_new_crtc_state(pstate->state, ++ pstate->crtc); ++ ++ vc4_fkms_crtc_get_margins(crtc_state, &left, &right, &top, &bottom); ++ ++ if (!left && !right && !top && !bottom) ++ return 0; ++ ++ if (left + right >= crtc_state->mode.hdisplay || ++ top + bottom >= crtc_state->mode.vdisplay) ++ return -EINVAL; ++ ++ adjhdisplay = crtc_state->mode.hdisplay - (left + right); ++ plane->dst_x = DIV_ROUND_CLOSEST(plane->dst_x * adjhdisplay, ++ (int)crtc_state->mode.hdisplay); ++ plane->dst_x += left; ++ if (plane->dst_x > (int)(crtc_state->mode.hdisplay - left)) ++ plane->dst_x = crtc_state->mode.hdisplay - left; ++ ++ adjvdisplay = crtc_state->mode.vdisplay - (top + bottom); ++ plane->dst_y = DIV_ROUND_CLOSEST(plane->dst_y * adjvdisplay, ++ (int)crtc_state->mode.vdisplay); ++ plane->dst_y += top; ++ if (plane->dst_y > (int)(crtc_state->mode.vdisplay - top)) ++ plane->dst_y = crtc_state->mode.vdisplay - top; ++ ++ plane->dst_w = DIV_ROUND_CLOSEST(plane->dst_w * adjhdisplay, ++ crtc_state->mode.hdisplay); ++ plane->dst_h = DIV_ROUND_CLOSEST(plane->dst_h * adjvdisplay, ++ crtc_state->mode.vdisplay); ++ ++ if (!plane->dst_w || !plane->dst_h) ++ return -EINVAL; ++ ++ return 0; ++} ++ + static void vc4_plane_atomic_update(struct drm_plane *plane, + struct drm_plane_state *old_state) + { + struct drm_plane_state *state = plane->state; ++ ++ /* ++ * Do NOT set now, as we haven't checked if the crtc is active or not. ++ * Set from vc4_plane_set_blank instead. ++ * ++ * If the CRTC is on (or going to be on) and we're enabled, ++ * then unblank. Otherwise, stay blank until CRTC enable. ++ */ ++ if (state->crtc->state->active) ++ vc4_plane_set_blank(plane, false); ++} ++ ++static void vc4_plane_atomic_disable(struct drm_plane *plane, ++ struct drm_plane_state *old_state) ++{ ++ struct drm_plane_state *state = plane->state; ++ struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane); ++ ++ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] plane disable %dx%d@%d +%d,%d\n", ++ plane->base.id, plane->name, ++ state->crtc_w, ++ state->crtc_h, ++ vc4_plane->mb.plane.vc_image_type, ++ state->crtc_x, ++ state->crtc_y); ++ vc4_plane_set_blank(plane, true); ++} ++ ++static bool plane_enabled(struct drm_plane_state *state) ++{ ++ return state->fb && state->crtc; ++} ++ ++static int vc4_plane_to_mb(struct drm_plane *plane, ++ struct mailbox_set_plane *mb, ++ struct drm_plane_state *state) ++{ + struct drm_framebuffer *fb = state->fb; + struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); + const struct drm_format_info *drm_fmt = fb->format; + const struct vc_image_format *vc_fmt = + vc4_get_vc_image_fmt(drm_fmt->format); +- struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane); +- struct mailbox_set_plane *mb = &vc4_plane->mb; + int num_planes = fb->format->num_planes; + struct drm_display_mode *mode = &state->crtc->mode; + unsigned int rotation = SUPPORTED_ROTATIONS; +@@ -417,25 +544,7 @@ static void vc4_plane_atomic_update(stru + break; + } + +- /* FIXME: If the dest rect goes off screen then clip the src rect so we +- * don't have off-screen pixels. +- */ +- if (plane->type == DRM_PLANE_TYPE_CURSOR) { +- /* There is no scaling on the cursor plane, therefore the calcs +- * to alter the source crop as the cursor goes off the screen +- * are simple. +- */ +- if (mb->plane.dst_x + mb->plane.dst_w > mode->hdisplay) { +- mb->plane.dst_w = mode->hdisplay - mb->plane.dst_x; +- mb->plane.src_w = (mode->hdisplay - mb->plane.dst_x) +- << 16; +- } +- if (mb->plane.dst_y + mb->plane.dst_h > mode->vdisplay) { +- mb->plane.dst_h = mode->vdisplay - mb->plane.dst_y; +- mb->plane.src_h = (mode->vdisplay - mb->plane.dst_y) +- << 16; +- } +- } ++ vc4_fkms_margins_adj(state, &mb->plane); + + if (num_planes > 1) { + /* Assume this must be YUV */ +@@ -525,38 +634,19 @@ static void vc4_plane_atomic_update(stru + state->alpha, + state->normalized_zpos); + +- /* +- * Do NOT set now, as we haven't checked if the crtc is active or not. +- * Set from vc4_plane_set_blank instead. +- * +- * If the CRTC is on (or going to be on) and we're enabled, +- * then unblank. Otherwise, stay blank until CRTC enable. +- */ +- if (state->crtc->state->active) +- vc4_plane_set_blank(plane, false); ++ return 0; + } + +-static void vc4_plane_atomic_disable(struct drm_plane *plane, +- struct drm_plane_state *old_state) ++static int vc4_plane_atomic_check(struct drm_plane *plane, ++ struct drm_plane_state *state) + { +- //struct vc4_dev *vc4 = to_vc4_dev(plane->dev); +- struct drm_plane_state *state = plane->state; + struct vc4_fkms_plane *vc4_plane = to_vc4_fkms_plane(plane); + +- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] plane disable %dx%d@%d +%d,%d\n", +- plane->base.id, plane->name, +- state->crtc_w, +- state->crtc_h, +- vc4_plane->mb.plane.vc_image_type, +- state->crtc_x, +- state->crtc_y); +- vc4_plane_set_blank(plane, true); +-} ++ if (!plane_enabled(state)) ++ return 0; ++ ++ return vc4_plane_to_mb(plane, &vc4_plane->mb, state); + +-static int vc4_plane_atomic_check(struct drm_plane *plane, +- struct drm_plane_state *state) +-{ +- return 0; + } + + static void vc4_plane_destroy(struct drm_plane *plane) +@@ -878,8 +968,23 @@ vc4_crtc_mode_valid(struct drm_crtc *crt + static int vc4_crtc_atomic_check(struct drm_crtc *crtc, + struct drm_crtc_state *state) + { +- DRM_DEBUG_KMS("[CRTC:%d] crtc_atomic_check.\n", +- crtc->base.id); ++ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state); ++ struct drm_connector *conn; ++ struct drm_connector_state *conn_state; ++ int i; ++ ++ DRM_DEBUG_KMS("[CRTC:%d] crtc_atomic_check.\n", crtc->base.id); ++ ++ for_each_new_connector_in_state(state->state, conn, conn_state, i) { ++ if (conn_state->crtc != crtc) ++ continue; ++ ++ vc4_state->margins.left = conn_state->tv.margins.left; ++ vc4_state->margins.right = conn_state->tv.margins.right; ++ vc4_state->margins.top = conn_state->tv.margins.top; ++ vc4_state->margins.bottom = conn_state->tv.margins.bottom; ++ break; ++ } + return 0; + } + +@@ -980,6 +1085,33 @@ static int vc4_page_flip(struct drm_crtc + return drm_atomic_helper_page_flip(crtc, fb, event, flags, ctx); + } + ++static struct drm_crtc_state * ++vc4_crtc_duplicate_state(struct drm_crtc *crtc) ++{ ++ struct vc4_crtc_state *vc4_state, *old_vc4_state; ++ ++ vc4_state = kzalloc(sizeof(*vc4_state), GFP_KERNEL); ++ if (!vc4_state) ++ return NULL; ++ ++ old_vc4_state = to_vc4_crtc_state(crtc->state); ++ vc4_state->margins = old_vc4_state->margins; ++ ++ __drm_atomic_helper_crtc_duplicate_state(crtc, &vc4_state->base); ++ return &vc4_state->base; ++} ++ ++static void ++vc4_crtc_reset(struct drm_crtc *crtc) ++{ ++ if (crtc->state) ++ __drm_atomic_helper_crtc_destroy_state(crtc->state); ++ ++ crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL); ++ if (crtc->state) ++ crtc->state->crtc = crtc; ++} ++ + static int vc4_fkms_enable_vblank(struct drm_crtc *crtc) + { + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); +@@ -1007,8 +1139,8 @@ static const struct drm_crtc_funcs vc4_c + .set_property = NULL, + .cursor_set = NULL, /* handled by drm_mode_cursor_universal */ + .cursor_move = NULL, /* handled by drm_mode_cursor_universal */ +- .reset = drm_atomic_helper_crtc_reset, +- .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, ++ .reset = vc4_crtc_reset, ++ .atomic_duplicate_state = vc4_crtc_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, + .enable_vblank = vc4_fkms_enable_vblank, + .disable_vblank = vc4_fkms_disable_vblank, +@@ -1267,6 +1399,13 @@ vc4_fkms_connector_init(struct drm_devic + connector->interlace_allowed = 0; + } + ++ /* Create and attach TV margin props to this connector. */ ++ ret = drm_mode_create_tv_margin_properties(dev); ++ if (ret) ++ return ERR_PTR(ret); ++ ++ drm_connector_attach_tv_margin_properties(connector); ++ + connector->polled = (DRM_CONNECTOR_POLL_CONNECT | + DRM_CONNECTOR_POLL_DISCONNECT); + diff --git a/target/linux/brcm2708/patches-4.19/950-0722-drm-vc4-Ensure-zpos-is-always-initialised.patch b/target/linux/brcm2708/patches-4.19/950-0722-drm-vc4-Ensure-zpos-is-always-initialised.patch new file mode 100644 index 0000000000..99af3a3322 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0722-drm-vc4-Ensure-zpos-is-always-initialised.patch @@ -0,0 +1,26 @@ +From 261c08d7841e46294700409ae6b9c25f479ad94a Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 19 Jul 2019 17:49:00 +0100 +Subject: [PATCH 722/725] drm/vc4: Ensure zpos is always initialised + +The compiler is warning that default_zpos can be used +uninitialised as there is no default case to catch all plane +types. +No other plane types should ever be presented to vc4_fkms_plane_init, +but add a default case regardless. + +Signed-off-by: Dave Stevenson +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -773,6 +773,7 @@ static struct drm_plane *vc4_fkms_plane_ + * other layers as requested by KMS. + */ + switch (type) { ++ default: + case DRM_PLANE_TYPE_PRIMARY: + default_zpos = 0; + break; diff --git a/target/linux/brcm2708/patches-4.19/950-0723-dts-bcm2838-add-missing-properties-for-pmu-and-gic-n.patch b/target/linux/brcm2708/patches-4.19/950-0723-dts-bcm2838-add-missing-properties-for-pmu-and-gic-n.patch new file mode 100644 index 0000000000..edd9d0f771 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0723-dts-bcm2838-add-missing-properties-for-pmu-and-gic-n.patch @@ -0,0 +1,45 @@ +From c803db37ac929c9732ae02edf92925a00e600236 Mon Sep 17 00:00:00 2001 +From: Jonathan Bell +Date: Wed, 24 Jul 2019 14:36:53 +0100 +Subject: [PATCH 723/725] dts: bcm2838: add missing properties for pmu and gic + nodes + +The GIC has a virtual interface maintenance interrupt and the PMU +interrupts need affinity mappings as they are wired to generic SPIs. + +Also, delete incorrect PMU compatible string. + +Signed-off-by: Jonathan Bell +--- + arch/arm/boot/dts/bcm2838.dtsi | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/arch/arm/boot/dts/bcm2838.dtsi ++++ b/arch/arm/boot/dts/bcm2838.dtsi +@@ -35,6 +35,8 @@ + <0x40042000 0x2000>, + <0x40044000 0x2000>, + <0x40046000 0x2000>; ++ interrupts = ; + }; + + thermal: thermal@7d5d2200 { +@@ -222,15 +224,12 @@ + }; + + arm-pmu { +- /* +- * N.B. the A72 PMU support only exists in arch/arm64, hence +- * the fallback to the A53 version. +- */ +- compatible = "arm,cortex-a72-pmu", "arm,cortex-a53-pmu"; ++ compatible = "arm,cortex-a72-pmu"; + interrupts = , + , + , + ; ++ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; + }; + + timer { diff --git a/target/linux/brcm2708/patches-4.19/950-0724-adds-the-Hifiberry-DAC-ADC-PRO-version.patch b/target/linux/brcm2708/patches-4.19/950-0724-adds-the-Hifiberry-DAC-ADC-PRO-version.patch new file mode 100644 index 0000000000..3e019ccc13 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0724-adds-the-Hifiberry-DAC-ADC-PRO-version.patch @@ -0,0 +1,734 @@ +From 9404c34f9d9aef6f1c5a8f8c223865a5adb81518 Mon Sep 17 00:00:00 2001 +From: Joerg Schambacher +Date: Tue, 23 Jul 2019 16:57:35 +0200 +Subject: [PATCH 724/725] adds the Hifiberry DAC+ADC PRO version + +This adds the driver for the DAC+ADC PRO version of the Hifiberry soundcard with software controlled PCM1863 ADC +Signed-off-by: Joerg Schambacher joerg@i2audio.com +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 21 + + .../hifiberry-dacplusadcpro-overlay.dts | 64 +++ + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcm2711_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + sound/soc/bcm/Kconfig | 8 + + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/hifiberry_dacplusadcpro.c | 538 ++++++++++++++++++ + 9 files changed, 637 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dacplusadcpro-overlay.dts + create mode 100644 sound/soc/bcm/hifiberry_dacplusadcpro.c + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -53,6 +53,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + hifiberry-dac.dtbo \ + hifiberry-dacplus.dtbo \ + hifiberry-dacplusadc.dtbo \ ++ hifiberry-dacplusadcpro.dtbo \ + hifiberry-digi.dtbo \ + hifiberry-digi-pro.dtbo \ + hy28a.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -883,6 +883,27 @@ Params: 24db_digital_gain Allow ga + master for bit clock and frame clock. + + ++Name: hifiberry-dacplusadcpro ++Info: Configures the HifiBerry DAC+ADC PRO audio card ++Load: dtoverlay=hifiberry-dacplusadcpro,= ++Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec ++ Digital volume control. Enable with ++ "dtoverlay=hifiberry-dacplusadcpro,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!) ++ slave Force DAC+ADC Pro into slave mode, using Pi as ++ master for bit clock and frame clock. ++ ++ + Name: hifiberry-digi + Info: Configures the HifiBerry Digi and Digi+ audio card + Load: dtoverlay=hifiberry-digi +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/hifiberry-dacplusadcpro-overlay.dts +@@ -0,0 +1,64 @@ ++// Definitions for HiFiBerry DAC+ADC PRO ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/clocks"; ++ __overlay__ { ++ dacpro_osc: dacpro_osc { ++ compatible = "hifiberry,dacpro-clk"; ++ #clock-cells = <0>; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ hb_dac: pcm5122@4d { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm5122"; ++ reg = <0x4d>; ++ clocks = <&dacpro_osc>; ++ status = "okay"; ++ }; ++ hb_adc: pcm186x@4a { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm1863"; ++ reg = <0x4a>; ++ clocks = <&dacpro_osc>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&sound>; ++ hifiberry_dacplusadcpro: __overlay__ { ++ compatible = "hifiberry,hifiberry-dacplusadcpro"; ++ audio-codec = <&hb_dac &hb_adc>; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ __overrides__ { ++ 24db_digital_gain = ++ <&hifiberry_dacplusadcpro>,"hifiberry-dacplusadcpro,24db_digital_gain?"; ++ slave = <&hifiberry_dacplusadcpro>,"hifiberry-dacplusadcpro,slave?"; ++ }; ++}; +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -961,6 +961,7 @@ CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SO + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADCPRO=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m + CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=m +--- a/arch/arm/configs/bcm2711_defconfig ++++ b/arch/arm/configs/bcm2711_defconfig +@@ -972,6 +972,7 @@ CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SO + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADCPRO=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m + CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=m +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -953,6 +953,7 @@ CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SO + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADCPRO=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m + CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m + CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=m +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -48,6 +48,14 @@ config SND_BCM2708_SOC_HIFIBERRY_DACPLUS + help + Say Y or M if you want to add support for HifiBerry DAC+ADC. + ++config SND_BCM2708_SOC_HIFIBERRY_DACPLUSADCPRO ++ tristate "Support for HifiBerry DAC+ADC PRO" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_PCM512x_I2C ++ select SND_SOC_PCM186X_I2C ++ help ++ Say Y or M if you want to add support for HifiBerry DAC+ADC PRO. ++ + config SND_BCM2708_SOC_HIFIBERRY_DIGI + tristate "Support for HifiBerry Digi" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -14,6 +14,7 @@ snd-soc-googlevoicehat-codec-objs := goo + # BCM2708 Machine Support + snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o + snd-soc-hifiberry-dacplusadc-objs := hifiberry_dacplusadc.o ++snd-soc-hifiberry-dacplusadcpro-objs := hifiberry_dacplusadcpro.o + snd-soc-justboom-dac-objs := justboom-dac.o + snd-soc-rpi-cirrus-objs := rpi-cirrus.o + snd-soc-rpi-proto-objs := rpi-proto.o +@@ -38,6 +39,7 @@ snd-soc-rpi-wm8804-soundcard-objs := rpi + obj-$(CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD) += snd-soc-googlevoicehat-codec.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC) += snd-soc-hifiberry-dacplusadc.o ++obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADCPRO) += snd-soc-hifiberry-dacplusadcpro.o + obj-$(CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC) += snd-soc-justboom-dac.o + obj-$(CONFIG_SND_BCM2708_SOC_RPI_CIRRUS) += snd-soc-rpi-cirrus.o + obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o +--- /dev/null ++++ b/sound/soc/bcm/hifiberry_dacplusadcpro.c +@@ -0,0 +1,538 @@ ++/* ++ * ASoC Driver for HiFiBerry DAC+ / DAC Pro with ADC PRO Version (SW control) ++ * ++ * Author: Daniel Matuschek, Stuart MacLean ++ * Copyright 2014-2015 ++ * based on code by Florian Meier ++ * ADC added by Joerg Schambacher ++ * Copyright 2018-19 ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "../codecs/pcm512x.h" ++#include "../codecs/pcm186x.h" ++ ++#define HIFIBERRY_DACPRO_NOCLOCK 0 ++#define HIFIBERRY_DACPRO_CLK44EN 1 ++#define HIFIBERRY_DACPRO_CLK48EN 2 ++ ++struct pcm512x_priv { ++ struct regmap *regmap; ++ struct clk *sclk; ++}; ++ ++/* Clock rate of CLK44EN attached to GPIO6 pin */ ++#define CLK_44EN_RATE 22579200UL ++/* Clock rate of CLK48EN attached to GPIO3 pin */ ++#define CLK_48EN_RATE 24576000UL ++ ++static bool slave; ++static bool snd_rpi_hifiberry_is_dacpro; ++static bool digital_gain_0db_limit = true; ++ ++static const unsigned int pcm186x_adc_input_channel_sel_value[] = { ++ 0x00, 0x01, 0x02, 0x03, 0x10 ++}; ++ ++static const char * const pcm186x_adcl_input_channel_sel_text[] = { ++ "No Select", ++ "VINL1[SE]", /* Default for ADCL */ ++ "VINL2[SE]", ++ "VINL2[SE] + VINL1[SE]", ++ "{VIN1P, VIN1M}[DIFF]" ++}; ++ ++static const char * const pcm186x_adcr_input_channel_sel_text[] = { ++ "No Select", ++ "VINR1[SE]", /* Default for ADCR */ ++ "VINR2[SE]", ++ "VINR2[SE] + VINR1[SE]", ++ "{VIN2P, VIN2M}[DIFF]" ++}; ++ ++static const struct soc_enum pcm186x_adc_input_channel_sel[] = { ++ SOC_VALUE_ENUM_SINGLE(PCM186X_ADC1_INPUT_SEL_L, 0, ++ PCM186X_ADC_INPUT_SEL_MASK, ++ ARRAY_SIZE(pcm186x_adcl_input_channel_sel_text), ++ pcm186x_adcl_input_channel_sel_text, ++ pcm186x_adc_input_channel_sel_value), ++ SOC_VALUE_ENUM_SINGLE(PCM186X_ADC1_INPUT_SEL_R, 0, ++ PCM186X_ADC_INPUT_SEL_MASK, ++ ARRAY_SIZE(pcm186x_adcr_input_channel_sel_text), ++ pcm186x_adcr_input_channel_sel_text, ++ pcm186x_adc_input_channel_sel_value), ++}; ++ ++static const unsigned int pcm186x_mic_bias_sel_value[] = { ++ 0x00, 0x01, 0x11 ++}; ++ ++static const char * const pcm186x_mic_bias_sel_text[] = { ++ "Mic Bias off", ++ "Mic Bias on", ++ "Mic Bias with Bypass Resistor" ++}; ++ ++static const struct soc_enum pcm186x_mic_bias_sel[] = { ++ SOC_VALUE_ENUM_SINGLE(PCM186X_MIC_BIAS_CTRL, 0, ++ GENMASK(4, 0), ++ ARRAY_SIZE(pcm186x_mic_bias_sel_text), ++ pcm186x_mic_bias_sel_text, ++ pcm186x_mic_bias_sel_value), ++}; ++ ++static const unsigned int pcm186x_gain_sel_value[] = { ++ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, ++ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, ++ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, ++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, ++ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, ++ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, ++ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, ++ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, ++ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, ++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, ++ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, ++ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, ++ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, ++ 0x50 ++}; ++ ++static const char * const pcm186x_gain_sel_text[] = { ++ "-12.0dB", "-11.5dB", "-11.0dB", "-10.5dB", "-10.0dB", "-9.5dB", ++ "-9.0dB", "-8.5dB", "-8.0dB", "-7.5dB", "-7.0dB", "-6.5dB", ++ "-6.0dB", "-5.5dB", "-5.0dB", "-4.5dB", "-4.0dB", "-3.5dB", ++ "-3.0dB", "-2.5dB", "-2.0dB", "-1.5dB", "-1.0dB", "-0.5dB", ++ "0.0dB", "0.5dB", "1.0dB", "1.5dB", "2.0dB", "2.5dB", ++ "3.0dB", "3.5dB", "4.0dB", "4.5dB", "5.0dB", "5.5dB", ++ "6.0dB", "6.5dB", "7.0dB", "7.5dB", "8.0dB", "8.5dB", ++ "9.0dB", "9.5dB", "10.0dB", "10.5dB", "11.0dB", "11.5dB", ++ "12.0dB", "12.5dB", "13.0dB", "13.5dB", "14.0dB", "14.5dB", ++ "15.0dB", "15.5dB", "16.0dB", "16.5dB", "17.0dB", "17.5dB", ++ "18.0dB", "18.5dB", "19.0dB", "19.5dB", "20.0dB", "20.5dB", ++ "21.0dB", "21.5dB", "22.0dB", "22.5dB", "23.0dB", "23.5dB", ++ "24.0dB", "24.5dB", "25.0dB", "25.5dB", "26.0dB", "26.5dB", ++ "27.0dB", "27.5dB", "28.0dB", "28.5dB", "29.0dB", "29.5dB", ++ "30.0dB", "30.5dB", "31.0dB", "31.5dB", "32.0dB", "32.5dB", ++ "33.0dB", "33.5dB", "34.0dB", "34.5dB", "35.0dB", "35.5dB", ++ "36.0dB", "36.5dB", "37.0dB", "37.5dB", "38.0dB", "38.5dB", ++ "39.0dB", "39.5dB", "40.0dB"}; ++ ++static const struct soc_enum pcm186x_gain_sel[] = { ++ SOC_VALUE_ENUM_SINGLE(PCM186X_PGA_VAL_CH1_L, 0, ++ 0xff, ++ ARRAY_SIZE(pcm186x_gain_sel_text), ++ pcm186x_gain_sel_text, ++ pcm186x_gain_sel_value), ++ SOC_VALUE_ENUM_SINGLE(PCM186X_PGA_VAL_CH1_R, 0, ++ 0xff, ++ ARRAY_SIZE(pcm186x_gain_sel_text), ++ pcm186x_gain_sel_text, ++ pcm186x_gain_sel_value), ++}; ++ ++static const struct snd_kcontrol_new pcm1863_snd_controls_card[] = { ++ SOC_ENUM("ADC Left Input", pcm186x_adc_input_channel_sel[0]), ++ SOC_ENUM("ADC Right Input", pcm186x_adc_input_channel_sel[1]), ++ SOC_ENUM("ADC Mic Bias", pcm186x_mic_bias_sel), ++ SOC_ENUM("PGA Gain Left", pcm186x_gain_sel[0]), ++ SOC_ENUM("PGA Gain Right", pcm186x_gain_sel[1]), ++}; ++ ++static int pcm1863_add_controls(struct snd_soc_component *component) ++{ ++ snd_soc_add_component_controls(component, ++ pcm1863_snd_controls_card, ++ ARRAY_SIZE(pcm1863_snd_controls_card)); ++ return 0; ++} ++ ++static void snd_rpi_hifiberry_dacplusadcpro_select_clk( ++ struct snd_soc_component *component, int clk_id) ++{ ++ switch (clk_id) { ++ case HIFIBERRY_DACPRO_NOCLOCK: ++ snd_soc_component_update_bits(component, ++ PCM512x_GPIO_CONTROL_1, 0x24, 0x00); ++ break; ++ case HIFIBERRY_DACPRO_CLK44EN: ++ snd_soc_component_update_bits(component, ++ PCM512x_GPIO_CONTROL_1, 0x24, 0x20); ++ break; ++ case HIFIBERRY_DACPRO_CLK48EN: ++ snd_soc_component_update_bits(component, ++ PCM512x_GPIO_CONTROL_1, 0x24, 0x04); ++ break; ++ } ++} ++ ++static void snd_rpi_hifiberry_dacplusadcpro_clk_gpio(struct snd_soc_component *component) ++{ ++ snd_soc_component_update_bits(component, PCM512x_GPIO_EN, 0x24, 0x24); ++ snd_soc_component_update_bits(component, PCM512x_GPIO_OUTPUT_3, 0x0f, 0x02); ++ snd_soc_component_update_bits(component, PCM512x_GPIO_OUTPUT_6, 0x0f, 0x02); ++} ++ ++static bool snd_rpi_hifiberry_dacplusadcpro_is_sclk(struct snd_soc_component *component) ++{ ++ unsigned int sck; ++ ++ snd_soc_component_read(component, PCM512x_RATE_DET_4, &sck); ++ return (!(sck & 0x40)); ++} ++ ++static bool snd_rpi_hifiberry_dacplusadcpro_is_sclk_sleep( ++ struct snd_soc_component *component) ++{ ++ msleep(2); ++ return snd_rpi_hifiberry_dacplusadcpro_is_sclk(component); ++} ++ ++static bool snd_rpi_hifiberry_dacplusadcpro_is_pro_card(struct snd_soc_component *component) ++{ ++ bool isClk44EN, isClk48En, isNoClk; ++ ++ snd_rpi_hifiberry_dacplusadcpro_clk_gpio(component); ++ ++ snd_rpi_hifiberry_dacplusadcpro_select_clk(component, HIFIBERRY_DACPRO_CLK44EN); ++ isClk44EN = snd_rpi_hifiberry_dacplusadcpro_is_sclk_sleep(component); ++ ++ snd_rpi_hifiberry_dacplusadcpro_select_clk(component, HIFIBERRY_DACPRO_NOCLOCK); ++ isNoClk = snd_rpi_hifiberry_dacplusadcpro_is_sclk_sleep(component); ++ ++ snd_rpi_hifiberry_dacplusadcpro_select_clk(component, HIFIBERRY_DACPRO_CLK48EN); ++ isClk48En = snd_rpi_hifiberry_dacplusadcpro_is_sclk_sleep(component); ++ ++ return (isClk44EN && isClk48En && !isNoClk); ++} ++ ++static int snd_rpi_hifiberry_dacplusadcpro_clk_for_rate(int sample_rate) ++{ ++ int type; ++ ++ switch (sample_rate) { ++ case 11025: ++ case 22050: ++ case 44100: ++ case 88200: ++ case 176400: ++ case 352800: ++ type = HIFIBERRY_DACPRO_CLK44EN; ++ break; ++ default: ++ type = HIFIBERRY_DACPRO_CLK48EN; ++ break; ++ } ++ return type; ++} ++ ++static void snd_rpi_hifiberry_dacplusadcpro_set_sclk(struct snd_soc_component *component, ++ int sample_rate) ++{ ++ struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component); ++ ++ if (!IS_ERR(pcm512x->sclk)) { ++ int ctype; ++ ++ ctype = snd_rpi_hifiberry_dacplusadcpro_clk_for_rate(sample_rate); ++ clk_set_rate(pcm512x->sclk, (ctype == HIFIBERRY_DACPRO_CLK44EN) ++ ? CLK_44EN_RATE : CLK_48EN_RATE); ++ snd_rpi_hifiberry_dacplusadcpro_select_clk(component, ctype); ++ } ++} ++ ++static int snd_rpi_hifiberry_dacplusadcpro_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ struct snd_soc_component *dac = rtd->codec_dais[0]->component; ++ struct snd_soc_component *adc = rtd->codec_dais[1]->component; ++ struct snd_soc_dai_driver *adc_driver = rtd->codec_dais[1]->driver; ++ struct pcm512x_priv *priv; ++ int ret; ++ ++ if (slave) ++ snd_rpi_hifiberry_is_dacpro = false; ++ else ++ snd_rpi_hifiberry_is_dacpro = ++ snd_rpi_hifiberry_dacplusadcpro_is_pro_card(dac); ++ ++ if (snd_rpi_hifiberry_is_dacpro) { ++ struct snd_soc_dai_link *dai = rtd->dai_link; ++ ++ dai->name = "HiFiBerry DAC+ADC Pro"; ++ dai->stream_name = "HiFiBerry DAC+ADC Pro HiFi"; ++ ++ // set DAC DAI configuration ++ ret = snd_soc_dai_set_fmt(rtd->codec_dais[0], ++ SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF ++ | SND_SOC_DAIFMT_CBM_CFM); ++ if (ret < 0) ++ return ret; ++ ++ // set ADC DAI configuration ++ ret = snd_soc_dai_set_fmt(rtd->codec_dais[1], ++ SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF ++ | SND_SOC_DAIFMT_CBS_CFS); ++ if (ret < 0) ++ return ret; ++ ++ // set CPU DAI configuration ++ ret = snd_soc_dai_set_fmt(rtd->cpu_dai, ++ SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); ++ if (ret < 0) ++ return ret; ++ ++ snd_soc_component_update_bits(dac, PCM512x_BCLK_LRCLK_CFG, 0x31, 0x11); ++ snd_soc_component_update_bits(dac, PCM512x_MASTER_MODE, 0x03, 0x03); ++ snd_soc_component_update_bits(dac, PCM512x_MASTER_CLKDIV_2, 0x7f, 63); ++ } else { ++ priv = snd_soc_component_get_drvdata(dac); ++ priv->sclk = ERR_PTR(-ENOENT); ++ } ++ ++ /* disable 24bit mode as long as I2S module does not have sign extension fixed */ ++ adc_driver->capture.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE; ++ ++ snd_soc_component_update_bits(dac, PCM512x_GPIO_EN, 0x08, 0x08); ++ snd_soc_component_update_bits(dac, PCM512x_GPIO_OUTPUT_4, 0x0f, 0x02); ++ snd_soc_component_update_bits(dac, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); ++ ++ ret = pcm1863_add_controls(adc); ++ if (ret < 0) ++ dev_warn(rtd->dev, "Failed to add pcm1863 controls: %d\n", ++ ret); ++ ++ /* set GPIO2 to output, GPIO3 input */ ++ snd_soc_component_write(adc, PCM186X_GPIO3_2_CTRL, 0x00); ++ snd_soc_component_write(adc, PCM186X_GPIO3_2_DIR_CTRL, 0x04); ++ snd_soc_component_update_bits(adc, PCM186X_GPIO_IN_OUT, 0x40, 0x40); ++ ++ 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_hifiberry_dacplusadcpro_update_rate_den( ++ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_component *component = rtd->codec_dais[0]->component; /* only use DAC */ ++ struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component); ++ struct snd_ratnum *rats_no_pll; ++ unsigned int num = 0, den = 0; ++ int err; ++ ++ rats_no_pll = devm_kzalloc(rtd->dev, sizeof(*rats_no_pll), GFP_KERNEL); ++ if (!rats_no_pll) ++ return -ENOMEM; ++ ++ rats_no_pll->num = clk_get_rate(pcm512x->sclk) / 64; ++ rats_no_pll->den_min = 1; ++ rats_no_pll->den_max = 128; ++ rats_no_pll->den_step = 1; ++ ++ err = snd_interval_ratnum(hw_param_interval(params, ++ SNDRV_PCM_HW_PARAM_RATE), 1, rats_no_pll, &num, &den); ++ if (err >= 0 && den) { ++ params->rate_num = num; ++ params->rate_den = den; ++ } ++ ++ devm_kfree(rtd->dev, rats_no_pll); ++ return 0; ++} ++ ++static int snd_rpi_hifiberry_dacplusadcpro_hw_params( ++ struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) ++{ ++ int ret = 0; ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ int channels = params_channels(params); ++ int width = 32; ++ struct snd_soc_component *dac = rtd->codec_dais[0]->component; ++ ++ if (snd_rpi_hifiberry_is_dacpro) { ++ ++ width = snd_pcm_format_physical_width(params_format(params)); ++ ++ snd_rpi_hifiberry_dacplusadcpro_set_sclk(dac, ++ params_rate(params)); ++ ++ ret = snd_rpi_hifiberry_dacplusadcpro_update_rate_den( ++ substream, params); ++ if (ret) ++ return ret; ++ } ++ ++ ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x03, 0x03, ++ channels, width); ++ if (ret) ++ return ret; ++ ret = snd_soc_dai_set_tdm_slot(rtd->codec_dais[0], 0x03, 0x03, ++ channels, width); ++ if (ret) ++ return ret; ++ ret = snd_soc_dai_set_tdm_slot(rtd->codec_dais[1], 0x03, 0x03, ++ channels, width); ++ return ret; ++} ++ ++static int snd_rpi_hifiberry_dacplusadcpro_startup( ++ struct snd_pcm_substream *substream) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_component *dac = rtd->codec_dais[0]->component; ++ struct snd_soc_component *adc = rtd->codec_dais[1]->component; ++ ++ /* switch on respective LED */ ++ if (!substream->stream) ++ snd_soc_component_update_bits(dac, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); ++ else ++ snd_soc_component_update_bits(adc, PCM186X_GPIO_IN_OUT, 0x40, 0x40); ++ return 0; ++} ++ ++static void snd_rpi_hifiberry_dacplusadcpro_shutdown( ++ struct snd_pcm_substream *substream) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_component *dac = rtd->codec_dais[0]->component; ++ struct snd_soc_component *adc = rtd->codec_dais[1]->component; ++ ++ /* switch off respective LED */ ++ if (!substream->stream) ++ snd_soc_component_update_bits(dac, PCM512x_GPIO_CONTROL_1, 0x08, 0x00); ++ else ++ snd_soc_component_update_bits(adc, PCM186X_GPIO_IN_OUT, 0x40, 0x00); ++} ++ ++ ++/* machine stream operations */ ++static struct snd_soc_ops snd_rpi_hifiberry_dacplusadcpro_ops = { ++ .hw_params = snd_rpi_hifiberry_dacplusadcpro_hw_params, ++ .startup = snd_rpi_hifiberry_dacplusadcpro_startup, ++ .shutdown = snd_rpi_hifiberry_dacplusadcpro_shutdown, ++}; ++ ++static struct snd_soc_dai_link_component snd_rpi_hifiberry_dacplusadcpro_codecs[] = { ++ { ++ .name = "pcm512x.1-004d", ++ .dai_name = "pcm512x-hifi", ++ }, ++ { ++ .name = "pcm186x.1-004a", ++ .dai_name = "pcm1863-aif", ++ }, ++}; ++ ++static struct snd_soc_dai_link snd_rpi_hifiberry_dacplusadcpro_dai[] = { ++{ ++ .name = "HiFiBerry DAC+ADC PRO", ++ .stream_name = "HiFiBerry DAC+ADC PRO HiFi", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .platform_name = "bcm2708-i2s.0", ++ .codecs = snd_rpi_hifiberry_dacplusadcpro_codecs, ++ .num_codecs = 2, ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS, ++ .ops = &snd_rpi_hifiberry_dacplusadcpro_ops, ++ .init = snd_rpi_hifiberry_dacplusadcpro_init, ++}, ++}; ++ ++/* audio machine driver */ ++static struct snd_soc_card snd_rpi_hifiberry_dacplusadcpro = { ++ .name = "snd_rpi_hifiberry_dacplusadcpro", ++ .driver_name = "HifiberryDacpAdcPro", ++ .owner = THIS_MODULE, ++ .dai_link = snd_rpi_hifiberry_dacplusadcpro_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dacplusadcpro_dai), ++}; ++ ++static int snd_rpi_hifiberry_dacplusadcpro_probe(struct platform_device *pdev) ++{ ++ int ret = 0, i = 0; ++ struct snd_soc_card *card = &snd_rpi_hifiberry_dacplusadcpro; ++ ++ snd_rpi_hifiberry_dacplusadcpro.dev = &pdev->dev; ++ if (pdev->dev.of_node) { ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai; ++ ++ dai = &snd_rpi_hifiberry_dacplusadcpro_dai[0]; ++ i2s_node = of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ if (i2s_node) { ++ for (i = 0; i < card->num_links; i++) { ++ 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, "hifiberry-dacplusadcpro,24db_digital_gain"); ++ slave = of_property_read_bool(pdev->dev.of_node, ++ "hifiberry-dacplusadcpro,slave"); ++ ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplusadcpro); ++ if (ret && ret != -EPROBE_DEFER) ++ dev_err(&pdev->dev, ++ "snd_soc_register_card() failed: %d\n", ret); ++ ++ return ret; ++} ++ ++static const struct of_device_id snd_rpi_hifiberry_dacplusadcpro_of_match[] = { ++ { .compatible = "hifiberry,hifiberry-dacplusadcpro", }, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_dacplusadcpro_of_match); ++ ++static struct platform_driver snd_rpi_hifiberry_dacplusadcpro_driver = { ++ .driver = { ++ .name = "snd-rpi-hifiberry-dacplusadcpro", ++ .owner = THIS_MODULE, ++ .of_match_table = snd_rpi_hifiberry_dacplusadcpro_of_match, ++ }, ++ .probe = snd_rpi_hifiberry_dacplusadcpro_probe, ++}; ++ ++module_platform_driver(snd_rpi_hifiberry_dacplusadcpro_driver); ++ ++MODULE_AUTHOR("Joerg Schambacher "); ++MODULE_AUTHOR("Daniel Matuschek "); ++MODULE_DESCRIPTION("ASoC Driver for HiFiBerry DAC+ADC"); ++MODULE_LICENSE("GPL v2"); diff --git a/target/linux/brcm2708/patches-4.19/950-0725-codecs-Correct-Katana-minimum-volume.patch b/target/linux/brcm2708/patches-4.19/950-0725-codecs-Correct-Katana-minimum-volume.patch new file mode 100644 index 0000000000..c64ef33248 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0725-codecs-Correct-Katana-minimum-volume.patch @@ -0,0 +1,23 @@ +From 25b5f8d3fdadafccc34e4ae24525ddfb5e6b2ae0 Mon Sep 17 00:00:00 2001 +From: allo-com +Date: Mon, 29 Jul 2019 15:06:57 +0530 +Subject: [PATCH 725/725] codecs: Correct Katana minimum volume + +Update Katana minimum volume to get the exact 0.5 dB value in each step. + +Signed-off-by: Sudeep Kumar +--- + sound/soc/bcm/allo-katana-codec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/soc/bcm/allo-katana-codec.c ++++ b/sound/soc/bcm/allo-katana-codec.c +@@ -126,7 +126,7 @@ static SOC_VALUE_ENUM_SINGLE_DECL(katana + katana_codec_deemphasis_texts, + katana_codec_deemphasis_values); + +-static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(master_tlv, -12700, 0); ++static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(master_tlv, -12750, 0); + + static const struct snd_kcontrol_new katana_codec_controls[] = { + SOC_DOUBLE_R_TLV("Master Playback Volume", KATANA_CODEC_VOLUME_1, diff --git a/target/linux/brcm2708/patches-4.19/961-add-arm64-platform-kconfig-mfd-core.patch b/target/linux/brcm2708/patches-4.19/961-add-arm64-platform-kconfig-mfd-core.patch index bc4b45b92f..8e2a7eb182 100644 --- a/target/linux/brcm2708/patches-4.19/961-add-arm64-platform-kconfig-mfd-core.patch +++ b/target/linux/brcm2708/patches-4.19/961-add-arm64-platform-kconfig-mfd-core.patch @@ -1,6 +1,6 @@ --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms -@@ -25,6 +25,7 @@ config ARCH_BCM2835 +@@ -26,6 +26,7 @@ config ARCH_BCM2835 select ARM_AMBA select ARM_TIMER_SP804 select HAVE_ARM_ARCH_TIMER diff --git a/target/linux/generic/config-4.19 b/target/linux/generic/config-4.19 index 8bb887444f..3c142a3084 100644 --- a/target/linux/generic/config-4.19 +++ b/target/linux/generic/config-4.19 @@ -699,6 +699,7 @@ CONFIG_BT_HCIUART_H4=y # CONFIG_BT_LE is not set # CONFIG_BT_LEDS is not set # CONFIG_BT_MRVL is not set +# CONFIG_BT_MTKUART is not set # CONFIG_BT_RFCOMM is not set CONFIG_BT_RFCOMM_TTY=y # CONFIG_BT_SELFTEST is not set @@ -1393,6 +1394,7 @@ CONFIG_EXPORTFS=y CONFIG_EXT4_USE_FOR_EXT2=y # CONFIG_EXTCON is not set # CONFIG_EXTCON_ADC_JACK is not set +# CONFIG_EXTCON_ARIZONA is not set # CONFIG_EXTCON_AXP288 is not set # CONFIG_EXTCON_GPIO is not set # CONFIG_EXTCON_INTEL_INT3496 is not set @@ -1757,6 +1759,7 @@ CONFIG_HAVE_STACKPROTECTOR=y # CONFIG_HID_BATTERY_STRENGTH is not set # CONFIG_HID_BELKIN is not set # CONFIG_HID_BETOP_FF is not set +# CONFIG_HID_BIGBEN_FF is not set # CONFIG_HID_CHERRY is not set # CONFIG_HID_CHICONY is not set # CONFIG_HID_CMEDIA is not set @@ -5322,6 +5325,7 @@ CONFIG_TMPFS_XATTR=y # CONFIG_TOUCHSCREEN_PROPERTIES is not set # CONFIG_TOUCHSCREEN_RM_TS is not set # CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set +# CONFIG_TOUCHSCREEN_RPI_FT5406 is not set # CONFIG_TOUCHSCREEN_S3C2410 is not set # CONFIG_TOUCHSCREEN_S6SY761 is not set # CONFIG_TOUCHSCREEN_SILEAD is not set