diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-10-18 21:14:17 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-12-03 00:10:50 -0500 |
commit | 106ddad5aa8e8e03503cea05f9a64611f849952f (patch) | |
tree | 8828a6937d3ae3c5bffab1d88840d2b038955b5b | |
parent | f4512e6579ddaa9b1f8ab1d5659131243ffc421f (diff) |
drm/nv50: clearer separation of the stages of evo init
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_reg.h | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.c | 93 |
2 files changed, 55 insertions, 52 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h index 1bbe7037cf99..5e28bc63c41e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_reg.h +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h | |||
@@ -747,15 +747,11 @@ | |||
747 | #define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS 0x00030000 | 747 | #define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS 0x00030000 |
748 | #define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE 0x00010000 | 748 | #define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE 0x00010000 |
749 | 749 | ||
750 | #define NV50_PDISPLAY_CTRL_STATE 0x00610300 | 750 | #define NV50_PDISPLAY_PIO_CTRL 0x00610300 |
751 | #define NV50_PDISPLAY_CTRL_STATE_PENDING 0x80000000 | 751 | #define NV50_PDISPLAY_PIO_CTRL_PENDING 0x80000000 |
752 | #define NV50_PDISPLAY_CTRL_STATE_METHOD 0x00001ffc | 752 | #define NV50_PDISPLAY_PIO_CTRL_MTHD 0x00001ffc |
753 | #define NV50_PDISPLAY_CTRL_STATE_ENABLE 0x00000001 | 753 | #define NV50_PDISPLAY_PIO_CTRL_ENABLED 0x00000001 |
754 | #define NV50_PDISPLAY_CTRL_VAL 0x00610304 | 754 | #define NV50_PDISPLAY_PIO_DATA 0x00610304 |
755 | #define NV50_PDISPLAY_UNK_380 0x00610380 | ||
756 | #define NV50_PDISPLAY_RAM_AMOUNT 0x00610384 | ||
757 | #define NV50_PDISPLAY_UNK_388 0x00610388 | ||
758 | #define NV50_PDISPLAY_UNK_38C 0x0061038c | ||
759 | 755 | ||
760 | #define NV50_PDISPLAY_CRTC_P(i, r) ((i) * 0x540 + NV50_PDISPLAY_CRTC_##r) | 756 | #define NV50_PDISPLAY_CRTC_P(i, r) ((i) * 0x540 + NV50_PDISPLAY_CRTC_##r) |
761 | #define NV50_PDISPLAY_CRTC_C(i, r) (4 + (i) * 0x540 + NV50_PDISPLAY_CRTC_##r) | 757 | #define NV50_PDISPLAY_CRTC_C(i, r) (4 + (i) * 0x540 + NV50_PDISPLAY_CRTC_##r) |
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 7ac87efb791f..7c9c7c5bf22a 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
@@ -225,6 +225,7 @@ nv50_display_init(struct drm_device *dev) | |||
225 | NV_DEBUG_KMS(dev, "\n"); | 225 | NV_DEBUG_KMS(dev, "\n"); |
226 | 226 | ||
227 | nv_wr32(dev, 0x00610184, nv_rd32(dev, 0x00614004)); | 227 | nv_wr32(dev, 0x00610184, nv_rd32(dev, 0x00614004)); |
228 | |||
228 | /* | 229 | /* |
229 | * I think the 0x006101XX range is some kind of main control area | 230 | * I think the 0x006101XX range is some kind of main control area |
230 | * that enables things. | 231 | * that enables things. |
@@ -240,16 +241,19 @@ nv50_display_init(struct drm_device *dev) | |||
240 | val = nv_rd32(dev, 0x0061610c + (i * 0x800)); | 241 | val = nv_rd32(dev, 0x0061610c + (i * 0x800)); |
241 | nv_wr32(dev, 0x0061019c + (i * 0x10), val); | 242 | nv_wr32(dev, 0x0061019c + (i * 0x10), val); |
242 | } | 243 | } |
244 | |||
243 | /* DAC */ | 245 | /* DAC */ |
244 | for (i = 0; i < 3; i++) { | 246 | for (i = 0; i < 3; i++) { |
245 | val = nv_rd32(dev, 0x0061a000 + (i * 0x800)); | 247 | val = nv_rd32(dev, 0x0061a000 + (i * 0x800)); |
246 | nv_wr32(dev, 0x006101d0 + (i * 0x04), val); | 248 | nv_wr32(dev, 0x006101d0 + (i * 0x04), val); |
247 | } | 249 | } |
250 | |||
248 | /* SOR */ | 251 | /* SOR */ |
249 | for (i = 0; i < nv50_sor_nr(dev); i++) { | 252 | for (i = 0; i < nv50_sor_nr(dev); i++) { |
250 | val = nv_rd32(dev, 0x0061c000 + (i * 0x800)); | 253 | val = nv_rd32(dev, 0x0061c000 + (i * 0x800)); |
251 | nv_wr32(dev, 0x006101e0 + (i * 0x04), val); | 254 | nv_wr32(dev, 0x006101e0 + (i * 0x04), val); |
252 | } | 255 | } |
256 | |||
253 | /* EXT */ | 257 | /* EXT */ |
254 | for (i = 0; i < 3; i++) { | 258 | for (i = 0; i < 3; i++) { |
255 | val = nv_rd32(dev, 0x0061e000 + (i * 0x800)); | 259 | val = nv_rd32(dev, 0x0061e000 + (i * 0x800)); |
@@ -276,6 +280,49 @@ nv50_display_init(struct drm_device *dev) | |||
276 | } | 280 | } |
277 | } | 281 | } |
278 | 282 | ||
283 | for (i = 0; i < 2; i++) { | ||
284 | nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0x2000); | ||
285 | if (!nv_wait(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), | ||
286 | NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) { | ||
287 | NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n"); | ||
288 | NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n", | ||
289 | nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i))); | ||
290 | return -EBUSY; | ||
291 | } | ||
292 | |||
293 | nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), | ||
294 | NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON); | ||
295 | if (!nv_wait(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), | ||
296 | NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, | ||
297 | NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE)) { | ||
298 | NV_ERROR(dev, "timeout: " | ||
299 | "CURSOR_CTRL2_STATUS_ACTIVE(%d)\n", i); | ||
300 | NV_ERROR(dev, "CURSOR_CTRL2(%d) = 0x%08x\n", i, | ||
301 | nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i))); | ||
302 | return -EBUSY; | ||
303 | } | ||
304 | } | ||
305 | |||
306 | nv_wr32(dev, NV50_PDISPLAY_OBJECTS, (evo->ramin->vinst >> 8) | 9); | ||
307 | nv_wr32(dev, NV50_PDISPLAY_PIO_CTRL, 0x00000000); | ||
308 | nv_wr32(dev, 0x610028, 0x00000000); | ||
309 | nv_mask(dev, NV50_PDISPLAY_INTR_0, 0x00000000, 0x00000000); | ||
310 | nv_mask(dev, NV50_PDISPLAY_INTR_1, 0x00000000, 0x00000000); | ||
311 | nv_wr32(dev, NV50_PDISPLAY_INTR_EN, | ||
312 | NV50_PDISPLAY_INTR_EN_CLK_UNK10 | | ||
313 | NV50_PDISPLAY_INTR_EN_CLK_UNK20 | | ||
314 | NV50_PDISPLAY_INTR_EN_CLK_UNK40); | ||
315 | |||
316 | /* enable hotplug interrupts */ | ||
317 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
318 | struct nouveau_connector *conn = nouveau_connector(connector); | ||
319 | |||
320 | if (conn->dcb->gpio_tag == 0xff) | ||
321 | continue; | ||
322 | |||
323 | pgpio->irq_enable(dev, conn->dcb->gpio_tag, true); | ||
324 | } | ||
325 | |||
279 | /* taken from nv bug #12637, attempts to un-wedge the hw if it's | 326 | /* taken from nv bug #12637, attempts to un-wedge the hw if it's |
280 | * stuck in some unspecified state | 327 | * stuck in some unspecified state |
281 | */ | 328 | */ |
@@ -297,7 +344,6 @@ nv50_display_init(struct drm_device *dev) | |||
297 | } | 344 | } |
298 | } | 345 | } |
299 | 346 | ||
300 | nv_wr32(dev, NV50_PDISPLAY_CTRL_STATE, NV50_PDISPLAY_CTRL_STATE_ENABLE); | ||
301 | nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x1000b03); | 347 | nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x1000b03); |
302 | if (!nv_wait(dev, NV50_PDISPLAY_CHANNEL_STAT(0), | 348 | if (!nv_wait(dev, NV50_PDISPLAY_CHANNEL_STAT(0), |
303 | 0x40000000, 0x40000000)) { | 349 | 0x40000000, 0x40000000)) { |
@@ -307,31 +353,6 @@ nv50_display_init(struct drm_device *dev) | |||
307 | return -EBUSY; | 353 | return -EBUSY; |
308 | } | 354 | } |
309 | 355 | ||
310 | for (i = 0; i < 2; i++) { | ||
311 | nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0x2000); | ||
312 | if (!nv_wait(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), | ||
313 | NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) { | ||
314 | NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n"); | ||
315 | NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n", | ||
316 | nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i))); | ||
317 | return -EBUSY; | ||
318 | } | ||
319 | |||
320 | nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), | ||
321 | NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON); | ||
322 | if (!nv_wait(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), | ||
323 | NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, | ||
324 | NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE)) { | ||
325 | NV_ERROR(dev, "timeout: " | ||
326 | "CURSOR_CTRL2_STATUS_ACTIVE(%d)\n", i); | ||
327 | NV_ERROR(dev, "CURSOR_CTRL2(%d) = 0x%08x\n", i, | ||
328 | nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i))); | ||
329 | return -EBUSY; | ||
330 | } | ||
331 | } | ||
332 | |||
333 | nv_wr32(dev, NV50_PDISPLAY_OBJECTS, (evo->ramin->vinst >> 8) | 9); | ||
334 | |||
335 | /* initialise fifo */ | 356 | /* initialise fifo */ |
336 | nv_wr32(dev, NV50_PDISPLAY_CHANNEL_DMA_CB(0), | 357 | nv_wr32(dev, NV50_PDISPLAY_CHANNEL_DMA_CB(0), |
337 | ((evo->pushbuf_bo->bo.mem.start << PAGE_SHIFT) >> 8) | | 358 | ((evo->pushbuf_bo->bo.mem.start << PAGE_SHIFT) >> 8) | |
@@ -350,7 +371,9 @@ nv50_display_init(struct drm_device *dev) | |||
350 | nv_wr32(dev, NV50_PDISPLAY_USER_PUT(0), 0); | 371 | nv_wr32(dev, NV50_PDISPLAY_USER_PUT(0), 0); |
351 | nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x01000003 | | 372 | nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x01000003 | |
352 | NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED); | 373 | NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED); |
353 | nv_wr32(dev, 0x610300, nv_rd32(dev, 0x610300) & ~1); | 374 | |
375 | /* enable error reporting on the channel */ | ||
376 | nv_mask(dev, 0x610028, 0x00000000, 0x00010001 << 0); | ||
354 | 377 | ||
355 | evo->dma.max = (4096/4) - 2; | 378 | evo->dma.max = (4096/4) - 2; |
356 | evo->dma.put = 0; | 379 | evo->dma.put = 0; |
@@ -382,21 +405,6 @@ nv50_display_init(struct drm_device *dev) | |||
382 | if (!nv_wait(dev, 0x640004, 0xffffffff, evo->dma.put << 2)) | 405 | if (!nv_wait(dev, 0x640004, 0xffffffff, evo->dma.put << 2)) |
383 | NV_ERROR(dev, "evo pushbuf stalled\n"); | 406 | NV_ERROR(dev, "evo pushbuf stalled\n"); |
384 | 407 | ||
385 | /* enable clock change interrupts. */ | ||
386 | nv_wr32(dev, 0x610028, 0x00010001); | ||
387 | nv_wr32(dev, NV50_PDISPLAY_INTR_EN, (NV50_PDISPLAY_INTR_EN_CLK_UNK10 | | ||
388 | NV50_PDISPLAY_INTR_EN_CLK_UNK20 | | ||
389 | NV50_PDISPLAY_INTR_EN_CLK_UNK40)); | ||
390 | |||
391 | /* enable hotplug interrupts */ | ||
392 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
393 | struct nouveau_connector *conn = nouveau_connector(connector); | ||
394 | |||
395 | if (conn->dcb->gpio_tag == 0xff) | ||
396 | continue; | ||
397 | |||
398 | pgpio->irq_enable(dev, conn->dcb->gpio_tag, true); | ||
399 | } | ||
400 | 408 | ||
401 | return 0; | 409 | return 0; |
402 | } | 410 | } |
@@ -442,7 +450,6 @@ static int nv50_display_disable(struct drm_device *dev) | |||
442 | } | 450 | } |
443 | 451 | ||
444 | nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0); | 452 | nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0); |
445 | nv_wr32(dev, NV50_PDISPLAY_CTRL_STATE, 0); | ||
446 | if (!nv_wait(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x1e0000, 0)) { | 453 | if (!nv_wait(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x1e0000, 0)) { |
447 | NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) == 0\n"); | 454 | NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) == 0\n"); |
448 | NV_ERROR(dev, "0x610200 = 0x%08x\n", | 455 | NV_ERROR(dev, "0x610200 = 0x%08x\n", |