@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
}
@@ -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);
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@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(+)