summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/gma500
diff options
context:
space:
mode:
authorThomas Zimmermann <tzimmermann@suse.de>2023-04-06 15:21:09 +0200
committerThomas Zimmermann <tzimmermann@suse.de>2023-04-16 14:18:10 +0200
commit116b1c5a364bcbdc40be64d4f3ec9dbc32e264dd (patch)
tree022d48d0daef251a872e92514ff3df09cad0ca47 /drivers/gpu/drm/gma500
parent5ca1479cd35d9003040e6ac829380debe89b802b (diff)
video/aperture: Provide a VGA helper for gma500 and internal use
The hardware for gma500 is different from the rest, as it uses stolen framebuffer memory that is not available via PCI BAR. The regular PCI removal helper cannot detect the framebuffer, while the non-PCI helper misses possible conflicting VGA devices (i.e., a framebuffer or text console). Gma500 therefore calls both helpers to catch all cases. It's confusing as it implies that there's something about the PCI device that requires ownership management. The relationship between the PCI device and the VGA devices is non-obvious. At worst, readers might assume that calling two functions for clearing aperture ownership is a bug in the driver. Hence, move the PCI removal helper's code for VGA functionality into a separate function and call this function from gma500. Documents the purpose of each call to aperture helpers. The change contains comments and example code form the discussion at [1]. v5: * fix grammar in gma500 comment (Javier) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.kernel.org/project/dri-devel/patch/20230404201842.567344-1-daniel.vetter@ffwll.ch/ # 1 Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230406132109.32050-10-tzimmermann@suse.de
Diffstat (limited to 'drivers/gpu/drm/gma500')
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.c48
1 files changed, 34 insertions, 14 deletions
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 4bb06a89e48d..8b64f61ffaf9 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -7,6 +7,7 @@
*
**************************************************************************/
+#include <linux/aperture.h>
#include <linux/cpu.h>
#include <linux/module.h>
#include <linux/notifier.h>
@@ -19,7 +20,6 @@
#include <acpi/video.h>
#include <drm/drm.h>
-#include <drm/drm_aperture.h>
#include <drm/drm_drv.h>
#include <drm/drm_file.h>
#include <drm/drm_ioctl.h>
@@ -414,25 +414,45 @@ out_err:
return ret;
}
-static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+/*
+ * Hardware for gma500 is a hybrid device, which both acts as a PCI
+ * device (for legacy vga functionality) but also more like an
+ * integrated display on a SoC where the framebuffer simply
+ * resides in main memory and not in a special PCI bar (that
+ * internally redirects to a stolen range of main memory) like all
+ * other integrated PCI display devices implement it.
+ *
+ * To catch all cases we need to remove conflicting firmware devices
+ * for the stolen system memory and for the VGA functionality. As we
+ * currently cannot easily find the framebuffer's location in stolen
+ * memory, we remove all framebuffers here.
+ *
+ * TODO: Refactor psb_driver_load() to map vdc_reg earlier. Then
+ * we might be able to read the framebuffer range from the
+ * device.
+ */
+static int gma_remove_conflicting_framebuffers(struct pci_dev *pdev,
+ const struct drm_driver *req_driver)
{
- struct drm_psb_private *dev_priv;
- struct drm_device *dev;
+ resource_size_t base = 0;
+ resource_size_t size = U32_MAX; /* 4 GiB HW limit */
+ const char *name = req_driver->name;
int ret;
- /*
- * We cannot yet easily find the framebuffer's location in memory. So
- * remove all framebuffers here. Note that we still want the pci special
- * handling to kick out vgacon.
- *
- * TODO: Refactor psb_driver_load() to map vdc_reg earlier. Then we
- * might be able to read the framebuffer range from the device.
- */
- ret = drm_aperture_remove_framebuffers(&driver);
+ ret = aperture_remove_conflicting_devices(base, size, name);
if (ret)
return ret;
- ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver);
+ return __aperture_remove_legacy_vga_devices(pdev);
+}
+
+static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ struct drm_psb_private *dev_priv;
+ struct drm_device *dev;
+ int ret;
+
+ ret = gma_remove_conflicting_framebuffers(pdev, &driver);
if (ret)
return ret;