diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2015-03-20 01:20:17 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2015-04-14 03:00:50 -0400 |
commit | e1fc44fb9dbec4ff4e63c888d206a0bc4ca93f4f (patch) | |
tree | be36af4b234d3ee2abccbbee6c135209a60818f0 | |
parent | d9da545e101312f52706c8b05afbd8f1f875ff81 (diff) |
drm/nouveau/pmu/gk110: implement gr power-up magic like PGOB on earlier chips
Turns out the PTHERM part of this dance is bracketed by the same PMU
fiddling that occurs on GK104/6, let's assume it's also PGOB.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/device/gk104.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c | 39 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/pmu/Kbuild | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c | 95 |
7 files changed, 101 insertions, 44 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h index 7b86acc634a0..755942352557 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h | |||
@@ -35,6 +35,7 @@ extern struct nvkm_oclass *gt215_pmu_oclass; | |||
35 | extern struct nvkm_oclass *gf100_pmu_oclass; | 35 | extern struct nvkm_oclass *gf100_pmu_oclass; |
36 | extern struct nvkm_oclass *gf110_pmu_oclass; | 36 | extern struct nvkm_oclass *gf110_pmu_oclass; |
37 | extern struct nvkm_oclass *gk104_pmu_oclass; | 37 | extern struct nvkm_oclass *gk104_pmu_oclass; |
38 | extern struct nvkm_oclass *gk110_pmu_oclass; | ||
38 | extern struct nvkm_oclass *gk208_pmu_oclass; | 39 | extern struct nvkm_oclass *gk208_pmu_oclass; |
39 | extern struct nvkm_oclass *gk20a_pmu_oclass; | 40 | extern struct nvkm_oclass *gk20a_pmu_oclass; |
40 | 41 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/gk104.c index 8f266a9a34a6..6a9483f65d83 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/gk104.c | |||
@@ -202,7 +202,7 @@ gk104_identify(struct nvkm_device *device) | |||
202 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | 202 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; |
203 | device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass; | 203 | device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass; |
204 | device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass; | 204 | device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass; |
205 | device->oclass[NVDEV_SUBDEV_PMU ] = gf110_pmu_oclass; | 205 | device->oclass[NVDEV_SUBDEV_PMU ] = gk110_pmu_oclass; |
206 | device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; | 206 | device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; |
207 | device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass; | 207 | device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass; |
208 | device->oclass[NVDEV_ENGINE_FIFO ] = gk104_fifo_oclass; | 208 | device->oclass[NVDEV_ENGINE_FIFO ] = gk104_fifo_oclass; |
@@ -236,7 +236,7 @@ gk104_identify(struct nvkm_device *device) | |||
236 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | 236 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; |
237 | device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass; | 237 | device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass; |
238 | device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass; | 238 | device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass; |
239 | device->oclass[NVDEV_SUBDEV_PMU ] = gf110_pmu_oclass; | 239 | device->oclass[NVDEV_SUBDEV_PMU ] = gk110_pmu_oclass; |
240 | device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; | 240 | device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; |
241 | device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass; | 241 | device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass; |
242 | device->oclass[NVDEV_ENGINE_FIFO ] = gk104_fifo_oclass; | 242 | device->oclass[NVDEV_ENGINE_FIFO ] = gk104_fifo_oclass; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index aeeca1be9cf0..fc821825a3cf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | |||
@@ -124,11 +124,8 @@ void gf100_gr_dtor(struct nvkm_object *); | |||
124 | int gf100_gr_init(struct nvkm_object *); | 124 | int gf100_gr_init(struct nvkm_object *); |
125 | void gf100_gr_zbc_init(struct gf100_gr_priv *); | 125 | void gf100_gr_zbc_init(struct gf100_gr_priv *); |
126 | 126 | ||
127 | int gk104_gr_fini(struct nvkm_object *, bool); | ||
128 | int gk104_gr_init(struct nvkm_object *); | 127 | int gk104_gr_init(struct nvkm_object *); |
129 | 128 | ||
130 | int gk110_gr_fini(struct nvkm_object *, bool); | ||
131 | |||
132 | extern struct nvkm_ofuncs gf100_fermi_ofuncs; | 129 | extern struct nvkm_ofuncs gf100_fermi_ofuncs; |
133 | 130 | ||
134 | extern struct nvkm_oclass gf100_gr_sclass[]; | 131 | extern struct nvkm_oclass gf100_gr_sclass[]; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index 78e03ab1608e..29569ac6b47b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c | |||
@@ -173,43 +173,6 @@ gk110_gr_pack_mmio[] = { | |||
173 | * PGRAPH engine/subdev functions | 173 | * PGRAPH engine/subdev functions |
174 | ******************************************************************************/ | 174 | ******************************************************************************/ |
175 | 175 | ||
176 | int | ||
177 | gk110_gr_fini(struct nvkm_object *object, bool suspend) | ||
178 | { | ||
179 | struct gf100_gr_priv *priv = (void *)object; | ||
180 | static const struct { | ||
181 | u32 addr; | ||
182 | u32 data; | ||
183 | } magic[] = { | ||
184 | { 0x020520, 0xfffffffc }, | ||
185 | { 0x020524, 0xfffffffe }, | ||
186 | { 0x020524, 0xfffffffc }, | ||
187 | { 0x020524, 0xfffffff8 }, | ||
188 | { 0x020524, 0xffffffe0 }, | ||
189 | { 0x020530, 0xfffffffe }, | ||
190 | { 0x02052c, 0xfffffffa }, | ||
191 | { 0x02052c, 0xfffffff0 }, | ||
192 | { 0x02052c, 0xffffffc0 }, | ||
193 | { 0x02052c, 0xffffff00 }, | ||
194 | { 0x02052c, 0xfffffc00 }, | ||
195 | { 0x02052c, 0xfffcfc00 }, | ||
196 | { 0x02052c, 0xfff0fc00 }, | ||
197 | { 0x02052c, 0xff80fc00 }, | ||
198 | { 0x020528, 0xfffffffe }, | ||
199 | { 0x020528, 0xfffffffc }, | ||
200 | }; | ||
201 | int i; | ||
202 | |||
203 | nv_mask(priv, 0x000200, 0x08001000, 0x00000000); | ||
204 | nv_mask(priv, 0x0206b4, 0x00000000, 0x00000000); | ||
205 | for (i = 0; i < ARRAY_SIZE(magic); i++) { | ||
206 | nv_wr32(priv, magic[i].addr, magic[i].data); | ||
207 | nv_wait(priv, magic[i].addr, 0x80000000, 0x00000000); | ||
208 | } | ||
209 | |||
210 | return nvkm_gr_fini(&priv->base, suspend); | ||
211 | } | ||
212 | |||
213 | #include "fuc/hubgk110.fuc3.h" | 176 | #include "fuc/hubgk110.fuc3.h" |
214 | 177 | ||
215 | struct gf100_gr_ucode | 178 | struct gf100_gr_ucode |
@@ -237,7 +200,7 @@ gk110_gr_oclass = &(struct gf100_gr_oclass) { | |||
237 | .ctor = gf100_gr_ctor, | 200 | .ctor = gf100_gr_ctor, |
238 | .dtor = gf100_gr_dtor, | 201 | .dtor = gf100_gr_dtor, |
239 | .init = gk104_gr_init, | 202 | .init = gk104_gr_init, |
240 | .fini = gk110_gr_fini, | 203 | .fini = _nvkm_gr_fini, |
241 | }, | 204 | }, |
242 | .cclass = &gk110_grctx_oclass, | 205 | .cclass = &gk110_grctx_oclass, |
243 | .sclass = gk110_gr_sclass, | 206 | .sclass = gk110_gr_sclass, |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index 5292c5a9a38c..7771451af50b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c | |||
@@ -105,7 +105,7 @@ gk110b_gr_oclass = &(struct gf100_gr_oclass) { | |||
105 | .ctor = gf100_gr_ctor, | 105 | .ctor = gf100_gr_ctor, |
106 | .dtor = gf100_gr_dtor, | 106 | .dtor = gf100_gr_dtor, |
107 | .init = gk104_gr_init, | 107 | .init = gk104_gr_init, |
108 | .fini = gk110_gr_fini, | 108 | .fini = _nvkm_gr_fini, |
109 | }, | 109 | }, |
110 | .cclass = &gk110b_grctx_oclass, | 110 | .cclass = &gk110b_grctx_oclass, |
111 | .sclass = gk110_gr_sclass, | 111 | .sclass = gk110_gr_sclass, |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/Kbuild index 9a150d520225..7081d6a9b95f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/Kbuild | |||
@@ -4,5 +4,6 @@ nvkm-y += nvkm/subdev/pmu/gt215.o | |||
4 | nvkm-y += nvkm/subdev/pmu/gf100.o | 4 | nvkm-y += nvkm/subdev/pmu/gf100.o |
5 | nvkm-y += nvkm/subdev/pmu/gf110.o | 5 | nvkm-y += nvkm/subdev/pmu/gf110.o |
6 | nvkm-y += nvkm/subdev/pmu/gk104.o | 6 | nvkm-y += nvkm/subdev/pmu/gk104.o |
7 | nvkm-y += nvkm/subdev/pmu/gk110.o | ||
7 | nvkm-y += nvkm/subdev/pmu/gk208.o | 8 | nvkm-y += nvkm/subdev/pmu/gk208.o |
8 | nvkm-y += nvkm/subdev/pmu/gk20a.o | 9 | nvkm-y += nvkm/subdev/pmu/gk20a.o |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c new file mode 100644 index 000000000000..e318745b8274 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * Copyright 2015 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs | ||
23 | */ | ||
24 | #define gf110_pmu_code gk110_pmu_code | ||
25 | #define gf110_pmu_data gk110_pmu_data | ||
26 | #include "priv.h" | ||
27 | #include "fuc/gf110.fuc4.h" | ||
28 | |||
29 | #include <subdev/timer.h> | ||
30 | |||
31 | static void | ||
32 | gk110_pmu_pgob(struct nvkm_pmu *pmu, bool enable) | ||
33 | { | ||
34 | static const struct { | ||
35 | u32 addr; | ||
36 | u32 data; | ||
37 | } magic[] = { | ||
38 | { 0x020520, 0xfffffffc }, | ||
39 | { 0x020524, 0xfffffffe }, | ||
40 | { 0x020524, 0xfffffffc }, | ||
41 | { 0x020524, 0xfffffff8 }, | ||
42 | { 0x020524, 0xffffffe0 }, | ||
43 | { 0x020530, 0xfffffffe }, | ||
44 | { 0x02052c, 0xfffffffa }, | ||
45 | { 0x02052c, 0xfffffff0 }, | ||
46 | { 0x02052c, 0xffffffc0 }, | ||
47 | { 0x02052c, 0xffffff00 }, | ||
48 | { 0x02052c, 0xfffffc00 }, | ||
49 | { 0x02052c, 0xfffcfc00 }, | ||
50 | { 0x02052c, 0xfff0fc00 }, | ||
51 | { 0x02052c, 0xff80fc00 }, | ||
52 | { 0x020528, 0xfffffffe }, | ||
53 | { 0x020528, 0xfffffffc }, | ||
54 | }; | ||
55 | int i; | ||
56 | |||
57 | nv_mask(pmu, 0x000200, 0x00001000, 0x00000000); | ||
58 | nv_rd32(pmu, 0x000200); | ||
59 | nv_mask(pmu, 0x000200, 0x08000000, 0x08000000); | ||
60 | msleep(50); | ||
61 | |||
62 | nv_mask(pmu, 0x10a78c, 0x00000002, 0x00000002); | ||
63 | nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000001); | ||
64 | nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000000); | ||
65 | |||
66 | nv_mask(pmu, 0x0206b4, 0x00000000, 0x00000000); | ||
67 | for (i = 0; i < ARRAY_SIZE(magic); i++) { | ||
68 | nv_wr32(pmu, magic[i].addr, magic[i].data); | ||
69 | nv_wait(pmu, magic[i].addr, 0x80000000, 0x00000000); | ||
70 | } | ||
71 | |||
72 | nv_mask(pmu, 0x10a78c, 0x00000002, 0x00000000); | ||
73 | nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000001); | ||
74 | nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000000); | ||
75 | |||
76 | nv_mask(pmu, 0x000200, 0x08000000, 0x00000000); | ||
77 | nv_mask(pmu, 0x000200, 0x00001000, 0x00001000); | ||
78 | nv_rd32(pmu, 0x000200); | ||
79 | } | ||
80 | |||
81 | struct nvkm_oclass * | ||
82 | gk110_pmu_oclass = &(struct nvkm_pmu_impl) { | ||
83 | .base.handle = NV_SUBDEV(PMU, 0xf0), | ||
84 | .base.ofuncs = &(struct nvkm_ofuncs) { | ||
85 | .ctor = _nvkm_pmu_ctor, | ||
86 | .dtor = _nvkm_pmu_dtor, | ||
87 | .init = _nvkm_pmu_init, | ||
88 | .fini = _nvkm_pmu_fini, | ||
89 | }, | ||
90 | .code.data = gk110_pmu_code, | ||
91 | .code.size = sizeof(gk110_pmu_code), | ||
92 | .data.data = gk110_pmu_data, | ||
93 | .data.size = sizeof(gk110_pmu_data), | ||
94 | .pgob = gk110_pmu_pgob, | ||
95 | }.base; | ||