diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-08-09 14:10:22 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-08-09 15:13:14 -0400 |
commit | 0ad72863ea426d46b2786cba9430e122a40aad0b (patch) | |
tree | bbb9346e53a5e0c16674f4e43807cad013c6cc25 /drivers/gpu/drm/nouveau/nv50_display.c | |
parent | 967e7bde8739fe3b215f7537e8f1f39c044902af (diff) |
drm/nouveau: port to nvif client/device/objects
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv50_display.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.c | 244 |
1 files changed, 119 insertions, 125 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 376b23530c00..ca8c1db0ccb4 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
@@ -37,15 +37,8 @@ | |||
37 | #include "nouveau_fence.h" | 37 | #include "nouveau_fence.h" |
38 | #include "nv50_display.h" | 38 | #include "nv50_display.h" |
39 | 39 | ||
40 | #include <core/client.h> | ||
41 | #include <core/gpuobj.h> | ||
42 | #include <core/class.h> | 40 | #include <core/class.h> |
43 | 41 | ||
44 | #include <subdev/timer.h> | ||
45 | #include <subdev/bar.h> | ||
46 | #include <subdev/fb.h> | ||
47 | #include <subdev/i2c.h> | ||
48 | |||
49 | #define EVO_DMA_NR 9 | 42 | #define EVO_DMA_NR 9 |
50 | 43 | ||
51 | #define EVO_MASTER (0x00) | 44 | #define EVO_MASTER (0x00) |
@@ -62,7 +55,7 @@ | |||
62 | 55 | ||
63 | #define EVO_CORE_HANDLE (0xd1500000) | 56 | #define EVO_CORE_HANDLE (0xd1500000) |
64 | #define EVO_CHAN_HANDLE(t,i) (0xd15c0000 | (((t) & 0x00ff) << 8) | (i)) | 57 | #define EVO_CHAN_HANDLE(t,i) (0xd15c0000 | (((t) & 0x00ff) << 8) | (i)) |
65 | #define EVO_CHAN_OCLASS(t,c) ((nv_hclass(c) & 0xff00) | ((t) & 0x00ff)) | 58 | #define EVO_CHAN_OCLASS(t,c) (((c)->oclass & 0xff00) | ((t) & 0x00ff)) |
66 | #define EVO_PUSH_HANDLE(t,i) (0xd15b0000 | (i) | \ | 59 | #define EVO_PUSH_HANDLE(t,i) (0xd15b0000 | (i) | \ |
67 | (((NV50_DISP_##t##_CLASS) & 0x00ff) << 8)) | 60 | (((NV50_DISP_##t##_CLASS) & 0x00ff) << 8)) |
68 | 61 | ||
@@ -71,34 +64,29 @@ | |||
71 | *****************************************************************************/ | 64 | *****************************************************************************/ |
72 | 65 | ||
73 | struct nv50_chan { | 66 | struct nv50_chan { |
74 | struct nouveau_object *user; | 67 | struct nvif_object user; |
75 | u32 handle; | ||
76 | }; | 68 | }; |
77 | 69 | ||
78 | static int | 70 | static int |
79 | nv50_chan_create(struct nouveau_object *core, u32 bclass, u8 head, | 71 | nv50_chan_create(struct nvif_object *disp, u32 bclass, u8 head, |
80 | void *data, u32 size, struct nv50_chan *chan) | 72 | void *data, u32 size, struct nv50_chan *chan) |
81 | { | 73 | { |
82 | struct nouveau_object *client = nv_pclass(core, NV_CLIENT_CLASS); | 74 | const u32 oclass = EVO_CHAN_OCLASS(bclass, disp); |
83 | const u32 oclass = EVO_CHAN_OCLASS(bclass, core); | ||
84 | const u32 handle = EVO_CHAN_HANDLE(bclass, head); | 75 | const u32 handle = EVO_CHAN_HANDLE(bclass, head); |
85 | int ret; | 76 | int ret; |
86 | 77 | ||
87 | ret = nouveau_object_new(client, EVO_CORE_HANDLE, handle, | 78 | ret = nvif_object_init(disp, NULL, handle, oclass, data, size, |
88 | oclass, data, size, &chan->user); | 79 | &chan->user); |
89 | if (ret) | 80 | if (ret) |
90 | return ret; | 81 | return ret; |
91 | 82 | ||
92 | chan->handle = handle; | ||
93 | return 0; | 83 | return 0; |
94 | } | 84 | } |
95 | 85 | ||
96 | static void | 86 | static void |
97 | nv50_chan_destroy(struct nouveau_object *core, struct nv50_chan *chan) | 87 | nv50_chan_destroy(struct nv50_chan *chan) |
98 | { | 88 | { |
99 | struct nouveau_object *client = nv_pclass(core, NV_CLIENT_CLASS); | 89 | nvif_object_fini(&chan->user); |
100 | if (chan->handle) | ||
101 | nouveau_object_del(client, EVO_CORE_HANDLE, chan->handle); | ||
102 | } | 90 | } |
103 | 91 | ||
104 | /****************************************************************************** | 92 | /****************************************************************************** |
@@ -110,16 +98,16 @@ struct nv50_pioc { | |||
110 | }; | 98 | }; |
111 | 99 | ||
112 | static void | 100 | static void |
113 | nv50_pioc_destroy(struct nouveau_object *core, struct nv50_pioc *pioc) | 101 | nv50_pioc_destroy(struct nv50_pioc *pioc) |
114 | { | 102 | { |
115 | nv50_chan_destroy(core, &pioc->base); | 103 | nv50_chan_destroy(&pioc->base); |
116 | } | 104 | } |
117 | 105 | ||
118 | static int | 106 | static int |
119 | nv50_pioc_create(struct nouveau_object *core, u32 bclass, u8 head, | 107 | nv50_pioc_create(struct nvif_object *disp, u32 bclass, u8 head, |
120 | void *data, u32 size, struct nv50_pioc *pioc) | 108 | void *data, u32 size, struct nv50_pioc *pioc) |
121 | { | 109 | { |
122 | return nv50_chan_create(core, bclass, head, data, size, &pioc->base); | 110 | return nv50_chan_create(disp, bclass, head, data, size, &pioc->base); |
123 | } | 111 | } |
124 | 112 | ||
125 | /****************************************************************************** | 113 | /****************************************************************************** |
@@ -131,6 +119,9 @@ struct nv50_dmac { | |||
131 | dma_addr_t handle; | 119 | dma_addr_t handle; |
132 | u32 *ptr; | 120 | u32 *ptr; |
133 | 121 | ||
122 | struct nvif_object sync; | ||
123 | struct nvif_object vram; | ||
124 | |||
134 | /* Protects against concurrent pushbuf access to this channel, lock is | 125 | /* Protects against concurrent pushbuf access to this channel, lock is |
135 | * grabbed by evo_wait (if the pushbuf reservation is successful) and | 126 | * grabbed by evo_wait (if the pushbuf reservation is successful) and |
136 | * dropped again by evo_kick. */ | 127 | * dropped again by evo_kick. */ |
@@ -138,68 +129,73 @@ struct nv50_dmac { | |||
138 | }; | 129 | }; |
139 | 130 | ||
140 | static void | 131 | static void |
141 | nv50_dmac_destroy(struct nouveau_object *core, struct nv50_dmac *dmac) | 132 | nv50_dmac_destroy(struct nv50_dmac *dmac, struct nvif_object *disp) |
142 | { | 133 | { |
134 | nvif_object_fini(&dmac->vram); | ||
135 | nvif_object_fini(&dmac->sync); | ||
136 | |||
137 | nv50_chan_destroy(&dmac->base); | ||
138 | |||
143 | if (dmac->ptr) { | 139 | if (dmac->ptr) { |
144 | struct pci_dev *pdev = nv_device(core)->pdev; | 140 | struct pci_dev *pdev = nvkm_device(nvif_device(disp))->pdev; |
145 | pci_free_consistent(pdev, PAGE_SIZE, dmac->ptr, dmac->handle); | 141 | pci_free_consistent(pdev, PAGE_SIZE, dmac->ptr, dmac->handle); |
146 | } | 142 | } |
147 | |||
148 | nv50_chan_destroy(core, &dmac->base); | ||
149 | } | 143 | } |
150 | 144 | ||
151 | static int | 145 | static int |
152 | nv50_dmac_create(struct nouveau_object *core, u32 bclass, u8 head, | 146 | nv50_dmac_create(struct nvif_object *disp, u32 bclass, u8 head, |
153 | void *data, u32 size, u64 syncbuf, | 147 | void *data, u32 size, u64 syncbuf, |
154 | struct nv50_dmac *dmac) | 148 | struct nv50_dmac *dmac) |
155 | { | 149 | { |
156 | struct nouveau_fb *pfb = nouveau_fb(core); | 150 | struct nouveau_fb *pfb = nvkm_fb(nvif_device(disp)); |
157 | struct nouveau_object *client = nv_pclass(core, NV_CLIENT_CLASS); | 151 | struct nvif_object pushbuf; |
158 | struct nouveau_object *object; | 152 | u32 handle = *(u32 *)data; |
159 | u32 pushbuf = *(u32 *)data; | ||
160 | int ret; | 153 | int ret; |
161 | 154 | ||
162 | mutex_init(&dmac->lock); | 155 | mutex_init(&dmac->lock); |
163 | 156 | ||
164 | dmac->ptr = pci_alloc_consistent(nv_device(core)->pdev, PAGE_SIZE, | 157 | dmac->ptr = pci_alloc_consistent(nvkm_device(nvif_device(disp))->pdev, |
165 | &dmac->handle); | 158 | PAGE_SIZE, &dmac->handle); |
166 | if (!dmac->ptr) | 159 | if (!dmac->ptr) |
167 | return -ENOMEM; | 160 | return -ENOMEM; |
168 | 161 | ||
169 | ret = nouveau_object_new(client, NVDRM_DEVICE, pushbuf, | 162 | ret = nvif_object_init(nvif_object(nvif_device(disp)), NULL, handle, |
170 | NV_DMA_FROM_MEMORY_CLASS, | 163 | NV_DMA_FROM_MEMORY_CLASS, |
171 | &(struct nv_dma_class) { | 164 | &(struct nv_dma_class) { |
172 | .flags = NV_DMA_TARGET_PCI_US | | 165 | .flags = NV_DMA_TARGET_PCI_US | |
173 | NV_DMA_ACCESS_RD, | 166 | NV_DMA_ACCESS_RD, |
174 | .start = dmac->handle + 0x0000, | 167 | .start = dmac->handle + 0x0000, |
175 | .limit = dmac->handle + 0x0fff, | 168 | .limit = dmac->handle + 0x0fff, |
176 | }, sizeof(struct nv_dma_class), &object); | 169 | }, sizeof(struct nv_dma_class), &pushbuf); |
177 | if (ret) | 170 | if (ret) |
178 | return ret; | 171 | return ret; |
179 | 172 | ||
180 | ret = nv50_chan_create(core, bclass, head, data, size, &dmac->base); | 173 | ret = nv50_chan_create(disp, bclass, head, data, size, &dmac->base); |
174 | nvif_object_fini(&pushbuf); | ||
181 | if (ret) | 175 | if (ret) |
182 | return ret; | 176 | return ret; |
183 | 177 | ||
184 | ret = nouveau_object_new(client, dmac->base.handle, NvEvoSync, | 178 | ret = nvif_object_init(&dmac->base.user, NULL, NvEvoSync, |
185 | NV_DMA_IN_MEMORY_CLASS, | 179 | NV_DMA_IN_MEMORY_CLASS, |
186 | &(struct nv_dma_class) { | 180 | &(struct nv_dma_class) { |
187 | .flags = NV_DMA_TARGET_VRAM | | 181 | .flags = NV_DMA_TARGET_VRAM | |
188 | NV_DMA_ACCESS_RDWR, | 182 | NV_DMA_ACCESS_RDWR, |
189 | .start = syncbuf + 0x0000, | 183 | .start = syncbuf + 0x0000, |
190 | .limit = syncbuf + 0x0fff, | 184 | .limit = syncbuf + 0x0fff, |
191 | }, sizeof(struct nv_dma_class), &object); | 185 | }, sizeof(struct nv_dma_class), |
186 | &dmac->sync); | ||
192 | if (ret) | 187 | if (ret) |
193 | return ret; | 188 | return ret; |
194 | 189 | ||
195 | ret = nouveau_object_new(client, dmac->base.handle, NvEvoVRAM, | 190 | ret = nvif_object_init(&dmac->base.user, NULL, NvEvoVRAM, |
196 | NV_DMA_IN_MEMORY_CLASS, | 191 | NV_DMA_IN_MEMORY_CLASS, |
197 | &(struct nv_dma_class) { | 192 | &(struct nv_dma_class) { |
198 | .flags = NV_DMA_TARGET_VRAM | | 193 | .flags = NV_DMA_TARGET_VRAM | |
199 | NV_DMA_ACCESS_RDWR, | 194 | NV_DMA_ACCESS_RDWR, |
200 | .start = 0, | 195 | .start = 0, |
201 | .limit = pfb->ram->size - 1, | 196 | .limit = pfb->ram->size - 1, |
202 | }, sizeof(struct nv_dma_class), &object); | 197 | }, sizeof(struct nv_dma_class), |
198 | &dmac->vram); | ||
203 | if (ret) | 199 | if (ret) |
204 | return ret; | 200 | return ret; |
205 | 201 | ||
@@ -243,10 +239,16 @@ struct nv50_head { | |||
243 | #define nv50_ovly(c) (&nv50_head(c)->ovly) | 239 | #define nv50_ovly(c) (&nv50_head(c)->ovly) |
244 | #define nv50_oimm(c) (&nv50_head(c)->oimm) | 240 | #define nv50_oimm(c) (&nv50_head(c)->oimm) |
245 | #define nv50_chan(c) (&(c)->base.base) | 241 | #define nv50_chan(c) (&(c)->base.base) |
246 | #define nv50_vers(c) nv_mclass(nv50_chan(c)->user) | 242 | #define nv50_vers(c) nv50_chan(c)->user.oclass |
243 | |||
244 | struct nv50_fbdma { | ||
245 | struct list_head head; | ||
246 | struct nvif_object core; | ||
247 | struct nvif_object base[4]; | ||
248 | }; | ||
247 | 249 | ||
248 | struct nv50_disp { | 250 | struct nv50_disp { |
249 | struct nouveau_object *core; | 251 | struct nvif_object *disp; |
250 | struct nv50_mast mast; | 252 | struct nv50_mast mast; |
251 | 253 | ||
252 | struct list_head fbdma; | 254 | struct list_head fbdma; |
@@ -275,16 +277,16 @@ static u32 * | |||
275 | evo_wait(void *evoc, int nr) | 277 | evo_wait(void *evoc, int nr) |
276 | { | 278 | { |
277 | struct nv50_dmac *dmac = evoc; | 279 | struct nv50_dmac *dmac = evoc; |
278 | u32 put = nv_ro32(dmac->base.user, 0x0000) / 4; | 280 | u32 put = nvif_rd32(&dmac->base.user, 0x0000) / 4; |
279 | 281 | ||
280 | mutex_lock(&dmac->lock); | 282 | mutex_lock(&dmac->lock); |
281 | if (put + nr >= (PAGE_SIZE / 4) - 8) { | 283 | if (put + nr >= (PAGE_SIZE / 4) - 8) { |
282 | dmac->ptr[put] = 0x20000000; | 284 | dmac->ptr[put] = 0x20000000; |
283 | 285 | ||
284 | nv_wo32(dmac->base.user, 0x0000, 0x00000000); | 286 | nvif_wr32(&dmac->base.user, 0x0000, 0x00000000); |
285 | if (!nv_wait(dmac->base.user, 0x0004, ~0, 0x00000000)) { | 287 | if (!nvkm_wait(&dmac->base.user, 0x0004, ~0, 0x00000000)) { |
286 | mutex_unlock(&dmac->lock); | 288 | mutex_unlock(&dmac->lock); |
287 | nv_error(dmac->base.user, "channel stalled\n"); | 289 | nv_error(nvkm_object(&dmac->base.user), "channel stalled\n"); |
288 | return NULL; | 290 | return NULL; |
289 | } | 291 | } |
290 | 292 | ||
@@ -298,7 +300,7 @@ static void | |||
298 | evo_kick(u32 *push, void *evoc) | 300 | evo_kick(u32 *push, void *evoc) |
299 | { | 301 | { |
300 | struct nv50_dmac *dmac = evoc; | 302 | struct nv50_dmac *dmac = evoc; |
301 | nv_wo32(dmac->base.user, 0x0000, (push - dmac->ptr) << 2); | 303 | nvif_wr32(&dmac->base.user, 0x0000, (push - dmac->ptr) << 2); |
302 | mutex_unlock(&dmac->lock); | 304 | mutex_unlock(&dmac->lock); |
303 | } | 305 | } |
304 | 306 | ||
@@ -408,7 +410,7 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
408 | if (unlikely(push == NULL)) | 410 | if (unlikely(push == NULL)) |
409 | return -EBUSY; | 411 | return -EBUSY; |
410 | 412 | ||
411 | if (chan && nv_mclass(chan->object) < NV84_CHANNEL_IND_CLASS) { | 413 | if (chan && chan->object->oclass < NV84_CHANNEL_IND_CLASS) { |
412 | ret = RING_SPACE(chan, 8); | 414 | ret = RING_SPACE(chan, 8); |
413 | if (ret) | 415 | if (ret) |
414 | return ret; | 416 | return ret; |
@@ -422,14 +424,14 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
422 | OUT_RING (chan, sync->addr); | 424 | OUT_RING (chan, sync->addr); |
423 | OUT_RING (chan, sync->data); | 425 | OUT_RING (chan, sync->data); |
424 | } else | 426 | } else |
425 | if (chan && nv_mclass(chan->object) < NVC0_CHANNEL_IND_CLASS) { | 427 | if (chan && chan->object->oclass < NVC0_CHANNEL_IND_CLASS) { |
426 | u64 addr = nv84_fence_crtc(chan, nv_crtc->index) + sync->addr; | 428 | u64 addr = nv84_fence_crtc(chan, nv_crtc->index) + sync->addr; |
427 | ret = RING_SPACE(chan, 12); | 429 | ret = RING_SPACE(chan, 12); |
428 | if (ret) | 430 | if (ret) |
429 | return ret; | 431 | return ret; |
430 | 432 | ||
431 | BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); | 433 | BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); |
432 | OUT_RING (chan, chan->vram); | 434 | OUT_RING (chan, chan->vram.handle); |
433 | BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); | 435 | BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); |
434 | OUT_RING (chan, upper_32_bits(addr ^ 0x10)); | 436 | OUT_RING (chan, upper_32_bits(addr ^ 0x10)); |
435 | OUT_RING (chan, lower_32_bits(addr ^ 0x10)); | 437 | OUT_RING (chan, lower_32_bits(addr ^ 0x10)); |
@@ -1066,7 +1068,7 @@ nv50_crtc_lut_load(struct drm_crtc *crtc) | |||
1066 | u16 g = nv_crtc->lut.g[i] >> 2; | 1068 | u16 g = nv_crtc->lut.g[i] >> 2; |
1067 | u16 b = nv_crtc->lut.b[i] >> 2; | 1069 | u16 b = nv_crtc->lut.b[i] >> 2; |
1068 | 1070 | ||
1069 | if (nv_mclass(disp->core) < NVD0_DISP_CLASS) { | 1071 | if (disp->disp->oclass < NVD0_DISP_CLASS) { |
1070 | writew(r + 0x0000, lut + (i * 0x08) + 0); | 1072 | writew(r + 0x0000, lut + (i * 0x08) + 0); |
1071 | writew(g + 0x0000, lut + (i * 0x08) + 2); | 1073 | writew(g + 0x0000, lut + (i * 0x08) + 2); |
1072 | writew(b + 0x0000, lut + (i * 0x08) + 4); | 1074 | writew(b + 0x0000, lut + (i * 0x08) + 4); |
@@ -1133,8 +1135,8 @@ nv50_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | |||
1133 | { | 1135 | { |
1134 | struct nv50_curs *curs = nv50_curs(crtc); | 1136 | struct nv50_curs *curs = nv50_curs(crtc); |
1135 | struct nv50_chan *chan = nv50_chan(curs); | 1137 | struct nv50_chan *chan = nv50_chan(curs); |
1136 | nv_wo32(chan->user, 0x0084, (y << 16) | (x & 0xffff)); | 1138 | nvif_wr32(&chan->user, 0x0084, (y << 16) | (x & 0xffff)); |
1137 | nv_wo32(chan->user, 0x0080, 0x00000000); | 1139 | nvif_wr32(&chan->user, 0x0080, 0x00000000); |
1138 | return 0; | 1140 | return 0; |
1139 | } | 1141 | } |
1140 | 1142 | ||
@@ -1161,11 +1163,16 @@ nv50_crtc_destroy(struct drm_crtc *crtc) | |||
1161 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 1163 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); |
1162 | struct nv50_disp *disp = nv50_disp(crtc->dev); | 1164 | struct nv50_disp *disp = nv50_disp(crtc->dev); |
1163 | struct nv50_head *head = nv50_head(crtc); | 1165 | struct nv50_head *head = nv50_head(crtc); |
1166 | struct nv50_fbdma *fbdma; | ||
1164 | 1167 | ||
1165 | nv50_dmac_destroy(disp->core, &head->ovly.base); | 1168 | list_for_each_entry(fbdma, &disp->fbdma, head) { |
1166 | nv50_pioc_destroy(disp->core, &head->oimm.base); | 1169 | nvif_object_fini(&fbdma->base[nv_crtc->index]); |
1167 | nv50_dmac_destroy(disp->core, &head->sync.base); | 1170 | } |
1168 | nv50_pioc_destroy(disp->core, &head->curs.base); | 1171 | |
1172 | nv50_dmac_destroy(&head->ovly.base, disp->disp); | ||
1173 | nv50_pioc_destroy(&head->oimm.base); | ||
1174 | nv50_dmac_destroy(&head->sync.base, disp->disp); | ||
1175 | nv50_pioc_destroy(&head->curs.base); | ||
1169 | 1176 | ||
1170 | /*XXX: this shouldn't be necessary, but the core doesn't call | 1177 | /*XXX: this shouldn't be necessary, but the core doesn't call |
1171 | * disconnect() during the cleanup paths | 1178 | * disconnect() during the cleanup paths |
@@ -1220,7 +1227,7 @@ nv50_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset) | |||
1220 | } | 1227 | } |
1221 | 1228 | ||
1222 | static int | 1229 | static int |
1223 | nv50_crtc_create(struct drm_device *dev, struct nouveau_object *core, int index) | 1230 | nv50_crtc_create(struct drm_device *dev, int index) |
1224 | { | 1231 | { |
1225 | struct nv50_disp *disp = nv50_disp(dev); | 1232 | struct nv50_disp *disp = nv50_disp(dev); |
1226 | struct nv50_head *head; | 1233 | struct nv50_head *head; |
@@ -1269,7 +1276,7 @@ nv50_crtc_create(struct drm_device *dev, struct nouveau_object *core, int index) | |||
1269 | nv50_crtc_lut_load(crtc); | 1276 | nv50_crtc_lut_load(crtc); |
1270 | 1277 | ||
1271 | /* allocate cursor resources */ | 1278 | /* allocate cursor resources */ |
1272 | ret = nv50_pioc_create(disp->core, NV50_DISP_CURS_CLASS, index, | 1279 | ret = nv50_pioc_create(disp->disp, NV50_DISP_CURS_CLASS, index, |
1273 | &(struct nv50_display_curs_class) { | 1280 | &(struct nv50_display_curs_class) { |
1274 | .head = index, | 1281 | .head = index, |
1275 | }, sizeof(struct nv50_display_curs_class), | 1282 | }, sizeof(struct nv50_display_curs_class), |
@@ -1294,7 +1301,7 @@ nv50_crtc_create(struct drm_device *dev, struct nouveau_object *core, int index) | |||
1294 | goto out; | 1301 | goto out; |
1295 | 1302 | ||
1296 | /* allocate page flip / sync resources */ | 1303 | /* allocate page flip / sync resources */ |
1297 | ret = nv50_dmac_create(disp->core, NV50_DISP_SYNC_CLASS, index, | 1304 | ret = nv50_dmac_create(disp->disp, NV50_DISP_SYNC_CLASS, index, |
1298 | &(struct nv50_display_sync_class) { | 1305 | &(struct nv50_display_sync_class) { |
1299 | .pushbuf = EVO_PUSH_HANDLE(SYNC, index), | 1306 | .pushbuf = EVO_PUSH_HANDLE(SYNC, index), |
1300 | .head = index, | 1307 | .head = index, |
@@ -1307,7 +1314,7 @@ nv50_crtc_create(struct drm_device *dev, struct nouveau_object *core, int index) | |||
1307 | head->sync.data = 0x00000000; | 1314 | head->sync.data = 0x00000000; |
1308 | 1315 | ||
1309 | /* allocate overlay resources */ | 1316 | /* allocate overlay resources */ |
1310 | ret = nv50_pioc_create(disp->core, NV50_DISP_OIMM_CLASS, index, | 1317 | ret = nv50_pioc_create(disp->disp, NV50_DISP_OIMM_CLASS, index, |
1311 | &(struct nv50_display_oimm_class) { | 1318 | &(struct nv50_display_oimm_class) { |
1312 | .head = index, | 1319 | .head = index, |
1313 | }, sizeof(struct nv50_display_oimm_class), | 1320 | }, sizeof(struct nv50_display_oimm_class), |
@@ -1315,7 +1322,7 @@ nv50_crtc_create(struct drm_device *dev, struct nouveau_object *core, int index) | |||
1315 | if (ret) | 1322 | if (ret) |
1316 | goto out; | 1323 | goto out; |
1317 | 1324 | ||
1318 | ret = nv50_dmac_create(disp->core, NV50_DISP_OVLY_CLASS, index, | 1325 | ret = nv50_dmac_create(disp->disp, NV50_DISP_OVLY_CLASS, index, |
1319 | &(struct nv50_display_ovly_class) { | 1326 | &(struct nv50_display_ovly_class) { |
1320 | .pushbuf = EVO_PUSH_HANDLE(OVLY, index), | 1327 | .pushbuf = EVO_PUSH_HANDLE(OVLY, index), |
1321 | .head = index, | 1328 | .head = index, |
@@ -1347,7 +1354,7 @@ nv50_dac_dpms(struct drm_encoder *encoder, int mode) | |||
1347 | if (mode == DRM_MODE_DPMS_SUSPEND || mode == DRM_MODE_DPMS_OFF) | 1354 | if (mode == DRM_MODE_DPMS_SUSPEND || mode == DRM_MODE_DPMS_OFF) |
1348 | dpms_ctrl |= 0x00000004; | 1355 | dpms_ctrl |= 0x00000004; |
1349 | 1356 | ||
1350 | nv_call(disp->core, NV50_DISP_DAC_PWR + or, dpms_ctrl); | 1357 | nvif_exec(disp->disp, NV50_DISP_DAC_PWR + or, &dpms_ctrl, sizeof(dpms_ctrl)); |
1351 | } | 1358 | } |
1352 | 1359 | ||
1353 | static bool | 1360 | static bool |
@@ -1460,7 +1467,7 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) | |||
1460 | if (load == 0) | 1467 | if (load == 0) |
1461 | load = 340; | 1468 | load = 340; |
1462 | 1469 | ||
1463 | ret = nv_exec(disp->core, NV50_DISP_DAC_LOAD + or, &load, sizeof(load)); | 1470 | ret = nvif_exec(disp->disp, NV50_DISP_DAC_LOAD + or, &load, sizeof(load)); |
1464 | if (ret || !load) | 1471 | if (ret || !load) |
1465 | return connector_status_disconnected; | 1472 | return connector_status_disconnected; |
1466 | 1473 | ||
@@ -1531,9 +1538,9 @@ nv50_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) | |||
1531 | 1538 | ||
1532 | drm_edid_to_eld(&nv_connector->base, nv_connector->edid); | 1539 | drm_edid_to_eld(&nv_connector->base, nv_connector->edid); |
1533 | 1540 | ||
1534 | nv_exec(disp->core, NVA3_DISP_SOR_HDA_ELD + nv_encoder->or, | 1541 | nvif_exec(disp->disp, NVA3_DISP_SOR_HDA_ELD + nv_encoder->or, |
1535 | nv_connector->base.eld, | 1542 | nv_connector->base.eld, |
1536 | nv_connector->base.eld[2] * 4); | 1543 | nv_connector->base.eld[2] * 4); |
1537 | } | 1544 | } |
1538 | 1545 | ||
1539 | static void | 1546 | static void |
@@ -1542,7 +1549,7 @@ nv50_audio_disconnect(struct drm_encoder *encoder) | |||
1542 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 1549 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
1543 | struct nv50_disp *disp = nv50_disp(encoder->dev); | 1550 | struct nv50_disp *disp = nv50_disp(encoder->dev); |
1544 | 1551 | ||
1545 | nv_exec(disp->core, NVA3_DISP_SOR_HDA_ELD + nv_encoder->or, NULL, 0); | 1552 | nvif_exec(disp->disp, NVA3_DISP_SOR_HDA_ELD + nv_encoder->or, NULL, 0); |
1546 | } | 1553 | } |
1547 | 1554 | ||
1548 | /****************************************************************************** | 1555 | /****************************************************************************** |
@@ -1558,6 +1565,7 @@ nv50_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) | |||
1558 | const u32 moff = (nv_crtc->index << 3) | nv_encoder->or; | 1565 | const u32 moff = (nv_crtc->index << 3) | nv_encoder->or; |
1559 | u32 rekey = 56; /* binary driver, and tegra constant */ | 1566 | u32 rekey = 56; /* binary driver, and tegra constant */ |
1560 | u32 max_ac_packet; | 1567 | u32 max_ac_packet; |
1568 | u32 data; | ||
1561 | 1569 | ||
1562 | nv_connector = nouveau_encoder_connector_get(nv_encoder); | 1570 | nv_connector = nouveau_encoder_connector_get(nv_encoder); |
1563 | if (!drm_detect_hdmi_monitor(nv_connector->edid)) | 1571 | if (!drm_detect_hdmi_monitor(nv_connector->edid)) |
@@ -1568,9 +1576,8 @@ nv50_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) | |||
1568 | max_ac_packet -= 18; /* constant from tegra */ | 1576 | max_ac_packet -= 18; /* constant from tegra */ |
1569 | max_ac_packet /= 32; | 1577 | max_ac_packet /= 32; |
1570 | 1578 | ||
1571 | nv_call(disp->core, NV84_DISP_SOR_HDMI_PWR + moff, | 1579 | data = NV84_DISP_SOR_HDMI_PWR_STATE_ON | (max_ac_packet << 16) | rekey; |
1572 | NV84_DISP_SOR_HDMI_PWR_STATE_ON | | 1580 | nvif_exec(disp->disp, NV84_DISP_SOR_HDMI_PWR + moff, &data, sizeof(data)); |
1573 | (max_ac_packet << 16) | rekey); | ||
1574 | 1581 | ||
1575 | nv50_audio_mode_set(encoder, mode); | 1582 | nv50_audio_mode_set(encoder, mode); |
1576 | } | 1583 | } |
@@ -1581,10 +1588,11 @@ nv50_hdmi_disconnect(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc) | |||
1581 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 1588 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
1582 | struct nv50_disp *disp = nv50_disp(encoder->dev); | 1589 | struct nv50_disp *disp = nv50_disp(encoder->dev); |
1583 | const u32 moff = (nv_crtc->index << 3) | nv_encoder->or; | 1590 | const u32 moff = (nv_crtc->index << 3) | nv_encoder->or; |
1591 | u32 data = 0; | ||
1584 | 1592 | ||
1585 | nv50_audio_disconnect(encoder); | 1593 | nv50_audio_disconnect(encoder); |
1586 | 1594 | ||
1587 | nv_call(disp->core, NV84_DISP_SOR_HDMI_PWR + moff, 0x00000000); | 1595 | nvif_exec(disp->disp, NV84_DISP_SOR_HDMI_PWR + moff, &data, sizeof(data)); |
1588 | } | 1596 | } |
1589 | 1597 | ||
1590 | /****************************************************************************** | 1598 | /****************************************************************************** |
@@ -1597,7 +1605,7 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) | |||
1597 | struct drm_device *dev = encoder->dev; | 1605 | struct drm_device *dev = encoder->dev; |
1598 | struct nv50_disp *disp = nv50_disp(dev); | 1606 | struct nv50_disp *disp = nv50_disp(dev); |
1599 | struct drm_encoder *partner; | 1607 | struct drm_encoder *partner; |
1600 | u32 mthd; | 1608 | u32 mthd, data; |
1601 | 1609 | ||
1602 | nv_encoder->last_dpms = mode; | 1610 | nv_encoder->last_dpms = mode; |
1603 | 1611 | ||
@@ -1620,13 +1628,15 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) | |||
1620 | mthd |= nv_encoder->or; | 1628 | mthd |= nv_encoder->or; |
1621 | 1629 | ||
1622 | if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { | 1630 | if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { |
1623 | nv_call(disp->core, NV50_DISP_SOR_PWR | mthd, 1); | 1631 | data = 1; |
1632 | nvif_exec(disp->disp, NV50_DISP_SOR_PWR | mthd, &data, sizeof(data)); | ||
1624 | mthd |= NV94_DISP_SOR_DP_PWR; | 1633 | mthd |= NV94_DISP_SOR_DP_PWR; |
1625 | } else { | 1634 | } else { |
1626 | mthd |= NV50_DISP_SOR_PWR; | 1635 | mthd |= NV50_DISP_SOR_PWR; |
1627 | } | 1636 | } |
1628 | 1637 | ||
1629 | nv_call(disp->core, mthd, (mode == DRM_MODE_DPMS_ON)); | 1638 | data = (mode == DRM_MODE_DPMS_ON); |
1639 | nvif_exec(disp->disp, mthd, &data, sizeof(data)); | ||
1630 | } | 1640 | } |
1631 | 1641 | ||
1632 | static bool | 1642 | static bool |
@@ -1749,7 +1759,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, | |||
1749 | lvds |= 0x0200; | 1759 | lvds |= 0x0200; |
1750 | } | 1760 | } |
1751 | 1761 | ||
1752 | nv_call(disp->core, NV50_DISP_SOR_LVDS_SCRIPT + nv_encoder->or, lvds); | 1762 | nvif_exec(disp->disp, NV50_DISP_SOR_LVDS_SCRIPT + nv_encoder->or, &lvds, sizeof(lvds)); |
1753 | break; | 1763 | break; |
1754 | case DCB_OUTPUT_DP: | 1764 | case DCB_OUTPUT_DP: |
1755 | if (nv_connector->base.display_info.bpc == 6) { | 1765 | if (nv_connector->base.display_info.bpc == 6) { |
@@ -1878,7 +1888,7 @@ nv50_pior_dpms(struct drm_encoder *encoder, int mode) | |||
1878 | struct nv50_disp *disp = nv50_disp(encoder->dev); | 1888 | struct nv50_disp *disp = nv50_disp(encoder->dev); |
1879 | u32 mthd = (nv_encoder->dcb->type << 12) | nv_encoder->or; | 1889 | u32 mthd = (nv_encoder->dcb->type << 12) | nv_encoder->or; |
1880 | u32 ctrl = (mode == DRM_MODE_DPMS_ON); | 1890 | u32 ctrl = (mode == DRM_MODE_DPMS_ON); |
1881 | nv_call(disp->core, NV50_DISP_PIOR_PWR + mthd, ctrl); | 1891 | nvif_exec(disp->disp, NV50_DISP_PIOR_PWR + mthd, &ctrl, sizeof(ctrl)); |
1882 | } | 1892 | } |
1883 | 1893 | ||
1884 | static bool | 1894 | static bool |
@@ -2046,25 +2056,13 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe) | |||
2046 | * Framebuffer | 2056 | * Framebuffer |
2047 | *****************************************************************************/ | 2057 | *****************************************************************************/ |
2048 | 2058 | ||
2049 | struct nv50_fbdma { | ||
2050 | struct list_head head; | ||
2051 | u32 name; | ||
2052 | }; | ||
2053 | |||
2054 | static void | 2059 | static void |
2055 | nv50_fbdma_fini(struct drm_device *dev, struct nv50_fbdma *fbdma) | 2060 | nv50_fbdma_fini(struct nv50_fbdma *fbdma) |
2056 | { | 2061 | { |
2057 | struct nv50_disp *disp = nv50_disp(dev); | 2062 | int i; |
2058 | struct nv50_mast *mast = nv50_mast(dev); | 2063 | for (i = 0; i < ARRAY_SIZE(fbdma->base); i++) |
2059 | struct nouveau_object *client = nv_pclass(disp->core, NV_CLIENT_CLASS); | 2064 | nvif_object_fini(&fbdma->base[i]); |
2060 | struct drm_crtc *crtc; | 2065 | nvif_object_fini(&fbdma->core); |
2061 | |||
2062 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
2063 | struct nv50_sync *sync = nv50_sync(crtc); | ||
2064 | nouveau_object_del(client, sync->base.base.handle, fbdma->name); | ||
2065 | } | ||
2066 | |||
2067 | nouveau_object_del(client, mast->base.base.handle, fbdma->name); | ||
2068 | list_del(&fbdma->head); | 2066 | list_del(&fbdma->head); |
2069 | kfree(fbdma); | 2067 | kfree(fbdma); |
2070 | } | 2068 | } |
@@ -2075,15 +2073,13 @@ nv50_fbdma_init(struct drm_device *dev, u32 name, u64 offset, u64 length, u8 kin | |||
2075 | struct nouveau_drm *drm = nouveau_drm(dev); | 2073 | struct nouveau_drm *drm = nouveau_drm(dev); |
2076 | struct nv50_disp *disp = nv50_disp(dev); | 2074 | struct nv50_disp *disp = nv50_disp(dev); |
2077 | struct nv50_mast *mast = nv50_mast(dev); | 2075 | struct nv50_mast *mast = nv50_mast(dev); |
2078 | struct nouveau_object *client = nv_pclass(disp->core, NV_CLIENT_CLASS); | ||
2079 | struct nouveau_object *object; | ||
2080 | struct nv_dma_class args; | 2076 | struct nv_dma_class args; |
2081 | struct nv50_fbdma *fbdma; | 2077 | struct nv50_fbdma *fbdma; |
2082 | struct drm_crtc *crtc; | 2078 | struct drm_crtc *crtc; |
2083 | int ret; | 2079 | int ret; |
2084 | 2080 | ||
2085 | list_for_each_entry(fbdma, &disp->fbdma, head) { | 2081 | list_for_each_entry(fbdma, &disp->fbdma, head) { |
2086 | if (fbdma->name == name) | 2082 | if (fbdma->core.handle == name) |
2087 | return 0; | 2083 | return 0; |
2088 | } | 2084 | } |
2089 | 2085 | ||
@@ -2091,7 +2087,6 @@ nv50_fbdma_init(struct drm_device *dev, u32 name, u64 offset, u64 length, u8 kin | |||
2091 | if (!fbdma) | 2087 | if (!fbdma) |
2092 | return -ENOMEM; | 2088 | return -ENOMEM; |
2093 | list_add(&fbdma->head, &disp->fbdma); | 2089 | list_add(&fbdma->head, &disp->fbdma); |
2094 | fbdma->name = name; | ||
2095 | 2090 | ||
2096 | args.flags = NV_DMA_TARGET_VRAM | NV_DMA_ACCESS_RDWR; | 2091 | args.flags = NV_DMA_TARGET_VRAM | NV_DMA_ACCESS_RDWR; |
2097 | args.start = offset; | 2092 | args.start = offset; |
@@ -2114,23 +2109,22 @@ nv50_fbdma_init(struct drm_device *dev, u32 name, u64 offset, u64 length, u8 kin | |||
2114 | } | 2109 | } |
2115 | 2110 | ||
2116 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 2111 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
2117 | struct nv50_sync *sync = nv50_sync(crtc); | 2112 | struct nv50_head *head = nv50_head(crtc); |
2118 | ret = nouveau_object_new(client, sync->base.base.handle, | 2113 | int ret = nvif_object_init(&head->sync.base.base.user, NULL, |
2119 | fbdma->name, NV_DMA_IN_MEMORY_CLASS, | 2114 | name, NV_DMA_IN_MEMORY_CLASS, |
2120 | &args, sizeof(args), &object); | 2115 | &args, sizeof(args), |
2116 | &fbdma->base[head->base.index]); | ||
2121 | if (ret) { | 2117 | if (ret) { |
2122 | printk(KERN_ERR "fail %d %08x %d\n", nv50_head(crtc)->base.index, fbdma->name, ret); | 2118 | nv50_fbdma_fini(fbdma); |
2123 | nv50_fbdma_fini(dev, fbdma); | ||
2124 | return ret; | 2119 | return ret; |
2125 | } | 2120 | } |
2126 | } | 2121 | } |
2127 | 2122 | ||
2128 | ret = nouveau_object_new(client, mast->base.base.handle, fbdma->name, | 2123 | ret = nvif_object_init(&mast->base.base.user, NULL, name, |
2129 | NV_DMA_IN_MEMORY_CLASS, &args, sizeof(args), | 2124 | NV_DMA_IN_MEMORY_CLASS, &args, sizeof(args), |
2130 | &object); | 2125 | &fbdma->core); |
2131 | if (ret) { | 2126 | if (ret) { |
2132 | printk(KERN_ERR "fail %08x %d\n", fbdma->name, ret); | 2127 | nv50_fbdma_fini(fbdma); |
2133 | nv50_fbdma_fini(dev, fbdma); | ||
2134 | return ret; | 2128 | return ret; |
2135 | } | 2129 | } |
2136 | 2130 | ||
@@ -2173,12 +2167,12 @@ nv50_fb_ctor(struct drm_framebuffer *fb) | |||
2173 | return -EINVAL; | 2167 | return -EINVAL; |
2174 | } | 2168 | } |
2175 | 2169 | ||
2176 | if (nv_mclass(disp->core) < NV84_DISP_CLASS) { | 2170 | if (disp->disp->oclass < NV84_DISP_CLASS) { |
2177 | nv_fb->r_pitch = kind ? (((fb->pitches[0] / 4) << 4) | tile) : | 2171 | nv_fb->r_pitch = kind ? (((fb->pitches[0] / 4) << 4) | tile) : |
2178 | (fb->pitches[0] | 0x00100000); | 2172 | (fb->pitches[0] | 0x00100000); |
2179 | nv_fb->r_format |= kind << 16; | 2173 | nv_fb->r_format |= kind << 16; |
2180 | } else | 2174 | } else |
2181 | if (nv_mclass(disp->core) < NVD0_DISP_CLASS) { | 2175 | if (disp->disp->oclass < NVD0_DISP_CLASS) { |
2182 | nv_fb->r_pitch = kind ? (((fb->pitches[0] / 4) << 4) | tile) : | 2176 | nv_fb->r_pitch = kind ? (((fb->pitches[0] / 4) << 4) | tile) : |
2183 | (fb->pitches[0] | 0x00100000); | 2177 | (fb->pitches[0] | 0x00100000); |
2184 | } else { | 2178 | } else { |
@@ -2228,10 +2222,10 @@ nv50_display_destroy(struct drm_device *dev) | |||
2228 | struct nv50_fbdma *fbdma, *fbtmp; | 2222 | struct nv50_fbdma *fbdma, *fbtmp; |
2229 | 2223 | ||
2230 | list_for_each_entry_safe(fbdma, fbtmp, &disp->fbdma, head) { | 2224 | list_for_each_entry_safe(fbdma, fbtmp, &disp->fbdma, head) { |
2231 | nv50_fbdma_fini(dev, fbdma); | 2225 | nv50_fbdma_fini(fbdma); |
2232 | } | 2226 | } |
2233 | 2227 | ||
2234 | nv50_dmac_destroy(disp->core, &disp->mast.base); | 2228 | nv50_dmac_destroy(&disp->mast.base, disp->disp); |
2235 | 2229 | ||
2236 | nouveau_bo_unmap(disp->sync); | 2230 | nouveau_bo_unmap(disp->sync); |
2237 | if (disp->sync) | 2231 | if (disp->sync) |
@@ -2264,7 +2258,7 @@ nv50_display_create(struct drm_device *dev) | |||
2264 | nouveau_display(dev)->fini = nv50_display_fini; | 2258 | nouveau_display(dev)->fini = nv50_display_fini; |
2265 | nouveau_display(dev)->fb_ctor = nv50_fb_ctor; | 2259 | nouveau_display(dev)->fb_ctor = nv50_fb_ctor; |
2266 | nouveau_display(dev)->fb_dtor = nv50_fb_dtor; | 2260 | nouveau_display(dev)->fb_dtor = nv50_fb_dtor; |
2267 | disp->core = nouveau_display(dev)->core; | 2261 | disp->disp = &nouveau_display(dev)->disp; |
2268 | 2262 | ||
2269 | /* small shared memory area we use for notifiers and semaphores */ | 2263 | /* small shared memory area we use for notifiers and semaphores */ |
2270 | ret = nouveau_bo_new(dev, 4096, 0x1000, TTM_PL_FLAG_VRAM, | 2264 | ret = nouveau_bo_new(dev, 4096, 0x1000, TTM_PL_FLAG_VRAM, |
@@ -2284,7 +2278,7 @@ nv50_display_create(struct drm_device *dev) | |||
2284 | goto out; | 2278 | goto out; |
2285 | 2279 | ||
2286 | /* allocate master evo channel */ | 2280 | /* allocate master evo channel */ |
2287 | ret = nv50_dmac_create(disp->core, NV50_DISP_MAST_CLASS, 0, | 2281 | ret = nv50_dmac_create(disp->disp, NV50_DISP_MAST_CLASS, 0, |
2288 | &(struct nv50_display_mast_class) { | 2282 | &(struct nv50_display_mast_class) { |
2289 | .pushbuf = EVO_PUSH_HANDLE(MAST, 0), | 2283 | .pushbuf = EVO_PUSH_HANDLE(MAST, 0), |
2290 | }, sizeof(struct nv50_display_mast_class), | 2284 | }, sizeof(struct nv50_display_mast_class), |
@@ -2293,13 +2287,13 @@ nv50_display_create(struct drm_device *dev) | |||
2293 | goto out; | 2287 | goto out; |
2294 | 2288 | ||
2295 | /* create crtc objects to represent the hw heads */ | 2289 | /* create crtc objects to represent the hw heads */ |
2296 | if (nv_mclass(disp->core) >= NVD0_DISP_CLASS) | 2290 | if (disp->disp->oclass >= NVD0_DISP_CLASS) |
2297 | crtcs = nvif_rd32(device, 0x022448); | 2291 | crtcs = nvif_rd32(device, 0x022448); |
2298 | else | 2292 | else |
2299 | crtcs = 2; | 2293 | crtcs = 2; |
2300 | 2294 | ||
2301 | for (i = 0; i < crtcs; i++) { | 2295 | for (i = 0; i < crtcs; i++) { |
2302 | ret = nv50_crtc_create(dev, disp->core, i); | 2296 | ret = nv50_crtc_create(dev, i); |
2303 | if (ret) | 2297 | if (ret) |
2304 | goto out; | 2298 | goto out; |
2305 | } | 2299 | } |