* [PATCH v2 0/9] PCIEs speed change
@ 2015-10-13 9:44 Karol Herbst
[not found] ` <1444729463-1560-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
0 siblings, 1 reply; 13+ messages in thread
From: Karol Herbst @ 2015-10-13 9:44 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
overall the same as the old stuff, but with better namings and tirivialy
improved code here and there
Karol Herbst (9):
pci: add gk104 variant
pci: add gf106 variant
pci: implement generic code for PCIe speed change
pci: implement pcie speed change for tesla
pci: implement pcie speed change on Fermi
pci: implement PCIe speed change for kepler+
bios/perf: parse the pci speed from the bios for tesla and newer cards
perf: add fields for pci speed and width and use it for the pstates
perf: change pcie speed on pstate change
drm/nouveau/include/nvkm/subdev/bios/perf.h | 2 +
drm/nouveau/include/nvkm/subdev/clk.h | 3 +
drm/nouveau/include/nvkm/subdev/pci.h | 16 ++
drm/nouveau/nvkm/engine/device/base.c | 30 ++--
drm/nouveau/nvkm/subdev/bios/perf.c | 16 ++
drm/nouveau/nvkm/subdev/clk/base.c | 6 +
drm/nouveau/nvkm/subdev/pci/Kbuild | 3 +
drm/nouveau/nvkm/subdev/pci/base.c | 5 +
drm/nouveau/nvkm/subdev/pci/g84.c | 105 ++++++++++++
drm/nouveau/nvkm/subdev/pci/g94.c | 10 ++
drm/nouveau/nvkm/subdev/pci/gf100.c | 64 ++++++++
drm/nouveau/nvkm/subdev/pci/gf106.c | 48 ++++++
drm/nouveau/nvkm/subdev/pci/gk104.c | 239 ++++++++++++++++++++++++++++
drm/nouveau/nvkm/subdev/pci/pcie.c | 165 +++++++++++++++++++
drm/nouveau/nvkm/subdev/pci/priv.h | 31 ++++
15 files changed, 728 insertions(+), 15 deletions(-)
create mode 100644 drm/nouveau/nvkm/subdev/pci/gf106.c
create mode 100644 drm/nouveau/nvkm/subdev/pci/gk104.c
create mode 100644 drm/nouveau/nvkm/subdev/pci/pcie.c
--
2.6.1
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 1/9] pci: add gk104 variant
[not found] ` <1444729463-1560-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
@ 2015-10-13 9:44 ` Karol Herbst
2015-10-13 9:44 ` [PATCH v2 2/9] pci: add gf106 variant Karol Herbst
` (7 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Karol Herbst @ 2015-10-13 9:44 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
v2: change email used in header
Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
drm/nouveau/include/nvkm/subdev/pci.h | 1 +
drm/nouveau/nvkm/engine/device/base.c | 20 +++++++++---------
drm/nouveau/nvkm/subdev/pci/Kbuild | 1 +
drm/nouveau/nvkm/subdev/pci/gk104.c | 38 +++++++++++++++++++++++++++++++++++
4 files changed, 50 insertions(+), 10 deletions(-)
create mode 100644 drm/nouveau/nvkm/subdev/pci/gk104.c
diff --git a/drm/nouveau/include/nvkm/subdev/pci.h b/drm/nouveau/include/nvkm/subdev/pci.h
index fee0a97..1cf5f72 100644
--- a/drm/nouveau/include/nvkm/subdev/pci.h
+++ b/drm/nouveau/include/nvkm/subdev/pci.h
@@ -34,4 +34,5 @@ int nv4c_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int g84_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int g94_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int gf100_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
+int gk104_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
#endif
diff --git a/drm/nouveau/nvkm/engine/device/base.c b/drm/nouveau/nvkm/engine/device/base.c
index 439c003..9c10c84 100644
--- a/drm/nouveau/nvkm/engine/device/base.c
+++ b/drm/nouveau/nvkm/engine/device/base.c
@@ -1669,7 +1669,7 @@ nve4_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
- .pci = g94_pci_new,
+ .pci = gk104_pci_new,
.pmu = gk104_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
@@ -1706,7 +1706,7 @@ nve6_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
- .pci = g94_pci_new,
+ .pci = gk104_pci_new,
.pmu = gk104_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
@@ -1743,7 +1743,7 @@ nve7_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
- .pci = g94_pci_new,
+ .pci = gk104_pci_new,
.pmu = gk104_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
@@ -1804,7 +1804,7 @@ nvf0_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
- .pci = g94_pci_new,
+ .pci = gk104_pci_new,
.pmu = gk110_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
@@ -1840,7 +1840,7 @@ nvf1_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
- .pci = g94_pci_new,
+ .pci = gk104_pci_new,
.pmu = gk110_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
@@ -1876,7 +1876,7 @@ nv106_chipset = {
.mc = gk20a_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
- .pci = g94_pci_new,
+ .pci = gk104_pci_new,
.pmu = gk208_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
@@ -1912,7 +1912,7 @@ nv108_chipset = {
.mc = gk20a_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
- .pci = g94_pci_new,
+ .pci = gk104_pci_new,
.pmu = gk208_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
@@ -1948,7 +1948,7 @@ nv117_chipset = {
.mc = gk20a_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
- .pci = g94_pci_new,
+ .pci = gk104_pci_new,
.pmu = gm107_pmu_new,
.therm = gm107_therm_new,
.timer = gk20a_timer_new,
@@ -1979,7 +1979,7 @@ nv124_chipset = {
.mc = gk20a_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
- .pci = g94_pci_new,
+ .pci = gk104_pci_new,
.pmu = gm107_pmu_new,
.timer = gk20a_timer_new,
.volt = gk104_volt_new,
@@ -2010,7 +2010,7 @@ nv126_chipset = {
.mc = gk20a_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
- .pci = g94_pci_new,
+ .pci = gk104_pci_new,
.pmu = gm107_pmu_new,
.timer = gk20a_timer_new,
.volt = gk104_volt_new,
diff --git a/drm/nouveau/nvkm/subdev/pci/Kbuild b/drm/nouveau/nvkm/subdev/pci/Kbuild
index 4476ef7..1a29869 100644
--- a/drm/nouveau/nvkm/subdev/pci/Kbuild
+++ b/drm/nouveau/nvkm/subdev/pci/Kbuild
@@ -7,3 +7,4 @@ nvkm-y += nvkm/subdev/pci/nv4c.o
nvkm-y += nvkm/subdev/pci/g84.o
nvkm-y += nvkm/subdev/pci/g94.o
nvkm-y += nvkm/subdev/pci/gf100.o
+nvkm-y += nvkm/subdev/pci/gk104.o
diff --git a/drm/nouveau/nvkm/subdev/pci/gk104.c b/drm/nouveau/nvkm/subdev/pci/gk104.c
new file mode 100644
index 0000000..6119f89
--- /dev/null
+++ b/drm/nouveau/nvkm/subdev/pci/gk104.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2015 Karol Herbst
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Karol Herbst <nouveau@karolherbst.de>
+ */
+#include "priv.h"
+
+static const struct nvkm_pci_func
+gk104_pci_func = {
+ .rd32 = nv40_pci_rd32,
+ .wr08 = nv40_pci_wr08,
+ .wr32 = nv40_pci_wr32,
+ .msi_rearm = nv40_pci_msi_rearm,
+};
+
+int
+gk104_pci_new(struct nvkm_device *device, int index, struct nvkm_pci **ppci)
+{
+ return nvkm_pci_new_(&gk104_pci_func, device, index, ppci);
+}
--
2.6.1
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 2/9] pci: add gf106 variant
[not found] ` <1444729463-1560-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
2015-10-13 9:44 ` [PATCH v2 1/9] pci: add gk104 variant Karol Herbst
@ 2015-10-13 9:44 ` Karol Herbst
2015-10-13 9:44 ` [PATCH v2 3/9] pci: implement generic code for PCIe speed change Karol Herbst
` (6 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Karol Herbst @ 2015-10-13 9:44 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
v2: change email used in header
Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
drm/nouveau/include/nvkm/subdev/pci.h | 1 +
drm/nouveau/nvkm/engine/device/base.c | 10 ++++-----
drm/nouveau/nvkm/subdev/pci/Kbuild | 1 +
drm/nouveau/nvkm/subdev/pci/gf106.c | 38 +++++++++++++++++++++++++++++++++++
4 files changed, 45 insertions(+), 5 deletions(-)
create mode 100644 drm/nouveau/nvkm/subdev/pci/gf106.c
diff --git a/drm/nouveau/include/nvkm/subdev/pci.h b/drm/nouveau/include/nvkm/subdev/pci.h
index 1cf5f72..17fe7b7 100644
--- a/drm/nouveau/include/nvkm/subdev/pci.h
+++ b/drm/nouveau/include/nvkm/subdev/pci.h
@@ -34,5 +34,6 @@ int nv4c_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int g84_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int g94_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int gf100_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
+int gf106_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int gk104_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
#endif
diff --git a/drm/nouveau/nvkm/engine/device/base.c b/drm/nouveau/nvkm/engine/device/base.c
index 9c10c84..653da48 100644
--- a/drm/nouveau/nvkm/engine/device/base.c
+++ b/drm/nouveau/nvkm/engine/device/base.c
@@ -1388,7 +1388,7 @@ nvc1_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
- .pci = g94_pci_new,
+ .pci = gf106_pci_new,
.pmu = gf100_pmu_new,
.therm = gt215_therm_new,
.timer = nv41_timer_new,
@@ -1423,7 +1423,7 @@ nvc3_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
- .pci = g94_pci_new,
+ .pci = gf106_pci_new,
.pmu = gf100_pmu_new,
.therm = gt215_therm_new,
.timer = nv41_timer_new,
@@ -1566,7 +1566,7 @@ nvcf_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
- .pci = g94_pci_new,
+ .pci = gf106_pci_new,
.pmu = gf100_pmu_new,
.therm = gt215_therm_new,
.timer = nv41_timer_new,
@@ -1601,7 +1601,7 @@ nvd7_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
- .pci = g94_pci_new,
+ .pci = gf106_pci_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
.ce[0] = gf100_ce_new,
@@ -1634,7 +1634,7 @@ nvd9_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
- .pci = g94_pci_new,
+ .pci = gf106_pci_new,
.pmu = gf119_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
diff --git a/drm/nouveau/nvkm/subdev/pci/Kbuild b/drm/nouveau/nvkm/subdev/pci/Kbuild
index 1a29869..724afd4 100644
--- a/drm/nouveau/nvkm/subdev/pci/Kbuild
+++ b/drm/nouveau/nvkm/subdev/pci/Kbuild
@@ -7,4 +7,5 @@ nvkm-y += nvkm/subdev/pci/nv4c.o
nvkm-y += nvkm/subdev/pci/g84.o
nvkm-y += nvkm/subdev/pci/g94.o
nvkm-y += nvkm/subdev/pci/gf100.o
+nvkm-y += nvkm/subdev/pci/gf106.o
nvkm-y += nvkm/subdev/pci/gk104.o
diff --git a/drm/nouveau/nvkm/subdev/pci/gf106.c b/drm/nouveau/nvkm/subdev/pci/gf106.c
new file mode 100644
index 0000000..82d8c27
--- /dev/null
+++ b/drm/nouveau/nvkm/subdev/pci/gf106.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2015 Karol Herbst
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Karol Herbst <nouveau@karolherbst.de>
+ */
+#include "priv.h"
+
+static const struct nvkm_pci_func
+gf106_pci_func = {
+ .rd32 = nv40_pci_rd32,
+ .wr08 = nv40_pci_wr08,
+ .wr32 = nv40_pci_wr32,
+ .msi_rearm = nv40_pci_msi_rearm,
+};
+
+int
+gf106_pci_new(struct nvkm_device *device, int index, struct nvkm_pci **ppci)
+{
+ return nvkm_pci_new_(&gf106_pci_func, device, index, ppci);
+}
--
2.6.1
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 3/9] pci: implement generic code for PCIe speed change
[not found] ` <1444729463-1560-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
2015-10-13 9:44 ` [PATCH v2 1/9] pci: add gk104 variant Karol Herbst
2015-10-13 9:44 ` [PATCH v2 2/9] pci: add gf106 variant Karol Herbst
@ 2015-10-13 9:44 ` Karol Herbst
[not found] ` <1444729463-1560-4-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
2015-10-13 9:44 ` [PATCH v2 4/9] pci: implement pcie speed change for tesla Karol Herbst
` (5 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: Karol Herbst @ 2015-10-13 9:44 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
v2: rename and group functions
Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
drm/nouveau/include/nvkm/subdev/pci.h | 14 +++
drm/nouveau/nvkm/subdev/pci/Kbuild | 1 +
drm/nouveau/nvkm/subdev/pci/base.c | 5 ++
drm/nouveau/nvkm/subdev/pci/pcie.c | 165 ++++++++++++++++++++++++++++++++++
drm/nouveau/nvkm/subdev/pci/priv.h | 15 ++++
5 files changed, 200 insertions(+)
create mode 100644 drm/nouveau/nvkm/subdev/pci/pcie.c
diff --git a/drm/nouveau/include/nvkm/subdev/pci.h b/drm/nouveau/include/nvkm/subdev/pci.h
index 17fe7b7..ab9d5cc 100644
--- a/drm/nouveau/include/nvkm/subdev/pci.h
+++ b/drm/nouveau/include/nvkm/subdev/pci.h
@@ -2,6 +2,12 @@
#define __NVKM_PCI_H__
#include <core/subdev.h>
+enum nvkm_pcie_speed {
+ NVKM_PCIE_SPEED_2_5,
+ NVKM_PCIE_SPEED_5_0,
+ NVKM_PCIE_SPEED_8_0,
+};
+
struct nvkm_pci {
const struct nvkm_pci_func *func;
struct nvkm_subdev subdev;
@@ -18,6 +24,11 @@ struct nvkm_pci {
bool acquired;
} agp;
+ struct {
+ enum nvkm_pcie_speed last_speed;
+ u8 last_width;
+ } pcie;
+
bool msi;
};
@@ -36,4 +47,7 @@ int g94_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int gf100_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int gf106_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int gk104_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);
#endif
diff --git a/drm/nouveau/nvkm/subdev/pci/Kbuild b/drm/nouveau/nvkm/subdev/pci/Kbuild
index 724afd4..3c2519f 100644
--- a/drm/nouveau/nvkm/subdev/pci/Kbuild
+++ b/drm/nouveau/nvkm/subdev/pci/Kbuild
@@ -1,5 +1,6 @@
nvkm-y += nvkm/subdev/pci/agp.o
nvkm-y += nvkm/subdev/pci/base.o
+nvkm-y += nvkm/subdev/pci/pcie.o
nvkm-y += nvkm/subdev/pci/nv04.o
nvkm-y += nvkm/subdev/pci/nv40.o
nvkm-y += nvkm/subdev/pci/nv46.o
diff --git a/drm/nouveau/nvkm/subdev/pci/base.c b/drm/nouveau/nvkm/subdev/pci/base.c
index d671dcf..95a8d05 100644
--- a/drm/nouveau/nvkm/subdev/pci/base.c
+++ b/drm/nouveau/nvkm/subdev/pci/base.c
@@ -117,6 +117,9 @@ nvkm_pci_init(struct nvkm_subdev *subdev)
ret = nvkm_agp_init(pci);
if (ret)
return ret;
+ } else {
+ if (pci_is_pcie(pci->pdev))
+ nvkm_pcie_init(pci);
}
if (pci->func->init)
@@ -160,6 +163,8 @@ nvkm_pci_new_(const struct nvkm_pci_func *func, struct nvkm_device *device,
pci->func = func;
pci->pdev = device->func->pci(device)->pdev;
pci->irq = -1;
+ pci->pcie.last_speed = -1;
+ pci->pcie.last_width = -1;
if (device->type == NVKM_DEVICE_AGP)
nvkm_agp_ctor(pci);
diff --git a/drm/nouveau/nvkm/subdev/pci/pcie.c b/drm/nouveau/nvkm/subdev/pci/pcie.c
new file mode 100644
index 0000000..e60d0ba
--- /dev/null
+++ b/drm/nouveau/nvkm/subdev/pci/pcie.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2015 Karol Herbst
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Karol Herbst <git@karolherbst.de>
+ */
+#include "priv.h"
+
+static char *pcie_speed_strings[] = {
+ "2.5GT/s",
+ "5.0GT/s",
+ "8.0GT/s",
+};
+
+static enum nvkm_pcie_speed
+pci_bus_speed_to_nvkm_pcie_speed(enum pci_bus_speed speed)
+{
+ switch (speed) {
+ case PCIE_SPEED_2_5GT:
+ return NVKM_PCIE_SPEED_2_5;
+ case PCIE_SPEED_5_0GT:
+ return NVKM_PCIE_SPEED_5_0;
+ case PCIE_SPEED_8_0GT:
+ return NVKM_PCIE_SPEED_8_0;
+ default:
+ /* XXX 0x16 is 8_0, assume 0x17 will be 16_0 for now */
+ if (speed == 0x17)
+ return NVKM_PCIE_SPEED_8_0;
+ return -1;
+ }
+}
+
+static s8
+nvkm_pci_get_pcie_version(struct nvkm_pci *pci)
+{
+ if (!pci_is_pcie(pci->pdev))
+ return -ENODEV;
+
+ if (!pci->func->pcie.version)
+ return -ENOSYS;
+
+ return pci->func->pcie.version(pci);
+}
+
+static s8
+nvkm_pci_raise_pcie_version(struct nvkm_pci *pci)
+{
+ int ret, supported;
+
+ if (!pci_is_pcie(pci->pdev))
+ return -ENODEV;
+
+ if (!pci->func->pcie.set_version || !pci->func->pcie.version_supported)
+ return -ENOSYS;
+
+ ret = nvkm_pci_get_pcie_version(pci);
+ supported = pci->func->pcie.version_supported(pci);
+ if (ret == 1 && ret < supported) {
+ nvkm_debug(&pci->subdev, "raising version\n");
+ pci->func->pcie.set_version(pci, supported);
+ ret = nvkm_pci_get_pcie_version(pci);
+ }
+ return ret >= supported ? ret : -EINVAL;
+}
+
+int
+nvkm_pcie_init(struct nvkm_pci *pci)
+{
+ struct nvkm_subdev *subdev = &pci->subdev;
+ int ret;
+
+ if (!pci_is_pcie(pci->pdev))
+ return -ENODEV;
+
+ /* raise pcie version first */
+ ret = nvkm_pci_raise_pcie_version(pci);
+ if (ret <= 0)
+ nvkm_error(subdev, "couldn't raise version: %i\n", ret);
+
+ if (pci->func->pcie.init)
+ pci->func->pcie.init(pci);
+
+ nvkm_info(subdev, "pcie version: %i\n", nvkm_pci_get_pcie_version(pci));
+ if (pci->func->pcie.max_speed)
+ nvkm_info(subdev, "pcie max speed: %s\n",
+ pcie_speed_strings[pci->func->pcie.max_speed(pci)]);
+
+ if (pci->pcie.last_speed != -1)
+ nvkm_pcie_set_link(pci, pci->pcie.last_speed, pci->pcie.last_width);
+
+ return 0;
+}
+
+int
+nvkm_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed req_speed,
+ u8 req_width)
+{
+ struct nvkm_subdev *subdev = &pci->subdev;
+ enum nvkm_pcie_speed sys_cur_speed, sys_max_speed;
+ struct pci_bus *pbus = pci->pdev->bus;
+ int ret;
+
+ if (!pci_is_pcie(pci->pdev))
+ return -ENODEV;
+
+ if (!pci->func->pcie.set_link || !pci->func->pcie.version
+ || !pci->func->pcie.max_speed || !pci->func->pcie.cur_speed)
+ return -ENOSYS;
+
+ nvkm_debug(subdev, "pcie speed %s requested\n",
+ pcie_speed_strings[req_speed]);
+
+ if (pci->func->pcie.version(pci) < 2) {
+ nvkm_error(subdev, "can't change link speed, "
+ "because current version too low\n");
+ return -ENODEV;
+ }
+
+ sys_cur_speed = pci->func->pcie.cur_speed(pci);
+ sys_max_speed = min(pci_bus_speed_to_nvkm_pcie_speed(pbus->max_bus_speed),
+ pci->func->pcie.max_speed(pci));
+
+ nvkm_debug(subdev, "bus current speed: %s max speed: %s\n",
+ pcie_speed_strings[sys_cur_speed], pcie_speed_strings[sys_max_speed]);
+
+ if (req_speed > sys_max_speed) {
+ req_speed = sys_max_speed;
+ nvkm_warn(subdev, "bus or card not fast enough, dropping "
+ "requested speed to %s", pcie_speed_strings[req_speed]);
+ }
+
+ pci->pcie.last_speed = req_speed;
+ pci->pcie.last_width = req_width;
+
+ if (req_speed == sys_cur_speed) {
+ nvkm_debug(subdev, "requested speed matches current speed already\n");
+ return req_speed;
+ }
+
+ nvkm_debug(subdev, "set link to speed: %s width: x%i\n",
+ pcie_speed_strings[req_speed], req_width);
+ ret = pci->func->pcie.set_link(pci, req_speed, req_width);
+
+ if (ret < 0)
+ nvkm_error(subdev, "setting link failed with ret: %i\n", ret);
+
+ return ret;
+}
diff --git a/drm/nouveau/nvkm/subdev/pci/priv.h b/drm/nouveau/nvkm/subdev/pci/priv.h
index cf46d38..5370f0d 100644
--- a/drm/nouveau/nvkm/subdev/pci/priv.h
+++ b/drm/nouveau/nvkm/subdev/pci/priv.h
@@ -12,6 +12,18 @@ struct nvkm_pci_func {
void (*wr08)(struct nvkm_pci *, u16 addr, u8 data);
void (*wr32)(struct nvkm_pci *, u16 addr, u32 data);
void (*msi_rearm)(struct nvkm_pci *);
+
+ struct {
+ int (*init)(struct nvkm_pci *);
+ int (*set_link)(struct nvkm_pci *, enum nvkm_pcie_speed, u8);
+
+ enum nvkm_pcie_speed (*max_speed)(struct nvkm_pci *);
+ enum nvkm_pcie_speed (*cur_speed)(struct nvkm_pci *);
+
+ void (*set_version)(struct nvkm_pci *, u8);
+ int (*version)(struct nvkm_pci *);
+ int (*version_supported)(struct nvkm_pci *);
+ } pcie;
};
u32 nv40_pci_rd32(struct nvkm_pci *, u16);
@@ -22,4 +34,7 @@ void nv40_pci_msi_rearm(struct nvkm_pci *);
void nv46_pci_msi_rearm(struct nvkm_pci *);
void g84_pci_init(struct nvkm_pci *pci);
+
+/* pcie functions */
+int nvkm_pcie_init(struct nvkm_pci *pci);
#endif
--
2.6.1
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 4/9] pci: implement pcie speed change for tesla
[not found] ` <1444729463-1560-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
` (2 preceding siblings ...)
2015-10-13 9:44 ` [PATCH v2 3/9] pci: implement generic code for PCIe speed change Karol Herbst
@ 2015-10-13 9:44 ` Karol Herbst
[not found] ` <1444729463-1560-5-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
2015-10-13 9:44 ` [PATCH v2 5/9] pci: implement pcie speed change on Fermi Karol Herbst
` (4 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: Karol Herbst @ 2015-10-13 9:44 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
v2: rename functions and simplify init
Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
drm/nouveau/nvkm/subdev/pci/g84.c | 105 ++++++++++++++++++++++++++++++++++++
drm/nouveau/nvkm/subdev/pci/g94.c | 10 ++++
drm/nouveau/nvkm/subdev/pci/gf100.c | 5 ++
drm/nouveau/nvkm/subdev/pci/gf106.c | 5 ++
drm/nouveau/nvkm/subdev/pci/gk104.c | 2 +
drm/nouveau/nvkm/subdev/pci/priv.h | 9 ++++
6 files changed, 136 insertions(+)
diff --git a/drm/nouveau/nvkm/subdev/pci/g84.c b/drm/nouveau/nvkm/subdev/pci/g84.c
index 3faa6bf..7a4e766 100644
--- a/drm/nouveau/nvkm/subdev/pci/g84.c
+++ b/drm/nouveau/nvkm/subdev/pci/g84.c
@@ -25,6 +25,94 @@
#include <core/pci.h>
+int
+g84_pcie_version_supported(struct nvkm_pci *pci)
+{
+ u32 chipset = pci->subdev.device->chipset, reg_v;
+
+ /* these cards report wrong information about what they support */
+ if (chipset == 0x84 || chipset == 0x86)
+ return 1;
+
+ reg_v = nvkm_pci_rd32(pci, 0x460) & 0x200;
+ if (reg_v == 0x200)
+ return 2;
+ return 1;
+}
+
+int
+g84_pcie_version(struct nvkm_pci *pci)
+{
+ struct nvkm_device *device = pci->subdev.device;
+ return (nvkm_rd32(device, 0x00154c) & 0x1) + 1;
+}
+
+void
+g84_pcie_set_version(struct nvkm_pci *pci, u8 ver)
+{
+ struct nvkm_device *device = pci->subdev.device;
+ nvkm_mask(device, 0x00154c, 0x1, (ver >= 2 ? 0x1 : 0x0));
+}
+
+static void
+g84_pcie_set_cap_speed(struct nvkm_pci *pci, bool full_speed)
+{
+ struct nvkm_device *device = pci->subdev.device;
+ nvkm_mask(device, 0x00154c, 0x80, full_speed ? 0x80 : 0x0);
+}
+
+enum nvkm_pcie_speed
+g84_pcie_cur_speed(struct nvkm_pci *pci)
+{
+ u32 reg_v = nvkm_pci_rd32(pci, 0x88) & 0x30000;
+ switch (reg_v) {
+ case 0x30000:
+ return NVKM_PCIE_SPEED_8_0;
+ case 0x20000:
+ return NVKM_PCIE_SPEED_5_0;
+ case 0x10000:
+ default:
+ return NVKM_PCIE_SPEED_2_5;
+ }
+}
+
+enum nvkm_pcie_speed
+g84_pcie_max_speed(struct nvkm_pci *pci)
+{
+ u32 reg_v = nvkm_pci_rd32(pci, 0x460) & 0x3300;
+ if (reg_v == 0x2200)
+ return NVKM_PCIE_SPEED_5_0;
+ return NVKM_PCIE_SPEED_2_5;
+}
+
+void
+g84_pcie_set_link_speed(struct nvkm_pci *pci, enum nvkm_pcie_speed speed)
+{
+ u32 mask_value;
+
+ if (speed == NVKM_PCIE_SPEED_5_0)
+ mask_value = 0x20;
+ else
+ mask_value = 0x10;
+
+ nvkm_pci_mask(pci, 0x460, 0x30, mask_value);
+ nvkm_pci_mask(pci, 0x460, 0x1, 0x1);
+}
+
+int
+g84_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed req_speed,
+ u8 req_width)
+{
+ if (req_speed == NVKM_PCIE_SPEED_5_0)
+ g84_pcie_set_cap_speed(pci, true);
+ else
+ g84_pcie_set_cap_speed(pci, false);
+
+ g84_pcie_set_link_speed(pci, req_speed);
+
+ return 0;
+}
+
void
g84_pci_init(struct nvkm_pci *pci)
{
@@ -48,6 +136,13 @@ g84_pci_init(struct nvkm_pci *pci)
nvkm_pci_mask(pci, 0x041c, 0x00000060, 0x00000000);
}
+int
+g84_pcie_init(struct nvkm_pci *pci)
+{
+ g84_pcie_set_cap_speed(pci, g84_pcie_cur_speed(pci) == NVKM_PCIE_SPEED_5_0);
+ return 0;
+}
+
static const struct nvkm_pci_func
g84_pci_func = {
.init = g84_pci_init,
@@ -55,6 +150,16 @@ g84_pci_func = {
.wr08 = nv40_pci_wr08,
.wr32 = nv40_pci_wr32,
.msi_rearm = nv46_pci_msi_rearm,
+
+ .pcie.init = g84_pcie_init,
+ .pcie.set_link = g84_pcie_set_link,
+
+ .pcie.max_speed = g84_pcie_max_speed,
+ .pcie.cur_speed = g84_pcie_cur_speed,
+
+ .pcie.set_version = g84_pcie_set_version,
+ .pcie.version = g84_pcie_version,
+ .pcie.version_supported = g84_pcie_version_supported,
};
int
diff --git a/drm/nouveau/nvkm/subdev/pci/g94.c b/drm/nouveau/nvkm/subdev/pci/g94.c
index cd311ee..f2f96c1 100644
--- a/drm/nouveau/nvkm/subdev/pci/g94.c
+++ b/drm/nouveau/nvkm/subdev/pci/g94.c
@@ -30,6 +30,16 @@ g94_pci_func = {
.wr08 = nv40_pci_wr08,
.wr32 = nv40_pci_wr32,
.msi_rearm = nv40_pci_msi_rearm,
+
+ .pcie.init = g84_pcie_init,
+ .pcie.set_link = g84_pcie_set_link,
+
+ .pcie.max_speed = g84_pcie_max_speed,
+ .pcie.cur_speed = g84_pcie_cur_speed,
+
+ .pcie.set_version = g84_pcie_set_version,
+ .pcie.version = g84_pcie_version,
+ .pcie.version_supported = g84_pcie_version_supported,
};
int
diff --git a/drm/nouveau/nvkm/subdev/pci/gf100.c b/drm/nouveau/nvkm/subdev/pci/gf100.c
index 25e1ae7..1ee43ad 100644
--- a/drm/nouveau/nvkm/subdev/pci/gf100.c
+++ b/drm/nouveau/nvkm/subdev/pci/gf100.c
@@ -36,6 +36,11 @@ gf100_pci_func = {
.wr08 = nv40_pci_wr08,
.wr32 = nv40_pci_wr32,
.msi_rearm = gf100_pci_msi_rearm,
+
+ .pcie.max_speed = g84_pcie_max_speed,
+ .pcie.cur_speed = g84_pcie_cur_speed,
+
+ .pcie.version_supported = g84_pcie_version_supported,
};
int
diff --git a/drm/nouveau/nvkm/subdev/pci/gf106.c b/drm/nouveau/nvkm/subdev/pci/gf106.c
index 82d8c27..d72f850 100644
--- a/drm/nouveau/nvkm/subdev/pci/gf106.c
+++ b/drm/nouveau/nvkm/subdev/pci/gf106.c
@@ -29,6 +29,11 @@ gf106_pci_func = {
.wr08 = nv40_pci_wr08,
.wr32 = nv40_pci_wr32,
.msi_rearm = nv40_pci_msi_rearm,
+
+ .pcie.max_speed = g84_pcie_max_speed,
+ .pcie.cur_speed = g84_pcie_cur_speed,
+
+ .pcie.version_supported = g84_pcie_version_supported,
};
int
diff --git a/drm/nouveau/nvkm/subdev/pci/gk104.c b/drm/nouveau/nvkm/subdev/pci/gk104.c
index 6119f89..af79d9b 100644
--- a/drm/nouveau/nvkm/subdev/pci/gk104.c
+++ b/drm/nouveau/nvkm/subdev/pci/gk104.c
@@ -29,6 +29,8 @@ gk104_pci_func = {
.wr08 = nv40_pci_wr08,
.wr32 = nv40_pci_wr32,
.msi_rearm = nv40_pci_msi_rearm,
+
+ .pcie.cur_speed = g84_pcie_cur_speed,
};
int
diff --git a/drm/nouveau/nvkm/subdev/pci/priv.h b/drm/nouveau/nvkm/subdev/pci/priv.h
index 5370f0d..a504812 100644
--- a/drm/nouveau/nvkm/subdev/pci/priv.h
+++ b/drm/nouveau/nvkm/subdev/pci/priv.h
@@ -36,5 +36,14 @@ void nv46_pci_msi_rearm(struct nvkm_pci *);
void g84_pci_init(struct nvkm_pci *pci);
/* pcie functions */
+void g84_pcie_set_version(struct nvkm_pci *, u8);
+int g84_pcie_version(struct nvkm_pci *);
+int g84_pcie_version_supported(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 *);
+int g84_pcie_init(struct nvkm_pci *);
+int g84_pcie_set_link(struct nvkm_pci *, enum nvkm_pcie_speed, u8);
+
int nvkm_pcie_init(struct nvkm_pci *pci);
#endif
--
2.6.1
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 5/9] pci: implement pcie speed change on Fermi
[not found] ` <1444729463-1560-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
` (3 preceding siblings ...)
2015-10-13 9:44 ` [PATCH v2 4/9] pci: implement pcie speed change for tesla Karol Herbst
@ 2015-10-13 9:44 ` Karol Herbst
2015-10-13 9:44 ` [PATCH v2 6/9] pci: implement PCIe speed change for kepler+ Karol Herbst
` (3 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Karol Herbst @ 2015-10-13 9:44 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
v2: rename functions and simplify code a little
Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
drm/nouveau/nvkm/subdev/pci/gf100.c | 59 +++++++++++++++++++++++++++++++++++++
drm/nouveau/nvkm/subdev/pci/gf106.c | 5 ++++
drm/nouveau/nvkm/subdev/pci/gk104.c | 3 ++
drm/nouveau/nvkm/subdev/pci/priv.h | 7 +++++
4 files changed, 74 insertions(+)
diff --git a/drm/nouveau/nvkm/subdev/pci/gf100.c b/drm/nouveau/nvkm/subdev/pci/gf100.c
index 1ee43ad..366c47b 100644
--- a/drm/nouveau/nvkm/subdev/pci/gf100.c
+++ b/drm/nouveau/nvkm/subdev/pci/gf100.c
@@ -29,6 +29,60 @@ gf100_pci_msi_rearm(struct nvkm_pci *pci)
nvkm_pci_wr08(pci, 0x0704, 0xff);
}
+void
+gf100_pcie_set_version(struct nvkm_pci *pci, u8 ver)
+{
+ struct nvkm_device *device = pci->subdev.device;
+
+ if (ver > 1)
+ ver = 1;
+ else
+ ver = 0;
+
+ nvkm_mask(device, 0x02241c, 0x1, ver);
+}
+
+int
+gf100_pcie_version(struct nvkm_pci *pci)
+{
+ struct nvkm_device *device = pci->subdev.device;
+ return (nvkm_rd32(device, 0x02241c) & 0x1) + 1;
+}
+
+void
+gf100_pcie_set_cap_speed(struct nvkm_pci *pci, bool full_speed)
+{
+ struct nvkm_device *device = pci->subdev.device;
+ nvkm_mask(device, 0x02241c, 0x80, full_speed ? 0x80 : 0x0);
+}
+
+int
+gf100_pcie_cap_speed(struct nvkm_pci *pci)
+{
+ struct nvkm_device *device = pci->subdev.device;
+ u8 punits_pci_cap_speed = nvkm_rd32(device, 0x02241c) & 0x80;
+ if (punits_pci_cap_speed == 0x80)
+ return 1;
+ return 0;
+}
+
+int
+gf100_pcie_init(struct nvkm_pci *pci)
+{
+ gf100_pcie_set_cap_speed(pci,
+ g84_pcie_cur_speed(pci) == NVKM_PCIE_SPEED_5_0);
+ return 0;
+}
+
+int
+gf100_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed req_speed,
+ u8 req_width)
+{
+ gf100_pcie_set_cap_speed(pci, req_speed == NVKM_PCIE_SPEED_5_0);
+ g84_pcie_set_link_speed(pci, req_speed);
+ return 0;
+}
+
static const struct nvkm_pci_func
gf100_pci_func = {
.init = g84_pci_init,
@@ -37,9 +91,14 @@ gf100_pci_func = {
.wr32 = nv40_pci_wr32,
.msi_rearm = gf100_pci_msi_rearm,
+ .pcie.init = gf100_pcie_init,
+ .pcie.set_link = gf100_pcie_set_link,
+
.pcie.max_speed = g84_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 = g84_pcie_version_supported,
};
diff --git a/drm/nouveau/nvkm/subdev/pci/gf106.c b/drm/nouveau/nvkm/subdev/pci/gf106.c
index d72f850..612e195 100644
--- a/drm/nouveau/nvkm/subdev/pci/gf106.c
+++ b/drm/nouveau/nvkm/subdev/pci/gf106.c
@@ -30,9 +30,14 @@ gf106_pci_func = {
.wr32 = nv40_pci_wr32,
.msi_rearm = nv40_pci_msi_rearm,
+ .pcie.init = gf100_pcie_init,
+ .pcie.set_link = gf100_pcie_set_link,
+
.pcie.max_speed = g84_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 = g84_pcie_version_supported,
};
diff --git a/drm/nouveau/nvkm/subdev/pci/gk104.c b/drm/nouveau/nvkm/subdev/pci/gk104.c
index af79d9b..458dd31 100644
--- a/drm/nouveau/nvkm/subdev/pci/gk104.c
+++ b/drm/nouveau/nvkm/subdev/pci/gk104.c
@@ -31,6 +31,9 @@ gk104_pci_func = {
.msi_rearm = nv40_pci_msi_rearm,
.pcie.cur_speed = g84_pcie_cur_speed,
+
+ .pcie.set_version = gf100_pcie_set_version,
+ .pcie.version = gf100_pcie_version,
};
int
diff --git a/drm/nouveau/nvkm/subdev/pci/priv.h b/drm/nouveau/nvkm/subdev/pci/priv.h
index a504812..6265e2c 100644
--- a/drm/nouveau/nvkm/subdev/pci/priv.h
+++ b/drm/nouveau/nvkm/subdev/pci/priv.h
@@ -45,5 +45,12 @@ enum nvkm_pcie_speed g84_pcie_max_speed(struct nvkm_pci *);
int g84_pcie_init(struct nvkm_pci *);
int g84_pcie_set_link(struct nvkm_pci *, enum nvkm_pcie_speed, u8);
+void gf100_pcie_set_version(struct nvkm_pci *, u8);
+int gf100_pcie_version(struct nvkm_pci *);
+void gf100_pcie_set_cap_speed(struct nvkm_pci *, bool);
+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 nvkm_pcie_init(struct nvkm_pci *pci);
#endif
--
2.6.1
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 6/9] pci: implement PCIe speed change for kepler+
[not found] ` <1444729463-1560-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
` (4 preceding siblings ...)
2015-10-13 9:44 ` [PATCH v2 5/9] pci: implement pcie speed change on Fermi Karol Herbst
@ 2015-10-13 9:44 ` Karol Herbst
[not found] ` <1444729463-1560-7-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
2015-10-13 9:44 ` [PATCH v2 7/9] bios/perf: parse the pci speed from the bios for tesla and newer cards Karol Herbst
` (2 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: Karol Herbst @ 2015-10-13 9:44 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
v2: rename functions
Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
drm/nouveau/nvkm/subdev/pci/gk104.c | 196 ++++++++++++++++++++++++++++++++++++
1 file changed, 196 insertions(+)
diff --git a/drm/nouveau/nvkm/subdev/pci/gk104.c b/drm/nouveau/nvkm/subdev/pci/gk104.c
index 458dd31..99b131c 100644
--- a/drm/nouveau/nvkm/subdev/pci/gk104.c
+++ b/drm/nouveau/nvkm/subdev/pci/gk104.c
@@ -23,6 +23,197 @@
*/
#include "priv.h"
+static u32
+gk104_pci2_rd32(struct nvkm_pci *pci, u16 addr)
+{
+ struct nvkm_device *device = pci->subdev.device;
+ return nvkm_rd32(device, 0x08c000 + addr);
+}
+
+static void
+gk104_pci2_mask(struct nvkm_pci *pci, u16 addr, u32 mask, u32 value)
+{
+ struct nvkm_device *device = pci->subdev.device;
+ nvkm_mask(device, 0x08c000 + addr, mask, value);
+}
+
+static int
+gk104_pcie_version_supported(struct nvkm_pci *pci)
+{
+ return (gk104_pci2_rd32(pci, 0x1c0) & 0x4) == 0x4 ? 2 : 1;
+}
+
+static void
+gk104_pcie_set_cap_speed(struct nvkm_pci *pci, enum nvkm_pcie_speed speed)
+{
+ switch (speed) {
+ case NVKM_PCIE_SPEED_2_5:
+ gf100_pcie_set_cap_speed(pci, false);
+ gk104_pci2_mask(pci, 0x1c0, 0x30000, 0x10000);
+ break;
+ case NVKM_PCIE_SPEED_5_0:
+ gf100_pcie_set_cap_speed(pci, true);
+ gk104_pci2_mask(pci, 0x1c0, 0x30000, 0x20000);
+ break;
+ case NVKM_PCIE_SPEED_8_0:
+ gf100_pcie_set_cap_speed(pci, true);
+ gk104_pci2_mask(pci, 0x1c0, 0x30000, 0x30000);
+ break;
+ }
+}
+
+static enum nvkm_pcie_speed
+gk104_pcie_cap_speed(struct nvkm_pci *pci)
+{
+ int speed = gf100_pcie_cap_speed(pci);
+ if (speed < 0)
+ return speed;
+
+ if (speed == 0)
+ return NVKM_PCIE_SPEED_2_5;
+
+ if (speed >= 1) {
+ int speed2 = gk104_pci2_rd32(pci, 0x1c0) & 0x30000;
+ switch (speed2) {
+ case 0x00000:
+ case 0x10000:
+ return NVKM_PCIE_SPEED_2_5;
+ case 0x20000:
+ return NVKM_PCIE_SPEED_5_0;
+ case 0x30000:
+ return NVKM_PCIE_SPEED_8_0;
+ }
+ }
+ return -EINVAL;
+}
+
+static void
+gk104_pcie_set_lnkctl_speed(struct nvkm_pci *pci, enum nvkm_pcie_speed speed)
+{
+ u8 reg_v = 0;
+ switch (speed) {
+ case NVKM_PCIE_SPEED_2_5:
+ reg_v = 1;
+ break;
+ case NVKM_PCIE_SPEED_5_0:
+ reg_v = 2;
+ break;
+ case NVKM_PCIE_SPEED_8_0:
+ reg_v = 3;
+ break;
+ }
+ nvkm_pci_mask(pci, 0xa8, 0x3, reg_v);
+}
+
+static enum nvkm_pcie_speed
+gk104_pcie_lnkctl_speed(struct nvkm_pci *pci)
+{
+ u8 reg_v = nvkm_pci_rd32(pci, 0xa8) & 0x3;
+ switch (reg_v) {
+ case 0:
+ case 1:
+ return NVKM_PCIE_SPEED_2_5;
+ case 2:
+ return NVKM_PCIE_SPEED_5_0;
+ case 3:
+ return NVKM_PCIE_SPEED_8_0;
+ }
+ return -1;
+}
+
+static enum nvkm_pcie_speed
+gk104_pcie_max_speed(struct nvkm_pci *pci)
+{
+ u32 max_speed = gk104_pci2_rd32(pci, 0x1c0) & 0x300000;
+ switch (max_speed) {
+ case 0x000000:
+ return NVKM_PCIE_SPEED_8_0;
+ case 0x100000:
+ return NVKM_PCIE_SPEED_5_0;
+ case 0x200000:
+ return NVKM_PCIE_SPEED_2_5;
+ }
+ return NVKM_PCIE_SPEED_2_5;
+}
+
+static void
+gk104_pcie_set_link_speed(struct nvkm_pci *pci, enum nvkm_pcie_speed speed)
+{
+ u32 mask_value;
+ switch (speed) {
+ default:
+ case NVKM_PCIE_SPEED_2_5:
+ mask_value = 0x80000;
+ break;
+ case NVKM_PCIE_SPEED_5_0:
+ mask_value = 0x40000;
+ break;
+ case NVKM_PCIE_SPEED_8_0:
+ mask_value = 0x00000;
+ break;
+ }
+ gk104_pci2_mask(pci, 0x40, 0xc0000, mask_value);
+ gk104_pci2_mask(pci, 0x40, 0x1, 0x1);
+}
+
+static int
+gk104_pcie_init(struct nvkm_pci * pci)
+{
+ if (!pci_is_pcie(pci->pdev))
+ return -ENODEV;
+
+ if (gf100_pcie_version(pci) > 1) {
+ enum nvkm_pcie_speed
+ lnkctl_speed = gk104_pcie_lnkctl_speed(pci),
+ max_speed = gk104_pcie_max_speed(pci),
+ cap_speed = gk104_pcie_cap_speed(pci);
+
+ if (cap_speed != max_speed) {
+ nvkm_debug(&pci->subdev, "adjusting cap speed to max speed\n");
+ gk104_pcie_set_cap_speed(pci, max_speed);
+ cap_speed = gk104_pcie_cap_speed(pci);
+ if (cap_speed != max_speed)
+ nvkm_error(&pci->subdev, "couldn't adjust cap speed\n");
+ }
+
+ if (lnkctl_speed != max_speed) {
+ nvkm_debug(&pci->subdev,
+ "adjusting link control speed to max speed\n");
+ gk104_pcie_set_lnkctl_speed(pci, max_speed);
+ lnkctl_speed = gk104_pcie_lnkctl_speed(pci);
+ if (lnkctl_speed != max_speed)
+ nvkm_error(&pci->subdev,
+ "couldn't adjust link control speed\n");
+ }
+ }
+ return 0;
+}
+
+static int
+gk104_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed req_speed,
+ u8 req_width)
+{
+ enum nvkm_pcie_speed
+ lnk_ctl_speed = gk104_pcie_lnkctl_speed(pci),
+ lnk_cap_speed = gk104_pcie_cap_speed(pci);
+
+ if (req_speed > lnk_cap_speed) {
+ req_speed = lnk_cap_speed;
+ nvkm_warn(&pci->subdev, "dropping requested PCIe speed due to low"
+ " cap speed\n");
+ }
+
+ if (req_speed > lnk_ctl_speed) {
+ req_speed = lnk_ctl_speed;
+ nvkm_warn(&pci->subdev, "dropping requested PCIe speed due to low"
+ " control speed\n");
+ }
+
+ gk104_pcie_set_link_speed(pci, req_speed);
+ return 0;
+}
+
+
static const struct nvkm_pci_func
gk104_pci_func = {
.rd32 = nv40_pci_rd32,
@@ -30,10 +221,15 @@ gk104_pci_func = {
.wr32 = nv40_pci_wr32,
.msi_rearm = nv40_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,
};
int
--
2.6.1
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 7/9] bios/perf: parse the pci speed from the bios for tesla and newer cards
[not found] ` <1444729463-1560-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
` (5 preceding siblings ...)
2015-10-13 9:44 ` [PATCH v2 6/9] pci: implement PCIe speed change for kepler+ Karol Herbst
@ 2015-10-13 9:44 ` Karol Herbst
2015-10-13 9:44 ` [PATCH v2 8/9] perf: add fields for pci speed and width and use it for the pstates Karol Herbst
2015-10-13 9:44 ` [PATCH v2 9/9] perf: change pcie speed on pstate change Karol Herbst
8 siblings, 0 replies; 13+ messages in thread
From: Karol Herbst @ 2015-10-13 9:44 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
drm/nouveau/include/nvkm/subdev/bios/perf.h | 2 ++
drm/nouveau/nvkm/subdev/bios/perf.c | 16 ++++++++++++++++
2 files changed, 18 insertions(+)
diff --git a/drm/nouveau/include/nvkm/subdev/bios/perf.h b/drm/nouveau/include/nvkm/subdev/bios/perf.h
index 7cc2bec..d3bd250 100644
--- a/drm/nouveau/include/nvkm/subdev/bios/perf.h
+++ b/drm/nouveau/include/nvkm/subdev/bios/perf.h
@@ -13,6 +13,8 @@ struct nvbios_perfE {
u32 vdec;
u32 disp;
u32 script;
+ u8 pcie_speed;
+ u8 pcie_width;
};
u16 nvbios_perf_entry(struct nvkm_bios *, int idx,
diff --git a/drm/nouveau/nvkm/subdev/bios/perf.c b/drm/nouveau/nvkm/subdev/bios/perf.c
index aa7e33b..636bfb6 100644
--- a/drm/nouveau/nvkm/subdev/bios/perf.c
+++ b/drm/nouveau/nvkm/subdev/bios/perf.c
@@ -24,6 +24,7 @@
#include <subdev/bios.h>
#include <subdev/bios/bit.h>
#include <subdev/bios/perf.h>
+#include <subdev/pci.h>
u16
nvbios_perf_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr,
@@ -145,6 +146,21 @@ nvbios_perfEp(struct nvkm_bios *bios, int idx,
break;
case 0x40:
info->voltage = nvbios_rd08(bios, perf + 0x02);
+ switch (nvbios_rd08(bios, perf + 0xb) & 0x3) {
+ case 0:
+ info->pcie_speed = NVKM_PCIE_SPEED_5_0;
+ break;
+ case 3:
+ case 1:
+ info->pcie_speed = NVKM_PCIE_SPEED_2_5;
+ break;
+ case 2:
+ info->pcie_speed = NVKM_PCIE_SPEED_8_0;
+ break;
+ default:
+ break;
+ }
+ info->pcie_width = 0xff;
break;
default:
return 0x0000;
--
2.6.1
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 8/9] perf: add fields for pci speed and width and use it for the pstates
[not found] ` <1444729463-1560-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
` (6 preceding siblings ...)
2015-10-13 9:44 ` [PATCH v2 7/9] bios/perf: parse the pci speed from the bios for tesla and newer cards Karol Herbst
@ 2015-10-13 9:44 ` Karol Herbst
2015-10-13 9:44 ` [PATCH v2 9/9] perf: change pcie speed on pstate change Karol Herbst
8 siblings, 0 replies; 13+ messages in thread
From: Karol Herbst @ 2015-10-13 9:44 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
drm/nouveau/include/nvkm/subdev/clk.h | 3 +++
drm/nouveau/nvkm/subdev/clk/base.c | 2 ++
2 files changed, 5 insertions(+)
diff --git a/drm/nouveau/include/nvkm/subdev/clk.h b/drm/nouveau/include/nvkm/subdev/clk.h
index 8708f0a..e9c4a81 100644
--- a/drm/nouveau/include/nvkm/subdev/clk.h
+++ b/drm/nouveau/include/nvkm/subdev/clk.h
@@ -2,6 +2,7 @@
#define __NVKM_CLK_H__
#include <core/subdev.h>
#include <core/notify.h>
+#include <subdev/pci.h>
struct nvbios_pll;
struct nvkm_pll_vals;
@@ -59,6 +60,8 @@ struct nvkm_pstate {
struct nvkm_cstate base;
u8 pstate;
u8 fanspeed;
+ enum nvkm_pcie_speed pcie_speed;
+ u8 pcie_width;
};
struct nvkm_domain {
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index b7d82a4..7ae4f26 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -330,6 +330,8 @@ nvkm_pstate_new(struct nvkm_clk *clk, int idx)
pstate->pstate = perfE.pstate;
pstate->fanspeed = perfE.fanspeed;
+ pstate->pcie_speed = perfE.pcie_speed;
+ pstate->pcie_width = perfE.pcie_width;
cstate->voltage = perfE.voltage;
cstate->domain[nv_clk_src_core] = perfE.core;
cstate->domain[nv_clk_src_shader] = perfE.shader;
--
2.6.1
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 9/9] perf: change pcie speed on pstate change
[not found] ` <1444729463-1560-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
` (7 preceding siblings ...)
2015-10-13 9:44 ` [PATCH v2 8/9] perf: add fields for pci speed and width and use it for the pstates Karol Herbst
@ 2015-10-13 9:44 ` Karol Herbst
8 siblings, 0 replies; 13+ messages in thread
From: Karol Herbst @ 2015-10-13 9:44 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
v2: remove error and only set link for pcie devices
Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
drm/nouveau/nvkm/subdev/clk/base.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drm/nouveau/nvkm/subdev/clk/base.c b/drm/nouveau/nvkm/subdev/clk/base.c
index 7ae4f26..137e06f 100644
--- a/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drm/nouveau/nvkm/subdev/clk/base.c
@@ -176,6 +176,7 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
{
struct nvkm_subdev *subdev = &clk->subdev;
struct nvkm_ram *ram = subdev->device->fb->ram;
+ struct nvkm_pci *pci = subdev->device->pci;
struct nvkm_pstate *pstate;
int ret, idx = 0;
@@ -187,6 +188,9 @@ nvkm_pstate_prog(struct nvkm_clk *clk, int pstatei)
nvkm_debug(subdev, "setting performance state %d\n", pstatei);
clk->pstate = pstatei;
+ if (pci && pci_is_pcie(pci->pdev))
+ nvkm_pcie_set_link(pci, pstate->pcie_speed, pstate->pcie_width);
+
if (ram && ram->func->calc) {
int khz = pstate->base.domain[nv_clk_src_mem];
do {
--
2.6.1
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 3/9] pci: implement generic code for PCIe speed change
[not found] ` <1444729463-1560-4-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
@ 2015-10-13 22:55 ` Ben Skeggs
0 siblings, 0 replies; 13+ messages in thread
From: Ben Skeggs @ 2015-10-13 22:55 UTC (permalink / raw)
To: Karol Herbst, nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
On 10/13/2015 07:44 PM, Karol Herbst wrote:
> v2: rename and group functions
>
> Signed-off-by: Karol Herbst <nouveau@karolherbst.de> ---
> drm/nouveau/include/nvkm/subdev/pci.h | 14 +++
> drm/nouveau/nvkm/subdev/pci/Kbuild | 1 +
> drm/nouveau/nvkm/subdev/pci/base.c | 5 ++
> drm/nouveau/nvkm/subdev/pci/pcie.c | 165
> ++++++++++++++++++++++++++++++++++
> drm/nouveau/nvkm/subdev/pci/priv.h | 15 ++++ 5 files changed,
> 200 insertions(+) create mode 100644
> drm/nouveau/nvkm/subdev/pci/pcie.c
>
> diff --git a/drm/nouveau/include/nvkm/subdev/pci.h
> b/drm/nouveau/include/nvkm/subdev/pci.h index 17fe7b7..ab9d5cc
> 100644 --- a/drm/nouveau/include/nvkm/subdev/pci.h +++
> b/drm/nouveau/include/nvkm/subdev/pci.h @@ -2,6 +2,12 @@ #define
> __NVKM_PCI_H__ #include <core/subdev.h>
>
> +enum nvkm_pcie_speed { + NVKM_PCIE_SPEED_2_5, +
> NVKM_PCIE_SPEED_5_0, + NVKM_PCIE_SPEED_8_0, +}; + struct nvkm_pci
> { const struct nvkm_pci_func *func; struct nvkm_subdev subdev; @@
> -18,6 +24,11 @@ struct nvkm_pci { bool acquired; } agp;
>
> + struct { + enum nvkm_pcie_speed last_speed; + u8 last_width; +
> } pcie; + bool msi; };
>
> @@ -36,4 +47,7 @@ int g94_pci_new(struct nvkm_device *, int, struct
> nvkm_pci **); int gf100_pci_new(struct nvkm_device *, int, struct
> nvkm_pci **); int gf106_pci_new(struct nvkm_device *, int, struct
> nvkm_pci **); int gk104_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); #endif diff --git a/drm/nouveau/nvkm/subdev/pci/Kbuild
> b/drm/nouveau/nvkm/subdev/pci/Kbuild index 724afd4..3c2519f 100644
> --- a/drm/nouveau/nvkm/subdev/pci/Kbuild +++
> b/drm/nouveau/nvkm/subdev/pci/Kbuild @@ -1,5 +1,6 @@ nvkm-y +=
> nvkm/subdev/pci/agp.o nvkm-y += nvkm/subdev/pci/base.o +nvkm-y +=
> nvkm/subdev/pci/pcie.o nvkm-y += nvkm/subdev/pci/nv04.o nvkm-y +=
> nvkm/subdev/pci/nv40.o nvkm-y += nvkm/subdev/pci/nv46.o diff --git
> a/drm/nouveau/nvkm/subdev/pci/base.c
> b/drm/nouveau/nvkm/subdev/pci/base.c index d671dcf..95a8d05 100644
> --- a/drm/nouveau/nvkm/subdev/pci/base.c +++
> b/drm/nouveau/nvkm/subdev/pci/base.c @@ -117,6 +117,9 @@
> nvkm_pci_init(struct nvkm_subdev *subdev) ret =
> nvkm_agp_init(pci); if (ret) return ret; + } else { + if
> (pci_is_pcie(pci->pdev)) + nvkm_pcie_init(pci); }
>
> if (pci->func->init) @@ -160,6 +163,8 @@ nvkm_pci_new_(const struct
> nvkm_pci_func *func, struct nvkm_device *device, pci->func = func;
> pci->pdev = device->func->pci(device)->pdev; pci->irq = -1; +
> pci->pcie.last_speed = -1; + pci->pcie.last_width = -1;
>
> if (device->type == NVKM_DEVICE_AGP) nvkm_agp_ctor(pci); diff --git
> a/drm/nouveau/nvkm/subdev/pci/pcie.c
> b/drm/nouveau/nvkm/subdev/pci/pcie.c new file mode 100644 index
> 0000000..e60d0ba --- /dev/null +++
> b/drm/nouveau/nvkm/subdev/pci/pcie.c @@ -0,0 +1,165 @@ +/* + *
> Copyright 2015 Karol Herbst + * + * Permission is hereby granted,
> free of charge, to any person obtaining a + * copy of this software
> and associated documentation files (the "Software"), + * to deal in
> the Software without restriction, including without limitation + *
> the rights to use, copy, modify, merge, publish, distribute,
> sublicense, + * and/or sell copies of the Software, and to permit
> persons to whom the + * Software is furnished to do so, subject to
> the following conditions: + * + * The above copyright notice and
> this permission notice shall be included in + * all copies or
> substantial portions of the Software. + * + * THE SOFTWARE IS
> PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + *
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND
> NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR
> AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY,
> WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING
> FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + *
> OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Karol Herbst
> <git@karolherbst.de> + */ +#include "priv.h" + +static char
> *pcie_speed_strings[] = { + "2.5GT/s", + "5.0GT/s", + "8.0GT/s",
> +}; + +static enum nvkm_pcie_speed
> +pci_bus_speed_to_nvkm_pcie_speed(enum pci_bus_speed speed) +{ +
> switch (speed) { + case PCIE_SPEED_2_5GT: + return
> NVKM_PCIE_SPEED_2_5; + case PCIE_SPEED_5_0GT: + return
> NVKM_PCIE_SPEED_5_0; + case PCIE_SPEED_8_0GT: + return
> NVKM_PCIE_SPEED_8_0; + default: + /* XXX 0x16 is 8_0, assume 0x17
> will be 16_0 for now */ + if (speed == 0x17) + return
> NVKM_PCIE_SPEED_8_0; + return -1; + } +} + +static s8
> +nvkm_pci_get_pcie_version(struct nvkm_pci *pci) +{ + if
> (!pci_is_pcie(pci->pdev)) + return -ENODEV; + + if
> (!pci->func->pcie.version) + return -ENOSYS; + + return
> pci->func->pcie.version(pci); +} + +static s8
> +nvkm_pci_raise_pcie_version(struct nvkm_pci *pci) +{ + int ret,
> supported; + + if (!pci_is_pcie(pci->pdev)) + return -ENODEV; + +
> if (!pci->func->pcie.set_version ||
> !pci->func->pcie.version_supported) + return -ENOSYS; + + ret =
> nvkm_pci_get_pcie_version(pci); + supported =
> pci->func->pcie.version_supported(pci); + if (ret == 1 && ret <
> supported) { + nvkm_debug(&pci->subdev, "raising version\n"); +
> pci->func->pcie.set_version(pci, supported); + ret =
> nvkm_pci_get_pcie_version(pci); + } + return ret >= supported ? ret
> : -EINVAL; +} + +int +nvkm_pcie_init(struct nvkm_pci *pci) +{ +
> struct nvkm_subdev *subdev = &pci->subdev; + int ret; + + if
> (!pci_is_pcie(pci->pdev)) + return -ENODEV; + + /* raise pcie
> version first */ + ret = nvkm_pci_raise_pcie_version(pci); + if
> (ret <= 0) + nvkm_error(subdev, "couldn't raise version: %i\n",
> ret); + + if (pci->func->pcie.init) + pci->func->pcie.init(pci);
> + + nvkm_info(subdev, "pcie version: %i\n",
> nvkm_pci_get_pcie_version(pci)); + if (pci->func->pcie.max_speed) +
> nvkm_info(subdev, "pcie max speed: %s\n", +
> pcie_speed_strings[pci->func->pcie.max_speed(pci)]); + + if
> (pci->pcie.last_speed != -1) + nvkm_pcie_set_link(pci,
> pci->pcie.last_speed, pci->pcie.last_width); + + return 0; +} +
> +int +nvkm_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed
> req_speed, + u8 req_width) +{ + struct nvkm_subdev *subdev =
> &pci->subdev; + enum nvkm_pcie_speed sys_cur_speed, sys_max_speed;
> + struct pci_bus *pbus = pci->pdev->bus; + int ret; + + if
> (!pci_is_pcie(pci->pdev)) + return -ENODEV; + + if
> (!pci->func->pcie.set_link || !pci->func->pcie.version + ||
> !pci->func->pcie.max_speed || !pci->func->pcie.cur_speed) + return
> -ENOSYS; + + nvkm_debug(subdev, "pcie speed %s requested\n", +
> pcie_speed_strings[req_speed]); + + if
> (pci->func->pcie.version(pci) < 2) { + nvkm_error(subdev, "can't
> change link speed, " + "because current version too low\n"); +
> return -ENODEV; + } + + sys_cur_speed =
> pci->func->pcie.cur_speed(pci); + sys_max_speed =
> min(pci_bus_speed_to_nvkm_pcie_speed(pbus->max_bus_speed), +
> pci->func->pcie.max_speed(pci)); + + nvkm_debug(subdev, "bus
> current speed: %s max speed: %s\n", +
> pcie_speed_strings[sys_cur_speed],
> pcie_speed_strings[sys_max_speed]); + + if (req_speed >
> sys_max_speed) { + req_speed = sys_max_speed; + nvkm_warn(subdev,
> "bus or card not fast enough, dropping " + "requested speed to
> %s", pcie_speed_strings[req_speed]); + } + + pci->pcie.last_speed =
> req_speed; + pci->pcie.last_width = req_width; + + if (req_speed ==
> sys_cur_speed) { + nvkm_debug(subdev, "requested speed matches
> current speed already\n"); + return req_speed; + } + +
> nvkm_debug(subdev, "set link to speed: %s width: x%i\n", +
> pcie_speed_strings[req_speed], req_width); + ret =
> pci->func->pcie.set_link(pci, req_speed, req_width); + + if (ret <
> 0) + nvkm_error(subdev, "setting link failed with ret: %i\n",
> ret); + + return ret; +} diff --git
> a/drm/nouveau/nvkm/subdev/pci/priv.h
> b/drm/nouveau/nvkm/subdev/pci/priv.h index cf46d38..5370f0d 100644
> --- a/drm/nouveau/nvkm/subdev/pci/priv.h +++
> b/drm/nouveau/nvkm/subdev/pci/priv.h @@ -12,6 +12,18 @@ struct
> nvkm_pci_func { void (*wr08)(struct nvkm_pci *, u16 addr, u8
> data); void (*wr32)(struct nvkm_pci *, u16 addr, u32 data); void
> (*msi_rearm)(struct nvkm_pci *); + + struct { + int (*init)(struct
> nvkm_pci *); + int (*set_link)(struct nvkm_pci *, enum
> nvkm_pcie_speed, u8); + + enum nvkm_pcie_speed (*max_speed)(struct
> nvkm_pci *); + enum nvkm_pcie_speed (*cur_speed)(struct nvkm_pci
> *); + + void (*set_version)(struct nvkm_pci *, u8); + int
> (*version)(struct nvkm_pci *); + int (*version_supported)(struct
> nvkm_pci *);
Very minor nit-pick: most of the code uses "blah_set" etc rather than
"set_blah", it would be nice to be consistent with these here.
> + } pcie; };
>
> u32 nv40_pci_rd32(struct nvkm_pci *, u16); @@ -22,4 +34,7 @@ void
> nv40_pci_msi_rearm(struct nvkm_pci *); void
> nv46_pci_msi_rearm(struct nvkm_pci *);
>
> void g84_pci_init(struct nvkm_pci *pci); + +/* pcie functions */
> +int nvkm_pcie_init(struct nvkm_pci *pci); #endif
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
iQIcBAEBCAAGBQJWHYvvAAoJEHYLnGJQkpH7L3kP/RMT3TfEl1Ecwm02PrIyygMK
vYq3sQvQ6+ZvMLkSJReUNbMmaqBfoeNmzO+zWhdPlzObh5K8lNMxD35WTSQYnzCr
ACdo0wc0JBfa5MMIuhU2Am/GfZrLm9lZ6m9Ke3LMkdmFWHx7WGZX2HVWUHSKFL7f
NlTYLS0SNKf6lab0gOiG5TMPxYcGmxYgCGdVhtYWfiu3raTUwfCQDj1qlztjAa8L
lRK/i0KtCMVB1t/fB/u3ekao3RHJNU6fcn50TmcMS4zS3p3LrowXhqAyVK27dYly
EDzC43o91cYFSNfHvMH9ZiIK54EKQI/vY2WrZdARRwQrNL/IO0UkNhh1g8llwmDb
3Ze7hY7xtomJSkqp7QFfjA8Iglpm9Z7DQP2vFqgoup3MVqDKBUscqoIkuu+HO+zR
nB+zuDSyNSnyWyUjaKlbcKucCJEsIF/EKw5OosegPNgQ6LGEFc+ub+ELk9+ozSDu
UxZvYfMb+P3jHBaPe2XoXoFnDvWUkrH70sodeYvii+jyYNxmhyEsVQVbKVAfTZ9B
1UUkmS9Mv0PvVeCBwThoyQ6x8fFAq3qkOKGtmepvzT8zY0E3Ps1RxQGQipPDrtdV
Tj7VEZdHbR7WUov2xz3pkh3f2MEhck+8idYR88JR6ijzbx7Bxz36gth624RSxu+L
VV3t6v60pr1hO25Xvz+G
=zLyv
-----END PGP SIGNATURE-----
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 4/9] pci: implement pcie speed change for tesla
[not found] ` <1444729463-1560-5-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
@ 2015-10-13 22:56 ` Ben Skeggs
0 siblings, 0 replies; 13+ messages in thread
From: Ben Skeggs @ 2015-10-13 22:56 UTC (permalink / raw)
To: Karol Herbst, nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
On 10/13/2015 07:44 PM, Karol Herbst wrote:
> v2: rename functions and simplify init
>
> Signed-off-by: Karol Herbst <nouveau@karolherbst.de> ---
> drm/nouveau/nvkm/subdev/pci/g84.c | 105
> ++++++++++++++++++++++++++++++++++++
> drm/nouveau/nvkm/subdev/pci/g94.c | 10 ++++
> drm/nouveau/nvkm/subdev/pci/gf100.c | 5 ++
> drm/nouveau/nvkm/subdev/pci/gf106.c | 5 ++
> drm/nouveau/nvkm/subdev/pci/gk104.c | 2 +
> drm/nouveau/nvkm/subdev/pci/priv.h | 9 ++++ 6 files changed, 136
> insertions(+)
>
> diff --git a/drm/nouveau/nvkm/subdev/pci/g84.c
> b/drm/nouveau/nvkm/subdev/pci/g84.c index 3faa6bf..7a4e766 100644
> --- a/drm/nouveau/nvkm/subdev/pci/g84.c +++
> b/drm/nouveau/nvkm/subdev/pci/g84.c @@ -25,6 +25,94 @@
>
> #include <core/pci.h>
>
> +int +g84_pcie_version_supported(struct nvkm_pci *pci) +{ + u32
> chipset = pci->subdev.device->chipset, reg_v; + + /* these cards
> report wrong information about what they support */ + if (chipset
> == 0x84 || chipset == 0x86) + return 1;
Give these chipsets their own implementation that just returns 1 for
this hook.
> + + reg_v = nvkm_pci_rd32(pci, 0x460) & 0x200; + if (reg_v ==
> 0x200) + return 2; + return 1; +} + +int +g84_pcie_version(struct
> nvkm_pci *pci) +{ + struct nvkm_device *device =
> pci->subdev.device; + return (nvkm_rd32(device, 0x00154c) & 0x1) +
> 1; +} + +void +g84_pcie_set_version(struct nvkm_pci *pci, u8 ver)
> +{ + struct nvkm_device *device = pci->subdev.device; +
> nvkm_mask(device, 0x00154c, 0x1, (ver >= 2 ? 0x1 : 0x0)); +} +
> +static void +g84_pcie_set_cap_speed(struct nvkm_pci *pci, bool
> full_speed) +{ + struct nvkm_device *device = pci->subdev.device; +
> nvkm_mask(device, 0x00154c, 0x80, full_speed ? 0x80 : 0x0); +} +
> +enum nvkm_pcie_speed +g84_pcie_cur_speed(struct nvkm_pci *pci) +{
> + u32 reg_v = nvkm_pci_rd32(pci, 0x88) & 0x30000; + switch (reg_v)
> { + case 0x30000: + return NVKM_PCIE_SPEED_8_0; + case
> 0x20000: + return NVKM_PCIE_SPEED_5_0; + case 0x10000: +
> default: + return NVKM_PCIE_SPEED_2_5; + } +} + +enum
> nvkm_pcie_speed +g84_pcie_max_speed(struct nvkm_pci *pci) +{ + u32
> reg_v = nvkm_pci_rd32(pci, 0x460) & 0x3300; + if (reg_v == 0x2200)
> + return NVKM_PCIE_SPEED_5_0; + return NVKM_PCIE_SPEED_2_5; +} +
> +void +g84_pcie_set_link_speed(struct nvkm_pci *pci, enum
> nvkm_pcie_speed speed) +{ + u32 mask_value; + + if (speed ==
> NVKM_PCIE_SPEED_5_0) + mask_value = 0x20; + else + mask_value =
> 0x10; + + nvkm_pci_mask(pci, 0x460, 0x30, mask_value); +
> nvkm_pci_mask(pci, 0x460, 0x1, 0x1); +} + +int
> +g84_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed
> req_speed, + u8 req_width) +{ + if (req_speed ==
> NVKM_PCIE_SPEED_5_0) + g84_pcie_set_cap_speed(pci, true); + else +
> g84_pcie_set_cap_speed(pci, false); + +
> g84_pcie_set_link_speed(pci, req_speed); + + return 0; +} + void
> g84_pci_init(struct nvkm_pci *pci) { @@ -48,6 +136,13 @@
> g84_pci_init(struct nvkm_pci *pci) nvkm_pci_mask(pci, 0x041c,
> 0x00000060, 0x00000000); }
>
> +int +g84_pcie_init(struct nvkm_pci *pci) +{ +
> g84_pcie_set_cap_speed(pci, g84_pcie_cur_speed(pci) ==
> NVKM_PCIE_SPEED_5_0); + return 0; +} + static const struct
> nvkm_pci_func g84_pci_func = { .init = g84_pci_init, @@ -55,6
> +150,16 @@ g84_pci_func = { .wr08 = nv40_pci_wr08, .wr32 =
> nv40_pci_wr32, .msi_rearm = nv46_pci_msi_rearm, + + .pcie.init =
> g84_pcie_init, + .pcie.set_link = g84_pcie_set_link, + +
> .pcie.max_speed = g84_pcie_max_speed, + .pcie.cur_speed =
> g84_pcie_cur_speed, + + .pcie.set_version = g84_pcie_set_version, +
> .pcie.version = g84_pcie_version, + .pcie.version_supported =
> g84_pcie_version_supported, };
>
> int diff --git a/drm/nouveau/nvkm/subdev/pci/g94.c
> b/drm/nouveau/nvkm/subdev/pci/g94.c index cd311ee..f2f96c1 100644
> --- a/drm/nouveau/nvkm/subdev/pci/g94.c +++
> b/drm/nouveau/nvkm/subdev/pci/g94.c @@ -30,6 +30,16 @@ g94_pci_func
> = { .wr08 = nv40_pci_wr08, .wr32 = nv40_pci_wr32, .msi_rearm =
> nv40_pci_msi_rearm, + + .pcie.init = g84_pcie_init, +
> .pcie.set_link = g84_pcie_set_link, + + .pcie.max_speed =
> g84_pcie_max_speed, + .pcie.cur_speed = g84_pcie_cur_speed, + +
> .pcie.set_version = g84_pcie_set_version, + .pcie.version =
> g84_pcie_version, + .pcie.version_supported =
> g84_pcie_version_supported, };
>
> int diff --git a/drm/nouveau/nvkm/subdev/pci/gf100.c
> b/drm/nouveau/nvkm/subdev/pci/gf100.c index 25e1ae7..1ee43ad
> 100644 --- a/drm/nouveau/nvkm/subdev/pci/gf100.c +++
> b/drm/nouveau/nvkm/subdev/pci/gf100.c @@ -36,6 +36,11 @@
> gf100_pci_func = { .wr08 = nv40_pci_wr08, .wr32 = nv40_pci_wr32,
> .msi_rearm = gf100_pci_msi_rearm, + + .pcie.max_speed =
> g84_pcie_max_speed, + .pcie.cur_speed = g84_pcie_cur_speed, + +
> .pcie.version_supported = g84_pcie_version_supported, };
>
> int diff --git a/drm/nouveau/nvkm/subdev/pci/gf106.c
> b/drm/nouveau/nvkm/subdev/pci/gf106.c index 82d8c27..d72f850
> 100644 --- a/drm/nouveau/nvkm/subdev/pci/gf106.c +++
> b/drm/nouveau/nvkm/subdev/pci/gf106.c @@ -29,6 +29,11 @@
> gf106_pci_func = { .wr08 = nv40_pci_wr08, .wr32 = nv40_pci_wr32,
> .msi_rearm = nv40_pci_msi_rearm, + + .pcie.max_speed =
> g84_pcie_max_speed, + .pcie.cur_speed = g84_pcie_cur_speed, + +
> .pcie.version_supported = g84_pcie_version_supported, };
>
> int diff --git a/drm/nouveau/nvkm/subdev/pci/gk104.c
> b/drm/nouveau/nvkm/subdev/pci/gk104.c index 6119f89..af79d9b
> 100644 --- a/drm/nouveau/nvkm/subdev/pci/gk104.c +++
> b/drm/nouveau/nvkm/subdev/pci/gk104.c @@ -29,6 +29,8 @@
> gk104_pci_func = { .wr08 = nv40_pci_wr08, .wr32 = nv40_pci_wr32,
> .msi_rearm = nv40_pci_msi_rearm, + + .pcie.cur_speed =
> g84_pcie_cur_speed, };
>
> int diff --git a/drm/nouveau/nvkm/subdev/pci/priv.h
> b/drm/nouveau/nvkm/subdev/pci/priv.h index 5370f0d..a504812 100644
> --- a/drm/nouveau/nvkm/subdev/pci/priv.h +++
> b/drm/nouveau/nvkm/subdev/pci/priv.h @@ -36,5 +36,14 @@ void
> nv46_pci_msi_rearm(struct nvkm_pci *); void g84_pci_init(struct
> nvkm_pci *pci);
>
> /* pcie functions */ +void g84_pcie_set_version(struct nvkm_pci *,
> u8); +int g84_pcie_version(struct nvkm_pci *); +int
> g84_pcie_version_supported(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 *); +int
> g84_pcie_init(struct nvkm_pci *); +int g84_pcie_set_link(struct
> nvkm_pci *, enum nvkm_pcie_speed, u8); + int nvkm_pcie_init(struct
> nvkm_pci *pci); #endif
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
iQIcBAEBCAAGBQJWHYwoAAoJEHYLnGJQkpH7V7wP/ArjtKXGn6CDPgDGp+a40BWc
mB4T3dLjgZhjGYVjbPG0eddynTiR4PyJP+RPyD0O4eS+PdknUMo+QJXPOYWVoKlg
a090vfzkAp35OSSRa6NjKOAf5LgK4+Zi6BgFXE3TpUJ6w2vxOkUIUDLOaC3HPc61
Kk1TqPEcKk8JCl7fHGmzt8gPhw/bJaDzDmFghudzpVzJit0jXzAkevqHN80y4Auz
ADYE0ayVPPG0hDEGIXhY09A2OZPbfAqJyP2A0mt97ELWsUc1w1ipjz3Psq0u6QvB
fCHX4FPp6a1Lbns0M3a+RWOOeVv7zciOcmrDGSvmiX2IbvnoFDzK+fK6/MadLFk5
2Sh5hdH6e6T5BLKetCU/A9JWF/RdytQF8GHZEYxr0aM6NINKyB+jU1ccAkRqJLmm
+sbd9ONkfbWVuweTeiQW7I4fBHI9+LVbdcMusnTREKsFK5mri4SRAovKTq20WKKp
EGGHzeJlm7YQVJg5JZGfK2FcCxE9yTkthK3mKYHI/c4HufyL+JMHfAJo1hKO3xL4
vAnmq2XoUltPJyNqzsTJMt8zooraXYEMaVfpzijE3A1B5wm+e5/7DpNNhcDZT86K
AvLj+bxQ3+B0Z74jfy2jUNerwiImKH/aFsa681kVlX7Y57fXcc1AaUXqLEwshQGp
FUxQj+UWJ/GIcImWaNVW
=6Pdy
-----END PGP SIGNATURE-----
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 6/9] pci: implement PCIe speed change for kepler+
[not found] ` <1444729463-1560-7-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
@ 2015-10-13 22:59 ` Ben Skeggs
0 siblings, 0 replies; 13+ messages in thread
From: Ben Skeggs @ 2015-10-13 22:59 UTC (permalink / raw)
To: Karol Herbst, nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
On 10/13/2015 07:44 PM, Karol Herbst wrote:
> v2: rename functions
>
> Signed-off-by: Karol Herbst <nouveau@karolherbst.de> ---
> drm/nouveau/nvkm/subdev/pci/gk104.c | 196
> ++++++++++++++++++++++++++++++++++++ 1 file changed, 196
> insertions(+)
>
> diff --git a/drm/nouveau/nvkm/subdev/pci/gk104.c
> b/drm/nouveau/nvkm/subdev/pci/gk104.c index 458dd31..99b131c
> 100644 --- a/drm/nouveau/nvkm/subdev/pci/gk104.c +++
> b/drm/nouveau/nvkm/subdev/pci/gk104.c @@ -23,6 +23,197 @@ */
> #include "priv.h"
>
> +static u32 +gk104_pci2_rd32(struct nvkm_pci *pci, u16 addr) +{ +
> struct nvkm_device *device = pci->subdev.device; + return
> nvkm_rd32(device, 0x08c000 + addr); +} + +static void
> +gk104_pci2_mask(struct nvkm_pci *pci, u16 addr, u32 mask, u32
> value) +{ + struct nvkm_device *device = pci->subdev.device; +
> nvkm_mask(device, 0x08c000 + addr, mask, value); +} +
Maybe skip these accessors and use nvkm_rd32/nvkm_mask directly, the
code is very specific to this chipset, and we don't need to abstract
away the mmio aperture difference like we do in some of the other code.
I don't have strong opinions on this one though.
> +static int +gk104_pcie_version_supported(struct nvkm_pci *pci) +{
> + return (gk104_pci2_rd32(pci, 0x1c0) & 0x4) == 0x4 ? 2 : 1; +} +
> +static void +gk104_pcie_set_cap_speed(struct nvkm_pci *pci, enum
> nvkm_pcie_speed speed) +{ + switch (speed) { + case
> NVKM_PCIE_SPEED_2_5: + gf100_pcie_set_cap_speed(pci, false); +
> gk104_pci2_mask(pci, 0x1c0, 0x30000, 0x10000); + break; + case
> NVKM_PCIE_SPEED_5_0: + gf100_pcie_set_cap_speed(pci, true); +
> gk104_pci2_mask(pci, 0x1c0, 0x30000, 0x20000); + break; + case
> NVKM_PCIE_SPEED_8_0: + gf100_pcie_set_cap_speed(pci, true); +
> gk104_pci2_mask(pci, 0x1c0, 0x30000, 0x30000); + break; + } +} +
> +static enum nvkm_pcie_speed +gk104_pcie_cap_speed(struct nvkm_pci
> *pci) +{ + int speed = gf100_pcie_cap_speed(pci); + if (speed < 0)
> + return speed; + + if (speed == 0) + return
> NVKM_PCIE_SPEED_2_5; + + if (speed >= 1) { + int speed2 =
> gk104_pci2_rd32(pci, 0x1c0) & 0x30000; + switch (speed2) { + case
> 0x00000: + case 0x10000: + return NVKM_PCIE_SPEED_2_5; + case
> 0x20000: + return NVKM_PCIE_SPEED_5_0; + case 0x30000: +
> return NVKM_PCIE_SPEED_8_0; + } + } + return -EINVAL; +} + +static
> void +gk104_pcie_set_lnkctl_speed(struct nvkm_pci *pci, enum
> nvkm_pcie_speed speed) +{ + u8 reg_v = 0; + switch (speed) { + case
> NVKM_PCIE_SPEED_2_5: + reg_v = 1; + break; + case
> NVKM_PCIE_SPEED_5_0: + reg_v = 2; + break; + case
> NVKM_PCIE_SPEED_8_0: + reg_v = 3; + break; + } +
> nvkm_pci_mask(pci, 0xa8, 0x3, reg_v); +} + +static enum
> nvkm_pcie_speed +gk104_pcie_lnkctl_speed(struct nvkm_pci *pci) +{ +
> u8 reg_v = nvkm_pci_rd32(pci, 0xa8) & 0x3; + switch (reg_v) { +
> case 0: + case 1: + return NVKM_PCIE_SPEED_2_5; + case 2: +
> return NVKM_PCIE_SPEED_5_0; + case 3: + return
> NVKM_PCIE_SPEED_8_0; + } + return -1; +} + +static enum
> nvkm_pcie_speed +gk104_pcie_max_speed(struct nvkm_pci *pci) +{ +
> u32 max_speed = gk104_pci2_rd32(pci, 0x1c0) & 0x300000; + switch
> (max_speed) { + case 0x000000: + return NVKM_PCIE_SPEED_8_0; +
> case 0x100000: + return NVKM_PCIE_SPEED_5_0; + case 0x200000: +
> return NVKM_PCIE_SPEED_2_5; + } + return NVKM_PCIE_SPEED_2_5; +} +
> +static void +gk104_pcie_set_link_speed(struct nvkm_pci *pci, enum
> nvkm_pcie_speed speed) +{ + u32 mask_value; + switch (speed) { +
> default: + case NVKM_PCIE_SPEED_2_5: + mask_value = 0x80000; +
> break; + case NVKM_PCIE_SPEED_5_0: + mask_value = 0x40000; +
> break; + case NVKM_PCIE_SPEED_8_0: + mask_value = 0x00000; +
> break; + } + gk104_pci2_mask(pci, 0x40, 0xc0000, mask_value); +
> gk104_pci2_mask(pci, 0x40, 0x1, 0x1); +} + +static int
> +gk104_pcie_init(struct nvkm_pci * pci) +{ + if
> (!pci_is_pcie(pci->pdev)) + return -ENODEV; + + if
> (gf100_pcie_version(pci) > 1) { + enum nvkm_pcie_speed +
> lnkctl_speed = gk104_pcie_lnkctl_speed(pci), + max_speed =
> gk104_pcie_max_speed(pci), + cap_speed =
> gk104_pcie_cap_speed(pci); + + if (cap_speed != max_speed) { +
> nvkm_debug(&pci->subdev, "adjusting cap speed to max speed\n"); +
> gk104_pcie_set_cap_speed(pci, max_speed); + cap_speed =
> gk104_pcie_cap_speed(pci); + if (cap_speed != max_speed) +
> nvkm_error(&pci->subdev, "couldn't adjust cap speed\n"); + } + +
> if (lnkctl_speed != max_speed) { + nvkm_debug(&pci->subdev, +
> "adjusting link control speed to max speed\n"); +
> gk104_pcie_set_lnkctl_speed(pci, max_speed); + lnkctl_speed =
> gk104_pcie_lnkctl_speed(pci); + if (lnkctl_speed != max_speed) +
> nvkm_error(&pci->subdev, + "couldn't adjust link control
> speed\n"); + } + } + return 0; +} + +static int
> +gk104_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed
> req_speed, + u8 req_width) +{ + enum nvkm_pcie_speed +
> lnk_ctl_speed = gk104_pcie_lnkctl_speed(pci), + lnk_cap_speed =
> gk104_pcie_cap_speed(pci); + + if (req_speed > lnk_cap_speed) { +
> req_speed = lnk_cap_speed; + nvkm_warn(&pci->subdev, "dropping
> requested PCIe speed due to low" + " cap speed\n"); + } + + if
> (req_speed > lnk_ctl_speed) { + req_speed = lnk_ctl_speed; +
> nvkm_warn(&pci->subdev, "dropping requested PCIe speed due to low"
> + " control speed\n"); + } + + gk104_pcie_set_link_speed(pci,
> req_speed); + return 0; +} + + static const struct nvkm_pci_func
> gk104_pci_func = { .rd32 = nv40_pci_rd32, @@ -30,10 +221,15 @@
> gk104_pci_func = { .wr32 = nv40_pci_wr32, .msi_rearm =
> nv40_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, };
>
> int
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
iQIcBAEBCAAGBQJWHYy5AAoJEHYLnGJQkpH7dTEQAKk+oKbt8nZlrrHEAOjarH6w
sLktjZeqLUUUSyK7KXNrpPgzZtvxmuBqPHTcCyjtJ2l/02d1XPT7d6xaRRxPeoXY
RMeqZoUz2t1yJHHuct6KTncTyYuItfO99G2nDbW5lUR6cW9bMBUnrL/FNbfZ+6VN
AJlFim6wiZ8dKsJalNPBS353dChRabSs6XNXlW1U7tOv52aTHRKt5S/PvEVmdyFW
BMMkYuB/8y47TeqjHZo4l3ZfnhPZ0jaJY76CWLOgSkhAx65bMFcu7px5EM0S2gmG
e4ptteJFq5psaeSiLr3kDa3ry4mDRHpwl/yMa4Ej1neTOt1DOl82GqClD/6QwlOw
QOiE41iPgJJYSPDahhmVnUmGEhuSODBtCOX4pMRo1wtjaPgAeP0hUh+sOZJEag/D
LMjnH5MFCtUcmcUSAUQjMlAZrtZw+Fo3eQglzBFd84Zl9JwdK8dNhKtpe8qWUsaB
Hf0bQhXn/5kZLXkhun+Rjucmi7cH6pTu4fDHSe/cHpzPgf06N8pqFQv+D+HzYRYL
7l+MC/gmzBODTx+hpdC75ETwFWBEQug2wuerpCV+nh4KPMbuLVzsBcF8H8xFwa6d
XDCdEQgk9f7KUT8Q2G3oaRBT6jWv8e7bntzu4kGe35aYBxi6pT6EnsbSFesZjxce
q0HaM0kT14JkA/C+NdHZ
=atdH
-----END PGP SIGNATURE-----
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2015-10-13 22:59 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-13 9:44 [PATCH v2 0/9] PCIEs speed change Karol Herbst
[not found] ` <1444729463-1560-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
2015-10-13 9:44 ` [PATCH v2 1/9] pci: add gk104 variant Karol Herbst
2015-10-13 9:44 ` [PATCH v2 2/9] pci: add gf106 variant Karol Herbst
2015-10-13 9:44 ` [PATCH v2 3/9] pci: implement generic code for PCIe speed change Karol Herbst
[not found] ` <1444729463-1560-4-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
2015-10-13 22:55 ` Ben Skeggs
2015-10-13 9:44 ` [PATCH v2 4/9] pci: implement pcie speed change for tesla Karol Herbst
[not found] ` <1444729463-1560-5-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
2015-10-13 22:56 ` Ben Skeggs
2015-10-13 9:44 ` [PATCH v2 5/9] pci: implement pcie speed change on Fermi Karol Herbst
2015-10-13 9:44 ` [PATCH v2 6/9] pci: implement PCIe speed change for kepler+ Karol Herbst
[not found] ` <1444729463-1560-7-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
2015-10-13 22:59 ` Ben Skeggs
2015-10-13 9:44 ` [PATCH v2 7/9] bios/perf: parse the pci speed from the bios for tesla and newer cards Karol Herbst
2015-10-13 9:44 ` [PATCH v2 8/9] perf: add fields for pci speed and width and use it for the pstates Karol Herbst
2015-10-13 9:44 ` [PATCH v2 9/9] perf: change pcie speed on pstate change Karol Herbst
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.