All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/9] PCIEs speed change
@ 2015-10-14  0:44 Karol Herbst
       [not found] ` <1444783477-3175-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
  0 siblings, 1 reply; 10+ messages in thread
From: Karol Herbst @ 2015-10-14  0:44 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

I hope now the final revison of that patch series.

I've taken care of 2 out of 3 comments from ben.

I left the set_link and set_version name this way, because I can't figure any
better name and because they are always used with pcie. in front, so they
should fit in nice

Ben: if you are strong about that, I can change that, but I really want better
names then.

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           |  97 ++++++++++++
 drm/nouveau/nvkm/subdev/pci/g94.c           |  18 +++
 drm/nouveau/nvkm/subdev/pci/gf100.c         |  64 ++++++++
 drm/nouveau/nvkm/subdev/pci/gf106.c         |  48 ++++++
 drm/nouveau/nvkm/subdev/pci/gk104.c         | 229 ++++++++++++++++++++++++++++
 drm/nouveau/nvkm/subdev/pci/pcie.c          | 165 ++++++++++++++++++++
 drm/nouveau/nvkm/subdev/pci/priv.h          |  32 ++++
 15 files changed, 719 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] 10+ messages in thread

* [PATCH v3 1/9] pci: add gk104 variant
       [not found] ` <1444783477-3175-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
@ 2015-10-14  0:44   ` Karol Herbst
  2015-10-14  0:44   ` [PATCH v3 2/9] pci: add gf106 variant Karol Herbst
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Karol Herbst @ 2015-10-14  0: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] 10+ messages in thread

* [PATCH v3 2/9] pci: add gf106 variant
       [not found] ` <1444783477-3175-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
  2015-10-14  0:44   ` [PATCH v3 1/9] pci: add gk104 variant Karol Herbst
@ 2015-10-14  0:44   ` Karol Herbst
  2015-10-14  0:44   ` [PATCH v3 3/9] pci: implement generic code for PCIe speed change Karol Herbst
                     ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Karol Herbst @ 2015-10-14  0: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] 10+ messages in thread

