diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2016-01-12 05:01:12 -0500 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2016-01-12 05:01:12 -0500 |
| commit | 1f16f116b01c110db20ab808562c8b8bc3ee3d6e (patch) | |
| tree | 44db563f64cf5f8d62af8f99a61e2b248c44ea3a /drivers/gpu/drm/radeon | |
| parent | 03724ac3d48f8f0e3caf1d30fa134f8fd96c94e2 (diff) | |
| parent | f9eccf24615672896dc13251410c3f2f33a14f95 (diff) | |
Merge branches 'clockevents/4.4-fixes' and 'clockevents/4.5-fixes' of http://git.linaro.org/people/daniel.lezcano/linux into timers/urgent
Pull in fixes from Daniel Lezcano:
- Fix the vt8500 timer leading to a system lock up when dealing with too
small delta (Roman Volkov)
- Select the CLKSRC_MMIO when the fsl_ftm_timer is enabled with COMPILE_TEST
(Daniel Lezcano)
- Prevent to compile timers using the 'iomem' API when the architecture has
not HAS_IOMEM set (Richard Weinberger)
Diffstat (limited to 'drivers/gpu/drm/radeon')
| -rw-r--r-- | drivers/gpu/drm/radeon/cik.c | 11 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 12 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_agp.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_connectors.c | 21 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 106 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_irq_kms.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_kms.c | 50 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_vce.c | 100 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/rs600.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/rs690.c | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/rv730_dpm.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/rv770_dpm.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/si.c | 5 |
18 files changed, 253 insertions, 99 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 248953d2fdb7..f81fb2641097 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
| @@ -4173,11 +4173,7 @@ void cik_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | |||
| 4173 | control |= ib->length_dw | (vm_id << 24); | 4173 | control |= ib->length_dw | (vm_id << 24); |
| 4174 | 4174 | ||
| 4175 | radeon_ring_write(ring, header); | 4175 | radeon_ring_write(ring, header); |
| 4176 | radeon_ring_write(ring, | 4176 | radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFFC)); |
| 4177 | #ifdef __BIG_ENDIAN | ||
| 4178 | (2 << 0) | | ||
| 4179 | #endif | ||
| 4180 | (ib->gpu_addr & 0xFFFFFFFC)); | ||
| 4181 | radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF); | 4177 | radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF); |
| 4182 | radeon_ring_write(ring, control); | 4178 | radeon_ring_write(ring, control); |
| 4183 | } | 4179 | } |
| @@ -8472,7 +8468,7 @@ restart_ih: | |||
| 8472 | if (queue_dp) | 8468 | if (queue_dp) |
| 8473 | schedule_work(&rdev->dp_work); | 8469 | schedule_work(&rdev->dp_work); |
| 8474 | if (queue_hotplug) | 8470 | if (queue_hotplug) |
| 8475 | schedule_work(&rdev->hotplug_work); | 8471 | schedule_delayed_work(&rdev->hotplug_work, 0); |
| 8476 | if (queue_reset) { | 8472 | if (queue_reset) { |
| 8477 | rdev->needs_reset = true; | 8473 | rdev->needs_reset = true; |
| 8478 | wake_up_all(&rdev->fence_queue); | 8474 | wake_up_all(&rdev->fence_queue); |
| @@ -9630,6 +9626,9 @@ static void dce8_program_watermarks(struct radeon_device *rdev, | |||
| 9630 | (rdev->disp_priority == 2)) { | 9626 | (rdev->disp_priority == 2)) { |
| 9631 | DRM_DEBUG_KMS("force priority to high\n"); | 9627 | DRM_DEBUG_KMS("force priority to high\n"); |
| 9632 | } | 9628 | } |
| 9629 | |||
| 9630 | /* Save number of lines the linebuffer leads before the scanout */ | ||
| 9631 | radeon_crtc->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay); | ||
| 9633 | } | 9632 | } |
| 9634 | 9633 | ||
| 9635 | /* select wm A */ | 9634 | /* select wm A */ |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 7f33767d7ed6..2ad462896896 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
| @@ -2372,6 +2372,9 @@ static void evergreen_program_watermarks(struct radeon_device *rdev, | |||
| 2372 | c.full = dfixed_div(c, a); | 2372 | c.full = dfixed_div(c, a); |
| 2373 | priority_b_mark = dfixed_trunc(c); | 2373 | priority_b_mark = dfixed_trunc(c); |
| 2374 | priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK; | 2374 | priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK; |
| 2375 | |||
| 2376 | /* Save number of lines the linebuffer leads before the scanout */ | ||
| 2377 | radeon_crtc->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay); | ||
| 2375 | } | 2378 | } |
| 2376 | 2379 | ||
| 2377 | /* select wm A */ | 2380 | /* select wm A */ |
| @@ -5344,7 +5347,7 @@ restart_ih: | |||
| 5344 | if (queue_dp) | 5347 | if (queue_dp) |
| 5345 | schedule_work(&rdev->dp_work); | 5348 | schedule_work(&rdev->dp_work); |
| 5346 | if (queue_hotplug) | 5349 | if (queue_hotplug) |
| 5347 | schedule_work(&rdev->hotplug_work); | 5350 | schedule_delayed_work(&rdev->hotplug_work, 0); |
| 5348 | if (queue_hdmi) | 5351 | if (queue_hdmi) |
| 5349 | schedule_work(&rdev->audio_work); | 5352 | schedule_work(&rdev->audio_work); |
| 5350 | if (queue_thermal && rdev->pm.dpm_enabled) | 5353 | if (queue_thermal && rdev->pm.dpm_enabled) |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 238b13f045c1..9e7e2bf03b81 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
| @@ -806,7 +806,7 @@ int r100_irq_process(struct radeon_device *rdev) | |||
| 806 | status = r100_irq_ack(rdev); | 806 | status = r100_irq_ack(rdev); |
| 807 | } | 807 | } |
| 808 | if (queue_hotplug) | 808 | if (queue_hotplug) |
| 809 | schedule_work(&rdev->hotplug_work); | 809 | schedule_delayed_work(&rdev->hotplug_work, 0); |
| 810 | if (rdev->msi_enabled) { | 810 | if (rdev->msi_enabled) { |
| 811 | switch (rdev->family) { | 811 | switch (rdev->family) { |
| 812 | case CHIP_RS400: | 812 | case CHIP_RS400: |
| @@ -3217,6 +3217,9 @@ void r100_bandwidth_update(struct radeon_device *rdev) | |||
| 3217 | uint32_t pixel_bytes1 = 0; | 3217 | uint32_t pixel_bytes1 = 0; |
| 3218 | uint32_t pixel_bytes2 = 0; | 3218 | uint32_t pixel_bytes2 = 0; |
| 3219 | 3219 | ||
| 3220 | /* Guess line buffer size to be 8192 pixels */ | ||
| 3221 | u32 lb_size = 8192; | ||
| 3222 | |||
| 3220 | if (!rdev->mode_info.mode_config_initialized) | 3223 | if (!rdev->mode_info.mode_config_initialized) |
| 3221 | return; | 3224 | return; |
| 3222 | 3225 | ||
| @@ -3631,6 +3634,13 @@ void r100_bandwidth_update(struct radeon_device *rdev) | |||
| 3631 | DRM_DEBUG_KMS("GRPH2_BUFFER_CNTL from to %x\n", | 3634 | DRM_DEBUG_KMS("GRPH2_BUFFER_CNTL from to %x\n", |
| 3632 | (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL)); | 3635 | (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL)); |
| 3633 | } | 3636 | } |
| 3637 | |||
| 3638 | /* Save number of lines the linebuffer leads before the scanout */ | ||
| 3639 | if (mode1) | ||
| 3640 | rdev->mode_info.crtcs[0]->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode1->crtc_hdisplay); | ||
| 3641 | |||
| 3642 | if (mode2) | ||
| 3643 | rdev->mode_info.crtcs[1]->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode2->crtc_hdisplay); | ||
| 3634 | } | 3644 | } |
| 3635 | 3645 | ||
| 3636 | int r100_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) | 3646 | int r100_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 4ea5b10ff5f4..cc2fdf0be37a 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -4276,7 +4276,7 @@ restart_ih: | |||
| 4276 | WREG32(IH_RB_RPTR, rptr); | 4276 | WREG32(IH_RB_RPTR, rptr); |
| 4277 | } | 4277 | } |
| 4278 | if (queue_hotplug) | 4278 | if (queue_hotplug) |
| 4279 | schedule_work(&rdev->hotplug_work); | 4279 | schedule_delayed_work(&rdev->hotplug_work, 0); |
| 4280 | if (queue_hdmi) | 4280 | if (queue_hdmi) |
| 4281 | schedule_work(&rdev->audio_work); | 4281 | schedule_work(&rdev->audio_work); |
| 4282 | if (queue_thermal && rdev->pm.dpm_enabled) | 4282 | if (queue_thermal && rdev->pm.dpm_enabled) |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index b6cbd816537e..87db64983ea8 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -2414,7 +2414,7 @@ struct radeon_device { | |||
| 2414 | struct r600_ih ih; /* r6/700 interrupt ring */ | 2414 | struct r600_ih ih; /* r6/700 interrupt ring */ |
| 2415 | struct radeon_rlc rlc; | 2415 | struct radeon_rlc rlc; |
| 2416 | struct radeon_mec mec; | 2416 | struct radeon_mec mec; |
| 2417 | struct work_struct hotplug_work; | 2417 | struct delayed_work hotplug_work; |
| 2418 | struct work_struct dp_work; | 2418 | struct work_struct dp_work; |
| 2419 | struct work_struct audio_work; | 2419 | struct work_struct audio_work; |
| 2420 | int num_crtc; /* number of crtcs */ | 2420 | int num_crtc; /* number of crtcs */ |
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index fe994aac3b04..c77d349c561c 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c | |||
| @@ -54,6 +54,9 @@ static struct radeon_agpmode_quirk radeon_agpmode_quirk_list[] = { | |||
| 54 | /* Intel 82855PM host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (lp #195051) */ | 54 | /* Intel 82855PM host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (lp #195051) */ |
| 55 | { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4e50, | 55 | { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4e50, |
| 56 | PCI_VENDOR_ID_IBM, 0x0550, 1}, | 56 | PCI_VENDOR_ID_IBM, 0x0550, 1}, |
| 57 | /* Intel 82855PM host bridge / RV250/M9 GL [Mobility FireGL 9000/Radeon 9000] needs AGPMode 1 (Thinkpad T40p) */ | ||
| 58 | { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c66, | ||
| 59 | PCI_VENDOR_ID_IBM, 0x054d, 1}, | ||
| 57 | /* Intel 82855PM host bridge / Mobility M7 needs AGPMode 1 */ | 60 | /* Intel 82855PM host bridge / Mobility M7 needs AGPMode 1 */ |
| 58 | { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c57, | 61 | { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c57, |
| 59 | PCI_VENDOR_ID_IBM, 0x0530, 1}, | 62 | PCI_VENDOR_ID_IBM, 0x0530, 1}, |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 5a2cafb4f1bc..340f3f549f29 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
| @@ -1234,13 +1234,32 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
| 1234 | if (r < 0) | 1234 | if (r < 0) |
| 1235 | return connector_status_disconnected; | 1235 | return connector_status_disconnected; |
| 1236 | 1236 | ||
| 1237 | if (radeon_connector->detected_hpd_without_ddc) { | ||
| 1238 | force = true; | ||
| 1239 | radeon_connector->detected_hpd_without_ddc = false; | ||
| 1240 | } | ||
| 1241 | |||
| 1237 | if (!force && radeon_check_hpd_status_unchanged(connector)) { | 1242 | if (!force && radeon_check_hpd_status_unchanged(connector)) { |
| 1238 | ret = connector->status; | 1243 | ret = connector->status; |
| 1239 | goto exit; | 1244 | goto exit; |
| 1240 | } | 1245 | } |
| 1241 | 1246 | ||
| 1242 | if (radeon_connector->ddc_bus) | 1247 | if (radeon_connector->ddc_bus) { |
| 1243 | dret = radeon_ddc_probe(radeon_connector, false); | 1248 | dret = radeon_ddc_probe(radeon_connector, false); |
| 1249 | |||
| 1250 | /* Sometimes the pins required for the DDC probe on DVI | ||
| 1251 | * connectors don't make contact at the same time that the ones | ||
| 1252 | * for HPD do. If the DDC probe fails even though we had an HPD | ||
| 1253 | * signal, try again later */ | ||
| 1254 | if (!dret && !force && | ||
| 1255 | connector->status != connector_status_connected) { | ||
| 1256 | DRM_DEBUG_KMS("hpd detected without ddc, retrying in 1 second\n"); | ||
| 1257 | radeon_connector->detected_hpd_without_ddc = true; | ||
| 1258 | schedule_delayed_work(&rdev->hotplug_work, | ||
| 1259 | msecs_to_jiffies(1000)); | ||
| 1260 | goto exit; | ||
| 1261 | } | ||
| 1262 | } | ||
| 1244 | if (dret) { | 1263 | if (dret) { |
| 1245 | radeon_connector->detected_by_load = false; | 1264 | radeon_connector->detected_by_load = false; |
| 1246 | radeon_connector_free_edid(connector); | 1265 | radeon_connector_free_edid(connector); |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index a8d9927ed9eb..1eca0acac016 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
| @@ -322,7 +322,9 @@ void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id) | |||
| 322 | * to complete in this vblank? | 322 | * to complete in this vblank? |
| 323 | */ | 323 | */ |
| 324 | if (update_pending && | 324 | if (update_pending && |
| 325 | (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id, 0, | 325 | (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, |
| 326 | crtc_id, | ||
| 327 | USE_REAL_VBLANKSTART, | ||
| 326 | &vpos, &hpos, NULL, NULL, | 328 | &vpos, &hpos, NULL, NULL, |
| 327 | &rdev->mode_info.crtcs[crtc_id]->base.hwmode)) && | 329 | &rdev->mode_info.crtcs[crtc_id]->base.hwmode)) && |
| 328 | ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) || | 330 | ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) || |
| @@ -401,6 +403,8 @@ static void radeon_flip_work_func(struct work_struct *__work) | |||
| 401 | struct drm_crtc *crtc = &radeon_crtc->base; | 403 | struct drm_crtc *crtc = &radeon_crtc->base; |
| 402 | unsigned long flags; | 404 | unsigned long flags; |
| 403 | int r; | 405 | int r; |
| 406 | int vpos, hpos, stat, min_udelay; | ||
| 407 | struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id]; | ||
| 404 | 408 | ||
| 405 | down_read(&rdev->exclusive_lock); | 409 | down_read(&rdev->exclusive_lock); |
| 406 | if (work->fence) { | 410 | if (work->fence) { |
| @@ -437,6 +441,41 @@ static void radeon_flip_work_func(struct work_struct *__work) | |||
| 437 | /* set the proper interrupt */ | 441 | /* set the proper interrupt */ |
| 438 | radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id); | 442 | radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id); |
| 439 | 443 | ||
| 444 | /* If this happens to execute within the "virtually extended" vblank | ||
| 445 | * interval before the start of the real vblank interval then it needs | ||
| 446 | * to delay programming the mmio flip until the real vblank is entered. | ||
| 447 | * This prevents completing a flip too early due to the way we fudge | ||
| 448 | * our vblank counter and vblank timestamps in order to work around the | ||
| 449 | * problem that the hw fires vblank interrupts before actual start of | ||
| 450 | * vblank (when line buffer refilling is done for a frame). It | ||
| 451 | * complements the fudging logic in radeon_get_crtc_scanoutpos() for | ||
| 452 | * timestamping and radeon_get_vblank_counter_kms() for vblank counts. | ||
| 453 | * | ||
| 454 | * In practice this won't execute very often unless on very fast | ||
| 455 | * machines because the time window for this to happen is very small. | ||
| 456 | */ | ||
| 457 | for (;;) { | ||
| 458 | /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank | ||
| 459 | * start in hpos, and to the "fudged earlier" vblank start in | ||
| 460 | * vpos. | ||
| 461 | */ | ||
| 462 | stat = radeon_get_crtc_scanoutpos(rdev->ddev, work->crtc_id, | ||
| 463 | GET_DISTANCE_TO_VBLANKSTART, | ||
| 464 | &vpos, &hpos, NULL, NULL, | ||
| 465 | &crtc->hwmode); | ||
| 466 | |||
| 467 | if ((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) != | ||
| 468 | (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE) || | ||
| 469 | !(vpos >= 0 && hpos <= 0)) | ||
| 470 | break; | ||
| 471 | |||
| 472 | /* Sleep at least until estimated real start of hw vblank */ | ||
| 473 | spin_unlock_irqrestore(&crtc->dev->event_lock, flags); | ||
| 474 | min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5); | ||
| 475 | usleep_range(min_udelay, 2 * min_udelay); | ||
| 476 | spin_lock_irqsave(&crtc->dev->event_lock, flags); | ||
| 477 | }; | ||
| 478 | |||
| 440 | /* do the flip (mmio) */ | 479 | /* do the flip (mmio) */ |
| 441 | radeon_page_flip(rdev, radeon_crtc->crtc_id, work->base); | 480 | radeon_page_flip(rdev, radeon_crtc->crtc_id, work->base); |
| 442 | 481 | ||
| @@ -1768,6 +1807,15 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
| 1768 | * \param dev Device to query. | 1807 | * \param dev Device to query. |
| 1769 | * \param crtc Crtc to query. | 1808 | * \param crtc Crtc to query. |
| 1770 | * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). | 1809 | * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). |
| 1810 | * For driver internal use only also supports these flags: | ||
| 1811 | * | ||
| 1812 | * USE_REAL_VBLANKSTART to use the real start of vblank instead | ||
| 1813 | * of a fudged earlier start of vblank. | ||
| 1814 | * | ||
| 1815 | * GET_DISTANCE_TO_VBLANKSTART to return distance to the | ||
| 1816 | * fudged earlier start of vblank in *vpos and the distance | ||
| 1817 | * to true start of vblank in *hpos. | ||
| 1818 | * | ||
| 1771 | * \param *vpos Location where vertical scanout position should be stored. | 1819 | * \param *vpos Location where vertical scanout position should be stored. |
| 1772 | * \param *hpos Location where horizontal scanout position should go. | 1820 | * \param *hpos Location where horizontal scanout position should go. |
| 1773 | * \param *stime Target location for timestamp taken immediately before | 1821 | * \param *stime Target location for timestamp taken immediately before |
| @@ -1911,10 +1959,40 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, | |||
| 1911 | vbl_end = 0; | 1959 | vbl_end = 0; |
| 1912 | } | 1960 | } |
| 1913 | 1961 | ||
| 1962 | /* Called from driver internal vblank counter query code? */ | ||
| 1963 | if (flags & GET_DISTANCE_TO_VBLANKSTART) { | ||
| 1964 | /* Caller wants distance from real vbl_start in *hpos */ | ||
| 1965 | *hpos = *vpos - vbl_start; | ||
| 1966 | } | ||
| 1967 | |||
| 1968 | /* Fudge vblank to start a few scanlines earlier to handle the | ||
| 1969 | * problem that vblank irqs fire a few scanlines before start | ||
| 1970 | * of vblank. Some driver internal callers need the true vblank | ||
| 1971 | * start to be used and signal this via the USE_REAL_VBLANKSTART flag. | ||
| 1972 | * | ||
| 1973 | * The cause of the "early" vblank irq is that the irq is triggered | ||
| 1974 | * by the line buffer logic when the line buffer read position enters | ||
| 1975 | * the vblank, whereas our crtc scanout position naturally lags the | ||
| 1976 | * line buffer read position. | ||
| 1977 | */ | ||
| 1978 | if (!(flags & USE_REAL_VBLANKSTART)) | ||
| 1979 | vbl_start -= rdev->mode_info.crtcs[pipe]->lb_vblank_lead_lines; | ||
| 1980 | |||
| 1914 | /* Test scanout position against vblank region. */ | 1981 | /* Test scanout position against vblank region. */ |
| 1915 | if ((*vpos < vbl_start) && (*vpos >= vbl_end)) | 1982 | if ((*vpos < vbl_start) && (*vpos >= vbl_end)) |
| 1916 | in_vbl = false; | 1983 | in_vbl = false; |
| 1917 | 1984 | ||
| 1985 | /* In vblank? */ | ||
| 1986 | if (in_vbl) | ||
| 1987 | ret |= DRM_SCANOUTPOS_IN_VBLANK; | ||
| 1988 | |||
| 1989 | /* Called from driver internal vblank counter query code? */ | ||
| 1990 | if (flags & GET_DISTANCE_TO_VBLANKSTART) { | ||
| 1991 | /* Caller wants distance from fudged earlier vbl_start */ | ||
| 1992 | *vpos -= vbl_start; | ||
| 1993 | return ret; | ||
| 1994 | } | ||
| 1995 | |||
| 1918 | /* Check if inside vblank area and apply corrective offsets: | 1996 | /* Check if inside vblank area and apply corrective offsets: |
| 1919 | * vpos will then be >=0 in video scanout area, but negative | 1997 | * vpos will then be >=0 in video scanout area, but negative |
| 1920 | * within vblank area, counting down the number of lines until | 1998 | * within vblank area, counting down the number of lines until |
| @@ -1930,31 +2008,5 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, | |||
| 1930 | /* Correct for shifted end of vbl at vbl_end. */ | 2008 | /* Correct for shifted end of vbl at vbl_end. */ |
| 1931 | *vpos = *vpos - vbl_end; | 2009 | *vpos = *vpos - vbl_end; |
| 1932 | 2010 | ||
| 1933 | /* In vblank? */ | ||
| 1934 | if (in_vbl) | ||
| 1935 | ret |= DRM_SCANOUTPOS_IN_VBLANK; | ||
| 1936 | |||
| 1937 | /* Is vpos outside nominal vblank area, but less than | ||
| 1938 | * 1/100 of a frame height away from start of vblank? | ||
| 1939 | * If so, assume this isn't a massively delayed vblank | ||
| 1940 | * interrupt, but a vblank interrupt that fired a few | ||
| 1941 | * microseconds before true start of vblank. Compensate | ||
| 1942 | * by adding a full frame duration to the final timestamp. | ||
| 1943 | * Happens, e.g., on ATI R500, R600. | ||
| 1944 | * | ||
| 1945 | * We only do this if DRM_CALLED_FROM_VBLIRQ. | ||
| 1946 | */ | ||
| 1947 | if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) { | ||
| 1948 | vbl_start = mode->crtc_vdisplay; | ||
| 1949 | vtotal = mode->crtc_vtotal; | ||
| 1950 | |||
| 1951 | if (vbl_start - *vpos < vtotal / 100) { | ||
| 1952 | *vpos -= vtotal; | ||
| 1953 | |||
| 1954 | /* Signal this correction as "applied". */ | ||
| 1955 | ret |= 0x8; | ||
| 1956 | } | ||
| 1957 | } | ||
| 1958 | |||
| 1959 | return ret; | 2011 | return ret; |
| 1960 | } | 2012 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 171d3e43c30c..979f3bf65f2c 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
| @@ -74,7 +74,7 @@ irqreturn_t radeon_driver_irq_handler_kms(int irq, void *arg) | |||
| 74 | static void radeon_hotplug_work_func(struct work_struct *work) | 74 | static void radeon_hotplug_work_func(struct work_struct *work) |
| 75 | { | 75 | { |
| 76 | struct radeon_device *rdev = container_of(work, struct radeon_device, | 76 | struct radeon_device *rdev = container_of(work, struct radeon_device, |
| 77 | hotplug_work); | 77 | hotplug_work.work); |
| 78 | struct drm_device *dev = rdev->ddev; | 78 | struct drm_device *dev = rdev->ddev; |
| 79 | struct drm_mode_config *mode_config = &dev->mode_config; | 79 | struct drm_mode_config *mode_config = &dev->mode_config; |
| 80 | struct drm_connector *connector; | 80 | struct drm_connector *connector; |
| @@ -302,7 +302,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev) | |||
| 302 | } | 302 | } |
| 303 | } | 303 | } |
| 304 | 304 | ||
| 305 | INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); | 305 | INIT_DELAYED_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); |
| 306 | INIT_WORK(&rdev->dp_work, radeon_dp_work_func); | 306 | INIT_WORK(&rdev->dp_work, radeon_dp_work_func); |
| 307 | INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi); | 307 | INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi); |
| 308 | 308 | ||
| @@ -310,7 +310,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev) | |||
| 310 | r = drm_irq_install(rdev->ddev, rdev->ddev->pdev->irq); | 310 | r = drm_irq_install(rdev->ddev, rdev->ddev->pdev->irq); |
| 311 | if (r) { | 311 | if (r) { |
| 312 | rdev->irq.installed = false; | 312 | rdev->irq.installed = false; |
| 313 | flush_work(&rdev->hotplug_work); | 313 | flush_delayed_work(&rdev->hotplug_work); |
| 314 | return r; | 314 | return r; |
| 315 | } | 315 | } |
| 316 | 316 | ||
| @@ -333,7 +333,7 @@ void radeon_irq_kms_fini(struct radeon_device *rdev) | |||
| 333 | rdev->irq.installed = false; | 333 | rdev->irq.installed = false; |
| 334 | if (rdev->msi_enabled) | 334 | if (rdev->msi_enabled) |
| 335 | pci_disable_msi(rdev->pdev); | 335 | pci_disable_msi(rdev->pdev); |
| 336 | flush_work(&rdev->hotplug_work); | 336 | flush_delayed_work(&rdev->hotplug_work); |
| 337 | } | 337 | } |
| 338 | } | 338 | } |
| 339 | 339 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 0ec6fcca16d3..d290a8a09036 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
| @@ -755,6 +755,8 @@ void radeon_driver_preclose_kms(struct drm_device *dev, | |||
| 755 | */ | 755 | */ |
| 756 | u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc) | 756 | u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc) |
| 757 | { | 757 | { |
| 758 | int vpos, hpos, stat; | ||
| 759 | u32 count; | ||
| 758 | struct radeon_device *rdev = dev->dev_private; | 760 | struct radeon_device *rdev = dev->dev_private; |
| 759 | 761 | ||
| 760 | if (crtc < 0 || crtc >= rdev->num_crtc) { | 762 | if (crtc < 0 || crtc >= rdev->num_crtc) { |
| @@ -762,7 +764,53 @@ u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc) | |||
| 762 | return -EINVAL; | 764 | return -EINVAL; |
| 763 | } | 765 | } |
| 764 | 766 | ||
| 765 | return radeon_get_vblank_counter(rdev, crtc); | 767 | /* The hw increments its frame counter at start of vsync, not at start |
| 768 | * of vblank, as is required by DRM core vblank counter handling. | ||
| 769 | * Cook the hw count here to make it appear to the caller as if it | ||
| 770 | * incremented at start of vblank. We measure distance to start of | ||
| 771 | * vblank in vpos. vpos therefore will be >= 0 between start of vblank | ||
| 772 | * and start of vsync, so vpos >= 0 means to bump the hw frame counter | ||
| 773 | * result by 1 to give the proper appearance to caller. | ||
| 774 | */ | ||
| 775 | if (rdev->mode_info.crtcs[crtc]) { | ||
| 776 | /* Repeat readout if needed to provide stable result if | ||
| 777 | * we cross start of vsync during the queries. | ||
| 778 | */ | ||
| 779 | do { | ||
| 780 | count = radeon_get_vblank_counter(rdev, crtc); | ||
| 781 | /* Ask radeon_get_crtc_scanoutpos to return vpos as | ||
| 782 | * distance to start of vblank, instead of regular | ||
| 783 | * vertical scanout pos. | ||
| 784 | */ | ||
| 785 | stat = radeon_get_crtc_scanoutpos( | ||
| 786 | dev, crtc, GET_DISTANCE_TO_VBLANKSTART, | ||
| 787 | &vpos, &hpos, NULL, NULL, | ||
| 788 | &rdev->mode_info.crtcs[crtc]->base.hwmode); | ||
| 789 | } while (count != radeon_get_vblank_counter(rdev, crtc)); | ||
| 790 | |||
| 791 | if (((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) != | ||
| 792 | (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE))) { | ||
| 793 | DRM_DEBUG_VBL("Query failed! stat %d\n", stat); | ||
| 794 | } | ||
| 795 | else { | ||
| 796 | DRM_DEBUG_VBL("crtc %d: dist from vblank start %d\n", | ||
| 797 | crtc, vpos); | ||
| 798 | |||
| 799 | /* Bump counter if we are at >= leading edge of vblank, | ||
| 800 | * but before vsync where vpos would turn negative and | ||
| 801 | * the hw counter really increments. | ||
| 802 | */ | ||
| 803 | if (vpos >= 0) | ||
| 804 | count++; | ||
| 805 | } | ||
| 806 | } | ||
| 807 | else { | ||
| 808 | /* Fallback to use value as is. */ | ||
| 809 | count = radeon_get_vblank_counter(rdev, crtc); | ||
| 810 | DRM_DEBUG_VBL("NULL mode info! Returned count may be wrong.\n"); | ||
| 811 | } | ||
| 812 | |||
| 813 | return count; | ||
| 766 | } | 814 | } |
| 767 | 815 | ||
| 768 | /** | 816 | /** |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 830e171c3a9e..bba112628b47 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
| @@ -367,6 +367,7 @@ struct radeon_crtc { | |||
| 367 | u32 line_time; | 367 | u32 line_time; |
| 368 | u32 wm_low; | 368 | u32 wm_low; |
| 369 | u32 wm_high; | 369 | u32 wm_high; |
| 370 | u32 lb_vblank_lead_lines; | ||
| 370 | struct drm_display_mode hw_mode; | 371 | struct drm_display_mode hw_mode; |
| 371 | enum radeon_output_csc output_csc; | 372 | enum radeon_output_csc output_csc; |
| 372 | }; | 373 | }; |
| @@ -553,6 +554,7 @@ struct radeon_connector { | |||
| 553 | void *con_priv; | 554 | void *con_priv; |
| 554 | bool dac_load_detect; | 555 | bool dac_load_detect; |
| 555 | bool detected_by_load; /* if the connection status was determined by load */ | 556 | bool detected_by_load; /* if the connection status was determined by load */ |
| 557 | bool detected_hpd_without_ddc; /* if an HPD signal was detected on DVI, but ddc probing failed */ | ||
| 556 | uint16_t connector_object_id; | 558 | uint16_t connector_object_id; |
| 557 | struct radeon_hpd hpd; | 559 | struct radeon_hpd hpd; |
| 558 | struct radeon_router router; | 560 | struct radeon_router router; |
| @@ -686,6 +688,9 @@ struct atom_voltage_table | |||
| 686 | struct atom_voltage_table_entry entries[MAX_VOLTAGE_ENTRIES]; | 688 | struct atom_voltage_table_entry entries[MAX_VOLTAGE_ENTRIES]; |
| 687 | }; | 689 | }; |
| 688 | 690 | ||
| 691 | /* Driver internal use only flags of radeon_get_crtc_scanoutpos() */ | ||
| 692 | #define USE_REAL_VBLANKSTART (1 << 30) | ||
| 693 | #define GET_DISTANCE_TO_VBLANKSTART (1 << 31) | ||
| 689 | 694 | ||
| 690 | extern void | 695 | extern void |
| 691 | radeon_add_atom_connector(struct drm_device *dev, | 696 | radeon_add_atom_connector(struct drm_device *dev, |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index f4f03dcc1530..59abebd6b5dc 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
| @@ -1756,7 +1756,9 @@ static bool radeon_pm_in_vbl(struct radeon_device *rdev) | |||
| 1756 | */ | 1756 | */ |
| 1757 | for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) { | 1757 | for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) { |
| 1758 | if (rdev->pm.active_crtcs & (1 << crtc)) { | 1758 | if (rdev->pm.active_crtcs & (1 << crtc)) { |
| 1759 | vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, 0, | 1759 | vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, |
| 1760 | crtc, | ||
| 1761 | USE_REAL_VBLANKSTART, | ||
| 1760 | &vpos, &hpos, NULL, NULL, | 1762 | &vpos, &hpos, NULL, NULL, |
| 1761 | &rdev->mode_info.crtcs[crtc]->base.hwmode); | 1763 | &rdev->mode_info.crtcs[crtc]->base.hwmode); |
| 1762 | if ((vbl_status & DRM_SCANOUTPOS_VALID) && | 1764 | if ((vbl_status & DRM_SCANOUTPOS_VALID) && |
diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c index 574f62bbd215..7eb1ae758906 100644 --- a/drivers/gpu/drm/radeon/radeon_vce.c +++ b/drivers/gpu/drm/radeon/radeon_vce.c | |||
| @@ -361,31 +361,31 @@ int radeon_vce_get_create_msg(struct radeon_device *rdev, int ring, | |||
| 361 | 361 | ||
| 362 | /* stitch together an VCE create msg */ | 362 | /* stitch together an VCE create msg */ |
| 363 | ib.length_dw = 0; | 363 | ib.length_dw = 0; |
| 364 | ib.ptr[ib.length_dw++] = 0x0000000c; /* len */ | 364 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x0000000c); /* len */ |
| 365 | ib.ptr[ib.length_dw++] = 0x00000001; /* session cmd */ | 365 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000001); /* session cmd */ |
| 366 | ib.ptr[ib.length_dw++] = handle; | 366 | ib.ptr[ib.length_dw++] = cpu_to_le32(handle); |
| 367 | 367 | ||
| 368 | ib.ptr[ib.length_dw++] = 0x00000030; /* len */ | 368 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000030); /* len */ |
| 369 | ib.ptr[ib.length_dw++] = 0x01000001; /* create cmd */ | 369 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x01000001); /* create cmd */ |
| 370 | ib.ptr[ib.length_dw++] = 0x00000000; | 370 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000000); |
| 371 | ib.ptr[ib.length_dw++] = 0x00000042; | 371 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000042); |
| 372 | ib.ptr[ib.length_dw++] = 0x0000000a; | 372 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x0000000a); |
| 373 | ib.ptr[ib.length_dw++] = 0x00000001; | 373 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000001); |
| 374 | ib.ptr[ib.length_dw++] = 0x00000080; | 374 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000080); |
| 375 | ib.ptr[ib.length_dw++] = 0x00000060; | 375 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000060); |
| 376 | ib.ptr[ib.length_dw++] = 0x00000100; | 376 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000100); |
| 377 | ib.ptr[ib.length_dw++] = 0x00000100; | 377 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000100); |
| 378 | ib.ptr[ib.length_dw++] = 0x0000000c; | 378 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x0000000c); |
| 379 | ib.ptr[ib.length_dw++] = 0x00000000; | 379 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000000); |
| 380 | 380 | ||
| 381 | ib.ptr[ib.length_dw++] = 0x00000014; /* len */ | 381 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000014); /* len */ |
| 382 | ib.ptr[ib.length_dw++] = 0x05000005; /* feedback buffer */ | 382 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x05000005); /* feedback buffer */ |
| 383 | ib.ptr[ib.length_dw++] = upper_32_bits(dummy); | 383 | ib.ptr[ib.length_dw++] = cpu_to_le32(upper_32_bits(dummy)); |
| 384 | ib.ptr[ib.length_dw++] = dummy; | 384 | ib.ptr[ib.length_dw++] = cpu_to_le32(dummy); |
| 385 | ib.ptr[ib.length_dw++] = 0x00000001; | 385 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000001); |
| 386 | 386 | ||
| 387 | for (i = ib.length_dw; i < ib_size_dw; ++i) | 387 | for (i = ib.length_dw; i < ib_size_dw; ++i) |
| 388 | ib.ptr[i] = 0x0; | 388 | ib.ptr[i] = cpu_to_le32(0x0); |
| 389 | 389 | ||
| 390 | r = radeon_ib_schedule(rdev, &ib, NULL, false); | 390 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
| 391 | if (r) { | 391 | if (r) { |
| @@ -428,21 +428,21 @@ int radeon_vce_get_destroy_msg(struct radeon_device *rdev, int ring, | |||
| 428 | 428 | ||
| 429 | /* stitch together an VCE destroy msg */ | 429 | /* stitch together an VCE destroy msg */ |
| 430 | ib.length_dw = 0; | 430 | ib.length_dw = 0; |
| 431 | ib.ptr[ib.length_dw++] = 0x0000000c; /* len */ | 431 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x0000000c); /* len */ |
| 432 | ib.ptr[ib.length_dw++] = 0x00000001; /* session cmd */ | 432 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000001); /* session cmd */ |
| 433 | ib.ptr[ib.length_dw++] = handle; | 433 | ib.ptr[ib.length_dw++] = cpu_to_le32(handle); |
| 434 | 434 | ||
| 435 | ib.ptr[ib.length_dw++] = 0x00000014; /* len */ | 435 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000014); /* len */ |
| 436 | ib.ptr[ib.length_dw++] = 0x05000005; /* feedback buffer */ | 436 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x05000005); /* feedback buffer */ |
| 437 | ib.ptr[ib.length_dw++] = upper_32_bits(dummy); | 437 | ib.ptr[ib.length_dw++] = cpu_to_le32(upper_32_bits(dummy)); |
| 438 | ib.ptr[ib.length_dw++] = dummy; | 438 | ib.ptr[ib.length_dw++] = cpu_to_le32(dummy); |
| 439 | ib.ptr[ib.length_dw++] = 0x00000001; | 439 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000001); |
| 440 | 440 | ||
| 441 | ib.ptr[ib.length_dw++] = 0x00000008; /* len */ | 441 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x00000008); /* len */ |
| 442 | ib.ptr[ib.length_dw++] = 0x02000001; /* destroy cmd */ | 442 | ib.ptr[ib.length_dw++] = cpu_to_le32(0x02000001); /* destroy cmd */ |
| 443 | 443 | ||
| 444 | for (i = ib.length_dw; i < ib_size_dw; ++i) | 444 | for (i = ib.length_dw; i < ib_size_dw; ++i) |
| 445 | ib.ptr[i] = 0x0; | 445 | ib.ptr[i] = cpu_to_le32(0x0); |
| 446 | 446 | ||
| 447 | r = radeon_ib_schedule(rdev, &ib, NULL, false); | 447 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
| 448 | if (r) { | 448 | if (r) { |
| @@ -699,12 +699,12 @@ bool radeon_vce_semaphore_emit(struct radeon_device *rdev, | |||
| 699 | { | 699 | { |
| 700 | uint64_t addr = semaphore->gpu_addr; | 700 | uint64_t addr = semaphore->gpu_addr; |
| 701 | 701 | ||
| 702 | radeon_ring_write(ring, VCE_CMD_SEMAPHORE); | 702 | radeon_ring_write(ring, cpu_to_le32(VCE_CMD_SEMAPHORE)); |
| 703 | radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF); | 703 | radeon_ring_write(ring, cpu_to_le32((addr >> 3) & 0x000FFFFF)); |
| 704 | radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF); | 704 | radeon_ring_write(ring, cpu_to_le32((addr >> 23) & 0x000FFFFF)); |
| 705 | radeon_ring_write(ring, 0x01003000 | (emit_wait ? 1 : 0)); | 705 | radeon_ring_write(ring, cpu_to_le32(0x01003000 | (emit_wait ? 1 : 0))); |
| 706 | if (!emit_wait) | 706 | if (!emit_wait) |
| 707 | radeon_ring_write(ring, VCE_CMD_END); | 707 | radeon_ring_write(ring, cpu_to_le32(VCE_CMD_END)); |
| 708 | 708 | ||
| 709 | return true; | 709 | return true; |
| 710 | } | 710 | } |
| @@ -719,10 +719,10 @@ bool radeon_vce_semaphore_emit(struct radeon_device *rdev, | |||
| 719 | void radeon_vce_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | 719 | void radeon_vce_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) |
| 720 | { | 720 | { |
| 721 | struct radeon_ring *ring = &rdev->ring[ib->ring]; | 721 | struct radeon_ring *ring = &rdev->ring[ib->ring]; |
| 722 | radeon_ring_write(ring, VCE_CMD_IB); | 722 | radeon_ring_write(ring, cpu_to_le32(VCE_CMD_IB)); |
| 723 | radeon_ring_write(ring, ib->gpu_addr); | 723 | radeon_ring_write(ring, cpu_to_le32(ib->gpu_addr)); |
| 724 | radeon_ring_write(ring, upper_32_bits(ib->gpu_addr)); | 724 | radeon_ring_write(ring, cpu_to_le32(upper_32_bits(ib->gpu_addr))); |
| 725 | radeon_ring_write(ring, ib->length_dw); | 725 | radeon_ring_write(ring, cpu_to_le32(ib->length_dw)); |
| 726 | } | 726 | } |
| 727 | 727 | ||
| 728 | /** | 728 | /** |
| @@ -738,12 +738,12 @@ void radeon_vce_fence_emit(struct radeon_device *rdev, | |||
| 738 | struct radeon_ring *ring = &rdev->ring[fence->ring]; | 738 | struct radeon_ring *ring = &rdev->ring[fence->ring]; |
| 739 | uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr; | 739 | uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr; |
| 740 | 740 | ||
| 741 | radeon_ring_write(ring, VCE_CMD_FENCE); | 741 | radeon_ring_write(ring, cpu_to_le32(VCE_CMD_FENCE)); |
| 742 | radeon_ring_write(ring, addr); | 742 | radeon_ring_write(ring, cpu_to_le32(addr)); |
| 743 | radeon_ring_write(ring, upper_32_bits(addr)); | 743 | radeon_ring_write(ring, cpu_to_le32(upper_32_bits(addr))); |
| 744 | radeon_ring_write(ring, fence->seq); | 744 | radeon_ring_write(ring, cpu_to_le32(fence->seq)); |
| 745 | radeon_ring_write(ring, VCE_CMD_TRAP); | 745 | radeon_ring_write(ring, cpu_to_le32(VCE_CMD_TRAP)); |
| 746 | radeon_ring_write(ring, VCE_CMD_END); | 746 | radeon_ring_write(ring, cpu_to_le32(VCE_CMD_END)); |
| 747 | } | 747 | } |
| 748 | 748 | ||
| 749 | /** | 749 | /** |
| @@ -765,7 +765,7 @@ int radeon_vce_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 765 | ring->idx, r); | 765 | ring->idx, r); |
| 766 | return r; | 766 | return r; |
| 767 | } | 767 | } |
| 768 | radeon_ring_write(ring, VCE_CMD_END); | 768 | radeon_ring_write(ring, cpu_to_le32(VCE_CMD_END)); |
| 769 | radeon_ring_unlock_commit(rdev, ring, false); | 769 | radeon_ring_unlock_commit(rdev, ring, false); |
| 770 | 770 | ||
| 771 | for (i = 0; i < rdev->usec_timeout; i++) { | 771 | for (i = 0; i < rdev->usec_timeout; i++) { |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 97a904835759..6244f4e44e9a 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
| @@ -813,7 +813,7 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
| 813 | status = rs600_irq_ack(rdev); | 813 | status = rs600_irq_ack(rdev); |
| 814 | } | 814 | } |
| 815 | if (queue_hotplug) | 815 | if (queue_hotplug) |
| 816 | schedule_work(&rdev->hotplug_work); | 816 | schedule_delayed_work(&rdev->hotplug_work, 0); |
| 817 | if (queue_hdmi) | 817 | if (queue_hdmi) |
| 818 | schedule_work(&rdev->audio_work); | 818 | schedule_work(&rdev->audio_work); |
| 819 | if (rdev->msi_enabled) { | 819 | if (rdev->msi_enabled) { |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 516ca27cfa12..6bc44c24e837 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
| @@ -207,6 +207,9 @@ void rs690_line_buffer_adjust(struct radeon_device *rdev, | |||
| 207 | { | 207 | { |
| 208 | u32 tmp; | 208 | u32 tmp; |
| 209 | 209 | ||
| 210 | /* Guess line buffer size to be 8192 pixels */ | ||
| 211 | u32 lb_size = 8192; | ||
| 212 | |||
| 210 | /* | 213 | /* |
| 211 | * Line Buffer Setup | 214 | * Line Buffer Setup |
| 212 | * There is a single line buffer shared by both display controllers. | 215 | * There is a single line buffer shared by both display controllers. |
| @@ -243,6 +246,13 @@ void rs690_line_buffer_adjust(struct radeon_device *rdev, | |||
| 243 | tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q; | 246 | tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q; |
| 244 | } | 247 | } |
| 245 | WREG32(R_006520_DC_LB_MEMORY_SPLIT, tmp); | 248 | WREG32(R_006520_DC_LB_MEMORY_SPLIT, tmp); |
| 249 | |||
| 250 | /* Save number of lines the linebuffer leads before the scanout */ | ||
| 251 | if (mode1) | ||
| 252 | rdev->mode_info.crtcs[0]->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode1->crtc_hdisplay); | ||
| 253 | |||
| 254 | if (mode2) | ||
| 255 | rdev->mode_info.crtcs[1]->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode2->crtc_hdisplay); | ||
| 246 | } | 256 | } |
| 247 | 257 | ||
| 248 | struct rs690_watermark { | 258 | struct rs690_watermark { |
diff --git a/drivers/gpu/drm/radeon/rv730_dpm.c b/drivers/gpu/drm/radeon/rv730_dpm.c index 3f5e1cf138ba..d37ba2cb886e 100644 --- a/drivers/gpu/drm/radeon/rv730_dpm.c +++ b/drivers/gpu/drm/radeon/rv730_dpm.c | |||
| @@ -464,7 +464,7 @@ void rv730_stop_dpm(struct radeon_device *rdev) | |||
| 464 | result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_TwoLevelsDisabled); | 464 | result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_TwoLevelsDisabled); |
| 465 | 465 | ||
| 466 | if (result != PPSMC_Result_OK) | 466 | if (result != PPSMC_Result_OK) |
| 467 | DRM_ERROR("Could not force DPM to low\n"); | 467 | DRM_DEBUG("Could not force DPM to low\n"); |
| 468 | 468 | ||
| 469 | WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN); | 469 | WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN); |
| 470 | 470 | ||
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index b9c770745a7a..e830c8935db0 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c | |||
| @@ -193,7 +193,7 @@ void rv770_stop_dpm(struct radeon_device *rdev) | |||
| 193 | result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_TwoLevelsDisabled); | 193 | result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_TwoLevelsDisabled); |
| 194 | 194 | ||
| 195 | if (result != PPSMC_Result_OK) | 195 | if (result != PPSMC_Result_OK) |
| 196 | DRM_ERROR("Could not force DPM to low.\n"); | 196 | DRM_DEBUG("Could not force DPM to low.\n"); |
| 197 | 197 | ||
| 198 | WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN); | 198 | WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN); |
| 199 | 199 | ||
| @@ -1418,7 +1418,7 @@ int rv770_resume_smc(struct radeon_device *rdev) | |||
| 1418 | int rv770_set_sw_state(struct radeon_device *rdev) | 1418 | int rv770_set_sw_state(struct radeon_device *rdev) |
| 1419 | { | 1419 | { |
| 1420 | if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToSwState) != PPSMC_Result_OK) | 1420 | if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToSwState) != PPSMC_Result_OK) |
| 1421 | return -EINVAL; | 1421 | DRM_DEBUG("rv770_set_sw_state failed\n"); |
| 1422 | return 0; | 1422 | return 0; |
| 1423 | } | 1423 | } |
| 1424 | 1424 | ||
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 07037e32dea3..f878d6962da5 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
| @@ -2376,6 +2376,9 @@ static void dce6_program_watermarks(struct radeon_device *rdev, | |||
| 2376 | c.full = dfixed_div(c, a); | 2376 | c.full = dfixed_div(c, a); |
| 2377 | priority_b_mark = dfixed_trunc(c); | 2377 | priority_b_mark = dfixed_trunc(c); |
| 2378 | priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK; | 2378 | priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK; |
| 2379 | |||
| 2380 | /* Save number of lines the linebuffer leads before the scanout */ | ||
| 2381 | radeon_crtc->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay); | ||
| 2379 | } | 2382 | } |
| 2380 | 2383 | ||
| 2381 | /* select wm A */ | 2384 | /* select wm A */ |
| @@ -6848,7 +6851,7 @@ restart_ih: | |||
| 6848 | if (queue_dp) | 6851 | if (queue_dp) |
| 6849 | schedule_work(&rdev->dp_work); | 6852 | schedule_work(&rdev->dp_work); |
| 6850 | if (queue_hotplug) | 6853 | if (queue_hotplug) |
| 6851 | schedule_work(&rdev->hotplug_work); | 6854 | schedule_delayed_work(&rdev->hotplug_work, 0); |
| 6852 | if (queue_thermal && rdev->pm.dpm_enabled) | 6855 | if (queue_thermal && rdev->pm.dpm_enabled) |
| 6853 | schedule_work(&rdev->pm.dpm.thermal.work); | 6856 | schedule_work(&rdev->pm.dpm.thermal.work); |
| 6854 | rdev->ih.rptr = rptr; | 6857 | rdev->ih.rptr = rptr; |
