1391e111c372cdf412fc23703c4280c901b36b8b
[oweals/openwrt.git] /
1 From 6085298cadb925cb62bf863326d083f2fc7fc224 Mon Sep 17 00:00:00 2001
2 From: James Hughes <james.hughes@raspberrypi.org>
3 Date: Thu, 14 Mar 2019 13:27:54 +0000
4 Subject: [PATCH 630/782] Pulled in the multi frame buffer support from the Pi3
5  repo
6
7 ---
8  drivers/video/fbdev/bcm2708_fb.c           | 580 +++++++++++++++------
9  include/soc/bcm2835/raspberrypi-firmware.h |   4 +
10  2 files changed, 432 insertions(+), 152 deletions(-)
11
12 --- a/drivers/video/fbdev/bcm2708_fb.c
13 +++ b/drivers/video/fbdev/bcm2708_fb.c
14 @@ -2,6 +2,7 @@
15   *  linux/drivers/video/bcm2708_fb.c
16   *
17   * Copyright (C) 2010 Broadcom
18 + * Copyright (C) 2018 Raspberry Pi (Trading) Ltd
19   *
20   * This file is subject to the terms and conditions of the GNU General Public
21   * License.  See the file COPYING in the main directory of this archive
22 @@ -13,6 +14,7 @@
23   * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com>
24   *
25   */
26 +
27  #include <linux/module.h>
28  #include <linux/kernel.h>
29  #include <linux/errno.h>
30 @@ -36,6 +38,7 @@
31  #include <linux/dma-mapping.h>
32  #include <linux/cred.h>
33  #include <soc/bcm2835/raspberrypi-firmware.h>
34 +#include <linux/mutex.h>
35  
36  //#define BCM2708_FB_DEBUG
37  #define MODULE_NAME "bcm2708_fb"
38 @@ -82,62 +85,139 @@ struct bcm2708_fb_stats {
39         u32 dma_irqs;
40  };
41  
42 +struct vc4_display_settings_t {
43 +       u32 display_num;
44 +       u32 width;
45 +       u32 height;
46 +       u32 pitch;
47 +       u32 depth;
48 +       u32 virtual_width;
49 +       u32 virtual_height;
50 +       u32 virtual_width_offset;
51 +       u32 virtual_height_offset;
52 +       unsigned long fb_bus_address;
53 +};
54 +
55 +struct bcm2708_fb_dev;
56 +
57  struct bcm2708_fb {
58         struct fb_info fb;
59         struct platform_device *dev;
60 -       struct rpi_firmware *fw;
61         u32 cmap[16];
62         u32 gpu_cmap[256];
63 +       struct dentry *debugfs_dir;
64 +       struct dentry *debugfs_subdir;
65 +       unsigned long fb_bus_address;
66 +       struct { u32 base, length; } gpu;
67 +       struct vc4_display_settings_t display_settings;
68 +       struct debugfs_regset32 screeninfo_regset;
69 +       struct bcm2708_fb_dev *fbdev;
70 +       unsigned int image_size;
71 +       dma_addr_t dma_addr;
72 +       void *cpuaddr;
73 +};
74 +
75 +#define MAX_FRAMEBUFFERS 3
76 +
77 +struct bcm2708_fb_dev {
78 +       int firmware_supports_multifb;
79 +       /* Protects the DMA system from multiple FB access */
80 +       struct mutex dma_mutex;
81         int dma_chan;
82         int dma_irq;
83         void __iomem *dma_chan_base;
84 -       void *cb_base;          /* DMA control blocks */
85 -       dma_addr_t cb_handle;
86 -       struct dentry *debugfs_dir;
87         wait_queue_head_t dma_waitq;
88 -       struct bcm2708_fb_stats stats;
89 -       unsigned long fb_bus_address;
90 -       struct { u32 base, length; } gpu;
91 +       bool disable_arm_alloc;
92 +       struct bcm2708_fb_stats dma_stats;
93 +       void *cb_base;  /* DMA control blocks */
94 +       dma_addr_t cb_handle;
95 +       int instance_count;
96 +       int num_displays;
97 +       struct rpi_firmware *fw;
98 +       struct bcm2708_fb displays[MAX_FRAMEBUFFERS];
99  };
100  
101  #define to_bcm2708(info)       container_of(info, struct bcm2708_fb, fb)
102  
103  static void bcm2708_fb_debugfs_deinit(struct bcm2708_fb *fb)
104  {
105 -       debugfs_remove_recursive(fb->debugfs_dir);
106 -       fb->debugfs_dir = NULL;
107 +       debugfs_remove_recursive(fb->debugfs_subdir);
108 +       fb->debugfs_subdir = NULL;
109 +
110 +       fb->fbdev->instance_count--;
111 +
112 +       if (!fb->fbdev->instance_count) {
113 +               debugfs_remove_recursive(fb->debugfs_dir);
114 +               fb->debugfs_dir = NULL;
115 +       }
116  }
117  
118  static int bcm2708_fb_debugfs_init(struct bcm2708_fb *fb)
119  {
120 +       char buf[3];
121 +       struct bcm2708_fb_dev *fbdev = fb->fbdev;
122 +
123         static struct debugfs_reg32 stats_registers[] = {
124 -               {
125 -                       "dma_copies",
126 -                       offsetof(struct bcm2708_fb_stats, dma_copies)
127 -               },
128 -               {
129 -                       "dma_irqs",
130 -                       offsetof(struct bcm2708_fb_stats, dma_irqs)
131 -               },
132 +       {"dma_copies", offsetof(struct bcm2708_fb_stats, dma_copies)},
133 +       {"dma_irqs",   offsetof(struct bcm2708_fb_stats, dma_irqs)},
134         };
135  
136 -       fb->debugfs_dir = debugfs_create_dir(DRIVER_NAME, NULL);
137 +       static struct debugfs_reg32 screeninfo[] = {
138 +       {"width",        offsetof(struct fb_var_screeninfo, xres)},
139 +       {"height",       offsetof(struct fb_var_screeninfo, yres)},
140 +       {"bpp",          offsetof(struct fb_var_screeninfo, bits_per_pixel)},
141 +       {"xres_virtual", offsetof(struct fb_var_screeninfo, xres_virtual)},
142 +       {"yres_virtual", offsetof(struct fb_var_screeninfo, yres_virtual)},
143 +       {"xoffset",      offsetof(struct fb_var_screeninfo, xoffset)},
144 +       {"yoffset",      offsetof(struct fb_var_screeninfo, yoffset)},
145 +       };
146 +
147 +       fb->debugfs_dir = debugfs_lookup(DRIVER_NAME, NULL);
148 +
149 +       if (!fb->debugfs_dir)
150 +               fb->debugfs_dir = debugfs_create_dir(DRIVER_NAME, NULL);
151 +
152         if (!fb->debugfs_dir) {
153 -               pr_warn("%s: could not create debugfs entry\n",
154 -                       __func__);
155 +               dev_warn(fb->fb.dev, "%s: could not create debugfs folder\n",
156 +                        __func__);
157 +               return -EFAULT;
158 +       }
159 +
160 +       snprintf(buf, sizeof(buf), "%u", fb->display_settings.display_num);
161 +
162 +       fb->debugfs_subdir = debugfs_create_dir(buf, fb->debugfs_dir);
163 +
164 +       if (!fb->debugfs_subdir) {
165 +               dev_warn(fb->fb.dev, "%s: could not create debugfs entry %u\n",
166 +                        __func__, fb->display_settings.display_num);
167                 return -EFAULT;
168         }
169  
170 -       fb->stats.regset.regs = stats_registers;
171 -       fb->stats.regset.nregs = ARRAY_SIZE(stats_registers);
172 -       fb->stats.regset.base = &fb->stats;
173 -
174 -       if (!debugfs_create_regset32("stats", 0444, fb->debugfs_dir,
175 -                                    &fb->stats.regset)) {
176 -               pr_warn("%s: could not create statistics registers\n",
177 -                       __func__);
178 +       fbdev->dma_stats.regset.regs = stats_registers;
179 +       fbdev->dma_stats.regset.nregs = ARRAY_SIZE(stats_registers);
180 +       fbdev->dma_stats.regset.base = &fbdev->dma_stats;
181 +
182 +       if (!debugfs_create_regset32("dma_stats", 0444, fb->debugfs_subdir,
183 +                                    &fbdev->dma_stats.regset)) {
184 +               dev_warn(fb->fb.dev, "%s: could not create statistics registers\n",
185 +                        __func__);
186 +               goto fail;
187 +       }
188 +
189 +       fb->screeninfo_regset.regs = screeninfo;
190 +       fb->screeninfo_regset.nregs = ARRAY_SIZE(screeninfo);
191 +       fb->screeninfo_regset.base = &fb->fb.var;
192 +
193 +       if (!debugfs_create_regset32("screeninfo", 0444, fb->debugfs_subdir,
194 +                                    &fb->screeninfo_regset)) {
195 +               dev_warn(fb->fb.dev,
196 +                        "%s: could not create dimensions registers\n",
197 +                        __func__);
198                 goto fail;
199         }
200 +
201 +       fbdev->instance_count++;
202 +
203         return 0;
204  
205  fail:
206 @@ -145,6 +225,20 @@ fail:
207         return -EFAULT;
208  }
209  
210 +static void set_display_num(struct bcm2708_fb *fb)
211 +{
212 +       if (fb && fb->fbdev && fb->fbdev->firmware_supports_multifb) {
213 +               u32 tmp = fb->display_settings.display_num;
214 +
215 +               if (rpi_firmware_property(fb->fbdev->fw,
216 +                                         RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM,
217 +                                         &tmp,
218 +                                         sizeof(tmp)))
219 +                       dev_warn_once(fb->fb.dev,
220 +                                     "Set display number call failed. Old GPU firmware?");
221 +       }
222 +}
223 +
224  static int bcm2708_fb_set_bitfields(struct fb_var_screeninfo *var)
225  {
226         int ret = 0;
227 @@ -222,11 +316,11 @@ static int bcm2708_fb_check_var(struct f
228                                 struct fb_info *info)
229  {
230         /* info input, var output */
231 -       print_debug("%s(%p) %dx%d (%dx%d), %d, %d\n",
232 +       print_debug("%s(%p) %ux%u (%ux%u), %ul, %u\n",
233                     __func__, info, info->var.xres, info->var.yres,
234                     info->var.xres_virtual, info->var.yres_virtual,
235 -                   (int)info->screen_size, info->var.bits_per_pixel);
236 -       print_debug("%s(%p) %dx%d (%dx%d), %d\n", __func__, var, var->xres,
237 +                   info->screen_size, info->var.bits_per_pixel);
238 +       print_debug("%s(%p) %ux%u (%ux%u), %u\n", __func__, var, var->xres,
239                     var->yres, var->xres_virtual, var->yres_virtual,
240                     var->bits_per_pixel);
241  
242 @@ -283,23 +377,96 @@ static int bcm2708_fb_set_par(struct fb_
243                         .xoffset = info->var.xoffset,
244                         .yoffset = info->var.yoffset,
245                 .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 },
246 -                       .base = 0,
247 -                       .screen_size = 0,
248 -               .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH, 4, 0 },
249 -                       .pitch = 0,
250 +                       /* base and screen_size will be initialised later */
251 +               .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH, 4, 0 },
252 +                       /* pitch will be initialised later */
253         };
254 -       int ret;
255 +       int ret, image_size;
256 +
257  
258 -       print_debug("%s(%p) %dx%d (%dx%d), %d, %d\n", __func__, info,
259 +       print_debug("%s(%p) %dx%d (%dx%d), %d, %d (display %d)\n", __func__,
260 +                   info,
261                     info->var.xres, info->var.yres, info->var.xres_virtual,
262                     info->var.yres_virtual, (int)info->screen_size,
263 -                   info->var.bits_per_pixel);
264 +                   info->var.bits_per_pixel, value);
265 +
266 +       /* Need to set the display number to act on first
267 +        * Cannot do it in the tag list because on older firmware the call
268 +        * will fail and stop the rest of the list being executed.
269 +        * We can ignore this call failing as the default at other end is 0
270 +        */
271 +       set_display_num(fb);
272 +
273 +       /* Try allocating our own buffer. We can specify all the parameters */
274 +       image_size = ((info->var.xres * info->var.yres) *
275 +                     info->var.bits_per_pixel) >> 3;
276 +
277 +       if (!fb->fbdev->disable_arm_alloc &&
278 +           (image_size != fb->image_size || !fb->dma_addr)) {
279 +               if (fb->dma_addr) {
280 +                       dma_free_coherent(info->device, fb->image_size,
281 +                                         fb->cpuaddr, fb->dma_addr);
282 +                       fb->image_size = 0;
283 +                       fb->cpuaddr = NULL;
284 +                       fb->dma_addr = 0;
285 +               }
286 +
287 +               fb->cpuaddr = dma_alloc_coherent(info->device, image_size,
288 +                                                &fb->dma_addr, GFP_KERNEL);
289 +
290 +               if (!fb->cpuaddr) {
291 +                       fb->dma_addr = 0;
292 +                       fb->fbdev->disable_arm_alloc = true;
293 +               } else {
294 +                       fb->image_size = image_size;
295 +               }
296 +       }
297 +
298 +       if (fb->cpuaddr) {
299 +               fbinfo.base = fb->dma_addr;
300 +               fbinfo.screen_size = image_size;
301 +               fbinfo.pitch = (info->var.xres * info->var.bits_per_pixel) >> 3;
302 +
303 +               ret = rpi_firmware_property_list(fb->fbdev->fw, &fbinfo,
304 +                                                sizeof(fbinfo));
305 +               if (ret || fbinfo.base != fb->dma_addr) {
306 +                       /* Firmware either failed, or assigned a different base
307 +                        * address (ie it doesn't support being passed an FB
308 +                        * allocation).
309 +                        * Destroy the allocation, and don't try again.
310 +                        */
311 +                       dma_free_coherent(info->device, fb->image_size,
312 +                                         fb->cpuaddr, fb->dma_addr);
313 +                       fb->image_size = 0;
314 +                       fb->cpuaddr = NULL;
315 +                       fb->dma_addr = 0;
316 +                       fb->fbdev->disable_arm_alloc = true;
317 +               }
318 +       } else {
319 +               /* Our allocation failed - drop into the old scheme of
320 +                * allocation by the VPU.
321 +                */
322 +               ret = -ENOMEM;
323 +       }
324  
325 -       ret = rpi_firmware_property_list(fb->fw, &fbinfo, sizeof(fbinfo));
326         if (ret) {
327 -               dev_err(info->device,
328 -                       "Failed to allocate GPU framebuffer (%d)\n", ret);
329 -               return ret;
330 +               /* Old scheme:
331 +                * - FRAMEBUFFER_ALLOCATE passes 0 for base and screen_size.
332 +                * - GET_PITCH instead of SET_PITCH.
333 +                */
334 +               fbinfo.base = 0;
335 +               fbinfo.screen_size = 0;
336 +               fbinfo.tag6.tag = RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH;
337 +               fbinfo.pitch = 0;
338 +
339 +               ret = rpi_firmware_property_list(fb->fbdev->fw, &fbinfo,
340 +                                                sizeof(fbinfo));
341 +               if (ret) {
342 +                       dev_err(info->device,
343 +                               "Failed to allocate GPU framebuffer (%d)\n",
344 +                               ret);
345 +                       return ret;
346 +               }
347         }
348  
349         if (info->var.bits_per_pixel <= 8)
350 @@ -314,9 +481,17 @@ static int bcm2708_fb_set_par(struct fb_
351         fb->fb.fix.smem_start = fbinfo.base;
352         fb->fb.fix.smem_len = fbinfo.pitch * fbinfo.yres_virtual;
353         fb->fb.screen_size = fbinfo.screen_size;
354 -       if (fb->fb.screen_base)
355 -               iounmap(fb->fb.screen_base);
356 -       fb->fb.screen_base = ioremap_wc(fbinfo.base, fb->fb.screen_size);
357 +
358 +       if (!fb->dma_addr) {
359 +               if (fb->fb.screen_base)
360 +                       iounmap(fb->fb.screen_base);
361 +
362 +               fb->fb.screen_base = ioremap_wc(fbinfo.base,
363 +                                               fb->fb.screen_size);
364 +       } else {
365 +               fb->fb.screen_base = fb->cpuaddr;
366 +       }
367 +
368         if (!fb->fb.screen_base) {
369                 /* the console may currently be locked */
370                 console_trylock();
371 @@ -374,7 +549,10 @@ static int bcm2708_fb_setcolreg(unsigned
372                         packet->length = regno + 1;
373                         memcpy(packet->cmap, fb->gpu_cmap,
374                                sizeof(packet->cmap));
375 -                       ret = rpi_firmware_property(fb->fw,
376 +
377 +                       set_display_num(fb);
378 +
379 +                       ret = rpi_firmware_property(fb->fbdev->fw,
380                                                     RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE,
381                                                     packet,
382                                                     (2 + packet->length) * sizeof(u32));
383 @@ -413,8 +591,11 @@ static int bcm2708_fb_blank(int blank_mo
384                 return -EINVAL;
385         }
386  
387 -       ret = rpi_firmware_property(fb->fw, RPI_FIRMWARE_FRAMEBUFFER_BLANK,
388 +       set_display_num(fb);
389 +
390 +       ret = rpi_firmware_property(fb->fbdev->fw, RPI_FIRMWARE_FRAMEBUFFER_BLANK,
391                                     &value, sizeof(value));
392 +
393         if (ret)
394                 dev_err(info->device, "%s(%d) failed: %d\n", __func__,
395                         blank_mode, ret);
396 @@ -431,7 +612,7 @@ static int bcm2708_fb_pan_display(struct
397         info->var.yoffset = var->yoffset;
398         result = bcm2708_fb_set_par(info);
399         if (result != 0)
400 -               pr_err("%s(%d,%d) returns=%d\n", __func__, var->xoffset,
401 +               pr_err("%s(%u,%u) returns=%d\n", __func__, var->xoffset,
402                        var->yoffset, result);
403         return result;
404  }
405 @@ -439,8 +620,9 @@ static int bcm2708_fb_pan_display(struct
406  static void dma_memcpy(struct bcm2708_fb *fb, dma_addr_t dst, dma_addr_t src,
407                        int size)
408  {
409 -       int burst_size = (fb->dma_chan == 0) ? 8 : 2;
410 -       struct bcm2708_dma_cb *cb = fb->cb_base;
411 +       struct bcm2708_fb_dev *fbdev = fb->fbdev;
412 +       struct bcm2708_dma_cb *cb = fbdev->cb_base;
413 +       int burst_size = (fbdev->dma_chan == 0) ? 8 : 2;
414  
415         cb->info = BCM2708_DMA_BURST(burst_size) | BCM2708_DMA_S_WIDTH |
416                    BCM2708_DMA_S_INC | BCM2708_DMA_D_WIDTH |
417 @@ -453,21 +635,27 @@ static void dma_memcpy(struct bcm2708_fb
418         cb->pad[1] = 0;
419         cb->next = 0;
420  
421 +       // Not sure what to do if this gets a signal whilst waiting
422 +       if (mutex_lock_interruptible(&fbdev->dma_mutex))
423 +               return;
424 +
425         if (size < dma_busy_wait_threshold) {
426 -               bcm_dma_start(fb->dma_chan_base, fb->cb_handle);
427 -               bcm_dma_wait_idle(fb->dma_chan_base);
428 +               bcm_dma_start(fbdev->dma_chan_base, fbdev->cb_handle);
429 +               bcm_dma_wait_idle(fbdev->dma_chan_base);
430         } else {
431 -               void __iomem *dma_chan = fb->dma_chan_base;
432 +               void __iomem *local_dma_chan = fbdev->dma_chan_base;
433  
434                 cb->info |= BCM2708_DMA_INT_EN;
435 -               bcm_dma_start(fb->dma_chan_base, fb->cb_handle);
436 -               while (bcm_dma_is_busy(dma_chan)) {
437 -                       wait_event_interruptible(fb->dma_waitq,
438 -                                                !bcm_dma_is_busy(dma_chan));
439 +               bcm_dma_start(fbdev->dma_chan_base, fbdev->cb_handle);
440 +               while (bcm_dma_is_busy(local_dma_chan)) {
441 +                       wait_event_interruptible(fbdev->dma_waitq,
442 +                                                !bcm_dma_is_busy(local_dma_chan));
443                 }
444 -               fb->stats.dma_irqs++;
445 +               fbdev->dma_stats.dma_irqs++;
446         }
447 -       fb->stats.dma_copies++;
448 +       fbdev->dma_stats.dma_copies++;
449 +
450 +       mutex_unlock(&fbdev->dma_mutex);
451  }
452  
453  /* address with no aliases */
454 @@ -542,10 +730,13 @@ static int bcm2708_ioctl(struct fb_info
455  
456         switch (cmd) {
457         case FBIO_WAITFORVSYNC:
458 -               ret = rpi_firmware_property(fb->fw,
459 +               set_display_num(fb);
460 +
461 +               ret = rpi_firmware_property(fb->fbdev->fw,
462                                             RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC,
463                                             &dummy, sizeof(dummy));
464                 break;
465 +
466         case FBIODMACOPY:
467         {
468                 struct fb_dmacopy ioparam;
469 @@ -615,23 +806,22 @@ static int bcm2708_compat_ioctl(struct f
470  static void bcm2708_fb_fillrect(struct fb_info *info,
471                                 const struct fb_fillrect *rect)
472  {
473 -       /* (is called) print_debug("bcm2708_fb_fillrect\n"); */
474         cfb_fillrect(info, rect);
475  }
476  
477  /* A helper function for configuring dma control block */
478  static void set_dma_cb(struct bcm2708_dma_cb *cb,
479 -                      int        burst_size,
480 -                      dma_addr_t dst,
481 -                      int        dst_stride,
482 -                      dma_addr_t src,
483 -                      int        src_stride,
484 -                      int        w,
485 -                      int        h)
486 +               int        burst_size,
487 +               dma_addr_t dst,
488 +               int        dst_stride,
489 +               dma_addr_t src,
490 +               int        src_stride,
491 +               int        w,
492 +               int        h)
493  {
494         cb->info = BCM2708_DMA_BURST(burst_size) | BCM2708_DMA_S_WIDTH |
495 -                  BCM2708_DMA_S_INC | BCM2708_DMA_D_WIDTH |
496 -                  BCM2708_DMA_D_INC | BCM2708_DMA_TDMODE;
497 +               BCM2708_DMA_S_INC | BCM2708_DMA_D_WIDTH |
498 +               BCM2708_DMA_D_INC | BCM2708_DMA_TDMODE;
499         cb->dst = dst;
500         cb->src = src;
501         /*
502 @@ -649,15 +839,19 @@ static void bcm2708_fb_copyarea(struct f
503                                 const struct fb_copyarea *region)
504  {
505         struct bcm2708_fb *fb = to_bcm2708(info);
506 -       struct bcm2708_dma_cb *cb = fb->cb_base;
507 +       struct bcm2708_fb_dev *fbdev = fb->fbdev;
508 +       struct bcm2708_dma_cb *cb = fbdev->cb_base;
509         int bytes_per_pixel = (info->var.bits_per_pixel + 7) >> 3;
510  
511         /* Channel 0 supports larger bursts and is a bit faster */
512 -       int burst_size = (fb->dma_chan == 0) ? 8 : 2;
513 +       int burst_size = (fbdev->dma_chan == 0) ? 8 : 2;
514         int pixels = region->width * region->height;
515  
516 -       /* Fallback to cfb_copyarea() if we don't like something */
517 -       if (bytes_per_pixel > 4 ||
518 +       /* If DMA is currently in use (ie being used on another FB), then
519 +        * rather than wait for it to finish, just use the cfb_copyarea
520 +        */
521 +       if (!mutex_trylock(&fbdev->dma_mutex) ||
522 +           bytes_per_pixel > 4 ||
523             info->var.xres * info->var.yres > 1920 * 1200 ||
524             region->width <= 0 || region->width > info->var.xres ||
525             region->height <= 0 || region->height > info->var.yres ||
526 @@ -684,8 +878,8 @@ static void bcm2708_fb_copyarea(struct f
527                  * 1920x1200 resolution at 32bpp pixel depth.
528                  */
529                 int y;
530 -               dma_addr_t control_block_pa = fb->cb_handle;
531 -               dma_addr_t scratchbuf = fb->cb_handle + 16 * 1024;
532 +               dma_addr_t control_block_pa = fbdev->cb_handle;
533 +               dma_addr_t scratchbuf = fbdev->cb_handle + 16 * 1024;
534                 int scanline_size = bytes_per_pixel * region->width;
535                 int scanlines_per_cb = (64 * 1024 - 16 * 1024) / scanline_size;
536  
537 @@ -735,10 +929,10 @@ static void bcm2708_fb_copyarea(struct f
538                 }
539                 set_dma_cb(cb, burst_size,
540                            fb->fb_bus_address + dy * fb->fb.fix.line_length +
541 -                                                  bytes_per_pixel * region->dx,
542 +                          bytes_per_pixel * region->dx,
543                            stride,
544                            fb->fb_bus_address + sy * fb->fb.fix.line_length +
545 -                                                  bytes_per_pixel * region->sx,
546 +                          bytes_per_pixel * region->sx,
547                            stride,
548                            region->width * bytes_per_pixel,
549                            region->height);
550 @@ -748,32 +942,33 @@ static void bcm2708_fb_copyarea(struct f
551         cb->next = 0;
552  
553         if (pixels < dma_busy_wait_threshold) {
554 -               bcm_dma_start(fb->dma_chan_base, fb->cb_handle);
555 -               bcm_dma_wait_idle(fb->dma_chan_base);
556 +               bcm_dma_start(fbdev->dma_chan_base, fbdev->cb_handle);
557 +               bcm_dma_wait_idle(fbdev->dma_chan_base);
558         } else {
559 -               void __iomem *dma_chan = fb->dma_chan_base;
560 +               void __iomem *local_dma_chan = fbdev->dma_chan_base;
561  
562                 cb->info |= BCM2708_DMA_INT_EN;
563 -               bcm_dma_start(fb->dma_chan_base, fb->cb_handle);
564 -               while (bcm_dma_is_busy(dma_chan)) {
565 -                       wait_event_interruptible(fb->dma_waitq,
566 -                                                !bcm_dma_is_busy(dma_chan));
567 +               bcm_dma_start(fbdev->dma_chan_base, fbdev->cb_handle);
568 +               while (bcm_dma_is_busy(local_dma_chan)) {
569 +                       wait_event_interruptible(fbdev->dma_waitq,
570 +                                                !bcm_dma_is_busy(local_dma_chan));
571                 }
572 -               fb->stats.dma_irqs++;
573 +               fbdev->dma_stats.dma_irqs++;
574         }
575 -       fb->stats.dma_copies++;
576 +       fbdev->dma_stats.dma_copies++;
577 +
578 +       mutex_unlock(&fbdev->dma_mutex);
579  }
580  
581  static void bcm2708_fb_imageblit(struct fb_info *info,
582                                  const struct fb_image *image)
583  {
584 -       /* (is called) print_debug("bcm2708_fb_imageblit\n"); */
585         cfb_imageblit(info, image);
586  }
587  
588  static irqreturn_t bcm2708_fb_dma_irq(int irq, void *cxt)
589  {
590 -       struct bcm2708_fb *fb = cxt;
591 +       struct bcm2708_fb_dev *fbdev = cxt;
592  
593         /* FIXME: should read status register to check if this is
594          * actually interrupting us or not, in case this interrupt
595 @@ -783,9 +978,9 @@ static irqreturn_t bcm2708_fb_dma_irq(in
596          */
597  
598         /* acknowledge the interrupt */
599 -       writel(BCM2708_DMA_INT, fb->dma_chan_base + BCM2708_DMA_CS);
600 +       writel(BCM2708_DMA_INT, fbdev->dma_chan_base + BCM2708_DMA_CS);
601  
602 -       wake_up(&fb->dma_waitq);
603 +       wake_up(&fbdev->dma_waitq);
604         return IRQ_HANDLED;
605  }
606  
607 @@ -821,11 +1016,23 @@ static int bcm2708_fb_register(struct bc
608         fb->fb.fix.ywrapstep = 0;
609         fb->fb.fix.accel = FB_ACCEL_NONE;
610  
611 -       fb->fb.var.xres = fbwidth;
612 -       fb->fb.var.yres = fbheight;
613 -       fb->fb.var.xres_virtual = fbwidth;
614 -       fb->fb.var.yres_virtual = fbheight;
615 -       fb->fb.var.bits_per_pixel = fbdepth;
616 +       /* If we have data from the VC4 on FB's, use that, otherwise use the
617 +        * module parameters
618 +        */
619 +       if (fb->display_settings.width) {
620 +               fb->fb.var.xres = fb->display_settings.width;
621 +               fb->fb.var.yres = fb->display_settings.height;
622 +               fb->fb.var.xres_virtual = fb->fb.var.xres;
623 +               fb->fb.var.yres_virtual = fb->fb.var.yres;
624 +               fb->fb.var.bits_per_pixel = fb->display_settings.depth;
625 +       } else {
626 +               fb->fb.var.xres = fbwidth;
627 +               fb->fb.var.yres = fbheight;
628 +               fb->fb.var.xres_virtual = fbwidth;
629 +               fb->fb.var.yres_virtual = fbheight;
630 +               fb->fb.var.bits_per_pixel = fbdepth;
631 +       }
632 +
633         fb->fb.var.vmode = FB_VMODE_NONINTERLACED;
634         fb->fb.var.activate = FB_ACTIVATE_NOW;
635         fb->fb.var.nonstd = 0;
636 @@ -841,26 +1048,23 @@ static int bcm2708_fb_register(struct bc
637         fb->fb.monspecs.dclkmax = 100000000;
638  
639         bcm2708_fb_set_bitfields(&fb->fb.var);
640 -       init_waitqueue_head(&fb->dma_waitq);
641  
642         /*
643          * Allocate colourmap.
644          */
645 -
646         fb_set_var(&fb->fb, &fb->fb.var);
647 +
648         ret = bcm2708_fb_set_par(&fb->fb);
649 +
650         if (ret)
651                 return ret;
652  
653 -       print_debug("BCM2708FB: registering framebuffer (%dx%d@%d) (%d)\n",
654 -                   fbwidth, fbheight, fbdepth, fbswap);
655 -
656         ret = register_framebuffer(&fb->fb);
657 -       print_debug("BCM2708FB: register framebuffer (%d)\n", ret);
658 +
659         if (ret == 0)
660                 goto out;
661  
662 -       print_debug("BCM2708FB: cannot register framebuffer (%d)\n", ret);
663 +       dev_warn(fb->fb.dev, "Unable to register framebuffer (%d)\n", ret);
664  out:
665         return ret;
666  }
667 @@ -869,10 +1073,18 @@ static int bcm2708_fb_probe(struct platf
668  {
669         struct device_node *fw_np;
670         struct rpi_firmware *fw;
671 -       struct bcm2708_fb *fb;
672 -       int ret;
673 +       int ret, i;
674 +       u32 num_displays;
675 +       struct bcm2708_fb_dev *fbdev;
676 +       struct { u32 base, length; } gpu_mem;
677 +
678 +       fbdev = devm_kzalloc(&dev->dev, sizeof(*fbdev), GFP_KERNEL);
679 +
680 +       if (!fbdev)
681 +               return -ENOMEM;
682  
683         fw_np = of_parse_phandle(dev->dev.of_node, "firmware", 0);
684 +
685  /* Remove comment when booting without Device Tree is no longer supported
686   *     if (!fw_np) {
687   *             dev_err(&dev->dev, "Missing firmware node\n");
688 @@ -880,90 +1092,154 @@ static int bcm2708_fb_probe(struct platf
689   *     }
690   */
691         fw = rpi_firmware_get(fw_np);
692 +       fbdev->fw = fw;
693 +
694         if (!fw)
695                 return -EPROBE_DEFER;
696  
697 -       fb = kzalloc(sizeof(*fb), GFP_KERNEL);
698 -       if (!fb) {
699 -               ret = -ENOMEM;
700 -               goto free_region;
701 +       ret = rpi_firmware_property(fw,
702 +                                   RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS,
703 +                                   &num_displays, sizeof(u32));
704 +
705 +       /* If we fail to get the number of displays, or it returns 0, then
706 +        * assume old firmware that doesn't have the mailbox call, so just
707 +        * set one display
708 +        */
709 +       if (ret || num_displays == 0) {
710 +               num_displays = 1;
711 +               dev_err(&dev->dev,
712 +                       "Unable to determine number of FB's. Assuming 1\n");
713 +               ret = 0;
714 +       } else {
715 +               fbdev->firmware_supports_multifb = 1;
716         }
717  
718 -       fb->fw = fw;
719 -       bcm2708_fb_debugfs_init(fb);
720 +       if (num_displays > MAX_FRAMEBUFFERS) {
721 +               dev_warn(&dev->dev,
722 +                        "More displays reported from firmware than supported in driver (%u vs %u)",
723 +                        num_displays, MAX_FRAMEBUFFERS);
724 +               num_displays = MAX_FRAMEBUFFERS;
725 +       }
726  
727 -       fb->cb_base = dma_alloc_writecombine(&dev->dev, SZ_64K,
728 -                                            &fb->cb_handle, GFP_KERNEL);
729 -       if (!fb->cb_base) {
730 +       dev_info(&dev->dev, "FB found %d display(s)\n", num_displays);
731 +
732 +       /* Set up the DMA information. Note we have just one set of DMA
733 +        * parameters to work with all the FB's so requires synchronising when
734 +        * being used
735 +        */
736 +
737 +       mutex_init(&fbdev->dma_mutex);
738 +
739 +       fbdev->cb_base = dma_alloc_writecombine(&dev->dev, SZ_64K,
740 +                                               &fbdev->cb_handle,
741 +                                               GFP_KERNEL);
742 +       if (!fbdev->cb_base) {
743                 dev_err(&dev->dev, "cannot allocate DMA CBs\n");
744                 ret = -ENOMEM;
745                 goto free_fb;
746         }
747  
748 -       pr_info("BCM2708FB: allocated DMA memory %pad\n", &fb->cb_handle);
749 -
750         ret = bcm_dma_chan_alloc(BCM_DMA_FEATURE_BULK,
751 -                                &fb->dma_chan_base, &fb->dma_irq);
752 +                                &fbdev->dma_chan_base,
753 +                                &fbdev->dma_irq);
754         if (ret < 0) {
755 -               dev_err(&dev->dev, "couldn't allocate a DMA channel\n");
756 +               dev_err(&dev->dev, "Couldn't allocate a DMA channel\n");
757                 goto free_cb;
758         }
759 -       fb->dma_chan = ret;
760 +       fbdev->dma_chan = ret;
761  
762 -       ret = request_irq(fb->dma_irq, bcm2708_fb_dma_irq,
763 -                         0, "bcm2708_fb dma", fb);
764 +       ret = request_irq(fbdev->dma_irq, bcm2708_fb_dma_irq,
765 +                         0, "bcm2708_fb DMA", fbdev);
766         if (ret) {
767 -               pr_err("%s: failed to request DMA irq\n", __func__);
768 +               dev_err(&dev->dev,
769 +                       "Failed to request DMA irq\n");
770                 goto free_dma_chan;
771         }
772  
773 -       pr_info("BCM2708FB: allocated DMA channel %d\n", fb->dma_chan);
774 +       rpi_firmware_property(fbdev->fw,
775 +                             RPI_FIRMWARE_GET_VC_MEMORY,
776 +                             &gpu_mem, sizeof(gpu_mem));
777 +
778 +       for (i = 0; i < num_displays; i++) {
779 +               struct bcm2708_fb *fb = &fbdev->displays[i];
780 +
781 +               fb->display_settings.display_num = i;
782 +               fb->dev = dev;
783 +               fb->fb.device = &dev->dev;
784 +               fb->fbdev = fbdev;
785 +
786 +               fb->gpu.base = gpu_mem.base;
787 +               fb->gpu.length = gpu_mem.length;
788 +
789 +               if (fbdev->firmware_supports_multifb) {
790 +                       ret = rpi_firmware_property(fw,
791 +                                                   RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_SETTINGS,
792 +                                                   &fb->display_settings,
793 +                                                   GET_DISPLAY_SETTINGS_PAYLOAD_SIZE);
794 +               } else {
795 +                       memset(&fb->display_settings, 0,
796 +                              sizeof(fb->display_settings));
797 +               }
798 +
799 +               ret = bcm2708_fb_register(fb);
800  
801 -       fb->dev = dev;
802 -       fb->fb.device = &dev->dev;
803 +               if (ret == 0) {
804 +                       bcm2708_fb_debugfs_init(fb);
805  
806 -       /* failure here isn't fatal, but we'll fail in vc_mem_copy if
807 -        * fb->gpu is not valid
808 -        */
809 -       rpi_firmware_property(fb->fw, RPI_FIRMWARE_GET_VC_MEMORY, &fb->gpu,
810 -                             sizeof(fb->gpu));
811 +                       fbdev->num_displays++;
812  
813 -       ret = bcm2708_fb_register(fb);
814 -       if (ret == 0) {
815 -               platform_set_drvdata(dev, fb);
816 -               goto out;
817 +                       dev_info(&dev->dev,
818 +                                "Registered framebuffer for display %u, size %ux%u\n",
819 +                                fb->display_settings.display_num,
820 +                                fb->fb.var.xres,
821 +                                fb->fb.var.yres);
822 +               } else {
823 +                       // Use this to flag if this FB entry is in use.
824 +                       fb->fbdev = NULL;
825 +               }
826 +       }
827 +
828 +       // Did we actually successfully create any FB's?
829 +       if (fbdev->num_displays) {
830 +               init_waitqueue_head(&fbdev->dma_waitq);
831 +               platform_set_drvdata(dev, fbdev);
832 +               return ret;
833         }
834  
835  free_dma_chan:
836 -       bcm_dma_chan_free(fb->dma_chan);
837 +       bcm_dma_chan_free(fbdev->dma_chan);
838  free_cb:
839 -       dma_free_writecombine(&dev->dev, SZ_64K, fb->cb_base, fb->cb_handle);
840 +       dma_free_writecombine(&dev->dev, SZ_64K, fbdev->cb_base,
841 +                             fbdev->cb_handle);
842  free_fb:
843 -       kfree(fb);
844 -free_region:
845         dev_err(&dev->dev, "probe failed, err %d\n", ret);
846 -out:
847 +
848         return ret;
849  }
850  
851  static int bcm2708_fb_remove(struct platform_device *dev)
852  {
853 -       struct bcm2708_fb *fb = platform_get_drvdata(dev);
854 +       struct bcm2708_fb_dev *fbdev = platform_get_drvdata(dev);
855 +       int i;
856  
857         platform_set_drvdata(dev, NULL);
858  
859 -       if (fb->fb.screen_base)
860 -               iounmap(fb->fb.screen_base);
861 -       unregister_framebuffer(&fb->fb);
862 -
863 -       dma_free_writecombine(&dev->dev, SZ_64K, fb->cb_base, fb->cb_handle);
864 -       bcm_dma_chan_free(fb->dma_chan);
865 -
866 -       bcm2708_fb_debugfs_deinit(fb);
867 +       for (i = 0; i < fbdev->num_displays; i++) {
868 +               if (fbdev->displays[i].fb.screen_base)
869 +                       iounmap(fbdev->displays[i].fb.screen_base);
870 +
871 +               if (fbdev->displays[i].fbdev) {
872 +                       unregister_framebuffer(&fbdev->displays[i].fb);
873 +                       bcm2708_fb_debugfs_deinit(&fbdev->displays[i]);
874 +               }
875 +       }
876  
877 -       free_irq(fb->dma_irq, fb);
878 +       dma_free_writecombine(&dev->dev, SZ_64K, fbdev->cb_base,
879 +                             fbdev->cb_handle);
880 +       bcm_dma_chan_free(fbdev->dma_chan);
881 +       free_irq(fbdev->dma_irq, fbdev);
882  
883 -       kfree(fb);
884 +       mutex_destroy(&fbdev->dma_mutex);
885  
886         return 0;
887  }
888 @@ -978,10 +1254,10 @@ static struct platform_driver bcm2708_fb
889         .probe = bcm2708_fb_probe,
890         .remove = bcm2708_fb_remove,
891         .driver = {
892 -                  .name = DRIVER_NAME,
893 -                  .owner = THIS_MODULE,
894 -                  .of_match_table = bcm2708_fb_of_match_table,
895 -                  },
896 +                 .name = DRIVER_NAME,
897 +                 .owner = THIS_MODULE,
898 +                 .of_match_table = bcm2708_fb_of_match_table,
899 +                 },
900  };
901  
902  static int __init bcm2708_fb_init(void)
903 --- a/include/soc/bcm2835/raspberrypi-firmware.h
904 +++ b/include/soc/bcm2835/raspberrypi-firmware.h
905 @@ -138,9 +138,11 @@ enum rpi_firmware_property_tag {
906         RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH =                  0x00048005,
907         RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER =            0x00048006,
908         RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE =             0x00048007,
909 +       RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH =                  0x00048008,
910         RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET =         0x00048009,
911         RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN =               0x0004800a,
912         RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE =                0x0004800b,
913 +
914         RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF =               0x0004801f,
915         RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF =            0x00048020,
916         RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC =                  0x0004800e,
917 @@ -159,6 +161,8 @@ enum rpi_firmware_property_tag {
918         RPI_FIRMWARE_GET_DMA_CHANNELS =                       0x00060001,
919  };
920  
921 +#define GET_DISPLAY_SETTINGS_PAYLOAD_SIZE 64
922 +
923  #if IS_ENABLED(CONFIG_RASPBERRYPI_FIRMWARE)
924  int rpi_firmware_property(struct rpi_firmware *fw,
925                           u32 tag, void *data, size_t len);