I merged the both series I sent out recently into one bigger one so that it's more obvious on why all of that is needed. Biggest changes since last sent: * reworked the ASPM patch * removed "pci: add nvkm_pcie_get_speed" patch Please test this on Laptops and report back if it either breaks something or doesn't fix runpm. Thanks Karol Herbst (6): pci: disable ASPM before changing the link speed pci/gk104: enable dl_mgr safe mode pci/gk104: wait for ltssm idle before changing the link pci: enable pcie link changes for pascal pci: set the pcie link speed to 8.0 when suspending drm: abort runtime suspend if we hit an error drm/nouveau/include/nvkm/core/device.h | 2 ++ drm/nouveau/include/nvkm/subdev/pci.h | 3 +- drm/nouveau/nouveau_drm.c | 6 ++++ drm/nouveau/nvkm/subdev/clk/base.c | 2 +- drm/nouveau/nvkm/subdev/pci/base.c | 2 ++ drm/nouveau/nvkm/subdev/pci/g84.c | 8 +++++ drm/nouveau/nvkm/subdev/pci/g92.c | 1 + drm/nouveau/nvkm/subdev/pci/g94.c | 1 + drm/nouveau/nvkm/subdev/pci/gf100.c | 1 + drm/nouveau/nvkm/subdev/pci/gf106.c | 1 + drm/nouveau/nvkm/subdev/pci/gk104.c | 29 +++++++++++++----- drm/nouveau/nvkm/subdev/pci/gp100.c | 11 +++++++ drm/nouveau/nvkm/subdev/pci/pcie.c | 42 +++++++++++++++++++++++--- drm/nouveau/nvkm/subdev/pci/priv.h | 16 ++++++++++ 14 files changed, 112 insertions(+), 13 deletions(-) -- 2.21.0
Karol Herbst
2019-Sep-17 21:00 UTC
[Nouveau] [PATCH 1/6] pci: disable ASPM before changing the link speed
taken from nvgpu v2: rename force_aspm_off to aspm_off rework interface to return old value and take a mask as the input Signed-off-by: Karol Herbst <kherbst at redhat.com> --- drm/nouveau/nvkm/subdev/pci/g84.c | 8 ++++++++ drm/nouveau/nvkm/subdev/pci/g92.c | 1 + drm/nouveau/nvkm/subdev/pci/g94.c | 1 + drm/nouveau/nvkm/subdev/pci/gf100.c | 1 + drm/nouveau/nvkm/subdev/pci/gf106.c | 1 + drm/nouveau/nvkm/subdev/pci/gk104.c | 1 + drm/nouveau/nvkm/subdev/pci/pcie.c | 15 +++++++++++++++ drm/nouveau/nvkm/subdev/pci/priv.h | 10 ++++++++++ 8 files changed, 38 insertions(+) diff --git a/drm/nouveau/nvkm/subdev/pci/g84.c b/drm/nouveau/nvkm/subdev/pci/g84.c index 62438d892..6cf0f1c89 100644 --- a/drm/nouveau/nvkm/subdev/pci/g84.c +++ b/drm/nouveau/nvkm/subdev/pci/g84.c @@ -122,6 +122,13 @@ g84_pci_init(struct nvkm_pci *pci) nvkm_pci_mask(pci, 0x041c, 0x00000060, 0x00000000); } +enum nvkm_pci_aspm +g84_pcie_aspm_off(struct nvkm_pci *pci, enum nvkm_pci_aspm states) +{ + u32 value = states << 7; + return (nvkm_pci_mask(pci, 0x150, 0x180, value) & 0x180) >> 7; +} + int g84_pcie_init(struct nvkm_pci *pci) { @@ -147,6 +154,7 @@ g84_pci_func = { .pcie.set_version = g84_pcie_set_version, .pcie.version = g84_pcie_version, .pcie.version_supported = g84_pcie_version_supported, + .pcie.aspm_off = g84_pcie_aspm_off, }; int diff --git a/drm/nouveau/nvkm/subdev/pci/g92.c b/drm/nouveau/nvkm/subdev/pci/g92.c index 48874359d..85629ffee 100644 --- a/drm/nouveau/nvkm/subdev/pci/g92.c +++ b/drm/nouveau/nvkm/subdev/pci/g92.c @@ -48,6 +48,7 @@ g92_pci_func = { .pcie.set_version = g84_pcie_set_version, .pcie.version = g84_pcie_version, .pcie.version_supported = g92_pcie_version_supported, + .pcie.aspm_off = g84_pcie_aspm_off, }; int diff --git a/drm/nouveau/nvkm/subdev/pci/g94.c b/drm/nouveau/nvkm/subdev/pci/g94.c index 09adb37a5..588bea4f6 100644 --- a/drm/nouveau/nvkm/subdev/pci/g94.c +++ b/drm/nouveau/nvkm/subdev/pci/g94.c @@ -40,6 +40,7 @@ g94_pci_func = { .pcie.set_version = g84_pcie_set_version, .pcie.version = g84_pcie_version, .pcie.version_supported = g92_pcie_version_supported, + .pcie.aspm_off = g84_pcie_aspm_off, }; int diff --git a/drm/nouveau/nvkm/subdev/pci/gf100.c b/drm/nouveau/nvkm/subdev/pci/gf100.c index 00a5e7d3e..7948942b6 100644 --- a/drm/nouveau/nvkm/subdev/pci/gf100.c +++ b/drm/nouveau/nvkm/subdev/pci/gf100.c @@ -93,6 +93,7 @@ gf100_pci_func = { .pcie.set_version = gf100_pcie_set_version, .pcie.version = gf100_pcie_version, .pcie.version_supported = g92_pcie_version_supported, + .pcie.aspm_off = g84_pcie_aspm_off, }; int diff --git a/drm/nouveau/nvkm/subdev/pci/gf106.c b/drm/nouveau/nvkm/subdev/pci/gf106.c index 11bf419af..c62c66a2e 100644 --- a/drm/nouveau/nvkm/subdev/pci/gf106.c +++ b/drm/nouveau/nvkm/subdev/pci/gf106.c @@ -40,6 +40,7 @@ gf106_pci_func = { .pcie.set_version = gf100_pcie_set_version, .pcie.version = gf100_pcie_version, .pcie.version_supported = g92_pcie_version_supported, + .pcie.aspm_off = g84_pcie_aspm_off, }; int diff --git a/drm/nouveau/nvkm/subdev/pci/gk104.c b/drm/nouveau/nvkm/subdev/pci/gk104.c index e68030507..a4014d4a7 100644 --- a/drm/nouveau/nvkm/subdev/pci/gk104.c +++ b/drm/nouveau/nvkm/subdev/pci/gk104.c @@ -219,6 +219,7 @@ gk104_pci_func = { .pcie.set_version = gf100_pcie_set_version, .pcie.version = gf100_pcie_version, .pcie.version_supported = gk104_pcie_version_supported, + .pcie.aspm_off = g84_pcie_aspm_off, }; int diff --git a/drm/nouveau/nvkm/subdev/pci/pcie.c b/drm/nouveau/nvkm/subdev/pci/pcie.c index d71e5db50..ed015b252 100644 --- a/drm/nouveau/nvkm/subdev/pci/pcie.c +++ b/drm/nouveau/nvkm/subdev/pci/pcie.c @@ -111,12 +111,21 @@ nvkm_pcie_init(struct nvkm_pci *pci) return 0; } +enum nvkm_pci_aspm +nvkm_pcie_aspm_off(struct nvkm_pci *pci, enum nvkm_pci_aspm states) +{ + if (!pci->func->pcie.aspm_off) + return NVKM_PCI_ASPM_NONE; + return pci->func->pcie.aspm_off(pci, states); +} + int nvkm_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width) { struct nvkm_subdev *subdev = &pci->subdev; enum nvkm_pcie_speed cur_speed, max_speed; struct pci_bus *pbus; + enum nvkm_pci_aspm old_aspm_state; int ret; if (!pci || !pci_is_pcie(pci->pdev)) @@ -157,9 +166,15 @@ nvkm_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width) nvkm_debug(subdev, "set link to %s x%i\n", nvkm_pcie_speeds[speed], width); + /* disable ASPM */ + old_aspm_state = nvkm_pcie_aspm_off(pci, NVKM_PCI_ASPM_L0S_L1); + ret = pci->func->pcie.set_link(pci, speed, width); if (ret < 0) nvkm_error(subdev, "setting link failed: %i\n", ret); + /* restore old ASPM state */ + nvkm_pcie_aspm_off(pci, old_aspm_state); + return ret; } diff --git a/drm/nouveau/nvkm/subdev/pci/priv.h b/drm/nouveau/nvkm/subdev/pci/priv.h index 7009aad86..8518ff056 100644 --- a/drm/nouveau/nvkm/subdev/pci/priv.h +++ b/drm/nouveau/nvkm/subdev/pci/priv.h @@ -7,6 +7,13 @@ int nvkm_pci_new_(const struct nvkm_pci_func *, struct nvkm_device *, int index, struct nvkm_pci **); +enum nvkm_pci_aspm { + NVKM_PCI_ASPM_NONE = 0, + NVKM_PCI_ASPM_L0S = 1, + NVKM_PCI_ASPM_L1 = 2, + NVKM_PCI_ASPM_L0S_L1 = 3, +}; + struct nvkm_pci_func { void (*init)(struct nvkm_pci *); u32 (*rd32)(struct nvkm_pci *, u16 addr); @@ -24,6 +31,8 @@ struct nvkm_pci_func { void (*set_version)(struct nvkm_pci *, u8); int (*version)(struct nvkm_pci *); int (*version_supported)(struct nvkm_pci *); + enum nvkm_pci_aspm (*aspm_off)(struct nvkm_pci *, + enum nvkm_pci_aspm); } pcie; }; @@ -42,6 +51,7 @@ int g84_pcie_version(struct nvkm_pci *); void g84_pcie_set_link_speed(struct nvkm_pci *, enum nvkm_pcie_speed); enum nvkm_pcie_speed g84_pcie_cur_speed(struct nvkm_pci *); enum nvkm_pcie_speed g84_pcie_max_speed(struct nvkm_pci *); +enum nvkm_pci_aspm g84_pcie_aspm_off(struct nvkm_pci *, enum nvkm_pci_aspm); int g84_pcie_init(struct nvkm_pci *); int g84_pcie_set_link(struct nvkm_pci *, enum nvkm_pcie_speed, u8); -- 2.21.0
Karol Herbst
2019-Sep-17 21:00 UTC
[Nouveau] [PATCH 2/6] pci/gk104: enable dl_mgr safe mode
no idea why and what it does, taken from nvgpu Signed-off-by: Karol Herbst <kherbst at redhat.com> --- drm/nouveau/nvkm/subdev/pci/gk104.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drm/nouveau/nvkm/subdev/pci/gk104.c b/drm/nouveau/nvkm/subdev/pci/gk104.c index a4014d4a7..1c4f9a1cd 100644 --- a/drm/nouveau/nvkm/subdev/pci/gk104.c +++ b/drm/nouveau/nvkm/subdev/pci/gk104.c @@ -184,6 +184,7 @@ gk104_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width) struct nvkm_subdev *subdev = &pci->subdev; enum nvkm_pcie_speed lnk_ctl_speed = gk104_pcie_lnkctl_speed(pci); enum nvkm_pcie_speed lnk_cap_speed = gk104_pcie_cap_speed(pci); + u32 old_dl_mgr; if (speed > lnk_cap_speed) { speed = lnk_cap_speed; @@ -197,7 +198,9 @@ gk104_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width) " lnkctl speed\n"); } + old_dl_mgr = nvkm_mask(subdev->device, 0x8b8c0, 0x4, 0x4); gk104_pcie_set_link_speed(pci, speed); + nvkm_wr32(subdev->device, 0x8b8c0, old_dl_mgr); return 0; } -- 2.21.0
Karol Herbst
2019-Sep-17 21:00 UTC
[Nouveau] [PATCH 3/6] pci/gk104: wait for ltssm idle before changing the link
taken from nvgpu v2: return -EBUSY when the timeout is reached Signed-off-by: Karol Herbst <kherbst at redhat.com> --- drm/nouveau/nvkm/subdev/pci/gk104.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drm/nouveau/nvkm/subdev/pci/gk104.c b/drm/nouveau/nvkm/subdev/pci/gk104.c index 1c4f9a1cd..dda113a45 100644 --- a/drm/nouveau/nvkm/subdev/pci/gk104.c +++ b/drm/nouveau/nvkm/subdev/pci/gk104.c @@ -23,6 +23,8 @@ */ #include "priv.h" +#include <subdev/timer.h> + static int gk104_pcie_version_supported(struct nvkm_pci *pci) { @@ -123,7 +125,7 @@ gk104_pcie_max_speed(struct nvkm_pci *pci) return NVKM_PCIE_SPEED_2_5; } -static void +static int gk104_pcie_set_link_speed(struct nvkm_pci *pci, enum nvkm_pcie_speed speed) { struct nvkm_device *device = pci->subdev.device; @@ -142,8 +144,16 @@ gk104_pcie_set_link_speed(struct nvkm_pci *pci, enum nvkm_pcie_speed speed) break; } + /* wait for ltssm idle */ + if (nvkm_msec(device, 200, + if ((nvkm_rd32(device, 0x8c040) & 0x1f) == 0) + break; + ) < 0) { + return -EBUSY; + } nvkm_mask(device, 0x8c040, 0xc0000, mask_value); nvkm_mask(device, 0x8c040, 0x1, 0x1); + return 0; } static int @@ -185,6 +195,7 @@ gk104_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width) enum nvkm_pcie_speed lnk_ctl_speed = gk104_pcie_lnkctl_speed(pci); enum nvkm_pcie_speed lnk_cap_speed = gk104_pcie_cap_speed(pci); u32 old_dl_mgr; + int ret; if (speed > lnk_cap_speed) { speed = lnk_cap_speed; @@ -199,9 +210,9 @@ gk104_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width) } old_dl_mgr = nvkm_mask(subdev->device, 0x8b8c0, 0x4, 0x4); - gk104_pcie_set_link_speed(pci, speed); + ret = gk104_pcie_set_link_speed(pci, speed); nvkm_wr32(subdev->device, 0x8b8c0, old_dl_mgr); - return 0; + return ret; } -- 2.21.0
Karol Herbst
2019-Sep-17 21:00 UTC
[Nouveau] [PATCH 4/6] pci: enable pcie link changes for pascal
v2: add force disable ASPM func pointer Signed-off-by: Karol Herbst <kherbst at redhat.com> Reviewed-by: Lyude Paul <lyude at redhat.com> --- drm/nouveau/nvkm/subdev/pci/gk104.c | 8 ++++---- drm/nouveau/nvkm/subdev/pci/gp100.c | 11 +++++++++++ drm/nouveau/nvkm/subdev/pci/priv.h | 5 +++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/drm/nouveau/nvkm/subdev/pci/gk104.c b/drm/nouveau/nvkm/subdev/pci/gk104.c index dda113a45..d6ba1918e 100644 --- a/drm/nouveau/nvkm/subdev/pci/gk104.c +++ b/drm/nouveau/nvkm/subdev/pci/gk104.c @@ -25,7 +25,7 @@ #include <subdev/timer.h> -static int +int gk104_pcie_version_supported(struct nvkm_pci *pci) { return (nvkm_rd32(pci->subdev.device, 0x8c1c0) & 0x4) == 0x4 ? 2 : 1; @@ -110,7 +110,7 @@ gk104_pcie_lnkctl_speed(struct nvkm_pci *pci) return -1; } -static enum nvkm_pcie_speed +enum nvkm_pcie_speed gk104_pcie_max_speed(struct nvkm_pci *pci) { u32 max_speed = nvkm_rd32(pci->subdev.device, 0x8c1c0) & 0x300000; @@ -156,7 +156,7 @@ gk104_pcie_set_link_speed(struct nvkm_pci *pci, enum nvkm_pcie_speed speed) return 0; } -static int +int gk104_pcie_init(struct nvkm_pci * pci) { enum nvkm_pcie_speed lnkctl_speed, max_speed, cap_speed; @@ -188,7 +188,7 @@ gk104_pcie_init(struct nvkm_pci * pci) return 0; } -static int +int gk104_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width) { struct nvkm_subdev *subdev = &pci->subdev; diff --git a/drm/nouveau/nvkm/subdev/pci/gp100.c b/drm/nouveau/nvkm/subdev/pci/gp100.c index 82c5234a0..c102109d9 100644 --- a/drm/nouveau/nvkm/subdev/pci/gp100.c +++ b/drm/nouveau/nvkm/subdev/pci/gp100.c @@ -35,6 +35,17 @@ gp100_pci_func = { .wr08 = nv40_pci_wr08, .wr32 = nv40_pci_wr32, .msi_rearm = gp100_pci_msi_rearm, + + .pcie.init = gk104_pcie_init, + .pcie.set_link = gk104_pcie_set_link, + + .pcie.max_speed = gk104_pcie_max_speed, + .pcie.cur_speed = g84_pcie_cur_speed, + + .pcie.set_version = gf100_pcie_set_version, + .pcie.version = gf100_pcie_version, + .pcie.version_supported = gk104_pcie_version_supported, + .pcie.aspm_off = g84_pcie_aspm_off, }; int diff --git a/drm/nouveau/nvkm/subdev/pci/priv.h b/drm/nouveau/nvkm/subdev/pci/priv.h index 8518ff056..17be1d563 100644 --- a/drm/nouveau/nvkm/subdev/pci/priv.h +++ b/drm/nouveau/nvkm/subdev/pci/priv.h @@ -64,6 +64,11 @@ int gf100_pcie_cap_speed(struct nvkm_pci *); int gf100_pcie_init(struct nvkm_pci *); int gf100_pcie_set_link(struct nvkm_pci *, enum nvkm_pcie_speed, u8); +int gk104_pcie_init(struct nvkm_pci *); +int gk104_pcie_set_link(struct nvkm_pci *, enum nvkm_pcie_speed, u8 width); +enum nvkm_pcie_speed gk104_pcie_max_speed(struct nvkm_pci *); +int gk104_pcie_version_supported(struct nvkm_pci *); + int nvkm_pcie_oneinit(struct nvkm_pci *); int nvkm_pcie_init(struct nvkm_pci *); #endif -- 2.21.0
Karol Herbst
2019-Sep-17 21:00 UTC
[Nouveau] [PATCH 5/6] pci: set the pcie link speed to 8.0 when suspending
Apperantly things go south if we suspend the device with a PCIe link speed set to 2.5. Fixes runtime suspend on my gp107. This all looks like some bug inside the pci subsystem and I would prefer a fix there instead of nouveau, but maybe there is no real nice way of doing that outside of drivers? v2: squashed together patch 4 and 5 v3: only restore pcie speed on machines with runpm add NvRunpmWorkaround config option to disable the workaround v4: only run the code on suspend always put the card into 8.0 mode, not what nouveau detected on load Signed-off-by: Karol Herbst <kherbst at redhat.com> Reviewed-by: Lyude Paul <lyude at redhat.com> --- drm/nouveau/include/nvkm/core/device.h | 2 ++ drm/nouveau/include/nvkm/subdev/pci.h | 3 ++- drm/nouveau/nouveau_drm.c | 1 + drm/nouveau/nvkm/subdev/clk/base.c | 2 +- drm/nouveau/nvkm/subdev/pci/base.c | 2 ++ drm/nouveau/nvkm/subdev/pci/pcie.c | 27 ++++++++++++++++++++++---- drm/nouveau/nvkm/subdev/pci/priv.h | 1 + 7 files changed, 32 insertions(+), 6 deletions(-) diff --git a/drm/nouveau/include/nvkm/core/device.h b/drm/nouveau/include/nvkm/core/device.h index 6d55cd047..4fb3f972f 100644 --- a/drm/nouveau/include/nvkm/core/device.h +++ b/drm/nouveau/include/nvkm/core/device.h @@ -125,6 +125,8 @@ struct nvkm_device { u8 chiprev; u32 crystal; + bool has_runpm; + struct { struct notifier_block nb; } acpi; diff --git a/drm/nouveau/include/nvkm/subdev/pci.h b/drm/nouveau/include/nvkm/subdev/pci.h index 4803a4fad..10d361e56 100644 --- a/drm/nouveau/include/nvkm/subdev/pci.h +++ b/drm/nouveau/include/nvkm/subdev/pci.h @@ -52,5 +52,6 @@ int gk104_pci_new(struct nvkm_device *, int, struct nvkm_pci **); int gp100_pci_new(struct nvkm_device *, int, struct nvkm_pci **); /* pcie functions */ -int nvkm_pcie_set_link(struct nvkm_pci *, enum nvkm_pcie_speed, u8 width); +int nvkm_pcie_set_link(struct nvkm_pci *, enum nvkm_pcie_speed, u8 width, + bool save); #endif diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c index 3d32afe8a..78d55c525 100644 --- a/drm/nouveau/nouveau_drm.c +++ b/drm/nouveau/nouveau_drm.c @@ -676,6 +676,7 @@ static int nouveau_drm_probe(struct pci_dev *pdev, if (nouveau_atomic) driver_pci.driver_features |= DRIVER_ATOMIC; + device->has_runpm = nouveau_pmops_runtime(); drm_dev = drm_dev_alloc(&driver_pci, &pdev->dev); if (IS_ERR(drm_dev)) { diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c index ba6a868d4..e30e77453 100644 --- a/drm/nouveau/nvkm/subdev/clk/base.c +++ b/drm/nouveau/nvkm/subdev/clk/base.c @@ -277,7 +277,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei) nvkm_debug(subdev, "setting performance state %d\n", pstatei); clk->pstate = pstatei; - nvkm_pcie_set_link(pci, pstate->pcie_speed, pstate->pcie_width); + nvkm_pcie_set_link(pci, pstate->pcie_speed, pstate->pcie_width, true); if (fb && fb->ram && fb->ram->func->calc) { struct nvkm_ram *ram = fb->ram; diff --git a/drm/nouveau/nvkm/subdev/pci/base.c b/drm/nouveau/nvkm/subdev/pci/base.c index ee2431a78..c9b60ef76 100644 --- a/drm/nouveau/nvkm/subdev/pci/base.c +++ b/drm/nouveau/nvkm/subdev/pci/base.c @@ -90,6 +90,8 @@ nvkm_pci_fini(struct nvkm_subdev *subdev, bool suspend) if (pci->agp.bridge) nvkm_agp_fini(pci); + else if (pci_is_pcie(pci->pdev)) + nvkm_pcie_fini(pci, suspend); return 0; } diff --git a/drm/nouveau/nvkm/subdev/pci/pcie.c b/drm/nouveau/nvkm/subdev/pci/pcie.c index ed015b252..6c290b3f5 100644 --- a/drm/nouveau/nvkm/subdev/pci/pcie.c +++ b/drm/nouveau/nvkm/subdev/pci/pcie.c @@ -23,6 +23,8 @@ */ #include "priv.h" +#include <core/option.h> + static char *nvkm_pcie_speeds[] = { "2.5GT/s", "5.0GT/s", @@ -106,11 +108,25 @@ nvkm_pcie_init(struct nvkm_pci *pci) pci->func->pcie.init(pci); if (pci->pcie.speed != -1) - nvkm_pcie_set_link(pci, pci->pcie.speed, pci->pcie.width); + nvkm_pcie_set_link(pci, pci->pcie.speed, + pci->pcie.width, false); return 0; } +int +nvkm_pcie_fini(struct nvkm_pci *pci, bool suspend) +{ + struct nvkm_device *device = pci->subdev.device; + if (!device->has_runpm || !suspend) + return 0; + + if (!nvkm_boolopt(device->cfgopt, "NvRunpmWorkaround", true)) + return 0; + + return nvkm_pcie_set_link(pci, NVKM_PCIE_SPEED_8_0, 16, false); +} + enum nvkm_pci_aspm nvkm_pcie_aspm_off(struct nvkm_pci *pci, enum nvkm_pci_aspm states) { @@ -120,7 +136,8 @@ nvkm_pcie_aspm_off(struct nvkm_pci *pci, enum nvkm_pci_aspm states) } int -nvkm_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width) +nvkm_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width, + bool save) { struct nvkm_subdev *subdev = &pci->subdev; enum nvkm_pcie_speed cur_speed, max_speed; @@ -155,8 +172,10 @@ nvkm_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width) speed = max_speed; } - pci->pcie.speed = speed; - pci->pcie.width = width; + if (save) { + pci->pcie.speed = speed; + pci->pcie.width = width; + } if (speed == cur_speed) { nvkm_debug(subdev, "requested matches current speed\n"); diff --git a/drm/nouveau/nvkm/subdev/pci/priv.h b/drm/nouveau/nvkm/subdev/pci/priv.h index 17be1d563..d9a32b41e 100644 --- a/drm/nouveau/nvkm/subdev/pci/priv.h +++ b/drm/nouveau/nvkm/subdev/pci/priv.h @@ -71,4 +71,5 @@ int gk104_pcie_version_supported(struct nvkm_pci *); int nvkm_pcie_oneinit(struct nvkm_pci *); int nvkm_pcie_init(struct nvkm_pci *); +int nvkm_pcie_fini(struct nvkm_pci *, bool suspend); #endif -- 2.21.0
Karol Herbst
2019-Sep-17 21:00 UTC
[Nouveau] [PATCH 6/6] drm: abort runtime suspend if we hit an error
Signed-off-by: Karol Herbst <kherbst at redhat.com> --- drm/nouveau/nouveau_drm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c index 78d55c525..6a6819d96 100644 --- a/drm/nouveau/nouveau_drm.c +++ b/drm/nouveau/nouveau_drm.c @@ -911,6 +911,7 @@ nouveau_pmops_runtime_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); + struct nouveau_drm *drm = nouveau_drm(drm_dev); int ret; if (!nouveau_pmops_runtime()) { @@ -920,6 +921,10 @@ nouveau_pmops_runtime_suspend(struct device *dev) nouveau_switcheroo_optimus_dsm(); ret = nouveau_do_suspend(drm_dev, true); + if (ret) { + NV_ERROR(drm, "suspend failed with: %d\n", ret); + return ret; + } pci_save_state(pdev); pci_disable_device(pdev); pci_ignore_hotplug(pdev); -- 2.21.0