* [PATCH v3 3/9] pci: implement generic code for PCIe speed change
       [not found] ` <1444783477-3175-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
  2015-10-14  0:44   ` [PATCH v3 1/9] pci: add gk104 variant Karol Herbst
  2015-10-14  0:44   ` [PATCH v3 2/9] pci: add gf106 variant Karol Herbst
@ 2015-10-14  0:44   ` Karol Herbst
  2015-10-14  0:44   ` [PATCH v3 4/9] pci: implement pcie speed change for tesla Karol Herbst
                     ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Karol Herbst @ 2015-10-14  0: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] 10+ messages in thread

* [PATCH v3 4/9] pci: implement pcie speed change for tesla
       [not found] ` <1444783477-3175-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (2 preceding siblings ...)
  2015-10-14  0:44   ` [PATCH v3 3/9] pci: implement generic code for PCIe speed change Karol Herbst
@ 2015-10-14  0:44   ` Karol Herbst
  2015-10-14  0:44   ` [PATCH v3 5/9] pci: implement pcie speed change on Fermi Karol Herbst
                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Karol Herbst @ 2015-10-14  0:44 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

v2: rename functions and simplify init
v3: give g84/6 their own implementation

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/nvkm/subdev/pci/g84.c   | 97 +++++++++++++++++++++++++++++++++++++
 drm/nouveau/nvkm/subdev/pci/g94.c   | 18 +++++++
 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  | 10 ++++
 6 files changed, 137 insertions(+)

diff --git a/drm/nouveau/nvkm/subdev/pci/g84.c b/drm/nouveau/nvkm/subdev/pci/g84.c
index 3faa6bf..521f9c2 100644
--- a/drm/nouveau/nvkm/subdev/pci/g84.c
+++ b/drm/nouveau/nvkm/subdev/pci/g84.c
@@ -25,6 +25,86 @@
 
 #include <core/pci.h>
 
+static int
+g84_pcie_version_supported(struct nvkm_pci *pci)
+{
+	/* g84 and g86 report wrong information about what they support */
+	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 +128,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 +142,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..4344412 100644
--- a/drm/nouveau/nvkm/subdev/pci/g94.c
+++ b/drm/nouveau/nvkm/subdev/pci/g94.c
@@ -23,6 +23,14 @@
  */
 #include "priv.h"
 
+int
+g94_pcie_version_supported(struct nvkm_pci *pci)
+{
+	if ((nvkm_pci_rd32(pci, 0x460) & 0x200) == 0x200)
+		return 2;
+	return 1;
+}
+
 static const struct nvkm_pci_func
 g94_pci_func = {
 	.init = g84_pci_init,
@@ -30,6 +38,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 = g94_pcie_version_supported,
 };
 
 int
diff --git a/drm/nouveau/nvkm/subdev/pci/gf100.c b/drm/nouveau/nvkm/subdev/pci/gf100.c
index 25e1ae7..5e57c0b 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 = g94_pcie_version_supported,
 };
 
 int
diff --git a/drm/nouveau/nvkm/subdev/pci/gf106.c b/drm/nouveau/nvkm/subdev/pci/gf106.c
index 82d8c27..994cdfd 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 = g94_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..ea496aa 100644
--- a/drm/nouveau/nvkm/subdev/pci/priv.h
+++ b/drm/nouveau/nvkm/subdev/pci/priv.h
@@ -36,5 +36,15 @@ 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 *);
+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 g94_pcie_version_supported(struct nvkm_pci *);
+
 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] 10+ messages in thread

* [PATCH v3 5/9] pci: implement pcie speed change on Fermi
       [not found] ` <1444783477-3175-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (3 preceding siblings ...)
  2015-10-14  0:44   ` [PATCH v3 4/9] pci: implement pcie speed change for tesla Karol Herbst
@ 2015-10-14  0:44   ` Karol Herbst
  2015-10-14  0:44   ` [PATCH v3 6/9] pci: implement PCIe speed change for kepler+ Karol Herbst
                     ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Karol Herbst @ 2015-10-14  0: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 5e57c0b..cfc866e 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 = g94_pcie_version_supported,
 };
 
diff --git a/drm/nouveau/nvkm/subdev/pci/gf106.c b/drm/nouveau/nvkm/subdev/pci/gf106.c
index 994cdfd..440d81b 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 = g94_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 ea496aa..cac279a 100644
--- a/drm/nouveau/nvkm/subdev/pci/priv.h
+++ b/drm/nouveau/nvkm/subdev/pci/priv.h
@@ -46,5 +46,12 @@ int g84_pcie_set_link(struct nvkm_pci *, enum nvkm_pcie_speed, u8);
 
 int g94_pcie_version_supported(struct nvkm_pci *);
 
+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] 10+ messages in thread

* [PATCH v3 6/9] pci: implement PCIe speed change for kepler+
       [not found] ` <1444783477-3175-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (4 preceding siblings ...)
  2015-10-14  0:44   ` [PATCH v3 5/9] pci: implement pcie speed change on Fermi Karol Herbst
@ 2015-10-14  0:44   ` Karol Herbst
  2015-10-14  0:44   ` [PATCH v3 7/9] bios/perf: parse the pci speed from the bios for tesla and newer cards Karol Herbst
                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Karol Herbst @ 2015-10-14  0:44 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

v2: rename functions
v3: remove pcie2 accessors

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/nvkm/subdev/pci/gk104.c | 186 ++++++++++++++++++++++++++++++++++++
 1 file changed, 186 insertions(+)

diff --git a/drm/nouveau/nvkm/subdev/pci/gk104.c b/drm/nouveau/nvkm/subdev/pci/gk104.c
index 458dd31..b752b6d 100644
--- a/drm/nouveau/nvkm/subdev/pci/gk104.c
+++ b/drm/nouveau/nvkm/subdev/pci/gk104.c
@@ -23,6 +23,187 @@
  */
 #include "priv.h"
 
+static int
+gk104_pcie_version_supported(struct nvkm_pci *pci)
+{
+	return (nvkm_rd32(pci->subdev.device, 0x8c1c0) & 0x4) == 0x4 ? 2 : 1;
+}
+
+static void
+gk104_pcie_set_cap_speed(struct nvkm_pci *pci, enum nvkm_pcie_speed speed)
+{
+	struct nvkm_device *device = pci->subdev.device;
+
+	switch (speed) {
+	case NVKM_PCIE_SPEED_2_5:
+		gf100_pcie_set_cap_speed(pci, false);
+		nvkm_mask(device, 0x8c1c0, 0x30000, 0x10000);
+		break;
+	case NVKM_PCIE_SPEED_5_0:
+		gf100_pcie_set_cap_speed(pci, true);
+		nvkm_mask(device, 0x8c1c0, 0x30000, 0x20000);
+		break;
+	case NVKM_PCIE_SPEED_8_0:
+		gf100_pcie_set_cap_speed(pci, true);
+		nvkm_mask(device, 0x8c1c0, 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 = nvkm_rd32(pci->subdev.device, 0x8c1c0) & 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 = nvkm_rd32(pci->subdev.device, 0x8c1c0) & 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)
+{
+	struct nvkm_device *device = pci->subdev.device;
+	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;
+	}
+	nvkm_mask(device, 0x8c040, 0xc0000, mask_value);
+	nvkm_mask(device, 0x8c040, 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 +211,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] 10+ messages in thread

* [PATCH v3 7/9] bios/perf: parse the pci speed from the bios for tesla and newer cards
       [not found] ` <1444783477-3175-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (5 preceding siblings ...)
  2015-10-14  0:44   ` [PATCH v3 6/9] pci: implement PCIe speed change for kepler+ Karol Herbst
@ 2015-10-14  0:44   ` Karol Herbst
  2015-10-14  0:44   ` [PATCH v3 8/9] perf: add fields for pci speed and width and use it for the pstates Karol Herbst
  2015-10-14  0:44   ` [PATCH v3 9/9] perf: change pcie speed on pstate change Karol Herbst
  8 siblings, 0 replies; 10+ messages in thread
