From d6795e5b6a1bd6361aa4179a0dfd3eedf2aafce8 Mon Sep 17 00:00:00 2001 From: MilhouseVH Date: Mon, 13 Mar 2017 17:20:41 +0000 Subject: [PATCH 1/8] linux: update to linux-4.10.1 --- packages/linux/package.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/linux/package.mk b/packages/linux/package.mk index 6471cbfacf..45471ad8f7 100644 --- a/packages/linux/package.mk +++ b/packages/linux/package.mk @@ -59,7 +59,7 @@ case "$LINUX" in PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET imx6-status-led imx6-soc-fan irqbalanced" ;; *) - PKG_VERSION="4.10" + PKG_VERSION="4.10.1" PKG_URL="http://www.kernel.org/pub/linux/kernel/v4.x/$PKG_NAME-$PKG_VERSION.tar.xz" PKG_PATCH_DIRS="default" ;; From b76de852bc3eafa0cf9c0cff549d9147c9430abe Mon Sep 17 00:00:00 2001 From: MilhouseVH Date: Mon, 13 Mar 2017 17:20:41 +0000 Subject: [PATCH 2/8] linux: update to linux-4.10.2 --- packages/linux/package.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/linux/package.mk b/packages/linux/package.mk index 45471ad8f7..4cb15c585c 100644 --- a/packages/linux/package.mk +++ b/packages/linux/package.mk @@ -59,7 +59,7 @@ case "$LINUX" in PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET imx6-status-led imx6-soc-fan irqbalanced" ;; *) - PKG_VERSION="4.10.1" + PKG_VERSION="4.10.2" PKG_URL="http://www.kernel.org/pub/linux/kernel/v4.x/$PKG_NAME-$PKG_VERSION.tar.xz" PKG_PATCH_DIRS="default" ;; From a46029f421435b70f8b268202199e9b32e49a8b0 Mon Sep 17 00:00:00 2001 From: MilhouseVH Date: Mon, 13 Mar 2017 17:20:41 +0000 Subject: [PATCH 3/8] RPi/RPi2: update linux support patches for linux 4.10.2 --- .../patches/linux/linux-01-RPi_support.patch | 7698 ++++++++++++++++- .../patches/linux/linux-01-RPi_support.patch | 7698 ++++++++++++++++- 2 files changed, 14822 insertions(+), 574 deletions(-) diff --git a/projects/RPi/patches/linux/linux-01-RPi_support.patch b/projects/RPi/patches/linux/linux-01-RPi_support.patch index 797c5d6065..7f75b2cbcb 100644 --- a/projects/RPi/patches/linux/linux-01-RPi_support.patch +++ b/projects/RPi/patches/linux/linux-01-RPi_support.patch @@ -1,7 +1,7 @@ -From 468cd1d3694d2c7fa2126c4dff4c92cfe1c71c70 Mon Sep 17 00:00:00 2001 +From d1e917656833e0994b3bb740743c6ab9ae0652ad Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Thu, 19 Feb 2015 18:47:12 +0000 -Subject: [PATCH 001/143] smsx95xx: fix crimes against truesize +Subject: [PATCH 001/190] 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. @@ -48,10 +48,10 @@ index 831aa33d078ae7d2dd57fdded5de71d1eb915f99..b77935bded8c0ff7808b00f170ff10e5 usbnet_skb_return(dev, ax_skb); } -From bc9f373027da6cd14af74a5ceb6a250f9f26a704 Mon Sep 17 00:00:00 2001 +From e1d30654234dc753d725f314a0161976ec8611c4 Mon Sep 17 00:00:00 2001 From: Sam Nazarko Date: Fri, 1 Apr 2016 17:27:21 +0100 -Subject: [PATCH 002/143] smsc95xx: Experimental: Enable turbo_mode and +Subject: [PATCH 002/190] smsc95xx: Experimental: Enable turbo_mode and packetsize=2560 by default See: http://forum.kodi.tv/showthread.php?tid=285288 @@ -94,10 +94,10 @@ index b77935bded8c0ff7808b00f170ff10e594300ad0..693f163684de921404738e33244881e0 netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld\n", -From d7e10b62fb345e91e63aa5e9033508150adc835c Mon Sep 17 00:00:00 2001 +From 14f6e078286abd55b3bdc8514be8cd4157aa3b7d Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 17:26:38 +0000 -Subject: [PATCH 003/143] Allow mac address to be set in smsc95xx +Subject: [PATCH 003/190] Allow mac address to be set in smsc95xx Signed-off-by: popcornmix --- @@ -193,10 +193,10 @@ index 693f163684de921404738e33244881e0aab92ec9..df60c989fc229bf0aab3c27e95ccd453 eth_hw_addr_random(dev->net); netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n"); -From 1ce0d09afcddde03315a95fbdd9eb451e9d5beb5 Mon Sep 17 00:00:00 2001 +From a595173c0c0e0f96f85e91dda95c75b26a76980b Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 13 Mar 2015 12:43:36 +0000 -Subject: [PATCH 004/143] Protect __release_resource against resources without +Subject: [PATCH 004/190] Protect __release_resource against resources without parents Without this patch, removing a device tree overlay can crash here. @@ -224,10 +224,10 @@ index 9b5f04404152c296af3a96132f27cfc80ffa9af9..f8a9af6e6b915812be2ba2c1c2b40106 for (;;) { tmp = *p; -From f1efecc4cc9a7bc17bcd05b760c56abd3c35b1c7 Mon Sep 17 00:00:00 2001 +From 55aa002ca4f4ee3171e05ece1af544d20420357e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Dec 2014 16:07:15 -0800 -Subject: [PATCH 005/143] mm: Remove the PFN busy warning +Subject: [PATCH 005/190] mm: Remove the PFN busy warning See commit dae803e165a11bc88ca8dbc07a11077caf97bbcb -- the warning is expected sometimes when using CMA. However, that commit still spams @@ -239,7 +239,7 @@ Signed-off-by: Eric Anholt 1 file changed, 2 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c -index f3e0c69a97b76997d9fa65cda0b7e1b1fb8fa29a..c0ef4472377fe5eea65b73d9764e464d72985b70 100644 +index 1a5f6655958e16ec09584c79405991dc248d2852..8068e8f926d87c02ac60f583d9b4cdefcdc2b146 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -7361,8 +7361,6 @@ int alloc_contig_range(unsigned long start, unsigned long end, @@ -252,10 +252,10 @@ index f3e0c69a97b76997d9fa65cda0b7e1b1fb8fa29a..c0ef4472377fe5eea65b73d9764e464d goto done; } -From a6ed755bf9e4e175e8316ce5ca49475c925b06b7 Mon Sep 17 00:00:00 2001 +From 707bedaadca8a746630e4a9c41892d5fe4e1fd1e Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 4 Dec 2015 17:41:50 +0000 -Subject: [PATCH 006/143] irq-bcm2836: Prevent spurious interrupts, and trap +Subject: [PATCH 006/190] irq-bcm2836: Prevent spurious interrupts, and trap them early The old arch-specific IRQ macros included a dsb to ensure the @@ -282,10 +282,10 @@ index e7463e3c08143acae3e8cc5682f918c6a0b07ebd..a8db33b50ad9ff83d284fa54fe4d3b65 #endif } else if (stat) { -From 1a63d13766b406f3c98a86c063e7d80e25f584bb Mon Sep 17 00:00:00 2001 +From 5709d5baf8b71d3a7e06e43c5afa68cbf6575862 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 007/143] irqchip: bcm2835: Add FIQ support +Subject: [PATCH 007/190] irqchip: bcm2835: Add FIQ support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -414,10 +414,10 @@ index 44d7c38dde479d771f3552e914bf8c1c1f5019f7..42ff5e6a8e0d532f5b60a1e7af7cc4d9 } -From 98c24bb5c2f7eab74c8307fde5c638cd44e1cc68 Mon Sep 17 00:00:00 2001 +From 6120b7ae9818c89da12301de5c8fca8761d92c0e 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 008/143] irqchip: irq-bcm2835: Add 2836 FIQ support +Subject: [PATCH 008/190] irqchip: irq-bcm2835: Add 2836 FIQ support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -516,10 +516,10 @@ index 42ff5e6a8e0d532f5b60a1e7af7cc4d941bd5008..eccf6ed025299cb480884f5bcbe77abf for (b = 0; b < NR_BANKS; b++) { for (i = 0; i < bank_irqs[b]; i++) { -From 44c736dd9491af829bd0c5684f5bbe883e09c2d1 Mon Sep 17 00:00:00 2001 +From c122f3bf18ae3def1f9e7b11f3b49a77da01ce9b Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 14 Jul 2015 10:26:09 +0100 -Subject: [PATCH 009/143] spidev: Add "spidev" compatible string to silence +Subject: [PATCH 009/190] spidev: Add "spidev" compatible string to silence warning See: https://github.com/raspberrypi/linux/issues/1054 @@ -540,10 +540,10 @@ index 9e2e099baf8ca5cc6510912a36d4ca03daeb8273..e59640942826db2ea14d0bde0ff5ab22 }; MODULE_DEVICE_TABLE(of, spidev_dt_ids); -From 4679b462878b70c11be6f05d70aaf411af8f0c94 Mon Sep 17 00:00:00 2001 +From 93a580f9d2b0f41bf30550529dff21478d8f1526 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 30 Jun 2015 14:12:42 +0100 -Subject: [PATCH 010/143] serial: 8250: Don't crash when nr_uarts is 0 +Subject: [PATCH 010/190] serial: 8250: Don't crash when nr_uarts is 0 --- drivers/tty/serial/8250/8250_core.c | 2 ++ @@ -563,10 +563,10 @@ index 76e03a7de9cc3d790a230948f599ef2db4b93249..0a172c2e6fa288de1e080463e897ea85 for (i = 0; i < nr_uarts; i++) { struct uart_8250_port *up = &serial8250_ports[i]; -From 7afdc575c0f1518aad2b980b7ff34571d9d5963f Mon Sep 17 00:00:00 2001 +From 50070832c703415df6aad13534498057c1e1ecad Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 3 Jan 2017 18:25:01 +0000 -Subject: [PATCH 011/143] Revert "pinctrl: bcm2835: switch to GPIOLIB_IRQCHIP" +Subject: [PATCH 011/190] Revert "pinctrl: bcm2835: switch to GPIOLIB_IRQCHIP" This reverts commit 85ae9e512f437cd09bf61564bdba29ab88bab3e3. --- @@ -860,10 +860,10 @@ index 85d0091128644c446aed878e87769e82c77c3ebf..4f2621272bfd5cbc0d691d2fabe89e2e if (IS_ERR(pc->pctl_dev)) { gpiochip_remove(&pc->gpio_chip); -From bf0a2edf0c0a2ebdd6e83fd18cb83e7723425ce4 Mon Sep 17 00:00:00 2001 +From 8cc90808c4fafe06a0f7e360de91570b60fc8743 Mon Sep 17 00:00:00 2001 From: notro Date: Thu, 10 Jul 2014 13:59:47 +0200 -Subject: [PATCH 012/143] pinctrl-bcm2835: Set base to 0 give expected gpio +Subject: [PATCH 012/190] pinctrl-bcm2835: Set base to 0 give expected gpio numbering Signed-off-by: Noralf Tronnes @@ -885,10 +885,10 @@ index 4f2621272bfd5cbc0d691d2fabe89e2ee428d6db..5b7cb4c415e19f98e25b221ab0ad36b6 .can_sleep = false, }; -From b769e2efdc8f7c809c5d83c0daa8a1a452e890db Mon Sep 17 00:00:00 2001 +From 7cb1239db975b8d6bd085f6fc35475988de7e418 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 26 Feb 2015 09:58:22 +0000 -Subject: [PATCH 013/143] pinctrl-bcm2835: Only request the interrupts listed +Subject: [PATCH 013/190] pinctrl-bcm2835: Only request the interrupts listed in the DTB Although the GPIO controller can generate three interrupts (four counting @@ -915,10 +915,10 @@ index 5b7cb4c415e19f98e25b221ab0ad36b6885dae4c..6351fe7f8e314ac5ebb102dd20847b38 pc->irq_data[i].irqgroup = i; -From c7575d85ded4666e609af7c4a65663379c5b7ffb Mon Sep 17 00:00:00 2001 +From 55f317c43b0d019fff5bebea158775e3dc9134ab Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 24 Jun 2015 14:10:44 +0100 -Subject: [PATCH 014/143] spi-bcm2835: Support pin groups other than 7-11 +Subject: [PATCH 014/190] 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 @@ -999,10 +999,10 @@ index f35cc10772f6670397ea923ad30158270dd68578..5dfe20ffc2866fa6789825016c585175 /* and set up the "mode" and level */ dev_info(&spi->dev, "setting up native-CS%i as GPIO %i\n", -From 4059c76642b41887bff173ca7c36d738a1d12daf Mon Sep 17 00:00:00 2001 +From 0f658a1ede61a3841cd5f11a1ce9b1c6fda9e7c7 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 1 Jul 2016 22:09:24 +0100 -Subject: [PATCH 015/143] spi-bcm2835: Disable forced software CS +Subject: [PATCH 015/190] 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 @@ -1036,10 +1036,10 @@ index 5dfe20ffc2866fa6789825016c585175a29705b6..8493474d286f7a1ac6454a22c61c8c2c return 0; } -From 3946ca2d555be10ee4025995a896a261546dbb16 Mon Sep 17 00:00:00 2001 +From 0b8bd6f69a5b3e8c617d789e190a4a4c451c12a7 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 8 Nov 2016 21:35:38 +0000 -Subject: [PATCH 016/143] spi-bcm2835: Remove unused code +Subject: [PATCH 016/190] spi-bcm2835: Remove unused code --- drivers/spi/spi-bcm2835.c | 61 ----------------------------------------------- @@ -1127,10 +1127,10 @@ index 8493474d286f7a1ac6454a22c61c8c2cef9121bf..33d75ad38a7f77d085321ace9101900a } -From 3e2637b9690a7170181a28e173be2df710bc42b0 Mon Sep 17 00:00:00 2001 +From 7fa50826d3b24f16e9edabfc9c0939041b2cf5ad 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 017/143] ARM: bcm2835: Set Serial number and Revision +Subject: [PATCH 017/190] ARM: bcm2835: Set Serial number and Revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -1183,10 +1183,10 @@ index 0c1edfc98696da0e0bb7f4a18cdfbcdd27a9795d..8f152266ba9b470df2eaaed9ebcf158e static const char * const bcm2835_compat[] = { -From 5ae2a094dc3d45ed43fc10955946a455614deed2 Mon Sep 17 00:00:00 2001 +From 678fb328a55e2ce06390c3c79c0e88b04db51f18 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 018/143] dmaengine: bcm2835: Load driver early and support +Subject: [PATCH 018/190] dmaengine: bcm2835: Load driver early and support legacy API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -1289,10 +1289,10 @@ index e18dc596cf2447fa9ef7e41b62d9396e29043426..80d35f760b4a4a51e60c355a84d538ba MODULE_ALIAS("platform:bcm2835-dma"); MODULE_DESCRIPTION("BCM2835 DMA engine driver"); -From ec29a80aa532673f479214b409dca3bbda1ad682 Mon Sep 17 00:00:00 2001 +From a868c95ac6626320fbb3dc99f67e43d566cd782e Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 25 Jan 2016 17:25:12 +0000 -Subject: [PATCH 019/143] firmware: Updated mailbox header +Subject: [PATCH 019/190] firmware: Updated mailbox header --- include/soc/bcm2835/raspberrypi-firmware.h | 9 +++++++++ @@ -1353,10 +1353,10 @@ index cb979ad90401e299344dd5fae38d09c489d8bd58..30fb37fe175df604a738258a2a632bca RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, -From 574fd69f5a7a477bbdb4b702fbd9ed4c771754ec Mon Sep 17 00:00:00 2001 +From 834b8d57570eb6a7d7c3887a24b5ce0d6a9e1e95 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 15 Jun 2016 16:48:41 +0100 -Subject: [PATCH 020/143] rtc: Add SPI alias for pcf2123 driver +Subject: [PATCH 020/190] rtc: Add SPI alias for pcf2123 driver Without this alias, Device Tree won't cause the driver to be loaded. @@ -1376,10 +1376,10 @@ index 8895f77726e8da5444afcd602dceff8f25a9b3fd..1833b8853ceb0e6147cceb93a00e558c MODULE_LICENSE("GPL"); +MODULE_ALIAS("spi:rtc-pcf2123"); -From 9caaab7c7d8bed852d27b583965a6058b98f57af Mon Sep 17 00:00:00 2001 +From d226a774328346e829a0b84046019174ababcb2d 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 021/143] watchdog: bcm2835: Support setting reboot partition +Subject: [PATCH 021/190] watchdog: bcm2835: Support setting reboot partition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -1503,10 +1503,10 @@ index c32c45bd8b097889c8f322255fa63c8ed507d6ab..ef02dfa23aa774e1cdf75f935c5de985 register_restart_handler(&wdt->restart_handler); if (pm_power_off == NULL) -From 232d0798c565f9ebf55bf1e2d2311b3c5ccdd393 Mon Sep 17 00:00:00 2001 +From 44473964e874063958ebc6feedeb9be246515233 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 5 Apr 2016 19:40:12 +0100 -Subject: [PATCH 022/143] reboot: Use power off rather than busy spinning when +Subject: [PATCH 022/190] reboot: Use power off rather than busy spinning when halt is requested --- @@ -1529,10 +1529,10 @@ index 3fa867a2aae672755c6ce6448f4148c989dbf964..80dca8dcd6709034b643c6a3f35729e0 /* -From efde81aa7c10d0d6e9c24e7cc8503ce0996faca9 Mon Sep 17 00:00:00 2001 +From fe3514b53963b85ca31f2fbbc708b9227416548b Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 9 Nov 2016 13:02:52 +0000 -Subject: [PATCH 023/143] bcm: Make RASPBERRYPI_POWER depend on PM +Subject: [PATCH 023/190] bcm: Make RASPBERRYPI_POWER depend on PM --- drivers/soc/bcm/Kconfig | 1 + @@ -1551,10 +1551,10 @@ index a39b0d58ddd0fdf0ac1cc7295f8aafb12546e226..e037a6dd79d1881a09e3ca9115782709 help This enables support for the RPi power domains which can be enabled -From a0c1361b3b8584885facacada6d30f09470ce3bb Mon Sep 17 00:00:00 2001 +From dbeeb2973e84b71eebc37cb8f75be56251abf775 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Fri, 2 Sep 2016 16:45:27 +0100 -Subject: [PATCH 024/143] Register the clocks early during the boot process, so +Subject: [PATCH 024/190] 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. @@ -1599,10 +1599,10 @@ index 0d14409097e777ce4546de30e9278fdebf74ec44..093694e00caec6e133eb26712f890691 MODULE_AUTHOR("Eric Anholt "); MODULE_DESCRIPTION("BCM2835 clock driver"); -From c3b7ffe0ce627827234c4012de92f199831caefb Mon Sep 17 00:00:00 2001 +From 26aa42e837a555ca85652e2be190934e930f47a0 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 6 Dec 2016 17:05:39 +0000 -Subject: [PATCH 025/143] bcm2835-rng: Avoid initialising if already enabled +Subject: [PATCH 025/190] bcm2835-rng: Avoid initialising if already enabled Avoids the 0x40000 cycles of warmup again if firmware has already used it --- @@ -1628,10 +1628,10 @@ index 574211a495491d9d6021dcaefe4274a63ed02055..e66c0fca8c6090e32f72796c0877a1cf err = hwrng_register(&bcm2835_rng_ops); if (err) { -From 5bfe6e7bc831a0e96fa156a19886809aff0328ca Mon Sep 17 00:00:00 2001 +From 328412e0e0f6b85ca305a4a49794f0e72092e38a Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 24 Aug 2016 16:28:44 +0100 -Subject: [PATCH 026/143] kbuild: Ignore dtco targets when filtering symbols +Subject: [PATCH 026/190] kbuild: Ignore dtco targets when filtering symbols --- scripts/Kbuild.include | 2 +- @@ -1651,10 +1651,10 @@ index 179219845dfcdfbeb586d12c5ec1296095d9fbf4..e0743e44f84188667a0c322e8c3d36f1 esac | tr ";" "\n" | sed -rn 's/^.*=== __KSYM_(.*) ===.*$$/KSYM_\1/p' -From 591508cc26f195e95549de1146bc05d8f21c5dee Mon Sep 17 00:00:00 2001 +From da4f5fa22c1f3e7bae55ca76ddeffa25e8ca1083 Mon Sep 17 00:00:00 2001 From: Robert Tiemann Date: Mon, 20 Jul 2015 11:01:25 +0200 -Subject: [PATCH 027/143] BCM2835_DT: Fix I2S register map +Subject: [PATCH 027/190] BCM2835_DT: Fix I2S register map --- Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt | 4 ++-- @@ -1692,10 +1692,10 @@ index 65783de0aedf3da79adc36fd077b7a89954ddb6b..a89fe4220fdc3f26f75ee66daf187554 dmas = <&dma 2>, <&dma 3>; -From 01804d5ae241e785859bd18934674c00fa692dc3 Mon Sep 17 00:00:00 2001 +From decba833672c4b549c5206c56a8bfc6769ba76d0 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 12 May 2013 12:24:19 +0100 -Subject: [PATCH 028/143] Main bcm2708/bcm2709 linux port +Subject: [PATCH 028/190] Main bcm2708/bcm2709 linux port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -1902,10 +1902,10 @@ index cfb4b4496dd9f61362dea012176c146120fada07..d9c6c217c4d6a2408abe2665bf7f2700 MODULE_AUTHOR("Lubomir Rintel "); MODULE_DESCRIPTION("BCM2835 mailbox IPC driver"); -From 228c89bd9ddd3b365c7eaa3c03d575bc794f7de7 Mon Sep 17 00:00:00 2001 +From 2d973c946e8f3e9a0b55e806bebfc733628c9852 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:46:17 +0100 -Subject: [PATCH 029/143] Add dwc_otg driver +Subject: [PATCH 029/190] Add dwc_otg driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -62962,10 +62962,10 @@ index 0000000000000000000000000000000000000000..cdc9963176e5a4a0d5250613b61e26c5 +test_main(); +0; -From f68c23214b22436e79194926e525fb6c0175576c Mon Sep 17 00:00:00 2001 +From eac25e87a2ca3a8cee733cda21c722a3427b9c1a Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 17:06:34 +0100 -Subject: [PATCH 030/143] bcm2708 framebuffer driver +Subject: [PATCH 030/190] bcm2708 framebuffer driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -66424,10 +66424,10 @@ index 3c14e43b82fefe1d32f591d1b2f61d2cd28d0fa8..7626beb6a5bb8df601ddf0f6e6909d1f +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 -From bdf4d5ad586e9074aacf2e7942335268f43162e3 Mon Sep 17 00:00:00 2001 +From 4fa6dd21376ce0220bd0e5e3ecb9d956c796a126 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:22:53 +0100 -Subject: [PATCH 031/143] dmaengine: Add support for BCM2708 +Subject: [PATCH 031/190] dmaengine: Add support for BCM2708 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -67058,10 +67058,10 @@ index 0000000000000000000000000000000000000000..c5bfff2765be4606077e6c8af73040ec + +#endif /* _PLAT_BCM2708_DMA_H */ -From 14cfe758a49f17af11460525c1d0d76012e10b46 Mon Sep 17 00:00:00 2001 +From 7b93c5b9222abb422f6d40abc3f6efe2c7a61a46 Mon Sep 17 00:00:00 2001 From: gellert Date: Fri, 15 Aug 2014 16:35:06 +0100 -Subject: [PATCH 032/143] MMC: added alternative MMC driver +Subject: [PATCH 032/190] MMC: added alternative MMC driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -68811,10 +68811,10 @@ index 0000000000000000000000000000000000000000..4fe8d1fe44578fbefcd48f8c327ba3d0 +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Gellert Weisz"); -From c2d33aadf0cf3d1c68c2dde3e48d6b335679816a Mon Sep 17 00:00:00 2001 +From 3e0108a5f4bab826b048f98655974e737de02623 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 25 Mar 2015 17:49:47 +0000 -Subject: [PATCH 033/143] Adding bcm2835-sdhost driver, and an overlay to +Subject: [PATCH 033/190] Adding bcm2835-sdhost driver, and an overlay to enable it BCM2835 has two SD card interfaces. This driver uses the other one. @@ -71219,10 +71219,10 @@ index 0000000000000000000000000000000000000000..a9bc79bfdbb71807819dfe2d8f165144 +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Phil Elwell"); -From 00496b5cfe106d6817de8a73031f1e935e54f4bb Mon Sep 17 00:00:00 2001 +From 2c3bfe168baa3d99b7b817162bf3f2405120b2b8 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 11 May 2016 12:50:33 +0100 -Subject: [PATCH 034/143] mmc: Add MMC_QUIRK_ERASE_BROKEN for some cards +Subject: [PATCH 034/190] mmc: Add MMC_QUIRK_ERASE_BROKEN for some cards Some SD cards have been found that corrupt data when small blocks are erased. Add a quirk to indicate that ERASE should not be used, @@ -71358,10 +71358,10 @@ index 95d69d4982965aa30fb65d9ffecfad13f4e7be8f..a97b881a04f4b3294cf3ede393cde717 unsigned int erase_shift; /* if erase unit is power 2 */ unsigned int pref_erase; /* in sectors */ -From ca13f6a5ce9cb58b3587bf0cfd8bfc622ec3da63 Mon Sep 17 00:00:00 2001 +From 84801dd88cc565a93de15e4b5d81d2459112b150 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:31:47 +0100 -Subject: [PATCH 035/143] cma: Add vc_cma driver to enable use of CMA +Subject: [PATCH 035/190] cma: Add vc_cma driver to enable use of CMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -72697,10 +72697,10 @@ index 0000000000000000000000000000000000000000..be2819d5d41f9d5ed65daf8eedb94c9e + +#endif /* VC_CMA_H */ -From 6174e627557707aa9ec6b80ea852a4abce9f85a2 Mon Sep 17 00:00:00 2001 +From 56add8155e63509b018673bef8f54aa2df627858 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 26 Mar 2012 22:15:50 +0100 -Subject: [PATCH 036/143] bcm2708: alsa sound driver +Subject: [PATCH 036/190] bcm2708: alsa sound driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -75435,10 +75435,10 @@ index 0000000000000000000000000000000000000000..af3e6eb690113fc32ce9e06bd2f0f294 + +#endif // _VC_AUDIO_DEFS_H_ -From a32d0d6bbe4bb394ac6724af37583d8c01973a67 Mon Sep 17 00:00:00 2001 +From 0d384cdc70ea243666b4abb77aee8f9cc91e1947 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 28 Oct 2016 15:36:43 +0100 -Subject: [PATCH 037/143] vc_mem: Add vc_mem driver for querying firmware +Subject: [PATCH 037/190] vc_mem: Add vc_mem driver for querying firmware memory addresses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -75962,10 +75962,10 @@ index 0000000000000000000000000000000000000000..20a475377eb3078ea1ecaef2b24efc35 + +#endif /* _VC_MEM_H */ -From c00e9788d5f56d3e876fe2127e9d80da8a456584 Mon Sep 17 00:00:00 2001 +From c1b9d636439bac24d32f07062453895a34d54fa3 Mon Sep 17 00:00:00 2001 From: Tim Gover Date: Tue, 22 Jul 2014 15:41:04 +0100 -Subject: [PATCH 038/143] vcsm: VideoCore shared memory service for BCM2835 +Subject: [PATCH 038/190] vcsm: VideoCore shared memory service for BCM2835 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -80372,10 +80372,10 @@ index 0000000000000000000000000000000000000000..334f36d0d697b047df2922b5f2db67f3 + +#endif /* __VMCS_SM_IOCTL_H__INCLUDED__ */ -From 32efcf2207a132a8e8d40424646b0e726e19e377 Mon Sep 17 00:00:00 2001 +From 1f931d0842ae1498d3b132db8705854957dbdb20 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Fri, 21 Aug 2015 23:14:48 +0100 -Subject: [PATCH 039/143] Add /dev/gpiomem device for rootless user GPIO access +Subject: [PATCH 039/190] Add /dev/gpiomem device for rootless user GPIO access Signed-off-by: Luke Wren @@ -80686,10 +80686,10 @@ index 0000000000000000000000000000000000000000..911f5b7393ed48ceed8751f06967ae64 +MODULE_DESCRIPTION("gpiomem driver for accessing GPIO from userspace"); +MODULE_AUTHOR("Luke Wren "); -From 227fa137a8d33de43c3a44e26d342a0192d6177b Mon Sep 17 00:00:00 2001 +From 3c245d477db104e2cfa1334ed1d1f79f34056902 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Sat, 5 Sep 2015 01:14:45 +0100 -Subject: [PATCH 040/143] Add SMI driver +Subject: [PATCH 040/190] Add SMI driver Signed-off-by: Luke Wren --- @@ -82640,10 +82640,10 @@ index 0000000000000000000000000000000000000000..ee3a75edfc033eeb0d90a687ffb68b10 + +#endif /* BCM2835_SMI_H */ -From c21d7f46c064ef8d4be52013e5c9760c4f85202b Mon Sep 17 00:00:00 2001 +From da256321f9f8e1e95ec5d9f6179cae24a8a9cb0a Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Tue, 26 Apr 2016 14:59:21 +0000 -Subject: [PATCH 041/143] MISC: bcm2835: smi: use clock manager and fix reload +Subject: [PATCH 041/190] MISC: bcm2835: smi: use clock manager and fix reload issues Use clock manager instead of self-made clockmanager. @@ -82813,10 +82813,10 @@ index 63a4ea08b9930a3a31a985f0a1d969b488ed49ec..1261540703127d1d63b9f3c87042c6e5 return 0; } -From 5d7a61f480af9494f6986a02ae3328854b6ead05 Mon Sep 17 00:00:00 2001 +From 314ca0c23570d6428dbc8a9269638dec38b21f75 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Sat, 5 Sep 2015 01:16:10 +0100 -Subject: [PATCH 042/143] Add SMI NAND driver +Subject: [PATCH 042/190] Add SMI NAND driver Signed-off-by: Luke Wren --- @@ -83181,10 +83181,10 @@ index 0000000000000000000000000000000000000000..02adda6da18bd0ba9ab19a104975b79d + ("Driver for NAND chips using Broadcom Secondary Memory Interface"); +MODULE_AUTHOR("Luke Wren "); -From 1995e1c034599ce8a4bad906a7935160058f79a9 Mon Sep 17 00:00:00 2001 +From b6bb92b2d8a850ffb75972efb6b9e8475a4c7578 Mon Sep 17 00:00:00 2001 From: Aron Szabo Date: Sat, 16 Jun 2012 12:15:55 +0200 -Subject: [PATCH 043/143] lirc: added support for RaspberryPi GPIO +Subject: [PATCH 043/190] lirc: added support for RaspberryPi GPIO lirc_rpi: Use read_current_timer to determine transmitter delay. Thanks to jjmz and others See: https://github.com/raspberrypi/linux/issues/525 @@ -84047,10 +84047,10 @@ index 0000000000000000000000000000000000000000..fb69624ccef00ddbdccf8256d6baf1b1 + +#endif -From 3c4052e9e9b9835346794628a416afdb8286f65b Mon Sep 17 00:00:00 2001 +From 435f90d39ab8a7bd738ee2316f4568b4019f9f62 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:49:20 +0100 -Subject: [PATCH 044/143] Add cpufreq driver +Subject: [PATCH 044/190] Add cpufreq driver Signed-off-by: popcornmix --- @@ -84317,10 +84317,10 @@ index 0000000000000000000000000000000000000000..414fbdc10dfbfc6e4bb47870a7af3fd5 +module_init(bcm2835_cpufreq_module_init); +module_exit(bcm2835_cpufreq_module_exit); -From 99f3536cecd3ec117d1b8f673471936f0935a839 Mon Sep 17 00:00:00 2001 +From 3c732076d6d4b2a1e79190906c1e2cf6611c842c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 19:24:24 +0000 -Subject: [PATCH 045/143] Added hwmon/thermal driver for reporting core +Subject: [PATCH 045/190] Added hwmon/thermal driver for reporting core temperature. Thanks Dorian MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -84486,10 +84486,10 @@ index 0000000000000000000000000000000000000000..c63fb9f9d143e19612a18fe530c7b2b3 +MODULE_DESCRIPTION("Thermal driver for bcm2835 chip"); +MODULE_LICENSE("GPL"); -From 0d51691b29ddf5a1c856738868f7067d0fef9a1b Mon Sep 17 00:00:00 2001 +From 8c94087475e5c223ba69548721685e9019142344 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 15:44:08 +0100 -Subject: [PATCH 046/143] Add Chris Boot's i2c driver +Subject: [PATCH 046/190] Add Chris Boot's i2c driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -85154,10 +85154,10 @@ index 0000000000000000000000000000000000000000..962f2e5c7455d91bf32925d785f5f16b +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); -From cb15069165df2b45009331fcea832183557c94fa Mon Sep 17 00:00:00 2001 +From 3e797f34b5cba6cd16712c23916859f3e69b6d3c 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 047/143] char: broadcom: Add vcio module +Subject: [PATCH 047/190] char: broadcom: Add vcio module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -85383,10 +85383,10 @@ index 0000000000000000000000000000000000000000..c19bc2075c77879563ef5e59038b5a14 +MODULE_DESCRIPTION("Mailbox userspace access"); +MODULE_LICENSE("GPL"); -From 08b1da5536118ce3e95f38366b1868fa27dcc489 Mon Sep 17 00:00:00 2001 +From f9a5c0c6e8691542599391afcfd152eb3494a3ea 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 048/143] firmware: bcm2835: Support ARCH_BCM270x +Subject: [PATCH 048/190] firmware: bcm2835: Support ARCH_BCM270x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -85469,10 +85469,10 @@ index dd506cd3a5b874f9e1acd07efb8cd151bb6145d1..3f070bd38a91511c986e3fb114b15bd4 MODULE_AUTHOR("Eric Anholt "); MODULE_DESCRIPTION("Raspberry Pi firmware driver"); -From bd6e61c1d0de223b77a89b11767c93d14c186222 Mon Sep 17 00:00:00 2001 +From 0dc4c631d6161c6bb646af43b31fc20a9f370d58 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 30 Jan 2013 12:45:18 +0000 -Subject: [PATCH 049/143] bcm2835: add v4l2 camera device +Subject: [PATCH 049/190] bcm2835: add v4l2 camera device - Supports raw YUV capture, preview, JPEG and H264. - Uses videobuf2 for data transfer, using dma_buf. @@ -93214,10 +93214,10 @@ index 0000000000000000000000000000000000000000..9d1d11e4a53e510c04a416d92d195a7d + +#endif /* MMAL_VCHIQ_H */ -From ffa6bcf63061b49a18bf0932a012e92ce64f1e90 Mon Sep 17 00:00:00 2001 +From 8a2c5cf31a7f214a896905e51fab0d9e2d914bde Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 11 May 2015 09:00:42 +0100 -Subject: [PATCH 050/143] scripts: Add mkknlimg and knlinfo scripts from tools +Subject: [PATCH 050/190] scripts: Add mkknlimg and knlinfo scripts from tools repo The Raspberry Pi firmware looks for a trailer on the kernel image to @@ -93737,10 +93737,10 @@ index 0000000000000000000000000000000000000000..60206de7fa9a49bd027c635306674a29 + return $trailer; +} -From 537c9deee795f656a41baf00cda7168211581b90 Mon Sep 17 00:00:00 2001 +From 9dec15424834fa630e801a3c6b0372213341ea3c Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 10 Aug 2015 09:49:15 +0100 -Subject: [PATCH 051/143] scripts/dtc: Update to upstream version 1.4.1 +Subject: [PATCH 051/190] scripts/dtc: Update to upstream version 1.4.1 Includes the new localfixups format. @@ -96591,10 +96591,10 @@ index ad9b05ae698b0495ecbda42ffcf4743555313a27..2595dfda020fd9e03f0beff5006f229d -#define DTC_VERSION "DTC 1.4.1-g53bf130b" +#define DTC_VERSION "DTC 1.4.1-g25efc119" -From 1fee8b71fef8abbfcef2cf6913627f2f6f7846a5 Mon Sep 17 00:00:00 2001 +From a17b8884ada3131d4295f64a1c041b99c2f02ac2 Mon Sep 17 00:00:00 2001 From: notro Date: Wed, 9 Jul 2014 14:46:08 +0200 -Subject: [PATCH 052/143] BCM2708: Add core Device Tree support +Subject: [PATCH 052/190] BCM2708: Add core Device Tree support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -106722,10 +106722,10 @@ index 0a07f9014944ed92a8e2e42983ae43be60b3e471..1967878a843461c3ff1f473b9a030eb0 # Bzip2 -From d02d6f6fbcf7be876dd09ecc70ce35ce7238a264 Mon Sep 17 00:00:00 2001 +From 85d20a997340861899ed8718bb9bd54d404a3e6f Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 6 Feb 2015 13:50:57 +0000 -Subject: [PATCH 053/143] BCM270x_DT: Add pwr_led, and the required "input" +Subject: [PATCH 053/190] BCM270x_DT: Add pwr_led, and the required "input" trigger The "input" trigger makes the associated GPIO an input. This is to support @@ -106901,10 +106901,10 @@ index 569cb531094c20a9aa2db478aaa6f348d2afd7f4..aca292f4b0932f61b5bd864251fd05b9 /* set_brightness_work / blink_timer flags, atomic, private. */ unsigned long work_flags; -From 187dd8daac23828689505c4a1ecb48e2c3605019 Mon Sep 17 00:00:00 2001 +From 71199775653ad02f233af3a3e223bf089495d6be Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Mon, 17 Jun 2013 13:32:11 +0300 -Subject: [PATCH 054/143] fbdev: add FBIOCOPYAREA ioctl +Subject: [PATCH 054/190] fbdev: add FBIOCOPYAREA ioctl Based on the patch authored by Ali Gholami Rudi at https://lkml.org/lkml/2009/7/13/153 @@ -107156,10 +107156,10 @@ index fb795c3b3c178ad3cd7c9e9e4547ffd492bac181..703fa8a70574323abe2fb32599254582 __u32 dx; /* screen-relative */ __u32 dy; -From 721fc1e3126da2df74166f87bab6a56c3e0da334 Mon Sep 17 00:00:00 2001 +From ac4d5aef8772f63221f3dec7c37d9d763cc893ab Mon Sep 17 00:00:00 2001 From: Harm Hanemaaijer Date: Thu, 20 Jun 2013 20:21:39 +0200 -Subject: [PATCH 055/143] Speed up console framebuffer imageblit function +Subject: [PATCH 055/190] 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 @@ -107368,10 +107368,10 @@ index a2bb276a8b2463eee98eb237c4647bc00cd93601..436494fba15abecb400ef28688466faf start_index, pitch_index); } else -From 6f03a5d68b9c89ef0f13a166e66c45d515378036 Mon Sep 17 00:00:00 2001 +From 6f62e6e579984cd5393284f6cb060e1bdbd8ca85 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 8 May 2013 11:46:50 +0100 -Subject: [PATCH 056/143] enabling the realtime clock 1-wire chip DS1307 and +Subject: [PATCH 056/190] enabling the realtime clock 1-wire chip DS1307 and 1-wire on GPIO4 (as a module) 1-wire: Add support for configuring pin for w1-gpio kernel module @@ -107621,10 +107621,10 @@ index d58594a3232492e33f1dd4babd3798b03e0f0203..feae94256256316fd9d850c3d83325af unsigned int ext_pullup_enable_pin; unsigned int pullup_duration; -From 7cc945130866491056dd227a0e01141f1dbf7c4c Mon Sep 17 00:00:00 2001 +From 3039b31c4a1ad1d1d1641e4cf7fb9110acbdc184 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 18 Dec 2013 22:16:19 +0000 -Subject: [PATCH 057/143] config: Enable CONFIG_MEMCG, but leave it disabled +Subject: [PATCH 057/190] config: Enable CONFIG_MEMCG, but leave it disabled (due to memory cost). Enable with cgroup_enable=memory. --- @@ -107674,10 +107674,10 @@ index 53bbca7c48598e44fa5e45f88626027749ca8932..62d610c934f80265a889d968c4880a71 * css_tryget_online_from_dir - get corresponding css from a cgroup dentry * @dentry: directory dentry of interest -From bc2335717f7d28dbb33dac229b8fd7701810102a Mon Sep 17 00:00:00 2001 +From 8cc796687b2adea248a13db94060680b1b9d0db9 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 14 Jul 2014 22:02:09 +0100 -Subject: [PATCH 058/143] hid: Reduce default mouse polling interval to 60Hz +Subject: [PATCH 058/190] hid: Reduce default mouse polling interval to 60Hz Reduces overhead when using X --- @@ -107713,10 +107713,10 @@ index 333108ef18cf2f3f94ee3816b2ba6522017295b6..da0ee3beeeed3a223ea6859f52a81e99 ret = -ENOMEM; if (usb_endpoint_dir_in(endpoint)) { -From 83febbc99afc598508f10d47ebdd71e188f07644 Mon Sep 17 00:00:00 2001 +From abe2eb1f1b819701d72ad2165229e184fe43d892 Mon Sep 17 00:00:00 2001 From: Gordon Hollingworth Date: Tue, 12 May 2015 14:47:56 +0100 -Subject: [PATCH 059/143] rpi-ft5406: Add touchscreen driver for pi LCD display +Subject: [PATCH 059/190] 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 @@ -108074,10 +108074,10 @@ index 30fb37fe175df604a738258a2a632bca3bfff33f..4a3d79d3b48eb483a4e4bf498f617515 RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f, -From bf9d8140feb1c5bb942a776a48741d69398dabde Mon Sep 17 00:00:00 2001 +From ffacb25f32a6abbceca3e59dc85d0f201b803f4d Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 28 Nov 2016 16:50:04 +0000 -Subject: [PATCH 060/143] Improve __copy_to_user and __copy_from_user +Subject: [PATCH 060/190] Improve __copy_to_user and __copy_from_user performance Provide a __copy_from_user that uses memcpy. On BCM2708, use @@ -109652,10 +109652,10 @@ index 333dc3c2e5ffbb2c5ab8fcfb6115b6162643cf20..46b787a6474ffa857da9b663948863ec bool "Broadcom BCM63xx DSL SoC" depends on ARCH_MULTI_V7 -From 49813e9c1a6fdf7a82c7262fb9e1f3d62c3a9e64 Mon Sep 17 00:00:00 2001 +From 3ef28d85d3b498470ecd0d71838f957624a9e4d1 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 25 Jun 2015 12:16:11 +0100 -Subject: [PATCH 061/143] gpio-poweroff: Allow it to work on Raspberry Pi +Subject: [PATCH 061/190] 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 @@ -109690,10 +109690,10 @@ index be3d81ff51cc3f510d85e4eed7a52960e51e7bc1..a030ae9fb1fca325061c093696e82186 "%s: pm_power_off function already registered", __func__); -From 4cf353cbfb5abcbe319726ab73d65c5c9725b06e Mon Sep 17 00:00:00 2001 +From 3b36679d415e2aa2c1dc649ab15df5cd437d6240 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 14 Jul 2015 14:32:47 +0100 -Subject: [PATCH 062/143] mfd: Add Raspberry Pi Sense HAT core driver +Subject: [PATCH 062/190] mfd: Add Raspberry Pi Sense HAT core driver --- drivers/input/joystick/Kconfig | 8 + @@ -110558,10 +110558,10 @@ index 0000000000000000000000000000000000000000..56196dc2af10e464a1e3f98b028dca1c + +#endif -From 298f0da2a99e2cc999e8db96151ff92c6826bbe1 Mon Sep 17 00:00:00 2001 +From cf75db874a71e35cf0b9304022e5b541fa97608b Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 19:19:08 +0100 -Subject: [PATCH 063/143] ASoC: Add support for HifiBerry DAC +Subject: [PATCH 063/190] ASoC: Add support for HifiBerry DAC This adds a machine driver for the HifiBerry DAC. It is a sound card that can @@ -110736,10 +110736,10 @@ index 0000000000000000000000000000000000000000..45f2b770ad9e67728ca599a7445d6ae9 +MODULE_DESCRIPTION("ASoC Driver for HifiBerry DAC"); +MODULE_LICENSE("GPL v2"); -From 4e5ef7798e0f16bd34b79dcf43ca2488c7ed1c1a Mon Sep 17 00:00:00 2001 +From 6560100f7ef897089c35ec10275a4707b59c141a Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Mon, 25 Jan 2016 15:48:59 +0000 -Subject: [PATCH 064/143] ASoC: Add support for Rpi-DAC +Subject: [PATCH 064/190] ASoC: Add support for Rpi-DAC --- sound/soc/bcm/Kconfig | 7 +++ @@ -111023,10 +111023,10 @@ index 0000000000000000000000000000000000000000..afe1b419582aa40c4b2729d242bb13cd +MODULE_AUTHOR("Florian Meier "); +MODULE_LICENSE("GPL v2"); -From 2bf400ba45d9bfb1ac5b26723d69bd7100e6f2a6 Mon Sep 17 00:00:00 2001 +From f8a2672a462be5ebe159c4012e323202844e06d0 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Wed, 15 Jan 2014 21:41:23 +0100 -Subject: [PATCH 065/143] ASoC: wm8804: Implement MCLK configuration options, +Subject: [PATCH 065/190] ASoC: wm8804: Implement MCLK configuration options, add 32bit support WM8804 can run with PLL frequencies of 256xfs and 128xfs for most sample rates. At 192kHz only 128xfs is supported. The existing driver selects 128xfs automatically for some lower samples rates. By using an @@ -111075,10 +111075,10 @@ index af95d648265b3e92e345101542b332aee35191d4..513f56ba132929662802d15cdc653af3 .component_driver = { .dapm_widgets = wm8804_dapm_widgets, -From 34f11bff0a9142a2c6f3a3848dbffcc2135f571a Mon Sep 17 00:00:00 2001 +From 87c2d9ef0aa0a06463268b5d70d46b8d45d25c2d Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Wed, 15 Jan 2014 21:42:08 +0100 -Subject: [PATCH 066/143] ASoC: BCM:Add support for HiFiBerry Digi. Driver is +Subject: [PATCH 066/190] ASoC: BCM:Add support for HiFiBerry Digi. Driver is based on the patched WM8804 driver. Signed-off-by: Daniel Matuschek @@ -111422,10 +111422,10 @@ index 0000000000000000000000000000000000000000..19dc953b7227ba86123fc7a2ba654499 +MODULE_DESCRIPTION("ASoC Driver for HifiBerry Digi"); +MODULE_LICENSE("GPL v2"); -From 9ee4bd0e00a551e81a809a1126b1e3e8696cb7c9 Mon Sep 17 00:00:00 2001 +From 3e395eb641f939908f7f27033dc2d1960b801339 Mon Sep 17 00:00:00 2001 From: Gordon Garrity Date: Sat, 8 Mar 2014 16:56:57 +0000 -Subject: [PATCH 067/143] Add IQaudIO Sound Card support for Raspberry Pi +Subject: [PATCH 067/190] Add IQaudIO Sound Card support for Raspberry Pi Set a limit of 0dB on Digital Volume Control @@ -111755,10 +111755,10 @@ index 0000000000000000000000000000000000000000..4e8e6dec14bcf4a1ff286c43742d4097 +MODULE_DESCRIPTION("ASoC Driver for IQAudio DAC"); +MODULE_LICENSE("GPL v2"); -From bf5fea3022d1d56c3dd82fa726cbbc0364fae64c Mon Sep 17 00:00:00 2001 +From 45a9c2a8c3b00ef70faa52600b5784c6e619862c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 25 Jul 2016 17:06:50 +0100 -Subject: [PATCH 068/143] iqaudio-dac: Compile fix - untested +Subject: [PATCH 068/190] iqaudio-dac: Compile fix - untested --- sound/soc/bcm/iqaudio-dac.c | 6 +++++- @@ -111782,10 +111782,10 @@ index 4e8e6dec14bcf4a1ff286c43742d4097249d6777..aa15bc4b49ca95edec905fddd8fd0a6d if (dapm->dev != codec_dai->dev) return 0; -From 67ba839a62a9d52ef318c1fb5a8b7e79817b890b Mon Sep 17 00:00:00 2001 +From bd9299e181b6b5e720a383b0bfa599bceeb01148 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Mon, 4 Aug 2014 10:06:56 +0200 -Subject: [PATCH 069/143] Added support for HiFiBerry DAC+ +Subject: [PATCH 069/190] 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. @@ -112415,10 +112415,10 @@ index 72b19e62f6267698aea45d2410d616d91c1825cb..c6839ef6e16754ed9de2698507b8986a dev_err(dev, "No LRCLK?\n"); return -EINVAL; -From e5b4dd0f27f8927b566004e89c0d630ba189e654 Mon Sep 17 00:00:00 2001 +From abd7a245731db74973abc4a9b3d655cc742c1091 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Mon, 4 Aug 2014 11:09:58 +0200 -Subject: [PATCH 070/143] Added driver for HiFiBerry Amp amplifier add-on board +Subject: [PATCH 070/190] 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. @@ -113253,10 +113253,10 @@ index 0000000000000000000000000000000000000000..8f019e04898754d2f87e9630137be9e8 + +#endif /* _TAS5713_H */ -From 85a279eaea5b66242702171e5d140e417d678ee9 Mon Sep 17 00:00:00 2001 +From bfd4d9ae8ac7addf045ea3c28546fb3080c1e781 Mon Sep 17 00:00:00 2001 From: Ryan Coe Date: Sat, 31 Jan 2015 18:25:49 -0700 -Subject: [PATCH 071/143] Update ds1307 driver for device-tree support +Subject: [PATCH 071/190] Update ds1307 driver for device-tree support Signed-off-by: Ryan Coe --- @@ -113283,10 +113283,10 @@ index 4ad97be480430babc3321075f2739114eaad8f04..2ac1c265dc9cea56a5949eb537949a1f .driver = { .name = "rtc-ds1307", -From 053bc362322ac4e8bf60530e93aee667167e7f8a Mon Sep 17 00:00:00 2001 +From 33d49d00d57ad0dae41e49f86338ca77cd8d530b Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 25 Mar 2015 09:26:17 +0100 -Subject: [PATCH 072/143] Add driver for rpi-proto +Subject: [PATCH 072/190] 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 @@ -113502,10 +113502,10 @@ index 0000000000000000000000000000000000000000..9db678e885efd63d84d60a098a84ed67 +MODULE_DESCRIPTION("ASoC Driver for Raspberry Pi connected to PROTO board (WM8731)"); +MODULE_LICENSE("GPL"); -From 88224370fc80b8de92c73c3b0ae02c04bb8e496c Mon Sep 17 00:00:00 2001 +From 56b0fc1adeb9156cb9371129e3cd45dede8316d8 Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Mon, 24 Aug 2015 16:03:47 +0100 -Subject: [PATCH 073/143] RaspiDAC3 support +Subject: [PATCH 073/190] RaspiDAC3 support Signed-off-by: Jan Grulich @@ -113748,10 +113748,10 @@ index 0000000000000000000000000000000000000000..dd9eeea2af0382307f437e6db09d1546 +MODULE_DESCRIPTION("ASoC Driver for RaspiDAC Rev.3x"); +MODULE_LICENSE("GPL v2"); -From 1385ec25eb578307ba8862c9ae77e0f06d14293c Mon Sep 17 00:00:00 2001 +From 7a62b97b250b0c4543c0e44e15a0217718984807 Mon Sep 17 00:00:00 2001 From: Aaron Shaw Date: Thu, 7 Apr 2016 21:26:21 +0100 -Subject: [PATCH 074/143] Add Support for JustBoom Audio boards +Subject: [PATCH 074/190] Add Support for JustBoom Audio boards justboom-dac: Adjust for ALSA API change @@ -114205,10 +114205,10 @@ index 0000000000000000000000000000000000000000..91acb666380faa3c0deb2230f8a0f8bb +MODULE_DESCRIPTION("ASoC Driver for JustBoom PI Digi HAT Sound Card"); +MODULE_LICENSE("GPL v2"); -From fd8c46fea411354bb97265a5fb57bec83820ad4c Mon Sep 17 00:00:00 2001 +From 63d7bf833f63563bedf80bb2c50a0df7ccdce0b9 Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Tue, 3 May 2016 22:10:59 -0400 -Subject: [PATCH 075/143] ARM: adau1977-adc: Add basic machine driver for +Subject: [PATCH 075/190] ARM: adau1977-adc: Add basic machine driver for adau1977 codec driver. This commit adds basic support for the codec usage including: Device tree overlay, @@ -114390,10 +114390,10 @@ index 0000000000000000000000000000000000000000..6e2ee027926ee63c89222f75ceb89e3d +MODULE_DESCRIPTION("ASoC Driver for ADAU1977 ADC"); +MODULE_LICENSE("GPL v2"); -From d42f4ed4d2c918abc3db37daee953eec5c50ad80 Mon Sep 17 00:00:00 2001 +From b687ba624d50086f37a7a184caa494d71823a790 Mon Sep 17 00:00:00 2001 From: Matt Flax Date: Mon, 16 May 2016 21:36:31 +1000 -Subject: [PATCH 076/143] New AudioInjector.net Pi soundcard with low jitter +Subject: [PATCH 076/190] 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. @@ -114644,10 +114644,10 @@ index 0000000000000000000000000000000000000000..ef54e0f07ea03f59e9957b5d98f3e7fd +MODULE_ALIAS("platform:audioinjector-pi-soundcard"); + -From 6689d861c13e3230c53f5f1b54b7987ef92aeba9 Mon Sep 17 00:00:00 2001 +From 059b80ad576b1e2d5d26b67aa9d9bd42ed51ab0a Mon Sep 17 00:00:00 2001 From: DigitalDreamtime Date: Thu, 30 Jun 2016 18:38:42 +0100 -Subject: [PATCH 077/143] Add IQAudIO Digi WM8804 board support +Subject: [PATCH 077/190] Add IQAudIO Digi WM8804 board support Support IQAudIO Digi board with iqaudio_digi machine driver and iqaudio-digi-wm8804-audio overlay. @@ -114947,10 +114947,10 @@ index 0000000000000000000000000000000000000000..9b6e829bcb5b1762a853775e78163196 +MODULE_DESCRIPTION("ASoC Driver for IQAudIO WM8804 Digi"); +MODULE_LICENSE("GPL v2"); -From 821ba52756aaabe8947659b9be1744cad032d376 Mon Sep 17 00:00:00 2001 +From 648f9937136cc90eddc8734238cfdc28518930d5 Mon Sep 17 00:00:00 2001 From: escalator2015 Date: Tue, 24 May 2016 16:20:09 +0100 -Subject: [PATCH 078/143] New driver for RRA DigiDAC1 soundcard using WM8741 + +Subject: [PATCH 078/190] New driver for RRA DigiDAC1 soundcard using WM8741 + WM8804 --- @@ -115423,10 +115423,10 @@ index 0000000000000000000000000000000000000000..446796e7e4c14a7d95b2f2a01211d9a0 +MODULE_DESCRIPTION("ASoC Driver for RRA DigiDAC1"); +MODULE_LICENSE("GPL v2"); -From 18217ab6c25f21d54af5891f725eacd148929a10 Mon Sep 17 00:00:00 2001 +From 58bef7451fa4731c00db49e0a1c8a8e9b33b4d20 Mon Sep 17 00:00:00 2001 From: DigitalDreamtime Date: Sat, 2 Jul 2016 16:26:19 +0100 -Subject: [PATCH 079/143] Add support for Dion Audio LOCO DAC-AMP HAT +Subject: [PATCH 079/190] Add support for Dion Audio LOCO DAC-AMP HAT Using dedicated machine driver and pcm5102a codec driver. @@ -115599,10 +115599,10 @@ index 0000000000000000000000000000000000000000..89e65317512bc774453ac8d0d5b0ff98 +MODULE_DESCRIPTION("ASoC Driver for DionAudio LOCO"); +MODULE_LICENSE("GPL v2"); -From b8e26d7c19304135ac8bb435da3c95df604b9403 Mon Sep 17 00:00:00 2001 +From ca493ce0ffa50d94defbc11ce2abb1cbaac52fb9 Mon Sep 17 00:00:00 2001 From: Clive Messer Date: Mon, 19 Sep 2016 14:01:04 +0100 -Subject: [PATCH 080/143] Allo Piano DAC boards: Initial 2 channel (stereo) +Subject: [PATCH 080/190] 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, @@ -115809,10 +115809,10 @@ index 0000000000000000000000000000000000000000..8e8e62e5a36a279b425ed4655cfbac99 +MODULE_DESCRIPTION("ALSA ASoC Machine Driver for Allo Piano DAC"); +MODULE_LICENSE("GPL v2"); -From 91e732e181547ba0f62c18fbe71687688d2c1878 Mon Sep 17 00:00:00 2001 +From ef3a71964f5c723b2c8ac29d3fabef6de28ee06d Mon Sep 17 00:00:00 2001 From: gtrainavicius Date: Sun, 23 Oct 2016 12:06:53 +0300 -Subject: [PATCH 081/143] Support for Blokas Labs pisound board +Subject: [PATCH 081/190] Support for Blokas Labs pisound board Pisound dynamic overlay (#1760) @@ -116989,10 +116989,10 @@ index 0000000000000000000000000000000000000000..4b8545487d06e4ea70073a5d063fb231 +MODULE_DESCRIPTION("ASoC Driver for pisound, http://blokas.io/pisound"); +MODULE_LICENSE("GPL v2"); -From a78893616a488abf9b4c9dbf0cace4e130ea0907 Mon Sep 17 00:00:00 2001 +From 8dfe629805951bb4b2a1010f1e4f4559de13ba18 Mon Sep 17 00:00:00 2001 From: P33M Date: Wed, 21 Oct 2015 14:55:21 +0100 -Subject: [PATCH 082/143] rpi_display: add backlight driver and overlay +Subject: [PATCH 082/190] 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 @@ -117161,10 +117161,10 @@ index 0000000000000000000000000000000000000000..14a0d9b037395497c1fdae2961feccd5 +MODULE_DESCRIPTION("Raspberry Pi mailbox based Backlight Driver"); +MODULE_LICENSE("GPL"); -From e3bcfd7cedcea1f6ce90667a860eba5d19e50ec6 Mon Sep 17 00:00:00 2001 +From 9a06b725757f2c41c77fe0aa3e83c70d9e20f97a Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 23 Feb 2016 19:56:04 +0000 -Subject: [PATCH 083/143] bcm2835-virtgpio: Virtual GPIO driver +Subject: [PATCH 083/190] bcm2835-virtgpio: Virtual GPIO driver Add a virtual GPIO driver that uses the firmware mailbox interface to request that the VPU toggles LEDs. @@ -117438,10 +117438,10 @@ index 4a3d79d3b48eb483a4e4bf498f617515e3ad158f..5f34e1257117fb48013c9926a8a223d6 RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f, -From afb0883dd8b8f571e565b59a5813f939a6cce163 Mon Sep 17 00:00:00 2001 +From 33865a17996f3dd14fedc7d6462df059a4869db9 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 23 Feb 2016 17:26:48 +0000 -Subject: [PATCH 084/143] amba_pl011: Don't use DT aliases for numbering +Subject: [PATCH 084/190] 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 @@ -117470,10 +117470,10 @@ index d4171d71a258f2696ab2ab2109376ee5a516bfba..6beb6233a0b6132b933cf8d85d8501dc uap->old_cr = 0; uap->port.dev = dev; -From fdfb4986a0abca080478d8449f4f257c835a9211 Mon Sep 17 00:00:00 2001 +From 11f45d0f6b3743e8850759373d376580040718da Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Wed, 3 Dec 2014 13:23:28 +0200 -Subject: [PATCH 085/143] OF: DT-Overlay configfs interface +Subject: [PATCH 085/190] 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. @@ -117905,10 +117905,10 @@ index 0000000000000000000000000000000000000000..0037e6868a6cda8706c88194c6a4454b +} +late_initcall(of_cfs_init); -From 3d29854cf0ba3548719f9977cdae2910bf4484db Mon Sep 17 00:00:00 2001 +From 6f9eaca7d4030cff1a597895637c8f11bbf233ba Mon Sep 17 00:00:00 2001 From: Cheong2K Date: Fri, 26 Feb 2016 18:20:10 +0800 -Subject: [PATCH 086/143] brcm: adds support for BCM43341 wifi +Subject: [PATCH 086/190] brcm: adds support for BCM43341 wifi brcmfmac: Disable power management @@ -118059,10 +118059,10 @@ index dfb0658713d9b31714566b5003564a9a53eb5e97..db5f8b70b407879f1c006ca4b7ab78d1 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362), BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339), -From a4b76e3a62a42b8e2b92de017f4a0fe6cdbe7abf Mon Sep 17 00:00:00 2001 +From d19563d4aae70d53028052dc3dad36f7dd2f24ae Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 17 Dec 2015 13:37:07 +0000 -Subject: [PATCH 087/143] hci_h5: Don't send conf_req when ACTIVE +Subject: [PATCH 087/190] 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. @@ -118085,10 +118085,10 @@ index 90d0456b67446bcc624fab4b1542c4eaf21531b1..f9adeac3bbba6418dcca298c55706356 if (H5_HDR_LEN(hdr) > 2) h5->tx_win = (data[2] & 0x07); -From c3980d1190ae7a74abc71a39d774fbe92691b4ca Mon Sep 17 00:00:00 2001 +From 6f72b7d45b99f5454e8adcce48ddd8ca97265ff5 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 13 Apr 2015 17:16:29 +0100 -Subject: [PATCH 088/143] config: Add default configs +Subject: [PATCH 088/190] config: Add default configs --- arch/arm/configs/bcm2709_defconfig | 1297 +++++++++++++++++++++++++++++++++++ @@ -120715,10 +120715,10 @@ index 0000000000000000000000000000000000000000..8acee9f31202ec14f2933d92dd70831c +CONFIG_CRC_ITU_T=y +CONFIG_LIBCRC32C=y -From c59ca307b42b2c8bab4bf1d3537ca164c96cb85b Mon Sep 17 00:00:00 2001 +From 34cfa6ecba9d7086f617b3fea63d26a6d3d47239 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Wed, 24 Aug 2016 03:35:56 -0700 -Subject: [PATCH 089/143] Add arm64 configuration and device tree differences. +Subject: [PATCH 089/190] Add arm64 configuration and device tree differences. Disable MMC_BCM2835_SDHOST and MMC_BCM2835 since these drivers are crashing at the moment. @@ -122133,10 +122133,10 @@ index 0000000000000000000000000000000000000000..e6b09fafa27eed2b762e3d53b55041f7 +CONFIG_LIBCRC32C=y +CONFIG_BCM2835_VCHIQ=n -From 8d3dcfb51bd8bee21c9e6e0296c8502ca09d1f70 Mon Sep 17 00:00:00 2001 +From 7da6f7eb8806f7dc6347390bcc1c4330b46dd9c7 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 27 Dec 2016 22:13:42 +0000 -Subject: [PATCH 090/143] Revert "staging: vc04_services: remove +Subject: [PATCH 090/190] Revert "staging: vc04_services: remove vchiq_copy_from_user" This reverts commit 49bec49fd7f273ec114e2e533c1bb8f21a654aaf. @@ -122886,10 +122886,10 @@ index d9771394a041bbb55daacd7744ac57758ae198d1..7694627b925c743552b093ce51d15c2f * * Arguments: VCHI_HELD_MSG_T *message -From 37b3ac436056e51053ef5d0348ef93dc71e3be98 Mon Sep 17 00:00:00 2001 +From 76a14440a1f32a5f7c401979802fd60bd5244e0a Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 23 Mar 2016 14:16:25 +0000 -Subject: [PATCH 091/143] vchiq_arm: Access the dequeue_pending flag locked +Subject: [PATCH 091/190] vchiq_arm: Access the dequeue_pending flag locked Reading through this code looking for another problem (now found in userland) the use of dequeue_pending outside a lock didn't seem safe. @@ -122947,10 +122947,10 @@ index 42998155eb4d7de8e49cc1ca82d84a430562a8da..74f1569097c7dd120cc68fb8d09d8c3d return add_completion(instance, reason, header, user_service, -From 23dc62ffb692ae7e3a5be4bba257e51a87ac56c4 Mon Sep 17 00:00:00 2001 +From a3d7bb034d97dbef8bfa92fdf82e090055eefd6a Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 23 Mar 2016 20:53:47 +0000 -Subject: [PATCH 092/143] vchiq_arm: Service callbacks must not fail +Subject: [PATCH 092/190] vchiq_arm: Service callbacks must not fail Service callbacks are not allowed to return an error. The internal callback that delivers events and messages to user tasks does not enqueue them if @@ -122976,10 +122976,10 @@ index 74f1569097c7dd120cc68fb8d09d8c3d63d56977..3ba6485f0c7b32de9f2aa75164e8b1b9 DEBUG_TRACE(SERVICE_CALLBACK_LINE); } -From ce301053ff5dc3f25a290a8378927b355793c888 Mon Sep 17 00:00:00 2001 +From 360f97c51240920b702ca740492d5a5c0de56ec0 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 21 Apr 2016 13:49:32 +0100 -Subject: [PATCH 093/143] vchiq_arm: Add completion records under the mutex +Subject: [PATCH 093/190] vchiq_arm: Add completion records under the mutex An issue was observed when flushing openmax components which generate a large number of messages returning @@ -123042,10 +123042,10 @@ index 3ba6485f0c7b32de9f2aa75164e8b1b901aa74ea..07d8eadd2aa2dc997db13c80dc303673 return VCHIQ_SUCCESS; -From c1fe6df4ea43f0b9545a6050b72b7d1fe5e84a99 Mon Sep 17 00:00:00 2001 +From bf4e56c17ba6175342240e5c0d7c8815c3be9cb9 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 20 Jun 2016 13:51:44 +0100 -Subject: [PATCH 094/143] vchiq_arm: Avoid use of mutex in add_completion +Subject: [PATCH 094/190] vchiq_arm: Avoid use of mutex in add_completion Claiming the completion_mutex within add_completion did prevent some messages appearing twice, but provokes a deadlock caused by vcsm using @@ -123239,10 +123239,10 @@ index c5b06cc4ca53135ec9491116ca79beaa98f57bcc..d6757ee263fb61a689c0d38c0dbb65c5 up(&state->slot_available_event); } -From 8c1a98f073a1510731dd6fec6e94ddeee3ed44fa Mon Sep 17 00:00:00 2001 +From 06ade643f2c66bb6284c3094b0095ed244d4ea65 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 14 Sep 2016 09:18:09 +0100 -Subject: [PATCH 095/143] raspberrypi-firmware: Define the MBOX channel in the +Subject: [PATCH 095/190] raspberrypi-firmware: Define the MBOX channel in the header. Signed-off-by: Eric Anholt @@ -123264,10 +123264,10 @@ index 5f34e1257117fb48013c9926a8a223d64a598ab7..7f0da0727422c690947e46e891a754de enum rpi_firmware_property_status { -From 7d3bc19bbd84fefcdd27577dd37fc46fd8e94495 Mon Sep 17 00:00:00 2001 +From f7a72fc372e54d3766c1e7e36e7b93835485f5db Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 14 Sep 2016 08:39:33 +0100 -Subject: [PATCH 096/143] drm/vc4: Add a mode for using the closed firmware for +Subject: [PATCH 096/190] drm/vc4: Add a mode for using the closed firmware for display. Signed-off-by: Eric Anholt @@ -124034,10 +124034,10 @@ index 0000000000000000000000000000000000000000..d18a1dae51a2275846c9826b5bf1ba57 + }, +}; -From b9d76cb88a9c87fe808ddb234e379d10a6c28e6f Mon Sep 17 00:00:00 2001 +From c78d53b11d542b1110111e2d152bbe8529193b66 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 097/143] i2c: bcm2835: Add debug support +Subject: [PATCH 097/190] i2c: bcm2835: Add debug support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -124226,10 +124226,10 @@ index c3436f627028477f7e21b47e079fd5ab06ec188a..8642f580ce41803bd22c76a0fa80d083 if (i2c_dev->msg_err & BCM2835_I2C_S_ERR) return -EREMOTEIO; -From 0943957d423c895c065a0722eae050927a92e597 Mon Sep 17 00:00:00 2001 +From c00d44997c9a24660ce060e56905967b34dd1448 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 14 Sep 2016 09:16:19 +0100 -Subject: [PATCH 098/143] raspberrypi-firmware: Export the general transaction +Subject: [PATCH 098/190] raspberrypi-firmware: Export the general transaction function. The vc4-firmware-kms module is going to be doing the MBOX FB call. @@ -124273,10 +124273,10 @@ index 7f0da0727422c690947e46e891a754de13dc1fea..280791fb9656901392ce67e44cb742c9 #endif /* __SOC_RASPBERRY_FIRMWARE_H__ */ -From d892ed3ef0153b2b3041f6f76a88410575270bd2 Mon Sep 17 00:00:00 2001 +From 24d7c6765eb6d6dee0f0b3231195d40d2e864f99 Mon Sep 17 00:00:00 2001 From: Alex Tucker Date: Tue, 13 Dec 2016 19:50:18 +0000 -Subject: [PATCH 099/143] Add support for Silicon Labs Si7013/20/21 +Subject: [PATCH 099/190] Add support for Silicon Labs Si7013/20/21 humidity/temperature sensor. --- @@ -124351,10 +124351,10 @@ index f6d134c095af2398fc55ae7d2b0e86456c30627c..31bda8da4cb6a56bfe493a81b9189009 }; }; -From a7f4466713fc62e679070212dd09533d66db889c Mon Sep 17 00:00:00 2001 +From 7d62423e76b97d6affb920a1bf9f813ee1bd403d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 3 Jan 2017 21:27:46 +0000 -Subject: [PATCH 100/143] Document the si7020 option +Subject: [PATCH 100/190] Document the si7020 option --- arch/arm/boot/dts/overlays/README | 3 +++ @@ -124375,10 +124375,10 @@ index 81d991803be335e5a1bc3bb0a8c7a2c9f5c392bd..e8fa4ccb44c34a20485c4e6155467af9 Name: i2c0-bcm2708 Info: Enable the i2c_bcm2708 driver for the i2c0 bus. Not all pin combinations -From 62211690633ae9f41cea842893da69f8ba168636 Mon Sep 17 00:00:00 2001 +From 5ff140d63e29b05b914274b61bad0fea2656b327 Mon Sep 17 00:00:00 2001 From: Giedrius Trainavicius Date: Thu, 5 Jan 2017 02:38:16 +0200 -Subject: [PATCH 101/143] pisound improvements: +Subject: [PATCH 101/190] pisound improvements: * Added a writable sysfs object to enable scripts / user space software to blink MIDI activity LEDs for variable duration. @@ -124672,10 +124672,10 @@ index 4b8545487d06e4ea70073a5d063fb2310b3b94d0..ba70734b89e61a11201657406223f0b3 }; -From d72d3147ef62a6da9b073b2d103a529aa7481c67 Mon Sep 17 00:00:00 2001 +From de3d5c6b875102ca2f0ce9c08a25eac10b473277 Mon Sep 17 00:00:00 2001 From: Aaron Shaw Date: Tue, 10 Jan 2017 16:05:41 +0000 -Subject: [PATCH 102/143] Add driver_name property +Subject: [PATCH 102/190] Add driver_name property Add driver name property for use with 5.1 passthrough audio in LibreElec and other Kodi based OSs --- @@ -124695,10 +124695,10 @@ index 8fd50dbe681508a2cfe8fdde1c9fedbe9a507fa7..05a224ec712d06b8b7587ab6b8bb562d .dai_link = snd_rpi_justboom_dac_dai, .num_links = ARRAY_SIZE(snd_rpi_justboom_dac_dai), -From 38aedb6db6a04fc234a823f2da4274b0712f8c8d Mon Sep 17 00:00:00 2001 +From 28362694432c973e25cbf973624521ab20f9f0e2 Mon Sep 17 00:00:00 2001 From: Aaron Shaw Date: Tue, 10 Jan 2017 16:11:04 +0000 -Subject: [PATCH 103/143] Add driver_name paramater +Subject: [PATCH 103/190] Add driver_name paramater Add driver_name parameter for use with 5.1 passthrough audio in LibreElec and other Kodi OSs --- @@ -124718,10 +124718,10 @@ index 91acb666380faa3c0deb2230f8a0f8bbec59417b..abfdc5c4dd5811e6847bddda4921abe3 .dai_link = snd_rpi_justboom_digi_dai, .num_links = ARRAY_SIZE(snd_rpi_justboom_digi_dai), -From 777083226e9e5b3d06c24bac85ced08f6f822cfd Mon Sep 17 00:00:00 2001 +From 57bff8c4aba4b0934aae00c688bebd3f615536b7 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 11 Jan 2017 13:01:21 +0000 -Subject: [PATCH 104/143] BCM270X_DT: Add pi3-disable-wifi overlay +Subject: [PATCH 104/190] BCM270X_DT: Add pi3-disable-wifi overlay pi3-disable-wifi is a minimal overlay to disable the onboard WiFi. @@ -124782,10 +124782,10 @@ index 0000000000000000000000000000000000000000..017199554bf2f4e381efcc7bb71e750c + }; +}; -From 8c98940e11190aa70ee56241e0b666e7adae7675 Mon Sep 17 00:00:00 2001 +From f11de16b9956c2b030a58f829caee0fa0608f571 Mon Sep 17 00:00:00 2001 From: Electron752 Date: Thu, 12 Jan 2017 07:07:08 -0800 -Subject: [PATCH 105/143] ARM64: Make it work again on 4.9 (#1790) +Subject: [PATCH 105/190] ARM64: Make it work again on 4.9 (#1790) * Invoke the dtc compiler with the same options used in arm mode. * ARM64 now uses the bcm2835 platform just like ARM32. @@ -125189,10 +125189,10 @@ index e6b09fafa27eed2b762e3d53b55041f793683d27..c7e891d72969a388d9b135a36dbfc9c9 CONFIG_LIBCRC32C=y -CONFIG_BCM2835_VCHIQ=n -From 8f1f3cb604b6a02ae7aec733ac4930f9409a9470 Mon Sep 17 00:00:00 2001 +From 957d8a45127a446a482ed7b0781f2114afcdef46 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Thu, 12 Jan 2017 18:56:54 -0800 -Subject: [PATCH 106/143] ARM64: Fix bad cast in vc04_services +Subject: [PATCH 106/190] ARM64: Fix bad cast in vc04_services The function vchiq_copy_from_user contains a non-portable cast to uint32_t. Convert this to a cast to unsigned long @@ -125217,10 +125217,10 @@ index 706e7f936c1a97352f7ef3d3fbd3b4a92943165d..c2108dec3096fffd68261f0eb29a37d3 } else { memcpy(dst, src, size); -From 9676247b36fc83b7ed908c052b00a3fcc323e9b9 Mon Sep 17 00:00:00 2001 +From c9424561d8ddcf5dbf8723186de2f29cc091231e Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Thu, 12 Jan 2017 19:05:46 -0800 -Subject: [PATCH 107/143] ARM64/SND_BCM2835: Port it to arm64. +Subject: [PATCH 107/190] ARM64/SND_BCM2835: Port it to arm64. In the messages sent to VCHIQ, SND_BCM2835 passes a callback and a context into two 32 bit pointers. Since this @@ -125317,10 +125317,10 @@ index af3e6eb690113fc32ce9e06bd2f0f294da7a7f00..ede6154bc09d38469a82008174d0e357 // Message header for all messages in HOST->VC direction -From 0e2f25b763a178a40c3d41db607f8274356cf9ee Mon Sep 17 00:00:00 2001 +From 8b2e4020bb202586de7c6e083a0fe13f4eaebfc2 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Thu, 12 Jan 2017 19:10:07 -0800 -Subject: [PATCH 108/143] ARM64: Enable HDMI audio and vc04_services in +Subject: [PATCH 108/190] ARM64: Enable HDMI audio and vc04_services in bcmrpi3_defconfig Signed-off-by: Michael Zoran @@ -125349,10 +125349,10 @@ index c7e891d72969a388d9b135a36dbfc9c9cb609bf8..4b90f9b64abe9f089ba56b13d5a00de3 CONFIG_BCM2835_MBOX=y # CONFIG_IOMMU_SUPPORT is not set -From 03d5ad561d3ffd312f88445ec5f6ec0ab9527fde Mon Sep 17 00:00:00 2001 +From db1ceaae2a32a0f12127af14fc0445f5656be08f Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Thu, 12 Jan 2017 19:14:03 -0800 -Subject: [PATCH 109/143] ARM64: Run bcmrpi3_defconfig through savedefconfig. +Subject: [PATCH 109/190] ARM64: Run bcmrpi3_defconfig through savedefconfig. Signed-off-by: Michael Zoran --- @@ -125397,10 +125397,10 @@ index 4b90f9b64abe9f089ba56b13d5a00de33343bfb9..dac962ca1634662ce7d966f1ffb53b5b CONFIG_FB_TFT_AGM1264K_FL=m CONFIG_FB_TFT_BD663474=m -From bae403b696c8f60057e8a025886ae67b287fc4c0 Mon Sep 17 00:00:00 2001 +From 05043a7cea9dc31db9197acf85c025dae2e89c26 Mon Sep 17 00:00:00 2001 From: Electron752 Date: Sat, 14 Jan 2017 02:54:26 -0800 -Subject: [PATCH 110/143] ARM64: Enable Kernel Address Space Randomization +Subject: [PATCH 110/190] ARM64: Enable Kernel Address Space Randomization (#1792) Randomization allows the mapping between virtual addresses and physical @@ -125432,10 +125432,10 @@ index dac962ca1634662ce7d966f1ffb53b5bfa27c506..aae33b4b3c3e736ea7cd3ca242158ad6 CONFIG_BINFMT_MISC=y CONFIG_COMPAT=y -From 3942188f6df384656ecc00a8721bdbc1cdea8438 Mon Sep 17 00:00:00 2001 +From 4c95e3cd42bfc39e2933d370f6599d35ae376355 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Sun, 15 Jan 2017 07:31:59 -0800 -Subject: [PATCH 111/143] ARM64: Enable RTL8187/RTL8192CU wifi in build config +Subject: [PATCH 111/190] ARM64: Enable RTL8187/RTL8192CU wifi in build config These drivers build now, so they can be enabled back in the build configuration just like they are for @@ -125460,10 +125460,10 @@ index aae33b4b3c3e736ea7cd3ca242158ad6ba558aff..b7d762df19b85e369a32cd823dfd0621 CONFIG_ZD1211RW=m CONFIG_MAC80211_HWSIM=m -From 9d0130fcb9311c2db10e4b49b4faab7e28f19d4b Mon Sep 17 00:00:00 2001 +From e6e0f03c0ce5046207285293cfb20cc46a861b52 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 16 Jan 2017 14:53:12 +0000 -Subject: [PATCH 112/143] BCM270X_DT: Add spi0-cs overlay +Subject: [PATCH 112/190] BCM270X_DT: Add spi0-cs overlay The spi0-cs overlay allows the software chip selectts to be modified using the cs0_pin and cs1_pin parameters. @@ -125551,10 +125551,10 @@ index 0000000000000000000000000000000000000000..7f79029d043c04d7496c7c3480450c69 + }; +}; -From 06935466e531c3423bb46c5043b14d0577ce113d Mon Sep 17 00:00:00 2001 +From 124efe6b711e1af91a1c3ba6d0a7efbbc8b2af45 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 1 Jul 2016 22:09:24 +0100 -Subject: [PATCH 113/143] spi-bcm2835: Disable forced software CS +Subject: [PATCH 113/190] 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 @@ -125580,10 +125580,10 @@ index 9a44da19089717f02462c657840ae9f24fd942ba..b710a4d67b8ec8c8c18ce8efb6f270e7 i2c0: i2c@7e205000 { -From 344059857429edb2332ea788e2c256668f24a609 Mon Sep 17 00:00:00 2001 +From 2f8e7d14b126767b1ee396ea3693624ffbdde4cf Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 17 Jan 2017 11:34:58 +0000 -Subject: [PATCH 114/143] BCM270X_DT: Enable UART0 on CM3 +Subject: [PATCH 114/190] BCM270X_DT: Enable UART0 on CM3 Signed-off-by: Phil Elwell --- @@ -125606,10 +125606,10 @@ index 41874c25a84226c0e4af92ec4059e0a571fe6123..3ba6e621856c288ae4694f758604619f sdhost_pins: sdhost_pins { brcm,pins = <48 49 50 51 52 53>; -From af4413600326fef6041165c26a66c1cee892233a Mon Sep 17 00:00:00 2001 +From 864b91126a504a382c987d45f851088c2b5ba410 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 17 Jan 2017 14:39:39 +0000 -Subject: [PATCH 115/143] config: Add CONFIG_MD_M25P80 and CONFIG_MD_SPI_NOR +Subject: [PATCH 115/190] config: Add CONFIG_MD_M25P80 and CONFIG_MD_SPI_NOR See: https://github.com/raspberrypi/linux/issues/1781 @@ -125714,10 +125714,10 @@ index 8acee9f31202ec14f2933d92dd70831cda8d7b51..aca8903da3156de11ba62afa64a06939 CONFIG_FB_TFT_AGM1264K_FL=m CONFIG_FB_TFT_BD663474=m -From 2db22e08eb782d9b31df67d4a2d2b6d3e2229222 Mon Sep 17 00:00:00 2001 +From 270efc01e40bb32d4fd60a0ee608a47c6fd76f32 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Sat, 14 Jan 2017 21:33:51 -0800 -Subject: [PATCH 116/143] ARM64/DWC_OTG: Port dwc_otg driver to ARM64 +Subject: [PATCH 116/190] 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 @@ -126060,10 +126060,10 @@ index 6b2c7d0c93f36a63863ff4b0ecc1f3eab77e058b..d7b700ff17821ad1944e36721fe6b2db /** The OS page size */ #define DWC_OS_PAGE_SIZE PAGE_SIZE -From 3fd685e26219daae1087d48f160f6121f6fffb87 Mon Sep 17 00:00:00 2001 +From 6f5f34f8126ea8f62d7774fb989564ef921208ba Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Sat, 14 Jan 2017 21:43:57 -0800 -Subject: [PATCH 117/143] ARM64: Round-Robin dispatch IRQs between CPUs. +Subject: [PATCH 117/190] 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 @@ -126137,10 +126137,10 @@ index a8db33b50ad9ff83d284fa54fe4d3b65f859df0f..67dcac46cca72db4ebe2300eab04f0a8 .name = "bcm2836-gpu", .irq_mask = bcm2836_arm_irqchip_mask_gpu_irq, -From 5798b8a6ee69242586c8d244d79acb4a49b32ffe Mon Sep 17 00:00:00 2001 +From 18bf49741a1afc8d00caae1b9e8346762a0310f8 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Sat, 14 Jan 2017 21:45:03 -0800 -Subject: [PATCH 118/143] ARM64: Enable DWC_OTG Driver In ARM64 Build +Subject: [PATCH 118/190] ARM64: Enable DWC_OTG Driver In ARM64 Build Config(bcmrpi3_defconfig) Signed-off-by: Michael Zoran @@ -126161,10 +126161,10 @@ index b7d762df19b85e369a32cd823dfd062145bdefa7..4d85c231c5ea0244e1b05fb4a5e3c8fd CONFIG_USB_STORAGE=y CONFIG_USB_STORAGE_REALTEK=m -From 72a5e963ed3e8137b91a721c8e5c151746a86b7d Mon Sep 17 00:00:00 2001 +From 1345c48679f5b0ba1df0386ad9a4fbd3540970d6 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Sat, 14 Jan 2017 21:46:04 -0800 -Subject: [PATCH 119/143] ARM64: Use dwc_otg driver by default for USB. +Subject: [PATCH 119/190] ARM64: Use dwc_otg driver by default for USB. If it breaks on anybody, they can use the standard device tree overlays to switch back to the dwc2 driver. @@ -126190,10 +126190,10 @@ index f6def5d7e5d622cf09e8f87332c7374fe28da08b..3e134a1208610b90e2d0fc22f03c6e9f -}; -#endif -From de0e945d578f47f93f927ef11f16b92eb0fe1de8 Mon Sep 17 00:00:00 2001 +From 1b346a8ae9a4a5df88620036346c8e9264e8e592 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 19 Jan 2017 11:18:55 +0000 -Subject: [PATCH 120/143] config: Add CONFIG_USB_DWC2 and CONFIG_USB_GADGET +Subject: [PATCH 120/190] config: Add CONFIG_USB_DWC2 and CONFIG_USB_GADGET The introduction of CM3 makes gadget mode on 2709 a useful option, so enable the building of the required modules. Note that these @@ -126226,10 +126226,10 @@ index c36f01d28097a513b32df092ce64a7d6b974e615..2e2b88fefdf367b2d9190ca227ea6eb3 CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_BCM2835=y -From bf4fff3dc99c07e8aed32dcbe9e77bf88199a5ba Mon Sep 17 00:00:00 2001 +From 21793303ed79ad833da586ba76950c1f3f9c01fe Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 23 Jan 2017 17:36:50 +0000 -Subject: [PATCH 121/143] BCM270X_DT: Add reference to audio_pins to CM dtb +Subject: [PATCH 121/190] BCM270X_DT: Add reference to audio_pins to CM dtb The CM1 dtb contains an empty audio_pins node, but no reference to it. Adding the usual pinctrl reference from the audio node enables the @@ -126257,10 +126257,10 @@ index eb8662f0d222b4c0a9a2bcb8bccb13e86a0006b3..10be69972bd1440f574e35d515f3d6a0 hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; }; -From acd57d74b3c2b58a8e30fda9a7690ab3617e12d3 Mon Sep 17 00:00:00 2001 +From aca25515739ed0b82705ee040163f9eac4026637 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 25 Jan 2017 11:30:38 +0000 -Subject: [PATCH 122/143] config: Add additional network scheduling modules +Subject: [PATCH 122/190] config: Add additional network scheduling modules --- arch/arm/configs/bcm2709_defconfig | 4 ++++ @@ -126312,10 +126312,10 @@ index aca8903da3156de11ba62afa64a0693900ee3611..c8c66751f263227e86cc21ad5b23861a CONFIG_NET_SCH_PLUG=m CONFIG_NET_CLS_BASIC=m -From 7eb8cc55a5c43be9072c29138436df54131cc9da Mon Sep 17 00:00:00 2001 +From 81f6d699d879170c02da4d3e1a26dd248ca76b9f Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 16 Jan 2017 16:33:54 +0000 -Subject: [PATCH 123/143] config: Add CONFIG_TCP_CONG_BBR See: +Subject: [PATCH 123/190] config: Add CONFIG_TCP_CONG_BBR See: https://github.com/raspberrypi/linux/issues/1784 --- @@ -126350,10 +126350,10 @@ index c8c66751f263227e86cc21ad5b23861a88a636a6..e483bdb7aa869b212ef69ed779c6055e CONFIG_IPV6_ROUTER_PREF=y CONFIG_INET6_AH=m -From 736809cbe89cb56b087efaaccc55eb4a5627db33 Mon Sep 17 00:00:00 2001 +From c2ce26b01adb38ab8143e2bfde14876d1dfb86da Mon Sep 17 00:00:00 2001 From: chris johnson Date: Sun, 22 Jan 2017 03:27:31 +0000 -Subject: [PATCH 124/143] ASoC: A simple-card overlay for ADAU7002 +Subject: [PATCH 124/190] ASoC: A simple-card overlay for ADAU7002 Usage: `dtoverlay=adau7002-simple` --- @@ -126451,10 +126451,10 @@ index 0000000000000000000000000000000000000000..e67e6625d7967abc92cf00cb604d4c12 + }; +}; -From 8178b62fa432470071fb0fca59a200376094c8b8 Mon Sep 17 00:00:00 2001 +From c2ddfaca8ffe702293c91d1d55467bb5155a0d72 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 25 Jan 2017 21:17:23 +0000 -Subject: [PATCH 125/143] config: Add SND_SOC_ADAU7002 codec module +Subject: [PATCH 125/190] config: Add SND_SOC_ADAU7002 codec module As there is now an overlay requiring it, build the codec module. @@ -126489,10 +126489,10 @@ index e483bdb7aa869b212ef69ed779c6055ef3b70e2a..1927b1671b6eced73e4b4d76352bb4b1 CONFIG_SND_SOC_WM8804_I2C=m CONFIG_SND_SIMPLE_CARD=m -From a6d7fbc3f756abc3c51088ac8509f85c49b16fff Mon Sep 17 00:00:00 2001 +From 733cf7745fe6f63e317b906b613bea3067283b28 Mon Sep 17 00:00:00 2001 From: Scott Ellis Date: Fri, 27 Jan 2017 06:42:42 -0500 -Subject: [PATCH 126/143] Add overlay for mcp3008 adc (#1818) +Subject: [PATCH 126/190] Add overlay for mcp3008 adc (#1818) Some example usage: @@ -126778,10 +126778,10 @@ index 0000000000000000000000000000000000000000..06bf4264959c380d8a9f90f74e780397 + }; +}; -From fd202b0efb38df7c056c3a0e97cfdebb6470c04d Mon Sep 17 00:00:00 2001 +From d5c35222663fd03efc750778f4f267f98a6a3b98 Mon Sep 17 00:00:00 2001 From: JamesH65 Date: Mon, 6 Feb 2017 15:24:47 +0000 -Subject: [PATCH 127/143] gpio_mem: Remove unnecessary dev_info output (#1830) +Subject: [PATCH 127/190] gpio_mem: Remove unnecessary dev_info output (#1830) The open function was spamming syslog every time called, so have removed call completely. @@ -126803,10 +126803,10 @@ index 911f5b7393ed48ceed8751f06967ae6463453f9c..f5e7f1ba8fb6f18dee77fad06a17480c dev_err(inst->dev, "Unknown minor device: %d", dev); ret = -ENXIO; -From 46c74000bbbec747bca0c5ab07a538e64392494c Mon Sep 17 00:00:00 2001 +From ec2fb02ca6392fc5b318d921b885a4c733955419 Mon Sep 17 00:00:00 2001 From: Claggy3 Date: Sat, 11 Feb 2017 14:00:30 +0000 -Subject: [PATCH 128/143] Update vfpmodule.c +Subject: [PATCH 128/190] 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 @@ -126943,10 +126943,10 @@ index 569d5a650a4a2c6266ddf8fc6d38e0cd96b985f6..5822a3f60a96510201a6d88828ac5262 /* * Save the userland NEON/VFP state. Under UP, -From 9e197d6809356852ca185489f156071cc5d47a7d Mon Sep 17 00:00:00 2001 +From 05a6020f89eaccbeb9d1bdc039f21943d2da8d27 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Sat, 11 Feb 2017 01:18:31 -0800 -Subject: [PATCH 129/143] ARM64: Force hardware emulation of deprecated +Subject: [PATCH 129/190] ARM64: Force hardware emulation of deprecated instructions. --- @@ -126974,10 +126974,10 @@ index ecf9298a12d48f11d5833dca0584d8ab028cf422..14e9146709857124891f8a3927efec87 case INSN_OBSOLETE: insn->current_mode = INSN_UNDEF; -From 919d9f14f43a8dd52c0008537f00dfccb96d5ef6 Mon Sep 17 00:00:00 2001 +From 47c4217bd9f5655847ec14e7d7b0b19078a40659 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 13 Feb 2017 15:33:47 +0000 -Subject: [PATCH 130/143] squash: fix order of sound/soc/bcm makefile +Subject: [PATCH 130/190] squash: fix order of sound/soc/bcm makefile --- sound/soc/bcm/Makefile | 4 ++-- @@ -127016,10 +127016,10 @@ index 222a7583891f632cc2297f49aa1a58ee46507875..bb1df438540193652ec5464e8bc51f63 obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o -From 56bd4eb7b09c4d016c8f7908d496b11bbadbd9a0 Mon Sep 17 00:00:00 2001 +From 885e780a94436ab097a715020294bb34292b878c Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 22 Jan 2017 12:49:36 +0100 -Subject: [PATCH 131/143] config: Enable regulator support +Subject: [PATCH 131/190] config: Enable regulator support Signed-off-by: Matthias Reichl --- @@ -127054,10 +127054,10 @@ index 1927b1671b6eced73e4b4d76352bb4b1301d077c..5351a59b7f670985f47fdbafa2611734 CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_MEDIA_ANALOG_TV_SUPPORT=y -From f135ac30c31d61724299d0449887727ce9def765 Mon Sep 17 00:00:00 2001 +From 9ea578dea494e6c139c6dcd2090705398e5c84d9 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 22 Jan 2017 12:49:36 +0100 -Subject: [PATCH 132/143] BCM270x DT: expose 3.3V and 5V system rails +Subject: [PATCH 132/190] BCM270x DT: expose 3.3V and 5V system rails Signed-off-by: Matthias Reichl --- @@ -127090,10 +127090,10 @@ index a46cb4a8b1419edd95e0e07c18b0f373222dc2bf..36d853715f2379e1952ce3d3be58dd67 + }; }; -From 437ca0a4918b034a16d8ac151b950cf838d484c5 Mon Sep 17 00:00:00 2001 +From d58dfa1aeb9618c7cbf8ffc76100b1af24265a46 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 22 Jan 2017 12:49:36 +0100 -Subject: [PATCH 133/143] BCM270x DT: Consolidate audio card overlays +Subject: [PATCH 133/190] BCM270x DT: Consolidate audio card overlays Reference 3.3V / 5V system rails instead of instantiating local regulators. @@ -127388,10 +127388,10 @@ index 16b1247bfa618ff85936ddf78c3aea58075eaa67..f8d48233e28c7c18509b4a95692f6aff __overlay__ { compatible = "rra,digidac1-soundcard"; -From 82906808c3fbe9c74524b2c055fad291c39c2fca Mon Sep 17 00:00:00 2001 +From 844ee22d27af5a1eaa22396bd4bb12e504e3cb7f Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 22 Jan 2017 12:49:37 +0100 -Subject: [PATCH 134/143] ASoC: Add driver for Cirrus Logic Audio Card +Subject: [PATCH 134/190] 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 @@ -128641,10 +128641,10 @@ index 0000000000000000000000000000000000000000..ac8651ddff7bd3701dffe22c7fb88352 +MODULE_DESCRIPTION("ASoC driver for Cirrus Logic Audio Card"); +MODULE_LICENSE("GPL"); -From 4dc3d4c1f881814cccba7de2c34e8a78345223fb Mon Sep 17 00:00:00 2001 +From a130902784ec875a268bf8b07dc86f586e90aba9 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 22 Jan 2017 12:49:37 +0100 -Subject: [PATCH 135/143] config: enable Cirrus Logic Audio Card +Subject: [PATCH 135/190] config: enable Cirrus Logic Audio Card Signed-off-by: Matthias Reichl --- @@ -128693,10 +128693,10 @@ index 5351a59b7f670985f47fdbafa26117346cafe87d..062a89f0e5fc723559ddc5739e19eb20 CONFIG_SND_BCM2708_SOC_RPI_PROTO=m CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m -From e3ef450ae4a4d20765f724e5b91e3378d2a8ba3c Mon Sep 17 00:00:00 2001 +From 2e138dae03942a44e5f035b2dce47b64bf6457c2 Mon Sep 17 00:00:00 2001 From: Martin Cerveny Date: Mon, 13 Feb 2017 17:23:47 +0100 -Subject: [PATCH 136/143] dwc_otg: fix summarize urb->actual_length for +Subject: [PATCH 136/190] dwc_otg: fix summarize urb->actual_length for isochronous transfers Kernel does not copy input data of ISO transfers to userspace @@ -128724,10 +128724,10 @@ index 162a656501988e56c9d780b7793d365fde09f801..992269d61ecf48126379a38e528f7190 dwc_otg_hcd_urb_get_iso_desc_status(dwc_otg_urb, i); } -From a58a00d172f51f697284a485ae1f3a6161ede074 Mon Sep 17 00:00:00 2001 +From 8e25438bf174b466801220bf904cd9fa9fbee65a Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 13 Feb 2017 17:20:08 +0000 -Subject: [PATCH 137/143] clk-bcm2835: Mark used PLLs and dividers CRITICAL +Subject: [PATCH 137/190] 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 @@ -128755,10 +128755,10 @@ index 093694e00caec6e133eb26712f890691cad999aa..33bfa2008479153402d188d71d382f02 divider->data = data; -From cef191d42985b1a1ba2c4a169b80e4628db23195 Mon Sep 17 00:00:00 2001 +From adcf0aa78d541f9beff8608fd800e620e898915d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 9 Feb 2017 14:33:30 +0000 -Subject: [PATCH 138/143] irq-bcm2836: Avoid "Invalid trigger warning" +Subject: [PATCH 138/190] irq-bcm2836: Avoid "Invalid trigger warning" Initialise the level for each IRQ to avoid a warning from the arm arch timer code. @@ -128782,10 +128782,10 @@ index 67dcac46cca72db4ebe2300eab04f0a867e8e14b..9a7ee04ee0d9b7aa734cf3159ed59c19 static void -From 70cab3f1bb92d60cf794a5baf22ac1fbdbec7ba2 Mon Sep 17 00:00:00 2001 +From fe1b02d4ef58bdd45ddc89d1e5ebaff94d8bd43c Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 9 Feb 2017 14:36:44 +0000 -Subject: [PATCH 139/143] sound: Demote deferral errors to INFO level +Subject: [PATCH 139/190] 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. @@ -128820,10 +128820,10 @@ index baa1afa41e3dd57fdc36655b7d3bbd147ade820f..0ddeffcc48d6c14f275ea6409d1a7de8 goto _err_defer; } -From cb1e295e8b8cf1edbab91d7d42919c28ebe3069e Mon Sep 17 00:00:00 2001 +From fd7ac16622c8784f8f270950692d00ca55e461eb Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 9 Feb 2017 14:40:33 +0000 -Subject: [PATCH 140/143] sound: Suppress error message about deferrals +Subject: [PATCH 140/190] sound: Suppress error message about deferrals Since driver load deferrals are expected and will already have resulted in a kernel message, suppress an essentially @@ -129070,10 +129070,10 @@ index 9db678e885efd63d84d60a098a84ed6772b19a2d..fadbfade100228aaafabb0d3bdf35c01 return ret; } -From 13607ce48ba1e8c887aeee343ac3f37ab9bf143b Mon Sep 17 00:00:00 2001 +From 32cd8c918fe1a0b5fdcce9ac9ef401f5d789c49d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 17 Feb 2017 09:47:11 +0000 -Subject: [PATCH 141/143] BCM270X_DT: Add SMSC ethernet controller to DT +Subject: [PATCH 141/190] BCM270X_DT: Add SMSC ethernet controller to DT With an ethernet node in the DT, a suitable firmware can populate the local-mac-address property, removing the need for a downstream patch @@ -129136,10 +129136,10 @@ index 12764a3495b2372ffaf47e32ea0d21326ca83686..2a5b512d3e1acb17c6a40bf9d370f222 / { model = "Raspberry Pi 3 Model B"; -From e1d3ee3e5c9e549cec2088efeb1cbc9b1a682b31 Mon Sep 17 00:00:00 2001 +From 42e17cc726d0c80c0c20f4f6b45222415f49defb Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 17 Feb 2017 15:26:13 +0000 -Subject: [PATCH 142/143] brcmfmac: Mute expected startup 'errors' +Subject: [PATCH 142/190] brcmfmac: Mute expected startup 'errors' The brcmfmac WiFi driver always complains about the '00' country code and the firmware version is reported as an error. Modify the driver to @@ -129178,10 +129178,10 @@ index 4051780f64f44a5ce522babe6c371a1beb79a824..b081673abcb4aa72d70d8e0834b608f6 /* locate firmware version number for ethtool */ ptr = strrchr(buf, ' ') + 1; -From cbeb4f8aeb1dd71e911d365a921c0da4fbbdfdbb Mon Sep 17 00:00:00 2001 +From aeeedc76e1aee10ca9bdbf9319cf10803ff2b073 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 13 Feb 2017 17:20:08 +0000 -Subject: [PATCH 143/143] clk-bcm2835: Add claim-clocks property +Subject: [PATCH 143/190] 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, @@ -129316,3 +129316,7127 @@ index 33bfa2008479153402d188d71d382f0274c104ea..0b62d20f8b718cfd03c0346af784688e cprman->osc_name = of_clk_get_parent_name(dev->of_node, 0); if (!cprman->osc_name) return -ENODEV; + +From 0a5d83e549e1e230826d6b363d5c0d3998b44396 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Mon, 20 Feb 2017 20:01:16 +0100 +Subject: [PATCH 144/190] dmaengine: bcm2835: Fix cyclic DMA period splitting + +The code responsible for splitting periods into chunks that +can be handled by the DMA controller missed to update total_len, +the number of bytes processed in the current period, when there +are more chunks to follow. + +Therefore total_len was stuck at 0 and the code didn't work at all. +This resulted in a wrong control block layout and audio issues because +the cyclic DMA callback wasn't executing on period boundaries. + +Fix this by adding the missing total_len update. + +Signed-off-by: Matthias Reichl +Signed-off-by: Martin Sperl +Tested-by: Clive Messer +Reviewed-by: Eric Anholt +--- + drivers/dma/bcm2835-dma.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c +index 80d35f760b4a4a51e60c355a84d538bac3892a4d..599c218dc8a73172dd4bd4a058fc8f95a73f982f 100644 +--- a/drivers/dma/bcm2835-dma.c ++++ b/drivers/dma/bcm2835-dma.c +@@ -253,8 +253,11 @@ static void bcm2835_dma_create_cb_set_length( + */ + + /* have we filled in period_length yet? */ +- if (*total_len + control_block->length < period_len) ++ if (*total_len + control_block->length < period_len) { ++ /* update number of bytes in this period so far */ ++ *total_len += control_block->length; + return; ++ } + + /* calculate the length that remains to reach period_length */ + control_block->length = period_len - *total_len; + +From 75749184f36f67c4b6d9c93583c0becea7d2038c Mon Sep 17 00:00:00 2001 +From: Scott Ellis +Date: Thu, 23 Feb 2017 11:56:20 -0500 +Subject: [PATCH 145/190] config: Add ads1015 driver to config + +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index 59f58450f4f7932dbfe051d7431c227737902b37..33f5dfda12efc3022da80982e65df09b4cf7a52e 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -649,6 +649,7 @@ CONFIG_HWMON=m + CONFIG_SENSORS_LM75=m + CONFIG_SENSORS_SHT21=m + CONFIG_SENSORS_SHTC1=m ++CONFIG_SENSORS_ADS1015=m + CONFIG_SENSORS_INA2XX=m + CONFIG_THERMAL=y + CONFIG_THERMAL_BCM2835=y +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index 062a89f0e5fc723559ddc5739e19eb20c030f0f1..97b88dcbc1e6c5b165406222227157776b162801 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -643,6 +643,7 @@ CONFIG_HWMON=m + CONFIG_SENSORS_LM75=m + CONFIG_SENSORS_SHT21=m + CONFIG_SENSORS_SHTC1=m ++CONFIG_SENSORS_ADS1015=m + CONFIG_SENSORS_INA2XX=m + CONFIG_THERMAL=y + CONFIG_THERMAL_BCM2835=y + +From db06ff42b88a08a8454e5a9249337659467bf0be Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Fri, 27 Jan 2017 18:49:30 +0000 +Subject: [PATCH 146/190] config: add slcan kernel module + +See: https://github.com/raspberrypi/linux/issues/1819 +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index 33f5dfda12efc3022da80982e65df09b4cf7a52e..6d1e9c7f30d80d28bc12bae0ee40044b31237f85 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -358,6 +358,7 @@ CONFIG_BAYCOM_SER_HDX=m + CONFIG_YAM=m + CONFIG_CAN=m + CONFIG_CAN_VCAN=m ++CONFIG_CAN_SLCAN=m + CONFIG_CAN_MCP251X=m + CONFIG_IRDA=m + CONFIG_IRLAN=m +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index 97b88dcbc1e6c5b165406222227157776b162801..2cfa65bc83fd4b7e802f56965543a217e7d5ed5c 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -354,6 +354,7 @@ CONFIG_BAYCOM_SER_HDX=m + CONFIG_YAM=m + CONFIG_CAN=m + CONFIG_CAN_VCAN=m ++CONFIG_CAN_SLCAN=m + CONFIG_CAN_MCP251X=m + CONFIG_IRDA=m + CONFIG_IRLAN=m + +From 4c84efa8ef92c7f5b107b8c729207a408b37f658 Mon Sep 17 00:00:00 2001 +From: Miquel +Date: Fri, 24 Feb 2017 20:51:06 +0100 +Subject: [PATCH 147/190] sound: Support for Dion Audio LOCO-V2 DAC-AMP HAT + +Signed-off-by: Miquel Blauw +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 19 +++ + .../dts/overlays/dionaudio-loco-v2-overlay.dts | 49 ++++++++ + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + sound/soc/bcm/Kconfig | 7 ++ + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/dionaudio_loco-v2.c | 140 +++++++++++++++++++++ + 8 files changed, 220 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts + create mode 100644 sound/soc/bcm/dionaudio_loco-v2.c + +diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile +index 0a7d30cd573060964bb081ee6617d5b77a17b974..8856139d061472311b7cead0641b5645ef33caad 100644 +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -13,6 +13,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + bmp085_i2c-sensor.dtbo \ + dht11.dtbo \ + dionaudio-loco.dtbo \ ++ dionaudio-loco-v2.dtbo \ + dpi18.dtbo \ + dpi24.dtbo \ + dwc-otg.dtbo \ +diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README +index 46228fd324fc4c52eb0ba50316b4c02f8245bf04..c9845ba37018b821d7e5093e15a06721318b558f 100644 +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -308,6 +308,25 @@ Load: dtoverlay=dionaudio-loco + Params: + + ++Name: dionaudio-loco-v2 ++Info: Configures the Dion Audio LOCO-V2 DAC-AMP ++Load: dtoverlay=dionaudio-loco-v2,= ++Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec ++ Digital volume control. Enable with ++ "dtoverlay=hifiberry-dacplus,24db_digital_gain" ++ (The default behaviour is that the Digital ++ volume control is limited to a maximum of ++ 0dB. ie. it can attenuate but not provide ++ gain. For most users, this will be desired ++ as it will prevent clipping. By appending ++ the 24dB_digital_gain parameter, the Digital ++ volume control will allow up to 24dB of ++ gain. If this parameter is enabled, it is the ++ responsibility of the user to ensure that ++ the Digital volume control is set to a value ++ that does not result in clipping/distortion!) ++ ++ + Name: dpi18 + Info: Overlay for a generic 18-bit DPI display + This uses GPIOs 0-21 (so no I2C, uart etc.), and activates the output +diff --git a/arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts b/arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts +new file mode 100644 +index 0000000000000000000000000000000000000000..a1af93de30119734e8d14cbd454589d365a3ba10 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts +@@ -0,0 +1,49 @@ ++/* ++ * Definitions for Dion Audio LOCO-V2 DAC-AMP ++ * eg. dtoverlay=dionaudio-loco-v2 ++ * ++ * PCM5242 DAC (in software mode) and TPA3255 AMP. ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ frag0: __overlay__ { ++ compatible = "dionaudio,dionaudio-loco-v2"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pcm5122@4c { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm5122"; ++ reg = <0x4d>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ 24db_digital_gain = <&frag0>,"dionaudio,24db_digital_gain?"; ++ }; ++}; +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index 6d1e9c7f30d80d28bc12bae0ee40044b31237f85..c48df02efdf83a16ef97babc1353487dc2fcfb18 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -883,6 +883,7 @@ CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m + CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m + CONFIG_SND_DIGIDAC1_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m ++CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m + CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m + CONFIG_SND_PISOUND=m + CONFIG_SND_SOC_ADAU1701=m +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index 2cfa65bc83fd4b7e802f56965543a217e7d5ed5c..92e0536cb9d5a1fe0b7c16edae18d1b3e71e053b 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -877,6 +877,7 @@ CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m + CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m + CONFIG_SND_DIGIDAC1_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m ++CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m + CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m + CONFIG_SND_PISOUND=m + CONFIG_SND_SOC_ADAU1701=m +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index c0489e591b9b8c8da004ca9e300e97f1a21e5ce1..3e1ee13ef8ec31849e29e551026ba427f8e44fe6 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -134,6 +134,13 @@ config SND_BCM2708_SOC_DIONAUDIO_LOCO + help + Say Y or M if you want to add support for Dion Audio LOCO. + ++config SND_BCM2708_SOC_DIONAUDIO_LOCO_V2 ++ tristate "Support for Dion Audio LOCO-V2 DAC-AMP" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_PCM5122 ++ help ++ Say Y or M if you want to add support for Dion Audio LOCO-V2. ++ + config SND_BCM2708_SOC_ALLO_PIANO_DAC + tristate "Support for Allo Piano DAC" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index 84c2b20ce2e51b525797ee58de95734ee7847e15..4d8adf691021a974310589e92e599924811f22cb 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -25,6 +25,7 @@ snd-soc-raspidac3-objs := raspidac3.o + snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o + snd-soc-digidac1-soundcard-objs := digidac1-soundcard.o + snd-soc-dionaudio-loco-objs := dionaudio_loco.o ++snd-soc-dionaudio-loco-v2-objs := dionaudio_loco-v2.o + snd-soc-allo-piano-dac-objs := allo-piano-dac.o + snd-soc-pisound-objs := pisound.o + +@@ -44,5 +45,6 @@ obj-$(CONFIG_SND_BCM2708_SOC_RASPIDAC3) += snd-soc-raspidac3.o + obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o + obj-$(CONFIG_SND_DIGIDAC1_SOUNDCARD) += snd-soc-digidac1-soundcard.o + obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO) += snd-soc-dionaudio-loco.o ++obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2) += snd-soc-dionaudio-loco-v2.o + obj-$(CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC) += snd-soc-allo-piano-dac.o + obj-$(CONFIG_SND_PISOUND) += snd-soc-pisound.o +diff --git a/sound/soc/bcm/dionaudio_loco-v2.c b/sound/soc/bcm/dionaudio_loco-v2.c +new file mode 100644 +index 0000000000000000000000000000000000000000..a009c49477972a9832175d86f201b0357a08f7c0 +--- /dev/null ++++ b/sound/soc/bcm/dionaudio_loco-v2.c +@@ -0,0 +1,140 @@ ++/* ++ * ASoC Driver for Dion Audio LOCO-V2 DAC-AMP ++ * ++ * Author: Miquel Blauw ++ * Copyright 2017 ++ * ++ * Based on the software of the RPi-DAC writen by Florian Meier ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++static bool digital_gain_0db_limit = true; ++ ++static int snd_rpi_dionaudio_loco_v2_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ if (digital_gain_0db_limit) { ++ int ret; ++ struct snd_soc_card *card = rtd->card; ++ ++ ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207); ++ if (ret < 0) ++ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); ++ } ++ ++ return 0; ++} ++ ++static int snd_rpi_dionaudio_loco_v2_hw_params( ++ struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; ++ ++ unsigned int sample_bits = ++ snd_pcm_format_physical_width(params_format(params)); ++ ++ return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2); ++} ++ ++/* machine stream operations */ ++static struct snd_soc_ops snd_rpi_dionaudio_loco_v2_ops = { ++ .hw_params = snd_rpi_dionaudio_loco_v2_hw_params, ++}; ++ ++static struct snd_soc_dai_link snd_rpi_dionaudio_loco_v2_dai[] = { ++{ ++ .name = "DionAudio LOCO-V2", ++ .stream_name = "DionAudio LOCO-V2 DAC-AMP", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "pcm512x-hifi", ++ .platform_name = "bcm2708-i2s.0", ++ .codec_name = "pcm512x.1-004d", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS, ++ .ops = &snd_rpi_dionaudio_loco_v2_ops, ++ .init = snd_rpi_dionaudio_loco_v2_init, ++},}; ++ ++/* audio machine driver */ ++static struct snd_soc_card snd_rpi_dionaudio_loco_v2 = { ++ .name = "Dion Audio LOCO-V2", ++ .dai_link = snd_rpi_dionaudio_loco_v2_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_dionaudio_loco_v2_dai), ++}; ++ ++static int snd_rpi_dionaudio_loco_v2_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ snd_rpi_dionaudio_loco_v2.dev = &pdev->dev; ++ ++ if (pdev->dev.of_node) { ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai = ++ &snd_rpi_dionaudio_loco_v2_dai[0]; ++ ++ i2s_node = of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ if (i2s_node) { ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = i2s_node; ++ dai->platform_name = NULL; ++ dai->platform_of_node = i2s_node; ++ } ++ ++ digital_gain_0db_limit = !of_property_read_bool( ++ pdev->dev.of_node, "dionaudio,24db_digital_gain"); ++ } ++ ++ ret = snd_soc_register_card(&snd_rpi_dionaudio_loco_v2); ++ if (ret) ++ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ++ ret); ++ ++ return ret; ++} ++ ++static int snd_rpi_dionaudio_loco_v2_remove(struct platform_device *pdev) ++{ ++ return snd_soc_unregister_card(&snd_rpi_dionaudio_loco_v2); ++} ++ ++static const struct of_device_id dionaudio_of_match[] = { ++ { .compatible = "dionaudio,dionaudio-loco-v2", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, dionaudio_of_match); ++ ++static struct platform_driver snd_rpi_dionaudio_loco_v2_driver = { ++ .driver = { ++ .name = "snd-rpi-dionaudio-loco-v2", ++ .owner = THIS_MODULE, ++ .of_match_table = dionaudio_of_match, ++ }, ++ .probe = snd_rpi_dionaudio_loco_v2_probe, ++ .remove = snd_rpi_dionaudio_loco_v2_remove, ++}; ++ ++module_platform_driver(snd_rpi_dionaudio_loco_v2_driver); ++ ++MODULE_AUTHOR("Miquel Blauw "); ++MODULE_DESCRIPTION("ASoC Driver for DionAudio LOCO-V2"); ++MODULE_LICENSE("GPL v2"); + +From 560b3f18f12a55269d5e82c60fbb620ab2e9490c Mon Sep 17 00:00:00 2001 +From: Fe-Pi +Date: Wed, 1 Mar 2017 04:42:43 -0700 +Subject: [PATCH 148/190] Add support for Fe-Pi audio sound card. (#1867) + +Fe-Pi Audio Sound Card is based on NXP SGTL5000 codec. +Mechanical specification of the board is the same the Raspberry Pi Zero. +3.5mm jacks for Headphone/Mic, Line In, and Line Out. + +Signed-off-by: Henry Kupis +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 6 + + arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts | 70 +++++++++ + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + sound/soc/bcm/Kconfig | 7 + + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/fe-pi-audio.c | 158 +++++++++++++++++++++ + 8 files changed, 246 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts + create mode 100644 sound/soc/bcm/fe-pi-audio.c + +diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile +index 8856139d061472311b7cead0641b5645ef33caad..c8825365a4129b0098abf2002e1dcd936ea1ec8c 100644 +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -20,6 +20,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + dwc2.dtbo \ + enc28j60.dtbo \ + enc28j60-spi2.dtbo \ ++ fe-pi-audio.dtbo \ + gpio-ir.dtbo \ + gpio-poweroff.dtbo \ + hifiberry-amp.dtbo \ +diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README +index c9845ba37018b821d7e5093e15a06721318b558f..788e9e3b23f37d4c44b94b60ff2b72e2f0dbeeac 100644 +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -383,6 +383,12 @@ Params: int_pin GPIO used for INT (default 39) + speed SPI bus speed (default 12000000) + + ++Name: fe-pi-audio ++Info: Configures the Fe-Pi Audio Sound Card ++Load: dtoverlay=fe-pi-audio ++Params: ++ ++ + Name: gpio-ir + Info: Use GPIO pin as rc-core style infrared receiver input. The rc-core- + based gpio_ir_recv driver maps received keys directly to a +diff --git a/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts b/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts +new file mode 100644 +index 0000000000000000000000000000000000000000..81a07ed5a8c7594e65f0df2176418cac57a7910c +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts +@@ -0,0 +1,70 @@ ++// Definitions for Fe-Pi Audio ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&clocks>; ++ __overlay__ { ++ sgtl5000_mclk: sgtl5000_mclk { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <12288000>; ++ clock-output-names = "sgtl5000-mclk"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&soc>; ++ __overlay__ { ++ reg_1v8: reg_1v8@0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "1V8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ sgtl5000@0a { ++ #sound-dai-cells = <0>; ++ compatible = "fepi,sgtl5000"; ++ reg = <0x0a>; ++ clocks = <&sgtl5000_mclk>; ++ micbias-resistor-k-ohms = <2>; ++ micbias-voltage-m-volts = <3000>; ++ VDDA-supply = <&vdd_3v3_reg>; ++ VDDIO-supply = <&vdd_3v3_reg>; ++ VDDD-supply = <®_1v8>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "fe-pi,fe-pi-audio"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index c48df02efdf83a16ef97babc1353487dc2fcfb18..4ca09cf1e4e19154868b576eb3827b85789b6caf 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -885,6 +885,7 @@ CONFIG_SND_DIGIDAC1_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m + CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m ++CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m + CONFIG_SND_PISOUND=m + CONFIG_SND_SOC_ADAU1701=m + CONFIG_SND_SOC_ADAU7002=m +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index 92e0536cb9d5a1fe0b7c16edae18d1b3e71e053b..a9c46f902eb32b364423d8bef07b6b37f798c617 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -879,6 +879,7 @@ CONFIG_SND_DIGIDAC1_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m + CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m ++CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m + CONFIG_SND_PISOUND=m + CONFIG_SND_SOC_ADAU1701=m + CONFIG_SND_SOC_ADAU7002=m +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index 3e1ee13ef8ec31849e29e551026ba427f8e44fe6..7473efd6f400a1a1618aac830753fce39d203b89 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -148,6 +148,13 @@ config SND_BCM2708_SOC_ALLO_PIANO_DAC + help + Say Y or M if you want to add support for Allo Piano DAC. + ++config SND_BCM2708_SOC_FE_PI_AUDIO ++ tristate "Support for Fe-Pi-Audio" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_SGTL5000 ++ help ++ Say Y or M if you want to add support for Fe-Pi-Audio. ++ + config SND_PISOUND + tristate "Support for Blokas Labs pisound" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index 4d8adf691021a974310589e92e599924811f22cb..8d2d2073dc2cede9fbd9eb8b49083650ba0a8172 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -28,6 +28,7 @@ snd-soc-dionaudio-loco-objs := dionaudio_loco.o + snd-soc-dionaudio-loco-v2-objs := dionaudio_loco-v2.o + snd-soc-allo-piano-dac-objs := allo-piano-dac.o + snd-soc-pisound-objs := pisound.o ++snd-soc-fe-pi-audio-objs := fe-pi-audio.o + + obj-$(CONFIG_SND_BCM2708_SOC_ADAU1977_ADC) += snd-soc-adau1977-adc.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o +@@ -48,3 +49,4 @@ obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO) += snd-soc-dionaudio-loco.o + obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2) += snd-soc-dionaudio-loco-v2.o + obj-$(CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC) += snd-soc-allo-piano-dac.o + obj-$(CONFIG_SND_PISOUND) += snd-soc-pisound.o ++obj-$(CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO) += snd-soc-fe-pi-audio.o +diff --git a/sound/soc/bcm/fe-pi-audio.c b/sound/soc/bcm/fe-pi-audio.c +new file mode 100644 +index 0000000000000000000000000000000000000000..015b56fd73cc36be5b5eecd17548fd036eb64d61 +--- /dev/null ++++ b/sound/soc/bcm/fe-pi-audio.c +@@ -0,0 +1,158 @@ ++/* ++ * ASoC Driver for Fe-Pi Audio Sound Card ++ * ++ * Author: Henry Kupis ++ * Copyright 2016 ++ * based on code by Florian Meier ++ * based on code by Shawn Guo ++ * ++ * 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 "../codecs/sgtl5000.h" ++ ++static int snd_fe_pi_audio_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ struct snd_soc_card *card = rtd->card; ++ struct snd_soc_codec *codec = rtd->codec; ++ ++ snd_soc_dapm_force_enable_pin(&card->dapm, "LO"); ++ snd_soc_dapm_force_enable_pin(&card->dapm, "ADC"); ++ snd_soc_dapm_force_enable_pin(&card->dapm, "DAC"); ++ snd_soc_dapm_force_enable_pin(&card->dapm, "HP"); ++ snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, ++ SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP); ++ ++ return 0; ++} ++ ++static int snd_fe_pi_audio_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct device *dev = rtd->card->dev; ++ struct snd_soc_dai *codec_dai = rtd->codec_dai; ++ ++ int ret; ++ ++ /* Set SGTL5000's SYSCLK */ ++ ret = snd_soc_dai_set_sysclk(codec_dai, SGTL5000_SYSCLK, 12288000, SND_SOC_CLOCK_IN); ++ if (ret) { ++ dev_err(dev, "could not set codec driver clock params\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++ ++static struct snd_soc_ops snd_fe_pi_audio_ops = { ++ .hw_params = snd_fe_pi_audio_hw_params, ++}; ++ ++static struct snd_soc_dai_link snd_fe_pi_audio_dai[] = { ++ { ++ .name = "FE-PI", ++ .stream_name = "Fe-Pi HiFi", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "sgtl5000", ++ .platform_name = "bcm2708-i2s.0", ++ .codec_name = "sgtl5000.1-000a", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBM_CFM, ++ .ops = &snd_fe_pi_audio_ops, ++ .init = snd_fe_pi_audio_init, ++ }, ++}; ++ ++static const struct snd_soc_dapm_route fe_pi_audio_dapm_routes[] = { ++ {"ADC", NULL, "Mic Bias"}, ++}; ++ ++ ++static struct snd_soc_card fe_pi_audio = { ++ .name = "Fe-Pi Audio", ++ .owner = THIS_MODULE, ++ .dai_link = snd_fe_pi_audio_dai, ++ .num_links = ARRAY_SIZE(snd_fe_pi_audio_dai), ++ ++ .dapm_routes = fe_pi_audio_dapm_routes, ++ .num_dapm_routes = ARRAY_SIZE(fe_pi_audio_dapm_routes), ++}; ++ ++static int snd_fe_pi_audio_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ struct snd_soc_card *card = &fe_pi_audio; ++ struct device_node *np = pdev->dev.of_node; ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai = &snd_fe_pi_audio_dai[0]; ++ ++ fe_pi_audio.dev = &pdev->dev; ++ ++ i2s_node = of_parse_phandle(np, "i2s-controller", 0); ++ if (!i2s_node) { ++ dev_err(&pdev->dev, "i2s_node phandle missing or invalid\n"); ++ return -EINVAL; ++ } ++ ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = i2s_node; ++ dai->platform_name = NULL; ++ dai->platform_of_node = i2s_node; ++ ++ of_node_put(i2s_node); ++ ++ card->dev = &pdev->dev; ++ platform_set_drvdata(pdev, card); ++ ++ ret = snd_soc_register_card(card); ++ if (ret && ret != -EPROBE_DEFER) ++ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); ++ ++ return ret; ++} ++ ++static int snd_fe_pi_audio_remove(struct platform_device *pdev) ++{ ++ return snd_soc_unregister_card(&fe_pi_audio); ++} ++ ++static const struct of_device_id snd_fe_pi_audio_of_match[] = { ++ { .compatible = "fe-pi,fe-pi-audio", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, snd_fe_pi_audio_of_match); ++ ++static struct platform_driver snd_fe_pi_audio_driver = { ++ .driver = { ++ .name = "snd-fe-pi-audio", ++ .owner = THIS_MODULE, ++ .of_match_table = snd_fe_pi_audio_of_match, ++ }, ++ .probe = snd_fe_pi_audio_probe, ++ .remove = snd_fe_pi_audio_remove, ++}; ++ ++module_platform_driver(snd_fe_pi_audio_driver); ++ ++MODULE_AUTHOR("Henry Kupis "); ++MODULE_DESCRIPTION("ASoC Driver for Fe-Pi Audio"); ++MODULE_LICENSE("GPL v2"); + +From d766ce62f73494e2390e6d81c7e207db38bec90f Mon Sep 17 00:00:00 2001 +From: Scott Ellis +Date: Wed, 1 Mar 2017 07:22:24 -0500 +Subject: [PATCH 149/190] Add overlay for ads1115 ADCs (#1864) + +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 22 ++++++ + arch/arm/boot/dts/overlays/ads1115-overlay.dts | 103 +++++++++++++++++++++++++ + 3 files changed, 126 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/ads1115-overlay.dts + +diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile +index c8825365a4129b0098abf2002e1dcd936ea1ec8c..c890e5ddb0e2eec982597a851023b539d318d6ce 100644 +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -4,6 +4,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + adau1977-adc.dtbo \ + adau7002-simple.dtbo \ + ads1015.dtbo \ ++ ads1115.dtbo \ + ads7846.dtbo \ + akkordion-iqdacplus.dtbo \ + allo-piano-dac-pcm512x-audio.dtbo \ +diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README +index 788e9e3b23f37d4c44b94b60ff2b72e2f0dbeeac..970c9c9b5c74467a3014a77039fa765d8f8c4e6f 100644 +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -196,6 +196,28 @@ Params: addr I2C bus address of device. Set based on how the + http://www.ti.com/lit/ds/symlink/ads1015.pdf + + ++Name: ads1115 ++Info: Texas Instruments ADS1115 ADC ++Load: dtoverlay=ads1115,[=] ++Params: addr I2C bus address of device. Set based on how the ++ addr pin is wired. (default=0x48 assumes addr ++ is pulled to GND) ++ cha_enable Enable virtual channel a. ++ cha_cfg Set the configuration for virtual channel a. ++ (default=4 configures this channel for the ++ voltage at A0 with respect to GND) ++ cha_datarate Set the datarate (samples/sec) for this channel. ++ (default=7 sets 860 sps) ++ cha_gain Set the gain of the Programmable Gain ++ Amplifier for this channel. (Default 1 sets the ++ full scale of the channel to 4.096 Volts) ++ ++ Channel parameters can be set for each enabled channel. ++ A maximum of 4 channels can be enabled (letters a thru d). ++ For more information refer to the device datasheet at: ++ http://www.ti.com/lit/ds/symlink/ads1115.pdf ++ ++ + Name: ads7846 + Info: ADS7846 Touch controller + Load: dtoverlay=ads7846,= +diff --git a/arch/arm/boot/dts/overlays/ads1115-overlay.dts b/arch/arm/boot/dts/overlays/ads1115-overlay.dts +new file mode 100644 +index 0000000000000000000000000000000000000000..7c16a1af3172d14e1a976b1776b9f1677278beed +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/ads1115-overlay.dts +@@ -0,0 +1,103 @@ ++/* ++ * TI ADS1115 multi-channel ADC overlay ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&i2c_arm>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ ads1115: ads1115 { ++ compatible = "ti,ads1115"; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0x48>; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "i2c_arm/ads1115"; ++ __dormant__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ channel_a: channel_a { ++ reg = <4>; ++ ti,gain = <1>; ++ ti,datarate = <7>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target-path = "i2c_arm/ads1115"; ++ __dormant__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ channel_b: channel_b { ++ reg = <5>; ++ ti,gain = <1>; ++ ti,datarate = <7>; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target-path = "i2c_arm/ads1115"; ++ __dormant__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ channel_c: channel_c { ++ reg = <6>; ++ ti,gain = <1>; ++ ti,datarate = <7>; ++ }; ++ }; ++ }; ++ ++ fragment@4 { ++ target-path = "i2c_arm/ads1115"; ++ __dormant__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ channel_d: channel_d { ++ reg = <7>; ++ ti,gain = <1>; ++ ti,datarate = <7>; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ addr = <&ads1115>,"reg:0"; ++ cha_enable = <0>,"=1"; ++ cha_cfg = <&channel_a>,"reg:0"; ++ cha_gain = <&channel_a>,"ti,gain:0"; ++ cha_datarate = <&channel_a>,"ti,datarate:0"; ++ chb_enable = <0>,"=2"; ++ chb_cfg = <&channel_b>,"reg:0"; ++ chb_gain = <&channel_b>,"ti,gain:0"; ++ chb_datarate = <&channel_b>,"ti,datarate:0"; ++ chc_enable = <0>,"=3"; ++ chc_cfg = <&channel_c>,"reg:0"; ++ chc_gain = <&channel_c>,"ti,gain:0"; ++ chc_datarate = <&channel_c>,"ti,datarate:0"; ++ chd_enable = <0>,"=4"; ++ chd_cfg = <&channel_d>,"reg:0"; ++ chd_gain = <&channel_d>,"ti,gain:0"; ++ chd_datarate = <&channel_d>,"ti,datarate:0"; ++ }; ++}; + +From 21dc54ba0a1b0864c414fec7c6ebf0e915f7765d Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 1 Mar 2017 16:06:53 +0000 +Subject: [PATCH 150/190] clk-bcm2835: Correct the prediv logic + +If a clock has the prediv flag set, both the integer and fractional +parts must be scaled when calculating the resulting frequency. + +Signed-off-by: Phil Elwell +--- + drivers/clk/bcm/clk-bcm2835.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index 0b62d20f8b718cfd03c0346af784688e26e9dcb6..ef0d05c58573f62de3632a920dfc19888c019d18 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -535,8 +535,10 @@ static unsigned long bcm2835_pll_get_rate(struct clk_hw *hw, + using_prediv = cprman_read(cprman, data->ana_reg_base + 4) & + data->ana->fb_prediv_mask; + +- if (using_prediv) ++ if (using_prediv) { + ndiv *= 2; ++ fdiv *= 2; ++ } + + return bcm2835_pll_rate_from_divisors(parent_rate, ndiv, fdiv, pdiv); + } + +From 1a01a08453ac677150039e7b4706ebc67b703bf1 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 1 Mar 2017 16:07:39 +0000 +Subject: [PATCH 151/190] amba_pl011: Round input clock up + +The UART clock is initialised to be as close to the requested +frequency as possible without exceeding it. Now that there is a +clock manager that returns the actual frequencies, an expected +48MHz clock is reported as 47999625. If the requested baudrate +== requested clock/16, there is no headroom and the slight +reduction in actual clock rate results in failure. + +Detect cases where it looks like a "round" clock was chosen and +adjust the reported clock to match that "round" value. As the +code comment says: + +/* + * If increasing a clock by less than 0.1% changes it + * from ..999.. to ..000.., round up. + */ + +Signed-off-by: Phil Elwell +--- + drivers/tty/serial/amba-pl011.c | 23 +++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c +index 6beb6233a0b6132b933cf8d85d8501dc1ce2fe4c..50792f9fa8fc530e2ecbc90f92adb11bada79cb2 100644 +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -1646,6 +1646,23 @@ static void pl011_put_poll_char(struct uart_port *port, + + #endif /* CONFIG_CONSOLE_POLL */ + ++unsigned long pl011_clk_round(unsigned long clk) ++{ ++ unsigned long scaler; ++ ++ /* ++ * If increasing a clock by less than 0.1% changes it ++ * from ..999.. to ..000.., round up. ++ */ ++ scaler = 1; ++ while (scaler * 100000 < clk) ++ scaler *= 10; ++ if ((clk + scaler - 1)/scaler % 1000 == 0) ++ clk = (clk/scaler + 1) * scaler; ++ ++ return clk; ++} ++ + static int pl011_hwinit(struct uart_port *port) + { + struct uart_amba_port *uap = +@@ -1662,7 +1679,7 @@ static int pl011_hwinit(struct uart_port *port) + if (retval) + return retval; + +- uap->port.uartclk = clk_get_rate(uap->clk); ++ uap->port.uartclk = pl011_clk_round(clk_get_rate(uap->clk)); + + /* Clear pending error and receive interrupts */ + pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS | +@@ -2300,7 +2317,7 @@ static int __init pl011_console_setup(struct console *co, char *options) + plat->init(); + } + +- uap->port.uartclk = clk_get_rate(uap->clk); ++ uap->port.uartclk = pl011_clk_round(clk_get_rate(uap->clk)); + + if (uap->vendor->fixed_options) { + baud = uap->fixed_baud; +@@ -2428,6 +2445,7 @@ static struct uart_driver amba_reg = { + .cons = AMBA_CONSOLE, + }; + ++#if 0 + static int pl011_probe_dt_alias(int index, struct device *dev) + { + struct device_node *np; +@@ -2459,6 +2477,7 @@ static int pl011_probe_dt_alias(int index, struct device *dev) + + return ret; + } ++#endif + + /* unregisters the driver also if no more ports are left */ + static void pl011_unregister_port(struct uart_amba_port *uap) + +From 5fae662f7139c34f8b49dbf761628d877ffc3c96 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 13 Feb 2017 11:10:50 +0000 +Subject: [PATCH 152/190] BCM2835-V4L2: Ensure H264 header bytes get a sensible + timestamp + +H264 header come off VC with 0 timestamps, which means they get a +strange timestamp when processed with VC/kernel start times, +particularly if used with the inline header option. +Remember the last frame timestamp and use that if set, or otherwise +use the kernel start time. + +https://github.com/raspberrypi/linux/issues/1836 + +Signed-off-by: Dave Stevenson +--- + drivers/media/platform/bcm2835/bcm2835-camera.c | 30 ++++++++++++++++++++++--- + drivers/media/platform/bcm2835/bcm2835-camera.h | 2 ++ + 2 files changed, 29 insertions(+), 3 deletions(-) + +diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.c b/drivers/media/platform/bcm2835/bcm2835-camera.c +index 4f03949aecf3afbf2e04df38289447195a8847a6..e69731320f4e59249933bc21843913deab4a1209 100644 +--- a/drivers/media/platform/bcm2835/bcm2835-camera.c ++++ b/drivers/media/platform/bcm2835/bcm2835-camera.c +@@ -356,8 +356,13 @@ static void buffer_cb(struct vchiq_mmal_instance *instance, + } + } else { + if (dev->capture.frame_count) { +- if (dev->capture.vc_start_timestamp != -1 && +- pts != 0) { ++ if (dev->capture.vc_start_timestamp == -1) { ++ buf->vb.vb2_buf.timestamp = ktime_get_ns(); ++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, ++ "Buffer time set as current time - %lld", ++ buf->vb.vb2_buf.timestamp); ++ ++ } else if(pts != 0) { + struct timeval timestamp; + s64 runtime_us = pts - + dev->capture.vc_start_timestamp; +@@ -390,10 +395,27 @@ static void buffer_cb(struct vchiq_mmal_instance *instance, + buf->vb.vb2_buf.timestamp = timestamp.tv_sec * 1000000000ULL + + timestamp.tv_usec * 1000ULL; + } else { +- buf->vb.vb2_buf.timestamp = ktime_get_ns(); ++ if (dev->capture.last_timestamp) { ++ buf->vb.vb2_buf.timestamp = dev->capture.last_timestamp; ++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, ++ "Buffer time set as last timestamp - %lld", ++ buf->vb.vb2_buf.timestamp); ++ } ++ else { ++ buf->vb.vb2_buf.timestamp = ++ dev->capture.kernel_start_ts.tv_sec * 1000000000ULL + ++ dev->capture.kernel_start_ts.tv_usec * 1000ULL; ++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, ++ "Buffer time set as start timestamp - %lld", ++ buf->vb.vb2_buf.timestamp); ++ } + } ++ dev->capture.last_timestamp = buf->vb.vb2_buf.timestamp; + + vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length); ++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, ++ "Buffer has ts %llu", ++ dev->capture.last_timestamp); + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + + if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS && +@@ -559,6 +581,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) + "Start time %lld size %d\n", + dev->capture.vc_start_timestamp, parameter_size); + ++ dev->capture.last_timestamp = 0; ++ + v4l2_get_timestamp(&dev->capture.kernel_start_ts); + + /* enable the camera port */ +diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.h b/drivers/media/platform/bcm2835/bcm2835-camera.h +index e6aeb7e7e381de65d6c6586205069a4c5cd33274..7f8a68916a67001bc9241bce2928519a2ce1ba78 100644 +--- a/drivers/media/platform/bcm2835/bcm2835-camera.h ++++ b/drivers/media/platform/bcm2835/bcm2835-camera.h +@@ -93,6 +93,8 @@ struct bm2835_mmal_dev { + s64 vc_start_timestamp; + /* Kernel start timestamp for streaming */ + struct timeval kernel_start_ts; ++ /* Timestamp of last frame */ ++ u64 last_timestamp; + + struct vchiq_mmal_port *port; /* port being used for capture */ + /* camera port being used for capture */ + +From 02a146929141f8f6cf60ec15854cbb7e79ad828e Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 13 Feb 2017 13:11:41 +0000 +Subject: [PATCH 153/190] BCM2835-V4L2: Correctly denote key frames in encoded + data + +Forward MMAL key frame flags to the V4L2 buffers. + +Signed-off-by: Dave Stevenson +--- + drivers/media/platform/bcm2835/bcm2835-camera.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.c b/drivers/media/platform/bcm2835/bcm2835-camera.c +index e69731320f4e59249933bc21843913deab4a1209..6bdec0806126044cf7146d53326e4da5b4269884 100644 +--- a/drivers/media/platform/bcm2835/bcm2835-camera.c ++++ b/drivers/media/platform/bcm2835/bcm2835-camera.c +@@ -413,6 +413,9 @@ static void buffer_cb(struct vchiq_mmal_instance *instance, + dev->capture.last_timestamp = buf->vb.vb2_buf.timestamp; + + vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length); ++ if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) ++ buf->vb.flags |= V4L2_BUF_FLAG_KEYFRAME; ++ + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Buffer has ts %llu", + dev->capture.last_timestamp); + +From 0caafb8487b1d9cb832d0d6f1be171615eb58d62 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 20 Feb 2017 17:01:21 +0000 +Subject: [PATCH 154/190] bcm2835-gpio-exp: Driver for GPIO expander via + mailbox service + +Pi3 and Compute Module 3 have a GPIO expander that the +VPU communicates with. +There is a mailbox service that now allows control of this +expander, so add a kernel driver that can make use of it. + +Pwr_led node added to device-tree for Pi3. + +Signed-off-by: Dave Stevenson +--- + arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 22 +++ + arch/arm/boot/dts/bcm2710-rpi-cm3.dts | 10 +- + arch/arm/configs/bcm2709_defconfig | 1 + + drivers/gpio/Kconfig | 7 + + drivers/gpio/Makefile | 1 + + drivers/gpio/gpio-bcm-exp.c | 256 +++++++++++++++++++++++++++++ + include/soc/bcm2835/raspberrypi-firmware.h | 4 + + 7 files changed, 300 insertions(+), 1 deletion(-) + create mode 100644 drivers/gpio/gpio-bcm-exp.c + +diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +index 2a5b512d3e1acb17c6a40bf9d370f22279c4d552..616cfd5c7094596b497101e8feca25e25e77c3e8 100644 +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +@@ -96,6 +96,14 @@ + firmware = <&firmware>; + status = "okay"; + }; ++ ++ expgpio: expgpio { ++ compatible = "brcm,bcm2835-expgpio"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ firmware = <&firmware>; ++ status = "okay"; ++ }; + }; + + &fb { +@@ -163,6 +171,16 @@ + linux,default-trigger = "mmc0"; + gpios = <&virtgpio 0 0>; + }; ++ ++ pwr_led: pwr { ++ label = "led1"; ++ linux,default-trigger = "input"; ++ gpios = <&expgpio 7 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&hdmi { ++ hpd-gpios = <&expgpio 4 GPIO_ACTIVE_LOW>; + }; + + &audio { +@@ -193,6 +211,10 @@ + act_led_activelow = <&act_led>,"gpios:8"; + act_led_trigger = <&act_led>,"linux,default-trigger"; + ++ pwr_led_gpio = <&pwr_led>,"gpios:4"; ++ pwr_led_activelow = <&pwr_led>,"gpios:8"; ++ pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; ++ + audio = <&audio>,"status"; + watchdog = <&watchdog>,"status"; + random = <&random>,"status"; +diff --git a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts +index 3ba6e621856c288ae4694f758604619f59064fdb..fe402e84cdda884583336422289ac8b3cc12fb28 100644 +--- a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts +@@ -65,6 +65,14 @@ + firmware = <&firmware>; + status = "okay"; + }; ++ ++ expgpio: expgpio { ++ compatible = "brcm,bcm2835-expgpio"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ firmware = <&firmware>; ++ status = "okay"; ++ }; + }; + + &fb { +@@ -123,7 +131,7 @@ + }; + + &hdmi { +- hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; ++ hpd-gpios = <&expgpio 0 GPIO_ACTIVE_LOW>; + }; + + &audio { +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index 4ca09cf1e4e19154868b576eb3827b85789b6caf..0ee1ff698a5571f80da89a1067025b32fe546136 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -621,6 +621,7 @@ CONFIG_PPS=m + CONFIG_PPS_CLIENT_LDISC=m + CONFIG_PPS_CLIENT_GPIO=m + CONFIG_GPIO_SYSFS=y ++CONFIG_GPIO_BCM_EXP=y + CONFIG_GPIO_BCM_VIRT=y + CONFIG_GPIO_ARIZONA=m + CONFIG_GPIO_STMPE=y +diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig +index ade9f7dd8f973fd44031a0a6d42c28f01b424d1b..a6a8caa2c803c4c4a119d5d4b6d0acd2d9f2083c 100644 +--- a/drivers/gpio/Kconfig ++++ b/drivers/gpio/Kconfig +@@ -128,6 +128,13 @@ config GPIO_AXP209 + help + Say yes to enable GPIO support for the AXP209 PMIC + ++config GPIO_BCM_EXP ++ bool "Broadcom Exp GPIO" ++ depends on OF_GPIO && RASPBERRYPI_FIRMWARE && (ARCH_BCM2835 || COMPILE_TEST) ++ help ++ Turn on GPIO support for Broadcom chips using the firmware mailbox ++ to communicate with VideoCore on BCM283x chips. ++ + config GPIO_BCM_KONA + bool "Broadcom Kona GPIO" + depends on OF_GPIO && (ARCH_BCM_MOBILE || COMPILE_TEST) +diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile +index dec0669a5f030023288047f2abe68b0f2e0946d7..73392801474433668c05442dc391af91b262b76e 100644 +--- a/drivers/gpio/Makefile ++++ b/drivers/gpio/Makefile +@@ -32,6 +32,7 @@ obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o + obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o + obj-$(CONFIG_GPIO_ASPEED) += gpio-aspeed.o + obj-$(CONFIG_GPIO_AXP209) += gpio-axp209.o ++obj-$(CONFIG_GPIO_BCM_EXP) += gpio-bcm-exp.o + obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o + obj-$(CONFIG_GPIO_BCM_VIRT) += gpio-bcm-virt.o + obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o +diff --git a/drivers/gpio/gpio-bcm-exp.c b/drivers/gpio/gpio-bcm-exp.c +new file mode 100644 +index 0000000000000000000000000000000000000000..681a91492d4c33bdfd42416e069218e8611cc4d9 +--- /dev/null ++++ b/drivers/gpio/gpio-bcm-exp.c +@@ -0,0 +1,256 @@ ++/* ++ * Broadcom expander GPIO driver ++ * ++ * Uses the firmware mailbox service to communicate with the ++ * GPIO expander on the VPU. ++ * ++ * Copyright (C) 2017 Raspberry Pi Trading Ltd. ++ * ++ * Author: Dave Stevenson ++ * Based on gpio-bcm-virt.c by Dom Cobley ++ * ++ * 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 ++ ++#define MODULE_NAME "brcmexp-gpio" ++#define NUM_GPIO 8 ++ ++struct brcmexp_gpio { ++ struct gpio_chip gc; ++ struct device *dev; ++ struct rpi_firmware *fw; ++}; ++ ++struct gpio_set_config { ++ u32 gpio, direction, polarity, term_en, term_pull_up, state; ++}; ++ ++struct gpio_get_config { ++ u32 gpio, direction, polarity, term_en, term_pull_up; ++}; ++ ++struct gpio_get_set_state { ++ u32 gpio, state; ++}; ++ ++static int brcmexp_gpio_get_polarity(struct gpio_chip *gc, unsigned int off) ++{ ++ struct brcmexp_gpio *gpio; ++ struct gpio_get_config get; ++ int ret; ++ ++ gpio = container_of(gc, struct brcmexp_gpio, gc); ++ ++ get.gpio = off + gpio->gc.base; /* GPIO to update */ ++ ++ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG, ++ &get, sizeof(get)); ++ if (ret) { ++ dev_err(gpio->dev, ++ "Failed to get GPIO %u config (%d)\n", off, ret); ++ return ret; ++ } ++ return get.polarity; ++} ++ ++static int brcmexp_gpio_dir_in(struct gpio_chip *gc, unsigned int off) ++{ ++ struct brcmexp_gpio *gpio; ++ struct gpio_set_config set_in; ++ int ret; ++ ++ gpio = container_of(gc, struct brcmexp_gpio, gc); ++ ++ set_in.gpio = off + gpio->gc.base; /* GPIO to update */ ++ set_in.direction = 0; /* Input */ ++ set_in.polarity = brcmexp_gpio_get_polarity(gc, off); ++ /* Retain existing setting */ ++ set_in.term_en = 0; /* termination disabled */ ++ set_in.term_pull_up = 0; /* n/a as termination disabled */ ++ set_in.state = 0; /* n/a as configured as an input */ ++ ++ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG, ++ &set_in, sizeof(set_in)); ++ if (ret) { ++ dev_err(gpio->dev, ++ "Failed to set GPIO %u to input (%d)\n", ++ off, ret); ++ return ret; ++ } ++ return 0; ++} ++ ++static int brcmexp_gpio_dir_out(struct gpio_chip *gc, unsigned int off, int val) ++{ ++ struct brcmexp_gpio *gpio; ++ struct gpio_set_config set_out; ++ int ret; ++ ++ gpio = container_of(gc, struct brcmexp_gpio, gc); ++ ++ set_out.gpio = off + gpio->gc.base; /* GPIO to update */ ++ set_out.direction = 1; /* Output */ ++ set_out.polarity = brcmexp_gpio_get_polarity(gc, off); ++ /* Retain existing setting */ ++ set_out.term_en = 0; /* n/a as an output */ ++ set_out.term_pull_up = 0; /* n/a as termination disabled */ ++ set_out.state = val; /* Output state */ ++ ++ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG, ++ &set_out, sizeof(set_out)); ++ if (ret) { ++ dev_err(gpio->dev, ++ "Failed to set GPIO %u to output (%d)\n", off, ret); ++ return ret; ++ } ++ return 0; ++} ++ ++static int brcmexp_gpio_get_direction(struct gpio_chip *gc, unsigned int off) ++{ ++ struct brcmexp_gpio *gpio; ++ struct gpio_get_config get; ++ int ret; ++ ++ gpio = container_of(gc, struct brcmexp_gpio, gc); ++ ++ get.gpio = off + gpio->gc.base; /* GPIO to update */ ++ ++ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG, ++ &get, sizeof(get)); ++ if (ret) { ++ dev_err(gpio->dev, ++ "Failed to get GPIO %u config (%d)\n", off, ret); ++ return ret; ++ } ++ return get.direction ? GPIOF_DIR_OUT : GPIOF_DIR_IN; ++} ++ ++static int brcmexp_gpio_get(struct gpio_chip *gc, unsigned int off) ++{ ++ struct brcmexp_gpio *gpio; ++ struct gpio_get_set_state get; ++ int ret; ++ ++ gpio = container_of(gc, struct brcmexp_gpio, gc); ++ ++ get.gpio = off + gpio->gc.base; /* GPIO to update */ ++ get.state = 0; /* storage for returned value */ ++ ++ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_STATE, ++ &get, sizeof(get)); ++ if (ret) { ++ dev_err(gpio->dev, ++ "Failed to get GPIO %u state (%d)\n", off, ret); ++ return ret; ++ } ++ return !!get.state; ++} ++ ++static void brcmexp_gpio_set(struct gpio_chip *gc, unsigned int off, int val) ++{ ++ struct brcmexp_gpio *gpio; ++ struct gpio_get_set_state set; ++ int ret; ++ ++ gpio = container_of(gc, struct brcmexp_gpio, gc); ++ ++ off += gpio->gc.base; ++ ++ set.gpio = off + gpio->gc.base; /* GPIO to update */ ++ set.state = val; /* Output state */ ++ ++ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_STATE, ++ &set, sizeof(set)); ++ if (ret) ++ dev_err(gpio->dev, ++ "Failed to set GPIO %u state (%d)\n", off, ret); ++} ++ ++static int brcmexp_gpio_probe(struct platform_device *pdev) ++{ ++ int err = 0; ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ struct device_node *fw_node; ++ struct rpi_firmware *fw; ++ struct brcmexp_gpio *ucb; ++ ++ fw_node = of_parse_phandle(np, "firmware", 0); ++ if (!fw_node) { ++ dev_err(dev, "Missing firmware node\n"); ++ return -ENOENT; ++ } ++ ++ fw = rpi_firmware_get(fw_node); ++ if (!fw) ++ return -EPROBE_DEFER; ++ ++ ucb = devm_kzalloc(dev, sizeof(*ucb), GFP_KERNEL); ++ if (!ucb) ++ return -EINVAL; ++ ++ ucb->fw = fw; ++ ucb->dev = dev; ++ ucb->gc.label = MODULE_NAME; ++ ucb->gc.owner = THIS_MODULE; ++ ucb->gc.of_node = np; ++ ucb->gc.base = 128; ++ ucb->gc.ngpio = NUM_GPIO; ++ ++ ucb->gc.direction_input = brcmexp_gpio_dir_in; ++ ucb->gc.direction_output = brcmexp_gpio_dir_out; ++ ucb->gc.get_direction = brcmexp_gpio_get_direction; ++ ucb->gc.get = brcmexp_gpio_get; ++ ucb->gc.set = brcmexp_gpio_set; ++ ucb->gc.can_sleep = true; ++ ++ err = gpiochip_add(&ucb->gc); ++ if (err) ++ return err; ++ ++ platform_set_drvdata(pdev, ucb); ++ ++ return 0; ++} ++ ++static int brcmexp_gpio_remove(struct platform_device *pdev) ++{ ++ struct brcmexp_gpio *ucb = platform_get_drvdata(pdev); ++ ++ gpiochip_remove(&ucb->gc); ++ ++ return 0; ++} ++ ++static const struct of_device_id __maybe_unused brcmexp_gpio_ids[] = { ++ { .compatible = "brcm,bcm2835-expgpio" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, brcmexp_gpio_ids); ++ ++static struct platform_driver brcmexp_gpio_driver = { ++ .driver = { ++ .name = MODULE_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(brcmexp_gpio_ids), ++ }, ++ .probe = brcmexp_gpio_probe, ++ .remove = brcmexp_gpio_remove, ++}; ++module_platform_driver(brcmexp_gpio_driver); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Dave Stevenson "); ++MODULE_DESCRIPTION("brcm-exp GPIO driver"); ++MODULE_ALIAS("platform:brcmexp-gpio"); +diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h +index 280791fb9656901392ce67e44cb742c96f090ed4..dc7fd58afd5dddebf9b17065bb069a1db663362c 100644 +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -83,7 +83,11 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_SET_TURBO = 0x00038009, + RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021, + RPI_FIRMWARE_SET_DOMAIN_STATE = 0x00038030, ++ RPI_FIRMWARE_GET_GPIO_STATE = 0x00030041, ++ RPI_FIRMWARE_SET_GPIO_STATE = 0x00038041, + RPI_FIRMWARE_SET_SDHOST_CLOCK = 0x00038042, ++ RPI_FIRMWARE_GET_GPIO_CONFIG = 0x00030043, ++ RPI_FIRMWARE_SET_GPIO_CONFIG = 0x00038043, + + /* Dispmanx TAGS */ + RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, + +From 6513883b414602f43a1f6172687910725ec2c513 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 24 May 2016 16:30:05 +0100 +Subject: [PATCH 155/190] BCM270X_DT: Add bcm2708-rpi-0-w.dts + +Add DT support for the Pi Zero W. N.B. It will not be loaded +automatically without a corresponding change to the firmware. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/Makefile | 1 + + arch/arm/boot/dts/bcm2708-rpi-0-w.dts | 197 ++++++++++++++++++++++++++++++++++ + 2 files changed, 198 insertions(+) + create mode 100644 arch/arm/boot/dts/bcm2708-rpi-0-w.dts + +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index 0263d6172d3af40668c02535a4f8dce022f3a93d..3c758781b9171f957b6afdd87c169795a61007a5 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -4,6 +4,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ + bcm2708-rpi-b.dtb \ + bcm2708-rpi-b-plus.dtb \ + bcm2708-rpi-cm.dtb \ ++ bcm2708-rpi-0-w.dtb \ + bcm2709-rpi-2-b.dtb \ + bcm2710-rpi-3-b.dtb \ + bcm2710-rpi-cm3.dtb +diff --git a/arch/arm/boot/dts/bcm2708-rpi-0-w.dts b/arch/arm/boot/dts/bcm2708-rpi-0-w.dts +new file mode 100644 +index 0000000000000000000000000000000000000000..db0f99ddf2f46e83827d56e21c4846dd0b414c63 +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2708-rpi-0-w.dts +@@ -0,0 +1,197 @@ ++/dts-v1/; ++ ++#include "bcm2708.dtsi" ++ ++/ { ++ model = "Raspberry Pi Zero W"; ++}; ++ ++&gpio { ++ sdhost_pins: sdhost_pins { ++ brcm,pins = <48 49 50 51 52 53>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ spi0_pins: spi0_pins { ++ brcm,pins = <9 10 11>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ spi0_cs_pins: spi0_cs_pins { ++ brcm,pins = <8 7>; ++ brcm,function = <1>; /* output */ ++ }; ++ ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; ++ }; ++ ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; ++ }; ++ ++ i2s_pins: i2s { ++ brcm,pins = <18 19 20 21>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ sdio_pins: sdio_pins { ++ brcm,pins = <34 35 36 37 38 39>; ++ brcm,function = <7>; /* ALT3 = SD1 */ ++ brcm,pull = <0 2 2 2 2 2>; ++ }; ++ ++ bt_pins: bt_pins { ++ brcm,pins = <43>; ++ brcm,function = <4>; /* alt0:GPCLK2 */ ++ brcm,pull = <0>; /* none */ ++ }; ++ ++ uart0_pins: uart0_pins { ++ brcm,pins = <30 31 32 33>; ++ brcm,function = <7>; /* alt3=UART0 */ ++ brcm,pull = <2 0 0 2>; /* up none none up */ ++ }; ++ ++ uart1_pins: uart1_pins { ++ brcm,pins; ++ brcm,function; ++ brcm,pull; ++ }; ++ ++ audio_pins: audio_pins { ++ brcm,pins = <>; ++ brcm,function = <>; ++ }; ++}; ++ ++&sdhost { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdhost_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&mmc { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio_pins>; ++ non-removable; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&fb { ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins &bt_pins>; ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "okay"; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; ++ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; ++ ++ spidev0: spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++ ++ spidev1: spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++}; ++ ++&i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c2 { ++ clock-frequency = <100000>; ++}; ++ ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++&random { ++ status = "okay"; ++}; ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; ++ gpios = <&gpio 47 0>; ++ }; ++}; ++ ++&hdmi { ++ hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; ++}; ++ ++&audio { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&audio_pins>; ++}; ++ ++/ { ++ chosen { ++ bootargs = "8250.nr_uarts=1"; ++ }; ++}; ++ ++/ { ++ __overrides__ { ++ uart0 = <&uart0>,"status"; ++ uart1 = <&uart1>,"status"; ++ i2s = <&i2s>,"status"; ++ spi = <&spi0>,"status"; ++ i2c0 = <&i2c0>,"status"; ++ i2c1 = <&i2c1>,"status"; ++ i2c2_iknowwhatimdoing = <&i2c2>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; ++ ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ ++ audio = <&audio>,"status"; ++ watchdog = <&watchdog>,"status"; ++ random = <&random>,"status"; ++ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; ++ sd_force_pio = <&sdhost>,"brcm,force-pio?"; ++ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; ++ sd_debug = <&sdhost>,"brcm,debug"; ++ }; ++}; + +From dca094edd80fab9d689912584a40a45314649288 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 6 Mar 2017 09:06:18 +0000 +Subject: [PATCH 156/190] 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 +driver. Since the core frequency can change without warning, it is +safer to report the maximum clock rate to users of the core clock - +I2C, SPI and the mini UART - to err on the safe side when calculating +clock divisors. + +If the DT node for the clock driver includes a reference to the +firmware node, use the firmware API to query the maximum core clock +instead of reading the divider registers. + +Prior to this patch, a "100KHz" I2C bus was sometimes clocked at about +160KHz. In particular, switching to the 4.9 kernel was likely to break +SenseHAT usage on a Pi3. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/bcm2708-rpi.dtsi | 4 ++++ + drivers/clk/bcm/clk-bcm2835.c | 39 +++++++++++++++++++++++++++++++++++++- + 2 files changed, 42 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/bcm2708-rpi.dtsi b/arch/arm/boot/dts/bcm2708-rpi.dtsi +index 055090ace687b94e4d25de65d1b8fbf7f730be9e..ef14e9ac6cd2092efb1681682dd2d3c52b8abfd5 100644 +--- a/arch/arm/boot/dts/bcm2708-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2708-rpi.dtsi +@@ -107,3 +107,7 @@ + &usb { + power-domains = <&power RPI_POWER_DOMAIN_USB>; + }; ++ ++&clocks { ++ firmware = <&firmware>; ++}; +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index ef0d05c58573f62de3632a920dfc19888c019d18..41dccc4ebe6f367054822aed11cb0cd4d985c21a 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -44,6 +44,7 @@ + #include + #include + #include ++#include + + #define CM_PASSWORD 0x5a000000 + +@@ -297,9 +298,12 @@ + #define LOCK_TIMEOUT_NS 100000000 + #define BCM2835_MAX_FB_RATE 1750000000u + ++#define VCMSG_ID_CORE_CLOCK 4 ++ + struct bcm2835_cprman { + struct device *dev; + void __iomem *regs; ++ struct rpi_firmware *fw; + spinlock_t regs_lock; /* spinlock for all clocks */ + const char *osc_name; + +@@ -936,6 +940,30 @@ static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw, + return bcm2835_clock_rate_from_divisor(clock, parent_rate, div); + } + ++static unsigned long bcm2835_clock_get_rate_vpu(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); ++ struct bcm2835_cprman *cprman = clock->cprman; ++ ++ if (cprman->fw) { ++ struct { ++ u32 id; ++ u32 val; ++ } packet; ++ ++ packet.id = VCMSG_ID_CORE_CLOCK; ++ packet.val = 0; ++ ++ if (!rpi_firmware_property(cprman->fw, ++ RPI_FIRMWARE_GET_MAX_CLOCK_RATE, ++ &packet, sizeof(packet))) ++ return packet.val; ++ } ++ ++ return bcm2835_clock_get_rate(hw, parent_rate); ++} ++ + static void bcm2835_clock_wait_busy(struct bcm2835_clock *clock) + { + struct bcm2835_cprman *cprman = clock->cprman; +@@ -1192,7 +1220,7 @@ static int bcm2835_vpu_clock_is_on(struct clk_hw *hw) + */ + static const struct clk_ops bcm2835_vpu_clock_clk_ops = { + .is_prepared = bcm2835_vpu_clock_is_on, +- .recalc_rate = bcm2835_clock_get_rate, ++ .recalc_rate = bcm2835_clock_get_rate_vpu, + .set_rate = bcm2835_clock_set_rate, + .determine_rate = bcm2835_clock_determine_rate, + .set_parent = bcm2835_clock_set_parent, +@@ -1952,6 +1980,7 @@ static int bcm2835_clk_probe(struct platform_device *pdev) + struct resource *res; + const struct bcm2835_clk_desc *desc; + const size_t asize = ARRAY_SIZE(clk_desc_array); ++ struct device_node *fw_node; + size_t i; + u32 clk_id; + int ret; +@@ -1969,6 +1998,14 @@ static int bcm2835_clk_probe(struct platform_device *pdev) + if (IS_ERR(cprman->regs)) + return PTR_ERR(cprman->regs); + ++ fw_node = of_parse_phandle(dev->of_node, "firmware", 0); ++ if (fw_node) { ++ struct rpi_firmware *fw = rpi_firmware_get(NULL); ++ if (!fw) ++ return -EPROBE_DEFER; ++ cprman->fw = fw; ++ } ++ + memset(bcm2835_clk_claimed, 0, sizeof(bcm2835_clk_claimed)); + for (i = 0; + !of_property_read_u32_index(pdev->dev.of_node, "claim-clocks", + +From d4fc13bbc1a9d270c2f5a601d96f39cfc5e8f89a Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 7 Mar 2017 19:48:23 +0000 +Subject: [PATCH 157/190] config: Add CONFIG_CRYPTO_LZ4 + +Enabling this options allows LZ4 memory compression. + +Fixes: https://github.com/raspberrypi/linux/issues/1875 + +Signed-off-by: Phil Elwell +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index 0ee1ff698a5571f80da89a1067025b32fe546136..b5260a6701e48fdfcaeae9aad7dac62b4e160986 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -1303,6 +1303,7 @@ 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_ARM_CRYPTO=y +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index a9c46f902eb32b364423d8bef07b6b37f798c617..e5996d77b02303c4b43e62a810e0e3e660c1e99e 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -1311,6 +1311,7 @@ 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_ARM_CRYPTO=y + +From 04fba23a3e1c5f3bfeecdd32a2c09ec47548c3b7 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Sun, 5 Mar 2017 11:46:41 +0000 +Subject: [PATCH 158/190] config: Add RTL8XXXU wifi module + +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index b5260a6701e48fdfcaeae9aad7dac62b4e160986..6143dfd58993aa0e5adb4808fea6987058979971 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -540,6 +540,7 @@ 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 +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index e5996d77b02303c4b43e62a810e0e3e660c1e99e..a691ce8b7fb6017fcc7990cf08e8ff4a39302fba 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -536,6 +536,7 @@ 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 + +From a259543813fa4e92c64d8f1bb3f3289e88ec4ad7 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 10 Mar 2017 14:43:15 +0000 +Subject: [PATCH 159/190] bcm2835-v4l2: Fix buffer overflow problem + +https://github.com/raspberrypi/linux/issues/1447 +port_parameter_get() failed to account for the header +(u32 id and u32 size) in the size before memcpying +the response into the response buffer, so overrunning +the provided buffer by 8 bytes. + +Account for those bytes, and also a belt-and-braces +check to ensure we never copy more than *value_size +bytes into value. + +Signed-off-by: Dave Stevenson +--- + drivers/media/platform/bcm2835/mmal-vchiq.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/platform/bcm2835/mmal-vchiq.c b/drivers/media/platform/bcm2835/mmal-vchiq.c +index 781322542d5a8295f3d7d5a3eaaf0cac29930c30..e4b243b33f58913f3d2952c97d2a2e3fbbbd0ae8 100644 +--- a/drivers/media/platform/bcm2835/mmal-vchiq.c ++++ b/drivers/media/platform/bcm2835/mmal-vchiq.c +@@ -1315,7 +1315,12 @@ static int port_parameter_get(struct vchiq_mmal_instance *instance, + } + + ret = -rmsg->u.port_parameter_get_reply.status; +- if (ret) { ++ /* 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 + */ + +From 8da66863fce1f5d19da99ecf124f15f8b5d5a36d Mon Sep 17 00:00:00 2001 +From: Matt Flax +Date: Wed, 8 Mar 2017 20:04:13 +1100 +Subject: [PATCH 160/190] Add support for the AudioInjector.net Octo sound card + +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 6 + + .../dts/overlays/audioinjector-addons-overlay.dts | 50 ++++ + arch/arm/configs/bcm2709_defconfig | 2 + + arch/arm/configs/bcmrpi_defconfig | 2 + + sound/soc/bcm/Kconfig | 7 + + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/audioinjector-octo-soundcard.c | 286 +++++++++++++++++++++ + 8 files changed, 356 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts + create mode 100644 sound/soc/bcm/audioinjector-octo-soundcard.c + +diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile +index c890e5ddb0e2eec982597a851023b539d318d6ce..0f7340799fb465ba1fb5aaa1e970cbf6295d75c4 100644 +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -9,6 +9,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + akkordion-iqdacplus.dtbo \ + allo-piano-dac-pcm512x-audio.dtbo \ + at86rf233.dtbo \ ++ audioinjector-addons.dtbo \ + audioinjector-wm8731-audio.dtbo \ + audremap.dtbo \ + bmp085_i2c-sensor.dtbo \ +diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README +index 970c9c9b5c74467a3014a77039fa765d8f8c4e6f..c1883bba938290f03826026651c764cfd4ac278b 100644 +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -295,6 +295,12 @@ Params: interrupt GPIO used for INT (default 23) + arrays (0=+0pF, 15=+4.5pF, default 15) + + ++Name: audioinjector-addons ++Info: Configures the audioinjector.net audio add on soundcards ++Load: dtoverlay=audioinjector-addons ++Params: ++ ++ + Name: audioinjector-wm8731-audio + Info: Configures the audioinjector.net audio add on soundcard + Load: dtoverlay=audioinjector-wm8731-audio +diff --git a/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts b/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts +new file mode 100644 +index 0000000000000000000000000000000000000000..dbf2f3cacc2e6bf5b7116fbadd97f2781580a79c +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts +@@ -0,0 +1,50 @@ ++// Definitions for audioinjector.net audio add on soundcard ++/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"; ++ ++ cs42448: cs42448@48 { ++ #sound-dai-cells = <0>; ++ compatible = "cirrus,cs42448"; ++ reg = <0x48>; ++ clocks = <&cs42448_mclk>; ++ clock-names = "mclk"; ++ status = "okay"; ++ }; ++ ++ cs42448_mclk: codec-mclk { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <49152000>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "ai,audioinjector-octo-soundcard"; ++ mult-gpios = <&gpio 27 0>, <&gpio 22 0>, <&gpio 23 0>, ++ <&gpio 24 0>; ++ i2s-controller = <&i2s>; ++ codec = <&cs42448>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index 6143dfd58993aa0e5adb4808fea6987058979971..97375c26f2d70d0c4f3956622f839dcf04463e31 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -883,6 +883,7 @@ CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m + CONFIG_SND_BCM2708_SOC_RASPIDAC3=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 +@@ -892,6 +893,7 @@ CONFIG_SND_PISOUND=m + CONFIG_SND_SOC_ADAU1701=m + CONFIG_SND_SOC_ADAU7002=m + CONFIG_SND_SOC_AK4554=m ++CONFIG_SND_SOC_CS42XX8_I2C=m + CONFIG_SND_SOC_WM8804_I2C=m + CONFIG_SND_SIMPLE_CARD=m + CONFIG_SOUND_PRIME=m +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index a691ce8b7fb6017fcc7990cf08e8ff4a39302fba..0e2c3679d9614d331db39cd25ae9095136d3190a 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -876,6 +876,7 @@ CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m + CONFIG_SND_BCM2708_SOC_RASPIDAC3=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 +@@ -885,6 +886,7 @@ CONFIG_SND_PISOUND=m + CONFIG_SND_SOC_ADAU1701=m + CONFIG_SND_SOC_ADAU7002=m + CONFIG_SND_SOC_AK4554=m ++CONFIG_SND_SOC_CS42XX8_I2C=m + CONFIG_SND_SOC_WM8804_I2C=m + CONFIG_SND_SIMPLE_CARD=m + CONFIG_SOUND_PRIME=m +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index 7473efd6f400a1a1618aac830753fce39d203b89..706c500b5303ac3a0fd8687d23dc9f06c7d08388 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -119,6 +119,13 @@ config SND_AUDIOINJECTOR_PI_SOUNDCARD + help + Say Y or M if you want to add support for audioinjector.net Pi Hat + ++config SND_AUDIOINJECTOR_OCTO_SOUNDCARD ++ tristate "Support for audioinjector.net Octo channel (Hat) soundcard" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_CS42XX8_I2C ++ help ++ Say Y or M if you want to add support for audioinjector.net octo add on ++ + config SND_DIGIDAC1_SOUNDCARD + tristate "Support for Red Rocks Audio DigiDAC1" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index 8d2d2073dc2cede9fbd9eb8b49083650ba0a8172..d448aa517bf994fc0a41580c91b5d87deec9e1b0 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -23,6 +23,7 @@ snd-soc-iqaudio-dac-objs := iqaudio-dac.o + snd-soc-iqaudio-digi-objs := iqaudio_digi.o + snd-soc-raspidac3-objs := raspidac3.o + snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o ++snd-soc-audioinjector-octo-soundcard-objs := audioinjector-octo-soundcard.o + snd-soc-digidac1-soundcard-objs := digidac1-soundcard.o + snd-soc-dionaudio-loco-objs := dionaudio_loco.o + snd-soc-dionaudio-loco-v2-objs := dionaudio_loco-v2.o +@@ -44,6 +45,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o + obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI) += snd-soc-iqaudio-digi.o + obj-$(CONFIG_SND_BCM2708_SOC_RASPIDAC3) += snd-soc-raspidac3.o + obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o ++obj-$(CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD) += snd-soc-audioinjector-octo-soundcard.o + obj-$(CONFIG_SND_DIGIDAC1_SOUNDCARD) += snd-soc-digidac1-soundcard.o + obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO) += snd-soc-dionaudio-loco.o + obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2) += snd-soc-dionaudio-loco-v2.o +diff --git a/sound/soc/bcm/audioinjector-octo-soundcard.c b/sound/soc/bcm/audioinjector-octo-soundcard.c +new file mode 100644 +index 0000000000000000000000000000000000000000..9effea725798640887755dfa688da45338718afc +--- /dev/null ++++ b/sound/soc/bcm/audioinjector-octo-soundcard.c +@@ -0,0 +1,286 @@ ++/* ++ * ASoC Driver for AudioInjector Pi octo channel soundcard (hat) ++ * ++ * Created on: 27-October-2016 ++ * Author: flatmax@flatmax.org ++ * based on audioinjector-pi-soundcard.c ++ * ++ * Copyright (C) 2016 Flatmax Pty. Ltd. ++ * ++ * 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 ++ ++static struct gpio_descs *mult_gpios; ++static unsigned int audioinjector_octo_rate; ++ ++static int audioinjector_octo_dai_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ return snd_soc_dai_set_bclk_ratio(rtd->cpu_dai, 64); ++} ++ ++static int audioinjector_octo_startup(struct snd_pcm_substream *substream) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ rtd->cpu_dai->driver->playback.channels_min = 8; ++ rtd->cpu_dai->driver->playback.channels_max = 8; ++ rtd->cpu_dai->driver->capture.channels_min = 8; ++ rtd->cpu_dai->driver->capture.channels_max = 8; ++ rtd->codec_dai->driver->capture.channels_max = 8; ++ return 0; ++} ++ ++static void audioinjector_octo_shutdown(struct snd_pcm_substream *substream) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ rtd->cpu_dai->driver->playback.channels_min = 2; ++ rtd->cpu_dai->driver->playback.channels_max = 2; ++ rtd->cpu_dai->driver->capture.channels_min = 2; ++ rtd->cpu_dai->driver->capture.channels_max = 2; ++ rtd->codec_dai->driver->capture.channels_max = 6; ++} ++ ++static int audioinjector_octo_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ ++ // set codec DAI configuration ++ int ret = snd_soc_dai_set_fmt(rtd->codec_dai, ++ SND_SOC_DAIFMT_CBS_CFS|SND_SOC_DAIFMT_DSP_A| ++ SND_SOC_DAIFMT_NB_NF); ++ if (ret < 0) ++ return ret; ++ ++ // set cpu DAI configuration ++ ret = snd_soc_dai_set_fmt(rtd->cpu_dai, ++ SND_SOC_DAIFMT_CBM_CFM|SND_SOC_DAIFMT_I2S| ++ SND_SOC_DAIFMT_NB_NF); ++ if (ret < 0) ++ return ret; ++ ++ audioinjector_octo_rate = params_rate(params); ++ ++ return 0; ++} ++ ++static int audioinjector_octo_trigger(struct snd_pcm_substream *substream, ++ int cmd){ ++ int mult[4]; ++ mult[0] = 0; ++ mult[1] = 0; ++ mult[2] = 0; ++ mult[3] = 0; ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ switch (audioinjector_octo_rate) { ++ case 192000: ++ mult[3] = 1; ++ case 176640: ++ mult[0] = 1; ++ mult[1] = 1; ++ mult[2] = 1; ++ break; ++ case 96000: ++ mult[3] = 1; ++ case 88200: ++ mult[1] = 1; ++ mult[2] = 1; ++ break; ++ case 64000: ++ mult[3] = 1; ++ case 58800: ++ mult[0] = 1; ++ mult[2] = 1; ++ break; ++ case 48000: ++ mult[3] = 1; ++ case 44100: ++ mult[2] = 1; ++ break; ++ case 32000: ++ mult[3] = 1; ++ case 29400: ++ mult[0] = 1; ++ mult[1] = 1; ++ break; ++ case 24000: ++ mult[3] = 1; ++ case 22050: ++ mult[1] = 1; ++ break; ++ case 16000: ++ mult[3] = 1; ++ case 14700: ++ mult[0] = 1; ++ break; ++ case 8000: ++ mult[3] = 1; ++ break; ++ default: ++ return -EINVAL; ++ } ++ break; ++ case SNDRV_PCM_TRIGGER_STOP: ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ break; ++ default: ++ return -EINVAL; ++ } ++ gpiod_set_array_value_cansleep(mult_gpios->ndescs, mult_gpios->desc, ++ mult); ++ ++ return 0; ++} ++ ++static struct snd_soc_ops audioinjector_octo_ops = { ++ .startup = audioinjector_octo_startup, ++ .shutdown = audioinjector_octo_shutdown, ++ .hw_params = audioinjector_octo_hw_params, ++ .trigger = audioinjector_octo_trigger, ++}; ++ ++static struct snd_soc_dai_link audioinjector_octo_dai[] = { ++ { ++ .name = "AudioInjector Octo", ++ .stream_name = "AudioInject-HIFI", ++ .codec_dai_name = "cs42448", ++ .ops = &audioinjector_octo_ops, ++ .init = audioinjector_octo_dai_init, ++ }, ++}; ++ ++static const struct snd_soc_dapm_widget audioinjector_octo_widgets[] = { ++ SND_SOC_DAPM_OUTPUT("OUTPUTS0"), ++ SND_SOC_DAPM_OUTPUT("OUTPUTS1"), ++ SND_SOC_DAPM_OUTPUT("OUTPUTS2"), ++ SND_SOC_DAPM_OUTPUT("OUTPUTS3"), ++ SND_SOC_DAPM_INPUT("INPUTS0"), ++ SND_SOC_DAPM_INPUT("INPUTS1"), ++ SND_SOC_DAPM_INPUT("INPUTS2"), ++}; ++ ++static const struct snd_soc_dapm_route audioinjector_octo_route[] = { ++ /* Balanced outputs */ ++ {"OUTPUTS0", NULL, "AOUT1L"}, ++ {"OUTPUTS0", NULL, "AOUT1R"}, ++ {"OUTPUTS1", NULL, "AOUT2L"}, ++ {"OUTPUTS1", NULL, "AOUT2R"}, ++ {"OUTPUTS2", NULL, "AOUT3L"}, ++ {"OUTPUTS2", NULL, "AOUT3R"}, ++ {"OUTPUTS3", NULL, "AOUT4L"}, ++ {"OUTPUTS3", NULL, "AOUT4R"}, ++ ++ /* Balanced inputs */ ++ {"AIN1L", NULL, "INPUTS0"}, ++ {"AIN1R", NULL, "INPUTS0"}, ++ {"AIN2L", NULL, "INPUTS1"}, ++ {"AIN2R", NULL, "INPUTS1"}, ++ {"AIN3L", NULL, "INPUTS2"}, ++ {"AIN3R", NULL, "INPUTS2"}, ++}; ++ ++static struct snd_soc_card snd_soc_audioinjector_octo = { ++ .name = "audioinjector-octo-soundcard", ++ .dai_link = audioinjector_octo_dai, ++ .num_links = ARRAY_SIZE(audioinjector_octo_dai), ++ ++ .dapm_widgets = audioinjector_octo_widgets, ++ .num_dapm_widgets = ARRAY_SIZE(audioinjector_octo_widgets), ++ .dapm_routes = audioinjector_octo_route, ++ .num_dapm_routes = ARRAY_SIZE(audioinjector_octo_route), ++}; ++ ++static int audioinjector_octo_probe(struct platform_device *pdev) ++{ ++ struct snd_soc_card *card = &snd_soc_audioinjector_octo; ++ int ret; ++ ++ card->dev = &pdev->dev; ++ ++ if (pdev->dev.of_node) { ++ struct snd_soc_dai_link *dai = &audioinjector_octo_dai[0]; ++ struct device_node *i2s_node = ++ of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ struct device_node *codec_node = ++ of_parse_phandle(pdev->dev.of_node, ++ "codec", 0); ++ ++ mult_gpios = devm_gpiod_get_array_optional(&pdev->dev, "mult", ++ GPIOD_OUT_LOW); ++ if (IS_ERR(mult_gpios)) ++ return PTR_ERR(mult_gpios); ++ ++ if (i2s_node && codec_node) { ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = i2s_node; ++ dai->platform_name = NULL; ++ dai->platform_of_node = i2s_node; ++ dai->codec_name = NULL; ++ dai->codec_of_node = codec_node; ++ } else ++ if (!dai->cpu_of_node) { ++ dev_err(&pdev->dev, ++ "i2s-controller missing or invalid in DT\n"); ++ return -EINVAL; ++ } else { ++ dev_err(&pdev->dev, ++ "Property 'codec' missing or invalid\n"); ++ return -EINVAL; ++ } ++ } ++ ++ ret = snd_soc_register_card(card); ++ if (ret != 0) ++ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); ++ return ret; ++} ++ ++static int audioinjector_octo_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 audioinjector_octo_of_match[] = { ++ { .compatible = "ai,audioinjector-octo-soundcard", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, audioinjector_octo_of_match); ++ ++static struct platform_driver audioinjector_octo_driver = { ++ .driver = { ++ .name = "audioinjector-audio", ++ .owner = THIS_MODULE, ++ .of_match_table = audioinjector_octo_of_match, ++ }, ++ .probe = audioinjector_octo_probe, ++ .remove = audioinjector_octo_remove, ++}; ++ ++module_platform_driver(audioinjector_octo_driver); ++MODULE_AUTHOR("Matt Flax "); ++MODULE_DESCRIPTION("AudioInjector.net octo Soundcard"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:audioinjector-octo-soundcard"); + +From 89823fe6327ef9c00f48721a779c785fb0c1cf1f Mon Sep 17 00:00:00 2001 +From: Matt Flax +Date: Wed, 8 Mar 2017 21:13:24 +1100 +Subject: [PATCH 161/190] ASoC: bcm2835_i2s.c: relax the ch2 register setting + for 8 channels + +This patch allows ch2 registers to be set for 8 channels of audio. +--- + sound/soc/bcm/bcm2835-i2s.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index 6ba20498202ed36906b52096893a88867a79269f..c8dd065aea8414b47aa2ea4fc04168b5e29002ad 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -239,6 +239,7 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, + unsigned int ch1pos, ch2pos, mode, format; + uint32_t csreg; + ++ + /* + * If a stream is already enabled, + * the registers are already set properly. +@@ -312,6 +313,7 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, + + switch (params_channels(params)) { + case 2: ++ case 8: + format = BCM2835_I2S_CH1(format) | BCM2835_I2S_CH2(format); + format |= BCM2835_I2S_CH1(BCM2835_I2S_CHPOS(ch1pos)); + format |= BCM2835_I2S_CH2(BCM2835_I2S_CHPOS(ch2pos)); + +From 6724b1f8f1c938422f898b8a333f203ad54ad4bb Mon Sep 17 00:00:00 2001 +From: Khem Raj +Date: Fri, 10 Feb 2017 17:57:08 -0800 +Subject: [PATCH 162/190] build/arm64: Add rules for .dtbo files for dts + overlays + +We now create overlays as .dtbo files. + +Signed-off-by: Khem Raj +--- + arch/arm64/Makefile | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile +index b9a4a934ca057623e0ea436fd9b2c7c0f675fced..54e3c38d6fd877827541cdc798de035cf439b17f 100644 +--- a/arch/arm64/Makefile ++++ b/arch/arm64/Makefile +@@ -119,6 +119,9 @@ zinstall install: + %.dtb: scripts + $(Q)$(MAKE) $(build)=$(boot)/dts $(boot)/dts/$@ + ++%.dtbo: | scripts ++ $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@ ++ + PHONY += dtbs dtbs_install + + dtbs: prepare scripts + +From 0e3412d4f406a8870c4e2c122127793e6abd41b1 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 24 Feb 2015 13:40:50 +0000 +Subject: [PATCH 163/190] pinctrl-bcm2835: Fix interrupt handling for GPIOs + 28-31 and 46-53 + +Contrary to the documentation, the BCM2835 GPIO controller actually has +four interrupt lines - one each for the three IRQ groups and one common. Rather +confusingly, the GPIO interrupt groups don't correspond directly with the GPIO +control banks. Instead, GPIOs 0-27 generate IRQ GPIO0, 28-45 GPIO1 and +46-53 GPIO2. + +Awkwardly, the GPIOS for IRQ GPIO1 straddle two 32-entry GPIO banks, so it is +cleaner to split out a function to process the interrupts for a single GPIO +bank. + +This bug has only just been observed because GPIOs above 27 can only be +accessed on an old Raspberry Pi with the optional P5 header fitted, where +the pins are often used for I2S instead. +--- + drivers/pinctrl/bcm/pinctrl-bcm2835.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +index 6351fe7f8e314ac5ebb102dd20847b383fd5b857..28745af5aadf3cb91fa7ff39118385c393e2d1d4 100644 +--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c ++++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +@@ -1109,6 +1109,7 @@ static struct platform_driver bcm2835_pinctrl_driver = { + .remove = bcm2835_pinctrl_remove, + .driver = { + .name = MODULE_NAME, ++ .owner = THIS_MODULE, + .of_match_table = bcm2835_pinctrl_match, + }, + }; + +From 2296a95a44a8709f354ebd6213f927777d892a46 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 9 May 2016 17:28:18 -0700 +Subject: [PATCH 164/190] clk: bcm2835: Mark GPIO clocks enabled at boot as + critical. + +These divide off of PLLD_PER and are used for the ethernet and wifi +PHYs source PLLs. Neither of them is currently represented by a phy +device that would grab the clock for us. + +This keeps other drivers from killing the networking PHYs when they +disable their own clocks and trigger PLLD_PER's refcount going to 0. + +v2: Skip marking as critical if they aren't on at boot. + +Signed-off-by: Eric Anholt +--- + drivers/clk/bcm/clk-bcm2835.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index 41dccc4ebe6f367054822aed11cb0cd4d985c21a..7ec0e71cbcfbcd6c86e2f6c8080e1d622ca5540a 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -1357,6 +1357,15 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman, + init.flags = data->flags | CLK_IGNORE_UNUSED; + + /* ++ * Some GPIO clocks for ethernet/wifi PLLs are marked as ++ * critical (since some platforms use them), but if the ++ * firmware didn't have them turned on then they clearly ++ * aren't actually critical. ++ */ ++ if ((cprman_read(cprman, data->ctl_reg) & CM_ENABLE) == 0) ++ init.flags &= ~CLK_IS_CRITICAL; ++ ++ /* + * Pass the CLK_SET_RATE_PARENT flag if we are allowed to propagate + * rate changes on at least of the parents. + */ + +From 35c10e8317071661af8a72f0ffb41a12956bd366 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 7 Mar 2016 15:05:11 +0000 +Subject: [PATCH 165/190] vchiq_arm: Tweak the logging output + +Signed-off-by: Phil Elwell +--- + .../vc04_services/interface/vchiq_arm/vchiq_core.c | 31 +++++++++------------- + 1 file changed, 13 insertions(+), 18 deletions(-) + +diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c +index d6757ee263fb61a689c0d38c0dbb65c57a8e39bb..7fd63cf6800d7ec35fbcb215a283630c11120c7f 100644 +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c +@@ -873,16 +873,14 @@ queue_message(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, + error_count); + return VCHIQ_ERROR; + } +- if (i == 0) { +- if (SRVTRACE_ENABLED(service, +- VCHIQ_LOG_INFO)) +- vchiq_log_dump_mem("Sent", 0, +- header->data + pos, +- min(64u, +- elements[0].size)); +- } + } + ++ if (SRVTRACE_ENABLED(service, ++ VCHIQ_LOG_INFO)) ++ vchiq_log_dump_mem("Sent", 0, ++ header->data, ++ min(16, pos)); ++ + spin_lock("a_spinlock); + service_quota->message_use_count++; + +@@ -1019,16 +1017,13 @@ queue_message_sync(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, + error_count); + return VCHIQ_ERROR; + } +- if (i == 0) { +- if (vchiq_sync_log_level >= +- VCHIQ_LOG_TRACE) +- vchiq_log_dump_mem("Sent Sync", +- 0, header->data + pos, +- min(64u, +- elements[0].size)); +- } + } + ++ if (vchiq_sync_log_level >= VCHIQ_LOG_TRACE) ++ vchiq_log_dump_mem("Sent Sync", ++ 0, header->data, ++ min(16, pos)); ++ + VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count); + VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size); + } else { +@@ -1691,7 +1686,7 @@ parse_rx_slots(VCHIQ_STATE_T *state) + remoteport, localport, size); + if (size > 0) + vchiq_log_dump_mem("Rcvd", 0, header->data, +- min(64, size)); ++ min(16, size)); + } + + if (((unsigned long)header & VCHIQ_SLOT_MASK) + +@@ -2148,7 +2143,7 @@ sync_func(void *v) + remoteport, localport, size); + if (size > 0) + vchiq_log_dump_mem("Rcvd", 0, header->data, +- min(64, size)); ++ min(16, size)); + } + + switch (type) { + +From f0b20f2f429ec522875e5eb561f266e305a67724 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 18 Jan 2017 07:31:55 +1100 +Subject: [PATCH 166/190] clk: bcm2835: Don't rate change PLLs on behalf of DSI + PLL dividers. + +Our core PLLs are intended to be configured once and left alone. With +the SET_RATE_PARENT, asking to set the PLLD_DSI1 clock rate would +change PLLD just to get closer to the requested DSI clock, thus +changing PLLD_PER, the UART and ethernet PHY clock rates downstream of +it, and breaking ethernet. + +We *do* want PLLH to change so that PLLH_AUX can be exactly the value +we want, though. Thus, we need to have a per-divider policy of +whether to pass rate changes up. + +Signed-off-by: Eric Anholt +Signed-off-by: Stephen Boyd +(cherry picked from commit 55486091bd1e1c5ed28c43c0d6b3392468a9adb5) +--- + drivers/clk/bcm/clk-bcm2835.c | 42 ++++++++++++++++++++++++++++-------------- + 1 file changed, 28 insertions(+), 14 deletions(-) + +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index 7ec0e71cbcfbcd6c86e2f6c8080e1d622ca5540a..3acf61ddeda8c27e6da0fd7e2beb46341679eb66 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -432,6 +432,7 @@ struct bcm2835_pll_divider_data { + u32 load_mask; + u32 hold_mask; + u32 fixed_divider; ++ u32 flags; + }; + + struct bcm2835_clock_data { +@@ -1287,7 +1288,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman, + init.num_parents = 1; + init.name = divider_name; + init.ops = &bcm2835_pll_divider_clk_ops; +- init.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED; ++ init.flags = data->flags | CLK_IGNORE_UNUSED; + + divider = devm_kzalloc(cprman->dev, sizeof(*divider), GFP_KERNEL); + if (!divider) +@@ -1517,7 +1518,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLA_CORE, + .load_mask = CM_PLLA_LOADCORE, + .hold_mask = CM_PLLA_HOLDCORE, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + [BCM2835_PLLA_PER] = REGISTER_PLL_DIV( + .name = "plla_per", + .source_pll = "plla", +@@ -1525,7 +1527,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLA_PER, + .load_mask = CM_PLLA_LOADPER, + .hold_mask = CM_PLLA_HOLDPER, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + [BCM2835_PLLA_DSI0] = REGISTER_PLL_DIV( + .name = "plla_dsi0", + .source_pll = "plla", +@@ -1541,7 +1544,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLA_CCP2, + .load_mask = CM_PLLA_LOADCCP2, + .hold_mask = CM_PLLA_HOLDCCP2, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + + /* PLLB is used for the ARM's clock. */ + [BCM2835_PLLB] = REGISTER_PLL( +@@ -1565,7 +1569,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLB_ARM, + .load_mask = CM_PLLB_LOADARM, + .hold_mask = CM_PLLB_HOLDARM, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + + /* + * PLLC is the core PLL, used to drive the core VPU clock. +@@ -1594,7 +1599,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLC_CORE0, + .load_mask = CM_PLLC_LOADCORE0, + .hold_mask = CM_PLLC_HOLDCORE0, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + [BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV( + .name = "pllc_core1", + .source_pll = "pllc", +@@ -1602,7 +1608,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLC_CORE1, + .load_mask = CM_PLLC_LOADCORE1, + .hold_mask = CM_PLLC_HOLDCORE1, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + [BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV( + .name = "pllc_core2", + .source_pll = "pllc", +@@ -1610,7 +1617,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLC_CORE2, + .load_mask = CM_PLLC_LOADCORE2, + .hold_mask = CM_PLLC_HOLDCORE2, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + [BCM2835_PLLC_PER] = REGISTER_PLL_DIV( + .name = "pllc_per", + .source_pll = "pllc", +@@ -1618,7 +1626,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLC_PER, + .load_mask = CM_PLLC_LOADPER, + .hold_mask = CM_PLLC_HOLDPER, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + + /* + * PLLD is the display PLL, used to drive DSI display panels. +@@ -1647,7 +1656,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLD_CORE, + .load_mask = CM_PLLD_LOADCORE, + .hold_mask = CM_PLLD_HOLDCORE, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + [BCM2835_PLLD_PER] = REGISTER_PLL_DIV( + .name = "plld_per", + .source_pll = "plld", +@@ -1655,7 +1665,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLD_PER, + .load_mask = CM_PLLD_LOADPER, + .hold_mask = CM_PLLD_HOLDPER, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + [BCM2835_PLLD_DSI0] = REGISTER_PLL_DIV( + .name = "plld_dsi0", + .source_pll = "plld", +@@ -1700,7 +1711,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLH_RCAL, + .load_mask = CM_PLLH_LOADRCAL, + .hold_mask = 0, +- .fixed_divider = 10), ++ .fixed_divider = 10, ++ .flags = CLK_SET_RATE_PARENT), + [BCM2835_PLLH_AUX] = REGISTER_PLL_DIV( + .name = "pllh_aux", + .source_pll = "pllh", +@@ -1708,7 +1720,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLH_AUX, + .load_mask = CM_PLLH_LOADAUX, + .hold_mask = 0, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV( + .name = "pllh_pix", + .source_pll = "pllh", +@@ -1716,7 +1729,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLH_PIX, + .load_mask = CM_PLLH_LOADPIX, + .hold_mask = 0, +- .fixed_divider = 10), ++ .fixed_divider = 10, ++ .flags = CLK_SET_RATE_PARENT), + + /* the clocks */ + + +From 5577a9c36ac8217d1b9f477f68c02f751d3ae0e5 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 18 Jan 2017 07:31:56 +1100 +Subject: [PATCH 167/190] clk: bcm2835: Register the DSI0/DSI1 pixel clocks. + +The DSI pixel clocks are muxed from clocks generated in the analog phy +by the DSI driver. In order to set them as parents, we need to do the +same name lookup dance on them as we do for our root oscillator. + +Signed-off-by: Eric Anholt +Signed-off-by: Stephen Boyd +(cherry picked from commit 8a39e9fa578229fd4604266c6ebb1a3a77d7994c) +--- + .../bindings/clock/brcm,bcm2835-cprman.txt | 15 ++- + drivers/clk/bcm/clk-bcm2835.c | 121 +++++++++++++++++++-- + include/dt-bindings/clock/bcm2835.h | 2 + + 3 files changed, 125 insertions(+), 13 deletions(-) + +diff --git a/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt b/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt +index e56a1df3a9d3ca7fefbc5058072ee392c49b4cfc..dd906db34b328a581e4f4d99d11284544ff817f4 100644 +--- a/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt ++++ b/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt +@@ -16,7 +16,20 @@ Required properties: + - #clock-cells: Should be <1>. The permitted clock-specifier values can be + found in include/dt-bindings/clock/bcm2835.h + - reg: Specifies base physical address and size of the registers +-- clocks: The external oscillator clock phandle ++- clocks: phandles to the parent clocks used as input to the module, in ++ the following order: ++ ++ - External oscillator ++ - DSI0 byte clock ++ - DSI0 DDR2 clock ++ - DSI0 DDR clock ++ - DSI1 byte clock ++ - DSI1 DDR2 clock ++ - DSI1 DDR clock ++ ++ Only external oscillator is required. The DSI clocks may ++ not be present, in which case their children will be ++ unusable. + + Example: + +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index 3acf61ddeda8c27e6da0fd7e2beb46341679eb66..428e75c8b970897d881b570228eb85e8aef28999 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -300,12 +300,33 @@ + + #define VCMSG_ID_CORE_CLOCK 4 + ++/* ++ * Names of clocks used within the driver that need to be replaced ++ * with an external parent's name. This array is in the order that ++ * the clocks node in the DT references external clocks. ++ */ ++static const char *const cprman_parent_names[] = { ++ "xosc", ++ "dsi0_byte", ++ "dsi0_ddr2", ++ "dsi0_ddr", ++ "dsi1_byte", ++ "dsi1_ddr2", ++ "dsi1_ddr", ++}; ++ + struct bcm2835_cprman { + struct device *dev; + void __iomem *regs; + struct rpi_firmware *fw; + spinlock_t regs_lock; /* spinlock for all clocks */ +- const char *osc_name; ++ ++ /* ++ * Real names of cprman clock parents looked up through ++ * of_clk_get_parent_name(), which will be used in the ++ * parent_names[] arrays for clock registration. ++ */ ++ const char *real_parent_names[ARRAY_SIZE(cprman_parent_names)]; + + /* Must be last */ + struct clk_hw_onecell_data onecell; +@@ -913,6 +934,9 @@ static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock, + const struct bcm2835_clock_data *data = clock->data; + u64 temp; + ++ if (data->int_bits == 0 && data->frac_bits == 0) ++ return parent_rate; ++ + /* + * The divisor is a 12.12 fixed point field, but only some of + * the bits are populated in any given clock. +@@ -936,7 +960,12 @@ static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw, + struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); + struct bcm2835_cprman *cprman = clock->cprman; + const struct bcm2835_clock_data *data = clock->data; +- u32 div = cprman_read(cprman, data->div_reg); ++ u32 div; ++ ++ if (data->int_bits == 0 && data->frac_bits == 0) ++ return parent_rate; ++ ++ div = cprman_read(cprman, data->div_reg); + + return bcm2835_clock_rate_from_divisor(clock, parent_rate, div); + } +@@ -1241,7 +1270,7 @@ static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman, + memset(&init, 0, sizeof(init)); + + /* All of the PLLs derive from the external oscillator. */ +- init.parent_names = &cprman->osc_name; ++ init.parent_names = &cprman->real_parent_names[0]; + init.num_parents = 1; + init.name = data->name; + init.ops = &bcm2835_pll_clk_ops; +@@ -1337,18 +1366,22 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman, + struct bcm2835_clock *clock; + struct clk_init_data init; + const char *parents[1 << CM_SRC_BITS]; +- size_t i; ++ size_t i, j; + int ret; + + /* +- * Replace our "xosc" references with the oscillator's +- * actual name. ++ * Replace our strings referencing parent clocks with the ++ * actual clock-output-name of the parent. + */ + for (i = 0; i < data->num_mux_parents; i++) { +- if (strcmp(data->parents[i], "xosc") == 0) +- parents[i] = cprman->osc_name; +- else +- parents[i] = data->parents[i]; ++ parents[i] = data->parents[i]; ++ ++ for (j = 0; j < ARRAY_SIZE(cprman_parent_names); j++) { ++ if (strcmp(parents[i], cprman_parent_names[j]) == 0) { ++ parents[i] = cprman->real_parent_names[j]; ++ break; ++ } ++ } + } + + memset(&init, 0, sizeof(init)); +@@ -1484,6 +1517,47 @@ static const char *const bcm2835_clock_vpu_parents[] = { + __VA_ARGS__) + + /* ++ * DSI parent clocks. The DSI byte/DDR/DDR2 clocks come from the DSI ++ * analog PHY. The _inv variants are generated internally to cprman, ++ * but we don't use them so they aren't hooked up. ++ */ ++static const char *const bcm2835_clock_dsi0_parents[] = { ++ "gnd", ++ "xosc", ++ "testdebug0", ++ "testdebug1", ++ "dsi0_ddr", ++ "dsi0_ddr_inv", ++ "dsi0_ddr2", ++ "dsi0_ddr2_inv", ++ "dsi0_byte", ++ "dsi0_byte_inv", ++}; ++ ++static const char *const bcm2835_clock_dsi1_parents[] = { ++ "gnd", ++ "xosc", ++ "testdebug0", ++ "testdebug1", ++ "dsi1_ddr", ++ "dsi1_ddr_inv", ++ "dsi1_ddr2", ++ "dsi1_ddr2_inv", ++ "dsi1_byte", ++ "dsi1_byte_inv", ++}; ++ ++#define REGISTER_DSI0_CLK(...) REGISTER_CLK( \ ++ .num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi0_parents), \ ++ .parents = bcm2835_clock_dsi0_parents, \ ++ __VA_ARGS__) ++ ++#define REGISTER_DSI1_CLK(...) REGISTER_CLK( \ ++ .num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi1_parents), \ ++ .parents = bcm2835_clock_dsi1_parents, \ ++ __VA_ARGS__) ++ ++/* + * the real definition of all the pll, pll_dividers and clocks + * these make use of the above REGISTER_* macros + */ +@@ -1946,6 +2020,18 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .div_reg = CM_DSI1EDIV, + .int_bits = 4, + .frac_bits = 8), ++ [BCM2835_CLOCK_DSI0P] = REGISTER_DSI0_CLK( ++ .name = "dsi0p", ++ .ctl_reg = CM_DSI0PCTL, ++ .div_reg = CM_DSI0PDIV, ++ .int_bits = 0, ++ .frac_bits = 0), ++ [BCM2835_CLOCK_DSI1P] = REGISTER_DSI1_CLK( ++ .name = "dsi1p", ++ .ctl_reg = CM_DSI1PCTL, ++ .div_reg = CM_DSI1PDIV, ++ .int_bits = 0, ++ .frac_bits = 0), + + /* the gates */ + +@@ -2036,8 +2122,19 @@ static int bcm2835_clk_probe(struct platform_device *pdev) + i++) + bcm2835_clk_claimed[clk_id]= true; + +- cprman->osc_name = of_clk_get_parent_name(dev->of_node, 0); +- if (!cprman->osc_name) ++ memcpy(cprman->real_parent_names, cprman_parent_names, ++ sizeof(cprman_parent_names)); ++ of_clk_parent_fill(dev->of_node, cprman->real_parent_names, ++ ARRAY_SIZE(cprman_parent_names)); ++ ++ /* ++ * Make sure the external oscillator has been registered. ++ * ++ * The other (DSI) clocks are not present on older device ++ * trees, which we still need to support for backwards ++ * compatibility. ++ */ ++ if (!cprman->real_parent_names[0]) + return -ENODEV; + + platform_set_drvdata(pdev, cprman); +diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h +index 360e00cefd35679b49890234b5c369fb52b89e20..a0c812b0fa391d149b4f546db39bdc4bef207960 100644 +--- a/include/dt-bindings/clock/bcm2835.h ++++ b/include/dt-bindings/clock/bcm2835.h +@@ -64,3 +64,5 @@ + #define BCM2835_CLOCK_CAM1 46 + #define BCM2835_CLOCK_DSI0E 47 + #define BCM2835_CLOCK_DSI1E 48 ++#define BCM2835_CLOCK_DSI0P 49 ++#define BCM2835_CLOCK_DSI1P 50 + +From 833c4754e30a0214e8a70b497238f0e0866bad29 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 18 Jan 2017 07:31:57 +1100 +Subject: [PATCH 168/190] clk: bcm2835: Add leaf clock measurement support, + disabled by default + +This proved incredibly useful during debugging of the DSI driver, to +see if our clocks were running at rate we requested. Let's leave it +here for the next person interacting with clocks on the platform (and +so that hopefully we can just hook it up to debugfs some day). + +Signed-off-by: Eric Anholt +Signed-off-by: Stephen Boyd +(cherry picked from commit 3f9195811d8d829556c4cd88d3f9e56a80d5ba60) +--- + drivers/clk/bcm/clk-bcm2835.c | 144 ++++++++++++++++++++++++++++++++++-------- + 1 file changed, 119 insertions(+), 25 deletions(-) + +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index 428e75c8b970897d881b570228eb85e8aef28999..fe3298b54cdfb96bd90fb4f39e13921d2e1d4356 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -99,7 +100,8 @@ + #define CM_SMIDIV 0x0b4 + /* no definition for 0x0b8 and 0x0bc */ + #define CM_TCNTCTL 0x0c0 +-#define CM_TCNTDIV 0x0c4 ++# define CM_TCNT_SRC1_SHIFT 12 ++#define CM_TCNTCNT 0x0c4 + #define CM_TECCTL 0x0c8 + #define CM_TECDIV 0x0cc + #define CM_TD0CTL 0x0d0 +@@ -342,6 +344,61 @@ static inline u32 cprman_read(struct bcm2835_cprman *cprman, u32 reg) + return readl(cprman->regs + reg); + } + ++/* Does a cycle of measuring a clock through the TCNT clock, which may ++ * source from many other clocks in the system. ++ */ ++static unsigned long bcm2835_measure_tcnt_mux(struct bcm2835_cprman *cprman, ++ u32 tcnt_mux) ++{ ++ u32 osccount = 19200; /* 1ms */ ++ u32 count; ++ ktime_t timeout; ++ ++ spin_lock(&cprman->regs_lock); ++ ++ cprman_write(cprman, CM_TCNTCTL, CM_KILL); ++ ++ cprman_write(cprman, CM_TCNTCTL, ++ (tcnt_mux & CM_SRC_MASK) | ++ (tcnt_mux >> CM_SRC_BITS) << CM_TCNT_SRC1_SHIFT); ++ ++ cprman_write(cprman, CM_OSCCOUNT, osccount); ++ ++ /* do a kind delay at the start */ ++ mdelay(1); ++ ++ /* Finish off whatever is left of OSCCOUNT */ ++ timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS); ++ while (cprman_read(cprman, CM_OSCCOUNT)) { ++ if (ktime_after(ktime_get(), timeout)) { ++ dev_err(cprman->dev, "timeout waiting for OSCCOUNT\n"); ++ count = 0; ++ goto out; ++ } ++ cpu_relax(); ++ } ++ ++ /* Wait for BUSY to clear. */ ++ timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS); ++ while (cprman_read(cprman, CM_TCNTCTL) & CM_BUSY) { ++ if (ktime_after(ktime_get(), timeout)) { ++ dev_err(cprman->dev, "timeout waiting for !BUSY\n"); ++ count = 0; ++ goto out; ++ } ++ cpu_relax(); ++ } ++ ++ count = cprman_read(cprman, CM_TCNTCNT); ++ ++ cprman_write(cprman, CM_TCNTCTL, 0); ++ ++out: ++ spin_unlock(&cprman->regs_lock); ++ ++ return count * 1000; ++} ++ + static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base, + struct debugfs_reg32 *regs, size_t nregs, + struct dentry *dentry) +@@ -477,6 +534,8 @@ struct bcm2835_clock_data { + + bool is_vpu_clock; + bool is_mash_clock; ++ ++ u32 tcnt_mux; + }; + + struct bcm2835_gate_data { +@@ -1038,6 +1097,17 @@ static int bcm2835_clock_on(struct clk_hw *hw) + CM_GATE); + spin_unlock(&cprman->regs_lock); + ++ /* Debug code to measure the clock once it's turned on to see ++ * if it's ticking at the rate we expect. ++ */ ++ if (data->tcnt_mux && false) { ++ dev_info(cprman->dev, ++ "clk %s: rate %ld, measure %ld\n", ++ data->name, ++ clk_hw_get_rate(hw), ++ bcm2835_measure_tcnt_mux(cprman, data->tcnt_mux)); ++ } ++ + return 0; + } + +@@ -1816,7 +1886,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .ctl_reg = CM_OTPCTL, + .div_reg = CM_OTPDIV, + .int_bits = 4, +- .frac_bits = 0), ++ .frac_bits = 0, ++ .tcnt_mux = 6), + /* + * Used for a 1Mhz clock for the system clocksource, and also used + * bythe watchdog timer and the camera pulse generator. +@@ -1850,13 +1921,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .ctl_reg = CM_H264CTL, + .div_reg = CM_H264DIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 1), + [BCM2835_CLOCK_ISP] = REGISTER_VPU_CLK( + .name = "isp", + .ctl_reg = CM_ISPCTL, + .div_reg = CM_ISPDIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 2), + + /* + * Secondary SDRAM clock. Used for low-voltage modes when the PLL +@@ -1867,13 +1940,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .ctl_reg = CM_SDCCTL, + .div_reg = CM_SDCDIV, + .int_bits = 6, +- .frac_bits = 0), ++ .frac_bits = 0, ++ .tcnt_mux = 3), + [BCM2835_CLOCK_V3D] = REGISTER_VPU_CLK( + .name = "v3d", + .ctl_reg = CM_V3DCTL, + .div_reg = CM_V3DDIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 4), + /* + * VPU clock. This doesn't have an enable bit, since it drives + * the bus for everything else, and is special so it doesn't need +@@ -1887,7 +1962,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .int_bits = 12, + .frac_bits = 8, + .flags = CLK_IS_CRITICAL, +- .is_vpu_clock = true), ++ .is_vpu_clock = true, ++ .tcnt_mux = 5), + + /* clocks with per parent mux */ + [BCM2835_CLOCK_AVEO] = REGISTER_PER_CLK( +@@ -1895,19 +1971,22 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .ctl_reg = CM_AVEOCTL, + .div_reg = CM_AVEODIV, + .int_bits = 4, +- .frac_bits = 0), ++ .frac_bits = 0, ++ .tcnt_mux = 38), + [BCM2835_CLOCK_CAM0] = REGISTER_PER_CLK( + .name = "cam0", + .ctl_reg = CM_CAM0CTL, + .div_reg = CM_CAM0DIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 14), + [BCM2835_CLOCK_CAM1] = REGISTER_PER_CLK( + .name = "cam1", + .ctl_reg = CM_CAM1CTL, + .div_reg = CM_CAM1DIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 15), + [BCM2835_CLOCK_DFT] = REGISTER_PER_CLK( + .name = "dft", + .ctl_reg = CM_DFTCTL, +@@ -1919,7 +1998,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .ctl_reg = CM_DPICTL, + .div_reg = CM_DPIDIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 17), + + /* Arasan EMMC clock */ + [BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK( +@@ -1927,7 +2007,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .ctl_reg = CM_EMMCCTL, + .div_reg = CM_EMMCDIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 39), + + /* General purpose (GPIO) clocks */ + [BCM2835_CLOCK_GP0] = REGISTER_PER_CLK( +@@ -1936,7 +2017,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .div_reg = CM_GP0DIV, + .int_bits = 12, + .frac_bits = 12, +- .is_mash_clock = true), ++ .is_mash_clock = true, ++ .tcnt_mux = 20), + [BCM2835_CLOCK_GP1] = REGISTER_PER_CLK( + .name = "gp1", + .ctl_reg = CM_GP1CTL, +@@ -1944,7 +2026,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .int_bits = 12, + .frac_bits = 12, + .flags = CLK_IS_CRITICAL, +- .is_mash_clock = true), ++ .is_mash_clock = true, ++ .tcnt_mux = 21), + [BCM2835_CLOCK_GP2] = REGISTER_PER_CLK( + .name = "gp2", + .ctl_reg = CM_GP2CTL, +@@ -1959,40 +2042,46 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .ctl_reg = CM_HSMCTL, + .div_reg = CM_HSMDIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 22), + [BCM2835_CLOCK_PCM] = REGISTER_PER_CLK( + .name = "pcm", + .ctl_reg = CM_PCMCTL, + .div_reg = CM_PCMDIV, + .int_bits = 12, + .frac_bits = 12, +- .is_mash_clock = true), ++ .is_mash_clock = true, ++ .tcnt_mux = 23), + [BCM2835_CLOCK_PWM] = REGISTER_PER_CLK( + .name = "pwm", + .ctl_reg = CM_PWMCTL, + .div_reg = CM_PWMDIV, + .int_bits = 12, + .frac_bits = 12, +- .is_mash_clock = true), ++ .is_mash_clock = true, ++ .tcnt_mux = 24), + [BCM2835_CLOCK_SLIM] = REGISTER_PER_CLK( + .name = "slim", + .ctl_reg = CM_SLIMCTL, + .div_reg = CM_SLIMDIV, + .int_bits = 12, + .frac_bits = 12, +- .is_mash_clock = true), ++ .is_mash_clock = true, ++ .tcnt_mux = 25), + [BCM2835_CLOCK_SMI] = REGISTER_PER_CLK( + .name = "smi", + .ctl_reg = CM_SMICTL, + .div_reg = CM_SMIDIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 27), + [BCM2835_CLOCK_UART] = REGISTER_PER_CLK( + .name = "uart", + .ctl_reg = CM_UARTCTL, + .div_reg = CM_UARTDIV, + .int_bits = 10, +- .frac_bits = 12), ++ .frac_bits = 12, ++ .tcnt_mux = 28), + + /* TV encoder clock. Only operating frequency is 108Mhz. */ + [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK( +@@ -2005,7 +2094,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + * Allow rate change propagation only on PLLH_AUX which is + * assigned index 7 in the parent array. + */ +- .set_rate_parent = BIT(7)), ++ .set_rate_parent = BIT(7), ++ .tcnt_mux = 29), + + /* dsi clocks */ + [BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK( +@@ -2013,25 +2103,29 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .ctl_reg = CM_DSI0ECTL, + .div_reg = CM_DSI0EDIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 18), + [BCM2835_CLOCK_DSI1E] = REGISTER_PER_CLK( + .name = "dsi1e", + .ctl_reg = CM_DSI1ECTL, + .div_reg = CM_DSI1EDIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 19), + [BCM2835_CLOCK_DSI0P] = REGISTER_DSI0_CLK( + .name = "dsi0p", + .ctl_reg = CM_DSI0PCTL, + .div_reg = CM_DSI0PDIV, + .int_bits = 0, +- .frac_bits = 0), ++ .frac_bits = 0, ++ .tcnt_mux = 12), + [BCM2835_CLOCK_DSI1P] = REGISTER_DSI1_CLK( + .name = "dsi1p", + .ctl_reg = CM_DSI1PCTL, + .div_reg = CM_DSI1PDIV, + .int_bits = 0, +- .frac_bits = 0), ++ .frac_bits = 0, ++ .tcnt_mux = 13), + + /* the gates */ + + +From 41136c787e4f6a7577b3568df3c38ba78e79c860 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Tue, 26 Apr 2016 13:46:13 -0700 +Subject: [PATCH 169/190] drm/panel: Add support for the Raspberry Pi 7" + Touchscreen. + +This driver communicates with the Atmel microcontroller for sequencing +the poweron of the TC358762 DSI-DPI bridge and controlling the +backlight PWM. + +The following lines are required in config.txt, to keep the firmware +from trying to bash our I2C lines and steal the DSI interrupts: + + disable_touchscreen=1 + ignore_lcd=2 + mask_gpu_interrupt1=0x1000 + +This means that the firmware won't power on the panel at boot time (no +rainbow) and the touchscreen input won't work. The native input +driver for the touchscreen still needs to be written. + +v2: Set the same default orientation as the closed source firmware + used, which is the best for viewing angle. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/panel/Kconfig | 8 + + drivers/gpu/drm/panel/Makefile | 1 + + .../gpu/drm/panel/panel-raspberrypi-touchscreen.c | 514 +++++++++++++++++++++ + 3 files changed, 523 insertions(+) + create mode 100644 drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c + +diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig +index 62aba976e744c146c26d7fedf44c54cdd480361e..de7a56ab758b8f043194391f9b9e43df65c06d0a 100644 +--- a/drivers/gpu/drm/panel/Kconfig ++++ b/drivers/gpu/drm/panel/Kconfig +@@ -52,6 +52,14 @@ config DRM_PANEL_PANASONIC_VVX10F034N00 + WUXGA (1920x1200) Novatek NT1397-based DSI panel as found in some + Xperia Z2 tablets + ++config DRM_PANEL_RASPBERRYPI_TOUCHSCREEN ++ tristate "Raspberry Pi 7-inch touchscreen panel" ++ depends on DRM_MIPI_DSI ++ help ++ Say Y here if you want to enable support for the Raspberry ++ Pi 7" Touchscreen. To compile this driver as a module, ++ choose M here. ++ + config DRM_PANEL_SAMSUNG_S6E8AA0 + tristate "Samsung S6E8AA0 DSI video mode panel" + depends on OF +diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile +index a5c7ec0236e0174079cce0f07d46372967e9cf3b..e8a7ed280fff907e5a730a13ae9a3e5e34cacce4 100644 +--- a/drivers/gpu/drm/panel/Makefile ++++ b/drivers/gpu/drm/panel/Makefile +@@ -2,6 +2,7 @@ obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o + obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o + obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o + obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o ++obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen.o + obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o + obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o + obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o +diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +new file mode 100644 +index 0000000000000000000000000000000000000000..1a536fe4d040f5fafe324baee110a6225dd0be08 +--- /dev/null ++++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +@@ -0,0 +1,514 @@ ++/* ++ * Copyright © 2016 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Portions of this file (derived from panel-simple.c) are: ++ * ++ * Copyright (C) 2013, NVIDIA Corporation. All rights reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sub license, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ */ ++ ++/** ++ * DOC: Raspberry Pi 7" touchscreen panel driver. ++ * ++ * The 7" touchscreen consists of a DPI LCD panel, a Toshiba ++ * TC358762XBG DSI-DPI bridge, and an I2C-connected Atmel ATTINY88-MUR ++ * controlling power management, the LCD PWM, and the touchscreen. ++ * ++ * This driver presents this device as a MIPI DSI panel to the DRM ++ * driver, and should expose the touchscreen as a HID device. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* I2C registers of the Atmel microcontroller. */ ++enum REG_ADDR { ++ REG_ID = 0x80, ++ REG_PORTA, // BIT(2) for horizontal flip, BIT(3) for vertical flip ++ REG_PORTB, ++ REG_PORTC, ++ REG_PORTD, ++ REG_POWERON, ++ REG_PWM, ++ REG_DDRA, ++ REG_DDRB, ++ REG_DDRC, ++ REG_DDRD, ++ REG_TEST, ++ REG_WR_ADDRL, ++ REG_WR_ADDRH, ++ REG_READH, ++ REG_READL, ++ REG_WRITEH, ++ REG_WRITEL, ++ REG_ID2, ++}; ++ ++/* We only turn the PWM on or off, without varying values. */ ++#define RPI_TOUCHSCREEN_MAX_BRIGHTNESS 1 ++ ++/* DSI D-PHY Layer Registers */ ++#define D0W_DPHYCONTTX 0x0004 ++#define CLW_DPHYCONTRX 0x0020 ++#define D0W_DPHYCONTRX 0x0024 ++#define D1W_DPHYCONTRX 0x0028 ++#define COM_DPHYCONTRX 0x0038 ++#define CLW_CNTRL 0x0040 ++#define D0W_CNTRL 0x0044 ++#define D1W_CNTRL 0x0048 ++#define DFTMODE_CNTRL 0x0054 ++ ++/* DSI PPI Layer Registers */ ++#define PPI_STARTPPI 0x0104 ++#define PPI_BUSYPPI 0x0108 ++#define PPI_LINEINITCNT 0x0110 ++#define PPI_LPTXTIMECNT 0x0114 ++//#define PPI_LANEENABLE 0x0134 ++//#define PPI_TX_RX_TA 0x013C ++#define PPI_CLS_ATMR 0x0140 ++#define PPI_D0S_ATMR 0x0144 ++#define PPI_D1S_ATMR 0x0148 ++#define PPI_D0S_CLRSIPOCOUNT 0x0164 ++#define PPI_D1S_CLRSIPOCOUNT 0x0168 ++#define CLS_PRE 0x0180 ++#define D0S_PRE 0x0184 ++#define D1S_PRE 0x0188 ++#define CLS_PREP 0x01A0 ++#define D0S_PREP 0x01A4 ++#define D1S_PREP 0x01A8 ++#define CLS_ZERO 0x01C0 ++#define D0S_ZERO 0x01C4 ++#define D1S_ZERO 0x01C8 ++#define PPI_CLRFLG 0x01E0 ++#define PPI_CLRSIPO 0x01E4 ++#define HSTIMEOUT 0x01F0 ++#define HSTIMEOUTENABLE 0x01F4 ++ ++/* DSI Protocol Layer Registers */ ++#define DSI_STARTDSI 0x0204 ++#define DSI_BUSYDSI 0x0208 ++#define DSI_LANEENABLE 0x0210 ++# define DSI_LANEENABLE_CLOCK BIT(0) ++# define DSI_LANEENABLE_D0 BIT(1) ++# define DSI_LANEENABLE_D1 BIT(2) ++ ++#define DSI_LANESTATUS0 0x0214 ++#define DSI_LANESTATUS1 0x0218 ++#define DSI_INTSTATUS 0x0220 ++#define DSI_INTMASK 0x0224 ++#define DSI_INTCLR 0x0228 ++#define DSI_LPTXTO 0x0230 ++#define DSI_MODE 0x0260 ++#define DSI_PAYLOAD0 0x0268 ++#define DSI_PAYLOAD1 0x026C ++#define DSI_SHORTPKTDAT 0x0270 ++#define DSI_SHORTPKTREQ 0x0274 ++#define DSI_BTASTA 0x0278 ++#define DSI_BTACLR 0x027C ++ ++/* DSI General Registers */ ++#define DSIERRCNT 0x0300 ++#define DSISIGMOD 0x0304 ++ ++/* DSI Application Layer Registers */ ++#define APLCTRL 0x0400 ++#define APLSTAT 0x0404 ++#define APLERR 0x0408 ++#define PWRMOD 0x040C ++#define RDPKTLN 0x0410 ++#define PXLFMT 0x0414 ++#define MEMWRCMD 0x0418 ++ ++/* LCDC/DPI Host Registers */ ++#define LCDCTRL 0x0420 ++#define HSR 0x0424 ++#define HDISPR 0x0428 ++#define VSR 0x042C ++#define VDISPR 0x0430 ++#define VFUEN 0x0434 ++ ++/* DBI-B Host Registers */ ++#define DBIBCTRL 0x0440 ++ ++/* SPI Master Registers */ ++#define SPICMR 0x0450 ++#define SPITCR 0x0454 ++ ++/* System Controller Registers */ ++#define SYSSTAT 0x0460 ++#define SYSCTRL 0x0464 ++#define SYSPLL1 0x0468 ++#define SYSPLL2 0x046C ++#define SYSPLL3 0x0470 ++#define SYSPMCTRL 0x047C ++ ++/* GPIO Registers */ ++#define GPIOC 0x0480 ++#define GPIOO 0x0484 ++#define GPIOI 0x0488 ++ ++/* I2C Registers */ ++#define I2CCLKCTRL 0x0490 ++ ++/* Chip/Rev Registers */ ++#define IDREG 0x04A0 ++ ++/* Debug Registers */ ++#define WCMDQUEUE 0x0500 ++#define RCMDQUEUE 0x0504 ++ ++struct rpi_touchscreen { ++ struct drm_panel base; ++ struct mipi_dsi_device *dsi; ++ struct i2c_client *bridge_i2c; ++ ++ /* Version of the firmware on the bridge chip */ ++ int atmel_ver; ++}; ++ ++static const struct drm_display_mode rpi_touchscreen_modes[] = { ++ { ++ /* The DSI PLL can only integer divide from the 2Ghz ++ * PLLD, giving us few choices. We pick a divide by 3 ++ * as our DSI HS clock, giving us a pixel clock of ++ * that divided by 24 bits. Pad out HFP to get our ++ * panel to refresh at 60Hz, even if that doesn't ++ * match the datasheet. ++ */ ++#define PIXEL_CLOCK ((2000000000 / 3) / 24) ++#define VREFRESH 60 ++#define VTOTAL (480 + 7 + 2 + 21) ++#define HACT 800 ++#define HSW 2 ++#define HBP 46 ++#define HFP ((PIXEL_CLOCK / (VTOTAL * VREFRESH)) - (HACT + HSW + HBP)) ++ ++ .clock = PIXEL_CLOCK / 1000, ++ .hdisplay = HACT, ++ .hsync_start = HACT + HFP, ++ .hsync_end = HACT + HFP + HSW, ++ .htotal = HACT + HFP + HSW + HBP, ++ .vdisplay = 480, ++ .vsync_start = 480 + 7, ++ .vsync_end = 480 + 7 + 2, ++ .vtotal = VTOTAL, ++ .vrefresh = 60, ++ }, ++}; ++ ++static struct rpi_touchscreen *panel_to_ts(struct drm_panel *panel) ++{ ++ return container_of(panel, struct rpi_touchscreen, base); ++} ++ ++static u8 rpi_touchscreen_i2c_read(struct rpi_touchscreen *ts, u8 reg) ++{ ++ return i2c_smbus_read_byte_data(ts->bridge_i2c, reg); ++} ++ ++static void rpi_touchscreen_i2c_write(struct rpi_touchscreen *ts, ++ u8 reg, u8 val) ++{ ++ int ret; ++ ++ ret = i2c_smbus_write_byte_data(ts->bridge_i2c, reg, val); ++ if (ret) ++ dev_err(&ts->dsi->dev, "I2C write failed: %d\n", ret); ++} ++ ++static int rpi_touchscreen_write(struct rpi_touchscreen *ts, u16 reg, u32 val) ++{ ++#if 0 ++ /* The firmware uses LP DSI transactions like this to bring up ++ * the hardware, which should be faster than using I2C to then ++ * pass to the Toshiba. However, I was unable to get it to ++ * work. ++ */ ++ u8 msg[] = { ++ reg, ++ reg >> 8, ++ val, ++ val >> 8, ++ val >> 16, ++ val >> 24, ++ }; ++ ++ mipi_dsi_dcs_write_buffer(ts->dsi, msg, sizeof(msg)); ++#else ++ rpi_touchscreen_i2c_write(ts, REG_WR_ADDRH, reg >> 8); ++ rpi_touchscreen_i2c_write(ts, REG_WR_ADDRL, reg); ++ rpi_touchscreen_i2c_write(ts, REG_WRITEH, val >> 8); ++ rpi_touchscreen_i2c_write(ts, REG_WRITEL, val); ++#endif ++ ++ return 0; ++} ++ ++static int rpi_touchscreen_disable(struct drm_panel *panel) ++{ ++ struct rpi_touchscreen *ts = panel_to_ts(panel); ++ ++ rpi_touchscreen_i2c_write(ts, REG_PWM, 0); ++ ++ rpi_touchscreen_i2c_write(ts, REG_POWERON, 0); ++ udelay(1); ++ ++ return 0; ++} ++ ++static int rpi_touchscreen_noop(struct drm_panel *panel) ++{ ++ return 0; ++} ++ ++static int rpi_touchscreen_enable(struct drm_panel *panel) ++{ ++ struct rpi_touchscreen *ts = panel_to_ts(panel); ++ int i; ++ ++ rpi_touchscreen_i2c_write(ts, REG_POWERON, 1); ++ /* Wait for nPWRDWN to go low to indicate poweron is done. */ ++ for (i = 0; i < 100; i++) { ++ if (rpi_touchscreen_i2c_read(ts, REG_PORTB) & 1) ++ break; ++ } ++ ++ rpi_touchscreen_write(ts, DSI_LANEENABLE, ++ DSI_LANEENABLE_CLOCK | ++ DSI_LANEENABLE_D0 | ++ (ts->dsi->lanes > 1 ? DSI_LANEENABLE_D1 : 0)); ++ rpi_touchscreen_write(ts, PPI_D0S_CLRSIPOCOUNT, 0x05); ++ rpi_touchscreen_write(ts, PPI_D1S_CLRSIPOCOUNT, 0x05); ++ rpi_touchscreen_write(ts, PPI_D0S_ATMR, 0x00); ++ rpi_touchscreen_write(ts, PPI_D1S_ATMR, 0x00); ++ rpi_touchscreen_write(ts, PPI_LPTXTIMECNT, 0x03); ++ ++ rpi_touchscreen_write(ts, SPICMR, 0x00); ++ rpi_touchscreen_write(ts, LCDCTRL, 0x00100150); ++ rpi_touchscreen_write(ts, SYSCTRL, 0x040f); ++ msleep(100); ++ ++ rpi_touchscreen_write(ts, PPI_STARTPPI, 0x01); ++ rpi_touchscreen_write(ts, DSI_STARTDSI, 0x01); ++ msleep(100); ++ ++ /* Turn on the backlight. */ ++ rpi_touchscreen_i2c_write(ts, REG_PWM, 255); ++ ++ /* Default to the same orientation as the closed source ++ * firmware used for the panel. Runtime rotation ++ * configuration will be supported using VC4's plane ++ * orientation bits. ++ */ ++ rpi_touchscreen_i2c_write(ts, REG_PORTA, BIT(2)); ++ ++ return 0; ++} ++ ++static int rpi_touchscreen_get_modes(struct drm_panel *panel) ++{ ++ struct drm_connector *connector = panel->connector; ++ struct drm_device *drm = panel->drm; ++ unsigned int i, num = 0; ++ ++ for (i = 0; i < ARRAY_SIZE(rpi_touchscreen_modes); i++) { ++ const struct drm_display_mode *m = &rpi_touchscreen_modes[i]; ++ struct drm_display_mode *mode; ++ ++ mode = drm_mode_duplicate(drm, m); ++ if (!mode) { ++ dev_err(drm->dev, "failed to add mode %ux%u@%u\n", ++ m->hdisplay, m->vdisplay, m->vrefresh); ++ continue; ++ } ++ ++ mode->type |= DRM_MODE_TYPE_DRIVER; ++ ++ if (i == 0) ++ mode->type |= DRM_MODE_TYPE_PREFERRED; ++ ++ drm_mode_set_name(mode); ++ ++ drm_mode_probed_add(connector, mode); ++ num++; ++ } ++ ++ connector->display_info.bpc = 8; ++ connector->display_info.width_mm = 154; ++ connector->display_info.height_mm = 86; ++ ++ return num; ++} ++ ++static const struct drm_panel_funcs rpi_touchscreen_funcs = { ++ .disable = rpi_touchscreen_disable, ++ .unprepare = rpi_touchscreen_noop, ++ .prepare = rpi_touchscreen_noop, ++ .enable = rpi_touchscreen_enable, ++ .get_modes = rpi_touchscreen_get_modes, ++}; ++ ++static struct i2c_client *rpi_touchscreen_get_i2c(struct device *dev, ++ const char *name) ++{ ++ struct device_node *node; ++ struct i2c_client *client; ++ ++ node = of_parse_phandle(dev->of_node, name, 0); ++ if (!node) ++ return ERR_PTR(-ENODEV); ++ ++ client = of_find_i2c_device_by_node(node); ++ ++ of_node_put(node); ++ ++ return client; ++} ++ ++static int rpi_touchscreen_dsi_probe(struct mipi_dsi_device *dsi) ++{ ++ struct device *dev = &dsi->dev; ++ struct rpi_touchscreen *ts; ++ int ret, ver; ++ ++ ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL); ++ if (!ts) ++ return -ENOMEM; ++ ++ dev_set_drvdata(dev, ts); ++ ++ ts->dsi = dsi; ++ dsi->mode_flags = (MIPI_DSI_MODE_VIDEO | ++ MIPI_DSI_MODE_VIDEO_SYNC_PULSE | ++ MIPI_DSI_MODE_LPM); ++ dsi->format = MIPI_DSI_FMT_RGB888; ++ dsi->lanes = 1; ++ ++ ts->bridge_i2c = ++ rpi_touchscreen_get_i2c(dev, "raspberrypi,touchscreen-bridge"); ++ if (IS_ERR(ts->bridge_i2c)) { ++ ret = -EPROBE_DEFER; ++ return ret; ++ } ++ ++ ver = rpi_touchscreen_i2c_read(ts, REG_ID); ++ if (ver < 0) { ++ dev_err(dev, "Atmel I2C read failed: %d\n", ver); ++ return -ENODEV; ++ } ++ ++ switch (ver) { ++ case 0xde: ++ ts->atmel_ver = 1; ++ break; ++ case 0xc3: ++ ts->atmel_ver = 2; ++ break; ++ default: ++ dev_err(dev, "Unknown Atmel firmware revision: 0x%02x\n", ver); ++ return -ENODEV; ++ } ++ ++ /* Turn off at boot, so we can cleanly sequence powering on. */ ++ rpi_touchscreen_i2c_write(ts, REG_POWERON, 0); ++ ++ drm_panel_init(&ts->base); ++ ts->base.dev = dev; ++ ts->base.funcs = &rpi_touchscreen_funcs; ++ ++ ret = drm_panel_add(&ts->base); ++ if (ret < 0) ++ goto err_release_bridge; ++ ++ return mipi_dsi_attach(dsi); ++ ++err_release_bridge: ++ put_device(&ts->bridge_i2c->dev); ++ return ret; ++} ++ ++static int rpi_touchscreen_dsi_remove(struct mipi_dsi_device *dsi) ++{ ++ struct device *dev = &dsi->dev; ++ struct rpi_touchscreen *ts = dev_get_drvdata(dev); ++ int ret; ++ ++ ret = mipi_dsi_detach(dsi); ++ if (ret < 0) { ++ dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret); ++ return ret; ++ } ++ ++ drm_panel_detach(&ts->base); ++ drm_panel_remove(&ts->base); ++ ++ put_device(&ts->bridge_i2c->dev); ++ ++ return 0; ++} ++ ++static void rpi_touchscreen_dsi_shutdown(struct mipi_dsi_device *dsi) ++{ ++ struct device *dev = &dsi->dev; ++ struct rpi_touchscreen *ts = dev_get_drvdata(dev); ++ ++ rpi_touchscreen_i2c_write(ts, REG_POWERON, 0); ++} ++ ++static const struct of_device_id rpi_touchscreen_of_match[] = { ++ { .compatible = "raspberrypi,touchscreen" }, ++ { } /* sentinel */ ++}; ++MODULE_DEVICE_TABLE(of, rpi_touchscreen_of_match); ++ ++static struct mipi_dsi_driver rpi_touchscreen_driver = { ++ .driver = { ++ .name = "raspberrypi-touchscreen", ++ .of_match_table = rpi_touchscreen_of_match, ++ }, ++ .probe = rpi_touchscreen_dsi_probe, ++ .remove = rpi_touchscreen_dsi_remove, ++ .shutdown = rpi_touchscreen_dsi_shutdown, ++}; ++module_mipi_dsi_driver(rpi_touchscreen_driver); ++ ++MODULE_AUTHOR("Eric Anholt "); ++MODULE_DESCRIPTION("Raspberry Pi 7-inch touchscreen driver"); ++MODULE_LICENSE("GPL v2"); + +From d09977bb38e54a34541e221bb849fb40b1d403ff Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 2 Jun 2016 12:29:45 -0700 +Subject: [PATCH 170/190] BCM270X: Add the DSI panel to the defconfig. + +Signed-off-by: Eric Anholt +--- + arch/arm/configs/bcm2709_defconfig | 2 ++ + arch/arm/configs/bcmrpi_defconfig | 2 ++ + arch/arm64/configs/bcmrpi3_defconfig | 2 ++ + 3 files changed, 6 insertions(+) + +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index 97375c26f2d70d0c4f3956622f839dcf04463e31..d3fd0252f78ec72bd6d93322e781abc3609af01c 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -833,6 +833,8 @@ CONFIG_VIDEO_OV7640=m + CONFIG_VIDEO_MT9V011=m + CONFIG_DRM=m + CONFIG_DRM_LOAD_EDID_FIRMWARE=y ++CONFIG_DRM_PANEL_SIMPLE=m ++CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m + CONFIG_DRM_UDL=m + CONFIG_DRM_VC4=m + CONFIG_FB=y +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index 0e2c3679d9614d331db39cd25ae9095136d3190a..0768998e5cbcc96714d546f656ff59eafe2dc754 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -826,6 +826,8 @@ CONFIG_VIDEO_OV7640=m + CONFIG_VIDEO_MT9V011=m + CONFIG_DRM=m + CONFIG_DRM_LOAD_EDID_FIRMWARE=y ++CONFIG_DRM_PANEL_SIMPLE=m ++CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m + CONFIG_DRM_UDL=m + CONFIG_DRM_VC4=m + CONFIG_FB=y +diff --git a/arch/arm64/configs/bcmrpi3_defconfig b/arch/arm64/configs/bcmrpi3_defconfig +index 4d85c231c5ea0244e1b05fb4a5e3c8fd3e651ddf..baf316e3a69d421d79ec098c7ad2603c906782df 100644 +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -812,6 +812,8 @@ CONFIG_VIDEO_OV7640=m + CONFIG_VIDEO_MT9V011=m + CONFIG_DRM=m + CONFIG_DRM_LOAD_EDID_FIRMWARE=y ++CONFIG_DRM_PANEL_SIMPLE=m ++CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m + CONFIG_DRM_UDL=m + CONFIG_DRM_VC4=m + CONFIG_FB=y + +From fb03cba6b7f53fa9fbc524d2b9ebf0e86d15dad2 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Tue, 13 Dec 2016 15:15:10 -0800 +Subject: [PATCH 171/190] ARM: bcm2835: dt: Add the DSI module nodes and + clocks. + +The modules stay disabled by default, and if you want to enable DSI +you'll need an overlay that connects a panel to it. + +Signed-off-by: Eric Anholt +--- + arch/arm/boot/dts/bcm2835-rpi.dtsi | 8 +++++++ + arch/arm/boot/dts/bcm283x.dtsi | 49 +++++++++++++++++++++++++++++++++++--- + 2 files changed, 54 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi +index 6ddf7dfe3f7202642cc4d595ff4763f91248c0a5..58f7d874c70a9cf965e10ae3f14fe3bb00846b71 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi +@@ -87,3 +87,11 @@ + power-domains = <&power RPI_POWER_DOMAIN_HDMI>; + status = "okay"; + }; ++ ++&dsi0 { ++ power-domains = <&power RPI_POWER_DOMAIN_DSI0>; ++}; ++ ++&dsi1 { ++ power-domains = <&power RPI_POWER_DOMAIN_DSI1>; ++}; +diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi +index b710a4d67b8ec8c8c18ce8efb6f270e7cfb68e52..304dd291a9ae94700e8e628c0c9ebd3fb98abb19 100644 +--- a/arch/arm/boot/dts/bcm283x.dtsi ++++ b/arch/arm/boot/dts/bcm283x.dtsi +@@ -93,10 +93,13 @@ + #clock-cells = <1>; + reg = <0x7e101000 0x2000>; + +- /* CPRMAN derives everything from the platform's +- * oscillator. ++ /* CPRMAN derives almost everything from the ++ * platform's oscillator. However, the DSI ++ * pixel clocks come from the DSI analog PHY. + */ +- clocks = <&clk_osc>; ++ clocks = <&clk_osc>, ++ <&dsi0 0>, <&dsi0 1>, <&dsi0 2>, ++ <&dsi1 0>, <&dsi1 1>, <&dsi1 2>; + }; + + rng@7e104000 { +@@ -391,6 +394,26 @@ + interrupts = <2 14>; /* pwa1 */ + }; + ++ dsi0: dsi@7e209000 { ++ compatible = "brcm,bcm2835-dsi0"; ++ reg = <0x7e209000 0x78>; ++ interrupts = <2 4>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #clock-cells = <1>; ++ ++ clocks = <&clocks BCM2835_PLLA_DSI0>, ++ <&clocks BCM2835_CLOCK_DSI0E>, ++ <&clocks BCM2835_CLOCK_DSI0P>; ++ clock-names = "phy", "escape", "pixel"; ++ ++ clock-output-names = "dsi0_byte", ++ "dsi0_ddr2", ++ "dsi0_ddr"; ++ ++ status = "disabled"; ++ }; ++ + thermal: thermal@7e212000 { + compatible = "brcm,bcm2835-thermal"; + reg = <0x7e212000 0x8>; +@@ -457,6 +480,26 @@ + interrupts = <2 1>; + }; + ++ dsi1: dsi@7e700000 { ++ compatible = "brcm,bcm2835-dsi1"; ++ reg = <0x7e700000 0x8c>; ++ interrupts = <2 12>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #clock-cells = <1>; ++ ++ clocks = <&clocks BCM2835_PLLD_DSI1>, ++ <&clocks BCM2835_CLOCK_DSI1E>, ++ <&clocks BCM2835_CLOCK_DSI1P>; ++ clock-names = "phy", "escape", "pixel"; ++ ++ clock-output-names = "dsi1_byte", ++ "dsi1_ddr2", ++ "dsi1_ddr"; ++ ++ status = "disabled"; ++ }; ++ + i2c1: i2c@7e804000 { + compatible = "brcm,bcm2835-i2c"; + reg = <0x7e804000 0x1000>; + +From 39f1530e82f569ce44aa1cbeba88ae4385b423cc Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 2 Jun 2016 15:09:35 -0700 +Subject: [PATCH 172/190] BCM270X: Enable the DSI panel node in the VC4 + overlay. + +Signed-off-by: Eric Anholt +--- + arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 5 ++++ + arch/arm/boot/dts/bcm2708-rpi-b.dts | 5 ++++ + arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 5 ++++ + arch/arm/boot/dts/bcm270x.dtsi | 27 ++++++++++++++++++++++ + arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 5 ++++ + arch/arm/boot/dts/bcm2710.dtsi | 1 - + arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 23 +++++++++++++++++- + 7 files changed, 69 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts +index 0b66ac9f25a5f7ae51f3d0666cfcb908f85e1d24..08bf838fab551638e898930fba7ba49b3aeefbb3 100644 +--- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts +@@ -155,3 +155,8 @@ + sd_debug = <&sdhost>,"brcm,debug"; + }; + }; ++ ++&i2c_dsi { ++ gpios = <&gpio 28 0 ++ &gpio 29 0>; ++}; +diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts +index e99e9d999e4142060c41eb47b93c8ac70a30f384..4e6b4dd6a8d9c4f13bc865bb8ced68264162cb6c 100644 +--- a/arch/arm/boot/dts/bcm2708-rpi-b.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts +@@ -145,3 +145,8 @@ + sd_debug = <&sdhost>,"brcm,debug"; + }; + }; ++ ++&i2c_dsi { ++ gpios = <&gpio 2 0 ++ &gpio 3 0>; ++}; +diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts +index 20674f250af922e9f9a43e3e8b13aee42e3930be..2dc0e1204e6374bbc6924e26dc4a04b68718559a 100644 +--- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts ++++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts +@@ -155,3 +155,8 @@ + sd_debug = <&sdhost>,"brcm,debug"; + }; + }; ++ ++&i2c_dsi { ++ gpios = <&gpio 28 0 ++ &gpio 29 0>; ++}; +diff --git a/arch/arm/boot/dts/bcm270x.dtsi b/arch/arm/boot/dts/bcm270x.dtsi +index 36d853715f2379e1952ce3d3be58dd670e305159..caa66393518603529d284f360b2000b0ed4852ef 100644 +--- a/arch/arm/boot/dts/bcm270x.dtsi ++++ b/arch/arm/boot/dts/bcm270x.dtsi +@@ -137,6 +137,29 @@ + /* Add alias */ + status = "disabled"; + }; ++ ++ i2c_dsi: i2cdsi { ++ /* We have to use i2c-gpio because the ++ * firmware is also polling another device ++ * using the only hardware I2C bus that could ++ * connect to these pins. ++ */ ++ compatible = "i2c-gpio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ ++ pitouchscreen_bridge: bridge@45 { ++ compatible = "raspberrypi,touchscreen-bridge-i2c"; ++ reg = <0x45>; ++ }; ++ ++ pitouchscreen_touch: bridge@38 { ++ compatible = "raspberrypi,touchscreen-ts-i2c"; ++ reg = <0x38>; ++ }; ++ }; ++ + }; + + vdd_5v0_reg: fixedregulator_5v0 { +@@ -155,3 +178,7 @@ + regulator-always-on; + }; + }; ++ ++&dsi1 { ++ power-domains = <&power RPI_POWER_DOMAIN_DSI1>; ++}; +diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +index 616cfd5c7094596b497101e8feca25e25e77c3e8..173103aaca503833b5e29530ed94e14c7cab0444 100644 +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +@@ -224,3 +224,8 @@ + sd_debug = <&sdhost>,"brcm,debug"; + }; + }; ++ ++&i2c_dsi { ++ gpios = <&gpio 44 0 ++ &gpio 45 0>; ++}; +diff --git a/arch/arm/boot/dts/bcm2710.dtsi b/arch/arm/boot/dts/bcm2710.dtsi +index 3e134a1208610b90e2d0fc22f03c6e9f372bfcd7..3fabac6a93e846f678d846637c4f9a5f5b8e7922 100644 +--- a/arch/arm/boot/dts/bcm2710.dtsi ++++ b/arch/arm/boot/dts/bcm2710.dtsi +@@ -145,4 +145,3 @@ + interrupt-parent = <&local_intc>; + interrupts = <8>; + }; +- +diff --git a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts +index fb45c6456b181b047d6cff8784f7696eb75da3c7..05faf1bfa1b7c73fd60b1efb813b969e10bbfefa 100644 +--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts ++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts +@@ -128,8 +128,29 @@ + }; + }; + +- + fragment@16 { ++ target = <&dsi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pitouchscreen: panel@0 { ++ compatible = "raspberrypi,touchscreen"; ++ reg = <0>; ++ raspberrypi,touchscreen-bridge = <&pitouchscreen_bridge>; ++ }; ++ }; ++ }; ++ ++ fragment@17 { ++ target = <&i2c_dsi>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@18 { + target = <&clocks>; + __overlay__ { + claim-clocks = < + +From e538449b34f8dd973e0ffc8ba2d43bfcedb08127 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 15 Sep 2016 15:25:23 +0100 +Subject: [PATCH 173/190] drm/vc4: Set up SCALER_DISPCTRL at boot. + +We want the HVS on, obviously, and we also want DSP3 (PV1's source) to +be muxed from HVS channel 2 like we expect in vc4_crtc.c. The +firmware wasn't setting the DSP3 mux up when both the LCD and HDMI +were disabled. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_hvs.c | 14 ++++++++++++++ + drivers/gpu/drm/vc4/vc4_regs.h | 3 +++ + 2 files changed, 17 insertions(+) + +diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c +index 6fbab1c82cb1089bde0834f3e0bf1fdf99f54221..fc68b1b4da5249ce3181d7eabb0a08bf8e4908cf 100644 +--- a/drivers/gpu/drm/vc4/vc4_hvs.c ++++ b/drivers/gpu/drm/vc4/vc4_hvs.c +@@ -170,6 +170,7 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) + struct vc4_dev *vc4 = drm->dev_private; + struct vc4_hvs *hvs = NULL; + int ret; ++ u32 dispctrl; + + hvs = devm_kzalloc(&pdev->dev, sizeof(*hvs), GFP_KERNEL); + if (!hvs) +@@ -211,6 +212,19 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) + return ret; + + vc4->hvs = hvs; ++ ++ dispctrl = HVS_READ(SCALER_DISPCTRL); ++ ++ dispctrl |= SCALER_DISPCTRL_ENABLE; ++ ++ /* Set DSP3 (PV1) to use HVS channel 2, which would otherwise ++ * be unused. ++ */ ++ dispctrl &= ~SCALER_DISPCTRL_DSP3_MUX_MASK; ++ dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_DSP3_MUX); ++ ++ HVS_WRITE(SCALER_DISPCTRL, dispctrl); ++ + return 0; + } + +diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h +index 39f6886b24100c43b590e47e0c7bc44846721d65..b3b297fba7097bc495fa8916292c547925720199 100644 +--- a/drivers/gpu/drm/vc4/vc4_regs.h ++++ b/drivers/gpu/drm/vc4/vc4_regs.h +@@ -244,6 +244,9 @@ + # define SCALER_DISPCTRL_ENABLE BIT(31) + # define SCALER_DISPCTRL_DSP2EISLUR BIT(15) + # define SCALER_DISPCTRL_DSP1EISLUR BIT(14) ++# define SCALER_DISPCTRL_DSP3_MUX_MASK VC4_MASK(19, 18) ++# define SCALER_DISPCTRL_DSP3_MUX_SHIFT 18 ++ + /* Enables Display 0 short line and underrun contribution to + * SCALER_DISPSTAT_IRQDISP0. Note that short frame contributions are + * always enabled. + +From dd949d3de2e21d3772e3ef5b10dff39f5806174c Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 10 Feb 2016 16:17:29 -0800 +Subject: [PATCH 174/190] drm/vc4: Add support for feeding DSI encoders from + the pixel valve. + +We have to set a different pixel format, which tells the hardware to +use the pix_width field that's fed in sideband from the DSI encoder to +divide the "pixel" clock. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_crtc.c | 33 +++++++++++++++++++-------------- + drivers/gpu/drm/vc4/vc4_regs.h | 2 ++ + 2 files changed, 21 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c +index bdf32c572fc2c46932daca934dfb002d05493883..0a861158740586836d2d47cccae4109ad4ec968d 100644 +--- a/drivers/gpu/drm/vc4/vc4_crtc.c ++++ b/drivers/gpu/drm/vc4/vc4_crtc.c +@@ -352,38 +352,40 @@ static u32 vc4_get_fifo_full_level(u32 format) + } + + /* +- * Returns the clock select bit for the connector attached to the +- * CRTC. ++ * Returns the encoder attached to the CRTC. ++ * ++ * VC4 can only scan out to one encoder at a time, while the DRM core ++ * allows drivers to push pixels to more than one encoder from the ++ * same CRTC. + */ +-static int vc4_get_clock_select(struct drm_crtc *crtc) ++static struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc) + { + struct drm_connector *connector; + + drm_for_each_connector(connector, crtc->dev) { + if (connector->state->crtc == crtc) { +- struct drm_encoder *encoder = connector->encoder; +- struct vc4_encoder *vc4_encoder = +- to_vc4_encoder(encoder); +- +- return vc4_encoder->clock_select; ++ return connector->encoder; + } + } + +- return -1; ++ return NULL; + } + + static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc) + { + struct drm_device *dev = crtc->dev; + struct vc4_dev *vc4 = to_vc4_dev(dev); ++ struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc); ++ struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); + struct drm_crtc_state *state = crtc->state; + struct drm_display_mode *mode = &state->adjusted_mode; + bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE; + u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1; +- u32 format = PV_CONTROL_FORMAT_24; ++ bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 || ++ vc4_encoder->type == VC4_ENCODER_TYPE_DSI1); ++ u32 format = is_dsi ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24; + bool debug_dump_regs = false; +- int clock_select = vc4_get_clock_select(crtc); + + if (debug_dump_regs) { + DRM_INFO("CRTC %d regs before:\n", drm_crtc_index(crtc)); +@@ -439,17 +441,19 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc) + */ + CRTC_WRITE(PV_V_CONTROL, + PV_VCONTROL_CONTINUOUS | ++ (is_dsi ? PV_VCONTROL_DSI : 0) | + PV_VCONTROL_INTERLACE | + VC4_SET_FIELD(mode->htotal * pixel_rep / 2, + PV_VCONTROL_ODD_DELAY)); + CRTC_WRITE(PV_VSYNCD_EVEN, 0); + } else { +- CRTC_WRITE(PV_V_CONTROL, PV_VCONTROL_CONTINUOUS); ++ CRTC_WRITE(PV_V_CONTROL, ++ PV_VCONTROL_CONTINUOUS | ++ (is_dsi ? PV_VCONTROL_DSI : 0)); + } + + CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep); + +- + CRTC_WRITE(PV_CONTROL, + VC4_SET_FIELD(format, PV_CONTROL_FORMAT) | + VC4_SET_FIELD(vc4_get_fifo_full_level(format), +@@ -458,7 +462,8 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc) + PV_CONTROL_CLR_AT_START | + PV_CONTROL_TRIGGER_UNDERFLOW | + PV_CONTROL_WAIT_HSTART | +- VC4_SET_FIELD(clock_select, PV_CONTROL_CLK_SELECT) | ++ VC4_SET_FIELD(vc4_encoder->clock_select, ++ PV_CONTROL_CLK_SELECT) | + PV_CONTROL_FIFO_CLR | + PV_CONTROL_EN); + +diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h +index b3b297fba7097bc495fa8916292c547925720199..385405a2df05eb3dd86d4f687aa8205331bec3cc 100644 +--- a/drivers/gpu/drm/vc4/vc4_regs.h ++++ b/drivers/gpu/drm/vc4/vc4_regs.h +@@ -190,6 +190,8 @@ + # define PV_VCONTROL_ODD_DELAY_SHIFT 6 + # define PV_VCONTROL_ODD_FIRST BIT(5) + # define PV_VCONTROL_INTERLACE BIT(4) ++# define PV_VCONTROL_DSI BIT(3) ++# define PV_VCONTROL_COMMAND BIT(2) + # define PV_VCONTROL_CONTINUOUS BIT(1) + # define PV_VCONTROL_VIDEN BIT(0) + + +From a7210ce30157876d38751e4096358eae0345588d Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 10 Feb 2016 11:42:32 -0800 +Subject: [PATCH 175/190] drm/vc4: Add DSI driver + +The DSI0 and DSI1 blocks on the 2835 are related hardware blocks. +Some registers move around, and the featureset is slightly different, +as DSI1 (the 4-lane DSI) is a later version of the hardware block. +This driver doesn't yet enable DSI0, since we don't have any hardware +to test against, but it does put a lot of the register definitions and +code in place. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/Kconfig | 2 + + drivers/gpu/drm/vc4/Makefile | 1 + + drivers/gpu/drm/vc4/vc4_debugfs.c | 1 + + drivers/gpu/drm/vc4/vc4_drv.c | 1 + + drivers/gpu/drm/vc4/vc4_drv.h | 5 + + drivers/gpu/drm/vc4/vc4_dsi.c | 1725 +++++++++++++++++++++++++++++++++++++ + 6 files changed, 1735 insertions(+) + create mode 100644 drivers/gpu/drm/vc4/vc4_dsi.c + +diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig +index e53df59cb139f25f8e6ae916bca93abf0c49e063..e1517d07cb7d22776ca164a5d2d9b87e55a5563a 100644 +--- a/drivers/gpu/drm/vc4/Kconfig ++++ b/drivers/gpu/drm/vc4/Kconfig +@@ -2,10 +2,12 @@ config DRM_VC4 + tristate "Broadcom VC4 Graphics" + depends on ARCH_BCM2835 || COMPILE_TEST + depends on DRM ++ depends on COMMON_CLK + select DRM_KMS_HELPER + select DRM_KMS_CMA_HELPER + select DRM_GEM_CMA_HELPER + select DRM_PANEL ++ select DRM_MIPI_DSI + help + Choose this option if you have a system that has a Broadcom + VC4 GPU, such as the Raspberry Pi or other BCM2708/BCM2835. +diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile +index 3358ec8775cf6e8738ea8cdb2246dad57bd29139..897f658bee287f84f7dde8dca43090ad5541495b 100644 +--- a/drivers/gpu/drm/vc4/Makefile ++++ b/drivers/gpu/drm/vc4/Makefile +@@ -8,6 +8,7 @@ vc4-y := \ + vc4_crtc.o \ + vc4_drv.o \ + vc4_dpi.o \ ++ vc4_dsi.o \ + vc4_firmware_kms.o \ + vc4_kms.o \ + vc4_gem.o \ +diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c b/drivers/gpu/drm/vc4/vc4_debugfs.c +index caf817bac8852c82f0d6a34b676a649c10e6e6cd..3ca476c6e0578e5fbe60d4fd623b09f8f937c0b7 100644 +--- a/drivers/gpu/drm/vc4/vc4_debugfs.c ++++ b/drivers/gpu/drm/vc4/vc4_debugfs.c +@@ -18,6 +18,7 @@ + static const struct drm_info_list vc4_debugfs_list[] = { + {"bo_stats", vc4_bo_stats_debugfs, 0}, + {"dpi_regs", vc4_dpi_debugfs_regs, 0}, ++ {"dsi1_regs", vc4_dsi_debugfs_regs, 0, (void *)(uintptr_t)1}, + {"hdmi_regs", vc4_hdmi_debugfs_regs, 0}, + {"vec_regs", vc4_vec_debugfs_regs, 0}, + {"hvs_regs", vc4_hvs_debugfs_regs, 0}, +diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c +index 44cd22340d82dbd5d094806e777121951f25010a..8666c4f46f1fad3192613c39fbe3aeb07b86bc68 100644 +--- a/drivers/gpu/drm/vc4/vc4_drv.c ++++ b/drivers/gpu/drm/vc4/vc4_drv.c +@@ -296,6 +296,7 @@ static struct platform_driver *const component_drivers[] = { + &vc4_hdmi_driver, + &vc4_vec_driver, + &vc4_dpi_driver, ++ &vc4_dsi_driver, + &vc4_hvs_driver, + &vc4_crtc_driver, + &vc4_firmware_kms_driver, +diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h +index 61a9b3e81823a3c96f36f710329844cc032e2628..44a8e6fda2b576fed63d93ef34e076cebf90d64c 100644 +--- a/drivers/gpu/drm/vc4/vc4_drv.h ++++ b/drivers/gpu/drm/vc4/vc4_drv.h +@@ -20,6 +20,7 @@ struct vc4_dev { + struct vc4_crtc *crtc[3]; + struct vc4_v3d *v3d; + struct vc4_dpi *dpi; ++ struct vc4_dsi *dsi1; + struct vc4_vec *vec; + + struct drm_fbdev_cma *fbdev; +@@ -468,6 +469,10 @@ void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index); + extern struct platform_driver vc4_dpi_driver; + int vc4_dpi_debugfs_regs(struct seq_file *m, void *unused); + ++/* vc4_dsi.c */ ++extern struct platform_driver vc4_dsi_driver; ++int vc4_dsi_debugfs_regs(struct seq_file *m, void *unused); ++ + /* vc4_firmware_kms.c */ + extern struct platform_driver vc4_firmware_kms_driver; + void vc4_fkms_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file); +diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c +new file mode 100644 +index 0000000000000000000000000000000000000000..17fcac381dbb37cd9a5ff210ad8578f480177039 +--- /dev/null ++++ b/drivers/gpu/drm/vc4/vc4_dsi.c +@@ -0,0 +1,1725 @@ ++/* ++ * Copyright (C) 2016 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published by ++ * the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program. If not, see . ++ */ ++ ++/** ++ * DOC: VC4 DSI0/DSI1 module ++ * ++ * BCM2835 contains two DSI modules, DSI0 and DSI1. DSI0 is a ++ * single-lane DSI controller, while DSI1 is a more modern 4-lane DSI ++ * controller. ++ * ++ * Most Raspberry Pi boards expose DSI1 as their "DISPLAY" connector, ++ * while the compute module brings both DSI0 and DSI1 out. ++ * ++ * This driver has been tested for DSI1 video-mode display only ++ * currently, with most of the information necessary for DSI0 ++ * hopefully present. ++ */ ++ ++#include "drm_atomic_helper.h" ++#include "drm_crtc_helper.h" ++#include "drm_edid.h" ++#include "drm_mipi_dsi.h" ++#include "drm_panel.h" ++#include "linux/clk.h" ++#include "linux/clk-provider.h" ++#include "linux/completion.h" ++#include "linux/component.h" ++#include "linux/dmaengine.h" ++#include "linux/i2c.h" ++#include "linux/of_address.h" ++#include "linux/of_platform.h" ++#include "linux/pm_runtime.h" ++#include "vc4_drv.h" ++#include "vc4_regs.h" ++ ++#define DSI_CMD_FIFO_DEPTH 16 ++#define DSI_PIX_FIFO_DEPTH 256 ++#define DSI_PIX_FIFO_WIDTH 4 ++ ++#define DSI0_CTRL 0x00 ++ ++/* Command packet control. */ ++#define DSI0_TXPKT1C 0x04 /* AKA PKTC */ ++#define DSI1_TXPKT1C 0x04 ++# define DSI_TXPKT1C_TRIG_CMD_MASK VC4_MASK(31, 24) ++# define DSI_TXPKT1C_TRIG_CMD_SHIFT 24 ++# define DSI_TXPKT1C_CMD_REPEAT_MASK VC4_MASK(23, 10) ++# define DSI_TXPKT1C_CMD_REPEAT_SHIFT 10 ++ ++# define DSI_TXPKT1C_DISPLAY_NO_MASK VC4_MASK(9, 8) ++# define DSI_TXPKT1C_DISPLAY_NO_SHIFT 8 ++/* Short, trigger, BTA, or a long packet that fits all in CMDFIFO. */ ++# define DSI_TXPKT1C_DISPLAY_NO_SHORT 0 ++/* Primary display where cmdfifo provides part of the payload and ++ * pixelvalve the rest. ++ */ ++# define DSI_TXPKT1C_DISPLAY_NO_PRIMARY 1 ++/* Secondary display where cmdfifo provides part of the payload and ++ * pixfifo the rest. ++ */ ++# define DSI_TXPKT1C_DISPLAY_NO_SECONDARY 2 ++ ++# define DSI_TXPKT1C_CMD_TX_TIME_MASK VC4_MASK(7, 6) ++# define DSI_TXPKT1C_CMD_TX_TIME_SHIFT 6 ++ ++# define DSI_TXPKT1C_CMD_CTRL_MASK VC4_MASK(5, 4) ++# define DSI_TXPKT1C_CMD_CTRL_SHIFT 4 ++/* Command only. Uses TXPKT1H and DISPLAY_NO */ ++# define DSI_TXPKT1C_CMD_CTRL_TX 0 ++/* Command with BTA for either ack or read data. */ ++# define DSI_TXPKT1C_CMD_CTRL_RX 1 ++/* Trigger according to TRIG_CMD */ ++# define DSI_TXPKT1C_CMD_CTRL_TRIG 2 ++/* BTA alone for getting error status after a command, or a TE trigger ++ * without a previous command. ++ */ ++# define DSI_TXPKT1C_CMD_CTRL_BTA 3 ++ ++# define DSI_TXPKT1C_CMD_MODE_LP BIT(3) ++# define DSI_TXPKT1C_CMD_TYPE_LONG BIT(2) ++# define DSI_TXPKT1C_CMD_TE_EN BIT(1) ++# define DSI_TXPKT1C_CMD_EN BIT(0) ++ ++/* Command packet header. */ ++#define DSI0_TXPKT1H 0x08 /* AKA PKTH */ ++#define DSI1_TXPKT1H 0x08 ++# define DSI_TXPKT1H_BC_CMDFIFO_MASK VC4_MASK(31, 24) ++# define DSI_TXPKT1H_BC_CMDFIFO_SHIFT 24 ++# define DSI_TXPKT1H_BC_PARAM_MASK VC4_MASK(23, 8) ++# define DSI_TXPKT1H_BC_PARAM_SHIFT 8 ++# define DSI_TXPKT1H_BC_DT_MASK VC4_MASK(7, 0) ++# define DSI_TXPKT1H_BC_DT_SHIFT 0 ++ ++#define DSI0_RXPKT1H 0x0c /* AKA RX1_PKTH */ ++#define DSI1_RXPKT1H 0x14 ++# define DSI_RXPKT1H_CRC_ERR BIT(31) ++# define DSI_RXPKT1H_DET_ERR BIT(30) ++# define DSI_RXPKT1H_ECC_ERR BIT(29) ++# define DSI_RXPKT1H_COR_ERR BIT(28) ++# define DSI_RXPKT1H_INCOMP_PKT BIT(25) ++# define DSI_RXPKT1H_PKT_TYPE_LONG BIT(24) ++/* Byte count if DSI_RXPKT1H_PKT_TYPE_LONG */ ++# define DSI_RXPKT1H_BC_PARAM_MASK VC4_MASK(23, 8) ++# define DSI_RXPKT1H_BC_PARAM_SHIFT 8 ++/* Short return bytes if !DSI_RXPKT1H_PKT_TYPE_LONG */ ++# define DSI_RXPKT1H_SHORT_1_MASK VC4_MASK(23, 16) ++# define DSI_RXPKT1H_SHORT_1_SHIFT 16 ++# define DSI_RXPKT1H_SHORT_0_MASK VC4_MASK(15, 8) ++# define DSI_RXPKT1H_SHORT_0_SHIFT 8 ++# define DSI_RXPKT1H_DT_LP_CMD_MASK VC4_MASK(7, 0) ++# define DSI_RXPKT1H_DT_LP_CMD_SHIFT 0 ++ ++#define DSI0_RXPKT2H 0x10 /* AKA RX2_PKTH */ ++#define DSI1_RXPKT2H 0x18 ++# define DSI_RXPKT1H_DET_ERR BIT(30) ++# define DSI_RXPKT1H_ECC_ERR BIT(29) ++# define DSI_RXPKT1H_COR_ERR BIT(28) ++# define DSI_RXPKT1H_INCOMP_PKT BIT(25) ++# define DSI_RXPKT1H_BC_PARAM_MASK VC4_MASK(23, 8) ++# define DSI_RXPKT1H_BC_PARAM_SHIFT 8 ++# define DSI_RXPKT1H_DT_MASK VC4_MASK(7, 0) ++# define DSI_RXPKT1H_DT_SHIFT 0 ++ ++#define DSI0_TXPKT_CMD_FIFO 0x14 /* AKA CMD_DATAF */ ++#define DSI1_TXPKT_CMD_FIFO 0x1c ++ ++#define DSI0_DISP0_CTRL 0x18 ++# define DSI_DISP0_PIX_CLK_DIV_MASK VC4_MASK(21, 13) ++# define DSI_DISP0_PIX_CLK_DIV_SHIFT 13 ++# define DSI_DISP0_LP_STOP_CTRL_MASK VC4_MASK(12, 11) ++# define DSI_DISP0_LP_STOP_CTRL_SHIFT 11 ++# define DSI_DISP0_LP_STOP_DISABLE 0 ++# define DSI_DISP0_LP_STOP_PERLINE 1 ++# define DSI_DISP0_LP_STOP_PERFRAME 2 ++ ++/* Transmit RGB pixels and null packets only during HACTIVE, instead ++ * of going to LP-STOP. ++ */ ++# define DSI_DISP_HACTIVE_NULL BIT(10) ++/* Transmit blanking packet only during vblank, instead of allowing LP-STOP. */ ++# define DSI_DISP_VBLP_CTRL BIT(9) ++/* Transmit blanking packet only during HFP, instead of allowing LP-STOP. */ ++# define DSI_DISP_HFP_CTRL BIT(8) ++/* Transmit blanking packet only during HBP, instead of allowing LP-STOP. */ ++# define DSI_DISP_HBP_CTRL BIT(7) ++# define DSI_DISP0_CHANNEL_MASK VC4_MASK(6, 5) ++# define DSI_DISP0_CHANNEL_SHIFT 5 ++/* Enables end events for HSYNC/VSYNC, not just start events. */ ++# define DSI_DISP0_ST_END BIT(4) ++# define DSI_DISP0_PFORMAT_MASK VC4_MASK(3, 2) ++# define DSI_DISP0_PFORMAT_SHIFT 2 ++# define DSI_PFORMAT_RGB565 0 ++# define DSI_PFORMAT_RGB666_PACKED 1 ++# define DSI_PFORMAT_RGB666 2 ++# define DSI_PFORMAT_RGB888 3 ++/* Default is VIDEO mode. */ ++# define DSI_DISP0_COMMAND_MODE BIT(1) ++# define DSI_DISP0_ENABLE BIT(0) ++ ++#define DSI0_DISP1_CTRL 0x1c ++#define DSI1_DISP1_CTRL 0x2c ++/* Format of the data written to TXPKT_PIX_FIFO. */ ++# define DSI_DISP1_PFORMAT_MASK VC4_MASK(2, 1) ++# define DSI_DISP1_PFORMAT_SHIFT 1 ++# define DSI_DISP1_PFORMAT_16BIT 0 ++# define DSI_DISP1_PFORMAT_24BIT 1 ++# define DSI_DISP1_PFORMAT_32BIT_LE 2 ++# define DSI_DISP1_PFORMAT_32BIT_BE 3 ++ ++/* DISP1 is always command mode. */ ++# define DSI_DISP1_ENABLE BIT(0) ++ ++#define DSI0_TXPKT_PIX_FIFO 0x20 /* AKA PIX_FIFO */ ++ ++#define DSI0_INT_STAT 0x24 ++#define DSI0_INT_EN 0x28 ++# define DSI1_INT_PHY_D3_ULPS BIT(30) ++# define DSI1_INT_PHY_D3_STOP BIT(29) ++# define DSI1_INT_PHY_D2_ULPS BIT(28) ++# define DSI1_INT_PHY_D2_STOP BIT(27) ++# define DSI1_INT_PHY_D1_ULPS BIT(26) ++# define DSI1_INT_PHY_D1_STOP BIT(25) ++# define DSI1_INT_PHY_D0_ULPS BIT(24) ++# define DSI1_INT_PHY_D0_STOP BIT(23) ++# define DSI1_INT_FIFO_ERR BIT(22) ++# define DSI1_INT_PHY_DIR_RTF BIT(21) ++# define DSI1_INT_PHY_RXLPDT BIT(20) ++# define DSI1_INT_PHY_RXTRIG BIT(19) ++# define DSI1_INT_PHY_D0_LPDT BIT(18) ++# define DSI1_INT_PHY_DIR_FTR BIT(17) ++ ++/* Signaled when the clock lane enters the given state. */ ++# define DSI1_INT_PHY_CLOCK_ULPS BIT(16) ++# define DSI1_INT_PHY_CLOCK_HS BIT(15) ++# define DSI1_INT_PHY_CLOCK_STOP BIT(14) ++ ++/* Signaled on timeouts */ ++# define DSI1_INT_PR_TO BIT(13) ++# define DSI1_INT_TA_TO BIT(12) ++# define DSI1_INT_LPRX_TO BIT(11) ++# define DSI1_INT_HSTX_TO BIT(10) ++ ++/* Contention on a line when trying to drive the line low */ ++# define DSI1_INT_ERR_CONT_LP1 BIT(9) ++# define DSI1_INT_ERR_CONT_LP0 BIT(8) ++ ++/* Control error: incorrect line state sequence on data lane 0. */ ++# define DSI1_INT_ERR_CONTROL BIT(7) ++/* LPDT synchronization error (bits received not a multiple of 8. */ ++ ++# define DSI1_INT_ERR_SYNC_ESC BIT(6) ++/* Signaled after receiving an error packet from the display in ++ * response to a read. ++ */ ++# define DSI1_INT_RXPKT2 BIT(5) ++/* Signaled after receiving a packet. The header and optional short ++ * response will be in RXPKT1H, and a long response will be in the ++ * RXPKT_FIFO. ++ */ ++# define DSI1_INT_RXPKT1 BIT(4) ++# define DSI1_INT_TXPKT2_DONE BIT(3) ++# define DSI1_INT_TXPKT2_END BIT(2) ++/* Signaled after all repeats of TXPKT1 are transferred. */ ++# define DSI1_INT_TXPKT1_DONE BIT(1) ++/* Signaled after each TXPKT1 repeat is scheduled. */ ++# define DSI1_INT_TXPKT1_END BIT(0) ++ ++#define DSI1_INTERRUPTS_ALWAYS_ENABLED (DSI1_INT_ERR_SYNC_ESC | \ ++ DSI1_INT_ERR_CONTROL | \ ++ DSI1_INT_ERR_CONT_LP0 | \ ++ DSI1_INT_ERR_CONT_LP1 | \ ++ DSI1_INT_HSTX_TO | \ ++ DSI1_INT_LPRX_TO | \ ++ DSI1_INT_TA_TO | \ ++ DSI1_INT_PR_TO) ++ ++#define DSI0_STAT 0x2c ++#define DSI0_HSTX_TO_CNT 0x30 ++#define DSI0_LPRX_TO_CNT 0x34 ++#define DSI0_TA_TO_CNT 0x38 ++#define DSI0_PR_TO_CNT 0x3c ++#define DSI0_PHYC 0x40 ++# define DSI1_PHYC_ESC_CLK_LPDT_MASK VC4_MASK(25, 20) ++# define DSI1_PHYC_ESC_CLK_LPDT_SHIFT 20 ++# define DSI1_PHYC_HS_CLK_CONTINUOUS BIT(18) ++# define DSI0_PHYC_ESC_CLK_LPDT_MASK VC4_MASK(17, 12) ++# define DSI0_PHYC_ESC_CLK_LPDT_SHIFT 12 ++# define DSI1_PHYC_CLANE_ULPS BIT(17) ++# define DSI1_PHYC_CLANE_ENABLE BIT(16) ++# define DSI_PHYC_DLANE3_ULPS BIT(13) ++# define DSI_PHYC_DLANE3_ENABLE BIT(12) ++# define DSI0_PHYC_HS_CLK_CONTINUOUS BIT(10) ++# define DSI0_PHYC_CLANE_ULPS BIT(9) ++# define DSI_PHYC_DLANE2_ULPS BIT(9) ++# define DSI0_PHYC_CLANE_ENABLE BIT(8) ++# define DSI_PHYC_DLANE2_ENABLE BIT(8) ++# define DSI_PHYC_DLANE1_ULPS BIT(5) ++# define DSI_PHYC_DLANE1_ENABLE BIT(4) ++# define DSI_PHYC_DLANE0_FORCE_STOP BIT(2) ++# define DSI_PHYC_DLANE0_ULPS BIT(1) ++# define DSI_PHYC_DLANE0_ENABLE BIT(0) ++ ++#define DSI0_HS_CLT0 0x44 ++#define DSI0_HS_CLT1 0x48 ++#define DSI0_HS_CLT2 0x4c ++#define DSI0_HS_DLT3 0x50 ++#define DSI0_HS_DLT4 0x54 ++#define DSI0_HS_DLT5 0x58 ++#define DSI0_HS_DLT6 0x5c ++#define DSI0_HS_DLT7 0x60 ++ ++#define DSI0_PHY_AFEC0 0x64 ++# define DSI0_PHY_AFEC0_DDR2CLK_EN BIT(26) ++# define DSI0_PHY_AFEC0_DDRCLK_EN BIT(25) ++# define DSI0_PHY_AFEC0_LATCH_ULPS BIT(24) ++# define DSI1_PHY_AFEC0_IDR_DLANE3_MASK VC4_MASK(31, 29) ++# define DSI1_PHY_AFEC0_IDR_DLANE3_SHIFT 29 ++# define DSI1_PHY_AFEC0_IDR_DLANE2_MASK VC4_MASK(28, 26) ++# define DSI1_PHY_AFEC0_IDR_DLANE2_SHIFT 26 ++# define DSI1_PHY_AFEC0_IDR_DLANE1_MASK VC4_MASK(27, 23) ++# define DSI1_PHY_AFEC0_IDR_DLANE1_SHIFT 23 ++# define DSI1_PHY_AFEC0_IDR_DLANE0_MASK VC4_MASK(22, 20) ++# define DSI1_PHY_AFEC0_IDR_DLANE0_SHIFT 20 ++# define DSI1_PHY_AFEC0_IDR_CLANE_MASK VC4_MASK(19, 17) ++# define DSI1_PHY_AFEC0_IDR_CLANE_SHIFT 17 ++# define DSI0_PHY_AFEC0_ACTRL_DLANE1_MASK VC4_MASK(23, 20) ++# define DSI0_PHY_AFEC0_ACTRL_DLANE1_SHIFT 20 ++# define DSI0_PHY_AFEC0_ACTRL_DLANE0_MASK VC4_MASK(19, 16) ++# define DSI0_PHY_AFEC0_ACTRL_DLANE0_SHIFT 16 ++# define DSI0_PHY_AFEC0_ACTRL_CLANE_MASK VC4_MASK(15, 12) ++# define DSI0_PHY_AFEC0_ACTRL_CLANE_SHIFT 12 ++# define DSI1_PHY_AFEC0_DDR2CLK_EN BIT(16) ++# define DSI1_PHY_AFEC0_DDRCLK_EN BIT(15) ++# define DSI1_PHY_AFEC0_LATCH_ULPS BIT(14) ++# define DSI1_PHY_AFEC0_RESET BIT(13) ++# define DSI1_PHY_AFEC0_PD BIT(12) ++# define DSI0_PHY_AFEC0_RESET BIT(11) ++# define DSI1_PHY_AFEC0_PD_BG BIT(11) ++# define DSI0_PHY_AFEC0_PD BIT(10) ++# define DSI1_PHY_AFEC0_PD_DLANE3 BIT(10) ++# define DSI0_PHY_AFEC0_PD_BG BIT(9) ++# define DSI1_PHY_AFEC0_PD_DLANE2 BIT(9) ++# define DSI0_PHY_AFEC0_PD_DLANE1 BIT(8) ++# define DSI1_PHY_AFEC0_PD_DLANE1 BIT(8) ++# define DSI_PHY_AFEC0_PTATADJ_MASK VC4_MASK(7, 4) ++# define DSI_PHY_AFEC0_PTATADJ_SHIFT 4 ++# define DSI_PHY_AFEC0_CTATADJ_MASK VC4_MASK(3, 0) ++# define DSI_PHY_AFEC0_CTATADJ_SHIFT 0 ++ ++#define DSI0_PHY_AFEC1 0x68 ++# define DSI0_PHY_AFEC1_IDR_DLANE1_MASK VC4_MASK(10, 8) ++# define DSI0_PHY_AFEC1_IDR_DLANE1_SHIFT 8 ++# define DSI0_PHY_AFEC1_IDR_DLANE0_MASK VC4_MASK(6, 4) ++# define DSI0_PHY_AFEC1_IDR_DLANE0_SHIFT 4 ++# define DSI0_PHY_AFEC1_IDR_CLANE_MASK VC4_MASK(2, 0) ++# define DSI0_PHY_AFEC1_IDR_CLANE_SHIFT 0 ++ ++#define DSI0_TST_SEL 0x6c ++#define DSI0_TST_MON 0x70 ++#define DSI0_ID 0x74 ++# define DSI_ID_VALUE 0x00647369 ++ ++#define DSI1_CTRL 0x00 ++# define DSI_CTRL_HS_CLKC_MASK VC4_MASK(15, 14) ++# define DSI_CTRL_HS_CLKC_SHIFT 14 ++# define DSI_CTRL_HS_CLKC_BYTE 0 ++# define DSI_CTRL_HS_CLKC_DDR2 1 ++# define DSI_CTRL_HS_CLKC_DDR 2 ++ ++# define DSI_CTRL_RX_LPDT_EOT_DISABLE BIT(13) ++# define DSI_CTRL_LPDT_EOT_DISABLE BIT(12) ++# define DSI_CTRL_HSDT_EOT_DISABLE BIT(11) ++# define DSI_CTRL_SOFT_RESET_CFG BIT(10) ++# define DSI_CTRL_CAL_BYTE BIT(9) ++# define DSI_CTRL_INV_BYTE BIT(8) ++# define DSI_CTRL_CLR_LDF BIT(7) ++# define DSI0_CTRL_CLR_PBCF BIT(6) ++# define DSI1_CTRL_CLR_RXF BIT(6) ++# define DSI0_CTRL_CLR_CPBCF BIT(5) ++# define DSI1_CTRL_CLR_PDF BIT(5) ++# define DSI0_CTRL_CLR_PDF BIT(4) ++# define DSI1_CTRL_CLR_CDF BIT(4) ++# define DSI0_CTRL_CLR_CDF BIT(3) ++# define DSI0_CTRL_CTRL2 BIT(2) ++# define DSI1_CTRL_DISABLE_DISP_CRCC BIT(2) ++# define DSI0_CTRL_CTRL1 BIT(1) ++# define DSI1_CTRL_DISABLE_DISP_ECCC BIT(1) ++# define DSI0_CTRL_CTRL0 BIT(0) ++# define DSI1_CTRL_EN BIT(0) ++# define DSI0_CTRL_RESET_FIFOS (DSI_CTRL_CLR_LDF | \ ++ DSI0_CTRL_CLR_PBCF | \ ++ DSI0_CTRL_CLR_CPBCF | \ ++ DSI0_CTRL_CLR_PDF | \ ++ DSI0_CTRL_CLR_CDF) ++# define DSI1_CTRL_RESET_FIFOS (DSI_CTRL_CLR_LDF | \ ++ DSI1_CTRL_CLR_RXF | \ ++ DSI1_CTRL_CLR_PDF | \ ++ DSI1_CTRL_CLR_CDF) ++ ++#define DSI1_TXPKT2C 0x0c ++#define DSI1_TXPKT2H 0x10 ++#define DSI1_TXPKT_PIX_FIFO 0x20 ++#define DSI1_RXPKT_FIFO 0x24 ++#define DSI1_DISP0_CTRL 0x28 ++#define DSI1_INT_STAT 0x30 ++#define DSI1_INT_EN 0x34 ++/* State reporting bits. These mostly behave like INT_STAT, where ++ * writing a 1 clears the bit. ++ */ ++#define DSI1_STAT 0x38 ++# define DSI1_STAT_PHY_D3_ULPS BIT(31) ++# define DSI1_STAT_PHY_D3_STOP BIT(30) ++# define DSI1_STAT_PHY_D2_ULPS BIT(29) ++# define DSI1_STAT_PHY_D2_STOP BIT(28) ++# define DSI1_STAT_PHY_D1_ULPS BIT(27) ++# define DSI1_STAT_PHY_D1_STOP BIT(26) ++# define DSI1_STAT_PHY_D0_ULPS BIT(25) ++# define DSI1_STAT_PHY_D0_STOP BIT(24) ++# define DSI1_STAT_FIFO_ERR BIT(23) ++# define DSI1_STAT_PHY_RXLPDT BIT(22) ++# define DSI1_STAT_PHY_RXTRIG BIT(21) ++# define DSI1_STAT_PHY_D0_LPDT BIT(20) ++/* Set when in forward direction */ ++# define DSI1_STAT_PHY_DIR BIT(19) ++# define DSI1_STAT_PHY_CLOCK_ULPS BIT(18) ++# define DSI1_STAT_PHY_CLOCK_HS BIT(17) ++# define DSI1_STAT_PHY_CLOCK_STOP BIT(16) ++# define DSI1_STAT_PR_TO BIT(15) ++# define DSI1_STAT_TA_TO BIT(14) ++# define DSI1_STAT_LPRX_TO BIT(13) ++# define DSI1_STAT_HSTX_TO BIT(12) ++# define DSI1_STAT_ERR_CONT_LP1 BIT(11) ++# define DSI1_STAT_ERR_CONT_LP0 BIT(10) ++# define DSI1_STAT_ERR_CONTROL BIT(9) ++# define DSI1_STAT_ERR_SYNC_ESC BIT(8) ++# define DSI1_STAT_RXPKT2 BIT(7) ++# define DSI1_STAT_RXPKT1 BIT(6) ++# define DSI1_STAT_TXPKT2_BUSY BIT(5) ++# define DSI1_STAT_TXPKT2_DONE BIT(4) ++# define DSI1_STAT_TXPKT2_END BIT(3) ++# define DSI1_STAT_TXPKT1_BUSY BIT(2) ++# define DSI1_STAT_TXPKT1_DONE BIT(1) ++# define DSI1_STAT_TXPKT1_END BIT(0) ++ ++#define DSI1_HSTX_TO_CNT 0x3c ++#define DSI1_LPRX_TO_CNT 0x40 ++#define DSI1_TA_TO_CNT 0x44 ++#define DSI1_PR_TO_CNT 0x48 ++#define DSI1_PHYC 0x4c ++ ++#define DSI1_HS_CLT0 0x50 ++# define DSI_HS_CLT0_CZERO_MASK VC4_MASK(26, 18) ++# define DSI_HS_CLT0_CZERO_SHIFT 18 ++# define DSI_HS_CLT0_CPRE_MASK VC4_MASK(17, 9) ++# define DSI_HS_CLT0_CPRE_SHIFT 9 ++# define DSI_HS_CLT0_CPREP_MASK VC4_MASK(8, 0) ++# define DSI_HS_CLT0_CPREP_SHIFT 0 ++ ++#define DSI1_HS_CLT1 0x54 ++# define DSI_HS_CLT1_CTRAIL_MASK VC4_MASK(17, 9) ++# define DSI_HS_CLT1_CTRAIL_SHIFT 9 ++# define DSI_HS_CLT1_CPOST_MASK VC4_MASK(8, 0) ++# define DSI_HS_CLT1_CPOST_SHIFT 0 ++ ++#define DSI1_HS_CLT2 0x58 ++# define DSI_HS_CLT2_WUP_MASK VC4_MASK(23, 0) ++# define DSI_HS_CLT2_WUP_SHIFT 0 ++ ++#define DSI1_HS_DLT3 0x5c ++# define DSI_HS_DLT3_EXIT_MASK VC4_MASK(26, 18) ++# define DSI_HS_DLT3_EXIT_SHIFT 18 ++# define DSI_HS_DLT3_ZERO_MASK VC4_MASK(17, 9) ++# define DSI_HS_DLT3_ZERO_SHIFT 9 ++# define DSI_HS_DLT3_PRE_MASK VC4_MASK(8, 0) ++# define DSI_HS_DLT3_PRE_SHIFT 0 ++ ++#define DSI1_HS_DLT4 0x60 ++# define DSI_HS_DLT4_ANLAT_MASK VC4_MASK(22, 18) ++# define DSI_HS_DLT4_ANLAT_SHIFT 18 ++# define DSI_HS_DLT4_TRAIL_MASK VC4_MASK(17, 9) ++# define DSI_HS_DLT4_TRAIL_SHIFT 9 ++# define DSI_HS_DLT4_LPX_MASK VC4_MASK(8, 0) ++# define DSI_HS_DLT4_LPX_SHIFT 0 ++ ++#define DSI1_HS_DLT5 0x64 ++# define DSI_HS_DLT5_INIT_MASK VC4_MASK(23, 0) ++# define DSI_HS_DLT5_INIT_SHIFT 0 ++ ++#define DSI1_HS_DLT6 0x68 ++# define DSI_HS_DLT6_TA_GET_MASK VC4_MASK(31, 24) ++# define DSI_HS_DLT6_TA_GET_SHIFT 24 ++# define DSI_HS_DLT6_TA_SURE_MASK VC4_MASK(23, 16) ++# define DSI_HS_DLT6_TA_SURE_SHIFT 16 ++# define DSI_HS_DLT6_TA_GO_MASK VC4_MASK(15, 8) ++# define DSI_HS_DLT6_TA_GO_SHIFT 8 ++# define DSI_HS_DLT6_LP_LPX_MASK VC4_MASK(7, 0) ++# define DSI_HS_DLT6_LP_LPX_SHIFT 0 ++ ++#define DSI1_HS_DLT7 0x6c ++# define DSI_HS_DLT7_LP_WUP_MASK VC4_MASK(23, 0) ++# define DSI_HS_DLT7_LP_WUP_SHIFT 0 ++ ++#define DSI1_PHY_AFEC0 0x70 ++ ++#define DSI1_PHY_AFEC1 0x74 ++# define DSI1_PHY_AFEC1_ACTRL_DLANE3_MASK VC4_MASK(19, 16) ++# define DSI1_PHY_AFEC1_ACTRL_DLANE3_SHIFT 16 ++# define DSI1_PHY_AFEC1_ACTRL_DLANE2_MASK VC4_MASK(15, 12) ++# define DSI1_PHY_AFEC1_ACTRL_DLANE2_SHIFT 12 ++# define DSI1_PHY_AFEC1_ACTRL_DLANE1_MASK VC4_MASK(11, 8) ++# define DSI1_PHY_AFEC1_ACTRL_DLANE1_SHIFT 8 ++# define DSI1_PHY_AFEC1_ACTRL_DLANE0_MASK VC4_MASK(7, 4) ++# define DSI1_PHY_AFEC1_ACTRL_DLANE0_SHIFT 4 ++# define DSI1_PHY_AFEC1_ACTRL_CLANE_MASK VC4_MASK(3, 0) ++# define DSI1_PHY_AFEC1_ACTRL_CLANE_SHIFT 0 ++ ++#define DSI1_TST_SEL 0x78 ++#define DSI1_TST_MON 0x7c ++#define DSI1_PHY_TST1 0x80 ++#define DSI1_PHY_TST2 0x84 ++#define DSI1_PHY_FIFO_STAT 0x88 ++/* Actually, all registers in the range that aren't otherwise claimed ++ * will return the ID. ++ */ ++#define DSI1_ID 0x8c ++ ++/* General DSI hardware state. */ ++struct vc4_dsi { ++ struct platform_device *pdev; ++ ++ struct mipi_dsi_host dsi_host; ++ struct drm_encoder *encoder; ++ struct drm_connector *connector; ++ struct drm_panel *panel; ++ ++ void __iomem *regs; ++ ++ struct dma_chan *reg_dma_chan; ++ dma_addr_t reg_dma_paddr; ++ u32 *reg_dma_mem; ++ dma_addr_t reg_paddr; ++ ++ /* Whether we're on bcm2835's DSI0 or DSI1. */ ++ int port; ++ ++ /* DSI channel for the panel we're connected to. */ ++ u32 channel; ++ u32 lanes; ++ enum mipi_dsi_pixel_format format; ++ u32 mode_flags; ++ ++ /* Input clock from CPRMAN to the digital PHY, for the DSI ++ * escape clock. ++ */ ++ struct clk *escape_clock; ++ ++ /* Input clock to the analog PHY, used to generate the DSI bit ++ * clock. ++ */ ++ struct clk *pll_phy_clock; ++ ++ /* HS Clocks generated within the DSI analog PHY. */ ++ struct clk_fixed_factor phy_clocks[3]; ++ ++ struct clk_onecell_data clk_onecell; ++ ++ /* Pixel clock output to the pixelvalve, generated from the HS ++ * clock. ++ */ ++ struct clk *pixel_clock; ++ ++ struct completion xfer_completion; ++ int xfer_result; ++}; ++ ++#define host_to_dsi(host) container_of(host, struct vc4_dsi, dsi_host) ++ ++static inline void ++dsi_dma_workaround_write(struct vc4_dsi *dsi, u32 offset, u32 val) ++{ ++ struct dma_chan *chan = dsi->reg_dma_chan; ++ struct dma_async_tx_descriptor *tx; ++ dma_cookie_t cookie; ++ int ret; ++ ++ /* DSI0 should be able to write normally. */ ++ if (!chan) { ++ writel(val, dsi->regs + offset); ++ return; ++ } ++ ++ *dsi->reg_dma_mem = val; ++ ++ tx = chan->device->device_prep_dma_memcpy(chan, ++ dsi->reg_paddr + offset, ++ dsi->reg_dma_paddr, ++ 4, 0); ++ if (!tx) { ++ DRM_ERROR("Failed to set up DMA register write\n"); ++ return; ++ } ++ ++ cookie = tx->tx_submit(tx); ++ ret = dma_submit_error(cookie); ++ if (ret) { ++ DRM_ERROR("Failed to submit DMA: %d\n", ret); ++ return; ++ } ++ ret = dma_sync_wait(chan, cookie); ++ if (ret) ++ DRM_ERROR("Failed to wait for DMA: %d\n", ret); ++} ++ ++#define DSI_READ(offset) readl(dsi->regs + (offset)) ++#define DSI_WRITE(offset, val) dsi_dma_workaround_write(dsi, offset, val) ++#define DSI_PORT_READ(offset) \ ++ DSI_READ(dsi->port ? DSI1_##offset : DSI0_##offset) ++#define DSI_PORT_WRITE(offset, val) \ ++ DSI_WRITE(dsi->port ? DSI1_##offset : DSI0_##offset, val) ++#define DSI_PORT_BIT(bit) (dsi->port ? DSI1_##bit : DSI0_##bit) ++ ++/* VC4 DSI encoder KMS struct */ ++struct vc4_dsi_encoder { ++ struct vc4_encoder base; ++ struct vc4_dsi *dsi; ++}; ++ ++static inline struct vc4_dsi_encoder * ++to_vc4_dsi_encoder(struct drm_encoder *encoder) ++{ ++ return container_of(encoder, struct vc4_dsi_encoder, base.base); ++} ++ ++/* VC4 DSI connector KMS struct */ ++struct vc4_dsi_connector { ++ struct drm_connector base; ++ struct vc4_dsi *dsi; ++}; ++ ++static inline struct vc4_dsi_connector * ++to_vc4_dsi_connector(struct drm_connector *connector) ++{ ++ return container_of(connector, struct vc4_dsi_connector, base); ++} ++ ++#define DSI_REG(reg) { reg, #reg } ++static const struct { ++ u32 reg; ++ const char *name; ++} dsi0_regs[] = { ++ DSI_REG(DSI0_CTRL), ++ DSI_REG(DSI0_STAT), ++ DSI_REG(DSI0_HSTX_TO_CNT), ++ DSI_REG(DSI0_LPRX_TO_CNT), ++ DSI_REG(DSI0_TA_TO_CNT), ++ DSI_REG(DSI0_PR_TO_CNT), ++ DSI_REG(DSI0_DISP0_CTRL), ++ DSI_REG(DSI0_DISP1_CTRL), ++ DSI_REG(DSI0_INT_STAT), ++ DSI_REG(DSI0_INT_EN), ++ DSI_REG(DSI0_PHYC), ++ DSI_REG(DSI0_HS_CLT0), ++ DSI_REG(DSI0_HS_CLT1), ++ DSI_REG(DSI0_HS_CLT2), ++ DSI_REG(DSI0_HS_DLT3), ++ DSI_REG(DSI0_HS_DLT4), ++ DSI_REG(DSI0_HS_DLT5), ++ DSI_REG(DSI0_HS_DLT6), ++ DSI_REG(DSI0_HS_DLT7), ++ DSI_REG(DSI0_PHY_AFEC0), ++ DSI_REG(DSI0_PHY_AFEC1), ++ DSI_REG(DSI0_ID), ++}; ++ ++static const struct { ++ u32 reg; ++ const char *name; ++} dsi1_regs[] = { ++ DSI_REG(DSI1_CTRL), ++ DSI_REG(DSI1_STAT), ++ DSI_REG(DSI1_HSTX_TO_CNT), ++ DSI_REG(DSI1_LPRX_TO_CNT), ++ DSI_REG(DSI1_TA_TO_CNT), ++ DSI_REG(DSI1_PR_TO_CNT), ++ DSI_REG(DSI1_DISP0_CTRL), ++ DSI_REG(DSI1_DISP1_CTRL), ++ DSI_REG(DSI1_INT_STAT), ++ DSI_REG(DSI1_INT_EN), ++ DSI_REG(DSI1_PHYC), ++ DSI_REG(DSI1_HS_CLT0), ++ DSI_REG(DSI1_HS_CLT1), ++ DSI_REG(DSI1_HS_CLT2), ++ DSI_REG(DSI1_HS_DLT3), ++ DSI_REG(DSI1_HS_DLT4), ++ DSI_REG(DSI1_HS_DLT5), ++ DSI_REG(DSI1_HS_DLT6), ++ DSI_REG(DSI1_HS_DLT7), ++ DSI_REG(DSI1_PHY_AFEC0), ++ DSI_REG(DSI1_PHY_AFEC1), ++ DSI_REG(DSI1_ID), ++}; ++ ++static void vc4_dsi_dump_regs(struct vc4_dsi *dsi) ++{ ++ int i; ++ ++ if (dsi->port == 0) { ++ for (i = 0; i < ARRAY_SIZE(dsi0_regs); i++) { ++ DRM_INFO("0x%04x (%s): 0x%08x\n", ++ dsi0_regs[i].reg, dsi0_regs[i].name, ++ DSI_READ(dsi0_regs[i].reg)); ++ } ++ } else { ++ for (i = 0; i < ARRAY_SIZE(dsi1_regs); i++) { ++ DRM_INFO("0x%04x (%s): 0x%08x\n", ++ dsi1_regs[i].reg, dsi1_regs[i].name, ++ DSI_READ(dsi1_regs[i].reg)); ++ } ++ } ++} ++ ++#ifdef CONFIG_DEBUG_FS ++int vc4_dsi_debugfs_regs(struct seq_file *m, void *unused) ++{ ++ struct drm_info_node *node = (struct drm_info_node *)m->private; ++ struct drm_device *drm = node->minor->dev; ++ struct vc4_dev *vc4 = to_vc4_dev(drm); ++ int dsi_index = (uintptr_t)node->info_ent->data; ++ struct vc4_dsi *dsi = (dsi_index == 1 ? vc4->dsi1 : NULL); ++ int i; ++ ++ if (!dsi) ++ return 0; ++ ++ if (dsi->port == 0) { ++ for (i = 0; i < ARRAY_SIZE(dsi0_regs); i++) { ++ seq_printf(m, "0x%04x (%s): 0x%08x\n", ++ dsi0_regs[i].reg, dsi0_regs[i].name, ++ DSI_READ(dsi0_regs[i].reg)); ++ } ++ } else { ++ for (i = 0; i < ARRAY_SIZE(dsi1_regs); i++) { ++ seq_printf(m, "0x%04x (%s): 0x%08x\n", ++ dsi1_regs[i].reg, dsi1_regs[i].name, ++ DSI_READ(dsi1_regs[i].reg)); ++ } ++ } ++ ++ return 0; ++} ++#endif ++ ++static enum drm_connector_status ++vc4_dsi_connector_detect(struct drm_connector *connector, bool force) ++{ ++ struct vc4_dsi_connector *vc4_connector = ++ to_vc4_dsi_connector(connector); ++ struct vc4_dsi *dsi = vc4_connector->dsi; ++ ++ if (dsi->panel) ++ return connector_status_connected; ++ else ++ return connector_status_disconnected; ++} ++ ++static void vc4_dsi_connector_destroy(struct drm_connector *connector) ++{ ++ drm_connector_unregister(connector); ++ drm_connector_cleanup(connector); ++} ++ ++static int vc4_dsi_connector_get_modes(struct drm_connector *connector) ++{ ++ struct vc4_dsi_connector *vc4_connector = ++ to_vc4_dsi_connector(connector); ++ struct vc4_dsi *dsi = vc4_connector->dsi; ++ ++ if (dsi->panel) ++ return drm_panel_get_modes(dsi->panel); ++ ++ return 0; ++} ++ ++static const struct drm_connector_funcs vc4_dsi_connector_funcs = { ++ .dpms = drm_atomic_helper_connector_dpms, ++ .detect = vc4_dsi_connector_detect, ++ .fill_modes = drm_helper_probe_single_connector_modes, ++ .destroy = vc4_dsi_connector_destroy, ++ .reset = drm_atomic_helper_connector_reset, ++ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, ++ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, ++}; ++ ++static const struct drm_connector_helper_funcs vc4_dsi_connector_helper_funcs = { ++ .get_modes = vc4_dsi_connector_get_modes, ++}; ++ ++static struct drm_connector *vc4_dsi_connector_init(struct drm_device *dev, ++ struct vc4_dsi *dsi) ++{ ++ struct drm_connector *connector = NULL; ++ struct vc4_dsi_connector *dsi_connector; ++ int ret = 0; ++ ++ dsi_connector = devm_kzalloc(dev->dev, sizeof(*dsi_connector), ++ GFP_KERNEL); ++ if (!dsi_connector) { ++ ret = -ENOMEM; ++ goto fail; ++ } ++ connector = &dsi_connector->base; ++ ++ dsi_connector->dsi = dsi; ++ ++ drm_connector_init(dev, connector, &vc4_dsi_connector_funcs, ++ DRM_MODE_CONNECTOR_DSI); ++ drm_connector_helper_add(connector, &vc4_dsi_connector_helper_funcs); ++ ++ connector->polled = 0; ++ connector->interlace_allowed = 0; ++ connector->doublescan_allowed = 0; ++ ++ drm_mode_connector_attach_encoder(connector, dsi->encoder); ++ ++ return connector; ++ ++fail: ++ if (connector) ++ vc4_dsi_connector_destroy(connector); ++ ++ return ERR_PTR(ret); ++} ++ ++static void vc4_dsi_encoder_destroy(struct drm_encoder *encoder) ++{ ++ drm_encoder_cleanup(encoder); ++} ++ ++static const struct drm_encoder_funcs vc4_dsi_encoder_funcs = { ++ .destroy = vc4_dsi_encoder_destroy, ++}; ++ ++static void vc4_dsi_latch_ulps(struct vc4_dsi *dsi, bool latch) ++{ ++ u32 afec0 = DSI_PORT_READ(PHY_AFEC0); ++ ++ if (latch) ++ afec0 |= DSI_PORT_BIT(PHY_AFEC0_LATCH_ULPS); ++ else ++ afec0 &= ~DSI_PORT_BIT(PHY_AFEC0_LATCH_ULPS); ++ ++ DSI_PORT_WRITE(PHY_AFEC0, afec0); ++} ++ ++/* Enters or exits Ultra Low Power State. */ ++static void vc4_dsi_ulps(struct vc4_dsi *dsi, bool ulps) ++{ ++ bool continuous = dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS; ++ u32 phyc_ulps = ((continuous ? DSI_PORT_BIT(PHYC_CLANE_ULPS) : 0) | ++ DSI_PHYC_DLANE0_ULPS | ++ (dsi->lanes > 1 ? DSI_PHYC_DLANE1_ULPS : 0) | ++ (dsi->lanes > 2 ? DSI_PHYC_DLANE2_ULPS : 0) | ++ (dsi->lanes > 3 ? DSI_PHYC_DLANE3_ULPS : 0)); ++ u32 stat_ulps = ((continuous ? DSI1_STAT_PHY_CLOCK_ULPS : 0) | ++ DSI1_STAT_PHY_D0_ULPS | ++ (dsi->lanes > 1 ? DSI1_STAT_PHY_D1_ULPS : 0) | ++ (dsi->lanes > 2 ? DSI1_STAT_PHY_D2_ULPS : 0) | ++ (dsi->lanes > 3 ? DSI1_STAT_PHY_D3_ULPS : 0)); ++ u32 stat_stop = ((continuous ? DSI1_STAT_PHY_CLOCK_STOP : 0) | ++ DSI1_STAT_PHY_D0_STOP | ++ (dsi->lanes > 1 ? DSI1_STAT_PHY_D1_STOP : 0) | ++ (dsi->lanes > 2 ? DSI1_STAT_PHY_D2_STOP : 0) | ++ (dsi->lanes > 3 ? DSI1_STAT_PHY_D3_STOP : 0)); ++ int ret; ++ ++ DSI_PORT_WRITE(STAT, stat_ulps); ++ DSI_PORT_WRITE(PHYC, DSI_PORT_READ(PHYC) | phyc_ulps); ++ ret = wait_for((DSI_PORT_READ(STAT) & stat_ulps) == stat_ulps, 200); ++ if (ret) { ++ dev_warn(&dsi->pdev->dev, ++ "Timeout waiting for DSI ULPS entry: STAT 0x%08x", ++ DSI_PORT_READ(STAT)); ++ DSI_PORT_WRITE(PHYC, DSI_PORT_READ(PHYC) & ~phyc_ulps); ++ vc4_dsi_latch_ulps(dsi, false); ++ return; ++ } ++ ++ /* The DSI module can't be disabled while the module is ++ * generating ULPS state. So, to be able to disable the ++ * module, we have the AFE latch the ULPS state and continue ++ * on to having the module enter STOP. ++ */ ++ vc4_dsi_latch_ulps(dsi, ulps); ++ ++ DSI_PORT_WRITE(STAT, stat_stop); ++ DSI_PORT_WRITE(PHYC, DSI_PORT_READ(PHYC) & ~phyc_ulps); ++ ret = wait_for((DSI_PORT_READ(STAT) & stat_stop) == stat_stop, 200); ++ if (ret) { ++ dev_warn(&dsi->pdev->dev, ++ "Timeout waiting for DSI STOP entry: STAT 0x%08x", ++ DSI_PORT_READ(STAT)); ++ DSI_PORT_WRITE(PHYC, DSI_PORT_READ(PHYC) & ~phyc_ulps); ++ return; ++ } ++} ++ ++static u32 ++dsi_hs_timing(u32 ui_ns, u32 ns, u32 ui) ++{ ++ /* The HS timings have to be rounded up to a multiple of 8 ++ * because we're using the byte clock. ++ */ ++ return roundup(ui + DIV_ROUND_UP(ns, ui_ns), 8); ++} ++ ++/* ESC always runs at 100Mhz. */ ++#define ESC_TIME_NS 10 ++ ++static u32 ++dsi_esc_timing(u32 ns) ++{ ++ return DIV_ROUND_UP(ns, ESC_TIME_NS); ++} ++ ++static void vc4_dsi_encoder_disable(struct drm_encoder *encoder) ++{ ++ struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder); ++ struct vc4_dsi *dsi = vc4_encoder->dsi; ++ struct device *dev = &dsi->pdev->dev; ++ ++ drm_panel_disable(dsi->panel); ++ ++ vc4_dsi_ulps(dsi, true); ++ ++ drm_panel_unprepare(dsi->panel); ++ ++ clk_disable_unprepare(dsi->pll_phy_clock); ++ clk_disable_unprepare(dsi->escape_clock); ++ clk_disable_unprepare(dsi->pixel_clock); ++ ++ pm_runtime_put(dev); ++} ++ ++static void vc4_dsi_encoder_enable(struct drm_encoder *encoder) ++{ ++ struct drm_display_mode *mode = &encoder->crtc->mode; ++ struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder); ++ struct vc4_dsi *dsi = vc4_encoder->dsi; ++ struct device *dev = &dsi->pdev->dev; ++ u32 format = 0, divider = 0; ++ bool debug_dump_regs = false; ++ unsigned long hs_clock; ++ u32 ui_ns; ++ /* Minimum LP state duration in escape clock cycles. */ ++ u32 lpx = dsi_esc_timing(60); ++ unsigned long pixel_clock_hz = mode->clock * 1000; ++ unsigned long dsip_clock; ++ unsigned long phy_clock; ++ int ret; ++ ++ ret = pm_runtime_get_sync(dev); ++ if (ret) { ++ DRM_ERROR("Failed to runtime PM enable on DSI%d\n", dsi->port); ++ return; ++ } ++ ++ ret = drm_panel_prepare(dsi->panel); ++ if (ret) { ++ DRM_ERROR("Panel failed to prepare\n"); ++ return; ++ } ++ ++ if (debug_dump_regs) { ++ DRM_INFO("DSI regs before:\n"); ++ vc4_dsi_dump_regs(dsi); ++ } ++ ++ switch (dsi->format) { ++ case MIPI_DSI_FMT_RGB888: ++ format = DSI_PFORMAT_RGB888; ++ divider = 24 / dsi->lanes; ++ break; ++ case MIPI_DSI_FMT_RGB666: ++ format = DSI_PFORMAT_RGB666; ++ divider = 24 / dsi->lanes; ++ break; ++ case MIPI_DSI_FMT_RGB666_PACKED: ++ format = DSI_PFORMAT_RGB666_PACKED; ++ divider = 18 / dsi->lanes; ++ break; ++ case MIPI_DSI_FMT_RGB565: ++ format = DSI_PFORMAT_RGB565; ++ divider = 16 / dsi->lanes; ++ break; ++ } ++ ++ phy_clock = pixel_clock_hz * divider; ++ ret = clk_set_rate(dsi->pll_phy_clock, phy_clock); ++ if (ret) { ++ dev_err(&dsi->pdev->dev, ++ "Failed to set phy clock to %ld: %d\n", phy_clock, ret); ++ } ++ ++ /* Reset the DSI and all its fifos. */ ++ DSI_PORT_WRITE(CTRL, ++ DSI_CTRL_SOFT_RESET_CFG | ++ DSI_PORT_BIT(CTRL_RESET_FIFOS)); ++ ++ DSI_PORT_WRITE(CTRL, ++ DSI_CTRL_HSDT_EOT_DISABLE | ++ DSI_CTRL_RX_LPDT_EOT_DISABLE); ++ ++ /* Clear all stat bits so we see what has happened during enable. */ ++ DSI_PORT_WRITE(STAT, DSI_PORT_READ(STAT)); ++ ++ /* Set AFE CTR00/CTR1 to release powerdown of analog. */ ++ if (dsi->port == 0) { ++ u32 afec0 = (VC4_SET_FIELD(7, DSI_PHY_AFEC0_PTATADJ) | ++ VC4_SET_FIELD(7, DSI_PHY_AFEC0_CTATADJ)); ++ ++ if (dsi->lanes < 2) ++ afec0 |= DSI0_PHY_AFEC0_PD_DLANE1; ++ ++ if (!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO)) ++ afec0 |= DSI0_PHY_AFEC0_RESET; ++ ++ DSI_PORT_WRITE(PHY_AFEC0, afec0); ++ ++ DSI_PORT_WRITE(PHY_AFEC1, ++ VC4_SET_FIELD(6, DSI0_PHY_AFEC1_IDR_DLANE1) | ++ VC4_SET_FIELD(6, DSI0_PHY_AFEC1_IDR_DLANE0) | ++ VC4_SET_FIELD(6, DSI0_PHY_AFEC1_IDR_CLANE)); ++ } else { ++ u32 afec0 = (VC4_SET_FIELD(7, DSI_PHY_AFEC0_PTATADJ) | ++ VC4_SET_FIELD(7, DSI_PHY_AFEC0_CTATADJ) | ++ VC4_SET_FIELD(6, DSI1_PHY_AFEC0_IDR_CLANE) | ++ VC4_SET_FIELD(6, DSI1_PHY_AFEC0_IDR_DLANE0) | ++ VC4_SET_FIELD(6, DSI1_PHY_AFEC0_IDR_DLANE1) | ++ VC4_SET_FIELD(6, DSI1_PHY_AFEC0_IDR_DLANE2) | ++ VC4_SET_FIELD(6, DSI1_PHY_AFEC0_IDR_DLANE3)); ++ ++ if (dsi->lanes < 4) ++ afec0 |= DSI1_PHY_AFEC0_PD_DLANE3; ++ if (dsi->lanes < 3) ++ afec0 |= DSI1_PHY_AFEC0_PD_DLANE2; ++ if (dsi->lanes < 2) ++ afec0 |= DSI1_PHY_AFEC0_PD_DLANE1; ++ ++ afec0 |= DSI1_PHY_AFEC0_RESET; ++ ++ DSI_PORT_WRITE(PHY_AFEC0, afec0); ++ ++ DSI_PORT_WRITE(PHY_AFEC1, 0); ++ ++ /* AFEC reset hold time */ ++ mdelay(1); ++ } ++ ++ ret = clk_prepare_enable(dsi->escape_clock); ++ if (ret) { ++ DRM_ERROR("Failed to turn on DSI escape clock: %d\n", ret); ++ return; ++ } ++ ++ ret = clk_prepare_enable(dsi->pll_phy_clock); ++ if (ret) { ++ DRM_ERROR("Failed to turn on DSI PLL: %d\n", ret); ++ return; ++ } ++ ++ hs_clock = clk_get_rate(dsi->pll_phy_clock); ++ ++ /* Yes, we set the DSI0P/DSI1P pixel clock to the byte rate, ++ * not the pixel clock rate. DSIxP take from the APHY's byte, ++ * DDR2, or DDR4 clock (we use byte) and feed into the PV at ++ * that rate. Separately, a value derived from PIX_CLK_DIV ++ * and HS_CLKC is fed into the PV to divide down to the actual ++ * pixel clock for pushing pixels into DSI. ++ */ ++ dsip_clock = phy_clock / 8; ++ ret = clk_set_rate(dsi->pixel_clock, dsip_clock); ++ if (ret) { ++ dev_err(dev, "Failed to set pixel clock to %ldHz: %d\n", ++ dsip_clock, ret); ++ } ++ ++ ret = clk_prepare_enable(dsi->pixel_clock); ++ if (ret) { ++ DRM_ERROR("Failed to turn on DSI pixel clock: %d\n", ret); ++ return; ++ } ++ ++ /* How many ns one DSI unit interval is. Note that the clock ++ * is DDR, so there's an extra divide by 2. ++ */ ++ ui_ns = DIV_ROUND_UP(500000000, hs_clock); ++ ++ DSI_PORT_WRITE(HS_CLT0, ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 262, 0), ++ DSI_HS_CLT0_CZERO) | ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 0, 8), ++ DSI_HS_CLT0_CPRE) | ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 38, 0), ++ DSI_HS_CLT0_CPREP)); ++ ++ DSI_PORT_WRITE(HS_CLT1, ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 60, 0), ++ DSI_HS_CLT1_CTRAIL) | ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 60, 52), ++ DSI_HS_CLT1_CPOST)); ++ ++ DSI_PORT_WRITE(HS_CLT2, ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 1000000, 0), ++ DSI_HS_CLT2_WUP)); ++ ++ DSI_PORT_WRITE(HS_DLT3, ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 100, 0), ++ DSI_HS_DLT3_EXIT) | ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 105, 6), ++ DSI_HS_DLT3_ZERO) | ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 40, 4), ++ DSI_HS_DLT3_PRE)); ++ ++ DSI_PORT_WRITE(HS_DLT4, ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, lpx * ESC_TIME_NS, 0), ++ DSI_HS_DLT4_LPX) | ++ VC4_SET_FIELD(max(dsi_hs_timing(ui_ns, 0, 8), ++ dsi_hs_timing(ui_ns, 60, 4)), ++ DSI_HS_DLT4_TRAIL) | ++ VC4_SET_FIELD(0, DSI_HS_DLT4_ANLAT)); ++ ++ DSI_PORT_WRITE(HS_DLT5, VC4_SET_FIELD(dsi_hs_timing(ui_ns, 1000, 5000), ++ DSI_HS_DLT5_INIT)); ++ ++ DSI_PORT_WRITE(HS_DLT6, ++ VC4_SET_FIELD(lpx * 5, DSI_HS_DLT6_TA_GET) | ++ VC4_SET_FIELD(lpx, DSI_HS_DLT6_TA_SURE) | ++ VC4_SET_FIELD(lpx * 4, DSI_HS_DLT6_TA_GO) | ++ VC4_SET_FIELD(lpx, DSI_HS_DLT6_LP_LPX)); ++ ++ DSI_PORT_WRITE(HS_DLT7, ++ VC4_SET_FIELD(dsi_esc_timing(1000000), ++ DSI_HS_DLT7_LP_WUP)); ++ ++ DSI_PORT_WRITE(PHYC, ++ DSI_PHYC_DLANE0_ENABLE | ++ (dsi->lanes >= 2 ? DSI_PHYC_DLANE1_ENABLE : 0) | ++ (dsi->lanes >= 3 ? DSI_PHYC_DLANE2_ENABLE : 0) | ++ (dsi->lanes >= 4 ? DSI_PHYC_DLANE3_ENABLE : 0) | ++ DSI_PORT_BIT(PHYC_CLANE_ENABLE) | ++ ((dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) ? ++ 0 : DSI_PORT_BIT(PHYC_HS_CLK_CONTINUOUS)) | ++ (dsi->port == 0 ? ++ VC4_SET_FIELD(lpx - 1, DSI0_PHYC_ESC_CLK_LPDT) : ++ VC4_SET_FIELD(lpx - 1, DSI1_PHYC_ESC_CLK_LPDT))); ++ ++ DSI_PORT_WRITE(CTRL, ++ DSI_PORT_READ(CTRL) | ++ DSI_CTRL_CAL_BYTE); ++ ++ /* HS timeout in HS clock cycles: disabled. */ ++ DSI_PORT_WRITE(HSTX_TO_CNT, 0); ++ /* LP receive timeout in HS clocks. */ ++ DSI_PORT_WRITE(LPRX_TO_CNT, 0xffffff); ++ /* Bus turnaround timeout */ ++ DSI_PORT_WRITE(TA_TO_CNT, 100000); ++ /* Display reset sequence timeout */ ++ DSI_PORT_WRITE(PR_TO_CNT, 100000); ++ ++ if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) { ++ DSI_PORT_WRITE(DISP0_CTRL, ++ VC4_SET_FIELD(divider, DSI_DISP0_PIX_CLK_DIV) | ++ VC4_SET_FIELD(format, DSI_DISP0_PFORMAT) | ++ VC4_SET_FIELD(DSI_DISP0_LP_STOP_PERFRAME, ++ DSI_DISP0_LP_STOP_CTRL) | ++ DSI_DISP0_ST_END | ++ DSI_DISP0_ENABLE); ++ } else { ++ DSI_PORT_WRITE(DISP0_CTRL, ++ DSI_DISP0_COMMAND_MODE | ++ DSI_DISP0_ENABLE); ++ } ++ ++ /* Set up DISP1 for transferring long command payloads through ++ * the pixfifo. ++ */ ++ DSI_PORT_WRITE(DISP1_CTRL, ++ VC4_SET_FIELD(DSI_DISP1_PFORMAT_32BIT_LE, ++ DSI_DISP1_PFORMAT) | ++ DSI_DISP1_ENABLE); ++ ++ /* Ungate the block. */ ++ if (dsi->port == 0) ++ DSI_PORT_WRITE(CTRL, DSI_PORT_READ(CTRL) | DSI0_CTRL_CTRL0); ++ else ++ DSI_PORT_WRITE(CTRL, DSI_PORT_READ(CTRL) | DSI1_CTRL_EN); ++ ++ /* Bring AFE out of reset. */ ++ if (dsi->port == 0) { ++ } else { ++ DSI_PORT_WRITE(PHY_AFEC0, ++ DSI_PORT_READ(PHY_AFEC0) & ++ ~DSI1_PHY_AFEC0_RESET); ++ } ++ ++ vc4_dsi_ulps(dsi, false); ++ ++ if (debug_dump_regs) { ++ DRM_INFO("DSI regs after:\n"); ++ vc4_dsi_dump_regs(dsi); ++ } ++ ++ ret = drm_panel_enable(dsi->panel); ++ if (ret) { ++ DRM_ERROR("Panel failed to enable\n"); ++ drm_panel_unprepare(dsi->panel); ++ return; ++ } ++} ++ ++static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host, ++ const struct mipi_dsi_msg *msg) ++{ ++ struct vc4_dsi *dsi = host_to_dsi(host); ++ struct mipi_dsi_packet packet; ++ u32 pkth = 0, pktc = 0; ++ int i, ret; ++ bool is_long = mipi_dsi_packet_format_is_long(msg->type); ++ u32 cmd_fifo_len = 0, pix_fifo_len = 0; ++ ++ mipi_dsi_create_packet(&packet, msg); ++ ++ pkth |= VC4_SET_FIELD(packet.header[0], DSI_TXPKT1H_BC_DT); ++ pkth |= VC4_SET_FIELD(packet.header[1] | ++ (packet.header[2] << 8), ++ DSI_TXPKT1H_BC_PARAM); ++ if (is_long) { ++ /* Divide data across the various FIFOs we have available. ++ * The command FIFO takes byte-oriented data, but is of ++ * limited size. The pixel FIFO (never actually used for ++ * pixel data in reality) is word oriented, and substantially ++ * larger. So, we use the pixel FIFO for most of the data, ++ * sending the residual bytes in the command FIFO at the start. ++ * ++ * With this arrangement, the command FIFO will never get full. ++ */ ++ if (packet.payload_length <= 16) { ++ cmd_fifo_len = packet.payload_length; ++ pix_fifo_len = 0; ++ } else { ++ cmd_fifo_len = (packet.payload_length % ++ DSI_PIX_FIFO_WIDTH); ++ pix_fifo_len = ((packet.payload_length - cmd_fifo_len) / ++ DSI_PIX_FIFO_WIDTH); ++ } ++ ++ WARN_ON_ONCE(pix_fifo_len >= DSI_PIX_FIFO_DEPTH); ++ ++ pkth |= VC4_SET_FIELD(cmd_fifo_len, DSI_TXPKT1H_BC_CMDFIFO); ++ } ++ ++ if (msg->rx_len) { ++ pktc |= VC4_SET_FIELD(DSI_TXPKT1C_CMD_CTRL_RX, ++ DSI_TXPKT1C_CMD_CTRL); ++ } else { ++ pktc |= VC4_SET_FIELD(DSI_TXPKT1C_CMD_CTRL_TX, ++ DSI_TXPKT1C_CMD_CTRL); ++ } ++ ++ for (i = 0; i < cmd_fifo_len; i++) ++ DSI_PORT_WRITE(TXPKT_CMD_FIFO, packet.payload[i]); ++ for (i = 0; i < pix_fifo_len; i++) { ++ const u8 *pix = packet.payload + cmd_fifo_len + i * 4; ++ ++ DSI_PORT_WRITE(TXPKT_PIX_FIFO, ++ pix[0] | ++ pix[1] << 8 | ++ pix[2] << 16 | ++ pix[3] << 24); ++ } ++ ++ if (msg->flags & MIPI_DSI_MSG_USE_LPM) ++ pktc |= DSI_TXPKT1C_CMD_MODE_LP; ++ if (is_long) ++ pktc |= DSI_TXPKT1C_CMD_TYPE_LONG; ++ ++ /* Send one copy of the packet. Larger repeats are used for pixel ++ * data in command mode. ++ */ ++ pktc |= VC4_SET_FIELD(1, DSI_TXPKT1C_CMD_REPEAT); ++ ++ pktc |= DSI_TXPKT1C_CMD_EN; ++ if (pix_fifo_len) { ++ pktc |= VC4_SET_FIELD(DSI_TXPKT1C_DISPLAY_NO_SECONDARY, ++ DSI_TXPKT1C_DISPLAY_NO); ++ } else { ++ pktc |= VC4_SET_FIELD(DSI_TXPKT1C_DISPLAY_NO_SHORT, ++ DSI_TXPKT1C_DISPLAY_NO); ++ } ++ ++ /* Enable the appropriate interrupt for the transfer completion. */ ++ dsi->xfer_result = 0; ++ reinit_completion(&dsi->xfer_completion); ++ DSI_PORT_WRITE(INT_STAT, DSI1_INT_TXPKT1_DONE | DSI1_INT_PHY_DIR_RTF); ++ if (msg->rx_len) { ++ DSI_PORT_WRITE(INT_EN, (DSI1_INTERRUPTS_ALWAYS_ENABLED | ++ DSI1_INT_PHY_DIR_RTF)); ++ } else { ++ DSI_PORT_WRITE(INT_EN, (DSI1_INTERRUPTS_ALWAYS_ENABLED | ++ DSI1_INT_TXPKT1_DONE)); ++ } ++ ++ /* Send the packet. */ ++ DSI_PORT_WRITE(TXPKT1H, pkth); ++ DSI_PORT_WRITE(TXPKT1C, pktc); ++ ++ if (!wait_for_completion_timeout(&dsi->xfer_completion, ++ msecs_to_jiffies(1000))) { ++ dev_err(&dsi->pdev->dev, "transfer interrupt wait timeout"); ++ dev_err(&dsi->pdev->dev, "instat: 0x%08x\n", ++ DSI_PORT_READ(INT_STAT)); ++ ret = -ETIMEDOUT; ++ } else { ++ ret = dsi->xfer_result; ++ } ++ ++ DSI_PORT_WRITE(INT_EN, DSI1_INTERRUPTS_ALWAYS_ENABLED); ++ ++ if (ret) ++ goto reset_fifo_and_return; ++ ++ if (ret == 0 && msg->rx_len) { ++ u32 rxpkt1h = DSI_PORT_READ(RXPKT1H); ++ u8 *msg_rx = msg->rx_buf; ++ ++ if (rxpkt1h & DSI_RXPKT1H_PKT_TYPE_LONG) { ++ u32 rxlen = VC4_GET_FIELD(rxpkt1h, ++ DSI_RXPKT1H_BC_PARAM); ++ ++ if (rxlen != msg->rx_len) { ++ DRM_ERROR("DSI returned %db, expecting %db\n", ++ rxlen, (int)msg->rx_len); ++ ret = -ENXIO; ++ goto reset_fifo_and_return; ++ } ++ ++ for (i = 0; i < msg->rx_len; i++) ++ msg_rx[i] = DSI_READ(DSI1_RXPKT_FIFO); ++ } else { ++ /* FINISHME: Handle AWER */ ++ ++ msg_rx[0] = VC4_GET_FIELD(rxpkt1h, ++ DSI_RXPKT1H_SHORT_0); ++ if (msg->rx_len > 1) { ++ msg_rx[1] = VC4_GET_FIELD(rxpkt1h, ++ DSI_RXPKT1H_SHORT_1); ++ } ++ } ++ } ++ ++ return ret; ++ ++reset_fifo_and_return: ++ DRM_ERROR("DSI transfer failed, resetting: %d\n", ret); ++ ++ DSI_PORT_WRITE(TXPKT1C, DSI_PORT_READ(TXPKT1C) & ~DSI_TXPKT1C_CMD_EN); ++ udelay(1); ++ DSI_PORT_WRITE(CTRL, ++ DSI_PORT_READ(CTRL) | ++ DSI_PORT_BIT(CTRL_RESET_FIFOS)); ++ ++ DSI_PORT_WRITE(TXPKT1C, 0); ++ DSI_PORT_WRITE(INT_EN, DSI1_INTERRUPTS_ALWAYS_ENABLED); ++ return ret; ++} ++ ++static int vc4_dsi_host_attach(struct mipi_dsi_host *host, ++ struct mipi_dsi_device *device) ++{ ++ struct vc4_dsi *dsi = host_to_dsi(host); ++ int ret = 0; ++ ++ dsi->lanes = device->lanes; ++ dsi->channel = device->channel; ++ dsi->format = device->format; ++ dsi->mode_flags = device->mode_flags; ++ ++ if (!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO)) { ++ dev_err(&dsi->pdev->dev, ++ "Only VIDEO mode panels supported currently.\n"); ++ return 0; ++ } ++ ++ dsi->panel = of_drm_find_panel(device->dev.of_node); ++ if (!dsi->panel) ++ return 0; ++ ++ ret = drm_panel_attach(dsi->panel, dsi->connector); ++ if (ret != 0) ++ return ret; ++ ++ drm_helper_hpd_irq_event(dsi->connector->dev); ++ ++ return 0; ++} ++ ++static int vc4_dsi_host_detach(struct mipi_dsi_host *host, ++ struct mipi_dsi_device *device) ++{ ++ struct vc4_dsi *dsi = host_to_dsi(host); ++ ++ if (dsi->panel) { ++ int ret = drm_panel_detach(dsi->panel); ++ ++ if (ret) ++ return ret; ++ ++ dsi->panel = NULL; ++ ++ drm_helper_hpd_irq_event(dsi->connector->dev); ++ } ++ ++ return 0; ++} ++ ++static const struct mipi_dsi_host_ops vc4_dsi_host_ops = { ++ .attach = vc4_dsi_host_attach, ++ .detach = vc4_dsi_host_detach, ++ .transfer = vc4_dsi_host_transfer, ++}; ++ ++static const struct drm_encoder_helper_funcs vc4_dsi_encoder_helper_funcs = { ++ .disable = vc4_dsi_encoder_disable, ++ .enable = vc4_dsi_encoder_enable, ++}; ++ ++static const struct of_device_id vc4_dsi_dt_match[] = { ++ { .compatible = "brcm,bcm2835-dsi1", (void *)(uintptr_t)1 }, ++ {} ++}; ++ ++static void dsi_handle_error(struct vc4_dsi *dsi, ++ irqreturn_t *ret, u32 stat, u32 bit, ++ const char *type) ++{ ++ if (!(stat & bit)) ++ return; ++ ++ DRM_ERROR("DSI%d: %s error\n", dsi->port, type); ++ *ret = IRQ_HANDLED; ++} ++ ++static irqreturn_t vc4_dsi_irq_handler(int irq, void *data) ++{ ++ struct vc4_dsi *dsi = data; ++ u32 stat = DSI_PORT_READ(INT_STAT); ++ irqreturn_t ret = IRQ_NONE; ++ ++ DSI_PORT_WRITE(INT_STAT, stat); ++ ++ dsi_handle_error(dsi, &ret, stat, ++ DSI1_INT_ERR_SYNC_ESC, "LPDT sync"); ++ dsi_handle_error(dsi, &ret, stat, ++ DSI1_INT_ERR_CONTROL, "data lane 0 sequence"); ++ dsi_handle_error(dsi, &ret, stat, ++ DSI1_INT_ERR_CONT_LP0, "LP0 contention"); ++ dsi_handle_error(dsi, &ret, stat, ++ DSI1_INT_ERR_CONT_LP1, "LP1 contention"); ++ dsi_handle_error(dsi, &ret, stat, ++ DSI1_INT_HSTX_TO, "HSTX timeout"); ++ dsi_handle_error(dsi, &ret, stat, ++ DSI1_INT_LPRX_TO, "LPRX timeout"); ++ dsi_handle_error(dsi, &ret, stat, ++ DSI1_INT_TA_TO, "turnaround timeout"); ++ dsi_handle_error(dsi, &ret, stat, ++ DSI1_INT_PR_TO, "peripheral reset timeout"); ++ ++ if (stat & (DSI1_INT_TXPKT1_DONE | DSI1_INT_PHY_DIR_RTF)) { ++ complete(&dsi->xfer_completion); ++ ret = IRQ_HANDLED; ++ } else if (stat & DSI1_INT_HSTX_TO) { ++ complete(&dsi->xfer_completion); ++ dsi->xfer_result = -ETIMEDOUT; ++ ret = IRQ_HANDLED; ++ } ++ ++ return ret; ++} ++ ++/** ++ * Exposes clocks generated by the analog PHY that are consumed by ++ * CPRMAN (clk-bcm2835.c). ++ */ ++static int ++vc4_dsi_init_phy_clocks(struct vc4_dsi *dsi) ++{ ++ struct device *dev = &dsi->pdev->dev; ++ const char *parent_name = __clk_get_name(dsi->pll_phy_clock); ++ static const struct { ++ const char *dsi0_name, *dsi1_name; ++ int div; ++ } phy_clocks[] = { ++ { "dsi0_byte", "dsi1_byte", 8 }, ++ { "dsi0_ddr2", "dsi1_ddr2", 4 }, ++ { "dsi0_ddr", "dsi1_ddr", 2 }, ++ }; ++ int i; ++ ++ dsi->clk_onecell.clk_num = ARRAY_SIZE(phy_clocks); ++ dsi->clk_onecell.clks = devm_kcalloc(dev, ++ dsi->clk_onecell.clk_num, ++ sizeof(*dsi->clk_onecell.clks), ++ GFP_KERNEL); ++ if (!dsi->clk_onecell.clks) ++ return -ENOMEM; ++ ++ for (i = 0; i < ARRAY_SIZE(phy_clocks); i++) { ++ struct clk_fixed_factor *fix = &dsi->phy_clocks[i]; ++ struct clk_init_data init; ++ struct clk *clk; ++ ++ /* We just use core fixed factor clock ops for the PHY ++ * clocks. The clocks are actually gated by the ++ * PHY_AFEC0_DDRCLK_EN bits, which we should be ++ * setting if we use the DDR/DDR2 clocks. However, ++ * vc4_dsi_encoder_enable() is setting up both AFEC0, ++ * setting both our parent DSI PLL's rate and this ++ * clock's rate, so it knows if DDR/DDR2 are going to ++ * be used and could enable the gates itself. ++ */ ++ fix->mult = 1; ++ fix->div = phy_clocks[i].div; ++ fix->hw.init = &init; ++ ++ memset(&init, 0, sizeof(init)); ++ init.parent_names = &parent_name; ++ init.num_parents = 1; ++ if (dsi->port == 1) ++ init.name = phy_clocks[i].dsi1_name; ++ else ++ init.name = phy_clocks[i].dsi0_name; ++ init.ops = &clk_fixed_factor_ops; ++ init.flags = CLK_IS_BASIC; ++ ++ clk = devm_clk_register(dev, &fix->hw); ++ if (IS_ERR(clk)) ++ return PTR_ERR(clk); ++ ++ dsi->clk_onecell.clks[i] = clk; ++ } ++ ++ return of_clk_add_provider(dev->of_node, ++ of_clk_src_onecell_get, ++ &dsi->clk_onecell); ++} ++ ++static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct drm_device *drm = dev_get_drvdata(master); ++ struct vc4_dev *vc4 = to_vc4_dev(drm); ++ struct vc4_dsi *dsi; ++ struct vc4_dsi_encoder *vc4_dsi_encoder; ++ const struct of_device_id *match; ++ dma_cap_mask_t dma_mask; ++ int ret; ++ ++ dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); ++ if (!dsi) ++ return -ENOMEM; ++ ++ match = of_match_device(vc4_dsi_dt_match, dev); ++ if (!match) ++ return -ENODEV; ++ ++ dsi->port = (uintptr_t)match->data; ++ ++ vc4_dsi_encoder = devm_kzalloc(dev, sizeof(*vc4_dsi_encoder), ++ GFP_KERNEL); ++ if (!vc4_dsi_encoder) ++ return -ENOMEM; ++ vc4_dsi_encoder->base.type = VC4_ENCODER_TYPE_DSI1; ++ vc4_dsi_encoder->dsi = dsi; ++ dsi->encoder = &vc4_dsi_encoder->base.base; ++ ++ dsi->pdev = pdev; ++ dsi->regs = vc4_ioremap_regs(pdev, 0); ++ if (IS_ERR(dsi->regs)) ++ return PTR_ERR(dsi->regs); ++ ++ if (DSI_PORT_READ(ID) != DSI_ID_VALUE) { ++ dev_err(dev, "Port returned 0x%08x for ID instead of 0x%08x\n", ++ DSI_PORT_READ(ID), DSI_ID_VALUE); ++ return -ENODEV; ++ } ++ ++ /* DSI1 has a broken AXI slave that doesn't respond to writes ++ * from the ARM. It does handle writes from the DMA engine, ++ * so set up a channel for talking to it. ++ */ ++ if (dsi->port == 1) { ++ dsi->reg_dma_mem = dma_alloc_coherent(dev, 4, ++ &dsi->reg_dma_paddr, ++ GFP_KERNEL); ++ if (!dsi->reg_dma_mem) { ++ DRM_ERROR("Failed to get DMA memory\n"); ++ return -ENOMEM; ++ } ++ ++ dma_cap_zero(dma_mask); ++ dma_cap_set(DMA_MEMCPY, dma_mask); ++ dsi->reg_dma_chan = dma_request_chan_by_mask(&dma_mask); ++ if (IS_ERR(dsi->reg_dma_chan)) { ++ ret = PTR_ERR(dsi->reg_dma_chan); ++ if (ret != -EPROBE_DEFER) ++ DRM_ERROR("Failed to get DMA channel: %d\n", ++ ret); ++ return ret; ++ } ++ ++ /* Get the physical address of the device's registers. The ++ * struct resource for the regs gives us the bus address ++ * instead. ++ */ ++ dsi->reg_paddr = be32_to_cpup(of_get_address(dev->of_node, ++ 0, NULL, NULL)); ++ } ++ ++ init_completion(&dsi->xfer_completion); ++ /* At startup enable error-reporting interrupts and nothing else. */ ++ DSI_PORT_WRITE(INT_EN, DSI1_INTERRUPTS_ALWAYS_ENABLED); ++ /* Clear any existing interrupt state. */ ++ DSI_PORT_WRITE(INT_STAT, DSI_PORT_READ(INT_STAT)); ++ ++ ret = devm_request_irq(dev, platform_get_irq(pdev, 0), ++ vc4_dsi_irq_handler, 0, "vc4 dsi", dsi); ++ if (ret) { ++ if (ret != -EPROBE_DEFER) ++ dev_err(dev, "Failed to get interrupt: %d\n", ret); ++ return ret; ++ } ++ ++ dsi->escape_clock = devm_clk_get(dev, "escape"); ++ if (IS_ERR(dsi->escape_clock)) { ++ ret = PTR_ERR(dsi->escape_clock); ++ if (ret != -EPROBE_DEFER) ++ dev_err(dev, "Failed to get escape clock: %d\n", ret); ++ return ret; ++ } ++ ++ dsi->pll_phy_clock = devm_clk_get(dev, "phy"); ++ if (IS_ERR(dsi->pll_phy_clock)) { ++ ret = PTR_ERR(dsi->pll_phy_clock); ++ if (ret != -EPROBE_DEFER) ++ dev_err(dev, "Failed to get phy clock: %d\n", ret); ++ return ret; ++ } ++ ++ dsi->pixel_clock = devm_clk_get(dev, "pixel"); ++ if (IS_ERR(dsi->pixel_clock)) { ++ ret = PTR_ERR(dsi->pixel_clock); ++ if (ret != -EPROBE_DEFER) ++ dev_err(dev, "Failed to get pixel clock: %d\n", ret); ++ return ret; ++ } ++ ++ /* The esc clock rate is supposed to always be 100Mhz. */ ++ ret = clk_set_rate(dsi->escape_clock, 100 * 1000000); ++ if (ret) { ++ dev_err(dev, "Failed to set esc clock: %d\n", ret); ++ return ret; ++ } ++ ++ ret = vc4_dsi_init_phy_clocks(dsi); ++ if (ret) ++ return ret; ++ ++ if (dsi->port == 1) ++ vc4->dsi1 = dsi; ++ ++ drm_encoder_init(drm, dsi->encoder, &vc4_dsi_encoder_funcs, ++ DRM_MODE_ENCODER_DSI, NULL); ++ drm_encoder_helper_add(dsi->encoder, &vc4_dsi_encoder_helper_funcs); ++ ++ dsi->connector = vc4_dsi_connector_init(drm, dsi); ++ if (IS_ERR(dsi->connector)) { ++ ret = PTR_ERR(dsi->connector); ++ goto err_destroy_encoder; ++ } ++ ++ dsi->dsi_host.ops = &vc4_dsi_host_ops; ++ dsi->dsi_host.dev = dev; ++ ++ mipi_dsi_host_register(&dsi->dsi_host); ++ ++ dev_set_drvdata(dev, dsi); ++ ++ pm_runtime_enable(dev); ++ ++ return 0; ++ ++err_destroy_encoder: ++ vc4_dsi_encoder_destroy(dsi->encoder); ++ ++ return ret; ++} ++ ++static void vc4_dsi_unbind(struct device *dev, struct device *master, ++ void *data) ++{ ++ struct drm_device *drm = dev_get_drvdata(master); ++ struct vc4_dev *vc4 = to_vc4_dev(drm); ++ struct vc4_dsi *dsi = dev_get_drvdata(dev); ++ ++ pm_runtime_disable(dev); ++ ++ vc4_dsi_connector_destroy(dsi->connector); ++ vc4_dsi_encoder_destroy(dsi->encoder); ++ ++ mipi_dsi_host_unregister(&dsi->dsi_host); ++ ++ clk_disable_unprepare(dsi->pll_phy_clock); ++ clk_disable_unprepare(dsi->escape_clock); ++ ++ if (dsi->port == 1) ++ vc4->dsi1 = NULL; ++} ++ ++static const struct component_ops vc4_dsi_ops = { ++ .bind = vc4_dsi_bind, ++ .unbind = vc4_dsi_unbind, ++}; ++ ++static int vc4_dsi_dev_probe(struct platform_device *pdev) ++{ ++ return component_add(&pdev->dev, &vc4_dsi_ops); ++} ++ ++static int vc4_dsi_dev_remove(struct platform_device *pdev) ++{ ++ component_del(&pdev->dev, &vc4_dsi_ops); ++ return 0; ++} ++ ++struct platform_driver vc4_dsi_driver = { ++ .probe = vc4_dsi_dev_probe, ++ .remove = vc4_dsi_dev_remove, ++ .driver = { ++ .name = "vc4_dsi", ++ .of_match_table = vc4_dsi_dt_match, ++ }, ++}; + +From a8252ac49ea4d23c2482dcc2e17b8895e74eb5c4 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Fri, 2 Dec 2016 14:48:12 +0100 +Subject: [PATCH 176/190] ARM: dts: bcm283x: Add VEC node in bcm283x.dtsi + +Add the VEC (Video EnCoder) node definition in bcm283x.dtsi. + +Signed-off-by: Boris Brezillon +Signed-off-by: Eric Anholt +(cherry picked from commit b899c45208d6f204a6da9a1132577993eeecf0fb) +--- + arch/arm/boot/dts/bcm283x.dtsi | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi +index 304dd291a9ae94700e8e628c0c9ebd3fb98abb19..ee69fd481fabd22d8f45ecdcffacdbb185e11f55 100644 +--- a/arch/arm/boot/dts/bcm283x.dtsi ++++ b/arch/arm/boot/dts/bcm283x.dtsi +@@ -520,6 +520,14 @@ + status = "disabled"; + }; + ++ vec: vec@7e806000 { ++ compatible = "brcm,bcm2835-vec"; ++ reg = <0x7e806000 0x1000>; ++ clocks = <&clocks BCM2835_CLOCK_VEC>; ++ interrupts = <2 27>; ++ status = "disabled"; ++ }; ++ + pixelvalve@7e807000 { + compatible = "brcm,bcm2835-pixelvalve2"; + reg = <0x7e807000 0x100>; + +From 80b784aa9111727a1536fb5625630ab883e31ab9 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Fri, 2 Dec 2016 14:48:13 +0100 +Subject: [PATCH 177/190] ARM: dts: bcm283x: Enable the VEC IP on all + RaspberryPi boards + +Enable the VEC IP on all RaspberryPi boards. + +Signed-off-by: Boris Brezillon +Signed-off-by: Eric Anholt +(cherry picked from commit 5ab1a37c6027c114a87a1ae32cfc5ef303d643c5) +--- + arch/arm/boot/dts/bcm2835-rpi.dtsi | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi +index 58f7d874c70a9cf965e10ae3f14fe3bb00846b71..023630efa7c1d8601ba5e83d2fdb38a7557b6460 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi +@@ -95,3 +95,8 @@ + &dsi1 { + power-domains = <&power RPI_POWER_DOMAIN_DSI1>; + }; ++ ++&vec { ++ power-domains = <&power RPI_POWER_DOMAIN_VEC>; ++ status = "okay"; ++}; + +From fefed2fac347a328b8a71318991a6ccd4d625964 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 23 Jan 2017 11:41:54 -0800 +Subject: [PATCH 178/190] BCM270X: Disable VEC unless vc4-kms-v3d is present. + +Signed-off-by: Eric Anholt +--- + arch/arm/boot/dts/bcm2708-rpi.dtsi | 4 ++++ + arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 7 +++++++ + 2 files changed, 11 insertions(+) + +diff --git a/arch/arm/boot/dts/bcm2708-rpi.dtsi b/arch/arm/boot/dts/bcm2708-rpi.dtsi +index ef14e9ac6cd2092efb1681682dd2d3c52b8abfd5..8bb9ca54a36f2ac29987ecc1c2738b6758849a16 100644 +--- a/arch/arm/boot/dts/bcm2708-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2708-rpi.dtsi +@@ -111,3 +111,7 @@ + &clocks { + firmware = <&firmware>; + }; ++ ++&vec { ++ status = "disabled"; ++}; +diff --git a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts +index 05faf1bfa1b7c73fd60b1efb813b969e10bbfefa..c57e795824e9261e0f60bcb40d6a57241019fd91 100644 +--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts ++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts +@@ -151,6 +151,13 @@ + }; + + fragment@18 { ++ target = <&vec>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@19 { + target = <&clocks>; + __overlay__ { + claim-clocks = < + +From 29059a451ac15090b051b9e3a9072a2513099ebe Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 1 Feb 2017 17:09:18 -0800 +Subject: [PATCH 179/190] drm/vc4: Name the primary and cursor planes in fkms. + +This makes debugging nicer, compared to trying to remember what the +IDs are. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/vc4/vc4_firmware_kms.c b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +index d18a1dae51a2275846c9826b5bf1ba57ae97b55c..e49ce68b607a7ffc2329e3235362f3bc21ed5cbb 100644 +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -267,7 +267,7 @@ static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev, + ret = drm_universal_plane_init(dev, plane, 0xff, + &vc4_plane_funcs, + primary ? &xrgb8888 : &argb8888, 1, +- type, NULL); ++ type, primary ? "primary" : "cursor"); + + if (type == DRM_PLANE_TYPE_PRIMARY) { + vc4_plane->fbinfo = + +From cb344e7984334a741c189b964bdad32f8afdc18f Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 1 Feb 2017 17:10:09 -0800 +Subject: [PATCH 180/190] drm/vc4: Add DRM_DEBUG_ATOMIC for the insides of + fkms. + +Trying to debug weston on fkms involved figuring out what calls I was +making to the firmware. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/drivers/gpu/drm/vc4/vc4_firmware_kms.c b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +index e49ce68b607a7ffc2329e3235362f3bc21ed5cbb..dbf065677202fbebf8e3a0cffbe880aa42daef3f 100644 +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -102,6 +102,11 @@ static int vc4_plane_set_primary_blank(struct drm_plane *plane, bool blank) + struct vc4_dev *vc4 = to_vc4_dev(plane->dev); + + u32 packet = blank; ++ ++ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary plane %s", ++ plane->base.id, plane->name, ++ blank ? "blank" : "unblank"); ++ + return rpi_firmware_property(vc4->firmware, + RPI_FIRMWARE_FRAMEBUFFER_BLANK, + &packet, sizeof(packet)); +@@ -149,6 +154,16 @@ static void vc4_primary_plane_atomic_update(struct drm_plane *plane, + WARN_ON_ONCE(vc4_plane->pitch != fb->pitches[0]); + } + ++ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary update %dx%d@%d +%d,%d 0x%08x/%d\n", ++ plane->base.id, plane->name, ++ state->crtc_w, ++ state->crtc_h, ++ bpp, ++ state->crtc_x, ++ state->crtc_y, ++ bo->paddr + fb->offsets[0], ++ fb->pitches[0]); ++ + ret = rpi_firmware_transaction(vc4->firmware, + RPI_FIRMWARE_CHAN_FB, + vc4_plane->fbinfo_bus_addr); +@@ -178,6 +193,15 @@ static void vc4_cursor_plane_atomic_update(struct drm_plane *plane, + WARN_ON_ONCE(fb->pitches[0] != state->crtc_w * 4); + WARN_ON_ONCE(fb->bits_per_pixel != 32); + ++ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] update %dx%d cursor at %d,%d (0x%08x/%d)", ++ plane->base.id, plane->name, ++ state->crtc_w, ++ state->crtc_h, ++ state->crtc_x, ++ state->crtc_y, ++ bo->paddr + fb->offsets[0], ++ fb->pitches[0]); ++ + ret = rpi_firmware_property(vc4->firmware, + RPI_FIRMWARE_SET_CURSOR_STATE, + &packet_state, +@@ -200,6 +224,8 @@ static void vc4_cursor_plane_atomic_disable(struct drm_plane *plane, + 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, + +From 7cb76db67b24f033a48fcc41b5db64198c6b59f4 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 2 Feb 2017 09:42:18 -0800 +Subject: [PATCH 181/190] drm/vc4: Fix sending of page flip completion events + in FKMS mode. + +In the rewrite of vc4_crtc.c for fkms, I dropped the part of the +CRTC's atomic flush handler that moved the completion event from the +proposed atomic state change to the CRTC's current state. That meant +that when full screen pageflipping happened (glxgears -fullscreen in +X, compton, por weston), the app would end up blocked firever waiting +to draw its next frame. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/drivers/gpu/drm/vc4/vc4_firmware_kms.c b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +index dbf065677202fbebf8e3a0cffbe880aa42daef3f..da818a207bfa639b8cea48d94bcf4566f97db816 100644 +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -338,6 +338,21 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc, + static void vc4_crtc_atomic_flush(struct drm_crtc *crtc, + struct drm_crtc_state *old_state) + { ++ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); ++ struct drm_device *dev = crtc->dev; ++ ++ if (crtc->state->event) { ++ unsigned long flags; ++ ++ crtc->state->event->pipe = drm_crtc_index(crtc); ++ ++ WARN_ON(drm_crtc_vblank_get(crtc) != 0); ++ ++ spin_lock_irqsave(&dev->event_lock, flags); ++ vc4_crtc->event = crtc->state->event; ++ crtc->state->event = NULL; ++ spin_unlock_irqrestore(&dev->event_lock, flags); ++ } + } + + static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc) + +From 73024c5a31635d4991db90642c8612511cfb5cd2 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 8 Feb 2017 15:00:54 -0800 +Subject: [PATCH 182/190] drm/vc4: Fulfill user BO creation requests from the + kernel BO cache. + +The from_cache flag was actually "the BO is invisible to userspace", +so we can repurpose to just zero out a cached BO and return it to +userspace. + +Improves wall time for a loop of 5 glsl-algebraic-add-add-1 by +-1.44989% +/- 0.862891% (n=28, 1 outlier removed from each that +appeared to be other system noise) + +Note that there's an intel-gpu-tools test to check for the proper +zeroing behavior here, which we continue to pass. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_bo.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c +index 3f6704cf6608d7be47637c6aa585de087b7f74ee..5ec14f25625dde6fd61e10415092fa25527cc151 100644 +--- a/drivers/gpu/drm/vc4/vc4_bo.c ++++ b/drivers/gpu/drm/vc4/vc4_bo.c +@@ -208,21 +208,22 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size) + } + + struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size, +- bool from_cache) ++ bool allow_unzeroed) + { + size_t size = roundup(unaligned_size, PAGE_SIZE); + struct vc4_dev *vc4 = to_vc4_dev(dev); + struct drm_gem_cma_object *cma_obj; ++ struct vc4_bo *bo; + + if (size == 0) + return ERR_PTR(-EINVAL); + + /* First, try to get a vc4_bo from the kernel BO cache. */ +- if (from_cache) { +- struct vc4_bo *bo = vc4_bo_get_from_cache(dev, size); +- +- if (bo) +- return bo; ++ bo = vc4_bo_get_from_cache(dev, size); ++ if (bo) { ++ if (!allow_unzeroed) ++ memset(bo->base.vaddr, 0, bo->base.base.size); ++ return bo; + } + + cma_obj = drm_gem_cma_create(dev, size); + +From 8b843fbc94dd5f3cc92699c8d0d8903ebb9089cb Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 9 Feb 2017 09:23:34 -0800 +Subject: [PATCH 183/190] drm/vc4: Fix OOPSes from trying to cache a partially + constructed BO. + +If a CMA allocation failed, the partially constructed BO would be +unreferenced through the normal path, and we might choose to put it in +the BO cache. If we then reused it before it expired from the cache, +the kernel would OOPS. + +Signed-off-by: Eric Anholt +Fixes: c826a6e10644 ("drm/vc4: Add a BO cache.") +--- + drivers/gpu/drm/vc4/vc4_bo.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c +index 5ec14f25625dde6fd61e10415092fa25527cc151..fd83a28076564b9ea5cf0f2ba29b884ee3c5af43 100644 +--- a/drivers/gpu/drm/vc4/vc4_bo.c ++++ b/drivers/gpu/drm/vc4/vc4_bo.c +@@ -314,6 +314,14 @@ void vc4_free_object(struct drm_gem_object *gem_bo) + goto out; + } + ++ /* If this object was partially constructed but CMA allocation ++ * had failed, just free it. ++ */ ++ if (!bo->base.vaddr) { ++ vc4_bo_destroy(bo); ++ goto out; ++ } ++ + cache_list = vc4_get_cache_list_for_size(dev, gem_bo->size); + if (!cache_list) { + vc4_bo_destroy(bo); + +From 142f6b052591eb5d3da338b9544df2a900e8b8d9 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 12 Oct 2015 08:58:08 -0700 +Subject: [PATCH 184/190] drm/vc4: Verify at boot that CMA doesn't cross a + 256MB boundary. + +I've seen lots of users cranking CMA up higher, so throw an error if +they do. + +Signed-off-by: Eric Anholt +--- + drivers/base/dma-contiguous.c | 1 + + drivers/gpu/drm/vc4/vc4_v3d.c | 18 ++++++++++++++++++ + mm/cma.c | 2 ++ + 3 files changed, 21 insertions(+) + +diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c +index e167a1e1bccb062efef2595fcd5299301a97df80..60f5c2591ccdb0202461458eab4035cfba731b8b 100644 +--- a/drivers/base/dma-contiguous.c ++++ b/drivers/base/dma-contiguous.c +@@ -35,6 +35,7 @@ + #endif + + struct cma *dma_contiguous_default_area; ++EXPORT_SYMBOL(dma_contiguous_default_area); + + /* + * Default global CMA area size can be defined in kernel's .config. +diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c +index 7cc346ad9b0baed63701d1fae8f0306aa7713129..1d9e5a6edd22c29ce8b2990c9c35627aa1af2bd8 100644 +--- a/drivers/gpu/drm/vc4/vc4_v3d.c ++++ b/drivers/gpu/drm/vc4/vc4_v3d.c +@@ -16,7 +16,10 @@ + * this program. If not, see . + */ + ++#include "linux/init.h" ++#include "linux/cma.h" + #include "linux/component.h" ++#include "linux/dma-contiguous.h" + #include "linux/pm_runtime.h" + #include "vc4_drv.h" + #include "vc4_regs.h" +@@ -185,8 +188,23 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data) + struct drm_device *drm = dev_get_drvdata(master); + struct vc4_dev *vc4 = to_vc4_dev(drm); + struct vc4_v3d *v3d = NULL; ++ struct cma *cma; + int ret; + ++ cma = dev_get_cma_area(dev); ++ if (!cma) ++ return -EINVAL; ++ ++ if ((cma_get_base(cma) & 0xf0000000) != ++ ((cma_get_base(cma) + cma_get_size(cma) - 1) & 0xf0000000)) { ++ DRM_ERROR("V3D requires that the CMA area (0x%08lx - 0x%08lx) " ++ "not span a 256MB boundary, or memory corruption " ++ "would happen.\n", ++ (long)cma_get_base(cma), ++ cma_get_base(cma) + cma_get_size(cma)); ++ return -EINVAL; ++ } ++ + v3d = devm_kzalloc(&pdev->dev, sizeof(*v3d), GFP_KERNEL); + if (!v3d) + return -ENOMEM; +diff --git a/mm/cma.c b/mm/cma.c +index c960459eda7e640ea55be1d4ed80c6a9125a8877..b50245282a18bc790da0f901944c2e670ffac2d2 100644 +--- a/mm/cma.c ++++ b/mm/cma.c +@@ -47,11 +47,13 @@ phys_addr_t cma_get_base(const struct cma *cma) + { + return PFN_PHYS(cma->base_pfn); + } ++EXPORT_SYMBOL(cma_get_base); + + unsigned long cma_get_size(const struct cma *cma) + { + return cma->count << PAGE_SHIFT; + } ++EXPORT_SYMBOL(cma_get_size); + + static unsigned long cma_bitmap_aligned_mask(const struct cma *cma, + int align_order) + +From c45c2efba49d217dd202c7aa6698838819beb67e Mon Sep 17 00:00:00 2001 +From: Scott Ellis +Date: Thu, 23 Feb 2017 11:56:20 -0500 +Subject: [PATCH 185/190] Add ads1015 driver to config + +--- + arch/arm/configs/bcm2709_defconfig | 2 +- + arch/arm/configs/bcmrpi_defconfig | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index d3fd0252f78ec72bd6d93322e781abc3609af01c..1a25a016a53badcb2cd76141d035d5552a72b2f8 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -833,9 +833,9 @@ CONFIG_VIDEO_OV7640=m + CONFIG_VIDEO_MT9V011=m + CONFIG_DRM=m + CONFIG_DRM_LOAD_EDID_FIRMWARE=y ++CONFIG_DRM_UDL=m + CONFIG_DRM_PANEL_SIMPLE=m + CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m +-CONFIG_DRM_UDL=m + CONFIG_DRM_VC4=m + CONFIG_FB=y + CONFIG_FB_BCM2708=y +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index 0768998e5cbcc96714d546f656ff59eafe2dc754..efc4898aca911d5c97426a38b0f1808b3c0d4baa 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -826,9 +826,9 @@ CONFIG_VIDEO_OV7640=m + CONFIG_VIDEO_MT9V011=m + CONFIG_DRM=m + CONFIG_DRM_LOAD_EDID_FIRMWARE=y ++CONFIG_DRM_UDL=m + CONFIG_DRM_PANEL_SIMPLE=m + CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m +-CONFIG_DRM_UDL=m + CONFIG_DRM_VC4=m + CONFIG_FB=y + CONFIG_FB_BCM2708=y + +From 26c424b1278ee59f8101ec98adbb03339dfdb083 Mon Sep 17 00:00:00 2001 +From: Michael Zoran +Date: Thu, 23 Feb 2017 17:54:31 -0800 +Subject: [PATCH 186/190] drm/vc4: Don't wait for vblank when updating the + cursor + +Commonly used desktop environments such as xfce4 and gnome +on debian sid can flood the graphics drivers with cursor +updates. Because the current implementation is waiting +for a vblank between cursor updates, this will cause the +display to hang for a long time since a typical refresh +rate is only 60Hz. + +This is unnecessary and unexpected by user mode software, +so simply swap out the cursor frame buffer without waiting. + +Signed-off-by: Michael Zoran +Reviewed-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_plane.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c +index 686cdd3c86f2e9178768282a0dd173850e0bf063..7bdbb0e2b50f9202efe1177df761b379f1232dbc 100644 +--- a/drivers/gpu/drm/vc4/vc4_plane.c ++++ b/drivers/gpu/drm/vc4/vc4_plane.c +@@ -20,6 +20,7 @@ + + #include "vc4_drv.h" + #include "vc4_regs.h" ++#include "drm_atomic.h" + #include "drm_atomic_helper.h" + #include "drm_fb_cma_helper.h" + #include "drm_plane_helper.h" +@@ -769,12 +770,6 @@ vc4_update_plane(struct drm_plane *plane, + if (!plane_state) + goto out; + +- /* If we're changing the cursor contents, do that in the +- * normal vblank-synced atomic path. +- */ +- if (fb != plane_state->fb) +- goto out; +- + /* No configuring new scaling in the fast path. */ + if (crtc_w != plane_state->crtc_w || + crtc_h != plane_state->crtc_h || +@@ -783,6 +778,11 @@ vc4_update_plane(struct drm_plane *plane, + goto out; + } + ++ if (fb != plane_state->fb) { ++ drm_atomic_set_fb_for_plane(plane->state, fb); ++ vc4_plane_async_set_fb(plane, fb); ++ } ++ + /* Set the cursor's position on the screen. This is the + * expected change from the drm_mode_cursor_universal() + * helper. + +From 51ed4d07d2ee6cc409cfcfe57075111f040b641f Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 6 Mar 2017 12:17:16 -0800 +Subject: [PATCH 187/190] panel-raspberrypi-touchscreen: Round up clk rate to + fix DSI panel. + +Commit 488f9bc8e3def93e0baef53cee2026c2cb0d8956 slightly increased the +reported rate of PLLD, so the clk driver decided that PLLD/3/8 was now +higher than our requested pixel clock rate and rejected it in favor of +PLLD/4/8, which then ran the pixel clock way out of spec. + +By bumping the requested clock rate just slightly, we get back to +PLLD/3/8 like we wanted and the panel displays content again. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +index 1a536fe4d040f5fafe324baee110a6225dd0be08..7f315f04b109621ca7f3861fdd8acf956e752629 100644 +--- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c ++++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +@@ -220,7 +220,12 @@ static const struct drm_display_mode rpi_touchscreen_modes[] = { + #define HBP 46 + #define HFP ((PIXEL_CLOCK / (VTOTAL * VREFRESH)) - (HACT + HSW + HBP)) + +- .clock = PIXEL_CLOCK / 1000, ++ /* Round up the pixel clock a bit (10khz), so that the ++ * "don't run things faster than the requested clock ++ * rate" rule of the clk driver doesn't reject the ++ * divide-by-3 mode due to rounding error. ++ */ ++ .clock = PIXEL_CLOCK / 1000 + 10, + .hdisplay = HACT, + .hsync_start = HACT + HFP, + .hsync_end = HACT + HFP + HSW, + +From 244ad5c32697ee6a86ad91de24e2fff4b6613981 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 13 Mar 2017 12:30:37 +0000 +Subject: [PATCH 188/190] thermal: Compatible strings for bcm2836, bcm2837 + +The upstream dt-bindings documentation for bcm2835-thermal (which +exists even though the driver isn't upstreamed) says to use +dedicated compatible strings on bcm2836 and bcm2837, even though +the downstream driver doesn't support them. The Pi2 DTB uses +"brcm,bcm2836-thermal", so the driver doesn't load. The Pi3 DTB +doesn't override the base value, but the arm64 Pi3 support uses "brcm,bcm2837-thermal". + +Solve the documentation problem by adding "brcm,bcm2836-thermal" and +"brcm,bcm2837-thermal" as alternative compatible strings for the +bcm2835-thermal driver. + +Signed-off-by: Phil Elwell +--- + drivers/thermal/bcm2835-thermal.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/thermal/bcm2835-thermal.c b/drivers/thermal/bcm2835-thermal.c +index c63fb9f9d143e19612a18fe530c7b2b3518a22a4..25b78c3eac1503fbc9e679b963a6284b673b2ed3 100644 +--- a/drivers/thermal/bcm2835-thermal.c ++++ b/drivers/thermal/bcm2835-thermal.c +@@ -89,6 +89,8 @@ static int bcm2835_thermal_remove(struct platform_device *pdev) + + static const struct of_device_id bcm2835_thermal_of_match_table[] = { + { .compatible = "brcm,bcm2835-thermal", }, ++ { .compatible = "brcm,bcm2836-thermal", }, ++ { .compatible = "brcm,bcm2837-thermal", }, + {}, + }; + MODULE_DEVICE_TABLE(of, bcm2835_thermal_of_match_table); + +From 0b71962faccc9830def0bd601c29c71b8c754454 Mon Sep 17 00:00:00 2001 +From: John Greb +Date: Wed, 8 Mar 2017 15:12:29 +0000 +Subject: [PATCH 189/190] Match dwc2 device-tree fifo sizes to the hardware + values. + +Since commit aa381a7259c3f53727bcaa8c5f9359e940a0e3fd was reverted with 3fa9538539ac737096c81f3315a14670b1609092 the g-tx-fifo-size array in the device-tree needs to match the preset values in the bcm2835. + +Resolves https://github.com/raspberrypi/linux/issues/1876 +--- + arch/arm/boot/dts/overlays/dwc2-overlay.dts | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/overlays/dwc2-overlay.dts b/arch/arm/boot/dts/overlays/dwc2-overlay.dts +index 527abc9f0ddf71f4dc7d58336d87684c931cc2f3..265a16bab008453edba198cf2366c423509d60d6 100644 +--- a/arch/arm/boot/dts/overlays/dwc2-overlay.dts ++++ b/arch/arm/boot/dts/overlays/dwc2-overlay.dts +@@ -15,7 +15,7 @@ + dr_mode = "otg"; + g-np-tx-fifo-size = <32>; + g-rx-fifo-size = <256>; +- g-tx-fifo-size = <256 128 128 64 64 64 32>; ++ g-tx-fifo-size = <512 512 512 512 512 768>; + status = "okay"; + }; + }; +@@ -24,6 +24,5 @@ + dr_mode = <&dwc2_usb>, "dr_mode"; + g-np-tx-fifo-size = <&dwc2_usb>,"g-np-tx-fifo-size:0"; + g-rx-fifo-size = <&dwc2_usb>,"g-rx-fifo-size:0"; +- g-tx-fifo-size = <&dwc2_usb>,"g-tx-fifo-size:0"; + }; + }; + +From 0c2b88f95778c87bbd5d0a480266c4f9a0ffdc35 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 7 Mar 2017 12:18:20 +0000 +Subject: [PATCH 190/190] BCM270X_DT: Invert Pi3 power LED to match fw change + +Firmware expgpio driver reworked due to complaint over +hotplug detect. +Requires power LED to change sense as firmware is no longer +inverting the read value. + +Signed-off-by: Dave Stevenson +--- + arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +index 173103aaca503833b5e29530ed94e14c7cab0444..b21d2866d204adc533b46d581028f290e5c34a3d 100644 +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +@@ -175,7 +175,7 @@ + pwr_led: pwr { + label = "led1"; + linux,default-trigger = "input"; +- gpios = <&expgpio 7 GPIO_ACTIVE_LOW>; ++ gpios = <&expgpio 7 0>; + }; + }; + diff --git a/projects/RPi2/patches/linux/linux-01-RPi_support.patch b/projects/RPi2/patches/linux/linux-01-RPi_support.patch index 797c5d6065..7f75b2cbcb 100644 --- a/projects/RPi2/patches/linux/linux-01-RPi_support.patch +++ b/projects/RPi2/patches/linux/linux-01-RPi_support.patch @@ -1,7 +1,7 @@ -From 468cd1d3694d2c7fa2126c4dff4c92cfe1c71c70 Mon Sep 17 00:00:00 2001 +From d1e917656833e0994b3bb740743c6ab9ae0652ad Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Thu, 19 Feb 2015 18:47:12 +0000 -Subject: [PATCH 001/143] smsx95xx: fix crimes against truesize +Subject: [PATCH 001/190] 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. @@ -48,10 +48,10 @@ index 831aa33d078ae7d2dd57fdded5de71d1eb915f99..b77935bded8c0ff7808b00f170ff10e5 usbnet_skb_return(dev, ax_skb); } -From bc9f373027da6cd14af74a5ceb6a250f9f26a704 Mon Sep 17 00:00:00 2001 +From e1d30654234dc753d725f314a0161976ec8611c4 Mon Sep 17 00:00:00 2001 From: Sam Nazarko Date: Fri, 1 Apr 2016 17:27:21 +0100 -Subject: [PATCH 002/143] smsc95xx: Experimental: Enable turbo_mode and +Subject: [PATCH 002/190] smsc95xx: Experimental: Enable turbo_mode and packetsize=2560 by default See: http://forum.kodi.tv/showthread.php?tid=285288 @@ -94,10 +94,10 @@ index b77935bded8c0ff7808b00f170ff10e594300ad0..693f163684de921404738e33244881e0 netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld\n", -From d7e10b62fb345e91e63aa5e9033508150adc835c Mon Sep 17 00:00:00 2001 +From 14f6e078286abd55b3bdc8514be8cd4157aa3b7d Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 17:26:38 +0000 -Subject: [PATCH 003/143] Allow mac address to be set in smsc95xx +Subject: [PATCH 003/190] Allow mac address to be set in smsc95xx Signed-off-by: popcornmix --- @@ -193,10 +193,10 @@ index 693f163684de921404738e33244881e0aab92ec9..df60c989fc229bf0aab3c27e95ccd453 eth_hw_addr_random(dev->net); netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n"); -From 1ce0d09afcddde03315a95fbdd9eb451e9d5beb5 Mon Sep 17 00:00:00 2001 +From a595173c0c0e0f96f85e91dda95c75b26a76980b Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 13 Mar 2015 12:43:36 +0000 -Subject: [PATCH 004/143] Protect __release_resource against resources without +Subject: [PATCH 004/190] Protect __release_resource against resources without parents Without this patch, removing a device tree overlay can crash here. @@ -224,10 +224,10 @@ index 9b5f04404152c296af3a96132f27cfc80ffa9af9..f8a9af6e6b915812be2ba2c1c2b40106 for (;;) { tmp = *p; -From f1efecc4cc9a7bc17bcd05b760c56abd3c35b1c7 Mon Sep 17 00:00:00 2001 +From 55aa002ca4f4ee3171e05ece1af544d20420357e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Dec 2014 16:07:15 -0800 -Subject: [PATCH 005/143] mm: Remove the PFN busy warning +Subject: [PATCH 005/190] mm: Remove the PFN busy warning See commit dae803e165a11bc88ca8dbc07a11077caf97bbcb -- the warning is expected sometimes when using CMA. However, that commit still spams @@ -239,7 +239,7 @@ Signed-off-by: Eric Anholt 1 file changed, 2 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c -index f3e0c69a97b76997d9fa65cda0b7e1b1fb8fa29a..c0ef4472377fe5eea65b73d9764e464d72985b70 100644 +index 1a5f6655958e16ec09584c79405991dc248d2852..8068e8f926d87c02ac60f583d9b4cdefcdc2b146 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -7361,8 +7361,6 @@ int alloc_contig_range(unsigned long start, unsigned long end, @@ -252,10 +252,10 @@ index f3e0c69a97b76997d9fa65cda0b7e1b1fb8fa29a..c0ef4472377fe5eea65b73d9764e464d goto done; } -From a6ed755bf9e4e175e8316ce5ca49475c925b06b7 Mon Sep 17 00:00:00 2001 +From 707bedaadca8a746630e4a9c41892d5fe4e1fd1e Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 4 Dec 2015 17:41:50 +0000 -Subject: [PATCH 006/143] irq-bcm2836: Prevent spurious interrupts, and trap +Subject: [PATCH 006/190] irq-bcm2836: Prevent spurious interrupts, and trap them early The old arch-specific IRQ macros included a dsb to ensure the @@ -282,10 +282,10 @@ index e7463e3c08143acae3e8cc5682f918c6a0b07ebd..a8db33b50ad9ff83d284fa54fe4d3b65 #endif } else if (stat) { -From 1a63d13766b406f3c98a86c063e7d80e25f584bb Mon Sep 17 00:00:00 2001 +From 5709d5baf8b71d3a7e06e43c5afa68cbf6575862 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 007/143] irqchip: bcm2835: Add FIQ support +Subject: [PATCH 007/190] irqchip: bcm2835: Add FIQ support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -414,10 +414,10 @@ index 44d7c38dde479d771f3552e914bf8c1c1f5019f7..42ff5e6a8e0d532f5b60a1e7af7cc4d9 } -From 98c24bb5c2f7eab74c8307fde5c638cd44e1cc68 Mon Sep 17 00:00:00 2001 +From 6120b7ae9818c89da12301de5c8fca8761d92c0e 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 008/143] irqchip: irq-bcm2835: Add 2836 FIQ support +Subject: [PATCH 008/190] irqchip: irq-bcm2835: Add 2836 FIQ support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -516,10 +516,10 @@ index 42ff5e6a8e0d532f5b60a1e7af7cc4d941bd5008..eccf6ed025299cb480884f5bcbe77abf for (b = 0; b < NR_BANKS; b++) { for (i = 0; i < bank_irqs[b]; i++) { -From 44c736dd9491af829bd0c5684f5bbe883e09c2d1 Mon Sep 17 00:00:00 2001 +From c122f3bf18ae3def1f9e7b11f3b49a77da01ce9b Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 14 Jul 2015 10:26:09 +0100 -Subject: [PATCH 009/143] spidev: Add "spidev" compatible string to silence +Subject: [PATCH 009/190] spidev: Add "spidev" compatible string to silence warning See: https://github.com/raspberrypi/linux/issues/1054 @@ -540,10 +540,10 @@ index 9e2e099baf8ca5cc6510912a36d4ca03daeb8273..e59640942826db2ea14d0bde0ff5ab22 }; MODULE_DEVICE_TABLE(of, spidev_dt_ids); -From 4679b462878b70c11be6f05d70aaf411af8f0c94 Mon Sep 17 00:00:00 2001 +From 93a580f9d2b0f41bf30550529dff21478d8f1526 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 30 Jun 2015 14:12:42 +0100 -Subject: [PATCH 010/143] serial: 8250: Don't crash when nr_uarts is 0 +Subject: [PATCH 010/190] serial: 8250: Don't crash when nr_uarts is 0 --- drivers/tty/serial/8250/8250_core.c | 2 ++ @@ -563,10 +563,10 @@ index 76e03a7de9cc3d790a230948f599ef2db4b93249..0a172c2e6fa288de1e080463e897ea85 for (i = 0; i < nr_uarts; i++) { struct uart_8250_port *up = &serial8250_ports[i]; -From 7afdc575c0f1518aad2b980b7ff34571d9d5963f Mon Sep 17 00:00:00 2001 +From 50070832c703415df6aad13534498057c1e1ecad Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 3 Jan 2017 18:25:01 +0000 -Subject: [PATCH 011/143] Revert "pinctrl: bcm2835: switch to GPIOLIB_IRQCHIP" +Subject: [PATCH 011/190] Revert "pinctrl: bcm2835: switch to GPIOLIB_IRQCHIP" This reverts commit 85ae9e512f437cd09bf61564bdba29ab88bab3e3. --- @@ -860,10 +860,10 @@ index 85d0091128644c446aed878e87769e82c77c3ebf..4f2621272bfd5cbc0d691d2fabe89e2e if (IS_ERR(pc->pctl_dev)) { gpiochip_remove(&pc->gpio_chip); -From bf0a2edf0c0a2ebdd6e83fd18cb83e7723425ce4 Mon Sep 17 00:00:00 2001 +From 8cc90808c4fafe06a0f7e360de91570b60fc8743 Mon Sep 17 00:00:00 2001 From: notro Date: Thu, 10 Jul 2014 13:59:47 +0200 -Subject: [PATCH 012/143] pinctrl-bcm2835: Set base to 0 give expected gpio +Subject: [PATCH 012/190] pinctrl-bcm2835: Set base to 0 give expected gpio numbering Signed-off-by: Noralf Tronnes @@ -885,10 +885,10 @@ index 4f2621272bfd5cbc0d691d2fabe89e2ee428d6db..5b7cb4c415e19f98e25b221ab0ad36b6 .can_sleep = false, }; -From b769e2efdc8f7c809c5d83c0daa8a1a452e890db Mon Sep 17 00:00:00 2001 +From 7cb1239db975b8d6bd085f6fc35475988de7e418 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 26 Feb 2015 09:58:22 +0000 -Subject: [PATCH 013/143] pinctrl-bcm2835: Only request the interrupts listed +Subject: [PATCH 013/190] pinctrl-bcm2835: Only request the interrupts listed in the DTB Although the GPIO controller can generate three interrupts (four counting @@ -915,10 +915,10 @@ index 5b7cb4c415e19f98e25b221ab0ad36b6885dae4c..6351fe7f8e314ac5ebb102dd20847b38 pc->irq_data[i].irqgroup = i; -From c7575d85ded4666e609af7c4a65663379c5b7ffb Mon Sep 17 00:00:00 2001 +From 55f317c43b0d019fff5bebea158775e3dc9134ab Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 24 Jun 2015 14:10:44 +0100 -Subject: [PATCH 014/143] spi-bcm2835: Support pin groups other than 7-11 +Subject: [PATCH 014/190] 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 @@ -999,10 +999,10 @@ index f35cc10772f6670397ea923ad30158270dd68578..5dfe20ffc2866fa6789825016c585175 /* and set up the "mode" and level */ dev_info(&spi->dev, "setting up native-CS%i as GPIO %i\n", -From 4059c76642b41887bff173ca7c36d738a1d12daf Mon Sep 17 00:00:00 2001 +From 0f658a1ede61a3841cd5f11a1ce9b1c6fda9e7c7 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 1 Jul 2016 22:09:24 +0100 -Subject: [PATCH 015/143] spi-bcm2835: Disable forced software CS +Subject: [PATCH 015/190] 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 @@ -1036,10 +1036,10 @@ index 5dfe20ffc2866fa6789825016c585175a29705b6..8493474d286f7a1ac6454a22c61c8c2c return 0; } -From 3946ca2d555be10ee4025995a896a261546dbb16 Mon Sep 17 00:00:00 2001 +From 0b8bd6f69a5b3e8c617d789e190a4a4c451c12a7 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 8 Nov 2016 21:35:38 +0000 -Subject: [PATCH 016/143] spi-bcm2835: Remove unused code +Subject: [PATCH 016/190] spi-bcm2835: Remove unused code --- drivers/spi/spi-bcm2835.c | 61 ----------------------------------------------- @@ -1127,10 +1127,10 @@ index 8493474d286f7a1ac6454a22c61c8c2cef9121bf..33d75ad38a7f77d085321ace9101900a } -From 3e2637b9690a7170181a28e173be2df710bc42b0 Mon Sep 17 00:00:00 2001 +From 7fa50826d3b24f16e9edabfc9c0939041b2cf5ad 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 017/143] ARM: bcm2835: Set Serial number and Revision +Subject: [PATCH 017/190] ARM: bcm2835: Set Serial number and Revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -1183,10 +1183,10 @@ index 0c1edfc98696da0e0bb7f4a18cdfbcdd27a9795d..8f152266ba9b470df2eaaed9ebcf158e static const char * const bcm2835_compat[] = { -From 5ae2a094dc3d45ed43fc10955946a455614deed2 Mon Sep 17 00:00:00 2001 +From 678fb328a55e2ce06390c3c79c0e88b04db51f18 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 018/143] dmaengine: bcm2835: Load driver early and support +Subject: [PATCH 018/190] dmaengine: bcm2835: Load driver early and support legacy API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -1289,10 +1289,10 @@ index e18dc596cf2447fa9ef7e41b62d9396e29043426..80d35f760b4a4a51e60c355a84d538ba MODULE_ALIAS("platform:bcm2835-dma"); MODULE_DESCRIPTION("BCM2835 DMA engine driver"); -From ec29a80aa532673f479214b409dca3bbda1ad682 Mon Sep 17 00:00:00 2001 +From a868c95ac6626320fbb3dc99f67e43d566cd782e Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 25 Jan 2016 17:25:12 +0000 -Subject: [PATCH 019/143] firmware: Updated mailbox header +Subject: [PATCH 019/190] firmware: Updated mailbox header --- include/soc/bcm2835/raspberrypi-firmware.h | 9 +++++++++ @@ -1353,10 +1353,10 @@ index cb979ad90401e299344dd5fae38d09c489d8bd58..30fb37fe175df604a738258a2a632bca RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, -From 574fd69f5a7a477bbdb4b702fbd9ed4c771754ec Mon Sep 17 00:00:00 2001 +From 834b8d57570eb6a7d7c3887a24b5ce0d6a9e1e95 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 15 Jun 2016 16:48:41 +0100 -Subject: [PATCH 020/143] rtc: Add SPI alias for pcf2123 driver +Subject: [PATCH 020/190] rtc: Add SPI alias for pcf2123 driver Without this alias, Device Tree won't cause the driver to be loaded. @@ -1376,10 +1376,10 @@ index 8895f77726e8da5444afcd602dceff8f25a9b3fd..1833b8853ceb0e6147cceb93a00e558c MODULE_LICENSE("GPL"); +MODULE_ALIAS("spi:rtc-pcf2123"); -From 9caaab7c7d8bed852d27b583965a6058b98f57af Mon Sep 17 00:00:00 2001 +From d226a774328346e829a0b84046019174ababcb2d 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 021/143] watchdog: bcm2835: Support setting reboot partition +Subject: [PATCH 021/190] watchdog: bcm2835: Support setting reboot partition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -1503,10 +1503,10 @@ index c32c45bd8b097889c8f322255fa63c8ed507d6ab..ef02dfa23aa774e1cdf75f935c5de985 register_restart_handler(&wdt->restart_handler); if (pm_power_off == NULL) -From 232d0798c565f9ebf55bf1e2d2311b3c5ccdd393 Mon Sep 17 00:00:00 2001 +From 44473964e874063958ebc6feedeb9be246515233 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 5 Apr 2016 19:40:12 +0100 -Subject: [PATCH 022/143] reboot: Use power off rather than busy spinning when +Subject: [PATCH 022/190] reboot: Use power off rather than busy spinning when halt is requested --- @@ -1529,10 +1529,10 @@ index 3fa867a2aae672755c6ce6448f4148c989dbf964..80dca8dcd6709034b643c6a3f35729e0 /* -From efde81aa7c10d0d6e9c24e7cc8503ce0996faca9 Mon Sep 17 00:00:00 2001 +From fe3514b53963b85ca31f2fbbc708b9227416548b Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 9 Nov 2016 13:02:52 +0000 -Subject: [PATCH 023/143] bcm: Make RASPBERRYPI_POWER depend on PM +Subject: [PATCH 023/190] bcm: Make RASPBERRYPI_POWER depend on PM --- drivers/soc/bcm/Kconfig | 1 + @@ -1551,10 +1551,10 @@ index a39b0d58ddd0fdf0ac1cc7295f8aafb12546e226..e037a6dd79d1881a09e3ca9115782709 help This enables support for the RPi power domains which can be enabled -From a0c1361b3b8584885facacada6d30f09470ce3bb Mon Sep 17 00:00:00 2001 +From dbeeb2973e84b71eebc37cb8f75be56251abf775 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Fri, 2 Sep 2016 16:45:27 +0100 -Subject: [PATCH 024/143] Register the clocks early during the boot process, so +Subject: [PATCH 024/190] 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. @@ -1599,10 +1599,10 @@ index 0d14409097e777ce4546de30e9278fdebf74ec44..093694e00caec6e133eb26712f890691 MODULE_AUTHOR("Eric Anholt "); MODULE_DESCRIPTION("BCM2835 clock driver"); -From c3b7ffe0ce627827234c4012de92f199831caefb Mon Sep 17 00:00:00 2001 +From 26aa42e837a555ca85652e2be190934e930f47a0 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 6 Dec 2016 17:05:39 +0000 -Subject: [PATCH 025/143] bcm2835-rng: Avoid initialising if already enabled +Subject: [PATCH 025/190] bcm2835-rng: Avoid initialising if already enabled Avoids the 0x40000 cycles of warmup again if firmware has already used it --- @@ -1628,10 +1628,10 @@ index 574211a495491d9d6021dcaefe4274a63ed02055..e66c0fca8c6090e32f72796c0877a1cf err = hwrng_register(&bcm2835_rng_ops); if (err) { -From 5bfe6e7bc831a0e96fa156a19886809aff0328ca Mon Sep 17 00:00:00 2001 +From 328412e0e0f6b85ca305a4a49794f0e72092e38a Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 24 Aug 2016 16:28:44 +0100 -Subject: [PATCH 026/143] kbuild: Ignore dtco targets when filtering symbols +Subject: [PATCH 026/190] kbuild: Ignore dtco targets when filtering symbols --- scripts/Kbuild.include | 2 +- @@ -1651,10 +1651,10 @@ index 179219845dfcdfbeb586d12c5ec1296095d9fbf4..e0743e44f84188667a0c322e8c3d36f1 esac | tr ";" "\n" | sed -rn 's/^.*=== __KSYM_(.*) ===.*$$/KSYM_\1/p' -From 591508cc26f195e95549de1146bc05d8f21c5dee Mon Sep 17 00:00:00 2001 +From da4f5fa22c1f3e7bae55ca76ddeffa25e8ca1083 Mon Sep 17 00:00:00 2001 From: Robert Tiemann Date: Mon, 20 Jul 2015 11:01:25 +0200 -Subject: [PATCH 027/143] BCM2835_DT: Fix I2S register map +Subject: [PATCH 027/190] BCM2835_DT: Fix I2S register map --- Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt | 4 ++-- @@ -1692,10 +1692,10 @@ index 65783de0aedf3da79adc36fd077b7a89954ddb6b..a89fe4220fdc3f26f75ee66daf187554 dmas = <&dma 2>, <&dma 3>; -From 01804d5ae241e785859bd18934674c00fa692dc3 Mon Sep 17 00:00:00 2001 +From decba833672c4b549c5206c56a8bfc6769ba76d0 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 12 May 2013 12:24:19 +0100 -Subject: [PATCH 028/143] Main bcm2708/bcm2709 linux port +Subject: [PATCH 028/190] Main bcm2708/bcm2709 linux port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -1902,10 +1902,10 @@ index cfb4b4496dd9f61362dea012176c146120fada07..d9c6c217c4d6a2408abe2665bf7f2700 MODULE_AUTHOR("Lubomir Rintel "); MODULE_DESCRIPTION("BCM2835 mailbox IPC driver"); -From 228c89bd9ddd3b365c7eaa3c03d575bc794f7de7 Mon Sep 17 00:00:00 2001 +From 2d973c946e8f3e9a0b55e806bebfc733628c9852 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:46:17 +0100 -Subject: [PATCH 029/143] Add dwc_otg driver +Subject: [PATCH 029/190] Add dwc_otg driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -62962,10 +62962,10 @@ index 0000000000000000000000000000000000000000..cdc9963176e5a4a0d5250613b61e26c5 +test_main(); +0; -From f68c23214b22436e79194926e525fb6c0175576c Mon Sep 17 00:00:00 2001 +From eac25e87a2ca3a8cee733cda21c722a3427b9c1a Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 17:06:34 +0100 -Subject: [PATCH 030/143] bcm2708 framebuffer driver +Subject: [PATCH 030/190] bcm2708 framebuffer driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -66424,10 +66424,10 @@ index 3c14e43b82fefe1d32f591d1b2f61d2cd28d0fa8..7626beb6a5bb8df601ddf0f6e6909d1f +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 -From bdf4d5ad586e9074aacf2e7942335268f43162e3 Mon Sep 17 00:00:00 2001 +From 4fa6dd21376ce0220bd0e5e3ecb9d956c796a126 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:22:53 +0100 -Subject: [PATCH 031/143] dmaengine: Add support for BCM2708 +Subject: [PATCH 031/190] dmaengine: Add support for BCM2708 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -67058,10 +67058,10 @@ index 0000000000000000000000000000000000000000..c5bfff2765be4606077e6c8af73040ec + +#endif /* _PLAT_BCM2708_DMA_H */ -From 14cfe758a49f17af11460525c1d0d76012e10b46 Mon Sep 17 00:00:00 2001 +From 7b93c5b9222abb422f6d40abc3f6efe2c7a61a46 Mon Sep 17 00:00:00 2001 From: gellert Date: Fri, 15 Aug 2014 16:35:06 +0100 -Subject: [PATCH 032/143] MMC: added alternative MMC driver +Subject: [PATCH 032/190] MMC: added alternative MMC driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -68811,10 +68811,10 @@ index 0000000000000000000000000000000000000000..4fe8d1fe44578fbefcd48f8c327ba3d0 +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Gellert Weisz"); -From c2d33aadf0cf3d1c68c2dde3e48d6b335679816a Mon Sep 17 00:00:00 2001 +From 3e0108a5f4bab826b048f98655974e737de02623 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 25 Mar 2015 17:49:47 +0000 -Subject: [PATCH 033/143] Adding bcm2835-sdhost driver, and an overlay to +Subject: [PATCH 033/190] Adding bcm2835-sdhost driver, and an overlay to enable it BCM2835 has two SD card interfaces. This driver uses the other one. @@ -71219,10 +71219,10 @@ index 0000000000000000000000000000000000000000..a9bc79bfdbb71807819dfe2d8f165144 +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Phil Elwell"); -From 00496b5cfe106d6817de8a73031f1e935e54f4bb Mon Sep 17 00:00:00 2001 +From 2c3bfe168baa3d99b7b817162bf3f2405120b2b8 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 11 May 2016 12:50:33 +0100 -Subject: [PATCH 034/143] mmc: Add MMC_QUIRK_ERASE_BROKEN for some cards +Subject: [PATCH 034/190] mmc: Add MMC_QUIRK_ERASE_BROKEN for some cards Some SD cards have been found that corrupt data when small blocks are erased. Add a quirk to indicate that ERASE should not be used, @@ -71358,10 +71358,10 @@ index 95d69d4982965aa30fb65d9ffecfad13f4e7be8f..a97b881a04f4b3294cf3ede393cde717 unsigned int erase_shift; /* if erase unit is power 2 */ unsigned int pref_erase; /* in sectors */ -From ca13f6a5ce9cb58b3587bf0cfd8bfc622ec3da63 Mon Sep 17 00:00:00 2001 +From 84801dd88cc565a93de15e4b5d81d2459112b150 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:31:47 +0100 -Subject: [PATCH 035/143] cma: Add vc_cma driver to enable use of CMA +Subject: [PATCH 035/190] cma: Add vc_cma driver to enable use of CMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -72697,10 +72697,10 @@ index 0000000000000000000000000000000000000000..be2819d5d41f9d5ed65daf8eedb94c9e + +#endif /* VC_CMA_H */ -From 6174e627557707aa9ec6b80ea852a4abce9f85a2 Mon Sep 17 00:00:00 2001 +From 56add8155e63509b018673bef8f54aa2df627858 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 26 Mar 2012 22:15:50 +0100 -Subject: [PATCH 036/143] bcm2708: alsa sound driver +Subject: [PATCH 036/190] bcm2708: alsa sound driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -75435,10 +75435,10 @@ index 0000000000000000000000000000000000000000..af3e6eb690113fc32ce9e06bd2f0f294 + +#endif // _VC_AUDIO_DEFS_H_ -From a32d0d6bbe4bb394ac6724af37583d8c01973a67 Mon Sep 17 00:00:00 2001 +From 0d384cdc70ea243666b4abb77aee8f9cc91e1947 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 28 Oct 2016 15:36:43 +0100 -Subject: [PATCH 037/143] vc_mem: Add vc_mem driver for querying firmware +Subject: [PATCH 037/190] vc_mem: Add vc_mem driver for querying firmware memory addresses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -75962,10 +75962,10 @@ index 0000000000000000000000000000000000000000..20a475377eb3078ea1ecaef2b24efc35 + +#endif /* _VC_MEM_H */ -From c00e9788d5f56d3e876fe2127e9d80da8a456584 Mon Sep 17 00:00:00 2001 +From c1b9d636439bac24d32f07062453895a34d54fa3 Mon Sep 17 00:00:00 2001 From: Tim Gover Date: Tue, 22 Jul 2014 15:41:04 +0100 -Subject: [PATCH 038/143] vcsm: VideoCore shared memory service for BCM2835 +Subject: [PATCH 038/190] vcsm: VideoCore shared memory service for BCM2835 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -80372,10 +80372,10 @@ index 0000000000000000000000000000000000000000..334f36d0d697b047df2922b5f2db67f3 + +#endif /* __VMCS_SM_IOCTL_H__INCLUDED__ */ -From 32efcf2207a132a8e8d40424646b0e726e19e377 Mon Sep 17 00:00:00 2001 +From 1f931d0842ae1498d3b132db8705854957dbdb20 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Fri, 21 Aug 2015 23:14:48 +0100 -Subject: [PATCH 039/143] Add /dev/gpiomem device for rootless user GPIO access +Subject: [PATCH 039/190] Add /dev/gpiomem device for rootless user GPIO access Signed-off-by: Luke Wren @@ -80686,10 +80686,10 @@ index 0000000000000000000000000000000000000000..911f5b7393ed48ceed8751f06967ae64 +MODULE_DESCRIPTION("gpiomem driver for accessing GPIO from userspace"); +MODULE_AUTHOR("Luke Wren "); -From 227fa137a8d33de43c3a44e26d342a0192d6177b Mon Sep 17 00:00:00 2001 +From 3c245d477db104e2cfa1334ed1d1f79f34056902 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Sat, 5 Sep 2015 01:14:45 +0100 -Subject: [PATCH 040/143] Add SMI driver +Subject: [PATCH 040/190] Add SMI driver Signed-off-by: Luke Wren --- @@ -82640,10 +82640,10 @@ index 0000000000000000000000000000000000000000..ee3a75edfc033eeb0d90a687ffb68b10 + +#endif /* BCM2835_SMI_H */ -From c21d7f46c064ef8d4be52013e5c9760c4f85202b Mon Sep 17 00:00:00 2001 +From da256321f9f8e1e95ec5d9f6179cae24a8a9cb0a Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Tue, 26 Apr 2016 14:59:21 +0000 -Subject: [PATCH 041/143] MISC: bcm2835: smi: use clock manager and fix reload +Subject: [PATCH 041/190] MISC: bcm2835: smi: use clock manager and fix reload issues Use clock manager instead of self-made clockmanager. @@ -82813,10 +82813,10 @@ index 63a4ea08b9930a3a31a985f0a1d969b488ed49ec..1261540703127d1d63b9f3c87042c6e5 return 0; } -From 5d7a61f480af9494f6986a02ae3328854b6ead05 Mon Sep 17 00:00:00 2001 +From 314ca0c23570d6428dbc8a9269638dec38b21f75 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Sat, 5 Sep 2015 01:16:10 +0100 -Subject: [PATCH 042/143] Add SMI NAND driver +Subject: [PATCH 042/190] Add SMI NAND driver Signed-off-by: Luke Wren --- @@ -83181,10 +83181,10 @@ index 0000000000000000000000000000000000000000..02adda6da18bd0ba9ab19a104975b79d + ("Driver for NAND chips using Broadcom Secondary Memory Interface"); +MODULE_AUTHOR("Luke Wren "); -From 1995e1c034599ce8a4bad906a7935160058f79a9 Mon Sep 17 00:00:00 2001 +From b6bb92b2d8a850ffb75972efb6b9e8475a4c7578 Mon Sep 17 00:00:00 2001 From: Aron Szabo Date: Sat, 16 Jun 2012 12:15:55 +0200 -Subject: [PATCH 043/143] lirc: added support for RaspberryPi GPIO +Subject: [PATCH 043/190] lirc: added support for RaspberryPi GPIO lirc_rpi: Use read_current_timer to determine transmitter delay. Thanks to jjmz and others See: https://github.com/raspberrypi/linux/issues/525 @@ -84047,10 +84047,10 @@ index 0000000000000000000000000000000000000000..fb69624ccef00ddbdccf8256d6baf1b1 + +#endif -From 3c4052e9e9b9835346794628a416afdb8286f65b Mon Sep 17 00:00:00 2001 +From 435f90d39ab8a7bd738ee2316f4568b4019f9f62 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:49:20 +0100 -Subject: [PATCH 044/143] Add cpufreq driver +Subject: [PATCH 044/190] Add cpufreq driver Signed-off-by: popcornmix --- @@ -84317,10 +84317,10 @@ index 0000000000000000000000000000000000000000..414fbdc10dfbfc6e4bb47870a7af3fd5 +module_init(bcm2835_cpufreq_module_init); +module_exit(bcm2835_cpufreq_module_exit); -From 99f3536cecd3ec117d1b8f673471936f0935a839 Mon Sep 17 00:00:00 2001 +From 3c732076d6d4b2a1e79190906c1e2cf6611c842c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 19:24:24 +0000 -Subject: [PATCH 045/143] Added hwmon/thermal driver for reporting core +Subject: [PATCH 045/190] Added hwmon/thermal driver for reporting core temperature. Thanks Dorian MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -84486,10 +84486,10 @@ index 0000000000000000000000000000000000000000..c63fb9f9d143e19612a18fe530c7b2b3 +MODULE_DESCRIPTION("Thermal driver for bcm2835 chip"); +MODULE_LICENSE("GPL"); -From 0d51691b29ddf5a1c856738868f7067d0fef9a1b Mon Sep 17 00:00:00 2001 +From 8c94087475e5c223ba69548721685e9019142344 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 17 Jun 2015 15:44:08 +0100 -Subject: [PATCH 046/143] Add Chris Boot's i2c driver +Subject: [PATCH 046/190] Add Chris Boot's i2c driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -85154,10 +85154,10 @@ index 0000000000000000000000000000000000000000..962f2e5c7455d91bf32925d785f5f16b +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); -From cb15069165df2b45009331fcea832183557c94fa Mon Sep 17 00:00:00 2001 +From 3e797f34b5cba6cd16712c23916859f3e69b6d3c 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 047/143] char: broadcom: Add vcio module +Subject: [PATCH 047/190] char: broadcom: Add vcio module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -85383,10 +85383,10 @@ index 0000000000000000000000000000000000000000..c19bc2075c77879563ef5e59038b5a14 +MODULE_DESCRIPTION("Mailbox userspace access"); +MODULE_LICENSE("GPL"); -From 08b1da5536118ce3e95f38366b1868fa27dcc489 Mon Sep 17 00:00:00 2001 +From f9a5c0c6e8691542599391afcfd152eb3494a3ea 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 048/143] firmware: bcm2835: Support ARCH_BCM270x +Subject: [PATCH 048/190] firmware: bcm2835: Support ARCH_BCM270x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -85469,10 +85469,10 @@ index dd506cd3a5b874f9e1acd07efb8cd151bb6145d1..3f070bd38a91511c986e3fb114b15bd4 MODULE_AUTHOR("Eric Anholt "); MODULE_DESCRIPTION("Raspberry Pi firmware driver"); -From bd6e61c1d0de223b77a89b11767c93d14c186222 Mon Sep 17 00:00:00 2001 +From 0dc4c631d6161c6bb646af43b31fc20a9f370d58 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 30 Jan 2013 12:45:18 +0000 -Subject: [PATCH 049/143] bcm2835: add v4l2 camera device +Subject: [PATCH 049/190] bcm2835: add v4l2 camera device - Supports raw YUV capture, preview, JPEG and H264. - Uses videobuf2 for data transfer, using dma_buf. @@ -93214,10 +93214,10 @@ index 0000000000000000000000000000000000000000..9d1d11e4a53e510c04a416d92d195a7d + +#endif /* MMAL_VCHIQ_H */ -From ffa6bcf63061b49a18bf0932a012e92ce64f1e90 Mon Sep 17 00:00:00 2001 +From 8a2c5cf31a7f214a896905e51fab0d9e2d914bde Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 11 May 2015 09:00:42 +0100 -Subject: [PATCH 050/143] scripts: Add mkknlimg and knlinfo scripts from tools +Subject: [PATCH 050/190] scripts: Add mkknlimg and knlinfo scripts from tools repo The Raspberry Pi firmware looks for a trailer on the kernel image to @@ -93737,10 +93737,10 @@ index 0000000000000000000000000000000000000000..60206de7fa9a49bd027c635306674a29 + return $trailer; +} -From 537c9deee795f656a41baf00cda7168211581b90 Mon Sep 17 00:00:00 2001 +From 9dec15424834fa630e801a3c6b0372213341ea3c Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 10 Aug 2015 09:49:15 +0100 -Subject: [PATCH 051/143] scripts/dtc: Update to upstream version 1.4.1 +Subject: [PATCH 051/190] scripts/dtc: Update to upstream version 1.4.1 Includes the new localfixups format. @@ -96591,10 +96591,10 @@ index ad9b05ae698b0495ecbda42ffcf4743555313a27..2595dfda020fd9e03f0beff5006f229d -#define DTC_VERSION "DTC 1.4.1-g53bf130b" +#define DTC_VERSION "DTC 1.4.1-g25efc119" -From 1fee8b71fef8abbfcef2cf6913627f2f6f7846a5 Mon Sep 17 00:00:00 2001 +From a17b8884ada3131d4295f64a1c041b99c2f02ac2 Mon Sep 17 00:00:00 2001 From: notro Date: Wed, 9 Jul 2014 14:46:08 +0200 -Subject: [PATCH 052/143] BCM2708: Add core Device Tree support +Subject: [PATCH 052/190] BCM2708: Add core Device Tree support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -106722,10 +106722,10 @@ index 0a07f9014944ed92a8e2e42983ae43be60b3e471..1967878a843461c3ff1f473b9a030eb0 # Bzip2 -From d02d6f6fbcf7be876dd09ecc70ce35ce7238a264 Mon Sep 17 00:00:00 2001 +From 85d20a997340861899ed8718bb9bd54d404a3e6f Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 6 Feb 2015 13:50:57 +0000 -Subject: [PATCH 053/143] BCM270x_DT: Add pwr_led, and the required "input" +Subject: [PATCH 053/190] BCM270x_DT: Add pwr_led, and the required "input" trigger The "input" trigger makes the associated GPIO an input. This is to support @@ -106901,10 +106901,10 @@ index 569cb531094c20a9aa2db478aaa6f348d2afd7f4..aca292f4b0932f61b5bd864251fd05b9 /* set_brightness_work / blink_timer flags, atomic, private. */ unsigned long work_flags; -From 187dd8daac23828689505c4a1ecb48e2c3605019 Mon Sep 17 00:00:00 2001 +From 71199775653ad02f233af3a3e223bf089495d6be Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Mon, 17 Jun 2013 13:32:11 +0300 -Subject: [PATCH 054/143] fbdev: add FBIOCOPYAREA ioctl +Subject: [PATCH 054/190] fbdev: add FBIOCOPYAREA ioctl Based on the patch authored by Ali Gholami Rudi at https://lkml.org/lkml/2009/7/13/153 @@ -107156,10 +107156,10 @@ index fb795c3b3c178ad3cd7c9e9e4547ffd492bac181..703fa8a70574323abe2fb32599254582 __u32 dx; /* screen-relative */ __u32 dy; -From 721fc1e3126da2df74166f87bab6a56c3e0da334 Mon Sep 17 00:00:00 2001 +From ac4d5aef8772f63221f3dec7c37d9d763cc893ab Mon Sep 17 00:00:00 2001 From: Harm Hanemaaijer Date: Thu, 20 Jun 2013 20:21:39 +0200 -Subject: [PATCH 055/143] Speed up console framebuffer imageblit function +Subject: [PATCH 055/190] 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 @@ -107368,10 +107368,10 @@ index a2bb276a8b2463eee98eb237c4647bc00cd93601..436494fba15abecb400ef28688466faf start_index, pitch_index); } else -From 6f03a5d68b9c89ef0f13a166e66c45d515378036 Mon Sep 17 00:00:00 2001 +From 6f62e6e579984cd5393284f6cb060e1bdbd8ca85 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 8 May 2013 11:46:50 +0100 -Subject: [PATCH 056/143] enabling the realtime clock 1-wire chip DS1307 and +Subject: [PATCH 056/190] enabling the realtime clock 1-wire chip DS1307 and 1-wire on GPIO4 (as a module) 1-wire: Add support for configuring pin for w1-gpio kernel module @@ -107621,10 +107621,10 @@ index d58594a3232492e33f1dd4babd3798b03e0f0203..feae94256256316fd9d850c3d83325af unsigned int ext_pullup_enable_pin; unsigned int pullup_duration; -From 7cc945130866491056dd227a0e01141f1dbf7c4c Mon Sep 17 00:00:00 2001 +From 3039b31c4a1ad1d1d1641e4cf7fb9110acbdc184 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 18 Dec 2013 22:16:19 +0000 -Subject: [PATCH 057/143] config: Enable CONFIG_MEMCG, but leave it disabled +Subject: [PATCH 057/190] config: Enable CONFIG_MEMCG, but leave it disabled (due to memory cost). Enable with cgroup_enable=memory. --- @@ -107674,10 +107674,10 @@ index 53bbca7c48598e44fa5e45f88626027749ca8932..62d610c934f80265a889d968c4880a71 * css_tryget_online_from_dir - get corresponding css from a cgroup dentry * @dentry: directory dentry of interest -From bc2335717f7d28dbb33dac229b8fd7701810102a Mon Sep 17 00:00:00 2001 +From 8cc796687b2adea248a13db94060680b1b9d0db9 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 14 Jul 2014 22:02:09 +0100 -Subject: [PATCH 058/143] hid: Reduce default mouse polling interval to 60Hz +Subject: [PATCH 058/190] hid: Reduce default mouse polling interval to 60Hz Reduces overhead when using X --- @@ -107713,10 +107713,10 @@ index 333108ef18cf2f3f94ee3816b2ba6522017295b6..da0ee3beeeed3a223ea6859f52a81e99 ret = -ENOMEM; if (usb_endpoint_dir_in(endpoint)) { -From 83febbc99afc598508f10d47ebdd71e188f07644 Mon Sep 17 00:00:00 2001 +From abe2eb1f1b819701d72ad2165229e184fe43d892 Mon Sep 17 00:00:00 2001 From: Gordon Hollingworth Date: Tue, 12 May 2015 14:47:56 +0100 -Subject: [PATCH 059/143] rpi-ft5406: Add touchscreen driver for pi LCD display +Subject: [PATCH 059/190] 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 @@ -108074,10 +108074,10 @@ index 30fb37fe175df604a738258a2a632bca3bfff33f..4a3d79d3b48eb483a4e4bf498f617515 RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f, -From bf9d8140feb1c5bb942a776a48741d69398dabde Mon Sep 17 00:00:00 2001 +From ffacb25f32a6abbceca3e59dc85d0f201b803f4d Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 28 Nov 2016 16:50:04 +0000 -Subject: [PATCH 060/143] Improve __copy_to_user and __copy_from_user +Subject: [PATCH 060/190] Improve __copy_to_user and __copy_from_user performance Provide a __copy_from_user that uses memcpy. On BCM2708, use @@ -109652,10 +109652,10 @@ index 333dc3c2e5ffbb2c5ab8fcfb6115b6162643cf20..46b787a6474ffa857da9b663948863ec bool "Broadcom BCM63xx DSL SoC" depends on ARCH_MULTI_V7 -From 49813e9c1a6fdf7a82c7262fb9e1f3d62c3a9e64 Mon Sep 17 00:00:00 2001 +From 3ef28d85d3b498470ecd0d71838f957624a9e4d1 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 25 Jun 2015 12:16:11 +0100 -Subject: [PATCH 061/143] gpio-poweroff: Allow it to work on Raspberry Pi +Subject: [PATCH 061/190] 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 @@ -109690,10 +109690,10 @@ index be3d81ff51cc3f510d85e4eed7a52960e51e7bc1..a030ae9fb1fca325061c093696e82186 "%s: pm_power_off function already registered", __func__); -From 4cf353cbfb5abcbe319726ab73d65c5c9725b06e Mon Sep 17 00:00:00 2001 +From 3b36679d415e2aa2c1dc649ab15df5cd437d6240 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 14 Jul 2015 14:32:47 +0100 -Subject: [PATCH 062/143] mfd: Add Raspberry Pi Sense HAT core driver +Subject: [PATCH 062/190] mfd: Add Raspberry Pi Sense HAT core driver --- drivers/input/joystick/Kconfig | 8 + @@ -110558,10 +110558,10 @@ index 0000000000000000000000000000000000000000..56196dc2af10e464a1e3f98b028dca1c + +#endif -From 298f0da2a99e2cc999e8db96151ff92c6826bbe1 Mon Sep 17 00:00:00 2001 +From cf75db874a71e35cf0b9304022e5b541fa97608b Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 19:19:08 +0100 -Subject: [PATCH 063/143] ASoC: Add support for HifiBerry DAC +Subject: [PATCH 063/190] ASoC: Add support for HifiBerry DAC This adds a machine driver for the HifiBerry DAC. It is a sound card that can @@ -110736,10 +110736,10 @@ index 0000000000000000000000000000000000000000..45f2b770ad9e67728ca599a7445d6ae9 +MODULE_DESCRIPTION("ASoC Driver for HifiBerry DAC"); +MODULE_LICENSE("GPL v2"); -From 4e5ef7798e0f16bd34b79dcf43ca2488c7ed1c1a Mon Sep 17 00:00:00 2001 +From 6560100f7ef897089c35ec10275a4707b59c141a Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Mon, 25 Jan 2016 15:48:59 +0000 -Subject: [PATCH 064/143] ASoC: Add support for Rpi-DAC +Subject: [PATCH 064/190] ASoC: Add support for Rpi-DAC --- sound/soc/bcm/Kconfig | 7 +++ @@ -111023,10 +111023,10 @@ index 0000000000000000000000000000000000000000..afe1b419582aa40c4b2729d242bb13cd +MODULE_AUTHOR("Florian Meier "); +MODULE_LICENSE("GPL v2"); -From 2bf400ba45d9bfb1ac5b26723d69bd7100e6f2a6 Mon Sep 17 00:00:00 2001 +From f8a2672a462be5ebe159c4012e323202844e06d0 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Wed, 15 Jan 2014 21:41:23 +0100 -Subject: [PATCH 065/143] ASoC: wm8804: Implement MCLK configuration options, +Subject: [PATCH 065/190] ASoC: wm8804: Implement MCLK configuration options, add 32bit support WM8804 can run with PLL frequencies of 256xfs and 128xfs for most sample rates. At 192kHz only 128xfs is supported. The existing driver selects 128xfs automatically for some lower samples rates. By using an @@ -111075,10 +111075,10 @@ index af95d648265b3e92e345101542b332aee35191d4..513f56ba132929662802d15cdc653af3 .component_driver = { .dapm_widgets = wm8804_dapm_widgets, -From 34f11bff0a9142a2c6f3a3848dbffcc2135f571a Mon Sep 17 00:00:00 2001 +From 87c2d9ef0aa0a06463268b5d70d46b8d45d25c2d Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Wed, 15 Jan 2014 21:42:08 +0100 -Subject: [PATCH 066/143] ASoC: BCM:Add support for HiFiBerry Digi. Driver is +Subject: [PATCH 066/190] ASoC: BCM:Add support for HiFiBerry Digi. Driver is based on the patched WM8804 driver. Signed-off-by: Daniel Matuschek @@ -111422,10 +111422,10 @@ index 0000000000000000000000000000000000000000..19dc953b7227ba86123fc7a2ba654499 +MODULE_DESCRIPTION("ASoC Driver for HifiBerry Digi"); +MODULE_LICENSE("GPL v2"); -From 9ee4bd0e00a551e81a809a1126b1e3e8696cb7c9 Mon Sep 17 00:00:00 2001 +From 3e395eb641f939908f7f27033dc2d1960b801339 Mon Sep 17 00:00:00 2001 From: Gordon Garrity Date: Sat, 8 Mar 2014 16:56:57 +0000 -Subject: [PATCH 067/143] Add IQaudIO Sound Card support for Raspberry Pi +Subject: [PATCH 067/190] Add IQaudIO Sound Card support for Raspberry Pi Set a limit of 0dB on Digital Volume Control @@ -111755,10 +111755,10 @@ index 0000000000000000000000000000000000000000..4e8e6dec14bcf4a1ff286c43742d4097 +MODULE_DESCRIPTION("ASoC Driver for IQAudio DAC"); +MODULE_LICENSE("GPL v2"); -From bf5fea3022d1d56c3dd82fa726cbbc0364fae64c Mon Sep 17 00:00:00 2001 +From 45a9c2a8c3b00ef70faa52600b5784c6e619862c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 25 Jul 2016 17:06:50 +0100 -Subject: [PATCH 068/143] iqaudio-dac: Compile fix - untested +Subject: [PATCH 068/190] iqaudio-dac: Compile fix - untested --- sound/soc/bcm/iqaudio-dac.c | 6 +++++- @@ -111782,10 +111782,10 @@ index 4e8e6dec14bcf4a1ff286c43742d4097249d6777..aa15bc4b49ca95edec905fddd8fd0a6d if (dapm->dev != codec_dai->dev) return 0; -From 67ba839a62a9d52ef318c1fb5a8b7e79817b890b Mon Sep 17 00:00:00 2001 +From bd9299e181b6b5e720a383b0bfa599bceeb01148 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Mon, 4 Aug 2014 10:06:56 +0200 -Subject: [PATCH 069/143] Added support for HiFiBerry DAC+ +Subject: [PATCH 069/190] 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. @@ -112415,10 +112415,10 @@ index 72b19e62f6267698aea45d2410d616d91c1825cb..c6839ef6e16754ed9de2698507b8986a dev_err(dev, "No LRCLK?\n"); return -EINVAL; -From e5b4dd0f27f8927b566004e89c0d630ba189e654 Mon Sep 17 00:00:00 2001 +From abd7a245731db74973abc4a9b3d655cc742c1091 Mon Sep 17 00:00:00 2001 From: Daniel Matuschek Date: Mon, 4 Aug 2014 11:09:58 +0200 -Subject: [PATCH 070/143] Added driver for HiFiBerry Amp amplifier add-on board +Subject: [PATCH 070/190] 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. @@ -113253,10 +113253,10 @@ index 0000000000000000000000000000000000000000..8f019e04898754d2f87e9630137be9e8 + +#endif /* _TAS5713_H */ -From 85a279eaea5b66242702171e5d140e417d678ee9 Mon Sep 17 00:00:00 2001 +From bfd4d9ae8ac7addf045ea3c28546fb3080c1e781 Mon Sep 17 00:00:00 2001 From: Ryan Coe Date: Sat, 31 Jan 2015 18:25:49 -0700 -Subject: [PATCH 071/143] Update ds1307 driver for device-tree support +Subject: [PATCH 071/190] Update ds1307 driver for device-tree support Signed-off-by: Ryan Coe --- @@ -113283,10 +113283,10 @@ index 4ad97be480430babc3321075f2739114eaad8f04..2ac1c265dc9cea56a5949eb537949a1f .driver = { .name = "rtc-ds1307", -From 053bc362322ac4e8bf60530e93aee667167e7f8a Mon Sep 17 00:00:00 2001 +From 33d49d00d57ad0dae41e49f86338ca77cd8d530b Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 25 Mar 2015 09:26:17 +0100 -Subject: [PATCH 072/143] Add driver for rpi-proto +Subject: [PATCH 072/190] 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 @@ -113502,10 +113502,10 @@ index 0000000000000000000000000000000000000000..9db678e885efd63d84d60a098a84ed67 +MODULE_DESCRIPTION("ASoC Driver for Raspberry Pi connected to PROTO board (WM8731)"); +MODULE_LICENSE("GPL"); -From 88224370fc80b8de92c73c3b0ae02c04bb8e496c Mon Sep 17 00:00:00 2001 +From 56b0fc1adeb9156cb9371129e3cd45dede8316d8 Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Mon, 24 Aug 2015 16:03:47 +0100 -Subject: [PATCH 073/143] RaspiDAC3 support +Subject: [PATCH 073/190] RaspiDAC3 support Signed-off-by: Jan Grulich @@ -113748,10 +113748,10 @@ index 0000000000000000000000000000000000000000..dd9eeea2af0382307f437e6db09d1546 +MODULE_DESCRIPTION("ASoC Driver for RaspiDAC Rev.3x"); +MODULE_LICENSE("GPL v2"); -From 1385ec25eb578307ba8862c9ae77e0f06d14293c Mon Sep 17 00:00:00 2001 +From 7a62b97b250b0c4543c0e44e15a0217718984807 Mon Sep 17 00:00:00 2001 From: Aaron Shaw Date: Thu, 7 Apr 2016 21:26:21 +0100 -Subject: [PATCH 074/143] Add Support for JustBoom Audio boards +Subject: [PATCH 074/190] Add Support for JustBoom Audio boards justboom-dac: Adjust for ALSA API change @@ -114205,10 +114205,10 @@ index 0000000000000000000000000000000000000000..91acb666380faa3c0deb2230f8a0f8bb +MODULE_DESCRIPTION("ASoC Driver for JustBoom PI Digi HAT Sound Card"); +MODULE_LICENSE("GPL v2"); -From fd8c46fea411354bb97265a5fb57bec83820ad4c Mon Sep 17 00:00:00 2001 +From 63d7bf833f63563bedf80bb2c50a0df7ccdce0b9 Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Tue, 3 May 2016 22:10:59 -0400 -Subject: [PATCH 075/143] ARM: adau1977-adc: Add basic machine driver for +Subject: [PATCH 075/190] ARM: adau1977-adc: Add basic machine driver for adau1977 codec driver. This commit adds basic support for the codec usage including: Device tree overlay, @@ -114390,10 +114390,10 @@ index 0000000000000000000000000000000000000000..6e2ee027926ee63c89222f75ceb89e3d +MODULE_DESCRIPTION("ASoC Driver for ADAU1977 ADC"); +MODULE_LICENSE("GPL v2"); -From d42f4ed4d2c918abc3db37daee953eec5c50ad80 Mon Sep 17 00:00:00 2001 +From b687ba624d50086f37a7a184caa494d71823a790 Mon Sep 17 00:00:00 2001 From: Matt Flax Date: Mon, 16 May 2016 21:36:31 +1000 -Subject: [PATCH 076/143] New AudioInjector.net Pi soundcard with low jitter +Subject: [PATCH 076/190] 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. @@ -114644,10 +114644,10 @@ index 0000000000000000000000000000000000000000..ef54e0f07ea03f59e9957b5d98f3e7fd +MODULE_ALIAS("platform:audioinjector-pi-soundcard"); + -From 6689d861c13e3230c53f5f1b54b7987ef92aeba9 Mon Sep 17 00:00:00 2001 +From 059b80ad576b1e2d5d26b67aa9d9bd42ed51ab0a Mon Sep 17 00:00:00 2001 From: DigitalDreamtime Date: Thu, 30 Jun 2016 18:38:42 +0100 -Subject: [PATCH 077/143] Add IQAudIO Digi WM8804 board support +Subject: [PATCH 077/190] Add IQAudIO Digi WM8804 board support Support IQAudIO Digi board with iqaudio_digi machine driver and iqaudio-digi-wm8804-audio overlay. @@ -114947,10 +114947,10 @@ index 0000000000000000000000000000000000000000..9b6e829bcb5b1762a853775e78163196 +MODULE_DESCRIPTION("ASoC Driver for IQAudIO WM8804 Digi"); +MODULE_LICENSE("GPL v2"); -From 821ba52756aaabe8947659b9be1744cad032d376 Mon Sep 17 00:00:00 2001 +From 648f9937136cc90eddc8734238cfdc28518930d5 Mon Sep 17 00:00:00 2001 From: escalator2015 Date: Tue, 24 May 2016 16:20:09 +0100 -Subject: [PATCH 078/143] New driver for RRA DigiDAC1 soundcard using WM8741 + +Subject: [PATCH 078/190] New driver for RRA DigiDAC1 soundcard using WM8741 + WM8804 --- @@ -115423,10 +115423,10 @@ index 0000000000000000000000000000000000000000..446796e7e4c14a7d95b2f2a01211d9a0 +MODULE_DESCRIPTION("ASoC Driver for RRA DigiDAC1"); +MODULE_LICENSE("GPL v2"); -From 18217ab6c25f21d54af5891f725eacd148929a10 Mon Sep 17 00:00:00 2001 +From 58bef7451fa4731c00db49e0a1c8a8e9b33b4d20 Mon Sep 17 00:00:00 2001 From: DigitalDreamtime Date: Sat, 2 Jul 2016 16:26:19 +0100 -Subject: [PATCH 079/143] Add support for Dion Audio LOCO DAC-AMP HAT +Subject: [PATCH 079/190] Add support for Dion Audio LOCO DAC-AMP HAT Using dedicated machine driver and pcm5102a codec driver. @@ -115599,10 +115599,10 @@ index 0000000000000000000000000000000000000000..89e65317512bc774453ac8d0d5b0ff98 +MODULE_DESCRIPTION("ASoC Driver for DionAudio LOCO"); +MODULE_LICENSE("GPL v2"); -From b8e26d7c19304135ac8bb435da3c95df604b9403 Mon Sep 17 00:00:00 2001 +From ca493ce0ffa50d94defbc11ce2abb1cbaac52fb9 Mon Sep 17 00:00:00 2001 From: Clive Messer Date: Mon, 19 Sep 2016 14:01:04 +0100 -Subject: [PATCH 080/143] Allo Piano DAC boards: Initial 2 channel (stereo) +Subject: [PATCH 080/190] 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, @@ -115809,10 +115809,10 @@ index 0000000000000000000000000000000000000000..8e8e62e5a36a279b425ed4655cfbac99 +MODULE_DESCRIPTION("ALSA ASoC Machine Driver for Allo Piano DAC"); +MODULE_LICENSE("GPL v2"); -From 91e732e181547ba0f62c18fbe71687688d2c1878 Mon Sep 17 00:00:00 2001 +From ef3a71964f5c723b2c8ac29d3fabef6de28ee06d Mon Sep 17 00:00:00 2001 From: gtrainavicius Date: Sun, 23 Oct 2016 12:06:53 +0300 -Subject: [PATCH 081/143] Support for Blokas Labs pisound board +Subject: [PATCH 081/190] Support for Blokas Labs pisound board Pisound dynamic overlay (#1760) @@ -116989,10 +116989,10 @@ index 0000000000000000000000000000000000000000..4b8545487d06e4ea70073a5d063fb231 +MODULE_DESCRIPTION("ASoC Driver for pisound, http://blokas.io/pisound"); +MODULE_LICENSE("GPL v2"); -From a78893616a488abf9b4c9dbf0cace4e130ea0907 Mon Sep 17 00:00:00 2001 +From 8dfe629805951bb4b2a1010f1e4f4559de13ba18 Mon Sep 17 00:00:00 2001 From: P33M Date: Wed, 21 Oct 2015 14:55:21 +0100 -Subject: [PATCH 082/143] rpi_display: add backlight driver and overlay +Subject: [PATCH 082/190] 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 @@ -117161,10 +117161,10 @@ index 0000000000000000000000000000000000000000..14a0d9b037395497c1fdae2961feccd5 +MODULE_DESCRIPTION("Raspberry Pi mailbox based Backlight Driver"); +MODULE_LICENSE("GPL"); -From e3bcfd7cedcea1f6ce90667a860eba5d19e50ec6 Mon Sep 17 00:00:00 2001 +From 9a06b725757f2c41c77fe0aa3e83c70d9e20f97a Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 23 Feb 2016 19:56:04 +0000 -Subject: [PATCH 083/143] bcm2835-virtgpio: Virtual GPIO driver +Subject: [PATCH 083/190] bcm2835-virtgpio: Virtual GPIO driver Add a virtual GPIO driver that uses the firmware mailbox interface to request that the VPU toggles LEDs. @@ -117438,10 +117438,10 @@ index 4a3d79d3b48eb483a4e4bf498f617515e3ad158f..5f34e1257117fb48013c9926a8a223d6 RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f, -From afb0883dd8b8f571e565b59a5813f939a6cce163 Mon Sep 17 00:00:00 2001 +From 33865a17996f3dd14fedc7d6462df059a4869db9 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 23 Feb 2016 17:26:48 +0000 -Subject: [PATCH 084/143] amba_pl011: Don't use DT aliases for numbering +Subject: [PATCH 084/190] 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 @@ -117470,10 +117470,10 @@ index d4171d71a258f2696ab2ab2109376ee5a516bfba..6beb6233a0b6132b933cf8d85d8501dc uap->old_cr = 0; uap->port.dev = dev; -From fdfb4986a0abca080478d8449f4f257c835a9211 Mon Sep 17 00:00:00 2001 +From 11f45d0f6b3743e8850759373d376580040718da Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Wed, 3 Dec 2014 13:23:28 +0200 -Subject: [PATCH 085/143] OF: DT-Overlay configfs interface +Subject: [PATCH 085/190] 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. @@ -117905,10 +117905,10 @@ index 0000000000000000000000000000000000000000..0037e6868a6cda8706c88194c6a4454b +} +late_initcall(of_cfs_init); -From 3d29854cf0ba3548719f9977cdae2910bf4484db Mon Sep 17 00:00:00 2001 +From 6f9eaca7d4030cff1a597895637c8f11bbf233ba Mon Sep 17 00:00:00 2001 From: Cheong2K Date: Fri, 26 Feb 2016 18:20:10 +0800 -Subject: [PATCH 086/143] brcm: adds support for BCM43341 wifi +Subject: [PATCH 086/190] brcm: adds support for BCM43341 wifi brcmfmac: Disable power management @@ -118059,10 +118059,10 @@ index dfb0658713d9b31714566b5003564a9a53eb5e97..db5f8b70b407879f1c006ca4b7ab78d1 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362), BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339), -From a4b76e3a62a42b8e2b92de017f4a0fe6cdbe7abf Mon Sep 17 00:00:00 2001 +From d19563d4aae70d53028052dc3dad36f7dd2f24ae Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 17 Dec 2015 13:37:07 +0000 -Subject: [PATCH 087/143] hci_h5: Don't send conf_req when ACTIVE +Subject: [PATCH 087/190] 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. @@ -118085,10 +118085,10 @@ index 90d0456b67446bcc624fab4b1542c4eaf21531b1..f9adeac3bbba6418dcca298c55706356 if (H5_HDR_LEN(hdr) > 2) h5->tx_win = (data[2] & 0x07); -From c3980d1190ae7a74abc71a39d774fbe92691b4ca Mon Sep 17 00:00:00 2001 +From 6f72b7d45b99f5454e8adcce48ddd8ca97265ff5 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 13 Apr 2015 17:16:29 +0100 -Subject: [PATCH 088/143] config: Add default configs +Subject: [PATCH 088/190] config: Add default configs --- arch/arm/configs/bcm2709_defconfig | 1297 +++++++++++++++++++++++++++++++++++ @@ -120715,10 +120715,10 @@ index 0000000000000000000000000000000000000000..8acee9f31202ec14f2933d92dd70831c +CONFIG_CRC_ITU_T=y +CONFIG_LIBCRC32C=y -From c59ca307b42b2c8bab4bf1d3537ca164c96cb85b Mon Sep 17 00:00:00 2001 +From 34cfa6ecba9d7086f617b3fea63d26a6d3d47239 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Wed, 24 Aug 2016 03:35:56 -0700 -Subject: [PATCH 089/143] Add arm64 configuration and device tree differences. +Subject: [PATCH 089/190] Add arm64 configuration and device tree differences. Disable MMC_BCM2835_SDHOST and MMC_BCM2835 since these drivers are crashing at the moment. @@ -122133,10 +122133,10 @@ index 0000000000000000000000000000000000000000..e6b09fafa27eed2b762e3d53b55041f7 +CONFIG_LIBCRC32C=y +CONFIG_BCM2835_VCHIQ=n -From 8d3dcfb51bd8bee21c9e6e0296c8502ca09d1f70 Mon Sep 17 00:00:00 2001 +From 7da6f7eb8806f7dc6347390bcc1c4330b46dd9c7 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 27 Dec 2016 22:13:42 +0000 -Subject: [PATCH 090/143] Revert "staging: vc04_services: remove +Subject: [PATCH 090/190] Revert "staging: vc04_services: remove vchiq_copy_from_user" This reverts commit 49bec49fd7f273ec114e2e533c1bb8f21a654aaf. @@ -122886,10 +122886,10 @@ index d9771394a041bbb55daacd7744ac57758ae198d1..7694627b925c743552b093ce51d15c2f * * Arguments: VCHI_HELD_MSG_T *message -From 37b3ac436056e51053ef5d0348ef93dc71e3be98 Mon Sep 17 00:00:00 2001 +From 76a14440a1f32a5f7c401979802fd60bd5244e0a Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 23 Mar 2016 14:16:25 +0000 -Subject: [PATCH 091/143] vchiq_arm: Access the dequeue_pending flag locked +Subject: [PATCH 091/190] vchiq_arm: Access the dequeue_pending flag locked Reading through this code looking for another problem (now found in userland) the use of dequeue_pending outside a lock didn't seem safe. @@ -122947,10 +122947,10 @@ index 42998155eb4d7de8e49cc1ca82d84a430562a8da..74f1569097c7dd120cc68fb8d09d8c3d return add_completion(instance, reason, header, user_service, -From 23dc62ffb692ae7e3a5be4bba257e51a87ac56c4 Mon Sep 17 00:00:00 2001 +From a3d7bb034d97dbef8bfa92fdf82e090055eefd6a Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 23 Mar 2016 20:53:47 +0000 -Subject: [PATCH 092/143] vchiq_arm: Service callbacks must not fail +Subject: [PATCH 092/190] vchiq_arm: Service callbacks must not fail Service callbacks are not allowed to return an error. The internal callback that delivers events and messages to user tasks does not enqueue them if @@ -122976,10 +122976,10 @@ index 74f1569097c7dd120cc68fb8d09d8c3d63d56977..3ba6485f0c7b32de9f2aa75164e8b1b9 DEBUG_TRACE(SERVICE_CALLBACK_LINE); } -From ce301053ff5dc3f25a290a8378927b355793c888 Mon Sep 17 00:00:00 2001 +From 360f97c51240920b702ca740492d5a5c0de56ec0 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 21 Apr 2016 13:49:32 +0100 -Subject: [PATCH 093/143] vchiq_arm: Add completion records under the mutex +Subject: [PATCH 093/190] vchiq_arm: Add completion records under the mutex An issue was observed when flushing openmax components which generate a large number of messages returning @@ -123042,10 +123042,10 @@ index 3ba6485f0c7b32de9f2aa75164e8b1b901aa74ea..07d8eadd2aa2dc997db13c80dc303673 return VCHIQ_SUCCESS; -From c1fe6df4ea43f0b9545a6050b72b7d1fe5e84a99 Mon Sep 17 00:00:00 2001 +From bf4e56c17ba6175342240e5c0d7c8815c3be9cb9 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 20 Jun 2016 13:51:44 +0100 -Subject: [PATCH 094/143] vchiq_arm: Avoid use of mutex in add_completion +Subject: [PATCH 094/190] vchiq_arm: Avoid use of mutex in add_completion Claiming the completion_mutex within add_completion did prevent some messages appearing twice, but provokes a deadlock caused by vcsm using @@ -123239,10 +123239,10 @@ index c5b06cc4ca53135ec9491116ca79beaa98f57bcc..d6757ee263fb61a689c0d38c0dbb65c5 up(&state->slot_available_event); } -From 8c1a98f073a1510731dd6fec6e94ddeee3ed44fa Mon Sep 17 00:00:00 2001 +From 06ade643f2c66bb6284c3094b0095ed244d4ea65 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 14 Sep 2016 09:18:09 +0100 -Subject: [PATCH 095/143] raspberrypi-firmware: Define the MBOX channel in the +Subject: [PATCH 095/190] raspberrypi-firmware: Define the MBOX channel in the header. Signed-off-by: Eric Anholt @@ -123264,10 +123264,10 @@ index 5f34e1257117fb48013c9926a8a223d64a598ab7..7f0da0727422c690947e46e891a754de enum rpi_firmware_property_status { -From 7d3bc19bbd84fefcdd27577dd37fc46fd8e94495 Mon Sep 17 00:00:00 2001 +From f7a72fc372e54d3766c1e7e36e7b93835485f5db Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 14 Sep 2016 08:39:33 +0100 -Subject: [PATCH 096/143] drm/vc4: Add a mode for using the closed firmware for +Subject: [PATCH 096/190] drm/vc4: Add a mode for using the closed firmware for display. Signed-off-by: Eric Anholt @@ -124034,10 +124034,10 @@ index 0000000000000000000000000000000000000000..d18a1dae51a2275846c9826b5bf1ba57 + }, +}; -From b9d76cb88a9c87fe808ddb234e379d10a6c28e6f Mon Sep 17 00:00:00 2001 +From c78d53b11d542b1110111e2d152bbe8529193b66 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 097/143] i2c: bcm2835: Add debug support +Subject: [PATCH 097/190] i2c: bcm2835: Add debug support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -124226,10 +124226,10 @@ index c3436f627028477f7e21b47e079fd5ab06ec188a..8642f580ce41803bd22c76a0fa80d083 if (i2c_dev->msg_err & BCM2835_I2C_S_ERR) return -EREMOTEIO; -From 0943957d423c895c065a0722eae050927a92e597 Mon Sep 17 00:00:00 2001 +From c00d44997c9a24660ce060e56905967b34dd1448 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 14 Sep 2016 09:16:19 +0100 -Subject: [PATCH 098/143] raspberrypi-firmware: Export the general transaction +Subject: [PATCH 098/190] raspberrypi-firmware: Export the general transaction function. The vc4-firmware-kms module is going to be doing the MBOX FB call. @@ -124273,10 +124273,10 @@ index 7f0da0727422c690947e46e891a754de13dc1fea..280791fb9656901392ce67e44cb742c9 #endif /* __SOC_RASPBERRY_FIRMWARE_H__ */ -From d892ed3ef0153b2b3041f6f76a88410575270bd2 Mon Sep 17 00:00:00 2001 +From 24d7c6765eb6d6dee0f0b3231195d40d2e864f99 Mon Sep 17 00:00:00 2001 From: Alex Tucker Date: Tue, 13 Dec 2016 19:50:18 +0000 -Subject: [PATCH 099/143] Add support for Silicon Labs Si7013/20/21 +Subject: [PATCH 099/190] Add support for Silicon Labs Si7013/20/21 humidity/temperature sensor. --- @@ -124351,10 +124351,10 @@ index f6d134c095af2398fc55ae7d2b0e86456c30627c..31bda8da4cb6a56bfe493a81b9189009 }; }; -From a7f4466713fc62e679070212dd09533d66db889c Mon Sep 17 00:00:00 2001 +From 7d62423e76b97d6affb920a1bf9f813ee1bd403d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 3 Jan 2017 21:27:46 +0000 -Subject: [PATCH 100/143] Document the si7020 option +Subject: [PATCH 100/190] Document the si7020 option --- arch/arm/boot/dts/overlays/README | 3 +++ @@ -124375,10 +124375,10 @@ index 81d991803be335e5a1bc3bb0a8c7a2c9f5c392bd..e8fa4ccb44c34a20485c4e6155467af9 Name: i2c0-bcm2708 Info: Enable the i2c_bcm2708 driver for the i2c0 bus. Not all pin combinations -From 62211690633ae9f41cea842893da69f8ba168636 Mon Sep 17 00:00:00 2001 +From 5ff140d63e29b05b914274b61bad0fea2656b327 Mon Sep 17 00:00:00 2001 From: Giedrius Trainavicius Date: Thu, 5 Jan 2017 02:38:16 +0200 -Subject: [PATCH 101/143] pisound improvements: +Subject: [PATCH 101/190] pisound improvements: * Added a writable sysfs object to enable scripts / user space software to blink MIDI activity LEDs for variable duration. @@ -124672,10 +124672,10 @@ index 4b8545487d06e4ea70073a5d063fb2310b3b94d0..ba70734b89e61a11201657406223f0b3 }; -From d72d3147ef62a6da9b073b2d103a529aa7481c67 Mon Sep 17 00:00:00 2001 +From de3d5c6b875102ca2f0ce9c08a25eac10b473277 Mon Sep 17 00:00:00 2001 From: Aaron Shaw Date: Tue, 10 Jan 2017 16:05:41 +0000 -Subject: [PATCH 102/143] Add driver_name property +Subject: [PATCH 102/190] Add driver_name property Add driver name property for use with 5.1 passthrough audio in LibreElec and other Kodi based OSs --- @@ -124695,10 +124695,10 @@ index 8fd50dbe681508a2cfe8fdde1c9fedbe9a507fa7..05a224ec712d06b8b7587ab6b8bb562d .dai_link = snd_rpi_justboom_dac_dai, .num_links = ARRAY_SIZE(snd_rpi_justboom_dac_dai), -From 38aedb6db6a04fc234a823f2da4274b0712f8c8d Mon Sep 17 00:00:00 2001 +From 28362694432c973e25cbf973624521ab20f9f0e2 Mon Sep 17 00:00:00 2001 From: Aaron Shaw Date: Tue, 10 Jan 2017 16:11:04 +0000 -Subject: [PATCH 103/143] Add driver_name paramater +Subject: [PATCH 103/190] Add driver_name paramater Add driver_name parameter for use with 5.1 passthrough audio in LibreElec and other Kodi OSs --- @@ -124718,10 +124718,10 @@ index 91acb666380faa3c0deb2230f8a0f8bbec59417b..abfdc5c4dd5811e6847bddda4921abe3 .dai_link = snd_rpi_justboom_digi_dai, .num_links = ARRAY_SIZE(snd_rpi_justboom_digi_dai), -From 777083226e9e5b3d06c24bac85ced08f6f822cfd Mon Sep 17 00:00:00 2001 +From 57bff8c4aba4b0934aae00c688bebd3f615536b7 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 11 Jan 2017 13:01:21 +0000 -Subject: [PATCH 104/143] BCM270X_DT: Add pi3-disable-wifi overlay +Subject: [PATCH 104/190] BCM270X_DT: Add pi3-disable-wifi overlay pi3-disable-wifi is a minimal overlay to disable the onboard WiFi. @@ -124782,10 +124782,10 @@ index 0000000000000000000000000000000000000000..017199554bf2f4e381efcc7bb71e750c + }; +}; -From 8c98940e11190aa70ee56241e0b666e7adae7675 Mon Sep 17 00:00:00 2001 +From f11de16b9956c2b030a58f829caee0fa0608f571 Mon Sep 17 00:00:00 2001 From: Electron752 Date: Thu, 12 Jan 2017 07:07:08 -0800 -Subject: [PATCH 105/143] ARM64: Make it work again on 4.9 (#1790) +Subject: [PATCH 105/190] ARM64: Make it work again on 4.9 (#1790) * Invoke the dtc compiler with the same options used in arm mode. * ARM64 now uses the bcm2835 platform just like ARM32. @@ -125189,10 +125189,10 @@ index e6b09fafa27eed2b762e3d53b55041f793683d27..c7e891d72969a388d9b135a36dbfc9c9 CONFIG_LIBCRC32C=y -CONFIG_BCM2835_VCHIQ=n -From 8f1f3cb604b6a02ae7aec733ac4930f9409a9470 Mon Sep 17 00:00:00 2001 +From 957d8a45127a446a482ed7b0781f2114afcdef46 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Thu, 12 Jan 2017 18:56:54 -0800 -Subject: [PATCH 106/143] ARM64: Fix bad cast in vc04_services +Subject: [PATCH 106/190] ARM64: Fix bad cast in vc04_services The function vchiq_copy_from_user contains a non-portable cast to uint32_t. Convert this to a cast to unsigned long @@ -125217,10 +125217,10 @@ index 706e7f936c1a97352f7ef3d3fbd3b4a92943165d..c2108dec3096fffd68261f0eb29a37d3 } else { memcpy(dst, src, size); -From 9676247b36fc83b7ed908c052b00a3fcc323e9b9 Mon Sep 17 00:00:00 2001 +From c9424561d8ddcf5dbf8723186de2f29cc091231e Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Thu, 12 Jan 2017 19:05:46 -0800 -Subject: [PATCH 107/143] ARM64/SND_BCM2835: Port it to arm64. +Subject: [PATCH 107/190] ARM64/SND_BCM2835: Port it to arm64. In the messages sent to VCHIQ, SND_BCM2835 passes a callback and a context into two 32 bit pointers. Since this @@ -125317,10 +125317,10 @@ index af3e6eb690113fc32ce9e06bd2f0f294da7a7f00..ede6154bc09d38469a82008174d0e357 // Message header for all messages in HOST->VC direction -From 0e2f25b763a178a40c3d41db607f8274356cf9ee Mon Sep 17 00:00:00 2001 +From 8b2e4020bb202586de7c6e083a0fe13f4eaebfc2 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Thu, 12 Jan 2017 19:10:07 -0800 -Subject: [PATCH 108/143] ARM64: Enable HDMI audio and vc04_services in +Subject: [PATCH 108/190] ARM64: Enable HDMI audio and vc04_services in bcmrpi3_defconfig Signed-off-by: Michael Zoran @@ -125349,10 +125349,10 @@ index c7e891d72969a388d9b135a36dbfc9c9cb609bf8..4b90f9b64abe9f089ba56b13d5a00de3 CONFIG_BCM2835_MBOX=y # CONFIG_IOMMU_SUPPORT is not set -From 03d5ad561d3ffd312f88445ec5f6ec0ab9527fde Mon Sep 17 00:00:00 2001 +From db1ceaae2a32a0f12127af14fc0445f5656be08f Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Thu, 12 Jan 2017 19:14:03 -0800 -Subject: [PATCH 109/143] ARM64: Run bcmrpi3_defconfig through savedefconfig. +Subject: [PATCH 109/190] ARM64: Run bcmrpi3_defconfig through savedefconfig. Signed-off-by: Michael Zoran --- @@ -125397,10 +125397,10 @@ index 4b90f9b64abe9f089ba56b13d5a00de33343bfb9..dac962ca1634662ce7d966f1ffb53b5b CONFIG_FB_TFT_AGM1264K_FL=m CONFIG_FB_TFT_BD663474=m -From bae403b696c8f60057e8a025886ae67b287fc4c0 Mon Sep 17 00:00:00 2001 +From 05043a7cea9dc31db9197acf85c025dae2e89c26 Mon Sep 17 00:00:00 2001 From: Electron752 Date: Sat, 14 Jan 2017 02:54:26 -0800 -Subject: [PATCH 110/143] ARM64: Enable Kernel Address Space Randomization +Subject: [PATCH 110/190] ARM64: Enable Kernel Address Space Randomization (#1792) Randomization allows the mapping between virtual addresses and physical @@ -125432,10 +125432,10 @@ index dac962ca1634662ce7d966f1ffb53b5bfa27c506..aae33b4b3c3e736ea7cd3ca242158ad6 CONFIG_BINFMT_MISC=y CONFIG_COMPAT=y -From 3942188f6df384656ecc00a8721bdbc1cdea8438 Mon Sep 17 00:00:00 2001 +From 4c95e3cd42bfc39e2933d370f6599d35ae376355 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Sun, 15 Jan 2017 07:31:59 -0800 -Subject: [PATCH 111/143] ARM64: Enable RTL8187/RTL8192CU wifi in build config +Subject: [PATCH 111/190] ARM64: Enable RTL8187/RTL8192CU wifi in build config These drivers build now, so they can be enabled back in the build configuration just like they are for @@ -125460,10 +125460,10 @@ index aae33b4b3c3e736ea7cd3ca242158ad6ba558aff..b7d762df19b85e369a32cd823dfd0621 CONFIG_ZD1211RW=m CONFIG_MAC80211_HWSIM=m -From 9d0130fcb9311c2db10e4b49b4faab7e28f19d4b Mon Sep 17 00:00:00 2001 +From e6e0f03c0ce5046207285293cfb20cc46a861b52 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 16 Jan 2017 14:53:12 +0000 -Subject: [PATCH 112/143] BCM270X_DT: Add spi0-cs overlay +Subject: [PATCH 112/190] BCM270X_DT: Add spi0-cs overlay The spi0-cs overlay allows the software chip selectts to be modified using the cs0_pin and cs1_pin parameters. @@ -125551,10 +125551,10 @@ index 0000000000000000000000000000000000000000..7f79029d043c04d7496c7c3480450c69 + }; +}; -From 06935466e531c3423bb46c5043b14d0577ce113d Mon Sep 17 00:00:00 2001 +From 124efe6b711e1af91a1c3ba6d0a7efbbc8b2af45 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 1 Jul 2016 22:09:24 +0100 -Subject: [PATCH 113/143] spi-bcm2835: Disable forced software CS +Subject: [PATCH 113/190] 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 @@ -125580,10 +125580,10 @@ index 9a44da19089717f02462c657840ae9f24fd942ba..b710a4d67b8ec8c8c18ce8efb6f270e7 i2c0: i2c@7e205000 { -From 344059857429edb2332ea788e2c256668f24a609 Mon Sep 17 00:00:00 2001 +From 2f8e7d14b126767b1ee396ea3693624ffbdde4cf Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 17 Jan 2017 11:34:58 +0000 -Subject: [PATCH 114/143] BCM270X_DT: Enable UART0 on CM3 +Subject: [PATCH 114/190] BCM270X_DT: Enable UART0 on CM3 Signed-off-by: Phil Elwell --- @@ -125606,10 +125606,10 @@ index 41874c25a84226c0e4af92ec4059e0a571fe6123..3ba6e621856c288ae4694f758604619f sdhost_pins: sdhost_pins { brcm,pins = <48 49 50 51 52 53>; -From af4413600326fef6041165c26a66c1cee892233a Mon Sep 17 00:00:00 2001 +From 864b91126a504a382c987d45f851088c2b5ba410 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 17 Jan 2017 14:39:39 +0000 -Subject: [PATCH 115/143] config: Add CONFIG_MD_M25P80 and CONFIG_MD_SPI_NOR +Subject: [PATCH 115/190] config: Add CONFIG_MD_M25P80 and CONFIG_MD_SPI_NOR See: https://github.com/raspberrypi/linux/issues/1781 @@ -125714,10 +125714,10 @@ index 8acee9f31202ec14f2933d92dd70831cda8d7b51..aca8903da3156de11ba62afa64a06939 CONFIG_FB_TFT_AGM1264K_FL=m CONFIG_FB_TFT_BD663474=m -From 2db22e08eb782d9b31df67d4a2d2b6d3e2229222 Mon Sep 17 00:00:00 2001 +From 270efc01e40bb32d4fd60a0ee608a47c6fd76f32 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Sat, 14 Jan 2017 21:33:51 -0800 -Subject: [PATCH 116/143] ARM64/DWC_OTG: Port dwc_otg driver to ARM64 +Subject: [PATCH 116/190] 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 @@ -126060,10 +126060,10 @@ index 6b2c7d0c93f36a63863ff4b0ecc1f3eab77e058b..d7b700ff17821ad1944e36721fe6b2db /** The OS page size */ #define DWC_OS_PAGE_SIZE PAGE_SIZE -From 3fd685e26219daae1087d48f160f6121f6fffb87 Mon Sep 17 00:00:00 2001 +From 6f5f34f8126ea8f62d7774fb989564ef921208ba Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Sat, 14 Jan 2017 21:43:57 -0800 -Subject: [PATCH 117/143] ARM64: Round-Robin dispatch IRQs between CPUs. +Subject: [PATCH 117/190] 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 @@ -126137,10 +126137,10 @@ index a8db33b50ad9ff83d284fa54fe4d3b65f859df0f..67dcac46cca72db4ebe2300eab04f0a8 .name = "bcm2836-gpu", .irq_mask = bcm2836_arm_irqchip_mask_gpu_irq, -From 5798b8a6ee69242586c8d244d79acb4a49b32ffe Mon Sep 17 00:00:00 2001 +From 18bf49741a1afc8d00caae1b9e8346762a0310f8 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Sat, 14 Jan 2017 21:45:03 -0800 -Subject: [PATCH 118/143] ARM64: Enable DWC_OTG Driver In ARM64 Build +Subject: [PATCH 118/190] ARM64: Enable DWC_OTG Driver In ARM64 Build Config(bcmrpi3_defconfig) Signed-off-by: Michael Zoran @@ -126161,10 +126161,10 @@ index b7d762df19b85e369a32cd823dfd062145bdefa7..4d85c231c5ea0244e1b05fb4a5e3c8fd CONFIG_USB_STORAGE=y CONFIG_USB_STORAGE_REALTEK=m -From 72a5e963ed3e8137b91a721c8e5c151746a86b7d Mon Sep 17 00:00:00 2001 +From 1345c48679f5b0ba1df0386ad9a4fbd3540970d6 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Sat, 14 Jan 2017 21:46:04 -0800 -Subject: [PATCH 119/143] ARM64: Use dwc_otg driver by default for USB. +Subject: [PATCH 119/190] ARM64: Use dwc_otg driver by default for USB. If it breaks on anybody, they can use the standard device tree overlays to switch back to the dwc2 driver. @@ -126190,10 +126190,10 @@ index f6def5d7e5d622cf09e8f87332c7374fe28da08b..3e134a1208610b90e2d0fc22f03c6e9f -}; -#endif -From de0e945d578f47f93f927ef11f16b92eb0fe1de8 Mon Sep 17 00:00:00 2001 +From 1b346a8ae9a4a5df88620036346c8e9264e8e592 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 19 Jan 2017 11:18:55 +0000 -Subject: [PATCH 120/143] config: Add CONFIG_USB_DWC2 and CONFIG_USB_GADGET +Subject: [PATCH 120/190] config: Add CONFIG_USB_DWC2 and CONFIG_USB_GADGET The introduction of CM3 makes gadget mode on 2709 a useful option, so enable the building of the required modules. Note that these @@ -126226,10 +126226,10 @@ index c36f01d28097a513b32df092ce64a7d6b974e615..2e2b88fefdf367b2d9190ca227ea6eb3 CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_BCM2835=y -From bf4fff3dc99c07e8aed32dcbe9e77bf88199a5ba Mon Sep 17 00:00:00 2001 +From 21793303ed79ad833da586ba76950c1f3f9c01fe Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 23 Jan 2017 17:36:50 +0000 -Subject: [PATCH 121/143] BCM270X_DT: Add reference to audio_pins to CM dtb +Subject: [PATCH 121/190] BCM270X_DT: Add reference to audio_pins to CM dtb The CM1 dtb contains an empty audio_pins node, but no reference to it. Adding the usual pinctrl reference from the audio node enables the @@ -126257,10 +126257,10 @@ index eb8662f0d222b4c0a9a2bcb8bccb13e86a0006b3..10be69972bd1440f574e35d515f3d6a0 hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; }; -From acd57d74b3c2b58a8e30fda9a7690ab3617e12d3 Mon Sep 17 00:00:00 2001 +From aca25515739ed0b82705ee040163f9eac4026637 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 25 Jan 2017 11:30:38 +0000 -Subject: [PATCH 122/143] config: Add additional network scheduling modules +Subject: [PATCH 122/190] config: Add additional network scheduling modules --- arch/arm/configs/bcm2709_defconfig | 4 ++++ @@ -126312,10 +126312,10 @@ index aca8903da3156de11ba62afa64a0693900ee3611..c8c66751f263227e86cc21ad5b23861a CONFIG_NET_SCH_PLUG=m CONFIG_NET_CLS_BASIC=m -From 7eb8cc55a5c43be9072c29138436df54131cc9da Mon Sep 17 00:00:00 2001 +From 81f6d699d879170c02da4d3e1a26dd248ca76b9f Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 16 Jan 2017 16:33:54 +0000 -Subject: [PATCH 123/143] config: Add CONFIG_TCP_CONG_BBR See: +Subject: [PATCH 123/190] config: Add CONFIG_TCP_CONG_BBR See: https://github.com/raspberrypi/linux/issues/1784 --- @@ -126350,10 +126350,10 @@ index c8c66751f263227e86cc21ad5b23861a88a636a6..e483bdb7aa869b212ef69ed779c6055e CONFIG_IPV6_ROUTER_PREF=y CONFIG_INET6_AH=m -From 736809cbe89cb56b087efaaccc55eb4a5627db33 Mon Sep 17 00:00:00 2001 +From c2ce26b01adb38ab8143e2bfde14876d1dfb86da Mon Sep 17 00:00:00 2001 From: chris johnson Date: Sun, 22 Jan 2017 03:27:31 +0000 -Subject: [PATCH 124/143] ASoC: A simple-card overlay for ADAU7002 +Subject: [PATCH 124/190] ASoC: A simple-card overlay for ADAU7002 Usage: `dtoverlay=adau7002-simple` --- @@ -126451,10 +126451,10 @@ index 0000000000000000000000000000000000000000..e67e6625d7967abc92cf00cb604d4c12 + }; +}; -From 8178b62fa432470071fb0fca59a200376094c8b8 Mon Sep 17 00:00:00 2001 +From c2ddfaca8ffe702293c91d1d55467bb5155a0d72 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 25 Jan 2017 21:17:23 +0000 -Subject: [PATCH 125/143] config: Add SND_SOC_ADAU7002 codec module +Subject: [PATCH 125/190] config: Add SND_SOC_ADAU7002 codec module As there is now an overlay requiring it, build the codec module. @@ -126489,10 +126489,10 @@ index e483bdb7aa869b212ef69ed779c6055ef3b70e2a..1927b1671b6eced73e4b4d76352bb4b1 CONFIG_SND_SOC_WM8804_I2C=m CONFIG_SND_SIMPLE_CARD=m -From a6d7fbc3f756abc3c51088ac8509f85c49b16fff Mon Sep 17 00:00:00 2001 +From 733cf7745fe6f63e317b906b613bea3067283b28 Mon Sep 17 00:00:00 2001 From: Scott Ellis Date: Fri, 27 Jan 2017 06:42:42 -0500 -Subject: [PATCH 126/143] Add overlay for mcp3008 adc (#1818) +Subject: [PATCH 126/190] Add overlay for mcp3008 adc (#1818) Some example usage: @@ -126778,10 +126778,10 @@ index 0000000000000000000000000000000000000000..06bf4264959c380d8a9f90f74e780397 + }; +}; -From fd202b0efb38df7c056c3a0e97cfdebb6470c04d Mon Sep 17 00:00:00 2001 +From d5c35222663fd03efc750778f4f267f98a6a3b98 Mon Sep 17 00:00:00 2001 From: JamesH65 Date: Mon, 6 Feb 2017 15:24:47 +0000 -Subject: [PATCH 127/143] gpio_mem: Remove unnecessary dev_info output (#1830) +Subject: [PATCH 127/190] gpio_mem: Remove unnecessary dev_info output (#1830) The open function was spamming syslog every time called, so have removed call completely. @@ -126803,10 +126803,10 @@ index 911f5b7393ed48ceed8751f06967ae6463453f9c..f5e7f1ba8fb6f18dee77fad06a17480c dev_err(inst->dev, "Unknown minor device: %d", dev); ret = -ENXIO; -From 46c74000bbbec747bca0c5ab07a538e64392494c Mon Sep 17 00:00:00 2001 +From ec2fb02ca6392fc5b318d921b885a4c733955419 Mon Sep 17 00:00:00 2001 From: Claggy3 Date: Sat, 11 Feb 2017 14:00:30 +0000 -Subject: [PATCH 128/143] Update vfpmodule.c +Subject: [PATCH 128/190] 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 @@ -126943,10 +126943,10 @@ index 569d5a650a4a2c6266ddf8fc6d38e0cd96b985f6..5822a3f60a96510201a6d88828ac5262 /* * Save the userland NEON/VFP state. Under UP, -From 9e197d6809356852ca185489f156071cc5d47a7d Mon Sep 17 00:00:00 2001 +From 05a6020f89eaccbeb9d1bdc039f21943d2da8d27 Mon Sep 17 00:00:00 2001 From: Michael Zoran Date: Sat, 11 Feb 2017 01:18:31 -0800 -Subject: [PATCH 129/143] ARM64: Force hardware emulation of deprecated +Subject: [PATCH 129/190] ARM64: Force hardware emulation of deprecated instructions. --- @@ -126974,10 +126974,10 @@ index ecf9298a12d48f11d5833dca0584d8ab028cf422..14e9146709857124891f8a3927efec87 case INSN_OBSOLETE: insn->current_mode = INSN_UNDEF; -From 919d9f14f43a8dd52c0008537f00dfccb96d5ef6 Mon Sep 17 00:00:00 2001 +From 47c4217bd9f5655847ec14e7d7b0b19078a40659 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 13 Feb 2017 15:33:47 +0000 -Subject: [PATCH 130/143] squash: fix order of sound/soc/bcm makefile +Subject: [PATCH 130/190] squash: fix order of sound/soc/bcm makefile --- sound/soc/bcm/Makefile | 4 ++-- @@ -127016,10 +127016,10 @@ index 222a7583891f632cc2297f49aa1a58ee46507875..bb1df438540193652ec5464e8bc51f63 obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o -From 56bd4eb7b09c4d016c8f7908d496b11bbadbd9a0 Mon Sep 17 00:00:00 2001 +From 885e780a94436ab097a715020294bb34292b878c Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 22 Jan 2017 12:49:36 +0100 -Subject: [PATCH 131/143] config: Enable regulator support +Subject: [PATCH 131/190] config: Enable regulator support Signed-off-by: Matthias Reichl --- @@ -127054,10 +127054,10 @@ index 1927b1671b6eced73e4b4d76352bb4b1301d077c..5351a59b7f670985f47fdbafa2611734 CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_MEDIA_ANALOG_TV_SUPPORT=y -From f135ac30c31d61724299d0449887727ce9def765 Mon Sep 17 00:00:00 2001 +From 9ea578dea494e6c139c6dcd2090705398e5c84d9 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 22 Jan 2017 12:49:36 +0100 -Subject: [PATCH 132/143] BCM270x DT: expose 3.3V and 5V system rails +Subject: [PATCH 132/190] BCM270x DT: expose 3.3V and 5V system rails Signed-off-by: Matthias Reichl --- @@ -127090,10 +127090,10 @@ index a46cb4a8b1419edd95e0e07c18b0f373222dc2bf..36d853715f2379e1952ce3d3be58dd67 + }; }; -From 437ca0a4918b034a16d8ac151b950cf838d484c5 Mon Sep 17 00:00:00 2001 +From d58dfa1aeb9618c7cbf8ffc76100b1af24265a46 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 22 Jan 2017 12:49:36 +0100 -Subject: [PATCH 133/143] BCM270x DT: Consolidate audio card overlays +Subject: [PATCH 133/190] BCM270x DT: Consolidate audio card overlays Reference 3.3V / 5V system rails instead of instantiating local regulators. @@ -127388,10 +127388,10 @@ index 16b1247bfa618ff85936ddf78c3aea58075eaa67..f8d48233e28c7c18509b4a95692f6aff __overlay__ { compatible = "rra,digidac1-soundcard"; -From 82906808c3fbe9c74524b2c055fad291c39c2fca Mon Sep 17 00:00:00 2001 +From 844ee22d27af5a1eaa22396bd4bb12e504e3cb7f Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 22 Jan 2017 12:49:37 +0100 -Subject: [PATCH 134/143] ASoC: Add driver for Cirrus Logic Audio Card +Subject: [PATCH 134/190] 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 @@ -128641,10 +128641,10 @@ index 0000000000000000000000000000000000000000..ac8651ddff7bd3701dffe22c7fb88352 +MODULE_DESCRIPTION("ASoC driver for Cirrus Logic Audio Card"); +MODULE_LICENSE("GPL"); -From 4dc3d4c1f881814cccba7de2c34e8a78345223fb Mon Sep 17 00:00:00 2001 +From a130902784ec875a268bf8b07dc86f586e90aba9 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 22 Jan 2017 12:49:37 +0100 -Subject: [PATCH 135/143] config: enable Cirrus Logic Audio Card +Subject: [PATCH 135/190] config: enable Cirrus Logic Audio Card Signed-off-by: Matthias Reichl --- @@ -128693,10 +128693,10 @@ index 5351a59b7f670985f47fdbafa26117346cafe87d..062a89f0e5fc723559ddc5739e19eb20 CONFIG_SND_BCM2708_SOC_RPI_PROTO=m CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m -From e3ef450ae4a4d20765f724e5b91e3378d2a8ba3c Mon Sep 17 00:00:00 2001 +From 2e138dae03942a44e5f035b2dce47b64bf6457c2 Mon Sep 17 00:00:00 2001 From: Martin Cerveny Date: Mon, 13 Feb 2017 17:23:47 +0100 -Subject: [PATCH 136/143] dwc_otg: fix summarize urb->actual_length for +Subject: [PATCH 136/190] dwc_otg: fix summarize urb->actual_length for isochronous transfers Kernel does not copy input data of ISO transfers to userspace @@ -128724,10 +128724,10 @@ index 162a656501988e56c9d780b7793d365fde09f801..992269d61ecf48126379a38e528f7190 dwc_otg_hcd_urb_get_iso_desc_status(dwc_otg_urb, i); } -From a58a00d172f51f697284a485ae1f3a6161ede074 Mon Sep 17 00:00:00 2001 +From 8e25438bf174b466801220bf904cd9fa9fbee65a Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 13 Feb 2017 17:20:08 +0000 -Subject: [PATCH 137/143] clk-bcm2835: Mark used PLLs and dividers CRITICAL +Subject: [PATCH 137/190] 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 @@ -128755,10 +128755,10 @@ index 093694e00caec6e133eb26712f890691cad999aa..33bfa2008479153402d188d71d382f02 divider->data = data; -From cef191d42985b1a1ba2c4a169b80e4628db23195 Mon Sep 17 00:00:00 2001 +From adcf0aa78d541f9beff8608fd800e620e898915d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 9 Feb 2017 14:33:30 +0000 -Subject: [PATCH 138/143] irq-bcm2836: Avoid "Invalid trigger warning" +Subject: [PATCH 138/190] irq-bcm2836: Avoid "Invalid trigger warning" Initialise the level for each IRQ to avoid a warning from the arm arch timer code. @@ -128782,10 +128782,10 @@ index 67dcac46cca72db4ebe2300eab04f0a867e8e14b..9a7ee04ee0d9b7aa734cf3159ed59c19 static void -From 70cab3f1bb92d60cf794a5baf22ac1fbdbec7ba2 Mon Sep 17 00:00:00 2001 +From fe1b02d4ef58bdd45ddc89d1e5ebaff94d8bd43c Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 9 Feb 2017 14:36:44 +0000 -Subject: [PATCH 139/143] sound: Demote deferral errors to INFO level +Subject: [PATCH 139/190] 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. @@ -128820,10 +128820,10 @@ index baa1afa41e3dd57fdc36655b7d3bbd147ade820f..0ddeffcc48d6c14f275ea6409d1a7de8 goto _err_defer; } -From cb1e295e8b8cf1edbab91d7d42919c28ebe3069e Mon Sep 17 00:00:00 2001 +From fd7ac16622c8784f8f270950692d00ca55e461eb Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 9 Feb 2017 14:40:33 +0000 -Subject: [PATCH 140/143] sound: Suppress error message about deferrals +Subject: [PATCH 140/190] sound: Suppress error message about deferrals Since driver load deferrals are expected and will already have resulted in a kernel message, suppress an essentially @@ -129070,10 +129070,10 @@ index 9db678e885efd63d84d60a098a84ed6772b19a2d..fadbfade100228aaafabb0d3bdf35c01 return ret; } -From 13607ce48ba1e8c887aeee343ac3f37ab9bf143b Mon Sep 17 00:00:00 2001 +From 32cd8c918fe1a0b5fdcce9ac9ef401f5d789c49d Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 17 Feb 2017 09:47:11 +0000 -Subject: [PATCH 141/143] BCM270X_DT: Add SMSC ethernet controller to DT +Subject: [PATCH 141/190] BCM270X_DT: Add SMSC ethernet controller to DT With an ethernet node in the DT, a suitable firmware can populate the local-mac-address property, removing the need for a downstream patch @@ -129136,10 +129136,10 @@ index 12764a3495b2372ffaf47e32ea0d21326ca83686..2a5b512d3e1acb17c6a40bf9d370f222 / { model = "Raspberry Pi 3 Model B"; -From e1d3ee3e5c9e549cec2088efeb1cbc9b1a682b31 Mon Sep 17 00:00:00 2001 +From 42e17cc726d0c80c0c20f4f6b45222415f49defb Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 17 Feb 2017 15:26:13 +0000 -Subject: [PATCH 142/143] brcmfmac: Mute expected startup 'errors' +Subject: [PATCH 142/190] brcmfmac: Mute expected startup 'errors' The brcmfmac WiFi driver always complains about the '00' country code and the firmware version is reported as an error. Modify the driver to @@ -129178,10 +129178,10 @@ index 4051780f64f44a5ce522babe6c371a1beb79a824..b081673abcb4aa72d70d8e0834b608f6 /* locate firmware version number for ethtool */ ptr = strrchr(buf, ' ') + 1; -From cbeb4f8aeb1dd71e911d365a921c0da4fbbdfdbb Mon Sep 17 00:00:00 2001 +From aeeedc76e1aee10ca9bdbf9319cf10803ff2b073 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 13 Feb 2017 17:20:08 +0000 -Subject: [PATCH 143/143] clk-bcm2835: Add claim-clocks property +Subject: [PATCH 143/190] 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, @@ -129316,3 +129316,7127 @@ index 33bfa2008479153402d188d71d382f0274c104ea..0b62d20f8b718cfd03c0346af784688e cprman->osc_name = of_clk_get_parent_name(dev->of_node, 0); if (!cprman->osc_name) return -ENODEV; + +From 0a5d83e549e1e230826d6b363d5c0d3998b44396 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Mon, 20 Feb 2017 20:01:16 +0100 +Subject: [PATCH 144/190] dmaengine: bcm2835: Fix cyclic DMA period splitting + +The code responsible for splitting periods into chunks that +can be handled by the DMA controller missed to update total_len, +the number of bytes processed in the current period, when there +are more chunks to follow. + +Therefore total_len was stuck at 0 and the code didn't work at all. +This resulted in a wrong control block layout and audio issues because +the cyclic DMA callback wasn't executing on period boundaries. + +Fix this by adding the missing total_len update. + +Signed-off-by: Matthias Reichl +Signed-off-by: Martin Sperl +Tested-by: Clive Messer +Reviewed-by: Eric Anholt +--- + drivers/dma/bcm2835-dma.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c +index 80d35f760b4a4a51e60c355a84d538bac3892a4d..599c218dc8a73172dd4bd4a058fc8f95a73f982f 100644 +--- a/drivers/dma/bcm2835-dma.c ++++ b/drivers/dma/bcm2835-dma.c +@@ -253,8 +253,11 @@ static void bcm2835_dma_create_cb_set_length( + */ + + /* have we filled in period_length yet? */ +- if (*total_len + control_block->length < period_len) ++ if (*total_len + control_block->length < period_len) { ++ /* update number of bytes in this period so far */ ++ *total_len += control_block->length; + return; ++ } + + /* calculate the length that remains to reach period_length */ + control_block->length = period_len - *total_len; + +From 75749184f36f67c4b6d9c93583c0becea7d2038c Mon Sep 17 00:00:00 2001 +From: Scott Ellis +Date: Thu, 23 Feb 2017 11:56:20 -0500 +Subject: [PATCH 145/190] config: Add ads1015 driver to config + +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index 59f58450f4f7932dbfe051d7431c227737902b37..33f5dfda12efc3022da80982e65df09b4cf7a52e 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -649,6 +649,7 @@ CONFIG_HWMON=m + CONFIG_SENSORS_LM75=m + CONFIG_SENSORS_SHT21=m + CONFIG_SENSORS_SHTC1=m ++CONFIG_SENSORS_ADS1015=m + CONFIG_SENSORS_INA2XX=m + CONFIG_THERMAL=y + CONFIG_THERMAL_BCM2835=y +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index 062a89f0e5fc723559ddc5739e19eb20c030f0f1..97b88dcbc1e6c5b165406222227157776b162801 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -643,6 +643,7 @@ CONFIG_HWMON=m + CONFIG_SENSORS_LM75=m + CONFIG_SENSORS_SHT21=m + CONFIG_SENSORS_SHTC1=m ++CONFIG_SENSORS_ADS1015=m + CONFIG_SENSORS_INA2XX=m + CONFIG_THERMAL=y + CONFIG_THERMAL_BCM2835=y + +From db06ff42b88a08a8454e5a9249337659467bf0be Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Fri, 27 Jan 2017 18:49:30 +0000 +Subject: [PATCH 146/190] config: add slcan kernel module + +See: https://github.com/raspberrypi/linux/issues/1819 +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index 33f5dfda12efc3022da80982e65df09b4cf7a52e..6d1e9c7f30d80d28bc12bae0ee40044b31237f85 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -358,6 +358,7 @@ CONFIG_BAYCOM_SER_HDX=m + CONFIG_YAM=m + CONFIG_CAN=m + CONFIG_CAN_VCAN=m ++CONFIG_CAN_SLCAN=m + CONFIG_CAN_MCP251X=m + CONFIG_IRDA=m + CONFIG_IRLAN=m +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index 97b88dcbc1e6c5b165406222227157776b162801..2cfa65bc83fd4b7e802f56965543a217e7d5ed5c 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -354,6 +354,7 @@ CONFIG_BAYCOM_SER_HDX=m + CONFIG_YAM=m + CONFIG_CAN=m + CONFIG_CAN_VCAN=m ++CONFIG_CAN_SLCAN=m + CONFIG_CAN_MCP251X=m + CONFIG_IRDA=m + CONFIG_IRLAN=m + +From 4c84efa8ef92c7f5b107b8c729207a408b37f658 Mon Sep 17 00:00:00 2001 +From: Miquel +Date: Fri, 24 Feb 2017 20:51:06 +0100 +Subject: [PATCH 147/190] sound: Support for Dion Audio LOCO-V2 DAC-AMP HAT + +Signed-off-by: Miquel Blauw +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 19 +++ + .../dts/overlays/dionaudio-loco-v2-overlay.dts | 49 ++++++++ + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + sound/soc/bcm/Kconfig | 7 ++ + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/dionaudio_loco-v2.c | 140 +++++++++++++++++++++ + 8 files changed, 220 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts + create mode 100644 sound/soc/bcm/dionaudio_loco-v2.c + +diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile +index 0a7d30cd573060964bb081ee6617d5b77a17b974..8856139d061472311b7cead0641b5645ef33caad 100644 +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -13,6 +13,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + bmp085_i2c-sensor.dtbo \ + dht11.dtbo \ + dionaudio-loco.dtbo \ ++ dionaudio-loco-v2.dtbo \ + dpi18.dtbo \ + dpi24.dtbo \ + dwc-otg.dtbo \ +diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README +index 46228fd324fc4c52eb0ba50316b4c02f8245bf04..c9845ba37018b821d7e5093e15a06721318b558f 100644 +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -308,6 +308,25 @@ Load: dtoverlay=dionaudio-loco + Params: + + ++Name: dionaudio-loco-v2 ++Info: Configures the Dion Audio LOCO-V2 DAC-AMP ++Load: dtoverlay=dionaudio-loco-v2,= ++Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec ++ Digital volume control. Enable with ++ "dtoverlay=hifiberry-dacplus,24db_digital_gain" ++ (The default behaviour is that the Digital ++ volume control is limited to a maximum of ++ 0dB. ie. it can attenuate but not provide ++ gain. For most users, this will be desired ++ as it will prevent clipping. By appending ++ the 24dB_digital_gain parameter, the Digital ++ volume control will allow up to 24dB of ++ gain. If this parameter is enabled, it is the ++ responsibility of the user to ensure that ++ the Digital volume control is set to a value ++ that does not result in clipping/distortion!) ++ ++ + Name: dpi18 + Info: Overlay for a generic 18-bit DPI display + This uses GPIOs 0-21 (so no I2C, uart etc.), and activates the output +diff --git a/arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts b/arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts +new file mode 100644 +index 0000000000000000000000000000000000000000..a1af93de30119734e8d14cbd454589d365a3ba10 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts +@@ -0,0 +1,49 @@ ++/* ++ * Definitions for Dion Audio LOCO-V2 DAC-AMP ++ * eg. dtoverlay=dionaudio-loco-v2 ++ * ++ * PCM5242 DAC (in software mode) and TPA3255 AMP. ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ frag0: __overlay__ { ++ compatible = "dionaudio,dionaudio-loco-v2"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pcm5122@4c { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm5122"; ++ reg = <0x4d>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ 24db_digital_gain = <&frag0>,"dionaudio,24db_digital_gain?"; ++ }; ++}; +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index 6d1e9c7f30d80d28bc12bae0ee40044b31237f85..c48df02efdf83a16ef97babc1353487dc2fcfb18 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -883,6 +883,7 @@ CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m + CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m + CONFIG_SND_DIGIDAC1_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m ++CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m + CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m + CONFIG_SND_PISOUND=m + CONFIG_SND_SOC_ADAU1701=m +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index 2cfa65bc83fd4b7e802f56965543a217e7d5ed5c..92e0536cb9d5a1fe0b7c16edae18d1b3e71e053b 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -877,6 +877,7 @@ CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m + CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m + CONFIG_SND_DIGIDAC1_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m ++CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m + CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m + CONFIG_SND_PISOUND=m + CONFIG_SND_SOC_ADAU1701=m +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index c0489e591b9b8c8da004ca9e300e97f1a21e5ce1..3e1ee13ef8ec31849e29e551026ba427f8e44fe6 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -134,6 +134,13 @@ config SND_BCM2708_SOC_DIONAUDIO_LOCO + help + Say Y or M if you want to add support for Dion Audio LOCO. + ++config SND_BCM2708_SOC_DIONAUDIO_LOCO_V2 ++ tristate "Support for Dion Audio LOCO-V2 DAC-AMP" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_PCM5122 ++ help ++ Say Y or M if you want to add support for Dion Audio LOCO-V2. ++ + config SND_BCM2708_SOC_ALLO_PIANO_DAC + tristate "Support for Allo Piano DAC" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index 84c2b20ce2e51b525797ee58de95734ee7847e15..4d8adf691021a974310589e92e599924811f22cb 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -25,6 +25,7 @@ snd-soc-raspidac3-objs := raspidac3.o + snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o + snd-soc-digidac1-soundcard-objs := digidac1-soundcard.o + snd-soc-dionaudio-loco-objs := dionaudio_loco.o ++snd-soc-dionaudio-loco-v2-objs := dionaudio_loco-v2.o + snd-soc-allo-piano-dac-objs := allo-piano-dac.o + snd-soc-pisound-objs := pisound.o + +@@ -44,5 +45,6 @@ obj-$(CONFIG_SND_BCM2708_SOC_RASPIDAC3) += snd-soc-raspidac3.o + obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o + obj-$(CONFIG_SND_DIGIDAC1_SOUNDCARD) += snd-soc-digidac1-soundcard.o + obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO) += snd-soc-dionaudio-loco.o ++obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2) += snd-soc-dionaudio-loco-v2.o + obj-$(CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC) += snd-soc-allo-piano-dac.o + obj-$(CONFIG_SND_PISOUND) += snd-soc-pisound.o +diff --git a/sound/soc/bcm/dionaudio_loco-v2.c b/sound/soc/bcm/dionaudio_loco-v2.c +new file mode 100644 +index 0000000000000000000000000000000000000000..a009c49477972a9832175d86f201b0357a08f7c0 +--- /dev/null ++++ b/sound/soc/bcm/dionaudio_loco-v2.c +@@ -0,0 +1,140 @@ ++/* ++ * ASoC Driver for Dion Audio LOCO-V2 DAC-AMP ++ * ++ * Author: Miquel Blauw ++ * Copyright 2017 ++ * ++ * Based on the software of the RPi-DAC writen by Florian Meier ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++static bool digital_gain_0db_limit = true; ++ ++static int snd_rpi_dionaudio_loco_v2_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ if (digital_gain_0db_limit) { ++ int ret; ++ struct snd_soc_card *card = rtd->card; ++ ++ ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207); ++ if (ret < 0) ++ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); ++ } ++ ++ return 0; ++} ++ ++static int snd_rpi_dionaudio_loco_v2_hw_params( ++ struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; ++ ++ unsigned int sample_bits = ++ snd_pcm_format_physical_width(params_format(params)); ++ ++ return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2); ++} ++ ++/* machine stream operations */ ++static struct snd_soc_ops snd_rpi_dionaudio_loco_v2_ops = { ++ .hw_params = snd_rpi_dionaudio_loco_v2_hw_params, ++}; ++ ++static struct snd_soc_dai_link snd_rpi_dionaudio_loco_v2_dai[] = { ++{ ++ .name = "DionAudio LOCO-V2", ++ .stream_name = "DionAudio LOCO-V2 DAC-AMP", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "pcm512x-hifi", ++ .platform_name = "bcm2708-i2s.0", ++ .codec_name = "pcm512x.1-004d", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS, ++ .ops = &snd_rpi_dionaudio_loco_v2_ops, ++ .init = snd_rpi_dionaudio_loco_v2_init, ++},}; ++ ++/* audio machine driver */ ++static struct snd_soc_card snd_rpi_dionaudio_loco_v2 = { ++ .name = "Dion Audio LOCO-V2", ++ .dai_link = snd_rpi_dionaudio_loco_v2_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_dionaudio_loco_v2_dai), ++}; ++ ++static int snd_rpi_dionaudio_loco_v2_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ snd_rpi_dionaudio_loco_v2.dev = &pdev->dev; ++ ++ if (pdev->dev.of_node) { ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai = ++ &snd_rpi_dionaudio_loco_v2_dai[0]; ++ ++ i2s_node = of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ if (i2s_node) { ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = i2s_node; ++ dai->platform_name = NULL; ++ dai->platform_of_node = i2s_node; ++ } ++ ++ digital_gain_0db_limit = !of_property_read_bool( ++ pdev->dev.of_node, "dionaudio,24db_digital_gain"); ++ } ++ ++ ret = snd_soc_register_card(&snd_rpi_dionaudio_loco_v2); ++ if (ret) ++ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ++ ret); ++ ++ return ret; ++} ++ ++static int snd_rpi_dionaudio_loco_v2_remove(struct platform_device *pdev) ++{ ++ return snd_soc_unregister_card(&snd_rpi_dionaudio_loco_v2); ++} ++ ++static const struct of_device_id dionaudio_of_match[] = { ++ { .compatible = "dionaudio,dionaudio-loco-v2", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, dionaudio_of_match); ++ ++static struct platform_driver snd_rpi_dionaudio_loco_v2_driver = { ++ .driver = { ++ .name = "snd-rpi-dionaudio-loco-v2", ++ .owner = THIS_MODULE, ++ .of_match_table = dionaudio_of_match, ++ }, ++ .probe = snd_rpi_dionaudio_loco_v2_probe, ++ .remove = snd_rpi_dionaudio_loco_v2_remove, ++}; ++ ++module_platform_driver(snd_rpi_dionaudio_loco_v2_driver); ++ ++MODULE_AUTHOR("Miquel Blauw "); ++MODULE_DESCRIPTION("ASoC Driver for DionAudio LOCO-V2"); ++MODULE_LICENSE("GPL v2"); + +From 560b3f18f12a55269d5e82c60fbb620ab2e9490c Mon Sep 17 00:00:00 2001 +From: Fe-Pi +Date: Wed, 1 Mar 2017 04:42:43 -0700 +Subject: [PATCH 148/190] Add support for Fe-Pi audio sound card. (#1867) + +Fe-Pi Audio Sound Card is based on NXP SGTL5000 codec. +Mechanical specification of the board is the same the Raspberry Pi Zero. +3.5mm jacks for Headphone/Mic, Line In, and Line Out. + +Signed-off-by: Henry Kupis +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 6 + + arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts | 70 +++++++++ + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + sound/soc/bcm/Kconfig | 7 + + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/fe-pi-audio.c | 158 +++++++++++++++++++++ + 8 files changed, 246 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts + create mode 100644 sound/soc/bcm/fe-pi-audio.c + +diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile +index 8856139d061472311b7cead0641b5645ef33caad..c8825365a4129b0098abf2002e1dcd936ea1ec8c 100644 +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -20,6 +20,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + dwc2.dtbo \ + enc28j60.dtbo \ + enc28j60-spi2.dtbo \ ++ fe-pi-audio.dtbo \ + gpio-ir.dtbo \ + gpio-poweroff.dtbo \ + hifiberry-amp.dtbo \ +diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README +index c9845ba37018b821d7e5093e15a06721318b558f..788e9e3b23f37d4c44b94b60ff2b72e2f0dbeeac 100644 +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -383,6 +383,12 @@ Params: int_pin GPIO used for INT (default 39) + speed SPI bus speed (default 12000000) + + ++Name: fe-pi-audio ++Info: Configures the Fe-Pi Audio Sound Card ++Load: dtoverlay=fe-pi-audio ++Params: ++ ++ + Name: gpio-ir + Info: Use GPIO pin as rc-core style infrared receiver input. The rc-core- + based gpio_ir_recv driver maps received keys directly to a +diff --git a/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts b/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts +new file mode 100644 +index 0000000000000000000000000000000000000000..81a07ed5a8c7594e65f0df2176418cac57a7910c +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts +@@ -0,0 +1,70 @@ ++// Definitions for Fe-Pi Audio ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&clocks>; ++ __overlay__ { ++ sgtl5000_mclk: sgtl5000_mclk { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <12288000>; ++ clock-output-names = "sgtl5000-mclk"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&soc>; ++ __overlay__ { ++ reg_1v8: reg_1v8@0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "1V8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ sgtl5000@0a { ++ #sound-dai-cells = <0>; ++ compatible = "fepi,sgtl5000"; ++ reg = <0x0a>; ++ clocks = <&sgtl5000_mclk>; ++ micbias-resistor-k-ohms = <2>; ++ micbias-voltage-m-volts = <3000>; ++ VDDA-supply = <&vdd_3v3_reg>; ++ VDDIO-supply = <&vdd_3v3_reg>; ++ VDDD-supply = <®_1v8>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "fe-pi,fe-pi-audio"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index c48df02efdf83a16ef97babc1353487dc2fcfb18..4ca09cf1e4e19154868b576eb3827b85789b6caf 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -885,6 +885,7 @@ CONFIG_SND_DIGIDAC1_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m + CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m ++CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m + CONFIG_SND_PISOUND=m + CONFIG_SND_SOC_ADAU1701=m + CONFIG_SND_SOC_ADAU7002=m +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index 92e0536cb9d5a1fe0b7c16edae18d1b3e71e053b..a9c46f902eb32b364423d8bef07b6b37f798c617 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -879,6 +879,7 @@ CONFIG_SND_DIGIDAC1_SOUNDCARD=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m + CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m + CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m ++CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m + CONFIG_SND_PISOUND=m + CONFIG_SND_SOC_ADAU1701=m + CONFIG_SND_SOC_ADAU7002=m +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index 3e1ee13ef8ec31849e29e551026ba427f8e44fe6..7473efd6f400a1a1618aac830753fce39d203b89 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -148,6 +148,13 @@ config SND_BCM2708_SOC_ALLO_PIANO_DAC + help + Say Y or M if you want to add support for Allo Piano DAC. + ++config SND_BCM2708_SOC_FE_PI_AUDIO ++ tristate "Support for Fe-Pi-Audio" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_SGTL5000 ++ help ++ Say Y or M if you want to add support for Fe-Pi-Audio. ++ + config SND_PISOUND + tristate "Support for Blokas Labs pisound" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index 4d8adf691021a974310589e92e599924811f22cb..8d2d2073dc2cede9fbd9eb8b49083650ba0a8172 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -28,6 +28,7 @@ snd-soc-dionaudio-loco-objs := dionaudio_loco.o + snd-soc-dionaudio-loco-v2-objs := dionaudio_loco-v2.o + snd-soc-allo-piano-dac-objs := allo-piano-dac.o + snd-soc-pisound-objs := pisound.o ++snd-soc-fe-pi-audio-objs := fe-pi-audio.o + + obj-$(CONFIG_SND_BCM2708_SOC_ADAU1977_ADC) += snd-soc-adau1977-adc.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o +@@ -48,3 +49,4 @@ obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO) += snd-soc-dionaudio-loco.o + obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2) += snd-soc-dionaudio-loco-v2.o + obj-$(CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC) += snd-soc-allo-piano-dac.o + obj-$(CONFIG_SND_PISOUND) += snd-soc-pisound.o ++obj-$(CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO) += snd-soc-fe-pi-audio.o +diff --git a/sound/soc/bcm/fe-pi-audio.c b/sound/soc/bcm/fe-pi-audio.c +new file mode 100644 +index 0000000000000000000000000000000000000000..015b56fd73cc36be5b5eecd17548fd036eb64d61 +--- /dev/null ++++ b/sound/soc/bcm/fe-pi-audio.c +@@ -0,0 +1,158 @@ ++/* ++ * ASoC Driver for Fe-Pi Audio Sound Card ++ * ++ * Author: Henry Kupis ++ * Copyright 2016 ++ * based on code by Florian Meier ++ * based on code by Shawn Guo ++ * ++ * 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 "../codecs/sgtl5000.h" ++ ++static int snd_fe_pi_audio_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ struct snd_soc_card *card = rtd->card; ++ struct snd_soc_codec *codec = rtd->codec; ++ ++ snd_soc_dapm_force_enable_pin(&card->dapm, "LO"); ++ snd_soc_dapm_force_enable_pin(&card->dapm, "ADC"); ++ snd_soc_dapm_force_enable_pin(&card->dapm, "DAC"); ++ snd_soc_dapm_force_enable_pin(&card->dapm, "HP"); ++ snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, ++ SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP); ++ ++ return 0; ++} ++ ++static int snd_fe_pi_audio_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct device *dev = rtd->card->dev; ++ struct snd_soc_dai *codec_dai = rtd->codec_dai; ++ ++ int ret; ++ ++ /* Set SGTL5000's SYSCLK */ ++ ret = snd_soc_dai_set_sysclk(codec_dai, SGTL5000_SYSCLK, 12288000, SND_SOC_CLOCK_IN); ++ if (ret) { ++ dev_err(dev, "could not set codec driver clock params\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++ ++static struct snd_soc_ops snd_fe_pi_audio_ops = { ++ .hw_params = snd_fe_pi_audio_hw_params, ++}; ++ ++static struct snd_soc_dai_link snd_fe_pi_audio_dai[] = { ++ { ++ .name = "FE-PI", ++ .stream_name = "Fe-Pi HiFi", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "sgtl5000", ++ .platform_name = "bcm2708-i2s.0", ++ .codec_name = "sgtl5000.1-000a", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBM_CFM, ++ .ops = &snd_fe_pi_audio_ops, ++ .init = snd_fe_pi_audio_init, ++ }, ++}; ++ ++static const struct snd_soc_dapm_route fe_pi_audio_dapm_routes[] = { ++ {"ADC", NULL, "Mic Bias"}, ++}; ++ ++ ++static struct snd_soc_card fe_pi_audio = { ++ .name = "Fe-Pi Audio", ++ .owner = THIS_MODULE, ++ .dai_link = snd_fe_pi_audio_dai, ++ .num_links = ARRAY_SIZE(snd_fe_pi_audio_dai), ++ ++ .dapm_routes = fe_pi_audio_dapm_routes, ++ .num_dapm_routes = ARRAY_SIZE(fe_pi_audio_dapm_routes), ++}; ++ ++static int snd_fe_pi_audio_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ struct snd_soc_card *card = &fe_pi_audio; ++ struct device_node *np = pdev->dev.of_node; ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai = &snd_fe_pi_audio_dai[0]; ++ ++ fe_pi_audio.dev = &pdev->dev; ++ ++ i2s_node = of_parse_phandle(np, "i2s-controller", 0); ++ if (!i2s_node) { ++ dev_err(&pdev->dev, "i2s_node phandle missing or invalid\n"); ++ return -EINVAL; ++ } ++ ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = i2s_node; ++ dai->platform_name = NULL; ++ dai->platform_of_node = i2s_node; ++ ++ of_node_put(i2s_node); ++ ++ card->dev = &pdev->dev; ++ platform_set_drvdata(pdev, card); ++ ++ ret = snd_soc_register_card(card); ++ if (ret && ret != -EPROBE_DEFER) ++ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); ++ ++ return ret; ++} ++ ++static int snd_fe_pi_audio_remove(struct platform_device *pdev) ++{ ++ return snd_soc_unregister_card(&fe_pi_audio); ++} ++ ++static const struct of_device_id snd_fe_pi_audio_of_match[] = { ++ { .compatible = "fe-pi,fe-pi-audio", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, snd_fe_pi_audio_of_match); ++ ++static struct platform_driver snd_fe_pi_audio_driver = { ++ .driver = { ++ .name = "snd-fe-pi-audio", ++ .owner = THIS_MODULE, ++ .of_match_table = snd_fe_pi_audio_of_match, ++ }, ++ .probe = snd_fe_pi_audio_probe, ++ .remove = snd_fe_pi_audio_remove, ++}; ++ ++module_platform_driver(snd_fe_pi_audio_driver); ++ ++MODULE_AUTHOR("Henry Kupis "); ++MODULE_DESCRIPTION("ASoC Driver for Fe-Pi Audio"); ++MODULE_LICENSE("GPL v2"); + +From d766ce62f73494e2390e6d81c7e207db38bec90f Mon Sep 17 00:00:00 2001 +From: Scott Ellis +Date: Wed, 1 Mar 2017 07:22:24 -0500 +Subject: [PATCH 149/190] Add overlay for ads1115 ADCs (#1864) + +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 22 ++++++ + arch/arm/boot/dts/overlays/ads1115-overlay.dts | 103 +++++++++++++++++++++++++ + 3 files changed, 126 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/ads1115-overlay.dts + +diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile +index c8825365a4129b0098abf2002e1dcd936ea1ec8c..c890e5ddb0e2eec982597a851023b539d318d6ce 100644 +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -4,6 +4,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + adau1977-adc.dtbo \ + adau7002-simple.dtbo \ + ads1015.dtbo \ ++ ads1115.dtbo \ + ads7846.dtbo \ + akkordion-iqdacplus.dtbo \ + allo-piano-dac-pcm512x-audio.dtbo \ +diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README +index 788e9e3b23f37d4c44b94b60ff2b72e2f0dbeeac..970c9c9b5c74467a3014a77039fa765d8f8c4e6f 100644 +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -196,6 +196,28 @@ Params: addr I2C bus address of device. Set based on how the + http://www.ti.com/lit/ds/symlink/ads1015.pdf + + ++Name: ads1115 ++Info: Texas Instruments ADS1115 ADC ++Load: dtoverlay=ads1115,[=] ++Params: addr I2C bus address of device. Set based on how the ++ addr pin is wired. (default=0x48 assumes addr ++ is pulled to GND) ++ cha_enable Enable virtual channel a. ++ cha_cfg Set the configuration for virtual channel a. ++ (default=4 configures this channel for the ++ voltage at A0 with respect to GND) ++ cha_datarate Set the datarate (samples/sec) for this channel. ++ (default=7 sets 860 sps) ++ cha_gain Set the gain of the Programmable Gain ++ Amplifier for this channel. (Default 1 sets the ++ full scale of the channel to 4.096 Volts) ++ ++ Channel parameters can be set for each enabled channel. ++ A maximum of 4 channels can be enabled (letters a thru d). ++ For more information refer to the device datasheet at: ++ http://www.ti.com/lit/ds/symlink/ads1115.pdf ++ ++ + Name: ads7846 + Info: ADS7846 Touch controller + Load: dtoverlay=ads7846,= +diff --git a/arch/arm/boot/dts/overlays/ads1115-overlay.dts b/arch/arm/boot/dts/overlays/ads1115-overlay.dts +new file mode 100644 +index 0000000000000000000000000000000000000000..7c16a1af3172d14e1a976b1776b9f1677278beed +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/ads1115-overlay.dts +@@ -0,0 +1,103 @@ ++/* ++ * TI ADS1115 multi-channel ADC overlay ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&i2c_arm>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ ads1115: ads1115 { ++ compatible = "ti,ads1115"; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0x48>; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "i2c_arm/ads1115"; ++ __dormant__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ channel_a: channel_a { ++ reg = <4>; ++ ti,gain = <1>; ++ ti,datarate = <7>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target-path = "i2c_arm/ads1115"; ++ __dormant__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ channel_b: channel_b { ++ reg = <5>; ++ ti,gain = <1>; ++ ti,datarate = <7>; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target-path = "i2c_arm/ads1115"; ++ __dormant__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ channel_c: channel_c { ++ reg = <6>; ++ ti,gain = <1>; ++ ti,datarate = <7>; ++ }; ++ }; ++ }; ++ ++ fragment@4 { ++ target-path = "i2c_arm/ads1115"; ++ __dormant__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ channel_d: channel_d { ++ reg = <7>; ++ ti,gain = <1>; ++ ti,datarate = <7>; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ addr = <&ads1115>,"reg:0"; ++ cha_enable = <0>,"=1"; ++ cha_cfg = <&channel_a>,"reg:0"; ++ cha_gain = <&channel_a>,"ti,gain:0"; ++ cha_datarate = <&channel_a>,"ti,datarate:0"; ++ chb_enable = <0>,"=2"; ++ chb_cfg = <&channel_b>,"reg:0"; ++ chb_gain = <&channel_b>,"ti,gain:0"; ++ chb_datarate = <&channel_b>,"ti,datarate:0"; ++ chc_enable = <0>,"=3"; ++ chc_cfg = <&channel_c>,"reg:0"; ++ chc_gain = <&channel_c>,"ti,gain:0"; ++ chc_datarate = <&channel_c>,"ti,datarate:0"; ++ chd_enable = <0>,"=4"; ++ chd_cfg = <&channel_d>,"reg:0"; ++ chd_gain = <&channel_d>,"ti,gain:0"; ++ chd_datarate = <&channel_d>,"ti,datarate:0"; ++ }; ++}; + +From 21dc54ba0a1b0864c414fec7c6ebf0e915f7765d Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 1 Mar 2017 16:06:53 +0000 +Subject: [PATCH 150/190] clk-bcm2835: Correct the prediv logic + +If a clock has the prediv flag set, both the integer and fractional +parts must be scaled when calculating the resulting frequency. + +Signed-off-by: Phil Elwell +--- + drivers/clk/bcm/clk-bcm2835.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index 0b62d20f8b718cfd03c0346af784688e26e9dcb6..ef0d05c58573f62de3632a920dfc19888c019d18 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -535,8 +535,10 @@ static unsigned long bcm2835_pll_get_rate(struct clk_hw *hw, + using_prediv = cprman_read(cprman, data->ana_reg_base + 4) & + data->ana->fb_prediv_mask; + +- if (using_prediv) ++ if (using_prediv) { + ndiv *= 2; ++ fdiv *= 2; ++ } + + return bcm2835_pll_rate_from_divisors(parent_rate, ndiv, fdiv, pdiv); + } + +From 1a01a08453ac677150039e7b4706ebc67b703bf1 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 1 Mar 2017 16:07:39 +0000 +Subject: [PATCH 151/190] amba_pl011: Round input clock up + +The UART clock is initialised to be as close to the requested +frequency as possible without exceeding it. Now that there is a +clock manager that returns the actual frequencies, an expected +48MHz clock is reported as 47999625. If the requested baudrate +== requested clock/16, there is no headroom and the slight +reduction in actual clock rate results in failure. + +Detect cases where it looks like a "round" clock was chosen and +adjust the reported clock to match that "round" value. As the +code comment says: + +/* + * If increasing a clock by less than 0.1% changes it + * from ..999.. to ..000.., round up. + */ + +Signed-off-by: Phil Elwell +--- + drivers/tty/serial/amba-pl011.c | 23 +++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c +index 6beb6233a0b6132b933cf8d85d8501dc1ce2fe4c..50792f9fa8fc530e2ecbc90f92adb11bada79cb2 100644 +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -1646,6 +1646,23 @@ static void pl011_put_poll_char(struct uart_port *port, + + #endif /* CONFIG_CONSOLE_POLL */ + ++unsigned long pl011_clk_round(unsigned long clk) ++{ ++ unsigned long scaler; ++ ++ /* ++ * If increasing a clock by less than 0.1% changes it ++ * from ..999.. to ..000.., round up. ++ */ ++ scaler = 1; ++ while (scaler * 100000 < clk) ++ scaler *= 10; ++ if ((clk + scaler - 1)/scaler % 1000 == 0) ++ clk = (clk/scaler + 1) * scaler; ++ ++ return clk; ++} ++ + static int pl011_hwinit(struct uart_port *port) + { + struct uart_amba_port *uap = +@@ -1662,7 +1679,7 @@ static int pl011_hwinit(struct uart_port *port) + if (retval) + return retval; + +- uap->port.uartclk = clk_get_rate(uap->clk); ++ uap->port.uartclk = pl011_clk_round(clk_get_rate(uap->clk)); + + /* Clear pending error and receive interrupts */ + pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS | +@@ -2300,7 +2317,7 @@ static int __init pl011_console_setup(struct console *co, char *options) + plat->init(); + } + +- uap->port.uartclk = clk_get_rate(uap->clk); ++ uap->port.uartclk = pl011_clk_round(clk_get_rate(uap->clk)); + + if (uap->vendor->fixed_options) { + baud = uap->fixed_baud; +@@ -2428,6 +2445,7 @@ static struct uart_driver amba_reg = { + .cons = AMBA_CONSOLE, + }; + ++#if 0 + static int pl011_probe_dt_alias(int index, struct device *dev) + { + struct device_node *np; +@@ -2459,6 +2477,7 @@ static int pl011_probe_dt_alias(int index, struct device *dev) + + return ret; + } ++#endif + + /* unregisters the driver also if no more ports are left */ + static void pl011_unregister_port(struct uart_amba_port *uap) + +From 5fae662f7139c34f8b49dbf761628d877ffc3c96 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 13 Feb 2017 11:10:50 +0000 +Subject: [PATCH 152/190] BCM2835-V4L2: Ensure H264 header bytes get a sensible + timestamp + +H264 header come off VC with 0 timestamps, which means they get a +strange timestamp when processed with VC/kernel start times, +particularly if used with the inline header option. +Remember the last frame timestamp and use that if set, or otherwise +use the kernel start time. + +https://github.com/raspberrypi/linux/issues/1836 + +Signed-off-by: Dave Stevenson +--- + drivers/media/platform/bcm2835/bcm2835-camera.c | 30 ++++++++++++++++++++++--- + drivers/media/platform/bcm2835/bcm2835-camera.h | 2 ++ + 2 files changed, 29 insertions(+), 3 deletions(-) + +diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.c b/drivers/media/platform/bcm2835/bcm2835-camera.c +index 4f03949aecf3afbf2e04df38289447195a8847a6..e69731320f4e59249933bc21843913deab4a1209 100644 +--- a/drivers/media/platform/bcm2835/bcm2835-camera.c ++++ b/drivers/media/platform/bcm2835/bcm2835-camera.c +@@ -356,8 +356,13 @@ static void buffer_cb(struct vchiq_mmal_instance *instance, + } + } else { + if (dev->capture.frame_count) { +- if (dev->capture.vc_start_timestamp != -1 && +- pts != 0) { ++ if (dev->capture.vc_start_timestamp == -1) { ++ buf->vb.vb2_buf.timestamp = ktime_get_ns(); ++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, ++ "Buffer time set as current time - %lld", ++ buf->vb.vb2_buf.timestamp); ++ ++ } else if(pts != 0) { + struct timeval timestamp; + s64 runtime_us = pts - + dev->capture.vc_start_timestamp; +@@ -390,10 +395,27 @@ static void buffer_cb(struct vchiq_mmal_instance *instance, + buf->vb.vb2_buf.timestamp = timestamp.tv_sec * 1000000000ULL + + timestamp.tv_usec * 1000ULL; + } else { +- buf->vb.vb2_buf.timestamp = ktime_get_ns(); ++ if (dev->capture.last_timestamp) { ++ buf->vb.vb2_buf.timestamp = dev->capture.last_timestamp; ++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, ++ "Buffer time set as last timestamp - %lld", ++ buf->vb.vb2_buf.timestamp); ++ } ++ else { ++ buf->vb.vb2_buf.timestamp = ++ dev->capture.kernel_start_ts.tv_sec * 1000000000ULL + ++ dev->capture.kernel_start_ts.tv_usec * 1000ULL; ++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, ++ "Buffer time set as start timestamp - %lld", ++ buf->vb.vb2_buf.timestamp); ++ } + } ++ dev->capture.last_timestamp = buf->vb.vb2_buf.timestamp; + + vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length); ++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, ++ "Buffer has ts %llu", ++ dev->capture.last_timestamp); + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + + if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS && +@@ -559,6 +581,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) + "Start time %lld size %d\n", + dev->capture.vc_start_timestamp, parameter_size); + ++ dev->capture.last_timestamp = 0; ++ + v4l2_get_timestamp(&dev->capture.kernel_start_ts); + + /* enable the camera port */ +diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.h b/drivers/media/platform/bcm2835/bcm2835-camera.h +index e6aeb7e7e381de65d6c6586205069a4c5cd33274..7f8a68916a67001bc9241bce2928519a2ce1ba78 100644 +--- a/drivers/media/platform/bcm2835/bcm2835-camera.h ++++ b/drivers/media/platform/bcm2835/bcm2835-camera.h +@@ -93,6 +93,8 @@ struct bm2835_mmal_dev { + s64 vc_start_timestamp; + /* Kernel start timestamp for streaming */ + struct timeval kernel_start_ts; ++ /* Timestamp of last frame */ ++ u64 last_timestamp; + + struct vchiq_mmal_port *port; /* port being used for capture */ + /* camera port being used for capture */ + +From 02a146929141f8f6cf60ec15854cbb7e79ad828e Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 13 Feb 2017 13:11:41 +0000 +Subject: [PATCH 153/190] BCM2835-V4L2: Correctly denote key frames in encoded + data + +Forward MMAL key frame flags to the V4L2 buffers. + +Signed-off-by: Dave Stevenson +--- + drivers/media/platform/bcm2835/bcm2835-camera.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.c b/drivers/media/platform/bcm2835/bcm2835-camera.c +index e69731320f4e59249933bc21843913deab4a1209..6bdec0806126044cf7146d53326e4da5b4269884 100644 +--- a/drivers/media/platform/bcm2835/bcm2835-camera.c ++++ b/drivers/media/platform/bcm2835/bcm2835-camera.c +@@ -413,6 +413,9 @@ static void buffer_cb(struct vchiq_mmal_instance *instance, + dev->capture.last_timestamp = buf->vb.vb2_buf.timestamp; + + vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length); ++ if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) ++ buf->vb.flags |= V4L2_BUF_FLAG_KEYFRAME; ++ + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "Buffer has ts %llu", + dev->capture.last_timestamp); + +From 0caafb8487b1d9cb832d0d6f1be171615eb58d62 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 20 Feb 2017 17:01:21 +0000 +Subject: [PATCH 154/190] bcm2835-gpio-exp: Driver for GPIO expander via + mailbox service + +Pi3 and Compute Module 3 have a GPIO expander that the +VPU communicates with. +There is a mailbox service that now allows control of this +expander, so add a kernel driver that can make use of it. + +Pwr_led node added to device-tree for Pi3. + +Signed-off-by: Dave Stevenson +--- + arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 22 +++ + arch/arm/boot/dts/bcm2710-rpi-cm3.dts | 10 +- + arch/arm/configs/bcm2709_defconfig | 1 + + drivers/gpio/Kconfig | 7 + + drivers/gpio/Makefile | 1 + + drivers/gpio/gpio-bcm-exp.c | 256 +++++++++++++++++++++++++++++ + include/soc/bcm2835/raspberrypi-firmware.h | 4 + + 7 files changed, 300 insertions(+), 1 deletion(-) + create mode 100644 drivers/gpio/gpio-bcm-exp.c + +diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +index 2a5b512d3e1acb17c6a40bf9d370f22279c4d552..616cfd5c7094596b497101e8feca25e25e77c3e8 100644 +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +@@ -96,6 +96,14 @@ + firmware = <&firmware>; + status = "okay"; + }; ++ ++ expgpio: expgpio { ++ compatible = "brcm,bcm2835-expgpio"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ firmware = <&firmware>; ++ status = "okay"; ++ }; + }; + + &fb { +@@ -163,6 +171,16 @@ + linux,default-trigger = "mmc0"; + gpios = <&virtgpio 0 0>; + }; ++ ++ pwr_led: pwr { ++ label = "led1"; ++ linux,default-trigger = "input"; ++ gpios = <&expgpio 7 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&hdmi { ++ hpd-gpios = <&expgpio 4 GPIO_ACTIVE_LOW>; + }; + + &audio { +@@ -193,6 +211,10 @@ + act_led_activelow = <&act_led>,"gpios:8"; + act_led_trigger = <&act_led>,"linux,default-trigger"; + ++ pwr_led_gpio = <&pwr_led>,"gpios:4"; ++ pwr_led_activelow = <&pwr_led>,"gpios:8"; ++ pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; ++ + audio = <&audio>,"status"; + watchdog = <&watchdog>,"status"; + random = <&random>,"status"; +diff --git a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts +index 3ba6e621856c288ae4694f758604619f59064fdb..fe402e84cdda884583336422289ac8b3cc12fb28 100644 +--- a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts +@@ -65,6 +65,14 @@ + firmware = <&firmware>; + status = "okay"; + }; ++ ++ expgpio: expgpio { ++ compatible = "brcm,bcm2835-expgpio"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ firmware = <&firmware>; ++ status = "okay"; ++ }; + }; + + &fb { +@@ -123,7 +131,7 @@ + }; + + &hdmi { +- hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; ++ hpd-gpios = <&expgpio 0 GPIO_ACTIVE_LOW>; + }; + + &audio { +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index 4ca09cf1e4e19154868b576eb3827b85789b6caf..0ee1ff698a5571f80da89a1067025b32fe546136 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -621,6 +621,7 @@ CONFIG_PPS=m + CONFIG_PPS_CLIENT_LDISC=m + CONFIG_PPS_CLIENT_GPIO=m + CONFIG_GPIO_SYSFS=y ++CONFIG_GPIO_BCM_EXP=y + CONFIG_GPIO_BCM_VIRT=y + CONFIG_GPIO_ARIZONA=m + CONFIG_GPIO_STMPE=y +diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig +index ade9f7dd8f973fd44031a0a6d42c28f01b424d1b..a6a8caa2c803c4c4a119d5d4b6d0acd2d9f2083c 100644 +--- a/drivers/gpio/Kconfig ++++ b/drivers/gpio/Kconfig +@@ -128,6 +128,13 @@ config GPIO_AXP209 + help + Say yes to enable GPIO support for the AXP209 PMIC + ++config GPIO_BCM_EXP ++ bool "Broadcom Exp GPIO" ++ depends on OF_GPIO && RASPBERRYPI_FIRMWARE && (ARCH_BCM2835 || COMPILE_TEST) ++ help ++ Turn on GPIO support for Broadcom chips using the firmware mailbox ++ to communicate with VideoCore on BCM283x chips. ++ + config GPIO_BCM_KONA + bool "Broadcom Kona GPIO" + depends on OF_GPIO && (ARCH_BCM_MOBILE || COMPILE_TEST) +diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile +index dec0669a5f030023288047f2abe68b0f2e0946d7..73392801474433668c05442dc391af91b262b76e 100644 +--- a/drivers/gpio/Makefile ++++ b/drivers/gpio/Makefile +@@ -32,6 +32,7 @@ obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o + obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o + obj-$(CONFIG_GPIO_ASPEED) += gpio-aspeed.o + obj-$(CONFIG_GPIO_AXP209) += gpio-axp209.o ++obj-$(CONFIG_GPIO_BCM_EXP) += gpio-bcm-exp.o + obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o + obj-$(CONFIG_GPIO_BCM_VIRT) += gpio-bcm-virt.o + obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o +diff --git a/drivers/gpio/gpio-bcm-exp.c b/drivers/gpio/gpio-bcm-exp.c +new file mode 100644 +index 0000000000000000000000000000000000000000..681a91492d4c33bdfd42416e069218e8611cc4d9 +--- /dev/null ++++ b/drivers/gpio/gpio-bcm-exp.c +@@ -0,0 +1,256 @@ ++/* ++ * Broadcom expander GPIO driver ++ * ++ * Uses the firmware mailbox service to communicate with the ++ * GPIO expander on the VPU. ++ * ++ * Copyright (C) 2017 Raspberry Pi Trading Ltd. ++ * ++ * Author: Dave Stevenson ++ * Based on gpio-bcm-virt.c by Dom Cobley ++ * ++ * 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 ++ ++#define MODULE_NAME "brcmexp-gpio" ++#define NUM_GPIO 8 ++ ++struct brcmexp_gpio { ++ struct gpio_chip gc; ++ struct device *dev; ++ struct rpi_firmware *fw; ++}; ++ ++struct gpio_set_config { ++ u32 gpio, direction, polarity, term_en, term_pull_up, state; ++}; ++ ++struct gpio_get_config { ++ u32 gpio, direction, polarity, term_en, term_pull_up; ++}; ++ ++struct gpio_get_set_state { ++ u32 gpio, state; ++}; ++ ++static int brcmexp_gpio_get_polarity(struct gpio_chip *gc, unsigned int off) ++{ ++ struct brcmexp_gpio *gpio; ++ struct gpio_get_config get; ++ int ret; ++ ++ gpio = container_of(gc, struct brcmexp_gpio, gc); ++ ++ get.gpio = off + gpio->gc.base; /* GPIO to update */ ++ ++ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG, ++ &get, sizeof(get)); ++ if (ret) { ++ dev_err(gpio->dev, ++ "Failed to get GPIO %u config (%d)\n", off, ret); ++ return ret; ++ } ++ return get.polarity; ++} ++ ++static int brcmexp_gpio_dir_in(struct gpio_chip *gc, unsigned int off) ++{ ++ struct brcmexp_gpio *gpio; ++ struct gpio_set_config set_in; ++ int ret; ++ ++ gpio = container_of(gc, struct brcmexp_gpio, gc); ++ ++ set_in.gpio = off + gpio->gc.base; /* GPIO to update */ ++ set_in.direction = 0; /* Input */ ++ set_in.polarity = brcmexp_gpio_get_polarity(gc, off); ++ /* Retain existing setting */ ++ set_in.term_en = 0; /* termination disabled */ ++ set_in.term_pull_up = 0; /* n/a as termination disabled */ ++ set_in.state = 0; /* n/a as configured as an input */ ++ ++ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG, ++ &set_in, sizeof(set_in)); ++ if (ret) { ++ dev_err(gpio->dev, ++ "Failed to set GPIO %u to input (%d)\n", ++ off, ret); ++ return ret; ++ } ++ return 0; ++} ++ ++static int brcmexp_gpio_dir_out(struct gpio_chip *gc, unsigned int off, int val) ++{ ++ struct brcmexp_gpio *gpio; ++ struct gpio_set_config set_out; ++ int ret; ++ ++ gpio = container_of(gc, struct brcmexp_gpio, gc); ++ ++ set_out.gpio = off + gpio->gc.base; /* GPIO to update */ ++ set_out.direction = 1; /* Output */ ++ set_out.polarity = brcmexp_gpio_get_polarity(gc, off); ++ /* Retain existing setting */ ++ set_out.term_en = 0; /* n/a as an output */ ++ set_out.term_pull_up = 0; /* n/a as termination disabled */ ++ set_out.state = val; /* Output state */ ++ ++ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG, ++ &set_out, sizeof(set_out)); ++ if (ret) { ++ dev_err(gpio->dev, ++ "Failed to set GPIO %u to output (%d)\n", off, ret); ++ return ret; ++ } ++ return 0; ++} ++ ++static int brcmexp_gpio_get_direction(struct gpio_chip *gc, unsigned int off) ++{ ++ struct brcmexp_gpio *gpio; ++ struct gpio_get_config get; ++ int ret; ++ ++ gpio = container_of(gc, struct brcmexp_gpio, gc); ++ ++ get.gpio = off + gpio->gc.base; /* GPIO to update */ ++ ++ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG, ++ &get, sizeof(get)); ++ if (ret) { ++ dev_err(gpio->dev, ++ "Failed to get GPIO %u config (%d)\n", off, ret); ++ return ret; ++ } ++ return get.direction ? GPIOF_DIR_OUT : GPIOF_DIR_IN; ++} ++ ++static int brcmexp_gpio_get(struct gpio_chip *gc, unsigned int off) ++{ ++ struct brcmexp_gpio *gpio; ++ struct gpio_get_set_state get; ++ int ret; ++ ++ gpio = container_of(gc, struct brcmexp_gpio, gc); ++ ++ get.gpio = off + gpio->gc.base; /* GPIO to update */ ++ get.state = 0; /* storage for returned value */ ++ ++ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_STATE, ++ &get, sizeof(get)); ++ if (ret) { ++ dev_err(gpio->dev, ++ "Failed to get GPIO %u state (%d)\n", off, ret); ++ return ret; ++ } ++ return !!get.state; ++} ++ ++static void brcmexp_gpio_set(struct gpio_chip *gc, unsigned int off, int val) ++{ ++ struct brcmexp_gpio *gpio; ++ struct gpio_get_set_state set; ++ int ret; ++ ++ gpio = container_of(gc, struct brcmexp_gpio, gc); ++ ++ off += gpio->gc.base; ++ ++ set.gpio = off + gpio->gc.base; /* GPIO to update */ ++ set.state = val; /* Output state */ ++ ++ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_STATE, ++ &set, sizeof(set)); ++ if (ret) ++ dev_err(gpio->dev, ++ "Failed to set GPIO %u state (%d)\n", off, ret); ++} ++ ++static int brcmexp_gpio_probe(struct platform_device *pdev) ++{ ++ int err = 0; ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ struct device_node *fw_node; ++ struct rpi_firmware *fw; ++ struct brcmexp_gpio *ucb; ++ ++ fw_node = of_parse_phandle(np, "firmware", 0); ++ if (!fw_node) { ++ dev_err(dev, "Missing firmware node\n"); ++ return -ENOENT; ++ } ++ ++ fw = rpi_firmware_get(fw_node); ++ if (!fw) ++ return -EPROBE_DEFER; ++ ++ ucb = devm_kzalloc(dev, sizeof(*ucb), GFP_KERNEL); ++ if (!ucb) ++ return -EINVAL; ++ ++ ucb->fw = fw; ++ ucb->dev = dev; ++ ucb->gc.label = MODULE_NAME; ++ ucb->gc.owner = THIS_MODULE; ++ ucb->gc.of_node = np; ++ ucb->gc.base = 128; ++ ucb->gc.ngpio = NUM_GPIO; ++ ++ ucb->gc.direction_input = brcmexp_gpio_dir_in; ++ ucb->gc.direction_output = brcmexp_gpio_dir_out; ++ ucb->gc.get_direction = brcmexp_gpio_get_direction; ++ ucb->gc.get = brcmexp_gpio_get; ++ ucb->gc.set = brcmexp_gpio_set; ++ ucb->gc.can_sleep = true; ++ ++ err = gpiochip_add(&ucb->gc); ++ if (err) ++ return err; ++ ++ platform_set_drvdata(pdev, ucb); ++ ++ return 0; ++} ++ ++static int brcmexp_gpio_remove(struct platform_device *pdev) ++{ ++ struct brcmexp_gpio *ucb = platform_get_drvdata(pdev); ++ ++ gpiochip_remove(&ucb->gc); ++ ++ return 0; ++} ++ ++static const struct of_device_id __maybe_unused brcmexp_gpio_ids[] = { ++ { .compatible = "brcm,bcm2835-expgpio" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, brcmexp_gpio_ids); ++ ++static struct platform_driver brcmexp_gpio_driver = { ++ .driver = { ++ .name = MODULE_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(brcmexp_gpio_ids), ++ }, ++ .probe = brcmexp_gpio_probe, ++ .remove = brcmexp_gpio_remove, ++}; ++module_platform_driver(brcmexp_gpio_driver); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Dave Stevenson "); ++MODULE_DESCRIPTION("brcm-exp GPIO driver"); ++MODULE_ALIAS("platform:brcmexp-gpio"); +diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h +index 280791fb9656901392ce67e44cb742c96f090ed4..dc7fd58afd5dddebf9b17065bb069a1db663362c 100644 +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -83,7 +83,11 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_SET_TURBO = 0x00038009, + RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021, + RPI_FIRMWARE_SET_DOMAIN_STATE = 0x00038030, ++ RPI_FIRMWARE_GET_GPIO_STATE = 0x00030041, ++ RPI_FIRMWARE_SET_GPIO_STATE = 0x00038041, + RPI_FIRMWARE_SET_SDHOST_CLOCK = 0x00038042, ++ RPI_FIRMWARE_GET_GPIO_CONFIG = 0x00030043, ++ RPI_FIRMWARE_SET_GPIO_CONFIG = 0x00038043, + + /* Dispmanx TAGS */ + RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, + +From 6513883b414602f43a1f6172687910725ec2c513 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 24 May 2016 16:30:05 +0100 +Subject: [PATCH 155/190] BCM270X_DT: Add bcm2708-rpi-0-w.dts + +Add DT support for the Pi Zero W. N.B. It will not be loaded +automatically without a corresponding change to the firmware. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/Makefile | 1 + + arch/arm/boot/dts/bcm2708-rpi-0-w.dts | 197 ++++++++++++++++++++++++++++++++++ + 2 files changed, 198 insertions(+) + create mode 100644 arch/arm/boot/dts/bcm2708-rpi-0-w.dts + +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index 0263d6172d3af40668c02535a4f8dce022f3a93d..3c758781b9171f957b6afdd87c169795a61007a5 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -4,6 +4,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ + bcm2708-rpi-b.dtb \ + bcm2708-rpi-b-plus.dtb \ + bcm2708-rpi-cm.dtb \ ++ bcm2708-rpi-0-w.dtb \ + bcm2709-rpi-2-b.dtb \ + bcm2710-rpi-3-b.dtb \ + bcm2710-rpi-cm3.dtb +diff --git a/arch/arm/boot/dts/bcm2708-rpi-0-w.dts b/arch/arm/boot/dts/bcm2708-rpi-0-w.dts +new file mode 100644 +index 0000000000000000000000000000000000000000..db0f99ddf2f46e83827d56e21c4846dd0b414c63 +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2708-rpi-0-w.dts +@@ -0,0 +1,197 @@ ++/dts-v1/; ++ ++#include "bcm2708.dtsi" ++ ++/ { ++ model = "Raspberry Pi Zero W"; ++}; ++ ++&gpio { ++ sdhost_pins: sdhost_pins { ++ brcm,pins = <48 49 50 51 52 53>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ spi0_pins: spi0_pins { ++ brcm,pins = <9 10 11>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ spi0_cs_pins: spi0_cs_pins { ++ brcm,pins = <8 7>; ++ brcm,function = <1>; /* output */ ++ }; ++ ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; ++ }; ++ ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; ++ }; ++ ++ i2s_pins: i2s { ++ brcm,pins = <18 19 20 21>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ sdio_pins: sdio_pins { ++ brcm,pins = <34 35 36 37 38 39>; ++ brcm,function = <7>; /* ALT3 = SD1 */ ++ brcm,pull = <0 2 2 2 2 2>; ++ }; ++ ++ bt_pins: bt_pins { ++ brcm,pins = <43>; ++ brcm,function = <4>; /* alt0:GPCLK2 */ ++ brcm,pull = <0>; /* none */ ++ }; ++ ++ uart0_pins: uart0_pins { ++ brcm,pins = <30 31 32 33>; ++ brcm,function = <7>; /* alt3=UART0 */ ++ brcm,pull = <2 0 0 2>; /* up none none up */ ++ }; ++ ++ uart1_pins: uart1_pins { ++ brcm,pins; ++ brcm,function; ++ brcm,pull; ++ }; ++ ++ audio_pins: audio_pins { ++ brcm,pins = <>; ++ brcm,function = <>; ++ }; ++}; ++ ++&sdhost { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdhost_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&mmc { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio_pins>; ++ non-removable; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&fb { ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins &bt_pins>; ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "okay"; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; ++ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; ++ ++ spidev0: spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++ ++ spidev1: spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++}; ++ ++&i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c2 { ++ clock-frequency = <100000>; ++}; ++ ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++&random { ++ status = "okay"; ++}; ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; ++ gpios = <&gpio 47 0>; ++ }; ++}; ++ ++&hdmi { ++ hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; ++}; ++ ++&audio { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&audio_pins>; ++}; ++ ++/ { ++ chosen { ++ bootargs = "8250.nr_uarts=1"; ++ }; ++}; ++ ++/ { ++ __overrides__ { ++ uart0 = <&uart0>,"status"; ++ uart1 = <&uart1>,"status"; ++ i2s = <&i2s>,"status"; ++ spi = <&spi0>,"status"; ++ i2c0 = <&i2c0>,"status"; ++ i2c1 = <&i2c1>,"status"; ++ i2c2_iknowwhatimdoing = <&i2c2>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ i2c2_baudrate = <&i2c2>,"clock-frequency:0"; ++ ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ ++ audio = <&audio>,"status"; ++ watchdog = <&watchdog>,"status"; ++ random = <&random>,"status"; ++ sd_overclock = <&sdhost>,"brcm,overclock-50:0"; ++ sd_force_pio = <&sdhost>,"brcm,force-pio?"; ++ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0"; ++ sd_debug = <&sdhost>,"brcm,debug"; ++ }; ++}; + +From dca094edd80fab9d689912584a40a45314649288 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 6 Mar 2017 09:06:18 +0000 +Subject: [PATCH 156/190] 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 +driver. Since the core frequency can change without warning, it is +safer to report the maximum clock rate to users of the core clock - +I2C, SPI and the mini UART - to err on the safe side when calculating +clock divisors. + +If the DT node for the clock driver includes a reference to the +firmware node, use the firmware API to query the maximum core clock +instead of reading the divider registers. + +Prior to this patch, a "100KHz" I2C bus was sometimes clocked at about +160KHz. In particular, switching to the 4.9 kernel was likely to break +SenseHAT usage on a Pi3. + +Signed-off-by: Phil Elwell +--- + arch/arm/boot/dts/bcm2708-rpi.dtsi | 4 ++++ + drivers/clk/bcm/clk-bcm2835.c | 39 +++++++++++++++++++++++++++++++++++++- + 2 files changed, 42 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/bcm2708-rpi.dtsi b/arch/arm/boot/dts/bcm2708-rpi.dtsi +index 055090ace687b94e4d25de65d1b8fbf7f730be9e..ef14e9ac6cd2092efb1681682dd2d3c52b8abfd5 100644 +--- a/arch/arm/boot/dts/bcm2708-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2708-rpi.dtsi +@@ -107,3 +107,7 @@ + &usb { + power-domains = <&power RPI_POWER_DOMAIN_USB>; + }; ++ ++&clocks { ++ firmware = <&firmware>; ++}; +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index ef0d05c58573f62de3632a920dfc19888c019d18..41dccc4ebe6f367054822aed11cb0cd4d985c21a 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -44,6 +44,7 @@ + #include + #include + #include ++#include + + #define CM_PASSWORD 0x5a000000 + +@@ -297,9 +298,12 @@ + #define LOCK_TIMEOUT_NS 100000000 + #define BCM2835_MAX_FB_RATE 1750000000u + ++#define VCMSG_ID_CORE_CLOCK 4 ++ + struct bcm2835_cprman { + struct device *dev; + void __iomem *regs; ++ struct rpi_firmware *fw; + spinlock_t regs_lock; /* spinlock for all clocks */ + const char *osc_name; + +@@ -936,6 +940,30 @@ static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw, + return bcm2835_clock_rate_from_divisor(clock, parent_rate, div); + } + ++static unsigned long bcm2835_clock_get_rate_vpu(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); ++ struct bcm2835_cprman *cprman = clock->cprman; ++ ++ if (cprman->fw) { ++ struct { ++ u32 id; ++ u32 val; ++ } packet; ++ ++ packet.id = VCMSG_ID_CORE_CLOCK; ++ packet.val = 0; ++ ++ if (!rpi_firmware_property(cprman->fw, ++ RPI_FIRMWARE_GET_MAX_CLOCK_RATE, ++ &packet, sizeof(packet))) ++ return packet.val; ++ } ++ ++ return bcm2835_clock_get_rate(hw, parent_rate); ++} ++ + static void bcm2835_clock_wait_busy(struct bcm2835_clock *clock) + { + struct bcm2835_cprman *cprman = clock->cprman; +@@ -1192,7 +1220,7 @@ static int bcm2835_vpu_clock_is_on(struct clk_hw *hw) + */ + static const struct clk_ops bcm2835_vpu_clock_clk_ops = { + .is_prepared = bcm2835_vpu_clock_is_on, +- .recalc_rate = bcm2835_clock_get_rate, ++ .recalc_rate = bcm2835_clock_get_rate_vpu, + .set_rate = bcm2835_clock_set_rate, + .determine_rate = bcm2835_clock_determine_rate, + .set_parent = bcm2835_clock_set_parent, +@@ -1952,6 +1980,7 @@ static int bcm2835_clk_probe(struct platform_device *pdev) + struct resource *res; + const struct bcm2835_clk_desc *desc; + const size_t asize = ARRAY_SIZE(clk_desc_array); ++ struct device_node *fw_node; + size_t i; + u32 clk_id; + int ret; +@@ -1969,6 +1998,14 @@ static int bcm2835_clk_probe(struct platform_device *pdev) + if (IS_ERR(cprman->regs)) + return PTR_ERR(cprman->regs); + ++ fw_node = of_parse_phandle(dev->of_node, "firmware", 0); ++ if (fw_node) { ++ struct rpi_firmware *fw = rpi_firmware_get(NULL); ++ if (!fw) ++ return -EPROBE_DEFER; ++ cprman->fw = fw; ++ } ++ + memset(bcm2835_clk_claimed, 0, sizeof(bcm2835_clk_claimed)); + for (i = 0; + !of_property_read_u32_index(pdev->dev.of_node, "claim-clocks", + +From d4fc13bbc1a9d270c2f5a601d96f39cfc5e8f89a Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 7 Mar 2017 19:48:23 +0000 +Subject: [PATCH 157/190] config: Add CONFIG_CRYPTO_LZ4 + +Enabling this options allows LZ4 memory compression. + +Fixes: https://github.com/raspberrypi/linux/issues/1875 + +Signed-off-by: Phil Elwell +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index 0ee1ff698a5571f80da89a1067025b32fe546136..b5260a6701e48fdfcaeae9aad7dac62b4e160986 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -1303,6 +1303,7 @@ 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_ARM_CRYPTO=y +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index a9c46f902eb32b364423d8bef07b6b37f798c617..e5996d77b02303c4b43e62a810e0e3e660c1e99e 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -1311,6 +1311,7 @@ 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_ARM_CRYPTO=y + +From 04fba23a3e1c5f3bfeecdd32a2c09ec47548c3b7 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Sun, 5 Mar 2017 11:46:41 +0000 +Subject: [PATCH 158/190] config: Add RTL8XXXU wifi module + +--- + arch/arm/configs/bcm2709_defconfig | 1 + + arch/arm/configs/bcmrpi_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index b5260a6701e48fdfcaeae9aad7dac62b4e160986..6143dfd58993aa0e5adb4808fea6987058979971 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -540,6 +540,7 @@ 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 +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index e5996d77b02303c4b43e62a810e0e3e660c1e99e..a691ce8b7fb6017fcc7990cf08e8ff4a39302fba 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -536,6 +536,7 @@ 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 + +From a259543813fa4e92c64d8f1bb3f3289e88ec4ad7 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Fri, 10 Mar 2017 14:43:15 +0000 +Subject: [PATCH 159/190] bcm2835-v4l2: Fix buffer overflow problem + +https://github.com/raspberrypi/linux/issues/1447 +port_parameter_get() failed to account for the header +(u32 id and u32 size) in the size before memcpying +the response into the response buffer, so overrunning +the provided buffer by 8 bytes. + +Account for those bytes, and also a belt-and-braces +check to ensure we never copy more than *value_size +bytes into value. + +Signed-off-by: Dave Stevenson +--- + drivers/media/platform/bcm2835/mmal-vchiq.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/platform/bcm2835/mmal-vchiq.c b/drivers/media/platform/bcm2835/mmal-vchiq.c +index 781322542d5a8295f3d7d5a3eaaf0cac29930c30..e4b243b33f58913f3d2952c97d2a2e3fbbbd0ae8 100644 +--- a/drivers/media/platform/bcm2835/mmal-vchiq.c ++++ b/drivers/media/platform/bcm2835/mmal-vchiq.c +@@ -1315,7 +1315,12 @@ static int port_parameter_get(struct vchiq_mmal_instance *instance, + } + + ret = -rmsg->u.port_parameter_get_reply.status; +- if (ret) { ++ /* 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 + */ + +From 8da66863fce1f5d19da99ecf124f15f8b5d5a36d Mon Sep 17 00:00:00 2001 +From: Matt Flax +Date: Wed, 8 Mar 2017 20:04:13 +1100 +Subject: [PATCH 160/190] Add support for the AudioInjector.net Octo sound card + +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 6 + + .../dts/overlays/audioinjector-addons-overlay.dts | 50 ++++ + arch/arm/configs/bcm2709_defconfig | 2 + + arch/arm/configs/bcmrpi_defconfig | 2 + + sound/soc/bcm/Kconfig | 7 + + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/audioinjector-octo-soundcard.c | 286 +++++++++++++++++++++ + 8 files changed, 356 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts + create mode 100644 sound/soc/bcm/audioinjector-octo-soundcard.c + +diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile +index c890e5ddb0e2eec982597a851023b539d318d6ce..0f7340799fb465ba1fb5aaa1e970cbf6295d75c4 100644 +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -9,6 +9,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + akkordion-iqdacplus.dtbo \ + allo-piano-dac-pcm512x-audio.dtbo \ + at86rf233.dtbo \ ++ audioinjector-addons.dtbo \ + audioinjector-wm8731-audio.dtbo \ + audremap.dtbo \ + bmp085_i2c-sensor.dtbo \ +diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README +index 970c9c9b5c74467a3014a77039fa765d8f8c4e6f..c1883bba938290f03826026651c764cfd4ac278b 100644 +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -295,6 +295,12 @@ Params: interrupt GPIO used for INT (default 23) + arrays (0=+0pF, 15=+4.5pF, default 15) + + ++Name: audioinjector-addons ++Info: Configures the audioinjector.net audio add on soundcards ++Load: dtoverlay=audioinjector-addons ++Params: ++ ++ + Name: audioinjector-wm8731-audio + Info: Configures the audioinjector.net audio add on soundcard + Load: dtoverlay=audioinjector-wm8731-audio +diff --git a/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts b/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts +new file mode 100644 +index 0000000000000000000000000000000000000000..dbf2f3cacc2e6bf5b7116fbadd97f2781580a79c +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/audioinjector-addons-overlay.dts +@@ -0,0 +1,50 @@ ++// Definitions for audioinjector.net audio add on soundcard ++/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"; ++ ++ cs42448: cs42448@48 { ++ #sound-dai-cells = <0>; ++ compatible = "cirrus,cs42448"; ++ reg = <0x48>; ++ clocks = <&cs42448_mclk>; ++ clock-names = "mclk"; ++ status = "okay"; ++ }; ++ ++ cs42448_mclk: codec-mclk { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <49152000>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "ai,audioinjector-octo-soundcard"; ++ mult-gpios = <&gpio 27 0>, <&gpio 22 0>, <&gpio 23 0>, ++ <&gpio 24 0>; ++ i2s-controller = <&i2s>; ++ codec = <&cs42448>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index 6143dfd58993aa0e5adb4808fea6987058979971..97375c26f2d70d0c4f3956622f839dcf04463e31 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -883,6 +883,7 @@ CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m + CONFIG_SND_BCM2708_SOC_RASPIDAC3=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 +@@ -892,6 +893,7 @@ CONFIG_SND_PISOUND=m + CONFIG_SND_SOC_ADAU1701=m + CONFIG_SND_SOC_ADAU7002=m + CONFIG_SND_SOC_AK4554=m ++CONFIG_SND_SOC_CS42XX8_I2C=m + CONFIG_SND_SOC_WM8804_I2C=m + CONFIG_SND_SIMPLE_CARD=m + CONFIG_SOUND_PRIME=m +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index a691ce8b7fb6017fcc7990cf08e8ff4a39302fba..0e2c3679d9614d331db39cd25ae9095136d3190a 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -876,6 +876,7 @@ CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m + CONFIG_SND_BCM2708_SOC_RASPIDAC3=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 +@@ -885,6 +886,7 @@ CONFIG_SND_PISOUND=m + CONFIG_SND_SOC_ADAU1701=m + CONFIG_SND_SOC_ADAU7002=m + CONFIG_SND_SOC_AK4554=m ++CONFIG_SND_SOC_CS42XX8_I2C=m + CONFIG_SND_SOC_WM8804_I2C=m + CONFIG_SND_SIMPLE_CARD=m + CONFIG_SOUND_PRIME=m +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index 7473efd6f400a1a1618aac830753fce39d203b89..706c500b5303ac3a0fd8687d23dc9f06c7d08388 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -119,6 +119,13 @@ config SND_AUDIOINJECTOR_PI_SOUNDCARD + help + Say Y or M if you want to add support for audioinjector.net Pi Hat + ++config SND_AUDIOINJECTOR_OCTO_SOUNDCARD ++ tristate "Support for audioinjector.net Octo channel (Hat) soundcard" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_CS42XX8_I2C ++ help ++ Say Y or M if you want to add support for audioinjector.net octo add on ++ + config SND_DIGIDAC1_SOUNDCARD + tristate "Support for Red Rocks Audio DigiDAC1" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index 8d2d2073dc2cede9fbd9eb8b49083650ba0a8172..d448aa517bf994fc0a41580c91b5d87deec9e1b0 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -23,6 +23,7 @@ snd-soc-iqaudio-dac-objs := iqaudio-dac.o + snd-soc-iqaudio-digi-objs := iqaudio_digi.o + snd-soc-raspidac3-objs := raspidac3.o + snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o ++snd-soc-audioinjector-octo-soundcard-objs := audioinjector-octo-soundcard.o + snd-soc-digidac1-soundcard-objs := digidac1-soundcard.o + snd-soc-dionaudio-loco-objs := dionaudio_loco.o + snd-soc-dionaudio-loco-v2-objs := dionaudio_loco-v2.o +@@ -44,6 +45,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o + obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI) += snd-soc-iqaudio-digi.o + obj-$(CONFIG_SND_BCM2708_SOC_RASPIDAC3) += snd-soc-raspidac3.o + obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o ++obj-$(CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD) += snd-soc-audioinjector-octo-soundcard.o + obj-$(CONFIG_SND_DIGIDAC1_SOUNDCARD) += snd-soc-digidac1-soundcard.o + obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO) += snd-soc-dionaudio-loco.o + obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2) += snd-soc-dionaudio-loco-v2.o +diff --git a/sound/soc/bcm/audioinjector-octo-soundcard.c b/sound/soc/bcm/audioinjector-octo-soundcard.c +new file mode 100644 +index 0000000000000000000000000000000000000000..9effea725798640887755dfa688da45338718afc +--- /dev/null ++++ b/sound/soc/bcm/audioinjector-octo-soundcard.c +@@ -0,0 +1,286 @@ ++/* ++ * ASoC Driver for AudioInjector Pi octo channel soundcard (hat) ++ * ++ * Created on: 27-October-2016 ++ * Author: flatmax@flatmax.org ++ * based on audioinjector-pi-soundcard.c ++ * ++ * Copyright (C) 2016 Flatmax Pty. Ltd. ++ * ++ * 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 ++ ++static struct gpio_descs *mult_gpios; ++static unsigned int audioinjector_octo_rate; ++ ++static int audioinjector_octo_dai_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ return snd_soc_dai_set_bclk_ratio(rtd->cpu_dai, 64); ++} ++ ++static int audioinjector_octo_startup(struct snd_pcm_substream *substream) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ rtd->cpu_dai->driver->playback.channels_min = 8; ++ rtd->cpu_dai->driver->playback.channels_max = 8; ++ rtd->cpu_dai->driver->capture.channels_min = 8; ++ rtd->cpu_dai->driver->capture.channels_max = 8; ++ rtd->codec_dai->driver->capture.channels_max = 8; ++ return 0; ++} ++ ++static void audioinjector_octo_shutdown(struct snd_pcm_substream *substream) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ rtd->cpu_dai->driver->playback.channels_min = 2; ++ rtd->cpu_dai->driver->playback.channels_max = 2; ++ rtd->cpu_dai->driver->capture.channels_min = 2; ++ rtd->cpu_dai->driver->capture.channels_max = 2; ++ rtd->codec_dai->driver->capture.channels_max = 6; ++} ++ ++static int audioinjector_octo_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ ++ // set codec DAI configuration ++ int ret = snd_soc_dai_set_fmt(rtd->codec_dai, ++ SND_SOC_DAIFMT_CBS_CFS|SND_SOC_DAIFMT_DSP_A| ++ SND_SOC_DAIFMT_NB_NF); ++ if (ret < 0) ++ return ret; ++ ++ // set cpu DAI configuration ++ ret = snd_soc_dai_set_fmt(rtd->cpu_dai, ++ SND_SOC_DAIFMT_CBM_CFM|SND_SOC_DAIFMT_I2S| ++ SND_SOC_DAIFMT_NB_NF); ++ if (ret < 0) ++ return ret; ++ ++ audioinjector_octo_rate = params_rate(params); ++ ++ return 0; ++} ++ ++static int audioinjector_octo_trigger(struct snd_pcm_substream *substream, ++ int cmd){ ++ int mult[4]; ++ mult[0] = 0; ++ mult[1] = 0; ++ mult[2] = 0; ++ mult[3] = 0; ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ switch (audioinjector_octo_rate) { ++ case 192000: ++ mult[3] = 1; ++ case 176640: ++ mult[0] = 1; ++ mult[1] = 1; ++ mult[2] = 1; ++ break; ++ case 96000: ++ mult[3] = 1; ++ case 88200: ++ mult[1] = 1; ++ mult[2] = 1; ++ break; ++ case 64000: ++ mult[3] = 1; ++ case 58800: ++ mult[0] = 1; ++ mult[2] = 1; ++ break; ++ case 48000: ++ mult[3] = 1; ++ case 44100: ++ mult[2] = 1; ++ break; ++ case 32000: ++ mult[3] = 1; ++ case 29400: ++ mult[0] = 1; ++ mult[1] = 1; ++ break; ++ case 24000: ++ mult[3] = 1; ++ case 22050: ++ mult[1] = 1; ++ break; ++ case 16000: ++ mult[3] = 1; ++ case 14700: ++ mult[0] = 1; ++ break; ++ case 8000: ++ mult[3] = 1; ++ break; ++ default: ++ return -EINVAL; ++ } ++ break; ++ case SNDRV_PCM_TRIGGER_STOP: ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ break; ++ default: ++ return -EINVAL; ++ } ++ gpiod_set_array_value_cansleep(mult_gpios->ndescs, mult_gpios->desc, ++ mult); ++ ++ return 0; ++} ++ ++static struct snd_soc_ops audioinjector_octo_ops = { ++ .startup = audioinjector_octo_startup, ++ .shutdown = audioinjector_octo_shutdown, ++ .hw_params = audioinjector_octo_hw_params, ++ .trigger = audioinjector_octo_trigger, ++}; ++ ++static struct snd_soc_dai_link audioinjector_octo_dai[] = { ++ { ++ .name = "AudioInjector Octo", ++ .stream_name = "AudioInject-HIFI", ++ .codec_dai_name = "cs42448", ++ .ops = &audioinjector_octo_ops, ++ .init = audioinjector_octo_dai_init, ++ }, ++}; ++ ++static const struct snd_soc_dapm_widget audioinjector_octo_widgets[] = { ++ SND_SOC_DAPM_OUTPUT("OUTPUTS0"), ++ SND_SOC_DAPM_OUTPUT("OUTPUTS1"), ++ SND_SOC_DAPM_OUTPUT("OUTPUTS2"), ++ SND_SOC_DAPM_OUTPUT("OUTPUTS3"), ++ SND_SOC_DAPM_INPUT("INPUTS0"), ++ SND_SOC_DAPM_INPUT("INPUTS1"), ++ SND_SOC_DAPM_INPUT("INPUTS2"), ++}; ++ ++static const struct snd_soc_dapm_route audioinjector_octo_route[] = { ++ /* Balanced outputs */ ++ {"OUTPUTS0", NULL, "AOUT1L"}, ++ {"OUTPUTS0", NULL, "AOUT1R"}, ++ {"OUTPUTS1", NULL, "AOUT2L"}, ++ {"OUTPUTS1", NULL, "AOUT2R"}, ++ {"OUTPUTS2", NULL, "AOUT3L"}, ++ {"OUTPUTS2", NULL, "AOUT3R"}, ++ {"OUTPUTS3", NULL, "AOUT4L"}, ++ {"OUTPUTS3", NULL, "AOUT4R"}, ++ ++ /* Balanced inputs */ ++ {"AIN1L", NULL, "INPUTS0"}, ++ {"AIN1R", NULL, "INPUTS0"}, ++ {"AIN2L", NULL, "INPUTS1"}, ++ {"AIN2R", NULL, "INPUTS1"}, ++ {"AIN3L", NULL, "INPUTS2"}, ++ {"AIN3R", NULL, "INPUTS2"}, ++}; ++ ++static struct snd_soc_card snd_soc_audioinjector_octo = { ++ .name = "audioinjector-octo-soundcard", ++ .dai_link = audioinjector_octo_dai, ++ .num_links = ARRAY_SIZE(audioinjector_octo_dai), ++ ++ .dapm_widgets = audioinjector_octo_widgets, ++ .num_dapm_widgets = ARRAY_SIZE(audioinjector_octo_widgets), ++ .dapm_routes = audioinjector_octo_route, ++ .num_dapm_routes = ARRAY_SIZE(audioinjector_octo_route), ++}; ++ ++static int audioinjector_octo_probe(struct platform_device *pdev) ++{ ++ struct snd_soc_card *card = &snd_soc_audioinjector_octo; ++ int ret; ++ ++ card->dev = &pdev->dev; ++ ++ if (pdev->dev.of_node) { ++ struct snd_soc_dai_link *dai = &audioinjector_octo_dai[0]; ++ struct device_node *i2s_node = ++ of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ struct device_node *codec_node = ++ of_parse_phandle(pdev->dev.of_node, ++ "codec", 0); ++ ++ mult_gpios = devm_gpiod_get_array_optional(&pdev->dev, "mult", ++ GPIOD_OUT_LOW); ++ if (IS_ERR(mult_gpios)) ++ return PTR_ERR(mult_gpios); ++ ++ if (i2s_node && codec_node) { ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = i2s_node; ++ dai->platform_name = NULL; ++ dai->platform_of_node = i2s_node; ++ dai->codec_name = NULL; ++ dai->codec_of_node = codec_node; ++ } else ++ if (!dai->cpu_of_node) { ++ dev_err(&pdev->dev, ++ "i2s-controller missing or invalid in DT\n"); ++ return -EINVAL; ++ } else { ++ dev_err(&pdev->dev, ++ "Property 'codec' missing or invalid\n"); ++ return -EINVAL; ++ } ++ } ++ ++ ret = snd_soc_register_card(card); ++ if (ret != 0) ++ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); ++ return ret; ++} ++ ++static int audioinjector_octo_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 audioinjector_octo_of_match[] = { ++ { .compatible = "ai,audioinjector-octo-soundcard", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, audioinjector_octo_of_match); ++ ++static struct platform_driver audioinjector_octo_driver = { ++ .driver = { ++ .name = "audioinjector-audio", ++ .owner = THIS_MODULE, ++ .of_match_table = audioinjector_octo_of_match, ++ }, ++ .probe = audioinjector_octo_probe, ++ .remove = audioinjector_octo_remove, ++}; ++ ++module_platform_driver(audioinjector_octo_driver); ++MODULE_AUTHOR("Matt Flax "); ++MODULE_DESCRIPTION("AudioInjector.net octo Soundcard"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:audioinjector-octo-soundcard"); + +From 89823fe6327ef9c00f48721a779c785fb0c1cf1f Mon Sep 17 00:00:00 2001 +From: Matt Flax +Date: Wed, 8 Mar 2017 21:13:24 +1100 +Subject: [PATCH 161/190] ASoC: bcm2835_i2s.c: relax the ch2 register setting + for 8 channels + +This patch allows ch2 registers to be set for 8 channels of audio. +--- + sound/soc/bcm/bcm2835-i2s.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index 6ba20498202ed36906b52096893a88867a79269f..c8dd065aea8414b47aa2ea4fc04168b5e29002ad 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -239,6 +239,7 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, + unsigned int ch1pos, ch2pos, mode, format; + uint32_t csreg; + ++ + /* + * If a stream is already enabled, + * the registers are already set properly. +@@ -312,6 +313,7 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, + + switch (params_channels(params)) { + case 2: ++ case 8: + format = BCM2835_I2S_CH1(format) | BCM2835_I2S_CH2(format); + format |= BCM2835_I2S_CH1(BCM2835_I2S_CHPOS(ch1pos)); + format |= BCM2835_I2S_CH2(BCM2835_I2S_CHPOS(ch2pos)); + +From 6724b1f8f1c938422f898b8a333f203ad54ad4bb Mon Sep 17 00:00:00 2001 +From: Khem Raj +Date: Fri, 10 Feb 2017 17:57:08 -0800 +Subject: [PATCH 162/190] build/arm64: Add rules for .dtbo files for dts + overlays + +We now create overlays as .dtbo files. + +Signed-off-by: Khem Raj +--- + arch/arm64/Makefile | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile +index b9a4a934ca057623e0ea436fd9b2c7c0f675fced..54e3c38d6fd877827541cdc798de035cf439b17f 100644 +--- a/arch/arm64/Makefile ++++ b/arch/arm64/Makefile +@@ -119,6 +119,9 @@ zinstall install: + %.dtb: scripts + $(Q)$(MAKE) $(build)=$(boot)/dts $(boot)/dts/$@ + ++%.dtbo: | scripts ++ $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@ ++ + PHONY += dtbs dtbs_install + + dtbs: prepare scripts + +From 0e3412d4f406a8870c4e2c122127793e6abd41b1 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Tue, 24 Feb 2015 13:40:50 +0000 +Subject: [PATCH 163/190] pinctrl-bcm2835: Fix interrupt handling for GPIOs + 28-31 and 46-53 + +Contrary to the documentation, the BCM2835 GPIO controller actually has +four interrupt lines - one each for the three IRQ groups and one common. Rather +confusingly, the GPIO interrupt groups don't correspond directly with the GPIO +control banks. Instead, GPIOs 0-27 generate IRQ GPIO0, 28-45 GPIO1 and +46-53 GPIO2. + +Awkwardly, the GPIOS for IRQ GPIO1 straddle two 32-entry GPIO banks, so it is +cleaner to split out a function to process the interrupts for a single GPIO +bank. + +This bug has only just been observed because GPIOs above 27 can only be +accessed on an old Raspberry Pi with the optional P5 header fitted, where +the pins are often used for I2S instead. +--- + drivers/pinctrl/bcm/pinctrl-bcm2835.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +index 6351fe7f8e314ac5ebb102dd20847b383fd5b857..28745af5aadf3cb91fa7ff39118385c393e2d1d4 100644 +--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c ++++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +@@ -1109,6 +1109,7 @@ static struct platform_driver bcm2835_pinctrl_driver = { + .remove = bcm2835_pinctrl_remove, + .driver = { + .name = MODULE_NAME, ++ .owner = THIS_MODULE, + .of_match_table = bcm2835_pinctrl_match, + }, + }; + +From 2296a95a44a8709f354ebd6213f927777d892a46 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 9 May 2016 17:28:18 -0700 +Subject: [PATCH 164/190] clk: bcm2835: Mark GPIO clocks enabled at boot as + critical. + +These divide off of PLLD_PER and are used for the ethernet and wifi +PHYs source PLLs. Neither of them is currently represented by a phy +device that would grab the clock for us. + +This keeps other drivers from killing the networking PHYs when they +disable their own clocks and trigger PLLD_PER's refcount going to 0. + +v2: Skip marking as critical if they aren't on at boot. + +Signed-off-by: Eric Anholt +--- + drivers/clk/bcm/clk-bcm2835.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index 41dccc4ebe6f367054822aed11cb0cd4d985c21a..7ec0e71cbcfbcd6c86e2f6c8080e1d622ca5540a 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -1357,6 +1357,15 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman, + init.flags = data->flags | CLK_IGNORE_UNUSED; + + /* ++ * Some GPIO clocks for ethernet/wifi PLLs are marked as ++ * critical (since some platforms use them), but if the ++ * firmware didn't have them turned on then they clearly ++ * aren't actually critical. ++ */ ++ if ((cprman_read(cprman, data->ctl_reg) & CM_ENABLE) == 0) ++ init.flags &= ~CLK_IS_CRITICAL; ++ ++ /* + * Pass the CLK_SET_RATE_PARENT flag if we are allowed to propagate + * rate changes on at least of the parents. + */ + +From 35c10e8317071661af8a72f0ffb41a12956bd366 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 7 Mar 2016 15:05:11 +0000 +Subject: [PATCH 165/190] vchiq_arm: Tweak the logging output + +Signed-off-by: Phil Elwell +--- + .../vc04_services/interface/vchiq_arm/vchiq_core.c | 31 +++++++++------------- + 1 file changed, 13 insertions(+), 18 deletions(-) + +diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c +index d6757ee263fb61a689c0d38c0dbb65c57a8e39bb..7fd63cf6800d7ec35fbcb215a283630c11120c7f 100644 +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c +@@ -873,16 +873,14 @@ queue_message(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, + error_count); + return VCHIQ_ERROR; + } +- if (i == 0) { +- if (SRVTRACE_ENABLED(service, +- VCHIQ_LOG_INFO)) +- vchiq_log_dump_mem("Sent", 0, +- header->data + pos, +- min(64u, +- elements[0].size)); +- } + } + ++ if (SRVTRACE_ENABLED(service, ++ VCHIQ_LOG_INFO)) ++ vchiq_log_dump_mem("Sent", 0, ++ header->data, ++ min(16, pos)); ++ + spin_lock("a_spinlock); + service_quota->message_use_count++; + +@@ -1019,16 +1017,13 @@ queue_message_sync(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, + error_count); + return VCHIQ_ERROR; + } +- if (i == 0) { +- if (vchiq_sync_log_level >= +- VCHIQ_LOG_TRACE) +- vchiq_log_dump_mem("Sent Sync", +- 0, header->data + pos, +- min(64u, +- elements[0].size)); +- } + } + ++ if (vchiq_sync_log_level >= VCHIQ_LOG_TRACE) ++ vchiq_log_dump_mem("Sent Sync", ++ 0, header->data, ++ min(16, pos)); ++ + VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count); + VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size); + } else { +@@ -1691,7 +1686,7 @@ parse_rx_slots(VCHIQ_STATE_T *state) + remoteport, localport, size); + if (size > 0) + vchiq_log_dump_mem("Rcvd", 0, header->data, +- min(64, size)); ++ min(16, size)); + } + + if (((unsigned long)header & VCHIQ_SLOT_MASK) + +@@ -2148,7 +2143,7 @@ sync_func(void *v) + remoteport, localport, size); + if (size > 0) + vchiq_log_dump_mem("Rcvd", 0, header->data, +- min(64, size)); ++ min(16, size)); + } + + switch (type) { + +From f0b20f2f429ec522875e5eb561f266e305a67724 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 18 Jan 2017 07:31:55 +1100 +Subject: [PATCH 166/190] clk: bcm2835: Don't rate change PLLs on behalf of DSI + PLL dividers. + +Our core PLLs are intended to be configured once and left alone. With +the SET_RATE_PARENT, asking to set the PLLD_DSI1 clock rate would +change PLLD just to get closer to the requested DSI clock, thus +changing PLLD_PER, the UART and ethernet PHY clock rates downstream of +it, and breaking ethernet. + +We *do* want PLLH to change so that PLLH_AUX can be exactly the value +we want, though. Thus, we need to have a per-divider policy of +whether to pass rate changes up. + +Signed-off-by: Eric Anholt +Signed-off-by: Stephen Boyd +(cherry picked from commit 55486091bd1e1c5ed28c43c0d6b3392468a9adb5) +--- + drivers/clk/bcm/clk-bcm2835.c | 42 ++++++++++++++++++++++++++++-------------- + 1 file changed, 28 insertions(+), 14 deletions(-) + +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index 7ec0e71cbcfbcd6c86e2f6c8080e1d622ca5540a..3acf61ddeda8c27e6da0fd7e2beb46341679eb66 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -432,6 +432,7 @@ struct bcm2835_pll_divider_data { + u32 load_mask; + u32 hold_mask; + u32 fixed_divider; ++ u32 flags; + }; + + struct bcm2835_clock_data { +@@ -1287,7 +1288,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman, + init.num_parents = 1; + init.name = divider_name; + init.ops = &bcm2835_pll_divider_clk_ops; +- init.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED; ++ init.flags = data->flags | CLK_IGNORE_UNUSED; + + divider = devm_kzalloc(cprman->dev, sizeof(*divider), GFP_KERNEL); + if (!divider) +@@ -1517,7 +1518,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLA_CORE, + .load_mask = CM_PLLA_LOADCORE, + .hold_mask = CM_PLLA_HOLDCORE, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + [BCM2835_PLLA_PER] = REGISTER_PLL_DIV( + .name = "plla_per", + .source_pll = "plla", +@@ -1525,7 +1527,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLA_PER, + .load_mask = CM_PLLA_LOADPER, + .hold_mask = CM_PLLA_HOLDPER, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + [BCM2835_PLLA_DSI0] = REGISTER_PLL_DIV( + .name = "plla_dsi0", + .source_pll = "plla", +@@ -1541,7 +1544,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLA_CCP2, + .load_mask = CM_PLLA_LOADCCP2, + .hold_mask = CM_PLLA_HOLDCCP2, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + + /* PLLB is used for the ARM's clock. */ + [BCM2835_PLLB] = REGISTER_PLL( +@@ -1565,7 +1569,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLB_ARM, + .load_mask = CM_PLLB_LOADARM, + .hold_mask = CM_PLLB_HOLDARM, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + + /* + * PLLC is the core PLL, used to drive the core VPU clock. +@@ -1594,7 +1599,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLC_CORE0, + .load_mask = CM_PLLC_LOADCORE0, + .hold_mask = CM_PLLC_HOLDCORE0, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + [BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV( + .name = "pllc_core1", + .source_pll = "pllc", +@@ -1602,7 +1608,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLC_CORE1, + .load_mask = CM_PLLC_LOADCORE1, + .hold_mask = CM_PLLC_HOLDCORE1, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + [BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV( + .name = "pllc_core2", + .source_pll = "pllc", +@@ -1610,7 +1617,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLC_CORE2, + .load_mask = CM_PLLC_LOADCORE2, + .hold_mask = CM_PLLC_HOLDCORE2, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + [BCM2835_PLLC_PER] = REGISTER_PLL_DIV( + .name = "pllc_per", + .source_pll = "pllc", +@@ -1618,7 +1626,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLC_PER, + .load_mask = CM_PLLC_LOADPER, + .hold_mask = CM_PLLC_HOLDPER, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + + /* + * PLLD is the display PLL, used to drive DSI display panels. +@@ -1647,7 +1656,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLD_CORE, + .load_mask = CM_PLLD_LOADCORE, + .hold_mask = CM_PLLD_HOLDCORE, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + [BCM2835_PLLD_PER] = REGISTER_PLL_DIV( + .name = "plld_per", + .source_pll = "plld", +@@ -1655,7 +1665,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLD_PER, + .load_mask = CM_PLLD_LOADPER, + .hold_mask = CM_PLLD_HOLDPER, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + [BCM2835_PLLD_DSI0] = REGISTER_PLL_DIV( + .name = "plld_dsi0", + .source_pll = "plld", +@@ -1700,7 +1711,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLH_RCAL, + .load_mask = CM_PLLH_LOADRCAL, + .hold_mask = 0, +- .fixed_divider = 10), ++ .fixed_divider = 10, ++ .flags = CLK_SET_RATE_PARENT), + [BCM2835_PLLH_AUX] = REGISTER_PLL_DIV( + .name = "pllh_aux", + .source_pll = "pllh", +@@ -1708,7 +1720,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLH_AUX, + .load_mask = CM_PLLH_LOADAUX, + .hold_mask = 0, +- .fixed_divider = 1), ++ .fixed_divider = 1, ++ .flags = CLK_SET_RATE_PARENT), + [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV( + .name = "pllh_pix", + .source_pll = "pllh", +@@ -1716,7 +1729,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .a2w_reg = A2W_PLLH_PIX, + .load_mask = CM_PLLH_LOADPIX, + .hold_mask = 0, +- .fixed_divider = 10), ++ .fixed_divider = 10, ++ .flags = CLK_SET_RATE_PARENT), + + /* the clocks */ + + +From 5577a9c36ac8217d1b9f477f68c02f751d3ae0e5 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 18 Jan 2017 07:31:56 +1100 +Subject: [PATCH 167/190] clk: bcm2835: Register the DSI0/DSI1 pixel clocks. + +The DSI pixel clocks are muxed from clocks generated in the analog phy +by the DSI driver. In order to set them as parents, we need to do the +same name lookup dance on them as we do for our root oscillator. + +Signed-off-by: Eric Anholt +Signed-off-by: Stephen Boyd +(cherry picked from commit 8a39e9fa578229fd4604266c6ebb1a3a77d7994c) +--- + .../bindings/clock/brcm,bcm2835-cprman.txt | 15 ++- + drivers/clk/bcm/clk-bcm2835.c | 121 +++++++++++++++++++-- + include/dt-bindings/clock/bcm2835.h | 2 + + 3 files changed, 125 insertions(+), 13 deletions(-) + +diff --git a/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt b/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt +index e56a1df3a9d3ca7fefbc5058072ee392c49b4cfc..dd906db34b328a581e4f4d99d11284544ff817f4 100644 +--- a/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt ++++ b/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt +@@ -16,7 +16,20 @@ Required properties: + - #clock-cells: Should be <1>. The permitted clock-specifier values can be + found in include/dt-bindings/clock/bcm2835.h + - reg: Specifies base physical address and size of the registers +-- clocks: The external oscillator clock phandle ++- clocks: phandles to the parent clocks used as input to the module, in ++ the following order: ++ ++ - External oscillator ++ - DSI0 byte clock ++ - DSI0 DDR2 clock ++ - DSI0 DDR clock ++ - DSI1 byte clock ++ - DSI1 DDR2 clock ++ - DSI1 DDR clock ++ ++ Only external oscillator is required. The DSI clocks may ++ not be present, in which case their children will be ++ unusable. + + Example: + +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index 3acf61ddeda8c27e6da0fd7e2beb46341679eb66..428e75c8b970897d881b570228eb85e8aef28999 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -300,12 +300,33 @@ + + #define VCMSG_ID_CORE_CLOCK 4 + ++/* ++ * Names of clocks used within the driver that need to be replaced ++ * with an external parent's name. This array is in the order that ++ * the clocks node in the DT references external clocks. ++ */ ++static const char *const cprman_parent_names[] = { ++ "xosc", ++ "dsi0_byte", ++ "dsi0_ddr2", ++ "dsi0_ddr", ++ "dsi1_byte", ++ "dsi1_ddr2", ++ "dsi1_ddr", ++}; ++ + struct bcm2835_cprman { + struct device *dev; + void __iomem *regs; + struct rpi_firmware *fw; + spinlock_t regs_lock; /* spinlock for all clocks */ +- const char *osc_name; ++ ++ /* ++ * Real names of cprman clock parents looked up through ++ * of_clk_get_parent_name(), which will be used in the ++ * parent_names[] arrays for clock registration. ++ */ ++ const char *real_parent_names[ARRAY_SIZE(cprman_parent_names)]; + + /* Must be last */ + struct clk_hw_onecell_data onecell; +@@ -913,6 +934,9 @@ static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock, + const struct bcm2835_clock_data *data = clock->data; + u64 temp; + ++ if (data->int_bits == 0 && data->frac_bits == 0) ++ return parent_rate; ++ + /* + * The divisor is a 12.12 fixed point field, but only some of + * the bits are populated in any given clock. +@@ -936,7 +960,12 @@ static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw, + struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); + struct bcm2835_cprman *cprman = clock->cprman; + const struct bcm2835_clock_data *data = clock->data; +- u32 div = cprman_read(cprman, data->div_reg); ++ u32 div; ++ ++ if (data->int_bits == 0 && data->frac_bits == 0) ++ return parent_rate; ++ ++ div = cprman_read(cprman, data->div_reg); + + return bcm2835_clock_rate_from_divisor(clock, parent_rate, div); + } +@@ -1241,7 +1270,7 @@ static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman, + memset(&init, 0, sizeof(init)); + + /* All of the PLLs derive from the external oscillator. */ +- init.parent_names = &cprman->osc_name; ++ init.parent_names = &cprman->real_parent_names[0]; + init.num_parents = 1; + init.name = data->name; + init.ops = &bcm2835_pll_clk_ops; +@@ -1337,18 +1366,22 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman, + struct bcm2835_clock *clock; + struct clk_init_data init; + const char *parents[1 << CM_SRC_BITS]; +- size_t i; ++ size_t i, j; + int ret; + + /* +- * Replace our "xosc" references with the oscillator's +- * actual name. ++ * Replace our strings referencing parent clocks with the ++ * actual clock-output-name of the parent. + */ + for (i = 0; i < data->num_mux_parents; i++) { +- if (strcmp(data->parents[i], "xosc") == 0) +- parents[i] = cprman->osc_name; +- else +- parents[i] = data->parents[i]; ++ parents[i] = data->parents[i]; ++ ++ for (j = 0; j < ARRAY_SIZE(cprman_parent_names); j++) { ++ if (strcmp(parents[i], cprman_parent_names[j]) == 0) { ++ parents[i] = cprman->real_parent_names[j]; ++ break; ++ } ++ } + } + + memset(&init, 0, sizeof(init)); +@@ -1484,6 +1517,47 @@ static const char *const bcm2835_clock_vpu_parents[] = { + __VA_ARGS__) + + /* ++ * DSI parent clocks. The DSI byte/DDR/DDR2 clocks come from the DSI ++ * analog PHY. The _inv variants are generated internally to cprman, ++ * but we don't use them so they aren't hooked up. ++ */ ++static const char *const bcm2835_clock_dsi0_parents[] = { ++ "gnd", ++ "xosc", ++ "testdebug0", ++ "testdebug1", ++ "dsi0_ddr", ++ "dsi0_ddr_inv", ++ "dsi0_ddr2", ++ "dsi0_ddr2_inv", ++ "dsi0_byte", ++ "dsi0_byte_inv", ++}; ++ ++static const char *const bcm2835_clock_dsi1_parents[] = { ++ "gnd", ++ "xosc", ++ "testdebug0", ++ "testdebug1", ++ "dsi1_ddr", ++ "dsi1_ddr_inv", ++ "dsi1_ddr2", ++ "dsi1_ddr2_inv", ++ "dsi1_byte", ++ "dsi1_byte_inv", ++}; ++ ++#define REGISTER_DSI0_CLK(...) REGISTER_CLK( \ ++ .num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi0_parents), \ ++ .parents = bcm2835_clock_dsi0_parents, \ ++ __VA_ARGS__) ++ ++#define REGISTER_DSI1_CLK(...) REGISTER_CLK( \ ++ .num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi1_parents), \ ++ .parents = bcm2835_clock_dsi1_parents, \ ++ __VA_ARGS__) ++ ++/* + * the real definition of all the pll, pll_dividers and clocks + * these make use of the above REGISTER_* macros + */ +@@ -1946,6 +2020,18 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .div_reg = CM_DSI1EDIV, + .int_bits = 4, + .frac_bits = 8), ++ [BCM2835_CLOCK_DSI0P] = REGISTER_DSI0_CLK( ++ .name = "dsi0p", ++ .ctl_reg = CM_DSI0PCTL, ++ .div_reg = CM_DSI0PDIV, ++ .int_bits = 0, ++ .frac_bits = 0), ++ [BCM2835_CLOCK_DSI1P] = REGISTER_DSI1_CLK( ++ .name = "dsi1p", ++ .ctl_reg = CM_DSI1PCTL, ++ .div_reg = CM_DSI1PDIV, ++ .int_bits = 0, ++ .frac_bits = 0), + + /* the gates */ + +@@ -2036,8 +2122,19 @@ static int bcm2835_clk_probe(struct platform_device *pdev) + i++) + bcm2835_clk_claimed[clk_id]= true; + +- cprman->osc_name = of_clk_get_parent_name(dev->of_node, 0); +- if (!cprman->osc_name) ++ memcpy(cprman->real_parent_names, cprman_parent_names, ++ sizeof(cprman_parent_names)); ++ of_clk_parent_fill(dev->of_node, cprman->real_parent_names, ++ ARRAY_SIZE(cprman_parent_names)); ++ ++ /* ++ * Make sure the external oscillator has been registered. ++ * ++ * The other (DSI) clocks are not present on older device ++ * trees, which we still need to support for backwards ++ * compatibility. ++ */ ++ if (!cprman->real_parent_names[0]) + return -ENODEV; + + platform_set_drvdata(pdev, cprman); +diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h +index 360e00cefd35679b49890234b5c369fb52b89e20..a0c812b0fa391d149b4f546db39bdc4bef207960 100644 +--- a/include/dt-bindings/clock/bcm2835.h ++++ b/include/dt-bindings/clock/bcm2835.h +@@ -64,3 +64,5 @@ + #define BCM2835_CLOCK_CAM1 46 + #define BCM2835_CLOCK_DSI0E 47 + #define BCM2835_CLOCK_DSI1E 48 ++#define BCM2835_CLOCK_DSI0P 49 ++#define BCM2835_CLOCK_DSI1P 50 + +From 833c4754e30a0214e8a70b497238f0e0866bad29 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 18 Jan 2017 07:31:57 +1100 +Subject: [PATCH 168/190] clk: bcm2835: Add leaf clock measurement support, + disabled by default + +This proved incredibly useful during debugging of the DSI driver, to +see if our clocks were running at rate we requested. Let's leave it +here for the next person interacting with clocks on the platform (and +so that hopefully we can just hook it up to debugfs some day). + +Signed-off-by: Eric Anholt +Signed-off-by: Stephen Boyd +(cherry picked from commit 3f9195811d8d829556c4cd88d3f9e56a80d5ba60) +--- + drivers/clk/bcm/clk-bcm2835.c | 144 ++++++++++++++++++++++++++++++++++-------- + 1 file changed, 119 insertions(+), 25 deletions(-) + +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index 428e75c8b970897d881b570228eb85e8aef28999..fe3298b54cdfb96bd90fb4f39e13921d2e1d4356 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -99,7 +100,8 @@ + #define CM_SMIDIV 0x0b4 + /* no definition for 0x0b8 and 0x0bc */ + #define CM_TCNTCTL 0x0c0 +-#define CM_TCNTDIV 0x0c4 ++# define CM_TCNT_SRC1_SHIFT 12 ++#define CM_TCNTCNT 0x0c4 + #define CM_TECCTL 0x0c8 + #define CM_TECDIV 0x0cc + #define CM_TD0CTL 0x0d0 +@@ -342,6 +344,61 @@ static inline u32 cprman_read(struct bcm2835_cprman *cprman, u32 reg) + return readl(cprman->regs + reg); + } + ++/* Does a cycle of measuring a clock through the TCNT clock, which may ++ * source from many other clocks in the system. ++ */ ++static unsigned long bcm2835_measure_tcnt_mux(struct bcm2835_cprman *cprman, ++ u32 tcnt_mux) ++{ ++ u32 osccount = 19200; /* 1ms */ ++ u32 count; ++ ktime_t timeout; ++ ++ spin_lock(&cprman->regs_lock); ++ ++ cprman_write(cprman, CM_TCNTCTL, CM_KILL); ++ ++ cprman_write(cprman, CM_TCNTCTL, ++ (tcnt_mux & CM_SRC_MASK) | ++ (tcnt_mux >> CM_SRC_BITS) << CM_TCNT_SRC1_SHIFT); ++ ++ cprman_write(cprman, CM_OSCCOUNT, osccount); ++ ++ /* do a kind delay at the start */ ++ mdelay(1); ++ ++ /* Finish off whatever is left of OSCCOUNT */ ++ timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS); ++ while (cprman_read(cprman, CM_OSCCOUNT)) { ++ if (ktime_after(ktime_get(), timeout)) { ++ dev_err(cprman->dev, "timeout waiting for OSCCOUNT\n"); ++ count = 0; ++ goto out; ++ } ++ cpu_relax(); ++ } ++ ++ /* Wait for BUSY to clear. */ ++ timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS); ++ while (cprman_read(cprman, CM_TCNTCTL) & CM_BUSY) { ++ if (ktime_after(ktime_get(), timeout)) { ++ dev_err(cprman->dev, "timeout waiting for !BUSY\n"); ++ count = 0; ++ goto out; ++ } ++ cpu_relax(); ++ } ++ ++ count = cprman_read(cprman, CM_TCNTCNT); ++ ++ cprman_write(cprman, CM_TCNTCTL, 0); ++ ++out: ++ spin_unlock(&cprman->regs_lock); ++ ++ return count * 1000; ++} ++ + static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base, + struct debugfs_reg32 *regs, size_t nregs, + struct dentry *dentry) +@@ -477,6 +534,8 @@ struct bcm2835_clock_data { + + bool is_vpu_clock; + bool is_mash_clock; ++ ++ u32 tcnt_mux; + }; + + struct bcm2835_gate_data { +@@ -1038,6 +1097,17 @@ static int bcm2835_clock_on(struct clk_hw *hw) + CM_GATE); + spin_unlock(&cprman->regs_lock); + ++ /* Debug code to measure the clock once it's turned on to see ++ * if it's ticking at the rate we expect. ++ */ ++ if (data->tcnt_mux && false) { ++ dev_info(cprman->dev, ++ "clk %s: rate %ld, measure %ld\n", ++ data->name, ++ clk_hw_get_rate(hw), ++ bcm2835_measure_tcnt_mux(cprman, data->tcnt_mux)); ++ } ++ + return 0; + } + +@@ -1816,7 +1886,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .ctl_reg = CM_OTPCTL, + .div_reg = CM_OTPDIV, + .int_bits = 4, +- .frac_bits = 0), ++ .frac_bits = 0, ++ .tcnt_mux = 6), + /* + * Used for a 1Mhz clock for the system clocksource, and also used + * bythe watchdog timer and the camera pulse generator. +@@ -1850,13 +1921,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .ctl_reg = CM_H264CTL, + .div_reg = CM_H264DIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 1), + [BCM2835_CLOCK_ISP] = REGISTER_VPU_CLK( + .name = "isp", + .ctl_reg = CM_ISPCTL, + .div_reg = CM_ISPDIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 2), + + /* + * Secondary SDRAM clock. Used for low-voltage modes when the PLL +@@ -1867,13 +1940,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .ctl_reg = CM_SDCCTL, + .div_reg = CM_SDCDIV, + .int_bits = 6, +- .frac_bits = 0), ++ .frac_bits = 0, ++ .tcnt_mux = 3), + [BCM2835_CLOCK_V3D] = REGISTER_VPU_CLK( + .name = "v3d", + .ctl_reg = CM_V3DCTL, + .div_reg = CM_V3DDIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 4), + /* + * VPU clock. This doesn't have an enable bit, since it drives + * the bus for everything else, and is special so it doesn't need +@@ -1887,7 +1962,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .int_bits = 12, + .frac_bits = 8, + .flags = CLK_IS_CRITICAL, +- .is_vpu_clock = true), ++ .is_vpu_clock = true, ++ .tcnt_mux = 5), + + /* clocks with per parent mux */ + [BCM2835_CLOCK_AVEO] = REGISTER_PER_CLK( +@@ -1895,19 +1971,22 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .ctl_reg = CM_AVEOCTL, + .div_reg = CM_AVEODIV, + .int_bits = 4, +- .frac_bits = 0), ++ .frac_bits = 0, ++ .tcnt_mux = 38), + [BCM2835_CLOCK_CAM0] = REGISTER_PER_CLK( + .name = "cam0", + .ctl_reg = CM_CAM0CTL, + .div_reg = CM_CAM0DIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 14), + [BCM2835_CLOCK_CAM1] = REGISTER_PER_CLK( + .name = "cam1", + .ctl_reg = CM_CAM1CTL, + .div_reg = CM_CAM1DIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 15), + [BCM2835_CLOCK_DFT] = REGISTER_PER_CLK( + .name = "dft", + .ctl_reg = CM_DFTCTL, +@@ -1919,7 +1998,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .ctl_reg = CM_DPICTL, + .div_reg = CM_DPIDIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 17), + + /* Arasan EMMC clock */ + [BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK( +@@ -1927,7 +2007,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .ctl_reg = CM_EMMCCTL, + .div_reg = CM_EMMCDIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 39), + + /* General purpose (GPIO) clocks */ + [BCM2835_CLOCK_GP0] = REGISTER_PER_CLK( +@@ -1936,7 +2017,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .div_reg = CM_GP0DIV, + .int_bits = 12, + .frac_bits = 12, +- .is_mash_clock = true), ++ .is_mash_clock = true, ++ .tcnt_mux = 20), + [BCM2835_CLOCK_GP1] = REGISTER_PER_CLK( + .name = "gp1", + .ctl_reg = CM_GP1CTL, +@@ -1944,7 +2026,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .int_bits = 12, + .frac_bits = 12, + .flags = CLK_IS_CRITICAL, +- .is_mash_clock = true), ++ .is_mash_clock = true, ++ .tcnt_mux = 21), + [BCM2835_CLOCK_GP2] = REGISTER_PER_CLK( + .name = "gp2", + .ctl_reg = CM_GP2CTL, +@@ -1959,40 +2042,46 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .ctl_reg = CM_HSMCTL, + .div_reg = CM_HSMDIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 22), + [BCM2835_CLOCK_PCM] = REGISTER_PER_CLK( + .name = "pcm", + .ctl_reg = CM_PCMCTL, + .div_reg = CM_PCMDIV, + .int_bits = 12, + .frac_bits = 12, +- .is_mash_clock = true), ++ .is_mash_clock = true, ++ .tcnt_mux = 23), + [BCM2835_CLOCK_PWM] = REGISTER_PER_CLK( + .name = "pwm", + .ctl_reg = CM_PWMCTL, + .div_reg = CM_PWMDIV, + .int_bits = 12, + .frac_bits = 12, +- .is_mash_clock = true), ++ .is_mash_clock = true, ++ .tcnt_mux = 24), + [BCM2835_CLOCK_SLIM] = REGISTER_PER_CLK( + .name = "slim", + .ctl_reg = CM_SLIMCTL, + .div_reg = CM_SLIMDIV, + .int_bits = 12, + .frac_bits = 12, +- .is_mash_clock = true), ++ .is_mash_clock = true, ++ .tcnt_mux = 25), + [BCM2835_CLOCK_SMI] = REGISTER_PER_CLK( + .name = "smi", + .ctl_reg = CM_SMICTL, + .div_reg = CM_SMIDIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 27), + [BCM2835_CLOCK_UART] = REGISTER_PER_CLK( + .name = "uart", + .ctl_reg = CM_UARTCTL, + .div_reg = CM_UARTDIV, + .int_bits = 10, +- .frac_bits = 12), ++ .frac_bits = 12, ++ .tcnt_mux = 28), + + /* TV encoder clock. Only operating frequency is 108Mhz. */ + [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK( +@@ -2005,7 +2094,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + * Allow rate change propagation only on PLLH_AUX which is + * assigned index 7 in the parent array. + */ +- .set_rate_parent = BIT(7)), ++ .set_rate_parent = BIT(7), ++ .tcnt_mux = 29), + + /* dsi clocks */ + [BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK( +@@ -2013,25 +2103,29 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { + .ctl_reg = CM_DSI0ECTL, + .div_reg = CM_DSI0EDIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 18), + [BCM2835_CLOCK_DSI1E] = REGISTER_PER_CLK( + .name = "dsi1e", + .ctl_reg = CM_DSI1ECTL, + .div_reg = CM_DSI1EDIV, + .int_bits = 4, +- .frac_bits = 8), ++ .frac_bits = 8, ++ .tcnt_mux = 19), + [BCM2835_CLOCK_DSI0P] = REGISTER_DSI0_CLK( + .name = "dsi0p", + .ctl_reg = CM_DSI0PCTL, + .div_reg = CM_DSI0PDIV, + .int_bits = 0, +- .frac_bits = 0), ++ .frac_bits = 0, ++ .tcnt_mux = 12), + [BCM2835_CLOCK_DSI1P] = REGISTER_DSI1_CLK( + .name = "dsi1p", + .ctl_reg = CM_DSI1PCTL, + .div_reg = CM_DSI1PDIV, + .int_bits = 0, +- .frac_bits = 0), ++ .frac_bits = 0, ++ .tcnt_mux = 13), + + /* the gates */ + + +From 41136c787e4f6a7577b3568df3c38ba78e79c860 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Tue, 26 Apr 2016 13:46:13 -0700 +Subject: [PATCH 169/190] drm/panel: Add support for the Raspberry Pi 7" + Touchscreen. + +This driver communicates with the Atmel microcontroller for sequencing +the poweron of the TC358762 DSI-DPI bridge and controlling the +backlight PWM. + +The following lines are required in config.txt, to keep the firmware +from trying to bash our I2C lines and steal the DSI interrupts: + + disable_touchscreen=1 + ignore_lcd=2 + mask_gpu_interrupt1=0x1000 + +This means that the firmware won't power on the panel at boot time (no +rainbow) and the touchscreen input won't work. The native input +driver for the touchscreen still needs to be written. + +v2: Set the same default orientation as the closed source firmware + used, which is the best for viewing angle. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/panel/Kconfig | 8 + + drivers/gpu/drm/panel/Makefile | 1 + + .../gpu/drm/panel/panel-raspberrypi-touchscreen.c | 514 +++++++++++++++++++++ + 3 files changed, 523 insertions(+) + create mode 100644 drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c + +diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig +index 62aba976e744c146c26d7fedf44c54cdd480361e..de7a56ab758b8f043194391f9b9e43df65c06d0a 100644 +--- a/drivers/gpu/drm/panel/Kconfig ++++ b/drivers/gpu/drm/panel/Kconfig +@@ -52,6 +52,14 @@ config DRM_PANEL_PANASONIC_VVX10F034N00 + WUXGA (1920x1200) Novatek NT1397-based DSI panel as found in some + Xperia Z2 tablets + ++config DRM_PANEL_RASPBERRYPI_TOUCHSCREEN ++ tristate "Raspberry Pi 7-inch touchscreen panel" ++ depends on DRM_MIPI_DSI ++ help ++ Say Y here if you want to enable support for the Raspberry ++ Pi 7" Touchscreen. To compile this driver as a module, ++ choose M here. ++ + config DRM_PANEL_SAMSUNG_S6E8AA0 + tristate "Samsung S6E8AA0 DSI video mode panel" + depends on OF +diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile +index a5c7ec0236e0174079cce0f07d46372967e9cf3b..e8a7ed280fff907e5a730a13ae9a3e5e34cacce4 100644 +--- a/drivers/gpu/drm/panel/Makefile ++++ b/drivers/gpu/drm/panel/Makefile +@@ -2,6 +2,7 @@ obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o + obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o + obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o + obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o ++obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen.o + obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o + obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o + obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o +diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +new file mode 100644 +index 0000000000000000000000000000000000000000..1a536fe4d040f5fafe324baee110a6225dd0be08 +--- /dev/null ++++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +@@ -0,0 +1,514 @@ ++/* ++ * Copyright © 2016 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Portions of this file (derived from panel-simple.c) are: ++ * ++ * Copyright (C) 2013, NVIDIA Corporation. All rights reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sub license, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ */ ++ ++/** ++ * DOC: Raspberry Pi 7" touchscreen panel driver. ++ * ++ * The 7" touchscreen consists of a DPI LCD panel, a Toshiba ++ * TC358762XBG DSI-DPI bridge, and an I2C-connected Atmel ATTINY88-MUR ++ * controlling power management, the LCD PWM, and the touchscreen. ++ * ++ * This driver presents this device as a MIPI DSI panel to the DRM ++ * driver, and should expose the touchscreen as a HID device. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* I2C registers of the Atmel microcontroller. */ ++enum REG_ADDR { ++ REG_ID = 0x80, ++ REG_PORTA, // BIT(2) for horizontal flip, BIT(3) for vertical flip ++ REG_PORTB, ++ REG_PORTC, ++ REG_PORTD, ++ REG_POWERON, ++ REG_PWM, ++ REG_DDRA, ++ REG_DDRB, ++ REG_DDRC, ++ REG_DDRD, ++ REG_TEST, ++ REG_WR_ADDRL, ++ REG_WR_ADDRH, ++ REG_READH, ++ REG_READL, ++ REG_WRITEH, ++ REG_WRITEL, ++ REG_ID2, ++}; ++ ++/* We only turn the PWM on or off, without varying values. */ ++#define RPI_TOUCHSCREEN_MAX_BRIGHTNESS 1 ++ ++/* DSI D-PHY Layer Registers */ ++#define D0W_DPHYCONTTX 0x0004 ++#define CLW_DPHYCONTRX 0x0020 ++#define D0W_DPHYCONTRX 0x0024 ++#define D1W_DPHYCONTRX 0x0028 ++#define COM_DPHYCONTRX 0x0038 ++#define CLW_CNTRL 0x0040 ++#define D0W_CNTRL 0x0044 ++#define D1W_CNTRL 0x0048 ++#define DFTMODE_CNTRL 0x0054 ++ ++/* DSI PPI Layer Registers */ ++#define PPI_STARTPPI 0x0104 ++#define PPI_BUSYPPI 0x0108 ++#define PPI_LINEINITCNT 0x0110 ++#define PPI_LPTXTIMECNT 0x0114 ++//#define PPI_LANEENABLE 0x0134 ++//#define PPI_TX_RX_TA 0x013C ++#define PPI_CLS_ATMR 0x0140 ++#define PPI_D0S_ATMR 0x0144 ++#define PPI_D1S_ATMR 0x0148 ++#define PPI_D0S_CLRSIPOCOUNT 0x0164 ++#define PPI_D1S_CLRSIPOCOUNT 0x0168 ++#define CLS_PRE 0x0180 ++#define D0S_PRE 0x0184 ++#define D1S_PRE 0x0188 ++#define CLS_PREP 0x01A0 ++#define D0S_PREP 0x01A4 ++#define D1S_PREP 0x01A8 ++#define CLS_ZERO 0x01C0 ++#define D0S_ZERO 0x01C4 ++#define D1S_ZERO 0x01C8 ++#define PPI_CLRFLG 0x01E0 ++#define PPI_CLRSIPO 0x01E4 ++#define HSTIMEOUT 0x01F0 ++#define HSTIMEOUTENABLE 0x01F4 ++ ++/* DSI Protocol Layer Registers */ ++#define DSI_STARTDSI 0x0204 ++#define DSI_BUSYDSI 0x0208 ++#define DSI_LANEENABLE 0x0210 ++# define DSI_LANEENABLE_CLOCK BIT(0) ++# define DSI_LANEENABLE_D0 BIT(1) ++# define DSI_LANEENABLE_D1 BIT(2) ++ ++#define DSI_LANESTATUS0 0x0214 ++#define DSI_LANESTATUS1 0x0218 ++#define DSI_INTSTATUS 0x0220 ++#define DSI_INTMASK 0x0224 ++#define DSI_INTCLR 0x0228 ++#define DSI_LPTXTO 0x0230 ++#define DSI_MODE 0x0260 ++#define DSI_PAYLOAD0 0x0268 ++#define DSI_PAYLOAD1 0x026C ++#define DSI_SHORTPKTDAT 0x0270 ++#define DSI_SHORTPKTREQ 0x0274 ++#define DSI_BTASTA 0x0278 ++#define DSI_BTACLR 0x027C ++ ++/* DSI General Registers */ ++#define DSIERRCNT 0x0300 ++#define DSISIGMOD 0x0304 ++ ++/* DSI Application Layer Registers */ ++#define APLCTRL 0x0400 ++#define APLSTAT 0x0404 ++#define APLERR 0x0408 ++#define PWRMOD 0x040C ++#define RDPKTLN 0x0410 ++#define PXLFMT 0x0414 ++#define MEMWRCMD 0x0418 ++ ++/* LCDC/DPI Host Registers */ ++#define LCDCTRL 0x0420 ++#define HSR 0x0424 ++#define HDISPR 0x0428 ++#define VSR 0x042C ++#define VDISPR 0x0430 ++#define VFUEN 0x0434 ++ ++/* DBI-B Host Registers */ ++#define DBIBCTRL 0x0440 ++ ++/* SPI Master Registers */ ++#define SPICMR 0x0450 ++#define SPITCR 0x0454 ++ ++/* System Controller Registers */ ++#define SYSSTAT 0x0460 ++#define SYSCTRL 0x0464 ++#define SYSPLL1 0x0468 ++#define SYSPLL2 0x046C ++#define SYSPLL3 0x0470 ++#define SYSPMCTRL 0x047C ++ ++/* GPIO Registers */ ++#define GPIOC 0x0480 ++#define GPIOO 0x0484 ++#define GPIOI 0x0488 ++ ++/* I2C Registers */ ++#define I2CCLKCTRL 0x0490 ++ ++/* Chip/Rev Registers */ ++#define IDREG 0x04A0 ++ ++/* Debug Registers */ ++#define WCMDQUEUE 0x0500 ++#define RCMDQUEUE 0x0504 ++ ++struct rpi_touchscreen { ++ struct drm_panel base; ++ struct mipi_dsi_device *dsi; ++ struct i2c_client *bridge_i2c; ++ ++ /* Version of the firmware on the bridge chip */ ++ int atmel_ver; ++}; ++ ++static const struct drm_display_mode rpi_touchscreen_modes[] = { ++ { ++ /* The DSI PLL can only integer divide from the 2Ghz ++ * PLLD, giving us few choices. We pick a divide by 3 ++ * as our DSI HS clock, giving us a pixel clock of ++ * that divided by 24 bits. Pad out HFP to get our ++ * panel to refresh at 60Hz, even if that doesn't ++ * match the datasheet. ++ */ ++#define PIXEL_CLOCK ((2000000000 / 3) / 24) ++#define VREFRESH 60 ++#define VTOTAL (480 + 7 + 2 + 21) ++#define HACT 800 ++#define HSW 2 ++#define HBP 46 ++#define HFP ((PIXEL_CLOCK / (VTOTAL * VREFRESH)) - (HACT + HSW + HBP)) ++ ++ .clock = PIXEL_CLOCK / 1000, ++ .hdisplay = HACT, ++ .hsync_start = HACT + HFP, ++ .hsync_end = HACT + HFP + HSW, ++ .htotal = HACT + HFP + HSW + HBP, ++ .vdisplay = 480, ++ .vsync_start = 480 + 7, ++ .vsync_end = 480 + 7 + 2, ++ .vtotal = VTOTAL, ++ .vrefresh = 60, ++ }, ++}; ++ ++static struct rpi_touchscreen *panel_to_ts(struct drm_panel *panel) ++{ ++ return container_of(panel, struct rpi_touchscreen, base); ++} ++ ++static u8 rpi_touchscreen_i2c_read(struct rpi_touchscreen *ts, u8 reg) ++{ ++ return i2c_smbus_read_byte_data(ts->bridge_i2c, reg); ++} ++ ++static void rpi_touchscreen_i2c_write(struct rpi_touchscreen *ts, ++ u8 reg, u8 val) ++{ ++ int ret; ++ ++ ret = i2c_smbus_write_byte_data(ts->bridge_i2c, reg, val); ++ if (ret) ++ dev_err(&ts->dsi->dev, "I2C write failed: %d\n", ret); ++} ++ ++static int rpi_touchscreen_write(struct rpi_touchscreen *ts, u16 reg, u32 val) ++{ ++#if 0 ++ /* The firmware uses LP DSI transactions like this to bring up ++ * the hardware, which should be faster than using I2C to then ++ * pass to the Toshiba. However, I was unable to get it to ++ * work. ++ */ ++ u8 msg[] = { ++ reg, ++ reg >> 8, ++ val, ++ val >> 8, ++ val >> 16, ++ val >> 24, ++ }; ++ ++ mipi_dsi_dcs_write_buffer(ts->dsi, msg, sizeof(msg)); ++#else ++ rpi_touchscreen_i2c_write(ts, REG_WR_ADDRH, reg >> 8); ++ rpi_touchscreen_i2c_write(ts, REG_WR_ADDRL, reg); ++ rpi_touchscreen_i2c_write(ts, REG_WRITEH, val >> 8); ++ rpi_touchscreen_i2c_write(ts, REG_WRITEL, val); ++#endif ++ ++ return 0; ++} ++ ++static int rpi_touchscreen_disable(struct drm_panel *panel) ++{ ++ struct rpi_touchscreen *ts = panel_to_ts(panel); ++ ++ rpi_touchscreen_i2c_write(ts, REG_PWM, 0); ++ ++ rpi_touchscreen_i2c_write(ts, REG_POWERON, 0); ++ udelay(1); ++ ++ return 0; ++} ++ ++static int rpi_touchscreen_noop(struct drm_panel *panel) ++{ ++ return 0; ++} ++ ++static int rpi_touchscreen_enable(struct drm_panel *panel) ++{ ++ struct rpi_touchscreen *ts = panel_to_ts(panel); ++ int i; ++ ++ rpi_touchscreen_i2c_write(ts, REG_POWERON, 1); ++ /* Wait for nPWRDWN to go low to indicate poweron is done. */ ++ for (i = 0; i < 100; i++) { ++ if (rpi_touchscreen_i2c_read(ts, REG_PORTB) & 1) ++ break; ++ } ++ ++ rpi_touchscreen_write(ts, DSI_LANEENABLE, ++ DSI_LANEENABLE_CLOCK | ++ DSI_LANEENABLE_D0 | ++ (ts->dsi->lanes > 1 ? DSI_LANEENABLE_D1 : 0)); ++ rpi_touchscreen_write(ts, PPI_D0S_CLRSIPOCOUNT, 0x05); ++ rpi_touchscreen_write(ts, PPI_D1S_CLRSIPOCOUNT, 0x05); ++ rpi_touchscreen_write(ts, PPI_D0S_ATMR, 0x00); ++ rpi_touchscreen_write(ts, PPI_D1S_ATMR, 0x00); ++ rpi_touchscreen_write(ts, PPI_LPTXTIMECNT, 0x03); ++ ++ rpi_touchscreen_write(ts, SPICMR, 0x00); ++ rpi_touchscreen_write(ts, LCDCTRL, 0x00100150); ++ rpi_touchscreen_write(ts, SYSCTRL, 0x040f); ++ msleep(100); ++ ++ rpi_touchscreen_write(ts, PPI_STARTPPI, 0x01); ++ rpi_touchscreen_write(ts, DSI_STARTDSI, 0x01); ++ msleep(100); ++ ++ /* Turn on the backlight. */ ++ rpi_touchscreen_i2c_write(ts, REG_PWM, 255); ++ ++ /* Default to the same orientation as the closed source ++ * firmware used for the panel. Runtime rotation ++ * configuration will be supported using VC4's plane ++ * orientation bits. ++ */ ++ rpi_touchscreen_i2c_write(ts, REG_PORTA, BIT(2)); ++ ++ return 0; ++} ++ ++static int rpi_touchscreen_get_modes(struct drm_panel *panel) ++{ ++ struct drm_connector *connector = panel->connector; ++ struct drm_device *drm = panel->drm; ++ unsigned int i, num = 0; ++ ++ for (i = 0; i < ARRAY_SIZE(rpi_touchscreen_modes); i++) { ++ const struct drm_display_mode *m = &rpi_touchscreen_modes[i]; ++ struct drm_display_mode *mode; ++ ++ mode = drm_mode_duplicate(drm, m); ++ if (!mode) { ++ dev_err(drm->dev, "failed to add mode %ux%u@%u\n", ++ m->hdisplay, m->vdisplay, m->vrefresh); ++ continue; ++ } ++ ++ mode->type |= DRM_MODE_TYPE_DRIVER; ++ ++ if (i == 0) ++ mode->type |= DRM_MODE_TYPE_PREFERRED; ++ ++ drm_mode_set_name(mode); ++ ++ drm_mode_probed_add(connector, mode); ++ num++; ++ } ++ ++ connector->display_info.bpc = 8; ++ connector->display_info.width_mm = 154; ++ connector->display_info.height_mm = 86; ++ ++ return num; ++} ++ ++static const struct drm_panel_funcs rpi_touchscreen_funcs = { ++ .disable = rpi_touchscreen_disable, ++ .unprepare = rpi_touchscreen_noop, ++ .prepare = rpi_touchscreen_noop, ++ .enable = rpi_touchscreen_enable, ++ .get_modes = rpi_touchscreen_get_modes, ++}; ++ ++static struct i2c_client *rpi_touchscreen_get_i2c(struct device *dev, ++ const char *name) ++{ ++ struct device_node *node; ++ struct i2c_client *client; ++ ++ node = of_parse_phandle(dev->of_node, name, 0); ++ if (!node) ++ return ERR_PTR(-ENODEV); ++ ++ client = of_find_i2c_device_by_node(node); ++ ++ of_node_put(node); ++ ++ return client; ++} ++ ++static int rpi_touchscreen_dsi_probe(struct mipi_dsi_device *dsi) ++{ ++ struct device *dev = &dsi->dev; ++ struct rpi_touchscreen *ts; ++ int ret, ver; ++ ++ ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL); ++ if (!ts) ++ return -ENOMEM; ++ ++ dev_set_drvdata(dev, ts); ++ ++ ts->dsi = dsi; ++ dsi->mode_flags = (MIPI_DSI_MODE_VIDEO | ++ MIPI_DSI_MODE_VIDEO_SYNC_PULSE | ++ MIPI_DSI_MODE_LPM); ++ dsi->format = MIPI_DSI_FMT_RGB888; ++ dsi->lanes = 1; ++ ++ ts->bridge_i2c = ++ rpi_touchscreen_get_i2c(dev, "raspberrypi,touchscreen-bridge"); ++ if (IS_ERR(ts->bridge_i2c)) { ++ ret = -EPROBE_DEFER; ++ return ret; ++ } ++ ++ ver = rpi_touchscreen_i2c_read(ts, REG_ID); ++ if (ver < 0) { ++ dev_err(dev, "Atmel I2C read failed: %d\n", ver); ++ return -ENODEV; ++ } ++ ++ switch (ver) { ++ case 0xde: ++ ts->atmel_ver = 1; ++ break; ++ case 0xc3: ++ ts->atmel_ver = 2; ++ break; ++ default: ++ dev_err(dev, "Unknown Atmel firmware revision: 0x%02x\n", ver); ++ return -ENODEV; ++ } ++ ++ /* Turn off at boot, so we can cleanly sequence powering on. */ ++ rpi_touchscreen_i2c_write(ts, REG_POWERON, 0); ++ ++ drm_panel_init(&ts->base); ++ ts->base.dev = dev; ++ ts->base.funcs = &rpi_touchscreen_funcs; ++ ++ ret = drm_panel_add(&ts->base); ++ if (ret < 0) ++ goto err_release_bridge; ++ ++ return mipi_dsi_attach(dsi); ++ ++err_release_bridge: ++ put_device(&ts->bridge_i2c->dev); ++ return ret; ++} ++ ++static int rpi_touchscreen_dsi_remove(struct mipi_dsi_device *dsi) ++{ ++ struct device *dev = &dsi->dev; ++ struct rpi_touchscreen *ts = dev_get_drvdata(dev); ++ int ret; ++ ++ ret = mipi_dsi_detach(dsi); ++ if (ret < 0) { ++ dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret); ++ return ret; ++ } ++ ++ drm_panel_detach(&ts->base); ++ drm_panel_remove(&ts->base); ++ ++ put_device(&ts->bridge_i2c->dev); ++ ++ return 0; ++} ++ ++static void rpi_touchscreen_dsi_shutdown(struct mipi_dsi_device *dsi) ++{ ++ struct device *dev = &dsi->dev; ++ struct rpi_touchscreen *ts = dev_get_drvdata(dev); ++ ++ rpi_touchscreen_i2c_write(ts, REG_POWERON, 0); ++} ++ ++static const struct of_device_id rpi_touchscreen_of_match[] = { ++ { .compatible = "raspberrypi,touchscreen" }, ++ { } /* sentinel */ ++}; ++MODULE_DEVICE_TABLE(of, rpi_touchscreen_of_match); ++ ++static struct mipi_dsi_driver rpi_touchscreen_driver = { ++ .driver = { ++ .name = "raspberrypi-touchscreen", ++ .of_match_table = rpi_touchscreen_of_match, ++ }, ++ .probe = rpi_touchscreen_dsi_probe, ++ .remove = rpi_touchscreen_dsi_remove, ++ .shutdown = rpi_touchscreen_dsi_shutdown, ++}; ++module_mipi_dsi_driver(rpi_touchscreen_driver); ++ ++MODULE_AUTHOR("Eric Anholt "); ++MODULE_DESCRIPTION("Raspberry Pi 7-inch touchscreen driver"); ++MODULE_LICENSE("GPL v2"); + +From d09977bb38e54a34541e221bb849fb40b1d403ff Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 2 Jun 2016 12:29:45 -0700 +Subject: [PATCH 170/190] BCM270X: Add the DSI panel to the defconfig. + +Signed-off-by: Eric Anholt +--- + arch/arm/configs/bcm2709_defconfig | 2 ++ + arch/arm/configs/bcmrpi_defconfig | 2 ++ + arch/arm64/configs/bcmrpi3_defconfig | 2 ++ + 3 files changed, 6 insertions(+) + +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index 97375c26f2d70d0c4f3956622f839dcf04463e31..d3fd0252f78ec72bd6d93322e781abc3609af01c 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -833,6 +833,8 @@ CONFIG_VIDEO_OV7640=m + CONFIG_VIDEO_MT9V011=m + CONFIG_DRM=m + CONFIG_DRM_LOAD_EDID_FIRMWARE=y ++CONFIG_DRM_PANEL_SIMPLE=m ++CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m + CONFIG_DRM_UDL=m + CONFIG_DRM_VC4=m + CONFIG_FB=y +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index 0e2c3679d9614d331db39cd25ae9095136d3190a..0768998e5cbcc96714d546f656ff59eafe2dc754 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -826,6 +826,8 @@ CONFIG_VIDEO_OV7640=m + CONFIG_VIDEO_MT9V011=m + CONFIG_DRM=m + CONFIG_DRM_LOAD_EDID_FIRMWARE=y ++CONFIG_DRM_PANEL_SIMPLE=m ++CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m + CONFIG_DRM_UDL=m + CONFIG_DRM_VC4=m + CONFIG_FB=y +diff --git a/arch/arm64/configs/bcmrpi3_defconfig b/arch/arm64/configs/bcmrpi3_defconfig +index 4d85c231c5ea0244e1b05fb4a5e3c8fd3e651ddf..baf316e3a69d421d79ec098c7ad2603c906782df 100644 +--- a/arch/arm64/configs/bcmrpi3_defconfig ++++ b/arch/arm64/configs/bcmrpi3_defconfig +@@ -812,6 +812,8 @@ CONFIG_VIDEO_OV7640=m + CONFIG_VIDEO_MT9V011=m + CONFIG_DRM=m + CONFIG_DRM_LOAD_EDID_FIRMWARE=y ++CONFIG_DRM_PANEL_SIMPLE=m ++CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m + CONFIG_DRM_UDL=m + CONFIG_DRM_VC4=m + CONFIG_FB=y + +From fb03cba6b7f53fa9fbc524d2b9ebf0e86d15dad2 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Tue, 13 Dec 2016 15:15:10 -0800 +Subject: [PATCH 171/190] ARM: bcm2835: dt: Add the DSI module nodes and + clocks. + +The modules stay disabled by default, and if you want to enable DSI +you'll need an overlay that connects a panel to it. + +Signed-off-by: Eric Anholt +--- + arch/arm/boot/dts/bcm2835-rpi.dtsi | 8 +++++++ + arch/arm/boot/dts/bcm283x.dtsi | 49 +++++++++++++++++++++++++++++++++++--- + 2 files changed, 54 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi +index 6ddf7dfe3f7202642cc4d595ff4763f91248c0a5..58f7d874c70a9cf965e10ae3f14fe3bb00846b71 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi +@@ -87,3 +87,11 @@ + power-domains = <&power RPI_POWER_DOMAIN_HDMI>; + status = "okay"; + }; ++ ++&dsi0 { ++ power-domains = <&power RPI_POWER_DOMAIN_DSI0>; ++}; ++ ++&dsi1 { ++ power-domains = <&power RPI_POWER_DOMAIN_DSI1>; ++}; +diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi +index b710a4d67b8ec8c8c18ce8efb6f270e7cfb68e52..304dd291a9ae94700e8e628c0c9ebd3fb98abb19 100644 +--- a/arch/arm/boot/dts/bcm283x.dtsi ++++ b/arch/arm/boot/dts/bcm283x.dtsi +@@ -93,10 +93,13 @@ + #clock-cells = <1>; + reg = <0x7e101000 0x2000>; + +- /* CPRMAN derives everything from the platform's +- * oscillator. ++ /* CPRMAN derives almost everything from the ++ * platform's oscillator. However, the DSI ++ * pixel clocks come from the DSI analog PHY. + */ +- clocks = <&clk_osc>; ++ clocks = <&clk_osc>, ++ <&dsi0 0>, <&dsi0 1>, <&dsi0 2>, ++ <&dsi1 0>, <&dsi1 1>, <&dsi1 2>; + }; + + rng@7e104000 { +@@ -391,6 +394,26 @@ + interrupts = <2 14>; /* pwa1 */ + }; + ++ dsi0: dsi@7e209000 { ++ compatible = "brcm,bcm2835-dsi0"; ++ reg = <0x7e209000 0x78>; ++ interrupts = <2 4>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #clock-cells = <1>; ++ ++ clocks = <&clocks BCM2835_PLLA_DSI0>, ++ <&clocks BCM2835_CLOCK_DSI0E>, ++ <&clocks BCM2835_CLOCK_DSI0P>; ++ clock-names = "phy", "escape", "pixel"; ++ ++ clock-output-names = "dsi0_byte", ++ "dsi0_ddr2", ++ "dsi0_ddr"; ++ ++ status = "disabled"; ++ }; ++ + thermal: thermal@7e212000 { + compatible = "brcm,bcm2835-thermal"; + reg = <0x7e212000 0x8>; +@@ -457,6 +480,26 @@ + interrupts = <2 1>; + }; + ++ dsi1: dsi@7e700000 { ++ compatible = "brcm,bcm2835-dsi1"; ++ reg = <0x7e700000 0x8c>; ++ interrupts = <2 12>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #clock-cells = <1>; ++ ++ clocks = <&clocks BCM2835_PLLD_DSI1>, ++ <&clocks BCM2835_CLOCK_DSI1E>, ++ <&clocks BCM2835_CLOCK_DSI1P>; ++ clock-names = "phy", "escape", "pixel"; ++ ++ clock-output-names = "dsi1_byte", ++ "dsi1_ddr2", ++ "dsi1_ddr"; ++ ++ status = "disabled"; ++ }; ++ + i2c1: i2c@7e804000 { + compatible = "brcm,bcm2835-i2c"; + reg = <0x7e804000 0x1000>; + +From 39f1530e82f569ce44aa1cbeba88ae4385b423cc Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 2 Jun 2016 15:09:35 -0700 +Subject: [PATCH 172/190] BCM270X: Enable the DSI panel node in the VC4 + overlay. + +Signed-off-by: Eric Anholt +--- + arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 5 ++++ + arch/arm/boot/dts/bcm2708-rpi-b.dts | 5 ++++ + arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 5 ++++ + arch/arm/boot/dts/bcm270x.dtsi | 27 ++++++++++++++++++++++ + arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 5 ++++ + arch/arm/boot/dts/bcm2710.dtsi | 1 - + arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 23 +++++++++++++++++- + 7 files changed, 69 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts +index 0b66ac9f25a5f7ae51f3d0666cfcb908f85e1d24..08bf838fab551638e898930fba7ba49b3aeefbb3 100644 +--- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts +@@ -155,3 +155,8 @@ + sd_debug = <&sdhost>,"brcm,debug"; + }; + }; ++ ++&i2c_dsi { ++ gpios = <&gpio 28 0 ++ &gpio 29 0>; ++}; +diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts +index e99e9d999e4142060c41eb47b93c8ac70a30f384..4e6b4dd6a8d9c4f13bc865bb8ced68264162cb6c 100644 +--- a/arch/arm/boot/dts/bcm2708-rpi-b.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts +@@ -145,3 +145,8 @@ + sd_debug = <&sdhost>,"brcm,debug"; + }; + }; ++ ++&i2c_dsi { ++ gpios = <&gpio 2 0 ++ &gpio 3 0>; ++}; +diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts +index 20674f250af922e9f9a43e3e8b13aee42e3930be..2dc0e1204e6374bbc6924e26dc4a04b68718559a 100644 +--- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts ++++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts +@@ -155,3 +155,8 @@ + sd_debug = <&sdhost>,"brcm,debug"; + }; + }; ++ ++&i2c_dsi { ++ gpios = <&gpio 28 0 ++ &gpio 29 0>; ++}; +diff --git a/arch/arm/boot/dts/bcm270x.dtsi b/arch/arm/boot/dts/bcm270x.dtsi +index 36d853715f2379e1952ce3d3be58dd670e305159..caa66393518603529d284f360b2000b0ed4852ef 100644 +--- a/arch/arm/boot/dts/bcm270x.dtsi ++++ b/arch/arm/boot/dts/bcm270x.dtsi +@@ -137,6 +137,29 @@ + /* Add alias */ + status = "disabled"; + }; ++ ++ i2c_dsi: i2cdsi { ++ /* We have to use i2c-gpio because the ++ * firmware is also polling another device ++ * using the only hardware I2C bus that could ++ * connect to these pins. ++ */ ++ compatible = "i2c-gpio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ ++ pitouchscreen_bridge: bridge@45 { ++ compatible = "raspberrypi,touchscreen-bridge-i2c"; ++ reg = <0x45>; ++ }; ++ ++ pitouchscreen_touch: bridge@38 { ++ compatible = "raspberrypi,touchscreen-ts-i2c"; ++ reg = <0x38>; ++ }; ++ }; ++ + }; + + vdd_5v0_reg: fixedregulator_5v0 { +@@ -155,3 +178,7 @@ + regulator-always-on; + }; + }; ++ ++&dsi1 { ++ power-domains = <&power RPI_POWER_DOMAIN_DSI1>; ++}; +diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +index 616cfd5c7094596b497101e8feca25e25e77c3e8..173103aaca503833b5e29530ed94e14c7cab0444 100644 +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +@@ -224,3 +224,8 @@ + sd_debug = <&sdhost>,"brcm,debug"; + }; + }; ++ ++&i2c_dsi { ++ gpios = <&gpio 44 0 ++ &gpio 45 0>; ++}; +diff --git a/arch/arm/boot/dts/bcm2710.dtsi b/arch/arm/boot/dts/bcm2710.dtsi +index 3e134a1208610b90e2d0fc22f03c6e9f372bfcd7..3fabac6a93e846f678d846637c4f9a5f5b8e7922 100644 +--- a/arch/arm/boot/dts/bcm2710.dtsi ++++ b/arch/arm/boot/dts/bcm2710.dtsi +@@ -145,4 +145,3 @@ + interrupt-parent = <&local_intc>; + interrupts = <8>; + }; +- +diff --git a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts +index fb45c6456b181b047d6cff8784f7696eb75da3c7..05faf1bfa1b7c73fd60b1efb813b969e10bbfefa 100644 +--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts ++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts +@@ -128,8 +128,29 @@ + }; + }; + +- + fragment@16 { ++ target = <&dsi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pitouchscreen: panel@0 { ++ compatible = "raspberrypi,touchscreen"; ++ reg = <0>; ++ raspberrypi,touchscreen-bridge = <&pitouchscreen_bridge>; ++ }; ++ }; ++ }; ++ ++ fragment@17 { ++ target = <&i2c_dsi>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@18 { + target = <&clocks>; + __overlay__ { + claim-clocks = < + +From e538449b34f8dd973e0ffc8ba2d43bfcedb08127 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 15 Sep 2016 15:25:23 +0100 +Subject: [PATCH 173/190] drm/vc4: Set up SCALER_DISPCTRL at boot. + +We want the HVS on, obviously, and we also want DSP3 (PV1's source) to +be muxed from HVS channel 2 like we expect in vc4_crtc.c. The +firmware wasn't setting the DSP3 mux up when both the LCD and HDMI +were disabled. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_hvs.c | 14 ++++++++++++++ + drivers/gpu/drm/vc4/vc4_regs.h | 3 +++ + 2 files changed, 17 insertions(+) + +diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c +index 6fbab1c82cb1089bde0834f3e0bf1fdf99f54221..fc68b1b4da5249ce3181d7eabb0a08bf8e4908cf 100644 +--- a/drivers/gpu/drm/vc4/vc4_hvs.c ++++ b/drivers/gpu/drm/vc4/vc4_hvs.c +@@ -170,6 +170,7 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) + struct vc4_dev *vc4 = drm->dev_private; + struct vc4_hvs *hvs = NULL; + int ret; ++ u32 dispctrl; + + hvs = devm_kzalloc(&pdev->dev, sizeof(*hvs), GFP_KERNEL); + if (!hvs) +@@ -211,6 +212,19 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) + return ret; + + vc4->hvs = hvs; ++ ++ dispctrl = HVS_READ(SCALER_DISPCTRL); ++ ++ dispctrl |= SCALER_DISPCTRL_ENABLE; ++ ++ /* Set DSP3 (PV1) to use HVS channel 2, which would otherwise ++ * be unused. ++ */ ++ dispctrl &= ~SCALER_DISPCTRL_DSP3_MUX_MASK; ++ dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_DSP3_MUX); ++ ++ HVS_WRITE(SCALER_DISPCTRL, dispctrl); ++ + return 0; + } + +diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h +index 39f6886b24100c43b590e47e0c7bc44846721d65..b3b297fba7097bc495fa8916292c547925720199 100644 +--- a/drivers/gpu/drm/vc4/vc4_regs.h ++++ b/drivers/gpu/drm/vc4/vc4_regs.h +@@ -244,6 +244,9 @@ + # define SCALER_DISPCTRL_ENABLE BIT(31) + # define SCALER_DISPCTRL_DSP2EISLUR BIT(15) + # define SCALER_DISPCTRL_DSP1EISLUR BIT(14) ++# define SCALER_DISPCTRL_DSP3_MUX_MASK VC4_MASK(19, 18) ++# define SCALER_DISPCTRL_DSP3_MUX_SHIFT 18 ++ + /* Enables Display 0 short line and underrun contribution to + * SCALER_DISPSTAT_IRQDISP0. Note that short frame contributions are + * always enabled. + +From dd949d3de2e21d3772e3ef5b10dff39f5806174c Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 10 Feb 2016 16:17:29 -0800 +Subject: [PATCH 174/190] drm/vc4: Add support for feeding DSI encoders from + the pixel valve. + +We have to set a different pixel format, which tells the hardware to +use the pix_width field that's fed in sideband from the DSI encoder to +divide the "pixel" clock. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_crtc.c | 33 +++++++++++++++++++-------------- + drivers/gpu/drm/vc4/vc4_regs.h | 2 ++ + 2 files changed, 21 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c +index bdf32c572fc2c46932daca934dfb002d05493883..0a861158740586836d2d47cccae4109ad4ec968d 100644 +--- a/drivers/gpu/drm/vc4/vc4_crtc.c ++++ b/drivers/gpu/drm/vc4/vc4_crtc.c +@@ -352,38 +352,40 @@ static u32 vc4_get_fifo_full_level(u32 format) + } + + /* +- * Returns the clock select bit for the connector attached to the +- * CRTC. ++ * Returns the encoder attached to the CRTC. ++ * ++ * VC4 can only scan out to one encoder at a time, while the DRM core ++ * allows drivers to push pixels to more than one encoder from the ++ * same CRTC. + */ +-static int vc4_get_clock_select(struct drm_crtc *crtc) ++static struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc) + { + struct drm_connector *connector; + + drm_for_each_connector(connector, crtc->dev) { + if (connector->state->crtc == crtc) { +- struct drm_encoder *encoder = connector->encoder; +- struct vc4_encoder *vc4_encoder = +- to_vc4_encoder(encoder); +- +- return vc4_encoder->clock_select; ++ return connector->encoder; + } + } + +- return -1; ++ return NULL; + } + + static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc) + { + struct drm_device *dev = crtc->dev; + struct vc4_dev *vc4 = to_vc4_dev(dev); ++ struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc); ++ struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); + struct drm_crtc_state *state = crtc->state; + struct drm_display_mode *mode = &state->adjusted_mode; + bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE; + u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1; +- u32 format = PV_CONTROL_FORMAT_24; ++ bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 || ++ vc4_encoder->type == VC4_ENCODER_TYPE_DSI1); ++ u32 format = is_dsi ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24; + bool debug_dump_regs = false; +- int clock_select = vc4_get_clock_select(crtc); + + if (debug_dump_regs) { + DRM_INFO("CRTC %d regs before:\n", drm_crtc_index(crtc)); +@@ -439,17 +441,19 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc) + */ + CRTC_WRITE(PV_V_CONTROL, + PV_VCONTROL_CONTINUOUS | ++ (is_dsi ? PV_VCONTROL_DSI : 0) | + PV_VCONTROL_INTERLACE | + VC4_SET_FIELD(mode->htotal * pixel_rep / 2, + PV_VCONTROL_ODD_DELAY)); + CRTC_WRITE(PV_VSYNCD_EVEN, 0); + } else { +- CRTC_WRITE(PV_V_CONTROL, PV_VCONTROL_CONTINUOUS); ++ CRTC_WRITE(PV_V_CONTROL, ++ PV_VCONTROL_CONTINUOUS | ++ (is_dsi ? PV_VCONTROL_DSI : 0)); + } + + CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep); + +- + CRTC_WRITE(PV_CONTROL, + VC4_SET_FIELD(format, PV_CONTROL_FORMAT) | + VC4_SET_FIELD(vc4_get_fifo_full_level(format), +@@ -458,7 +462,8 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc) + PV_CONTROL_CLR_AT_START | + PV_CONTROL_TRIGGER_UNDERFLOW | + PV_CONTROL_WAIT_HSTART | +- VC4_SET_FIELD(clock_select, PV_CONTROL_CLK_SELECT) | ++ VC4_SET_FIELD(vc4_encoder->clock_select, ++ PV_CONTROL_CLK_SELECT) | + PV_CONTROL_FIFO_CLR | + PV_CONTROL_EN); + +diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h +index b3b297fba7097bc495fa8916292c547925720199..385405a2df05eb3dd86d4f687aa8205331bec3cc 100644 +--- a/drivers/gpu/drm/vc4/vc4_regs.h ++++ b/drivers/gpu/drm/vc4/vc4_regs.h +@@ -190,6 +190,8 @@ + # define PV_VCONTROL_ODD_DELAY_SHIFT 6 + # define PV_VCONTROL_ODD_FIRST BIT(5) + # define PV_VCONTROL_INTERLACE BIT(4) ++# define PV_VCONTROL_DSI BIT(3) ++# define PV_VCONTROL_COMMAND BIT(2) + # define PV_VCONTROL_CONTINUOUS BIT(1) + # define PV_VCONTROL_VIDEN BIT(0) + + +From a7210ce30157876d38751e4096358eae0345588d Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 10 Feb 2016 11:42:32 -0800 +Subject: [PATCH 175/190] drm/vc4: Add DSI driver + +The DSI0 and DSI1 blocks on the 2835 are related hardware blocks. +Some registers move around, and the featureset is slightly different, +as DSI1 (the 4-lane DSI) is a later version of the hardware block. +This driver doesn't yet enable DSI0, since we don't have any hardware +to test against, but it does put a lot of the register definitions and +code in place. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/Kconfig | 2 + + drivers/gpu/drm/vc4/Makefile | 1 + + drivers/gpu/drm/vc4/vc4_debugfs.c | 1 + + drivers/gpu/drm/vc4/vc4_drv.c | 1 + + drivers/gpu/drm/vc4/vc4_drv.h | 5 + + drivers/gpu/drm/vc4/vc4_dsi.c | 1725 +++++++++++++++++++++++++++++++++++++ + 6 files changed, 1735 insertions(+) + create mode 100644 drivers/gpu/drm/vc4/vc4_dsi.c + +diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig +index e53df59cb139f25f8e6ae916bca93abf0c49e063..e1517d07cb7d22776ca164a5d2d9b87e55a5563a 100644 +--- a/drivers/gpu/drm/vc4/Kconfig ++++ b/drivers/gpu/drm/vc4/Kconfig +@@ -2,10 +2,12 @@ config DRM_VC4 + tristate "Broadcom VC4 Graphics" + depends on ARCH_BCM2835 || COMPILE_TEST + depends on DRM ++ depends on COMMON_CLK + select DRM_KMS_HELPER + select DRM_KMS_CMA_HELPER + select DRM_GEM_CMA_HELPER + select DRM_PANEL ++ select DRM_MIPI_DSI + help + Choose this option if you have a system that has a Broadcom + VC4 GPU, such as the Raspberry Pi or other BCM2708/BCM2835. +diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile +index 3358ec8775cf6e8738ea8cdb2246dad57bd29139..897f658bee287f84f7dde8dca43090ad5541495b 100644 +--- a/drivers/gpu/drm/vc4/Makefile ++++ b/drivers/gpu/drm/vc4/Makefile +@@ -8,6 +8,7 @@ vc4-y := \ + vc4_crtc.o \ + vc4_drv.o \ + vc4_dpi.o \ ++ vc4_dsi.o \ + vc4_firmware_kms.o \ + vc4_kms.o \ + vc4_gem.o \ +diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c b/drivers/gpu/drm/vc4/vc4_debugfs.c +index caf817bac8852c82f0d6a34b676a649c10e6e6cd..3ca476c6e0578e5fbe60d4fd623b09f8f937c0b7 100644 +--- a/drivers/gpu/drm/vc4/vc4_debugfs.c ++++ b/drivers/gpu/drm/vc4/vc4_debugfs.c +@@ -18,6 +18,7 @@ + static const struct drm_info_list vc4_debugfs_list[] = { + {"bo_stats", vc4_bo_stats_debugfs, 0}, + {"dpi_regs", vc4_dpi_debugfs_regs, 0}, ++ {"dsi1_regs", vc4_dsi_debugfs_regs, 0, (void *)(uintptr_t)1}, + {"hdmi_regs", vc4_hdmi_debugfs_regs, 0}, + {"vec_regs", vc4_vec_debugfs_regs, 0}, + {"hvs_regs", vc4_hvs_debugfs_regs, 0}, +diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c +index 44cd22340d82dbd5d094806e777121951f25010a..8666c4f46f1fad3192613c39fbe3aeb07b86bc68 100644 +--- a/drivers/gpu/drm/vc4/vc4_drv.c ++++ b/drivers/gpu/drm/vc4/vc4_drv.c +@@ -296,6 +296,7 @@ static struct platform_driver *const component_drivers[] = { + &vc4_hdmi_driver, + &vc4_vec_driver, + &vc4_dpi_driver, ++ &vc4_dsi_driver, + &vc4_hvs_driver, + &vc4_crtc_driver, + &vc4_firmware_kms_driver, +diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h +index 61a9b3e81823a3c96f36f710329844cc032e2628..44a8e6fda2b576fed63d93ef34e076cebf90d64c 100644 +--- a/drivers/gpu/drm/vc4/vc4_drv.h ++++ b/drivers/gpu/drm/vc4/vc4_drv.h +@@ -20,6 +20,7 @@ struct vc4_dev { + struct vc4_crtc *crtc[3]; + struct vc4_v3d *v3d; + struct vc4_dpi *dpi; ++ struct vc4_dsi *dsi1; + struct vc4_vec *vec; + + struct drm_fbdev_cma *fbdev; +@@ -468,6 +469,10 @@ void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index); + extern struct platform_driver vc4_dpi_driver; + int vc4_dpi_debugfs_regs(struct seq_file *m, void *unused); + ++/* vc4_dsi.c */ ++extern struct platform_driver vc4_dsi_driver; ++int vc4_dsi_debugfs_regs(struct seq_file *m, void *unused); ++ + /* vc4_firmware_kms.c */ + extern struct platform_driver vc4_firmware_kms_driver; + void vc4_fkms_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file); +diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c +new file mode 100644 +index 0000000000000000000000000000000000000000..17fcac381dbb37cd9a5ff210ad8578f480177039 +--- /dev/null ++++ b/drivers/gpu/drm/vc4/vc4_dsi.c +@@ -0,0 +1,1725 @@ ++/* ++ * Copyright (C) 2016 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published by ++ * the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program. If not, see . ++ */ ++ ++/** ++ * DOC: VC4 DSI0/DSI1 module ++ * ++ * BCM2835 contains two DSI modules, DSI0 and DSI1. DSI0 is a ++ * single-lane DSI controller, while DSI1 is a more modern 4-lane DSI ++ * controller. ++ * ++ * Most Raspberry Pi boards expose DSI1 as their "DISPLAY" connector, ++ * while the compute module brings both DSI0 and DSI1 out. ++ * ++ * This driver has been tested for DSI1 video-mode display only ++ * currently, with most of the information necessary for DSI0 ++ * hopefully present. ++ */ ++ ++#include "drm_atomic_helper.h" ++#include "drm_crtc_helper.h" ++#include "drm_edid.h" ++#include "drm_mipi_dsi.h" ++#include "drm_panel.h" ++#include "linux/clk.h" ++#include "linux/clk-provider.h" ++#include "linux/completion.h" ++#include "linux/component.h" ++#include "linux/dmaengine.h" ++#include "linux/i2c.h" ++#include "linux/of_address.h" ++#include "linux/of_platform.h" ++#include "linux/pm_runtime.h" ++#include "vc4_drv.h" ++#include "vc4_regs.h" ++ ++#define DSI_CMD_FIFO_DEPTH 16 ++#define DSI_PIX_FIFO_DEPTH 256 ++#define DSI_PIX_FIFO_WIDTH 4 ++ ++#define DSI0_CTRL 0x00 ++ ++/* Command packet control. */ ++#define DSI0_TXPKT1C 0x04 /* AKA PKTC */ ++#define DSI1_TXPKT1C 0x04 ++# define DSI_TXPKT1C_TRIG_CMD_MASK VC4_MASK(31, 24) ++# define DSI_TXPKT1C_TRIG_CMD_SHIFT 24 ++# define DSI_TXPKT1C_CMD_REPEAT_MASK VC4_MASK(23, 10) ++# define DSI_TXPKT1C_CMD_REPEAT_SHIFT 10 ++ ++# define DSI_TXPKT1C_DISPLAY_NO_MASK VC4_MASK(9, 8) ++# define DSI_TXPKT1C_DISPLAY_NO_SHIFT 8 ++/* Short, trigger, BTA, or a long packet that fits all in CMDFIFO. */ ++# define DSI_TXPKT1C_DISPLAY_NO_SHORT 0 ++/* Primary display where cmdfifo provides part of the payload and ++ * pixelvalve the rest. ++ */ ++# define DSI_TXPKT1C_DISPLAY_NO_PRIMARY 1 ++/* Secondary display where cmdfifo provides part of the payload and ++ * pixfifo the rest. ++ */ ++# define DSI_TXPKT1C_DISPLAY_NO_SECONDARY 2 ++ ++# define DSI_TXPKT1C_CMD_TX_TIME_MASK VC4_MASK(7, 6) ++# define DSI_TXPKT1C_CMD_TX_TIME_SHIFT 6 ++ ++# define DSI_TXPKT1C_CMD_CTRL_MASK VC4_MASK(5, 4) ++# define DSI_TXPKT1C_CMD_CTRL_SHIFT 4 ++/* Command only. Uses TXPKT1H and DISPLAY_NO */ ++# define DSI_TXPKT1C_CMD_CTRL_TX 0 ++/* Command with BTA for either ack or read data. */ ++# define DSI_TXPKT1C_CMD_CTRL_RX 1 ++/* Trigger according to TRIG_CMD */ ++# define DSI_TXPKT1C_CMD_CTRL_TRIG 2 ++/* BTA alone for getting error status after a command, or a TE trigger ++ * without a previous command. ++ */ ++# define DSI_TXPKT1C_CMD_CTRL_BTA 3 ++ ++# define DSI_TXPKT1C_CMD_MODE_LP BIT(3) ++# define DSI_TXPKT1C_CMD_TYPE_LONG BIT(2) ++# define DSI_TXPKT1C_CMD_TE_EN BIT(1) ++# define DSI_TXPKT1C_CMD_EN BIT(0) ++ ++/* Command packet header. */ ++#define DSI0_TXPKT1H 0x08 /* AKA PKTH */ ++#define DSI1_TXPKT1H 0x08 ++# define DSI_TXPKT1H_BC_CMDFIFO_MASK VC4_MASK(31, 24) ++# define DSI_TXPKT1H_BC_CMDFIFO_SHIFT 24 ++# define DSI_TXPKT1H_BC_PARAM_MASK VC4_MASK(23, 8) ++# define DSI_TXPKT1H_BC_PARAM_SHIFT 8 ++# define DSI_TXPKT1H_BC_DT_MASK VC4_MASK(7, 0) ++# define DSI_TXPKT1H_BC_DT_SHIFT 0 ++ ++#define DSI0_RXPKT1H 0x0c /* AKA RX1_PKTH */ ++#define DSI1_RXPKT1H 0x14 ++# define DSI_RXPKT1H_CRC_ERR BIT(31) ++# define DSI_RXPKT1H_DET_ERR BIT(30) ++# define DSI_RXPKT1H_ECC_ERR BIT(29) ++# define DSI_RXPKT1H_COR_ERR BIT(28) ++# define DSI_RXPKT1H_INCOMP_PKT BIT(25) ++# define DSI_RXPKT1H_PKT_TYPE_LONG BIT(24) ++/* Byte count if DSI_RXPKT1H_PKT_TYPE_LONG */ ++# define DSI_RXPKT1H_BC_PARAM_MASK VC4_MASK(23, 8) ++# define DSI_RXPKT1H_BC_PARAM_SHIFT 8 ++/* Short return bytes if !DSI_RXPKT1H_PKT_TYPE_LONG */ ++# define DSI_RXPKT1H_SHORT_1_MASK VC4_MASK(23, 16) ++# define DSI_RXPKT1H_SHORT_1_SHIFT 16 ++# define DSI_RXPKT1H_SHORT_0_MASK VC4_MASK(15, 8) ++# define DSI_RXPKT1H_SHORT_0_SHIFT 8 ++# define DSI_RXPKT1H_DT_LP_CMD_MASK VC4_MASK(7, 0) ++# define DSI_RXPKT1H_DT_LP_CMD_SHIFT 0 ++ ++#define DSI0_RXPKT2H 0x10 /* AKA RX2_PKTH */ ++#define DSI1_RXPKT2H 0x18 ++# define DSI_RXPKT1H_DET_ERR BIT(30) ++# define DSI_RXPKT1H_ECC_ERR BIT(29) ++# define DSI_RXPKT1H_COR_ERR BIT(28) ++# define DSI_RXPKT1H_INCOMP_PKT BIT(25) ++# define DSI_RXPKT1H_BC_PARAM_MASK VC4_MASK(23, 8) ++# define DSI_RXPKT1H_BC_PARAM_SHIFT 8 ++# define DSI_RXPKT1H_DT_MASK VC4_MASK(7, 0) ++# define DSI_RXPKT1H_DT_SHIFT 0 ++ ++#define DSI0_TXPKT_CMD_FIFO 0x14 /* AKA CMD_DATAF */ ++#define DSI1_TXPKT_CMD_FIFO 0x1c ++ ++#define DSI0_DISP0_CTRL 0x18 ++# define DSI_DISP0_PIX_CLK_DIV_MASK VC4_MASK(21, 13) ++# define DSI_DISP0_PIX_CLK_DIV_SHIFT 13 ++# define DSI_DISP0_LP_STOP_CTRL_MASK VC4_MASK(12, 11) ++# define DSI_DISP0_LP_STOP_CTRL_SHIFT 11 ++# define DSI_DISP0_LP_STOP_DISABLE 0 ++# define DSI_DISP0_LP_STOP_PERLINE 1 ++# define DSI_DISP0_LP_STOP_PERFRAME 2 ++ ++/* Transmit RGB pixels and null packets only during HACTIVE, instead ++ * of going to LP-STOP. ++ */ ++# define DSI_DISP_HACTIVE_NULL BIT(10) ++/* Transmit blanking packet only during vblank, instead of allowing LP-STOP. */ ++# define DSI_DISP_VBLP_CTRL BIT(9) ++/* Transmit blanking packet only during HFP, instead of allowing LP-STOP. */ ++# define DSI_DISP_HFP_CTRL BIT(8) ++/* Transmit blanking packet only during HBP, instead of allowing LP-STOP. */ ++# define DSI_DISP_HBP_CTRL BIT(7) ++# define DSI_DISP0_CHANNEL_MASK VC4_MASK(6, 5) ++# define DSI_DISP0_CHANNEL_SHIFT 5 ++/* Enables end events for HSYNC/VSYNC, not just start events. */ ++# define DSI_DISP0_ST_END BIT(4) ++# define DSI_DISP0_PFORMAT_MASK VC4_MASK(3, 2) ++# define DSI_DISP0_PFORMAT_SHIFT 2 ++# define DSI_PFORMAT_RGB565 0 ++# define DSI_PFORMAT_RGB666_PACKED 1 ++# define DSI_PFORMAT_RGB666 2 ++# define DSI_PFORMAT_RGB888 3 ++/* Default is VIDEO mode. */ ++# define DSI_DISP0_COMMAND_MODE BIT(1) ++# define DSI_DISP0_ENABLE BIT(0) ++ ++#define DSI0_DISP1_CTRL 0x1c ++#define DSI1_DISP1_CTRL 0x2c ++/* Format of the data written to TXPKT_PIX_FIFO. */ ++# define DSI_DISP1_PFORMAT_MASK VC4_MASK(2, 1) ++# define DSI_DISP1_PFORMAT_SHIFT 1 ++# define DSI_DISP1_PFORMAT_16BIT 0 ++# define DSI_DISP1_PFORMAT_24BIT 1 ++# define DSI_DISP1_PFORMAT_32BIT_LE 2 ++# define DSI_DISP1_PFORMAT_32BIT_BE 3 ++ ++/* DISP1 is always command mode. */ ++# define DSI_DISP1_ENABLE BIT(0) ++ ++#define DSI0_TXPKT_PIX_FIFO 0x20 /* AKA PIX_FIFO */ ++ ++#define DSI0_INT_STAT 0x24 ++#define DSI0_INT_EN 0x28 ++# define DSI1_INT_PHY_D3_ULPS BIT(30) ++# define DSI1_INT_PHY_D3_STOP BIT(29) ++# define DSI1_INT_PHY_D2_ULPS BIT(28) ++# define DSI1_INT_PHY_D2_STOP BIT(27) ++# define DSI1_INT_PHY_D1_ULPS BIT(26) ++# define DSI1_INT_PHY_D1_STOP BIT(25) ++# define DSI1_INT_PHY_D0_ULPS BIT(24) ++# define DSI1_INT_PHY_D0_STOP BIT(23) ++# define DSI1_INT_FIFO_ERR BIT(22) ++# define DSI1_INT_PHY_DIR_RTF BIT(21) ++# define DSI1_INT_PHY_RXLPDT BIT(20) ++# define DSI1_INT_PHY_RXTRIG BIT(19) ++# define DSI1_INT_PHY_D0_LPDT BIT(18) ++# define DSI1_INT_PHY_DIR_FTR BIT(17) ++ ++/* Signaled when the clock lane enters the given state. */ ++# define DSI1_INT_PHY_CLOCK_ULPS BIT(16) ++# define DSI1_INT_PHY_CLOCK_HS BIT(15) ++# define DSI1_INT_PHY_CLOCK_STOP BIT(14) ++ ++/* Signaled on timeouts */ ++# define DSI1_INT_PR_TO BIT(13) ++# define DSI1_INT_TA_TO BIT(12) ++# define DSI1_INT_LPRX_TO BIT(11) ++# define DSI1_INT_HSTX_TO BIT(10) ++ ++/* Contention on a line when trying to drive the line low */ ++# define DSI1_INT_ERR_CONT_LP1 BIT(9) ++# define DSI1_INT_ERR_CONT_LP0 BIT(8) ++ ++/* Control error: incorrect line state sequence on data lane 0. */ ++# define DSI1_INT_ERR_CONTROL BIT(7) ++/* LPDT synchronization error (bits received not a multiple of 8. */ ++ ++# define DSI1_INT_ERR_SYNC_ESC BIT(6) ++/* Signaled after receiving an error packet from the display in ++ * response to a read. ++ */ ++# define DSI1_INT_RXPKT2 BIT(5) ++/* Signaled after receiving a packet. The header and optional short ++ * response will be in RXPKT1H, and a long response will be in the ++ * RXPKT_FIFO. ++ */ ++# define DSI1_INT_RXPKT1 BIT(4) ++# define DSI1_INT_TXPKT2_DONE BIT(3) ++# define DSI1_INT_TXPKT2_END BIT(2) ++/* Signaled after all repeats of TXPKT1 are transferred. */ ++# define DSI1_INT_TXPKT1_DONE BIT(1) ++/* Signaled after each TXPKT1 repeat is scheduled. */ ++# define DSI1_INT_TXPKT1_END BIT(0) ++ ++#define DSI1_INTERRUPTS_ALWAYS_ENABLED (DSI1_INT_ERR_SYNC_ESC | \ ++ DSI1_INT_ERR_CONTROL | \ ++ DSI1_INT_ERR_CONT_LP0 | \ ++ DSI1_INT_ERR_CONT_LP1 | \ ++ DSI1_INT_HSTX_TO | \ ++ DSI1_INT_LPRX_TO | \ ++ DSI1_INT_TA_TO | \ ++ DSI1_INT_PR_TO) ++ ++#define DSI0_STAT 0x2c ++#define DSI0_HSTX_TO_CNT 0x30 ++#define DSI0_LPRX_TO_CNT 0x34 ++#define DSI0_TA_TO_CNT 0x38 ++#define DSI0_PR_TO_CNT 0x3c ++#define DSI0_PHYC 0x40 ++# define DSI1_PHYC_ESC_CLK_LPDT_MASK VC4_MASK(25, 20) ++# define DSI1_PHYC_ESC_CLK_LPDT_SHIFT 20 ++# define DSI1_PHYC_HS_CLK_CONTINUOUS BIT(18) ++# define DSI0_PHYC_ESC_CLK_LPDT_MASK VC4_MASK(17, 12) ++# define DSI0_PHYC_ESC_CLK_LPDT_SHIFT 12 ++# define DSI1_PHYC_CLANE_ULPS BIT(17) ++# define DSI1_PHYC_CLANE_ENABLE BIT(16) ++# define DSI_PHYC_DLANE3_ULPS BIT(13) ++# define DSI_PHYC_DLANE3_ENABLE BIT(12) ++# define DSI0_PHYC_HS_CLK_CONTINUOUS BIT(10) ++# define DSI0_PHYC_CLANE_ULPS BIT(9) ++# define DSI_PHYC_DLANE2_ULPS BIT(9) ++# define DSI0_PHYC_CLANE_ENABLE BIT(8) ++# define DSI_PHYC_DLANE2_ENABLE BIT(8) ++# define DSI_PHYC_DLANE1_ULPS BIT(5) ++# define DSI_PHYC_DLANE1_ENABLE BIT(4) ++# define DSI_PHYC_DLANE0_FORCE_STOP BIT(2) ++# define DSI_PHYC_DLANE0_ULPS BIT(1) ++# define DSI_PHYC_DLANE0_ENABLE BIT(0) ++ ++#define DSI0_HS_CLT0 0x44 ++#define DSI0_HS_CLT1 0x48 ++#define DSI0_HS_CLT2 0x4c ++#define DSI0_HS_DLT3 0x50 ++#define DSI0_HS_DLT4 0x54 ++#define DSI0_HS_DLT5 0x58 ++#define DSI0_HS_DLT6 0x5c ++#define DSI0_HS_DLT7 0x60 ++ ++#define DSI0_PHY_AFEC0 0x64 ++# define DSI0_PHY_AFEC0_DDR2CLK_EN BIT(26) ++# define DSI0_PHY_AFEC0_DDRCLK_EN BIT(25) ++# define DSI0_PHY_AFEC0_LATCH_ULPS BIT(24) ++# define DSI1_PHY_AFEC0_IDR_DLANE3_MASK VC4_MASK(31, 29) ++# define DSI1_PHY_AFEC0_IDR_DLANE3_SHIFT 29 ++# define DSI1_PHY_AFEC0_IDR_DLANE2_MASK VC4_MASK(28, 26) ++# define DSI1_PHY_AFEC0_IDR_DLANE2_SHIFT 26 ++# define DSI1_PHY_AFEC0_IDR_DLANE1_MASK VC4_MASK(27, 23) ++# define DSI1_PHY_AFEC0_IDR_DLANE1_SHIFT 23 ++# define DSI1_PHY_AFEC0_IDR_DLANE0_MASK VC4_MASK(22, 20) ++# define DSI1_PHY_AFEC0_IDR_DLANE0_SHIFT 20 ++# define DSI1_PHY_AFEC0_IDR_CLANE_MASK VC4_MASK(19, 17) ++# define DSI1_PHY_AFEC0_IDR_CLANE_SHIFT 17 ++# define DSI0_PHY_AFEC0_ACTRL_DLANE1_MASK VC4_MASK(23, 20) ++# define DSI0_PHY_AFEC0_ACTRL_DLANE1_SHIFT 20 ++# define DSI0_PHY_AFEC0_ACTRL_DLANE0_MASK VC4_MASK(19, 16) ++# define DSI0_PHY_AFEC0_ACTRL_DLANE0_SHIFT 16 ++# define DSI0_PHY_AFEC0_ACTRL_CLANE_MASK VC4_MASK(15, 12) ++# define DSI0_PHY_AFEC0_ACTRL_CLANE_SHIFT 12 ++# define DSI1_PHY_AFEC0_DDR2CLK_EN BIT(16) ++# define DSI1_PHY_AFEC0_DDRCLK_EN BIT(15) ++# define DSI1_PHY_AFEC0_LATCH_ULPS BIT(14) ++# define DSI1_PHY_AFEC0_RESET BIT(13) ++# define DSI1_PHY_AFEC0_PD BIT(12) ++# define DSI0_PHY_AFEC0_RESET BIT(11) ++# define DSI1_PHY_AFEC0_PD_BG BIT(11) ++# define DSI0_PHY_AFEC0_PD BIT(10) ++# define DSI1_PHY_AFEC0_PD_DLANE3 BIT(10) ++# define DSI0_PHY_AFEC0_PD_BG BIT(9) ++# define DSI1_PHY_AFEC0_PD_DLANE2 BIT(9) ++# define DSI0_PHY_AFEC0_PD_DLANE1 BIT(8) ++# define DSI1_PHY_AFEC0_PD_DLANE1 BIT(8) ++# define DSI_PHY_AFEC0_PTATADJ_MASK VC4_MASK(7, 4) ++# define DSI_PHY_AFEC0_PTATADJ_SHIFT 4 ++# define DSI_PHY_AFEC0_CTATADJ_MASK VC4_MASK(3, 0) ++# define DSI_PHY_AFEC0_CTATADJ_SHIFT 0 ++ ++#define DSI0_PHY_AFEC1 0x68 ++# define DSI0_PHY_AFEC1_IDR_DLANE1_MASK VC4_MASK(10, 8) ++# define DSI0_PHY_AFEC1_IDR_DLANE1_SHIFT 8 ++# define DSI0_PHY_AFEC1_IDR_DLANE0_MASK VC4_MASK(6, 4) ++# define DSI0_PHY_AFEC1_IDR_DLANE0_SHIFT 4 ++# define DSI0_PHY_AFEC1_IDR_CLANE_MASK VC4_MASK(2, 0) ++# define DSI0_PHY_AFEC1_IDR_CLANE_SHIFT 0 ++ ++#define DSI0_TST_SEL 0x6c ++#define DSI0_TST_MON 0x70 ++#define DSI0_ID 0x74 ++# define DSI_ID_VALUE 0x00647369 ++ ++#define DSI1_CTRL 0x00 ++# define DSI_CTRL_HS_CLKC_MASK VC4_MASK(15, 14) ++# define DSI_CTRL_HS_CLKC_SHIFT 14 ++# define DSI_CTRL_HS_CLKC_BYTE 0 ++# define DSI_CTRL_HS_CLKC_DDR2 1 ++# define DSI_CTRL_HS_CLKC_DDR 2 ++ ++# define DSI_CTRL_RX_LPDT_EOT_DISABLE BIT(13) ++# define DSI_CTRL_LPDT_EOT_DISABLE BIT(12) ++# define DSI_CTRL_HSDT_EOT_DISABLE BIT(11) ++# define DSI_CTRL_SOFT_RESET_CFG BIT(10) ++# define DSI_CTRL_CAL_BYTE BIT(9) ++# define DSI_CTRL_INV_BYTE BIT(8) ++# define DSI_CTRL_CLR_LDF BIT(7) ++# define DSI0_CTRL_CLR_PBCF BIT(6) ++# define DSI1_CTRL_CLR_RXF BIT(6) ++# define DSI0_CTRL_CLR_CPBCF BIT(5) ++# define DSI1_CTRL_CLR_PDF BIT(5) ++# define DSI0_CTRL_CLR_PDF BIT(4) ++# define DSI1_CTRL_CLR_CDF BIT(4) ++# define DSI0_CTRL_CLR_CDF BIT(3) ++# define DSI0_CTRL_CTRL2 BIT(2) ++# define DSI1_CTRL_DISABLE_DISP_CRCC BIT(2) ++# define DSI0_CTRL_CTRL1 BIT(1) ++# define DSI1_CTRL_DISABLE_DISP_ECCC BIT(1) ++# define DSI0_CTRL_CTRL0 BIT(0) ++# define DSI1_CTRL_EN BIT(0) ++# define DSI0_CTRL_RESET_FIFOS (DSI_CTRL_CLR_LDF | \ ++ DSI0_CTRL_CLR_PBCF | \ ++ DSI0_CTRL_CLR_CPBCF | \ ++ DSI0_CTRL_CLR_PDF | \ ++ DSI0_CTRL_CLR_CDF) ++# define DSI1_CTRL_RESET_FIFOS (DSI_CTRL_CLR_LDF | \ ++ DSI1_CTRL_CLR_RXF | \ ++ DSI1_CTRL_CLR_PDF | \ ++ DSI1_CTRL_CLR_CDF) ++ ++#define DSI1_TXPKT2C 0x0c ++#define DSI1_TXPKT2H 0x10 ++#define DSI1_TXPKT_PIX_FIFO 0x20 ++#define DSI1_RXPKT_FIFO 0x24 ++#define DSI1_DISP0_CTRL 0x28 ++#define DSI1_INT_STAT 0x30 ++#define DSI1_INT_EN 0x34 ++/* State reporting bits. These mostly behave like INT_STAT, where ++ * writing a 1 clears the bit. ++ */ ++#define DSI1_STAT 0x38 ++# define DSI1_STAT_PHY_D3_ULPS BIT(31) ++# define DSI1_STAT_PHY_D3_STOP BIT(30) ++# define DSI1_STAT_PHY_D2_ULPS BIT(29) ++# define DSI1_STAT_PHY_D2_STOP BIT(28) ++# define DSI1_STAT_PHY_D1_ULPS BIT(27) ++# define DSI1_STAT_PHY_D1_STOP BIT(26) ++# define DSI1_STAT_PHY_D0_ULPS BIT(25) ++# define DSI1_STAT_PHY_D0_STOP BIT(24) ++# define DSI1_STAT_FIFO_ERR BIT(23) ++# define DSI1_STAT_PHY_RXLPDT BIT(22) ++# define DSI1_STAT_PHY_RXTRIG BIT(21) ++# define DSI1_STAT_PHY_D0_LPDT BIT(20) ++/* Set when in forward direction */ ++# define DSI1_STAT_PHY_DIR BIT(19) ++# define DSI1_STAT_PHY_CLOCK_ULPS BIT(18) ++# define DSI1_STAT_PHY_CLOCK_HS BIT(17) ++# define DSI1_STAT_PHY_CLOCK_STOP BIT(16) ++# define DSI1_STAT_PR_TO BIT(15) ++# define DSI1_STAT_TA_TO BIT(14) ++# define DSI1_STAT_LPRX_TO BIT(13) ++# define DSI1_STAT_HSTX_TO BIT(12) ++# define DSI1_STAT_ERR_CONT_LP1 BIT(11) ++# define DSI1_STAT_ERR_CONT_LP0 BIT(10) ++# define DSI1_STAT_ERR_CONTROL BIT(9) ++# define DSI1_STAT_ERR_SYNC_ESC BIT(8) ++# define DSI1_STAT_RXPKT2 BIT(7) ++# define DSI1_STAT_RXPKT1 BIT(6) ++# define DSI1_STAT_TXPKT2_BUSY BIT(5) ++# define DSI1_STAT_TXPKT2_DONE BIT(4) ++# define DSI1_STAT_TXPKT2_END BIT(3) ++# define DSI1_STAT_TXPKT1_BUSY BIT(2) ++# define DSI1_STAT_TXPKT1_DONE BIT(1) ++# define DSI1_STAT_TXPKT1_END BIT(0) ++ ++#define DSI1_HSTX_TO_CNT 0x3c ++#define DSI1_LPRX_TO_CNT 0x40 ++#define DSI1_TA_TO_CNT 0x44 ++#define DSI1_PR_TO_CNT 0x48 ++#define DSI1_PHYC 0x4c ++ ++#define DSI1_HS_CLT0 0x50 ++# define DSI_HS_CLT0_CZERO_MASK VC4_MASK(26, 18) ++# define DSI_HS_CLT0_CZERO_SHIFT 18 ++# define DSI_HS_CLT0_CPRE_MASK VC4_MASK(17, 9) ++# define DSI_HS_CLT0_CPRE_SHIFT 9 ++# define DSI_HS_CLT0_CPREP_MASK VC4_MASK(8, 0) ++# define DSI_HS_CLT0_CPREP_SHIFT 0 ++ ++#define DSI1_HS_CLT1 0x54 ++# define DSI_HS_CLT1_CTRAIL_MASK VC4_MASK(17, 9) ++# define DSI_HS_CLT1_CTRAIL_SHIFT 9 ++# define DSI_HS_CLT1_CPOST_MASK VC4_MASK(8, 0) ++# define DSI_HS_CLT1_CPOST_SHIFT 0 ++ ++#define DSI1_HS_CLT2 0x58 ++# define DSI_HS_CLT2_WUP_MASK VC4_MASK(23, 0) ++# define DSI_HS_CLT2_WUP_SHIFT 0 ++ ++#define DSI1_HS_DLT3 0x5c ++# define DSI_HS_DLT3_EXIT_MASK VC4_MASK(26, 18) ++# define DSI_HS_DLT3_EXIT_SHIFT 18 ++# define DSI_HS_DLT3_ZERO_MASK VC4_MASK(17, 9) ++# define DSI_HS_DLT3_ZERO_SHIFT 9 ++# define DSI_HS_DLT3_PRE_MASK VC4_MASK(8, 0) ++# define DSI_HS_DLT3_PRE_SHIFT 0 ++ ++#define DSI1_HS_DLT4 0x60 ++# define DSI_HS_DLT4_ANLAT_MASK VC4_MASK(22, 18) ++# define DSI_HS_DLT4_ANLAT_SHIFT 18 ++# define DSI_HS_DLT4_TRAIL_MASK VC4_MASK(17, 9) ++# define DSI_HS_DLT4_TRAIL_SHIFT 9 ++# define DSI_HS_DLT4_LPX_MASK VC4_MASK(8, 0) ++# define DSI_HS_DLT4_LPX_SHIFT 0 ++ ++#define DSI1_HS_DLT5 0x64 ++# define DSI_HS_DLT5_INIT_MASK VC4_MASK(23, 0) ++# define DSI_HS_DLT5_INIT_SHIFT 0 ++ ++#define DSI1_HS_DLT6 0x68 ++# define DSI_HS_DLT6_TA_GET_MASK VC4_MASK(31, 24) ++# define DSI_HS_DLT6_TA_GET_SHIFT 24 ++# define DSI_HS_DLT6_TA_SURE_MASK VC4_MASK(23, 16) ++# define DSI_HS_DLT6_TA_SURE_SHIFT 16 ++# define DSI_HS_DLT6_TA_GO_MASK VC4_MASK(15, 8) ++# define DSI_HS_DLT6_TA_GO_SHIFT 8 ++# define DSI_HS_DLT6_LP_LPX_MASK VC4_MASK(7, 0) ++# define DSI_HS_DLT6_LP_LPX_SHIFT 0 ++ ++#define DSI1_HS_DLT7 0x6c ++# define DSI_HS_DLT7_LP_WUP_MASK VC4_MASK(23, 0) ++# define DSI_HS_DLT7_LP_WUP_SHIFT 0 ++ ++#define DSI1_PHY_AFEC0 0x70 ++ ++#define DSI1_PHY_AFEC1 0x74 ++# define DSI1_PHY_AFEC1_ACTRL_DLANE3_MASK VC4_MASK(19, 16) ++# define DSI1_PHY_AFEC1_ACTRL_DLANE3_SHIFT 16 ++# define DSI1_PHY_AFEC1_ACTRL_DLANE2_MASK VC4_MASK(15, 12) ++# define DSI1_PHY_AFEC1_ACTRL_DLANE2_SHIFT 12 ++# define DSI1_PHY_AFEC1_ACTRL_DLANE1_MASK VC4_MASK(11, 8) ++# define DSI1_PHY_AFEC1_ACTRL_DLANE1_SHIFT 8 ++# define DSI1_PHY_AFEC1_ACTRL_DLANE0_MASK VC4_MASK(7, 4) ++# define DSI1_PHY_AFEC1_ACTRL_DLANE0_SHIFT 4 ++# define DSI1_PHY_AFEC1_ACTRL_CLANE_MASK VC4_MASK(3, 0) ++# define DSI1_PHY_AFEC1_ACTRL_CLANE_SHIFT 0 ++ ++#define DSI1_TST_SEL 0x78 ++#define DSI1_TST_MON 0x7c ++#define DSI1_PHY_TST1 0x80 ++#define DSI1_PHY_TST2 0x84 ++#define DSI1_PHY_FIFO_STAT 0x88 ++/* Actually, all registers in the range that aren't otherwise claimed ++ * will return the ID. ++ */ ++#define DSI1_ID 0x8c ++ ++/* General DSI hardware state. */ ++struct vc4_dsi { ++ struct platform_device *pdev; ++ ++ struct mipi_dsi_host dsi_host; ++ struct drm_encoder *encoder; ++ struct drm_connector *connector; ++ struct drm_panel *panel; ++ ++ void __iomem *regs; ++ ++ struct dma_chan *reg_dma_chan; ++ dma_addr_t reg_dma_paddr; ++ u32 *reg_dma_mem; ++ dma_addr_t reg_paddr; ++ ++ /* Whether we're on bcm2835's DSI0 or DSI1. */ ++ int port; ++ ++ /* DSI channel for the panel we're connected to. */ ++ u32 channel; ++ u32 lanes; ++ enum mipi_dsi_pixel_format format; ++ u32 mode_flags; ++ ++ /* Input clock from CPRMAN to the digital PHY, for the DSI ++ * escape clock. ++ */ ++ struct clk *escape_clock; ++ ++ /* Input clock to the analog PHY, used to generate the DSI bit ++ * clock. ++ */ ++ struct clk *pll_phy_clock; ++ ++ /* HS Clocks generated within the DSI analog PHY. */ ++ struct clk_fixed_factor phy_clocks[3]; ++ ++ struct clk_onecell_data clk_onecell; ++ ++ /* Pixel clock output to the pixelvalve, generated from the HS ++ * clock. ++ */ ++ struct clk *pixel_clock; ++ ++ struct completion xfer_completion; ++ int xfer_result; ++}; ++ ++#define host_to_dsi(host) container_of(host, struct vc4_dsi, dsi_host) ++ ++static inline void ++dsi_dma_workaround_write(struct vc4_dsi *dsi, u32 offset, u32 val) ++{ ++ struct dma_chan *chan = dsi->reg_dma_chan; ++ struct dma_async_tx_descriptor *tx; ++ dma_cookie_t cookie; ++ int ret; ++ ++ /* DSI0 should be able to write normally. */ ++ if (!chan) { ++ writel(val, dsi->regs + offset); ++ return; ++ } ++ ++ *dsi->reg_dma_mem = val; ++ ++ tx = chan->device->device_prep_dma_memcpy(chan, ++ dsi->reg_paddr + offset, ++ dsi->reg_dma_paddr, ++ 4, 0); ++ if (!tx) { ++ DRM_ERROR("Failed to set up DMA register write\n"); ++ return; ++ } ++ ++ cookie = tx->tx_submit(tx); ++ ret = dma_submit_error(cookie); ++ if (ret) { ++ DRM_ERROR("Failed to submit DMA: %d\n", ret); ++ return; ++ } ++ ret = dma_sync_wait(chan, cookie); ++ if (ret) ++ DRM_ERROR("Failed to wait for DMA: %d\n", ret); ++} ++ ++#define DSI_READ(offset) readl(dsi->regs + (offset)) ++#define DSI_WRITE(offset, val) dsi_dma_workaround_write(dsi, offset, val) ++#define DSI_PORT_READ(offset) \ ++ DSI_READ(dsi->port ? DSI1_##offset : DSI0_##offset) ++#define DSI_PORT_WRITE(offset, val) \ ++ DSI_WRITE(dsi->port ? DSI1_##offset : DSI0_##offset, val) ++#define DSI_PORT_BIT(bit) (dsi->port ? DSI1_##bit : DSI0_##bit) ++ ++/* VC4 DSI encoder KMS struct */ ++struct vc4_dsi_encoder { ++ struct vc4_encoder base; ++ struct vc4_dsi *dsi; ++}; ++ ++static inline struct vc4_dsi_encoder * ++to_vc4_dsi_encoder(struct drm_encoder *encoder) ++{ ++ return container_of(encoder, struct vc4_dsi_encoder, base.base); ++} ++ ++/* VC4 DSI connector KMS struct */ ++struct vc4_dsi_connector { ++ struct drm_connector base; ++ struct vc4_dsi *dsi; ++}; ++ ++static inline struct vc4_dsi_connector * ++to_vc4_dsi_connector(struct drm_connector *connector) ++{ ++ return container_of(connector, struct vc4_dsi_connector, base); ++} ++ ++#define DSI_REG(reg) { reg, #reg } ++static const struct { ++ u32 reg; ++ const char *name; ++} dsi0_regs[] = { ++ DSI_REG(DSI0_CTRL), ++ DSI_REG(DSI0_STAT), ++ DSI_REG(DSI0_HSTX_TO_CNT), ++ DSI_REG(DSI0_LPRX_TO_CNT), ++ DSI_REG(DSI0_TA_TO_CNT), ++ DSI_REG(DSI0_PR_TO_CNT), ++ DSI_REG(DSI0_DISP0_CTRL), ++ DSI_REG(DSI0_DISP1_CTRL), ++ DSI_REG(DSI0_INT_STAT), ++ DSI_REG(DSI0_INT_EN), ++ DSI_REG(DSI0_PHYC), ++ DSI_REG(DSI0_HS_CLT0), ++ DSI_REG(DSI0_HS_CLT1), ++ DSI_REG(DSI0_HS_CLT2), ++ DSI_REG(DSI0_HS_DLT3), ++ DSI_REG(DSI0_HS_DLT4), ++ DSI_REG(DSI0_HS_DLT5), ++ DSI_REG(DSI0_HS_DLT6), ++ DSI_REG(DSI0_HS_DLT7), ++ DSI_REG(DSI0_PHY_AFEC0), ++ DSI_REG(DSI0_PHY_AFEC1), ++ DSI_REG(DSI0_ID), ++}; ++ ++static const struct { ++ u32 reg; ++ const char *name; ++} dsi1_regs[] = { ++ DSI_REG(DSI1_CTRL), ++ DSI_REG(DSI1_STAT), ++ DSI_REG(DSI1_HSTX_TO_CNT), ++ DSI_REG(DSI1_LPRX_TO_CNT), ++ DSI_REG(DSI1_TA_TO_CNT), ++ DSI_REG(DSI1_PR_TO_CNT), ++ DSI_REG(DSI1_DISP0_CTRL), ++ DSI_REG(DSI1_DISP1_CTRL), ++ DSI_REG(DSI1_INT_STAT), ++ DSI_REG(DSI1_INT_EN), ++ DSI_REG(DSI1_PHYC), ++ DSI_REG(DSI1_HS_CLT0), ++ DSI_REG(DSI1_HS_CLT1), ++ DSI_REG(DSI1_HS_CLT2), ++ DSI_REG(DSI1_HS_DLT3), ++ DSI_REG(DSI1_HS_DLT4), ++ DSI_REG(DSI1_HS_DLT5), ++ DSI_REG(DSI1_HS_DLT6), ++ DSI_REG(DSI1_HS_DLT7), ++ DSI_REG(DSI1_PHY_AFEC0), ++ DSI_REG(DSI1_PHY_AFEC1), ++ DSI_REG(DSI1_ID), ++}; ++ ++static void vc4_dsi_dump_regs(struct vc4_dsi *dsi) ++{ ++ int i; ++ ++ if (dsi->port == 0) { ++ for (i = 0; i < ARRAY_SIZE(dsi0_regs); i++) { ++ DRM_INFO("0x%04x (%s): 0x%08x\n", ++ dsi0_regs[i].reg, dsi0_regs[i].name, ++ DSI_READ(dsi0_regs[i].reg)); ++ } ++ } else { ++ for (i = 0; i < ARRAY_SIZE(dsi1_regs); i++) { ++ DRM_INFO("0x%04x (%s): 0x%08x\n", ++ dsi1_regs[i].reg, dsi1_regs[i].name, ++ DSI_READ(dsi1_regs[i].reg)); ++ } ++ } ++} ++ ++#ifdef CONFIG_DEBUG_FS ++int vc4_dsi_debugfs_regs(struct seq_file *m, void *unused) ++{ ++ struct drm_info_node *node = (struct drm_info_node *)m->private; ++ struct drm_device *drm = node->minor->dev; ++ struct vc4_dev *vc4 = to_vc4_dev(drm); ++ int dsi_index = (uintptr_t)node->info_ent->data; ++ struct vc4_dsi *dsi = (dsi_index == 1 ? vc4->dsi1 : NULL); ++ int i; ++ ++ if (!dsi) ++ return 0; ++ ++ if (dsi->port == 0) { ++ for (i = 0; i < ARRAY_SIZE(dsi0_regs); i++) { ++ seq_printf(m, "0x%04x (%s): 0x%08x\n", ++ dsi0_regs[i].reg, dsi0_regs[i].name, ++ DSI_READ(dsi0_regs[i].reg)); ++ } ++ } else { ++ for (i = 0; i < ARRAY_SIZE(dsi1_regs); i++) { ++ seq_printf(m, "0x%04x (%s): 0x%08x\n", ++ dsi1_regs[i].reg, dsi1_regs[i].name, ++ DSI_READ(dsi1_regs[i].reg)); ++ } ++ } ++ ++ return 0; ++} ++#endif ++ ++static enum drm_connector_status ++vc4_dsi_connector_detect(struct drm_connector *connector, bool force) ++{ ++ struct vc4_dsi_connector *vc4_connector = ++ to_vc4_dsi_connector(connector); ++ struct vc4_dsi *dsi = vc4_connector->dsi; ++ ++ if (dsi->panel) ++ return connector_status_connected; ++ else ++ return connector_status_disconnected; ++} ++ ++static void vc4_dsi_connector_destroy(struct drm_connector *connector) ++{ ++ drm_connector_unregister(connector); ++ drm_connector_cleanup(connector); ++} ++ ++static int vc4_dsi_connector_get_modes(struct drm_connector *connector) ++{ ++ struct vc4_dsi_connector *vc4_connector = ++ to_vc4_dsi_connector(connector); ++ struct vc4_dsi *dsi = vc4_connector->dsi; ++ ++ if (dsi->panel) ++ return drm_panel_get_modes(dsi->panel); ++ ++ return 0; ++} ++ ++static const struct drm_connector_funcs vc4_dsi_connector_funcs = { ++ .dpms = drm_atomic_helper_connector_dpms, ++ .detect = vc4_dsi_connector_detect, ++ .fill_modes = drm_helper_probe_single_connector_modes, ++ .destroy = vc4_dsi_connector_destroy, ++ .reset = drm_atomic_helper_connector_reset, ++ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, ++ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, ++}; ++ ++static const struct drm_connector_helper_funcs vc4_dsi_connector_helper_funcs = { ++ .get_modes = vc4_dsi_connector_get_modes, ++}; ++ ++static struct drm_connector *vc4_dsi_connector_init(struct drm_device *dev, ++ struct vc4_dsi *dsi) ++{ ++ struct drm_connector *connector = NULL; ++ struct vc4_dsi_connector *dsi_connector; ++ int ret = 0; ++ ++ dsi_connector = devm_kzalloc(dev->dev, sizeof(*dsi_connector), ++ GFP_KERNEL); ++ if (!dsi_connector) { ++ ret = -ENOMEM; ++ goto fail; ++ } ++ connector = &dsi_connector->base; ++ ++ dsi_connector->dsi = dsi; ++ ++ drm_connector_init(dev, connector, &vc4_dsi_connector_funcs, ++ DRM_MODE_CONNECTOR_DSI); ++ drm_connector_helper_add(connector, &vc4_dsi_connector_helper_funcs); ++ ++ connector->polled = 0; ++ connector->interlace_allowed = 0; ++ connector->doublescan_allowed = 0; ++ ++ drm_mode_connector_attach_encoder(connector, dsi->encoder); ++ ++ return connector; ++ ++fail: ++ if (connector) ++ vc4_dsi_connector_destroy(connector); ++ ++ return ERR_PTR(ret); ++} ++ ++static void vc4_dsi_encoder_destroy(struct drm_encoder *encoder) ++{ ++ drm_encoder_cleanup(encoder); ++} ++ ++static const struct drm_encoder_funcs vc4_dsi_encoder_funcs = { ++ .destroy = vc4_dsi_encoder_destroy, ++}; ++ ++static void vc4_dsi_latch_ulps(struct vc4_dsi *dsi, bool latch) ++{ ++ u32 afec0 = DSI_PORT_READ(PHY_AFEC0); ++ ++ if (latch) ++ afec0 |= DSI_PORT_BIT(PHY_AFEC0_LATCH_ULPS); ++ else ++ afec0 &= ~DSI_PORT_BIT(PHY_AFEC0_LATCH_ULPS); ++ ++ DSI_PORT_WRITE(PHY_AFEC0, afec0); ++} ++ ++/* Enters or exits Ultra Low Power State. */ ++static void vc4_dsi_ulps(struct vc4_dsi *dsi, bool ulps) ++{ ++ bool continuous = dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS; ++ u32 phyc_ulps = ((continuous ? DSI_PORT_BIT(PHYC_CLANE_ULPS) : 0) | ++ DSI_PHYC_DLANE0_ULPS | ++ (dsi->lanes > 1 ? DSI_PHYC_DLANE1_ULPS : 0) | ++ (dsi->lanes > 2 ? DSI_PHYC_DLANE2_ULPS : 0) | ++ (dsi->lanes > 3 ? DSI_PHYC_DLANE3_ULPS : 0)); ++ u32 stat_ulps = ((continuous ? DSI1_STAT_PHY_CLOCK_ULPS : 0) | ++ DSI1_STAT_PHY_D0_ULPS | ++ (dsi->lanes > 1 ? DSI1_STAT_PHY_D1_ULPS : 0) | ++ (dsi->lanes > 2 ? DSI1_STAT_PHY_D2_ULPS : 0) | ++ (dsi->lanes > 3 ? DSI1_STAT_PHY_D3_ULPS : 0)); ++ u32 stat_stop = ((continuous ? DSI1_STAT_PHY_CLOCK_STOP : 0) | ++ DSI1_STAT_PHY_D0_STOP | ++ (dsi->lanes > 1 ? DSI1_STAT_PHY_D1_STOP : 0) | ++ (dsi->lanes > 2 ? DSI1_STAT_PHY_D2_STOP : 0) | ++ (dsi->lanes > 3 ? DSI1_STAT_PHY_D3_STOP : 0)); ++ int ret; ++ ++ DSI_PORT_WRITE(STAT, stat_ulps); ++ DSI_PORT_WRITE(PHYC, DSI_PORT_READ(PHYC) | phyc_ulps); ++ ret = wait_for((DSI_PORT_READ(STAT) & stat_ulps) == stat_ulps, 200); ++ if (ret) { ++ dev_warn(&dsi->pdev->dev, ++ "Timeout waiting for DSI ULPS entry: STAT 0x%08x", ++ DSI_PORT_READ(STAT)); ++ DSI_PORT_WRITE(PHYC, DSI_PORT_READ(PHYC) & ~phyc_ulps); ++ vc4_dsi_latch_ulps(dsi, false); ++ return; ++ } ++ ++ /* The DSI module can't be disabled while the module is ++ * generating ULPS state. So, to be able to disable the ++ * module, we have the AFE latch the ULPS state and continue ++ * on to having the module enter STOP. ++ */ ++ vc4_dsi_latch_ulps(dsi, ulps); ++ ++ DSI_PORT_WRITE(STAT, stat_stop); ++ DSI_PORT_WRITE(PHYC, DSI_PORT_READ(PHYC) & ~phyc_ulps); ++ ret = wait_for((DSI_PORT_READ(STAT) & stat_stop) == stat_stop, 200); ++ if (ret) { ++ dev_warn(&dsi->pdev->dev, ++ "Timeout waiting for DSI STOP entry: STAT 0x%08x", ++ DSI_PORT_READ(STAT)); ++ DSI_PORT_WRITE(PHYC, DSI_PORT_READ(PHYC) & ~phyc_ulps); ++ return; ++ } ++} ++ ++static u32 ++dsi_hs_timing(u32 ui_ns, u32 ns, u32 ui) ++{ ++ /* The HS timings have to be rounded up to a multiple of 8 ++ * because we're using the byte clock. ++ */ ++ return roundup(ui + DIV_ROUND_UP(ns, ui_ns), 8); ++} ++ ++/* ESC always runs at 100Mhz. */ ++#define ESC_TIME_NS 10 ++ ++static u32 ++dsi_esc_timing(u32 ns) ++{ ++ return DIV_ROUND_UP(ns, ESC_TIME_NS); ++} ++ ++static void vc4_dsi_encoder_disable(struct drm_encoder *encoder) ++{ ++ struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder); ++ struct vc4_dsi *dsi = vc4_encoder->dsi; ++ struct device *dev = &dsi->pdev->dev; ++ ++ drm_panel_disable(dsi->panel); ++ ++ vc4_dsi_ulps(dsi, true); ++ ++ drm_panel_unprepare(dsi->panel); ++ ++ clk_disable_unprepare(dsi->pll_phy_clock); ++ clk_disable_unprepare(dsi->escape_clock); ++ clk_disable_unprepare(dsi->pixel_clock); ++ ++ pm_runtime_put(dev); ++} ++ ++static void vc4_dsi_encoder_enable(struct drm_encoder *encoder) ++{ ++ struct drm_display_mode *mode = &encoder->crtc->mode; ++ struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder); ++ struct vc4_dsi *dsi = vc4_encoder->dsi; ++ struct device *dev = &dsi->pdev->dev; ++ u32 format = 0, divider = 0; ++ bool debug_dump_regs = false; ++ unsigned long hs_clock; ++ u32 ui_ns; ++ /* Minimum LP state duration in escape clock cycles. */ ++ u32 lpx = dsi_esc_timing(60); ++ unsigned long pixel_clock_hz = mode->clock * 1000; ++ unsigned long dsip_clock; ++ unsigned long phy_clock; ++ int ret; ++ ++ ret = pm_runtime_get_sync(dev); ++ if (ret) { ++ DRM_ERROR("Failed to runtime PM enable on DSI%d\n", dsi->port); ++ return; ++ } ++ ++ ret = drm_panel_prepare(dsi->panel); ++ if (ret) { ++ DRM_ERROR("Panel failed to prepare\n"); ++ return; ++ } ++ ++ if (debug_dump_regs) { ++ DRM_INFO("DSI regs before:\n"); ++ vc4_dsi_dump_regs(dsi); ++ } ++ ++ switch (dsi->format) { ++ case MIPI_DSI_FMT_RGB888: ++ format = DSI_PFORMAT_RGB888; ++ divider = 24 / dsi->lanes; ++ break; ++ case MIPI_DSI_FMT_RGB666: ++ format = DSI_PFORMAT_RGB666; ++ divider = 24 / dsi->lanes; ++ break; ++ case MIPI_DSI_FMT_RGB666_PACKED: ++ format = DSI_PFORMAT_RGB666_PACKED; ++ divider = 18 / dsi->lanes; ++ break; ++ case MIPI_DSI_FMT_RGB565: ++ format = DSI_PFORMAT_RGB565; ++ divider = 16 / dsi->lanes; ++ break; ++ } ++ ++ phy_clock = pixel_clock_hz * divider; ++ ret = clk_set_rate(dsi->pll_phy_clock, phy_clock); ++ if (ret) { ++ dev_err(&dsi->pdev->dev, ++ "Failed to set phy clock to %ld: %d\n", phy_clock, ret); ++ } ++ ++ /* Reset the DSI and all its fifos. */ ++ DSI_PORT_WRITE(CTRL, ++ DSI_CTRL_SOFT_RESET_CFG | ++ DSI_PORT_BIT(CTRL_RESET_FIFOS)); ++ ++ DSI_PORT_WRITE(CTRL, ++ DSI_CTRL_HSDT_EOT_DISABLE | ++ DSI_CTRL_RX_LPDT_EOT_DISABLE); ++ ++ /* Clear all stat bits so we see what has happened during enable. */ ++ DSI_PORT_WRITE(STAT, DSI_PORT_READ(STAT)); ++ ++ /* Set AFE CTR00/CTR1 to release powerdown of analog. */ ++ if (dsi->port == 0) { ++ u32 afec0 = (VC4_SET_FIELD(7, DSI_PHY_AFEC0_PTATADJ) | ++ VC4_SET_FIELD(7, DSI_PHY_AFEC0_CTATADJ)); ++ ++ if (dsi->lanes < 2) ++ afec0 |= DSI0_PHY_AFEC0_PD_DLANE1; ++ ++ if (!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO)) ++ afec0 |= DSI0_PHY_AFEC0_RESET; ++ ++ DSI_PORT_WRITE(PHY_AFEC0, afec0); ++ ++ DSI_PORT_WRITE(PHY_AFEC1, ++ VC4_SET_FIELD(6, DSI0_PHY_AFEC1_IDR_DLANE1) | ++ VC4_SET_FIELD(6, DSI0_PHY_AFEC1_IDR_DLANE0) | ++ VC4_SET_FIELD(6, DSI0_PHY_AFEC1_IDR_CLANE)); ++ } else { ++ u32 afec0 = (VC4_SET_FIELD(7, DSI_PHY_AFEC0_PTATADJ) | ++ VC4_SET_FIELD(7, DSI_PHY_AFEC0_CTATADJ) | ++ VC4_SET_FIELD(6, DSI1_PHY_AFEC0_IDR_CLANE) | ++ VC4_SET_FIELD(6, DSI1_PHY_AFEC0_IDR_DLANE0) | ++ VC4_SET_FIELD(6, DSI1_PHY_AFEC0_IDR_DLANE1) | ++ VC4_SET_FIELD(6, DSI1_PHY_AFEC0_IDR_DLANE2) | ++ VC4_SET_FIELD(6, DSI1_PHY_AFEC0_IDR_DLANE3)); ++ ++ if (dsi->lanes < 4) ++ afec0 |= DSI1_PHY_AFEC0_PD_DLANE3; ++ if (dsi->lanes < 3) ++ afec0 |= DSI1_PHY_AFEC0_PD_DLANE2; ++ if (dsi->lanes < 2) ++ afec0 |= DSI1_PHY_AFEC0_PD_DLANE1; ++ ++ afec0 |= DSI1_PHY_AFEC0_RESET; ++ ++ DSI_PORT_WRITE(PHY_AFEC0, afec0); ++ ++ DSI_PORT_WRITE(PHY_AFEC1, 0); ++ ++ /* AFEC reset hold time */ ++ mdelay(1); ++ } ++ ++ ret = clk_prepare_enable(dsi->escape_clock); ++ if (ret) { ++ DRM_ERROR("Failed to turn on DSI escape clock: %d\n", ret); ++ return; ++ } ++ ++ ret = clk_prepare_enable(dsi->pll_phy_clock); ++ if (ret) { ++ DRM_ERROR("Failed to turn on DSI PLL: %d\n", ret); ++ return; ++ } ++ ++ hs_clock = clk_get_rate(dsi->pll_phy_clock); ++ ++ /* Yes, we set the DSI0P/DSI1P pixel clock to the byte rate, ++ * not the pixel clock rate. DSIxP take from the APHY's byte, ++ * DDR2, or DDR4 clock (we use byte) and feed into the PV at ++ * that rate. Separately, a value derived from PIX_CLK_DIV ++ * and HS_CLKC is fed into the PV to divide down to the actual ++ * pixel clock for pushing pixels into DSI. ++ */ ++ dsip_clock = phy_clock / 8; ++ ret = clk_set_rate(dsi->pixel_clock, dsip_clock); ++ if (ret) { ++ dev_err(dev, "Failed to set pixel clock to %ldHz: %d\n", ++ dsip_clock, ret); ++ } ++ ++ ret = clk_prepare_enable(dsi->pixel_clock); ++ if (ret) { ++ DRM_ERROR("Failed to turn on DSI pixel clock: %d\n", ret); ++ return; ++ } ++ ++ /* How many ns one DSI unit interval is. Note that the clock ++ * is DDR, so there's an extra divide by 2. ++ */ ++ ui_ns = DIV_ROUND_UP(500000000, hs_clock); ++ ++ DSI_PORT_WRITE(HS_CLT0, ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 262, 0), ++ DSI_HS_CLT0_CZERO) | ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 0, 8), ++ DSI_HS_CLT0_CPRE) | ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 38, 0), ++ DSI_HS_CLT0_CPREP)); ++ ++ DSI_PORT_WRITE(HS_CLT1, ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 60, 0), ++ DSI_HS_CLT1_CTRAIL) | ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 60, 52), ++ DSI_HS_CLT1_CPOST)); ++ ++ DSI_PORT_WRITE(HS_CLT2, ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 1000000, 0), ++ DSI_HS_CLT2_WUP)); ++ ++ DSI_PORT_WRITE(HS_DLT3, ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 100, 0), ++ DSI_HS_DLT3_EXIT) | ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 105, 6), ++ DSI_HS_DLT3_ZERO) | ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 40, 4), ++ DSI_HS_DLT3_PRE)); ++ ++ DSI_PORT_WRITE(HS_DLT4, ++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, lpx * ESC_TIME_NS, 0), ++ DSI_HS_DLT4_LPX) | ++ VC4_SET_FIELD(max(dsi_hs_timing(ui_ns, 0, 8), ++ dsi_hs_timing(ui_ns, 60, 4)), ++ DSI_HS_DLT4_TRAIL) | ++ VC4_SET_FIELD(0, DSI_HS_DLT4_ANLAT)); ++ ++ DSI_PORT_WRITE(HS_DLT5, VC4_SET_FIELD(dsi_hs_timing(ui_ns, 1000, 5000), ++ DSI_HS_DLT5_INIT)); ++ ++ DSI_PORT_WRITE(HS_DLT6, ++ VC4_SET_FIELD(lpx * 5, DSI_HS_DLT6_TA_GET) | ++ VC4_SET_FIELD(lpx, DSI_HS_DLT6_TA_SURE) | ++ VC4_SET_FIELD(lpx * 4, DSI_HS_DLT6_TA_GO) | ++ VC4_SET_FIELD(lpx, DSI_HS_DLT6_LP_LPX)); ++ ++ DSI_PORT_WRITE(HS_DLT7, ++ VC4_SET_FIELD(dsi_esc_timing(1000000), ++ DSI_HS_DLT7_LP_WUP)); ++ ++ DSI_PORT_WRITE(PHYC, ++ DSI_PHYC_DLANE0_ENABLE | ++ (dsi->lanes >= 2 ? DSI_PHYC_DLANE1_ENABLE : 0) | ++ (dsi->lanes >= 3 ? DSI_PHYC_DLANE2_ENABLE : 0) | ++ (dsi->lanes >= 4 ? DSI_PHYC_DLANE3_ENABLE : 0) | ++ DSI_PORT_BIT(PHYC_CLANE_ENABLE) | ++ ((dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) ? ++ 0 : DSI_PORT_BIT(PHYC_HS_CLK_CONTINUOUS)) | ++ (dsi->port == 0 ? ++ VC4_SET_FIELD(lpx - 1, DSI0_PHYC_ESC_CLK_LPDT) : ++ VC4_SET_FIELD(lpx - 1, DSI1_PHYC_ESC_CLK_LPDT))); ++ ++ DSI_PORT_WRITE(CTRL, ++ DSI_PORT_READ(CTRL) | ++ DSI_CTRL_CAL_BYTE); ++ ++ /* HS timeout in HS clock cycles: disabled. */ ++ DSI_PORT_WRITE(HSTX_TO_CNT, 0); ++ /* LP receive timeout in HS clocks. */ ++ DSI_PORT_WRITE(LPRX_TO_CNT, 0xffffff); ++ /* Bus turnaround timeout */ ++ DSI_PORT_WRITE(TA_TO_CNT, 100000); ++ /* Display reset sequence timeout */ ++ DSI_PORT_WRITE(PR_TO_CNT, 100000); ++ ++ if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) { ++ DSI_PORT_WRITE(DISP0_CTRL, ++ VC4_SET_FIELD(divider, DSI_DISP0_PIX_CLK_DIV) | ++ VC4_SET_FIELD(format, DSI_DISP0_PFORMAT) | ++ VC4_SET_FIELD(DSI_DISP0_LP_STOP_PERFRAME, ++ DSI_DISP0_LP_STOP_CTRL) | ++ DSI_DISP0_ST_END | ++ DSI_DISP0_ENABLE); ++ } else { ++ DSI_PORT_WRITE(DISP0_CTRL, ++ DSI_DISP0_COMMAND_MODE | ++ DSI_DISP0_ENABLE); ++ } ++ ++ /* Set up DISP1 for transferring long command payloads through ++ * the pixfifo. ++ */ ++ DSI_PORT_WRITE(DISP1_CTRL, ++ VC4_SET_FIELD(DSI_DISP1_PFORMAT_32BIT_LE, ++ DSI_DISP1_PFORMAT) | ++ DSI_DISP1_ENABLE); ++ ++ /* Ungate the block. */ ++ if (dsi->port == 0) ++ DSI_PORT_WRITE(CTRL, DSI_PORT_READ(CTRL) | DSI0_CTRL_CTRL0); ++ else ++ DSI_PORT_WRITE(CTRL, DSI_PORT_READ(CTRL) | DSI1_CTRL_EN); ++ ++ /* Bring AFE out of reset. */ ++ if (dsi->port == 0) { ++ } else { ++ DSI_PORT_WRITE(PHY_AFEC0, ++ DSI_PORT_READ(PHY_AFEC0) & ++ ~DSI1_PHY_AFEC0_RESET); ++ } ++ ++ vc4_dsi_ulps(dsi, false); ++ ++ if (debug_dump_regs) { ++ DRM_INFO("DSI regs after:\n"); ++ vc4_dsi_dump_regs(dsi); ++ } ++ ++ ret = drm_panel_enable(dsi->panel); ++ if (ret) { ++ DRM_ERROR("Panel failed to enable\n"); ++ drm_panel_unprepare(dsi->panel); ++ return; ++ } ++} ++ ++static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host, ++ const struct mipi_dsi_msg *msg) ++{ ++ struct vc4_dsi *dsi = host_to_dsi(host); ++ struct mipi_dsi_packet packet; ++ u32 pkth = 0, pktc = 0; ++ int i, ret; ++ bool is_long = mipi_dsi_packet_format_is_long(msg->type); ++ u32 cmd_fifo_len = 0, pix_fifo_len = 0; ++ ++ mipi_dsi_create_packet(&packet, msg); ++ ++ pkth |= VC4_SET_FIELD(packet.header[0], DSI_TXPKT1H_BC_DT); ++ pkth |= VC4_SET_FIELD(packet.header[1] | ++ (packet.header[2] << 8), ++ DSI_TXPKT1H_BC_PARAM); ++ if (is_long) { ++ /* Divide data across the various FIFOs we have available. ++ * The command FIFO takes byte-oriented data, but is of ++ * limited size. The pixel FIFO (never actually used for ++ * pixel data in reality) is word oriented, and substantially ++ * larger. So, we use the pixel FIFO for most of the data, ++ * sending the residual bytes in the command FIFO at the start. ++ * ++ * With this arrangement, the command FIFO will never get full. ++ */ ++ if (packet.payload_length <= 16) { ++ cmd_fifo_len = packet.payload_length; ++ pix_fifo_len = 0; ++ } else { ++ cmd_fifo_len = (packet.payload_length % ++ DSI_PIX_FIFO_WIDTH); ++ pix_fifo_len = ((packet.payload_length - cmd_fifo_len) / ++ DSI_PIX_FIFO_WIDTH); ++ } ++ ++ WARN_ON_ONCE(pix_fifo_len >= DSI_PIX_FIFO_DEPTH); ++ ++ pkth |= VC4_SET_FIELD(cmd_fifo_len, DSI_TXPKT1H_BC_CMDFIFO); ++ } ++ ++ if (msg->rx_len) { ++ pktc |= VC4_SET_FIELD(DSI_TXPKT1C_CMD_CTRL_RX, ++ DSI_TXPKT1C_CMD_CTRL); ++ } else { ++ pktc |= VC4_SET_FIELD(DSI_TXPKT1C_CMD_CTRL_TX, ++ DSI_TXPKT1C_CMD_CTRL); ++ } ++ ++ for (i = 0; i < cmd_fifo_len; i++) ++ DSI_PORT_WRITE(TXPKT_CMD_FIFO, packet.payload[i]); ++ for (i = 0; i < pix_fifo_len; i++) { ++ const u8 *pix = packet.payload + cmd_fifo_len + i * 4; ++ ++ DSI_PORT_WRITE(TXPKT_PIX_FIFO, ++ pix[0] | ++ pix[1] << 8 | ++ pix[2] << 16 | ++ pix[3] << 24); ++ } ++ ++ if (msg->flags & MIPI_DSI_MSG_USE_LPM) ++ pktc |= DSI_TXPKT1C_CMD_MODE_LP; ++ if (is_long) ++ pktc |= DSI_TXPKT1C_CMD_TYPE_LONG; ++ ++ /* Send one copy of the packet. Larger repeats are used for pixel ++ * data in command mode. ++ */ ++ pktc |= VC4_SET_FIELD(1, DSI_TXPKT1C_CMD_REPEAT); ++ ++ pktc |= DSI_TXPKT1C_CMD_EN; ++ if (pix_fifo_len) { ++ pktc |= VC4_SET_FIELD(DSI_TXPKT1C_DISPLAY_NO_SECONDARY, ++ DSI_TXPKT1C_DISPLAY_NO); ++ } else { ++ pktc |= VC4_SET_FIELD(DSI_TXPKT1C_DISPLAY_NO_SHORT, ++ DSI_TXPKT1C_DISPLAY_NO); ++ } ++ ++ /* Enable the appropriate interrupt for the transfer completion. */ ++ dsi->xfer_result = 0; ++ reinit_completion(&dsi->xfer_completion); ++ DSI_PORT_WRITE(INT_STAT, DSI1_INT_TXPKT1_DONE | DSI1_INT_PHY_DIR_RTF); ++ if (msg->rx_len) { ++ DSI_PORT_WRITE(INT_EN, (DSI1_INTERRUPTS_ALWAYS_ENABLED | ++ DSI1_INT_PHY_DIR_RTF)); ++ } else { ++ DSI_PORT_WRITE(INT_EN, (DSI1_INTERRUPTS_ALWAYS_ENABLED | ++ DSI1_INT_TXPKT1_DONE)); ++ } ++ ++ /* Send the packet. */ ++ DSI_PORT_WRITE(TXPKT1H, pkth); ++ DSI_PORT_WRITE(TXPKT1C, pktc); ++ ++ if (!wait_for_completion_timeout(&dsi->xfer_completion, ++ msecs_to_jiffies(1000))) { ++ dev_err(&dsi->pdev->dev, "transfer interrupt wait timeout"); ++ dev_err(&dsi->pdev->dev, "instat: 0x%08x\n", ++ DSI_PORT_READ(INT_STAT)); ++ ret = -ETIMEDOUT; ++ } else { ++ ret = dsi->xfer_result; ++ } ++ ++ DSI_PORT_WRITE(INT_EN, DSI1_INTERRUPTS_ALWAYS_ENABLED); ++ ++ if (ret) ++ goto reset_fifo_and_return; ++ ++ if (ret == 0 && msg->rx_len) { ++ u32 rxpkt1h = DSI_PORT_READ(RXPKT1H); ++ u8 *msg_rx = msg->rx_buf; ++ ++ if (rxpkt1h & DSI_RXPKT1H_PKT_TYPE_LONG) { ++ u32 rxlen = VC4_GET_FIELD(rxpkt1h, ++ DSI_RXPKT1H_BC_PARAM); ++ ++ if (rxlen != msg->rx_len) { ++ DRM_ERROR("DSI returned %db, expecting %db\n", ++ rxlen, (int)msg->rx_len); ++ ret = -ENXIO; ++ goto reset_fifo_and_return; ++ } ++ ++ for (i = 0; i < msg->rx_len; i++) ++ msg_rx[i] = DSI_READ(DSI1_RXPKT_FIFO); ++ } else { ++ /* FINISHME: Handle AWER */ ++ ++ msg_rx[0] = VC4_GET_FIELD(rxpkt1h, ++ DSI_RXPKT1H_SHORT_0); ++ if (msg->rx_len > 1) { ++ msg_rx[1] = VC4_GET_FIELD(rxpkt1h, ++ DSI_RXPKT1H_SHORT_1); ++ } ++ } ++ } ++ ++ return ret; ++ ++reset_fifo_and_return: ++ DRM_ERROR("DSI transfer failed, resetting: %d\n", ret); ++ ++ DSI_PORT_WRITE(TXPKT1C, DSI_PORT_READ(TXPKT1C) & ~DSI_TXPKT1C_CMD_EN); ++ udelay(1); ++ DSI_PORT_WRITE(CTRL, ++ DSI_PORT_READ(CTRL) | ++ DSI_PORT_BIT(CTRL_RESET_FIFOS)); ++ ++ DSI_PORT_WRITE(TXPKT1C, 0); ++ DSI_PORT_WRITE(INT_EN, DSI1_INTERRUPTS_ALWAYS_ENABLED); ++ return ret; ++} ++ ++static int vc4_dsi_host_attach(struct mipi_dsi_host *host, ++ struct mipi_dsi_device *device) ++{ ++ struct vc4_dsi *dsi = host_to_dsi(host); ++ int ret = 0; ++ ++ dsi->lanes = device->lanes; ++ dsi->channel = device->channel; ++ dsi->format = device->format; ++ dsi->mode_flags = device->mode_flags; ++ ++ if (!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO)) { ++ dev_err(&dsi->pdev->dev, ++ "Only VIDEO mode panels supported currently.\n"); ++ return 0; ++ } ++ ++ dsi->panel = of_drm_find_panel(device->dev.of_node); ++ if (!dsi->panel) ++ return 0; ++ ++ ret = drm_panel_attach(dsi->panel, dsi->connector); ++ if (ret != 0) ++ return ret; ++ ++ drm_helper_hpd_irq_event(dsi->connector->dev); ++ ++ return 0; ++} ++ ++static int vc4_dsi_host_detach(struct mipi_dsi_host *host, ++ struct mipi_dsi_device *device) ++{ ++ struct vc4_dsi *dsi = host_to_dsi(host); ++ ++ if (dsi->panel) { ++ int ret = drm_panel_detach(dsi->panel); ++ ++ if (ret) ++ return ret; ++ ++ dsi->panel = NULL; ++ ++ drm_helper_hpd_irq_event(dsi->connector->dev); ++ } ++ ++ return 0; ++} ++ ++static const struct mipi_dsi_host_ops vc4_dsi_host_ops = { ++ .attach = vc4_dsi_host_attach, ++ .detach = vc4_dsi_host_detach, ++ .transfer = vc4_dsi_host_transfer, ++}; ++ ++static const struct drm_encoder_helper_funcs vc4_dsi_encoder_helper_funcs = { ++ .disable = vc4_dsi_encoder_disable, ++ .enable = vc4_dsi_encoder_enable, ++}; ++ ++static const struct of_device_id vc4_dsi_dt_match[] = { ++ { .compatible = "brcm,bcm2835-dsi1", (void *)(uintptr_t)1 }, ++ {} ++}; ++ ++static void dsi_handle_error(struct vc4_dsi *dsi, ++ irqreturn_t *ret, u32 stat, u32 bit, ++ const char *type) ++{ ++ if (!(stat & bit)) ++ return; ++ ++ DRM_ERROR("DSI%d: %s error\n", dsi->port, type); ++ *ret = IRQ_HANDLED; ++} ++ ++static irqreturn_t vc4_dsi_irq_handler(int irq, void *data) ++{ ++ struct vc4_dsi *dsi = data; ++ u32 stat = DSI_PORT_READ(INT_STAT); ++ irqreturn_t ret = IRQ_NONE; ++ ++ DSI_PORT_WRITE(INT_STAT, stat); ++ ++ dsi_handle_error(dsi, &ret, stat, ++ DSI1_INT_ERR_SYNC_ESC, "LPDT sync"); ++ dsi_handle_error(dsi, &ret, stat, ++ DSI1_INT_ERR_CONTROL, "data lane 0 sequence"); ++ dsi_handle_error(dsi, &ret, stat, ++ DSI1_INT_ERR_CONT_LP0, "LP0 contention"); ++ dsi_handle_error(dsi, &ret, stat, ++ DSI1_INT_ERR_CONT_LP1, "LP1 contention"); ++ dsi_handle_error(dsi, &ret, stat, ++ DSI1_INT_HSTX_TO, "HSTX timeout"); ++ dsi_handle_error(dsi, &ret, stat, ++ DSI1_INT_LPRX_TO, "LPRX timeout"); ++ dsi_handle_error(dsi, &ret, stat, ++ DSI1_INT_TA_TO, "turnaround timeout"); ++ dsi_handle_error(dsi, &ret, stat, ++ DSI1_INT_PR_TO, "peripheral reset timeout"); ++ ++ if (stat & (DSI1_INT_TXPKT1_DONE | DSI1_INT_PHY_DIR_RTF)) { ++ complete(&dsi->xfer_completion); ++ ret = IRQ_HANDLED; ++ } else if (stat & DSI1_INT_HSTX_TO) { ++ complete(&dsi->xfer_completion); ++ dsi->xfer_result = -ETIMEDOUT; ++ ret = IRQ_HANDLED; ++ } ++ ++ return ret; ++} ++ ++/** ++ * Exposes clocks generated by the analog PHY that are consumed by ++ * CPRMAN (clk-bcm2835.c). ++ */ ++static int ++vc4_dsi_init_phy_clocks(struct vc4_dsi *dsi) ++{ ++ struct device *dev = &dsi->pdev->dev; ++ const char *parent_name = __clk_get_name(dsi->pll_phy_clock); ++ static const struct { ++ const char *dsi0_name, *dsi1_name; ++ int div; ++ } phy_clocks[] = { ++ { "dsi0_byte", "dsi1_byte", 8 }, ++ { "dsi0_ddr2", "dsi1_ddr2", 4 }, ++ { "dsi0_ddr", "dsi1_ddr", 2 }, ++ }; ++ int i; ++ ++ dsi->clk_onecell.clk_num = ARRAY_SIZE(phy_clocks); ++ dsi->clk_onecell.clks = devm_kcalloc(dev, ++ dsi->clk_onecell.clk_num, ++ sizeof(*dsi->clk_onecell.clks), ++ GFP_KERNEL); ++ if (!dsi->clk_onecell.clks) ++ return -ENOMEM; ++ ++ for (i = 0; i < ARRAY_SIZE(phy_clocks); i++) { ++ struct clk_fixed_factor *fix = &dsi->phy_clocks[i]; ++ struct clk_init_data init; ++ struct clk *clk; ++ ++ /* We just use core fixed factor clock ops for the PHY ++ * clocks. The clocks are actually gated by the ++ * PHY_AFEC0_DDRCLK_EN bits, which we should be ++ * setting if we use the DDR/DDR2 clocks. However, ++ * vc4_dsi_encoder_enable() is setting up both AFEC0, ++ * setting both our parent DSI PLL's rate and this ++ * clock's rate, so it knows if DDR/DDR2 are going to ++ * be used and could enable the gates itself. ++ */ ++ fix->mult = 1; ++ fix->div = phy_clocks[i].div; ++ fix->hw.init = &init; ++ ++ memset(&init, 0, sizeof(init)); ++ init.parent_names = &parent_name; ++ init.num_parents = 1; ++ if (dsi->port == 1) ++ init.name = phy_clocks[i].dsi1_name; ++ else ++ init.name = phy_clocks[i].dsi0_name; ++ init.ops = &clk_fixed_factor_ops; ++ init.flags = CLK_IS_BASIC; ++ ++ clk = devm_clk_register(dev, &fix->hw); ++ if (IS_ERR(clk)) ++ return PTR_ERR(clk); ++ ++ dsi->clk_onecell.clks[i] = clk; ++ } ++ ++ return of_clk_add_provider(dev->of_node, ++ of_clk_src_onecell_get, ++ &dsi->clk_onecell); ++} ++ ++static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct drm_device *drm = dev_get_drvdata(master); ++ struct vc4_dev *vc4 = to_vc4_dev(drm); ++ struct vc4_dsi *dsi; ++ struct vc4_dsi_encoder *vc4_dsi_encoder; ++ const struct of_device_id *match; ++ dma_cap_mask_t dma_mask; ++ int ret; ++ ++ dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); ++ if (!dsi) ++ return -ENOMEM; ++ ++ match = of_match_device(vc4_dsi_dt_match, dev); ++ if (!match) ++ return -ENODEV; ++ ++ dsi->port = (uintptr_t)match->data; ++ ++ vc4_dsi_encoder = devm_kzalloc(dev, sizeof(*vc4_dsi_encoder), ++ GFP_KERNEL); ++ if (!vc4_dsi_encoder) ++ return -ENOMEM; ++ vc4_dsi_encoder->base.type = VC4_ENCODER_TYPE_DSI1; ++ vc4_dsi_encoder->dsi = dsi; ++ dsi->encoder = &vc4_dsi_encoder->base.base; ++ ++ dsi->pdev = pdev; ++ dsi->regs = vc4_ioremap_regs(pdev, 0); ++ if (IS_ERR(dsi->regs)) ++ return PTR_ERR(dsi->regs); ++ ++ if (DSI_PORT_READ(ID) != DSI_ID_VALUE) { ++ dev_err(dev, "Port returned 0x%08x for ID instead of 0x%08x\n", ++ DSI_PORT_READ(ID), DSI_ID_VALUE); ++ return -ENODEV; ++ } ++ ++ /* DSI1 has a broken AXI slave that doesn't respond to writes ++ * from the ARM. It does handle writes from the DMA engine, ++ * so set up a channel for talking to it. ++ */ ++ if (dsi->port == 1) { ++ dsi->reg_dma_mem = dma_alloc_coherent(dev, 4, ++ &dsi->reg_dma_paddr, ++ GFP_KERNEL); ++ if (!dsi->reg_dma_mem) { ++ DRM_ERROR("Failed to get DMA memory\n"); ++ return -ENOMEM; ++ } ++ ++ dma_cap_zero(dma_mask); ++ dma_cap_set(DMA_MEMCPY, dma_mask); ++ dsi->reg_dma_chan = dma_request_chan_by_mask(&dma_mask); ++ if (IS_ERR(dsi->reg_dma_chan)) { ++ ret = PTR_ERR(dsi->reg_dma_chan); ++ if (ret != -EPROBE_DEFER) ++ DRM_ERROR("Failed to get DMA channel: %d\n", ++ ret); ++ return ret; ++ } ++ ++ /* Get the physical address of the device's registers. The ++ * struct resource for the regs gives us the bus address ++ * instead. ++ */ ++ dsi->reg_paddr = be32_to_cpup(of_get_address(dev->of_node, ++ 0, NULL, NULL)); ++ } ++ ++ init_completion(&dsi->xfer_completion); ++ /* At startup enable error-reporting interrupts and nothing else. */ ++ DSI_PORT_WRITE(INT_EN, DSI1_INTERRUPTS_ALWAYS_ENABLED); ++ /* Clear any existing interrupt state. */ ++ DSI_PORT_WRITE(INT_STAT, DSI_PORT_READ(INT_STAT)); ++ ++ ret = devm_request_irq(dev, platform_get_irq(pdev, 0), ++ vc4_dsi_irq_handler, 0, "vc4 dsi", dsi); ++ if (ret) { ++ if (ret != -EPROBE_DEFER) ++ dev_err(dev, "Failed to get interrupt: %d\n", ret); ++ return ret; ++ } ++ ++ dsi->escape_clock = devm_clk_get(dev, "escape"); ++ if (IS_ERR(dsi->escape_clock)) { ++ ret = PTR_ERR(dsi->escape_clock); ++ if (ret != -EPROBE_DEFER) ++ dev_err(dev, "Failed to get escape clock: %d\n", ret); ++ return ret; ++ } ++ ++ dsi->pll_phy_clock = devm_clk_get(dev, "phy"); ++ if (IS_ERR(dsi->pll_phy_clock)) { ++ ret = PTR_ERR(dsi->pll_phy_clock); ++ if (ret != -EPROBE_DEFER) ++ dev_err(dev, "Failed to get phy clock: %d\n", ret); ++ return ret; ++ } ++ ++ dsi->pixel_clock = devm_clk_get(dev, "pixel"); ++ if (IS_ERR(dsi->pixel_clock)) { ++ ret = PTR_ERR(dsi->pixel_clock); ++ if (ret != -EPROBE_DEFER) ++ dev_err(dev, "Failed to get pixel clock: %d\n", ret); ++ return ret; ++ } ++ ++ /* The esc clock rate is supposed to always be 100Mhz. */ ++ ret = clk_set_rate(dsi->escape_clock, 100 * 1000000); ++ if (ret) { ++ dev_err(dev, "Failed to set esc clock: %d\n", ret); ++ return ret; ++ } ++ ++ ret = vc4_dsi_init_phy_clocks(dsi); ++ if (ret) ++ return ret; ++ ++ if (dsi->port == 1) ++ vc4->dsi1 = dsi; ++ ++ drm_encoder_init(drm, dsi->encoder, &vc4_dsi_encoder_funcs, ++ DRM_MODE_ENCODER_DSI, NULL); ++ drm_encoder_helper_add(dsi->encoder, &vc4_dsi_encoder_helper_funcs); ++ ++ dsi->connector = vc4_dsi_connector_init(drm, dsi); ++ if (IS_ERR(dsi->connector)) { ++ ret = PTR_ERR(dsi->connector); ++ goto err_destroy_encoder; ++ } ++ ++ dsi->dsi_host.ops = &vc4_dsi_host_ops; ++ dsi->dsi_host.dev = dev; ++ ++ mipi_dsi_host_register(&dsi->dsi_host); ++ ++ dev_set_drvdata(dev, dsi); ++ ++ pm_runtime_enable(dev); ++ ++ return 0; ++ ++err_destroy_encoder: ++ vc4_dsi_encoder_destroy(dsi->encoder); ++ ++ return ret; ++} ++ ++static void vc4_dsi_unbind(struct device *dev, struct device *master, ++ void *data) ++{ ++ struct drm_device *drm = dev_get_drvdata(master); ++ struct vc4_dev *vc4 = to_vc4_dev(drm); ++ struct vc4_dsi *dsi = dev_get_drvdata(dev); ++ ++ pm_runtime_disable(dev); ++ ++ vc4_dsi_connector_destroy(dsi->connector); ++ vc4_dsi_encoder_destroy(dsi->encoder); ++ ++ mipi_dsi_host_unregister(&dsi->dsi_host); ++ ++ clk_disable_unprepare(dsi->pll_phy_clock); ++ clk_disable_unprepare(dsi->escape_clock); ++ ++ if (dsi->port == 1) ++ vc4->dsi1 = NULL; ++} ++ ++static const struct component_ops vc4_dsi_ops = { ++ .bind = vc4_dsi_bind, ++ .unbind = vc4_dsi_unbind, ++}; ++ ++static int vc4_dsi_dev_probe(struct platform_device *pdev) ++{ ++ return component_add(&pdev->dev, &vc4_dsi_ops); ++} ++ ++static int vc4_dsi_dev_remove(struct platform_device *pdev) ++{ ++ component_del(&pdev->dev, &vc4_dsi_ops); ++ return 0; ++} ++ ++struct platform_driver vc4_dsi_driver = { ++ .probe = vc4_dsi_dev_probe, ++ .remove = vc4_dsi_dev_remove, ++ .driver = { ++ .name = "vc4_dsi", ++ .of_match_table = vc4_dsi_dt_match, ++ }, ++}; + +From a8252ac49ea4d23c2482dcc2e17b8895e74eb5c4 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Fri, 2 Dec 2016 14:48:12 +0100 +Subject: [PATCH 176/190] ARM: dts: bcm283x: Add VEC node in bcm283x.dtsi + +Add the VEC (Video EnCoder) node definition in bcm283x.dtsi. + +Signed-off-by: Boris Brezillon +Signed-off-by: Eric Anholt +(cherry picked from commit b899c45208d6f204a6da9a1132577993eeecf0fb) +--- + arch/arm/boot/dts/bcm283x.dtsi | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi +index 304dd291a9ae94700e8e628c0c9ebd3fb98abb19..ee69fd481fabd22d8f45ecdcffacdbb185e11f55 100644 +--- a/arch/arm/boot/dts/bcm283x.dtsi ++++ b/arch/arm/boot/dts/bcm283x.dtsi +@@ -520,6 +520,14 @@ + status = "disabled"; + }; + ++ vec: vec@7e806000 { ++ compatible = "brcm,bcm2835-vec"; ++ reg = <0x7e806000 0x1000>; ++ clocks = <&clocks BCM2835_CLOCK_VEC>; ++ interrupts = <2 27>; ++ status = "disabled"; ++ }; ++ + pixelvalve@7e807000 { + compatible = "brcm,bcm2835-pixelvalve2"; + reg = <0x7e807000 0x100>; + +From 80b784aa9111727a1536fb5625630ab883e31ab9 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Fri, 2 Dec 2016 14:48:13 +0100 +Subject: [PATCH 177/190] ARM: dts: bcm283x: Enable the VEC IP on all + RaspberryPi boards + +Enable the VEC IP on all RaspberryPi boards. + +Signed-off-by: Boris Brezillon +Signed-off-by: Eric Anholt +(cherry picked from commit 5ab1a37c6027c114a87a1ae32cfc5ef303d643c5) +--- + arch/arm/boot/dts/bcm2835-rpi.dtsi | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi +index 58f7d874c70a9cf965e10ae3f14fe3bb00846b71..023630efa7c1d8601ba5e83d2fdb38a7557b6460 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi +@@ -95,3 +95,8 @@ + &dsi1 { + power-domains = <&power RPI_POWER_DOMAIN_DSI1>; + }; ++ ++&vec { ++ power-domains = <&power RPI_POWER_DOMAIN_VEC>; ++ status = "okay"; ++}; + +From fefed2fac347a328b8a71318991a6ccd4d625964 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 23 Jan 2017 11:41:54 -0800 +Subject: [PATCH 178/190] BCM270X: Disable VEC unless vc4-kms-v3d is present. + +Signed-off-by: Eric Anholt +--- + arch/arm/boot/dts/bcm2708-rpi.dtsi | 4 ++++ + arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 7 +++++++ + 2 files changed, 11 insertions(+) + +diff --git a/arch/arm/boot/dts/bcm2708-rpi.dtsi b/arch/arm/boot/dts/bcm2708-rpi.dtsi +index ef14e9ac6cd2092efb1681682dd2d3c52b8abfd5..8bb9ca54a36f2ac29987ecc1c2738b6758849a16 100644 +--- a/arch/arm/boot/dts/bcm2708-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2708-rpi.dtsi +@@ -111,3 +111,7 @@ + &clocks { + firmware = <&firmware>; + }; ++ ++&vec { ++ status = "disabled"; ++}; +diff --git a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts +index 05faf1bfa1b7c73fd60b1efb813b969e10bbfefa..c57e795824e9261e0f60bcb40d6a57241019fd91 100644 +--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts ++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts +@@ -151,6 +151,13 @@ + }; + + fragment@18 { ++ target = <&vec>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@19 { + target = <&clocks>; + __overlay__ { + claim-clocks = < + +From 29059a451ac15090b051b9e3a9072a2513099ebe Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 1 Feb 2017 17:09:18 -0800 +Subject: [PATCH 179/190] drm/vc4: Name the primary and cursor planes in fkms. + +This makes debugging nicer, compared to trying to remember what the +IDs are. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/vc4/vc4_firmware_kms.c b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +index d18a1dae51a2275846c9826b5bf1ba57ae97b55c..e49ce68b607a7ffc2329e3235362f3bc21ed5cbb 100644 +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -267,7 +267,7 @@ static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev, + ret = drm_universal_plane_init(dev, plane, 0xff, + &vc4_plane_funcs, + primary ? &xrgb8888 : &argb8888, 1, +- type, NULL); ++ type, primary ? "primary" : "cursor"); + + if (type == DRM_PLANE_TYPE_PRIMARY) { + vc4_plane->fbinfo = + +From cb344e7984334a741c189b964bdad32f8afdc18f Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 1 Feb 2017 17:10:09 -0800 +Subject: [PATCH 180/190] drm/vc4: Add DRM_DEBUG_ATOMIC for the insides of + fkms. + +Trying to debug weston on fkms involved figuring out what calls I was +making to the firmware. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/drivers/gpu/drm/vc4/vc4_firmware_kms.c b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +index e49ce68b607a7ffc2329e3235362f3bc21ed5cbb..dbf065677202fbebf8e3a0cffbe880aa42daef3f 100644 +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -102,6 +102,11 @@ static int vc4_plane_set_primary_blank(struct drm_plane *plane, bool blank) + struct vc4_dev *vc4 = to_vc4_dev(plane->dev); + + u32 packet = blank; ++ ++ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary plane %s", ++ plane->base.id, plane->name, ++ blank ? "blank" : "unblank"); ++ + return rpi_firmware_property(vc4->firmware, + RPI_FIRMWARE_FRAMEBUFFER_BLANK, + &packet, sizeof(packet)); +@@ -149,6 +154,16 @@ static void vc4_primary_plane_atomic_update(struct drm_plane *plane, + WARN_ON_ONCE(vc4_plane->pitch != fb->pitches[0]); + } + ++ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary update %dx%d@%d +%d,%d 0x%08x/%d\n", ++ plane->base.id, plane->name, ++ state->crtc_w, ++ state->crtc_h, ++ bpp, ++ state->crtc_x, ++ state->crtc_y, ++ bo->paddr + fb->offsets[0], ++ fb->pitches[0]); ++ + ret = rpi_firmware_transaction(vc4->firmware, + RPI_FIRMWARE_CHAN_FB, + vc4_plane->fbinfo_bus_addr); +@@ -178,6 +193,15 @@ static void vc4_cursor_plane_atomic_update(struct drm_plane *plane, + WARN_ON_ONCE(fb->pitches[0] != state->crtc_w * 4); + WARN_ON_ONCE(fb->bits_per_pixel != 32); + ++ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] update %dx%d cursor at %d,%d (0x%08x/%d)", ++ plane->base.id, plane->name, ++ state->crtc_w, ++ state->crtc_h, ++ state->crtc_x, ++ state->crtc_y, ++ bo->paddr + fb->offsets[0], ++ fb->pitches[0]); ++ + ret = rpi_firmware_property(vc4->firmware, + RPI_FIRMWARE_SET_CURSOR_STATE, + &packet_state, +@@ -200,6 +224,8 @@ static void vc4_cursor_plane_atomic_disable(struct drm_plane *plane, + 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, + +From 7cb76db67b24f033a48fcc41b5db64198c6b59f4 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 2 Feb 2017 09:42:18 -0800 +Subject: [PATCH 181/190] drm/vc4: Fix sending of page flip completion events + in FKMS mode. + +In the rewrite of vc4_crtc.c for fkms, I dropped the part of the +CRTC's atomic flush handler that moved the completion event from the +proposed atomic state change to the CRTC's current state. That meant +that when full screen pageflipping happened (glxgears -fullscreen in +X, compton, por weston), the app would end up blocked firever waiting +to draw its next frame. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/drivers/gpu/drm/vc4/vc4_firmware_kms.c b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +index dbf065677202fbebf8e3a0cffbe880aa42daef3f..da818a207bfa639b8cea48d94bcf4566f97db816 100644 +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -338,6 +338,21 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc, + static void vc4_crtc_atomic_flush(struct drm_crtc *crtc, + struct drm_crtc_state *old_state) + { ++ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); ++ struct drm_device *dev = crtc->dev; ++ ++ if (crtc->state->event) { ++ unsigned long flags; ++ ++ crtc->state->event->pipe = drm_crtc_index(crtc); ++ ++ WARN_ON(drm_crtc_vblank_get(crtc) != 0); ++ ++ spin_lock_irqsave(&dev->event_lock, flags); ++ vc4_crtc->event = crtc->state->event; ++ crtc->state->event = NULL; ++ spin_unlock_irqrestore(&dev->event_lock, flags); ++ } + } + + static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc) + +From 73024c5a31635d4991db90642c8612511cfb5cd2 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 8 Feb 2017 15:00:54 -0800 +Subject: [PATCH 182/190] drm/vc4: Fulfill user BO creation requests from the + kernel BO cache. + +The from_cache flag was actually "the BO is invisible to userspace", +so we can repurpose to just zero out a cached BO and return it to +userspace. + +Improves wall time for a loop of 5 glsl-algebraic-add-add-1 by +-1.44989% +/- 0.862891% (n=28, 1 outlier removed from each that +appeared to be other system noise) + +Note that there's an intel-gpu-tools test to check for the proper +zeroing behavior here, which we continue to pass. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_bo.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c +index 3f6704cf6608d7be47637c6aa585de087b7f74ee..5ec14f25625dde6fd61e10415092fa25527cc151 100644 +--- a/drivers/gpu/drm/vc4/vc4_bo.c ++++ b/drivers/gpu/drm/vc4/vc4_bo.c +@@ -208,21 +208,22 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size) + } + + struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size, +- bool from_cache) ++ bool allow_unzeroed) + { + size_t size = roundup(unaligned_size, PAGE_SIZE); + struct vc4_dev *vc4 = to_vc4_dev(dev); + struct drm_gem_cma_object *cma_obj; ++ struct vc4_bo *bo; + + if (size == 0) + return ERR_PTR(-EINVAL); + + /* First, try to get a vc4_bo from the kernel BO cache. */ +- if (from_cache) { +- struct vc4_bo *bo = vc4_bo_get_from_cache(dev, size); +- +- if (bo) +- return bo; ++ bo = vc4_bo_get_from_cache(dev, size); ++ if (bo) { ++ if (!allow_unzeroed) ++ memset(bo->base.vaddr, 0, bo->base.base.size); ++ return bo; + } + + cma_obj = drm_gem_cma_create(dev, size); + +From 8b843fbc94dd5f3cc92699c8d0d8903ebb9089cb Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Thu, 9 Feb 2017 09:23:34 -0800 +Subject: [PATCH 183/190] drm/vc4: Fix OOPSes from trying to cache a partially + constructed BO. + +If a CMA allocation failed, the partially constructed BO would be +unreferenced through the normal path, and we might choose to put it in +the BO cache. If we then reused it before it expired from the cache, +the kernel would OOPS. + +Signed-off-by: Eric Anholt +Fixes: c826a6e10644 ("drm/vc4: Add a BO cache.") +--- + drivers/gpu/drm/vc4/vc4_bo.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c +index 5ec14f25625dde6fd61e10415092fa25527cc151..fd83a28076564b9ea5cf0f2ba29b884ee3c5af43 100644 +--- a/drivers/gpu/drm/vc4/vc4_bo.c ++++ b/drivers/gpu/drm/vc4/vc4_bo.c +@@ -314,6 +314,14 @@ void vc4_free_object(struct drm_gem_object *gem_bo) + goto out; + } + ++ /* If this object was partially constructed but CMA allocation ++ * had failed, just free it. ++ */ ++ if (!bo->base.vaddr) { ++ vc4_bo_destroy(bo); ++ goto out; ++ } ++ + cache_list = vc4_get_cache_list_for_size(dev, gem_bo->size); + if (!cache_list) { + vc4_bo_destroy(bo); + +From 142f6b052591eb5d3da338b9544df2a900e8b8d9 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 12 Oct 2015 08:58:08 -0700 +Subject: [PATCH 184/190] drm/vc4: Verify at boot that CMA doesn't cross a + 256MB boundary. + +I've seen lots of users cranking CMA up higher, so throw an error if +they do. + +Signed-off-by: Eric Anholt +--- + drivers/base/dma-contiguous.c | 1 + + drivers/gpu/drm/vc4/vc4_v3d.c | 18 ++++++++++++++++++ + mm/cma.c | 2 ++ + 3 files changed, 21 insertions(+) + +diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c +index e167a1e1bccb062efef2595fcd5299301a97df80..60f5c2591ccdb0202461458eab4035cfba731b8b 100644 +--- a/drivers/base/dma-contiguous.c ++++ b/drivers/base/dma-contiguous.c +@@ -35,6 +35,7 @@ + #endif + + struct cma *dma_contiguous_default_area; ++EXPORT_SYMBOL(dma_contiguous_default_area); + + /* + * Default global CMA area size can be defined in kernel's .config. +diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c +index 7cc346ad9b0baed63701d1fae8f0306aa7713129..1d9e5a6edd22c29ce8b2990c9c35627aa1af2bd8 100644 +--- a/drivers/gpu/drm/vc4/vc4_v3d.c ++++ b/drivers/gpu/drm/vc4/vc4_v3d.c +@@ -16,7 +16,10 @@ + * this program. If not, see . + */ + ++#include "linux/init.h" ++#include "linux/cma.h" + #include "linux/component.h" ++#include "linux/dma-contiguous.h" + #include "linux/pm_runtime.h" + #include "vc4_drv.h" + #include "vc4_regs.h" +@@ -185,8 +188,23 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data) + struct drm_device *drm = dev_get_drvdata(master); + struct vc4_dev *vc4 = to_vc4_dev(drm); + struct vc4_v3d *v3d = NULL; ++ struct cma *cma; + int ret; + ++ cma = dev_get_cma_area(dev); ++ if (!cma) ++ return -EINVAL; ++ ++ if ((cma_get_base(cma) & 0xf0000000) != ++ ((cma_get_base(cma) + cma_get_size(cma) - 1) & 0xf0000000)) { ++ DRM_ERROR("V3D requires that the CMA area (0x%08lx - 0x%08lx) " ++ "not span a 256MB boundary, or memory corruption " ++ "would happen.\n", ++ (long)cma_get_base(cma), ++ cma_get_base(cma) + cma_get_size(cma)); ++ return -EINVAL; ++ } ++ + v3d = devm_kzalloc(&pdev->dev, sizeof(*v3d), GFP_KERNEL); + if (!v3d) + return -ENOMEM; +diff --git a/mm/cma.c b/mm/cma.c +index c960459eda7e640ea55be1d4ed80c6a9125a8877..b50245282a18bc790da0f901944c2e670ffac2d2 100644 +--- a/mm/cma.c ++++ b/mm/cma.c +@@ -47,11 +47,13 @@ phys_addr_t cma_get_base(const struct cma *cma) + { + return PFN_PHYS(cma->base_pfn); + } ++EXPORT_SYMBOL(cma_get_base); + + unsigned long cma_get_size(const struct cma *cma) + { + return cma->count << PAGE_SHIFT; + } ++EXPORT_SYMBOL(cma_get_size); + + static unsigned long cma_bitmap_aligned_mask(const struct cma *cma, + int align_order) + +From c45c2efba49d217dd202c7aa6698838819beb67e Mon Sep 17 00:00:00 2001 +From: Scott Ellis +Date: Thu, 23 Feb 2017 11:56:20 -0500 +Subject: [PATCH 185/190] Add ads1015 driver to config + +--- + arch/arm/configs/bcm2709_defconfig | 2 +- + arch/arm/configs/bcmrpi_defconfig | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig +index d3fd0252f78ec72bd6d93322e781abc3609af01c..1a25a016a53badcb2cd76141d035d5552a72b2f8 100644 +--- a/arch/arm/configs/bcm2709_defconfig ++++ b/arch/arm/configs/bcm2709_defconfig +@@ -833,9 +833,9 @@ CONFIG_VIDEO_OV7640=m + CONFIG_VIDEO_MT9V011=m + CONFIG_DRM=m + CONFIG_DRM_LOAD_EDID_FIRMWARE=y ++CONFIG_DRM_UDL=m + CONFIG_DRM_PANEL_SIMPLE=m + CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m +-CONFIG_DRM_UDL=m + CONFIG_DRM_VC4=m + CONFIG_FB=y + CONFIG_FB_BCM2708=y +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +index 0768998e5cbcc96714d546f656ff59eafe2dc754..efc4898aca911d5c97426a38b0f1808b3c0d4baa 100644 +--- a/arch/arm/configs/bcmrpi_defconfig ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -826,9 +826,9 @@ CONFIG_VIDEO_OV7640=m + CONFIG_VIDEO_MT9V011=m + CONFIG_DRM=m + CONFIG_DRM_LOAD_EDID_FIRMWARE=y ++CONFIG_DRM_UDL=m + CONFIG_DRM_PANEL_SIMPLE=m + CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m +-CONFIG_DRM_UDL=m + CONFIG_DRM_VC4=m + CONFIG_FB=y + CONFIG_FB_BCM2708=y + +From 26c424b1278ee59f8101ec98adbb03339dfdb083 Mon Sep 17 00:00:00 2001 +From: Michael Zoran +Date: Thu, 23 Feb 2017 17:54:31 -0800 +Subject: [PATCH 186/190] drm/vc4: Don't wait for vblank when updating the + cursor + +Commonly used desktop environments such as xfce4 and gnome +on debian sid can flood the graphics drivers with cursor +updates. Because the current implementation is waiting +for a vblank between cursor updates, this will cause the +display to hang for a long time since a typical refresh +rate is only 60Hz. + +This is unnecessary and unexpected by user mode software, +so simply swap out the cursor frame buffer without waiting. + +Signed-off-by: Michael Zoran +Reviewed-by: Eric Anholt +--- + drivers/gpu/drm/vc4/vc4_plane.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c +index 686cdd3c86f2e9178768282a0dd173850e0bf063..7bdbb0e2b50f9202efe1177df761b379f1232dbc 100644 +--- a/drivers/gpu/drm/vc4/vc4_plane.c ++++ b/drivers/gpu/drm/vc4/vc4_plane.c +@@ -20,6 +20,7 @@ + + #include "vc4_drv.h" + #include "vc4_regs.h" ++#include "drm_atomic.h" + #include "drm_atomic_helper.h" + #include "drm_fb_cma_helper.h" + #include "drm_plane_helper.h" +@@ -769,12 +770,6 @@ vc4_update_plane(struct drm_plane *plane, + if (!plane_state) + goto out; + +- /* If we're changing the cursor contents, do that in the +- * normal vblank-synced atomic path. +- */ +- if (fb != plane_state->fb) +- goto out; +- + /* No configuring new scaling in the fast path. */ + if (crtc_w != plane_state->crtc_w || + crtc_h != plane_state->crtc_h || +@@ -783,6 +778,11 @@ vc4_update_plane(struct drm_plane *plane, + goto out; + } + ++ if (fb != plane_state->fb) { ++ drm_atomic_set_fb_for_plane(plane->state, fb); ++ vc4_plane_async_set_fb(plane, fb); ++ } ++ + /* Set the cursor's position on the screen. This is the + * expected change from the drm_mode_cursor_universal() + * helper. + +From 51ed4d07d2ee6cc409cfcfe57075111f040b641f Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Mon, 6 Mar 2017 12:17:16 -0800 +Subject: [PATCH 187/190] panel-raspberrypi-touchscreen: Round up clk rate to + fix DSI panel. + +Commit 488f9bc8e3def93e0baef53cee2026c2cb0d8956 slightly increased the +reported rate of PLLD, so the clk driver decided that PLLD/3/8 was now +higher than our requested pixel clock rate and rejected it in favor of +PLLD/4/8, which then ran the pixel clock way out of spec. + +By bumping the requested clock rate just slightly, we get back to +PLLD/3/8 like we wanted and the panel displays content again. + +Signed-off-by: Eric Anholt +--- + drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +index 1a536fe4d040f5fafe324baee110a6225dd0be08..7f315f04b109621ca7f3861fdd8acf956e752629 100644 +--- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c ++++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +@@ -220,7 +220,12 @@ static const struct drm_display_mode rpi_touchscreen_modes[] = { + #define HBP 46 + #define HFP ((PIXEL_CLOCK / (VTOTAL * VREFRESH)) - (HACT + HSW + HBP)) + +- .clock = PIXEL_CLOCK / 1000, ++ /* Round up the pixel clock a bit (10khz), so that the ++ * "don't run things faster than the requested clock ++ * rate" rule of the clk driver doesn't reject the ++ * divide-by-3 mode due to rounding error. ++ */ ++ .clock = PIXEL_CLOCK / 1000 + 10, + .hdisplay = HACT, + .hsync_start = HACT + HFP, + .hsync_end = HACT + HFP + HSW, + +From 244ad5c32697ee6a86ad91de24e2fff4b6613981 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 13 Mar 2017 12:30:37 +0000 +Subject: [PATCH 188/190] thermal: Compatible strings for bcm2836, bcm2837 + +The upstream dt-bindings documentation for bcm2835-thermal (which +exists even though the driver isn't upstreamed) says to use +dedicated compatible strings on bcm2836 and bcm2837, even though +the downstream driver doesn't support them. The Pi2 DTB uses +"brcm,bcm2836-thermal", so the driver doesn't load. The Pi3 DTB +doesn't override the base value, but the arm64 Pi3 support uses "brcm,bcm2837-thermal". + +Solve the documentation problem by adding "brcm,bcm2836-thermal" and +"brcm,bcm2837-thermal" as alternative compatible strings for the +bcm2835-thermal driver. + +Signed-off-by: Phil Elwell +--- + drivers/thermal/bcm2835-thermal.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/thermal/bcm2835-thermal.c b/drivers/thermal/bcm2835-thermal.c +index c63fb9f9d143e19612a18fe530c7b2b3518a22a4..25b78c3eac1503fbc9e679b963a6284b673b2ed3 100644 +--- a/drivers/thermal/bcm2835-thermal.c ++++ b/drivers/thermal/bcm2835-thermal.c +@@ -89,6 +89,8 @@ static int bcm2835_thermal_remove(struct platform_device *pdev) + + static const struct of_device_id bcm2835_thermal_of_match_table[] = { + { .compatible = "brcm,bcm2835-thermal", }, ++ { .compatible = "brcm,bcm2836-thermal", }, ++ { .compatible = "brcm,bcm2837-thermal", }, + {}, + }; + MODULE_DEVICE_TABLE(of, bcm2835_thermal_of_match_table); + +From 0b71962faccc9830def0bd601c29c71b8c754454 Mon Sep 17 00:00:00 2001 +From: John Greb +Date: Wed, 8 Mar 2017 15:12:29 +0000 +Subject: [PATCH 189/190] Match dwc2 device-tree fifo sizes to the hardware + values. + +Since commit aa381a7259c3f53727bcaa8c5f9359e940a0e3fd was reverted with 3fa9538539ac737096c81f3315a14670b1609092 the g-tx-fifo-size array in the device-tree needs to match the preset values in the bcm2835. + +Resolves https://github.com/raspberrypi/linux/issues/1876 +--- + arch/arm/boot/dts/overlays/dwc2-overlay.dts | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/overlays/dwc2-overlay.dts b/arch/arm/boot/dts/overlays/dwc2-overlay.dts +index 527abc9f0ddf71f4dc7d58336d87684c931cc2f3..265a16bab008453edba198cf2366c423509d60d6 100644 +--- a/arch/arm/boot/dts/overlays/dwc2-overlay.dts ++++ b/arch/arm/boot/dts/overlays/dwc2-overlay.dts +@@ -15,7 +15,7 @@ + dr_mode = "otg"; + g-np-tx-fifo-size = <32>; + g-rx-fifo-size = <256>; +- g-tx-fifo-size = <256 128 128 64 64 64 32>; ++ g-tx-fifo-size = <512 512 512 512 512 768>; + status = "okay"; + }; + }; +@@ -24,6 +24,5 @@ + dr_mode = <&dwc2_usb>, "dr_mode"; + g-np-tx-fifo-size = <&dwc2_usb>,"g-np-tx-fifo-size:0"; + g-rx-fifo-size = <&dwc2_usb>,"g-rx-fifo-size:0"; +- g-tx-fifo-size = <&dwc2_usb>,"g-tx-fifo-size:0"; + }; + }; + +From 0c2b88f95778c87bbd5d0a480266c4f9a0ffdc35 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Tue, 7 Mar 2017 12:18:20 +0000 +Subject: [PATCH 190/190] BCM270X_DT: Invert Pi3 power LED to match fw change + +Firmware expgpio driver reworked due to complaint over +hotplug detect. +Requires power LED to change sense as firmware is no longer +inverting the read value. + +Signed-off-by: Dave Stevenson +--- + arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +index 173103aaca503833b5e29530ed94e14c7cab0444..b21d2866d204adc533b46d581028f290e5c34a3d 100644 +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +@@ -175,7 +175,7 @@ + pwr_led: pwr { + label = "led1"; + linux,default-trigger = "input"; +- gpios = <&expgpio 7 GPIO_ACTIVE_LOW>; ++ gpios = <&expgpio 7 0>; + }; + }; + From fb1fe7c0cb55f0179abb7ee47a98865453356e1e Mon Sep 17 00:00:00 2001 From: MilhouseVH Date: Mon, 13 Mar 2017 17:20:41 +0000 Subject: [PATCH 4/8] RBP: Add support for Dion Audio LOCO-V2 DAC-AMP --- projects/RPi/linux/linux.arm.conf | 1 + projects/RPi2/linux/linux.arm.conf | 1 + 2 files changed, 2 insertions(+) diff --git a/projects/RPi/linux/linux.arm.conf b/projects/RPi/linux/linux.arm.conf index abee34650d..350ef87a52 100644 --- a/projects/RPi/linux/linux.arm.conf +++ b/projects/RPi/linux/linux.arm.conf @@ -2805,6 +2805,7 @@ CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m CONFIG_SND_DIGIDAC1_SOUNDCARD=m CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m +CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m CONFIG_SND_PISOUND=m # CONFIG_SND_DESIGNWARE_I2S is not set diff --git a/projects/RPi2/linux/linux.arm.conf b/projects/RPi2/linux/linux.arm.conf index d713f0f705..5ab97e994a 100644 --- a/projects/RPi2/linux/linux.arm.conf +++ b/projects/RPi2/linux/linux.arm.conf @@ -2896,6 +2896,7 @@ CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m CONFIG_SND_DIGIDAC1_SOUNDCARD=m CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m +CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m CONFIG_SND_PISOUND=m # CONFIG_SND_DESIGNWARE_I2S is not set From 7d0bbf2746b3b6d737c04ff35b29133694d6aefa Mon Sep 17 00:00:00 2001 From: MilhouseVH Date: Mon, 13 Mar 2017 17:20:41 +0000 Subject: [PATCH 5/8] RBP: Add support for Fe-Pi audio sound card --- projects/RPi/linux/linux.arm.conf | 3 ++- projects/RPi2/linux/linux.arm.conf | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/projects/RPi/linux/linux.arm.conf b/projects/RPi/linux/linux.arm.conf index 350ef87a52..fbe8470743 100644 --- a/projects/RPi/linux/linux.arm.conf +++ b/projects/RPi/linux/linux.arm.conf @@ -2807,6 +2807,7 @@ CONFIG_SND_DIGIDAC1_SOUNDCARD=m CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m +CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m CONFIG_SND_PISOUND=m # CONFIG_SND_DESIGNWARE_I2S is not set @@ -2878,7 +2879,7 @@ CONFIG_SND_SOC_PCM512x_I2C=m CONFIG_SND_SOC_PCM1794A=m # CONFIG_SND_SOC_RT5631 is not set # CONFIG_SND_SOC_RT5677_SPI is not set -# CONFIG_SND_SOC_SGTL5000 is not set +CONFIG_SND_SOC_SGTL5000=m # CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set # CONFIG_SND_SOC_SPDIF is not set # CONFIG_SND_SOC_SSM2602_SPI is not set diff --git a/projects/RPi2/linux/linux.arm.conf b/projects/RPi2/linux/linux.arm.conf index 5ab97e994a..760bb09bca 100644 --- a/projects/RPi2/linux/linux.arm.conf +++ b/projects/RPi2/linux/linux.arm.conf @@ -2898,6 +2898,7 @@ CONFIG_SND_DIGIDAC1_SOUNDCARD=m CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m +CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m CONFIG_SND_PISOUND=m # CONFIG_SND_DESIGNWARE_I2S is not set @@ -2969,7 +2970,7 @@ CONFIG_SND_SOC_PCM512x_I2C=m CONFIG_SND_SOC_PCM1794A=m # CONFIG_SND_SOC_RT5631 is not set # CONFIG_SND_SOC_RT5677_SPI is not set -# CONFIG_SND_SOC_SGTL5000 is not set +CONFIG_SND_SOC_SGTL5000=m # CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set # CONFIG_SND_SOC_SPDIF is not set # CONFIG_SND_SOC_SSM2602_SPI is not set From 8b93fde760ec96261a02b5e492b0edbb154db8ac Mon Sep 17 00:00:00 2001 From: MilhouseVH Date: Mon, 13 Mar 2017 17:20:41 +0000 Subject: [PATCH 6/8] RBP: bcm2835-gpio-exp: Driver for GPIO expander via mailbox service (rpi/1852) --- projects/RPi/linux/linux.arm.conf | 1 + projects/RPi2/linux/linux.arm.conf | 1 + 2 files changed, 2 insertions(+) diff --git a/projects/RPi/linux/linux.arm.conf b/projects/RPi/linux/linux.arm.conf index fbe8470743..07c4dd3074 100644 --- a/projects/RPi/linux/linux.arm.conf +++ b/projects/RPi/linux/linux.arm.conf @@ -1810,6 +1810,7 @@ CONFIG_GPIO_SYSFS=y # # CONFIG_GPIO_74XX_MMIO is not set # CONFIG_GPIO_ALTERA is not set +CONFIG_GPIO_BCM_EXP=y CONFIG_GPIO_BCM_VIRT=y # CONFIG_GPIO_DWAPB is not set # CONFIG_GPIO_GENERIC_PLATFORM is not set diff --git a/projects/RPi2/linux/linux.arm.conf b/projects/RPi2/linux/linux.arm.conf index 760bb09bca..832e333473 100644 --- a/projects/RPi2/linux/linux.arm.conf +++ b/projects/RPi2/linux/linux.arm.conf @@ -1896,6 +1896,7 @@ CONFIG_GPIO_SYSFS=y # # CONFIG_GPIO_74XX_MMIO is not set # CONFIG_GPIO_ALTERA is not set +CONFIG_GPIO_BCM_EXP=y CONFIG_GPIO_BCM_VIRT=y # CONFIG_GPIO_DWAPB is not set # CONFIG_GPIO_GENERIC_PLATFORM is not set From 984d29e043436c9e094587b4a993244be27ef2d7 Mon Sep 17 00:00:00 2001 From: MilhouseVH Date: Mon, 13 Mar 2017 17:20:41 +0000 Subject: [PATCH 7/8] RBP: Add support for AudioInjector.net Octo sound card --- projects/RPi/linux/linux.arm.conf | 6 ++++-- projects/RPi2/linux/linux.arm.conf | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/projects/RPi/linux/linux.arm.conf b/projects/RPi/linux/linux.arm.conf index 07c4dd3074..b614eb0f7b 100644 --- a/projects/RPi/linux/linux.arm.conf +++ b/projects/RPi/linux/linux.arm.conf @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 4.10.0 Kernel Configuration +# Linux/arm 4.10.2 Kernel Configuration # CONFIG_ARM=y CONFIG_ARM_HAS_SG_CHAIN=y @@ -2804,6 +2804,7 @@ CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m CONFIG_SND_BCM2708_SOC_RASPIDAC3=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 @@ -2858,7 +2859,8 @@ CONFIG_SND_SOC_ADAU7002=m # CONFIG_SND_SOC_CS4270 is not set # CONFIG_SND_SOC_CS4271_I2C is not set # CONFIG_SND_SOC_CS4271_SPI is not set -# CONFIG_SND_SOC_CS42XX8_I2C is not set +CONFIG_SND_SOC_CS42XX8=m +CONFIG_SND_SOC_CS42XX8_I2C=m # CONFIG_SND_SOC_CS4349 is not set # CONFIG_SND_SOC_CS53L30 is not set # CONFIG_SND_SOC_ES8328 is not set diff --git a/projects/RPi2/linux/linux.arm.conf b/projects/RPi2/linux/linux.arm.conf index 832e333473..b8558ec8f7 100644 --- a/projects/RPi2/linux/linux.arm.conf +++ b/projects/RPi2/linux/linux.arm.conf @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 4.10.0 Kernel Configuration +# Linux/arm 4.10.2 Kernel Configuration # CONFIG_ARM=y CONFIG_ARM_HAS_SG_CHAIN=y @@ -2895,6 +2895,7 @@ CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m CONFIG_SND_BCM2708_SOC_RASPIDAC3=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 @@ -2949,7 +2950,8 @@ CONFIG_SND_SOC_ADAU7002=m # CONFIG_SND_SOC_CS4270 is not set # CONFIG_SND_SOC_CS4271_I2C is not set # CONFIG_SND_SOC_CS4271_SPI is not set -# CONFIG_SND_SOC_CS42XX8_I2C is not set +CONFIG_SND_SOC_CS42XX8=m +CONFIG_SND_SOC_CS42XX8_I2C=m # CONFIG_SND_SOC_CS4349 is not set # CONFIG_SND_SOC_CS53L30 is not set # CONFIG_SND_SOC_ES8328 is not set From 8ce3c16c328fb5a1fa380db6168af2a3c917f043 Mon Sep 17 00:00:00 2001 From: MilhouseVH Date: Mon, 13 Mar 2017 17:20:41 +0000 Subject: [PATCH 8/8] RBP: update firmware to 509beaa --- packages/graphics/bcm2835-driver/package.mk | 2 +- packages/tools/bcm2835-bootloader/package.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/graphics/bcm2835-driver/package.mk b/packages/graphics/bcm2835-driver/package.mk index 016b96cb44..25c10cf48b 100644 --- a/packages/graphics/bcm2835-driver/package.mk +++ b/packages/graphics/bcm2835-driver/package.mk @@ -17,7 +17,7 @@ ################################################################################ PKG_NAME="bcm2835-driver" -PKG_VERSION="1af015c" +PKG_VERSION="509beaa" PKG_ARCH="any" PKG_LICENSE="nonfree" PKG_SITE="http://www.broadcom.com" diff --git a/packages/tools/bcm2835-bootloader/package.mk b/packages/tools/bcm2835-bootloader/package.mk index 60b5a76aba..091a080cb9 100644 --- a/packages/tools/bcm2835-bootloader/package.mk +++ b/packages/tools/bcm2835-bootloader/package.mk @@ -17,7 +17,7 @@ ################################################################################ PKG_NAME="bcm2835-bootloader" -PKG_VERSION="1af015c" +PKG_VERSION="509beaa" PKG_ARCH="arm" PKG_LICENSE="nonfree" PKG_SITE="http://www.broadcom.com"