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 /drivers/gpu | |
| parent | bcc19d9bf5cd8d49428c487adced1aa101271b18 (diff) | |
drm/nouveau/pci: implement pcie speed change for tesla
v5: don't set fermi or kepler func pointers
v6: fix alignment
Diffstat (limited to 'drivers/gpu')
| -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 |
