Message ID | 20211227182506.2110551-1-alexander.deucher@amd.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/2] fbdev: fbmem: add a helper to determine if an aperture is used by a fw fb | expand |
Hi Am 27.12.21 um 19:25 schrieb Alex Deucher: > Add a function for drivers to check if the a firmware initialized > fb is corresponds to their aperture. This allows drivers to check if the > device corresponds to what the firmware set up as the display device. If simpledrm is in use, it will register via DRM aperture helpers. You probably need a similar function in drm_aperture.c to handle this. Best regards Thomas > > Bug: https://bugzilla.kernel.org/show_bug.cgi?id=215203 > Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1840 > Signed-off-by: Alex Deucher <alexander.deucher@amd.com> > --- > drivers/video/fbdev/core/fbmem.c | 47 ++++++++++++++++++++++++++++++++ > include/linux/fb.h | 1 + > 2 files changed, 48 insertions(+) > > diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c > index 826175ad88a2..0fa7ede94fa6 100644 > --- a/drivers/video/fbdev/core/fbmem.c > +++ b/drivers/video/fbdev/core/fbmem.c > @@ -1762,6 +1762,53 @@ int remove_conflicting_framebuffers(struct apertures_struct *a, > } > EXPORT_SYMBOL(remove_conflicting_framebuffers); > > +/** > + * is_firmware_framebuffer - detect if firmware-configured framebuffer matches > + * @a: memory range, users of which are to be checked > + * > + * This function checks framebuffer devices (initialized by firmware/bootloader) > + * which use memory range described by @a. If @a matchesm the function returns > + * true, otherwise false. > + */ > +bool is_firmware_framebuffer(struct apertures_struct *a) > +{ > + bool do_free = false; > + bool found = false; > + int i; > + > + if (!a) { > + a = alloc_apertures(1); > + if (!a) > + return false; > + > + a->ranges[0].base = 0; > + a->ranges[0].size = ~0; > + do_free = true; > + } > + > + mutex_lock(®istration_lock); > + /* check all firmware fbs and kick off if the base addr overlaps */ > + for_each_registered_fb(i) { > + struct apertures_struct *gen_aper; > + > + if (!(registered_fb[i]->flags & FBINFO_MISC_FIRMWARE)) > + continue; > + > + gen_aper = registered_fb[i]->apertures; > + if (fb_do_apertures_overlap(gen_aper, a)) { > + found = true; > + break; > + } > + } > + mutex_unlock(®istration_lock); > + > + if (do_free) > + kfree(a); > + > + return found; > +} > +EXPORT_SYMBOL(is_firmware_framebuffer); > + > /** > * remove_conflicting_pci_framebuffers - remove firmware-configured framebuffers for PCI devices > * @pdev: PCI device > diff --git a/include/linux/fb.h b/include/linux/fb.h > index 6f3db99ab990..3da95842b207 100644 > --- a/include/linux/fb.h > +++ b/include/linux/fb.h > @@ -610,6 +610,7 @@ extern int remove_conflicting_pci_framebuffers(struct pci_dev *pdev, > const char *name); > extern int remove_conflicting_framebuffers(struct apertures_struct *a, > const char *name, bool primary); > +extern bool is_firmware_framebuffer(struct apertures_struct *a); > extern int fb_prepare_logo(struct fb_info *fb_info, int rotate); > extern int fb_show_logo(struct fb_info *fb_info, int rotate); > extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 826175ad88a2..0fa7ede94fa6 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1762,6 +1762,53 @@ int remove_conflicting_framebuffers(struct apertures_struct *a, } EXPORT_SYMBOL(remove_conflicting_framebuffers); +/** + * is_firmware_framebuffer - detect if firmware-configured framebuffer matches + * @a: memory range, users of which are to be checked + * + * This function checks framebuffer devices (initialized by firmware/bootloader) + * which use memory range described by @a. If @a matchesm the function returns + * true, otherwise false. + */ +bool is_firmware_framebuffer(struct apertures_struct *a) +{ + bool do_free = false; + bool found = false; + int i; + + if (!a) { + a = alloc_apertures(1); + if (!a) + return false; + + a->ranges[0].base = 0; + a->ranges[0].size = ~0; + do_free = true; + } + + mutex_lock(®istration_lock); + /* check all firmware fbs and kick off if the base addr overlaps */ + for_each_registered_fb(i) { + struct apertures_struct *gen_aper; + + if (!(registered_fb[i]->flags & FBINFO_MISC_FIRMWARE)) + continue; + + gen_aper = registered_fb[i]->apertures; + if (fb_do_apertures_overlap(gen_aper, a)) { + found = true; + break; + } + } + mutex_unlock(®istration_lock); + + if (do_free) + kfree(a); + + return found; +} +EXPORT_SYMBOL(is_firmware_framebuffer); + /** * remove_conflicting_pci_framebuffers - remove firmware-configured framebuffers for PCI devices * @pdev: PCI device diff --git a/include/linux/fb.h b/include/linux/fb.h index 6f3db99ab990..3da95842b207 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -610,6 +610,7 @@ extern int remove_conflicting_pci_framebuffers(struct pci_dev *pdev, const char *name); extern int remove_conflicting_framebuffers(struct apertures_struct *a, const char *name, bool primary); +extern bool is_firmware_framebuffer(struct apertures_struct *a); extern int fb_prepare_logo(struct fb_info *fb_info, int rotate); extern int fb_show_logo(struct fb_info *fb_info, int rotate); extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
Add a function for drivers to check if the a firmware initialized fb is corresponds to their aperture. This allows drivers to check if the device corresponds to what the firmware set up as the display device. Bug: https://bugzilla.kernel.org/show_bug.cgi?id=215203 Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1840 Signed-off-by: Alex Deucher <alexander.deucher@amd.com> --- drivers/video/fbdev/core/fbmem.c | 47 ++++++++++++++++++++++++++++++++ include/linux/fb.h | 1 + 2 files changed, 48 insertions(+)