diff options
author | Karol Herbst <nouveau@karolherbst.de> | 2016-01-05 15:44:18 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2016-01-10 20:30:20 -0500 |
commit | 5cca4bdc0d0518b31c7bf8f5e8a895af01c4c90a (patch) | |
tree | becad663c7629018b82125fd9cec2a0127afcc34 | |
parent | bcc19d9bf5cd8d49428c487adced1aa101271b18 (diff) |
drm/nouveau/pci: implement pcie speed change for tesla
v5: don't set fermi or kepler func pointers
v6: fix alignment
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c | 92 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/pci/priv.h | 10 |
3 files changed, 120 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c index 3faa6bfb895b..62438d892f42 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c | |||
@@ -25,6 +25,80 @@ | |||
25 | 25 | ||
26 | #include <core/pci.h> | 26 | #include <core/pci.h> |
27 | 27 | ||
28 | static int | ||
29 | g84_pcie_version_supported(struct nvkm_pci *pci) | ||
30 | { | ||
31 | /* g84 and g86 report wrong information about what they support */ | ||
32 | return 1; | ||
33 | } | ||
34 | |||
35 | int | ||
36 | g84_pcie_version(struct nvkm_pci *pci) | ||
37 | { | ||
38 | struct nvkm_device *device = pci->subdev.device; | ||
39 | return (nvkm_rd32(device, 0x00154c) & 0x1) + 1; | ||
40 | } | ||
41 | |||
42 | void | ||
43 | g84_pcie_set_version(struct nvkm_pci *pci, u8 ver) | ||
44 | { | ||
45 | struct nvkm_device *device = pci->subdev.device; | ||
46 | nvkm_mask(device, 0x00154c, 0x1, (ver >= 2 ? 0x1 : 0x0)); | ||
47 | } | ||
48 | |||
49 | static void | ||
50 | g84_pcie_set_cap_speed(struct nvkm_pci *pci, bool full_speed) | ||
51 | { | ||
52 | struct nvkm_device *device = pci->subdev.device; | ||
53 | nvkm_mask(device, 0x00154c, 0x80, full_speed ? 0x80 : 0x0); | ||
54 | } | ||
55 | |||
56 | enum nvkm_pcie_speed | ||
57 | g84_pcie_cur_speed(struct nvkm_pci *pci) | ||
58 | { | ||
59 | u32 reg_v = nvkm_pci_rd32(pci, 0x88) & 0x30000; | ||
60 | switch (reg_v) { | ||
61 | case 0x30000: | ||
62 | return NVKM_PCIE_SPEED_8_0; | ||
63 | case 0x20000: | ||
64 | return NVKM_PCIE_SPEED_5_0; | ||
65 | case 0x10000: | ||
66 | default: | ||
67 | return NVKM_PCIE_SPEED_2_5; | ||
68 | } | ||
69 | } | ||
70 | |||
71 | enum nvkm_pcie_speed | ||
72 | g84_pcie_max_speed(struct nvkm_pci *pci) | ||
73 | { | ||
74 | u32 reg_v = nvkm_pci_rd32(pci, 0x460) & 0x3300; | ||
75 | if (reg_v == 0x2200) | ||
76 | return NVKM_PCIE_SPEED_5_0; | ||
77 | return NVKM_PCIE_SPEED_2_5; | ||
78 | } | ||
79 | |||
80 | void | ||
81 | g84_pcie_set_link_speed(struct nvkm_pci *pci, enum nvkm_pcie_speed speed) | ||
82 | { | ||
83 | u32 mask_value; | ||
84 | |||
85 | if (speed == NVKM_PCIE_SPEED_5_0) | ||
86 | mask_value = 0x20; | ||
87 | else | ||
88 | mask_value = 0x10; | ||
89 | |||
90 | nvkm_pci_mask(pci, 0x460, 0x30, mask_value); | ||
91 | nvkm_pci_mask(pci, 0x460, 0x1, 0x1); | ||
92 | } | ||
93 | |||
94 | int | ||
95 | g84_pcie_set_link(struct nvkm_pci *pci, enum nvkm_pcie_speed speed, u8 width) | ||
96 | { | ||
97 | g84_pcie_set_cap_speed(pci, speed == NVKM_PCIE_SPEED_5_0); | ||
98 | g84_pcie_set_link_speed(pci, speed); | ||
99 | return 0; | ||
100 | } | ||
101 | |||
28 | void | 102 | void |
29 | g84_pci_init(struct nvkm_pci *pci) | 103 | g84_pci_init(struct nvkm_pci *pci) |
30 | { | 104 | { |
@@ -48,6 +122,14 @@ g84_pci_init(struct nvkm_pci *pci) | |||
48 | nvkm_pci_mask(pci, 0x041c, 0x00000060, 0x00000000); | 122 | nvkm_pci_mask(pci, 0x041c, 0x00000060, 0x00000000); |
49 | } | 123 | } |
50 | 124 | ||
125 | int | ||
126 | g84_pcie_init(struct nvkm_pci *pci) | ||
127 | { | ||
128 | bool full_speed = g84_pcie_cur_speed(pci) == NVKM_PCIE_SPEED_5_0; | ||
129 | g84_pcie_set_cap_speed(pci, full_speed); | ||
130 | return 0; | ||
131 | } | ||
132 | |||
51 | static const struct nvkm_pci_func | 133 | static const struct nvkm_pci_func |
52 | g84_pci_func = { | 134 | g84_pci_func = { |
53 | .init = g84_pci_init, | 135 | .init = g84_pci_init, |
@@ -55,6 +137,16 @@ g84_pci_func = { | |||
55 | .wr08 = nv40_pci_wr08, | 137 | .wr08 = nv40_pci_wr08, |
56 | .wr32 = nv40_pci_wr32, | 138 | .wr32 = nv40_pci_wr32, |
57 | .msi_rearm = nv46_pci_msi_rearm, | 139 | .msi_rearm = nv46_pci_msi_rearm, |
140 | |||
141 | .pcie.init = g84_pcie_init, | ||
142 | .pcie.set_link = g84_pcie_set_link, | ||
143 | |||
144 | .pcie.max_speed = g84_pcie_max_speed, | ||
145 | .pcie.cur_speed = g84_pcie_cur_speed, | ||
146 | |||
147 | .pcie.set_version = g84_pcie_set_version, | ||
148 | .pcie.version = g84_pcie_version, | ||
149 | .pcie.version_supported = g84_pcie_version_supported, | ||
58 | }; | 150 | }; |
59 | 151 | ||
60 | int | 152 | int |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c index cd311ee311cc..43444123bc04 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c | |||
@@ -23,6 +23,14 @@ | |||
23 | */ | 23 | */ |
24 | #include "priv.h" | 24 | #include "priv.h" |
25 | 25 | ||
26 | int | ||
27 | g94_pcie_version_supported(struct nvkm_pci *pci) | ||
28 | { | ||
29 | if ((nvkm_pci_rd32(pci, 0x460) & 0x200) == 0x200) | ||
30 | return 2; | ||
31 | return 1; | ||
32 | } | ||
33 | |||
26 | static const struct nvkm_pci_func | 34 | static const struct nvkm_pci_func |
27 | g94_pci_func = { | 35 | g94_pci_func = { |
28 | .init = g84_pci_init, | 36 | .init = g84_pci_init, |
@@ -30,6 +38,16 @@ g94_pci_func = { | |||
30 | .wr08 = nv40_pci_wr08, | 38 | .wr08 = nv40_pci_wr08, |
31 | .wr32 = nv40_pci_wr32, | 39 | .wr32 = nv40_pci_wr32, |
32 | .msi_rearm = nv40_pci_msi_rearm, | 40 | .msi_rearm = nv40_pci_msi_rearm, |
41 | |||
42 | .pcie.init = g84_pcie_init, | ||
43 | .pcie.set_link = g84_pcie_set_link, | ||
44 | |||
45 | .pcie.max_speed = g84_pcie_max_speed, | ||
46 | .pcie.cur_speed = g84_pcie_cur_speed, | ||
47 | |||
48 | .pcie.set_version = g84_pcie_set_version, | ||
49 | .pcie.version = g84_pcie_version, | ||
50 | .pcie.version_supported = g94_pcie_version_supported, | ||
33 | }; | 51 | }; |
34 | 52 | ||
35 | int | 53 | int |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/priv.h index 79eb9795dda1..8c389a61d5a1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/priv.h | |||
@@ -36,6 +36,16 @@ void nv46_pci_msi_rearm(struct nvkm_pci *); | |||
36 | void g84_pci_init(struct nvkm_pci *pci); | 36 | void g84_pci_init(struct nvkm_pci *pci); |
37 | 37 | ||
38 | /* pcie functions */ | 38 | /* pcie functions */ |
39 | void g84_pcie_set_version(struct nvkm_pci *, u8); | ||
40 | int g84_pcie_version(struct nvkm_pci *); | ||
41 | void g84_pcie_set_link_speed(struct nvkm_pci *, enum nvkm_pcie_speed); | ||
42 | enum nvkm_pcie_speed g84_pcie_cur_speed(struct nvkm_pci *); | ||
43 | enum nvkm_pcie_speed g84_pcie_max_speed(struct nvkm_pci *); | ||
44 | int g84_pcie_init(struct nvkm_pci *); | ||
45 | int g84_pcie_set_link(struct nvkm_pci *, enum nvkm_pcie_speed, u8); | ||
46 | |||
47 | int g94_pcie_version_supported(struct nvkm_pci *); | ||
48 | |||
39 | int nvkm_pcie_oneinit(struct nvkm_pci *); | 49 | int nvkm_pcie_oneinit(struct nvkm_pci *); |
40 | int nvkm_pcie_init(struct nvkm_pci *); | 50 | int nvkm_pcie_init(struct nvkm_pci *); |
41 | #endif | 51 | #endif |