[Nouveau] [PATCH 3/8] pci/gk104: wait for ltssm idle before changing the link
Karol Herbst
kherbst at redhat.com
Mon Sep 23 20:39:46 UTC 2019
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
More information about the Nouveau
mailing list