summaryrefslogtreecommitdiffstats
path: root/drivers/video/fbdev/core/fbmem.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-10-05 11:24:12 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2022-10-05 11:24:12 -0700
commit7e6739b9336e61fe23ca4e2c8d1fda8f19f979bf (patch)
treeda3dc30b7ba682edbb7392028e20dcce194b958b /drivers/video/fbdev/core/fbmem.c
parenta47e60729d9624e931f988709ab76e043e2ee8b9 (diff)
parent65898687cf7392c372ea8d04a88617e2cb794465 (diff)
downloadlinux-7e6739b9336e61fe23ca4e2c8d1fda8f19f979bf.tar.bz2
Merge tag 'drm-next-2022-10-05' of git://anongit.freedesktop.org/drm/drm
Pull drm updates from Dave Airlie: "Lots of stuff all over, some new AMD IP support and gang submit support. i915 has further DG2 and Meteorlake pieces, and a bunch of i915 display refactoring. msm has a shrinker rework. There are also a bunch of conversions to use kunit. This has two external pieces, some MEI changes needed for future Intel discrete GPUs. These should be acked by Greg. There is also a cross maintainer shared tree with some backlight rework from Hans in here. Core: - convert selftests to kunit - managed init for more objects - move to idr_init_base - rename fb and gem cma helpers to dma - hide unregistered connectors from getconnector ioctl - DSC passthrough aux support - backlight handling improvements - add dma_resv_assert_held to vmap/vunmap edid: - move luminance calculation to core fbdev: - fix aperture helper usage fourcc: - add more format helpers - add DRM_FORMAT_Cxx, DRM_FORMAT_Rxx, DRM_FORMAT_Dxx - add packed AYUV8888, XYUV8888 - add some kunit tests ttm: - allow bos without backing store - rewrite placement to use intersect/compatible functions dma-buf: - docs update - improve signalling when debugging udmabuf: - fix failure path GPF dp: - drop dp/mst legacy code - atomic mst state support - audio infoframe packing panel: - Samsung LTL101AL01 - B120XAN01.0 - R140NWF5 RH - DMT028VGHMCMI-1A T - AUO B133UAN02.1 - IVO M133NW4J-R3 - Innolux N120ACA-EA1 amdgpu: - Gang submit support - Mode2 reset for RDNA2 - New IP support: DCN 3.1.4, 3.2 SMU 13.x NBIO 7.7 GC 11.x PSP 13.x SDMA 6.x GMC 11.x - DSC passthrough support - PSP fixes for TA support - vangogh GFXOFF stats - clang fixes - gang submit CS cleanup prep work - fix VRAM eviction issues amdkfd: - GC 10.3 IP ISA fixes - fix CRIU regression - CPU fault on COW mapping fixes i915: - align fw versioning with kernel practices - add display substruct to i915 private - add initial runtime info to driver info - split out HDCP and backlight registers - MEI XeHP SDV GSC support - add per-gt sysfs defaults - TLB invalidation improvements - Disable PCI BAR resize on 32-bit - GuC firmware updates and compat changes - GuC log timestamp translation - DG2 preemption workaround changes - DG2 improved HDMI pixel clocks support - PCI BAR sanity checks - Enable DC5 on DG2 - DG2 DMC fw bumped - ADL-S PCI ID added - Meteorlake enablement - Rename ggtt_view to gtt_view - host RPS fixes - release mmaps on rpm suspend on discrete - clocking and dpll refactoring - VBT definitions and parsing updates - SKL watermark code extracted to separate file - allow seamless M/N changes on eDP panels - BUG_ON removal and cleanups msm: - DPU: simplified VBIF configuration cleanup CTL interfaces - DSI: removed unused msm_display_dsc_config struct switch regulator calls to new API switched to PANEL_BRIDGE for direct attached panels - DSI_PHY: convert drivers to parent_hws - DP: cleanup pixel_rate handling - HDMI: turned hdmi-phy-8996 into OF clk provider - misc dt-bindings fixes - choose eDP as primary display if it's available - support getting interconnects from either the mdss or the mdp5/dpu device nodes - gem: Shrinker + LRU re-work: - adds a shared GEM LRU+shrinker helper and moves msm over to that - reduce lock contention between retire and submit by avoiding the need to acquire obj lock in retire path (and instead using resv seeing obj's busyness in the shrinker - fix reclaim vs submit issues - GEM fault injection for triggering userspace error paths - Map/unmap optimization - Improved robustness for a6xx GPU recovery virtio: - improve error and edge conditions handling - convert to use managed helpers - stop exposing LINEAR modifier mgag200: - split modeset handling per model udl: - suspend/disconnect handling improvements vc4: - rework HDMI power up - depend on PM - better unplugging support ast: - resolution handling improvements ingenic: - add JZ4760(B) support - avoid a modeset when sharpness property is unchanged - use the new PM ops it6505: - power seq and clock updates ssd130x: - regmap bulk write - use atomic helpers instead of simple helpers via: - rename via_drv to via_dri1, consolidate all code. radeon: - drop DP MST experimental support - delayed work flush fix - use time_after ti-sn65dsi86: - DP support mediatek: - MT8195 DP support - drop of_gpio header - remove unneeded result - small DP code improvements vkms: - RGB565, XRGB64 and ARGB64 support sun4i: - tv: convert to atomic rcar-du: - Synopsys DW HDMI bridge DT bindings update exynos: - use drm_display_info.is_hdmi - correct return of mixer_mode_valid and hdmi_mode_valid omap: - refcounting fix rockchip: - RK3568 support - RK3399 gamma support" * tag 'drm-next-2022-10-05' of git://anongit.freedesktop.org/drm/drm: (1374 commits) drm/amdkfd: Fix UBSAN shift-out-of-bounds warning drm/amdkfd: Track unified memory when switching xnack mode drm/amdgpu: Enable sram on vcn_4_0_2 drm/amdgpu: Enable VCN DPG for GC11_0_1 drm/msm: Fix build break with recent mm tree drm/panel: simple: Use dev_err_probe() to simplify code drm/panel: panel-edp: Use dev_err_probe() to simplify code drm/panel: simple: Add Multi-Inno Technology MI0800FT-9 dt-bindings: display: simple: Add Multi-Inno Technology MI0800FT-9 panel drm/amdgpu: correct the memcpy size for ip discovery firmware drm/amdgpu: Skip put_reset_domain if it doesn't exist drm/amdgpu: remove switch from amdgpu_gmc_noretry_set drm/amdgpu: Fix mc_umc_status used uninitialized warning drm/amd/display: Prevent OTG shutdown during PSR SU drm/amdgpu: add page retirement handling for CPU RAS drm/amdgpu: use RAS error address convert api in mca notifier drm/amdgpu: support to convert dedicated umc mca address drm/amdgpu: export umc error address convert interface drm/amdgpu: fix sdma v4 init microcode error drm/amd/display: fix array-bounds error in dc_stream_remove_writeback() ...
Diffstat (limited to 'drivers/video/fbdev/core/fbmem.c')
-rw-r--r--drivers/video/fbdev/core/fbmem.c219
1 files changed, 28 insertions, 191 deletions
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index 02b0cf2cfafe..1e70d8c67653 100644
--- a/drivers/video/fbdev/core/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
@@ -13,13 +13,13 @@
#include <linux/module.h>
+#include <linux/aperture.h>
#include <linux/compat.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/slab.h>
-#include <linux/sysfb.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/vt.h>
@@ -40,6 +40,7 @@
#include <asm/fb.h>
+#include <video/vga.h>
/*
* Frame buffer device initialization and setup routines
@@ -50,10 +51,10 @@
static DEFINE_MUTEX(registration_lock);
struct fb_info *registered_fb[FB_MAX] __read_mostly;
-EXPORT_SYMBOL(registered_fb);
-
int num_registered_fb __read_mostly;
-EXPORT_SYMBOL(num_registered_fb);
+#define for_each_registered_fb(i) \
+ for (i = 0; i < FB_MAX; i++) \
+ if (!registered_fb[i]) {} else
bool fb_center_logo __read_mostly;
@@ -1525,103 +1526,6 @@ static int fb_check_foreignness(struct fb_info *fi)
return 0;
}
-static bool apertures_overlap(struct aperture *gen, struct aperture *hw)
-{
- /* is the generic aperture base the same as the HW one */
- if (gen->base == hw->base)
- return true;
- /* is the generic aperture base inside the hw base->hw base+size */
- if (gen->base > hw->base && gen->base < hw->base + hw->size)
- return true;
- return false;
-}
-
-static bool fb_do_apertures_overlap(struct apertures_struct *gena,
- struct apertures_struct *hwa)
-{
- int i, j;
- if (!hwa || !gena)
- return false;
-
- for (i = 0; i < hwa->count; ++i) {
- struct aperture *h = &hwa->ranges[i];
- for (j = 0; j < gena->count; ++j) {
- struct aperture *g = &gena->ranges[j];
- printk(KERN_DEBUG "checking generic (%llx %llx) vs hw (%llx %llx)\n",
- (unsigned long long)g->base,
- (unsigned long long)g->size,
- (unsigned long long)h->base,
- (unsigned long long)h->size);
- if (apertures_overlap(g, h))
- return true;
- }
- }
-
- return false;
-}
-
-static void do_unregister_framebuffer(struct fb_info *fb_info);
-
-#define VGA_FB_PHYS 0xA0000
-static void do_remove_conflicting_framebuffers(struct apertures_struct *a,
- const char *name, bool primary)
-{
- int i;
-
-restart_removal:
- /* check all firmware fbs and kick off if the base addr overlaps */
- for_each_registered_fb(i) {
- struct apertures_struct *gen_aper;
- struct device *device;
-
- if (!(registered_fb[i]->flags & FBINFO_MISC_FIRMWARE))
- continue;
-
- gen_aper = registered_fb[i]->apertures;
- device = registered_fb[i]->device;
- if (fb_do_apertures_overlap(gen_aper, a) ||
- (primary && gen_aper && gen_aper->count &&
- gen_aper->ranges[0].base == VGA_FB_PHYS)) {
-
- printk(KERN_INFO "fb%d: switching to %s from %s\n",
- i, name, registered_fb[i]->fix.id);
-
- /*
- * If we kick-out a firmware driver, we also want to remove
- * the underlying platform device, such as simple-framebuffer,
- * VESA, EFI, etc. A native driver will then be able to
- * allocate the memory range.
- *
- * If it's not a platform device, at least print a warning. A
- * fix would add code to remove the device from the system. For
- * framebuffers without any Linux device, print a warning as
- * well.
- */
- if (!device) {
- pr_warn("fb%d: no device set\n", i);
- do_unregister_framebuffer(registered_fb[i]);
- } else if (dev_is_platform(device)) {
- /*
- * Drop the lock because if the device is unregistered, its
- * driver will call to unregister_framebuffer(), that takes
- * this lock.
- */
- mutex_unlock(&registration_lock);
- platform_device_unregister(to_platform_device(device));
- mutex_lock(&registration_lock);
- } else {
- pr_warn("fb%d: cannot remove device\n", i);
- do_unregister_framebuffer(registered_fb[i]);
- }
- /*
- * Restart the removal loop now that the device has been
- * unregistered and its associated framebuffer gone.
- */
- goto restart_removal;
- }
- }
-}
-
static int do_register_framebuffer(struct fb_info *fb_info)
{
int i;
@@ -1630,10 +1534,6 @@ static int do_register_framebuffer(struct fb_info *fb_info)
if (fb_check_foreignness(fb_info))
return -ENOSYS;
- do_remove_conflicting_framebuffers(fb_info->apertures,
- fb_info->fix.id,
- fb_is_primary_device(fb_info));
-
if (num_registered_fb == FB_MAX)
return -ENXIO;
@@ -1752,100 +1652,31 @@ static void do_unregister_framebuffer(struct fb_info *fb_info)
put_fb_info(fb_info);
}
-/**
- * remove_conflicting_framebuffers - remove firmware-configured framebuffers
- * @a: memory range, users of which are to be removed
- * @name: requesting driver name
- * @primary: also kick vga16fb if present
- *
- * This function removes framebuffer devices (initialized by firmware/bootloader)
- * which use memory range described by @a. If @a is NULL all such devices are
- * removed.
- */
-int remove_conflicting_framebuffers(struct apertures_struct *a,
- const char *name, bool primary)
+static int fb_aperture_acquire_for_platform_device(struct fb_info *fb_info)
{
- bool do_free = false;
-
- if (!a) {
- a = alloc_apertures(1);
- if (!a)
- return -ENOMEM;
-
- a->ranges[0].base = 0;
- a->ranges[0].size = ~0;
- do_free = true;
- }
-
- /*
- * If a driver asked to unregister a platform device registered by
- * sysfb, then can be assumed that this is a driver for a display
- * that is set up by the system firmware and has a generic driver.
- *
- * Drivers for devices that don't have a generic driver will never
- * ask for this, so let's assume that a real driver for the display
- * was already probed and prevent sysfb to register devices later.
- */
- sysfb_disable();
-
- mutex_lock(&registration_lock);
- do_remove_conflicting_framebuffers(a, name, primary);
- mutex_unlock(&registration_lock);
-
- if (do_free)
- kfree(a);
-
- return 0;
-}
-EXPORT_SYMBOL(remove_conflicting_framebuffers);
+ struct apertures_struct *ap = fb_info->apertures;
+ struct device *dev = fb_info->device;
+ struct platform_device *pdev;
+ unsigned int i;
+ int ret;
-/**
- * remove_conflicting_pci_framebuffers - remove firmware-configured framebuffers for PCI devices
- * @pdev: PCI device
- * @name: requesting driver name
- *
- * This function removes framebuffer devices (eg. initialized by firmware)
- * using memory range configured for any of @pdev's memory bars.
- *
- * The function assumes that PCI device with shadowed ROM drives a primary
- * display and so kicks out vga16fb.
- */
-int remove_conflicting_pci_framebuffers(struct pci_dev *pdev, const char *name)
-{
- struct apertures_struct *ap;
- bool primary = false;
- int err, idx, bar;
+ if (!ap)
+ return 0;
- for (idx = 0, bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
- if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM))
- continue;
- idx++;
- }
+ if (!dev_is_platform(dev))
+ return 0;
- ap = alloc_apertures(idx);
- if (!ap)
- return -ENOMEM;
+ pdev = to_platform_device(dev);
- for (idx = 0, bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
- if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM))
- continue;
- ap->ranges[idx].base = pci_resource_start(pdev, bar);
- ap->ranges[idx].size = pci_resource_len(pdev, bar);
- pci_dbg(pdev, "%s: bar %d: 0x%lx -> 0x%lx\n", __func__, bar,
- (unsigned long)pci_resource_start(pdev, bar),
- (unsigned long)pci_resource_end(pdev, bar));
- idx++;
+ for (ret = 0, i = 0; i < ap->count; ++i) {
+ ret = devm_aperture_acquire_for_platform_device(pdev, ap->ranges[i].base,
+ ap->ranges[i].size);
+ if (ret)
+ break;
}
-#ifdef CONFIG_X86
- primary = pdev->resource[PCI_ROM_RESOURCE].flags &
- IORESOURCE_ROM_SHADOW;
-#endif
- err = remove_conflicting_framebuffers(ap, name, primary);
- kfree(ap);
- return err;
+ return ret;
}
-EXPORT_SYMBOL(remove_conflicting_pci_framebuffers);
/**
* register_framebuffer - registers a frame buffer device
@@ -1861,6 +1692,12 @@ register_framebuffer(struct fb_info *fb_info)
{
int ret;
+ if (fb_info->flags & FBINFO_MISC_FIRMWARE) {
+ ret = fb_aperture_acquire_for_platform_device(fb_info);
+ if (ret)
+ return ret;
+ }
+
mutex_lock(&registration_lock);
ret = do_register_framebuffer(fb_info);
mutex_unlock(&registration_lock);