diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4')
922 files changed, 41563 insertions, 292 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Disable-forced-software-CS.patch b/target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Disable-forced-software-CS.patch new file mode 100644 index 0000000000..0abe5059c0 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Disable-forced-software-CS.patch @@ -0,0 +1,47 @@ +From dc1e3fefce7abd7532fbc74e26df61a8ced1dcd6 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.org> +Date: Tue, 15 Jan 2019 12:41:15 +0000 +Subject: [PATCH] spi: spi-bcm2835: Disable forced software CS + +With GPIO CS used by the DTBs, allow hardware CS to be selected by an +overlay. + +Signed-off-by: Phil Elwell <phil@raspberrypi.org> +--- + drivers/spi/spi-bcm2835.c | 37 ------------------------------------- + 1 file changed, 37 deletions(-) + +--- a/drivers/spi/spi-bcm2835.c ++++ b/drivers/spi/spi-bcm2835.c +@@ -1230,31 +1230,6 @@ static int bcm2835_spi_setup(struct spi_ + return -EINVAL; + } + +- /* +- * Translate native CS to GPIO +- * +- * FIXME: poking around in the gpiolib internals like this is +- * not very good practice. Find a way to locate the real problem +- * and fix it. Why is the GPIO descriptor in spi->cs_gpiod +- * sometimes not assigned correctly? Erroneous device trees? +- */ +- +- /* get the gpio chip for the base */ +- chip = gpiochip_find("pinctrl-bcm2835", chip_match_name); +- if (!chip) +- return 0; +- +- spi->cs_gpiod = gpiochip_request_own_desc(chip, 8 - spi->chip_select, +- DRV_NAME, +- GPIO_LOOKUP_FLAGS_DEFAULT, +- GPIOD_OUT_LOW); +- if (IS_ERR(spi->cs_gpiod)) +- return PTR_ERR(spi->cs_gpiod); +- +- /* and set up the "mode" and level */ +- dev_info(&spi->dev, "setting up native-CS%i to use GPIO\n", +- spi->chip_select); +- + return 0; + } + diff --git a/target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Re-enable-HW-CS.patch b/target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Re-enable-HW-CS.patch deleted file mode 100644 index 13dd356f93..0000000000 --- a/target/linux/bcm27xx/patches-5.4/950-0134-spi-spi-bcm2835-Re-enable-HW-CS.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 33b150a792ccde6eded4240dea0e3ec784b07d7c Mon Sep 17 00:00:00 2001 -From: Phil Elwell <phil@raspberrypi.org> -Date: Tue, 15 Jan 2019 12:39:50 +0000 -Subject: [PATCH] spi: spi-bcm2835: Re-enable HW CS - -Signed-off-by: Phil Elwell <phil@raspberrypi.org> ---- - drivers/spi/spi-bcm2835.c | 53 +++++++++++++++++++++++++++++++++++++-- - 1 file changed, 51 insertions(+), 2 deletions(-) - ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -1169,9 +1169,57 @@ static void bcm2835_spi_handle_err(struc - bcm2835_spi_reset_hw(ctlr); - } - --static int chip_match_name(struct gpio_chip *chip, void *data) -+static void bcm2835_spi_set_cs(struct spi_device *spi, bool gpio_level) - { -- return !strcmp(chip->label, data); -+ /* -+ * we can assume that we are "native" as per spi_set_cs -+ * calling us ONLY when cs_gpio is not set -+ * we can also assume that we are CS < 3 as per bcm2835_spi_setup -+ * we would not get called because of error handling there. -+ * the level passed is the electrical level not enabled/disabled -+ * so it has to get translated back to enable/disable -+ * see spi_set_cs in spi.c for the implementation -+ */ -+ -+ struct spi_master *master = spi->master; -+ struct bcm2835_spi *bs = spi_master_get_devdata(master); -+ u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); -+ bool enable; -+ -+ /* calculate the enable flag from the passed gpio_level */ -+ enable = (spi->mode & SPI_CS_HIGH) ? gpio_level : !gpio_level; -+ -+ /* set flags for "reverse" polarity in the registers */ -+ if (spi->mode & SPI_CS_HIGH) { -+ /* set the correct CS-bits */ -+ cs |= BCM2835_SPI_CS_CSPOL; -+ cs |= BCM2835_SPI_CS_CSPOL0 << spi->chip_select; -+ } else { -+ /* clean the CS-bits */ -+ cs &= ~BCM2835_SPI_CS_CSPOL; -+ cs &= ~(BCM2835_SPI_CS_CSPOL0 << spi->chip_select); -+ } -+ -+ /* select the correct chip_select depending on disabled/enabled */ -+ if (enable) { -+ /* set cs correctly */ -+ if (spi->mode & SPI_NO_CS) { -+ /* use the "undefined" chip-select */ -+ cs |= BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01; -+ } else { -+ /* set the chip select */ -+ cs &= ~(BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01); -+ cs |= spi->chip_select; -+ } -+ } else { -+ /* disable CSPOL which puts HW-CS into deselected state */ -+ cs &= ~BCM2835_SPI_CS_CSPOL; -+ /* use the "undefined" chip-select as precaution */ -+ cs |= BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01; -+ } -+ -+ /* finally set the calculated flags in SPI_CS */ -+ bcm2835_wr(bs, BCM2835_SPI_CS, cs); - } - - static int bcm2835_spi_setup(struct spi_device *spi) -@@ -1276,6 +1324,7 @@ static int bcm2835_spi_probe(struct plat - ctlr->bits_per_word_mask = SPI_BPW_MASK(8); - ctlr->num_chipselect = BCM2835_SPI_NUM_CS; - ctlr->setup = bcm2835_spi_setup; -+ ctlr->set_cs = bcm2835_spi_set_cs; - ctlr->transfer_one = bcm2835_spi_transfer_one; - ctlr->handle_err = bcm2835_spi_handle_err; - ctlr->prepare_message = bcm2835_spi_prepare_message; diff --git a/target/linux/bcm27xx/patches-5.4/950-0136-Added-driver-for-the-HiFiBerry-DAC-ADC-2694.patch b/target/linux/bcm27xx/patches-5.4/950-0135-Added-driver-for-the-HiFiBerry-DAC-ADC-2694.patch index cc379f55e1..cc379f55e1 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0136-Added-driver-for-the-HiFiBerry-DAC-ADC-2694.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0135-Added-driver-for-the-HiFiBerry-DAC-ADC-2694.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0135-spi-spi-bcm2835-Disable-forced-software-CS.patch b/target/linux/bcm27xx/patches-5.4/950-0135-spi-spi-bcm2835-Disable-forced-software-CS.patch deleted file mode 100644 index 752464087f..0000000000 --- a/target/linux/bcm27xx/patches-5.4/950-0135-spi-spi-bcm2835-Disable-forced-software-CS.patch +++ /dev/null @@ -1,47 +0,0 @@ -From dc1e3fefce7abd7532fbc74e26df61a8ced1dcd6 Mon Sep 17 00:00:00 2001 -From: Phil Elwell <phil@raspberrypi.org> -Date: Tue, 15 Jan 2019 12:41:15 +0000 -Subject: [PATCH] spi: spi-bcm2835: Disable forced software CS - -With GPIO CS used by the DTBs, allow hardware CS to be selected by an -overlay. - -Signed-off-by: Phil Elwell <phil@raspberrypi.org> ---- - drivers/spi/spi-bcm2835.c | 37 ------------------------------------- - 1 file changed, 37 deletions(-) - ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -1278,31 +1278,6 @@ static int bcm2835_spi_setup(struct spi_ - return -EINVAL; - } - -- /* -- * Translate native CS to GPIO -- * -- * FIXME: poking around in the gpiolib internals like this is -- * not very good practice. Find a way to locate the real problem -- * and fix it. Why is the GPIO descriptor in spi->cs_gpiod -- * sometimes not assigned correctly? Erroneous device trees? -- */ -- -- /* get the gpio chip for the base */ -- chip = gpiochip_find("pinctrl-bcm2835", chip_match_name); -- if (!chip) -- return 0; -- -- spi->cs_gpiod = gpiochip_request_own_desc(chip, 8 - spi->chip_select, -- DRV_NAME, -- GPIO_LOOKUP_FLAGS_DEFAULT, -- GPIOD_OUT_LOW); -- if (IS_ERR(spi->cs_gpiod)) -- return PTR_ERR(spi->cs_gpiod); -- -- /* and set up the "mode" and level */ -- dev_info(&spi->dev, "setting up native-CS%i to use GPIO\n", -- spi->chip_select); -- - return 0; - } - diff --git a/target/linux/bcm27xx/patches-5.4/950-0137-configs-Enable-the-AD193x-codecs.patch b/target/linux/bcm27xx/patches-5.4/950-0136-configs-Enable-the-AD193x-codecs.patch index bbf7c5a634..bbf7c5a634 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0137-configs-Enable-the-AD193x-codecs.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0136-configs-Enable-the-AD193x-codecs.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0138-lan78xx-EEE-support-is-now-a-PHY-property.patch b/target/linux/bcm27xx/patches-5.4/950-0137-lan78xx-EEE-support-is-now-a-PHY-property.patch index 2778f40a94..2778f40a94 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0138-lan78xx-EEE-support-is-now-a-PHY-property.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0137-lan78xx-EEE-support-is-now-a-PHY-property.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0139-Revert-staging-vchiq-delete-vchiq_killable.h.patch b/target/linux/bcm27xx/patches-5.4/950-0138-Revert-staging-vchiq-delete-vchiq_killable.h.patch index 0e314ec396..0e314ec396 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0139-Revert-staging-vchiq-delete-vchiq_killable.h.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0138-Revert-staging-vchiq-delete-vchiq_killable.h.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0140-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch b/target/linux/bcm27xx/patches-5.4/950-0139-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch index 09bfb7acad..09bfb7acad 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0140-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0139-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0141-gpu-vc4_firmware_kms-Fix-up-64-bit-compile-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-0140-gpu-vc4_firmware_kms-Fix-up-64-bit-compile-warnings.patch index 288281916c..288281916c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0141-gpu-vc4_firmware_kms-Fix-up-64-bit-compile-warnings.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0140-gpu-vc4_firmware_kms-Fix-up-64-bit-compile-warnings.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0142-bcm2835-dma-Add-support-for-per-channel-flags.patch b/target/linux/bcm27xx/patches-5.4/950-0141-bcm2835-dma-Add-support-for-per-channel-flags.patch index 8f68768588..8f68768588 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0142-bcm2835-dma-Add-support-for-per-channel-flags.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0141-bcm2835-dma-Add-support-for-per-channel-flags.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0143-drm-vc4-Programming-the-CTM-is-conditional-on-runnin.patch b/target/linux/bcm27xx/patches-5.4/950-0142-drm-vc4-Programming-the-CTM-is-conditional-on-runnin.patch index 0ec79adb27..0ec79adb27 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0143-drm-vc4-Programming-the-CTM-is-conditional-on-runnin.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0142-drm-vc4-Programming-the-CTM-is-conditional-on-runnin.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0144-rtc-rv3028-Add-backup-switchover-mode-support.patch b/target/linux/bcm27xx/patches-5.4/950-0143-rtc-rv3028-Add-backup-switchover-mode-support.patch index 375bd6e6b7..375bd6e6b7 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0144-rtc-rv3028-Add-backup-switchover-mode-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0143-rtc-rv3028-Add-backup-switchover-mode-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0145-Audiophonics-I-Sabre-9038Q2M-DAC-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0144-Audiophonics-I-Sabre-9038Q2M-DAC-driver.patch index 501e81092e..501e81092e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0145-Audiophonics-I-Sabre-9038Q2M-DAC-driver.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0144-Audiophonics-I-Sabre-9038Q2M-DAC-driver.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0146-lan78xx-use-default-alignment-for-rx-buffers.patch b/target/linux/bcm27xx/patches-5.4/950-0145-lan78xx-use-default-alignment-for-rx-buffers.patch index 1c2daad764..1c2daad764 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0146-lan78xx-use-default-alignment-for-rx-buffers.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0145-lan78xx-use-default-alignment-for-rx-buffers.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0147-Added-IQaudIO-Pi-Codec-board-support-2969.patch b/target/linux/bcm27xx/patches-5.4/950-0146-Added-IQaudIO-Pi-Codec-board-support-2969.patch index 2e4039c6b1..2e4039c6b1 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0147-Added-IQaudIO-Pi-Codec-board-support-2969.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0146-Added-IQaudIO-Pi-Codec-board-support-2969.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0148-sound-pcm512x-codec-Adding-352.8kHz-samplerate-suppo.patch b/target/linux/bcm27xx/patches-5.4/950-0147-sound-pcm512x-codec-Adding-352.8kHz-samplerate-suppo.patch index 838508559e..838508559e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0148-sound-pcm512x-codec-Adding-352.8kHz-samplerate-suppo.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0147-sound-pcm512x-codec-Adding-352.8kHz-samplerate-suppo.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0149-media-ov5647-Add-set_fmt-and-get_fmt-calls.patch b/target/linux/bcm27xx/patches-5.4/950-0148-media-ov5647-Add-set_fmt-and-get_fmt-calls.patch index 6b5aa2b664..6b5aa2b664 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0149-media-ov5647-Add-set_fmt-and-get_fmt-calls.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0148-media-ov5647-Add-set_fmt-and-get_fmt-calls.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0150-media-Documentation-DT-add-device-tree-for-PWDN-cont.patch b/target/linux/bcm27xx/patches-5.4/950-0149-media-Documentation-DT-add-device-tree-for-PWDN-cont.patch index 6d2cd03daa..6d2cd03daa 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0150-media-Documentation-DT-add-device-tree-for-PWDN-cont.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0149-media-Documentation-DT-add-device-tree-for-PWDN-cont.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0151-media-ov5647-Add-support-for-PWDN-GPIO.patch b/target/linux/bcm27xx/patches-5.4/950-0150-media-ov5647-Add-support-for-PWDN-GPIO.patch index 24b678f858..24b678f858 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0151-media-ov5647-Add-support-for-PWDN-GPIO.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0150-media-ov5647-Add-support-for-PWDN-GPIO.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0152-media-ov5647-Add-support-for-non-continuous-clock-mo.patch b/target/linux/bcm27xx/patches-5.4/950-0151-media-ov5647-Add-support-for-non-continuous-clock-mo.patch index 0fc4fa3420..0fc4fa3420 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0152-media-ov5647-Add-support-for-non-continuous-clock-mo.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0151-media-ov5647-Add-support-for-non-continuous-clock-mo.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0153-media-tc358743-Increase-FIFO-level-to-374.patch b/target/linux/bcm27xx/patches-5.4/950-0152-media-tc358743-Increase-FIFO-level-to-374.patch index 8ec643f102..8ec643f102 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0153-media-tc358743-Increase-FIFO-level-to-374.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0152-media-tc358743-Increase-FIFO-level-to-374.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0154-media-tc358743-fix-connected-active-CSI-2-lane-repor.patch b/target/linux/bcm27xx/patches-5.4/950-0153-media-tc358743-fix-connected-active-CSI-2-lane-repor.patch index 2357c878d7..2357c878d7 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0154-media-tc358743-fix-connected-active-CSI-2-lane-repor.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0153-media-tc358743-fix-connected-active-CSI-2-lane-repor.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0155-media-tc358743-Add-support-for-972Mbit-s-link-freq.patch b/target/linux/bcm27xx/patches-5.4/950-0154-media-tc358743-Add-support-for-972Mbit-s-link-freq.patch index 18ee169b1c..18ee169b1c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0155-media-tc358743-Add-support-for-972Mbit-s-link-freq.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0154-media-tc358743-Add-support-for-972Mbit-s-link-freq.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0156-media-tc358743-Check-I2C-succeeded-during-probe.patch b/target/linux/bcm27xx/patches-5.4/950-0155-media-tc358743-Check-I2C-succeeded-during-probe.patch index 653602b306..653602b306 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0156-media-tc358743-Check-I2C-succeeded-during-probe.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0155-media-tc358743-Check-I2C-succeeded-during-probe.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0157-media-adv7180-Default-to-the-first-valid-input.patch b/target/linux/bcm27xx/patches-5.4/950-0156-media-adv7180-Default-to-the-first-valid-input.patch index 7e2066b211..7e2066b211 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0157-media-adv7180-Default-to-the-first-valid-input.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0156-media-adv7180-Default-to-the-first-valid-input.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0158-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch b/target/linux/bcm27xx/patches-5.4/950-0157-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch index 75323fceb2..75323fceb2 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0158-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0157-media-adv7180-Add-YPrPb-support-for-ADV7282M.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0159-media-videodev2-Add-helper-defines-for-printing-FOUR.patch b/target/linux/bcm27xx/patches-5.4/950-0158-media-videodev2-Add-helper-defines-for-printing-FOUR.patch index 683e5611e1..683e5611e1 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0159-media-videodev2-Add-helper-defines-for-printing-FOUR.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0158-media-videodev2-Add-helper-defines-for-printing-FOUR.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0160-dt-bindings-Document-BCM283x-CSI2-CCP2-receiver.patch b/target/linux/bcm27xx/patches-5.4/950-0159-dt-bindings-Document-BCM283x-CSI2-CCP2-receiver.patch index d091a14bc5..d091a14bc5 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0160-dt-bindings-Document-BCM283x-CSI2-CCP2-receiver.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0159-dt-bindings-Document-BCM283x-CSI2-CCP2-receiver.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0161-MAINTAINERS-Add-entry-for-BCM2835-Unicam-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0160-MAINTAINERS-Add-entry-for-BCM2835-Unicam-driver.patch index 4b8b3aa431..4b8b3aa431 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0161-MAINTAINERS-Add-entry-for-BCM2835-Unicam-driver.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0160-MAINTAINERS-Add-entry-for-BCM2835-Unicam-driver.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0162-media-tc358743-Return-an-appropriate-colorspace-from.patch b/target/linux/bcm27xx/patches-5.4/950-0161-media-tc358743-Return-an-appropriate-colorspace-from.patch index b5b9105f4f..b5b9105f4f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0162-media-tc358743-Return-an-appropriate-colorspace-from.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0161-media-tc358743-Return-an-appropriate-colorspace-from.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0164-staging-bcm2835-camera-Fix-logical-continuation-spli.patch b/target/linux/bcm27xx/patches-5.4/950-0162-staging-bcm2835-camera-Fix-logical-continuation-spli.patch index c1cbff5671..c1cbff5671 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0164-staging-bcm2835-camera-Fix-logical-continuation-spli.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0162-staging-bcm2835-camera-Fix-logical-continuation-spli.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0165-staging-bcm2835-camera-Ensure-timestamps-never-go-ba.patch b/target/linux/bcm27xx/patches-5.4/950-0163-staging-bcm2835-camera-Ensure-timestamps-never-go-ba.patch index c9e18874ab..c9e18874ab 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0165-staging-bcm2835-camera-Ensure-timestamps-never-go-ba.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0163-staging-bcm2835-camera-Ensure-timestamps-never-go-ba.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0166-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch b/target/linux/bcm27xx/patches-5.4/950-0164-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch index 278d57b1bd..278d57b1bd 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0166-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0164-staging-vc04_services-Split-vchiq-mmal-into-a-module.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0167-staging-mmal-vchiq-Allocate-and-free-components-as-r.patch b/target/linux/bcm27xx/patches-5.4/950-0165-staging-mmal-vchiq-Allocate-and-free-components-as-r.patch index 53a6c07e9d..53a6c07e9d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0167-staging-mmal-vchiq-Allocate-and-free-components-as-r.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0165-staging-mmal-vchiq-Allocate-and-free-components-as-r.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0168-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch b/target/linux/bcm27xx/patches-5.4/950-0166-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch index 31f7c8a525..31f7c8a525 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0168-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0166-staging-mmal-vchiq-Avoid-use-of-bool-in-structures.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0169-staging-mmal-vchiq-Make-timeout-a-defined-parameter.patch b/target/linux/bcm27xx/patches-5.4/950-0167-staging-mmal-vchiq-Make-timeout-a-defined-parameter.patch index fa37fff35f..fa37fff35f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0169-staging-mmal-vchiq-Make-timeout-a-defined-parameter.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0167-staging-mmal-vchiq-Make-timeout-a-defined-parameter.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0170-staging-mmal-vchiq-Make-a-mmal_buf-struct-for-passin.patch b/target/linux/bcm27xx/patches-5.4/950-0168-staging-mmal-vchiq-Make-a-mmal_buf-struct-for-passin.patch index 95f5885c4a..95f5885c4a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0170-staging-mmal-vchiq-Make-a-mmal_buf-struct-for-passin.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0168-staging-mmal-vchiq-Make-a-mmal_buf-struct-for-passin.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0171-staging-mmal-vchiq-Add-support-for-event-callbacks.patch b/target/linux/bcm27xx/patches-5.4/950-0169-staging-mmal-vchiq-Add-support-for-event-callbacks.patch index 125f9d552e..125f9d552e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0171-staging-mmal-vchiq-Add-support-for-event-callbacks.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0169-staging-mmal-vchiq-Add-support-for-event-callbacks.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0172-staging-vc04_services-Support-sending-data-to-MMAL-p.patch b/target/linux/bcm27xx/patches-5.4/950-0170-staging-vc04_services-Support-sending-data-to-MMAL-p.patch index 5dec3c4127..5dec3c4127 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0172-staging-vc04_services-Support-sending-data-to-MMAL-p.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0170-staging-vc04_services-Support-sending-data-to-MMAL-p.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0173-staging-vc04_services-Fixup-vchiq-mmal-include-order.patch b/target/linux/bcm27xx/patches-5.4/950-0171-staging-vc04_services-Fixup-vchiq-mmal-include-order.patch index 7dd50f75bf..7dd50f75bf 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0173-staging-vc04_services-Fixup-vchiq-mmal-include-order.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0171-staging-vc04_services-Fixup-vchiq-mmal-include-order.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0174-staging-vc04_services-Add-new-vc-sm-cma-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0172-staging-vc04_services-Add-new-vc-sm-cma-driver.patch index d1d3df0890..d1d3df0890 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0174-staging-vc04_services-Add-new-vc-sm-cma-driver.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0172-staging-vc04_services-Add-new-vc-sm-cma-driver.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0175-staging-vc04_services-Use-vc-sm-cma-to-support-zero-.patch b/target/linux/bcm27xx/patches-5.4/950-0173-staging-vc04_services-Use-vc-sm-cma-to-support-zero-.patch index 62cce8a94e..62cce8a94e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0175-staging-vc04_services-Use-vc-sm-cma-to-support-zero-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0173-staging-vc04_services-Use-vc-sm-cma-to-support-zero-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0176-media-videobuf2-Allow-exporting-of-a-struct-dmabuf.patch b/target/linux/bcm27xx/patches-5.4/950-0174-media-videobuf2-Allow-exporting-of-a-struct-dmabuf.patch index 74d03540ad..74d03540ad 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0176-media-videobuf2-Allow-exporting-of-a-struct-dmabuf.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0174-media-videobuf2-Allow-exporting-of-a-struct-dmabuf.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0177-staging-vc04_services-Add-a-V4L2-M2M-codec-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0175-staging-vc04_services-Add-a-V4L2-M2M-codec-driver.patch index 2093cf05cc..2093cf05cc 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0177-staging-vc04_services-Add-a-V4L2-M2M-codec-driver.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0175-staging-vc04_services-Add-a-V4L2-M2M-codec-driver.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0178-staging-mmal-vchiq-Fix-client_component-for-64-bit-k.patch b/target/linux/bcm27xx/patches-5.4/950-0176-staging-mmal-vchiq-Fix-client_component-for-64-bit-k.patch index 5c64238741..5c64238741 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0178-staging-mmal-vchiq-Fix-client_component-for-64-bit-k.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0176-staging-mmal-vchiq-Fix-client_component-for-64-bit-k.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0179-clk-clk-bcm2835-Use-zd-when-printing-size_t.patch b/target/linux/bcm27xx/patches-5.4/950-0177-clk-clk-bcm2835-Use-zd-when-printing-size_t.patch index c8acb1a378..c8acb1a378 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0179-clk-clk-bcm2835-Use-zd-when-printing-size_t.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0177-clk-clk-bcm2835-Use-zd-when-printing-size_t.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0180-media-ov5647-Use-gpiod_set_value_cansleep.patch b/target/linux/bcm27xx/patches-5.4/950-0178-media-ov5647-Use-gpiod_set_value_cansleep.patch index d141349f98..d141349f98 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0180-media-ov5647-Use-gpiod_set_value_cansleep.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0178-media-ov5647-Use-gpiod_set_value_cansleep.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0181-staging-bcm2835-codec-variable-vb2-may-be-used-unini.patch b/target/linux/bcm27xx/patches-5.4/950-0179-staging-bcm2835-codec-variable-vb2-may-be-used-unini.patch index ecb867ba89..ecb867ba89 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0181-staging-bcm2835-codec-variable-vb2-may-be-used-unini.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0179-staging-bcm2835-codec-variable-vb2-may-be-used-unini.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0182-staging-bcm2835-codec-Fix-potentially-uninitialised-.patch b/target/linux/bcm27xx/patches-5.4/950-0180-staging-bcm2835-codec-Fix-potentially-uninitialised-.patch index bfda5a48c9..bfda5a48c9 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0182-staging-bcm2835-codec-Fix-potentially-uninitialised-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0180-staging-bcm2835-codec-Fix-potentially-uninitialised-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0183-staging-mmal_vchiq-Add-in-the-Bayer-encoding-formats.patch b/target/linux/bcm27xx/patches-5.4/950-0181-staging-mmal_vchiq-Add-in-the-Bayer-encoding-formats.patch index 715061a917..715061a917 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0183-staging-mmal_vchiq-Add-in-the-Bayer-encoding-formats.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0181-staging-mmal_vchiq-Add-in-the-Bayer-encoding-formats.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0184-staging-mmal-vchiq-Always-return-the-param-size-from.patch b/target/linux/bcm27xx/patches-5.4/950-0182-staging-mmal-vchiq-Always-return-the-param-size-from.patch index a8c8aebe1c..a8c8aebe1c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0184-staging-mmal-vchiq-Always-return-the-param-size-from.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0182-staging-mmal-vchiq-Always-return-the-param-size-from.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0185-staging-mmal-vchiq-If-the-VPU-returns-an-error-don-t.patch b/target/linux/bcm27xx/patches-5.4/950-0183-staging-mmal-vchiq-If-the-VPU-returns-an-error-don-t.patch index 60550ede00..60550ede00 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0185-staging-mmal-vchiq-If-the-VPU-returns-an-error-don-t.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0183-staging-mmal-vchiq-If-the-VPU-returns-an-error-don-t.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0186-staging-bcm2835_codec-Query-supported-formats-from-t.patch b/target/linux/bcm27xx/patches-5.4/950-0184-staging-bcm2835_codec-Query-supported-formats-from-t.patch index 00c3837c3c..00c3837c3c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0186-staging-bcm2835_codec-Query-supported-formats-from-t.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0184-staging-bcm2835_codec-Query-supported-formats-from-t.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0187-staging-bcm2835_codec-Add-support-for-the-ISP-as-an-.patch b/target/linux/bcm27xx/patches-5.4/950-0185-staging-bcm2835_codec-Add-support-for-the-ISP-as-an-.patch index 3bbe6814c3..3bbe6814c3 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0187-staging-bcm2835_codec-Add-support-for-the-ISP-as-an-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0185-staging-bcm2835_codec-Add-support-for-the-ISP-as-an-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0188-staging-bcm2835_codec-Add-an-option-for-ignoring-Bay.patch b/target/linux/bcm27xx/patches-5.4/950-0186-staging-bcm2835_codec-Add-an-option-for-ignoring-Bay.patch index 911612621c..911612621c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0188-staging-bcm2835_codec-Add-an-option-for-ignoring-Bay.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0186-staging-bcm2835_codec-Add-an-option-for-ignoring-Bay.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0189-staging-bcm2835_codec-Fix-handling-of-VB2_MEMORY_DMA.patch b/target/linux/bcm27xx/patches-5.4/950-0187-staging-bcm2835_codec-Fix-handling-of-VB2_MEMORY_DMA.patch index f2aeb91620..f2aeb91620 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0189-staging-bcm2835_codec-Fix-handling-of-VB2_MEMORY_DMA.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0187-staging-bcm2835_codec-Fix-handling-of-VB2_MEMORY_DMA.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0190-staging-mmal-vchiq-Update-mmal_parameters.h-with-rec.patch b/target/linux/bcm27xx/patches-5.4/950-0188-staging-mmal-vchiq-Update-mmal_parameters.h-with-rec.patch index 1198880531..1198880531 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0190-staging-mmal-vchiq-Update-mmal_parameters.h-with-rec.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0188-staging-mmal-vchiq-Update-mmal_parameters.h-with-rec.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0191-staging-bcm2835_codec-Include-timing-info-in-SPS-hea.patch b/target/linux/bcm27xx/patches-5.4/950-0189-staging-bcm2835_codec-Include-timing-info-in-SPS-hea.patch index b552698797..b552698797 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0191-staging-bcm2835_codec-Include-timing-info-in-SPS-hea.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0189-staging-bcm2835_codec-Include-timing-info-in-SPS-hea.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0192-staging-bcm2835-codec-NULL-component-handle-on-queue.patch b/target/linux/bcm27xx/patches-5.4/950-0190-staging-bcm2835-codec-NULL-component-handle-on-queue.patch index 45ba5acba0..45ba5acba0 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0192-staging-bcm2835-codec-NULL-component-handle-on-queue.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0190-staging-bcm2835-codec-NULL-component-handle-on-queue.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0193-staging-bcm2835_codec-Clean-up-logging-on-unloading-.patch b/target/linux/bcm27xx/patches-5.4/950-0191-staging-bcm2835_codec-Clean-up-logging-on-unloading-.patch index 8b110ca42e..8b110ca42e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0193-staging-bcm2835_codec-Clean-up-logging-on-unloading-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0191-staging-bcm2835_codec-Clean-up-logging-on-unloading-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0194-staging-bcm2835-codec-Refactor-default-resolution-co.patch b/target/linux/bcm27xx/patches-5.4/950-0192-staging-bcm2835-codec-Refactor-default-resolution-co.patch index 42ab46c1c4..42ab46c1c4 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0194-staging-bcm2835-codec-Refactor-default-resolution-co.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0192-staging-bcm2835-codec-Refactor-default-resolution-co.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0195-staging-bcm2835-codec-Correct-port-width-calc-for-tr.patch b/target/linux/bcm27xx/patches-5.4/950-0193-staging-bcm2835-codec-Correct-port-width-calc-for-tr.patch index cf57c4cc5f..cf57c4cc5f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0195-staging-bcm2835-codec-Correct-port-width-calc-for-tr.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0193-staging-bcm2835-codec-Correct-port-width-calc-for-tr.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0196-staging-bcm2835-codec-Remove-height-padding-for-ISP-.patch b/target/linux/bcm27xx/patches-5.4/950-0194-staging-bcm2835-codec-Remove-height-padding-for-ISP-.patch index 7a94ffa663..7a94ffa663 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0196-staging-bcm2835-codec-Remove-height-padding-for-ISP-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0194-staging-bcm2835-codec-Remove-height-padding-for-ISP-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0197-staging-mmal-vchiq-Free-the-event-context-for-contro.patch b/target/linux/bcm27xx/patches-5.4/950-0195-staging-mmal-vchiq-Free-the-event-context-for-contro.patch index c510e64c47..c510e64c47 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0197-staging-mmal-vchiq-Free-the-event-context-for-contro.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0195-staging-mmal-vchiq-Free-the-event-context-for-contro.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0198-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch b/target/linux/bcm27xx/patches-5.4/950-0196-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch index 6e846e4c7d..6e846e4c7d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0198-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0196-staging-mmal-vchiq-Fix-memory-leak-in-error-path.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0200-staging-bcm2835-codec-Convert-V4L2-nsec-timestamps-t.patch b/target/linux/bcm27xx/patches-5.4/950-0197-staging-bcm2835-codec-Convert-V4L2-nsec-timestamps-t.patch index 481ca484d5..481ca484d5 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0200-staging-bcm2835-codec-Convert-V4L2-nsec-timestamps-t.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0197-staging-bcm2835-codec-Convert-V4L2-nsec-timestamps-t.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0201-staging-bcm2835-codec-Add-support-for-setting-S_PARM.patch b/target/linux/bcm27xx/patches-5.4/950-0198-staging-bcm2835-codec-Add-support-for-setting-S_PARM.patch index dca6c2402b..dca6c2402b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0201-staging-bcm2835-codec-Add-support-for-setting-S_PARM.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0198-staging-bcm2835-codec-Add-support-for-setting-S_PARM.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0199-Bluetooth-Check-key-sizes-only-when-Secure-Simple-Pa.patch b/target/linux/bcm27xx/patches-5.4/950-0199-Bluetooth-Check-key-sizes-only-when-Secure-Simple-Pa.patch deleted file mode 100644 index 0de55097c5..0000000000 --- a/target/linux/bcm27xx/patches-5.4/950-0199-Bluetooth-Check-key-sizes-only-when-Secure-Simple-Pa.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 3e2981c7e55d75dc93a2f2e9bb6be2b9704c05f5 Mon Sep 17 00:00:00 2001 -From: Marcel Holtmann <marcel@holtmann.org> -Date: Wed, 22 May 2019 09:05:40 +0200 -Subject: [PATCH] Bluetooth: Check key sizes only when Secure Simple - Pairing is enabled - -The encryption is only mandatory to be enforced when both sides are using -Secure Simple Pairing and this means the key size check makes only sense -in that case. - -On legacy Bluetooth 2.0 and earlier devices like mice the encryption was -optional and thus causing an issue if the key size check is not bound to -using Secure Simple Pairing. - -Fixes: d5bb334a8e17 ("Bluetooth: Align minimum encryption key size for LE and BR/EDR connections") -Signed-off-by: Marcel Holtmann <marcel@holtmann.org> -Cc: stable@vger.kernel.org ---- - net/bluetooth/hci_conn.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - ---- a/net/bluetooth/hci_conn.c -+++ b/net/bluetooth/hci_conn.c -@@ -1302,8 +1302,13 @@ int hci_conn_check_link_mode(struct hci_ - return 0; - } - -- if (hci_conn_ssp_enabled(conn) && -- !test_bit(HCI_CONN_ENCRYPT, &conn->flags)) -+ /* If Secure Simple Pairing is not enabled, then legacy connection -+ * setup is used and no encryption or key sizes can be enforced. -+ */ -+ if (!hci_conn_ssp_enabled(conn)) -+ return 1; -+ -+ if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags)) - return 0; - - return 1; diff --git a/target/linux/bcm27xx/patches-5.4/950-0202-w1-w1-gpio-Make-GPIO-an-output-for-strong-pullup.patch b/target/linux/bcm27xx/patches-5.4/950-0199-w1-w1-gpio-Make-GPIO-an-output-for-strong-pullup.patch index c8d656a1cf..c8d656a1cf 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0202-w1-w1-gpio-Make-GPIO-an-output-for-strong-pullup.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0199-w1-w1-gpio-Make-GPIO-an-output-for-strong-pullup.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0203-arm-bcm2835-Fix-FIQ-early-ioremap.patch b/target/linux/bcm27xx/patches-5.4/950-0200-arm-bcm2835-Fix-FIQ-early-ioremap.patch index 1521476de1..1521476de1 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0203-arm-bcm2835-Fix-FIQ-early-ioremap.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0200-arm-bcm2835-Fix-FIQ-early-ioremap.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0204-Fix-copy_from_user-if-BCM2835_FAST_MEMCPY-n.patch b/target/linux/bcm27xx/patches-5.4/950-0201-Fix-copy_from_user-if-BCM2835_FAST_MEMCPY-n.patch index fc6efceacd..fc6efceacd 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0204-Fix-copy_from_user-if-BCM2835_FAST_MEMCPY-n.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0201-Fix-copy_from_user-if-BCM2835_FAST_MEMCPY-n.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0205-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch b/target/linux/bcm27xx/patches-5.4/950-0202-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch index d4ff3165b3..d4ff3165b3 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0205-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0202-dt-bindings-pci-Add-DT-docs-for-Brcmstb-PCIe-device.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0206-arm-bcm2835-DMA-can-only-address-1GB.patch b/target/linux/bcm27xx/patches-5.4/950-0203-arm-bcm2835-DMA-can-only-address-1GB.patch index 86ad707b95..86ad707b95 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0206-arm-bcm2835-DMA-can-only-address-1GB.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0203-arm-bcm2835-DMA-can-only-address-1GB.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0207-hwrng-iproc-rng200-Add-BCM2838-support.patch b/target/linux/bcm27xx/patches-5.4/950-0204-hwrng-iproc-rng200-Add-BCM2838-support.patch index c9eac88066..c9eac88066 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0207-hwrng-iproc-rng200-Add-BCM2838-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0204-hwrng-iproc-rng200-Add-BCM2838-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0208-vchiq-Add-36-bit-address-support.patch b/target/linux/bcm27xx/patches-5.4/950-0205-vchiq-Add-36-bit-address-support.patch index ca2a40488a..ca2a40488a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0208-vchiq-Add-36-bit-address-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0205-vchiq-Add-36-bit-address-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0209-bcm2835-pcm.c-Support-multichannel-audio.patch b/target/linux/bcm27xx/patches-5.4/950-0206-bcm2835-pcm.c-Support-multichannel-audio.patch index 133d346afb..133d346afb 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0209-bcm2835-pcm.c-Support-multichannel-audio.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0206-bcm2835-pcm.c-Support-multichannel-audio.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0210-bcmgenet-constrain-max-DMA-burst-length.patch b/target/linux/bcm27xx/patches-5.4/950-0207-bcmgenet-constrain-max-DMA-burst-length.patch index 5f683b506b..5f683b506b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0210-bcmgenet-constrain-max-DMA-burst-length.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0207-bcmgenet-constrain-max-DMA-burst-length.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0211-bcmgenet-Better-coalescing-parameter-defaults.patch b/target/linux/bcm27xx/patches-5.4/950-0208-bcmgenet-Better-coalescing-parameter-defaults.patch index 3a38f64436..3a38f64436 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0211-bcmgenet-Better-coalescing-parameter-defaults.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0208-bcmgenet-Better-coalescing-parameter-defaults.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0212-net-genet-enable-link-energy-detect-powerdown-for-ex.patch b/target/linux/bcm27xx/patches-5.4/950-0209-net-genet-enable-link-energy-detect-powerdown-for-ex.patch index ab43dfdfe5..ab43dfdfe5 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0212-net-genet-enable-link-energy-detect-powerdown-for-ex.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0209-net-genet-enable-link-energy-detect-powerdown-for-ex.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0213-usb-xhci-Disable-the-XHCI-5-second-timeout.patch b/target/linux/bcm27xx/patches-5.4/950-0210-usb-xhci-Disable-the-XHCI-5-second-timeout.patch index 2f5e08b7a2..2f5e08b7a2 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0213-usb-xhci-Disable-the-XHCI-5-second-timeout.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0210-usb-xhci-Disable-the-XHCI-5-second-timeout.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0214-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch b/target/linux/bcm27xx/patches-5.4/950-0211-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch index b2a8279da2..b2a8279da2 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0214-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0211-usb-xhci-Show-that-the-VIA-VL805-supports-LPM.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0212-spi-bcm2835-enable-shared-interrupt-support.patch b/target/linux/bcm27xx/patches-5.4/950-0212-spi-bcm2835-enable-shared-interrupt-support.patch new file mode 100644 index 0000000000..f82ae7d9f6 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0212-spi-bcm2835-enable-shared-interrupt-support.patch @@ -0,0 +1,35 @@ +From ac94635b678715af00a685ada0a1b60dfb54c771 Mon Sep 17 00:00:00 2001 +From: Martin Sperl <kernel@martin.sperl.org> +Date: Mon, 13 May 2019 11:05:27 +0000 +Subject: [PATCH] spi: bcm2835: enable shared interrupt support + +Add shared interrupt support for this driver. + +Signed-off-by: Martin Sperl <kernel@martin.sperl.org> +--- + drivers/spi/spi-bcm2835.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/spi/spi-bcm2835.c ++++ b/drivers/spi/spi-bcm2835.c +@@ -379,6 +379,10 @@ static irqreturn_t bcm2835_spi_interrupt + if (bs->tx_len && cs & BCM2835_SPI_CS_DONE) + bcm2835_wr_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE); + ++ /* check if we got interrupt enabled */ ++ if (!(bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_INTR)) ++ return IRQ_NONE; ++ + /* Read as many bytes as possible from FIFO */ + bcm2835_rd_fifo(bs); + /* Write as many bytes as possible to FIFO */ +@@ -1281,7 +1285,8 @@ static int bcm2835_spi_probe(struct plat + bcm2835_wr(bs, BCM2835_SPI_CS, + BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); + +- err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, 0, ++ err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, ++ IRQF_SHARED, + dev_name(&pdev->dev), ctlr); + if (err) { + dev_err(&pdev->dev, "could not request IRQ: %d\n", err); diff --git a/target/linux/bcm27xx/patches-5.4/950-0216-clk-bcm2835-Don-t-wait-for-pllh-lock.patch b/target/linux/bcm27xx/patches-5.4/950-0213-clk-bcm2835-Don-t-wait-for-pllh-lock.patch index 77625e8e23..77625e8e23 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0216-clk-bcm2835-Don-t-wait-for-pllh-lock.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0213-clk-bcm2835-Don-t-wait-for-pllh-lock.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0217-soc-bcm-bcm2835-pm-Add-support-for-2711.patch b/target/linux/bcm27xx/patches-5.4/950-0214-soc-bcm-bcm2835-pm-Add-support-for-2711.patch index 61bf911f28..61bf911f28 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0217-soc-bcm-bcm2835-pm-Add-support-for-2711.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0214-soc-bcm-bcm2835-pm-Add-support-for-2711.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0218-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch b/target/linux/bcm27xx/patches-5.4/950-0215-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch index 4e3805d9a7..4e3805d9a7 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0218-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0215-config-Permit-LPAE-and-PCIE_BRCMSTB-on-BCM2835.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0215-spi-bcm2835-enable-shared-interrupt-support.patch b/target/linux/bcm27xx/patches-5.4/950-0215-spi-bcm2835-enable-shared-interrupt-support.patch deleted file mode 100644 index 35a4e71245..0000000000 --- a/target/linux/bcm27xx/patches-5.4/950-0215-spi-bcm2835-enable-shared-interrupt-support.patch +++ /dev/null @@ -1,35 +0,0 @@ -From ac94635b678715af00a685ada0a1b60dfb54c771 Mon Sep 17 00:00:00 2001 -From: Martin Sperl <kernel@martin.sperl.org> -Date: Mon, 13 May 2019 11:05:27 +0000 -Subject: [PATCH] spi: bcm2835: enable shared interrupt support - -Add shared interrupt support for this driver. - -Signed-off-by: Martin Sperl <kernel@martin.sperl.org> ---- - drivers/spi/spi-bcm2835.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -379,6 +379,10 @@ static irqreturn_t bcm2835_spi_interrupt - if (bs->tx_len && cs & BCM2835_SPI_CS_DONE) - bcm2835_wr_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE); - -+ /* check if we got interrupt enabled */ -+ if (!(bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_INTR)) -+ return IRQ_NONE; -+ - /* Read as many bytes as possible from FIFO */ - bcm2835_rd_fifo(bs); - /* Write as many bytes as possible to FIFO */ -@@ -1330,7 +1334,8 @@ static int bcm2835_spi_probe(struct plat - bcm2835_wr(bs, BCM2835_SPI_CS, - BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); - -- err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, 0, -+ err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, -+ IRQF_SHARED, - dev_name(&pdev->dev), ctlr); - if (err) { - dev_err(&pdev->dev, "could not request IRQ: %d\n", err); diff --git a/target/linux/bcm27xx/patches-5.4/950-0219-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch b/target/linux/bcm27xx/patches-5.4/950-0216-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch index 3227f8c914..3227f8c914 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0219-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0216-clk-bcm2835-Add-support-for-setting-leaf-clock-rates.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0220-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch b/target/linux/bcm27xx/patches-5.4/950-0217-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch index bae0f84e1a..bae0f84e1a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0220-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0217-clk-bcm2835-Allow-reparenting-leaf-clocks-while-they.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0221-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch b/target/linux/bcm27xx/patches-5.4/950-0218-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch index 127e91cd24..127e91cd24 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0221-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0218-usb-add-plumbing-for-updating-interrupt-endpoint-int.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0222-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch b/target/linux/bcm27xx/patches-5.4/950-0219-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch index 5c241536dd..5c241536dd 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0222-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0219-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0223-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch b/target/linux/bcm27xx/patches-5.4/950-0220-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch index bf88c40780..bf88c40780 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0223-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0220-usbhid-call-usb_fixup_endpoint-after-mangling-interv.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0224-arm-bcm2835-Add-bcm2838-compatible-string.patch b/target/linux/bcm27xx/patches-5.4/950-0221-arm-bcm2835-Add-bcm2838-compatible-string.patch index f11ccb44e9..f11ccb44e9 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0224-arm-bcm2835-Add-bcm2838-compatible-string.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0221-arm-bcm2835-Add-bcm2838-compatible-string.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0225-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch b/target/linux/bcm27xx/patches-5.4/950-0222-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch index f95c8778a6..f95c8778a6 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0225-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0222-drm-vc4-Fix-oops-at-boot-with-firmwarekms-on-4.19.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0226-drm-v3d-Add-support-for-2711.patch b/target/linux/bcm27xx/patches-5.4/950-0223-drm-v3d-Add-support-for-2711.patch index 328c303083..328c303083 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0226-drm-v3d-Add-support-for-2711.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0223-drm-v3d-Add-support-for-2711.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0227-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch b/target/linux/bcm27xx/patches-5.4/950-0224-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch index 1581cc0070..1581cc0070 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0227-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0224-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0228-drm-v3d-Hook-up-the-runtime-PM-ops.patch b/target/linux/bcm27xx/patches-5.4/950-0225-drm-v3d-Hook-up-the-runtime-PM-ops.patch index 438922177d..438922177d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0228-drm-v3d-Hook-up-the-runtime-PM-ops.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0225-drm-v3d-Hook-up-the-runtime-PM-ops.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0229-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch b/target/linux/bcm27xx/patches-5.4/950-0226-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch index ccd6de065c..ccd6de065c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0229-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0226-drm-vc4-Fix-synchronization-firmwarekms-against-GL-r.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0230-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch b/target/linux/bcm27xx/patches-5.4/950-0227-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch index cb5b6d5aa7..cb5b6d5aa7 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0230-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0227-drm-vc4-Expose-the-format-modifiers-for-firmware-kms.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0231-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch b/target/linux/bcm27xx/patches-5.4/950-0228-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch index 3b03c98088..3b03c98088 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0231-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0228-drm-vc4-Fix-vblank-timestamping-for-firmwarekms.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0232-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch b/target/linux/bcm27xx/patches-5.4/950-0229-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch index fc84f535de..fc84f535de 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0232-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0229-gpu-vc4-fkms-Switch-to-the-newer-mailbox-frame-buffe.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0233-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch b/target/linux/bcm27xx/patches-5.4/950-0230-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch index 6878a0c26a..6878a0c26a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0233-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0230-drm-vc4-Add-an-overlay-plane-to-vc4-firmware-kms.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0234-drm-vc4-Increase-max-screen-size-to-4096x4096.patch b/target/linux/bcm27xx/patches-5.4/950-0231-drm-vc4-Increase-max-screen-size-to-4096x4096.patch index 92d3d35ead..92d3d35ead 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0234-drm-vc4-Increase-max-screen-size-to-4096x4096.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0231-drm-vc4-Increase-max-screen-size-to-4096x4096.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0235-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch b/target/linux/bcm27xx/patches-5.4/950-0232-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch index cbba43bf2e..cbba43bf2e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0235-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0232-drm-vc4-Add-support-for-multiple-displays-to-fkms.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0236-drm-vc4-Fix-build-warning.patch b/target/linux/bcm27xx/patches-5.4/950-0233-drm-vc4-Fix-build-warning.patch index 63246286a2..63246286a2 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0236-drm-vc4-Fix-build-warning.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0233-drm-vc4-Fix-build-warning.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0237-drm-vc4-Select-display-to-blank-during-initialisatio.patch b/target/linux/bcm27xx/patches-5.4/950-0234-drm-vc4-Select-display-to-blank-during-initialisatio.patch index 693292d04f..693292d04f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0237-drm-vc4-Select-display-to-blank-during-initialisatio.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0234-drm-vc4-Select-display-to-blank-during-initialisatio.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0238-drm-vc4-Remove-now-unused-structure.patch b/target/linux/bcm27xx/patches-5.4/950-0235-drm-vc4-Remove-now-unused-structure.patch index e6e4950e9a..e6e4950e9a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0238-drm-vc4-Remove-now-unused-structure.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0235-drm-vc4-Remove-now-unused-structure.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0239-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch b/target/linux/bcm27xx/patches-5.4/950-0236-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch index 6e463e70eb..6e463e70eb 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0239-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0236-drm-vc4-Query-the-display-ID-for-each-display-in-FKM.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0240-drm-vc4-Set-the-display-number-when-querying-the-dis.patch b/target/linux/bcm27xx/patches-5.4/950-0237-drm-vc4-Set-the-display-number-when-querying-the-dis.patch index 7b8efc7e73..7b8efc7e73 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0240-drm-vc4-Set-the-display-number-when-querying-the-dis.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0237-drm-vc4-Set-the-display-number-when-querying-the-dis.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0241-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch b/target/linux/bcm27xx/patches-5.4/950-0238-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch index 635340c082..635340c082 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0241-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0238-drm-vc4-Need-to-call-drm_crtc_vblank_-on-off-from-vc.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0242-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch b/target/linux/bcm27xx/patches-5.4/950-0239-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch index 43a2ffab16..43a2ffab16 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0242-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0239-drm-vc4-Add-support-for-H-V-flips-on-each-plane-for-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0243-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch b/target/linux/bcm27xx/patches-5.4/950-0240-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch index 6740f7fc6e..6740f7fc6e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0243-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0240-drm-vc4-Remove-unused-vc4_fkms_cancel_page_flip-func.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0244-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch b/target/linux/bcm27xx/patches-5.4/950-0241-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch index 05f50cd913..05f50cd913 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0244-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0241-drm-vc4-Iterate-over-all-planes-in-vc4_crtc_-dis-en-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0245-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch b/target/linux/bcm27xx/patches-5.4/950-0242-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch index 10a655ade1..10a655ade1 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0245-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0242-drm-vc4-Bring-fkms-into-line-with-kms-in-blocking-do.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0246-drm-vc4-Increase-max_width-height-to-7680.patch b/target/linux/bcm27xx/patches-5.4/950-0243-drm-vc4-Increase-max_width-height-to-7680.patch index 69d1470663..69d1470663 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0246-drm-vc4-Increase-max_width-height-to-7680.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0243-drm-vc4-Increase-max_width-height-to-7680.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0247-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch b/target/linux/bcm27xx/patches-5.4/950-0244-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch index 92400560ac..92400560ac 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0247-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0244-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0248-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch b/target/linux/bcm27xx/patches-5.4/950-0245-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch index 2a365798f5..2a365798f5 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0248-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0245-drm-vc4-firmware-kms-Remove-incorrect-overscan-suppo.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0249-drm-vc4-Log-flags-in-fkms-mode-set.patch b/target/linux/bcm27xx/patches-5.4/950-0246-drm-vc4-Log-flags-in-fkms-mode-set.patch index caca1c9f82..caca1c9f82 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0249-drm-vc4-Log-flags-in-fkms-mode-set.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0246-drm-vc4-Log-flags-in-fkms-mode-set.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0250-drm-vc4-firmware-kms-Fix-DSI-display-support.patch b/target/linux/bcm27xx/patches-5.4/950-0247-drm-vc4-firmware-kms-Fix-DSI-display-support.patch index 450c156602..450c156602 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0250-drm-vc4-firmware-kms-Fix-DSI-display-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0247-drm-vc4-firmware-kms-Fix-DSI-display-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0251-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch b/target/linux/bcm27xx/patches-5.4/950-0248-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch index a917540869..a917540869 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0251-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0248-drm-vc4-Probe-DPI-DSI-timings-from-the-firmware.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0252-drm-vc4-handle-the-case-where-there-are-no-available.patch b/target/linux/bcm27xx/patches-5.4/950-0249-drm-vc4-handle-the-case-where-there-are-no-available.patch index 72b205c2e4..72b205c2e4 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0252-drm-vc4-handle-the-case-where-there-are-no-available.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0249-drm-vc4-handle-the-case-where-there-are-no-available.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0253-drm-vc4-Support-the-VEC-in-FKMS.patch b/target/linux/bcm27xx/patches-5.4/950-0250-drm-vc4-Support-the-VEC-in-FKMS.patch index 87aeacd616..87aeacd616 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0253-drm-vc4-Support-the-VEC-in-FKMS.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0250-drm-vc4-Support-the-VEC-in-FKMS.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0254-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch b/target/linux/bcm27xx/patches-5.4/950-0251-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch index 8008619639..8008619639 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0254-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0251-drm-vc4-Fixup-typo-when-setting-HDMI-aspect-ratio.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0255-drm-vc4-Correct-SAND-support-for-FKMS.patch b/target/linux/bcm27xx/patches-5.4/950-0252-drm-vc4-Correct-SAND-support-for-FKMS.patch index dcf57e07e7..dcf57e07e7 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0255-drm-vc4-Correct-SAND-support-for-FKMS.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0252-drm-vc4-Correct-SAND-support-for-FKMS.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch b/target/linux/bcm27xx/patches-5.4/950-0253-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch index 186a7c891f..186a7c891f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0253-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0257-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch b/target/linux/bcm27xx/patches-5.4/950-0254-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch index 63931bf611..63931bf611 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0257-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0254-drm-vc4-Max-resolution-of-7680-is-conditional-on-bei.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0258-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch b/target/linux/bcm27xx/patches-5.4/950-0255-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch index 5d6171ce40..5d6171ce40 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0258-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0255-drm-vc4-Fix-T-format-modifiers-in-FKMS.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0259-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch b/target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch index 06e073b2ea..06e073b2ea 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0259-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-Remove-340MHz-clock-limit-from-FKMS-now-scra.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0260-drm-vc4-Add-status-of-which-display-is-updated-throu.patch b/target/linux/bcm27xx/patches-5.4/950-0257-drm-vc4-Add-status-of-which-display-is-updated-throu.patch index 8dd4caad1c..8dd4caad1c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0260-drm-vc4-Add-status-of-which-display-is-updated-throu.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0257-drm-vc4-Add-status-of-which-display-is-updated-throu.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0261-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch b/target/linux/bcm27xx/patches-5.4/950-0258-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch index 38b12e049f..38b12e049f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0261-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0258-drm-vc4-In-FKMS-look-at-the-modifiers-correctly-for-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0262-drm-vc4-Limit-fkms-to-modes-85Hz.patch b/target/linux/bcm27xx/patches-5.4/950-0259-drm-vc4-Limit-fkms-to-modes-85Hz.patch index 128ac5d54b..128ac5d54b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0262-drm-vc4-Limit-fkms-to-modes-85Hz.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0259-drm-vc4-Limit-fkms-to-modes-85Hz.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0263-drm-vc4-Ignore-HVS-unless-initialised.patch b/target/linux/bcm27xx/patches-5.4/950-0260-drm-vc4-Ignore-HVS-unless-initialised.patch index f17f4be37d..f17f4be37d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0263-drm-vc4-Ignore-HVS-unless-initialised.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0260-drm-vc4-Ignore-HVS-unless-initialised.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0264-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch b/target/linux/bcm27xx/patches-5.4/950-0261-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch index 9fd796850f..9fd796850f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0264-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0261-drm-vc4_dsi-Fix-DMA-channel-and-memory-leak-in-vc4-3.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0265-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch b/target/linux/bcm27xx/patches-5.4/950-0262-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch index 619eb811cd..619eb811cd 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0265-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0262-drm-vc4-Add-support-for-color-encoding-on-YUV-planes.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0266-tty-amba-pl011-Make-TX-optimisation-conditional.patch b/target/linux/bcm27xx/patches-5.4/950-0263-tty-amba-pl011-Make-TX-optimisation-conditional.patch index 58829c9e92..58829c9e92 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0266-tty-amba-pl011-Make-TX-optimisation-conditional.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0263-tty-amba-pl011-Make-TX-optimisation-conditional.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0267-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch b/target/linux/bcm27xx/patches-5.4/950-0264-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch index a125fdcb47..a125fdcb47 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0267-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0264-xhci-add-quirk-for-host-controllers-that-don-t-updat.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0268-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch b/target/linux/bcm27xx/patches-5.4/950-0265-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch index a3bc6c91b6..a3bc6c91b6 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0268-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0265-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0269-staging-vc04_services-fix-compiling-in-separate-dire.patch b/target/linux/bcm27xx/patches-5.4/950-0266-staging-vc04_services-fix-compiling-in-separate-dire.patch index b3d57dc2b3..b3d57dc2b3 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0269-staging-vc04_services-fix-compiling-in-separate-dire.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0266-staging-vc04_services-fix-compiling-in-separate-dire.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0270-clk-bcm2835-Avoid-null-pointer-exception.patch b/target/linux/bcm27xx/patches-5.4/950-0267-clk-bcm2835-Avoid-null-pointer-exception.patch index 8a529af7b0..8a529af7b0 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0270-clk-bcm2835-Avoid-null-pointer-exception.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0267-clk-bcm2835-Avoid-null-pointer-exception.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0271-drm-vc4-Prevent-load-tracking-from-breaking-FKMS.patch b/target/linux/bcm27xx/patches-5.4/950-0268-drm-vc4-Prevent-load-tracking-from-breaking-FKMS.patch index e4f178d0a2..e4f178d0a2 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0271-drm-vc4-Prevent-load-tracking-from-breaking-FKMS.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0268-drm-vc4-Prevent-load-tracking-from-breaking-FKMS.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0272-drm-v3d-HACK-gut-runtime-pm-for-now.patch b/target/linux/bcm27xx/patches-5.4/950-0269-drm-v3d-HACK-gut-runtime-pm-for-now.patch index ed69f2d157..ed69f2d157 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0272-drm-v3d-HACK-gut-runtime-pm-for-now.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0269-drm-v3d-HACK-gut-runtime-pm-for-now.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0273-drm-v3d-Clock-V3D-down-when-not-in-use.patch b/target/linux/bcm27xx/patches-5.4/950-0270-drm-v3d-Clock-V3D-down-when-not-in-use.patch index 782cc197d5..782cc197d5 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0273-drm-v3d-Clock-V3D-down-when-not-in-use.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0270-drm-v3d-Clock-V3D-down-when-not-in-use.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0274-According-to-5713-pdf-doc-CLOCK_CTRL-is-a-readonly-s.patch b/target/linux/bcm27xx/patches-5.4/950-0271-According-to-5713-pdf-doc-CLOCK_CTRL-is-a-readonly-s.patch index 267725d3ef..267725d3ef 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0274-According-to-5713-pdf-doc-CLOCK_CTRL-is-a-readonly-s.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0271-According-to-5713-pdf-doc-CLOCK_CTRL-is-a-readonly-s.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0275-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch b/target/linux/bcm27xx/patches-5.4/950-0272-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch index b5358cef29..b5358cef29 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0275-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0272-drm-vc4-Query-firmware-for-custom-HDMI-mode.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0276-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch b/target/linux/bcm27xx/patches-5.4/950-0273-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch index ce73e34541..ce73e34541 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0276-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0273-drm-vc4-Pass-the-drm-vrefresh-to-the-firmware-on-mod.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0277-drm-vc4-Add-support-for-margins-to-fkms.patch b/target/linux/bcm27xx/patches-5.4/950-0274-drm-vc4-Add-support-for-margins-to-fkms.patch index 968eb3ff55..968eb3ff55 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0277-drm-vc4-Add-support-for-margins-to-fkms.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0274-drm-vc4-Add-support-for-margins-to-fkms.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0278-drm-vc4-Ensure-zpos-is-always-initialised.patch b/target/linux/bcm27xx/patches-5.4/950-0275-drm-vc4-Ensure-zpos-is-always-initialised.patch index 32a13d9c86..32a13d9c86 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0278-drm-vc4-Ensure-zpos-is-always-initialised.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0275-drm-vc4-Ensure-zpos-is-always-initialised.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0279-adds-the-Hifiberry-DAC-ADC-PRO-version.patch b/target/linux/bcm27xx/patches-5.4/950-0276-adds-the-Hifiberry-DAC-ADC-PRO-version.patch index ed6d6db813..ed6d6db813 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0279-adds-the-Hifiberry-DAC-ADC-PRO-version.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0276-adds-the-Hifiberry-DAC-ADC-PRO-version.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0280-drm-vc4-A-present-but-empty-dmas-disables-audio.patch b/target/linux/bcm27xx/patches-5.4/950-0277-drm-vc4-A-present-but-empty-dmas-disables-audio.patch index b0c5b969f2..b0c5b969f2 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0280-drm-vc4-A-present-but-empty-dmas-disables-audio.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0277-drm-vc4-A-present-but-empty-dmas-disables-audio.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0281-Fixup-FKMS-interrupt-handing-for-non-existent-displa.patch b/target/linux/bcm27xx/patches-5.4/950-0278-Fixup-FKMS-interrupt-handing-for-non-existent-displa.patch index 60c9c9b03f..60c9c9b03f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0281-Fixup-FKMS-interrupt-handing-for-non-existent-displa.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0278-Fixup-FKMS-interrupt-handing-for-non-existent-displa.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0282-drivers-char-add-chardev-for-mmap-ing-the-RPiVid-con.patch b/target/linux/bcm27xx/patches-5.4/950-0279-drivers-char-add-chardev-for-mmap-ing-the-RPiVid-con.patch index 3f3c5ea148..3f3c5ea148 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0282-drivers-char-add-chardev-for-mmap-ing-the-RPiVid-con.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0279-drivers-char-add-chardev-for-mmap-ing-the-RPiVid-con.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0283-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch b/target/linux/bcm27xx/patches-5.4/950-0280-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch index ee886e31a5..ee886e31a5 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0283-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0280-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0284-drm-vc4-Add-Broadcast-RGB-connector-property.patch b/target/linux/bcm27xx/patches-5.4/950-0281-drm-vc4-Add-Broadcast-RGB-connector-property.patch index e221e41189..e221e41189 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0284-drm-vc4-Add-Broadcast-RGB-connector-property.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0281-drm-vc4-Add-Broadcast-RGB-connector-property.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0285-drm-vc4-fkms-Set-default-state-margin-at-reset.patch b/target/linux/bcm27xx/patches-5.4/950-0282-drm-vc4-fkms-Set-default-state-margin-at-reset.patch index 51664f3f98..51664f3f98 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0285-drm-vc4-fkms-Set-default-state-margin-at-reset.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0282-drm-vc4-fkms-Set-default-state-margin-at-reset.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0286-staging-bcm2835-codec-switch-to-multi-planar-API.patch b/target/linux/bcm27xx/patches-5.4/950-0283-staging-bcm2835-codec-switch-to-multi-planar-API.patch index c4eab3a02a..c4eab3a02a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0286-staging-bcm2835-codec-switch-to-multi-planar-API.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0283-staging-bcm2835-codec-switch-to-multi-planar-API.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0287-staging-bcm2835-codec-implement-V4L2_CID_MIN_BUFFERS.patch b/target/linux/bcm27xx/patches-5.4/950-0284-staging-bcm2835-codec-implement-V4L2_CID_MIN_BUFFERS.patch index 6e4af3e38d..6e4af3e38d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0287-staging-bcm2835-codec-implement-V4L2_CID_MIN_BUFFERS.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0284-staging-bcm2835-codec-implement-V4L2_CID_MIN_BUFFERS.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0288-staging-bcm2835-codec-set-device_caps-in-struct-vide.patch b/target/linux/bcm27xx/patches-5.4/950-0285-staging-bcm2835-codec-set-device_caps-in-struct-vide.patch index a194eaba14..a194eaba14 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0288-staging-bcm2835-codec-set-device_caps-in-struct-vide.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0285-staging-bcm2835-codec-set-device_caps-in-struct-vide.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0289-Add-HDMI1-facility-to-the-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0286-Add-HDMI1-facility-to-the-driver.patch index b18d1458fd..b18d1458fd 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0289-Add-HDMI1-facility-to-the-driver.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0286-Add-HDMI1-facility-to-the-driver.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0290-drm-vc4-Resolve-the-vblank-warnings-on-mode-switchin.patch b/target/linux/bcm27xx/patches-5.4/950-0287-drm-vc4-Resolve-the-vblank-warnings-on-mode-switchin.patch index e50bdee8ae..e50bdee8ae 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0290-drm-vc4-Resolve-the-vblank-warnings-on-mode-switchin.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0287-drm-vc4-Resolve-the-vblank-warnings-on-mode-switchin.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0291-drm-vc4-Remove-unused-mode-variable.patch b/target/linux/bcm27xx/patches-5.4/950-0288-drm-vc4-Remove-unused-mode-variable.patch index e82fc421d2..e82fc421d2 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0291-drm-vc4-Remove-unused-mode-variable.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0288-drm-vc4-Remove-unused-mode-variable.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0292-staging-bcm2835-codec-Expand-logging-on-format-setti.patch b/target/linux/bcm27xx/patches-5.4/950-0289-staging-bcm2835-codec-Expand-logging-on-format-setti.patch index d2ebeea7f7..d2ebeea7f7 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0292-staging-bcm2835-codec-Expand-logging-on-format-setti.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0289-staging-bcm2835-codec-Expand-logging-on-format-setti.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0293-staging-bcm2835-codec-Correct-bytesperline-on-format.patch b/target/linux/bcm27xx/patches-5.4/950-0290-staging-bcm2835-codec-Correct-bytesperline-on-format.patch index eaba48466a..eaba48466a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0293-staging-bcm2835-codec-Correct-bytesperline-on-format.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0290-staging-bcm2835-codec-Correct-bytesperline-on-format.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0294-drm-vc4-Add-missing-NULL-check-to-vc4_crtc_consume_e.patch b/target/linux/bcm27xx/patches-5.4/950-0291-drm-vc4-Add-missing-NULL-check-to-vc4_crtc_consume_e.patch index f29ba4dc5d..f29ba4dc5d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0294-drm-vc4-Add-missing-NULL-check-to-vc4_crtc_consume_e.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0291-drm-vc4-Add-missing-NULL-check-to-vc4_crtc_consume_e.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0295-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch b/target/linux/bcm27xx/patches-5.4/950-0292-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch index db1866d6e7..db1866d6e7 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0295-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0292-net-bcmgenet-Workaround-2-for-Pi4-Ethernet-fail.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0296-xhci-Use-more-event-ring-segment-table-entries.patch b/target/linux/bcm27xx/patches-5.4/950-0293-xhci-Use-more-event-ring-segment-table-entries.patch index 4b4766f739..4b4766f739 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0296-xhci-Use-more-event-ring-segment-table-entries.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0293-xhci-Use-more-event-ring-segment-table-entries.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0297-configs-arm64-bcm2711-Enable-V3D.patch b/target/linux/bcm27xx/patches-5.4/950-0294-configs-arm64-bcm2711-Enable-V3D.patch index f079fcf9ac..f079fcf9ac 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0297-configs-arm64-bcm2711-Enable-V3D.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0294-configs-arm64-bcm2711-Enable-V3D.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0298-staging-bcm2835-codec-add-support-for-V4L2_CID_MPEG_.patch b/target/linux/bcm27xx/patches-5.4/950-0295-staging-bcm2835-codec-add-support-for-V4L2_CID_MPEG_.patch index 42baf4c7d4..42baf4c7d4 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0298-staging-bcm2835-codec-add-support-for-V4L2_CID_MPEG_.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0295-staging-bcm2835-codec-add-support-for-V4L2_CID_MPEG_.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0299-staging-bcm2835-codec-remove-unnecessary-padding-on-.patch b/target/linux/bcm27xx/patches-5.4/950-0296-staging-bcm2835-codec-remove-unnecessary-padding-on-.patch index d2a50860d2..d2a50860d2 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0299-staging-bcm2835-codec-remove-unnecessary-padding-on-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0296-staging-bcm2835-codec-remove-unnecessary-padding-on-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0300-arch-arm-Add-model-string-to-cpuinfo.patch b/target/linux/bcm27xx/patches-5.4/950-0297-arch-arm-Add-model-string-to-cpuinfo.patch index 83c1592df9..83c1592df9 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0300-arch-arm-Add-model-string-to-cpuinfo.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0297-arch-arm-Add-model-string-to-cpuinfo.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0301-arch-arm64-Add-Revision-Serial-Model-to-cpuinfo.patch b/target/linux/bcm27xx/patches-5.4/950-0298-arch-arm64-Add-Revision-Serial-Model-to-cpuinfo.patch index af76b81f31..af76b81f31 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0301-arch-arm64-Add-Revision-Serial-Model-to-cpuinfo.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0298-arch-arm64-Add-Revision-Serial-Model-to-cpuinfo.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0302-staging-bcm2835-codec-Fix-non-documentation-comment-.patch b/target/linux/bcm27xx/patches-5.4/950-0299-staging-bcm2835-codec-Fix-non-documentation-comment-.patch index e1ec7d9e69..e1ec7d9e69 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0302-staging-bcm2835-codec-Fix-non-documentation-comment-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0299-staging-bcm2835-codec-Fix-non-documentation-comment-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0303-staging-bcm2835-codec-Fix-declaration-of-roles.patch b/target/linux/bcm27xx/patches-5.4/950-0300-staging-bcm2835-codec-Fix-declaration-of-roles.patch index 6e544199ba..6e544199ba 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0303-staging-bcm2835-codec-Fix-declaration-of-roles.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0300-staging-bcm2835-codec-Fix-declaration-of-roles.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0304-staging-bcm2835-codec-Add-role-to-device-name.patch b/target/linux/bcm27xx/patches-5.4/950-0301-staging-bcm2835-codec-Add-role-to-device-name.patch index e1539f4a71..e1539f4a71 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0304-staging-bcm2835-codec-Add-role-to-device-name.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0301-staging-bcm2835-codec-Add-role-to-device-name.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0305-staging-bcm2835-codec-Pass-driver-context-to-create-.patch b/target/linux/bcm27xx/patches-5.4/950-0302-staging-bcm2835-codec-Pass-driver-context-to-create-.patch index a0b86db2d6..a0b86db2d6 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0305-staging-bcm2835-codec-Pass-driver-context-to-create-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0302-staging-bcm2835-codec-Pass-driver-context-to-create-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0306-staging-bcm2835-codec-add-media-controller-support.patch b/target/linux/bcm27xx/patches-5.4/950-0303-staging-bcm2835-codec-add-media-controller-support.patch index f0ac32340c..f0ac32340c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0306-staging-bcm2835-codec-add-media-controller-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0303-staging-bcm2835-codec-add-media-controller-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0307-v4l2-Add-a-Greyworld-AWB-mode.patch b/target/linux/bcm27xx/patches-5.4/950-0304-v4l2-Add-a-Greyworld-AWB-mode.patch index 459646e7e7..459646e7e7 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0307-v4l2-Add-a-Greyworld-AWB-mode.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0304-v4l2-Add-a-Greyworld-AWB-mode.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0308-staging-bcm2835-camera-Add-greyworld-AWB-mode.patch b/target/linux/bcm27xx/patches-5.4/950-0305-staging-bcm2835-camera-Add-greyworld-AWB-mode.patch index e29c3800c4..e29c3800c4 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0308-staging-bcm2835-camera-Add-greyworld-AWB-mode.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0305-staging-bcm2835-camera-Add-greyworld-AWB-mode.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0309-drm-vc4-Fix-for-margins-in-composite-SDTV-mode-3223.patch b/target/linux/bcm27xx/patches-5.4/950-0306-drm-vc4-Fix-for-margins-in-composite-SDTV-mode-3223.patch index f6391e0b96..f6391e0b96 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0309-drm-vc4-Fix-for-margins-in-composite-SDTV-mode-3223.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0306-drm-vc4-Fix-for-margins-in-composite-SDTV-mode-3223.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0310-Add-Hifiberry-DAC-DSP-soundcard-driver-3224.patch b/target/linux/bcm27xx/patches-5.4/950-0307-Add-Hifiberry-DAC-DSP-soundcard-driver-3224.patch index 5855d0057b..5855d0057b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0310-Add-Hifiberry-DAC-DSP-soundcard-driver-3224.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0307-Add-Hifiberry-DAC-DSP-soundcard-driver-3224.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0311-staging-bcm2835-codec-Allow-height-of-1920.patch b/target/linux/bcm27xx/patches-5.4/950-0308-staging-bcm2835-codec-Allow-height-of-1920.patch index 862737f383..862737f383 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0311-staging-bcm2835-codec-Allow-height-of-1920.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0308-staging-bcm2835-codec-Allow-height-of-1920.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0312-staging-bcm2835-codec-Correct-g-s_selection-API-MPLA.patch b/target/linux/bcm27xx/patches-5.4/950-0309-staging-bcm2835-codec-Correct-g-s_selection-API-MPLA.patch index a91bcc3111..a91bcc3111 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0312-staging-bcm2835-codec-Correct-g-s_selection-API-MPLA.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0309-staging-bcm2835-codec-Correct-g-s_selection-API-MPLA.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0313-drm-v3d-Delete-pm_runtime-support.patch b/target/linux/bcm27xx/patches-5.4/950-0310-drm-v3d-Delete-pm_runtime-support.patch index 642be233ad..642be233ad 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0313-drm-v3d-Delete-pm_runtime-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0310-drm-v3d-Delete-pm_runtime-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0314-dts-Add-DTS-for-Pi-2B-rev-1.2-with-BCM2837-3235.patch b/target/linux/bcm27xx/patches-5.4/950-0311-dts-Add-DTS-for-Pi-2B-rev-1.2-with-BCM2837-3235.patch index c7eccdeed4..c7eccdeed4 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0314-dts-Add-DTS-for-Pi-2B-rev-1.2-with-BCM2837-3235.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0311-dts-Add-DTS-for-Pi-2B-rev-1.2-with-BCM2837-3235.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0315-drm-v3d-clean-caches-at-the-end-of-render-jobs-on-re.patch b/target/linux/bcm27xx/patches-5.4/950-0312-drm-v3d-clean-caches-at-the-end-of-render-jobs-on-re.patch index 961c0cc92b..961c0cc92b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0315-drm-v3d-clean-caches-at-the-end-of-render-jobs-on-re.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0312-drm-v3d-clean-caches-at-the-end-of-render-jobs-on-re.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0316-kbuild-Allow-.dtbo-overlays-to-be-built-piecemeal.patch b/target/linux/bcm27xx/patches-5.4/950-0313-kbuild-Allow-.dtbo-overlays-to-be-built-piecemeal.patch index d36f3eb802..d36f3eb802 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0316-kbuild-Allow-.dtbo-overlays-to-be-built-piecemeal.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0313-kbuild-Allow-.dtbo-overlays-to-be-built-piecemeal.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0317-dma-direct-Temporary-DMA-fix-on-arm64.patch b/target/linux/bcm27xx/patches-5.4/950-0314-dma-direct-Temporary-DMA-fix-on-arm64.patch index 327a77c424..327a77c424 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0317-dma-direct-Temporary-DMA-fix-on-arm64.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0314-dma-direct-Temporary-DMA-fix-on-arm64.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0318-ARM-bcm-Switch-board-clk-and-pinctrl-to-bcm2711-comp.patch b/target/linux/bcm27xx/patches-5.4/950-0315-ARM-bcm-Switch-board-clk-and-pinctrl-to-bcm2711-comp.patch index 254a621c83..254a621c83 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0318-ARM-bcm-Switch-board-clk-and-pinctrl-to-bcm2711-comp.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0315-ARM-bcm-Switch-board-clk-and-pinctrl-to-bcm2711-comp.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0319-pinctrl-bcm2835-Add-support-for-BCM2711-pull-up-func.patch b/target/linux/bcm27xx/patches-5.4/950-0316-pinctrl-bcm2835-Add-support-for-BCM2711-pull-up-func.patch index 2ad17cb17c..2ad17cb17c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0319-pinctrl-bcm2835-Add-support-for-BCM2711-pull-up-func.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0316-pinctrl-bcm2835-Add-support-for-BCM2711-pull-up-func.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0320-vchiq_2835_arm-suppress-warning.patch b/target/linux/bcm27xx/patches-5.4/950-0317-vchiq_2835_arm-suppress-warning.patch index 1be935caf4..1be935caf4 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0320-vchiq_2835_arm-suppress-warning.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0317-vchiq_2835_arm-suppress-warning.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0321-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch b/target/linux/bcm27xx/patches-5.4/950-0318-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch index 8ec836621d..8ec836621d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0321-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0318-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0322-drm-vc4-Add-support-for-YUV-color-encodings-and-rang.patch b/target/linux/bcm27xx/patches-5.4/950-0319-drm-vc4-Add-support-for-YUV-color-encodings-and-rang.patch index d7e6bbc561..d7e6bbc561 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0322-drm-vc4-Add-support-for-YUV-color-encodings-and-rang.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0319-drm-vc4-Add-support-for-YUV-color-encodings-and-rang.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0323-drm-vc4-Correct-handling-of-rotation-parameter-in-fk.patch b/target/linux/bcm27xx/patches-5.4/950-0320-drm-vc4-Correct-handling-of-rotation-parameter-in-fk.patch index f98002e99c..f98002e99c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0323-drm-vc4-Correct-handling-of-rotation-parameter-in-fk.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0320-drm-vc4-Correct-handling-of-rotation-parameter-in-fk.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0324-dt-bindings-Add-binding-for-the-Infineon-IRS1125-sen.patch b/target/linux/bcm27xx/patches-5.4/950-0321-dt-bindings-Add-binding-for-the-Infineon-IRS1125-sen.patch index 6f487bf7c6..6f487bf7c6 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0324-dt-bindings-Add-binding-for-the-Infineon-IRS1125-sen.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0321-dt-bindings-Add-binding-for-the-Infineon-IRS1125-sen.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0325-media-i2c-Add-a-driver-for-the-Infineon-IRS1125-dept.patch b/target/linux/bcm27xx/patches-5.4/950-0322-media-i2c-Add-a-driver-for-the-Infineon-IRS1125-dept.patch index 71e218d9ec..71e218d9ec 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0325-media-i2c-Add-a-driver-for-the-Infineon-IRS1125-dept.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0322-media-i2c-Add-a-driver-for-the-Infineon-IRS1125-dept.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0326-staging-bcm2835-codec-Add-support-for-ENUM_FRAMESIZE.patch b/target/linux/bcm27xx/patches-5.4/950-0323-staging-bcm2835-codec-Add-support-for-ENUM_FRAMESIZE.patch index ab3a971608..ab3a971608 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0326-staging-bcm2835-codec-Add-support-for-ENUM_FRAMESIZE.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0323-staging-bcm2835-codec-Add-support-for-ENUM_FRAMESIZE.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0327-staging-bcm2835-codec-Correct-buffer-type-check-on-G.patch b/target/linux/bcm27xx/patches-5.4/950-0324-staging-bcm2835-codec-Correct-buffer-type-check-on-G.patch index fb60b16e56..fb60b16e56 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0327-staging-bcm2835-codec-Correct-buffer-type-check-on-G.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0324-staging-bcm2835-codec-Correct-buffer-type-check-on-G.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0328-staging-bcm2835-codec-Set-default-and-error-check-ti.patch b/target/linux/bcm27xx/patches-5.4/950-0325-staging-bcm2835-codec-Set-default-and-error-check-ti.patch index 124b7ae742..124b7ae742 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0328-staging-bcm2835-codec-Set-default-and-error-check-ti.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0325-staging-bcm2835-codec-Set-default-and-error-check-ti.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0329-staging-bcm2835-codec-Fix-imbalance-in-dma_buf_get-d.patch b/target/linux/bcm27xx/patches-5.4/950-0326-staging-bcm2835-codec-Fix-imbalance-in-dma_buf_get-d.patch index f0fdfd29c8..f0fdfd29c8 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0329-staging-bcm2835-codec-Fix-imbalance-in-dma_buf_get-d.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0326-staging-bcm2835-codec-Fix-imbalance-in-dma_buf_get-d.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0330-drm-vc4-Added-calls-for-firmware-display-blank-unbla.patch b/target/linux/bcm27xx/patches-5.4/950-0327-drm-vc4-Added-calls-for-firmware-display-blank-unbla.patch index 812f69643f..812f69643f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0330-drm-vc4-Added-calls-for-firmware-display-blank-unbla.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0327-drm-vc4-Added-calls-for-firmware-display-blank-unbla.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0331-Revert-pinctrl-bcm2835-Pass-irqchip-when-adding-gpio.patch b/target/linux/bcm27xx/patches-5.4/950-0328-Revert-pinctrl-bcm2835-Pass-irqchip-when-adding-gpio.patch index f2cf28433a..f2cf28433a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0331-Revert-pinctrl-bcm2835-Pass-irqchip-when-adding-gpio.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0328-Revert-pinctrl-bcm2835-Pass-irqchip-when-adding-gpio.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0332-drm-v3d-Don-t-clear-MMU-control-bits-on-exception.patch b/target/linux/bcm27xx/patches-5.4/950-0329-drm-v3d-Don-t-clear-MMU-control-bits-on-exception.patch index a4a9dc817b..a4a9dc817b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0332-drm-v3d-Don-t-clear-MMU-control-bits-on-exception.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0329-drm-v3d-Don-t-clear-MMU-control-bits-on-exception.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0333-drm-v3d-Suppress-all-but-the-first-MMU-error.patch b/target/linux/bcm27xx/patches-5.4/950-0330-drm-v3d-Suppress-all-but-the-first-MMU-error.patch index 58f3a44aff..58f3a44aff 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0333-drm-v3d-Suppress-all-but-the-first-MMU-error.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0330-drm-v3d-Suppress-all-but-the-first-MMU-error.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0334-drm-v3d-Plug-dma_fence-leak.patch b/target/linux/bcm27xx/patches-5.4/950-0331-drm-v3d-Plug-dma_fence-leak.patch index a79912df1e..a79912df1e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0334-drm-v3d-Plug-dma_fence-leak.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0331-drm-v3d-Plug-dma_fence-leak.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0335-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch b/target/linux/bcm27xx/patches-5.4/950-0332-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch index cf8d563c72..cf8d563c72 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0335-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0332-staging-vchiq_arm-Register-vcsm-cma-as-a-platform-dr.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0336-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch b/target/linux/bcm27xx/patches-5.4/950-0333-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch index 9e1b777cac..9e1b777cac 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0336-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0333-staging-vchiq_arm-Register-bcm2835-codec-as-a-platfo.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0337-staging-bcm2835-codec-Fix-potential-memory-leak-of-i.patch b/target/linux/bcm27xx/patches-5.4/950-0334-staging-bcm2835-codec-Fix-potential-memory-leak-of-i.patch index 915ca1a29f..915ca1a29f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0337-staging-bcm2835-codec-Fix-potential-memory-leak-of-i.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0334-staging-bcm2835-codec-Fix-potential-memory-leak-of-i.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0339-net-bcmgenet-The-second-IRQ-is-optional.patch b/target/linux/bcm27xx/patches-5.4/950-0335-net-bcmgenet-The-second-IRQ-is-optional.patch index d48e6948d3..d48e6948d3 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0339-net-bcmgenet-The-second-IRQ-is-optional.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0335-net-bcmgenet-The-second-IRQ-is-optional.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0340-drm-v3d-The-third-IRQ-is-optional.patch b/target/linux/bcm27xx/patches-5.4/950-0336-drm-v3d-The-third-IRQ-is-optional.patch index 97ff76a6a3..97ff76a6a3 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0340-drm-v3d-The-third-IRQ-is-optional.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0336-drm-v3d-The-third-IRQ-is-optional.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0341-dwc_otg-Declare-DMA-capability-with-HCD_DMA-flag.patch b/target/linux/bcm27xx/patches-5.4/950-0337-dwc_otg-Declare-DMA-capability-with-HCD_DMA-flag.patch index afd72da286..afd72da286 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0341-dwc_otg-Declare-DMA-capability-with-HCD_DMA-flag.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0337-dwc_otg-Declare-DMA-capability-with-HCD_DMA-flag.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0342-rpi-poe-fan-fix-def_pwm1-writes.patch b/target/linux/bcm27xx/patches-5.4/950-0338-rpi-poe-fan-fix-def_pwm1-writes.patch index 8792d5954c..8792d5954c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0342-rpi-poe-fan-fix-def_pwm1-writes.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0338-rpi-poe-fan-fix-def_pwm1-writes.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0343-net-phy-2711-Allow-ethernet-LED-mode-to-be-set-via-d.patch b/target/linux/bcm27xx/patches-5.4/950-0339-net-phy-2711-Allow-ethernet-LED-mode-to-be-set-via-d.patch index b3e237fdf5..b3e237fdf5 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0343-net-phy-2711-Allow-ethernet-LED-mode-to-be-set-via-d.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0339-net-phy-2711-Allow-ethernet-LED-mode-to-be-set-via-d.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0344-overlays-smi-fix-typo-in-comment-3320.patch b/target/linux/bcm27xx/patches-5.4/950-0340-overlays-smi-fix-typo-in-comment-3320.patch index 0a4f630a4c..0a4f630a4c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0344-overlays-smi-fix-typo-in-comment-3320.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0340-overlays-smi-fix-typo-in-comment-3320.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0345-net-phy-2711-Change-the-default-ethernet-LED-actions.patch b/target/linux/bcm27xx/patches-5.4/950-0341-net-phy-2711-Change-the-default-ethernet-LED-actions.patch index d76fd0ec0d..d76fd0ec0d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0345-net-phy-2711-Change-the-default-ethernet-LED-actions.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0341-net-phy-2711-Change-the-default-ethernet-LED-actions.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0346-overlays-Add-apds9960-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0342-overlays-Add-apds9960-overlay.patch index f0f5368076..f0f5368076 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0346-overlays-Add-apds9960-overlay.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0342-overlays-Add-apds9960-overlay.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0347-overlays-Remove-hack-from-uart0-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0343-overlays-Remove-hack-from-uart0-overlay.patch index ac70b35413..ac70b35413 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0347-overlays-Remove-hack-from-uart0-overlay.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0343-overlays-Remove-hack-from-uart0-overlay.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0348-arm-dts-overlays-pitft35-resistive-add-upstream-comp.patch b/target/linux/bcm27xx/patches-5.4/950-0344-arm-dts-overlays-pitft35-resistive-add-upstream-comp.patch index ba19abb895..ba19abb895 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0348-arm-dts-overlays-pitft35-resistive-add-upstream-comp.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0344-arm-dts-overlays-pitft35-resistive-add-upstream-comp.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0349-v3d_drv-Handle-missing-clock-more-gracefully.patch b/target/linux/bcm27xx/patches-5.4/950-0345-v3d_drv-Handle-missing-clock-more-gracefully.patch index 812d6f1311..812d6f1311 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0349-v3d_drv-Handle-missing-clock-more-gracefully.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0345-v3d_drv-Handle-missing-clock-more-gracefully.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0350-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch b/target/linux/bcm27xx/patches-5.4/950-0346-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch index 1892a145fa..1892a145fa 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0350-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0346-v3d_gem-Kick-the-clock-so-firmware-knows-we-are-usin.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0351-clk-bcm2835-Disable-v3d-clock.patch b/target/linux/bcm27xx/patches-5.4/950-0347-clk-bcm2835-Disable-v3d-clock.patch index a7a5221fab..a7a5221fab 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0351-clk-bcm2835-Disable-v3d-clock.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0347-clk-bcm2835-Disable-v3d-clock.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0353-arm-dts-Correct-Pi-4B-LED-values.patch b/target/linux/bcm27xx/patches-5.4/950-0348-arm-dts-Correct-Pi-4B-LED-values.patch index a3bae521e7..a3bae521e7 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0353-arm-dts-Correct-Pi-4B-LED-values.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0348-arm-dts-Correct-Pi-4B-LED-values.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0354-drm-v3d-Set-dma_mask-as-well-as-coherent_dma_mask.patch b/target/linux/bcm27xx/patches-5.4/950-0349-drm-v3d-Set-dma_mask-as-well-as-coherent_dma_mask.patch index 67cdd44f29..67cdd44f29 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0354-drm-v3d-Set-dma_mask-as-well-as-coherent_dma_mask.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0349-drm-v3d-Set-dma_mask-as-well-as-coherent_dma_mask.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0355-arm-dts-2711-Add-pcie0-alias.patch b/target/linux/bcm27xx/patches-5.4/950-0350-arm-dts-2711-Add-pcie0-alias.patch index fa00fb1974..fa00fb1974 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0355-arm-dts-2711-Add-pcie0-alias.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0350-arm-dts-2711-Add-pcie0-alias.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0356-rpi-cirrus-wm5102-overlay-fix-pinctrl-configuration.patch b/target/linux/bcm27xx/patches-5.4/950-0351-rpi-cirrus-wm5102-overlay-fix-pinctrl-configuration.patch index 61f49d5ae4..61f49d5ae4 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0356-rpi-cirrus-wm5102-overlay-fix-pinctrl-configuration.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0351-rpi-cirrus-wm5102-overlay-fix-pinctrl-configuration.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0352-raspberrypi-cpufreq-Only-report-integer-pll-divisor-.patch b/target/linux/bcm27xx/patches-5.4/950-0352-raspberrypi-cpufreq-Only-report-integer-pll-divisor-.patch deleted file mode 100644 index 192b13b69a..0000000000 --- a/target/linux/bcm27xx/patches-5.4/950-0352-raspberrypi-cpufreq-Only-report-integer-pll-divisor-.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 814af1a008845b61a08111f2f9cf7e66511ab362 Mon Sep 17 00:00:00 2001 -From: popcornmix <popcornmix@gmail.com> -Date: Fri, 13 Sep 2019 13:45:11 +0100 -Subject: [PATCH] raspberrypi-cpufreq: Only report integer pll divisor - frequencies - ---- - drivers/cpufreq/raspberrypi-cpufreq.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/cpufreq/raspberrypi-cpufreq.c -+++ b/drivers/cpufreq/raspberrypi-cpufreq.c -@@ -8,6 +8,7 @@ - #include <linux/clk.h> - #include <linux/cpu.h> - #include <linux/cpufreq.h> -+#include <linux/math64.h> - #include <linux/module.h> - #include <linux/platform_device.h> - #include <linux/pm_opp.h> -@@ -22,6 +23,7 @@ static int raspberrypi_cpufreq_probe(str - unsigned long min, max; - unsigned long rate; - struct clk *clk; -+ int div; - int ret; - - cpu_dev = get_cpu_device(0); -@@ -44,7 +46,10 @@ static int raspberrypi_cpufreq_probe(str - max = roundup(clk_round_rate(clk, ULONG_MAX), RASPBERRYPI_FREQ_INTERVAL); - clk_put(clk); - -- for (rate = min; rate <= max; rate += RASPBERRYPI_FREQ_INTERVAL) { -+ for (div = 2; ; div++) { -+ rate = div_u64((u64)max * 2, div); -+ if (rate < min) -+ break; - ret = dev_pm_opp_add(cpu_dev, rate, 0); - if (ret) - goto remove_opp; diff --git a/target/linux/bcm27xx/patches-5.4/950-0357-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch b/target/linux/bcm27xx/patches-5.4/950-0352-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch index 0a6660b893..0a6660b893 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0357-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0352-staging-vchiq_arm-Set-up-dma-ranges-on-child-devices.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0358-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch b/target/linux/bcm27xx/patches-5.4/950-0353-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch index eb35a81023..eb35a81023 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0358-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0353-staging-vchiq-Use-the-old-dma-controller-for-OF-conf.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0359-dwc_otg-checking-the-urb-transfer_buffer-too-early-3.patch b/target/linux/bcm27xx/patches-5.4/950-0354-dwc_otg-checking-the-urb-transfer_buffer-too-early-3.patch index 3bc9abde27..3bc9abde27 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0359-dwc_otg-checking-the-urb-transfer_buffer-too-early-3.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0354-dwc_otg-checking-the-urb-transfer_buffer-too-early-3.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0360-overlays-Make-mcp342x-run-time-compatible.patch b/target/linux/bcm27xx/patches-5.4/950-0355-overlays-Make-mcp342x-run-time-compatible.patch index 1b4809db0d..1b4809db0d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0360-overlays-Make-mcp342x-run-time-compatible.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0355-overlays-Make-mcp342x-run-time-compatible.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0361-rpi-cirrus-wm5102-overlay-use-reset-gpios-instead-of.patch b/target/linux/bcm27xx/patches-5.4/950-0356-rpi-cirrus-wm5102-overlay-use-reset-gpios-instead-of.patch index e1ffd3b0b7..e1ffd3b0b7 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0361-rpi-cirrus-wm5102-overlay-use-reset-gpios-instead-of.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0356-rpi-cirrus-wm5102-overlay-use-reset-gpios-instead-of.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0362-sound-soc-only-first-codec-is-master-in-multicodec-s.patch b/target/linux/bcm27xx/patches-5.4/950-0357-sound-soc-only-first-codec-is-master-in-multicodec-s.patch index 263f3532f3..263f3532f3 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0362-sound-soc-only-first-codec-is-master-in-multicodec-s.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0357-sound-soc-only-first-codec-is-master-in-multicodec-s.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0363-Allow-simultaneous-use-of-JustBoom-DAC-and-Digi.patch b/target/linux/bcm27xx/patches-5.4/950-0358-Allow-simultaneous-use-of-JustBoom-DAC-and-Digi.patch index d0d1e28757..d0d1e28757 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0363-Allow-simultaneous-use-of-JustBoom-DAC-and-Digi.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0358-Allow-simultaneous-use-of-JustBoom-DAC-and-Digi.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0364-overlays-dht11-Allow-multiple-instantiation.patch b/target/linux/bcm27xx/patches-5.4/950-0359-overlays-dht11-Allow-multiple-instantiation.patch index b75f1d4988..b75f1d4988 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0364-overlays-dht11-Allow-multiple-instantiation.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0359-overlays-dht11-Allow-multiple-instantiation.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0365-overlays-i2c-rtc-Add-pcf85363-support.patch b/target/linux/bcm27xx/patches-5.4/950-0360-overlays-i2c-rtc-Add-pcf85363-support.patch index 93a699a66a..93a699a66a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0365-overlays-i2c-rtc-Add-pcf85363-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0360-overlays-i2c-rtc-Add-pcf85363-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0366-pinctrl-bcm2835-Remove-gpiochip-on-error.patch b/target/linux/bcm27xx/patches-5.4/950-0361-pinctrl-bcm2835-Remove-gpiochip-on-error.patch index 31a1a24caf..31a1a24caf 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0366-pinctrl-bcm2835-Remove-gpiochip-on-error.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0361-pinctrl-bcm2835-Remove-gpiochip-on-error.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0367-pinctrl-bcm2835-Change-init-order-for-gpio-hogs.patch b/target/linux/bcm27xx/patches-5.4/950-0362-pinctrl-bcm2835-Change-init-order-for-gpio-hogs.patch index 3865ae11fb..3865ae11fb 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0367-pinctrl-bcm2835-Change-init-order-for-gpio-hogs.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0362-pinctrl-bcm2835-Change-init-order-for-gpio-hogs.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0368-Pisound-MIDI-communication-fixes-for-scaled-down-CPU.patch b/target/linux/bcm27xx/patches-5.4/950-0363-Pisound-MIDI-communication-fixes-for-scaled-down-CPU.patch index 0221803993..0221803993 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0368-Pisound-MIDI-communication-fixes-for-scaled-down-CPU.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0363-Pisound-MIDI-communication-fixes-for-scaled-down-CPU.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0369-ARM-dts-bcm283x-Remove-simple-bus-from-fixed-clocks.patch b/target/linux/bcm27xx/patches-5.4/950-0364-ARM-dts-bcm283x-Remove-simple-bus-from-fixed-clocks.patch index db90055343..db90055343 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0369-ARM-dts-bcm283x-Remove-simple-bus-from-fixed-clocks.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0364-ARM-dts-bcm283x-Remove-simple-bus-from-fixed-clocks.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0370-ARM-dts-bcm283x-Move-system-timer-back-to-bcm283x.dt.patch b/target/linux/bcm27xx/patches-5.4/950-0365-ARM-dts-bcm283x-Move-system-timer-back-to-bcm283x.dt.patch index 3ececc8f92..3ececc8f92 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0370-ARM-dts-bcm283x-Move-system-timer-back-to-bcm283x.dt.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0365-ARM-dts-bcm283x-Move-system-timer-back-to-bcm283x.dt.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0371-ARM-dts-bcm283x-Move-pixelvalve-to-bcm2835-common.dt.patch b/target/linux/bcm27xx/patches-5.4/950-0366-ARM-dts-bcm283x-Move-pixelvalve-to-bcm2835-common.dt.patch index 218a846fa3..218a846fa3 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0371-ARM-dts-bcm283x-Move-pixelvalve-to-bcm2835-common.dt.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0366-ARM-dts-bcm283x-Move-pixelvalve-to-bcm2835-common.dt.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0372-ARM-dts-bcm2838-rpi-4-b-Fix-memory-node.patch b/target/linux/bcm27xx/patches-5.4/950-0367-ARM-dts-bcm2838-rpi-4-b-Fix-memory-node.patch index 1acf84b7ce..1acf84b7ce 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0372-ARM-dts-bcm2838-rpi-4-b-Fix-memory-node.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0367-ARM-dts-bcm2838-rpi-4-b-Fix-memory-node.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0373-ARM-dts-bcm2838-rpi-4-b-Backport-BT-part-from-upstre.patch b/target/linux/bcm27xx/patches-5.4/950-0368-ARM-dts-bcm2838-rpi-4-b-Backport-BT-part-from-upstre.patch index ce0b8811d0..ce0b8811d0 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0373-ARM-dts-bcm2838-rpi-4-b-Backport-BT-part-from-upstre.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0368-ARM-dts-bcm2838-rpi-4-b-Backport-BT-part-from-upstre.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0374-ARM-dts-bcm2838-Backport-node-names-from-upstream.patch b/target/linux/bcm27xx/patches-5.4/950-0369-ARM-dts-bcm2838-Backport-node-names-from-upstream.patch index fb3a6a3806..fb3a6a3806 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0374-ARM-dts-bcm2838-Backport-node-names-from-upstream.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0369-ARM-dts-bcm2838-Backport-node-names-from-upstream.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0375-ARM-dts-bcm283x-Move-intc-label-to-bcm2835-common.dt.patch b/target/linux/bcm27xx/patches-5.4/950-0370-ARM-dts-bcm283x-Move-intc-label-to-bcm2835-common.dt.patch index ef26293498..ef26293498 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0375-ARM-dts-bcm283x-Move-intc-label-to-bcm2835-common.dt.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0370-ARM-dts-bcm283x-Move-intc-label-to-bcm2835-common.dt.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0376-ARM-dts-bcm2838-Remove-always-on-from-armv7-timer.patch b/target/linux/bcm27xx/patches-5.4/950-0371-ARM-dts-bcm2838-Remove-always-on-from-armv7-timer.patch index 0e2a78649f..0e2a78649f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0376-ARM-dts-bcm2838-Remove-always-on-from-armv7-timer.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0371-ARM-dts-bcm2838-Remove-always-on-from-armv7-timer.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0377-net-bcmgenet-Add-RGMII_RXID-support.patch b/target/linux/bcm27xx/patches-5.4/950-0372-net-bcmgenet-Add-RGMII_RXID-support.patch index 0e13394c7f..0e13394c7f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0377-net-bcmgenet-Add-RGMII_RXID-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0372-net-bcmgenet-Add-RGMII_RXID-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0378-ARM-dts-bcm2838-Backport-genet-from-upstream.patch b/target/linux/bcm27xx/patches-5.4/950-0373-ARM-dts-bcm2838-Backport-genet-from-upstream.patch index ffd7d8e540..ffd7d8e540 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0378-ARM-dts-bcm2838-Backport-genet-from-upstream.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0373-ARM-dts-bcm2838-Backport-genet-from-upstream.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0379-ARM-bcm-Backport-BCM2711-support-from-upstream.patch b/target/linux/bcm27xx/patches-5.4/950-0374-ARM-bcm-Backport-BCM2711-support-from-upstream.patch index 8d16152154..8d16152154 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0379-ARM-bcm-Backport-BCM2711-support-from-upstream.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0374-ARM-bcm-Backport-BCM2711-support-from-upstream.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0380-hwrng-iproc-rng200-Add-support-for-BCM2711.patch b/target/linux/bcm27xx/patches-5.4/950-0375-hwrng-iproc-rng200-Add-support-for-BCM2711.patch index 7a47128837..7a47128837 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0380-hwrng-iproc-rng200-Add-support-for-BCM2711.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0375-hwrng-iproc-rng200-Add-support-for-BCM2711.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0381-ARM-dts-bcm2838-Add-upstream-RNG-compatible.patch b/target/linux/bcm27xx/patches-5.4/950-0376-ARM-dts-bcm2838-Add-upstream-RNG-compatible.patch index 2feda7389e..2feda7389e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0381-ARM-dts-bcm2838-Add-upstream-RNG-compatible.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0376-ARM-dts-bcm2838-Add-upstream-RNG-compatible.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0382-driver-char-rpivid-Destroy-the-legacy-device-on-remo.patch b/target/linux/bcm27xx/patches-5.4/950-0377-driver-char-rpivid-Destroy-the-legacy-device-on-remo.patch index 49d885cd73..49d885cd73 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0382-driver-char-rpivid-Destroy-the-legacy-device-on-remo.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0377-driver-char-rpivid-Destroy-the-legacy-device-on-remo.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0383-driver-char-rpivid-Clean-up-error-handling-use-of-ER.patch b/target/linux/bcm27xx/patches-5.4/950-0378-driver-char-rpivid-Clean-up-error-handling-use-of-ER.patch index b61e2c5cfe..b61e2c5cfe 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0383-driver-char-rpivid-Clean-up-error-handling-use-of-ER.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0378-driver-char-rpivid-Clean-up-error-handling-use-of-ER.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0384-driver-char-rpivid-Add-error-handling-to-the-legacy-.patch b/target/linux/bcm27xx/patches-5.4/950-0379-driver-char-rpivid-Add-error-handling-to-the-legacy-.patch index 52aa87ed04..52aa87ed04 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0384-driver-char-rpivid-Add-error-handling-to-the-legacy-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0379-driver-char-rpivid-Add-error-handling-to-the-legacy-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0385-driver-char-rpivid-Fix-coding-style-whitespace-issue.patch b/target/linux/bcm27xx/patches-5.4/950-0380-driver-char-rpivid-Fix-coding-style-whitespace-issue.patch index 26d0c9894b..26d0c9894b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0385-driver-char-rpivid-Fix-coding-style-whitespace-issue.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0380-driver-char-rpivid-Fix-coding-style-whitespace-issue.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0386-driver-char-rpimem-Add-SPDX-licence-header.patch b/target/linux/bcm27xx/patches-5.4/950-0381-driver-char-rpimem-Add-SPDX-licence-header.patch index 86b9400ac6..86b9400ac6 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0386-driver-char-rpimem-Add-SPDX-licence-header.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0381-driver-char-rpimem-Add-SPDX-licence-header.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0387-driver-char-rpivid-Fix-access-to-freed-memory.patch b/target/linux/bcm27xx/patches-5.4/950-0382-driver-char-rpivid-Fix-access-to-freed-memory.patch index 67147fa58d..67147fa58d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0387-driver-char-rpivid-Fix-access-to-freed-memory.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0382-driver-char-rpivid-Fix-access-to-freed-memory.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0388-add-BME680-to-i2c-sensor-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0383-add-BME680-to-i2c-sensor-overlay.patch index 0c2fe6aa8a..0c2fe6aa8a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0388-add-BME680-to-i2c-sensor-overlay.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0383-add-BME680-to-i2c-sensor-overlay.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0389-dwc_otg-constrain-endpoint-max-packet-and-transfer-s.patch b/target/linux/bcm27xx/patches-5.4/950-0384-dwc_otg-constrain-endpoint-max-packet-and-transfer-s.patch index 4de95a5449..4de95a5449 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0389-dwc_otg-constrain-endpoint-max-packet-and-transfer-s.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0384-dwc_otg-constrain-endpoint-max-packet-and-transfer-s.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0390-dwc_otg-fiq_fsm-pause-when-cancelling-split-transact.patch b/target/linux/bcm27xx/patches-5.4/950-0385-dwc_otg-fiq_fsm-pause-when-cancelling-split-transact.patch index 0a7356ffa2..0a7356ffa2 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0390-dwc_otg-fiq_fsm-pause-when-cancelling-split-transact.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0385-dwc_otg-fiq_fsm-pause-when-cancelling-split-transact.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0391-dwc_otg-fiq_fsm-add-a-barrier-on-entry-into-FIQ-hand.patch b/target/linux/bcm27xx/patches-5.4/950-0386-dwc_otg-fiq_fsm-add-a-barrier-on-entry-into-FIQ-hand.patch index e986f425ff..e986f425ff 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0391-dwc_otg-fiq_fsm-add-a-barrier-on-entry-into-FIQ-hand.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0386-dwc_otg-fiq_fsm-add-a-barrier-on-entry-into-FIQ-hand.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0392-Add-universal-device-tree-overlay-for-SPI-devices.patch b/target/linux/bcm27xx/patches-5.4/950-0387-Add-universal-device-tree-overlay-for-SPI-devices.patch index cb8fa91bef..cb8fa91bef 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0392-Add-universal-device-tree-overlay-for-SPI-devices.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0387-Add-universal-device-tree-overlay-for-SPI-devices.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0393-sound-Add-the-HiFiBerry-DAC-HD-version.patch b/target/linux/bcm27xx/patches-5.4/950-0388-sound-Add-the-HiFiBerry-DAC-HD-version.patch index 6b9a6bd29c..6b9a6bd29c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0393-sound-Add-the-HiFiBerry-DAC-HD-version.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0388-sound-Add-the-HiFiBerry-DAC-HD-version.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0394-Initialise-rpi-firmware-before-clk-bcm2835.patch b/target/linux/bcm27xx/patches-5.4/950-0389-Initialise-rpi-firmware-before-clk-bcm2835.patch index cdd5e7e9ab..cdd5e7e9ab 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0394-Initialise-rpi-firmware-before-clk-bcm2835.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0389-Initialise-rpi-firmware-before-clk-bcm2835.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0395-Fix-master-mode-settings-of-HiFiBerry-DAC-ADC-PRO-ca.patch b/target/linux/bcm27xx/patches-5.4/950-0390-Fix-master-mode-settings-of-HiFiBerry-DAC-ADC-PRO-ca.patch index 54b366f65a..54b366f65a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0395-Fix-master-mode-settings-of-HiFiBerry-DAC-ADC-PRO-ca.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0390-Fix-master-mode-settings-of-HiFiBerry-DAC-ADC-PRO-ca.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0396-overlays-Use-preferred-compatible-strings.patch b/target/linux/bcm27xx/patches-5.4/950-0391-overlays-Use-preferred-compatible-strings.patch index 6a246050cf..6a246050cf 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0396-overlays-Use-preferred-compatible-strings.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0391-overlays-Use-preferred-compatible-strings.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0397-tty-amba-pl011-Add-un-throttle-support.patch b/target/linux/bcm27xx/patches-5.4/950-0392-tty-amba-pl011-Add-un-throttle-support.patch index ced0bf2b79..ced0bf2b79 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0397-tty-amba-pl011-Add-un-throttle-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0392-tty-amba-pl011-Add-un-throttle-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0398-Fix-i2c-pwm-pca9685a-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0393-Fix-i2c-pwm-pca9685a-overlay.patch index 17bdf3984e..17bdf3984e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0398-Fix-i2c-pwm-pca9685a-overlay.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0393-Fix-i2c-pwm-pca9685a-overlay.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0399-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-PRO-sound-.patch b/target/linux/bcm27xx/patches-5.4/950-0394-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-PRO-sound-.patch index 397a2c3331..397a2c3331 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0399-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-PRO-sound-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0394-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-PRO-sound-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0400-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-sound-card.patch b/target/linux/bcm27xx/patches-5.4/950-0395-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-sound-card.patch index bd8f405ef8..bd8f405ef8 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0400-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-sound-card.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0395-adds-LED-OFF-feature-to-HiFiBerry-DAC-ADC-sound-card.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0401-adds-LED-OFF-feature-to-HiFiBerry-DAC-DAC-PRO-sound-.patch b/target/linux/bcm27xx/patches-5.4/950-0396-adds-LED-OFF-feature-to-HiFiBerry-DAC-DAC-PRO-sound-.patch index a5c3d40512..a5c3d40512 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0401-adds-LED-OFF-feature-to-HiFiBerry-DAC-DAC-PRO-sound-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0396-adds-LED-OFF-feature-to-HiFiBerry-DAC-DAC-PRO-sound-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0402-pisound-Added-reading-Pisound-board-hardware-revisio.patch b/target/linux/bcm27xx/patches-5.4/950-0397-pisound-Added-reading-Pisound-board-hardware-revisio.patch index df6f526e2e..df6f526e2e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0402-pisound-Added-reading-Pisound-board-hardware-revisio.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0397-pisound-Added-reading-Pisound-board-hardware-revisio.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0403-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch b/target/linux/bcm27xx/patches-5.4/950-0398-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch index 4713dde247..4713dde247 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0403-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0398-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0404-ARM-dts-Declare-RPi-4B-SD-card-power-regulator.patch b/target/linux/bcm27xx/patches-5.4/950-0399-ARM-dts-Declare-RPi-4B-SD-card-power-regulator.patch index a69feb50b4..a69feb50b4 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0404-ARM-dts-Declare-RPi-4B-SD-card-power-regulator.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0399-ARM-dts-Declare-RPi-4B-SD-card-power-regulator.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0405-bcm2838.dtsi-Use-BCM2711-PCIe-compatible-string.patch b/target/linux/bcm27xx/patches-5.4/950-0400-bcm2838.dtsi-Use-BCM2711-PCIe-compatible-string.patch index 2f5d87b004..2f5d87b004 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0405-bcm2838.dtsi-Use-BCM2711-PCIe-compatible-string.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0400-bcm2838.dtsi-Use-BCM2711-PCIe-compatible-string.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0406-ARM-dts-Remove-bcm2838-rpi-4-b.dts.patch b/target/linux/bcm27xx/patches-5.4/950-0401-ARM-dts-Remove-bcm2838-rpi-4-b.dts.patch index 10c5d23b46..10c5d23b46 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0406-ARM-dts-Remove-bcm2838-rpi-4-b.dts.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0401-ARM-dts-Remove-bcm2838-rpi-4-b.dts.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0407-tty-amba-pl011-Avoid-rare-write-when-full-error.patch b/target/linux/bcm27xx/patches-5.4/950-0402-tty-amba-pl011-Avoid-rare-write-when-full-error.patch index 6283b83e17..6283b83e17 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0407-tty-amba-pl011-Avoid-rare-write-when-full-error.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0402-tty-amba-pl011-Avoid-rare-write-when-full-error.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0408-usb-xhci-Raspberry-Pi-FW-loader-for-VIA-VL805.patch b/target/linux/bcm27xx/patches-5.4/950-0403-usb-xhci-Raspberry-Pi-FW-loader-for-VIA-VL805.patch index 06e979a462..06e979a462 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0408-usb-xhci-Raspberry-Pi-FW-loader-for-VIA-VL805.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0403-usb-xhci-Raspberry-Pi-FW-loader-for-VIA-VL805.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0409-overlays-Correct-the-eth_led-colour-assignments.patch b/target/linux/bcm27xx/patches-5.4/950-0404-overlays-Correct-the-eth_led-colour-assignments.patch index f1f3290bad..f1f3290bad 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0409-overlays-Correct-the-eth_led-colour-assignments.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0404-overlays-Correct-the-eth_led-colour-assignments.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0410-ARM-dts-Add-sd_poll_once-dtparam-to-bcm283x-2711.patch b/target/linux/bcm27xx/patches-5.4/950-0405-ARM-dts-Add-sd_poll_once-dtparam-to-bcm283x-2711.patch index fef644e1c9..fef644e1c9 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0410-ARM-dts-Add-sd_poll_once-dtparam-to-bcm283x-2711.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0405-ARM-dts-Add-sd_poll_once-dtparam-to-bcm283x-2711.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0411-overlays-Add-ssd1306-spi-ssh1106-spi-ssd-1351-spi.patch b/target/linux/bcm27xx/patches-5.4/950-0406-overlays-Add-ssd1306-spi-ssh1106-spi-ssd-1351-spi.patch index 77bf63e2e2..77bf63e2e2 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0411-overlays-Add-ssd1306-spi-ssh1106-spi-ssd-1351-spi.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0406-overlays-Add-ssd1306-spi-ssh1106-spi-ssd-1351-spi.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0412-overlays-dwc2-Increase-RX-FIFO-size.patch b/target/linux/bcm27xx/patches-5.4/950-0407-overlays-dwc2-Increase-RX-FIFO-size.patch index 23bc39b3d8..23bc39b3d8 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0412-overlays-dwc2-Increase-RX-FIFO-size.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0407-overlays-dwc2-Increase-RX-FIFO-size.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0413-overlays-Fix-mcp23017-s-addr-parameter.patch b/target/linux/bcm27xx/patches-5.4/950-0408-overlays-Fix-mcp23017-s-addr-parameter.patch index 29ad87227d..29ad87227d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0413-overlays-Fix-mcp23017-s-addr-parameter.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0408-overlays-Fix-mcp23017-s-addr-parameter.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0409-SQUASH-Fix-spi-driver-compiler-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-0409-SQUASH-Fix-spi-driver-compiler-warnings.patch new file mode 100644 index 0000000000..4413439101 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0409-SQUASH-Fix-spi-driver-compiler-warnings.patch @@ -0,0 +1,22 @@ +From 69811ede9ad350beb531082177bdc6da92c7fdb9 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Tue, 4 Feb 2020 16:35:12 +0000 +Subject: [PATCH] SQUASH: Fix spi driver compiler warnings + +Squash with "spi: spi-bcm2835: Disable forced software CS" + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/spi/spi-bcm2835.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/spi/spi-bcm2835.c ++++ b/drivers/spi/spi-bcm2835.c +@@ -1182,7 +1182,6 @@ static int bcm2835_spi_setup(struct spi_ + { + struct spi_controller *ctlr = spi->controller; + struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); +- struct gpio_chip *chip; + u32 cs; + + /* diff --git a/target/linux/bcm27xx/patches-5.4/950-0415-overlays-add-hdmi-backlight-hwhack-gpio-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0410-overlays-add-hdmi-backlight-hwhack-gpio-overlay.patch index e94f15196b..e94f15196b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0415-overlays-add-hdmi-backlight-hwhack-gpio-overlay.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0410-overlays-add-hdmi-backlight-hwhack-gpio-overlay.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0416-ARM-dts-Revert-all-changes-to-upstream-dts-files.patch b/target/linux/bcm27xx/patches-5.4/950-0411-ARM-dts-Revert-all-changes-to-upstream-dts-files.patch index 403f534baf..403f534baf 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0416-ARM-dts-Revert-all-changes-to-upstream-dts-files.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0411-ARM-dts-Revert-all-changes-to-upstream-dts-files.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0417-ARM-dts-Clean-out-downstream-BCM2711-2838-files.patch b/target/linux/bcm27xx/patches-5.4/950-0412-ARM-dts-Clean-out-downstream-BCM2711-2838-files.patch index a66202a2c9..a66202a2c9 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0417-ARM-dts-Clean-out-downstream-BCM2711-2838-files.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0412-ARM-dts-Clean-out-downstream-BCM2711-2838-files.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0418-ARM-dts-Add-minimal-Raspberry-Pi-4-support.patch b/target/linux/bcm27xx/patches-5.4/950-0413-ARM-dts-Add-minimal-Raspberry-Pi-4-support.patch index 15e4f53a0a..15e4f53a0a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0418-ARM-dts-Add-minimal-Raspberry-Pi-4-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0413-ARM-dts-Add-minimal-Raspberry-Pi-4-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0419-ARM-dts-bcm2711-force-CMA-into-first-GB-of-memory.patch b/target/linux/bcm27xx/patches-5.4/950-0414-ARM-dts-bcm2711-force-CMA-into-first-GB-of-memory.patch index 44f60d610f..44f60d610f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0419-ARM-dts-bcm2711-force-CMA-into-first-GB-of-memory.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0414-ARM-dts-bcm2711-force-CMA-into-first-GB-of-memory.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0414-SQUASH-Fix-spi-driver-compiler-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-0414-SQUASH-Fix-spi-driver-compiler-warnings.patch deleted file mode 100644 index f233c4aedc..0000000000 --- a/target/linux/bcm27xx/patches-5.4/950-0414-SQUASH-Fix-spi-driver-compiler-warnings.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 69811ede9ad350beb531082177bdc6da92c7fdb9 Mon Sep 17 00:00:00 2001 -From: Phil Elwell <phil@raspberrypi.com> -Date: Tue, 4 Feb 2020 16:35:12 +0000 -Subject: [PATCH] SQUASH: Fix spi driver compiler warnings - -Squash with "spi: spi-bcm2835: Disable forced software CS" - -Signed-off-by: Phil Elwell <phil@raspberrypi.com> ---- - drivers/spi/spi-bcm2835.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -1230,7 +1230,6 @@ static int bcm2835_spi_setup(struct spi_ - { - struct spi_controller *ctlr = spi->controller; - struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); -- struct gpio_chip *chip; - u32 cs; - - /* diff --git a/target/linux/bcm27xx/patches-5.4/950-0420-ARM-dts-bcm2711-rpi-4-Enable-GENET-support.patch b/target/linux/bcm27xx/patches-5.4/950-0415-ARM-dts-bcm2711-rpi-4-Enable-GENET-support.patch index e204859fbd..e204859fbd 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0420-ARM-dts-bcm2711-rpi-4-Enable-GENET-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0415-ARM-dts-bcm2711-rpi-4-Enable-GENET-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0421-ARM-dts-bcm2711-fix-soc-s-node-dma-ranges.patch b/target/linux/bcm27xx/patches-5.4/950-0416-ARM-dts-bcm2711-fix-soc-s-node-dma-ranges.patch index ed0be9b9a3..ed0be9b9a3 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0421-ARM-dts-bcm2711-fix-soc-s-node-dma-ranges.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0416-ARM-dts-bcm2711-fix-soc-s-node-dma-ranges.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0422-ARM-dts-Rebuild-downstream-DTS-files.patch b/target/linux/bcm27xx/patches-5.4/950-0417-ARM-dts-Rebuild-downstream-DTS-files.patch index 8d230d0edb..8d230d0edb 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0422-ARM-dts-Rebuild-downstream-DTS-files.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0417-ARM-dts-Rebuild-downstream-DTS-files.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0423-staging-vchiq_arm-Fix-bcm2711-compatible-string.patch b/target/linux/bcm27xx/patches-5.4/950-0418-staging-vchiq_arm-Fix-bcm2711-compatible-string.patch index 4436c0a39d..4436c0a39d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0423-staging-vchiq_arm-Fix-bcm2711-compatible-string.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0418-staging-vchiq_arm-Fix-bcm2711-compatible-string.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0424-hwrng-iproc-rng200-Correct-SoC-name.patch b/target/linux/bcm27xx/patches-5.4/950-0419-hwrng-iproc-rng200-Correct-SoC-name.patch index f4e93308b1..f4e93308b1 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0424-hwrng-iproc-rng200-Correct-SoC-name.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0419-hwrng-iproc-rng200-Correct-SoC-name.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0425-ARM-dts-Correct-SoC-name.patch b/target/linux/bcm27xx/patches-5.4/950-0420-ARM-dts-Correct-SoC-name.patch index c18eb8af3c..c18eb8af3c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0425-ARM-dts-Correct-SoC-name.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0420-ARM-dts-Correct-SoC-name.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0426-ARM-dts-Remove-CMA-allocation-from-Pi-4-dts.patch b/target/linux/bcm27xx/patches-5.4/950-0421-ARM-dts-Remove-CMA-allocation-from-Pi-4-dts.patch index 2c093459da..2c093459da 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0426-ARM-dts-Remove-CMA-allocation-from-Pi-4-dts.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0421-ARM-dts-Remove-CMA-allocation-from-Pi-4-dts.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0427-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch b/target/linux/bcm27xx/patches-5.4/950-0422-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch index 7fb3443fa9..7fb3443fa9 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0427-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0422-staging-vchiq_arm-Give-vchiq-children-DT-nodes.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0429-ARM-dts-Move-audio-node-under-the-vchiq-parent.patch b/target/linux/bcm27xx/patches-5.4/950-0423-ARM-dts-Move-audio-node-under-the-vchiq-parent.patch index b5e59e6464..b5e59e6464 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0429-ARM-dts-Move-audio-node-under-the-vchiq-parent.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0423-ARM-dts-Move-audio-node-under-the-vchiq-parent.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0430-ARM-dts-overlays-Create-custom-clocks-in.patch b/target/linux/bcm27xx/patches-5.4/950-0424-ARM-dts-overlays-Create-custom-clocks-in.patch index ac50884bce..ac50884bce 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0430-ARM-dts-overlays-Create-custom-clocks-in.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0424-ARM-dts-overlays-Create-custom-clocks-in.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0431-staging-vc04_services-Fix-vcsm-overflow-bug-when-cou.patch b/target/linux/bcm27xx/patches-5.4/950-0425-staging-vc04_services-Fix-vcsm-overflow-bug-when-cou.patch index 4774fd2326..4774fd2326 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0431-staging-vc04_services-Fix-vcsm-overflow-bug-when-cou.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0425-staging-vc04_services-Fix-vcsm-overflow-bug-when-cou.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0432-overlays-Add-timeout_ms-parameter-to-gpio-poweroff.patch b/target/linux/bcm27xx/patches-5.4/950-0426-overlays-Add-timeout_ms-parameter-to-gpio-poweroff.patch index 213e8b8d9d..213e8b8d9d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0432-overlays-Add-timeout_ms-parameter-to-gpio-poweroff.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0426-overlays-Add-timeout_ms-parameter-to-gpio-poweroff.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0433-of-overlay-Correct-symbol-path-fixups.patch b/target/linux/bcm27xx/patches-5.4/950-0427-of-overlay-Correct-symbol-path-fixups.patch index 4b005876de..4b005876de 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0433-of-overlay-Correct-symbol-path-fixups.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0427-of-overlay-Correct-symbol-path-fixups.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0434-overlays-sc16ic750-i2c-Fix-xtal-parameter.patch b/target/linux/bcm27xx/patches-5.4/950-0428-overlays-sc16ic750-i2c-Fix-xtal-parameter.patch index 636ad26a91..636ad26a91 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0434-overlays-sc16ic750-i2c-Fix-xtal-parameter.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0428-overlays-sc16ic750-i2c-Fix-xtal-parameter.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0435-of-address-Introduce-of_get_next_dma_parent-helper.patch b/target/linux/bcm27xx/patches-5.4/950-0429-of-address-Introduce-of_get_next_dma_parent-helper.patch index 1056cfc60d..1056cfc60d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0435-of-address-Introduce-of_get_next_dma_parent-helper.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0429-of-address-Introduce-of_get_next_dma_parent-helper.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0436-of-address-Follow-DMA-parent-for-dma-coherent.patch b/target/linux/bcm27xx/patches-5.4/950-0430-of-address-Follow-DMA-parent-for-dma-coherent.patch index 76af58a126..76af58a126 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0436-of-address-Follow-DMA-parent-for-dma-coherent.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0430-of-address-Follow-DMA-parent-for-dma-coherent.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0437-of-Factor-out-addr-size-cells-parsing.patch b/target/linux/bcm27xx/patches-5.4/950-0431-of-Factor-out-addr-size-cells-parsing.patch index 045ee9827f..045ee9827f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0437-of-Factor-out-addr-size-cells-parsing.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0431-of-Factor-out-addr-size-cells-parsing.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0438-of-address-Translate-dma-ranges-for-parent-nodes-mis.patch b/target/linux/bcm27xx/patches-5.4/950-0432-of-address-Translate-dma-ranges-for-parent-nodes-mis.patch index 28d1987a9c..28d1987a9c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0438-of-address-Translate-dma-ranges-for-parent-nodes-mis.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0432-of-address-Translate-dma-ranges-for-parent-nodes-mis.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0439-of-Make-of_dma_get_range-work-on-bus-nodes.patch b/target/linux/bcm27xx/patches-5.4/950-0433-of-Make-of_dma_get_range-work-on-bus-nodes.patch index 1cac2dfcd8..1cac2dfcd8 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0439-of-Make-of_dma_get_range-work-on-bus-nodes.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0433-of-Make-of_dma_get_range-work-on-bus-nodes.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0440-arm64-mm-use-arm64_dma_phys_limit-instead-of-calling.patch b/target/linux/bcm27xx/patches-5.4/950-0434-arm64-mm-use-arm64_dma_phys_limit-instead-of-calling.patch index c697494f8a..c697494f8a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0440-arm64-mm-use-arm64_dma_phys_limit-instead-of-calling.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0434-arm64-mm-use-arm64_dma_phys_limit-instead-of-calling.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0441-arm64-rename-variables-used-to-calculate-ZONE_DMA32-.patch b/target/linux/bcm27xx/patches-5.4/950-0435-arm64-rename-variables-used-to-calculate-ZONE_DMA32-.patch index df184f53ee..df184f53ee 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0441-arm64-rename-variables-used-to-calculate-ZONE_DMA32-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0435-arm64-rename-variables-used-to-calculate-ZONE_DMA32-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0442-arm64-use-both-ZONE_DMA-and-ZONE_DMA32.patch b/target/linux/bcm27xx/patches-5.4/950-0436-arm64-use-both-ZONE_DMA-and-ZONE_DMA32.patch index ccb2071f17..ccb2071f17 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0442-arm64-use-both-ZONE_DMA-and-ZONE_DMA32.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0436-arm64-use-both-ZONE_DMA-and-ZONE_DMA32.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0443-mm-refresh-ZONE_DMA-and-ZONE_DMA32-comments-in-enum-.patch b/target/linux/bcm27xx/patches-5.4/950-0437-mm-refresh-ZONE_DMA-and-ZONE_DMA32-comments-in-enum-.patch index 23811e0b6e..23811e0b6e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0443-mm-refresh-ZONE_DMA-and-ZONE_DMA32-comments-in-enum-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0437-mm-refresh-ZONE_DMA-and-ZONE_DMA32-comments-in-enum-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0444-resource-Add-a-resource_list_first_type-helper.patch b/target/linux/bcm27xx/patches-5.4/950-0438-resource-Add-a-resource_list_first_type-helper.patch index c2c959a3c1..c2c959a3c1 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0444-resource-Add-a-resource_list_first_type-helper.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0438-resource-Add-a-resource_list_first_type-helper.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0445-dma-direct-turn-ARCH_ZONE_DMA_BITS-into-a-variable.patch b/target/linux/bcm27xx/patches-5.4/950-0439-dma-direct-turn-ARCH_ZONE_DMA_BITS-into-a-variable.patch index ab04d64b72..ab04d64b72 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0445-dma-direct-turn-ARCH_ZONE_DMA_BITS-into-a-variable.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0439-dma-direct-turn-ARCH_ZONE_DMA_BITS-into-a-variable.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0446-x86-PCI-sta2x11-use-default-DMA-address-translation.patch b/target/linux/bcm27xx/patches-5.4/950-0440-x86-PCI-sta2x11-use-default-DMA-address-translation.patch index 51fd4be35e..51fd4be35e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0446-x86-PCI-sta2x11-use-default-DMA-address-translation.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0440-x86-PCI-sta2x11-use-default-DMA-address-translation.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0447-PCI-of-Add-inbound-resource-parsing-to-helpers.patch b/target/linux/bcm27xx/patches-5.4/950-0441-PCI-of-Add-inbound-resource-parsing-to-helpers.patch index 493ea63825..493ea63825 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0447-PCI-of-Add-inbound-resource-parsing-to-helpers.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0441-PCI-of-Add-inbound-resource-parsing-to-helpers.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0448-dma-direct-unify-the-dma_capable-definitions.patch b/target/linux/bcm27xx/patches-5.4/950-0442-dma-direct-unify-the-dma_capable-definitions.patch index d115f0eb80..d115f0eb80 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0448-dma-direct-unify-the-dma_capable-definitions.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0442-dma-direct-unify-the-dma_capable-definitions.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0449-dma-direct-avoid-a-forward-declaration-for-phys_to_d.patch b/target/linux/bcm27xx/patches-5.4/950-0443-dma-direct-avoid-a-forward-declaration-for-phys_to_d.patch index a98f1d3852..a98f1d3852 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0449-dma-direct-avoid-a-forward-declaration-for-phys_to_d.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0443-dma-direct-avoid-a-forward-declaration-for-phys_to_d.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0450-dma-direct-exclude-dma_direct_map_resource-from-the-.patch b/target/linux/bcm27xx/patches-5.4/950-0444-dma-direct-exclude-dma_direct_map_resource-from-the-.patch index 2534b71b73..2534b71b73 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0450-dma-direct-exclude-dma_direct_map_resource-from-the-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0444-dma-direct-exclude-dma_direct_map_resource-from-the-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0451-dma-mapping-treat-dev-bus_dma_mask-as-a-DMA-limit.patch b/target/linux/bcm27xx/patches-5.4/950-0445-dma-mapping-treat-dev-bus_dma_mask-as-a-DMA-limit.patch index d968e93153..d968e93153 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0451-dma-mapping-treat-dev-bus_dma_mask-as-a-DMA-limit.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0445-dma-mapping-treat-dev-bus_dma_mask-as-a-DMA-limit.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0452-ARM-dts-bcm2711-Enable-PCIe-controller.patch b/target/linux/bcm27xx/patches-5.4/950-0446-ARM-dts-bcm2711-Enable-PCIe-controller.patch index 9f114c1633..9f114c1633 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0452-ARM-dts-bcm2711-Enable-PCIe-controller.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0446-ARM-dts-bcm2711-Enable-PCIe-controller.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0453-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch b/target/linux/bcm27xx/patches-5.4/950-0447-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch index ca97a1966e..ca97a1966e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0453-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0447-PCI-brcmstb-Add-Broadcom-STB-PCIe-host-controller-dr.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0454-PCI-brcmstb-Add-MSI-support.patch b/target/linux/bcm27xx/patches-5.4/950-0448-PCI-brcmstb-Add-MSI-support.patch index a27259bd19..a27259bd19 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0454-PCI-brcmstb-Add-MSI-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0448-PCI-brcmstb-Add-MSI-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0455-PCI-brcmstb-Fix-build-on-32bit-ARM-platforms-with-ol.patch b/target/linux/bcm27xx/patches-5.4/950-0449-PCI-brcmstb-Fix-build-on-32bit-ARM-platforms-with-ol.patch index 6bb45ccb1f..6bb45ccb1f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0455-PCI-brcmstb-Fix-build-on-32bit-ARM-platforms-with-ol.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0449-PCI-brcmstb-Fix-build-on-32bit-ARM-platforms-with-ol.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0456-bcm2711-rpi.dtsi-Use-upstream-pcie-node.patch b/target/linux/bcm27xx/patches-5.4/950-0450-bcm2711-rpi.dtsi-Use-upstream-pcie-node.patch index 729d6e68ba..729d6e68ba 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0456-bcm2711-rpi.dtsi-Use-upstream-pcie-node.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0450-bcm2711-rpi.dtsi-Use-upstream-pcie-node.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0457-media-dt-bindings-media-i2c-Add-IMX219-CMOS-sensor-b.patch b/target/linux/bcm27xx/patches-5.4/950-0451-media-dt-bindings-media-i2c-Add-IMX219-CMOS-sensor-b.patch index c93f4501c4..c93f4501c4 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0457-media-dt-bindings-media-i2c-Add-IMX219-CMOS-sensor-b.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0451-media-dt-bindings-media-i2c-Add-IMX219-CMOS-sensor-b.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0458-media-i2c-Add-driver-for-Sony-IMX219-sensor.patch b/target/linux/bcm27xx/patches-5.4/950-0452-media-i2c-Add-driver-for-Sony-IMX219-sensor.patch index 4ca345f2ad..4ca345f2ad 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0458-media-i2c-Add-driver-for-Sony-IMX219-sensor.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0452-media-i2c-Add-driver-for-Sony-IMX219-sensor.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0459-overlays-imx219-Correct-link-frequency-to-match-the-.patch b/target/linux/bcm27xx/patches-5.4/950-0453-overlays-imx219-Correct-link-frequency-to-match-the-.patch index e9eed21451..e9eed21451 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0459-overlays-imx219-Correct-link-frequency-to-match-the-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0453-overlays-imx219-Correct-link-frequency-to-match-the-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0460-Kbuild-Allow-.dtbo-overlays-to-be-built-adjust.patch b/target/linux/bcm27xx/patches-5.4/950-0454-Kbuild-Allow-.dtbo-overlays-to-be-built-adjust.patch index b1cd7bffbe..b1cd7bffbe 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0460-Kbuild-Allow-.dtbo-overlays-to-be-built-adjust.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0454-Kbuild-Allow-.dtbo-overlays-to-be-built-adjust.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0461-media-ov5647-Fix-return-codes-from-ov5647_write-ov56.patch b/target/linux/bcm27xx/patches-5.4/950-0455-media-ov5647-Fix-return-codes-from-ov5647_write-ov56.patch index c7e10cbdc1..c7e10cbdc1 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0461-media-ov5647-Fix-return-codes-from-ov5647_write-ov56.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0455-media-ov5647-Fix-return-codes-from-ov5647_write-ov56.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0462-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch b/target/linux/bcm27xx/patches-5.4/950-0456-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch index 5846e96af8..5846e96af8 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0462-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0456-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0463-media-ov5647-Add-V4L2-controls-for-analogue-gain-exp.patch b/target/linux/bcm27xx/patches-5.4/950-0457-media-ov5647-Add-V4L2-controls-for-analogue-gain-exp.patch index 907bab5cfd..907bab5cfd 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0463-media-ov5647-Add-V4L2-controls-for-analogue-gain-exp.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0457-media-ov5647-Add-V4L2-controls-for-analogue-gain-exp.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0464-media-ov5647-Add-extra-10-bit-sensor-modes.patch b/target/linux/bcm27xx/patches-5.4/950-0458-media-ov5647-Add-extra-10-bit-sensor-modes.patch index 9e40b5164a..9e40b5164a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0464-media-ov5647-Add-extra-10-bit-sensor-modes.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0458-media-ov5647-Add-extra-10-bit-sensor-modes.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0465-media-ov5647-change-defaults-to-better-match-raw-cam.patch b/target/linux/bcm27xx/patches-5.4/950-0459-media-ov5647-change-defaults-to-better-match-raw-cam.patch index 58d23b7bcb..58d23b7bcb 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0465-media-ov5647-change-defaults-to-better-match-raw-cam.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0459-media-ov5647-change-defaults-to-better-match-raw-cam.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0466-drm-vc4-fkms-Change-crtc_state-structure-name-to-avo.patch b/target/linux/bcm27xx/patches-5.4/950-0460-drm-vc4-fkms-Change-crtc_state-structure-name-to-avo.patch index 0b48018c1e..0b48018c1e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0466-drm-vc4-fkms-Change-crtc_state-structure-name-to-avo.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0460-drm-vc4-fkms-Change-crtc_state-structure-name-to-avo.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0467-drm-fourcc-Add-packed-10bit-YUV-4-2-0-format.patch b/target/linux/bcm27xx/patches-5.4/950-0461-drm-fourcc-Add-packed-10bit-YUV-4-2-0-format.patch index ac4fe1698b..ac4fe1698b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0467-drm-fourcc-Add-packed-10bit-YUV-4-2-0-format.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0461-drm-fourcc-Add-packed-10bit-YUV-4-2-0-format.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0468-drm-vc4-Add-DRM_FORMAT_P030-support-to-firmware-kms.patch b/target/linux/bcm27xx/patches-5.4/950-0462-drm-vc4-Add-DRM_FORMAT_P030-support-to-firmware-kms.patch index f6264ff04a..f6264ff04a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0468-drm-vc4-Add-DRM_FORMAT_P030-support-to-firmware-kms.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0462-drm-vc4-Add-DRM_FORMAT_P030-support-to-firmware-kms.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0469-gpio-ir-overlay-add-parameter-to-configure-signal-po.patch b/target/linux/bcm27xx/patches-5.4/950-0463-gpio-ir-overlay-add-parameter-to-configure-signal-po.patch index cdd14f7940..cdd14f7940 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0469-gpio-ir-overlay-add-parameter-to-configure-signal-po.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0463-gpio-ir-overlay-add-parameter-to-configure-signal-po.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0470-Add-support-for-merus-amp-soundcard-and-ma120x0p-cod.patch b/target/linux/bcm27xx/patches-5.4/950-0464-Add-support-for-merus-amp-soundcard-and-ma120x0p-cod.patch index 8e66bccf6e..8e66bccf6e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0470-Add-support-for-merus-amp-soundcard-and-ma120x0p-cod.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0464-Add-support-for-merus-amp-soundcard-and-ma120x0p-cod.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0471-ARM-dts-bcm2711-Add-32-bit-PMU-compatibility.patch b/target/linux/bcm27xx/patches-5.4/950-0465-ARM-dts-bcm2711-Add-32-bit-PMU-compatibility.patch index f549e73fd3..f549e73fd3 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0471-ARM-dts-bcm2711-Add-32-bit-PMU-compatibility.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0465-ARM-dts-bcm2711-Add-32-bit-PMU-compatibility.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0472-ARM-dts-bcm271x-Use-a53-pmu-drop-RPI364.patch b/target/linux/bcm27xx/patches-5.4/950-0466-ARM-dts-bcm271x-Use-a53-pmu-drop-RPI364.patch index 9504bb3982..9504bb3982 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0472-ARM-dts-bcm271x-Use-a53-pmu-drop-RPI364.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0466-ARM-dts-bcm271x-Use-a53-pmu-drop-RPI364.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0473-net-bcmgenet-Clear-ID_MODE_DIS-in-EXT_RGMII_OOB_CTRL.patch b/target/linux/bcm27xx/patches-5.4/950-0467-net-bcmgenet-Clear-ID_MODE_DIS-in-EXT_RGMII_OOB_CTRL.patch index 9d8090441a..9d8090441a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0473-net-bcmgenet-Clear-ID_MODE_DIS-in-EXT_RGMII_OOB_CTRL.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0467-net-bcmgenet-Clear-ID_MODE_DIS-in-EXT_RGMII_OOB_CTRL.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0474-drm-modes-parse_cmdline-Fix-possible-reference-past-.patch b/target/linux/bcm27xx/patches-5.4/950-0468-drm-modes-parse_cmdline-Fix-possible-reference-past-.patch index 9b514c3a25..9b514c3a25 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0474-drm-modes-parse_cmdline-Fix-possible-reference-past-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0468-drm-modes-parse_cmdline-Fix-possible-reference-past-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0475-drm-modes-parse_cmdline-Make-various-char-pointers-c.patch b/target/linux/bcm27xx/patches-5.4/950-0469-drm-modes-parse_cmdline-Make-various-char-pointers-c.patch index 6abe7beb32..6abe7beb32 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0475-drm-modes-parse_cmdline-Make-various-char-pointers-c.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0469-drm-modes-parse_cmdline-Make-various-char-pointers-c.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0476-drm-modes-parse_cmdline-Stop-parsing-extras-after-bp.patch b/target/linux/bcm27xx/patches-5.4/950-0470-drm-modes-parse_cmdline-Stop-parsing-extras-after-bp.patch index 1d356eb6ab..1d356eb6ab 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0476-drm-modes-parse_cmdline-Stop-parsing-extras-after-bp.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0470-drm-modes-parse_cmdline-Stop-parsing-extras-after-bp.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0477-drm-modes-parse_cmdline-Accept-extras-directly-after.patch b/target/linux/bcm27xx/patches-5.4/950-0471-drm-modes-parse_cmdline-Accept-extras-directly-after.patch index 8d9a92ec0d..8d9a92ec0d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0477-drm-modes-parse_cmdline-Accept-extras-directly-after.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0471-drm-modes-parse_cmdline-Accept-extras-directly-after.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0478-drm-modes-parse_cmdline-Rework-drm_mode_parse_cmdlin.patch b/target/linux/bcm27xx/patches-5.4/950-0472-drm-modes-parse_cmdline-Rework-drm_mode_parse_cmdlin.patch index 1716ebd7be..1716ebd7be 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0478-drm-modes-parse_cmdline-Rework-drm_mode_parse_cmdlin.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0472-drm-modes-parse_cmdline-Rework-drm_mode_parse_cmdlin.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0479-drm-modes-parse_cmdline-Add-freestanding-argument-to.patch b/target/linux/bcm27xx/patches-5.4/950-0473-drm-modes-parse_cmdline-Add-freestanding-argument-to.patch index 6ed952bd45..6ed952bd45 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0479-drm-modes-parse_cmdline-Add-freestanding-argument-to.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0473-drm-modes-parse_cmdline-Add-freestanding-argument-to.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0480-drm-modes-parse_cmdline-Set-bpp-refresh_specified-af.patch b/target/linux/bcm27xx/patches-5.4/950-0474-drm-modes-parse_cmdline-Set-bpp-refresh_specified-af.patch index ac973e1d4e..ac973e1d4e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0480-drm-modes-parse_cmdline-Set-bpp-refresh_specified-af.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0474-drm-modes-parse_cmdline-Set-bpp-refresh_specified-af.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0481-drm-modes-parse_cmdline-Allow-specifying-stand-alone.patch b/target/linux/bcm27xx/patches-5.4/950-0475-drm-modes-parse_cmdline-Allow-specifying-stand-alone.patch index 746f35f83b..746f35f83b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0481-drm-modes-parse_cmdline-Allow-specifying-stand-alone.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0475-drm-modes-parse_cmdline-Allow-specifying-stand-alone.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0482-drm-modes-parse_cmdline-Add-support-for-specifying-p.patch b/target/linux/bcm27xx/patches-5.4/950-0476-drm-modes-parse_cmdline-Add-support-for-specifying-p.patch index cbda9ecc10..cbda9ecc10 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0482-drm-modes-parse_cmdline-Add-support-for-specifying-p.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0476-drm-modes-parse_cmdline-Add-support-for-specifying-p.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0483-drm-modes-parse_cmdline-Remove-some-unnecessary-code.patch b/target/linux/bcm27xx/patches-5.4/950-0477-drm-modes-parse_cmdline-Remove-some-unnecessary-code.patch index fb4a7f1cda..fb4a7f1cda 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0483-drm-modes-parse_cmdline-Remove-some-unnecessary-code.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0477-drm-modes-parse_cmdline-Remove-some-unnecessary-code.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0484-drm-modes-parse_cmdline-Explicitly-memset-the-passed.patch b/target/linux/bcm27xx/patches-5.4/950-0478-drm-modes-parse_cmdline-Explicitly-memset-the-passed.patch index 372cd0d665..372cd0d665 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0484-drm-modes-parse_cmdline-Explicitly-memset-the-passed.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0478-drm-modes-parse_cmdline-Explicitly-memset-the-passed.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0485-drm-v3d-Replace-wait_for-macros-to-remove-use-of-msl.patch b/target/linux/bcm27xx/patches-5.4/950-0479-drm-v3d-Replace-wait_for-macros-to-remove-use-of-msl.patch index 830bc1125e..830bc1125e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0485-drm-v3d-Replace-wait_for-macros-to-remove-use-of-msl.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0479-drm-v3d-Replace-wait_for-macros-to-remove-use-of-msl.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0486-Reduce-noise-from-rpi-poe-hat-fan.patch b/target/linux/bcm27xx/patches-5.4/950-0480-Reduce-noise-from-rpi-poe-hat-fan.patch index 7c50843102..7c50843102 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0486-Reduce-noise-from-rpi-poe-hat-fan.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0480-Reduce-noise-from-rpi-poe-hat-fan.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0487-add-Sensirion-SPS30-to-i2c-sensor-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0481-add-Sensirion-SPS30-to-i2c-sensor-overlay.patch index 72941b59bb..72941b59bb 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0487-add-Sensirion-SPS30-to-i2c-sensor-overlay.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0481-add-Sensirion-SPS30-to-i2c-sensor-overlay.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0488-media-add-V4L2_CTRL_TYPE_AREA-control-type.patch b/target/linux/bcm27xx/patches-5.4/950-0482-media-add-V4L2_CTRL_TYPE_AREA-control-type.patch index d82c3196b8..d82c3196b8 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0488-media-add-V4L2_CTRL_TYPE_AREA-control-type.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0482-media-add-V4L2_CTRL_TYPE_AREA-control-type.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0489-media-add-V4L2_CID_UNIT_CELL_SIZE-control.patch b/target/linux/bcm27xx/patches-5.4/950-0483-media-add-V4L2_CID_UNIT_CELL_SIZE-control.patch index 0c860c7e4a..0c860c7e4a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0489-media-add-V4L2_CID_UNIT_CELL_SIZE-control.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0483-media-add-V4L2_CID_UNIT_CELL_SIZE-control.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0490-media-v4l2-common-add-pixel-encoding-support.patch b/target/linux/bcm27xx/patches-5.4/950-0484-media-v4l2-common-add-pixel-encoding-support.patch index aa127ab5e7..aa127ab5e7 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0490-media-v4l2-common-add-pixel-encoding-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0484-media-v4l2-common-add-pixel-encoding-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0491-media-v4l2-common-add-RGB565-and-RGB55-to-v4l2_forma.patch b/target/linux/bcm27xx/patches-5.4/950-0485-media-v4l2-common-add-RGB565-and-RGB55-to-v4l2_forma.patch index 0171cdf821..0171cdf821 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0491-media-v4l2-common-add-RGB565-and-RGB55-to-v4l2_forma.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0485-media-v4l2-common-add-RGB565-and-RGB55-to-v4l2_forma.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0492-media-vb2-add-V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF.patch b/target/linux/bcm27xx/patches-5.4/950-0486-media-vb2-add-V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF.patch index b05c34ccbe..b05c34ccbe 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0492-media-vb2-add-V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0486-media-vb2-add-V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0493-media-v4l2-mem2mem-support-held-capture-buffers.patch b/target/linux/bcm27xx/patches-5.4/950-0487-media-v4l2-mem2mem-support-held-capture-buffers.patch index bb66baf07d..bb66baf07d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0493-media-v4l2-mem2mem-support-held-capture-buffers.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0487-media-v4l2-mem2mem-support-held-capture-buffers.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0494-media-videodev2.h-add-V4L2_DEC_CMD_FLUSH.patch b/target/linux/bcm27xx/patches-5.4/950-0488-media-videodev2.h-add-V4L2_DEC_CMD_FLUSH.patch index 56fee1e029..56fee1e029 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0494-media-videodev2.h-add-V4L2_DEC_CMD_FLUSH.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0488-media-videodev2.h-add-V4L2_DEC_CMD_FLUSH.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0495-media-v4l2-mem2mem-add-stateless_-try_-decoder_cmd-i.patch b/target/linux/bcm27xx/patches-5.4/950-0489-media-v4l2-mem2mem-add-stateless_-try_-decoder_cmd-i.patch index 0b74dbf123..0b74dbf123 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0495-media-v4l2-mem2mem-add-stateless_-try_-decoder_cmd-i.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0489-media-v4l2-mem2mem-add-stateless_-try_-decoder_cmd-i.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0496-media-v4l2-mem2mem-add-new_frame-detection.patch b/target/linux/bcm27xx/patches-5.4/950-0490-media-v4l2-mem2mem-add-new_frame-detection.patch index 3c777922f1..3c777922f1 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0496-media-v4l2-mem2mem-add-new_frame-detection.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0490-media-v4l2-mem2mem-add-new_frame-detection.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0497-media-Documentation-media-Document-V4L2_CTRL_TYPE_AR.patch b/target/linux/bcm27xx/patches-5.4/950-0491-media-Documentation-media-Document-V4L2_CTRL_TYPE_AR.patch index 1d478fc68a..1d478fc68a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0497-media-Documentation-media-Document-V4L2_CTRL_TYPE_AR.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0491-media-Documentation-media-Document-V4L2_CTRL_TYPE_AR.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0498-media-v4l-Add-definitions-for-HEVC-stateless-decodin.patch b/target/linux/bcm27xx/patches-5.4/950-0492-media-v4l-Add-definitions-for-HEVC-stateless-decodin.patch index 0fe0f8cea4..0fe0f8cea4 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0498-media-v4l-Add-definitions-for-HEVC-stateless-decodin.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0492-media-v4l-Add-definitions-for-HEVC-stateless-decodin.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0499-media-v4l2-mem2mem-Fix-hold-buf-flag-checks.patch b/target/linux/bcm27xx/patches-5.4/950-0493-media-v4l2-mem2mem-Fix-hold-buf-flag-checks.patch index 18073a8f9d..18073a8f9d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0499-media-v4l2-mem2mem-Fix-hold-buf-flag-checks.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0493-media-v4l2-mem2mem-Fix-hold-buf-flag-checks.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0500-media-pixfmt-Document-the-HEVC-slice-pixel-format.patch b/target/linux/bcm27xx/patches-5.4/950-0494-media-pixfmt-Document-the-HEVC-slice-pixel-format.patch index 7398807782..7398807782 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0500-media-pixfmt-Document-the-HEVC-slice-pixel-format.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0494-media-pixfmt-Document-the-HEVC-slice-pixel-format.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0501-media-uapi-hevc-Add-scaling-matrix-control.patch b/target/linux/bcm27xx/patches-5.4/950-0495-media-uapi-hevc-Add-scaling-matrix-control.patch index c2cf27a40e..c2cf27a40e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0501-media-uapi-hevc-Add-scaling-matrix-control.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0495-media-uapi-hevc-Add-scaling-matrix-control.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0502-media-uapi-hevc-Add-segment-address-field.patch b/target/linux/bcm27xx/patches-5.4/950-0496-media-uapi-hevc-Add-segment-address-field.patch index 91f195b4ae..91f195b4ae 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0502-media-uapi-hevc-Add-segment-address-field.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0496-media-uapi-hevc-Add-segment-address-field.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0503-media-hevc_ctrls-Add-slice-param-dependent-slice-seg.patch b/target/linux/bcm27xx/patches-5.4/950-0497-media-hevc_ctrls-Add-slice-param-dependent-slice-seg.patch index 1353480476..1353480476 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0503-media-hevc_ctrls-Add-slice-param-dependent-slice-seg.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0497-media-hevc_ctrls-Add-slice-param-dependent-slice-seg.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0504-media-uapi-Add-hevc-ctrls-for-WPP-decoding.patch b/target/linux/bcm27xx/patches-5.4/950-0498-media-uapi-Add-hevc-ctrls-for-WPP-decoding.patch index 234cb82b2a..234cb82b2a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0504-media-uapi-Add-hevc-ctrls-for-WPP-decoding.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0498-media-uapi-Add-hevc-ctrls-for-WPP-decoding.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0505-media-videodev2.h-Add-a-format-for-column-YUV4-2-0-m.patch b/target/linux/bcm27xx/patches-5.4/950-0499-media-videodev2.h-Add-a-format-for-column-YUV4-2-0-m.patch index 5a309827e2..5a309827e2 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0505-media-videodev2.h-Add-a-format-for-column-YUV4-2-0-m.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0499-media-videodev2.h-Add-a-format-for-column-YUV4-2-0-m.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0506-media-v4l2-mem2mem-allow-request-job-buffer-processi.patch b/target/linux/bcm27xx/patches-5.4/950-0500-media-v4l2-mem2mem-allow-request-job-buffer-processi.patch index a3023cae2b..a3023cae2b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0506-media-v4l2-mem2mem-allow-request-job-buffer-processi.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0500-media-v4l2-mem2mem-allow-request-job-buffer-processi.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0507-media-dt-bindings-media-Add-binding-for-the-Raspberr.patch b/target/linux/bcm27xx/patches-5.4/950-0501-media-dt-bindings-media-Add-binding-for-the-Raspberr.patch index 203e112466..203e112466 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0507-media-dt-bindings-media-Add-binding-for-the-Raspberr.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0501-media-dt-bindings-media-Add-binding-for-the-Raspberr.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0508-staging-media-Add-Raspberry-Pi-V4L2-H265-decoder.patch b/target/linux/bcm27xx/patches-5.4/950-0502-staging-media-Add-Raspberry-Pi-V4L2-H265-decoder.patch index 134a685f0e..134a685f0e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0508-staging-media-Add-Raspberry-Pi-V4L2-H265-decoder.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0502-staging-media-Add-Raspberry-Pi-V4L2-H265-decoder.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0509-dtoverlays-Add-overlay-to-enable-the-HEVC-V4L2-drive.patch b/target/linux/bcm27xx/patches-5.4/950-0503-dtoverlays-Add-overlay-to-enable-the-HEVC-V4L2-drive.patch index ee92ada02f..ee92ada02f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0509-dtoverlays-Add-overlay-to-enable-the-HEVC-V4L2-drive.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0503-dtoverlays-Add-overlay-to-enable-the-HEVC-V4L2-drive.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0510-mmc-sdhci-Silence-MMC-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-0504-mmc-sdhci-Silence-MMC-warnings.patch index 38349280bb..38349280bb 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0510-mmc-sdhci-Silence-MMC-warnings.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0504-mmc-sdhci-Silence-MMC-warnings.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0511-dt-bindings-i2c-brcmstb-Convert-the-BRCMSTB-binding-.patch b/target/linux/bcm27xx/patches-5.4/950-0505-dt-bindings-i2c-brcmstb-Convert-the-BRCMSTB-binding-.patch index 01bdfee303..01bdfee303 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0511-dt-bindings-i2c-brcmstb-Convert-the-BRCMSTB-binding-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0505-dt-bindings-i2c-brcmstb-Convert-the-BRCMSTB-binding-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0512-dt-bindings-i2c-brcmstb-Add-BCM2711-BSC-AUTO-I2C-bin.patch b/target/linux/bcm27xx/patches-5.4/950-0506-dt-bindings-i2c-brcmstb-Add-BCM2711-BSC-AUTO-I2C-bin.patch index 2716a13d25..2716a13d25 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0512-dt-bindings-i2c-brcmstb-Add-BCM2711-BSC-AUTO-I2C-bin.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0506-dt-bindings-i2c-brcmstb-Add-BCM2711-BSC-AUTO-I2C-bin.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0513-i2c-brcmstb-Support-BCM2711-HDMI-BSC-controllers.patch b/target/linux/bcm27xx/patches-5.4/950-0507-i2c-brcmstb-Support-BCM2711-HDMI-BSC-controllers.patch index 76ce7403da..76ce7403da 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0513-i2c-brcmstb-Support-BCM2711-HDMI-BSC-controllers.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0507-i2c-brcmstb-Support-BCM2711-HDMI-BSC-controllers.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0514-i2c-brcmstb-Allow-to-compile-it-on-BCM2835.patch b/target/linux/bcm27xx/patches-5.4/950-0508-i2c-brcmstb-Allow-to-compile-it-on-BCM2835.patch index a21035b69b..a21035b69b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0514-i2c-brcmstb-Allow-to-compile-it-on-BCM2835.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0508-i2c-brcmstb-Allow-to-compile-it-on-BCM2835.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0515-dt-bindings-clock-Add-a-binding-for-the-RPi-Firmware.patch b/target/linux/bcm27xx/patches-5.4/950-0509-dt-bindings-clock-Add-a-binding-for-the-RPi-Firmware.patch index f3587060d1..f3587060d1 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0515-dt-bindings-clock-Add-a-binding-for-the-RPi-Firmware.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0509-dt-bindings-clock-Add-a-binding-for-the-RPi-Firmware.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0516-clk-bcm-rpi-Allow-the-driver-to-be-probed-by-DT.patch b/target/linux/bcm27xx/patches-5.4/950-0510-clk-bcm-rpi-Allow-the-driver-to-be-probed-by-DT.patch index d622d9ded5..d622d9ded5 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0516-clk-bcm-rpi-Allow-the-driver-to-be-probed-by-DT.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0510-clk-bcm-rpi-Allow-the-driver-to-be-probed-by-DT.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0517-clk-bcm-rpi-Statically-init-clk_init_data.patch b/target/linux/bcm27xx/patches-5.4/950-0511-clk-bcm-rpi-Statically-init-clk_init_data.patch index 5c7cb2b437..5c7cb2b437 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0517-clk-bcm-rpi-Statically-init-clk_init_data.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0511-clk-bcm-rpi-Statically-init-clk_init_data.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0518-clk-bcm-rpi-Use-clk_hw_register-for-pllb_arm.patch b/target/linux/bcm27xx/patches-5.4/950-0512-clk-bcm-rpi-Use-clk_hw_register-for-pllb_arm.patch index 55f86ae340..55f86ae340 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0518-clk-bcm-rpi-Use-clk_hw_register-for-pllb_arm.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0512-clk-bcm-rpi-Use-clk_hw_register-for-pllb_arm.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0519-clk-bcm-rpi-Remove-global-pllb_arm-clock-pointer.patch b/target/linux/bcm27xx/patches-5.4/950-0513-clk-bcm-rpi-Remove-global-pllb_arm-clock-pointer.patch index 32fc94c675..32fc94c675 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0519-clk-bcm-rpi-Remove-global-pllb_arm-clock-pointer.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0513-clk-bcm-rpi-Remove-global-pllb_arm-clock-pointer.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0520-clk-bcm-rpi-Make-sure-pllb_arm-is-removed.patch b/target/linux/bcm27xx/patches-5.4/950-0514-clk-bcm-rpi-Make-sure-pllb_arm-is-removed.patch index 425830d5c4..425830d5c4 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0520-clk-bcm-rpi-Make-sure-pllb_arm-is-removed.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0514-clk-bcm-rpi-Make-sure-pllb_arm-is-removed.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0521-clk-bcm-rpi-Remove-pllb_arm_lookup-global-pointer.patch b/target/linux/bcm27xx/patches-5.4/950-0515-clk-bcm-rpi-Remove-pllb_arm_lookup-global-pointer.patch index e193b7906a..e193b7906a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0521-clk-bcm-rpi-Remove-pllb_arm_lookup-global-pointer.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0515-clk-bcm-rpi-Remove-pllb_arm_lookup-global-pointer.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0522-clk-bcm-rpi-Switch-to-clk_hw_register_clkdev.patch b/target/linux/bcm27xx/patches-5.4/950-0516-clk-bcm-rpi-Switch-to-clk_hw_register_clkdev.patch index e4a129f233..e4a129f233 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0522-clk-bcm-rpi-Switch-to-clk_hw_register_clkdev.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0516-clk-bcm-rpi-Switch-to-clk_hw_register_clkdev.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0523-clk-bcm-rpi-Make-sure-the-clkdev-lookup-is-removed.patch b/target/linux/bcm27xx/patches-5.4/950-0517-clk-bcm-rpi-Make-sure-the-clkdev-lookup-is-removed.patch index 7c887795ee..7c887795ee 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0523-clk-bcm-rpi-Make-sure-the-clkdev-lookup-is-removed.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0517-clk-bcm-rpi-Make-sure-the-clkdev-lookup-is-removed.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0524-clk-bcm-rpi-Create-a-data-structure-for-the-clocks.patch b/target/linux/bcm27xx/patches-5.4/950-0518-clk-bcm-rpi-Create-a-data-structure-for-the-clocks.patch index 85b6f4a6e2..85b6f4a6e2 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0524-clk-bcm-rpi-Create-a-data-structure-for-the-clocks.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0518-clk-bcm-rpi-Create-a-data-structure-for-the-clocks.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0525-clk-bcm-rpi-Add-clock-id-to-data.patch b/target/linux/bcm27xx/patches-5.4/950-0519-clk-bcm-rpi-Add-clock-id-to-data.patch index 09f023e09c..09f023e09c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0525-clk-bcm-rpi-Add-clock-id-to-data.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0519-clk-bcm-rpi-Add-clock-id-to-data.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0526-clk-bcm-rpi-Pass-the-clocks-data-to-the-firmware-fun.patch b/target/linux/bcm27xx/patches-5.4/950-0520-clk-bcm-rpi-Pass-the-clocks-data-to-the-firmware-fun.patch index 7822ff0d11..7822ff0d11 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0526-clk-bcm-rpi-Pass-the-clocks-data-to-the-firmware-fun.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0520-clk-bcm-rpi-Pass-the-clocks-data-to-the-firmware-fun.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0527-clk-bcm-rpi-Rename-is_prepared-function.patch b/target/linux/bcm27xx/patches-5.4/950-0521-clk-bcm-rpi-Rename-is_prepared-function.patch index 1a6c9813de..1a6c9813de 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0527-clk-bcm-rpi-Rename-is_prepared-function.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0521-clk-bcm-rpi-Rename-is_prepared-function.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0528-clk-bcm-rpi-Split-pllb-clock-hooks.patch b/target/linux/bcm27xx/patches-5.4/950-0522-clk-bcm-rpi-Split-pllb-clock-hooks.patch index 38720b89bd..38720b89bd 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0528-clk-bcm-rpi-Split-pllb-clock-hooks.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0522-clk-bcm-rpi-Split-pllb-clock-hooks.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0529-clk-bcm-rpi-Make-the-PLLB-registration-function-retu.patch b/target/linux/bcm27xx/patches-5.4/950-0523-clk-bcm-rpi-Make-the-PLLB-registration-function-retu.patch index 633cf18782..633cf18782 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0529-clk-bcm-rpi-Make-the-PLLB-registration-function-retu.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0523-clk-bcm-rpi-Make-the-PLLB-registration-function-retu.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0530-clk-bcm-rpi-Add-DT-provider-for-the-clocks.patch b/target/linux/bcm27xx/patches-5.4/950-0524-clk-bcm-rpi-Add-DT-provider-for-the-clocks.patch index 99fdf8fbd6..99fdf8fbd6 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0530-clk-bcm-rpi-Add-DT-provider-for-the-clocks.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0524-clk-bcm-rpi-Add-DT-provider-for-the-clocks.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0531-clk-bcm-rpi-Discover-the-firmware-clocks.patch b/target/linux/bcm27xx/patches-5.4/950-0525-clk-bcm-rpi-Discover-the-firmware-clocks.patch index eaa4a81141..eaa4a81141 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0531-clk-bcm-rpi-Discover-the-firmware-clocks.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0525-clk-bcm-rpi-Discover-the-firmware-clocks.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0532-ARM-dts-bcm2711-Add-firmware-clocks-node.patch b/target/linux/bcm27xx/patches-5.4/950-0526-ARM-dts-bcm2711-Add-firmware-clocks-node.patch index 098903d2e1..098903d2e1 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0532-ARM-dts-bcm2711-Add-firmware-clocks-node.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0526-ARM-dts-bcm2711-Add-firmware-clocks-node.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0533-reset-Move-reset-simple-header-out-of-drivers-reset.patch b/target/linux/bcm27xx/patches-5.4/950-0527-reset-Move-reset-simple-header-out-of-drivers-reset.patch index 3df4fde439..3df4fde439 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0533-reset-Move-reset-simple-header-out-of-drivers-reset.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0527-reset-Move-reset-simple-header-out-of-drivers-reset.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0534-reset-simple-Add-reset-callback.patch b/target/linux/bcm27xx/patches-5.4/950-0528-reset-simple-Add-reset-callback.patch index 035c9d6aa0..035c9d6aa0 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0534-reset-simple-Add-reset-callback.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0528-reset-simple-Add-reset-callback.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0535-dt-bindings-clock-Add-BCM2711-DVP-binding.patch b/target/linux/bcm27xx/patches-5.4/950-0529-dt-bindings-clock-Add-BCM2711-DVP-binding.patch index ca87cbac83..ca87cbac83 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0535-dt-bindings-clock-Add-BCM2711-DVP-binding.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0529-dt-bindings-clock-Add-BCM2711-DVP-binding.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0536-clk-bcm-Add-BCM2711-DVP-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0530-clk-bcm-Add-BCM2711-DVP-driver.patch index 23105057a9..23105057a9 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0536-clk-bcm-Add-BCM2711-DVP-driver.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0530-clk-bcm-Add-BCM2711-DVP-driver.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0537-ARM-dts-bcm2711-Add-HDMI-DVP.patch b/target/linux/bcm27xx/patches-5.4/950-0531-ARM-dts-bcm2711-Add-HDMI-DVP.patch index c4d230e730..c4d230e730 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0537-ARM-dts-bcm2711-Add-HDMI-DVP.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0531-ARM-dts-bcm2711-Add-HDMI-DVP.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0538-dt-bindings-display-Convert-VC4-bindings-to-schemas.patch b/target/linux/bcm27xx/patches-5.4/950-0532-dt-bindings-display-Convert-VC4-bindings-to-schemas.patch index d9482649cc..d9482649cc 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0538-dt-bindings-display-Convert-VC4-bindings-to-schemas.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0532-dt-bindings-display-Convert-VC4-bindings-to-schemas.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0539-dt-bindings-display-vc4-dpi-Add-missing-clock-names-.patch b/target/linux/bcm27xx/patches-5.4/950-0533-dt-bindings-display-vc4-dpi-Add-missing-clock-names-.patch index 2150f0abec..2150f0abec 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0539-dt-bindings-display-vc4-dpi-Add-missing-clock-names-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0533-dt-bindings-display-vc4-dpi-Add-missing-clock-names-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0540-dt-bindings-display-vc4-dsi-Add-missing-clock-proper.patch b/target/linux/bcm27xx/patches-5.4/950-0534-dt-bindings-display-vc4-dsi-Add-missing-clock-proper.patch index 4cb313f152..4cb313f152 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0540-dt-bindings-display-vc4-dsi-Add-missing-clock-proper.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0534-dt-bindings-display-vc4-dsi-Add-missing-clock-proper.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0541-dt-bindings-display-vc4-hdmi-Add-missing-clock-names.patch b/target/linux/bcm27xx/patches-5.4/950-0535-dt-bindings-display-vc4-hdmi-Add-missing-clock-names.patch index 5ef4eaeab9..5ef4eaeab9 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0541-dt-bindings-display-vc4-hdmi-Add-missing-clock-names.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0535-dt-bindings-display-vc4-hdmi-Add-missing-clock-names.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0542-dt-bindings-display-vc4-Document-BCM2711-VC5.patch b/target/linux/bcm27xx/patches-5.4/950-0536-dt-bindings-display-vc4-Document-BCM2711-VC5.patch index 2499dee0c9..2499dee0c9 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0542-dt-bindings-display-vc4-Document-BCM2711-VC5.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0536-dt-bindings-display-vc4-Document-BCM2711-VC5.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0543-drm-vc4-drv-Add-include-guards.patch b/target/linux/bcm27xx/patches-5.4/950-0537-drm-vc4-drv-Add-include-guards.patch index 16f8b0ad82..16f8b0ad82 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0543-drm-vc4-drv-Add-include-guards.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0537-drm-vc4-drv-Add-include-guards.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0544-drm-vc4-drv-Support-BCM2711.patch b/target/linux/bcm27xx/patches-5.4/950-0538-drm-vc4-drv-Support-BCM2711.patch index 21018e11b7..21018e11b7 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0544-drm-vc4-drv-Support-BCM2711.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0538-drm-vc4-drv-Support-BCM2711.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0545-drm-vc4-drv-Add-support-for-the-BCM2711-HVS5.patch b/target/linux/bcm27xx/patches-5.4/950-0539-drm-vc4-drv-Add-support-for-the-BCM2711-HVS5.patch index a02663ac8b..a02663ac8b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0545-drm-vc4-drv-Add-support-for-the-BCM2711-HVS5.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0539-drm-vc4-drv-Add-support-for-the-BCM2711-HVS5.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0546-drm-vc4-plane-Improve-LBM-usage.patch b/target/linux/bcm27xx/patches-5.4/950-0540-drm-vc4-plane-Improve-LBM-usage.patch index 5342e0ad23..5342e0ad23 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0546-drm-vc4-plane-Improve-LBM-usage.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0540-drm-vc4-plane-Improve-LBM-usage.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0547-drm-vc4-plane-Move-planes-creation-to-its-own-functi.patch b/target/linux/bcm27xx/patches-5.4/950-0541-drm-vc4-plane-Move-planes-creation-to-its-own-functi.patch index 025efee0e3..025efee0e3 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0547-drm-vc4-plane-Move-planes-creation-to-its-own-functi.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0541-drm-vc4-plane-Move-planes-creation-to-its-own-functi.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0548-drm-vc4-plane-Move-additional-planes-creation-to-dri.patch b/target/linux/bcm27xx/patches-5.4/950-0542-drm-vc4-plane-Move-additional-planes-creation-to-dri.patch index b2e9f15647..b2e9f15647 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0548-drm-vc4-plane-Move-additional-planes-creation-to-dri.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0542-drm-vc4-plane-Move-additional-planes-creation-to-dri.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0549-drm-vc4-plane-Register-all-the-planes-at-once.patch b/target/linux/bcm27xx/patches-5.4/950-0543-drm-vc4-plane-Register-all-the-planes-at-once.patch index 28277f1e56..28277f1e56 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0549-drm-vc4-plane-Register-all-the-planes-at-once.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0543-drm-vc4-plane-Register-all-the-planes-at-once.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0550-drm-vc4-plane-Create-overlays-for-any-CRTC.patch b/target/linux/bcm27xx/patches-5.4/950-0544-drm-vc4-plane-Create-overlays-for-any-CRTC.patch index 7b9ec02cf6..7b9ec02cf6 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0550-drm-vc4-plane-Create-overlays-for-any-CRTC.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0544-drm-vc4-plane-Create-overlays-for-any-CRTC.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0551-drm-vc4-plane-Create-more-planes.patch b/target/linux/bcm27xx/patches-5.4/950-0545-drm-vc4-plane-Create-more-planes.patch index 931e2bdad4..931e2bdad4 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0551-drm-vc4-plane-Create-more-planes.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0545-drm-vc4-plane-Create-more-planes.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0552-drm-vc4-crtc-Rename-SoC-data-structures.patch b/target/linux/bcm27xx/patches-5.4/950-0546-drm-vc4-crtc-Rename-SoC-data-structures.patch index 8b8eeea737..8b8eeea737 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0552-drm-vc4-crtc-Rename-SoC-data-structures.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0546-drm-vc4-crtc-Rename-SoC-data-structures.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0553-drm-vc4-crtc-Move-crtc-state-to-common-header.patch b/target/linux/bcm27xx/patches-5.4/950-0547-drm-vc4-crtc-Move-crtc-state-to-common-header.patch index 6108f86787..6108f86787 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0553-drm-vc4-crtc-Move-crtc-state-to-common-header.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0547-drm-vc4-crtc-Move-crtc-state-to-common-header.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0554-drm-vc4-crtc-Deal-with-different-number-of-pixel-per.patch b/target/linux/bcm27xx/patches-5.4/950-0548-drm-vc4-crtc-Deal-with-different-number-of-pixel-per.patch index 5949e616f9..5949e616f9 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0554-drm-vc4-crtc-Deal-with-different-number-of-pixel-per.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0548-drm-vc4-crtc-Deal-with-different-number-of-pixel-per.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0555-drm-vc4-crtc-Use-a-shared-interrupt.patch b/target/linux/bcm27xx/patches-5.4/950-0549-drm-vc4-crtc-Use-a-shared-interrupt.patch index b517b5414b..b517b5414b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0555-drm-vc4-crtc-Use-a-shared-interrupt.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0549-drm-vc4-crtc-Use-a-shared-interrupt.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0556-drm-vc4-crtc-Turn-static-const-variable-into-a-defin.patch b/target/linux/bcm27xx/patches-5.4/950-0550-drm-vc4-crtc-Turn-static-const-variable-into-a-defin.patch index 3deefc361f..3deefc361f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0556-drm-vc4-crtc-Turn-static-const-variable-into-a-defin.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0550-drm-vc4-crtc-Turn-static-const-variable-into-a-defin.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0557-drm-vc4-crtc-Move-the-cob-allocation-outside-of-bind.patch b/target/linux/bcm27xx/patches-5.4/950-0551-drm-vc4-crtc-Move-the-cob-allocation-outside-of-bind.patch index 83c49132a3..83c49132a3 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0557-drm-vc4-crtc-Move-the-cob-allocation-outside-of-bind.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0551-drm-vc4-crtc-Move-the-cob-allocation-outside-of-bind.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0558-drm-vc4-crtc-Rename-HVS-channel-to-output.patch b/target/linux/bcm27xx/patches-5.4/950-0552-drm-vc4-crtc-Rename-HVS-channel-to-output.patch index cf854fceb8..cf854fceb8 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0558-drm-vc4-crtc-Rename-HVS-channel-to-output.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0552-drm-vc4-crtc-Rename-HVS-channel-to-output.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0559-drm-vc4-crtc-Use-local-chan-variable.patch b/target/linux/bcm27xx/patches-5.4/950-0553-drm-vc4-crtc-Use-local-chan-variable.patch index 6f77bace01..6f77bace01 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0559-drm-vc4-crtc-Use-local-chan-variable.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0553-drm-vc4-crtc-Use-local-chan-variable.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0560-drm-vc4-crtc-Enable-and-disable-the-PV-in-atomic_ena.patch b/target/linux/bcm27xx/patches-5.4/950-0554-drm-vc4-crtc-Enable-and-disable-the-PV-in-atomic_ena.patch index c5f06f20ea..c5f06f20ea 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0560-drm-vc4-crtc-Enable-and-disable-the-PV-in-atomic_ena.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0554-drm-vc4-crtc-Enable-and-disable-the-PV-in-atomic_ena.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0561-drm-vc4-crtc-Assign-output-to-channel-automatically.patch b/target/linux/bcm27xx/patches-5.4/950-0555-drm-vc4-crtc-Assign-output-to-channel-automatically.patch index d470f3b7f0..d470f3b7f0 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0561-drm-vc4-crtc-Assign-output-to-channel-automatically.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0555-drm-vc4-crtc-Assign-output-to-channel-automatically.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0562-drm-vc4-crtc-Add-FIFO-depth-to-vc4_crtc_data.patch b/target/linux/bcm27xx/patches-5.4/950-0556-drm-vc4-crtc-Add-FIFO-depth-to-vc4_crtc_data.patch index e920a0be64..e920a0be64 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0562-drm-vc4-crtc-Add-FIFO-depth-to-vc4_crtc_data.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0556-drm-vc4-crtc-Add-FIFO-depth-to-vc4_crtc_data.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0563-drm-vc4-crtc-Add-function-to-compute-FIFO-level-bits.patch b/target/linux/bcm27xx/patches-5.4/950-0557-drm-vc4-crtc-Add-function-to-compute-FIFO-level-bits.patch index 77952c0eea..77952c0eea 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0563-drm-vc4-crtc-Add-function-to-compute-FIFO-level-bits.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0557-drm-vc4-crtc-Add-function-to-compute-FIFO-level-bits.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0564-drm-vc4-crtc-Rename-HDMI-encoder-type-to-HDMI0.patch b/target/linux/bcm27xx/patches-5.4/950-0558-drm-vc4-crtc-Rename-HDMI-encoder-type-to-HDMI0.patch index fa6a8f9a63..fa6a8f9a63 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0564-drm-vc4-crtc-Rename-HDMI-encoder-type-to-HDMI0.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0558-drm-vc4-crtc-Rename-HDMI-encoder-type-to-HDMI0.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0565-drm-vc4-crtc-Add-HDMI1-encoder-type.patch b/target/linux/bcm27xx/patches-5.4/950-0559-drm-vc4-crtc-Add-HDMI1-encoder-type.patch index 00ad755492..00ad755492 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0565-drm-vc4-crtc-Add-HDMI1-encoder-type.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0559-drm-vc4-crtc-Add-HDMI1-encoder-type.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-crtc-Remove-redundant-call-to-drm_crtc_enabl.patch b/target/linux/bcm27xx/patches-5.4/950-0560-drm-vc4-crtc-Remove-redundant-call-to-drm_crtc_enabl.patch index 5704952569..5704952569 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-crtc-Remove-redundant-call-to-drm_crtc_enabl.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0560-drm-vc4-crtc-Remove-redundant-call-to-drm_crtc_enabl.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0567-drm-vc4-crtc-Disable-color-management-for-HVS5.patch b/target/linux/bcm27xx/patches-5.4/950-0561-drm-vc4-crtc-Disable-color-management-for-HVS5.patch index bd487df5c4..bd487df5c4 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0567-drm-vc4-crtc-Disable-color-management-for-HVS5.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0561-drm-vc4-crtc-Disable-color-management-for-HVS5.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0568-dt-bindings-display-vc4-pv-Add-BCM2711-pixel-valves.patch b/target/linux/bcm27xx/patches-5.4/950-0562-dt-bindings-display-vc4-pv-Add-BCM2711-pixel-valves.patch index 6bf6ab74c4..6bf6ab74c4 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0568-dt-bindings-display-vc4-pv-Add-BCM2711-pixel-valves.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0562-dt-bindings-display-vc4-pv-Add-BCM2711-pixel-valves.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0569-drm-vc4-crtc-Add-BCM2711-pixelvalves.patch b/target/linux/bcm27xx/patches-5.4/950-0563-drm-vc4-crtc-Add-BCM2711-pixelvalves.patch index 3ff57ef3df..3ff57ef3df 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0569-drm-vc4-crtc-Add-BCM2711-pixelvalves.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0563-drm-vc4-crtc-Add-BCM2711-pixelvalves.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0570-drm-vc4-hdmi-Use-debugfs-private-field.patch b/target/linux/bcm27xx/patches-5.4/950-0564-drm-vc4-hdmi-Use-debugfs-private-field.patch index 89d8aae28d..89d8aae28d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0570-drm-vc4-hdmi-Use-debugfs-private-field.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0564-drm-vc4-hdmi-Use-debugfs-private-field.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0571-drm-vc4-hdmi-Move-structure-to-header.patch b/target/linux/bcm27xx/patches-5.4/950-0565-drm-vc4-hdmi-Move-structure-to-header.patch index 430fc0459e..430fc0459e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0571-drm-vc4-hdmi-Move-structure-to-header.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0565-drm-vc4-hdmi-Move-structure-to-header.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0572-drm-vc4-hdmi-rework-connectors-and-encoders.patch b/target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-hdmi-rework-connectors-and-encoders.patch index ebe6432913..ebe6432913 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0572-drm-vc4-hdmi-rework-connectors-and-encoders.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-hdmi-rework-connectors-and-encoders.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0573-drm-vc4-hdmi-Rename-hdmi-to-vc4_hdmi.patch b/target/linux/bcm27xx/patches-5.4/950-0567-drm-vc4-hdmi-Rename-hdmi-to-vc4_hdmi.patch index 19296e93ee..19296e93ee 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0573-drm-vc4-hdmi-Rename-hdmi-to-vc4_hdmi.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0567-drm-vc4-hdmi-Rename-hdmi-to-vc4_hdmi.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0574-drm-vc4-hdmi-Move-accessors-to-vc4_hdmi.patch b/target/linux/bcm27xx/patches-5.4/950-0568-drm-vc4-hdmi-Move-accessors-to-vc4_hdmi.patch index 1e50c0c579..1e50c0c579 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0574-drm-vc4-hdmi-Move-accessors-to-vc4_hdmi.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0568-drm-vc4-hdmi-Move-accessors-to-vc4_hdmi.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0575-drm-vc4-hdmi-Use-local-vc4_hdmi-directly.patch b/target/linux/bcm27xx/patches-5.4/950-0569-drm-vc4-hdmi-Use-local-vc4_hdmi-directly.patch index 9b60fbb72b..9b60fbb72b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0575-drm-vc4-hdmi-Use-local-vc4_hdmi-directly.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0569-drm-vc4-hdmi-Use-local-vc4_hdmi-directly.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0576-drm-vc4-hdmi-Add-container_of-macros-for-encoders-an.patch b/target/linux/bcm27xx/patches-5.4/950-0570-drm-vc4-hdmi-Add-container_of-macros-for-encoders-an.patch index 1d70ca851c..1d70ca851c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0576-drm-vc4-hdmi-Add-container_of-macros-for-encoders-an.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0570-drm-vc4-hdmi-Add-container_of-macros-for-encoders-an.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0577-drm-vc4-hdmi-Pass-vc4_hdmi-to-CEC-code.patch b/target/linux/bcm27xx/patches-5.4/950-0571-drm-vc4-hdmi-Pass-vc4_hdmi-to-CEC-code.patch index 092efc17f5..092efc17f5 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0577-drm-vc4-hdmi-Pass-vc4_hdmi-to-CEC-code.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0571-drm-vc4-hdmi-Pass-vc4_hdmi-to-CEC-code.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0578-drm-vc4-hdmi-Remove-vc4_dev-hdmi-pointer.patch b/target/linux/bcm27xx/patches-5.4/950-0572-drm-vc4-hdmi-Remove-vc4_dev-hdmi-pointer.patch index 24e4229c0e..24e4229c0e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0578-drm-vc4-hdmi-Remove-vc4_dev-hdmi-pointer.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0572-drm-vc4-hdmi-Remove-vc4_dev-hdmi-pointer.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0579-drm-vc4-hdmi-Remove-vc4_hdmi_connector.patch b/target/linux/bcm27xx/patches-5.4/950-0573-drm-vc4-hdmi-Remove-vc4_hdmi_connector.patch index 15d15c6afe..15d15c6afe 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0579-drm-vc4-hdmi-Remove-vc4_hdmi_connector.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0573-drm-vc4-hdmi-Remove-vc4_hdmi_connector.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0580-drm-vc4-hdmi-Introduce-resource-init-and-variant.patch b/target/linux/bcm27xx/patches-5.4/950-0574-drm-vc4-hdmi-Introduce-resource-init-and-variant.patch index c3a4a76bad..c3a4a76bad 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0580-drm-vc4-hdmi-Introduce-resource-init-and-variant.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0574-drm-vc4-hdmi-Introduce-resource-init-and-variant.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0581-drm-vc4-hdmi-Implement-a-register-layout-abstraction.patch b/target/linux/bcm27xx/patches-5.4/950-0575-drm-vc4-hdmi-Implement-a-register-layout-abstraction.patch index dbfb08eebb..dbfb08eebb 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0581-drm-vc4-hdmi-Implement-a-register-layout-abstraction.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0575-drm-vc4-hdmi-Implement-a-register-layout-abstraction.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0582-drm-vc4-hdmi-Add-reset-callback.patch b/target/linux/bcm27xx/patches-5.4/950-0576-drm-vc4-hdmi-Add-reset-callback.patch index 18c11aba45..18c11aba45 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0582-drm-vc4-hdmi-Add-reset-callback.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0576-drm-vc4-hdmi-Add-reset-callback.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0583-drm-vc4-hdmi-Add-PHY-init-and-disable-function.patch b/target/linux/bcm27xx/patches-5.4/950-0577-drm-vc4-hdmi-Add-PHY-init-and-disable-function.patch index ce295f3fce..ce295f3fce 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0583-drm-vc4-hdmi-Add-PHY-init-and-disable-function.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0577-drm-vc4-hdmi-Add-PHY-init-and-disable-function.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0584-drm-vc4-hdmi-Add-PHY-RNG-enable-disable-function.patch b/target/linux/bcm27xx/patches-5.4/950-0578-drm-vc4-hdmi-Add-PHY-RNG-enable-disable-function.patch index 0fb6a63bcc..0fb6a63bcc 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0584-drm-vc4-hdmi-Add-PHY-RNG-enable-disable-function.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0578-drm-vc4-hdmi-Add-PHY-RNG-enable-disable-function.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0585-drm-vc4-hdmi-Add-a-CSC-setup-callback.patch b/target/linux/bcm27xx/patches-5.4/950-0579-drm-vc4-hdmi-Add-a-CSC-setup-callback.patch index 0106470d93..0106470d93 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0585-drm-vc4-hdmi-Add-a-CSC-setup-callback.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0579-drm-vc4-hdmi-Add-a-CSC-setup-callback.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0586-drm-vc4-hdmi-Add-a-set_timings-callback.patch b/target/linux/bcm27xx/patches-5.4/950-0580-drm-vc4-hdmi-Add-a-set_timings-callback.patch index 064925c61a..064925c61a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0586-drm-vc4-hdmi-Add-a-set_timings-callback.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0580-drm-vc4-hdmi-Add-a-set_timings-callback.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0587-drm-vc4-hdmi-Add-HDMI-ID.patch b/target/linux/bcm27xx/patches-5.4/950-0581-drm-vc4-hdmi-Add-HDMI-ID.patch index b5d9c7b340..b5d9c7b340 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0587-drm-vc4-hdmi-Add-HDMI-ID.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0581-drm-vc4-hdmi-Add-HDMI-ID.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0588-drm-vc4-hdmi-Deal-with-multiple-debugfs-files.patch b/target/linux/bcm27xx/patches-5.4/950-0582-drm-vc4-hdmi-Deal-with-multiple-debugfs-files.patch index e25b18a21f..e25b18a21f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0588-drm-vc4-hdmi-Deal-with-multiple-debugfs-files.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0582-drm-vc4-hdmi-Deal-with-multiple-debugfs-files.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0589-drm-vc4-hdmi-Add-an-audio-support-flag.patch b/target/linux/bcm27xx/patches-5.4/950-0583-drm-vc4-hdmi-Add-an-audio-support-flag.patch index 9c8240714a..9c8240714a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0589-drm-vc4-hdmi-Add-an-audio-support-flag.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0583-drm-vc4-hdmi-Add-an-audio-support-flag.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0590-drm-vc4-hdmi-Move-CEC-init-to-its-own-function.patch b/target/linux/bcm27xx/patches-5.4/950-0584-drm-vc4-hdmi-Move-CEC-init-to-its-own-function.patch index a3efadd2ad..a3efadd2ad 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0590-drm-vc4-hdmi-Move-CEC-init-to-its-own-function.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0584-drm-vc4-hdmi-Move-CEC-init-to-its-own-function.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0591-drm-vc4-hdmi-Add-CEC-support-flag.patch b/target/linux/bcm27xx/patches-5.4/950-0585-drm-vc4-hdmi-Add-CEC-support-flag.patch index 396e8a5523..396e8a5523 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0591-drm-vc4-hdmi-Add-CEC-support-flag.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0585-drm-vc4-hdmi-Add-CEC-support-flag.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0592-drm-vc4-hdmi-Remove-unused-CEC_CLOCK_DIV-define.patch b/target/linux/bcm27xx/patches-5.4/950-0586-drm-vc4-hdmi-Remove-unused-CEC_CLOCK_DIV-define.patch index 4befec6c05..4befec6c05 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0592-drm-vc4-hdmi-Remove-unused-CEC_CLOCK_DIV-define.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0586-drm-vc4-hdmi-Remove-unused-CEC_CLOCK_DIV-define.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0593-drm-vc4-hdmi-Rename-drm_encoder-pointer-in-mode_vali.patch b/target/linux/bcm27xx/patches-5.4/950-0587-drm-vc4-hdmi-Rename-drm_encoder-pointer-in-mode_vali.patch index 5c0ab9768b..5c0ab9768b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0593-drm-vc4-hdmi-Rename-drm_encoder-pointer-in-mode_vali.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0587-drm-vc4-hdmi-Rename-drm_encoder-pointer-in-mode_vali.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0594-drm-vc4-hdmi-Adjust-HSM-clock-rate-depending-on-pixe.patch b/target/linux/bcm27xx/patches-5.4/950-0588-drm-vc4-hdmi-Adjust-HSM-clock-rate-depending-on-pixe.patch index 5b836f8bf8..5b836f8bf8 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0594-drm-vc4-hdmi-Adjust-HSM-clock-rate-depending-on-pixe.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0588-drm-vc4-hdmi-Adjust-HSM-clock-rate-depending-on-pixe.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0595-drm-vc4-hdmi-Support-the-BCM2711-HDMI-controllers.patch b/target/linux/bcm27xx/patches-5.4/950-0589-drm-vc4-hdmi-Support-the-BCM2711-HDMI-controllers.patch index 8a2772299a..8a2772299a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0595-drm-vc4-hdmi-Support-the-BCM2711-HDMI-controllers.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0589-drm-vc4-hdmi-Support-the-BCM2711-HDMI-controllers.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0596-dt-bindings-display-vc4-hdmi-Add-BCM2711-HDMI-contro.patch b/target/linux/bcm27xx/patches-5.4/950-0590-dt-bindings-display-vc4-hdmi-Add-BCM2711-HDMI-contro.patch index c41e063fde..c41e063fde 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0596-dt-bindings-display-vc4-hdmi-Add-BCM2711-HDMI-contro.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0590-dt-bindings-display-vc4-hdmi-Add-BCM2711-HDMI-contro.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0597-ARM-dts-bcm2711-Enable-the-display-pipeline.patch b/target/linux/bcm27xx/patches-5.4/950-0591-ARM-dts-bcm2711-Enable-the-display-pipeline.patch index aae9b9e00d..aae9b9e00d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0597-ARM-dts-bcm2711-Enable-the-display-pipeline.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0591-ARM-dts-bcm2711-Enable-the-display-pipeline.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0598-DOWNSTREAM-ARM-dts-rpi4-Disable-KMS-driver-by-defaul.patch b/target/linux/bcm27xx/patches-5.4/950-0592-DOWNSTREAM-ARM-dts-rpi4-Disable-KMS-driver-by-defaul.patch index b27d355340..b27d355340 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0598-DOWNSTREAM-ARM-dts-rpi4-Disable-KMS-driver-by-defaul.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0592-DOWNSTREAM-ARM-dts-rpi4-Disable-KMS-driver-by-defaul.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0599-dtoverlays-Add-Pi4-version-of-vc4-kms-v3d.patch b/target/linux/bcm27xx/patches-5.4/950-0593-dtoverlays-Add-Pi4-version-of-vc4-kms-v3d.patch index 1c46fa4485..1c46fa4485 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0599-dtoverlays-Add-Pi4-version-of-vc4-kms-v3d.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0593-dtoverlays-Add-Pi4-version-of-vc4-kms-v3d.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0600-drm-Checking-of-the-pitch-is-only-valid-for-linear-f.patch b/target/linux/bcm27xx/patches-5.4/950-0594-drm-Checking-of-the-pitch-is-only-valid-for-linear-f.patch index 3f0aa4aa02..3f0aa4aa02 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0600-drm-Checking-of-the-pitch-is-only-valid-for-linear-f.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0594-drm-Checking-of-the-pitch-is-only-valid-for-linear-f.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0601-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch b/target/linux/bcm27xx/patches-5.4/950-0595-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch index a4d5afe406..a4d5afe406 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0601-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0595-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0602-Fixup-P030-support.patch b/target/linux/bcm27xx/patches-5.4/950-0596-Fixup-P030-support.patch index 0963824d9e..0963824d9e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0602-Fixup-P030-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0596-Fixup-P030-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0603-drm-vc4-The-check-for-assigned-HVS-channels-is-not-a.patch b/target/linux/bcm27xx/patches-5.4/950-0597-drm-vc4-The-check-for-assigned-HVS-channels-is-not-a.patch index 00a65a9b11..00a65a9b11 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0603-drm-vc4-The-check-for-assigned-HVS-channels-is-not-a.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0597-drm-vc4-The-check-for-assigned-HVS-channels-is-not-a.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0604-dt-Update-v3d-to-use-firmware_clocks.patch b/target/linux/bcm27xx/patches-5.4/950-0598-dt-Update-v3d-to-use-firmware_clocks.patch index b67f38782f..b67f38782f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0604-dt-Update-v3d-to-use-firmware_clocks.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0598-dt-Update-v3d-to-use-firmware_clocks.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0605-drm-vc4-Reset-audio-infoframe-on-encoder_enable-if-p.patch b/target/linux/bcm27xx/patches-5.4/950-0599-drm-vc4-Reset-audio-infoframe-on-encoder_enable-if-p.patch index 56106a4274..56106a4274 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0605-drm-vc4-Reset-audio-infoframe-on-encoder_enable-if-p.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0599-drm-vc4-Reset-audio-infoframe-on-encoder_enable-if-p.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0606-drm-vc4-Set-the-b-frame-marker-to-the-match-ALSA-s-d.patch b/target/linux/bcm27xx/patches-5.4/950-0600-drm-vc4-Set-the-b-frame-marker-to-the-match-ALSA-s-d.patch index 4827f96023..4827f96023 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0606-drm-vc4-Set-the-b-frame-marker-to-the-match-ALSA-s-d.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0600-drm-vc4-Set-the-b-frame-marker-to-the-match-ALSA-s-d.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0607-dts-Add-reg-names-for-the-HDMI-registers-on-bcm2835.patch b/target/linux/bcm27xx/patches-5.4/950-0601-dts-Add-reg-names-for-the-HDMI-registers-on-bcm2835.patch index 65e206c181..65e206c181 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0607-dts-Add-reg-names-for-the-HDMI-registers-on-bcm2835.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0601-dts-Add-reg-names-for-the-HDMI-registers-on-bcm2835.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0608-dt-Add-HDMI-audio-dma-values-to-bcm2711.dtsi.patch b/target/linux/bcm27xx/patches-5.4/950-0602-dt-Add-HDMI-audio-dma-values-to-bcm2711.dtsi.patch index 9a9fd06eeb..9a9fd06eeb 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0608-dt-Add-HDMI-audio-dma-values-to-bcm2711.dtsi.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0602-dt-Add-HDMI-audio-dma-values-to-bcm2711.dtsi.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0609-drm-vc4-Use-reg-names-to-configure-HDMI-audio.patch b/target/linux/bcm27xx/patches-5.4/950-0603-drm-vc4-Use-reg-names-to-configure-HDMI-audio.patch index 2504a07083..2504a07083 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0609-drm-vc4-Use-reg-names-to-configure-HDMI-audio.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0603-drm-vc4-Use-reg-names-to-configure-HDMI-audio.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0610-drm-vc4-Add-audio-initialisation-for-Pi4.patch b/target/linux/bcm27xx/patches-5.4/950-0604-drm-vc4-Add-audio-initialisation-for-Pi4.patch index 4388099671..4388099671 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0610-drm-vc4-Add-audio-initialisation-for-Pi4.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0604-drm-vc4-Add-audio-initialisation-for-Pi4.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0611-drm-vc4-Enable-audio-on-Pi4.patch b/target/linux/bcm27xx/patches-5.4/950-0605-drm-vc4-Enable-audio-on-Pi4.patch index b07a815df4..b07a815df4 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0611-drm-vc4-Enable-audio-on-Pi4.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0605-drm-vc4-Enable-audio-on-Pi4.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0612-drm-vc4-Alter-the-HDMI-state-machine-clock-calc-to-a.patch b/target/linux/bcm27xx/patches-5.4/950-0606-drm-vc4-Alter-the-HDMI-state-machine-clock-calc-to-a.patch index dc2d1a2a04..dc2d1a2a04 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0612-drm-vc4-Alter-the-HDMI-state-machine-clock-calc-to-a.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0606-drm-vc4-Alter-the-HDMI-state-machine-clock-calc-to-a.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0613-dtoverlays-Remove-comment-about-vc4-kms-v3d-locking-.patch b/target/linux/bcm27xx/patches-5.4/950-0607-dtoverlays-Remove-comment-about-vc4-kms-v3d-locking-.patch index a05bf055ff..a05bf055ff 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0613-dtoverlays-Remove-comment-about-vc4-kms-v3d-locking-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0607-dtoverlays-Remove-comment-about-vc4-kms-v3d-locking-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0614-drm-vc4-Kick-the-core-clock-up-during-a-mode-change.patch b/target/linux/bcm27xx/patches-5.4/950-0608-drm-vc4-Kick-the-core-clock-up-during-a-mode-change.patch index 871d86a7a9..871d86a7a9 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0614-drm-vc4-Kick-the-core-clock-up-during-a-mode-change.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0608-drm-vc4-Kick-the-core-clock-up-during-a-mode-change.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0615-drm-vc4-Fixup-for-firmware-KMS.patch b/target/linux/bcm27xx/patches-5.4/950-0609-drm-vc4-Fixup-for-firmware-KMS.patch index 62080bffec..62080bffec 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0615-drm-vc4-Fixup-for-firmware-KMS.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0609-drm-vc4-Fixup-for-firmware-KMS.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0616-drm-vc4-Fixup-plane-init-within-firmware-kms.patch b/target/linux/bcm27xx/patches-5.4/950-0610-drm-vc4-Fixup-plane-init-within-firmware-kms.patch index 8edba988f2..8edba988f2 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0616-drm-vc4-Fixup-plane-init-within-firmware-kms.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0610-drm-vc4-Fixup-plane-init-within-firmware-kms.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0617-drm-vc4-hdmi-Give-the-HDMI-audio-instances-different.patch b/target/linux/bcm27xx/patches-5.4/950-0611-drm-vc4-hdmi-Give-the-HDMI-audio-instances-different.patch index aff182dbec..aff182dbec 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0617-drm-vc4-hdmi-Give-the-HDMI-audio-instances-different.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0611-drm-vc4-hdmi-Give-the-HDMI-audio-instances-different.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0618-i2c-brcmstb-The-interrupt-line-is-optional-so-use-pl.patch b/target/linux/bcm27xx/patches-5.4/950-0612-i2c-brcmstb-The-interrupt-line-is-optional-so-use-pl.patch index 89285ad25c..89285ad25c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0618-i2c-brcmstb-The-interrupt-line-is-optional-so-use-pl.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0612-i2c-brcmstb-The-interrupt-line-is-optional-so-use-pl.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0619-dt-Drop-I2C-for-Pi4-HDMI-interfaces-to-97.5kHz.patch b/target/linux/bcm27xx/patches-5.4/950-0613-dt-Drop-I2C-for-Pi4-HDMI-interfaces-to-97.5kHz.patch index cd18cd1309..cd18cd1309 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0619-dt-Drop-I2C-for-Pi4-HDMI-interfaces-to-97.5kHz.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0613-dt-Drop-I2C-for-Pi4-HDMI-interfaces-to-97.5kHz.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0620-overlays-Add-missing-rpi-poe-parameters.patch b/target/linux/bcm27xx/patches-5.4/950-0614-overlays-Add-missing-rpi-poe-parameters.patch index 716678f078..716678f078 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0620-overlays-Add-missing-rpi-poe-parameters.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0614-overlays-Add-missing-rpi-poe-parameters.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0621-vc4_hdmi_phy-Fix-offset-calculation.patch b/target/linux/bcm27xx/patches-5.4/950-0615-vc4_hdmi_phy-Fix-offset-calculation.patch index 83d8d25e29..83d8d25e29 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0621-vc4_hdmi_phy-Fix-offset-calculation.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0615-vc4_hdmi_phy-Fix-offset-calculation.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0622-overlays-Add-overlay_map.patch b/target/linux/bcm27xx/patches-5.4/950-0616-overlays-Add-overlay_map.patch index 20f548328c..20f548328c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0622-overlays-Add-overlay_map.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0616-overlays-Add-overlay_map.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0623-overlays-Formally-rename-deprecate-old-overlays.patch b/target/linux/bcm27xx/patches-5.4/950-0617-overlays-Formally-rename-deprecate-old-overlays.patch index edcb3792af..edcb3792af 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0623-overlays-Formally-rename-deprecate-old-overlays.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0617-overlays-Formally-rename-deprecate-old-overlays.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0624-overlays-Add-vc4-kms-v3d-pi4-to-overlay_map.patch b/target/linux/bcm27xx/patches-5.4/950-0618-overlays-Add-vc4-kms-v3d-pi4-to-overlay_map.patch index 4fd5879ec8..4fd5879ec8 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0624-overlays-Add-vc4-kms-v3d-pi4-to-overlay_map.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0618-overlays-Add-vc4-kms-v3d-pi4-to-overlay_map.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0625-Add-upstream-and-upstream-pi4-to-overlay_map.patch b/target/linux/bcm27xx/patches-5.4/950-0619-Add-upstream-and-upstream-pi4-to-overlay_map.patch index e76367b9da..e76367b9da 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0625-Add-upstream-and-upstream-pi4-to-overlay_map.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0619-Add-upstream-and-upstream-pi4-to-overlay_map.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0626-clk-raspberrypi-Allow-cpufreq-driver-to-also-adjust-.patch b/target/linux/bcm27xx/patches-5.4/950-0620-clk-raspberrypi-Allow-cpufreq-driver-to-also-adjust-.patch index c0422f4ed3..c0422f4ed3 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0626-clk-raspberrypi-Allow-cpufreq-driver-to-also-adjust-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0620-clk-raspberrypi-Allow-cpufreq-driver-to-also-adjust-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0627-Add-support-for-the-AudioInjector.net-Isolated-sound.patch b/target/linux/bcm27xx/patches-5.4/950-0621-Add-support-for-the-AudioInjector.net-Isolated-sound.patch index e35806962e..e35806962e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0627-Add-support-for-the-AudioInjector.net-Isolated-sound.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0621-Add-support-for-the-AudioInjector.net-Isolated-sound.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0628-overlays-Fix-dtc-warnings-in-i2c-gpio.patch b/target/linux/bcm27xx/patches-5.4/950-0622-overlays-Fix-dtc-warnings-in-i2c-gpio.patch index 2da57b81de..2da57b81de 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0628-overlays-Fix-dtc-warnings-in-i2c-gpio.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0622-overlays-Fix-dtc-warnings-in-i2c-gpio.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0629-kbuild-Disable-gcc-plugins.patch b/target/linux/bcm27xx/patches-5.4/950-0623-kbuild-Disable-gcc-plugins.patch index 66091ca591..66091ca591 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0629-kbuild-Disable-gcc-plugins.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0623-kbuild-Disable-gcc-plugins.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0630-ASoC-ma120x0p-Add-96KHz-rate-support.patch b/target/linux/bcm27xx/patches-5.4/950-0624-ASoC-ma120x0p-Add-96KHz-rate-support.patch index a5aee43aef..a5aee43aef 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0630-ASoC-ma120x0p-Add-96KHz-rate-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0624-ASoC-ma120x0p-Add-96KHz-rate-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0631-arm64-mm-reserve-CMA-and-crashkernel-in-ZONE_DMA32.patch b/target/linux/bcm27xx/patches-5.4/950-0625-arm64-mm-reserve-CMA-and-crashkernel-in-ZONE_DMA32.patch index e1a340ec91..e1a340ec91 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0631-arm64-mm-reserve-CMA-and-crashkernel-in-ZONE_DMA32.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0625-arm64-mm-reserve-CMA-and-crashkernel-in-ZONE_DMA32.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0632-arm64-mm-Fix-initialisation-of-DMA-zones-on-non-NUMA.patch b/target/linux/bcm27xx/patches-5.4/950-0626-arm64-mm-Fix-initialisation-of-DMA-zones-on-non-NUMA.patch index 0f4f09ee1c..0f4f09ee1c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0632-arm64-mm-Fix-initialisation-of-DMA-zones-on-non-NUMA.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0626-arm64-mm-Fix-initialisation-of-DMA-zones-on-non-NUMA.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0633-ARM-dts-bcm283x-Unify-CMA-configuration.patch b/target/linux/bcm27xx/patches-5.4/950-0627-ARM-dts-bcm283x-Unify-CMA-configuration.patch index a0dfcb3325..a0dfcb3325 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0633-ARM-dts-bcm283x-Unify-CMA-configuration.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0627-ARM-dts-bcm283x-Unify-CMA-configuration.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0634-dma-contiguous-CMA-give-precedence-to-cmdline.patch b/target/linux/bcm27xx/patches-5.4/950-0628-dma-contiguous-CMA-give-precedence-to-cmdline.patch index d3354bb9e1..d3354bb9e1 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0634-dma-contiguous-CMA-give-precedence-to-cmdline.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0628-dma-contiguous-CMA-give-precedence-to-cmdline.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0635-ARM-dts-Use-upstream-CMA-configuration.patch b/target/linux/bcm27xx/patches-5.4/950-0629-ARM-dts-Use-upstream-CMA-configuration.patch index fb4fe893c0..fb4fe893c0 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0635-ARM-dts-Use-upstream-CMA-configuration.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0629-ARM-dts-Use-upstream-CMA-configuration.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0636-ARM-dts-overlays-Unify-overlay-CMA-handling.patch b/target/linux/bcm27xx/patches-5.4/950-0630-ARM-dts-overlays-Unify-overlay-CMA-handling.patch index 3c0f1e4388..3c0f1e4388 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0636-ARM-dts-overlays-Unify-overlay-CMA-handling.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0630-ARM-dts-overlays-Unify-overlay-CMA-handling.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0637-ARM-dts-bcm283x-Fix-vc4-s-firmware-bus-DMA-limitatio.patch b/target/linux/bcm27xx/patches-5.4/950-0631-ARM-dts-bcm283x-Fix-vc4-s-firmware-bus-DMA-limitatio.patch index 31840e5437..31840e5437 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0637-ARM-dts-bcm283x-Fix-vc4-s-firmware-bus-DMA-limitatio.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0631-ARM-dts-bcm283x-Fix-vc4-s-firmware-bus-DMA-limitatio.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0638-ARM-dts-bcm2711-Restrict-CMA-to-first-768MB.patch b/target/linux/bcm27xx/patches-5.4/950-0632-ARM-dts-bcm2711-Restrict-CMA-to-first-768MB.patch index 9a1e29e7d1..9a1e29e7d1 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0638-ARM-dts-bcm2711-Restrict-CMA-to-first-768MB.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0632-ARM-dts-bcm2711-Restrict-CMA-to-first-768MB.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0639-ARM-dts-Extend-SCB-bus-address-range.patch b/target/linux/bcm27xx/patches-5.4/950-0633-ARM-dts-Extend-SCB-bus-address-range.patch index 8eb2b16b10..8eb2b16b10 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0639-ARM-dts-Extend-SCB-bus-address-range.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0633-ARM-dts-Extend-SCB-bus-address-range.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0640-dts-bcm2711-Move-emmc2-to-its-own-bus.patch b/target/linux/bcm27xx/patches-5.4/950-0634-dts-bcm2711-Move-emmc2-to-its-own-bus.patch index 52cf03a382..52cf03a382 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0640-dts-bcm2711-Move-emmc2-to-its-own-bus.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0634-dts-bcm2711-Move-emmc2-to-its-own-bus.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0641-drm-vc4-hdmi-Silence-pixel-clock-error-on-EPROBE_DEF.patch b/target/linux/bcm27xx/patches-5.4/950-0635-drm-vc4-hdmi-Silence-pixel-clock-error-on-EPROBE_DEF.patch index 0580fc8b93..0580fc8b93 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0641-drm-vc4-hdmi-Silence-pixel-clock-error-on-EPROBE_DEF.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0635-drm-vc4-hdmi-Silence-pixel-clock-error-on-EPROBE_DEF.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0643-Fixes-a-problem-with-clock-settings-of-HiFiBerry-DAC.patch b/target/linux/bcm27xx/patches-5.4/950-0636-Fixes-a-problem-with-clock-settings-of-HiFiBerry-DAC.patch index f1427ae71f..f1427ae71f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0643-Fixes-a-problem-with-clock-settings-of-HiFiBerry-DAC.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0636-Fixes-a-problem-with-clock-settings-of-HiFiBerry-DAC.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0644-Documentation-media-Update-sub-device-API-intro.patch b/target/linux/bcm27xx/patches-5.4/950-0637-Documentation-media-Update-sub-device-API-intro.patch index f843a83a7d..f843a83a7d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0644-Documentation-media-Update-sub-device-API-intro.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0637-Documentation-media-Update-sub-device-API-intro.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0645-Documentation-media-Document-read-only-subdevice.patch b/target/linux/bcm27xx/patches-5.4/950-0638-Documentation-media-Document-read-only-subdevice.patch index 1983334ae1..1983334ae1 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0645-Documentation-media-Document-read-only-subdevice.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0638-Documentation-media-Document-read-only-subdevice.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0646-media-v4l2-dev-Add-v4l2_device_register_ro_subdev_no.patch b/target/linux/bcm27xx/patches-5.4/950-0639-media-v4l2-dev-Add-v4l2_device_register_ro_subdev_no.patch index 47f2551ec7..47f2551ec7 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0646-media-v4l2-dev-Add-v4l2_device_register_ro_subdev_no.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0639-media-v4l2-dev-Add-v4l2_device_register_ro_subdev_no.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0647-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch b/target/linux/bcm27xx/patches-5.4/950-0640-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch index e142f598ad..e142f598ad 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0647-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0640-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0648-media-uapi-v4l2-core-Add-sensor-ancillary-data-V4L2-.patch b/target/linux/bcm27xx/patches-5.4/950-0641-media-uapi-v4l2-core-Add-sensor-ancillary-data-V4L2-.patch index 69414e381c..69414e381c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0648-media-uapi-v4l2-core-Add-sensor-ancillary-data-V4L2-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0641-media-uapi-v4l2-core-Add-sensor-ancillary-data-V4L2-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0649-media-uapi-Add-MEDIA_BUS_FMT_SENSOR_DATA-media-bus-f.patch b/target/linux/bcm27xx/patches-5.4/950-0642-media-uapi-Add-MEDIA_BUS_FMT_SENSOR_DATA-media-bus-f.patch index 65162cc5d5..65162cc5d5 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0649-media-uapi-Add-MEDIA_BUS_FMT_SENSOR_DATA-media-bus-f.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0642-media-uapi-Add-MEDIA_BUS_FMT_SENSOR_DATA-media-bus-f.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0650-media-bcm2835-unicam-Add-support-for-mulitple-device.patch b/target/linux/bcm27xx/patches-5.4/950-0643-media-bcm2835-unicam-Add-support-for-mulitple-device.patch index 315feff5d3..315feff5d3 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0650-media-bcm2835-unicam-Add-support-for-mulitple-device.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0643-media-bcm2835-unicam-Add-support-for-mulitple-device.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0651-media-bcm2835-unicam-Add-embedded-data-node.patch b/target/linux/bcm27xx/patches-5.4/950-0644-media-bcm2835-unicam-Add-embedded-data-node.patch index a163a6f1a5..a163a6f1a5 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0651-media-bcm2835-unicam-Add-embedded-data-node.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0644-media-bcm2835-unicam-Add-embedded-data-node.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0652-media-bcm2835-unicam-Use-dummy-buffer-if-none-have-b.patch b/target/linux/bcm27xx/patches-5.4/950-0645-media-bcm2835-unicam-Use-dummy-buffer-if-none-have-b.patch index 836ced8a04..836ced8a04 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0652-media-bcm2835-unicam-Use-dummy-buffer-if-none-have-b.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0645-media-bcm2835-unicam-Use-dummy-buffer-if-none-have-b.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0653-spi-Force-CS_HIGH-if-GPIO-descriptors-are-used.patch b/target/linux/bcm27xx/patches-5.4/950-0646-spi-Force-CS_HIGH-if-GPIO-descriptors-are-used.patch index 42d22c3003..42d22c3003 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0653-spi-Force-CS_HIGH-if-GPIO-descriptors-are-used.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0646-spi-Force-CS_HIGH-if-GPIO-descriptors-are-used.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0654-media-i2c-imx219-Fix-power-sequence.patch b/target/linux/bcm27xx/patches-5.4/950-0647-media-i2c-imx219-Fix-power-sequence.patch index b85d917878..b85d917878 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0654-media-i2c-imx219-Fix-power-sequence.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0647-media-i2c-imx219-Fix-power-sequence.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0655-media-i2c-imx219-Add-support-for-RAW8-bit-bayer-form.patch b/target/linux/bcm27xx/patches-5.4/950-0648-media-i2c-imx219-Add-support-for-RAW8-bit-bayer-form.patch index 552516bd67..552516bd67 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0655-media-i2c-imx219-Add-support-for-RAW8-bit-bayer-form.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0648-media-i2c-imx219-Add-support-for-RAW8-bit-bayer-form.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0656-media-i2c-imx219-Add-support-for-cropped-640x480-res.patch b/target/linux/bcm27xx/patches-5.4/950-0649-media-i2c-imx219-Add-support-for-cropped-640x480-res.patch index 3ad377dfbe..3ad377dfbe 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0656-media-i2c-imx219-Add-support-for-cropped-640x480-res.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0649-media-i2c-imx219-Add-support-for-cropped-640x480-res.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0657-media-i2c-imx219-Fix-a-bug-in-imx219_enum_frame_size.patch b/target/linux/bcm27xx/patches-5.4/950-0650-media-i2c-imx219-Fix-a-bug-in-imx219_enum_frame_size.patch index ef8eff6c00..ef8eff6c00 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0657-media-i2c-imx219-Fix-a-bug-in-imx219_enum_frame_size.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0650-media-i2c-imx219-Fix-a-bug-in-imx219_enum_frame_size.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0658-media-bcm2835-unicam-Disable-event-related-ioctls-on.patch b/target/linux/bcm27xx/patches-5.4/950-0651-media-bcm2835-unicam-Disable-event-related-ioctls-on.patch index cb36ce2d96..cb36ce2d96 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0658-media-bcm2835-unicam-Disable-event-related-ioctls-on.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0651-media-bcm2835-unicam-Disable-event-related-ioctls-on.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0659-media-bcm2835-unicam-Add-support-for-the-FRAME_SYNC-.patch b/target/linux/bcm27xx/patches-5.4/950-0652-media-bcm2835-unicam-Add-support-for-the-FRAME_SYNC-.patch index 544d597a35..544d597a35 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0659-media-bcm2835-unicam-Add-support-for-the-FRAME_SYNC-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0652-media-bcm2835-unicam-Add-support-for-the-FRAME_SYNC-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0660-Revert-firmware-raspberrypi-register-clk-device.patch b/target/linux/bcm27xx/patches-5.4/950-0653-Revert-firmware-raspberrypi-register-clk-device.patch index 01533d1f3f..01533d1f3f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0660-Revert-firmware-raspberrypi-register-clk-device.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0653-Revert-firmware-raspberrypi-register-clk-device.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0661-media-imx219-Advertise-embedded-data-node-on-media-p.patch b/target/linux/bcm27xx/patches-5.4/950-0654-media-imx219-Advertise-embedded-data-node-on-media-p.patch index c4c25d1512..c4c25d1512 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0661-media-imx219-Advertise-embedded-data-node-on-media-p.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0654-media-imx219-Advertise-embedded-data-node-on-media-p.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0662-dts-bcm2711-EMMC2-can-address-the-whole-first-GB.patch b/target/linux/bcm27xx/patches-5.4/950-0655-dts-bcm2711-EMMC2-can-address-the-whole-first-GB.patch index 4c5e50636c..4c5e50636c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0662-dts-bcm2711-EMMC2-can-address-the-whole-first-GB.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0655-dts-bcm2711-EMMC2-can-address-the-whole-first-GB.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0663-driver-char-rpivid-Remove-legacy-name-support.patch b/target/linux/bcm27xx/patches-5.4/950-0656-driver-char-rpivid-Remove-legacy-name-support.patch index a3896be439..a3896be439 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0663-driver-char-rpivid-Remove-legacy-name-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0656-driver-char-rpivid-Remove-legacy-name-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0664-driver-char-rpivid-Don-t-map-more-than-wanted.patch b/target/linux/bcm27xx/patches-5.4/950-0657-driver-char-rpivid-Don-t-map-more-than-wanted.patch index afc1a5a6a8..afc1a5a6a8 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0664-driver-char-rpivid-Don-t-map-more-than-wanted.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0657-driver-char-rpivid-Don-t-map-more-than-wanted.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0665-dt-Implement-an-I2C-pinctrl-mux-for-BSC0.patch b/target/linux/bcm27xx/patches-5.4/950-0658-dt-Implement-an-I2C-pinctrl-mux-for-BSC0.patch index 002ad8686e..002ad8686e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0665-dt-Implement-an-I2C-pinctrl-mux-for-BSC0.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0658-dt-Implement-an-I2C-pinctrl-mux-for-BSC0.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0666-dtoverlays-Update-CSI-overlays-to-use-i2c_csi_dsi.patch b/target/linux/bcm27xx/patches-5.4/950-0659-dtoverlays-Update-CSI-overlays-to-use-i2c_csi_dsi.patch index f6b6340c7f..f6b6340c7f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0666-dtoverlays-Update-CSI-overlays-to-use-i2c_csi_dsi.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0659-dtoverlays-Update-CSI-overlays-to-use-i2c_csi_dsi.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0667-dt-Update-all-mainline-bcm283x-dt-files-for-i2c0-pin.patch b/target/linux/bcm27xx/patches-5.4/950-0660-dt-Update-all-mainline-bcm283x-dt-files-for-i2c0-pin.patch index f5e4e4b008..f5e4e4b008 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0667-dt-Update-all-mainline-bcm283x-dt-files-for-i2c0-pin.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0660-dt-Update-all-mainline-bcm283x-dt-files-for-i2c0-pin.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0668-ARM-dts-Create-bcm2708-rpi-b-rev1.dts.patch b/target/linux/bcm27xx/patches-5.4/950-0661-ARM-dts-Create-bcm2708-rpi-b-rev1.dts.patch index 42067a7816..42067a7816 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0668-ARM-dts-Create-bcm2708-rpi-b-rev1.dts.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0661-ARM-dts-Create-bcm2708-rpi-b-rev1.dts.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0669-dts-bcm2711-set-size-cells-2.patch b/target/linux/bcm27xx/patches-5.4/950-0662-dts-bcm2711-set-size-cells-2.patch index fa5a2d4f54..fa5a2d4f54 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0669-dts-bcm2711-set-size-cells-2.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0662-dts-bcm2711-set-size-cells-2.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0670-dts-bcm2711-add-High-Peripheral-mode-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0663-dts-bcm2711-add-High-Peripheral-mode-overlay.patch index e24f5de000..e24f5de000 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0670-dts-bcm2711-add-High-Peripheral-mode-overlay.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0663-dts-bcm2711-add-High-Peripheral-mode-overlay.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0671-Revert-spi-spidev-Fix-CS-polarity-if-GPIO-descriptor.patch b/target/linux/bcm27xx/patches-5.4/950-0664-Revert-spi-spidev-Fix-CS-polarity-if-GPIO-descriptor.patch index 00bbe98117..00bbe98117 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0671-Revert-spi-spidev-Fix-CS-polarity-if-GPIO-descriptor.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0664-Revert-spi-spidev-Fix-CS-polarity-if-GPIO-descriptor.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0672-spi-use_gpio_descriptor-fixup-moved-to-spi_setup.patch b/target/linux/bcm27xx/patches-5.4/950-0665-spi-use_gpio_descriptor-fixup-moved-to-spi_setup.patch index 8792faa0c9..8792faa0c9 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0672-spi-use_gpio_descriptor-fixup-moved-to-spi_setup.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0665-spi-use_gpio_descriptor-fixup-moved-to-spi_setup.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0673-overlays-rpivid-v4l2-also-needs-size-cells-2.patch b/target/linux/bcm27xx/patches-5.4/950-0666-overlays-rpivid-v4l2-also-needs-size-cells-2.patch index 4a1757dd44..4a1757dd44 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0673-overlays-rpivid-v4l2-also-needs-size-cells-2.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0666-overlays-rpivid-v4l2-also-needs-size-cells-2.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0674-media-bcm2835-unicam-Re-fetch-mbus-code-from-subdev-.patch b/target/linux/bcm27xx/patches-5.4/950-0667-media-bcm2835-unicam-Re-fetch-mbus-code-from-subdev-.patch index 4d43c97e56..4d43c97e56 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0674-media-bcm2835-unicam-Re-fetch-mbus-code-from-subdev-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0667-media-bcm2835-unicam-Re-fetch-mbus-code-from-subdev-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0675-uapi-bcm2835-isp-Add-bcm2835-isp-uapi-header-file.patch b/target/linux/bcm27xx/patches-5.4/950-0668-uapi-bcm2835-isp-Add-bcm2835-isp-uapi-header-file.patch index 9f41783b46..9f41783b46 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0675-uapi-bcm2835-isp-Add-bcm2835-isp-uapi-header-file.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0668-uapi-bcm2835-isp-Add-bcm2835-isp-uapi-header-file.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0676-media-uapi-v4l2-core-Add-ISP-statistics-output-V4L2-.patch b/target/linux/bcm27xx/patches-5.4/950-0669-media-uapi-v4l2-core-Add-ISP-statistics-output-V4L2-.patch index 082dff510c..082dff510c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0676-media-uapi-v4l2-core-Add-ISP-statistics-output-V4L2-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0669-media-uapi-v4l2-core-Add-ISP-statistics-output-V4L2-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0677-media-uapi-v4l-ctrls-Add-CID-base-for-the-bcm2835-is.patch b/target/linux/bcm27xx/patches-5.4/950-0670-media-uapi-v4l-ctrls-Add-CID-base-for-the-bcm2835-is.patch index 96e6e124af..96e6e124af 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0677-media-uapi-v4l-ctrls-Add-CID-base-for-the-bcm2835-is.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0670-media-uapi-v4l-ctrls-Add-CID-base-for-the-bcm2835-is.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0678-staging-mmal-vchiq-Fix-formatting-errors-in-mmal_par.patch b/target/linux/bcm27xx/patches-5.4/950-0671-staging-mmal-vchiq-Fix-formatting-errors-in-mmal_par.patch index f428ce5e9f..f428ce5e9f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0678-staging-mmal-vchiq-Fix-formatting-errors-in-mmal_par.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0671-staging-mmal-vchiq-Fix-formatting-errors-in-mmal_par.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0679-staging-vc04_services-ISP-Add-a-more-complex-ISP-pro.patch b/target/linux/bcm27xx/patches-5.4/950-0672-staging-vc04_services-ISP-Add-a-more-complex-ISP-pro.patch index 38015cc98a..38015cc98a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0679-staging-vc04_services-ISP-Add-a-more-complex-ISP-pro.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0672-staging-vc04_services-ISP-Add-a-more-complex-ISP-pro.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0680-staging-vchiq-Load-bcm2835_isp-driver-from-vchiq.patch b/target/linux/bcm27xx/patches-5.4/950-0673-staging-vchiq-Load-bcm2835_isp-driver-from-vchiq.patch index 70fe392a3b..70fe392a3b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0680-staging-vchiq-Load-bcm2835_isp-driver-from-vchiq.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0673-staging-vchiq-Load-bcm2835_isp-driver-from-vchiq.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0681-vc4_hvs-Mark-core-clock-as-optional.patch b/target/linux/bcm27xx/patches-5.4/950-0674-vc4_hvs-Mark-core-clock-as-optional.patch index 816ca3c589..816ca3c589 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0681-vc4_hvs-Mark-core-clock-as-optional.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0674-vc4_hvs-Mark-core-clock-as-optional.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0682-vc4_hdmi-BCM2835-requires-a-fixed-hsm-clock-for-CEC-.patch b/target/linux/bcm27xx/patches-5.4/950-0675-vc4_hdmi-BCM2835-requires-a-fixed-hsm-clock-for-CEC-.patch index e5ffc3e96f..e5ffc3e96f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0682-vc4_hdmi-BCM2835-requires-a-fixed-hsm-clock-for-CEC-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0675-vc4_hdmi-BCM2835-requires-a-fixed-hsm-clock-for-CEC-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0683-media-i2c-imx219-Implement-get_selection.patch b/target/linux/bcm27xx/patches-5.4/950-0676-media-i2c-imx219-Implement-get_selection.patch index cb7a0af605..cb7a0af605 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0683-media-i2c-imx219-Implement-get_selection.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0676-media-i2c-imx219-Implement-get_selection.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0684-media-i2c-ov5647-Add-support-for-g_selection-to-refl.patch b/target/linux/bcm27xx/patches-5.4/950-0677-media-i2c-ov5647-Add-support-for-g_selection-to-refl.patch index 66715a108e..66715a108e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0684-media-i2c-ov5647-Add-support-for-g_selection-to-refl.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0677-media-i2c-ov5647-Add-support-for-g_selection-to-refl.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0685-media-i2c-ov5467-Fixup-error-path-to-release-mutex.patch b/target/linux/bcm27xx/patches-5.4/950-0678-media-i2c-ov5467-Fixup-error-path-to-release-mutex.patch index d8a0104739..d8a0104739 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0685-media-i2c-ov5467-Fixup-error-path-to-release-mutex.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0678-media-i2c-ov5467-Fixup-error-path-to-release-mutex.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0686-media-i2c-ov5647-Support-V4L2_CID_PIXEL_RATE.patch b/target/linux/bcm27xx/patches-5.4/950-0679-media-i2c-ov5647-Support-V4L2_CID_PIXEL_RATE.patch index ce16832d35..ce16832d35 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0686-media-i2c-ov5647-Support-V4L2_CID_PIXEL_RATE.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0679-media-i2c-ov5647-Support-V4L2_CID_PIXEL_RATE.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0687-media-i2c-ov5647-Set-V4L2_SUBDEV_FL_HAS_EVENTS-flag.patch b/target/linux/bcm27xx/patches-5.4/950-0680-media-i2c-ov5647-Set-V4L2_SUBDEV_FL_HAS_EVENTS-flag.patch index b7a3f19753..b7a3f19753 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0687-media-i2c-ov5647-Set-V4L2_SUBDEV_FL_HAS_EVENTS-flag.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0680-media-i2c-ov5647-Set-V4L2_SUBDEV_FL_HAS_EVENTS-flag.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0688-media-i2c-ov5647-Add-support-for-V4L2_CID_VBLANK.patch b/target/linux/bcm27xx/patches-5.4/950-0681-media-i2c-ov5647-Add-support-for-V4L2_CID_VBLANK.patch index 85d63cf1a3..85d63cf1a3 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0688-media-i2c-ov5647-Add-support-for-V4L2_CID_VBLANK.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0681-media-i2c-ov5647-Add-support-for-V4L2_CID_VBLANK.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0689-media-i2c-ov5647-Neither-analogue-gain-nor-exposure-.patch b/target/linux/bcm27xx/patches-5.4/950-0682-media-i2c-ov5647-Neither-analogue-gain-nor-exposure-.patch index 039809e94e..039809e94e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0689-media-i2c-ov5647-Neither-analogue-gain-nor-exposure-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0682-media-i2c-ov5647-Neither-analogue-gain-nor-exposure-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0690-media-i2c-ov5647-Use-member-names-in-mode-tables.patch b/target/linux/bcm27xx/patches-5.4/950-0683-media-i2c-ov5647-Use-member-names-in-mode-tables.patch index d8ef700a59..d8ef700a59 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0690-media-i2c-ov5647-Use-member-names-in-mode-tables.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0683-media-i2c-ov5647-Use-member-names-in-mode-tables.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0691-media-i2c-ov5647-Advertise-the-correct-exposure-rang.patch b/target/linux/bcm27xx/patches-5.4/950-0684-media-i2c-ov5647-Advertise-the-correct-exposure-rang.patch index 9b874485a8..9b874485a8 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0691-media-i2c-ov5647-Advertise-the-correct-exposure-rang.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0684-media-i2c-ov5647-Advertise-the-correct-exposure-rang.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0692-media-i2c-imx219-Declare-that-the-driver-can-create-.patch b/target/linux/bcm27xx/patches-5.4/950-0685-media-i2c-imx219-Declare-that-the-driver-can-create-.patch index fa700a81a3..fa700a81a3 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0692-media-i2c-imx219-Declare-that-the-driver-can-create-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0685-media-i2c-imx219-Declare-that-the-driver-can-create-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0693-media-bcm2835-unicam-Add-support-for-VIDIOC_-S-G-_SE.patch b/target/linux/bcm27xx/patches-5.4/950-0686-media-bcm2835-unicam-Add-support-for-VIDIOC_-S-G-_SE.patch index b30d106f6e..b30d106f6e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0693-media-bcm2835-unicam-Add-support-for-VIDIOC_-S-G-_SE.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0686-media-bcm2835-unicam-Add-support-for-VIDIOC_-S-G-_SE.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0694-media-bcm2835-unicam-Do-not-stop-streaming-in-unicam.patch b/target/linux/bcm27xx/patches-5.4/950-0687-media-bcm2835-unicam-Do-not-stop-streaming-in-unicam.patch index 74abba4ac9..74abba4ac9 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0694-media-bcm2835-unicam-Do-not-stop-streaming-in-unicam.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0687-media-bcm2835-unicam-Do-not-stop-streaming-in-unicam.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0695-media-bcm2835-unicam-Fix-reference-counting-in-unica.patch b/target/linux/bcm27xx/patches-5.4/950-0688-media-bcm2835-unicam-Fix-reference-counting-in-unica.patch index ba979632ae..ba979632ae 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0695-media-bcm2835-unicam-Fix-reference-counting-in-unica.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0688-media-bcm2835-unicam-Fix-reference-counting-in-unica.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0696-staging-vc04_services-ISP-Add-enum_framesizes-ioctl.patch b/target/linux/bcm27xx/patches-5.4/950-0689-staging-vc04_services-ISP-Add-enum_framesizes-ioctl.patch index 1673bde514..1673bde514 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0696-staging-vc04_services-ISP-Add-enum_framesizes-ioctl.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0689-staging-vc04_services-ISP-Add-enum_framesizes-ioctl.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0697-SQUASH-spi-Demote-SPI_CS_HIGH-warning-to-KERN_DEBUG.patch b/target/linux/bcm27xx/patches-5.4/950-0690-SQUASH-spi-Demote-SPI_CS_HIGH-warning-to-KERN_DEBUG.patch index e4b2e7ed2a..e4b2e7ed2a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0697-SQUASH-spi-Demote-SPI_CS_HIGH-warning-to-KERN_DEBUG.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0690-SQUASH-spi-Demote-SPI_CS_HIGH-warning-to-KERN_DEBUG.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0698-bcm2835-dma-Add-proper-40-bit-DMA-support.patch b/target/linux/bcm27xx/patches-5.4/950-0691-bcm2835-dma-Add-proper-40-bit-DMA-support.patch index 3fb47589ee..3fb47589ee 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0698-bcm2835-dma-Add-proper-40-bit-DMA-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0691-bcm2835-dma-Add-proper-40-bit-DMA-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0699-ARM-dts-bcm2711-Allow-40-bit-DMA-for-SPI.patch b/target/linux/bcm27xx/patches-5.4/950-0692-ARM-dts-bcm2711-Allow-40-bit-DMA-for-SPI.patch index ac6543fe4f..ac6543fe4f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0699-ARM-dts-bcm2711-Allow-40-bit-DMA-for-SPI.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0692-ARM-dts-bcm2711-Allow-40-bit-DMA-for-SPI.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0700-overlays-Make-the-i2c-gpio-overlay-safe-again.patch b/target/linux/bcm27xx/patches-5.4/950-0693-overlays-Make-the-i2c-gpio-overlay-safe-again.patch index 537ca5dc55..537ca5dc55 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0700-overlays-Make-the-i2c-gpio-overlay-safe-again.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0693-overlays-Make-the-i2c-gpio-overlay-safe-again.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0701-staging-vc04_services-isp-Remove-duplicated-initiali.patch b/target/linux/bcm27xx/patches-5.4/950-0694-staging-vc04_services-isp-Remove-duplicated-initiali.patch index d2b0bf1f2f..d2b0bf1f2f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0701-staging-vc04_services-isp-Remove-duplicated-initiali.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0694-staging-vc04_services-isp-Remove-duplicated-initiali.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0702-staging-vc04_services-isp-Make-all-references-to-bcm.patch b/target/linux/bcm27xx/patches-5.4/950-0695-staging-vc04_services-isp-Make-all-references-to-bcm.patch index 97ca47bcd0..97ca47bcd0 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0702-staging-vc04_services-isp-Make-all-references-to-bcm.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0695-staging-vc04_services-isp-Make-all-references-to-bcm.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0704-vc4_hdmi_phy-Fix-typo-in-phy_get_cp_current.patch b/target/linux/bcm27xx/patches-5.4/950-0696-vc4_hdmi_phy-Fix-typo-in-phy_get_cp_current.patch index 45429d506d..45429d506d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0704-vc4_hdmi_phy-Fix-typo-in-phy_get_cp_current.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0696-vc4_hdmi_phy-Fix-typo-in-phy_get_cp_current.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0705-overlays-Make-use-of-intra-overlay-fragments.patch b/target/linux/bcm27xx/patches-5.4/950-0697-overlays-Make-use-of-intra-overlay-fragments.patch index 628bec3f33..628bec3f33 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0705-overlays-Make-use-of-intra-overlay-fragments.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0697-overlays-Make-use-of-intra-overlay-fragments.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0706-media-i2c-tc358743-Fix-fallthrough-warning.patch b/target/linux/bcm27xx/patches-5.4/950-0698-media-i2c-tc358743-Fix-fallthrough-warning.patch index 26c1f95bf2..26c1f95bf2 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0706-media-i2c-tc358743-Fix-fallthrough-warning.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0698-media-i2c-tc358743-Fix-fallthrough-warning.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0707-media-bcm2835-unicam-Fix-uninitialized-warning.patch b/target/linux/bcm27xx/patches-5.4/950-0699-media-bcm2835-unicam-Fix-uninitialized-warning.patch index 2186d7b802..2186d7b802 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0707-media-bcm2835-unicam-Fix-uninitialized-warning.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0699-media-bcm2835-unicam-Fix-uninitialized-warning.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0708-video-bcm2708_fb-Disable-FB-if-no-displays-found.patch b/target/linux/bcm27xx/patches-5.4/950-0700-video-bcm2708_fb-Disable-FB-if-no-displays-found.patch index 90cb5e276e..90cb5e276e 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0708-video-bcm2708_fb-Disable-FB-if-no-displays-found.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0700-video-bcm2708_fb-Disable-FB-if-no-displays-found.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0709-overlays-sc16is752-spi1-Add-xtal-parameter.patch b/target/linux/bcm27xx/patches-5.4/950-0701-overlays-sc16is752-spi1-Add-xtal-parameter.patch index 582c32aa90..582c32aa90 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0709-overlays-sc16is752-spi1-Add-xtal-parameter.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0701-overlays-sc16is752-spi1-Add-xtal-parameter.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0710-vc4_hdmi-Fix-register-offset-when-sending-longer-CEC.patch b/target/linux/bcm27xx/patches-5.4/950-0702-vc4_hdmi-Fix-register-offset-when-sending-longer-CEC.patch index d192565145..d192565145 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0710-vc4_hdmi-Fix-register-offset-when-sending-longer-CEC.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0702-vc4_hdmi-Fix-register-offset-when-sending-longer-CEC.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0703-overlays-gpio-keys-Avoid-open-drain-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-0703-overlays-gpio-keys-Avoid-open-drain-warnings.patch deleted file mode 100644 index 579b3b61b6..0000000000 --- a/target/linux/bcm27xx/patches-5.4/950-0703-overlays-gpio-keys-Avoid-open-drain-warnings.patch +++ /dev/null @@ -1,29 +0,0 @@ -From ae10c15867d9a5b85eefaf11333bd30473af4b2b Mon Sep 17 00:00:00 2001 -From: Phil Elwell <phil@raspberrypi.com> -Date: Sat, 2 May 2020 13:43:06 +0100 -Subject: [PATCH] overlays: gpio-keys: Avoid open-drain warnings - -The i2c-gpio driver expects to use a GPIO in open-drain mode. Failure -to configure it in that way causes alarming warnings in the kernel log. -The BCM283x and BCM2711 GPIO blocks don't support open-drain mode, -but i2c-gpio works anyway. Silence the warning by declaring that -open-drain mode has been enabled by other means. - -See: https://github.com/raspberrypi/firmware/issues/1381 - -Signed-off-by: Phil Elwell <phil@raspberrypi.com> ---- - arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts -@@ -16,6 +16,8 @@ - &gpio 24 0 /* scl */ - >; - i2c-gpio,delay-us = <2>; /* ~100 kHz */ -+ i2c-gpio,sda-open-drain; -+ i2c-gpio,scl-open-drain; - #address-cells = <1>; - #size-cells = <0>; - }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0711-vc4_hdmi-Fix-up-CEC-registers.patch b/target/linux/bcm27xx/patches-5.4/950-0703-vc4_hdmi-Fix-up-CEC-registers.patch index a00aee15bd..a00aee15bd 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0711-vc4_hdmi-Fix-up-CEC-registers.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0703-vc4_hdmi-Fix-up-CEC-registers.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0712-vc4_hdmi_regs-Add-Intr2-register-block.patch b/target/linux/bcm27xx/patches-5.4/950-0704-vc4_hdmi_regs-Add-Intr2-register-block.patch index e3299acf9d..e3299acf9d 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0712-vc4_hdmi_regs-Add-Intr2-register-block.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0704-vc4_hdmi_regs-Add-Intr2-register-block.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0713-vc4_hdmi_regs-Make-interrupt-mask-variant-specific.patch b/target/linux/bcm27xx/patches-5.4/950-0705-vc4_hdmi_regs-Make-interrupt-mask-variant-specific.patch index f2a30c6443..f2a30c6443 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0713-vc4_hdmi_regs-Make-interrupt-mask-variant-specific.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0705-vc4_hdmi_regs-Make-interrupt-mask-variant-specific.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0714-vc4_hdmi-Make-irq-shared.patch b/target/linux/bcm27xx/patches-5.4/950-0706-vc4_hdmi-Make-irq-shared.patch index 423812324b..423812324b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0714-vc4_hdmi-Make-irq-shared.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0706-vc4_hdmi-Make-irq-shared.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0715-vc4_hdmi-Adjust-CEC-ref-clock-based-on-its-input-clo.patch b/target/linux/bcm27xx/patches-5.4/950-0707-vc4_hdmi-Adjust-CEC-ref-clock-based-on-its-input-clo.patch index f6145e4ff5..f6145e4ff5 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0715-vc4_hdmi-Adjust-CEC-ref-clock-based-on-its-input-clo.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0707-vc4_hdmi-Adjust-CEC-ref-clock-based-on-its-input-clo.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0716-vc4_hdmi-Remove-cec_available-flag-as-always-support.patch b/target/linux/bcm27xx/patches-5.4/950-0708-vc4_hdmi-Remove-cec_available-flag-as-always-support.patch index 7713eed5b1..7713eed5b1 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0716-vc4_hdmi-Remove-cec_available-flag-as-always-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0708-vc4_hdmi-Remove-cec_available-flag-as-always-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0717-overlays-tc358743-Use-intra-overlay-fragments.patch b/target/linux/bcm27xx/patches-5.4/950-0709-overlays-tc358743-Use-intra-overlay-fragments.patch index 5bfa6bc60a..5bfa6bc60a 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0717-overlays-tc358743-Use-intra-overlay-fragments.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0709-overlays-tc358743-Use-intra-overlay-fragments.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0718-overlays-Move-fixed-clock-nodes-to-the-root.patch b/target/linux/bcm27xx/patches-5.4/950-0710-overlays-Move-fixed-clock-nodes-to-the-root.patch index aa19ca11d5..aa19ca11d5 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0718-overlays-Move-fixed-clock-nodes-to-the-root.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0710-overlays-Move-fixed-clock-nodes-to-the-root.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0719-raspberrypi-dts-Switch-to-discrete-ALSA-devices.patch b/target/linux/bcm27xx/patches-5.4/950-0711-raspberrypi-dts-Switch-to-discrete-ALSA-devices.patch index c5c302f832..c5c302f832 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0719-raspberrypi-dts-Switch-to-discrete-ALSA-devices.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0711-raspberrypi-dts-Switch-to-discrete-ALSA-devices.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0720-dt-bindings-media-i2c-Add-IMX477-CMOS-sensor-binding.patch b/target/linux/bcm27xx/patches-5.4/950-0712-dt-bindings-media-i2c-Add-IMX477-CMOS-sensor-binding.patch index eb5430bbae..eb5430bbae 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0720-dt-bindings-media-i2c-Add-IMX477-CMOS-sensor-binding.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0712-dt-bindings-media-i2c-Add-IMX477-CMOS-sensor-binding.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0721-dtoverlays-Add-IMX477-sensor-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0713-dtoverlays-Add-IMX477-sensor-overlay.patch index 0d5ea3c188..0d5ea3c188 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0721-dtoverlays-Add-IMX477-sensor-overlay.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0713-dtoverlays-Add-IMX477-sensor-overlay.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0722-media-i2c-Add-driver-for-Sony-IMX477-sensor.patch b/target/linux/bcm27xx/patches-5.4/950-0714-media-i2c-Add-driver-for-Sony-IMX477-sensor.patch index f3e2052bfd..f3e2052bfd 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0722-media-i2c-Add-driver-for-Sony-IMX477-sensor.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0714-media-i2c-Add-driver-for-Sony-IMX477-sensor.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0723-media-i2c-imx477-Add-support-for-adaptive-frame-cont.patch b/target/linux/bcm27xx/patches-5.4/950-0715-media-i2c-imx477-Add-support-for-adaptive-frame-cont.patch index 1da5dea326..1da5dea326 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0723-media-i2c-imx477-Add-support-for-adaptive-frame-cont.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0715-media-i2c-imx477-Add-support-for-adaptive-frame-cont.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0724-udmabuf-Remove-deleted-map-unmap-handlers.patch b/target/linux/bcm27xx/patches-5.4/950-0716-udmabuf-Remove-deleted-map-unmap-handlers.patch index bc7b5bea91..bc7b5bea91 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0724-udmabuf-Remove-deleted-map-unmap-handlers.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0716-udmabuf-Remove-deleted-map-unmap-handlers.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0725-udmabuf-use-cache_sgt_mapping-option.patch b/target/linux/bcm27xx/patches-5.4/950-0717-udmabuf-use-cache_sgt_mapping-option.patch index 166055556f..166055556f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0725-udmabuf-use-cache_sgt_mapping-option.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0717-udmabuf-use-cache_sgt_mapping-option.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0726-udmabuf-add-a-pointer-to-the-miscdevice-in-dma-buf-p.patch b/target/linux/bcm27xx/patches-5.4/950-0718-udmabuf-add-a-pointer-to-the-miscdevice-in-dma-buf-p.patch index 68feae3d48..68feae3d48 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0726-udmabuf-add-a-pointer-to-the-miscdevice-in-dma-buf-p.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0718-udmabuf-add-a-pointer-to-the-miscdevice-in-dma-buf-p.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0727-udmabuf-separate-out-creating-destroying-scatter-tab.patch b/target/linux/bcm27xx/patches-5.4/950-0719-udmabuf-separate-out-creating-destroying-scatter-tab.patch index 5a0a59ced1..5a0a59ced1 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0727-udmabuf-separate-out-creating-destroying-scatter-tab.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0719-udmabuf-separate-out-creating-destroying-scatter-tab.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0728-udmabuf-implement-begin_cpu_access-end_cpu_access-ho.patch b/target/linux/bcm27xx/patches-5.4/950-0720-udmabuf-implement-begin_cpu_access-end_cpu_access-ho.patch index 79f6a67387..79f6a67387 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0728-udmabuf-implement-begin_cpu_access-end_cpu_access-ho.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0720-udmabuf-implement-begin_cpu_access-end_cpu_access-ho.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0729-udmabuf-fix-dma-buf-cpu-access.patch b/target/linux/bcm27xx/patches-5.4/950-0721-udmabuf-fix-dma-buf-cpu-access.patch index 14cfe8aed3..14cfe8aed3 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0729-udmabuf-fix-dma-buf-cpu-access.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0721-udmabuf-fix-dma-buf-cpu-access.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0730-dma-buf-Add-dma-buf-heaps-framework.patch b/target/linux/bcm27xx/patches-5.4/950-0722-dma-buf-Add-dma-buf-heaps-framework.patch index f60d402379..f60d402379 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0730-dma-buf-Add-dma-buf-heaps-framework.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0722-dma-buf-Add-dma-buf-heaps-framework.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0731-dma-buf-heaps-Add-heap-helpers.patch b/target/linux/bcm27xx/patches-5.4/950-0723-dma-buf-heaps-Add-heap-helpers.patch index 10eb46ca7b..10eb46ca7b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0731-dma-buf-heaps-Add-heap-helpers.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0723-dma-buf-heaps-Add-heap-helpers.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0732-dma-buf-heaps-Add-system-heap-to-dmabuf-heaps.patch b/target/linux/bcm27xx/patches-5.4/950-0724-dma-buf-heaps-Add-system-heap-to-dmabuf-heaps.patch index 55c2450821..55c2450821 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0732-dma-buf-heaps-Add-system-heap-to-dmabuf-heaps.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0724-dma-buf-heaps-Add-system-heap-to-dmabuf-heaps.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0733-dma-buf-heaps-Add-CMA-heap-to-dmabuf-heaps.patch b/target/linux/bcm27xx/patches-5.4/950-0725-dma-buf-heaps-Add-CMA-heap-to-dmabuf-heaps.patch index d1828702b4..d1828702b4 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0733-dma-buf-heaps-Add-CMA-heap-to-dmabuf-heaps.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0725-dma-buf-heaps-Add-CMA-heap-to-dmabuf-heaps.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0734-kselftests-Add-dma-heap-test.patch b/target/linux/bcm27xx/patches-5.4/950-0726-kselftests-Add-dma-heap-test.patch index ff4dda9a63..ff4dda9a63 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0734-kselftests-Add-dma-heap-test.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0726-kselftests-Add-dma-heap-test.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0735-dma-buf-heaps-Use-_IOCTL_-for-userspace-IOCTL-identi.patch b/target/linux/bcm27xx/patches-5.4/950-0727-dma-buf-heaps-Use-_IOCTL_-for-userspace-IOCTL-identi.patch index a949831525..a949831525 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0735-dma-buf-heaps-Use-_IOCTL_-for-userspace-IOCTL-identi.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0727-dma-buf-heaps-Use-_IOCTL_-for-userspace-IOCTL-identi.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0736-dma-buf-heaps-Remove-redundant-heap-identifier-from-.patch b/target/linux/bcm27xx/patches-5.4/950-0728-dma-buf-heaps-Remove-redundant-heap-identifier-from-.patch index 288f468a78..288f468a78 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0736-dma-buf-heaps-Remove-redundant-heap-identifier-from-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0728-dma-buf-heaps-Remove-redundant-heap-identifier-from-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0737-dma-buf-fix-resource-leak-on-ENOTTY-error-return-pat.patch b/target/linux/bcm27xx/patches-5.4/950-0729-dma-buf-fix-resource-leak-on-ENOTTY-error-return-pat.patch index 89b66956e0..89b66956e0 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0737-dma-buf-fix-resource-leak-on-ENOTTY-error-return-pat.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0729-dma-buf-fix-resource-leak-on-ENOTTY-error-return-pat.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0738-dma-heap-Make-the-symbol-dma_heap_ioctl_cmds-static.patch b/target/linux/bcm27xx/patches-5.4/950-0730-dma-heap-Make-the-symbol-dma_heap_ioctl_cmds-static.patch index 900637ddeb..900637ddeb 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0738-dma-heap-Make-the-symbol-dma_heap_ioctl_cmds-static.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0730-dma-heap-Make-the-symbol-dma_heap_ioctl_cmds-static.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0739-ARM-dts-Enable-firmware-clocks-on-all-Pis.patch b/target/linux/bcm27xx/patches-5.4/950-0731-ARM-dts-Enable-firmware-clocks-on-all-Pis.patch index f319bdca9f..f319bdca9f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0739-ARM-dts-Enable-firmware-clocks-on-all-Pis.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0731-ARM-dts-Enable-firmware-clocks-on-all-Pis.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0740-media-bcm2835-unicam-Always-service-interrupts.patch b/target/linux/bcm27xx/patches-5.4/950-0732-media-bcm2835-unicam-Always-service-interrupts.patch index 378824c495..378824c495 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0740-media-bcm2835-unicam-Always-service-interrupts.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0732-media-bcm2835-unicam-Always-service-interrupts.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0741-sc16is7xx-Fix-for-hardware-flow-control.patch b/target/linux/bcm27xx/patches-5.4/950-0733-sc16is7xx-Fix-for-hardware-flow-control.patch index 3ff77bcea9..3ff77bcea9 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0741-sc16is7xx-Fix-for-hardware-flow-control.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0733-sc16is7xx-Fix-for-hardware-flow-control.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0742-drm-vc4-Fix-VIC-usage-with-Broadcast-RGB.patch b/target/linux/bcm27xx/patches-5.4/950-0734-drm-vc4-Fix-VIC-usage-with-Broadcast-RGB.patch index 611e5db743..611e5db743 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0742-drm-vc4-Fix-VIC-usage-with-Broadcast-RGB.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0734-drm-vc4-Fix-VIC-usage-with-Broadcast-RGB.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0743-staging-vc04_services-mmal-vchiq-Update-parameters-l.patch b/target/linux/bcm27xx/patches-5.4/950-0735-staging-vc04_services-mmal-vchiq-Update-parameters-l.patch index fd878ef737..fd878ef737 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0743-staging-vc04_services-mmal-vchiq-Update-parameters-l.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0735-staging-vc04_services-mmal-vchiq-Update-parameters-l.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0744-staging-vc04_services-bcm2835-codec-Request-headers-.patch b/target/linux/bcm27xx/patches-5.4/950-0736-staging-vc04_services-bcm2835-codec-Request-headers-.patch index 7698f822d3..7698f822d3 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0744-staging-vc04_services-bcm2835-codec-Request-headers-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0736-staging-vc04_services-bcm2835-codec-Request-headers-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0745-staging-vc04_services-bcm2835-codec-Avoid-fragmentin.patch b/target/linux/bcm27xx/patches-5.4/950-0737-staging-vc04_services-bcm2835-codec-Avoid-fragmentin.patch index da273ca65b..da273ca65b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0745-staging-vc04_services-bcm2835-codec-Avoid-fragmentin.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0737-staging-vc04_services-bcm2835-codec-Avoid-fragmentin.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0746-staging-vc04_services-bcm2835-camera-Request-headers.patch b/target/linux/bcm27xx/patches-5.4/950-0738-staging-vc04_services-bcm2835-camera-Request-headers.patch index 5d400e2530..5d400e2530 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0746-staging-vc04_services-bcm2835-camera-Request-headers.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0738-staging-vc04_services-bcm2835-camera-Request-headers.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0747-overlays-Fix-audio-parameter-of-vc4-kms-v3d.patch b/target/linux/bcm27xx/patches-5.4/950-0739-overlays-Fix-audio-parameter-of-vc4-kms-v3d.patch index 4e69e41710..4e69e41710 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0747-overlays-Fix-audio-parameter-of-vc4-kms-v3d.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0739-overlays-Fix-audio-parameter-of-vc4-kms-v3d.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0748-Switch-to-snd_soc_dai_set_bclk_ratio.patch b/target/linux/bcm27xx/patches-5.4/950-0740-Switch-to-snd_soc_dai_set_bclk_ratio.patch index b104f00efc..b104f00efc 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0748-Switch-to-snd_soc_dai_set_bclk_ratio.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0740-Switch-to-snd_soc_dai_set_bclk_ratio.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0749-media-bcm2835-unicam-Retain-packing-information-on-G.patch b/target/linux/bcm27xx/patches-5.4/950-0741-media-bcm2835-unicam-Retain-packing-information-on-G.patch index 1e0051be30..1e0051be30 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0749-media-bcm2835-unicam-Retain-packing-information-on-G.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0741-media-bcm2835-unicam-Retain-packing-information-on-G.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0750-zswap-Defer-zswap-initialisation.patch b/target/linux/bcm27xx/patches-5.4/950-0742-zswap-Defer-zswap-initialisation.patch index 124a1d95cd..124a1d95cd 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0750-zswap-Defer-zswap-initialisation.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0742-zswap-Defer-zswap-initialisation.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0751-drm-vc4-Adopt-the-dma-configuration-from-the-HVS-or-.patch b/target/linux/bcm27xx/patches-5.4/950-0743-drm-vc4-Adopt-the-dma-configuration-from-the-HVS-or-.patch index 2c9449df0f..2c9449df0f 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0751-drm-vc4-Adopt-the-dma-configuration-from-the-HVS-or-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0743-drm-vc4-Adopt-the-dma-configuration-from-the-HVS-or-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0752-drm-vc4-Add-FKMS-as-an-acceptable-node-for-dma-range.patch b/target/linux/bcm27xx/patches-5.4/950-0744-drm-vc4-Add-FKMS-as-an-acceptable-node-for-dma-range.patch index 127c5aef11..127c5aef11 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0752-drm-vc4-Add-FKMS-as-an-acceptable-node-for-dma-range.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0744-drm-vc4-Add-FKMS-as-an-acceptable-node-for-dma-range.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0753-media-i2c-imx477-Return-correct-result-on-sensor-id-.patch b/target/linux/bcm27xx/patches-5.4/950-0745-media-i2c-imx477-Return-correct-result-on-sensor-id-.patch index 4585d2d8dd..4585d2d8dd 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0753-media-i2c-imx477-Return-correct-result-on-sensor-id-.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0745-media-i2c-imx477-Return-correct-result-on-sensor-id-.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0754-staging-vchiq_arm-Clean-up-40-bit-DMA-support.patch b/target/linux/bcm27xx/patches-5.4/950-0746-staging-vchiq_arm-Clean-up-40-bit-DMA-support.patch index 1dac504877..1dac504877 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0754-staging-vchiq_arm-Clean-up-40-bit-DMA-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0746-staging-vchiq_arm-Clean-up-40-bit-DMA-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0755-ARM-dts-Update-for-new-VCHIQ-BCM2711-DMA-support.patch b/target/linux/bcm27xx/patches-5.4/950-0747-ARM-dts-Update-for-new-VCHIQ-BCM2711-DMA-support.patch index 947fb73a39..947fb73a39 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0755-ARM-dts-Update-for-new-VCHIQ-BCM2711-DMA-support.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0747-ARM-dts-Update-for-new-VCHIQ-BCM2711-DMA-support.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0756-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch b/target/linux/bcm27xx/patches-5.4/950-0748-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch index 6f14ffc02c..6f14ffc02c 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0756-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0748-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0757-dt-bindings-Add-Broadcom-AVS-RO-thermal.patch b/target/linux/bcm27xx/patches-5.4/950-0749-dt-bindings-Add-Broadcom-AVS-RO-thermal.patch index bf41ba748b..bf41ba748b 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0757-dt-bindings-Add-Broadcom-AVS-RO-thermal.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0749-dt-bindings-Add-Broadcom-AVS-RO-thermal.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0758-thermal-Add-BCM2711-thermal-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0750-thermal-Add-BCM2711-thermal-driver.patch index d7e438fd72..d7e438fd72 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0758-thermal-Add-BCM2711-thermal-driver.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0750-thermal-Add-BCM2711-thermal-driver.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0759-ARM-dts-bcm2711-Enable-thermal.patch b/target/linux/bcm27xx/patches-5.4/950-0751-ARM-dts-bcm2711-Enable-thermal.patch index 33289324bb..33289324bb 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0759-ARM-dts-bcm2711-Enable-thermal.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0751-ARM-dts-bcm2711-Enable-thermal.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0760-ARM-dts-bcm2711-rpi-Remove-downstream-thermal-sensor.patch b/target/linux/bcm27xx/patches-5.4/950-0752-ARM-dts-bcm2711-rpi-Remove-downstream-thermal-sensor.patch index 1d885635d6..1d885635d6 100644 --- a/target/linux/bcm27xx/patches-5.4/950-0760-ARM-dts-bcm2711-rpi-Remove-downstream-thermal-sensor.patch +++ b/target/linux/bcm27xx/patches-5.4/950-0752-ARM-dts-bcm2711-rpi-Remove-downstream-thermal-sensor.patch diff --git a/target/linux/bcm27xx/patches-5.4/950-0753-overlays-i2c-rtc-Fix-trickle-resistor-ohms-param.patch b/target/linux/bcm27xx/patches-5.4/950-0753-overlays-i2c-rtc-Fix-trickle-resistor-ohms-param.patch new file mode 100644 index 0000000000..a702ef7137 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0753-overlays-i2c-rtc-Fix-trickle-resistor-ohms-param.patch @@ -0,0 +1,26 @@ +From 7871e3600c1190c6cf7968e280bd2fd1ec8bbff2 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Fri, 29 May 2020 14:41:13 +0100 +Subject: [PATCH] overlays: i2c-rtc: Fix trickle-resistor-ohms param + +The abx80x implementation of the trickle-resistor-ohms parameter is +missing the ":0" indicating that the target is an integer/cell value. + +See: https://github.com/raspberrypi/linux/issues/3642 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts +@@ -229,7 +229,7 @@ + <&m41t62>, "reg:0"; + trickle-diode-type = <&abx80x>,"abracon,tc-diode"; + trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0", +- <&abx80x>,"abracon,tc-resistor", ++ <&abx80x>,"abracon,tc-resistor:0", + <&rv3028>,"trickle-resistor-ohms:0"; + backup-switchover-mode = <&rv3028>,"backup-switchover-mode:0"; + wakeup-source = <&ds1339>,"wakeup-source?", diff --git a/target/linux/bcm27xx/patches-5.4/950-0754-overlays-gpio-shutdown-Add-information-for-SysV-init.patch b/target/linux/bcm27xx/patches-5.4/950-0754-overlays-gpio-shutdown-Add-information-for-SysV-init.patch new file mode 100644 index 0000000000..ca0fd4942b --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0754-overlays-gpio-shutdown-Add-information-for-SysV-init.patch @@ -0,0 +1,51 @@ +From 047041db91fabcb768c3e5680645b69fa9528e86 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Thu, 30 Apr 2020 19:40:07 +0200 +Subject: [PATCH] overlays: gpio-shutdown: Add information for SysV + init / inittab + +KeyboardSignal and kb::kbrequest can be used to call /sbin/shutdown +--- + arch/arm/boot/dts/overlays/README | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -847,6 +847,7 @@ Params: gpiopin GPIO for + Name: gpio-shutdown + Info: Initiates a shutdown when GPIO pin changes. The given GPIO pin + is configured as an input key that generates KEY_POWER events. ++ + This event is handled by systemd-logind by initiating a + shutdown. Systemd versions older than 225 need an udev rule + enable listening to the input device: +@@ -855,6 +856,29 @@ Info: Initiates a shutdown when GPIO p + SUBSYSTEMS=="platform", DRIVERS=="gpio-keys", \ + ATTRS{keys}=="116", TAG+="power-switch" + ++ Alternatively this event can be handled also on systems without ++ systemd, just by traditional SysV init daemon. KEY_POWER event ++ (keycode 116) needs to be mapped to KeyboardSignal on console ++ and then kb::kbrequest inittab action which is triggered by ++ KeyboardSignal from console can be configured to issue system ++ shutdown. Steps for this configuration are: ++ ++ Add following lines to the /etc/console-setup/remap.inc file: ++ ++ # Key Power as special keypress ++ keycode 116 = KeyboardSignal ++ ++ Then add following lines to /etc/inittab file: ++ ++ # Action on special keypress (Key Power) ++ kb::kbrequest:/sbin/shutdown -t1 -a -h -P now ++ ++ And finally reload configuration by calling following commands: ++ ++ # dpkg-reconfigure console-setup ++ # service console-setup reload ++ # init q ++ + This overlay only handles shutdown. After shutdown, the system + can be powered up again by driving GPIO3 low. The default + configuration uses GPIO3 with a pullup, so if you connect a diff --git a/target/linux/bcm27xx/patches-5.4/950-0755-overlays-gpio-shutdown-Add-information-for-Raspberry.patch b/target/linux/bcm27xx/patches-5.4/950-0755-overlays-gpio-shutdown-Add-information-for-Raspberry.patch new file mode 100644 index 0000000000..5bb6ee23ab --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0755-overlays-gpio-shutdown-Add-information-for-Raspberry.patch @@ -0,0 +1,62 @@ +From 5f9fcc99c517a517e8d74ce001fc5bc2648f0e59 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Thu, 30 Apr 2020 19:41:10 +0200 +Subject: [PATCH] overlays: gpio-shutdown: Add information for + Raspberry Pi 1 Model B rev 1 + +Raspberry Pi 1 Model B rev 1 uses GPIO1 for power-up instead of GPIO3. +--- + arch/arm/boot/dts/overlays/README | 10 ++++++++-- + arch/arm/boot/dts/overlays/gpio-shutdown-overlay.dts | 6 ++++-- + 2 files changed, 12 insertions(+), 4 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -883,9 +883,14 @@ Info: Initiates a shutdown when GPIO p + can be powered up again by driving GPIO3 low. The default + configuration uses GPIO3 with a pullup, so if you connect a + button between GPIO3 and GND (pin 5 and 6 on the 40-pin header), +- you get a shutdown and power-up button. ++ you get a shutdown and power-up button. Please note that ++ Raspberry Pi 1 Model B rev 1 uses GPIO1 instead of GPIO3. + Load: dtoverlay=gpio-shutdown,<param>=<val> + Params: gpio_pin GPIO pin to trigger on (default 3) ++ For Raspberry Pi 1 Model B rev 1 set this ++ explicitly to value 1, e.g.: ++ ++ dtoverlay=gpio-shutdown,gpio_pin=1 + + active_low When this is 1 (active low), a falling + edge generates a key down event and a +@@ -897,7 +902,8 @@ Params: gpio_pin GPIO pin + Default is "up". + + Note that the default pin (GPIO3) has an +- external pullup. ++ external pullup. Same applies for GPIO1 ++ on Raspberry Pi 1 Model B rev 1. + + debounce Specify the debounce interval in milliseconds + (default 100) +--- a/arch/arm/boot/dts/overlays/gpio-shutdown-overlay.dts ++++ b/arch/arm/boot/dts/overlays/gpio-shutdown-overlay.dts +@@ -4,7 +4,9 @@ + + // This overlay sets up an input device that generates KEY_POWER events + // when a given GPIO pin changes. It defaults to using GPIO3, which can +-// also be used to wake up (start) the Rpi again after shutdown. Since ++// also be used to wake up (start) the Rpi again after shutdown. ++// Raspberry Pi 1 Model B rev 1 can be wake up only by GPIO1 pin, so for ++// these boards change default GPIO pin to 1 via gpio_pin parameter. Since + // wakeup is active-low, this defaults to active-low with a pullup + // enabled, but all of this can be changed using overlay parameters (but + // note that GPIO3 has an external pullup on at least some boards). +@@ -71,7 +73,7 @@ + + // Allow changing the internal pullup/down state. 0 = none, 1 = pulldown, 2 = pullup + // Note that GPIO3 and GPIO2 are the I2c pins and have an external pullup (at least +- // on some boards). ++ // on some boards). Same applies for GPIO1 on Raspberry Pi 1 Model B rev 1. + gpio_pull = <&pin_state>,"brcm,pull:0"; + + // Allow setting the active_low flag. 0 = active high, 1 = active low diff --git a/target/linux/bcm27xx/patches-5.4/950-0756-overlays-Add-spi0-overlay-to-support-sc16is752.patch b/target/linux/bcm27xx/patches-5.4/950-0756-overlays-Add-spi0-overlay-to-support-sc16is752.patch new file mode 100644 index 0000000000..afd760b8f3 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0756-overlays-Add-spi0-overlay-to-support-sc16is752.patch @@ -0,0 +1,87 @@ +From b2998ffa15aabea3292159ca20973f45ed9cb4b0 Mon Sep 17 00:00:00 2001 +From: bjorn <beikeland@gmail.com> +Date: Thu, 7 May 2020 05:11:43 +0200 +Subject: [PATCH] overlays: Add spi0 overlay to support sc16is752 + +Signed-off-by: Bjorn <beikeland@gmail.com> +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 8 ++++ + .../dts/overlays/sc16is752-spi0-overlay.dts | 44 +++++++++++++++++++ + 3 files changed, 53 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/sc16is752-spi0-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -143,6 +143,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + rra-digidac1-wm8741-audio.dtbo \ + sc16is750-i2c.dtbo \ + sc16is752-i2c.dtbo \ ++ sc16is752-spi0.dtbo \ + sc16is752-spi1.dtbo \ + sdhost.dtbo \ + sdio.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -2144,6 +2144,14 @@ Params: int_pin GPIO use + xtal On-board crystal frequency (default 14745600) + + ++Name: sc16is752-spi0 ++Info: Overlay for the NXP SC16IS752 Dual UART with SPI Interface ++ Enables the chip on SPI0. ++Load: dtoverlay=sc16is752-spi0,<param>=<val> ++Params: int_pin GPIO used for IRQ (default 24) ++ xtal On-board crystal frequency (default 14745600) ++ ++ + Name: sc16is752-spi1 + Info: Overlay for the NXP SC16IS752 Dual UART with SPI Interface + Enables the chip on SPI1. +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/sc16is752-spi0-overlay.dts +@@ -0,0 +1,44 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ sc16is752: sc16is752@0 { ++ compatible = "nxp,sc16is752"; ++ reg = <0>; /* CE0 */ ++ clocks = <&sc16is752_clk>; ++ interrupt-parent = <&gpio>; ++ interrupts = <24 2>; /* IRQ_TYPE_EDGE_FALLING */ ++ #gpio-controller; ++ #gpio-cells = <2>; ++ spi-max-frequency = <4000000>; ++ ++ sc16is752_clk: sc16is752_clk { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <14745600>; ++ }; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ __overrides__ { ++ int_pin = <&sc16is752>,"interrupts:0"; ++ xtal = <&sc16is752_clk>, "clock-frequency:0"; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-5.4/950-0757-overlays-i2c-rtc-gpio-Fix-trickle-resistor-ohms-para.patch b/target/linux/bcm27xx/patches-5.4/950-0757-overlays-i2c-rtc-gpio-Fix-trickle-resistor-ohms-para.patch new file mode 100644 index 0000000000..6b81afb7c1 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0757-overlays-i2c-rtc-gpio-Fix-trickle-resistor-ohms-para.patch @@ -0,0 +1,27 @@ +From 00771f36d14f8446ad155ba6fde1f3f608e26642 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Fri, 29 May 2020 16:55:12 +0100 +Subject: [PATCH] overlays: i2c-rtc-gpio: Fix trickle-resistor-ohms + param + +The abx80x implementation of the trickle-resistor-ohms parameter is +missing the ":0" indicating that the target is an integer/cell value. + +See: https://github.com/raspberrypi/linux/issues/3642 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts +@@ -230,7 +230,7 @@ + + trickle-diode-type = <&abx80x>,"abracon,tc-diode"; + trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0", +- <&abx80x>,"abracon,tc-resistor", ++ <&abx80x>,"abracon,tc-resistor:0", + <&rv3028>,"trickle-resistor-ohms:0"; + backup-switchover-mode = <&rv3028>,"backup-switchover-mode:0"; + wakeup-source = <&ds1339>,"wakeup-source?", diff --git a/target/linux/bcm27xx/patches-5.4/950-0758-media-bcm2835-isp-fix-bytes-per-line-calculations-fo.patch b/target/linux/bcm27xx/patches-5.4/950-0758-media-bcm2835-isp-fix-bytes-per-line-calculations-fo.patch new file mode 100644 index 0000000000..7f4943f9ab --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0758-media-bcm2835-isp-fix-bytes-per-line-calculations-fo.patch @@ -0,0 +1,80 @@ +From 5b07adb57e04530dc571c2a4a1aeea4b7bc57723 Mon Sep 17 00:00:00 2001 +From: David Plowman <david.plowman@raspberrypi.com> +Date: Fri, 29 May 2020 14:36:56 +0100 +Subject: [PATCH] media: bcm2835-isp: fix bytes per line calculations + for some image formats + +The bytes per line numbers calculated by get_bytesperline was not +matching the equivalent calculation being performed by the VideoCore +(mostly by the calculate_pitch function there), resulting in failures +to set the image format with some image width values. This patches up +the RGB24 and YUYV type formats to match the VideoCore calculation. + +Signed-off-by: David Plowman <david.plowman@raspberrypi.com> +--- + .../vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c | 6 +++++- + .../vc04_services/bcm2835-isp/bcm2835_isp_fmts.h | 10 +++++----- + 2 files changed, 10 insertions(+), 6 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c ++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c +@@ -676,7 +676,11 @@ struct bcm2835_isp_fmt *get_default_form + static inline unsigned int get_bytesperline(int width, + const struct bcm2835_isp_fmt *fmt) + { +- return ALIGN((width * fmt->depth) >> 3, fmt->bytesperline_align); ++ /* GPU aligns 24bpp images to a multiple of 32 pixels (not bytes). */ ++ if (fmt->depth == 24) ++ return ALIGN(width, 32) * 3; ++ else ++ return ALIGN((width * fmt->depth) >> 3, fmt->bytesperline_align); + } + + static inline unsigned int get_sizeimage(int bpl, int width, int height, +--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_fmts.h ++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_fmts.h +@@ -71,7 +71,7 @@ static const struct bcm2835_isp_fmt supp + }, { + .fourcc = V4L2_PIX_FMT_YUYV, + .depth = 16, +- .bytesperline_align = 32, ++ .bytesperline_align = 64, + .flags = 0, + .mmal_fmt = MMAL_ENCODING_YUYV, + .size_multiplier_x2 = 2, +@@ -80,7 +80,7 @@ static const struct bcm2835_isp_fmt supp + }, { + .fourcc = V4L2_PIX_FMT_UYVY, + .depth = 16, +- .bytesperline_align = 32, ++ .bytesperline_align = 64, + .flags = 0, + .mmal_fmt = MMAL_ENCODING_UYVY, + .size_multiplier_x2 = 2, +@@ -89,7 +89,7 @@ static const struct bcm2835_isp_fmt supp + }, { + .fourcc = V4L2_PIX_FMT_YVYU, + .depth = 16, +- .bytesperline_align = 32, ++ .bytesperline_align = 64, + .flags = 0, + .mmal_fmt = MMAL_ENCODING_YVYU, + .size_multiplier_x2 = 2, +@@ -98,7 +98,7 @@ static const struct bcm2835_isp_fmt supp + }, { + .fourcc = V4L2_PIX_FMT_VYUY, + .depth = 16, +- .bytesperline_align = 32, ++ .bytesperline_align = 64, + .flags = 0, + .mmal_fmt = MMAL_ENCODING_VYUY, + .size_multiplier_x2 = 2, +@@ -135,7 +135,7 @@ static const struct bcm2835_isp_fmt supp + }, { + .fourcc = V4L2_PIX_FMT_ABGR32, + .depth = 32, +- .bytesperline_align = 32, ++ .bytesperline_align = 64, + .flags = 0, + .mmal_fmt = MMAL_ENCODING_BGRA, + .size_multiplier_x2 = 2, diff --git a/target/linux/bcm27xx/patches-5.4/950-0759-Add-Micro-Crystal-RV-1805-to-i2c-rtc-overlays.patch b/target/linux/bcm27xx/patches-5.4/950-0759-Add-Micro-Crystal-RV-1805-to-i2c-rtc-overlays.patch new file mode 100644 index 0000000000..6e9951bd4a --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0759-Add-Micro-Crystal-RV-1805-to-i2c-rtc-overlays.patch @@ -0,0 +1,167 @@ +From 8c16d549cd0b9e9cf890ac3ead5d58d92590140f Mon Sep 17 00:00:00 2001 +From: "Kevin P. Fleming" <kevin+linux@km6g.us> +Date: Mon, 1 Jun 2020 07:02:00 -0400 +Subject: [PATCH] Add Micro Crystal RV-1805 to i2c-rtc overlays + +While the RV-1805 is supported by the rtc-abx80x driver via +auto-detection, in order for it to be initialized properly +it must be explcitly selected. + +Signed-off-by: Kevin P. Fleming <kevin+linux@km6g.us> +--- + arch/arm/boot/dts/overlays/README | 12 +++++--- + .../dts/overlays/i2c-rtc-gpio-overlay.dts | 28 ++++++++++++++++--- + .../arm/boot/dts/overlays/i2c-rtc-overlay.dts | 27 ++++++++++++++++-- + 3 files changed, 56 insertions(+), 11 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1196,6 +1196,8 @@ Params: abx80x Select o + + pcf8563 Select the PCF8563 device + ++ rv1805 Select the Micro Crystal RV1805 device ++ + rv3028 Select the Micro Crystal RV3028 device + + addr Sets the address for the RTC. Note that the +@@ -1203,10 +1205,10 @@ Params: abx80x Select o + address. + + trickle-diode-type Diode type for trickle charge - "standard" or +- "schottky" (ABx80x only) ++ "schottky" (ABx80x and RV1805 only) + + trickle-resistor-ohms Resistor value for trickle charge (DS1339, +- ABx80x, RV3028) ++ ABx80x, RV1805, RV3028) + + wakeup-source Specify that the RTC can be used as a wakeup + source +@@ -1243,6 +1245,8 @@ Params: abx80x Select o + + pcf8563 Select the PCF8563 device + ++ rv1805 Select the Micro Crystal RV1805 device ++ + rv3028 Select the Micro Crystal RV3028 device + + addr Sets the address for the RTC. Note that the +@@ -1250,10 +1254,10 @@ Params: abx80x Select o + address. + + trickle-diode-type Diode type for trickle charge - "standard" or +- "schottky" (ABx80x only) ++ "schottky" (ABx80x and RV1805 only) + + trickle-resistor-ohms Resistor value for trickle charge (DS1339, +- ABx80x, RV3028) ++ ABx80x, RV1805, RV3028) + + wakeup-source Specify that the RTC can be used as a wakeup + source +--- a/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts +@@ -204,6 +204,23 @@ + }; + }; + ++ fragment@13 { ++ target = <&i2c_gpio>; ++ __dormant__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ rv1805: rv1805@69 { ++ compatible = "microcrystal,rv1805"; ++ reg = <0x69>; ++ abracon,tc-diode = "standard"; ++ abracon,tc-resistor = <0>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ + __overrides__ { + abx80x = <0>,"+1"; + ds1307 = <0>,"+2"; +@@ -217,6 +234,7 @@ + m41t62 = <0>,"+10"; + rv3028 = <0>,"+11"; + pcf2129 = <0>,"+12"; ++ rv1805 = <0>,"+13"; + + addr = <&abx80x>, "reg:0", + <&ds1307>, "reg:0", +@@ -226,12 +244,14 @@ + <&mcp7941x>, "reg:0", + <&pcf8523>, "reg:0", + <&pcf8563>, "reg:0", +- <&m41t62>, "reg:0"; +- +- trickle-diode-type = <&abx80x>,"abracon,tc-diode"; ++ <&m41t62>, "reg:0", ++ <&rv1805>, "reg:0"; ++ trickle-diode-type = <&abx80x>,"abracon,tc-diode", ++ <&rv1805>,"abracon,tc-diode"; + trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0", + <&abx80x>,"abracon,tc-resistor:0", +- <&rv3028>,"trickle-resistor-ohms:0"; ++ <&rv3028>,"trickle-resistor-ohms:0", ++ <&rv1805>,"abracon,tc-resistor:0"; + backup-switchover-mode = <&rv3028>,"backup-switchover-mode:0"; + wakeup-source = <&ds1339>,"wakeup-source?", + <&ds3231>,"wakeup-source?", +--- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts +@@ -203,6 +203,23 @@ + }; + }; + ++ fragment@13 { ++ target = <&i2c_arm>; ++ __dormant__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ rv1805: rv1805@69 { ++ compatible = "microcrystal,rv1805"; ++ reg = <0x69>; ++ abracon,tc-diode = "standard"; ++ abracon,tc-resistor = <0>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ + __overrides__ { + abx80x = <0>,"+0"; + ds1307 = <0>,"+1"; +@@ -217,6 +234,7 @@ + rv3028 = <0>,"+10"; + pcf2129 = <0>,"+11"; + pcf85363 = <0>,"+12"; ++ rv1805 = <0>,"+13"; + + addr = <&abx80x>, "reg:0", + <&ds1307>, "reg:0", +@@ -226,11 +244,14 @@ + <&mcp7941x>, "reg:0", + <&pcf8523>, "reg:0", + <&pcf8563>, "reg:0", +- <&m41t62>, "reg:0"; +- trickle-diode-type = <&abx80x>,"abracon,tc-diode"; ++ <&m41t62>, "reg:0", ++ <&rv1805>, "reg:0"; ++ trickle-diode-type = <&abx80x>,"abracon,tc-diode", ++ <&rv1805>,"abracon,tc-diode"; + trickle-resistor-ohms = <&ds1339>,"trickle-resistor-ohms:0", + <&abx80x>,"abracon,tc-resistor:0", +- <&rv3028>,"trickle-resistor-ohms:0"; ++ <&rv3028>,"trickle-resistor-ohms:0", ++ <&rv1805>,"abracon,tc-resistor:0"; + backup-switchover-mode = <&rv3028>,"backup-switchover-mode:0"; + wakeup-source = <&ds1339>,"wakeup-source?", + <&ds3231>,"wakeup-source?", diff --git a/target/linux/bcm27xx/patches-5.4/950-0760-vc4-Set-driver_name-for-card.patch b/target/linux/bcm27xx/patches-5.4/950-0760-vc4-Set-driver_name-for-card.patch new file mode 100644 index 0000000000..0f02d99d97 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0760-vc4-Set-driver_name-for-card.patch @@ -0,0 +1,22 @@ +From aff5900c0b389e5ad2b8f2fc67544e769f94cbf4 Mon Sep 17 00:00:00 2001 +From: Dom Cobley <popcornmix@gmail.com> +Date: Tue, 2 Jun 2020 19:31:49 +0100 +Subject: [PATCH] vc4: Set driver_name for card + +Allows use of the same alsa conf file for hdmi1 + +Signed-off-by: Dom Cobley <popcornmix@gmail.com> +--- + drivers/gpu/drm/vc4/vc4_hdmi.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -1216,6 +1216,7 @@ static int vc4_hdmi_audio_init(struct vc + card->dai_link = dai_link; + card->num_links = 1; + card->name = vc4_hdmi->variant->id ? "vc4-hdmi1" : "vc4-hdmi"; ++ card->driver_name = "vc4-hdmi"; + card->dev = dev; + card->owner = THIS_MODULE; + diff --git a/target/linux/bcm27xx/patches-5.4/950-0761-staging-vchiq_arm-Use-g_dma_dev-for-dma_unmap_sg.patch b/target/linux/bcm27xx/patches-5.4/950-0761-staging-vchiq_arm-Use-g_dma_dev-for-dma_unmap_sg.patch new file mode 100644 index 0000000000..4af13475f9 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0761-staging-vchiq_arm-Use-g_dma_dev-for-dma_unmap_sg.patch @@ -0,0 +1,27 @@ +From fecd0c670aabdbe5bac8fb58be374dd02ea2e8a2 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Thu, 4 Jun 2020 17:23:36 +0100 +Subject: [PATCH] staging: vchiq_arm: Use g_dma_dev for dma_unmap_sg + +Commit "staging: vchiq_arm: Clean up 40-bit DMA support" failed to +change one of the calls to dma_unmap_sg to pass in g_dma_dev (rather +than g_dev). Correct that oversight. + +See: https://github.com/raspberrypi/linux/issues/3647 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + .../staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +@@ -641,7 +641,7 @@ free_pagelist(struct vchiq_pagelist_info + * NOTE: dma_unmap_sg must be called before the + * cpu can touch any of the data/pages. + */ +- dma_unmap_sg(g_dev, pagelistinfo->scatterlist, ++ dma_unmap_sg(g_dma_dev, pagelistinfo->scatterlist, + pagelistinfo->num_pages, pagelistinfo->dma_dir); + pagelistinfo->scatterlist_mapped = 0; + diff --git a/target/linux/bcm27xx/patches-5.4/950-0762-vc4-cec-Restore-cec-physical-address-on-reconnect.patch b/target/linux/bcm27xx/patches-5.4/950-0762-vc4-cec-Restore-cec-physical-address-on-reconnect.patch new file mode 100644 index 0000000000..d42f61d2e4 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0762-vc4-cec-Restore-cec-physical-address-on-reconnect.patch @@ -0,0 +1,56 @@ +From 7776a876ce7a6eeda164aebacc965116821d3095 Mon Sep 17 00:00:00 2001 +From: Dom Cobley <popcornmix@gmail.com> +Date: Wed, 3 Jun 2020 12:20:19 +0100 +Subject: [PATCH] vc4: cec: Restore cec physical address on reconnect + +Currently we call cec_phys_addr_invalidate on a hotplug deassert. +That may be due to a TV power cycling, or an AVR being switched +on (and switching edid). This makes CEC unusable. + +Set it back up again on the hotplug assert. + +Signed-off-by: Dom Cobley <popcornmix@gmail.com> +--- + drivers/gpu/drm/vc4/vc4_hdmi.c | 25 +++++++++++++++++-------- + 1 file changed, 17 insertions(+), 8 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -113,20 +113,29 @@ static enum drm_connector_status + vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) + { + struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); ++ bool connected = false; + + if (vc4_hdmi->hpd_gpio) { + if (gpio_get_value_cansleep(vc4_hdmi->hpd_gpio) ^ + vc4_hdmi->hpd_active_low) +- return connector_status_connected; +- cec_phys_addr_invalidate(vc4_hdmi->cec_adap); +- return connector_status_disconnected; +- } +- +- if (drm_probe_ddc(vc4_hdmi->ddc)) +- return connector_status_connected; +- ++ connected = true; ++ } else if (drm_probe_ddc(vc4_hdmi->ddc)) ++ connected = true; + if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED) ++ connected = true; ++ if (connected) { ++ if (connector->status != connector_status_connected) { ++ struct edid *edid = drm_get_edid(connector, vc4_hdmi->ddc); ++ ++ if (edid) { ++ cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, edid); ++ vc4_hdmi->encoder.hdmi_monitor = drm_detect_hdmi_monitor(edid); ++ drm_connector_update_edid_property(connector, edid); ++ kfree(edid); ++ } ++ } + return connector_status_connected; ++ } + cec_phys_addr_invalidate(vc4_hdmi->cec_adap); + return connector_status_disconnected; + } diff --git a/target/linux/bcm27xx/patches-5.4/950-0763-snd_bcm2835-disable-HDMI-audio-when-vc4-is-used-3640.patch b/target/linux/bcm27xx/patches-5.4/950-0763-snd_bcm2835-disable-HDMI-audio-when-vc4-is-used-3640.patch new file mode 100644 index 0000000000..ed45410294 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0763-snd_bcm2835-disable-HDMI-audio-when-vc4-is-used-3640.patch @@ -0,0 +1,92 @@ +From 744543757bef8621f7791e28ecb894b2627cb449 Mon Sep 17 00:00:00 2001 +From: Hristo Venev <hristo@venev.name> +Date: Fri, 5 Jun 2020 09:22:49 +0000 +Subject: [PATCH] snd_bcm2835: disable HDMI audio when vc4 is used + (#3640) + +Things don't work too well when both the vc4 driver and the firmware +driver are trying to control the same audio output: + +[ 763.569406] bcm2835_audio bcm2835_audio: vchi message timeout, msg=5 + +Hence, when the vc4 HDMI driver is used, let it control audio. This is done +by introducing a new device tree property to the audio node, and +extending the vc4-kms-v3d overlays to set it appropriately. + +Signed-off-by: Hristo Venev <hristo@venev.name> +--- + arch/arm/boot/dts/overlays/README | 2 ++ + arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 10 +++++++++- + arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts | 8 ++++++++ + drivers/staging/vc04_services/bcm2835-audio/bcm2835.c | 4 +++- + 4 files changed, 22 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -2745,6 +2745,7 @@ Params: cma-256 CMA is 2 + cma-size CMA size in bytes, 4MB aligned + cma-default Use upstream's default value + audio Enable or disable audio over HDMI (default "on") ++ noaudio Disable all HDMI audio (default "off") + + + Name: vc4-kms-v3d-pi4 +@@ -2761,6 +2762,7 @@ Params: cma-256 CMA is 2 + "on") + audio1 Enable or disable audio over HDMI1 (default + "on") ++ noaudio Disable all HDMI audio (default "off") + + + Name: vga666 +--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts ++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts +@@ -108,7 +108,15 @@ + }; + }; + ++ fragment@14 { ++ target = <&audio>; ++ __overlay__ { ++ brcm,disable-hdmi; ++ }; ++ }; ++ + __overrides__ { +- audio = <0>,"!13"; ++ audio = <0>,"!13", <0>,"=14"; ++ noaudio = <0>,"=13", <0>,"!14"; + }; + }; +--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts ++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts +@@ -138,8 +138,16 @@ + }; + }; + ++ fragment@19 { ++ target = <&audio>; ++ __overlay__ { ++ brcm,disable-hdmi; ++ }; ++ }; ++ + __overrides__ { + audio = <0>,"!17"; + audio1 = <0>,"!18"; ++ noaudio = <0>,"=17", <0>,"=18", <0>,"!19"; + }; + }; +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +@@ -381,7 +381,9 @@ static int snd_bcm2835_alsa_probe(struct + } + + if (!enable_compat_alsa) { +- set_hdmi_enables(dev); ++ if (!of_property_read_bool(dev->of_node, "brcm,disable-hdmi")) ++ set_hdmi_enables(dev); ++ + // In this mode, always enable analog output + enable_headphones = true; + } else { diff --git a/target/linux/bcm27xx/patches-5.4/950-0764-overlays-i2c-gpio-Avoid-open-drain-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-0764-overlays-i2c-gpio-Avoid-open-drain-warnings.patch new file mode 100644 index 0000000000..9b6cb1d564 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0764-overlays-i2c-gpio-Avoid-open-drain-warnings.patch @@ -0,0 +1,93 @@ +From 11f89a12530471a2b25c71416e106eaa014818c0 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Fri, 5 Jun 2020 16:07:07 +0100 +Subject: [PATCH] overlays: i2c-gpio: Avoid open-drain warnings + +The i2c-gpio driver expects to use a GPIO in open-drain mode. Failure +to configure it in that way causes alarming warnings in the kernel log. +The BCM283x and BCM2711 GPIO blocks don't support open-drain mode, but +gpiolib can emulate it in software if configured correctly. + +Silence the warning by declaring the GPIOs as requiring open-drain +mode, trusting gpiolib to manage the emulation. The previous +incarnation of this patch took the other approach of telling the +i2c-gpio driver that the GPIOs were configured for open-drain, but +this had the effect of disabling the emulation. In some cases this +appears to work, but examining the waveforms as analogue voltages +shows contention, the success or failure depending on drive strengths. + +See: https://github.com/raspberrypi/firmware/issues/1381 +See: https://github.com/raspberrypi/firmware/issues/1401 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/balena-fin-overlay.dts | 5 ++++- + arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts | 6 ++++-- + arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts | 6 ++++-- + 3 files changed, 12 insertions(+), 5 deletions(-) + +--- a/arch/arm/boot/dts/overlays/balena-fin-overlay.dts ++++ b/arch/arm/boot/dts/overlays/balena-fin-overlay.dts +@@ -1,6 +1,8 @@ + /dts-v1/; + /plugin/; + ++#include <dt-bindings/gpio/gpio.h> ++ + /{ + compatible = "brcm,bcm2835"; + +@@ -48,7 +50,8 @@ + + i2c_soft: i2c@0 { + compatible = "i2c-gpio"; +- gpios = <&gpio 43 0 /* sda */ &gpio 42 0 /* scl */>; ++ gpios = <&gpio 43 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) /* sda */ ++ &gpio 42 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) /* scl */>; + i2c-gpio,delay-us = <5>; + i2c-gpio,scl-open-drain; + i2c-gpio,sda-open-drain; +--- a/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts +@@ -2,6 +2,8 @@ + /dts-v1/; + /plugin/; + ++#include <dt-bindings/gpio/gpio.h> ++ + / { + compatible = "brcm,bcm2835"; + +@@ -12,8 +14,8 @@ + i2c_gpio: i2c@0 { + reg = <0xffffffff>; + compatible = "i2c-gpio"; +- gpios = <&gpio 23 0 /* sda */ +- &gpio 24 0 /* scl */ ++ gpios = <&gpio 23 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) /* sda */ ++ &gpio 24 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) /* scl */ + >; + i2c-gpio,delay-us = <2>; /* ~100 kHz */ + #address-cells = <1>; +--- a/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-rtc-gpio-overlay.dts +@@ -3,6 +3,8 @@ + /dts-v1/; + /plugin/; + ++#include <dt-bindings/gpio/gpio.h> ++ + / { + compatible = "brcm,bcm2835"; + +@@ -11,8 +13,8 @@ + __overlay__ { + i2c_gpio: i2c-gpio-rtc@0 { + compatible = "i2c-gpio"; +- gpios = <&gpio 23 0 /* sda */ +- &gpio 24 0 /* scl */ ++ gpios = <&gpio 23 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) /* sda */ ++ &gpio 24 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN) /* scl */ + >; + i2c-gpio,delay-us = <2>; /* ~100 kHz */ + #address-cells = <1>; diff --git a/target/linux/bcm27xx/patches-5.4/950-0765-overlays-Update-upstream-overlays-after-vc4-kms-v3d-.patch b/target/linux/bcm27xx/patches-5.4/950-0765-overlays-Update-upstream-overlays-after-vc4-kms-v3d-.patch new file mode 100644 index 0000000000..dd5f2ee90a --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0765-overlays-Update-upstream-overlays-after-vc4-kms-v3d-.patch @@ -0,0 +1,42 @@ +From 964d9575e0a9849f197edaa243e9f2268d5ab44e Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Fri, 5 Jun 2020 16:18:52 +0100 +Subject: [PATCH] overlays: Update upstream overlays after + vc4-kms-v3d change + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/upstream-overlay.dts | 6 ++++++ + arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts | 6 ++++++ + 2 files changed, 12 insertions(+) + +--- a/arch/arm/boot/dts/overlays/upstream-overlay.dts ++++ b/arch/arm/boot/dts/overlays/upstream-overlay.dts +@@ -92,6 +92,12 @@ + }; + }; + fragment@14 { ++ target = <&audio>; ++ __overlay__ { ++ brcm,disable-hdmi; ++ }; ++ }; ++ fragment@15 { + target = <&usb>; + #address-cells = <1>; + #size-cells = <1>; +--- a/arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts ++++ b/arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts +@@ -122,6 +122,12 @@ + }; + }; + fragment@19 { ++ target = <&audio>; ++ __overlay__ { ++ brcm,disable-hdmi; ++ }; ++ }; ++ fragment@20 { + target = <&usb>; + #address-cells = <1>; + #size-cells = <1>; diff --git a/target/linux/bcm27xx/patches-5.4/950-0766-w1_therm-adding-code-comments-and-code-reordering.patch b/target/linux/bcm27xx/patches-5.4/950-0766-w1_therm-adding-code-comments-and-code-reordering.patch new file mode 100644 index 0000000000..5db05123da --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0766-w1_therm-adding-code-comments-and-code-reordering.patch @@ -0,0 +1,580 @@ +From 7c49e87acd0412ff1fb2490c4ac6fcb5471afd9b Mon Sep 17 00:00:00 2001 +From: Akira Shimahara <akira215corp@gmail.com> +Date: Mon, 11 May 2020 22:35:35 +0200 +Subject: [PATCH] w1_therm: adding code comments and code reordering + +commit 92b8d2724464bc1d2e735a84c0da5741dce33485 upstream. + +Adding code comments to split code in dedicated parts. After the global +declarations (defines, macros and function declarations), code is organized +as follow : + - Device and family dependent structures and functions + - Interfaces functions + - Helpers functions + - Hardware functions + - Sysfs interface functions + +Signed-off-by: Akira Shimahara <akira215corp@gmail.com> +Link: https://lore.kernel.org/r/20200511203535.409599-1-akira215corp@gmail.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/w1/slaves/w1_therm.c | 427 +++++++++++++++++++++-------------- + 1 file changed, 259 insertions(+), 168 deletions(-) + +--- a/drivers/w1/slaves/w1_therm.c ++++ b/drivers/w1/slaves/w1_therm.c +@@ -25,7 +25,8 @@ + #define W1_THERM_DS1825 0x3B + #define W1_THERM_DS28EA00 0x42 + +-/* Allow the strong pullup to be disabled, but default to enabled. ++/* ++ * Allow the strong pullup to be disabled, but default to enabled. + * If it was disabled a parasite powered device might not get the require + * current to do a temperature conversion. If it is enabled parasite powered + * devices have a better chance of getting the current required. +@@ -41,42 +42,55 @@ + static int w1_strong_pullup = 1; + module_param_named(strong_pullup, w1_strong_pullup, int, 0); + ++/* Helpers Macros */ ++ ++/* return the address of the refcnt in the family data */ ++#define THERM_REFCNT(family_data) \ ++ (&((struct w1_therm_family_data *)family_data)->refcnt) ++ ++/* Structs definition */ ++ ++/** ++ * struct w1_therm_family_converter - bind device specific functions ++ * @broken: flag for non-registred families ++ * @reserved: not used here ++ * @f: pointer to the device binding structure ++ * @convert: pointer to the device conversion function ++ * @precision: pointer to the device precision function ++ * @eeprom: pointer to eeprom function ++ */ ++struct w1_therm_family_converter { ++ u8 broken; ++ u16 reserved; ++ struct w1_family *f; ++ int (*convert)(u8 rom[9]); ++ int (*precision)(struct device *device, int val); ++ int (*eeprom)(struct device *device); ++}; ++ ++/** ++ * struct w1_therm_family_data - device data ++ * @rom: ROM device id (64bit Lasered ROM code + 1 CRC byte) ++ * @refcnt: ref count ++ */ + struct w1_therm_family_data { + uint8_t rom[9]; + atomic_t refcnt; + }; + ++/** ++ * struct therm_info - store temperature reading ++ * @rom: read device data (8 data bytes + 1 CRC byte) ++ * @crc: computed crc from rom ++ * @verdict: 1 crc checked, 0 crc not matching ++ */ + struct therm_info { + u8 rom[9]; + u8 crc; + u8 verdict; + }; + +-/* return the address of the refcnt in the family data */ +-#define THERM_REFCNT(family_data) \ +- (&((struct w1_therm_family_data *)family_data)->refcnt) +- +-static int w1_therm_add_slave(struct w1_slave *sl) +-{ +- sl->family_data = kzalloc(sizeof(struct w1_therm_family_data), +- GFP_KERNEL); +- if (!sl->family_data) +- return -ENOMEM; +- atomic_set(THERM_REFCNT(sl->family_data), 1); +- return 0; +-} +- +-static void w1_therm_remove_slave(struct w1_slave *sl) +-{ +- int refcnt = atomic_sub_return(1, THERM_REFCNT(sl->family_data)); +- +- while (refcnt) { +- msleep(1000); +- refcnt = atomic_read(THERM_REFCNT(sl->family_data)); +- } +- kfree(sl->family_data); +- sl->family_data = NULL; +-} ++/* Sysfs interface declaration */ + + static ssize_t w1_slave_show(struct device *device, + struct device_attribute *attr, char *buf); +@@ -87,9 +101,35 @@ static ssize_t w1_slave_store(struct dev + static ssize_t w1_seq_show(struct device *device, + struct device_attribute *attr, char *buf); + ++/* Attributes declarations */ ++ + static DEVICE_ATTR_RW(w1_slave); + static DEVICE_ATTR_RO(w1_seq); + ++/* Interface Functions declaration */ ++ ++/** ++ * w1_therm_add_slave() - Called when a new slave is discovered ++ * @sl: slave just discovered by the master. ++ * ++ * Called by the master when the slave is discovered on the bus. Used to ++ * initialize slave state before the beginning of any communication. ++ * ++ * Return: 0 - If success, negative kernel code otherwise ++ */ ++static int w1_therm_add_slave(struct w1_slave *sl); ++ ++/** ++ * w1_therm_remove_slave() - Called when a slave is removed ++ * @sl: slave to be removed. ++ * ++ * Called by the master when the slave is considered not to be on the bus ++ * anymore. Used to free memory. ++ */ ++static void w1_therm_remove_slave(struct w1_slave *sl); ++ ++/* Family attributes */ ++ + static struct attribute *w1_therm_attrs[] = { + &dev_attr_w1_slave.attr, + NULL, +@@ -101,6 +141,8 @@ static struct attribute *w1_ds28ea00_att + NULL, + }; + ++/* Attribute groups */ ++ + ATTRIBUTE_GROUPS(w1_therm); + ATTRIBUTE_GROUPS(w1_ds28ea00); + +@@ -154,6 +196,8 @@ static const struct hwmon_chip_info w1_c + #define W1_CHIPINFO NULL + #endif + ++/* Family operations */ ++ + static struct w1_family_ops w1_therm_fops = { + .add_slave = w1_therm_add_slave, + .remove_slave = w1_therm_remove_slave, +@@ -168,6 +212,8 @@ static struct w1_family_ops w1_ds28ea00_ + .chip_info = W1_CHIPINFO, + }; + ++/* Family binding operations struct */ ++ + static struct w1_family w1_therm_family_DS18S20 = { + .fid = W1_THERM_DS18S20, + .fops = &w1_therm_fops, +@@ -193,138 +239,18 @@ static struct w1_family w1_therm_family_ + .fops = &w1_therm_fops, + }; + +-struct w1_therm_family_converter { +- u8 broken; +- u16 reserved; +- struct w1_family *f; +- int (*convert)(u8 rom[9]); +- int (*precision)(struct device *device, int val); +- int (*eeprom)(struct device *device); +-}; ++/* Device dependent func */ + + /* write configuration to eeprom */ + static inline int w1_therm_eeprom(struct device *device); + +-/* Set precision for conversion */ +-static inline int w1_DS18B20_precision(struct device *device, int val); +-static inline int w1_DS18S20_precision(struct device *device, int val); +- +-/* The return value is millidegrees Centigrade. */ +-static inline int w1_DS18B20_convert_temp(u8 rom[9]); +-static inline int w1_DS18S20_convert_temp(u8 rom[9]); +- +-static struct w1_therm_family_converter w1_therm_families[] = { +- { +- .f = &w1_therm_family_DS18S20, +- .convert = w1_DS18S20_convert_temp, +- .precision = w1_DS18S20_precision, +- .eeprom = w1_therm_eeprom +- }, +- { +- .f = &w1_therm_family_DS1822, +- .convert = w1_DS18B20_convert_temp, +- .precision = w1_DS18S20_precision, +- .eeprom = w1_therm_eeprom +- }, +- { +- .f = &w1_therm_family_DS18B20, +- .convert = w1_DS18B20_convert_temp, +- .precision = w1_DS18B20_precision, +- .eeprom = w1_therm_eeprom +- }, +- { +- .f = &w1_therm_family_DS28EA00, +- .convert = w1_DS18B20_convert_temp, +- .precision = w1_DS18S20_precision, +- .eeprom = w1_therm_eeprom +- }, +- { +- .f = &w1_therm_family_DS1825, +- .convert = w1_DS18B20_convert_temp, +- .precision = w1_DS18S20_precision, +- .eeprom = w1_therm_eeprom +- } +-}; +- +-static inline int w1_therm_eeprom(struct device *device) +-{ +- struct w1_slave *sl = dev_to_w1_slave(device); +- struct w1_master *dev = sl->master; +- u8 rom[9], external_power; +- int ret, max_trying = 10; +- u8 *family_data = sl->family_data; +- +- if (!sl->family_data) { +- ret = -ENODEV; +- goto error; +- } +- +- /* prevent the slave from going away in sleep */ +- atomic_inc(THERM_REFCNT(family_data)); +- +- ret = mutex_lock_interruptible(&dev->bus_mutex); +- if (ret != 0) +- goto dec_refcnt; +- +- memset(rom, 0, sizeof(rom)); +- +- while (max_trying--) { +- if (!w1_reset_select_slave(sl)) { +- unsigned int tm = 10; +- unsigned long sleep_rem; +- +- /* check if in parasite mode */ +- w1_write_8(dev, W1_READ_PSUPPLY); +- external_power = w1_read_8(dev); +- +- if (w1_reset_select_slave(sl)) +- continue; +- +- /* 10ms strong pullup/delay after the copy command */ +- if (w1_strong_pullup == 2 || +- (!external_power && w1_strong_pullup)) +- w1_next_pullup(dev, tm); +- +- w1_write_8(dev, W1_COPY_SCRATCHPAD); +- +- if (external_power) { +- mutex_unlock(&dev->bus_mutex); +- +- sleep_rem = msleep_interruptible(tm); +- if (sleep_rem != 0) { +- ret = -EINTR; +- goto dec_refcnt; +- } +- +- ret = mutex_lock_interruptible(&dev->bus_mutex); +- if (ret != 0) +- goto dec_refcnt; +- } else if (!w1_strong_pullup) { +- sleep_rem = msleep_interruptible(tm); +- if (sleep_rem != 0) { +- ret = -EINTR; +- goto mt_unlock; +- } +- } +- +- break; +- } +- } +- +-mt_unlock: +- mutex_unlock(&dev->bus_mutex); +-dec_refcnt: +- atomic_dec(THERM_REFCNT(family_data)); +-error: +- return ret; +-} +- + /* DS18S20 does not feature configuration register */ + static inline int w1_DS18S20_precision(struct device *device, int val) + { + return 0; + } + ++/* Set precision for conversion */ + static inline int w1_DS18B20_precision(struct device *device, int val) + { + struct w1_slave *sl = dev_to_w1_slave(device); +@@ -407,6 +333,14 @@ error: + return ret; + } + ++/** ++ * w1_DS18B20_convert_temp() - temperature computation for DS18B20 ++ * @rom: data read from device RAM (8 data bytes + 1 CRC byte) ++ * ++ * Can be called for any DS18B20 compliant device. ++ * ++ * Return: value in millidegrees Celsius. ++ */ + static inline int w1_DS18B20_convert_temp(u8 rom[9]) + { + s16 t = le16_to_cpup((__le16 *)rom); +@@ -414,6 +348,14 @@ static inline int w1_DS18B20_convert_tem + return t*1000/16; + } + ++/** ++ * w1_DS18S20_convert_temp() - temperature computation for DS18S20 ++ * @rom: data read from device RAM (8 data bytes + 1 CRC byte) ++ * ++ * Can be called for any DS18S20 compliant device. ++ * ++ * Return: value in millidegrees Celsius. ++ */ + static inline int w1_DS18S20_convert_temp(u8 rom[9]) + { + int t, h; +@@ -434,6 +376,53 @@ static inline int w1_DS18S20_convert_tem + return t; + } + ++/* Device capability description */ ++ ++static struct w1_therm_family_converter w1_therm_families[] = { ++ { ++ .f = &w1_therm_family_DS18S20, ++ .convert = w1_DS18S20_convert_temp, ++ .precision = w1_DS18S20_precision, ++ .eeprom = w1_therm_eeprom ++ }, ++ { ++ .f = &w1_therm_family_DS1822, ++ .convert = w1_DS18B20_convert_temp, ++ .precision = w1_DS18S20_precision, ++ .eeprom = w1_therm_eeprom ++ }, ++ { ++ .f = &w1_therm_family_DS18B20, ++ .convert = w1_DS18B20_convert_temp, ++ .precision = w1_DS18B20_precision, ++ .eeprom = w1_therm_eeprom ++ }, ++ { ++ .f = &w1_therm_family_DS28EA00, ++ .convert = w1_DS18B20_convert_temp, ++ .precision = w1_DS18S20_precision, ++ .eeprom = w1_therm_eeprom ++ }, ++ { ++ .f = &w1_therm_family_DS1825, ++ .convert = w1_DS18B20_convert_temp, ++ .precision = w1_DS18S20_precision, ++ .eeprom = w1_therm_eeprom ++ } ++}; ++ ++/* Helpers Functions */ ++ ++/** ++ * w1_convert_temp() - temperature conversion binding function ++ * @rom: data read from device RAM (8 data bytes + 1 CRC byte) ++ * @fid: device family id ++ * ++ * The function call the temperature computation function according to ++ * device family. ++ * ++ * Return: value in millidegrees Celsius. ++ */ + static inline int w1_convert_temp(u8 rom[9], u8 fid) + { + int i; +@@ -445,31 +434,32 @@ static inline int w1_convert_temp(u8 rom + return 0; + } + +-static ssize_t w1_slave_store(struct device *device, +- struct device_attribute *attr, const char *buf, +- size_t size) ++/* Interface Functions */ ++ ++static int w1_therm_add_slave(struct w1_slave *sl) + { +- int val, ret; +- struct w1_slave *sl = dev_to_w1_slave(device); +- int i; ++ sl->family_data = kzalloc(sizeof(struct w1_therm_family_data), ++ GFP_KERNEL); ++ if (!sl->family_data) ++ return -ENOMEM; ++ atomic_set(THERM_REFCNT(sl->family_data), 1); ++ return 0; ++} + +- ret = kstrtoint(buf, 0, &val); +- if (ret) +- return ret; ++static void w1_therm_remove_slave(struct w1_slave *sl) ++{ ++ int refcnt = atomic_sub_return(1, THERM_REFCNT(sl->family_data)); + +- for (i = 0; i < ARRAY_SIZE(w1_therm_families); ++i) { +- if (w1_therm_families[i].f->fid == sl->family->fid) { +- /* zero value indicates to write current configuration to eeprom */ +- if (val == 0) +- ret = w1_therm_families[i].eeprom(device); +- else +- ret = w1_therm_families[i].precision(device, val); +- break; +- } ++ while (refcnt) { ++ msleep(1000); ++ refcnt = atomic_read(THERM_REFCNT(sl->family_data)); + } +- return ret ? : size; ++ kfree(sl->family_data); ++ sl->family_data = NULL; + } + ++/* Hardware Functions */ ++ + static ssize_t read_therm(struct device *device, + struct w1_slave *sl, struct therm_info *info) + { +@@ -564,6 +554,81 @@ error: + return ret; + } + ++static inline int w1_therm_eeprom(struct device *device) ++{ ++ struct w1_slave *sl = dev_to_w1_slave(device); ++ struct w1_master *dev = sl->master; ++ u8 rom[9], external_power; ++ int ret, max_trying = 10; ++ u8 *family_data = sl->family_data; ++ ++ if (!sl->family_data) { ++ ret = -ENODEV; ++ goto error; ++ } ++ ++ /* prevent the slave from going away in sleep */ ++ atomic_inc(THERM_REFCNT(family_data)); ++ ++ ret = mutex_lock_interruptible(&dev->bus_mutex); ++ if (ret != 0) ++ goto dec_refcnt; ++ ++ memset(rom, 0, sizeof(rom)); ++ ++ while (max_trying--) { ++ if (!w1_reset_select_slave(sl)) { ++ unsigned int tm = 10; ++ unsigned long sleep_rem; ++ ++ /* check if in parasite mode */ ++ w1_write_8(dev, W1_READ_PSUPPLY); ++ external_power = w1_read_8(dev); ++ ++ if (w1_reset_select_slave(sl)) ++ continue; ++ ++ /* 10ms strong pullup/delay after the copy command */ ++ if (w1_strong_pullup == 2 || ++ (!external_power && w1_strong_pullup)) ++ w1_next_pullup(dev, tm); ++ ++ w1_write_8(dev, W1_COPY_SCRATCHPAD); ++ ++ if (external_power) { ++ mutex_unlock(&dev->bus_mutex); ++ ++ sleep_rem = msleep_interruptible(tm); ++ if (sleep_rem != 0) { ++ ret = -EINTR; ++ goto dec_refcnt; ++ } ++ ++ ret = mutex_lock_interruptible(&dev->bus_mutex); ++ if (ret != 0) ++ goto dec_refcnt; ++ } else if (!w1_strong_pullup) { ++ sleep_rem = msleep_interruptible(tm); ++ if (sleep_rem != 0) { ++ ret = -EINTR; ++ goto mt_unlock; ++ } ++ } ++ ++ break; ++ } ++ } ++ ++mt_unlock: ++ mutex_unlock(&dev->bus_mutex); ++dec_refcnt: ++ atomic_dec(THERM_REFCNT(family_data)); ++error: ++ return ret; ++} ++ ++/* Sysfs Interface definition */ ++ + static ssize_t w1_slave_show(struct device *device, + struct device_attribute *attr, char *buf) + { +@@ -597,6 +662,32 @@ static ssize_t w1_slave_show(struct devi + return ret; + } + ++static ssize_t w1_slave_store(struct device *device, ++ struct device_attribute *attr, const char *buf, ++ size_t size) ++{ ++ int val, ret; ++ struct w1_slave *sl = dev_to_w1_slave(device); ++ int i; ++ ++ ret = kstrtoint(buf, 0, &val); ++ if (ret) ++ return ret; ++ ++ for (i = 0; i < ARRAY_SIZE(w1_therm_families); ++i) { ++ if (w1_therm_families[i].f->fid == sl->family->fid) { ++ /* zero value indicates to write current configuration to eeprom */ ++ if (val == 0) ++ ret = w1_therm_families[i].eeprom(device); ++ else ++ ret = w1_therm_families[i].precision(device, ++ val); ++ break; ++ } ++ } ++ return ret ? : size; ++} ++ + #if IS_REACHABLE(CONFIG_HWMON) + static int w1_read_temp(struct device *device, u32 attr, int channel, + long *val) +@@ -666,7 +757,7 @@ static ssize_t w1_seq_show(struct device + if (ack != W1_42_SUCCESS_CONFIRM_BYTE) + goto error; + +- /* In case the bus fails to send 0xFF, limit*/ ++ /* In case the bus fails to send 0xFF, limit */ + for (i = 0; i <= 64; i++) { + if (w1_reset_bus(sl->master)) + goto error; diff --git a/target/linux/bcm27xx/patches-5.4/950-0767-w1_therm-fix-reset_select_slave-during-discovery.patch b/target/linux/bcm27xx/patches-5.4/950-0767-w1_therm-fix-reset_select_slave-during-discovery.patch new file mode 100644 index 0000000000..9881f81de4 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0767-w1_therm-fix-reset_select_slave-during-discovery.patch @@ -0,0 +1,149 @@ +From dfc9fd0060f9103ca1f9335d529401ee8a105737 Mon Sep 17 00:00:00 2001 +From: Akira Shimahara <akira215corp@gmail.com> +Date: Mon, 11 May 2020 22:36:10 +0200 +Subject: [PATCH] w1_therm: fix reset_select_slave during discovery + +commit c8ad65f6fbfdcb9b620674ef456020eef2bfeb36 upstream. + +Fix reset_select_slave issue during devices discovery by the master on +bus. The w1_reset_select_slave() from w1_io.c, which was previously used, +assume that if the slave count is 1 there is only one slave attached on +the bus. This is not always true. For example when discovering devices, +when the first device is discover by the bus master, its slave count is +1, but some other slaves may be on the bus. + +In that case instead of adressing command to the attached slave the +master throw a SKIP ROM command so that all slaves attached on the bus +will answer simultenaously causing data collision. + +A dedicated reset_select_slave() function is implemented here, +it always perform an adressing to each slave using the MATCH ROM +command. + +Signed-off-by: Akira Shimahara <akira215corp@gmail.com> +Link: https://lore.kernel.org/r/20200511203610.409975-1-akira215corp@gmail.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/w1/slaves/w1_therm.c | 48 ++++++++++++++++++++++++++++++------ + 1 file changed, 41 insertions(+), 7 deletions(-) + +--- a/drivers/w1/slaves/w1_therm.c ++++ b/drivers/w1/slaves/w1_therm.c +@@ -16,6 +16,7 @@ + #include <linux/slab.h> + #include <linux/delay.h> + #include <linux/hwmon.h> ++#include <linux/string.h> + + #include <linux/w1.h> + +@@ -90,6 +91,24 @@ struct therm_info { + u8 verdict; + }; + ++/* Hardware Functions declaration */ ++ ++/** ++ * reset_select_slave() - reset and select a slave ++ * @sl: the slave to select ++ * ++ * Resets the bus and select the slave by sending a ROM MATCH cmd ++ * w1_reset_select_slave() from w1_io.c could not be used here because ++ * it sent a SKIP ROM command if only one device is on the line. ++ * At the beginning of the such process, sl->master->slave_count is 1 even if ++ * more devices are on the line, causing collision on the line. ++ * ++ * Context: The w1 master lock must be held. ++ * ++ * Return: 0 if success, negative kernel error code otherwise. ++ */ ++static int reset_select_slave(struct w1_slave *sl); ++ + /* Sysfs interface declaration */ + + static ssize_t w1_slave_show(struct device *device, +@@ -301,7 +320,7 @@ static inline int w1_DS18B20_precision(s + while (max_trying--) { + crc = 0; + +- if (!w1_reset_select_slave(sl)) { ++ if (!reset_select_slave(sl)) { + int count = 0; + + /* read values to only alter precision bits */ +@@ -314,7 +333,7 @@ static inline int w1_DS18B20_precision(s + if (rom[8] == crc) { + rom[4] = (rom[4] & ~mask) | (precision_bits & mask); + +- if (!w1_reset_select_slave(sl)) { ++ if (!reset_select_slave(sl)) { + w1_write_8(dev, W1_WRITE_SCRATCHPAD); + w1_write_8(dev, rom[2]); + w1_write_8(dev, rom[3]); +@@ -460,6 +479,21 @@ static void w1_therm_remove_slave(struct + + /* Hardware Functions */ + ++/* Safe version of reset_select_slave - avoid using the one in w_io.c */ ++static int reset_select_slave(struct w1_slave *sl) ++{ ++ u8 match[9] = { W1_MATCH_ROM, }; ++ u64 rn = le64_to_cpu(*((u64 *)&sl->reg_num)); ++ ++ if (w1_reset_bus(sl->master)) ++ return -ENODEV; ++ ++ memcpy(&match[1], &rn, 8); ++ w1_write_block(sl->master, match, 9); ++ ++ return 0; ++} ++ + static ssize_t read_therm(struct device *device, + struct w1_slave *sl, struct therm_info *info) + { +@@ -487,7 +521,7 @@ static ssize_t read_therm(struct device + info->verdict = 0; + info->crc = 0; + +- if (!w1_reset_select_slave(sl)) { ++ if (!reset_select_slave(sl)) { + int count = 0; + unsigned int tm = 750; + unsigned long sleep_rem; +@@ -495,7 +529,7 @@ static ssize_t read_therm(struct device + w1_write_8(dev, W1_READ_PSUPPLY); + external_power = w1_read_8(dev); + +- if (w1_reset_select_slave(sl)) ++ if (reset_select_slave(sl)) + continue; + + /* 750ms strong pullup (or delay) after the convert */ +@@ -525,7 +559,7 @@ static ssize_t read_therm(struct device + } + } + +- if (!w1_reset_select_slave(sl)) { ++ if (!reset_select_slave(sl)) { + + w1_write_8(dev, W1_READ_SCRATCHPAD); + count = w1_read_block(dev, info->rom, 9); +@@ -577,7 +611,7 @@ static inline int w1_therm_eeprom(struct + memset(rom, 0, sizeof(rom)); + + while (max_trying--) { +- if (!w1_reset_select_slave(sl)) { ++ if (!reset_select_slave(sl)) { + unsigned int tm = 10; + unsigned long sleep_rem; + +@@ -585,7 +619,7 @@ static inline int w1_therm_eeprom(struct + w1_write_8(dev, W1_READ_PSUPPLY); + external_power = w1_read_8(dev); + +- if (w1_reset_select_slave(sl)) ++ if (reset_select_slave(sl)) + continue; + + /* 10ms strong pullup/delay after the copy command */ diff --git a/target/linux/bcm27xx/patches-5.4/950-0768-w1_therm-adding-ext_power-sysfs-entry.patch b/target/linux/bcm27xx/patches-5.4/950-0768-w1_therm-adding-ext_power-sysfs-entry.patch new file mode 100644 index 0000000000..b2e8195b64 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0768-w1_therm-adding-ext_power-sysfs-entry.patch @@ -0,0 +1,293 @@ +From 5737e27d3c5e2f743421e68f926c05e8581ae21f Mon Sep 17 00:00:00 2001 +From: Akira Shimahara <akira215corp@gmail.com> +Date: Mon, 11 May 2020 22:36:50 +0200 +Subject: [PATCH] w1_therm: adding ext_power sysfs entry + +commit b7bb6ca17a90f47c2fe2848531b5bbaf27a65ba7 upstream. + +Adding ext_power sysfs entry (RO). Return the power status of the device: + - 0: device parasite powered + - 1: device externally powered + - xx: xx is kernel error + +The power status of each device is check when the device is +discover by the bus master, in 'w1_therm_add_slave(struct w1_slave *)'. +The status is stored in the device structure w1_therm_family_data so +that the driver always knows the power state of each device, which could +be used later to determine the required strong pull up to apply on the +line. + +The power status is re evaluate each time the sysfs ext_power read by +a user. + +The hardware function 'read_powermode(struct w1_slave *sl)' act just as +per device specifications, sending W1_READ_PSUPPLY command on the bus, +and issue a read time slot, reading only one bit. + +A helper function 'bool bus_mutex_lock(struct mutex *lock)' is introduced. +It try to aquire the bus mutex several times (W1_THERM_MAX_TRY), waiting +W1_THERM_RETRY_DELAY between two attempt. + +Updating Documentation/ABI/testing/sysfs-driver-w1_therm accordingly. + +Signed-off-by: Akira Shimahara <akira215corp@gmail.com> +Link: https://lore.kernel.org/r/20200511203650.410439-1-akira215corp@gmail.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + .../ABI/testing/sysfs-driver-w1_therm | 29 ++++ + drivers/w1/slaves/w1_therm.c | 137 ++++++++++++++++++ + 2 files changed, 166 insertions(+) + create mode 100644 Documentation/ABI/testing/sysfs-driver-w1_therm + +--- /dev/null ++++ b/Documentation/ABI/testing/sysfs-driver-w1_therm +@@ -0,0 +1,29 @@ ++What: /sys/bus/w1/devices/.../ext_power ++Date: May 2020 ++Contact: Akira Shimahara <akira215corp@gmail.com> ++Description: ++ (RO) return the power status by asking the device ++ * '0': device parasite powered ++ * '1': device externally powered ++ * '-xx': xx is kernel error when reading power status ++Users: any user space application which wants to communicate with ++ w1_term device ++ ++ ++What: /sys/bus/w1/devices/.../w1_slave ++Date: May 2020 ++Contact: Akira Shimahara <akira215corp@gmail.com> ++Description: ++ (RW) return the temperature in 1/1000 degC. ++ *read*: return 2 lines with the hexa output data sent on the ++ bus, return the CRC check and temperature in 1/1000 degC ++ *write* : ++ * '0' : save the 2 or 3 bytes to the device EEPROM ++ (i.e. TH, TL and config register) ++ * '9..12' : set the device resolution in RAM ++ (if supported) ++ * Anything else: do nothing ++ refer to Documentation/w1/slaves/w1_therm.rst for detailed ++ information. ++Users: any user space application which wants to communicate with ++ w1_term device +\ No newline at end of file +--- a/drivers/w1/slaves/w1_therm.c ++++ b/drivers/w1/slaves/w1_therm.c +@@ -43,8 +43,21 @@ + static int w1_strong_pullup = 1; + module_param_named(strong_pullup, w1_strong_pullup, int, 0); + ++/* Nb of try for an operation */ ++#define W1_THERM_MAX_TRY 5 ++ ++/* ms delay to retry bus mutex */ ++#define W1_THERM_RETRY_DELAY 20 ++ + /* Helpers Macros */ + ++/* ++ * return the power mode of the sl slave : 1-ext, 0-parasite, <0 unknown ++ * always test family data existence before using this macro ++ */ ++#define SLAVE_POWERMODE(sl) \ ++ (((struct w1_therm_family_data *)(sl->family_data))->external_powered) ++ + /* return the address of the refcnt in the family data */ + #define THERM_REFCNT(family_data) \ + (&((struct w1_therm_family_data *)family_data)->refcnt) +@@ -73,10 +86,14 @@ struct w1_therm_family_converter { + * struct w1_therm_family_data - device data + * @rom: ROM device id (64bit Lasered ROM code + 1 CRC byte) + * @refcnt: ref count ++ * @external_powered: 1 device powered externally, ++ * 0 device parasite powered, ++ * -x error or undefined + */ + struct w1_therm_family_data { + uint8_t rom[9]; + atomic_t refcnt; ++ int external_powered; + }; + + /** +@@ -109,6 +126,20 @@ struct therm_info { + */ + static int reset_select_slave(struct w1_slave *sl); + ++/** ++ * read_powermode() - Query the power mode of the slave ++ * @sl: slave to retrieve the power mode ++ * ++ * Ask the device to get its power mode (external or parasite) ++ * and store the power status in the &struct w1_therm_family_data. ++ * ++ * Return: ++ * * 0 parasite powered device ++ * * 1 externally powered device ++ * * <0 kernel error code ++ */ ++static int read_powermode(struct w1_slave *sl); ++ + /* Sysfs interface declaration */ + + static ssize_t w1_slave_show(struct device *device, +@@ -120,10 +151,14 @@ static ssize_t w1_slave_store(struct dev + static ssize_t w1_seq_show(struct device *device, + struct device_attribute *attr, char *buf); + ++static ssize_t ext_power_show(struct device *device, ++ struct device_attribute *attr, char *buf); ++ + /* Attributes declarations */ + + static DEVICE_ATTR_RW(w1_slave); + static DEVICE_ATTR_RO(w1_seq); ++static DEVICE_ATTR_RO(ext_power); + + /* Interface Functions declaration */ + +@@ -151,12 +186,14 @@ static void w1_therm_remove_slave(struct + + static struct attribute *w1_therm_attrs[] = { + &dev_attr_w1_slave.attr, ++ &dev_attr_ext_power.attr, + NULL, + }; + + static struct attribute *w1_ds28ea00_attrs[] = { + &dev_attr_w1_slave.attr, + &dev_attr_w1_seq.attr, ++ &dev_attr_ext_power.attr, + NULL, + }; + +@@ -433,6 +470,34 @@ static struct w1_therm_family_converter + /* Helpers Functions */ + + /** ++ * bus_mutex_lock() - Acquire the mutex ++ * @lock: w1 bus mutex to acquire ++ * ++ * It try to acquire the mutex W1_THERM_MAX_TRY times and wait ++ * W1_THERM_RETRY_DELAY between 2 attempts. ++ * ++ * Return: true is mutex is acquired and lock, false otherwise ++ */ ++static inline bool bus_mutex_lock(struct mutex *lock) ++{ ++ int max_trying = W1_THERM_MAX_TRY; ++ ++ /* try to acquire the mutex, if not, sleep retry_delay before retry) */ ++ while (mutex_lock_interruptible(lock) != 0 && max_trying > 0) { ++ unsigned long sleep_rem; ++ ++ sleep_rem = msleep_interruptible(W1_THERM_RETRY_DELAY); ++ if (!sleep_rem) ++ max_trying--; ++ } ++ ++ if (!max_trying) ++ return false; /* Didn't acquire the bus mutex */ ++ ++ return true; ++} ++ ++/** + * w1_convert_temp() - temperature conversion binding function + * @rom: data read from device RAM (8 data bytes + 1 CRC byte) + * @fid: device family id +@@ -461,7 +526,19 @@ static int w1_therm_add_slave(struct w1_ + GFP_KERNEL); + if (!sl->family_data) + return -ENOMEM; ++ + atomic_set(THERM_REFCNT(sl->family_data), 1); ++ ++ /* Getting the power mode of the device {external, parasite} */ ++ SLAVE_POWERMODE(sl) = read_powermode(sl); ++ ++ if (SLAVE_POWERMODE(sl) < 0) { ++ /* no error returned as device has been added */ ++ dev_warn(&sl->dev, ++ "%s: Device has been added, but power_mode may be corrupted. err=%d\n", ++ __func__, SLAVE_POWERMODE(sl)); ++ } ++ + return 0; + } + +@@ -661,6 +738,44 @@ error: + return ret; + } + ++static int read_powermode(struct w1_slave *sl) ++{ ++ struct w1_master *dev_master = sl->master; ++ int max_trying = W1_THERM_MAX_TRY; ++ int ret = -ENODEV; ++ ++ if (!sl->family_data) ++ goto error; ++ ++ /* prevent the slave from going away in sleep */ ++ atomic_inc(THERM_REFCNT(sl->family_data)); ++ ++ if (!bus_mutex_lock(&dev_master->bus_mutex)) { ++ ret = -EAGAIN; /* Didn't acquire the mutex */ ++ goto dec_refcnt; ++ } ++ ++ while ((max_trying--) && (ret < 0)) { ++ /* safe version to select slave */ ++ if (!reset_select_slave(sl)) { ++ w1_write_8(dev_master, W1_READ_PSUPPLY); ++ /* ++ * Emit a read time slot and read only one bit, ++ * 1 is externally powered, ++ * 0 is parasite powered ++ */ ++ ret = w1_touch_bit(dev_master, 1); ++ /* ret should be either 1 either 0 */ ++ } ++ } ++ mutex_unlock(&dev_master->bus_mutex); ++ ++dec_refcnt: ++ atomic_dec(THERM_REFCNT(sl->family_data)); ++error: ++ return ret; ++} ++ + /* Sysfs Interface definition */ + + static ssize_t w1_slave_show(struct device *device, +@@ -722,6 +837,28 @@ static ssize_t w1_slave_store(struct dev + return ret ? : size; + } + ++static ssize_t ext_power_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct w1_slave *sl = dev_to_w1_slave(device); ++ ++ if (!sl->family_data) { ++ dev_info(device, ++ "%s: Device not supported by the driver\n", __func__); ++ return 0; /* No device family */ ++ } ++ ++ /* Getting the power mode of the device {external, parasite} */ ++ SLAVE_POWERMODE(sl) = read_powermode(sl); ++ ++ if (SLAVE_POWERMODE(sl) < 0) { ++ dev_dbg(device, ++ "%s: Power_mode may be corrupted. err=%d\n", ++ __func__, SLAVE_POWERMODE(sl)); ++ } ++ return sprintf(buf, "%d\n", SLAVE_POWERMODE(sl)); ++} ++ + #if IS_REACHABLE(CONFIG_HWMON) + static int w1_read_temp(struct device *device, u32 attr, int channel, + long *val) diff --git a/target/linux/bcm27xx/patches-5.4/950-0769-w1_therm-adding-resolution-sysfs-entry.patch b/target/linux/bcm27xx/patches-5.4/950-0769-w1_therm-adding-resolution-sysfs-entry.patch new file mode 100644 index 0000000000..17b047a0c7 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0769-w1_therm-adding-resolution-sysfs-entry.patch @@ -0,0 +1,713 @@ +From feffc2efed02adda00c6c5480292db012663e6e8 Mon Sep 17 00:00:00 2001 +From: Akira Shimahara <akira215corp@gmail.com> +Date: Mon, 11 May 2020 22:37:08 +0200 +Subject: [PATCH] w1_therm: adding resolution sysfs entry + +commit 308bdb94de0c1abe7eac5193f58638b8aeaddf4b upstream. + +Adding resolution sysfs entry (RW) to get or set the device resolution +Write values are managed as follow: + * '9..12': resolution to set in bit + * Anything else: do nothing +Read values are : + * '9..12': device resolution in bit + * '-xx': xx is kernel error when reading the resolution + +Only supported devices will show the sysfs entry. A new family has been +created for DS18S20 devices as they do not implement resolution feature. + +The resolution of each device is check when the device is +discover by the bus master, in 'w1_therm_add_slave(struct w1_slave *)'. +The status is stored in the device structure w1_therm_family_data so +that the driver always knows the resolution of each device, which could +be used later to determine the required conversion duration (resolution +dependent). + +The resolution is re evaluate each time a user read or write the sysfs +entry. + +To avoid looping through the w1_therm_families at run time, the pointer +'specific_functions' is set up to the correct 'w1_therm_family_converter' +when the slave is added (which mean when it is discovered by the master). +This initialization is done by a helper function +'device_family(struct w1_slave *sl)', and a dedicated macro +'SLAVE_SPECIFIC_FUNC(sl)' allow the access to the specific function of the +slave device. + +'read_scratchpad' and 'write_scratchpad' are the hardware functions to +access the device RAM, as per protocol specification. + +It cancel the former 'precision' functions, which was only set and never +read (so not stored in the device struct). + +Updating Documentation/ABI/testing/sysfs-driver-w1_therm accordingly. + +Signed-off-by: Akira Shimahara <akira215corp@gmail.com> +Link: https://lore.kernel.org/r/20200511203708.410649-1-akira215corp@gmail.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + .../ABI/testing/sysfs-driver-w1_therm | 17 + + drivers/w1/slaves/w1_therm.c | 442 ++++++++++++++---- + 2 files changed, 361 insertions(+), 98 deletions(-) + +--- a/Documentation/ABI/testing/sysfs-driver-w1_therm ++++ b/Documentation/ABI/testing/sysfs-driver-w1_therm +@@ -10,6 +10,23 @@ Users: any user space application which + w1_term device + + ++What: /sys/bus/w1/devices/.../resolution ++Date: May 2020 ++Contact: Akira Shimahara <akira215corp@gmail.com> ++Description: ++ (RW) get or set the device resolution (on supported devices, ++ if not, this entry is not present). Note that the resolution ++ will be changed only in device RAM, so it will be cleared when ++ power is lost. Trigger a 'save' to EEPROM command to keep ++ values after power-on. Read or write are : ++ * '9..12': device resolution in bit ++ or resolution to set in bit ++ * '-xx': xx is kernel error when reading the resolution ++ * Anything else: do nothing ++Users: any user space application which wants to communicate with ++ w1_term device ++ ++ + What: /sys/bus/w1/devices/.../w1_slave + Date: May 2020 + Contact: Akira Shimahara <akira215corp@gmail.com> +--- a/drivers/w1/slaves/w1_therm.c ++++ b/drivers/w1/slaves/w1_therm.c +@@ -52,12 +52,26 @@ module_param_named(strong_pullup, w1_str + /* Helpers Macros */ + + /* ++ * return a pointer on the slave w1_therm_family_converter struct: ++ * always test family data existence before using this macro ++ */ ++#define SLAVE_SPECIFIC_FUNC(sl) \ ++ (((struct w1_therm_family_data *)(sl->family_data))->specific_functions) ++ ++/* + * return the power mode of the sl slave : 1-ext, 0-parasite, <0 unknown + * always test family data existence before using this macro + */ + #define SLAVE_POWERMODE(sl) \ + (((struct w1_therm_family_data *)(sl->family_data))->external_powered) + ++/* ++ * return the resolution in bit of the sl slave : <0 unknown ++ * always test family data existence before using this macro ++ */ ++#define SLAVE_RESOLUTION(sl) \ ++ (((struct w1_therm_family_data *)(sl->family_data))->resolution) ++ + /* return the address of the refcnt in the family data */ + #define THERM_REFCNT(family_data) \ + (&((struct w1_therm_family_data *)family_data)->refcnt) +@@ -70,7 +84,8 @@ module_param_named(strong_pullup, w1_str + * @reserved: not used here + * @f: pointer to the device binding structure + * @convert: pointer to the device conversion function +- * @precision: pointer to the device precision function ++ * @set_resolution: pointer to the device set_resolution function ++ * @get_resolution: pointer to the device get_resolution function + * @eeprom: pointer to eeprom function + */ + struct w1_therm_family_converter { +@@ -78,7 +93,8 @@ struct w1_therm_family_converter { + u16 reserved; + struct w1_family *f; + int (*convert)(u8 rom[9]); +- int (*precision)(struct device *device, int val); ++ int (*set_resolution)(struct w1_slave *sl, int val); ++ int (*get_resolution)(struct w1_slave *sl); + int (*eeprom)(struct device *device); + }; + +@@ -89,11 +105,15 @@ struct w1_therm_family_converter { + * @external_powered: 1 device powered externally, + * 0 device parasite powered, + * -x error or undefined ++ * @resolution: current device resolution ++ * @specific_functions: pointer to struct of device specific function + */ + struct w1_therm_family_data { + uint8_t rom[9]; + atomic_t refcnt; + int external_powered; ++ int resolution; ++ struct w1_therm_family_converter *specific_functions; + }; + + /** +@@ -127,6 +147,25 @@ struct therm_info { + static int reset_select_slave(struct w1_slave *sl); + + /** ++ * read_scratchpad() - read the data in device RAM ++ * @sl: pointer to the slave to read ++ * @info: pointer to a structure to store the read results ++ * ++ * Return: 0 if success, -kernel error code otherwise ++ */ ++static int read_scratchpad(struct w1_slave *sl, struct therm_info *info); ++ ++/** ++ * write_scratchpad() - write nb_bytes in the device RAM ++ * @sl: pointer to the slave to write in ++ * @data: pointer to an array of 3 bytes, as 3 bytes MUST be written ++ * @nb_bytes: number of bytes to be written (2 for DS18S20, 3 otherwise) ++ * ++ * Return: 0 if success, -kernel error code otherwise ++ */ ++static int write_scratchpad(struct w1_slave *sl, const u8 *data, u8 nb_bytes); ++ ++/** + * read_powermode() - Query the power mode of the slave + * @sl: slave to retrieve the power mode + * +@@ -154,11 +193,18 @@ static ssize_t w1_seq_show(struct device + static ssize_t ext_power_show(struct device *device, + struct device_attribute *attr, char *buf); + ++static ssize_t resolution_show(struct device *device, ++ struct device_attribute *attr, char *buf); ++ ++static ssize_t resolution_store(struct device *device, ++ struct device_attribute *attr, const char *buf, size_t size); ++ + /* Attributes declarations */ + + static DEVICE_ATTR_RW(w1_slave); + static DEVICE_ATTR_RO(w1_seq); + static DEVICE_ATTR_RO(ext_power); ++static DEVICE_ATTR_RW(resolution); + + /* Interface Functions declaration */ + +@@ -187,6 +233,13 @@ static void w1_therm_remove_slave(struct + static struct attribute *w1_therm_attrs[] = { + &dev_attr_w1_slave.attr, + &dev_attr_ext_power.attr, ++ &dev_attr_resolution.attr, ++ NULL, ++}; ++ ++static struct attribute *w1_ds18s20_attrs[] = { ++ &dev_attr_w1_slave.attr, ++ &dev_attr_ext_power.attr, + NULL, + }; + +@@ -194,12 +247,14 @@ static struct attribute *w1_ds28ea00_att + &dev_attr_w1_slave.attr, + &dev_attr_w1_seq.attr, + &dev_attr_ext_power.attr, ++ &dev_attr_resolution.attr, + NULL, + }; + + /* Attribute groups */ + + ATTRIBUTE_GROUPS(w1_therm); ++ATTRIBUTE_GROUPS(w1_ds18s20); + ATTRIBUTE_GROUPS(w1_ds28ea00); + + #if IS_REACHABLE(CONFIG_HWMON) +@@ -261,6 +316,13 @@ static struct w1_family_ops w1_therm_fop + .chip_info = W1_CHIPINFO, + }; + ++static struct w1_family_ops w1_ds18s20_fops = { ++ .add_slave = w1_therm_add_slave, ++ .remove_slave = w1_therm_remove_slave, ++ .groups = w1_ds18s20_groups, ++ .chip_info = W1_CHIPINFO, ++}; ++ + static struct w1_family_ops w1_ds28ea00_fops = { + .add_slave = w1_therm_add_slave, + .remove_slave = w1_therm_remove_slave, +@@ -272,7 +334,7 @@ static struct w1_family_ops w1_ds28ea00_ + + static struct w1_family w1_therm_family_DS18S20 = { + .fid = W1_THERM_DS18S20, +- .fops = &w1_therm_fops, ++ .fops = &w1_ds18s20_fops, + }; + + static struct w1_family w1_therm_family_DS18B20 = { +@@ -300,92 +362,67 @@ static struct w1_family w1_therm_family_ + /* write configuration to eeprom */ + static inline int w1_therm_eeprom(struct device *device); + +-/* DS18S20 does not feature configuration register */ +-static inline int w1_DS18S20_precision(struct device *device, int val) ++static inline int w1_DS18B20_write_data(struct w1_slave *sl, ++ const u8 *data) + { +- return 0; ++ return write_scratchpad(sl, data, 3); + } + +-/* Set precision for conversion */ +-static inline int w1_DS18B20_precision(struct device *device, int val) ++static inline int w1_DS18S20_write_data(struct w1_slave *sl, ++ const u8 *data) + { +- struct w1_slave *sl = dev_to_w1_slave(device); +- struct w1_master *dev = sl->master; +- u8 rom[9], crc; +- int ret, max_trying = 10; +- u8 *family_data = sl->family_data; +- uint8_t precision_bits; +- uint8_t mask = 0x60; +- +- if (val > 12 || val < 9) { +- pr_warn("Unsupported precision\n"); +- ret = -EINVAL; +- goto error; +- } +- +- if (!sl->family_data) { +- ret = -ENODEV; +- goto error; +- } +- +- /* prevent the slave from going away in sleep */ +- atomic_inc(THERM_REFCNT(family_data)); ++ /* No config register */ ++ return write_scratchpad(sl, data, 2); ++} + +- ret = mutex_lock_interruptible(&dev->bus_mutex); +- if (ret != 0) +- goto dec_refcnt; ++static inline int w1_DS18B20_set_resolution(struct w1_slave *sl, int val) ++{ ++ int ret = -ENODEV; ++ u8 new_config_register[3]; /* array of data to be written */ ++ struct therm_info info; + +- memset(rom, 0, sizeof(rom)); ++ /* resolution of DS18B20 is in the range [9..12] bits */ ++ if (val < 9 || val > 12) ++ return -EINVAL; ++ ++ val -= 9; /* soustract 9 the lowest resolution in bit */ ++ val = (val << 5); /* shift to position bit 5 & bit 6 */ ++ ++ /* ++ * Read the scratchpad to change only the required bits ++ * (bit5 & bit 6 from byte 4) ++ */ ++ ret = read_scratchpad(sl, &info); ++ if (!ret) { ++ new_config_register[0] = info.rom[2]; ++ new_config_register[1] = info.rom[3]; ++ /* config register is byte 4 & mask 0b10011111*/ ++ new_config_register[2] = (info.rom[4] & 0x9F) | ++ (u8) val; ++ } else ++ return ret; + +- /* translate precision to bitmask (see datasheet page 9) */ +- switch (val) { +- case 9: +- precision_bits = 0x00; +- break; +- case 10: +- precision_bits = 0x20; +- break; +- case 11: +- precision_bits = 0x40; +- break; +- case 12: +- default: +- precision_bits = 0x60; +- break; +- } ++ /* Write data in the device RAM */ ++ ret = w1_DS18B20_write_data(sl, new_config_register); + +- while (max_trying--) { +- crc = 0; ++ return ret; ++} + +- if (!reset_select_slave(sl)) { +- int count = 0; ++static inline int w1_DS18B20_get_resolution(struct w1_slave *sl) ++{ ++ int ret = -ENODEV; ++ u8 config_register; ++ struct therm_info info; + +- /* read values to only alter precision bits */ +- w1_write_8(dev, W1_READ_SCRATCHPAD); +- count = w1_read_block(dev, rom, 9); +- if (count != 9) +- dev_warn(device, "w1_read_block() returned %u instead of 9.\n", count); +- +- crc = w1_calc_crc8(rom, 8); +- if (rom[8] == crc) { +- rom[4] = (rom[4] & ~mask) | (precision_bits & mask); +- +- if (!reset_select_slave(sl)) { +- w1_write_8(dev, W1_WRITE_SCRATCHPAD); +- w1_write_8(dev, rom[2]); +- w1_write_8(dev, rom[3]); +- w1_write_8(dev, rom[4]); ++ ret = read_scratchpad(sl, &info); + +- break; +- } +- } +- } ++ if (!ret) { ++ config_register = info.rom[4]; /* config register is byte 4 */ ++ config_register &= 0x60; /* 0b01100000 keep only bit 5 & 6 */ ++ config_register = (config_register >> 5); /* shift */ ++ config_register += 9; /* add 9 the lowest resolution in bit */ ++ ret = (int) config_register; + } +- +- mutex_unlock(&dev->bus_mutex); +-dec_refcnt: +- atomic_dec(THERM_REFCNT(family_data)); +-error: + return ret; + } + +@@ -438,31 +475,36 @@ static struct w1_therm_family_converter + { + .f = &w1_therm_family_DS18S20, + .convert = w1_DS18S20_convert_temp, +- .precision = w1_DS18S20_precision, ++ .set_resolution = NULL, /* no config register */ ++ .get_resolution = NULL, /* no config register */ + .eeprom = w1_therm_eeprom + }, + { + .f = &w1_therm_family_DS1822, + .convert = w1_DS18B20_convert_temp, +- .precision = w1_DS18S20_precision, ++ .set_resolution = w1_DS18B20_set_resolution, ++ .get_resolution = w1_DS18B20_get_resolution, + .eeprom = w1_therm_eeprom + }, + { + .f = &w1_therm_family_DS18B20, + .convert = w1_DS18B20_convert_temp, +- .precision = w1_DS18B20_precision, ++ .set_resolution = w1_DS18B20_set_resolution, ++ .get_resolution = w1_DS18B20_get_resolution, + .eeprom = w1_therm_eeprom + }, + { + .f = &w1_therm_family_DS28EA00, + .convert = w1_DS18B20_convert_temp, +- .precision = w1_DS18S20_precision, ++ .set_resolution = w1_DS18B20_set_resolution, ++ .get_resolution = w1_DS18B20_get_resolution, + .eeprom = w1_therm_eeprom + }, + { + .f = &w1_therm_family_DS1825, + .convert = w1_DS18B20_convert_temp, +- .precision = w1_DS18S20_precision, ++ .set_resolution = w1_DS18B20_set_resolution, ++ .get_resolution = w1_DS18B20_get_resolution, + .eeprom = w1_therm_eeprom + } + }; +@@ -470,6 +512,26 @@ static struct w1_therm_family_converter + /* Helpers Functions */ + + /** ++ * device_family() - Retrieve a pointer on &struct w1_therm_family_converter ++ * @sl: slave to retrieve the device specific structure ++ * ++ * Return: pointer to the slaves's family converter, NULL if not known ++ */ ++static struct w1_therm_family_converter *device_family(struct w1_slave *sl) ++{ ++ struct w1_therm_family_converter *ret = NULL; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(w1_therm_families); ++i) { ++ if (w1_therm_families[i].f->fid == sl->family->fid) { ++ ret = &w1_therm_families[i]; ++ break; ++ } ++ } ++ return ret; ++} ++ ++/** + * bus_mutex_lock() - Acquire the mutex + * @lock: w1 bus mutex to acquire + * +@@ -522,6 +584,9 @@ static inline int w1_convert_temp(u8 rom + + static int w1_therm_add_slave(struct w1_slave *sl) + { ++ struct w1_therm_family_converter *sl_family_conv; ++ ++ /* Allocate memory */ + sl->family_data = kzalloc(sizeof(struct w1_therm_family_data), + GFP_KERNEL); + if (!sl->family_data) +@@ -529,6 +594,15 @@ static int w1_therm_add_slave(struct w1_ + + atomic_set(THERM_REFCNT(sl->family_data), 1); + ++ /* Get a pointer to the device specific function struct */ ++ sl_family_conv = device_family(sl); ++ if (!sl_family_conv) { ++ kfree(sl->family_data); ++ return -ENODEV; ++ } ++ /* save this pointer to the device structure */ ++ SLAVE_SPECIFIC_FUNC(sl) = sl_family_conv; ++ + /* Getting the power mode of the device {external, parasite} */ + SLAVE_POWERMODE(sl) = read_powermode(sl); + +@@ -539,6 +613,18 @@ static int w1_therm_add_slave(struct w1_ + __func__, SLAVE_POWERMODE(sl)); + } + ++ /* Getting the resolution of the device */ ++ if (SLAVE_SPECIFIC_FUNC(sl)->get_resolution) { ++ SLAVE_RESOLUTION(sl) = ++ SLAVE_SPECIFIC_FUNC(sl)->get_resolution(sl); ++ if (SLAVE_RESOLUTION(sl) < 0) { ++ /* no error returned as device has been added */ ++ dev_warn(&sl->dev, ++ "%s:Device has been added, but resolution may be corrupted. err=%d\n", ++ __func__, SLAVE_RESOLUTION(sl)); ++ } ++ } ++ + return 0; + } + +@@ -665,6 +751,93 @@ error: + return ret; + } + ++static int read_scratchpad(struct w1_slave *sl, struct therm_info *info) ++{ ++ struct w1_master *dev_master = sl->master; ++ int max_trying = W1_THERM_MAX_TRY; ++ int ret = -ENODEV; ++ ++ info->verdict = 0; ++ ++ if (!sl->family_data) ++ goto error; ++ ++ memset(info->rom, 0, sizeof(info->rom)); ++ ++ /* prevent the slave from going away in sleep */ ++ atomic_inc(THERM_REFCNT(sl->family_data)); ++ ++ if (!bus_mutex_lock(&dev_master->bus_mutex)) { ++ ret = -EAGAIN; /* Didn't acquire the mutex */ ++ goto dec_refcnt; ++ } ++ ++ while (max_trying-- && ret) { /* ret should be 0 */ ++ /* safe version to select slave */ ++ if (!reset_select_slave(sl)) { ++ u8 nb_bytes_read; ++ ++ w1_write_8(dev_master, W1_READ_SCRATCHPAD); ++ ++ nb_bytes_read = w1_read_block(dev_master, info->rom, 9); ++ if (nb_bytes_read != 9) { ++ dev_warn(&sl->dev, ++ "w1_read_block(): returned %u instead of 9.\n", ++ nb_bytes_read); ++ ret = -EIO; ++ } ++ ++ info->crc = w1_calc_crc8(info->rom, 8); ++ ++ if (info->rom[8] == info->crc) { ++ info->verdict = 1; ++ ret = 0; ++ } else ++ ret = -EIO; /* CRC not checked */ ++ } ++ ++ } ++ mutex_unlock(&dev_master->bus_mutex); ++ ++dec_refcnt: ++ atomic_dec(THERM_REFCNT(sl->family_data)); ++error: ++ return ret; ++} ++ ++static int write_scratchpad(struct w1_slave *sl, const u8 *data, u8 nb_bytes) ++{ ++ struct w1_master *dev_master = sl->master; ++ int max_trying = W1_THERM_MAX_TRY; ++ int ret = -ENODEV; ++ ++ if (!sl->family_data) ++ goto error; ++ ++ /* prevent the slave from going away in sleep */ ++ atomic_inc(THERM_REFCNT(sl->family_data)); ++ ++ if (!bus_mutex_lock(&dev_master->bus_mutex)) { ++ ret = -EAGAIN; /* Didn't acquire the mutex */ ++ goto dec_refcnt; ++ } ++ ++ while (max_trying-- && ret) { /* ret should be 0 */ ++ /* safe version to select slave */ ++ if (!reset_select_slave(sl)) { ++ w1_write_8(dev_master, W1_WRITE_SCRATCHPAD); ++ w1_write_block(dev_master, data, nb_bytes); ++ ret = 0; ++ } ++ } ++ mutex_unlock(&dev_master->bus_mutex); ++ ++dec_refcnt: ++ atomic_dec(THERM_REFCNT(sl->family_data)); ++error: ++ return ret; ++} ++ + static inline int w1_therm_eeprom(struct device *device) + { + struct w1_slave *sl = dev_to_w1_slave(device); +@@ -815,26 +988,38 @@ static ssize_t w1_slave_store(struct dev + struct device_attribute *attr, const char *buf, + size_t size) + { +- int val, ret; ++ int val, ret = 0; + struct w1_slave *sl = dev_to_w1_slave(device); +- int i; + +- ret = kstrtoint(buf, 0, &val); +- if (ret) +- return ret; ++ ret = kstrtoint(buf, 10, &val); /* converting user entry to int */ + +- for (i = 0; i < ARRAY_SIZE(w1_therm_families); ++i) { +- if (w1_therm_families[i].f->fid == sl->family->fid) { +- /* zero value indicates to write current configuration to eeprom */ +- if (val == 0) +- ret = w1_therm_families[i].eeprom(device); +- else +- ret = w1_therm_families[i].precision(device, +- val); +- break; +- } ++ if (ret) { /* conversion error */ ++ dev_info(device, ++ "%s: conversion error. err= %d\n", __func__, ret); ++ return size; /* return size to avoid call back again */ ++ } ++ ++ if ((!sl->family_data) || (!SLAVE_SPECIFIC_FUNC(sl))) { ++ dev_info(device, ++ "%s: Device not supported by the driver\n", __func__); ++ return size; /* No device family */ ++ } ++ ++ if (val == 0) /* val=0 : trigger a EEPROM save */ ++ ret = SLAVE_SPECIFIC_FUNC(sl)->eeprom(device); ++ else { ++ if (SLAVE_SPECIFIC_FUNC(sl)->set_resolution) ++ ret = SLAVE_SPECIFIC_FUNC(sl)->set_resolution(sl, val); + } +- return ret ? : size; ++ ++ if (ret) { ++ dev_info(device, ++ "%s: writing error %d\n", __func__, ret); ++ /* return size to avoid call back again */ ++ } else ++ SLAVE_RESOLUTION(sl) = val; ++ ++ return size; /* always return size to avoid infinite calling */ + } + + static ssize_t ext_power_show(struct device *device, +@@ -859,6 +1044,67 @@ static ssize_t ext_power_show(struct dev + return sprintf(buf, "%d\n", SLAVE_POWERMODE(sl)); + } + ++static ssize_t resolution_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct w1_slave *sl = dev_to_w1_slave(device); ++ ++ if ((!sl->family_data) || (!SLAVE_SPECIFIC_FUNC(sl))) { ++ dev_info(device, ++ "%s: Device not supported by the driver\n", __func__); ++ return 0; /* No device family */ ++ } ++ ++ /* get the correct function depending on the device */ ++ SLAVE_RESOLUTION(sl) = SLAVE_SPECIFIC_FUNC(sl)->get_resolution(sl); ++ if (SLAVE_RESOLUTION(sl) < 0) { ++ dev_dbg(device, ++ "%s: Resolution may be corrupted. err=%d\n", ++ __func__, SLAVE_RESOLUTION(sl)); ++ } ++ ++ return sprintf(buf, "%d\n", SLAVE_RESOLUTION(sl)); ++} ++ ++static ssize_t resolution_store(struct device *device, ++ struct device_attribute *attr, const char *buf, size_t size) ++{ ++ struct w1_slave *sl = dev_to_w1_slave(device); ++ int val; ++ int ret = 0; ++ ++ ret = kstrtoint(buf, 10, &val); /* converting user entry to int */ ++ ++ if (ret) { /* conversion error */ ++ dev_info(device, ++ "%s: conversion error. err= %d\n", __func__, ret); ++ return size; /* return size to avoid call back again */ ++ } ++ ++ if ((!sl->family_data) || (!SLAVE_SPECIFIC_FUNC(sl))) { ++ dev_info(device, ++ "%s: Device not supported by the driver\n", __func__); ++ return size; /* No device family */ ++ } ++ ++ /* ++ * Don't deal with the val enterd by user, ++ * only device knows what is correct or not ++ */ ++ ++ /* get the correct function depending on the device */ ++ ret = SLAVE_SPECIFIC_FUNC(sl)->set_resolution(sl, val); ++ ++ if (ret) { ++ dev_info(device, ++ "%s: writing error %d\n", __func__, ret); ++ /* return size to avoid call back again */ ++ } else ++ SLAVE_RESOLUTION(sl) = val; ++ ++ return size; ++} ++ + #if IS_REACHABLE(CONFIG_HWMON) + static int w1_read_temp(struct device *device, u32 attr, int channel, + long *val) diff --git a/target/linux/bcm27xx/patches-5.4/950-0770-w1_therm-adding-eeprom-sysfs-entry.patch b/target/linux/bcm27xx/patches-5.4/950-0770-w1_therm-adding-eeprom-sysfs-entry.patch new file mode 100644 index 0000000000..58467a00c3 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0770-w1_therm-adding-eeprom-sysfs-entry.patch @@ -0,0 +1,372 @@ +From 855a8d82506c7c2428e13beebe8dbf7739ea6176 Mon Sep 17 00:00:00 2001 +From: Akira Shimahara <akira215corp@gmail.com> +Date: Mon, 11 May 2020 22:37:25 +0200 +Subject: [PATCH] w1_therm: adding eeprom sysfs entry + +commit 45d457a4cf24455eefd076a01a3d86414fc2ff1e upstream. + +The driver implement 2 hardware functions to access device RAM: + * copy_scratchpad + * recall_scratchpad +They act according to device specifications. + +As EEPROM operations are not device dependent (all w1_therm can perform +EEPROM read/write operation following the same protocol), it is removed +from device families structures. + +Updating Documentation/ABI/testing/sysfs-driver-w1_therm accordingly. + +Signed-off-by: Akira Shimahara <akira215corp@gmail.com> +Link: https://lore.kernel.org/r/20200511203725.410844-1-akira215corp@gmail.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + .../ABI/testing/sysfs-driver-w1_therm | 14 ++ + drivers/w1/slaves/w1_therm.c | 175 ++++++++++++------ + 2 files changed, 132 insertions(+), 57 deletions(-) + +--- a/Documentation/ABI/testing/sysfs-driver-w1_therm ++++ b/Documentation/ABI/testing/sysfs-driver-w1_therm +@@ -1,3 +1,17 @@ ++What: /sys/bus/w1/devices/.../eeprom ++Date: May 2020 ++Contact: Akira Shimahara <akira215corp@gmail.com> ++Description: ++ (WO) writing that file will either trigger a save of the ++ device data to its embedded EEPROM, either restore data ++ embedded in device EEPROM. Be aware that devices support ++ limited EEPROM writing cycles (typical 50k) ++ * 'save': save device RAM to EEPROM ++ * 'restore': restore EEPROM data in device RAM ++Users: any user space application which wants to communicate with ++ w1_term device ++ ++ + What: /sys/bus/w1/devices/.../ext_power + Date: May 2020 + Contact: Akira Shimahara <akira215corp@gmail.com> +--- a/drivers/w1/slaves/w1_therm.c ++++ b/drivers/w1/slaves/w1_therm.c +@@ -43,12 +43,21 @@ + static int w1_strong_pullup = 1; + module_param_named(strong_pullup, w1_strong_pullup, int, 0); + ++/* This command should be in public header w1.h but is not */ ++#define W1_RECALL_EEPROM 0xB8 ++ + /* Nb of try for an operation */ + #define W1_THERM_MAX_TRY 5 + + /* ms delay to retry bus mutex */ + #define W1_THERM_RETRY_DELAY 20 + ++/* delay in ms to write in EEPROM */ ++#define W1_THERM_EEPROM_WRITE_DELAY 10 ++ ++#define EEPROM_CMD_WRITE "save" /* cmd for write eeprom sysfs */ ++#define EEPROM_CMD_READ "restore" /* cmd for read eeprom sysfs */ ++ + /* Helpers Macros */ + + /* +@@ -86,7 +95,6 @@ module_param_named(strong_pullup, w1_str + * @convert: pointer to the device conversion function + * @set_resolution: pointer to the device set_resolution function + * @get_resolution: pointer to the device get_resolution function +- * @eeprom: pointer to eeprom function + */ + struct w1_therm_family_converter { + u8 broken; +@@ -95,7 +103,6 @@ struct w1_therm_family_converter { + int (*convert)(u8 rom[9]); + int (*set_resolution)(struct w1_slave *sl, int val); + int (*get_resolution)(struct w1_slave *sl); +- int (*eeprom)(struct device *device); + }; + + /** +@@ -166,6 +173,22 @@ static int read_scratchpad(struct w1_sla + static int write_scratchpad(struct w1_slave *sl, const u8 *data, u8 nb_bytes); + + /** ++ * copy_scratchpad() - Copy the content of scratchpad in device EEPROM ++ * @sl: slave involved ++ * ++ * Return: 0 if success, -kernel error code otherwise ++ */ ++static int copy_scratchpad(struct w1_slave *sl); ++ ++/** ++ * recall_eeprom() - Restore EEPROM data to device RAM ++ * @sl: slave involved ++ * ++ * Return: 0 if success, -kernel error code otherwise ++ */ ++static int recall_eeprom(struct w1_slave *sl); ++ ++/** + * read_powermode() - Query the power mode of the slave + * @sl: slave to retrieve the power mode + * +@@ -199,12 +222,16 @@ static ssize_t resolution_show(struct de + static ssize_t resolution_store(struct device *device, + struct device_attribute *attr, const char *buf, size_t size); + ++static ssize_t eeprom_store(struct device *device, ++ struct device_attribute *attr, const char *buf, size_t size); ++ + /* Attributes declarations */ + + static DEVICE_ATTR_RW(w1_slave); + static DEVICE_ATTR_RO(w1_seq); + static DEVICE_ATTR_RO(ext_power); + static DEVICE_ATTR_RW(resolution); ++static DEVICE_ATTR_WO(eeprom); + + /* Interface Functions declaration */ + +@@ -234,12 +261,14 @@ static struct attribute *w1_therm_attrs[ + &dev_attr_w1_slave.attr, + &dev_attr_ext_power.attr, + &dev_attr_resolution.attr, ++ &dev_attr_eeprom.attr, + NULL, + }; + + static struct attribute *w1_ds18s20_attrs[] = { + &dev_attr_w1_slave.attr, + &dev_attr_ext_power.attr, ++ &dev_attr_eeprom.attr, + NULL, + }; + +@@ -248,6 +277,7 @@ static struct attribute *w1_ds28ea00_att + &dev_attr_w1_seq.attr, + &dev_attr_ext_power.attr, + &dev_attr_resolution.attr, ++ &dev_attr_eeprom.attr, + NULL, + }; + +@@ -359,9 +389,6 @@ static struct w1_family w1_therm_family_ + + /* Device dependent func */ + +-/* write configuration to eeprom */ +-static inline int w1_therm_eeprom(struct device *device); +- + static inline int w1_DS18B20_write_data(struct w1_slave *sl, + const u8 *data) + { +@@ -477,35 +504,30 @@ static struct w1_therm_family_converter + .convert = w1_DS18S20_convert_temp, + .set_resolution = NULL, /* no config register */ + .get_resolution = NULL, /* no config register */ +- .eeprom = w1_therm_eeprom + }, + { + .f = &w1_therm_family_DS1822, + .convert = w1_DS18B20_convert_temp, + .set_resolution = w1_DS18B20_set_resolution, + .get_resolution = w1_DS18B20_get_resolution, +- .eeprom = w1_therm_eeprom + }, + { + .f = &w1_therm_family_DS18B20, + .convert = w1_DS18B20_convert_temp, + .set_resolution = w1_DS18B20_set_resolution, + .get_resolution = w1_DS18B20_get_resolution, +- .eeprom = w1_therm_eeprom + }, + { + .f = &w1_therm_family_DS28EA00, + .convert = w1_DS18B20_convert_temp, + .set_resolution = w1_DS18B20_set_resolution, + .get_resolution = w1_DS18B20_get_resolution, +- .eeprom = w1_therm_eeprom + }, + { + .f = &w1_therm_family_DS1825, + .convert = w1_DS18B20_convert_temp, + .set_resolution = w1_DS18B20_set_resolution, + .get_resolution = w1_DS18B20_get_resolution, +- .eeprom = w1_therm_eeprom + } + }; + +@@ -838,75 +860,94 @@ error: + return ret; + } + +-static inline int w1_therm_eeprom(struct device *device) ++static int copy_scratchpad(struct w1_slave *sl) + { +- struct w1_slave *sl = dev_to_w1_slave(device); +- struct w1_master *dev = sl->master; +- u8 rom[9], external_power; +- int ret, max_trying = 10; +- u8 *family_data = sl->family_data; ++ struct w1_master *dev_master = sl->master; ++ int max_trying = W1_THERM_MAX_TRY; ++ int t_write, ret = -ENODEV; ++ bool strong_pullup; + +- if (!sl->family_data) { +- ret = -ENODEV; ++ if (!sl->family_data) + goto error; +- } ++ ++ t_write = W1_THERM_EEPROM_WRITE_DELAY; ++ strong_pullup = (w1_strong_pullup == 2 || ++ (!SLAVE_POWERMODE(sl) && ++ w1_strong_pullup)); + + /* prevent the slave from going away in sleep */ +- atomic_inc(THERM_REFCNT(family_data)); ++ atomic_inc(THERM_REFCNT(sl->family_data)); + +- ret = mutex_lock_interruptible(&dev->bus_mutex); +- if (ret != 0) ++ if (!bus_mutex_lock(&dev_master->bus_mutex)) { ++ ret = -EAGAIN; /* Didn't acquire the mutex */ + goto dec_refcnt; ++ } + +- memset(rom, 0, sizeof(rom)); +- +- while (max_trying--) { ++ while (max_trying-- && ret) { /* ret should be 0 */ ++ /* safe version to select slave */ + if (!reset_select_slave(sl)) { +- unsigned int tm = 10; + unsigned long sleep_rem; + +- /* check if in parasite mode */ +- w1_write_8(dev, W1_READ_PSUPPLY); +- external_power = w1_read_8(dev); +- +- if (reset_select_slave(sl)) +- continue; +- +- /* 10ms strong pullup/delay after the copy command */ +- if (w1_strong_pullup == 2 || +- (!external_power && w1_strong_pullup)) +- w1_next_pullup(dev, tm); +- +- w1_write_8(dev, W1_COPY_SCRATCHPAD); +- +- if (external_power) { +- mutex_unlock(&dev->bus_mutex); ++ /* 10ms strong pullup (or delay) after the convert */ ++ if (strong_pullup) ++ w1_next_pullup(dev_master, t_write); + +- sleep_rem = msleep_interruptible(tm); +- if (sleep_rem != 0) { +- ret = -EINTR; +- goto dec_refcnt; +- } ++ w1_write_8(dev_master, W1_COPY_SCRATCHPAD); + +- ret = mutex_lock_interruptible(&dev->bus_mutex); +- if (ret != 0) +- goto dec_refcnt; +- } else if (!w1_strong_pullup) { +- sleep_rem = msleep_interruptible(tm); ++ if (strong_pullup) { ++ sleep_rem = msleep_interruptible(t_write); + if (sleep_rem != 0) { + ret = -EINTR; + goto mt_unlock; + } + } +- +- break; ++ ret = 0; + } ++ + } + + mt_unlock: +- mutex_unlock(&dev->bus_mutex); ++ mutex_unlock(&dev_master->bus_mutex); + dec_refcnt: +- atomic_dec(THERM_REFCNT(family_data)); ++ atomic_dec(THERM_REFCNT(sl->family_data)); ++error: ++ return ret; ++} ++ ++static int recall_eeprom(struct w1_slave *sl) ++{ ++ struct w1_master *dev_master = sl->master; ++ int max_trying = W1_THERM_MAX_TRY; ++ int ret = -ENODEV; ++ ++ if (!sl->family_data) ++ goto error; ++ ++ /* prevent the slave from going away in sleep */ ++ atomic_inc(THERM_REFCNT(sl->family_data)); ++ ++ if (!bus_mutex_lock(&dev_master->bus_mutex)) { ++ ret = -EAGAIN; /* Didn't acquire the mutex */ ++ goto dec_refcnt; ++ } ++ ++ while (max_trying-- && ret) { /* ret should be 0 */ ++ /* safe version to select slave */ ++ if (!reset_select_slave(sl)) { ++ ++ w1_write_8(dev_master, W1_RECALL_EEPROM); ++ ++ ret = 1; /* Slave will pull line to 0 */ ++ while (ret) ++ ret = 1 - w1_touch_bit(dev_master, 1); ++ } ++ ++ } ++ ++ mutex_unlock(&dev_master->bus_mutex); ++ ++dec_refcnt: ++ atomic_dec(THERM_REFCNT(sl->family_data)); + error: + return ret; + } +@@ -1006,7 +1047,7 @@ static ssize_t w1_slave_store(struct dev + } + + if (val == 0) /* val=0 : trigger a EEPROM save */ +- ret = SLAVE_SPECIFIC_FUNC(sl)->eeprom(device); ++ ret = copy_scratchpad(sl); + else { + if (SLAVE_SPECIFIC_FUNC(sl)->set_resolution) + ret = SLAVE_SPECIFIC_FUNC(sl)->set_resolution(sl, val); +@@ -1104,6 +1145,26 @@ static ssize_t resolution_store(struct d + + return size; + } ++ ++static ssize_t eeprom_store(struct device *device, ++ struct device_attribute *attr, const char *buf, size_t size) ++{ ++ struct w1_slave *sl = dev_to_w1_slave(device); ++ int ret = -EINVAL; /* Invalid argument */ ++ ++ if (size == sizeof(EEPROM_CMD_WRITE)) { ++ if (!strncmp(buf, EEPROM_CMD_WRITE, sizeof(EEPROM_CMD_WRITE)-1)) ++ ret = copy_scratchpad(sl); ++ } else if (size == sizeof(EEPROM_CMD_READ)) { ++ if (!strncmp(buf, EEPROM_CMD_READ, sizeof(EEPROM_CMD_READ)-1)) ++ ret = recall_eeprom(sl); ++ } ++ ++ if (ret) ++ dev_info(device, "%s: error in process %d\n", __func__, ret); ++ ++ return size; ++} + + #if IS_REACHABLE(CONFIG_HWMON) + static int w1_read_temp(struct device *device, u32 attr, int channel, diff --git a/target/linux/bcm27xx/patches-5.4/950-0771-w1_therm-optimizing-temperature-read-timings.patch b/target/linux/bcm27xx/patches-5.4/950-0771-w1_therm-optimizing-temperature-read-timings.patch new file mode 100644 index 0000000000..142560c6da --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0771-w1_therm-optimizing-temperature-read-timings.patch @@ -0,0 +1,528 @@ +From 23769ad113407ceb21a4285a8194c7d788149269 Mon Sep 17 00:00:00 2001 +From: Akira Shimahara <akira215corp@gmail.com> +Date: Mon, 11 May 2020 22:37:42 +0200 +Subject: [PATCH] w1_therm: optimizing temperature read timings + +commit 67b392f7b8edfa6f427fecd98722acab34c1c99f upstream. + +Optimizing temperature reading by reducing waiting conversion time +according to device resolution settings, as per device specification. +This is device dependent as not all the devices supports resolution +setting, so it has been added in device family structures. + +The process to read the temperature on the device has been adapted in a +new function 'convert_t()', which replace the former 'read_therm()', is +introduce to deal with this timing. Strong pull up is also applied during +the required time, according to device power status needs and +'strong_pullup' module parameter. + +'temperature_from_RAM()' function is introduced to get the correct +temperature computation (device dependent) from device RAM data. + +An new sysfs entry has been added to ouptut only temperature. The old +entry w1_slave has been kept for compatibility, without changing its +output format. + +Updating Documentation/ABI/testing/sysfs-driver-w1_therm accordingly. + +Signed-off-by: Akira Shimahara <akira215corp@gmail.com> +Link: https://lore.kernel.org/r/20200511203742.411039-1-akira215corp@gmail.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + .../ABI/testing/sysfs-driver-w1_therm | 12 + + drivers/w1/slaves/w1_therm.c | 286 +++++++++++------- + 2 files changed, 197 insertions(+), 101 deletions(-) + +--- a/Documentation/ABI/testing/sysfs-driver-w1_therm ++++ b/Documentation/ABI/testing/sysfs-driver-w1_therm +@@ -41,6 +41,18 @@ Users: any user space application which + w1_term device + + ++What: /sys/bus/w1/devices/.../temperature ++Date: May 2020 ++Contact: Akira Shimahara <akira215corp@gmail.com> ++Description: ++ (RO) return the temperature in 1/1000 degC. ++ Note that the conversion duration depend on the resolution (if ++ device support this feature). It takes 94ms in 9bits ++ resolution, 750ms for 12bits. ++Users: any user space application which wants to communicate with ++ w1_term device ++ ++ + What: /sys/bus/w1/devices/.../w1_slave + Date: May 2020 + Contact: Akira Shimahara <akira215corp@gmail.com> +--- a/drivers/w1/slaves/w1_therm.c ++++ b/drivers/w1/slaves/w1_therm.c +@@ -93,6 +93,7 @@ module_param_named(strong_pullup, w1_str + * @reserved: not used here + * @f: pointer to the device binding structure + * @convert: pointer to the device conversion function ++ * @get_conversion_time: pointer to the device conversion time function + * @set_resolution: pointer to the device set_resolution function + * @get_resolution: pointer to the device get_resolution function + */ +@@ -101,6 +102,7 @@ struct w1_therm_family_converter { + u16 reserved; + struct w1_family *f; + int (*convert)(u8 rom[9]); ++ int (*get_conversion_time)(struct w1_slave *sl); + int (*set_resolution)(struct w1_slave *sl, int val); + int (*get_resolution)(struct w1_slave *sl); + }; +@@ -154,6 +156,15 @@ struct therm_info { + static int reset_select_slave(struct w1_slave *sl); + + /** ++ * convert_t() - Query the device for temperature conversion and read ++ * @sl: pointer to the slave to read ++ * @info: pointer to a structure to store the read results ++ * ++ * Return: 0 if success, -kernel error code otherwise ++ */ ++static int convert_t(struct w1_slave *sl, struct therm_info *info); ++ ++/** + * read_scratchpad() - read the data in device RAM + * @sl: pointer to the slave to read + * @info: pointer to a structure to store the read results +@@ -213,6 +224,9 @@ static ssize_t w1_slave_store(struct dev + static ssize_t w1_seq_show(struct device *device, + struct device_attribute *attr, char *buf); + ++static ssize_t temperature_show(struct device *device, ++ struct device_attribute *attr, char *buf); ++ + static ssize_t ext_power_show(struct device *device, + struct device_attribute *attr, char *buf); + +@@ -229,6 +243,7 @@ static ssize_t eeprom_store(struct devic + + static DEVICE_ATTR_RW(w1_slave); + static DEVICE_ATTR_RO(w1_seq); ++static DEVICE_ATTR_RO(temperature); + static DEVICE_ATTR_RO(ext_power); + static DEVICE_ATTR_RW(resolution); + static DEVICE_ATTR_WO(eeprom); +@@ -259,6 +274,7 @@ static void w1_therm_remove_slave(struct + + static struct attribute *w1_therm_attrs[] = { + &dev_attr_w1_slave.attr, ++ &dev_attr_temperature.attr, + &dev_attr_ext_power.attr, + &dev_attr_resolution.attr, + &dev_attr_eeprom.attr, +@@ -267,6 +283,7 @@ static struct attribute *w1_therm_attrs[ + + static struct attribute *w1_ds18s20_attrs[] = { + &dev_attr_w1_slave.attr, ++ &dev_attr_temperature.attr, + &dev_attr_ext_power.attr, + &dev_attr_eeprom.attr, + NULL, +@@ -275,6 +292,7 @@ static struct attribute *w1_ds18s20_attr + static struct attribute *w1_ds28ea00_attrs[] = { + &dev_attr_w1_slave.attr, + &dev_attr_w1_seq.attr, ++ &dev_attr_temperature.attr, + &dev_attr_ext_power.attr, + &dev_attr_resolution.attr, + &dev_attr_eeprom.attr, +@@ -389,6 +407,37 @@ static struct w1_family w1_therm_family_ + + /* Device dependent func */ + ++static inline int w1_DS18B20_convert_time(struct w1_slave *sl) ++{ ++ int ret; ++ ++ if (!sl->family_data) ++ return -ENODEV; /* device unknown */ ++ ++ /* return time in ms for conversion operation */ ++ switch (SLAVE_RESOLUTION(sl)) { ++ case 9: ++ ret = 95; ++ break; ++ case 10: ++ ret = 190; ++ break; ++ case 11: ++ ret = 375; ++ break; ++ case 12: ++ default: ++ ret = 750; ++ } ++ return ret; ++} ++ ++static inline int w1_DS18S20_convert_time(struct w1_slave *sl) ++{ ++ (void)(sl); ++ return 750; /* always 750ms for DS18S20 */ ++} ++ + static inline int w1_DS18B20_write_data(struct w1_slave *sl, + const u8 *data) + { +@@ -480,8 +529,10 @@ static inline int w1_DS18S20_convert_tem + { + int t, h; + +- if (!rom[7]) ++ if (!rom[7]) { ++ pr_debug("%s: Invalid argument for conversion\n", __func__); + return 0; ++ } + + if (rom[1] == 0) + t = ((s32)rom[0] >> 1)*1000; +@@ -500,34 +551,39 @@ static inline int w1_DS18S20_convert_tem + + static struct w1_therm_family_converter w1_therm_families[] = { + { +- .f = &w1_therm_family_DS18S20, +- .convert = w1_DS18S20_convert_temp, +- .set_resolution = NULL, /* no config register */ +- .get_resolution = NULL, /* no config register */ ++ .f = &w1_therm_family_DS18S20, ++ .convert = w1_DS18S20_convert_temp, ++ .get_conversion_time = w1_DS18S20_convert_time, ++ .set_resolution = NULL, /* no config register */ ++ .get_resolution = NULL, /* no config register */ + }, + { +- .f = &w1_therm_family_DS1822, +- .convert = w1_DS18B20_convert_temp, +- .set_resolution = w1_DS18B20_set_resolution, +- .get_resolution = w1_DS18B20_get_resolution, ++ .f = &w1_therm_family_DS1822, ++ .convert = w1_DS18B20_convert_temp, ++ .get_conversion_time = w1_DS18B20_convert_time, ++ .set_resolution = w1_DS18B20_set_resolution, ++ .get_resolution = w1_DS18B20_get_resolution, + }, + { +- .f = &w1_therm_family_DS18B20, +- .convert = w1_DS18B20_convert_temp, +- .set_resolution = w1_DS18B20_set_resolution, +- .get_resolution = w1_DS18B20_get_resolution, ++ .f = &w1_therm_family_DS18B20, ++ .convert = w1_DS18B20_convert_temp, ++ .get_conversion_time = w1_DS18B20_convert_time, ++ .set_resolution = w1_DS18B20_set_resolution, ++ .get_resolution = w1_DS18B20_get_resolution, + }, + { +- .f = &w1_therm_family_DS28EA00, +- .convert = w1_DS18B20_convert_temp, +- .set_resolution = w1_DS18B20_set_resolution, +- .get_resolution = w1_DS18B20_get_resolution, ++ .f = &w1_therm_family_DS28EA00, ++ .convert = w1_DS18B20_convert_temp, ++ .get_conversion_time = w1_DS18B20_convert_time, ++ .set_resolution = w1_DS18B20_set_resolution, ++ .get_resolution = w1_DS18B20_get_resolution, + }, + { +- .f = &w1_therm_family_DS1825, +- .convert = w1_DS18B20_convert_temp, +- .set_resolution = w1_DS18B20_set_resolution, +- .get_resolution = w1_DS18B20_get_resolution, ++ .f = &w1_therm_family_DS1825, ++ .convert = w1_DS18B20_convert_temp, ++ .get_conversion_time = w1_DS18B20_convert_time, ++ .set_resolution = w1_DS18B20_set_resolution, ++ .get_resolution = w1_DS18B20_get_resolution, + } + }; + +@@ -582,24 +638,44 @@ static inline bool bus_mutex_lock(struct + } + + /** +- * w1_convert_temp() - temperature conversion binding function +- * @rom: data read from device RAM (8 data bytes + 1 CRC byte) +- * @fid: device family id ++ * conversion_time() - get the Tconv for the slave ++ * @sl: device to get the conversion time + * +- * The function call the temperature computation function according to +- * device family. ++ * On device supporting resolution settings, conversion time depend ++ * on the resolution setting. This helper function get the slave timing, ++ * depending on its current setting. + * +- * Return: value in millidegrees Celsius. ++ * Return: conversion time in ms, negative values are kernel error code + */ +-static inline int w1_convert_temp(u8 rom[9], u8 fid) ++static inline int conversion_time(struct w1_slave *sl) + { +- int i; ++ if (SLAVE_SPECIFIC_FUNC(sl)) ++ return SLAVE_SPECIFIC_FUNC(sl)->get_conversion_time(sl); + +- for (i = 0; i < ARRAY_SIZE(w1_therm_families); ++i) +- if (w1_therm_families[i].f->fid == fid) +- return w1_therm_families[i].convert(rom); ++ dev_info(&sl->dev, ++ "%s: Device not supported by the driver\n", __func__); + +- return 0; ++ return -ENODEV; /* No device family */ ++} ++ ++/** ++ * temperature_from_RAM() - Convert the read info to temperature ++ * @sl: device that sent the RAM data ++ * @rom: read value on the slave device RAM ++ * ++ * Device dependent, the function bind the correct computation method. ++ * ++ * Return: temperature in 1/1000degC, 0 on error. ++ */ ++static inline int temperature_from_RAM(struct w1_slave *sl, u8 rom[9]) ++{ ++ if (SLAVE_SPECIFIC_FUNC(sl)) ++ return SLAVE_SPECIFIC_FUNC(sl)->convert(rom); ++ ++ dev_info(&sl->dev, ++ "%s: Device not supported by the driver\n", __func__); ++ ++ return 0; /* No device family */ + } + + /* Interface Functions */ +@@ -679,96 +755,74 @@ static int reset_select_slave(struct w1_ + return 0; + } + +-static ssize_t read_therm(struct device *device, +- struct w1_slave *sl, struct therm_info *info) ++static int convert_t(struct w1_slave *sl, struct therm_info *info) + { +- struct w1_master *dev = sl->master; +- u8 external_power; +- int ret, max_trying = 10; +- u8 *family_data = sl->family_data; ++ struct w1_master *dev_master = sl->master; ++ int max_trying = W1_THERM_MAX_TRY; ++ int t_conv; ++ int ret = -ENODEV; ++ bool strong_pullup; + +- if (!family_data) { +- ret = -ENODEV; ++ if (!sl->family_data) + goto error; +- } + +- /* prevent the slave from going away in sleep */ +- atomic_inc(THERM_REFCNT(family_data)); ++ strong_pullup = (w1_strong_pullup == 2 || ++ (!SLAVE_POWERMODE(sl) && ++ w1_strong_pullup)); + +- ret = mutex_lock_interruptible(&dev->bus_mutex); +- if (ret != 0) +- goto dec_refcnt; ++ /* get conversion duration device and id dependent */ ++ t_conv = conversion_time(sl); + + memset(info->rom, 0, sizeof(info->rom)); + +- while (max_trying--) { ++ /* prevent the slave from going away in sleep */ ++ atomic_inc(THERM_REFCNT(sl->family_data)); ++ ++ if (!bus_mutex_lock(&dev_master->bus_mutex)) { ++ ret = -EAGAIN; /* Didn't acquire the mutex */ ++ goto dec_refcnt; ++ } ++ ++ while (max_trying-- && ret) { /* ret should be 0 */ + + info->verdict = 0; + info->crc = 0; +- ++ /* safe version to select slave */ + if (!reset_select_slave(sl)) { +- int count = 0; +- unsigned int tm = 750; + unsigned long sleep_rem; + +- w1_write_8(dev, W1_READ_PSUPPLY); +- external_power = w1_read_8(dev); +- +- if (reset_select_slave(sl)) +- continue; +- + /* 750ms strong pullup (or delay) after the convert */ +- if (w1_strong_pullup == 2 || +- (!external_power && w1_strong_pullup)) +- w1_next_pullup(dev, tm); +- +- w1_write_8(dev, W1_CONVERT_TEMP); ++ if (strong_pullup) ++ w1_next_pullup(dev_master, t_conv); + +- if (external_power) { +- mutex_unlock(&dev->bus_mutex); ++ w1_write_8(dev_master, W1_CONVERT_TEMP); + +- sleep_rem = msleep_interruptible(tm); ++ if (strong_pullup) { /*some device need pullup */ ++ sleep_rem = msleep_interruptible(t_conv); + if (sleep_rem != 0) { + ret = -EINTR; +- goto dec_refcnt; ++ goto mt_unlock; + } ++ mutex_unlock(&dev_master->bus_mutex); ++ } else { /*no device need pullup */ ++ mutex_unlock(&dev_master->bus_mutex); + +- ret = mutex_lock_interruptible(&dev->bus_mutex); +- if (ret != 0) +- goto dec_refcnt; +- } else if (!w1_strong_pullup) { +- sleep_rem = msleep_interruptible(tm); ++ sleep_rem = msleep_interruptible(t_conv); + if (sleep_rem != 0) { + ret = -EINTR; +- goto mt_unlock; ++ goto dec_refcnt; + } + } +- +- if (!reset_select_slave(sl)) { +- +- w1_write_8(dev, W1_READ_SCRATCHPAD); +- count = w1_read_block(dev, info->rom, 9); +- if (count != 9) { +- dev_warn(device, "w1_read_block() " +- "returned %u instead of 9.\n", +- count); +- } +- +- info->crc = w1_calc_crc8(info->rom, 8); +- +- if (info->rom[8] == info->crc) +- info->verdict = 1; +- } ++ ret = read_scratchpad(sl, info); ++ goto dec_refcnt; + } + +- if (info->verdict) +- break; + } + + mt_unlock: +- mutex_unlock(&dev->bus_mutex); ++ mutex_unlock(&dev_master->bus_mutex); + dec_refcnt: +- atomic_dec(THERM_REFCNT(family_data)); ++ atomic_dec(THERM_REFCNT(sl->family_data)); + error: + return ret; + } +@@ -1000,27 +1054,33 @@ static ssize_t w1_slave_show(struct devi + u8 *family_data = sl->family_data; + int ret, i; + ssize_t c = PAGE_SIZE; +- u8 fid = sl->family->fid; + +- ret = read_therm(device, sl, &info); +- if (ret) +- return ret; ++ ret = convert_t(sl, &info); ++ ++ if (ret < 0) { ++ dev_dbg(device, ++ "%s: Temperature data may be corrupted. err=%d\n", ++ __func__, ret); ++ return 0; ++ } + + for (i = 0; i < 9; ++i) + c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", info.rom[i]); + c -= snprintf(buf + PAGE_SIZE - c, c, ": crc=%02x %s\n", + info.crc, (info.verdict) ? "YES" : "NO"); ++ + if (info.verdict) + memcpy(family_data, info.rom, sizeof(info.rom)); + else +- dev_warn(device, "Read failed CRC check\n"); ++ dev_warn(device, "%s:Read failed CRC check\n", __func__); + + for (i = 0; i < 9; ++i) + c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", + ((u8 *)family_data)[i]); + + c -= snprintf(buf + PAGE_SIZE - c, c, "t=%d\n", +- w1_convert_temp(info.rom, fid)); ++ temperature_from_RAM(sl, info.rom)); ++ + ret = PAGE_SIZE - c; + return ret; + } +@@ -1063,6 +1123,31 @@ static ssize_t w1_slave_store(struct dev + return size; /* always return size to avoid infinite calling */ + } + ++static ssize_t temperature_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct w1_slave *sl = dev_to_w1_slave(device); ++ struct therm_info info; ++ int ret = 0; ++ ++ if ((!sl->family_data) || (!SLAVE_SPECIFIC_FUNC(sl))) { ++ dev_info(device, ++ "%s: Device not supported by the driver\n", __func__); ++ return 0; /* No device family */ ++ } ++ ++ ret = convert_t(sl, &info); ++ ++ if (ret < 0) { ++ dev_dbg(device, ++ "%s: Temperature data may be corrupted. err=%d\n", ++ __func__, ret); ++ return 0; ++ } ++ ++ return sprintf(buf, "%d\n", temperature_from_RAM(sl, info.rom)); ++} ++ + static ssize_t ext_power_show(struct device *device, + struct device_attribute *attr, char *buf) + { +@@ -1172,12 +1257,11 @@ static int w1_read_temp(struct device *d + { + struct w1_slave *sl = dev_get_drvdata(device); + struct therm_info info; +- u8 fid = sl->family->fid; + int ret; + + switch (attr) { + case hwmon_temp_input: +- ret = read_therm(device, sl, &info); ++ ret = convert_t(sl, &info); + if (ret) + return ret; + +@@ -1186,7 +1270,7 @@ static int w1_read_temp(struct device *d + return ret; + } + +- *val = w1_convert_temp(info.rom, fid); ++ *val = temperature_from_RAM(sl, info.rom); + ret = 0; + break; + default: diff --git a/target/linux/bcm27xx/patches-5.4/950-0772-w1_therm-adding-alarm-sysfs-entry.patch b/target/linux/bcm27xx/patches-5.4/950-0772-w1_therm-adding-alarm-sysfs-entry.patch new file mode 100644 index 0000000000..f4b8d5d1d6 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0772-w1_therm-adding-alarm-sysfs-entry.patch @@ -0,0 +1,319 @@ +From 8c3d9356c3c3b9c9188f1e192c7e2541e313c7ab Mon Sep 17 00:00:00 2001 +From: Akira Shimahara <akira215corp@gmail.com> +Date: Mon, 11 May 2020 22:38:01 +0200 +Subject: [PATCH] w1_therm: adding alarm sysfs entry + +commit e2c94d6f572079511945e64537eb1218643f2e68 upstream. + +Adding device alarms settings by a dedicated sysfs entry alarms (RW): +read or write TH and TL in the device RAM. Checking devices in alarm +state could be performed using the master search command. + +As alarms temperature level are store in a 8 bit register on the device +and are signed values, a safe cast shall be performed using the min and +max temperature that device are able to measure. This is done by +int_to_short inline function. + +A 'write_data' field is added in the device structure, to bind the +correct writing function, as some devices may have 2 or 3 bytes RAM. + +Updating Documentation/ABI/testing/sysfs-driver-w1_therm accordingly. + +Signed-off-by: Akira Shimahara <akira215corp@gmail.com> +Link: https://lore.kernel.org/r/20200511203801.411253-1-akira215corp@gmail.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + .../ABI/testing/sysfs-driver-w1_therm | 16 ++ + drivers/w1/slaves/w1_therm.c | 161 ++++++++++++++++++ + 2 files changed, 177 insertions(+) + +--- a/Documentation/ABI/testing/sysfs-driver-w1_therm ++++ b/Documentation/ABI/testing/sysfs-driver-w1_therm +@@ -1,3 +1,19 @@ ++What: /sys/bus/w1/devices/.../alarms ++Date: May 2020 ++Contact: Akira Shimahara <akira215corp@gmail.com> ++Description: ++ (RW) read or write TH and TL (Temperature High an Low) alarms. ++ Values shall be space separated and in the device range ++ (typical -55 degC to 125 degC), if not values will be trimmed ++ to device min/max capabilities. Values are integer as they are ++ stored in a 8bit register in the device. Lowest value is ++ automatically put to TL. Once set, alarms could be search at ++ master level, refer to Documentation/w1/w1_generic.rst for ++ detailed information ++Users: any user space application which wants to communicate with ++ w1_term device ++ ++ + What: /sys/bus/w1/devices/.../eeprom + Date: May 2020 + Contact: Akira Shimahara <akira215corp@gmail.com> +--- a/drivers/w1/slaves/w1_therm.c ++++ b/drivers/w1/slaves/w1_therm.c +@@ -58,6 +58,9 @@ module_param_named(strong_pullup, w1_str + #define EEPROM_CMD_WRITE "save" /* cmd for write eeprom sysfs */ + #define EEPROM_CMD_READ "restore" /* cmd for read eeprom sysfs */ + ++#define MIN_TEMP -55 /* min temperature that can be mesured */ ++#define MAX_TEMP 125 /* max temperature that can be mesured */ ++ + /* Helpers Macros */ + + /* +@@ -96,6 +99,7 @@ module_param_named(strong_pullup, w1_str + * @get_conversion_time: pointer to the device conversion time function + * @set_resolution: pointer to the device set_resolution function + * @get_resolution: pointer to the device get_resolution function ++ * @write_data: pointer to the device writing function (2 or 3 bytes) + */ + struct w1_therm_family_converter { + u8 broken; +@@ -105,6 +109,7 @@ struct w1_therm_family_converter { + int (*get_conversion_time)(struct w1_slave *sl); + int (*set_resolution)(struct w1_slave *sl, int val); + int (*get_resolution)(struct w1_slave *sl); ++ int (*write_data)(struct w1_slave *sl, const u8 *data); + }; + + /** +@@ -239,6 +244,12 @@ static ssize_t resolution_store(struct d + static ssize_t eeprom_store(struct device *device, + struct device_attribute *attr, const char *buf, size_t size); + ++static ssize_t alarms_store(struct device *device, ++ struct device_attribute *attr, const char *buf, size_t size); ++ ++static ssize_t alarms_show(struct device *device, ++ struct device_attribute *attr, char *buf); ++ + /* Attributes declarations */ + + static DEVICE_ATTR_RW(w1_slave); +@@ -247,6 +258,7 @@ static DEVICE_ATTR_RO(temperature); + static DEVICE_ATTR_RO(ext_power); + static DEVICE_ATTR_RW(resolution); + static DEVICE_ATTR_WO(eeprom); ++static DEVICE_ATTR_RW(alarms); + + /* Interface Functions declaration */ + +@@ -278,6 +290,7 @@ static struct attribute *w1_therm_attrs[ + &dev_attr_ext_power.attr, + &dev_attr_resolution.attr, + &dev_attr_eeprom.attr, ++ &dev_attr_alarms.attr, + NULL, + }; + +@@ -286,6 +299,7 @@ static struct attribute *w1_ds18s20_attr + &dev_attr_temperature.attr, + &dev_attr_ext_power.attr, + &dev_attr_eeprom.attr, ++ &dev_attr_alarms.attr, + NULL, + }; + +@@ -296,6 +310,7 @@ static struct attribute *w1_ds28ea00_att + &dev_attr_ext_power.attr, + &dev_attr_resolution.attr, + &dev_attr_eeprom.attr, ++ &dev_attr_alarms.attr, + NULL, + }; + +@@ -556,6 +571,7 @@ static struct w1_therm_family_converter + .get_conversion_time = w1_DS18S20_convert_time, + .set_resolution = NULL, /* no config register */ + .get_resolution = NULL, /* no config register */ ++ .write_data = w1_DS18S20_write_data, + }, + { + .f = &w1_therm_family_DS1822, +@@ -563,6 +579,7 @@ static struct w1_therm_family_converter + .get_conversion_time = w1_DS18B20_convert_time, + .set_resolution = w1_DS18B20_set_resolution, + .get_resolution = w1_DS18B20_get_resolution, ++ .write_data = w1_DS18B20_write_data, + }, + { + .f = &w1_therm_family_DS18B20, +@@ -570,6 +587,7 @@ static struct w1_therm_family_converter + .get_conversion_time = w1_DS18B20_convert_time, + .set_resolution = w1_DS18B20_set_resolution, + .get_resolution = w1_DS18B20_get_resolution, ++ .write_data = w1_DS18B20_write_data, + }, + { + .f = &w1_therm_family_DS28EA00, +@@ -577,6 +595,7 @@ static struct w1_therm_family_converter + .get_conversion_time = w1_DS18B20_convert_time, + .set_resolution = w1_DS18B20_set_resolution, + .get_resolution = w1_DS18B20_get_resolution, ++ .write_data = w1_DS18B20_write_data, + }, + { + .f = &w1_therm_family_DS1825, +@@ -584,6 +603,7 @@ static struct w1_therm_family_converter + .get_conversion_time = w1_DS18B20_convert_time, + .set_resolution = w1_DS18B20_set_resolution, + .get_resolution = w1_DS18B20_get_resolution, ++ .write_data = w1_DS18B20_write_data, + } + }; + +@@ -678,6 +698,26 @@ static inline int temperature_from_RAM(s + return 0; /* No device family */ + } + ++/** ++ * int_to_short() - Safe casting of int to short ++ * ++ * @i: integer to be converted to short ++ * ++ * Device register use 1 byte to store signed integer. ++ * This helper function convert the int in a signed short, ++ * using the min/max values that device can measure as limits. ++ * min/max values are defined by macro. ++ * ++ * Return: a short in the range of min/max value ++ */ ++static inline s8 int_to_short(int i) ++{ ++ /* Prepare to cast to short by eliminating out of range values */ ++ i = i > MAX_TEMP ? MAX_TEMP : i; ++ i = i < MIN_TEMP ? MIN_TEMP : i; ++ return (s8) i; ++} ++ + /* Interface Functions */ + + static int w1_therm_add_slave(struct w1_slave *sl) +@@ -1250,6 +1290,127 @@ static ssize_t eeprom_store(struct devic + + return size; + } ++ ++static ssize_t alarms_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct w1_slave *sl = dev_to_w1_slave(device); ++ int ret = -ENODEV; ++ s8 th = 0, tl = 0; ++ struct therm_info scratchpad; ++ ++ ret = read_scratchpad(sl, &scratchpad); ++ ++ if (!ret) { ++ th = scratchpad.rom[2]; /* TH is byte 2 */ ++ tl = scratchpad.rom[3]; /* TL is byte 3 */ ++ } else { ++ dev_info(device, ++ "%s: error reading alarms register %d\n", ++ __func__, ret); ++ } ++ ++ return sprintf(buf, "%hd %hd\n", tl, th); ++} ++ ++static ssize_t alarms_store(struct device *device, ++ struct device_attribute *attr, const char *buf, size_t size) ++{ ++ struct w1_slave *sl = dev_to_w1_slave(device); ++ struct therm_info info; ++ u8 new_config_register[3]; /* array of data to be written */ ++ int temp, ret = -EINVAL; ++ char *token = NULL; ++ s8 tl, th, tt; /* 1 byte per value + temp ring order */ ++ char *p_args = kmalloc(size, GFP_KERNEL); ++ ++ /* Safe string copys as buf is const */ ++ if (!p_args) { ++ dev_warn(device, ++ "%s: error unable to allocate memory %d\n", ++ __func__, -ENOMEM); ++ return size; ++ } ++ strcpy(p_args, buf); ++ ++ /* Split string using space char */ ++ token = strsep(&p_args, " "); ++ ++ if (!token) { ++ dev_info(device, ++ "%s: error parsing args %d\n", __func__, -EINVAL); ++ goto free_m; ++ } ++ ++ /* Convert 1st entry to int */ ++ ret = kstrtoint (token, 10, &temp); ++ if (ret) { ++ dev_info(device, ++ "%s: error parsing args %d\n", __func__, ret); ++ goto free_m; ++ } ++ ++ tl = int_to_short(temp); ++ ++ /* Split string using space char */ ++ token = strsep(&p_args, " "); ++ if (!token) { ++ dev_info(device, ++ "%s: error parsing args %d\n", __func__, -EINVAL); ++ goto free_m; ++ } ++ /* Convert 2nd entry to int */ ++ ret = kstrtoint (token, 10, &temp); ++ if (ret) { ++ dev_info(device, ++ "%s: error parsing args %d\n", __func__, ret); ++ goto free_m; ++ } ++ ++ /* Prepare to cast to short by eliminating out of range values */ ++ th = int_to_short(temp); ++ ++ /* Reorder if required th and tl */ ++ if (tl > th) { ++ tt = tl; tl = th; th = tt; ++ } ++ ++ /* ++ * Read the scratchpad to change only the required bits ++ * (th : byte 2 - tl: byte 3) ++ */ ++ ret = read_scratchpad(sl, &info); ++ if (!ret) { ++ new_config_register[0] = th; /* Byte 2 */ ++ new_config_register[1] = tl; /* Byte 3 */ ++ new_config_register[2] = info.rom[4];/* Byte 4 */ ++ } else { ++ dev_info(device, ++ "%s: error reading from the slave device %d\n", ++ __func__, ret); ++ goto free_m; ++ } ++ ++ /* Write data in the device RAM */ ++ if (!SLAVE_SPECIFIC_FUNC(sl)) { ++ dev_info(device, ++ "%s: Device not supported by the driver %d\n", ++ __func__, -ENODEV); ++ goto free_m; ++ } ++ ++ ret = SLAVE_SPECIFIC_FUNC(sl)->write_data(sl, new_config_register); ++ if (ret) ++ dev_info(device, ++ "%s: error writing to the slave device %d\n", ++ __func__, ret); ++ ++free_m: ++ /* free allocated memory */ ++ kfree(p_args); ++ ++ return size; ++} + + #if IS_REACHABLE(CONFIG_HWMON) + static int w1_read_temp(struct device *device, u32 attr, int channel, diff --git a/target/linux/bcm27xx/patches-5.4/950-0773-w1_therm-adding-bulk-read-support-to-trigger-multipl.patch b/target/linux/bcm27xx/patches-5.4/950-0773-w1_therm-adding-bulk-read-support-to-trigger-multipl.patch new file mode 100644 index 0000000000..ad641e1e98 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0773-w1_therm-adding-bulk-read-support-to-trigger-multipl.patch @@ -0,0 +1,587 @@ +From e6585a1d299375740f95f30027b8b3f4b34e7548 Mon Sep 17 00:00:00 2001 +From: Akira Shimahara <akira215corp@gmail.com> +Date: Mon, 11 May 2020 22:38:20 +0200 +Subject: [PATCH] w1_therm: adding bulk read support to trigger + multiple conversion on bus + +commit 57c76221d5af648c8355a55c09b050c5d8d38189 upstream. + +Adding bulk read support: +Sending a 'trigger' command in the dedicated sysfs entry of bus master +device send a conversion command for all the slaves on the bus. The sysfs +entry is added as soon as at least one device supporting this feature +is detected on the bus. + +The behavior of the sysfs reading temperature on the device is as follow: + * If no bulk read pending, trigger a conversion on the device, wait for + the conversion to be done, read the temperature in device RAM + * If a bulk read has been trigger, access directly the device RAM +This behavior is the same on the 2 sysfs entries ('temperature' and +'w1_slave'). + +Reading the therm_bulk_read sysfs give the status of bulk operations: + * '-1': conversion in progress on at least 1 sensor + * '1': conversion complete but at least one sensor has not been read yet + * '0': no bulk operation. Reading temperature on ecah device will trigger +a conversion + +As not all devices support bulk read feature, it has been added in device +family structure. + +The attribute is set at master level as soon as a supporting device is +discover. It is removed when the last supported device leave the bus. +The count of supported device is kept with the static counter +bulk_read_device_counter. + +A strong pull up is apply on the line if at least one device required it. +The duration of the pull up is the max time required by a device on the +line, which depends on the resolution settings of each device. The strong +pull up could be adjust with the a module parameter. + +Updating documentation in Documentation/ABI/testing/sysfs-driver-w1_therm +and Documentation/w1/slaves/w1_therm.rst accordingly. + +Signed-off-by: Akira Shimahara <akira215corp@gmail.com> +Link: https://lore.kernel.org/r/20200511203820.411483-1-akira215corp@gmail.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + .../ABI/testing/sysfs-driver-w1_therm | 36 ++- + Documentation/w1/slaves/w1_therm.rst | 50 +++- + drivers/w1/slaves/w1_therm.c | 251 +++++++++++++++++- + 3 files changed, 322 insertions(+), 15 deletions(-) + +--- a/Documentation/ABI/testing/sysfs-driver-w1_therm ++++ b/Documentation/ABI/testing/sysfs-driver-w1_therm +@@ -62,9 +62,16 @@ Date: May 2020 + Contact: Akira Shimahara <akira215corp@gmail.com> + Description: + (RO) return the temperature in 1/1000 degC. +- Note that the conversion duration depend on the resolution (if +- device support this feature). It takes 94ms in 9bits +- resolution, 750ms for 12bits. ++ * If a bulk read has been triggered, it will directly ++ return the temperature computed when the bulk read ++ occurred, if available. If not yet available, nothing ++ is returned (a debug kernel message is sent), you ++ should retry later on. ++ * If no bulk read has been triggered, it will trigger ++ a conversion and send the result. Note that the ++ conversion duration depend on the resolution (if ++ device support this feature). It takes 94ms in 9bits ++ resolution, 750ms for 12bits. + Users: any user space application which wants to communicate with + w1_term device + +@@ -85,4 +92,25 @@ Description: + refer to Documentation/w1/slaves/w1_therm.rst for detailed + information. + Users: any user space application which wants to communicate with +- w1_term device +\ No newline at end of file ++ w1_term device ++ ++ ++What: /sys/bus/w1/devices/w1_bus_masterXX/therm_bulk_read ++Date: May 2020 ++Contact: Akira Shimahara <akira215corp@gmail.com> ++Description: ++ (RW) trigger a bulk read conversion. read the status ++ *read*: ++ * '-1': conversion in progress on at least 1 sensor ++ * '1' : conversion complete but at least one sensor ++ value has not been read yet ++ * '0' : no bulk operation. Reading temperature will ++ trigger a conversion on each device ++ *write*: 'trigger': trigger a bulk read on all supporting ++ devices on the bus ++ Note that if a bulk read is sent but one sensor is not read ++ immediately, the next access to temperature on this device ++ will return the temperature measured at the time of issue ++ of the bulk read command (not the current temperature). ++Users: any user space application which wants to communicate with ++ w1_term device +--- a/Documentation/w1/slaves/w1_therm.rst ++++ b/Documentation/w1/slaves/w1_therm.rst +@@ -26,20 +26,31 @@ W1_THERM_DS1825 0x3B + W1_THERM_DS28EA00 0x42 + ==================== ==== + +-Support is provided through the sysfs w1_slave file. Each open and ++Support is provided through the sysfs w1_slave file. Each open and + read sequence will initiate a temperature conversion then provide two +-lines of ASCII output. The first line contains the nine hex bytes ++lines of ASCII output. The first line contains the nine hex bytes + read along with a calculated crc value and YES or NO if it matched. +-If the crc matched the returned values are retained. The second line ++If the crc matched the returned values are retained. The second line + displays the retained values along with a temperature in millidegrees + Centigrade after t=. + +-Parasite powered devices are limited to one slave performing a +-temperature conversion at a time. If none of the devices are parasite +-powered it would be possible to convert all the devices at the same +-time and then go back to read individual sensors. That isn't +-currently supported. The driver also doesn't support reduced +-precision (which would also reduce the conversion time) when reading values. ++Alternatively, temperature can be read using temperature sysfs, it ++return only temperature in millidegrees Centigrade. ++ ++A bulk read of all devices on the bus could be done writing 'trigger' ++in the therm_bulk_read sysfs entry at w1_bus_master level. This will ++sent the convert command on all devices on the bus, and if parasite ++powered devices are detected on the bus (and strong pullup is enable ++in the module), it will drive the line high during the longer conversion ++time required by parasited powered device on the line. Reading ++therm_bulk_read will return 0 if no bulk conversion pending, ++-1 if at least one sensor still in conversion, 1 if conversion is complete ++but at least one sensor value has not been read yet. Result temperature is ++then accessed by reading the temperature sysfs entry of each device, which ++may return empty if conversion is still in progress. Note that if a bulk ++read is sent but one sensor is not read immediately, the next access to ++temperature on this device will return the temperature measured at the ++time of issue of the bulk read command (not the current temperature). + + Writing a value between 9 and 12 to the sysfs w1_slave file will change the + precision of the sensor for the next readings. This value is in (volatile) +@@ -49,6 +60,27 @@ To store the current precision configura + has to be written to the sysfs w1_slave file. Since the EEPROM has a limited + amount of writes (>50k), this command should be used wisely. + ++Alternatively, resolution can be set or read (value from 9 to 12) using the ++dedicated resolution sysfs entry on each device. This sysfs entry is not ++present for devices not supporting this feature. Driver will adjust the ++correct conversion time for each device regarding to its resolution setting. ++In particular, strong pullup will be applied if required during the conversion ++duration. ++ ++The write-only sysfs entry eeprom is an alternative for EEPROM operations: ++ * 'save': will save device RAM to EEPROM ++ * 'restore': will restore EEPROM data in device RAM. ++ ++ext_power syfs entry allow tho check the power status of each device. ++ * '0': device parasite powered ++ * '1': device externally powered ++ ++sysfs alarms allow read or write TH and TL (Temperature High an Low) alarms. ++Values shall be space separated and in the device range (typical -55 degC ++to 125 degC). Values are integer as they are store in a 8bit register in ++the device. Lowest value is automatically put to TL.Once set, alarms could ++be search at master level. ++ + The module parameter strong_pullup can be set to 0 to disable the + strong pullup, 1 to enable autodetection or 2 to force strong pullup. + In case of autodetection, the driver will use the "READ POWER SUPPLY" +--- a/drivers/w1/slaves/w1_therm.c ++++ b/drivers/w1/slaves/w1_therm.c +@@ -43,6 +43,9 @@ + static int w1_strong_pullup = 1; + module_param_named(strong_pullup, w1_strong_pullup, int, 0); + ++/* Counter for devices supporting bulk reading */ ++static u16 bulk_read_device_counter; /* =0 as per C standard */ ++ + /* This command should be in public header w1.h but is not */ + #define W1_RECALL_EEPROM 0xB8 + +@@ -57,6 +60,7 @@ module_param_named(strong_pullup, w1_str + + #define EEPROM_CMD_WRITE "save" /* cmd for write eeprom sysfs */ + #define EEPROM_CMD_READ "restore" /* cmd for read eeprom sysfs */ ++#define BULK_TRIGGER_CMD "trigger" /* cmd to trigger a bulk read */ + + #define MIN_TEMP -55 /* min temperature that can be mesured */ + #define MAX_TEMP 125 /* max temperature that can be mesured */ +@@ -84,6 +88,15 @@ module_param_named(strong_pullup, w1_str + #define SLAVE_RESOLUTION(sl) \ + (((struct w1_therm_family_data *)(sl->family_data))->resolution) + ++/* ++ * return whether or not a converT command has been issued to the slave ++ * * 0: no bulk read is pending ++ * * -1: conversion is in progress ++ * * 1: conversion done, result to be read ++ */ ++#define SLAVE_CONVERT_TRIGGERED(sl) \ ++ (((struct w1_therm_family_data *)(sl->family_data))->convert_triggered) ++ + /* return the address of the refcnt in the family data */ + #define THERM_REFCNT(family_data) \ + (&((struct w1_therm_family_data *)family_data)->refcnt) +@@ -100,6 +113,7 @@ module_param_named(strong_pullup, w1_str + * @set_resolution: pointer to the device set_resolution function + * @get_resolution: pointer to the device get_resolution function + * @write_data: pointer to the device writing function (2 or 3 bytes) ++ * @bulk_read: true if device family support bulk read, false otherwise + */ + struct w1_therm_family_converter { + u8 broken; +@@ -110,6 +124,7 @@ struct w1_therm_family_converter { + int (*set_resolution)(struct w1_slave *sl, int val); + int (*get_resolution)(struct w1_slave *sl); + int (*write_data)(struct w1_slave *sl, const u8 *data); ++ bool bulk_read; + }; + + /** +@@ -120,6 +135,7 @@ struct w1_therm_family_converter { + * 0 device parasite powered, + * -x error or undefined + * @resolution: current device resolution ++ * @convert_triggered: conversion state of the device + * @specific_functions: pointer to struct of device specific function + */ + struct w1_therm_family_data { +@@ -127,6 +143,7 @@ struct w1_therm_family_data { + atomic_t refcnt; + int external_powered; + int resolution; ++ int convert_triggered; + struct w1_therm_family_converter *specific_functions; + }; + +@@ -218,6 +235,18 @@ static int recall_eeprom(struct w1_slave + */ + static int read_powermode(struct w1_slave *sl); + ++/** ++ * trigger_bulk_read() - function to trigger a bulk read on the bus ++ * @dev_master: the device master of the bus ++ * ++ * Send a SKIP ROM follow by a CONVERT T commmand on the bus. ++ * It also set the status flag in each slave &struct w1_therm_family_data ++ * to signal that a conversion is in progress. ++ * ++ * Return: 0 if success, -kernel error code otherwise ++ */ ++static int trigger_bulk_read(struct w1_master *dev_master); ++ + /* Sysfs interface declaration */ + + static ssize_t w1_slave_show(struct device *device, +@@ -250,6 +279,12 @@ static ssize_t alarms_store(struct devic + static ssize_t alarms_show(struct device *device, + struct device_attribute *attr, char *buf); + ++static ssize_t therm_bulk_read_store(struct device *device, ++ struct device_attribute *attr, const char *buf, size_t size); ++ ++static ssize_t therm_bulk_read_show(struct device *device, ++ struct device_attribute *attr, char *buf); ++ + /* Attributes declarations */ + + static DEVICE_ATTR_RW(w1_slave); +@@ -260,6 +295,8 @@ static DEVICE_ATTR_RW(resolution); + static DEVICE_ATTR_WO(eeprom); + static DEVICE_ATTR_RW(alarms); + ++static DEVICE_ATTR_RW(therm_bulk_read); /* attribut at master level */ ++ + /* Interface Functions declaration */ + + /** +@@ -572,6 +609,7 @@ static struct w1_therm_family_converter + .set_resolution = NULL, /* no config register */ + .get_resolution = NULL, /* no config register */ + .write_data = w1_DS18S20_write_data, ++ .bulk_read = true + }, + { + .f = &w1_therm_family_DS1822, +@@ -580,6 +618,7 @@ static struct w1_therm_family_converter + .set_resolution = w1_DS18B20_set_resolution, + .get_resolution = w1_DS18B20_get_resolution, + .write_data = w1_DS18B20_write_data, ++ .bulk_read = true + }, + { + .f = &w1_therm_family_DS18B20, +@@ -588,6 +627,7 @@ static struct w1_therm_family_converter + .set_resolution = w1_DS18B20_set_resolution, + .get_resolution = w1_DS18B20_get_resolution, + .write_data = w1_DS18B20_write_data, ++ .bulk_read = true + }, + { + .f = &w1_therm_family_DS28EA00, +@@ -596,6 +636,7 @@ static struct w1_therm_family_converter + .set_resolution = w1_DS18B20_set_resolution, + .get_resolution = w1_DS18B20_get_resolution, + .write_data = w1_DS18B20_write_data, ++ .bulk_read = false + }, + { + .f = &w1_therm_family_DS1825, +@@ -604,6 +645,7 @@ static struct w1_therm_family_converter + .set_resolution = w1_DS18B20_set_resolution, + .get_resolution = w1_DS18B20_get_resolution, + .write_data = w1_DS18B20_write_data, ++ .bulk_read = true + } + }; + +@@ -658,6 +700,23 @@ static inline bool bus_mutex_lock(struct + } + + /** ++ * support_bulk_read() - check if slave support bulk read ++ * @sl: device to check the ability ++ * ++ * Return: true if bulk read is supported, false if not or error ++ */ ++static inline bool bulk_read_support(struct w1_slave *sl) ++{ ++ if (SLAVE_SPECIFIC_FUNC(sl)) ++ return SLAVE_SPECIFIC_FUNC(sl)->bulk_read; ++ ++ dev_info(&sl->dev, ++ "%s: Device not supported by the driver\n", __func__); ++ ++ return false; /* No device family */ ++} ++ ++/** + * conversion_time() - get the Tconv for the slave + * @sl: device to get the conversion time + * +@@ -741,6 +800,24 @@ static int w1_therm_add_slave(struct w1_ + /* save this pointer to the device structure */ + SLAVE_SPECIFIC_FUNC(sl) = sl_family_conv; + ++ if (bulk_read_support(sl)) { ++ /* ++ * add the sys entry to trigger bulk_read ++ * at master level only the 1st time ++ */ ++ if (!bulk_read_device_counter) { ++ int err = device_create_file(&sl->master->dev, ++ &dev_attr_therm_bulk_read); ++ ++ if (err) ++ dev_warn(&sl->dev, ++ "%s: Device has been added, but bulk read is unavailable. err=%d\n", ++ __func__, err); ++ } ++ /* Increment the counter */ ++ bulk_read_device_counter++; ++ } ++ + /* Getting the power mode of the device {external, parasite} */ + SLAVE_POWERMODE(sl) = read_powermode(sl); + +@@ -763,6 +840,9 @@ static int w1_therm_add_slave(struct w1_ + } + } + ++ /* Finally initialize convert_triggered flag */ ++ SLAVE_CONVERT_TRIGGERED(sl) = 0; ++ + return 0; + } + +@@ -770,6 +850,14 @@ static void w1_therm_remove_slave(struct + { + int refcnt = atomic_sub_return(1, THERM_REFCNT(sl->family_data)); + ++ if (bulk_read_support(sl)) { ++ bulk_read_device_counter--; ++ /* Delete the entry if no more device support the feature */ ++ if (!bulk_read_device_counter) ++ device_remove_file(&sl->master->dev, ++ &dev_attr_therm_bulk_read); ++ } ++ + while (refcnt) { + msleep(1000); + refcnt = atomic_read(THERM_REFCNT(sl->family_data)); +@@ -1084,6 +1172,96 @@ error: + return ret; + } + ++static int trigger_bulk_read(struct w1_master *dev_master) ++{ ++ struct w1_slave *sl = NULL; /* used to iterate through slaves */ ++ int max_trying = W1_THERM_MAX_TRY; ++ int t_conv = 0; ++ int ret = -ENODEV; ++ bool strong_pullup = false; ++ ++ /* ++ * Check whether there are parasite powered device on the bus, ++ * and compute duration of conversion for these devices ++ * so we can apply a strong pullup if required ++ */ ++ list_for_each_entry(sl, &dev_master->slist, w1_slave_entry) { ++ if (!sl->family_data) ++ goto error; ++ if (bulk_read_support(sl)) { ++ int t_cur = conversion_time(sl); ++ ++ t_conv = t_cur > t_conv ? t_cur : t_conv; ++ strong_pullup = strong_pullup || ++ (w1_strong_pullup == 2 || ++ (!SLAVE_POWERMODE(sl) && ++ w1_strong_pullup)); ++ } ++ } ++ ++ /* ++ * t_conv is the max conversion time required on the bus ++ * If its 0, no device support the bulk read feature ++ */ ++ if (!t_conv) ++ goto error; ++ ++ if (!bus_mutex_lock(&dev_master->bus_mutex)) { ++ ret = -EAGAIN; /* Didn't acquire the mutex */ ++ goto error; ++ } ++ ++ while ((max_trying--) && (ret < 0)) { /* ret should be either 0 */ ++ ++ if (!w1_reset_bus(dev_master)) { /* Just reset the bus */ ++ unsigned long sleep_rem; ++ ++ w1_write_8(dev_master, W1_SKIP_ROM); ++ ++ if (strong_pullup) /* Apply pullup if required */ ++ w1_next_pullup(dev_master, t_conv); ++ ++ w1_write_8(dev_master, W1_CONVERT_TEMP); ++ ++ /* set a flag to instruct that converT pending */ ++ list_for_each_entry(sl, ++ &dev_master->slist, w1_slave_entry) { ++ if (bulk_read_support(sl)) ++ SLAVE_CONVERT_TRIGGERED(sl) = -1; ++ } ++ ++ if (strong_pullup) { /* some device need pullup */ ++ sleep_rem = msleep_interruptible(t_conv); ++ if (sleep_rem != 0) { ++ ret = -EINTR; ++ goto mt_unlock; ++ } ++ mutex_unlock(&dev_master->bus_mutex); ++ } else { ++ mutex_unlock(&dev_master->bus_mutex); ++ sleep_rem = msleep_interruptible(t_conv); ++ if (sleep_rem != 0) { ++ ret = -EINTR; ++ goto set_flag; ++ } ++ } ++ ret = 0; ++ goto set_flag; ++ } ++ } ++ ++mt_unlock: ++ mutex_unlock(&dev_master->bus_mutex); ++set_flag: ++ /* set a flag to register convsersion is done */ ++ list_for_each_entry(sl, &dev_master->slist, w1_slave_entry) { ++ if (bulk_read_support(sl)) ++ SLAVE_CONVERT_TRIGGERED(sl) = 1; ++ } ++error: ++ return ret; ++} ++ + /* Sysfs Interface definition */ + + static ssize_t w1_slave_show(struct device *device, +@@ -1095,7 +1273,20 @@ static ssize_t w1_slave_show(struct devi + int ret, i; + ssize_t c = PAGE_SIZE; + +- ret = convert_t(sl, &info); ++ if (bulk_read_support(sl)) { ++ if (SLAVE_CONVERT_TRIGGERED(sl) < 0) { ++ dev_dbg(device, ++ "%s: Conversion in progress, retry later\n", ++ __func__); ++ return 0; ++ } else if (SLAVE_CONVERT_TRIGGERED(sl) > 0) { ++ /* A bulk read has been issued, read the device RAM */ ++ ret = read_scratchpad(sl, &info); ++ SLAVE_CONVERT_TRIGGERED(sl) = 0; ++ } else ++ ret = convert_t(sl, &info); ++ } else ++ ret = convert_t(sl, &info); + + if (ret < 0) { + dev_dbg(device, +@@ -1176,7 +1367,20 @@ static ssize_t temperature_show(struct d + return 0; /* No device family */ + } + +- ret = convert_t(sl, &info); ++ if (bulk_read_support(sl)) { ++ if (SLAVE_CONVERT_TRIGGERED(sl) < 0) { ++ dev_dbg(device, ++ "%s: Conversion in progress, retry later\n", ++ __func__); ++ return 0; ++ } else if (SLAVE_CONVERT_TRIGGERED(sl) > 0) { ++ /* A bulk read has been issued, read the device RAM */ ++ ret = read_scratchpad(sl, &info); ++ SLAVE_CONVERT_TRIGGERED(sl) = 0; ++ } else ++ ret = convert_t(sl, &info); ++ } else ++ ret = convert_t(sl, &info); + + if (ret < 0) { + dev_dbg(device, +@@ -1412,6 +1616,49 @@ free_m: + return size; + } + ++static ssize_t therm_bulk_read_store(struct device *device, ++ struct device_attribute *attr, const char *buf, size_t size) ++{ ++ struct w1_master *dev_master = dev_to_w1_master(device); ++ int ret = -EINVAL; /* Invalid argument */ ++ ++ if (size == sizeof(BULK_TRIGGER_CMD)) ++ if (!strncmp(buf, BULK_TRIGGER_CMD, ++ sizeof(BULK_TRIGGER_CMD)-1)) ++ ret = trigger_bulk_read(dev_master); ++ ++ if (ret) ++ dev_info(device, ++ "%s: unable to trigger a bulk read on the bus. err=%d\n", ++ __func__, ret); ++ ++ return size; ++} ++ ++static ssize_t therm_bulk_read_show(struct device *device, ++ struct device_attribute *attr, char *buf) ++{ ++ struct w1_master *dev_master = dev_to_w1_master(device); ++ struct w1_slave *sl = NULL; ++ int ret = 0; ++ ++ list_for_each_entry(sl, &dev_master->slist, w1_slave_entry) { ++ if (sl->family_data) { ++ if (bulk_read_support(sl)) { ++ if (SLAVE_CONVERT_TRIGGERED(sl) == -1) { ++ ret = -1; ++ goto show_result; ++ } ++ if (SLAVE_CONVERT_TRIGGERED(sl) == 1) ++ /* continue to check other slaves */ ++ ret = 1; ++ } ++ } ++ } ++show_result: ++ return sprintf(buf, "%d\n", ret); ++} ++ + #if IS_REACHABLE(CONFIG_HWMON) + static int w1_read_temp(struct device *device, u32 attr, int channel, + long *val) diff --git a/target/linux/bcm27xx/patches-5.4/950-0774-w1_therm-Free-the-correct-variable.patch b/target/linux/bcm27xx/patches-5.4/950-0774-w1_therm-Free-the-correct-variable.patch new file mode 100644 index 0000000000..fede4120ba --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0774-w1_therm-Free-the-correct-variable.patch @@ -0,0 +1,41 @@ +From 039babe99fda6eb04a77ca29cacf98efd1a5f406 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Wed, 20 May 2020 15:00:19 +0300 +Subject: [PATCH] w1_therm: Free the correct variable + +commit e420637b81f78d0fbacf539bdb1b341eba602aea upstream. + +The problem is that we change "p_args" to point to the middle of the +string so when we free it at the end of the function it's not freeing +the same pointer that we originally allocated. + +Fixes: e2c94d6f5720 ("w1_therm: adding alarm sysfs entry") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Link: https://lore.kernel.org/r/20200520120019.GA172354@mwanda +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/w1/slaves/w1_therm.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/w1/slaves/w1_therm.c ++++ b/drivers/w1/slaves/w1_therm.c +@@ -1526,8 +1526,9 @@ static ssize_t alarms_store(struct devic + int temp, ret = -EINVAL; + char *token = NULL; + s8 tl, th, tt; /* 1 byte per value + temp ring order */ +- char *p_args = kmalloc(size, GFP_KERNEL); ++ char *p_args, *orig; + ++ p_args = orig = kmalloc(size, GFP_KERNEL); + /* Safe string copys as buf is const */ + if (!p_args) { + dev_warn(device, +@@ -1611,7 +1612,7 @@ static ssize_t alarms_store(struct devic + + free_m: + /* free allocated memory */ +- kfree(p_args); ++ kfree(orig); + + return size; + } diff --git a/target/linux/bcm27xx/patches-5.4/950-0775-w1_therm-remove-redundant-assignments-to-variable-re.patch b/target/linux/bcm27xx/patches-5.4/950-0775-w1_therm-remove-redundant-assignments-to-variable-re.patch new file mode 100644 index 0000000000..73bc9d5402 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0775-w1_therm-remove-redundant-assignments-to-variable-re.patch @@ -0,0 +1,58 @@ +From 7566655c9e659e890f44784a6403de98ad77ae5b Mon Sep 17 00:00:00 2001 +From: Colin Ian King <colin.king@canonical.com> +Date: Tue, 19 May 2020 16:45:53 +0100 +Subject: [PATCH] w1_therm: remove redundant assignments to variable + ret + +commit f37d13d52c0560bd2bac40b22466af538e61a5ce upstream. + +The variable ret is being initialized with a value that is never read +and it is being updated later with a new value. The initialization +is redundant and can be removed. + +Addresses-Coverity: ("Unused value") +Signed-off-by: Colin Ian King <colin.king@canonical.com> +Link: https://lore.kernel.org/r/20200519154553.873413-1-colin.king@canonical.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/w1/slaves/w1_therm.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/w1/slaves/w1_therm.c ++++ b/drivers/w1/slaves/w1_therm.c +@@ -505,7 +505,7 @@ static inline int w1_DS18S20_write_data( + + static inline int w1_DS18B20_set_resolution(struct w1_slave *sl, int val) + { +- int ret = -ENODEV; ++ int ret; + u8 new_config_register[3]; /* array of data to be written */ + struct therm_info info; + +@@ -538,7 +538,7 @@ static inline int w1_DS18B20_set_resolut + + static inline int w1_DS18B20_get_resolution(struct w1_slave *sl) + { +- int ret = -ENODEV; ++ int ret; + u8 config_register; + struct therm_info info; + +@@ -1499,7 +1499,7 @@ static ssize_t alarms_show(struct device + struct device_attribute *attr, char *buf) + { + struct w1_slave *sl = dev_to_w1_slave(device); +- int ret = -ENODEV; ++ int ret; + s8 th = 0, tl = 0; + struct therm_info scratchpad; + +@@ -1523,7 +1523,7 @@ static ssize_t alarms_store(struct devic + struct w1_slave *sl = dev_to_w1_slave(device); + struct therm_info info; + u8 new_config_register[3]; /* array of data to be written */ +- int temp, ret = -EINVAL; ++ int temp, ret; + char *token = NULL; + s8 tl, th, tt; /* 1 byte per value + temp ring order */ + char *p_args, *orig; diff --git a/target/linux/bcm27xx/patches-5.4/950-0776-PCI-brcmstb-Assert-fundamental-reset-on-initializati.patch b/target/linux/bcm27xx/patches-5.4/950-0776-PCI-brcmstb-Assert-fundamental-reset-on-initializati.patch new file mode 100644 index 0000000000..2692bed050 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0776-PCI-brcmstb-Assert-fundamental-reset-on-initializati.patch @@ -0,0 +1,33 @@ +From d9317f90391167ebc275696d9df3c21ce754d609 Mon Sep 17 00:00:00 2001 +From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> +Date: Thu, 7 May 2020 19:20:20 +0200 +Subject: [PATCH] PCI: brcmstb: Assert fundamental reset on + initialization + +commit 22e21e51ce755399fd42055a3f668ee4af370881 upstream. + +While preparing the driver for upstream this detail was missed. + +If not asserted during the initialization process, devices connected on +the bus will not be made aware of the internal reset happening. This, +potentially resulting in unexpected behavior. + +Link: https://lore.kernel.org/r/20200507172020.18000-1-nsaenzjulienne@suse.de +Fixes: c0452137034b ("PCI: brcmstb: Add Broadcom STB PCIe host controller driver") +Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> +Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> +Acked-by: Florian Fainelli <f.fainelli@gmail.com> +--- + drivers/pci/controller/pcie-brcmstb.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/pci/controller/pcie-brcmstb.c ++++ b/drivers/pci/controller/pcie-brcmstb.c +@@ -697,6 +697,7 @@ static int brcm_pcie_setup(struct brcm_p + + /* Reset the bridge */ + brcm_pcie_bridge_sw_init_set(pcie, 1); ++ brcm_pcie_perst_set(pcie, 1); + + usleep_range(100, 200); + diff --git a/target/linux/bcm27xx/patches-5.4/950-0777-clk-rpi-Adjust-DT-binding-to-match-upstream.patch b/target/linux/bcm27xx/patches-5.4/950-0777-clk-rpi-Adjust-DT-binding-to-match-upstream.patch new file mode 100644 index 0000000000..35278708e9 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0777-clk-rpi-Adjust-DT-binding-to-match-upstream.patch @@ -0,0 +1,189 @@ +From d8daf6289869513ed548bcb0da410d7de3e5d57a Mon Sep 17 00:00:00 2001 +From: Maxime Ripard <maxime@cerno.tech> +Date: Wed, 10 Jun 2020 16:28:56 +0200 +Subject: [PATCH] clk: rpi: Adjust DT binding to match upstream + +Signed-off-by: Maxime Ripard <maxime@cerno.tech> +--- + arch/arm/boot/dts/bcm270x.dtsi | 6 ------ + arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 5 +++++ + arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 5 +++++ + arch/arm/boot/dts/bcm2710-rpi-cm3.dts | 5 +++++ + arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 5 +++++ + arch/arm/boot/dts/bcm2711.dtsi | 6 ------ + arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts | 5 +++++ + arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 5 +++++ + arch/arm/boot/dts/bcm2837-rpi-3-b.dts | 5 +++++ + arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi | 5 +++++ + drivers/clk/bcm/clk-raspberrypi.c | 12 +++++++++++- + 11 files changed, 51 insertions(+), 13 deletions(-) + +--- a/arch/arm/boot/dts/bcm270x.dtsi ++++ b/arch/arm/boot/dts/bcm270x.dtsi +@@ -7,12 +7,6 @@ + /delete-property/ stdout-path; + }; + +- firmware_clocks: firmware-clocks { +- compatible = "raspberrypi,firmware-clocks"; +- raspberrypi,firmware = <&firmware>; +- #clock-cells = <1>; +- }; +- + soc: soc { + + watchdog: watchdog@7e100000 { +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts +@@ -85,6 +85,11 @@ + }; + + &firmware { ++ firmware_clocks: clocks { ++ compatible = "raspberrypi,firmware-clocks"; ++ #clock-cells = <1>; ++ }; ++ + expgpio: expgpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +@@ -96,6 +96,11 @@ + }; + + &firmware { ++ firmware_clocks: clocks { ++ compatible = "raspberrypi,firmware-clocks"; ++ #clock-cells = <1>; ++ }; ++ + expgpio: expgpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; +--- a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts +@@ -58,6 +58,11 @@ + }; + + &firmware { ++ firmware_clocks: clocks { ++ compatible = "raspberrypi,firmware-clocks"; ++ #clock-cells = <1>; ++ }; ++ + expgpio: expgpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; +--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts +@@ -54,6 +54,11 @@ + }; + + &firmware { ++ firmware_clocks: clocks { ++ compatible = "raspberrypi,firmware-clocks"; ++ #clock-cells = <1>; ++ }; ++ + expgpio: gpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; +--- a/arch/arm/boot/dts/bcm2711.dtsi ++++ b/arch/arm/boot/dts/bcm2711.dtsi +@@ -24,12 +24,6 @@ + clock-output-names = "108MHz-clock"; + }; + +- firmware_clocks: firmware-clocks { +- compatible = "raspberrypi,firmware-clocks"; +- raspberrypi,firmware = <&firmware>; +- #clock-cells = <1>; +- }; +- + soc { + /* + * Defined ranges: +--- a/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts ++++ b/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts +@@ -31,6 +31,11 @@ + }; + + &firmware { ++ firmware_clocks: clocks { ++ compatible = "raspberrypi,firmware-clocks"; ++ #clock-cells = <1>; ++ }; ++ + expgpio: gpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; +--- a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts +@@ -37,6 +37,11 @@ + }; + + &firmware { ++ firmware_clocks: clocks { ++ compatible = "raspberrypi,firmware-clocks"; ++ #clock-cells = <1>; ++ }; ++ + expgpio: gpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; +--- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts +@@ -32,6 +32,11 @@ + }; + + &firmware { ++ firmware_clocks: clocks { ++ compatible = "raspberrypi,firmware-clocks"; ++ #clock-cells = <1>; ++ }; ++ + expgpio: gpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; +--- a/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi ++++ b/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi +@@ -35,6 +35,11 @@ + }; + + &firmware { ++ firmware_clocks: clocks { ++ compatible = "raspberrypi,firmware-clocks"; ++ #clock-cells = <1>; ++ }; ++ + expgpio: gpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; +--- a/drivers/clk/bcm/clk-raspberrypi.c ++++ b/drivers/clk/bcm/clk-raspberrypi.c +@@ -383,13 +383,23 @@ static int raspberrypi_clk_probe(struct + struct raspberrypi_clk *rpi; + int ret; + +- firmware_node = of_parse_phandle(dev->of_node, "raspberrypi,firmware", 0); ++ /* ++ * We can be probed either through the an old-fashioned ++ * platform device registration or through a DT node that is a ++ * child of the firmware node. Handle both cases. ++ */ ++ if (dev->of_node) ++ firmware_node = of_get_parent(dev->of_node); ++ else ++ firmware_node = of_find_compatible_node(NULL, NULL, ++ "raspberrypi,bcm2835-firmware"); + if (!firmware_node) { + dev_err(dev, "Missing firmware node\n"); + return -ENOENT; + } + + firmware = rpi_firmware_get(firmware_node); ++ of_node_put(firmware_node); + if (!firmware) + return -EPROBE_DEFER; + diff --git a/target/linux/bcm27xx/patches-5.4/950-0778-clk-bcm-rpi-Add-an-enum-for-the-firmware-clocks.patch b/target/linux/bcm27xx/patches-5.4/950-0778-clk-bcm-rpi-Add-an-enum-for-the-firmware-clocks.patch new file mode 100644 index 0000000000..c69b5685d4 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0778-clk-bcm-rpi-Add-an-enum-for-the-firmware-clocks.patch @@ -0,0 +1,80 @@ +From d9b492679a107e535cfd39ee00bd2ce6f12089e0 Mon Sep 17 00:00:00 2001 +From: Maxime Ripard <maxime@cerno.tech> +Date: Tue, 26 May 2020 14:23:04 +0200 +Subject: [PATCH] clk: bcm: rpi: Add an enum for the firmware clocks + +While the firmware allows us to discover the available clocks, we need to +discriminate those clocks to only register the ones meaningful to Linux. +The firmware also doesn't provide a clock name, so having a list of the ID +will help us to give clocks a proper name later on. + +Acked-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> +Signed-off-by: Maxime Ripard <maxime@cerno.tech> +--- + drivers/clk/bcm/clk-raspberrypi.c | 30 ++++++++++++++++++++++++------ + 1 file changed, 24 insertions(+), 6 deletions(-) + +--- a/drivers/clk/bcm/clk-raspberrypi.c ++++ b/drivers/clk/bcm/clk-raspberrypi.c +@@ -18,7 +18,23 @@ + + #include <soc/bcm2835/raspberrypi-firmware.h> + +-#define RPI_FIRMWARE_ARM_CLK_ID 0x00000003 ++enum rpi_firmware_clk_id { ++ RPI_FIRMWARE_EMMC_CLK_ID = 1, ++ RPI_FIRMWARE_UART_CLK_ID, ++ RPI_FIRMWARE_ARM_CLK_ID, ++ RPI_FIRMWARE_CORE_CLK_ID, ++ RPI_FIRMWARE_V3D_CLK_ID, ++ RPI_FIRMWARE_H264_CLK_ID, ++ RPI_FIRMWARE_ISP_CLK_ID, ++ RPI_FIRMWARE_SDRAM_CLK_ID, ++ RPI_FIRMWARE_PIXEL_CLK_ID, ++ RPI_FIRMWARE_PWM_CLK_ID, ++ RPI_FIRMWARE_HEVC_CLK_ID, ++ RPI_FIRMWARE_EMMC2_CLK_ID, ++ RPI_FIRMWARE_M2MC_CLK_ID, ++ RPI_FIRMWARE_PIXEL_BVB_CLK_ID, ++ RPI_FIRMWARE_NUM_CLK_ID, ++}; + + #define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0) + #define RPI_FIRMWARE_STATE_WAIT_BIT BIT(1) +@@ -31,8 +47,6 @@ + + #define A2W_PLL_FRAC_BITS 20 + +-#define NUM_FW_CLKS 16 +- + struct raspberrypi_clk { + struct device *dev; + struct rpi_firmware *firmware; +@@ -350,12 +364,15 @@ static int raspberrypi_discover_clocks(s + struct rpi_firmware_get_clocks_response *clks; + int ret; + +- clks = devm_kcalloc(rpi->dev, sizeof(*clks), NUM_FW_CLKS, GFP_KERNEL); ++ clks = devm_kcalloc(rpi->dev, ++ sizeof(*clks), RPI_FIRMWARE_NUM_CLK_ID, ++ GFP_KERNEL); + if (!clks) + return -ENOMEM; + + ret = rpi_firmware_property(rpi->firmware, RPI_FIRMWARE_GET_CLOCKS, +- clks, sizeof(*clks) * NUM_FW_CLKS); ++ clks, ++ sizeof(*clks) * RPI_FIRMWARE_NUM_CLK_ID); + if (ret) + return ret; + +@@ -411,7 +428,8 @@ static int raspberrypi_clk_probe(struct + rpi->firmware = firmware; + platform_set_drvdata(pdev, rpi); + +- clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, NUM_FW_CLKS), ++ clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, ++ RPI_FIRMWARE_NUM_CLK_ID), + GFP_KERNEL); + if (!clk_data) + return -ENOMEM; diff --git a/target/linux/bcm27xx/patches-5.4/950-0779-clk-bcm-rpi-Use-CCF-boundaries-instead-of-rolling-ou.patch b/target/linux/bcm27xx/patches-5.4/950-0779-clk-bcm-rpi-Use-CCF-boundaries-instead-of-rolling-ou.patch new file mode 100644 index 0000000000..22f1aa6742 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0779-clk-bcm-rpi-Use-CCF-boundaries-instead-of-rolling-ou.patch @@ -0,0 +1,134 @@ +From cd72d75cfb216a7ef15ec8649e57b03b4fc48b62 Mon Sep 17 00:00:00 2001 +From: Maxime Ripard <maxime@cerno.tech> +Date: Wed, 27 May 2020 11:13:52 +0200 +Subject: [PATCH] clk: bcm: rpi: Use CCF boundaries instead of + rolling our own + +The raspberrypi firmware clock driver has a min_rate / max_rate clamping by +storing the info it needs in a private structure. + +However, the CCF already provides such a facility, so we can switch to it +to remove the boilerplate. + +Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> +Signed-off-by: Maxime Ripard <maxime@cerno.tech> +--- + drivers/clk/bcm/clk-raspberrypi.c | 49 ++++++++++++++++++++----------- + 1 file changed, 32 insertions(+), 17 deletions(-) + +--- a/drivers/clk/bcm/clk-raspberrypi.c ++++ b/drivers/clk/bcm/clk-raspberrypi.c +@@ -57,9 +57,6 @@ struct raspberrypi_clk_data { + struct clk_hw hw; + unsigned id; + +- unsigned long min_rate; +- unsigned long max_rate; +- + struct raspberrypi_clk *rpi; + }; + +@@ -177,13 +174,11 @@ static int raspberrypi_fw_pll_set_rate(s + static int raspberrypi_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) + { +- struct raspberrypi_clk_data *data = +- container_of(hw, struct raspberrypi_clk_data, hw); + u64 div, final_rate; + u32 ndiv, fdiv; + + /* We can't use req->rate directly as it would overflow */ +- final_rate = clamp(req->rate, data->min_rate, data->max_rate); ++ final_rate = clamp(req->rate, req->min_rate, req->max_rate); + + div = (u64)final_rate << A2W_PLL_FRAC_BITS; + do_div(div, req->best_parent_rate); +@@ -254,16 +249,15 @@ static struct clk_hw *raspberrypi_regist + dev_info(rpi->dev, "CPU frequency range: min %u, max %u\n", + min_rate, max_rate); + +- data->min_rate = min_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE; +- data->max_rate = max_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE; +- + data->hw.init = &init; + + ret = devm_clk_hw_register(rpi->dev, &data->hw); +- if (ret) +- return ERR_PTR(ret); ++ if (!ret) ++ clk_hw_set_rate_range(&data->hw, ++ min_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE, ++ max_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE); + +- return &data->hw; ++ return ret; + } + + static struct clk_fixed_factor raspberrypi_clk_pllb_arm = { +@@ -299,22 +293,22 @@ static struct clk_hw *raspberrypi_regist + return &raspberrypi_clk_pllb_arm.hw; + } + +-static long raspberrypi_fw_dumb_round_rate(struct clk_hw *hw, +- unsigned long rate, +- unsigned long *parent_rate) ++static int raspberrypi_fw_dumb_determine_rate(struct clk_hw *hw, ++ struct clk_rate_request *req) + { + /* + * The firmware will do the rounding but that isn't part of + * the interface with the firmware, so we just do our best + * here. + */ +- return rate; ++ req->rate = clamp(req->rate, req->min_rate, req->max_rate); ++ return 0; + } + + static const struct clk_ops raspberrypi_firmware_clk_ops = { + .is_prepared = raspberrypi_fw_is_prepared, + .recalc_rate = raspberrypi_fw_get_rate, +- .round_rate = raspberrypi_fw_dumb_round_rate, ++ .determine_rate = raspberrypi_fw_dumb_determine_rate, + .set_rate = raspberrypi_fw_set_rate, + }; + +@@ -324,6 +318,7 @@ static struct clk_hw *raspberrypi_clk_re + { + struct raspberrypi_clk_data *data; + struct clk_init_data init = {}; ++ u32 min_rate, max_rate; + int ret; + + if (id == RPI_FIRMWARE_ARM_CLK_ID) { +@@ -351,10 +346,30 @@ static struct clk_hw *raspberrypi_clk_re + + data->hw.init = &init; + ++ ret = raspberrypi_clock_property(rpi->firmware, data, ++ RPI_FIRMWARE_GET_MIN_CLOCK_RATE, ++ &min_rate); ++ if (ret) { ++ dev_err(rpi->dev, "Failed to get %s min freq: %d\n", ++ init.name, ret); ++ return ERR_PTR(ret); ++ } ++ ++ ret = raspberrypi_clock_property(rpi->firmware, data, ++ RPI_FIRMWARE_GET_MAX_CLOCK_RATE, ++ &max_rate); ++ if (ret) { ++ dev_err(rpi->dev, "Failed to get %s max freq: %d\n", ++ init.name, ret); ++ return ERR_PTR(ret); ++ } ++ + ret = devm_clk_hw_register(rpi->dev, &data->hw); + if (ret) + return ERR_PTR(ret); + ++ clk_hw_set_rate_range(&data->hw, min_rate, max_rate); ++ + return &data->hw; + } + diff --git a/target/linux/bcm27xx/patches-5.4/950-0780-clk-bcm-rpi-Give-firmware-clocks-a-name.patch b/target/linux/bcm27xx/patches-5.4/950-0780-clk-bcm-rpi-Give-firmware-clocks-a-name.patch new file mode 100644 index 0000000000..745e8588ac --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0780-clk-bcm-rpi-Give-firmware-clocks-a-name.patch @@ -0,0 +1,52 @@ +From 5f69f49a942cd31e5f8b511e166fb55e3a0df267 Mon Sep 17 00:00:00 2001 +From: Maxime Ripard <maxime@cerno.tech> +Date: Tue, 26 May 2020 14:30:31 +0200 +Subject: [PATCH] clk: bcm: rpi: Give firmware clocks a name + +We've registered the firmware clocks using their ID as name, but it's much +more convenient to register them using their proper name. Since the +firmware doesn't provide it, we have to duplicate it. + +Acked-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> +Signed-off-by: Maxime Ripard <maxime@cerno.tech> +--- + drivers/clk/bcm/clk-raspberrypi.c | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +--- a/drivers/clk/bcm/clk-raspberrypi.c ++++ b/drivers/clk/bcm/clk-raspberrypi.c +@@ -36,6 +36,23 @@ enum rpi_firmware_clk_id { + RPI_FIRMWARE_NUM_CLK_ID, + }; + ++static char *rpi_firmware_clk_names[] = { ++ [RPI_FIRMWARE_EMMC_CLK_ID] = "emmc", ++ [RPI_FIRMWARE_UART_CLK_ID] = "uart", ++ [RPI_FIRMWARE_ARM_CLK_ID] = "arm", ++ [RPI_FIRMWARE_CORE_CLK_ID] = "core", ++ [RPI_FIRMWARE_V3D_CLK_ID] = "v3d", ++ [RPI_FIRMWARE_H264_CLK_ID] = "h264", ++ [RPI_FIRMWARE_ISP_CLK_ID] = "isp", ++ [RPI_FIRMWARE_SDRAM_CLK_ID] = "sdram", ++ [RPI_FIRMWARE_PIXEL_CLK_ID] = "pixel", ++ [RPI_FIRMWARE_PWM_CLK_ID] = "pwm", ++ [RPI_FIRMWARE_HEVC_CLK_ID] = "hevc", ++ [RPI_FIRMWARE_EMMC2_CLK_ID] = "emmc2", ++ [RPI_FIRMWARE_M2MC_CLK_ID] = "m2mc", ++ [RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = "pixel-bvb", ++}; ++ + #define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0) + #define RPI_FIRMWARE_STATE_WAIT_BIT BIT(1) + +@@ -340,7 +357,9 @@ static struct clk_hw *raspberrypi_clk_re + data->rpi = rpi; + data->id = id; + +- init.name = devm_kasprintf(rpi->dev, GFP_KERNEL, "fw-clk-%u", id); ++ init.name = devm_kasprintf(rpi->dev, GFP_KERNEL, ++ "fw-clk-%s", ++ rpi_firmware_clk_names[id]); + init.ops = &raspberrypi_firmware_clk_ops; + init.flags = CLK_GET_RATE_NOCACHE; + diff --git a/target/linux/bcm27xx/patches-5.4/950-0781-clk-bcm-rpi-Remove-the-quirks-for-the-CPU-clock.patch b/target/linux/bcm27xx/patches-5.4/950-0781-clk-bcm-rpi-Remove-the-quirks-for-the-CPU-clock.patch new file mode 100644 index 0000000000..0e9bb9c601 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0781-clk-bcm-rpi-Remove-the-quirks-for-the-CPU-clock.patch @@ -0,0 +1,207 @@ +From 30ae66617ee6f340343c8e75c244e370721ed2eb Mon Sep 17 00:00:00 2001 +From: Maxime Ripard <maxime@cerno.tech> +Date: Tue, 26 May 2020 15:27:35 +0200 +Subject: [PATCH] clk: bcm: rpi: Remove the quirks for the CPU clock + +The CPU clock has had so far a bunch of quirks to expose the clock tree +properly, but since we reverted to exposing them through the MMIO driver, +we can remove that code from the firmware driver. + +Signed-off-by: Maxime Ripard <maxime@cerno.tech> +--- + drivers/clk/bcm/clk-raspberrypi.c | 163 ++---------------------------- + 1 file changed, 9 insertions(+), 154 deletions(-) + +--- a/drivers/clk/bcm/clk-raspberrypi.c ++++ b/drivers/clk/bcm/clk-raspberrypi.c +@@ -151,13 +151,6 @@ static unsigned long raspberrypi_fw_get_ + return val; + } + +-static unsigned long raspberrypi_fw_pll_get_rate(struct clk_hw *hw, +- unsigned long parent_rate) +-{ +- return raspberrypi_fw_get_rate(hw, parent_rate) * +- RPI_FIRMWARE_PLLB_ARM_DIV_RATE; +-} +- + static int raspberrypi_fw_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) + { +@@ -176,140 +169,6 @@ static int raspberrypi_fw_set_rate(struc + return ret; + } + +-static int raspberrypi_fw_pll_set_rate(struct clk_hw *hw, unsigned long rate, +- unsigned long parent_rate) +-{ +- u32 new_rate = rate / RPI_FIRMWARE_PLLB_ARM_DIV_RATE; +- +- return raspberrypi_fw_set_rate(hw, new_rate, parent_rate); +-} +- +-/* +- * Sadly there is no firmware rate rounding interface. We borrowed it from +- * clk-bcm2835. +- */ +-static int raspberrypi_pll_determine_rate(struct clk_hw *hw, +- struct clk_rate_request *req) +-{ +- u64 div, final_rate; +- u32 ndiv, fdiv; +- +- /* We can't use req->rate directly as it would overflow */ +- final_rate = clamp(req->rate, req->min_rate, req->max_rate); +- +- div = (u64)final_rate << A2W_PLL_FRAC_BITS; +- do_div(div, req->best_parent_rate); +- +- ndiv = div >> A2W_PLL_FRAC_BITS; +- fdiv = div & ((1 << A2W_PLL_FRAC_BITS) - 1); +- +- final_rate = ((u64)req->best_parent_rate * +- ((ndiv << A2W_PLL_FRAC_BITS) + fdiv)); +- +- req->rate = final_rate >> A2W_PLL_FRAC_BITS; +- +- return 0; +-} +- +-static const struct clk_ops raspberrypi_firmware_pll_clk_ops = { +- .is_prepared = raspberrypi_fw_is_prepared, +- .recalc_rate = raspberrypi_fw_pll_get_rate, +- .set_rate = raspberrypi_fw_pll_set_rate, +- .determine_rate = raspberrypi_pll_determine_rate, +-}; +- +-static struct clk_hw *raspberrypi_register_pllb(struct raspberrypi_clk *rpi) +-{ +- struct raspberrypi_clk_data *data; +- struct clk_init_data init = {}; +- u32 min_rate = 0, max_rate = 0; +- int ret; +- +- data = devm_kzalloc(rpi->dev, sizeof(*data), GFP_KERNEL); +- if (!data) +- return ERR_PTR(-ENOMEM); +- data->rpi = rpi; +- data->id = RPI_FIRMWARE_ARM_CLK_ID; +- +- /* All of the PLLs derive from the external oscillator. */ +- init.parent_names = (const char *[]){ "osc" }; +- init.num_parents = 1; +- init.name = "pllb"; +- init.ops = &raspberrypi_firmware_pll_clk_ops; +- init.flags = CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED; +- +- /* Get min & max rates set by the firmware */ +- ret = raspberrypi_clock_property(rpi->firmware, data, +- RPI_FIRMWARE_GET_MIN_CLOCK_RATE, +- &min_rate); +- if (ret) { +- dev_err(rpi->dev, "Failed to get %s min freq: %d\n", +- init.name, ret); +- return ERR_PTR(ret); +- } +- +- ret = raspberrypi_clock_property(rpi->firmware, data, +- RPI_FIRMWARE_GET_MAX_CLOCK_RATE, +- &max_rate); +- if (ret) { +- dev_err(rpi->dev, "Failed to get %s max freq: %d\n", +- init.name, ret); +- return ERR_PTR(ret); +- } +- +- if (!min_rate || !max_rate) { +- dev_err(rpi->dev, "Unexpected frequency range: min %u, max %u\n", +- min_rate, max_rate); +- return ERR_PTR(-EINVAL); +- } +- +- dev_info(rpi->dev, "CPU frequency range: min %u, max %u\n", +- min_rate, max_rate); +- +- data->hw.init = &init; +- +- ret = devm_clk_hw_register(rpi->dev, &data->hw); +- if (!ret) +- clk_hw_set_rate_range(&data->hw, +- min_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE, +- max_rate * RPI_FIRMWARE_PLLB_ARM_DIV_RATE); +- +- return ret; +-} +- +-static struct clk_fixed_factor raspberrypi_clk_pllb_arm = { +- .mult = 1, +- .div = 2, +- .hw.init = &(struct clk_init_data) { +- .name = "pllb_arm", +- .parent_names = (const char *[]){ "pllb" }, +- .num_parents = 1, +- .ops = &clk_fixed_factor_ops, +- .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, +- }, +-}; +- +-static struct clk_hw *raspberrypi_register_pllb_arm(struct raspberrypi_clk *rpi) +-{ +- int ret; +- +- ret = devm_clk_hw_register(rpi->dev, &raspberrypi_clk_pllb_arm.hw); +- if (ret) { +- dev_err(rpi->dev, "Failed to initialize pllb_arm\n"); +- return ERR_PTR(ret); +- } +- +- ret = devm_clk_hw_register_clkdev(rpi->dev, +- &raspberrypi_clk_pllb_arm.hw, +- NULL, "cpu0"); +- if (ret) { +- dev_err(rpi->dev, "Failed to initialize clkdev\n"); +- return ERR_PTR(ret); +- } +- +- return &raspberrypi_clk_pllb_arm.hw; +-} +- + static int raspberrypi_fw_dumb_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) + { +@@ -338,19 +197,6 @@ static struct clk_hw *raspberrypi_clk_re + u32 min_rate, max_rate; + int ret; + +- if (id == RPI_FIRMWARE_ARM_CLK_ID) { +- struct clk_hw *hw; +- +- hw = raspberrypi_register_pllb(rpi); +- if (IS_ERR(hw)) { +- dev_err(rpi->dev, "Failed to initialize pllb, %ld\n", +- PTR_ERR(hw)); +- return hw; +- } +- +- return raspberrypi_register_pllb_arm(rpi); +- } +- + data = devm_kzalloc(rpi->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return ERR_PTR(-ENOMEM); +@@ -389,6 +235,15 @@ static struct clk_hw *raspberrypi_clk_re + + clk_hw_set_rate_range(&data->hw, min_rate, max_rate); + ++ if (id == RPI_FIRMWARE_ARM_CLK_ID) { ++ ret = devm_clk_hw_register_clkdev(rpi->dev, &data->hw, ++ NULL, "cpu0"); ++ if (ret) { ++ dev_err(rpi->dev, "Failed to initialize clkdev\n"); ++ return ERR_PTR(ret); ++ } ++ } ++ + return &data->hw; + } + diff --git a/target/linux/bcm27xx/patches-5.4/950-0782-clk-rpi-Only-register-a-few-firmware-clocks.patch b/target/linux/bcm27xx/patches-5.4/950-0782-clk-rpi-Only-register-a-few-firmware-clocks.patch new file mode 100644 index 0000000000..580a90c9d3 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0782-clk-rpi-Only-register-a-few-firmware-clocks.patch @@ -0,0 +1,43 @@ +From 73a8443ea82fef7a1f8a466fff83da7863baed49 Mon Sep 17 00:00:00 2001 +From: Maxime Ripard <maxime@cerno.tech> +Date: Wed, 10 Jun 2020 16:18:17 +0200 +Subject: [PATCH] clk: rpi: Only register a few firmware clocks + +Signed-off-by: Maxime Ripard <maxime@cerno.tech> +--- + drivers/clk/bcm/clk-raspberrypi.c | 25 ++++++++++++++++++------- + 1 file changed, 18 insertions(+), 7 deletions(-) + +--- a/drivers/clk/bcm/clk-raspberrypi.c ++++ b/drivers/clk/bcm/clk-raspberrypi.c +@@ -268,13 +268,24 @@ static int raspberrypi_discover_clocks(s + while (clks->id) { + struct clk_hw *hw; + +- hw = raspberrypi_clk_register(rpi, clks->parent, clks->id); +- if (IS_ERR(hw)) +- return PTR_ERR(hw); ++ switch (clks->id) { ++ case RPI_FIRMWARE_ARM_CLK_ID: ++ case RPI_FIRMWARE_CORE_CLK_ID: ++ case RPI_FIRMWARE_M2MC_CLK_ID: ++ case RPI_FIRMWARE_V3D_CLK_ID: ++ hw = raspberrypi_clk_register(rpi, clks->parent, ++ clks->id); ++ if (IS_ERR(hw)) ++ return PTR_ERR(hw); + +- data->hws[clks->id] = hw; +- data->num = clks->id + 1; +- clks++; ++ data->hws[clks->id] = hw; ++ data->num = clks->id + 1; ++ fallthrough; ++ ++ default: ++ clks++; ++ break; ++ } + } + + return 0; diff --git a/target/linux/bcm27xx/patches-5.4/950-0783-clk-rpi-Fix-compatible-indentation.patch b/target/linux/bcm27xx/patches-5.4/950-0783-clk-rpi-Fix-compatible-indentation.patch new file mode 100644 index 0000000000..da9d3b8c56 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0783-clk-rpi-Fix-compatible-indentation.patch @@ -0,0 +1,23 @@ +From 4a1d8af9737868f6494f491e9a1efb0fb348588e Mon Sep 17 00:00:00 2001 +From: Maxime Ripard <maxime@cerno.tech> +Date: Wed, 10 Jun 2020 16:29:08 +0200 +Subject: [PATCH] clk: rpi: Fix compatible indentation + +Signed-off-by: Maxime Ripard <maxime@cerno.tech> +--- + drivers/clk/bcm/clk-raspberrypi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/clk/bcm/clk-raspberrypi.c ++++ b/drivers/clk/bcm/clk-raspberrypi.c +@@ -359,8 +359,8 @@ static int raspberrypi_clk_remove(struct + } + + static const struct of_device_id raspberrypi_clk_match[] = { +- { .compatible = "raspberrypi,firmware-clocks" }, +- { }, ++ { .compatible = "raspberrypi,firmware-clocks" }, ++ { }, + }; + MODULE_DEVICE_TABLE(of, raspberrypi_clk_match); + diff --git a/target/linux/bcm27xx/patches-5.4/950-0784-SQUASH-dts-Fix-firmware-clocks-support.patch b/target/linux/bcm27xx/patches-5.4/950-0784-SQUASH-dts-Fix-firmware-clocks-support.patch new file mode 100644 index 0000000000..35c2c4429c --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0784-SQUASH-dts-Fix-firmware-clocks-support.patch @@ -0,0 +1,176 @@ +From 10f7562d7ce7ea6fe6324df059c865ff660811fc Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Thu, 11 Jun 2020 16:34:00 +0100 +Subject: [PATCH] SQUASH: dts: Fix firmware clocks support + +Commit [1] touched a lot of files and still missed some platforms. +In particular, Pi 2 was left with no clock scaling. Simplify the +firmware clocks DTS support and extend it to all platforms that +use the raspberrypi-cpufreq driver. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2709-rpi.dtsi | 7 +++++++ + arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 5 ----- + arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 5 ----- + arch/arm/boot/dts/bcm2710-rpi-cm3.dts | 5 ----- + arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 5 ----- + arch/arm/boot/dts/bcm2711-rpi.dtsi | 7 +++++++ + arch/arm/boot/dts/bcm2836-rpi.dtsi | 7 +++++++ + arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts | 5 ----- + arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 5 ----- + arch/arm/boot/dts/bcm2837-rpi-3-b.dts | 5 ----- + arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi | 5 ----- + 11 files changed, 21 insertions(+), 40 deletions(-) + +--- a/arch/arm/boot/dts/bcm2709-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2709-rpi.dtsi +@@ -3,3 +3,10 @@ + &vchiq { + compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq"; + }; ++ ++&firmware { ++ firmware_clocks: clocks { ++ compatible = "raspberrypi,firmware-clocks"; ++ #clock-cells = <1>; ++ }; ++}; +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts +@@ -85,11 +85,6 @@ + }; + + &firmware { +- firmware_clocks: clocks { +- compatible = "raspberrypi,firmware-clocks"; +- #clock-cells = <1>; +- }; +- + expgpio: expgpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +@@ -96,11 +96,6 @@ + }; + + &firmware { +- firmware_clocks: clocks { +- compatible = "raspberrypi,firmware-clocks"; +- #clock-cells = <1>; +- }; +- + expgpio: expgpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; +--- a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts +@@ -58,11 +58,6 @@ + }; + + &firmware { +- firmware_clocks: clocks { +- compatible = "raspberrypi,firmware-clocks"; +- #clock-cells = <1>; +- }; +- + expgpio: expgpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; +--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts +@@ -54,11 +54,6 @@ + }; + + &firmware { +- firmware_clocks: clocks { +- compatible = "raspberrypi,firmware-clocks"; +- #clock-cells = <1>; +- }; +- + expgpio: gpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; +--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi +@@ -170,3 +170,10 @@ + &genet { + compatible = "brcm,bcm2711-genet-v5", "brcm,genet-v5"; + }; ++ ++&firmware { ++ firmware_clocks: clocks { ++ compatible = "raspberrypi,firmware-clocks"; ++ #clock-cells = <1>; ++ }; ++}; +--- a/arch/arm/boot/dts/bcm2836-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2836-rpi.dtsi +@@ -4,3 +4,10 @@ + &vchiq { + compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq"; + }; ++ ++&firmware { ++ firmware_clocks: clocks { ++ compatible = "raspberrypi,firmware-clocks"; ++ #clock-cells = <1>; ++ }; ++}; +--- a/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts ++++ b/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts +@@ -31,11 +31,6 @@ + }; + + &firmware { +- firmware_clocks: clocks { +- compatible = "raspberrypi,firmware-clocks"; +- #clock-cells = <1>; +- }; +- + expgpio: gpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; +--- a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts +@@ -37,11 +37,6 @@ + }; + + &firmware { +- firmware_clocks: clocks { +- compatible = "raspberrypi,firmware-clocks"; +- #clock-cells = <1>; +- }; +- + expgpio: gpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; +--- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts +@@ -32,11 +32,6 @@ + }; + + &firmware { +- firmware_clocks: clocks { +- compatible = "raspberrypi,firmware-clocks"; +- #clock-cells = <1>; +- }; +- + expgpio: gpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; +--- a/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi ++++ b/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi +@@ -35,11 +35,6 @@ + }; + + &firmware { +- firmware_clocks: clocks { +- compatible = "raspberrypi,firmware-clocks"; +- #clock-cells = <1>; +- }; +- + expgpio: gpio { + compatible = "raspberrypi,firmware-gpio"; + gpio-controller; diff --git a/target/linux/bcm27xx/patches-5.4/950-0785-ARM-dts-Add-bcm2711-rpi-cm4.dts.patch b/target/linux/bcm27xx/patches-5.4/950-0785-ARM-dts-Add-bcm2711-rpi-cm4.dts.patch new file mode 100644 index 0000000000..fa6837b4f0 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0785-ARM-dts-Add-bcm2711-rpi-cm4.dts.patch @@ -0,0 +1,631 @@ +From 104dcc1aff0ae5509ad9875c11e3e0d8c290709d Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Tue, 2 Jun 2020 17:19:51 +0100 +Subject: [PATCH] ARM: dts: Add bcm2711-rpi-cm4.dts + +Add initial DTS file for Compute Module 4. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/Makefile | 3 +- + arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 586 ++++++++++++++++++++++++++ + arch/arm/boot/dts/overlays/README | 6 + + 3 files changed, 594 insertions(+), 1 deletion(-) + create mode 100644 arch/arm/boot/dts/bcm2711-rpi-cm4.dts + +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -12,7 +12,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ + bcm2710-rpi-3-b.dtb \ + bcm2711-rpi-4-b.dtb \ + bcm2710-rpi-3-b-plus.dtb \ +- bcm2710-rpi-cm3.dtb ++ bcm2710-rpi-cm3.dtb \ ++ bcm2711-rpi-cm4.dtb + + dtb-$(CONFIG_ARCH_ALPINE) += \ + alpine-db.dtb +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts +@@ -0,0 +1,586 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/dts-v1/; ++#include "bcm2711.dtsi" ++#include "bcm2835-rpi.dtsi" ++ ++/ { ++ compatible = "raspberrypi,4-compute-module", "brcm,bcm2711"; ++ model = "Raspberry Pi Compute Module 4"; ++ ++ chosen { ++ /* 8250 auxiliary UART instead of pl011 */ ++ stdout-path = "serial1:115200n8"; ++ }; ++ ++ /* Will be filled by the bootloader */ ++ memory@0 { ++ device_type = "memory"; ++ reg = <0 0 0>; ++ }; ++ ++ aliases { ++ ethernet0 = &genet; ++ }; ++ ++ leds { ++ act { ++ gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ pwr { ++ label = "PWR"; ++ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ wifi_pwrseq: wifi-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>; ++ }; ++ ++ sd_io_1v8_reg: sd_io_1v8_reg { ++ compatible = "regulator-gpio"; ++ regulator-name = "vdd-sd-io"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-settling-time-us = <5000>; ++ gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>; ++ states = <1800000 0x1 ++ 3300000 0x0>; ++ status = "okay"; ++ }; ++}; ++ ++&firmware { ++ expgpio: gpio { ++ compatible = "raspberrypi,firmware-gpio"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ gpio-line-names = "BT_ON", ++ "WL_ON", ++ "PWR_LED_OFF", ++ "ANT1", ++ "VDD_SD_IO_SEL", ++ "CAM_GPIO", ++ "SD_PWR_ON", ++ "ANT2"; ++ status = "okay"; ++ ++ ant1: ant1 { ++ gpio-hog; ++ gpios = <3 GPIO_ACTIVE_HIGH>; ++ output-high; ++ }; ++ ++ ant2: ant2 { ++ gpio-hog; ++ gpios = <7 GPIO_ACTIVE_HIGH>; ++ output-low; ++ }; ++ }; ++}; ++ ++&pwm1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm1_0_gpio40 &pwm1_1_gpio41>; ++ status = "okay"; ++}; ++ ++/* SDHCI is used to control the SDIO for wireless */ ++&sdhci { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_gpio34>; ++ bus-width = <4>; ++ non-removable; ++ mmc-pwrseq = <&wifi_pwrseq>; ++ status = "okay"; ++ ++ brcmf: wifi@1 { ++ reg = <1>; ++ compatible = "brcm,bcm4329-fmac"; ++ }; ++}; ++ ++/* EMMC2 is used to drive the SD card */ ++&emmc2 { ++ vqmmc-supply = <&sd_io_1v8_reg>; ++ broken-cd; ++ status = "okay"; ++}; ++ ++&genet { ++ phy-handle = <&phy1>; ++ phy-mode = "rgmii-rxid"; ++ status = "okay"; ++}; ++ ++&genet_mdio { ++ phy1: ethernet-phy@1 { ++ /* No PHY interrupt */ ++ reg = <0x1>; ++ }; ++}; ++ ++/* uart0 communicates with the BT module */ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32>; ++ uart-has-rtscts; ++ status = "okay"; ++ ++ bluetooth { ++ compatible = "brcm,bcm43438-bt"; ++ max-speed = <2000000>; ++ shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++/* uart1 is mapped to the pin header */ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_gpio14>; ++ status = "okay"; ++}; ++ ++&vchiq { ++ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; ++}; ++ ++&vc4 { ++ status = "okay"; ++}; ++ ++&pixelvalve0 { ++ status = "okay"; ++}; ++ ++&pixelvalve1 { ++ status = "okay"; ++}; ++ ++&pixelvalve2 { ++ status = "okay"; ++}; ++ ++&pixelvalve3 { ++ status = "okay"; ++}; ++ ++&pixelvalve4 { ++ status = "okay"; ++}; ++ ++&hdmi0 { ++ status = "okay"; ++}; ++ ++&ddc0 { ++ status = "okay"; ++}; ++ ++&hdmi1 { ++ status = "okay"; ++}; ++ ++&ddc1 { ++ status = "okay"; ++}; ++ ++// ============================================= ++// Downstream rpi- changes ++ ++#include "bcm270x.dtsi" ++ ++/ { ++ soc { ++ /delete-node/ pixelvalve@7e807000; ++ /delete-node/ hdmi@7e902000; ++ }; ++}; ++ ++#include "bcm2711-rpi.dtsi" ++#include "bcm283x-rpi-csi1-2lane.dtsi" ++#include "bcm283x-rpi-i2c0mux_0_44.dtsi" ++ ++/delete-node/ &emmc2; ++ ++/ { ++ chosen { ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1"; ++ }; ++ ++ aliases { ++ serial0 = &uart1; ++ serial1 = &uart0; ++ mmc0 = &emmc2; ++ mmc1 = &mmcnr; ++ mmc2 = &sdhost; ++ /delete-property/ i2c2; ++ i2c3 = &i2c3; ++ i2c4 = &i2c4; ++ i2c5 = &i2c5; ++ i2c6 = &i2c6; ++ /delete-property/ ethernet; ++ /delete-property/ intc; ++ pcie0 = &pcie0; ++ emmc2bus = &emmc2bus; ++ }; ++ ++ emmc2bus: emmc2bus { ++ compatible = "simple-bus"; ++ #address-cells = <2>; ++ #size-cells = <1>; ++ ++ ranges = <0x0 0x7e000000 0x0 0xfe000000 0x01800000>; ++ dma-ranges = <0x0 0xc0000000 0x0 0x00000000 0x40000000>; ++ ++ emmc2: emmc2@7e340000 { ++ compatible = "brcm,bcm2711-emmc2"; ++ status = "okay"; ++ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&clocks BCM2711_CLOCK_EMMC2>; ++ reg = <0x0 0x7e340000 0x100>; ++ vqmmc-supply = <&sd_io_1v8_reg>; ++ broken-cd; ++ }; ++ }; ++ ++ /delete-node/ wifi-pwrseq; ++}; ++ ++&mmcnr { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-0 = <&uart0_pins &bt_pins>; ++ status = "okay"; ++ ++ /delete-node/ bluetooth; ++}; ++ ++&uart1 { ++ pinctrl-0 = <&uart1_pins>; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; ++ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; ++ ++ spidev0: spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ }; ++ ++ spidev1: spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ }; ++}; ++ ++&gpio { ++ spi0_pins: spi0_pins { ++ brcm,pins = <9 10 11>; ++ brcm,function = <BCM2835_FSEL_ALT0>; ++ }; ++ ++ spi0_cs_pins: spi0_cs_pins { ++ brcm,pins = <8 7>; ++ brcm,function = <BCM2835_FSEL_GPIO_OUT>; ++ }; ++ ++ spi3_pins: spi3_pins { ++ brcm,pins = <1 2 3>; ++ brcm,function = <BCM2835_FSEL_ALT3>; ++ }; ++ ++ spi3_cs_pins: spi3_cs_pins { ++ brcm,pins = <0 24>; ++ brcm,function = <BCM2835_FSEL_GPIO_OUT>; ++ }; ++ ++ spi4_pins: spi4_pins { ++ brcm,pins = <5 6 7>; ++ brcm,function = <BCM2835_FSEL_ALT3>; ++ }; ++ ++ spi4_cs_pins: spi4_cs_pins { ++ brcm,pins = <4 25>; ++ brcm,function = <BCM2835_FSEL_GPIO_OUT>; ++ }; ++ ++ spi5_pins: spi5_pins { ++ brcm,pins = <13 14 15>; ++ brcm,function = <BCM2835_FSEL_ALT3>; ++ }; ++ ++ spi5_cs_pins: spi5_cs_pins { ++ brcm,pins = <12 26>; ++ brcm,function = <BCM2835_FSEL_GPIO_OUT>; ++ }; ++ ++ spi6_pins: spi6_pins { ++ brcm,pins = <19 20 21>; ++ brcm,function = <BCM2835_FSEL_ALT3>; ++ }; ++ ++ spi6_cs_pins: spi6_cs_pins { ++ brcm,pins = <18 27>; ++ brcm,function = <BCM2835_FSEL_GPIO_OUT>; ++ }; ++ ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <BCM2835_FSEL_ALT0>; ++ brcm,pull = <BCM2835_PUD_UP>; ++ }; ++ ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <BCM2835_FSEL_ALT0>; ++ brcm,pull = <BCM2835_PUD_UP>; ++ }; ++ ++ i2c3_pins: i2c3 { ++ brcm,pins = <4 5>; ++ brcm,function = <BCM2835_FSEL_ALT5>; ++ brcm,pull = <BCM2835_PUD_UP>; ++ }; ++ ++ i2c4_pins: i2c4 { ++ brcm,pins = <8 9>; ++ brcm,function = <BCM2835_FSEL_ALT5>; ++ brcm,pull = <BCM2835_PUD_UP>; ++ }; ++ ++ i2c5_pins: i2c5 { ++ brcm,pins = <12 13>; ++ brcm,function = <BCM2835_FSEL_ALT5>; ++ brcm,pull = <BCM2835_PUD_UP>; ++ }; ++ ++ i2c6_pins: i2c6 { ++ brcm,pins = <22 23>; ++ brcm,function = <BCM2835_FSEL_ALT5>; ++ brcm,pull = <BCM2835_PUD_UP>; ++ }; ++ ++ i2s_pins: i2s { ++ brcm,pins = <18 19 20 21>; ++ brcm,function = <BCM2835_FSEL_ALT0>; ++ }; ++ ++ sdio_pins: sdio_pins { ++ brcm,pins = <34 35 36 37 38 39>; ++ brcm,function = <BCM2835_FSEL_ALT3>; // alt3 = SD1 ++ brcm,pull = <0 2 2 2 2 2>; ++ }; ++ ++ bt_pins: bt_pins { ++ brcm,pins = "-"; // non-empty to keep btuart happy, //4 = 0 ++ // to fool pinctrl ++ brcm,function = <0>; ++ brcm,pull = <2>; ++ }; ++ ++ uart0_pins: uart0_pins { ++ brcm,pins = <32 33>; ++ brcm,function = <BCM2835_FSEL_ALT3>; ++ brcm,pull = <0 2>; ++ }; ++ ++ uart1_pins: uart1_pins { ++ brcm,pins; ++ brcm,function; ++ brcm,pull; ++ }; ++ ++ uart2_pins: uart2_pins { ++ brcm,pins = <0 1>; ++ brcm,function = <BCM2835_FSEL_ALT4>; ++ brcm,pull = <0 2>; ++ }; ++ ++ uart3_pins: uart3_pins { ++ brcm,pins = <4 5>; ++ brcm,function = <BCM2835_FSEL_ALT4>; ++ brcm,pull = <0 2>; ++ }; ++ ++ uart4_pins: uart4_pins { ++ brcm,pins = <8 9>; ++ brcm,function = <BCM2835_FSEL_ALT4>; ++ brcm,pull = <0 2>; ++ }; ++ ++ uart5_pins: uart5_pins { ++ brcm,pins = <12 13>; ++ brcm,function = <BCM2835_FSEL_ALT4>; ++ brcm,pull = <0 2>; ++ }; ++}; ++ ++&i2c0if { ++ clock-frequency = <100000>; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2s { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++/ { ++ __overrides__ { ++ /delete-property/ i2c2_baudrate; ++ /delete-property/ i2c2_iknowwhatimdoing; ++ }; ++}; ++ ++// ============================================= ++// Board specific stuff here ++ ++/ { ++ sd_vcc_reg: sd_vcc_reg { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc-sd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ enable-active-high; ++ gpio = <&expgpio 6 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++&sdhost { ++ status = "disabled"; ++}; ++ ++&emmc2 { ++ vmmc-supply = <&sd_vcc_reg>; ++ bus-width = <8>; ++}; ++ ++&phy1 { ++ led-modes = <0x00 0x08>; /* link/activity link */ ++}; ++ ++&gpio { ++ audio_pins: audio_pins { ++ brcm,pins = <40 41>; ++ brcm,function = <4>; ++ }; ++}; ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; ++ gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ pwr_led: pwr { ++ label = "led1"; ++ linux,default-trigger = "default-on"; ++ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&pwm1 { ++ status = "disabled"; ++}; ++ ++&audio { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&audio_pins>; ++}; ++ ++&vc4 { ++ status = "disabled"; ++}; ++ ++&pixelvalve0 { ++ status = "disabled"; ++}; ++ ++&pixelvalve1 { ++ status = "disabled"; ++}; ++ ++&pixelvalve2 { ++ status = "disabled"; ++}; ++ ++&pixelvalve3 { ++ status = "disabled"; ++}; ++ ++&pixelvalve4 { ++ status = "disabled"; ++}; ++ ++&hdmi0 { ++ status = "disabled"; ++}; ++ ++&ddc0 { ++ status = "disabled"; ++}; ++ ++&hdmi1 { ++ status = "disabled"; ++}; ++ ++&ddc1 { ++ status = "disabled"; ++}; ++ ++/ { ++ __overrides__ { ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ ++ pwr_led_gpio = <&pwr_led>,"gpios:4"; ++ pwr_led_activelow = <&pwr_led>,"gpios:8"; ++ pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; ++ ++ eth_led0 = <&phy1>,"led-modes:0"; ++ eth_led1 = <&phy1>,"led-modes:4"; ++ ++ ant1 = <&ant1>,"output-high?=on", ++ <&ant1>, "output-low?=off", ++ <&ant2>, "output-high?=off", ++ <&ant2>, "output-low?=on"; ++ ant2 = <&ant1>,"output-high?=off", ++ <&ant1>, "output-low?=on", ++ <&ant2>, "output-high?=on", ++ <&ant2>, "output-low?=off"; ++ noant = <&ant1>,"output-high?=off", ++ <&ant1>, "output-low?=on", ++ <&ant2>, "output-high?=off", ++ <&ant2>, "output-low?=on"; ++ ++ spi_dma4 = <&spi0>, "dmas:0=", <&dma40>, ++ <&spi0>, "dmas:8=", <&dma40>; ++ }; ++}; +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -92,6 +92,12 @@ Name: <The base DTB> + Info: Configures the base Raspberry Pi hardware + Load: <loaded automatically> + Params: ++ ant1 Select antenna 1 (default). CM4 only. ++ ++ ant2 Select antenna 2. CM4 only. ++ ++ noant Disable both antennas. CM4 only. ++ + audio Set to "on" to enable the onboard ALSA audio + interface (default "off") + diff --git a/target/linux/bcm27xx/patches-5.4/950-0786-PCI-brcmstb-Add-DT-property-to-control-L1SS.patch b/target/linux/bcm27xx/patches-5.4/950-0786-PCI-brcmstb-Add-DT-property-to-control-L1SS.patch new file mode 100644 index 0000000000..1d54cff647 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0786-PCI-brcmstb-Add-DT-property-to-control-L1SS.patch @@ -0,0 +1,79 @@ +From faca7230ba711f7f966cd51bf46f83c5848a8623 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Thu, 11 Jun 2020 09:57:03 +0100 +Subject: [PATCH] PCI: brcmstb: Add DT property to control L1SS + +The BRCM PCIe block has controls to enable control of the CLKREQ# +signal by the L1SS, and to gate the refclk with the CLKREQ# input. +These controls are mutually exclusive - the upstream code sets the +latter, but some use cases require the former. + +Add a Device Tree property - brcm,enable-l1ss - to switch to the +L1SS configuration. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/pci/controller/pcie-brcmstb.c | 30 ++++++++++++++++++++------- + 1 file changed, 23 insertions(+), 7 deletions(-) + +--- a/drivers/pci/controller/pcie-brcmstb.c ++++ b/drivers/pci/controller/pcie-brcmstb.c +@@ -102,8 +102,9 @@ + PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8) + + #define PCIE_MISC_HARD_PCIE_HARD_DEBUG 0x4204 +-#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2 +-#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000 ++#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK BIT(1) ++#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_L1SS_ENABLE_MASK BIT(21) ++#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK BIT(27) + + #define PCIE_MSI_INTR2_STATUS 0x4500 + #define PCIE_MSI_INTR2_CLR 0x4508 +@@ -170,6 +171,7 @@ struct brcm_pcie { + struct pci_bus *root_bus; + struct device_node *np; + bool ssc; ++ bool l1ss; + int gen; + u64 msi_target_addr; + struct brcm_msi *msi; +@@ -834,12 +836,25 @@ static int brcm_pcie_setup(struct brcm_p + PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK); + writel(tmp, base + PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1); + +- /* +- * Refclk from RC should be gated with CLKREQ# input when ASPM L0s,L1 +- * is enabled => setting the CLKREQ_DEBUG_ENABLE field to 1. +- */ + tmp = readl(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG); +- tmp |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK; ++ if (pcie->l1ss) { ++ /* ++ * Enable CLKREQ# signalling include L1 Substate control of ++ * the CLKREQ# signal and the external reference clock buffer. ++ * meet requirement for Endpoints that require CLKREQ# ++ * assertion to clock active within 400ns. ++ */ ++ tmp &= ~PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK; ++ tmp |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_L1SS_ENABLE_MASK; ++ } else { ++ /* ++ * Refclk from RC should be gated with CLKREQ# input when ++ * ASPM L0s,L1 is enabled => setting the CLKREQ_DEBUG_ENABLE ++ * field to 1. ++ */ ++ tmp &= ~PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_L1SS_ENABLE_MASK; ++ tmp |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK; ++ } + writel(tmp, base + PCIE_MISC_HARD_PCIE_HARD_DEBUG); + + return 0; +@@ -944,6 +959,7 @@ static int brcm_pcie_probe(struct platfo + pcie->gen = (ret < 0) ? 0 : ret; + + pcie->ssc = of_property_read_bool(np, "brcm,enable-ssc"); ++ pcie->l1ss = of_property_read_bool(np, "brcm,enable-l1ss"); + + ret = pci_parse_request_of_pci_ranges(pcie->dev, &bridge->windows, + &bridge->dma_ranges, NULL); diff --git a/target/linux/bcm27xx/patches-5.4/950-0787-ARM-dts-Set-brcm-enable-l1ss-for-CM4.patch b/target/linux/bcm27xx/patches-5.4/950-0787-ARM-dts-Set-brcm-enable-l1ss-for-CM4.patch new file mode 100644 index 0000000000..4b53564311 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0787-ARM-dts-Set-brcm-enable-l1ss-for-CM4.patch @@ -0,0 +1,27 @@ +From a883d8b6624ea9b924323920cac080cb68e02110 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Thu, 11 Jun 2020 11:22:38 +0100 +Subject: [PATCH] ARM: dts: Set brcm,enable-l1ss for CM4 + +Enable the PCIE L1SS on Compute Module 4. It's possible that this is +also the right thing to do for Pi 4, but it has been working as is +up to now. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts +@@ -252,6 +252,10 @@ + /delete-node/ wifi-pwrseq; + }; + ++&pcie0 { ++ brcm,enable-l1ss; ++}; ++ + &mmcnr { + pinctrl-names = "default"; + pinctrl-0 = <&sdio_pins>; diff --git a/target/linux/bcm27xx/patches-5.4/950-0788-Revert-SQUASH-Fix-spi-driver-compiler-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-0788-Revert-SQUASH-Fix-spi-driver-compiler-warnings.patch new file mode 100644 index 0000000000..437e5aba59 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0788-Revert-SQUASH-Fix-spi-driver-compiler-warnings.patch @@ -0,0 +1,23 @@ +From 34072d0778e21edf69455d900b8a16be6b9ac95c Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Tue, 16 Jun 2020 10:23:03 +0100 +Subject: [PATCH] Revert "SQUASH: Fix spi driver compiler warnings" + +This reverts commit fe3f696b7e5229678ae45d1293e97b5ecc00c245. + +See: https://github.com/raspberrypi/linux/pull/3687 +--- + drivers/spi/spi-bcm2835.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/spi/spi-bcm2835.c ++++ b/drivers/spi/spi-bcm2835.c +@@ -1182,6 +1182,8 @@ static int bcm2835_spi_setup(struct spi_ + { + struct spi_controller *ctlr = spi->controller; + struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); ++ struct gpio_chip *chip; ++ enum gpio_lookup_flags lflags; + u32 cs; + + /* diff --git a/target/linux/bcm27xx/patches-5.4/950-0789-Revert-spi-spi-bcm2835-Disable-forced-software-CS.patch b/target/linux/bcm27xx/patches-5.4/950-0789-Revert-spi-spi-bcm2835-Disable-forced-software-CS.patch new file mode 100644 index 0000000000..1479335217 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0789-Revert-spi-spi-bcm2835-Disable-forced-software-CS.patch @@ -0,0 +1,59 @@ +From 1d78f72cb5a387922870e2a54228be25f84f95f6 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Tue, 16 Jun 2020 10:23:29 +0100 +Subject: [PATCH] Revert "spi: spi-bcm2835: Disable forced software + CS" + +This reverts commit 2697f0186db346176832b8eb79adaf5c874681e8. + +See: https://github.com/raspberrypi/linux/pull/3687 +--- + drivers/spi/spi-bcm2835.c | 37 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +--- a/drivers/spi/spi-bcm2835.c ++++ b/drivers/spi/spi-bcm2835.c +@@ -1235,6 +1235,43 @@ static int bcm2835_spi_setup(struct spi_ + return -EINVAL; + } + ++ /* ++ * Translate native CS to GPIO ++ * ++ * FIXME: poking around in the gpiolib internals like this is ++ * not very good practice. Find a way to locate the real problem ++ * and fix it. Why is the GPIO descriptor in spi->cs_gpiod ++ * sometimes not assigned correctly? Erroneous device trees? ++ */ ++ ++ /* get the gpio chip for the base */ ++ chip = gpiochip_find("pinctrl-bcm2835", chip_match_name); ++ if (!chip) ++ return 0; ++ ++ /* ++ * Retrieve the corresponding GPIO line used for CS. ++ * The inversion semantics will be handled by the GPIO core ++ * code, so we pass GPIOS_OUT_LOW for "unasserted" and ++ * the correct flag for inversion semantics. The SPI_CS_HIGH ++ * on spi->mode cannot be checked for polarity in this case ++ * as the flag use_gpio_descriptors enforces SPI_CS_HIGH. ++ */ ++ if (of_property_read_bool(spi->dev.of_node, "spi-cs-high")) ++ lflags = GPIO_ACTIVE_HIGH; ++ else ++ lflags = GPIO_ACTIVE_LOW; ++ spi->cs_gpiod = gpiochip_request_own_desc(chip, 8 - spi->chip_select, ++ DRV_NAME, ++ lflags, ++ GPIOD_OUT_LOW); ++ if (IS_ERR(spi->cs_gpiod)) ++ return PTR_ERR(spi->cs_gpiod); ++ ++ /* and set up the "mode" and level */ ++ dev_info(&spi->dev, "setting up native-CS%i to use GPIO\n", ++ spi->chip_select); ++ + return 0; + } + diff --git a/target/linux/bcm27xx/patches-5.4/950-0790-media-irs1125-Using-i2c_transfer-for-ic2-reads.patch b/target/linux/bcm27xx/patches-5.4/950-0790-media-irs1125-Using-i2c_transfer-for-ic2-reads.patch new file mode 100644 index 0000000000..c68c6ea801 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0790-media-irs1125-Using-i2c_transfer-for-ic2-reads.patch @@ -0,0 +1,65 @@ +From 167060f4e3303200d373ca55a39ba4b4c55adbcc Mon Sep 17 00:00:00 2001 +From: Markus Proeller <markus.proeller@pieye.org> +Date: Tue, 16 Jun 2020 13:24:31 +0200 +Subject: [PATCH] media: irs1125: Using i2c_transfer for ic2 reads + +Reading data over i2c is done by using i2c_transfer to ensure that this +operation can't be interrupted. + +Signed-off-by: Markus Proeller <markus.proeller@pieye.org> +--- + drivers/media/i2c/irs1125.c | 37 ++++++++++++++++++++++--------------- + 1 file changed, 22 insertions(+), 15 deletions(-) + +--- a/drivers/media/i2c/irs1125.c ++++ b/drivers/media/i2c/irs1125.c +@@ -248,27 +248,34 @@ static int irs1125_write(struct v4l2_sub + + static int irs1125_read(struct v4l2_subdev *sd, u16 reg, u16 *val) + { +- int ret; +- unsigned char data_w[2] = { reg >> 8, reg & 0xff }; +- char rdval[2]; +- + struct i2c_client *client = v4l2_get_subdevdata(sd); ++ struct i2c_msg msgs[2]; ++ u8 addr_buf[2] = { reg >> 8, reg & 0xff }; ++ u8 data_buf[2] = { 0, }; ++ int ret; + +- ret = i2c_master_send(client, data_w, 2); +- if (ret < 0) { +- dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n", +- __func__, reg); ++ /* Write register address */ ++ msgs[0].addr = client->addr; ++ msgs[0].flags = 0; ++ msgs[0].len = ARRAY_SIZE(addr_buf); ++ msgs[0].buf = addr_buf; ++ ++ /* Read data from register */ ++ msgs[1].addr = client->addr; ++ msgs[1].flags = I2C_M_RD; ++ msgs[1].len = 2; ++ msgs[1].buf = data_buf; ++ ++ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); ++ if (ret != ARRAY_SIZE(msgs)) { ++ if (ret >= 0) ++ ret = -EIO; + return ret; + } + +- ret = i2c_master_recv(client, rdval, 2); +- if (ret < 0) +- dev_err(&client->dev, "%s: i2c read error, reg: %x\n", +- __func__, reg); +- +- *val = rdval[1] | (rdval[0] << 8); ++ *val = data_buf[1] | (data_buf[0] << 8); + +- return ret; ++ return 0; + } + + static int irs1125_write_array(struct v4l2_subdev *sd, diff --git a/target/linux/bcm27xx/patches-5.4/950-0791-media-irs1125-Refactoring-and-debug-messages.patch b/target/linux/bcm27xx/patches-5.4/950-0791-media-irs1125-Refactoring-and-debug-messages.patch new file mode 100644 index 0000000000..c26ab8fd77 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0791-media-irs1125-Refactoring-and-debug-messages.patch @@ -0,0 +1,123 @@ +From 6ba58915e8c2f884d17b651d68535959f9eff97d Mon Sep 17 00:00:00 2001 +From: Markus Proeller <markus.proeller@pieye.org> +Date: Tue, 16 Jun 2020 13:27:42 +0200 +Subject: [PATCH] media: irs1125: Refactoring and debug messages + +Changed some variable names to comply with checkpatch --strict mode. +Debug messages added. + +Signed-off-by: Markus Proeller <markus.proeller@pieye.org> +--- + drivers/media/i2c/irs1125.c | 36 ++++++++++++++++++++---------------- + 1 file changed, 20 insertions(+), 16 deletions(-) + +--- a/drivers/media/i2c/irs1125.c ++++ b/drivers/media/i2c/irs1125.c +@@ -15,6 +15,7 @@ + #include "irs1125.h" + #include <linux/clk.h> + #include <linux/delay.h> ++#include <linux/firmware.h> + #include <linux/gpio/consumer.h> + #include <linux/i2c.h> + #include <linux/init.h> +@@ -22,13 +23,13 @@ + #include <linux/module.h> + #include <linux/of_graph.h> + #include <linux/slab.h> ++#include <linux/types.h> + #include <linux/videodev2.h> +-#include <linux/firmware.h> ++#include <media/v4l2-ctrls.h> + #include <media/v4l2-device.h> + #include <media/v4l2-fwnode.h> + #include <media/v4l2-image-sizes.h> + #include <media/v4l2-mediabus.h> +-#include <media/v4l2-ctrls.h> + + #define CHECK_BIT(val, pos) ((val) & BIT(pos)) + +@@ -38,18 +39,19 @@ + + #define IRS1125_ALTERNATE_FW "irs1125_af.bin" + +-#define IRS1125_REG_CSICFG 0xA882 +-#define IRS1125_REG_DESIGN_STEP 0xB0AD +-#define IRS1125_REG_EFUSEVAL2 0xB09F +-#define IRS1125_REG_EFUSEVAL3 0xB0A0 +-#define IRS1125_REG_EFUSEVAL4 0xB0A1 +-#define IRS1125_REG_DMEM_SHADOW 0xC320 ++#define IRS1125_REG_SAFE_RECONFIG 0xA850 ++#define IRS1125_REG_CSICFG 0xA882 ++#define IRS1125_REG_DESIGN_STEP 0xB0AD ++#define IRS1125_REG_EFUSEVAL2 0xB09F ++#define IRS1125_REG_EFUSEVAL3 0xB0A0 ++#define IRS1125_REG_EFUSEVAL4 0xB0A1 ++#define IRS1125_REG_DMEM_SHADOW 0xC320 + +-#define IRS1125_DESIGN_STEP_EXPECTED 0x0a12 ++#define IRS1125_DESIGN_STEP_EXPECTED 0x0a12 + + #define IRS1125_ROW_START_DEF 0 + #define IRS1125_COLUMN_START_DEF 0 +-#define IRS1125_WINDOW_HEIGHT_DEF 288 ++#define IRS1125_WINDOW_HEIGHT_DEF 288 + #define IRS1125_WINDOW_WIDTH_DEF 352 + + struct regval_list { +@@ -87,7 +89,7 @@ static inline struct irs1125 *to_state(s + return container_of(sd, struct irs1125, sd); + } + +-static struct regval_list irs1125_26MHz[] = { ++static struct regval_list irs1125_26mhz[] = { + {0xB017, 0x0413}, + {0xB086, 0x3535}, + {0xB0AE, 0xEF02}, +@@ -153,7 +155,7 @@ static struct regval_list irs1125_26MHz[ + {0xFFFF, 100} + }; + +-static struct regval_list irs1125_seq_cfg[] = { ++static struct regval_list irs1125_seq_cfg_init[] = { + {0xC3A0, 0x823D}, + {0xC3A1, 0xB13B}, + {0xC3A2, 0x0313}, +@@ -243,6 +245,7 @@ static int irs1125_write(struct v4l2_sub + dev_err(&client->dev, "%s: i2c write error, reg: %x\n", + __func__, reg); + ++ dev_dbg(&client->dev, "write addr 0x%04x, val 0x%04x\n", reg, val); + return ret; + } + +@@ -364,8 +367,8 @@ static int __sensor_init(struct v4l2_sub + cnt++; + } + +- ret = irs1125_write_array(sd, irs1125_26MHz, +- ARRAY_SIZE(irs1125_26MHz)); ++ ret = irs1125_write_array(sd, irs1125_26mhz, ++ ARRAY_SIZE(irs1125_26mhz)); + if (ret < 0) { + dev_err(&client->dev, "write sensor default regs error\n"); + return ret; +@@ -415,8 +418,8 @@ static int __sensor_init(struct v4l2_sub + } + release_firmware(fw); + +- ret = irs1125_write_array(sd, irs1125_seq_cfg, +- ARRAY_SIZE(irs1125_seq_cfg)); ++ ret = irs1125_write_array(sd, irs1125_seq_cfg_init, ++ ARRAY_SIZE(irs1125_seq_cfg_init)); + if (ret < 0) { + dev_err(&client->dev, "write default sequence failed\n"); + return ret; +@@ -1037,6 +1040,7 @@ static int irs1125_probe(struct i2c_clie + } + + gpio_num = desc_to_gpio(sensor->reset); ++ dev_dbg(&client->dev, "reset on GPIO num %d\n", gpio_num); + + mutex_init(&sensor->lock); + diff --git a/target/linux/bcm27xx/patches-5.4/950-0792-media-irs1125-Atomic-access-to-imager-reconfiguratio.patch b/target/linux/bcm27xx/patches-5.4/950-0792-media-irs1125-Atomic-access-to-imager-reconfiguratio.patch new file mode 100644 index 0000000000..2b5d4b53d5 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0792-media-irs1125-Atomic-access-to-imager-reconfiguratio.patch @@ -0,0 +1,381 @@ +From 3afb0a757409f5186812b3ea36c61a03855e47d2 Mon Sep 17 00:00:00 2001 +From: Markus Proeller <markus.proeller@pieye.org> +Date: Tue, 16 Jun 2020 13:31:36 +0200 +Subject: [PATCH] media: irs1125: Atomic access to imager + reconfiguration + +Instead of changing the exposure and framerate settings for all sequences, +they can be changed for every sequence individually now. Therefore the +IRS1125_CID_SAFE_RECONFIG ctrl has been removed and replaced by +IRS1125_CID_SAFE_RECONFIG_S<seq_num>_EXPO and *_FRAME ctrls. + +The consistency check in the sequence ctrl IRS1125_CID_SEQ_CONFIG +is removed. + +Signed-off-by: Markus Proeller <markus.proeller@pieye.org> +--- + drivers/media/i2c/irs1125.c | 224 ++++++++++++++++++++++++------------ + drivers/media/i2c/irs1125.h | 68 ++++++++--- + 2 files changed, 204 insertions(+), 88 deletions(-) + +--- a/drivers/media/i2c/irs1125.c ++++ b/drivers/media/i2c/irs1125.c +@@ -89,6 +89,52 @@ static inline struct irs1125 *to_state(s + return container_of(sd, struct irs1125, sd); + } + ++static const char *expo_ctrl_names[IRS1125_NUM_SEQ_ENTRIES] = { ++ "safe reconfiguration of exposure of sequence 0", ++ "safe reconfiguration of exposure of sequence 1", ++ "safe reconfiguration of exposure of sequence 2", ++ "safe reconfiguration of exposure of sequence 3", ++ "safe reconfiguration of exposure of sequence 4", ++ "safe reconfiguration of exposure of sequence 5", ++ "safe reconfiguration of exposure of sequence 6", ++ "safe reconfiguration of exposure of sequence 7", ++ "safe reconfiguration of exposure of sequence 8", ++ "safe reconfiguration of exposure of sequence 9", ++ "safe reconfiguration of exposure of sequence 10", ++ "safe reconfiguration of exposure of sequence 11", ++ "safe reconfiguration of exposure of sequence 12", ++ "safe reconfiguration of exposure of sequence 13", ++ "safe reconfiguration of exposure of sequence 14", ++ "safe reconfiguration of exposure of sequence 15", ++ "safe reconfiguration of exposure of sequence 16", ++ "safe reconfiguration of exposure of sequence 17", ++ "safe reconfiguration of exposure of sequence 18", ++ "safe reconfiguration of exposure of sequence 19", ++}; ++ ++static const char *frame_ctrl_names[IRS1125_NUM_SEQ_ENTRIES] = { ++ "safe reconfiguration of framerate of sequence 0", ++ "safe reconfiguration of framerate of sequence 1", ++ "safe reconfiguration of framerate of sequence 2", ++ "safe reconfiguration of framerate of sequence 3", ++ "safe reconfiguration of framerate of sequence 4", ++ "safe reconfiguration of framerate of sequence 5", ++ "safe reconfiguration of framerate of sequence 6", ++ "safe reconfiguration of framerate of sequence 7", ++ "safe reconfiguration of framerate of sequence 8", ++ "safe reconfiguration of framerate of sequence 9", ++ "safe reconfiguration of framerate of sequence 10", ++ "safe reconfiguration of framerate of sequence 11", ++ "safe reconfiguration of framerate of sequence 12", ++ "safe reconfiguration of framerate of sequence 13", ++ "safe reconfiguration of framerate of sequence 14", ++ "safe reconfiguration of framerate of sequence 15", ++ "safe reconfiguration of framerate of sequence 16", ++ "safe reconfiguration of framerate of sequence 17", ++ "safe reconfiguration of framerate of sequence 18", ++ "safe reconfiguration of framerate of sequence 19", ++}; ++ + static struct regval_list irs1125_26mhz[] = { + {0xB017, 0x0413}, + {0xB086, 0x3535}, +@@ -561,36 +607,57 @@ static int irs1125_s_ctrl(struct v4l2_ct + struct irs1125 *dev = container_of(ctrl->handler, + struct irs1125, ctrl_handler); + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); +- int err, i; + struct irs1125_mod_pll *mod_cur, *mod_new; +- struct irs1125_seq_cfg *cfg_cur, *cfg_new; + u16 addr, val; +- +- err = 0; ++ int err = 0, i; + + switch (ctrl->id) { +- case IRS1125_CID_SAFE_RECONFIG: +- { +- struct irs1125_illu *illu_cur, *illu_new; +- +- illu_new = (struct irs1125_illu *)ctrl->p_new.p; +- illu_cur = (struct irs1125_illu *)ctrl->p_cur.p; +- for (i = 0; i < IRS1125_NUM_SEQ_ENTRIES; i++) { +- if (illu_cur[i].exposure != illu_new[i].exposure) { +- addr = 0xA850 + i * 2; +- val = illu_new[i].exposure; +- err = irs1125_write(&dev->sd, addr, val); +- if (err < 0) +- break; +- } +- if (illu_cur[i].framerate != illu_new[i].framerate) { +- addr = 0xA851 + i * 2; +- val = illu_new[i].framerate; +- err = irs1125_write(&dev->sd, addr, val); +- if (err < 0) +- break; +- } +- } ++ case IRS1125_CID_SAFE_RECONFIG_S0_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S0_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S1_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S1_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S2_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S2_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S3_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S3_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S4_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S4_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S5_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S5_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S6_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S6_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S7_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S7_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S8_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S8_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S9_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S9_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S10_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S10_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S11_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S11_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S12_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S12_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S13_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S13_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S14_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S14_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S15_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S15_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S16_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S16_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S17_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S17_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S18_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S18_FRAME: ++ case IRS1125_CID_SAFE_RECONFIG_S19_EXPO: ++ case IRS1125_CID_SAFE_RECONFIG_S19_FRAME: { ++ unsigned int offset = ctrl->id - ++ IRS1125_CID_SAFE_RECONFIG_S0_EXPO; ++ ++ err = irs1125_write(&dev->sd, ++ IRS1125_REG_SAFE_RECONFIG + offset, ++ ctrl->val); + break; + } + case IRS1125_CID_MOD_PLL: +@@ -655,40 +722,40 @@ static int irs1125_s_ctrl(struct v4l2_ct + } + } + break; +- case IRS1125_CID_SEQ_CONFIG: ++ case IRS1125_CID_SEQ_CONFIG: { ++ struct irs1125_seq_cfg *cfg_new; ++ + cfg_new = (struct irs1125_seq_cfg *)ctrl->p_new.p; +- cfg_cur = (struct irs1125_seq_cfg *)ctrl->p_cur.p; + for (i = 0; i < IRS1125_NUM_SEQ_ENTRIES; i++) { +- if (cfg_cur[i].exposure != cfg_new[i].exposure) { +- addr = IRS1125_REG_DMEM_SHADOW + i * 4; +- val = cfg_new[i].exposure; +- err = irs1125_write(&dev->sd, addr, val); +- if (err < 0) +- break; +- } +- if (cfg_cur[i].framerate != cfg_new[i].framerate) { +- addr = IRS1125_REG_DMEM_SHADOW + 1 + i * 4; +- val = cfg_new[i].framerate; +- err = irs1125_write(&dev->sd, addr, val); +- if (err < 0) +- break; +- } +- if (cfg_cur[i].ps != cfg_new[i].ps) { +- addr = IRS1125_REG_DMEM_SHADOW + 2 + i * 4; +- val = cfg_new[i].ps; +- err = irs1125_write(&dev->sd, addr, val); +- if (err < 0) +- break; +- } +- if (cfg_cur[i].pll != cfg_new[i].pll) { +- addr = IRS1125_REG_DMEM_SHADOW + 3 + i * 4; +- val = cfg_new[i].pll; +- err = irs1125_write(&dev->sd, addr, val); +- if (err < 0) +- break; +- } ++ unsigned int seq_offset = i * 4; ++ u16 addr, val; ++ ++ addr = IRS1125_REG_DMEM_SHADOW + seq_offset; ++ val = cfg_new[i].exposure; ++ err = irs1125_write(&dev->sd, addr, val); ++ if (err < 0) ++ break; ++ ++ addr = IRS1125_REG_DMEM_SHADOW + 1 + seq_offset; ++ val = cfg_new[i].framerate; ++ err = irs1125_write(&dev->sd, addr, val); ++ if (err < 0) ++ break; ++ ++ addr = IRS1125_REG_DMEM_SHADOW + 2 + seq_offset; ++ val = cfg_new[i].ps; ++ err = irs1125_write(&dev->sd, addr, val); ++ if (err < 0) ++ break; ++ ++ addr = IRS1125_REG_DMEM_SHADOW + 3 + seq_offset; ++ val = cfg_new[i].pll; ++ err = irs1125_write(&dev->sd, addr, val); ++ if (err < 0) ++ break; + } + break; ++ } + case IRS1125_CID_NUM_SEQS: + err = irs1125_write(&dev->sd, 0xA88D, ctrl->val - 1); + if (err >= 0) +@@ -760,19 +827,6 @@ static const struct v4l2_ctrl_config irs + IRS1125_NUM_MOD_PLLS} + }, { + .ops = &irs1125_ctrl_ops, +- .id = IRS1125_CID_SAFE_RECONFIG, +- .name = "Change exposure and pause of single seq", +- .type = V4L2_CTRL_TYPE_U16, +- .flags = V4L2_CTRL_FLAG_HAS_PAYLOAD, +- .min = 0, +- .max = U16_MAX, +- .step = 1, +- .def = 0, +- .elem_size = sizeof(u16), +- .dims = {sizeof(struct irs1125_illu) / sizeof(u16), +- IRS1125_NUM_SEQ_ENTRIES} +- }, { +- .ops = &irs1125_ctrl_ops, + .id = IRS1125_CID_SEQ_CONFIG, + .name = "Change sequence settings", + .type = V4L2_CTRL_TYPE_U16, +@@ -900,9 +954,16 @@ static int irs1125_ctrls_init(struct irs + { + struct v4l2_ctrl *ctrl; + int err, i; +- struct v4l2_ctrl_handler *hdl; ++ struct v4l2_ctrl_handler *hdl = &sensor->ctrl_handler; ++ struct v4l2_ctrl_config ctrl_cfg = { ++ .ops = &irs1125_ctrl_ops, ++ .type = V4L2_CTRL_TYPE_INTEGER, ++ .min = 0, ++ .max = U16_MAX, ++ .step = 1, ++ .def = 0x1000 ++ }; + +- hdl = &sensor->ctrl_handler; + v4l2_ctrl_handler_init(hdl, ARRAY_SIZE(irs1125_custom_ctrls)); + + for (i = 0; i < ARRAY_SIZE(irs1125_custom_ctrls); i++) { +@@ -923,6 +984,27 @@ static int irs1125_ctrls_init(struct irs + goto error_ctrls; + } + ++ for (i = 0; i < IRS1125_NUM_SEQ_ENTRIES; i++) { ++ ctrl_cfg.name = expo_ctrl_names[i]; ++ ctrl_cfg.id = IRS1125_CID_SAFE_RECONFIG_S0_EXPO + i * 2; ++ ctrl = v4l2_ctrl_new_custom(hdl, &ctrl_cfg, ++ NULL); ++ if (!ctrl) ++ dev_err(dev, "Failed to init exposure control %s\n", ++ ctrl_cfg.name); ++ } ++ ++ ctrl_cfg.def = 0; ++ for (i = 0; i < IRS1125_NUM_SEQ_ENTRIES; i++) { ++ ctrl_cfg.name = frame_ctrl_names[i]; ++ ctrl_cfg.id = IRS1125_CID_SAFE_RECONFIG_S0_FRAME + i * 2; ++ ctrl = v4l2_ctrl_new_custom(hdl, &ctrl_cfg, ++ NULL); ++ if (!ctrl) ++ dev_err(dev, "Failed to init framerate control %s\n", ++ ctrl_cfg.name); ++ } ++ + sensor->sd.ctrl_handler = hdl; + return 0; + +--- a/drivers/media/i2c/irs1125.h ++++ b/drivers/media/i2c/irs1125.h +@@ -21,18 +21,57 @@ + #define IRS1125_NUM_SEQ_ENTRIES 20 + #define IRS1125_NUM_MOD_PLLS 4 + +-#define IRS1125_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000) +-#define IRS1125_CID_SAFE_RECONFIG (IRS1125_CID_CUSTOM_BASE + 0) +-#define IRS1125_CID_CONTINUOUS_TRIG (IRS1125_CID_CUSTOM_BASE + 1) +-#define IRS1125_CID_TRIGGER (IRS1125_CID_CUSTOM_BASE + 2) +-#define IRS1125_CID_RECONFIG (IRS1125_CID_CUSTOM_BASE + 3) +-#define IRS1125_CID_ILLU_ON (IRS1125_CID_CUSTOM_BASE + 4) +-#define IRS1125_CID_NUM_SEQS (IRS1125_CID_CUSTOM_BASE + 5) +-#define IRS1125_CID_MOD_PLL (IRS1125_CID_CUSTOM_BASE + 6) +-#define IRS1125_CID_SEQ_CONFIG (IRS1125_CID_CUSTOM_BASE + 7) +-#define IRS1125_CID_IDENT0 (IRS1125_CID_CUSTOM_BASE + 8) +-#define IRS1125_CID_IDENT1 (IRS1125_CID_CUSTOM_BASE + 9) +-#define IRS1125_CID_IDENT2 (IRS1125_CID_CUSTOM_BASE + 10) ++#define IRS1125_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000) ++#define IRS1125_CID_CONTINUOUS_TRIG (IRS1125_CID_CUSTOM_BASE + 1) ++#define IRS1125_CID_TRIGGER (IRS1125_CID_CUSTOM_BASE + 2) ++#define IRS1125_CID_RECONFIG (IRS1125_CID_CUSTOM_BASE + 3) ++#define IRS1125_CID_ILLU_ON (IRS1125_CID_CUSTOM_BASE + 4) ++#define IRS1125_CID_NUM_SEQS (IRS1125_CID_CUSTOM_BASE + 5) ++#define IRS1125_CID_MOD_PLL (IRS1125_CID_CUSTOM_BASE + 6) ++#define IRS1125_CID_SEQ_CONFIG (IRS1125_CID_CUSTOM_BASE + 7) ++#define IRS1125_CID_IDENT0 (IRS1125_CID_CUSTOM_BASE + 8) ++#define IRS1125_CID_IDENT1 (IRS1125_CID_CUSTOM_BASE + 9) ++#define IRS1125_CID_IDENT2 (IRS1125_CID_CUSTOM_BASE + 10) ++#define IRS1125_CID_SAFE_RECONFIG_S0_EXPO (IRS1125_CID_CUSTOM_BASE + 11) ++#define IRS1125_CID_SAFE_RECONFIG_S0_FRAME (IRS1125_CID_CUSTOM_BASE + 12) ++#define IRS1125_CID_SAFE_RECONFIG_S1_EXPO (IRS1125_CID_CUSTOM_BASE + 13) ++#define IRS1125_CID_SAFE_RECONFIG_S1_FRAME (IRS1125_CID_CUSTOM_BASE + 14) ++#define IRS1125_CID_SAFE_RECONFIG_S2_EXPO (IRS1125_CID_CUSTOM_BASE + 15) ++#define IRS1125_CID_SAFE_RECONFIG_S2_FRAME (IRS1125_CID_CUSTOM_BASE + 16) ++#define IRS1125_CID_SAFE_RECONFIG_S3_EXPO (IRS1125_CID_CUSTOM_BASE + 17) ++#define IRS1125_CID_SAFE_RECONFIG_S3_FRAME (IRS1125_CID_CUSTOM_BASE + 18) ++#define IRS1125_CID_SAFE_RECONFIG_S4_EXPO (IRS1125_CID_CUSTOM_BASE + 19) ++#define IRS1125_CID_SAFE_RECONFIG_S4_FRAME (IRS1125_CID_CUSTOM_BASE + 20) ++#define IRS1125_CID_SAFE_RECONFIG_S5_EXPO (IRS1125_CID_CUSTOM_BASE + 21) ++#define IRS1125_CID_SAFE_RECONFIG_S5_FRAME (IRS1125_CID_CUSTOM_BASE + 22) ++#define IRS1125_CID_SAFE_RECONFIG_S6_EXPO (IRS1125_CID_CUSTOM_BASE + 23) ++#define IRS1125_CID_SAFE_RECONFIG_S6_FRAME (IRS1125_CID_CUSTOM_BASE + 24) ++#define IRS1125_CID_SAFE_RECONFIG_S7_EXPO (IRS1125_CID_CUSTOM_BASE + 25) ++#define IRS1125_CID_SAFE_RECONFIG_S7_FRAME (IRS1125_CID_CUSTOM_BASE + 26) ++#define IRS1125_CID_SAFE_RECONFIG_S8_EXPO (IRS1125_CID_CUSTOM_BASE + 27) ++#define IRS1125_CID_SAFE_RECONFIG_S8_FRAME (IRS1125_CID_CUSTOM_BASE + 28) ++#define IRS1125_CID_SAFE_RECONFIG_S9_EXPO (IRS1125_CID_CUSTOM_BASE + 29) ++#define IRS1125_CID_SAFE_RECONFIG_S9_FRAME (IRS1125_CID_CUSTOM_BASE + 30) ++#define IRS1125_CID_SAFE_RECONFIG_S10_EXPO (IRS1125_CID_CUSTOM_BASE + 31) ++#define IRS1125_CID_SAFE_RECONFIG_S10_FRAME (IRS1125_CID_CUSTOM_BASE + 32) ++#define IRS1125_CID_SAFE_RECONFIG_S11_EXPO (IRS1125_CID_CUSTOM_BASE + 33) ++#define IRS1125_CID_SAFE_RECONFIG_S11_FRAME (IRS1125_CID_CUSTOM_BASE + 34) ++#define IRS1125_CID_SAFE_RECONFIG_S12_EXPO (IRS1125_CID_CUSTOM_BASE + 35) ++#define IRS1125_CID_SAFE_RECONFIG_S12_FRAME (IRS1125_CID_CUSTOM_BASE + 36) ++#define IRS1125_CID_SAFE_RECONFIG_S13_EXPO (IRS1125_CID_CUSTOM_BASE + 37) ++#define IRS1125_CID_SAFE_RECONFIG_S13_FRAME (IRS1125_CID_CUSTOM_BASE + 38) ++#define IRS1125_CID_SAFE_RECONFIG_S14_EXPO (IRS1125_CID_CUSTOM_BASE + 39) ++#define IRS1125_CID_SAFE_RECONFIG_S14_FRAME (IRS1125_CID_CUSTOM_BASE + 40) ++#define IRS1125_CID_SAFE_RECONFIG_S15_EXPO (IRS1125_CID_CUSTOM_BASE + 41) ++#define IRS1125_CID_SAFE_RECONFIG_S15_FRAME (IRS1125_CID_CUSTOM_BASE + 42) ++#define IRS1125_CID_SAFE_RECONFIG_S16_EXPO (IRS1125_CID_CUSTOM_BASE + 43) ++#define IRS1125_CID_SAFE_RECONFIG_S16_FRAME (IRS1125_CID_CUSTOM_BASE + 44) ++#define IRS1125_CID_SAFE_RECONFIG_S17_EXPO (IRS1125_CID_CUSTOM_BASE + 45) ++#define IRS1125_CID_SAFE_RECONFIG_S17_FRAME (IRS1125_CID_CUSTOM_BASE + 46) ++#define IRS1125_CID_SAFE_RECONFIG_S18_EXPO (IRS1125_CID_CUSTOM_BASE + 47) ++#define IRS1125_CID_SAFE_RECONFIG_S18_FRAME (IRS1125_CID_CUSTOM_BASE + 48) ++#define IRS1125_CID_SAFE_RECONFIG_S19_EXPO (IRS1125_CID_CUSTOM_BASE + 49) ++#define IRS1125_CID_SAFE_RECONFIG_S19_FRAME (IRS1125_CID_CUSTOM_BASE + 50) + + struct irs1125_seq_cfg { + __u16 exposure; +@@ -41,11 +80,6 @@ struct irs1125_seq_cfg { + __u16 pll; + }; + +-struct irs1125_illu { +- __u16 exposure; +- __u16 framerate; +-}; +- + struct irs1125_mod_pll { + __u16 pllcfg1; + __u16 pllcfg2; diff --git a/target/linux/bcm27xx/patches-5.4/950-0793-media-irs1125-Keep-HW-in-sync-after-imager-reset.patch b/target/linux/bcm27xx/patches-5.4/950-0793-media-irs1125-Keep-HW-in-sync-after-imager-reset.patch new file mode 100644 index 0000000000..9e9b2729cc --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0793-media-irs1125-Keep-HW-in-sync-after-imager-reset.patch @@ -0,0 +1,181 @@ +From be2df6c864ba668364011301530372f5b8798593 Mon Sep 17 00:00:00 2001 +From: Markus Proeller <markus.proeller@pieye.org> +Date: Tue, 16 Jun 2020 13:33:56 +0200 +Subject: [PATCH] media: irs1125: Keep HW in sync after imager reset + +When closing the video device, the irs1125 is put in power down state. +To keep V4L2 ctrls and the HW in sync, v4l2_ctrl_handler_setup is +called after power up. + +The compound ctrl IRS1125_CID_MOD_PLL however has a default value +of all zeros, which puts the imager into a non responding state. +Thus, this ctrl is not written by the driver into HW after power up. +The userspace has to take care to write senseful data. + +Signed-off-by: Markus Proeller <markus.proeller@pieye.org> +--- + drivers/media/i2c/irs1125.c | 121 +++++++++++++++++------------------- + 1 file changed, 58 insertions(+), 63 deletions(-) + +--- a/drivers/media/i2c/irs1125.c ++++ b/drivers/media/i2c/irs1125.c +@@ -82,6 +82,7 @@ struct irs1125 { + struct v4l2_ctrl *ctrl_numseq; + + int power_count; ++ bool mod_pll_init; + }; + + static inline struct irs1125 *to_state(struct v4l2_subdev *sd) +@@ -276,8 +277,7 @@ static struct regval_list irs1125_seq_cf + {0xC039, 0x0000}, + {0xC401, 0x0002}, + +- {0xFFFF, 1}, +- {0xA87C, 0x0001} ++ {0xFFFF, 1} + }; + + static int irs1125_write(struct v4l2_subdev *sd, u16 reg, u16 val) +@@ -471,7 +471,11 @@ static int __sensor_init(struct v4l2_sub + return ret; + } + +- return 0; ++ irs1125->mod_pll_init = true; ++ v4l2_ctrl_handler_setup(&irs1125->ctrl_handler); ++ irs1125->mod_pll_init = false; ++ ++ return irs1125_write(sd, 0xA87C, 0x0001); + } + + static int irs1125_sensor_power(struct v4l2_subdev *sd, int on) +@@ -607,8 +611,6 @@ static int irs1125_s_ctrl(struct v4l2_ct + struct irs1125 *dev = container_of(ctrl->handler, + struct irs1125, ctrl_handler); + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); +- struct irs1125_mod_pll *mod_cur, *mod_new; +- u16 addr, val; + int err = 0, i; + + switch (ctrl->id) { +@@ -660,68 +662,61 @@ static int irs1125_s_ctrl(struct v4l2_ct + ctrl->val); + break; + } +- case IRS1125_CID_MOD_PLL: ++ case IRS1125_CID_MOD_PLL: { ++ struct irs1125_mod_pll *mod_new; ++ ++ if (dev->mod_pll_init) ++ break; ++ + mod_new = (struct irs1125_mod_pll *)ctrl->p_new.p; +- mod_cur = (struct irs1125_mod_pll *)ctrl->p_cur.p; + for (i = 0; i < IRS1125_NUM_MOD_PLLS; i++) { +- if (mod_cur[i].pllcfg1 != mod_new[i].pllcfg1) { +- addr = 0xC3A0 + i * 3; +- val = mod_new[i].pllcfg1; +- err = irs1125_write(&dev->sd, addr, val); +- if (err < 0) +- break; +- } +- if (mod_cur[i].pllcfg2 != mod_new[i].pllcfg2) { +- addr = 0xC3A1 + i * 3; +- val = mod_new[i].pllcfg2; +- err = irs1125_write(&dev->sd, addr, val); +- if (err < 0) +- break; +- } +- if (mod_cur[i].pllcfg3 != mod_new[i].pllcfg3) { +- addr = 0xC3A2 + i * 3; +- val = mod_new[i].pllcfg3; +- err = irs1125_write(&dev->sd, addr, val); +- if (err < 0) +- break; +- } +- if (mod_cur[i].pllcfg4 != mod_new[i].pllcfg4) { +- addr = 0xC24C + i * 5; +- val = mod_new[i].pllcfg4; +- err = irs1125_write(&dev->sd, addr, val); +- if (err < 0) +- break; +- } +- if (mod_cur[i].pllcfg5 != mod_new[i].pllcfg5) { +- addr = 0xC24D + i * 5; +- val = mod_new[i].pllcfg5; +- err = irs1125_write(&dev->sd, addr, val); +- if (err < 0) +- break; +- } +- if (mod_cur[i].pllcfg6 != mod_new[i].pllcfg6) { +- addr = 0xC24E + i * 5; +- val = mod_new[i].pllcfg6; +- err = irs1125_write(&dev->sd, addr, val); +- if (err < 0) +- break; +- } +- if (mod_cur[i].pllcfg7 != mod_new[i].pllcfg7) { +- addr = 0xC24F + i * 5; +- val = mod_new[i].pllcfg7; +- err = irs1125_write(&dev->sd, addr, val); +- if (err < 0) +- break; +- } +- if (mod_cur[i].pllcfg8 != mod_new[i].pllcfg8) { +- addr = 0xC250 + i * 5; +- val = mod_new[i].pllcfg8; +- err = irs1125_write(&dev->sd, addr, val); +- if (err < 0) +- break; +- } ++ unsigned int pll_offset, ssc_offset; ++ ++ pll_offset = i * 3; ++ ssc_offset = i * 5; ++ ++ err = irs1125_write(&dev->sd, 0xC3A0 + pll_offset, ++ mod_new[i].pllcfg1); ++ if (err < 0) ++ break; ++ ++ err = irs1125_write(&dev->sd, 0xC3A1 + pll_offset, ++ mod_new[i].pllcfg2); ++ if (err < 0) ++ break; ++ ++ err = irs1125_write(&dev->sd, 0xC3A2 + pll_offset, ++ mod_new[i].pllcfg3); ++ if (err < 0) ++ break; ++ ++ err = irs1125_write(&dev->sd, 0xC24C + ssc_offset, ++ mod_new[i].pllcfg4); ++ if (err < 0) ++ break; ++ ++ err = irs1125_write(&dev->sd, 0xC24D + ssc_offset, ++ mod_new[i].pllcfg5); ++ if (err < 0) ++ break; ++ ++ err = irs1125_write(&dev->sd, 0xC24E + ssc_offset, ++ mod_new[i].pllcfg6); ++ if (err < 0) ++ break; ++ ++ err = irs1125_write(&dev->sd, 0xC24F + ssc_offset, ++ mod_new[i].pllcfg7); ++ if (err < 0) ++ break; ++ ++ err = irs1125_write(&dev->sd, 0xC250 + ssc_offset, ++ mod_new[i].pllcfg8); ++ if (err < 0) ++ break; + } + break; ++ } + case IRS1125_CID_SEQ_CONFIG: { + struct irs1125_seq_cfg *cfg_new; + diff --git a/target/linux/bcm27xx/patches-5.4/950-0794-staging-bcm2835-audio-Add-missing-MODULE_ALIAS.patch b/target/linux/bcm27xx/patches-5.4/950-0794-staging-bcm2835-audio-Add-missing-MODULE_ALIAS.patch new file mode 100644 index 0000000000..5e096442bb --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0794-staging-bcm2835-audio-Add-missing-MODULE_ALIAS.patch @@ -0,0 +1,30 @@ +From 1f7c929fc7b010ceca45f8b91b22e71e697b6ec7 Mon Sep 17 00:00:00 2001 +From: Maxim Mikityanskiy <maxtram95@gmail.com> +Date: Sat, 20 Jun 2020 15:40:00 +0300 +Subject: [PATCH] staging: bcm2835-audio: Add missing MODULE_ALIAS + +Commit 8353fe6f1e0f ("Revert "staging: bcm2835-audio: Drop DT +dependency"") reverts the upstream change and makes bcm2835-audio use +device tree again, however, it also removes the MODULE_ALIAS for the +platform device. This MODULE_ALIAS is needed, because VCHIQ registers +bcm2835-audio as a child platform device since commit 25c7597af20d +("staging: vchiq_arm: Register a platform device for audio"), and this +mechanism is adopted also in the downstream kernel. + +This commit puts back that MODULE_ALIAS to make bcm2835-audio +autoprobing work again. The rest of VCHIQ children have their +MODULE_ALIASes in place. + +Fixes: 8353fe6f1e0f ("Revert "staging: bcm2835-audio: Drop DT dependency"") +Signed-off-by: Maxim Mikityanskiy <maxtram95@gmail.com> +--- + drivers/staging/vc04_services/bcm2835-audio/bcm2835.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +@@ -438,3 +438,4 @@ module_platform_driver(bcm2835_alsa_driv + MODULE_AUTHOR("Dom Cobley"); + MODULE_DESCRIPTION("Alsa driver for BCM2835 chip"); + MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:bcm2835_audio"); diff --git a/target/linux/bcm27xx/patches-5.4/950-0795-media-v4l2-subdev-Introduce-get-set-_mbus_config-pad.patch b/target/linux/bcm27xx/patches-5.4/950-0795-media-v4l2-subdev-Introduce-get-set-_mbus_config-pad.patch new file mode 100644 index 0000000000..910828421b --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0795-media-v4l2-subdev-Introduce-get-set-_mbus_config-pad.patch @@ -0,0 +1,63 @@ +From 487203abdef24b7d3cdd110f1b1e699fd22aa02c Mon Sep 17 00:00:00 2001 +From: Jacopo Mondi <jacopo+renesas@jmondi.org> +Date: Tue, 16 Jun 2020 16:12:36 +0200 +Subject: [PATCH]_mbus_config + pad ops + +Upstream https://patchwork.linuxtv.org/patch/64669/ + +Introduce two new pad operations to allow retrieving and configuring the +media bus parameters on a subdevice pad. + +The newly introduced operations aims to replace the s/g_mbus_config video +operations, which have been on their way for deprecation since a long +time. + +Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org> +--- + include/media/v4l2-subdev.h | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +--- a/include/media/v4l2-subdev.h ++++ b/include/media/v4l2-subdev.h +@@ -670,6 +670,29 @@ struct v4l2_subdev_pad_config { + * + * @set_frame_desc: set the low level media bus frame parameters, @fd array + * may be adjusted by the subdev driver to device capabilities. ++ * ++ * @get_mbus_config: get the media bus configuration of a remote sub-device. ++ * The media bus configuration is usually retrieved from the ++ * firmware interface at sub-device probe time, immediately ++ * applied to the hardware and eventually adjusted by the ++ * driver. Remote sub-devices (usually video receivers) shall ++ * use this operation to query the transmitting end bus ++ * configuration in order to adjust their own one accordingly. ++ * Callers should make sure they get the most up-to-date as ++ * possible configuration from the remote end, likely calling ++ * this operation as close as possible to stream on time. The ++ * operation shall fail if the pad index it has been called on ++ * is not valid. ++ * ++ * @set_mbus_config: set the media bus configuration of a remote sub-device. ++ * This operations is intended to allow, in combination with ++ * the get_mbus_config operation, the negotiation of media bus ++ * configuration parameters between media sub-devices. The ++ * operation shall not fail if the requested configuration is ++ * not supported, but the driver shall update the content of ++ * the %config argument to reflect what has been actually ++ * applied to the hardware. The operation shall fail if the ++ * pad index it has been called on is not valid. + */ + struct v4l2_subdev_pad_ops { + int (*init_cfg)(struct v4l2_subdev *sd, +@@ -710,6 +733,10 @@ struct v4l2_subdev_pad_ops { + struct v4l2_mbus_frame_desc *fd); + int (*set_frame_desc)(struct v4l2_subdev *sd, unsigned int pad, + struct v4l2_mbus_frame_desc *fd); ++ int (*get_mbus_config)(struct v4l2_subdev *sd, unsigned int pad, ++ struct v4l2_mbus_config *config); ++ int (*set_mbus_config)(struct v4l2_subdev *sd, unsigned int pad, ++ struct v4l2_mbus_config *config); + }; + + /** diff --git a/target/linux/bcm27xx/patches-5.4/950-0796-media-i2c-Use-the-new-get_mbus_config-pad-op.patch b/target/linux/bcm27xx/patches-5.4/950-0796-media-i2c-Use-the-new-get_mbus_config-pad-op.patch new file mode 100644 index 0000000000..5c432d0c00 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0796-media-i2c-Use-the-new-get_mbus_config-pad-op.patch @@ -0,0 +1,235 @@ +From 87fde70ab0ba99860153b127e6821be5ae74e73b Mon Sep 17 00:00:00 2001 +From: Jacopo Mondi <jacopo+renesas@jmondi.org> +Date: Tue, 16 Jun 2020 16:12:37 +0200 +Subject: [PATCH] media: i2c: Use the new get_mbus_config pad op + +Upstream https://patchwork.linuxtv.org/patch/64669/ + +Move the existing users of the g_mbus_config video operation to use the +newly introduced get_mbus_config pad operations. + +All the ported drivers report a static media bus configuration and do no +support s_mbus_config so the operation implementation has not changed. + +Bridge drivers needs to call the new pad operation and will receive an +-ENOICTLCMD when calling the old g_mbus_config video operation + +Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org> +--- + drivers/media/i2c/adv7180.c | 7 ++++--- + drivers/media/i2c/ml86v7667.c | 7 ++++--- + drivers/media/i2c/mt9m001.c | 7 ++++--- + drivers/media/i2c/mt9m111.c | 7 ++++--- + drivers/media/i2c/ov9640.c | 7 ++++--- + drivers/media/i2c/tc358743.c | 7 ++++--- + drivers/media/i2c/tvp5150.c | 7 ++++--- + 7 files changed, 28 insertions(+), 21 deletions(-) + +--- a/drivers/media/i2c/adv7180.c ++++ b/drivers/media/i2c/adv7180.c +@@ -749,8 +749,9 @@ static int adv7180_set_pad_format(struct + return ret; + } + +-static int adv7180_g_mbus_config(struct v4l2_subdev *sd, +- struct v4l2_mbus_config *cfg) ++static int adv7180_get_mbus_config(struct v4l2_subdev *sd, ++ unsigned int pad, ++ struct v4l2_mbus_config *cfg) + { + struct adv7180_state *state = to_state(sd); + +@@ -841,7 +842,6 @@ static const struct v4l2_subdev_video_op + .querystd = adv7180_querystd, + .g_input_status = adv7180_g_input_status, + .s_routing = adv7180_s_routing, +- .g_mbus_config = adv7180_g_mbus_config, + .g_pixelaspect = adv7180_g_pixelaspect, + .g_tvnorms = adv7180_g_tvnorms, + .s_stream = adv7180_s_stream, +@@ -857,6 +857,7 @@ static const struct v4l2_subdev_pad_ops + .enum_mbus_code = adv7180_enum_mbus_code, + .set_fmt = adv7180_set_pad_format, + .get_fmt = adv7180_get_pad_format, ++ .get_mbus_config = adv7180_get_mbus_config, + }; + + static const struct v4l2_subdev_sensor_ops adv7180_sensor_ops = { +--- a/drivers/media/i2c/ml86v7667.c ++++ b/drivers/media/i2c/ml86v7667.c +@@ -219,8 +219,9 @@ static int ml86v7667_fill_fmt(struct v4l + return 0; + } + +-static int ml86v7667_g_mbus_config(struct v4l2_subdev *sd, +- struct v4l2_mbus_config *cfg) ++static int ml86v7667_get_mbus_config(struct v4l2_subdev *sd, ++ unsigned int pad, ++ struct v4l2_mbus_config *cfg) + { + cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING | + V4L2_MBUS_DATA_ACTIVE_HIGH; +@@ -291,13 +292,13 @@ static const struct v4l2_subdev_video_op + .s_std = ml86v7667_s_std, + .querystd = ml86v7667_querystd, + .g_input_status = ml86v7667_g_input_status, +- .g_mbus_config = ml86v7667_g_mbus_config, + }; + + static const struct v4l2_subdev_pad_ops ml86v7667_subdev_pad_ops = { + .enum_mbus_code = ml86v7667_enum_mbus_code, + .get_fmt = ml86v7667_fill_fmt, + .set_fmt = ml86v7667_fill_fmt, ++ .get_mbus_config = ml86v7667_get_mbus_config, + }; + + static const struct v4l2_subdev_core_ops ml86v7667_subdev_core_ops = { +--- a/drivers/media/i2c/mt9m001.c ++++ b/drivers/media/i2c/mt9m001.c +@@ -689,8 +689,9 @@ static int mt9m001_enum_mbus_code(struct + return 0; + } + +-static int mt9m001_g_mbus_config(struct v4l2_subdev *sd, +- struct v4l2_mbus_config *cfg) ++static int mt9m001_get_mbus_config(struct v4l2_subdev *sd, ++ unsigned int pad, ++ struct v4l2_mbus_config *cfg) + { + /* MT9M001 has all capture_format parameters fixed */ + cfg->flags = V4L2_MBUS_PCLK_SAMPLE_FALLING | +@@ -703,7 +704,6 @@ static int mt9m001_g_mbus_config(struct + + static const struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = { + .s_stream = mt9m001_s_stream, +- .g_mbus_config = mt9m001_g_mbus_config, + }; + + static const struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = { +@@ -717,6 +717,7 @@ static const struct v4l2_subdev_pad_ops + .set_selection = mt9m001_set_selection, + .get_fmt = mt9m001_get_fmt, + .set_fmt = mt9m001_set_fmt, ++ .get_mbus_config = mt9m001_get_mbus_config, + }; + + static const struct v4l2_subdev_ops mt9m001_subdev_ops = { +--- a/drivers/media/i2c/mt9m111.c ++++ b/drivers/media/i2c/mt9m111.c +@@ -1137,8 +1137,9 @@ static int mt9m111_init_cfg(struct v4l2_ + return 0; + } + +-static int mt9m111_g_mbus_config(struct v4l2_subdev *sd, +- struct v4l2_mbus_config *cfg) ++static int mt9m111_get_mbus_config(struct v4l2_subdev *sd, ++ unsigned int pad, ++ struct v4l2_mbus_config *cfg) + { + struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); + +@@ -1155,7 +1156,6 @@ static int mt9m111_g_mbus_config(struct + } + + static const struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = { +- .g_mbus_config = mt9m111_g_mbus_config, + .s_stream = mt9m111_s_stream, + .g_frame_interval = mt9m111_g_frame_interval, + .s_frame_interval = mt9m111_s_frame_interval, +@@ -1168,6 +1168,7 @@ static const struct v4l2_subdev_pad_ops + .set_selection = mt9m111_set_selection, + .get_fmt = mt9m111_get_fmt, + .set_fmt = mt9m111_set_fmt, ++ .get_mbus_config = mt9m111_get_mbus_config, + }; + + static const struct v4l2_subdev_ops mt9m111_subdev_ops = { +--- a/drivers/media/i2c/ov9640.c ++++ b/drivers/media/i2c/ov9640.c +@@ -648,8 +648,9 @@ static const struct v4l2_subdev_core_ops + }; + + /* Request bus settings on camera side */ +-static int ov9640_g_mbus_config(struct v4l2_subdev *sd, +- struct v4l2_mbus_config *cfg) ++static int ov9640_get_mbus_config(struct v4l2_subdev *sd, ++ unsigned int pad, ++ struct v4l2_mbus_config *cfg) + { + cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER | + V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH | +@@ -661,13 +662,13 @@ static int ov9640_g_mbus_config(struct v + + static const struct v4l2_subdev_video_ops ov9640_video_ops = { + .s_stream = ov9640_s_stream, +- .g_mbus_config = ov9640_g_mbus_config, + }; + + static const struct v4l2_subdev_pad_ops ov9640_pad_ops = { + .enum_mbus_code = ov9640_enum_mbus_code, + .get_selection = ov9640_get_selection, + .set_fmt = ov9640_set_fmt, ++ .get_mbus_config = ov9640_get_mbus_config, + }; + + static const struct v4l2_subdev_ops ov9640_subdev_ops = { +--- a/drivers/media/i2c/tc358743.c ++++ b/drivers/media/i2c/tc358743.c +@@ -1621,8 +1621,9 @@ static int tc358743_dv_timings_cap(struc + return 0; + } + +-static int tc358743_g_mbus_config(struct v4l2_subdev *sd, +- struct v4l2_mbus_config *cfg) ++static int tc358743_get_mbus_config(struct v4l2_subdev *sd, ++ unsigned int pad, ++ struct v4l2_mbus_config *cfg) + { + struct tc358743_state *state = to_state(sd); + const u32 mask = V4L2_MBUS_CSI2_LANE_MASK; +@@ -1852,7 +1853,6 @@ static const struct v4l2_subdev_video_op + .s_dv_timings = tc358743_s_dv_timings, + .g_dv_timings = tc358743_g_dv_timings, + .query_dv_timings = tc358743_query_dv_timings, +- .g_mbus_config = tc358743_g_mbus_config, + .s_stream = tc358743_s_stream, + }; + +@@ -1864,6 +1864,7 @@ static const struct v4l2_subdev_pad_ops + .set_edid = tc358743_s_edid, + .enum_dv_timings = tc358743_enum_dv_timings, + .dv_timings_cap = tc358743_dv_timings_cap, ++ .get_mbus_config = tc358743_get_mbus_config, + }; + + static const struct v4l2_subdev_ops tc358743_ops = { +--- a/drivers/media/i2c/tvp5150.c ++++ b/drivers/media/i2c/tvp5150.c +@@ -1104,8 +1104,9 @@ static int tvp5150_get_selection(struct + } + } + +-static int tvp5150_g_mbus_config(struct v4l2_subdev *sd, +- struct v4l2_mbus_config *cfg) ++static int tvp5150_get_mbus_config(struct v4l2_subdev *sd, ++ unsigned int pad, ++ struct v4l2_mbus_config *cfg) + { + struct tvp5150 *decoder = to_tvp5150(sd); + +@@ -1411,7 +1412,6 @@ static const struct v4l2_subdev_video_op + .querystd = tvp5150_querystd, + .s_stream = tvp5150_s_stream, + .s_routing = tvp5150_s_routing, +- .g_mbus_config = tvp5150_g_mbus_config, + }; + + static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = { +@@ -1429,6 +1429,7 @@ static const struct v4l2_subdev_pad_ops + .get_fmt = tvp5150_fill_fmt, + .get_selection = tvp5150_get_selection, + .set_selection = tvp5150_set_selection, ++ .get_mbus_config = tvp5150_get_mbus_config, + }; + + static const struct v4l2_subdev_ops tvp5150_ops = { diff --git a/target/linux/bcm27xx/patches-5.4/950-0797-media-i2c-ov6650-Use-new-get-set-_mbus_config-ops.patch b/target/linux/bcm27xx/patches-5.4/950-0797-media-i2c-ov6650-Use-new-get-set-_mbus_config-ops.patch new file mode 100644 index 0000000000..d1c0a65baf --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0797-media-i2c-ov6650-Use-new-get-set-_mbus_config-ops.patch @@ -0,0 +1,134 @@ +From 0dd7e12bb7dc81e09440f3330465c31349497dc3 Mon Sep 17 00:00:00 2001 +From: Jacopo Mondi <jacopo+renesas@jmondi.org> +Date: Tue, 16 Jun 2020 16:12:38 +0200 +Subject: [PATCH]_mbus_config + ops + +Upstream https://patchwork.linuxtv.org/patch/64674/ + +Use the new get_mbus_config and set_mbus_config pad operations in place +of the video operations currently in use. + +Compared to other drivers where the same conversion has been performed, +ov6650 proved to be a bit more tricky, as the existing g_mbus_config +implementation did not report the currently applied configuration but +the set of all possible configuration options. + +Adapt the driver to support the semantic of the two newly introduced +operations: +- get_mbus_config reports the current media bus configuration +- set_mbus_config applies only changes explicitly requested and updates + the provided cfg parameter to report what has actually been applied to + the hardware. + +Compile-tested only. + +Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org> +--- + drivers/media/i2c/ov6650.c | 56 ++++++++++++++++++++++++++------------ + 1 file changed, 39 insertions(+), 17 deletions(-) + +--- a/drivers/media/i2c/ov6650.c ++++ b/drivers/media/i2c/ov6650.c +@@ -909,46 +909,68 @@ static const struct v4l2_subdev_core_ops + }; + + /* Request bus settings on camera side */ +-static int ov6650_g_mbus_config(struct v4l2_subdev *sd, +- struct v4l2_mbus_config *cfg) ++static int ov6650_get_mbus_config(struct v4l2_subdev *sd, ++ unsigned int pad, ++ struct v4l2_mbus_config *cfg) + { ++ struct i2c_client *client = v4l2_get_subdevdata(sd); ++ u8 comj, comf; ++ int ret; ++ ++ ret = ov6650_reg_read(client, REG_COMJ, &comj); ++ if (ret) ++ return ret; ++ ++ ret = ov6650_reg_read(client, REG_COMF, &comf); ++ if (ret) ++ return ret; + +- cfg->flags = V4L2_MBUS_MASTER | +- V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | +- V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW | +- V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW | +- V4L2_MBUS_DATA_ACTIVE_HIGH; ++ cfg->flags = V4L2_MBUS_MASTER ++ | ((comj & COMJ_VSYNC_HIGH) ? V4L2_MBUS_VSYNC_ACTIVE_HIGH ++ : V4L2_MBUS_VSYNC_ACTIVE_LOW) ++ | ((comf & COMF_HREF_LOW) ? V4L2_MBUS_HSYNC_ACTIVE_LOW ++ : V4L2_MBUS_HSYNC_ACTIVE_HIGH) ++ | ((comj & COMJ_PCLK_RISING) ? V4L2_MBUS_PCLK_SAMPLE_RISING ++ : V4L2_MBUS_PCLK_SAMPLE_FALLING); + cfg->type = V4L2_MBUS_PARALLEL; + + return 0; + } + + /* Alter bus settings on camera side */ +-static int ov6650_s_mbus_config(struct v4l2_subdev *sd, +- const struct v4l2_mbus_config *cfg) ++static int ov6650_set_mbus_config(struct v4l2_subdev *sd, ++ unsigned int pad, ++ struct v4l2_mbus_config *cfg) + { + struct i2c_client *client = v4l2_get_subdevdata(sd); +- int ret; ++ int ret = 0; + + if (cfg->flags & V4L2_MBUS_PCLK_SAMPLE_RISING) + ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_PCLK_RISING, 0); +- else ++ else if (cfg->flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) + ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_PCLK_RISING); + if (ret) +- return ret; ++ goto error; + + if (cfg->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) + ret = ov6650_reg_rmw(client, REG_COMF, COMF_HREF_LOW, 0); +- else ++ else if (cfg->flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) + ret = ov6650_reg_rmw(client, REG_COMF, 0, COMF_HREF_LOW); + if (ret) +- return ret; ++ goto error; + + if (cfg->flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) + ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_VSYNC_HIGH, 0); +- else ++ else if (cfg->flags & V4L2_MBUS_VSYNC_ACTIVE_LOW) + ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_VSYNC_HIGH); + ++error: ++ /* ++ * Update the configuration to report what is actually applied to ++ * the hardware. ++ */ ++ ov6650_get_mbus_config(sd, pad, cfg); ++ + return ret; + } + +@@ -956,8 +978,6 @@ static const struct v4l2_subdev_video_op + .s_stream = ov6650_s_stream, + .g_frame_interval = ov6650_g_frame_interval, + .s_frame_interval = ov6650_s_frame_interval, +- .g_mbus_config = ov6650_g_mbus_config, +- .s_mbus_config = ov6650_s_mbus_config, + }; + + static const struct v4l2_subdev_pad_ops ov6650_pad_ops = { +@@ -966,6 +986,8 @@ static const struct v4l2_subdev_pad_ops + .set_selection = ov6650_set_selection, + .get_fmt = ov6650_get_fmt, + .set_fmt = ov6650_set_fmt, ++ .get_mbus_config = ov6650_get_mbus_config, ++ .set_mbus_config = ov6650_set_mbus_config, + }; + + static const struct v4l2_subdev_ops ov6650_subdev_ops = { diff --git a/target/linux/bcm27xx/patches-5.4/950-0798-media-pxa_camera-Use-the-new-set_mbus_config-op.patch b/target/linux/bcm27xx/patches-5.4/950-0798-media-pxa_camera-Use-the-new-set_mbus_config-op.patch new file mode 100644 index 0000000000..d682cf842f --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0798-media-pxa_camera-Use-the-new-set_mbus_config-op.patch @@ -0,0 +1,285 @@ +From 63f4970ce038e60455a6225b317d0b259e046c94 Mon Sep 17 00:00:00 2001 +From: Jacopo Mondi <jacopo+renesas@jmondi.org> +Date: Tue, 16 Jun 2020 16:12:39 +0200 +Subject: [PATCH] media: pxa_camera: Use the new set_mbus_config op + +Upstream https://patchwork.linuxtv.org/patch/64671/ + +Move the PXA camera driver to use the new set_mbus_config pad operation. +For this platform the change is not only cosmetic, as the pxa driver is +currently the only driver in mainline to make use of the g_mbus_config +and s_mbus_config video operations. + +The existing driver semantic is the following: +- Collect all supported mbus config flags from the remote end +- Match them with the supported PXA mbus configuration flags +- If the remote subdevice allows multiple options for for VSYNC, HSYNC + and PCLK polarity, use platform data requested settings + +The semantic of the new get_mbus_config and set_mbus_config differs from +the corresponding video ops, particularly in the fact get_mbus_config +reports the current mbus configuration and not the set of supported +configuration options, with set_mbus_config always reporting the actual +mbus configuration applied to the remote subdevice. + +Adapt the driver to perform the following +- Set the remote subdevice mbus configuration according to the PXA + platform data preferences. +- If the applied configuration differs from the requested one (i.e. the + remote subdevice does not allow changing one setting) make sure that + - The remote end does not claim for DATA_ACTIVE_LOW, which seems not + supported by the platform + - The bus mastering roles match + +While at there remove a few checks performed on the media bus +configuration at get_format() time as they do not belong there. + +Compile-tested only. + +Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org> +--- + drivers/media/platform/pxa_camera.c | 189 ++++++++-------------------- + 1 file changed, 51 insertions(+), 138 deletions(-) + +--- a/drivers/media/platform/pxa_camera.c ++++ b/drivers/media/platform/pxa_camera.c +@@ -605,42 +605,6 @@ static const struct pxa_mbus_pixelfmt *p + return pxa_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt)); + } + +-static unsigned int pxa_mbus_config_compatible(const struct v4l2_mbus_config *cfg, +- unsigned int flags) +-{ +- unsigned long common_flags; +- bool hsync = true, vsync = true, pclk, data, mode; +- bool mipi_lanes, mipi_clock; +- +- common_flags = cfg->flags & flags; +- +- switch (cfg->type) { +- case V4L2_MBUS_PARALLEL: +- hsync = common_flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH | +- V4L2_MBUS_HSYNC_ACTIVE_LOW); +- vsync = common_flags & (V4L2_MBUS_VSYNC_ACTIVE_HIGH | +- V4L2_MBUS_VSYNC_ACTIVE_LOW); +- /* fall through */ +- case V4L2_MBUS_BT656: +- pclk = common_flags & (V4L2_MBUS_PCLK_SAMPLE_RISING | +- V4L2_MBUS_PCLK_SAMPLE_FALLING); +- data = common_flags & (V4L2_MBUS_DATA_ACTIVE_HIGH | +- V4L2_MBUS_DATA_ACTIVE_LOW); +- mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE); +- return (!hsync || !vsync || !pclk || !data || !mode) ? +- 0 : common_flags; +- case V4L2_MBUS_CSI2_DPHY: +- mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES; +- mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK | +- V4L2_MBUS_CSI2_CONTINUOUS_CLOCK); +- return (!mipi_lanes || !mipi_clock) ? 0 : common_flags; +- default: +- WARN_ON(1); +- return -EINVAL; +- } +- return 0; +-} +- + /** + * struct pxa_camera_format_xlate - match between host and sensor formats + * @code: code of a sensor provided format +@@ -1231,31 +1195,6 @@ static irqreturn_t pxa_camera_irq(int ir + return IRQ_HANDLED; + } + +-static int test_platform_param(struct pxa_camera_dev *pcdev, +- unsigned char buswidth, unsigned long *flags) +-{ +- /* +- * Platform specified synchronization and pixel clock polarities are +- * only a recommendation and are only used during probing. The PXA270 +- * quick capture interface supports both. +- */ +- *flags = (pcdev->platform_flags & PXA_CAMERA_MASTER ? +- V4L2_MBUS_MASTER : V4L2_MBUS_SLAVE) | +- V4L2_MBUS_HSYNC_ACTIVE_HIGH | +- V4L2_MBUS_HSYNC_ACTIVE_LOW | +- V4L2_MBUS_VSYNC_ACTIVE_HIGH | +- V4L2_MBUS_VSYNC_ACTIVE_LOW | +- V4L2_MBUS_DATA_ACTIVE_HIGH | +- V4L2_MBUS_PCLK_SAMPLE_RISING | +- V4L2_MBUS_PCLK_SAMPLE_FALLING; +- +- /* If requested data width is supported by the platform, use it */ +- if ((1 << (buswidth - 1)) & pcdev->width_flags) +- return 0; +- +- return -EINVAL; +-} +- + static void pxa_camera_setup_cicr(struct pxa_camera_dev *pcdev, + unsigned long flags, __u32 pixfmt) + { +@@ -1598,99 +1537,78 @@ static int pxa_camera_init_videobuf2(str + */ + static int pxa_camera_set_bus_param(struct pxa_camera_dev *pcdev) + { ++ unsigned int bus_width = pcdev->current_fmt->host_fmt->bits_per_sample; + struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; + u32 pixfmt = pcdev->current_fmt->host_fmt->fourcc; +- unsigned long bus_flags, common_flags; ++ int mbus_config; + int ret; + +- ret = test_platform_param(pcdev, +- pcdev->current_fmt->host_fmt->bits_per_sample, +- &bus_flags); +- if (ret < 0) +- return ret; +- +- ret = sensor_call(pcdev, video, g_mbus_config, &cfg); +- if (!ret) { +- common_flags = pxa_mbus_config_compatible(&cfg, +- bus_flags); +- if (!common_flags) { +- dev_warn(pcdev_to_dev(pcdev), +- "Flags incompatible: camera 0x%x, host 0x%lx\n", +- cfg.flags, bus_flags); +- return -EINVAL; +- } +- } else if (ret != -ENOIOCTLCMD) { +- return ret; +- } else { +- common_flags = bus_flags; ++ if (!((1 << (bus_width - 1)) & pcdev->width_flags)) { ++ dev_err(pcdev_to_dev(pcdev), "Unsupported bus width %u", ++ bus_width); ++ return -EINVAL; + } + + pcdev->channels = 1; + + /* Make choices, based on platform preferences */ +- if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) && +- (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) { +- if (pcdev->platform_flags & PXA_CAMERA_HSP) +- common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH; +- else +- common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW; +- } +- +- if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) && +- (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) { +- if (pcdev->platform_flags & PXA_CAMERA_VSP) +- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH; +- else +- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW; +- } +- +- if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) && +- (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) { +- if (pcdev->platform_flags & PXA_CAMERA_PCP) +- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING; +- else +- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING; +- } +- +- cfg.flags = common_flags; +- ret = sensor_call(pcdev, video, s_mbus_config, &cfg); +- if (ret < 0 && ret != -ENOIOCTLCMD) { +- dev_dbg(pcdev_to_dev(pcdev), +- "camera s_mbus_config(0x%lx) returned %d\n", +- common_flags, ret); +- return ret; +- } ++ mbus_config = 0; ++ if (pcdev->platform_flags & PXA_CAMERA_MASTER) ++ mbus_config |= V4L2_MBUS_MASTER; ++ else ++ mbus_config |= V4L2_MBUS_SLAVE; + +- pxa_camera_setup_cicr(pcdev, common_flags, pixfmt); ++ if (pcdev->platform_flags & PXA_CAMERA_HSP) ++ mbus_config |= V4L2_MBUS_HSYNC_ACTIVE_HIGH; ++ else ++ mbus_config |= V4L2_MBUS_HSYNC_ACTIVE_LOW; + +- return 0; +-} ++ if (pcdev->platform_flags & PXA_CAMERA_VSP) ++ mbus_config |= V4L2_MBUS_VSYNC_ACTIVE_HIGH; ++ else ++ mbus_config |= V4L2_MBUS_VSYNC_ACTIVE_LOW; + +-static int pxa_camera_try_bus_param(struct pxa_camera_dev *pcdev, +- unsigned char buswidth) +-{ +- struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; +- unsigned long bus_flags, common_flags; +- int ret = test_platform_param(pcdev, buswidth, &bus_flags); ++ if (pcdev->platform_flags & PXA_CAMERA_PCP) ++ mbus_config |= V4L2_MBUS_PCLK_SAMPLE_RISING; ++ else ++ mbus_config |= V4L2_MBUS_PCLK_SAMPLE_FALLING; ++ mbus_config |= V4L2_MBUS_DATA_ACTIVE_HIGH; + +- if (ret < 0) ++ cfg.flags = mbus_config; ++ ret = sensor_call(pcdev, pad, set_mbus_config, 0, &cfg); ++ if (ret < 0 && ret != -ENOIOCTLCMD) { ++ dev_err(pcdev_to_dev(pcdev), ++ "Failed to call set_mbus_config: %d\n", ret); + return ret; ++ } ++ ++ /* ++ * If the requested media bus configuration has not been fully applied ++ * make sure it is supported by the platform. ++ * ++ * PXA does not support V4L2_MBUS_DATA_ACTIVE_LOW and the bus mastering ++ * roles should match. ++ */ ++ if (cfg.flags != mbus_config) { ++ unsigned int pxa_mbus_role = mbus_config & (V4L2_MBUS_MASTER | ++ V4L2_MBUS_SLAVE); ++ if (pxa_mbus_role != (cfg.flags & (V4L2_MBUS_MASTER | ++ V4L2_MBUS_SLAVE))) { ++ dev_err(pcdev_to_dev(pcdev), ++ "Unsupported mbus configuration: bus mastering\n"); ++ return -EINVAL; ++ } + +- ret = sensor_call(pcdev, video, g_mbus_config, &cfg); +- if (!ret) { +- common_flags = pxa_mbus_config_compatible(&cfg, +- bus_flags); +- if (!common_flags) { +- dev_warn(pcdev_to_dev(pcdev), +- "Flags incompatible: camera 0x%x, host 0x%lx\n", +- cfg.flags, bus_flags); ++ if (cfg.flags & V4L2_MBUS_DATA_ACTIVE_LOW) { ++ dev_err(pcdev_to_dev(pcdev), ++ "Unsupported mbus configuration: DATA_ACTIVE_LOW\n"); + return -EINVAL; + } +- } else if (ret == -ENOIOCTLCMD) { +- ret = 0; + } + +- return ret; ++ pxa_camera_setup_cicr(pcdev, cfg.flags, pixfmt); ++ ++ return 0; + } + + static const struct pxa_mbus_pixelfmt pxa_camera_formats[] = { +@@ -1738,11 +1656,6 @@ static int pxa_camera_get_formats(struct + return 0; + } + +- /* This also checks support for the requested bits-per-sample */ +- ret = pxa_camera_try_bus_param(pcdev, fmt->bits_per_sample); +- if (ret < 0) +- return 0; +- + switch (code.code) { + case MEDIA_BUS_FMT_UYVY8_2X8: + formats++; diff --git a/target/linux/bcm27xx/patches-5.4/950-0799-media-v4l2-subdev-Remove-s-g-_mbus_config-video-ops.patch b/target/linux/bcm27xx/patches-5.4/950-0799-media-v4l2-subdev-Remove-s-g-_mbus_config-video-ops.patch new file mode 100644 index 0000000000..a7186da342 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0799-media-v4l2-subdev-Remove-s-g-_mbus_config-video-ops.patch @@ -0,0 +1,43 @@ +From 316ebebe8edf42f264a0b2225adc5baa46451415 Mon Sep 17 00:00:00 2001 +From: Jacopo Mondi <jacopo+renesas@jmondi.org> +Date: Tue, 16 Jun 2020 16:12:40 +0200 +Subject: [PATCH]_mbus_config video + ops + +Upstream https://patchwork.linuxtv.org/patch/64670/ + +With all sensor and platform drivers now converted to use the new +get_mbus_config and set_mbus_config pad operations, remove the +deprecated video operations g_mbus_config and s_mbus_config. + +Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org> +--- + include/media/v4l2-subdev.h | 10 ---------- + 1 file changed, 10 deletions(-) + +--- a/include/media/v4l2-subdev.h ++++ b/include/media/v4l2-subdev.h +@@ -402,12 +402,6 @@ struct v4l2_mbus_frame_desc { + * + * @query_dv_timings: callback for VIDIOC_QUERY_DV_TIMINGS() ioctl handler code. + * +- * @g_mbus_config: get supported mediabus configurations +- * +- * @s_mbus_config: set a certain mediabus configuration. This operation is added +- * for compatibility with soc-camera drivers and should not be used by new +- * software. +- * + * @s_rx_buffer: set a host allocated memory buffer for the subdev. The subdev + * can adjust @size to a lower value and must not write more data to the + * buffer starting at @data than the original value of @size. +@@ -435,10 +429,6 @@ struct v4l2_subdev_video_ops { + struct v4l2_dv_timings *timings); + int (*query_dv_timings)(struct v4l2_subdev *sd, + struct v4l2_dv_timings *timings); +- int (*g_mbus_config)(struct v4l2_subdev *sd, +- struct v4l2_mbus_config *cfg); +- int (*s_mbus_config)(struct v4l2_subdev *sd, +- const struct v4l2_mbus_config *cfg); + int (*s_rx_buffer)(struct v4l2_subdev *sd, void *buf, + unsigned int *size); + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0800-staging-media-imx-Update-TODO-entry.patch b/target/linux/bcm27xx/patches-5.4/950-0800-staging-media-imx-Update-TODO-entry.patch new file mode 100644 index 0000000000..6d4b569b7f --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0800-staging-media-imx-Update-TODO-entry.patch @@ -0,0 +1,28 @@ +From 3dff4096a98f9ebb3fbc1ed7275d2d64f299db26 Mon Sep 17 00:00:00 2001 +From: Jacopo Mondi <jacopo+renesas@jmondi.org> +Date: Tue, 16 Jun 2020 16:12:41 +0200 +Subject: [PATCH] staging: media: imx: Update TODO entry + +Upstream https://patchwork.linuxtv.org/patch/64672/ + +Update the TODO entry that mentioned a potential use case for the now +removed g_mbus_config video operation. + +Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org> +--- + drivers/staging/media/imx/TODO | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/staging/media/imx/TODO ++++ b/drivers/staging/media/imx/TODO +@@ -10,6 +10,10 @@ + driver uses the parsed DT bus config method until this issue is + resolved. + ++ 2020-06: g_mbus has been removed in favour of the get_mbus_config pad ++ operation which should be used to avoid parsing the remote endpoint ++ configuration. ++ + - This media driver supports inheriting V4L2 controls to the + video capture devices, from the subdevices in the capture device's + pipeline. The controls for each capture device are updated in the diff --git a/target/linux/bcm27xx/patches-5.4/950-0801-media-i2c-adv748x-Adjust-TXA-data-lanes-number.patch b/target/linux/bcm27xx/patches-5.4/950-0801-media-i2c-adv748x-Adjust-TXA-data-lanes-number.patch new file mode 100644 index 0000000000..b4a9753a84 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0801-media-i2c-adv748x-Adjust-TXA-data-lanes-number.patch @@ -0,0 +1,123 @@ +From a3fddd6eaaa8740aceeeefea6548d5313412a062 Mon Sep 17 00:00:00 2001 +From: Jacopo Mondi <jacopo+renesas@jmondi.org> +Date: Tue, 16 Jun 2020 16:12:42 +0200 +Subject: [PATCH] media: i2c: adv748x: Adjust TXA data lanes number +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Upstream https://patchwork.linuxtv.org/patch/64673/ + +When outputting SD-Core output through the TXA MIPI CSI-2 interface, +the number of enabled data lanes should be reduced in order to guarantee +that the two video formats produced by the SD-Core (480i and 576i) +generate a MIPI CSI-2 link clock frequency compatible with the MIPI D-PHY +specifications. + +Limit the number of enabled data lanes to 2, which is guaranteed to +support 480i and 576i formats. + +Cache the number of enabled data lanes to be able to report it through +the new get_mbus_config operation. + +Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com> +Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> +Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org> +--- + drivers/media/i2c/adv748x/adv748x-core.c | 31 ++++++++++++++++++------ + drivers/media/i2c/adv748x/adv748x.h | 1 + + 2 files changed, 25 insertions(+), 7 deletions(-) + +--- a/drivers/media/i2c/adv748x/adv748x-core.c ++++ b/drivers/media/i2c/adv748x/adv748x-core.c +@@ -241,10 +241,10 @@ static int adv748x_power_up_tx(struct ad + int ret = 0; + + /* Enable n-lane MIPI */ +- adv748x_write_check(state, page, 0x00, 0x80 | tx->num_lanes, &ret); ++ adv748x_write_check(state, page, 0x00, 0x80 | tx->active_lanes, &ret); + + /* Set Auto DPHY Timing */ +- adv748x_write_check(state, page, 0x00, 0xa0 | tx->num_lanes, &ret); ++ adv748x_write_check(state, page, 0x00, 0xa0 | tx->active_lanes, &ret); + + /* ADI Required Write */ + if (tx->src == &state->hdmi.sd) { +@@ -270,7 +270,7 @@ static int adv748x_power_up_tx(struct ad + usleep_range(2000, 2500); + + /* Power-up CSI-TX */ +- adv748x_write_check(state, page, 0x00, 0x20 | tx->num_lanes, &ret); ++ adv748x_write_check(state, page, 0x00, 0x20 | tx->active_lanes, &ret); + usleep_range(1000, 1500); + + /* ADI Required Writes */ +@@ -292,7 +292,7 @@ static int adv748x_power_down_tx(struct + adv748x_write_check(state, page, 0x1e, 0x00, &ret); + + /* Enable n-lane MIPI */ +- adv748x_write_check(state, page, 0x00, 0x80 | tx->num_lanes, &ret); ++ adv748x_write_check(state, page, 0x00, 0x80 | tx->active_lanes, &ret); + + /* i2c_mipi_pll_en - 1'b1 */ + adv748x_write_check(state, page, 0xda, 0x01, &ret); +@@ -357,14 +357,29 @@ static int adv748x_link_setup(struct med + if (state->afe.tx) { + /* AFE Requires TXA enabled, even when output to TXB */ + io10 |= ADV748X_IO_10_CSI4_EN; +- if (is_txa(tx)) ++ if (is_txa(tx)) { ++ /* ++ * Output from the SD-core (480i and 576i) from the TXA ++ * interface requires reducing the number of enabled ++ * data lanes in order to guarantee a valid link ++ * frequency. ++ */ ++ tx->active_lanes = min(tx->num_lanes, 2U); + io10 |= ADV748X_IO_10_CSI4_IN_SEL_AFE; +- else ++ } else { ++ /* TXB has a single data lane, no need to adjust. */ + io10 |= ADV748X_IO_10_CSI1_EN; ++ } + } + +- if (state->hdmi.tx) ++ if (state->hdmi.tx) { ++ /* ++ * Restore the number of active lanes, in case we have gone ++ * through an AFE->TXA streaming sessions. ++ */ ++ tx->active_lanes = tx->num_lanes; + io10 |= ADV748X_IO_10_CSI4_EN; ++ } + + return io_clrset(state, ADV748X_IO_10, io10_mask, io10); + } +@@ -596,6 +611,7 @@ static int adv748x_parse_csi2_lanes(stru + } + + state->txa.num_lanes = num_lanes; ++ state->txa.active_lanes = num_lanes; + adv_dbg(state, "TXA: using %u lanes\n", state->txa.num_lanes); + } + +@@ -607,6 +623,7 @@ static int adv748x_parse_csi2_lanes(stru + } + + state->txb.num_lanes = num_lanes; ++ state->txb.active_lanes = num_lanes; + adv_dbg(state, "TXB: using %u lanes\n", state->txb.num_lanes); + } + +--- a/drivers/media/i2c/adv748x/adv748x.h ++++ b/drivers/media/i2c/adv748x/adv748x.h +@@ -79,6 +79,7 @@ struct adv748x_csi2 { + unsigned int page; + unsigned int port; + unsigned int num_lanes; ++ unsigned int active_lanes; + + struct media_pad pads[ADV748X_CSI2_NR_PADS]; + struct v4l2_ctrl_handler ctrl_hdl; diff --git a/target/linux/bcm27xx/patches-5.4/950-0802-media-i2c-adv748x-Implement-get_mbus_config.patch b/target/linux/bcm27xx/patches-5.4/950-0802-media-i2c-adv748x-Implement-get_mbus_config.patch new file mode 100644 index 0000000000..19c4d4c29d --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0802-media-i2c-adv748x-Implement-get_mbus_config.patch @@ -0,0 +1,63 @@ +From 3269627852346852f99244b2650daaa79056b29d Mon Sep 17 00:00:00 2001 +From: Jacopo Mondi <jacopo+renesas@jmondi.org> +Date: Tue, 16 Jun 2020 16:12:43 +0200 +Subject: [PATCH] media: i2c: adv748x: Implement get_mbus_config +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Upstream https://patchwork.linuxtv.org/patch/64676/ + +Implement the newly introduced get_mbus_config operation to report the +number of currently used data lanes on the MIPI CSI-2 interface. + +Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com> +Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> +Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org> +--- + drivers/media/i2c/adv748x/adv748x-csi2.c | 31 ++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +--- a/drivers/media/i2c/adv748x/adv748x-csi2.c ++++ b/drivers/media/i2c/adv748x/adv748x-csi2.c +@@ -214,9 +214,40 @@ unlock: + return ret; + } + ++static int adv748x_csi2_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad, ++ struct v4l2_mbus_config *config) ++{ ++ struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); ++ ++ if (pad != ADV748X_CSI2_SOURCE) ++ return -EINVAL; ++ ++ config->type = V4L2_MBUS_CSI2_DPHY; ++ switch (tx->active_lanes) { ++ case 1: ++ config->flags = V4L2_MBUS_CSI2_1_LANE; ++ break; ++ ++ case 2: ++ config->flags = V4L2_MBUS_CSI2_2_LANE; ++ break; ++ ++ case 3: ++ config->flags = V4L2_MBUS_CSI2_3_LANE; ++ break; ++ ++ case 4: ++ config->flags = V4L2_MBUS_CSI2_4_LANE; ++ break; ++ } ++ ++ return 0; ++} ++ + static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = { + .get_fmt = adv748x_csi2_get_format, + .set_fmt = adv748x_csi2_set_format, ++ .get_mbus_config = adv748x_csi2_get_mbus_config, + }; + + /* ----------------------------------------------------------------------------- diff --git a/target/linux/bcm27xx/patches-5.4/950-0803-media-rcar-csi2-Negotiate-data-lanes-number.patch b/target/linux/bcm27xx/patches-5.4/950-0803-media-rcar-csi2-Negotiate-data-lanes-number.patch new file mode 100644 index 0000000000..f54b33e59c --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0803-media-rcar-csi2-Negotiate-data-lanes-number.patch @@ -0,0 +1,159 @@ +From 15221304a23fd99c84a6da4b68dc0e887150d1ee Mon Sep 17 00:00:00 2001 +From: Jacopo Mondi <jacopo+renesas@jmondi.org> +Date: Tue, 16 Jun 2020 16:12:44 +0200 +Subject: [PATCH] media: rcar-csi2: Negotiate data lanes number + +Upstream https://patchwork.linuxtv.org/patch/64675/ + +Use the newly introduced get_mbus_config() subdevice pad operation to +retrieve the remote subdevice MIPI CSI-2 bus configuration and configure +the number of active data lanes accordingly. + +In order to be able to call the remote subdevice operation cache the +index of the remote pad connected to the single CSI-2 input port. + +Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org> +--- + drivers/media/platform/rcar-vin/rcar-csi2.c | 74 +++++++++++++++++++-- + 1 file changed, 67 insertions(+), 7 deletions(-) + +--- a/drivers/media/platform/rcar-vin/rcar-csi2.c ++++ b/drivers/media/platform/rcar-vin/rcar-csi2.c +@@ -362,6 +362,7 @@ struct rcar_csi2 { + + struct v4l2_async_notifier notifier; + struct v4l2_subdev *remote; ++ unsigned int remote_pad; + + struct v4l2_mbus_framefmt mf; + +@@ -407,13 +408,14 @@ static void rcsi2_exit_standby(struct rc + reset_control_deassert(priv->rstc); + } + +-static int rcsi2_wait_phy_start(struct rcar_csi2 *priv) ++static int rcsi2_wait_phy_start(struct rcar_csi2 *priv, ++ unsigned int active_lanes) + { + unsigned int timeout; + + /* Wait for the clock and data lanes to enter LP-11 state. */ + for (timeout = 0; timeout <= 20; timeout++) { +- const u32 lane_mask = (1 << priv->lanes) - 1; ++ const u32 lane_mask = (1 << active_lanes) - 1; + + if ((rcsi2_read(priv, PHCLM_REG) & PHCLM_STOPSTATECKL) && + (rcsi2_read(priv, PHDLM_REG) & lane_mask) == lane_mask) +@@ -445,7 +447,8 @@ static int rcsi2_set_phypll(struct rcar_ + return 0; + } + +-static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp) ++static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp, ++ unsigned int active_lanes) + { + struct v4l2_subdev *source; + struct v4l2_ctrl *ctrl; +@@ -470,15 +473,63 @@ static int rcsi2_calc_mbps(struct rcar_c + * bps = link_freq * 2 + */ + mbps = v4l2_ctrl_g_ctrl_int64(ctrl) * bpp; +- do_div(mbps, priv->lanes * 1000000); ++ do_div(mbps, active_lanes * 1000000); + + return mbps; + } + ++static int rcsi2_config_active_lanes(struct rcar_csi2 *priv, ++ unsigned int *active_lanes) ++{ ++ struct v4l2_mbus_config mbus_config = { 0 }; ++ unsigned int num_lanes = (-1U); ++ int ret; ++ ++ *active_lanes = priv->lanes; ++ ret = v4l2_subdev_call(priv->remote, pad, get_mbus_config, ++ priv->remote_pad, &mbus_config); ++ if (ret == -ENOIOCTLCMD) { ++ dev_dbg(priv->dev, "No remote mbus configuration available\n"); ++ return 0; ++ } ++ ++ if (ret) { ++ dev_err(priv->dev, "Failed to get remote mbus configuration\n"); ++ return ret; ++ } ++ ++ if (mbus_config.type != V4L2_MBUS_CSI2_DPHY) { ++ dev_err(priv->dev, "Unsupported media bus type %u\n", ++ mbus_config.type); ++ return -EINVAL; ++ } ++ ++ if (mbus_config.flags & V4L2_MBUS_CSI2_1_LANE) ++ num_lanes = 1; ++ else if (mbus_config.flags & V4L2_MBUS_CSI2_2_LANE) ++ num_lanes = 2; ++ else if (mbus_config.flags & V4L2_MBUS_CSI2_3_LANE) ++ num_lanes = 3; ++ else if (mbus_config.flags & V4L2_MBUS_CSI2_4_LANE) ++ num_lanes = 4; ++ ++ if (num_lanes > priv->lanes) { ++ dev_err(priv->dev, ++ "Unsupported mbus config: too many data lanes %u\n", ++ num_lanes); ++ return -EINVAL; ++ } ++ ++ *active_lanes = num_lanes; ++ ++ return 0; ++} ++ + static int rcsi2_start_receiver(struct rcar_csi2 *priv) + { + const struct rcar_csi2_format *format; + u32 phycnt, vcdt = 0, vcdt2 = 0, fld = 0; ++ unsigned int active_lanes; + unsigned int i; + int mbps, ret; + +@@ -520,10 +571,18 @@ static int rcsi2_start_receiver(struct r + fld |= FLD_FLD_NUM(1); + } + ++ /* ++ * Get the number of active data lanes inspecting the remote mbus ++ * configuration. ++ */ ++ ret = rcsi2_config_active_lanes(priv, &active_lanes); ++ if (ret) ++ return ret; ++ + phycnt = PHYCNT_ENABLECLK; +- phycnt |= (1 << priv->lanes) - 1; ++ phycnt |= (1 << active_lanes) - 1; + +- mbps = rcsi2_calc_mbps(priv, format->bpp); ++ mbps = rcsi2_calc_mbps(priv, format->bpp, active_lanes); + if (mbps < 0) + return mbps; + +@@ -570,7 +629,7 @@ static int rcsi2_start_receiver(struct r + rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ); + rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ | PHYCNT_RSTZ); + +- ret = rcsi2_wait_phy_start(priv); ++ ret = rcsi2_wait_phy_start(priv, active_lanes); + if (ret) + return ret; + +@@ -747,6 +806,7 @@ static int rcsi2_notify_bound(struct v4l + } + + priv->remote = subdev; ++ priv->remote_pad = pad; + + dev_dbg(priv->dev, "Bound %s pad: %d\n", subdev->name, pad); + diff --git a/target/linux/bcm27xx/patches-5.4/950-0804-drivers-media-Remove-the-downstream-version-of-bcm28.patch b/target/linux/bcm27xx/patches-5.4/950-0804-drivers-media-Remove-the-downstream-version-of-bcm28.patch new file mode 100644 index 0000000000..f4a89a99bd --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0804-drivers-media-Remove-the-downstream-version-of-bcm28.patch @@ -0,0 +1,3175 @@ +From c6a423459a233669b280e1a4e4836881d77c9ff0 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 23 Jun 2020 10:05:57 +0100 +Subject: [PATCH] drivers: media: Remove the downstream version of + bcm2835-unicam + +About to be replaced by the upstream version. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/platform/bcm2835/Kconfig | 14 - + drivers/media/platform/bcm2835/Makefile | 3 - + .../media/platform/bcm2835/bcm2835-unicam.c | 2873 ----------------- + .../media/platform/bcm2835/vc4-regs-unicam.h | 253 -- + 4 files changed, 3143 deletions(-) + delete mode 100644 drivers/media/platform/bcm2835/Kconfig + delete mode 100644 drivers/media/platform/bcm2835/Makefile + delete mode 100644 drivers/media/platform/bcm2835/bcm2835-unicam.c + delete mode 100644 drivers/media/platform/bcm2835/vc4-regs-unicam.h + +--- a/drivers/media/platform/bcm2835/Kconfig ++++ /dev/null +@@ -1,14 +0,0 @@ +-# Broadcom VideoCore4 V4L2 camera support +- +-config VIDEO_BCM2835_UNICAM +- tristate "Broadcom BCM2835 Unicam video capture driver" +- depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER +- depends on ARCH_BCM2835 || COMPILE_TEST +- select VIDEOBUF2_DMA_CONTIG +- select V4L2_FWNODE +- help +- Say Y here to enable V4L2 subdevice for CSI2 receiver. +- This is a V4L2 subdevice that interfaces directly to the VC4 peripheral. +- +- To compile this driver as a module, choose M here. The module +- will be called bcm2835-unicam. +--- a/drivers/media/platform/bcm2835/Makefile ++++ /dev/null +@@ -1,3 +0,0 @@ +-# Makefile for BCM2835 Unicam driver +- +-obj-$(CONFIG_VIDEO_BCM2835_UNICAM) += bcm2835-unicam.o +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ /dev/null +@@ -1,2873 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-only +-/* +- * BCM2835 Unicam Capture Driver +- * +- * Copyright (C) 2017-2020 - Raspberry Pi (Trading) Ltd. +- * +- * Dave Stevenson <dave.stevenson@raspberrypi.com> +- * +- * Based on TI am437x driver by +- * Benoit Parrot <bparrot@ti.com> +- * Lad, Prabhakar <prabhakar.csengg@gmail.com> +- * +- * and TI CAL camera interface driver by +- * Benoit Parrot <bparrot@ti.com> +- * +- * +- * There are two camera drivers in the kernel for BCM283x - this one +- * and bcm2835-camera (currently in staging). +- * +- * This driver directly controls the Unicam peripheral - there is no +- * involvement with the VideoCore firmware. Unicam receives CSI-2 or +- * CCP2 data and writes it into SDRAM. +- * The only potential processing options are to repack Bayer data into an +- * alternate format, and applying windowing. +- * The repacking does not shift the data, so can repack V4L2_PIX_FMT_Sxxxx10P +- * to V4L2_PIX_FMT_Sxxxx10, or V4L2_PIX_FMT_Sxxxx12P to V4L2_PIX_FMT_Sxxxx12, +- * but not generically up to V4L2_PIX_FMT_Sxxxx16. The driver will add both +- * formats where the relevant formats are defined, and will automatically +- * configure the repacking as required. +- * Support for windowing may be added later. +- * +- * It should be possible to connect this driver to any sensor with a +- * suitable output interface and V4L2 subdevice driver. +- * +- * bcm2835-camera uses the VideoCore firmware to control the sensor, +- * Unicam, ISP, and all tuner control loops. Fully processed frames are +- * delivered to the driver by the firmware. It only has sensor drivers +- * for Omnivision OV5647, and Sony IMX219 sensors. +- * +- * The two drivers are mutually exclusive for the same Unicam instance. +- * The VideoCore firmware checks the device tree configuration during boot. +- * If it finds device tree nodes called csi0 or csi1 it will block the +- * firmware from accessing the peripheral, and bcm2835-camera will +- * not be able to stream data. +- */ +- +-#include <linux/clk.h> +-#include <linux/delay.h> +-#include <linux/device.h> +-#include <linux/dma-mapping.h> +-#include <linux/err.h> +-#include <linux/init.h> +-#include <linux/interrupt.h> +-#include <linux/io.h> +-#include <linux/module.h> +-#include <linux/of_device.h> +-#include <linux/of_graph.h> +-#include <linux/pinctrl/consumer.h> +-#include <linux/platform_device.h> +-#include <linux/pm_runtime.h> +-#include <linux/slab.h> +-#include <linux/uaccess.h> +-#include <linux/videodev2.h> +- +-#include <media/v4l2-common.h> +-#include <media/v4l2-ctrls.h> +-#include <media/v4l2-dev.h> +-#include <media/v4l2-device.h> +-#include <media/v4l2-dv-timings.h> +-#include <media/v4l2-event.h> +-#include <media/v4l2-ioctl.h> +-#include <media/v4l2-fwnode.h> +-#include <media/videobuf2-dma-contig.h> +- +-#include "vc4-regs-unicam.h" +- +-#define UNICAM_MODULE_NAME "unicam" +-#define UNICAM_VERSION "0.1.0" +- +-static int debug; +-module_param(debug, int, 0644); +-MODULE_PARM_DESC(debug, "Debug level 0-3"); +- +-#define unicam_dbg(level, dev, fmt, arg...) \ +- v4l2_dbg(level, debug, &(dev)->v4l2_dev, fmt, ##arg) +-#define unicam_info(dev, fmt, arg...) \ +- v4l2_info(&(dev)->v4l2_dev, fmt, ##arg) +-#define unicam_err(dev, fmt, arg...) \ +- v4l2_err(&(dev)->v4l2_dev, fmt, ##arg) +- +-/* To protect against a dodgy sensor driver never returning an error from +- * enum_mbus_code, set a maximum index value to be used. +- */ +-#define MAX_ENUM_MBUS_CODE 128 +- +-/* +- * Stride is a 16 bit register, but also has to be a multiple of 32. +- */ +-#define BPL_ALIGNMENT 32 +-#define MAX_BYTESPERLINE ((1 << 16) - BPL_ALIGNMENT) +-/* +- * Max width is therefore determined by the max stride divided by +- * the number of bits per pixel. Take 32bpp as a +- * worst case. +- * No imposed limit on the height, so adopt a square image for want +- * of anything better. +- */ +-#define MAX_WIDTH (MAX_BYTESPERLINE / 4) +-#define MAX_HEIGHT MAX_WIDTH +-/* Define a nominal minimum image size */ +-#define MIN_WIDTH 16 +-#define MIN_HEIGHT 16 +-/* Default size of the embedded buffer */ +-#define UNICAM_EMBEDDED_SIZE 8192 +- +-/* +- * Size of the dummy buffer. Can be any size really, but the DMA +- * allocation works in units of page sizes. +- */ +-#define DUMMY_BUF_SIZE (PAGE_SIZE) +- +-enum pad_types { +- IMAGE_PAD, +- METADATA_PAD, +- MAX_NODES +-}; +- +-/* +- * struct unicam_fmt - Unicam media bus format information +- * @pixelformat: V4L2 pixel format FCC identifier. 0 if n/a. +- * @repacked_fourcc: V4L2 pixel format FCC identifier if the data is expanded +- * out to 16bpp. 0 if n/a. +- * @code: V4L2 media bus format code. +- * @depth: Bits per pixel as delivered from the source. +- * @csi_dt: CSI data type. +- * @check_variants: Flag to denote that there are multiple mediabus formats +- * still in the list that could match this V4L2 format. +- */ +-struct unicam_fmt { +- u32 fourcc; +- u32 repacked_fourcc; +- u32 code; +- u8 depth; +- u8 csi_dt; +- u8 check_variants; +-}; +- +-static const struct unicam_fmt formats[] = { +- /* YUV Formats */ +- { +- .fourcc = V4L2_PIX_FMT_YUYV, +- .code = MEDIA_BUS_FMT_YUYV8_2X8, +- .depth = 16, +- .csi_dt = 0x1e, +- .check_variants = 1, +- }, { +- .fourcc = V4L2_PIX_FMT_UYVY, +- .code = MEDIA_BUS_FMT_UYVY8_2X8, +- .depth = 16, +- .csi_dt = 0x1e, +- .check_variants = 1, +- }, { +- .fourcc = V4L2_PIX_FMT_YVYU, +- .code = MEDIA_BUS_FMT_YVYU8_2X8, +- .depth = 16, +- .csi_dt = 0x1e, +- .check_variants = 1, +- }, { +- .fourcc = V4L2_PIX_FMT_VYUY, +- .code = MEDIA_BUS_FMT_VYUY8_2X8, +- .depth = 16, +- .csi_dt = 0x1e, +- .check_variants = 1, +- }, { +- .fourcc = V4L2_PIX_FMT_YUYV, +- .code = MEDIA_BUS_FMT_YUYV8_1X16, +- .depth = 16, +- .csi_dt = 0x1e, +- }, { +- .fourcc = V4L2_PIX_FMT_UYVY, +- .code = MEDIA_BUS_FMT_UYVY8_1X16, +- .depth = 16, +- .csi_dt = 0x1e, +- }, { +- .fourcc = V4L2_PIX_FMT_YVYU, +- .code = MEDIA_BUS_FMT_YVYU8_1X16, +- .depth = 16, +- .csi_dt = 0x1e, +- }, { +- .fourcc = V4L2_PIX_FMT_VYUY, +- .code = MEDIA_BUS_FMT_VYUY8_1X16, +- .depth = 16, +- .csi_dt = 0x1e, +- }, { +- /* RGB Formats */ +- .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ +- .code = MEDIA_BUS_FMT_RGB565_2X8_LE, +- .depth = 16, +- .csi_dt = 0x22, +- }, { +- .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */ +- .code = MEDIA_BUS_FMT_RGB565_2X8_BE, +- .depth = 16, +- .csi_dt = 0x22 +- }, { +- .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */ +- .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, +- .depth = 16, +- .csi_dt = 0x21, +- }, { +- .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */ +- .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, +- .depth = 16, +- .csi_dt = 0x21, +- }, { +- .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */ +- .code = MEDIA_BUS_FMT_RGB888_1X24, +- .depth = 24, +- .csi_dt = 0x24, +- }, { +- .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */ +- .code = MEDIA_BUS_FMT_BGR888_1X24, +- .depth = 24, +- .csi_dt = 0x24, +- }, { +- .fourcc = V4L2_PIX_FMT_RGB32, /* argb */ +- .code = MEDIA_BUS_FMT_ARGB8888_1X32, +- .depth = 32, +- .csi_dt = 0x0, +- }, { +- /* Bayer Formats */ +- .fourcc = V4L2_PIX_FMT_SBGGR8, +- .code = MEDIA_BUS_FMT_SBGGR8_1X8, +- .depth = 8, +- .csi_dt = 0x2a, +- }, { +- .fourcc = V4L2_PIX_FMT_SGBRG8, +- .code = MEDIA_BUS_FMT_SGBRG8_1X8, +- .depth = 8, +- .csi_dt = 0x2a, +- }, { +- .fourcc = V4L2_PIX_FMT_SGRBG8, +- .code = MEDIA_BUS_FMT_SGRBG8_1X8, +- .depth = 8, +- .csi_dt = 0x2a, +- }, { +- .fourcc = V4L2_PIX_FMT_SRGGB8, +- .code = MEDIA_BUS_FMT_SRGGB8_1X8, +- .depth = 8, +- .csi_dt = 0x2a, +- }, { +- .fourcc = V4L2_PIX_FMT_SBGGR10P, +- .repacked_fourcc = V4L2_PIX_FMT_SBGGR10, +- .code = MEDIA_BUS_FMT_SBGGR10_1X10, +- .depth = 10, +- .csi_dt = 0x2b, +- }, { +- .fourcc = V4L2_PIX_FMT_SGBRG10P, +- .repacked_fourcc = V4L2_PIX_FMT_SGBRG10, +- .code = MEDIA_BUS_FMT_SGBRG10_1X10, +- .depth = 10, +- .csi_dt = 0x2b, +- }, { +- .fourcc = V4L2_PIX_FMT_SGRBG10P, +- .repacked_fourcc = V4L2_PIX_FMT_SGRBG10, +- .code = MEDIA_BUS_FMT_SGRBG10_1X10, +- .depth = 10, +- .csi_dt = 0x2b, +- }, { +- .fourcc = V4L2_PIX_FMT_SRGGB10P, +- .repacked_fourcc = V4L2_PIX_FMT_SRGGB10, +- .code = MEDIA_BUS_FMT_SRGGB10_1X10, +- .depth = 10, +- .csi_dt = 0x2b, +- }, { +- .fourcc = V4L2_PIX_FMT_SBGGR12P, +- .repacked_fourcc = V4L2_PIX_FMT_SBGGR12, +- .code = MEDIA_BUS_FMT_SBGGR12_1X12, +- .depth = 12, +- .csi_dt = 0x2c, +- }, { +- .fourcc = V4L2_PIX_FMT_SGBRG12P, +- .repacked_fourcc = V4L2_PIX_FMT_SGBRG12, +- .code = MEDIA_BUS_FMT_SGBRG12_1X12, +- .depth = 12, +- .csi_dt = 0x2c, +- }, { +- .fourcc = V4L2_PIX_FMT_SGRBG12P, +- .repacked_fourcc = V4L2_PIX_FMT_SGRBG12, +- .code = MEDIA_BUS_FMT_SGRBG12_1X12, +- .depth = 12, +- .csi_dt = 0x2c, +- }, { +- .fourcc = V4L2_PIX_FMT_SRGGB12P, +- .repacked_fourcc = V4L2_PIX_FMT_SRGGB12, +- .code = MEDIA_BUS_FMT_SRGGB12_1X12, +- .depth = 12, +- .csi_dt = 0x2c, +- }, { +- .fourcc = V4L2_PIX_FMT_SBGGR14P, +- .code = MEDIA_BUS_FMT_SBGGR14_1X14, +- .depth = 14, +- .csi_dt = 0x2d, +- }, { +- .fourcc = V4L2_PIX_FMT_SGBRG14P, +- .code = MEDIA_BUS_FMT_SGBRG14_1X14, +- .depth = 14, +- .csi_dt = 0x2d, +- }, { +- .fourcc = V4L2_PIX_FMT_SGRBG14P, +- .code = MEDIA_BUS_FMT_SGRBG14_1X14, +- .depth = 14, +- .csi_dt = 0x2d, +- }, { +- .fourcc = V4L2_PIX_FMT_SRGGB14P, +- .code = MEDIA_BUS_FMT_SRGGB14_1X14, +- .depth = 14, +- .csi_dt = 0x2d, +- }, { +- /* +- * 16 bit Bayer formats could be supported, but there is no CSI2 +- * data_type defined for raw 16, and no sensors that produce it at +- * present. +- */ +- +- /* Greyscale formats */ +- .fourcc = V4L2_PIX_FMT_GREY, +- .code = MEDIA_BUS_FMT_Y8_1X8, +- .depth = 8, +- .csi_dt = 0x2a, +- }, { +- .fourcc = V4L2_PIX_FMT_Y10P, +- .repacked_fourcc = V4L2_PIX_FMT_Y10, +- .code = MEDIA_BUS_FMT_Y10_1X10, +- .depth = 10, +- .csi_dt = 0x2b, +- }, { +- /* NB There is no packed V4L2 fourcc for this format. */ +- .repacked_fourcc = V4L2_PIX_FMT_Y12, +- .code = MEDIA_BUS_FMT_Y12_1X12, +- .depth = 12, +- .csi_dt = 0x2c, +- }, +- /* Embedded data format */ +- { +- .fourcc = V4L2_META_FMT_SENSOR_DATA, +- .code = MEDIA_BUS_FMT_SENSOR_DATA, +- .depth = 8, +- } +-}; +- +-struct unicam_dmaqueue { +- struct list_head active; +-}; +- +-struct unicam_buffer { +- struct vb2_v4l2_buffer vb; +- struct list_head list; +-}; +- +-struct unicam_cfg { +- /* peripheral base address */ +- void __iomem *base; +- /* clock gating base address */ +- void __iomem *clk_gate_base; +-}; +- +-#define MAX_POSSIBLE_PIX_FMTS (ARRAY_SIZE(formats)) +- +-struct unicam_node { +- int registered; +- int open; +- int streaming; +- unsigned int pad_id; +- /* Pointer pointing to current v4l2_buffer */ +- struct unicam_buffer *cur_frm; +- /* Pointer pointing to next v4l2_buffer */ +- struct unicam_buffer *next_frm; +- /* video capture */ +- const struct unicam_fmt *fmt; +- /* Used to store current pixel format */ +- struct v4l2_format v_fmt; +- /* Used to store current mbus frame format */ +- struct v4l2_mbus_framefmt m_fmt; +- /* Buffer queue used in video-buf */ +- struct vb2_queue buffer_queue; +- /* Queue of filled frames */ +- struct unicam_dmaqueue dma_queue; +- /* IRQ lock for DMA queue */ +- spinlock_t dma_queue_lock; +- /* lock used to access this structure */ +- struct mutex lock; +- /* Identifies video device for this channel */ +- struct video_device video_dev; +- /* Pointer to the parent handle */ +- struct unicam_device *dev; +- struct media_pad pad; +- struct v4l2_ctrl_handler ctrl_handler; +- unsigned int embedded_lines; +- /* +- * Dummy buffer intended to be used by unicam +- * if we have no other queued buffers to swap to. +- */ +- void *dummy_buf_cpu_addr; +- dma_addr_t dummy_buf_dma_addr; +-}; +- +-struct unicam_device { +- /* V4l2 specific parameters */ +- +- struct v4l2_fwnode_endpoint endpoint; +- +- struct v4l2_async_subdev asd; +- +- /* unicam cfg */ +- struct unicam_cfg cfg; +- /* clock handle */ +- struct clk *clock; +- /* V4l2 device */ +- struct v4l2_device v4l2_dev; +- struct media_device mdev; +- +- /* parent device */ +- struct platform_device *pdev; +- /* subdevice async Notifier */ +- struct v4l2_async_notifier notifier; +- unsigned int sequence; +- +- /* ptr to sub device */ +- struct v4l2_subdev *sensor; +- /* Pad config for the sensor */ +- struct v4l2_subdev_pad_config *sensor_config; +- +- unsigned int virtual_channel; +- enum v4l2_mbus_type bus_type; +- /* +- * Stores bus.mipi_csi2.flags for CSI2 sensors, or +- * bus.mipi_csi1.strobe for CCP2. +- */ +- unsigned int bus_flags; +- unsigned int max_data_lanes; +- unsigned int active_data_lanes; +- bool sensor_embedded_data; +- +- struct unicam_node node[MAX_NODES]; +-}; +- +-/* Hardware access */ +-#define clk_write(dev, val) writel((val) | 0x5a000000, (dev)->clk_gate_base) +-#define clk_read(dev) readl((dev)->clk_gate_base) +- +-#define reg_read(dev, offset) readl((dev)->base + (offset)) +-#define reg_write(dev, offset, val) writel(val, (dev)->base + (offset)) +- +-#define reg_read_field(dev, offset, mask) get_field(reg_read((dev), (offset), \ +- mask)) +- +-static inline int get_field(u32 value, u32 mask) +-{ +- return (value & mask) >> __ffs(mask); +-} +- +-static inline void set_field(u32 *valp, u32 field, u32 mask) +-{ +- u32 val = *valp; +- +- val &= ~mask; +- val |= (field << __ffs(mask)) & mask; +- *valp = val; +-} +- +-static inline void reg_write_field(struct unicam_cfg *dev, u32 offset, +- u32 field, u32 mask) +-{ +- u32 val = reg_read((dev), (offset)); +- +- set_field(&val, field, mask); +- reg_write((dev), (offset), val); +-} +- +-/* Power management functions */ +-static inline int unicam_runtime_get(struct unicam_device *dev) +-{ +- return pm_runtime_get_sync(&dev->pdev->dev); +-} +- +-static inline void unicam_runtime_put(struct unicam_device *dev) +-{ +- pm_runtime_put_sync(&dev->pdev->dev); +-} +- +-/* Format setup functions */ +-static const struct unicam_fmt *find_format_by_code(u32 code) +-{ +- unsigned int i; +- +- for (i = 0; i < ARRAY_SIZE(formats); i++) { +- if (formats[i].code == code) +- return &formats[i]; +- } +- +- return NULL; +-} +- +-static int check_mbus_format(struct unicam_device *dev, +- const struct unicam_fmt *format) +-{ +- struct v4l2_subdev_mbus_code_enum mbus_code; +- int ret = 0; +- int i; +- +- for (i = 0; !ret && i < MAX_ENUM_MBUS_CODE; i++) { +- memset(&mbus_code, 0, sizeof(mbus_code)); +- mbus_code.index = i; +- mbus_code.pad = IMAGE_PAD; +- mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE; +- +- ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, +- NULL, &mbus_code); +- +- if (!ret && mbus_code.code == format->code) +- return 1; +- } +- +- return 0; +-} +- +-static const struct unicam_fmt *find_format_by_pix(struct unicam_device *dev, +- u32 pixelformat) +-{ +- unsigned int i; +- +- for (i = 0; i < ARRAY_SIZE(formats); i++) { +- if (formats[i].fourcc == pixelformat || +- formats[i].repacked_fourcc == pixelformat) { +- if (formats[i].check_variants && +- !check_mbus_format(dev, &formats[i])) +- continue; +- return &formats[i]; +- } +- } +- +- return NULL; +-} +- +-static inline unsigned int bytes_per_line(u32 width, +- const struct unicam_fmt *fmt, +- u32 v4l2_fourcc) +-{ +- if (v4l2_fourcc == fmt->repacked_fourcc) +- /* Repacking always goes to 16bpp */ +- return ALIGN(width << 1, BPL_ALIGNMENT); +- else +- return ALIGN((width * fmt->depth) >> 3, BPL_ALIGNMENT); +-} +- +-static int __subdev_get_format(struct unicam_device *dev, +- struct v4l2_mbus_framefmt *fmt, int pad_id) +-{ +- struct v4l2_subdev_format sd_fmt = { +- .which = V4L2_SUBDEV_FORMAT_ACTIVE, +- .pad = pad_id +- }; +- int ret; +- +- ret = v4l2_subdev_call(dev->sensor, pad, get_fmt, dev->sensor_config, +- &sd_fmt); +- if (ret < 0) +- return ret; +- +- *fmt = sd_fmt.format; +- +- unicam_dbg(1, dev, "%s %dx%d code:%04x\n", __func__, +- fmt->width, fmt->height, fmt->code); +- +- return 0; +-} +- +-static int __subdev_set_format(struct unicam_device *dev, +- struct v4l2_mbus_framefmt *fmt, int pad_id) +-{ +- struct v4l2_subdev_format sd_fmt = { +- .which = V4L2_SUBDEV_FORMAT_ACTIVE, +- .pad = pad_id +- }; +- int ret; +- +- sd_fmt.format = *fmt; +- +- ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, dev->sensor_config, +- &sd_fmt); +- if (ret < 0) +- return ret; +- +- if (pad_id == IMAGE_PAD) +- unicam_dbg(1, dev, "%s %dx%d code:%04x\n", __func__, fmt->width, +- fmt->height, fmt->code); +- else +- unicam_dbg(1, dev, "%s Embedded data code:%04x\n", __func__, +- sd_fmt.format.code); +- +- return 0; +-} +- +-static int unicam_calc_format_size_bpl(struct unicam_device *dev, +- const struct unicam_fmt *fmt, +- struct v4l2_format *f) +-{ +- unsigned int min_bytesperline; +- +- v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, MAX_WIDTH, 2, +- &f->fmt.pix.height, MIN_HEIGHT, MAX_HEIGHT, 0, +- 0); +- +- min_bytesperline = bytes_per_line(f->fmt.pix.width, fmt, +- f->fmt.pix.pixelformat); +- +- if (f->fmt.pix.bytesperline > min_bytesperline && +- f->fmt.pix.bytesperline <= MAX_BYTESPERLINE) +- f->fmt.pix.bytesperline = ALIGN(f->fmt.pix.bytesperline, +- BPL_ALIGNMENT); +- else +- f->fmt.pix.bytesperline = min_bytesperline; +- +- f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; +- +- unicam_dbg(3, dev, "%s: fourcc: %08X size: %dx%d bpl:%d img_size:%d\n", +- __func__, +- f->fmt.pix.pixelformat, +- f->fmt.pix.width, f->fmt.pix.height, +- f->fmt.pix.bytesperline, f->fmt.pix.sizeimage); +- +- return 0; +-} +- +-static int unicam_reset_format(struct unicam_node *node) +-{ +- struct unicam_device *dev = node->dev; +- struct v4l2_mbus_framefmt mbus_fmt; +- int ret; +- +- if (dev->sensor_embedded_data || node->pad_id != METADATA_PAD) { +- ret = __subdev_get_format(dev, &mbus_fmt, node->pad_id); +- if (ret) { +- unicam_err(dev, "Failed to get_format - ret %d\n", ret); +- return ret; +- } +- +- if (mbus_fmt.code != node->fmt->code) { +- unicam_err(dev, "code mismatch - fmt->code %08x, mbus_fmt.code %08x\n", +- node->fmt->code, mbus_fmt.code); +- return ret; +- } +- } +- +- if (node->pad_id == IMAGE_PAD) { +- v4l2_fill_pix_format(&node->v_fmt.fmt.pix, &mbus_fmt); +- node->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; +- unicam_calc_format_size_bpl(dev, node->fmt, &node->v_fmt); +- } else { +- node->v_fmt.type = V4L2_BUF_TYPE_META_CAPTURE; +- node->v_fmt.fmt.meta.dataformat = V4L2_META_FMT_SENSOR_DATA; +- if (dev->sensor_embedded_data) { +- node->v_fmt.fmt.meta.buffersize = +- mbus_fmt.width * mbus_fmt.height; +- node->embedded_lines = mbus_fmt.height; +- } else { +- node->v_fmt.fmt.meta.buffersize = UNICAM_EMBEDDED_SIZE; +- node->embedded_lines = 1; +- } +- } +- +- node->m_fmt = mbus_fmt; +- return 0; +-} +- +-static void unicam_wr_dma_addr(struct unicam_cfg *cfg, dma_addr_t dmaaddr, +- unsigned int buffer_size, int pad_id) +-{ +- dma_addr_t endaddr = dmaaddr + buffer_size; +- +- /* +- * dmaaddr and endaddr should be a 32-bit address with the top two bits +- * set to 0x3 to signify uncached access through the Videocore memory +- * controller. +- */ +- BUG_ON((dmaaddr >> 30) != 0x3 && (endaddr >> 30) != 0x3); +- +- if (pad_id == IMAGE_PAD) { +- reg_write(cfg, UNICAM_IBSA0, dmaaddr); +- reg_write(cfg, UNICAM_IBEA0, endaddr); +- } else { +- reg_write(cfg, UNICAM_DBSA0, dmaaddr); +- reg_write(cfg, UNICAM_DBEA0, endaddr); +- } +-} +- +-static inline unsigned int unicam_get_lines_done(struct unicam_device *dev) +-{ +- dma_addr_t start_addr, cur_addr; +- unsigned int stride = dev->node[IMAGE_PAD].v_fmt.fmt.pix.bytesperline; +- struct unicam_buffer *frm = dev->node[IMAGE_PAD].cur_frm; +- +- if (!frm) +- return 0; +- +- start_addr = vb2_dma_contig_plane_dma_addr(&frm->vb.vb2_buf, 0); +- cur_addr = reg_read(&dev->cfg, UNICAM_IBWP); +- return (unsigned int)(cur_addr - start_addr) / stride; +-} +- +-static inline void unicam_schedule_next_buffer(struct unicam_node *node) +-{ +- struct unicam_device *dev = node->dev; +- struct unicam_dmaqueue *dma_q = &node->dma_queue; +- struct unicam_buffer *buf; +- unsigned int size; +- dma_addr_t addr; +- +- buf = list_entry(dma_q->active.next, struct unicam_buffer, list); +- node->next_frm = buf; +- list_del(&buf->list); +- +- addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0); +- size = (node->pad_id == IMAGE_PAD) ? +- dev->node[IMAGE_PAD].v_fmt.fmt.pix.sizeimage : +- dev->node[METADATA_PAD].v_fmt.fmt.meta.buffersize; +- +- unicam_wr_dma_addr(&dev->cfg, addr, size, node->pad_id); +-} +- +-static inline void unicam_schedule_dummy_buffer(struct unicam_node *node) +-{ +- struct unicam_device *dev = node->dev; +- dma_addr_t addr = node->dummy_buf_dma_addr; +- +- unicam_dbg(3, dev, "Scheduling dummy buffer for node %d\n", +- node->pad_id); +- +- unicam_wr_dma_addr(&dev->cfg, addr, DUMMY_BUF_SIZE, node->pad_id); +- node->next_frm = NULL; +-} +- +-static inline void unicam_process_buffer_complete(struct unicam_node *node, +- unsigned int sequence) +-{ +- node->cur_frm->vb.field = node->m_fmt.field; +- node->cur_frm->vb.sequence = sequence; +- +- vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE); +-} +- +-static int unicam_num_nodes_streaming(struct unicam_device *dev) +-{ +- return dev->node[IMAGE_PAD].streaming + +- dev->node[METADATA_PAD].streaming; +-} +- +-static int unicam_all_nodes_streaming(struct unicam_device *dev) +-{ +- int ret; +- +- ret = dev->node[IMAGE_PAD].open && dev->node[IMAGE_PAD].streaming; +- ret &= !dev->node[METADATA_PAD].open || +- dev->node[METADATA_PAD].streaming; +- return ret; +-} +- +-static void unicam_queue_event_sof(struct unicam_device *unicam) +-{ +- struct v4l2_event event = { +- .type = V4L2_EVENT_FRAME_SYNC, +- .u.frame_sync.frame_sequence = unicam->sequence, +- }; +- +- v4l2_event_queue(&unicam->node[IMAGE_PAD].video_dev, &event); +-} +- +-/* +- * unicam_isr : ISR handler for unicam capture +- * @irq: irq number +- * @dev_id: dev_id ptr +- * +- * It changes status of the captured buffer, takes next buffer from the queue +- * and sets its address in unicam registers +- */ +-static irqreturn_t unicam_isr(int irq, void *dev) +-{ +- struct unicam_device *unicam = (struct unicam_device *)dev; +- struct unicam_cfg *cfg = &unicam->cfg; +- unsigned int lines_done = unicam_get_lines_done(dev); +- unsigned int sequence = unicam->sequence; +- int num_nodes_streaming = unicam_num_nodes_streaming(dev); +- int ista, sta; +- u64 ts; +- int i; +- +- sta = reg_read(cfg, UNICAM_STA); +- /* Write value back to clear the interrupts */ +- reg_write(cfg, UNICAM_STA, sta); +- +- ista = reg_read(cfg, UNICAM_ISTA); +- /* Write value back to clear the interrupts */ +- reg_write(cfg, UNICAM_ISTA, ista); +- +- unicam_dbg(3, unicam, "ISR: ISTA: 0x%X, STA: 0x%X, sequence %d, lines done %d", +- ista, sta, sequence, lines_done); +- +- if (!(sta && (UNICAM_IS | UNICAM_PI0))) +- return IRQ_HANDLED; +- +- /* +- * We must run the frame end handler first. If we have a valid next_frm +- * and we get a simultaneout FE + FS interrupt, running the FS handler +- * first would null out the next_frm ptr and we would have lost the +- * buffer forever. +- */ +- if (ista & UNICAM_FEI || sta & UNICAM_PI0) { +- /* +- * Ensure we have swapped buffers already as we can't +- * stop the peripheral. If no buffer is available, use a +- * dummy buffer to dump out frames until we get a new buffer +- * to use. +- */ +- for (i = 0; i < num_nodes_streaming; i++) { +- if (unicam->node[i].cur_frm) +- unicam_process_buffer_complete(&unicam->node[i], +- sequence); +- unicam->node[i].cur_frm = unicam->node[i].next_frm; +- } +- unicam->sequence++; +- } +- +- if (ista & UNICAM_FSI) { +- /* +- * Timestamp is to be when the first data byte was captured, +- * aka frame start. +- */ +- ts = ktime_get_ns(); +- for (i = 0; i < num_nodes_streaming; i++) { +- if (unicam->node[i].cur_frm) +- unicam->node[i].cur_frm->vb.vb2_buf.timestamp = +- ts; +- /* +- * Set the next frame output to go to a dummy frame +- * if we have not managed to obtain another frame +- * from the queue. +- */ +- unicam_schedule_dummy_buffer(&unicam->node[i]); +- } +- +- unicam_queue_event_sof(unicam); +- } +- /* +- * Cannot swap buffer at frame end, there may be a race condition +- * where the HW does not actually swap it if the new frame has +- * already started. +- */ +- if (ista & (UNICAM_FSI | UNICAM_LCI) && !(ista & UNICAM_FEI)) { +- for (i = 0; i < num_nodes_streaming; i++) { +- spin_lock(&unicam->node[i].dma_queue_lock); +- if (!list_empty(&unicam->node[i].dma_queue.active) && +- !unicam->node[i].next_frm) +- unicam_schedule_next_buffer(&unicam->node[i]); +- spin_unlock(&unicam->node[i].dma_queue_lock); +- } +- } +- +- if (reg_read(&unicam->cfg, UNICAM_ICTL) & UNICAM_FCM) { +- /* Switch out of trigger mode if selected */ +- reg_write_field(&unicam->cfg, UNICAM_ICTL, 1, UNICAM_TFC); +- reg_write_field(&unicam->cfg, UNICAM_ICTL, 0, UNICAM_FCM); +- } +- return IRQ_HANDLED; +-} +- +-static int unicam_querycap(struct file *file, void *priv, +- struct v4l2_capability *cap) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- +- strlcpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver)); +- strlcpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card)); +- +- snprintf(cap->bus_info, sizeof(cap->bus_info), +- "platform:%s", dev->v4l2_dev.name); +- +- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | +- V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS | +- V4L2_CAP_META_CAPTURE; +- +- if (node->pad_id == IMAGE_PAD) +- cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; +- else +- cap->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING; +- +- return 0; +-} +- +-static int unicam_enum_fmt_vid_cap(struct file *file, void *priv, +- struct v4l2_fmtdesc *f) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- struct v4l2_subdev_mbus_code_enum mbus_code; +- const struct unicam_fmt *fmt = NULL; +- int index = 0; +- int ret = 0; +- int i; +- +- if (node->pad_id == METADATA_PAD) +- return -EINVAL; +- +- for (i = 0; !ret && i < MAX_ENUM_MBUS_CODE; i++) { +- memset(&mbus_code, 0, sizeof(mbus_code)); +- mbus_code.index = i; +- mbus_code.pad = IMAGE_PAD; +- mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE; +- +- ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, +- NULL, &mbus_code); +- if (ret < 0) { +- unicam_dbg(2, dev, +- "subdev->enum_mbus_code idx %d returned %d - index invalid\n", +- i, ret); +- return -EINVAL; +- } +- +- fmt = find_format_by_code(mbus_code.code); +- if (fmt) { +- if (fmt->fourcc) { +- if (index == f->index) { +- f->pixelformat = fmt->fourcc; +- break; +- } +- index++; +- } +- if (fmt->repacked_fourcc) { +- if (index == f->index) { +- f->pixelformat = fmt->repacked_fourcc; +- break; +- } +- index++; +- } +- } +- } +- +- return 0; +-} +- +-static int unicam_g_fmt_vid_cap(struct file *file, void *priv, +- struct v4l2_format *f) +-{ +- struct v4l2_mbus_framefmt mbus_fmt = {0}; +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- const struct unicam_fmt *fmt = NULL; +- int ret; +- +- if (node->pad_id != IMAGE_PAD) +- return -EINVAL; +- +- /* +- * If a flip has occurred in the sensor, the fmt code might have +- * changed. So we will need to re-fetch the format from the subdevice. +- */ +- ret = __subdev_get_format(dev, &mbus_fmt, node->pad_id); +- if (ret) +- return -EINVAL; +- +- /* Find the V4L2 format from mbus code. We must match a known format. */ +- fmt = find_format_by_code(mbus_fmt.code); +- if (!fmt) +- return -EINVAL; +- +- if (node->fmt != fmt) { +- /* +- * The sensor format has changed so the pixelformat needs to +- * be updated. Try and retain the packed/unpacked choice if +- * at all possible. +- */ +- if (node->fmt->repacked_fourcc == +- node->v_fmt.fmt.pix.pixelformat) +- /* Using the repacked format */ +- node->v_fmt.fmt.pix.pixelformat = fmt->repacked_fourcc; +- else +- /* Using the native format */ +- node->v_fmt.fmt.pix.pixelformat = fmt->fourcc; +- +- node->fmt = fmt; +- } +- +- *f = node->v_fmt; +- +- return 0; +-} +- +-static +-const struct unicam_fmt *get_first_supported_format(struct unicam_device *dev) +-{ +- struct v4l2_subdev_mbus_code_enum mbus_code; +- const struct unicam_fmt *fmt = NULL; +- int ret = 0; +- int j; +- +- for (j = 0; ret != -EINVAL && ret != -ENOIOCTLCMD; ++j) { +- memset(&mbus_code, 0, sizeof(mbus_code)); +- mbus_code.index = j; +- mbus_code.pad = IMAGE_PAD; +- mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE; +- +- ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, NULL, +- &mbus_code); +- if (ret < 0) { +- unicam_dbg(2, dev, +- "subdev->enum_mbus_code idx %d returned %d - continue\n", +- j, ret); +- continue; +- } +- +- unicam_dbg(2, dev, "subdev %s: code: 0x%08x idx: %d\n", +- dev->sensor->name, mbus_code.code, j); +- +- fmt = find_format_by_code(mbus_code.code); +- unicam_dbg(2, dev, "fmt 0x%08x returned as %p, V4L2 FOURCC 0x%08x, csi_dt 0x%02x\n", +- mbus_code.code, fmt, fmt ? fmt->fourcc : 0, +- fmt ? fmt->csi_dt : 0); +- if (fmt) +- return fmt; +- } +- +- return NULL; +-} +- +-static int unicam_try_fmt_vid_cap(struct file *file, void *priv, +- struct v4l2_format *f) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- struct v4l2_subdev_format sd_fmt = { +- .which = V4L2_SUBDEV_FORMAT_TRY, +- .pad = IMAGE_PAD +- }; +- struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format; +- const struct unicam_fmt *fmt; +- int ret; +- +- if (node->pad_id == METADATA_PAD) +- return -EINVAL; +- +- fmt = find_format_by_pix(dev, f->fmt.pix.pixelformat); +- if (!fmt) { +- /* Pixel format not supported by unicam. Choose the first +- * supported format, and let the sensor choose something else. +- */ +- unicam_dbg(3, dev, "Fourcc format (0x%08x) not found. Use first format.\n", +- f->fmt.pix.pixelformat); +- +- fmt = &formats[0]; +- f->fmt.pix.pixelformat = fmt->fourcc; +- } +- +- v4l2_fill_mbus_format(mbus_fmt, &f->fmt.pix, fmt->code); +- /* +- * No support for receiving interlaced video, so never +- * request it from the sensor subdev. +- */ +- mbus_fmt->field = V4L2_FIELD_NONE; +- +- ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, dev->sensor_config, +- &sd_fmt); +- if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) +- return ret; +- +- if (mbus_fmt->field != V4L2_FIELD_NONE) +- unicam_info(dev, "Sensor trying to send interlaced video - results may be unpredictable\n"); +- +- v4l2_fill_pix_format(&f->fmt.pix, &sd_fmt.format); +- if (mbus_fmt->code != fmt->code) { +- /* Sensor has returned an alternate format */ +- fmt = find_format_by_code(mbus_fmt->code); +- if (!fmt) { +- /* The alternate format is one unicam can't support. +- * Find the first format that is supported by both, and +- * then set that. +- */ +- fmt = get_first_supported_format(dev); +- mbus_fmt->code = fmt->code; +- +- ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, +- dev->sensor_config, &sd_fmt); +- if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) +- return ret; +- +- if (mbus_fmt->field != V4L2_FIELD_NONE) +- unicam_info(dev, "Sensor trying to send interlaced video - results may be unpredictable\n"); +- +- v4l2_fill_pix_format(&f->fmt.pix, &sd_fmt.format); +- +- if (mbus_fmt->code != fmt->code) { +- /* We've set a format that the sensor reports +- * as being supported, but it refuses to set it. +- * Not much else we can do. +- * Assume that the sensor driver may accept the +- * format when it is set (rather than tried). +- */ +- unicam_err(dev, "Sensor won't accept default format, and Unicam can't support sensor default\n"); +- } +- } +- +- if (fmt->fourcc) +- f->fmt.pix.pixelformat = fmt->fourcc; +- else +- f->fmt.pix.pixelformat = fmt->repacked_fourcc; +- } +- +- return unicam_calc_format_size_bpl(dev, fmt, f); +-} +- +-static int unicam_s_fmt_vid_cap(struct file *file, void *priv, +- struct v4l2_format *f) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- struct vb2_queue *q = &node->buffer_queue; +- struct v4l2_mbus_framefmt mbus_fmt = {0}; +- const struct unicam_fmt *fmt; +- int ret; +- +- if (vb2_is_busy(q)) +- return -EBUSY; +- +- ret = unicam_try_fmt_vid_cap(file, priv, f); +- if (ret < 0) +- return ret; +- +- fmt = find_format_by_pix(dev, f->fmt.pix.pixelformat); +- if (!fmt) { +- /* Unknown pixel format - adopt a default. +- * This shouldn't happen as try_fmt should have resolved any +- * issues first. +- */ +- fmt = get_first_supported_format(dev); +- if (!fmt) +- /* It shouldn't be possible to get here with no +- * supported formats +- */ +- return -EINVAL; +- f->fmt.pix.pixelformat = fmt->fourcc; +- return -EINVAL; +- } +- +- v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, fmt->code); +- +- ret = __subdev_set_format(dev, &mbus_fmt, node->pad_id); +- if (ret) { +- unicam_dbg(3, dev, "%s __subdev_set_format failed %d\n", +- __func__, ret); +- return ret; +- } +- +- /* Just double check nothing has gone wrong */ +- if (mbus_fmt.code != fmt->code) { +- unicam_dbg(3, dev, +- "%s subdev changed format on us, this should not happen\n", +- __func__); +- return -EINVAL; +- } +- +- node->fmt = fmt; +- node->v_fmt.fmt.pix.pixelformat = f->fmt.pix.pixelformat; +- node->v_fmt.fmt.pix.bytesperline = f->fmt.pix.bytesperline; +- unicam_reset_format(node); +- +- unicam_dbg(3, dev, +- "%s %dx%d, mbus_fmt 0x%08X, V4L2 pix 0x%08X.\n", +- __func__, node->v_fmt.fmt.pix.width, +- node->v_fmt.fmt.pix.height, mbus_fmt.code, +- node->v_fmt.fmt.pix.pixelformat); +- +- *f = node->v_fmt; +- +- return 0; +-} +- +-static int unicam_enum_fmt_meta_cap(struct file *file, void *priv, +- struct v4l2_fmtdesc *f) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- struct v4l2_subdev_mbus_code_enum mbus_code; +- const struct unicam_fmt *fmt = NULL; +- int ret = 0; +- +- if (node->pad_id != METADATA_PAD || f->index != 0) +- return -EINVAL; +- +- if (dev->sensor_embedded_data) { +- memset(&mbus_code, 0, sizeof(mbus_code)); +- mbus_code.index = f->index; +- mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE; +- mbus_code.pad = METADATA_PAD; +- +- ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, NULL, +- &mbus_code); +- if (ret < 0) { +- unicam_dbg(2, dev, +- "subdev->enum_mbus_code idx 0 returned %d - index invalid\n", +- ret); +- return -EINVAL; +- } +- } else { +- mbus_code.code = MEDIA_BUS_FMT_SENSOR_DATA; +- } +- +- fmt = find_format_by_code(mbus_code.code); +- if (fmt) +- f->pixelformat = fmt->fourcc; +- +- return 0; +-} +- +-static int unicam_g_fmt_meta_cap(struct file *file, void *priv, +- struct v4l2_format *f) +-{ +- struct unicam_node *node = video_drvdata(file); +- +- if (node->pad_id != METADATA_PAD) +- return -EINVAL; +- +- *f = node->v_fmt; +- +- return 0; +-} +- +-static int unicam_try_fmt_meta_cap(struct file *file, void *priv, +- struct v4l2_format *f) +-{ +- struct unicam_node *node = video_drvdata(file); +- +- if (node->pad_id != METADATA_PAD) +- return -EINVAL; +- +- *f = node->v_fmt; +- +- return 0; +-} +- +-static int unicam_s_fmt_meta_cap(struct file *file, void *priv, +- struct v4l2_format *f) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- struct v4l2_mbus_framefmt mbus_fmt = { 0 }; +- const struct unicam_fmt *fmt; +- int ret; +- +- if (node->pad_id == IMAGE_PAD) +- return -EINVAL; +- +- if (dev->sensor_embedded_data) { +- fmt = find_format_by_pix(dev, f->fmt.meta.dataformat); +- if (!fmt) { +- unicam_err(dev, "unknown format: V4L2 pix 0x%08x\n", +- f->fmt.meta.dataformat); +- return -EINVAL; +- } +- mbus_fmt.code = fmt->code; +- ret = __subdev_set_format(dev, &mbus_fmt, node->pad_id); +- if (ret) { +- unicam_dbg(3, dev, "%s __subdev_set_format failed %d\n", +- __func__, ret); +- return ret; +- } +- } +- +- *f = node->v_fmt; +- +- unicam_dbg(3, dev, "%s size %d, V4L2 pix 0x%08x\n", +- __func__, node->v_fmt.fmt.meta.buffersize, +- node->v_fmt.fmt.meta.dataformat); +- +- return 0; +-} +- +-static int unicam_queue_setup(struct vb2_queue *vq, +- unsigned int *nbuffers, +- unsigned int *nplanes, +- unsigned int sizes[], +- struct device *alloc_devs[]) +-{ +- struct unicam_node *node = vb2_get_drv_priv(vq); +- struct unicam_device *dev = node->dev; +- unsigned int size = node->pad_id == IMAGE_PAD ? +- node->v_fmt.fmt.pix.sizeimage : +- node->v_fmt.fmt.meta.buffersize; +- +- if (vq->num_buffers + *nbuffers < 3) +- *nbuffers = 3 - vq->num_buffers; +- +- if (*nplanes) { +- if (sizes[0] < size) { +- unicam_err(dev, "sizes[0] %i < size %u\n", sizes[0], +- size); +- return -EINVAL; +- } +- size = sizes[0]; +- } +- +- *nplanes = 1; +- sizes[0] = size; +- +- return 0; +-} +- +-static int unicam_buffer_prepare(struct vb2_buffer *vb) +-{ +- struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue); +- struct unicam_device *dev = node->dev; +- struct unicam_buffer *buf = container_of(vb, struct unicam_buffer, +- vb.vb2_buf); +- unsigned long size; +- +- if (WARN_ON(!node->fmt)) +- return -EINVAL; +- +- size = node->pad_id == IMAGE_PAD ? node->v_fmt.fmt.pix.sizeimage : +- node->v_fmt.fmt.meta.buffersize; +- if (vb2_plane_size(vb, 0) < size) { +- unicam_err(dev, "data will not fit into plane (%lu < %lu)\n", +- vb2_plane_size(vb, 0), size); +- return -EINVAL; +- } +- +- vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size); +- return 0; +-} +- +-static void unicam_buffer_queue(struct vb2_buffer *vb) +-{ +- struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue); +- struct unicam_buffer *buf = container_of(vb, struct unicam_buffer, +- vb.vb2_buf); +- struct unicam_dmaqueue *dma_queue = &node->dma_queue; +- unsigned long flags = 0; +- +- spin_lock_irqsave(&node->dma_queue_lock, flags); +- list_add_tail(&buf->list, &dma_queue->active); +- spin_unlock_irqrestore(&node->dma_queue_lock, flags); +-} +- +-static void unicam_set_packing_config(struct unicam_device *dev) +-{ +- int pack, unpack; +- u32 val; +- +- if (dev->node[IMAGE_PAD].v_fmt.fmt.pix.pixelformat == +- dev->node[IMAGE_PAD].fmt->fourcc) { +- unpack = UNICAM_PUM_NONE; +- pack = UNICAM_PPM_NONE; +- } else { +- switch (dev->node[IMAGE_PAD].fmt->depth) { +- case 8: +- unpack = UNICAM_PUM_UNPACK8; +- break; +- case 10: +- unpack = UNICAM_PUM_UNPACK10; +- break; +- case 12: +- unpack = UNICAM_PUM_UNPACK12; +- break; +- case 14: +- unpack = UNICAM_PUM_UNPACK14; +- break; +- case 16: +- unpack = UNICAM_PUM_UNPACK16; +- break; +- default: +- unpack = UNICAM_PUM_NONE; +- break; +- } +- +- /* Repacking is always to 16bpp */ +- pack = UNICAM_PPM_PACK16; +- } +- +- val = 0; +- set_field(&val, unpack, UNICAM_PUM_MASK); +- set_field(&val, pack, UNICAM_PPM_MASK); +- reg_write(&dev->cfg, UNICAM_IPIPE, val); +-} +- +-static void unicam_cfg_image_id(struct unicam_device *dev) +-{ +- struct unicam_cfg *cfg = &dev->cfg; +- +- if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { +- /* CSI2 mode */ +- reg_write(cfg, UNICAM_IDI0, +- (dev->virtual_channel << 6) | +- dev->node[IMAGE_PAD].fmt->csi_dt); +- } else { +- /* CCP2 mode */ +- reg_write(cfg, UNICAM_IDI0, +- 0x80 | dev->node[IMAGE_PAD].fmt->csi_dt); +- } +-} +- +-static void unicam_enable_ed(struct unicam_device *dev) +-{ +- struct unicam_cfg *cfg = &dev->cfg; +- u32 val = reg_read(cfg, UNICAM_DCS); +- +- set_field(&val, 2, UNICAM_EDL_MASK); +- /* Do not wrap at the end of the embedded data buffer */ +- set_field(&val, 0, UNICAM_DBOB); +- +- reg_write(cfg, UNICAM_DCS, val); +-} +- +-static void unicam_start_rx(struct unicam_device *dev, dma_addr_t *addr) +-{ +- struct unicam_cfg *cfg = &dev->cfg; +- int line_int_freq = dev->node[IMAGE_PAD].v_fmt.fmt.pix.height >> 2; +- unsigned int size, i; +- u32 val; +- +- if (line_int_freq < 128) +- line_int_freq = 128; +- +- /* Enable lane clocks */ +- val = 1; +- for (i = 0; i < dev->active_data_lanes; i++) +- val = val << 2 | 1; +- clk_write(cfg, val); +- +- /* Basic init */ +- reg_write(cfg, UNICAM_CTRL, UNICAM_MEM); +- +- /* Enable analogue control, and leave in reset. */ +- val = UNICAM_AR; +- set_field(&val, 7, UNICAM_CTATADJ_MASK); +- set_field(&val, 7, UNICAM_PTATADJ_MASK); +- reg_write(cfg, UNICAM_ANA, val); +- usleep_range(1000, 2000); +- +- /* Come out of reset */ +- reg_write_field(cfg, UNICAM_ANA, 0, UNICAM_AR); +- +- /* Peripheral reset */ +- reg_write_field(cfg, UNICAM_CTRL, 1, UNICAM_CPR); +- reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_CPR); +- +- reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_CPE); +- +- /* Enable Rx control. */ +- val = reg_read(cfg, UNICAM_CTRL); +- if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { +- set_field(&val, UNICAM_CPM_CSI2, UNICAM_CPM_MASK); +- set_field(&val, UNICAM_DCM_STROBE, UNICAM_DCM_MASK); +- } else { +- set_field(&val, UNICAM_CPM_CCP2, UNICAM_CPM_MASK); +- set_field(&val, dev->bus_flags, UNICAM_DCM_MASK); +- } +- /* Packet framer timeout */ +- set_field(&val, 0xf, UNICAM_PFT_MASK); +- set_field(&val, 128, UNICAM_OET_MASK); +- reg_write(cfg, UNICAM_CTRL, val); +- +- reg_write(cfg, UNICAM_IHWIN, 0); +- reg_write(cfg, UNICAM_IVWIN, 0); +- +- /* AXI bus access QoS setup */ +- val = reg_read(&dev->cfg, UNICAM_PRI); +- set_field(&val, 0, UNICAM_BL_MASK); +- set_field(&val, 0, UNICAM_BS_MASK); +- set_field(&val, 0xe, UNICAM_PP_MASK); +- set_field(&val, 8, UNICAM_NP_MASK); +- set_field(&val, 2, UNICAM_PT_MASK); +- set_field(&val, 1, UNICAM_PE); +- reg_write(cfg, UNICAM_PRI, val); +- +- reg_write_field(cfg, UNICAM_ANA, 0, UNICAM_DDL); +- +- /* Always start in trigger frame capture mode (UNICAM_FCM set) */ +- val = UNICAM_FSIE | UNICAM_FEIE | UNICAM_FCM | UNICAM_IBOB; +- set_field(&val, line_int_freq, UNICAM_LCIE_MASK); +- reg_write(cfg, UNICAM_ICTL, val); +- reg_write(cfg, UNICAM_STA, UNICAM_STA_MASK_ALL); +- reg_write(cfg, UNICAM_ISTA, UNICAM_ISTA_MASK_ALL); +- +- /* tclk_term_en */ +- reg_write_field(cfg, UNICAM_CLT, 2, UNICAM_CLT1_MASK); +- /* tclk_settle */ +- reg_write_field(cfg, UNICAM_CLT, 6, UNICAM_CLT2_MASK); +- /* td_term_en */ +- reg_write_field(cfg, UNICAM_DLT, 2, UNICAM_DLT1_MASK); +- /* ths_settle */ +- reg_write_field(cfg, UNICAM_DLT, 6, UNICAM_DLT2_MASK); +- /* trx_enable */ +- reg_write_field(cfg, UNICAM_DLT, 0, UNICAM_DLT3_MASK); +- +- reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_SOE); +- +- /* Packet compare setup - required to avoid missing frame ends */ +- val = 0; +- set_field(&val, 1, UNICAM_PCE); +- set_field(&val, 1, UNICAM_GI); +- set_field(&val, 1, UNICAM_CPH); +- set_field(&val, 0, UNICAM_PCVC_MASK); +- set_field(&val, 1, UNICAM_PCDT_MASK); +- reg_write(cfg, UNICAM_CMP0, val); +- +- /* Enable clock lane and set up terminations */ +- val = 0; +- if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { +- /* CSI2 */ +- set_field(&val, 1, UNICAM_CLE); +- set_field(&val, 1, UNICAM_CLLPE); +- if (dev->bus_flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) { +- set_field(&val, 1, UNICAM_CLTRE); +- set_field(&val, 1, UNICAM_CLHSE); +- } +- } else { +- /* CCP2 */ +- set_field(&val, 1, UNICAM_CLE); +- set_field(&val, 1, UNICAM_CLHSE); +- set_field(&val, 1, UNICAM_CLTRE); +- } +- reg_write(cfg, UNICAM_CLK, val); +- +- /* +- * Enable required data lanes with appropriate terminations. +- * The same value needs to be written to UNICAM_DATn registers for +- * the active lanes, and 0 for inactive ones. +- */ +- val = 0; +- if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { +- /* CSI2 */ +- set_field(&val, 1, UNICAM_DLE); +- set_field(&val, 1, UNICAM_DLLPE); +- if (dev->bus_flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) { +- set_field(&val, 1, UNICAM_DLTRE); +- set_field(&val, 1, UNICAM_DLHSE); +- } +- } else { +- /* CCP2 */ +- set_field(&val, 1, UNICAM_DLE); +- set_field(&val, 1, UNICAM_DLHSE); +- set_field(&val, 1, UNICAM_DLTRE); +- } +- reg_write(cfg, UNICAM_DAT0, val); +- +- if (dev->active_data_lanes == 1) +- val = 0; +- reg_write(cfg, UNICAM_DAT1, val); +- +- if (dev->max_data_lanes > 2) { +- /* +- * Registers UNICAM_DAT2 and UNICAM_DAT3 only valid if the +- * instance supports more than 2 data lanes. +- */ +- if (dev->active_data_lanes == 2) +- val = 0; +- reg_write(cfg, UNICAM_DAT2, val); +- +- if (dev->active_data_lanes == 3) +- val = 0; +- reg_write(cfg, UNICAM_DAT3, val); +- } +- +- reg_write(&dev->cfg, UNICAM_IBLS, +- dev->node[IMAGE_PAD].v_fmt.fmt.pix.bytesperline); +- size = dev->node[IMAGE_PAD].v_fmt.fmt.pix.sizeimage; +- unicam_wr_dma_addr(&dev->cfg, addr[IMAGE_PAD], size, IMAGE_PAD); +- unicam_set_packing_config(dev); +- unicam_cfg_image_id(dev); +- +- val = reg_read(cfg, UNICAM_MISC); +- set_field(&val, 1, UNICAM_FL0); +- set_field(&val, 1, UNICAM_FL1); +- reg_write(cfg, UNICAM_MISC, val); +- +- if (dev->node[METADATA_PAD].streaming && dev->sensor_embedded_data) { +- size = dev->node[METADATA_PAD].v_fmt.fmt.meta.buffersize; +- unicam_enable_ed(dev); +- unicam_wr_dma_addr(&dev->cfg, addr[METADATA_PAD], size, +- METADATA_PAD); +- } +- +- /* Enable peripheral */ +- reg_write_field(cfg, UNICAM_CTRL, 1, UNICAM_CPE); +- +- /* Load image pointers */ +- reg_write_field(cfg, UNICAM_ICTL, 1, UNICAM_LIP_MASK); +- +- /* Load embedded data buffer pointers if needed */ +- if (dev->node[METADATA_PAD].streaming && dev->sensor_embedded_data) +- reg_write_field(cfg, UNICAM_DCS, 1, UNICAM_LDP); +- +- /* +- * Enable trigger only for the first frame to +- * sync correctly to the FS from the source. +- */ +- reg_write_field(cfg, UNICAM_ICTL, 1, UNICAM_TFC); +-} +- +-static void unicam_disable(struct unicam_device *dev) +-{ +- struct unicam_cfg *cfg = &dev->cfg; +- +- /* Analogue lane control disable */ +- reg_write_field(cfg, UNICAM_ANA, 1, UNICAM_DDL); +- +- /* Stop the output engine */ +- reg_write_field(cfg, UNICAM_CTRL, 1, UNICAM_SOE); +- +- /* Disable the data lanes. */ +- reg_write(cfg, UNICAM_DAT0, 0); +- reg_write(cfg, UNICAM_DAT1, 0); +- +- if (dev->max_data_lanes > 2) { +- reg_write(cfg, UNICAM_DAT2, 0); +- reg_write(cfg, UNICAM_DAT3, 0); +- } +- +- /* Peripheral reset */ +- reg_write_field(cfg, UNICAM_CTRL, 1, UNICAM_CPR); +- usleep_range(50, 100); +- reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_CPR); +- +- /* Disable peripheral */ +- reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_CPE); +- +- /* Clear ED setup */ +- reg_write(cfg, UNICAM_DCS, 0); +- +- /* Disable all lane clocks */ +- clk_write(cfg, 0); +-} +- +-static int unicam_start_streaming(struct vb2_queue *vq, unsigned int count) +-{ +- struct unicam_node *node = vb2_get_drv_priv(vq); +- struct unicam_device *dev = node->dev; +- struct unicam_buffer *buf; +- dma_addr_t buffer_addr[MAX_NODES] = { 0 }; +- int num_nodes_streaming; +- unsigned long flags; +- int ret, i; +- +- node->streaming = 1; +- if (!unicam_all_nodes_streaming(dev)) { +- unicam_dbg(3, dev, "Not all nodes are streaming yet."); +- return 0; +- } +- +- dev->sequence = 0; +- ret = unicam_runtime_get(dev); +- if (ret < 0) { +- unicam_dbg(3, dev, "unicam_runtime_get failed\n"); +- return ret; +- } +- +- dev->active_data_lanes = dev->max_data_lanes; +- if (dev->bus_type == V4L2_MBUS_CSI2_DPHY && +- v4l2_subdev_has_op(dev->sensor, video, g_mbus_config)) { +- struct v4l2_mbus_config mbus_config; +- +- ret = v4l2_subdev_call(dev->sensor, video, g_mbus_config, +- &mbus_config); +- if (ret < 0) { +- unicam_dbg(3, dev, "g_mbus_config failed\n"); +- goto err_pm_put; +- } +- +- dev->active_data_lanes = +- (mbus_config.flags & V4L2_MBUS_CSI2_LANE_MASK) >> +- __ffs(V4L2_MBUS_CSI2_LANE_MASK); +- if (!dev->active_data_lanes) +- dev->active_data_lanes = dev->max_data_lanes; +- } +- if (dev->active_data_lanes > dev->max_data_lanes) { +- unicam_err(dev, "Device has requested %u data lanes, which is >%u configured in DT\n", +- dev->active_data_lanes, dev->max_data_lanes); +- ret = -EINVAL; +- goto err_pm_put; +- } +- +- unicam_dbg(1, dev, "Running with %u data lanes\n", +- dev->active_data_lanes); +- +- ret = clk_set_rate(dev->clock, 100 * 1000 * 1000); +- if (ret) { +- unicam_err(dev, "failed to set up clock\n"); +- goto err_pm_put; +- } +- +- ret = clk_prepare_enable(dev->clock); +- if (ret) { +- unicam_err(dev, "Failed to enable CSI clock: %d\n", ret); +- goto err_pm_put; +- } +- +- num_nodes_streaming = unicam_num_nodes_streaming(dev); +- for (i = 0; i < num_nodes_streaming; i++) { +- spin_lock_irqsave(&dev->node[i].dma_queue_lock, flags); +- buf = list_entry(dev->node[i].dma_queue.active.next, +- struct unicam_buffer, list); +- dev->node[i].cur_frm = buf; +- dev->node[i].next_frm = buf; +- list_del(&buf->list); +- spin_unlock_irqrestore(&dev->node[i].dma_queue_lock, flags); +- buffer_addr[i] = +- vb2_dma_contig_plane_dma_addr(&dev->node[i].cur_frm->vb.vb2_buf, +- 0); +- } +- +- unicam_start_rx(dev, buffer_addr); +- +- ret = v4l2_subdev_call(dev->sensor, video, s_stream, 1); +- if (ret < 0) { +- unicam_err(dev, "stream on failed in subdev\n"); +- goto err_disable_unicam; +- } +- +- return 0; +- +-err_disable_unicam: +- node->streaming = 0; +- unicam_disable(dev); +- clk_disable_unprepare(dev->clock); +-err_pm_put: +- unicam_runtime_put(dev); +- +- return ret; +-} +- +-static void unicam_stop_streaming(struct vb2_queue *vq) +-{ +- struct unicam_node *node = vb2_get_drv_priv(vq); +- struct unicam_device *dev = node->dev; +- struct unicam_dmaqueue *dma_q = &node->dma_queue; +- struct unicam_buffer *buf, *tmp; +- unsigned long flags; +- +- node->streaming = 0; +- +- if (node->pad_id == IMAGE_PAD) { +- /* Stop streaming the sensor and disable the peripheral. +- * We cannot continue streaming embedded data with the +- * image pad disabled. +- */ +- if (v4l2_subdev_call(dev->sensor, video, s_stream, 0) < 0) +- unicam_err(dev, "stream off failed in subdev\n"); +- +- unicam_disable(dev); +- clk_disable_unprepare(dev->clock); +- unicam_runtime_put(dev); +- +- } else if (node->pad_id == METADATA_PAD) { +- /* Allow the hardware to spin in the dummy buffer. +- * This is only really needed if the embedded data pad is +- * disabled before the image pad. The 0x3 in the top two bits +- * signifies uncached accesses through the Videocore memory +- * controller. +- */ +- unicam_wr_dma_addr(&dev->cfg, node->dummy_buf_dma_addr, +- DUMMY_BUF_SIZE, METADATA_PAD); +- } +- +- /* Clear all queued buffers for the node */ +- spin_lock_irqsave(&node->dma_queue_lock, flags); +- list_for_each_entry_safe(buf, tmp, &dma_q->active, list) { +- list_del(&buf->list); +- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); +- } +- +- if (node->cur_frm) +- vb2_buffer_done(&node->cur_frm->vb.vb2_buf, +- VB2_BUF_STATE_ERROR); +- if (node->next_frm && node->cur_frm != node->next_frm) +- vb2_buffer_done(&node->next_frm->vb.vb2_buf, +- VB2_BUF_STATE_ERROR); +- +- node->cur_frm = NULL; +- node->next_frm = NULL; +- spin_unlock_irqrestore(&node->dma_queue_lock, flags); +-} +- +-static int unicam_enum_input(struct file *file, void *priv, +- struct v4l2_input *inp) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- +- if (inp->index != 0) +- return -EINVAL; +- +- inp->type = V4L2_INPUT_TYPE_CAMERA; +- if (v4l2_subdev_has_op(dev->sensor, video, s_dv_timings)) { +- inp->capabilities = V4L2_IN_CAP_DV_TIMINGS; +- inp->std = 0; +- } else if (v4l2_subdev_has_op(dev->sensor, video, s_std)) { +- inp->capabilities = V4L2_IN_CAP_STD; +- if (v4l2_subdev_call(dev->sensor, video, g_tvnorms, &inp->std) +- < 0) +- inp->std = V4L2_STD_ALL; +- } else { +- inp->capabilities = 0; +- inp->std = 0; +- } +- sprintf(inp->name, "Camera 0"); +- return 0; +-} +- +-static int unicam_g_input(struct file *file, void *priv, unsigned int *i) +-{ +- *i = 0; +- +- return 0; +-} +- +-static int unicam_s_input(struct file *file, void *priv, unsigned int i) +-{ +- /* +- * FIXME: Ideally we would like to be able to query the source +- * subdevice for information over the input connectors it supports, +- * and map that through in to a call to video_ops->s_routing. +- * There is no infrastructure support for defining that within +- * devicetree at present. Until that is implemented we can't +- * map a user physical connector number to s_routing input number. +- */ +- if (i > 0) +- return -EINVAL; +- +- return 0; +-} +- +-static int unicam_querystd(struct file *file, void *priv, +- v4l2_std_id *std) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- +- return v4l2_subdev_call(dev->sensor, video, querystd, std); +-} +- +-static int unicam_g_std(struct file *file, void *priv, v4l2_std_id *std) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- +- return v4l2_subdev_call(dev->sensor, video, g_std, std); +-} +- +-static int unicam_s_std(struct file *file, void *priv, v4l2_std_id std) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- int ret; +- v4l2_std_id current_std; +- +- ret = v4l2_subdev_call(dev->sensor, video, g_std, ¤t_std); +- if (ret) +- return ret; +- +- if (std == current_std) +- return 0; +- +- if (vb2_is_busy(&node->buffer_queue)) +- return -EBUSY; +- +- ret = v4l2_subdev_call(dev->sensor, video, s_std, std); +- +- /* Force recomputation of bytesperline */ +- node->v_fmt.fmt.pix.bytesperline = 0; +- +- unicam_reset_format(node); +- +- return ret; +-} +- +-static int unicam_s_edid(struct file *file, void *priv, struct v4l2_edid *edid) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- +- return v4l2_subdev_call(dev->sensor, pad, set_edid, edid); +-} +- +-static int unicam_g_edid(struct file *file, void *priv, struct v4l2_edid *edid) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- +- return v4l2_subdev_call(dev->sensor, pad, get_edid, edid); +-} +- +-static int unicam_s_selection(struct file *file, void *priv, +- struct v4l2_selection *sel) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- struct v4l2_subdev_selection sdsel = { +- .which = V4L2_SUBDEV_FORMAT_ACTIVE, +- .target = sel->target, +- .flags = sel->flags, +- .r = sel->r, +- }; +- +- return v4l2_subdev_call(dev->sensor, pad, set_selection, NULL, &sdsel); +-} +- +-static int unicam_g_selection(struct file *file, void *priv, +- struct v4l2_selection *sel) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- struct v4l2_subdev_selection sdsel = { +- .which = V4L2_SUBDEV_FORMAT_ACTIVE, +- .target = sel->target, +- }; +- int ret; +- +- ret = v4l2_subdev_call(dev->sensor, pad, get_selection, NULL, &sdsel); +- if (!ret) +- sel->r = sdsel.r; +- +- return ret; +-} +- +-static int unicam_enum_framesizes(struct file *file, void *priv, +- struct v4l2_frmsizeenum *fsize) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- const struct unicam_fmt *fmt; +- struct v4l2_subdev_frame_size_enum fse; +- int ret; +- +- if (node->pad_id == IMAGE_PAD) { +- /* check for valid format */ +- fmt = find_format_by_pix(dev, fsize->pixel_format); +- if (!fmt) { +- unicam_dbg(3, dev, "Invalid pixel code: %x\n", +- fsize->pixel_format); +- return -EINVAL; +- } +- fse.code = fmt->code; +- } else { +- /* This pad is for embedded data, so just set the format */ +- fse.code = MEDIA_BUS_FMT_SENSOR_DATA; +- } +- +- fse.which = V4L2_SUBDEV_FORMAT_ACTIVE; +- fse.index = fsize->index; +- fse.pad = node->pad_id; +- +- ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_size, NULL, &fse); +- if (ret) +- return ret; +- +- unicam_dbg(1, dev, "%s: index: %d code: %x W:[%d,%d] H:[%d,%d]\n", +- __func__, fse.index, fse.code, fse.min_width, fse.max_width, +- fse.min_height, fse.max_height); +- +- fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; +- fsize->discrete.width = fse.max_width; +- fsize->discrete.height = fse.max_height; +- +- return 0; +-} +- +-static int unicam_enum_frameintervals(struct file *file, void *priv, +- struct v4l2_frmivalenum *fival) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- const struct unicam_fmt *fmt; +- struct v4l2_subdev_frame_interval_enum fie = { +- .index = fival->index, +- .width = fival->width, +- .height = fival->height, +- .which = V4L2_SUBDEV_FORMAT_ACTIVE, +- }; +- int ret; +- +- fmt = find_format_by_pix(dev, fival->pixel_format); +- if (!fmt) +- return -EINVAL; +- +- fie.code = fmt->code; +- ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_interval, +- NULL, &fie); +- if (ret) +- return ret; +- +- fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; +- fival->discrete = fie.interval; +- +- return 0; +-} +- +-static int unicam_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- +- return v4l2_g_parm_cap(video_devdata(file), dev->sensor, a); +-} +- +-static int unicam_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- +- return v4l2_s_parm_cap(video_devdata(file), dev->sensor, a); +-} +- +-static int unicam_g_dv_timings(struct file *file, void *priv, +- struct v4l2_dv_timings *timings) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- +- return v4l2_subdev_call(dev->sensor, video, g_dv_timings, timings); +-} +- +-static int unicam_s_dv_timings(struct file *file, void *priv, +- struct v4l2_dv_timings *timings) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- struct v4l2_dv_timings current_timings; +- int ret; +- +- ret = v4l2_subdev_call(dev->sensor, video, g_dv_timings, +- ¤t_timings); +- +- if (v4l2_match_dv_timings(timings, ¤t_timings, 0, false)) +- return 0; +- +- if (vb2_is_busy(&node->buffer_queue)) +- return -EBUSY; +- +- ret = v4l2_subdev_call(dev->sensor, video, s_dv_timings, timings); +- +- /* Force recomputation of bytesperline */ +- node->v_fmt.fmt.pix.bytesperline = 0; +- +- unicam_reset_format(node); +- +- return ret; +-} +- +-static int unicam_query_dv_timings(struct file *file, void *priv, +- struct v4l2_dv_timings *timings) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- +- return v4l2_subdev_call(dev->sensor, video, query_dv_timings, timings); +-} +- +-static int unicam_enum_dv_timings(struct file *file, void *priv, +- struct v4l2_enum_dv_timings *timings) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- +- return v4l2_subdev_call(dev->sensor, pad, enum_dv_timings, timings); +-} +- +-static int unicam_dv_timings_cap(struct file *file, void *priv, +- struct v4l2_dv_timings_cap *cap) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- +- return v4l2_subdev_call(dev->sensor, pad, dv_timings_cap, cap); +-} +- +-static int unicam_subscribe_event(struct v4l2_fh *fh, +- const struct v4l2_event_subscription *sub) +-{ +- switch (sub->type) { +- case V4L2_EVENT_FRAME_SYNC: +- return v4l2_event_subscribe(fh, sub, 2, NULL); +- case V4L2_EVENT_SOURCE_CHANGE: +- return v4l2_event_subscribe(fh, sub, 4, NULL); +- } +- +- return v4l2_ctrl_subscribe_event(fh, sub); +-} +- +-static int unicam_log_status(struct file *file, void *fh) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- struct unicam_cfg *cfg = &dev->cfg; +- u32 reg; +- +- /* status for sub devices */ +- v4l2_device_call_all(&dev->v4l2_dev, 0, core, log_status); +- +- unicam_info(dev, "-----Receiver status-----\n"); +- unicam_info(dev, "V4L2 width/height: %ux%u\n", +- node->v_fmt.fmt.pix.width, node->v_fmt.fmt.pix.height); +- unicam_info(dev, "Mediabus format: %08x\n", node->fmt->code); +- unicam_info(dev, "V4L2 format: %08x\n", +- node->v_fmt.fmt.pix.pixelformat); +- reg = reg_read(&dev->cfg, UNICAM_IPIPE); +- unicam_info(dev, "Unpacking/packing: %u / %u\n", +- get_field(reg, UNICAM_PUM_MASK), +- get_field(reg, UNICAM_PPM_MASK)); +- unicam_info(dev, "----Live data----\n"); +- unicam_info(dev, "Programmed stride: %4u\n", +- reg_read(cfg, UNICAM_IBLS)); +- unicam_info(dev, "Detected resolution: %ux%u\n", +- reg_read(cfg, UNICAM_IHSTA), +- reg_read(cfg, UNICAM_IVSTA)); +- unicam_info(dev, "Write pointer: %08x\n", +- reg_read(cfg, UNICAM_IBWP)); +- +- return 0; +-} +- +-static void unicam_notify(struct v4l2_subdev *sd, +- unsigned int notification, void *arg) +-{ +- struct unicam_device *dev = +- container_of(sd->v4l2_dev, struct unicam_device, v4l2_dev); +- +- switch (notification) { +- case V4L2_DEVICE_NOTIFY_EVENT: +- v4l2_event_queue(&dev->node[IMAGE_PAD].video_dev, arg); +- break; +- default: +- break; +- } +-} +- +-static const struct vb2_ops unicam_video_qops = { +- .wait_prepare = vb2_ops_wait_prepare, +- .wait_finish = vb2_ops_wait_finish, +- .queue_setup = unicam_queue_setup, +- .buf_prepare = unicam_buffer_prepare, +- .buf_queue = unicam_buffer_queue, +- .start_streaming = unicam_start_streaming, +- .stop_streaming = unicam_stop_streaming, +-}; +- +-/* +- * unicam_open : This function is based on the v4l2_fh_open helper function. +- * It has been augmented to handle sensor subdevice power management, +- */ +-static int unicam_open(struct file *file) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- int ret; +- +- mutex_lock(&node->lock); +- +- ret = v4l2_fh_open(file); +- if (ret) { +- unicam_err(dev, "v4l2_fh_open failed\n"); +- goto unlock; +- } +- +- node->open++; +- +- if (!v4l2_fh_is_singular_file(file)) +- goto unlock; +- +- ret = v4l2_subdev_call(dev->sensor, core, s_power, 1); +- if (ret < 0 && ret != -ENOIOCTLCMD) { +- v4l2_fh_release(file); +- node->open--; +- goto unlock; +- } +- +- ret = 0; +- +-unlock: +- mutex_unlock(&node->lock); +- return ret; +-} +- +-static int unicam_release(struct file *file) +-{ +- struct unicam_node *node = video_drvdata(file); +- struct unicam_device *dev = node->dev; +- struct v4l2_subdev *sd = dev->sensor; +- bool fh_singular; +- int ret; +- +- mutex_lock(&node->lock); +- +- fh_singular = v4l2_fh_is_singular_file(file); +- +- ret = _vb2_fop_release(file, NULL); +- +- if (fh_singular) +- v4l2_subdev_call(sd, core, s_power, 0); +- +- node->open--; +- mutex_unlock(&node->lock); +- +- return ret; +-} +- +-/* unicam capture driver file operations */ +-static const struct v4l2_file_operations unicam_fops = { +- .owner = THIS_MODULE, +- .open = unicam_open, +- .release = unicam_release, +- .read = vb2_fop_read, +- .poll = vb2_fop_poll, +- .unlocked_ioctl = video_ioctl2, +- .mmap = vb2_fop_mmap, +-}; +- +-/* unicam capture ioctl operations */ +-static const struct v4l2_ioctl_ops unicam_ioctl_ops = { +- .vidioc_querycap = unicam_querycap, +- .vidioc_enum_fmt_vid_cap = unicam_enum_fmt_vid_cap, +- .vidioc_g_fmt_vid_cap = unicam_g_fmt_vid_cap, +- .vidioc_s_fmt_vid_cap = unicam_s_fmt_vid_cap, +- .vidioc_try_fmt_vid_cap = unicam_try_fmt_vid_cap, +- +- .vidioc_enum_fmt_meta_cap = unicam_enum_fmt_meta_cap, +- .vidioc_g_fmt_meta_cap = unicam_g_fmt_meta_cap, +- .vidioc_s_fmt_meta_cap = unicam_s_fmt_meta_cap, +- .vidioc_try_fmt_meta_cap = unicam_try_fmt_meta_cap, +- +- .vidioc_enum_input = unicam_enum_input, +- .vidioc_g_input = unicam_g_input, +- .vidioc_s_input = unicam_s_input, +- +- .vidioc_querystd = unicam_querystd, +- .vidioc_s_std = unicam_s_std, +- .vidioc_g_std = unicam_g_std, +- +- .vidioc_g_edid = unicam_g_edid, +- .vidioc_s_edid = unicam_s_edid, +- +- .vidioc_enum_framesizes = unicam_enum_framesizes, +- .vidioc_enum_frameintervals = unicam_enum_frameintervals, +- +- .vidioc_g_selection = unicam_g_selection, +- .vidioc_s_selection = unicam_s_selection, +- +- .vidioc_g_parm = unicam_g_parm, +- .vidioc_s_parm = unicam_s_parm, +- +- .vidioc_s_dv_timings = unicam_s_dv_timings, +- .vidioc_g_dv_timings = unicam_g_dv_timings, +- .vidioc_query_dv_timings = unicam_query_dv_timings, +- .vidioc_enum_dv_timings = unicam_enum_dv_timings, +- .vidioc_dv_timings_cap = unicam_dv_timings_cap, +- +- .vidioc_reqbufs = vb2_ioctl_reqbufs, +- .vidioc_create_bufs = vb2_ioctl_create_bufs, +- .vidioc_prepare_buf = vb2_ioctl_prepare_buf, +- .vidioc_querybuf = vb2_ioctl_querybuf, +- .vidioc_qbuf = vb2_ioctl_qbuf, +- .vidioc_dqbuf = vb2_ioctl_dqbuf, +- .vidioc_expbuf = vb2_ioctl_expbuf, +- .vidioc_streamon = vb2_ioctl_streamon, +- .vidioc_streamoff = vb2_ioctl_streamoff, +- +- .vidioc_log_status = unicam_log_status, +- .vidioc_subscribe_event = unicam_subscribe_event, +- .vidioc_unsubscribe_event = v4l2_event_unsubscribe, +-}; +- +-static int +-unicam_async_bound(struct v4l2_async_notifier *notifier, +- struct v4l2_subdev *subdev, +- struct v4l2_async_subdev *asd) +-{ +- struct unicam_device *unicam = container_of(notifier->v4l2_dev, +- struct unicam_device, v4l2_dev); +- +- if (unicam->sensor) { +- unicam_info(unicam, "Rejecting subdev %s (Already set!!)", +- subdev->name); +- return 0; +- } +- +- unicam->sensor = subdev; +- unicam_dbg(1, unicam, "Using sensor %s for capture\n", subdev->name); +- +- return 0; +-} +- +-static int register_node(struct unicam_device *unicam, struct unicam_node *node, +- enum v4l2_buf_type type, int pad_id) +-{ +- struct video_device *vdev; +- struct vb2_queue *q; +- struct v4l2_mbus_framefmt mbus_fmt = {0}; +- const struct unicam_fmt *fmt; +- int ret; +- +- if (unicam->sensor_embedded_data || pad_id != METADATA_PAD) { +- ret = __subdev_get_format(unicam, &mbus_fmt, pad_id); +- if (ret) { +- unicam_err(unicam, "Failed to get_format - ret %d\n", +- ret); +- return ret; +- } +- +- fmt = find_format_by_code(mbus_fmt.code); +- if (!fmt) { +- /* Find the first format that the sensor and unicam both +- * support +- */ +- fmt = get_first_supported_format(unicam); +- +- if (!fmt) +- /* No compatible formats */ +- return -EINVAL; +- +- mbus_fmt.code = fmt->code; +- ret = __subdev_set_format(unicam, &mbus_fmt, pad_id); +- if (ret) +- return -EINVAL; +- } +- if (mbus_fmt.field != V4L2_FIELD_NONE) { +- /* Interlaced not supported - disable it now. */ +- mbus_fmt.field = V4L2_FIELD_NONE; +- ret = __subdev_set_format(unicam, &mbus_fmt, pad_id); +- if (ret) +- return -EINVAL; +- } +- } else { +- /* Fix this node format as embedded data. */ +- fmt = find_format_by_code(MEDIA_BUS_FMT_SENSOR_DATA); +- } +- +- node->dev = unicam; +- node->pad_id = pad_id; +- node->fmt = fmt; +- if (fmt->fourcc) { +- if (fmt->fourcc != V4L2_META_FMT_SENSOR_DATA) +- node->v_fmt.fmt.pix.pixelformat = fmt->fourcc; +- else +- node->v_fmt.fmt.meta.dataformat = fmt->fourcc; +- } else { +- node->v_fmt.fmt.pix.pixelformat = fmt->repacked_fourcc; +- } +- +- /* Read current subdev format */ +- unicam_reset_format(node); +- +- if (v4l2_subdev_has_op(unicam->sensor, video, s_std)) { +- v4l2_std_id tvnorms; +- +- if (WARN_ON(!v4l2_subdev_has_op(unicam->sensor, video, +- g_tvnorms))) +- /* +- * Subdevice should not advertise s_std but not +- * g_tvnorms +- */ +- return -EINVAL; +- +- ret = v4l2_subdev_call(unicam->sensor, video, +- g_tvnorms, &tvnorms); +- if (WARN_ON(ret)) +- return -EINVAL; +- node->video_dev.tvnorms |= tvnorms; +- } +- +- spin_lock_init(&node->dma_queue_lock); +- mutex_init(&node->lock); +- +- vdev = &node->video_dev; +- if (pad_id == IMAGE_PAD) { +- /* Add controls from the subdevice */ +- ret = v4l2_ctrl_add_handler(&node->ctrl_handler, +- unicam->sensor->ctrl_handler, NULL, +- true); +- if (ret < 0) +- return ret; +- +- /* +- * If the sensor subdevice has any controls, associate the node +- * with the ctrl handler to allow access from userland. +- */ +- if (!list_empty(&node->ctrl_handler.ctrls)) +- vdev->ctrl_handler = &node->ctrl_handler; +- } +- +- q = &node->buffer_queue; +- q->type = type; +- q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ; +- q->drv_priv = node; +- q->ops = &unicam_video_qops; +- q->mem_ops = &vb2_dma_contig_memops; +- q->buf_struct_size = sizeof(struct unicam_buffer); +- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; +- q->lock = &node->lock; +- q->min_buffers_needed = 1; +- q->dev = &unicam->pdev->dev; +- +- ret = vb2_queue_init(q); +- if (ret) { +- unicam_err(unicam, "vb2_queue_init() failed\n"); +- return ret; +- } +- +- INIT_LIST_HEAD(&node->dma_queue.active); +- +- vdev->release = video_device_release_empty; +- vdev->fops = &unicam_fops; +- vdev->ioctl_ops = &unicam_ioctl_ops; +- vdev->v4l2_dev = &unicam->v4l2_dev; +- vdev->vfl_dir = VFL_DIR_RX; +- vdev->queue = q; +- vdev->lock = &node->lock; +- vdev->device_caps = (pad_id == IMAGE_PAD) ? +- (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING) : +- (V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING); +- +- /* Define the device names */ +- snprintf(vdev->name, sizeof(vdev->name), "%s-%s", UNICAM_MODULE_NAME, +- node->pad_id == IMAGE_PAD ? "image" : "embedded"); +- +- video_set_drvdata(vdev, node); +- vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT; +- +- node->dummy_buf_cpu_addr = dma_alloc_coherent(&unicam->pdev->dev, +- DUMMY_BUF_SIZE, +- &node->dummy_buf_dma_addr, +- GFP_ATOMIC); +- if (!node->dummy_buf_cpu_addr) { +- unicam_err(unicam, "Unable to allocate dummy buffer.\n"); +- return -ENOMEM; +- } +- +- if (node->pad_id == METADATA_PAD) { +- v4l2_disable_ioctl(vdev, VIDIOC_DQEVENT); +- v4l2_disable_ioctl(vdev, VIDIOC_SUBSCRIBE_EVENT); +- v4l2_disable_ioctl(vdev, VIDIOC_UNSUBSCRIBE_EVENT); +- } +- if (node->pad_id == METADATA_PAD || +- !v4l2_subdev_has_op(unicam->sensor, video, s_std)) { +- v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_STD); +- v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_STD); +- v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUMSTD); +- } +- if (node->pad_id == METADATA_PAD || +- !v4l2_subdev_has_op(unicam->sensor, video, querystd)) +- v4l2_disable_ioctl(&node->video_dev, VIDIOC_QUERYSTD); +- if (node->pad_id == METADATA_PAD || +- !v4l2_subdev_has_op(unicam->sensor, video, s_dv_timings)) { +- v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_EDID); +- v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_EDID); +- v4l2_disable_ioctl(&node->video_dev, VIDIOC_DV_TIMINGS_CAP); +- v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_DV_TIMINGS); +- v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_DV_TIMINGS); +- v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUM_DV_TIMINGS); +- v4l2_disable_ioctl(&node->video_dev, VIDIOC_QUERY_DV_TIMINGS); +- } +- if (node->pad_id == METADATA_PAD || +- !v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_interval)) +- v4l2_disable_ioctl(&node->video_dev, +- VIDIOC_ENUM_FRAMEINTERVALS); +- if (node->pad_id == METADATA_PAD || +- !v4l2_subdev_has_op(unicam->sensor, video, g_frame_interval)) +- v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_PARM); +- if (node->pad_id == METADATA_PAD || +- !v4l2_subdev_has_op(unicam->sensor, video, s_frame_interval)) +- v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_PARM); +- +- if (node->pad_id == METADATA_PAD || +- !v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_size)) +- v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUM_FRAMESIZES); +- +- if (node->pad_id == METADATA_PAD || +- !v4l2_subdev_has_op(unicam->sensor, pad, set_selection)) +- v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_SELECTION); +- +- if (node->pad_id == METADATA_PAD || +- !v4l2_subdev_has_op(unicam->sensor, pad, get_selection)) +- v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_SELECTION); +- +- ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); +- if (ret) { +- unicam_err(unicam, "Unable to register video device.\n"); +- return ret; +- } +- node->registered = 1; +- +- if (unicam->sensor_embedded_data) { +- ret = media_create_pad_link(&unicam->sensor->entity, pad_id, +- &node->video_dev.entity, 0, +- MEDIA_LNK_FL_ENABLED | +- MEDIA_LNK_FL_IMMUTABLE); +- if (ret) +- unicam_err(unicam, "Unable to create pad links.\n"); +- } +- +- return ret; +-} +- +-static void unregister_nodes(struct unicam_device *unicam) +-{ +- struct unicam_node *node; +- int i; +- +- for (i = 0; i < MAX_NODES; i++) { +- node = &unicam->node[i]; +- if (node->dummy_buf_cpu_addr) { +- dma_free_coherent(&unicam->pdev->dev, DUMMY_BUF_SIZE, +- node->dummy_buf_cpu_addr, +- node->dummy_buf_dma_addr); +- } +- if (node->registered) { +- video_unregister_device(&node->video_dev); +- node->registered = 0; +- } +- } +-} +- +-static int unicam_probe_complete(struct unicam_device *unicam) +-{ +- int ret; +- +- v4l2_set_subdev_hostdata(unicam->sensor, unicam); +- +- unicam->v4l2_dev.notify = unicam_notify; +- +- unicam->sensor_config = v4l2_subdev_alloc_pad_config(unicam->sensor); +- if (!unicam->sensor_config) +- return -ENOMEM; +- +- unicam->sensor_embedded_data = (unicam->sensor->entity.num_pads >= 2); +- +- ret = register_node(unicam, &unicam->node[IMAGE_PAD], +- V4L2_BUF_TYPE_VIDEO_CAPTURE, IMAGE_PAD); +- if (ret) { +- unicam_err(unicam, "Unable to register subdev node 0.\n"); +- goto unregister; +- } +- +- ret = register_node(unicam, &unicam->node[METADATA_PAD], +- V4L2_BUF_TYPE_META_CAPTURE, METADATA_PAD); +- if (ret) { +- unicam_err(unicam, "Unable to register subdev node 1.\n"); +- goto unregister; +- } +- +- ret = v4l2_device_register_ro_subdev_nodes(&unicam->v4l2_dev); +- if (ret) { +- unicam_err(unicam, "Unable to register subdev nodes.\n"); +- goto unregister; +- } +- +- return 0; +- +-unregister: +- unregister_nodes(unicam); +- +- return ret; +-} +- +-static int unicam_async_complete(struct v4l2_async_notifier *notifier) +-{ +- struct unicam_device *unicam = container_of(notifier->v4l2_dev, +- struct unicam_device, v4l2_dev); +- +- return unicam_probe_complete(unicam); +-} +- +-static const struct v4l2_async_notifier_operations unicam_async_ops = { +- .bound = unicam_async_bound, +- .complete = unicam_async_complete, +-}; +- +-static int of_unicam_connect_subdevs(struct unicam_device *dev) +-{ +- struct platform_device *pdev = dev->pdev; +- struct device_node *parent, *ep_node = NULL, *remote_ep = NULL, +- *sensor_node = NULL; +- struct v4l2_fwnode_endpoint *ep; +- struct v4l2_async_subdev *asd; +- unsigned int peripheral_data_lanes; +- int ret = -EINVAL; +- unsigned int lane; +- +- parent = pdev->dev.of_node; +- +- asd = &dev->asd; +- ep = &dev->endpoint; +- +- ep_node = of_graph_get_next_endpoint(parent, NULL); +- if (!ep_node) { +- unicam_dbg(3, dev, "can't get next endpoint\n"); +- goto cleanup_exit; +- } +- +- unicam_dbg(3, dev, "ep_node is %s\n", ep_node->name); +- +- v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), ep); +- +- for (lane = 0; lane < ep->bus.mipi_csi2.num_data_lanes; lane++) { +- if (ep->bus.mipi_csi2.data_lanes[lane] != lane + 1) { +- unicam_err(dev, "Local endpoint - data lane reordering not supported\n"); +- goto cleanup_exit; +- } +- } +- +- peripheral_data_lanes = ep->bus.mipi_csi2.num_data_lanes; +- +- sensor_node = of_graph_get_remote_port_parent(ep_node); +- if (!sensor_node) { +- unicam_dbg(3, dev, "can't get remote parent\n"); +- goto cleanup_exit; +- } +- unicam_dbg(3, dev, "sensor_node is %s\n", sensor_node->name); +- asd->match_type = V4L2_ASYNC_MATCH_FWNODE; +- asd->match.fwnode = of_fwnode_handle(sensor_node); +- +- remote_ep = of_graph_get_remote_endpoint(ep_node); +- if (!remote_ep) { +- unicam_dbg(3, dev, "can't get remote-endpoint\n"); +- goto cleanup_exit; +- } +- unicam_dbg(3, dev, "remote_ep is %s\n", remote_ep->name); +- v4l2_fwnode_endpoint_parse(of_fwnode_handle(remote_ep), ep); +- unicam_dbg(3, dev, "parsed remote_ep to endpoint. nr_of_link_frequencies %u, bus_type %u\n", +- ep->nr_of_link_frequencies, ep->bus_type); +- +- switch (ep->bus_type) { +- case V4L2_MBUS_CSI2_DPHY: +- if (ep->bus.mipi_csi2.num_data_lanes > +- peripheral_data_lanes) { +- unicam_err(dev, "Subdevice %s wants too many data lanes (%u > %u)\n", +- sensor_node->name, +- ep->bus.mipi_csi2.num_data_lanes, +- peripheral_data_lanes); +- goto cleanup_exit; +- } +- for (lane = 0; +- lane < ep->bus.mipi_csi2.num_data_lanes; +- lane++) { +- if (ep->bus.mipi_csi2.data_lanes[lane] != lane + 1) { +- unicam_err(dev, "Subdevice %s - incompatible data lane config\n", +- sensor_node->name); +- goto cleanup_exit; +- } +- } +- dev->max_data_lanes = ep->bus.mipi_csi2.num_data_lanes; +- dev->bus_flags = ep->bus.mipi_csi2.flags; +- break; +- case V4L2_MBUS_CCP2: +- if (ep->bus.mipi_csi1.clock_lane != 0 || +- ep->bus.mipi_csi1.data_lane != 1) { +- unicam_err(dev, "Subdevice %s incompatible lane config\n", +- sensor_node->name); +- goto cleanup_exit; +- } +- dev->max_data_lanes = 1; +- dev->bus_flags = ep->bus.mipi_csi1.strobe; +- break; +- default: +- /* Unsupported bus type */ +- unicam_err(dev, "sub-device %s is not a CSI2 or CCP2 device %d\n", +- sensor_node->name, ep->bus_type); +- goto cleanup_exit; +- } +- +- /* Store bus type - CSI2 or CCP2 */ +- dev->bus_type = ep->bus_type; +- unicam_dbg(3, dev, "bus_type is %d\n", dev->bus_type); +- +- /* Store Virtual Channel number */ +- dev->virtual_channel = ep->base.id; +- +- unicam_dbg(3, dev, "v4l2-endpoint: %s\n", +- dev->bus_type == V4L2_MBUS_CSI2_DPHY ? "CSI2" : "CCP2"); +- unicam_dbg(3, dev, "Virtual Channel=%d\n", dev->virtual_channel); +- if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) +- unicam_dbg(3, dev, "flags=0x%08x\n", ep->bus.mipi_csi2.flags); +- unicam_dbg(3, dev, "num_data_lanes=%d\n", dev->max_data_lanes); +- +- unicam_dbg(1, dev, "found sub-device %s\n", sensor_node->name); +- +- v4l2_async_notifier_init(&dev->notifier); +- +- ret = v4l2_async_notifier_add_subdev(&dev->notifier, asd); +- if (ret) { +- unicam_err(dev, "Error adding subdevice - ret %d\n", ret); +- goto cleanup_exit; +- } +- +- dev->notifier.ops = &unicam_async_ops; +- ret = v4l2_async_notifier_register(&dev->v4l2_dev, +- &dev->notifier); +- if (ret) { +- unicam_err(dev, "Error registering async notifier - ret %d\n", +- ret); +- ret = -EINVAL; +- } +- +-cleanup_exit: +- if (remote_ep) +- of_node_put(remote_ep); +- if (sensor_node) +- of_node_put(sensor_node); +- if (ep_node) +- of_node_put(ep_node); +- +- return ret; +-} +- +-static int unicam_probe(struct platform_device *pdev) +-{ +- struct unicam_cfg *unicam_cfg; +- struct unicam_device *unicam; +- struct v4l2_ctrl_handler *hdl; +- struct resource *res; +- int ret; +- +- unicam = devm_kzalloc(&pdev->dev, sizeof(*unicam), GFP_KERNEL); +- if (!unicam) +- return -ENOMEM; +- +- unicam->pdev = pdev; +- unicam_cfg = &unicam->cfg; +- +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- unicam_cfg->base = devm_ioremap_resource(&pdev->dev, res); +- if (IS_ERR(unicam_cfg->base)) { +- unicam_err(unicam, "Failed to get main io block\n"); +- return PTR_ERR(unicam_cfg->base); +- } +- +- res = platform_get_resource(pdev, IORESOURCE_MEM, 1); +- unicam_cfg->clk_gate_base = devm_ioremap_resource(&pdev->dev, res); +- if (IS_ERR(unicam_cfg->clk_gate_base)) { +- unicam_err(unicam, "Failed to get 2nd io block\n"); +- return PTR_ERR(unicam_cfg->clk_gate_base); +- } +- +- unicam->clock = devm_clk_get(&pdev->dev, "lp"); +- if (IS_ERR(unicam->clock)) { +- unicam_err(unicam, "Failed to get clock\n"); +- return PTR_ERR(unicam->clock); +- } +- +- ret = platform_get_irq(pdev, 0); +- if (ret <= 0) { +- dev_err(&pdev->dev, "No IRQ resource\n"); +- return -ENODEV; +- } +- +- ret = devm_request_irq(&pdev->dev, ret, unicam_isr, 0, +- "unicam_capture0", unicam); +- if (ret) { +- dev_err(&pdev->dev, "Unable to request interrupt\n"); +- return -EINVAL; +- } +- +- unicam->mdev.dev = &pdev->dev; +- strscpy(unicam->mdev.model, UNICAM_MODULE_NAME, +- sizeof(unicam->mdev.model)); +- strscpy(unicam->mdev.serial, "", sizeof(unicam->mdev.serial)); +- snprintf(unicam->mdev.bus_info, sizeof(unicam->mdev.bus_info), +- "platform:%s %s", +- pdev->dev.driver->name, dev_name(&pdev->dev)); +- unicam->mdev.hw_revision = 1; +- +- media_entity_pads_init(&unicam->node[IMAGE_PAD].video_dev.entity, 1, +- &unicam->node[IMAGE_PAD].pad); +- media_entity_pads_init(&unicam->node[METADATA_PAD].video_dev.entity, 1, +- &unicam->node[METADATA_PAD].pad); +- media_device_init(&unicam->mdev); +- +- unicam->v4l2_dev.mdev = &unicam->mdev; +- +- ret = v4l2_device_register(&pdev->dev, &unicam->v4l2_dev); +- if (ret) { +- unicam_err(unicam, +- "Unable to register v4l2 device.\n"); +- goto media_cleanup; +- } +- +- ret = media_device_register(&unicam->mdev); +- if (ret < 0) { +- unicam_err(unicam, +- "Unable to register media-controller device.\n"); +- goto probe_out_v4l2_unregister; +- } +- +- /* Reserve space for the controls */ +- hdl = &unicam->node[IMAGE_PAD].ctrl_handler; +- ret = v4l2_ctrl_handler_init(hdl, 16); +- if (ret < 0) +- goto media_unregister; +- +- /* set the driver data in platform device */ +- platform_set_drvdata(pdev, unicam); +- +- ret = of_unicam_connect_subdevs(unicam); +- if (ret) { +- dev_err(&pdev->dev, "Failed to connect subdevs\n"); +- goto free_hdl; +- } +- +- /* Enable the block power domain */ +- pm_runtime_enable(&pdev->dev); +- +- return 0; +- +-free_hdl: +- v4l2_ctrl_handler_free(hdl); +-media_unregister: +- media_device_unregister(&unicam->mdev); +-probe_out_v4l2_unregister: +- v4l2_device_unregister(&unicam->v4l2_dev); +-media_cleanup: +- media_device_cleanup(&unicam->mdev); +- +- return ret; +-} +- +-static int unicam_remove(struct platform_device *pdev) +-{ +- struct unicam_device *unicam = platform_get_drvdata(pdev); +- +- unicam_dbg(2, unicam, "%s\n", __func__); +- +- pm_runtime_disable(&pdev->dev); +- +- v4l2_async_notifier_unregister(&unicam->notifier); +- v4l2_ctrl_handler_free(&unicam->node[IMAGE_PAD].ctrl_handler); +- v4l2_device_unregister(&unicam->v4l2_dev); +- unregister_nodes(unicam); +- if (unicam->sensor_config) +- v4l2_subdev_free_pad_config(unicam->sensor_config); +- media_device_unregister(&unicam->mdev); +- media_device_cleanup(&unicam->mdev); +- +- return 0; +-} +- +-static const struct of_device_id unicam_of_match[] = { +- { .compatible = "brcm,bcm2835-unicam", }, +- { /* sentinel */ }, +-}; +-MODULE_DEVICE_TABLE(of, unicam_of_match); +- +-static struct platform_driver unicam_driver = { +- .probe = unicam_probe, +- .remove = unicam_remove, +- .driver = { +- .name = UNICAM_MODULE_NAME, +- .of_match_table = of_match_ptr(unicam_of_match), +- }, +-}; +- +-module_platform_driver(unicam_driver); +- +-MODULE_AUTHOR("Dave Stevenson <dave.stevenson@raspberrypi.com>"); +-MODULE_DESCRIPTION("BCM2835 Unicam driver"); +-MODULE_LICENSE("GPL"); +-MODULE_VERSION(UNICAM_VERSION); +--- a/drivers/media/platform/bcm2835/vc4-regs-unicam.h ++++ /dev/null +@@ -1,253 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-only */ +- +-/* +- * Copyright (C) 2017-2020 Raspberry Pi Trading. +- * Dave Stevenson <dave.stevenson@raspberrypi.com> +- */ +- +-#ifndef VC4_REGS_UNICAM_H +-#define VC4_REGS_UNICAM_H +- +-/* +- * The following values are taken from files found within the code drop +- * made by Broadcom for the BCM21553 Graphics Driver, predominantly in +- * brcm_usrlib/dag/vmcsx/vcinclude/hardware_vc4.h. +- * They have been modified to be only the register offset. +- */ +-#define UNICAM_CTRL 0x000 +-#define UNICAM_STA 0x004 +-#define UNICAM_ANA 0x008 +-#define UNICAM_PRI 0x00c +-#define UNICAM_CLK 0x010 +-#define UNICAM_CLT 0x014 +-#define UNICAM_DAT0 0x018 +-#define UNICAM_DAT1 0x01c +-#define UNICAM_DAT2 0x020 +-#define UNICAM_DAT3 0x024 +-#define UNICAM_DLT 0x028 +-#define UNICAM_CMP0 0x02c +-#define UNICAM_CMP1 0x030 +-#define UNICAM_CAP0 0x034 +-#define UNICAM_CAP1 0x038 +-#define UNICAM_ICTL 0x100 +-#define UNICAM_ISTA 0x104 +-#define UNICAM_IDI0 0x108 +-#define UNICAM_IPIPE 0x10c +-#define UNICAM_IBSA0 0x110 +-#define UNICAM_IBEA0 0x114 +-#define UNICAM_IBLS 0x118 +-#define UNICAM_IBWP 0x11c +-#define UNICAM_IHWIN 0x120 +-#define UNICAM_IHSTA 0x124 +-#define UNICAM_IVWIN 0x128 +-#define UNICAM_IVSTA 0x12c +-#define UNICAM_ICC 0x130 +-#define UNICAM_ICS 0x134 +-#define UNICAM_IDC 0x138 +-#define UNICAM_IDPO 0x13c +-#define UNICAM_IDCA 0x140 +-#define UNICAM_IDCD 0x144 +-#define UNICAM_IDS 0x148 +-#define UNICAM_DCS 0x200 +-#define UNICAM_DBSA0 0x204 +-#define UNICAM_DBEA0 0x208 +-#define UNICAM_DBWP 0x20c +-#define UNICAM_DBCTL 0x300 +-#define UNICAM_IBSA1 0x304 +-#define UNICAM_IBEA1 0x308 +-#define UNICAM_IDI1 0x30c +-#define UNICAM_DBSA1 0x310 +-#define UNICAM_DBEA1 0x314 +-#define UNICAM_MISC 0x400 +- +-/* +- * The following bitmasks are from the kernel released by Broadcom +- * for Android - https://android.googlesource.com/kernel/bcm/ +- * The Rhea, Hawaii, and Java chips all contain the same VideoCore4 +- * Unicam block as BCM2835, as defined in eg +- * arch/arm/mach-rhea/include/mach/rdb_A0/brcm_rdb_cam.h and similar. +- * Values reworked to use the kernel BIT and GENMASK macros. +- * +- * Some of the bit mnenomics have been amended to match the datasheet. +- */ +-/* UNICAM_CTRL Register */ +-#define UNICAM_CPE BIT(0) +-#define UNICAM_MEM BIT(1) +-#define UNICAM_CPR BIT(2) +-#define UNICAM_CPM_MASK GENMASK(3, 3) +-#define UNICAM_CPM_CSI2 0 +-#define UNICAM_CPM_CCP2 1 +-#define UNICAM_SOE BIT(4) +-#define UNICAM_DCM_MASK GENMASK(5, 5) +-#define UNICAM_DCM_STROBE 0 +-#define UNICAM_DCM_DATA 1 +-#define UNICAM_SLS BIT(6) +-#define UNICAM_PFT_MASK GENMASK(11, 8) +-#define UNICAM_OET_MASK GENMASK(20, 12) +- +-/* UNICAM_STA Register */ +-#define UNICAM_SYN BIT(0) +-#define UNICAM_CS BIT(1) +-#define UNICAM_SBE BIT(2) +-#define UNICAM_PBE BIT(3) +-#define UNICAM_HOE BIT(4) +-#define UNICAM_PLE BIT(5) +-#define UNICAM_SSC BIT(6) +-#define UNICAM_CRCE BIT(7) +-#define UNICAM_OES BIT(8) +-#define UNICAM_IFO BIT(9) +-#define UNICAM_OFO BIT(10) +-#define UNICAM_BFO BIT(11) +-#define UNICAM_DL BIT(12) +-#define UNICAM_PS BIT(13) +-#define UNICAM_IS BIT(14) +-#define UNICAM_PI0 BIT(15) +-#define UNICAM_PI1 BIT(16) +-#define UNICAM_FSI_S BIT(17) +-#define UNICAM_FEI_S BIT(18) +-#define UNICAM_LCI_S BIT(19) +-#define UNICAM_BUF0_RDY BIT(20) +-#define UNICAM_BUF0_NO BIT(21) +-#define UNICAM_BUF1_RDY BIT(22) +-#define UNICAM_BUF1_NO BIT(23) +-#define UNICAM_DI BIT(24) +- +-#define UNICAM_STA_MASK_ALL \ +- (UNICAM_DL + \ +- UNICAM_SBE + \ +- UNICAM_PBE + \ +- UNICAM_HOE + \ +- UNICAM_PLE + \ +- UNICAM_SSC + \ +- UNICAM_CRCE + \ +- UNICAM_IFO + \ +- UNICAM_OFO + \ +- UNICAM_PS + \ +- UNICAM_PI0 + \ +- UNICAM_PI1) +- +-/* UNICAM_ANA Register */ +-#define UNICAM_APD BIT(0) +-#define UNICAM_BPD BIT(1) +-#define UNICAM_AR BIT(2) +-#define UNICAM_DDL BIT(3) +-#define UNICAM_CTATADJ_MASK GENMASK(7, 4) +-#define UNICAM_PTATADJ_MASK GENMASK(11, 8) +- +-/* UNICAM_PRI Register */ +-#define UNICAM_PE BIT(0) +-#define UNICAM_PT_MASK GENMASK(2, 1) +-#define UNICAM_NP_MASK GENMASK(7, 4) +-#define UNICAM_PP_MASK GENMASK(11, 8) +-#define UNICAM_BS_MASK GENMASK(15, 12) +-#define UNICAM_BL_MASK GENMASK(17, 16) +- +-/* UNICAM_CLK Register */ +-#define UNICAM_CLE BIT(0) +-#define UNICAM_CLPD BIT(1) +-#define UNICAM_CLLPE BIT(2) +-#define UNICAM_CLHSE BIT(3) +-#define UNICAM_CLTRE BIT(4) +-#define UNICAM_CLAC_MASK GENMASK(8, 5) +-#define UNICAM_CLSTE BIT(29) +- +-/* UNICAM_CLT Register */ +-#define UNICAM_CLT1_MASK GENMASK(7, 0) +-#define UNICAM_CLT2_MASK GENMASK(15, 8) +- +-/* UNICAM_DATn Registers */ +-#define UNICAM_DLE BIT(0) +-#define UNICAM_DLPD BIT(1) +-#define UNICAM_DLLPE BIT(2) +-#define UNICAM_DLHSE BIT(3) +-#define UNICAM_DLTRE BIT(4) +-#define UNICAM_DLSM BIT(5) +-#define UNICAM_DLFO BIT(28) +-#define UNICAM_DLSTE BIT(29) +- +-#define UNICAM_DAT_MASK_ALL (UNICAM_DLSTE + UNICAM_DLFO) +- +-/* UNICAM_DLT Register */ +-#define UNICAM_DLT1_MASK GENMASK(7, 0) +-#define UNICAM_DLT2_MASK GENMASK(15, 8) +-#define UNICAM_DLT3_MASK GENMASK(23, 16) +- +-/* UNICAM_ICTL Register */ +-#define UNICAM_FSIE BIT(0) +-#define UNICAM_FEIE BIT(1) +-#define UNICAM_IBOB BIT(2) +-#define UNICAM_FCM BIT(3) +-#define UNICAM_TFC BIT(4) +-#define UNICAM_LIP_MASK GENMASK(6, 5) +-#define UNICAM_LCIE_MASK GENMASK(28, 16) +- +-/* UNICAM_IDI0/1 Register */ +-#define UNICAM_ID0_MASK GENMASK(7, 0) +-#define UNICAM_ID1_MASK GENMASK(15, 8) +-#define UNICAM_ID2_MASK GENMASK(23, 16) +-#define UNICAM_ID3_MASK GENMASK(31, 24) +- +-/* UNICAM_ISTA Register */ +-#define UNICAM_FSI BIT(0) +-#define UNICAM_FEI BIT(1) +-#define UNICAM_LCI BIT(2) +- +-#define UNICAM_ISTA_MASK_ALL (UNICAM_FSI + UNICAM_FEI + UNICAM_LCI) +- +-/* UNICAM_IPIPE Register */ +-#define UNICAM_PUM_MASK GENMASK(2, 0) +- /* Unpacking modes */ +- #define UNICAM_PUM_NONE 0 +- #define UNICAM_PUM_UNPACK6 1 +- #define UNICAM_PUM_UNPACK7 2 +- #define UNICAM_PUM_UNPACK8 3 +- #define UNICAM_PUM_UNPACK10 4 +- #define UNICAM_PUM_UNPACK12 5 +- #define UNICAM_PUM_UNPACK14 6 +- #define UNICAM_PUM_UNPACK16 7 +-#define UNICAM_DDM_MASK GENMASK(6, 3) +-#define UNICAM_PPM_MASK GENMASK(9, 7) +- /* Packing modes */ +- #define UNICAM_PPM_NONE 0 +- #define UNICAM_PPM_PACK8 1 +- #define UNICAM_PPM_PACK10 2 +- #define UNICAM_PPM_PACK12 3 +- #define UNICAM_PPM_PACK14 4 +- #define UNICAM_PPM_PACK16 5 +-#define UNICAM_DEM_MASK GENMASK(11, 10) +-#define UNICAM_DEBL_MASK GENMASK(14, 12) +-#define UNICAM_ICM_MASK GENMASK(16, 15) +-#define UNICAM_IDM_MASK GENMASK(17, 17) +- +-/* UNICAM_ICC Register */ +-#define UNICAM_ICFL_MASK GENMASK(4, 0) +-#define UNICAM_ICFH_MASK GENMASK(9, 5) +-#define UNICAM_ICST_MASK GENMASK(12, 10) +-#define UNICAM_ICLT_MASK GENMASK(15, 13) +-#define UNICAM_ICLL_MASK GENMASK(31, 16) +- +-/* UNICAM_DCS Register */ +-#define UNICAM_DIE BIT(0) +-#define UNICAM_DIM BIT(1) +-#define UNICAM_DBOB BIT(3) +-#define UNICAM_FDE BIT(4) +-#define UNICAM_LDP BIT(5) +-#define UNICAM_EDL_MASK GENMASK(15, 8) +- +-/* UNICAM_DBCTL Register */ +-#define UNICAM_DBEN BIT(0) +-#define UNICAM_BUF0_IE BIT(1) +-#define UNICAM_BUF1_IE BIT(2) +- +-/* UNICAM_CMP[0,1] register */ +-#define UNICAM_PCE BIT(31) +-#define UNICAM_GI BIT(9) +-#define UNICAM_CPH BIT(8) +-#define UNICAM_PCVC_MASK GENMASK(7, 6) +-#define UNICAM_PCDT_MASK GENMASK(5, 0) +- +-/* UNICAM_MISC register */ +-#define UNICAM_FL0 BIT(6) +-#define UNICAM_FL1 BIT(9) +- +-#endif diff --git a/target/linux/bcm27xx/patches-5.4/950-0805-include-media-Add-vfl_devnode_type-of-VFL_TYPE_VIDEO.patch b/target/linux/bcm27xx/patches-5.4/950-0805-include-media-Add-vfl_devnode_type-of-VFL_TYPE_VIDEO.patch new file mode 100644 index 0000000000..acd3034d21 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0805-include-media-Add-vfl_devnode_type-of-VFL_TYPE_VIDEO.patch @@ -0,0 +1,25 @@ +From 7c74b86873fd5252becee33d092d8317ceff5f5b Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 23 Jun 2020 10:35:24 +0100 +Subject: [PATCH] include: media: Add vfl_devnode_type of + VFL_TYPE_VIDEO + +Upsstream are renaming VFL_TYPE_GRABBER to VFL_TYPE_VIDEO. +To make backporting the upstream Unicam driver easier, add an +extra enum entry (same as VFL_TYPE_GRABBER) to match that. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + include/media/v4l2-dev.h | 1 + + 1 file changed, 1 insertion(+) + +--- a/include/media/v4l2-dev.h ++++ b/include/media/v4l2-dev.h +@@ -34,6 +34,7 @@ + */ + enum vfl_devnode_type { + VFL_TYPE_GRABBER = 0, ++ VFL_TYPE_VIDEO = VFL_TYPE_GRABBER, + VFL_TYPE_VBI, + VFL_TYPE_RADIO, + VFL_TYPE_SUBDEV, diff --git a/target/linux/bcm27xx/patches-5.4/950-0806-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch b/target/linux/bcm27xx/patches-5.4/950-0806-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch new file mode 100644 index 0000000000..561b1fda30 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0806-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch @@ -0,0 +1,3150 @@ +From c339b677f34884fdbe0e6bcdda6d59b7ae30d118 Mon Sep 17 00:00:00 2001 +From: Naushir Patuck <naush@raspberrypi.com> +Date: Mon, 4 May 2020 12:25:41 +0300 +Subject: [PATCH] media: bcm2835-unicam: Driver for CCP2/CSI2 camera + interface + +Add a driver for the Unicam camera receiver block on BCM283x processors. +Compared to the bcm2835-camera driver present in staging, this driver +handles the Unicam block only (CSI-2 receiver), and doesn't depend on +the VC4 firmware running on the VPU. + +The commit is made up of a series of changes cherry-picked from the +rpi-5.4.y branch of https://github.com/raspberrypi/linux/ with +additional enhancements, forward-ported to the mainline kernel. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +Signed-off-by: Naushir Patuck <naush@raspberrypi.com> +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Reported-by: kbuild test robot <lkp@intel.com> +--- + MAINTAINERS | 2 +- + drivers/media/platform/bcm2835/Kconfig | 15 + + drivers/media/platform/bcm2835/Makefile | 3 + + .../media/platform/bcm2835/bcm2835-unicam.c | 2825 +++++++++++++++++ + .../media/platform/bcm2835/vc4-regs-unicam.h | 253 ++ + 5 files changed, 3097 insertions(+), 1 deletion(-) + create mode 100644 drivers/media/platform/bcm2835/Kconfig + create mode 100644 drivers/media/platform/bcm2835/Makefile + create mode 100644 drivers/media/platform/bcm2835/bcm2835-unicam.c + create mode 100644 drivers/media/platform/bcm2835/vc4-regs-unicam.h + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -3210,7 +3210,7 @@ M: Raspberry Pi Kernel Maintenance <kern + L: linux-media@vger.kernel.org + S: Maintained + F: drivers/media/platform/bcm2835/ +-F: Documentation/devicetree/bindings/media/bcm2835-unicam.txt ++F: Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml + + BROADCOM BCM2835 ISP DRIVER + M: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com> +--- /dev/null ++++ b/drivers/media/platform/bcm2835/Kconfig +@@ -0,0 +1,15 @@ ++# Broadcom VideoCore4 V4L2 camera support ++ ++config VIDEO_BCM2835_UNICAM ++ tristate "Broadcom BCM2835 Unicam video capture driver" ++ depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER ++ depends on ARCH_BCM2835 || COMPILE_TEST ++ select VIDEOBUF2_DMA_CONTIG ++ select V4L2_FWNODE ++ help ++ Say Y here to enable support for the BCM2835 CSI-2 receiver. This is a ++ V4L2 driver that controls the CSI-2 receiver directly, independently ++ from the VC4 firmware. ++ ++ To compile this driver as a module, choose M here. The module will be ++ called bcm2835-unicam. +--- /dev/null ++++ b/drivers/media/platform/bcm2835/Makefile +@@ -0,0 +1,3 @@ ++# Makefile for BCM2835 Unicam driver ++ ++obj-$(CONFIG_VIDEO_BCM2835_UNICAM) += bcm2835-unicam.o +--- /dev/null ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -0,0 +1,2825 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * BCM2835 Unicam Capture Driver ++ * ++ * Copyright (C) 2017-2020 - Raspberry Pi (Trading) Ltd. ++ * ++ * Dave Stevenson <dave.stevenson@raspberrypi.com> ++ * ++ * Based on TI am437x driver by ++ * Benoit Parrot <bparrot@ti.com> ++ * Lad, Prabhakar <prabhakar.csengg@gmail.com> ++ * ++ * and TI CAL camera interface driver by ++ * Benoit Parrot <bparrot@ti.com> ++ * ++ * ++ * There are two camera drivers in the kernel for BCM283x - this one ++ * and bcm2835-camera (currently in staging). ++ * ++ * This driver directly controls the Unicam peripheral - there is no ++ * involvement with the VideoCore firmware. Unicam receives CSI-2 or ++ * CCP2 data and writes it into SDRAM. ++ * The only potential processing options are to repack Bayer data into an ++ * alternate format, and applying windowing. ++ * The repacking does not shift the data, so can repack V4L2_PIX_FMT_Sxxxx10P ++ * to V4L2_PIX_FMT_Sxxxx10, or V4L2_PIX_FMT_Sxxxx12P to V4L2_PIX_FMT_Sxxxx12, ++ * but not generically up to V4L2_PIX_FMT_Sxxxx16. The driver will add both ++ * formats where the relevant formats are defined, and will automatically ++ * configure the repacking as required. ++ * Support for windowing may be added later. ++ * ++ * It should be possible to connect this driver to any sensor with a ++ * suitable output interface and V4L2 subdevice driver. ++ * ++ * bcm2835-camera uses the VideoCore firmware to control the sensor, ++ * Unicam, ISP, and all tuner control loops. Fully processed frames are ++ * delivered to the driver by the firmware. It only has sensor drivers ++ * for Omnivision OV5647, and Sony IMX219 sensors. ++ * ++ * The two drivers are mutually exclusive for the same Unicam instance. ++ * The VideoCore firmware checks the device tree configuration during boot. ++ * If it finds device tree nodes called csi0 or csi1 it will block the ++ * firmware from accessing the peripheral, and bcm2835-camera will ++ * not be able to stream data. ++ */ ++ ++#include <linux/clk.h> ++#include <linux/delay.h> ++#include <linux/device.h> ++#include <linux/dma-mapping.h> ++#include <linux/err.h> ++#include <linux/init.h> ++#include <linux/interrupt.h> ++#include <linux/io.h> ++#include <linux/module.h> ++#include <linux/of_device.h> ++#include <linux/of_graph.h> ++#include <linux/pinctrl/consumer.h> ++#include <linux/platform_device.h> ++#include <linux/pm_runtime.h> ++#include <linux/slab.h> ++#include <linux/uaccess.h> ++#include <linux/videodev2.h> ++ ++#include <media/v4l2-common.h> ++#include <media/v4l2-ctrls.h> ++#include <media/v4l2-dev.h> ++#include <media/v4l2-device.h> ++#include <media/v4l2-dv-timings.h> ++#include <media/v4l2-event.h> ++#include <media/v4l2-ioctl.h> ++#include <media/v4l2-fwnode.h> ++#include <media/videobuf2-dma-contig.h> ++ ++#include "vc4-regs-unicam.h" ++ ++#define UNICAM_MODULE_NAME "unicam" ++#define UNICAM_VERSION "0.1.0" ++ ++static int debug; ++module_param(debug, int, 0644); ++MODULE_PARM_DESC(debug, "Debug level 0-3"); ++ ++#define unicam_dbg(level, dev, fmt, arg...) \ ++ v4l2_dbg(level, debug, &(dev)->v4l2_dev, fmt, ##arg) ++#define unicam_info(dev, fmt, arg...) \ ++ v4l2_info(&(dev)->v4l2_dev, fmt, ##arg) ++#define unicam_err(dev, fmt, arg...) \ ++ v4l2_err(&(dev)->v4l2_dev, fmt, ##arg) ++ ++/* ++ * To protect against a dodgy sensor driver never returning an error from ++ * enum_mbus_code, set a maximum index value to be used. ++ */ ++#define MAX_ENUM_MBUS_CODE 128 ++ ++/* ++ * Stride is a 16 bit register, but also has to be a multiple of 32. ++ */ ++#define BPL_ALIGNMENT 32 ++#define MAX_BYTESPERLINE ((1 << 16) - BPL_ALIGNMENT) ++/* ++ * Max width is therefore determined by the max stride divided by ++ * the number of bits per pixel. Take 32bpp as a ++ * worst case. ++ * No imposed limit on the height, so adopt a square image for want ++ * of anything better. ++ */ ++#define MAX_WIDTH (MAX_BYTESPERLINE / 4) ++#define MAX_HEIGHT MAX_WIDTH ++/* Define a nominal minimum image size */ ++#define MIN_WIDTH 16 ++#define MIN_HEIGHT 16 ++/* Default size of the embedded buffer */ ++#define UNICAM_EMBEDDED_SIZE 8192 ++ ++/* ++ * Size of the dummy buffer. Can be any size really, but the DMA ++ * allocation works in units of page sizes. ++ */ ++#define DUMMY_BUF_SIZE (PAGE_SIZE) ++ ++enum pad_types { ++ IMAGE_PAD, ++ METADATA_PAD, ++ MAX_NODES ++}; ++ ++/* ++ * struct unicam_fmt - Unicam media bus format information ++ * @pixelformat: V4L2 pixel format FCC identifier. 0 if n/a. ++ * @repacked_fourcc: V4L2 pixel format FCC identifier if the data is expanded ++ * out to 16bpp. 0 if n/a. ++ * @code: V4L2 media bus format code. ++ * @depth: Bits per pixel as delivered from the source. ++ * @csi_dt: CSI data type. ++ * @check_variants: Flag to denote that there are multiple mediabus formats ++ * still in the list that could match this V4L2 format. ++ */ ++struct unicam_fmt { ++ u32 fourcc; ++ u32 repacked_fourcc; ++ u32 code; ++ u8 depth; ++ u8 csi_dt; ++ u8 check_variants; ++}; ++ ++static const struct unicam_fmt formats[] = { ++ /* YUV Formats */ ++ { ++ .fourcc = V4L2_PIX_FMT_YUYV, ++ .code = MEDIA_BUS_FMT_YUYV8_2X8, ++ .depth = 16, ++ .csi_dt = 0x1e, ++ .check_variants = 1, ++ }, { ++ .fourcc = V4L2_PIX_FMT_UYVY, ++ .code = MEDIA_BUS_FMT_UYVY8_2X8, ++ .depth = 16, ++ .csi_dt = 0x1e, ++ .check_variants = 1, ++ }, { ++ .fourcc = V4L2_PIX_FMT_YVYU, ++ .code = MEDIA_BUS_FMT_YVYU8_2X8, ++ .depth = 16, ++ .csi_dt = 0x1e, ++ .check_variants = 1, ++ }, { ++ .fourcc = V4L2_PIX_FMT_VYUY, ++ .code = MEDIA_BUS_FMT_VYUY8_2X8, ++ .depth = 16, ++ .csi_dt = 0x1e, ++ .check_variants = 1, ++ }, { ++ .fourcc = V4L2_PIX_FMT_YUYV, ++ .code = MEDIA_BUS_FMT_YUYV8_1X16, ++ .depth = 16, ++ .csi_dt = 0x1e, ++ }, { ++ .fourcc = V4L2_PIX_FMT_UYVY, ++ .code = MEDIA_BUS_FMT_UYVY8_1X16, ++ .depth = 16, ++ .csi_dt = 0x1e, ++ }, { ++ .fourcc = V4L2_PIX_FMT_YVYU, ++ .code = MEDIA_BUS_FMT_YVYU8_1X16, ++ .depth = 16, ++ .csi_dt = 0x1e, ++ }, { ++ .fourcc = V4L2_PIX_FMT_VYUY, ++ .code = MEDIA_BUS_FMT_VYUY8_1X16, ++ .depth = 16, ++ .csi_dt = 0x1e, ++ }, { ++ /* RGB Formats */ ++ .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ ++ .code = MEDIA_BUS_FMT_RGB565_2X8_LE, ++ .depth = 16, ++ .csi_dt = 0x22, ++ }, { ++ .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */ ++ .code = MEDIA_BUS_FMT_RGB565_2X8_BE, ++ .depth = 16, ++ .csi_dt = 0x22 ++ }, { ++ .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */ ++ .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, ++ .depth = 16, ++ .csi_dt = 0x21, ++ }, { ++ .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */ ++ .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, ++ .depth = 16, ++ .csi_dt = 0x21, ++ }, { ++ .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */ ++ .code = MEDIA_BUS_FMT_RGB888_1X24, ++ .depth = 24, ++ .csi_dt = 0x24, ++ }, { ++ .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */ ++ .code = MEDIA_BUS_FMT_BGR888_1X24, ++ .depth = 24, ++ .csi_dt = 0x24, ++ }, { ++ .fourcc = V4L2_PIX_FMT_RGB32, /* argb */ ++ .code = MEDIA_BUS_FMT_ARGB8888_1X32, ++ .depth = 32, ++ .csi_dt = 0x0, ++ }, { ++ /* Bayer Formats */ ++ .fourcc = V4L2_PIX_FMT_SBGGR8, ++ .code = MEDIA_BUS_FMT_SBGGR8_1X8, ++ .depth = 8, ++ .csi_dt = 0x2a, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGBRG8, ++ .code = MEDIA_BUS_FMT_SGBRG8_1X8, ++ .depth = 8, ++ .csi_dt = 0x2a, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGRBG8, ++ .code = MEDIA_BUS_FMT_SGRBG8_1X8, ++ .depth = 8, ++ .csi_dt = 0x2a, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SRGGB8, ++ .code = MEDIA_BUS_FMT_SRGGB8_1X8, ++ .depth = 8, ++ .csi_dt = 0x2a, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SBGGR10P, ++ .repacked_fourcc = V4L2_PIX_FMT_SBGGR10, ++ .code = MEDIA_BUS_FMT_SBGGR10_1X10, ++ .depth = 10, ++ .csi_dt = 0x2b, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGBRG10P, ++ .repacked_fourcc = V4L2_PIX_FMT_SGBRG10, ++ .code = MEDIA_BUS_FMT_SGBRG10_1X10, ++ .depth = 10, ++ .csi_dt = 0x2b, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGRBG10P, ++ .repacked_fourcc = V4L2_PIX_FMT_SGRBG10, ++ .code = MEDIA_BUS_FMT_SGRBG10_1X10, ++ .depth = 10, ++ .csi_dt = 0x2b, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SRGGB10P, ++ .repacked_fourcc = V4L2_PIX_FMT_SRGGB10, ++ .code = MEDIA_BUS_FMT_SRGGB10_1X10, ++ .depth = 10, ++ .csi_dt = 0x2b, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SBGGR12P, ++ .repacked_fourcc = V4L2_PIX_FMT_SBGGR12, ++ .code = MEDIA_BUS_FMT_SBGGR12_1X12, ++ .depth = 12, ++ .csi_dt = 0x2c, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGBRG12P, ++ .repacked_fourcc = V4L2_PIX_FMT_SGBRG12, ++ .code = MEDIA_BUS_FMT_SGBRG12_1X12, ++ .depth = 12, ++ .csi_dt = 0x2c, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGRBG12P, ++ .repacked_fourcc = V4L2_PIX_FMT_SGRBG12, ++ .code = MEDIA_BUS_FMT_SGRBG12_1X12, ++ .depth = 12, ++ .csi_dt = 0x2c, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SRGGB12P, ++ .repacked_fourcc = V4L2_PIX_FMT_SRGGB12, ++ .code = MEDIA_BUS_FMT_SRGGB12_1X12, ++ .depth = 12, ++ .csi_dt = 0x2c, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SBGGR14P, ++ .code = MEDIA_BUS_FMT_SBGGR14_1X14, ++ .depth = 14, ++ .csi_dt = 0x2d, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGBRG14P, ++ .code = MEDIA_BUS_FMT_SGBRG14_1X14, ++ .depth = 14, ++ .csi_dt = 0x2d, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGRBG14P, ++ .code = MEDIA_BUS_FMT_SGRBG14_1X14, ++ .depth = 14, ++ .csi_dt = 0x2d, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SRGGB14P, ++ .code = MEDIA_BUS_FMT_SRGGB14_1X14, ++ .depth = 14, ++ .csi_dt = 0x2d, ++ }, { ++ /* ++ * 16 bit Bayer formats could be supported, but there is no CSI2 ++ * data_type defined for raw 16, and no sensors that produce it at ++ * present. ++ */ ++ ++ /* Greyscale formats */ ++ .fourcc = V4L2_PIX_FMT_GREY, ++ .code = MEDIA_BUS_FMT_Y8_1X8, ++ .depth = 8, ++ .csi_dt = 0x2a, ++ }, { ++ .fourcc = V4L2_PIX_FMT_Y10P, ++ .repacked_fourcc = V4L2_PIX_FMT_Y10, ++ .code = MEDIA_BUS_FMT_Y10_1X10, ++ .depth = 10, ++ .csi_dt = 0x2b, ++ }, { ++ /* NB There is no packed V4L2 fourcc for this format. */ ++ .repacked_fourcc = V4L2_PIX_FMT_Y12, ++ .code = MEDIA_BUS_FMT_Y12_1X12, ++ .depth = 12, ++ .csi_dt = 0x2c, ++ }, ++ /* Embedded data format */ ++ { ++ .fourcc = V4L2_META_FMT_SENSOR_DATA, ++ .code = MEDIA_BUS_FMT_SENSOR_DATA, ++ .depth = 8, ++ } ++}; ++ ++struct unicam_buffer { ++ struct vb2_v4l2_buffer vb; ++ struct list_head list; ++}; ++ ++static inline struct unicam_buffer *to_unicam_buffer(struct vb2_buffer *vb) ++{ ++ return container_of(vb, struct unicam_buffer, vb.vb2_buf); ++} ++ ++struct unicam_node { ++ bool registered; ++ int open; ++ bool streaming; ++ unsigned int pad_id; ++ /* Pointer pointing to current v4l2_buffer */ ++ struct unicam_buffer *cur_frm; ++ /* Pointer pointing to next v4l2_buffer */ ++ struct unicam_buffer *next_frm; ++ /* video capture */ ++ const struct unicam_fmt *fmt; ++ /* Used to store current pixel format */ ++ struct v4l2_format v_fmt; ++ /* Used to store current mbus frame format */ ++ struct v4l2_mbus_framefmt m_fmt; ++ /* Buffer queue used in video-buf */ ++ struct vb2_queue buffer_queue; ++ /* Queue of filled frames */ ++ struct list_head dma_queue; ++ /* IRQ lock for DMA queue */ ++ spinlock_t dma_queue_lock; ++ /* lock used to access this structure */ ++ struct mutex lock; ++ /* Identifies video device for this channel */ ++ struct video_device video_dev; ++ /* Pointer to the parent handle */ ++ struct unicam_device *dev; ++ struct media_pad pad; ++ unsigned int embedded_lines; ++ /* ++ * Dummy buffer intended to be used by unicam ++ * if we have no other queued buffers to swap to. ++ */ ++ void *dummy_buf_cpu_addr; ++ dma_addr_t dummy_buf_dma_addr; ++}; ++ ++struct unicam_device { ++ struct kref kref; ++ ++ /* V4l2 specific parameters */ ++ struct v4l2_async_subdev asd; ++ ++ /* peripheral base address */ ++ void __iomem *base; ++ /* clock gating base address */ ++ void __iomem *clk_gate_base; ++ /* clock handle */ ++ struct clk *clock; ++ /* V4l2 device */ ++ struct v4l2_device v4l2_dev; ++ struct media_device mdev; ++ ++ /* parent device */ ++ struct platform_device *pdev; ++ /* subdevice async Notifier */ ++ struct v4l2_async_notifier notifier; ++ unsigned int sequence; ++ ++ /* ptr to sub device */ ++ struct v4l2_subdev *sensor; ++ /* Pad config for the sensor */ ++ struct v4l2_subdev_pad_config *sensor_config; ++ ++ enum v4l2_mbus_type bus_type; ++ /* ++ * Stores bus.mipi_csi2.flags for CSI2 sensors, or ++ * bus.mipi_csi1.strobe for CCP2. ++ */ ++ unsigned int bus_flags; ++ unsigned int max_data_lanes; ++ unsigned int active_data_lanes; ++ bool sensor_embedded_data; ++ ++ struct unicam_node node[MAX_NODES]; ++ struct v4l2_ctrl_handler ctrl_handler; ++}; ++ ++static inline struct unicam_device * ++to_unicam_device(struct v4l2_device *v4l2_dev) ++{ ++ return container_of(v4l2_dev, struct unicam_device, v4l2_dev); ++} ++ ++/* Hardware access */ ++static inline void clk_write(struct unicam_device *dev, u32 val) ++{ ++ writel(val | 0x5a000000, dev->clk_gate_base); ++} ++ ++static inline u32 reg_read(struct unicam_device *dev, u32 offset) ++{ ++ return readl(dev->base + offset); ++} ++ ++static inline void reg_write(struct unicam_device *dev, u32 offset, u32 val) ++{ ++ writel(val, dev->base + offset); ++} ++ ++static inline int get_field(u32 value, u32 mask) ++{ ++ return (value & mask) >> __ffs(mask); ++} ++ ++static inline void set_field(u32 *valp, u32 field, u32 mask) ++{ ++ u32 val = *valp; ++ ++ val &= ~mask; ++ val |= (field << __ffs(mask)) & mask; ++ *valp = val; ++} ++ ++static inline u32 reg_read_field(struct unicam_device *dev, u32 offset, ++ u32 mask) ++{ ++ return get_field(reg_read(dev, offset), mask); ++} ++ ++static inline void reg_write_field(struct unicam_device *dev, u32 offset, ++ u32 field, u32 mask) ++{ ++ u32 val = reg_read(dev, offset); ++ ++ set_field(&val, field, mask); ++ reg_write(dev, offset, val); ++} ++ ++/* Power management functions */ ++static inline int unicam_runtime_get(struct unicam_device *dev) ++{ ++ return pm_runtime_get_sync(&dev->pdev->dev); ++} ++ ++static inline void unicam_runtime_put(struct unicam_device *dev) ++{ ++ pm_runtime_put_sync(&dev->pdev->dev); ++} ++ ++/* Format setup functions */ ++static const struct unicam_fmt *find_format_by_code(u32 code) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(formats); i++) { ++ if (formats[i].code == code) ++ return &formats[i]; ++ } ++ ++ return NULL; ++} ++ ++static int check_mbus_format(struct unicam_device *dev, ++ const struct unicam_fmt *format) ++{ ++ unsigned int i; ++ int ret = 0; ++ ++ for (i = 0; !ret && i < MAX_ENUM_MBUS_CODE; i++) { ++ struct v4l2_subdev_mbus_code_enum mbus_code = { ++ .index = i, ++ .pad = IMAGE_PAD, ++ .which = V4L2_SUBDEV_FORMAT_ACTIVE, ++ }; ++ ++ ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, ++ NULL, &mbus_code); ++ ++ if (!ret && mbus_code.code == format->code) ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static const struct unicam_fmt *find_format_by_pix(struct unicam_device *dev, ++ u32 pixelformat) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(formats); i++) { ++ if (formats[i].fourcc == pixelformat || ++ formats[i].repacked_fourcc == pixelformat) { ++ if (formats[i].check_variants && ++ !check_mbus_format(dev, &formats[i])) ++ continue; ++ return &formats[i]; ++ } ++ } ++ ++ return NULL; ++} ++ ++static inline unsigned int bytes_per_line(u32 width, ++ const struct unicam_fmt *fmt, ++ u32 v4l2_fourcc) ++{ ++ if (v4l2_fourcc == fmt->repacked_fourcc) ++ /* Repacking always goes to 16bpp */ ++ return ALIGN(width << 1, BPL_ALIGNMENT); ++ else ++ return ALIGN((width * fmt->depth) >> 3, BPL_ALIGNMENT); ++} ++ ++static int __subdev_get_format(struct unicam_device *dev, ++ struct v4l2_mbus_framefmt *fmt, int pad_id) ++{ ++ struct v4l2_subdev_format sd_fmt = { ++ .which = V4L2_SUBDEV_FORMAT_ACTIVE, ++ .pad = pad_id ++ }; ++ int ret; ++ ++ ret = v4l2_subdev_call(dev->sensor, pad, get_fmt, dev->sensor_config, ++ &sd_fmt); ++ if (ret < 0) ++ return ret; ++ ++ *fmt = sd_fmt.format; ++ ++ unicam_dbg(1, dev, "%s %dx%d code:%04x\n", __func__, ++ fmt->width, fmt->height, fmt->code); ++ ++ return 0; ++} ++ ++static int __subdev_set_format(struct unicam_device *dev, ++ struct v4l2_mbus_framefmt *fmt, int pad_id) ++{ ++ struct v4l2_subdev_format sd_fmt = { ++ .which = V4L2_SUBDEV_FORMAT_ACTIVE, ++ .pad = pad_id ++ }; ++ int ret; ++ ++ sd_fmt.format = *fmt; ++ ++ ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, dev->sensor_config, ++ &sd_fmt); ++ if (ret < 0) ++ return ret; ++ ++ *fmt = sd_fmt.format; ++ ++ if (pad_id == IMAGE_PAD) ++ unicam_dbg(1, dev, "%s %dx%d code:%04x\n", __func__, fmt->width, ++ fmt->height, fmt->code); ++ else ++ unicam_dbg(1, dev, "%s Embedded data code:%04x\n", __func__, ++ sd_fmt.format.code); ++ ++ return 0; ++} ++ ++static int unicam_calc_format_size_bpl(struct unicam_device *dev, ++ const struct unicam_fmt *fmt, ++ struct v4l2_format *f) ++{ ++ unsigned int min_bytesperline; ++ ++ v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, MAX_WIDTH, 2, ++ &f->fmt.pix.height, MIN_HEIGHT, MAX_HEIGHT, 0, ++ 0); ++ ++ min_bytesperline = bytes_per_line(f->fmt.pix.width, fmt, ++ f->fmt.pix.pixelformat); ++ ++ if (f->fmt.pix.bytesperline > min_bytesperline && ++ f->fmt.pix.bytesperline <= MAX_BYTESPERLINE) ++ f->fmt.pix.bytesperline = ALIGN(f->fmt.pix.bytesperline, ++ BPL_ALIGNMENT); ++ else ++ f->fmt.pix.bytesperline = min_bytesperline; ++ ++ f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; ++ ++ unicam_dbg(3, dev, "%s: fourcc: %08X size: %dx%d bpl:%d img_size:%d\n", ++ __func__, ++ f->fmt.pix.pixelformat, ++ f->fmt.pix.width, f->fmt.pix.height, ++ f->fmt.pix.bytesperline, f->fmt.pix.sizeimage); ++ ++ return 0; ++} ++ ++static int unicam_reset_format(struct unicam_node *node) ++{ ++ struct unicam_device *dev = node->dev; ++ struct v4l2_mbus_framefmt mbus_fmt; ++ int ret; ++ ++ if (dev->sensor_embedded_data || node->pad_id != METADATA_PAD) { ++ ret = __subdev_get_format(dev, &mbus_fmt, node->pad_id); ++ if (ret) { ++ unicam_err(dev, "Failed to get_format - ret %d\n", ret); ++ return ret; ++ } ++ ++ if (mbus_fmt.code != node->fmt->code) { ++ unicam_err(dev, "code mismatch - fmt->code %08x, mbus_fmt.code %08x\n", ++ node->fmt->code, mbus_fmt.code); ++ return ret; ++ } ++ } ++ ++ if (node->pad_id == IMAGE_PAD) { ++ v4l2_fill_pix_format(&node->v_fmt.fmt.pix, &mbus_fmt); ++ node->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ++ unicam_calc_format_size_bpl(dev, node->fmt, &node->v_fmt); ++ } else { ++ node->v_fmt.type = V4L2_BUF_TYPE_META_CAPTURE; ++ node->v_fmt.fmt.meta.dataformat = V4L2_META_FMT_SENSOR_DATA; ++ if (dev->sensor_embedded_data) { ++ node->v_fmt.fmt.meta.buffersize = ++ mbus_fmt.width * mbus_fmt.height; ++ node->embedded_lines = mbus_fmt.height; ++ } else { ++ node->v_fmt.fmt.meta.buffersize = UNICAM_EMBEDDED_SIZE; ++ node->embedded_lines = 1; ++ } ++ } ++ ++ node->m_fmt = mbus_fmt; ++ return 0; ++} ++ ++static void unicam_wr_dma_addr(struct unicam_device *dev, dma_addr_t dmaaddr, ++ unsigned int buffer_size, int pad_id) ++{ ++ dma_addr_t endaddr = dmaaddr + buffer_size; ++ ++ /* ++ * dmaaddr and endaddr should be a 32-bit address with the top two bits ++ * set to 0x3 to signify uncached access through the Videocore memory ++ * controller. ++ */ ++ WARN_ON((dmaaddr >> 30) != 0x3 || (endaddr >> 30) != 0x3); ++ ++ if (pad_id == IMAGE_PAD) { ++ reg_write(dev, UNICAM_IBSA0, dmaaddr); ++ reg_write(dev, UNICAM_IBEA0, endaddr); ++ } else { ++ reg_write(dev, UNICAM_DBSA0, dmaaddr); ++ reg_write(dev, UNICAM_DBEA0, endaddr); ++ } ++} ++ ++static inline unsigned int unicam_get_lines_done(struct unicam_device *dev) ++{ ++ dma_addr_t start_addr, cur_addr; ++ unsigned int stride = dev->node[IMAGE_PAD].v_fmt.fmt.pix.bytesperline; ++ struct unicam_buffer *frm = dev->node[IMAGE_PAD].cur_frm; ++ ++ if (!frm) ++ return 0; ++ ++ start_addr = vb2_dma_contig_plane_dma_addr(&frm->vb.vb2_buf, 0); ++ cur_addr = reg_read(dev, UNICAM_IBWP); ++ return (unsigned int)(cur_addr - start_addr) / stride; ++} ++ ++static inline void unicam_schedule_next_buffer(struct unicam_node *node) ++{ ++ struct unicam_device *dev = node->dev; ++ struct unicam_buffer *buf; ++ unsigned int size; ++ dma_addr_t addr; ++ ++ buf = list_first_entry(&node->dma_queue, struct unicam_buffer, list); ++ node->next_frm = buf; ++ list_del(&buf->list); ++ ++ addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0); ++ size = (node->pad_id == IMAGE_PAD) ? ++ node->v_fmt.fmt.pix.sizeimage : ++ node->v_fmt.fmt.meta.buffersize; ++ ++ unicam_wr_dma_addr(dev, addr, size, node->pad_id); ++} ++ ++static inline void unicam_schedule_dummy_buffer(struct unicam_node *node) ++{ ++ struct unicam_device *dev = node->dev; ++ ++ unicam_dbg(3, dev, "Scheduling dummy buffer for node %d\n", ++ node->pad_id); ++ ++ unicam_wr_dma_addr(dev, node->dummy_buf_dma_addr, DUMMY_BUF_SIZE, ++ node->pad_id); ++ node->next_frm = NULL; ++} ++ ++static inline void unicam_process_buffer_complete(struct unicam_node *node, ++ unsigned int sequence) ++{ ++ node->cur_frm->vb.field = node->m_fmt.field; ++ node->cur_frm->vb.sequence = sequence; ++ ++ vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE); ++} ++ ++static bool unicam_all_nodes_streaming(struct unicam_device *dev) ++{ ++ bool ret; ++ ++ ret = dev->node[IMAGE_PAD].open && dev->node[IMAGE_PAD].streaming; ++ ret &= !dev->node[METADATA_PAD].open || ++ dev->node[METADATA_PAD].streaming; ++ return ret; ++} ++ ++static bool unicam_all_nodes_disabled(struct unicam_device *dev) ++{ ++ return !dev->node[IMAGE_PAD].streaming && ++ !dev->node[METADATA_PAD].streaming; ++} ++ ++static void unicam_queue_event_sof(struct unicam_device *unicam) ++{ ++ struct v4l2_event event = { ++ .type = V4L2_EVENT_FRAME_SYNC, ++ .u.frame_sync.frame_sequence = unicam->sequence, ++ }; ++ ++ v4l2_event_queue(&unicam->node[IMAGE_PAD].video_dev, &event); ++} ++ ++/* ++ * unicam_isr : ISR handler for unicam capture ++ * @irq: irq number ++ * @dev_id: dev_id ptr ++ * ++ * It changes status of the captured buffer, takes next buffer from the queue ++ * and sets its address in unicam registers ++ */ ++static irqreturn_t unicam_isr(int irq, void *dev) ++{ ++ struct unicam_device *unicam = dev; ++ unsigned int lines_done = unicam_get_lines_done(dev); ++ unsigned int sequence = unicam->sequence; ++ unsigned int i; ++ u32 ista, sta; ++ u64 ts; ++ ++ /* ++ * Don't service interrupts if not streaming. ++ * Avoids issues if the VPU should enable the ++ * peripheral without the kernel knowing (that ++ * shouldn't happen, but causes issues if it does). ++ */ ++ if (unicam_all_nodes_disabled(unicam)) ++ return IRQ_NONE; ++ ++ sta = reg_read(unicam, UNICAM_STA); ++ /* Write value back to clear the interrupts */ ++ reg_write(unicam, UNICAM_STA, sta); ++ ++ ista = reg_read(unicam, UNICAM_ISTA); ++ /* Write value back to clear the interrupts */ ++ reg_write(unicam, UNICAM_ISTA, ista); ++ ++ unicam_dbg(3, unicam, "ISR: ISTA: 0x%X, STA: 0x%X, sequence %d, lines done %d", ++ ista, sta, sequence, lines_done); ++ ++ if (!(sta & (UNICAM_IS | UNICAM_PI0))) ++ return IRQ_HANDLED; ++ ++ /* ++ * We must run the frame end handler first. If we have a valid next_frm ++ * and we get a simultaneout FE + FS interrupt, running the FS handler ++ * first would null out the next_frm ptr and we would have lost the ++ * buffer forever. ++ */ ++ if (ista & UNICAM_FEI || sta & UNICAM_PI0) { ++ /* ++ * Ensure we have swapped buffers already as we can't ++ * stop the peripheral. If no buffer is available, use a ++ * dummy buffer to dump out frames until we get a new buffer ++ * to use. ++ */ ++ for (i = 0; i < ARRAY_SIZE(unicam->node); i++) { ++ if (!unicam->node[i].streaming) ++ continue; ++ ++ if (unicam->node[i].cur_frm) ++ unicam_process_buffer_complete(&unicam->node[i], ++ sequence); ++ unicam->node[i].cur_frm = unicam->node[i].next_frm; ++ } ++ unicam->sequence++; ++ } ++ ++ if (ista & UNICAM_FSI) { ++ /* ++ * Timestamp is to be when the first data byte was captured, ++ * aka frame start. ++ */ ++ ts = ktime_get_ns(); ++ for (i = 0; i < ARRAY_SIZE(unicam->node); i++) { ++ if (!unicam->node[i].streaming) ++ continue; ++ ++ if (unicam->node[i].cur_frm) ++ unicam->node[i].cur_frm->vb.vb2_buf.timestamp = ++ ts; ++ /* ++ * Set the next frame output to go to a dummy frame ++ * if we have not managed to obtain another frame ++ * from the queue. ++ */ ++ unicam_schedule_dummy_buffer(&unicam->node[i]); ++ } ++ ++ unicam_queue_event_sof(unicam); ++ } ++ ++ /* ++ * Cannot swap buffer at frame end, there may be a race condition ++ * where the HW does not actually swap it if the new frame has ++ * already started. ++ */ ++ if (ista & (UNICAM_FSI | UNICAM_LCI) && !(ista & UNICAM_FEI)) { ++ for (i = 0; i < ARRAY_SIZE(unicam->node); i++) { ++ if (!unicam->node[i].streaming) ++ continue; ++ ++ spin_lock(&unicam->node[i].dma_queue_lock); ++ if (!list_empty(&unicam->node[i].dma_queue) && ++ !unicam->node[i].next_frm) ++ unicam_schedule_next_buffer(&unicam->node[i]); ++ spin_unlock(&unicam->node[i].dma_queue_lock); ++ } ++ } ++ ++ if (reg_read(unicam, UNICAM_ICTL) & UNICAM_FCM) { ++ /* Switch out of trigger mode if selected */ ++ reg_write_field(unicam, UNICAM_ICTL, 1, UNICAM_TFC); ++ reg_write_field(unicam, UNICAM_ICTL, 0, UNICAM_FCM); ++ } ++ return IRQ_HANDLED; ++} ++ ++static int unicam_querycap(struct file *file, void *priv, ++ struct v4l2_capability *cap) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ ++ strlcpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver)); ++ strlcpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card)); ++ ++ snprintf(cap->bus_info, sizeof(cap->bus_info), ++ "platform:%s", dev_name(&dev->pdev->dev)); ++ ++ cap->capabilities |= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_META_CAPTURE; ++ ++ return 0; ++} ++ ++static int unicam_enum_fmt_vid_cap(struct file *file, void *priv, ++ struct v4l2_fmtdesc *f) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ unsigned int index = 0; ++ unsigned int i; ++ int ret = 0; ++ ++ if (node->pad_id != IMAGE_PAD) ++ return -EINVAL; ++ ++ for (i = 0; !ret && i < MAX_ENUM_MBUS_CODE; i++) { ++ struct v4l2_subdev_mbus_code_enum mbus_code = { ++ .index = i, ++ .pad = IMAGE_PAD, ++ .which = V4L2_SUBDEV_FORMAT_ACTIVE, ++ }; ++ const struct unicam_fmt *fmt; ++ ++ ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, ++ NULL, &mbus_code); ++ if (ret < 0) { ++ unicam_dbg(2, dev, ++ "subdev->enum_mbus_code idx %d returned %d - index invalid\n", ++ i, ret); ++ return -EINVAL; ++ } ++ ++ fmt = find_format_by_code(mbus_code.code); ++ if (fmt) { ++ if (fmt->fourcc) { ++ if (index == f->index) { ++ f->pixelformat = fmt->fourcc; ++ break; ++ } ++ index++; ++ } ++ if (fmt->repacked_fourcc) { ++ if (index == f->index) { ++ f->pixelformat = fmt->repacked_fourcc; ++ break; ++ } ++ index++; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++static int unicam_g_fmt_vid_cap(struct file *file, void *priv, ++ struct v4l2_format *f) ++{ ++ struct v4l2_mbus_framefmt mbus_fmt = {0}; ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ const struct unicam_fmt *fmt = NULL; ++ int ret; ++ ++ if (node->pad_id != IMAGE_PAD) ++ return -EINVAL; ++ ++ /* ++ * If a flip has occurred in the sensor, the fmt code might have ++ * changed. So we will need to re-fetch the format from the subdevice. ++ */ ++ ret = __subdev_get_format(dev, &mbus_fmt, node->pad_id); ++ if (ret) ++ return -EINVAL; ++ ++ /* Find the V4L2 format from mbus code. We must match a known format. */ ++ fmt = find_format_by_code(mbus_fmt.code); ++ if (!fmt) ++ return -EINVAL; ++ ++ node->fmt = fmt; ++ node->v_fmt.fmt.pix.pixelformat = fmt->fourcc; ++ *f = node->v_fmt; ++ ++ return 0; ++} ++ ++static ++const struct unicam_fmt *get_first_supported_format(struct unicam_device *dev) ++{ ++ struct v4l2_subdev_mbus_code_enum mbus_code; ++ const struct unicam_fmt *fmt = NULL; ++ unsigned int i; ++ int ret; ++ ++ for (i = 0; ret != -EINVAL && ret != -ENOIOCTLCMD; ++i) { ++ memset(&mbus_code, 0, sizeof(mbus_code)); ++ mbus_code.index = i; ++ mbus_code.pad = IMAGE_PAD; ++ mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE; ++ ++ ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, NULL, ++ &mbus_code); ++ if (ret < 0) { ++ unicam_dbg(2, dev, ++ "subdev->enum_mbus_code idx %u returned %d - continue\n", ++ i, ret); ++ continue; ++ } ++ ++ unicam_dbg(2, dev, "subdev %s: code: 0x%08x idx: %u\n", ++ dev->sensor->name, mbus_code.code, i); ++ ++ fmt = find_format_by_code(mbus_code.code); ++ unicam_dbg(2, dev, "fmt 0x%08x returned as %p, V4L2 FOURCC 0x%08x, csi_dt 0x%02x\n", ++ mbus_code.code, fmt, fmt ? fmt->fourcc : 0, ++ fmt ? fmt->csi_dt : 0); ++ if (fmt) ++ return fmt; ++ } ++ ++ return NULL; ++} ++ ++static int unicam_try_fmt_vid_cap(struct file *file, void *priv, ++ struct v4l2_format *f) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ struct v4l2_subdev_format sd_fmt = { ++ .which = V4L2_SUBDEV_FORMAT_TRY, ++ .pad = IMAGE_PAD ++ }; ++ struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format; ++ const struct unicam_fmt *fmt; ++ int ret; ++ ++ if (node->pad_id != IMAGE_PAD) ++ return -EINVAL; ++ ++ fmt = find_format_by_pix(dev, f->fmt.pix.pixelformat); ++ if (!fmt) { ++ /* ++ * Pixel format not supported by unicam. Choose the first ++ * supported format, and let the sensor choose something else. ++ */ ++ unicam_dbg(3, dev, "Fourcc format (0x%08x) not found. Use first format.\n", ++ f->fmt.pix.pixelformat); ++ ++ fmt = &formats[0]; ++ f->fmt.pix.pixelformat = fmt->fourcc; ++ } ++ ++ v4l2_fill_mbus_format(mbus_fmt, &f->fmt.pix, fmt->code); ++ /* ++ * No support for receiving interlaced video, so never ++ * request it from the sensor subdev. ++ */ ++ mbus_fmt->field = V4L2_FIELD_NONE; ++ ++ ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, dev->sensor_config, ++ &sd_fmt); ++ if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) ++ return ret; ++ ++ if (mbus_fmt->field != V4L2_FIELD_NONE) ++ unicam_info(dev, "Sensor trying to send interlaced video - results may be unpredictable\n"); ++ ++ v4l2_fill_pix_format(&f->fmt.pix, &sd_fmt.format); ++ if (mbus_fmt->code != fmt->code) { ++ /* Sensor has returned an alternate format */ ++ fmt = find_format_by_code(mbus_fmt->code); ++ if (!fmt) { ++ /* ++ * The alternate format is one unicam can't support. ++ * Find the first format that is supported by both, and ++ * then set that. ++ */ ++ fmt = get_first_supported_format(dev); ++ mbus_fmt->code = fmt->code; ++ ++ ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, ++ dev->sensor_config, &sd_fmt); ++ if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) ++ return ret; ++ ++ if (mbus_fmt->field != V4L2_FIELD_NONE) ++ unicam_info(dev, "Sensor trying to send interlaced video - results may be unpredictable\n"); ++ ++ v4l2_fill_pix_format(&f->fmt.pix, &sd_fmt.format); ++ ++ if (mbus_fmt->code != fmt->code) { ++ /* ++ * We've set a format that the sensor reports ++ * as being supported, but it refuses to set it. ++ * Not much else we can do. ++ * Assume that the sensor driver may accept the ++ * format when it is set (rather than tried). ++ */ ++ unicam_err(dev, "Sensor won't accept default format, and Unicam can't support sensor default\n"); ++ } ++ } ++ ++ if (fmt->fourcc) ++ f->fmt.pix.pixelformat = fmt->fourcc; ++ else ++ f->fmt.pix.pixelformat = fmt->repacked_fourcc; ++ } ++ ++ return unicam_calc_format_size_bpl(dev, fmt, f); ++} ++ ++static int unicam_s_fmt_vid_cap(struct file *file, void *priv, ++ struct v4l2_format *f) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ struct vb2_queue *q = &node->buffer_queue; ++ struct v4l2_mbus_framefmt mbus_fmt = {0}; ++ const struct unicam_fmt *fmt; ++ int ret; ++ ++ if (vb2_is_busy(q)) ++ return -EBUSY; ++ ++ ret = unicam_try_fmt_vid_cap(file, priv, f); ++ if (ret < 0) ++ return ret; ++ ++ fmt = find_format_by_pix(dev, f->fmt.pix.pixelformat); ++ if (!fmt) { ++ /* ++ * Unknown pixel format - adopt a default. ++ * This shouldn't happen as try_fmt should have resolved any ++ * issues first. ++ */ ++ fmt = get_first_supported_format(dev); ++ if (!fmt) ++ /* ++ * It shouldn't be possible to get here with no ++ * supported formats ++ */ ++ return -EINVAL; ++ f->fmt.pix.pixelformat = fmt->fourcc; ++ return -EINVAL; ++ } ++ ++ v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, fmt->code); ++ ++ ret = __subdev_set_format(dev, &mbus_fmt, node->pad_id); ++ if (ret) { ++ unicam_dbg(3, dev, "%s __subdev_set_format failed %d\n", ++ __func__, ret); ++ return ret; ++ } ++ ++ /* Just double check nothing has gone wrong */ ++ if (mbus_fmt.code != fmt->code) { ++ unicam_dbg(3, dev, ++ "%s subdev changed format on us, this should not happen\n", ++ __func__); ++ return -EINVAL; ++ } ++ ++ node->fmt = fmt; ++ node->v_fmt.fmt.pix.pixelformat = f->fmt.pix.pixelformat; ++ node->v_fmt.fmt.pix.bytesperline = f->fmt.pix.bytesperline; ++ unicam_reset_format(node); ++ ++ unicam_dbg(3, dev, ++ "%s %dx%d, mbus_fmt 0x%08X, V4L2 pix 0x%08X.\n", ++ __func__, node->v_fmt.fmt.pix.width, ++ node->v_fmt.fmt.pix.height, mbus_fmt.code, ++ node->v_fmt.fmt.pix.pixelformat); ++ ++ *f = node->v_fmt; ++ ++ return 0; ++} ++ ++static int unicam_enum_fmt_meta_cap(struct file *file, void *priv, ++ struct v4l2_fmtdesc *f) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ const struct unicam_fmt *fmt; ++ u32 code; ++ int ret = 0; ++ ++ if (node->pad_id != METADATA_PAD || f->index != 0) ++ return -EINVAL; ++ ++ if (dev->sensor_embedded_data) { ++ struct v4l2_subdev_mbus_code_enum mbus_code = { ++ .index = f->index, ++ .which = V4L2_SUBDEV_FORMAT_ACTIVE, ++ .pad = METADATA_PAD, ++ }; ++ ++ ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, NULL, ++ &mbus_code); ++ if (ret < 0) { ++ unicam_dbg(2, dev, ++ "subdev->enum_mbus_code idx 0 returned %d - index invalid\n", ++ ret); ++ return -EINVAL; ++ } ++ ++ code = mbus_code.code; ++ } else { ++ code = MEDIA_BUS_FMT_SENSOR_DATA; ++ } ++ ++ fmt = find_format_by_code(code); ++ if (fmt) ++ f->pixelformat = fmt->fourcc; ++ ++ return 0; ++} ++ ++static int unicam_g_fmt_meta_cap(struct file *file, void *priv, ++ struct v4l2_format *f) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ ++ if (node->pad_id != METADATA_PAD) ++ return -EINVAL; ++ ++ *f = node->v_fmt; ++ ++ return 0; ++} ++ ++static int unicam_queue_setup(struct vb2_queue *vq, ++ unsigned int *nbuffers, ++ unsigned int *nplanes, ++ unsigned int sizes[], ++ struct device *alloc_devs[]) ++{ ++ struct unicam_node *node = vb2_get_drv_priv(vq); ++ struct unicam_device *dev = node->dev; ++ unsigned int size = node->pad_id == IMAGE_PAD ? ++ node->v_fmt.fmt.pix.sizeimage : ++ node->v_fmt.fmt.meta.buffersize; ++ ++ if (vq->num_buffers + *nbuffers < 3) ++ *nbuffers = 3 - vq->num_buffers; ++ ++ if (*nplanes) { ++ if (sizes[0] < size) { ++ unicam_err(dev, "sizes[0] %i < size %u\n", sizes[0], ++ size); ++ return -EINVAL; ++ } ++ size = sizes[0]; ++ } ++ ++ *nplanes = 1; ++ sizes[0] = size; ++ ++ return 0; ++} ++ ++static int unicam_buffer_prepare(struct vb2_buffer *vb) ++{ ++ struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue); ++ struct unicam_device *dev = node->dev; ++ struct unicam_buffer *buf = to_unicam_buffer(vb); ++ unsigned long size; ++ ++ if (WARN_ON(!node->fmt)) ++ return -EINVAL; ++ ++ size = node->pad_id == IMAGE_PAD ? node->v_fmt.fmt.pix.sizeimage : ++ node->v_fmt.fmt.meta.buffersize; ++ if (vb2_plane_size(vb, 0) < size) { ++ unicam_err(dev, "data will not fit into plane (%lu < %lu)\n", ++ vb2_plane_size(vb, 0), size); ++ return -EINVAL; ++ } ++ ++ vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size); ++ return 0; ++} ++ ++static void unicam_buffer_queue(struct vb2_buffer *vb) ++{ ++ struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue); ++ struct unicam_buffer *buf = to_unicam_buffer(vb); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&node->dma_queue_lock, flags); ++ list_add_tail(&buf->list, &node->dma_queue); ++ spin_unlock_irqrestore(&node->dma_queue_lock, flags); ++} ++ ++static void unicam_set_packing_config(struct unicam_device *dev) ++{ ++ u32 pack, unpack; ++ u32 val; ++ ++ if (dev->node[IMAGE_PAD].v_fmt.fmt.pix.pixelformat == ++ dev->node[IMAGE_PAD].fmt->fourcc) { ++ unpack = UNICAM_PUM_NONE; ++ pack = UNICAM_PPM_NONE; ++ } else { ++ switch (dev->node[IMAGE_PAD].fmt->depth) { ++ case 8: ++ unpack = UNICAM_PUM_UNPACK8; ++ break; ++ case 10: ++ unpack = UNICAM_PUM_UNPACK10; ++ break; ++ case 12: ++ unpack = UNICAM_PUM_UNPACK12; ++ break; ++ case 14: ++ unpack = UNICAM_PUM_UNPACK14; ++ break; ++ case 16: ++ unpack = UNICAM_PUM_UNPACK16; ++ break; ++ default: ++ unpack = UNICAM_PUM_NONE; ++ break; ++ } ++ ++ /* Repacking is always to 16bpp */ ++ pack = UNICAM_PPM_PACK16; ++ } ++ ++ val = 0; ++ set_field(&val, unpack, UNICAM_PUM_MASK); ++ set_field(&val, pack, UNICAM_PPM_MASK); ++ reg_write(dev, UNICAM_IPIPE, val); ++} ++ ++static void unicam_cfg_image_id(struct unicam_device *dev) ++{ ++ if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { ++ /* CSI2 mode, hardcode VC 0 for now. */ ++ reg_write(dev, UNICAM_IDI0, ++ (0 << 6) | dev->node[IMAGE_PAD].fmt->csi_dt); ++ } else { ++ /* CCP2 mode */ ++ reg_write(dev, UNICAM_IDI0, ++ 0x80 | dev->node[IMAGE_PAD].fmt->csi_dt); ++ } ++} ++ ++static void unicam_enable_ed(struct unicam_device *dev) ++{ ++ u32 val = reg_read(dev, UNICAM_DCS); ++ ++ set_field(&val, 2, UNICAM_EDL_MASK); ++ /* Do not wrap at the end of the embedded data buffer */ ++ set_field(&val, 0, UNICAM_DBOB); ++ ++ reg_write(dev, UNICAM_DCS, val); ++} ++ ++static void unicam_start_rx(struct unicam_device *dev, dma_addr_t *addr) ++{ ++ int line_int_freq = dev->node[IMAGE_PAD].v_fmt.fmt.pix.height >> 2; ++ unsigned int size, i; ++ u32 val; ++ ++ if (line_int_freq < 128) ++ line_int_freq = 128; ++ ++ /* Enable lane clocks */ ++ val = 1; ++ for (i = 0; i < dev->active_data_lanes; i++) ++ val = val << 2 | 1; ++ clk_write(dev, val); ++ ++ /* Basic init */ ++ reg_write(dev, UNICAM_CTRL, UNICAM_MEM); ++ ++ /* Enable analogue control, and leave in reset. */ ++ val = UNICAM_AR; ++ set_field(&val, 7, UNICAM_CTATADJ_MASK); ++ set_field(&val, 7, UNICAM_PTATADJ_MASK); ++ reg_write(dev, UNICAM_ANA, val); ++ usleep_range(1000, 2000); ++ ++ /* Come out of reset */ ++ reg_write_field(dev, UNICAM_ANA, 0, UNICAM_AR); ++ ++ /* Peripheral reset */ ++ reg_write_field(dev, UNICAM_CTRL, 1, UNICAM_CPR); ++ reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_CPR); ++ ++ reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_CPE); ++ ++ /* Enable Rx control. */ ++ val = reg_read(dev, UNICAM_CTRL); ++ if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { ++ set_field(&val, UNICAM_CPM_CSI2, UNICAM_CPM_MASK); ++ set_field(&val, UNICAM_DCM_STROBE, UNICAM_DCM_MASK); ++ } else { ++ set_field(&val, UNICAM_CPM_CCP2, UNICAM_CPM_MASK); ++ set_field(&val, dev->bus_flags, UNICAM_DCM_MASK); ++ } ++ /* Packet framer timeout */ ++ set_field(&val, 0xf, UNICAM_PFT_MASK); ++ set_field(&val, 128, UNICAM_OET_MASK); ++ reg_write(dev, UNICAM_CTRL, val); ++ ++ reg_write(dev, UNICAM_IHWIN, 0); ++ reg_write(dev, UNICAM_IVWIN, 0); ++ ++ /* AXI bus access QoS setup */ ++ val = reg_read(dev, UNICAM_PRI); ++ set_field(&val, 0, UNICAM_BL_MASK); ++ set_field(&val, 0, UNICAM_BS_MASK); ++ set_field(&val, 0xe, UNICAM_PP_MASK); ++ set_field(&val, 8, UNICAM_NP_MASK); ++ set_field(&val, 2, UNICAM_PT_MASK); ++ set_field(&val, 1, UNICAM_PE); ++ reg_write(dev, UNICAM_PRI, val); ++ ++ reg_write_field(dev, UNICAM_ANA, 0, UNICAM_DDL); ++ ++ /* Always start in trigger frame capture mode (UNICAM_FCM set) */ ++ val = UNICAM_FSIE | UNICAM_FEIE | UNICAM_FCM | UNICAM_IBOB; ++ set_field(&val, line_int_freq, UNICAM_LCIE_MASK); ++ reg_write(dev, UNICAM_ICTL, val); ++ reg_write(dev, UNICAM_STA, UNICAM_STA_MASK_ALL); ++ reg_write(dev, UNICAM_ISTA, UNICAM_ISTA_MASK_ALL); ++ ++ /* tclk_term_en */ ++ reg_write_field(dev, UNICAM_CLT, 2, UNICAM_CLT1_MASK); ++ /* tclk_settle */ ++ reg_write_field(dev, UNICAM_CLT, 6, UNICAM_CLT2_MASK); ++ /* td_term_en */ ++ reg_write_field(dev, UNICAM_DLT, 2, UNICAM_DLT1_MASK); ++ /* ths_settle */ ++ reg_write_field(dev, UNICAM_DLT, 6, UNICAM_DLT2_MASK); ++ /* trx_enable */ ++ reg_write_field(dev, UNICAM_DLT, 0, UNICAM_DLT3_MASK); ++ ++ reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_SOE); ++ ++ /* Packet compare setup - required to avoid missing frame ends */ ++ val = 0; ++ set_field(&val, 1, UNICAM_PCE); ++ set_field(&val, 1, UNICAM_GI); ++ set_field(&val, 1, UNICAM_CPH); ++ set_field(&val, 0, UNICAM_PCVC_MASK); ++ set_field(&val, 1, UNICAM_PCDT_MASK); ++ reg_write(dev, UNICAM_CMP0, val); ++ ++ /* Enable clock lane and set up terminations */ ++ val = 0; ++ if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { ++ /* CSI2 */ ++ set_field(&val, 1, UNICAM_CLE); ++ set_field(&val, 1, UNICAM_CLLPE); ++ if (dev->bus_flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) { ++ set_field(&val, 1, UNICAM_CLTRE); ++ set_field(&val, 1, UNICAM_CLHSE); ++ } ++ } else { ++ /* CCP2 */ ++ set_field(&val, 1, UNICAM_CLE); ++ set_field(&val, 1, UNICAM_CLHSE); ++ set_field(&val, 1, UNICAM_CLTRE); ++ } ++ reg_write(dev, UNICAM_CLK, val); ++ ++ /* ++ * Enable required data lanes with appropriate terminations. ++ * The same value needs to be written to UNICAM_DATn registers for ++ * the active lanes, and 0 for inactive ones. ++ */ ++ val = 0; ++ if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { ++ /* CSI2 */ ++ set_field(&val, 1, UNICAM_DLE); ++ set_field(&val, 1, UNICAM_DLLPE); ++ if (dev->bus_flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) { ++ set_field(&val, 1, UNICAM_DLTRE); ++ set_field(&val, 1, UNICAM_DLHSE); ++ } ++ } else { ++ /* CCP2 */ ++ set_field(&val, 1, UNICAM_DLE); ++ set_field(&val, 1, UNICAM_DLHSE); ++ set_field(&val, 1, UNICAM_DLTRE); ++ } ++ reg_write(dev, UNICAM_DAT0, val); ++ ++ if (dev->active_data_lanes == 1) ++ val = 0; ++ reg_write(dev, UNICAM_DAT1, val); ++ ++ if (dev->max_data_lanes > 2) { ++ /* ++ * Registers UNICAM_DAT2 and UNICAM_DAT3 only valid if the ++ * instance supports more than 2 data lanes. ++ */ ++ if (dev->active_data_lanes == 2) ++ val = 0; ++ reg_write(dev, UNICAM_DAT2, val); ++ ++ if (dev->active_data_lanes == 3) ++ val = 0; ++ reg_write(dev, UNICAM_DAT3, val); ++ } ++ ++ reg_write(dev, UNICAM_IBLS, ++ dev->node[IMAGE_PAD].v_fmt.fmt.pix.bytesperline); ++ size = dev->node[IMAGE_PAD].v_fmt.fmt.pix.sizeimage; ++ unicam_wr_dma_addr(dev, addr[IMAGE_PAD], size, IMAGE_PAD); ++ unicam_set_packing_config(dev); ++ unicam_cfg_image_id(dev); ++ ++ val = reg_read(dev, UNICAM_MISC); ++ set_field(&val, 1, UNICAM_FL0); ++ set_field(&val, 1, UNICAM_FL1); ++ reg_write(dev, UNICAM_MISC, val); ++ ++ if (dev->node[METADATA_PAD].streaming && dev->sensor_embedded_data) { ++ size = dev->node[METADATA_PAD].v_fmt.fmt.meta.buffersize; ++ unicam_enable_ed(dev); ++ unicam_wr_dma_addr(dev, addr[METADATA_PAD], size, METADATA_PAD); ++ } ++ ++ /* Enable peripheral */ ++ reg_write_field(dev, UNICAM_CTRL, 1, UNICAM_CPE); ++ ++ /* Load image pointers */ ++ reg_write_field(dev, UNICAM_ICTL, 1, UNICAM_LIP_MASK); ++ ++ /* Load embedded data buffer pointers if needed */ ++ if (dev->node[METADATA_PAD].streaming && dev->sensor_embedded_data) ++ reg_write_field(dev, UNICAM_DCS, 1, UNICAM_LDP); ++ ++ /* ++ * Enable trigger only for the first frame to ++ * sync correctly to the FS from the source. ++ */ ++ reg_write_field(dev, UNICAM_ICTL, 1, UNICAM_TFC); ++} ++ ++static void unicam_disable(struct unicam_device *dev) ++{ ++ /* Analogue lane control disable */ ++ reg_write_field(dev, UNICAM_ANA, 1, UNICAM_DDL); ++ ++ /* Stop the output engine */ ++ reg_write_field(dev, UNICAM_CTRL, 1, UNICAM_SOE); ++ ++ /* Disable the data lanes. */ ++ reg_write(dev, UNICAM_DAT0, 0); ++ reg_write(dev, UNICAM_DAT1, 0); ++ ++ if (dev->max_data_lanes > 2) { ++ reg_write(dev, UNICAM_DAT2, 0); ++ reg_write(dev, UNICAM_DAT3, 0); ++ } ++ ++ /* Peripheral reset */ ++ reg_write_field(dev, UNICAM_CTRL, 1, UNICAM_CPR); ++ usleep_range(50, 100); ++ reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_CPR); ++ ++ /* Disable peripheral */ ++ reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_CPE); ++ ++ /* Clear ED setup */ ++ reg_write(dev, UNICAM_DCS, 0); ++ ++ /* Disable all lane clocks */ ++ clk_write(dev, 0); ++} ++ ++static void unicam_return_buffers(struct unicam_node *node) ++{ ++ struct unicam_buffer *buf, *tmp; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&node->dma_queue_lock, flags); ++ list_for_each_entry_safe(buf, tmp, &node->dma_queue, list) { ++ list_del(&buf->list); ++ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); ++ } ++ ++ if (node->cur_frm) ++ vb2_buffer_done(&node->cur_frm->vb.vb2_buf, ++ VB2_BUF_STATE_ERROR); ++ if (node->next_frm && node->cur_frm != node->next_frm) ++ vb2_buffer_done(&node->next_frm->vb.vb2_buf, ++ VB2_BUF_STATE_ERROR); ++ ++ node->cur_frm = NULL; ++ node->next_frm = NULL; ++ spin_unlock_irqrestore(&node->dma_queue_lock, flags); ++} ++ ++static int unicam_start_streaming(struct vb2_queue *vq, unsigned int count) ++{ ++ struct unicam_node *node = vb2_get_drv_priv(vq); ++ struct unicam_device *dev = node->dev; ++ dma_addr_t buffer_addr[MAX_NODES] = { 0 }; ++ unsigned long flags; ++ unsigned int i; ++ int ret; ++ ++ node->streaming = true; ++ if (!unicam_all_nodes_streaming(dev)) { ++ unicam_dbg(3, dev, "Not all nodes are streaming yet."); ++ return 0; ++ } ++ ++ dev->sequence = 0; ++ ret = unicam_runtime_get(dev); ++ if (ret < 0) { ++ unicam_dbg(3, dev, "unicam_runtime_get failed\n"); ++ goto err_streaming; ++ } ++ ++ /* ++ * TODO: Retrieve the number of active data lanes from the connected ++ * subdevice. ++ */ ++ dev->active_data_lanes = dev->max_data_lanes; ++ ++ ret = clk_set_rate(dev->clock, 100 * 1000 * 1000); ++ if (ret) { ++ unicam_err(dev, "failed to set up clock\n"); ++ goto err_pm_put; ++ } ++ ++ ret = clk_prepare_enable(dev->clock); ++ if (ret) { ++ unicam_err(dev, "Failed to enable CSI clock: %d\n", ret); ++ goto err_pm_put; ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(dev->node); i++) { ++ struct unicam_buffer *buf; ++ ++ if (!dev->node[i].streaming) ++ continue; ++ ++ spin_lock_irqsave(&dev->node[i].dma_queue_lock, flags); ++ buf = list_first_entry(&dev->node[i].dma_queue, ++ struct unicam_buffer, list); ++ dev->node[i].cur_frm = buf; ++ dev->node[i].next_frm = buf; ++ list_del(&buf->list); ++ spin_unlock_irqrestore(&dev->node[i].dma_queue_lock, flags); ++ ++ buffer_addr[i] = ++ vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0); ++ } ++ ++ unicam_start_rx(dev, buffer_addr); ++ ++ ret = v4l2_subdev_call(dev->sensor, video, s_stream, 1); ++ if (ret < 0) { ++ unicam_err(dev, "stream on failed in subdev\n"); ++ goto err_disable_unicam; ++ } ++ ++ return 0; ++ ++err_disable_unicam: ++ unicam_disable(dev); ++ clk_disable_unprepare(dev->clock); ++err_pm_put: ++ unicam_runtime_put(dev); ++err_streaming: ++ unicam_return_buffers(node); ++ node->streaming = false; ++ ++ return ret; ++} ++ ++static void unicam_stop_streaming(struct vb2_queue *vq) ++{ ++ struct unicam_node *node = vb2_get_drv_priv(vq); ++ struct unicam_device *dev = node->dev; ++ ++ node->streaming = false; ++ ++ if (node->pad_id == IMAGE_PAD) { ++ /* ++ * Stop streaming the sensor and disable the peripheral. ++ * We cannot continue streaming embedded data with the ++ * image pad disabled. ++ */ ++ if (v4l2_subdev_call(dev->sensor, video, s_stream, 0) < 0) ++ unicam_err(dev, "stream off failed in subdev\n"); ++ ++ unicam_disable(dev); ++ clk_disable_unprepare(dev->clock); ++ unicam_runtime_put(dev); ++ ++ } else if (node->pad_id == METADATA_PAD) { ++ /* ++ * Allow the hardware to spin in the dummy buffer. ++ * This is only really needed if the embedded data pad is ++ * disabled before the image pad. ++ */ ++ unicam_wr_dma_addr(dev, node->dummy_buf_dma_addr, ++ DUMMY_BUF_SIZE, METADATA_PAD); ++ } ++ ++ /* Clear all queued buffers for the node */ ++ unicam_return_buffers(node); ++} ++ ++static int unicam_enum_input(struct file *file, void *priv, ++ struct v4l2_input *inp) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ ++ if (inp->index != 0) ++ return -EINVAL; ++ ++ inp->type = V4L2_INPUT_TYPE_CAMERA; ++ if (v4l2_subdev_has_op(dev->sensor, video, s_dv_timings)) { ++ inp->capabilities = V4L2_IN_CAP_DV_TIMINGS; ++ inp->std = 0; ++ } else if (v4l2_subdev_has_op(dev->sensor, video, s_std)) { ++ inp->capabilities = V4L2_IN_CAP_STD; ++ if (v4l2_subdev_call(dev->sensor, video, g_tvnorms, &inp->std) ++ < 0) ++ inp->std = V4L2_STD_ALL; ++ } else { ++ inp->capabilities = 0; ++ inp->std = 0; ++ } ++ sprintf(inp->name, "Camera 0"); ++ return 0; ++} ++ ++static int unicam_g_input(struct file *file, void *priv, unsigned int *i) ++{ ++ *i = 0; ++ ++ return 0; ++} ++ ++static int unicam_s_input(struct file *file, void *priv, unsigned int i) ++{ ++ /* ++ * FIXME: Ideally we would like to be able to query the source ++ * subdevice for information over the input connectors it supports, ++ * and map that through in to a call to video_ops->s_routing. ++ * There is no infrastructure support for defining that within ++ * devicetree at present. Until that is implemented we can't ++ * map a user physical connector number to s_routing input number. ++ */ ++ if (i > 0) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int unicam_querystd(struct file *file, void *priv, ++ v4l2_std_id *std) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ ++ return v4l2_subdev_call(dev->sensor, video, querystd, std); ++} ++ ++static int unicam_g_std(struct file *file, void *priv, v4l2_std_id *std) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ ++ return v4l2_subdev_call(dev->sensor, video, g_std, std); ++} ++ ++static int unicam_s_std(struct file *file, void *priv, v4l2_std_id std) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ int ret; ++ v4l2_std_id current_std; ++ ++ ret = v4l2_subdev_call(dev->sensor, video, g_std, ¤t_std); ++ if (ret) ++ return ret; ++ ++ if (std == current_std) ++ return 0; ++ ++ if (vb2_is_busy(&node->buffer_queue)) ++ return -EBUSY; ++ ++ ret = v4l2_subdev_call(dev->sensor, video, s_std, std); ++ ++ /* Force recomputation of bytesperline */ ++ node->v_fmt.fmt.pix.bytesperline = 0; ++ ++ unicam_reset_format(node); ++ ++ return ret; ++} ++ ++static int unicam_s_edid(struct file *file, void *priv, struct v4l2_edid *edid) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ ++ return v4l2_subdev_call(dev->sensor, pad, set_edid, edid); ++} ++ ++static int unicam_g_edid(struct file *file, void *priv, struct v4l2_edid *edid) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ ++ return v4l2_subdev_call(dev->sensor, pad, get_edid, edid); ++} ++ ++static int unicam_s_selection(struct file *file, void *priv, ++ struct v4l2_selection *sel) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ struct v4l2_subdev_selection sdsel = { ++ .which = V4L2_SUBDEV_FORMAT_ACTIVE, ++ .target = sel->target, ++ .flags = sel->flags, ++ .r = sel->r, ++ }; ++ ++ return v4l2_subdev_call(dev->sensor, pad, set_selection, NULL, &sdsel); ++} ++ ++static int unicam_g_selection(struct file *file, void *priv, ++ struct v4l2_selection *sel) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ struct v4l2_subdev_selection sdsel = { ++ .which = V4L2_SUBDEV_FORMAT_ACTIVE, ++ .target = sel->target, ++ }; ++ int ret; ++ ++ ret = v4l2_subdev_call(dev->sensor, pad, get_selection, NULL, &sdsel); ++ if (!ret) ++ sel->r = sdsel.r; ++ ++ return ret; ++} ++ ++static int unicam_enum_framesizes(struct file *file, void *priv, ++ struct v4l2_frmsizeenum *fsize) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ const struct unicam_fmt *fmt; ++ struct v4l2_subdev_frame_size_enum fse; ++ int ret; ++ ++ /* check for valid format */ ++ fmt = find_format_by_pix(dev, fsize->pixel_format); ++ if (!fmt) { ++ unicam_dbg(3, dev, "Invalid pixel code: %x\n", ++ fsize->pixel_format); ++ return -EINVAL; ++ } ++ fse.code = fmt->code; ++ ++ fse.which = V4L2_SUBDEV_FORMAT_ACTIVE; ++ fse.index = fsize->index; ++ fse.pad = node->pad_id; ++ ++ ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_size, NULL, &fse); ++ if (ret) ++ return ret; ++ ++ unicam_dbg(1, dev, "%s: index: %d code: %x W:[%d,%d] H:[%d,%d]\n", ++ __func__, fse.index, fse.code, fse.min_width, fse.max_width, ++ fse.min_height, fse.max_height); ++ ++ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; ++ fsize->discrete.width = fse.max_width; ++ fsize->discrete.height = fse.max_height; ++ ++ return 0; ++} ++ ++static int unicam_enum_frameintervals(struct file *file, void *priv, ++ struct v4l2_frmivalenum *fival) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ const struct unicam_fmt *fmt; ++ struct v4l2_subdev_frame_interval_enum fie = { ++ .index = fival->index, ++ .width = fival->width, ++ .height = fival->height, ++ .which = V4L2_SUBDEV_FORMAT_ACTIVE, ++ }; ++ int ret; ++ ++ fmt = find_format_by_pix(dev, fival->pixel_format); ++ if (!fmt) ++ return -EINVAL; ++ ++ fie.code = fmt->code; ++ ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_interval, ++ NULL, &fie); ++ if (ret) ++ return ret; ++ ++ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; ++ fival->discrete = fie.interval; ++ ++ return 0; ++} ++ ++static int unicam_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ ++ return v4l2_g_parm_cap(video_devdata(file), dev->sensor, a); ++} ++ ++static int unicam_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ ++ return v4l2_s_parm_cap(video_devdata(file), dev->sensor, a); ++} ++ ++static int unicam_g_dv_timings(struct file *file, void *priv, ++ struct v4l2_dv_timings *timings) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ ++ return v4l2_subdev_call(dev->sensor, video, g_dv_timings, timings); ++} ++ ++static int unicam_s_dv_timings(struct file *file, void *priv, ++ struct v4l2_dv_timings *timings) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ struct v4l2_dv_timings current_timings; ++ int ret; ++ ++ ret = v4l2_subdev_call(dev->sensor, video, g_dv_timings, ++ ¤t_timings); ++ ++ if (v4l2_match_dv_timings(timings, ¤t_timings, 0, false)) ++ return 0; ++ ++ if (vb2_is_busy(&node->buffer_queue)) ++ return -EBUSY; ++ ++ ret = v4l2_subdev_call(dev->sensor, video, s_dv_timings, timings); ++ ++ /* Force recomputation of bytesperline */ ++ node->v_fmt.fmt.pix.bytesperline = 0; ++ ++ unicam_reset_format(node); ++ ++ return ret; ++} ++ ++static int unicam_query_dv_timings(struct file *file, void *priv, ++ struct v4l2_dv_timings *timings) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ ++ return v4l2_subdev_call(dev->sensor, video, query_dv_timings, timings); ++} ++ ++static int unicam_enum_dv_timings(struct file *file, void *priv, ++ struct v4l2_enum_dv_timings *timings) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ ++ return v4l2_subdev_call(dev->sensor, pad, enum_dv_timings, timings); ++} ++ ++static int unicam_dv_timings_cap(struct file *file, void *priv, ++ struct v4l2_dv_timings_cap *cap) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ ++ return v4l2_subdev_call(dev->sensor, pad, dv_timings_cap, cap); ++} ++ ++static int unicam_subscribe_event(struct v4l2_fh *fh, ++ const struct v4l2_event_subscription *sub) ++{ ++ switch (sub->type) { ++ case V4L2_EVENT_FRAME_SYNC: ++ return v4l2_event_subscribe(fh, sub, 2, NULL); ++ case V4L2_EVENT_SOURCE_CHANGE: ++ return v4l2_event_subscribe(fh, sub, 4, NULL); ++ } ++ ++ return v4l2_ctrl_subscribe_event(fh, sub); ++} ++ ++static int unicam_log_status(struct file *file, void *fh) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ u32 reg; ++ ++ /* status for sub devices */ ++ v4l2_device_call_all(&dev->v4l2_dev, 0, core, log_status); ++ ++ unicam_info(dev, "-----Receiver status-----\n"); ++ unicam_info(dev, "V4L2 width/height: %ux%u\n", ++ node->v_fmt.fmt.pix.width, node->v_fmt.fmt.pix.height); ++ unicam_info(dev, "Mediabus format: %08x\n", node->fmt->code); ++ unicam_info(dev, "V4L2 format: %08x\n", ++ node->v_fmt.fmt.pix.pixelformat); ++ reg = reg_read(dev, UNICAM_IPIPE); ++ unicam_info(dev, "Unpacking/packing: %u / %u\n", ++ get_field(reg, UNICAM_PUM_MASK), ++ get_field(reg, UNICAM_PPM_MASK)); ++ unicam_info(dev, "----Live data----\n"); ++ unicam_info(dev, "Programmed stride: %4u\n", ++ reg_read(dev, UNICAM_IBLS)); ++ unicam_info(dev, "Detected resolution: %ux%u\n", ++ reg_read(dev, UNICAM_IHSTA), ++ reg_read(dev, UNICAM_IVSTA)); ++ unicam_info(dev, "Write pointer: %08x\n", ++ reg_read(dev, UNICAM_IBWP)); ++ ++ return 0; ++} ++ ++static void unicam_notify(struct v4l2_subdev *sd, ++ unsigned int notification, void *arg) ++{ ++ struct unicam_device *dev = to_unicam_device(sd->v4l2_dev); ++ ++ switch (notification) { ++ case V4L2_DEVICE_NOTIFY_EVENT: ++ v4l2_event_queue(&dev->node[IMAGE_PAD].video_dev, arg); ++ break; ++ default: ++ break; ++ } ++} ++ ++static const struct vb2_ops unicam_video_qops = { ++ .wait_prepare = vb2_ops_wait_prepare, ++ .wait_finish = vb2_ops_wait_finish, ++ .queue_setup = unicam_queue_setup, ++ .buf_prepare = unicam_buffer_prepare, ++ .buf_queue = unicam_buffer_queue, ++ .start_streaming = unicam_start_streaming, ++ .stop_streaming = unicam_stop_streaming, ++}; ++ ++/* ++ * unicam_v4l2_open : This function is based on the v4l2_fh_open helper ++ * function. It has been augmented to handle sensor subdevice power management, ++ */ ++static int unicam_v4l2_open(struct file *file) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ int ret; ++ ++ mutex_lock(&node->lock); ++ ++ ret = v4l2_fh_open(file); ++ if (ret) { ++ unicam_err(dev, "v4l2_fh_open failed\n"); ++ goto unlock; ++ } ++ ++ node->open++; ++ ++ if (!v4l2_fh_is_singular_file(file)) ++ goto unlock; ++ ++ ret = v4l2_subdev_call(dev->sensor, core, s_power, 1); ++ if (ret < 0 && ret != -ENOIOCTLCMD) { ++ v4l2_fh_release(file); ++ node->open--; ++ goto unlock; ++ } ++ ++ ret = 0; ++ ++unlock: ++ mutex_unlock(&node->lock); ++ return ret; ++} ++ ++static int unicam_v4l2_release(struct file *file) ++{ ++ struct unicam_node *node = video_drvdata(file); ++ struct unicam_device *dev = node->dev; ++ struct v4l2_subdev *sd = dev->sensor; ++ bool fh_singular; ++ int ret; ++ ++ mutex_lock(&node->lock); ++ ++ fh_singular = v4l2_fh_is_singular_file(file); ++ ++ ret = _vb2_fop_release(file, NULL); ++ ++ if (fh_singular) ++ v4l2_subdev_call(sd, core, s_power, 0); ++ ++ node->open--; ++ mutex_unlock(&node->lock); ++ ++ return ret; ++} ++ ++/* unicam capture driver file operations */ ++static const struct v4l2_file_operations unicam_fops = { ++ .owner = THIS_MODULE, ++ .open = unicam_v4l2_open, ++ .release = unicam_v4l2_release, ++ .read = vb2_fop_read, ++ .poll = vb2_fop_poll, ++ .unlocked_ioctl = video_ioctl2, ++ .mmap = vb2_fop_mmap, ++}; ++ ++/* unicam capture ioctl operations */ ++static const struct v4l2_ioctl_ops unicam_ioctl_ops = { ++ .vidioc_querycap = unicam_querycap, ++ .vidioc_enum_fmt_vid_cap = unicam_enum_fmt_vid_cap, ++ .vidioc_g_fmt_vid_cap = unicam_g_fmt_vid_cap, ++ .vidioc_s_fmt_vid_cap = unicam_s_fmt_vid_cap, ++ .vidioc_try_fmt_vid_cap = unicam_try_fmt_vid_cap, ++ ++ .vidioc_enum_fmt_meta_cap = unicam_enum_fmt_meta_cap, ++ .vidioc_g_fmt_meta_cap = unicam_g_fmt_meta_cap, ++ .vidioc_s_fmt_meta_cap = unicam_g_fmt_meta_cap, ++ .vidioc_try_fmt_meta_cap = unicam_g_fmt_meta_cap, ++ ++ .vidioc_enum_input = unicam_enum_input, ++ .vidioc_g_input = unicam_g_input, ++ .vidioc_s_input = unicam_s_input, ++ ++ .vidioc_querystd = unicam_querystd, ++ .vidioc_s_std = unicam_s_std, ++ .vidioc_g_std = unicam_g_std, ++ ++ .vidioc_g_edid = unicam_g_edid, ++ .vidioc_s_edid = unicam_s_edid, ++ ++ .vidioc_enum_framesizes = unicam_enum_framesizes, ++ .vidioc_enum_frameintervals = unicam_enum_frameintervals, ++ ++ .vidioc_g_selection = unicam_g_selection, ++ .vidioc_s_selection = unicam_s_selection, ++ ++ .vidioc_g_parm = unicam_g_parm, ++ .vidioc_s_parm = unicam_s_parm, ++ ++ .vidioc_s_dv_timings = unicam_s_dv_timings, ++ .vidioc_g_dv_timings = unicam_g_dv_timings, ++ .vidioc_query_dv_timings = unicam_query_dv_timings, ++ .vidioc_enum_dv_timings = unicam_enum_dv_timings, ++ .vidioc_dv_timings_cap = unicam_dv_timings_cap, ++ ++ .vidioc_reqbufs = vb2_ioctl_reqbufs, ++ .vidioc_create_bufs = vb2_ioctl_create_bufs, ++ .vidioc_prepare_buf = vb2_ioctl_prepare_buf, ++ .vidioc_querybuf = vb2_ioctl_querybuf, ++ .vidioc_qbuf = vb2_ioctl_qbuf, ++ .vidioc_dqbuf = vb2_ioctl_dqbuf, ++ .vidioc_expbuf = vb2_ioctl_expbuf, ++ .vidioc_streamon = vb2_ioctl_streamon, ++ .vidioc_streamoff = vb2_ioctl_streamoff, ++ ++ .vidioc_log_status = unicam_log_status, ++ .vidioc_subscribe_event = unicam_subscribe_event, ++ .vidioc_unsubscribe_event = v4l2_event_unsubscribe, ++}; ++ ++static int ++unicam_async_bound(struct v4l2_async_notifier *notifier, ++ struct v4l2_subdev *subdev, ++ struct v4l2_async_subdev *asd) ++{ ++ struct unicam_device *unicam = to_unicam_device(notifier->v4l2_dev); ++ ++ if (unicam->sensor) { ++ unicam_info(unicam, "Rejecting subdev %s (Already set!!)", ++ subdev->name); ++ return 0; ++ } ++ ++ unicam->sensor = subdev; ++ unicam_dbg(1, unicam, "Using sensor %s for capture\n", subdev->name); ++ ++ return 0; ++} ++ ++static void unicam_release(struct kref *kref) ++{ ++ struct unicam_device *unicam = ++ container_of(kref, struct unicam_device, kref); ++ ++ v4l2_ctrl_handler_free(&unicam->ctrl_handler); ++ media_device_cleanup(&unicam->mdev); ++ ++ if (unicam->sensor_config) ++ v4l2_subdev_free_pad_config(unicam->sensor_config); ++ ++ kfree(unicam); ++} ++ ++static void unicam_put(struct unicam_device *unicam) ++{ ++ kref_put(&unicam->kref, unicam_release); ++} ++ ++static void unicam_get(struct unicam_device *unicam) ++{ ++ kref_get(&unicam->kref); ++} ++ ++static void unicam_node_release(struct video_device *vdev) ++{ ++ struct unicam_node *node = video_get_drvdata(vdev); ++ ++ unicam_put(node->dev); ++} ++ ++static int register_node(struct unicam_device *unicam, struct unicam_node *node, ++ enum v4l2_buf_type type, int pad_id) ++{ ++ struct video_device *vdev; ++ struct vb2_queue *q; ++ struct v4l2_mbus_framefmt mbus_fmt = {0}; ++ const struct unicam_fmt *fmt; ++ int ret; ++ ++ if (pad_id == IMAGE_PAD) { ++ ret = __subdev_get_format(unicam, &mbus_fmt, pad_id); ++ if (ret) { ++ unicam_err(unicam, "Failed to get_format - ret %d\n", ++ ret); ++ return ret; ++ } ++ ++ fmt = find_format_by_code(mbus_fmt.code); ++ if (!fmt) { ++ /* ++ * Find the first format that the sensor and unicam both ++ * support ++ */ ++ fmt = get_first_supported_format(unicam); ++ ++ if (!fmt) ++ /* No compatible formats */ ++ return -EINVAL; ++ ++ mbus_fmt.code = fmt->code; ++ ret = __subdev_set_format(unicam, &mbus_fmt, pad_id); ++ if (ret) ++ return -EINVAL; ++ } ++ if (mbus_fmt.field != V4L2_FIELD_NONE) { ++ /* Interlaced not supported - disable it now. */ ++ mbus_fmt.field = V4L2_FIELD_NONE; ++ ret = __subdev_set_format(unicam, &mbus_fmt, pad_id); ++ if (ret) ++ return -EINVAL; ++ } ++ ++ node->v_fmt.fmt.pix.pixelformat = fmt->fourcc ? fmt->fourcc ++ : fmt->repacked_fourcc; ++ } else { ++ /* Fix this node format as embedded data. */ ++ fmt = find_format_by_code(MEDIA_BUS_FMT_SENSOR_DATA); ++ node->v_fmt.fmt.meta.dataformat = fmt->fourcc; ++ } ++ ++ node->dev = unicam; ++ node->pad_id = pad_id; ++ node->fmt = fmt; ++ ++ /* Read current subdev format */ ++ unicam_reset_format(node); ++ ++ if (v4l2_subdev_has_op(unicam->sensor, video, s_std)) { ++ v4l2_std_id tvnorms; ++ ++ if (WARN_ON(!v4l2_subdev_has_op(unicam->sensor, video, ++ g_tvnorms))) ++ /* ++ * Subdevice should not advertise s_std but not ++ * g_tvnorms ++ */ ++ return -EINVAL; ++ ++ ret = v4l2_subdev_call(unicam->sensor, video, ++ g_tvnorms, &tvnorms); ++ if (WARN_ON(ret)) ++ return -EINVAL; ++ node->video_dev.tvnorms |= tvnorms; ++ } ++ ++ spin_lock_init(&node->dma_queue_lock); ++ mutex_init(&node->lock); ++ ++ vdev = &node->video_dev; ++ if (pad_id == IMAGE_PAD) { ++ /* Add controls from the subdevice */ ++ ret = v4l2_ctrl_add_handler(&unicam->ctrl_handler, ++ unicam->sensor->ctrl_handler, NULL, ++ true); ++ if (ret < 0) ++ return ret; ++ ++ /* ++ * If the sensor subdevice has any controls, associate the node ++ * with the ctrl handler to allow access from userland. ++ */ ++ if (!list_empty(&unicam->ctrl_handler.ctrls)) ++ vdev->ctrl_handler = &unicam->ctrl_handler; ++ } ++ ++ q = &node->buffer_queue; ++ q->type = type; ++ q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ; ++ q->drv_priv = node; ++ q->ops = &unicam_video_qops; ++ q->mem_ops = &vb2_dma_contig_memops; ++ q->buf_struct_size = sizeof(struct unicam_buffer); ++ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; ++ q->lock = &node->lock; ++ q->min_buffers_needed = 2; ++ q->dev = &unicam->pdev->dev; ++ ++ ret = vb2_queue_init(q); ++ if (ret) { ++ unicam_err(unicam, "vb2_queue_init() failed\n"); ++ return ret; ++ } ++ ++ INIT_LIST_HEAD(&node->dma_queue); ++ ++ vdev->release = unicam_node_release; ++ vdev->fops = &unicam_fops; ++ vdev->ioctl_ops = &unicam_ioctl_ops; ++ vdev->v4l2_dev = &unicam->v4l2_dev; ++ vdev->vfl_dir = VFL_DIR_RX; ++ vdev->queue = q; ++ vdev->lock = &node->lock; ++ vdev->device_caps = (pad_id == IMAGE_PAD) ? ++ (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING) : ++ (V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING); ++ ++ /* Define the device names */ ++ snprintf(vdev->name, sizeof(vdev->name), "%s-%s", UNICAM_MODULE_NAME, ++ pad_id == IMAGE_PAD ? "image" : "embedded"); ++ ++ video_set_drvdata(vdev, node); ++ if (pad_id == IMAGE_PAD) ++ vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT; ++ node->pad.flags = MEDIA_PAD_FL_SINK; ++ media_entity_pads_init(&vdev->entity, 1, &node->pad); ++ ++ node->dummy_buf_cpu_addr = dma_alloc_coherent(&unicam->pdev->dev, ++ DUMMY_BUF_SIZE, ++ &node->dummy_buf_dma_addr, ++ GFP_KERNEL); ++ if (!node->dummy_buf_cpu_addr) { ++ unicam_err(unicam, "Unable to allocate dummy buffer.\n"); ++ return -ENOMEM; ++ } ++ ++ if (pad_id == METADATA_PAD) { ++ v4l2_disable_ioctl(vdev, VIDIOC_DQEVENT); ++ v4l2_disable_ioctl(vdev, VIDIOC_SUBSCRIBE_EVENT); ++ v4l2_disable_ioctl(vdev, VIDIOC_UNSUBSCRIBE_EVENT); ++ } ++ if (pad_id == METADATA_PAD || ++ !v4l2_subdev_has_op(unicam->sensor, video, s_std)) { ++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_STD); ++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_STD); ++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUMSTD); ++ } ++ if (pad_id == METADATA_PAD || ++ !v4l2_subdev_has_op(unicam->sensor, video, querystd)) ++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_QUERYSTD); ++ if (pad_id == METADATA_PAD || ++ !v4l2_subdev_has_op(unicam->sensor, video, s_dv_timings)) { ++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_EDID); ++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_EDID); ++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_DV_TIMINGS_CAP); ++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_DV_TIMINGS); ++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_DV_TIMINGS); ++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUM_DV_TIMINGS); ++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_QUERY_DV_TIMINGS); ++ } ++ if (pad_id == METADATA_PAD || ++ !v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_interval)) ++ v4l2_disable_ioctl(&node->video_dev, ++ VIDIOC_ENUM_FRAMEINTERVALS); ++ if (pad_id == METADATA_PAD || ++ !v4l2_subdev_has_op(unicam->sensor, video, g_frame_interval)) ++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_PARM); ++ if (pad_id == METADATA_PAD || ++ !v4l2_subdev_has_op(unicam->sensor, video, s_frame_interval)) ++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_PARM); ++ ++ if (pad_id == METADATA_PAD || ++ !v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_size)) ++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUM_FRAMESIZES); ++ ++ if (node->pad_id == METADATA_PAD || ++ !v4l2_subdev_has_op(unicam->sensor, pad, set_selection)) ++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_SELECTION); ++ ++ if (node->pad_id == METADATA_PAD || ++ !v4l2_subdev_has_op(unicam->sensor, pad, get_selection)) ++ v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_SELECTION); ++ ++ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); ++ if (ret) { ++ unicam_err(unicam, "Unable to register video device %s\n", ++ vdev->name); ++ return ret; ++ } ++ ++ /* ++ * Acquire a reference to unicam, which will be released when the video ++ * device will be unregistered and userspace will have closed all open ++ * file handles. ++ */ ++ unicam_get(unicam); ++ node->registered = true; ++ ++ if (pad_id != METADATA_PAD || unicam->sensor_embedded_data) { ++ ret = media_create_pad_link(&unicam->sensor->entity, pad_id, ++ &node->video_dev.entity, 0, ++ MEDIA_LNK_FL_ENABLED | ++ MEDIA_LNK_FL_IMMUTABLE); ++ if (ret) ++ unicam_err(unicam, "Unable to create pad link for %s\n", ++ vdev->name); ++ } ++ ++ return ret; ++} ++ ++static void unregister_nodes(struct unicam_device *unicam) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(unicam->node); i++) { ++ struct unicam_node *node = &unicam->node[i]; ++ ++ if (node->dummy_buf_cpu_addr) { ++ dma_free_coherent(&unicam->pdev->dev, DUMMY_BUF_SIZE, ++ node->dummy_buf_cpu_addr, ++ node->dummy_buf_dma_addr); ++ } ++ ++ if (node->registered) { ++ node->registered = false; ++ video_unregister_device(&node->video_dev); ++ } ++ } ++} ++ ++static int unicam_probe_complete(struct unicam_device *unicam) ++{ ++ int ret; ++ ++ unicam->v4l2_dev.notify = unicam_notify; ++ ++ unicam->sensor_config = v4l2_subdev_alloc_pad_config(unicam->sensor); ++ if (!unicam->sensor_config) ++ return -ENOMEM; ++ ++ unicam->sensor_embedded_data = (unicam->sensor->entity.num_pads >= 2); ++ ++ ret = register_node(unicam, &unicam->node[IMAGE_PAD], ++ V4L2_BUF_TYPE_VIDEO_CAPTURE, IMAGE_PAD); ++ if (ret) { ++ unicam_err(unicam, "Unable to register image video device.\n"); ++ goto unregister; ++ } ++ ++ ret = register_node(unicam, &unicam->node[METADATA_PAD], ++ V4L2_BUF_TYPE_META_CAPTURE, METADATA_PAD); ++ if (ret) { ++ unicam_err(unicam, "Unable to register metadata video device.\n"); ++ goto unregister; ++ } ++ ++ ret = v4l2_device_register_ro_subdev_nodes(&unicam->v4l2_dev); ++ if (ret) { ++ unicam_err(unicam, "Unable to register subdev nodes.\n"); ++ goto unregister; ++ } ++ ++ /* ++ * Release the initial reference, all references are now owned by the ++ * video devices. ++ */ ++ unicam_put(unicam); ++ return 0; ++ ++unregister: ++ unregister_nodes(unicam); ++ unicam_put(unicam); ++ ++ return ret; ++} ++ ++static int unicam_async_complete(struct v4l2_async_notifier *notifier) ++{ ++ struct unicam_device *unicam = to_unicam_device(notifier->v4l2_dev); ++ ++ return unicam_probe_complete(unicam); ++} ++ ++static const struct v4l2_async_notifier_operations unicam_async_ops = { ++ .bound = unicam_async_bound, ++ .complete = unicam_async_complete, ++}; ++ ++static int of_unicam_connect_subdevs(struct unicam_device *dev) ++{ ++ struct platform_device *pdev = dev->pdev; ++ struct v4l2_fwnode_endpoint ep = { 0 }; ++ struct device_node *ep_node; ++ struct device_node *sensor_node; ++ unsigned int lane; ++ int ret = -EINVAL; ++ ++ if (of_property_read_u32(pdev->dev.of_node, "brcm,num-data-lanes", ++ &dev->max_data_lanes) < 0) { ++ unicam_err(dev, "number of data lanes not set\n"); ++ return -EINVAL; ++ } ++ ++ /* Get the local endpoint and remote device. */ ++ ep_node = of_graph_get_next_endpoint(pdev->dev.of_node, NULL); ++ if (!ep_node) { ++ unicam_dbg(3, dev, "can't get next endpoint\n"); ++ return -EINVAL; ++ } ++ ++ unicam_dbg(3, dev, "ep_node is %pOF\n", ep_node); ++ ++ sensor_node = of_graph_get_remote_port_parent(ep_node); ++ if (!sensor_node) { ++ unicam_dbg(3, dev, "can't get remote parent\n"); ++ goto cleanup_exit; ++ } ++ ++ unicam_dbg(1, dev, "found subdevice %pOF\n", sensor_node); ++ ++ /* Parse the local endpoint and validate its configuration. */ ++ v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), &ep); ++ ++ unicam_dbg(3, dev, "parsed local endpoint, bus_type %u\n", ++ ep.bus_type); ++ ++ dev->bus_type = ep.bus_type; ++ ++ switch (ep.bus_type) { ++ case V4L2_MBUS_CSI2_DPHY: ++ switch (ep.bus.mipi_csi2.num_data_lanes) { ++ case 1: ++ case 2: ++ case 4: ++ break; ++ ++ default: ++ unicam_err(dev, "subdevice %pOF: %u data lanes not supported\n", ++ sensor_node, ++ ep.bus.mipi_csi2.num_data_lanes); ++ goto cleanup_exit; ++ } ++ ++ for (lane = 0; lane < ep.bus.mipi_csi2.num_data_lanes; lane++) { ++ if (ep.bus.mipi_csi2.data_lanes[lane] != lane + 1) { ++ unicam_err(dev, "subdevice %pOF: data lanes reordering not supported\n", ++ sensor_node); ++ goto cleanup_exit; ++ } ++ } ++ ++ if (ep.bus.mipi_csi2.num_data_lanes > dev->max_data_lanes) { ++ unicam_err(dev, "subdevice requires %u data lanes when %u are supported\n", ++ ep.bus.mipi_csi2.num_data_lanes, ++ dev->max_data_lanes); ++ } ++ ++ dev->max_data_lanes = ep.bus.mipi_csi2.num_data_lanes; ++ dev->bus_flags = ep.bus.mipi_csi2.flags; ++ ++ break; ++ ++ case V4L2_MBUS_CCP2: ++ if (ep.bus.mipi_csi1.clock_lane != 0 || ++ ep.bus.mipi_csi1.data_lane != 1) { ++ unicam_err(dev, "subdevice %pOF: unsupported lanes configuration\n", ++ sensor_node); ++ goto cleanup_exit; ++ } ++ ++ dev->max_data_lanes = 1; ++ dev->bus_flags = ep.bus.mipi_csi1.strobe; ++ break; ++ ++ default: ++ /* Unsupported bus type */ ++ unicam_err(dev, "subdevice %pOF: unsupported bus type %u\n", ++ sensor_node, ep.bus_type); ++ goto cleanup_exit; ++ } ++ ++ unicam_dbg(3, dev, "subdevice %pOF: %s bus, %u data lanes, flags=0x%08x\n", ++ sensor_node, ++ dev->bus_type == V4L2_MBUS_CSI2_DPHY ? "CSI-2" : "CCP2", ++ dev->max_data_lanes, dev->bus_flags); ++ ++ /* Initialize and register the async notifier. */ ++ v4l2_async_notifier_init(&dev->notifier); ++ dev->notifier.ops = &unicam_async_ops; ++ ++ dev->asd.match_type = V4L2_ASYNC_MATCH_FWNODE; ++ dev->asd.match.fwnode = of_fwnode_handle(sensor_node); ++ ret = v4l2_async_notifier_add_subdev(&dev->notifier, &dev->asd); ++ if (ret) { ++ unicam_err(dev, "Error adding subdevice: %d\n", ret); ++ goto cleanup_exit; ++ } ++ ++ ret = v4l2_async_notifier_register(&dev->v4l2_dev, &dev->notifier); ++ if (ret) { ++ unicam_err(dev, "Error registering async notifier: %d\n", ret); ++ ret = -EINVAL; ++ } ++ ++cleanup_exit: ++ of_node_put(sensor_node); ++ of_node_put(ep_node); ++ ++ return ret; ++} ++ ++static int unicam_probe(struct platform_device *pdev) ++{ ++ struct unicam_device *unicam; ++ int ret; ++ ++ unicam = kzalloc(sizeof(*unicam), GFP_KERNEL); ++ if (!unicam) ++ return -ENOMEM; ++ ++ kref_init(&unicam->kref); ++ unicam->pdev = pdev; ++ ++ unicam->base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(unicam->base)) { ++ unicam_err(unicam, "Failed to get main io block\n"); ++ ret = PTR_ERR(unicam->base); ++ goto err_unicam_put; ++ } ++ ++ unicam->clk_gate_base = devm_platform_ioremap_resource(pdev, 1); ++ if (IS_ERR(unicam->clk_gate_base)) { ++ unicam_err(unicam, "Failed to get 2nd io block\n"); ++ ret = PTR_ERR(unicam->clk_gate_base); ++ goto err_unicam_put; ++ } ++ ++ unicam->clock = devm_clk_get(&pdev->dev, "lp"); ++ if (IS_ERR(unicam->clock)) { ++ unicam_err(unicam, "Failed to get clock\n"); ++ ret = PTR_ERR(unicam->clock); ++ goto err_unicam_put; ++ } ++ ++ ret = platform_get_irq(pdev, 0); ++ if (ret <= 0) { ++ dev_err(&pdev->dev, "No IRQ resource\n"); ++ ret = -EINVAL; ++ goto err_unicam_put; ++ } ++ ++ ret = devm_request_irq(&pdev->dev, ret, unicam_isr, 0, ++ "unicam_capture0", unicam); ++ if (ret) { ++ dev_err(&pdev->dev, "Unable to request interrupt\n"); ++ ret = -EINVAL; ++ goto err_unicam_put; ++ } ++ ++ unicam->mdev.dev = &pdev->dev; ++ strscpy(unicam->mdev.model, UNICAM_MODULE_NAME, ++ sizeof(unicam->mdev.model)); ++ strscpy(unicam->mdev.serial, "", sizeof(unicam->mdev.serial)); ++ snprintf(unicam->mdev.bus_info, sizeof(unicam->mdev.bus_info), ++ "platform:%s", dev_name(&pdev->dev)); ++ unicam->mdev.hw_revision = 0; ++ ++ media_device_init(&unicam->mdev); ++ ++ unicam->v4l2_dev.mdev = &unicam->mdev; ++ ++ ret = v4l2_device_register(&pdev->dev, &unicam->v4l2_dev); ++ if (ret) { ++ unicam_err(unicam, ++ "Unable to register v4l2 device.\n"); ++ goto err_unicam_put; ++ } ++ ++ ret = media_device_register(&unicam->mdev); ++ if (ret < 0) { ++ unicam_err(unicam, ++ "Unable to register media-controller device.\n"); ++ goto err_v4l2_unregister; ++ } ++ ++ /* Reserve space for the controls */ ++ ret = v4l2_ctrl_handler_init(&unicam->ctrl_handler, 16); ++ if (ret < 0) ++ goto err_media_unregister; ++ ++ /* set the driver data in platform device */ ++ platform_set_drvdata(pdev, unicam); ++ ++ ret = of_unicam_connect_subdevs(unicam); ++ if (ret) { ++ dev_err(&pdev->dev, "Failed to connect subdevs\n"); ++ goto err_media_unregister; ++ } ++ ++ /* Enable the block power domain */ ++ pm_runtime_enable(&pdev->dev); ++ ++ return 0; ++ ++err_media_unregister: ++ media_device_unregister(&unicam->mdev); ++err_v4l2_unregister: ++ v4l2_device_unregister(&unicam->v4l2_dev); ++err_unicam_put: ++ unicam_put(unicam); ++ ++ return ret; ++} ++ ++static int unicam_remove(struct platform_device *pdev) ++{ ++ struct unicam_device *unicam = platform_get_drvdata(pdev); ++ ++ unicam_dbg(2, unicam, "%s\n", __func__); ++ ++ v4l2_async_notifier_unregister(&unicam->notifier); ++ v4l2_device_unregister(&unicam->v4l2_dev); ++ media_device_unregister(&unicam->mdev); ++ unregister_nodes(unicam); ++ ++ pm_runtime_disable(&pdev->dev); ++ ++ return 0; ++} ++ ++static const struct of_device_id unicam_of_match[] = { ++ { .compatible = "brcm,bcm2835-unicam", }, ++ { /* sentinel */ }, ++}; ++MODULE_DEVICE_TABLE(of, unicam_of_match); ++ ++static struct platform_driver unicam_driver = { ++ .probe = unicam_probe, ++ .remove = unicam_remove, ++ .driver = { ++ .name = UNICAM_MODULE_NAME, ++ .of_match_table = of_match_ptr(unicam_of_match), ++ }, ++}; ++ ++module_platform_driver(unicam_driver); ++ ++MODULE_AUTHOR("Dave Stevenson <dave.stevenson@raspberrypi.com>"); ++MODULE_DESCRIPTION("BCM2835 Unicam driver"); ++MODULE_LICENSE("GPL"); ++MODULE_VERSION(UNICAM_VERSION); +--- /dev/null ++++ b/drivers/media/platform/bcm2835/vc4-regs-unicam.h +@@ -0,0 +1,253 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++/* ++ * Copyright (C) 2017-2020 Raspberry Pi Trading. ++ * Dave Stevenson <dave.stevenson@raspberrypi.com> ++ */ ++ ++#ifndef VC4_REGS_UNICAM_H ++#define VC4_REGS_UNICAM_H ++ ++/* ++ * The following values are taken from files found within the code drop ++ * made by Broadcom for the BCM21553 Graphics Driver, predominantly in ++ * brcm_usrlib/dag/vmcsx/vcinclude/hardware_vc4.h. ++ * They have been modified to be only the register offset. ++ */ ++#define UNICAM_CTRL 0x000 ++#define UNICAM_STA 0x004 ++#define UNICAM_ANA 0x008 ++#define UNICAM_PRI 0x00c ++#define UNICAM_CLK 0x010 ++#define UNICAM_CLT 0x014 ++#define UNICAM_DAT0 0x018 ++#define UNICAM_DAT1 0x01c ++#define UNICAM_DAT2 0x020 ++#define UNICAM_DAT3 0x024 ++#define UNICAM_DLT 0x028 ++#define UNICAM_CMP0 0x02c ++#define UNICAM_CMP1 0x030 ++#define UNICAM_CAP0 0x034 ++#define UNICAM_CAP1 0x038 ++#define UNICAM_ICTL 0x100 ++#define UNICAM_ISTA 0x104 ++#define UNICAM_IDI0 0x108 ++#define UNICAM_IPIPE 0x10c ++#define UNICAM_IBSA0 0x110 ++#define UNICAM_IBEA0 0x114 ++#define UNICAM_IBLS 0x118 ++#define UNICAM_IBWP 0x11c ++#define UNICAM_IHWIN 0x120 ++#define UNICAM_IHSTA 0x124 ++#define UNICAM_IVWIN 0x128 ++#define UNICAM_IVSTA 0x12c ++#define UNICAM_ICC 0x130 ++#define UNICAM_ICS 0x134 ++#define UNICAM_IDC 0x138 ++#define UNICAM_IDPO 0x13c ++#define UNICAM_IDCA 0x140 ++#define UNICAM_IDCD 0x144 ++#define UNICAM_IDS 0x148 ++#define UNICAM_DCS 0x200 ++#define UNICAM_DBSA0 0x204 ++#define UNICAM_DBEA0 0x208 ++#define UNICAM_DBWP 0x20c ++#define UNICAM_DBCTL 0x300 ++#define UNICAM_IBSA1 0x304 ++#define UNICAM_IBEA1 0x308 ++#define UNICAM_IDI1 0x30c ++#define UNICAM_DBSA1 0x310 ++#define UNICAM_DBEA1 0x314 ++#define UNICAM_MISC 0x400 ++ ++/* ++ * The following bitmasks are from the kernel released by Broadcom ++ * for Android - https://android.googlesource.com/kernel/bcm/ ++ * The Rhea, Hawaii, and Java chips all contain the same VideoCore4 ++ * Unicam block as BCM2835, as defined in eg ++ * arch/arm/mach-rhea/include/mach/rdb_A0/brcm_rdb_cam.h and similar. ++ * Values reworked to use the kernel BIT and GENMASK macros. ++ * ++ * Some of the bit mnenomics have been amended to match the datasheet. ++ */ ++/* UNICAM_CTRL Register */ ++#define UNICAM_CPE BIT(0) ++#define UNICAM_MEM BIT(1) ++#define UNICAM_CPR BIT(2) ++#define UNICAM_CPM_MASK GENMASK(3, 3) ++#define UNICAM_CPM_CSI2 0 ++#define UNICAM_CPM_CCP2 1 ++#define UNICAM_SOE BIT(4) ++#define UNICAM_DCM_MASK GENMASK(5, 5) ++#define UNICAM_DCM_STROBE 0 ++#define UNICAM_DCM_DATA 1 ++#define UNICAM_SLS BIT(6) ++#define UNICAM_PFT_MASK GENMASK(11, 8) ++#define UNICAM_OET_MASK GENMASK(20, 12) ++ ++/* UNICAM_STA Register */ ++#define UNICAM_SYN BIT(0) ++#define UNICAM_CS BIT(1) ++#define UNICAM_SBE BIT(2) ++#define UNICAM_PBE BIT(3) ++#define UNICAM_HOE BIT(4) ++#define UNICAM_PLE BIT(5) ++#define UNICAM_SSC BIT(6) ++#define UNICAM_CRCE BIT(7) ++#define UNICAM_OES BIT(8) ++#define UNICAM_IFO BIT(9) ++#define UNICAM_OFO BIT(10) ++#define UNICAM_BFO BIT(11) ++#define UNICAM_DL BIT(12) ++#define UNICAM_PS BIT(13) ++#define UNICAM_IS BIT(14) ++#define UNICAM_PI0 BIT(15) ++#define UNICAM_PI1 BIT(16) ++#define UNICAM_FSI_S BIT(17) ++#define UNICAM_FEI_S BIT(18) ++#define UNICAM_LCI_S BIT(19) ++#define UNICAM_BUF0_RDY BIT(20) ++#define UNICAM_BUF0_NO BIT(21) ++#define UNICAM_BUF1_RDY BIT(22) ++#define UNICAM_BUF1_NO BIT(23) ++#define UNICAM_DI BIT(24) ++ ++#define UNICAM_STA_MASK_ALL \ ++ (UNICAM_DL + \ ++ UNICAM_SBE + \ ++ UNICAM_PBE + \ ++ UNICAM_HOE + \ ++ UNICAM_PLE + \ ++ UNICAM_SSC + \ ++ UNICAM_CRCE + \ ++ UNICAM_IFO + \ ++ UNICAM_OFO + \ ++ UNICAM_PS + \ ++ UNICAM_PI0 + \ ++ UNICAM_PI1) ++ ++/* UNICAM_ANA Register */ ++#define UNICAM_APD BIT(0) ++#define UNICAM_BPD BIT(1) ++#define UNICAM_AR BIT(2) ++#define UNICAM_DDL BIT(3) ++#define UNICAM_CTATADJ_MASK GENMASK(7, 4) ++#define UNICAM_PTATADJ_MASK GENMASK(11, 8) ++ ++/* UNICAM_PRI Register */ ++#define UNICAM_PE BIT(0) ++#define UNICAM_PT_MASK GENMASK(2, 1) ++#define UNICAM_NP_MASK GENMASK(7, 4) ++#define UNICAM_PP_MASK GENMASK(11, 8) ++#define UNICAM_BS_MASK GENMASK(15, 12) ++#define UNICAM_BL_MASK GENMASK(17, 16) ++ ++/* UNICAM_CLK Register */ ++#define UNICAM_CLE BIT(0) ++#define UNICAM_CLPD BIT(1) ++#define UNICAM_CLLPE BIT(2) ++#define UNICAM_CLHSE BIT(3) ++#define UNICAM_CLTRE BIT(4) ++#define UNICAM_CLAC_MASK GENMASK(8, 5) ++#define UNICAM_CLSTE BIT(29) ++ ++/* UNICAM_CLT Register */ ++#define UNICAM_CLT1_MASK GENMASK(7, 0) ++#define UNICAM_CLT2_MASK GENMASK(15, 8) ++ ++/* UNICAM_DATn Registers */ ++#define UNICAM_DLE BIT(0) ++#define UNICAM_DLPD BIT(1) ++#define UNICAM_DLLPE BIT(2) ++#define UNICAM_DLHSE BIT(3) ++#define UNICAM_DLTRE BIT(4) ++#define UNICAM_DLSM BIT(5) ++#define UNICAM_DLFO BIT(28) ++#define UNICAM_DLSTE BIT(29) ++ ++#define UNICAM_DAT_MASK_ALL (UNICAM_DLSTE + UNICAM_DLFO) ++ ++/* UNICAM_DLT Register */ ++#define UNICAM_DLT1_MASK GENMASK(7, 0) ++#define UNICAM_DLT2_MASK GENMASK(15, 8) ++#define UNICAM_DLT3_MASK GENMASK(23, 16) ++ ++/* UNICAM_ICTL Register */ ++#define UNICAM_FSIE BIT(0) ++#define UNICAM_FEIE BIT(1) ++#define UNICAM_IBOB BIT(2) ++#define UNICAM_FCM BIT(3) ++#define UNICAM_TFC BIT(4) ++#define UNICAM_LIP_MASK GENMASK(6, 5) ++#define UNICAM_LCIE_MASK GENMASK(28, 16) ++ ++/* UNICAM_IDI0/1 Register */ ++#define UNICAM_ID0_MASK GENMASK(7, 0) ++#define UNICAM_ID1_MASK GENMASK(15, 8) ++#define UNICAM_ID2_MASK GENMASK(23, 16) ++#define UNICAM_ID3_MASK GENMASK(31, 24) ++ ++/* UNICAM_ISTA Register */ ++#define UNICAM_FSI BIT(0) ++#define UNICAM_FEI BIT(1) ++#define UNICAM_LCI BIT(2) ++ ++#define UNICAM_ISTA_MASK_ALL (UNICAM_FSI + UNICAM_FEI + UNICAM_LCI) ++ ++/* UNICAM_IPIPE Register */ ++#define UNICAM_PUM_MASK GENMASK(2, 0) ++ /* Unpacking modes */ ++ #define UNICAM_PUM_NONE 0 ++ #define UNICAM_PUM_UNPACK6 1 ++ #define UNICAM_PUM_UNPACK7 2 ++ #define UNICAM_PUM_UNPACK8 3 ++ #define UNICAM_PUM_UNPACK10 4 ++ #define UNICAM_PUM_UNPACK12 5 ++ #define UNICAM_PUM_UNPACK14 6 ++ #define UNICAM_PUM_UNPACK16 7 ++#define UNICAM_DDM_MASK GENMASK(6, 3) ++#define UNICAM_PPM_MASK GENMASK(9, 7) ++ /* Packing modes */ ++ #define UNICAM_PPM_NONE 0 ++ #define UNICAM_PPM_PACK8 1 ++ #define UNICAM_PPM_PACK10 2 ++ #define UNICAM_PPM_PACK12 3 ++ #define UNICAM_PPM_PACK14 4 ++ #define UNICAM_PPM_PACK16 5 ++#define UNICAM_DEM_MASK GENMASK(11, 10) ++#define UNICAM_DEBL_MASK GENMASK(14, 12) ++#define UNICAM_ICM_MASK GENMASK(16, 15) ++#define UNICAM_IDM_MASK GENMASK(17, 17) ++ ++/* UNICAM_ICC Register */ ++#define UNICAM_ICFL_MASK GENMASK(4, 0) ++#define UNICAM_ICFH_MASK GENMASK(9, 5) ++#define UNICAM_ICST_MASK GENMASK(12, 10) ++#define UNICAM_ICLT_MASK GENMASK(15, 13) ++#define UNICAM_ICLL_MASK GENMASK(31, 16) ++ ++/* UNICAM_DCS Register */ ++#define UNICAM_DIE BIT(0) ++#define UNICAM_DIM BIT(1) ++#define UNICAM_DBOB BIT(3) ++#define UNICAM_FDE BIT(4) ++#define UNICAM_LDP BIT(5) ++#define UNICAM_EDL_MASK GENMASK(15, 8) ++ ++/* UNICAM_DBCTL Register */ ++#define UNICAM_DBEN BIT(0) ++#define UNICAM_BUF0_IE BIT(1) ++#define UNICAM_BUF1_IE BIT(2) ++ ++/* UNICAM_CMP[0,1] register */ ++#define UNICAM_PCE BIT(31) ++#define UNICAM_GI BIT(9) ++#define UNICAM_CPH BIT(8) ++#define UNICAM_PCVC_MASK GENMASK(7, 6) ++#define UNICAM_PCDT_MASK GENMASK(5, 0) ++ ++/* UNICAM_MISC register */ ++#define UNICAM_FL0 BIT(6) ++#define UNICAM_FL1 BIT(9) ++ ++#endif diff --git a/target/linux/bcm27xx/patches-5.4/950-0807-media-bcm2835-unicam-Add-support-for-get_mbus_config.patch b/target/linux/bcm27xx/patches-5.4/950-0807-media-bcm2835-unicam-Add-support-for-get_mbus_config.patch new file mode 100644 index 0000000000..8e3cef06d4 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0807-media-bcm2835-unicam-Add-support-for-get_mbus_config.patch @@ -0,0 +1,56 @@ +From f1ab20a9584c97eddf07d4f8937f0aff42bd1038 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 23 Jun 2020 14:32:51 +0100 +Subject: [PATCH] media: bcm2835-unicam: Add support for + get_mbus_config to set num lanes + +Use the get_mbus_config pad subdev call to allow a source to use +fewer than the number of CSI2 lanes defined in device tree. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + .../media/platform/bcm2835/bcm2835-unicam.c | 31 ++++++++++++++++--- + 1 file changed, 27 insertions(+), 4 deletions(-) + +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -1639,12 +1639,35 @@ static int unicam_start_streaming(struct + goto err_streaming; + } + +- /* +- * TODO: Retrieve the number of active data lanes from the connected +- * subdevice. +- */ + dev->active_data_lanes = dev->max_data_lanes; + ++ if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { ++ struct v4l2_mbus_config mbus_config = { 0 }; ++ ++ ret = v4l2_subdev_call(dev->sensor, pad, get_mbus_config, ++ 0, &mbus_config); ++ if (ret < 0 && ret != -ENOIOCTLCMD) { ++ unicam_dbg(3, dev, "g_mbus_config failed\n"); ++ goto err_pm_put; ++ } ++ ++ dev->active_data_lanes = ++ (mbus_config.flags & V4L2_MBUS_CSI2_LANE_MASK) >> ++ __ffs(V4L2_MBUS_CSI2_LANE_MASK); ++ if (!dev->active_data_lanes) ++ dev->active_data_lanes = dev->max_data_lanes; ++ if (dev->active_data_lanes > dev->max_data_lanes) { ++ unicam_err(dev, "Device has requested %u data lanes, which is >%u configured in DT\n", ++ dev->active_data_lanes, ++ dev->max_data_lanes); ++ ret = -EINVAL; ++ goto err_pm_put; ++ } ++ } ++ ++ unicam_dbg(1, dev, "Running with %u data lanes\n", ++ dev->active_data_lanes); ++ + ret = clk_set_rate(dev->clock, 100 * 1000 * 1000); + if (ret) { + unicam_err(dev, "failed to set up clock\n"); diff --git a/target/linux/bcm27xx/patches-5.4/950-0808-media-bcm2835-unicam-Always-service-interrupts.patch b/target/linux/bcm27xx/patches-5.4/950-0808-media-bcm2835-unicam-Always-service-interrupts.patch new file mode 100644 index 0000000000..371013fe60 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0808-media-bcm2835-unicam-Always-service-interrupts.patch @@ -0,0 +1,51 @@ +From b493e2a03c1780ae1ba09a9de58474c17a33310d Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Wed, 13 May 2020 18:28:27 +0100 +Subject: [PATCH] media: bcm2835-unicam: Always service interrupts + +From when bringing up the driver, there was a check in the isr +to ignore interrupts (claiming them handled) should the driver +not be streaming. + +The VPU now will not register a camera driver if it finds a +CSI2 node enabled in device tree, therefore this flawed check is +redundant. + +https://github.com/raspberrypi/linux/issues/3602 + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/platform/bcm2835/bcm2835-unicam.c | 15 --------------- + 1 file changed, 15 deletions(-) + +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -772,12 +772,6 @@ static bool unicam_all_nodes_streaming(s + return ret; + } + +-static bool unicam_all_nodes_disabled(struct unicam_device *dev) +-{ +- return !dev->node[IMAGE_PAD].streaming && +- !dev->node[METADATA_PAD].streaming; +-} +- + static void unicam_queue_event_sof(struct unicam_device *unicam) + { + struct v4l2_event event = { +@@ -805,15 +799,6 @@ static irqreturn_t unicam_isr(int irq, v + u32 ista, sta; + u64 ts; + +- /* +- * Don't service interrupts if not streaming. +- * Avoids issues if the VPU should enable the +- * peripheral without the kernel knowing (that +- * shouldn't happen, but causes issues if it does). +- */ +- if (unicam_all_nodes_disabled(unicam)) +- return IRQ_NONE; +- + sta = reg_read(unicam, UNICAM_STA); + /* Write value back to clear the interrupts */ + reg_write(unicam, UNICAM_STA, sta); diff --git a/target/linux/bcm27xx/patches-5.4/950-0809-media-bcm2835-unicam-Fix-uninitialized-warning.patch b/target/linux/bcm27xx/patches-5.4/950-0809-media-bcm2835-unicam-Fix-uninitialized-warning.patch new file mode 100644 index 0000000000..1935c6b78f --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0809-media-bcm2835-unicam-Fix-uninitialized-warning.patch @@ -0,0 +1,21 @@ +From bea7aa3af93ab5eb9b0f993230a802e65023081e Mon Sep 17 00:00:00 2001 +From: Jacko Dirks <jdirks.linuxdev@gmail.com> +Date: Tue, 5 May 2020 14:33:31 +0200 +Subject: [PATCH] media: bcm2835: unicam: Fix uninitialized warning + +Signed-off-by: Jacko Dirks <jdirks.linuxdev@gmail.com> +--- + drivers/media/platform/bcm2835/bcm2835-unicam.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -994,7 +994,7 @@ const struct unicam_fmt *get_first_suppo + struct v4l2_subdev_mbus_code_enum mbus_code; + const struct unicam_fmt *fmt = NULL; + unsigned int i; +- int ret; ++ int ret = 0; + + for (i = 0; ret != -EINVAL && ret != -ENOIOCTLCMD; ++i) { + memset(&mbus_code, 0, sizeof(mbus_code)); diff --git a/target/linux/bcm27xx/patches-5.4/950-0810-media-bcm2835-unicam-Fixup-review-comments-from-Hans.patch b/target/linux/bcm27xx/patches-5.4/950-0810-media-bcm2835-unicam-Fixup-review-comments-from-Hans.patch new file mode 100644 index 0000000000..18565a7933 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0810-media-bcm2835-unicam-Fixup-review-comments-from-Hans.patch @@ -0,0 +1,242 @@ +From 30351afb528e439a48960443c028b6b9c236c55a Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 23 Jun 2020 15:14:05 +0100 +Subject: [PATCH] media: bcm2835-unicam: Fixup review comments from + Hans. + +Updates the driver based on the upstream review comments from +Hans Verkuil at https://patchwork.linuxtv.org/patch/63531/ + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/platform/bcm2835/Kconfig | 12 ++-- + .../media/platform/bcm2835/bcm2835-unicam.c | 70 ++++++++----------- + 2 files changed, 39 insertions(+), 43 deletions(-) + +--- a/drivers/media/platform/bcm2835/Kconfig ++++ b/drivers/media/platform/bcm2835/Kconfig +@@ -1,15 +1,19 @@ + # Broadcom VideoCore4 V4L2 camera support + + config VIDEO_BCM2835_UNICAM +- tristate "Broadcom BCM2835 Unicam video capture driver" ++ tristate "Broadcom BCM283x/BCM271x Unicam video capture driver" + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER + depends on ARCH_BCM2835 || COMPILE_TEST + select VIDEOBUF2_DMA_CONTIG + select V4L2_FWNODE + help +- Say Y here to enable support for the BCM2835 CSI-2 receiver. This is a +- V4L2 driver that controls the CSI-2 receiver directly, independently +- from the VC4 firmware. ++ Say Y here to enable support for the BCM283x/BCM271x CSI-2 receiver. ++ This is a V4L2 driver that controls the CSI-2 receiver directly, ++ independently from the VC4 firmware. ++ This driver is mutually exclusive with the use of bcm2835-camera. The ++ firmware will disable all access to the peripheral from within the ++ firmware if it finds a DT node using it, and bcm2835-camera will ++ therefore fail to probe. + + To compile this driver as a module, choose M here. The module will be + called bcm2835-unicam. +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* +- * BCM2835 Unicam Capture Driver ++ * BCM283x / BCM271x Unicam Capture Driver + * + * Copyright (C) 2017-2020 - Raspberry Pi (Trading) Ltd. + * +@@ -554,9 +554,8 @@ static const struct unicam_fmt *find_for + return NULL; + } + +-static inline unsigned int bytes_per_line(u32 width, +- const struct unicam_fmt *fmt, +- u32 v4l2_fourcc) ++static unsigned int bytes_per_line(u32 width, const struct unicam_fmt *fmt, ++ u32 v4l2_fourcc) + { + if (v4l2_fourcc == fmt->repacked_fourcc) + /* Repacking always goes to 16bpp */ +@@ -708,7 +707,7 @@ static void unicam_wr_dma_addr(struct un + } + } + +-static inline unsigned int unicam_get_lines_done(struct unicam_device *dev) ++static unsigned int unicam_get_lines_done(struct unicam_device *dev) + { + dma_addr_t start_addr, cur_addr; + unsigned int stride = dev->node[IMAGE_PAD].v_fmt.fmt.pix.bytesperline; +@@ -722,7 +721,7 @@ static inline unsigned int unicam_get_li + return (unsigned int)(cur_addr - start_addr) / stride; + } + +-static inline void unicam_schedule_next_buffer(struct unicam_node *node) ++static void unicam_schedule_next_buffer(struct unicam_node *node) + { + struct unicam_device *dev = node->dev; + struct unicam_buffer *buf; +@@ -741,7 +740,7 @@ static inline void unicam_schedule_next_ + unicam_wr_dma_addr(dev, addr, size, node->pad_id); + } + +-static inline void unicam_schedule_dummy_buffer(struct unicam_node *node) ++static void unicam_schedule_dummy_buffer(struct unicam_node *node) + { + struct unicam_device *dev = node->dev; + +@@ -753,8 +752,8 @@ static inline void unicam_schedule_dummy + node->next_frm = NULL; + } + +-static inline void unicam_process_buffer_complete(struct unicam_node *node, +- unsigned int sequence) ++static void unicam_process_buffer_complete(struct unicam_node *node, ++ unsigned int sequence) + { + node->cur_frm->vb.field = node->m_fmt.field; + node->cur_frm->vb.sequence = sequence; +@@ -762,16 +761,6 @@ static inline void unicam_process_buffer + vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE); + } + +-static bool unicam_all_nodes_streaming(struct unicam_device *dev) +-{ +- bool ret; +- +- ret = dev->node[IMAGE_PAD].open && dev->node[IMAGE_PAD].streaming; +- ret &= !dev->node[METADATA_PAD].open || +- dev->node[METADATA_PAD].streaming; +- return ret; +-} +- + static void unicam_queue_event_sof(struct unicam_device *unicam) + { + struct v4l2_event event = { +@@ -894,8 +883,8 @@ static int unicam_querycap(struct file * + struct unicam_node *node = video_drvdata(file); + struct unicam_device *dev = node->dev; + +- strlcpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver)); +- strlcpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card)); ++ strscpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver)); ++ strscpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card)); + + snprintf(cap->bus_info, sizeof(cap->bus_info), + "platform:%s", dev_name(&dev->pdev->dev)); +@@ -988,8 +977,8 @@ static int unicam_g_fmt_vid_cap(struct f + return 0; + } + +-static +-const struct unicam_fmt *get_first_supported_format(struct unicam_device *dev) ++static const struct unicam_fmt * ++get_first_supported_format(struct unicam_device *dev) + { + struct v4l2_subdev_mbus_code_enum mbus_code; + const struct unicam_fmt *fmt = NULL; +@@ -1579,7 +1568,8 @@ static void unicam_disable(struct unicam + clk_write(dev, 0); + } + +-static void unicam_return_buffers(struct unicam_node *node) ++static void unicam_return_buffers(struct unicam_node *node, ++ enum vb2_buffer_state state) + { + struct unicam_buffer *buf, *tmp; + unsigned long flags; +@@ -1587,15 +1577,15 @@ static void unicam_return_buffers(struct + spin_lock_irqsave(&node->dma_queue_lock, flags); + list_for_each_entry_safe(buf, tmp, &node->dma_queue, list) { + list_del(&buf->list); +- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); ++ vb2_buffer_done(&buf->vb.vb2_buf, state); + } + + if (node->cur_frm) + vb2_buffer_done(&node->cur_frm->vb.vb2_buf, +- VB2_BUF_STATE_ERROR); ++ state); + if (node->next_frm && node->cur_frm != node->next_frm) + vb2_buffer_done(&node->next_frm->vb.vb2_buf, +- VB2_BUF_STATE_ERROR); ++ state); + + node->cur_frm = NULL; + node->next_frm = NULL; +@@ -1612,7 +1602,13 @@ static int unicam_start_streaming(struct + int ret; + + node->streaming = true; +- if (!unicam_all_nodes_streaming(dev)) { ++ if (!(dev->node[IMAGE_PAD].open && dev->node[IMAGE_PAD].streaming && ++ (!dev->node[METADATA_PAD].open || ++ dev->node[METADATA_PAD].streaming))) { ++ /* ++ * Metadata pad must be enabled before image pad if it is ++ * wanted. ++ */ + unicam_dbg(3, dev, "Not all nodes are streaming yet."); + return 0; + } +@@ -1699,7 +1695,7 @@ err_disable_unicam: + err_pm_put: + unicam_runtime_put(dev); + err_streaming: +- unicam_return_buffers(node); ++ unicam_return_buffers(node, VB2_BUF_STATE_QUEUED); + node->streaming = false; + + return ret; +@@ -1736,7 +1732,7 @@ static void unicam_stop_streaming(struct + } + + /* Clear all queued buffers for the node */ +- unicam_return_buffers(node); ++ unicam_return_buffers(node, VB2_BUF_STATE_ERROR); + } + + static int unicam_enum_input(struct file *file, void *priv, +@@ -1754,14 +1750,13 @@ static int unicam_enum_input(struct file + inp->std = 0; + } else if (v4l2_subdev_has_op(dev->sensor, video, s_std)) { + inp->capabilities = V4L2_IN_CAP_STD; +- if (v4l2_subdev_call(dev->sensor, video, g_tvnorms, &inp->std) +- < 0) ++ if (v4l2_subdev_call(dev->sensor, video, g_tvnorms, &inp->std) < 0) + inp->std = V4L2_STD_ALL; + } else { + inp->capabilities = 0; + inp->std = 0; + } +- sprintf(inp->name, "Camera 0"); ++ snprintf(inp->name, sizeof(inp->name), "Camera 0"); + return 0; + } + +@@ -1984,6 +1979,9 @@ static int unicam_s_dv_timings(struct fi + ret = v4l2_subdev_call(dev->sensor, video, g_dv_timings, + ¤t_timings); + ++ if (ret < 0) ++ return ret; ++ + if (v4l2_match_dv_timings(timings, ¤t_timings, 0, false)) + return 0; + +@@ -2414,12 +2412,6 @@ static int register_node(struct unicam_d + unicam_err(unicam, "Unable to allocate dummy buffer.\n"); + return -ENOMEM; + } +- +- if (pad_id == METADATA_PAD) { +- v4l2_disable_ioctl(vdev, VIDIOC_DQEVENT); +- v4l2_disable_ioctl(vdev, VIDIOC_SUBSCRIBE_EVENT); +- v4l2_disable_ioctl(vdev, VIDIOC_UNSUBSCRIBE_EVENT); +- } + if (pad_id == METADATA_PAD || + !v4l2_subdev_has_op(unicam->sensor, video, s_std)) { + v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_STD); diff --git a/target/linux/bcm27xx/patches-5.4/950-0811-media-bcm2835-unicam-Retain-packing-information-on-G.patch b/target/linux/bcm27xx/patches-5.4/950-0811-media-bcm2835-unicam-Retain-packing-information-on-G.patch new file mode 100644 index 0000000000..8d2b9d8ea3 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0811-media-bcm2835-unicam-Retain-packing-information-on-G.patch @@ -0,0 +1,48 @@ +From bf722c887dd9d0d24493edd20c61b2fcde5f66dd Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 19 May 2020 11:46:47 +0100 +Subject: [PATCH] media: bcm2835-unicam: Retain packing information + on G_FMT + +The change to retrieve the pixel format always on g_fmt didn't +check whether the native or unpacked version of the format +had been requested, and always returned the packed one. +Correct this so that the packing setting is retained whereever +possible. + +Fixes "9d59e89 media: bcm2835-unicam: Re-fetch mbus code from subdev +on a g_fmt call" + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + .../media/platform/bcm2835/bcm2835-unicam.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -970,8 +970,23 @@ static int unicam_g_fmt_vid_cap(struct f + if (!fmt) + return -EINVAL; + +- node->fmt = fmt; +- node->v_fmt.fmt.pix.pixelformat = fmt->fourcc; ++ if (node->fmt != fmt) { ++ /* ++ * The sensor format has changed so the pixelformat needs to ++ * be updated. Try and retain the packed/unpacked choice if ++ * at all possible. ++ */ ++ if (node->fmt->repacked_fourcc == ++ node->v_fmt.fmt.pix.pixelformat) ++ /* Using the repacked format */ ++ node->v_fmt.fmt.pix.pixelformat = fmt->repacked_fourcc; ++ else ++ /* Using the native format */ ++ node->v_fmt.fmt.pix.pixelformat = fmt->fourcc; ++ ++ node->fmt = fmt; ++ } ++ + *f = node->v_fmt; + + return 0; diff --git a/target/linux/bcm27xx/patches-5.4/950-0812-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch b/target/linux/bcm27xx/patches-5.4/950-0812-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch new file mode 100644 index 0000000000..770b00b88a --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0812-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch @@ -0,0 +1,28 @@ +From 4f745137c92902f4f541ebe5e458dd2c4e89a42d Mon Sep 17 00:00:00 2001 +From: David Plowman <david.plowman@raspberrypi.com> +Date: Thu, 28 May 2020 11:09:48 +0100 +Subject: [PATCH] media: bcm2835-unicam: change minimum number of + vb2_queue buffers to 1 + +Since the unicam driver was modified to write to a dummy buffer when no +user-supplied buffer is available, it can now write to and return a +buffer even when there's only a single one. Enable this by changing the +min_buffers_needed in the vb2_queue; it will be useful for enabling +still captures without allocating more memory than absolutely necessary. + +Signed-off-by: David Plowman <david.plowman@raspberrypi.com> +--- + drivers/media/platform/bcm2835/bcm2835-unicam.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -2387,7 +2387,7 @@ static int register_node(struct unicam_d + q->buf_struct_size = sizeof(struct unicam_buffer); + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->lock = &node->lock; +- q->min_buffers_needed = 2; ++ q->min_buffers_needed = 1; + q->dev = &unicam->pdev->dev; + + ret = vb2_queue_init(q); diff --git a/target/linux/bcm27xx/patches-5.4/950-0813-dt-dtoverlays-Fix-up-base-DT-and-overlays-for-update.patch b/target/linux/bcm27xx/patches-5.4/950-0813-dt-dtoverlays-Fix-up-base-DT-and-overlays-for-update.patch new file mode 100644 index 0000000000..edfca1ed67 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0813-dt-dtoverlays-Fix-up-base-DT-and-overlays-for-update.patch @@ -0,0 +1,144 @@ +From 7a1905f969cfa2e303f5e74efee56dbd0523e5bb Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 23 Jun 2020 15:41:42 +0100 +Subject: [PATCH] dt/dtoverlays: Fix up base DT and overlays for + updated Unicam driver + +The upstreamed Unicam driver uses a dt property to denote how many +lanes are supported by the receiver peripheral, independent of +the number of lanes that the sensor wants to use. It also doesn't +check the remote endpoint config for the number of lanes as that +isn't the accepted way of doing things. + +Update the base DT for the brcm,num-data-lanes property, and the +overlays to define the desired number of lanes at both ends of +the link. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 3 ++- + arch/arm/boot/dts/bcm283x-rpi-csi0-2lane.dtsi | 6 +----- + arch/arm/boot/dts/bcm283x-rpi-csi1-2lane.dtsi | 6 +----- + arch/arm/boot/dts/bcm283x-rpi-csi1-4lane.dtsi | 6 +----- + arch/arm/boot/dts/overlays/adv7282m-overlay.dts | 1 + + arch/arm/boot/dts/overlays/imx477-overlay.dts | 1 + + arch/arm/boot/dts/overlays/irs1125-overlay.dts | 2 ++ + arch/arm/boot/dts/overlays/ov5647-overlay.dts | 1 + + arch/arm/boot/dts/overlays/tc358743-overlay.dts | 16 +++++++++++++++- + 9 files changed, 25 insertions(+), 17 deletions(-) + +--- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts +@@ -203,7 +203,8 @@ + }; + + #include "bcm2711-rpi.dtsi" +-#include "bcm283x-rpi-csi1-2lane.dtsi" ++#include "bcm283x-rpi-csi0-2lane.dtsi" ++#include "bcm283x-rpi-csi1-4lane.dtsi" + #include "bcm283x-rpi-i2c0mux_0_44.dtsi" + + /delete-node/ &emmc2; +--- a/arch/arm/boot/dts/bcm283x-rpi-csi0-2lane.dtsi ++++ b/arch/arm/boot/dts/bcm283x-rpi-csi0-2lane.dtsi +@@ -1,8 +1,4 @@ + // SPDX-License-Identifier: GPL-2.0-only + &csi0 { +- port { +- endpoint { +- data-lanes = <1 2>; +- }; +- }; ++ brcm,num-data-lanes = <2>; + }; +--- a/arch/arm/boot/dts/bcm283x-rpi-csi1-2lane.dtsi ++++ b/arch/arm/boot/dts/bcm283x-rpi-csi1-2lane.dtsi +@@ -1,8 +1,4 @@ + // SPDX-License-Identifier: GPL-2.0-only + &csi1 { +- port { +- endpoint { +- data-lanes = <1 2>; +- }; +- }; ++ brcm,num-data-lanes = <2>; + }; +--- a/arch/arm/boot/dts/bcm283x-rpi-csi1-4lane.dtsi ++++ b/arch/arm/boot/dts/bcm283x-rpi-csi1-4lane.dtsi +@@ -1,8 +1,4 @@ + // SPDX-License-Identifier: GPL-2.0-only + &csi1 { +- port { +- endpoint { +- data-lanes = <1 2 3 4>; +- }; +- }; ++ brcm,num-data-lanes = <4>; + }; +--- a/arch/arm/boot/dts/overlays/adv7282m-overlay.dts ++++ b/arch/arm/boot/dts/overlays/adv7282m-overlay.dts +@@ -40,6 +40,7 @@ + port { + csi1_ep: endpoint { + remote-endpoint = <&adv728x_0>; ++ data-lanes = <1>; + }; + }; + }; +--- a/arch/arm/boot/dts/overlays/imx477-overlay.dts ++++ b/arch/arm/boot/dts/overlays/imx477-overlay.dts +@@ -49,6 +49,7 @@ + port { + csi1_ep: endpoint { + remote-endpoint = <&imx477_0>; ++ data-lanes = <1 2>; + }; + }; + }; +--- a/arch/arm/boot/dts/overlays/irs1125-overlay.dts ++++ b/arch/arm/boot/dts/overlays/irs1125-overlay.dts +@@ -43,6 +43,8 @@ + port { + csi1_ep: endpoint { + remote-endpoint = <&irs1125_0>; ++ data-lanes = <1 2>; ++ clock-noncontinuous; + }; + }; + }; +--- a/arch/arm/boot/dts/overlays/ov5647-overlay.dts ++++ b/arch/arm/boot/dts/overlays/ov5647-overlay.dts +@@ -43,6 +43,7 @@ + port { + csi1_ep: endpoint { + remote-endpoint = <&ov5647_0>; ++ data-lanes = <1 2>; + }; + }; + }; +--- a/arch/arm/boot/dts/overlays/tc358743-overlay.dts ++++ b/arch/arm/boot/dts/overlays/tc358743-overlay.dts +@@ -86,8 +86,22 @@ + }; + }; + ++ fragment@7 { ++ target = <&csi1_ep>; ++ __overlay__ { ++ data-lanes = <1 2>; ++ }; ++ }; ++ ++ fragment@8 { ++ target = <&csi1_ep>; ++ __dormant__ { ++ data-lanes = <1 2 3 4>; ++ }; ++ }; ++ + __overrides__ { +- 4lane = <0>, "-2+3"; ++ 4lane = <0>, "-2+3-7+8"; + link-frequency = <&tc358743>,"link-frequencies#0"; + }; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0814-media-bcm2835-unicam-Avoid-gcc-warning-over-0-on-end.patch b/target/linux/bcm27xx/patches-5.4/950-0814-media-bcm2835-unicam-Avoid-gcc-warning-over-0-on-end.patch new file mode 100644 index 0000000000..f70dba77c0 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0814-media-bcm2835-unicam-Avoid-gcc-warning-over-0-on-end.patch @@ -0,0 +1,27 @@ +From 3f8d0137a1fc1cb0333cb99624213fe4622a92b6 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Fri, 26 Jun 2020 15:53:44 +0100 +Subject: [PATCH] media: bcm2835-unicam: Avoid gcc warning over {0} + on endpoint + +Older gcc versions object to = { 0 } initialisation if the first +elemtn in the structure is a substructure. + +Use = { } to avoid this compiler warning. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/platform/bcm2835/bcm2835-unicam.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -2578,7 +2578,7 @@ static const struct v4l2_async_notifier_ + static int of_unicam_connect_subdevs(struct unicam_device *dev) + { + struct platform_device *pdev = dev->pdev; +- struct v4l2_fwnode_endpoint ep = { 0 }; ++ struct v4l2_fwnode_endpoint ep = { }; + struct device_node *ep_node; + struct device_node *sensor_node; + unsigned int lane; diff --git a/target/linux/bcm27xx/patches-5.4/950-0815-media-dt-bindings-media-i2c-Add-IMX290-CMOS-sensor-b.patch b/target/linux/bcm27xx/patches-5.4/950-0815-media-dt-bindings-media-i2c-Add-IMX290-CMOS-sensor-b.patch new file mode 100644 index 0000000000..120ad34dc2 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0815-media-dt-bindings-media-i2c-Add-IMX290-CMOS-sensor-b.patch @@ -0,0 +1,98 @@ +From 6bbb873c79b9bb0b3ca95fa4a4fe6cfd0ebe9d2c Mon Sep 17 00:00:00 2001 +From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Date: Fri, 4 Oct 2019 13:05:24 -0300 +Subject: [PATCH] media: dt-bindings: media: i2c: Add IMX290 CMOS + sensor binding + +Commit 8a97a4676f8b1badcd9cfbed2b081342847bb1b1 upstream. + +Add devicetree binding for IMX290 CMOS image sensor. Let's also +add MAINTAINERS entry for the binding and driver. + +Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Reviewed-by: Rob Herring <robh@kernel.org> +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> +--- + .../devicetree/bindings/media/i2c/imx290.txt | 57 +++++++++++++++++++ + MAINTAINERS | 8 +++ + 2 files changed, 65 insertions(+) + create mode 100644 Documentation/devicetree/bindings/media/i2c/imx290.txt + +--- /dev/null ++++ b/Documentation/devicetree/bindings/media/i2c/imx290.txt +@@ -0,0 +1,57 @@ ++* Sony IMX290 1/2.8-Inch CMOS Image Sensor ++ ++The Sony IMX290 is a 1/2.8-Inch CMOS Solid-state image sensor with ++Square Pixel for Color Cameras. It is programmable through I2C and 4-wire ++interfaces. The sensor output is available via CMOS logic parallel SDR output, ++Low voltage LVDS DDR output and CSI-2 serial data output. The CSI-2 bus is the ++default. No bindings have been defined for the other busses. ++ ++Required Properties: ++- compatible: Should be "sony,imx290" ++- reg: I2C bus address of the device ++- clocks: Reference to the xclk clock. ++- clock-names: Should be "xclk". ++- clock-frequency: Frequency of the xclk clock in Hz. ++- vdddo-supply: Sensor digital IO regulator. ++- vdda-supply: Sensor analog regulator. ++- vddd-supply: Sensor digital core regulator. ++ ++Optional Properties: ++- reset-gpios: Sensor reset GPIO ++ ++The imx290 device node should contain one 'port' child node with ++an 'endpoint' subnode. For further reading on port node refer to ++Documentation/devicetree/bindings/media/video-interfaces.txt. ++ ++Required Properties on endpoint: ++- data-lanes: check ../video-interfaces.txt ++- link-frequencies: check ../video-interfaces.txt ++- remote-endpoint: check ../video-interfaces.txt ++ ++Example: ++ &i2c1 { ++ ... ++ imx290: camera-sensor@1a { ++ compatible = "sony,imx290"; ++ reg = <0x1a>; ++ ++ reset-gpios = <&msmgpio 35 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&camera_rear_default>; ++ ++ clocks = <&gcc GCC_CAMSS_MCLK0_CLK>; ++ clock-names = "xclk"; ++ clock-frequency = <37125000>; ++ ++ vdddo-supply = <&camera_vdddo_1v8>; ++ vdda-supply = <&camera_vdda_2v8>; ++ vddd-supply = <&camera_vddd_1v5>; ++ ++ port { ++ imx290_ep: endpoint { ++ data-lanes = <1 2 3 4>; ++ link-frequencies = /bits/ 64 <445500000>; ++ remote-endpoint = <&csiphy0_ep>; ++ }; ++ }; ++ }; +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -15200,6 +15200,14 @@ S: Maintained + F: drivers/media/i2c/imx274.c + F: Documentation/devicetree/bindings/media/i2c/imx274.txt + ++SONY IMX290 SENSOR DRIVER ++M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> ++L: linux-media@vger.kernel.org ++T: git git://linuxtv.org/media_tree.git ++S: Maintained ++F: drivers/media/i2c/imx290.c ++F: Documentation/devicetree/bindings/media/i2c/imx290.txt ++ + SONY IMX319 SENSOR DRIVER + M: Bingbu Cao <bingbu.cao@intel.com> + L: linux-media@vger.kernel.org diff --git a/target/linux/bcm27xx/patches-5.4/950-0816-media-i2c-Add-IMX290-CMOS-image-sensor-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0816-media-i2c-Add-IMX290-CMOS-image-sensor-driver.patch new file mode 100644 index 0000000000..a44aa767bd --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0816-media-i2c-Add-IMX290-CMOS-image-sensor-driver.patch @@ -0,0 +1,939 @@ +From d13c94482be9ca356df8a04f8fd5f3738dc31ab1 Mon Sep 17 00:00:00 2001 +From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Date: Fri, 4 Oct 2019 13:05:25 -0300 +Subject: [PATCH] media: i2c: Add IMX290 CMOS image sensor driver + +Commit 828dbc299278065b634e913d2700d254a3224853 upstream. + +Add driver for Sony IMX290 CMOS image sensor driver. The driver only +supports I2C interface for programming and MIPI CSI-2 for sensor output. + +[Sakari Ailus: Rewrapped a few lines over 80 chars a little.] + +Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> +--- + drivers/media/i2c/Kconfig | 11 + + drivers/media/i2c/Makefile | 1 + + drivers/media/i2c/imx290.c | 884 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 896 insertions(+) + create mode 100644 drivers/media/i2c/imx290.c + +--- a/drivers/media/i2c/Kconfig ++++ b/drivers/media/i2c/Kconfig +@@ -609,6 +609,17 @@ config VIDEO_IMX274 + This is a V4L2 sensor driver for the Sony IMX274 + CMOS image sensor. + ++config VIDEO_IMX290 ++ tristate "Sony IMX290 sensor support" ++ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API ++ select V4L2_FWNODE ++ help ++ This is a Video4Linux2 sensor driver for the Sony ++ IMX290 camera sensor. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called imx290. ++ + config VIDEO_IMX477 + tristate "Sony IMX477 sensor support" + depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API +--- a/drivers/media/i2c/Makefile ++++ b/drivers/media/i2c/Makefile +@@ -114,6 +114,7 @@ obj-$(CONFIG_VIDEO_IMX214) += imx214.o + obj-$(CONFIG_VIDEO_IMX219) += imx219.o + obj-$(CONFIG_VIDEO_IMX258) += imx258.o + obj-$(CONFIG_VIDEO_IMX274) += imx274.o ++obj-$(CONFIG_VIDEO_IMX290) += imx290.o + obj-$(CONFIG_VIDEO_IMX477) += imx477.o + obj-$(CONFIG_VIDEO_IMX319) += imx319.o + obj-$(CONFIG_VIDEO_IMX355) += imx355.o +--- /dev/null ++++ b/drivers/media/i2c/imx290.c +@@ -0,0 +1,884 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Sony IMX290 CMOS Image Sensor Driver ++ * ++ * Copyright (C) 2019 FRAMOS GmbH. ++ * ++ * Copyright (C) 2019 Linaro Ltd. ++ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> ++ */ ++ ++#include <linux/clk.h> ++#include <linux/delay.h> ++#include <linux/gpio/consumer.h> ++#include <linux/i2c.h> ++#include <linux/module.h> ++#include <linux/pm_runtime.h> ++#include <linux/regmap.h> ++#include <linux/regulator/consumer.h> ++#include <media/media-entity.h> ++#include <media/v4l2-ctrls.h> ++#include <media/v4l2-device.h> ++#include <media/v4l2-fwnode.h> ++#include <media/v4l2-subdev.h> ++ ++#define IMX290_STANDBY 0x3000 ++#define IMX290_REGHOLD 0x3001 ++#define IMX290_XMSTA 0x3002 ++#define IMX290_GAIN 0x3014 ++ ++#define IMX290_DEFAULT_LINK_FREQ 445500000 ++ ++static const char * const imx290_supply_name[] = { ++ "vdda", ++ "vddd", ++ "vdddo", ++}; ++ ++#define IMX290_NUM_SUPPLIES ARRAY_SIZE(imx290_supply_name) ++ ++struct imx290_regval { ++ u16 reg; ++ u8 val; ++}; ++ ++struct imx290_mode { ++ u32 width; ++ u32 height; ++ u32 pixel_rate; ++ u32 link_freq_index; ++ ++ const struct imx290_regval *data; ++ u32 data_size; ++}; ++ ++struct imx290 { ++ struct device *dev; ++ struct clk *xclk; ++ struct regmap *regmap; ++ ++ struct v4l2_subdev sd; ++ struct v4l2_fwnode_endpoint ep; ++ struct media_pad pad; ++ struct v4l2_mbus_framefmt current_format; ++ const struct imx290_mode *current_mode; ++ ++ struct regulator_bulk_data supplies[IMX290_NUM_SUPPLIES]; ++ struct gpio_desc *rst_gpio; ++ ++ struct v4l2_ctrl_handler ctrls; ++ struct v4l2_ctrl *link_freq; ++ struct v4l2_ctrl *pixel_rate; ++ ++ struct mutex lock; ++}; ++ ++struct imx290_pixfmt { ++ u32 code; ++}; ++ ++static const struct imx290_pixfmt imx290_formats[] = { ++ { MEDIA_BUS_FMT_SRGGB10_1X10 }, ++}; ++ ++static const struct regmap_config imx290_regmap_config = { ++ .reg_bits = 16, ++ .val_bits = 8, ++ .cache_type = REGCACHE_RBTREE, ++}; ++ ++static const struct imx290_regval imx290_global_init_settings[] = { ++ { 0x3007, 0x00 }, ++ { 0x3009, 0x00 }, ++ { 0x3018, 0x65 }, ++ { 0x3019, 0x04 }, ++ { 0x301a, 0x00 }, ++ { 0x3443, 0x03 }, ++ { 0x3444, 0x20 }, ++ { 0x3445, 0x25 }, ++ { 0x3407, 0x03 }, ++ { 0x303a, 0x0c }, ++ { 0x3040, 0x00 }, ++ { 0x3041, 0x00 }, ++ { 0x303c, 0x00 }, ++ { 0x303d, 0x00 }, ++ { 0x3042, 0x9c }, ++ { 0x3043, 0x07 }, ++ { 0x303e, 0x49 }, ++ { 0x303f, 0x04 }, ++ { 0x304b, 0x0a }, ++ { 0x300f, 0x00 }, ++ { 0x3010, 0x21 }, ++ { 0x3012, 0x64 }, ++ { 0x3016, 0x09 }, ++ { 0x3070, 0x02 }, ++ { 0x3071, 0x11 }, ++ { 0x309b, 0x10 }, ++ { 0x309c, 0x22 }, ++ { 0x30a2, 0x02 }, ++ { 0x30a6, 0x20 }, ++ { 0x30a8, 0x20 }, ++ { 0x30aa, 0x20 }, ++ { 0x30ac, 0x20 }, ++ { 0x30b0, 0x43 }, ++ { 0x3119, 0x9e }, ++ { 0x311c, 0x1e }, ++ { 0x311e, 0x08 }, ++ { 0x3128, 0x05 }, ++ { 0x313d, 0x83 }, ++ { 0x3150, 0x03 }, ++ { 0x317e, 0x00 }, ++ { 0x32b8, 0x50 }, ++ { 0x32b9, 0x10 }, ++ { 0x32ba, 0x00 }, ++ { 0x32bb, 0x04 }, ++ { 0x32c8, 0x50 }, ++ { 0x32c9, 0x10 }, ++ { 0x32ca, 0x00 }, ++ { 0x32cb, 0x04 }, ++ { 0x332c, 0xd3 }, ++ { 0x332d, 0x10 }, ++ { 0x332e, 0x0d }, ++ { 0x3358, 0x06 }, ++ { 0x3359, 0xe1 }, ++ { 0x335a, 0x11 }, ++ { 0x3360, 0x1e }, ++ { 0x3361, 0x61 }, ++ { 0x3362, 0x10 }, ++ { 0x33b0, 0x50 }, ++ { 0x33b2, 0x1a }, ++ { 0x33b3, 0x04 }, ++}; ++ ++static const struct imx290_regval imx290_1080p_settings[] = { ++ /* mode settings */ ++ { 0x3007, 0x00 }, ++ { 0x303a, 0x0c }, ++ { 0x3414, 0x0a }, ++ { 0x3472, 0x80 }, ++ { 0x3473, 0x07 }, ++ { 0x3418, 0x38 }, ++ { 0x3419, 0x04 }, ++ { 0x3012, 0x64 }, ++ { 0x3013, 0x00 }, ++ { 0x305c, 0x18 }, ++ { 0x305d, 0x03 }, ++ { 0x305e, 0x20 }, ++ { 0x305f, 0x01 }, ++ { 0x315e, 0x1a }, ++ { 0x3164, 0x1a }, ++ { 0x3480, 0x49 }, ++ /* data rate settings */ ++ { 0x3009, 0x01 }, ++ { 0x3405, 0x10 }, ++ { 0x3446, 0x57 }, ++ { 0x3447, 0x00 }, ++ { 0x3448, 0x37 }, ++ { 0x3449, 0x00 }, ++ { 0x344a, 0x1f }, ++ { 0x344b, 0x00 }, ++ { 0x344c, 0x1f }, ++ { 0x344d, 0x00 }, ++ { 0x344e, 0x1f }, ++ { 0x344f, 0x00 }, ++ { 0x3450, 0x77 }, ++ { 0x3451, 0x00 }, ++ { 0x3452, 0x1f }, ++ { 0x3453, 0x00 }, ++ { 0x3454, 0x17 }, ++ { 0x3455, 0x00 }, ++ { 0x301c, 0x98 }, ++ { 0x301d, 0x08 }, ++}; ++ ++static const struct imx290_regval imx290_720p_settings[] = { ++ /* mode settings */ ++ { 0x3007, 0x10 }, ++ { 0x303a, 0x06 }, ++ { 0x3414, 0x04 }, ++ { 0x3472, 0x00 }, ++ { 0x3473, 0x05 }, ++ { 0x3418, 0xd0 }, ++ { 0x3419, 0x02 }, ++ { 0x3012, 0x64 }, ++ { 0x3013, 0x00 }, ++ { 0x305c, 0x20 }, ++ { 0x305d, 0x00 }, ++ { 0x305e, 0x20 }, ++ { 0x305f, 0x01 }, ++ { 0x315e, 0x1a }, ++ { 0x3164, 0x1a }, ++ { 0x3480, 0x49 }, ++ /* data rate settings */ ++ { 0x3009, 0x01 }, ++ { 0x3405, 0x10 }, ++ { 0x3446, 0x4f }, ++ { 0x3447, 0x00 }, ++ { 0x3448, 0x2f }, ++ { 0x3449, 0x00 }, ++ { 0x344a, 0x17 }, ++ { 0x344b, 0x00 }, ++ { 0x344c, 0x17 }, ++ { 0x344d, 0x00 }, ++ { 0x344e, 0x17 }, ++ { 0x344f, 0x00 }, ++ { 0x3450, 0x57 }, ++ { 0x3451, 0x00 }, ++ { 0x3452, 0x17 }, ++ { 0x3453, 0x00 }, ++ { 0x3454, 0x17 }, ++ { 0x3455, 0x00 }, ++ { 0x301c, 0xe4 }, ++ { 0x301d, 0x0c }, ++}; ++ ++static const struct imx290_regval imx290_10bit_settings[] = { ++ { 0x3005, 0x00}, ++ { 0x3046, 0x00}, ++ { 0x3129, 0x1d}, ++ { 0x317c, 0x12}, ++ { 0x31ec, 0x37}, ++ { 0x3441, 0x0a}, ++ { 0x3442, 0x0a}, ++ { 0x300a, 0x3c}, ++ { 0x300b, 0x00}, ++}; ++ ++/* supported link frequencies */ ++static const s64 imx290_link_freq[] = { ++ IMX290_DEFAULT_LINK_FREQ, ++}; ++ ++/* Mode configs */ ++static const struct imx290_mode imx290_modes[] = { ++ { ++ .width = 1920, ++ .height = 1080, ++ .data = imx290_1080p_settings, ++ .data_size = ARRAY_SIZE(imx290_1080p_settings), ++ .pixel_rate = 178200000, ++ .link_freq_index = 0, ++ }, ++ { ++ .width = 1280, ++ .height = 720, ++ .data = imx290_720p_settings, ++ .data_size = ARRAY_SIZE(imx290_720p_settings), ++ .pixel_rate = 178200000, ++ .link_freq_index = 0, ++ }, ++}; ++ ++static inline struct imx290 *to_imx290(struct v4l2_subdev *_sd) ++{ ++ return container_of(_sd, struct imx290, sd); ++} ++ ++static inline int imx290_read_reg(struct imx290 *imx290, u16 addr, u8 *value) ++{ ++ unsigned int regval; ++ int ret; ++ ++ ret = regmap_read(imx290->regmap, addr, ®val); ++ if (ret) { ++ dev_err(imx290->dev, "I2C read failed for addr: %x\n", addr); ++ return ret; ++ } ++ ++ *value = regval & 0xff; ++ ++ return 0; ++} ++ ++static int imx290_write_reg(struct imx290 *imx290, u16 addr, u8 value) ++{ ++ int ret; ++ ++ ret = regmap_write(imx290->regmap, addr, value); ++ if (ret) { ++ dev_err(imx290->dev, "I2C write failed for addr: %x\n", addr); ++ return ret; ++ } ++ ++ return ret; ++} ++ ++static int imx290_set_register_array(struct imx290 *imx290, ++ const struct imx290_regval *settings, ++ unsigned int num_settings) ++{ ++ unsigned int i; ++ int ret; ++ ++ for (i = 0; i < num_settings; ++i, ++settings) { ++ ret = imx290_write_reg(imx290, settings->reg, settings->val); ++ if (ret < 0) ++ return ret; ++ ++ /* Settle time is 10ms for all registers */ ++ msleep(10); ++ } ++ ++ return 0; ++} ++ ++static int imx290_write_buffered_reg(struct imx290 *imx290, u16 address_low, ++ u8 nr_regs, u32 value) ++{ ++ unsigned int i; ++ int ret; ++ ++ ret = imx290_write_reg(imx290, IMX290_REGHOLD, 0x01); ++ if (ret) { ++ dev_err(imx290->dev, "Error setting hold register\n"); ++ return ret; ++ } ++ ++ for (i = 0; i < nr_regs; i++) { ++ ret = imx290_write_reg(imx290, address_low + i, ++ (u8)(value >> (i * 8))); ++ if (ret) { ++ dev_err(imx290->dev, "Error writing buffered registers\n"); ++ return ret; ++ } ++ } ++ ++ ret = imx290_write_reg(imx290, IMX290_REGHOLD, 0x00); ++ if (ret) { ++ dev_err(imx290->dev, "Error setting hold register\n"); ++ return ret; ++ } ++ ++ return ret; ++} ++ ++static int imx290_set_gain(struct imx290 *imx290, u32 value) ++{ ++ int ret; ++ ++ ret = imx290_write_buffered_reg(imx290, IMX290_GAIN, 1, value); ++ if (ret) ++ dev_err(imx290->dev, "Unable to write gain\n"); ++ ++ return ret; ++} ++ ++/* Stop streaming */ ++static int imx290_stop_streaming(struct imx290 *imx290) ++{ ++ int ret; ++ ++ ret = imx290_write_reg(imx290, IMX290_STANDBY, 0x01); ++ if (ret < 0) ++ return ret; ++ ++ msleep(30); ++ ++ return imx290_write_reg(imx290, IMX290_XMSTA, 0x01); ++} ++ ++static int imx290_set_ctrl(struct v4l2_ctrl *ctrl) ++{ ++ struct imx290 *imx290 = container_of(ctrl->handler, ++ struct imx290, ctrls); ++ int ret = 0; ++ ++ /* V4L2 controls values will be applied only when power is already up */ ++ if (!pm_runtime_get_if_in_use(imx290->dev)) ++ return 0; ++ ++ switch (ctrl->id) { ++ case V4L2_CID_GAIN: ++ ret = imx290_set_gain(imx290, ctrl->val); ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ ++ pm_runtime_put(imx290->dev); ++ ++ return ret; ++} ++ ++static const struct v4l2_ctrl_ops imx290_ctrl_ops = { ++ .s_ctrl = imx290_set_ctrl, ++}; ++ ++static int imx290_enum_mbus_code(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_mbus_code_enum *code) ++{ ++ if (code->index >= ARRAY_SIZE(imx290_formats)) ++ return -EINVAL; ++ ++ code->code = imx290_formats[code->index].code; ++ ++ return 0; ++} ++ ++static int imx290_get_fmt(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_format *fmt) ++{ ++ struct imx290 *imx290 = to_imx290(sd); ++ struct v4l2_mbus_framefmt *framefmt; ++ ++ mutex_lock(&imx290->lock); ++ ++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) ++ framefmt = v4l2_subdev_get_try_format(&imx290->sd, cfg, ++ fmt->pad); ++ else ++ framefmt = &imx290->current_format; ++ ++ fmt->format = *framefmt; ++ ++ mutex_unlock(&imx290->lock); ++ ++ return 0; ++} ++ ++static int imx290_set_fmt(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_format *fmt) ++{ ++ struct imx290 *imx290 = to_imx290(sd); ++ const struct imx290_mode *mode; ++ struct v4l2_mbus_framefmt *format; ++ unsigned int i; ++ ++ mutex_lock(&imx290->lock); ++ ++ mode = v4l2_find_nearest_size(imx290_modes, ++ ARRAY_SIZE(imx290_modes), ++ width, height, ++ fmt->format.width, fmt->format.height); ++ ++ fmt->format.width = mode->width; ++ fmt->format.height = mode->height; ++ ++ for (i = 0; i < ARRAY_SIZE(imx290_formats); i++) ++ if (imx290_formats[i].code == fmt->format.code) ++ break; ++ ++ if (i >= ARRAY_SIZE(imx290_formats)) ++ i = 0; ++ ++ fmt->format.code = imx290_formats[i].code; ++ fmt->format.field = V4L2_FIELD_NONE; ++ ++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { ++ format = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); ++ } else { ++ format = &imx290->current_format; ++ __v4l2_ctrl_s_ctrl(imx290->link_freq, mode->link_freq_index); ++ __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate, mode->pixel_rate); ++ ++ imx290->current_mode = mode; ++ } ++ ++ *format = fmt->format; ++ ++ mutex_unlock(&imx290->lock); ++ ++ return 0; ++} ++ ++static int imx290_entity_init_cfg(struct v4l2_subdev *subdev, ++ struct v4l2_subdev_pad_config *cfg) ++{ ++ struct v4l2_subdev_format fmt = { 0 }; ++ ++ fmt.which = cfg ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; ++ fmt.format.width = 1920; ++ fmt.format.height = 1080; ++ ++ imx290_set_fmt(subdev, cfg, &fmt); ++ ++ return 0; ++} ++ ++static int imx290_write_current_format(struct imx290 *imx290, ++ struct v4l2_mbus_framefmt *format) ++{ ++ int ret; ++ ++ switch (format->code) { ++ case MEDIA_BUS_FMT_SRGGB10_1X10: ++ ret = imx290_set_register_array(imx290, imx290_10bit_settings, ++ ARRAY_SIZE( ++ imx290_10bit_settings)); ++ if (ret < 0) { ++ dev_err(imx290->dev, "Could not set format registers\n"); ++ return ret; ++ } ++ break; ++ default: ++ dev_err(imx290->dev, "Unknown pixel format\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* Start streaming */ ++static int imx290_start_streaming(struct imx290 *imx290) ++{ ++ int ret; ++ ++ /* Set init register settings */ ++ ret = imx290_set_register_array(imx290, imx290_global_init_settings, ++ ARRAY_SIZE( ++ imx290_global_init_settings)); ++ if (ret < 0) { ++ dev_err(imx290->dev, "Could not set init registers\n"); ++ return ret; ++ } ++ ++ /* Set current frame format */ ++ ret = imx290_write_current_format(imx290, &imx290->current_format); ++ if (ret < 0) { ++ dev_err(imx290->dev, "Could not set frame format\n"); ++ return ret; ++ } ++ ++ /* Apply default values of current mode */ ++ ret = imx290_set_register_array(imx290, imx290->current_mode->data, ++ imx290->current_mode->data_size); ++ if (ret < 0) { ++ dev_err(imx290->dev, "Could not set current mode\n"); ++ return ret; ++ } ++ ++ /* Apply customized values from user */ ++ ret = v4l2_ctrl_handler_setup(imx290->sd.ctrl_handler); ++ if (ret) { ++ dev_err(imx290->dev, "Could not sync v4l2 controls\n"); ++ return ret; ++ } ++ ++ ret = imx290_write_reg(imx290, IMX290_STANDBY, 0x00); ++ if (ret < 0) ++ return ret; ++ ++ msleep(30); ++ ++ /* Start streaming */ ++ return imx290_write_reg(imx290, IMX290_XMSTA, 0x00); ++} ++ ++static int imx290_set_stream(struct v4l2_subdev *sd, int enable) ++{ ++ struct imx290 *imx290 = to_imx290(sd); ++ int ret = 0; ++ ++ if (enable) { ++ ret = pm_runtime_get_sync(imx290->dev); ++ if (ret < 0) { ++ pm_runtime_put_noidle(imx290->dev); ++ goto unlock_and_return; ++ } ++ ++ ret = imx290_start_streaming(imx290); ++ if (ret) { ++ dev_err(imx290->dev, "Start stream failed\n"); ++ pm_runtime_put(imx290->dev); ++ goto unlock_and_return; ++ } ++ } else { ++ imx290_stop_streaming(imx290); ++ pm_runtime_put(imx290->dev); ++ } ++ ++unlock_and_return: ++ ++ return ret; ++} ++ ++static int imx290_get_regulators(struct device *dev, struct imx290 *imx290) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < IMX290_NUM_SUPPLIES; i++) ++ imx290->supplies[i].supply = imx290_supply_name[i]; ++ ++ return devm_regulator_bulk_get(dev, IMX290_NUM_SUPPLIES, ++ imx290->supplies); ++} ++ ++static int imx290_power_on(struct device *dev) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct v4l2_subdev *sd = i2c_get_clientdata(client); ++ struct imx290 *imx290 = to_imx290(sd); ++ int ret; ++ ++ ret = clk_prepare_enable(imx290->xclk); ++ if (ret) { ++ dev_err(imx290->dev, "Failed to enable clock\n"); ++ return ret; ++ } ++ ++ ret = regulator_bulk_enable(IMX290_NUM_SUPPLIES, imx290->supplies); ++ if (ret) { ++ dev_err(imx290->dev, "Failed to enable regulators\n"); ++ clk_disable_unprepare(imx290->xclk); ++ return ret; ++ } ++ ++ usleep_range(1, 2); ++ gpiod_set_value_cansleep(imx290->rst_gpio, 1); ++ usleep_range(30000, 31000); ++ ++ return 0; ++} ++ ++static int imx290_power_off(struct device *dev) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct v4l2_subdev *sd = i2c_get_clientdata(client); ++ struct imx290 *imx290 = to_imx290(sd); ++ ++ clk_disable_unprepare(imx290->xclk); ++ gpiod_set_value_cansleep(imx290->rst_gpio, 0); ++ regulator_bulk_disable(IMX290_NUM_SUPPLIES, imx290->supplies); ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops imx290_pm_ops = { ++ SET_RUNTIME_PM_OPS(imx290_power_on, imx290_power_off, NULL) ++}; ++ ++static const struct v4l2_subdev_video_ops imx290_video_ops = { ++ .s_stream = imx290_set_stream, ++}; ++ ++static const struct v4l2_subdev_pad_ops imx290_pad_ops = { ++ .init_cfg = imx290_entity_init_cfg, ++ .enum_mbus_code = imx290_enum_mbus_code, ++ .get_fmt = imx290_get_fmt, ++ .set_fmt = imx290_set_fmt, ++}; ++ ++static const struct v4l2_subdev_ops imx290_subdev_ops = { ++ .video = &imx290_video_ops, ++ .pad = &imx290_pad_ops, ++}; ++ ++static const struct media_entity_operations imx290_subdev_entity_ops = { ++ .link_validate = v4l2_subdev_link_validate, ++}; ++ ++static int imx290_probe(struct i2c_client *client) ++{ ++ struct device *dev = &client->dev; ++ struct fwnode_handle *endpoint; ++ struct imx290 *imx290; ++ u32 xclk_freq; ++ int ret; ++ ++ imx290 = devm_kzalloc(dev, sizeof(*imx290), GFP_KERNEL); ++ if (!imx290) ++ return -ENOMEM; ++ ++ imx290->dev = dev; ++ imx290->regmap = devm_regmap_init_i2c(client, &imx290_regmap_config); ++ if (IS_ERR(imx290->regmap)) { ++ dev_err(dev, "Unable to initialize I2C\n"); ++ return -ENODEV; ++ } ++ ++ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL); ++ if (!endpoint) { ++ dev_err(dev, "Endpoint node not found\n"); ++ return -EINVAL; ++ } ++ ++ ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &imx290->ep); ++ fwnode_handle_put(endpoint); ++ if (ret) { ++ dev_err(dev, "Parsing endpoint node failed\n"); ++ goto free_err; ++ } ++ ++ if (!imx290->ep.nr_of_link_frequencies) { ++ dev_err(dev, "link-frequency property not found in DT\n"); ++ ret = -EINVAL; ++ goto free_err; ++ } ++ ++ if (imx290->ep.link_frequencies[0] != IMX290_DEFAULT_LINK_FREQ) { ++ dev_err(dev, "Unsupported link frequency\n"); ++ ret = -EINVAL; ++ goto free_err; ++ } ++ ++ /* Only CSI2 is supported for now */ ++ if (imx290->ep.bus_type != V4L2_MBUS_CSI2_DPHY) { ++ dev_err(dev, "Unsupported bus type, should be CSI2\n"); ++ ret = -EINVAL; ++ goto free_err; ++ } ++ ++ /* Set default mode to max resolution */ ++ imx290->current_mode = &imx290_modes[0]; ++ ++ /* get system clock (xclk) */ ++ imx290->xclk = devm_clk_get(dev, "xclk"); ++ if (IS_ERR(imx290->xclk)) { ++ dev_err(dev, "Could not get xclk"); ++ ret = PTR_ERR(imx290->xclk); ++ goto free_err; ++ } ++ ++ ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency", ++ &xclk_freq); ++ if (ret) { ++ dev_err(dev, "Could not get xclk frequency\n"); ++ goto free_err; ++ } ++ ++ /* external clock must be 37.125 MHz */ ++ if (xclk_freq != 37125000) { ++ dev_err(dev, "External clock frequency %u is not supported\n", ++ xclk_freq); ++ ret = -EINVAL; ++ goto free_err; ++ } ++ ++ ret = clk_set_rate(imx290->xclk, xclk_freq); ++ if (ret) { ++ dev_err(dev, "Could not set xclk frequency\n"); ++ goto free_err; ++ } ++ ++ ret = imx290_get_regulators(dev, imx290); ++ if (ret < 0) { ++ dev_err(dev, "Cannot get regulators\n"); ++ goto free_err; ++ } ++ ++ imx290->rst_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS); ++ if (IS_ERR(imx290->rst_gpio)) { ++ dev_err(dev, "Cannot get reset gpio\n"); ++ ret = PTR_ERR(imx290->rst_gpio); ++ goto free_err; ++ } ++ ++ mutex_init(&imx290->lock); ++ ++ v4l2_ctrl_handler_init(&imx290->ctrls, 3); ++ ++ v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, ++ V4L2_CID_GAIN, 0, 72, 1, 0); ++ imx290->link_freq = ++ v4l2_ctrl_new_int_menu(&imx290->ctrls, ++ &imx290_ctrl_ops, ++ V4L2_CID_LINK_FREQ, ++ ARRAY_SIZE(imx290_link_freq) - 1, ++ 0, imx290_link_freq); ++ if (imx290->link_freq) ++ imx290->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; ++ ++ imx290->pixel_rate = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, ++ V4L2_CID_PIXEL_RATE, 1, ++ INT_MAX, 1, ++ imx290_modes[0].pixel_rate); ++ ++ imx290->sd.ctrl_handler = &imx290->ctrls; ++ ++ if (imx290->ctrls.error) { ++ dev_err(dev, "Control initialization error %d\n", ++ imx290->ctrls.error); ++ ret = imx290->ctrls.error; ++ goto free_ctrl; ++ } ++ ++ v4l2_i2c_subdev_init(&imx290->sd, client, &imx290_subdev_ops); ++ imx290->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; ++ imx290->sd.dev = &client->dev; ++ imx290->sd.entity.ops = &imx290_subdev_entity_ops; ++ imx290->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; ++ ++ imx290->pad.flags = MEDIA_PAD_FL_SOURCE; ++ ret = media_entity_pads_init(&imx290->sd.entity, 1, &imx290->pad); ++ if (ret < 0) { ++ dev_err(dev, "Could not register media entity\n"); ++ goto free_ctrl; ++ } ++ ++ ret = v4l2_async_register_subdev(&imx290->sd); ++ if (ret < 0) { ++ dev_err(dev, "Could not register v4l2 device\n"); ++ goto free_entity; ++ } ++ ++ /* Power on the device to match runtime PM state below */ ++ ret = imx290_power_on(dev); ++ if (ret < 0) { ++ dev_err(dev, "Could not power on the device\n"); ++ goto free_entity; ++ } ++ ++ pm_runtime_set_active(dev); ++ pm_runtime_enable(dev); ++ pm_runtime_idle(dev); ++ ++ v4l2_fwnode_endpoint_free(&imx290->ep); ++ ++ return 0; ++ ++free_entity: ++ media_entity_cleanup(&imx290->sd.entity); ++free_ctrl: ++ v4l2_ctrl_handler_free(&imx290->ctrls); ++ mutex_destroy(&imx290->lock); ++free_err: ++ v4l2_fwnode_endpoint_free(&imx290->ep); ++ ++ return ret; ++} ++ ++static int imx290_remove(struct i2c_client *client) ++{ ++ struct v4l2_subdev *sd = i2c_get_clientdata(client); ++ struct imx290 *imx290 = to_imx290(sd); ++ ++ v4l2_async_unregister_subdev(sd); ++ media_entity_cleanup(&sd->entity); ++ v4l2_ctrl_handler_free(sd->ctrl_handler); ++ ++ mutex_destroy(&imx290->lock); ++ ++ pm_runtime_disable(imx290->dev); ++ if (!pm_runtime_status_suspended(imx290->dev)) ++ imx290_power_off(imx290->dev); ++ pm_runtime_set_suspended(imx290->dev); ++ ++ return 0; ++} ++ ++static const struct of_device_id imx290_of_match[] = { ++ { .compatible = "sony,imx290" }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, imx290_of_match); ++ ++static struct i2c_driver imx290_i2c_driver = { ++ .probe_new = imx290_probe, ++ .remove = imx290_remove, ++ .driver = { ++ .name = "imx290", ++ .pm = &imx290_pm_ops, ++ .of_match_table = of_match_ptr(imx290_of_match), ++ }, ++}; ++ ++module_i2c_driver(imx290_i2c_driver); ++ ++MODULE_DESCRIPTION("Sony IMX290 CMOS Image Sensor Driver"); ++MODULE_AUTHOR("FRAMOS GmbH"); ++MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>"); ++MODULE_LICENSE("GPL v2"); diff --git a/target/linux/bcm27xx/patches-5.4/950-0817-media-i2c-imx290-set-the-format-before-VIDIOC_SUBDEV.patch b/target/linux/bcm27xx/patches-5.4/950-0817-media-i2c-imx290-set-the-format-before-VIDIOC_SUBDEV.patch new file mode 100644 index 0000000000..68f8fcfd34 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0817-media-i2c-imx290-set-the-format-before-VIDIOC_SUBDEV.patch @@ -0,0 +1,50 @@ +From 2beb8ff8039f3ee8262f05d7f3d91c44826e5df9 Mon Sep 17 00:00:00 2001 +From: Andrey Konovalov <andrey.konovalov@linaro.org> +Date: Fri, 12 Jun 2020 15:53:46 +0200 +Subject: [PATCH] media: i2c: imx290: set the format before + VIDIOC_SUBDEV_G_FMT is called + +Commit d46cfdc86c30d5ec768924f0b1e2683c8d20b671 upstream. + +With the current driver 'media-ctl -p' issued right after the imx290 driver +is loaded prints: +pad0: Source + [fmt:unknown/0x0] + +The format value of zero is due to the current_format field of the imx290 +struct not being initialized yet. + +As imx290_entity_init_cfg() calls imx290_set_fmt(), the current_mode field +is also initialized, so the line which set current_mode to a default value +in driver's probe() function is no longer needed. + +Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org> +Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/i2c/imx290.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -722,9 +722,6 @@ static int imx290_probe(struct i2c_clien + goto free_err; + } + +- /* Set default mode to max resolution */ +- imx290->current_mode = &imx290_modes[0]; +- + /* get system clock (xclk) */ + imx290->xclk = devm_clk_get(dev, "xclk"); + if (IS_ERR(imx290->xclk)) { +@@ -809,6 +806,9 @@ static int imx290_probe(struct i2c_clien + goto free_ctrl; + } + ++ /* Initialize the frame format (this also sets imx290->current_mode) */ ++ imx290_entity_init_cfg(&imx290->sd, NULL); ++ + ret = v4l2_async_register_subdev(&imx290->sd); + if (ret < 0) { + dev_err(dev, "Could not register v4l2 device\n"); diff --git a/target/linux/bcm27xx/patches-5.4/950-0818-media-i2c-imx290-fix-the-order-of-the-args-in-SET_RU.patch b/target/linux/bcm27xx/patches-5.4/950-0818-media-i2c-imx290-fix-the-order-of-the-args-in-SET_RU.patch new file mode 100644 index 0000000000..a3332a7eac --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0818-media-i2c-imx290-fix-the-order-of-the-args-in-SET_RU.patch @@ -0,0 +1,30 @@ +From 8c3334dd193798648c329779ce7a3c6ddec7944e Mon Sep 17 00:00:00 2001 +From: Andrey Konovalov <andrey.konovalov@linaro.org> +Date: Fri, 12 Jun 2020 15:53:47 +0200 +Subject: [PATCH] media: i2c: imx290: fix the order of the args in + SET_RUNTIME_PM_OPS() + +Commit 8d2d1bedb1b9af3e0c039a4444858da7b6da71f8 upstream. + +The macro is defined as SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn), +so imx290_power_off must be the 1st arg, and imx290_power_on the 2nd. + +Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org> +Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/i2c/imx290.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -648,7 +648,7 @@ static int imx290_power_off(struct devic + } + + static const struct dev_pm_ops imx290_pm_ops = { +- SET_RUNTIME_PM_OPS(imx290_power_on, imx290_power_off, NULL) ++ SET_RUNTIME_PM_OPS(imx290_power_off, imx290_power_on, NULL) + }; + + static const struct v4l2_subdev_video_ops imx290_video_ops = { diff --git a/target/linux/bcm27xx/patches-5.4/950-0819-media-i2c-imx290-fix-reset-GPIO-pin-handling.patch b/target/linux/bcm27xx/patches-5.4/950-0819-media-i2c-imx290-fix-reset-GPIO-pin-handling.patch new file mode 100644 index 0000000000..f4c122de93 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0819-media-i2c-imx290-fix-reset-GPIO-pin-handling.patch @@ -0,0 +1,61 @@ +From 47f49370b3c1c7f4d4aae855966d2a3beef6c6d4 Mon Sep 17 00:00:00 2001 +From: Andrey Konovalov <andrey.konovalov@linaro.org> +Date: Fri, 12 Jun 2020 15:53:48 +0200 +Subject: [PATCH] media: i2c: imx290: fix reset GPIO pin handling + +Commit 3909a92d7df622b41b9ceeeea694e641cad7667b upstream. + +According to https://www.kernel.org/doc/Documentation/gpio/consumer.txt, + +- all of the gpiod_set_value_xxx() functions operate with the *logical* +value. So in imx290_power_on() the reset signal should be cleared +(de-asserted) with gpiod_set_value_cansleep(imx290->rst_gpio, 0), and in +imx290_power_off() the value of 1 must be used to apply/assert the reset +to the sensor. In the device tree the reset pin is described as +GPIO_ACTIVE_LOW, and gpiod_set_value_xxx() functions take this into +account, + +- when devm_gpiod_get_optional() is called with GPIOD_ASIS, the GPIO is +not initialized, and the direction must be set later; using a GPIO +without setting its direction first is illegal and will result in undefined +behavior. Fix this by using GPIOD_OUT_HIGH instead of GPIOD_ASIS (this +asserts the reset signal to the sensor initially). + +Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org> +Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/i2c/imx290.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -628,7 +628,7 @@ static int imx290_power_on(struct device + } + + usleep_range(1, 2); +- gpiod_set_value_cansleep(imx290->rst_gpio, 1); ++ gpiod_set_value_cansleep(imx290->rst_gpio, 0); + usleep_range(30000, 31000); + + return 0; +@@ -641,7 +641,7 @@ static int imx290_power_off(struct devic + struct imx290 *imx290 = to_imx290(sd); + + clk_disable_unprepare(imx290->xclk); +- gpiod_set_value_cansleep(imx290->rst_gpio, 0); ++ gpiod_set_value_cansleep(imx290->rst_gpio, 1); + regulator_bulk_disable(IMX290_NUM_SUPPLIES, imx290->supplies); + + return 0; +@@ -757,7 +757,8 @@ static int imx290_probe(struct i2c_clien + goto free_err; + } + +- imx290->rst_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS); ++ imx290->rst_gpio = devm_gpiod_get_optional(dev, "reset", ++ GPIOD_OUT_HIGH); + if (IS_ERR(imx290->rst_gpio)) { + dev_err(dev, "Cannot get reset gpio\n"); + ret = PTR_ERR(imx290->rst_gpio); diff --git a/target/linux/bcm27xx/patches-5.4/950-0820-media-i2c-imx290-Add-support-for-2-data-lanes.patch b/target/linux/bcm27xx/patches-5.4/950-0820-media-i2c-imx290-Add-support-for-2-data-lanes.patch new file mode 100644 index 0000000000..68b89999c5 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0820-media-i2c-imx290-Add-support-for-2-data-lanes.patch @@ -0,0 +1,314 @@ +From 78d867300b5026ab31c9a3fbd37b6590b7940f66 Mon Sep 17 00:00:00 2001 +From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Date: Fri, 12 Jun 2020 15:53:49 +0200 +Subject: [PATCH] media: i2c: imx290: Add support for 2 data lanes + +Commit 97589ad61c730e0f486635c6c19fa25ab8e8f29d upstream. + +The IMX290 sensor can output frames with 2/4 CSI2 data lanes. This commit +adds support for 2 lane mode in addition to the 4 lane and also +configuring the data lane settings in the driver based on system +configuration. + +Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org> +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/i2c/imx290.c | 147 +++++++++++++++++++++++++++++++++---- + 1 file changed, 133 insertions(+), 14 deletions(-) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -25,7 +25,12 @@ + #define IMX290_STANDBY 0x3000 + #define IMX290_REGHOLD 0x3001 + #define IMX290_XMSTA 0x3002 ++#define IMX290_FR_FDG_SEL 0x3009 + #define IMX290_GAIN 0x3014 ++#define IMX290_HMAX_LOW 0x301c ++#define IMX290_HMAX_HIGH 0x301d ++#define IMX290_PHY_LANE_NUM 0x3407 ++#define IMX290_CSI_LANE_MODE 0x3443 + + #define IMX290_DEFAULT_LINK_FREQ 445500000 + +@@ -45,6 +50,7 @@ struct imx290_regval { + struct imx290_mode { + u32 width; + u32 height; ++ u32 hmax; + u32 pixel_rate; + u32 link_freq_index; + +@@ -56,6 +62,7 @@ struct imx290 { + struct device *dev; + struct clk *xclk; + struct regmap *regmap; ++ u8 nlanes; + + struct v4l2_subdev sd; + struct v4l2_fwnode_endpoint ep; +@@ -89,14 +96,11 @@ static const struct regmap_config imx290 + + static const struct imx290_regval imx290_global_init_settings[] = { + { 0x3007, 0x00 }, +- { 0x3009, 0x00 }, + { 0x3018, 0x65 }, + { 0x3019, 0x04 }, + { 0x301a, 0x00 }, +- { 0x3443, 0x03 }, + { 0x3444, 0x20 }, + { 0x3445, 0x25 }, +- { 0x3407, 0x03 }, + { 0x303a, 0x0c }, + { 0x3040, 0x00 }, + { 0x3041, 0x00 }, +@@ -169,7 +173,6 @@ static const struct imx290_regval imx290 + { 0x3164, 0x1a }, + { 0x3480, 0x49 }, + /* data rate settings */ +- { 0x3009, 0x01 }, + { 0x3405, 0x10 }, + { 0x3446, 0x57 }, + { 0x3447, 0x00 }, +@@ -187,8 +190,6 @@ static const struct imx290_regval imx290 + { 0x3453, 0x00 }, + { 0x3454, 0x17 }, + { 0x3455, 0x00 }, +- { 0x301c, 0x98 }, +- { 0x301d, 0x08 }, + }; + + static const struct imx290_regval imx290_720p_settings[] = { +@@ -210,7 +211,6 @@ static const struct imx290_regval imx290 + { 0x3164, 0x1a }, + { 0x3480, 0x49 }, + /* data rate settings */ +- { 0x3009, 0x01 }, + { 0x3405, 0x10 }, + { 0x3446, 0x4f }, + { 0x3447, 0x00 }, +@@ -228,8 +228,6 @@ static const struct imx290_regval imx290 + { 0x3453, 0x00 }, + { 0x3454, 0x17 }, + { 0x3455, 0x00 }, +- { 0x301c, 0xe4 }, +- { 0x301d, 0x0c }, + }; + + static const struct imx290_regval imx290_10bit_settings[] = { +@@ -250,10 +248,11 @@ static const s64 imx290_link_freq[] = { + }; + + /* Mode configs */ +-static const struct imx290_mode imx290_modes[] = { ++static const struct imx290_mode imx290_modes_2lanes[] = { + { + .width = 1920, + .height = 1080, ++ .hmax = 0x1130, + .data = imx290_1080p_settings, + .data_size = ARRAY_SIZE(imx290_1080p_settings), + .pixel_rate = 178200000, +@@ -262,6 +261,7 @@ static const struct imx290_mode imx290_m + { + .width = 1280, + .height = 720, ++ .hmax = 0x19c8, + .data = imx290_720p_settings, + .data_size = ARRAY_SIZE(imx290_720p_settings), + .pixel_rate = 178200000, +@@ -269,6 +269,44 @@ static const struct imx290_mode imx290_m + }, + }; + ++static const struct imx290_mode imx290_modes_4lanes[] = { ++ { ++ .width = 1920, ++ .height = 1080, ++ .hmax = 0x0898, ++ .data = imx290_1080p_settings, ++ .data_size = ARRAY_SIZE(imx290_1080p_settings), ++ .pixel_rate = 178200000, ++ .link_freq_index = 0, ++ }, ++ { ++ .width = 1280, ++ .height = 720, ++ .hmax = 0x0ce4, ++ .data = imx290_720p_settings, ++ .data_size = ARRAY_SIZE(imx290_720p_settings), ++ .pixel_rate = 178200000, ++ .link_freq_index = 0, ++ }, ++}; ++ ++static inline const struct imx290_mode *imx290_modes_ptr(const struct imx290 *imx290) ++{ ++ /* We rely on imx290_probe() to ensure that nlanes is either 2 or 4 */ ++ if (imx290->nlanes == 2) ++ return imx290_modes_2lanes; ++ else ++ return imx290_modes_4lanes; ++} ++ ++static inline int imx290_modes_num(const struct imx290 *imx290) ++{ ++ if (imx290->nlanes == 2) ++ return ARRAY_SIZE(imx290_modes_2lanes); ++ else ++ return ARRAY_SIZE(imx290_modes_4lanes); ++} ++ + static inline struct imx290 *to_imx290(struct v4l2_subdev *_sd) + { + return container_of(_sd, struct imx290, sd); +@@ -450,9 +488,8 @@ static int imx290_set_fmt(struct v4l2_su + + mutex_lock(&imx290->lock); + +- mode = v4l2_find_nearest_size(imx290_modes, +- ARRAY_SIZE(imx290_modes), +- width, height, ++ mode = v4l2_find_nearest_size(imx290_modes_ptr(imx290), ++ imx290_modes_num(imx290), width, height, + fmt->format.width, fmt->format.height); + + fmt->format.width = mode->width; +@@ -522,6 +559,25 @@ static int imx290_write_current_format(s + return 0; + } + ++static int imx290_set_hmax(struct imx290 *imx290, u32 val) ++{ ++ int ret; ++ ++ ret = imx290_write_reg(imx290, IMX290_HMAX_LOW, (val & 0xff)); ++ if (ret) { ++ dev_err(imx290->dev, "Error setting HMAX register\n"); ++ return ret; ++ } ++ ++ ret = imx290_write_reg(imx290, IMX290_HMAX_HIGH, ((val >> 8) & 0xff)); ++ if (ret) { ++ dev_err(imx290->dev, "Error setting HMAX register\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ + /* Start streaming */ + static int imx290_start_streaming(struct imx290 *imx290) + { +@@ -550,6 +606,9 @@ static int imx290_start_streaming(struct + dev_err(imx290->dev, "Could not set current mode\n"); + return ret; + } ++ ret = imx290_set_hmax(imx290, imx290->current_mode->hmax); ++ if (ret < 0) ++ return ret; + + /* Apply customized values from user */ + ret = v4l2_ctrl_handler_setup(imx290->sd.ctrl_handler); +@@ -607,6 +666,49 @@ static int imx290_get_regulators(struct + imx290->supplies); + } + ++static int imx290_set_data_lanes(struct imx290 *imx290) ++{ ++ int ret = 0, laneval, frsel; ++ ++ switch (imx290->nlanes) { ++ case 2: ++ laneval = 0x01; ++ frsel = 0x02; ++ break; ++ case 4: ++ laneval = 0x03; ++ frsel = 0x01; ++ break; ++ default: ++ /* ++ * We should never hit this since the data lane count is ++ * validated in probe itself ++ */ ++ dev_err(imx290->dev, "Lane configuration not supported\n"); ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ ret = imx290_write_reg(imx290, IMX290_PHY_LANE_NUM, laneval); ++ if (ret) { ++ dev_err(imx290->dev, "Error setting Physical Lane number register\n"); ++ goto exit; ++ } ++ ++ ret = imx290_write_reg(imx290, IMX290_CSI_LANE_MODE, laneval); ++ if (ret) { ++ dev_err(imx290->dev, "Error setting CSI Lane mode register\n"); ++ goto exit; ++ } ++ ++ ret = imx290_write_reg(imx290, IMX290_FR_FDG_SEL, frsel); ++ if (ret) ++ dev_err(imx290->dev, "Error setting FR/FDG SEL register\n"); ++ ++exit: ++ return ret; ++} ++ + static int imx290_power_on(struct device *dev) + { + struct i2c_client *client = to_i2c_client(dev); +@@ -631,6 +733,9 @@ static int imx290_power_on(struct device + gpiod_set_value_cansleep(imx290->rst_gpio, 0); + usleep_range(30000, 31000); + ++ /* Set data lane count */ ++ imx290_set_data_lanes(imx290); ++ + return 0; + } + +@@ -677,6 +782,7 @@ static int imx290_probe(struct i2c_clien + struct fwnode_handle *endpoint; + struct imx290 *imx290; + u32 xclk_freq; ++ u32 default_pixel_rate; + int ret; + + imx290 = devm_kzalloc(dev, sizeof(*imx290), GFP_KERNEL); +@@ -703,6 +809,16 @@ static int imx290_probe(struct i2c_clien + goto free_err; + } + ++ /* Get number of data lanes */ ++ imx290->nlanes = imx290->ep.bus.mipi_csi2.num_data_lanes; ++ if (imx290->nlanes != 2 && imx290->nlanes != 4) { ++ dev_err(dev, "Invalid data lanes: %d\n", imx290->nlanes); ++ ret = -EINVAL; ++ goto free_err; ++ } ++ ++ dev_dbg(dev, "Using %u data lanes\n", imx290->nlanes); ++ + if (!imx290->ep.nr_of_link_frequencies) { + dev_err(dev, "link-frequency property not found in DT\n"); + ret = -EINVAL; +@@ -780,10 +896,13 @@ static int imx290_probe(struct i2c_clien + if (imx290->link_freq) + imx290->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; + ++ default_pixel_rate = imx290->nlanes == 2 ? ++ imx290_modes_2lanes[0].pixel_rate : ++ imx290_modes_4lanes[0].pixel_rate; + imx290->pixel_rate = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, + V4L2_CID_PIXEL_RATE, 1, + INT_MAX, 1, +- imx290_modes[0].pixel_rate); ++ default_pixel_rate); + + imx290->sd.ctrl_handler = &imx290->ctrls; + diff --git a/target/linux/bcm27xx/patches-5.4/950-0821-media-i2c-imx290-Add-configurable-link-frequency-and.patch b/target/linux/bcm27xx/patches-5.4/950-0821-media-i2c-imx290-Add-configurable-link-frequency-and.patch new file mode 100644 index 0000000000..f74627962e --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0821-media-i2c-imx290-Add-configurable-link-frequency-and.patch @@ -0,0 +1,307 @@ +From e3c6ec43e950d9e08715e2c693771080c7d078a3 Mon Sep 17 00:00:00 2001 +From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Date: Fri, 12 Jun 2020 15:53:50 +0200 +Subject: [PATCH] media: i2c: imx290: Add configurable link frequency + and pixel rate + +Commit 98e0500eadb772e1be32d8e369fcc3b7bcac93ed upstream. + +IMX290 operates with multiple link frequency and pixel rate combinations. +The initial driver used a single setting for both but since we now have +the lane count support in place, let's add configurable link frequency +and pixel rate. + +Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org> +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/i2c/imx290.c | 148 +++++++++++++++++++++++++++---------- + 1 file changed, 109 insertions(+), 39 deletions(-) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -32,8 +32,6 @@ + #define IMX290_PHY_LANE_NUM 0x3407 + #define IMX290_CSI_LANE_MODE 0x3443 + +-#define IMX290_DEFAULT_LINK_FREQ 445500000 +- + static const char * const imx290_supply_name[] = { + "vdda", + "vddd", +@@ -51,8 +49,7 @@ struct imx290_mode { + u32 width; + u32 height; + u32 hmax; +- u32 pixel_rate; +- u32 link_freq_index; ++ u8 link_freq_index; + + const struct imx290_regval *data; + u32 data_size; +@@ -243,9 +240,36 @@ static const struct imx290_regval imx290 + }; + + /* supported link frequencies */ +-static const s64 imx290_link_freq[] = { +- IMX290_DEFAULT_LINK_FREQ, +-}; ++#define FREQ_INDEX_1080P 0 ++#define FREQ_INDEX_720P 1 ++static const s64 imx290_link_freq_2lanes[] = { ++ [FREQ_INDEX_1080P] = 445500000, ++ [FREQ_INDEX_720P] = 297000000, ++}; ++static const s64 imx290_link_freq_4lanes[] = { ++ [FREQ_INDEX_1080P] = 222750000, ++ [FREQ_INDEX_720P] = 148500000, ++}; ++ ++/* ++ * In this function and in the similar ones below We rely on imx290_probe() ++ * to ensure that nlanes is either 2 or 4. ++ */ ++static inline const s64 *imx290_link_freqs_ptr(const struct imx290 *imx290) ++{ ++ if (imx290->nlanes == 2) ++ return imx290_link_freq_2lanes; ++ else ++ return imx290_link_freq_4lanes; ++} ++ ++static inline int imx290_link_freqs_num(const struct imx290 *imx290) ++{ ++ if (imx290->nlanes == 2) ++ return ARRAY_SIZE(imx290_link_freq_2lanes); ++ else ++ return ARRAY_SIZE(imx290_link_freq_4lanes); ++} + + /* Mode configs */ + static const struct imx290_mode imx290_modes_2lanes[] = { +@@ -253,19 +277,17 @@ static const struct imx290_mode imx290_m + .width = 1920, + .height = 1080, + .hmax = 0x1130, ++ .link_freq_index = FREQ_INDEX_1080P, + .data = imx290_1080p_settings, + .data_size = ARRAY_SIZE(imx290_1080p_settings), +- .pixel_rate = 178200000, +- .link_freq_index = 0, + }, + { + .width = 1280, + .height = 720, + .hmax = 0x19c8, ++ .link_freq_index = FREQ_INDEX_720P, + .data = imx290_720p_settings, + .data_size = ARRAY_SIZE(imx290_720p_settings), +- .pixel_rate = 178200000, +- .link_freq_index = 0, + }, + }; + +@@ -274,25 +296,22 @@ static const struct imx290_mode imx290_m + .width = 1920, + .height = 1080, + .hmax = 0x0898, ++ .link_freq_index = FREQ_INDEX_1080P, + .data = imx290_1080p_settings, + .data_size = ARRAY_SIZE(imx290_1080p_settings), +- .pixel_rate = 178200000, +- .link_freq_index = 0, + }, + { + .width = 1280, + .height = 720, + .hmax = 0x0ce4, ++ .link_freq_index = FREQ_INDEX_720P, + .data = imx290_720p_settings, + .data_size = ARRAY_SIZE(imx290_720p_settings), +- .pixel_rate = 178200000, +- .link_freq_index = 0, + }, + }; + + static inline const struct imx290_mode *imx290_modes_ptr(const struct imx290 *imx290) + { +- /* We rely on imx290_probe() to ensure that nlanes is either 2 or 4 */ + if (imx290->nlanes == 2) + return imx290_modes_2lanes; + else +@@ -477,6 +496,30 @@ static int imx290_get_fmt(struct v4l2_su + return 0; + } + ++static inline u8 imx290_get_link_freq_index(struct imx290 *imx290) ++{ ++ return imx290->current_mode->link_freq_index; ++} ++ ++static s64 imx290_get_link_freq(struct imx290 *imx290) ++{ ++ u8 index = imx290_get_link_freq_index(imx290); ++ ++ return *(imx290_link_freqs_ptr(imx290) + index); ++} ++ ++static u64 imx290_calc_pixel_rate(struct imx290 *imx290) ++{ ++ s64 link_freq = imx290_get_link_freq(imx290); ++ u8 nlanes = imx290->nlanes; ++ u64 pixel_rate; ++ ++ /* pixel rate = link_freq * 2 * nr_of_lanes / bits_per_sample */ ++ pixel_rate = link_freq * 2 * nlanes; ++ do_div(pixel_rate, 10); ++ return pixel_rate; ++} ++ + static int imx290_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +@@ -509,10 +552,14 @@ static int imx290_set_fmt(struct v4l2_su + format = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + } else { + format = &imx290->current_format; +- __v4l2_ctrl_s_ctrl(imx290->link_freq, mode->link_freq_index); +- __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate, mode->pixel_rate); +- + imx290->current_mode = mode; ++ ++ if (imx290->link_freq) ++ __v4l2_ctrl_s_ctrl(imx290->link_freq, ++ imx290_get_link_freq_index(imx290)); ++ if (imx290->pixel_rate) ++ __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate, ++ imx290_calc_pixel_rate(imx290)); + } + + *format = fmt->format; +@@ -536,12 +583,11 @@ static int imx290_entity_init_cfg(struct + return 0; + } + +-static int imx290_write_current_format(struct imx290 *imx290, +- struct v4l2_mbus_framefmt *format) ++static int imx290_write_current_format(struct imx290 *imx290) + { + int ret; + +- switch (format->code) { ++ switch (imx290->current_format.code) { + case MEDIA_BUS_FMT_SRGGB10_1X10: + ret = imx290_set_register_array(imx290, imx290_10bit_settings, + ARRAY_SIZE( +@@ -592,8 +638,8 @@ static int imx290_start_streaming(struct + return ret; + } + +- /* Set current frame format */ +- ret = imx290_write_current_format(imx290, &imx290->current_format); ++ /* Apply the register values related to current frame format */ ++ ret = imx290_write_current_format(imx290); + if (ret < 0) { + dev_err(imx290->dev, "Could not set frame format\n"); + return ret; +@@ -776,13 +822,34 @@ static const struct media_entity_operati + .link_validate = v4l2_subdev_link_validate, + }; + ++/* ++ * Returns 0 if all link frequencies used by the driver for the given number ++ * of MIPI data lanes are mentioned in the device tree, or the value of the ++ * first missing frequency otherwise. ++ */ ++static s64 imx290_check_link_freqs(const struct imx290 *imx290) ++{ ++ int i, j; ++ const s64 *freqs = imx290_link_freqs_ptr(imx290); ++ int freqs_count = imx290_link_freqs_num(imx290); ++ ++ for (i = 0; i < freqs_count; i++) { ++ for (j = 0; j < imx290->ep.nr_of_link_frequencies; j++) ++ if (freqs[i] == imx290->ep.link_frequencies[j]) ++ break; ++ if (j == imx290->ep.nr_of_link_frequencies) ++ return freqs[i]; ++ } ++ return 0; ++} ++ + static int imx290_probe(struct i2c_client *client) + { + struct device *dev = &client->dev; + struct fwnode_handle *endpoint; + struct imx290 *imx290; + u32 xclk_freq; +- u32 default_pixel_rate; ++ s64 fq; + int ret; + + imx290 = devm_kzalloc(dev, sizeof(*imx290), GFP_KERNEL); +@@ -825,8 +892,10 @@ static int imx290_probe(struct i2c_clien + goto free_err; + } + +- if (imx290->ep.link_frequencies[0] != IMX290_DEFAULT_LINK_FREQ) { +- dev_err(dev, "Unsupported link frequency\n"); ++ /* Check that link frequences for all the modes are in device tree */ ++ fq = imx290_check_link_freqs(imx290); ++ if (fq) { ++ dev_err(dev, "Link frequency of %lld is not supported\n", fq); + ret = -EINVAL; + goto free_err; + } +@@ -883,26 +952,30 @@ static int imx290_probe(struct i2c_clien + + mutex_init(&imx290->lock); + ++ /* ++ * Initialize the frame format. In particular, imx290->current_mode ++ * and imx290->bpp are set to defaults: imx290_calc_pixel_rate() call ++ * below relies on these fields. ++ */ ++ imx290_entity_init_cfg(&imx290->sd, NULL); ++ + v4l2_ctrl_handler_init(&imx290->ctrls, 3); + + v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, + V4L2_CID_GAIN, 0, 72, 1, 0); ++ + imx290->link_freq = +- v4l2_ctrl_new_int_menu(&imx290->ctrls, +- &imx290_ctrl_ops, ++ v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops, + V4L2_CID_LINK_FREQ, +- ARRAY_SIZE(imx290_link_freq) - 1, +- 0, imx290_link_freq); ++ imx290_link_freqs_num(imx290) - 1, 0, ++ imx290_link_freqs_ptr(imx290)); + if (imx290->link_freq) + imx290->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; + +- default_pixel_rate = imx290->nlanes == 2 ? +- imx290_modes_2lanes[0].pixel_rate : +- imx290_modes_4lanes[0].pixel_rate; + imx290->pixel_rate = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, +- V4L2_CID_PIXEL_RATE, 1, +- INT_MAX, 1, +- default_pixel_rate); ++ V4L2_CID_PIXEL_RATE, ++ 1, INT_MAX, 1, ++ imx290_calc_pixel_rate(imx290)); + + imx290->sd.ctrl_handler = &imx290->ctrls; + +@@ -926,9 +999,6 @@ static int imx290_probe(struct i2c_clien + goto free_ctrl; + } + +- /* Initialize the frame format (this also sets imx290->current_mode) */ +- imx290_entity_init_cfg(&imx290->sd, NULL); +- + ret = v4l2_async_register_subdev(&imx290->sd); + if (ret < 0) { + dev_err(dev, "Could not register v4l2 device\n"); diff --git a/target/linux/bcm27xx/patches-5.4/950-0822-media-i2c-imx290-Add-support-for-test-pattern-genera.patch b/target/linux/bcm27xx/patches-5.4/950-0822-media-i2c-imx290-Add-support-for-test-pattern-genera.patch new file mode 100644 index 0000000000..e7900ab800 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0822-media-i2c-imx290-Add-support-for-test-pattern-genera.patch @@ -0,0 +1,110 @@ +From f1a8ae8064a65846489386fe95790900fb150242 Mon Sep 17 00:00:00 2001 +From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Date: Fri, 12 Jun 2020 15:53:51 +0200 +Subject: [PATCH] media: i2c: imx290: Add support for test pattern + generation + +Commit a58df1f9e4885eaf3d0663574a217e513821a9f0 upstream. + +Add support for generating following test patterns by IMX290: + +* Sequence Pattern 1 +* Horizontal Color-bar Chart +* Vertical Color-bar Chart +* Sequence Pattern 2 +* Gradation Pattern 1 +* Gradation Pattern 2 +* 000/555h Toggle Pattern + +Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org> +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/i2c/imx290.c | 41 +++++++++++++++++++++++++++++++++++++- + 1 file changed, 40 insertions(+), 1 deletion(-) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -26,12 +26,19 @@ + #define IMX290_REGHOLD 0x3001 + #define IMX290_XMSTA 0x3002 + #define IMX290_FR_FDG_SEL 0x3009 ++#define IMX290_BLKLEVEL_LOW 0x300a ++#define IMX290_BLKLEVEL_HIGH 0x300b + #define IMX290_GAIN 0x3014 + #define IMX290_HMAX_LOW 0x301c + #define IMX290_HMAX_HIGH 0x301d ++#define IMX290_PGCTRL 0x308c + #define IMX290_PHY_LANE_NUM 0x3407 + #define IMX290_CSI_LANE_MODE 0x3443 + ++#define IMX290_PGCTRL_REGEN BIT(0) ++#define IMX290_PGCTRL_THRU BIT(1) ++#define IMX290_PGCTRL_MODE(n) ((n) << 4) ++ + static const char * const imx290_supply_name[] = { + "vdda", + "vddd", +@@ -91,6 +98,17 @@ static const struct regmap_config imx290 + .cache_type = REGCACHE_RBTREE, + }; + ++static const char * const imx290_test_pattern_menu[] = { ++ "Disabled", ++ "Sequence Pattern 1", ++ "Horizontal Color-bar Chart", ++ "Vertical Color-bar Chart", ++ "Sequence Pattern 2", ++ "Gradation Pattern 1", ++ "Gradation Pattern 2", ++ "000/555h Toggle Pattern", ++}; ++ + static const struct imx290_regval imx290_global_init_settings[] = { + { 0x3007, 0x00 }, + { 0x3018, 0x65 }, +@@ -448,6 +466,22 @@ static int imx290_set_ctrl(struct v4l2_c + case V4L2_CID_GAIN: + ret = imx290_set_gain(imx290, ctrl->val); + break; ++ case V4L2_CID_TEST_PATTERN: ++ if (ctrl->val) { ++ imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x00); ++ imx290_write_reg(imx290, IMX290_BLKLEVEL_HIGH, 0x00); ++ msleep(10); ++ imx290_write_reg(imx290, IMX290_PGCTRL, ++ (u8)(IMX290_PGCTRL_REGEN | ++ IMX290_PGCTRL_THRU | ++ IMX290_PGCTRL_MODE(ctrl->val))); ++ } else { ++ imx290_write_reg(imx290, IMX290_PGCTRL, 0x00); ++ msleep(10); ++ imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x3c); ++ imx290_write_reg(imx290, IMX290_BLKLEVEL_HIGH, 0x00); ++ } ++ break; + default: + ret = -EINVAL; + break; +@@ -959,7 +993,7 @@ static int imx290_probe(struct i2c_clien + */ + imx290_entity_init_cfg(&imx290->sd, NULL); + +- v4l2_ctrl_handler_init(&imx290->ctrls, 3); ++ v4l2_ctrl_handler_init(&imx290->ctrls, 4); + + v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, + V4L2_CID_GAIN, 0, 72, 1, 0); +@@ -977,6 +1011,11 @@ static int imx290_probe(struct i2c_clien + 1, INT_MAX, 1, + imx290_calc_pixel_rate(imx290)); + ++ v4l2_ctrl_new_std_menu_items(&imx290->ctrls, &imx290_ctrl_ops, ++ V4L2_CID_TEST_PATTERN, ++ ARRAY_SIZE(imx290_test_pattern_menu) - 1, ++ 0, 0, imx290_test_pattern_menu); ++ + imx290->sd.ctrl_handler = &imx290->ctrls; + + if (imx290->ctrls.error) { diff --git a/target/linux/bcm27xx/patches-5.4/950-0823-media-i2c-imx290-Add-RAW12-mode-support.patch b/target/linux/bcm27xx/patches-5.4/950-0823-media-i2c-imx290-Add-RAW12-mode-support.patch new file mode 100644 index 0000000000..6e437350c8 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0823-media-i2c-imx290-Add-RAW12-mode-support.patch @@ -0,0 +1,109 @@ +From 9f6a310ab3b466940c0a15260987d4cfe868a79a Mon Sep 17 00:00:00 2001 +From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Date: Fri, 12 Jun 2020 15:53:52 +0200 +Subject: [PATCH] media: i2c: imx290: Add RAW12 mode support + +Commit c566ac01ceaa02450acc155201772c0623530e76 upstream. + +IMX290 is capable of outputting frames in both Raw Bayer (packed) 10 and +12 bit formats. Since the driver already supports RAW10 mode, let's add +the missing RAW12 mode as well. + +Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org> +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/i2c/imx290.c | 36 +++++++++++++++++++++++++++++++++--- + 1 file changed, 33 insertions(+), 3 deletions(-) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -67,6 +67,7 @@ struct imx290 { + struct clk *xclk; + struct regmap *regmap; + u8 nlanes; ++ u8 bpp; + + struct v4l2_subdev sd; + struct v4l2_fwnode_endpoint ep; +@@ -86,10 +87,12 @@ struct imx290 { + + struct imx290_pixfmt { + u32 code; ++ u8 bpp; + }; + + static const struct imx290_pixfmt imx290_formats[] = { +- { MEDIA_BUS_FMT_SRGGB10_1X10 }, ++ { MEDIA_BUS_FMT_SRGGB10_1X10, 10 }, ++ { MEDIA_BUS_FMT_SRGGB12_1X12, 12 }, + }; + + static const struct regmap_config imx290_regmap_config = { +@@ -257,6 +260,18 @@ static const struct imx290_regval imx290 + { 0x300b, 0x00}, + }; + ++static const struct imx290_regval imx290_12bit_settings[] = { ++ { 0x3005, 0x01 }, ++ { 0x3046, 0x01 }, ++ { 0x3129, 0x00 }, ++ { 0x317c, 0x00 }, ++ { 0x31ec, 0x0e }, ++ { 0x3441, 0x0c }, ++ { 0x3442, 0x0c }, ++ { 0x300a, 0xf0 }, ++ { 0x300b, 0x00 }, ++}; ++ + /* supported link frequencies */ + #define FREQ_INDEX_1080P 0 + #define FREQ_INDEX_720P 1 +@@ -478,7 +493,12 @@ static int imx290_set_ctrl(struct v4l2_c + } else { + imx290_write_reg(imx290, IMX290_PGCTRL, 0x00); + msleep(10); +- imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x3c); ++ if (imx290->bpp == 10) ++ imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, ++ 0x3c); ++ else /* 12 bits per pixel */ ++ imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, ++ 0xf0); + imx290_write_reg(imx290, IMX290_BLKLEVEL_HIGH, 0x00); + } + break; +@@ -550,7 +570,7 @@ static u64 imx290_calc_pixel_rate(struct + + /* pixel rate = link_freq * 2 * nr_of_lanes / bits_per_sample */ + pixel_rate = link_freq * 2 * nlanes; +- do_div(pixel_rate, 10); ++ do_div(pixel_rate, imx290->bpp); + return pixel_rate; + } + +@@ -587,6 +607,7 @@ static int imx290_set_fmt(struct v4l2_su + } else { + format = &imx290->current_format; + imx290->current_mode = mode; ++ imx290->bpp = imx290_formats[i].bpp; + + if (imx290->link_freq) + __v4l2_ctrl_s_ctrl(imx290->link_freq, +@@ -629,6 +650,15 @@ static int imx290_write_current_format(s + if (ret < 0) { + dev_err(imx290->dev, "Could not set format registers\n"); + return ret; ++ } ++ break; ++ case MEDIA_BUS_FMT_SRGGB12_1X12: ++ ret = imx290_set_register_array(imx290, imx290_12bit_settings, ++ ARRAY_SIZE( ++ imx290_12bit_settings)); ++ if (ret < 0) { ++ dev_err(imx290->dev, "Could not set format registers\n"); ++ return ret; + } + break; + default: diff --git a/target/linux/bcm27xx/patches-5.4/950-0824-media-i2c-imx290-Add-support-to-enumerate-all-frame-.patch b/target/linux/bcm27xx/patches-5.4/950-0824-media-i2c-imx290-Add-support-to-enumerate-all-frame-.patch new file mode 100644 index 0000000000..8ae528a423 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0824-media-i2c-imx290-Add-support-to-enumerate-all-frame-.patch @@ -0,0 +1,58 @@ +From 9ca04663315302f1556798e9da29eabf08aecd59 Mon Sep 17 00:00:00 2001 +From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Date: Fri, 12 Jun 2020 15:53:53 +0200 +Subject: [PATCH] media: i2c: imx290: Add support to enumerate all + frame sizes + +Commit 3b867fb641d884b714fba390ae866714ba475f29 upstream. + +Add support to enumerate all frame sizes supported by IMX290. This is +required for using with userspace tools such as libcamera. + +Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org> +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/i2c/imx290.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -528,6 +528,28 @@ static int imx290_enum_mbus_code(struct + return 0; + } + ++static int imx290_enum_frame_size(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_frame_size_enum *fse) ++{ ++ const struct imx290 *imx290 = to_imx290(sd); ++ const struct imx290_mode *imx290_modes = imx290_modes_ptr(imx290); ++ ++ if ((fse->code != imx290_formats[0].code) && ++ (fse->code != imx290_formats[1].code)) ++ return -EINVAL; ++ ++ if (fse->index >= imx290_modes_num(imx290)) ++ return -EINVAL; ++ ++ fse->min_width = imx290_modes[fse->index].width; ++ fse->max_width = imx290_modes[fse->index].width; ++ fse->min_height = imx290_modes[fse->index].height; ++ fse->max_height = imx290_modes[fse->index].height; ++ ++ return 0; ++} ++ + static int imx290_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +@@ -873,6 +895,7 @@ static const struct v4l2_subdev_video_op + static const struct v4l2_subdev_pad_ops imx290_pad_ops = { + .init_cfg = imx290_entity_init_cfg, + .enum_mbus_code = imx290_enum_mbus_code, ++ .enum_frame_size = imx290_enum_frame_size, + .get_fmt = imx290_get_fmt, + .set_fmt = imx290_set_fmt, + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0825-media-i2c-imx290-Move-the-settle-time-delay-out-of-l.patch b/target/linux/bcm27xx/patches-5.4/950-0825-media-i2c-imx290-Move-the-settle-time-delay-out-of-l.patch new file mode 100644 index 0000000000..a46c0c98ea --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0825-media-i2c-imx290-Move-the-settle-time-delay-out-of-l.patch @@ -0,0 +1,37 @@ +From d2155366275ce70438d12169a59959e90b637f9c Mon Sep 17 00:00:00 2001 +From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Date: Fri, 12 Jun 2020 15:53:54 +0200 +Subject: [PATCH] media: i2c: imx290: Move the settle time delay out + of loop + +Commit 6544af9b04b4484867c234ba0be1b5008e4a14ee upstream. + +The 10ms settle time is needed only at the end of all consecutive +register writes. So move the delay to outside of the for loop of +imx290_set_register_array(). + +Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org> +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/i2c/imx290.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -404,11 +404,11 @@ static int imx290_set_register_array(str + ret = imx290_write_reg(imx290, settings->reg, settings->val); + if (ret < 0) + return ret; +- +- /* Settle time is 10ms for all registers */ +- msleep(10); + } + ++ /* Provide 10ms settle time */ ++ msleep(10); ++ + return 0; + } + diff --git a/target/linux/bcm27xx/patches-5.4/950-0826-media-i2c-imx290-set-bus_type-before-calling-v4l2_fw.patch b/target/linux/bcm27xx/patches-5.4/950-0826-media-i2c-imx290-set-bus_type-before-calling-v4l2_fw.patch new file mode 100644 index 0000000000..5180ee60e7 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0826-media-i2c-imx290-set-bus_type-before-calling-v4l2_fw.patch @@ -0,0 +1,137 @@ +From e5b34fd95be9c59fe55e4755ba84aa05efaaaf62 Mon Sep 17 00:00:00 2001 +From: Andrey Konovalov <andrey.konovalov@linaro.org> +Date: Fri, 12 Jun 2020 15:53:55 +0200 +Subject: [PATCH] media: i2c: imx290: set bus_type before calling + v4l2_fwnode_endpoint_alloc_parse() + +Commit a270675875829b6d46eb9e38960fd6019555ebb8 upstream. + +The bus_type field of v4l2_fwnode_endpoint structure passed as the argument +to v4l2_fwnode_endpoint_alloc_parse() function must be initiaized. +Set it to V4L2_MBUS_CSI2_DPHY, and check for -ENXIO which is returned +when the requested media bus type doesn't match the fwnode. + +Also remove v4l2_fwnode_endpoint field from struct imx290 as it is only +needed in the probe function: use the local variable for this purpose. + +Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org> +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/i2c/imx290.c | 38 +++++++++++++++++++------------------- + 1 file changed, 19 insertions(+), 19 deletions(-) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -70,7 +70,6 @@ struct imx290 { + u8 bpp; + + struct v4l2_subdev sd; +- struct v4l2_fwnode_endpoint ep; + struct media_pad pad; + struct v4l2_mbus_framefmt current_format; + const struct imx290_mode *current_mode; +@@ -914,17 +913,18 @@ static const struct media_entity_operati + * of MIPI data lanes are mentioned in the device tree, or the value of the + * first missing frequency otherwise. + */ +-static s64 imx290_check_link_freqs(const struct imx290 *imx290) ++static s64 imx290_check_link_freqs(const struct imx290 *imx290, ++ const struct v4l2_fwnode_endpoint *ep) + { + int i, j; + const s64 *freqs = imx290_link_freqs_ptr(imx290); + int freqs_count = imx290_link_freqs_num(imx290); + + for (i = 0; i < freqs_count; i++) { +- for (j = 0; j < imx290->ep.nr_of_link_frequencies; j++) +- if (freqs[i] == imx290->ep.link_frequencies[j]) ++ for (j = 0; j < ep->nr_of_link_frequencies; j++) ++ if (freqs[i] == ep->link_frequencies[j]) + break; +- if (j == imx290->ep.nr_of_link_frequencies) ++ if (j == ep->nr_of_link_frequencies) + return freqs[i]; + } + return 0; +@@ -934,6 +934,10 @@ static int imx290_probe(struct i2c_clien + { + struct device *dev = &client->dev; + struct fwnode_handle *endpoint; ++ /* Only CSI2 is supported for now: */ ++ struct v4l2_fwnode_endpoint ep = { ++ .bus_type = V4L2_MBUS_CSI2_DPHY ++ }; + struct imx290 *imx290; + u32 xclk_freq; + s64 fq; +@@ -956,15 +960,18 @@ static int imx290_probe(struct i2c_clien + return -EINVAL; + } + +- ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &imx290->ep); ++ ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep); + fwnode_handle_put(endpoint); +- if (ret) { ++ if (ret == -ENXIO) { ++ dev_err(dev, "Unsupported bus type, should be CSI2\n"); ++ goto free_err; ++ } else if (ret) { + dev_err(dev, "Parsing endpoint node failed\n"); + goto free_err; + } + + /* Get number of data lanes */ +- imx290->nlanes = imx290->ep.bus.mipi_csi2.num_data_lanes; ++ imx290->nlanes = ep.bus.mipi_csi2.num_data_lanes; + if (imx290->nlanes != 2 && imx290->nlanes != 4) { + dev_err(dev, "Invalid data lanes: %d\n", imx290->nlanes); + ret = -EINVAL; +@@ -973,27 +980,20 @@ static int imx290_probe(struct i2c_clien + + dev_dbg(dev, "Using %u data lanes\n", imx290->nlanes); + +- if (!imx290->ep.nr_of_link_frequencies) { ++ if (!ep.nr_of_link_frequencies) { + dev_err(dev, "link-frequency property not found in DT\n"); + ret = -EINVAL; + goto free_err; + } + + /* Check that link frequences for all the modes are in device tree */ +- fq = imx290_check_link_freqs(imx290); ++ fq = imx290_check_link_freqs(imx290, &ep); + if (fq) { + dev_err(dev, "Link frequency of %lld is not supported\n", fq); + ret = -EINVAL; + goto free_err; + } + +- /* Only CSI2 is supported for now */ +- if (imx290->ep.bus_type != V4L2_MBUS_CSI2_DPHY) { +- dev_err(dev, "Unsupported bus type, should be CSI2\n"); +- ret = -EINVAL; +- goto free_err; +- } +- + /* get system clock (xclk) */ + imx290->xclk = devm_clk_get(dev, "xclk"); + if (IS_ERR(imx290->xclk)) { +@@ -1108,7 +1108,7 @@ static int imx290_probe(struct i2c_clien + pm_runtime_enable(dev); + pm_runtime_idle(dev); + +- v4l2_fwnode_endpoint_free(&imx290->ep); ++ v4l2_fwnode_endpoint_free(&ep); + + return 0; + +@@ -1118,7 +1118,7 @@ free_ctrl: + v4l2_ctrl_handler_free(&imx290->ctrls); + mutex_destroy(&imx290->lock); + free_err: +- v4l2_fwnode_endpoint_free(&imx290->ep); ++ v4l2_fwnode_endpoint_free(&ep); + + return ret; + } diff --git a/target/linux/bcm27xx/patches-5.4/950-0827-media-i2c-imx290-Add-support-for-74.25MHz-clock.patch b/target/linux/bcm27xx/patches-5.4/950-0827-media-i2c-imx290-Add-support-for-74.25MHz-clock.patch new file mode 100644 index 0000000000..87661b7177 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0827-media-i2c-imx290-Add-support-for-74.25MHz-clock.patch @@ -0,0 +1,264 @@ +From c175c735869b0dfa8c21fc57d5bd02ca370f9117 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 25 Jun 2020 08:28:51 +0100 +Subject: [PATCH] media: i2c: imx290: Add support for 74.25MHz clock + +The existing driver only supported a clock of 37.125MHz, but the +sensor also supports 74.25MHz. + +Add the relevant register modifications to support this alternate +clock frequency. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/i2c/imx290.c | 119 ++++++++++++++++++++++++++++++------- + 1 file changed, 97 insertions(+), 22 deletions(-) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -1,6 +1,10 @@ + // SPDX-License-Identifier: GPL-2.0 + /* +- * Sony IMX290 CMOS Image Sensor Driver ++ * Sony IMX290/327 CMOS Image Sensor Driver ++ * ++ * The IMX290 and IMX327 are very similar 1920x1080 1/2.8 CMOS image sensors. ++ * IMX327 can support up to 60fps, whilst IMX290 support up to 120fps (only ++ * 10bit and when connected over 4 CSI-2 lanes). + * + * Copyright (C) 2019 FRAMOS GmbH. + * +@@ -22,6 +26,11 @@ + #include <media/v4l2-fwnode.h> + #include <media/v4l2-subdev.h> + ++enum imx290_clk_index { ++ CLK_37_125, ++ CLK_74_25, ++}; ++ + #define IMX290_STANDBY 0x3000 + #define IMX290_REGHOLD 0x3001 + #define IMX290_XMSTA 0x3002 +@@ -60,11 +69,16 @@ struct imx290_mode { + + const struct imx290_regval *data; + u32 data_size; ++ ++ /* Clock setup can vary. Index as enum imx290_clk_index */ ++ const struct imx290_regval *clk_data[2]; ++ u32 clk_size; + }; + + struct imx290 { + struct device *dev; + struct clk *xclk; ++ u32 xclk_freq; + struct regmap *regmap; + u8 nlanes; + u8 bpp; +@@ -116,8 +130,6 @@ static const struct imx290_regval imx290 + { 0x3018, 0x65 }, + { 0x3019, 0x04 }, + { 0x301a, 0x00 }, +- { 0x3444, 0x20 }, +- { 0x3445, 0x25 }, + { 0x303a, 0x0c }, + { 0x3040, 0x00 }, + { 0x3041, 0x00 }, +@@ -171,6 +183,30 @@ static const struct imx290_regval imx290 + { 0x33b3, 0x04 }, + }; + ++static const struct imx290_regval imx290_37_125mhz_clock_1080p[] = { ++ { 0x305c, 0x18 }, ++ { 0x305d, 0x03 }, ++ { 0x305e, 0x20 }, ++ { 0x305f, 0x01 }, ++ { 0x315e, 0x1a }, ++ { 0x3164, 0x1a }, ++ { 0x3444, 0x20 }, ++ { 0x3445, 0x25 }, ++ { 0x3480, 0x49 }, ++}; ++ ++static const struct imx290_regval imx290_74_250mhz_clock_1080p[] = { ++ { 0x305c, 0x0c }, ++ { 0x305d, 0x03 }, ++ { 0x305e, 0x10 }, ++ { 0x305f, 0x01 }, ++ { 0x315e, 0x1b }, ++ { 0x3164, 0x1b }, ++ { 0x3444, 0x40 }, ++ { 0x3445, 0x4a }, ++ { 0x3480, 0x92 }, ++}; ++ + static const struct imx290_regval imx290_1080p_settings[] = { + /* mode settings */ + { 0x3007, 0x00 }, +@@ -182,13 +218,6 @@ static const struct imx290_regval imx290 + { 0x3419, 0x04 }, + { 0x3012, 0x64 }, + { 0x3013, 0x00 }, +- { 0x305c, 0x18 }, +- { 0x305d, 0x03 }, +- { 0x305e, 0x20 }, +- { 0x305f, 0x01 }, +- { 0x315e, 0x1a }, +- { 0x3164, 0x1a }, +- { 0x3480, 0x49 }, + /* data rate settings */ + { 0x3405, 0x10 }, + { 0x3446, 0x57 }, +@@ -209,6 +238,30 @@ static const struct imx290_regval imx290 + { 0x3455, 0x00 }, + }; + ++static const struct imx290_regval imx290_37_125mhz_clock_720p[] = { ++ { 0x305c, 0x20 }, ++ { 0x305d, 0x00 }, ++ { 0x305e, 0x20 }, ++ { 0x305f, 0x01 }, ++ { 0x315e, 0x1a }, ++ { 0x3164, 0x1a }, ++ { 0x3444, 0x20 }, ++ { 0x3445, 0x25 }, ++ { 0x3480, 0x49 }, ++}; ++ ++static const struct imx290_regval imx290_74_250mhz_clock_720p[] = { ++ { 0x305c, 0x10 }, ++ { 0x305d, 0x00 }, ++ { 0x305e, 0x10 }, ++ { 0x305f, 0x01 }, ++ { 0x315e, 0x1b }, ++ { 0x3164, 0x1b }, ++ { 0x3444, 0x40 }, ++ { 0x3445, 0x4a }, ++ { 0x3480, 0x92 }, ++}; ++ + static const struct imx290_regval imx290_720p_settings[] = { + /* mode settings */ + { 0x3007, 0x10 }, +@@ -220,13 +273,6 @@ static const struct imx290_regval imx290 + { 0x3419, 0x02 }, + { 0x3012, 0x64 }, + { 0x3013, 0x00 }, +- { 0x305c, 0x20 }, +- { 0x305d, 0x00 }, +- { 0x305e, 0x20 }, +- { 0x305f, 0x01 }, +- { 0x315e, 0x1a }, +- { 0x3164, 0x1a }, +- { 0x3480, 0x49 }, + /* data rate settings */ + { 0x3405, 0x10 }, + { 0x3446, 0x4f }, +@@ -312,6 +358,11 @@ static const struct imx290_mode imx290_m + .link_freq_index = FREQ_INDEX_1080P, + .data = imx290_1080p_settings, + .data_size = ARRAY_SIZE(imx290_1080p_settings), ++ .clk_data = { ++ [CLK_37_125] = imx290_37_125mhz_clock_1080p, ++ [CLK_74_25] = imx290_74_250mhz_clock_1080p, ++ }, ++ .clk_size = ARRAY_SIZE(imx290_37_125mhz_clock_1080p), + }, + { + .width = 1280, +@@ -320,6 +371,11 @@ static const struct imx290_mode imx290_m + .link_freq_index = FREQ_INDEX_720P, + .data = imx290_720p_settings, + .data_size = ARRAY_SIZE(imx290_720p_settings), ++ .clk_data = { ++ [CLK_37_125] = imx290_37_125mhz_clock_1080p, ++ [CLK_74_25] = imx290_74_250mhz_clock_1080p, ++ }, ++ .clk_size = ARRAY_SIZE(imx290_37_125mhz_clock_1080p), + }, + }; + +@@ -331,6 +387,11 @@ static const struct imx290_mode imx290_m + .link_freq_index = FREQ_INDEX_1080P, + .data = imx290_1080p_settings, + .data_size = ARRAY_SIZE(imx290_1080p_settings), ++ .clk_data = { ++ [CLK_37_125] = imx290_37_125mhz_clock_720p, ++ [CLK_74_25] = imx290_74_250mhz_clock_720p, ++ }, ++ .clk_size = ARRAY_SIZE(imx290_37_125mhz_clock_720p), + }, + { + .width = 1280, +@@ -339,6 +400,11 @@ static const struct imx290_mode imx290_m + .link_freq_index = FREQ_INDEX_720P, + .data = imx290_720p_settings, + .data_size = ARRAY_SIZE(imx290_720p_settings), ++ .clk_data = { ++ [CLK_37_125] = imx290_37_125mhz_clock_720p, ++ [CLK_74_25] = imx290_74_250mhz_clock_720p, ++ }, ++ .clk_size = ARRAY_SIZE(imx290_37_125mhz_clock_720p), + }, + }; + +@@ -712,6 +778,8 @@ static int imx290_set_hmax(struct imx290 + /* Start streaming */ + static int imx290_start_streaming(struct imx290 *imx290) + { ++ enum imx290_clk_index clk_idx = imx290->xclk_freq == 37125000 ? ++ CLK_37_125 : CLK_74_25; + int ret; + + /* Set init register settings */ +@@ -723,6 +791,14 @@ static int imx290_start_streaming(struct + return ret; + } + ++ ret = imx290_set_register_array(imx290, ++ imx290->current_mode->clk_data[clk_idx], ++ imx290->current_mode->clk_size); ++ if (ret < 0) { ++ dev_err(imx290->dev, "Could not set clock registers\n"); ++ return ret; ++ } ++ + /* Apply the register values related to current frame format */ + ret = imx290_write_current_format(imx290); + if (ret < 0) { +@@ -939,7 +1015,6 @@ static int imx290_probe(struct i2c_clien + .bus_type = V4L2_MBUS_CSI2_DPHY + }; + struct imx290 *imx290; +- u32 xclk_freq; + s64 fq; + int ret; + +@@ -1003,21 +1078,21 @@ static int imx290_probe(struct i2c_clien + } + + ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency", +- &xclk_freq); ++ &imx290->xclk_freq); + if (ret) { + dev_err(dev, "Could not get xclk frequency\n"); + goto free_err; + } + + /* external clock must be 37.125 MHz */ +- if (xclk_freq != 37125000) { ++ if (imx290->xclk_freq != 37125000 && imx290->xclk_freq != 74250000) { + dev_err(dev, "External clock frequency %u is not supported\n", +- xclk_freq); ++ imx290->xclk_freq); + ret = -EINVAL; + goto free_err; + } + +- ret = clk_set_rate(imx290->xclk, xclk_freq); ++ ret = clk_set_rate(imx290->xclk, imx290->xclk_freq); + if (ret) { + dev_err(dev, "Could not set xclk frequency\n"); + goto free_err; diff --git a/target/linux/bcm27xx/patches-5.4/950-0828-media-i2c-imx290-Correct-range-for-V4L2_CID_GAIN-to-.patch b/target/linux/bcm27xx/patches-5.4/950-0828-media-i2c-imx290-Correct-range-for-V4L2_CID_GAIN-to-.patch new file mode 100644 index 0000000000..462c88dab4 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0828-media-i2c-imx290-Correct-range-for-V4L2_CID_GAIN-to-.patch @@ -0,0 +1,26 @@ +From 6d659cddefb5f9f35160f4b7b8d5a77935480b2d Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 11 Jun 2020 13:41:43 +0100 +Subject: [PATCH] media: i2c: imx290: Correct range for V4L2_CID_GAIN + to 0-238 + +The datasheet lists the gain as being 0.0 to 72.0dB in 0.3dB steps, which +makes 238 steps total. +Correct the 0-72 range defined in the driver. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/i2c/imx290.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -1124,7 +1124,7 @@ static int imx290_probe(struct i2c_clien + v4l2_ctrl_handler_init(&imx290->ctrls, 4); + + v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, +- V4L2_CID_GAIN, 0, 72, 1, 0); ++ V4L2_CID_GAIN, 0, 238, 1, 0); + + imx290->link_freq = + v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops, diff --git a/target/linux/bcm27xx/patches-5.4/950-0829-media-i2c-imx290-Convert-HMAX-setting-into-V4L2_CID_.patch b/target/linux/bcm27xx/patches-5.4/950-0829-media-i2c-imx290-Convert-HMAX-setting-into-V4L2_CID_.patch new file mode 100644 index 0000000000..7a0a5f06aa --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0829-media-i2c-imx290-Convert-HMAX-setting-into-V4L2_CID_.patch @@ -0,0 +1,159 @@ +From 116dc059ca9c6b088afba98dde7b679a97ae7198 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 11 Jun 2020 14:36:40 +0100 +Subject: [PATCH] media: i2c: imx290: Convert HMAX setting into + V4L2_CID_HBLANK + +Userspace needs to know HBLANK if it is to work out exposure times +and frame rates, therefore convert it to map onto V4L2_CID_HBLANK + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/i2c/imx290.c | 66 +++++++++++++++++++++++++------------- + 1 file changed, 44 insertions(+), 22 deletions(-) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -40,6 +40,9 @@ enum imx290_clk_index { + #define IMX290_GAIN 0x3014 + #define IMX290_HMAX_LOW 0x301c + #define IMX290_HMAX_HIGH 0x301d ++#define IMX290_HMAX_MIN_2LANE 4400 /* Min of 4400 pixels = 30fps */ ++#define IMX290_HMAX_MIN_4LANE 2200 /* Min of 2200 pixels = 60fps */ ++#define IMX290_HMAX_MAX 0xffff + #define IMX290_PGCTRL 0x308c + #define IMX290_PHY_LANE_NUM 0x3407 + #define IMX290_CSI_LANE_MODE 0x3443 +@@ -82,6 +85,7 @@ struct imx290 { + struct regmap *regmap; + u8 nlanes; + u8 bpp; ++ u16 hmax_min; + + struct v4l2_subdev sd; + struct media_pad pad; +@@ -94,6 +98,7 @@ struct imx290 { + struct v4l2_ctrl_handler ctrls; + struct v4l2_ctrl *link_freq; + struct v4l2_ctrl *pixel_rate; ++ struct v4l2_ctrl *hblank; + + struct mutex lock; + }; +@@ -518,6 +523,26 @@ static int imx290_set_gain(struct imx290 + return ret; + } + ++static int imx290_set_hmax(struct imx290 *imx290, u32 val) ++{ ++ u32 hmax = val + imx290->current_mode->width; ++ int ret; ++ ++ ret = imx290_write_reg(imx290, IMX290_HMAX_LOW, (hmax & 0xff)); ++ if (ret) { ++ dev_err(imx290->dev, "Error setting HMAX register\n"); ++ return ret; ++ } ++ ++ ret = imx290_write_reg(imx290, IMX290_HMAX_HIGH, ((hmax >> 8) & 0xff)); ++ if (ret) { ++ dev_err(imx290->dev, "Error setting HMAX register\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ + /* Stop streaming */ + static int imx290_stop_streaming(struct imx290 *imx290) + { +@@ -546,6 +571,9 @@ static int imx290_set_ctrl(struct v4l2_c + case V4L2_CID_GAIN: + ret = imx290_set_gain(imx290, ctrl->val); + break; ++ case V4L2_CID_HBLANK: ++ ret = imx290_set_hmax(imx290, ctrl->val); ++ break; + case V4L2_CID_TEST_PATTERN: + if (ctrl->val) { + imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x00); +@@ -702,6 +730,12 @@ static int imx290_set_fmt(struct v4l2_su + if (imx290->pixel_rate) + __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate, + imx290_calc_pixel_rate(imx290)); ++ ++ if (imx290->hblank) ++ __v4l2_ctrl_modify_range(imx290->hblank, ++ imx290->hmax_min - mode->width, ++ IMX290_HMAX_MAX - mode->width, ++ 1, mode->hmax - mode->width); + } + + *format = fmt->format; +@@ -756,25 +790,6 @@ static int imx290_write_current_format(s + return 0; + } + +-static int imx290_set_hmax(struct imx290 *imx290, u32 val) +-{ +- int ret; +- +- ret = imx290_write_reg(imx290, IMX290_HMAX_LOW, (val & 0xff)); +- if (ret) { +- dev_err(imx290->dev, "Error setting HMAX register\n"); +- return ret; +- } +- +- ret = imx290_write_reg(imx290, IMX290_HMAX_HIGH, ((val >> 8) & 0xff)); +- if (ret) { +- dev_err(imx290->dev, "Error setting HMAX register\n"); +- return ret; +- } +- +- return 0; +-} +- + /* Start streaming */ + static int imx290_start_streaming(struct imx290 *imx290) + { +@@ -813,9 +828,6 @@ static int imx290_start_streaming(struct + dev_err(imx290->dev, "Could not set current mode\n"); + return ret; + } +- ret = imx290_set_hmax(imx290, imx290->current_mode->hmax); +- if (ret < 0) +- return ret; + + /* Apply customized values from user */ + ret = v4l2_ctrl_handler_setup(imx290->sd.ctrl_handler); +@@ -1014,6 +1026,7 @@ static int imx290_probe(struct i2c_clien + struct v4l2_fwnode_endpoint ep = { + .bus_type = V4L2_MBUS_CSI2_DPHY + }; ++ const struct imx290_mode *mode; + struct imx290 *imx290; + s64 fq; + int ret; +@@ -1052,6 +1065,8 @@ static int imx290_probe(struct i2c_clien + ret = -EINVAL; + goto free_err; + } ++ imx290->hmax_min = (imx290->nlanes == 2) ? IMX290_HMAX_MIN_2LANE : ++ IMX290_HMAX_MIN_4LANE; + + dev_dbg(dev, "Using %u data lanes\n", imx290->nlanes); + +@@ -1126,6 +1141,13 @@ static int imx290_probe(struct i2c_clien + v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, + V4L2_CID_GAIN, 0, 238, 1, 0); + ++ mode = imx290->current_mode; ++ imx290->hblank = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, ++ V4L2_CID_HBLANK, ++ imx290->hmax_min - mode->width, ++ IMX290_HMAX_MAX - mode->width, 1, ++ mode->hmax - mode->width); ++ + imx290->link_freq = + v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops, + V4L2_CID_LINK_FREQ, diff --git a/target/linux/bcm27xx/patches-5.4/950-0830-media-i2c-imx290-Add-support-for-V4L2_CID_VBLANK.patch b/target/linux/bcm27xx/patches-5.4/950-0830-media-i2c-imx290-Add-support-for-V4L2_CID_VBLANK.patch new file mode 100644 index 0000000000..daa5d54145 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0830-media-i2c-imx290-Add-support-for-V4L2_CID_VBLANK.patch @@ -0,0 +1,141 @@ +From 12a04a18c7a56dbd2943b6666c7978b09499fc4b Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 11 Jun 2020 18:09:12 +0100 +Subject: [PATCH] media: i2c: imx290: Add support for V4L2_CID_VBLANK + +In order to calculate framerate and durations userspace needs +the vertical blanking information. This can be configurable, +and indeed the datasheet lists different values for VBLANK for +the 1080p and 720p modes. + +Add the new control, and adopt the datasheet values for each mode. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/i2c/imx290.c | 38 ++++++++++++++++++++++++++++++++++++-- + 1 file changed, 36 insertions(+), 2 deletions(-) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -38,6 +38,8 @@ enum imx290_clk_index { + #define IMX290_BLKLEVEL_LOW 0x300a + #define IMX290_BLKLEVEL_HIGH 0x300b + #define IMX290_GAIN 0x3014 ++#define IMX290_VMAX_LOW 0x3018 ++#define IMX290_VMAX_MAX 0x3fff + #define IMX290_HMAX_LOW 0x301c + #define IMX290_HMAX_HIGH 0x301d + #define IMX290_HMAX_MIN_2LANE 4400 /* Min of 4400 pixels = 30fps */ +@@ -68,6 +70,7 @@ struct imx290_mode { + u32 width; + u32 height; + u32 hmax; ++ u32 vmax; + u8 link_freq_index; + + const struct imx290_regval *data; +@@ -99,6 +102,7 @@ struct imx290 { + struct v4l2_ctrl *link_freq; + struct v4l2_ctrl *pixel_rate; + struct v4l2_ctrl *hblank; ++ struct v4l2_ctrl *vblank; + + struct mutex lock; + }; +@@ -132,8 +136,6 @@ static const char * const imx290_test_pa + + static const struct imx290_regval imx290_global_init_settings[] = { + { 0x3007, 0x00 }, +- { 0x3018, 0x65 }, +- { 0x3019, 0x04 }, + { 0x301a, 0x00 }, + { 0x303a, 0x0c }, + { 0x3040, 0x00 }, +@@ -360,6 +362,7 @@ static const struct imx290_mode imx290_m + .width = 1920, + .height = 1080, + .hmax = 0x1130, ++ .vmax = 0x0465, + .link_freq_index = FREQ_INDEX_1080P, + .data = imx290_1080p_settings, + .data_size = ARRAY_SIZE(imx290_1080p_settings), +@@ -373,6 +376,7 @@ static const struct imx290_mode imx290_m + .width = 1280, + .height = 720, + .hmax = 0x19c8, ++ .vmax = 0x02ee, + .link_freq_index = FREQ_INDEX_720P, + .data = imx290_720p_settings, + .data_size = ARRAY_SIZE(imx290_720p_settings), +@@ -389,6 +393,7 @@ static const struct imx290_mode imx290_m + .width = 1920, + .height = 1080, + .hmax = 0x0898, ++ .vmax = 0x0465, + .link_freq_index = FREQ_INDEX_1080P, + .data = imx290_1080p_settings, + .data_size = ARRAY_SIZE(imx290_1080p_settings), +@@ -402,6 +407,7 @@ static const struct imx290_mode imx290_m + .width = 1280, + .height = 720, + .hmax = 0x0ce4, ++ .vmax = 0x02ee, + .link_freq_index = FREQ_INDEX_720P, + .data = imx290_720p_settings, + .data_size = ARRAY_SIZE(imx290_720p_settings), +@@ -543,6 +549,19 @@ static int imx290_set_hmax(struct imx290 + return 0; + } + ++static int imx290_set_vmax(struct imx290 *imx290, u32 val) ++{ ++ u32 vmax = val + imx290->current_mode->height; ++ int ret; ++ ++ ret = imx290_write_buffered_reg(imx290, IMX290_VMAX_LOW, 3, ++ vmax); ++ if (ret) ++ dev_err(imx290->dev, "Unable to write vmax\n"); ++ ++ return ret; ++} ++ + /* Stop streaming */ + static int imx290_stop_streaming(struct imx290 *imx290) + { +@@ -574,6 +593,9 @@ static int imx290_set_ctrl(struct v4l2_c + case V4L2_CID_HBLANK: + ret = imx290_set_hmax(imx290, ctrl->val); + break; ++ case V4L2_CID_VBLANK: ++ ret = imx290_set_vmax(imx290, ctrl->val); ++ break; + case V4L2_CID_TEST_PATTERN: + if (ctrl->val) { + imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x00); +@@ -736,6 +758,12 @@ static int imx290_set_fmt(struct v4l2_su + imx290->hmax_min - mode->width, + IMX290_HMAX_MAX - mode->width, + 1, mode->hmax - mode->width); ++ if (imx290->vblank) ++ __v4l2_ctrl_modify_range(imx290->vblank, ++ mode->vmax - mode->height, ++ IMX290_VMAX_MAX - mode->height, ++ 1, ++ mode->vmax - mode->height); + } + + *format = fmt->format; +@@ -1148,6 +1176,12 @@ static int imx290_probe(struct i2c_clien + IMX290_HMAX_MAX - mode->width, 1, + mode->hmax - mode->width); + ++ imx290->vblank = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, ++ V4L2_CID_VBLANK, ++ mode->vmax - mode->height, ++ IMX290_VMAX_MAX - mode->height, 1, ++ mode->vmax - mode->height); ++ + imx290->link_freq = + v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops, + V4L2_CID_LINK_FREQ, diff --git a/target/linux/bcm27xx/patches-5.4/950-0831-media-i2c-imx290-Add-exposure-control-to-the-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0831-media-i2c-imx290-Add-exposure-control-to-the-driver.patch new file mode 100644 index 0000000000..86836dc3af --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0831-media-i2c-imx290-Add-exposure-control-to-the-driver.patch @@ -0,0 +1,93 @@ +From d6c85afca764dc32c3d7981867471fc820e07388 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 11 Jun 2020 18:19:13 +0100 +Subject: [PATCH] media: i2c: imx290: Add exposure control to the + driver. + +Adds support for V4L2_CID_EXPOSURE so that userspace can control +the sensor exposure time. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/i2c/imx290.c | 35 +++++++++++++++++++++++++++++++++++ + 1 file changed, 35 insertions(+) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -45,6 +45,10 @@ enum imx290_clk_index { + #define IMX290_HMAX_MIN_2LANE 4400 /* Min of 4400 pixels = 30fps */ + #define IMX290_HMAX_MIN_4LANE 2200 /* Min of 2200 pixels = 60fps */ + #define IMX290_HMAX_MAX 0xffff ++ ++#define IMX290_EXPOSURE_MIN 2 ++#define IMX290_EXPOSURE_STEP 1 ++#define IMX290_EXPOSURE_LOW 0x3020 + #define IMX290_PGCTRL 0x308c + #define IMX290_PHY_LANE_NUM 0x3407 + #define IMX290_CSI_LANE_MODE 0x3443 +@@ -103,6 +107,7 @@ struct imx290 { + struct v4l2_ctrl *pixel_rate; + struct v4l2_ctrl *hblank; + struct v4l2_ctrl *vblank; ++ struct v4l2_ctrl *exposure; + + struct mutex lock; + }; +@@ -529,6 +534,20 @@ static int imx290_set_gain(struct imx290 + return ret; + } + ++static int imx290_set_exposure(struct imx290 *imx290, u32 value) ++{ ++ u32 exposure = (imx290->current_mode->height + imx290->vblank->val) - ++ value; ++ int ret; ++ ++ ret = imx290_write_buffered_reg(imx290, IMX290_EXPOSURE_LOW, 3, ++ exposure); ++ if (ret) ++ dev_err(imx290->dev, "Unable to write exposure\n"); ++ ++ return ret; ++} ++ + static int imx290_set_hmax(struct imx290 *imx290, u32 val) + { + u32 hmax = val + imx290->current_mode->width; +@@ -590,6 +609,9 @@ static int imx290_set_ctrl(struct v4l2_c + case V4L2_CID_GAIN: + ret = imx290_set_gain(imx290, ctrl->val); + break; ++ case V4L2_CID_EXPOSURE: ++ ret = imx290_set_exposure(imx290, ctrl->val); ++ break; + case V4L2_CID_HBLANK: + ret = imx290_set_hmax(imx290, ctrl->val); + break; +@@ -764,6 +786,12 @@ static int imx290_set_fmt(struct v4l2_su + IMX290_VMAX_MAX - mode->height, + 1, + mode->vmax - mode->height); ++ if (imx290->exposure) ++ __v4l2_ctrl_modify_range(imx290->exposure, ++ mode->vmax - mode->height, ++ mode->vmax - 4, ++ IMX290_EXPOSURE_STEP, ++ mode->vmax - 4); + } + + *format = fmt->format; +@@ -1182,6 +1210,13 @@ static int imx290_probe(struct i2c_clien + IMX290_VMAX_MAX - mode->height, 1, + mode->vmax - mode->height); + ++ imx290->exposure = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, ++ V4L2_CID_EXPOSURE, ++ IMX290_EXPOSURE_MIN, ++ mode->vmax - 4, ++ IMX290_EXPOSURE_STEP, ++ mode->vmax - 4); ++ + imx290->link_freq = + v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops, + V4L2_CID_LINK_FREQ, diff --git a/target/linux/bcm27xx/patches-5.4/950-0832-media-i2c-imx290-Add-H-and-V-flip-controls.patch b/target/linux/bcm27xx/patches-5.4/950-0832-media-i2c-imx290-Add-H-and-V-flip-controls.patch new file mode 100644 index 0000000000..b96807b6cd --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0832-media-i2c-imx290-Add-H-and-V-flip-controls.patch @@ -0,0 +1,83 @@ +From a6048e36f5e5d73a29d1f5096fc77286f8aa949d Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 11 Jun 2020 18:34:16 +0100 +Subject: [PATCH] media: i2c: imx290: Add H and V flip controls + +The sensor supports horizontal and vertical flips, so support them +through V4L2_CID_HFLIP and V4L2_CID_VFLIP. + +This sensor does NOT change the Bayer order when changing the +direction of readout, therefore no special handling is required for +that. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/i2c/imx290.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -34,6 +34,7 @@ enum imx290_clk_index { + #define IMX290_STANDBY 0x3000 + #define IMX290_REGHOLD 0x3001 + #define IMX290_XMSTA 0x3002 ++#define IMX290_FLIP_WINMODE 0x3007 + #define IMX290_FR_FDG_SEL 0x3009 + #define IMX290_BLKLEVEL_LOW 0x300a + #define IMX290_BLKLEVEL_HIGH 0x300b +@@ -107,6 +108,8 @@ struct imx290 { + struct v4l2_ctrl *pixel_rate; + struct v4l2_ctrl *hblank; + struct v4l2_ctrl *vblank; ++ struct v4l2_ctrl *hflip; ++ struct v4l2_ctrl *vflip; + struct v4l2_ctrl *exposure; + + struct mutex lock; +@@ -600,6 +603,7 @@ static int imx290_set_ctrl(struct v4l2_c + struct imx290 *imx290 = container_of(ctrl->handler, + struct imx290, ctrls); + int ret = 0; ++ u8 val; + + /* V4L2 controls values will be applied only when power is already up */ + if (!pm_runtime_get_if_in_use(imx290->dev)) +@@ -618,6 +622,16 @@ static int imx290_set_ctrl(struct v4l2_c + case V4L2_CID_VBLANK: + ret = imx290_set_vmax(imx290, ctrl->val); + break; ++ case V4L2_CID_HFLIP: ++ case V4L2_CID_VFLIP: ++ /* WINMODE is in bits [6:4], so need to read-modify-write */ ++ ret = imx290_read_reg(imx290, IMX290_FLIP_WINMODE, &val); ++ if (ret) ++ break; ++ val &= ~0x03; ++ val |= imx290->vflip->val | (imx290->hflip->val << 1); ++ ret = imx290_write_reg(imx290, IMX290_FLIP_WINMODE, val); ++ break; + case V4L2_CID_TEST_PATTERN: + if (ctrl->val) { + imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x00); +@@ -924,6 +938,9 @@ static int imx290_set_stream(struct v4l2 + imx290_stop_streaming(imx290); + pm_runtime_put(imx290->dev); + } ++ /* vflip and hflip cannot change during streaming */ ++ __v4l2_ctrl_grab(imx290->vflip, enable); ++ __v4l2_ctrl_grab(imx290->hflip, enable); + + unlock_and_return: + +@@ -1217,6 +1234,11 @@ static int imx290_probe(struct i2c_clien + IMX290_EXPOSURE_STEP, + mode->vmax - 4); + ++ imx290->hflip = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, ++ V4L2_CID_HFLIP, 0, 1, 1, 0); ++ imx290->vflip = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, ++ V4L2_CID_VFLIP, 0, 1, 1, 0); ++ + imx290->link_freq = + v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops, + V4L2_CID_LINK_FREQ, diff --git a/target/linux/bcm27xx/patches-5.4/950-0833-media-dt-bindings-media-i2c-Add-mono-version-to-IMX2.patch b/target/linux/bcm27xx/patches-5.4/950-0833-media-dt-bindings-media-i2c-Add-mono-version-to-IMX2.patch new file mode 100644 index 0000000000..50c93f0a9e --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0833-media-dt-bindings-media-i2c-Add-mono-version-to-IMX2.patch @@ -0,0 +1,36 @@ +From 05ba3df09751ff516de5d862c98f5a979b51bb56 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 25 Jun 2020 16:52:14 +0100 +Subject: [PATCH] media: dt-bindings: media: i2c: Add mono version to + IMX290 bindings + +The IMX290 module is available as either monochrome or colour and +the variant is not detectable at runtime. + +Add a new compatible string for the monochrome version. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + Documentation/devicetree/bindings/media/i2c/imx290.txt | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/Documentation/devicetree/bindings/media/i2c/imx290.txt ++++ b/Documentation/devicetree/bindings/media/i2c/imx290.txt +@@ -1,13 +1,14 @@ + * Sony IMX290 1/2.8-Inch CMOS Image Sensor + + The Sony IMX290 is a 1/2.8-Inch CMOS Solid-state image sensor with +-Square Pixel for Color Cameras. It is programmable through I2C and 4-wire +-interfaces. The sensor output is available via CMOS logic parallel SDR output, ++Square Pixel for Color or Monochrome Cameras. It is programmable through I2C ++and 4-wire interfaces. ++The sensor output is available via CMOS logic parallel SDR output, + Low voltage LVDS DDR output and CSI-2 serial data output. The CSI-2 bus is the + default. No bindings have been defined for the other busses. + + Required Properties: +-- compatible: Should be "sony,imx290" ++- compatible: Should be "sony,imx290", or "sony,imx290-mono" + - reg: I2C bus address of the device + - clocks: Reference to the xclk clock. + - clock-names: Should be "xclk". diff --git a/target/linux/bcm27xx/patches-5.4/950-0834-media-i2c-imx290-Add-support-for-the-mono-sensor-var.patch b/target/linux/bcm27xx/patches-5.4/950-0834-media-i2c-imx290-Add-support-for-the-mono-sensor-var.patch new file mode 100644 index 0000000000..f75a2203df --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0834-media-i2c-imx290-Add-support-for-the-mono-sensor-var.patch @@ -0,0 +1,185 @@ +From c9f918319593861c4975b229579def5fbd637ad9 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 25 Jun 2020 17:03:11 +0100 +Subject: [PATCH] media : i2c: imx290: Add support for the mono + sensor variant. + +The IMX290 module is available as either mono or colour (Bayer). + +Update the driver so that it can advertise the correct mono +formats instead of the colour ones. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/i2c/imx290.c | 58 +++++++++++++++++++++++++++----------- + 1 file changed, 41 insertions(+), 17 deletions(-) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -1,10 +1,12 @@ + // SPDX-License-Identifier: GPL-2.0 + /* +- * Sony IMX290/327 CMOS Image Sensor Driver ++ * Sony IMX290 & IMX327 CMOS Image Sensor Driver + * + * The IMX290 and IMX327 are very similar 1920x1080 1/2.8 CMOS image sensors. +- * IMX327 can support up to 60fps, whilst IMX290 support up to 120fps (only +- * 10bit and when connected over 4 CSI-2 lanes). ++ * IMX327 can support up to 60fps, whilst IMX290 can support up to 120fps, but ++ * only 10bit and when connected over 4 CSI-2 lanes. ++ * The modules don't appear to have a mechanism to identify whether the mono or ++ * colour variant is connected, therefore it is done via compatible string. + * + * Copyright (C) 2019 FRAMOS GmbH. + * +@@ -17,6 +19,7 @@ + #include <linux/gpio/consumer.h> + #include <linux/i2c.h> + #include <linux/module.h> ++#include <linux/of_device.h> + #include <linux/pm_runtime.h> + #include <linux/regmap.h> + #include <linux/regulator/consumer.h> +@@ -95,6 +98,8 @@ struct imx290 { + u8 bpp; + u16 hmax_min; + ++ const struct imx290_pixfmt *formats; ++ + struct v4l2_subdev sd; + struct media_pad pad; + struct v4l2_mbus_framefmt current_format; +@@ -120,11 +125,18 @@ struct imx290_pixfmt { + u8 bpp; + }; + +-static const struct imx290_pixfmt imx290_formats[] = { ++#define IMX290_NUM_FORMATS 2 ++ ++static const struct imx290_pixfmt imx290_colour_formats[IMX290_NUM_FORMATS] = { + { MEDIA_BUS_FMT_SRGGB10_1X10, 10 }, + { MEDIA_BUS_FMT_SRGGB12_1X12, 12 }, + }; + ++static const struct imx290_pixfmt imx290_mono_formats[IMX290_NUM_FORMATS] = { ++ { MEDIA_BUS_FMT_Y10_1X10, 10 }, ++ { MEDIA_BUS_FMT_Y12_1X12, 12 }, ++}; ++ + static const struct regmap_config imx290_regmap_config = { + .reg_bits = 16, + .val_bits = 8, +@@ -671,10 +683,12 @@ static int imx290_enum_mbus_code(struct + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) + { +- if (code->index >= ARRAY_SIZE(imx290_formats)) ++ const struct imx290 *imx290 = to_imx290(sd); ++ ++ if (code->index >= IMX290_NUM_FORMATS) + return -EINVAL; + +- code->code = imx290_formats[code->index].code; ++ code->code = imx290->formats[code->index].code; + + return 0; + } +@@ -686,8 +700,8 @@ static int imx290_enum_frame_size(struct + const struct imx290 *imx290 = to_imx290(sd); + const struct imx290_mode *imx290_modes = imx290_modes_ptr(imx290); + +- if ((fse->code != imx290_formats[0].code) && +- (fse->code != imx290_formats[1].code)) ++ if (fse->code != imx290->formats[0].code && ++ fse->code != imx290->formats[1].code) + return -EINVAL; + + if (fse->index >= imx290_modes_num(imx290)) +@@ -765,14 +779,14 @@ static int imx290_set_fmt(struct v4l2_su + fmt->format.width = mode->width; + fmt->format.height = mode->height; + +- for (i = 0; i < ARRAY_SIZE(imx290_formats); i++) +- if (imx290_formats[i].code == fmt->format.code) ++ for (i = 0; i < IMX290_NUM_FORMATS; i++) ++ if (imx290->formats[i].code == fmt->format.code) + break; + +- if (i >= ARRAY_SIZE(imx290_formats)) ++ if (i >= IMX290_NUM_FORMATS) + i = 0; + +- fmt->format.code = imx290_formats[i].code; ++ fmt->format.code = imx290->formats[i].code; + fmt->format.field = V4L2_FIELD_NONE; + + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { +@@ -780,7 +794,7 @@ static int imx290_set_fmt(struct v4l2_su + } else { + format = &imx290->current_format; + imx290->current_mode = mode; +- imx290->bpp = imx290_formats[i].bpp; ++ imx290->bpp = imx290->formats[i].bpp; + + if (imx290->link_freq) + __v4l2_ctrl_s_ctrl(imx290->link_freq, +@@ -835,6 +849,7 @@ static int imx290_write_current_format(s + + switch (imx290->current_format.code) { + case MEDIA_BUS_FMT_SRGGB10_1X10: ++ case MEDIA_BUS_FMT_Y10_1X10: + ret = imx290_set_register_array(imx290, imx290_10bit_settings, + ARRAY_SIZE( + imx290_10bit_settings)); +@@ -844,6 +859,7 @@ static int imx290_write_current_format(s + } + break; + case MEDIA_BUS_FMT_SRGGB12_1X12: ++ case MEDIA_BUS_FMT_Y12_1X12: + ret = imx290_set_register_array(imx290, imx290_12bit_settings, + ARRAY_SIZE( + imx290_12bit_settings)); +@@ -1091,6 +1107,12 @@ static s64 imx290_check_link_freqs(const + return 0; + } + ++static const struct of_device_id imx290_of_match[] = { ++ { .compatible = "sony,imx290", .data = imx290_colour_formats }, ++ { .compatible = "sony,imx290-mono", .data = imx290_mono_formats }, ++ { /* sentinel */ } ++}; ++ + static int imx290_probe(struct i2c_client *client) + { + struct device *dev = &client->dev; +@@ -1099,6 +1121,7 @@ static int imx290_probe(struct i2c_clien + struct v4l2_fwnode_endpoint ep = { + .bus_type = V4L2_MBUS_CSI2_DPHY + }; ++ const struct of_device_id *match; + const struct imx290_mode *mode; + struct imx290 *imx290; + s64 fq; +@@ -1115,6 +1138,11 @@ static int imx290_probe(struct i2c_clien + return -ENODEV; + } + ++ match = of_match_device(imx290_of_match, dev); ++ if (!match) ++ return -ENODEV; ++ imx290->formats = (const struct imx290_pixfmt *)match->data; ++ + endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL); + if (!endpoint) { + dev_err(dev, "Endpoint node not found\n"); +@@ -1330,10 +1358,6 @@ static int imx290_remove(struct i2c_clie + return 0; + } + +-static const struct of_device_id imx290_of_match[] = { +- { .compatible = "sony,imx290" }, +- { /* sentinel */ } +-}; + MODULE_DEVICE_TABLE(of, imx290_of_match); + + static struct i2c_driver imx290_i2c_driver = { diff --git a/target/linux/bcm27xx/patches-5.4/950-0835-media-i2c-imx290-Switch-set_hmax-to-use-imx290_write.patch b/target/linux/bcm27xx/patches-5.4/950-0835-media-i2c-imx290-Switch-set_hmax-to-use-imx290_write.patch new file mode 100644 index 0000000000..7819e70ea3 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0835-media-i2c-imx290-Switch-set_hmax-to-use-imx290_write.patch @@ -0,0 +1,43 @@ +From 970208edb92b04eaa329c666e2e91717984c28b6 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Fri, 26 Jun 2020 18:11:49 +0100 +Subject: [PATCH] media: i2c: imx290: Switch set_hmax to use + imx290_write_buffered_reg + +imx290_set_hmax was using two independent writes to set up hmax, +when all other multi-register writes were using imx290_write_buffered_reg +which claims the group hold first. + +Switch imx290_set_hmax to using imx290_write_buffered_reg too. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/i2c/imx290.c | 15 ++++----------- + 1 file changed, 4 insertions(+), 11 deletions(-) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -568,19 +568,12 @@ static int imx290_set_hmax(struct imx290 + u32 hmax = val + imx290->current_mode->width; + int ret; + +- ret = imx290_write_reg(imx290, IMX290_HMAX_LOW, (hmax & 0xff)); +- if (ret) { ++ ret = imx290_write_buffered_reg(imx290, IMX290_HMAX_LOW, 2, ++ hmax); ++ if (ret) + dev_err(imx290->dev, "Error setting HMAX register\n"); +- return ret; +- } + +- ret = imx290_write_reg(imx290, IMX290_HMAX_HIGH, ((hmax >> 8) & 0xff)); +- if (ret) { +- dev_err(imx290->dev, "Error setting HMAX register\n"); +- return ret; +- } +- +- return 0; ++ return ret; + } + + static int imx290_set_vmax(struct imx290 *imx290, u32 val) diff --git a/target/linux/bcm27xx/patches-5.4/950-0836-dtoverlays-Add-an-overlay-for-the-Sony-IMX290-image-.patch b/target/linux/bcm27xx/patches-5.4/950-0836-dtoverlays-Add-an-overlay-for-the-Sony-IMX290-image-.patch new file mode 100644 index 0000000000..f64db00ddc --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0836-dtoverlays-Add-an-overlay-for-the-Sony-IMX290-image-.patch @@ -0,0 +1,236 @@ +From 57250281004e141dff4662d1abb3f31982ec01ee Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 19 May 2020 13:35:17 +0100 +Subject: [PATCH] dtoverlays: Add an overlay for the Sony IMX290 + image sensor + +Adds an overlay to configure the IMX290 image sensor. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 16 ++ + arch/arm/boot/dts/overlays/imx290-overlay.dts | 32 ++++ + .../boot/dts/overlays/imx290_327-overlay.dtsi | 145 ++++++++++++++++++ + 4 files changed, 194 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/imx290-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/imx290_327-overlay.dtsi + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -85,6 +85,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + i2s-gpio28-31.dtbo \ + ilitek251x.dtbo \ + imx219.dtbo \ ++ imx290.dtbo \ + imx477.dtbo \ + iqaudio-codec.dtbo \ + iqaudio-dac.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1430,6 +1430,22 @@ Load: dtoverlay=imx219 + Params: <None> + + ++Name: imx290 ++Info: Sony IMX290 camera module. ++ Uses Unicam 1, which is the standard camera connector on most Pi ++ variants. NB This currently uses 4 CSI2 data lanes and therefore will ++ only work on a CM. ++Load: dtoverlay=imx290,<param> ++Params: 4lane Enable 4 CSI2 lanes. This requires a Compute ++ Module (1, 3, or 4). ++ clock-frequency Sets the clock frequency to match that used on ++ the board. ++ Modules from Vision Components use 37.125MHz ++ (the default), whilst those from Innomaker use ++ 74.25MHz. ++ mono Denote that the module is a mono sensor. ++ ++ + Name: imx477 + Info: Sony IMX477 camera module. + Uses Unicam 1, which is the standard camera connector on most Pi +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/imx290-overlay.dts +@@ -0,0 +1,32 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++// Definitions for IMX290 camera module on VC I2C bus ++/dts-v1/; ++/plugin/; ++ ++#include <dt-bindings/gpio/gpio.h> ++#include "imx290_327-overlay.dtsi" ++ ++/{ ++ compatible = "brcm,bcm2835"; ++ ++ // Fragment numbers deliberately high to avoid conflicts with the ++ // included imx290_327 overlay file. ++ ++ fragment@101 { ++ target = <&imx290>; ++ __overlay__ { ++ compatible = "sony,imx290"; ++ }; ++ }; ++ ++ fragment@102 { ++ target = <&imx290>; ++ __dormant__ { ++ compatible = "sony,imx290-mono"; ++ }; ++ }; ++ ++ __overrides__ { ++ mono = <0>, "-101+102"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/imx290_327-overlay.dtsi +@@ -0,0 +1,145 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++// Partial definitions for IMX290 or IMX327 camera module on VC I2C bus ++// The compatible string should be set in an overlay that then includes this one ++/dts-v1/; ++/plugin/; ++ ++#include <dt-bindings/gpio/gpio.h> ++ ++/{ ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&i2c_csi_dsi>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ imx290: imx290@1a { ++ reg = <0x1a>; ++ status = "okay"; ++ ++ clocks = <&imx290_clk>; ++ clock-names = "xclk"; ++ clock-frequency = <37125000>; ++ ++ vdda-supply = <&imx290_vdda>; /* 2.8v */ ++ vdddo-supply = <&imx290_vdddo>; /* 1.8v */ ++ vddd-supply = <&imx290_vddd>; /* 1.5v */ ++ ++ port { ++ imx290_0: endpoint { ++ remote-endpoint = <&csi1_ep>; ++ clock-lanes = <0>; ++ }; ++ }; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&csi1>; ++ __overlay__ { ++ status = "okay"; ++ ++ port { ++ csi1_ep: endpoint { ++ remote-endpoint = <&imx290_0>; ++ }; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c0if>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@3 { ++ target-path="/"; ++ __overlay__ { ++ imx290_vdda: fixedregulator@0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "imx290_vdda"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ gpio = <&gpio 41 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ }; ++ imx290_vdddo: fixedregulator@1 { ++ compatible = "regulator-fixed"; ++ regulator-name = "imx290_vdddo"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ }; ++ imx290_vddd: fixedregulator@2 { ++ compatible = "regulator-fixed"; ++ regulator-name = "imx290_vddd"; ++ regulator-min-microvolt = <1500000>; ++ regulator-max-microvolt = <1500000>; ++ }; ++ ++ imx290_clk: camera-clk { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <37125000>; ++ }; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&i2c0mux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@5 { ++ target-path="/__overrides__"; ++ __overlay__ { ++ cam0-pwdn-ctrl = <&imx290_vdda>,"gpio:0"; ++ cam0-pwdn = <&imx290_vdda>,"gpio:4"; ++ }; ++ }; ++ ++ fragment@6 { ++ target = <&imx290_0>; ++ __overlay__ { ++ data-lanes = <1 2>; ++ link-frequencies = ++ /bits/ 64 <445500000 297000000>; ++ }; ++ }; ++ ++ fragment@7 { ++ target = <&imx290_0>; ++ __dormant__ { ++ data-lanes = <1 2 3 4>; ++ link-frequencies = ++ /bits/ 64 <222750000 148500000>; ++ }; ++ }; ++ ++ fragment@8 { ++ target = <&csi1_ep>; ++ __overlay__ { ++ data-lanes = <1 2>; ++ }; ++ }; ++ ++ fragment@9 { ++ target = <&csi1_ep>; ++ __dormant__ { ++ data-lanes = <1 2 3 4>; ++ }; ++ }; ++ ++ __overrides__ { ++ 4lane = <0>, "-6+7-8+9"; ++ clock-frequency = <&imx290_clk>,"clock-frequency:0", ++ <&imx290>,"clock-frequency:0"; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-5.4/950-0837-vc4_hdmi-Set-HD_CTL_WHOLSMP-and-HD_CTL_CHALIGN_SET.patch b/target/linux/bcm27xx/patches-5.4/950-0837-vc4_hdmi-Set-HD_CTL_WHOLSMP-and-HD_CTL_CHALIGN_SET.patch new file mode 100644 index 0000000000..859a560bba --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0837-vc4_hdmi-Set-HD_CTL_WHOLSMP-and-HD_CTL_CHALIGN_SET.patch @@ -0,0 +1,38 @@ +From c69a53be3b5f6f7cba0ac6a5461d4f342f7e9c41 Mon Sep 17 00:00:00 2001 +From: Dom Cobley <popcornmix@gmail.com> +Date: Tue, 23 Jun 2020 18:37:01 +0100 +Subject: [PATCH] vc4_hdmi: Set HD_CTL_WHOLSMP and HD_CTL_CHALIGN_SET + +Symptom is random switching of speakers when using multichannel. + +Repeatedly running speakertest -c8 occasionally starts with +channels jumbled. This is fixed with HD_CTL_WHOLSMP. + +The other bit looks beneficial and apears harmless in testing so +I'd suggest adding it too. + +Documentation says: HD_CTL_WHILSMP_SET +Wait for whole sample. When this bit is set MAI transmit will start +only when there is at least one whole sample available in the fifo. + +Documentation says: HD_CTL_CHALIGN_SET +Channel Align When Overflow. This bit is used to realign the audio channels in case of an overflow. +If this bit is set, after the detection of an overflow, equal amount of dummy words to the missing +words will be written to fifo, filling up the broken sample and maintaining alignment. + +Signed-off-by: Dom Cobley <popcornmix@gmail.com> +--- + drivers/gpu/drm/vc4/vc4_hdmi.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -1002,6 +1002,8 @@ static int vc4_hdmi_audio_trigger(struct + HDMI_WRITE(HDMI_MAI_CTL, + VC4_SET_FIELD(vc4_hdmi->audio.channels, + VC4_HD_MAI_CTL_CHNUM) | ++ VC4_HD_MAI_CTL_WHOLSMP | ++ VC4_HD_MAI_CTL_CHALIGN | + VC4_HD_MAI_CTL_ENABLE); + break; + case SNDRV_PCM_TRIGGER_STOP: diff --git a/target/linux/bcm27xx/patches-5.4/950-0838-staging-vc04_services-isp-Fixup-g-s_selection-implem.patch b/target/linux/bcm27xx/patches-5.4/950-0838-staging-vc04_services-isp-Fixup-g-s_selection-implem.patch new file mode 100644 index 0000000000..fd24c87bc3 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0838-staging-vc04_services-isp-Fixup-g-s_selection-implem.patch @@ -0,0 +1,129 @@ +From 7ec008222fcb4682fa2cfdbb62e657bf98950ec5 Mon Sep 17 00:00:00 2001 +From: Naushir Patuck <naush@raspberrypi.com> +Date: Tue, 19 May 2020 15:56:47 +0100 +Subject: [PATCH] staging: vc04_services: isp: Fixup g/s_selection + implementation + +Add V4L2_SEL_TGT_CROP_DEFAULT and V4L2_SEL_TGT_CROP_BOUND targets. +Disable the appropriate ioctls for the meta capture nodes - this now +passes v4l2-compliance tests. + +Signed-off-by: Naushir Patuck <naush@raspberrypi.com> +--- + .../bcm2835-isp/bcm2835-v4l2-isp.c | 84 ++++++++++++------- + 1 file changed, 55 insertions(+), 29 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c ++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c +@@ -1006,15 +1006,32 @@ static int bcm2835_isp_node_s_selection( + if (!s->r.width || !s->r.height) + return -EINVAL; + +- /* Adjust the crop window if goes outside the frame dimensions. */ +- s->r.left = min((unsigned int)max(s->r.left, 0), +- node->q_data.width - MIN_DIM); +- s->r.top = min((unsigned int)max(s->r.top, 0), +- node->q_data.height - MIN_DIM); +- s->r.width = max(min(s->r.width, node->q_data.width - s->r.left), +- MIN_DIM); +- s->r.height = max(min(s->r.height, node->q_data.height - s->r.top), +- MIN_DIM); ++ /* We can only set crop on the input. */ ++ switch (s->target) { ++ case V4L2_SEL_TGT_CROP: ++ /* ++ * Adjust the crop window if it goes outside of the frame ++ * dimensions. ++ */ ++ s->r.left = min((unsigned int)max(s->r.left, 0), ++ node->q_data.width - MIN_DIM); ++ s->r.top = min((unsigned int)max(s->r.top, 0), ++ node->q_data.height - MIN_DIM); ++ s->r.width = max(min(s->r.width, ++ node->q_data.width - s->r.left), MIN_DIM); ++ s->r.height = max(min(s->r.height, ++ node->q_data.height - s->r.top), MIN_DIM); ++ break; ++ case V4L2_SEL_TGT_CROP_DEFAULT: ++ /* Default (i.e. no) crop window. */ ++ s->r.left = 0; ++ s->r.top = 0; ++ s->r.width = node->q_data.width; ++ s->r.height = node->q_data.height; ++ break; ++ default: ++ return -EINVAL; ++ } + + crop.rect.x = s->r.left; + crop.rect.y = s->r.top; +@@ -1029,33 +1046,40 @@ static int bcm2835_isp_node_s_selection( + static int bcm2835_isp_node_g_selection(struct file *file, void *fh, + struct v4l2_selection *s) + { ++ struct mmal_parameter_crop crop; + struct bcm2835_isp_node *node = video_drvdata(file); +- struct bcm2835_isp_dev *dev = node_get_dev(node); + struct vchiq_mmal_port *port = get_port_data(node); +- struct mmal_parameter_crop crop; ++ struct bcm2835_isp_dev *dev = node_get_dev(node); + u32 crop_size = sizeof(crop); + int ret; + +- /* This return value is required for V4L2 compliance. */ +- if (node_is_stats(node)) +- return -ENOTTY; +- + /* We can only return out an input crop. */ +- if (s->target != V4L2_SEL_TGT_CROP) +- return -EINVAL; +- +- ret = vchiq_mmal_port_parameter_get(dev->mmal_instance, port, +- MMAL_PARAMETER_CROP, +- &crop, &crop_size); +- if (!ret) +- return -EINVAL; +- +- s->r.left = crop.rect.x; +- s->r.top = crop.rect.y; +- s->r.width = crop.rect.width; +- s->r.height = crop.rect.height; ++ switch (s->target) { ++ case V4L2_SEL_TGT_CROP: ++ ret = vchiq_mmal_port_parameter_get(dev->mmal_instance, port, ++ MMAL_PARAMETER_CROP, ++ &crop, &crop_size); ++ if (!ret) { ++ s->r.left = crop.rect.x; ++ s->r.top = crop.rect.y; ++ s->r.width = crop.rect.width; ++ s->r.height = crop.rect.height; ++ } ++ break; ++ case V4L2_SEL_TGT_CROP_DEFAULT: ++ case V4L2_SEL_TGT_CROP_BOUNDS: ++ /* Default (i.e. no) crop window. */ ++ s->r.left = 0; ++ s->r.top = 0; ++ s->r.width = node->q_data.width; ++ s->r.height = node->q_data.height; ++ ret = 0; ++ break; ++ default: ++ ret = -EINVAL; ++ } + +- return 0; ++ return ret; + } + + static int bcm3285_isp_subscribe_event(struct v4l2_fh *fh, +@@ -1218,6 +1242,8 @@ static int register_node(struct bcm2835_ + node->vfl_dir = VFL_DIR_RX; + node->name = "stats"; + v4l2_disable_ioctl(&node->vfd, VIDIOC_S_CTRL); ++ v4l2_disable_ioctl(&node->vfd, VIDIOC_S_SELECTION); ++ v4l2_disable_ioctl(&node->vfd, VIDIOC_G_SELECTION); + break; + } + diff --git a/target/linux/bcm27xx/patches-5.4/950-0839-staging-vc04_services-isp-Reorder-operations-during-.patch b/target/linux/bcm27xx/patches-5.4/950-0839-staging-vc04_services-isp-Reorder-operations-during-.patch new file mode 100644 index 0000000000..3300ed4686 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0839-staging-vc04_services-isp-Reorder-operations-during-.patch @@ -0,0 +1,92 @@ +From af066bde5a442efd50868ffed1aad30190400c91 Mon Sep 17 00:00:00 2001 +From: Naushir Patuck <naush@raspberrypi.com> +Date: Tue, 19 May 2020 15:57:08 +0100 +Subject: [PATCH] staging: vc04_services: isp: Reorder operations + during device probe + +Register the video node at the end of the probe, swapping order with +registering the controls. + +Signed-off-by: Naushir Patuck <naush@raspberrypi.com> +--- + .../bcm2835-isp/bcm2835-v4l2-isp.c | 48 ++++++++++++------- + 1 file changed, 32 insertions(+), 16 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c ++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c +@@ -1295,21 +1295,6 @@ static int register_node(struct bcm2835_ + } + node->queue_init = true; + +- /* Define the device names */ +- snprintf(vfd->name, sizeof(node->vfd.name), "%s-%s%d", BCM2835_ISP_NAME, +- node->name, node->id); +- +- ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr + index); +- if (ret) { +- v4l2_err(&dev->v4l2_dev, +- "Failed to register video %s[%d] device node\n", +- node->name, node->id); +- return ret; +- } +- +- node->registered = true; +- video_set_drvdata(vfd, node); +- + /* Set some controls and defaults, but only on the VIDEO_OUTPUT node. */ + if (node_is_output(node)) { + unsigned int i; +@@ -1324,7 +1309,12 @@ static int register_node(struct bcm2835_ + .step = 1, + }; + +- v4l2_ctrl_handler_init(&dev->ctrl_handler, 4); ++ ret = v4l2_ctrl_handler_init(&dev->ctrl_handler, 12); ++ if (ret) { ++ v4l2_err(&dev->v4l2_dev, "ctrl_handler init failed (%d)\n", ++ ret); ++ return ret; ++ } + + dev->r_gain = 1000; + dev->b_gain = 1000; +@@ -1350,13 +1340,39 @@ static int register_node(struct bcm2835_ + } + + node->vfd.ctrl_handler = &dev->ctrl_handler; ++ if (dev->ctrl_handler.error) { ++ ret = dev->ctrl_handler.error; ++ v4l2_err(&dev->v4l2_dev, "controls init failed (%d)\n", ++ ret); ++ v4l2_ctrl_handler_free(&dev->ctrl_handler); ++ goto ctrl_cleanup; ++ } + } + ++ /* Define the device names */ ++ snprintf(vfd->name, sizeof(node->vfd.name), "%s-%s%d", BCM2835_ISP_NAME, ++ node->name, node->id); ++ ++ ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr + index); ++ if (ret) { ++ v4l2_err(&dev->v4l2_dev, ++ "Failed to register video %s[%d] device node\n", ++ node->name, node->id); ++ goto ctrl_cleanup; ++ } ++ ++ node->registered = true; ++ video_set_drvdata(vfd, node); ++ + v4l2_info(&dev->v4l2_dev, + "Device node %s[%d] registered as /dev/video%d\n", + node->name, node->id, vfd->num); + + return 0; ++ ++ctrl_cleanup: ++ v4l2_ctrl_handler_free(&dev->ctrl_handler); ++ return ret; + } + + /* Unregister one of the /dev/video<N> nodes associated with the ISP. */ diff --git a/target/linux/bcm27xx/patches-5.4/950-0840-uapi-bcm2835-isp-Fixups-for-bcm2835-isp-uapi-structu.patch b/target/linux/bcm27xx/patches-5.4/950-0840-uapi-bcm2835-isp-Fixups-for-bcm2835-isp-uapi-structu.patch new file mode 100644 index 0000000000..e3ee0d96d7 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0840-uapi-bcm2835-isp-Fixups-for-bcm2835-isp-uapi-structu.patch @@ -0,0 +1,34 @@ +From b1a21b378ea123942db1d07007a040c5e89b23aa Mon Sep 17 00:00:00 2001 +From: Naushir Patuck <naush@raspberrypi.com> +Date: Tue, 19 May 2020 15:57:23 +0100 +Subject: [PATCH] uapi: bcm2835-isp: Fixups for bcm2835-isp uapi + structures + +Rename pad_[] to padding[]. +struct bcm2835_isp_rational.den is now unsigned. + +Signed-off-by: Naushir Patuck <naush@raspberrypi.com> +--- + include/uapi/linux/bcm2835-isp.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/include/uapi/linux/bcm2835-isp.h ++++ b/include/uapi/linux/bcm2835-isp.h +@@ -46,7 +46,7 @@ + */ + struct bcm2835_isp_rational { + __s32 num; +- __s32 den; ++ __u32 den; + }; + + /** +@@ -140,7 +140,7 @@ struct bcm2835_isp_black_level { + __u16 black_level_r; + __u16 black_level_g; + __u16 black_level_b; +- __u8 pad_[2]; /* Unused */ ++ __u8 padding[2]; /* Unused */ + }; + + /** diff --git a/target/linux/bcm27xx/patches-5.4/950-0841-ARM-dts-Add-Bluetooth-nodes-for-Raspberry-Pi.patch b/target/linux/bcm27xx/patches-5.4/950-0841-ARM-dts-Add-Bluetooth-nodes-for-Raspberry-Pi.patch new file mode 100644 index 0000000000..fd66e6590d --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0841-ARM-dts-Add-Bluetooth-nodes-for-Raspberry-Pi.patch @@ -0,0 +1,283 @@ +From c46a59c99e53ab41096afcf7f7879bb12769346b Mon Sep 17 00:00:00 2001 +From: Maxim Mikityanskiy <maxtram95@gmail.com> +Date: Sat, 27 Jun 2020 13:08:26 +0300 +Subject: [PATCH] ARM: dts: Add Bluetooth nodes for Raspberry Pi + +Add device tree nodes for Bluetooth on supported Raspberry Pi boards. +It's disabled by default and can be enabled by `krnbt=on` dtparam. It's +an alternative way of configuring Bluetooth, as compared to hciattach or +btattach. When the dtparam is enabled, the Bluetooth driver is probed +automatically and doesn't require any additional bring-up scripts. + +Note that Raspberry Pi 3 B rev 1.2 doesn't have the required hardware +flow control pins of UART0 connected to the Bluetooth module, so the +user should decrease the baudrate by passing `krnbt_baudrate=921600` +dtparam to make it more stable. It resembles the behavior of the btuart +script from Raspbian. + +The miniuart-bt overlay was modified to support Bluetooth probing with +device tree, too. It's disabled by default and can be enabled by +`krnbt=on` parameter of the miniuart-bt overlay. + +Signed-off-by: Maxim Mikityanskiy <maxtram95@gmail.com> +--- + arch/arm/boot/dts/bcm2708-rpi-bt.dtsi | 26 +++++++++++++++++++ + arch/arm/boot/dts/bcm2708-rpi-zero-w.dts | 1 + + arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 1 + + arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 1 + + arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 3 +-- + arch/arm/boot/dts/bcm271x-rpi-bt.dtsi | 26 +++++++++++++++++++ + arch/arm/boot/dts/overlays/README | 12 +++++++-- + .../boot/dts/overlays/disable-bt-overlay.dts | 13 ++++++++-- + .../boot/dts/overlays/miniuart-bt-overlay.dts | 21 ++++++++++++--- + 9 files changed, 94 insertions(+), 10 deletions(-) + create mode 100644 arch/arm/boot/dts/bcm2708-rpi-bt.dtsi + create mode 100644 arch/arm/boot/dts/bcm271x-rpi-bt.dtsi + +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2708-rpi-bt.dtsi +@@ -0,0 +1,26 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++&uart0 { ++ bt: bluetooth { ++ compatible = "brcm,bcm43438-bt"; ++ max-speed = <3000000>; ++ shutdown-gpios = <&gpio 45 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++}; ++ ++&uart1 { ++ minibt: bluetooth { ++ compatible = "brcm,bcm43438-bt"; ++ max-speed = <460800>; ++ shutdown-gpios = <&gpio 45 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++}; ++ ++/ { ++ __overrides__ { ++ krnbt = <&bt>,"status"; ++ krnbt_baudrate = <&bt>,"max-speed:0"; ++ }; ++}; +--- a/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts +@@ -4,6 +4,7 @@ + #include "bcm2708-rpi.dtsi" + #include "bcm283x-rpi-csi1-2lane.dtsi" + #include "bcm283x-rpi-i2c0mux_0_28.dtsi" ++#include "bcm2708-rpi-bt.dtsi" + + / { + compatible = "raspberrypi,model-zero-w", "brcm,bcm2835"; +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts +@@ -5,6 +5,7 @@ + #include "bcm283x-rpi-lan7515.dtsi" + #include "bcm283x-rpi-csi1-2lane.dtsi" + #include "bcm283x-rpi-i2c0mux_0_44.dtsi" ++#include "bcm271x-rpi-bt.dtsi" + + / { + compatible = "raspberrypi,3-model-b-plus", "brcm,bcm2837"; +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +@@ -5,6 +5,7 @@ + #include "bcm283x-rpi-smsc9514.dtsi" + #include "bcm283x-rpi-csi1-2lane.dtsi" + #include "bcm283x-rpi-i2c0mux_0_44.dtsi" ++#include "bcm271x-rpi-bt.dtsi" + + / { + compatible = "raspberrypi,3-model-b", "brcm,bcm2837"; +--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts +@@ -182,6 +182,7 @@ + // Downstream rpi- changes + + #include "bcm270x.dtsi" ++#include "bcm271x-rpi-bt.dtsi" + + / { + soc { +@@ -250,8 +251,6 @@ + &uart0 { + pinctrl-0 = <&uart0_pins &bt_pins>; + status = "okay"; +- +- /delete-node/ bluetooth; + }; + + &uart1 { +--- /dev/null ++++ b/arch/arm/boot/dts/bcm271x-rpi-bt.dtsi +@@ -0,0 +1,26 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++&uart0 { ++ bt: bluetooth { ++ compatible = "brcm,bcm43438-bt"; ++ max-speed = <3000000>; ++ shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++}; ++ ++&uart1 { ++ minibt: bluetooth { ++ compatible = "brcm,bcm43438-bt"; ++ max-speed = <460800>; ++ shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++}; ++ ++/ { ++ __overrides__ { ++ krnbt = <&bt>,"status"; ++ krnbt_baudrate = <&bt>,"max-speed:0"; ++ }; ++}; +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -162,6 +162,13 @@ Params: + i2s Set to "on" to enable the i2s interface + (default "off") + ++ krnbt Set to "on" to enable autoprobing of Bluetooth ++ driver without need of hciattach/btattach ++ (default "off") ++ ++ krnbt_baudrate Set the baudrate of the PL011 UART when used ++ with krnbt=on ++ + spi Set to "on" to enable the spi interfaces + (default "off") + +@@ -1764,8 +1771,9 @@ Info: Switch the onboard Bluetooth fun + in which case use /dev/serial1 instead because it will always be + correct. Furthermore, you must also set core_freq and core_freq_min to + the same value in config.txt or the miniuart will not work. +-Load: dtoverlay=miniuart-bt +-Params: <None> ++Load: dtoverlay=miniuart-bt,<param>=<val> ++Params: krnbt Set to "on" to enable autoprobing of Bluetooth ++ driver without need of hciattach/btattach + + + Name: mmc +--- a/arch/arm/boot/dts/overlays/disable-bt-overlay.dts ++++ b/arch/arm/boot/dts/overlays/disable-bt-overlay.dts +@@ -8,6 +8,8 @@ + sudo systemctl disable hciuart + */ + ++#include <dt-bindings/gpio/gpio.h> ++ + /{ + compatible = "brcm,bcm2835"; + +@@ -28,6 +30,13 @@ + }; + + fragment@2 { ++ target = <&bt>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { + target = <&uart0_pins>; + __overlay__ { + brcm,pins; +@@ -36,7 +45,7 @@ + }; + }; + +- fragment@3 { ++ fragment@4 { + target = <&bt_pins>; + __overlay__ { + brcm,pins; +@@ -45,7 +54,7 @@ + }; + }; + +- fragment@4 { ++ fragment@5 { + target-path = "/aliases"; + __overlay__ { + serial0 = "/soc/serial@7e201000"; +--- a/arch/arm/boot/dts/overlays/miniuart-bt-overlay.dts ++++ b/arch/arm/boot/dts/overlays/miniuart-bt-overlay.dts +@@ -15,6 +15,8 @@ + this overlay is used. + */ + ++#include <dt-bindings/gpio/gpio.h> ++ + /{ + compatible = "brcm,bcm2835"; + +@@ -28,6 +30,13 @@ + }; + + fragment@1 { ++ target = <&bt>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { + target = <&uart1>; + __overlay__ { + pinctrl-names = "default"; +@@ -36,7 +45,7 @@ + }; + }; + +- fragment@2 { ++ fragment@3 { + target = <&uart0_pins>; + __overlay__ { + brcm,pins; +@@ -45,7 +54,7 @@ + }; + }; + +- fragment@3 { ++ fragment@4 { + target = <&uart1_pins>; + __overlay__ { + brcm,pins = <32 33>; +@@ -54,7 +63,7 @@ + }; + }; + +- fragment@4 { ++ fragment@5 { + target = <&gpio>; + __overlay__ { + fake_bt_cts: fake_bt_cts { +@@ -64,11 +73,15 @@ + }; + }; + +- fragment@5 { ++ fragment@6 { + target-path = "/aliases"; + __overlay__ { + serial0 = "/soc/serial@7e201000"; + serial1 = "/soc/serial@7e215040"; + }; + }; ++ ++ __overrides__ { ++ krnbt = <&minibt>,"status"; ++ }; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0842-drm-vc4-Allow-interlaced-HDMI-modes-from-FKMS.patch b/target/linux/bcm27xx/patches-5.4/950-0842-drm-vc4-Allow-interlaced-HDMI-modes-from-FKMS.patch new file mode 100644 index 0000000000..8cb85316c6 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0842-drm-vc4-Allow-interlaced-HDMI-modes-from-FKMS.patch @@ -0,0 +1,37 @@ +From 354bf89fd678a6da6256a6ac37440c27c3b62e80 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 30 Jun 2020 18:04:13 +0100 +Subject: [PATCH] drm/vc4: Allow interlaced HDMI modes from FKMS. + +Having checked the firmware handling for interlaced modes, +it appears to be possible to support interlaced modes on +HDMI without adverse side effects, so do so. + +https://github.com/raspberrypi/linux/issues/3694 + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -936,6 +936,9 @@ static void vc4_crtc_mode_set_nofb(struc + break; + } + ++ if (mode->flags & DRM_MODE_FLAG_INTERLACE) ++ mb.timings.flags |= TIMINGS_FLAGS_INTERLACE; ++ + mb.timings.video_id_code = frame.avi.video_code; + + if (!vc4_encoder->hdmi_monitor) { +@@ -1632,7 +1635,7 @@ vc4_fkms_connector_init(struct drm_devic + DRM_MODE_CONNECTOR_HDMIA); + drm_connector_helper_add(connector, + &vc4_fkms_connector_helper_funcs); +- connector->interlace_allowed = 0; ++ connector->interlace_allowed = 1; + } + + ret = drm_mode_create_tv_margin_properties(dev); diff --git a/target/linux/bcm27xx/patches-5.4/950-0843-serial-8250-bcm2835aux-defer-if-clock-is-zero.patch b/target/linux/bcm27xx/patches-5.4/950-0843-serial-8250-bcm2835aux-defer-if-clock-is-zero.patch new file mode 100644 index 0000000000..b421ba9cdc --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0843-serial-8250-bcm2835aux-defer-if-clock-is-zero.patch @@ -0,0 +1,28 @@ +From 80163961af8e31a2045271c5a12adaae620445e1 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Thu, 2 Jul 2020 13:53:20 +0100 +Subject: [PATCH] serial: 8250: bcm2835aux - defer if clock is zero + +See: https://github.com/raspberrypi/linux/issues/3700 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/tty/serial/8250/8250_bcm2835aux.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/tty/serial/8250/8250_bcm2835aux.c ++++ b/drivers/tty/serial/8250/8250_bcm2835aux.c +@@ -92,6 +92,13 @@ static int bcm2835aux_serial_probe(struc + */ + data->uart.port.uartclk = clk_get_rate(data->clk) * 2; + ++ /* The clock is only queried at probe time, which means we get one shot ++ * at this. A zero clock is never going to work and is almost certainly ++ * due to a parent not being ready, so prefer to defer. ++ */ ++ if (!data->uart.port.uartclk) ++ return -EPROBE_DEFER; ++ + /* register the port */ + ret = serial8250_register_8250_port(&data->uart); + if (ret < 0) { diff --git a/target/linux/bcm27xx/patches-5.4/950-0844-media-v4l-Add-14-bit-raw-bayer-pixel-formats.patch b/target/linux/bcm27xx/patches-5.4/950-0844-media-v4l-Add-14-bit-raw-bayer-pixel-formats.patch new file mode 100644 index 0000000000..1bb9a932a3 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0844-media-v4l-Add-14-bit-raw-bayer-pixel-formats.patch @@ -0,0 +1,151 @@ +From 59a535539277240c4bdbb9c21bc07c8b586b2c3a Mon Sep 17 00:00:00 2001 +From: Sakari Ailus <sakari.ailus@linux.intel.com> +Date: Mon, 24 Feb 2020 18:52:20 +0100 +Subject: [PATCH] media: v4l: Add 14-bit raw bayer pixel formats +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit d12127ed0e18192491c2508caae45bb19c2f8fdd upstream. + +The formats added by this patch are: + + V4L2_PIX_FMT_SBGGR14 + V4L2_PIX_FMT_SGBRG14 + V4L2_PIX_FMT_SGRBG14 + V4L2_PIX_FMT_SRGGB14 + +Signed-off-by: Jouni Ukkonen <jouni.ukkonen@intel.com> +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +[dg@emlix.com: rebased onto current media_tree] +Signed-off-by: Daniel Glöckner <dg@emlix.com> +Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + Documentation/media/uapi/v4l/pixfmt-bayer.rst | 1 + + .../media/uapi/v4l/pixfmt-srggb14.rst | 82 +++++++++++++++++++ + drivers/media/v4l2-core/v4l2-ioctl.c | 4 + + include/uapi/linux/videodev2.h | 4 + + 4 files changed, 91 insertions(+) + create mode 100644 Documentation/media/uapi/v4l/pixfmt-srggb14.rst + +--- a/Documentation/media/uapi/v4l/pixfmt-bayer.rst ++++ b/Documentation/media/uapi/v4l/pixfmt-bayer.rst +@@ -34,5 +34,6 @@ orders. See also `the Wikipedia article + pixfmt-srggb10-ipu3 + pixfmt-srggb12 + pixfmt-srggb12p ++ pixfmt-srggb14 + pixfmt-srggb14p + pixfmt-srggb16 +--- /dev/null ++++ b/Documentation/media/uapi/v4l/pixfmt-srggb14.rst +@@ -0,0 +1,82 @@ ++.. Permission is granted to copy, distribute and/or modify this ++.. document under the terms of the GNU Free Documentation License, ++.. Version 1.1 or any later version published by the Free Software ++.. Foundation, with no Invariant Sections, no Front-Cover Texts ++.. and no Back-Cover Texts. A copy of the license is included at ++.. Documentation/media/uapi/fdl-appendix.rst. ++.. ++.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections ++ ++.. _V4L2-PIX-FMT-SRGGB14: ++.. _v4l2-pix-fmt-sbggr14: ++.. _v4l2-pix-fmt-sgbrg14: ++.. _v4l2-pix-fmt-sgrbg14: ++ ++ ++*************************************************************************************************************************** ++V4L2_PIX_FMT_SRGGB14 ('RG14'), V4L2_PIX_FMT_SGRBG14 ('GR14'), V4L2_PIX_FMT_SGBRG14 ('GB14'), V4L2_PIX_FMT_SBGGR14 ('BG14'), ++*************************************************************************************************************************** ++ ++ ++14-bit Bayer formats expanded to 16 bits ++ ++ ++Description ++=========== ++ ++These four pixel formats are raw sRGB / Bayer formats with 14 bits per ++colour. Each sample is stored in a 16-bit word, with two unused high ++bits filled with zeros. Each n-pixel row contains n/2 green samples ++and n/2 blue or red samples, with alternating red and blue rows. Bytes ++are stored in memory in little endian order. They are conventionally ++described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an ++example of a small V4L2_PIX_FMT_SBGGR14 image: ++ ++**Byte Order.** ++Each cell is one byte, the two most significant bits in the high bytes are ++zero. ++ ++ ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 2 1 1 1 1 1 1 1 1 ++ ++ ++ * - start + 0: ++ - B\ :sub:`00low` ++ - B\ :sub:`00high` ++ - G\ :sub:`01low` ++ - G\ :sub:`01high` ++ - B\ :sub:`02low` ++ - B\ :sub:`02high` ++ - G\ :sub:`03low` ++ - G\ :sub:`03high` ++ * - start + 8: ++ - G\ :sub:`10low` ++ - G\ :sub:`10high` ++ - R\ :sub:`11low` ++ - R\ :sub:`11high` ++ - G\ :sub:`12low` ++ - G\ :sub:`12high` ++ - R\ :sub:`13low` ++ - R\ :sub:`13high` ++ * - start + 16: ++ - B\ :sub:`20low` ++ - B\ :sub:`20high` ++ - G\ :sub:`21low` ++ - G\ :sub:`21high` ++ - B\ :sub:`22low` ++ - B\ :sub:`22high` ++ - G\ :sub:`23low` ++ - G\ :sub:`23high` ++ * - start + 24: ++ - G\ :sub:`30low` ++ - G\ :sub:`30high` ++ - R\ :sub:`31low` ++ - R\ :sub:`31high` ++ - G\ :sub:`32low` ++ - G\ :sub:`32high` ++ - R\ :sub:`33low` ++ - R\ :sub:`33high` +--- a/drivers/media/v4l2-core/v4l2-ioctl.c ++++ b/drivers/media/v4l2-core/v4l2-ioctl.c +@@ -1298,6 +1298,10 @@ static void v4l_fill_fmtdesc(struct v4l2 + case V4L2_PIX_FMT_SGBRG12P: descr = "12-bit Bayer GBGB/RGRG Packed"; break; + case V4L2_PIX_FMT_SGRBG12P: descr = "12-bit Bayer GRGR/BGBG Packed"; break; + case V4L2_PIX_FMT_SRGGB12P: descr = "12-bit Bayer RGRG/GBGB Packed"; break; ++ case V4L2_PIX_FMT_SBGGR14: descr = "14-bit Bayer BGBG/GRGR"; break; ++ case V4L2_PIX_FMT_SGBRG14: descr = "14-bit Bayer GBGB/RGRG"; break; ++ case V4L2_PIX_FMT_SGRBG14: descr = "14-bit Bayer GRGR/BGBG"; break; ++ case V4L2_PIX_FMT_SRGGB14: descr = "14-bit Bayer RGRG/GBGB"; break; + case V4L2_PIX_FMT_SBGGR14P: descr = "14-bit Bayer BGBG/GRGR Packed"; break; + case V4L2_PIX_FMT_SGBRG14P: descr = "14-bit Bayer GBGB/RGRG Packed"; break; + case V4L2_PIX_FMT_SGRBG14P: descr = "14-bit Bayer GRGR/BGBG Packed"; break; +--- a/include/uapi/linux/videodev2.h ++++ b/include/uapi/linux/videodev2.h +@@ -666,6 +666,10 @@ struct v4l2_pix_format { + #define V4L2_PIX_FMT_SGBRG12P v4l2_fourcc('p', 'G', 'C', 'C') + #define V4L2_PIX_FMT_SGRBG12P v4l2_fourcc('p', 'g', 'C', 'C') + #define V4L2_PIX_FMT_SRGGB12P v4l2_fourcc('p', 'R', 'C', 'C') ++#define V4L2_PIX_FMT_SBGGR14 v4l2_fourcc('B', 'G', '1', '4') /* 14 BGBG.. GRGR.. */ ++#define V4L2_PIX_FMT_SGBRG14 v4l2_fourcc('G', 'B', '1', '4') /* 14 GBGB.. RGRG.. */ ++#define V4L2_PIX_FMT_SGRBG14 v4l2_fourcc('G', 'R', '1', '4') /* 14 GRGR.. BGBG.. */ ++#define V4L2_PIX_FMT_SRGGB14 v4l2_fourcc('R', 'G', '1', '4') /* 14 RGRG.. GBGB.. */ + /* 14bit raw bayer packed, 7 bytes for every 4 pixels */ + #define V4L2_PIX_FMT_SBGGR14P v4l2_fourcc('p', 'B', 'E', 'E') + #define V4L2_PIX_FMT_SGBRG14P v4l2_fourcc('p', 'G', 'E', 'E') diff --git a/target/linux/bcm27xx/patches-5.4/950-0845-media-v4l-Add-14-bit-raw-greyscale-pixel-format.patch b/target/linux/bcm27xx/patches-5.4/950-0845-media-v4l-Add-14-bit-raw-greyscale-pixel-format.patch new file mode 100644 index 0000000000..1910668595 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0845-media-v4l-Add-14-bit-raw-greyscale-pixel-format.patch @@ -0,0 +1,131 @@ +From 363792f3fff5f4f79e2ac08ccfcc21c05216787a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20Gl=C3=B6ckner?= <dg@emlix.com> +Date: Mon, 24 Feb 2020 18:52:21 +0100 +Subject: [PATCH] media: v4l: Add 14-bit raw greyscale pixel format +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit ae9753a04cfc8e41262605875e531b6ea5e3d0ac upstream. + +The new format is called V4L2_PIX_FMT_Y14. Like V4L2_PIX_FMT_Y10 and +V4L2_PIX_FMT_Y12 it is stored in two bytes per pixel but has only two +unused bits at the top. + +Signed-off-by: Daniel Glöckner <dg@emlix.com> +Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> +Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + Documentation/media/uapi/v4l/pixfmt-y14.rst | 72 ++++++++++++++++++++ + Documentation/media/uapi/v4l/yuv-formats.rst | 1 + + drivers/media/v4l2-core/v4l2-ioctl.c | 1 + + include/uapi/linux/videodev2.h | 1 + + 4 files changed, 75 insertions(+) + create mode 100644 Documentation/media/uapi/v4l/pixfmt-y14.rst + +--- /dev/null ++++ b/Documentation/media/uapi/v4l/pixfmt-y14.rst +@@ -0,0 +1,72 @@ ++.. Permission is granted to copy, distribute and/or modify this ++.. document under the terms of the GNU Free Documentation License, ++.. Version 1.1 or any later version published by the Free Software ++.. Foundation, with no Invariant Sections, no Front-Cover Texts ++.. and no Back-Cover Texts. A copy of the license is included at ++.. Documentation/media/uapi/fdl-appendix.rst. ++.. ++.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections ++ ++.. _V4L2-PIX-FMT-Y14: ++ ++************************* ++V4L2_PIX_FMT_Y14 ('Y14 ') ++************************* ++ ++ ++Grey-scale image ++ ++ ++Description ++=========== ++ ++This is a grey-scale image with a depth of 14 bits per pixel. Pixels are ++stored in 16-bit words with unused high bits padded with 0. The least ++significant byte is stored at lower memory addresses (little-endian). ++ ++**Byte Order.** ++Each cell is one byte. ++ ++ ++ ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ ++ * - start + 0: ++ - Y'\ :sub:`00low` ++ - Y'\ :sub:`00high` ++ - Y'\ :sub:`01low` ++ - Y'\ :sub:`01high` ++ - Y'\ :sub:`02low` ++ - Y'\ :sub:`02high` ++ - Y'\ :sub:`03low` ++ - Y'\ :sub:`03high` ++ * - start + 8: ++ - Y'\ :sub:`10low` ++ - Y'\ :sub:`10high` ++ - Y'\ :sub:`11low` ++ - Y'\ :sub:`11high` ++ - Y'\ :sub:`12low` ++ - Y'\ :sub:`12high` ++ - Y'\ :sub:`13low` ++ - Y'\ :sub:`13high` ++ * - start + 16: ++ - Y'\ :sub:`20low` ++ - Y'\ :sub:`20high` ++ - Y'\ :sub:`21low` ++ - Y'\ :sub:`21high` ++ - Y'\ :sub:`22low` ++ - Y'\ :sub:`22high` ++ - Y'\ :sub:`23low` ++ - Y'\ :sub:`23high` ++ * - start + 24: ++ - Y'\ :sub:`30low` ++ - Y'\ :sub:`30high` ++ - Y'\ :sub:`31low` ++ - Y'\ :sub:`31high` ++ - Y'\ :sub:`32low` ++ - Y'\ :sub:`32high` ++ - Y'\ :sub:`33low` ++ - Y'\ :sub:`33high` +--- a/Documentation/media/uapi/v4l/yuv-formats.rst ++++ b/Documentation/media/uapi/v4l/yuv-formats.rst +@@ -35,6 +35,7 @@ to brightness information. + pixfmt-grey + pixfmt-y10 + pixfmt-y12 ++ pixfmt-y14 + pixfmt-y10b + pixfmt-y10p + pixfmt-y16 +--- a/drivers/media/v4l2-core/v4l2-ioctl.c ++++ b/drivers/media/v4l2-core/v4l2-ioctl.c +@@ -1212,6 +1212,7 @@ static void v4l_fill_fmtdesc(struct v4l2 + case V4L2_PIX_FMT_Y6: descr = "6-bit Greyscale"; break; + case V4L2_PIX_FMT_Y10: descr = "10-bit Greyscale"; break; + case V4L2_PIX_FMT_Y12: descr = "12-bit Greyscale"; break; ++ case V4L2_PIX_FMT_Y14: descr = "14-bit Greyscale"; break; + case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break; + case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break; + case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break; +--- a/include/uapi/linux/videodev2.h ++++ b/include/uapi/linux/videodev2.h +@@ -569,6 +569,7 @@ struct v4l2_pix_format { + #define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */ + #define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */ + #define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') /* 12 Greyscale */ ++#define V4L2_PIX_FMT_Y14 v4l2_fourcc('Y', '1', '4', ' ') /* 14 Greyscale */ + #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ + #define V4L2_PIX_FMT_Y16_BE v4l2_fourcc_be('Y', '1', '6', ' ') /* 16 Greyscale BE */ + diff --git a/target/linux/bcm27xx/patches-5.4/950-0846-media-v4l-Add-1X14-14-bit-greyscale-media-bus-code-d.patch b/target/linux/bcm27xx/patches-5.4/950-0846-media-v4l-Add-1X14-14-bit-greyscale-media-bus-code-d.patch new file mode 100644 index 0000000000..09c4330157 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0846-media-v4l-Add-1X14-14-bit-greyscale-media-bus-code-d.patch @@ -0,0 +1,88 @@ +From efc06d6c82d5b6b3ee5dd2bfa7c010f737a0fa49 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20Gl=C3=B6ckner?= <dg@emlix.com> +Date: Mon, 24 Feb 2020 18:52:22 +0100 +Subject: [PATCH] media: v4l: Add 1X14 14-bit greyscale media bus + code definition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit 573a750813459725c6f6fc4bc5779da1fe03238a upstream. + +The code is called MEDIA_BUS_FMT_Y14_1X14 and behaves just like +MEDIA_BUS_FMT_Y12_1X12 with two more bits. + +Signed-off-by: Daniel Glöckner <dg@emlix.com> +Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> +Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + .../media/uapi/v4l/subdev-formats.rst | 37 +++++++++++++++++++ + include/uapi/linux/media-bus-format.h | 3 +- + 2 files changed, 39 insertions(+), 1 deletion(-) + +--- a/Documentation/media/uapi/v4l/subdev-formats.rst ++++ b/Documentation/media/uapi/v4l/subdev-formats.rst +@@ -5792,6 +5792,43 @@ the following codes. + - u\ :sub:`2` + - u\ :sub:`1` + - u\ :sub:`0` ++ * .. _MEDIA-BUS-FMT-Y14-1X14: ++ ++ - MEDIA_BUS_FMT_Y14_1X14 ++ - 0x202d ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - y\ :sub:`13` ++ - y\ :sub:`12` ++ - y\ :sub:`11` ++ - y\ :sub:`10` ++ - y\ :sub:`9` ++ - y\ :sub:`8` ++ - y\ :sub:`7` ++ - y\ :sub:`6` ++ - y\ :sub:`5` ++ - y\ :sub:`4` ++ - y\ :sub:`3` ++ - y\ :sub:`2` ++ - y\ :sub:`1` ++ - y\ :sub:`0` + * .. _MEDIA-BUS-FMT-UYVY8-1X16: + + - MEDIA_BUS_FMT_UYVY8_1X16 +--- a/include/uapi/linux/media-bus-format.h ++++ b/include/uapi/linux/media-bus-format.h +@@ -64,7 +64,7 @@ + #define MEDIA_BUS_FMT_RGB121212_1X36 0x1019 + #define MEDIA_BUS_FMT_RGB161616_1X48 0x101a + +-/* YUV (including grey) - next is 0x202d */ ++/* YUV (including grey) - next is 0x202e */ + #define MEDIA_BUS_FMT_Y8_1X8 0x2001 + #define MEDIA_BUS_FMT_UV8_1X8 0x2015 + #define MEDIA_BUS_FMT_UYVY8_1_5X8 0x2002 +@@ -86,6 +86,7 @@ + #define MEDIA_BUS_FMT_VYUY12_2X12 0x201d + #define MEDIA_BUS_FMT_YUYV12_2X12 0x201e + #define MEDIA_BUS_FMT_YVYU12_2X12 0x201f ++#define MEDIA_BUS_FMT_Y14_1X14 0x202d + #define MEDIA_BUS_FMT_UYVY8_1X16 0x200f + #define MEDIA_BUS_FMT_VYUY8_1X16 0x2010 + #define MEDIA_BUS_FMT_YUYV8_1X16 0x2011 diff --git a/target/linux/bcm27xx/patches-5.4/950-0847-media-Add-a-pixel-format-for-MIPI-packed-12bit-luma-.patch b/target/linux/bcm27xx/patches-5.4/950-0847-media-Add-a-pixel-format-for-MIPI-packed-12bit-luma-.patch new file mode 100644 index 0000000000..b5d407b205 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0847-media-Add-a-pixel-format-for-MIPI-packed-12bit-luma-.patch @@ -0,0 +1,95 @@ +From 14ed8669ba80f2bb9a5f0d6be51052813d4a75e8 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 7 May 2020 16:59:03 +0100 +Subject: [PATCH] media: Add a pixel format for MIPI packed 12bit + luma only. + +This is the format used by monochrome 12bit image sensors. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + Documentation/media/uapi/v4l/pixfmt-y12p.rst | 45 ++++++++++++++++++++ + Documentation/media/uapi/v4l/yuv-formats.rst | 1 + + drivers/media/v4l2-core/v4l2-ioctl.c | 1 + + include/uapi/linux/videodev2.h | 1 + + 4 files changed, 48 insertions(+) + create mode 100644 Documentation/media/uapi/v4l/pixfmt-y12p.rst + +--- /dev/null ++++ b/Documentation/media/uapi/v4l/pixfmt-y12p.rst +@@ -0,0 +1,45 @@ ++.. Permission is granted to copy, distribute and/or modify this ++.. document under the terms of the GNU Free Documentation License, ++.. Version 1.1 or any later version published by the Free Software ++.. Foundation, with no Invariant Sections, no Front-Cover Texts ++.. and no Back-Cover Texts. A copy of the license is included at ++.. Documentation/media/uapi/fdl-appendix.rst. ++.. ++.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections ++ ++.. _V4L2-PIX-FMT-Y12P: ++ ++****************************** ++V4L2_PIX_FMT_Y12P ('Y12P') ++****************************** ++ ++Grey-scale image as a MIPI RAW12 packed array ++ ++ ++Description ++=========== ++ ++This is a packed grey-scale image format with a depth of 12 bits per ++pixel. Two consecutive pixels are packed into 3 bytes. The first 2 bytes ++contain the 8 high order bits of the pixels, and the 3rd byte contains the 4 ++least significants bits of each pixel, in the same order. ++ ++**Byte Order.** ++Each cell is one byte. ++ ++.. tabularcolumns:: |p{2.2cm}|p{1.2cm}|p{1.2cm}|p{3.1cm}| ++ ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 2 1 1 1 ++ ++ ++ - - start + 0: ++ - Y'\ :sub:`00high` ++ - Y'\ :sub:`01high` ++ - Y'\ :sub:`01low`\ (bits 7--4) ++ ++ Y'\ :sub:`00low`\ (bits 3--0) ++ +--- a/Documentation/media/uapi/v4l/yuv-formats.rst ++++ b/Documentation/media/uapi/v4l/yuv-formats.rst +@@ -35,6 +35,7 @@ to brightness information. + pixfmt-grey + pixfmt-y10 + pixfmt-y12 ++ pixfmt-y12p + pixfmt-y14 + pixfmt-y10b + pixfmt-y10p +--- a/drivers/media/v4l2-core/v4l2-ioctl.c ++++ b/drivers/media/v4l2-core/v4l2-ioctl.c +@@ -1217,6 +1217,7 @@ static void v4l_fill_fmtdesc(struct v4l2 + case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break; + case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break; + case V4L2_PIX_FMT_Y10P: descr = "10-bit Greyscale (MIPI Packed)"; break; ++ case V4L2_PIX_FMT_Y12P: descr = "12-bit Greyscale (MIPI Packed)"; break; + case V4L2_PIX_FMT_Y8I: descr = "Interleaved 8-bit Greyscale"; break; + case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; break; + case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break; +--- a/include/uapi/linux/videodev2.h ++++ b/include/uapi/linux/videodev2.h +@@ -576,6 +576,7 @@ struct v4l2_pix_format { + /* Grey bit-packed formats */ + #define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */ + #define V4L2_PIX_FMT_Y10P v4l2_fourcc('Y', '1', '0', 'P') /* 10 Greyscale, MIPI RAW10 packed */ ++#define V4L2_PIX_FMT_Y12P v4l2_fourcc('Y', '1', '2', 'P') /* 12 Greyscale, MIPI RAW12 packed */ + + /* Palette formats */ + #define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */ diff --git a/target/linux/bcm27xx/patches-5.4/950-0848-media-Add-a-pixel-format-for-MIPI-packed-14bit-luma-.patch b/target/linux/bcm27xx/patches-5.4/950-0848-media-Add-a-pixel-format-for-MIPI-packed-14bit-luma-.patch new file mode 100644 index 0000000000..f8b255f15a --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0848-media-Add-a-pixel-format-for-MIPI-packed-14bit-luma-.patch @@ -0,0 +1,104 @@ +From 8c51a9a891458e5d66cfedea84b1a38ceb01b7ae Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 25 Jun 2020 17:51:03 +0100 +Subject: [PATCH] media: Add a pixel format for MIPI packed 14bit + luma only. + +This is the format used by monochrome 14bit image sensors. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + Documentation/media/uapi/v4l/pixfmt-y14p.rst | 54 ++++++++++++++++++++ + Documentation/media/uapi/v4l/yuv-formats.rst | 1 + + drivers/media/v4l2-core/v4l2-ioctl.c | 1 + + include/uapi/linux/videodev2.h | 1 + + 4 files changed, 57 insertions(+) + create mode 100644 Documentation/media/uapi/v4l/pixfmt-y14p.rst + +--- /dev/null ++++ b/Documentation/media/uapi/v4l/pixfmt-y14p.rst +@@ -0,0 +1,54 @@ ++.. Permission is granted to copy, distribute and/or modify this ++.. document under the terms of the GNU Free Documentation License, ++.. Version 1.1 or any later version published by the Free Software ++.. Foundation, with no Invariant Sections, no Front-Cover Texts ++.. and no Back-Cover Texts. A copy of the license is included at ++.. Documentation/media/uapi/fdl-appendix.rst. ++.. ++.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections ++ ++.. _V4L2-PIX-FMT-Y14P: ++ ++************************** ++V4L2_PIX_FMT_Y14P ('Y14P') ++************************** ++ ++Grey-scale image as a MIPI RAW14 packed array ++ ++ ++Description ++=========== ++ ++This is a packed grey-scale image format with a depth of 14 bits per ++pixel. Every four consecutive samples are packed into seven bytes. Each ++of the first four bytes contain the eight high order bits of the pixels, ++and the three following bytes contains the six least significants bits of ++each pixel, in the same order. ++ ++**Byte Order.** ++Each cell is one byte. ++ ++.. tabularcolumns:: |p{1.8cm}|p{1.0cm}|p{1.0cm}|p{1.0cm}|p{1.1cm}|p{3.3cm}|p{3.3cm}|p{3.3cm}| ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 2 1 1 1 1 3 3 3 ++ ++ ++ - - start + 0: ++ - Y'\ :sub:`00high` ++ - Y'\ :sub:`01high` ++ - Y'\ :sub:`02high` ++ - Y'\ :sub:`03high` ++ - Y'\ :sub:`01low bits 1--0`\ (bits 7--6) ++ ++ Y'\ :sub:`00low bits 5--0`\ (bits 5--0) ++ ++ - Y'\ :sub:`02low bits 3--0`\ (bits 7--4) ++ ++ Y'\ :sub:`01low bits 5--2`\ (bits 3--0) ++ ++ - Y'\ :sub:`03low bits 5--0`\ (bits 7--2) ++ ++ Y'\ :sub:`02low bits 5--4`\ (bits 1--0) +--- a/Documentation/media/uapi/v4l/yuv-formats.rst ++++ b/Documentation/media/uapi/v4l/yuv-formats.rst +@@ -37,6 +37,7 @@ to brightness information. + pixfmt-y12 + pixfmt-y12p + pixfmt-y14 ++ pixfmt-y14p + pixfmt-y10b + pixfmt-y10p + pixfmt-y16 +--- a/drivers/media/v4l2-core/v4l2-ioctl.c ++++ b/drivers/media/v4l2-core/v4l2-ioctl.c +@@ -1218,6 +1218,7 @@ static void v4l_fill_fmtdesc(struct v4l2 + case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break; + case V4L2_PIX_FMT_Y10P: descr = "10-bit Greyscale (MIPI Packed)"; break; + case V4L2_PIX_FMT_Y12P: descr = "12-bit Greyscale (MIPI Packed)"; break; ++ case V4L2_PIX_FMT_Y14P: descr = "14-bit Greyscale (MIPI Packed)"; break; + case V4L2_PIX_FMT_Y8I: descr = "Interleaved 8-bit Greyscale"; break; + case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; break; + case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break; +--- a/include/uapi/linux/videodev2.h ++++ b/include/uapi/linux/videodev2.h +@@ -577,6 +577,7 @@ struct v4l2_pix_format { + #define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */ + #define V4L2_PIX_FMT_Y10P v4l2_fourcc('Y', '1', '0', 'P') /* 10 Greyscale, MIPI RAW10 packed */ + #define V4L2_PIX_FMT_Y12P v4l2_fourcc('Y', '1', '2', 'P') /* 12 Greyscale, MIPI RAW12 packed */ ++#define V4L2_PIX_FMT_Y14P v4l2_fourcc('Y', '1', '4', 'P') /* 14 Greyscale, MIPI RAW12 packed */ + + /* Palette formats */ + #define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */ diff --git a/target/linux/bcm27xx/patches-5.4/950-0849-staging-vc04_services-isp-Add-support-for-14bit-Baye.patch b/target/linux/bcm27xx/patches-5.4/950-0849-staging-vc04_services-isp-Add-support-for-14bit-Baye.patch new file mode 100644 index 0000000000..837b6b5d95 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0849-staging-vc04_services-isp-Add-support-for-14bit-Baye.patch @@ -0,0 +1,75 @@ +From ac6ebed4a0e06b4102831976e826a5986732ed33 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Wed, 6 May 2020 18:09:04 +0100 +Subject: [PATCH] staging: vc04_services: isp: Add support for 14bit + Bayer + +The only thing missing was a set of defines, therefore add them in. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + .../bcm2835-isp/bcm2835_isp_fmts.h | 37 +++++++++++++++++++ + .../vc04_services/vchiq-mmal/mmal-encodings.h | 6 +++ + 2 files changed, 43 insertions(+) + +--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_fmts.h ++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_fmts.h +@@ -254,6 +254,43 @@ static const struct bcm2835_isp_fmt supp + .colorspace = V4L2_COLORSPACE_RAW, + .step_size = 2, + }, { ++ /* 14 bit */ ++ .fourcc = V4L2_PIX_FMT_SRGGB14P, ++ .depth = 14, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB14P, ++ .size_multiplier_x2 = 2, ++ .colorspace = V4L2_COLORSPACE_RAW, ++ .step_size = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SBGGR14P, ++ .depth = 14, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR14P, ++ .size_multiplier_x2 = 2, ++ .colorspace = V4L2_COLORSPACE_RAW, ++ .step_size = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGRBG14P, ++ .depth = 14, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG14P, ++ .size_multiplier_x2 = 2, ++ .colorspace = V4L2_COLORSPACE_RAW, ++ .step_size = 2, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGBRG14P, ++ .depth = 14, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG14P, ++ .size_multiplier_x2 = 2, ++ .colorspace = V4L2_COLORSPACE_RAW, ++ .step_size = 2, ++ }, { + /* 16 bit */ + .fourcc = V4L2_PIX_FMT_SRGGB16, + .depth = 16, +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h +@@ -90,6 +90,12 @@ + #define MMAL_ENCODING_BAYER_SGBRG12P MMAL_FOURCC('p', 'G', '1', '2') + #define MMAL_ENCODING_BAYER_SRGGB12P MMAL_FOURCC('p', 'R', '1', '2') + ++//14 bit per pixel Bayer formats. ++#define MMAL_ENCODING_BAYER_SBGGR14P MMAL_FOURCC('p', 'B', 'E', 'E') ++#define MMAL_ENCODING_BAYER_SGBRG14P MMAL_FOURCC('p', 'G', 'E', 'E') ++#define MMAL_ENCODING_BAYER_SGRBG14P MMAL_FOURCC('p', 'g', 'E', 'E') ++#define MMAL_ENCODING_BAYER_SRGGB14P MMAL_FOURCC('p', 'R', 'E', 'E') ++ + /* 16 bit per pixel Bayer formats. */ + #define MMAL_ENCODING_BAYER_SBGGR16 MMAL_FOURCC('B', 'G', '1', '6') + #define MMAL_ENCODING_BAYER_SGBRG16 MMAL_FOURCC('G', 'B', '1', '6') diff --git a/target/linux/bcm27xx/patches-5.4/950-0850-staging-vc04_services-isp-Add-monochrome-image-forma.patch b/target/linux/bcm27xx/patches-5.4/950-0850-staging-vc04_services-isp-Add-monochrome-image-forma.patch new file mode 100644 index 0000000000..849417f6ae --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0850-staging-vc04_services-isp-Add-monochrome-image-forma.patch @@ -0,0 +1,92 @@ +From ef305037fd7423386d3a59b640114bdff67d824f Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Wed, 6 May 2020 18:11:14 +0100 +Subject: [PATCH] staging: vc04_services: isp: Add monochrome image + formats + +Adds support for monochrome image formats in the various +MIPI packings. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + .../bcm2835-isp/bcm2835_isp_fmts.h | 52 ++++++++++++++++++- + .../vc04_services/vchiq-mmal/mmal-encodings.h | 7 +++ + 2 files changed, 58 insertions(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_fmts.h ++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_fmts.h +@@ -328,7 +328,57 @@ static const struct bcm2835_isp_fmt supp + .colorspace = V4L2_COLORSPACE_RAW, + .step_size = 2, + }, { +- /* ISP statistics format */ ++ /* Monochrome MIPI formats */ ++ /* 8 bit */ ++ .fourcc = V4L2_PIX_FMT_GREY, ++ .depth = 8, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_GREY, ++ .size_multiplier_x2 = 2, ++ .colorspace = V4L2_COLORSPACE_RAW, ++ .step_size = 2, ++ }, { ++ /* 10 bit */ ++ .fourcc = V4L2_PIX_FMT_Y10P, ++ .depth = 10, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_Y10P, ++ .size_multiplier_x2 = 2, ++ .colorspace = V4L2_COLORSPACE_RAW, ++ .step_size = 2, ++ }, { ++ /* 12 bit */ ++ .fourcc = V4L2_PIX_FMT_Y12P, ++ .depth = 12, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_Y12P, ++ .size_multiplier_x2 = 2, ++ .colorspace = V4L2_COLORSPACE_RAW, ++ .step_size = 2, ++ }, { ++ /* 14 bit */ ++ .fourcc = V4L2_PIX_FMT_Y14P, ++ .depth = 14, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_Y14P, ++ .size_multiplier_x2 = 2, ++ .colorspace = V4L2_COLORSPACE_RAW, ++ .step_size = 2, ++ }, { ++ /* 16 bit */ ++ .fourcc = V4L2_PIX_FMT_Y16, ++ .depth = 16, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_Y16, ++ .size_multiplier_x2 = 2, ++ .colorspace = V4L2_COLORSPACE_RAW, ++ .step_size = 2, ++ }, { + .fourcc = V4L2_META_FMT_BCM2835_ISP_STATS, + .mmal_fmt = MMAL_ENCODING_BRCM_STATS, + /* The rest are not valid fields for stats. */ +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h +@@ -102,6 +102,13 @@ + #define MMAL_ENCODING_BAYER_SGRBG16 MMAL_FOURCC('G', 'R', '1', '6') + #define MMAL_ENCODING_BAYER_SRGGB16 MMAL_FOURCC('R', 'G', '1', '6') + ++/* MIPI packed monochrome images */ ++#define MMAL_ENCODING_GREY MMAL_FOURCC('G', 'R', 'E', 'Y') ++#define MMAL_ENCODING_Y10P MMAL_FOURCC('Y', '1', '0', 'P') ++#define MMAL_ENCODING_Y12P MMAL_FOURCC('Y', '1', '2', 'P') ++#define MMAL_ENCODING_Y14P MMAL_FOURCC('Y', '1', '4', 'P') ++#define MMAL_ENCODING_Y16 MMAL_FOURCC('Y', '1', '6', ' ') ++ + /** An EGL image handle + */ + #define MMAL_ENCODING_EGL_IMAGE MMAL_FOURCC('E', 'G', 'L', 'I') diff --git a/target/linux/bcm27xx/patches-5.4/950-0851-staging-vc04_services-isp-Increase-the-number-of-sup.patch b/target/linux/bcm27xx/patches-5.4/950-0851-staging-vc04_services-isp-Increase-the-number-of-sup.patch new file mode 100644 index 0000000000..ebf16db9ae --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0851-staging-vc04_services-isp-Increase-the-number-of-sup.patch @@ -0,0 +1,29 @@ +From 9b0b99ee3711846203d6f2500925e8b463fbeb8e Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Wed, 6 May 2020 18:24:34 +0100 +Subject: [PATCH] staging: vc04_services: isp: Increase the number of + supported formats expected + +The ISP now supports 47 different input formats, therefore increase the +array size for the number expected. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c ++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c +@@ -1134,10 +1134,10 @@ static const struct v4l2_ioctl_ops bcm28 + * Size of the array to provide to the VPU when asking for the list of supported + * formats. + * +- * The ISP component currently advertises 33 input formats, so add a small ++ * The ISP component currently advertises 44 input formats, so add a small + * overhead on that. + */ +-#define MAX_SUPPORTED_ENCODINGS 40 ++#define MAX_SUPPORTED_ENCODINGS 50 + + /* Populate node->supported_fmts with the formats supported by those ports. */ + static int bcm2835_isp_get_supported_fmts(struct bcm2835_isp_node *node) diff --git a/target/linux/bcm27xx/patches-5.4/950-0852-staging-vc04_services-codec-Increase-the-number-of-s.patch b/target/linux/bcm27xx/patches-5.4/950-0852-staging-vc04_services-codec-Increase-the-number-of-s.patch new file mode 100644 index 0000000000..c4e20c61a1 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0852-staging-vc04_services-codec-Increase-the-number-of-s.patch @@ -0,0 +1,29 @@ +From 8827ec069302241c3a22371887d3980b9f855bba Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 25 Jun 2020 17:40:56 +0100 +Subject: [PATCH] staging: vc04_services: codec: Increase the number + of supported formats expected + +The ISP now supports 47 different input formats, therefore increase the +array size for the number expected. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -2569,10 +2569,10 @@ static const struct v4l2_m2m_ops m2m_ops + + /* Size of the array to provide to the VPU when asking for the list of supported + * formats. +- * The ISP component currently advertises 33 input formats, so add a small ++ * The ISP component currently advertises 44 input formats, so add a small + * overhead on that. + */ +-#define MAX_SUPPORTED_ENCODINGS 40 ++#define MAX_SUPPORTED_ENCODINGS 50 + + /* Populate dev->supported_fmts with the formats supported by those ports. */ + static int bcm2835_codec_get_supported_fmts(struct bcm2835_codec_dev *dev) diff --git a/target/linux/bcm27xx/patches-5.4/950-0853-staging-vc04_services-codec-Add-support-for-mono-for.patch b/target/linux/bcm27xx/patches-5.4/950-0853-staging-vc04_services-codec-Add-support-for-mono-for.patch new file mode 100644 index 0000000000..620ad14248 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0853-staging-vc04_services-codec-Add-support-for-mono-for.patch @@ -0,0 +1,64 @@ +From 6e6861281012b9ac99b85b9e2703cad35d91c279 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Wed, 1 Jul 2020 10:38:12 +0100 +Subject: [PATCH] staging: vc04_services: codec: Add support for mono + formats + +The firmware ISP component now allows for processing of mono +images, so add those formats for use by the simple ISP device. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + .../bcm2835-codec/bcm2835-v4l2-codec.c | 41 +++++++++++++++++++ + 1 file changed, 41 insertions(+) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -344,6 +344,47 @@ static const struct bcm2835_codec_fmt su + .size_multiplier_x2 = 2, + .is_bayer = true, + }, { ++ /* Monochrome MIPI formats */ ++ /* 8 bit */ ++ .fourcc = V4L2_PIX_FMT_GREY, ++ .depth = 8, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_GREY, ++ .size_multiplier_x2 = 2, ++ }, { ++ /* 10 bit */ ++ .fourcc = V4L2_PIX_FMT_Y10P, ++ .depth = 10, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_Y10P, ++ .size_multiplier_x2 = 2, ++ }, { ++ /* 12 bit */ ++ .fourcc = V4L2_PIX_FMT_Y12P, ++ .depth = 12, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_Y12P, ++ .size_multiplier_x2 = 2, ++ }, { ++ /* 14 bit */ ++ .fourcc = V4L2_PIX_FMT_Y14P, ++ .depth = 14, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_Y14P, ++ .size_multiplier_x2 = 2, ++ }, { ++ /* 16 bit */ ++ .fourcc = V4L2_PIX_FMT_Y16, ++ .depth = 16, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_Y16, ++ .size_multiplier_x2 = 2, ++ }, { + /* Compressed formats */ + .fourcc = V4L2_PIX_FMT_H264, + .depth = 0, diff --git a/target/linux/bcm27xx/patches-5.4/950-0854-staging-vc04_services-codec-Add-support-for-14bit-Ba.patch b/target/linux/bcm27xx/patches-5.4/950-0854-staging-vc04_services-codec-Add-support-for-14bit-Ba.patch new file mode 100644 index 0000000000..e261f62570 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0854-staging-vc04_services-codec-Add-support-for-14bit-Ba.patch @@ -0,0 +1,57 @@ +From 34963c9fb717bc47131b662c34a472c4f717f7fe Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Wed, 1 Jul 2020 10:50:12 +0100 +Subject: [PATCH] staging: vc04_services: codec: Add support for + 14bit Bayer formats + +Now that the 14bit Bayer formats have been defined within +V4L2, add them to the lookup table of V4L2/MMAL formats. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + .../bcm2835-codec/bcm2835-v4l2-codec.c | 34 +++++++++++++++++++ + 1 file changed, 34 insertions(+) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -311,6 +311,40 @@ static const struct bcm2835_codec_fmt su + .size_multiplier_x2 = 2, + .is_bayer = true, + }, { ++ /* 14 bit */ ++ .fourcc = V4L2_PIX_FMT_SRGGB14P, ++ .depth = 14, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB14P, ++ .size_multiplier_x2 = 2, ++ .is_bayer = true, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SBGGR14P, ++ .depth = 14, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR14P, ++ .size_multiplier_x2 = 2, ++ .is_bayer = true, ++ ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGRBG14P, ++ .depth = 14, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG14P, ++ .size_multiplier_x2 = 2, ++ .is_bayer = true, ++ }, { ++ .fourcc = V4L2_PIX_FMT_SGBRG14P, ++ .depth = 14, ++ .bytesperline_align = 32, ++ .flags = 0, ++ .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG14P, ++ .size_multiplier_x2 = 2, ++ .is_bayer = true, ++ }, { + /* 16 bit */ + .fourcc = V4L2_PIX_FMT_SRGGB16, + .depth = 16, diff --git a/target/linux/bcm27xx/patches-5.4/950-0855-media-bcm2835-unicam-Add-support-for-12bit-mono-pack.patch b/target/linux/bcm27xx/patches-5.4/950-0855-media-bcm2835-unicam-Add-support-for-12bit-mono-pack.patch new file mode 100644 index 0000000000..fdef58c626 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0855-media-bcm2835-unicam-Add-support-for-12bit-mono-pack.patch @@ -0,0 +1,25 @@ +From 511c9a4b7c3d2e40eee68dad4d4c02ca42678204 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 25 Jun 2020 17:53:32 +0100 +Subject: [PATCH] media: bcm2835-unicam: Add support for 12bit mono + packed format + +Now that V4L2_PIX_FMT_Y12P is defined, allow passing raw 12bit +mono packed data through the peripheral. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/platform/bcm2835/bcm2835-unicam.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -336,7 +336,7 @@ static const struct unicam_fmt formats[] + .depth = 10, + .csi_dt = 0x2b, + }, { +- /* NB There is no packed V4L2 fourcc for this format. */ ++ .fourcc = V4L2_PIX_FMT_Y12P, + .repacked_fourcc = V4L2_PIX_FMT_Y12, + .code = MEDIA_BUS_FMT_Y12_1X12, + .depth = 12, diff --git a/target/linux/bcm27xx/patches-5.4/950-0856-media-bcm2835-unicam-Add-support-for-14bit-mono-sour.patch b/target/linux/bcm27xx/patches-5.4/950-0856-media-bcm2835-unicam-Add-support-for-14bit-mono-sour.patch new file mode 100644 index 0000000000..a65945cb1b --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0856-media-bcm2835-unicam-Add-support-for-14bit-mono-sour.patch @@ -0,0 +1,29 @@ +From 668ed11b1e8fbbe7ad9a63abbfece67d44b0aa85 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 25 Jun 2020 18:03:47 +0100 +Subject: [PATCH] media: bcm2835-unicam: Add support for 14bit mono + sources + +Now that V4L2_PIX_FMT_Y14 and V4L2_PIX_FMT_Y14P are defined, +allow passing 14bit mono data through the peripheral. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/platform/bcm2835/bcm2835-unicam.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -341,6 +341,12 @@ static const struct unicam_fmt formats[] + .code = MEDIA_BUS_FMT_Y12_1X12, + .depth = 12, + .csi_dt = 0x2c, ++ }, { ++ .fourcc = V4L2_PIX_FMT_Y14P, ++ .repacked_fourcc = V4L2_PIX_FMT_Y14, ++ .code = MEDIA_BUS_FMT_Y14_1X14, ++ .depth = 14, ++ .csi_dt = 0x2d, + }, + /* Embedded data format */ + { diff --git a/target/linux/bcm27xx/patches-5.4/950-0857-media-bcm2835-unicam-Add-support-for-unpacked-14bit-.patch b/target/linux/bcm27xx/patches-5.4/950-0857-media-bcm2835-unicam-Add-support-for-unpacked-14bit-.patch new file mode 100644 index 0000000000..b52a59a6e0 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0857-media-bcm2835-unicam-Add-support-for-unpacked-14bit-.patch @@ -0,0 +1,42 @@ +From 9c0121e45af13c0b0850601ee4d88029c548b240 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Wed, 1 Jul 2020 10:57:57 +0100 +Subject: [PATCH] media: bcm2835-unicam: Add support for unpacked + 14bit Bayer formats + +Now that the 14bit non-packed Bayer formats are defined, add them +into the supported formats lookup table. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/platform/bcm2835/bcm2835-unicam.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -299,21 +299,25 @@ static const struct unicam_fmt formats[] + .csi_dt = 0x2c, + }, { + .fourcc = V4L2_PIX_FMT_SBGGR14P, ++ .repacked_fourcc = V4L2_PIX_FMT_SBGGR14, + .code = MEDIA_BUS_FMT_SBGGR14_1X14, + .depth = 14, + .csi_dt = 0x2d, + }, { + .fourcc = V4L2_PIX_FMT_SGBRG14P, ++ .repacked_fourcc = V4L2_PIX_FMT_SGBRG14, + .code = MEDIA_BUS_FMT_SGBRG14_1X14, + .depth = 14, + .csi_dt = 0x2d, + }, { + .fourcc = V4L2_PIX_FMT_SGRBG14P, ++ .repacked_fourcc = V4L2_PIX_FMT_SGRBG14, + .code = MEDIA_BUS_FMT_SGRBG14_1X14, + .depth = 14, + .csi_dt = 0x2d, + }, { + .fourcc = V4L2_PIX_FMT_SRGGB14P, ++ .repacked_fourcc = V4L2_PIX_FMT_SRGGB14, + .code = MEDIA_BUS_FMT_SRGGB14_1X14, + .depth = 14, + .csi_dt = 0x2d, diff --git a/target/linux/bcm27xx/patches-5.4/950-0858-overlays-Fix-miniuart-bt-krnbt-parameter.patch b/target/linux/bcm27xx/patches-5.4/950-0858-overlays-Fix-miniuart-bt-krnbt-parameter.patch new file mode 100644 index 0000000000..f7edf8a5b5 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0858-overlays-Fix-miniuart-bt-krnbt-parameter.patch @@ -0,0 +1,32 @@ +From 2d54451c77c85e153046baebdfedeabc224a59d7 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Thu, 2 Jul 2020 15:21:05 +0100 +Subject: [PATCH] overlays: Fix miniuart-bt "krnbt" parameter + +Although superficially appealing, an overlay parameter that targets a +label in the base DTB is not currently supported. Instead it is +necessary to create a fragment targeting the label which is patched +by the parameter. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/miniuart-bt-overlay.dts | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/overlays/miniuart-bt-overlay.dts ++++ b/arch/arm/boot/dts/overlays/miniuart-bt-overlay.dts +@@ -81,7 +81,13 @@ + }; + }; + ++ fragment@7 { ++ target = <&minibt>; ++ minibt_frag: __overlay__ { ++ }; ++ }; ++ + __overrides__ { +- krnbt = <&minibt>,"status"; ++ krnbt = <&minibt_frag>,"status"; + }; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0859-drm-vc4-Make-FKMS-max-refresh-rate-a-module-paramete.patch b/target/linux/bcm27xx/patches-5.4/950-0859-drm-vc4-Make-FKMS-max-refresh-rate-a-module-paramete.patch new file mode 100644 index 0000000000..bf27d7aa53 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0859-drm-vc4-Make-FKMS-max-refresh-rate-a-module-paramete.patch @@ -0,0 +1,55 @@ +From ff882e312a746a4a794a089e912e5e56baa8b5b4 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Fri, 3 Jul 2020 14:11:55 +0100 +Subject: [PATCH] drm/vc4: Make FKMS max refresh rate a module + parameter + +Some people want to use the high refresh rate modes for 1080p100 +and 1080p120, but they're currently filtered out as generally +they don't add anything. + +Make the filter threshold a module parameter so that it can be +adjusted. + +https://github.com/raspberrypi/linux/issues/3677 + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -14,6 +14,8 @@ + * Pi's firmware display stack. + */ + ++#include <linux/module.h> ++ + #include "drm/drm_atomic_helper.h" + #include "drm/drm_gem_framebuffer_helper.h" + #include "drm/drm_plane_helper.h" +@@ -32,6 +34,10 @@ + #include "vc_image_types.h" + #include <soc/bcm2835/raspberrypi-firmware.h> + ++int fkms_max_refresh_rate = 85; ++module_param(fkms_max_refresh_rate, int, 0644); ++MODULE_PARM_DESC(fkms_max_refresh_rate, "Max supported refresh rate"); ++ + struct get_display_cfg { + u32 max_pixel_clock[2]; //Max pixel clock for each display + }; +@@ -1069,8 +1075,10 @@ vc4_crtc_mode_valid(struct drm_crtc *crt + return MODE_NO_DBLESCAN; + } + +- /* Disable refresh rates > 85Hz as limited gain from them */ +- if (drm_mode_vrefresh(mode) > 85) ++ /* Disable refresh rates > defined threshold (default 85Hz) as limited ++ * gain from them ++ */ ++ if (drm_mode_vrefresh(mode) > fkms_max_refresh_rate) + return MODE_BAD_VVALUE; + + /* Limit the pixel clock based on the HDMI clock limits from the diff --git a/target/linux/bcm27xx/patches-5.4/950-0860-drm-vc4-FKMS-Block-modes-with-odd-horizontal-timing-.patch b/target/linux/bcm27xx/patches-5.4/950-0860-drm-vc4-FKMS-Block-modes-with-odd-horizontal-timing-.patch new file mode 100644 index 0000000000..4bddd13ad5 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0860-drm-vc4-FKMS-Block-modes-with-odd-horizontal-timing-.patch @@ -0,0 +1,74 @@ +From aa791f2cb6777e8ca99102009b631afdeea1c59d Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Fri, 3 Jul 2020 16:06:55 +0100 +Subject: [PATCH] drm/vc4: FKMS Block modes with odd horizontal + timing values on Pi4 + +Pi4 HDMI pipeline is 2 pixels/clock and can not produce timings +that have odd values for active pixels, front porch, sync width, +or back porch. +Detect these modes and block them within fkms. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -44,6 +44,7 @@ struct get_display_cfg { + + struct vc4_fkms { + struct get_display_cfg cfg; ++ bool bcm2711; + }; + + #define PLANES_PER_CRTC 3 +@@ -1097,6 +1098,17 @@ vc4_crtc_mode_valid(struct drm_crtc *crt + break; + } + ++ /* Pi4 can't generate odd horizontal timings on HDMI, so reject modes ++ * that would set them. ++ */ ++ if (fkms->bcm2711 && ++ (vc4_crtc->display_number == 2 || vc4_crtc->display_number == 7) && ++ ((mode->hdisplay | /* active */ ++ (mode->hsync_start - mode->hdisplay) | /* front porch */ ++ (mode->hsync_end - mode->hsync_start) | /* sync pulse */ ++ (mode->htotal - mode->hsync_end)) & 1)) /* back porch */ ++ return MODE_H_ILLEGAL; ++ + return MODE_OK; + } + +@@ -1282,6 +1294,8 @@ static const struct drm_crtc_helper_func + + static const struct of_device_id vc4_firmware_kms_dt_match[] = { + { .compatible = "raspberrypi,rpi-firmware-kms" }, ++ { .compatible = "raspberrypi,rpi-firmware-kms-2711", ++ .data = (void *)1 }, + {} + }; + +@@ -1815,6 +1829,7 @@ static int vc4_fkms_bind(struct device * + struct drm_device *drm = dev_get_drvdata(master); + struct vc4_dev *vc4 = to_vc4_dev(drm); + struct device_node *firmware_node; ++ const struct of_device_id *match; + struct vc4_crtc **crtc_list; + u32 num_displays, display_num; + struct vc4_fkms *fkms; +@@ -1827,6 +1842,12 @@ static int vc4_fkms_bind(struct device * + if (!fkms) + return -ENOMEM; + ++ match = of_match_device(vc4_firmware_kms_dt_match, dev); ++ if (!match) ++ return -ENODEV; ++ if (match->data) ++ fkms->bcm2711 = true; ++ + /* firmware kms doesn't have precise a scanoutpos implementation, so + * we can't do the precise vblank timestamp mode. + */ diff --git a/target/linux/bcm27xx/patches-5.4/950-0861-dt-Use-rpi-firmware-kms-2711-on-2711-platforms.patch b/target/linux/bcm27xx/patches-5.4/950-0861-dt-Use-rpi-firmware-kms-2711-on-2711-platforms.patch new file mode 100644 index 0000000000..d1805a6cd5 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0861-dt-Use-rpi-firmware-kms-2711-on-2711-platforms.patch @@ -0,0 +1,37 @@ +From 603b5b55d5f52869263647c44fe682d105f8ee46 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Fri, 3 Jul 2020 16:05:37 +0100 +Subject: [PATCH] dt: Use rpi-firmware-kms-2711 on 2711 platforms + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 4 ++++ + arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 4 ++++ + 2 files changed, 8 insertions(+) + +--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts +@@ -443,6 +443,10 @@ + }; + }; + ++&firmwarekms { ++ compatible = "raspberrypi,rpi-firmware-kms-2711"; ++}; ++ + // ============================================= + // Board specific stuff here + +--- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts +@@ -461,6 +461,10 @@ + }; + }; + ++&firmwarekms { ++ compatible = "raspberrypi,rpi-firmware-kms-2711"; ++}; ++ + // ============================================= + // Board specific stuff here + diff --git a/target/linux/bcm27xx/patches-5.4/950-0862-drm-vc4-FKMS-Put-includes-in-alphabetical-order-and-.patch b/target/linux/bcm27xx/patches-5.4/950-0862-drm-vc4-FKMS-Put-includes-in-alphabetical-order-and-.patch new file mode 100644 index 0000000000..4adbe8a03c --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0862-drm-vc4-FKMS-Put-includes-in-alphabetical-order-and-.patch @@ -0,0 +1,57 @@ +From 0a5e493ea20d9d24d0808d8a4e05a97deb19b423 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Fri, 3 Jul 2020 16:13:33 +0100 +Subject: [PATCH] drm/vc4: FKMS: Put includes in alphabetical order, + and use <> instead of "" + +Reorder the includes, and use the system include paths rather than +local ones + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 29 +++++++++++++------------- + 1 file changed, 15 insertions(+), 14 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -14,25 +14,26 @@ + * Pi's firmware display stack. + */ + ++#include <drm/drm_atomic_helper.h> ++#include <drm/drm_crtc_helper.h> ++#include <drm/drm_drv.h> ++#include <drm/drm_fb_cma_helper.h> ++#include <drm/drm_fourcc.h> ++#include <drm/drm_gem_framebuffer_helper.h> ++#include <drm/drm_plane_helper.h> ++#include <drm/drm_probe_helper.h> ++#include <drm/drm_vblank.h> ++ ++#include <linux/component.h> ++#include <linux/clk.h> ++#include <linux/debugfs.h> + #include <linux/module.h> + +-#include "drm/drm_atomic_helper.h" +-#include "drm/drm_gem_framebuffer_helper.h" +-#include "drm/drm_plane_helper.h" +-#include "drm/drm_crtc_helper.h" +-#include "drm/drm_fourcc.h" +-#include "drm/drm_probe_helper.h" +-#include "drm/drm_drv.h" +-#include "drm/drm_vblank.h" +-#include "linux/clk.h" +-#include "linux/debugfs.h" +-#include "drm/drm_fb_cma_helper.h" +-#include "linux/component.h" +-#include "linux/of_device.h" ++#include <soc/bcm2835/raspberrypi-firmware.h> ++ + #include "vc4_drv.h" + #include "vc4_regs.h" + #include "vc_image_types.h" +-#include <soc/bcm2835/raspberrypi-firmware.h> + + int fkms_max_refresh_rate = 85; + module_param(fkms_max_refresh_rate, int, 0644); diff --git a/target/linux/bcm27xx/patches-5.4/950-0863-irqchip-bcm2835-Quiesce-IRQs-left-enabled-by-bootloa.patch b/target/linux/bcm27xx/patches-5.4/950-0863-irqchip-bcm2835-Quiesce-IRQs-left-enabled-by-bootloa.patch new file mode 100644 index 0000000000..f27d448864 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0863-irqchip-bcm2835-Quiesce-IRQs-left-enabled-by-bootloa.patch @@ -0,0 +1,105 @@ +From 4ae861da5eaf53e5b4303f080bff0e34e22da0d9 Mon Sep 17 00:00:00 2001 +From: Lukas Wunner <lukas@wunner.de> +Date: Tue, 4 Feb 2020 15:50:41 +0100 +Subject: [PATCH] irqchip/bcm2835: Quiesce IRQs left enabled by + bootloader + +[ Upstream commit bd59b343a9c902c522f006e6d71080f4893bbf42 ] + +Per the spec, the BCM2835's IRQs are all disabled when coming out of +power-on reset. Its IRQ driver assumes that's still the case when the +kernel boots and does not perform any initialization of the registers. +However the Raspberry Pi Foundation's bootloader leaves the USB +interrupt enabled when handing over control to the kernel. + +Quiesce IRQs and the FIQ if they were left enabled and log a message to +let users know that they should update the bootloader once a fixed +version is released. + +If the USB interrupt is not quiesced and the USB driver later on claims +the FIQ (as it does on the Raspberry Pi Foundation's downstream kernel), +interrupt latency for all other peripherals increases and occasional +lockups occur. That's because both the FIQ and the normal USB interrupt +fire simultaneously: + +On a multicore Raspberry Pi, if normal interrupts are routed to CPU 0 +and the FIQ to CPU 1 (hardcoded in the Foundation's kernel), then a USB +interrupt causes CPU 0 to spin in bcm2836_chained_handle_irq() until the +FIQ on CPU 1 has cleared it. Other peripherals' interrupts are starved +as long. I've seen CPU 0 blocked for up to 2.9 msec. eMMC throughput +on a Compute Module 3 irregularly dips to 23.0 MB/s without this commit +but remains relatively constant at 23.5 MB/s with this commit. + +The lockups occur when CPU 0 receives a USB interrupt while holding a +lock which CPU 1 is trying to acquire while the FIQ is temporarily +disabled on CPU 1. At best users get RCU CPU stall warnings, but most +of the time the system just freezes. + +Fixes: 89214f009c1d ("ARM: bcm2835: add interrupt controller driver") +Signed-off-by: Lukas Wunner <lukas@wunner.de> +Signed-off-by: Marc Zyngier <maz@kernel.org> +Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> +Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> +Link: https://lore.kernel.org/r/f97868ba4e9b86ddad71f44ec9d8b3b7d8daa1ea.1582618537.git.lukas@wunner.de +--- + drivers/irqchip/irq-bcm2835.c | 21 +++++++++++++++++---- + 1 file changed, 17 insertions(+), 4 deletions(-) + +--- a/drivers/irqchip/irq-bcm2835.c ++++ b/drivers/irqchip/irq-bcm2835.c +@@ -67,8 +67,7 @@ + #define ARM_LOCAL_GPU_INT_ROUTING 0x0c + + #define REG_FIQ_CONTROL 0x0c +-#define REG_FIQ_ENABLE 0x80 +-#define REG_FIQ_DISABLE 0 ++#define FIQ_CONTROL_ENABLE BIT(7) + + #define NR_BANKS 3 + #define IRQS_PER_BANK 32 +@@ -116,7 +115,7 @@ static inline unsigned int hwirq_to_fiq( + static void armctrl_mask_irq(struct irq_data *d) + { + if (d->hwirq >= NUMBER_IRQS) +- writel_relaxed(REG_FIQ_DISABLE, intc.base + REG_FIQ_CONTROL); ++ writel_relaxed(0, intc.base + REG_FIQ_CONTROL); + else + writel_relaxed(HWIRQ_BIT(d->hwirq), + intc.disable[HWIRQ_BANK(d->hwirq)]); +@@ -143,7 +142,7 @@ static void armctrl_unmask_irq(struct ir + ARM_LOCAL_GPU_INT_ROUTING); + } + +- writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq), ++ writel_relaxed(FIQ_CONTROL_ENABLE | hwirq_to_fiq(d->hwirq), + intc.base + REG_FIQ_CONTROL); + } else { + writel_relaxed(HWIRQ_BIT(d->hwirq), +@@ -201,6 +200,7 @@ static int __init armctrl_of_init(struct + { + void __iomem *base; + int irq = 0, last_irq, b, i; ++ u32 reg; + + base = of_iomap(node, 0); + if (!base) +@@ -224,6 +224,19 @@ static int __init armctrl_of_init(struct + handle_level_irq); + irq_set_probe(irq); + } ++ ++ reg = readl_relaxed(intc.enable[b]); ++ if (reg) { ++ writel_relaxed(reg, intc.disable[b]); ++ pr_err(FW_BUG "Bootloader left irq enabled: " ++ "bank %d irq %*pbl\n", b, IRQS_PER_BANK, ®); ++ } ++ } ++ ++ reg = readl_relaxed(base + REG_FIQ_CONTROL); ++ if (reg & FIQ_CONTROL_ENABLE) { ++ writel_relaxed(0, base + REG_FIQ_CONTROL); ++ pr_err(FW_BUG "Bootloader left fiq enabled\n"); + } + + last_irq = irq; diff --git a/target/linux/bcm27xx/patches-5.4/950-0864-dtoverlays-Fixup-imx219-and-imx477-overlays-due-to-p.patch b/target/linux/bcm27xx/patches-5.4/950-0864-dtoverlays-Fixup-imx219-and-imx477-overlays-due-to-p.patch new file mode 100644 index 0000000000..44ecd49f16 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0864-dtoverlays-Fixup-imx219-and-imx477-overlays-due-to-p.patch @@ -0,0 +1,42 @@ +From ae906e8cc5152d171ff4d0bf7e668b941a6b1a06 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Wed, 1 Jul 2020 18:28:10 +0100 +Subject: [PATCH] dtoverlays: Fixup imx219 and imx477 overlays due to + parsing failures + +imx219 overlay failed to detect as CSI2 as it was missing any +of the CSI2 properties on the Unicam end of the configuration. +Clean up imx477 as well to include all the relevant properties. + +Fixes: "dt/dtoverlays: Fix up base DT and overlays for updated Unicam driver" + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/imx219-overlay.dts | 3 +++ + arch/arm/boot/dts/overlays/imx477-overlay.dts | 2 ++ + 2 files changed, 5 insertions(+) + +--- a/arch/arm/boot/dts/overlays/imx219-overlay.dts ++++ b/arch/arm/boot/dts/overlays/imx219-overlay.dts +@@ -49,6 +49,9 @@ + port { + csi1_ep: endpoint { + remote-endpoint = <&imx219_0>; ++ clock-lanes = <0>; ++ data-lanes = <1 2>; ++ clock-noncontinuous; + }; + }; + }; +--- a/arch/arm/boot/dts/overlays/imx477-overlay.dts ++++ b/arch/arm/boot/dts/overlays/imx477-overlay.dts +@@ -49,7 +49,9 @@ + port { + csi1_ep: endpoint { + remote-endpoint = <&imx477_0>; ++ clock-lanes = <0>; + data-lanes = <1 2>; ++ clock-noncontinuous; + }; + }; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0865-overlays-rpi-ft5406-Fix-boolean-parameters.patch b/target/linux/bcm27xx/patches-5.4/950-0865-overlays-rpi-ft5406-Fix-boolean-parameters.patch new file mode 100644 index 0000000000..f1daaf2e66 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0865-overlays-rpi-ft5406-Fix-boolean-parameters.patch @@ -0,0 +1,27 @@ +From e61f4babc548c69b26f60c93eaa4e20d676db8b8 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Sat, 4 Jul 2020 22:19:26 +0100 +Subject: [PATCH] overlays: rpi-ft5406: Fix boolean parameters + +An improvement in the automated testing of overlays revealed +these invalid boolean parameter declarations. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts ++++ b/arch/arm/boot/dts/overlays/rpi-ft5406-overlay.dts +@@ -18,8 +18,8 @@ + __overrides__ { + touchscreen-size-x = <&ts>,"touchscreen-size-x:0"; + touchscreen-size-y = <&ts>,"touchscreen-size-y:0"; +- touchscreen-inverted-x = <&ts>,"touchscreen-inverted-x:?"; +- touchscreen-inverted-y = <&ts>,"touchscreen-inverted-y:?"; +- touchscreen-swapped-x-y = <&ts>,"touchscreen-swapped-x-y:?"; ++ touchscreen-inverted-x = <&ts>,"touchscreen-inverted-x?"; ++ touchscreen-inverted-y = <&ts>,"touchscreen-inverted-y?"; ++ touchscreen-swapped-x-y = <&ts>,"touchscreen-swapped-x-y?"; + }; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0866-ARM-dts-Copy-kernel-BT-changes-to-CM4.patch b/target/linux/bcm27xx/patches-5.4/950-0866-ARM-dts-Copy-kernel-BT-changes-to-CM4.patch new file mode 100644 index 0000000000..0c4158b165 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0866-ARM-dts-Copy-kernel-BT-changes-to-CM4.patch @@ -0,0 +1,29 @@ +From c1037594129cb19e62ea7551b0b4c449a392d883 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 6 Jul 2020 17:53:47 +0100 +Subject: [PATCH] ARM: dts: Copy kernel BT changes to CM4 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts +@@ -194,6 +194,7 @@ + // Downstream rpi- changes + + #include "bcm270x.dtsi" ++#include "bcm271x-rpi-bt.dtsi" + + / { + soc { +@@ -267,8 +268,6 @@ + &uart0 { + pinctrl-0 = <&uart0_pins &bt_pins>; + status = "okay"; +- +- /delete-node/ bluetooth; + }; + + &uart1 { diff --git a/target/linux/bcm27xx/patches-5.4/950-0867-ARM-dts-Make-bcm2711-dts-more-like-5.7.patch b/target/linux/bcm27xx/patches-5.4/950-0867-ARM-dts-Make-bcm2711-dts-more-like-5.7.patch new file mode 100644 index 0000000000..bbe5569e61 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0867-ARM-dts-Make-bcm2711-dts-more-like-5.7.patch @@ -0,0 +1,696 @@ +From 0f02c32b2d27fa5f0b21c67fb5518a36b5234f3a Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Tue, 7 Jul 2020 09:01:54 +0100 +Subject: [PATCH] ARM: dts: Make bcm2711 dts more like 5.7 + +The multiple declarations of pixelvalve2 were causing problems for the +DT checkers. Aligning the dts files closer to the later kernel versions +avoids some repetition and should make maintenance easier. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 142 ++++++++++++----------- + arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 69 +---------- + arch/arm/boot/dts/bcm2711-rpi.dtsi | 150 +++++++++++++++++++++++- + arch/arm/boot/dts/bcm2711.dtsi | 157 +++----------------------- + 4 files changed, 245 insertions(+), 273 deletions(-) + +--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts +@@ -19,7 +19,9 @@ + }; + + aliases { ++ emmc2bus = &emmc2bus; + ethernet0 = &genet; ++ pcie0 = &pcie0; + }; + + leds { +@@ -30,6 +32,8 @@ + pwr { + label = "PWR"; + gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; ++ default-state = "keep"; ++ linux,default-trigger = "default-on"; + }; + }; + +@@ -70,6 +74,79 @@ + }; + }; + ++&gpio { ++ /* ++ * Parts taken from rpi_SCH_4b_4p0_reduced.pdf and ++ * the official GPU firmware DT blob. ++ * ++ * Legend: ++ * "FOO" = GPIO line named "FOO" on the schematic ++ * "FOO_N" = GPIO line named "FOO" on schematic, active low ++ */ ++ gpio-line-names = "ID_SDA", ++ "ID_SCL", ++ "SDA1", ++ "SCL1", ++ "GPIO_GCLK", ++ "GPIO5", ++ "GPIO6", ++ "SPI_CE1_N", ++ "SPI_CE0_N", ++ "SPI_MISO", ++ "SPI_MOSI", ++ "SPI_SCLK", ++ "GPIO12", ++ "GPIO13", ++ /* Serial port */ ++ "TXD1", ++ "RXD1", ++ "GPIO16", ++ "GPIO17", ++ "GPIO18", ++ "GPIO19", ++ "GPIO20", ++ "GPIO21", ++ "GPIO22", ++ "GPIO23", ++ "GPIO24", ++ "GPIO25", ++ "GPIO26", ++ "GPIO27", ++ "RGMII_MDIO", ++ "RGMIO_MDC", ++ /* Used by BT module */ ++ "CTS0", ++ "RTS0", ++ "TXD0", ++ "RXD0", ++ /* Used by Wifi */ ++ "SD1_CLK", ++ "SD1_CMD", ++ "SD1_DATA0", ++ "SD1_DATA1", ++ "SD1_DATA2", ++ "SD1_DATA3", ++ /* Shared with SPI flash */ ++ "PWM0_MISO", ++ "PWM1_MOSI", ++ "STATUS_LED_G_CLK", ++ "SPIFLASH_CE_N", ++ "SDA0", ++ "SCL0", ++ "RGMII_RXCLK", ++ "RGMII_RXCTL", ++ "RGMII_RXD0", ++ "RGMII_RXD1", ++ "RGMII_RXD2", ++ "RGMII_RXD3", ++ "RGMII_TXCLK", ++ "RGMII_TXCTL", ++ "RGMII_TXD0", ++ "RGMII_TXD1", ++ "RGMII_TXD2", ++ "RGMII_TXD3"; ++}; ++ + &pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pwm1_0_gpio40 &pwm1_1_gpio41>; +@@ -138,46 +215,6 @@ + interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; + }; + +-&vc4 { +- status = "okay"; +-}; +- +-&pixelvalve0 { +- status = "okay"; +-}; +- +-&pixelvalve1 { +- status = "okay"; +-}; +- +-&pixelvalve2 { +- status = "okay"; +-}; +- +-&pixelvalve3 { +- status = "okay"; +-}; +- +-&pixelvalve4 { +- status = "okay"; +-}; +- +-&hdmi0 { +- status = "okay"; +-}; +- +-&ddc0 { +- status = "okay"; +-}; +- +-&hdmi1 { +- status = "okay"; +-}; +- +-&ddc1 { +- status = "okay"; +-}; +- + // ============================================= + // Downstream rpi- changes + +@@ -195,8 +232,6 @@ + #include "bcm283x-rpi-csi1-2lane.dtsi" + #include "bcm283x-rpi-i2c0mux_0_44.dtsi" + +-/delete-node/ &emmc2; +- + / { + chosen { + bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1"; +@@ -213,29 +248,7 @@ + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; +- /delete-property/ ethernet; + /delete-property/ intc; +- pcie0 = &pcie0; +- emmc2bus = &emmc2bus; +- }; +- +- emmc2bus: emmc2bus { +- compatible = "simple-bus"; +- #address-cells = <2>; +- #size-cells = <1>; +- +- ranges = <0x0 0x7e000000 0x0 0xfe000000 0x01800000>; +- dma-ranges = <0x0 0xc0000000 0x0 0x00000000 0x40000000>; +- +- emmc2: emmc2@7e340000 { +- compatible = "brcm,bcm2711-emmc2"; +- status = "okay"; +- interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; +- clocks = <&clocks BCM2711_CLOCK_EMMC2>; +- reg = <0x0 0x7e340000 0x100>; +- vqmmc-supply = <&sd_io_1v8_reg>; +- broken-cd; +- }; + }; + + /delete-node/ wifi-pwrseq; +@@ -557,6 +570,7 @@ + eth_led0 = <&phy1>,"led-modes:0"; + eth_led1 = <&phy1>,"led-modes:4"; + ++ sd_poll_once = <&emmc2>, "non-removable?"; + spi_dma4 = <&spi0>, "dmas:0=", <&dma40>, + <&spi0>, "dmas:8=", <&dma40>; + }; +--- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts +@@ -19,7 +19,9 @@ + }; + + aliases { ++ emmc2bus = &emmc2bus; + ethernet0 = &genet; ++ pcie0 = &pcie0; + }; + + leds { +@@ -30,6 +32,8 @@ + pwr { + label = "PWR"; + gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; ++ default-state = "keep"; ++ linux,default-trigger = "default-on"; + }; + }; + +@@ -150,46 +154,6 @@ + interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; + }; + +-&vc4 { +- status = "okay"; +-}; +- +-&pixelvalve0 { +- status = "okay"; +-}; +- +-&pixelvalve1 { +- status = "okay"; +-}; +- +-&pixelvalve2 { +- status = "okay"; +-}; +- +-&pixelvalve3 { +- status = "okay"; +-}; +- +-&pixelvalve4 { +- status = "okay"; +-}; +- +-&hdmi0 { +- status = "okay"; +-}; +- +-&ddc0 { +- status = "okay"; +-}; +- +-&hdmi1 { +- status = "okay"; +-}; +- +-&ddc1 { +- status = "okay"; +-}; +- + // ============================================= + // Downstream rpi- changes + +@@ -208,8 +172,6 @@ + #include "bcm283x-rpi-csi1-4lane.dtsi" + #include "bcm283x-rpi-i2c0mux_0_44.dtsi" + +-/delete-node/ &emmc2; +- + / { + chosen { + bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1"; +@@ -226,29 +188,7 @@ + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; +- /delete-property/ ethernet; + /delete-property/ intc; +- pcie0 = &pcie0; +- emmc2bus = &emmc2bus; +- }; +- +- emmc2bus: emmc2bus { +- compatible = "simple-bus"; +- #address-cells = <2>; +- #size-cells = <1>; +- +- ranges = <0x0 0x7e000000 0x0 0xfe000000 0x01800000>; +- dma-ranges = <0x0 0xc0000000 0x0 0x00000000 0x40000000>; +- +- emmc2: emmc2@7e340000 { +- compatible = "brcm,bcm2711-emmc2"; +- status = "okay"; +- interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; +- clocks = <&clocks BCM2711_CLOCK_EMMC2>; +- reg = <0x0 0x7e340000 0x100>; +- vqmmc-supply = <&sd_io_1v8_reg>; +- broken-cd; +- }; + }; + + /delete-node/ wifi-pwrseq; +@@ -588,6 +528,7 @@ + <&ant2>, "output-high?=off", + <&ant2>, "output-low?=on"; + ++ sd_poll_once = <&emmc2>, "non-removable?"; + spi_dma4 = <&spi0>, "dmas:0=", <&dma40>, + <&spi0>, "dmas:8=", <&dma40>; + }; +--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi +@@ -4,6 +4,129 @@ + / { + soc { + /delete-node/ v3d@7ec00000; ++ ++ pixelvalve0: pixelvalve@7e206000 { ++ compatible = "brcm,bcm2711-pixelvalve0"; ++ reg = <0x7e206000 0x100>; ++ interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>; ++ status = "disabled"; ++ }; ++ ++ pixelvalve1: pixelvalve@7e207000 { ++ compatible = "brcm,bcm2711-pixelvalve1"; ++ reg = <0x7e207000 0x100>; ++ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; ++ status = "disabled"; ++ }; ++ ++ pixelvalve2: pixelvalve@7e20a000 { ++ compatible = "brcm,bcm2711-pixelvalve2"; ++ reg = <0x7e20a000 0x100>; ++ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; ++ status = "disabled"; ++ }; ++ ++ pixelvalve4: pixelvalve@7e216000 { ++ compatible = "brcm,bcm2711-pixelvalve4"; ++ reg = <0x7e216000 0x100>; ++ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; ++ status = "disabled"; ++ }; ++ ++ pixelvalve3: pixelvalve@7ec12000 { ++ compatible = "brcm,bcm2711-pixelvalve3"; ++ reg = <0x7ec12000 0x100>; ++ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; ++ status = "disabled"; ++ }; ++ ++ dvp: clock@7ef00000 { ++ compatible = "brcm,brcm2711-dvp"; ++ reg = <0x7ef00000 0x10>; ++ clocks = <&clk_108MHz>; ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++ }; ++ ++ hdmi0: hdmi@7ef00700 { ++ compatible = "brcm,bcm2711-hdmi0"; ++ reg = <0x7ef00700 0x300>, ++ <0x7ef00300 0x200>, ++ <0x7ef00f00 0x80>, ++ <0x7ef00f80 0x80>, ++ <0x7ef01b00 0x200>, ++ <0x7ef01f00 0x400>, ++ <0x7ef00200 0x80>, ++ <0x7ef04300 0x100>, ++ <0x7ef20000 0x100>, ++ <0x7ef00100 0x30>; ++ reg-names = "hdmi", ++ "dvp", ++ "phy", ++ "rm", ++ "packet", ++ "metadata", ++ "csc", ++ "cec", ++ "hd", ++ "intr2"; ++ clocks = <&firmware_clocks 13>; ++ clock-names = "hdmi"; ++ resets = <&dvp 0>; ++ ddc = <&ddc0>; ++ dmas = <&dma 10>; ++ dma-names = "audio-rx"; ++ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ddc0: i2c@7ef04500 { ++ compatible = "brcm,bcm2711-hdmi-i2c"; ++ reg = <0x7ef04500 0x100>, <0x7ef00b00 0x300>; ++ reg-names = "bsc", "auto-i2c"; ++ clock-frequency = <97500>; ++ status = "disabled"; ++ }; ++ ++ hdmi1: hdmi@7ef05700 { ++ compatible = "brcm,bcm2711-hdmi1"; ++ reg = <0x7ef05700 0x300>, ++ <0x7ef05300 0x200>, ++ <0x7ef05f00 0x80>, ++ <0x7ef05f80 0x80>, ++ <0x7ef06b00 0x200>, ++ <0x7ef06f00 0x400>, ++ <0x7ef00280 0x80>, ++ <0x7ef09300 0x100>, ++ <0x7ef20000 0x100>, ++ <0x7ef00100 0x30>; ++ reg-names = "hdmi", ++ "dvp", ++ "phy", ++ "rm", ++ "packet", ++ "metadata", ++ "csc", ++ "cec", ++ "hd", ++ "intr2"; ++ ddc = <&ddc1>; ++ clocks = <&firmware_clocks 13>; ++ clock-names = "hdmi"; ++ resets = <&dvp 1>; ++ dmas = <&dma 17>; ++ dma-names = "audio-rx"; ++ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ddc1: i2c@7ef09500 { ++ compatible = "brcm,bcm2711-hdmi-i2c"; ++ reg = <0x7ef09500 0x100>, <0x7ef05b00 0x300>; ++ reg-names = "bsc", "auto-i2c"; ++ clock-frequency = <97500>; ++ status = "disabled"; ++ }; + }; + + __overrides__ { +@@ -42,22 +165,33 @@ + scb: scb { + /* Add a label */ + }; +-}; + +-&cma { +- /* Limit cma to the lower 768MB to allow room for HIGHMEM on 32-bit */ +- alloc-ranges = <0x0 0x00000000 0x30000000>; ++ vc4: gpu { ++ compatible = "brcm,bcm2711-vc5"; ++ status = "disabled"; ++ }; ++ ++ clk_108MHz: clk-108M { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <108000000>; ++ clock-output-names = "108MHz-clock"; ++ }; + }; + + &soc { + /delete-node/ audio; + }; + ++&cma { ++ /* Limit cma to the lower 768MB to allow room for HIGHMEM on 32-bit */ ++ alloc-ranges = <0x0 0x00000000 0x30000000>; ++}; ++ + &scb { + ranges = <0x0 0x7c000000 0x0 0xfc000000 0x0 0x03800000>, + <0x0 0x40000000 0x0 0xff800000 0x0 0x00800000>, +- <0x6 0x00000000 0x6 0x00000000 0x0 0x40000000>, +- <0x0 0x00000000 0x0 0x00000000 0x0 0xfc000000>; ++ <0x6 0x00000000 0x6 0x00000000 0x0 0x40000000>; + dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0xfc000000>, + <0x1 0x00000000 0x1 0x00000000 0x1 0x00000000>; + +@@ -171,6 +305,10 @@ + compatible = "brcm,bcm2711-genet-v5", "brcm,genet-v5"; + }; + ++&hvs { ++ clocks = <&firmware_clocks 4>; ++}; ++ + &firmware { + firmware_clocks: clocks { + compatible = "raspberrypi,firmware-clocks"; +--- a/arch/arm/boot/dts/bcm2711.dtsi ++++ b/arch/arm/boot/dts/bcm2711.dtsi +@@ -12,18 +12,6 @@ + + interrupt-parent = <&gicv2>; + +- vc4: gpu { +- compatible = "brcm,bcm2711-vc5"; +- status = "disabled"; +- }; +- +- clk_108MHz: clk-108M { +- #clock-cells = <0>; +- compatible = "fixed-clock"; +- clock-frequency = <108000000>; +- clock-output-names = "108MHz-clock"; +- }; +- + soc { + /* + * Defined ranges: +@@ -245,27 +233,6 @@ + status = "disabled"; + }; + +- pixelvalve0: pixelvalve@7e206000 { +- compatible = "brcm,bcm2711-pixelvalve0"; +- reg = <0x7e206000 0x100>; +- interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>; +- status = "disabled"; +- }; +- +- pixelvalve1: pixelvalve@7e207000 { +- compatible = "brcm,bcm2711-pixelvalve1"; +- reg = <0x7e207000 0x100>; +- interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; +- status = "disabled"; +- }; +- +- pixelvalve2: pixelvalve@7e20a000 { +- compatible = "brcm,bcm2711-pixelvalve2"; +- reg = <0x7e20a000 0x100>; +- interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; +- status = "disabled"; +- }; +- + pwm1: pwm@7e20c800 { + compatible = "brcm,bcm2835-pwm"; + reg = <0x7e20c800 0x28>; +@@ -276,118 +243,30 @@ + status = "disabled"; + }; + +- pixelvalve4: pixelvalve@7e216000 { +- compatible = "brcm,bcm2711-pixelvalve4"; +- reg = <0x7e216000 0x100>; +- interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; +- status = "disabled"; +- }; +- +- emmc2: emmc2@7e340000 { +- compatible = "brcm,bcm2711-emmc2"; +- reg = <0x7e340000 0x100>; +- interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; +- clocks = <&clocks BCM2711_CLOCK_EMMC2>; +- status = "disabled"; +- }; +- + hvs@7e400000 { +- clocks = <&firmware_clocks 4>; + interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; + }; ++ }; + +- pixelvalve3: pixelvalve@7ec12000 { +- compatible = "brcm,bcm2711-pixelvalve3"; +- reg = <0x7ec12000 0x100>; +- interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; +- status = "disabled"; +- }; ++ /* ++ * emmc2 has different DMA constraints based on SoC revisions. It was ++ * moved into its own bus, so as for RPi4's firmware to update them. ++ * The firmware will find whether the emmc2bus alias is defined, and if ++ * so, it'll edit the dma-ranges property below accordingly. ++ */ ++ emmc2bus: emmc2bus { ++ compatible = "simple-bus"; ++ #address-cells = <2>; ++ #size-cells = <1>; + +- dvp: clock@7ef00000 { +- compatible = "brcm,brcm2711-dvp"; +- reg = <0x7ef00000 0x10>; +- clocks = <&clk_108MHz>; +- #clock-cells = <1>; +- #reset-cells = <1>; +- }; ++ ranges = <0x0 0x7e000000 0x0 0xfe000000 0x01800000>; ++ dma-ranges = <0x0 0xc0000000 0x0 0x00000000 0x40000000>; + +- hdmi0: hdmi@7ef00700 { +- compatible = "brcm,bcm2711-hdmi0"; +- reg = <0x7ef00700 0x300>, +- <0x7ef00300 0x200>, +- <0x7ef00f00 0x80>, +- <0x7ef00f80 0x80>, +- <0x7ef01b00 0x200>, +- <0x7ef01f00 0x400>, +- <0x7ef00200 0x80>, +- <0x7ef04300 0x100>, +- <0x7ef20000 0x100>, +- <0x7ef00100 0x30>; +- reg-names = "hdmi", +- "dvp", +- "phy", +- "rm", +- "packet", +- "metadata", +- "csc", +- "cec", +- "hd", +- "intr2"; +- clocks = <&firmware_clocks 13>; +- clock-names = "hdmi"; +- resets = <&dvp 0>; +- ddc = <&ddc0>; +- dmas = <&dma 10>; +- dma-names = "audio-rx"; +- interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; +- status = "disabled"; +- }; +- +- ddc0: i2c@7ef04500 { +- compatible = "brcm,bcm2711-hdmi-i2c"; +- reg = <0x7ef04500 0x100>, <0x7ef00b00 0x300>; +- reg-names = "bsc", "auto-i2c"; +- clock-frequency = <97500>; +- status = "disabled"; +- }; +- +- hdmi1: hdmi@7ef05700 { +- compatible = "brcm,bcm2711-hdmi1"; +- reg = <0x7ef05700 0x300>, +- <0x7ef05300 0x200>, +- <0x7ef05f00 0x80>, +- <0x7ef05f80 0x80>, +- <0x7ef06b00 0x200>, +- <0x7ef06f00 0x400>, +- <0x7ef00280 0x80>, +- <0x7ef09300 0x100>, +- <0x7ef20000 0x100>, +- <0x7ef00100 0x30>; +- reg-names = "hdmi", +- "dvp", +- "phy", +- "rm", +- "packet", +- "metadata", +- "csc", +- "cec", +- "hd", +- "intr2"; +- ddc = <&ddc1>; +- clocks = <&firmware_clocks 13>; +- clock-names = "hdmi"; +- resets = <&dvp 1>; +- dmas = <&dma 17>; +- dma-names = "audio-rx"; +- interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; +- status = "disabled"; +- }; +- +- ddc1: i2c@7ef09500 { +- compatible = "brcm,bcm2711-hdmi-i2c"; +- reg = <0x7ef09500 0x100>, <0x7ef05b00 0x300>; +- reg-names = "bsc", "auto-i2c"; +- clock-frequency = <97500>; ++ emmc2: emmc2@7e340000 { ++ compatible = "brcm,bcm2711-emmc2"; ++ reg = <0x0 0x7e340000 0x100>; ++ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&clocks BCM2711_CLOCK_EMMC2>; + status = "disabled"; + }; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0868-bcm2835-dma-Add-NO_WAIT_RESP-flag.patch b/target/linux/bcm27xx/patches-5.4/950-0868-bcm2835-dma-Add-NO_WAIT_RESP-flag.patch new file mode 100644 index 0000000000..8fc7069e61 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0868-bcm2835-dma-Add-NO_WAIT_RESP-flag.patch @@ -0,0 +1,54 @@ +From 8c070947d0d9ef7f890eeff329d4deb1c393ef87 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Wed, 1 Jul 2020 20:28:27 +0100 +Subject: [PATCH] bcm2835-dma: Add NO_WAIT_RESP flag + +Use bit 27 of the dreq value (the second cell of the DT DMA descriptor) +to request that the WAIT_RESP bit is not set. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/dma/bcm2835-dma.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/drivers/dma/bcm2835-dma.c ++++ b/drivers/dma/bcm2835-dma.c +@@ -167,6 +167,11 @@ struct bcm2835_desc { + #define BCM2835_DMA_WAIT(x) ((x & 31) << 21) /* add DMA-wait cycles */ + #define BCM2835_DMA_NO_WIDE_BURSTS BIT(26) /* no 2 beat write bursts */ + ++/* A fake bit to request that the driver doesn't set the WAIT_RESP bit. */ ++#define BCM2835_DMA_NO_WAIT_RESP BIT(27) ++#define WAIT_RESP(x) ((x & BCM2835_DMA_NO_WAIT_RESP) ? \ ++ 0 : BCM2835_DMA_WAIT_RESP) ++ + /* debug register bits */ + #define BCM2835_DMA_DEBUG_LAST_NOT_SET_ERR BIT(0) + #define BCM2835_DMA_DEBUG_FIFO_ERR BIT(1) +@@ -845,7 +850,7 @@ static struct dma_async_tx_descriptor *b + struct bcm2835_chan *c = to_bcm2835_dma_chan(chan); + struct bcm2835_desc *d; + u32 info = BCM2835_DMA_D_INC | BCM2835_DMA_S_INC; +- u32 extra = BCM2835_DMA_INT_EN | BCM2835_DMA_WAIT_RESP; ++ u32 extra = BCM2835_DMA_INT_EN | WAIT_RESP(c->dreq); + size_t max_len = bcm2835_dma_max_frame_length(c); + size_t frames; + +@@ -875,7 +880,7 @@ static struct dma_async_tx_descriptor *b + struct bcm2835_chan *c = to_bcm2835_dma_chan(chan); + struct bcm2835_desc *d; + dma_addr_t src = 0, dst = 0; +- u32 info = BCM2835_DMA_WAIT_RESP; ++ u32 info = WAIT_RESP(c->dreq); + u32 extra = BCM2835_DMA_INT_EN; + size_t frames; + +@@ -937,7 +942,7 @@ static struct dma_async_tx_descriptor *b + struct bcm2835_chan *c = to_bcm2835_dma_chan(chan); + struct bcm2835_desc *d; + dma_addr_t src, dst; +- u32 info = BCM2835_DMA_WAIT_RESP; ++ u32 info = WAIT_RESP(c->dreq); + u32 extra = 0; + size_t max_len = bcm2835_dma_max_frame_length(c); + size_t frames; diff --git a/target/linux/bcm27xx/patches-5.4/950-0869-ARM-dts-Restore-the-old-2711-scb-ranges-property.patch b/target/linux/bcm27xx/patches-5.4/950-0869-ARM-dts-Restore-the-old-2711-scb-ranges-property.patch new file mode 100644 index 0000000000..614b149f34 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0869-ARM-dts-Restore-the-old-2711-scb-ranges-property.patch @@ -0,0 +1,24 @@ +From f2233a2a1baf7036469e5291b06457311120dfb4 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Tue, 7 Jul 2020 14:08:55 +0100 +Subject: [PATCH] ARM: dts: Restore the old 2711 scb ranges property + +The back-ported value breaks PCIe. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2711-rpi.dtsi | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi +@@ -191,7 +191,8 @@ + &scb { + ranges = <0x0 0x7c000000 0x0 0xfc000000 0x0 0x03800000>, + <0x0 0x40000000 0x0 0xff800000 0x0 0x00800000>, +- <0x6 0x00000000 0x6 0x00000000 0x0 0x40000000>; ++ <0x6 0x00000000 0x6 0x00000000 0x0 0x40000000>, ++ <0x0 0x00000000 0x0 0x00000000 0x0 0xfc000000>; + dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0xfc000000>, + <0x1 0x00000000 0x1 0x00000000 0x1 0x00000000>; + diff --git a/target/linux/bcm27xx/patches-5.4/950-0870-media-i2c-add-ov9281-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0870-media-i2c-add-ov9281-driver.patch new file mode 100644 index 0000000000..c48a146591 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0870-media-i2c-add-ov9281-driver.patch @@ -0,0 +1,1218 @@ +From ca6aba3a4bf358b763d0e508df95455de3ae992c Mon Sep 17 00:00:00 2001 +From: Zefa Chen <zefa.chen@rock-chips.com> +Date: Fri, 17 May 2019 18:23:03 +0800 +Subject: [PATCH] media: i2c: add ov9281 driver. + +Change-Id: I7b77250bbc56d2f861450cf77271ad15f9b88ab1 +Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com> +--- + drivers/media/i2c/Kconfig | 11 + + drivers/media/i2c/Makefile | 1 + + drivers/media/i2c/ov9281.c | 1171 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 1183 insertions(+) + create mode 100644 drivers/media/i2c/ov9281.c + +--- a/drivers/media/i2c/Kconfig ++++ b/drivers/media/i2c/Kconfig +@@ -855,6 +855,17 @@ config VIDEO_OV9640 + This is a Video4Linux2 sensor driver for the OmniVision + OV9640 camera sensor. + ++config VIDEO_OV9281 ++ tristate "OmniVision OV9281 sensor support" ++ depends on I2C && VIDEO_V4L2 ++ depends on MEDIA_CAMERA_SUPPORT ++ help ++ This is a Video4Linux2 sensor-level driver for the OmniVision ++ OV9281 camera. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called ov9281. ++ + config VIDEO_OV9650 + tristate "OmniVision OV9650/OV9652 sensor support" + depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API +--- a/drivers/media/i2c/Makefile ++++ b/drivers/media/i2c/Makefile +@@ -79,6 +79,7 @@ obj-$(CONFIG_VIDEO_OV7670) += ov7670.o + obj-$(CONFIG_VIDEO_OV772X) += ov772x.o + obj-$(CONFIG_VIDEO_OV7740) += ov7740.o + obj-$(CONFIG_VIDEO_OV8856) += ov8856.o ++obj-$(CONFIG_VIDEO_OV9281) += ov9281.o + obj-$(CONFIG_VIDEO_OV9640) += ov9640.o + obj-$(CONFIG_VIDEO_OV9650) += ov9650.o + obj-$(CONFIG_VIDEO_OV13858) += ov13858.o +--- /dev/null ++++ b/drivers/media/i2c/ov9281.c +@@ -0,0 +1,1171 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * ov9281 driver ++ * ++ * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd. ++ */ ++ ++#include <linux/clk.h> ++#include <linux/device.h> ++#include <linux/delay.h> ++#include <linux/gpio/consumer.h> ++#include <linux/i2c.h> ++#include <linux/module.h> ++#include <linux/pm_runtime.h> ++#include <linux/regulator/consumer.h> ++#include <linux/sysfs.h> ++#include <linux/slab.h> ++#include <linux/rk-camera-module.h> ++#include <media/media-entity.h> ++#include <media/v4l2-async.h> ++#include <media/v4l2-ctrls.h> ++#include <media/v4l2-subdev.h> ++#include <linux/pinctrl/consumer.h> ++ ++#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x0) ++ ++#ifndef V4L2_CID_DIGITAL_GAIN ++#define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN ++#endif ++ ++#define OV9281_LINK_FREQ_400MHZ 400000000 ++/* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */ ++#define OV9281_PIXEL_RATE (OV9281_LINK_FREQ_400MHZ * 2 * 2 / 10) ++#define OV9281_XVCLK_FREQ 24000000 ++ ++#define CHIP_ID 0x9281 ++#define OV9281_REG_CHIP_ID 0x300a ++ ++#define OV9281_REG_CTRL_MODE 0x0100 ++#define OV9281_MODE_SW_STANDBY 0x0 ++#define OV9281_MODE_STREAMING BIT(0) ++ ++#define OV9281_REG_EXPOSURE 0x3500 ++#define OV9281_EXPOSURE_MIN 4 ++#define OV9281_EXPOSURE_STEP 1 ++#define OV9281_VTS_MAX 0x7fff ++ ++#define OV9281_REG_GAIN_H 0x3508 ++#define OV9281_REG_GAIN_L 0x3509 ++#define OV9281_GAIN_H_MASK 0x07 ++#define OV9281_GAIN_H_SHIFT 8 ++#define OV9281_GAIN_L_MASK 0xff ++#define OV9281_GAIN_MIN 0x10 ++#define OV9281_GAIN_MAX 0xf8 ++#define OV9281_GAIN_STEP 1 ++#define OV9281_GAIN_DEFAULT 0x10 ++ ++#define OV9281_REG_TEST_PATTERN 0x5e00 ++#define OV9281_TEST_PATTERN_ENABLE 0x80 ++#define OV9281_TEST_PATTERN_DISABLE 0x0 ++ ++#define OV9281_REG_VTS 0x380e ++ ++#define REG_NULL 0xFFFF ++ ++#define OV9281_REG_VALUE_08BIT 1 ++#define OV9281_REG_VALUE_16BIT 2 ++#define OV9281_REG_VALUE_24BIT 3 ++ ++#define OV9281_LANES 2 ++#define OV9281_BITS_PER_SAMPLE 10 ++ ++#define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default" ++#define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep" ++ ++#define OV9281_NAME "ov9281" ++ ++static const char * const ov9281_supply_names[] = { ++ "avdd", /* Analog power */ ++ "dovdd", /* Digital I/O power */ ++ "dvdd", /* Digital core power */ ++}; ++ ++#define OV9281_NUM_SUPPLIES ARRAY_SIZE(ov9281_supply_names) ++ ++struct regval { ++ u16 addr; ++ u8 val; ++}; ++ ++struct ov9281_mode { ++ u32 width; ++ u32 height; ++ u32 max_fps; ++ u32 hts_def; ++ u32 vts_def; ++ u32 exp_def; ++ const struct regval *reg_list; ++}; ++ ++struct ov9281 { ++ struct i2c_client *client; ++ struct clk *xvclk; ++ struct gpio_desc *reset_gpio; ++ struct gpio_desc *pwdn_gpio; ++ struct regulator_bulk_data supplies[OV9281_NUM_SUPPLIES]; ++ ++ struct pinctrl *pinctrl; ++ struct pinctrl_state *pins_default; ++ struct pinctrl_state *pins_sleep; ++ ++ struct v4l2_subdev subdev; ++ struct media_pad pad; ++ struct v4l2_ctrl_handler ctrl_handler; ++ struct v4l2_ctrl *exposure; ++ struct v4l2_ctrl *anal_gain; ++ struct v4l2_ctrl *digi_gain; ++ struct v4l2_ctrl *hblank; ++ struct v4l2_ctrl *vblank; ++ struct v4l2_ctrl *test_pattern; ++ struct mutex mutex; ++ bool streaming; ++ bool power_on; ++ const struct ov9281_mode *cur_mode; ++ u32 module_index; ++ const char *module_facing; ++ const char *module_name; ++ const char *len_name; ++}; ++ ++#define to_ov9281(sd) container_of(sd, struct ov9281, subdev) ++ ++/* ++ * Xclk 24Mhz ++ */ ++static const struct regval ov9281_global_regs[] = { ++ {REG_NULL, 0x00}, ++}; ++ ++/* ++ * Xclk 24Mhz ++ * max_framerate 120fps ++ * mipi_datarate per lane 800Mbps ++ */ ++static const struct regval ov9281_1280x800_regs[] = { ++ {0x0103, 0x01}, ++ {0x0302, 0x32}, ++ {0x030d, 0x50}, ++ {0x030e, 0x02}, ++ {0x3001, 0x00}, ++ {0x3004, 0x00}, ++ {0x3005, 0x00}, ++ {0x3006, 0x04}, ++ {0x3011, 0x0a}, ++ {0x3013, 0x18}, ++ {0x3022, 0x01}, ++ {0x3023, 0x00}, ++ {0x302c, 0x00}, ++ {0x302f, 0x00}, ++ {0x3030, 0x04}, ++ {0x3039, 0x32}, ++ {0x303a, 0x00}, ++ {0x303f, 0x01}, ++ {0x3500, 0x00}, ++ {0x3501, 0x2a}, ++ {0x3502, 0x90}, ++ {0x3503, 0x08}, ++ {0x3505, 0x8c}, ++ {0x3507, 0x03}, ++ {0x3508, 0x00}, ++ {0x3509, 0x10}, ++ {0x3610, 0x80}, ++ {0x3611, 0xa0}, ++ {0x3620, 0x6f}, ++ {0x3632, 0x56}, ++ {0x3633, 0x78}, ++ {0x3662, 0x05}, ++ {0x3666, 0x00}, ++ {0x366f, 0x5a}, ++ {0x3680, 0x84}, ++ {0x3712, 0x80}, ++ {0x372d, 0x22}, ++ {0x3731, 0x80}, ++ {0x3732, 0x30}, ++ {0x3778, 0x00}, ++ {0x377d, 0x22}, ++ {0x3788, 0x02}, ++ {0x3789, 0xa4}, ++ {0x378a, 0x00}, ++ {0x378b, 0x4a}, ++ {0x3799, 0x20}, ++ {0x3800, 0x00}, ++ {0x3801, 0x00}, ++ {0x3802, 0x00}, ++ {0x3803, 0x00}, ++ {0x3804, 0x05}, ++ {0x3805, 0x0f}, ++ {0x3806, 0x03}, ++ {0x3807, 0x2f}, ++ {0x3808, 0x05}, ++ {0x3809, 0x00}, ++ {0x380a, 0x03}, ++ {0x380b, 0x20}, ++ {0x380c, 0x02}, ++ {0x380d, 0xd8}, ++ {0x380e, 0x03}, ++ {0x380f, 0x8e}, ++ {0x3810, 0x00}, ++ {0x3811, 0x08}, ++ {0x3812, 0x00}, ++ {0x3813, 0x08}, ++ {0x3814, 0x11}, ++ {0x3815, 0x11}, ++ {0x3820, 0x40}, ++ {0x3821, 0x00}, ++ {0x3881, 0x42}, ++ {0x38b1, 0x00}, ++ {0x3920, 0xff}, ++ {0x4003, 0x40}, ++ {0x4008, 0x04}, ++ {0x4009, 0x0b}, ++ {0x400c, 0x00}, ++ {0x400d, 0x07}, ++ {0x4010, 0x40}, ++ {0x4043, 0x40}, ++ {0x4307, 0x30}, ++ {0x4317, 0x00}, ++ {0x4501, 0x00}, ++ {0x4507, 0x00}, ++ {0x4509, 0x00}, ++ {0x450a, 0x08}, ++ {0x4601, 0x04}, ++ {0x470f, 0x00}, ++ {0x4f07, 0x00}, ++ {0x4800, 0x00}, ++ {0x5000, 0x9f}, ++ {0x5001, 0x00}, ++ {0x5e00, 0x00}, ++ {0x5d00, 0x07}, ++ {0x5d01, 0x00}, ++ {REG_NULL, 0x00}, ++}; ++ ++static const struct ov9281_mode supported_modes[] = { ++ { ++ .width = 1280, ++ .height = 800, ++ .max_fps = 120, ++ .exp_def = 0x0320, ++ .hts_def = 0x0b60,//0x2d8*4 ++ .vts_def = 0x038e, ++ .reg_list = ov9281_1280x800_regs, ++ }, ++}; ++ ++static const s64 link_freq_menu_items[] = { ++ OV9281_LINK_FREQ_400MHZ ++}; ++ ++static const char * const ov9281_test_pattern_menu[] = { ++ "Disabled", ++ "Vertical Color Bar Type 1", ++ "Vertical Color Bar Type 2", ++ "Vertical Color Bar Type 3", ++ "Vertical Color Bar Type 4" ++}; ++ ++/* Write registers up to 4 at a time */ ++static int ov9281_write_reg(struct i2c_client *client, u16 reg, ++ u32 len, u32 val) ++{ ++ u32 buf_i, val_i; ++ u8 buf[6]; ++ u8 *val_p; ++ __be32 val_be; ++ ++ if (len > 4) ++ return -EINVAL; ++ ++ buf[0] = reg >> 8; ++ buf[1] = reg & 0xff; ++ ++ val_be = cpu_to_be32(val); ++ val_p = (u8 *)&val_be; ++ buf_i = 2; ++ val_i = 4 - len; ++ ++ while (val_i < 4) ++ buf[buf_i++] = val_p[val_i++]; ++ ++ if (i2c_master_send(client, buf, len + 2) != len + 2) ++ return -EIO; ++ ++ return 0; ++} ++ ++static int ov9281_write_array(struct i2c_client *client, ++ const struct regval *regs) ++{ ++ u32 i; ++ int ret = 0; ++ ++ for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) ++ ret = ov9281_write_reg(client, regs[i].addr, ++ OV9281_REG_VALUE_08BIT, regs[i].val); ++ ++ return ret; ++} ++ ++/* Read registers up to 4 at a time */ ++static int ov9281_read_reg(struct i2c_client *client, u16 reg, unsigned int len, ++ u32 *val) ++{ ++ struct i2c_msg msgs[2]; ++ u8 *data_be_p; ++ __be32 data_be = 0; ++ __be16 reg_addr_be = cpu_to_be16(reg); ++ int ret; ++ ++ if (len > 4 || !len) ++ return -EINVAL; ++ ++ data_be_p = (u8 *)&data_be; ++ /* Write register address */ ++ msgs[0].addr = client->addr; ++ msgs[0].flags = 0; ++ msgs[0].len = 2; ++ msgs[0].buf = (u8 *)®_addr_be; ++ ++ /* Read data from register */ ++ msgs[1].addr = client->addr; ++ msgs[1].flags = I2C_M_RD; ++ msgs[1].len = len; ++ msgs[1].buf = &data_be_p[4 - len]; ++ ++ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); ++ if (ret != ARRAY_SIZE(msgs)) ++ return -EIO; ++ ++ *val = be32_to_cpu(data_be); ++ ++ return 0; ++} ++ ++static int ov9281_get_reso_dist(const struct ov9281_mode *mode, ++ struct v4l2_mbus_framefmt *framefmt) ++{ ++ return abs(mode->width - framefmt->width) + ++ abs(mode->height - framefmt->height); ++} ++ ++static const struct ov9281_mode * ++ov9281_find_best_fit(struct v4l2_subdev_format *fmt) ++{ ++ struct v4l2_mbus_framefmt *framefmt = &fmt->format; ++ int dist; ++ int cur_best_fit = 0; ++ int cur_best_fit_dist = -1; ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(supported_modes); i++) { ++ dist = ov9281_get_reso_dist(&supported_modes[i], framefmt); ++ if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) { ++ cur_best_fit_dist = dist; ++ cur_best_fit = i; ++ } ++ } ++ ++ return &supported_modes[cur_best_fit]; ++} ++ ++static int ov9281_set_fmt(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_format *fmt) ++{ ++ struct ov9281 *ov9281 = to_ov9281(sd); ++ const struct ov9281_mode *mode; ++ s64 h_blank, vblank_def; ++ ++ mutex_lock(&ov9281->mutex); ++ ++ mode = ov9281_find_best_fit(fmt); ++ fmt->format.code = MEDIA_BUS_FMT_Y10_1X10; ++ fmt->format.width = mode->width; ++ fmt->format.height = mode->height; ++ fmt->format.field = V4L2_FIELD_NONE; ++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { ++#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API ++ *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; ++#else ++ mutex_unlock(&ov9281->mutex); ++ return -ENOTTY; ++#endif ++ } else { ++ ov9281->cur_mode = mode; ++ h_blank = mode->hts_def - mode->width; ++ __v4l2_ctrl_modify_range(ov9281->hblank, h_blank, ++ h_blank, 1, h_blank); ++ vblank_def = mode->vts_def - mode->height; ++ __v4l2_ctrl_modify_range(ov9281->vblank, vblank_def, ++ OV9281_VTS_MAX - mode->height, ++ 1, vblank_def); ++ } ++ ++ mutex_unlock(&ov9281->mutex); ++ ++ return 0; ++} ++ ++static int ov9281_get_fmt(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_format *fmt) ++{ ++ struct ov9281 *ov9281 = to_ov9281(sd); ++ const struct ov9281_mode *mode = ov9281->cur_mode; ++ ++ mutex_lock(&ov9281->mutex); ++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { ++#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API ++ fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); ++#else ++ mutex_unlock(&ov9281->mutex); ++ return -ENOTTY; ++#endif ++ } else { ++ fmt->format.width = mode->width; ++ fmt->format.height = mode->height; ++ fmt->format.code = MEDIA_BUS_FMT_Y10_1X10; ++ fmt->format.field = V4L2_FIELD_NONE; ++ } ++ mutex_unlock(&ov9281->mutex); ++ ++ return 0; ++} ++ ++static int ov9281_enum_mbus_code(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_mbus_code_enum *code) ++{ ++ if (code->index != 0) ++ return -EINVAL; ++ code->code = MEDIA_BUS_FMT_Y10_1X10; ++ ++ return 0; ++} ++ ++static int ov9281_enum_frame_sizes(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_frame_size_enum *fse) ++{ ++ if (fse->index >= ARRAY_SIZE(supported_modes)) ++ return -EINVAL; ++ ++ if (fse->code != MEDIA_BUS_FMT_Y10_1X10) ++ return -EINVAL; ++ ++ fse->min_width = supported_modes[fse->index].width; ++ fse->max_width = supported_modes[fse->index].width; ++ fse->max_height = supported_modes[fse->index].height; ++ fse->min_height = supported_modes[fse->index].height; ++ ++ return 0; ++} ++ ++static int ov9281_enable_test_pattern(struct ov9281 *ov9281, u32 pattern) ++{ ++ u32 val; ++ ++ if (pattern) ++ val = (pattern - 1) | OV9281_TEST_PATTERN_ENABLE; ++ else ++ val = OV9281_TEST_PATTERN_DISABLE; ++ ++ return ov9281_write_reg(ov9281->client, OV9281_REG_TEST_PATTERN, ++ OV9281_REG_VALUE_08BIT, val); ++} ++ ++static int OV9281_g_frame_interval(struct v4l2_subdev *sd, ++ struct v4l2_subdev_frame_interval *fi) ++{ ++ struct ov9281 *ov9281 = to_ov9281(sd); ++ const struct ov9281_mode *mode = ov9281->cur_mode; ++ ++ mutex_lock(&ov9281->mutex); ++ fi->interval.numerator = 10000; ++ fi->interval.denominator = mode->max_fps * 10000; ++ mutex_unlock(&ov9281->mutex); ++ ++ return 0; ++} ++ ++static void ov9281_get_module_inf(struct ov9281 *ov9281, ++ struct rkmodule_inf *inf) ++{ ++ memset(inf, 0, sizeof(*inf)); ++ strlcpy(inf->base.sensor, OV9281_NAME, sizeof(inf->base.sensor)); ++ strlcpy(inf->base.module, ov9281->module_name, ++ sizeof(inf->base.module)); ++ strlcpy(inf->base.lens, ov9281->len_name, sizeof(inf->base.lens)); ++} ++ ++static long ov9281_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) ++{ ++ struct ov9281 *ov9281 = to_ov9281(sd); ++ long ret = 0; ++ ++ switch (cmd) { ++ case RKMODULE_GET_MODULE_INFO: ++ ov9281_get_module_inf(ov9281, (struct rkmodule_inf *)arg); ++ break; ++ default: ++ ret = -ENOIOCTLCMD; ++ break; ++ } ++ ++ return ret; ++} ++ ++#ifdef CONFIG_COMPAT ++static long ov9281_compat_ioctl32(struct v4l2_subdev *sd, ++ unsigned int cmd, unsigned long arg) ++{ ++ void __user *up = compat_ptr(arg); ++ struct rkmodule_inf *inf; ++ struct rkmodule_awb_cfg *cfg; ++ long ret; ++ ++ switch (cmd) { ++ case RKMODULE_GET_MODULE_INFO: ++ inf = kzalloc(sizeof(*inf), GFP_KERNEL); ++ if (!inf) { ++ ret = -ENOMEM; ++ return ret; ++ } ++ ++ ret = ov9281_ioctl(sd, cmd, inf); ++ if (!ret) ++ ret = copy_to_user(up, inf, sizeof(*inf)); ++ kfree(inf); ++ break; ++ case RKMODULE_AWB_CFG: ++ cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); ++ if (!cfg) { ++ ret = -ENOMEM; ++ return ret; ++ } ++ ++ ret = copy_from_user(cfg, up, sizeof(*cfg)); ++ if (!ret) ++ ret = ov9281_ioctl(sd, cmd, cfg); ++ kfree(cfg); ++ break; ++ default: ++ ret = -ENOIOCTLCMD; ++ break; ++ } ++ ++ return ret; ++} ++#endif ++ ++static int __ov9281_start_stream(struct ov9281 *ov9281) ++{ ++ int ret; ++ ++ ret = ov9281_write_array(ov9281->client, ov9281->cur_mode->reg_list); ++ if (ret) ++ return ret; ++ ++ /* In case these controls are set before streaming */ ++ mutex_unlock(&ov9281->mutex); ++ ret = v4l2_ctrl_handler_setup(&ov9281->ctrl_handler); ++ mutex_lock(&ov9281->mutex); ++ if (ret) ++ return ret; ++ ++ return ov9281_write_reg(ov9281->client, OV9281_REG_CTRL_MODE, ++ OV9281_REG_VALUE_08BIT, OV9281_MODE_STREAMING); ++} ++ ++static int __ov9281_stop_stream(struct ov9281 *ov9281) ++{ ++ return ov9281_write_reg(ov9281->client, OV9281_REG_CTRL_MODE, ++ OV9281_REG_VALUE_08BIT, OV9281_MODE_SW_STANDBY); ++} ++ ++static int ov9281_s_stream(struct v4l2_subdev *sd, int on) ++{ ++ struct ov9281 *ov9281 = to_ov9281(sd); ++ struct i2c_client *client = ov9281->client; ++ int ret = 0; ++ ++ mutex_lock(&ov9281->mutex); ++ on = !!on; ++ if (on == ov9281->streaming) ++ goto unlock_and_return; ++ ++ if (on) { ++ ret = pm_runtime_get_sync(&client->dev); ++ if (ret < 0) { ++ pm_runtime_put_noidle(&client->dev); ++ goto unlock_and_return; ++ } ++ ++ ret = __ov9281_start_stream(ov9281); ++ if (ret) { ++ v4l2_err(sd, "start stream failed while write regs\n"); ++ pm_runtime_put(&client->dev); ++ goto unlock_and_return; ++ } ++ } else { ++ __ov9281_stop_stream(ov9281); ++ pm_runtime_put(&client->dev); ++ } ++ ++ ov9281->streaming = on; ++ ++unlock_and_return: ++ mutex_unlock(&ov9281->mutex); ++ ++ return ret; ++} ++ ++static int ov9281_s_power(struct v4l2_subdev *sd, int on) ++{ ++ struct ov9281 *ov9281 = to_ov9281(sd); ++ struct i2c_client *client = ov9281->client; ++ int ret = 0; ++ ++ mutex_lock(&ov9281->mutex); ++ ++ /* If the power state is not modified - no work to do. */ ++ if (ov9281->power_on == !!on) ++ goto unlock_and_return; ++ ++ if (on) { ++ ret = pm_runtime_get_sync(&client->dev); ++ if (ret < 0) { ++ pm_runtime_put_noidle(&client->dev); ++ goto unlock_and_return; ++ } ++ ret = ov9281_write_array(ov9281->client, ov9281_global_regs); ++ if (ret) { ++ v4l2_err(sd, "could not set init registers\n"); ++ pm_runtime_put_noidle(&client->dev); ++ goto unlock_and_return; ++ } ++ ov9281->power_on = true; ++ } else { ++ pm_runtime_put(&client->dev); ++ ov9281->power_on = false; ++ } ++ ++unlock_and_return: ++ mutex_unlock(&ov9281->mutex); ++ ++ return ret; ++} ++ ++/* Calculate the delay in us by clock rate and clock cycles */ ++static inline u32 ov9281_cal_delay(u32 cycles) ++{ ++ return DIV_ROUND_UP(cycles, OV9281_XVCLK_FREQ / 1000 / 1000); ++} ++ ++static int __ov9281_power_on(struct ov9281 *ov9281) ++{ ++ int ret; ++ u32 delay_us; ++ struct device *dev = &ov9281->client->dev; ++ ++ if (!IS_ERR_OR_NULL(ov9281->pins_default)) { ++ ret = pinctrl_select_state(ov9281->pinctrl, ++ ov9281->pins_default); ++ if (ret < 0) ++ dev_err(dev, "could not set pins\n"); ++ } ++ ++ ret = clk_prepare_enable(ov9281->xvclk); ++ if (ret < 0) { ++ dev_err(dev, "Failed to enable xvclk\n"); ++ return ret; ++ } ++ ++ if (!IS_ERR(ov9281->reset_gpio)) ++ gpiod_set_value_cansleep(ov9281->reset_gpio, 0); ++ ++ ret = regulator_bulk_enable(OV9281_NUM_SUPPLIES, ov9281->supplies); ++ if (ret < 0) { ++ dev_err(dev, "Failed to enable regulators\n"); ++ goto disable_clk; ++ } ++ ++ if (!IS_ERR(ov9281->reset_gpio)) ++ gpiod_set_value_cansleep(ov9281->reset_gpio, 1); ++ ++ usleep_range(500, 1000); ++ if (!IS_ERR(ov9281->pwdn_gpio)) ++ gpiod_set_value_cansleep(ov9281->pwdn_gpio, 1); ++ ++ /* 8192 cycles prior to first SCCB transaction */ ++ delay_us = ov9281_cal_delay(8192); ++ usleep_range(delay_us, delay_us * 2); ++ ++ return 0; ++ ++disable_clk: ++ clk_disable_unprepare(ov9281->xvclk); ++ ++ return ret; ++} ++ ++static void __ov9281_power_off(struct ov9281 *ov9281) ++{ ++ int ret; ++ struct device *dev = &ov9281->client->dev; ++ ++ if (!IS_ERR(ov9281->pwdn_gpio)) ++ gpiod_set_value_cansleep(ov9281->pwdn_gpio, 0); ++ clk_disable_unprepare(ov9281->xvclk); ++ if (!IS_ERR(ov9281->reset_gpio)) ++ gpiod_set_value_cansleep(ov9281->reset_gpio, 0); ++ if (!IS_ERR_OR_NULL(ov9281->pins_sleep)) { ++ ret = pinctrl_select_state(ov9281->pinctrl, ++ ov9281->pins_sleep); ++ if (ret < 0) ++ dev_dbg(dev, "could not set pins\n"); ++ } ++ regulator_bulk_disable(OV9281_NUM_SUPPLIES, ov9281->supplies); ++} ++ ++static int ov9281_runtime_resume(struct device *dev) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct v4l2_subdev *sd = i2c_get_clientdata(client); ++ struct ov9281 *ov9281 = to_ov9281(sd); ++ ++ return __ov9281_power_on(ov9281); ++} ++ ++static int ov9281_runtime_suspend(struct device *dev) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct v4l2_subdev *sd = i2c_get_clientdata(client); ++ struct ov9281 *ov9281 = to_ov9281(sd); ++ ++ __ov9281_power_off(ov9281); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API ++static int ov9281_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) ++{ ++ struct ov9281 *ov9281 = to_ov9281(sd); ++ struct v4l2_mbus_framefmt *try_fmt = ++ v4l2_subdev_get_try_format(sd, fh->pad, 0); ++ const struct ov9281_mode *def_mode = &supported_modes[0]; ++ ++ mutex_lock(&ov9281->mutex); ++ /* Initialize try_fmt */ ++ try_fmt->width = def_mode->width; ++ try_fmt->height = def_mode->height; ++ try_fmt->code = MEDIA_BUS_FMT_Y10_1X10; ++ try_fmt->field = V4L2_FIELD_NONE; ++ ++ mutex_unlock(&ov9281->mutex); ++ /* No crop or compose */ ++ ++ return 0; ++} ++#endif ++ ++static const struct dev_pm_ops ov9281_pm_ops = { ++ SET_RUNTIME_PM_OPS(ov9281_runtime_suspend, ++ ov9281_runtime_resume, NULL) ++}; ++ ++#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API ++static const struct v4l2_subdev_internal_ops ov9281_internal_ops = { ++ .open = ov9281_open, ++}; ++#endif ++ ++static const struct v4l2_subdev_core_ops ov9281_core_ops = { ++ .s_power = ov9281_s_power, ++ .ioctl = ov9281_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl32 = ov9281_compat_ioctl32, ++#endif ++}; ++ ++static const struct v4l2_subdev_video_ops ov9281_video_ops = { ++ .s_stream = ov9281_s_stream, ++ .g_frame_interval = OV9281_g_frame_interval, ++}; ++ ++static const struct v4l2_subdev_pad_ops ov9281_pad_ops = { ++ .enum_mbus_code = ov9281_enum_mbus_code, ++ .enum_frame_size = ov9281_enum_frame_sizes, ++ .get_fmt = ov9281_get_fmt, ++ .set_fmt = ov9281_set_fmt, ++}; ++ ++static const struct v4l2_subdev_ops ov9281_subdev_ops = { ++ .core = &ov9281_core_ops, ++ .video = &ov9281_video_ops, ++ .pad = &ov9281_pad_ops, ++}; ++ ++static int ov9281_set_ctrl(struct v4l2_ctrl *ctrl) ++{ ++ struct ov9281 *ov9281 = container_of(ctrl->handler, ++ struct ov9281, ctrl_handler); ++ struct i2c_client *client = ov9281->client; ++ s64 max; ++ int ret = 0; ++ ++ /* Propagate change of current control to all related controls */ ++ switch (ctrl->id) { ++ case V4L2_CID_VBLANK: ++ /* Update max exposure while meeting expected vblanking */ ++ max = ov9281->cur_mode->height + ctrl->val - 4; ++ __v4l2_ctrl_modify_range(ov9281->exposure, ++ ov9281->exposure->minimum, max, ++ ov9281->exposure->step, ++ ov9281->exposure->default_value); ++ break; ++ } ++ ++ if (pm_runtime_get(&client->dev) <= 0) ++ return 0; ++ ++ switch (ctrl->id) { ++ case V4L2_CID_EXPOSURE: ++ /* 4 least significant bits of expsoure are fractional part */ ++ ret = ov9281_write_reg(ov9281->client, OV9281_REG_EXPOSURE, ++ OV9281_REG_VALUE_24BIT, ctrl->val << 4); ++ break; ++ case V4L2_CID_ANALOGUE_GAIN: ++ ret = ov9281_write_reg(ov9281->client, OV9281_REG_GAIN_H, ++ OV9281_REG_VALUE_08BIT, ++ (ctrl->val >> OV9281_GAIN_H_SHIFT) & OV9281_GAIN_H_MASK); ++ ret |= ov9281_write_reg(ov9281->client, OV9281_REG_GAIN_L, ++ OV9281_REG_VALUE_08BIT, ++ ctrl->val & OV9281_GAIN_L_MASK); ++ break; ++ case V4L2_CID_VBLANK: ++ ret = ov9281_write_reg(ov9281->client, OV9281_REG_VTS, ++ OV9281_REG_VALUE_16BIT, ++ ctrl->val + ov9281->cur_mode->height); ++ break; ++ case V4L2_CID_TEST_PATTERN: ++ ret = ov9281_enable_test_pattern(ov9281, ctrl->val); ++ break; ++ default: ++ dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n", ++ __func__, ctrl->id, ctrl->val); ++ break; ++ } ++ ++ pm_runtime_put(&client->dev); ++ ++ return ret; ++} ++ ++static const struct v4l2_ctrl_ops ov9281_ctrl_ops = { ++ .s_ctrl = ov9281_set_ctrl, ++}; ++ ++static int ov9281_initialize_controls(struct ov9281 *ov9281) ++{ ++ const struct ov9281_mode *mode; ++ struct v4l2_ctrl_handler *handler; ++ struct v4l2_ctrl *ctrl; ++ s64 exposure_max, vblank_def; ++ u32 h_blank; ++ int ret; ++ ++ handler = &ov9281->ctrl_handler; ++ mode = ov9281->cur_mode; ++ ret = v4l2_ctrl_handler_init(handler, 8); ++ if (ret) ++ return ret; ++ handler->lock = &ov9281->mutex; ++ ++ ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ, ++ 0, 0, link_freq_menu_items); ++ if (ctrl) ++ ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; ++ ++ v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, ++ 0, OV9281_PIXEL_RATE, 1, OV9281_PIXEL_RATE); ++ ++ h_blank = mode->hts_def - mode->width; ++ ov9281->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK, ++ h_blank, h_blank, 1, h_blank); ++ if (ov9281->hblank) ++ ov9281->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; ++ ++ vblank_def = mode->vts_def - mode->height; ++ ov9281->vblank = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops, ++ V4L2_CID_VBLANK, vblank_def, ++ OV9281_VTS_MAX - mode->height, ++ 1, vblank_def); ++ ++ exposure_max = mode->vts_def - 4; ++ ov9281->exposure = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops, ++ V4L2_CID_EXPOSURE, OV9281_EXPOSURE_MIN, ++ exposure_max, OV9281_EXPOSURE_STEP, ++ mode->exp_def); ++ ++ ov9281->anal_gain = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops, ++ V4L2_CID_ANALOGUE_GAIN, OV9281_GAIN_MIN, ++ OV9281_GAIN_MAX, OV9281_GAIN_STEP, ++ OV9281_GAIN_DEFAULT); ++ ++ ov9281->test_pattern = v4l2_ctrl_new_std_menu_items(handler, ++ &ov9281_ctrl_ops, V4L2_CID_TEST_PATTERN, ++ ARRAY_SIZE(ov9281_test_pattern_menu) - 1, ++ 0, 0, ov9281_test_pattern_menu); ++ ++ if (handler->error) { ++ ret = handler->error; ++ dev_err(&ov9281->client->dev, ++ "Failed to init controls(%d)\n", ret); ++ goto err_free_handler; ++ } ++ ++ ov9281->subdev.ctrl_handler = handler; ++ ++ return 0; ++ ++err_free_handler: ++ v4l2_ctrl_handler_free(handler); ++ ++ return ret; ++} ++ ++static int ov9281_check_sensor_id(struct ov9281 *ov9281, ++ struct i2c_client *client) ++{ ++ struct device *dev = &ov9281->client->dev; ++ u32 id = 0; ++ int ret; ++ ++ ret = ov9281_read_reg(client, OV9281_REG_CHIP_ID, ++ OV9281_REG_VALUE_16BIT, &id); ++ if (id != CHIP_ID) { ++ dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret); ++ return -ENODEV; ++ } ++ ++ dev_info(dev, "Detected OV%06x sensor\n", CHIP_ID); ++ ++ return 0; ++} ++ ++static int ov9281_configure_regulators(struct ov9281 *ov9281) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < OV9281_NUM_SUPPLIES; i++) ++ ov9281->supplies[i].supply = ov9281_supply_names[i]; ++ ++ return devm_regulator_bulk_get(&ov9281->client->dev, ++ OV9281_NUM_SUPPLIES, ++ ov9281->supplies); ++} ++ ++static int ov9281_probe(struct i2c_client *client, ++ const struct i2c_device_id *id) ++{ ++ struct device *dev = &client->dev; ++ struct device_node *node = dev->of_node; ++ struct ov9281 *ov9281; ++ struct v4l2_subdev *sd; ++ char facing[2]; ++ int ret; ++ ++ dev_info(dev, "driver version: %02x.%02x.%02x", ++ DRIVER_VERSION >> 16, ++ (DRIVER_VERSION & 0xff00) >> 8, ++ DRIVER_VERSION & 0x00ff); ++ ++ ov9281 = devm_kzalloc(dev, sizeof(*ov9281), GFP_KERNEL); ++ if (!ov9281) ++ return -ENOMEM; ++ ++ ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX, ++ &ov9281->module_index); ++ ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING, ++ &ov9281->module_facing); ++ ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME, ++ &ov9281->module_name); ++ ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME, ++ &ov9281->len_name); ++ if (ret) { ++ dev_err(dev, "could not get module information!\n"); ++ return -EINVAL; ++ } ++ ++ ov9281->client = client; ++ ov9281->cur_mode = &supported_modes[0]; ++ ++ ov9281->xvclk = devm_clk_get(dev, "xvclk"); ++ if (IS_ERR(ov9281->xvclk)) { ++ dev_err(dev, "Failed to get xvclk\n"); ++ return -EINVAL; ++ } ++ ret = clk_set_rate(ov9281->xvclk, OV9281_XVCLK_FREQ); ++ if (ret < 0) { ++ dev_err(dev, "Failed to set xvclk rate (24MHz)\n"); ++ return ret; ++ } ++ if (clk_get_rate(ov9281->xvclk) != OV9281_XVCLK_FREQ) ++ dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n"); ++ ++ ov9281->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); ++ if (IS_ERR(ov9281->reset_gpio)) ++ dev_warn(dev, "Failed to get reset-gpios\n"); ++ ++ ov9281->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW); ++ if (IS_ERR(ov9281->pwdn_gpio)) ++ dev_warn(dev, "Failed to get pwdn-gpios\n"); ++ ++ ov9281->pinctrl = devm_pinctrl_get(dev); ++ if (!IS_ERR(ov9281->pinctrl)) { ++ ov9281->pins_default = ++ pinctrl_lookup_state(ov9281->pinctrl, ++ OF_CAMERA_PINCTRL_STATE_DEFAULT); ++ if (IS_ERR(ov9281->pins_default)) ++ dev_err(dev, "could not get default pinstate\n"); ++ ++ ov9281->pins_sleep = ++ pinctrl_lookup_state(ov9281->pinctrl, ++ OF_CAMERA_PINCTRL_STATE_SLEEP); ++ if (IS_ERR(ov9281->pins_sleep)) ++ dev_err(dev, "could not get sleep pinstate\n"); ++ } else { ++ dev_err(dev, "no pinctrl\n"); ++ } ++ ++ ret = ov9281_configure_regulators(ov9281); ++ if (ret) { ++ dev_err(dev, "Failed to get power regulators\n"); ++ return ret; ++ } ++ ++ mutex_init(&ov9281->mutex); ++ ++ sd = &ov9281->subdev; ++ v4l2_i2c_subdev_init(sd, client, &ov9281_subdev_ops); ++ ret = ov9281_initialize_controls(ov9281); ++ if (ret) ++ goto err_destroy_mutex; ++ ++ ret = __ov9281_power_on(ov9281); ++ if (ret) ++ goto err_free_handler; ++ ++ ret = ov9281_check_sensor_id(ov9281, client); ++ if (ret) ++ goto err_power_off; ++ ++#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API ++ sd->internal_ops = &ov9281_internal_ops; ++ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; ++#endif ++#if defined(CONFIG_MEDIA_CONTROLLER) ++ ov9281->pad.flags = MEDIA_PAD_FL_SOURCE; ++ sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ++ ret = media_entity_init(&sd->entity, 1, &ov9281->pad, 0); ++ if (ret < 0) ++ goto err_power_off; ++#endif ++ ++ memset(facing, 0, sizeof(facing)); ++ if (strcmp(ov9281->module_facing, "back") == 0) ++ facing[0] = 'b'; ++ else ++ facing[0] = 'f'; ++ ++ snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s", ++ ov9281->module_index, facing, ++ OV9281_NAME, dev_name(sd->dev)); ++ ret = v4l2_async_register_subdev_sensor_common(sd); ++ if (ret) { ++ dev_err(dev, "v4l2 async register subdev failed\n"); ++ goto err_clean_entity; ++ } ++ ++ pm_runtime_set_active(dev); ++ pm_runtime_enable(dev); ++ pm_runtime_idle(dev); ++ ++ return 0; ++ ++err_clean_entity: ++#if defined(CONFIG_MEDIA_CONTROLLER) ++ media_entity_cleanup(&sd->entity); ++#endif ++err_power_off: ++ __ov9281_power_off(ov9281); ++err_free_handler: ++ v4l2_ctrl_handler_free(&ov9281->ctrl_handler); ++err_destroy_mutex: ++ mutex_destroy(&ov9281->mutex); ++ ++ return ret; ++} ++ ++static int ov9281_remove(struct i2c_client *client) ++{ ++ struct v4l2_subdev *sd = i2c_get_clientdata(client); ++ struct ov9281 *ov9281 = to_ov9281(sd); ++ ++ v4l2_async_unregister_subdev(sd); ++#if defined(CONFIG_MEDIA_CONTROLLER) ++ media_entity_cleanup(&sd->entity); ++#endif ++ v4l2_ctrl_handler_free(&ov9281->ctrl_handler); ++ mutex_destroy(&ov9281->mutex); ++ ++ pm_runtime_disable(&client->dev); ++ if (!pm_runtime_status_suspended(&client->dev)) ++ __ov9281_power_off(ov9281); ++ pm_runtime_set_suspended(&client->dev); ++ ++ return 0; ++} ++ ++#if IS_ENABLED(CONFIG_OF) ++static const struct of_device_id ov9281_of_match[] = { ++ { .compatible = "ovti,ov9281" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, ov9281_of_match); ++#endif ++ ++static const struct i2c_device_id ov9281_match_id[] = { ++ { "ovti,ov9281", 0 }, ++ { }, ++}; ++ ++static struct i2c_driver ov9281_i2c_driver = { ++ .driver = { ++ .name = OV9281_NAME, ++ .pm = &ov9281_pm_ops, ++ .of_match_table = of_match_ptr(ov9281_of_match), ++ }, ++ .probe = &ov9281_probe, ++ .remove = &ov9281_remove, ++ .id_table = ov9281_match_id, ++}; ++ ++static int __init sensor_mod_init(void) ++{ ++ return i2c_add_driver(&ov9281_i2c_driver); ++} ++ ++static void __exit sensor_mod_exit(void) ++{ ++ i2c_del_driver(&ov9281_i2c_driver); ++} ++ ++device_initcall_sync(sensor_mod_init); ++module_exit(sensor_mod_exit); ++ ++MODULE_DESCRIPTION("OmniVision ov9281 sensor driver"); ++MODULE_LICENSE("GPL v2"); diff --git a/target/linux/bcm27xx/patches-5.4/950-0871-media-i2c-ov9281-fix-mclk-issue-when-probe-multiple-.patch b/target/linux/bcm27xx/patches-5.4/950-0871-media-i2c-ov9281-fix-mclk-issue-when-probe-multiple-.patch new file mode 100644 index 0000000000..4a2bbed249 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0871-media-i2c-ov9281-fix-mclk-issue-when-probe-multiple-.patch @@ -0,0 +1,60 @@ +From a02d918e1bf4dc70c51b630c12182e038d0a73d2 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 14 Apr 2020 15:47:09 +0100 +Subject: [PATCH] media: i2c: ov9281: fix mclk issue when probe + multiple camera. + +Takes the ov9281 part only from the Rockchip's patch. + +Change-Id: I30e833baf2c1bb07d6d87ddb3b00759ab45a90e4 +Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com> +--- + drivers/media/i2c/ov9281.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/media/i2c/ov9281.c ++++ b/drivers/media/i2c/ov9281.c +@@ -3,6 +3,7 @@ + * ov9281 driver + * + * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd. ++ * V0.0X01.0X02 fix mclk issue when probe multiple camera. + */ + + #include <linux/clk.h> +@@ -22,7 +23,7 @@ + #include <media/v4l2-subdev.h> + #include <linux/pinctrl/consumer.h> + +-#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x0) ++#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x2) + + #ifndef V4L2_CID_DIGITAL_GAIN + #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN +@@ -676,6 +677,12 @@ static int __ov9281_power_on(struct ov92 + dev_err(dev, "could not set pins\n"); + } + ++ ret = clk_set_rate(ov9281->xvclk, OV9281_XVCLK_FREQ); ++ if (ret < 0) ++ dev_warn(dev, "Failed to set xvclk rate (24MHz)\n"); ++ if (clk_get_rate(ov9281->xvclk) != OV9281_XVCLK_FREQ) ++ dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n"); ++ + ret = clk_prepare_enable(ov9281->xvclk); + if (ret < 0) { + dev_err(dev, "Failed to enable xvclk\n"); +@@ -1008,13 +1015,6 @@ static int ov9281_probe(struct i2c_clien + dev_err(dev, "Failed to get xvclk\n"); + return -EINVAL; + } +- ret = clk_set_rate(ov9281->xvclk, OV9281_XVCLK_FREQ); +- if (ret < 0) { +- dev_err(dev, "Failed to set xvclk rate (24MHz)\n"); +- return ret; +- } +- if (clk_get_rate(ov9281->xvclk) != OV9281_XVCLK_FREQ) +- dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n"); + + ov9281->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(ov9281->reset_gpio)) diff --git a/target/linux/bcm27xx/patches-5.4/950-0872-media-i2c-ov9281-add-enum_frame_interval-function-fo.patch b/target/linux/bcm27xx/patches-5.4/950-0872-media-i2c-ov9281-add-enum_frame_interval-function-fo.patch new file mode 100644 index 0000000000..c772521a9f --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0872-media-i2c-ov9281-add-enum_frame_interval-function-fo.patch @@ -0,0 +1,97 @@ +From c99b6817190eefc77c91567e57fc930656f205bf Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 14 Apr 2020 15:51:50 +0100 +Subject: [PATCH] media: i2c: ov9281: add enum_frame_interval + function for iq tool 2.2 and hal3 + +Adds the ov9281 parts of the Rockchip patch adding enum_frame_interval to +a large number of drivers. + +Change-Id: I03344cd6cf278dd7c18fce8e97479089ef185a5c +Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com> +--- + drivers/media/i2c/ov9281.c | 31 ++++++++++++++++++++++++++----- + 1 file changed, 26 insertions(+), 5 deletions(-) + +--- a/drivers/media/i2c/ov9281.c ++++ b/drivers/media/i2c/ov9281.c +@@ -4,6 +4,7 @@ + * + * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd. + * V0.0X01.0X02 fix mclk issue when probe multiple camera. ++ * V0.0X01.0X03 add enum_frame_interval function. + */ + + #include <linux/clk.h> +@@ -23,7 +24,7 @@ + #include <media/v4l2-subdev.h> + #include <linux/pinctrl/consumer.h> + +-#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x2) ++#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x3) + + #ifndef V4L2_CID_DIGITAL_GAIN + #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN +@@ -92,7 +93,7 @@ struct regval { + struct ov9281_mode { + u32 width; + u32 height; +- u32 max_fps; ++ struct v4l2_fract max_fps; + u32 hts_def; + u32 vts_def; + u32 exp_def; +@@ -246,7 +247,10 @@ static const struct ov9281_mode supporte + { + .width = 1280, + .height = 800, +- .max_fps = 120, ++ .max_fps = { ++ .numerator = 10000, ++ .denominator = 1200000, ++ }, + .exp_def = 0x0320, + .hts_def = 0x0b60,//0x2d8*4 + .vts_def = 0x038e, +@@ -483,8 +487,7 @@ static int OV9281_g_frame_interval(struc + const struct ov9281_mode *mode = ov9281->cur_mode; + + mutex_lock(&ov9281->mutex); +- fi->interval.numerator = 10000; +- fi->interval.denominator = mode->max_fps * 10000; ++ fi->interval = mode->max_fps; + mutex_unlock(&ov9281->mutex); + + return 0; +@@ -778,6 +781,23 @@ static int ov9281_open(struct v4l2_subde + } + #endif + ++static int ++ov9281_enum_frame_interval(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_frame_interval_enum *fie) ++{ ++ if (fie->index >= ARRAY_SIZE(supported_modes)) ++ return -EINVAL; ++ ++ if (fie->code != MEDIA_BUS_FMT_Y10_1X10) ++ return -EINVAL; ++ ++ fie->width = supported_modes[fie->index].width; ++ fie->height = supported_modes[fie->index].height; ++ fie->interval = supported_modes[fie->index].max_fps; ++ return 0; ++} ++ + static const struct dev_pm_ops ov9281_pm_ops = { + SET_RUNTIME_PM_OPS(ov9281_runtime_suspend, + ov9281_runtime_resume, NULL) +@@ -805,6 +825,7 @@ static const struct v4l2_subdev_video_op + static const struct v4l2_subdev_pad_ops ov9281_pad_ops = { + .enum_mbus_code = ov9281_enum_mbus_code, + .enum_frame_size = ov9281_enum_frame_sizes, ++ .enum_frame_interval = ov9281_enum_frame_interval, + .get_fmt = ov9281_get_fmt, + .set_fmt = ov9281_set_fmt, + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0873-media-i2c-ov9281-Fixup-for-recent-kernel-releases-an.patch b/target/linux/bcm27xx/patches-5.4/950-0873-media-i2c-ov9281-Fixup-for-recent-kernel-releases-an.patch new file mode 100644 index 0000000000..4f3bcf35cf --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0873-media-i2c-ov9281-Fixup-for-recent-kernel-releases-an.patch @@ -0,0 +1,693 @@ +From 898198428aa35f52c2b58c037e960dcbcc4ef9d8 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 14 Apr 2020 16:12:33 +0100 +Subject: [PATCH] media: i2c: ov9281: Fixup for recent kernel + releases, and remove custom code + +The Rockchip driver was based on a 4.4 kernel, and had several custom +Rockchip parts. + +Update to 5.4 kernel APIs, with the relevant controls required by +libcamera, and remove custom Rockchip parts. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/i2c/Kconfig | 2 +- + drivers/media/i2c/ov9281.c | 361 +++++++++++++------------------------ + 2 files changed, 123 insertions(+), 240 deletions(-) + +--- a/drivers/media/i2c/Kconfig ++++ b/drivers/media/i2c/Kconfig +@@ -857,7 +857,7 @@ config VIDEO_OV9640 + + config VIDEO_OV9281 + tristate "OmniVision OV9281 sensor support" +- depends on I2C && VIDEO_V4L2 ++ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + depends on MEDIA_CAMERA_SUPPORT + help + This is a Video4Linux2 sensor-level driver for the OmniVision +--- a/drivers/media/i2c/ov9281.c ++++ b/drivers/media/i2c/ov9281.c +@@ -1,6 +1,11 @@ + // SPDX-License-Identifier: GPL-2.0 + /* +- * ov9281 driver ++ * Omnivision OV9281 1280x800 global shutter image sensor driver ++ * ++ * This driver has been taken from ++ * https://github.com/rockchip-linux/kernel/blob/develop-4.4/drivers/media/i2c/ov9281.c ++ * cleaned up, made to compile against mainline kernels instead of the Rockchip ++ * vendor kernel, and the relevant controls added to work with libcamera. + * + * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd. + * V0.0X01.0X02 fix mclk issue when probe multiple camera. +@@ -17,22 +22,18 @@ + #include <linux/regulator/consumer.h> + #include <linux/sysfs.h> + #include <linux/slab.h> +-#include <linux/rk-camera-module.h> + #include <media/media-entity.h> + #include <media/v4l2-async.h> + #include <media/v4l2-ctrls.h> + #include <media/v4l2-subdev.h> +-#include <linux/pinctrl/consumer.h> +- +-#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x3) +- +-#ifndef V4L2_CID_DIGITAL_GAIN +-#define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN +-#endif + + #define OV9281_LINK_FREQ_400MHZ 400000000 ++#define OV9281_LANES 2 ++#define OV9281_BITS_PER_SAMPLE 10 ++ + /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */ +-#define OV9281_PIXEL_RATE (OV9281_LINK_FREQ_400MHZ * 2 * 2 / 10) ++#define OV9281_PIXEL_RATE (OV9281_LINK_FREQ_400MHZ * 2 * \ ++ OV9281_LANES / OV9281_BITS_PER_SAMPLE) + #define OV9281_XVCLK_FREQ 24000000 + + #define CHIP_ID 0x9281 +@@ -63,18 +64,24 @@ + + #define OV9281_REG_VTS 0x380e + ++/* ++ * OV9281 native and active pixel array size. ++ * Datasheet not available to confirm these values, so assume there are no ++ * border pixels. ++ */ ++#define OV9281_NATIVE_WIDTH 1280U ++#define OV9281_NATIVE_HEIGHT 800U ++#define OV9281_PIXEL_ARRAY_LEFT 0U ++#define OV9281_PIXEL_ARRAY_TOP 0U ++#define OV9281_PIXEL_ARRAY_WIDTH 1280U ++#define OV9281_PIXEL_ARRAY_HEIGHT 800U ++ + #define REG_NULL 0xFFFF + + #define OV9281_REG_VALUE_08BIT 1 + #define OV9281_REG_VALUE_16BIT 2 + #define OV9281_REG_VALUE_24BIT 3 + +-#define OV9281_LANES 2 +-#define OV9281_BITS_PER_SAMPLE 10 +- +-#define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default" +-#define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep" +- + #define OV9281_NAME "ov9281" + + static const char * const ov9281_supply_names[] = { +@@ -93,10 +100,10 @@ struct regval { + struct ov9281_mode { + u32 width; + u32 height; +- struct v4l2_fract max_fps; + u32 hts_def; + u32 vts_def; + u32 exp_def; ++ struct v4l2_rect crop; + const struct regval *reg_list; + }; + +@@ -107,10 +114,6 @@ struct ov9281 { + struct gpio_desc *pwdn_gpio; + struct regulator_bulk_data supplies[OV9281_NUM_SUPPLIES]; + +- struct pinctrl *pinctrl; +- struct pinctrl_state *pins_default; +- struct pinctrl_state *pins_sleep; +- + struct v4l2_subdev subdev; + struct media_pad pad; + struct v4l2_ctrl_handler ctrl_handler; +@@ -124,23 +127,12 @@ struct ov9281 { + bool streaming; + bool power_on; + const struct ov9281_mode *cur_mode; +- u32 module_index; +- const char *module_facing; +- const char *module_name; +- const char *len_name; + }; + + #define to_ov9281(sd) container_of(sd, struct ov9281, subdev) + + /* + * Xclk 24Mhz +- */ +-static const struct regval ov9281_global_regs[] = { +- {REG_NULL, 0x00}, +-}; +- +-/* +- * Xclk 24Mhz + * max_framerate 120fps + * mipi_datarate per lane 800Mbps + */ +@@ -247,13 +239,15 @@ static const struct ov9281_mode supporte + { + .width = 1280, + .height = 800, +- .max_fps = { +- .numerator = 10000, +- .denominator = 1200000, +- }, + .exp_def = 0x0320, +- .hts_def = 0x0b60,//0x2d8*4 ++ .hts_def = 0x05b0, /* 0x2d8*2 */ + .vts_def = 0x038e, ++ .crop = { ++ .left = 0, ++ .top = 0, ++ .width = 1280, ++ .height = 800 ++ }, + .reg_list = ov9281_1280x800_regs, + }, + }; +@@ -389,22 +383,28 @@ static int ov9281_set_fmt(struct v4l2_su + fmt->format.width = mode->width; + fmt->format.height = mode->height; + fmt->format.field = V4L2_FIELD_NONE; ++ fmt->format.colorspace = V4L2_COLORSPACE_SRGB; ++ fmt->format.ycbcr_enc = ++ V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->format.colorspace); ++ fmt->format.quantization = ++ V4L2_MAP_QUANTIZATION_DEFAULT(true, fmt->format.colorspace, ++ fmt->format.ycbcr_enc); ++ fmt->format.xfer_func = ++ V4L2_MAP_XFER_FUNC_DEFAULT(fmt->format.colorspace); ++ + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { +-#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; +-#else +- mutex_unlock(&ov9281->mutex); +- return -ENOTTY; +-#endif + } else { + ov9281->cur_mode = mode; + h_blank = mode->hts_def - mode->width; + __v4l2_ctrl_modify_range(ov9281->hblank, h_blank, + h_blank, 1, h_blank); ++ __v4l2_ctrl_s_ctrl(ov9281->hblank, h_blank); + vblank_def = mode->vts_def - mode->height; + __v4l2_ctrl_modify_range(ov9281->vblank, vblank_def, + OV9281_VTS_MAX - mode->height, + 1, vblank_def); ++ __v4l2_ctrl_s_ctrl(ov9281->vblank, vblank_def); + } + + mutex_unlock(&ov9281->mutex); +@@ -421,17 +421,21 @@ static int ov9281_get_fmt(struct v4l2_su + + mutex_lock(&ov9281->mutex); + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { +-#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); +-#else +- mutex_unlock(&ov9281->mutex); +- return -ENOTTY; +-#endif + } else { + fmt->format.width = mode->width; + fmt->format.height = mode->height; + fmt->format.code = MEDIA_BUS_FMT_Y10_1X10; + fmt->format.field = V4L2_FIELD_NONE; ++ fmt->format.colorspace = V4L2_COLORSPACE_SRGB; ++ fmt->format.ycbcr_enc = ++ V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->format.colorspace); ++ fmt->format.quantization = ++ V4L2_MAP_QUANTIZATION_DEFAULT(true, ++ fmt->format.colorspace, ++ fmt->format.ycbcr_enc); ++ fmt->format.xfer_func = ++ V4L2_MAP_XFER_FUNC_DEFAULT(fmt->format.colorspace); + } + mutex_unlock(&ov9281->mutex); + +@@ -442,7 +446,7 @@ static int ov9281_enum_mbus_code(struct + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) + { +- if (code->index != 0) ++ if (code->index) + return -EINVAL; + code->code = MEDIA_BUS_FMT_Y10_1X10; + +@@ -480,88 +484,56 @@ static int ov9281_enable_test_pattern(st + OV9281_REG_VALUE_08BIT, val); + } + +-static int OV9281_g_frame_interval(struct v4l2_subdev *sd, +- struct v4l2_subdev_frame_interval *fi) +-{ +- struct ov9281 *ov9281 = to_ov9281(sd); +- const struct ov9281_mode *mode = ov9281->cur_mode; +- +- mutex_lock(&ov9281->mutex); +- fi->interval = mode->max_fps; +- mutex_unlock(&ov9281->mutex); ++static const struct v4l2_rect * ++__ov9281_get_pad_crop(struct ov9281 *ov9281, struct v4l2_subdev_pad_config *cfg, ++ unsigned int pad, enum v4l2_subdev_format_whence which) ++{ ++ switch (which) { ++ case V4L2_SUBDEV_FORMAT_TRY: ++ return v4l2_subdev_get_try_crop(&ov9281->subdev, cfg, pad); ++ case V4L2_SUBDEV_FORMAT_ACTIVE: ++ return &ov9281->cur_mode->crop; ++ } + +- return 0; ++ return NULL; + } + +-static void ov9281_get_module_inf(struct ov9281 *ov9281, +- struct rkmodule_inf *inf) ++static int ov9281_get_selection(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_selection *sel) + { +- memset(inf, 0, sizeof(*inf)); +- strlcpy(inf->base.sensor, OV9281_NAME, sizeof(inf->base.sensor)); +- strlcpy(inf->base.module, ov9281->module_name, +- sizeof(inf->base.module)); +- strlcpy(inf->base.lens, ov9281->len_name, sizeof(inf->base.lens)); +-} ++ switch (sel->target) { ++ case V4L2_SEL_TGT_CROP: { ++ struct ov9281 *ov9281 = to_ov9281(sd); + +-static long ov9281_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +-{ +- struct ov9281 *ov9281 = to_ov9281(sd); +- long ret = 0; ++ mutex_lock(&ov9281->mutex); ++ sel->r = *__ov9281_get_pad_crop(ov9281, cfg, sel->pad, ++ sel->which); ++ mutex_unlock(&ov9281->mutex); + +- switch (cmd) { +- case RKMODULE_GET_MODULE_INFO: +- ov9281_get_module_inf(ov9281, (struct rkmodule_inf *)arg); +- break; +- default: +- ret = -ENOIOCTLCMD; +- break; ++ return 0; + } + +- return ret; +-} ++ case V4L2_SEL_TGT_NATIVE_SIZE: ++ sel->r.top = 0; ++ sel->r.left = 0; ++ sel->r.width = OV9281_NATIVE_WIDTH; ++ sel->r.height = OV9281_NATIVE_HEIGHT; + +-#ifdef CONFIG_COMPAT +-static long ov9281_compat_ioctl32(struct v4l2_subdev *sd, +- unsigned int cmd, unsigned long arg) +-{ +- void __user *up = compat_ptr(arg); +- struct rkmodule_inf *inf; +- struct rkmodule_awb_cfg *cfg; +- long ret; +- +- switch (cmd) { +- case RKMODULE_GET_MODULE_INFO: +- inf = kzalloc(sizeof(*inf), GFP_KERNEL); +- if (!inf) { +- ret = -ENOMEM; +- return ret; +- } ++ return 0; + +- ret = ov9281_ioctl(sd, cmd, inf); +- if (!ret) +- ret = copy_to_user(up, inf, sizeof(*inf)); +- kfree(inf); +- break; +- case RKMODULE_AWB_CFG: +- cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); +- if (!cfg) { +- ret = -ENOMEM; +- return ret; +- } ++ case V4L2_SEL_TGT_CROP_DEFAULT: ++ case V4L2_SEL_TGT_CROP_BOUNDS: ++ sel->r.top = OV9281_PIXEL_ARRAY_TOP; ++ sel->r.left = OV9281_PIXEL_ARRAY_LEFT; ++ sel->r.width = OV9281_PIXEL_ARRAY_WIDTH; ++ sel->r.height = OV9281_PIXEL_ARRAY_HEIGHT; + +- ret = copy_from_user(cfg, up, sizeof(*cfg)); +- if (!ret) +- ret = ov9281_ioctl(sd, cmd, cfg); +- kfree(cfg); +- break; +- default: +- ret = -ENOIOCTLCMD; +- break; ++ return 0; + } + +- return ret; ++ return -EINVAL; + } +-#endif + + static int __ov9281_start_stream(struct ov9281 *ov9281) + { +@@ -643,12 +615,6 @@ static int ov9281_s_power(struct v4l2_su + pm_runtime_put_noidle(&client->dev); + goto unlock_and_return; + } +- ret = ov9281_write_array(ov9281->client, ov9281_global_regs); +- if (ret) { +- v4l2_err(sd, "could not set init registers\n"); +- pm_runtime_put_noidle(&client->dev); +- goto unlock_and_return; +- } + ov9281->power_on = true; + } else { + pm_runtime_put(&client->dev); +@@ -673,18 +639,12 @@ static int __ov9281_power_on(struct ov92 + u32 delay_us; + struct device *dev = &ov9281->client->dev; + +- if (!IS_ERR_OR_NULL(ov9281->pins_default)) { +- ret = pinctrl_select_state(ov9281->pinctrl, +- ov9281->pins_default); +- if (ret < 0) +- dev_err(dev, "could not set pins\n"); +- } +- + ret = clk_set_rate(ov9281->xvclk, OV9281_XVCLK_FREQ); + if (ret < 0) + dev_warn(dev, "Failed to set xvclk rate (24MHz)\n"); + if (clk_get_rate(ov9281->xvclk) != OV9281_XVCLK_FREQ) +- dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n"); ++ dev_warn(dev, "xvclk mismatched, modes are based on 24MHz - rate is %lu\n", ++ clk_get_rate(ov9281->xvclk)); + + ret = clk_prepare_enable(ov9281->xvclk); + if (ret < 0) { +@@ -722,20 +682,11 @@ disable_clk: + + static void __ov9281_power_off(struct ov9281 *ov9281) + { +- int ret; +- struct device *dev = &ov9281->client->dev; +- + if (!IS_ERR(ov9281->pwdn_gpio)) + gpiod_set_value_cansleep(ov9281->pwdn_gpio, 0); + clk_disable_unprepare(ov9281->xvclk); + if (!IS_ERR(ov9281->reset_gpio)) + gpiod_set_value_cansleep(ov9281->reset_gpio, 0); +- if (!IS_ERR_OR_NULL(ov9281->pins_sleep)) { +- ret = pinctrl_select_state(ov9281->pinctrl, +- ov9281->pins_sleep); +- if (ret < 0) +- dev_dbg(dev, "could not set pins\n"); +- } + regulator_bulk_disable(OV9281_NUM_SUPPLIES, ov9281->supplies); + } + +@@ -759,7 +710,6 @@ static int ov9281_runtime_suspend(struct + return 0; + } + +-#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + static int ov9281_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) + { + struct ov9281 *ov9281 = to_ov9281(sd); +@@ -773,61 +723,42 @@ static int ov9281_open(struct v4l2_subde + try_fmt->height = def_mode->height; + try_fmt->code = MEDIA_BUS_FMT_Y10_1X10; + try_fmt->field = V4L2_FIELD_NONE; ++ try_fmt->colorspace = V4L2_COLORSPACE_SRGB; ++ try_fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(try_fmt->colorspace); ++ try_fmt->quantization = ++ V4L2_MAP_QUANTIZATION_DEFAULT(true, try_fmt->colorspace, ++ try_fmt->ycbcr_enc); ++ try_fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(try_fmt->colorspace); + + mutex_unlock(&ov9281->mutex); + /* No crop or compose */ + + return 0; + } +-#endif +- +-static int +-ov9281_enum_frame_interval(struct v4l2_subdev *sd, +- struct v4l2_subdev_pad_config *cfg, +- struct v4l2_subdev_frame_interval_enum *fie) +-{ +- if (fie->index >= ARRAY_SIZE(supported_modes)) +- return -EINVAL; +- +- if (fie->code != MEDIA_BUS_FMT_Y10_1X10) +- return -EINVAL; +- +- fie->width = supported_modes[fie->index].width; +- fie->height = supported_modes[fie->index].height; +- fie->interval = supported_modes[fie->index].max_fps; +- return 0; +-} + + static const struct dev_pm_ops ov9281_pm_ops = { + SET_RUNTIME_PM_OPS(ov9281_runtime_suspend, + ov9281_runtime_resume, NULL) + }; + +-#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + static const struct v4l2_subdev_internal_ops ov9281_internal_ops = { + .open = ov9281_open, + }; +-#endif + + static const struct v4l2_subdev_core_ops ov9281_core_ops = { + .s_power = ov9281_s_power, +- .ioctl = ov9281_ioctl, +-#ifdef CONFIG_COMPAT +- .compat_ioctl32 = ov9281_compat_ioctl32, +-#endif + }; + + static const struct v4l2_subdev_video_ops ov9281_video_ops = { + .s_stream = ov9281_s_stream, +- .g_frame_interval = OV9281_g_frame_interval, + }; + + static const struct v4l2_subdev_pad_ops ov9281_pad_ops = { + .enum_mbus_code = ov9281_enum_mbus_code, + .enum_frame_size = ov9281_enum_frame_sizes, +- .enum_frame_interval = ov9281_enum_frame_interval, + .get_fmt = ov9281_get_fmt, + .set_fmt = ov9281_set_fmt, ++ .get_selection = ov9281_get_selection, + }; + + static const struct v4l2_subdev_ops ov9281_subdev_ops = { +@@ -868,7 +799,8 @@ static int ov9281_set_ctrl(struct v4l2_c + case V4L2_CID_ANALOGUE_GAIN: + ret = ov9281_write_reg(ov9281->client, OV9281_REG_GAIN_H, + OV9281_REG_VALUE_08BIT, +- (ctrl->val >> OV9281_GAIN_H_SHIFT) & OV9281_GAIN_H_MASK); ++ (ctrl->val >> OV9281_GAIN_H_SHIFT) & ++ OV9281_GAIN_H_MASK); + ret |= ov9281_write_reg(ov9281->client, OV9281_REG_GAIN_L, + OV9281_REG_VALUE_08BIT, + ctrl->val & OV9281_GAIN_L_MASK); +@@ -922,31 +854,34 @@ static int ov9281_initialize_controls(st + + h_blank = mode->hts_def - mode->width; + ov9281->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK, +- h_blank, h_blank, 1, h_blank); ++ h_blank, h_blank, 1, h_blank); + if (ov9281->hblank) + ov9281->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; + + vblank_def = mode->vts_def - mode->height; + ov9281->vblank = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops, +- V4L2_CID_VBLANK, vblank_def, +- OV9281_VTS_MAX - mode->height, +- 1, vblank_def); ++ V4L2_CID_VBLANK, vblank_def, ++ OV9281_VTS_MAX - mode->height, 1, ++ vblank_def); + + exposure_max = mode->vts_def - 4; + ov9281->exposure = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops, +- V4L2_CID_EXPOSURE, OV9281_EXPOSURE_MIN, +- exposure_max, OV9281_EXPOSURE_STEP, +- mode->exp_def); ++ V4L2_CID_EXPOSURE, ++ OV9281_EXPOSURE_MIN, exposure_max, ++ OV9281_EXPOSURE_STEP, ++ mode->exp_def); + + ov9281->anal_gain = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops, +- V4L2_CID_ANALOGUE_GAIN, OV9281_GAIN_MIN, +- OV9281_GAIN_MAX, OV9281_GAIN_STEP, +- OV9281_GAIN_DEFAULT); +- +- ov9281->test_pattern = v4l2_ctrl_new_std_menu_items(handler, +- &ov9281_ctrl_ops, V4L2_CID_TEST_PATTERN, +- ARRAY_SIZE(ov9281_test_pattern_menu) - 1, +- 0, 0, ov9281_test_pattern_menu); ++ V4L2_CID_ANALOGUE_GAIN, ++ OV9281_GAIN_MIN, OV9281_GAIN_MAX, ++ OV9281_GAIN_STEP, ++ OV9281_GAIN_DEFAULT); ++ ++ ov9281->test_pattern = ++ v4l2_ctrl_new_std_menu_items(handler, &ov9281_ctrl_ops, ++ V4L2_CID_TEST_PATTERN, ++ ARRAY_SIZE(ov9281_test_pattern_menu) - 1, ++ 0, 0, ov9281_test_pattern_menu); + + if (handler->error) { + ret = handler->error; +@@ -1000,34 +935,14 @@ static int ov9281_probe(struct i2c_clien + const struct i2c_device_id *id) + { + struct device *dev = &client->dev; +- struct device_node *node = dev->of_node; + struct ov9281 *ov9281; + struct v4l2_subdev *sd; +- char facing[2]; + int ret; + +- dev_info(dev, "driver version: %02x.%02x.%02x", +- DRIVER_VERSION >> 16, +- (DRIVER_VERSION & 0xff00) >> 8, +- DRIVER_VERSION & 0x00ff); +- + ov9281 = devm_kzalloc(dev, sizeof(*ov9281), GFP_KERNEL); + if (!ov9281) + return -ENOMEM; + +- ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX, +- &ov9281->module_index); +- ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING, +- &ov9281->module_facing); +- ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME, +- &ov9281->module_name); +- ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME, +- &ov9281->len_name); +- if (ret) { +- dev_err(dev, "could not get module information!\n"); +- return -EINVAL; +- } +- + ov9281->client = client; + ov9281->cur_mode = &supported_modes[0]; + +@@ -1037,31 +952,15 @@ static int ov9281_probe(struct i2c_clien + return -EINVAL; + } + +- ov9281->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); ++ ov9281->reset_gpio = devm_gpiod_get_optional(dev, "reset", ++ GPIOD_OUT_LOW); + if (IS_ERR(ov9281->reset_gpio)) + dev_warn(dev, "Failed to get reset-gpios\n"); + +- ov9281->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW); ++ ov9281->pwdn_gpio = devm_gpiod_get_optional(dev, "pwdn", GPIOD_OUT_LOW); + if (IS_ERR(ov9281->pwdn_gpio)) + dev_warn(dev, "Failed to get pwdn-gpios\n"); + +- ov9281->pinctrl = devm_pinctrl_get(dev); +- if (!IS_ERR(ov9281->pinctrl)) { +- ov9281->pins_default = +- pinctrl_lookup_state(ov9281->pinctrl, +- OF_CAMERA_PINCTRL_STATE_DEFAULT); +- if (IS_ERR(ov9281->pins_default)) +- dev_err(dev, "could not get default pinstate\n"); +- +- ov9281->pins_sleep = +- pinctrl_lookup_state(ov9281->pinctrl, +- OF_CAMERA_PINCTRL_STATE_SLEEP); +- if (IS_ERR(ov9281->pins_sleep)) +- dev_err(dev, "could not get sleep pinstate\n"); +- } else { +- dev_err(dev, "no pinctrl\n"); +- } +- + ret = ov9281_configure_regulators(ov9281); + if (ret) { + dev_err(dev, "Failed to get power regulators\n"); +@@ -1084,26 +983,16 @@ static int ov9281_probe(struct i2c_clien + if (ret) + goto err_power_off; + +-#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + sd->internal_ops = &ov9281_internal_ops; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; +-#endif +-#if defined(CONFIG_MEDIA_CONTROLLER) ++ + ov9281->pad.flags = MEDIA_PAD_FL_SOURCE; +- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; +- ret = media_entity_init(&sd->entity, 1, &ov9281->pad, 0); ++ sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ++ ret = media_entity_pads_init(&sd->entity, 1, &ov9281->pad); + if (ret < 0) + goto err_power_off; +-#endif +- +- memset(facing, 0, sizeof(facing)); +- if (strcmp(ov9281->module_facing, "back") == 0) +- facing[0] = 'b'; +- else +- facing[0] = 'f'; + +- snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s", +- ov9281->module_index, facing, ++ snprintf(sd->name, sizeof(sd->name), "m%s %s", + OV9281_NAME, dev_name(sd->dev)); + ret = v4l2_async_register_subdev_sensor_common(sd); + if (ret) { +@@ -1118,9 +1007,7 @@ static int ov9281_probe(struct i2c_clien + return 0; + + err_clean_entity: +-#if defined(CONFIG_MEDIA_CONTROLLER) + media_entity_cleanup(&sd->entity); +-#endif + err_power_off: + __ov9281_power_off(ov9281); + err_free_handler: +@@ -1137,9 +1024,7 @@ static int ov9281_remove(struct i2c_clie + struct ov9281 *ov9281 = to_ov9281(sd); + + v4l2_async_unregister_subdev(sd); +-#if defined(CONFIG_MEDIA_CONTROLLER) + media_entity_cleanup(&sd->entity); +-#endif + v4l2_ctrl_handler_free(&ov9281->ctrl_handler); + mutex_destroy(&ov9281->mutex); + +@@ -1151,13 +1036,11 @@ static int ov9281_remove(struct i2c_clie + return 0; + } + +-#if IS_ENABLED(CONFIG_OF) + static const struct of_device_id ov9281_of_match[] = { + { .compatible = "ovti,ov9281" }, + {}, + }; + MODULE_DEVICE_TABLE(of, ov9281_of_match); +-#endif + + static const struct i2c_device_id ov9281_match_id[] = { + { "ovti,ov9281", 0 }, diff --git a/target/linux/bcm27xx/patches-5.4/950-0874-media-i2c-ov9281-Read-chip-ID-via-2-reads.patch b/target/linux/bcm27xx/patches-5.4/950-0874-media-i2c-ov9281-Read-chip-ID-via-2-reads.patch new file mode 100644 index 0000000000..0b06442a3e --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0874-media-i2c-ov9281-Read-chip-ID-via-2-reads.patch @@ -0,0 +1,42 @@ +From 5c6b7b60d7d607b59b4208e758180d4f93be8788 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Mon, 6 Jul 2020 17:51:32 +0100 +Subject: [PATCH] media: i2c: ov9281: Read chip ID via 2 reads + +Vision Components have made an OV9281 module which blocks reading +back the majority of registers to comply with NDAs, and in doing +so doesn't allow auto-increment register reading as used when +reading the chip ID. + +Use two reads and manually combine the results. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/i2c/ov9281.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +--- a/drivers/media/i2c/ov9281.c ++++ b/drivers/media/i2c/ov9281.c +@@ -904,13 +904,17 @@ static int ov9281_check_sensor_id(struct + struct i2c_client *client) + { + struct device *dev = &ov9281->client->dev; +- u32 id = 0; ++ u32 id = 0, id_msb; + int ret; + +- ret = ov9281_read_reg(client, OV9281_REG_CHIP_ID, +- OV9281_REG_VALUE_16BIT, &id); +- if (id != CHIP_ID) { +- dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret); ++ ret = ov9281_read_reg(client, OV9281_REG_CHIP_ID + 1, ++ OV9281_REG_VALUE_08BIT, &id); ++ if (!ret) ++ ret = ov9281_read_reg(client, OV9281_REG_CHIP_ID, ++ OV9281_REG_VALUE_08BIT, &id_msb); ++ id |= (id_msb << 8); ++ if (ret || id != CHIP_ID) { ++ dev_err(dev, "Unexpected sensor id(%04x), ret(%d)\n", id, ret); + return -ENODEV; + } + diff --git a/target/linux/bcm27xx/patches-5.4/950-0875-dtoverlay-Add-overlay-for-Omnivision-OV9281-image-se.patch b/target/linux/bcm27xx/patches-5.4/950-0875-dtoverlay-Add-overlay-for-Omnivision-OV9281-image-se.patch new file mode 100644 index 0000000000..c1664532ff --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0875-dtoverlay-Add-overlay-for-Omnivision-OV9281-image-se.patch @@ -0,0 +1,157 @@ +From 489b7fc3df2013766f3c4d5f682dcc7992950293 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Mon, 6 Jul 2020 17:32:21 +0100 +Subject: [PATCH] dtoverlay: Add overlay for Omnivision OV9281 image + sensor + +Adds an overlay for the OV9281 mono imaging sensor using 2 CSI-2 +data lanes. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 8 ++ + arch/arm/boot/dts/overlays/ov9281-overlay.dts | 110 ++++++++++++++++++ + 3 files changed, 119 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/ov9281-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -115,6 +115,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + mpu6050.dtbo \ + mz61581.dtbo \ + ov5647.dtbo \ ++ ov9281.dtbo \ + papirus.dtbo \ + pibell.dtbo \ + piglow.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1813,6 +1813,14 @@ Load: dtoverlay=ov5647 + Params: <None> + + ++Name: ov9281 ++Info: Omnivision OV9281 camera module. ++ Uses Unicam 1, which is the standard camera connector on most Pi ++ variants. ++Load: dtoverlay=ov9281 ++Params: <None> ++ ++ + Name: papirus + Info: PaPiRus ePaper Screen by Pi Supply (both HAT and pHAT) + Load: dtoverlay=papirus,<param>=<val> +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/ov9281-overlay.dts +@@ -0,0 +1,110 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++// Definitions for OV9281 camera module on VC I2C bus ++/dts-v1/; ++/plugin/; ++ ++#include <dt-bindings/gpio/gpio.h> ++ ++/{ ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&i2c_csi_dsi>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ ov9281: ov9281@60 { ++ compatible = "ovti,ov9281"; ++ reg = <0x60>; ++ status = "okay"; ++ ++ clocks = <&ov9281_clk>; ++ clock-names = "xvclk"; ++ ++ avdd-supply = <&ov9281_avdd>; ++ dovdd-supply = <&ov9281_dovdd>; ++ dvdd-supply = <&ov9281_dvdd>; ++ ++ port { ++ ov9281_0: endpoint { ++ remote-endpoint = <&csi1_ep>; ++ clock-lanes = <0>; ++ data-lanes = <1 2>; ++ clock-noncontinuous; ++ link-frequencies = ++ /bits/ 64 <456000000>; ++ }; ++ }; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&csi1>; ++ __overlay__ { ++ status = "okay"; ++ ++ port { ++ csi1_ep: endpoint { ++ remote-endpoint = <&ov9281_0>; ++ data-lanes = <1 2>; ++ }; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c0if>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@3 { ++ target-path="/"; ++ __overlay__ { ++ ov9281_avdd: fixedregulator@0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "ov9281_avdd"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ gpio = <&gpio 41 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ }; ++ ov9281_dovdd: fixedregulator@1 { ++ compatible = "regulator-fixed"; ++ regulator-name = "ov9281_dovdd"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ }; ++ ov9281_dvdd: fixedregulator@2 { ++ compatible = "regulator-fixed"; ++ regulator-name = "ov9281_dvdd"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ }; ++ ov9281_clk: ov9281-clk { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <24000000>; ++ }; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&i2c0mux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@5 { ++ target-path="/__overrides__"; ++ __overlay__ { ++ cam0-pwdn-ctrl = <&ov9281_avdd>,"gpio:0"; ++ cam0-pwdn = <&ov9281_avdd>,"gpio:4"; ++ }; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-5.4/950-0876-Bluetooth-hci_bcm-Fix-RTS-handling-during-startup.patch b/target/linux/bcm27xx/patches-5.4/950-0876-Bluetooth-hci_bcm-Fix-RTS-handling-during-startup.patch new file mode 100644 index 0000000000..a288f5ed3c --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0876-Bluetooth-hci_bcm-Fix-RTS-handling-during-startup.patch @@ -0,0 +1,33 @@ +From 44843cf006346751e42c0f4100eea7cefe61cbdf Mon Sep 17 00:00:00 2001 +From: Stefan Wahren <wahrenst@gmx.net> +Date: Sun, 6 Oct 2019 17:28:19 +0200 +Subject: [PATCH] Bluetooth: hci_bcm: Fix RTS handling during startup + +commit 3347a80965b38f096b1d6f995c00c9c9e53d4b8b upstream. + +The RPi 4 uses the hardware handshake lines for CYW43455, but the chip +doesn't react to HCI requests during DT probe. The reason is the inproper +handling of the RTS line during startup. According to the startup +signaling sequence in the CYW43455 datasheet, the hosts RTS line must +be driven after BT_REG_ON and BT_HOST_WAKE. + +Signed-off-by: Stefan Wahren <wahrenst@gmx.net> +Signed-off-by: Marcel Holtmann <marcel@holtmann.org> +--- + drivers/bluetooth/hci_bcm.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/bluetooth/hci_bcm.c ++++ b/drivers/bluetooth/hci_bcm.c +@@ -448,9 +448,11 @@ static int bcm_open(struct hci_uart *hu) + + out: + if (bcm->dev) { ++ hci_uart_set_flow_control(hu, true); + hu->init_speed = bcm->dev->init_speed; + hu->oper_speed = bcm->dev->oper_speed; + err = bcm_gpio_set_power(bcm->dev, true); ++ hci_uart_set_flow_control(hu, false); + if (err) + goto err_unset_hu; + } diff --git a/target/linux/bcm27xx/patches-5.4/950-0877-Bluetooth-hci_bcm-Add-compatible-string-for-BCM43540.patch b/target/linux/bcm27xx/patches-5.4/950-0877-Bluetooth-hci_bcm-Add-compatible-string-for-BCM43540.patch new file mode 100644 index 0000000000..f429b15a88 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0877-Bluetooth-hci_bcm-Add-compatible-string-for-BCM43540.patch @@ -0,0 +1,28 @@ +From 9ca6a4103585907a20b099f9627abfd7312f8f1c Mon Sep 17 00:00:00 2001 +From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> +Date: Fri, 25 Oct 2019 14:54:26 -0700 +Subject: [PATCH] Bluetooth: hci_bcm: Add compatible string for + BCM43540 + +commit d462af20dbfa1b9b1a831412f32d9d6757b82459 upstream. + +The BCM43540 chip is a 802.11 a/b/g/n/ac + Bluetooth 4.1 combo module. +This patch adds a compatible string match to the serdev driver for the +Bluetooth part of the chip. + +Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> +Signed-off-by: Marcel Holtmann <marcel@holtmann.org> +--- + drivers/bluetooth/hci_bcm.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/bluetooth/hci_bcm.c ++++ b/drivers/bluetooth/hci_bcm.c +@@ -1427,6 +1427,7 @@ static const struct of_device_id bcm_blu + { .compatible = "brcm,bcm4345c5" }, + { .compatible = "brcm,bcm4330-bt" }, + { .compatible = "brcm,bcm43438-bt" }, ++ { .compatible = "brcm,bcm43540-bt" }, + { }, + }; + MODULE_DEVICE_TABLE(of, bcm_bluetooth_of_match); diff --git a/target/linux/bcm27xx/patches-5.4/950-0878-Bluetooth-btbcm-Add-entry-for-BCM4335A0-UART-bluetoo.patch b/target/linux/bcm27xx/patches-5.4/950-0878-Bluetooth-btbcm-Add-entry-for-BCM4335A0-UART-bluetoo.patch new file mode 100644 index 0000000000..e2ad19b677 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0878-Bluetooth-btbcm-Add-entry-for-BCM4335A0-UART-bluetoo.patch @@ -0,0 +1,58 @@ +From 9dcea546a8f8ccd054e693b3ab124f49886de2ab Mon Sep 17 00:00:00 2001 +From: Mohammad Rasim <mohammad.rasim96@gmail.com> +Date: Wed, 20 Nov 2019 14:02:35 +0300 +Subject: [PATCH] Bluetooth: btbcm: Add entry for BCM4335A0 UART + bluetooth + +commit 1199ab4c9e1d4cdfbabd70b4aadbc8e72c691f65 upstream. + +This patch adds the device ID for the BCM4335A0 module +(part of the AMPAK AP6335 WIFI/Bluetooth combo) + +hciconfig output: +``` +hci1: Type: Primary Bus: UART + BD Address: 43:35:B0:07:1F:AC ACL MTU: 1021:8 SCO MTU: 64:1 + UP RUNNING + RX bytes:5079 acl:0 sco:0 events:567 errors:0 + TX bytes:69065 acl:0 sco:0 commands:567 errors:0 + Features: 0xbf 0xfe 0xcf 0xff 0xdf 0xff 0x7b 0x87 + Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3 + Link policy: RSWITCH SNIFF + Link mode: SLAVE ACCEPT + Name: 'alarm' + Class: 0x000000 + Service Classes: Unspecified + Device Class: Miscellaneous, + HCI Version: 4.0 (0x6) Revision: 0x161 + LMP Version: 4.0 (0x6) Subversion: 0x4106 + Manufacturer: Broadcom Corporation (15) +``` + +Signed-off-by: Mohammad Rasim <mohammad.rasim96@gmail.com> +Signed-off-by: Marcel Holtmann <marcel@holtmann.org> +--- + drivers/bluetooth/btbcm.c | 1 + + drivers/bluetooth/hci_bcm.c | 1 + + 2 files changed, 2 insertions(+) + +--- a/drivers/bluetooth/btbcm.c ++++ b/drivers/bluetooth/btbcm.c +@@ -340,6 +340,7 @@ static const struct bcm_subver_table bcm + { 0x220e, "BCM20702A1" }, /* 001.002.014 */ + { 0x4217, "BCM4329B1" }, /* 002.002.023 */ + { 0x6106, "BCM4359C0" }, /* 003.001.006 */ ++ { 0x4106, "BCM4335A0" }, /* 002.001.006 */ + { } + }; + +--- a/drivers/bluetooth/hci_bcm.c ++++ b/drivers/bluetooth/hci_bcm.c +@@ -1428,6 +1428,7 @@ static const struct of_device_id bcm_blu + { .compatible = "brcm,bcm4330-bt" }, + { .compatible = "brcm,bcm43438-bt" }, + { .compatible = "brcm,bcm43540-bt" }, ++ { .compatible = "brcm,bcm4335a0" }, + { }, + }; + MODULE_DEVICE_TABLE(of, bcm_bluetooth_of_match); diff --git a/target/linux/bcm27xx/patches-5.4/950-0879-Bluetooth-hci_bcm-Disallow-set_baudrate-for-BCM4354.patch b/target/linux/bcm27xx/patches-5.4/950-0879-Bluetooth-hci_bcm-Disallow-set_baudrate-for-BCM4354.patch new file mode 100644 index 0000000000..da8f37b3dd --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0879-Bluetooth-hci_bcm-Disallow-set_baudrate-for-BCM4354.patch @@ -0,0 +1,115 @@ +From 4c40c6ae0510be0fc9626d1717ff4163358cbfb2 Mon Sep 17 00:00:00 2001 +From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> +Date: Tue, 26 Nov 2019 08:17:29 +0100 +Subject: [PATCH] Bluetooth: hci_bcm: Disallow set_baudrate for + BCM4354 + +commit 5d6f391073d5c1c903ac12be72c66b96b2ae93f4 upstream. + +Without updating the patchram, the BCM4354 does not support a higher +operating speed. The normal bcm_setup follows the correct order +(init_speed, patchram and then oper_speed) but the serdev driver will +set the operating speed before calling the hu->setup function. Thus, +for the BCM4354, don't set the operating speed before patchram. + +Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> +Signed-off-by: Marcel Holtmann <marcel@holtmann.org> +Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> +--- + drivers/bluetooth/hci_bcm.c | 31 +++++++++++++++++++++++++++++-- + 1 file changed, 29 insertions(+), 2 deletions(-) + +--- a/drivers/bluetooth/hci_bcm.c ++++ b/drivers/bluetooth/hci_bcm.c +@@ -48,6 +48,14 @@ + #define BCM_NUM_SUPPLIES 2 + + /** ++ * struct bcm_device_data - device specific data ++ * @no_early_set_baudrate: Disallow set baudrate before driver setup() ++ */ ++struct bcm_device_data { ++ bool no_early_set_baudrate; ++}; ++ ++/** + * struct bcm_device - device driver resources + * @serdev_hu: HCI UART controller struct + * @list: bcm_device_list node +@@ -79,6 +87,7 @@ + * @hu: pointer to HCI UART controller struct, + * used to disable flow control during runtime suspend and system sleep + * @is_suspended: whether flow control is currently disabled ++ * @no_early_set_baudrate: don't set_baudrate before setup() + */ + struct bcm_device { + /* Must be the first member, hci_serdev.c expects this. */ +@@ -113,6 +122,7 @@ struct bcm_device { + struct hci_uart *hu; + bool is_suspended; + #endif ++ bool no_early_set_baudrate; + }; + + /* generic bcm uart resources */ +@@ -450,7 +460,13 @@ out: + if (bcm->dev) { + hci_uart_set_flow_control(hu, true); + hu->init_speed = bcm->dev->init_speed; +- hu->oper_speed = bcm->dev->oper_speed; ++ ++ /* If oper_speed is set, ldisc/serdev will set the baudrate ++ * before calling setup() ++ */ ++ if (!bcm->dev->no_early_set_baudrate) ++ hu->oper_speed = bcm->dev->oper_speed; ++ + err = bcm_gpio_set_power(bcm->dev, true); + hci_uart_set_flow_control(hu, false); + if (err) +@@ -568,6 +584,8 @@ static int bcm_setup(struct hci_uart *hu + /* Operational speed if any */ + if (hu->oper_speed) + speed = hu->oper_speed; ++ else if (bcm->dev && bcm->dev->oper_speed) ++ speed = bcm->dev->oper_speed; + else if (hu->proto->oper_speed) + speed = hu->proto->oper_speed; + else +@@ -1377,6 +1395,7 @@ static struct platform_driver bcm_driver + static int bcm_serdev_probe(struct serdev_device *serdev) + { + struct bcm_device *bcmdev; ++ const struct bcm_device_data *data; + int err; + + bcmdev = devm_kzalloc(&serdev->dev, sizeof(*bcmdev), GFP_KERNEL); +@@ -1411,6 +1430,10 @@ static int bcm_serdev_probe(struct serde + if (err) + dev_err(&serdev->dev, "Failed to power down\n"); + ++ data = device_get_match_data(bcmdev->dev); ++ if (data) ++ bcmdev->no_early_set_baudrate = data->no_early_set_baudrate; ++ + return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto); + } + +@@ -1422,12 +1445,16 @@ static void bcm_serdev_remove(struct ser + } + + #ifdef CONFIG_OF ++static struct bcm_device_data bcm4354_device_data = { ++ .no_early_set_baudrate = true, ++}; ++ + static const struct of_device_id bcm_bluetooth_of_match[] = { + { .compatible = "brcm,bcm20702a1" }, + { .compatible = "brcm,bcm4345c5" }, + { .compatible = "brcm,bcm4330-bt" }, + { .compatible = "brcm,bcm43438-bt" }, +- { .compatible = "brcm,bcm43540-bt" }, ++ { .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data }, + { .compatible = "brcm,bcm4335a0" }, + { }, + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0880-Bluetooth-btbcm-Support-pcm-configuration.patch b/target/linux/bcm27xx/patches-5.4/950-0880-Bluetooth-btbcm-Support-pcm-configuration.patch new file mode 100644 index 0000000000..2d40e7f5ac --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0880-Bluetooth-btbcm-Support-pcm-configuration.patch @@ -0,0 +1,124 @@ +From 6631d2076af26d2b5b6a3a2f17e8a33de48abcac Mon Sep 17 00:00:00 2001 +From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> +Date: Tue, 26 Nov 2019 08:17:30 +0100 +Subject: [PATCH] Bluetooth: btbcm: Support pcm configuration + +commit 528379902337102b0264fe5343eafb3d6c59fa45 upstream. + +Add BCM vendor specific command to configure PCM parameters. The new +vendor opcode allows us to set the sco routing, the pcm interface rate, +and a few other pcm specific options (frame sync, sync mode, and clock +mode). See broadcom-bluetooth.txt in Documentation for more information +about valid values for those settings. + +Here is an example trace where this opcode was used to configure +a BCM4354: + + < HCI Command: Vendor (0x3f|0x001c) plen 5 + 01 02 00 01 01 + > HCI Event: Command Complete (0x0e) plen 4 + Vendor (0x3f|0x001c) ncmd 1 + Status: Success (0x00) + +We can read back the values as well with ocf 0x001d to confirm the +values that were set: + $ hcitool cmd 0x3f 0x001d + < HCI Command: ogf 0x3f, ocf 0x001d, plen 0 + > HCI Event: 0x0e plen 9 + 01 1D FC 00 01 02 00 01 01 + +Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> +Signed-off-by: Marcel Holtmann <marcel@holtmann.org> +Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> +--- + drivers/bluetooth/btbcm.c | 46 +++++++++++++++++++++++++++++++++++++++ + drivers/bluetooth/btbcm.h | 16 ++++++++++++++ + 2 files changed, 62 insertions(+) + +--- a/drivers/bluetooth/btbcm.c ++++ b/drivers/bluetooth/btbcm.c +@@ -105,6 +105,52 @@ int btbcm_set_bdaddr(struct hci_dev *hde + } + EXPORT_SYMBOL_GPL(btbcm_set_bdaddr); + ++int btbcm_read_pcm_int_params(struct hci_dev *hdev, ++ struct bcm_set_pcm_int_params *params) ++{ ++ struct sk_buff *skb; ++ int err = 0; ++ ++ skb = __hci_cmd_sync(hdev, 0xfc1d, 0, NULL, HCI_INIT_TIMEOUT); ++ if (IS_ERR(skb)) { ++ err = PTR_ERR(skb); ++ bt_dev_err(hdev, "BCM: Read PCM int params failed (%d)", err); ++ return err; ++ } ++ ++ if (skb->len != 6 || skb->data[0]) { ++ bt_dev_err(hdev, "BCM: Read PCM int params length mismatch"); ++ kfree_skb(skb); ++ return -EIO; ++ } ++ ++ if (params) ++ memcpy(params, skb->data + 1, 5); ++ ++ kfree_skb(skb); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(btbcm_read_pcm_int_params); ++ ++int btbcm_write_pcm_int_params(struct hci_dev *hdev, ++ const struct bcm_set_pcm_int_params *params) ++{ ++ struct sk_buff *skb; ++ int err; ++ ++ skb = __hci_cmd_sync(hdev, 0xfc1c, 5, params, HCI_INIT_TIMEOUT); ++ if (IS_ERR(skb)) { ++ err = PTR_ERR(skb); ++ bt_dev_err(hdev, "BCM: Write PCM int params failed (%d)", err); ++ return err; ++ } ++ kfree_skb(skb); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(btbcm_write_pcm_int_params); ++ + int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw) + { + const struct hci_command_hdr *cmd; +--- a/drivers/bluetooth/btbcm.h ++++ b/drivers/bluetooth/btbcm.h +@@ -54,6 +54,10 @@ struct bcm_set_pcm_format_params { + int btbcm_check_bdaddr(struct hci_dev *hdev); + int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr); + int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw); ++int btbcm_read_pcm_int_params(struct hci_dev *hdev, ++ struct bcm_set_pcm_int_params *params); ++int btbcm_write_pcm_int_params(struct hci_dev *hdev, ++ const struct bcm_set_pcm_int_params *params); + + int btbcm_setup_patchram(struct hci_dev *hdev); + int btbcm_setup_apple(struct hci_dev *hdev); +@@ -73,6 +77,18 @@ static inline int btbcm_set_bdaddr(struc + { + return -EOPNOTSUPP; + } ++ ++int btbcm_read_pcm_int_params(struct hci_dev *hdev, ++ struct bcm_set_pcm_int_params *params) ++{ ++ return -EOPNOTSUPP; ++} ++ ++int btbcm_write_pcm_int_params(struct hci_dev *hdev, ++ const struct bcm_set_pcm_int_params *params) ++{ ++ return -EOPNOTSUPP; ++} + + static inline int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw) + { diff --git a/target/linux/bcm27xx/patches-5.4/950-0881-Bluetooth-hci_bcm-Support-pcm-params-in-dts.patch b/target/linux/bcm27xx/patches-5.4/950-0881-Bluetooth-hci_bcm-Support-pcm-params-in-dts.patch new file mode 100644 index 0000000000..fa2de56bfe --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0881-Bluetooth-hci_bcm-Support-pcm-params-in-dts.patch @@ -0,0 +1,74 @@ +From 8b4d7321625cc8403a9ce7f050bd8d1b4ef7446d Mon Sep 17 00:00:00 2001 +From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> +Date: Tue, 26 Nov 2019 08:17:32 +0100 +Subject: [PATCH] Bluetooth: hci_bcm: Support pcm params in dts + +commit eb762b94111b646b4f116ebfdbfcadbad14e12b3 upstream. + +BCM chips may require configuration of PCM to operate correctly and +there is a vendor specific HCI command to do this. Add support in the +hci_bcm driver to parse this from devicetree and configure the chip. + +Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> +Signed-off-by: Marcel Holtmann <marcel@holtmann.org> +Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> +--- + drivers/bluetooth/hci_bcm.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +--- a/drivers/bluetooth/hci_bcm.c ++++ b/drivers/bluetooth/hci_bcm.c +@@ -123,6 +123,7 @@ struct bcm_device { + bool is_suspended; + #endif + bool no_early_set_baudrate; ++ u8 pcm_int_params[5]; + }; + + /* generic bcm uart resources */ +@@ -597,6 +598,16 @@ static int bcm_setup(struct hci_uart *hu + host_set_baudrate(hu, speed); + } + ++ /* PCM parameters if provided */ ++ if (bcm->dev && bcm->dev->pcm_int_params[0] != 0xff) { ++ struct bcm_set_pcm_int_params params; ++ ++ btbcm_read_pcm_int_params(hu->hdev, ¶ms); ++ ++ memcpy(¶ms, bcm->dev->pcm_int_params, 5); ++ btbcm_write_pcm_int_params(hu->hdev, ¶ms); ++ } ++ + finalize: + release_firmware(fw); + +@@ -1134,6 +1145,8 @@ static int bcm_acpi_probe(struct bcm_dev + static int bcm_of_probe(struct bcm_device *bdev) + { + device_property_read_u32(bdev->dev, "max-speed", &bdev->oper_speed); ++ device_property_read_u8_array(bdev->dev, "brcm,bt-pcm-int-params", ++ bdev->pcm_int_params, 5); + return 0; + } + +@@ -1149,6 +1162,9 @@ static int bcm_probe(struct platform_dev + dev->dev = &pdev->dev; + dev->irq = platform_get_irq(pdev, 0); + ++ /* Initialize routing field to an unused value */ ++ dev->pcm_int_params[0] = 0xff; ++ + if (has_acpi_companion(&pdev->dev)) { + ret = bcm_acpi_probe(dev); + if (ret) +@@ -1409,6 +1425,9 @@ static int bcm_serdev_probe(struct serde + bcmdev->serdev_hu.serdev = serdev; + serdev_device_set_drvdata(serdev, bcmdev); + ++ /* Initialize routing field to an unused value */ ++ bcmdev->pcm_int_params[0] = 0xff; ++ + if (has_acpi_companion(&serdev->dev)) + err = bcm_acpi_probe(bcmdev); + else diff --git a/target/linux/bcm27xx/patches-5.4/950-0882-Bluetooth-hci_bcm-Drive-RTS-only-for-BCM43438.patch b/target/linux/bcm27xx/patches-5.4/950-0882-Bluetooth-hci_bcm-Drive-RTS-only-for-BCM43438.patch new file mode 100644 index 0000000000..507f21ab66 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0882-Bluetooth-hci_bcm-Drive-RTS-only-for-BCM43438.patch @@ -0,0 +1,92 @@ +From b2e19dbff471eb6b9b39ff8f21c8d38e4fac8fe6 Mon Sep 17 00:00:00 2001 +From: Stefan Wahren <wahrenst@gmx.net> +Date: Wed, 1 Jan 2020 15:01:34 +0100 +Subject: [PATCH] Bluetooth: hci_bcm: Drive RTS only for BCM43438 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit e601daed271e9eb1b923972a0a1af65f8c7bb77b upstream. + +The commit 3347a80965b3 ("Bluetooth: hci_bcm: Fix RTS handling during +startup") is causing at least a regression for AP6256 on Orange Pi 3. +So do the RTS line handing during startup only on the necessary platform. + +Fixes: 3347a80965b3 ("Bluetooth: hci_bcm: Fix RTS handling during startup") +Reported-by: OndÅ™ej Jirman <megous@megous.com> +Signed-off-by: Stefan Wahren <wahrenst@gmx.net> +Signed-off-by: Marcel Holtmann <marcel@holtmann.org> +--- + drivers/bluetooth/hci_bcm.c | 21 +++++++++++++++++---- + 1 file changed, 17 insertions(+), 4 deletions(-) + +--- a/drivers/bluetooth/hci_bcm.c ++++ b/drivers/bluetooth/hci_bcm.c +@@ -53,6 +53,7 @@ + */ + struct bcm_device_data { + bool no_early_set_baudrate; ++ bool drive_rts_on_open; + }; + + /** +@@ -123,6 +124,7 @@ struct bcm_device { + bool is_suspended; + #endif + bool no_early_set_baudrate; ++ bool drive_rts_on_open; + u8 pcm_int_params[5]; + }; + +@@ -459,7 +461,9 @@ static int bcm_open(struct hci_uart *hu) + + out: + if (bcm->dev) { +- hci_uart_set_flow_control(hu, true); ++ if (bcm->dev->drive_rts_on_open) ++ hci_uart_set_flow_control(hu, true); ++ + hu->init_speed = bcm->dev->init_speed; + + /* If oper_speed is set, ldisc/serdev will set the baudrate +@@ -469,7 +473,10 @@ out: + hu->oper_speed = bcm->dev->oper_speed; + + err = bcm_gpio_set_power(bcm->dev, true); +- hci_uart_set_flow_control(hu, false); ++ ++ if (bcm->dev->drive_rts_on_open) ++ hci_uart_set_flow_control(hu, false); ++ + if (err) + goto err_unset_hu; + } +@@ -1450,8 +1457,10 @@ static int bcm_serdev_probe(struct serde + dev_err(&serdev->dev, "Failed to power down\n"); + + data = device_get_match_data(bcmdev->dev); +- if (data) ++ if (data) { + bcmdev->no_early_set_baudrate = data->no_early_set_baudrate; ++ bcmdev->drive_rts_on_open = data->drive_rts_on_open; ++ } + + return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto); + } +@@ -1468,11 +1477,15 @@ static struct bcm_device_data bcm4354_de + .no_early_set_baudrate = true, + }; + ++static struct bcm_device_data bcm43438_device_data = { ++ .drive_rts_on_open = true, ++}; ++ + static const struct of_device_id bcm_bluetooth_of_match[] = { + { .compatible = "brcm,bcm20702a1" }, + { .compatible = "brcm,bcm4345c5" }, + { .compatible = "brcm,bcm4330-bt" }, +- { .compatible = "brcm,bcm43438-bt" }, ++ { .compatible = "brcm,bcm43438-bt", .data = &bcm43438_device_data }, + { .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data }, + { .compatible = "brcm,bcm4335a0" }, + { }, diff --git a/target/linux/bcm27xx/patches-5.4/950-0883-Enhances-the-DAC-driver-to-control-the-optional-head.patch b/target/linux/bcm27xx/patches-5.4/950-0883-Enhances-the-DAC-driver-to-control-the-optional-head.patch new file mode 100644 index 0000000000..128906026d --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0883-Enhances-the-DAC-driver-to-control-the-optional-head.patch @@ -0,0 +1,134 @@ +From defa915bf0acf6ab5e56997a6733546c33f87682 Mon Sep 17 00:00:00 2001 +From: Joerg Schambacher <joerg@i2audio.com> +Date: Tue, 7 Jul 2020 15:09:06 +0200 +Subject: [PATCH] Enhances the DAC+ driver to control the optional + headphone amplifier + +Probes on the I2C bus for TPA6130A2, if successful, it sets DT-parameter +'status' from 'disabled' to 'okay' using change_sets to enable +the headphone control. + +Signed-off-by: Joerg Schambacher joerg@i2audio.com +--- + sound/soc/bcm/Kconfig | 1 + + sound/soc/bcm/hifiberry_dacplus.c | 68 ++++++++++++++++++++++++++++++- + 2 files changed, 67 insertions(+), 2 deletions(-) + +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -38,6 +38,7 @@ config SND_BCM2708_SOC_HIFIBERRY_DACPLUS + tristate "Support for HifiBerry DAC+" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S + select SND_SOC_PCM512x ++ select SND_SOC_TPA6130A2 + select COMMON_CLK_HIFIBERRY_DACPRO + help + Say Y or M if you want to add support for HifiBerry DAC+. +--- a/sound/soc/bcm/hifiberry_dacplus.c ++++ b/sound/soc/bcm/hifiberry_dacplus.c +@@ -4,6 +4,7 @@ + * Author: Daniel Matuschek, Stuart MacLean <stuart@hifiberry.com> + * Copyright 2014-2015 + * based on code by Florian Meier <florian.meier@koalo.de> ++ * Headphone added by Joerg Schambacher, joerg@i2audio.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License +@@ -24,6 +25,7 @@ + #include <linux/of.h> + #include <linux/slab.h> + #include <linux/delay.h> ++#include <linux/i2c.h> + + #include <sound/core.h> + #include <sound/pcm.h> +@@ -177,8 +179,7 @@ static int snd_rpi_hifiberry_dacplus_ini + else + snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); + +- if (digital_gain_0db_limit) +- { ++ if (digital_gain_0db_limit) { + int ret; + struct snd_soc_card *card = rtd->card; + +@@ -292,6 +293,15 @@ static struct snd_soc_dai_link snd_rpi_h + }, + }; + ++/* aux device for optional headphone amp */ ++static struct snd_soc_aux_dev hifiberry_dacplus_aux_devs[] = { ++ { ++ .dlc = { ++ .name = "tpa6130a2.1-0060", ++ }, ++ }, ++}; ++ + /* audio machine driver */ + static struct snd_soc_card snd_rpi_hifiberry_dacplus = { + .name = "snd_rpi_hifiberry_dacplus", +@@ -301,9 +311,63 @@ static struct snd_soc_card snd_rpi_hifib + .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dacplus_dai), + }; + ++static int hb_hp_detect(void) ++{ ++ struct i2c_adapter *adap = i2c_get_adapter(1); ++ int ret; ++ ++ struct i2c_client tpa_i2c_client = { ++ .addr = 0x60, ++ .adapter = adap, ++ }; ++ ++ ret = i2c_smbus_read_byte(&tpa_i2c_client) >= 0; ++ i2c_put_adapter(adap); ++ return ret; ++}; ++ ++static struct property tpa_enable_prop = { ++ .name = "status", ++ .length = 4 + 1, /* length 'okay' + 1 */ ++ .value = "okay", ++ }; ++ + static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev) + { + int ret = 0; ++ struct snd_soc_card *card = &snd_rpi_hifiberry_dacplus; ++ int len; ++ struct device_node *tpa_node; ++ struct property *tpa_prop; ++ struct of_changeset ocs; ++ ++ /* probe for head phone amp */ ++ if (hb_hp_detect()) { ++ card->aux_dev = hifiberry_dacplus_aux_devs; ++ card->num_aux_devs = ++ ARRAY_SIZE(hifiberry_dacplus_aux_devs); ++ tpa_node = of_find_compatible_node(NULL, NULL, "ti,tpa6130a2"); ++ tpa_prop = of_find_property(tpa_node, "status", &len); ++ ++ if (strcmp((char *)tpa_prop->value, "okay")) { ++ /* and activate headphone using change_sets */ ++ dev_info(&pdev->dev, "activating headphone amplifier"); ++ of_changeset_init(&ocs); ++ ret = of_changeset_update_property(&ocs, tpa_node, ++ &tpa_enable_prop); ++ if (ret) { ++ dev_err(&pdev->dev, ++ "cannot activate headphone amplifier\n"); ++ return -ENODEV; ++ } ++ ret = of_changeset_apply(&ocs); ++ if (ret) { ++ dev_err(&pdev->dev, ++ "cannot activate headphone amplifier\n"); ++ return -ENODEV; ++ } ++ } ++ } + + snd_rpi_hifiberry_dacplus.dev = &pdev->dev; + if (pdev->dev.of_node) { diff --git a/target/linux/bcm27xx/patches-5.4/950-0884-ARM-dts-hifiberry-dacplus-headphone-amp-support.patch b/target/linux/bcm27xx/patches-5.4/950-0884-ARM-dts-hifiberry-dacplus-headphone-amp-support.patch new file mode 100644 index 0000000000..937d1040d0 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0884-ARM-dts-hifiberry-dacplus-headphone-amp-support.patch @@ -0,0 +1,24 @@ +From 3295a6b483ea507f8e5d19a806b7db1da1f5a567 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Wed, 8 Jul 2020 17:33:06 +0100 +Subject: [PATCH] ARM: dts: hifiberry-dacplus headphone amp support + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts ++++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts +@@ -39,6 +39,11 @@ + CPVDD-supply = <&vdd_3v3_reg>; + status = "okay"; + }; ++ hpamp: hpamp@60 { ++ compatible = "ti,tpa6130a2"; ++ reg = <0x60>; ++ status = "disabled"; ++ }; + }; + }; + diff --git a/target/linux/bcm27xx/patches-5.4/950-0885-media-i2c-imx290-Explicitly-set-v-h-blank-on-mode-ch.patch b/target/linux/bcm27xx/patches-5.4/950-0885-media-i2c-imx290-Explicitly-set-v-h-blank-on-mode-ch.patch new file mode 100644 index 0000000000..751f46db35 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0885-media-i2c-imx290-Explicitly-set-v-h-blank-on-mode-ch.patch @@ -0,0 +1,46 @@ +From 0a47c61cee411b3ada4413f6cebae8cdb06f062e Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 7 Jul 2020 10:31:53 +0100 +Subject: [PATCH] media: i2c: imx290: Explicitly set v&h blank on + mode change + +__v4l2_ctrl_modify_range only updates the current value should +it be invalid within the new range. That can leave modes producing +odd frame rates. + +Explicitly update the HBLANK and VBLANK values so that on mode +change we revert to the default frame rate for the mode. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/i2c/imx290.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -796,17 +796,23 @@ static int imx290_set_fmt(struct v4l2_su + __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate, + imx290_calc_pixel_rate(imx290)); + +- if (imx290->hblank) ++ if (imx290->hblank) { + __v4l2_ctrl_modify_range(imx290->hblank, + imx290->hmax_min - mode->width, + IMX290_HMAX_MAX - mode->width, + 1, mode->hmax - mode->width); +- if (imx290->vblank) ++ __v4l2_ctrl_s_ctrl(imx290->hblank, ++ mode->hmax - mode->width); ++ } ++ if (imx290->vblank) { + __v4l2_ctrl_modify_range(imx290->vblank, + mode->vmax - mode->height, + IMX290_VMAX_MAX - mode->height, + 1, + mode->vmax - mode->height); ++ __v4l2_ctrl_s_ctrl(imx290->vblank, ++ mode->vmax - mode->height); ++ } + if (imx290->exposure) + __v4l2_ctrl_modify_range(imx290->exposure, + mode->vmax - mode->height, diff --git a/target/linux/bcm27xx/patches-5.4/950-0886-media-i2c-imx290-Add-support-for-g_selection-to-repo.patch b/target/linux/bcm27xx/patches-5.4/950-0886-media-i2c-imx290-Add-support-for-g_selection-to-repo.patch new file mode 100644 index 0000000000..86680af234 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0886-media-i2c-imx290-Add-support-for-g_selection-to-repo.patch @@ -0,0 +1,156 @@ +From a191c6d6e5180f54ecf16adda61988a16ce9fe48 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 7 Jul 2020 11:23:48 +0100 +Subject: [PATCH] media: i2c: imx290: Add support for g_selection to + report cropping + +Userspace needs to know the cropping arrangements for each mode, +so expose this through g_selection. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/i2c/imx290.c | 84 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 84 insertions(+) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -61,6 +61,13 @@ enum imx290_clk_index { + #define IMX290_PGCTRL_THRU BIT(1) + #define IMX290_PGCTRL_MODE(n) ((n) << 4) + ++#define IMX290_NATIVE_WIDTH 1945U ++#define IMX290_NATIVE_HEIGHT 1109U ++#define IMX290_PIXEL_ARRAY_LEFT 4U ++#define IMX290_PIXEL_ARRAY_TOP 12U ++#define IMX290_PIXEL_ARRAY_WIDTH 1937U ++#define IMX290_PIXEL_ARRAY_HEIGHT 1097U ++ + static const char * const imx290_supply_name[] = { + "vdda", + "vddd", +@@ -80,6 +87,7 @@ struct imx290_mode { + u32 hmax; + u32 vmax; + u8 link_freq_index; ++ struct v4l2_rect crop; + + const struct imx290_regval *data; + u32 data_size; +@@ -384,6 +392,12 @@ static const struct imx290_mode imx290_m + .hmax = 0x1130, + .vmax = 0x0465, + .link_freq_index = FREQ_INDEX_1080P, ++ .crop = { ++ .left = 4 + 8, ++ .top = 12 + 8, ++ .width = 1920, ++ .height = 1080, ++ }, + .data = imx290_1080p_settings, + .data_size = ARRAY_SIZE(imx290_1080p_settings), + .clk_data = { +@@ -398,6 +412,12 @@ static const struct imx290_mode imx290_m + .hmax = 0x19c8, + .vmax = 0x02ee, + .link_freq_index = FREQ_INDEX_720P, ++ .crop = { ++ .left = 4 + 8 + 320, ++ .top = 12 + 8 + 180, ++ .width = 1280, ++ .height = 720, ++ }, + .data = imx290_720p_settings, + .data_size = ARRAY_SIZE(imx290_720p_settings), + .clk_data = { +@@ -415,6 +435,12 @@ static const struct imx290_mode imx290_m + .hmax = 0x0898, + .vmax = 0x0465, + .link_freq_index = FREQ_INDEX_1080P, ++ .crop = { ++ .left = 4 + 8, ++ .top = 12 + 8, ++ .width = 1920, ++ .height = 1080, ++ }, + .data = imx290_1080p_settings, + .data_size = ARRAY_SIZE(imx290_1080p_settings), + .clk_data = { +@@ -429,6 +455,12 @@ static const struct imx290_mode imx290_m + .hmax = 0x0ce4, + .vmax = 0x02ee, + .link_freq_index = FREQ_INDEX_720P, ++ .crop = { ++ .left = 4 + 8 + 320, ++ .top = 12 + 8 + 180, ++ .width = 1280, ++ .height = 720, ++ }, + .data = imx290_720p_settings, + .data_size = ARRAY_SIZE(imx290_720p_settings), + .clk_data = { +@@ -875,6 +907,57 @@ static int imx290_write_current_format(s + return 0; + } + ++static const struct v4l2_rect * ++__imx290_get_pad_crop(struct imx290 *imx290, struct v4l2_subdev_pad_config *cfg, ++ unsigned int pad, enum v4l2_subdev_format_whence which) ++{ ++ switch (which) { ++ case V4L2_SUBDEV_FORMAT_TRY: ++ return v4l2_subdev_get_try_crop(&imx290->sd, cfg, pad); ++ case V4L2_SUBDEV_FORMAT_ACTIVE: ++ return &imx290->current_mode->crop; ++ } ++ ++ return NULL; ++} ++ ++static int imx290_get_selection(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_selection *sel) ++{ ++ switch (sel->target) { ++ case V4L2_SEL_TGT_CROP: { ++ struct imx290 *imx290 = to_imx290(sd); ++ ++ mutex_lock(&imx290->lock); ++ sel->r = *__imx290_get_pad_crop(imx290, cfg, sel->pad, ++ sel->which); ++ mutex_unlock(&imx290->lock); ++ ++ return 0; ++ } ++ ++ case V4L2_SEL_TGT_NATIVE_SIZE: ++ sel->r.top = 0; ++ sel->r.left = 0; ++ sel->r.width = IMX290_NATIVE_WIDTH; ++ sel->r.height = IMX290_NATIVE_HEIGHT; ++ ++ return 0; ++ ++ case V4L2_SEL_TGT_CROP_DEFAULT: ++ case V4L2_SEL_TGT_CROP_BOUNDS: ++ sel->r.top = IMX290_PIXEL_ARRAY_TOP; ++ sel->r.left = IMX290_PIXEL_ARRAY_LEFT; ++ sel->r.width = IMX290_PIXEL_ARRAY_WIDTH; ++ sel->r.height = IMX290_PIXEL_ARRAY_HEIGHT; ++ ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ + /* Start streaming */ + static int imx290_start_streaming(struct imx290 *imx290) + { +@@ -1073,6 +1156,7 @@ static const struct v4l2_subdev_pad_ops + .enum_frame_size = imx290_enum_frame_size, + .get_fmt = imx290_get_fmt, + .set_fmt = imx290_set_fmt, ++ .get_selection = imx290_get_selection, + }; + + static const struct v4l2_subdev_ops imx290_subdev_ops = { diff --git a/target/linux/bcm27xx/patches-5.4/950-0887-media-i2c-imx290-Set-the-colorspace-fields-in-the-fo.patch b/target/linux/bcm27xx/patches-5.4/950-0887-media-i2c-imx290-Set-the-colorspace-fields-in-the-fo.patch new file mode 100644 index 0000000000..28c43cda52 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0887-media-i2c-imx290-Set-the-colorspace-fields-in-the-fo.patch @@ -0,0 +1,31 @@ +From b02ddac32c2bcd8894dac22de7ef1fb80a4dfe1a Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 7 Jul 2020 11:51:26 +0100 +Subject: [PATCH] media: i2c: imx290: Set the colorspace fields in + the format + +The colorspace fields were left untouched in imx290_set_fmt +which lead to a v4l2-compliance failure. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/i2c/imx290.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -813,6 +813,14 @@ static int imx290_set_fmt(struct v4l2_su + + fmt->format.code = imx290->formats[i].code; + fmt->format.field = V4L2_FIELD_NONE; ++ fmt->format.colorspace = V4L2_COLORSPACE_SRGB; ++ fmt->format.ycbcr_enc = ++ V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->format.colorspace); ++ fmt->format.quantization = ++ V4L2_MAP_QUANTIZATION_DEFAULT(true, fmt->format.colorspace, ++ fmt->format.ycbcr_enc); ++ fmt->format.xfer_func = ++ V4L2_MAP_XFER_FUNC_DEFAULT(fmt->format.colorspace); + + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { + format = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); diff --git a/target/linux/bcm27xx/patches-5.4/950-0888-media-bcm2835-unicam-Reinstate-V4L2_CAP_READWRITE-in.patch b/target/linux/bcm27xx/patches-5.4/950-0888-media-bcm2835-unicam-Reinstate-V4L2_CAP_READWRITE-in.patch new file mode 100644 index 0000000000..5b2b280b1e --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0888-media-bcm2835-unicam-Reinstate-V4L2_CAP_READWRITE-in.patch @@ -0,0 +1,28 @@ +From 6253cd2eee555c6b2779667cc41ee1d75aa85034 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 7 Jul 2020 14:23:40 +0100 +Subject: [PATCH] media: bcm2835-unicam: Reinstate V4L2_CAP_READWRITE + in the caps + +v4l2-compliance throws a failure if the device doesn't advertise +V4L2_CAP_READWRITE but allows read or write operations. +We do support read, so reinstate the flag. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/platform/bcm2835/bcm2835-unicam.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -2416,8 +2416,8 @@ static int register_node(struct unicam_d + vdev->queue = q; + vdev->lock = &node->lock; + vdev->device_caps = (pad_id == IMAGE_PAD) ? +- (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING) : +- (V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING); ++ V4L2_CAP_VIDEO_CAPTURE : V4L2_CAP_META_CAPTURE; ++ vdev->device_caps |= V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; + + /* Define the device names */ + snprintf(vdev->name, sizeof(vdev->name), "%s-%s", UNICAM_MODULE_NAME, diff --git a/target/linux/bcm27xx/patches-5.4/950-0889-media-bcm2835-unicam-Ensure-type-is-VIDEO_CAPTURE-in.patch b/target/linux/bcm27xx/patches-5.4/950-0889-media-bcm2835-unicam-Ensure-type-is-VIDEO_CAPTURE-in.patch new file mode 100644 index 0000000000..1e8407fca8 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0889-media-bcm2835-unicam-Ensure-type-is-VIDEO_CAPTURE-in.patch @@ -0,0 +1,36 @@ +From 470e49cf5ee0b77e6812595ca396e34af8ae67b4 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 7 Jul 2020 14:52:43 +0100 +Subject: [PATCH] media: bcm2835-unicam: Ensure type is VIDEO_CAPTURE + in [g|s]_selection + +[g|s]_selection pass in a buffer type that needs to be validated +before passing on to the sensor subdev. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/platform/bcm2835/bcm2835-unicam.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -1880,6 +1880,9 @@ static int unicam_s_selection(struct fil + .r = sel->r, + }; + ++ if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) ++ return -EINVAL; ++ + return v4l2_subdev_call(dev->sensor, pad, set_selection, NULL, &sdsel); + } + +@@ -1894,6 +1897,9 @@ static int unicam_g_selection(struct fil + }; + int ret; + ++ if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) ++ return -EINVAL; ++ + ret = v4l2_subdev_call(dev->sensor, pad, get_selection, NULL, &sdsel); + if (!ret) + sel->r = sdsel.r; diff --git a/target/linux/bcm27xx/patches-5.4/950-0890-dtoverlays-Create-an-overlay-for-the-Omnivision-OV72.patch b/target/linux/bcm27xx/patches-5.4/950-0890-dtoverlays-Create-an-overlay-for-the-Omnivision-OV72.patch new file mode 100644 index 0000000000..6a4da8f814 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0890-dtoverlays-Create-an-overlay-for-the-Omnivision-OV72.patch @@ -0,0 +1,157 @@ +From 870de3bc0e80a9b79b470a45636437a0078041c1 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 7 Jul 2020 16:12:05 +0100 +Subject: [PATCH] dtoverlays: Create an overlay for the Omnivision + OV7251 sensor + +Adds an overlay for the OV7251 VGA global shutter sensor. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 8 ++ + arch/arm/boot/dts/overlays/ov7251-overlay.dts | 111 ++++++++++++++++++ + 3 files changed, 120 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/ov7251-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -115,6 +115,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + mpu6050.dtbo \ + mz61581.dtbo \ + ov5647.dtbo \ ++ ov7251.dtbo \ + ov9281.dtbo \ + papirus.dtbo \ + pibell.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1813,6 +1813,14 @@ Load: dtoverlay=ov5647 + Params: <None> + + ++Name: ov7251 ++Info: Omnivision OV7251 camera module. ++ Uses Unicam 1, which is the standard camera connector on most Pi ++ variants. ++Load: dtoverlay=ov7251 ++Params: <None> ++ ++ + Name: ov9281 + Info: Omnivision OV9281 camera module. + Uses Unicam 1, which is the standard camera connector on most Pi +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/ov7251-overlay.dts +@@ -0,0 +1,111 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++// Definitions for OV7251 camera module on VC I2C bus ++/dts-v1/; ++/plugin/; ++ ++#include <dt-bindings/gpio/gpio.h> ++ ++/{ ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&i2c_csi_dsi>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ ov7251: ov7251@60 { ++ compatible = "ovti,ov7251"; ++ reg = <0x60>; ++ status = "okay"; ++ ++ clocks = <&ov7251_clk>; ++ clock-names = "xclk"; ++ clock-frequency = <24000000>; ++ ++ vdddo-supply = <&ov7251_dovdd>; ++ vdda-supply = <&ov7251_avdd>; ++ vddd-supply = <&ov7251_dvdd>; ++ ++ enable-gpios = <&gpio 41 GPIO_ACTIVE_HIGH>; ++ ++ port { ++ ov7251_0: endpoint { ++ remote-endpoint = <&csi1_ep>; ++ clock-lanes = <0>; ++ data-lanes = <1>; ++ clock-noncontinuous; ++ link-frequencies = ++ /bits/ 64 <456000000>; ++ }; ++ }; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&csi1>; ++ __overlay__ { ++ status = "okay"; ++ ++ port { ++ csi1_ep: endpoint { ++ remote-endpoint = <&ov7251_0>; ++ data-lanes = <1>; ++ }; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c0if>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@3 { ++ target-path="/"; ++ __overlay__ { ++ ov7251_avdd: fixedregulator@0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "ov7251_avdd"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ }; ++ ov7251_dovdd: fixedregulator@1 { ++ compatible = "regulator-fixed"; ++ regulator-name = "ov7251_dovdd"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ }; ++ ov7251_dvdd: fixedregulator@2 { ++ compatible = "regulator-fixed"; ++ regulator-name = "ov7251_dvdd"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ }; ++ ov7251_clk: ov7251-clk { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <24000000>; ++ }; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&i2c0mux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@5 { ++ target-path="/__overrides__"; ++ __overlay__ { ++ cam0-pwdn-ctrl = <&ov7251>,"enable-gpios:0"; ++ cam0-pwdn = <&ov7251>,"enable-gpios:4"; ++ }; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-5.4/950-0891-vc4_hdmi-Set-HDMI_MAI_FMT.patch b/target/linux/bcm27xx/patches-5.4/950-0891-vc4_hdmi-Set-HDMI_MAI_FMT.patch new file mode 100644 index 0000000000..2c305a0bff --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0891-vc4_hdmi-Set-HDMI_MAI_FMT.patch @@ -0,0 +1,124 @@ +From c9ba62745ba17d21542db28bf7dc28a39e19f7c2 Mon Sep 17 00:00:00 2001 +From: popcornmix <popcornmix@gmail.com> +Date: Tue, 10 Mar 2020 22:21:15 +0000 +Subject: [PATCH] vc4_hdmi: Set HDMI_MAI_FMT + +The hardware uses this for generating the right audio +data island packets when using formats other than PCM + +Signed-off-by: Dom Cobley <popcornmix@gmail.com> +--- + drivers/gpu/drm/vc4/vc4_hdmi.c | 47 ++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/vc4/vc4_regs.h | 31 ++++++++++++++++++++++ + 2 files changed, 78 insertions(+) + +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -917,6 +917,45 @@ static void vc4_hdmi_audio_shutdown(stru + vc4_hdmi->audio.substream = NULL; + } + ++static int sample_rate_to_mai_fmt(int samplerate) ++{ ++ switch(samplerate) ++ { ++ case 8000: ++ return VC4_HDMI_MAI_SAMPLE_RATE_8000; ++ case 11025: ++ return VC4_HDMI_MAI_SAMPLE_RATE_11025; ++ case 12000: ++ return VC4_HDMI_MAI_SAMPLE_RATE_12000; ++ case 16000: ++ return VC4_HDMI_MAI_SAMPLE_RATE_16000; ++ case 22050: ++ return VC4_HDMI_MAI_SAMPLE_RATE_22050; ++ case 24000: ++ return VC4_HDMI_MAI_SAMPLE_RATE_24000; ++ case 32000: ++ return VC4_HDMI_MAI_SAMPLE_RATE_32000; ++ case 44100: ++ return VC4_HDMI_MAI_SAMPLE_RATE_44100; ++ case 48000: ++ return VC4_HDMI_MAI_SAMPLE_RATE_48000; ++ case 64000: ++ return VC4_HDMI_MAI_SAMPLE_RATE_64000; ++ case 88200: ++ return VC4_HDMI_MAI_SAMPLE_RATE_88200; ++ case 96000: ++ return VC4_HDMI_MAI_SAMPLE_RATE_96000; ++ case 128000: ++ return VC4_HDMI_MAI_SAMPLE_RATE_128000; ++ case 176400: ++ return VC4_HDMI_MAI_SAMPLE_RATE_176400; ++ case 192000: ++ return VC4_HDMI_MAI_SAMPLE_RATE_192000; ++ default: ++ return VC4_HDMI_MAI_SAMPLE_RATE_NOT_INDICATED; ++ } ++} ++ + /* HDMI audio codec callbacks */ + static int vc4_hdmi_audio_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, +@@ -926,6 +965,8 @@ static int vc4_hdmi_audio_hw_params(stru + struct device *dev = &vc4_hdmi->pdev->dev; + u32 audio_packet_config, channel_mask; + u32 channel_map; ++ u32 mai_audio_format; ++ u32 mai_sample_rate; + + if (substream != vc4_hdmi->audio.substream) + return -EINVAL; +@@ -946,6 +987,12 @@ static int vc4_hdmi_audio_hw_params(stru + + vc4_hdmi_audio_set_mai_clock(vc4_hdmi); + ++ mai_sample_rate = sample_rate_to_mai_fmt(vc4_hdmi->audio.samplerate); ++ mai_audio_format = VC4_HDMI_MAI_FORMAT_PCM; ++ HDMI_WRITE(HDMI_MAI_FMT, ++ VC4_SET_FIELD(mai_sample_rate, VC4_HDMI_MAI_FORMAT_SAMPLE_RATE) | ++ VC4_SET_FIELD(mai_audio_format, VC4_HDMI_MAI_FORMAT_AUDIO_FORMAT)); ++ + /* The B frame identifier should match the value used by alsa-lib (8) */ + audio_packet_config = + VC4_HDMI_AUDIO_PACKET_ZERO_DATA_ON_SAMPLE_FLAT | +--- a/drivers/gpu/drm/vc4/vc4_regs.h ++++ b/drivers/gpu/drm/vc4/vc4_regs.h +@@ -516,6 +516,37 @@ + # define VC4_HDMI_AUDIO_PACKET_CEA_MASK_MASK VC4_MASK(7, 0) + # define VC4_HDMI_AUDIO_PACKET_CEA_MASK_SHIFT 0 + ++ ++# define VC4_HDMI_MAI_FORMAT_AUDIO_FORMAT_MASK VC4_MASK(23, 16) ++# define VC4_HDMI_MAI_FORMAT_AUDIO_FORMAT_SHIFT 16 ++ ++enum { ++ VC4_HDMI_MAI_FORMAT_PCM = 2, ++ VC4_HDMI_MAI_FORMAT_HBR = 200, ++}; ++ ++# define VC4_HDMI_MAI_FORMAT_SAMPLE_RATE_MASK VC4_MASK(15, 8) ++# define VC4_HDMI_MAI_FORMAT_SAMPLE_RATE_SHIFT 8 ++ ++enum { ++ VC4_HDMI_MAI_SAMPLE_RATE_NOT_INDICATED = 0, ++ VC4_HDMI_MAI_SAMPLE_RATE_8000 = 1, ++ VC4_HDMI_MAI_SAMPLE_RATE_11025 = 2, ++ VC4_HDMI_MAI_SAMPLE_RATE_12000 = 3, ++ VC4_HDMI_MAI_SAMPLE_RATE_16000 = 4, ++ VC4_HDMI_MAI_SAMPLE_RATE_22050 = 5, ++ VC4_HDMI_MAI_SAMPLE_RATE_24000 = 6, ++ VC4_HDMI_MAI_SAMPLE_RATE_32000 = 7, ++ VC4_HDMI_MAI_SAMPLE_RATE_44100 = 8, ++ VC4_HDMI_MAI_SAMPLE_RATE_48000 = 9, ++ VC4_HDMI_MAI_SAMPLE_RATE_64000 = 10, ++ VC4_HDMI_MAI_SAMPLE_RATE_88200 = 11, ++ VC4_HDMI_MAI_SAMPLE_RATE_96000 = 12, ++ VC4_HDMI_MAI_SAMPLE_RATE_128000 = 13, ++ VC4_HDMI_MAI_SAMPLE_RATE_176400 = 14, ++ VC4_HDMI_MAI_SAMPLE_RATE_192000 = 15, ++}; ++ + # define VC4_HDMI_RAM_PACKET_ENABLE BIT(16) + + /* When set, the CTS_PERIOD counts based on MAI bus sync pulse instead diff --git a/target/linux/bcm27xx/patches-5.4/950-0892-drm-vc4-add-iec958-controls-to-vc4_hdmi.patch b/target/linux/bcm27xx/patches-5.4/950-0892-drm-vc4-add-iec958-controls-to-vc4_hdmi.patch new file mode 100644 index 0000000000..bc5aacad88 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0892-drm-vc4-add-iec958-controls-to-vc4_hdmi.patch @@ -0,0 +1,119 @@ +From 209a350d81cded4ac83c31088d9e941c6497eb0e Mon Sep 17 00:00:00 2001 +From: Matthias Reichl <hias@horus.com> +Date: Tue, 17 Mar 2020 12:12:22 +0100 +Subject: [PATCH] drm/vc4: add iec958 controls to vc4_hdmi + +Although vc4 get an IEC958 formatted stream passed in from userspace +the driver needs the info from the channel status bits to properly +set up the hardware, eg for HBR passthrough. + +Add iec958 controls so the channel status bits can be passed in +from userspace. + +Signed-off-by: Matthias Reichl <hias@horus.com> +--- + drivers/gpu/drm/vc4/vc4_hdmi.c | 60 ++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/vc4/vc4_hdmi.h | 2 ++ + 2 files changed, 62 insertions(+) + +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -43,6 +43,7 @@ + #include <linux/pm_runtime.h> + #include <linux/rational.h> + #include <linux/reset.h> ++#include <sound/asoundef.h> + #include <sound/dmaengine_pcm.h> + #include <sound/pcm_drm_eld.h> + #include <sound/pcm_params.h> +@@ -1106,6 +1107,47 @@ static int vc4_hdmi_audio_eld_ctl_get(st + return 0; + } + ++static int vc4_spdif_info(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; ++ uinfo->count = 1; ++ return 0; ++} ++ ++static int vc4_spdif_playback_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); ++ struct vc4_hdmi *vc4_hdmi = snd_component_to_hdmi(component); ++ ++ memcpy(ucontrol->value.iec958.status, vc4_hdmi->audio.iec_status, ++ sizeof(vc4_hdmi->audio.iec_status)); ++ ++ return 0; ++} ++ ++static int vc4_spdif_playback_put(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); ++ struct vc4_hdmi *vc4_hdmi = snd_component_to_hdmi(component); ++ ++ memcpy(vc4_hdmi->audio.iec_status, ucontrol->value.iec958.status, ++ sizeof(vc4_hdmi->audio.iec_status)); ++ ++ return 0; ++} ++ ++static int vc4_spdif_mask_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ memset(ucontrol->value.iec958.status, 0xff, ++ FIELD_SIZEOF(struct vc4_hdmi_audio, iec_status)); ++ ++ return 0; ++} ++ + static const struct snd_kcontrol_new vc4_hdmi_audio_controls[] = { + { + .access = SNDRV_CTL_ELEM_ACCESS_READ | +@@ -1115,6 +1157,19 @@ static const struct snd_kcontrol_new vc4 + .info = vc4_hdmi_audio_eld_ctl_info, + .get = vc4_hdmi_audio_eld_ctl_get, + }, ++ { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), ++ .info = vc4_spdif_info, ++ .get = vc4_spdif_playback_get, ++ .put = vc4_spdif_playback_put, ++ }, ++ { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK), ++ .info = vc4_spdif_info, ++ .get = vc4_spdif_mask_get, ++ }, + }; + + static const struct snd_soc_dapm_widget vc4_hdmi_audio_widgets[] = { +@@ -1235,6 +1290,11 @@ static int vc4_hdmi_audio_init(struct vc + vc4_hdmi->audio.dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + vc4_hdmi->audio.dma_data.maxburst = 2; + ++ vc4_hdmi->audio.iec_status[0] = IEC958_AES0_CON_NOT_COPYRIGHT; ++ vc4_hdmi->audio.iec_status[1] = ++ IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER; ++ vc4_hdmi->audio.iec_status[3] = IEC958_AES3_CON_FS_48000; ++ + ret = devm_snd_dmaengine_pcm_register(dev, &pcm_conf, 0); + if (ret) { + dev_err(dev, "Could not register PCM component: %d\n", ret); +--- a/drivers/gpu/drm/vc4/vc4_hdmi.h ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.h +@@ -115,6 +115,8 @@ struct vc4_hdmi_audio { + struct snd_pcm_substream *substream; + + bool streaming; ++ ++ unsigned char iec_status[4]; + }; + + /* General HDMI hardware state. */ diff --git a/target/linux/bcm27xx/patches-5.4/950-0893-drm-vc4-move-setup-from-hw_params-to-prepare.patch b/target/linux/bcm27xx/patches-5.4/950-0893-drm-vc4-move-setup-from-hw_params-to-prepare.patch new file mode 100644 index 0000000000..1e63b34a3a --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0893-drm-vc4-move-setup-from-hw_params-to-prepare.patch @@ -0,0 +1,56 @@ +From 18b1ff043d713b6b3669a8746062f2faeb6c3557 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl <hias@horus.com> +Date: Thu, 19 Mar 2020 20:00:35 +0100 +Subject: [PATCH] drm/vc4: move setup from hw_params to prepare + +Configuring HDMI audio registers in prepare allows us to take +IEC958 bits into account which are set by the alsa hook after +the hw_params call. + +Signed-off-by: Matthias Reichl <hias@horus.com> +--- + drivers/gpu/drm/vc4/vc4_hdmi.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -958,8 +958,7 @@ static int sample_rate_to_mai_fmt(int sa + } + + /* HDMI audio codec callbacks */ +-static int vc4_hdmi_audio_hw_params(struct snd_pcm_substream *substream, +- struct snd_pcm_hw_params *params, ++static int vc4_hdmi_audio_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) + { + struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai); +@@ -972,12 +971,15 @@ static int vc4_hdmi_audio_hw_params(stru + if (substream != vc4_hdmi->audio.substream) + return -EINVAL; + +- dev_dbg(dev, "%s: %u Hz, %d bit, %d channels\n", __func__, +- params_rate(params), params_width(params), +- params_channels(params)); ++ dev_dbg(dev, "%s: %u Hz, %d bit, %d channels AES0=%02x\n", ++ __func__, ++ substream->runtime->rate, ++ snd_pcm_format_width(substream->runtime->format), ++ substream->runtime->channels, ++ vc4_hdmi->audio.iec_status[0]); + +- vc4_hdmi->audio.channels = params_channels(params); +- vc4_hdmi->audio.samplerate = params_rate(params); ++ vc4_hdmi->audio.channels = substream->runtime->channels; ++ vc4_hdmi->audio.samplerate = substream->runtime->rate; + + HDMI_WRITE(HDMI_MAI_CTL, + VC4_HD_MAI_CTL_RESET | +@@ -1196,7 +1198,7 @@ static const struct snd_soc_component_dr + static const struct snd_soc_dai_ops vc4_hdmi_audio_dai_ops = { + .startup = vc4_hdmi_audio_startup, + .shutdown = vc4_hdmi_audio_shutdown, +- .hw_params = vc4_hdmi_audio_hw_params, ++ .prepare = vc4_hdmi_audio_prepare, + .set_fmt = vc4_hdmi_audio_set_fmt, + .trigger = vc4_hdmi_audio_trigger, + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0894-drm-vc4-enable-HBR-MAI-format-on-HBR-streams.patch b/target/linux/bcm27xx/patches-5.4/950-0894-drm-vc4-enable-HBR-MAI-format-on-HBR-streams.patch new file mode 100644 index 0000000000..823e9ebab5 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0894-drm-vc4-enable-HBR-MAI-format-on-HBR-streams.patch @@ -0,0 +1,25 @@ +From 52beca6270b034cce84a738c71d36ffff7088389 Mon Sep 17 00:00:00 2001 +From: Dom Cobley <popcornmix@gmail.com> +Date: Fri, 10 Jul 2020 11:51:16 +0100 +Subject: [PATCH] drm/vc4: enable HBR MAI format on HBR streams + +Signed-off-by: Matthias Reichl <hias@horus.com> +--- + drivers/gpu/drm/vc4/vc4_hdmi.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -991,7 +991,11 @@ static int vc4_hdmi_audio_prepare(struct + vc4_hdmi_audio_set_mai_clock(vc4_hdmi); + + mai_sample_rate = sample_rate_to_mai_fmt(vc4_hdmi->audio.samplerate); +- mai_audio_format = VC4_HDMI_MAI_FORMAT_PCM; ++ if (vc4_hdmi->audio.iec_status[0] & IEC958_AES0_NONAUDIO && ++ vc4_hdmi->audio.channels == 8) ++ mai_audio_format = VC4_HDMI_MAI_FORMAT_HBR; ++ else ++ mai_audio_format = VC4_HDMI_MAI_FORMAT_PCM; + HDMI_WRITE(HDMI_MAI_FMT, + VC4_SET_FIELD(mai_sample_rate, VC4_HDMI_MAI_FORMAT_SAMPLE_RATE) | + VC4_SET_FIELD(mai_audio_format, VC4_HDMI_MAI_FORMAT_AUDIO_FORMAT)); diff --git a/target/linux/bcm27xx/patches-5.4/950-0895-vc4_hdmi-Remove-firmware-logic-for-MAI-threshold-set.patch b/target/linux/bcm27xx/patches-5.4/950-0895-vc4_hdmi-Remove-firmware-logic-for-MAI-threshold-set.patch new file mode 100644 index 0000000000..e08ceca15a --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0895-vc4_hdmi-Remove-firmware-logic-for-MAI-threshold-set.patch @@ -0,0 +1,47 @@ +From 5f22fca663178a49bbb72058ea9225d35b3d155d Mon Sep 17 00:00:00 2001 +From: Dom Cobley <popcornmix@gmail.com> +Date: Thu, 25 Jun 2020 18:48:40 +0100 +Subject: [PATCH] vc4_hdmi: Remove firmware logic for MAI threshold + setting + +This was a workaround for bugs in hardware on earlier Pi models +and wasn't totally successful. + +It makes audio quality worse on a Pi4 at the higher sample rates + +Signed-off-by: Dom Cobley <popcornmix@gmail.com> +--- + drivers/gpu/drm/vc4/vc4_hdmi.c | 22 ++++++---------------- + 1 file changed, 6 insertions(+), 16 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -1010,22 +1010,12 @@ static int vc4_hdmi_audio_prepare(struct + audio_packet_config |= VC4_SET_FIELD(channel_mask, + VC4_HDMI_AUDIO_PACKET_CEA_MASK); + +- /* Set the MAI threshold. This logic mimics the firmware's. */ +- if (vc4_hdmi->audio.samplerate > 96000) { +- HDMI_WRITE(HDMI_MAI_THR, +- VC4_SET_FIELD(0x12, VC4_HD_MAI_THR_DREQHIGH) | +- VC4_SET_FIELD(0x12, VC4_HD_MAI_THR_DREQLOW)); +- } else if (vc4_hdmi->audio.samplerate > 48000) { +- HDMI_WRITE(HDMI_MAI_THR, +- VC4_SET_FIELD(0x14, VC4_HD_MAI_THR_DREQHIGH) | +- VC4_SET_FIELD(0x12, VC4_HD_MAI_THR_DREQLOW)); +- } else { +- HDMI_WRITE(HDMI_MAI_THR, +- VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICHIGH) | +- VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICLOW) | +- VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQHIGH) | +- VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQLOW)); +- } ++ /* Set the MAI threshold */ ++ HDMI_WRITE(HDMI_MAI_THR, ++ VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICHIGH) | ++ VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICLOW) | ++ VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQHIGH) | ++ VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQLOW)); + + HDMI_WRITE(HDMI_MAI_CONFIG, + VC4_HDMI_MAI_CONFIG_BIT_REVERSE | diff --git a/target/linux/bcm27xx/patches-5.4/950-0896-vc_hdmi-Set-VC4_HDMI_MAI_CONFIG_FORMAT_REVERSE.patch b/target/linux/bcm27xx/patches-5.4/950-0896-vc_hdmi-Set-VC4_HDMI_MAI_CONFIG_FORMAT_REVERSE.patch new file mode 100644 index 0000000000..6fca81a53d --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0896-vc_hdmi-Set-VC4_HDMI_MAI_CONFIG_FORMAT_REVERSE.patch @@ -0,0 +1,24 @@ +From 203c14fa37c25a7d92c4f433ae918c6a7ce4f4db Mon Sep 17 00:00:00 2001 +From: Dom Cobley <popcornmix@gmail.com> +Date: Tue, 30 Jun 2020 11:23:49 +0100 +Subject: [PATCH] vc_hdmi: Set VC4_HDMI_MAI_CONFIG_FORMAT_REVERSE + +Without this bit set, HDMI_MAI_FORMAT doesn't pick up +the format and samplerate from DVP_CFG_MAI0_FMT and you +can't get HDMI_HDMI_13_AUDIO_STATUS_1 to indicate HBR mode + +Signed-off-by: Dom Cobley <popcornmix@gmail.com> +--- + drivers/gpu/drm/vc4/vc4_hdmi.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -1019,6 +1019,7 @@ static int vc4_hdmi_audio_prepare(struct + + HDMI_WRITE(HDMI_MAI_CONFIG, + VC4_HDMI_MAI_CONFIG_BIT_REVERSE | ++ VC4_HDMI_MAI_CONFIG_FORMAT_REVERSE | + VC4_SET_FIELD(channel_mask, VC4_HDMI_MAI_CHANNEL_MASK)); + + channel_map = vc4_hdmi->variant->channel_map(vc4_hdmi, channel_mask); diff --git a/target/linux/bcm27xx/patches-5.4/950-0897-dts-Enable-NO_WAIT_RESP-for-hdmi-audio-dma.patch b/target/linux/bcm27xx/patches-5.4/950-0897-dts-Enable-NO_WAIT_RESP-for-hdmi-audio-dma.patch new file mode 100644 index 0000000000..7e84dc41aa --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0897-dts-Enable-NO_WAIT_RESP-for-hdmi-audio-dma.patch @@ -0,0 +1,45 @@ +From 2318f056a6c740f66fdeb6b9f47cea319dcdeb20 Mon Sep 17 00:00:00 2001 +From: Dom Cobley <popcornmix@gmail.com> +Date: Thu, 2 Jul 2020 19:36:08 +0100 +Subject: [PATCH] dts: Enable NO_WAIT_RESP for hdmi audio dma + +Without this set, DVP_CFG_MAI0_CTL indicates occasional +DLATE errors when configured to 8 channel 192kHz + +Signed-off-by: Dom Cobley <popcornmix@gmail.com> +--- + arch/arm/boot/dts/bcm2711-rpi.dtsi | 4 ++-- + arch/arm/boot/dts/bcm2835-common.dtsi | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi +@@ -74,7 +74,7 @@ + clock-names = "hdmi"; + resets = <&dvp 0>; + ddc = <&ddc0>; +- dmas = <&dma 10>; ++ dmas = <&dma (10|(1<<27))>; + dma-names = "audio-rx"; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; +@@ -114,7 +114,7 @@ + clocks = <&firmware_clocks 13>; + clock-names = "hdmi"; + resets = <&dvp 1>; +- dmas = <&dma 17>; ++ dmas = <&dma (17|(1<<27))>; + dma-names = "audio-rx"; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; +--- a/arch/arm/boot/dts/bcm2835-common.dtsi ++++ b/arch/arm/boot/dts/bcm2835-common.dtsi +@@ -117,7 +117,7 @@ + clocks = <&clocks BCM2835_PLLH_PIX>, + <&clocks BCM2835_CLOCK_HSM>; + clock-names = "pixel", "hdmi"; +- dmas = <&dma 17>; ++ dmas = <&dma (17|(1<<27))>; + dma-names = "audio-rx"; + status = "disabled"; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0898-SQUASH-dts-Further-simplify-firmware-clocks.patch b/target/linux/bcm27xx/patches-5.4/950-0898-SQUASH-dts-Further-simplify-firmware-clocks.patch new file mode 100644 index 0000000000..eea0166476 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0898-SQUASH-dts-Further-simplify-firmware-clocks.patch @@ -0,0 +1,69 @@ +From af629960be92b1548d0b3c15b6e082930403fbae Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Fri, 10 Jul 2020 16:57:43 +0100 +Subject: [PATCH] SQUASH: dts: Further simplify firmware clocks + +All Pi platforms will use the firmware clocks driver, so declare it in +the most common place - bcm2835-rpi.dtsi. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2709-rpi.dtsi | 7 ------- + arch/arm/boot/dts/bcm2711-rpi.dtsi | 7 ------- + arch/arm/boot/dts/bcm2835-rpi.dtsi | 5 +++++ + arch/arm/boot/dts/bcm2836-rpi.dtsi | 7 ------- + 4 files changed, 5 insertions(+), 21 deletions(-) + +--- a/arch/arm/boot/dts/bcm2709-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2709-rpi.dtsi +@@ -3,10 +3,3 @@ + &vchiq { + compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq"; + }; +- +-&firmware { +- firmware_clocks: clocks { +- compatible = "raspberrypi,firmware-clocks"; +- #clock-cells = <1>; +- }; +-}; +--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi +@@ -309,10 +309,3 @@ + &hvs { + clocks = <&firmware_clocks 4>; + }; +- +-&firmware { +- firmware_clocks: clocks { +- compatible = "raspberrypi,firmware-clocks"; +- #clock-cells = <1>; +- }; +-}; +--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi +@@ -16,6 +16,11 @@ + compatible = "raspberrypi,bcm2835-firmware", "simple-bus"; + mboxes = <&mailbox>; + dma-ranges; ++ ++ firmware_clocks: clocks { ++ compatible = "raspberrypi,firmware-clocks"; ++ #clock-cells = <1>; ++ }; + }; + + power: power { +--- a/arch/arm/boot/dts/bcm2836-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2836-rpi.dtsi +@@ -4,10 +4,3 @@ + &vchiq { + compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq"; + }; +- +-&firmware { +- firmware_clocks: clocks { +- compatible = "raspberrypi,firmware-clocks"; +- #clock-cells = <1>; +- }; +-}; diff --git a/target/linux/bcm27xx/patches-5.4/950-0899-media-bcm2835-unicam-Set-VPU-min-clock-freq-to-250Mh.patch b/target/linux/bcm27xx/patches-5.4/950-0899-media-bcm2835-unicam-Set-VPU-min-clock-freq-to-250Mh.patch new file mode 100644 index 0000000000..788606cd8b --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0899-media-bcm2835-unicam-Set-VPU-min-clock-freq-to-250Mh.patch @@ -0,0 +1,154 @@ +From 09c1533f7f5dabd79aa2018083d1b71d26cd7eda Mon Sep 17 00:00:00 2001 +From: Naushir Patuck <naush@raspberrypi.com> +Date: Mon, 11 May 2020 13:02:22 +0100 +Subject: [PATCH] media: bcm2835: unicam: Set VPU min clock freq to + 250Mhz. + +When streaming with Unicam, the VPU must have a clock frequency of at +least 250Mhz. Otherwise, the input fifos could overrun, causing +image corruption. + +Signed-off-by: Naushir Patuck <naush@raspberrypi.com> +--- + arch/arm/boot/dts/bcm270x.dtsi | 10 ++-- + .../media/platform/bcm2835/bcm2835-unicam.c | 49 +++++++++++++++++-- + 2 files changed, 50 insertions(+), 9 deletions(-) + +--- a/arch/arm/boot/dts/bcm270x.dtsi ++++ b/arch/arm/boot/dts/bcm270x.dtsi +@@ -88,8 +88,9 @@ + reg = <0x7e800000 0x800>, + <0x7e802000 0x4>; + interrupts = <2 6>; +- clocks = <&clocks BCM2835_CLOCK_CAM0>; +- clock-names = "lp"; ++ clocks = <&clocks BCM2835_CLOCK_CAM0>, ++ <&firmware_clocks 4>; ++ clock-names = "lp", "vpu"; + power-domains = <&power RPI_POWER_DOMAIN_UNICAM0>; + #address-cells = <1>; + #size-cells = <0>; +@@ -102,8 +103,9 @@ + reg = <0x7e801000 0x800>, + <0x7e802004 0x4>; + interrupts = <2 7>; +- clocks = <&clocks BCM2835_CLOCK_CAM1>; +- clock-names = "lp"; ++ clocks = <&clocks BCM2835_CLOCK_CAM1>, ++ <&firmware_clocks 4>; ++ clock-names = "lp", "vpu"; + power-domains = <&power RPI_POWER_DOMAIN_UNICAM1>; + #address-cells = <1>; + #size-cells = <0>; +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -89,6 +89,11 @@ MODULE_PARM_DESC(debug, "Debug level 0-3 + v4l2_err(&(dev)->v4l2_dev, fmt, ##arg) + + /* ++ * Unicam must request a minimum of 250Mhz from the VPU clock. ++ * Otherwise the input FIFOs overrun and cause image corruption. ++ */ ++#define MIN_VPU_CLOCK_RATE (250 * 1000 * 1000) ++/* + * To protect against a dodgy sensor driver never returning an error from + * enum_mbus_code, set a maximum index value to be used. + */ +@@ -417,8 +422,10 @@ struct unicam_device { + void __iomem *base; + /* clock gating base address */ + void __iomem *clk_gate_base; +- /* clock handle */ ++ /* lp clock handle */ + struct clk *clock; ++ /* vpu clock handle */ ++ struct clk *vpu_clock; + /* V4l2 device */ + struct v4l2_device v4l2_dev; + struct media_device mdev; +@@ -1674,16 +1681,28 @@ static int unicam_start_streaming(struct + unicam_dbg(1, dev, "Running with %u data lanes\n", + dev->active_data_lanes); + +- ret = clk_set_rate(dev->clock, 100 * 1000 * 1000); ++ ret = clk_set_min_rate(dev->vpu_clock, MIN_VPU_CLOCK_RATE); ++ if (ret) { ++ unicam_err(dev, "failed to set up VPU clock\n"); ++ goto err_pm_put; ++ } ++ ++ ret = clk_prepare_enable(dev->vpu_clock); + if (ret) { +- unicam_err(dev, "failed to set up clock\n"); ++ unicam_err(dev, "Failed to enable VPU clock: %d\n", ret); + goto err_pm_put; + } + ++ ret = clk_set_rate(dev->clock, 100 * 1000 * 1000); ++ if (ret) { ++ unicam_err(dev, "failed to set up CSI clock\n"); ++ goto err_vpu_clock; ++ } ++ + ret = clk_prepare_enable(dev->clock); + if (ret) { + unicam_err(dev, "Failed to enable CSI clock: %d\n", ret); +- goto err_pm_put; ++ goto err_vpu_clock; + } + + for (i = 0; i < ARRAY_SIZE(dev->node); i++) { +@@ -1717,6 +1736,11 @@ static int unicam_start_streaming(struct + err_disable_unicam: + unicam_disable(dev); + clk_disable_unprepare(dev->clock); ++err_vpu_clock: ++ ret = clk_set_min_rate(dev->vpu_clock, 0); ++ if (ret) ++ unicam_err(dev, "failed to reset the VPU clock\n"); ++ clk_disable_unprepare(dev->vpu_clock); + err_pm_put: + unicam_runtime_put(dev); + err_streaming: +@@ -1734,6 +1758,8 @@ static void unicam_stop_streaming(struct + node->streaming = false; + + if (node->pad_id == IMAGE_PAD) { ++ int ret; ++ + /* + * Stop streaming the sensor and disable the peripheral. + * We cannot continue streaming embedded data with the +@@ -1743,6 +1769,12 @@ static void unicam_stop_streaming(struct + unicam_err(dev, "stream off failed in subdev\n"); + + unicam_disable(dev); ++ ++ ret = clk_set_min_rate(dev->vpu_clock, 0); ++ if (ret) ++ unicam_err(dev, "failed to reset the min VPU clock\n"); ++ ++ clk_disable_unprepare(dev->vpu_clock); + clk_disable_unprepare(dev->clock); + unicam_runtime_put(dev); + +@@ -2742,11 +2774,18 @@ static int unicam_probe(struct platform_ + + unicam->clock = devm_clk_get(&pdev->dev, "lp"); + if (IS_ERR(unicam->clock)) { +- unicam_err(unicam, "Failed to get clock\n"); ++ unicam_err(unicam, "Failed to get lp clock\n"); + ret = PTR_ERR(unicam->clock); + goto err_unicam_put; + } + ++ unicam->vpu_clock = devm_clk_get(&pdev->dev, "vpu"); ++ if (IS_ERR(unicam->vpu_clock)) { ++ unicam_err(unicam, "Failed to get vpu clock\n"); ++ ret = PTR_ERR(unicam->vpu_clock); ++ goto err_unicam_put; ++ } ++ + ret = platform_get_irq(pdev, 0); + if (ret <= 0) { + dev_err(&pdev->dev, "No IRQ resource\n"); diff --git a/target/linux/bcm27xx/patches-5.4/950-0900-dt-bindings-bcm2835-unicam-Update-documentation-with.patch b/target/linux/bcm27xx/patches-5.4/950-0900-dt-bindings-bcm2835-unicam-Update-documentation-with.patch new file mode 100644 index 0000000000..c8b53d6955 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0900-dt-bindings-bcm2835-unicam-Update-documentation-with.patch @@ -0,0 +1,38 @@ +From f747c5b5f35490ff177b8327ff1f7299f7d0bf4a Mon Sep 17 00:00:00 2001 +From: Naushir Patuck <naush@raspberrypi.com> +Date: Mon, 11 May 2020 13:06:27 +0100 +Subject: [PATCH] dt-bindings: bcm2835-unicam: Update documentation + with new clock params + +Update the documentation to reflect the new "VPU" clock needed +by the bcm2835-unicam driver. + +Signed-off-by: Naushir Patuck <naush@raspberrypi.com> +--- + .../devicetree/bindings/media/bcm2835-unicam.txt | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/Documentation/devicetree/bindings/media/bcm2835-unicam.txt ++++ b/Documentation/devicetree/bindings/media/bcm2835-unicam.txt +@@ -20,7 +20,7 @@ Required properties: + - interrupts : should contain the IRQ line for this Unicam instance. + - clocks : list of clock specifiers, corresponding to entries in + clock-names property. +-- clock-names : must contain an "lp" entry, matching entries in the ++- clock-names : must contain "lp" and "vpu" entries, matching entries in the + clocks property. + + Unicam supports a single port node. It should contain one 'port' child node +@@ -46,9 +46,9 @@ Example: + reg = <0x7e801000 0x800>, + <0x7e802004 0x4>; + interrupts = <2 7>; +- clocks = <&clocks BCM2835_CLOCK_CAM1>; +- clock-names = "lp"; +- ++ clocks = <&clocks BCM2835_CLOCK_CAM1>, ++ <&firmware_clocks 4>; ++ clock-names = "lp", "vpu"; + port { + csi1_ep: endpoint { + remote-endpoint = <&tc358743_0>; diff --git a/target/linux/bcm27xx/patches-5.4/950-0901-correct-SND_SOC_DAILINK_DEFS.patch b/target/linux/bcm27xx/patches-5.4/950-0901-correct-SND_SOC_DAILINK_DEFS.patch new file mode 100644 index 0000000000..6823283d0f --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0901-correct-SND_SOC_DAILINK_DEFS.patch @@ -0,0 +1,21 @@ +From b27a6e98851f8889f8d9059bfebb91014ac7b057 Mon Sep 17 00:00:00 2001 +From: AMuszkat <ariel.muszkat@gmail.com> +Date: Tue, 14 Jul 2020 17:51:03 +0200 +Subject: [PATCH] correct SND_SOC_DAILINK_DEFS + +Signed-off-by: AMuszkat <ariel.muszkat@gmail.com> +--- + sound/soc/bcm/rpi-simple-soundcard.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/soc/bcm/rpi-simple-soundcard.c ++++ b/sound/soc/bcm/rpi-simple-soundcard.c +@@ -235,7 +235,7 @@ static struct snd_rpi_simple_drvdata drv + + SND_SOC_DAILINK_DEFS(merus_amp, + DAILINK_COMP_ARRAY(COMP_EMPTY()), +- DAILINK_COMP_ARRAY(COMP_CODEC("ma120x0p-amp", "ma120x0p.1-0020")), ++ DAILINK_COMP_ARRAY(COMP_CODEC("ma120x0p.1-0020","ma120x0p-amp")), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + + static struct snd_soc_dai_link snd_merus_amp_dai[] = { diff --git a/target/linux/bcm27xx/patches-5.4/950-0902-media-dt-bindings-video-interfaces-Document-orientat.patch b/target/linux/bcm27xx/patches-5.4/950-0902-media-dt-bindings-video-interfaces-Document-orientat.patch new file mode 100644 index 0000000000..de2fd156dd --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0902-media-dt-bindings-video-interfaces-Document-orientat.patch @@ -0,0 +1,43 @@ +From cc7d8104a44cf0ad67081f9ad0efd0e260a2379b Mon Sep 17 00:00:00 2001 +From: Jacopo Mondi <jacopo@jmondi.org> +Date: Sat, 9 May 2020 11:04:44 +0200 +Subject: [PATCH] media: dt-bindings: video-interfaces: Document + 'orientation' property + +Add the 'orientation' device property, used to specify the device mounting +position. The property is particularly meaningful for mobile devices +with a well defined usage orientation. + +Reviewed-by: Rob Herring <robh@kernel.org> +Acked-by: Tomasz Figa <tfiga@chromium.org> +Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> + +Commit cabc918e5b877ed547e5b6463f5ea6e3ac4edbb3 upstream + +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +--- + .../devicetree/bindings/media/video-interfaces.txt | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/Documentation/devicetree/bindings/media/video-interfaces.txt ++++ b/Documentation/devicetree/bindings/media/video-interfaces.txt +@@ -89,6 +89,17 @@ Optional properties + but a number of degrees counter clockwise. Typical values are 0 and 180 + (upside down). + ++- orientation: The orientation of a device (typically an image sensor or a flash ++ LED) describing its mounting position relative to the usage orientation of the ++ system where the device is installed on. ++ Possible values are: ++ 0 - Front. The device is mounted on the front facing side of the system. ++ For mobile devices such as smartphones, tablets and laptops the front side is ++ the user facing side. ++ 1 - Back. The device is mounted on the back side of the system, which is ++ defined as the opposite side of the front facing one. ++ 2 - External. The device is not attached directly to the system but is ++ attached in a way that allows it to move freely. + + Optional endpoint properties + ---------------------------- diff --git a/target/linux/bcm27xx/patches-5.4/950-0903-media-dt-bindings-video-interface-Replace-rotation-d.patch b/target/linux/bcm27xx/patches-5.4/950-0903-media-dt-bindings-video-interface-Replace-rotation-d.patch new file mode 100644 index 0000000000..a070c2a897 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0903-media-dt-bindings-video-interface-Replace-rotation-d.patch @@ -0,0 +1,390 @@ +From 1af1c75a6965dd975d40e904e921d9f07395ffcb Mon Sep 17 00:00:00 2001 +From: Jacopo Mondi <jacopo@jmondi.org> +Date: Sat, 9 May 2020 11:04:45 +0200 +Subject: [PATCH] media: dt-bindings: video-interface: Replace + 'rotation' description + +Replace the 'rotation' property description by providing a definition +relative to the camera sensor pixel array coordinate system and the +captured scene. + +Acked-by: Rob Herring <robh@kernel.org> +Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> + +Commit 915bd31ce9ed328535e5ecf3ca730c5764ec1a38 upstream + +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +--- + .../bindings/media/video-interfaces.txt | 359 +++++++++++++++++- + 1 file changed, 356 insertions(+), 3 deletions(-) + +--- a/Documentation/devicetree/bindings/media/video-interfaces.txt ++++ b/Documentation/devicetree/bindings/media/video-interfaces.txt +@@ -85,9 +85,362 @@ Optional properties + + - lens-focus: A phandle to the node of the focus lens controller. + +-- rotation: The device, typically an image sensor, is not mounted upright, +- but a number of degrees counter clockwise. Typical values are 0 and 180 +- (upside down). ++- rotation: The camera rotation is expressed as the angular difference in ++ degrees between two reference systems, one relative to the camera module, and ++ one defined on the external world scene to be captured when projected on the ++ image sensor pixel array. ++ ++ A camera sensor has a 2-dimensional reference system 'Rc' defined by ++ its pixel array read-out order. The origin is set to the first pixel ++ being read out, the X-axis points along the column read-out direction ++ towards the last columns, and the Y-axis along the row read-out ++ direction towards the last row. ++ ++ A typical example for a sensor with a 2592x1944 pixel array matrix ++ observed from the front is: ++ ++ 2591 X-axis 0 ++ <------------------------+ 0 ++ .......... ... ..........! ++ .......... ... ..........! Y-axis ++ ... ! ++ .......... ... ..........! ++ .......... ... ..........! 1943 ++ V ++ ++ The external world scene reference system 'Rs' is a 2-dimensional ++ reference system on the focal plane of the camera module. The origin is ++ placed on the top-left corner of the visible scene, the X-axis points ++ towards the right, and the Y-axis points towards the bottom of the ++ scene. The top, bottom, left and right directions are intentionally not ++ defined and depend on the environment in which the camera is used. ++ ++ A typical example of a (very common) picture of a shark swimming from ++ left to right, as seen from the camera, is: ++ ++ 0 X-axis ++ 0 +-------------------------------------> ++ ! ++ ! ++ ! ++ ! |\____)\___ ++ ! ) _____ __`< ++ ! |/ )/ ++ ! ++ ! ++ ! ++ V ++ Y-axis ++ ++ with the reference system 'Rs' placed on the camera focal plane: ++ ++ ¸.·˙! ++ ¸.·˙ ! ++ _ ¸.·˙ ! ++ +-/ \-+¸.·˙ ! ++ | (o) | ! Camera focal plane ++ +-----+˙·.¸ ! ++ ˙·.¸ ! ++ ˙·.¸ ! ++ ˙·.¸! ++ ++ When projected on the sensor's pixel array, the image and the associated ++ reference system 'Rs' are typically (but not always) inverted, due to ++ the camera module's lens optical inversion effect. ++ ++ Assuming the above represented scene of the swimming shark, the lens ++ inversion projects the scene and its reference system onto the sensor ++ pixel array, seen from the front of the camera sensor, as follows: ++ ++ Y-axis ++ ^ ++ ! ++ ! ++ ! ++ ! |\_____)\__ ++ ! ) ____ ___.< ++ ! |/ )/ ++ ! ++ ! ++ ! ++ 0 +-------------------------------------> ++ 0 X-axis ++ ++ Note the shark being upside-down. ++ ++ The resulting projected reference system is named 'Rp'. ++ ++ The camera rotation property is then defined as the angular difference ++ in the counter-clockwise direction between the camera reference system ++ 'Rc' and the projected scene reference system 'Rp'. It is expressed in ++ degrees as a number in the range [0, 360[. ++ ++ Examples ++ ++ 0 degrees camera rotation: ++ ++ ++ Y-Rp ++ ^ ++ Y-Rc ! ++ ^ ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! 0 +-------------------------------------> ++ ! 0 X-Rp ++ 0 +-------------------------------------> ++ 0 X-Rc ++ ++ ++ X-Rc 0 ++ <------------------------------------+ 0 ++ X-Rp 0 ! ++ <------------------------------------+ 0 ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! V ++ ! Y-Rc ++ V ++ Y-Rp ++ ++ 90 degrees camera rotation: ++ ++ 0 Y-Rc ++ 0 +--------------------> ++ ! Y-Rp ++ ! ^ ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! 0 +-------------------------------------> ++ ! 0 X-Rp ++ ! ++ ! ++ ! ++ ! ++ V ++ X-Rc ++ ++ 180 degrees camera rotation: ++ ++ 0 ++ <------------------------------------+ 0 ++ X-Rc ! ++ Y-Rp ! ++ ^ ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! V ++ ! Y-Rc ++ 0 +-------------------------------------> ++ 0 X-Rp ++ ++ 270 degrees camera rotation: ++ ++ 0 Y-Rc ++ 0 +--------------------> ++ ! 0 ++ ! <-----------------------------------+ 0 ++ ! X-Rp ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! ! ++ ! V ++ ! Y-Rp ++ ! ++ ! ++ ! ++ ! ++ V ++ X-Rc ++ ++ ++ Example one - Webcam ++ ++ A camera module installed on the user facing part of a laptop screen ++ casing used for video calls. The captured images are meant to be ++ displayed in landscape mode (width > height) on the laptop screen. ++ ++ The camera is typically mounted upside-down to compensate the lens ++ optical inversion effect: ++ ++ Y-Rp ++ Y-Rc ^ ++ ^ ! ++ ! ! ++ ! ! |\_____)\__ ++ ! ! ) ____ ___.< ++ ! ! |/ )/ ++ ! ! ++ ! ! ++ ! ! ++ ! 0 +-------------------------------------> ++ ! 0 X-Rp ++ 0 +-------------------------------------> ++ 0 X-Rc ++ ++ The two reference systems are aligned, the resulting camera rotation is ++ 0 degrees, no rotation correction needs to be applied to the resulting ++ image once captured to memory buffers to correctly display it to users: ++ ++ +--------------------------------------+ ++ ! ! ++ ! ! ++ ! ! ++ ! |\____)\___ ! ++ ! ) _____ __`< ! ++ ! |/ )/ ! ++ ! ! ++ ! ! ++ ! ! ++ +--------------------------------------+ ++ ++ If the camera sensor is not mounted upside-down to compensate for the ++ lens optical inversion, the two reference systems will not be aligned, ++ with 'Rp' being rotated 180 degrees relatively to 'Rc': ++ ++ ++ X-Rc 0 ++ <------------------------------------+ 0 ++ ! ++ Y-Rp ! ++ ^ ! ++ ! ! ++ ! |\_____)\__ ! ++ ! ) ____ ___.< ! ++ ! |/ )/ ! ++ ! ! ++ ! ! ++ ! V ++ ! Y-Rc ++ 0 +-------------------------------------> ++ 0 X-Rp ++ ++ The image once captured to memory will then be rotated by 180 degrees: ++ ++ +--------------------------------------+ ++ ! ! ++ ! ! ++ ! ! ++ ! __/(_____/| ! ++ ! >.___ ____ ( ! ++ ! \( \| ! ++ ! ! ++ ! ! ++ ! ! ++ +--------------------------------------+ ++ ++ A software rotation correction of 180 degrees should be applied to ++ correctly display the image: ++ ++ +--------------------------------------+ ++ ! ! ++ ! ! ++ ! ! ++ ! |\____)\___ ! ++ ! ) _____ __`< ! ++ ! |/ )/ ! ++ ! ! ++ ! ! ++ ! ! ++ +--------------------------------------+ ++ ++ Example two - Phone camera ++ ++ A camera installed on the back side of a mobile device facing away from ++ the user. The captured images are meant to be displayed in portrait mode ++ (height > width) to match the device screen orientation and the device ++ usage orientation used when taking the picture. ++ ++ The camera sensor is typically mounted with its pixel array longer side ++ aligned to the device longer side, upside-down mounted to compensate for ++ the lens optical inversion effect: ++ ++ 0 Y-Rc ++ 0 +--------------------> ++ ! Y-Rp ++ ! ^ ++ ! ! ++ ! ! ++ ! ! ++ ! ! |\_____)\__ ++ ! ! ) ____ ___.< ++ ! ! |/ )/ ++ ! ! ++ ! ! ++ ! ! ++ ! 0 +-------------------------------------> ++ ! 0 X-Rp ++ ! ++ ! ++ ! ++ ! ++ V ++ X-Rc ++ ++ The two reference systems are not aligned and the 'Rp' reference ++ system is rotated by 90 degrees in the counter-clockwise direction ++ relatively to the 'Rc' reference system. ++ ++ The image once captured to memory will be rotated: ++ ++ +-------------------------------------+ ++ | _ _ | ++ | \ / | ++ | | | | ++ | | | | ++ | | > | ++ | < | | ++ | | | | ++ | . | ++ | V | ++ +-------------------------------------+ ++ ++ A correction of 90 degrees in counter-clockwise direction has to be ++ applied to correctly display the image in portrait mode on the device ++ screen: ++ ++ +--------------------+ ++ | | ++ | | ++ | | ++ | | ++ | | ++ | | ++ | |\____)\___ | ++ | ) _____ __`< | ++ | |/ )/ | ++ | | ++ | | ++ | | ++ | | ++ | | ++ +--------------------+ + + - orientation: The orientation of a device (typically an image sensor or a flash + LED) describing its mounting position relative to the usage orientation of the diff --git a/target/linux/bcm27xx/patches-5.4/950-0904-media-v4l2-ctrl-Document-V4L2_CID_CAMERA_ORIENTATION.patch b/target/linux/bcm27xx/patches-5.4/950-0904-media-v4l2-ctrl-Document-V4L2_CID_CAMERA_ORIENTATION.patch new file mode 100644 index 0000000000..9516e653ab --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0904-media-v4l2-ctrl-Document-V4L2_CID_CAMERA_ORIENTATION.patch @@ -0,0 +1,61 @@ +From 16a7ef36055e414560143ebcb95113f9513ca49d Mon Sep 17 00:00:00 2001 +From: Jacopo Mondi <jacopo@jmondi.org> +Date: Sat, 9 May 2020 11:04:46 +0200 +Subject: [PATCH] media: v4l2-ctrl: Document + V4L2_CID_CAMERA_ORIENTATION + +Add documentation for the V4L2_CID_CAMERA_ORIENTATION camera +control. The newly added read-only control reports the camera device +orientation relative to the usage orientation of the system the camera +is installed on. + +Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> + +Commit 9397a83f40183eeafd5c787af2240ed0d6b26daa upstream + +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +--- + .../media/uapi/v4l/ext-ctrls-camera.rst | 30 +++++++++++++++++++ + 1 file changed, 30 insertions(+) + +--- a/Documentation/media/uapi/v4l/ext-ctrls-camera.rst ++++ b/Documentation/media/uapi/v4l/ext-ctrls-camera.rst +@@ -510,6 +510,36 @@ enum v4l2_scene_mode - + value down. A value of zero stops the motion if one is in progress + and has no effect otherwise. + ++``V4L2_CID_CAMERA_ORIENTATION (menu)`` ++ This read-only control describes the camera orientation by reporting its ++ mounting position on the device where the camera is installed. The control ++ value is constant and not modifiable by software. This control is ++ particularly meaningful for devices which have a well defined orientation, ++ such as phones, laptops and portable devices since the control is expressed ++ as a position relative to the device's intended usage orientation. For ++ example, a camera installed on the user-facing side of a phone, a tablet or ++ a laptop device is said to be have ``V4L2_CAMERA_ORIENTATION_FRONT`` ++ orientation, while a camera installed on the opposite side of the front one ++ is said to be have ``V4L2_CAMERA_ORIENTATION_BACK`` orientation. Camera ++ sensors not directly attached to the device, or attached in a way that ++ allows them to move freely, such as webcams and digital cameras, are said to ++ have the ``V4L2_CAMERA_ORIENTATION_EXTERNAL`` orientation. ++ ++ ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ ++ * - ``V4L2_CAMERA_ORIENTATION_FRONT`` ++ - The camera is oriented towards the user facing side of the device. ++ * - ``V4L2_CAMERA_ORIENTATION_BACK`` ++ - The camera is oriented towards the back facing side of the device. ++ * - ``V4L2_CAMERA_ORIENTATION_EXTERNAL`` ++ - The camera is not directly attached to the device and is freely movable. ++ ++ ++ + .. [#f1] + This control may be changed to a menu control in the future, if more + options are required. diff --git a/target/linux/bcm27xx/patches-5.4/950-0905-media-v4l2-ctrl-Document-V4L2_CID_CAMERA_SENSOR_ROTA.patch b/target/linux/bcm27xx/patches-5.4/950-0905-media-v4l2-ctrl-Document-V4L2_CID_CAMERA_SENSOR_ROTA.patch new file mode 100644 index 0000000000..9be7e6a368 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0905-media-v4l2-ctrl-Document-V4L2_CID_CAMERA_SENSOR_ROTA.patch @@ -0,0 +1,151 @@ +From 00d84a43c7042b55e81d0818b0d1a6e44c6f79b5 Mon Sep 17 00:00:00 2001 +From: Jacopo Mondi <jacopo@jmondi.org> +Date: Sat, 9 May 2020 11:04:47 +0200 +Subject: [PATCH] media: v4l2-ctrl: Document + V4L2_CID_CAMERA_SENSOR_ROTATION + +Add documentation for the V4L2_CID_CAMERA_SENSOR_ROTATION camera +control. The newly added read-only control reports the rotation +correction to be applied to images before displaying them to the user. + +Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> + +Commit 9926c2248740a632b0629fd8c07d0fc361dc15cc upstream + +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +--- + .../media/uapi/v4l/ext-ctrls-camera.rst | 121 ++++++++++++++++++ + 1 file changed, 121 insertions(+) + +--- a/Documentation/media/uapi/v4l/ext-ctrls-camera.rst ++++ b/Documentation/media/uapi/v4l/ext-ctrls-camera.rst +@@ -540,6 +540,127 @@ enum v4l2_scene_mode - + + + ++``V4L2_CID_CAMERA_SENSOR_ROTATION (integer)`` ++ This read-only control describes the rotation correction in degrees in the ++ counter-clockwise direction to be applied to the captured images once ++ captured to memory to compensate for the camera sensor mounting rotation. ++ ++ For a precise definition of the sensor mounting rotation refer to the ++ extensive description of the 'rotation' properties in the device tree ++ bindings file 'video-interfaces.txt'. ++ ++ A few examples are below reported, using a shark swimming from left to ++ right in front of the user as the example scene to capture. :: ++ ++ 0 X-axis ++ 0 +-------------------------------------> ++ ! ++ ! ++ ! ++ ! |\____)\___ ++ ! ) _____ __`< ++ ! |/ )/ ++ ! ++ ! ++ ! ++ V ++ Y-axis ++ ++ Example one - Webcam ++ ++ Assuming you can bring your laptop with you while swimming with sharks, ++ the camera module of the laptop is installed on the user facing part of a ++ laptop screen casing, and is typically used for video calls. The captured ++ images are meant to be displayed in landscape mode (width > height) on the ++ laptop screen. ++ ++ The camera is typically mounted upside-down to compensate the lens optical ++ inversion effect. In this case the value of the ++ V4L2_CID_CAMERA_SENSOR_ROTATION control is 0, no rotation is required to ++ display images correctly to the user. ++ ++ If the camera sensor is not mounted upside-down it is required to compensate ++ the lens optical inversion effect and the value of the ++ V4L2_CID_CAMERA_SENSOR_ROTATION control is 180 degrees, as images will ++ result rotated when captured to memory. :: ++ ++ +--------------------------------------+ ++ ! ! ++ ! ! ++ ! ! ++ ! __/(_____/| ! ++ ! >.___ ____ ( ! ++ ! \( \| ! ++ ! ! ++ ! ! ++ ! ! ++ +--------------------------------------+ ++ ++ A software rotation correction of 180 degrees has to be applied to correctly ++ display the image on the user screen. :: ++ ++ +--------------------------------------+ ++ ! ! ++ ! ! ++ ! ! ++ ! |\____)\___ ! ++ ! ) _____ __`< ! ++ ! |/ )/ ! ++ ! ! ++ ! ! ++ ! ! ++ +--------------------------------------+ ++ ++ Example two - Phone camera ++ ++ It is more handy to go and swim with sharks with only your mobile phone ++ with you and take pictures with the camera that is installed on the back ++ side of the device, facing away from the user. The captured images are meant ++ to be displayed in portrait mode (height > width) to match the device screen ++ orientation and the device usage orientation used when taking the picture. ++ ++ The camera sensor is typically mounted with its pixel array longer side ++ aligned to the device longer side, upside-down mounted to compensate for ++ the lens optical inversion effect. ++ ++ The images once captured to memory will be rotated and the value of the ++ V4L2_CID_CAMERA_SENSOR_ROTATION will report a 90 degree rotation. :: ++ ++ ++ +-------------------------------------+ ++ | _ _ | ++ | \ / | ++ | | | | ++ | | | | ++ | | > | ++ | < | | ++ | | | | ++ | . | ++ | V | ++ +-------------------------------------+ ++ ++ A correction of 90 degrees in counter-clockwise direction has to be ++ applied to correctly display the image in portrait mode on the device ++ screen. :: ++ ++ +--------------------+ ++ | | ++ | | ++ | | ++ | | ++ | | ++ | | ++ | |\____)\___ | ++ | ) _____ __`< | ++ | |/ )/ | ++ | | ++ | | ++ | | ++ | | ++ | | ++ +--------------------+ ++ ++ + .. [#f1] + This control may be changed to a menu control in the future, if more + options are required. diff --git a/target/linux/bcm27xx/patches-5.4/950-0906-media-v4l2-ctrls-Add-camera-orientation-and-rotation.patch b/target/linux/bcm27xx/patches-5.4/950-0906-media-v4l2-ctrls-Add-camera-orientation-and-rotation.patch new file mode 100644 index 0000000000..921b08ee7c --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0906-media-v4l2-ctrls-Add-camera-orientation-and-rotation.patch @@ -0,0 +1,89 @@ +From d25d713f7bfe272cbeaac90769eb88fee382b2e9 Mon Sep 17 00:00:00 2001 +From: Jacopo Mondi <jacopo@jmondi.org> +Date: Sat, 9 May 2020 11:04:48 +0200 +Subject: [PATCH] media: v4l2-ctrls: Add camera orientation and + rotation + +Add support for the newly defined V4L2_CID_CAMERA_ORIENTATION +and V4L2_CID_CAMERA_SENSOR_ROTATION read-only controls used to report +the camera device mounting position and orientation respectively. + +Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> + +Commit 926645d43fd43622a2b056471a2cf41cc19cbf4c upstream + +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +--- + drivers/media/v4l2-core/v4l2-ctrls.c | 13 +++++++++++++ + include/uapi/linux/v4l2-controls.h | 7 +++++++ + 2 files changed, 20 insertions(+) + +--- a/drivers/media/v4l2-core/v4l2-ctrls.c ++++ b/drivers/media/v4l2-core/v4l2-ctrls.c +@@ -577,6 +577,12 @@ const char * const *v4l2_ctrl_get_menu(u + "Annex B Start Code", + NULL, + }; ++ static const char * const camera_orientation[] = { ++ "Front", ++ "Back", ++ "External", ++ NULL, ++ }; + + switch (id) { + case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: +@@ -702,6 +708,8 @@ const char * const *v4l2_ctrl_get_menu(u + return hevc_decode_mode; + case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: + return hevc_start_code; ++ case V4L2_CID_CAMERA_ORIENTATION: ++ return camera_orientation; + default: + return NULL; + } +@@ -1015,6 +1023,8 @@ const char *v4l2_ctrl_get_name(u32 id) + case V4L2_CID_PAN_SPEED: return "Pan, Speed"; + case V4L2_CID_TILT_SPEED: return "Tilt, Speed"; + case V4L2_CID_UNIT_CELL_SIZE: return "Unit Cell Size"; ++ case V4L2_CID_CAMERA_ORIENTATION: return "Camera Orientation"; ++ case V4L2_CID_CAMERA_SENSOR_ROTATION: return "Camera Sensor Rotation"; + + /* FM Radio Modulator controls */ + /* Keep the order of the 'case's the same as in v4l2-controls.h! */ +@@ -1288,6 +1298,7 @@ void v4l2_ctrl_fill(u32 id, const char * + case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: + case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: + case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: ++ case V4L2_CID_CAMERA_ORIENTATION: + *type = V4L2_CTRL_TYPE_MENU; + break; + case V4L2_CID_LINK_FREQ: +@@ -1480,6 +1491,8 @@ void v4l2_ctrl_fill(u32 id, const char * + case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT: + case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM: + case V4L2_CID_RDS_RX_MUSIC_SPEECH: ++ case V4L2_CID_CAMERA_ORIENTATION: ++ case V4L2_CID_CAMERA_SENSOR_ROTATION: + *flags |= V4L2_CTRL_FLAG_READ_ONLY; + break; + case V4L2_CID_RF_TUNER_PLL_LOCK: +--- a/include/uapi/linux/v4l2-controls.h ++++ b/include/uapi/linux/v4l2-controls.h +@@ -917,6 +917,13 @@ enum v4l2_auto_focus_range { + #define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE+32) + #define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE+33) + ++#define V4L2_CID_CAMERA_ORIENTATION (V4L2_CID_CAMERA_CLASS_BASE+34) ++#define V4L2_CAMERA_ORIENTATION_FRONT 0 ++#define V4L2_CAMERA_ORIENTATION_BACK 1 ++#define V4L2_CAMERA_ORIENTATION_EXTERNAL 2 ++ ++#define V4L2_CID_CAMERA_SENSOR_ROTATION (V4L2_CID_CAMERA_CLASS_BASE+35) ++ + /* FM Modulator class control IDs */ + + #define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900) diff --git a/target/linux/bcm27xx/patches-5.4/950-0907-media-v4l2-fwnode-Add-helper-to-parse-device-propert.patch b/target/linux/bcm27xx/patches-5.4/950-0907-media-v4l2-fwnode-Add-helper-to-parse-device-propert.patch new file mode 100644 index 0000000000..d0d21fc7f2 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0907-media-v4l2-fwnode-Add-helper-to-parse-device-propert.patch @@ -0,0 +1,138 @@ +From 1cc9056759e1f500de5e401afd4b0acff90cc653 Mon Sep 17 00:00:00 2001 +From: Jacopo Mondi <jacopo@jmondi.org> +Date: Sat, 9 May 2020 11:04:49 +0200 +Subject: [PATCH] media: v4l2-fwnode: Add helper to parse device + properties + +Add an helper function to parse common device properties in the same +way as v4l2_fwnode_endpoint_parse() parses common endpoint properties. + +Parse the 'rotation' and 'orientation' properties from the firmware +interface. + +Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> + +Commit 344897ef1d9b33e246b64e255d807ca6c053f349 upstream + +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +--- + drivers/media/v4l2-core/v4l2-fwnode.c | 42 ++++++++++++++++++++++++ + include/media/v4l2-fwnode.h | 47 +++++++++++++++++++++++++++ + 2 files changed, 89 insertions(+) + +--- a/drivers/media/v4l2-core/v4l2-fwnode.c ++++ b/drivers/media/v4l2-core/v4l2-fwnode.c +@@ -599,6 +599,48 @@ void v4l2_fwnode_put_link(struct v4l2_fw + } + EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link); + ++int v4l2_fwnode_device_parse(struct device *dev, ++ struct v4l2_fwnode_device_properties *props) ++{ ++ struct fwnode_handle *fwnode = dev_fwnode(dev); ++ u32 val; ++ int ret; ++ ++ memset(props, 0, sizeof(*props)); ++ ++ props->orientation = V4L2_FWNODE_PROPERTY_UNSET; ++ ret = fwnode_property_read_u32(fwnode, "orientation", &val); ++ if (!ret) { ++ switch (val) { ++ case V4L2_FWNODE_ORIENTATION_FRONT: ++ case V4L2_FWNODE_ORIENTATION_BACK: ++ case V4L2_FWNODE_ORIENTATION_EXTERNAL: ++ break; ++ default: ++ dev_warn(dev, "Unsupported device orientation: %u\n", val); ++ return -EINVAL; ++ } ++ ++ props->orientation = val; ++ dev_dbg(dev, "device orientation: %u\n", val); ++ } ++ ++ props->rotation = V4L2_FWNODE_PROPERTY_UNSET; ++ ret = fwnode_property_read_u32(fwnode, "rotation", &val); ++ if (!ret) { ++ if (val >= 360) { ++ dev_warn(dev, "Unsupported device rotation: %u\n", val); ++ return -EINVAL; ++ } ++ ++ props->rotation = val; ++ dev_dbg(dev, "device rotation: %u\n", val); ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(v4l2_fwnode_device_parse); ++ + static int + v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev, + struct v4l2_async_notifier *notifier, +--- a/include/media/v4l2-fwnode.h ++++ b/include/media/v4l2-fwnode.h +@@ -110,6 +110,36 @@ struct v4l2_fwnode_endpoint { + }; + + /** ++ * V4L2_FWNODE_PROPERTY_UNSET - identify a non initialized property ++ * ++ * All properties in &struct v4l2_fwnode_device_properties are initialized ++ * to this value. ++ */ ++#define V4L2_FWNODE_PROPERTY_UNSET (-1U) ++ ++/** ++ * enum v4l2_fwnode_orientation - possible device orientation ++ * @V4L2_FWNODE_ORIENTATION_FRONT: device installed on the front side ++ * @V4L2_FWNODE_ORIENTATION_BACK: device installed on the back side ++ * @V4L2_FWNODE_ORIENTATION_EXTERNAL: device externally located ++ */ ++enum v4l2_fwnode_orientation { ++ V4L2_FWNODE_ORIENTATION_FRONT, ++ V4L2_FWNODE_ORIENTATION_BACK, ++ V4L2_FWNODE_ORIENTATION_EXTERNAL ++}; ++ ++/** ++ * struct v4l2_fwnode_device_properties - fwnode device properties ++ * @orientation: device orientation. See &enum v4l2_fwnode_orientation ++ * @rotation: device rotation ++ */ ++struct v4l2_fwnode_device_properties { ++ enum v4l2_fwnode_orientation orientation; ++ unsigned int rotation; ++}; ++ ++/** + * struct v4l2_fwnode_link - a link between two endpoints + * @local_node: pointer to device_node of this endpoint + * @local_port: identifier of the port this endpoint belongs to +@@ -234,6 +264,23 @@ int v4l2_fwnode_parse_link(struct fwnode + void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link); + + /** ++ * v4l2_fwnode_device_parse() - parse fwnode device properties ++ * @dev: pointer to &struct device ++ * @props: pointer to &struct v4l2_fwnode_device_properties where to store the ++ * parsed properties values ++ * ++ * This function parses and validates the V4L2 fwnode device properties from the ++ * firmware interface, and fills the @struct v4l2_fwnode_device_properties ++ * provided by the caller. ++ * ++ * Return: ++ * % 0 on success ++ * %-EINVAL if a parsed property value is not valid ++ */ ++int v4l2_fwnode_device_parse(struct device *dev, ++ struct v4l2_fwnode_device_properties *props); ++ ++/** + * typedef parse_endpoint_func - Driver's callback function to be called on + * each V4L2 fwnode endpoint. + * diff --git a/target/linux/bcm27xx/patches-5.4/950-0908-media-v4l2-ctrls-Add-helper-to-register-properties.patch b/target/linux/bcm27xx/patches-5.4/950-0908-media-v4l2-ctrls-Add-helper-to-register-properties.patch new file mode 100644 index 0000000000..a76de95bf3 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0908-media-v4l2-ctrls-Add-helper-to-register-properties.patch @@ -0,0 +1,114 @@ +From 67429ff939ad15a313663a05461d7a07d209449f Mon Sep 17 00:00:00 2001 +From: Jacopo Mondi <jacopo@jmondi.org> +Date: Sat, 9 May 2020 11:04:52 +0200 +Subject: [PATCH] media: v4l2-ctrls: Add helper to register + properties + +Add an helper function to v4l2-ctrls to register controls associated +with a device property. + +Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> + +Commit e0a360630debdf12355d9ec9f1417172c3fa6756 upstream + +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +--- + drivers/media/v4l2-core/v4l2-ctrls.c | 40 ++++++++++++++++++++++++++++ + include/media/v4l2-ctrls.h | 26 ++++++++++++++++++ + 2 files changed, 66 insertions(+) + +--- a/drivers/media/v4l2-core/v4l2-ctrls.c ++++ b/drivers/media/v4l2-core/v4l2-ctrls.c +@@ -17,6 +17,7 @@ + #include <media/v4l2-ctrls.h> + #include <media/v4l2-event.h> + #include <media/v4l2-dev.h> ++#include <media/v4l2-fwnode.h> + + #define dprintk(vdev, fmt, arg...) do { \ + if (!WARN_ON(!(vdev)) && ((vdev)->dev_debug & V4L2_DEV_DEBUG_CTRL)) \ +@@ -4577,3 +4578,42 @@ __poll_t v4l2_ctrl_poll(struct file *fil + return 0; + } + EXPORT_SYMBOL(v4l2_ctrl_poll); ++ ++int v4l2_ctrl_new_fwnode_properties(struct v4l2_ctrl_handler *hdl, ++ const struct v4l2_ctrl_ops *ctrl_ops, ++ const struct v4l2_fwnode_device_properties *p) ++{ ++ if (p->orientation != V4L2_FWNODE_PROPERTY_UNSET) { ++ u32 orientation_ctrl; ++ ++ switch (p->orientation) { ++ case V4L2_FWNODE_ORIENTATION_FRONT: ++ orientation_ctrl = V4L2_CAMERA_ORIENTATION_FRONT; ++ break; ++ case V4L2_FWNODE_ORIENTATION_BACK: ++ orientation_ctrl = V4L2_CAMERA_ORIENTATION_BACK; ++ break; ++ case V4L2_FWNODE_ORIENTATION_EXTERNAL: ++ orientation_ctrl = V4L2_CAMERA_ORIENTATION_EXTERNAL; ++ break; ++ default: ++ return -EINVAL; ++ } ++ if (!v4l2_ctrl_new_std_menu(hdl, ctrl_ops, ++ V4L2_CID_CAMERA_ORIENTATION, ++ V4L2_CAMERA_ORIENTATION_EXTERNAL, 0, ++ orientation_ctrl)) ++ return hdl->error; ++ } ++ ++ if (p->rotation != V4L2_FWNODE_PROPERTY_UNSET) { ++ if (!v4l2_ctrl_new_std(hdl, ctrl_ops, ++ V4L2_CID_CAMERA_SENSOR_ROTATION, ++ p->rotation, p->rotation, 1, ++ p->rotation)) ++ return hdl->error; ++ } ++ ++ return hdl->error; ++} ++EXPORT_SYMBOL(v4l2_ctrl_new_fwnode_properties); +--- a/include/media/v4l2-ctrls.h ++++ b/include/media/v4l2-ctrls.h +@@ -29,6 +29,7 @@ struct v4l2_ctrl_handler; + struct v4l2_ctrl_helper; + struct v4l2_ctrl; + struct video_device; ++struct v4l2_fwnode_device_properties; + struct v4l2_subdev; + struct v4l2_subscribed_event; + struct v4l2_fh; +@@ -1379,4 +1380,29 @@ int v4l2_ctrl_subdev_subscribe_event(str + */ + int v4l2_ctrl_subdev_log_status(struct v4l2_subdev *sd); + ++/** ++ * v4l2_ctrl_new_fwnode_properties() - Register controls for the device ++ * properties ++ * ++ * @hdl: pointer to &struct v4l2_ctrl_handler to register controls on ++ * @ctrl_ops: pointer to &struct v4l2_ctrl_ops to register controls with ++ * @p: pointer to &struct v4l2_fwnode_device_properties ++ * ++ * This function registers controls associated to device properties, using the ++ * property values contained in @p parameter, if the property has been set to ++ * a value. ++ * ++ * Currently the following v4l2 controls are parsed and registered: ++ * - V4L2_CID_CAMERA_ORIENTATION ++ * - V4L2_CID_CAMERA_SENSOR_ROTATION; ++ * ++ * Controls already registered by the caller with the @hdl control handler are ++ * not overwritten. Callers should register the controls they want to handle ++ * themselves before calling this function. ++ * ++ * Return: 0 on success, a negative error code on failure. ++ */ ++int v4l2_ctrl_new_fwnode_properties(struct v4l2_ctrl_handler *hdl, ++ const struct v4l2_ctrl_ops *ctrl_ops, ++ const struct v4l2_fwnode_device_properties *p); + #endif diff --git a/target/linux/bcm27xx/patches-5.4/950-0909-media-i2c-ov5647-Parse-and-register-properties.patch b/target/linux/bcm27xx/patches-5.4/950-0909-media-i2c-ov5647-Parse-and-register-properties.patch new file mode 100644 index 0000000000..ac7d70c392 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0909-media-i2c-ov5647-Parse-and-register-properties.patch @@ -0,0 +1,49 @@ +From 4b738c3d5c0f2719642b9515cece7fbfce9dc108 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Date: Sat, 4 Jul 2020 01:45:08 +0300 +Subject: [PATCH] media: i2c: ov5647: Parse and register properties + +Parse device properties and register controls for them using the V4L2 +fwnode properties helpers. + +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +--- + drivers/media/i2c/ov5647.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +--- a/drivers/media/i2c/ov5647.c ++++ b/drivers/media/i2c/ov5647.c +@@ -1501,6 +1501,7 @@ static int ov5647_probe(struct i2c_clien + struct device_node *np = client->dev.of_node; + u32 xclk_freq; + int hblank, exposure_max, exposure_def; ++ struct v4l2_fwnode_device_properties props; + + sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL); + if (!sensor) +@@ -1534,7 +1535,7 @@ static int ov5647_probe(struct i2c_clien + mutex_init(&sensor->lock); + + /* Initialise controls. */ +- v4l2_ctrl_handler_init(&sensor->ctrls, 7); ++ v4l2_ctrl_handler_init(&sensor->ctrls, 9); + v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, + V4L2_CID_AUTOGAIN, + 0, /* min */ +@@ -1598,6 +1599,16 @@ static int ov5647_probe(struct i2c_clien + __func__, ret); + goto error; + } ++ ++ ret = v4l2_fwnode_device_parse(&client->dev, &props); ++ if (ret) ++ goto error; ++ ++ ret = v4l2_ctrl_new_fwnode_properties(&sensor->ctrls, &ov5647_ctrl_ops, ++ &props); ++ if (ret) ++ goto error; ++ + sensor->sd.ctrl_handler = &sensor->ctrls; + + /* Write out the register set over I2C on stream-on. */ diff --git a/target/linux/bcm27xx/patches-5.4/950-0910-media-i2c-imx219-Parse-and-register-properties.patch b/target/linux/bcm27xx/patches-5.4/950-0910-media-i2c-imx219-Parse-and-register-properties.patch new file mode 100644 index 0000000000..dc5584e847 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0910-media-i2c-imx219-Parse-and-register-properties.patch @@ -0,0 +1,51 @@ +From db0889b08409484160a9082bc0b5f39877fe9591 Mon Sep 17 00:00:00 2001 +From: Jacopo Mondi <jacopo@jmondi.org> +Date: Sat, 9 May 2020 11:04:55 +0200 +Subject: [PATCH] media: i2c: imx219: Parse and register properties + +Parse device properties and register controls for them using the newly +introduced helpers. + +Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> + +Commit ad3a44cbd1b2e1559c6b93e80dc0c9c29632969a upstream + +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +--- + drivers/media/i2c/imx219.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/drivers/media/i2c/imx219.c ++++ b/drivers/media/i2c/imx219.c +@@ -1348,11 +1348,12 @@ static int imx219_init_controls(struct i + struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); + struct v4l2_ctrl_handler *ctrl_hdlr; + unsigned int height = imx219->mode->height; ++ struct v4l2_fwnode_device_properties props; + int exposure_max, exposure_def, hblank; + int i, ret; + + ctrl_hdlr = &imx219->ctrl_handler; +- ret = v4l2_ctrl_handler_init(ctrl_hdlr, 9); ++ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 11); + if (ret) + return ret; + +@@ -1431,6 +1432,15 @@ static int imx219_init_controls(struct i + goto error; + } + ++ ret = v4l2_fwnode_device_parse(&client->dev, &props); ++ if (ret) ++ goto error; ++ ++ ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx219_ctrl_ops, ++ &props); ++ if (ret) ++ goto error; ++ + imx219->sd.ctrl_handler = ctrl_hdlr; + + return 0; diff --git a/target/linux/bcm27xx/patches-5.4/950-0911-media-i2c-imx477-Parse-and-register-properties.patch b/target/linux/bcm27xx/patches-5.4/950-0911-media-i2c-imx477-Parse-and-register-properties.patch new file mode 100644 index 0000000000..fe022c9b57 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0911-media-i2c-imx477-Parse-and-register-properties.patch @@ -0,0 +1,45 @@ +From df12dbc41bbdb2b949eb395088f9d6b197d9db8a Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Date: Sat, 4 Jul 2020 01:45:08 +0300 +Subject: [PATCH] media: i2c: imx477: Parse and register properties + +Parse device properties and register controls for them using the V4L2 +fwnode properties helpers. + +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +--- + drivers/media/i2c/imx477.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/drivers/media/i2c/imx477.c ++++ b/drivers/media/i2c/imx477.c +@@ -1957,11 +1957,12 @@ static int imx477_init_controls(struct i + { + struct v4l2_ctrl_handler *ctrl_hdlr; + struct i2c_client *client = v4l2_get_subdevdata(&imx477->sd); ++ struct v4l2_fwnode_device_properties props; + unsigned int i; + int ret; + + ctrl_hdlr = &imx477->ctrl_handler; +- ret = v4l2_ctrl_handler_init(ctrl_hdlr, 14); ++ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 16); + if (ret) + return ret; + +@@ -2045,6 +2046,15 @@ static int imx477_init_controls(struct i + goto error; + } + ++ ret = v4l2_fwnode_device_parse(&client->dev, &props); ++ if (ret) ++ goto error; ++ ++ ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx477_ctrl_ops, ++ &props); ++ if (ret) ++ goto error; ++ + imx477->sd.ctrl_handler = ctrl_hdlr; + + /* Setup exposure and frame/line length limits. */ diff --git a/target/linux/bcm27xx/patches-5.4/950-0912-dt-dtoverlays-ov5647-Add-parameter-to-set-camera-mod.patch b/target/linux/bcm27xx/patches-5.4/950-0912-dt-dtoverlays-ov5647-Add-parameter-to-set-camera-mod.patch new file mode 100644 index 0000000000..23a2fb9c26 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0912-dt-dtoverlays-ov5647-Add-parameter-to-set-camera-mod.patch @@ -0,0 +1,49 @@ +From 7d2efa734da00de05c8a58688da28cf1e380ef3a Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Date: Sat, 4 Jul 2020 03:04:38 +0300 +Subject: [PATCH] dt/dtoverlays: ov5647: Add parameter to set camera + module rotation + +Add a rotation DT overlay parameter to allow specifying the camera +module mounting rotation. + +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +--- + arch/arm/boot/dts/overlays/README | 5 +++-- + arch/arm/boot/dts/overlays/ov5647-overlay.dts | 6 ++++++ + 2 files changed, 9 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1809,8 +1809,9 @@ Name: ov5647 + Info: Omnivision OV5647 camera module. + Uses Unicam 1, which is the standard camera connector on most Pi + variants. +-Load: dtoverlay=ov5647 +-Params: <None> ++Load: dtoverlay=ov5647,<param>=<val> ++Params: rotation Mounting rotation of the camera sensor (0 or ++ 180, default 0) + + + Name: ov7251 +--- a/arch/arm/boot/dts/overlays/ov5647-overlay.dts ++++ b/arch/arm/boot/dts/overlays/ov5647-overlay.dts +@@ -21,6 +21,8 @@ + pwdn-gpios = <&gpio 41 1>, <&gpio 32 1>; + clocks = <&ov5647_clk>; + ++ rotation = <0>; ++ + port { + ov5647_0: endpoint { + remote-endpoint = <&csi1_ep>; +@@ -83,4 +85,8 @@ + }; + }; + }; ++ ++ __overrides__ { ++ rotation = <&ov5647>,"rotation:0"; ++ }; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0913-dt-dtoverlays-imx219-Add-parameter-to-set-camera-mod.patch b/target/linux/bcm27xx/patches-5.4/950-0913-dt-dtoverlays-imx219-Add-parameter-to-set-camera-mod.patch new file mode 100644 index 0000000000..be22dd3316 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0913-dt-dtoverlays-imx219-Add-parameter-to-set-camera-mod.patch @@ -0,0 +1,50 @@ +From 30fbdcf8d58658860e43c0396cb50c5d4ade2dc5 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Date: Sat, 4 Jul 2020 03:04:38 +0300 +Subject: [PATCH] dt/dtoverlays: imx219: Add parameter to set camera + module rotation + +Add a rotation DT overlay parameter to allow specifying the camera +module mounting rotation. Set the default rotation to 180 as the module +is typically mounted upside-down. + +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +--- + arch/arm/boot/dts/overlays/README | 5 +++-- + arch/arm/boot/dts/overlays/imx219-overlay.dts | 6 ++++++ + 2 files changed, 9 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1433,8 +1433,9 @@ Name: imx219 + Info: Sony IMX219 camera module. + Uses Unicam 1, which is the standard camera connector on most Pi + variants. +-Load: dtoverlay=imx219 +-Params: <None> ++Load: dtoverlay=imx219,<param>=<val> ++Params: rotation Mounting rotation of the camera sensor (0 or ++ 180, default 180) + + + Name: imx290 +--- a/arch/arm/boot/dts/overlays/imx219-overlay.dts ++++ b/arch/arm/boot/dts/overlays/imx219-overlay.dts +@@ -27,6 +27,8 @@ + VDIG-supply = <&imx219_vdig>; /* 1.8v */ + VDDL-supply = <&imx219_vddl>; /* 1.2v */ + ++ rotation = <180>; ++ + port { + imx219_0: endpoint { + remote-endpoint = <&csi1_ep>; +@@ -110,4 +112,8 @@ + cam0-pwdn = <&imx219_vana>,"gpio:4"; + }; + }; ++ ++ __overrides__ { ++ rotation = <&imx219>,"rotation:0"; ++ }; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0914-dt-dtoverlays-imx477-Add-parameter-to-set-camera-mod.patch b/target/linux/bcm27xx/patches-5.4/950-0914-dt-dtoverlays-imx477-Add-parameter-to-set-camera-mod.patch new file mode 100644 index 0000000000..11a5d3da98 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0914-dt-dtoverlays-imx477-Add-parameter-to-set-camera-mod.patch @@ -0,0 +1,50 @@ +From afed51afadb2f5d43e093c969bdf6535b2ea0ad3 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Date: Sat, 4 Jul 2020 03:04:38 +0300 +Subject: [PATCH] dt/dtoverlays: imx477: Add parameter to set camera + module rotation + +Add a rotation DT overlay parameter to allow specifying the camera +module mounting rotation. Set the default rotation to 180 as the module +is typically mounted upside-down. + +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +--- + arch/arm/boot/dts/overlays/README | 5 +++-- + arch/arm/boot/dts/overlays/imx477-overlay.dts | 6 ++++++ + 2 files changed, 9 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1458,8 +1458,9 @@ Name: imx477 + Info: Sony IMX477 camera module. + Uses Unicam 1, which is the standard camera connector on most Pi + variants. +-Load: dtoverlay=imx477 +-Params: <None> ++Load: dtoverlay=imx477,<param>=<val> ++Params: rotation Mounting rotation of the camera sensor (0 or ++ 180, default 180) + + + Name: iqaudio-codec +--- a/arch/arm/boot/dts/overlays/imx477-overlay.dts ++++ b/arch/arm/boot/dts/overlays/imx477-overlay.dts +@@ -27,6 +27,8 @@ + VDIG-supply = <&imx477_vdig>; /* 1.05v */ + VDDL-supply = <&imx477_vddl>; /* 1.8v */ + ++ rotation = <180>; ++ + port { + imx477_0: endpoint { + remote-endpoint = <&csi1_ep>; +@@ -110,4 +112,8 @@ + cam0-pwdn = <&imx477_vana>,"gpio:4"; + }; + }; ++ ++ __overrides__ { ++ rotation = <&imx477>,"rotation:0"; ++ }; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0915-drm-vc4-Add-DRM_MODE_FLAG_DBLCLK-support-to-vc4-fkms.patch b/target/linux/bcm27xx/patches-5.4/950-0915-drm-vc4-Add-DRM_MODE_FLAG_DBLCLK-support-to-vc4-fkms.patch new file mode 100644 index 0000000000..a7a1d91290 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0915-drm-vc4-Add-DRM_MODE_FLAG_DBLCLK-support-to-vc4-fkms.patch @@ -0,0 +1,54 @@ +From 16349a9b271d331a496a482f46f41a3e1db56891 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 16 Jul 2020 12:02:47 +0100 +Subject: [PATCH] drm/vc4: Add DRM_MODE_FLAG_DBLCLK support to + vc4-fkms + +480i and several other modes use DRM_MODE_FLAG_DBLCLK and pixel +replication. + +Add in flags for that so that FKMS can select CEA modes 6 & 7. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -158,6 +158,8 @@ struct set_timings { + #define TIMINGS_FLAGS_RGB_LIMITED BIT(8) + /* DVI monitor, therefore disable infoframes. Not set corresponds to HDMI. */ + #define TIMINGS_FLAGS_DVI BIT(9) ++/* Double clock */ ++#define TIMINGS_FLAGS_DBL_CLK BIT(10) + }; + + struct mailbox_set_mode { +@@ -946,6 +948,8 @@ static void vc4_crtc_mode_set_nofb(struc + + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + mb.timings.flags |= TIMINGS_FLAGS_INTERLACE; ++ if (mode->flags & DRM_MODE_FLAG_DBLCLK) ++ mb.timings.flags |= TIMINGS_FLAGS_DBL_CLK; + + mb.timings.video_id_code = frame.avi.video_code; + +@@ -1104,11 +1108,16 @@ vc4_crtc_mode_valid(struct drm_crtc *crt + */ + if (fkms->bcm2711 && + (vc4_crtc->display_number == 2 || vc4_crtc->display_number == 7) && ++ !(mode->flags & DRM_MODE_FLAG_DBLCLK) && + ((mode->hdisplay | /* active */ + (mode->hsync_start - mode->hdisplay) | /* front porch */ + (mode->hsync_end - mode->hsync_start) | /* sync pulse */ +- (mode->htotal - mode->hsync_end)) & 1)) /* back porch */ ++ (mode->htotal - mode->hsync_end)) & 1)) /* back porch */ { ++ DRM_DEBUG_KMS("[CRTC:%d] Odd timing rejected %u %u %u %u.\n", ++ crtc->base.id, mode->hdisplay, mode->hsync_start, ++ mode->hsync_end, mode->htotal); + return MODE_H_ILLEGAL; ++ } + + return MODE_OK; + } diff --git a/target/linux/bcm27xx/patches-5.4/950-0916-leds-Add-the-actpwr-trigger.patch b/target/linux/bcm27xx/patches-5.4/950-0916-leds-Add-the-actpwr-trigger.patch new file mode 100644 index 0000000000..2f0aaa0006 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0916-leds-Add-the-actpwr-trigger.patch @@ -0,0 +1,236 @@ +From 6586d75915287dd336b71e17826f037be7926ebe Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 13 Jul 2020 10:33:19 +0100 +Subject: [PATCH] leds: Add the actpwr trigger + +The actpwr trigger is a meta trigger that cycles between an inverted +mmc0 and default-on. It is written in a way that could fairly easily +be generalised to support alternative sets of source triggers. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/leds/trigger/Kconfig | 11 ++ + drivers/leds/trigger/Makefile | 1 + + drivers/leds/trigger/ledtrig-actpwr.c | 191 ++++++++++++++++++++++++++ + 3 files changed, 203 insertions(+) + create mode 100644 drivers/leds/trigger/ledtrig-actpwr.c + +--- a/drivers/leds/trigger/Kconfig ++++ b/drivers/leds/trigger/Kconfig +@@ -151,4 +151,15 @@ config LEDS_TRIGGER_AUDIO + the audio mute and mic-mute changes. + If unsure, say N + ++config LEDS_TRIGGER_ACTPWR ++ tristate "ACT/PWR Input Trigger" ++ depends on LEDS_TRIGGERS ++ help ++ This trigger is intended for platforms that have one software- ++ controllable LED and no dedicated activity or power LEDs, hence the ++ need to make the one LED perform both functions. It cycles between ++ default-on and an inverted mmc0 every 500ms, guaranteeing that it is ++ on for at least half of the time. ++ If unsure, say N. ++ + endif # LEDS_TRIGGERS +--- a/drivers/leds/trigger/Makefile ++++ b/drivers/leds/trigger/Makefile +@@ -16,3 +16,4 @@ obj-$(CONFIG_LEDS_TRIGGER_PANIC) += ledt + obj-$(CONFIG_LEDS_TRIGGER_NETDEV) += ledtrig-netdev.o + obj-$(CONFIG_LEDS_TRIGGER_PATTERN) += ledtrig-pattern.o + obj-$(CONFIG_LEDS_TRIGGER_AUDIO) += ledtrig-audio.o ++obj-$(CONFIG_LEDS_TRIGGER_ACTPWR) += ledtrig-actpwr.o +--- /dev/null ++++ b/drivers/leds/trigger/ledtrig-actpwr.c +@@ -0,0 +1,191 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Activity/power trigger ++ * ++ * Copyright (C) 2020 Raspberry Pi (Trading) Ltd. ++ * ++ * Based on Atsushi Nemoto's ledtrig-heartbeat.c, although there may be ++ * nothing left of the original now. ++ */ ++ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/timer.h> ++#include <linux/leds.h> ++#include "../leds.h" ++ ++enum { ++ TRIG_ACT, ++ TRIG_PWR, ++ ++ TRIG_COUNT ++}; ++ ++struct actpwr_trig_src { ++ const char *name; ++ int interval; ++ bool invert; ++}; ++ ++struct actpwr_vled { ++ struct led_classdev cdev; ++ struct actpwr_trig_data *parent; ++ enum led_brightness value; ++ unsigned int interval; ++ bool invert; ++}; ++ ++struct actpwr_trig_data { ++ struct led_trigger trig; ++ struct actpwr_vled virt_leds[TRIG_COUNT]; ++ struct actpwr_vled *active; ++ struct timer_list timer; ++ int next_active; ++}; ++ ++static int actpwr_trig_activate(struct led_classdev *led_cdev); ++static void actpwr_trig_deactivate(struct led_classdev *led_cdev); ++ ++static const struct actpwr_trig_src actpwr_trig_sources[TRIG_COUNT] = { ++ [TRIG_ACT] = { "mmc0", 500, true }, ++ [TRIG_PWR] = { "default-on", 500, false }, ++}; ++ ++static struct actpwr_trig_data actpwr_data = { ++ { ++ .name = "actpwr", ++ .activate = actpwr_trig_activate, ++ .deactivate = actpwr_trig_deactivate, ++ } ++}; ++ ++static void actpwr_brightness_set(struct led_classdev *led_cdev, ++ enum led_brightness value) ++{ ++ struct actpwr_vled *vled = container_of(led_cdev, struct actpwr_vled, ++ cdev); ++ struct actpwr_trig_data *trig = vled->parent; ++ ++ if (vled->invert) ++ value = !value; ++ vled->value = value; ++ ++ if (vled == trig->active) ++ led_trigger_event(&trig->trig, value); ++} ++ ++static int actpwr_brightness_set_blocking(struct led_classdev *led_cdev, ++ enum led_brightness value) ++{ ++ actpwr_brightness_set(led_cdev, value); ++ return 0; ++} ++ ++static enum led_brightness actpwr_brightness_get(struct led_classdev *led_cdev) ++{ ++ struct actpwr_vled *vled = container_of(led_cdev, struct actpwr_vled, ++ cdev); ++ ++ return vled->value; ++} ++ ++static void actpwr_trig_cycle(struct timer_list *t) ++{ ++ struct actpwr_trig_data *trig = &actpwr_data; ++ struct actpwr_vled *active; ++ enum led_brightness value; ++ ++ active = &trig->virt_leds[trig->next_active]; ++ trig->active = active; ++ trig->next_active = (trig->next_active + 1) % TRIG_COUNT; ++ ++ led_trigger_event(&trig->trig, active->value); ++ ++ mod_timer(&trig->timer, jiffies + msecs_to_jiffies(active->interval)); ++} ++ ++static int actpwr_trig_activate(struct led_classdev *led_cdev) ++{ ++ struct actpwr_trig_data *trig = &actpwr_data; ++ ++ /* Start the timer if this is the first LED */ ++ if (!trig->active) ++ actpwr_trig_cycle(&trig->timer); ++ else ++ led_set_brightness_nosleep(led_cdev, trig->active->value); ++ ++ return 0; ++} ++ ++static void actpwr_trig_deactivate(struct led_classdev *led_cdev) ++{ ++ struct actpwr_trig_data *trig = &actpwr_data; ++ ++ if (list_empty(&trig->trig.led_cdevs)) { ++ del_timer_sync(&trig->timer); ++ trig->active = NULL; ++ } ++} ++ ++static int __init actpwr_trig_init(void) ++{ ++ struct actpwr_trig_data *trig = &actpwr_data; ++ int ret = 0; ++ int i; ++ ++ timer_setup(&trig->timer, actpwr_trig_cycle, 0); ++ ++ /* Register one "LED" for each source trigger */ ++ for (i = 0; i < TRIG_COUNT; i++) ++ { ++ struct actpwr_vled *vled = &trig->virt_leds[i]; ++ struct led_classdev *cdev = &vled->cdev; ++ const struct actpwr_trig_src *src = &actpwr_trig_sources[i]; ++ ++ vled->parent = trig; ++ vled->interval = src->interval; ++ vled->invert = src->invert; ++ cdev->name = src->name; ++ cdev->brightness_set = actpwr_brightness_set; ++ cdev->brightness_set_blocking = actpwr_brightness_set_blocking; ++ cdev->brightness_get = actpwr_brightness_get; ++ cdev->default_trigger = src->name; ++ ret = led_classdev_register(NULL, cdev); ++ if (ret) ++ goto error_classdev; ++ } ++ ++ ret = led_trigger_register(&trig->trig); ++ if (ret) ++ goto error_classdev; ++ ++ return 0; ++ ++error_classdev: ++ while (i > 0) ++ { ++ i--; ++ led_classdev_unregister(&trig->virt_leds[i].cdev); ++ } ++ ++ return ret; ++} ++ ++static void __exit actpwr_trig_exit(void) ++{ ++ int i; ++ ++ led_trigger_unregister(&actpwr_data.trig); ++ for (i = 0; i < TRIG_COUNT; i++) ++ { ++ led_classdev_unregister(&actpwr_data.virt_leds[i].cdev); ++ } ++} ++ ++module_init(actpwr_trig_init); ++module_exit(actpwr_trig_exit); ++ ++MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.com>"); ++MODULE_DESCRIPTION("ACT/PWR LED trigger"); ++MODULE_LICENSE("GPL v2"); diff --git a/target/linux/bcm27xx/patches-5.4/950-0917-ARM-dts-Select-the-actpwr-LED-trigger-on-Zeroes.patch b/target/linux/bcm27xx/patches-5.4/950-0917-ARM-dts-Select-the-actpwr-LED-trigger-on-Zeroes.patch new file mode 100644 index 0000000000..02f425a9b1 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0917-ARM-dts-Select-the-actpwr-LED-trigger-on-Zeroes.patch @@ -0,0 +1,41 @@ +From 990bc7c8a234a0f446a7d56067b1a9f8348e0f35 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Thu, 16 Jul 2020 18:19:58 +0100 +Subject: [PATCH] ARM: dts: Select the actpwr LED trigger on Zeroes + +The new "actpwr" LED trigger guarantees that the combined PWR and ACT +LED is on for at least half of every second. Under heavy SD card +load it emits a steady 1Hz square wave. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2708-rpi-zero-w.dts | 4 ++-- + arch/arm/boot/dts/bcm2708-rpi-zero.dts | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts +@@ -144,8 +144,8 @@ + &leds { + act_led: act { + label = "led0"; +- linux,default-trigger = "mmc0"; +- gpios = <&gpio 47 0>; ++ linux,default-trigger = "actpwr"; ++ gpios = <&gpio 47 GPIO_ACTIVE_LOW>; + }; + }; + +--- a/arch/arm/boot/dts/bcm2708-rpi-zero.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-zero.dts +@@ -98,8 +98,8 @@ + &leds { + act_led: act { + label = "led0"; +- linux,default-trigger = "mmc0"; +- gpios = <&gpio 47 0>; ++ linux,default-trigger = "actpwr"; ++ gpios = <&gpio 47 GPIO_ACTIVE_LOW>; + }; + }; + diff --git a/target/linux/bcm27xx/patches-5.4/950-0918-staging-vc04_services-isp-Rework-lens-shading-to-tak.patch b/target/linux/bcm27xx/patches-5.4/950-0918-staging-vc04_services-isp-Rework-lens-shading-to-tak.patch new file mode 100644 index 0000000000..8748214797 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0918-staging-vc04_services-isp-Rework-lens-shading-to-tak.patch @@ -0,0 +1,87 @@ +From 7504f92483407233d9093e164d8f001db5c374e5 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Fri, 8 May 2020 22:05:29 +0100 +Subject: [PATCH] staging: vc04_services: isp: Rework lens shading to + take a dmabuf + +This removes the need for the client to use vcsm at all. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + .../bcm2835-isp/bcm2835-v4l2-isp.c | 36 +++++++++++++++++-- + include/uapi/linux/bcm2835-isp.h | 4 +-- + 2 files changed, 35 insertions(+), 5 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c ++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c +@@ -21,6 +21,8 @@ + #include "vchiq-mmal/mmal-parameters.h" + #include "vchiq-mmal/mmal-vchiq.h" + ++#include "vc-sm-cma/vc_sm_knl.h" ++ + #include "bcm2835_isp_ctrls.h" + #include "bcm2835_isp_fmts.h" + +@@ -722,10 +724,38 @@ static int bcm2835_isp_s_ctrl(struct v4l + sizeof(struct bcm2835_isp_custom_ccm)); + break; + case V4L2_CID_USER_BCM2835_ISP_LENS_SHADING: +- ret = set_isp_param(node, MMAL_PARAMETER_LENS_SHADING_OVERRIDE, +- ctrl->p_new.p_u8, +- sizeof(struct bcm2835_isp_lens_shading)); ++ { ++ struct bcm2835_isp_lens_shading ls; ++ struct dma_buf *dmabuf; ++ void *vcsm_handle; ++ ++ memcpy(&ls, ctrl->p_new.p_u8, ++ sizeof(struct bcm2835_isp_lens_shading)); ++ ++ dmabuf = dma_buf_get(ls.dmabuf); ++ if (!dmabuf) ++ return -EINVAL; ++ ++ ret = vc_sm_cma_import_dmabuf(dmabuf, ++ &vcsm_handle); ++ if (ret) { ++ dma_buf_put(dmabuf); ++ return -EINVAL; ++ } ++ ++ ls.dmabuf = vc_sm_cma_int_handle(vcsm_handle); ++ if (ls.dmabuf) ++ ret = set_isp_param(node, ++ MMAL_PARAMETER_LENS_SHADING_OVERRIDE, ++ &ls, ++ sizeof(struct bcm2835_isp_lens_shading)); ++ else ++ ret = -EINVAL; ++ ++ vc_sm_cma_free(vcsm_handle); ++ dma_buf_put(dmabuf); + break; ++ } + case V4L2_CID_USER_BCM2835_ISP_BLACK_LEVEL: + ret = set_isp_param(node, MMAL_PARAMETER_BLACK_LEVEL, + ctrl->p_new.p_u8, +--- a/include/uapi/linux/bcm2835-isp.h ++++ b/include/uapi/linux/bcm2835-isp.h +@@ -108,7 +108,7 @@ enum bcm2835_isp_gain_format { + * @grid_stride: Row to row distance (in grid cells) between grid cells + * in the same horizontal location. + * @grid_height: Height of lens shading tables in grid cells. +- * @mem_handle_table: Memory handle to the tables. ++ * @dmabuf: dmabuf file handle containing the table. + * @ref_transform: Reference transform - unsupported, please pass zero. + * @corner_sampled: Whether the gains are sampled at the corner points + * of the grid cells or in the cell centres. +@@ -120,7 +120,7 @@ struct bcm2835_isp_lens_shading { + __u32 grid_width; + __u32 grid_stride; + __u32 grid_height; +- __u32 mem_handle_table; ++ __s32 dmabuf; + __u32 ref_transform; + __u32 corner_sampled; + __u32 gain_format; diff --git a/target/linux/bcm27xx/patches-5.4/950-0919-Mute-bug-fix-for-the-Audioinjector.net-isolated-soun.patch b/target/linux/bcm27xx/patches-5.4/950-0919-Mute-bug-fix-for-the-Audioinjector.net-isolated-soun.patch new file mode 100644 index 0000000000..10fe757577 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0919-Mute-bug-fix-for-the-Audioinjector.net-isolated-soun.patch @@ -0,0 +1,64 @@ +From 11a2b192e0a8b7514895f9f6b7451f4c6ddd0a22 Mon Sep 17 00:00:00 2001 +From: Matt Flax <flatmax@flatmax.org> +Date: Fri, 17 Jul 2020 09:17:36 +1000 +Subject: [PATCH] Mute bug fix for the Audioinjector.net isolated + soundcard. + +--- + .../bcm/audioinjector-isolated-soundcard.c | 26 +++---------------- + 1 file changed, 3 insertions(+), 23 deletions(-) + +--- a/sound/soc/bcm/audioinjector-isolated-soundcard.c ++++ b/sound/soc/bcm/audioinjector-isolated-soundcard.c +@@ -42,41 +42,20 @@ static int audioinjector_isolated_dai_in + int ret=snd_soc_dai_set_sysclk(rtd->codec_dai, 0, 24576000, 0); + if (ret) + return ret; +- + return snd_soc_dai_set_bclk_ratio(rtd->cpu_dai, 64); + } + + static int audioinjector_isolated_startup(struct snd_pcm_substream *substream) + { + snd_pcm_hw_constraint_list(substream->runtime, 0, +- SNDRV_PCM_HW_PARAM_RATE, &audioinjector_isolated_constraints); +- +- return 0; +-} ++ SNDRV_PCM_HW_PARAM_RATE, &audioinjector_isolated_constraints); + +-static int audioinjector_isolated_trigger(struct snd_pcm_substream *substream, +- int cmd){ +- +- switch (cmd) { +- case SNDRV_PCM_TRIGGER_STOP: +- case SNDRV_PCM_TRIGGER_SUSPEND: +- case SNDRV_PCM_TRIGGER_PAUSE_PUSH: +- gpiod_set_value(mute_gpio, 0); +- break; +- case SNDRV_PCM_TRIGGER_START: +- case SNDRV_PCM_TRIGGER_RESUME: +- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: +- gpiod_set_value(mute_gpio, 1); +- break; +- default: +- return -EINVAL; +- } ++ gpiod_set_value(mute_gpio, 1); + return 0; + } + + static struct snd_soc_ops audioinjector_isolated_ops = { + .startup = audioinjector_isolated_startup, +- .trigger = audioinjector_isolated_trigger, + }; + + SND_SOC_DAILINK_DEFS(audioinjector_isolated, +@@ -153,6 +132,7 @@ static int audioinjector_isolated_probe( + dev_err(&pdev->dev, "mute gpio not found in dt overlay\n"); + return PTR_ERR(mute_gpio); + } ++ gpiod_set_value(mute_gpio, 0); + } + + ret = devm_snd_soc_register_card(&pdev->dev, card); diff --git a/target/linux/bcm27xx/patches-5.4/950-0920-vc4-Report-channel-mapping-back-to-userspace.patch b/target/linux/bcm27xx/patches-5.4/950-0920-vc4-Report-channel-mapping-back-to-userspace.patch new file mode 100644 index 0000000000..8c4e1012bf --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0920-vc4-Report-channel-mapping-back-to-userspace.patch @@ -0,0 +1,504 @@ +From 058328afcdd3d5c9531cfac8b980d0c0db75856f Mon Sep 17 00:00:00 2001 +From: popcornmix <popcornmix@gmail.com> +Date: Mon, 20 Apr 2020 18:00:38 +0100 +Subject: [PATCH] vc4: Report channel mapping back to userspace + +This follows logic in hdmi-codec.c to use speaker layout +from ELD to choose a suitable speaker mapping based on +number of channels requested and signal that in audio +infoframe and report this back to userspace. + +This allows apps like speaker-test and kodi to get the +output to the right speakers. + +Signed-off-by: Dom Cobley <popcornmix@gmail.com> +--- + drivers/gpu/drm/vc4/vc4_hdmi.c | 415 +++++++++++++++++++++++++++++++++ + drivers/gpu/drm/vc4/vc4_hdmi.h | 3 + + 2 files changed, 418 insertions(+) + +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -48,6 +48,7 @@ + #include <sound/pcm_drm_eld.h> + #include <sound/pcm_params.h> + #include <sound/soc.h> ++#include <sound/tlv.h> + #include "media/cec.h" + #include "vc4_drv.h" + #include "vc4_hdmi.h" +@@ -82,6 +83,311 @@ + #define CEC_CLOCK_FREQ 40000 + #define VC4_HSM_CLOCK 163682864 + ++#define HDMI_CODEC_CHMAP_IDX_UNKNOWN -1 ++ ++/* ++ * CEA speaker placement for HDMI 1.4: ++ * ++ * FL FLC FC FRC FR FRW ++ * ++ * LFE ++ * ++ * RL RLC RC RRC RR ++ * ++ * Speaker placement has to be extended to support HDMI 2.0 ++ */ ++enum hdmi_codec_cea_spk_placement { ++ FL = BIT(0), /* Front Left */ ++ FC = BIT(1), /* Front Center */ ++ FR = BIT(2), /* Front Right */ ++ FLC = BIT(3), /* Front Left Center */ ++ FRC = BIT(4), /* Front Right Center */ ++ RL = BIT(5), /* Rear Left */ ++ RC = BIT(6), /* Rear Center */ ++ RR = BIT(7), /* Rear Right */ ++ RLC = BIT(8), /* Rear Left Center */ ++ RRC = BIT(9), /* Rear Right Center */ ++ LFE = BIT(10), /* Low Frequency Effect */ ++}; ++ ++/* ++ * cea Speaker allocation structure ++ */ ++struct hdmi_codec_cea_spk_alloc { ++ const int ca_id; ++ unsigned int n_ch; ++ unsigned long mask; ++}; ++ ++/* Channel maps stereo HDMI */ ++static const struct snd_pcm_chmap_elem hdmi_codec_stereo_chmaps[] = { ++ { .channels = 2, ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, ++ { } ++}; ++ ++/* Channel maps for multi-channel playbacks, up to 8 n_ch */ ++static const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = { ++ { .channels = 2, /* CA_ID 0x00 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, ++ { .channels = 4, /* CA_ID 0x01 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA } }, ++ { .channels = 4, /* CA_ID 0x02 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC } }, ++ { .channels = 4, /* CA_ID 0x03 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC } }, ++ { .channels = 6, /* CA_ID 0x04 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 6, /* CA_ID 0x05 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 6, /* CA_ID 0x06 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 6, /* CA_ID 0x07 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 6, /* CA_ID 0x08 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } }, ++ { .channels = 6, /* CA_ID 0x09 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } }, ++ { .channels = 6, /* CA_ID 0x0A */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } }, ++ { .channels = 6, /* CA_ID 0x0B */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } }, ++ { .channels = 8, /* CA_ID 0x0C */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 8, /* CA_ID 0x0D */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 8, /* CA_ID 0x0E */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 8, /* CA_ID 0x0F */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } }, ++ { .channels = 8, /* CA_ID 0x10 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } }, ++ { .channels = 8, /* CA_ID 0x11 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } }, ++ { .channels = 8, /* CA_ID 0x12 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } }, ++ { .channels = 8, /* CA_ID 0x13 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR, ++ SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } }, ++ { .channels = 8, /* CA_ID 0x14 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x15 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x16 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x17 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x18 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x19 */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x1A */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x1B */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x1C */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x1D */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x1E */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { .channels = 8, /* CA_ID 0x1F */ ++ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, ++ SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, ++ SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } }, ++ { } ++}; ++ ++/* ++ * hdmi_codec_channel_alloc: speaker configuration available for CEA ++ * ++ * This is an ordered list that must match with hdmi_codec_8ch_chmaps struct ++ * The preceding ones have better chances to be selected by ++ * hdmi_codec_get_ch_alloc_table_idx(). ++ */ ++static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = { ++ { .ca_id = 0x00, .n_ch = 2, ++ .mask = FL | FR}, ++ /* 2.1 */ ++ { .ca_id = 0x01, .n_ch = 4, ++ .mask = FL | FR | LFE}, ++ /* Dolby Surround */ ++ { .ca_id = 0x02, .n_ch = 4, ++ .mask = FL | FR | FC }, ++ /* surround51 */ ++ { .ca_id = 0x0b, .n_ch = 6, ++ .mask = FL | FR | LFE | FC | RL | RR}, ++ /* surround40 */ ++ { .ca_id = 0x08, .n_ch = 6, ++ .mask = FL | FR | RL | RR }, ++ /* surround41 */ ++ { .ca_id = 0x09, .n_ch = 6, ++ .mask = FL | FR | LFE | RL | RR }, ++ /* surround50 */ ++ { .ca_id = 0x0a, .n_ch = 6, ++ .mask = FL | FR | FC | RL | RR }, ++ /* 6.1 */ ++ { .ca_id = 0x0f, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | RL | RR | RC }, ++ /* surround71 */ ++ { .ca_id = 0x13, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | RL | RR | RLC | RRC }, ++ /* others */ ++ { .ca_id = 0x03, .n_ch = 8, ++ .mask = FL | FR | LFE | FC }, ++ { .ca_id = 0x04, .n_ch = 8, ++ .mask = FL | FR | RC}, ++ { .ca_id = 0x05, .n_ch = 8, ++ .mask = FL | FR | LFE | RC }, ++ { .ca_id = 0x06, .n_ch = 8, ++ .mask = FL | FR | FC | RC }, ++ { .ca_id = 0x07, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | RC }, ++ { .ca_id = 0x0c, .n_ch = 8, ++ .mask = FL | FR | RC | RL | RR }, ++ { .ca_id = 0x0d, .n_ch = 8, ++ .mask = FL | FR | LFE | RL | RR | RC }, ++ { .ca_id = 0x0e, .n_ch = 8, ++ .mask = FL | FR | FC | RL | RR | RC }, ++ { .ca_id = 0x10, .n_ch = 8, ++ .mask = FL | FR | RL | RR | RLC | RRC }, ++ { .ca_id = 0x11, .n_ch = 8, ++ .mask = FL | FR | LFE | RL | RR | RLC | RRC }, ++ { .ca_id = 0x12, .n_ch = 8, ++ .mask = FL | FR | FC | RL | RR | RLC | RRC }, ++ { .ca_id = 0x14, .n_ch = 8, ++ .mask = FL | FR | FLC | FRC }, ++ { .ca_id = 0x15, .n_ch = 8, ++ .mask = FL | FR | LFE | FLC | FRC }, ++ { .ca_id = 0x16, .n_ch = 8, ++ .mask = FL | FR | FC | FLC | FRC }, ++ { .ca_id = 0x17, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | FLC | FRC }, ++ { .ca_id = 0x18, .n_ch = 8, ++ .mask = FL | FR | RC | FLC | FRC }, ++ { .ca_id = 0x19, .n_ch = 8, ++ .mask = FL | FR | LFE | RC | FLC | FRC }, ++ { .ca_id = 0x1a, .n_ch = 8, ++ .mask = FL | FR | RC | FC | FLC | FRC }, ++ { .ca_id = 0x1b, .n_ch = 8, ++ .mask = FL | FR | LFE | RC | FC | FLC | FRC }, ++ { .ca_id = 0x1c, .n_ch = 8, ++ .mask = FL | FR | RL | RR | FLC | FRC }, ++ { .ca_id = 0x1d, .n_ch = 8, ++ .mask = FL | FR | LFE | RL | RR | FLC | FRC }, ++ { .ca_id = 0x1e, .n_ch = 8, ++ .mask = FL | FR | FC | RL | RR | FLC | FRC }, ++ { .ca_id = 0x1f, .n_ch = 8, ++ .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC }, ++}; ++ ++static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc) ++{ ++ int i; ++ static const unsigned long hdmi_codec_eld_spk_alloc_bits[] = { ++ [0] = FL | FR, [1] = LFE, [2] = FC, [3] = RL | RR, ++ [4] = RC, [5] = FLC | FRC, [6] = RLC | RRC, ++ }; ++ unsigned long spk_mask = 0; ++ ++ for (i = 0; i < ARRAY_SIZE(hdmi_codec_eld_spk_alloc_bits); i++) { ++ if (spk_alloc & (1 << i)) ++ spk_mask |= hdmi_codec_eld_spk_alloc_bits[i]; ++ } ++ ++ return spk_mask; ++} ++ ++static int hdmi_codec_get_ch_alloc_table_idx(struct vc4_hdmi *vc4_hdmi, ++ unsigned char channels) ++{ ++ struct drm_connector *connector = &vc4_hdmi->connector; ++ int i; ++ u8 spk_alloc; ++ unsigned long spk_mask; ++ const struct hdmi_codec_cea_spk_alloc *cap = hdmi_codec_channel_alloc; ++ ++ spk_alloc = drm_eld_get_spk_alloc(connector->eld); ++ spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc); ++ ++ for (i = 0; i < ARRAY_SIZE(hdmi_codec_channel_alloc); i++, cap++) { ++ /* If spk_alloc == 0, HDMI is unplugged return stereo config*/ ++ if (!spk_alloc && cap->ca_id == 0) ++ return i; ++ if (cap->n_ch != channels) ++ continue; ++ if (!(cap->mask == (spk_mask & cap->mask))) ++ continue; ++ return i; ++ } ++ ++ return -EINVAL; ++} ++ ++static void hdmi_codec_eld_chmap(struct vc4_hdmi *vc4_hdmi) ++{ ++ struct drm_connector *connector = &vc4_hdmi->connector; ++ u8 spk_alloc; ++ unsigned long spk_mask; ++ ++ spk_alloc = drm_eld_get_spk_alloc(connector->eld); ++ spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc); ++ ++ /* Detect if only stereo supported, else return 8 channels mappings */ ++ if ((spk_mask & ~(FL | FR))) ++ vc4_hdmi->audio.chmap = hdmi_codec_8ch_chmaps; ++ else ++ vc4_hdmi->audio.chmap = hdmi_codec_stereo_chmaps; ++} ++ + static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused) + { + struct drm_info_node *node = (struct drm_info_node *)m->private; +@@ -350,6 +656,9 @@ static void vc4_hdmi_set_audio_infoframe + frame.audio.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; + frame.audio.channels = vc4_hdmi->audio.channels; + ++ /* Select a channel allocation that matches with ELD and pcm channels */ ++ frame.audio.channel_allocation = vc4_hdmi->audio.chmap_idx; ++ + vc4_hdmi_write_infoframe(encoder, &frame); + } + +@@ -881,6 +1190,10 @@ static int vc4_hdmi_audio_startup(struct + if (ret) + return ret; + ++ /* Select chmap supported */ ++ vc4_hdmi->audio.max_channels = 8; ++ hdmi_codec_eld_chmap(vc4_hdmi); ++ + return 0; + } + +@@ -967,6 +1280,7 @@ static int vc4_hdmi_audio_prepare(struct + u32 channel_map; + u32 mai_audio_format; + u32 mai_sample_rate; ++ int idx; + + if (substream != vc4_hdmi->audio.substream) + return -EINVAL; +@@ -1027,6 +1341,14 @@ static int vc4_hdmi_audio_prepare(struct + HDMI_WRITE(HDMI_AUDIO_PACKET_CONFIG, audio_packet_config); + vc4_hdmi_set_n_cts(vc4_hdmi); + ++ idx = hdmi_codec_get_ch_alloc_table_idx(vc4_hdmi, vc4_hdmi->audio.channels); ++ if (idx < 0) { ++ DRM_ERROR("Not able to map channels to speakers (%d)\n", idx); ++ vc4_hdmi->audio.chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; ++ } else { ++ vc4_hdmi->audio.chmap_idx = hdmi_codec_channel_alloc[idx].ca_id; ++ } ++ + return 0; + } + +@@ -1145,6 +1467,89 @@ static int vc4_spdif_mask_get(struct snd + return 0; + } + ++/* ++ * ALSA API channel-map control callbacks ++ */ ++static int vc4_chmap_ctl_info(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); ++ struct vc4_hdmi *vc4_hdmi = snd_component_to_hdmi(component); ++ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = vc4_hdmi->audio.max_channels; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = SNDRV_CHMAP_LAST; ++ ++ return 0; ++} ++ ++static int vc4_chmap_ctl_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); ++ struct vc4_hdmi *vc4_hdmi = snd_component_to_hdmi(component); ++ unsigned const char *map; ++ unsigned int i; ++ ++ if (!vc4_hdmi->audio.chmap) ++ return -EINVAL; ++ ++ map = vc4_hdmi->audio.chmap[vc4_hdmi->audio.chmap_idx].map; ++ ++ for (i = 0; i < vc4_hdmi->audio.max_channels; i++) { ++ if (vc4_hdmi->audio.chmap_idx == HDMI_CODEC_CHMAP_IDX_UNKNOWN) ++ ucontrol->value.integer.value[i] = 0; ++ else ++ ucontrol->value.integer.value[i] = map[i]; ++ } ++ return 0; ++} ++ ++static int vc4_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag, ++ unsigned int size, unsigned int __user *tlv) ++{ ++ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); ++ struct vc4_hdmi *vc4_hdmi = snd_component_to_hdmi(component); ++ const struct snd_pcm_chmap_elem *map; ++ unsigned int __user *dst; ++ int c, count = 0; ++ ++ if (!vc4_hdmi->audio.chmap) ++ return -EINVAL; ++ if (size < 8) ++ return -ENOMEM; ++ if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv)) ++ return -EFAULT; ++ size -= 8; ++ dst = tlv + 2; ++ for (map = vc4_hdmi->audio.chmap; map->channels; map++) { ++ int chs_bytes = map->channels * 4; ++ //if (!valid_chmap_channels(info, map->channels)) ++ // continue; ++ if (size < 8) ++ return -ENOMEM; ++ if (put_user(SNDRV_CTL_TLVT_CHMAP_FIXED, dst) || ++ put_user(chs_bytes, dst + 1)) ++ return -EFAULT; ++ dst += 2; ++ size -= 8; ++ count += 8; ++ if (size < chs_bytes) ++ return -ENOMEM; ++ size -= chs_bytes; ++ count += chs_bytes; ++ for (c = 0; c < map->channels; c++) { ++ if (put_user(map->map[c], dst)) ++ return -EFAULT; ++ dst++; ++ } ++ } ++ if (put_user(count, tlv + 1)) ++ return -EFAULT; ++ return 0; ++} ++ + static const struct snd_kcontrol_new vc4_hdmi_audio_controls[] = { + { + .access = SNDRV_CTL_ELEM_ACCESS_READ | +@@ -1167,6 +1572,16 @@ static const struct snd_kcontrol_new vc4 + .info = vc4_spdif_info, + .get = vc4_spdif_mask_get, + }, ++ { ++ .access = SNDRV_CTL_ELEM_ACCESS_READ | ++ SNDRV_CTL_ELEM_ACCESS_TLV_READ | ++ SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, ++ .iface = SNDRV_CTL_ELEM_IFACE_PCM, ++ .name = "Playback Channel Map", ++ .info = vc4_chmap_ctl_info, ++ .get = vc4_chmap_ctl_get, ++ .tlv.c = vc4_chmap_ctl_tlv, ++ }, + }; + + static const struct snd_soc_dapm_widget vc4_hdmi_audio_widgets[] = { +--- a/drivers/gpu/drm/vc4/vc4_hdmi.h ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.h +@@ -117,6 +117,9 @@ struct vc4_hdmi_audio { + bool streaming; + + unsigned char iec_status[4]; ++ const struct snd_pcm_chmap_elem *chmap; ++ unsigned int chmap_idx; ++ unsigned int max_channels; + }; + + /* General HDMI hardware state. */ diff --git a/target/linux/bcm27xx/patches-5.4/950-0921-SQUASH-leds-actpwr-delete-unused-variable.patch b/target/linux/bcm27xx/patches-5.4/950-0921-SQUASH-leds-actpwr-delete-unused-variable.patch new file mode 100644 index 0000000000..1166f6a2ed --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0921-SQUASH-leds-actpwr-delete-unused-variable.patch @@ -0,0 +1,20 @@ +From 867a447dbe461b6cfdfae2fcd71c449dced9cd8a Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 20 Jul 2020 09:35:46 +0100 +Subject: [PATCH] SQUASH: leds: actpwr - delete unused variable + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/leds/trigger/ledtrig-actpwr.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/leds/trigger/ledtrig-actpwr.c ++++ b/drivers/leds/trigger/ledtrig-actpwr.c +@@ -94,7 +94,6 @@ static void actpwr_trig_cycle(struct tim + { + struct actpwr_trig_data *trig = &actpwr_data; + struct actpwr_vled *active; +- enum led_brightness value; + + active = &trig->virt_leds[trig->next_active]; + trig->active = active; diff --git a/target/linux/bcm27xx/patches-5.4/950-0922-staging-vchiq_arm-children-inherit-DMA-config.patch b/target/linux/bcm27xx/patches-5.4/950-0922-staging-vchiq_arm-children-inherit-DMA-config.patch new file mode 100644 index 0000000000..9dbc80c4ac --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0922-staging-vchiq_arm-children-inherit-DMA-config.patch @@ -0,0 +1,36 @@ +From 9f0d49445428265cd6cf0862d94bc7f3dd1304d0 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Tue, 21 Jul 2020 17:34:09 +0100 +Subject: [PATCH] staging: vchiq_arm: children inherit DMA config + +Although it is no longer necessary for vchiq's children to have a +different DMA configuration to the parent, they do still need to +explicitly to have their DMA configuration set - to be that of the +parent. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +@@ -3205,8 +3205,18 @@ vchiq_register_child(struct platform_dev + + child->dev.of_node = np; + ++ /* ++ * We want the dma-ranges etc to be copied from the parent VCHIQ device ++ * to be passed on to the children without a node of their own. ++ */ ++ if (!np) ++ np = pdev->dev.of_node; ++ + of_dma_configure(&child->dev, np, true); + ++ if (np != pdev->dev.of_node) ++ of_node_put(np); ++ + return child; + } + diff --git a/target/linux/bcm27xx/patches-5.4/950-0923-ARM-dts-2711-DMA-can-address-36-bits.patch b/target/linux/bcm27xx/patches-5.4/950-0923-ARM-dts-2711-DMA-can-address-36-bits.patch new file mode 100644 index 0000000000..a77737986e --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0923-ARM-dts-2711-DMA-can-address-36-bits.patch @@ -0,0 +1,25 @@ +From df3f3eba7e6f19694369ea52360c0d5d18d310c3 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Wed, 22 Jul 2020 17:45:24 +0100 +Subject: [PATCH] ARM: dts: 2711 DMA can address 36 bits + +Kernels prior to 5.7 only see the first entry in dma-ranges, so make +it cover the full addressable range. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2711-rpi.dtsi | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi +@@ -193,8 +193,7 @@ + <0x0 0x40000000 0x0 0xff800000 0x0 0x00800000>, + <0x6 0x00000000 0x6 0x00000000 0x0 0x40000000>, + <0x0 0x00000000 0x0 0x00000000 0x0 0xfc000000>; +- dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0xfc000000>, +- <0x1 0x00000000 0x1 0x00000000 0x1 0x00000000>; ++ dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x4 0x00000000>; + + dma40: dma@7e007b00 { + compatible = "brcm,bcm2711-dma"; diff --git a/target/linux/bcm27xx/patches-5.4/950-0924-bcm2835-dma-Advertise-the-full-DMA-range.patch b/target/linux/bcm27xx/patches-5.4/950-0924-bcm2835-dma-Advertise-the-full-DMA-range.patch new file mode 100644 index 0000000000..33c740ffef --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0924-bcm2835-dma-Advertise-the-full-DMA-range.patch @@ -0,0 +1,77 @@ +From bf7baee1935c4d485083c3b3c439631ae4ac3c0f Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Wed, 22 Jul 2020 17:59:31 +0100 +Subject: [PATCH] bcm2835-dma: Advertise the full DMA range + +Unless the DMA mask is set wider than 32 bits, DMA mapping will use a +bounce buffer. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/dma/bcm2835-dma.c | 18 +++++++++++++++--- + 1 file changed, 15 insertions(+), 3 deletions(-) + +--- a/drivers/dma/bcm2835-dma.c ++++ b/drivers/dma/bcm2835-dma.c +@@ -41,6 +41,7 @@ + #define BCM2711_DMA_MEMCPY_CHAN 14 + + struct bcm2835_dma_cfg_data { ++ u64 dma_mask; + u32 chan_40bit_mask; + }; + +@@ -302,10 +303,12 @@ DEFINE_SPINLOCK(memcpy_lock); + + static const struct bcm2835_dma_cfg_data bcm2835_dma_cfg = { + .chan_40bit_mask = 0, ++ .dma_mask = DMA_BIT_MASK(32), + }; + + static const struct bcm2835_dma_cfg_data bcm2711_dma_cfg = { + .chan_40bit_mask = BIT(11) | BIT(12) | BIT(13) | BIT(14), ++ .dma_mask = DMA_BIT_MASK(36), + }; + + static inline size_t bcm2835_dma_max_frame_length(struct bcm2835_chan *c) +@@ -1185,6 +1188,8 @@ static struct dma_chan *bcm2835_dma_xlat + + static int bcm2835_dma_probe(struct platform_device *pdev) + { ++ const struct bcm2835_dma_cfg_data *cfg_data; ++ const struct of_device_id *of_id; + struct bcm2835_dmadev *od; + struct resource *res; + void __iomem *base; +@@ -1194,13 +1199,20 @@ static int bcm2835_dma_probe(struct plat + int irq_flags; + uint32_t chans_available; + char chan_name[BCM2835_DMA_CHAN_NAME_SIZE]; +- const struct of_device_id *of_id; + int chan_count, chan_start, chan_end; + ++ of_id = of_match_node(bcm2835_dma_of_match, pdev->dev.of_node); ++ if (!of_id) { ++ dev_err(&pdev->dev, "Failed to match compatible string\n"); ++ return -EINVAL; ++ } ++ ++ cfg_data = of_id->data; ++ + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; + +- rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); ++ rc = dma_set_mask_and_coherent(&pdev->dev, cfg_data->dma_mask); + if (rc) { + dev_err(&pdev->dev, "Unable to set DMA mask\n"); + return rc; +@@ -1266,7 +1278,7 @@ static int bcm2835_dma_probe(struct plat + return -EINVAL; + } + +- od->cfg_data = of_id->data; ++ od->cfg_data = cfg_data; + + /* Request DMA channel mask from device tree */ + if (of_property_read_u32(pdev->dev.of_node, diff --git a/target/linux/bcm27xx/patches-5.4/950-0925-ARM-dts-Add-UART-skip-init-properties-for-U-boot.patch b/target/linux/bcm27xx/patches-5.4/950-0925-ARM-dts-Add-UART-skip-init-properties-for-U-boot.patch new file mode 100644 index 0000000000..be6c9dd250 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0925-ARM-dts-Add-UART-skip-init-properties-for-U-boot.patch @@ -0,0 +1,35 @@ +From 197b4fbd218a0a12573cdfcb011eeb3f00765d96 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Fri, 17 Jul 2020 11:20:07 +0100 +Subject: [PATCH] ARM: dts: Add UART skip-init properties for U-boot + +U-boot can get stuck trying to initialise UARTs that aren't mapped +to the pin header. There is no reason for U-boot not to rely on the +initialisation by the firmware, so tag both UARTs with the u-boot +magic boolean property "skip-init". + +See: https://github.com/raspberrypi/linux/pull/3731 + https://lists.denx.de/pipermail/u-boot/2017-April/285606.html + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm270x-rpi.dtsi | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/arch/arm/boot/dts/bcm270x-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm270x-rpi.dtsi +@@ -102,6 +102,14 @@ + }; + }; + ++&uart0 { ++ skip-init; ++}; ++ ++&uart1 { ++ skip-init; ++}; ++ + &txp { + status = "disabled"; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0926-drm-vc4-Remove-UIF-from-the-list-of-modifiers-return.patch b/target/linux/bcm27xx/patches-5.4/950-0926-drm-vc4-Remove-UIF-from-the-list-of-modifiers-return.patch new file mode 100644 index 0000000000..7ae22a72fc --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0926-drm-vc4-Remove-UIF-from-the-list-of-modifiers-return.patch @@ -0,0 +1,29 @@ +From 132454781a30f57ccb393443209def76dc0b572a Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 28 Jul 2020 13:01:42 +0100 +Subject: [PATCH] drm/vc4: Remove UIF from the list of modifiers + returned by format_mod_supported + +FKMS was listing UIF in the supported modifiers from format_mod_supported +when actually the pipeline doesn't support it. X was then choosing to +use it, and that then failed to render. + +Remove references to UIF. + +https://github.com/raspberrypi/linux/issues/3665 + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -718,7 +718,6 @@ static bool vc4_fkms_format_mod_supporte + switch (modifier) { + case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: + case DRM_FORMAT_MOD_LINEAR: +- case DRM_FORMAT_MOD_BROADCOM_UIF: + return true; + default: + return false; diff --git a/target/linux/bcm27xx/patches-5.4/950-0927-ARM-proc-v7-Force-misalignment-of-early-stmia.patch b/target/linux/bcm27xx/patches-5.4/950-0927-ARM-proc-v7-Force-misalignment-of-early-stmia.patch new file mode 100644 index 0000000000..158ff69bff --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0927-ARM-proc-v7-Force-misalignment-of-early-stmia.patch @@ -0,0 +1,60 @@ +From 965cce6b1c6acc25d7cfd29ccf95c8ebbf1d7f57 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Wed, 29 Jul 2020 13:47:55 +0100 +Subject: [PATCH] ARM: proc-v7: Force misalignment of early stmia + +In an attempt to prevent the problem of CPUn not starting, explicitly +misalign the scratch space used to save registers acros the cache +invalidation. + +Notes: +At this stage in the boot process the core is running with its cache +disabled. Before enabling the cache its contents must be explicitly +invalidated, a process that requires quite a few registers that the +caller must preserve. Evidence suggests that something is writing a +block of zeroes over that space at a time when all other cores should +be idle, possibly some kind of write-combiner, and the misalignment is +designed to disrupt any write-coalescing. + +In truth, I don't understand why this patch works, and when the failure +is so random it is hard to be certain that this isn't just rolling the +dice again. One interesting test would be to change the "addeq r12, #4"s +to "addeq r12, #0"s determine see if the offset itself is significant or +just the additional code. + +See: https://github.com/Hexxeh/rpi-firmware/issues/232 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/mm/proc-v7.S | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/arch/arm/mm/proc-v7.S ++++ b/arch/arm/mm/proc-v7.S +@@ -287,6 +287,8 @@ __v7_ca17mp_setup: + mov r10, #0 + 1: adr r0, __v7_setup_stack_ptr + ldr r12, [r0] ++ tst r12, #0x1f ++ addeq r12, r12, #4 + add r12, r12, r0 @ the local stack + stmia r12, {r1-r6, lr} @ v7_invalidate_l1 touches r0-r6 + bl v7_invalidate_l1 +@@ -474,6 +476,8 @@ __v7_setup: + adr r0, __v7_setup_stack_ptr + ldr r12, [r0] + add r12, r12, r0 @ the local stack ++ tst r12, #0x1f ++ addeq r12, r12, #4 + stmia r12, {r1-r6, lr} @ v7_invalidate_l1 touches r0-r6 + bl v7_invalidate_l1 + ldmia r12, {r1-r6, lr} +@@ -557,7 +561,7 @@ ENDPROC(__v7_setup) + .bss + .align 2 + __v7_setup_stack: +- .space 4 * 7 @ 7 registers ++ .space 4 * 8 @ 7 registers + 1 spare + + __INITDATA + diff --git a/target/linux/bcm27xx/patches-5.4/950-0928-overlays-Fix-sc16is75x-overlays-w.r.t.-serdev.patch b/target/linux/bcm27xx/patches-5.4/950-0928-overlays-Fix-sc16is75x-overlays-w.r.t.-serdev.patch new file mode 100644 index 0000000000..ed9f1e1492 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0928-overlays-Fix-sc16is75x-overlays-w.r.t.-serdev.patch @@ -0,0 +1,182 @@ +From a934bc7776953d7ce8e27c2d8720de58d5ceeeef Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Thu, 30 Jul 2020 15:13:09 +0100 +Subject: [PATCH] overlays: Fix sc16is75x overlays w.r.t. serdev + +Enabling serdev support in rpi-5.4.y had the unintended consequence of +making any UART device node with a subnode look like a "serdev" node, +which prevents it from having the usual /dev/ttyXXX character device. +Solve the problem by moving the subnode (a static clock declaration) +into the root node. + +At the same time, regularise (and sometimes correct) the overlays. + +See: https://github.com/raspberrypi/linux/issues/3765 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + .../dts/overlays/sc16is750-i2c-overlay.dts | 23 +++++++++------- + .../dts/overlays/sc16is752-i2c-overlay.dts | 27 ++++++++++--------- + .../dts/overlays/sc16is752-spi0-overlay.dts | 21 +++++++++------ + .../dts/overlays/sc16is752-spi1-overlay.dts | 6 ++--- + 4 files changed, 45 insertions(+), 32 deletions(-) + +--- a/arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sc16is750-i2c-overlay.dts +@@ -13,26 +13,31 @@ + + sc16is750: sc16is750@48 { + compatible = "nxp,sc16is750"; +- reg = <0x48>; /* address */ ++ reg = <0x48>; /* i2c address */ + clocks = <&sc16is750_clk>; + interrupt-parent = <&gpio>; + interrupts = <24 2>; /* IRQ_TYPE_EDGE_FALLING */ ++ gpio-controller; + #gpio-cells = <2>; +- +- sc16is750_clk: sc16is750_clk { +- compatible = "fixed-clock"; +- #clock-cells = <0>; +- clock-frequency = <14745600>; +- }; ++ i2c-max-frequency = <400000>; + }; + }; + }; + ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ sc16is750_clk: sc16is750_i2c_clk@48 { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <14745600>; ++ }; ++ }; ++ }; + + __overrides__ { + int_pin = <&sc16is750>,"interrupts:0"; +- addr = <&sc16is750>,"reg:0",<&sc16is750_clk>,"name"; ++ addr = <&sc16is750>,"reg:0", <&sc16is750_clk>,"name"; + xtal = <&sc16is750_clk>,"clock-frequency:0"; + }; +- + }; +--- a/arch/arm/boot/dts/overlays/sc16is752-i2c-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sc16is752-i2c-overlay.dts +@@ -5,29 +5,32 @@ + compatible = "brcm,bcm2835"; + + fragment@0 { +- target = <&i2c1>; +- +- frag1: __overlay__ { ++ target = <&i2c_arm>; ++ __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + sc16is752: sc16is752@48 { + compatible = "nxp,sc16is752"; +- reg = <0x48>; // i2c address ++ reg = <0x48>; /* i2c address */ + clocks = <&sc16is752_clk>; + interrupt-parent = <&gpio>; +- interrupts = <24 0x2>; /* IRQ_TYPE_EDGE_FALLING */ ++ interrupts = <24 2>; /* IRQ_TYPE_EDGE_FALLING */ + gpio-controller; +- #gpio-cells = <0>; ++ #gpio-cells = <2>; + i2c-max-frequency = <400000>; +- status = "okay"; ++ }; ++ }; ++ }; + +- sc16is752_clk: sc16is752_clk { +- compatible = "fixed-clock"; +- #clock-cells = <0>; +- clock-frequency = <14745600>; +- }; ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ sc16is752_clk: sc16is752_i2c_clk@48 { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <14745600>; + }; + }; + }; +--- a/arch/arm/boot/dts/overlays/sc16is752-spi0-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sc16is752-spi0-overlay.dts +@@ -17,15 +17,9 @@ + clocks = <&sc16is752_clk>; + interrupt-parent = <&gpio>; + interrupts = <24 2>; /* IRQ_TYPE_EDGE_FALLING */ +- #gpio-controller; ++ gpio-controller; + #gpio-cells = <2>; + spi-max-frequency = <4000000>; +- +- sc16is752_clk: sc16is752_clk { +- compatible = "fixed-clock"; +- #clock-cells = <0>; +- clock-frequency = <14745600>; +- }; + }; + }; + }; +@@ -37,8 +31,19 @@ + }; + }; + ++ fragment@2 { ++ target-path = "/"; ++ __overlay__ { ++ sc16is752_clk: sc16is752_spi0_0_clk { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <14745600>; ++ }; ++ }; ++ }; ++ + __overrides__ { + int_pin = <&sc16is752>,"interrupts:0"; +- xtal = <&sc16is752_clk>, "clock-frequency:0"; ++ xtal = <&sc16is752_clk>,"clock-frequency:0"; + }; + }; +--- a/arch/arm/boot/dts/overlays/sc16is752-spi1-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sc16is752-spi1-overlay.dts +@@ -21,7 +21,7 @@ + + fragment@1 { + target = <&spi1>; +- frag1: __overlay__ { ++ __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; +@@ -35,7 +35,7 @@ + clocks = <&sc16is752_clk>; + interrupt-parent = <&gpio>; + interrupts = <24 2>; /* IRQ_TYPE_EDGE_FALLING */ +- #gpio-controller; ++ gpio-controller; + #gpio-cells = <2>; + spi-max-frequency = <4000000>; + }; +@@ -52,7 +52,7 @@ + fragment@3 { + target-path = "/"; + __overlay__ { +- sc16is752_clk: sc16is752_spi1_clk { ++ sc16is752_clk: sc16is752_spi1_0_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <14745600>; diff --git a/target/linux/bcm27xx/patches-5.4/950-0929-overlays-Delete-spi0-hw-cs.patch b/target/linux/bcm27xx/patches-5.4/950-0929-overlays-Delete-spi0-hw-cs.patch new file mode 100644 index 0000000000..044a3ad3f1 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0929-overlays-Delete-spi0-hw-cs.patch @@ -0,0 +1,87 @@ +From 9fcbc40311f8de3f7a0a27155f310ff19e150d76 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Thu, 30 Jul 2020 18:06:24 +0100 +Subject: [PATCH] overlays: Delete spi0-hw-cs + +The spi0-hw-cs overlay is unnecessary (and actually harmful) with the +current kernels. Delete it, leaving a note in the README and a +deprecation message from the firmware: + + dterror: overlay 'spi0-hw-cs' is deprecated: no longer necessary + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/Makefile | 1 - + arch/arm/boot/dts/overlays/README | 6 ++--- + arch/arm/boot/dts/overlays/overlay_map.dts | 4 +++ + .../boot/dts/overlays/spi0-hw-cs-overlay.dts | 26 ------------------- + 4 files changed, 7 insertions(+), 30 deletions(-) + delete mode 100644 arch/arm/boot/dts/overlays/spi0-hw-cs-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -159,7 +159,6 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + spi-gpio40-45.dtbo \ + spi-rtc.dtbo \ + spi0-cs.dtbo \ +- spi0-hw-cs.dtbo \ + spi1-1cs.dtbo \ + spi1-2cs.dtbo \ + spi1-3cs.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -2346,9 +2346,9 @@ Params: cs0_pin GPIO pin + + + Name: spi0-hw-cs +-Info: Re-enables hardware CS/CE (chip selects) for SPI0 +-Load: dtoverlay=spi0-hw-cs +-Params: <None> ++Info: This overlay has been deprecated and removed because it is no longer ++ necessary and has been seen to prevent spi0 from working. ++Load: <Deprecated> + + + Name: spi1-1cs +--- a/arch/arm/boot/dts/overlays/overlay_map.dts ++++ b/arch/arm/boot/dts/overlays/overlay_map.dts +@@ -61,6 +61,10 @@ + deprecated = "use sdio,bus_width=1,gpios_22_25"; + }; + ++ spi0-hw-cs { ++ deprecated = "no longer necessary"; ++ }; ++ + spi3-1cs { + bcm2711; + }; +--- a/arch/arm/boot/dts/overlays/spi0-hw-cs-overlay.dts ++++ /dev/null +@@ -1,26 +0,0 @@ +-/* +- * Device tree overlay to re-enable hardware CS for SPI0 +- */ +- +-/dts-v1/; +-/plugin/; +- +-/ { +- compatible = "brcm,bcm2835"; +- +- fragment@0 { +- target = <&spi0>; +- __overlay__ { +- cs-gpios = <0>, <0>; +- status = "okay"; +- }; +- }; +- +- fragment@1 { +- target = <&spi0_cs_pins>; +- __overlay__ { +- brcm,pins = <8 7>; +- brcm,function = <4>; /* alt0 */ +- }; +- }; +-}; diff --git a/target/linux/bcm27xx/patches-5.4/950-0930-backlight-gpio-Explicitly-set-the-direction-of-the-G.patch b/target/linux/bcm27xx/patches-5.4/950-0930-backlight-gpio-Explicitly-set-the-direction-of-the-G.patch new file mode 100644 index 0000000000..d016cdaa43 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0930-backlight-gpio-Explicitly-set-the-direction-of-the-G.patch @@ -0,0 +1,88 @@ +From aa455fdc2495cb05b65cc03cc472de43df632c5c Mon Sep 17 00:00:00 2001 +From: Bartosz Golaszewski <bgolaszewski@baylibre.com> +Date: Tue, 22 Oct 2019 10:36:24 +0200 +Subject: [PATCH] backlight: gpio: Explicitly set the direction of + the GPIO + +commit 706dc68102bc7421a9e6573d149ab6d769d71cc7 upstream. + +The GPIO backlight driver currently requests the line 'as is', without +acively setting its direction. This can lead to problems: if the line +is in input mode by default, we won't be able to drive it later when +updating the status and also reading its initial value doesn't make +sense for backlight setting. + +Request the line 'as is' initially, so that we can read its value +without affecting it but then change the direction to output explicitly +when setting the initial brightness. + +Also: check the current direction and only read the value if it's output. + +Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> +Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org> +Signed-off-by: Lee Jones <lee.jones@linaro.org> +--- + drivers/video/backlight/gpio_backlight.c | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +--- a/drivers/video/backlight/gpio_backlight.c ++++ b/drivers/video/backlight/gpio_backlight.c +@@ -26,9 +26,8 @@ struct gpio_backlight { + int def_value; + }; + +-static int gpio_backlight_update_status(struct backlight_device *bl) ++static int gpio_backlight_get_next_brightness(struct backlight_device *bl) + { +- struct gpio_backlight *gbl = bl_get_data(bl); + int brightness = bl->props.brightness; + + if (bl->props.power != FB_BLANK_UNBLANK || +@@ -36,6 +35,14 @@ static int gpio_backlight_update_status( + bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) + brightness = 0; + ++ return brightness; ++} ++ ++static int gpio_backlight_update_status(struct backlight_device *bl) ++{ ++ struct gpio_backlight *gbl = bl_get_data(bl); ++ int brightness = gpio_backlight_get_next_brightness(bl); ++ + gpiod_set_value_cansleep(gbl->gpiod, brightness); + + return 0; +@@ -86,7 +93,8 @@ static int gpio_backlight_initial_power_ + return gbl->def_value ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; + + /* if the enable GPIO is disabled, do not enable the backlight */ +- if (gpiod_get_value_cansleep(gbl->gpiod) == 0) ++ if (gpiod_get_direction(gbl->gpiod) == 0 && ++ gpiod_get_value_cansleep(gbl->gpiod) == 0) + return FB_BLANK_POWERDOWN; + + return FB_BLANK_UNBLANK; +@@ -100,7 +108,7 @@ static int gpio_backlight_probe(struct p + struct backlight_properties props; + struct backlight_device *bl; + struct gpio_backlight *gbl; +- int ret; ++ int ret, init_brightness; + + gbl = devm_kzalloc(&pdev->dev, sizeof(*gbl), GFP_KERNEL); + if (gbl == NULL) +@@ -153,7 +161,12 @@ static int gpio_backlight_probe(struct p + bl->props.power = gpio_backlight_initial_power_state(gbl); + bl->props.brightness = 1; + +- backlight_update_status(bl); ++ init_brightness = gpio_backlight_get_next_brightness(bl); ++ ret = gpiod_direction_output(gbl->gpiod, init_brightness); ++ if (ret) { ++ dev_err(&pdev->dev, "failed to set initial brightness\n"); ++ return ret; ++ } + + platform_set_drvdata(pdev, bl); + return 0; diff --git a/target/linux/bcm27xx/patches-5.4/950-0931-overlays-Add-maxtherm-overlay-for-MAX6675-31855.patch b/target/linux/bcm27xx/patches-5.4/950-0931-overlays-Add-maxtherm-overlay-for-MAX6675-31855.patch new file mode 100644 index 0000000000..882cb8df5e --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0931-overlays-Add-maxtherm-overlay-for-MAX6675-31855.patch @@ -0,0 +1,238 @@ +From 56e726d1631c9551530b8db4127352c64c3cb94d Mon Sep 17 00:00:00 2001 +From: Dougie Lawson <dl1ims@gmail.com> +Date: Mon, 27 Jul 2020 23:52:40 +0100 +Subject: [PATCH] overlays: Add maxtherm overlay for MAX6675/31855 + +Add an overlay - maxtherm - to support the MAX6675 and MAX31855 family +of thermocouples. + +Developed from an original set of overlays by Dougie Lawson. + +See: https://github.com/raspberrypi/linux/pull/3763 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 30 ++++ + .../boot/dts/overlays/maxtherm-overlay.dts | 166 ++++++++++++++++++ + 3 files changed, 197 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/maxtherm-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -98,6 +98,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + justboom-digi.dtbo \ + ltc294x.dtbo \ + max98357a.dtbo \ ++ maxtherm.dtbo \ + mbed-dac.dtbo \ + mcp23017.dtbo \ + mcp23s17.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1622,6 +1622,36 @@ Params: no-sdmode Driver d + of the DAC (default GPIO4 if parameter omitted). + + ++Name: maxtherm ++Info: Configure a MAX6675 or MAX31855 thermocouple as an IIO device. ++ ++ For devices on spi1 or spi2, the interfaces should be enabled ++ with one of the spi1-1/2/3cs and/or spi2-1/2/3cs overlays. ++ The overlay expects to disable the relevant spidev node, so also using ++ e.g. cs0_spidev=off is unnecessary. ++ ++ Note: with the 5.7 kernel (and later) there will also be ++ overlays for MAX31855E, MAX31855J, MAX31855K, ++ MAX31885N, MAX31855R, MAX31855S and MAX31855T. ++ ++ Example: ++ MAX31855 on /dev/spidev0.0 ++ dtoverlay=maxtherm,spi0-0,max31855 ++ ++Load: dtoverlay=maxtherm,<param>=<val> ++Params: spi<n>-<m> Configure device at spi<n>, cs<m> ++ (boolean, required) ++ max6675 Enable support for the MAX6675 (default) ++ max31855 Enable support for the MAX31855 ++ max31855e Enable support for the MAX31855E ++ max31855j Enable support for the MAX31855J ++ max31855k Enable support for the MAX31855K ++ max31855n Enable support for the MAX31855N ++ max31855r Enable support for the MAX31855R ++ max31855s Enable support for the MAX31855S ++ max31855t Enable support for the MAX31855T ++ ++ + Name: mbed-dac + Info: Configures the mbed AudioCODEC (TLV320AIC23B) + Load: dtoverlay=mbed-dac +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/maxtherm-overlay.dts +@@ -0,0 +1,166 @@ ++/* ++ * Universal device tree overlay for SPI devices ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&spidev0>; ++ __dormant__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spidev1>; ++ __dormant__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target-path = "spi1/spidev@0"; ++ __dormant__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { ++ target-path = "spi1/spidev@1"; ++ __dormant__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@4 { ++ target-path = "spi1/spidev@2"; ++ __dormant__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@5 { ++ target-path = "spi2/spidev@0"; ++ __dormant__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@6 { ++ target-path = "spi2/spidev@1"; ++ __dormant__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@7 { ++ target-path = "spi2/spidev@2"; ++ __dormant__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ maxfrag: fragment@8 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ max: maxtherm@0 { ++ compatible = "maxim,max6675"; ++ reg = <0>; ++ spi-max-frequency = <500000>; ++ }; ++ }; ++ }; ++ ++ fragment@9 { ++ target = <&max>; ++ __dormant__ { ++ compatible = "maxim,max31855e", "maxim,max31855"; ++ }; ++ }; ++ ++ fragment@10 { ++ target = <&max>; ++ __dormant__ { ++ compatible = "maxim,max31855j", "maxim,max31855"; ++ }; ++ }; ++ ++ fragment@11 { ++ target = <&max>; ++ __dormant__ { ++ compatible = "maxim,max31855k", "maxim,max31855"; ++ }; ++ }; ++ ++ fragment@12 { ++ target = <&max>; ++ __dormant__ { ++ compatible = "maxim,max31855n", "maxim,max31855"; ++ }; ++ }; ++ ++ fragment@13 { ++ target = <&max>; ++ __dormant__ { ++ compatible = "maxim,max31855r", "maxim,max31855"; ++ }; ++ }; ++ ++ fragment@14 { ++ target = <&max>; ++ __dormant__ { ++ compatible = "maxim,max31855s", "maxim,max31855"; ++ }; ++ }; ++ ++ fragment@15 { ++ target = <&max>; ++ __dormant__ { ++ compatible = "maxim,max31855t", "maxim,max31855"; ++ }; ++ }; ++ ++ __overrides__ { ++ spi0-0 = <0>, "+0", ++ <&maxfrag>,"target:0=",<&spi0>, ++ <&max>,"reg:0=0"; ++ spi0-1 = <0>, "+1", ++ <&maxfrag>,"target:0=",<&spi0>, ++ <&max>,"reg:0=1"; ++ spi1-0 = <0>, "+2", ++ <&maxfrag>,"target:0=",<&spi1>, ++ <&max>,"reg:0=0"; ++ spi1-1 = <0>, "+3", ++ <&maxfrag>,"target:0=",<&spi1>, ++ <&max>,"reg:0=1"; ++ spi1-2 = <0>, "+4", ++ <&maxfrag>,"target:0=",<&spi1>, ++ <&max>,"reg:0=2"; ++ spi2-0 = <0>, "+5", ++ <&maxfrag>,"target:0=",<&spi2>, ++ <&max>,"reg:0=0"; ++ spi2-1 = <0>, "+6", ++ <&maxfrag>,"target:0=",<&spi2>, ++ <&max>,"reg:0=1"; ++ spi2-2 = <0>, "+7", ++ <&maxfrag>,"target:0=",<&spi2>, ++ <&max>,"reg:0=2"; ++ max6675 = <&max>,"compatible=maxim,max6675"; ++ max31855 = <&max>,"compatible=maxim,max31855"; ++ max31855e = <0>,"+9"; ++ max31855j = <0>,"+10"; ++ max31855k = <0>,"+11"; ++ max31855n = <0>,"+12"; ++ max31855r = <0>,"+13"; ++ max31855s = <0>,"+14"; ++ max31855t = <0>,"+15"; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-5.4/950-0932-dtoverlays-Add-the-iio_hwmon-driver-to-correct-ADC-i.patch b/target/linux/bcm27xx/patches-5.4/950-0932-dtoverlays-Add-the-iio_hwmon-driver-to-correct-ADC-i.patch new file mode 100644 index 0000000000..1005396340 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0932-dtoverlays-Add-the-iio_hwmon-driver-to-correct-ADC-i.patch @@ -0,0 +1,40 @@ +From 8bfdbba339bd363633e2232777fd749000011a41 Mon Sep 17 00:00:00 2001 +From: Annaliese McDermond <nh6z@nh6z.net> +Date: Sun, 2 Aug 2020 18:25:07 +0000 +Subject: [PATCH] dtoverlays: Add the iio_hwmon driver to correct ADC + issues + +The Linux kernel maintainers removed the hwmon driver for the +ads1015 used on this board. They deprecated it in favor of using +the IIO version of the driver with the iio_hwmon bridge. This +patch updates the DRAWS dtoverlay to support that usage. + +Signed-off-by: Annaliese McDermond <nh6z@nh6z.net> +--- + arch/arm/boot/dts/overlays/draws-overlay.dts | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/arch/arm/boot/dts/overlays/draws-overlay.dts ++++ b/arch/arm/boot/dts/overlays/draws-overlay.dts +@@ -45,6 +45,13 @@ + gpios = <&gpio 7 0>; + status = "okay"; + }; ++ ++ iio-hwmon { ++ compatible = "iio-hwmon"; ++ status = "okay"; ++ io-channels = <&tla2024 4>, <&tla2024 5>, <&tla2024 6>, ++ <&tla2024 7>; ++ }; + }; + }; + +@@ -91,6 +98,7 @@ + reg = <0x48>; + #address-cells = <1>; + #size-cells = <0>; ++ #io-channel-cells = <1>; + + adc_ch4: channel@4 { + reg = <4>; diff --git a/target/linux/bcm27xx/patches-5.4/950-0933-dts-bcm2711-Disable-DVP-by-default.patch b/target/linux/bcm27xx/patches-5.4/950-0933-dts-bcm2711-Disable-DVP-by-default.patch new file mode 100644 index 0000000000..9e4612e871 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0933-dts-bcm2711-Disable-DVP-by-default.patch @@ -0,0 +1,44 @@ +From c74f523a5af1d9d3a6f9aee05585e52a78a79f53 Mon Sep 17 00:00:00 2001 +From: Tim Gover <tim.gover@raspberrypi.com> +Date: Fri, 7 Aug 2020 13:55:18 +0100 +Subject: [PATCH] dts: bcm2711: Disable DVP by default + +The HDMI DVP should be disabled by default as is the case for other +display related drivers. This changes resolves an issue when using +the legacy firmware display driver where the DVP caused the 108 MHz +clock in HDMI TX to be gated off when Linux started. This effectively +stopped the firmware from being able to change the HDMI analog PHY +registers. + +Add a fragment to re-enable this in vc4-kms-v3d-pi4-overlay +--- + arch/arm/boot/dts/bcm2711-rpi.dtsi | 1 + + arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts | 7 +++++++ + 2 files changed, 8 insertions(+) + +--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi +@@ -46,6 +46,7 @@ + clocks = <&clk_108MHz>; + #clock-cells = <1>; + #reset-cells = <1>; ++ status = "disabled"; + }; + + hdmi0: hdmi@7ef00700 { +--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts ++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts +@@ -145,6 +145,13 @@ + }; + }; + ++ fragment@20 { ++ target = <&dvp>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ + __overrides__ { + audio = <0>,"!17"; + audio1 = <0>,"!18"; diff --git a/target/linux/bcm27xx/patches-5.4/950-0934-ARM-dts-Add-required-USB-power-domain-for-XCHI.patch b/target/linux/bcm27xx/patches-5.4/950-0934-ARM-dts-Add-required-USB-power-domain-for-XCHI.patch new file mode 100644 index 0000000000..28cb8e72ae --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0934-ARM-dts-Add-required-USB-power-domain-for-XCHI.patch @@ -0,0 +1,24 @@ +From 0ce033a8b915cd72b002505dd7b7ff90c36def02 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Wed, 5 Aug 2020 17:35:48 +0100 +Subject: [PATCH] ARM: dts: Add required USB power domain for XCHI + +The firmware setting otg_mode=1 can be used to enable the onboard XHCI +controller in host mode, but that requires that the USB power domain +is enabled. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2711-rpi.dtsi | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi +@@ -217,6 +217,7 @@ + status = "disabled"; + reg = <0x0 0x7e9c0000 0x0 0x100000>; + interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>; ++ power-domains = <&power RPI_POWER_DOMAIN_USB>; + }; + + hevc-decoder@7eb00000 { diff --git a/target/linux/bcm27xx/patches-5.4/950-0935-overlays-Regenerate-upstream-pi4.patch b/target/linux/bcm27xx/patches-5.4/950-0935-overlays-Regenerate-upstream-pi4.patch new file mode 100644 index 0000000000..429390931d --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0935-overlays-Regenerate-upstream-pi4.patch @@ -0,0 +1,28 @@ +From a5dd8f7ddc00f0f4e58f56b729b7e0066edf4e71 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Wed, 12 Aug 2020 10:15:52 +0100 +Subject: [PATCH] overlays: Regenerate upstream-pi4 + +The recent modification to vc4-kms-v3d-pi4 also results in a change +to the Pi 4 version of the upstream overlay. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts ++++ b/arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts +@@ -128,6 +128,12 @@ + }; + }; + fragment@20 { ++ target = <&dvp>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ fragment@21 { + target = <&usb>; + #address-cells = <1>; + #size-cells = <1>; diff --git a/target/linux/bcm27xx/patches-5.4/950-0936-drm-vc4-Increase-the-number-of-planes-per-crtc-in-FK.patch b/target/linux/bcm27xx/patches-5.4/950-0936-drm-vc4-Increase-the-number-of-planes-per-crtc-in-FK.patch new file mode 100644 index 0000000000..b2b1e7f46d --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0936-drm-vc4-Increase-the-number-of-planes-per-crtc-in-FK.patch @@ -0,0 +1,105 @@ +From 078e6dfcff1fc4ef0ee3b29a5f94403624c2e7ac Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Mon, 20 Jul 2020 16:42:57 +0100 +Subject: [PATCH] drm/vc4: Increase the number of planes per crtc in + FKMS. + +The number assigned was arbitrary as one primary, one overlay, +and one cursor. +The number has to be below the DRM limit of 32 planes total, +and the current firmware API limit of 16 planes total. + +Increase the number to 8 planes per crtc (1 primary, +6 overlay, and a cursor). + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 54 ++++++++++---------------- + 1 file changed, 21 insertions(+), 33 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -48,7 +48,7 @@ struct vc4_fkms { + bool bcm2711; + }; + +-#define PLANES_PER_CRTC 3 ++#define PLANES_PER_CRTC 8 + + struct set_plane { + u8 display; +@@ -1742,7 +1742,6 @@ static int vc4_fkms_create_screen(struct + struct vc4_crtc *vc4_crtc; + struct vc4_fkms_encoder *vc4_encoder; + struct drm_crtc *crtc; +- struct drm_plane *primary_plane, *overlay_plane, *cursor_plane; + struct drm_plane *destroy_plane, *temp; + struct mailbox_blank_display blank = { + .tag1 = {RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM, 4, 0, }, +@@ -1750,7 +1749,8 @@ static int vc4_fkms_create_screen(struct + .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_BLANK, 4, 0, }, + .blank = 1, + }; +- int ret; ++ struct drm_plane *planes[PLANES_PER_CRTC]; ++ int ret, i; + + vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL); + if (!vc4_crtc) +@@ -1763,38 +1763,26 @@ static int vc4_fkms_create_screen(struct + /* Blank the firmware provided framebuffer */ + rpi_firmware_property_list(vc4->firmware, &blank, sizeof(blank)); + +- primary_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_PRIMARY, +- display_ref, +- 0 + (display_idx * PLANES_PER_CRTC) +- ); +- if (IS_ERR(primary_plane)) { +- dev_err(dev, "failed to construct primary plane\n"); +- ret = PTR_ERR(primary_plane); +- goto err; +- } +- +- overlay_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_OVERLAY, +- display_ref, +- 1 + (display_idx * PLANES_PER_CRTC) +- ); +- if (IS_ERR(overlay_plane)) { +- dev_err(dev, "failed to construct overlay plane\n"); +- ret = PTR_ERR(overlay_plane); +- goto err; +- } +- +- cursor_plane = vc4_fkms_plane_init(drm, DRM_PLANE_TYPE_CURSOR, +- display_ref, +- 2 + (display_idx * PLANES_PER_CRTC) +- ); +- if (IS_ERR(cursor_plane)) { +- dev_err(dev, "failed to construct cursor plane\n"); +- ret = PTR_ERR(cursor_plane); +- goto err; ++ for (i = 0; i < PLANES_PER_CRTC; i++) { ++ planes[i] = vc4_fkms_plane_init(drm, ++ (i == 0) ? ++ DRM_PLANE_TYPE_PRIMARY : ++ (i == PLANES_PER_CRTC - 1) ? ++ DRM_PLANE_TYPE_CURSOR : ++ DRM_PLANE_TYPE_OVERLAY, ++ display_ref, ++ i + (display_idx * PLANES_PER_CRTC) ++ ); ++ if (IS_ERR(planes[i])) { ++ dev_err(dev, "failed to construct plane %u\n", i); ++ ret = PTR_ERR(planes[i]); ++ goto err; ++ } + } + +- drm_crtc_init_with_planes(drm, crtc, primary_plane, cursor_plane, +- &vc4_crtc_funcs, NULL); ++ drm_crtc_init_with_planes(drm, crtc, planes[0], ++ planes[PLANES_PER_CRTC - 1], &vc4_crtc_funcs, ++ NULL); + drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs); + + vc4_encoder = devm_kzalloc(dev, sizeof(*vc4_encoder), GFP_KERNEL); diff --git a/target/linux/bcm27xx/patches-5.4/950-0937-drm-vc4-Set-the-possible-crtcs-mask-correctly-for-pl.patch b/target/linux/bcm27xx/patches-5.4/950-0937-drm-vc4-Set-the-possible-crtcs-mask-correctly-for-pl.patch new file mode 100644 index 0000000000..9f020f7a53 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0937-drm-vc4-Set-the-possible-crtcs-mask-correctly-for-pl.patch @@ -0,0 +1,40 @@ +From 84a67330f3457469bc42f203111fc5ad800c506b Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 13 Aug 2020 18:29:56 +0100 +Subject: [PATCH] drm/vc4: Set the possible crtcs mask correctly for + planes with FKMS + +The driver was assigning all planes to crtcs when actually they're +mapped to a specific crtc. + +Correct the mask. + +https://github.com/raspberrypi/linux/issues/3734 + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -816,7 +816,7 @@ static struct drm_plane *vc4_fkms_plane_ + formats[num_formats++] = vc_image_formats[i].drm; + + plane = &vc4_plane->base; +- ret = drm_universal_plane_init(dev, plane, 0xff, ++ ret = drm_universal_plane_init(dev, plane, 0, + &vc4_plane_funcs, + formats, num_formats, modifiers, + type, NULL); +@@ -1785,6 +1785,10 @@ static int vc4_fkms_create_screen(struct + NULL); + drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs); + ++ /* Update the possible_crtcs mask for the overlay plane(s) */ ++ for (i = 1; i < (PLANES_PER_CRTC - 1); i++) ++ planes[i]->possible_crtcs = drm_crtc_mask(crtc); ++ + vc4_encoder = devm_kzalloc(dev, sizeof(*vc4_encoder), GFP_KERNEL); + if (!vc4_encoder) + return -ENOMEM; diff --git a/target/linux/bcm27xx/patches-5.4/950-0938-staging-vc04_services-codec-Fix-incorrect-buffer-cle.patch b/target/linux/bcm27xx/patches-5.4/950-0938-staging-vc04_services-codec-Fix-incorrect-buffer-cle.patch new file mode 100644 index 0000000000..14736dc2dc --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0938-staging-vc04_services-codec-Fix-incorrect-buffer-cle.patch @@ -0,0 +1,52 @@ +From 84fa15b87a5f938c064ee2d9fca43248865ffbec Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 13 Aug 2020 16:58:18 +0100 +Subject: [PATCH] staging: vc04_services: codec: Fix incorrect buffer + cleanup + +The allocated input and output buffers are initialised in +buf_init and should only be cleared up in buf_cleanup. +stop_streaming was (incorrectly) cleaning up the buffers to +avoid an issue in videobuf2 that had been fixed by the orphaned +buffer support. + +Remove the erroneous cleanup. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + .../bcm2835-codec/bcm2835-v4l2-codec.c | 17 +---------------- + 1 file changed, 1 insertion(+), 16 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -2320,10 +2320,7 @@ static void bcm2835_codec_stop_streaming + struct bcm2835_codec_q_data *q_data = get_q_data(ctx, q->type); + struct vchiq_mmal_port *port = get_port_data(ctx, q->type); + struct vb2_v4l2_buffer *vbuf; +- struct vb2_v4l2_buffer *vb2; +- struct v4l2_m2m_buffer *m2m; +- struct m2m_mmal_buffer *buf; +- int ret, i; ++ int ret; + + v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: type: %d - return buffers\n", + __func__, q->type); +@@ -2363,18 +2360,6 @@ static void bcm2835_codec_stop_streaming + } + } + +- /* +- * Release the VCSM handle here as otherwise REQBUFS(0) aborts because +- * someone is using the dmabuf before giving the driver a chance to do +- * anything about it. +- */ +- for (i = 0; i < q->num_buffers; i++) { +- vb2 = to_vb2_v4l2_buffer(q->bufs[i]); +- m2m = container_of(vb2, struct v4l2_m2m_buffer, vb); +- buf = container_of(m2m, struct m2m_mmal_buffer, m2m); +- +- bcm2835_codec_mmal_buf_cleanup(&buf->mmal); +- } + + /* If both ports disabled, then disable the component */ + if (!ctx->component->input[0].enabled && diff --git a/target/linux/bcm27xx/patches-5.4/950-0939-staging-vc04_service-codec-Allow-start_streaming-to-.patch b/target/linux/bcm27xx/patches-5.4/950-0939-staging-vc04_service-codec-Allow-start_streaming-to-.patch new file mode 100644 index 0000000000..66a551d2d7 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0939-staging-vc04_service-codec-Allow-start_streaming-to-.patch @@ -0,0 +1,70 @@ +From d88ef7d22cac032c4ddf7e4b8af5982d5a3019cb Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 13 Aug 2020 17:01:27 +0100 +Subject: [PATCH] staging: vc04_service: codec: Allow start_streaming + to update the buffernum + +start_streaming passes a count of how many buffers have been queued +to videobuf2. + +Allow this value to update the number of buffers the VPU allocates +on a port to avoid buffer recycling issues. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + .../bcm2835-codec/bcm2835-v4l2-codec.c | 23 +++++++++++++++---- + 1 file changed, 19 insertions(+), 4 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -2268,6 +2268,7 @@ static int bcm2835_codec_start_streaming + struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(q); + struct bcm2835_codec_dev *dev = ctx->dev; + struct bcm2835_codec_q_data *q_data = get_q_data(ctx, q->type); ++ struct vchiq_mmal_port *port = get_port_data(ctx, q->type); + int ret; + + v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: type: %d count %d\n", +@@ -2283,6 +2284,20 @@ static int bcm2835_codec_start_streaming + ctx->component_enabled = true; + } + ++ if (count < port->minimum_buffer.num) ++ count = port->minimum_buffer.num; ++ ++ if (port->current_buffer.num != count + 1) { ++ v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: ctx:%p, buffer count changed %u to %u\n", ++ __func__, ctx, port->current_buffer.num, count + 1); ++ ++ port->current_buffer.num = count + 1; ++ ret = vchiq_mmal_port_set_format(dev->instance, port); ++ if (ret) ++ v4l2_err(&ctx->dev->v4l2_dev, "%s: Error updating buffer count, ret %d\n", ++ __func__, ret); ++ } ++ + if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + /* + * Create the EOS buffer. +@@ -2294,17 +2309,17 @@ static int bcm2835_codec_start_streaming + &q_data->eos_buffer.mmal); + q_data->eos_buffer_in_use = false; + +- ctx->component->input[0].cb_ctx = ctx; ++ port->cb_ctx = ctx; + ret = vchiq_mmal_port_enable(dev->instance, +- &ctx->component->input[0], ++ port, + ip_buffer_cb); + if (ret) + v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling i/p port, ret %d\n", + __func__, ret); + } else { +- ctx->component->output[0].cb_ctx = ctx; ++ port->cb_ctx = ctx; + ret = vchiq_mmal_port_enable(dev->instance, +- &ctx->component->output[0], ++ port, + op_buffer_cb); + if (ret) + v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling o/p port, ret %d\n", diff --git a/target/linux/bcm27xx/patches-5.4/950-0940-staging-vc04_services-codec-Fix-component-enable-dis.patch b/target/linux/bcm27xx/patches-5.4/950-0940-staging-vc04_services-codec-Fix-component-enable-dis.patch new file mode 100644 index 0000000000..16c1cd79c0 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0940-staging-vc04_services-codec-Fix-component-enable-dis.patch @@ -0,0 +1,38 @@ +From 764c8052ce21a56a55dc25dbc6ee0c075952cdeb Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 13 Aug 2020 17:04:53 +0100 +Subject: [PATCH] staging: vc04_services: codec: Fix component + enable/disable + +start_streaming enabled the VPU component if ctx->component_enabled +was not set. +stop_streaming disabled the VPU component if both ports were +disabled. It didn't clear ctx->component_enabled. + +If seeking, this meant that the component never got re-enabled, +and buffers never got processed afterwards. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -2377,13 +2377,15 @@ static void bcm2835_codec_stop_streaming + + + /* If both ports disabled, then disable the component */ +- if (!ctx->component->input[0].enabled && ++ if (ctx->component_enabled && ++ !ctx->component->input[0].enabled && + !ctx->component->output[0].enabled) { + ret = vchiq_mmal_component_disable(dev->instance, + ctx->component); + if (ret) + v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling component, ret %d\n", + __func__, ret); ++ ctx->component_enabled = false; + } + + if (V4L2_TYPE_IS_OUTPUT(q->type)) diff --git a/target/linux/bcm27xx/patches-5.4/950-0941-update-rpi-display-overlay.dts-pins-for-5.4.patch b/target/linux/bcm27xx/patches-5.4/950-0941-update-rpi-display-overlay.dts-pins-for-5.4.patch new file mode 100644 index 0000000000..eed665bd4e --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0941-update-rpi-display-overlay.dts-pins-for-5.4.patch @@ -0,0 +1,32 @@ +From 6d2723af0ade644e99e069b54dbcac8b58d603f2 Mon Sep 17 00:00:00 2001 +From: Andreas Watterott <1488433+awatterott@users.noreply.github.com> +Date: Mon, 17 Aug 2020 21:17:09 +0200 +Subject: [PATCH] update rpi-display-overlay.dts pins for 5.4 + +--- + arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/arm/boot/dts/overlays/rpi-display-overlay.dts ++++ b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts +@@ -59,9 +59,9 @@ + bgr; + fps = <30>; + buswidth = <8>; +- reset-gpios = <&gpio 23 0>; ++ reset-gpios = <&gpio 23 1>; + dc-gpios = <&gpio 24 0>; +- led-gpios = <&gpio 18 1>; ++ led-gpios = <&gpio 18 0>; + debug = <0>; + }; + +@@ -72,7 +72,7 @@ + spi-max-frequency = <2000000>; + interrupts = <25 2>; /* high-to-low edge triggered */ + interrupt-parent = <&gpio>; +- pendown-gpio = <&gpio 25 0>; ++ pendown-gpio = <&gpio 25 1>; + ti,x-plate-ohms = /bits/ 16 <60>; + ti,pressure-max = /bits/ 16 <255>; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0942-Bluetooth-btrtl-Add-support-for-RTL8761B.patch b/target/linux/bcm27xx/patches-5.4/950-0942-Bluetooth-btrtl-Add-support-for-RTL8761B.patch new file mode 100644 index 0000000000..f0fbdd4356 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0942-Bluetooth-btrtl-Add-support-for-RTL8761B.patch @@ -0,0 +1,77 @@ +From 61695e30db3121c11e52be89751e610d2e97212a Mon Sep 17 00:00:00 2001 +From: "Ziqian SUN (Zamir)" <sztsian@gmail.com> +Date: Sat, 11 Apr 2020 09:34:27 +0800 +Subject: [PATCH] Bluetooth: btrtl: Add support for RTL8761B + +commit 04896832c94aae4842100cafb8d3a73e1bed3a45 upstream. + +Add new compatible device RTL8761B. RTL8761B is a USB Bluetooth device, +with support of BLE and BR/EDR. The USB info is + +T: Bus=03 Lev=04 Prnt=04 Port=00 Cnt=01 Dev#= 29 Spd=12 MxCh= 0 +D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=0bda ProdID=8771 Rev= 2.00 +S: Manufacturer=Realtek +S: Product=Bluetooth Radio +S: SerialNumber=XXXXXXXXXXXX +C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms + +Signed-off-by: Ziqian SUN (Zamir) <sztsian@gmail.com> +Signed-off-by: Marcel Holtmann <marcel@holtmann.org> +--- + drivers/bluetooth/btrtl.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/bluetooth/btrtl.c ++++ b/drivers/bluetooth/btrtl.c +@@ -130,12 +130,19 @@ static const struct id_table ic_id_table + .cfg_name = "rtl_bt/rtl8821c_config" }, + + /* 8761A */ +- { IC_MATCH_FL_LMPSUBV, RTL_ROM_LMP_8761A, 0x0, ++ { IC_INFO(RTL_ROM_LMP_8761A, 0xa), + .config_needed = false, + .has_rom_version = true, + .fw_name = "rtl_bt/rtl8761a_fw.bin", + .cfg_name = "rtl_bt/rtl8761a_config" }, + ++ /* 8761B */ ++ { IC_INFO(RTL_ROM_LMP_8761A, 0xb), ++ .config_needed = false, ++ .has_rom_version = true, ++ .fw_name = "rtl_bt/rtl8761b_fw.bin", ++ .cfg_name = "rtl_bt/rtl8761b_config" }, ++ + /* 8822C with USB interface */ + { IC_INFO(RTL_ROM_LMP_8822B, 0xc), + .config_needed = false, +@@ -255,6 +262,7 @@ static int rtlbt_parse_firmware(struct h + { RTL_ROM_LMP_8723B, 9 }, /* 8723D */ + { RTL_ROM_LMP_8821A, 10 }, /* 8821C */ + { RTL_ROM_LMP_8822B, 13 }, /* 8822C */ ++ { RTL_ROM_LMP_8761A, 14 }, /* 8761B */ + }; + + min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3; diff --git a/target/linux/bcm27xx/patches-5.4/950-0943-dtoverlays-Add-overlay-for-the-PCA953x-family-of-GPI.patch b/target/linux/bcm27xx/patches-5.4/950-0943-dtoverlays-Add-overlay-for-the-PCA953x-family-of-GPI.patch new file mode 100644 index 0000000000..181440c8db --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0943-dtoverlays-Add-overlay-for-the-PCA953x-family-of-GPI.patch @@ -0,0 +1,315 @@ +From 5a7c48622a4f7665039211414c9fe4a1914ae3eb Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Mon, 17 Aug 2020 18:11:47 +0100 +Subject: [PATCH] dtoverlays: Add overlay for the PCA953x family of + GPIO expanders + +Adds an overlay for configuring all the GPIO expanders supported +by the driver under GPIO_PCA953X. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 36 +++ + .../arm/boot/dts/overlays/pca953x-overlay.dts | 240 ++++++++++++++++++ + 3 files changed, 277 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/pca953x-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -119,6 +119,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + ov7251.dtbo \ + ov9281.dtbo \ + papirus.dtbo \ ++ pca953x.dtbo \ + pibell.dtbo \ + piglow.dtbo \ + piscreen.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1873,6 +1873,42 @@ Params: panel Display + speed Display SPI bus speed + + ++Name: pca953x ++Info: TI PCA953x family of I2C GPIO expanders. Default is for NXP PCA9534. ++Load: dtoverlay=pca953x,<param>=<val> ++Params: addr I2C address of expander. Default 0x20. ++ pca6416 Select the NXP PCA6416 (16 bit) ++ pca9505 Select the NXP PCA9505 (40 bit) ++ pca9535 Select the NXP PCA9535 (16 bit) ++ pca9536 Select the NXP PCA9536 or TI PCA9536 (4 bit) ++ pca9537 Select the NXP PCA9537 (4 bit) ++ pca9538 Select the NXP PCA9538 (8 bit) ++ pca9539 Select the NXP PCA9539 (16 bit) ++ pca9554 Select the NXP PCA9554 (8 bit) ++ pca9555 Select the NXP PCA9555 (16 bit) ++ pca9556 Select the NXP PCA9556 (8 bit) ++ pca9557 Select the NXP PCA9557 (8 bit) ++ pca9574 Select the NXP PCA9574 (8 bit) ++ pca9575 Select the NXP PCA9575 (16 bit) ++ pca9698 Select the NXP PCA9698 (40 bit) ++ pca16416 Select the NXP PCA16416 (16 bit) ++ pca16524 Select the NXP PCA16524 (24 bit) ++ pca19555a Select the NXP PCA19555A (16 bit) ++ max7310 Select the Maxim MAX7310 (8 bit) ++ max7312 Select the Maxim MAX7312 (16 bit) ++ max7313 Select the Maxim MAX7313 (16 bit) ++ max7315 Select the Maxim MAX7315 (8 bit) ++ pca6107 Select the TI PCA6107 (8 bit) ++ tca6408 Select the TI TCA6408 (8 bit) ++ tca6416 Select the TI TCA6416 (16 bit) ++ tca6424 Select the TI TCA6424 (24 bit) ++ tca9539 Select the TI TCA9539 (16 bit) ++ tca9554 Select the TI TCA9554 (8 bit) ++ cat9554 Select the Onnn CAT9554 (8 bit) ++ pca9654 Select the Onnn PCA9654 (8 bit) ++ xra1202 Select the Exar XRA1202 (8 bit) ++ ++ + [ The pcf2127-rtc overlay has been deleted. See i2c-rtc. ] + + +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pca953x-overlay.dts +@@ -0,0 +1,240 @@ ++// Definitions for NXP PCA953x family of I2C GPIO controllers on ARM I2C bus. ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&i2c_arm>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pca: pca@20 { ++ compatible = "nxp,pca9534"; ++ reg = <0x20>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "nxp,pca6416"; ++ }; ++ }; ++ fragment@2 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "nxp,pca9505"; ++ }; ++ }; ++ fragment@3 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "nxp,pca9535"; ++ }; ++ }; ++ fragment@4 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "nxp,pca9536"; ++ }; ++ }; ++ fragment@5 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "nxp,pca9537"; ++ }; ++ }; ++ fragment@6 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "nxp,pca9538"; ++ }; ++ }; ++ fragment@7 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "nxp,pca9539"; ++ }; ++ }; ++ fragment@8 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "nxp,pca9554"; ++ }; ++ }; ++ fragment@9 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "nxp,pca9555"; ++ }; ++ }; ++ fragment@10 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "nxp,pca9556"; ++ }; ++ }; ++ fragment@11 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "nxp,pca9557"; ++ }; ++ }; ++ fragment@12 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "nxp,pca9574"; ++ }; ++ }; ++ fragment@13 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "nxp,pca9575"; ++ }; ++ }; ++ fragment@14 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "nxp,pca9698"; ++ }; ++ }; ++ fragment@15 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "nxp,pca16416"; ++ }; ++ }; ++ fragment@16 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "nxp,pca16524"; ++ }; ++ }; ++ fragment@17 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "nxp,pca19555a"; ++ }; ++ }; ++ fragment@18 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "maxim,max7310"; ++ }; ++ }; ++ fragment@19 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "maxim,max7312"; ++ }; ++ }; ++ fragment@20 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "maxim,max7313"; ++ }; ++ }; ++ fragment@21 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "maxim,max7315"; ++ }; ++ }; ++ fragment@22 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "ti,pca6107"; ++ }; ++ }; ++ fragment@23 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "ti,tca6408"; ++ }; ++ }; ++ fragment@24 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "ti,tca6416"; ++ }; ++ }; ++ fragment@25 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "ti,tca6424"; ++ }; ++ }; ++ fragment@26 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "ti,tca9539"; ++ }; ++ }; ++ fragment@27 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "ti,tca9554"; ++ }; ++ }; ++ fragment@28 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "onnn,cat9554"; ++ }; ++ }; ++ fragment@29 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "onnn,pca9654"; ++ }; ++ }; ++ fragment@30 { ++ target = <&pca>; ++ __dormant__ { ++ compatible = "exar,xra1202"; ++ }; ++ }; ++ ++ __overrides__ { ++ addr = <&pca>,"reg:0"; ++ pca6416 = <0>, "+1"; ++ pca9505 = <0>, "+2"; ++ pca9535 = <0>, "+3"; ++ pca9536 = <0>, "+4"; ++ pca9537 = <0>, "+5"; ++ pca9538 = <0>, "+6"; ++ pca9539 = <0>, "+7"; ++ pca9554 = <0>, "+8"; ++ pca9555 = <0>, "+9"; ++ pca9556 = <0>, "+10"; ++ pca9557 = <0>, "+11"; ++ pca9574 = <0>, "+12"; ++ pca9575 = <0>, "+13"; ++ pca9698 = <0>, "+14"; ++ pca16416 = <0>, "+15"; ++ pca16524 = <0>, "+16"; ++ pca19555a = <0>, "+17"; ++ max7310 = <0>, "+18"; ++ max7312 = <0>, "+19"; ++ max7313 = <0>, "+20"; ++ max7315 = <0>, "+21"; ++ pca6107 = <0>, "+22"; ++ tca6408 = <0>, "+23"; ++ tca6416 = <0>, "+24"; ++ tca6424 = <0>, "+25"; ++ tca9539 = <0>, "+26"; ++ tca9554 = <0>, "+27"; ++ cat9554 = <0>, "+28"; ++ pca9654 = <0>, "+29"; ++ xra1202 = <0>, "+30"; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-5.4/950-0944-rtc-rv3028-Write-BSM-and-TCE-TCR-to-EEPROM.patch b/target/linux/bcm27xx/patches-5.4/950-0944-rtc-rv3028-Write-BSM-and-TCE-TCR-to-EEPROM.patch new file mode 100644 index 0000000000..54f3f4f367 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0944-rtc-rv3028-Write-BSM-and-TCE-TCR-to-EEPROM.patch @@ -0,0 +1,120 @@ +From ffc137a8949cd7859bdf139fa7a56b9dbdb4b2ce Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Fri, 15 May 2020 16:28:32 +0100 +Subject: [PATCH] rtc: rv3028: Write BSM and TCE/TCR to EEPROM + +Periodically the RV3028 refreshes registers from the EEPROM. When this +happens, some settings that have only been committed to registers are +lost. Change the handling of backup-switchover-mode and +trickle-resistor-ohms to write the EEPROM instead (if something has +changed), on the understanding that registers will be refreshed +afterwards. + +See: https://github.com/raspberrypi/linux/issues/2912 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/rtc/rtc-rv3028.c | 60 ++++++++++++++++++++++++++++------------ + 1 file changed, 43 insertions(+), 17 deletions(-) + +--- a/drivers/rtc/rtc-rv3028.c ++++ b/drivers/rtc/rtc-rv3028.c +@@ -18,6 +18,7 @@ + #include <linux/of_device.h> + #include <linux/regmap.h> + #include <linux/rtc.h> ++//#include "rtc-core.h" + + #define RV3028_SEC 0x00 + #define RV3028_MIN 0x01 +@@ -73,7 +74,7 @@ + + #define RV3028_BACKUP_TCE BIT(5) + #define RV3028_BACKUP_TCR_MASK GENMASK(1,0) +-#define RV3028_BACKUP_BSM_MASK 0x0C ++#define RV3028_BACKUP_BSM_MASK GENMASK(3,2) + + #define OFFSET_STEP_PPT 953674 + +@@ -601,7 +602,8 @@ static int rv3028_probe(struct i2c_clien + struct rv3028_data *rv3028; + int ret, status; + u32 ohms; +- u8 bsm; ++ u32 bsm; ++ u8 backup, backup_bits, backup_mask; + struct nvmem_config nvmem_cfg = { + .name = "rv3028_nvram", + .word_size = 1, +@@ -673,16 +675,17 @@ static int rv3028_probe(struct i2c_clien + if (ret) + return ret; + ++ backup_bits = 0; ++ backup_mask = 0; ++ + /* setup backup switchover mode */ +- if (!device_property_read_u8(&client->dev, "backup-switchover-mode", +- &bsm)) { ++ dev_dbg(&client->dev, "Checking RTC backup switchover-mode\n"); ++ if (!device_property_read_u32(&client->dev, ++ "backup-switchover-mode", ++ &bsm)) { + if (bsm <= 3) { +- ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP, +- RV3028_BACKUP_BSM_MASK, +- (bsm & 0x03) << 2); +- +- if (ret) +- return ret; ++ backup_bits |= (u8)(bsm << 2); ++ backup_mask |= RV3028_BACKUP_BSM_MASK; + } else { + dev_warn(&client->dev, "invalid backup switchover mode value\n"); + } +@@ -698,15 +701,38 @@ static int rv3028_probe(struct i2c_clien + break; + + if (i < ARRAY_SIZE(rv3028_trickle_resistors)) { +- ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP, +- RV3028_BACKUP_TCE | +- RV3028_BACKUP_TCR_MASK, +- RV3028_BACKUP_TCE | i); +- if (ret) +- return ret; ++ backup_bits |= RV3028_BACKUP_TCE | i; ++ backup_mask |= RV3028_BACKUP_TCE | ++ RV3028_BACKUP_TCR_MASK; + } else { +- dev_warn(&client->dev, "invalid trickle resistor value\n"); ++ dev_warn(&client->dev, ++ "invalid trickle resistor value\n"); ++ } ++ } ++ ++ if (backup_mask) { ++ ret = rv3028_eeprom_read((void *)(rv3028->regmap), ++ RV3028_BACKUP, ++ (void *)&backup, 1); ++ if (!ret) { ++ /* Write EEPROM only if needed */ ++ if ((backup & backup_mask) != backup_bits) { ++ backup = (backup & ~backup_mask) | backup_bits; ++ dev_dbg(&client->dev, ++ "Backup register doesn't match: EEPROM write required\n"); ++ ret = rv3028_eeprom_write( ++ (void *)(rv3028->regmap), ++ RV3028_BACKUP, (void *)&backup, 1); ++ } + } ++ ++ /* In the event of an EEPROM failure, update the register ++ instead. */ ++ if (ret) ++ ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP, ++ backup_mask, backup_bits); ++ if (ret) ++ return ret; + } + + ret = rtc_add_group(rv3028->rtc, &rv3028_attr_group); diff --git a/target/linux/bcm27xx/patches-5.4/950-0945-rtc-rv3028-Refresh-RAM-on-EEPROM-write.patch b/target/linux/bcm27xx/patches-5.4/950-0945-rtc-rv3028-Refresh-RAM-on-EEPROM-write.patch new file mode 100644 index 0000000000..94e3038c8a --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0945-rtc-rv3028-Refresh-RAM-on-EEPROM-write.patch @@ -0,0 +1,92 @@ +From 010b506d6b215673f188ed5cdc4e35419e3ea715 Mon Sep 17 00:00:00 2001 +From: Einar Vading <einar.vading@rhimagnesita.com> +Date: Fri, 14 Aug 2020 22:14:41 +0200 +Subject: [PATCH] rtc: rv3028: Refresh RAM on EEPROM write + +The active RV3028 settings are in RAM so after modifying the settings in +EEPROM the RAM should be refreshed so that they take effect. + +Signed-off-by: Einar Vading <einar.vading@rhimagnesita.com> +--- + drivers/rtc/rtc-rv3028.c | 56 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 56 insertions(+) + +--- a/drivers/rtc/rtc-rv3028.c ++++ b/drivers/rtc/rtc-rv3028.c +@@ -66,6 +66,7 @@ + + #define RV3028_EVT_CTRL_TSR BIT(2) + ++#define RV3028_EEPROM_CMD_REFRESH 0x12 + #define RV3028_EEPROM_CMD_WRITE 0x21 + #define RV3028_EEPROM_CMD_READ 0x22 + +@@ -583,6 +584,58 @@ restore_eerd: + return ret; + } + ++static int rv3028_ram_refresh(void *priv) ++{ ++ u32 status, ctrl1; ++ int ret, err; ++ ++ ret = regmap_read(priv, RV3028_CTRL1, &ctrl1); ++ if (ret) ++ return ret; ++ ++ if (!(ctrl1 & RV3028_CTRL1_EERD)) { ++ ret = regmap_update_bits(priv, RV3028_CTRL1, ++ RV3028_CTRL1_EERD, RV3028_CTRL1_EERD); ++ if (ret) ++ return ret; ++ ++ ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, ++ !(status & RV3028_STATUS_EEBUSY), ++ RV3028_EEBUSY_POLL, ++ RV3028_EEBUSY_TIMEOUT); ++ if (ret) ++ goto restore_eerd; ++ } ++ ++ ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0); ++ if (ret) ++ goto restore_eerd; ++ ++ ret = regmap_write(priv, RV3028_EEPROM_CMD, ++ RV3028_EEPROM_CMD_REFRESH); ++ if (ret) ++ goto restore_eerd; ++ ++ usleep_range(RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT); ++ ++ ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, ++ !(status & RV3028_STATUS_EEBUSY), ++ RV3028_EEBUSY_POLL, ++ RV3028_EEBUSY_TIMEOUT); ++ if (ret) ++ goto restore_eerd; ++ ++restore_eerd: ++ if (!(ctrl1 & RV3028_CTRL1_EERD)) { ++ err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD, ++ 0); ++ if (err && !ret) ++ ret = err; ++ } ++ ++ return ret; ++} ++ + static struct rtc_class_ops rv3028_rtc_ops = { + .read_time = rv3028_get_time, + .set_time = rv3028_set_time, +@@ -723,6 +776,9 @@ static int rv3028_probe(struct i2c_clien + ret = rv3028_eeprom_write( + (void *)(rv3028->regmap), + RV3028_BACKUP, (void *)&backup, 1); ++ ++ if (!ret) ++ ret = rv3028_ram_refresh((void *)(rv3028->regmap)); + } + } + diff --git a/target/linux/bcm27xx/patches-5.4/950-0946-dt-overlays-Add-PiFace-Digital-Device-Tree-Overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0946-dt-overlays-Add-PiFace-Digital-Device-Tree-Overlay.patch new file mode 100644 index 0000000000..d9a6675f07 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0946-dt-overlays-Add-PiFace-Digital-Device-Tree-Overlay.patch @@ -0,0 +1,199 @@ +From 296cff78df285c99a52760cbcd896abc37820e06 Mon Sep 17 00:00:00 2001 +From: Thomas Preston <thomas.preston@codethink.co.uk> +Date: Thu, 13 Aug 2020 01:38:35 +0100 +Subject: [PATCH] dt/overlays: Add PiFace Digital Device Tree Overlay + +The PiFace Digital is a convenient breakout board for the Microchip +mcp23s17 SPI GPIO port expander. + +The first eight GPIOs 0..7 (bank A) are connected to eight output +terminals and LEDs, plus two relays on the first two outputs. These +output loads are active-high. + +The next eight GPIOs 8..15 (bank B) are connected to eight input +terminals with four on-board switches connecting them to ground. Inputs +devices are therefore expected to bridge terminals to ground, so the +mcp23s17 pullups are activated for GPIO bank B. + +Signed-off-by: Thomas Preston <thomas.preston@codethink.co.uk> +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 8 + + .../dts/overlays/pifacedigital-overlay.dts | 144 ++++++++++++++++++ + 3 files changed, 153 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/pifacedigital-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -121,6 +121,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + papirus.dtbo \ + pca953x.dtbo \ + pibell.dtbo \ ++ pifacedigital.dtbo \ + piglow.dtbo \ + piscreen.dtbo \ + piscreen2r.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1949,6 +1949,14 @@ Params: alsaname Set the + "PiBell") + + ++Name: pifacedigital ++Info: Configures the PiFace Digital mcp23s17 GPIO port expander. ++Load: dtoverlay=pifacedigital,<param>=<val> ++Params: spi-present-mask 8-bit integer, bitmap indicating MCP23S17 SPI0 ++ CS0 address. PiFace Digital supports addresses ++ 0-3, which can be configured with JP1 and JP2. ++ ++ + Name: piglow + Info: Configures the PiGlow by pimoroni.com + Load: dtoverlay=piglow +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pifacedigital-overlay.dts +@@ -0,0 +1,144 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * PiFace Digital, Device Tree Overlay. ++ * Copyright (C) 2020 Thomas Preston <thomas.preston@codethink.co.uk> ++ * ++ * The PiFace Digital is a convenient breakout board for the Microchip mcp23s17 ++ * SPI GPIO port expander. ++ * ++ * The first eight GPIOs 0..7 (bank A) are connected to eight output terminals ++ * and LEDs, plus two relays on the first two outputs. These output loads are ++ * active-high. ++ * ++ * The next eight GPIOs 8..15 (bank B) are connected to eight input terminals ++ * with four on-board switches connecting them to ground. Inputs devices are ++ * therefore expected to bridge terminals to ground, so the mcp23s17 pullups are ++ * activated for GPIO bank B. ++ * ++ * On PiFace Digital, the mcp23s17 is connected to the Raspberry Pi's SPI0 CS0 ++ * bus. Each SPI bus supports up to eight addressable child devices. The PiFace ++ * Digital only supports addresses 0-4, which can be configured by jumpers JP1 ++ * and JP2. ++ * ++ * You can tell the driver about these jumper configurations with the ++ * spi-present-mask bitmask: ++ * ++ * | JP1 | JP2 | dtoverlay line in /boot/config.txt | ++ * | --- | --- | ------------------------------------------ | ++ * | 0 | 0 | dtoverlay=pifacedigital | ++ * | 0 | 0 | dtoverlay=pifacedigital:spi-present-mask=1 | ++ * | 0 | 1 | dtoverlay=pifacedigital:spi-present-mask=2 | ++ * | 1 | 0 | dtoverlay=pifacedigital:spi-present-mask=4 | ++ * | 1 | 1 | dtoverlay=pifacedigital:spi-present-mask=8 | ++ * ++ * # Example ++ * Set the dtoverlay config in /boot/config.txt and power off the Raspberry Pi: ++ * ++ * $ grep pifacedigital /boot/config.txt ++ * dtoverlay=pifacedigital ++ * $ sudo systemctl poweroff ++ * ++ * Attach the PiFace Digital and power on the Raspberry Pi. ++ * Then use the libgpiod tools to query the device: ++ * ++ * $ sudo apt install gpiod ++ * $ gpiodetect | grep mcp23s17 ++ * gpiochip2 [mcp23s17.0] (16 lines) ++ * ++ * Set GPIO outputs 0, 2 and 5: ++ * ++ * $ gpioset gpiochip2 0=1 2=1 5=1 ++ * ++ * Get GPIO status (input GPIO 8..15 are high, because they are active-low): ++ * ++ * $ gpioget gpiochip2 {8..15} ++ * 1 1 1 1 1 1 1 1 ++ * ++ * And even monitor interrupts: ++ * ++ * $ gpiomon gpiochip2 {8..15} ++ * event: FALLING EDGE offset: 11 timestamp: [1597361662.926741667] ++ * event: RISING EDGE offset: 11 timestamp: [1597361663.062555051] ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ ++ /* Disable exposing /dev/spidev0.0 */ ++ fragment@0 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ /* Add the PiFace Digital device node to the spi0.0 device. */ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pfdigital: pifacedigital@0 { ++ compatible = "microchip,mcp23s17"; ++ reg = <0>; ++ ++ /* Set devices present with 8-bit mask. */ ++ microchip,spi-present-mask = <0x01>; ++ spi-max-frequency = <500000>; ++ ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ /* This device can pass through interrupts. */ ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ ++ /* INTB is connected to GPIO 25. ++ * 0x8 active-low level-sensitive ++ */ ++ interrupts = <25 0x8>; ++ interrupt-parent = <&gpio>; ++ ++ /* Configure pull-ups on bank B GPIOs */ ++ pinctrl-0 = <&pfdigital_irq &pfdigital_pullups>; ++ pinctrl-names = "default"; ++ pfdigital_pullups: pinmux { ++ pins = ++ "gpio8", ++ "gpio9", ++ "gpio10", ++ "gpio11", ++ "gpio12", ++ "gpio13", ++ "gpio14", ++ "gpio15"; ++ bias-pull-up; ++ }; ++ }; ++ }; ++ }; ++ ++ /* PiFace Digital mcp23s17 INTB pin is connected to GPIO 25. The INTB ++ * pin is configured active-low (0 on interrupt), so expect to see ++ * FALLING_EDGE when inputs are bridged to ground (switch is pressed). ++ */ ++ fragment@3 { ++ target = <&gpio>; ++ __overlay__ { ++ pfdigital_irq: pifacedigital_irq { ++ brcm,pins = <25>; ++ brcm,function = <0>; /* input */ ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ spi-present-mask = <&pfdigital>, "microchip,spi-present-mask:0"; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-5.4/950-0947-overlays-Updated-MCP3008-compatible-strings.patch b/target/linux/bcm27xx/patches-5.4/950-0947-overlays-Updated-MCP3008-compatible-strings.patch new file mode 100644 index 0000000000..739c4dab52 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0947-overlays-Updated-MCP3008-compatible-strings.patch @@ -0,0 +1,84 @@ +From 9c5770dd049b3839296ac49fb40f01b6fe55fa81 Mon Sep 17 00:00:00 2001 +From: RICCIARDI-Adrien <adrien.ricciardi@hotmail.fr> +Date: Thu, 20 Aug 2020 10:18:35 +0200 +Subject: [PATCH] overlays: Updated MCP3008 compatible strings. + +Used recommended ones from Documentation/devicetree/bindings/iio/adc/mcp320x.txt. +--- + arch/arm/boot/dts/overlays/mcp3008-overlay.dts | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/arch/arm/boot/dts/overlays/mcp3008-overlay.dts ++++ b/arch/arm/boot/dts/overlays/mcp3008-overlay.dts +@@ -72,7 +72,7 @@ + #size-cells = <0>; + + mcp3008_00: mcp3008@0 { +- compatible = "mcp3008"; ++ compatible = "microchip,mcp3008"; + reg = <0>; + spi-max-frequency = <1600000>; + }; +@@ -87,7 +87,7 @@ + #size-cells = <0>; + + mcp3008_01: mcp3008@1 { +- compatible = "mcp3008"; ++ compatible = "microchip,mcp3008"; + reg = <1>; + spi-max-frequency = <1600000>; + }; +@@ -102,7 +102,7 @@ + #size-cells = <0>; + + mcp3008_10: mcp3008@0 { +- compatible = "mcp3008"; ++ compatible = "microchip,mcp3008"; + reg = <0>; + spi-max-frequency = <1600000>; + }; +@@ -117,7 +117,7 @@ + #size-cells = <0>; + + mcp3008_11: mcp3008@1 { +- compatible = "mcp3008"; ++ compatible = "microchip,mcp3008"; + reg = <1>; + spi-max-frequency = <1600000>; + }; +@@ -132,7 +132,7 @@ + #size-cells = <0>; + + mcp3008_12: mcp3008@2 { +- compatible = "mcp3008"; ++ compatible = "microchip,mcp3008"; + reg = <2>; + spi-max-frequency = <1600000>; + }; +@@ -147,7 +147,7 @@ + #size-cells = <0>; + + mcp3008_20: mcp3008@0 { +- compatible = "mcp3008"; ++ compatible = "microchip,mcp3008"; + reg = <0>; + spi-max-frequency = <1600000>; + }; +@@ -162,7 +162,7 @@ + #size-cells = <0>; + + mcp3008_21: mcp3008@1 { +- compatible = "mcp3008"; ++ compatible = "microchip,mcp3008"; + reg = <1>; + spi-max-frequency = <1600000>; + }; +@@ -177,7 +177,7 @@ + #size-cells = <0>; + + mcp3008_22: mcp3008@2 { +- compatible = "mcp3008"; ++ compatible = "microchip,mcp3008"; + reg = <2>; + spi-max-frequency = <1600000>; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0948-RESET_CONTROLLER-needs-to-be-activated-to-compile-Br.patch b/target/linux/bcm27xx/patches-5.4/950-0948-RESET_CONTROLLER-needs-to-be-activated-to-compile-Br.patch new file mode 100644 index 0000000000..68627aa564 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0948-RESET_CONTROLLER-needs-to-be-activated-to-compile-Br.patch @@ -0,0 +1,20 @@ +From b28871fe542f7805751e804ee385a803af00efae Mon Sep 17 00:00:00 2001 +From: Ramin Moussavi <lordrasmus@gmail.com> +Date: Sat, 25 Jul 2020 22:31:49 +0200 +Subject: [PATCH] RESET_CONTROLLER needs to be activated to compile + Broadcom BCM2835 clock support + +--- + drivers/clk/bcm/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/clk/bcm/Kconfig ++++ b/drivers/clk/bcm/Kconfig +@@ -5,6 +5,7 @@ config CLK_BCM2835 + depends on COMMON_CLK + default ARCH_BCM2835 || ARCH_BRCMSTB + select RESET_SIMPLE ++ select RESET_CONTROLLER + help + Enable common clock framework support for Broadcom BCM2835 + SoCs. diff --git a/target/linux/bcm27xx/patches-5.4/950-0949-media-dvbsky-use-a-single-mutex-and-state-buffers-fo.patch b/target/linux/bcm27xx/patches-5.4/950-0949-media-dvbsky-use-a-single-mutex-and-state-buffers-fo.patch new file mode 100644 index 0000000000..836364e5de --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0949-media-dvbsky-use-a-single-mutex-and-state-buffers-fo.patch @@ -0,0 +1,64 @@ +From 08ccbb8e0667e90e5c7334057965c6205a3855fb Mon Sep 17 00:00:00 2001 +From: Andrei Koshkosh <andreykosh000@mail.ru> +Date: Sun, 29 Sep 2019 05:04:05 -0300 +Subject: [PATCH] media: dvbsky: use a single mutex and state buffers + for all R/W ops + +commit cecf0bbbcb6f035a5ca2197f3e11ec2b7fb3da83 upstream. + +Re-use usb_mutex from dvb_usb_device for this. + +See: https://github.com/raspberrypi/linux/issues/3809 + +Tested-by: Jan Pieter van Woerkom <jp@jpvw.nl> +Signed-off-by: Andrei Koshkosh <andreykosh000@mail.ru> +Signed-off-by: Sean Young <sean@mess.org> +Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> +--- + drivers/media/usb/dvb-usb-v2/dvbsky.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/media/usb/dvb-usb-v2/dvbsky.c ++++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c +@@ -22,7 +22,6 @@ MODULE_PARM_DESC(disable_rc, "Disable in + DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + + struct dvbsky_state { +- struct mutex stream_mutex; + u8 ibuf[DVBSKY_BUF_LEN]; + u8 obuf[DVBSKY_BUF_LEN]; + u8 last_lock; +@@ -60,17 +59,19 @@ static int dvbsky_usb_generic_rw(struct + static int dvbsky_stream_ctrl(struct dvb_usb_device *d, u8 onoff) + { + struct dvbsky_state *state = d_to_priv(d); ++ static const u8 obuf_pre[3] = { 0x37, 0, 0 }; ++ static const u8 obuf_post[3] = { 0x36, 3, 0 }; + int ret; +- u8 obuf_pre[3] = { 0x37, 0, 0 }; +- u8 obuf_post[3] = { 0x36, 3, 0 }; + +- mutex_lock(&state->stream_mutex); +- ret = dvbsky_usb_generic_rw(d, obuf_pre, 3, NULL, 0); ++ mutex_lock(&d->usb_mutex); ++ memcpy(state->obuf, obuf_pre, 3); ++ ret = dvb_usbv2_generic_write_locked(d, state->obuf, 3); + if (!ret && onoff) { + msleep(20); +- ret = dvbsky_usb_generic_rw(d, obuf_post, 3, NULL, 0); ++ memcpy(state->obuf, obuf_post, 3); ++ ret = dvb_usbv2_generic_write_locked(d, state->obuf, 3); + } +- mutex_unlock(&state->stream_mutex); ++ mutex_unlock(&d->usb_mutex); + return ret; + } + +@@ -598,7 +599,6 @@ static int dvbsky_init(struct dvb_usb_de + if (ret) + return ret; + */ +- mutex_init(&state->stream_mutex); + + state->last_lock = 0; + diff --git a/target/linux/bcm27xx/patches-5.4/950-0950-ARM-dts-bcm2711-Enable-support-for-DDR52-eMMC.patch b/target/linux/bcm27xx/patches-5.4/950-0950-ARM-dts-bcm2711-Enable-support-for-DDR52-eMMC.patch new file mode 100644 index 0000000000..7a0e78d2f6 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0950-ARM-dts-bcm2711-Enable-support-for-DDR52-eMMC.patch @@ -0,0 +1,22 @@ +From e31ec540cff5498f86f57cccb7a35b323bdb6f33 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 24 Aug 2020 17:11:34 +0100 +Subject: [PATCH] ARM: dts: bcm2711: Enable support for DDR52 eMMC + +See: https://github.com/raspberrypi/linux/issues/3802 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2711-rpi.dtsi | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi +@@ -310,3 +310,7 @@ + &hvs { + clocks = <&firmware_clocks 4>; + }; ++ ++&emmc2 { ++ mmc-ddr-3_3v; ++}; diff --git a/target/linux/bcm27xx/patches-5.4/950-0951-staging-vc04_services-ISP-Fix-dmabuf-error-check-in-.patch b/target/linux/bcm27xx/patches-5.4/950-0951-staging-vc04_services-ISP-Fix-dmabuf-error-check-in-.patch new file mode 100644 index 0000000000..32f66fbb8b --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0951-staging-vc04_services-ISP-Fix-dmabuf-error-check-in-.patch @@ -0,0 +1,25 @@ +From 971ec8a5c6229dc45b89105196a86333635fc553 Mon Sep 17 00:00:00 2001 +From: Paul Elder <paul.elder@ideasonboard.com> +Date: Mon, 24 Aug 2020 17:14:29 +0900 +Subject: [PATCH] staging: vc04_services: ISP: Fix dmabuf error check + in S_CTRL + +In bcm2835_isp_s_ctrl, the error check for dma_buf_get() is incorrect, +and considers ERR_PTR pointers as valid dmabufs. Fix this error check. + +Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> +--- + drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c ++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c +@@ -733,7 +733,7 @@ static int bcm2835_isp_s_ctrl(struct v4l + sizeof(struct bcm2835_isp_lens_shading)); + + dmabuf = dma_buf_get(ls.dmabuf); +- if (!dmabuf) ++ if (IS_ERR_OR_NULL(dmabuf)) + return -EINVAL; + + ret = vc_sm_cma_import_dmabuf(dmabuf, diff --git a/target/linux/bcm27xx/patches-5.4/950-0952-ARM-dts-bcm2708.dtsi-Don-t-delete-the-cpus-node.patch b/target/linux/bcm27xx/patches-5.4/950-0952-ARM-dts-bcm2708.dtsi-Don-t-delete-the-cpus-node.patch new file mode 100644 index 0000000000..2ad707d33b --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0952-ARM-dts-bcm2708.dtsi-Don-t-delete-the-cpus-node.patch @@ -0,0 +1,26 @@ +From a32c73cc5a06b0bf7f2b18314b46a052ce6517ee Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 24 Aug 2020 18:28:52 +0100 +Subject: [PATCH] ARM: dts: bcm2708.dtsi: Don't delete the cpus node + +The cpus node was originally deleted to match the then downstream +version of the BCM2835 DTS files, but doing so doesn't seem to make +any material difference. Its presence is necessary for the CPUFREQ_DT +support that is planned in the near future, so remove the deletion. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2708.dtsi | 2 -- + 1 file changed, 2 deletions(-) + +--- a/arch/arm/boot/dts/bcm2708.dtsi ++++ b/arch/arm/boot/dts/bcm2708.dtsi +@@ -2,8 +2,6 @@ + #include "bcm270x.dtsi" + + / { +- /delete-node/ cpus; +- + __overrides__ { + arm_freq; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0953-ARM-dts-bcm2835-Use-the-L2-non-allocating-alias.patch b/target/linux/bcm27xx/patches-5.4/950-0953-ARM-dts-bcm2835-Use-the-L2-non-allocating-alias.patch new file mode 100644 index 0000000000..d87ffc8c22 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0953-ARM-dts-bcm2835-Use-the-L2-non-allocating-alias.patch @@ -0,0 +1,30 @@ +From 121fdf16a2ff4cf651c376a37eeca255544c47fd Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Thu, 27 Aug 2020 17:57:18 +0100 +Subject: [PATCH] ARM: dts: bcm2835: Use the L2 non-allocating alias + +The /soc/dma-ranges property on BCM2835 currently results in DMA +addresses in the range 0x40000000-0x5fffffff. This will allocate in the +system L2 cache, which may adversely affect performance. + +Change the dma-ranges property to give addresses in the range +0x80000000-0x9fffffff, which are coherent with L2 but non-allocating. + +See: https://github.com/raspberrypi/linux/issues/3602 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2835.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/bcm2835.dtsi ++++ b/arch/arm/boot/dts/bcm2835.dtsi +@@ -18,7 +18,7 @@ + + soc { + ranges = <0x7e000000 0x20000000 0x02000000>; +- dma-ranges = <0x40000000 0x00000000 0x20000000>; ++ dma-ranges = <0x80000000 0x00000000 0x20000000>; + }; + + arm-pmu { diff --git a/target/linux/bcm27xx/patches-5.4/950-0954-media-bcm2835-unicam-Drop-WARN-on-uing-direct-cache-.patch b/target/linux/bcm27xx/patches-5.4/950-0954-media-bcm2835-unicam-Drop-WARN-on-uing-direct-cache-.patch new file mode 100644 index 0000000000..481c55b649 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0954-media-bcm2835-unicam-Drop-WARN-on-uing-direct-cache-.patch @@ -0,0 +1,34 @@ +From d535074e3e2c08ba5a6b627e54f4597f0f6f9240 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 27 Aug 2020 16:30:26 +0100 +Subject: [PATCH] media: bcm2835-unicam: Drop WARN on uing direct + cache alias + +Pi 0&1 pass all ARM accesses through the VPU L2 cache, therefore +the dma-ranges property sets the cache alias bits to other +than the direct alias, hence this WARN was firing. + +It was overprotective coding, so assume that everything is OK +with the dma-ranges, and remove the WARN. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/platform/bcm2835/bcm2835-unicam.c | 7 ------- + 1 file changed, 7 deletions(-) + +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -708,13 +708,6 @@ static void unicam_wr_dma_addr(struct un + { + dma_addr_t endaddr = dmaaddr + buffer_size; + +- /* +- * dmaaddr and endaddr should be a 32-bit address with the top two bits +- * set to 0x3 to signify uncached access through the Videocore memory +- * controller. +- */ +- WARN_ON((dmaaddr >> 30) != 0x3 || (endaddr >> 30) != 0x3); +- + if (pad_id == IMAGE_PAD) { + reg_write(dev, UNICAM_IBSA0, dmaaddr); + reg_write(dev, UNICAM_IBEA0, endaddr); diff --git a/target/linux/bcm27xx/patches-5.4/950-0955-media-i2c-tc358743-Only-allow-supported-pixel-fmts-i.patch b/target/linux/bcm27xx/patches-5.4/950-0955-media-i2c-tc358743-Only-allow-supported-pixel-fmts-i.patch new file mode 100644 index 0000000000..e7836602c5 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0955-media-i2c-tc358743-Only-allow-supported-pixel-fmts-i.patch @@ -0,0 +1,30 @@ +From b443f3889a2f689c7f480211e12f17ddc3b483f8 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Fri, 10 Jul 2020 12:40:50 +0100 +Subject: [PATCH] media: i2c: tc358743: Only allow supported pixel + fmts in set_fmt + +Fix commit "media: tc358743: Return an appropriate colorspace from +tc358743_set_fmt" to ensure that the format passed in to set_fmt +is checked to be valid, and reset to the current format if not. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/i2c/tc358743.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/media/i2c/tc358743.c ++++ b/drivers/media/i2c/tc358743.c +@@ -1731,8 +1731,10 @@ static int tc358743_set_fmt(struct v4l2_ + u32 code = format->format.code; /* is overwritten by get_fmt */ + int ret = tc358743_get_fmt(sd, cfg, format); + +- format->format.code = code; +- format->format.colorspace = tc358743_g_colorspace(code); ++ if (code == MEDIA_BUS_FMT_RGB888_1X24 || ++ code == MEDIA_BUS_FMT_UYVY8_1X16) ++ format->format.code = code; ++ format->format.colorspace = tc358743_g_colorspace(format->format.code); + + if (ret) + return ret; diff --git a/target/linux/bcm27xx/patches-5.4/950-0956-media-i2c-ov9281-Add-support-for-8-bit-readout.patch b/target/linux/bcm27xx/patches-5.4/950-0956-media-i2c-ov9281-Add-support-for-8-bit-readout.patch new file mode 100644 index 0000000000..f6880c9eae --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0956-media-i2c-ov9281-Add-support-for-8-bit-readout.patch @@ -0,0 +1,188 @@ +From c673ce1338b69c5c8c6572e361be02356af93a72 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 7 Jul 2020 18:29:10 +0100 +Subject: [PATCH] media: i2c: ov9281: Add support for 8 bit readout + +The sensor supports 8 bit mode as well as 10bit, so add the +relevant code to allow selection of this. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/i2c/ov9281.c | 66 ++++++++++++++++++++++++++++++-------- + 1 file changed, 52 insertions(+), 14 deletions(-) + +--- a/drivers/media/i2c/ov9281.c ++++ b/drivers/media/i2c/ov9281.c +@@ -29,11 +29,12 @@ + + #define OV9281_LINK_FREQ_400MHZ 400000000 + #define OV9281_LANES 2 +-#define OV9281_BITS_PER_SAMPLE 10 + + /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */ +-#define OV9281_PIXEL_RATE (OV9281_LINK_FREQ_400MHZ * 2 * \ +- OV9281_LANES / OV9281_BITS_PER_SAMPLE) ++#define OV9281_PIXEL_RATE_10BIT (OV9281_LINK_FREQ_400MHZ * 2 * \ ++ OV9281_LANES / 10) ++#define OV9281_PIXEL_RATE_8BIT (OV9281_LINK_FREQ_400MHZ * 2 * \ ++ OV9281_LANES / 8) + #define OV9281_XVCLK_FREQ 24000000 + + #define CHIP_ID 0x9281 +@@ -122,24 +123,25 @@ struct ov9281 { + struct v4l2_ctrl *digi_gain; + struct v4l2_ctrl *hblank; + struct v4l2_ctrl *vblank; ++ struct v4l2_ctrl *pixel_rate; + struct v4l2_ctrl *test_pattern; + struct mutex mutex; + bool streaming; + bool power_on; + const struct ov9281_mode *cur_mode; ++ u32 code; + }; + + #define to_ov9281(sd) container_of(sd, struct ov9281, subdev) + + /* + * Xclk 24Mhz +- * max_framerate 120fps ++ * max_framerate 120fps for 10 bit, 144fps for 8 bit. + * mipi_datarate per lane 800Mbps + */ + static const struct regval ov9281_1280x800_regs[] = { + {0x0103, 0x01}, + {0x0302, 0x32}, +- {0x030d, 0x50}, + {0x030e, 0x02}, + {0x3001, 0x00}, + {0x3004, 0x00}, +@@ -168,7 +170,6 @@ static const struct regval ov9281_1280x8 + {0x3620, 0x6f}, + {0x3632, 0x56}, + {0x3633, 0x78}, +- {0x3662, 0x05}, + {0x3666, 0x00}, + {0x366f, 0x5a}, + {0x3680, 0x84}, +@@ -235,6 +236,18 @@ static const struct regval ov9281_1280x8 + {REG_NULL, 0x00}, + }; + ++static const struct regval op_10bit[] = { ++ {0x030d, 0x50}, ++ {0x3662, 0x05}, ++ {REG_NULL, 0x00}, ++}; ++ ++static const struct regval op_8bit[] = { ++ {0x030d, 0x60}, ++ {0x3662, 0x07}, ++ {REG_NULL, 0x00}, ++}; ++ + static const struct ov9281_mode supported_modes[] = { + { + .width = 1280, +@@ -374,12 +387,13 @@ static int ov9281_set_fmt(struct v4l2_su + { + struct ov9281 *ov9281 = to_ov9281(sd); + const struct ov9281_mode *mode; +- s64 h_blank, vblank_def; ++ s64 h_blank, vblank_def, pixel_rate; + + mutex_lock(&ov9281->mutex); + + mode = ov9281_find_best_fit(fmt); +- fmt->format.code = MEDIA_BUS_FMT_Y10_1X10; ++ if (fmt->format.code != MEDIA_BUS_FMT_Y8_1X8) ++ fmt->format.code = MEDIA_BUS_FMT_Y10_1X10; + fmt->format.width = mode->width; + fmt->format.height = mode->height; + fmt->format.field = V4L2_FIELD_NONE; +@@ -396,6 +410,7 @@ static int ov9281_set_fmt(struct v4l2_su + *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; + } else { + ov9281->cur_mode = mode; ++ ov9281->code = fmt->format.code; + h_blank = mode->hts_def - mode->width; + __v4l2_ctrl_modify_range(ov9281->hblank, h_blank, + h_blank, 1, h_blank); +@@ -405,6 +420,11 @@ static int ov9281_set_fmt(struct v4l2_su + OV9281_VTS_MAX - mode->height, + 1, vblank_def); + __v4l2_ctrl_s_ctrl(ov9281->vblank, vblank_def); ++ ++ pixel_rate = (fmt->format.code == MEDIA_BUS_FMT_Y10_1X10) ? ++ OV9281_PIXEL_RATE_10BIT : OV9281_PIXEL_RATE_8BIT; ++ __v4l2_ctrl_modify_range(ov9281->pixel_rate, pixel_rate, ++ pixel_rate, 1, pixel_rate); + } + + mutex_unlock(&ov9281->mutex); +@@ -425,7 +445,7 @@ static int ov9281_get_fmt(struct v4l2_su + } else { + fmt->format.width = mode->width; + fmt->format.height = mode->height; +- fmt->format.code = MEDIA_BUS_FMT_Y10_1X10; ++ fmt->format.code = ov9281->code; + fmt->format.field = V4L2_FIELD_NONE; + fmt->format.colorspace = V4L2_COLORSPACE_SRGB; + fmt->format.ycbcr_enc = +@@ -446,9 +466,16 @@ static int ov9281_enum_mbus_code(struct + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) + { +- if (code->index) ++ switch (code->index) { ++ default: + return -EINVAL; +- code->code = MEDIA_BUS_FMT_Y10_1X10; ++ case 0: ++ code->code = MEDIA_BUS_FMT_Y10_1X10; ++ break; ++ case 1: ++ code->code = MEDIA_BUS_FMT_Y8_1X8; ++ break; ++ } + + return 0; + } +@@ -460,7 +487,8 @@ static int ov9281_enum_frame_sizes(struc + if (fse->index >= ARRAY_SIZE(supported_modes)) + return -EINVAL; + +- if (fse->code != MEDIA_BUS_FMT_Y10_1X10) ++ if (fse->code != MEDIA_BUS_FMT_Y10_1X10 && ++ fse->code != MEDIA_BUS_FMT_Y8_1X8) + return -EINVAL; + + fse->min_width = supported_modes[fse->index].width; +@@ -543,6 +571,13 @@ static int __ov9281_start_stream(struct + if (ret) + return ret; + ++ if (ov9281->code == MEDIA_BUS_FMT_Y10_1X10) ++ ret = ov9281_write_array(ov9281->client, op_10bit); ++ else ++ ret = ov9281_write_array(ov9281->client, op_8bit); ++ if (ret) ++ return ret; ++ + /* In case these controls are set before streaming */ + mutex_unlock(&ov9281->mutex); + ret = v4l2_ctrl_handler_setup(&ov9281->ctrl_handler); +@@ -849,8 +884,11 @@ static int ov9281_initialize_controls(st + if (ctrl) + ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; + +- v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, +- 0, OV9281_PIXEL_RATE, 1, OV9281_PIXEL_RATE); ++ ov9281->pixel_rate = v4l2_ctrl_new_std(handler, NULL, ++ V4L2_CID_PIXEL_RATE, ++ OV9281_PIXEL_RATE_10BIT, ++ OV9281_PIXEL_RATE_10BIT, 1, ++ OV9281_PIXEL_RATE_10BIT); + + h_blank = mode->hts_def - mode->width; + ov9281->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK, diff --git a/target/linux/bcm27xx/patches-5.4/950-0957-overlays-Add-spi0-1cs-and-spi0-2cs.patch b/target/linux/bcm27xx/patches-5.4/950-0957-overlays-Add-spi0-1cs-and-spi0-2cs.patch new file mode 100644 index 0000000000..3af45bb0b6 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0957-overlays-Add-spi0-1cs-and-spi0-2cs.patch @@ -0,0 +1,199 @@ +From 692af7a59fd6d9d3b64edbf028cd75b0096ef8c7 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Fri, 28 Aug 2020 12:55:41 +0100 +Subject: [PATCH] overlays: Add spi0-1cs and spi0-2cs + +The spi0-1cs overlay allows the SPI0 interface to be run with a single +CS line, which can be useful if GPIOs are in short supply. The no_miso +parameter is for write-only devices that don't need the return channel, +and again is there to free up a GPIO. + +spi0-2cs is the new name for spi0-cs (now deprecated with a redirect +to spi0-2cs), but with the addedd no_miso parameter. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/Makefile | 3 +- + arch/arm/boot/dts/overlays/README | 22 ++++++++-- + arch/arm/boot/dts/overlays/overlay_map.dts | 4 ++ + .../boot/dts/overlays/spi0-1cs-overlay.dts | 42 +++++++++++++++++++ + ...i0-cs-overlay.dts => spi0-2cs-overlay.dts} | 8 ++++ + 5 files changed, 75 insertions(+), 4 deletions(-) + create mode 100644 arch/arm/boot/dts/overlays/spi0-1cs-overlay.dts + rename arch/arm/boot/dts/overlays/{spi0-cs-overlay.dts => spi0-2cs-overlay.dts} (79%) + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -161,7 +161,8 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + spi-gpio35-39.dtbo \ + spi-gpio40-45.dtbo \ + spi-rtc.dtbo \ +- spi0-cs.dtbo \ ++ spi0-1cs.dtbo \ ++ spi0-2cs.dtbo \ + spi1-1cs.dtbo \ + spi1-2cs.dtbo \ + spi1-3cs.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -2412,11 +2412,27 @@ Load: dtoverlay=spi-rtc,<param>=<val> + Params: pcf2123 Select the PCF2123 device + + +-Name: spi0-cs +-Info: Allows the (software) CS pins for SPI0 to be changed +-Load: dtoverlay=spi0-cs,<param>=<val> ++Name: spi0-1cs ++Info: Only use one CS pin for SPI0 ++Load: dtoverlay=spi0-1cs,<param>=<val> ++Params: cs0_pin GPIO pin for CS0 (default 8) ++ no_miso Don't claim and use the MISO pin (9), freeing ++ it for other uses. ++ ++ ++Name: spi0-2cs ++Info: Change the CS pins for SPI0 ++Load: dtoverlay=spi0-2cs,<param>=<val> + Params: cs0_pin GPIO pin for CS0 (default 8) + cs1_pin GPIO pin for CS1 (default 7) ++ no_miso Don't claim and use the MISO pin (9), freeing ++ it for other uses. ++ ++ ++Name: spi0-cs ++Info: This overlay has been renamed spi0-1cs, keeping spi0-cs as an ++ alias for backwards compatibility. ++Load: <Deprecated> + + + Name: spi0-hw-cs +--- a/arch/arm/boot/dts/overlays/overlay_map.dts ++++ b/arch/arm/boot/dts/overlays/overlay_map.dts +@@ -61,6 +61,10 @@ + deprecated = "use sdio,bus_width=1,gpios_22_25"; + }; + ++ spi0-cs { ++ renamed = "spi0-2cs"; ++ }; ++ + spi0-hw-cs { + deprecated = "no longer necessary"; + }; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi0-1cs-overlay.dts +@@ -0,0 +1,42 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&spi0_cs_pins>; ++ frag0: __overlay__ { ++ brcm,pins = <8>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ frag1: __overlay__ { ++ cs-gpios = <&gpio 8 1>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&spi0_pins>; ++ __dormant__ { ++ brcm,pins = <10 11>; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&frag0>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ no_miso = <0>,"=3"; ++ }; ++}; +--- a/arch/arm/boot/dts/overlays/spi0-cs-overlay.dts ++++ /dev/null +@@ -1,29 +0,0 @@ +-/dts-v1/; +-/plugin/; +- +- +-/ { +- compatible = "brcm,bcm2835"; +- +- fragment@0 { +- target = <&spi0_cs_pins>; +- frag0: __overlay__ { +- brcm,pins = <8 7>; +- }; +- }; +- +- fragment@1 { +- target = <&spi0>; +- frag1: __overlay__ { +- cs-gpios = <&gpio 8 1>, <&gpio 7 1>; +- status = "okay"; +- }; +- }; +- +- __overrides__ { +- cs0_pin = <&frag0>,"brcm,pins:0", +- <&frag1>,"cs-gpios:4"; +- cs1_pin = <&frag0>,"brcm,pins:4", +- <&frag1>,"cs-gpios:16"; +- }; +-}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi0-2cs-overlay.dts +@@ -0,0 +1,37 @@ ++/dts-v1/; ++/plugin/; ++ ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&spi0_cs_pins>; ++ frag0: __overlay__ { ++ brcm,pins = <8 7>; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ frag1: __overlay__ { ++ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0_pins>; ++ __dormant__ { ++ brcm,pins = <10 11>; ++ }; ++ }; ++ ++ __overrides__ { ++ cs0_pin = <&frag0>,"brcm,pins:0", ++ <&frag1>,"cs-gpios:4"; ++ cs1_pin = <&frag0>,"brcm,pins:4", ++ <&frag1>,"cs-gpios:16"; ++ no_miso = <0>,"=2"; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-5.4/950-0958-overlays-Fix-error-in-README.patch b/target/linux/bcm27xx/patches-5.4/950-0958-overlays-Fix-error-in-README.patch new file mode 100644 index 0000000000..ab6db1e389 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0958-overlays-Fix-error-in-README.patch @@ -0,0 +1,23 @@ +From 9102032e6d06f271058b6bd98db453a2275ec9b9 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Fri, 28 Aug 2020 22:04:05 +0100 +Subject: [PATCH] overlays: Fix error in README + +spi0-cs has been renamed spi0-2cs, not spi0-1cs. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/README | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -2430,7 +2430,7 @@ Params: cs0_pin GPIO pin + + + Name: spi0-cs +-Info: This overlay has been renamed spi0-1cs, keeping spi0-cs as an ++Info: This overlay has been renamed spi0-2cs, keeping spi0-cs as an + alias for backwards compatibility. + Load: <Deprecated> + diff --git a/target/linux/bcm27xx/patches-5.4/950-0959-overlays-Minor-README-correction.patch b/target/linux/bcm27xx/patches-5.4/950-0959-overlays-Minor-README-correction.patch new file mode 100644 index 0000000000..1cc7ff9c47 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0959-overlays-Minor-README-correction.patch @@ -0,0 +1,21 @@ +From 8314b7ffe066745d9a2045e2ecaf287487342df3 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Wed, 2 Sep 2020 08:39:57 +0100 +Subject: [PATCH] overlays: Minor README correction + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/README | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -134,7 +134,7 @@ Params: + 6=Alt 7=Speed/Flash + 8=Link 9=Activity + +- eth_led1 Set mode of LED1 - green on Pi3B (default "6"), ++ eth_led1 Set mode of LED1 - green on Pi3B+ (default "6"), + amber on Pi4 (default "8"). See eth_led0 for + legal values. + diff --git a/target/linux/bcm27xx/patches-5.4/950-0960-staging-fbtft-Add-support-for-display-variants.patch b/target/linux/bcm27xx/patches-5.4/950-0960-staging-fbtft-Add-support-for-display-variants.patch new file mode 100644 index 0000000000..185e8eb493 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0960-staging-fbtft-Add-support-for-display-variants.patch @@ -0,0 +1,204 @@ +From fe85ae40abf546bf592d171de942c17238103e52 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Tue, 1 Sep 2020 18:15:27 +0100 +Subject: [PATCH] staging/fbtft: Add support for display variants + +Display variants are intended as a replacement for the now-deleted +fbtft_device drivers. Drivers can register additional compatible +strings with a custom callback that can make the required changes +to the fbtft_display structure. + +Start the ball rolling by adding adafruit18, adafruit18_green and +sainsmart18 displays. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/staging/fbtft/fb_st7735r.c | 38 +++++++++++++++++++++++++++++- + drivers/staging/fbtft/fbtft-core.c | 15 +++++++++++- + drivers/staging/fbtft/fbtft.h | 28 +++++++++++++++++----- + 3 files changed, 73 insertions(+), 8 deletions(-) + +--- a/drivers/staging/fbtft/fb_st7735r.c ++++ b/drivers/staging/fbtft/fb_st7735r.c +@@ -16,6 +16,10 @@ + #define DEFAULT_GAMMA "0F 1A 0F 18 2F 28 20 22 1F 1B 23 37 00 07 02 10\n" \ + "0F 1B 0F 17 33 2C 29 2E 30 30 39 3F 00 07 03 10" + ++#define ADAFRUIT18_GAMMA \ ++ "02 1c 07 12 37 32 29 2d 29 25 2B 39 00 01 03 10\n" \ ++ "03 1d 07 06 2E 2C 29 2D 2E 2E 37 3F 00 00 02 10" ++ + static const s16 default_init_sequence[] = { + -1, MIPI_DCS_SOFT_RESET, + -2, 150, /* delay */ +@@ -94,6 +98,14 @@ static void set_addr_win(struct fbtft_pa + write_reg(par, MIPI_DCS_WRITE_MEMORY_START); + } + ++static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par, ++ int xs, int ys, int xe, int ye) ++{ ++ write_reg(par, 0x2A, 0, xs + 2, 0, xe + 2); ++ write_reg(par, 0x2B, 0, ys + 1, 0, ye + 1); ++ write_reg(par, 0x2C); ++} ++ + #define MY BIT(7) + #define MX BIT(6) + #define MV BIT(5) +@@ -174,12 +186,36 @@ static struct fbtft_display display = { + }, + }; + +-FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7735r", &display); ++int variant_adafruit18(struct fbtft_display *display) ++{ ++ display->gamma = ADAFRUIT18_GAMMA; ++ return 0; ++} ++ ++int variant_adafruit18_green(struct fbtft_display *display) ++{ ++ display->gamma = ADAFRUIT18_GAMMA; ++ display->fbtftops.set_addr_win = adafruit18_green_tab_set_addr_win; ++ return 0; ++} ++ ++FBTFT_REGISTER_DRIVER_START(&display) ++FBTFT_COMPATIBLE("sitronix,st7735r") ++FBTFT_COMPATIBLE("fbtft,sainsmart18") ++FBTFT_VARIANT_COMPATIBLE("fbtft,adafruit18", variant_adafruit18) ++FBTFT_VARIANT_COMPATIBLE("fbtft,adafruit18_green", variant_adafruit18_green) ++FBTFT_REGISTER_DRIVER_END(DRVNAME, &display); + + MODULE_ALIAS("spi:" DRVNAME); + MODULE_ALIAS("platform:" DRVNAME); + MODULE_ALIAS("spi:st7735r"); + MODULE_ALIAS("platform:st7735r"); ++MODULE_ALIAS("spi:sainsmart18"); ++MODULE_ALIAS("platform:sainsmart"); ++MODULE_ALIAS("spi:adafruit18"); ++MODULE_ALIAS("platform:adafruit18"); ++MODULE_ALIAS("spi:adafruit18_green"); ++MODULE_ALIAS("platform:adafruit18_green"); + + MODULE_DESCRIPTION("FB driver for the ST7735R LCD Controller"); + MODULE_AUTHOR("Noralf Tronnes"); +--- a/drivers/staging/fbtft/fbtft-core.c ++++ b/drivers/staging/fbtft/fbtft-core.c +@@ -24,6 +24,7 @@ + #include <linux/platform_device.h> + #include <linux/spinlock.h> + #include <linux/of.h> ++#include <linux/of_device.h> + #include <video/mipi_display.h> + + #include "fbtft.h" +@@ -1200,6 +1201,7 @@ static struct fbtft_platform_data *fbtft + * @display: Display properties + * @sdev: SPI device + * @pdev: Platform device ++ * @dt_ids: Compatible string table + * + * Allocates, initializes and registers a framebuffer + * +@@ -1209,12 +1211,15 @@ static struct fbtft_platform_data *fbtft + */ + int fbtft_probe_common(struct fbtft_display *display, + struct spi_device *sdev, +- struct platform_device *pdev) ++ struct platform_device *pdev, ++ const struct of_device_id *dt_ids) + { + struct device *dev; + struct fb_info *info; + struct fbtft_par *par; + struct fbtft_platform_data *pdata; ++ const struct of_device_id *match; ++ int (*variant)(struct fbtft_display *); + int ret; + + if (sdev) +@@ -1230,6 +1235,14 @@ int fbtft_probe_common(struct fbtft_disp + pdata = fbtft_probe_dt(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); ++ match = of_match_device(dt_ids, dev); ++ if (match && match->data) { ++ /* apply the variant */ ++ variant = match->data; ++ ret = (*variant)(display); ++ if (ret) ++ return ret; ++ } + } + + info = fbtft_framebuffer_alloc(display, dev, pdata); +--- a/drivers/staging/fbtft/fbtft.h ++++ b/drivers/staging/fbtft/fbtft.h +@@ -251,7 +251,8 @@ void fbtft_register_backlight(struct fbt + void fbtft_unregister_backlight(struct fbtft_par *par); + int fbtft_init_display(struct fbtft_par *par); + int fbtft_probe_common(struct fbtft_display *display, struct spi_device *sdev, +- struct platform_device *pdev); ++ struct platform_device *pdev, ++ const struct of_device_id *dt_ids); + int fbtft_remove_common(struct device *dev, struct fb_info *info); + + /* fbtft-io.c */ +@@ -272,11 +273,13 @@ void fbtft_write_reg8_bus9(struct fbtft_ + void fbtft_write_reg16_bus8(struct fbtft_par *par, int len, ...); + void fbtft_write_reg16_bus16(struct fbtft_par *par, int len, ...); + +-#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \ ++#define FBTFT_REGISTER_DRIVER_START(_display) \ ++ \ ++static const struct of_device_id dt_ids[]; \ + \ + static int fbtft_driver_probe_spi(struct spi_device *spi) \ + { \ +- return fbtft_probe_common(_display, spi, NULL); \ ++ return fbtft_probe_common(_display, spi, NULL, dt_ids); \ + } \ + \ + static int fbtft_driver_remove_spi(struct spi_device *spi) \ +@@ -288,7 +291,7 @@ static int fbtft_driver_remove_spi(struc + \ + static int fbtft_driver_probe_pdev(struct platform_device *pdev) \ + { \ +- return fbtft_probe_common(_display, NULL, pdev); \ ++ return fbtft_probe_common(_display, NULL, pdev, dt_ids); \ + } \ + \ + static int fbtft_driver_remove_pdev(struct platform_device *pdev) \ +@@ -298,8 +301,16 @@ static int fbtft_driver_remove_pdev(stru + return fbtft_remove_common(&pdev->dev, info); \ + } \ + \ +-static const struct of_device_id dt_ids[] = { \ +- { .compatible = _compatible }, \ ++static const struct of_device_id dt_ids[] = { ++ ++#define FBTFT_COMPATIBLE(_compatible) \ ++ { .compatible = _compatible }, ++ ++#define FBTFT_VARIANT_COMPATIBLE(_compatible, _variant) \ ++ { .compatible = _compatible, .data = _variant }, ++ ++#define FBTFT_REGISTER_DRIVER_END(_name, _display) \ ++ \ + {}, \ + }; \ + \ +@@ -344,6 +355,11 @@ static void __exit fbtft_driver_module_e + module_init(fbtft_driver_module_init); \ + module_exit(fbtft_driver_module_exit); + ++#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \ ++ FBTFT_REGISTER_DRIVER_START(_display) \ ++ FBTFT_COMPATIBLE(_compatible) \ ++ FBTFT_REGISTER_DRIVER_END(_name, _display) ++ + /* Debug macros */ + + /* shorthand debug levels */ diff --git a/target/linux/bcm27xx/patches-5.4/950-0961-overlays-Add-adafruit18-and-sainsmart18-overlays.patch b/target/linux/bcm27xx/patches-5.4/950-0961-overlays-Add-adafruit18-and-sainsmart18-overlays.patch new file mode 100644 index 0000000000..986ddd49b5 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0961-overlays-Add-adafruit18-and-sainsmart18-overlays.patch @@ -0,0 +1,169 @@ +From dde4afa87452e8499c611c9a889f4c5f35d9e2bb Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Thu, 3 Sep 2020 17:36:00 +0100 +Subject: [PATCH] overlays: Add adafruit18 and sainsmart18 overlays + +Add support for three ST7735R-based displays - adafruit18, +adafruit18_green and sainsmart18. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/Makefile | 2 + + arch/arm/boot/dts/overlays/README | 15 ++++++ + .../boot/dts/overlays/adafruit18-overlay.dts | 49 +++++++++++++++++++ + .../boot/dts/overlays/sainsmart18-overlay.dts | 47 ++++++++++++++++++ + 4 files changed, 113 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/adafruit18-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/sainsmart18-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -4,6 +4,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += overlay_ma + + dtbo-$(CONFIG_ARCH_BCM2835) += \ + act-led.dtbo \ ++ adafruit18.dtbo \ + adau1977-adc.dtbo \ + adau7002-simple.dtbo \ + ads1015.dtbo \ +@@ -147,6 +148,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + rpi-tv.dtbo \ + rpivid-v4l2.dtbo \ + rra-digidac1-wm8741-audio.dtbo \ ++ sainsmart18.dtbo \ + sc16is750-i2c.dtbo \ + sc16is752-i2c.dtbo \ + sc16is752-spi0.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -261,6 +261,14 @@ Params: activelow Set to " + REQUIRED + + ++Name: adafruit18 ++Info: Overlay for the SPI-connected Adafruit 1.8" display (based on the ++ ST7735R chip). It includes support for the "green tab" version. ++Load: dtoverlay=adafruit18,<param>=<val> ++Params: green Use the adafruit18_green variant. ++ rotate Display rotation {0,90,180,270} ++ ++ + Name: adau1977-adc + Info: Overlay for activation of ADAU1977 ADC codec over I2C for control + and I2S for data. +@@ -2251,6 +2259,13 @@ Load: dtoverlay=rra-digidac1-wm8741-au + Params: <None> + + ++Name: sainsmart18 ++Info: Overlay for the SPI-connected Sainsmart 1.8" display (based on the ++ ST7735R chip). ++Load: dtoverlay=sainsmart18,<param>=<val> ++Params: rotate Display rotation {0,90,180,270} ++ ++ + Name: sc16is750-i2c + Info: Overlay for the NXP SC16IS750 UART with I2C Interface + Enables the chip on I2C1 at 0x48 (or the "addr" parameter value). To +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/adafruit18-overlay.dts +@@ -0,0 +1,49 @@ ++/* ++ * Device Tree overlay for Adafruit 1.8" TFT LCD with ST7735R chip 160x128 ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ af18: adafruit18@0 { ++ compatible = "fbtft,adafruit18"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ spi-max-frequency = <40000000>; ++ rotate = <90>; ++ buswidth = <8>; ++ fps = <50>; ++ height = <160>; ++ width = <128>; ++ reset-gpios = <&gpio 25 0>; ++ dc-gpios = <&gpio 24 0>; ++ led-gpios = <&gpio 18 0>; ++ bgr; ++ debug = <0>; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ green = <&af18>, "compatible=fbtft,adafruit18_green"; ++ rotate = <&af18>, "rotate:0"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/sainsmart18-overlay.dts +@@ -0,0 +1,47 @@ ++/* ++ * Device Tree overlay for the Sainsmart 1.8" TFT LCD with ST7735R chip 160x128 ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ ss18: sainsmart18@0 { ++ compatible = "fbtft,sainsmart18"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ spi-max-frequency = <40000000>; ++ rotate = <90>; ++ buswidth = <8>; ++ fps = <50>; ++ height = <160>; ++ width = <128>; ++ reset-gpios = <&gpio 25 0>; ++ dc-gpios = <&gpio 24 0>; ++ bgr; ++ debug = <0>; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ rotate = <&ss18>, "rotate:0"; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-5.4/950-0962-ARM-dts-Limit-BT-modem-baud-rate-on-3B.patch b/target/linux/bcm27xx/patches-5.4/950-0962-ARM-dts-Limit-BT-modem-baud-rate-on-3B.patch new file mode 100644 index 0000000000..f88cc7b397 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0962-ARM-dts-Limit-BT-modem-baud-rate-on-3B.patch @@ -0,0 +1,28 @@ +From 27f210c863d3349d41e366fb7573e9dcc0708e3d Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Fri, 4 Sep 2020 09:04:29 +0100 +Subject: [PATCH] ARM: dts: Limit BT modem baud rate on 3B + +The 3B doesn't have the flow control signals connected to the BT modem, +which limits the maximum usable baud rate to below 1 Mbaud. Use +921600 as a relatively safe default value, but the krnbt_baudrate +parameter can still override it. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +@@ -117,6 +117,10 @@ + status = "okay"; + }; + ++&bt { ++ max-speed = <921600>; ++}; ++ + &spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins &spi0_cs_pins>; diff --git a/target/linux/bcm27xx/patches-5.4/950-0963-overlays-Update-i2c0-overlay-to-disable-the-i2c0mux.patch b/target/linux/bcm27xx/patches-5.4/950-0963-overlays-Update-i2c0-overlay-to-disable-the-i2c0mux.patch new file mode 100644 index 0000000000..3ce5e0bbd3 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0963-overlays-Update-i2c0-overlay-to-disable-the-i2c0mux.patch @@ -0,0 +1,70 @@ +From 2be1e1c949138b40aac6be1e6f761c69e98dcf66 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 3 Sep 2020 14:59:40 +0100 +Subject: [PATCH] overlays: Update i2c0 overlay to disable the + i2c0mux. + +The i2c0 overlay was assigning pinctrl settings to node i2c0, +which is now the port@0 output of the mux. That leaves a high +chance of it colliding with the port@1 output and not doing +what was intended. + +Set the i2c0 overlay to disable i2c0mux, set the pin-ctrl on +the root i2c controller, and redirect the alias, so overall it +behaves exactly as before. +Combining with dtparam=i2c_vc=on is going to cause conflicts, +so this is noted in the README. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/README | 7 +++++++ + arch/arm/boot/dts/overlays/i2c0-overlay.dts | 15 ++++++++++++++- + 2 files changed, 21 insertions(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1354,6 +1354,13 @@ Name: i2c0 + Info: Change i2c0 pin usage. Not all pin combinations are usable on all + platforms - platforms other then Compute Modules can only use this + to disable transaction combining. ++ Do NOT use in conjunction with dtparam=i2c_vc=on. From the 5.4 kernel ++ onwards the base DT includes the use of i2c_mux_pinctrl to expose two ++ muxings of BSC0 - GPIOs 0&1, and whichever combination is used for the ++ camera and display connectors. This overlay disables that mux and ++ configures /dev/i2c0 to point at whichever set of pins is requested. ++ dtparam=i2c_vc=on will try and enable the mux, so combining the two ++ will cause conflicts. + Load: dtoverlay=i2c0,<param>=<val> + Params: pins_0_1 Use pins 0 and 1 (default) + pins_28_29 Use pins 28 and 29 +--- a/arch/arm/boot/dts/overlays/i2c0-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c0-overlay.dts +@@ -5,7 +5,7 @@ + compatible = "brcm,bcm2835"; + + fragment@0 { +- target = <&i2c0>; ++ target = <&i2c0if>; + __overlay__ { + status = "okay"; + pinctrl-0 = <&i2c0_pins>; +@@ -51,6 +51,19 @@ + }; + }; + ++ fragment@6 { ++ target = <&i2c0mux>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@7 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c0 = "/soc/i2c@7e205000"; ++ }; ++ }; + __overrides__ { + pins_0_1 = <0>,"+1-2-3-4"; + pins_28_29 = <0>,"-1+2-3-4"; diff --git a/target/linux/bcm27xx/patches-5.4/950-0964-dt-Remove-duplicate-assignment-for-i2c0-pinctrl-conf.patch b/target/linux/bcm27xx/patches-5.4/950-0964-dt-Remove-duplicate-assignment-for-i2c0-pinctrl-conf.patch new file mode 100644 index 0000000000..ce3d9b5773 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0964-dt-Remove-duplicate-assignment-for-i2c0-pinctrl-conf.patch @@ -0,0 +1,155 @@ +From 12bd4eee1bb882417a38c2b5c9790e97725e489d Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 3 Sep 2020 15:12:50 +0100 +Subject: [PATCH] dt: Remove duplicate assignment for i2c0 pinctrl + config + +The include file bcm283x-rpi-i2c0mux_0_XX.dtsi was setting +pinctrl-0 on i2c0mux, as were the individual platform DT files. + +Remove this duplication and rely on the include file. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 4 ---- + arch/arm/boot/dts/bcm2708-rpi-b.dts | 4 ---- + arch/arm/boot/dts/bcm2708-rpi-cm.dts | 4 ---- + arch/arm/boot/dts/bcm2708-rpi-zero-w.dts | 4 ---- + arch/arm/boot/dts/bcm2708-rpi-zero.dts | 4 ---- + arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 4 ---- + arch/arm/boot/dts/bcm2710-rpi-2-b.dts | 4 ---- + arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 4 ---- + arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 4 ---- + arch/arm/boot/dts/bcm2710-rpi-cm3.dts | 4 ---- + 10 files changed, 40 deletions(-) + +--- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts +@@ -73,10 +73,6 @@ + clock-frequency = <100000>; + }; + +-&i2c0mux { +- pinctrl-0 = <&i2c0_pins>; +-}; +- + &i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; +--- a/arch/arm/boot/dts/bcm2708-rpi-b.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts +@@ -73,10 +73,6 @@ + clock-frequency = <100000>; + }; + +-&i2c0mux { +- pinctrl-0 = <&i2c0_pins>; +-}; +- + &i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; +--- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts +@@ -72,10 +72,6 @@ + clock-frequency = <100000>; + }; + +-&i2c0mux { +- pinctrl-0 = <&i2c0_pins>; +-}; +- + &i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; +--- a/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts +@@ -122,10 +122,6 @@ + clock-frequency = <100000>; + }; + +-&i2c0mux { +- pinctrl-0 = <&i2c0_pins>; +-}; +- + &i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; +--- a/arch/arm/boot/dts/bcm2708-rpi-zero.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-zero.dts +@@ -76,10 +76,6 @@ + clock-frequency = <100000>; + }; + +-&i2c0mux { +- pinctrl-0 = <&i2c0_pins>; +-}; +- + &i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; +--- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts ++++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts +@@ -73,10 +73,6 @@ + clock-frequency = <100000>; + }; + +-&i2c0mux { +- pinctrl-0 = <&i2c0_pins>; +-}; +- + &i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; +--- a/arch/arm/boot/dts/bcm2710-rpi-2-b.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-2-b.dts +@@ -73,10 +73,6 @@ + clock-frequency = <100000>; + }; + +-&i2c0mux { +- pinctrl-0 = <&i2c0_pins>; +-}; +- + &i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts +@@ -132,10 +132,6 @@ + clock-frequency = <100000>; + }; + +-&i2c0mux { +- pinctrl-0 = <&i2c0_pins>; +-}; +- + &i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +@@ -147,10 +147,6 @@ + clock-frequency = <100000>; + }; + +-&i2c0mux { +- pinctrl-0 = <&i2c0_pins>; +-}; +- + &i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; +--- a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts +@@ -92,10 +92,6 @@ + clock-frequency = <100000>; + }; + +-&i2c0mux { +- pinctrl-0 = <&i2c0_pins>; +-}; +- + &i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; diff --git a/target/linux/bcm27xx/patches-5.4/950-0965-overlays-Add-option-for-composite-to-vc4-kms-v3d-pi4.patch b/target/linux/bcm27xx/patches-5.4/950-0965-overlays-Add-option-for-composite-to-vc4-kms-v3d-pi4.patch new file mode 100644 index 0000000000..0334261bb5 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0965-overlays-Add-option-for-composite-to-vc4-kms-v3d-pi4.patch @@ -0,0 +1,68 @@ +From bbced22ee3d4c08612bbc35c860d2274e85d5a51 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 27 Aug 2020 18:57:26 +0100 +Subject: [PATCH] overlays: Add option for composite to + vc4-kms-v3d-pi4. + +Composite is an alternative to HDMI/DPI/DSI on Pi4 as it +requires very particular clock setups. +Add an option to vc4-kms-v3d-pi4 to enable composite and +disable all other graphics outputs. + +NB This must be used in conjunction with enable_tvout=1 + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/README | 2 ++ + .../dts/overlays/vc4-kms-v3d-pi4-overlay.dts | 26 +++++++++++++++++++ + 2 files changed, 28 insertions(+) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -2924,6 +2924,8 @@ Params: cma-256 CMA is 2 + audio1 Enable or disable audio over HDMI1 (default + "on") + noaudio Disable all HDMI audio (default "off") ++ composite Enable the composite output (disables all other ++ outputs) + + + Name: vga666 +--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts ++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts +@@ -152,9 +152,35 @@ + }; + }; + ++ fragment@21 { ++ target = <&pixelvalve3>; ++ __dormant__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@22 { ++ target = <&vec>; ++ __dormant__ { ++ status = "okay"; ++ }; ++ }; ++ + __overrides__ { + audio = <0>,"!17"; + audio1 = <0>,"!18"; + noaudio = <0>,"=17", <0>,"=18", <0>,"!19"; ++ composite = <0>, "!1", ++ <0>, "!2", ++ <0>, "!3", ++ <0>, "!4", ++ <0>, "!6", ++ <0>, "!7", ++ <0>, "!8", ++ <0>, "!9", ++ <0>, "!10", ++ <0>, "!16", ++ <0>, "=21", ++ <0>, "=22"; + }; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0966-minor-typo-in-directions.patch b/target/linux/bcm27xx/patches-5.4/950-0966-minor-typo-in-directions.patch new file mode 100644 index 0000000000..2a649333cf --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0966-minor-typo-in-directions.patch @@ -0,0 +1,20 @@ +From 8f2841137865fb064ab59fc60b2bd22bbd27078a Mon Sep 17 00:00:00 2001 +From: lsellens <lsellens@gmail.com> +Date: Mon, 14 Sep 2020 22:35:39 -0500 +Subject: [PATCH] minor typo in directions + +--- + arch/arm/boot/dts/overlays/gpio-fan-overlay.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/overlays/gpio-fan-overlay.dts ++++ b/arch/arm/boot/dts/overlays/gpio-fan-overlay.dts +@@ -31,7 +31,7 @@ + * - sudo nano /boot/config.txt add "dtoverlay=gpio-fan" or "dtoverlay=gpio-fan,gpiopin=12,temp=45000" + * or + * - sudo sh -c 'printf "\n# Enable PI GPIO-Fan Default\ndtoverlay=gpio-fan\n" >> /boot/config.txt' +- * - sudo sh -c 'printf "\n# Enable PI GPIO-Fan Custom\ntoverlay=gpio-fan,gpiopin=12,temp=45000\n" >> /boot/config.txt' ++ * - sudo sh -c 'printf "\n# Enable PI GPIO-Fan Custom\ndtoverlay=gpio-fan,gpiopin=12,temp=45000\n" >> /boot/config.txt' + * + */ + /dts-v1/; diff --git a/target/linux/bcm27xx/patches-5.4/950-0967-overlays-Regenerate-upstream-pi4-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0967-overlays-Regenerate-upstream-pi4-overlay.patch new file mode 100644 index 0000000000..c025aa2735 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0967-overlays-Regenerate-upstream-pi4-overlay.patch @@ -0,0 +1,31 @@ +From b1345dbdf08ded4350233bc95925647d01e936f8 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 14 Sep 2020 15:49:38 +0100 +Subject: [PATCH] overlays: Regenerate upstream-pi4 overlay + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts ++++ b/arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts +@@ -134,6 +134,18 @@ + }; + }; + fragment@21 { ++ target = <&pixelvalve3>; ++ __dormant__ { ++ status = "okay"; ++ }; ++ }; ++ fragment@22 { ++ target = <&vec>; ++ __dormant__ { ++ status = "okay"; ++ }; ++ }; ++ fragment@23 { + target = <&usb>; + #address-cells = <1>; + #size-cells = <1>; diff --git a/target/linux/bcm27xx/patches-5.4/950-0968-overlays-Add-parameters-to-adafruit18-sainsmart18.patch b/target/linux/bcm27xx/patches-5.4/950-0968-overlays-Add-parameters-to-adafruit18-sainsmart18.patch new file mode 100644 index 0000000000..99ef611fe3 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0968-overlays-Add-parameters-to-adafruit18-sainsmart18.patch @@ -0,0 +1,94 @@ +From 9249fb1ac6b8bfcc0056fe2a871d4965b774c667 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 14 Sep 2020 15:48:16 +0100 +Subject: [PATCH] overlays: Add parameters to adafruit18, sainsmart18 + +Also fix polarity of the reset GPIO. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/README | 13 +++++++++++++ + arch/arm/boot/dts/overlays/adafruit18-overlay.dts | 11 +++++++++-- + arch/arm/boot/dts/overlays/sainsmart18-overlay.dts | 10 ++++++++-- + 3 files changed, 30 insertions(+), 4 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -267,6 +267,13 @@ Info: Overlay for the SPI-connected Ad + Load: dtoverlay=adafruit18,<param>=<val> + Params: green Use the adafruit18_green variant. + rotate Display rotation {0,90,180,270} ++ speed SPI bus speed in Hz (default 4000000) ++ fps Display frame rate in Hz ++ bgr Enable BGR mode (default on) ++ debug Debug output level {0-7} ++ dc_pin GPIO pin for D/C (default 24) ++ reset_pin GPIO pin for RESET (default 25) ++ led_pin GPIO used to control backlight (default 18) + + + Name: adau1977-adc +@@ -2271,6 +2278,12 @@ Info: Overlay for the SPI-connected Sa + ST7735R chip). + Load: dtoverlay=sainsmart18,<param>=<val> + Params: rotate Display rotation {0,90,180,270} ++ speed SPI bus speed in Hz (default 4000000) ++ fps Display frame rate in Hz ++ bgr Enable BGR mode (default on) ++ debug Debug output level {0-7} ++ dc_pin GPIO pin for D/C (default 24) ++ reset_pin GPIO pin for RESET (default 25) + + + Name: sc16is750-i2c +--- a/arch/arm/boot/dts/overlays/adafruit18-overlay.dts ++++ b/arch/arm/boot/dts/overlays/adafruit18-overlay.dts +@@ -33,7 +33,7 @@ + fps = <50>; + height = <160>; + width = <128>; +- reset-gpios = <&gpio 25 0>; ++ reset-gpios = <&gpio 25 1>; + dc-gpios = <&gpio 24 0>; + led-gpios = <&gpio 18 0>; + bgr; +@@ -44,6 +44,13 @@ + + __overrides__ { + green = <&af18>, "compatible=fbtft,adafruit18_green"; +- rotate = <&af18>, "rotate:0"; ++ speed = <&af18>,"spi-max-frequency:0"; ++ rotate = <&af18>,"rotate:0"; ++ fps = <&af18>,"fps:0"; ++ bgr = <&af18>,"bgr?"; ++ debug = <&af18>,"debug:0"; ++ dc_pin = <&af18>,"dc-gpios:4"; ++ reset_pin = <&af18>,"reset-gpios:4"; ++ led_pin = <&af18>,"led-gpios:4"; + }; + }; +--- a/arch/arm/boot/dts/overlays/sainsmart18-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sainsmart18-overlay.dts +@@ -33,7 +33,7 @@ + fps = <50>; + height = <160>; + width = <128>; +- reset-gpios = <&gpio 25 0>; ++ reset-gpios = <&gpio 25 1>; + dc-gpios = <&gpio 24 0>; + bgr; + debug = <0>; +@@ -42,6 +42,12 @@ + }; + + __overrides__ { +- rotate = <&ss18>, "rotate:0"; ++ speed = <&ss18>,"spi-max-frequency:0"; ++ rotate = <&ss18>,"rotate:0"; ++ fps = <&ss18>,"fps:0"; ++ bgr = <&ss18>,"bgr?"; ++ debug = <&ss18>,"debug:0"; ++ dc_pin = <&ss18>,"dc-gpios:4"; ++ reset_pin = <&ss18>,"reset-gpios:4"; + }; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0969-rpivid_h265-Fix-width-height-typo.patch b/target/linux/bcm27xx/patches-5.4/950-0969-rpivid_h265-Fix-width-height-typo.patch new file mode 100644 index 0000000000..3aeb6e41ca --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0969-rpivid_h265-Fix-width-height-typo.patch @@ -0,0 +1,21 @@ +From 3effc5ad6a017d4523158e04d2543a42def1744f Mon Sep 17 00:00:00 2001 +From: popcornmix <popcornmix@gmail.com> +Date: Mon, 21 Sep 2020 14:02:44 +0100 +Subject: [PATCH] rpivid_h265: Fix width/height typo + +Signed-off-by: popcornmix <popcornmix@gmail.com> +--- + drivers/staging/media/rpivid/rpivid_h265.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/media/rpivid/rpivid_h265.c ++++ b/drivers/staging/media/rpivid/rpivid_h265.c +@@ -2178,7 +2178,7 @@ static int rpivid_h265_start(struct rpiv + if (w > 4096) + w = 4096; + if (h == 0) +- w = 1088; ++ h = 1088; + if (h > 4096) + h = 4096; + wxh = w * h; diff --git a/target/linux/bcm27xx/patches-5.4/950-0970-overlays-Add-extra-CMA-sizes-up-to-512M.patch b/target/linux/bcm27xx/patches-5.4/950-0970-overlays-Add-extra-CMA-sizes-up-to-512M.patch new file mode 100644 index 0000000000..b9d46ac8b3 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0970-overlays-Add-extra-CMA-sizes-up-to-512M.patch @@ -0,0 +1,78 @@ +From 43d90a5beafa788c629c41a22623d82c10a9bbb9 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 21 Sep 2020 22:00:10 +0100 +Subject: [PATCH] overlays: Add extra CMA sizes (up to 512M) + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/README | 24 ++++++++++++++++++---- + arch/arm/boot/dts/overlays/cma-overlay.dts | 4 ++++ + 2 files changed, 24 insertions(+), 4 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -582,7 +582,11 @@ Name: cma + Info: Set custom CMA sizes, only use if you know what you are doing, might + clash with other overlays like vc4-fkms-v3d and vc4-kms-v3d. + Load: dtoverlay=cma,<param>=<val> +-Params: cma-256 CMA is 256MB (needs 1GB) ++Params: cma-512 CMA is 512MB (needs 1GB) ++ cma-448 CMA is 448MB (needs 1GB) ++ cma-384 CMA is 384MB (needs 1GB) ++ cma-320 CMA is 320MB (needs 1GB) ++ cma-256 CMA is 256MB (needs 1GB) + cma-192 CMA is 192MB (needs 1GB) + cma-128 CMA is 128MB + cma-96 CMA is 96MB +@@ -2892,7 +2896,11 @@ Name: vc4-fkms-v3d + Info: Enable Eric Anholt's DRM VC4 V3D driver on top of the dispmanx + display stack. + Load: dtoverlay=vc4-fkms-v3d,<param> +-Params: cma-256 CMA is 256MB (needs 1GB) ++Params: cma-512 CMA is 512MB (needs 1GB) ++ cma-448 CMA is 448MB (needs 1GB) ++ cma-384 CMA is 384MB (needs 1GB) ++ cma-320 CMA is 320MB (needs 1GB) ++ cma-256 CMA is 256MB (needs 1GB) + cma-192 CMA is 192MB (needs 1GB) + cma-128 CMA is 128MB + cma-96 CMA is 96MB +@@ -2911,7 +2919,11 @@ Params: <None> + Name: vc4-kms-v3d + Info: Enable Eric Anholt's DRM VC4 HDMI/HVS/V3D driver. + Load: dtoverlay=vc4-kms-v3d,<param> +-Params: cma-256 CMA is 256MB (needs 1GB) ++Params: cma-512 CMA is 512MB (needs 1GB) ++ cma-448 CMA is 448MB (needs 1GB) ++ cma-384 CMA is 384MB (needs 1GB) ++ cma-320 CMA is 320MB (needs 1GB) ++ cma-256 CMA is 256MB (needs 1GB) + cma-192 CMA is 192MB (needs 1GB) + cma-128 CMA is 128MB + cma-96 CMA is 96MB +@@ -2925,7 +2937,11 @@ Params: cma-256 CMA is 2 + Name: vc4-kms-v3d-pi4 + Info: Enable Eric Anholt's DRM VC4 HDMI/HVS/V3D driver for Pi4. + Load: dtoverlay=vc4-kms-v3d-pi4,<param> +-Params: cma-256 CMA is 256MB ++Params: cma-512 CMA is 512MB ++ cma-448 CMA is 448MB ++ cma-384 CMA is 384MB ++ cma-320 CMA is 320MB ++ cma-256 CMA is 256MB + cma-192 CMA is 192MB + cma-128 CMA is 128MB + cma-96 CMA is 96MB +--- a/arch/arm/boot/dts/overlays/cma-overlay.dts ++++ b/arch/arm/boot/dts/overlays/cma-overlay.dts +@@ -21,6 +21,10 @@ + }; + + __overrides__ { ++ cma-512 = <&frag0>,"size:0=",<0x20000000>; ++ cma-448 = <&frag0>,"size:0=",<0x1c000000>; ++ cma-384 = <&frag0>,"size:0=",<0x18000000>; ++ cma-320 = <&frag0>,"size:0=",<0x14000000>; + cma-256 = <&frag0>,"size:0=",<0x10000000>; + cma-192 = <&frag0>,"size:0=",<0xC000000>; + cma-128 = <&frag0>,"size:0=",<0x8000000>; diff --git a/target/linux/bcm27xx/patches-5.4/950-0971-overlays-Add-note-to-BCM2711-overlays.patch b/target/linux/bcm27xx/patches-5.4/950-0971-overlays-Add-note-to-BCM2711-overlays.patch new file mode 100644 index 0000000000..3cf76d0934 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0971-overlays-Add-note-to-BCM2711-overlays.patch @@ -0,0 +1,150 @@ +From b2e311257e8c06f5d39004515c4adb65bb4fad3f Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 21 Sep 2020 22:09:40 +0100 +Subject: [PATCH] overlays: Add note to BCM2711 overlays + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/README | 32 +++++++++++++++---------------- + 1 file changed, 16 insertions(+), 16 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1403,7 +1403,7 @@ Load: <Deprecated> + + + Name: i2c3 +-Info: Enable the i2c3 bus ++Info: Enable the i2c3 bus. BCM2711 only. + Load: dtoverlay=i2c3,<param> + Params: pins_2_3 Use GPIOs 2 and 3 + pins_4_5 Use GPIOs 4 and 5 (default) +@@ -1412,7 +1412,7 @@ Params: pins_2_3 Use GPIO + + + Name: i2c4 +-Info: Enable the i2c4 bus ++Info: Enable the i2c4 bus. BCM2711 only. + Load: dtoverlay=i2c4,<param> + Params: pins_6_7 Use GPIOs 6 and 7 + pins_8_9 Use GPIOs 8 and 9 (default) +@@ -1421,7 +1421,7 @@ Params: pins_6_7 Use GPIO + + + Name: i2c5 +-Info: Enable the i2c5 bus ++Info: Enable the i2c5 bus. BCM2711 only. + Load: dtoverlay=i2c5,<param> + Params: pins_10_11 Use GPIOs 10 and 11 + pins_12_13 Use GPIOs 12 and 13 (default) +@@ -1430,7 +1430,7 @@ Params: pins_10_11 Use GPIO + + + Name: i2c6 +-Info: Enable the i2c6 bus ++Info: Enable the i2c6 bus. BCM2711 only. + Load: dtoverlay=i2c6,<param> + Params: pins_0_1 Use GPIOs 0 and 1 + pins_22_23 Use GPIOs 22 and 23 (default) +@@ -2582,7 +2582,7 @@ Params: cs0_pin GPIO pin + Name: spi3-1cs + Info: Enables spi3 with a single chip select (CS) line and associated spidev + dev node. The gpio pin number for the CS line and spidev device node +- creation are configurable. ++ creation are configurable. BCM2711 only. + Load: dtoverlay=spi3-1cs,<param>=<val> + Params: cs0_pin GPIO pin for CS0 (default 0 - BCM SPI3_CE0). + cs0_spidev Set to 'off' to prevent the creation of a +@@ -2593,7 +2593,7 @@ Params: cs0_pin GPIO pin + Name: spi3-2cs + Info: Enables spi3 with two chip select (CS) lines and associated spidev + dev nodes. The gpio pin numbers for the CS lines and spidev device node +- creation are configurable. ++ creation are configurable. BCM2711 only. + Load: dtoverlay=spi3-2cs,<param>=<val> + Params: cs0_pin GPIO pin for CS0 (default 0 - BCM SPI3_CE0). + cs1_pin GPIO pin for CS1 (default 24 - BCM SPI3_CE1). +@@ -2608,7 +2608,7 @@ Params: cs0_pin GPIO pin + Name: spi4-1cs + Info: Enables spi4 with a single chip select (CS) line and associated spidev + dev node. The gpio pin number for the CS line and spidev device node +- creation are configurable. ++ creation are configurable. BCM2711 only. + Load: dtoverlay=spi4-1cs,<param>=<val> + Params: cs0_pin GPIO pin for CS0 (default 4 - BCM SPI4_CE0). + cs0_spidev Set to 'off' to prevent the creation of a +@@ -2619,7 +2619,7 @@ Params: cs0_pin GPIO pin + Name: spi4-2cs + Info: Enables spi4 with two chip select (CS) lines and associated spidev + dev nodes. The gpio pin numbers for the CS lines and spidev device node +- creation are configurable. ++ creation are configurable. BCM2711 only. + Load: dtoverlay=spi4-2cs,<param>=<val> + Params: cs0_pin GPIO pin for CS0 (default 4 - BCM SPI4_CE0). + cs1_pin GPIO pin for CS1 (default 25 - BCM SPI4_CE1). +@@ -2634,7 +2634,7 @@ Params: cs0_pin GPIO pin + Name: spi5-1cs + Info: Enables spi5 with a single chip select (CS) line and associated spidev + dev node. The gpio pin numbers for the CS lines and spidev device node +- creation are configurable. ++ creation are configurable. BCM2711 only. + Load: dtoverlay=spi5-1cs,<param>=<val> + Params: cs0_pin GPIO pin for CS0 (default 12 - BCM SPI5_CE0). + cs0_spidev Set to 'off' to prevent the creation of a +@@ -2645,7 +2645,7 @@ Params: cs0_pin GPIO pin + Name: spi5-2cs + Info: Enables spi5 with two chip select (CS) lines and associated spidev + dev nodes. The gpio pin numbers for the CS lines and spidev device node +- creation are configurable. ++ creation are configurable. BCM2711 only. + Load: dtoverlay=spi5-2cs,<param>=<val> + Params: cs0_pin GPIO pin for CS0 (default 12 - BCM SPI5_CE0). + cs1_pin GPIO pin for CS1 (default 26 - BCM SPI5_CE1). +@@ -2660,7 +2660,7 @@ Params: cs0_pin GPIO pin + Name: spi6-1cs + Info: Enables spi6 with a single chip select (CS) line and associated spidev + dev node. The gpio pin number for the CS line and spidev device node +- creation are configurable. ++ creation are configurable. BCM2711 only. + Load: dtoverlay=spi6-1cs,<param>=<val> + Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI6_CE0). + cs0_spidev Set to 'off' to prevent the creation of a +@@ -2671,7 +2671,7 @@ Params: cs0_pin GPIO pin + Name: spi6-2cs + Info: Enables spi6 with two chip select (CS) lines and associated spidev + dev nodes. The gpio pin numbers for the CS lines and spidev device node +- creation are configurable. ++ creation are configurable. BCM2711 only. + Load: dtoverlay=spi6-2cs,<param>=<val> + Params: cs0_pin GPIO pin for CS0 (default 18 - BCM SPI6_CE0). + cs1_pin GPIO pin for CS1 (default 27 - BCM SPI6_CE1). +@@ -2843,25 +2843,25 @@ Params: txd1_pin GPIO pin + + + Name: uart2 +-Info: Enable uart 2 on GPIOs 0-3 ++Info: Enable uart 2 on GPIOs 0-3. BCM2711 only. + Load: dtoverlay=uart2,<param> + Params: ctsrts Enable CTS/RTS on GPIOs 2-3 (default off) + + + Name: uart3 +-Info: Enable uart 3 on GPIOs 4-7 ++Info: Enable uart 3 on GPIOs 4-7. BCM2711 only. + Load: dtoverlay=uart3,<param> + Params: ctsrts Enable CTS/RTS on GPIOs 6-7 (default off) + + + Name: uart4 +-Info: Enable uart 4 on GPIOs 8-11 ++Info: Enable uart 4 on GPIOs 8-11. BCM2711 only. + Load: dtoverlay=uart4,<param> + Params: ctsrts Enable CTS/RTS on GPIOs 10-11 (default off) + + + Name: uart5 +-Info: Enable uart 5 on GPIOs 12-15 ++Info: Enable uart 5 on GPIOs 12-15. BCM2711 only. + Load: dtoverlay=uart5,<param> + Params: ctsrts Enable CTS/RTS on GPIOs 14-15 (default off) + diff --git a/target/linux/bcm27xx/patches-5.4/950-0972-overlays-adafruit18-sainsmart18-default-bgr-to-off.patch b/target/linux/bcm27xx/patches-5.4/950-0972-overlays-adafruit18-sainsmart18-default-bgr-to-off.patch new file mode 100644 index 0000000000..70e11f46ab --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0972-overlays-adafruit18-sainsmart18-default-bgr-to-off.patch @@ -0,0 +1,53 @@ +From b9801549748233e71a5c0dd76351e02a125505b4 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 21 Sep 2020 20:45:46 +0100 +Subject: [PATCH] overlays: adafruit18,sainsmart18: default bgr to + off + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/README | 4 ++-- + arch/arm/boot/dts/overlays/adafruit18-overlay.dts | 1 - + arch/arm/boot/dts/overlays/sainsmart18-overlay.dts | 1 - + 3 files changed, 2 insertions(+), 4 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -269,7 +269,7 @@ Params: green Use the + rotate Display rotation {0,90,180,270} + speed SPI bus speed in Hz (default 4000000) + fps Display frame rate in Hz +- bgr Enable BGR mode (default on) ++ bgr Enable BGR mode (default off) + debug Debug output level {0-7} + dc_pin GPIO pin for D/C (default 24) + reset_pin GPIO pin for RESET (default 25) +@@ -2284,7 +2284,7 @@ Load: dtoverlay=sainsmart18,<param>=<v + Params: rotate Display rotation {0,90,180,270} + speed SPI bus speed in Hz (default 4000000) + fps Display frame rate in Hz +- bgr Enable BGR mode (default on) ++ bgr Enable BGR mode (default off) + debug Debug output level {0-7} + dc_pin GPIO pin for D/C (default 24) + reset_pin GPIO pin for RESET (default 25) +--- a/arch/arm/boot/dts/overlays/adafruit18-overlay.dts ++++ b/arch/arm/boot/dts/overlays/adafruit18-overlay.dts +@@ -36,7 +36,6 @@ + reset-gpios = <&gpio 25 1>; + dc-gpios = <&gpio 24 0>; + led-gpios = <&gpio 18 0>; +- bgr; + debug = <0>; + }; + }; +--- a/arch/arm/boot/dts/overlays/sainsmart18-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sainsmart18-overlay.dts +@@ -35,7 +35,6 @@ + width = <128>; + reset-gpios = <&gpio 25 1>; + dc-gpios = <&gpio 24 0>; +- bgr; + debug = <0>; + }; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0973-net-bcmgenet-Reset-RBUF-on-first-open.patch b/target/linux/bcm27xx/patches-5.4/950-0973-net-bcmgenet-Reset-RBUF-on-first-open.patch new file mode 100644 index 0000000000..b7f0ce0cad --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0973-net-bcmgenet-Reset-RBUF-on-first-open.patch @@ -0,0 +1,70 @@ +From 507c4d749a1bbc3eb5c364dda61ac6bf95026cf1 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Fri, 25 Sep 2020 15:07:23 +0100 +Subject: [PATCH] net: bcmgenet: Reset RBUF on first open + +If the RBUF logic is not reset when the kernel starts then there +may be some data left over from any network boot loader. If the +64-byte packet headers are enabled then this can be fatal. + +Extend bcmgenet_dma_disable to do perform the reset, but not when +called from bcmgenet_resume in order to preserve a wake packet. + +N.B. This different handling of resume is just based on a hunch - +why else wouldn't one reset the RBUF as well as the TBUF? If this +isn't the case then it's easy to change the patch to make the RBUF +reset unconditional. + +See: https://github.com/raspberrypi/linux/issues/3850 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/net/ethernet/broadcom/genet/bcmgenet.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +@@ -2790,7 +2790,7 @@ static void bcmgenet_set_hw_addr(struct + } + + /* Returns a reusable dma control register value */ +-static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv) ++static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv, bool flush_rx) + { + u32 reg; + u32 dma_ctrl; +@@ -2809,6 +2809,14 @@ static u32 bcmgenet_dma_disable(struct b + udelay(10); + bcmgenet_umac_writel(priv, 0, UMAC_TX_FLUSH); + ++ if (flush_rx) { ++ reg = bcmgenet_rbuf_ctrl_get(priv); ++ bcmgenet_rbuf_ctrl_set(priv, reg | BIT(0)); ++ udelay(10); ++ bcmgenet_rbuf_ctrl_set(priv, reg); ++ udelay(10); ++ } ++ + return dma_ctrl; + } + +@@ -2910,8 +2918,8 @@ static int bcmgenet_open(struct net_devi + bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT); + } + +- /* Disable RX/TX DMA and flush TX queues */ +- dma_ctrl = bcmgenet_dma_disable(priv); ++ /* Disable RX/TX DMA and flush TX and RX queues */ ++ dma_ctrl = bcmgenet_dma_disable(priv, true); + + /* Reinitialize TDMA and RDMA and SW housekeeping */ + ret = bcmgenet_init_dma(priv); +@@ -3671,7 +3679,7 @@ static int bcmgenet_resume(struct device + bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC); + + /* Disable RX/TX DMA and flush TX queues */ +- dma_ctrl = bcmgenet_dma_disable(priv); ++ dma_ctrl = bcmgenet_dma_disable(priv, false); + + /* Reinitialize TDMA and RDMA and SW housekeeping */ + ret = bcmgenet_init_dma(priv); diff --git a/target/linux/bcm27xx/patches-5.4/950-0974-ASoC-cs42xx8-Only-define-cs42xx8_of_match-once.patch b/target/linux/bcm27xx/patches-5.4/950-0974-ASoC-cs42xx8-Only-define-cs42xx8_of_match-once.patch new file mode 100644 index 0000000000..1c8e4d6699 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0974-ASoC-cs42xx8-Only-define-cs42xx8_of_match-once.patch @@ -0,0 +1,43 @@ +From e84f00c45ad064f1503d2eb03d7600e59744f0e6 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Tue, 29 Sep 2020 15:03:34 +0100 +Subject: [PATCH] ASoC: cs42xx8: Only define cs42xx8_of_match once + +cs42xx8.c exports cs42xx8_of_match, so there's no need to redefine it +in cs42xx8-i2c.c - doing so breaks linking when loadable module +support is disabled. It would be tidy to use the exported match table +in cs42xx8.c's of_match_table member, but an imported symbol can't be +used in a module's MODULE_DEVICE_TABLE declaration. Instead, rename +the duplicated declarations so as not to clash. + +See: https://github.com/raspberrypi/linux/issues/3873 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + sound/soc/codecs/cs42xx8-i2c.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/sound/soc/codecs/cs42xx8-i2c.c ++++ b/sound/soc/codecs/cs42xx8-i2c.c +@@ -45,18 +45,18 @@ static struct i2c_device_id cs42xx8_i2c_ + }; + MODULE_DEVICE_TABLE(i2c, cs42xx8_i2c_id); + +-const struct of_device_id cs42xx8_of_match[] = { ++const struct of_device_id cs42xx8_i2c_of_match[] = { + { .compatible = "cirrus,cs42448", .data = &cs42448_data, }, + { .compatible = "cirrus,cs42888", .data = &cs42888_data, }, + { /* sentinel */ } + }; +-MODULE_DEVICE_TABLE(of, cs42xx8_of_match); ++MODULE_DEVICE_TABLE(of, cs42xx8_i2c_of_match); + + static struct i2c_driver cs42xx8_i2c_driver = { + .driver = { + .name = "cs42xx8", + .pm = &cs42xx8_pm, +- .of_match_table = cs42xx8_of_match, ++ .of_match_table = cs42xx8_i2c_of_match, + }, + .probe = cs42xx8_i2c_probe, + .remove = cs42xx8_i2c_remove, diff --git a/target/linux/bcm27xx/patches-5.4/950-0975-staging-bcm2835-codec-Use-a-define-the-completion-ti.patch b/target/linux/bcm27xx/patches-5.4/950-0975-staging-bcm2835-codec-Use-a-define-the-completion-ti.patch new file mode 100644 index 0000000000..f85baf297c --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0975-staging-bcm2835-codec-Use-a-define-the-completion-ti.patch @@ -0,0 +1,35 @@ +From 7ad713e695d67b78b3cb69927d099a29593444b1 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Wed, 30 Sep 2020 12:12:32 +0100 +Subject: [PATCH] staging: bcm2835-codec: Use a define the completion + timeout + +Hiding a use of "HZ" as a timeout is a little nasty. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -89,6 +89,9 @@ static const char * const components[] = + "ril.isp", + }; + ++/* Timeout for stop_streaming to allow all buffers to return */ ++#define COMPLETE_TIMEOUT (2 * HZ) ++ + #define MIN_W 32 + #define MIN_H 32 + #define MAX_W 1920 +@@ -2366,7 +2369,8 @@ static void bcm2835_codec_stop_streaming + while (atomic_read(&port->buffers_with_vpu)) { + v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Waiting for buffers to be returned - %d outstanding\n", + __func__, atomic_read(&port->buffers_with_vpu)); +- ret = wait_for_completion_timeout(&ctx->frame_cmplt, HZ); ++ ret = wait_for_completion_timeout(&ctx->frame_cmplt, ++ COMPLETE_TIMEOUT); + if (ret <= 0) { + v4l2_err(&ctx->dev->v4l2_dev, "%s: Timeout waiting for buffers to be returned - %d outstanding\n", + __func__, diff --git a/target/linux/bcm27xx/patches-5.4/950-0976-staging-bcm2835-codec-Correct-buffer-number-change-o.patch b/target/linux/bcm27xx/patches-5.4/950-0976-staging-bcm2835-codec-Correct-buffer-number-change-o.patch new file mode 100644 index 0000000000..c0193cb2e7 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0976-staging-bcm2835-codec-Correct-buffer-number-change-o.patch @@ -0,0 +1,30 @@ +From 96f4d69496b483b8eb65dc4602d5cb96844f6647 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Wed, 30 Sep 2020 12:13:44 +0100 +Subject: [PATCH] staging: bcm2835-codec: Correct buffer number + change on start streaming + +"cac8c90 staging: vc04_service: codec: Allow start_streaming to update +the buffernum" allowed the number of buffers configured to be decreased +as well as increased, but there is no requirement for all buffers to +have been queued when start_streaming is called. + +Only allow increasing the buffernum. + +Fixes: "cac8c90 staging: vc04_service: codec: Allow start_streaming to update the buffernum" +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -2290,7 +2290,7 @@ static int bcm2835_codec_start_streaming + if (count < port->minimum_buffer.num) + count = port->minimum_buffer.num; + +- if (port->current_buffer.num != count + 1) { ++ if (port->current_buffer.num < count + 1) { + v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: ctx:%p, buffer count changed %u to %u\n", + __func__, ctx, port->current_buffer.num, count + 1); + diff --git a/target/linux/bcm27xx/patches-5.4/950-0977-USB-gadget-f_hid-avoid-crashes-and-log-spam.patch b/target/linux/bcm27xx/patches-5.4/950-0977-USB-gadget-f_hid-avoid-crashes-and-log-spam.patch new file mode 100644 index 0000000000..1fe685cd99 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0977-USB-gadget-f_hid-avoid-crashes-and-log-spam.patch @@ -0,0 +1,56 @@ +From 22198e801db7542c59098a75bdab120bcbc42652 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Wed, 30 Sep 2020 19:23:43 +0100 +Subject: [PATCH] USB: gadget: f_hid: avoid crashes and log spam + +Disconnecting and reconnecting the USB cable can lead to crashes and a +variety of kernel log spam. Try to fix or minimise both. + +See: https://github.com/raspberrypi/linux/issues/3870 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/usb/gadget/function/f_hid.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/function/f_hid.c ++++ b/drivers/usb/gadget/function/f_hid.c +@@ -344,6 +344,11 @@ static ssize_t f_hidg_write(struct file + + spin_lock_irqsave(&hidg->write_spinlock, flags); + ++ if (!hidg->req) { ++ spin_unlock_irqrestore(&hidg->write_spinlock, flags); ++ return -ESHUTDOWN; ++ } ++ + #define WRITE_COND (!hidg->write_pending) + try_again: + /* write queue */ +@@ -364,7 +369,13 @@ try_again: + count = min_t(unsigned, count, hidg->report_length); + + spin_unlock_irqrestore(&hidg->write_spinlock, flags); +- status = copy_from_user(req->buf, buffer, count); ++ if (req) { ++ status = copy_from_user(req->buf, buffer, count); ++ } else { ++ ERROR(hidg->func.config->cdev, "hidg->req is NULL\n"); ++ status = -ESHUTDOWN; ++ goto release_write_pending; ++ } + + if (status != 0) { + ERROR(hidg->func.config->cdev, +@@ -393,6 +404,11 @@ try_again: + + spin_unlock_irqrestore(&hidg->write_spinlock, flags); + ++ if (!hidg->in_ep->enabled) { ++ ERROR(hidg->func.config->cdev, "in_ep is disabled\n"); ++ status = -ESHUTDOWN; ++ goto release_write_pending; ++ } + status = usb_ep_queue(hidg->in_ep, req, GFP_ATOMIC); + if (status < 0) { + ERROR(hidg->func.config->cdev, diff --git a/target/linux/bcm27xx/patches-5.4/950-0978-Update-hy28b-overlay.dts.patch b/target/linux/bcm27xx/patches-5.4/950-0978-Update-hy28b-overlay.dts.patch new file mode 100644 index 0000000000..48efb5adc2 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0978-Update-hy28b-overlay.dts.patch @@ -0,0 +1,21 @@ +From 8c997be099769362cb201d360ad57b639e799e9e Mon Sep 17 00:00:00 2001 +From: newbloke82 <39644602+newbloke82@users.noreply.github.com> +Date: Thu, 1 Oct 2020 19:16:35 +0200 +Subject: [PATCH] Update hy28b-overlay.dts + +My hy28b TFT stopped working on upgrade to 5.4 kernel. I had a whitescreen but no obvious errors when using 'sudo vcdbg log msg' or 'dmesg'. Both /dev/fb0 and /dev/fb1 were present. Followed this article on waveshare32b that 'reset_gpios needed to be 0 0 1 instead of 0 0 0' (https://forum.armbian.com/topic/13233-any-clues-for-the-creation-of-a-dtoverlay-for-fbtft-on-54y/). I applied a similar change to this dts file and compiled a new dtbo: 'dtc -O dtb -o hy28b.dtbo hy28b-overlay.dts'. Fixed my issue - may help others? I got from the 5.4 upgrade thread that other tft users are having issues with small tfts... https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=269769&p=1706597&hilit=gpio#p1706597 +--- + arch/arm/boot/dts/overlays/hy28b-overlay.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/overlays/hy28b-overlay.dts ++++ b/arch/arm/boot/dts/overlays/hy28b-overlay.dts +@@ -61,7 +61,7 @@ + fps = <50>; + buswidth = <8>; + startbyte = <0x70>; +- reset-gpios = <&gpio 25 0>; ++ reset-gpios = <&gpio 25 1>; + led-gpios = <&gpio 18 1>; + + gamma = "04 1F 4 7 7 0 7 7 6 0\n0F 00 1 7 4 0 0 0 6 7"; diff --git a/target/linux/bcm27xx/patches-5.4/950-0979-overlays-Update-display-GPIO-declarations.patch b/target/linux/bcm27xx/patches-5.4/950-0979-overlays-Update-display-GPIO-declarations.patch new file mode 100644 index 0000000000..9b3cc5d64e --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0979-overlays-Update-display-GPIO-declarations.patch @@ -0,0 +1,170 @@ +From 0e81e4689a34e3f413ef403e0d801970d324c5b2 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Fri, 2 Oct 2020 10:06:49 +0100 +Subject: [PATCH] overlays: Update display GPIO declarations + +The 5.4 kernel changes the way a number of display drivers use GPIOs. +That change has exposed flaws/broken a number of display overlays, so +after a trickle of single-display patches this is a best-guess attempt +to fix the remainder. As none of these changes have been tested on real +displays there is a possibility that this either doesn't fix the +problem or even breaks something that was working - apologies if that +is the case. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/goodix-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/hy28a-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/hy28b-2017-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/media-center-overlay.dts | 6 +++--- + arch/arm/boot/dts/overlays/mz61581-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/piscreen-overlay.dts | 4 ++-- + arch/arm/boot/dts/overlays/piscreen2r-overlay.dts | 4 ++-- + arch/arm/boot/dts/overlays/sh1106-spi-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/ssd1306-spi-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/ssd1351-spi-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 4 ++-- + 11 files changed, 16 insertions(+), 16 deletions(-) + +--- a/arch/arm/boot/dts/overlays/goodix-overlay.dts ++++ b/arch/arm/boot/dts/overlays/goodix-overlay.dts +@@ -31,7 +31,7 @@ + interrupt-parent = <&gpio>; + interrupts = <4 2>; // high-to-low edge triggered + irq-gpios = <&gpio 4 0>; // Pin7 on GPIO header +- reset-gpios = <&gpio 17 0>; // Pin11 on GPIO header ++ reset-gpios = <&gpio 17 1>; // Pin11 on GPIO header + }; + }; + }; +--- a/arch/arm/boot/dts/overlays/hy28a-overlay.dts ++++ b/arch/arm/boot/dts/overlays/hy28a-overlay.dts +@@ -61,7 +61,7 @@ + fps = <50>; + buswidth = <8>; + startbyte = <0x70>; +- reset-gpios = <&gpio 25 0>; ++ reset-gpios = <&gpio 25 1>; + led-gpios = <&gpio 18 1>; + debug = <0>; + }; +--- a/arch/arm/boot/dts/overlays/hy28b-2017-overlay.dts ++++ b/arch/arm/boot/dts/overlays/hy28b-2017-overlay.dts +@@ -61,7 +61,7 @@ + fps = <50>; + buswidth = <8>; + startbyte = <0x70>; +- reset-gpios = <&gpio 25 0>; ++ reset-gpios = <&gpio 25 1>; + led-gpios = <&gpio 18 1>; + + init = <0x10000e5 0x78F0 +--- a/arch/arm/boot/dts/overlays/media-center-overlay.dts ++++ b/arch/arm/boot/dts/overlays/media-center-overlay.dts +@@ -53,9 +53,9 @@ + bgr; + fps = <30>; + buswidth = <8>; +- reset-gpios = <&gpio 23 0>; ++ reset-gpios = <&gpio 23 1>; + dc-gpios = <&gpio 24 0>; +- led-gpios = <&gpio 12 1>; ++ led-gpios = <&gpio 12 0>; + debug = <0>; + }; + +@@ -66,7 +66,7 @@ + spi-max-frequency = <2000000>; + interrupts = <25 2>; /* high-to-low edge triggered */ + interrupt-parent = <&gpio>; +- pendown-gpio = <&gpio 25 0>; ++ pendown-gpio = <&gpio 25 1>; + ti,x-plate-ohms = /bits/ 16 <60>; + ti,pressure-max = /bits/ 16 <255>; + }; +--- a/arch/arm/boot/dts/overlays/mz61581-overlay.dts ++++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts +@@ -65,7 +65,7 @@ + buswidth = <8>; + txbuflen = <32768>; + +- reset-gpios = <&gpio 15 0>; ++ reset-gpios = <&gpio 15 1>; + dc-gpios = <&gpio 25 0>; + led-gpios = <&gpio 18 0>; + +--- a/arch/arm/boot/dts/overlays/piscreen-overlay.dts ++++ b/arch/arm/boot/dts/overlays/piscreen-overlay.dts +@@ -59,9 +59,9 @@ + fps = <30>; + buswidth = <8>; + regwidth = <16>; +- reset-gpios = <&gpio 25 0>; ++ reset-gpios = <&gpio 25 1>; + dc-gpios = <&gpio 24 0>; +- led-gpios = <&gpio 22 1>; ++ led-gpios = <&gpio 22 0>; + debug = <0>; + + init = <0x10000b0 0x00 +--- a/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts ++++ b/arch/arm/boot/dts/overlays/piscreen2r-overlay.dts +@@ -59,9 +59,9 @@ + buswidth = <8>; + regwidth = <16>; + txbuflen = <32768>; +- reset-gpios = <&gpio 25 0>; ++ reset-gpios = <&gpio 25 1>; + dc-gpios = <&gpio 24 0>; +- led-gpios = <&gpio 22 1>; ++ led-gpios = <&gpio 22 0>; + debug = <0>; + + init = <0x10000b0 0x00 +--- a/arch/arm/boot/dts/overlays/sh1106-spi-overlay.dts ++++ b/arch/arm/boot/dts/overlays/sh1106-spi-overlay.dts +@@ -59,7 +59,7 @@ + rotate = <0>; + fps = <25>; + buswidth = <8>; +- reset-gpios = <&gpio 25 0>; ++ reset-gpios = <&gpio 25 1>; + dc-gpios = <&gpio 24 0>; + debug = <0>; + +--- a/arch/arm/boot/dts/overlays/ssd1306-spi-overlay.dts ++++ b/arch/arm/boot/dts/overlays/ssd1306-spi-overlay.dts +@@ -59,7 +59,7 @@ + rotate = <0>; + fps = <25>; + buswidth = <8>; +- reset-gpios = <&gpio 25 0>; ++ reset-gpios = <&gpio 25 1>; + dc-gpios = <&gpio 24 0>; + debug = <0>; + +--- a/arch/arm/boot/dts/overlays/ssd1351-spi-overlay.dts ++++ b/arch/arm/boot/dts/overlays/ssd1351-spi-overlay.dts +@@ -59,7 +59,7 @@ + rotate = <0>; + fps = <25>; + buswidth = <8>; +- reset-gpios = <&gpio 25 0>; ++ reset-gpios = <&gpio 25 1>; + dc-gpios = <&gpio 24 0>; + debug = <0>; + +--- a/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts ++++ b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts +@@ -85,9 +85,9 @@ + fps = <20>; + bgr; + buswidth = <8>; +- reset-gpios = <&gpio 25 0>; ++ reset-gpios = <&gpio 25 1>; + dc-gpios = <&gpio 24 0>; +- led-gpios = <&gpio 18 1>; ++ led-gpios = <&gpio 18 0>; + debug = <0>; + + init = <0x10000B0 0x80 diff --git a/target/linux/bcm27xx/patches-5.4/950-0980-SQUASH-USB-gadget-f_hid-remove-more-spam.patch b/target/linux/bcm27xx/patches-5.4/950-0980-SQUASH-USB-gadget-f_hid-remove-more-spam.patch new file mode 100644 index 0000000000..3f199cfdf1 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0980-SQUASH-USB-gadget-f_hid-remove-more-spam.patch @@ -0,0 +1,26 @@ +From 5018dc559136e2bca24973e71ed8747adf0f37f3 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 5 Oct 2020 15:41:15 +0100 +Subject: [PATCH] SQUASH: USB: gadget: f_hid: remove more spam + +Tidying up the previous patch to this file dropped the deletion of a +particularly noisy error message. Restore its removal. + +See: https://github.com/raspberrypi/linux/issues/3870 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/usb/gadget/function/f_hid.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/usb/gadget/function/f_hid.c ++++ b/drivers/usb/gadget/function/f_hid.c +@@ -411,8 +411,6 @@ try_again: + } + status = usb_ep_queue(hidg->in_ep, req, GFP_ATOMIC); + if (status < 0) { +- ERROR(hidg->func.config->cdev, +- "usb_ep_queue error on int endpoint %zd\n", status); + goto release_write_pending; + } else { + status = count; diff --git a/target/linux/bcm27xx/patches-5.4/950-0981-overlays-Add-sd3078-to-the-i2c-rtc-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0981-overlays-Add-sd3078-to-the-i2c-rtc-overlay.patch new file mode 100644 index 0000000000..5df3d2ded9 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0981-overlays-Add-sd3078-to-the-i2c-rtc-overlay.patch @@ -0,0 +1,58 @@ +From 8688b06ae53d6f60adcdcfe3d58ad7ef0ed7dba0 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 5 Oct 2020 16:10:26 +0100 +Subject: [PATCH] overlays: Add sd3078 to the i2c-rtc overlay + +Add support for the SD3078 RTC to the i2c-rtc overlay. + +See: https://github.com/raspberrypi/linux/issues/3881 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/README | 2 ++ + arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 16 ++++++++++++++++ + 2 files changed, 18 insertions(+) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1232,6 +1232,8 @@ Params: abx80x Select o + + rv3028 Select the Micro Crystal RV3028 device + ++ sd3078 Select the ZXW Shenzhen whwave SD3078 device ++ + addr Sets the address for the RTC. Note that the + device must be configured to use the specified + address. +--- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts +@@ -220,6 +220,21 @@ + }; + }; + ++ fragment@14 { ++ target = <&i2c_arm>; ++ __dormant__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ sd3078: sd3078@32 { ++ compatible = "whwave,sd3078"; ++ reg = <0x32>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ + __overrides__ { + abx80x = <0>,"+0"; + ds1307 = <0>,"+1"; +@@ -235,6 +250,7 @@ + pcf2129 = <0>,"+11"; + pcf85363 = <0>,"+12"; + rv1805 = <0>,"+13"; ++ sd3078 = <0>,"+14"; + + addr = <&abx80x>, "reg:0", + <&ds1307>, "reg:0", diff --git a/target/linux/bcm27xx/patches-5.4/950-0982-dwc_otg-initialise-sched_frame-for-periodic-QHs-that.patch b/target/linux/bcm27xx/patches-5.4/950-0982-dwc_otg-initialise-sched_frame-for-periodic-QHs-that.patch new file mode 100644 index 0000000000..2a12614196 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0982-dwc_otg-initialise-sched_frame-for-periodic-QHs-that.patch @@ -0,0 +1,33 @@ +From 2ae3859a69cecc2820f768f4d22022000e9f2e22 Mon Sep 17 00:00:00 2001 +From: Jonathan Bell <jonathan@raspberrypi.org> +Date: Wed, 7 Oct 2020 15:09:29 +0100 +Subject: [PATCH] dwc_otg: initialise sched_frame for periodic QHs + that were parked + +If a periodic QH has no remaining QTDs, then it is removed from all +periodic schedules. When re-adding, initialise the sched_frame and +start_split_frame from the current value of the frame counter. + +See https://bugs.launchpad.net/raspbian/+bug/1819560 +and + https://github.com/raspberrypi/linux/issues/3883 + +Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com> +--- + drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c +@@ -689,7 +689,11 @@ int dwc_otg_hcd_qh_add(dwc_otg_hcd_t * h + &qh->qh_list_entry); + //hcd->fiq_state->kick_np_queues = 1; + } else { ++ /* If the QH wasn't in a schedule, then sched_frame is stale. */ ++ qh->sched_frame = dwc_frame_num_inc(dwc_otg_hcd_get_frame_number(hcd), ++ SCHEDULE_SLOP); + status = schedule_periodic(hcd, qh); ++ qh->start_split_frame = qh->sched_frame; + if ( !hcd->periodic_qh_count ) { + intr_mask.b.sofintr = 1; + if (fiq_enable) { diff --git a/target/linux/bcm27xx/patches-5.4/950-0983-staging-bcm2835-camera-Replace-deprecated-V4L2_PIX_F.patch b/target/linux/bcm27xx/patches-5.4/950-0983-staging-bcm2835-camera-Replace-deprecated-V4L2_PIX_F.patch new file mode 100644 index 0000000000..f86566ee63 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0983-staging-bcm2835-camera-Replace-deprecated-V4L2_PIX_F.patch @@ -0,0 +1,30 @@ +From c46ee3d6fc36bcfe42ca860f8da85775f0b9cc6a Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 8 Oct 2020 15:35:14 +0100 +Subject: [PATCH] staging: bcm2835-camera: Replace deprecated + V4L2_PIX_FMT_BGR32 + +V4L2_PIX_FMT_BGR32 is deprecated as it is ambiguous over where +the alpha byte is. Cheese/GStreamer appear to get it wrong for +one, and qv4l2 gets red and blue swapped. + +Swap to the newer V4L2_PIX_FMT_BGRX32 format. + +https://www.raspberrypi.org/forums/viewtopic.php?f=38&t=267736&p=1738912 + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c ++++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +@@ -175,7 +175,7 @@ static struct mmal_fmt formats[] = { + .ybbp = 1, + .remove_padding = 1, + }, { +- .fourcc = V4L2_PIX_FMT_BGR32, ++ .fourcc = V4L2_PIX_FMT_BGRX32, + .mmal = MMAL_ENCODING_BGRA, + .depth = 32, + .mmal_component = COMP_CAMERA, diff --git a/target/linux/bcm27xx/patches-5.4/950-0984-staging-bcm2835-codec-Replace-deprecated-V4L2_PIX_FM.patch b/target/linux/bcm27xx/patches-5.4/950-0984-staging-bcm2835-codec-Replace-deprecated-V4L2_PIX_FM.patch new file mode 100644 index 0000000000..2e6d04bcbb --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0984-staging-bcm2835-codec-Replace-deprecated-V4L2_PIX_FM.patch @@ -0,0 +1,27 @@ +From ed4adfd60c1495b864720e1f79b0b2a443447e38 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 8 Oct 2020 16:06:59 +0100 +Subject: [PATCH] staging: bcm2835-codec: Replace deprecated + V4L2_PIX_FMT_BGR32 + +V4L2_PIX_FMT_BGR32 is deprecated as it is ambiguous over where +the alpha byte is. + +Swap to the newer V4L2_PIX_FMT_BGRX32 format. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c ++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +@@ -207,7 +207,7 @@ static const struct bcm2835_codec_fmt su + .mmal_fmt = MMAL_ENCODING_BGR24, + .size_multiplier_x2 = 2, + }, { +- .fourcc = V4L2_PIX_FMT_BGR32, ++ .fourcc = V4L2_PIX_FMT_BGRX32, + .depth = 32, + .bytesperline_align = 32, + .flags = 0, diff --git a/target/linux/bcm27xx/patches-5.4/950-0985-ARM-bcm2711-rpi.dts-Unlock-DMA-channels-9-10.patch b/target/linux/bcm27xx/patches-5.4/950-0985-ARM-bcm2711-rpi.dts-Unlock-DMA-channels-9-10.patch new file mode 100644 index 0000000000..8895a020b2 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0985-ARM-bcm2711-rpi.dts-Unlock-DMA-channels-9-10.patch @@ -0,0 +1,33 @@ +From b10a49ab016ed9ac8f231845fb3e83fbf3505652 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 12 Oct 2020 14:36:35 +0100 +Subject: [PATCH] ARM: bcm2711-rpi.dts: Unlock DMA channels 9 & 10 + +The downstream-specific override of the 32-bit DMA mask needlessly +disables channels 9 and 10 - the VPU doesn't use them. This override +is redundant, so delete it. + +See: https://github.com/raspberrypi/linux/issues/3896 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2711-rpi.dtsi | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +--- a/arch/arm/boot/dts/bcm2711-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi +@@ -246,13 +246,8 @@ + }; + }; + +-&dma { +- /* The VPU firmware uses DMA channel 11 for VCHIQ */ +- brcm,dma-channel-mask = <0x1f5>; +-}; +- + &dma40 { +- /* The VPU firmware DMA channel 11 for VCHIQ */ ++ /* The VPU firmware uses DMA channel 11 for VCHIQ */ + brcm,dma-channel-mask = <0x7000>; + }; + diff --git a/target/linux/bcm27xx/patches-5.4/950-0986-gpio-Add-gpio-fsm-driver.patch b/target/linux/bcm27xx/patches-5.4/950-0986-gpio-Add-gpio-fsm-driver.patch new file mode 100644 index 0000000000..7076026e7c --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0986-gpio-Add-gpio-fsm-driver.patch @@ -0,0 +1,1182 @@ +From c31626a9e173f2b2e0adc4cb8bfbb86a958bafcd Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Wed, 30 Sep 2020 12:00:54 +0100 +Subject: [PATCH] gpio: Add gpio-fsm driver + +The gpio-fsm driver implements simple state machines that allow GPIOs +to be controlled in response to inputs from other GPIOs - real and +soft/virtual - and time delays. It can: ++ create dummy GPIOs for drivers that demand them, ++ drive multiple GPIOs from a single input, with optional delays, ++ add a debounce circuit to an input, ++ drive pattern sequences onto LEDs +etc. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/gpio/Kconfig | 9 + + drivers/gpio/Makefile | 1 + + drivers/gpio/gpio-fsm.c | 1103 +++++++++++++++++++++++++++ + include/dt-bindings/gpio/gpio-fsm.h | 21 + + 4 files changed, 1134 insertions(+) + create mode 100644 drivers/gpio/gpio-fsm.c + create mode 100644 include/dt-bindings/gpio/gpio-fsm.h + +--- a/drivers/gpio/Kconfig ++++ b/drivers/gpio/Kconfig +@@ -1071,6 +1071,15 @@ config HTC_EGPIO + several HTC phones. It provides basic support for input + pins, output pins, and irqs. + ++config GPIO_FSM ++ tristate "GPIO FSM support" ++ help ++ The GPIO FSM driver allows the creation of state machines for ++ manipulating GPIOs (both real and virtual), with state transitions ++ triggered by GPIO edges or delays. ++ ++ If unsure, say N. ++ + config GPIO_JANZ_TTL + tristate "Janz VMOD-TTL Digital IO Module" + depends on MFD_JANZ_CMODIO +--- a/drivers/gpio/Makefile ++++ b/drivers/gpio/Makefile +@@ -55,6 +55,7 @@ obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93x + obj-$(CONFIG_GPIO_EXAR) += gpio-exar.o + obj-$(CONFIG_GPIO_F7188X) += gpio-f7188x.o + obj-$(CONFIG_GPIO_FTGPIO010) += gpio-ftgpio010.o ++obj-$(CONFIG_GPIO_FSM) += gpio-fsm.o + obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o + obj-$(CONFIG_GPIO_GPIO_MM) += gpio-gpio-mm.o + obj-$(CONFIG_GPIO_GRGPIO) += gpio-grgpio.o +--- /dev/null ++++ b/drivers/gpio/gpio-fsm.c +@@ -0,0 +1,1103 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * GPIO FSM driver ++ * ++ * This driver implements simple state machines that allow real GPIOs to be ++ * controlled in response to inputs from other GPIOs - real and soft/virtual - ++ * and time delays. It can: ++ * + create dummy GPIOs for drivers that demand them ++ * + drive multiple GPIOs from a single input, with optional delays ++ * + add a debounce circuit to an input ++ * + drive pattern sequences onto LEDs ++ * etc. ++ * ++ * Copyright (C) 2020 Raspberry Pi (Trading) Ltd. ++ */ ++ ++#include <linux/err.h> ++#include <linux/gpio.h> ++#include <linux/gpio/driver.h> ++#include <linux/interrupt.h> ++#include <linux/module.h> ++#include <linux/platform_device.h> ++ ++#include <dt-bindings/gpio/gpio-fsm.h> ++ ++#define MODULE_NAME "gpio-fsm" ++ ++#define GF_IO_TYPE(x) ((u32)(x) & 0xffff) ++#define GF_IO_INDEX(x) ((u32)(x) >> 16) ++ ++enum { ++ SIGNAL_GPIO, ++ SIGNAL_SOFT ++}; ++ ++enum { ++ INPUT_GPIO, ++ INPUT_SOFT ++}; ++ ++enum { ++ SYM_UNDEFINED, ++ SYM_NAME, ++ SYM_SET, ++ SYM_START, ++ SYM_SHUTDOWN, ++ ++ SYM_MAX ++}; ++ ++struct soft_gpio { ++ int dir; ++ int value; ++}; ++ ++struct input_gpio_state { ++ struct gpio_fsm *gf; ++ struct gpio_desc *desc; ++ struct fsm_state *target; ++ int index; ++ int value; ++ int irq; ++ bool enabled; ++ bool active_low; ++}; ++ ++struct gpio_event { ++ int index; ++ int value; ++ struct fsm_state *target; ++}; ++ ++struct symtab_entry { ++ const char *name; ++ void *value; ++ struct symtab_entry *next; ++}; ++ ++struct output_signal { ++ u8 type; ++ u8 value; ++ u16 index; ++}; ++ ++struct fsm_state { ++ const char *name; ++ struct output_signal *signals; ++ struct gpio_event *gpio_events; ++ struct gpio_event *soft_events; ++ struct fsm_state *delay_target; ++ struct fsm_state *shutdown_target; ++ unsigned int num_signals; ++ unsigned int num_gpio_events; ++ unsigned int num_soft_events; ++ unsigned int delay_ms; ++ unsigned int shutdown_ms; ++}; ++ ++struct gpio_fsm { ++ struct gpio_chip gc; ++ struct device *dev; ++ spinlock_t spinlock; ++ struct work_struct work; ++ struct timer_list timer; ++ wait_queue_head_t shutdown_event; ++ struct fsm_state *states; ++ struct input_gpio_state *input_gpio_states; ++ struct gpio_descs *input_gpios; ++ struct gpio_descs *output_gpios; ++ struct soft_gpio *soft_gpios; ++ struct fsm_state *start_state; ++ struct fsm_state *shutdown_state; ++ unsigned int num_states; ++ unsigned int num_output_gpios; ++ unsigned int num_input_gpios; ++ unsigned int num_soft_gpios; ++ unsigned int shutdown_timeout_ms; ++ unsigned int shutdown_jiffies; ++ ++ struct fsm_state *current_state; ++ struct fsm_state *next_state; ++ struct fsm_state *delay_target_state; ++ int delay_ms; ++ unsigned int debug; ++ bool shutting_down; ++ struct symtab_entry *symtab; ++}; ++ ++static struct symtab_entry *do_add_symbol(struct symtab_entry **symtab, ++ const char *name, void *value) ++{ ++ struct symtab_entry **p = symtab; ++ ++ while (*p && strcmp((*p)->name, name)) ++ p = &(*p)->next; ++ ++ if (*p) { ++ /* This is an existing symbol */ ++ if ((*p)->value) { ++ /* Already defined */ ++ if (value) { ++ if ((uintptr_t)value < SYM_MAX) ++ return ERR_PTR(-EINVAL); ++ else ++ return ERR_PTR(-EEXIST); ++ } ++ } else { ++ /* Undefined */ ++ (*p)->value = value; ++ } ++ } else { ++ /* This is a new symbol */ ++ *p = kmalloc(sizeof(struct symtab_entry), GFP_KERNEL); ++ if (*p) { ++ (*p)->name = name; ++ (*p)->value = value; ++ (*p)->next = NULL; ++ } ++ } ++ return *p; ++} ++ ++static int add_symbol(struct symtab_entry **symtab, ++ const char *name, void *value) ++{ ++ struct symtab_entry *sym = do_add_symbol(symtab, name, value); ++ ++ return PTR_ERR_OR_ZERO(sym); ++} ++ ++static struct symtab_entry *get_symbol(struct symtab_entry **symtab, ++ const char *name) ++{ ++ struct symtab_entry *sym = do_add_symbol(symtab, name, NULL); ++ ++ if (IS_ERR(sym)) ++ return NULL; ++ return sym; ++} ++ ++static void free_symbols(struct symtab_entry **symtab) ++{ ++ struct symtab_entry *sym = *symtab; ++ void *p; ++ ++ *symtab = NULL; ++ while (sym) { ++ p = sym; ++ sym = sym->next; ++ kfree(p); ++ } ++} ++ ++static int gpio_fsm_get_direction(struct gpio_chip *gc, unsigned int off) ++{ ++ struct gpio_fsm *gf = gpiochip_get_data(gc); ++ struct soft_gpio *sg; ++ ++ if (off >= gf->num_soft_gpios) ++ return -EINVAL; ++ sg = &gf->soft_gpios[off]; ++ ++ return sg->dir; ++} ++ ++static int gpio_fsm_get(struct gpio_chip *gc, unsigned int off) ++{ ++ struct gpio_fsm *gf = gpiochip_get_data(gc); ++ struct soft_gpio *sg; ++ ++ if (off >= gf->num_soft_gpios) ++ return -EINVAL; ++ sg = &gf->soft_gpios[off]; ++ ++ return sg->value; ++} ++ ++static void gpio_fsm_go_to_state(struct gpio_fsm *gf, ++ struct fsm_state *new_state) ++{ ++ struct input_gpio_state *inp_state; ++ struct gpio_event *gp_ev; ++ struct fsm_state *state; ++ int i; ++ ++ dev_dbg(gf->dev, "go_to_state(%s)\n", ++ new_state ? new_state->name : "<unset>"); ++ ++ spin_lock(&gf->spinlock); ++ ++ if (gf->next_state) { ++ /* Something else has already requested a transition */ ++ spin_unlock(&gf->spinlock); ++ return; ++ } ++ ++ gf->next_state = new_state; ++ state = gf->current_state; ++ gf->delay_target_state = NULL; ++ ++ if (state) { ++ /* Disarm any GPIO IRQs */ ++ for (i = 0; i < state->num_gpio_events; i++) { ++ gp_ev = &state->gpio_events[i]; ++ inp_state = &gf->input_gpio_states[gp_ev->index]; ++ inp_state->target = NULL; ++ } ++ } ++ ++ spin_unlock(&gf->spinlock); ++ ++ if (new_state) ++ schedule_work(&gf->work); ++} ++ ++static void gpio_fsm_set_soft(struct gpio_fsm *gf, ++ unsigned int off, int val) ++{ ++ struct soft_gpio *sg = &gf->soft_gpios[off]; ++ struct gpio_event *gp_ev; ++ struct fsm_state *state; ++ int i; ++ ++ dev_dbg(gf->dev, "set(%d,%d)\n", off, val); ++ state = gf->current_state; ++ sg->value = val; ++ for (i = 0; i < state->num_soft_events; i++) { ++ gp_ev = &state->soft_events[i]; ++ if (gp_ev->index == off && gp_ev->value == val) { ++ if (gf->debug) ++ dev_info(gf->dev, ++ "GF_SOFT %d->%d -> %s\n", gp_ev->index, ++ gp_ev->value, gp_ev->target->name); ++ gpio_fsm_go_to_state(gf, gp_ev->target); ++ break; ++ } ++ } ++} ++ ++static int gpio_fsm_direction_input(struct gpio_chip *gc, unsigned int off) ++{ ++ struct gpio_fsm *gf = gpiochip_get_data(gc); ++ struct soft_gpio *sg; ++ ++ if (off >= gf->num_soft_gpios) ++ return -EINVAL; ++ sg = &gf->soft_gpios[off]; ++ sg->dir = GPIOF_DIR_IN; ++ ++ return 0; ++} ++ ++static int gpio_fsm_direction_output(struct gpio_chip *gc, unsigned int off, ++ int value) ++{ ++ struct gpio_fsm *gf = gpiochip_get_data(gc); ++ struct soft_gpio *sg; ++ ++ if (off >= gf->num_soft_gpios) ++ return -EINVAL; ++ sg = &gf->soft_gpios[off]; ++ sg->dir = GPIOF_DIR_OUT; ++ gpio_fsm_set_soft(gf, off, value); ++ ++ return 0; ++} ++ ++static void gpio_fsm_set(struct gpio_chip *gc, unsigned int off, int val) ++{ ++ struct gpio_fsm *gf; ++ ++ gf = gpiochip_get_data(gc); ++ if (off < gf->num_soft_gpios) ++ gpio_fsm_set_soft(gf, off, val); ++} ++ ++static void gpio_fsm_enter_state(struct gpio_fsm *gf, ++ struct fsm_state *state) ++{ ++ struct input_gpio_state *inp_state; ++ struct output_signal *signal; ++ struct gpio_event *event; ++ struct gpio_desc *gpiod; ++ struct soft_gpio *soft; ++ int value; ++ int i; ++ ++ dev_dbg(gf->dev, "enter_state(%s)\n", state->name); ++ ++ gf->current_state = state; ++ ++ // 1. Apply any listed signals ++ for (i = 0; i < state->num_signals; i++) { ++ signal = &state->signals[i]; ++ ++ if (gf->debug) ++ dev_info(gf->dev, " set %s %d->%d\n", ++ (signal->type == SIGNAL_GPIO) ? "GF_OUT" : ++ "GF_SOFT", ++ signal->index, signal->value); ++ switch (signal->type) { ++ case SIGNAL_GPIO: ++ gpiod = gf->output_gpios->desc[signal->index]; ++ gpiod_set_value_cansleep(gpiod, signal->value); ++ break; ++ case SIGNAL_SOFT: ++ soft = &gf->soft_gpios[signal->index]; ++ gpio_fsm_set_soft(gf, signal->index, signal->value); ++ break; ++ } ++ } ++ ++ // 2. Exit if successfully reached shutdown state ++ if (gf->shutting_down && state == state->shutdown_target) { ++ wake_up(&gf->shutdown_event); ++ return; ++ } ++ ++ // 3. Schedule a timer callback if shutting down ++ if (state->shutdown_target) { ++ // Remember the absolute shutdown time in case remove is called ++ // at a later time. ++ gf->shutdown_jiffies = ++ jiffies + msecs_to_jiffies(state->shutdown_ms); ++ ++ if (gf->shutting_down) { ++ gf->delay_target_state = state->shutdown_target; ++ gf->delay_ms = state->shutdown_ms; ++ mod_timer(&gf->timer, gf->shutdown_jiffies); ++ } ++ } ++ ++ // During shutdown, skip everything else ++ if (gf->shutting_down) ++ return; ++ ++ // Otherwise record what the shutdown time would be ++ gf->shutdown_jiffies = jiffies + msecs_to_jiffies(state->shutdown_ms); ++ ++ // 4. Check soft inputs for transitions to take ++ for (i = 0; i < state->num_soft_events; i++) { ++ event = &state->soft_events[i]; ++ if (gf->soft_gpios[event->index].value == event->value) { ++ if (gf->debug) ++ dev_info(gf->dev, ++ "GF_SOFT %d=%d -> %s\n", event->index, ++ event->value, event->target->name); ++ gpio_fsm_go_to_state(gf, event->target); ++ return; ++ } ++ } ++ ++ // 5. Check GPIOs for transitions to take, enabling the IRQs ++ for (i = 0; i < state->num_gpio_events; i++) { ++ event = &state->gpio_events[i]; ++ inp_state = &gf->input_gpio_states[event->index]; ++ inp_state->target = event->target; ++ inp_state->value = event->value; ++ inp_state->enabled = true; ++ ++ value = gpiod_get_value(gf->input_gpios->desc[event->index]); ++ ++ // Clear stale event state ++ disable_irq(inp_state->irq); ++ ++ irq_set_irq_type(inp_state->irq, ++ (inp_state->value ^ inp_state->active_low) ? ++ IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING); ++ enable_irq(inp_state->irq); ++ ++ if (value == event->value && inp_state->target) { ++ if (gf->debug) ++ dev_info(gf->dev, ++ "GF_IN %d=%d -> %s\n", event->index, ++ event->value, event->target->name); ++ gpio_fsm_go_to_state(gf, event->target); ++ return; ++ } ++ } ++ ++ // 6. Schedule a timer callback if delay_target ++ if (state->delay_target) { ++ gf->delay_target_state = state->delay_target; ++ gf->delay_ms = state->delay_ms; ++ mod_timer(&gf->timer, ++ jiffies + msecs_to_jiffies(state->delay_ms)); ++ } ++} ++ ++static void gpio_fsm_work(struct work_struct *work) ++{ ++ struct input_gpio_state *inp_state; ++ struct fsm_state *new_state; ++ struct fsm_state *state; ++ struct gpio_event *gp_ev; ++ struct gpio_fsm *gf; ++ int i; ++ ++ gf = container_of(work, struct gpio_fsm, work); ++ spin_lock(&gf->spinlock); ++ state = gf->current_state; ++ new_state = gf->next_state; ++ if (!new_state) ++ new_state = gf->delay_target_state; ++ gf->next_state = NULL; ++ gf->delay_target_state = NULL; ++ spin_unlock(&gf->spinlock); ++ ++ if (state) { ++ /* Disable any enabled GPIO IRQs */ ++ for (i = 0; i < state->num_gpio_events; i++) { ++ gp_ev = &state->gpio_events[i]; ++ inp_state = &gf->input_gpio_states[gp_ev->index]; ++ if (inp_state->enabled) { ++ inp_state->enabled = false; ++ irq_set_irq_type(inp_state->irq, ++ IRQF_TRIGGER_NONE); ++ } ++ } ++ } ++ ++ if (new_state) ++ gpio_fsm_enter_state(gf, new_state); ++} ++ ++static irqreturn_t gpio_fsm_gpio_irq_handler(int irq, void *dev_id) ++{ ++ struct input_gpio_state *inp_state = dev_id; ++ struct gpio_fsm *gf = inp_state->gf; ++ struct fsm_state *target; ++ ++ target = inp_state->target; ++ if (!target) ++ return IRQ_NONE; ++ ++ /* If the IRQ has fired then the desired state _must_ have occurred */ ++ inp_state->enabled = false; ++ irq_set_irq_type(inp_state->irq, IRQF_TRIGGER_NONE); ++ if (gf->debug) ++ dev_info(gf->dev, "GF_IN %d->%d -> %s\n", ++ inp_state->index, inp_state->value, target->name); ++ gpio_fsm_go_to_state(gf, target); ++ return IRQ_HANDLED; ++} ++ ++static void gpio_fsm_timer(struct timer_list *timer) ++{ ++ struct gpio_fsm *gf = container_of(timer, struct gpio_fsm, timer); ++ struct fsm_state *target; ++ ++ target = gf->delay_target_state; ++ if (!target) ++ return; ++ ++ if (gf->debug) ++ dev_info(gf->dev, "GF_DELAY %d -> %s\n", gf->delay_ms, ++ target->name); ++ ++ gpio_fsm_go_to_state(gf, target); ++} ++ ++int gpio_fsm_parse_signals(struct gpio_fsm *gf, struct fsm_state *state, ++ struct property *prop) ++{ ++ const __be32 *cells = prop->value; ++ struct output_signal *signal; ++ u32 io; ++ u32 type; ++ u32 index; ++ u32 value; ++ int ret = 0; ++ int i; ++ ++ if (prop->length % 8) { ++ dev_err(gf->dev, "malformed set in state %s\n", ++ state->name); ++ return -EINVAL; ++ } ++ ++ state->num_signals = prop->length/8; ++ state->signals = devm_kcalloc(gf->dev, state->num_signals, ++ sizeof(struct output_signal), ++ GFP_KERNEL); ++ for (i = 0; i < state->num_signals; i++) { ++ signal = &state->signals[i]; ++ io = be32_to_cpu(cells[0]); ++ type = GF_IO_TYPE(io); ++ index = GF_IO_INDEX(io); ++ value = be32_to_cpu(cells[1]); ++ ++ if (type != GF_OUT && type != GF_SOFT) { ++ dev_err(gf->dev, ++ "invalid set type %d in state %s\n", ++ type, state->name); ++ ret = -EINVAL; ++ break; ++ } ++ if (type == GF_OUT && index >= gf->num_output_gpios) { ++ dev_err(gf->dev, ++ "invalid GF_OUT number %d in state %s\n", ++ index, state->name); ++ ret = -EINVAL; ++ break; ++ } ++ if (type == GF_SOFT && index >= gf->num_soft_gpios) { ++ dev_err(gf->dev, ++ "invalid GF_SOFT number %d in state %s\n", ++ index, state->name); ++ ret = -EINVAL; ++ break; ++ } ++ if (value != 0 && value != 1) { ++ dev_err(gf->dev, ++ "invalid set value %d in state %s\n", ++ value, state->name); ++ ret = -EINVAL; ++ break; ++ } ++ signal->type = (type == GF_OUT) ? SIGNAL_GPIO : SIGNAL_SOFT; ++ signal->index = index; ++ signal->value = value; ++ cells += 2; ++ } ++ ++ return ret; ++} ++ ++struct gpio_event *new_event(struct gpio_event **events, int *num_events) ++{ ++ int num = ++(*num_events); ++ *events = krealloc(*events, num * sizeof(struct gpio_event), ++ GFP_KERNEL); ++ return *events ? *events + (num - 1) : NULL; ++} ++ ++int gpio_fsm_parse_events(struct gpio_fsm *gf, struct fsm_state *state, ++ struct property *prop) ++{ ++ const __be32 *cells = prop->value; ++ struct symtab_entry *sym; ++ int num_cells; ++ int ret = 0; ++ int i; ++ ++ if (prop->length % 8) { ++ dev_err(gf->dev, ++ "malformed transitions from state %s to state %s\n", ++ state->name, prop->name); ++ return -EINVAL; ++ } ++ ++ sym = get_symbol(&gf->symtab, prop->name); ++ num_cells = prop->length / 4; ++ i = 0; ++ while (i < num_cells) { ++ struct gpio_event *gp_ev; ++ u32 event, param; ++ u32 index; ++ ++ event = be32_to_cpu(cells[i++]); ++ param = be32_to_cpu(cells[i++]); ++ index = GF_IO_INDEX(event); ++ ++ switch (GF_IO_TYPE(event)) { ++ case GF_IN: ++ if (index >= gf->num_input_gpios) { ++ dev_err(gf->dev, ++ "invalid GF_IN %d in transitions from state %s to state %s\n", ++ index, state->name, prop->name); ++ return -EINVAL; ++ } ++ if (param > 1) { ++ dev_err(gf->dev, ++ "invalid GF_IN value %d in transitions from state %s to state %s\n", ++ param, state->name, prop->name); ++ return -EINVAL; ++ } ++ gp_ev = new_event(&state->gpio_events, ++ &state->num_gpio_events); ++ if (!gp_ev) ++ return -ENOMEM; ++ gp_ev->index = index; ++ gp_ev->value = param; ++ gp_ev->target = (struct fsm_state *)sym; ++ break; ++ ++ case GF_SOFT: ++ if (index >= gf->num_soft_gpios) { ++ dev_err(gf->dev, ++ "invalid GF_SOFT %d in transitions from state %s to state %s\n", ++ index, state->name, prop->name); ++ return -EINVAL; ++ } ++ if (param > 1) { ++ dev_err(gf->dev, ++ "invalid GF_SOFT value %d in transitions from state %s to state %s\n", ++ param, state->name, prop->name); ++ return -EINVAL; ++ } ++ gp_ev = new_event(&state->soft_events, ++ &state->num_soft_events); ++ if (!gp_ev) ++ return -ENOMEM; ++ gp_ev->index = index; ++ gp_ev->value = param; ++ gp_ev->target = (struct fsm_state *)sym; ++ break; ++ ++ case GF_DELAY: ++ if (state->delay_target) { ++ dev_err(gf->dev, ++ "state %s has multiple GF_DELAYs\n", ++ state->name); ++ return -EINVAL; ++ } ++ state->delay_target = (struct fsm_state *)sym; ++ state->delay_ms = param; ++ break; ++ ++ case GF_SHUTDOWN: ++ if (state->shutdown_target == state) { ++ dev_err(gf->dev, ++ "shutdown state %s has GF_SHUTDOWN\n", ++ state->name); ++ return -EINVAL; ++ } else if (state->shutdown_target) { ++ dev_err(gf->dev, ++ "state %s has multiple GF_SHUTDOWNs\n", ++ state->name); ++ return -EINVAL; ++ } ++ state->shutdown_target = ++ (struct fsm_state *)sym; ++ state->shutdown_ms = param; ++ break; ++ ++ default: ++ dev_err(gf->dev, ++ "invalid event %08x in transitions from state %s to state %s\n", ++ event, state->name, prop->name); ++ return -EINVAL; ++ } ++ } ++ if (i != num_cells) { ++ dev_err(gf->dev, ++ "malformed transitions from state %s to state %s\n", ++ state->name, prop->name); ++ return -EINVAL; ++ } ++ ++ return ret; ++} ++ ++int gpio_fsm_parse_state(struct gpio_fsm *gf, ++ struct fsm_state *state, ++ struct device_node *np) ++{ ++ struct symtab_entry *sym; ++ struct property *prop; ++ int ret; ++ ++ state->name = np->name; ++ ret = add_symbol(&gf->symtab, np->name, state); ++ if (ret) { ++ switch (ret) { ++ case -EINVAL: ++ dev_err(gf->dev, "'%s' is not a valid state name\n", ++ np->name); ++ break; ++ case -EEXIST: ++ dev_err(gf->dev, "state %s already defined\n", ++ np->name); ++ break; ++ default: ++ dev_err(gf->dev, "error %d adding state %s symbol\n", ++ ret, np->name); ++ break; ++ } ++ return ret; ++ } ++ ++ for_each_property_of_node(np, prop) { ++ sym = get_symbol(&gf->symtab, prop->name); ++ if (!sym) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ switch ((uintptr_t)sym->value) { ++ case SYM_SET: ++ ret = gpio_fsm_parse_signals(gf, state, prop); ++ break; ++ case SYM_START: ++ if (gf->start_state) { ++ dev_err(gf->dev, "multiple start states\n"); ++ ret = -EINVAL; ++ } else { ++ gf->start_state = state; ++ } ++ break; ++ case SYM_SHUTDOWN: ++ state->shutdown_target = state; ++ gf->shutdown_state = state; ++ break; ++ case SYM_NAME: ++ /* Ignore */ ++ break; ++ default: ++ /* A set of transition events to this state */ ++ ret = gpio_fsm_parse_events(gf, state, prop); ++ break; ++ } ++ } ++ ++ return ret; ++} ++ ++static void dump_all(struct gpio_fsm *gf) ++{ ++ int i, j; ++ ++ dev_info(gf->dev, "Input GPIOs:\n"); ++ for (i = 0; i < gf->num_input_gpios; i++) ++ dev_info(gf->dev, " %d: %p\n", i, ++ gf->input_gpios->desc[i]); ++ ++ dev_info(gf->dev, "Output GPIOs:\n"); ++ for (i = 0; i < gf->num_output_gpios; i++) ++ dev_info(gf->dev, " %d: %p\n", i, ++ gf->output_gpios->desc[i]); ++ ++ dev_info(gf->dev, "Soft GPIOs:\n"); ++ for (i = 0; i < gf->num_soft_gpios; i++) ++ dev_info(gf->dev, " %d: %s %d\n", i, ++ (gf->soft_gpios[i].dir == GPIOF_DIR_IN) ? "IN" : "OUT", ++ gf->soft_gpios[i].value); ++ ++ dev_info(gf->dev, "Start state: %s\n", ++ gf->start_state ? gf->start_state->name : "-"); ++ ++ dev_info(gf->dev, "Shutdown timeout: %d ms\n", ++ gf->shutdown_timeout_ms); ++ ++ for (i = 0; i < gf->num_states; i++) { ++ struct fsm_state *state = &gf->states[i]; ++ ++ dev_info(gf->dev, "State %s:\n", state->name); ++ ++ if (state->shutdown_target == state) ++ dev_info(gf->dev, " Shutdown state\n"); ++ ++ dev_info(gf->dev, " Signals:\n"); ++ for (j = 0; j < state->num_signals; j++) { ++ struct output_signal *signal = &state->signals[j]; ++ ++ dev_info(gf->dev, " %d: %s %d=%d\n", j, ++ (signal->type == SIGNAL_GPIO) ? "GPIO" : ++ "SOFT", ++ signal->index, signal->value); ++ } ++ ++ dev_info(gf->dev, " GPIO events:\n"); ++ for (j = 0; j < state->num_gpio_events; j++) { ++ struct gpio_event *event = &state->gpio_events[j]; ++ ++ dev_info(gf->dev, " %d: %d=%d -> %s\n", j, ++ event->index, event->value, ++ event->target->name); ++ } ++ ++ dev_info(gf->dev, " Soft events:\n"); ++ for (j = 0; j < state->num_soft_events; j++) { ++ struct gpio_event *event = &state->soft_events[j]; ++ ++ dev_info(gf->dev, " %d: %d=%d -> %s\n", j, ++ event->index, event->value, ++ event->target->name); ++ } ++ ++ if (state->delay_target) ++ dev_info(gf->dev, " Delay: %d ms -> %s\n", ++ state->delay_ms, state->delay_target->name); ++ ++ if (state->shutdown_target && state->shutdown_target != state) ++ dev_info(gf->dev, " Shutdown: %d ms -> %s\n", ++ state->shutdown_ms, ++ state->shutdown_target->name); ++ } ++ dev_info(gf->dev, "\n"); ++} ++ ++static int resolve_sym_to_state(struct gpio_fsm *gf, struct fsm_state **pstate) ++{ ++ struct symtab_entry *sym = (struct symtab_entry *)*pstate; ++ ++ if (!sym) ++ return -ENOMEM; ++ ++ *pstate = sym->value; ++ ++ if (!*pstate) { ++ dev_err(gf->dev, "state %s not defined\n", ++ sym->name); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int gpio_fsm_probe(struct platform_device *pdev) ++{ ++ struct input_gpio_state *inp_state; ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ struct device_node *cp; ++ struct gpio_fsm *gf; ++ u32 debug = 0; ++ int num_states; ++ u32 num_soft_gpios; ++ int ret; ++ int i; ++ static const char *const reserved_symbols[] = { ++ [SYM_NAME] = "name", ++ [SYM_SET] = "set", ++ [SYM_START] = "start_state", ++ [SYM_SHUTDOWN] = "shutdown_state", ++ }; ++ ++ if (of_property_read_u32(np, "num-soft-gpios", &num_soft_gpios)) { ++ dev_err(dev, "missing 'num-soft-gpios' property\n"); ++ return -EINVAL; ++ } ++ ++ of_property_read_u32(np, "debug", &debug); ++ ++ gf = devm_kzalloc(dev, sizeof(*gf), GFP_KERNEL); ++ if (!gf) ++ return -ENOMEM; ++ ++ gf->dev = dev; ++ gf->debug = debug; ++ ++ if (of_property_read_u32(np, "shutdown-timeout-ms", ++ &gf->shutdown_timeout_ms)) ++ gf->shutdown_timeout_ms = 5000; ++ ++ gf->num_soft_gpios = num_soft_gpios; ++ gf->soft_gpios = devm_kcalloc(dev, num_soft_gpios, ++ sizeof(struct soft_gpio), GFP_KERNEL); ++ if (!gf->soft_gpios) ++ return -ENOMEM; ++ for (i = 0; i < num_soft_gpios; i++) { ++ struct soft_gpio *sg = &gf->soft_gpios[i]; ++ ++ sg->dir = GPIOF_DIR_IN; ++ sg->value = 0; ++ } ++ ++ gf->input_gpios = devm_gpiod_get_array_optional(dev, "input", GPIOD_IN); ++ if (IS_ERR(gf->input_gpios)) { ++ ret = PTR_ERR(gf->input_gpios); ++ dev_err(dev, "failed to get input gpios from DT - %d\n", ret); ++ return ret; ++ } ++ gf->num_input_gpios = (gf->input_gpios ? gf->input_gpios->ndescs : 0); ++ ++ gf->input_gpio_states = devm_kcalloc(dev, gf->num_input_gpios, ++ sizeof(struct input_gpio_state), ++ GFP_KERNEL); ++ if (!gf->input_gpio_states) ++ return -ENOMEM; ++ for (i = 0; i < gf->num_input_gpios; i++) { ++ inp_state = &gf->input_gpio_states[i]; ++ inp_state->desc = gf->input_gpios->desc[i]; ++ inp_state->gf = gf; ++ inp_state->index = i; ++ inp_state->irq = gpiod_to_irq(inp_state->desc); ++ inp_state->active_low = gpiod_is_active_low(inp_state->desc); ++ if (inp_state->irq >= 0) ++ ret = devm_request_irq(gf->dev, inp_state->irq, ++ gpio_fsm_gpio_irq_handler, ++ IRQF_TRIGGER_NONE, ++ dev_name(dev), ++ inp_state); ++ else ++ ret = inp_state->irq; ++ ++ if (ret) { ++ dev_err(dev, ++ "failed to get IRQ for input gpio - %d\n", ++ ret); ++ return ret; ++ } ++ } ++ ++ gf->output_gpios = devm_gpiod_get_array_optional(dev, "output", ++ GPIOD_OUT_LOW); ++ if (IS_ERR(gf->output_gpios)) { ++ ret = PTR_ERR(gf->output_gpios); ++ dev_err(dev, "failed to get output gpios from DT - %d\n", ret); ++ return ret; ++ } ++ gf->num_output_gpios = (gf->output_gpios ? gf->output_gpios->ndescs : ++ 0); ++ ++ num_states = of_get_child_count(np); ++ if (!num_states) { ++ dev_err(dev, "no states declared\n"); ++ return -EINVAL; ++ } ++ gf->states = devm_kcalloc(dev, num_states, ++ sizeof(struct fsm_state), GFP_KERNEL); ++ if (!gf->states) ++ return -ENOMEM; ++ ++ // add reserved words to the symbol table ++ for (i = 0; i < ARRAY_SIZE(reserved_symbols); i++) { ++ if (reserved_symbols[i]) ++ add_symbol(&gf->symtab, reserved_symbols[i], (void *)i); ++ } ++ ++ // parse the state ++ for_each_child_of_node(np, cp) { ++ struct fsm_state *state = &gf->states[gf->num_states]; ++ ++ ret = gpio_fsm_parse_state(gf, state, cp); ++ if (ret) ++ return ret; ++ gf->num_states++; ++ } ++ ++ if (!gf->start_state) { ++ dev_err(gf->dev, "no start state defined\n"); ++ return -EINVAL; ++ } ++ ++ // resolve symbol pointers into state pointers ++ for (i = 0; !ret && i < gf->num_states; i++) { ++ struct fsm_state *state = &gf->states[i]; ++ int j; ++ ++ for (j = 0; !ret && j < state->num_gpio_events; j++) { ++ struct gpio_event *ev = &state->gpio_events[j]; ++ ++ ret = resolve_sym_to_state(gf, &ev->target); ++ } ++ ++ for (j = 0; !ret && j < state->num_soft_events; j++) { ++ struct gpio_event *ev = &state->soft_events[j]; ++ ++ ret = resolve_sym_to_state(gf, &ev->target); ++ } ++ ++ if (!ret) { ++ resolve_sym_to_state(gf, &state->delay_target); ++ if (state->shutdown_target != state) ++ resolve_sym_to_state(gf, ++ &state->shutdown_target); ++ } ++ } ++ ++ if (!ret && gf->debug > 1) ++ dump_all(gf); ++ ++ free_symbols(&gf->symtab); ++ ++ if (ret) ++ return ret; ++ ++ gf->gc.parent = dev; ++ gf->gc.label = np->name; ++ gf->gc.owner = THIS_MODULE; ++ gf->gc.of_node = np; ++ gf->gc.base = -1; ++ gf->gc.ngpio = num_soft_gpios; ++ ++ gf->gc.get_direction = gpio_fsm_get_direction; ++ gf->gc.direction_input = gpio_fsm_direction_input; ++ gf->gc.direction_output = gpio_fsm_direction_output; ++ gf->gc.get = gpio_fsm_get; ++ gf->gc.set = gpio_fsm_set; ++ gf->gc.can_sleep = true; ++ spin_lock_init(&gf->spinlock); ++ INIT_WORK(&gf->work, gpio_fsm_work); ++ timer_setup(&gf->timer, gpio_fsm_timer, 0); ++ init_waitqueue_head(&gf->shutdown_event); ++ ++ platform_set_drvdata(pdev, gf); ++ ++ if (gf->debug) ++ dev_info(gf->dev, "Start -> %s\n", gf->start_state->name); ++ ++ gpio_fsm_go_to_state(gf, gf->start_state); ++ ++ return devm_gpiochip_add_data(dev, &gf->gc, gf); ++} ++ ++static int gpio_fsm_remove(struct platform_device *pdev) ++{ ++ struct gpio_fsm *gf = platform_get_drvdata(pdev); ++ int i; ++ ++ if (gf->shutdown_state) { ++ if (gf->debug) ++ dev_info(gf->dev, "Shutting down...\n"); ++ ++ spin_lock(&gf->spinlock); ++ gf->shutting_down = true; ++ if (gf->current_state->shutdown_target && ++ gf->current_state->shutdown_target != gf->current_state) { ++ gf->delay_target_state = ++ gf->current_state->shutdown_target; ++ mod_timer(&gf->timer, gf->shutdown_jiffies); ++ } ++ spin_unlock(&gf->spinlock); ++ ++ wait_event_timeout(gf->shutdown_event, ++ gf->current_state->shutdown_target == ++ gf->current_state, ++ msecs_to_jiffies(gf->shutdown_timeout_ms)); ++ if (gf->current_state->shutdown_target == gf->current_state) ++ gpio_fsm_enter_state(gf, gf->shutdown_state); ++ } ++ cancel_work_sync(&gf->work); ++ del_timer_sync(&gf->timer); ++ ++ /* Events aren't allocated from managed storage */ ++ for (i = 0; i < gf->num_states; i++) { ++ kfree(gf->states[i].gpio_events); ++ kfree(gf->states[i].soft_events); ++ } ++ if (gf->debug) ++ dev_info(gf->dev, "Exiting\n"); ++ ++ return 0; ++} ++ ++static void gpio_fsm_shutdown(struct platform_device *pdev) ++{ ++ gpio_fsm_remove(pdev); ++} ++ ++static const struct of_device_id gpio_fsm_ids[] = { ++ { .compatible = "rpi,gpio-fsm" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, gpio_fsm_ids); ++ ++static struct platform_driver gpio_fsm_driver = { ++ .driver = { ++ .name = MODULE_NAME, ++ .of_match_table = of_match_ptr(gpio_fsm_ids), ++ }, ++ .probe = gpio_fsm_probe, ++ .remove = gpio_fsm_remove, ++ .shutdown = gpio_fsm_shutdown, ++}; ++module_platform_driver(gpio_fsm_driver); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.com>"); ++MODULE_DESCRIPTION("GPIO FSM driver"); ++MODULE_ALIAS("platform:gpio-fsm"); +--- /dev/null ++++ b/include/dt-bindings/gpio/gpio-fsm.h +@@ -0,0 +1,21 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * This header provides constants for binding rpi,gpio-fsm. ++ */ ++ ++#ifndef _DT_BINDINGS_GPIO_FSM_H ++#define _DT_BINDINGS_GPIO_FSM_H ++ ++#define GF_IN 0 ++#define GF_OUT 1 ++#define GF_SOFT 2 ++#define GF_DELAY 3 ++#define GF_SHUTDOWN 4 ++ ++#define GF_IO(t, v) (((v) << 16) | ((t) & 0xffff)) ++ ++#define GF_IP(x) GF_IO(GF_IN, (x)) ++#define GF_OP(x) GF_IO(GF_OUT, (x)) ++#define GF_SW(x) GF_IO(GF_SOFT, (x)) ++ ++#endif diff --git a/target/linux/bcm27xx/patches-5.4/950-0987-overlays-Add-fsm-demo-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0987-overlays-Add-fsm-demo-overlay.patch new file mode 100644 index 0000000000..7b56627447 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0987-overlays-Add-fsm-demo-overlay.patch @@ -0,0 +1,151 @@ +From d27d1447e49bc6ffa92f787f7bc5c2eea29ba7d2 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Wed, 30 Sep 2020 12:08:08 +0100 +Subject: [PATCH] overlays: Add fsm-demo overlay + +fsm-demo demonstrates the usage of the gpio-fsm driver. It is +designed to be used with a set of "traffic light" LEDs on GPIOs +7, 8 and 25. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 8 ++ + .../boot/dts/overlays/fsm-demo-overlay.dts | 104 ++++++++++++++++++ + 3 files changed, 113 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/fsm-demo-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -44,6 +44,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + enc28j60-spi2.dtbo \ + exc3000.dtbo \ + fe-pi-audio.dtbo \ ++ fsm-demo.dtbo \ + goodix.dtbo \ + googlevoicehat-soundcard.dtbo \ + gpio-fan.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -767,6 +767,14 @@ Load: dtoverlay=fe-pi-audio + Params: <None> + + ++Name: fsm-demo ++Info: A demonstration of the gpio-fsm driver. The GPIOs are chosen to work ++ nicely with a "traffic-light" display of red, amber and green LEDs on ++ GPIOs 7, 8 and 25 respectively. ++Load: dtoverlay=fsm-demo,<param>=<val> ++Params: fsm_debug Enable debug logging (default off) ++ ++ + Name: goodix + Info: Enables I2C connected Goodix gt9271 multiple touch controller using + GPIOs 4 and 17 (pins 7 and 11 on GPIO header) for interrupt and reset. +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/fsm-demo-overlay.dts +@@ -0,0 +1,104 @@ ++// Demo overlay for the gpio-fsm driver ++/dts-v1/; ++/plugin/; ++ ++#include <dt-bindings/gpio/gpio-fsm.h> ++ ++#define BUTTON1 GF_IP(0) ++#define BUTTON2 GF_SW(0) ++#define RED GF_OP(0) // GPIO7 ++#define AMBER GF_OP(1) // GPIO8 ++#define GREEN GF_OP(2) // GPIO25 ++ ++/{ ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ fsm_demo: fsm-demo { ++ compatible = "rpi,gpio-fsm"; ++ ++ debug = <0>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ num-soft-gpios = <1>; ++ gpio-line-names = "button2"; ++ input-gpios = <&gpio 6 1>; // BUTTON1 (active-low) ++ output-gpios = <&gpio 7 0>, // RED ++ <&gpio 8 0>, // AMBER ++ <&gpio 25 0>; // GREEN ++ shutdown-timeout-ms = <2000>; ++ ++ start { ++ start_state; ++ set = <RED 1>, <AMBER 0>, <GREEN 0>; ++ start2 = <GF_DELAY 250>; ++ }; ++ ++ start2 { ++ set = <RED 0>, <AMBER 1>; ++ go = <GF_DELAY 250>; ++ }; ++ ++ go { ++ set = <RED 0>, <AMBER 0>, <GREEN 1>; ++ ready_wait = <BUTTON1 0>; ++ shutdown1 = <GF_SHUTDOWN 0>; ++ }; ++ ++ ready_wait { ++ // Clear the soft GPIO ++ set = <BUTTON2 0>; ++ ready = <GF_DELAY 1000>; ++ shutdown1 = <GF_SHUTDOWN 0>; ++ }; ++ ++ ready { ++ stopping = <BUTTON1 1>, <BUTTON2 1>; ++ shutdown1 = <GF_SHUTDOWN 0>; ++ }; ++ ++ stopping { ++ set = <GREEN 0>, <AMBER 1>; ++ stopped = <GF_DELAY 1000>; ++ }; ++ ++ stopped { ++ set = <AMBER 0>, <RED 1>; ++ get_set = <GF_DELAY 3000>; ++ shutdown1 = <GF_SHUTDOWN 0>; ++ }; ++ ++ get_set { ++ set = <AMBER 1>; ++ go = <GF_DELAY 1000>; ++ }; ++ ++ shutdown1 { ++ set = <RED 0>, <AMBER 0>, <GREEN 1>; ++ shutdown2 = <GF_SHUTDOWN 250>; ++ }; ++ ++ shutdown2 { ++ set = <AMBER 1>, <GREEN 0>; ++ shutdown3 = <GF_SHUTDOWN 250>; ++ }; ++ ++ shutdown3 { ++ set = <RED 1>, <AMBER 0>; ++ shutdown4 = <GF_SHUTDOWN 250>; ++ }; ++ ++ shutdown4 { ++ shutdown_state; ++ set = <RED 0>; ++ }; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ fsm_debug = <&fsm_demo>,"debug:0"; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-5.4/950-0988-overlays-Add-ghost-amp-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-0988-overlays-Add-ghost-amp-overlay.patch new file mode 100644 index 0000000000..7404bf7f7a --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0988-overlays-Add-ghost-amp-overlay.patch @@ -0,0 +1,163 @@ +From 96f25d50e2352922e16ae74bb16fd8b6985f0f66 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Wed, 30 Sep 2020 12:17:48 +0100 +Subject: [PATCH] overlays: Add ghost-amp overlay + +Add an overlay for the Ghost amplifier. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 7 ++ + .../boot/dts/overlays/ghost-amp-overlay.dts | 119 ++++++++++++++++++ + 3 files changed, 127 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/ghost-amp-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -45,6 +45,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + exc3000.dtbo \ + fe-pi-audio.dtbo \ + fsm-demo.dtbo \ ++ ghost-amp.dtbo \ + goodix.dtbo \ + googlevoicehat-soundcard.dtbo \ + gpio-fan.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -775,6 +775,13 @@ Load: dtoverlay=fsm-demo,<param>=<val> + Params: fsm_debug Enable debug logging (default off) + + ++Name: ghost-amp ++Info: An overlay for the Ghost amplifier. ++Load: dtoverlay=ghost-amp,<param>=<val> ++Params: fsm_debug Enable debug logging of the GPIO FSM (default ++ off) ++ ++ + Name: goodix + Info: Enables I2C connected Goodix gt9271 multiple touch controller using + GPIOs 4 and 17 (pins 7 and 11 on GPIO header) for interrupt and reset. +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/ghost-amp-overlay.dts +@@ -0,0 +1,119 @@ ++// Overlay for the PCM5122-based Ghost amplifier using gpio-fsm ++/dts-v1/; ++/plugin/; ++ ++#include <dt-bindings/gpio/gpio-fsm.h> ++ ++#define ENABLE GF_SW(0) ++#define FAULT GF_IP(0) // GPIO5 ++#define RELAY1 GF_OP(0) // GPIO22 ++#define RELAY2 GF_OP(1) // GPIO23 ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pcm5122@4c { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm5122"; ++ reg = <0x4c>; ++ AVDD-supply = <&vdd_3v3_reg>; ++ DVDD-supply = <&vdd_3v3_reg>; ++ CPVDD-supply = <&vdd_3v3_reg>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&sound>; ++ iqaudio_dac: __overlay__ { ++ compatible = "iqaudio,iqaudio-dac"; ++ i2s-controller = <&i2s>; ++ mute-gpios = <& 0 0>; ++ iqaudio-dac,auto-mute-amp; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@3 { ++ target-path = "/"; ++ __overlay__ { ++ amp: ghost-amp { ++ compatible = "rpi,gpio-fsm"; ++ ++ debug = <0>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ num-soft-gpios = <1>; ++ gpio-line-names = "enable"; ++ input-gpios = <&gpio 5 1>; // FAULT (active low) ++ output-gpios = <&gpio 22 0>, // RELAY1 ++ <&gpio 23 0>; // RELAY2 ++ shutdown-timeout-ms = <1000>; ++ ++ amp_off { ++ start_state; ++ shutdown_state; ++ ++ set = <RELAY2 0>, ++ <RELAY1 0>; ++ amp_on_1 = <ENABLE 1>; ++ fault = <FAULT 1>; ++ }; ++ ++ amp_on_1 { ++ set = <RELAY1 1>; ++ amp_on = <GF_DELAY 1500>; ++ amp_off = <ENABLE 0>; ++ fault = <FAULT 1>; ++ }; ++ ++ amp_on { ++ set = <RELAY2 1>; ++ amp_off_wait = <ENABLE 0>; ++ fault = <FAULT 1>; ++ }; ++ ++ amp_off_wait { ++ amp_off_1 = <GF_DELAY (30*60*1000)>, ++ <GF_SHUTDOWN 0>; ++ amp_on = <ENABLE 1>; ++ fault = <FAULT 1>; ++ }; ++ ++ amp_off_1 { ++ set = <RELAY2 0>; ++ amp_on = <ENABLE 1>; ++ amp_off = <GF_DELAY 100>; ++ fault = <FAULT 1>; ++ }; ++ ++ // Keep this a distinct state to prevent ++ // changes and for the diagnostic output ++ fault { ++ set = <RELAY2 0>, ++ <RELAY1 0>; ++ shutdown_state; ++ }; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ fsm_debug = <&>,"debug:0"; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-5.4/950-0989-Bluetooth-Disable-High-Speed-by-default.patch b/target/linux/bcm27xx/patches-5.4/950-0989-Bluetooth-Disable-High-Speed-by-default.patch new file mode 100644 index 0000000000..03173126c4 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0989-Bluetooth-Disable-High-Speed-by-default.patch @@ -0,0 +1,26 @@ +From 8ccf890b3514c07c0596a8a3e389e08fd00c0d8e Mon Sep 17 00:00:00 2001 +From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> +Date: Thu, 6 Aug 2020 11:17:13 -0700 +Subject: [PATCH] Bluetooth: Disable High Speed by default + +commit b176dd0ef6afcb3bca24f41d78b0d0b731ec2d08 upstream. + +Bluetooth High Speed requires hardware support which is very uncommon +nowadays since HS has not pickup interest by the industry. + +Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> +Signed-off-by: Marcel Holtmann <marcel@holtmann.org> +--- + net/bluetooth/Kconfig | 1 - + 1 file changed, 1 deletion(-) + +--- a/net/bluetooth/Kconfig ++++ b/net/bluetooth/Kconfig +@@ -64,7 +64,6 @@ source "net/bluetooth/hidp/Kconfig" + config BT_HS + bool "Bluetooth High Speed (HS) features" + depends on BT_BREDR +- default y + help + Bluetooth High Speed includes support for off-loading + Bluetooth connections via 802.11 (wifi) physical layer diff --git a/target/linux/bcm27xx/patches-5.4/950-0990-Fixes-a-problem-when-module-probes-before-i2c-module.patch b/target/linux/bcm27xx/patches-5.4/950-0990-Fixes-a-problem-when-module-probes-before-i2c-module.patch new file mode 100644 index 0000000000..e9397727e9 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0990-Fixes-a-problem-when-module-probes-before-i2c-module.patch @@ -0,0 +1,46 @@ +From bc55eb17b46668e70dfbd1a091159935d8f95eb9 Mon Sep 17 00:00:00 2001 +From: Joerg Schambacher <joerg@i2audio.com> +Date: Fri, 16 Oct 2020 15:17:07 +0200 +Subject: [PATCH] Fixes a problem when module probes before i2c + module is available + +The driver crashed while a NULL pointer returned by i2c_get_adapter() +has been used to access the i2c bus functions. +The headphone probing function hb_hp_probe() now returns -EPROBE_DEFER +in case the i2c module has not been loaded yet. + +Signed-off-by: Joerg Schambacher <joerg@i2audio.com> +--- + sound/soc/bcm/hifiberry_dacplus.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/sound/soc/bcm/hifiberry_dacplus.c ++++ b/sound/soc/bcm/hifiberry_dacplus.c +@@ -315,12 +315,14 @@ static int hb_hp_detect(void) + { + struct i2c_adapter *adap = i2c_get_adapter(1); + int ret; +- + struct i2c_client tpa_i2c_client = { + .addr = 0x60, + .adapter = adap, + }; + ++ if (!adap) ++ return -EPROBE_DEFER; /* I2C module not yet available */ ++ + ret = i2c_smbus_read_byte(&tpa_i2c_client) >= 0; + i2c_put_adapter(adap); + return ret; +@@ -342,7 +344,10 @@ static int snd_rpi_hifiberry_dacplus_pro + struct of_changeset ocs; + + /* probe for head phone amp */ +- if (hb_hp_detect()) { ++ ret = hb_hp_detect(); ++ if (ret < 0) ++ return ret; ++ if (ret) { + card->aux_dev = hifiberry_dacplus_aux_devs; + card->num_aux_devs = + ARRAY_SIZE(hifiberry_dacplus_aux_devs); diff --git a/target/linux/bcm27xx/patches-5.4/950-0991-uapi-Update-V4L2_CID_USER_BCM2835_ISP_BASE-due-to-up.patch b/target/linux/bcm27xx/patches-5.4/950-0991-uapi-Update-V4L2_CID_USER_BCM2835_ISP_BASE-due-to-up.patch new file mode 100644 index 0000000000..71c27e168a --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0991-uapi-Update-V4L2_CID_USER_BCM2835_ISP_BASE-due-to-up.patch @@ -0,0 +1,41 @@ +From 90e833fddb15bbdd8aeb6285ba596b4c657383c2 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Thu, 15 Oct 2020 11:59:02 +0100 +Subject: [PATCH] uapi: Update V4L2_CID_USER_BCM2835_ISP_BASE due to + upstream change + +Commit "4e52889 media: atmel: atmel-isc-base: expose white +balance as v4l2 controls" in the upstream kernels reserves +(V4L2_CID_USER_BASE + 0x10c0) for use by the Atmel ISC, +therefore we have a control collision with our existing +define for V4L2_CID_USER_BCM2835_ISP_BASE. + +Update V4L2_CID_USER_BCM2835_ISP_BASE to + 0x10e0 as the +next available block. + +NB ABI breakage for libcamera (the only user of these controls). + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + include/uapi/linux/v4l2-controls.h | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/include/uapi/linux/v4l2-controls.h ++++ b/include/uapi/linux/v4l2-controls.h +@@ -192,9 +192,15 @@ enum v4l2_colorfx { + * We reserve 16 controls for this driver. */ + #define V4L2_CID_USER_IMX_BASE (V4L2_CID_USER_BASE + 0x10b0) + ++/* ++ * The base for the atmel isc driver controls. ++ * We reserve 32 controls for this driver. ++ */ ++#define V4L2_CID_USER_ATMEL_ISC_BASE (V4L2_CID_USER_BASE + 0x10c0) ++ + /* The base for the bcm2835-isp driver controls. + * We reserve 16 controls for this driver. */ +-#define V4L2_CID_USER_BCM2835_ISP_BASE (V4L2_CID_USER_BASE + 0x10c0) ++#define V4L2_CID_USER_BCM2835_ISP_BASE (V4L2_CID_USER_BASE + 0x10e0) + + /* MPEG-class control IDs */ + /* The MPEG controls are applicable to all codec controls diff --git a/target/linux/bcm27xx/patches-5.4/950-0992-dtoverlays-Correct-CSI2-settings-for-ov9281.patch b/target/linux/bcm27xx/patches-5.4/950-0992-dtoverlays-Correct-CSI2-settings-for-ov9281.patch new file mode 100644 index 0000000000..84a4e98de1 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0992-dtoverlays-Correct-CSI2-settings-for-ov9281.patch @@ -0,0 +1,36 @@ +From ac315f66be96c5a423382efb559f193e5b786226 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Wed, 21 Oct 2020 18:33:02 +0100 +Subject: [PATCH] dtoverlays: Correct CSI2 settings for ov9281 + +OV9281 appears to drop the clock to LP mode between frames, but +the overlay didn't define this at both ends of the CSI2 link. +The overlay also had an incorrect link frequency defined, not that +the driver ever checked for one. + +Fix both issues. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/ov9281-overlay.dts | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/overlays/ov9281-overlay.dts ++++ b/arch/arm/boot/dts/overlays/ov9281-overlay.dts +@@ -34,7 +34,7 @@ + data-lanes = <1 2>; + clock-noncontinuous; + link-frequencies = +- /bits/ 64 <456000000>; ++ /bits/ 64 <400000000>; + }; + }; + }; +@@ -50,6 +50,7 @@ + csi1_ep: endpoint { + remote-endpoint = <&ov9281_0>; + data-lanes = <1 2>; ++ clock-noncontinuous; + }; + }; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-0993-xhci-quirks-add-link-TRB-quirk-for-VL805.patch b/target/linux/bcm27xx/patches-5.4/950-0993-xhci-quirks-add-link-TRB-quirk-for-VL805.patch new file mode 100644 index 0000000000..3c89f1348f --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0993-xhci-quirks-add-link-TRB-quirk-for-VL805.patch @@ -0,0 +1,61 @@ +From 510fccc1a7533aa9f46d97ad500fe45ab7f91010 Mon Sep 17 00:00:00 2001 +From: Jonathan Bell <jonathan@raspberrypi.org> +Date: Mon, 26 Oct 2020 14:03:35 +0000 +Subject: [PATCH] xhci: quirks: add link TRB quirk for VL805 + +The VL805 controller can't cope with the TR Dequeue Pointer for an endpoint +being set to a Link TRB. The hardware-maintained endpoint context ends up +stuck at the address of the Link TRB, leading to erroneous ring expansion +events whenever the enqueue pointer wraps to the dequeue position. + +If the search for the end of the current TD and ring cycle state lands on +a Link TRB, move to the next segment. + +See: https://github.com/raspberrypi/linux/issues/3919 + +Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com> +--- + drivers/usb/host/xhci-pci.c | 1 + + drivers/usb/host/xhci-ring.c | 10 ++++++++++ + drivers/usb/host/xhci.h | 1 + + 3 files changed, 12 insertions(+) + +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -258,6 +258,7 @@ static void xhci_pci_quirks(struct devic + pdev->device == 0x3483) { + xhci->quirks |= XHCI_LPM_SUPPORT; + xhci->quirks |= XHCI_EP_CTX_BROKEN_DCS; ++ xhci->quirks |= XHCI_AVOID_DQ_ON_LINK; + } + + if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -624,6 +624,16 @@ void xhci_find_new_dequeue_state(struct + + } while (!cycle_found || !td_last_trb_found); + ++ /* ++ * Quirk: the xHC does not correctly parse link TRBs if the HW Dequeue ++ * pointer is set to one. Advance to the next TRB (and next segment). ++ */ ++ if (xhci->quirks & XHCI_AVOID_DQ_ON_LINK && trb_is_link(new_deq)) { ++ if (link_trb_toggles_cycle(new_deq)) ++ state->new_cycle_state ^= 0x1; ++ next_trb(xhci, ep_ring, &new_seg, &new_deq); ++ } ++ + state->new_deq_seg = new_seg; + state->new_deq_ptr = new_deq; + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1876,6 +1876,7 @@ struct xhci_hcd { + #define XHCI_EP_CTX_BROKEN_DCS BIT_ULL(36) + #define XHCI_SKIP_PHY_INIT BIT_ULL(37) + #define XHCI_DISABLE_SPARSE BIT_ULL(38) ++#define XHCI_AVOID_DQ_ON_LINK BIT_ULL(39) + + unsigned int num_active_eps; + unsigned int limit_active_eps; diff --git a/target/linux/bcm27xx/patches-5.4/950-0994-dts-Add-CM4-to-arm64-dt-files.patch b/target/linux/bcm27xx/patches-5.4/950-0994-dts-Add-CM4-to-arm64-dt-files.patch new file mode 100644 index 0000000000..03d0fe8393 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0994-dts-Add-CM4-to-arm64-dt-files.patch @@ -0,0 +1,28 @@ +From 0ea39ee546de55f9dcf5729f1e39ebc2747477ba Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Fri, 23 Oct 2020 15:45:11 +0100 +Subject: [PATCH] dts: Add CM4 to arm64 dt files + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + arch/arm64/boot/dts/broadcom/Makefile | 3 ++- + arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4.dts | 1 + + 2 files changed, 3 insertions(+), 1 deletion(-) + create mode 100644 arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4.dts + +--- a/arch/arm64/boot/dts/broadcom/Makefile ++++ b/arch/arm64/boot/dts/broadcom/Makefile +@@ -7,7 +7,8 @@ dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rp + dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-3-b.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-2-b.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b.dtb +-dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-4-b.dtb ++dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-4-b.dtb \ ++ bcm2711-rpi-cm4.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b-plus.dtb + dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-cm3.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-cm3.dtb +--- /dev/null ++++ b/arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4.dts +@@ -0,0 +1 @@ ++#include "../../../../arm/boot/dts/bcm2711-rpi-cm4.dts" diff --git a/target/linux/bcm27xx/patches-5.4/950-0995-dts-Tidy-the-Raspberry-Pi-Makefile-entries.patch b/target/linux/bcm27xx/patches-5.4/950-0995-dts-Tidy-the-Raspberry-Pi-Makefile-entries.patch new file mode 100644 index 0000000000..af427f44d9 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0995-dts-Tidy-the-Raspberry-Pi-Makefile-entries.patch @@ -0,0 +1,43 @@ +From fd3620d39c813e9846ace3511bc96a868b5be61a Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 26 Oct 2020 15:01:21 +0000 +Subject: [PATCH] dts: Tidy the Raspberry Pi Makefile entries + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/Makefile | 2 +- + arch/arm64/boot/dts/broadcom/Makefile | 7 ++----- + 2 files changed, 3 insertions(+), 6 deletions(-) + +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -10,8 +10,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ + bcm2709-rpi-2-b.dtb \ + bcm2710-rpi-2-b.dtb \ + bcm2710-rpi-3-b.dtb \ +- bcm2711-rpi-4-b.dtb \ + bcm2710-rpi-3-b-plus.dtb \ ++ bcm2711-rpi-4-b.dtb \ + bcm2710-rpi-cm3.dtb \ + bcm2711-rpi-cm4.dtb + +--- a/arch/arm64/boot/dts/broadcom/Makefile ++++ b/arch/arm64/boot/dts/broadcom/Makefile +@@ -3,15 +3,12 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rp + bcm2837-rpi-3-b.dtb \ + bcm2837-rpi-3-b-plus.dtb \ + bcm2837-rpi-cm3-io3.dtb +-dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-2-b.dtb +-dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-3-b.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-2-b.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b.dtb +-dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-4-b.dtb \ +- bcm2711-rpi-cm4.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b-plus.dtb +-dtb-$(CONFIG_ARCH_BCM2709) += bcm2710-rpi-cm3.dtb ++dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-4-b.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-cm3.dtb ++dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-cm4.dtb + + subdir-y += northstar2 + subdir-y += stingray diff --git a/target/linux/bcm27xx/patches-5.4/950-0996-staging-bcm2835-audio-Add-disable-headphones-flag.patch b/target/linux/bcm27xx/patches-5.4/950-0996-staging-bcm2835-audio-Add-disable-headphones-flag.patch new file mode 100644 index 0000000000..3c30745714 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0996-staging-bcm2835-audio-Add-disable-headphones-flag.patch @@ -0,0 +1,34 @@ +From af217539bab20a3bba6e1bbd4e4c8f68e7644e50 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 26 Oct 2020 10:23:22 +0000 +Subject: [PATCH] staging: bcm2835-audio: Add disable-headphones flag + +Add a property to allow the headphone output to be disabled. Use an +integer property rather than a boolean so that an overlay can clear it. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/staging/vc04_services/bcm2835-audio/bcm2835.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +@@ -381,11 +381,16 @@ static int snd_bcm2835_alsa_probe(struct + } + + if (!enable_compat_alsa) { ++ // In this mode, enable analog output by default ++ u32 disable_headphones = 0; ++ + if (!of_property_read_bool(dev->of_node, "brcm,disable-hdmi")) + set_hdmi_enables(dev); + +- // In this mode, always enable analog output +- enable_headphones = true; ++ of_property_read_u32(dev->of_node, ++ "brcm,disable-headphones", ++ &disable_headphones); ++ enable_headphones = !disable_headphones; + } else { + enable_hdmi0 = enable_hdmi; + } diff --git a/target/linux/bcm27xx/patches-5.4/950-0997-ARM-dts-Disable-headphone-audio-on-Zeroes-CM4.patch b/target/linux/bcm27xx/patches-5.4/950-0997-ARM-dts-Disable-headphone-audio-on-Zeroes-CM4.patch new file mode 100644 index 0000000000..475d0a8842 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0997-ARM-dts-Disable-headphone-audio-on-Zeroes-CM4.patch @@ -0,0 +1,42 @@ +From 9fc10178e1130b43ccc8b855a73fb22643963da0 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 26 Oct 2020 10:18:50 +0000 +Subject: [PATCH] ARM: dts: Disable headphone audio on Zeroes, CM4 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2708-rpi-zero-w.dts | 1 + + arch/arm/boot/dts/bcm2708-rpi-zero.dts | 1 + + arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 1 + + 3 files changed, 3 insertions(+) + +--- a/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts +@@ -152,6 +152,7 @@ + &audio { + pinctrl-names = "default"; + pinctrl-0 = <&audio_pins>; ++ brcm,disable-headphones = <1>; + }; + + / { +--- a/arch/arm/boot/dts/bcm2708-rpi-zero.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-zero.dts +@@ -106,6 +106,7 @@ + &audio { + pinctrl-names = "default"; + pinctrl-0 = <&audio_pins>; ++ brcm,disable-headphones = <1>; + }; + + / { +--- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts +@@ -460,6 +460,7 @@ + &audio { + pinctrl-names = "default"; + pinctrl-0 = <&audio_pins>; ++ brcm,disable-headphones = <1>; + }; + + &vc4 { diff --git a/target/linux/bcm27xx/patches-5.4/950-0998-overlays-Enable-headphone-audio-in-audremap.patch b/target/linux/bcm27xx/patches-5.4/950-0998-overlays-Enable-headphone-audio-in-audremap.patch new file mode 100644 index 0000000000..e206ca42ed --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0998-overlays-Enable-headphone-audio-in-audremap.patch @@ -0,0 +1,26 @@ +From 4a69ef912ed791855fcc058230eed14342c6cd02 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 26 Oct 2020 10:21:23 +0000 +Subject: [PATCH] overlays: Enable headphone audio in audremap + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/audremap-overlay.dts | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/arch/arm/boot/dts/overlays/audremap-overlay.dts ++++ b/arch/arm/boot/dts/overlays/audremap-overlay.dts +@@ -26,6 +26,13 @@ + }; + }; + ++ fragment@3 { ++ target = <&audio>; ++ __overlay__ { ++ brcm,disable-headphones = <0>; ++ }; ++ }; ++ + __overrides__ { + swap_lr = <&frag0>, "swap_lr?"; + enable_jack = <&frag0>, "enable_jack?"; diff --git a/target/linux/bcm27xx/patches-5.4/950-0999-rpisense-fb-Set-pseudo_pallete-to-prevent-crash-on-f.patch b/target/linux/bcm27xx/patches-5.4/950-0999-rpisense-fb-Set-pseudo_pallete-to-prevent-crash-on-f.patch new file mode 100644 index 0000000000..66d9c694c5 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0999-rpisense-fb-Set-pseudo_pallete-to-prevent-crash-on-f.patch @@ -0,0 +1,30 @@ +From 24a2cc7c39f7232b5256dc8adb2f2e87ee1062ec Mon Sep 17 00:00:00 2001 +From: Serge Schneider <serge@raspberrypi.com> +Date: Mon, 26 Oct 2020 16:38:21 +0000 +Subject: [PATCH] rpisense-fb: Set pseudo_pallete to prevent crash on + fbcon takeover + +Signed-off-by: Serge Schneider <serge@raspberrypi.com> +--- + drivers/video/fbdev/rpisense-fb.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/video/fbdev/rpisense-fb.c ++++ b/drivers/video/fbdev/rpisense-fb.c +@@ -52,6 +52,8 @@ static u8 gamma_low[32] = {0x00, 0x01, 0 + + static u8 gamma_user[32]; + ++static u32 pseudo_palette[16]; ++ + static struct rpisense_fb_param rpisense_fb_param = { + .vmem = NULL, + .vmemsize = 128, +@@ -225,6 +227,7 @@ static int rpisense_fb_probe(struct plat + info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB; + info->screen_base = rpisense_fb_param.vmem; + info->screen_size = rpisense_fb_param.vmemsize; ++ info->pseudo_palette = pseudo_palette; + + if (lowlight) + rpisense_fb_param.gamma = gamma_low; diff --git a/target/linux/bcm27xx/patches-5.4/950-1000-PiFi-40-Devicetree-files.patch b/target/linux/bcm27xx/patches-5.4/950-1000-PiFi-40-Devicetree-files.patch new file mode 100644 index 0000000000..06f5da66e7 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1000-PiFi-40-Devicetree-files.patch @@ -0,0 +1,91 @@ +From a822d6667a687451cdf65aef66ecc7fa15891205 Mon Sep 17 00:00:00 2001 +From: David Knell <david.knell@gmail.com> +Date: Wed, 28 Oct 2020 14:20:56 +0000 +Subject: [PATCH] PiFi-40 Devicetree files + +Signed-off-by: David Knell <david.knell@gmail.com> +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 6 +++ + .../arm/boot/dts/overlays/pifi-40-overlay.dts | 50 +++++++++++++++++++ + 3 files changed, 57 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/pifi-40-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -125,6 +125,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + pca953x.dtbo \ + pibell.dtbo \ + pifacedigital.dtbo \ ++ pifi-40.dtbo \ + piglow.dtbo \ + piscreen.dtbo \ + piscreen2r.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -2000,6 +2000,12 @@ Params: spi-present-mask 8-bit in + 0-3, which can be configured with JP1 and JP2. + + ++Name: pifi-40 ++Info: Configures the PiFi 40W stereo amplifier ++Load: dtoverlay=pifi-40 ++Params: <None> ++ ++ + Name: piglow + Info: Configures the PiGlow by pimoroni.com + Load: dtoverlay=piglow +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pifi-40-overlay.dts +@@ -0,0 +1,50 @@ ++// Definitions for PiFi-40 Amp ++/dts-v1/; ++/plugin/; ++#include <dt-bindings/gpio/gpio.h> ++/ { ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ tas5711l: audio-codec@1a { ++ compatible = "ti,tas5711"; ++ reg = <0x1a>; ++ #sound-dai-cells = <0>; ++ sound-name-prefix = "Left"; ++ status = "okay"; ++ }; ++ ++ tas5711r: audio-codec@1b { ++ compatible = "ti,tas5711"; ++ reg = <0x1b>; ++ #sound-dai-cells = <0>; ++ sound-name-prefix = "Right"; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&sound>; ++ pifi_40: __overlay__ { ++ compatible = "pifi,pifi-40"; ++ audio-codec = <&tas5711l &tas5711r>; ++ i2s-controller = <&i2s>; ++ pdn-gpios = <&gpio 23 1>; ++ status = "okay"; ++ }; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-5.4/950-1001-PiFi-40-driver-Makefile-and-Kconfig.patch b/target/linux/bcm27xx/patches-5.4/950-1001-PiFi-40-driver-Makefile-and-Kconfig.patch new file mode 100644 index 0000000000..5c584f4971 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1001-PiFi-40-driver-Makefile-and-Kconfig.patch @@ -0,0 +1,331 @@ +From b7bbdd72e5c9e1b7538b74deb584a7ab0f85847d Mon Sep 17 00:00:00 2001 +From: David Knell <david.knell@gmail.com> +Date: Wed, 28 Oct 2020 14:21:37 +0000 +Subject: [PATCH] PiFi-40 driver, Makefile and Kconfig + +Signed-off-by: David Knell <david.knell@gmail.com> +--- + sound/soc/bcm/Kconfig | 8 ++ + sound/soc/bcm/Makefile | 3 + + sound/soc/bcm/pifi-40.c | 282 ++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 293 insertions(+) + create mode 100644 sound/soc/bcm/pifi-40.c + +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -91,6 +91,14 @@ config SND_BCM2708_SOC_HIFIBERRY_AMP + help + Say Y or M if you want to add support for the HifiBerry Amp amplifier board. + ++ config SND_BCM2708_SOC_PIFI_40 ++ tristate "Support for the PiFi-40 amp" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_TAS571X ++ select SND_PIFI_40 ++ help ++ Say Y or M if you want to add support for the PiFi40 amp board ++ + config SND_BCM2708_SOC_RPI_CIRRUS + tristate "Support for Cirrus Logic Audio Card" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -40,6 +40,7 @@ snd-soc-pisound-objs := pisound.o + snd-soc-fe-pi-audio-objs := fe-pi-audio.o + snd-soc-rpi-simple-soundcard-objs := rpi-simple-soundcard.o + snd-soc-rpi-wm8804-soundcard-objs := rpi-wm8804-soundcard.o ++snd-soc-pifi-40-objs := pifi-40.o + + obj-$(CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD) += snd-soc-googlevoicehat-codec.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o +@@ -69,3 +70,5 @@ obj-$(CONFIG_SND_PISOUND) += snd-soc-pis + obj-$(CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO) += snd-soc-fe-pi-audio.o + obj-$(CONFIG_SND_RPI_SIMPLE_SOUNDCARD) += snd-soc-rpi-simple-soundcard.o + obj-$(CONFIG_SND_RPI_WM8804_SOUNDCARD) += snd-soc-rpi-wm8804-soundcard.o ++obj-$(CONFIG_SND_BCM2708_SOC_PIFI_40) += snd-soc-pifi-40.o ++ +--- /dev/null ++++ b/sound/soc/bcm/pifi-40.c +@@ -0,0 +1,282 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * ALSA ASoC Machine Driver for PiFi-40 ++ * ++ * Author: David Knell <david.knell@gmail.com) ++ * based on code by Daniel Matuschek <info@crazy-audio.com> ++ * based on code by Florian Meier <florian.meier@koalo.de> ++ * Copyright (C) 2020 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include <linux/module.h> ++#include <linux/platform_device.h> ++#include <linux/gpio/consumer.h> ++#include <sound/core.h> ++#include <sound/pcm.h> ++#include <sound/pcm_params.h> ++#include <sound/soc.h> ++#include <linux/firmware.h> ++#include <linux/delay.h> ++#include <sound/tlv.h> ++ ++static struct gpio_desc *pdn_gpio; ++static int vol = 0x30; ++ ++// Volume control ++static int pifi_40_vol_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ ucontrol->value.integer.value[0] = vol; ++ ucontrol->value.integer.value[1] = vol; ++ return 0; ++} ++ ++static int pifi_40_vol_set(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); ++ struct snd_soc_pcm_runtime *rtd; ++ unsigned int v = ucontrol->value.integer.value[0]; ++ struct snd_soc_component *dac[2]; ++ ++ rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name); ++ dac[0] = rtd->codec_dais[0]->component; ++ dac[1] = rtd->codec_dais[1]->component; ++ ++ snd_soc_component_write(dac[0], 0x07, 255 - v); ++ snd_soc_component_write(dac[1], 0x07, 255 - v); ++ ++ vol = v; ++ return 1; ++} ++ ++static const DECLARE_TLV_DB_SCALE(digital_tlv_master, -10350, 50, 1); ++static const struct snd_kcontrol_new pifi_40_controls[] = { ++ SOC_DOUBLE_R_EXT_TLV("Master Volume", 0x00, 0x01, ++ 0x00, // Min ++ 0xff, // Max ++ 0x01, // Invert ++ pifi_40_vol_get, pifi_40_vol_set, ++ digital_tlv_master) ++}; ++ ++static const char * const codec_ctl_pfx[] = { "Left", "Right" }; ++ ++static const char * const codec_ctl_name[] = { "Master Volume", ++ "Speaker Volume", ++ "Speaker Switch" }; ++ ++static int snd_pifi_40_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ struct snd_soc_card *card = rtd->card; ++ struct snd_soc_component *dac[2]; ++ struct snd_kcontrol *kctl; ++ int i, j; ++ ++ dac[0] = rtd->codec_dais[0]->component; ++ dac[1] = rtd->codec_dais[1]->component; ++ ++ // Set up cards - pulse power down first ++ gpiod_set_value_cansleep(pdn_gpio, 1); ++ usleep_range(1000, 10000); ++ gpiod_set_value_cansleep(pdn_gpio, 0); ++ usleep_range(20000, 30000); ++ ++ // Oscillator trim ++ snd_soc_component_write(dac[0], 0x1b, 0); ++ snd_soc_component_write(dac[1], 0x1b, 0); ++ usleep_range(60000, 80000); ++ ++ // Common setup ++ for (i = 0; i < 2; i++) { ++ // MCLK at 64fs, sample rate 44.1 or 48kHz ++ snd_soc_component_write(dac[i], 0x00, 0x60); ++ ++ // Set up for PBTL ++ snd_soc_component_write(dac[i], 0x19, 0x3A); ++ snd_soc_component_write(dac[i], 0x25, 0x01103245); ++ ++ // Master vol to -10db ++ snd_soc_component_write(dac[i], 0x07, 0x44); ++ } ++ // Inputs set to L and R respectively ++ snd_soc_component_write(dac[0], 0x20, 0x00017772); ++ snd_soc_component_write(dac[1], 0x20, 0x00107772); ++ ++ // Remove codec controls ++ for (i = 0; i < 2; i++) { ++ for (j = 0; j < 3; j++) { ++ char cname[256]; ++ ++ sprintf(cname, "%s %s", codec_ctl_pfx[i], ++ codec_ctl_name[j]); ++ kctl = snd_soc_card_get_kcontrol(card, cname); ++ if (!kctl) { ++ pr_info("Control %s not found\n", ++ cname); ++ } else { ++ kctl->vd[0].access = ++ SNDRV_CTL_ELEM_ACCESS_READWRITE; ++ snd_ctl_remove(card->snd_card, kctl); ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++static int snd_pifi_40_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; ++ ++ sample_bits = snd_pcm_format_physical_width(params_format(params)); ++ return snd_soc_dai_set_bclk_ratio(cpu_dai, 64); ++} ++ ++static struct snd_soc_ops snd_pifi_40_ops = { .hw_params = ++ snd_pifi_40_hw_params }; ++ ++static struct snd_soc_dai_link_component pifi_40_codecs[] = { ++ { ++ .dai_name = "tas571x-hifi", ++ }, ++ { ++ .dai_name = "tas571x-hifi", ++ }, ++}; ++ ++SND_SOC_DAILINK_DEFS( ++ pifi_40_dai, DAILINK_COMP_ARRAY(COMP_EMPTY()), ++ DAILINK_COMP_ARRAY(COMP_CODEC("tas571x.1-001a", "tas571x-hifi"), ++ COMP_CODEC("tas571x.1-001b", "tas571x-hifi")), ++ DAILINK_COMP_ARRAY(COMP_EMPTY())); ++ ++static struct snd_soc_dai_link snd_pifi_40_dai[] = { ++ { ++ .name = "PiFi40", ++ .stream_name = "PiFi40", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS, ++ .ops = &snd_pifi_40_ops, ++ .init = snd_pifi_40_init, ++ SND_SOC_DAILINK_REG(pifi_40_dai), ++ }, ++}; ++ ++// Machine driver ++static struct snd_soc_card snd_pifi_40 = { ++ .name = "PiFi40", ++ .owner = THIS_MODULE, ++ .dai_link = snd_pifi_40_dai, ++ .num_links = ARRAY_SIZE(snd_pifi_40_dai), ++ .controls = pifi_40_controls, ++ .num_controls = ARRAY_SIZE(pifi_40_controls) ++}; ++ ++static void snd_pifi_40_pdn(struct snd_soc_card *card, int on) ++{ ++ if (pdn_gpio) ++ gpiod_set_value_cansleep(pdn_gpio, on ? 0 : 1); ++} ++ ++static int snd_pifi_40_probe(struct platform_device *pdev) ++{ ++ struct snd_soc_card *card = &snd_pifi_40; ++ int ret = 0, i = 0; ++ ++ card->dev = &pdev->dev; ++ platform_set_drvdata(pdev, &snd_pifi_40); ++ ++ if (pdev->dev.of_node) { ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai; ++ ++ dai = &snd_pifi_40_dai[0]; ++ i2s_node = of_parse_phandle(pdev->dev.of_node, "i2s-controller", ++ 0); ++ if (i2s_node) { ++ for (i = 0; i < card->num_links; i++) { ++ dai->cpus->dai_name = NULL; ++ dai->cpus->of_node = i2s_node; ++ dai->platforms->name = NULL; ++ dai->platforms->of_node = i2s_node; ++ } ++ } ++ ++ pifi_40_codecs[0].of_node = ++ of_parse_phandle(pdev->dev.of_node, "audio-codec", 0); ++ pifi_40_codecs[1].of_node = ++ of_parse_phandle(pdev->dev.of_node, "audio-codec", 1); ++ if (!pifi_40_codecs[0].of_node || !pifi_40_codecs[1].of_node) { ++ dev_err(&pdev->dev, ++ "Property 'audio-codec' missing or invalid\n"); ++ return -EINVAL; ++ } ++ ++ pdn_gpio = devm_gpiod_get_optional(&pdev->dev, "pdn", ++ GPIOD_OUT_LOW); ++ if (IS_ERR(pdn_gpio)) { ++ ret = PTR_ERR(pdn_gpio); ++ dev_err(&pdev->dev, "failed to get pdn gpio: %d\n", ++ ret); ++ return ret; ++ } ++ ++ ret = snd_soc_register_card(&snd_pifi_40); ++ if (ret < 0) { ++ dev_err(&pdev->dev, ++ "snd_soc_register_card() failed: %d\n", ret); ++ return ret; ++ } ++ ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ ++static int snd_pifi_40_remove(struct platform_device *pdev) ++{ ++ struct snd_soc_card *card = platform_get_drvdata(pdev); ++ ++ kfree(&card->drvdata); ++ snd_pifi_40_pdn(&snd_pifi_40, 0); ++ return snd_soc_unregister_card(&snd_pifi_40); ++} ++ ++static const struct of_device_id snd_pifi_40_of_match[] = { ++ { ++ .compatible = "pifi,pifi-40", ++ }, ++ { /* sentinel */ }, ++}; ++ ++MODULE_DEVICE_TABLE(of, snd_pifi_40_of_match); ++ ++static struct platform_driver snd_pifi_40_driver = { ++ .driver = { ++ .name = "snd-pifi-40", ++ .owner = THIS_MODULE, ++ .of_match_table = snd_pifi_40_of_match, ++ }, ++ .probe = snd_pifi_40_probe, ++ .remove = snd_pifi_40_remove, ++}; ++ ++module_platform_driver(snd_pifi_40_driver); ++ ++MODULE_AUTHOR("David Knell <david.knell@gmail.com>"); ++MODULE_DESCRIPTION("ALSA ASoC Machine Driver for PiFi-40"); ++MODULE_LICENSE("GPL v2"); diff --git a/target/linux/bcm27xx/patches-5.4/950-1002-dwc_otg-Minimise-header-and-fix-build-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-1002-dwc_otg-Minimise-header-and-fix-build-warnings.patch new file mode 100644 index 0000000000..233b9f312b --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1002-dwc_otg-Minimise-header-and-fix-build-warnings.patch @@ -0,0 +1,747 @@ +From ed478a5013976948e94834244d8e5c0abcaab5c3 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Tue, 27 Oct 2020 09:59:49 +0000 +Subject: [PATCH] dwc_otg: Minimise header and fix build warnings + +Delete a large amount of unused declaration from "usb.h", some of which +were causing build warnings, and get the module building cleanly. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/usb/host/dwc_common_port/usb.h | 664 ------------------- + drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 4 +- + drivers/usb/host/dwc_otg/dwc_otg_pcd_intr.c | 2 +- + 3 files changed, 3 insertions(+), 667 deletions(-) + +--- a/drivers/usb/host/dwc_common_port/usb.h ++++ b/drivers/usb/host/dwc_common_port/usb.h +@@ -55,12 +55,6 @@ typedef u_int8_t uByte; + typedef u_int8_t uWord[2]; + typedef u_int8_t uDWord[4]; + +-#define USETW2(w,h,l) ((w)[0] = (u_int8_t)(l), (w)[1] = (u_int8_t)(h)) +-#define UCONSTW(x) { (x) & 0xff, ((x) >> 8) & 0xff } +-#define UCONSTDW(x) { (x) & 0xff, ((x) >> 8) & 0xff, \ +- ((x) >> 16) & 0xff, ((x) >> 24) & 0xff } +- +-#if 1 + #define UGETW(w) ((w)[0] | ((w)[1] << 8)) + #define USETW(w,v) ((w)[0] = (u_int8_t)(v), (w)[1] = (u_int8_t)((v) >> 8)) + #define UGETDW(w) ((w)[0] | ((w)[1] << 8) | ((w)[2] << 16) | ((w)[3] << 24)) +@@ -68,31 +62,6 @@ typedef u_int8_t uDWord[4]; + (w)[1] = (u_int8_t)((v) >> 8), \ + (w)[2] = (u_int8_t)((v) >> 16), \ + (w)[3] = (u_int8_t)((v) >> 24)) +-#else +-/* +- * On little-endian machines that can handle unanliged accesses +- * (e.g. i386) these macros can be replaced by the following. +- */ +-#define UGETW(w) (*(u_int16_t *)(w)) +-#define USETW(w,v) (*(u_int16_t *)(w) = (v)) +-#define UGETDW(w) (*(u_int32_t *)(w)) +-#define USETDW(w,v) (*(u_int32_t *)(w) = (v)) +-#endif +- +-/* +- * Macros for accessing UAS IU fields, which are big-endian +- */ +-#define IUSETW2(w,h,l) ((w)[0] = (u_int8_t)(h), (w)[1] = (u_int8_t)(l)) +-#define IUCONSTW(x) { ((x) >> 8) & 0xff, (x) & 0xff } +-#define IUCONSTDW(x) { ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \ +- ((x) >> 8) & 0xff, (x) & 0xff } +-#define IUGETW(w) (((w)[0] << 8) | (w)[1]) +-#define IUSETW(w,v) ((w)[0] = (u_int8_t)((v) >> 8), (w)[1] = (u_int8_t)(v)) +-#define IUGETDW(w) (((w)[0] << 24) | ((w)[1] << 16) | ((w)[2] << 8) | (w)[3]) +-#define IUSETDW(w,v) ((w)[0] = (u_int8_t)((v) >> 24), \ +- (w)[1] = (u_int8_t)((v) >> 16), \ +- (w)[2] = (u_int8_t)((v) >> 8), \ +- (w)[3] = (u_int8_t)(v)) + + #define UPACKED __attribute__((__packed__)) + +@@ -119,29 +88,6 @@ typedef struct { + #define UT_ENDPOINT 0x02 + #define UT_OTHER 0x03 + +-#define UT_READ_DEVICE (UT_READ | UT_STANDARD | UT_DEVICE) +-#define UT_READ_INTERFACE (UT_READ | UT_STANDARD | UT_INTERFACE) +-#define UT_READ_ENDPOINT (UT_READ | UT_STANDARD | UT_ENDPOINT) +-#define UT_WRITE_DEVICE (UT_WRITE | UT_STANDARD | UT_DEVICE) +-#define UT_WRITE_INTERFACE (UT_WRITE | UT_STANDARD | UT_INTERFACE) +-#define UT_WRITE_ENDPOINT (UT_WRITE | UT_STANDARD | UT_ENDPOINT) +-#define UT_READ_CLASS_DEVICE (UT_READ | UT_CLASS | UT_DEVICE) +-#define UT_READ_CLASS_INTERFACE (UT_READ | UT_CLASS | UT_INTERFACE) +-#define UT_READ_CLASS_OTHER (UT_READ | UT_CLASS | UT_OTHER) +-#define UT_READ_CLASS_ENDPOINT (UT_READ | UT_CLASS | UT_ENDPOINT) +-#define UT_WRITE_CLASS_DEVICE (UT_WRITE | UT_CLASS | UT_DEVICE) +-#define UT_WRITE_CLASS_INTERFACE (UT_WRITE | UT_CLASS | UT_INTERFACE) +-#define UT_WRITE_CLASS_OTHER (UT_WRITE | UT_CLASS | UT_OTHER) +-#define UT_WRITE_CLASS_ENDPOINT (UT_WRITE | UT_CLASS | UT_ENDPOINT) +-#define UT_READ_VENDOR_DEVICE (UT_READ | UT_VENDOR | UT_DEVICE) +-#define UT_READ_VENDOR_INTERFACE (UT_READ | UT_VENDOR | UT_INTERFACE) +-#define UT_READ_VENDOR_OTHER (UT_READ | UT_VENDOR | UT_OTHER) +-#define UT_READ_VENDOR_ENDPOINT (UT_READ | UT_VENDOR | UT_ENDPOINT) +-#define UT_WRITE_VENDOR_DEVICE (UT_WRITE | UT_VENDOR | UT_DEVICE) +-#define UT_WRITE_VENDOR_INTERFACE (UT_WRITE | UT_VENDOR | UT_INTERFACE) +-#define UT_WRITE_VENDOR_OTHER (UT_WRITE | UT_VENDOR | UT_OTHER) +-#define UT_WRITE_VENDOR_ENDPOINT (UT_WRITE | UT_VENDOR | UT_ENDPOINT) +- + /* Requests */ + #define UR_GET_STATUS 0x00 + #define USTAT_STANDARD_STATUS 0x00 +@@ -243,71 +189,6 @@ typedef struct { + typedef struct { + uByte bLength; + uByte bDescriptorType; +- uByte bDescriptorSubtype; +-} UPACKED usb_descriptor_t; +- +-typedef struct { +- uByte bLength; +- uByte bDescriptorType; +-} UPACKED usb_descriptor_header_t; +- +-typedef struct { +- uByte bLength; +- uByte bDescriptorType; +- uWord bcdUSB; +-#define UD_USB_2_0 0x0200 +-#define UD_IS_USB2(d) (UGETW((d)->bcdUSB) >= UD_USB_2_0) +- uByte bDeviceClass; +- uByte bDeviceSubClass; +- uByte bDeviceProtocol; +- uByte bMaxPacketSize; +- /* The fields below are not part of the initial descriptor. */ +- uWord idVendor; +- uWord idProduct; +- uWord bcdDevice; +- uByte iManufacturer; +- uByte iProduct; +- uByte iSerialNumber; +- uByte bNumConfigurations; +-} UPACKED usb_device_descriptor_t; +-#define USB_DEVICE_DESCRIPTOR_SIZE 18 +- +-typedef struct { +- uByte bLength; +- uByte bDescriptorType; +- uWord wTotalLength; +- uByte bNumInterface; +- uByte bConfigurationValue; +- uByte iConfiguration; +-#define UC_ATT_ONE (1 << 7) /* must be set */ +-#define UC_ATT_SELFPOWER (1 << 6) /* self powered */ +-#define UC_ATT_WAKEUP (1 << 5) /* can wakeup */ +-#define UC_ATT_BATTERY (1 << 4) /* battery powered */ +- uByte bmAttributes; +-#define UC_BUS_POWERED 0x80 +-#define UC_SELF_POWERED 0x40 +-#define UC_REMOTE_WAKEUP 0x20 +- uByte bMaxPower; /* max current in 2 mA units */ +-#define UC_POWER_FACTOR 2 +-} UPACKED usb_config_descriptor_t; +-#define USB_CONFIG_DESCRIPTOR_SIZE 9 +- +-typedef struct { +- uByte bLength; +- uByte bDescriptorType; +- uByte bInterfaceNumber; +- uByte bAlternateSetting; +- uByte bNumEndpoints; +- uByte bInterfaceClass; +- uByte bInterfaceSubClass; +- uByte bInterfaceProtocol; +- uByte iInterface; +-} UPACKED usb_interface_descriptor_t; +-#define USB_INTERFACE_DESCRIPTOR_SIZE 9 +- +-typedef struct { +- uByte bLength; +- uByte bDescriptorType; + uByte bEndpointAddress; + #define UE_GET_DIR(a) ((a) & 0x80) + #define UE_SET_DIR(a,d) ((a) | (((d)&1) << 7)) +@@ -332,27 +213,6 @@ typedef struct { + } UPACKED usb_endpoint_descriptor_t; + #define USB_ENDPOINT_DESCRIPTOR_SIZE 7 + +-typedef struct ss_endpoint_companion_descriptor { +- uByte bLength; +- uByte bDescriptorType; +- uByte bMaxBurst; +-#define USSE_GET_MAX_STREAMS(a) ((a) & 0x1f) +-#define USSE_SET_MAX_STREAMS(a, b) ((a) | ((b) & 0x1f)) +-#define USSE_GET_MAX_PACKET_NUM(a) ((a) & 0x03) +-#define USSE_SET_MAX_PACKET_NUM(a, b) ((a) | ((b) & 0x03)) +- uByte bmAttributes; +- uWord wBytesPerInterval; +-} UPACKED ss_endpoint_companion_descriptor_t; +-#define USB_SS_ENDPOINT_COMPANION_DESCRIPTOR_SIZE 6 +- +-typedef struct { +- uByte bLength; +- uByte bDescriptorType; +- uWord bString[127]; +-} UPACKED usb_string_descriptor_t; +-#define USB_MAX_STRING_LEN 128 +-#define USB_LANGUAGE_TABLE 0 /* # of the string language id table */ +- + /* Hub specific request */ + #define UR_GET_BUS_STATE 0x02 + #define UR_CLEAR_TT_BUFFER 0x08 +@@ -411,530 +271,6 @@ typedef struct { + } UPACKED usb_hub_descriptor_t; + #define USB_HUB_DESCRIPTOR_SIZE 9 /* includes deprecated PortPowerCtrlMask */ + +-typedef struct { +- uByte bLength; +- uByte bDescriptorType; +- uWord bcdUSB; +- uByte bDeviceClass; +- uByte bDeviceSubClass; +- uByte bDeviceProtocol; +- uByte bMaxPacketSize0; +- uByte bNumConfigurations; +- uByte bReserved; +-} UPACKED usb_device_qualifier_t; +-#define USB_DEVICE_QUALIFIER_SIZE 10 +- +-typedef struct { +- uByte bLength; +- uByte bDescriptorType; +- uByte bmAttributes; +-#define UOTG_SRP 0x01 +-#define UOTG_HNP 0x02 +-} UPACKED usb_otg_descriptor_t; +- +-/* OTG feature selectors */ +-#define UOTG_B_HNP_ENABLE 3 +-#define UOTG_A_HNP_SUPPORT 4 +-#define UOTG_A_ALT_HNP_SUPPORT 5 +- +-typedef struct { +- uWord wStatus; +-/* Device status flags */ +-#define UDS_SELF_POWERED 0x0001 +-#define UDS_REMOTE_WAKEUP 0x0002 +-/* Endpoint status flags */ +-#define UES_HALT 0x0001 +-} UPACKED usb_status_t; +- +-typedef struct { +- uWord wHubStatus; +-#define UHS_LOCAL_POWER 0x0001 +-#define UHS_OVER_CURRENT 0x0002 +- uWord wHubChange; +-} UPACKED usb_hub_status_t; +- +-typedef struct { +- uWord wPortStatus; +-#define UPS_CURRENT_CONNECT_STATUS 0x0001 +-#define UPS_PORT_ENABLED 0x0002 +-#define UPS_SUSPEND 0x0004 +-#define UPS_OVERCURRENT_INDICATOR 0x0008 +-#define UPS_RESET 0x0010 +-#define UPS_PORT_POWER 0x0100 +-#define UPS_LOW_SPEED 0x0200 +-#define UPS_HIGH_SPEED 0x0400 +-#define UPS_PORT_TEST 0x0800 +-#define UPS_PORT_INDICATOR 0x1000 +- uWord wPortChange; +-#define UPS_C_CONNECT_STATUS 0x0001 +-#define UPS_C_PORT_ENABLED 0x0002 +-#define UPS_C_SUSPEND 0x0004 +-#define UPS_C_OVERCURRENT_INDICATOR 0x0008 +-#define UPS_C_PORT_RESET 0x0010 +-} UPACKED usb_port_status_t; +- +-#ifdef _MSC_VER +-#include <poppack.h> +-#endif +- +-/* Device class codes */ +-#define UDCLASS_IN_INTERFACE 0x00 +-#define UDCLASS_COMM 0x02 +-#define UDCLASS_HUB 0x09 +-#define UDSUBCLASS_HUB 0x00 +-#define UDPROTO_FSHUB 0x00 +-#define UDPROTO_HSHUBSTT 0x01 +-#define UDPROTO_HSHUBMTT 0x02 +-#define UDCLASS_DIAGNOSTIC 0xdc +-#define UDCLASS_WIRELESS 0xe0 +-#define UDSUBCLASS_RF 0x01 +-#define UDPROTO_BLUETOOTH 0x01 +-#define UDCLASS_VENDOR 0xff +- +-/* Interface class codes */ +-#define UICLASS_UNSPEC 0x00 +- +-#define UICLASS_AUDIO 0x01 +-#define UISUBCLASS_AUDIOCONTROL 1 +-#define UISUBCLASS_AUDIOSTREAM 2 +-#define UISUBCLASS_MIDISTREAM 3 +- +-#define UICLASS_CDC 0x02 /* communication */ +-#define UISUBCLASS_DIRECT_LINE_CONTROL_MODEL 1 +-#define UISUBCLASS_ABSTRACT_CONTROL_MODEL 2 +-#define UISUBCLASS_TELEPHONE_CONTROL_MODEL 3 +-#define UISUBCLASS_MULTICHANNEL_CONTROL_MODEL 4 +-#define UISUBCLASS_CAPI_CONTROLMODEL 5 +-#define UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6 +-#define UISUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7 +-#define UIPROTO_CDC_AT 1 +- +-#define UICLASS_HID 0x03 +-#define UISUBCLASS_BOOT 1 +-#define UIPROTO_BOOT_KEYBOARD 1 +- +-#define UICLASS_PHYSICAL 0x05 +- +-#define UICLASS_IMAGE 0x06 +- +-#define UICLASS_PRINTER 0x07 +-#define UISUBCLASS_PRINTER 1 +-#define UIPROTO_PRINTER_UNI 1 +-#define UIPROTO_PRINTER_BI 2 +-#define UIPROTO_PRINTER_1284 3 +- +-#define UICLASS_MASS 0x08 +-#define UISUBCLASS_RBC 1 +-#define UISUBCLASS_SFF8020I 2 +-#define UISUBCLASS_QIC157 3 +-#define UISUBCLASS_UFI 4 +-#define UISUBCLASS_SFF8070I 5 +-#define UISUBCLASS_SCSI 6 +-#define UIPROTO_MASS_CBI_I 0 +-#define UIPROTO_MASS_CBI 1 +-#define UIPROTO_MASS_BBB_OLD 2 /* Not in the spec anymore */ +-#define UIPROTO_MASS_BBB 80 /* 'P' for the Iomega Zip drive */ +- +-#define UICLASS_HUB 0x09 +-#define UISUBCLASS_HUB 0 +-#define UIPROTO_FSHUB 0 +-#define UIPROTO_HSHUBSTT 0 /* Yes, same as previous */ +-#define UIPROTO_HSHUBMTT 1 +- +-#define UICLASS_CDC_DATA 0x0a +-#define UISUBCLASS_DATA 0 +-#define UIPROTO_DATA_ISDNBRI 0x30 /* Physical iface */ +-#define UIPROTO_DATA_HDLC 0x31 /* HDLC */ +-#define UIPROTO_DATA_TRANSPARENT 0x32 /* Transparent */ +-#define UIPROTO_DATA_Q921M 0x50 /* Management for Q921 */ +-#define UIPROTO_DATA_Q921 0x51 /* Data for Q921 */ +-#define UIPROTO_DATA_Q921TM 0x52 /* TEI multiplexer for Q921 */ +-#define UIPROTO_DATA_V42BIS 0x90 /* Data compression */ +-#define UIPROTO_DATA_Q931 0x91 /* Euro-ISDN */ +-#define UIPROTO_DATA_V120 0x92 /* V.24 rate adaption */ +-#define UIPROTO_DATA_CAPI 0x93 /* CAPI 2.0 commands */ +-#define UIPROTO_DATA_HOST_BASED 0xfd /* Host based driver */ +-#define UIPROTO_DATA_PUF 0xfe /* see Prot. Unit Func. Desc.*/ +-#define UIPROTO_DATA_VENDOR 0xff /* Vendor specific */ +- +-#define UICLASS_SMARTCARD 0x0b +- +-/*#define UICLASS_FIRM_UPD 0x0c*/ +- +-#define UICLASS_SECURITY 0x0d +- +-#define UICLASS_DIAGNOSTIC 0xdc +- +-#define UICLASS_WIRELESS 0xe0 +-#define UISUBCLASS_RF 0x01 +-#define UIPROTO_BLUETOOTH 0x01 +- +-#define UICLASS_APPL_SPEC 0xfe +-#define UISUBCLASS_FIRMWARE_DOWNLOAD 1 +-#define UISUBCLASS_IRDA 2 +-#define UIPROTO_IRDA 0 +- +-#define UICLASS_VENDOR 0xff +- +-#define USB_HUB_MAX_DEPTH 5 +- +-/* +- * Minimum time a device needs to be powered down to go through +- * a power cycle. XXX Are these time in the spec? +- */ +-#define USB_POWER_DOWN_TIME 200 /* ms */ +-#define USB_PORT_POWER_DOWN_TIME 100 /* ms */ +- +-#if 0 +-/* These are the values from the spec. */ +-#define USB_PORT_RESET_DELAY 10 /* ms */ +-#define USB_PORT_ROOT_RESET_DELAY 50 /* ms */ +-#define USB_PORT_RESET_RECOVERY 10 /* ms */ +-#define USB_PORT_POWERUP_DELAY 100 /* ms */ +-#define USB_SET_ADDRESS_SETTLE 2 /* ms */ +-#define USB_RESUME_DELAY (20*5) /* ms */ +-#define USB_RESUME_WAIT 10 /* ms */ +-#define USB_RESUME_RECOVERY 10 /* ms */ +-#define USB_EXTRA_POWER_UP_TIME 0 /* ms */ +-#else +-/* Allow for marginal (i.e. non-conforming) devices. */ +-#define USB_PORT_RESET_DELAY 50 /* ms */ +-#define USB_PORT_ROOT_RESET_DELAY 250 /* ms */ +-#define USB_PORT_RESET_RECOVERY 250 /* ms */ +-#define USB_PORT_POWERUP_DELAY 300 /* ms */ +-#define USB_SET_ADDRESS_SETTLE 10 /* ms */ +-#define USB_RESUME_DELAY (50*5) /* ms */ +-#define USB_RESUME_WAIT 50 /* ms */ +-#define USB_RESUME_RECOVERY 50 /* ms */ +-#define USB_EXTRA_POWER_UP_TIME 20 /* ms */ +-#endif +- +-#define USB_MIN_POWER 100 /* mA */ +-#define USB_MAX_POWER 500 /* mA */ +- +-#define USB_BUS_RESET_DELAY 100 /* ms XXX?*/ +- +-#define USB_UNCONFIG_NO 0 +-#define USB_UNCONFIG_INDEX (-1) +- +-/*** ioctl() related stuff ***/ +- +-struct usb_ctl_request { +- int ucr_addr; +- usb_device_request_t ucr_request; +- void *ucr_data; +- int ucr_flags; +-#define USBD_SHORT_XFER_OK 0x04 /* allow short reads */ +- int ucr_actlen; /* actual length transferred */ +-}; +- +-struct usb_alt_interface { +- int uai_config_index; +- int uai_interface_index; +- int uai_alt_no; +-}; +- +-#define USB_CURRENT_CONFIG_INDEX (-1) +-#define USB_CURRENT_ALT_INDEX (-1) +- +-struct usb_config_desc { +- int ucd_config_index; +- usb_config_descriptor_t ucd_desc; +-}; +- +-struct usb_interface_desc { +- int uid_config_index; +- int uid_interface_index; +- int uid_alt_index; +- usb_interface_descriptor_t uid_desc; +-}; +- +-struct usb_endpoint_desc { +- int ued_config_index; +- int ued_interface_index; +- int ued_alt_index; +- int ued_endpoint_index; +- usb_endpoint_descriptor_t ued_desc; +-}; +- +-struct usb_full_desc { +- int ufd_config_index; +- u_int ufd_size; +- u_char *ufd_data; +-}; +- +-struct usb_string_desc { +- int usd_string_index; +- int usd_language_id; +- usb_string_descriptor_t usd_desc; +-}; +- +-struct usb_ctl_report_desc { +- int ucrd_size; +- u_char ucrd_data[1024]; /* filled data size will vary */ +-}; +- +-typedef struct { u_int32_t cookie; } usb_event_cookie_t; +- +-#define USB_MAX_DEVNAMES 4 +-#define USB_MAX_DEVNAMELEN 16 +-struct usb_device_info { +- u_int8_t udi_bus; +- u_int8_t udi_addr; /* device address */ +- usb_event_cookie_t udi_cookie; +- char udi_product[USB_MAX_STRING_LEN]; +- char udi_vendor[USB_MAX_STRING_LEN]; +- char udi_release[8]; +- u_int16_t udi_productNo; +- u_int16_t udi_vendorNo; +- u_int16_t udi_releaseNo; +- u_int8_t udi_class; +- u_int8_t udi_subclass; +- u_int8_t udi_protocol; +- u_int8_t udi_config; +- u_int8_t udi_speed; +-#define USB_SPEED_UNKNOWN 0 +-#define USB_SPEED_LOW 1 +-#define USB_SPEED_FULL 2 +-#define USB_SPEED_HIGH 3 +-#define USB_SPEED_VARIABLE 4 +-#define USB_SPEED_SUPER 5 +- int udi_power; /* power consumption in mA, 0 if selfpowered */ +- int udi_nports; +- char udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN]; +- u_int8_t udi_ports[16];/* hub only: addresses of devices on ports */ +-#define USB_PORT_ENABLED 0xff +-#define USB_PORT_SUSPENDED 0xfe +-#define USB_PORT_POWERED 0xfd +-#define USB_PORT_DISABLED 0xfc +-}; +- +-struct usb_ctl_report { +- int ucr_report; +- u_char ucr_data[1024]; /* filled data size will vary */ +-}; +- +-struct usb_device_stats { +- u_long uds_requests[4]; /* indexed by transfer type UE_* */ +-}; +- +-#define WUSB_MIN_IE 0x80 +-#define WUSB_WCTA_IE 0x80 +-#define WUSB_WCONNECTACK_IE 0x81 +-#define WUSB_WHOSTINFO_IE 0x82 +-#define WUHI_GET_CA(_bmAttributes_) ((_bmAttributes_) & 0x3) +-#define WUHI_CA_RECONN 0x00 +-#define WUHI_CA_LIMITED 0x01 +-#define WUHI_CA_ALL 0x03 +-#define WUHI_GET_MLSI(_bmAttributes_) (((_bmAttributes_) & 0x38) >> 3) +-#define WUSB_WCHCHANGEANNOUNCE_IE 0x83 +-#define WUSB_WDEV_DISCONNECT_IE 0x84 +-#define WUSB_WHOST_DISCONNECT_IE 0x85 +-#define WUSB_WRELEASE_CHANNEL_IE 0x86 +-#define WUSB_WWORK_IE 0x87 +-#define WUSB_WCHANNEL_STOP_IE 0x88 +-#define WUSB_WDEV_KEEPALIVE_IE 0x89 +-#define WUSB_WISOCH_DISCARD_IE 0x8A +-#define WUSB_WRESETDEVICE_IE 0x8B +-#define WUSB_WXMIT_PACKET_ADJUST_IE 0x8C +-#define WUSB_MAX_IE 0x8C +- +-/* Device Notification Types */ +- +-#define WUSB_DN_MIN 0x01 +-#define WUSB_DN_CONNECT 0x01 +-# define WUSB_DA_OLDCONN 0x00 +-# define WUSB_DA_NEWCONN 0x01 +-# define WUSB_DA_SELF_BEACON 0x02 +-# define WUSB_DA_DIR_BEACON 0x04 +-# define WUSB_DA_NO_BEACON 0x06 +-#define WUSB_DN_DISCONNECT 0x02 +-#define WUSB_DN_EPRDY 0x03 +-#define WUSB_DN_MASAVAILCHANGED 0x04 +-#define WUSB_DN_REMOTEWAKEUP 0x05 +-#define WUSB_DN_SLEEP 0x06 +-#define WUSB_DN_ALIVE 0x07 +-#define WUSB_DN_MAX 0x07 +- +-#ifdef _MSC_VER +-#include <pshpack1.h> +-#endif +- +-/* WUSB Handshake Data. Used during the SET/GET HANDSHAKE requests */ +-typedef struct wusb_hndshk_data { +- uByte bMessageNumber; +- uByte bStatus; +- uByte tTKID[3]; +- uByte bReserved; +- uByte CDID[16]; +- uByte Nonce[16]; +- uByte MIC[8]; +-} UPACKED wusb_hndshk_data_t; +-#define WUSB_HANDSHAKE_LEN_FOR_MIC 38 +- +-/* WUSB Connection Context */ +-typedef struct wusb_conn_context { +- uByte CHID [16]; +- uByte CDID [16]; +- uByte CK [16]; +-} UPACKED wusb_conn_context_t; +- +-/* WUSB Security Descriptor */ +-typedef struct wusb_security_desc { +- uByte bLength; +- uByte bDescriptorType; +- uWord wTotalLength; +- uByte bNumEncryptionTypes; +-} UPACKED wusb_security_desc_t; +- +-/* WUSB Encryption Type Descriptor */ +-typedef struct wusb_encrypt_type_desc { +- uByte bLength; +- uByte bDescriptorType; +- +- uByte bEncryptionType; +-#define WUETD_UNSECURE 0 +-#define WUETD_WIRED 1 +-#define WUETD_CCM_1 2 +-#define WUETD_RSA_1 3 +- +- uByte bEncryptionValue; +- uByte bAuthKeyIndex; +-} UPACKED wusb_encrypt_type_desc_t; +- +-/* WUSB Key Descriptor */ +-typedef struct wusb_key_desc { +- uByte bLength; +- uByte bDescriptorType; +- uByte tTKID[3]; +- uByte bReserved; +- uByte KeyData[1]; /* variable length */ +-} UPACKED wusb_key_desc_t; +- +-/* WUSB BOS Descriptor (Binary device Object Store) */ +-typedef struct wusb_bos_desc { +- uByte bLength; +- uByte bDescriptorType; +- uWord wTotalLength; +- uByte bNumDeviceCaps; +-} UPACKED wusb_bos_desc_t; +- +-#define USB_DEVICE_CAPABILITY_20_EXTENSION 0x02 +-typedef struct usb_dev_cap_20_ext_desc { +- uByte bLength; +- uByte bDescriptorType; +- uByte bDevCapabilityType; +-#define USB_20_EXT_LPM 0x02 +- uDWord bmAttributes; +-} UPACKED usb_dev_cap_20_ext_desc_t; +- +-#define USB_DEVICE_CAPABILITY_SS_USB 0x03 +-typedef struct usb_dev_cap_ss_usb { +- uByte bLength; +- uByte bDescriptorType; +- uByte bDevCapabilityType; +-#define USB_DC_SS_USB_LTM_CAPABLE 0x02 +- uByte bmAttributes; +-#define USB_DC_SS_USB_SPEED_SUPPORT_LOW 0x01 +-#define USB_DC_SS_USB_SPEED_SUPPORT_FULL 0x02 +-#define USB_DC_SS_USB_SPEED_SUPPORT_HIGH 0x04 +-#define USB_DC_SS_USB_SPEED_SUPPORT_SS 0x08 +- uWord wSpeedsSupported; +- uByte bFunctionalitySupport; +- uByte bU1DevExitLat; +- uWord wU2DevExitLat; +-} UPACKED usb_dev_cap_ss_usb_t; +- +-#define USB_DEVICE_CAPABILITY_CONTAINER_ID 0x04 +-typedef struct usb_dev_cap_container_id { +- uByte bLength; +- uByte bDescriptorType; +- uByte bDevCapabilityType; +- uByte bReserved; +- uByte containerID[16]; +-} UPACKED usb_dev_cap_container_id_t; +- +-/* Device Capability Type Codes */ +-#define WUSB_DEVICE_CAPABILITY_WIRELESS_USB 0x01 +- +-/* Device Capability Descriptor */ +-typedef struct wusb_dev_cap_desc { +- uByte bLength; +- uByte bDescriptorType; +- uByte bDevCapabilityType; +- uByte caps[1]; /* Variable length */ +-} UPACKED wusb_dev_cap_desc_t; +- +-/* Device Capability Descriptor */ +-typedef struct wusb_dev_cap_uwb_desc { +- uByte bLength; +- uByte bDescriptorType; +- uByte bDevCapabilityType; +- uByte bmAttributes; +- uWord wPHYRates; /* Bitmap */ +- uByte bmTFITXPowerInfo; +- uByte bmFFITXPowerInfo; +- uWord bmBandGroup; +- uByte bReserved; +-} UPACKED wusb_dev_cap_uwb_desc_t; +- +-/* Wireless USB Endpoint Companion Descriptor */ +-typedef struct wusb_endpoint_companion_desc { +- uByte bLength; +- uByte bDescriptorType; +- uByte bMaxBurst; +- uByte bMaxSequence; +- uWord wMaxStreamDelay; +- uWord wOverTheAirPacketSize; +- uByte bOverTheAirInterval; +- uByte bmCompAttributes; +-} UPACKED wusb_endpoint_companion_desc_t; +- +-/* Wireless USB Numeric Association M1 Data Structure */ +-typedef struct wusb_m1_data { +- uByte version; +- uWord langId; +- uByte deviceFriendlyNameLength; +- uByte sha_256_m3[32]; +- uByte deviceFriendlyName[256]; +-} UPACKED wusb_m1_data_t; +- +-typedef struct wusb_m2_data { +- uByte version; +- uWord langId; +- uByte hostFriendlyNameLength; +- uByte pkh[384]; +- uByte hostFriendlyName[256]; +-} UPACKED wusb_m2_data_t; +- +-typedef struct wusb_m3_data { +- uByte pkd[384]; +- uByte nd; +-} UPACKED wusb_m3_data_t; +- +-typedef struct wusb_m4_data { +- uDWord _attributeTypeIdAndLength_1; +- uWord associationTypeId; +- +- uDWord _attributeTypeIdAndLength_2; +- uWord associationSubTypeId; +- +- uDWord _attributeTypeIdAndLength_3; +- uDWord length; +- +- uDWord _attributeTypeIdAndLength_4; +- uDWord associationStatus; +- +- uDWord _attributeTypeIdAndLength_5; +- uByte chid[16]; +- +- uDWord _attributeTypeIdAndLength_6; +- uByte cdid[16]; +- +- uDWord _attributeTypeIdAndLength_7; +- uByte bandGroups[2]; +-} UPACKED wusb_m4_data_t; +- + #ifdef _MSC_VER + #include <poppack.h> + #endif +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c +@@ -457,8 +457,8 @@ static void hcd_init_fiq(void *cookie) + otg_dev->os_dep.mphi_base + 0x1f0; + dwc_otg_hcd->fiq_state->mphi_regs.swirq_clr = + otg_dev->os_dep.mphi_base + 0x1f4; +- DWC_WARN("Fake MPHI regs_base at 0x%08x", +- (int)dwc_otg_hcd->fiq_state->mphi_regs.base); ++ DWC_WARN("Fake MPHI regs_base at %px", ++ dwc_otg_hcd->fiq_state->mphi_regs.base); + } else { + dwc_otg_hcd->fiq_state->mphi_regs.ctrl = + otg_dev->os_dep.mphi_base + 0x4c; +--- a/drivers/usb/host/dwc_otg/dwc_otg_pcd_intr.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_pcd_intr.c +@@ -3377,7 +3377,7 @@ void predict_nextep_seq( dwc_otg_core_if + dtknq1_data_t dtknqr1; + uint32_t in_tkn_epnums[4]; + uint8_t seqnum[MAX_EPS_CHANNELS]; +- uint8_t intkn_seq[TOKEN_Q_DEPTH]; ++ uint8_t intkn_seq[1 << 5]; + grstctl_t resetctl = {.d32 = 0 }; + uint8_t temp; + int ndx = 0; diff --git a/target/linux/bcm27xx/patches-5.4/950-1003-gpio-fsm-Fix-a-build-warning.patch b/target/linux/bcm27xx/patches-5.4/950-1003-gpio-fsm-Fix-a-build-warning.patch new file mode 100644 index 0000000000..d9ebc3a355 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1003-gpio-fsm-Fix-a-build-warning.patch @@ -0,0 +1,22 @@ +From 60f17bc7d9100d7c3296987498a9f2d6c13f3f02 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Tue, 27 Oct 2020 12:10:04 +0000 +Subject: [PATCH] gpio-fsm: Fix a build warning + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/gpio/gpio-fsm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpio/gpio-fsm.c ++++ b/drivers/gpio/gpio-fsm.c +@@ -956,7 +956,8 @@ static int gpio_fsm_probe(struct platfor + // add reserved words to the symbol table + for (i = 0; i < ARRAY_SIZE(reserved_symbols); i++) { + if (reserved_symbols[i]) +- add_symbol(&gf->symtab, reserved_symbols[i], (void *)i); ++ add_symbol(&gf->symtab, reserved_symbols[i], ++ (void *)(uintptr_t)i); + } + + // parse the state diff --git a/target/linux/bcm27xx/patches-5.4/950-1004-rpivid_h625-Fix-build-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-1004-rpivid_h625-Fix-build-warnings.patch new file mode 100644 index 0000000000..375f1cac98 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1004-rpivid_h625-Fix-build-warnings.patch @@ -0,0 +1,68 @@ +From c23b30df4bcafaa1a2bca210bc09f65c01ace375 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Tue, 27 Oct 2020 12:10:40 +0000 +Subject: [PATCH] rpivid_h625: Fix build warnings + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/staging/media/rpivid/rpivid_h265.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/staging/media/rpivid/rpivid_h265.c ++++ b/drivers/staging/media/rpivid/rpivid_h265.c +@@ -1341,10 +1341,10 @@ static int frame_end(struct rpivid_dev * + + if (gptr_realloc_new(dev, de->cmd_copy_gptr, cmd_alloc)) { + v4l2_err(&dev->v4l2_dev, +- "Alloc cmd buffer (%d): FAILED\n", cmd_alloc); ++ "Alloc cmd buffer (%zu): FAILED\n", cmd_alloc); + return -ENOMEM; + } +- v4l2_info(&dev->v4l2_dev, "Alloc cmd buffer (%d): OK\n", ++ v4l2_info(&dev->v4l2_dev, "Alloc cmd buffer (%zu): OK\n", + cmd_alloc); + } + +@@ -1696,12 +1696,12 @@ static void rpivid_h265_setup(struct rpi + bits_alloc, + DMA_ATTR_FORCE_CONTIGUOUS) != 0) { + v4l2_err(&dev->v4l2_dev, +- "Unable to alloc buf (%d) for bit copy\n", ++ "Unable to alloc buf (%zu) for bit copy\n", + bits_alloc); + goto fail; + } + v4l2_info(&dev->v4l2_dev, +- "Alloc buf (%d) for bit copy OK\n", ++ "Alloc buf (%zu) for bit copy OK\n", + bits_alloc); + } + } +@@ -1995,11 +1995,11 @@ static void phase1_thread(struct rpivid_ + if (de->p1_status & STATUS_PU_EXHAUSTED) { + if (gptr_realloc_new(dev, pu_gptr, next_size(pu_gptr->size))) { + v4l2_err(&dev->v4l2_dev, +- "%s: PU realloc (%#x) failed\n", ++ "%s: PU realloc (%zx) failed\n", + __func__, pu_gptr->size); + goto fail; + } +- v4l2_info(&dev->v4l2_dev, "%s: PU realloc (%#x) OK\n", ++ v4l2_info(&dev->v4l2_dev, "%s: PU realloc (%zx) OK\n", + __func__, pu_gptr->size); + } + +@@ -2007,11 +2007,11 @@ static void phase1_thread(struct rpivid_ + if (gptr_realloc_new(dev, coeff_gptr, + next_size(coeff_gptr->size))) { + v4l2_err(&dev->v4l2_dev, +- "%s: Coeff realloc (%#x) failed\n", ++ "%s: Coeff realloc (%zx) failed\n", + __func__, coeff_gptr->size); + goto fail; + } +- v4l2_info(&dev->v4l2_dev, "%s: Coeff realloc (%#x) OK\n", ++ v4l2_info(&dev->v4l2_dev, "%s: Coeff realloc (%zx) OK\n", + __func__, coeff_gptr->size); + } + diff --git a/target/linux/bcm27xx/patches-5.4/950-1005-dwc_otg-Fix-more-build-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-1005-dwc_otg-Fix-more-build-warnings.patch new file mode 100644 index 0000000000..a9f560530a --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1005-dwc_otg-Fix-more-build-warnings.patch @@ -0,0 +1,149 @@ +From 9b899afd231b7dde6084092cf46dd15c05ed8a5c Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Tue, 27 Oct 2020 12:11:56 +0000 +Subject: [PATCH] dwc_otg: Fix more build warnings + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 10 +++++---- + drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 23 ++++++++++++++------- + drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c | 3 ++- + drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 8 +++---- + 4 files changed, 27 insertions(+), 17 deletions(-) + +--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c +@@ -240,7 +240,8 @@ static int notrace fiq_increment_dma_buf + hcdma_data_t hcdma; + int i = st->channel[n].dma_info.index; + int len; +- struct fiq_dma_blob *blob = (struct fiq_dma_blob *) st->dma_base; ++ struct fiq_dma_blob *blob = ++ (struct fiq_dma_blob *)(uintptr_t)st->dma_base; + + len = fiq_get_xfer_len(st, n); + fiq_print(FIQDBG_INT, st, "LEN: %03d", len); +@@ -249,7 +250,7 @@ static int notrace fiq_increment_dma_buf + if (i > 6) + BUG(); + +- hcdma.d32 = (dma_addr_t) &blob->channel[n].index[i].buf[0]; ++ hcdma.d32 = (u32)(uintptr_t)&blob->channel[n].index[i].buf[0]; + FIQ_WRITE(st->dwc_regs_base + HC_START + (HC_OFFSET * n) + HC_DMA, hcdma.d32); + st->channel[n].dma_info.index = i; + return 0; +@@ -289,7 +290,8 @@ static int notrace fiq_iso_out_advance(s + hcsplt_data_t hcsplt; + hctsiz_data_t hctsiz; + hcdma_data_t hcdma; +- struct fiq_dma_blob *blob = (struct fiq_dma_blob *) st->dma_base; ++ struct fiq_dma_blob *blob = ++ (struct fiq_dma_blob *)(uintptr_t)st->dma_base; + int last = 0; + int i = st->channel[n].dma_info.index; + +@@ -301,7 +303,7 @@ static int notrace fiq_iso_out_advance(s + last = 1; + + /* New DMA address - address of bounce buffer referred to in index */ +- hcdma.d32 = (dma_addr_t) blob->channel[n].index[i].buf; ++ hcdma.d32 = (u32)(uintptr_t)blob->channel[n].index[i].buf; + //hcdma.d32 = FIQ_READ(st->dwc_regs_base + HC_START + (HC_OFFSET * n) + HC_DMA); + //hcdma.d32 += st->channel[n].dma_info.slot_len[i]; + fiq_print(FIQDBG_INT, st, "LAST: %01d ", last); +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c +@@ -1268,7 +1268,8 @@ static void assign_and_init_hc(dwc_otg_h + hc->multi_count = 1; + + if (hcd->core_if->dma_enable) { +- hc->xfer_buff = (uint8_t *) urb->dma + urb->actual_length; ++ hc->xfer_buff = ++ (uint8_t *)(uintptr_t)urb->dma + urb->actual_length; + + /* For non-dword aligned case */ + if (((unsigned long)hc->xfer_buff & 0x3) +@@ -1312,7 +1313,8 @@ static void assign_and_init_hc(dwc_otg_h + hc->ep_is_in = 0; + hc->data_pid_start = DWC_OTG_HC_PID_SETUP; + if (hcd->core_if->dma_enable) { +- hc->xfer_buff = (uint8_t *) urb->setup_dma; ++ hc->xfer_buff = ++ (uint8_t *)(uintptr_t)urb->setup_dma; + } else { + hc->xfer_buff = (uint8_t *) urb->setup_packet; + } +@@ -1360,7 +1362,8 @@ static void assign_and_init_hc(dwc_otg_h + + hc->xfer_len = 0; + if (hcd->core_if->dma_enable) { +- hc->xfer_buff = (uint8_t *) hcd->status_buf_dma; ++ hc->xfer_buff = (uint8_t *) ++ (uintptr_t)hcd->status_buf_dma; + } else { + hc->xfer_buff = (uint8_t *) hcd->status_buf; + } +@@ -1388,7 +1391,7 @@ static void assign_and_init_hc(dwc_otg_h + frame_desc->status = 0; + + if (hcd->core_if->dma_enable) { +- hc->xfer_buff = (uint8_t *) urb->dma; ++ hc->xfer_buff = (uint8_t *)(uintptr_t)urb->dma; + } else { + hc->xfer_buff = (uint8_t *) urb->buf; + } +@@ -1569,8 +1572,10 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h + * Pointer arithmetic on hcd->fiq_state->dma_base (a dma_addr_t) + * to point it to the correct offset in the allocated buffers. + */ +- blob = (struct fiq_dma_blob *) hcd->fiq_state->dma_base; +- st->hcdma_copy.d32 = (dma_addr_t) blob->channel[hc->hc_num].index[0].buf; ++ blob = (struct fiq_dma_blob *) ++ (uintptr_t)hcd->fiq_state->dma_base; ++ st->hcdma_copy.d32 =(u32)(uintptr_t) ++ blob->channel[hc->hc_num].index[0].buf; + + /* Calculate the max number of CSPLITS such that the FIQ can time out + * a transaction if it fails. +@@ -1625,8 +1630,10 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h + * dma_addr_t) to point it to the correct offset in the + * allocated buffers. + */ +- blob = (struct fiq_dma_blob *) hcd->fiq_state->dma_base; +- st->hcdma_copy.d32 = (dma_addr_t) blob->channel[hc->hc_num].index[0].buf; ++ blob = (struct fiq_dma_blob *) ++ (uintptr_t)hcd->fiq_state->dma_base; ++ st->hcdma_copy.d32 = (u32)(uintptr_t) ++ blob->channel[hc->hc_num].index[0].buf; + + /* fixup xfersize to the actual packet size */ + st->hctsiz_copy.b.pid = 0; +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c +@@ -620,7 +620,8 @@ static void init_non_isoc_dma_desc(dwc_o + + if (n_desc) { + /* SG request - more than 1 QTDs */ +- hc->xfer_buff = (uint8_t *)qtd->urb->dma + qtd->urb->actual_length; ++ hc->xfer_buff = (uint8_t *)(uintptr_t)qtd->urb->dma + ++ qtd->urb->actual_length; + hc->xfer_len = qtd->urb->length - qtd->urb->actual_length; + } + +--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c ++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c +@@ -1857,10 +1857,10 @@ static int32_t handle_hc_ahberr_intr(dwc + DWC_ERROR(" Max packet size: %d\n", + dwc_otg_hcd_get_mps(&urb->pipe_info)); + DWC_ERROR(" Data buffer length: %d\n", urb->length); +- DWC_ERROR(" Transfer buffer: %p, Transfer DMA: %p\n", +- urb->buf, (void *)urb->dma); +- DWC_ERROR(" Setup buffer: %p, Setup DMA: %p\n", +- urb->setup_packet, (void *)urb->setup_dma); ++ DWC_ERROR(" Transfer buffer: %p, Transfer DMA: %pad\n", ++ urb->buf, &urb->dma); ++ DWC_ERROR(" Setup buffer: %p, Setup DMA: %pad\n", ++ urb->setup_packet, &urb->setup_dma); + DWC_ERROR(" Interval: %d\n", urb->interval); + + /* Core haltes the channel for Descriptor DMA mode */ diff --git a/target/linux/bcm27xx/patches-5.4/950-1006-bcm2708_fb-Fix-a-build-warning.patch b/target/linux/bcm27xx/patches-5.4/950-1006-bcm2708_fb-Fix-a-build-warning.patch new file mode 100644 index 0000000000..2eb5f78dc3 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1006-bcm2708_fb-Fix-a-build-warning.patch @@ -0,0 +1,22 @@ +From 61ed3659dae5bdb4c7b1120b3ba4efd3e6abff05 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Tue, 27 Oct 2020 12:12:22 +0000 +Subject: [PATCH] bcm2708_fb: Fix a build warning + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/video/fbdev/bcm2708_fb.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/video/fbdev/bcm2708_fb.c ++++ b/drivers/video/fbdev/bcm2708_fb.c +@@ -705,7 +705,8 @@ static long vc_mem_copy(struct bcm2708_f + u8 *q = (u8 *)ioparam->dst + offset; + + dma_memcpy(fb, bus_addr, +- INTALIAS_L1L2_NONALLOCATING((dma_addr_t)p), size); ++ INTALIAS_L1L2_NONALLOCATING((u32)(uintptr_t)p), ++ size); + if (copy_to_user(q, buf, s) != 0) { + pr_err("[%s]: failed to copy-to-user\n", __func__); + rc = -EFAULT; diff --git a/target/linux/bcm27xx/patches-5.4/950-1007-bcm2835-pcm-Fix-up-multichannel-pcm-audio.patch b/target/linux/bcm27xx/patches-5.4/950-1007-bcm2835-pcm-Fix-up-multichannel-pcm-audio.patch new file mode 100644 index 0000000000..a41d16edaf --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1007-bcm2835-pcm-Fix-up-multichannel-pcm-audio.patch @@ -0,0 +1,55 @@ +From 88bddc0f26024c64e1e17562dea77d8a50e1f1d0 Mon Sep 17 00:00:00 2001 +From: Dom Cobley <popcornmix@gmail.com> +Date: Tue, 27 Oct 2020 12:24:14 +0000 +Subject: [PATCH] bcm2835-pcm: Fix up multichannel pcm audio + +Fixes: a9c1660ff5f02d048c5f31abf1fd1108ccf9ef87 +Signed-off-by: Dom Cobley <popcornmix@gmail.com> +--- + .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 21 +++++++++---------- + 1 file changed, 10 insertions(+), 11 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +@@ -14,14 +14,14 @@ static const struct snd_pcm_hardware snd + SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_SYNC_APPLPTR), + .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, +- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000, ++ .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, +- .channels_max = 2, +- .buffer_bytes_max = 128 * 1024, ++ .channels_max = 8, ++ .buffer_bytes_max = 512 * 1024, + .period_bytes_min = 1 * 1024, +- .period_bytes_max = 128 * 1024, ++ .period_bytes_max = 512 * 1024, + .periods_min = 1, + .periods_max = 128, + }; +@@ -31,16 +31,15 @@ static const struct snd_pcm_hardware snd + SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_SYNC_APPLPTR), + .formats = SNDRV_PCM_FMTBIT_S16_LE, +- .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | +- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | +- SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, ++ .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 | ++ SNDRV_PCM_RATE_48000, + .rate_min = 44100, +- .rate_max = 192000, ++ .rate_max = 48000, + .channels_min = 2, +- .channels_max = 8, +- .buffer_bytes_max = 512 * 1024, ++ .channels_max = 2, ++ .buffer_bytes_max = 128 * 1024, + .period_bytes_min = 1 * 1024, +- .period_bytes_max = 512 * 1024, ++ .period_bytes_max = 128 * 1024, + .periods_min = 1, + .periods_max = 128, + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-1008-watchdog-bcm2835-Ignore-params-after-the-partition-n.patch b/target/linux/bcm27xx/patches-5.4/950-1008-watchdog-bcm2835-Ignore-params-after-the-partition-n.patch new file mode 100644 index 0000000000..44108ecda5 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1008-watchdog-bcm2835-Ignore-params-after-the-partition-n.patch @@ -0,0 +1,29 @@ +From 118538ed52b7dd927226837094d44a5d1cd14ab7 Mon Sep 17 00:00:00 2001 +From: Tim Gover <tim.gover@raspberrypi.org> +Date: Thu, 22 Oct 2020 15:30:55 +0100 +Subject: [PATCH] watchdog: bcm2835: Ignore params after the + partition number + +Use sscanf to extract the partition number and ignore extra parameters +which are only relevant to other reboot notifiers. +--- + drivers/watchdog/bcm2835_wdt.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/watchdog/bcm2835_wdt.c ++++ b/drivers/watchdog/bcm2835_wdt.c +@@ -126,10 +126,12 @@ static int bcm2835_restart(struct watchd + { + struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog); + +- unsigned long long val; ++ unsigned long val; + u8 partition = 0; + +- if (data && !kstrtoull(data, 0, &val) && val <= 63) ++ // Allow extra arguments separated by spaces after ++ // the partition number. ++ if (data && sscanf(data, "%lu", &val) && val < 63) + partition = val; + + __bcm2835_restart(wdt, partition); diff --git a/target/linux/bcm27xx/patches-5.4/950-1009-firmware-raspberrypi-Add-support-for-tryonce-reboot-.patch b/target/linux/bcm27xx/patches-5.4/950-1009-firmware-raspberrypi-Add-support-for-tryonce-reboot-.patch new file mode 100644 index 0000000000..4d7a83f02b --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1009-firmware-raspberrypi-Add-support-for-tryonce-reboot-.patch @@ -0,0 +1,72 @@ +From bf41f32582df3ca5faab2cf2de15e5d4ff688822 Mon Sep 17 00:00:00 2001 +From: Tim Gover <tim.gover@raspberrypi.com> +Date: Tue, 20 Oct 2020 11:55:37 +0100 +Subject: [PATCH] firmware: raspberrypi: Add support for tryonce + reboot flag + +Define a new mailbox (SET_REBOOT_FLAGS) which may be used to +pass optional flags to the Raspberry Pi firmware that changes +the behaviour of the bootloader and firmware during a reboot. + +Currently this just defines the 'tryboot' flag which causes +the firmware to load tryboot.txt instead config.txt. This +alternate configuration file can be used to specify the +path of an alternate firmware and kernels allowing a fallback +mechanism to be implemented for OS upgrades. +--- + drivers/firmware/raspberrypi.c | 25 ++++++++++++++++++++-- + include/soc/bcm2835/raspberrypi-firmware.h | 2 ++ + 2 files changed, 25 insertions(+), 2 deletions(-) + +--- a/drivers/firmware/raspberrypi.c ++++ b/drivers/firmware/raspberrypi.c +@@ -190,6 +190,7 @@ static int rpi_firmware_notify_reboot(st + { + struct rpi_firmware *fw; + struct platform_device *pdev = g_pdev; ++ u32 reboot_flags = 0; + + if (!pdev) + return 0; +@@ -198,8 +199,28 @@ static int rpi_firmware_notify_reboot(st + if (!fw) + return 0; + +- (void)rpi_firmware_property(fw, RPI_FIRMWARE_NOTIFY_REBOOT, +- 0, 0); ++ // The partition id is the first parameter followed by zero or ++ // more flags separated by spaces indicating the reason for the reboot. ++ // ++ // 'tryboot': Sets a one-shot flag which is cleared upon reboot and ++ // causes the tryboot.txt to be loaded instead of config.txt ++ // by the bootloader and the start.elf firmware. ++ // ++ // This is intended to allow automatic fallback to a known ++ // good image if an OS/FW upgrade fails. ++ // ++ // N.B. The firmware mechanism for storing reboot flags may vary ++ // on different Raspberry Pi models. ++ if (data && strstr(data, " tryboot")) ++ reboot_flags |= 0x1; ++ ++ // The mailbox might have been called earlier, directly via vcmailbox ++ // so only overwrite if reboot flags are passed to the reboot command. ++ if (reboot_flags) ++ (void)rpi_firmware_property(fw, RPI_FIRMWARE_SET_REBOOT_FLAGS, ++ &reboot_flags, sizeof(reboot_flags)); ++ ++ (void)rpi_firmware_property(fw, RPI_FIRMWARE_NOTIFY_REBOOT, NULL, 0); + + return 0; + } +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -96,6 +96,8 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_GET_POE_HAT_VAL = 0x00030049, + RPI_FIRMWARE_SET_POE_HAT_VAL = 0x00030050, + RPI_FIRMWARE_NOTIFY_XHCI_RESET = 0x00030058, ++ RPI_FIRMWARE_GET_REBOOT_FLAGS = 0x00030064, ++ RPI_FIRMWARE_SET_REBOOT_FLAGS = 0x00038064, + + /* Dispmanx TAGS */ + RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, diff --git a/target/linux/bcm27xx/patches-5.4/950-1010-phy-broadcom-split-out-the-BCM54213PE-from-the-BCM54.patch b/target/linux/bcm27xx/patches-5.4/950-1010-phy-broadcom-split-out-the-BCM54213PE-from-the-BCM54.patch new file mode 100644 index 0000000000..cf376b909e --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1010-phy-broadcom-split-out-the-BCM54213PE-from-the-BCM54.patch @@ -0,0 +1,71 @@ +From 797cf96a09d1d4ee851a3998e590f7641cfc9b9a Mon Sep 17 00:00:00 2001 +From: Jonathan Bell <jonathan@raspberrypi.org> +Date: Tue, 14 May 2019 17:00:41 +0100 +Subject: [PATCH] phy: broadcom: split out the BCM54213PE from the + BCM54210E IDs + +The last nibble is a revision ID, and the 54213pe is a later rev +than the 54210e. Running the 54210e setup code on a 54213pe results +in a broken RGMII interface. + +Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org> +--- + drivers/net/phy/broadcom.c | 16 +++++++++++++--- + include/linux/brcmphy.h | 1 + + 2 files changed, 14 insertions(+), 3 deletions(-) + +--- a/drivers/net/phy/broadcom.c ++++ b/drivers/net/phy/broadcom.c +@@ -213,7 +213,8 @@ static void bcm54xx_adjust_rxrefclk(stru + /* Abort if we are using an untested phy. */ + if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 && + BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 && +- BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M) ++ BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M && ++ BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54213PE) + return; + + val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR3); +@@ -620,13 +621,21 @@ static struct phy_driver broadcom_driver + .config_intr = bcm_phy_config_intr, + }, { + .phy_id = PHY_ID_BCM54210E, +- .phy_id_mask = 0xfffffff0, ++ .phy_id_mask = 0xffffffff, + .name = "Broadcom BCM54210E", + /* PHY_GBIT_FEATURES */ + .config_init = bcm54xx_config_init, + .ack_interrupt = bcm_phy_ack_intr, + .config_intr = bcm_phy_config_intr, + }, { ++ .phy_id = PHY_ID_BCM54213PE, ++ .phy_id_mask = 0xffffffff, ++ .name = "Broadcom BCM54213PE", ++ /* PHY_GBIT_FEATURES */ ++ .config_init = bcm54xx_config_init, ++ .ack_interrupt = bcm_phy_ack_intr, ++ .config_intr = bcm_phy_config_intr, ++}, { + .phy_id = PHY_ID_BCM5461, + .phy_id_mask = 0xfffffff0, + .name = "Broadcom BCM5461", +@@ -753,7 +762,8 @@ module_phy_driver(broadcom_drivers); + static struct mdio_device_id __maybe_unused broadcom_tbl[] = { + { PHY_ID_BCM5411, 0xfffffff0 }, + { PHY_ID_BCM5421, 0xfffffff0 }, +- { PHY_ID_BCM54210E, 0xfffffff0 }, ++ { PHY_ID_BCM54210E, 0xffffffff }, ++ { PHY_ID_BCM54213PE, 0xffffffff }, + { PHY_ID_BCM5461, 0xfffffff0 }, + { PHY_ID_BCM54612E, 0xfffffff0 }, + { PHY_ID_BCM54616S, 0xfffffff0 }, +--- a/include/linux/brcmphy.h ++++ b/include/linux/brcmphy.h +@@ -20,6 +20,7 @@ + #define PHY_ID_BCM5411 0x00206070 + #define PHY_ID_BCM5421 0x002060e0 + #define PHY_ID_BCM54210E 0x600d84a0 ++#define PHY_ID_BCM54213PE 0x600d84a2 + #define PHY_ID_BCM5464 0x002060b0 + #define PHY_ID_BCM5461 0x002060c0 + #define PHY_ID_BCM54612E 0x03625e60 diff --git a/target/linux/bcm27xx/patches-5.4/950-1011-phy-broadcom-Add-bcm54213pe-configuration.patch b/target/linux/bcm27xx/patches-5.4/950-1011-phy-broadcom-Add-bcm54213pe-configuration.patch new file mode 100644 index 0000000000..d4f6c24ccf --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1011-phy-broadcom-Add-bcm54213pe-configuration.patch @@ -0,0 +1,35 @@ +From 9c08f4ff9f8f9e56011395dc064100ff6f139bdc Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Thu, 29 Oct 2020 14:10:56 +0000 +Subject: [PATCH] phy: broadcom: Add bcm54213pe configuration + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/net/phy/broadcom.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/net/phy/broadcom.c ++++ b/drivers/net/phy/broadcom.c +@@ -43,6 +43,11 @@ static int bcm54210e_config_init(struct + return 0; + } + ++static int bcm54213pe_config_init(struct phy_device *phydev) ++{ ++ return bcm54210e_config_init(phydev); ++} ++ + static int bcm54612e_config_init(struct phy_device *phydev) + { + int reg; +@@ -304,6 +309,10 @@ static int bcm54xx_config_init(struct ph + err = bcm54210e_config_init(phydev); + if (err) + return err; ++ } else if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54213PE) { ++ err = bcm54213pe_config_init(phydev); ++ if (err) ++ return err; + } else if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54612E) { + err = bcm54612e_config_init(phydev); + if (err) diff --git a/target/linux/bcm27xx/patches-5.4/950-1012-Allo-boss2-driver.patch b/target/linux/bcm27xx/patches-5.4/950-1012-Allo-boss2-driver.patch new file mode 100644 index 0000000000..aacbc7dcbe --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1012-Allo-boss2-driver.patch @@ -0,0 +1,1185 @@ +From 51ce8712f4633484615b9982dc48038b3b86e235 Mon Sep 17 00:00:00 2001 +From: Sudeep <sudeepkumar@cem-solutions.net> +Date: Fri, 23 Oct 2020 15:47:17 +0530 +Subject: [PATCH] Allo boss2 driver + +Signed-off-by: Sudeep <sudeepkumar@cem-solutions.net> +--- + sound/soc/bcm/Kconfig | 9 + + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/allo-boss2-dac.c | 1133 ++++++++++++++++++++++++++++++++ + 3 files changed, 1144 insertions(+) + create mode 100644 sound/soc/bcm/allo-boss2-dac.c + +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -258,6 +258,15 @@ config SND_BCM2708_SOC_ALLO_BOSS_DAC + help + Say Y or M if you want to add support for Allo Boss DAC. + ++config SND_BCM2708_SOC_ALLO_BOSS2_DAC ++ tristate "Support for Allo Boss2 DAC" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ depends on I2C ++ select REGMAP_I2C ++ select SND_AUDIO_GRAPH_CARD ++ help ++ Say Y or M if you want to add support for Allo Boss2 DAC. ++ + config SND_BCM2708_SOC_ALLO_DIGIONE + tristate "Support for Allo DigiOne" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -33,6 +33,7 @@ snd-soc-digidac1-soundcard-objs := digid + snd-soc-dionaudio-loco-objs := dionaudio_loco.o + snd-soc-dionaudio-loco-v2-objs := dionaudio_loco-v2.o + snd-soc-allo-boss-dac-objs := allo-boss-dac.o ++snd-soc-allo-boss2-dac-objs := allo-boss2-dac.o + snd-soc-allo-piano-dac-objs := allo-piano-dac.o + snd-soc-allo-piano-dac-plus-objs := allo-piano-dac-plus.o + snd-soc-allo-katana-codec-objs := allo-katana-codec.o +@@ -63,6 +64,7 @@ obj-$(CONFIG_SND_DIGIDAC1_SOUNDCARD) += + 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_BOSS_DAC) += snd-soc-allo-boss-dac.o ++obj-$(CONFIG_SND_BCM2708_SOC_ALLO_BOSS2_DAC) += snd-soc-allo-boss2-dac.o + obj-$(CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC) += snd-soc-allo-piano-dac.o + obj-$(CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC_PLUS) += snd-soc-allo-piano-dac-plus.o + obj-$(CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC) += snd-soc-allo-katana-codec.o +--- /dev/null ++++ b/sound/soc/bcm/allo-boss2-dac.c +@@ -0,0 +1,1133 @@ ++/* ++ * Driver for the ALLO KATANA CODEC ++ * ++ * Author: Jaikumar <sudeepkumar@cem-solutions.net> ++ * Copyright 2018 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/delay.h> ++#include <linux/gpio.h> ++#include <linux/gpio/consumer.h> ++#include <linux/platform_device.h> ++#include <linux/pm.h> ++#include <linux/i2c.h> ++#include <linux/of_device.h> ++#include <linux/regmap.h> ++#include <linux/slab.h> ++#include <sound/core.h> ++#include <sound/pcm.h> ++#include <sound/pcm_params.h> ++#include <sound/soc.h> ++#include <sound/soc-dapm.h> ++#include <sound/initval.h> ++#include <sound/tlv.h> ++#include <linux/of_gpio.h> ++#include <linux/regulator/consumer.h> ++#include <linux/pm_runtime.h> ++#include <linux/of_irq.h> ++#include <linux/completion.h> ++#include <linux/mutex.h> ++#include <linux/workqueue.h> ++#include <sound/jack.h> ++ ++#include "../codecs/cs43130.h" ++ ++#include <linux/clk.h> ++#include <linux/gcd.h> ++#define DEBUG ++ ++#define CS43130_DSD_EN_MASK 0x10 ++#define CS43130_PDN_DONE_INT_MASK 0x00 ++ ++static struct gpio_desc *snd_allo_clk44gpio; ++static struct gpio_desc *snd_allo_clk48gpio; ++ ++struct cs43130_priv { ++ struct snd_soc_component *component; ++ struct regmap *regmap; ++ struct regulator_bulk_data supplies[CS43130_NUM_SUPPLIES]; ++ struct gpio_desc *reset_gpio; ++ unsigned int dev_id; /* codec device ID */ ++ int xtal_ibias; ++ /* shared by both DAIs */ ++ struct mutex clk_mutex; ++ int clk_req; ++ bool pll_bypass; ++ struct completion xtal_rdy; ++ struct completion pll_rdy; ++ unsigned int mclk; ++ unsigned int mclk_int; ++ int mclk_int_src; ++ ++ /* DAI specific */ ++ struct cs43130_dai dais[CS43130_DAI_ID_MAX]; ++ ++ /* HP load specific */ ++ bool dc_meas; ++ bool ac_meas; ++ bool hpload_done; ++ struct completion hpload_evt; ++ unsigned int hpload_stat; ++ u16 hpload_dc[2]; ++ u16 dc_threshold[CS43130_DC_THRESHOLD]; ++ u16 ac_freq[CS43130_AC_FREQ]; ++ u16 hpload_ac[CS43130_AC_FREQ][2]; ++ struct workqueue_struct *wq; ++ struct work_struct work; ++ struct snd_soc_jack jack; ++}; ++ ++static const struct reg_default cs43130_reg_defaults[] = { ++ {CS43130_SYS_CLK_CTL_1, 0x06}, ++ {CS43130_SP_SRATE, 0x01}, ++ {CS43130_SP_BITSIZE, 0x05}, ++ {CS43130_PAD_INT_CFG, 0x03}, ++ {CS43130_PWDN_CTL, 0xFE}, ++ {CS43130_CRYSTAL_SET, 0x04}, ++ {CS43130_PLL_SET_1, 0x00}, ++ {CS43130_PLL_SET_2, 0x00}, ++ {CS43130_PLL_SET_3, 0x00}, ++ {CS43130_PLL_SET_4, 0x00}, ++ {CS43130_PLL_SET_5, 0x40}, ++ {CS43130_PLL_SET_6, 0x10}, ++ {CS43130_PLL_SET_7, 0x80}, ++ {CS43130_PLL_SET_8, 0x03}, ++ {CS43130_PLL_SET_9, 0x02}, ++ {CS43130_PLL_SET_10, 0x02}, ++ {CS43130_CLKOUT_CTL, 0x00}, ++ {CS43130_ASP_NUM_1, 0x01}, ++ {CS43130_ASP_NUM_2, 0x00}, ++ {CS43130_ASP_DEN_1, 0x08}, ++ {CS43130_ASP_DEN_2, 0x00}, ++ {CS43130_ASP_LRCK_HI_TIME_1, 0x1F}, ++ {CS43130_ASP_LRCK_HI_TIME_2, 0x00}, ++ {CS43130_ASP_LRCK_PERIOD_1, 0x3F}, ++ {CS43130_ASP_LRCK_PERIOD_2, 0x00}, ++ {CS43130_ASP_CLOCK_CONF, 0x0C}, ++ {CS43130_ASP_FRAME_CONF, 0x0A}, ++ {CS43130_XSP_NUM_1, 0x01}, ++ {CS43130_XSP_NUM_2, 0x00}, ++ {CS43130_XSP_DEN_1, 0x02}, ++ {CS43130_XSP_DEN_2, 0x00}, ++ {CS43130_XSP_LRCK_HI_TIME_1, 0x1F}, ++ {CS43130_XSP_LRCK_HI_TIME_2, 0x00}, ++ {CS43130_XSP_LRCK_PERIOD_1, 0x3F}, ++ {CS43130_XSP_LRCK_PERIOD_2, 0x00}, ++ {CS43130_XSP_CLOCK_CONF, 0x0C}, ++ {CS43130_XSP_FRAME_CONF, 0x0A}, ++ {CS43130_ASP_CH_1_LOC, 0x00}, ++ {CS43130_ASP_CH_2_LOC, 0x00}, ++ {CS43130_ASP_CH_1_SZ_EN, 0x06}, ++ {CS43130_ASP_CH_2_SZ_EN, 0x0E}, ++ {CS43130_XSP_CH_1_LOC, 0x00}, ++ {CS43130_XSP_CH_2_LOC, 0x00}, ++ {CS43130_XSP_CH_1_SZ_EN, 0x06}, ++ {CS43130_XSP_CH_2_SZ_EN, 0x0E}, ++ {CS43130_DSD_VOL_B, 0x78}, ++ {CS43130_DSD_VOL_A, 0x78}, ++ {CS43130_DSD_PATH_CTL_1, 0xA8}, ++ {CS43130_DSD_INT_CFG, 0x00}, ++ {CS43130_DSD_PATH_CTL_2, 0x02}, ++ {CS43130_DSD_PCM_MIX_CTL, 0x00}, ++ {CS43130_DSD_PATH_CTL_3, 0x40}, ++ {CS43130_HP_OUT_CTL_1, 0x30}, ++ {CS43130_PCM_FILT_OPT, 0x02}, ++ {CS43130_PCM_VOL_B, 0x78}, ++ {CS43130_PCM_VOL_A, 0x78}, ++ {CS43130_PCM_PATH_CTL_1, 0xA8}, ++ {CS43130_PCM_PATH_CTL_2, 0x00}, ++ {CS43130_CLASS_H_CTL, 0x1E}, ++ {CS43130_HP_DETECT, 0x04}, ++ {CS43130_HP_LOAD_1, 0x00}, ++ {CS43130_HP_MEAS_LOAD_1, 0x00}, ++ {CS43130_HP_MEAS_LOAD_2, 0x00}, ++ {CS43130_INT_MASK_1, 0xFF}, ++ {CS43130_INT_MASK_2, 0xFF}, ++ {CS43130_INT_MASK_3, 0xFF}, ++ {CS43130_INT_MASK_4, 0xFF}, ++ {CS43130_INT_MASK_5, 0xFF}, ++}; ++static bool cs43130_volatile_register(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5: ++ case CS43130_HP_DC_STAT_1 ... CS43130_HP_DC_STAT_2: ++ case CS43130_HP_AC_STAT_1 ... CS43130_HP_AC_STAT_2: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static const char * const pcm_spd_texts[] = { ++ "Fast", ++ "Slow", ++}; ++ ++static SOC_ENUM_SINGLE_DECL(pcm_spd_enum, CS43130_PCM_FILT_OPT, 7, ++ pcm_spd_texts); ++ ++static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(master_tlv, -12750, 0); ++ ++static const struct snd_kcontrol_new cs43130_controls[] = { ++ SOC_DOUBLE_R_TLV("Master Playback Volume", CS43130_PCM_VOL_B, ++ CS43130_PCM_VOL_A, 0, 255, 1, master_tlv), ++ SOC_DOUBLE("Master Playback Switch", CS43130_PCM_PATH_CTL_1, ++ 0, 1, 1, 1), ++ SOC_DOUBLE_R_TLV("Digital Playback Volume", CS43130_DSD_VOL_B, ++ CS43130_DSD_VOL_A, 0, 255, 1, master_tlv), ++ SOC_DOUBLE("Digital Playback Switch", CS43130_DSD_PATH_CTL_1, ++ 0, 1, 1, 1), ++ SOC_SINGLE("HV_Enable", CS43130_HP_OUT_CTL_1, 0, 1, 0), ++ SOC_ENUM("PCM Filter Speed", pcm_spd_enum), ++ SOC_SINGLE("PCM Phase Compensation", CS43130_PCM_FILT_OPT, 6, 1, 0), ++ SOC_SINGLE("PCM Nonoversample Emulate", CS43130_PCM_FILT_OPT, 5, 1, 0), ++ SOC_SINGLE("PCM High-pass Filter", CS43130_PCM_FILT_OPT, 1, 1, 0), ++ SOC_SINGLE("PCM De-emphasis Filter", CS43130_PCM_FILT_OPT, 0, 1, 0), ++}; ++ ++static bool cs43130_readable_register(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case CS43130_DEVID_AB ... CS43130_SYS_CLK_CTL_1: ++ case CS43130_SP_SRATE ... CS43130_PAD_INT_CFG: ++ case CS43130_PWDN_CTL: ++ case CS43130_CRYSTAL_SET: ++ case CS43130_PLL_SET_1 ... CS43130_PLL_SET_5: ++ case CS43130_PLL_SET_6: ++ case CS43130_PLL_SET_7: ++ case CS43130_PLL_SET_8: ++ case CS43130_PLL_SET_9: ++ case CS43130_PLL_SET_10: ++ case CS43130_CLKOUT_CTL: ++ case CS43130_ASP_NUM_1 ... CS43130_ASP_FRAME_CONF: ++ case CS43130_XSP_NUM_1 ... CS43130_XSP_FRAME_CONF: ++ case CS43130_ASP_CH_1_LOC: ++ case CS43130_ASP_CH_2_LOC: ++ case CS43130_ASP_CH_1_SZ_EN: ++ case CS43130_ASP_CH_2_SZ_EN: ++ case CS43130_XSP_CH_1_LOC: ++ case CS43130_XSP_CH_2_LOC: ++ case CS43130_XSP_CH_1_SZ_EN: ++ case CS43130_XSP_CH_2_SZ_EN: ++ case CS43130_DSD_VOL_B ... CS43130_DSD_PATH_CTL_3: ++ case CS43130_HP_OUT_CTL_1: ++ case CS43130_PCM_FILT_OPT ... CS43130_PCM_PATH_CTL_2: ++ case CS43130_CLASS_H_CTL: ++ case CS43130_HP_DETECT: ++ case CS43130_HP_STATUS: ++ case CS43130_HP_LOAD_1: ++ case CS43130_HP_MEAS_LOAD_1: ++ case CS43130_HP_MEAS_LOAD_2: ++ case CS43130_HP_DC_STAT_1: ++ case CS43130_HP_DC_STAT_2: ++ case CS43130_HP_AC_STAT_1: ++ case CS43130_HP_AC_STAT_2: ++ case CS43130_HP_LOAD_STAT: ++ case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5: ++ case CS43130_INT_MASK_1 ... CS43130_INT_MASK_5: ++ return true; ++ default: ++ return false; ++ } ++} ++static bool cs43130_precious_register(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5: ++ return true; ++ default: ++ return false; ++ } ++} ++static int cs43130_pcm_pdn(struct snd_soc_component *component) ++{ ++ struct cs43130_priv *cs43130 = ++ snd_soc_component_get_drvdata(component); ++ int ret; ++ unsigned int reg, pdn_int; ++ ++ regmap_write(cs43130->regmap, CS43130_DSD_PATH_CTL_2, 0x02); ++ regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, ++ CS43130_PDN_DONE_INT_MASK, 0); ++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, ++ CS43130_PDN_HP_MASK, 1 << CS43130_PDN_HP_SHIFT); ++ usleep_range(10, 50); ++ ret = regmap_read(cs43130->regmap, CS43130_INT_STATUS_1, ®); ++ pdn_int = reg & 0xFE; ++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, ++ CS43130_PDN_ASP_MASK, 1 << CS43130_PDN_ASP_SHIFT); ++ return 0; ++ ++} ++static int cs43130_pwr_up_asp_dac(struct snd_soc_component *component) ++{ ++ struct cs43130_priv *cs43130 = ++ snd_soc_component_get_drvdata(component); ++ ++ regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG, ++ CS43130_ASP_3ST_MASK, 0); ++ regmap_write(cs43130->regmap, CS43130_DXD1, 0x99); ++ regmap_write(cs43130->regmap, CS43130_DXD13, 0x20); ++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, ++ CS43130_PDN_ASP_MASK, 0); ++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, ++ CS43130_PDN_HP_MASK, 0); ++ usleep_range(10000, 12000); ++ regmap_write(cs43130->regmap, CS43130_DXD1, 0x00); ++ regmap_write(cs43130->regmap, CS43130_DXD13, 0x00); ++ return 0; ++} ++static int cs43130_change_clksrc(struct snd_soc_component *component, ++ enum cs43130_mclk_src_sel src) ++{ ++ int ret; ++ struct cs43130_priv *cs43130 = ++ snd_soc_component_get_drvdata(component); ++ int mclk_int_decoded; ++ ++ if (src == cs43130->mclk_int_src) { ++ /* clk source has not changed */ ++ return 0; ++ } ++ switch (cs43130->mclk_int) { ++ case CS43130_MCLK_22M: ++ mclk_int_decoded = CS43130_MCLK_22P5; ++ break; ++ case CS43130_MCLK_24M: ++ mclk_int_decoded = CS43130_MCLK_24P5; ++ break; ++ default: ++ dev_err(component->dev, "Invalid MCLK INT freq: %u\n", ++ cs43130->mclk_int); ++ return -EINVAL; ++ } ++ ++ switch (src) { ++ case CS43130_MCLK_SRC_EXT: ++ cs43130->pll_bypass = true; ++ cs43130->mclk_int_src = CS43130_MCLK_SRC_EXT; ++ if (cs43130->xtal_ibias == CS43130_XTAL_UNUSED) { ++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, ++ CS43130_PDN_XTAL_MASK, ++ 1 << CS43130_PDN_XTAL_SHIFT); ++ } else { ++ reinit_completion(&cs43130->xtal_rdy); ++ regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, ++ CS43130_XTAL_RDY_INT_MASK, 0); ++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, ++ CS43130_PDN_XTAL_MASK, 0); ++ ret = wait_for_completion_timeout(&cs43130->xtal_rdy, ++ msecs_to_jiffies(100)); ++ regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, ++ CS43130_XTAL_RDY_INT_MASK, ++ 1 << CS43130_XTAL_RDY_INT_SHIFT); ++ if (ret == 0) { ++ dev_err(component->dev, "Timeout waiting for XTAL_READY interrupt\n"); ++ return -ETIMEDOUT; ++ } ++ } ++ regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1, ++ CS43130_MCLK_SRC_SEL_MASK, ++ src << CS43130_MCLK_SRC_SEL_SHIFT); ++ regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1, ++ CS43130_MCLK_INT_MASK, ++ mclk_int_decoded << CS43130_MCLK_INT_SHIFT); ++ usleep_range(150, 200); ++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, ++ CS43130_PDN_PLL_MASK, ++ 1 << CS43130_PDN_PLL_SHIFT); ++ break; ++ case CS43130_MCLK_SRC_RCO: ++ cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO; ++ ++ regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1, ++ CS43130_MCLK_SRC_SEL_MASK, ++ src << CS43130_MCLK_SRC_SEL_SHIFT); ++ regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1, ++ CS43130_MCLK_INT_MASK, ++ CS43130_MCLK_22P5 << CS43130_MCLK_INT_SHIFT); ++ usleep_range(150, 200); ++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, ++ CS43130_PDN_XTAL_MASK, ++ 1 << CS43130_PDN_XTAL_SHIFT); ++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, ++ CS43130_PDN_PLL_MASK, ++ 1 << CS43130_PDN_PLL_SHIFT); ++ break; ++ default: ++ dev_err(component->dev, "Invalid MCLK source value\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++static const struct cs43130_bitwidth_map cs43130_bitwidth_table[] = { ++ {8, CS43130_SP_BIT_SIZE_8, CS43130_CH_BIT_SIZE_8}, ++ {16, CS43130_SP_BIT_SIZE_16, CS43130_CH_BIT_SIZE_16}, ++ {24, CS43130_SP_BIT_SIZE_24, CS43130_CH_BIT_SIZE_24}, ++ {32, CS43130_SP_BIT_SIZE_32, CS43130_CH_BIT_SIZE_32}, ++}; ++ ++static const struct cs43130_bitwidth_map *cs43130_get_bitwidth_table( ++ unsigned int bitwidth) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(cs43130_bitwidth_table); i++) { ++ if (cs43130_bitwidth_table[i].bitwidth == bitwidth) ++ return &cs43130_bitwidth_table[i]; ++ } ++ ++ return NULL; ++} ++static int cs43130_set_bitwidth(int dai_id, unsigned int bitwidth_dai, ++ struct regmap *regmap) ++{ ++ const struct cs43130_bitwidth_map *bw_map; ++ ++ bw_map = cs43130_get_bitwidth_table(bitwidth_dai); ++ if (!bw_map) ++ return -EINVAL; ++ ++ switch (dai_id) { ++ case CS43130_ASP_PCM_DAI: ++ case CS43130_ASP_DOP_DAI: ++ regmap_update_bits(regmap, CS43130_ASP_CH_1_SZ_EN, ++ CS43130_CH_BITSIZE_MASK, bw_map->ch_bit); ++ regmap_update_bits(regmap, CS43130_ASP_CH_2_SZ_EN, ++ CS43130_CH_BITSIZE_MASK, bw_map->ch_bit); ++ regmap_update_bits(regmap, CS43130_SP_BITSIZE, ++ CS43130_ASP_BITSIZE_MASK, bw_map->sp_bit); ++ break; ++ case CS43130_XSP_DOP_DAI: ++ regmap_update_bits(regmap, CS43130_XSP_CH_1_SZ_EN, ++ CS43130_CH_BITSIZE_MASK, bw_map->ch_bit); ++ regmap_update_bits(regmap, CS43130_XSP_CH_2_SZ_EN, ++ CS43130_CH_BITSIZE_MASK, bw_map->ch_bit); ++ regmap_update_bits(regmap, CS43130_SP_BITSIZE, ++ CS43130_XSP_BITSIZE_MASK, bw_map->sp_bit << ++ CS43130_XSP_BITSIZE_SHIFT); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++static const struct cs43130_rate_map cs43130_rate_table[] = { ++ {32000, CS43130_ASP_SPRATE_32K}, ++ {44100, CS43130_ASP_SPRATE_44_1K}, ++ {48000, CS43130_ASP_SPRATE_48K}, ++ {88200, CS43130_ASP_SPRATE_88_2K}, ++ {96000, CS43130_ASP_SPRATE_96K}, ++ {176400, CS43130_ASP_SPRATE_176_4K}, ++ {192000, CS43130_ASP_SPRATE_192K}, ++ {352800, CS43130_ASP_SPRATE_352_8K}, ++ {384000, CS43130_ASP_SPRATE_384K}, ++}; ++ ++static const struct cs43130_rate_map *cs43130_get_rate_table(int fs) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(cs43130_rate_table); i++) { ++ if (cs43130_rate_table[i].fs == fs) ++ return &cs43130_rate_table[i]; ++ } ++ ++ return NULL; ++} ++ ++static const struct cs43130_clk_gen *cs43130_get_clk_gen(int mclk_int, int fs, ++ const struct cs43130_clk_gen *clk_gen_table, int len_clk_gen_table) ++{ ++ int i; ++ ++ for (i = 0; i < len_clk_gen_table; i++) { ++ if (clk_gen_table[i].mclk_int == mclk_int && ++ clk_gen_table[i].fs == fs) ++ return &clk_gen_table[i]; ++ } ++ return NULL; ++} ++ ++static int cs43130_set_sp_fmt(int dai_id, unsigned int bitwidth_sclk, ++ struct snd_pcm_hw_params *params, ++ struct cs43130_priv *cs43130) ++{ ++ u16 frm_size; ++ u16 hi_size; ++ u8 frm_delay; ++ u8 frm_phase; ++ u8 frm_data; ++ u8 sclk_edge; ++ u8 lrck_edge; ++ u8 clk_data; ++ u8 loc_ch1; ++ u8 loc_ch2; ++ u8 dai_mode_val; ++ const struct cs43130_clk_gen *clk_gen; ++ ++ switch (cs43130->dais[dai_id].dai_format) { ++ case SND_SOC_DAIFMT_I2S: ++ hi_size = bitwidth_sclk; ++ frm_delay = 2; ++ frm_phase = 0; ++ break; ++ case SND_SOC_DAIFMT_LEFT_J: ++ hi_size = bitwidth_sclk; ++ frm_delay = 2; ++ frm_phase = 1; ++ break; ++ case SND_SOC_DAIFMT_DSP_A: ++ hi_size = 1; ++ frm_delay = 2; ++ frm_phase = 1; ++ break; ++ case SND_SOC_DAIFMT_DSP_B: ++ hi_size = 1; ++ frm_delay = 0; ++ frm_phase = 1; ++ break; ++ default: ++ return -EINVAL; ++ } ++ switch (cs43130->dais[dai_id].dai_mode) { ++ case SND_SOC_DAIFMT_CBS_CFS: ++ dai_mode_val = 0; ++ break; ++ case SND_SOC_DAIFMT_CBM_CFM: ++ dai_mode_val = 1; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ frm_size = bitwidth_sclk * params_channels(params); ++ sclk_edge = 1; ++ lrck_edge = 0; ++ loc_ch1 = 0; ++ loc_ch2 = bitwidth_sclk * (params_channels(params) - 1); ++ ++ frm_data = frm_delay & CS43130_SP_FSD_MASK; ++ frm_data |= (frm_phase << CS43130_SP_STP_SHIFT) & CS43130_SP_STP_MASK; ++ ++ clk_data = lrck_edge & CS43130_SP_LCPOL_IN_MASK; ++ clk_data |= (lrck_edge << CS43130_SP_LCPOL_OUT_SHIFT) & ++ CS43130_SP_LCPOL_OUT_MASK; ++ clk_data |= (sclk_edge << CS43130_SP_SCPOL_IN_SHIFT) & ++ CS43130_SP_SCPOL_IN_MASK; ++ clk_data |= (sclk_edge << CS43130_SP_SCPOL_OUT_SHIFT) & ++ CS43130_SP_SCPOL_OUT_MASK; ++ clk_data |= (dai_mode_val << CS43130_SP_MODE_SHIFT) & ++ CS43130_SP_MODE_MASK; ++ switch (dai_id) { ++ case CS43130_ASP_PCM_DAI: ++ case CS43130_ASP_DOP_DAI: ++ regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_PERIOD_1, ++ CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >> ++ CS43130_SP_LCPR_LSB_DATA_SHIFT); ++ regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_PERIOD_2, ++ CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >> ++ CS43130_SP_LCPR_MSB_DATA_SHIFT); ++ regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_HI_TIME_1, ++ CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >> ++ CS43130_SP_LCHI_LSB_DATA_SHIFT); ++ regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_HI_TIME_2, ++ CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >> ++ CS43130_SP_LCHI_MSB_DATA_SHIFT); ++ regmap_write(cs43130->regmap, CS43130_ASP_FRAME_CONF, frm_data); ++ regmap_write(cs43130->regmap, CS43130_ASP_CH_1_LOC, loc_ch1); ++ regmap_write(cs43130->regmap, CS43130_ASP_CH_2_LOC, loc_ch2); ++ regmap_update_bits(cs43130->regmap, CS43130_ASP_CH_1_SZ_EN, ++ CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT); ++ regmap_update_bits(cs43130->regmap, CS43130_ASP_CH_2_SZ_EN, ++ CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT); ++ regmap_write(cs43130->regmap, CS43130_ASP_CLOCK_CONF, clk_data); ++ break; ++ case CS43130_XSP_DOP_DAI: ++ regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_PERIOD_1, ++ CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >> ++ CS43130_SP_LCPR_LSB_DATA_SHIFT); ++ regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_PERIOD_2, ++ CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >> ++ CS43130_SP_LCPR_MSB_DATA_SHIFT); ++ regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_HI_TIME_1, ++ CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >> ++ CS43130_SP_LCHI_LSB_DATA_SHIFT); ++ regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_HI_TIME_2, ++ CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >> ++ CS43130_SP_LCHI_MSB_DATA_SHIFT); ++ regmap_write(cs43130->regmap, CS43130_XSP_FRAME_CONF, frm_data); ++ regmap_write(cs43130->regmap, CS43130_XSP_CH_1_LOC, loc_ch1); ++ regmap_write(cs43130->regmap, CS43130_XSP_CH_2_LOC, loc_ch2); ++ regmap_update_bits(cs43130->regmap, CS43130_XSP_CH_1_SZ_EN, ++ CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT); ++ regmap_update_bits(cs43130->regmap, CS43130_XSP_CH_2_SZ_EN, ++ CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT); ++ regmap_write(cs43130->regmap, CS43130_XSP_CLOCK_CONF, clk_data); ++ break; ++ default: ++ return -EINVAL; ++ } ++ switch (frm_size) { ++ case 16: ++ clk_gen = cs43130_get_clk_gen(cs43130->mclk_int, ++ params_rate(params), ++ cs43130_16_clk_gen, ++ ARRAY_SIZE(cs43130_16_clk_gen)); ++ break; ++ case 32: ++ clk_gen = cs43130_get_clk_gen(cs43130->mclk_int, ++ params_rate(params), ++ cs43130_32_clk_gen, ++ ARRAY_SIZE(cs43130_32_clk_gen)); ++ break; ++ case 48: ++ clk_gen = cs43130_get_clk_gen(cs43130->mclk_int, ++ params_rate(params), ++ cs43130_48_clk_gen, ++ ARRAY_SIZE(cs43130_48_clk_gen)); ++ break; ++ case 64: ++ clk_gen = cs43130_get_clk_gen(cs43130->mclk_int, ++ params_rate(params), ++ cs43130_64_clk_gen, ++ ARRAY_SIZE(cs43130_64_clk_gen)); ++ break; ++ default: ++ return -EINVAL; ++ } ++ if (!clk_gen) ++ return -EINVAL; ++ switch (dai_id) { ++ case CS43130_ASP_PCM_DAI: ++ case CS43130_ASP_DOP_DAI: ++ regmap_write(cs43130->regmap, CS43130_ASP_DEN_1, ++ (clk_gen->den & CS43130_SP_M_LSB_DATA_MASK) >> ++ CS43130_SP_M_LSB_DATA_SHIFT); ++ regmap_write(cs43130->regmap, CS43130_ASP_DEN_2, ++ (clk_gen->den & CS43130_SP_M_MSB_DATA_MASK) >> ++ CS43130_SP_M_MSB_DATA_SHIFT); ++ regmap_write(cs43130->regmap, CS43130_ASP_NUM_1, ++ (clk_gen->num & CS43130_SP_N_LSB_DATA_MASK) >> ++ CS43130_SP_N_LSB_DATA_SHIFT); ++ regmap_write(cs43130->regmap, CS43130_ASP_NUM_2, ++ (clk_gen->num & CS43130_SP_N_MSB_DATA_MASK) >> ++ CS43130_SP_N_MSB_DATA_SHIFT); ++ break; ++ case CS43130_XSP_DOP_DAI: ++ regmap_write(cs43130->regmap, CS43130_XSP_DEN_1, ++ (clk_gen->den & CS43130_SP_M_LSB_DATA_MASK) >> ++ CS43130_SP_M_LSB_DATA_SHIFT); ++ regmap_write(cs43130->regmap, CS43130_XSP_DEN_2, ++ (clk_gen->den & CS43130_SP_M_MSB_DATA_MASK) >> ++ CS43130_SP_M_MSB_DATA_SHIFT); ++ regmap_write(cs43130->regmap, CS43130_XSP_NUM_1, ++ (clk_gen->num & CS43130_SP_N_LSB_DATA_MASK) >> ++ CS43130_SP_N_LSB_DATA_SHIFT); ++ regmap_write(cs43130->regmap, CS43130_XSP_NUM_2, ++ (clk_gen->num & CS43130_SP_N_MSB_DATA_MASK) >> ++ CS43130_SP_N_MSB_DATA_SHIFT); ++ break; ++ default: ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static int cs43130_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_component *component = dai->component; ++ struct cs43130_priv *cs43130 = ++ snd_soc_component_get_drvdata(component); ++ const struct cs43130_rate_map *rate_map; ++ unsigned int sclk = cs43130->dais[dai->id].sclk; ++ unsigned int bitwidth_sclk; ++ unsigned int bitwidth_dai = (unsigned int)(params_width(params)); ++ unsigned int dop_rate = (unsigned int)(params_rate(params)); ++ unsigned int required_clk, ret; ++ u8 dsd_speed; ++ ++ cs43130->pll_bypass = true; ++ cs43130_pcm_pdn(component); ++ mutex_lock(&cs43130->clk_mutex); ++ if (!cs43130->clk_req) { ++ /* no DAI is currently using clk */ ++ if (!(CS43130_MCLK_22M % params_rate(params))) { ++ required_clk = CS43130_MCLK_22M; ++ cs43130->mclk_int = CS43130_MCLK_22M; ++ gpiod_set_value_cansleep(snd_allo_clk44gpio, 1); ++ gpiod_set_value_cansleep(snd_allo_clk48gpio, 0); ++ usleep_range(13500, 14000); ++ } else { ++ required_clk = CS43130_MCLK_24M; ++ cs43130->mclk_int = CS43130_MCLK_24M; ++ gpiod_set_value_cansleep(snd_allo_clk48gpio, 1); ++ gpiod_set_value_cansleep(snd_allo_clk44gpio, 0); ++ usleep_range(13500, 14000); ++ } ++ if (cs43130->pll_bypass) ++ cs43130_change_clksrc(component, CS43130_MCLK_SRC_EXT); ++ else ++ cs43130_change_clksrc(component, CS43130_MCLK_SRC_PLL); ++ } ++ ++ cs43130->clk_req++; ++ mutex_unlock(&cs43130->clk_mutex); ++ ++ switch (dai->id) { ++ case CS43130_ASP_DOP_DAI: ++ case CS43130_XSP_DOP_DAI: ++ /* DoP bitwidth is always 24-bit */ ++ bitwidth_dai = 24; ++ sclk = params_rate(params) * bitwidth_dai * ++ params_channels(params); ++ ++ switch (params_rate(params)) { ++ case 176400: ++ dsd_speed = 0; ++ break; ++ case 352800: ++ dsd_speed = 1; ++ break; ++ default: ++ dev_err(component->dev, "Rate(%u) not supported\n", ++ params_rate(params)); ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2, ++ CS43130_DSD_SPEED_MASK, ++ dsd_speed << CS43130_DSD_SPEED_SHIFT); ++ break; ++ case CS43130_ASP_PCM_DAI: ++ rate_map = cs43130_get_rate_table(params_rate(params)); ++ if (!rate_map) ++ return -EINVAL; ++ ++ regmap_write(cs43130->regmap, CS43130_SP_SRATE, rate_map->val); ++ if ((dop_rate == 176400) && (bitwidth_dai == 24)) { ++ dsd_speed = 0; ++ regmap_update_bits(cs43130->regmap, ++ CS43130_DSD_PATH_CTL_2, ++ CS43130_DSD_SPEED_MASK, ++ dsd_speed << CS43130_DSD_SPEED_SHIFT); ++ regmap_update_bits(cs43130->regmap, ++ CS43130_DSD_PATH_CTL_2, ++ CS43130_DSD_SRC_MASK, ++ CS43130_DSD_SRC_ASP << ++ CS43130_DSD_SRC_SHIFT); ++ regmap_update_bits(cs43130->regmap, ++ CS43130_DSD_PATH_CTL_2, ++ CS43130_DSD_EN_MASK, 0x01 << ++ CS43130_DSD_EN_SHIFT); ++ } ++ break; ++ default: ++ dev_err(component->dev, "Invalid DAI (%d)\n", dai->id); ++ return -EINVAL; ++ } ++ ++ switch (dai->id) { ++ case CS43130_ASP_DOP_DAI: ++ regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2, ++ CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_ASP << ++ CS43130_DSD_SRC_SHIFT); ++ regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2, ++ CS43130_DSD_EN_MASK, 0x01 << ++ CS43130_DSD_EN_SHIFT); ++ break; ++ case CS43130_XSP_DOP_DAI: ++ regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2, ++ CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_XSP << ++ CS43130_DSD_SRC_SHIFT); ++ break; ++ } ++ if (!sclk && cs43130->dais[dai->id].dai_mode == ++ SND_SOC_DAIFMT_CBM_CFM) { ++ /* Calculate SCLK in master mode if unassigned */ ++ sclk = params_rate(params) * bitwidth_dai * ++ params_channels(params); ++ } ++ if (!sclk) { ++ /* at this point, SCLK must be set */ ++ dev_err(component->dev, "SCLK freq is not set\n"); ++ return -EINVAL; ++ } ++ ++ bitwidth_sclk = (sclk / params_rate(params)) / params_channels(params); ++ if (bitwidth_sclk < bitwidth_dai) { ++ dev_err(component->dev, "Format not supported: SCLK freq is too low\n"); ++ return -EINVAL; ++ } ++ ++ dev_dbg(component->dev, ++ "sclk = %u, fs = %d, bitwidth_dai = %u\n", ++ sclk, params_rate(params), bitwidth_dai); ++ ++ dev_dbg(component->dev, ++ "bitwidth_sclk = %u, num_ch = %u\n", ++ bitwidth_sclk, params_channels(params)); ++ ++ cs43130_set_bitwidth(dai->id, bitwidth_dai, cs43130->regmap); ++ cs43130_set_sp_fmt(dai->id, bitwidth_sclk, params, cs43130); ++ ret = cs43130_pwr_up_asp_dac(component); ++ return 0; ++} ++ ++static int cs43130_hw_free(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_component *component = dai->component; ++ struct cs43130_priv *cs43130 = ++ snd_soc_component_get_drvdata(component); ++ ++ mutex_lock(&cs43130->clk_mutex); ++ cs43130->clk_req--; ++ if (!cs43130->clk_req) { ++ /* no DAI is currently using clk */ ++ cs43130_change_clksrc(component, CS43130_MCLK_SRC_RCO); ++ cs43130_pcm_pdn(component); ++ } ++ mutex_unlock(&cs43130->clk_mutex); ++ ++ return 0; ++} ++ ++static const unsigned int cs43130_asp_src_rates[] = { ++ 32000, 44100, 48000, 88200, 96000, 176400, 192000 ++}; ++ ++static const struct snd_pcm_hw_constraint_list cs43130_asp_constraints = { ++ .count = ARRAY_SIZE(cs43130_asp_src_rates), ++ .list = cs43130_asp_src_rates, ++}; ++ ++static int cs43130_pcm_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ return snd_pcm_hw_constraint_list(substream->runtime, 0, ++ SNDRV_PCM_HW_PARAM_RATE, ++ &cs43130_asp_constraints); ++} ++ ++static int cs43130_pcm_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) ++{ ++ struct snd_soc_component *component = codec_dai->component; ++ struct cs43130_priv *cs43130 = ++ snd_soc_component_get_drvdata(component); ++ ++ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { ++ case SND_SOC_DAIFMT_CBS_CFS: ++ cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBS_CFS; ++ break; ++ case SND_SOC_DAIFMT_CBM_CFM: ++ cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM; ++ break; ++ default: ++ dev_err(component->dev, "unsupported mode\n"); ++ return -EINVAL; ++ } ++ ++ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { ++ case SND_SOC_DAIFMT_I2S: ++ cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_I2S; ++ break; ++ case SND_SOC_DAIFMT_LEFT_J: ++ cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_LEFT_J; ++ break; ++ default: ++ dev_err(component->dev, ++ "unsupported audio format\n"); ++ return -EINVAL; ++ } ++ ++ dev_dbg(component->dev, "dai_id = %d, dai_mode = %u, dai_format = %u\n", ++ codec_dai->id, ++ cs43130->dais[codec_dai->id].dai_mode, ++ cs43130->dais[codec_dai->id].dai_format); ++ ++ return 0; ++} ++ ++static int cs43130_set_sysclk(struct snd_soc_dai *codec_dai, ++ int clk_id, unsigned int freq, int dir) ++{ ++ struct snd_soc_component *component = codec_dai->component; ++ struct cs43130_priv *cs43130 = ++ snd_soc_component_get_drvdata(component); ++ ++ cs43130->dais[codec_dai->id].sclk = freq; ++ dev_dbg(component->dev, "dai_id = %d, sclk = %u\n", codec_dai->id, ++ cs43130->dais[codec_dai->id].sclk); ++ ++ return 0; ++} ++ ++static int cs43130_component_set_sysclk(struct snd_soc_component *component, ++ int clk_id, int source, ++ unsigned int freq, int dir) ++{ ++ struct cs43130_priv *cs43130 = ++ snd_soc_component_get_drvdata(component); ++ ++ dev_dbg(component->dev, "clk_id = %d, source = %d, freq = %d, dir = %d\n", ++ clk_id, source, freq, dir); ++ ++ switch (freq) { ++ case CS43130_MCLK_22M: ++ case CS43130_MCLK_24M: ++ cs43130->mclk = freq; ++ break; ++ default: ++ dev_err(component->dev, "Invalid MCLK INT freq: %u\n", freq); ++ return -EINVAL; ++ } ++ ++ if (source == CS43130_MCLK_SRC_EXT) { ++ cs43130->pll_bypass = true; ++ } else { ++ dev_err(component->dev, "Invalid MCLK source\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++static u16 const cs43130_ac_freq[CS43130_AC_FREQ] = { ++ 24, ++ 43, ++ 93, ++ 200, ++ 431, ++ 928, ++ 2000, ++ 4309, ++ 9283, ++ 20000, ++}; ++static const struct snd_soc_dai_ops cs43130_dai_ops = { ++ .startup = cs43130_pcm_startup, ++ .hw_params = cs43130_hw_params, ++ .hw_free = cs43130_hw_free, ++ .set_sysclk = cs43130_set_sysclk, ++ .set_fmt = cs43130_pcm_set_fmt, ++}; ++ ++static struct snd_soc_dai_driver cs43130_codec_dai = { ++ .name = "allo-cs43130", ++ .playback = { ++ .stream_name = "Playback", ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = SNDRV_PCM_RATE_CONTINUOUS, ++ .rate_min = 44100, ++ .rate_max = 192000, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE | ++ SNDRV_PCM_FMTBIT_S24_LE | ++ SNDRV_PCM_FMTBIT_S32_LE ++ ++ }, ++ .ops = &cs43130_dai_ops, ++}; ++ ++static struct snd_soc_component_driver cs43130_component_driver = { ++ .idle_bias_on = true, ++ .controls = cs43130_controls, ++ .num_controls = ARRAY_SIZE(cs43130_controls), ++ .set_sysclk = cs43130_component_set_sysclk, ++ .idle_bias_on = 1, ++ .use_pmdown_time = 1, ++ .endianness = 1, ++ .non_legacy_dai_naming = 1, ++}; ++ ++static const struct regmap_config cs43130_regmap = { ++ .reg_bits = 24, ++ .pad_bits = 8, ++ .val_bits = 8, ++ ++ .max_register = CS43130_LASTREG, ++ .reg_defaults = cs43130_reg_defaults, ++ .num_reg_defaults = ARRAY_SIZE(cs43130_reg_defaults), ++ .readable_reg = cs43130_readable_register, ++ .precious_reg = cs43130_precious_register, ++ .volatile_reg = cs43130_volatile_register, ++ .cache_type = REGCACHE_RBTREE, ++ /* needed for regcache_sync */ ++ .use_single_read = true, ++ .use_single_write = true, ++}; ++ ++static u16 const cs43130_dc_threshold[CS43130_DC_THRESHOLD] = { ++ 50, ++ 120, ++}; ++ ++static int cs43130_handle_device_data(struct i2c_client *i2c_client, ++ struct cs43130_priv *cs43130) ++{ ++ struct device_node *np = i2c_client->dev.of_node; ++ unsigned int val; ++ int i; ++ ++ if (of_property_read_u32(np, "cirrus,xtal-ibias", &val) < 0) { ++ /* Crystal is unused. System clock is used for external MCLK */ ++ cs43130->xtal_ibias = CS43130_XTAL_UNUSED; ++ return 0; ++ } ++ ++ switch (val) { ++ case 1: ++ cs43130->xtal_ibias = CS43130_XTAL_IBIAS_7_5UA; ++ break; ++ case 2: ++ cs43130->xtal_ibias = CS43130_XTAL_IBIAS_12_5UA; ++ break; ++ case 3: ++ cs43130->xtal_ibias = CS43130_XTAL_IBIAS_15UA; ++ break; ++ default: ++ dev_err(&i2c_client->dev, ++ "Invalid cirrus,xtal-ibias value: %d\n", val); ++ return -EINVAL; ++ } ++ ++ cs43130->dc_meas = of_property_read_bool(np, "cirrus,dc-measure"); ++ cs43130->ac_meas = of_property_read_bool(np, "cirrus,ac-measure"); ++ ++ if (of_property_read_u16_array(np, "cirrus,ac-freq", cs43130->ac_freq, ++ CS43130_AC_FREQ) < 0) { ++ for (i = 0; i < CS43130_AC_FREQ; i++) ++ cs43130->ac_freq[i] = cs43130_ac_freq[i]; ++ } ++ ++ if (of_property_read_u16_array(np, "cirrus,dc-threshold", ++ cs43130->dc_threshold, ++ CS43130_DC_THRESHOLD) < 0) { ++ for (i = 0; i < CS43130_DC_THRESHOLD; i++) ++ cs43130->dc_threshold[i] = cs43130_dc_threshold[i]; ++ } ++ ++ return 0; ++} ++ ++ ++static int allo_cs43130_component_probe(struct i2c_client *i2c, ++ const struct i2c_device_id *id) ++{ ++ struct regmap *regmap; ++ struct regmap_config config = cs43130_regmap; ++ struct device *dev = &i2c->dev; ++ struct cs43130_priv *cs43130; ++ unsigned int devid = 0; ++ unsigned int reg; ++ int ret; ++ ++ regmap = devm_regmap_init_i2c(i2c, &config); ++ if (IS_ERR(regmap)) ++ return PTR_ERR(regmap); ++ ++ cs43130 = devm_kzalloc(dev, sizeof(struct cs43130_priv), ++ GFP_KERNEL); ++ if (!cs43130) ++ return -ENOMEM; ++ ++ dev_set_drvdata(dev, cs43130); ++ cs43130->regmap = regmap; ++ ++ if (i2c->dev.of_node) { ++ ret = cs43130_handle_device_data(i2c, cs43130); ++ if (ret != 0) ++ return ret; ++ } ++ usleep_range(2000, 2050); ++ ++ ret = regmap_read(cs43130->regmap, CS43130_DEVID_AB, ®); ++ devid = (reg & 0xFF) << 12; ++ ret = regmap_read(cs43130->regmap, CS43130_DEVID_CD, ®); ++ devid |= (reg & 0xFF) << 4; ++ ret = regmap_read(cs43130->regmap, CS43130_DEVID_E, ®); ++ devid |= (reg & 0xF0) >> 4; ++ if (devid != CS43198_CHIP_ID) { ++ dev_err(dev, "Failed to read Chip or wrong Chip id: %d\n", ret); ++ return ret; ++ } ++ ++ cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO; ++ msleep(20); ++ ++ ret = snd_soc_register_component(dev, &cs43130_component_driver, ++ &cs43130_codec_dai, 1); ++ if (ret != 0) { ++ dev_err(dev, "failed to register codec: %d\n", ret); ++ return ret; ++ } ++ regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG, ++ CS43130_ASP_3ST_MASK, 0); ++ regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG, ++ CS43130_XSP_3ST_MASK, 1); ++ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, ++ CS43130_PDN_HP_MASK, 1 << CS43130_PDN_HP_SHIFT); ++ msleep(20); ++ regmap_write(cs43130->regmap, CS43130_CLASS_H_CTL, 0x06); ++ snd_allo_clk44gpio = devm_gpiod_get(dev, "clock44", GPIOD_OUT_HIGH); ++ if (IS_ERR(snd_allo_clk44gpio)) ++ dev_err(dev, "devm_gpiod_get() failed\n"); ++ ++ snd_allo_clk48gpio = devm_gpiod_get(dev, "clock48", GPIOD_OUT_LOW); ++ if (IS_ERR(snd_allo_clk48gpio)) ++ dev_err(dev, "devm_gpiod_get() failed\n"); ++ ++ return 0; ++} ++ ++static int allo_cs43130_component_remove(struct i2c_client *i2c) ++{ ++ snd_soc_unregister_component(&i2c->dev); ++ return 0; ++} ++ ++static const struct i2c_device_id allo_cs43130_component_id[] = { ++ { "allo-cs43198", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(i2c, allo_cs43130_component_id); ++ ++static const struct of_device_id allo_cs43130_codec_of_match[] = { ++ { .compatible = "allo,allo-cs43198", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, allo_cs43130_codec_of_match); ++ ++static struct i2c_driver allo_cs43130_component_driver = { ++ .probe = allo_cs43130_component_probe, ++ .remove = allo_cs43130_component_remove, ++ .id_table = allo_cs43130_component_id, ++ .driver = { ++ .name = "allo-cs43198", ++ .of_match_table = allo_cs43130_codec_of_match, ++ }, ++}; ++ ++module_i2c_driver(allo_cs43130_component_driver); ++ ++MODULE_DESCRIPTION("ASoC Allo Boss2 Codec Driver"); ++MODULE_AUTHOR("Sudeepkumar <sudeepkumar@cem-solutions.net>"); ++MODULE_LICENSE("GPL v2"); diff --git a/target/linux/bcm27xx/patches-5.4/950-1013-Add-allo-boss2-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-1013-Add-allo-boss2-overlay.patch new file mode 100644 index 0000000000..97bc4a5757 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1013-Add-allo-boss2-overlay.patch @@ -0,0 +1,98 @@ +From b07f4bea8e3259c30fa905b047dce73449147f58 Mon Sep 17 00:00:00 2001 +From: Sudeep <sudeepkumar@cem-solutions.net> +Date: Fri, 23 Oct 2020 15:51:15 +0530 +Subject: [PATCH] Add allo boss2 overlay + +Signed-off-by: Sudeep <sudeepkumar@cem-solutions.net> +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 6 ++ + .../overlays/allo-boss2-dac-audio-overlay.dts | 57 +++++++++++++++++++ + 3 files changed, 64 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/allo-boss2-dac-audio-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -14,6 +14,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + adv728x-m.dtbo \ + akkordion-iqdacplus.dtbo \ + allo-boss-dac-pcm512x-audio.dtbo \ ++ allo-boss2-dac-audio.dtbo \ + allo-digione.dtbo \ + allo-katana-dac-audio.dtbo \ + allo-piano-dac-pcm512x-audio.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -420,6 +420,12 @@ Params: 24db_digital_gain Allow ga + slave" + + ++Name: allo-boss2-dac-audio ++Info: Configures the Allo Boss2 DAC audio card ++Load: dtoverlay=allo-boss2-dac-audio ++Params: <None> ++ ++ + Name: allo-digione + Info: Configures the Allo Digione audio card + Load: dtoverlay=allo-digione +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/allo-boss2-dac-audio-overlay.dts +@@ -0,0 +1,57 @@ ++/* * Definitions for Allo Boss2 DAC boards ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&i2s>; ++ __overlay__ { ++ #sound-dai-cells = <0>; ++ status = "okay"; ++ cpu_port: port { ++ cpu_endpoint: endpoint { ++ remote-endpoint = <&codec_endpoint>; ++ bitclock-master = <&codec_endpoint>; ++ frame-master = <&codec_endpoint>; ++ dai-format = "i2s"; ++ }; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ allo-cs43130@30 { ++ #sound-dai-cells = <0>; ++ compatible = "allo,allo-cs43198"; ++ clock44-gpio = <&gpio 5 0>; ++ clock48-gpio = <&gpio 6 0>; ++ reg = <0x30>; ++ port { ++ codec_endpoint: endpoint { ++ remote-endpoint = <&cpu_endpoint>; ++ }; ++ }; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&sound>; ++ boss2_dac: __overlay__ { ++ compatible = "audio-graph-card"; ++ label = "Allo Boss2"; ++ dais = <&cpu_port>; ++ status = "okay"; ++ }; ++ }; ++}; ++ diff --git a/target/linux/bcm27xx/patches-5.4/950-1014-Revert-mailbox-avoid-timer-start-from-callback.patch b/target/linux/bcm27xx/patches-5.4/950-1014-Revert-mailbox-avoid-timer-start-from-callback.patch new file mode 100644 index 0000000000..849bdd192e --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1014-Revert-mailbox-avoid-timer-start-from-callback.patch @@ -0,0 +1,60 @@ +From 2b7fcd18b15d9cc7b2e68deb77f4e0acfa904c41 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Tue, 3 Nov 2020 10:13:48 +0000 +Subject: [PATCH] Revert "mailbox: avoid timer start from callback" + +This reverts commit 6dc15642c8b830d384fd3e6c9ea63144202b8932. + +The Pi 400 shutdown/poweroff mechanism relies on being able to set +a GPIO on the expander in the pm_power_off handler, something that +requires two mailbox calls - GET_GPIO_STATE and SET_GPIO_STATE. A +recent kernel change introduces a reasonable possibility that the +GET call doesn't completes, and bisecting led to a commit from +October that changes the timer usage of the mailbox. + +My theory is that there is a race condition in the new code that breaks +the poll timer, but that it normally goes unnoticed because subsequent +mailbox activity wakes it up again. The power-off mailbox calls happen +at a time when other subsystems have been shut down, so if one of them +fails then there is nothing to allow it to recover. + +Revert 6dc15642 as (at least) a workaround. + +See: https://github.com/raspberrypi/linux/issues/3941 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/mailbox/mailbox.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +--- a/drivers/mailbox/mailbox.c ++++ b/drivers/mailbox/mailbox.c +@@ -82,12 +82,9 @@ static void msg_submit(struct mbox_chan + exit: + spin_unlock_irqrestore(&chan->lock, flags); + +- /* kick start the timer immediately to avoid delays */ +- if (!err && (chan->txdone_method & TXDONE_BY_POLL)) { +- /* but only if not already active */ +- if (!hrtimer_active(&chan->mbox->poll_hrt)) +- hrtimer_start(&chan->mbox->poll_hrt, 0, HRTIMER_MODE_REL); +- } ++ if (!err && (chan->txdone_method & TXDONE_BY_POLL)) ++ /* kick start the timer immediately to avoid delays */ ++ hrtimer_start(&chan->mbox->poll_hrt, 0, HRTIMER_MODE_REL); + } + + static void tx_tick(struct mbox_chan *chan, int r) +@@ -125,10 +122,11 @@ static enum hrtimer_restart txdone_hrtim + struct mbox_chan *chan = &mbox->chans[i]; + + if (chan->active_req && chan->cl) { +- resched = true; + txdone = chan->mbox->ops->last_tx_done(chan); + if (txdone) + tx_tick(chan, 0); ++ else ++ resched = true; + } + } + diff --git a/target/linux/bcm27xx/patches-5.4/950-1015-ARM-dts-Add-bcm2711-rpi-400.dts.patch b/target/linux/bcm27xx/patches-5.4/950-1015-ARM-dts-Add-bcm2711-rpi-400.dts.patch new file mode 100644 index 0000000000..444c7ae3bb --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1015-ARM-dts-Add-bcm2711-rpi-400.dts.patch @@ -0,0 +1,627 @@ +From 37034aa6ba14c346f67e8b99a317c45e40f0a2eb Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Tue, 14 Jul 2020 14:21:33 +0100 +Subject: [PATCH] ARM: dts: Add bcm2711-rpi-400.dts + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/Makefile | 1 + + arch/arm/boot/dts/bcm2711-rpi-400.dts | 585 ++++++++++++++++++ + arch/arm64/boot/dts/broadcom/Makefile | 1 + + .../boot/dts/broadcom/bcm2711-rpi-400.dts | 1 + + 4 files changed, 588 insertions(+) + create mode 100644 arch/arm/boot/dts/bcm2711-rpi-400.dts + create mode 100644 arch/arm64/boot/dts/broadcom/bcm2711-rpi-400.dts + +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -12,6 +12,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ + bcm2710-rpi-3-b.dtb \ + bcm2710-rpi-3-b-plus.dtb \ + bcm2711-rpi-4-b.dtb \ ++ bcm2711-rpi-400.dtb \ + bcm2710-rpi-cm3.dtb \ + bcm2711-rpi-cm4.dtb + +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2711-rpi-400.dts +@@ -0,0 +1,585 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/dts-v1/; ++#include "bcm2711.dtsi" ++#include "bcm2835-rpi.dtsi" ++ ++/ { ++ compatible = "raspberrypi,400", "brcm,bcm2711"; ++ model = "Raspberry Pi 400"; ++ ++ chosen { ++ /* 8250 auxiliary UART instead of pl011 */ ++ stdout-path = "serial1:115200n8"; ++ }; ++ ++ /* Will be filled by the bootloader */ ++ memory@0 { ++ device_type = "memory"; ++ reg = <0 0 0>; ++ }; ++ ++ aliases { ++ emmc2bus = &emmc2bus; ++ ethernet0 = &genet; ++ pcie0 = &pcie0; ++ }; ++ ++ leds { ++ act { ++ gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ pwr { ++ label = "PWR"; ++ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; ++ default-state = "keep"; ++ linux,default-trigger = "default-on"; ++ }; ++ }; ++ ++ wifi_pwrseq: wifi-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>; ++ }; ++ ++ sd_io_1v8_reg: sd_io_1v8_reg { ++ compatible = "regulator-gpio"; ++ regulator-name = "vdd-sd-io"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-settling-time-us = <5000>; ++ gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>; ++ states = <1800000 0x1 ++ 3300000 0x0>; ++ status = "okay"; ++ }; ++}; ++ ++&firmware { ++ expgpio: gpio { ++ compatible = "raspberrypi,firmware-gpio"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ gpio-line-names = "BT_ON", ++ "WL_ON", ++ "PWR_LED_OFF", ++ "GLOBAL_RESET", ++ "VDD_SD_IO_SEL", ++ "CAM_GPIO", ++ "SD_PWR_ON", ++ "SD_OC_N"; ++ status = "okay"; ++ }; ++}; ++ ++&gpio { ++ /* ++ * Parts taken from rpi_SCH_4b_4p0_reduced.pdf and ++ * the official GPU firmware DT blob. ++ * ++ * Legend: ++ * "FOO" = GPIO line named "FOO" on the schematic ++ * "FOO_N" = GPIO line named "FOO" on schematic, active low ++ */ ++ gpio-line-names = "ID_SDA", ++ "ID_SCL", ++ "SDA1", ++ "SCL1", ++ "GPIO_GCLK", ++ "GPIO5", ++ "GPIO6", ++ "SPI_CE1_N", ++ "SPI_CE0_N", ++ "SPI_MISO", ++ "SPI_MOSI", ++ "SPI_SCLK", ++ "GPIO12", ++ "GPIO13", ++ /* Serial port */ ++ "TXD1", ++ "RXD1", ++ "GPIO16", ++ "GPIO17", ++ "GPIO18", ++ "GPIO19", ++ "GPIO20", ++ "GPIO21", ++ "GPIO22", ++ "GPIO23", ++ "GPIO24", ++ "GPIO25", ++ "GPIO26", ++ "GPIO27", ++ "RGMII_MDIO", ++ "RGMIO_MDC", ++ /* Used by BT module */ ++ "CTS0", ++ "RTS0", ++ "TXD0", ++ "RXD0", ++ /* Used by Wifi */ ++ "SD1_CLK", ++ "SD1_CMD", ++ "SD1_DATA0", ++ "SD1_DATA1", ++ "SD1_DATA2", ++ "SD1_DATA3", ++ /* Shared with SPI flash */ ++ "PWM0_MISO", ++ "PWM1_MOSI", ++ "STATUS_LED_G_CLK", ++ "SPIFLASH_CE_N", ++ "SDA0", ++ "SCL0", ++ "RGMII_RXCLK", ++ "RGMII_RXCTL", ++ "RGMII_RXD0", ++ "RGMII_RXD1", ++ "RGMII_RXD2", ++ "RGMII_RXD3", ++ "RGMII_TXCLK", ++ "RGMII_TXCTL", ++ "RGMII_TXD0", ++ "RGMII_TXD1", ++ "RGMII_TXD2", ++ "RGMII_TXD3"; ++}; ++ ++&pwm1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm1_0_gpio40 &pwm1_1_gpio41>; ++ status = "okay"; ++}; ++ ++/* SDHCI is used to control the SDIO for wireless */ ++&sdhci { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_gpio34>; ++ bus-width = <4>; ++ non-removable; ++ mmc-pwrseq = <&wifi_pwrseq>; ++ status = "okay"; ++ ++ brcmf: wifi@1 { ++ reg = <1>; ++ compatible = "brcm,bcm4329-fmac"; ++ }; ++}; ++ ++/* EMMC2 is used to drive the SD card */ ++&emmc2 { ++ vqmmc-supply = <&sd_io_1v8_reg>; ++ broken-cd; ++ status = "okay"; ++}; ++ ++&genet { ++ phy-handle = <&phy1>; ++ phy-mode = "rgmii-rxid"; ++ status = "okay"; ++}; ++ ++&genet_mdio { ++ phy1: ethernet-phy@1 { ++ /* No PHY interrupt */ ++ reg = <0x1>; ++ }; ++}; ++ ++/* uart0 communicates with the BT module */ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32>; ++ uart-has-rtscts; ++ status = "okay"; ++ ++ bluetooth { ++ compatible = "brcm,bcm43438-bt"; ++ max-speed = <2000000>; ++ shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++/* uart1 is mapped to the pin header */ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_gpio14>; ++ status = "okay"; ++}; ++ ++&vchiq { ++ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; ++}; ++ ++// ============================================= ++// Downstream rpi- changes ++ ++#include "bcm270x.dtsi" ++#include "bcm271x-rpi-bt.dtsi" ++ ++/ { ++ soc { ++ /delete-node/ pixelvalve@7e807000; ++ /delete-node/ hdmi@7e902000; ++ }; ++}; ++ ++#include "bcm2711-rpi.dtsi" ++#include "bcm283x-rpi-csi1-2lane.dtsi" ++#include "bcm283x-rpi-i2c0mux_0_44.dtsi" ++ ++/ { ++ chosen { ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1"; ++ }; ++ ++ aliases { ++ serial0 = &uart1; ++ serial1 = &uart0; ++ mmc0 = &emmc2; ++ mmc1 = &mmcnr; ++ mmc2 = &sdhost; ++ /delete-property/ i2c2; ++ i2c3 = &i2c3; ++ i2c4 = &i2c4; ++ i2c5 = &i2c5; ++ i2c6 = &i2c6; ++ /delete-property/ intc; ++ }; ++ ++ /delete-node/ wifi-pwrseq; ++}; ++ ++&mmcnr { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-0 = <&uart0_pins &bt_pins>; ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-0 = <&uart1_pins>; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; ++ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; ++ ++ spidev0: spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ }; ++ ++ spidev1: spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ }; ++}; ++ ++&gpio { ++ spi0_pins: spi0_pins { ++ brcm,pins = <9 10 11>; ++ brcm,function = <BCM2835_FSEL_ALT0>; ++ }; ++ ++ spi0_cs_pins: spi0_cs_pins { ++ brcm,pins = <8 7>; ++ brcm,function = <BCM2835_FSEL_GPIO_OUT>; ++ }; ++ ++ spi3_pins: spi3_pins { ++ brcm,pins = <1 2 3>; ++ brcm,function = <BCM2835_FSEL_ALT3>; ++ }; ++ ++ spi3_cs_pins: spi3_cs_pins { ++ brcm,pins = <0 24>; ++ brcm,function = <BCM2835_FSEL_GPIO_OUT>; ++ }; ++ ++ spi4_pins: spi4_pins { ++ brcm,pins = <5 6 7>; ++ brcm,function = <BCM2835_FSEL_ALT3>; ++ }; ++ ++ spi4_cs_pins: spi4_cs_pins { ++ brcm,pins = <4 25>; ++ brcm,function = <BCM2835_FSEL_GPIO_OUT>; ++ }; ++ ++ spi5_pins: spi5_pins { ++ brcm,pins = <13 14 15>; ++ brcm,function = <BCM2835_FSEL_ALT3>; ++ }; ++ ++ spi5_cs_pins: spi5_cs_pins { ++ brcm,pins = <12 26>; ++ brcm,function = <BCM2835_FSEL_GPIO_OUT>; ++ }; ++ ++ spi6_pins: spi6_pins { ++ brcm,pins = <19 20 21>; ++ brcm,function = <BCM2835_FSEL_ALT3>; ++ }; ++ ++ spi6_cs_pins: spi6_cs_pins { ++ brcm,pins = <18 27>; ++ brcm,function = <BCM2835_FSEL_GPIO_OUT>; ++ }; ++ ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <BCM2835_FSEL_ALT0>; ++ brcm,pull = <BCM2835_PUD_UP>; ++ }; ++ ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <BCM2835_FSEL_ALT0>; ++ brcm,pull = <BCM2835_PUD_UP>; ++ }; ++ ++ i2c3_pins: i2c3 { ++ brcm,pins = <4 5>; ++ brcm,function = <BCM2835_FSEL_ALT5>; ++ brcm,pull = <BCM2835_PUD_UP>; ++ }; ++ ++ i2c4_pins: i2c4 { ++ brcm,pins = <8 9>; ++ brcm,function = <BCM2835_FSEL_ALT5>; ++ brcm,pull = <BCM2835_PUD_UP>; ++ }; ++ ++ i2c5_pins: i2c5 { ++ brcm,pins = <12 13>; ++ brcm,function = <BCM2835_FSEL_ALT5>; ++ brcm,pull = <BCM2835_PUD_UP>; ++ }; ++ ++ i2c6_pins: i2c6 { ++ brcm,pins = <22 23>; ++ brcm,function = <BCM2835_FSEL_ALT5>; ++ brcm,pull = <BCM2835_PUD_UP>; ++ }; ++ ++ i2s_pins: i2s { ++ brcm,pins = <18 19 20 21>; ++ brcm,function = <BCM2835_FSEL_ALT0>; ++ }; ++ ++ sdio_pins: sdio_pins { ++ brcm,pins = <34 35 36 37 38 39>; ++ brcm,function = <BCM2835_FSEL_ALT3>; // alt3 = SD1 ++ brcm,pull = <0 2 2 2 2 2>; ++ }; ++ ++ bt_pins: bt_pins { ++ brcm,pins = "-"; // non-empty to keep btuart happy, //4 = 0 ++ // to fool pinctrl ++ brcm,function = <0>; ++ brcm,pull = <2>; ++ }; ++ ++ uart0_pins: uart0_pins { ++ brcm,pins = <32 33>; ++ brcm,function = <BCM2835_FSEL_ALT3>; ++ brcm,pull = <0 2>; ++ }; ++ ++ uart1_pins: uart1_pins { ++ brcm,pins; ++ brcm,function; ++ brcm,pull; ++ }; ++ ++ uart2_pins: uart2_pins { ++ brcm,pins = <0 1>; ++ brcm,function = <BCM2835_FSEL_ALT4>; ++ brcm,pull = <0 2>; ++ }; ++ ++ uart3_pins: uart3_pins { ++ brcm,pins = <4 5>; ++ brcm,function = <BCM2835_FSEL_ALT4>; ++ brcm,pull = <0 2>; ++ }; ++ ++ uart4_pins: uart4_pins { ++ brcm,pins = <8 9>; ++ brcm,function = <BCM2835_FSEL_ALT4>; ++ brcm,pull = <0 2>; ++ }; ++ ++ uart5_pins: uart5_pins { ++ brcm,pins = <12 13>; ++ brcm,function = <BCM2835_FSEL_ALT4>; ++ brcm,pull = <0 2>; ++ }; ++}; ++ ++&i2c0if { ++ clock-frequency = <100000>; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2s { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++/ { ++ __overrides__ { ++ /delete-property/ i2c2_baudrate; ++ /delete-property/ i2c2_iknowwhatimdoing; ++ }; ++}; ++ ++&firmwarekms { ++ compatible = "raspberrypi,rpi-firmware-kms-2711"; ++}; ++ ++// ============================================= ++// Board specific stuff here ++ ++/ { ++ sd_vcc_reg: sd_vcc_reg { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc-sd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ enable-active-high; ++ gpio = <&expgpio 6 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ power_ctrl: power_ctrl { ++ compatible = "gpio-poweroff"; ++ gpios = <&expgpio 5 0>; ++ force; ++ }; ++}; ++ ++&sdhost { ++ status = "disabled"; ++}; ++ ++&emmc2 { ++ vmmc-supply = <&sd_vcc_reg>; ++}; ++ ++&phy1 { ++ led-modes = <0x00 0x08>; /* link/activity link */ ++}; ++ ++&gpio { ++ audio_pins: audio_pins { ++ brcm,pins = <40 41>; ++ brcm,function = <4>; ++ }; ++}; ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "default-on"; ++ default-state = "on"; ++ gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ pwr_led: pwr { ++ label = "led1"; ++ linux,default-trigger = "default-on"; ++ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&pwm1 { ++ status = "disabled"; ++}; ++ ++&audio { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&audio_pins>; ++ brcm,disable-headphones = <1>; ++}; ++ ++&vc4 { ++ status = "disabled"; ++}; ++ ++&pixelvalve0 { ++ status = "disabled"; ++}; ++ ++&pixelvalve1 { ++ status = "disabled"; ++}; ++ ++&pixelvalve2 { ++ status = "disabled"; ++}; ++ ++&pixelvalve3 { ++ status = "disabled"; ++}; ++ ++&pixelvalve4 { ++ status = "disabled"; ++}; ++ ++&hdmi0 { ++ status = "disabled"; ++}; ++ ++&ddc0 { ++ status = "disabled"; ++}; ++ ++&hdmi1 { ++ status = "disabled"; ++}; ++ ++&ddc1 { ++ status = "disabled"; ++}; ++ ++/ { ++ __overrides__ { ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ ++ pwr_led_gpio = <&pwr_led>,"gpios:4"; ++ pwr_led_activelow = <&pwr_led>,"gpios:8"; ++ pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; ++ ++ eth_led0 = <&phy1>,"led-modes:0"; ++ eth_led1 = <&phy1>,"led-modes:4"; ++ ++ sd_poll_once = <&emmc2>, "non-removable?"; ++ spi_dma4 = <&spi0>, "dmas:0=", <&dma40>, ++ <&spi0>, "dmas:8=", <&dma40>; ++ }; ++}; +--- a/arch/arm64/boot/dts/broadcom/Makefile ++++ b/arch/arm64/boot/dts/broadcom/Makefile +@@ -7,6 +7,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rp + dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b-plus.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-4-b.dtb ++dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-400.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-cm3.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-cm4.dtb + +--- /dev/null ++++ b/arch/arm64/boot/dts/broadcom/bcm2711-rpi-400.dts +@@ -0,0 +1 @@ ++#include "../../../../arm/boot/dts/bcm2711-rpi-400.dts" diff --git a/target/linux/bcm27xx/patches-5.4/950-1016-overlays-Deprecate-and-delete-the-sdtweak-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-1016-overlays-Deprecate-and-delete-the-sdtweak-overlay.patch new file mode 100644 index 0000000000..fb0107c24d --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1016-overlays-Deprecate-and-delete-the-sdtweak-overlay.patch @@ -0,0 +1,64 @@ +From 88358069ed07f16a0aab0764ed1337e540006e29 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Wed, 4 Nov 2020 11:25:02 +0000 +Subject: [PATCH] overlays: Deprecate and delete the sdtweak overlay + +The sdtweak overlay has been superseded by the board-specific +sd_* parameters such as sd_poll_once, sd_overclock etc. + +For example, replace: + + dtoverlay=sdtweak,poll_once + +with: + + dtparam=sd_poll_once + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/overlay_map.dts | 4 +++ + .../arm/boot/dts/overlays/sdtweak-overlay.dts | 25 ------------------- + 2 files changed, 4 insertions(+), 25 deletions(-) + delete mode 100644 arch/arm/boot/dts/overlays/sdtweak-overlay.dts + +--- a/arch/arm/boot/dts/overlays/overlay_map.dts ++++ b/arch/arm/boot/dts/overlays/overlay_map.dts +@@ -61,6 +61,10 @@ + deprecated = "use sdio,bus_width=1,gpios_22_25"; + }; + ++ sdtweak { ++ deprecated = "use 'dtparam=sd_poll_once' etc."; ++ }; ++ + spi0-cs { + renamed = "spi0-2cs"; + }; +--- a/arch/arm/boot/dts/overlays/sdtweak-overlay.dts ++++ /dev/null +@@ -1,25 +0,0 @@ +-/dts-v1/; +-/plugin/; +- +-/* Provide backwards compatible aliases for the old sdhost dtparams. */ +- +-/{ +- compatible = "brcm,bcm2835"; +- +- fragment@0 { +- target = <&sdhost>; +- frag0: __overlay__ { +- brcm,overclock-50 = <0>; +- brcm,pio-limit = <1>; +- }; +- }; +- +- __overrides__ { +- overclock_50 = <&frag0>,"brcm,overclock-50:0"; +- force_pio = <&frag0>,"brcm,force-pio?"; +- pio_limit = <&frag0>,"brcm,pio-limit:0"; +- debug = <&frag0>,"brcm,debug?"; +- enable = <&frag0>,"status"; +- poll_once = <&frag0>,"non-removable?"; +- }; +-}; diff --git a/target/linux/bcm27xx/patches-5.4/950-1017-overlays-Complete-the-sdtweak-excision.patch b/target/linux/bcm27xx/patches-5.4/950-1017-overlays-Complete-the-sdtweak-excision.patch new file mode 100644 index 0000000000..dc63f39dd7 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1017-overlays-Complete-the-sdtweak-excision.patch @@ -0,0 +1,57 @@ +From 572fe7f4e008792e3f14822d5ddddb37c86329fe Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Thu, 5 Nov 2020 09:54:33 +0000 +Subject: [PATCH] overlays: Complete the sdtweak excision + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/Makefile | 1 - + arch/arm/boot/dts/overlays/README | 27 ++++----------------------- + 2 files changed, 4 insertions(+), 24 deletions(-) + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -159,7 +159,6 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + sc16is752-spi1.dtbo \ + sdhost.dtbo \ + sdio.dtbo \ +- sdtweak.dtbo \ + sh1106-spi.dtbo \ + smi.dtbo \ + smi-dev.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -2407,29 +2407,10 @@ Load: <Deprecated> + + + Name: sdtweak +-Info: Tunes the bcm2835-sdhost SD/MMC driver +- N.B. This functionality is now available via the sd_* dtparams in the +- base DTB. +-Load: dtoverlay=sdtweak,<param>=<val> +-Params: overclock_50 Clock (in MHz) to use when the MMC framework +- requests 50MHz +- +- force_pio Disable DMA support (default off) +- +- pio_limit Number of blocks above which to use DMA +- (default 1) +- +- debug Enable debug output (default off) +- +- poll_once Looks for a card once after booting. Useful +- for network booting scenarios to avoid the +- overhead of continuous polling. N.B. Using +- this option restricts the system to using a +- single card per boot (or none at all). +- (default off) +- +- enable Set to off to completely disable the interface +- (default on) ++Info: This overlay is now deprecated. Use the sd_* dtparams in the ++ base DTB, e.g. "dtoverlay=sdtweak,poll_once" becomes ++ "dtparam=sd_poll_once". ++Load: <Deprecated> + + + Name: sh1106-spi diff --git a/target/linux/bcm27xx/patches-5.4/950-1018-ARM-dts-bcm27xx-Remove-enable_headphones-setting.patch b/target/linux/bcm27xx/patches-5.4/950-1018-ARM-dts-bcm27xx-Remove-enable_headphones-setting.patch new file mode 100644 index 0000000000..f3db1905c2 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1018-ARM-dts-bcm27xx-Remove-enable_headphones-setting.patch @@ -0,0 +1,110 @@ +From f1d85a62da9a69fba1438e64b4fcc785abb6c957 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Thu, 5 Nov 2020 11:39:35 +0000 +Subject: [PATCH] ARM: dts: bcm27xx: Remove enable_headphones setting + +The enable_headphones parameter of the snd_bcm2835 module is forced +to 1 if enable_compat_alsa is 0, so setting them both on the kernel +command line is pointless (and, in the case of Pi 400 and Pi Zeroes, +confusing). + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2708-rpi-zero-w.dts | 2 +- + arch/arm/boot/dts/bcm2708-rpi-zero.dts | 2 +- + arch/arm/boot/dts/bcm270x.dtsi | 2 +- + arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 2 +- + arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 2 +- + arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 2 +- + arch/arm/boot/dts/bcm2711-rpi-400.dts | 2 +- + arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 2 +- + 8 files changed, 8 insertions(+), 8 deletions(-) + +--- a/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts +@@ -11,7 +11,7 @@ + model = "Raspberry Pi Zero W"; + + chosen { +- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1"; ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1"; + }; + + aliases { +--- a/arch/arm/boot/dts/bcm2708-rpi-zero.dts ++++ b/arch/arm/boot/dts/bcm2708-rpi-zero.dts +@@ -10,7 +10,7 @@ + model = "Raspberry Pi Zero"; + + chosen { +- bootargs = "coherent_pool=1M snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1"; ++ bootargs = "coherent_pool=1M snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1"; + }; + }; + +--- a/arch/arm/boot/dts/bcm270x.dtsi ++++ b/arch/arm/boot/dts/bcm270x.dtsi +@@ -3,7 +3,7 @@ + + / { + chosen { +- bootargs = "coherent_pool=1M snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1"; ++ bootargs = "coherent_pool=1M snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1"; + /delete-property/ stdout-path; + }; + +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts +@@ -12,7 +12,7 @@ + model = "Raspberry Pi 3 Model B+"; + + chosen { +- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1"; ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1"; + }; + + aliases { +--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts ++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts +@@ -12,7 +12,7 @@ + model = "Raspberry Pi 3 Model B"; + + chosen { +- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1"; ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1"; + }; + + aliases { +--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts +@@ -234,7 +234,7 @@ + + / { + chosen { +- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1"; ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1"; + }; + + aliases { +--- a/arch/arm/boot/dts/bcm2711-rpi-400.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-400.dts +@@ -234,7 +234,7 @@ + + / { + chosen { +- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1"; ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1"; + }; + + aliases { +--- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts +@@ -174,7 +174,7 @@ + + / { + chosen { +- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1"; ++ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1"; + }; + + aliases { diff --git a/target/linux/bcm27xx/patches-5.4/950-1019-staging-vcsm-cma-Fix-memory-leak-from-not-detaching-.patch b/target/linux/bcm27xx/patches-5.4/950-1019-staging-vcsm-cma-Fix-memory-leak-from-not-detaching-.patch new file mode 100644 index 0000000000..992adc67fb --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1019-staging-vcsm-cma-Fix-memory-leak-from-not-detaching-.patch @@ -0,0 +1,77 @@ +From 6ff310748f67d98d1c2c8ea75decd9dee13aa50c Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Wed, 4 Nov 2020 18:54:20 +0000 +Subject: [PATCH] staging: vcsm-cma: Fix memory leak from not + detaching dmabuf + +When importing there was a missing call to detach the buffer, +so each import leaked the sg table entry. + +Actually the release process for both locally allocated and +imported buffers is identical, so fix them to both use the same +function. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + .../staging/vc04_services/vc-sm-cma/vc_sm.c | 22 ++----------------- + 1 file changed, 2 insertions(+), 20 deletions(-) + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -237,6 +237,7 @@ static void vc_sm_add_resource(struct vc + + /* + * Cleans up imported dmabuf. ++ * Should be called with mutex held. + */ + static void vc_sm_clean_up_dmabuf(struct vc_sm_buffer *buffer) + { +@@ -244,7 +245,6 @@ static void vc_sm_clean_up_dmabuf(struct + return; + + /* Handle cleaning up imported dmabufs */ +- mutex_lock(&buffer->lock); + if (buffer->import.sgt) { + dma_buf_unmap_attachment(buffer->import.attach, + buffer->import.sgt, +@@ -255,7 +255,6 @@ static void vc_sm_clean_up_dmabuf(struct + dma_buf_detach(buffer->dma_buf, buffer->import.attach); + buffer->import.attach = NULL; + } +- mutex_unlock(&buffer->lock); + } + + /* +@@ -687,23 +686,6 @@ int vc_sm_import_dmabuf_mmap(struct dma_ + } + + static +-void vc_sm_import_dma_buf_release(struct dma_buf *dmabuf) +-{ +- struct vc_sm_buffer *buf = dmabuf->priv; +- +- pr_debug("%s: Relasing dma_buf %p\n", __func__, dmabuf); +- mutex_lock(&buf->lock); +- if (!buf->imported) +- return; +- +- buf->in_use = 0; +- +- vc_sm_vpu_free(buf); +- +- vc_sm_release_resource(buf); +-} +- +-static + void *vc_sm_import_dma_buf_kmap(struct dma_buf *dmabuf, + unsigned long offset) + { +@@ -753,7 +735,7 @@ static const struct dma_buf_ops dma_buf_ + .map_dma_buf = vc_sm_import_map_dma_buf, + .unmap_dma_buf = vc_sm_import_unmap_dma_buf, + .mmap = vc_sm_import_dmabuf_mmap, +- .release = vc_sm_import_dma_buf_release, ++ .release = vc_sm_dma_buf_release, + .attach = vc_sm_import_dma_buf_attach, + .detach = vc_sm_import_dma_buf_detatch, + .begin_cpu_access = vc_sm_import_dma_buf_begin_cpu_access, diff --git a/target/linux/bcm27xx/patches-5.4/950-1020-Update-Allo-Piano-Dac-Driver-for-5.4.y-kernels.patch b/target/linux/bcm27xx/patches-5.4/950-1020-Update-Allo-Piano-Dac-Driver-for-5.4.y-kernels.patch new file mode 100644 index 0000000000..00d319e291 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1020-Update-Allo-Piano-Dac-Driver-for-5.4.y-kernels.patch @@ -0,0 +1,246 @@ +From 7f7ea09cdfa44c447c31db4884c1bb958d27f10a Mon Sep 17 00:00:00 2001 +From: paul-1 <6473457+paul-1@users.noreply.github.com> +Date: Wed, 4 Nov 2020 19:11:37 -0500 +Subject: [PATCH] Update Allo Piano Dac Driver for 5.4.y kernels + +Add unique names to the individual dac coded drivers +Remove some of the codec controls that are not used. + +Signed-off-by: Paul Hermann <paul@picoreplayer.org> +--- + sound/soc/bcm/allo-piano-dac-plus.c | 129 +++++++++++++++++++++------- + 1 file changed, 97 insertions(+), 32 deletions(-) + +--- a/sound/soc/bcm/allo-piano-dac-plus.c ++++ b/sound/soc/bcm/allo-piano-dac-plus.c +@@ -2,7 +2,8 @@ + * ALSA ASoC Machine Driver for Allo Piano DAC Plus Subwoofer + * + * Author: Baswaraj K <jaikumar@cem-solutions.net> +- * Copyright 2016 ++ * Copyright 2020 ++ * based on code by David Knell <david.knell@gmail.com) + * based on code by Daniel Matuschek <info@crazy-audio.com> + * based on code by Florian Meier <florian.meier@koalo.de> + * +@@ -276,8 +277,15 @@ static int snd_allo_piano_dual_mode_put( + PCM512x_DIGITAL_VOLUME_2, 0xff); + + list_for_each_entry(kctl, &snd_card_ptr->controls, list) { +- if (!strncmp(kctl->id.name, "Digital Playback Volume", +- sizeof(kctl->id.name))) { ++ if (!strncmp(kctl->id.name, "Main Digital Playback Volume", ++ sizeof(kctl->id.name))) { ++ mc = (struct soc_mixer_control *) ++ kctl->private_value; ++ mc->rreg = mc->reg; ++ break; ++ } ++ if (!strncmp(kctl->id.name, "Sub Digital Playback Volume", ++ sizeof(kctl->id.name))) { + mc = (struct soc_mixer_control *) + kctl->private_value; + mc->rreg = mc->reg; +@@ -291,13 +299,20 @@ static int snd_allo_piano_dual_mode_put( + PCM512x_DIGITAL_VOLUME_3, &right_val); + + list_for_each_entry(kctl, &snd_card_ptr->controls, list) { +- if (!strncmp(kctl->id.name, "Digital Playback Volume", +- sizeof(kctl->id.name))) { ++ if (!strncmp(kctl->id.name, "Main Digital Playback Volume", ++ sizeof(kctl->id.name))) { + mc = (struct soc_mixer_control *) + kctl->private_value; + mc->rreg = PCM512x_DIGITAL_VOLUME_3; + break; + } ++ if (!strncmp(kctl->id.name, "Sub Digital Playback Volume", ++ sizeof(kctl->id.name))) { ++ mc = (struct soc_mixer_control *) ++ kctl->private_value; ++ mc->rreg = PCM512x_DIGITAL_VOLUME_2; ++ break; ++ } + } + + snd_soc_component_write(rtd->codec_dais[0]->component, +@@ -344,13 +359,20 @@ static int snd_allo_piano_mode_put(struc + PCM512x_DIGITAL_VOLUME_2, &right_val); + + list_for_each_entry(kctl, &snd_card_ptr->controls, list) { +- if (!strncmp(kctl->id.name, "Digital Playback Volume", +- sizeof(kctl->id.name))) { ++ if (!strncmp(kctl->id.name, "Main Digital Playback Volume", ++ sizeof(kctl->id.name))) { + mc = (struct soc_mixer_control *) + kctl->private_value; + mc->rreg = PCM512x_DIGITAL_VOLUME_3; + break; + } ++ if (!strncmp(kctl->id.name, "Sub Digital Playback Volume", ++ sizeof(kctl->id.name))) { ++ mc = (struct soc_mixer_control *) ++ kctl->private_value; ++ mc->rreg = PCM512x_DIGITAL_VOLUME_2; ++ break; ++ } + } + snd_soc_component_write(rtd->codec_dais[0]->component, + PCM512x_DIGITAL_VOLUME_3, left_val); +@@ -434,12 +456,6 @@ static int pcm512x_set_reg_sub(struct sn + int ret = 0; + + rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name); +- if (glb_ptr->dual_mode != 1) { +- ret = snd_soc_component_write(rtd->codec_dais[1]->component, +- PCM512x_DIGITAL_VOLUME_2, (~left_val)); +- if (ret < 0) +- return ret; +- } + + if (digital_gain_0db_limit) { + ret = snd_soc_limit_volume(card, "Subwoofer Playback Volume", +@@ -449,6 +465,13 @@ static int pcm512x_set_reg_sub(struct sn + ret); + } + ++ if (glb_ptr->dual_mode != 1) { ++ ret = snd_soc_component_write(rtd->codec_dais[1]->component, ++ PCM512x_DIGITAL_VOLUME_2, (~left_val)); ++ if (ret < 0) ++ return ret; ++ } ++ + ret = snd_soc_component_write(rtd->codec_dais[1]->component, + PCM512x_DIGITAL_VOLUME_3, (~right_val)); + if (ret < 0) +@@ -674,7 +697,7 @@ static const struct snd_kcontrol_new all + + SOC_DOUBLE_R_EXT_TLV("Subwoofer Playback Volume", + PCM512x_DIGITAL_VOLUME_2, +- PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, ++ PCM512x_DIGITAL_VOLUME_3, 0, 207, 1, + pcm512x_get_reg_sub, + pcm512x_set_reg_sub, + digital_tlv_sub), +@@ -688,7 +711,7 @@ static const struct snd_kcontrol_new all + + SOC_DOUBLE_R_EXT_TLV("Master Playback Volume", + PCM512x_DIGITAL_VOLUME_2, +- PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, ++ PCM512x_DIGITAL_VOLUME_3, 0, 207, 1, + pcm512x_get_reg_master, + pcm512x_set_reg_master, + digital_tlv_master), +@@ -701,10 +724,28 @@ static const struct snd_kcontrol_new all + pcm512x_set_reg_master_switch), + }; + ++static const char * const codec_ctl_pfx[] = { "Main", "Sub" }; ++static const char * const codec_ctl_name[] = { ++ "Digital Playback Volume", ++ "Digital Playback Switch", ++ "Auto Mute Mono Switch", ++ "Auto Mute Switch", ++ "Auto Mute Time Left", ++ "Auto Mute Time Right", ++ "Clock Missing Period", ++ "Max Overclock DAC", ++ "Max Overclock DSP", ++ "Max Overclock PLL", ++ "Volume Ramp Down Emergency Rate", ++ "Volume Ramp Down Emergency Step" ++}; ++ + static int snd_allo_piano_dac_init(struct snd_soc_pcm_runtime *rtd) + { + struct snd_soc_card *card = rtd->card; + struct glb_pool *glb_ptr; ++ struct snd_kcontrol *kctl; ++ int i, j; + + glb_ptr = kzalloc(sizeof(struct glb_pool), GFP_KERNEL); + if (!glb_ptr) +@@ -719,12 +760,37 @@ static int snd_allo_piano_dac_init(struc + if (digital_gain_0db_limit) { + int ret; + +- 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); ++ //Set volume limit on both dacs ++ for (i = 0; i < ARRAY_SIZE(codec_ctl_pfx); i++) { ++ char cname[256]; ++ ++ sprintf(cname, "%s %s", codec_ctl_pfx[i], codec_ctl_name[0]); ++ ret = snd_soc_limit_volume(card, cname, 207); ++ if (ret < 0) ++ dev_warn(card->dev, "Failed to set volume limit: %d\n", ++ ret); ++ } ++ } ++ ++ // Remove codec controls ++ for (i = 0; i < ARRAY_SIZE(codec_ctl_pfx); i++) { ++ // Start at 1, leave the Digital Volume control. ++ for (j = 1; j < ARRAY_SIZE(codec_ctl_name); j++) { ++ char cname[256]; ++ ++ sprintf(cname, "%s %s", codec_ctl_pfx[i], codec_ctl_name[j]); ++ kctl = snd_soc_card_get_kcontrol(card, cname); ++ if (!kctl) { ++ dev_err(rtd->card->dev, "Control %s not found\n", ++ cname); ++ } else { ++ kctl->vd[0].access = ++ SNDRV_CTL_ELEM_ACCESS_READWRITE; ++ snd_ctl_remove(card->snd_card, kctl); ++ } ++ } + } ++ + return 0; + } + +@@ -868,10 +934,10 @@ static struct snd_soc_dai_link_component + }; + + SND_SOC_DAILINK_DEFS(allo_piano_dai_plus, +- DAILINK_COMP_ARRAY(COMP_CPU("bcm2708-i2s.0")), +- DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "pcm512x-hifi"), +- COMP_CODEC(NULL, "pcm512x-hifi")), +- DAILINK_COMP_ARRAY(COMP_PLATFORM("bcm2708-i2s.0"))); ++ DAILINK_COMP_ARRAY(COMP_EMPTY()), ++ DAILINK_COMP_ARRAY(COMP_CODEC("pcm512x.1-004c", "pcm512x-hifi"), ++ COMP_CODEC("pcm512x.1-004d", "pcm512x-hifi")), ++ DAILINK_COMP_ARRAY(COMP_EMPTY())); + + static struct snd_soc_dai_link snd_allo_piano_dac_dai[] = { + { +@@ -964,17 +1030,16 @@ static int snd_allo_piano_dac_probe(stru + snd_allo_piano_dac.set_bias_level = + snd_allo_piano_set_bias_level; + +- ret = snd_soc_register_card(&snd_allo_piano_dac); +- if (ret < 0) { +- dev_err(&pdev->dev, +- "snd_soc_register_card() failed: %d\n", ret); +- return ret; +- } +- + if ((mute_gpio[0]) && (mute_gpio[1])) + snd_allo_piano_gpio_mute(&snd_allo_piano_dac); + +- return 0; ++ ret = devm_snd_soc_register_card(&pdev->dev, &snd_allo_piano_dac); ++ ++ if (ret && ret != -EPROBE_DEFER) ++ dev_err(&pdev->dev, ++ "snd_soc_register_card() failed: %d\n", ret); ++ return ret; ++ + } + + return -EINVAL; diff --git a/target/linux/bcm27xx/patches-5.4/950-1021-Overlay-Update-Allo-Piano-Plus-dac-driver-for-5.4.y-.patch b/target/linux/bcm27xx/patches-5.4/950-1021-Overlay-Update-Allo-Piano-Plus-dac-driver-for-5.4.y-.patch new file mode 100644 index 0000000000..68b713d740 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1021-Overlay-Update-Allo-Piano-Plus-dac-driver-for-5.4.y-.patch @@ -0,0 +1,30 @@ +From 244817626f3f3f5d0e5f6e2881f7046087a225ff Mon Sep 17 00:00:00 2001 +From: paul-1 <6473457+paul-1@users.noreply.github.com> +Date: Wed, 4 Nov 2020 19:17:48 -0500 +Subject: [PATCH] Overlay: Update Allo Piano Plus dac driver for + 5.4.y kernels. + +Create unique names for the two instances of the codec driver. + +Signed-off-by: Paul Hermann <paul@picoreplayer.org> +--- + .../dts/overlays/allo-piano-dac-plus-pcm512x-audio-overlay.dts | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/arm/boot/dts/overlays/allo-piano-dac-plus-pcm512x-audio-overlay.dts ++++ b/arch/arm/boot/dts/overlays/allo-piano-dac-plus-pcm512x-audio-overlay.dts +@@ -23,12 +23,14 @@ + #sound-dai-cells = <0>; + compatible = "ti,pcm5122"; + reg = <0x4c>; ++ sound-name-prefix = "Main"; + status = "okay"; + }; + allo_pcm5122_4d: pcm5122@4d { + #sound-dai-cells = <0>; + compatible = "ti,pcm5122"; + reg = <0x4d>; ++ sound-name-prefix = "Sub"; + status = "okay"; + }; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-1022-Update-volume-controls-in-Allo-Piano-Dac-Plus.patch b/target/linux/bcm27xx/patches-5.4/950-1022-Update-volume-controls-in-Allo-Piano-Dac-Plus.patch new file mode 100644 index 0000000000..ab5448a6ba --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1022-Update-volume-controls-in-Allo-Piano-Dac-Plus.patch @@ -0,0 +1,141 @@ +From cc1a511f1a582e2fbf9fa1e257f6b88cbcc2e0d9 Mon Sep 17 00:00:00 2001 +From: paul-1 <6473457+paul-1@users.noreply.github.com> +Date: Sat, 7 Nov 2020 12:01:44 -0500 +Subject: [PATCH] Update volume controls in Allo Piano Dac Plus + +Put control scaling back to 255. +Clean up what master/sub volume controls set in codec. +Remove more unneeded mixer controls. + +Signed-off-by: Paul Hermann <paul@picoreplayer.org> +--- + sound/soc/bcm/allo-piano-dac-plus.c | 56 +++++++++++++++++------------ + 1 file changed, 33 insertions(+), 23 deletions(-) + +--- a/sound/soc/bcm/allo-piano-dac-plus.c ++++ b/sound/soc/bcm/allo-piano-dac-plus.c +@@ -420,6 +420,7 @@ static int pcm512x_get_reg_sub(struct sn + unsigned int right_val = 0; + int ret; + rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name); ++ + ret = snd_soc_component_read(rtd->codec_dais[1]->component, + PCM512x_DIGITAL_VOLUME_3, &right_val); + if (ret < 0) +@@ -465,17 +466,20 @@ static int pcm512x_set_reg_sub(struct sn + ret); + } + +- if (glb_ptr->dual_mode != 1) { ++ // When in Dual Mono, Sub vol control should not set anything. ++ if (glb_ptr->dual_mode != 1) { //Not in Dual Mono mode ++ + ret = snd_soc_component_write(rtd->codec_dais[1]->component, + PCM512x_DIGITAL_VOLUME_2, (~left_val)); + if (ret < 0) + return ret; +- } + +- ret = snd_soc_component_write(rtd->codec_dais[1]->component, +- PCM512x_DIGITAL_VOLUME_3, (~right_val)); +- if (ret < 0) +- return ret; ++ ret = snd_soc_component_write(rtd->codec_dais[1]->component, ++ PCM512x_DIGITAL_VOLUME_3, (~right_val)); ++ if (ret < 0) ++ return ret; ++ ++ } + + return 1; + } +@@ -540,7 +544,7 @@ static int pcm512x_get_reg_master(struct + if ( ret < 0) + return ret; + +- if (glb_ptr->dual_mode == 1) { ++ if (glb_ptr->dual_mode == 1) { // in Dual Mono mode + ret = snd_soc_component_read(rtd->codec_dais[1]->component, + PCM512x_DIGITAL_VOLUME_3, &right_val); + if (ret < 0) +@@ -582,8 +586,21 @@ static int pcm512x_set_reg_master(struct + ret); + } + +- if (glb_ptr->dual_mode != 1) { ++ if (glb_ptr->dual_mode == 1) { //in Dual Mono Mode ++ ++ ret = snd_soc_component_write(rtd->codec_dais[0]->component, ++ PCM512x_DIGITAL_VOLUME_2, (~left_val)); ++ if (ret < 0) ++ return ret; ++ + ret = snd_soc_component_write(rtd->codec_dais[1]->component, ++ PCM512x_DIGITAL_VOLUME_3, (~right_val)); ++ if (ret < 0) ++ return ret; ++ ++ } else { ++ ++ ret = snd_soc_component_write(rtd->codec_dais[0]->component, + PCM512x_DIGITAL_VOLUME_2, (~left_val)); + if (ret < 0) + return ret; +@@ -594,16 +611,6 @@ static int pcm512x_set_reg_master(struct + return ret; + + } +- +- ret = snd_soc_component_write(rtd->codec_dais[1]->component, +- PCM512x_DIGITAL_VOLUME_3, (~right_val)); +- if (ret < 0) +- return ret; +- +- ret = snd_soc_component_write(rtd->codec_dais[0]->component, +- PCM512x_DIGITAL_VOLUME_2, (~left_val)); +- if (ret < 0) +- return ret; + return 1; + } + +@@ -697,7 +704,7 @@ static const struct snd_kcontrol_new all + + SOC_DOUBLE_R_EXT_TLV("Subwoofer Playback Volume", + PCM512x_DIGITAL_VOLUME_2, +- PCM512x_DIGITAL_VOLUME_3, 0, 207, 1, ++ PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, + pcm512x_get_reg_sub, + pcm512x_set_reg_sub, + digital_tlv_sub), +@@ -711,7 +718,7 @@ static const struct snd_kcontrol_new all + + SOC_DOUBLE_R_EXT_TLV("Master Playback Volume", + PCM512x_DIGITAL_VOLUME_2, +- PCM512x_DIGITAL_VOLUME_3, 0, 207, 1, ++ PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, + pcm512x_get_reg_master, + pcm512x_set_reg_master, + digital_tlv_master), +@@ -737,7 +744,11 @@ static const char * const codec_ctl_name + "Max Overclock DSP", + "Max Overclock PLL", + "Volume Ramp Down Emergency Rate", +- "Volume Ramp Down Emergency Step" ++ "Volume Ramp Down Emergency Step", ++ "Volume Ramp Up Rate", ++ "Volume Ramp Down Rate", ++ "Volume Ramp Up Step", ++ "Volume Ramp Down Step" + }; + + static int snd_allo_piano_dac_init(struct snd_soc_pcm_runtime *rtd) +@@ -774,8 +785,7 @@ static int snd_allo_piano_dac_init(struc + + // Remove codec controls + for (i = 0; i < ARRAY_SIZE(codec_ctl_pfx); i++) { +- // Start at 1, leave the Digital Volume control. +- for (j = 1; j < ARRAY_SIZE(codec_ctl_name); j++) { ++ for (j = 0; j < ARRAY_SIZE(codec_ctl_name); j++) { + char cname[256]; + + sprintf(cname, "%s %s", codec_ctl_pfx[i], codec_ctl_name[j]); diff --git a/target/linux/bcm27xx/patches-5.4/950-1023-media-i2c-imx219-Selection-compliance-fixes.patch b/target/linux/bcm27xx/patches-5.4/950-1023-media-i2c-imx219-Selection-compliance-fixes.patch new file mode 100644 index 0000000000..600e25ed26 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1023-media-i2c-imx219-Selection-compliance-fixes.patch @@ -0,0 +1,80 @@ +From de47ea073936726d9a5ad843908fd3074c1fb8f0 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil <hverkuil@xs4all.nl> +Date: Wed, 5 Aug 2020 12:57:21 +0200 +Subject: [PATCH] media: i2c: imx219: Selection compliance fixes + +To comply with the intended usage of the V4L2 selection target when +used to retrieve a sensor image properties, adjust the rectangles +returned by the imx219 driver. + +The top/left crop coordinates of the TGT_CROP rectangle were set to +(0, 0) instead of (8, 8) which is the offset from the larger physical +pixel array rectangle. This was also a mismatch with the default values +crop rectangle value, so this is corrected. Found with v4l2-compliance. + +While at it, add V4L2_SEL_TGT_CROP_BOUNDS support: CROP_DEFAULT and +CROP_BOUNDS have the same size as the non-active pixels are not readable +using the selection API. Found with v4l2-compliance. + +Fixes: e6d4ef7d58aa7 ("media: i2c: imx219: Implement get_selection") +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +[reword commit message, use macros for pixel offsets] +Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> +--- + drivers/media/i2c/imx219.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +--- a/drivers/media/i2c/imx219.c ++++ b/drivers/media/i2c/imx219.c +@@ -485,8 +485,8 @@ static const struct imx219_mode supporte + .width = 3280, + .height = 2464, + .crop = { +- .left = 0, +- .top = 0, ++ .left = IMX219_PIXEL_ARRAY_LEFT, ++ .top = IMX219_PIXEL_ARRAY_TOP, + .width = 3280, + .height = 2464 + }, +@@ -501,8 +501,8 @@ static const struct imx219_mode supporte + .width = 1920, + .height = 1080, + .crop = { +- .left = 680, +- .top = 692, ++ .left = 688, ++ .top = 700, + .width = 1920, + .height = 1080 + }, +@@ -517,8 +517,8 @@ static const struct imx219_mode supporte + .width = 1640, + .height = 1232, + .crop = { +- .left = 0, +- .top = 0, ++ .left = IMX219_PIXEL_ARRAY_LEFT, ++ .top = IMX219_PIXEL_ARRAY_TOP, + .width = 3280, + .height = 2464 + }, +@@ -533,8 +533,8 @@ static const struct imx219_mode supporte + .width = 640, + .height = 480, + .crop = { +- .left = 1000, +- .top = 752, ++ .left = 1008, ++ .top = 760, + .width = 1280, + .height = 960 + }, +@@ -1093,6 +1093,7 @@ static int imx219_get_selection(struct v + return 0; + + case V4L2_SEL_TGT_CROP_DEFAULT: ++ case V4L2_SEL_TGT_CROP_BOUNDS: + sel->r.top = IMX219_PIXEL_ARRAY_TOP; + sel->r.left = IMX219_PIXEL_ARRAY_LEFT; + sel->r.width = IMX219_PIXEL_ARRAY_WIDTH; diff --git a/target/linux/bcm27xx/patches-5.4/950-1024-media-bcm2835-unicam-Correctly-handle-error-propagat.patch b/target/linux/bcm27xx/patches-5.4/950-1024-media-bcm2835-unicam-Correctly-handle-error-propagat.patch new file mode 100644 index 0000000000..906e45b1bc --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1024-media-bcm2835-unicam-Correctly-handle-error-propagat.patch @@ -0,0 +1,27 @@ +From 85dae0158c3ba741e2cb815879b4d5d55b3254d7 Mon Sep 17 00:00:00 2001 +From: Naushir Patuck <naush@raspberrypi.com> +Date: Wed, 2 Dec 2020 15:22:23 +0000 +Subject: [PATCH] media: bcm2835-unicam: Correctly handle error + propagation for stream on + +On a failure in start_streaming(), the error code would not propagate to +the calling function on all conditions. This would cause the userland +caller to not know of the failure. + +Signed-off-by: Naushir Patuck <naush@raspberrypi.com> +--- + drivers/media/platform/bcm2835/bcm2835-unicam.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -1730,8 +1730,7 @@ err_disable_unicam: + unicam_disable(dev); + clk_disable_unprepare(dev->clock); + err_vpu_clock: +- ret = clk_set_min_rate(dev->vpu_clock, 0); +- if (ret) ++ if (clk_set_min_rate(dev->vpu_clock, 0)) + unicam_err(dev, "failed to reset the VPU clock\n"); + clk_disable_unprepare(dev->vpu_clock); + err_pm_put: diff --git a/target/linux/bcm27xx/patches-5.4/950-1025-media-bcm2835-unicam-Return-early-from-stop_streamin.patch b/target/linux/bcm27xx/patches-5.4/950-1025-media-bcm2835-unicam-Return-early-from-stop_streamin.patch new file mode 100644 index 0000000000..92c699a08b --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1025-media-bcm2835-unicam-Return-early-from-stop_streamin.patch @@ -0,0 +1,64 @@ +From 1e888ff376c880b2803aecea3f69d28dc2ae4349 Mon Sep 17 00:00:00 2001 +From: Naushir Patuck <naush@raspberrypi.com> +Date: Wed, 2 Dec 2020 15:26:09 +0000 +Subject: [PATCH] media: bcm2835-unicam: Return early from + stop_streaming() if stopped + +clk_disable_unprepare() is called unconditionally in stop_streaming(). +This is incorrect in the cases where start_streaming() fails, and +unprepares all clocks as part of the failure cleanup. To avoid this, +ensure that clk_disable_unprepare() is only called in stop_streaming() +if the clocks are in a prepared state. + +Signed-off-by: Naushir Patuck <naush@raspberrypi.com> +--- + drivers/media/platform/bcm2835/bcm2835-unicam.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -426,6 +426,8 @@ struct unicam_device { + struct clk *clock; + /* vpu clock handle */ + struct clk *vpu_clock; ++ /* clock status for error handling */ ++ bool clocks_enabled; + /* V4l2 device */ + struct v4l2_device v4l2_dev; + struct media_device mdev; +@@ -1724,6 +1726,7 @@ static int unicam_start_streaming(struct + goto err_disable_unicam; + } + ++ dev->clocks_enabled = true; + return 0; + + err_disable_unicam: +@@ -1750,8 +1753,6 @@ static void unicam_stop_streaming(struct + node->streaming = false; + + if (node->pad_id == IMAGE_PAD) { +- int ret; +- + /* + * Stop streaming the sensor and disable the peripheral. + * We cannot continue streaming embedded data with the +@@ -1762,12 +1763,13 @@ static void unicam_stop_streaming(struct + + unicam_disable(dev); + +- ret = clk_set_min_rate(dev->vpu_clock, 0); +- if (ret) +- unicam_err(dev, "failed to reset the min VPU clock\n"); ++ if (dev->clocks_enabled) { ++ if (clk_set_min_rate(dev->vpu_clock, 0)) ++ unicam_err(dev, "failed to reset the min VPU clock\n"); + +- clk_disable_unprepare(dev->vpu_clock); +- clk_disable_unprepare(dev->clock); ++ clk_disable_unprepare(dev->vpu_clock); ++ clk_disable_unprepare(dev->clock); ++ } + unicam_runtime_put(dev); + + } else if (node->pad_id == METADATA_PAD) { diff --git a/target/linux/bcm27xx/patches-5.4/950-1026-media-bcm2835-unicam-Clear-clock-state-when-stopping.patch b/target/linux/bcm27xx/patches-5.4/950-1026-media-bcm2835-unicam-Clear-clock-state-when-stopping.patch new file mode 100644 index 0000000000..3163107124 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1026-media-bcm2835-unicam-Clear-clock-state-when-stopping.patch @@ -0,0 +1,25 @@ +From 210f956f55dcc457386d8a4c9b4b5803c671d28a Mon Sep 17 00:00:00 2001 +From: Naushir Patuck <naush@raspberrypi.com> +Date: Wed, 2 Dec 2020 16:48:41 +0000 +Subject: [PATCH] media: bcm2835-unicam: Clear clock state when + stopping streaming + +Commit 65e08c465020d4c5b51afb452efc2246d80fd66f failed to clear the +clock state when the device stopped streaming. Fix this, as it might +again cause the same problems when doing an unprepare. + +Signed-off-by: Naushir Patuck <naush@raspberrypi.com> +--- + drivers/media/platform/bcm2835/bcm2835-unicam.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c ++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c +@@ -1769,6 +1769,7 @@ static void unicam_stop_streaming(struct + + clk_disable_unprepare(dev->vpu_clock); + clk_disable_unprepare(dev->clock); ++ dev->clocks_enabled = false; + } + unicam_runtime_put(dev); + diff --git a/target/linux/bcm27xx/patches-5.4/950-1027-ARM-dts-CM4-audio-pins-are-not-connected.patch b/target/linux/bcm27xx/patches-5.4/950-1027-ARM-dts-CM4-audio-pins-are-not-connected.patch new file mode 100644 index 0000000000..8ac82438e7 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1027-ARM-dts-CM4-audio-pins-are-not-connected.patch @@ -0,0 +1,21 @@ +From a679b9471f0ed1496b7d853becf38001282a738f Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 7 Dec 2020 09:35:57 +0000 +Subject: [PATCH] ARM: dts: CM4 audio pins are not connected + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 2 -- + 1 file changed, 2 deletions(-) + +--- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts +@@ -434,8 +434,6 @@ + + &gpio { + audio_pins: audio_pins { +- brcm,pins = <40 41>; +- brcm,function = <4>; + }; + }; + diff --git a/target/linux/bcm27xx/patches-5.4/950-1028-overlays-Add-PCF85063-and-PCF85063A-to-i2c-rtc.patch b/target/linux/bcm27xx/patches-5.4/950-1028-overlays-Add-PCF85063-and-PCF85063A-to-i2c-rtc.patch new file mode 100644 index 0000000000..f55f9f6836 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1028-overlays-Add-PCF85063-and-PCF85063A-to-i2c-rtc.patch @@ -0,0 +1,339 @@ +From ecfd415e5ae3fc05bf0c2b16a80f1d3e00447896 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 7 Dec 2020 08:49:53 +0000 +Subject: [PATCH] overlays: Add PCF85063 and PCF85063A to i2c-rtc + +Add support for the PCF85063 and PCF85063A RTC devices to the +i2c-rtc overlay. + +Also enable the device to be used on i2c0 (i2c_vc) on GPIOs 0&1 (use +parameter "i2c0") and GPIOs 44 & 45 (use parameter "i2c_csi_dsi"). + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/README | 8 ++ + .../arm/boot/dts/overlays/i2c-rtc-overlay.dts | 98 ++++++++++--------- + 2 files changed, 61 insertions(+), 45 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1243,6 +1243,10 @@ Params: abx80x Select o + + pcf2129 Select the PCF2129 device + ++ pcf85063 Select the PCF85363 device ++ ++ pcf85063a Select the PCF85363A device ++ + pcf8523 Select the PCF8523 device + + pcf85363 Select the PCF85363 device +@@ -1255,6 +1259,10 @@ Params: abx80x Select o + + sd3078 Select the ZXW Shenzhen whwave SD3078 device + ++ i2c0 Choose the I2C0 bus on GPIOs 0&1 ++ ++ i2c_csi_dsi Choose the I2C0 bus on GPIOs 44&45 ++ + addr Sets the address for the RTC. Note that the + device must be configured to use the specified + address. +--- a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts ++++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts +@@ -6,235 +6,238 @@ + compatible = "brcm,bcm2835"; + + fragment@0 { +- target = <&i2c_arm>; ++ target = <&i2cbus>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; +- status = "okay"; + + abx80x: abx80x@69 { + compatible = "abracon,abx80x"; + reg = <0x69>; + abracon,tc-diode = "standard"; + abracon,tc-resistor = <0>; +- status = "okay"; + }; + }; + }; + + fragment@1 { +- target = <&i2c_arm>; ++ target = <&i2cbus>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; +- status = "okay"; + + ds1307: ds1307@68 { + compatible = "dallas,ds1307"; + reg = <0x68>; +- status = "okay"; + }; + }; + }; + + fragment@2 { +- target = <&i2c_arm>; ++ target = <&i2cbus>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; +- status = "okay"; + + ds1339: ds1339@68 { + compatible = "dallas,ds1339"; + trickle-resistor-ohms = <0>; + reg = <0x68>; +- status = "okay"; + }; + }; + }; + + fragment@3 { +- target = <&i2c_arm>; ++ target = <&i2cbus>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; +- status = "okay"; + + ds3231: ds3231@68 { + compatible = "maxim,ds3231"; + reg = <0x68>; +- status = "okay"; + }; + }; + }; + + fragment@4 { +- target = <&i2c_arm>; ++ target = <&i2cbus>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; +- status = "okay"; + + mcp7940x: mcp7940x@6f { + compatible = "microchip,mcp7940x"; + reg = <0x6f>; +- status = "okay"; + }; + }; + }; + + fragment@5 { +- target = <&i2c_arm>; ++ target = <&i2cbus>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; +- status = "okay"; + + mcp7941x: mcp7941x@6f { + compatible = "microchip,mcp7941x"; + reg = <0x6f>; +- status = "okay"; + }; + }; + }; + + fragment@6 { +- target = <&i2c_arm>; ++ target = <&i2cbus>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; +- status = "okay"; + + pcf2127@51 { + compatible = "nxp,pcf2127"; + reg = <0x51>; +- status = "okay"; + }; + }; + }; + + fragment@7 { +- target = <&i2c_arm>; ++ target = <&i2cbus>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; +- status = "okay"; + + pcf8523: pcf8523@68 { + compatible = "nxp,pcf8523"; + reg = <0x68>; +- status = "okay"; + }; + }; + }; + + fragment@8 { +- target = <&i2c_arm>; ++ target = <&i2cbus>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; +- status = "okay"; + + pcf8563: pcf8563@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; +- status = "okay"; + }; + }; + }; + + fragment@9 { +- target = <&i2c_arm>; ++ target = <&i2cbus>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; +- status = "okay"; + + m41t62: m41t62@68 { + compatible = "st,m41t62"; + reg = <0x68>; +- status = "okay"; + }; + }; + }; + + fragment@10 { +- target = <&i2c_arm>; ++ target = <&i2cbus>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; +- status = "okay"; + + rv3028: rv3028@52 { + compatible = "microcrystal,rv3028"; + reg = <0x52>; +- status = "okay"; + }; + }; + }; + + fragment@11 { +- target = <&i2c_arm>; ++ target = <&i2cbus>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; +- status = "okay"; + + pcf2129@51 { + compatible = "nxp,pcf2129"; + reg = <0x51>; +- status = "okay"; + }; + }; + }; + + fragment@12 { +- target = <&i2c_arm>; ++ target = <&i2cbus>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; +- status = "okay"; + + pcf85363@51 { + compatible = "nxp,pcf85363"; + reg = <0x51>; +- status = "okay"; + }; + }; + }; + + fragment@13 { +- target = <&i2c_arm>; ++ target = <&i2cbus>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; +- status = "okay"; + + rv1805: rv1805@69 { + compatible = "microcrystal,rv1805"; + reg = <0x69>; + abracon,tc-diode = "standard"; + abracon,tc-resistor = <0>; +- status = "okay"; + }; + }; + }; + + fragment@14 { +- target = <&i2c_arm>; ++ target = <&i2cbus>; + __dormant__ { + #address-cells = <1>; + #size-cells = <0>; +- status = "okay"; + + sd3078: sd3078@32 { + compatible = "whwave,sd3078"; + reg = <0x32>; +- status = "okay"; + }; + }; + }; + ++ fragment@15 { ++ target = <&i2cbus>; ++ __dormant__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pcf85063@51 { ++ compatible = "nxp,pcf85063"; ++ reg = <0x51>; ++ }; ++ }; ++ }; ++ ++ fragment@16 { ++ target = <&i2cbus>; ++ __dormant__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pcf85063a@51 { ++ compatible = "nxp,pcf85063a"; ++ reg = <0x51>; ++ }; ++ }; ++ }; ++ ++ frag100: fragment@100 { ++ target = <&i2c_arm>; ++ i2cbus: __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ + __overrides__ { + abx80x = <0>,"+0"; + ds1307 = <0>,"+1"; +@@ -251,6 +254,11 @@ + pcf85363 = <0>,"+12"; + rv1805 = <0>,"+13"; + sd3078 = <0>,"+14"; ++ pcf85063 = <0>,"+15"; ++ pcf85063a = <0>,"+16"; ++ ++ i2c0 = <&frag100>, "target:0=",<&i2c0>; ++ i2c_csi_dsi = <&frag100>, "target:0=",<&i2c_csi_dsi>; + + addr = <&abx80x>, "reg:0", + <&ds1307>, "reg:0", diff --git a/target/linux/bcm27xx/patches-5.4/950-1029-overlays-Fix-cut-and-paste-error-in-README.patch b/target/linux/bcm27xx/patches-5.4/950-1029-overlays-Fix-cut-and-paste-error-in-README.patch new file mode 100644 index 0000000000..4741daec7c --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1029-overlays-Fix-cut-and-paste-error-in-README.patch @@ -0,0 +1,24 @@ +From 27f9953df117db0f38c5e597290435ecd6f3ed10 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Mon, 7 Dec 2020 17:18:39 +0000 +Subject: [PATCH] overlays: Fix cut-and-paste error in README + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/README | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1243,9 +1243,9 @@ Params: abx80x Select o + + pcf2129 Select the PCF2129 device + +- pcf85063 Select the PCF85363 device ++ pcf85063 Select the PCF85063 device + +- pcf85063a Select the PCF85363A device ++ pcf85063a Select the PCF85063A device + + pcf8523 Select the PCF8523 device + diff --git a/target/linux/bcm27xx/patches-5.4/950-1030-media-i2c-imx477-Selection-compliance-fixes.patch b/target/linux/bcm27xx/patches-5.4/950-1030-media-i2c-imx477-Selection-compliance-fixes.patch new file mode 100644 index 0000000000..e2ed71be39 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1030-media-i2c-imx477-Selection-compliance-fixes.patch @@ -0,0 +1,80 @@ +From cf3885ed8bb4194c5653a9a933b4ea669cdb51c2 Mon Sep 17 00:00:00 2001 +From: Naushir Patuck <naush@raspberrypi.com> +Date: Wed, 9 Dec 2020 11:30:12 +0000 +Subject: [PATCH] media: i2c: imx477: Selection compliance fixes + +To comply with the intended usage of the V4L2 selection target when +used to retrieve a sensor image properties, adjust the rectangles +returned by the imx477 driver. + +The top/left crop coordinates of the TGT_CROP rectangle were set to +(0, 0) instead of (8, 16) which is the offset from the larger physical +pixel array rectangle. This was also a mismatch with the default values +crop rectangle value, so this is corrected. Found with v4l2-compliance. + +While at it, add V4L2_SEL_TGT_CROP_BOUNDS support: CROP_DEFAULT and +CROP_BOUNDS have the same size as the non-active pixels are not readable +using the selection API. Found with v4l2-compliance. + +This commit mirrors 543790f777ba1b3264c168c653db6d415e7c983f done for +the imx219 sensor. + +Signed-off-by: Naushir Patuck <naush@raspberrypi.com> +--- + drivers/media/i2c/imx477.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +--- a/drivers/media/i2c/imx477.c ++++ b/drivers/media/i2c/imx477.c +@@ -900,8 +900,8 @@ static const struct imx477_mode supporte + .height = 3040, + .line_length_pix = 0x5dc0, + .crop = { +- .left = 0, +- .top = 0, ++ .left = IMX477_PIXEL_ARRAY_LEFT, ++ .top = IMX477_PIXEL_ARRAY_TOP, + .width = 4056, + .height = 3040, + }, +@@ -924,8 +924,8 @@ static const struct imx477_mode supporte + .height = 1520, + .line_length_pix = 0x31c4, + .crop = { +- .left = 0, +- .top = 0, ++ .left = IMX477_PIXEL_ARRAY_LEFT, ++ .top = IMX477_PIXEL_ARRAY_TOP, + .width = 4056, + .height = 3040, + }, +@@ -948,8 +948,8 @@ static const struct imx477_mode supporte + .height = 1080, + .line_length_pix = 0x31c4, + .crop = { +- .left = 0, +- .top = 440, ++ .left = IMX477_PIXEL_ARRAY_LEFT, ++ .top = IMX477_PIXEL_ARRAY_TOP + 440, + .width = 4056, + .height = 2600, + }, +@@ -983,8 +983,8 @@ static const struct imx477_mode supporte + * rectangle once the driver is expanded to represent + * its processing blocks with multiple subdevs. + */ +- .left = 4, +- .top = 0, ++ .left = IMX477_PIXEL_ARRAY_LEFT + 4, ++ .top = IMX477_PIXEL_ARRAY_TOP, + .width = 4052, + .height = 3040, + }, +@@ -1696,6 +1696,7 @@ static int imx477_get_selection(struct v + return 0; + + case V4L2_SEL_TGT_CROP_DEFAULT: ++ case V4L2_SEL_TGT_CROP_BOUNDS: + sel->r.left = IMX477_PIXEL_ARRAY_LEFT; + sel->r.top = IMX477_PIXEL_ARRAY_TOP; + sel->r.width = IMX477_PIXEL_ARRAY_WIDTH; diff --git a/target/linux/bcm27xx/patches-5.4/950-1031-net-lan78xx-Ack-pending-PHY-ints-when-resetting.patch b/target/linux/bcm27xx/patches-5.4/950-1031-net-lan78xx-Ack-pending-PHY-ints-when-resetting.patch new file mode 100644 index 0000000000..2dc2a13cb7 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1031-net-lan78xx-Ack-pending-PHY-ints-when-resetting.patch @@ -0,0 +1,32 @@ +From 598d6389f41c1e01b70df7d8b1056c3839e0c1c2 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Tue, 15 Dec 2020 16:38:37 +0000 +Subject: [PATCH] net: lan78xx: Ack pending PHY ints when resetting + +lan78xx_link_reset explicitly clears the MAC's view of the PHY's IRQ +status. In doing so it potentially leaves the PHY with a pending +interrupt that will never be acknowledged, at which point no further +interrupts will be generated. + +Avoid the problem by acknowledging any pending PHY interrupt after +clearing the MAC's status bit. + +See: https://github.com/raspberrypi/linux/issues/2937 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + drivers/net/usb/lan78xx.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -1181,6 +1181,9 @@ static int lan78xx_link_reset(struct lan + if (unlikely(ret < 0)) + return -EIO; + ++ /* Acknowledge any pending PHY interrupt, lest it be the last */ ++ phy_read(phydev, LAN88XX_INT_STS); ++ + phy_read_status(phydev); + + if (!phydev->link && dev->link_on) { diff --git a/target/linux/bcm27xx/patches-5.4/950-1032-overlays-mpu6050-Add-addr-parameter.patch b/target/linux/bcm27xx/patches-5.4/950-1032-overlays-mpu6050-Add-addr-parameter.patch new file mode 100644 index 0000000000..543b07ad08 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1032-overlays-mpu6050-Add-addr-parameter.patch @@ -0,0 +1,36 @@ +From fcf08ed99d1421158ca913a7b6a4893c31ee1bd5 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Tue, 15 Dec 2020 17:02:17 +0000 +Subject: [PATCH] overlays: mpu6050: Add 'addr' parameter + +The mpu6050 starts up at address 0x68 by default, but can be set to +0x69 if the ADO pin is pulled high. Give the overlay an addr parameter +to allow devices at the alternate address to be used. + +See: https://github.com/Hexxeh/rpi-firmware/issues/252 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/README | 1 + + arch/arm/boot/dts/overlays/mpu6050-overlay.dts | 1 + + 2 files changed, 2 insertions(+) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1876,6 +1876,7 @@ Name: mpu6050 + Info: Overlay for i2c connected mpu6050 imu + Load: dtoverlay=mpu6050,<param>=<val> + Params: interrupt GPIO pin for interrupt (default 4) ++ addr I2C address of the device (default 0x68) + + + Name: mz61581 +--- a/arch/arm/boot/dts/overlays/mpu6050-overlay.dts ++++ b/arch/arm/boot/dts/overlays/mpu6050-overlay.dts +@@ -24,5 +24,6 @@ + + __overrides__ { + interrupt = <&mpu6050>,"interrupts:0"; ++ addr = <&mpu6050>,"reg:0"; + }; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-1033-overlays-Add-missing-addresses-to-ads1015-ads1115.patch b/target/linux/bcm27xx/patches-5.4/950-1033-overlays-Add-missing-addresses-to-ads1015-ads1115.patch new file mode 100644 index 0000000000..6db63af319 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1033-overlays-Add-missing-addresses-to-ads1015-ads1115.patch @@ -0,0 +1,41 @@ +From 0a8f3e6fcdbad71c0c7e993f27117f3873438e5d Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Wed, 16 Dec 2020 09:28:17 +0000 +Subject: [PATCH] overlays: Add missing addresses to ads1015/ads1115 + +The overlays for the ads1015 and ads1115 I2C ADCs omitted the addresses +in the main device node names. As well as breaking the conventions for +I2C devices, this prevents the firmware from renaming them when the +"reg" property is modified, which in turn stops the overlays from being +instantiated multiple times. + +See: https://www.raspberrypi.org/forums/viewtopic.php?f=107&t=294465 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/overlays/ads1015-overlay.dts | 2 +- + arch/arm/boot/dts/overlays/ads1115-overlay.dts | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/overlays/ads1015-overlay.dts ++++ b/arch/arm/boot/dts/overlays/ads1015-overlay.dts +@@ -13,7 +13,7 @@ + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; +- ads1015: ads1015 { ++ ads1015: ads1015@48 { + compatible = "ti,ads1015"; + status = "okay"; + #address-cells = <1>; +--- a/arch/arm/boot/dts/overlays/ads1115-overlay.dts ++++ b/arch/arm/boot/dts/overlays/ads1115-overlay.dts +@@ -15,7 +15,7 @@ + #size-cells = <0>; + status = "okay"; + +- ads1115: ads1115 { ++ ads1115: ads1115@48 { + compatible = "ti,ads1115"; + status = "okay"; + #address-cells = <1>; diff --git a/target/linux/bcm27xx/patches-5.4/950-1034-media-i2c-ov5647-Selection-compliance-fixes.patch b/target/linux/bcm27xx/patches-5.4/950-1034-media-i2c-ov5647-Selection-compliance-fixes.patch new file mode 100644 index 0000000000..58ba7e16e6 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1034-media-i2c-ov5647-Selection-compliance-fixes.patch @@ -0,0 +1,88 @@ +From f05add64bf89b04310bc78606a5c70c0e97cb8b8 Mon Sep 17 00:00:00 2001 +From: Paul Elder <paul.elder@ideasonboard.com> +Date: Tue, 22 Dec 2020 14:27:46 +0900 +Subject: [PATCH] media: i2c: ov5647: Selection compliance fixes + +To comply with the intended usage of the V4L2 selection target when +used to retrieve a sensor image properties, adjust the rectangles +returned by the ov5647 driver. + +The top/left crop coordinates of the TGT_CROP rectangle were set to +(0, 0) instead of (16, 16) which is the offset from the larger physical +pixel array rectangle. This was also a mismatch with the default values +crop rectangle value, so this is corrected. Found with v4l2-compliance. + +While at it, add V4L2_SEL_TGT_CROP_BOUNDS support: CROP_DEFAULT and +CROP_BOUNDS have the same size as the non-active pixels are not readable +using the selection API. Found with v4l2-compliance. + +Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> +--- + drivers/media/i2c/ov5647.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +--- a/drivers/media/i2c/ov5647.c ++++ b/drivers/media/i2c/ov5647.c +@@ -606,8 +606,8 @@ static struct ov5647_mode supported_mode + .height = 480 + }, + .crop = { +- .left = 0, +- .top = 0, ++ .left = OV5647_PIXEL_ARRAY_LEFT, ++ .top = OV5647_PIXEL_ARRAY_TOP, + .width = 1280, + .height = 960, + }, +@@ -632,8 +632,8 @@ static struct ov5647_mode supported_mode + .height = 1944 + }, + .crop = { +- .left = 0, +- .top = 0, ++ .left = OV5647_PIXEL_ARRAY_LEFT, ++ .top = OV5647_PIXEL_ARRAY_TOP, + .width = 2592, + .height = 1944 + }, +@@ -656,8 +656,8 @@ static struct ov5647_mode supported_mode + .height = 1080 + }, + .crop = { +- .left = 348, +- .top = 434, ++ .left = 364, ++ .top = 450, + .width = 1928, + .height = 1080, + }, +@@ -679,8 +679,8 @@ static struct ov5647_mode supported_mode + .height = 972 + }, + .crop = { +- .left = 0, +- .top = 0, ++ .left = OV5647_PIXEL_ARRAY_LEFT, ++ .top = OV5647_PIXEL_ARRAY_TOP, + .width = 2592, + .height = 1944, + }, +@@ -703,8 +703,8 @@ static struct ov5647_mode supported_mode + .height = 480 + }, + .crop = { +- .left = 16, +- .top = 0, ++ .left = OV5647_PIXEL_ARRAY_LEFT, ++ .top = OV5647_PIXEL_ARRAY_TOP, + .width = 2560, + .height = 1920, + }, +@@ -1080,6 +1080,7 @@ static int ov5647_get_selection(struct v + return 0; + + case V4L2_SEL_TGT_CROP_DEFAULT: ++ case V4L2_SEL_TGT_CROP_BOUNDS: + sel->r.top = OV5647_PIXEL_ARRAY_TOP; + sel->r.left = OV5647_PIXEL_ARRAY_LEFT; + sel->r.width = OV5647_PIXEL_ARRAY_WIDTH; diff --git a/target/linux/bcm27xx/patches-5.4/950-1035-Add-overlay-for-Seeed-Studio-CAN-BUS-FD-HAT-4034.patch b/target/linux/bcm27xx/patches-5.4/950-1035-Add-overlay-for-Seeed-Studio-CAN-BUS-FD-HAT-4034.patch new file mode 100644 index 0000000000..a5bbbdd4e6 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1035-Add-overlay-for-Seeed-Studio-CAN-BUS-FD-HAT-4034.patch @@ -0,0 +1,217 @@ +From 4a314a9b9d91cacbf6be9dd521cf3abd3ae8bcef Mon Sep 17 00:00:00 2001 +From: menschel <menschel.p@posteo.de> +Date: Wed, 30 Dec 2020 21:55:34 +0100 +Subject: [PATCH] Add overlay for Seeed Studio CAN BUS FD HAT (#4034) + +This patch adds the overlay for the Seeed Studio CAN BUS FD HAT +with two CAN FD Channels and an RTC. +https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html + +The overlay was generated by +ovmerge -c mcp251xfd-overlay.dts,spi0-0,interrupt=25 \ + mcp251xfd-overlay.dts,spi0-1,interrupt=24 \ + i2c-rtc-overlay.dts,pcf85063 + + +Also, add description on how to generate overlays + +Signed-off-by: Patrick Menschel <menschel.p@posteo.de> +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 46 +++++++ + .../dts/overlays/seeed-can-fd-hat-overlay.dts | 117 ++++++++++++++++++ + 3 files changed, 164 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/seeed-can-fd-hat-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -159,6 +159,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + sc16is752-spi1.dtbo \ + sdhost.dtbo \ + sdio.dtbo \ ++ seeed-can-fd-hat.dtbo \ + sh1106-spi.dtbo \ + smi.dtbo \ + smi-dev.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -81,6 +81,44 @@ Parameters usually have default values, + mandatory. See the list of overlays below for a description of the parameters + and their defaults. + ++Making new Overlays based on existing Overlays ++============================================== ++ ++Recent overlays have been designed in a more general way, so that they can be ++adapted to hardware by changing their parameters. When you have additional ++hardware with more than one device of a kind, you end up using the same overlay ++multiple times with other parameters, e.g. ++ ++ # 2 CAN FD interfaces on spi but with different pins ++ dtoverlay=mcp251xfd,spi0-0,interrupt=25 ++ dtoverlay=mcp251xfd,spi0-1,interrupt=24 ++ ++ # a realtime clock on i2c ++ dtoverlay=i2c-rtc,pcf85063 ++ ++While this approach does work, it requires knowledge about the hardware design. ++It is more feasible to simplify things for the end user by providing a single ++overlay as it is done the traditional way. ++ ++A new overlay can be generated by using ovmerge utility. ++https://github.com/raspberrypi/utils/blob/master/ovmerge/ovmerge ++ ++To generate an overlay for the above configuration we pass the configuration ++to ovmerge and add the -c flag. ++ ++ ovmerge -c mcp251xfd-overlay.dts,spi0-0,interrupt=25 \ ++ mcp251xfd-overlay.dts,spi0-1,interrupt=24 \ ++ i2c-rtc-overlay.dts,pcf85063 \ ++ >> merged-overlay.dts ++ ++The -c option writes the command above as a comment into the overlay as ++a marker that this overlay is generated and how it was generated. ++After compiling the overlay it can be loaded in a single line. ++ ++ dtoverlay=merged ++ ++It does the same as the original configuration but without parameters. ++ + The Overlay and Parameter Reference + =================================== + +@@ -2422,6 +2460,14 @@ Info: This overlay is now deprecated. + Load: <Deprecated> + + ++Name: seeed-can-fd-hat ++Info: Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD channels and an ++ RTC. ++ https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html ++Load: dtoverlay=seeed-can-fd-hat ++Params: <None> ++ ++ + Name: sh1106-spi + Info: Overlay for SH1106 OLED via SPI using fbtft staging driver. + Load: dtoverlay=sh1106-spi,<param>=<val> +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/seeed-can-fd-hat-overlay.dts +@@ -0,0 +1,117 @@ ++// redo: ovmerge -c mcp251xfd-overlay.dts,spi0-0,interrupt=25 mcp251xfd-overlay.dts,spi0-1,interrupt=24 i2c-rtc-overlay.dts,pcf85063 ++ ++// Device tree overlay for https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html ++ ++/dts-v1/; ++/plugin/; ++ ++#include <dt-bindings/gpio/gpio.h> ++#include <dt-bindings/interrupt-controller/irq.h> ++#include <dt-bindings/pinctrl/bcm2835.h> ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ fragment@0 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ mcp251xfd_pins: mcp251xfd_spi0_0_pins { ++ brcm,pins = <25>; ++ brcm,function = <BCM2835_FSEL_GPIO_IN>; ++ }; ++ }; ++ }; ++ fragment@2 { ++ target-path = "/clocks"; ++ __overlay__ { ++ clk_mcp251xfd_osc: mcp251xfd-spi0-0-osc { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <40000000>; ++ }; ++ }; ++ }; ++ fragment@3 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ mcp251xfd@0 { ++ compatible = "microchip,mcp251xfd"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mcp251xfd_pins>; ++ spi-max-frequency = <20000000>; ++ interrupt-parent = <&gpio>; ++ interrupts = <25 IRQ_TYPE_LEVEL_LOW>; ++ clocks = <&clk_mcp251xfd_osc>; ++ }; ++ }; ++ }; ++ fragment@4 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ fragment@5 { ++ target = <&gpio>; ++ __overlay__ { ++ mcp251xfd_pins_1: mcp251xfd_spi0_1_pins { ++ brcm,pins = <24>; ++ brcm,function = <BCM2835_FSEL_GPIO_IN>; ++ }; ++ }; ++ }; ++ fragment@6 { ++ target-path = "/clocks"; ++ __overlay__ { ++ clk_mcp251xfd_osc_1: mcp251xfd-spi0-1-osc { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <40000000>; ++ }; ++ }; ++ }; ++ fragment@7 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ mcp251xfd@1 { ++ compatible = "microchip,mcp251xfd"; ++ reg = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mcp251xfd_pins_1>; ++ spi-max-frequency = <20000000>; ++ interrupt-parent = <&gpio>; ++ interrupts = <24 IRQ_TYPE_LEVEL_LOW>; ++ clocks = <&clk_mcp251xfd_osc_1>; ++ }; ++ }; ++ }; ++ fragment@8 { ++ target = <&i2cbus>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pcf85063@51 { ++ compatible = "nxp,pcf85063"; ++ reg = <0x51>; ++ }; ++ }; ++ }; ++ fragment@9 { ++ target = <&i2c_arm>; ++ i2cbus: __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-5.4/950-1036-overlays-Rebuild-upstream-with-latest-ovmerge.patch b/target/linux/bcm27xx/patches-5.4/950-1036-overlays-Rebuild-upstream-with-latest-ovmerge.patch new file mode 100644 index 0000000000..b2e32cd9aa --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1036-overlays-Rebuild-upstream-with-latest-ovmerge.patch @@ -0,0 +1,173 @@ +From 6091a6c5536f422df652c4a14725de7dd1fc5e0f Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Wed, 30 Dec 2020 20:00:38 +0000 +Subject: [PATCH] overlays: Rebuild "upstream" with latest ovmerge + +The latest ovmerge drops disabled fragments, causing the "upstream" +overlay to change. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + .../boot/dts/overlays/upstream-overlay.dts | 38 +++++++------------ + .../dts/overlays/upstream-pi4-overlay.dts | 28 +------------- + 2 files changed, 15 insertions(+), 51 deletions(-) + +--- a/arch/arm/boot/dts/overlays/upstream-overlay.dts ++++ b/arch/arm/boot/dts/overlays/upstream-overlay.dts +@@ -8,96 +8,84 @@ + / { + compatible = "brcm,bcm2835"; + fragment@0 { +- target = <&cma>; +- __dormant__ { +- size = <0x10000000>; +- }; +- }; +- fragment@1 { + target = <&i2c2>; + __overlay__ { + status = "okay"; + }; + }; +- fragment@2 { ++ fragment@1 { + target = <&fb>; + __overlay__ { + status = "disabled"; + }; + }; +- fragment@3 { ++ fragment@2 { + target = <&pixelvalve0>; + __overlay__ { + status = "okay"; + }; + }; +- fragment@4 { ++ fragment@3 { + target = <&pixelvalve1>; + __overlay__ { + status = "okay"; + }; + }; +- fragment@5 { ++ fragment@4 { + target = <&pixelvalve2>; + __overlay__ { + status = "okay"; + }; + }; +- fragment@6 { ++ fragment@5 { + target = <&hvs>; + __overlay__ { + status = "okay"; + }; + }; +- fragment@7 { ++ fragment@6 { + target = <&hdmi>; + __overlay__ { + status = "okay"; + }; + }; +- fragment@8 { ++ fragment@7 { + target = <&v3d>; + __overlay__ { + status = "okay"; + }; + }; +- fragment@9 { ++ fragment@8 { + target = <&vc4>; + __overlay__ { + status = "okay"; + }; + }; +- fragment@10 { ++ fragment@9 { + target = <&clocks>; + __overlay__ { + claim-clocks = <BCM2835_PLLD_DSI0 BCM2835_PLLD_DSI1 BCM2835_PLLH_AUX BCM2835_PLLH_PIX>; + }; + }; +- fragment@11 { ++ fragment@10 { + target = <&vec>; + __overlay__ { + status = "okay"; + }; + }; +- fragment@12 { ++ fragment@11 { + target = <&txp>; + __overlay__ { + status = "okay"; + }; + }; +- fragment@13 { +- target = <&hdmi>; +- __dormant__ { +- dmas; +- }; +- }; +- fragment@14 { ++ fragment@12 { + target = <&audio>; + __overlay__ { + brcm,disable-hdmi; + }; + }; +- fragment@15 { ++ fragment@13 { + target = <&usb>; + #address-cells = <1>; + #size-cells = <1>; +--- a/arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts ++++ b/arch/arm/boot/dts/overlays/upstream-pi4-overlay.dts +@@ -110,42 +110,18 @@ + }; + }; + fragment@17 { +- target = <&hdmi0>; +- __dormant__ { +- dmas; +- }; +- }; +- fragment@18 { +- target = <&hdmi1>; +- __dormant__ { +- dmas; +- }; +- }; +- fragment@19 { + target = <&audio>; + __overlay__ { + brcm,disable-hdmi; + }; + }; +- fragment@20 { ++ fragment@18 { + target = <&dvp>; + __overlay__ { + status = "okay"; + }; + }; +- fragment@21 { +- target = <&pixelvalve3>; +- __dormant__ { +- status = "okay"; +- }; +- }; +- fragment@22 { +- target = <&vec>; +- __dormant__ { +- status = "okay"; +- }; +- }; +- fragment@23 { ++ fragment@19 { + target = <&usb>; + #address-cells = <1>; + #size-cells = <1>; diff --git a/target/linux/bcm27xx/patches-5.4/950-1037-overlays-give-Seeed-Studio-CAN-BUS-FD-HAT-a-v2-postf.patch b/target/linux/bcm27xx/patches-5.4/950-1037-overlays-give-Seeed-Studio-CAN-BUS-FD-HAT-a-v2-postf.patch new file mode 100644 index 0000000000..185c16c800 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1037-overlays-give-Seeed-Studio-CAN-BUS-FD-HAT-a-v2-postf.patch @@ -0,0 +1,286 @@ +From 6b458078a50b9332e799e045f91c288a7ff8d8ca Mon Sep 17 00:00:00 2001 +From: Marc Kleine-Budde <mkl@pengutronix.de> +Date: Sat, 2 Jan 2021 21:08:59 +0100 +Subject: [PATCH] overlays: give Seeed Studio CAN BUS FD HAT a -v2 + postfix + +There are several versions of the Seeed Studio CAN BUS FD HAT. This is the +second version, based on the mcp2518fd, so give it a -v2 postfix. + +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> +--- + arch/arm/boot/dts/overlays/Makefile | 2 +- + arch/arm/boot/dts/overlays/README | 8 ++++---- + ...fd-hat-overlay.dts => seeed-can-fd-hat-v2-overlay.dts} | 0 + 3 files changed, 5 insertions(+), 5 deletions(-) + rename arch/arm/boot/dts/overlays/{seeed-can-fd-hat-overlay.dts => seeed-can-fd-hat-v2-overlay.dts} (100%) + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -159,7 +159,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + sc16is752-spi1.dtbo \ + sdhost.dtbo \ + sdio.dtbo \ +- seeed-can-fd-hat.dtbo \ ++ seeed-can-fd-hat-v2.dtbo \ + sh1106-spi.dtbo \ + smi.dtbo \ + smi-dev.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -2460,11 +2460,11 @@ Info: This overlay is now deprecated. + Load: <Deprecated> + + +-Name: seeed-can-fd-hat +-Info: Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD channels and an +- RTC. ++Name: seeed-can-fd-hat-v2 ++Info: Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD channels ++ (based on the mcp2518fd) and an RTC. + https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html +-Load: dtoverlay=seeed-can-fd-hat ++Load: dtoverlay=seeed-can-fd-hat-v2 + Params: <None> + + +--- a/arch/arm/boot/dts/overlays/seeed-can-fd-hat-overlay.dts ++++ /dev/null +@@ -1,117 +0,0 @@ +-// redo: ovmerge -c mcp251xfd-overlay.dts,spi0-0,interrupt=25 mcp251xfd-overlay.dts,spi0-1,interrupt=24 i2c-rtc-overlay.dts,pcf85063 +- +-// Device tree overlay for https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html +- +-/dts-v1/; +-/plugin/; +- +-#include <dt-bindings/gpio/gpio.h> +-#include <dt-bindings/interrupt-controller/irq.h> +-#include <dt-bindings/pinctrl/bcm2835.h> +- +-/ { +- compatible = "brcm,bcm2835"; +- fragment@0 { +- target = <&spidev0>; +- __overlay__ { +- status = "disabled"; +- }; +- }; +- fragment@1 { +- target = <&gpio>; +- __overlay__ { +- mcp251xfd_pins: mcp251xfd_spi0_0_pins { +- brcm,pins = <25>; +- brcm,function = <BCM2835_FSEL_GPIO_IN>; +- }; +- }; +- }; +- fragment@2 { +- target-path = "/clocks"; +- __overlay__ { +- clk_mcp251xfd_osc: mcp251xfd-spi0-0-osc { +- #clock-cells = <0>; +- compatible = "fixed-clock"; +- clock-frequency = <40000000>; +- }; +- }; +- }; +- fragment@3 { +- target = <&spi0>; +- __overlay__ { +- status = "okay"; +- #address-cells = <1>; +- #size-cells = <0>; +- mcp251xfd@0 { +- compatible = "microchip,mcp251xfd"; +- reg = <0>; +- pinctrl-names = "default"; +- pinctrl-0 = <&mcp251xfd_pins>; +- spi-max-frequency = <20000000>; +- interrupt-parent = <&gpio>; +- interrupts = <25 IRQ_TYPE_LEVEL_LOW>; +- clocks = <&clk_mcp251xfd_osc>; +- }; +- }; +- }; +- fragment@4 { +- target = <&spidev1>; +- __overlay__ { +- status = "disabled"; +- }; +- }; +- fragment@5 { +- target = <&gpio>; +- __overlay__ { +- mcp251xfd_pins_1: mcp251xfd_spi0_1_pins { +- brcm,pins = <24>; +- brcm,function = <BCM2835_FSEL_GPIO_IN>; +- }; +- }; +- }; +- fragment@6 { +- target-path = "/clocks"; +- __overlay__ { +- clk_mcp251xfd_osc_1: mcp251xfd-spi0-1-osc { +- #clock-cells = <0>; +- compatible = "fixed-clock"; +- clock-frequency = <40000000>; +- }; +- }; +- }; +- fragment@7 { +- target = <&spi0>; +- __overlay__ { +- status = "okay"; +- #address-cells = <1>; +- #size-cells = <0>; +- mcp251xfd@1 { +- compatible = "microchip,mcp251xfd"; +- reg = <1>; +- pinctrl-names = "default"; +- pinctrl-0 = <&mcp251xfd_pins_1>; +- spi-max-frequency = <20000000>; +- interrupt-parent = <&gpio>; +- interrupts = <24 IRQ_TYPE_LEVEL_LOW>; +- clocks = <&clk_mcp251xfd_osc_1>; +- }; +- }; +- }; +- fragment@8 { +- target = <&i2cbus>; +- __overlay__ { +- #address-cells = <1>; +- #size-cells = <0>; +- pcf85063@51 { +- compatible = "nxp,pcf85063"; +- reg = <0x51>; +- }; +- }; +- }; +- fragment@9 { +- target = <&i2c_arm>; +- i2cbus: __overlay__ { +- status = "okay"; +- }; +- }; +-}; +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/seeed-can-fd-hat-v2-overlay.dts +@@ -0,0 +1,117 @@ ++// redo: ovmerge -c mcp251xfd-overlay.dts,spi0-0,interrupt=25 mcp251xfd-overlay.dts,spi0-1,interrupt=24 i2c-rtc-overlay.dts,pcf85063 ++ ++// Device tree overlay for https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html ++ ++/dts-v1/; ++/plugin/; ++ ++#include <dt-bindings/gpio/gpio.h> ++#include <dt-bindings/interrupt-controller/irq.h> ++#include <dt-bindings/pinctrl/bcm2835.h> ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ fragment@0 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ mcp251xfd_pins: mcp251xfd_spi0_0_pins { ++ brcm,pins = <25>; ++ brcm,function = <BCM2835_FSEL_GPIO_IN>; ++ }; ++ }; ++ }; ++ fragment@2 { ++ target-path = "/clocks"; ++ __overlay__ { ++ clk_mcp251xfd_osc: mcp251xfd-spi0-0-osc { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <40000000>; ++ }; ++ }; ++ }; ++ fragment@3 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ mcp251xfd@0 { ++ compatible = "microchip,mcp251xfd"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mcp251xfd_pins>; ++ spi-max-frequency = <20000000>; ++ interrupt-parent = <&gpio>; ++ interrupts = <25 IRQ_TYPE_LEVEL_LOW>; ++ clocks = <&clk_mcp251xfd_osc>; ++ }; ++ }; ++ }; ++ fragment@4 { ++ target = <&spidev1>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ fragment@5 { ++ target = <&gpio>; ++ __overlay__ { ++ mcp251xfd_pins_1: mcp251xfd_spi0_1_pins { ++ brcm,pins = <24>; ++ brcm,function = <BCM2835_FSEL_GPIO_IN>; ++ }; ++ }; ++ }; ++ fragment@6 { ++ target-path = "/clocks"; ++ __overlay__ { ++ clk_mcp251xfd_osc_1: mcp251xfd-spi0-1-osc { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <40000000>; ++ }; ++ }; ++ }; ++ fragment@7 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ mcp251xfd@1 { ++ compatible = "microchip,mcp251xfd"; ++ reg = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mcp251xfd_pins_1>; ++ spi-max-frequency = <20000000>; ++ interrupt-parent = <&gpio>; ++ interrupts = <24 IRQ_TYPE_LEVEL_LOW>; ++ clocks = <&clk_mcp251xfd_osc_1>; ++ }; ++ }; ++ }; ++ fragment@8 { ++ target = <&i2cbus>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pcf85063@51 { ++ compatible = "nxp,pcf85063"; ++ reg = <0x51>; ++ }; ++ }; ++ }; ++ fragment@9 { ++ target = <&i2c_arm>; ++ i2cbus: __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-5.4/950-1038-overlays-Add-overlay-for-Seeed-Studio-CAN-BUS-FD-HAT.patch b/target/linux/bcm27xx/patches-5.4/950-1038-overlays-Add-overlay-for-Seeed-Studio-CAN-BUS-FD-HAT.patch new file mode 100644 index 0000000000..6ae1680d88 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1038-overlays-Add-overlay-for-Seeed-Studio-CAN-BUS-FD-HAT.patch @@ -0,0 +1,192 @@ +From 42c792400770ec57cafce87cb9594a948d6c0700 Mon Sep 17 00:00:00 2001 +From: Marc Kleine-Budde <mkl@pengutronix.de> +Date: Sat, 2 Jan 2021 21:38:58 +0100 +Subject: [PATCH] overlays: Add overlay for Seeed Studio CAN BUS FD + HAT v1 (based on mcp2517fd) + +This patch adds the overlay for the Seeed Studio CAN BUS FD HAT v1 with two CAN +FD Channels (based on mcp2517fd). + +https://www.seeedstudio.com/2-Channel-CAN-BUS-FD-Shield-for-Raspberry-Pi-p-4072.html + +The overlay was generated by: +ovmerge -c spi1-1cs-overlay.dts,cs0_pin=18,cs0_spidev=false \ + mcp251xfd-overlay.dts,spi0-0,interrupt=25 \ + mcp251xfd-overlay.dts,spi1-0,interrupt=24 + +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 8 + + .../overlays/seeed-can-fd-hat-v1-overlay.dts | 138 ++++++++++++++++++ + 3 files changed, 147 insertions(+) + create mode 100644 arch/arm/boot/dts/overlays/seeed-can-fd-hat-v1-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -159,6 +159,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + sc16is752-spi1.dtbo \ + sdhost.dtbo \ + sdio.dtbo \ ++ seeed-can-fd-hat-v1.dtbo \ + seeed-can-fd-hat-v2.dtbo \ + sh1106-spi.dtbo \ + smi.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -2460,6 +2460,14 @@ Info: This overlay is now deprecated. + Load: <Deprecated> + + ++Name: seeed-can-fd-hat-v1 ++Info: Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD channels ++ (based on the mcp2517fd). ++ https://www.seeedstudio.com/2-Channel-CAN-BUS-FD-Shield-for-Raspberry-Pi-p-4072.html ++Load: dtoverlay=seeed-can-fd-hat-v1 ++Params: <None> ++ ++ + Name: seeed-can-fd-hat-v2 + Info: Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD channels + (based on the mcp2518fd) and an RTC. +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/seeed-can-fd-hat-v1-overlay.dts +@@ -0,0 +1,138 @@ ++// redo: ovmerge -c spi1-1cs-overlay.dts,cs0_pin=18,cs0_spidev=false mcp251xfd-overlay.dts,spi0-0,interrupt=25 mcp251xfd-overlay.dts,spi1-0,interrupt=24 ++ ++// Device tree overlay for https://www.seeedstudio.com/2-Channel-CAN-BUS-FD-Shield-for-Raspberry-Pi-p-4072.html ++ ++/dts-v1/; ++/plugin/; ++ ++#include <dt-bindings/gpio/gpio.h> ++#include <dt-bindings/interrupt-controller/irq.h> ++#include <dt-bindings/pinctrl/bcm2835.h> ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ fragment@0 { ++ target = <&gpio>; ++ __overlay__ { ++ spi1_pins: spi1_pins { ++ brcm,pins = <19 20 21>; ++ brcm,function = <3>; ++ }; ++ spi1_cs_pins: spi1_cs_pins { ++ brcm,pins = <18>; ++ brcm,function = <1>; ++ }; ++ }; ++ }; ++ fragment@1 { ++ target = <&spi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi1_pins &spi1_cs_pins>; ++ cs-gpios = <&gpio 18 1>; ++ status = "okay"; ++ spidev@0 { ++ compatible = "spidev"; ++ reg = <0>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <125000000>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ fragment@2 { ++ target = <&aux>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ fragment@3 { ++ target = <&spidev0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ fragment@4 { ++ target = <&gpio>; ++ __overlay__ { ++ mcp251xfd_pins: mcp251xfd_spi0_0_pins { ++ brcm,pins = <25>; ++ brcm,function = <BCM2835_FSEL_GPIO_IN>; ++ }; ++ }; ++ }; ++ fragment@5 { ++ target-path = "/clocks"; ++ __overlay__ { ++ clk_mcp251xfd_osc: mcp251xfd-spi0-0-osc { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <40000000>; ++ }; ++ }; ++ }; ++ fragment@6 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ mcp251xfd@0 { ++ compatible = "microchip,mcp251xfd"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mcp251xfd_pins>; ++ spi-max-frequency = <20000000>; ++ interrupt-parent = <&gpio>; ++ interrupts = <25 IRQ_TYPE_LEVEL_LOW>; ++ clocks = <&clk_mcp251xfd_osc>; ++ }; ++ }; ++ }; ++ fragment@7 { ++ target-path = "spi1/spidev@0"; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ fragment@8 { ++ target = <&gpio>; ++ __overlay__ { ++ mcp251xfd_pins_1: mcp251xfd_spi1_0_pins { ++ brcm,pins = <24>; ++ brcm,function = <BCM2835_FSEL_GPIO_IN>; ++ }; ++ }; ++ }; ++ fragment@9 { ++ target-path = "/clocks"; ++ __overlay__ { ++ clk_mcp251xfd_osc_1: mcp251xfd-spi1-0-osc { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <40000000>; ++ }; ++ }; ++ }; ++ fragment@10 { ++ target = <&spi1>; ++ __overlay__ { ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ mcp251xfd@0 { ++ compatible = "microchip,mcp251xfd"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mcp251xfd_pins_1>; ++ spi-max-frequency = <20000000>; ++ interrupt-parent = <&gpio>; ++ interrupts = <24 IRQ_TYPE_LEVEL_LOW>; ++ clocks = <&clk_mcp251xfd_osc_1>; ++ }; ++ }; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-5.4/950-1039-overlays-add-wm8960-soundcard-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-1039-overlays-add-wm8960-soundcard-overlay.patch new file mode 100644 index 0000000000..fa2f54cacf --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1039-overlays-add-wm8960-soundcard-overlay.patch @@ -0,0 +1,129 @@ +From 4b26aad69c65e141e7ad5187c558d20304eb4bd8 Mon Sep 17 00:00:00 2001 +From: Aaron Shaw <shawaj@gmail.com> +Date: Sat, 2 Jan 2021 02:34:03 +0000 +Subject: [PATCH] overlays: add wm8960-soundcard overlay + +add overlay for waveshare wm8960 simple-audio-card + +Change-type: patch +Signed-off-by: Aaron Shaw <shawaj@gmail.com> +--- + arch/arm/boot/dts/overlays/Makefile | 3 +- + arch/arm/boot/dts/overlays/README | 7 ++ + .../dts/overlays/wm8960-soundcard-overlay.dts | 82 +++++++++++++++++++ + 3 files changed, 91 insertions(+), 1 deletion(-) + create mode 100644 arch/arm/boot/dts/overlays/wm8960-soundcard-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -210,7 +210,8 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + w1-gpio.dtbo \ + w1-gpio-pullup.dtbo \ + w5500.dtbo \ +- wittypi.dtbo ++ wittypi.dtbo \ ++ wm8960-soundcard.dtbo + + targets += dtbs dtbs_install + targets += $(dtbo-y) +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -3073,6 +3073,13 @@ Params: led_gpio GPIO for + "default-on") + + ++Name: wm8960-soundcard ++Info: Overlay for the Waveshare wm8960 soundcard ++Load: dtoverlay=wm8960-soundcard,<param>=<val> ++Params: alsaname Changes the card name in ALSA ++ compatible Changes the codec compatibility ++ ++ + Troubleshooting + =============== + +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/wm8960-soundcard-overlay.dts +@@ -0,0 +1,82 @@ ++// Definitions for Waveshare WM8960 https://github.com/waveshare/WM8960-Audio-HAT ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path="/"; ++ __overlay__ { ++ wm8960_mclk: wm8960_mclk { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <12288000>; ++ }; ++ }; ++ }; ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ wm8960: wm8960 { ++ compatible = "wlf,wm8960"; ++ reg = <0x1a>; ++ #sound-dai-cells = <0>; ++ AVDD-supply = <&vdd_5v0_reg>; ++ DVDD-supply = <&vdd_3v3_reg>; ++ }; ++ }; ++ }; ++ ++ ++ fragment@3 { ++ target = <&sound>; ++ slave_overlay: __overlay__ { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,name = "wm8960-soundcard"; ++ status = "okay"; ++ ++ simple-audio-card,widgets = ++ "Microphone", "Mic Jack", ++ "Line", "Line In", ++ "Line", "Line Out", ++ "Speaker", "Speaker", ++ "Headphone", "Headphone Jack"; ++ simple-audio-card,routing = ++ "Headphone Jack", "HP_L", ++ "Headphone Jack", "HP_R", ++ "Speaker", "SPK_LP", ++ "Speaker", "SPK_LN", ++ "LINPUT1", "Mic Jack", ++ "LINPUT3", "Mic Jack", ++ "RINPUT1", "Mic Jack", ++ "RINPUT2", "Mic Jack"; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&i2s>; ++ }; ++ dailink0_slave: simple-audio-card,codec { ++ sound-dai = <&wm8960>; ++ clocks = <&wm8960_mclk>; ++ clock-names = "mclk"; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ alsaname = <&slave_overlay>,"simple-audio-card,name"; ++ compatible = <&wm8960>,"compatible"; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-5.4/950-1040-overlays-add-spi-override-to-merus-amp-overlay.patch b/target/linux/bcm27xx/patches-5.4/950-1040-overlays-add-spi-override-to-merus-amp-overlay.patch new file mode 100644 index 0000000000..213d29367d --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1040-overlays-add-spi-override-to-merus-amp-overlay.patch @@ -0,0 +1,44 @@ +From 2b4ffcc3d1a589154928830e56d4b8efdf15e368 Mon Sep 17 00:00:00 2001 +From: Aaron Shaw <shawaj@gmail.com> +Date: Sat, 26 Dec 2020 03:13:14 +0000 +Subject: [PATCH] overlays: add spi override to merus-amp overlay + +adds an override to the merus-amp overlay to turn the spi bus off + +Change-type: patch +Signed-off-by: Aaron Shaw <shawaj@gmail.com> +--- + arch/arm/boot/dts/overlays/README | 4 ++-- + arch/arm/boot/dts/overlays/merus-amp-overlay.dts | 10 ++++++++++ + 2 files changed, 12 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1870,8 +1870,8 @@ Params: speed Display + + Name: merus-amp + Info: Configures the merus-amp audio card +-Load: dtoverlay=merus-amp +-Params: <None> ++Load: dtoverlay=merus-amp,<param>=<val> ++Params: spioff Turn SPI bus off + + + Name: midi-uart0 +--- a/arch/arm/boot/dts/overlays/merus-amp-overlay.dts ++++ b/arch/arm/boot/dts/overlays/merus-amp-overlay.dts +@@ -57,4 +57,14 @@ + status = "okay"; + }; + }; ++ ++ fragment@4 { ++ target = <&spi0>; ++ frag4: __overlay__ { ++ }; ++ }; ++ ++ __overrides__ { ++ spioff = <&frag4>, "status=disabled"; ++ }; + }; diff --git a/target/linux/bcm27xx/patches-5.4/950-1041-overlays-seeed-can-fd-hat-clarify-how-to-identify-HA.patch b/target/linux/bcm27xx/patches-5.4/950-1041-overlays-seeed-can-fd-hat-clarify-how-to-identify-HA.patch new file mode 100644 index 0000000000..d622888e1f --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1041-overlays-seeed-can-fd-hat-clarify-how-to-identify-HA.patch @@ -0,0 +1,45 @@ +From 426116286821ed9ce10e415ffdebb2c55e728050 Mon Sep 17 00:00:00 2001 +From: Marc Kleine-Budde <mkl@pengutronix.de> +Date: Sat, 9 Jan 2021 17:03:32 +0100 +Subject: [PATCH] overlays: seeed-can-fd-hat: clarify how to identify + HAT version + +It turns out the used CAN SPI chip is not a good way to identify the version of +the CAN HAT. + +There are two different board layouts of the Seeed Studio CAN BUS FD HAT. The +v1 board doesn't have a battery holder, while the v2 board has. Update the +overlay README accordinly. + +Link: https://github.com/Seeed-Studio/seeed-linux-dtoverlays/issues/13 +Cc: Patrick Menschel <menschel.p@posteo.de> +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> +--- + arch/arm/boot/dts/overlays/README | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -2461,16 +2461,18 @@ Load: <Deprecated> + + + Name: seeed-can-fd-hat-v1 +-Info: Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD channels +- (based on the mcp2517fd). ++Info: Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD ++ channels without RTC. Use this overlay if your HAT has no ++ battery holder. + https://www.seeedstudio.com/2-Channel-CAN-BUS-FD-Shield-for-Raspberry-Pi-p-4072.html + Load: dtoverlay=seeed-can-fd-hat-v1 + Params: <None> + + + Name: seeed-can-fd-hat-v2 +-Info: Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD channels +- (based on the mcp2518fd) and an RTC. ++Info: Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD ++ channels and an RTC. Use this overlay if your HAT has a ++ battery holder. + https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html + Load: dtoverlay=seeed-can-fd-hat-v2 + Params: <None> diff --git a/target/linux/bcm27xx/patches-5.4/950-1042-uapi-bcm2835-isp-Add-colour-denoise-configuration.patch b/target/linux/bcm27xx/patches-5.4/950-1042-uapi-bcm2835-isp-Add-colour-denoise-configuration.patch new file mode 100644 index 0000000000..48ffc017f0 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1042-uapi-bcm2835-isp-Add-colour-denoise-configuration.patch @@ -0,0 +1,56 @@ +From b920f23b301503d6127f3fcdc3c88e24aa470679 Mon Sep 17 00:00:00 2001 +From: Naushir Patuck <naush@raspberrypi.com> +Date: Thu, 14 Jan 2021 09:18:42 +0000 +Subject: [PATCH] uapi: bcm2835-isp: Add colour denoise configuration + +Add a configuration structure for colour denoise to the bcm2835_isp +driver. + +Signed-off-by: Naushir Patuck <naush@raspberrypi.com> +--- + include/uapi/linux/bcm2835-isp.h | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +--- a/include/uapi/linux/bcm2835-isp.h ++++ b/include/uapi/linux/bcm2835-isp.h +@@ -31,6 +31,8 @@ + (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0007) + #define V4L2_CID_USER_BCM2835_ISP_DPC \ + (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0008) ++#define V4L2_CID_USER_BCM2835_ISP_CDN \ ++ (V4L2_CID_USER_BCM2835_ISP_BASE + 0x0009) + + /* + * All structs below are directly mapped onto the equivalent structs in +@@ -176,6 +178,31 @@ struct bcm2835_isp_gamma { + }; + + /** ++ * enum bcm2835_isp_cdn_mode - Mode of operation for colour denoise. ++ * ++ * @CDN_MODE_FAST: Fast (but lower quality) colour denoise ++ * algorithm, typically used for video recording. ++ * @CDN_HIGH_QUALITY: High quality (but slower) colour denoise ++ * algorithm, typically used for stills capture. ++ */ ++enum bcm2835_isp_cdn_mode { ++ CDN_MODE_FAST = 0, ++ CDN_MODE_HIGH_QUALITY = 1, ++}; ++ ++/** ++ * struct bcm2835_isp_cdn - Colour denoise parameters set with the ++ * V4L2_CID_USER_BCM2835_ISP_CDN ctrl. ++ * ++ * @enabled: Enable colour denoise. ++ * @mode: Colour denoise operating mode (see enum &bcm2835_isp_cdn_mode) ++ */ ++struct bcm2835_isp_cdn { ++ __u32 enabled; ++ __u32 mode; ++}; ++ ++/** + * struct bcm2835_isp_denoise - Denoise parameters set with the + * V4L2_CID_USER_BCM2835_ISP_DENOISE ctrl. + * diff --git a/target/linux/bcm27xx/patches-5.4/950-1043-staging-vc04_services-ISP-Add-colour-denoise-control.patch b/target/linux/bcm27xx/patches-5.4/950-1043-staging-vc04_services-ISP-Add-colour-denoise-control.patch new file mode 100644 index 0000000000..6df7a0c49c --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1043-staging-vc04_services-ISP-Add-colour-denoise-control.patch @@ -0,0 +1,75 @@ +From 29ec709794ac2aae569c8d486dd19a7d731cfeeb Mon Sep 17 00:00:00 2001 +From: Naushir Patuck <naush@raspberrypi.com> +Date: Thu, 14 Jan 2021 09:20:52 +0000 +Subject: [PATCH] staging: vc04_services: ISP: Add colour denoise + control + +Add colour denoise control to the bcm2835 driver through a new v4l2 +control: V4L2_CID_USER_BCM2835_ISP_CDN. + +Add the accompanying MMAL configuration structure definitions as well. + +Signed-off-by: Naushir Patuck <naush@raspberrypi.com> +--- + .../vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c | 5 +++++ + .../vc04_services/bcm2835-isp/bcm2835_isp_ctrls.h | 5 +++++ + .../vc04_services/vchiq-mmal/mmal-parameters.h | 13 +++++++++++++ + 3 files changed, 23 insertions(+) + +--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c ++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c +@@ -776,6 +776,11 @@ static int bcm2835_isp_s_ctrl(struct v4l + ctrl->p_new.p_u8, + sizeof(struct bcm2835_isp_denoise)); + break; ++ case V4L2_CID_USER_BCM2835_ISP_CDN: ++ ret = set_isp_param(node, MMAL_PARAMETER_CDN, ++ ctrl->p_new.p_u8, ++ sizeof(struct bcm2835_isp_cdn)); ++ break; + case V4L2_CID_USER_BCM2835_ISP_SHARPEN: + ret = set_isp_param(node, MMAL_PARAMETER_SHARPEN, + ctrl->p_new.p_u8, +--- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_ctrls.h ++++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835_isp_ctrls.h +@@ -57,6 +57,11 @@ static const struct bcm2835_isp_custom_c + .size = sizeof(struct bcm2835_isp_denoise), + .flags = 0 + }, { ++ .name = "Colour Denoise", ++ .id = V4L2_CID_USER_BCM2835_ISP_CDN, ++ .size = sizeof(struct bcm2835_isp_cdn), ++ .flags = 0 ++ }, { + .name = "Defective Pixel Correction", + .id = V4L2_CID_USER_BCM2835_ISP_DPC, + .size = sizeof(struct bcm2835_isp_dpc), +--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h ++++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h +@@ -277,6 +277,8 @@ enum mmal_parameter_camera_type { + MMAL_PARAMETER_DPC, + /**< Tales a @ref MMAP_PARAMETER_GAMMA_T */ + MMAL_PARAMETER_GAMMA, ++ /**< Takes a @ref MMAL_PARAMETER_CDN_T */ ++ MMAL_PARAMETER_CDN, + }; + + struct mmal_parameter_rational { +@@ -910,6 +912,17 @@ struct mmal_parameter_gamma { + u16 y[MMAL_NUM_GAMMA_PTS]; + }; + ++enum mmal_parameter_cdn_mode { ++ MMAL_PARAM_CDN_FAST = 0, ++ MMAL_PARAM_CDN_HIGH_QUALITY = 1, ++ MMAL_PARAM_CDN_DUMMY = 0x7FFFFFFF ++}; ++ ++struct mmal_parameter_colour_denoise { ++ u32 enabled; ++ enum mmal_parameter_cdn_mode mode; ++}; ++ + struct mmal_parameter_denoise { + u32 enabled; + u32 constant; diff --git a/target/linux/bcm27xx/patches-5.4/950-1044-kbuild-Silence-unavoidable-dtc-overlay-warnings.patch b/target/linux/bcm27xx/patches-5.4/950-1044-kbuild-Silence-unavoidable-dtc-overlay-warnings.patch new file mode 100644 index 0000000000..24292fe13b --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1044-kbuild-Silence-unavoidable-dtc-overlay-warnings.patch @@ -0,0 +1,31 @@ +From 6f36a21e2a77b33eed45159a1556a4dd77422976 Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Fri, 29 Jan 2021 10:34:11 +0000 +Subject: [PATCH] kbuild: Silence unavoidable dtc overlay warnings + +Much effort has been put into finding ways to avoid warnings from dtc +about overlays, usually to do with the presence of #address-cells and +size-cells, but not exclusively so. Since the issues being warned about +are harmless, suppress the warnings to declutter the build output and +to avoid alarming users. + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + scripts/Makefile.lib | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/scripts/Makefile.lib ++++ b/scripts/Makefile.lib +@@ -306,6 +306,12 @@ cmd_dtco = mkdir -p $(dir ${dtc-tmp}) ; + $(DTC) -@ -H epapr -O dtb -o $@ -b 0 \ + -i $(dir $<) $(DTC_FLAGS) \ + -Wno-interrupts_property \ ++ -Wno-label_is_string \ ++ -Wno-reg_format \ ++ -Wno-pci_device_bus_num \ ++ -Wno-i2c_bus_reg \ ++ -Wno-spi_bus_reg \ ++ -Wno-avoid_default_addr_size \ + -d $(depfile).dtc.tmp $(dtc-tmp) ; \ + cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) + diff --git a/target/linux/bcm27xx/patches-5.4/950-1045-Adds-the-DT-overlays-to-support-Hifiberry-AMP100.patch b/target/linux/bcm27xx/patches-5.4/950-1045-Adds-the-DT-overlays-to-support-Hifiberry-AMP100.patch new file mode 100644 index 0000000000..24ff1b3a34 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1045-Adds-the-DT-overlays-to-support-Hifiberry-AMP100.patch @@ -0,0 +1,132 @@ +From d689ccf52fb81664b7eccb91dc05a93d64ba793c Mon Sep 17 00:00:00 2001 +From: Joerg Schambacher <joerg@i2audio.com> +Date: Fri, 29 Jan 2021 08:26:44 +0100 +Subject: [PATCH] Adds the DT-overlays to support Hifiberry AMP100 + +Adds new DT-overlay to control AMP100. + +Signed-off-by: Joerg Schambacher <joerg@hifiberry.com> +--- + arch/arm/boot/dts/overlays/Makefile | 1 + + arch/arm/boot/dts/overlays/README | 30 ++++++++- + .../dts/overlays/hifiberry-amp100-overlay.dts | 64 +++++++++++++++++++ + 3 files changed, 94 insertions(+), 1 deletion(-) + create mode 100644 arch/arm/boot/dts/overlays/hifiberry-amp100-overlay.dts + +--- a/arch/arm/boot/dts/overlays/Makefile ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -60,6 +60,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ + hd44780-lcd.dtbo \ + hdmi-backlight-hwhack-gpio.dtbo \ + hifiberry-amp.dtbo \ ++ hifiberry-amp100.dtbo \ + hifiberry-dac.dtbo \ + hifiberry-dacplus.dtbo \ + hifiberry-dacplusadc.dtbo \ +--- a/arch/arm/boot/dts/overlays/README ++++ b/arch/arm/boot/dts/overlays/README +@@ -1045,8 +1045,36 @@ Load: dtoverlay=hifiberry-amp + Params: <None> + + ++Name: hifiberry-amp100 ++Info: Configures the HifiBerry AMP100 audio card ++Load: dtoverlay=hifiberry-amp100,<param>=<val> ++Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec ++ Digital volume control. Enable with ++ "dtoverlay=hifiberry-amp100,24db_digital_gain" ++ (The default behaviour is that the Digital ++ volume control is limited to a maximum of ++ 0dB. ie. it can attenuate but not provide ++ gain. For most users, this will be desired ++ as it will prevent clipping. By appending ++ the 24dB_digital_gain parameter, the Digital ++ volume control will allow up to 24dB of ++ gain. If this parameter is enabled, it is the ++ responsibility of the user to ensure that ++ the Digital volume control is set to a value ++ that does not result in clipping/distortion!) ++ slave Force DAC+ Pro into slave mode, using Pi as ++ master for bit clock and frame clock. ++ leds_off If set to 'true' the onboard indicator LEDs ++ are switched off at all times. ++ auto_mute If set to 'true' the amplifier is automatically ++ muted when the DAC is not playing. ++ mute_ext_ctl The amplifier's HW mute control is enabled ++ in ALSA mixer and set to <val>. ++ Will be overwritten by ALSA user settings. ++ ++ + Name: hifiberry-dac +-Info: Configures the HifiBerry DAC audio card ++Info: Configures the HifiBerry DAC audio cards + Load: dtoverlay=hifiberry-dac + Params: <None> + +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/hifiberry-amp100-overlay.dts +@@ -0,0 +1,64 @@ ++// Definitions for HiFiBerry AMP100 ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ dacpro_osc: dacpro_osc { ++ compatible = "hifiberry,dacpro-clk"; ++ #clock-cells = <0>; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pcm5122@4d { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm5122"; ++ reg = <0x4d>; ++ clocks = <&dacpro_osc>; ++ AVDD-supply = <&vdd_3v3_reg>; ++ DVDD-supply = <&vdd_3v3_reg>; ++ CPVDD-supply = <&vdd_3v3_reg>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&sound>; ++ hifiberry_dacplus: __overlay__ { ++ compatible = "hifiberry,hifiberry-dacplus"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ mute-gpio = <&gpio 4 0>; ++ reset-gpio = <&gpio 17 0x11>; ++ }; ++ }; ++ ++ __overrides__ { ++ 24db_digital_gain = ++ <&hifiberry_dacplus>,"hifiberry,24db_digital_gain?"; ++ slave = <&hifiberry_dacplus>,"hifiberry-dacplus,slave?"; ++ leds_off = <&hifiberry_dacplus>,"hifiberry-dacplus,leds_off?"; ++ mute_ext_ctl = <&hifiberry_dacplus>,"hifiberry-dacplus,mute_ext_ctl:0"; ++ auto_mute = <&hifiberry_dacplus>,"hifiberry-dacplus,auto_mute?"; ++ }; ++}; diff --git a/target/linux/bcm27xx/patches-5.4/950-1046-Enhances-the-Hifiberry-DAC-driver-for-Hifiberry-AMP1.patch b/target/linux/bcm27xx/patches-5.4/950-1046-Enhances-the-Hifiberry-DAC-driver-for-Hifiberry-AMP1.patch new file mode 100644 index 0000000000..4e15285220 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1046-Enhances-the-Hifiberry-DAC-driver-for-Hifiberry-AMP1.patch @@ -0,0 +1,238 @@ +From 0b584f3c2808dba8dc9e74a628b65008302804a5 Mon Sep 17 00:00:00 2001 +From: Joerg Schambacher <joerg@i2audio.com> +Date: Fri, 29 Jan 2021 16:16:39 +0100 +Subject: [PATCH] Enhances the Hifiberry DAC+ driver for Hifiberry + AMP100 support + +Adds the necessary GPIO handling and ALSA mixer extensions. +Also fixes a problem with the PLL/CLK control when switching sample rates. +Thanks to Clive Messer for the support! + +Signed-off-by: Joerg Schambacher <joerg@hifiberry.com> +--- + sound/soc/bcm/hifiberry_dacplus.c | 124 ++++++++++++++++++++++++++---- + 1 file changed, 111 insertions(+), 13 deletions(-) + +--- a/sound/soc/bcm/hifiberry_dacplus.c ++++ b/sound/soc/bcm/hifiberry_dacplus.c +@@ -1,10 +1,10 @@ + /* +- * ASoC Driver for HiFiBerry DAC+ / DAC Pro ++ * ASoC Driver for HiFiBerry DAC+ / DAC Pro / AMP100 + * + * Author: Daniel Matuschek, Stuart MacLean <stuart@hifiberry.com> + * Copyright 2014-2015 + * based on code by Florian Meier <florian.meier@koalo.de> +- * Headphone added by Joerg Schambacher, joerg@i2audio.com ++ * Headphone/AMP100 Joerg Schambacher <joerg@hifiberry.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License +@@ -17,6 +17,8 @@ + */ + + #include <linux/module.h> ++#include <linux/gpio/consumer.h> ++#include <../drivers/gpio/gpiolib.h> + #include <linux/platform_device.h> + #include <linux/kernel.h> + #include <linux/clk.h> +@@ -53,6 +55,47 @@ static bool slave; + static bool snd_rpi_hifiberry_is_dacpro; + static bool digital_gain_0db_limit = true; + static bool leds_off; ++static bool auto_mute; ++static int mute_ext_ctl; ++static int mute_ext; ++static struct gpio_desc *snd_mute_gpio; ++static struct gpio_desc *snd_reset_gpio; ++static struct snd_soc_card snd_rpi_hifiberry_dacplus; ++ ++static int snd_rpi_hifiberry_dacplus_mute_set(int mute) ++{ ++ gpiod_set_value_cansleep(snd_mute_gpio, mute); ++ return 1; ++} ++ ++static int snd_rpi_hifiberry_dacplus_mute_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ ucontrol->value.integer.value[0] = mute_ext; ++ ++ return 0; ++} ++ ++static int snd_rpi_hifiberry_dacplus_mute_put(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ if (mute_ext == ucontrol->value.integer.value[0]) ++ return 0; ++ ++ mute_ext = ucontrol->value.integer.value[0]; ++ ++ return snd_rpi_hifiberry_dacplus_mute_set(mute_ext); ++} ++ ++static const char * const mute_text[] = {"Play", "Mute"}; ++static const struct soc_enum hb_dacplus_opt_mute_enum = ++ SOC_ENUM_SINGLE_EXT(2, mute_text); ++ ++static const struct snd_kcontrol_new hb_dacplus_opt_mute_controls[] = { ++ SOC_ENUM_EXT("Mute(ext)", hb_dacplus_opt_mute_enum, ++ snd_rpi_hifiberry_dacplus_mute_get, ++ snd_rpi_hifiberry_dacplus_mute_put), ++}; + + static void snd_rpi_hifiberry_dacplus_select_clk(struct snd_soc_component *component, + int clk_id) +@@ -68,6 +111,7 @@ static void snd_rpi_hifiberry_dacplus_se + snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x24, 0x04); + break; + } ++ usleep_range(2000, 2100); + } + + static void snd_rpi_hifiberry_dacplus_clk_gpio(struct snd_soc_component *component) +@@ -85,13 +129,6 @@ static bool snd_rpi_hifiberry_dacplus_is + return (!(sck & 0x40)); + } + +-static bool snd_rpi_hifiberry_dacplus_is_sclk_sleep( +- struct snd_soc_component *component) +-{ +- msleep(2); +- return snd_rpi_hifiberry_dacplus_is_sclk(component); +-} +- + static bool snd_rpi_hifiberry_dacplus_is_pro_card(struct snd_soc_component *component) + { + bool isClk44EN, isClk48En, isNoClk; +@@ -99,13 +136,13 @@ static bool snd_rpi_hifiberry_dacplus_is + snd_rpi_hifiberry_dacplus_clk_gpio(component); + + snd_rpi_hifiberry_dacplus_select_clk(component, HIFIBERRY_DACPRO_CLK44EN); +- isClk44EN = snd_rpi_hifiberry_dacplus_is_sclk_sleep(component); ++ isClk44EN = snd_rpi_hifiberry_dacplus_is_sclk(component); + + snd_rpi_hifiberry_dacplus_select_clk(component, HIFIBERRY_DACPRO_NOCLOCK); +- isNoClk = snd_rpi_hifiberry_dacplus_is_sclk_sleep(component); ++ isNoClk = snd_rpi_hifiberry_dacplus_is_sclk(component); + + snd_rpi_hifiberry_dacplus_select_clk(component, HIFIBERRY_DACPRO_CLK48EN); +- isClk48En = snd_rpi_hifiberry_dacplus_is_sclk_sleep(component); ++ isClk48En = snd_rpi_hifiberry_dacplus_is_sclk(component); + + return (isClk44EN && isClk48En && !isNoClk); + } +@@ -149,6 +186,7 @@ static int snd_rpi_hifiberry_dacplus_ini + { + struct snd_soc_component *component = rtd->codec_dai->component; + struct pcm512x_priv *priv; ++ struct snd_soc_card *card = &snd_rpi_hifiberry_dacplus; + + if (slave) + snd_rpi_hifiberry_is_dacpro = false; +@@ -187,6 +225,20 @@ static int snd_rpi_hifiberry_dacplus_ini + if (ret < 0) + dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); + } ++ if (snd_reset_gpio) { ++ gpiod_set_value_cansleep(snd_reset_gpio, 0); ++ msleep(1); ++ gpiod_set_value_cansleep(snd_reset_gpio, 1); ++ msleep(1); ++ gpiod_set_value_cansleep(snd_reset_gpio, 0); ++ } ++ ++ if (mute_ext_ctl) ++ snd_soc_add_card_controls(card, hb_dacplus_opt_mute_controls, ++ ARRAY_SIZE(hb_dacplus_opt_mute_controls)); ++ ++ if (snd_mute_gpio) ++ gpiod_set_value_cansleep(snd_mute_gpio, mute_ext); + + return 0; + } +@@ -254,6 +306,8 @@ static int snd_rpi_hifiberry_dacplus_sta + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_component *component = rtd->codec_dai->component; + ++ if (auto_mute) ++ gpiod_set_value_cansleep(snd_mute_gpio, 0); + if (leds_off) + return 0; + snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); +@@ -267,6 +321,8 @@ static void snd_rpi_hifiberry_dacplus_sh + struct snd_soc_component *component = rtd->codec_dai->component; + + snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x08, 0x00); ++ if (auto_mute) ++ gpiod_set_value_cansleep(snd_mute_gpio, 1); + } + + /* machine stream operations */ +@@ -342,6 +398,8 @@ static int snd_rpi_hifiberry_dacplus_pro + struct device_node *tpa_node; + struct property *tpa_prop; + struct of_changeset ocs; ++ struct property *pp; ++ int tmp; + + /* probe for head phone amp */ + ret = hb_hp_detect(); +@@ -396,6 +454,39 @@ static int snd_rpi_hifiberry_dacplus_pro + "hifiberry-dacplus,slave"); + leds_off = of_property_read_bool(pdev->dev.of_node, + "hifiberry-dacplus,leds_off"); ++ auto_mute = of_property_read_bool(pdev->dev.of_node, ++ "hifiberry-dacplus,auto_mute"); ++ ++ /* ++ * check for HW MUTE as defined in DT-overlay ++ * active high, therefore default to HIGH to MUTE ++ */ ++ snd_mute_gpio = devm_gpiod_get_optional(&pdev->dev, ++ "mute", GPIOD_OUT_HIGH); ++ if (IS_ERR(snd_mute_gpio)) { ++ dev_err(&pdev->dev, "Can't allocate GPIO (HW-MUTE)"); ++ return PTR_ERR(snd_mute_gpio); ++ } ++ ++ /* add ALSA control if requested in DT-overlay (AMP100) */ ++ pp = of_find_property(pdev->dev.of_node, ++ "hifiberry-dacplus,mute_ext_ctl", &tmp); ++ if (pp) { ++ if (!of_property_read_u32(pdev->dev.of_node, ++ "hifiberry-dacplus,mute_ext_ctl", &mute_ext)) { ++ /* ALSA control will be used */ ++ mute_ext_ctl = 1; ++ } ++ } ++ ++ /* check for HW RESET (AMP100) */ ++ snd_reset_gpio = devm_gpiod_get_optional(&pdev->dev, ++ "reset", GPIOD_OUT_HIGH); ++ if (IS_ERR(snd_reset_gpio)) { ++ dev_err(&pdev->dev, "Can't allocate GPIO (HW-RESET)"); ++ return PTR_ERR(snd_reset_gpio); ++ } ++ + } + + ret = devm_snd_soc_register_card(&pdev->dev, +@@ -403,7 +494,14 @@ static int snd_rpi_hifiberry_dacplus_pro + if (ret && ret != -EPROBE_DEFER) + dev_err(&pdev->dev, + "snd_soc_register_card() failed: %d\n", ret); +- ++ if (!ret) { ++ if (snd_mute_gpio) ++ dev_info(&pdev->dev, "GPIO%i for HW-MUTE selected", ++ gpio_chip_hwgpio(snd_mute_gpio)); ++ if (snd_reset_gpio) ++ dev_info(&pdev->dev, "GPIO%i for HW-RESET selected", ++ gpio_chip_hwgpio(snd_reset_gpio)); ++ } + return ret; + } + diff --git a/target/linux/bcm27xx/patches-5.4/950-1047-ARM-dts-Declare-Pi400-and-CM4-have-no-audio-pins.patch b/target/linux/bcm27xx/patches-5.4/950-1047-ARM-dts-Declare-Pi400-and-CM4-have-no-audio-pins.patch new file mode 100644 index 0000000000..c7d7c66d44 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1047-ARM-dts-Declare-Pi400-and-CM4-have-no-audio-pins.patch @@ -0,0 +1,41 @@ +From 747df57eabbe2e3b5bd47e268aa42658a57749ca Mon Sep 17 00:00:00 2001 +From: Phil Elwell <phil@raspberrypi.com> +Date: Wed, 3 Feb 2021 16:23:43 +0000 +Subject: [PATCH] ARM: dts: Declare Pi400 and CM4 have no audio pins + +The audio_pins node is left as a placeholder for the audremap overlay, +and it must have (empty) brcm,function and brcm,pins properties +otherwise it will be rejected by the pinctrl driver. + +See: https://www.raspberrypi.org/forums/viewtopic.php?f=98&t=301891 + +Signed-off-by: Phil Elwell <phil@raspberrypi.com> +--- + arch/arm/boot/dts/bcm2711-rpi-400.dts | 4 ++-- + arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 2 ++ + 2 files changed, 4 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/bcm2711-rpi-400.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-400.dts +@@ -495,8 +495,8 @@ + + &gpio { + audio_pins: audio_pins { +- brcm,pins = <40 41>; +- brcm,function = <4>; ++ brcm,pins = <>; ++ brcm,function = <>; + }; + }; + +--- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts ++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts +@@ -434,6 +434,8 @@ + + &gpio { + audio_pins: audio_pins { ++ brcm,pins = <>; ++ brcm,function = <>; + }; + }; + diff --git a/target/linux/bcm27xx/patches-5.4/950-1048-Hifiberry-DAC-ADC-Pro-fix-for-the-PLL-when-changing-.patch b/target/linux/bcm27xx/patches-5.4/950-1048-Hifiberry-DAC-ADC-Pro-fix-for-the-PLL-when-changing-.patch new file mode 100644 index 0000000000..47ecb8b2ce --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-1048-Hifiberry-DAC-ADC-Pro-fix-for-the-PLL-when-changing-.patch @@ -0,0 +1,56 @@ +From c70ae3d1923339746d156bd1d723d141113183aa Mon Sep 17 00:00:00 2001 +From: Joerg Schambacher <joerg@i2audio.com> +Date: Mon, 1 Feb 2021 16:53:46 +0100 +Subject: [PATCH] Hifiberry DAC+ADC Pro fix for the PLL when changing + sample rates + +Adds 2 msecs delay when switching between oscillators to allow +correct PLL settling. +Thanks to Clive Messer for the support! + +Signed-off-by: Joerg Schambacher <joerg@hifiberry.com> +--- + sound/soc/bcm/hifiberry_dacplusadcpro.c | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +--- a/sound/soc/bcm/hifiberry_dacplusadcpro.c ++++ b/sound/soc/bcm/hifiberry_dacplusadcpro.c +@@ -190,6 +190,7 @@ static void snd_rpi_hifiberry_dacplusadc + PCM512x_GPIO_CONTROL_1, 0x24, 0x04); + break; + } ++ usleep_range(2000, 2100); + } + + static void snd_rpi_hifiberry_dacplusadcpro_clk_gpio(struct snd_soc_component *component) +@@ -207,13 +208,6 @@ static bool snd_rpi_hifiberry_dacplusadc + return (!(sck & 0x40)); + } + +-static bool snd_rpi_hifiberry_dacplusadcpro_is_sclk_sleep( +- struct snd_soc_component *component) +-{ +- msleep(2); +- return snd_rpi_hifiberry_dacplusadcpro_is_sclk(component); +-} +- + static bool snd_rpi_hifiberry_dacplusadcpro_is_pro_card(struct snd_soc_component *component) + { + bool isClk44EN, isClk48En, isNoClk; +@@ -221,13 +215,13 @@ static bool snd_rpi_hifiberry_dacplusadc + snd_rpi_hifiberry_dacplusadcpro_clk_gpio(component); + + snd_rpi_hifiberry_dacplusadcpro_select_clk(component, HIFIBERRY_DACPRO_CLK44EN); +- isClk44EN = snd_rpi_hifiberry_dacplusadcpro_is_sclk_sleep(component); ++ isClk44EN = snd_rpi_hifiberry_dacplusadcpro_is_sclk(component); + + snd_rpi_hifiberry_dacplusadcpro_select_clk(component, HIFIBERRY_DACPRO_NOCLOCK); +- isNoClk = snd_rpi_hifiberry_dacplusadcpro_is_sclk_sleep(component); ++ isNoClk = snd_rpi_hifiberry_dacplusadcpro_is_sclk(component); + + snd_rpi_hifiberry_dacplusadcpro_select_clk(component, HIFIBERRY_DACPRO_CLK48EN); +- isClk48En = snd_rpi_hifiberry_dacplusadcpro_is_sclk_sleep(component); ++ isClk48En = snd_rpi_hifiberry_dacplusadcpro_is_sclk(component); + + return (isClk44EN && isClk48En && !isNoClk); + } |