Skip to content

Commit 7a6043c

Browse files
committed
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
2 parents ddec8ed + 936a937 commit 7a6043c

File tree

6 files changed

+90
-1
lines changed

6 files changed

+90
-1
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,7 @@ struct amdgpu_device {
10771077
bool runpm;
10781078
bool in_runpm;
10791079
bool has_pr3;
1080+
bool is_fw_fb;
10801081

10811082
bool pm_sysfs_en;
10821083
bool ucode_sysfs_en;

drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <linux/mmu_notifier.h>
4040
#include <linux/suspend.h>
4141
#include <linux/cc_platform.h>
42+
#include <linux/fb.h>
4243

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

18911892
static const struct drm_driver amdgpu_kms_driver;
18921893

1894+
static bool amdgpu_is_fw_framebuffer(resource_size_t base,
1895+
resource_size_t size)
1896+
{
1897+
bool found = false;
1898+
#if IS_REACHABLE(CONFIG_FB)
1899+
struct apertures_struct *a;
1900+
1901+
a = alloc_apertures(1);
1902+
if (!a)
1903+
return false;
1904+
1905+
a->ranges[0].base = base;
1906+
a->ranges[0].size = size;
1907+
1908+
found = is_firmware_framebuffer(a);
1909+
kfree(a);
1910+
#endif
1911+
return found;
1912+
}
1913+
18931914
static int amdgpu_pci_probe(struct pci_dev *pdev,
18941915
const struct pci_device_id *ent)
18951916
{
@@ -1898,6 +1919,8 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
18981919
unsigned long flags = ent->driver_data;
18991920
int ret, retry = 0, i;
19001921
bool supports_atomic = false;
1922+
bool is_fw_fb;
1923+
resource_size_t base, size;
19011924

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

1992+
base = pci_resource_start(pdev, 0);
1993+
size = pci_resource_len(pdev, 0);
1994+
is_fw_fb = amdgpu_is_fw_framebuffer(base, size);
1995+
19691996
/* Get rid of things like offb */
19701997
ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &amdgpu_kms_driver);
19711998
if (ret)
@@ -1978,6 +2005,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
19782005
adev->dev = &pdev->dev;
19792006
adev->pdev = pdev;
19802007
ddev = adev_to_drm(adev);
2008+
adev->is_fw_fb = is_fw_fb;
19812009

19822010
if (!supports_atomic)
19832011
ddev->driver_features &= ~DRIVER_ATOMIC;

drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,12 @@ int amdgpu_driver_load_kms(struct amdgpu_device *adev, unsigned long flags)
206206
adev->runpm = true;
207207
break;
208208
}
209+
/* XXX: disable runtime pm if we are the primary adapter
210+
* to avoid displays being re-enabled after DPMS.
211+
* This needs to be sorted out and fixed properly.
212+
*/
213+
if (adev->is_fw_fb)
214+
adev->runpm = false;
209215
if (adev->runpm)
210216
dev_info(adev->dev, "Using BACO for runtime pm\n");
211217
}

drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1400,8 +1400,14 @@ static int smu_disable_dpms(struct smu_context *smu)
14001400
{
14011401
struct amdgpu_device *adev = smu->adev;
14021402
int ret = 0;
1403+
/*
1404+
* TODO: (adev->in_suspend && !adev->in_s0ix) is added to pair
1405+
* the workaround which always reset the asic in suspend.
1406+
* It's likely that workaround will be dropped in the future.
1407+
* Then the change here should be dropped together.
1408+
*/
14031409
bool use_baco = !smu->is_apu &&
1404-
((amdgpu_in_reset(adev) &&
1410+
(((amdgpu_in_reset(adev) || (adev->in_suspend && !adev->in_s0ix)) &&
14051411
(amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)) ||
14061412
((adev->in_runpm || adev->in_s4) && amdgpu_asic_supports_baco(adev)));
14071413

drivers/video/fbdev/core/fbmem.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,6 +1762,53 @@ int remove_conflicting_framebuffers(struct apertures_struct *a,
17621762
}
17631763
EXPORT_SYMBOL(remove_conflicting_framebuffers);
17641764

1765+
/**
1766+
* is_firmware_framebuffer - detect if firmware-configured framebuffer matches
1767+
* @a: memory range, users of which are to be checked
1768+
*
1769+
* This function checks framebuffer devices (initialized by firmware/bootloader)
1770+
* which use memory range described by @a. If @a matchesm the function returns
1771+
* true, otherwise false.
1772+
*/
1773+
bool is_firmware_framebuffer(struct apertures_struct *a)
1774+
{
1775+
bool do_free = false;
1776+
bool found = false;
1777+
int i;
1778+
1779+
if (!a) {
1780+
a = alloc_apertures(1);
1781+
if (!a)
1782+
return false;
1783+
1784+
a->ranges[0].base = 0;
1785+
a->ranges[0].size = ~0;
1786+
do_free = true;
1787+
}
1788+
1789+
mutex_lock(&registration_lock);
1790+
/* check all firmware fbs and kick off if the base addr overlaps */
1791+
for_each_registered_fb(i) {
1792+
struct apertures_struct *gen_aper;
1793+
1794+
if (!(registered_fb[i]->flags & FBINFO_MISC_FIRMWARE))
1795+
continue;
1796+
1797+
gen_aper = registered_fb[i]->apertures;
1798+
if (fb_do_apertures_overlap(gen_aper, a)) {
1799+
found = true;
1800+
break;
1801+
}
1802+
}
1803+
mutex_unlock(&registration_lock);
1804+
1805+
if (do_free)
1806+
kfree(a);
1807+
1808+
return found;
1809+
}
1810+
EXPORT_SYMBOL(is_firmware_framebuffer);
1811+
17651812
/**
17661813
* remove_conflicting_pci_framebuffers - remove firmware-configured framebuffers for PCI devices
17671814
* @pdev: PCI device

include/linux/fb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@ extern int remove_conflicting_pci_framebuffers(struct pci_dev *pdev,
610610
const char *name);
611611
extern int remove_conflicting_framebuffers(struct apertures_struct *a,
612612
const char *name, bool primary);
613+
extern bool is_firmware_framebuffer(struct apertures_struct *a);
613614
extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
614615
extern int fb_show_logo(struct fb_info *fb_info, int rotate);
615616
extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);

0 commit comments

Comments
 (0)