diff mbox series

[1/2] fbdev: fbmem: add a helper to determine if an aperture is used by a fw fb

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

Commit Message

Alex Deucher Dec. 27, 2021, 6:25 p.m. UTC
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(+)

Comments

Thomas Zimmermann Jan. 6, 2022, 9:50 a.m. UTC | #1
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(&registration_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(&registration_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 mbox series

Patch

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(&registration_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(&registration_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);