Commit 7a6043cc authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'drm-fixes-2022-01-07' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes from Dave Airlie:
 "There is only the amdgpu runtime pm regression fix in here:

  amdgpu:

   - suspend/resume fix

   - fix runtime PM regression"

* tag 'drm-fixes-2022-01-07' of git://anongit.freedesktop.org/drm/drm:
  drm/amdgpu: disable runpm if we are the primary adapter
  fbdev: fbmem: add a helper to determine if an aperture is used by a fw fb
  drm/amd/pm: keep the BACO feature enabled for suspend
parents ddec8ed2 936a9377
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1077,6 +1077,7 @@ struct amdgpu_device {
	bool                            runpm;
	bool                            in_runpm;
	bool                            has_pr3;
	bool                            is_fw_fb;

	bool                            pm_sysfs_en;
	bool                            ucode_sysfs_en;
+28 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#include <linux/mmu_notifier.h>
#include <linux/suspend.h>
#include <linux/cc_platform.h>
#include <linux/fb.h>

#include "amdgpu.h"
#include "amdgpu_irq.h"
@@ -1890,6 +1891,26 @@ MODULE_DEVICE_TABLE(pci, pciidlist);

static const struct drm_driver amdgpu_kms_driver;

static bool amdgpu_is_fw_framebuffer(resource_size_t base,
				     resource_size_t size)
{
	bool found = false;
#if IS_REACHABLE(CONFIG_FB)
	struct apertures_struct *a;

	a = alloc_apertures(1);
	if (!a)
		return false;

	a->ranges[0].base = base;
	a->ranges[0].size = size;

	found = is_firmware_framebuffer(a);
	kfree(a);
#endif
	return found;
}

static int amdgpu_pci_probe(struct pci_dev *pdev,
			    const struct pci_device_id *ent)
{
@@ -1898,6 +1919,8 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
	unsigned long flags = ent->driver_data;
	int ret, retry = 0, i;
	bool supports_atomic = false;
	bool is_fw_fb;
	resource_size_t base, size;

	/* skip devices which are owned by radeon */
	for (i = 0; i < ARRAY_SIZE(amdgpu_unsupported_pciidlist); i++) {
@@ -1966,6 +1989,10 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
	}
#endif

	base = pci_resource_start(pdev, 0);
	size = pci_resource_len(pdev, 0);
	is_fw_fb = amdgpu_is_fw_framebuffer(base, size);

	/* Get rid of things like offb */
	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &amdgpu_kms_driver);
	if (ret)
@@ -1978,6 +2005,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
	adev->dev  = &pdev->dev;
	adev->pdev = pdev;
	ddev = adev_to_drm(adev);
	adev->is_fw_fb = is_fw_fb;

	if (!supports_atomic)
		ddev->driver_features &= ~DRIVER_ATOMIC;
+6 −0
Original line number Diff line number Diff line
@@ -206,6 +206,12 @@ int amdgpu_driver_load_kms(struct amdgpu_device *adev, unsigned long flags)
			adev->runpm = true;
			break;
		}
		/* XXX: disable runtime pm if we are the primary adapter
		 * to avoid displays being re-enabled after DPMS.
		 * This needs to be sorted out and fixed properly.
		 */
		if (adev->is_fw_fb)
			adev->runpm = false;
		if (adev->runpm)
			dev_info(adev->dev, "Using BACO for runtime pm\n");
	}
+7 −1
Original line number Diff line number Diff line
@@ -1400,8 +1400,14 @@ static int smu_disable_dpms(struct smu_context *smu)
{
	struct amdgpu_device *adev = smu->adev;
	int ret = 0;
	/*
	 * TODO: (adev->in_suspend && !adev->in_s0ix) is added to pair
	 * the workaround which always reset the asic in suspend.
	 * It's likely that workaround will be dropped in the future.
	 * Then the change here should be dropped together.
	 */
	bool use_baco = !smu->is_apu &&
		((amdgpu_in_reset(adev) &&
		(((amdgpu_in_reset(adev) || (adev->in_suspend && !adev->in_s0ix)) &&
		  (amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)) ||
		 ((adev->in_runpm || adev->in_s4) && amdgpu_asic_supports_baco(adev)));

+47 −0
Original line number Diff line number Diff line
@@ -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
Loading