From: Karol Herbst @ 2015-10-14  0: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] 10+ messages in thread

* [PATCH v3 8/9] perf: add fields for pci speed and width and use it for the pstates
       [not found] ` <1444783477-3175-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (6 preceding siblings ...)
  2015-10-14  0:44   ` [PATCH v3 7/9] bios/perf: parse the pci speed from the bios for tesla and newer cards Karol Herbst
@ 2015-10-14  0:44   ` Karol Herbst
  2015-10-14  0:44   ` [PATCH v3 9/9] perf: change pcie speed on pstate change Karol Herbst
  8 siblings, 0 replies; 10+ messages in thread
From: Karol Herbst @ 2015-10-14  0: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] 10+ messages in thread

* [PATCH v3 9/9] perf: change pcie speed on pstate change
       [not found] ` <1444783477-3175-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (7 preceding siblings ...)
  2015-10-14  0:44   ` [PATCH v3 8/9] perf: add fields for pci speed and width and use it for the pstates Karol Herbst
@ 2015-10-14  0:44   ` Karol Herbst
  8 siblings, 0 replies; 10+ messages in thread
From: Karol Herbst @ 2015-10-14  0: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] 10+ messages in thread

end of thread, other threads:[~2015-10-14  0:44 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-14  0:44 [PATCH v3 0/9] PCIEs speed change Karol Herbst
     [not found] ` <1444783477-3175-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
2015-10-14  0:44   ` [PATCH v3 1/9] pci: add gk104 variant Karol Herbst
2015-10-14  0:44   ` [PATCH v3 2/9] pci: add gf106 variant Karol Herbst
2015-10-14  0:44   ` [PATCH v3 3/9] pci: implement generic code for PCIe speed change Karol Herbst
2015-10-14  0:44   ` [PATCH v3 4/9] pci: implement pcie speed change for tesla Karol Herbst
2015-10-14  0:44   ` [PATCH v3 5/9] pci: implement pcie speed change on Fermi Karol Herbst
2015-10-14  0:44   ` [PATCH v3 6/9] pci: implement PCIe speed change for kepler+ Karol Herbst
2015-10-14  0:44   ` [PATCH v3 7/9] bios/perf: parse the pci speed from the bios for tesla and newer cards Karol Herbst
2015-10-14  0:44   ` [PATCH v3 8/9] perf: add fields for pci speed and width and use it for the pstates Karol Herbst
2015-10-14  0:44   ` [PATCH v3 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.