Browse Source

Raspberry Pi VideoCore: Wait for framebuffer address if not available

Sometimes the VideoCore does not immediately provide the framebuffer
address, even after it has returned success via a mailbox read.
Aaron Lindsay 7 years ago
parent
commit
828beb45bd
1 changed files with 27 additions and 11 deletions
  1. 27 11
      drivers/bcm2835_videocore.c

+ 27 - 11
drivers/bcm2835_videocore.c

@@ -25,16 +25,16 @@
25 25
 #include <drivers/bcm2835_mailbox.h>
26 26
 
27 27
 struct bcm2835_config {
28
-	uint32 width;
29
-	uint32 height;
30
-	uint32 vwidth;
31
-	uint32 vheight;
32
-	uint32 pitch;
33
-	uint32 color_depth;
34
-	uint32 xoffset;
35
-	uint32 yoffset;
36
-	uint32 fb_base_addr;
37
-	uint32 size;
28
+	volatile uint32 width;
29
+	volatile uint32 height;
30
+	volatile uint32 vwidth;
31
+	volatile uint32 vheight;
32
+	volatile uint32 pitch;
33
+	volatile uint32 color_depth;
34
+	volatile uint32 xoffset;
35
+	volatile uint32 yoffset;
36
+	volatile uint32 fb_base_addr;
37
+	volatile uint32 size;
38 38
 };
39 39
 
40 40
 #define MAILBOX_BUFFER_SIZE (32*4*2)
@@ -75,11 +75,27 @@ int bcm2835_videocore_init(struct fb *f, unsigned int color_depth) {
75 75
 	mailbox_write(MBOX_FB, (uint32)cfg);
76 76
 	result = mailbox_read(MBOX_FB);
77 77
 
78
-	if (result || !cfg->fb_base_addr) {
78
+	if (result) {
79 79
 		print("Error: did not request a proper framebuffer\n");
80 80
 		return -1;
81 81
 	}
82 82
 
83
+	if (!cfg->fb_base_addr) {
84
+		int i;
85
+		print("BCM2835 VideoCore returned success from framebuffer "
86
+				"setup mailbox call, but framebuffer address is "
87
+				"not yet available. Waiting...\n");
88
+		for (i = 0; i < 1<<30 && !cfg->fb_base_addr; i++);
89
+
90
+		if (!cfg->fb_base_addr) {
91
+
92
+			print("Error: VideoCore did not provide framebuffer "
93
+					"base address.\n");
94
+			return -1;
95
+		}
96
+		print("VideoCore provided framebuffer base address after %d loops.\n", i);
97
+	}
98
+
83 99
 	f->device = &bcm2835_fb_device;
84 100
 	f->device->fbaddr = (void*)cfg->fb_base_addr;
85 101
 	f->width = cfg->width;