aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.10/950-0497-media-bcm2835-unicam-Fix-bug-in-buffer-swapping-logi.patch
diff options
context:
space:
mode:
authorÁlvaro Fernández Rojas <noltari@gmail.com>2021-08-21 10:54:34 +0200
committerÁlvaro Fernández Rojas <noltari@gmail.com>2021-08-21 19:07:07 +0200
commit8299d1f057439f94c6a4412e2e5c5082b82a30c9 (patch)
tree1bf678d61f11f7394493be464c7876e496f7faed /target/linux/bcm27xx/patches-5.10/950-0497-media-bcm2835-unicam-Fix-bug-in-buffer-swapping-logi.patch
parent33b6885975ce376ff075362b7f0890326043111b (diff)
downloadupstream-8299d1f057439f94c6a4412e2e5c5082b82a30c9.tar.gz
upstream-8299d1f057439f94c6a4412e2e5c5082b82a30c9.tar.bz2
upstream-8299d1f057439f94c6a4412e2e5c5082b82a30c9.zip
bcm27xx: add kernel 5.10 support
Rebased RPi foundation patches on linux 5.10.59, removed applied and reverted patches, wireless patches and defconfig patches. bcm2708: boot tested on RPi B+ v1.2 bcm2709: boot tested on RPi 4B v1.1 4G bcm2711: boot tested on RPi 4B v1.1 4G Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Diffstat (limited to 'target/linux/bcm27xx/patches-5.10/950-0497-media-bcm2835-unicam-Fix-bug-in-buffer-swapping-logi.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.10/950-0497-media-bcm2835-unicam-Fix-bug-in-buffer-swapping-logi.patch75
1 files changed, 75 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.10/950-0497-media-bcm2835-unicam-Fix-bug-in-buffer-swapping-logi.patch b/target/linux/bcm27xx/patches-5.10/950-0497-media-bcm2835-unicam-Fix-bug-in-buffer-swapping-logi.patch
new file mode 100644
index 0000000000..f8c37f2784
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.10/950-0497-media-bcm2835-unicam-Fix-bug-in-buffer-swapping-logi.patch
@@ -0,0 +1,75 @@
+From 8740c5d8ab750b3e12f7f081082e2ae8c22ab6db Mon Sep 17 00:00:00 2001
+From: Naushir Patuck <naush@raspberrypi.com>
+Date: Fri, 5 Mar 2021 15:40:45 +0000
+Subject: [PATCH] media: bcm2835-unicam: Fix bug in buffer swapping
+ logic
+
+If multiple sets of interrupts occur simultaneously, it may be unsafe
+to swap buffers, as the hardware may already be re-using the current
+buffers. In such cases, avoid swapping buffers, and wait for the next
+opportunity at the Frame End interrupt to signal completion.
+
+Additionally, check the packet compare status when watching for frame
+end for buffers swaps, as this could also signify a frame end event.
+
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ .../media/platform/bcm2835/bcm2835-unicam.c | 21 ++++++++++++++++---
+ 1 file changed, 18 insertions(+), 3 deletions(-)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
++++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
+@@ -798,6 +798,7 @@ static irqreturn_t unicam_isr(int irq, v
+ unsigned int sequence = unicam->sequence;
+ unsigned int i;
+ u32 ista, sta;
++ bool fe;
+ u64 ts;
+
+ sta = reg_read(unicam, UNICAM_STA);
+@@ -815,12 +816,18 @@ static irqreturn_t unicam_isr(int irq, v
+ return IRQ_HANDLED;
+
+ /*
++ * Look for either the Frame End interrupt or the Packet Capture status
++ * to signal a frame end.
++ */
++ fe = (ista & UNICAM_FEI || sta & UNICAM_PI0);
++
++ /*
+ * 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) {
++ if (fe) {
+ /*
+ * Ensure we have swapped buffers already as we can't
+ * stop the peripheral. If no buffer is available, use a
+@@ -831,7 +838,15 @@ static irqreturn_t unicam_isr(int irq, v
+ if (!unicam->node[i].streaming)
+ continue;
+
+- if (unicam->node[i].cur_frm)
++ /*
++ * If cur_frm == next_frm, it means we have not had
++ * a chance to swap buffers, likely due to having
++ * multiple interrupts occurring simultaneously (like FE
++ * + FS + LS). In this case, we cannot signal the buffer
++ * as complete, as the HW will reuse that buffer.
++ */
++ if (unicam->node[i].cur_frm &&
++ unicam->node[i].cur_frm != unicam->node[i].next_frm)
+ unicam_process_buffer_complete(&unicam->node[i],
+ sequence);
+ unicam->node[i].cur_frm = unicam->node[i].next_frm;
+@@ -868,7 +883,7 @@ static irqreturn_t unicam_isr(int irq, v
+ * where the HW does not actually swap it if the new frame has
+ * already started.
+ */
+- if (ista & (UNICAM_FSI | UNICAM_LCI) && !(ista & UNICAM_FEI)) {
++ if (ista & (UNICAM_FSI | UNICAM_LCI) && !fe) {
+ for (i = 0; i < ARRAY_SIZE(unicam->node); i++) {
+ if (!unicam->node[i].streaming)
+ continue;