diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_display.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 391 |
1 files changed, 364 insertions, 27 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 1df4dc6c063c..d26dabf878d9 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -68,7 +68,7 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc) | |||
68 | WREG32(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id); | 68 | WREG32(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id); |
69 | } | 69 | } |
70 | 70 | ||
71 | static void evergreen_crtc_load_lut(struct drm_crtc *crtc) | 71 | static void dce4_crtc_load_lut(struct drm_crtc *crtc) |
72 | { | 72 | { |
73 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 73 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
74 | struct drm_device *dev = crtc->dev; | 74 | struct drm_device *dev = crtc->dev; |
@@ -98,6 +98,66 @@ static void evergreen_crtc_load_lut(struct drm_crtc *crtc) | |||
98 | } | 98 | } |
99 | } | 99 | } |
100 | 100 | ||
101 | static void dce5_crtc_load_lut(struct drm_crtc *crtc) | ||
102 | { | ||
103 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
104 | struct drm_device *dev = crtc->dev; | ||
105 | struct radeon_device *rdev = dev->dev_private; | ||
106 | int i; | ||
107 | |||
108 | DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); | ||
109 | |||
110 | WREG32(NI_INPUT_CSC_CONTROL + radeon_crtc->crtc_offset, | ||
111 | (NI_INPUT_CSC_GRPH_MODE(NI_INPUT_CSC_BYPASS) | | ||
112 | NI_INPUT_CSC_OVL_MODE(NI_INPUT_CSC_BYPASS))); | ||
113 | WREG32(NI_PRESCALE_GRPH_CONTROL + radeon_crtc->crtc_offset, | ||
114 | NI_GRPH_PRESCALE_BYPASS); | ||
115 | WREG32(NI_PRESCALE_OVL_CONTROL + radeon_crtc->crtc_offset, | ||
116 | NI_OVL_PRESCALE_BYPASS); | ||
117 | WREG32(NI_INPUT_GAMMA_CONTROL + radeon_crtc->crtc_offset, | ||
118 | (NI_GRPH_INPUT_GAMMA_MODE(NI_INPUT_GAMMA_USE_LUT) | | ||
119 | NI_OVL_INPUT_GAMMA_MODE(NI_INPUT_GAMMA_USE_LUT))); | ||
120 | |||
121 | WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0); | ||
122 | |||
123 | WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0); | ||
124 | WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0); | ||
125 | WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0); | ||
126 | |||
127 | WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff); | ||
128 | WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff); | ||
129 | WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff); | ||
130 | |||
131 | WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0); | ||
132 | WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007); | ||
133 | |||
134 | WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0); | ||
135 | for (i = 0; i < 256; i++) { | ||
136 | WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset, | ||
137 | (radeon_crtc->lut_r[i] << 20) | | ||
138 | (radeon_crtc->lut_g[i] << 10) | | ||
139 | (radeon_crtc->lut_b[i] << 0)); | ||
140 | } | ||
141 | |||
142 | WREG32(NI_DEGAMMA_CONTROL + radeon_crtc->crtc_offset, | ||
143 | (NI_GRPH_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) | | ||
144 | NI_OVL_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) | | ||
145 | NI_ICON_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) | | ||
146 | NI_CURSOR_DEGAMMA_MODE(NI_DEGAMMA_BYPASS))); | ||
147 | WREG32(NI_GAMUT_REMAP_CONTROL + radeon_crtc->crtc_offset, | ||
148 | (NI_GRPH_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS) | | ||
149 | NI_OVL_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS))); | ||
150 | WREG32(NI_REGAMMA_CONTROL + radeon_crtc->crtc_offset, | ||
151 | (NI_GRPH_REGAMMA_MODE(NI_REGAMMA_BYPASS) | | ||
152 | NI_OVL_REGAMMA_MODE(NI_REGAMMA_BYPASS))); | ||
153 | WREG32(NI_OUTPUT_CSC_CONTROL + radeon_crtc->crtc_offset, | ||
154 | (NI_OUTPUT_CSC_GRPH_MODE(NI_OUTPUT_CSC_BYPASS) | | ||
155 | NI_OUTPUT_CSC_OVL_MODE(NI_OUTPUT_CSC_BYPASS))); | ||
156 | /* XXX match this to the depth of the crtc fmt block, move to modeset? */ | ||
157 | WREG32(0x6940 + radeon_crtc->crtc_offset, 0); | ||
158 | |||
159 | } | ||
160 | |||
101 | static void legacy_crtc_load_lut(struct drm_crtc *crtc) | 161 | static void legacy_crtc_load_lut(struct drm_crtc *crtc) |
102 | { | 162 | { |
103 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 163 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
@@ -130,8 +190,10 @@ void radeon_crtc_load_lut(struct drm_crtc *crtc) | |||
130 | if (!crtc->enabled) | 190 | if (!crtc->enabled) |
131 | return; | 191 | return; |
132 | 192 | ||
133 | if (ASIC_IS_DCE4(rdev)) | 193 | if (ASIC_IS_DCE5(rdev)) |
134 | evergreen_crtc_load_lut(crtc); | 194 | dce5_crtc_load_lut(crtc); |
195 | else if (ASIC_IS_DCE4(rdev)) | ||
196 | dce4_crtc_load_lut(crtc); | ||
135 | else if (ASIC_IS_AVIVO(rdev)) | 197 | else if (ASIC_IS_AVIVO(rdev)) |
136 | avivo_crtc_load_lut(crtc); | 198 | avivo_crtc_load_lut(crtc); |
137 | else | 199 | else |
@@ -183,12 +245,272 @@ static void radeon_crtc_destroy(struct drm_crtc *crtc) | |||
183 | kfree(radeon_crtc); | 245 | kfree(radeon_crtc); |
184 | } | 246 | } |
185 | 247 | ||
248 | /* | ||
249 | * Handle unpin events outside the interrupt handler proper. | ||
250 | */ | ||
251 | static void radeon_unpin_work_func(struct work_struct *__work) | ||
252 | { | ||
253 | struct radeon_unpin_work *work = | ||
254 | container_of(__work, struct radeon_unpin_work, work); | ||
255 | int r; | ||
256 | |||
257 | /* unpin of the old buffer */ | ||
258 | r = radeon_bo_reserve(work->old_rbo, false); | ||
259 | if (likely(r == 0)) { | ||
260 | r = radeon_bo_unpin(work->old_rbo); | ||
261 | if (unlikely(r != 0)) { | ||
262 | DRM_ERROR("failed to unpin buffer after flip\n"); | ||
263 | } | ||
264 | radeon_bo_unreserve(work->old_rbo); | ||
265 | } else | ||
266 | DRM_ERROR("failed to reserve buffer after flip\n"); | ||
267 | kfree(work); | ||
268 | } | ||
269 | |||
270 | void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id) | ||
271 | { | ||
272 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; | ||
273 | struct radeon_unpin_work *work; | ||
274 | struct drm_pending_vblank_event *e; | ||
275 | struct timeval now; | ||
276 | unsigned long flags; | ||
277 | u32 update_pending; | ||
278 | int vpos, hpos; | ||
279 | |||
280 | spin_lock_irqsave(&rdev->ddev->event_lock, flags); | ||
281 | work = radeon_crtc->unpin_work; | ||
282 | if (work == NULL || | ||
283 | !radeon_fence_signaled(work->fence)) { | ||
284 | spin_unlock_irqrestore(&rdev->ddev->event_lock, flags); | ||
285 | return; | ||
286 | } | ||
287 | /* New pageflip, or just completion of a previous one? */ | ||
288 | if (!radeon_crtc->deferred_flip_completion) { | ||
289 | /* do the flip (mmio) */ | ||
290 | update_pending = radeon_page_flip(rdev, crtc_id, work->new_crtc_base); | ||
291 | } else { | ||
292 | /* This is just a completion of a flip queued in crtc | ||
293 | * at last invocation. Make sure we go directly to | ||
294 | * completion routine. | ||
295 | */ | ||
296 | update_pending = 0; | ||
297 | radeon_crtc->deferred_flip_completion = 0; | ||
298 | } | ||
299 | |||
300 | /* Has the pageflip already completed in crtc, or is it certain | ||
301 | * to complete in this vblank? | ||
302 | */ | ||
303 | if (update_pending && | ||
304 | (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id, | ||
305 | &vpos, &hpos)) && | ||
306 | (vpos >=0) && | ||
307 | (vpos < (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100)) { | ||
308 | /* crtc didn't flip in this target vblank interval, | ||
309 | * but flip is pending in crtc. It will complete it | ||
310 | * in next vblank interval, so complete the flip at | ||
311 | * next vblank irq. | ||
312 | */ | ||
313 | radeon_crtc->deferred_flip_completion = 1; | ||
314 | spin_unlock_irqrestore(&rdev->ddev->event_lock, flags); | ||
315 | return; | ||
316 | } | ||
317 | |||
318 | /* Pageflip (will be) certainly completed in this vblank. Clean up. */ | ||
319 | radeon_crtc->unpin_work = NULL; | ||
320 | |||
321 | /* wakeup userspace */ | ||
322 | if (work->event) { | ||
323 | e = work->event; | ||
324 | e->event.sequence = drm_vblank_count_and_time(rdev->ddev, crtc_id, &now); | ||
325 | e->event.tv_sec = now.tv_sec; | ||
326 | e->event.tv_usec = now.tv_usec; | ||
327 | list_add_tail(&e->base.link, &e->base.file_priv->event_list); | ||
328 | wake_up_interruptible(&e->base.file_priv->event_wait); | ||
329 | } | ||
330 | spin_unlock_irqrestore(&rdev->ddev->event_lock, flags); | ||
331 | |||
332 | drm_vblank_put(rdev->ddev, radeon_crtc->crtc_id); | ||
333 | radeon_fence_unref(&work->fence); | ||
334 | radeon_post_page_flip(work->rdev, work->crtc_id); | ||
335 | schedule_work(&work->work); | ||
336 | } | ||
337 | |||
338 | static int radeon_crtc_page_flip(struct drm_crtc *crtc, | ||
339 | struct drm_framebuffer *fb, | ||
340 | struct drm_pending_vblank_event *event) | ||
341 | { | ||
342 | struct drm_device *dev = crtc->dev; | ||
343 | struct radeon_device *rdev = dev->dev_private; | ||
344 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
345 | struct radeon_framebuffer *old_radeon_fb; | ||
346 | struct radeon_framebuffer *new_radeon_fb; | ||
347 | struct drm_gem_object *obj; | ||
348 | struct radeon_bo *rbo; | ||
349 | struct radeon_fence *fence; | ||
350 | struct radeon_unpin_work *work; | ||
351 | unsigned long flags; | ||
352 | u32 tiling_flags, pitch_pixels; | ||
353 | u64 base; | ||
354 | int r; | ||
355 | |||
356 | work = kzalloc(sizeof *work, GFP_KERNEL); | ||
357 | if (work == NULL) | ||
358 | return -ENOMEM; | ||
359 | |||
360 | r = radeon_fence_create(rdev, &fence); | ||
361 | if (unlikely(r != 0)) { | ||
362 | kfree(work); | ||
363 | DRM_ERROR("flip queue: failed to create fence.\n"); | ||
364 | return -ENOMEM; | ||
365 | } | ||
366 | work->event = event; | ||
367 | work->rdev = rdev; | ||
368 | work->crtc_id = radeon_crtc->crtc_id; | ||
369 | work->fence = radeon_fence_ref(fence); | ||
370 | old_radeon_fb = to_radeon_framebuffer(crtc->fb); | ||
371 | new_radeon_fb = to_radeon_framebuffer(fb); | ||
372 | /* schedule unpin of the old buffer */ | ||
373 | obj = old_radeon_fb->obj; | ||
374 | rbo = obj->driver_private; | ||
375 | work->old_rbo = rbo; | ||
376 | INIT_WORK(&work->work, radeon_unpin_work_func); | ||
377 | |||
378 | /* We borrow the event spin lock for protecting unpin_work */ | ||
379 | spin_lock_irqsave(&dev->event_lock, flags); | ||
380 | if (radeon_crtc->unpin_work) { | ||
381 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
382 | kfree(work); | ||
383 | radeon_fence_unref(&fence); | ||
384 | |||
385 | DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); | ||
386 | return -EBUSY; | ||
387 | } | ||
388 | radeon_crtc->unpin_work = work; | ||
389 | radeon_crtc->deferred_flip_completion = 0; | ||
390 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
391 | |||
392 | /* pin the new buffer */ | ||
393 | obj = new_radeon_fb->obj; | ||
394 | rbo = obj->driver_private; | ||
395 | |||
396 | DRM_DEBUG_DRIVER("flip-ioctl() cur_fbo = %p, cur_bbo = %p\n", | ||
397 | work->old_rbo, rbo); | ||
398 | |||
399 | r = radeon_bo_reserve(rbo, false); | ||
400 | if (unlikely(r != 0)) { | ||
401 | DRM_ERROR("failed to reserve new rbo buffer before flip\n"); | ||
402 | goto pflip_cleanup; | ||
403 | } | ||
404 | r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &base); | ||
405 | if (unlikely(r != 0)) { | ||
406 | radeon_bo_unreserve(rbo); | ||
407 | r = -EINVAL; | ||
408 | DRM_ERROR("failed to pin new rbo buffer before flip\n"); | ||
409 | goto pflip_cleanup; | ||
410 | } | ||
411 | radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); | ||
412 | radeon_bo_unreserve(rbo); | ||
413 | |||
414 | if (!ASIC_IS_AVIVO(rdev)) { | ||
415 | /* crtc offset is from display base addr not FB location */ | ||
416 | base -= radeon_crtc->legacy_display_base_addr; | ||
417 | pitch_pixels = fb->pitch / (fb->bits_per_pixel / 8); | ||
418 | |||
419 | if (tiling_flags & RADEON_TILING_MACRO) { | ||
420 | if (ASIC_IS_R300(rdev)) { | ||
421 | base &= ~0x7ff; | ||
422 | } else { | ||
423 | int byteshift = fb->bits_per_pixel >> 4; | ||
424 | int tile_addr = (((crtc->y >> 3) * pitch_pixels + crtc->x) >> (8 - byteshift)) << 11; | ||
425 | base += tile_addr + ((crtc->x << byteshift) % 256) + ((crtc->y % 8) << 8); | ||
426 | } | ||
427 | } else { | ||
428 | int offset = crtc->y * pitch_pixels + crtc->x; | ||
429 | switch (fb->bits_per_pixel) { | ||
430 | case 8: | ||
431 | default: | ||
432 | offset *= 1; | ||
433 | break; | ||
434 | case 15: | ||
435 | case 16: | ||
436 | offset *= 2; | ||
437 | break; | ||
438 | case 24: | ||
439 | offset *= 3; | ||
440 | break; | ||
441 | case 32: | ||
442 | offset *= 4; | ||
443 | break; | ||
444 | } | ||
445 | base += offset; | ||
446 | } | ||
447 | base &= ~7; | ||
448 | } | ||
449 | |||
450 | spin_lock_irqsave(&dev->event_lock, flags); | ||
451 | work->new_crtc_base = base; | ||
452 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
453 | |||
454 | /* update crtc fb */ | ||
455 | crtc->fb = fb; | ||
456 | |||
457 | r = drm_vblank_get(dev, radeon_crtc->crtc_id); | ||
458 | if (r) { | ||
459 | DRM_ERROR("failed to get vblank before flip\n"); | ||
460 | goto pflip_cleanup1; | ||
461 | } | ||
462 | |||
463 | /* 32 ought to cover us */ | ||
464 | r = radeon_ring_lock(rdev, 32); | ||
465 | if (r) { | ||
466 | DRM_ERROR("failed to lock the ring before flip\n"); | ||
467 | goto pflip_cleanup2; | ||
468 | } | ||
469 | |||
470 | /* emit the fence */ | ||
471 | radeon_fence_emit(rdev, fence); | ||
472 | /* set the proper interrupt */ | ||
473 | radeon_pre_page_flip(rdev, radeon_crtc->crtc_id); | ||
474 | /* fire the ring */ | ||
475 | radeon_ring_unlock_commit(rdev); | ||
476 | |||
477 | return 0; | ||
478 | |||
479 | pflip_cleanup2: | ||
480 | drm_vblank_put(dev, radeon_crtc->crtc_id); | ||
481 | |||
482 | pflip_cleanup1: | ||
483 | r = radeon_bo_reserve(rbo, false); | ||
484 | if (unlikely(r != 0)) { | ||
485 | DRM_ERROR("failed to reserve new rbo in error path\n"); | ||
486 | goto pflip_cleanup; | ||
487 | } | ||
488 | r = radeon_bo_unpin(rbo); | ||
489 | if (unlikely(r != 0)) { | ||
490 | radeon_bo_unreserve(rbo); | ||
491 | r = -EINVAL; | ||
492 | DRM_ERROR("failed to unpin new rbo in error path\n"); | ||
493 | goto pflip_cleanup; | ||
494 | } | ||
495 | radeon_bo_unreserve(rbo); | ||
496 | |||
497 | pflip_cleanup: | ||
498 | spin_lock_irqsave(&dev->event_lock, flags); | ||
499 | radeon_crtc->unpin_work = NULL; | ||
500 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
501 | radeon_fence_unref(&fence); | ||
502 | kfree(work); | ||
503 | |||
504 | return r; | ||
505 | } | ||
506 | |||
186 | static const struct drm_crtc_funcs radeon_crtc_funcs = { | 507 | static const struct drm_crtc_funcs radeon_crtc_funcs = { |
187 | .cursor_set = radeon_crtc_cursor_set, | 508 | .cursor_set = radeon_crtc_cursor_set, |
188 | .cursor_move = radeon_crtc_cursor_move, | 509 | .cursor_move = radeon_crtc_cursor_move, |
189 | .gamma_set = radeon_crtc_gamma_set, | 510 | .gamma_set = radeon_crtc_gamma_set, |
190 | .set_config = drm_crtc_helper_set_config, | 511 | .set_config = drm_crtc_helper_set_config, |
191 | .destroy = radeon_crtc_destroy, | 512 | .destroy = radeon_crtc_destroy, |
513 | .page_flip = radeon_crtc_page_flip, | ||
192 | }; | 514 | }; |
193 | 515 | ||
194 | static void radeon_crtc_init(struct drm_device *dev, int index) | 516 | static void radeon_crtc_init(struct drm_device *dev, int index) |
@@ -225,7 +547,7 @@ static void radeon_crtc_init(struct drm_device *dev, int index) | |||
225 | radeon_legacy_init_crtc(dev, radeon_crtc); | 547 | radeon_legacy_init_crtc(dev, radeon_crtc); |
226 | } | 548 | } |
227 | 549 | ||
228 | static const char *encoder_names[34] = { | 550 | static const char *encoder_names[36] = { |
229 | "NONE", | 551 | "NONE", |
230 | "INTERNAL_LVDS", | 552 | "INTERNAL_LVDS", |
231 | "INTERNAL_TMDS1", | 553 | "INTERNAL_TMDS1", |
@@ -260,6 +582,8 @@ static const char *encoder_names[34] = { | |||
260 | "INTERNAL_KLDSCP_LVTMA", | 582 | "INTERNAL_KLDSCP_LVTMA", |
261 | "INTERNAL_UNIPHY1", | 583 | "INTERNAL_UNIPHY1", |
262 | "INTERNAL_UNIPHY2", | 584 | "INTERNAL_UNIPHY2", |
585 | "NUTMEG", | ||
586 | "TRAVIS", | ||
263 | }; | 587 | }; |
264 | 588 | ||
265 | static const char *connector_names[15] = { | 589 | static const char *connector_names[15] = { |
@@ -417,9 +741,17 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) | |||
417 | if (!radeon_connector->edid) { | 741 | if (!radeon_connector->edid) { |
418 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); | 742 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); |
419 | } | 743 | } |
420 | /* some servers provide a hardcoded edid in rom for KVMs */ | 744 | |
421 | if (!radeon_connector->edid) | 745 | if (!radeon_connector->edid) { |
422 | radeon_connector->edid = radeon_combios_get_hardcoded_edid(rdev); | 746 | if (rdev->is_atom_bios) { |
747 | /* some laptops provide a hardcoded edid in rom for LCDs */ | ||
748 | if (((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_LVDS) || | ||
749 | (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP))) | ||
750 | radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev); | ||
751 | } else | ||
752 | /* some servers provide a hardcoded edid in rom for KVMs */ | ||
753 | radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev); | ||
754 | } | ||
423 | if (radeon_connector->edid) { | 755 | if (radeon_connector->edid) { |
424 | drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid); | 756 | drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid); |
425 | ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid); | 757 | ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid); |
@@ -849,7 +1181,10 @@ int radeon_modeset_init(struct radeon_device *rdev) | |||
849 | 1181 | ||
850 | rdev->ddev->mode_config.funcs = (void *)&radeon_mode_funcs; | 1182 | rdev->ddev->mode_config.funcs = (void *)&radeon_mode_funcs; |
851 | 1183 | ||
852 | if (ASIC_IS_AVIVO(rdev)) { | 1184 | if (ASIC_IS_DCE5(rdev)) { |
1185 | rdev->ddev->mode_config.max_width = 16384; | ||
1186 | rdev->ddev->mode_config.max_height = 16384; | ||
1187 | } else if (ASIC_IS_AVIVO(rdev)) { | ||
853 | rdev->ddev->mode_config.max_width = 8192; | 1188 | rdev->ddev->mode_config.max_width = 8192; |
854 | rdev->ddev->mode_config.max_height = 8192; | 1189 | rdev->ddev->mode_config.max_height = 8192; |
855 | } else { | 1190 | } else { |
@@ -1019,7 +1354,7 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
1019 | /* | 1354 | /* |
1020 | * Retrieve current video scanout position of crtc on a given gpu. | 1355 | * Retrieve current video scanout position of crtc on a given gpu. |
1021 | * | 1356 | * |
1022 | * \param rdev Device to query. | 1357 | * \param dev Device to query. |
1023 | * \param crtc Crtc to query. | 1358 | * \param crtc Crtc to query. |
1024 | * \param *vpos Location where vertical scanout position should be stored. | 1359 | * \param *vpos Location where vertical scanout position should be stored. |
1025 | * \param *hpos Location where horizontal scanout position should go. | 1360 | * \param *hpos Location where horizontal scanout position should go. |
@@ -1031,72 +1366,74 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
1031 | * | 1366 | * |
1032 | * \return Flags, or'ed together as follows: | 1367 | * \return Flags, or'ed together as follows: |
1033 | * | 1368 | * |
1034 | * RADEON_SCANOUTPOS_VALID = Query successfull. | 1369 | * DRM_SCANOUTPOS_VALID = Query successfull. |
1035 | * RADEON_SCANOUTPOS_INVBL = Inside vblank. | 1370 | * DRM_SCANOUTPOS_INVBL = Inside vblank. |
1036 | * RADEON_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of | 1371 | * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of |
1037 | * this flag means that returned position may be offset by a constant but | 1372 | * this flag means that returned position may be offset by a constant but |
1038 | * unknown small number of scanlines wrt. real scanout position. | 1373 | * unknown small number of scanlines wrt. real scanout position. |
1039 | * | 1374 | * |
1040 | */ | 1375 | */ |
1041 | int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, int *hpos) | 1376 | int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int *hpos) |
1042 | { | 1377 | { |
1043 | u32 stat_crtc = 0, vbl = 0, position = 0; | 1378 | u32 stat_crtc = 0, vbl = 0, position = 0; |
1044 | int vbl_start, vbl_end, vtotal, ret = 0; | 1379 | int vbl_start, vbl_end, vtotal, ret = 0; |
1045 | bool in_vbl = true; | 1380 | bool in_vbl = true; |
1046 | 1381 | ||
1382 | struct radeon_device *rdev = dev->dev_private; | ||
1383 | |||
1047 | if (ASIC_IS_DCE4(rdev)) { | 1384 | if (ASIC_IS_DCE4(rdev)) { |
1048 | if (crtc == 0) { | 1385 | if (crtc == 0) { |
1049 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + | 1386 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + |
1050 | EVERGREEN_CRTC0_REGISTER_OFFSET); | 1387 | EVERGREEN_CRTC0_REGISTER_OFFSET); |
1051 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + | 1388 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + |
1052 | EVERGREEN_CRTC0_REGISTER_OFFSET); | 1389 | EVERGREEN_CRTC0_REGISTER_OFFSET); |
1053 | ret |= RADEON_SCANOUTPOS_VALID; | 1390 | ret |= DRM_SCANOUTPOS_VALID; |
1054 | } | 1391 | } |
1055 | if (crtc == 1) { | 1392 | if (crtc == 1) { |
1056 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + | 1393 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + |
1057 | EVERGREEN_CRTC1_REGISTER_OFFSET); | 1394 | EVERGREEN_CRTC1_REGISTER_OFFSET); |
1058 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + | 1395 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + |
1059 | EVERGREEN_CRTC1_REGISTER_OFFSET); | 1396 | EVERGREEN_CRTC1_REGISTER_OFFSET); |
1060 | ret |= RADEON_SCANOUTPOS_VALID; | 1397 | ret |= DRM_SCANOUTPOS_VALID; |
1061 | } | 1398 | } |
1062 | if (crtc == 2) { | 1399 | if (crtc == 2) { |
1063 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + | 1400 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + |
1064 | EVERGREEN_CRTC2_REGISTER_OFFSET); | 1401 | EVERGREEN_CRTC2_REGISTER_OFFSET); |
1065 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + | 1402 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + |
1066 | EVERGREEN_CRTC2_REGISTER_OFFSET); | 1403 | EVERGREEN_CRTC2_REGISTER_OFFSET); |
1067 | ret |= RADEON_SCANOUTPOS_VALID; | 1404 | ret |= DRM_SCANOUTPOS_VALID; |
1068 | } | 1405 | } |
1069 | if (crtc == 3) { | 1406 | if (crtc == 3) { |
1070 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + | 1407 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + |
1071 | EVERGREEN_CRTC3_REGISTER_OFFSET); | 1408 | EVERGREEN_CRTC3_REGISTER_OFFSET); |
1072 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + | 1409 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + |
1073 | EVERGREEN_CRTC3_REGISTER_OFFSET); | 1410 | EVERGREEN_CRTC3_REGISTER_OFFSET); |
1074 | ret |= RADEON_SCANOUTPOS_VALID; | 1411 | ret |= DRM_SCANOUTPOS_VALID; |
1075 | } | 1412 | } |
1076 | if (crtc == 4) { | 1413 | if (crtc == 4) { |
1077 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + | 1414 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + |
1078 | EVERGREEN_CRTC4_REGISTER_OFFSET); | 1415 | EVERGREEN_CRTC4_REGISTER_OFFSET); |
1079 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + | 1416 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + |
1080 | EVERGREEN_CRTC4_REGISTER_OFFSET); | 1417 | EVERGREEN_CRTC4_REGISTER_OFFSET); |
1081 | ret |= RADEON_SCANOUTPOS_VALID; | 1418 | ret |= DRM_SCANOUTPOS_VALID; |
1082 | } | 1419 | } |
1083 | if (crtc == 5) { | 1420 | if (crtc == 5) { |
1084 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + | 1421 | vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + |
1085 | EVERGREEN_CRTC5_REGISTER_OFFSET); | 1422 | EVERGREEN_CRTC5_REGISTER_OFFSET); |
1086 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + | 1423 | position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + |
1087 | EVERGREEN_CRTC5_REGISTER_OFFSET); | 1424 | EVERGREEN_CRTC5_REGISTER_OFFSET); |
1088 | ret |= RADEON_SCANOUTPOS_VALID; | 1425 | ret |= DRM_SCANOUTPOS_VALID; |
1089 | } | 1426 | } |
1090 | } else if (ASIC_IS_AVIVO(rdev)) { | 1427 | } else if (ASIC_IS_AVIVO(rdev)) { |
1091 | if (crtc == 0) { | 1428 | if (crtc == 0) { |
1092 | vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END); | 1429 | vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END); |
1093 | position = RREG32(AVIVO_D1CRTC_STATUS_POSITION); | 1430 | position = RREG32(AVIVO_D1CRTC_STATUS_POSITION); |
1094 | ret |= RADEON_SCANOUTPOS_VALID; | 1431 | ret |= DRM_SCANOUTPOS_VALID; |
1095 | } | 1432 | } |
1096 | if (crtc == 1) { | 1433 | if (crtc == 1) { |
1097 | vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END); | 1434 | vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END); |
1098 | position = RREG32(AVIVO_D2CRTC_STATUS_POSITION); | 1435 | position = RREG32(AVIVO_D2CRTC_STATUS_POSITION); |
1099 | ret |= RADEON_SCANOUTPOS_VALID; | 1436 | ret |= DRM_SCANOUTPOS_VALID; |
1100 | } | 1437 | } |
1101 | } else { | 1438 | } else { |
1102 | /* Pre-AVIVO: Different encoding of scanout pos and vblank interval. */ | 1439 | /* Pre-AVIVO: Different encoding of scanout pos and vblank interval. */ |
@@ -1112,7 +1449,7 @@ int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, | |||
1112 | if (!(stat_crtc & 1)) | 1449 | if (!(stat_crtc & 1)) |
1113 | in_vbl = false; | 1450 | in_vbl = false; |
1114 | 1451 | ||
1115 | ret |= RADEON_SCANOUTPOS_VALID; | 1452 | ret |= DRM_SCANOUTPOS_VALID; |
1116 | } | 1453 | } |
1117 | if (crtc == 1) { | 1454 | if (crtc == 1) { |
1118 | vbl = (RREG32(RADEON_CRTC2_V_TOTAL_DISP) & | 1455 | vbl = (RREG32(RADEON_CRTC2_V_TOTAL_DISP) & |
@@ -1122,7 +1459,7 @@ int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, | |||
1122 | if (!(stat_crtc & 1)) | 1459 | if (!(stat_crtc & 1)) |
1123 | in_vbl = false; | 1460 | in_vbl = false; |
1124 | 1461 | ||
1125 | ret |= RADEON_SCANOUTPOS_VALID; | 1462 | ret |= DRM_SCANOUTPOS_VALID; |
1126 | } | 1463 | } |
1127 | } | 1464 | } |
1128 | 1465 | ||
@@ -1133,13 +1470,13 @@ int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, | |||
1133 | /* Valid vblank area boundaries from gpu retrieved? */ | 1470 | /* Valid vblank area boundaries from gpu retrieved? */ |
1134 | if (vbl > 0) { | 1471 | if (vbl > 0) { |
1135 | /* Yes: Decode. */ | 1472 | /* Yes: Decode. */ |
1136 | ret |= RADEON_SCANOUTPOS_ACCURATE; | 1473 | ret |= DRM_SCANOUTPOS_ACCURATE; |
1137 | vbl_start = vbl & 0x1fff; | 1474 | vbl_start = vbl & 0x1fff; |
1138 | vbl_end = (vbl >> 16) & 0x1fff; | 1475 | vbl_end = (vbl >> 16) & 0x1fff; |
1139 | } | 1476 | } |
1140 | else { | 1477 | else { |
1141 | /* No: Fake something reasonable which gives at least ok results. */ | 1478 | /* No: Fake something reasonable which gives at least ok results. */ |
1142 | vbl_start = rdev->mode_info.crtcs[crtc]->base.mode.crtc_vdisplay; | 1479 | vbl_start = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay; |
1143 | vbl_end = 0; | 1480 | vbl_end = 0; |
1144 | } | 1481 | } |
1145 | 1482 | ||
@@ -1155,7 +1492,7 @@ int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, | |||
1155 | 1492 | ||
1156 | /* Inside "upper part" of vblank area? Apply corrective offset if so: */ | 1493 | /* Inside "upper part" of vblank area? Apply corrective offset if so: */ |
1157 | if (in_vbl && (*vpos >= vbl_start)) { | 1494 | if (in_vbl && (*vpos >= vbl_start)) { |
1158 | vtotal = rdev->mode_info.crtcs[crtc]->base.mode.crtc_vtotal; | 1495 | vtotal = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal; |
1159 | *vpos = *vpos - vtotal; | 1496 | *vpos = *vpos - vtotal; |
1160 | } | 1497 | } |
1161 | 1498 | ||
@@ -1164,7 +1501,7 @@ int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, | |||
1164 | 1501 | ||
1165 | /* In vblank? */ | 1502 | /* In vblank? */ |
1166 | if (in_vbl) | 1503 | if (in_vbl) |
1167 | ret |= RADEON_SCANOUTPOS_INVBL; | 1504 | ret |= DRM_SCANOUTPOS_INVBL; |
1168 | 1505 | ||
1169 | return ret; | 1506 | return ret; |
1170 | } | 1507 | } |