diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-02-23 23:17:49 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-03-26 00:00:58 -0400 |
commit | f6bad8abc61b70c484ee4be5ffef6157136a8f40 (patch) | |
tree | dd5ab66e6be6d158725ff1e2cc214103bf68a27c | |
parent | 6bd9293ea8aa4c9ff8a7ea228b41df188ad8e2c0 (diff) |
drm/gm107/ltcg: initial implementation
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/Makefile | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/device/nvc0.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/device/nve0.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/ltcg/gf100.c (renamed from drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c) | 109 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/ltcg/gf100.h | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/ltcg/gm107.c | 142 |
7 files changed, 231 insertions, 75 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index bd55b96d1cf6..266551b27033 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile | |||
@@ -139,7 +139,8 @@ nouveau-y += core/subdev/instmem/base.o | |||
139 | nouveau-y += core/subdev/instmem/nv04.o | 139 | nouveau-y += core/subdev/instmem/nv04.o |
140 | nouveau-y += core/subdev/instmem/nv40.o | 140 | nouveau-y += core/subdev/instmem/nv40.o |
141 | nouveau-y += core/subdev/instmem/nv50.o | 141 | nouveau-y += core/subdev/instmem/nv50.o |
142 | nouveau-y += core/subdev/ltcg/nvc0.o | 142 | nouveau-y += core/subdev/ltcg/gf100.o |
143 | nouveau-y += core/subdev/ltcg/gm107.o | ||
143 | nouveau-y += core/subdev/mc/base.o | 144 | nouveau-y += core/subdev/mc/base.o |
144 | nouveau-y += core/subdev/mc/nv04.o | 145 | nouveau-y += core/subdev/mc/nv04.o |
145 | nouveau-y += core/subdev/mc/nv40.o | 146 | nouveau-y += core/subdev/mc/nv40.o |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c index 79520995223c..78f4bfd6686f 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c | |||
@@ -70,7 +70,7 @@ nvc0_identify(struct nouveau_device *device) | |||
70 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | 70 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; |
71 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 71 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
72 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; | 72 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; |
73 | device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; | 73 | device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; |
74 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; | 74 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; |
75 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | 75 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; |
76 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | 76 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; |
@@ -102,7 +102,7 @@ nvc0_identify(struct nouveau_device *device) | |||
102 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | 102 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; |
103 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 103 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
104 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; | 104 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; |
105 | device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; | 105 | device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; |
106 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; | 106 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; |
107 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | 107 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; |
108 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | 108 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; |
@@ -134,7 +134,7 @@ nvc0_identify(struct nouveau_device *device) | |||
134 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | 134 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; |
135 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 135 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
136 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; | 136 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; |
137 | device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; | 137 | device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; |
138 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; | 138 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; |
139 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | 139 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; |
140 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | 140 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; |
@@ -165,7 +165,7 @@ nvc0_identify(struct nouveau_device *device) | |||
165 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | 165 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; |
166 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 166 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
167 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; | 167 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; |
168 | device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; | 168 | device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; |
169 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; | 169 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; |
170 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | 170 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; |
171 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | 171 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; |
@@ -197,7 +197,7 @@ nvc0_identify(struct nouveau_device *device) | |||
197 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | 197 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; |
198 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 198 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
199 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; | 199 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; |
200 | device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; | 200 | device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; |
201 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; | 201 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; |
202 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | 202 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; |
203 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | 203 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; |
@@ -229,7 +229,7 @@ nvc0_identify(struct nouveau_device *device) | |||
229 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | 229 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; |
230 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 230 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
231 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; | 231 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; |
232 | device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; | 232 | device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; |
233 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; | 233 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; |
234 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | 234 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; |
235 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | 235 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; |
@@ -260,7 +260,7 @@ nvc0_identify(struct nouveau_device *device) | |||
260 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | 260 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; |
261 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 261 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
262 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; | 262 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; |
263 | device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; | 263 | device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; |
264 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; | 264 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; |
265 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | 265 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; |
266 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | 266 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; |
@@ -292,7 +292,7 @@ nvc0_identify(struct nouveau_device *device) | |||
292 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | 292 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; |
293 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 293 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
294 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; | 294 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; |
295 | device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; | 295 | device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; |
296 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; | 296 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; |
297 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | 297 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; |
298 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | 298 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; |
@@ -323,7 +323,7 @@ nvc0_identify(struct nouveau_device *device) | |||
323 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | 323 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; |
324 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 324 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
325 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; | 325 | device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; |
326 | device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; | 326 | device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; |
327 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; | 327 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; |
328 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | 328 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; |
329 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | 329 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c index d3aff6088370..9784cbf8a9d2 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c | |||
@@ -70,7 +70,7 @@ nve0_identify(struct nouveau_device *device) | |||
70 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | 70 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; |
71 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 71 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
72 | device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; | 72 | device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; |
73 | device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; | 73 | device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; |
74 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; | 74 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; |
75 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | 75 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; |
76 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | 76 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; |
@@ -103,7 +103,7 @@ nve0_identify(struct nouveau_device *device) | |||
103 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | 103 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; |
104 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 104 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
105 | device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; | 105 | device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; |
106 | device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; | 106 | device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; |
107 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; | 107 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; |
108 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | 108 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; |
109 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | 109 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; |
@@ -136,7 +136,7 @@ nve0_identify(struct nouveau_device *device) | |||
136 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | 136 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; |
137 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 137 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
138 | device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; | 138 | device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; |
139 | device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; | 139 | device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; |
140 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; | 140 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; |
141 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | 141 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; |
142 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | 142 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; |
@@ -169,7 +169,7 @@ nve0_identify(struct nouveau_device *device) | |||
169 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | 169 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; |
170 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 170 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
171 | device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; | 171 | device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; |
172 | device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; | 172 | device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; |
173 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; | 173 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; |
174 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | 174 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; |
175 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | 175 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; |
@@ -204,7 +204,7 @@ nve0_identify(struct nouveau_device *device) | |||
204 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | 204 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; |
205 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 205 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
206 | device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; | 206 | device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; |
207 | device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; | 207 | device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; |
208 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; | 208 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; |
209 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | 209 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; |
210 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | 210 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; |
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h b/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h index a1985ed3d58d..c9c1950b7743 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h | |||
@@ -35,6 +35,7 @@ nouveau_ltcg(void *obj) | |||
35 | #define _nouveau_ltcg_init _nouveau_subdev_init | 35 | #define _nouveau_ltcg_init _nouveau_subdev_init |
36 | #define _nouveau_ltcg_fini _nouveau_subdev_fini | 36 | #define _nouveau_ltcg_fini _nouveau_subdev_fini |
37 | 37 | ||
38 | extern struct nouveau_oclass nvc0_ltcg_oclass; | 38 | extern struct nouveau_oclass *gf100_ltcg_oclass; |
39 | extern struct nouveau_oclass *gm107_ltcg_oclass; | ||
39 | 40 | ||
40 | #endif | 41 | #endif |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/ltcg/gf100.c index cce65cc56514..f2f3338a967a 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/ltcg/gf100.c | |||
@@ -22,44 +22,35 @@ | |||
22 | * Authors: Ben Skeggs | 22 | * Authors: Ben Skeggs |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <subdev/ltcg.h> | ||
26 | #include <subdev/fb.h> | 25 | #include <subdev/fb.h> |
27 | #include <subdev/timer.h> | 26 | #include <subdev/timer.h> |
28 | 27 | ||
29 | struct nvc0_ltcg_priv { | 28 | #include "gf100.h" |
30 | struct nouveau_ltcg base; | ||
31 | u32 part_nr; | ||
32 | u32 subp_nr; | ||
33 | u32 num_tags; | ||
34 | u32 tag_base; | ||
35 | struct nouveau_mm tags; | ||
36 | struct nouveau_mm_node *tag_ram; | ||
37 | }; | ||
38 | 29 | ||
39 | static void | 30 | static void |
40 | nvc0_ltcg_subp_isr(struct nvc0_ltcg_priv *priv, int unit, int subp) | 31 | gf100_ltcg_lts_isr(struct gf100_ltcg_priv *priv, int ltc, int lts) |
41 | { | 32 | { |
42 | u32 subp_base = 0x141000 + (unit * 0x2000) + (subp * 0x400); | 33 | u32 base = 0x141000 + (ltc * 0x2000) + (lts * 0x400); |
43 | u32 stat = nv_rd32(priv, subp_base + 0x020); | 34 | u32 stat = nv_rd32(priv, base + 0x020); |
44 | 35 | ||
45 | if (stat) { | 36 | if (stat) { |
46 | nv_info(priv, "LTC%d_LTS%d: 0x%08x\n", unit, subp, stat); | 37 | nv_info(priv, "LTC%d_LTS%d: 0x%08x\n", ltc, lts, stat); |
47 | nv_wr32(priv, subp_base + 0x020, stat); | 38 | nv_wr32(priv, base + 0x020, stat); |
48 | } | 39 | } |
49 | } | 40 | } |
50 | 41 | ||
51 | static void | 42 | static void |
52 | nvc0_ltcg_intr(struct nouveau_subdev *subdev) | 43 | gf100_ltcg_intr(struct nouveau_subdev *subdev) |
53 | { | 44 | { |
54 | struct nvc0_ltcg_priv *priv = (void *)subdev; | 45 | struct gf100_ltcg_priv *priv = (void *)subdev; |
55 | u32 units; | 46 | u32 mask; |
56 | 47 | ||
57 | units = nv_rd32(priv, 0x00017c); | 48 | mask = nv_rd32(priv, 0x00017c); |
58 | while (units) { | 49 | while (mask) { |
59 | u32 subp, unit = ffs(units) - 1; | 50 | u32 lts, ltc = __ffs(mask); |
60 | for (subp = 0; subp < priv->subp_nr; subp++) | 51 | for (lts = 0; lts < priv->lts_nr; lts++) |
61 | nvc0_ltcg_subp_isr(priv, unit, subp); | 52 | gf100_ltcg_lts_isr(priv, ltc, lts); |
62 | units &= ~(1 << unit); | 53 | mask &= ~(1 << ltc); |
63 | } | 54 | } |
64 | 55 | ||
65 | /* we do something horribly wrong and upset PMFB a lot, so mask off | 56 | /* we do something horribly wrong and upset PMFB a lot, so mask off |
@@ -68,11 +59,11 @@ nvc0_ltcg_intr(struct nouveau_subdev *subdev) | |||
68 | nv_mask(priv, 0x000640, 0x02000000, 0x00000000); | 59 | nv_mask(priv, 0x000640, 0x02000000, 0x00000000); |
69 | } | 60 | } |
70 | 61 | ||
71 | static int | 62 | int |
72 | nvc0_ltcg_tags_alloc(struct nouveau_ltcg *ltcg, u32 n, | 63 | gf100_ltcg_tags_alloc(struct nouveau_ltcg *ltcg, u32 n, |
73 | struct nouveau_mm_node **pnode) | 64 | struct nouveau_mm_node **pnode) |
74 | { | 65 | { |
75 | struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; | 66 | struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; |
76 | int ret; | 67 | int ret; |
77 | 68 | ||
78 | ret = nouveau_mm_head(&priv->tags, 1, n, n, 1, pnode); | 69 | ret = nouveau_mm_head(&priv->tags, 1, n, n, 1, pnode); |
@@ -82,18 +73,18 @@ nvc0_ltcg_tags_alloc(struct nouveau_ltcg *ltcg, u32 n, | |||
82 | return ret; | 73 | return ret; |
83 | } | 74 | } |
84 | 75 | ||
85 | static void | 76 | void |
86 | nvc0_ltcg_tags_free(struct nouveau_ltcg *ltcg, struct nouveau_mm_node **pnode) | 77 | gf100_ltcg_tags_free(struct nouveau_ltcg *ltcg, struct nouveau_mm_node **pnode) |
87 | { | 78 | { |
88 | struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; | 79 | struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; |
89 | 80 | ||
90 | nouveau_mm_free(&priv->tags, pnode); | 81 | nouveau_mm_free(&priv->tags, pnode); |
91 | } | 82 | } |
92 | 83 | ||
93 | static void | 84 | static void |
94 | nvc0_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count) | 85 | gf100_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count) |
95 | { | 86 | { |
96 | struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; | 87 | struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; |
97 | u32 last = first + count - 1; | 88 | u32 last = first + count - 1; |
98 | int p, i; | 89 | int p, i; |
99 | 90 | ||
@@ -104,16 +95,16 @@ nvc0_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count) | |||
104 | nv_wr32(priv, 0x17e8c8, 0x4); /* trigger clear */ | 95 | nv_wr32(priv, 0x17e8c8, 0x4); /* trigger clear */ |
105 | 96 | ||
106 | /* wait until it's finished with clearing */ | 97 | /* wait until it's finished with clearing */ |
107 | for (p = 0; p < priv->part_nr; ++p) { | 98 | for (p = 0; p < priv->ltc_nr; ++p) { |
108 | for (i = 0; i < priv->subp_nr; ++i) | 99 | for (i = 0; i < priv->lts_nr; ++i) |
109 | nv_wait(priv, 0x1410c8 + p * 0x2000 + i * 0x400, ~0, 0); | 100 | nv_wait(priv, 0x1410c8 + p * 0x2000 + i * 0x400, ~0, 0); |
110 | } | 101 | } |
111 | } | 102 | } |
112 | 103 | ||
113 | /* TODO: Figure out tag memory details and drop the over-cautious allocation. | 104 | /* TODO: Figure out tag memory details and drop the over-cautious allocation. |
114 | */ | 105 | */ |
115 | static int | 106 | int |
116 | nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv) | 107 | gf100_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct gf100_ltcg_priv *priv) |
117 | { | 108 | { |
118 | u32 tag_size, tag_margin, tag_align; | 109 | u32 tag_size, tag_margin, tag_align; |
119 | int ret; | 110 | int ret; |
@@ -124,7 +115,7 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv) | |||
124 | priv->num_tags = 1 << 17; /* we have 17 bits in PTE */ | 115 | priv->num_tags = 1 << 17; /* we have 17 bits in PTE */ |
125 | priv->num_tags = (priv->num_tags + 63) & ~63; /* round up to 64 */ | 116 | priv->num_tags = (priv->num_tags + 63) & ~63; /* round up to 64 */ |
126 | 117 | ||
127 | tag_align = priv->part_nr * 0x800; | 118 | tag_align = priv->ltc_nr * 0x800; |
128 | tag_margin = (tag_align < 0x6000) ? 0x6000 : tag_align; | 119 | tag_margin = (tag_align < 0x6000) ? 0x6000 : tag_align; |
129 | 120 | ||
130 | /* 4 part 4 sub: 0x2000 bytes for 56 tags */ | 121 | /* 4 part 4 sub: 0x2000 bytes for 56 tags */ |
@@ -157,11 +148,11 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv) | |||
157 | } | 148 | } |
158 | 149 | ||
159 | static int | 150 | static int |
160 | nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | 151 | gf100_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, |
161 | struct nouveau_oclass *oclass, void *data, u32 size, | 152 | struct nouveau_oclass *oclass, void *data, u32 size, |
162 | struct nouveau_object **pobject) | 153 | struct nouveau_object **pobject) |
163 | { | 154 | { |
164 | struct nvc0_ltcg_priv *priv; | 155 | struct gf100_ltcg_priv *priv; |
165 | struct nouveau_fb *pfb = nouveau_fb(parent); | 156 | struct nouveau_fb *pfb = nouveau_fb(parent); |
166 | u32 parts, mask; | 157 | u32 parts, mask; |
167 | int ret, i; | 158 | int ret, i; |
@@ -175,27 +166,27 @@ nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
175 | mask = nv_rd32(priv, 0x022554); | 166 | mask = nv_rd32(priv, 0x022554); |
176 | for (i = 0; i < parts; i++) { | 167 | for (i = 0; i < parts; i++) { |
177 | if (!(mask & (1 << i))) | 168 | if (!(mask & (1 << i))) |
178 | priv->part_nr++; | 169 | priv->ltc_nr++; |
179 | } | 170 | } |
180 | priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 28; | 171 | priv->lts_nr = nv_rd32(priv, 0x17e8dc) >> 28; |
181 | 172 | ||
182 | ret = nvc0_ltcg_init_tag_ram(pfb, priv); | 173 | ret = gf100_ltcg_init_tag_ram(pfb, priv); |
183 | if (ret) | 174 | if (ret) |
184 | return ret; | 175 | return ret; |
185 | 176 | ||
186 | priv->base.tags_alloc = nvc0_ltcg_tags_alloc; | 177 | priv->base.tags_alloc = gf100_ltcg_tags_alloc; |
187 | priv->base.tags_free = nvc0_ltcg_tags_free; | 178 | priv->base.tags_free = gf100_ltcg_tags_free; |
188 | priv->base.tags_clear = nvc0_ltcg_tags_clear; | 179 | priv->base.tags_clear = gf100_ltcg_tags_clear; |
189 | 180 | ||
190 | nv_subdev(priv)->intr = nvc0_ltcg_intr; | 181 | nv_subdev(priv)->intr = gf100_ltcg_intr; |
191 | return 0; | 182 | return 0; |
192 | } | 183 | } |
193 | 184 | ||
194 | static void | 185 | void |
195 | nvc0_ltcg_dtor(struct nouveau_object *object) | 186 | gf100_ltcg_dtor(struct nouveau_object *object) |
196 | { | 187 | { |
197 | struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object; | 188 | struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object; |
198 | struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; | 189 | struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; |
199 | struct nouveau_fb *pfb = nouveau_fb(ltcg->base.base.parent); | 190 | struct nouveau_fb *pfb = nouveau_fb(ltcg->base.base.parent); |
200 | 191 | ||
201 | nouveau_mm_fini(&priv->tags); | 192 | nouveau_mm_fini(&priv->tags); |
@@ -205,10 +196,10 @@ nvc0_ltcg_dtor(struct nouveau_object *object) | |||
205 | } | 196 | } |
206 | 197 | ||
207 | static int | 198 | static int |
208 | nvc0_ltcg_init(struct nouveau_object *object) | 199 | gf100_ltcg_init(struct nouveau_object *object) |
209 | { | 200 | { |
210 | struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object; | 201 | struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object; |
211 | struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; | 202 | struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; |
212 | int ret; | 203 | int ret; |
213 | 204 | ||
214 | ret = nouveau_ltcg_init(ltcg); | 205 | ret = nouveau_ltcg_init(ltcg); |
@@ -216,20 +207,20 @@ nvc0_ltcg_init(struct nouveau_object *object) | |||
216 | return ret; | 207 | return ret; |
217 | 208 | ||
218 | nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */ | 209 | nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */ |
219 | nv_wr32(priv, 0x17e8d8, priv->part_nr); | 210 | nv_wr32(priv, 0x17e8d8, priv->ltc_nr); |
220 | if (nv_device(ltcg)->card_type >= NV_E0) | 211 | if (nv_device(ltcg)->card_type >= NV_E0) |
221 | nv_wr32(priv, 0x17e000, priv->part_nr); | 212 | nv_wr32(priv, 0x17e000, priv->ltc_nr); |
222 | nv_wr32(priv, 0x17e8d4, priv->tag_base); | 213 | nv_wr32(priv, 0x17e8d4, priv->tag_base); |
223 | return 0; | 214 | return 0; |
224 | } | 215 | } |
225 | 216 | ||
226 | struct nouveau_oclass | 217 | struct nouveau_oclass * |
227 | nvc0_ltcg_oclass = { | 218 | gf100_ltcg_oclass = &(struct nouveau_oclass) { |
228 | .handle = NV_SUBDEV(LTCG, 0xc0), | 219 | .handle = NV_SUBDEV(LTCG, 0xc0), |
229 | .ofuncs = &(struct nouveau_ofuncs) { | 220 | .ofuncs = &(struct nouveau_ofuncs) { |
230 | .ctor = nvc0_ltcg_ctor, | 221 | .ctor = gf100_ltcg_ctor, |
231 | .dtor = nvc0_ltcg_dtor, | 222 | .dtor = gf100_ltcg_dtor, |
232 | .init = nvc0_ltcg_init, | 223 | .init = gf100_ltcg_init, |
233 | .fini = _nouveau_ltcg_fini, | 224 | .fini = _nouveau_ltcg_fini, |
234 | }, | 225 | }, |
235 | }; | 226 | }; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltcg/gf100.h b/drivers/gpu/drm/nouveau/core/subdev/ltcg/gf100.h new file mode 100644 index 000000000000..87b10b8412ea --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/ltcg/gf100.h | |||
@@ -0,0 +1,21 @@ | |||
1 | #ifndef __NVKM_LTCG_PRIV_GF100_H__ | ||
2 | #define __NVKM_LTCG_PRIV_GF100_H__ | ||
3 | |||
4 | #include <subdev/ltcg.h> | ||
5 | |||
6 | struct gf100_ltcg_priv { | ||
7 | struct nouveau_ltcg base; | ||
8 | u32 ltc_nr; | ||
9 | u32 lts_nr; | ||
10 | u32 num_tags; | ||
11 | u32 tag_base; | ||
12 | struct nouveau_mm tags; | ||
13 | struct nouveau_mm_node *tag_ram; | ||
14 | }; | ||
15 | |||
16 | void gf100_ltcg_dtor(struct nouveau_object *); | ||
17 | int gf100_ltcg_init_tag_ram(struct nouveau_fb *, struct gf100_ltcg_priv *); | ||
18 | int gf100_ltcg_tags_alloc(struct nouveau_ltcg *, u32, struct nouveau_mm_node **); | ||
19 | void gf100_ltcg_tags_free(struct nouveau_ltcg *, struct nouveau_mm_node **); | ||
20 | |||
21 | #endif | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltcg/gm107.c b/drivers/gpu/drm/nouveau/core/subdev/ltcg/gm107.c new file mode 100644 index 000000000000..e79d0e81de40 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/ltcg/gm107.c | |||
@@ -0,0 +1,142 @@ | |||
1 | /* | ||
2 | * Copyright 2014 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 | |||
25 | #include <subdev/fb.h> | ||
26 | #include <subdev/timer.h> | ||
27 | |||
28 | #include "gf100.h" | ||
29 | |||
30 | static void | ||
31 | gm107_ltcg_lts_isr(struct gf100_ltcg_priv *priv, int ltc, int lts) | ||
32 | { | ||
33 | u32 base = 0x140000 + (ltc * 0x2000) + (lts * 0x400); | ||
34 | u32 stat = nv_rd32(priv, base + 0x00c); | ||
35 | |||
36 | if (stat) { | ||
37 | nv_info(priv, "LTC%d_LTS%d: 0x%08x\n", ltc, lts, stat); | ||
38 | nv_wr32(priv, base + 0x00c, stat); | ||
39 | } | ||
40 | } | ||
41 | |||
42 | static void | ||
43 | gm107_ltcg_intr(struct nouveau_subdev *subdev) | ||
44 | { | ||
45 | struct gf100_ltcg_priv *priv = (void *)subdev; | ||
46 | u32 mask; | ||
47 | |||
48 | mask = nv_rd32(priv, 0x00017c); | ||
49 | while (mask) { | ||
50 | u32 lts, ltc = __ffs(mask); | ||
51 | for (lts = 0; lts < priv->lts_nr; lts++) | ||
52 | gm107_ltcg_lts_isr(priv, ltc, lts); | ||
53 | mask &= ~(1 << ltc); | ||
54 | } | ||
55 | |||
56 | /* we do something horribly wrong and upset PMFB a lot, so mask off | ||
57 | * interrupts from it after the first one until it's fixed | ||
58 | */ | ||
59 | nv_mask(priv, 0x000640, 0x02000000, 0x00000000); | ||
60 | } | ||
61 | |||
62 | static void | ||
63 | gm107_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count) | ||
64 | { | ||
65 | struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; | ||
66 | u32 last = first + count - 1; | ||
67 | int p, i; | ||
68 | |||
69 | BUG_ON((first > last) || (last >= priv->num_tags)); | ||
70 | |||
71 | nv_wr32(priv, 0x17e270, first); | ||
72 | nv_wr32(priv, 0x17e274, last); | ||
73 | nv_wr32(priv, 0x17e26c, 0x4); /* trigger clear */ | ||
74 | |||
75 | /* wait until it's finished with clearing */ | ||
76 | for (p = 0; p < priv->ltc_nr; ++p) { | ||
77 | for (i = 0; i < priv->lts_nr; ++i) | ||
78 | nv_wait(priv, 0x14046c + p * 0x2000 + i * 0x200, ~0, 0); | ||
79 | } | ||
80 | } | ||
81 | |||
82 | static int | ||
83 | gm107_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | ||
84 | struct nouveau_oclass *oclass, void *data, u32 size, | ||
85 | struct nouveau_object **pobject) | ||
86 | { | ||
87 | struct gf100_ltcg_priv *priv; | ||
88 | struct nouveau_fb *pfb = nouveau_fb(parent); | ||
89 | u32 parts, mask; | ||
90 | int ret, i; | ||
91 | |||
92 | ret = nouveau_ltcg_create(parent, engine, oclass, &priv); | ||
93 | *pobject = nv_object(priv); | ||
94 | if (ret) | ||
95 | return ret; | ||
96 | |||
97 | parts = nv_rd32(priv, 0x022438); | ||
98 | mask = nv_rd32(priv, 0x021c14); | ||
99 | for (i = 0; i < parts; i++) { | ||
100 | if (!(mask & (1 << i))) | ||
101 | priv->ltc_nr++; | ||
102 | } | ||
103 | priv->lts_nr = nv_rd32(priv, 0x17e280) >> 28; | ||
104 | |||
105 | ret = gf100_ltcg_init_tag_ram(pfb, priv); | ||
106 | if (ret) | ||
107 | return ret; | ||
108 | |||
109 | priv->base.tags_alloc = gf100_ltcg_tags_alloc; | ||
110 | priv->base.tags_free = gf100_ltcg_tags_free; | ||
111 | priv->base.tags_clear = gm107_ltcg_tags_clear; | ||
112 | |||
113 | nv_subdev(priv)->intr = gm107_ltcg_intr; | ||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static int | ||
118 | gm107_ltcg_init(struct nouveau_object *object) | ||
119 | { | ||
120 | struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object; | ||
121 | struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; | ||
122 | int ret; | ||
123 | |||
124 | ret = nouveau_ltcg_init(ltcg); | ||
125 | if (ret) | ||
126 | return ret; | ||
127 | |||
128 | nv_wr32(priv, 0x17e27c, priv->ltc_nr); | ||
129 | nv_wr32(priv, 0x17e278, priv->tag_base); | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | struct nouveau_oclass * | ||
134 | gm107_ltcg_oclass = &(struct nouveau_oclass) { | ||
135 | .handle = NV_SUBDEV(LTCG, 0xff), | ||
136 | .ofuncs = &(struct nouveau_ofuncs) { | ||
137 | .ctor = gm107_ltcg_ctor, | ||
138 | .dtor = gf100_ltcg_dtor, | ||
139 | .init = gm107_ltcg_init, | ||
140 | .fini = _nouveau_ltcg_fini, | ||
141 | }, | ||
142 | }; | ||