Merge tag 'amd-drm-fixes-5.16-2021-12-31' of ssh://gitlab.freedesktop.org/agd5f/linux into drm-fixes
amd-drm-fixes-5.16-2021-12-31: amdgpu: - Suspend/resume fix - Restore runtime pm behavior with efifb Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20211231143825.11479-1-alexander.deucher@amd.com
This commit is contained in:
Коммит
936a93775b
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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)));
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче