diff options
32 files changed, 353 insertions, 165 deletions
diff --git a/drivers/gpu/drm/ast/ast_ttm.c b/drivers/gpu/drm/ast/ast_ttm.c index 98d670825a1a..6e8887fe6c1b 100644 --- a/drivers/gpu/drm/ast/ast_ttm.c +++ b/drivers/gpu/drm/ast/ast_ttm.c | |||
| @@ -323,6 +323,7 @@ int ast_bo_create(struct drm_device *dev, int size, int align, | |||
| 323 | 323 | ||
| 324 | astbo->gem.driver_private = NULL; | 324 | astbo->gem.driver_private = NULL; |
| 325 | astbo->bo.bdev = &ast->ttm.bdev; | 325 | astbo->bo.bdev = &ast->ttm.bdev; |
| 326 | astbo->bo.bdev->dev_mapping = dev->dev_mapping; | ||
| 326 | 327 | ||
| 327 | ast_ttm_placement(astbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); | 328 | ast_ttm_placement(astbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); |
| 328 | 329 | ||
diff --git a/drivers/gpu/drm/cirrus/cirrus_ttm.c b/drivers/gpu/drm/cirrus/cirrus_ttm.c index 0047012045c2..69fd8f1ac8df 100644 --- a/drivers/gpu/drm/cirrus/cirrus_ttm.c +++ b/drivers/gpu/drm/cirrus/cirrus_ttm.c | |||
| @@ -328,6 +328,7 @@ int cirrus_bo_create(struct drm_device *dev, int size, int align, | |||
| 328 | 328 | ||
| 329 | cirrusbo->gem.driver_private = NULL; | 329 | cirrusbo->gem.driver_private = NULL; |
| 330 | cirrusbo->bo.bdev = &cirrus->ttm.bdev; | 330 | cirrusbo->bo.bdev = &cirrus->ttm.bdev; |
| 331 | cirrusbo->bo.bdev->dev_mapping = dev->dev_mapping; | ||
| 331 | 332 | ||
| 332 | cirrus_ttm_placement(cirrusbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); | 333 | cirrus_ttm_placement(cirrusbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); |
| 333 | 334 | ||
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 8bcce7866d36..f92da0a32f0d 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
| @@ -708,7 +708,10 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, | |||
| 708 | /* Subtract time delta from raw timestamp to get final | 708 | /* Subtract time delta from raw timestamp to get final |
| 709 | * vblank_time timestamp for end of vblank. | 709 | * vblank_time timestamp for end of vblank. |
| 710 | */ | 710 | */ |
| 711 | etime = ktime_sub_ns(etime, delta_ns); | 711 | if (delta_ns < 0) |
| 712 | etime = ktime_add_ns(etime, -delta_ns); | ||
| 713 | else | ||
| 714 | etime = ktime_sub_ns(etime, delta_ns); | ||
| 712 | *vblank_time = ktime_to_timeval(etime); | 715 | *vblank_time = ktime_to_timeval(etime); |
| 713 | 716 | ||
| 714 | DRM_DEBUG("crtc %d : v %d p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", | 717 | DRM_DEBUG("crtc %d : v %d p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f2326fc60ac9..6f514297c483 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -1856,10 +1856,16 @@ | |||
| 1856 | #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) | 1856 | #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) |
| 1857 | 1857 | ||
| 1858 | #define PORT_HOTPLUG_STAT (dev_priv->info->display_mmio_offset + 0x61114) | 1858 | #define PORT_HOTPLUG_STAT (dev_priv->info->display_mmio_offset + 0x61114) |
| 1859 | /* HDMI/DP bits are gen4+ */ | 1859 | /* |
| 1860 | #define PORTB_HOTPLUG_LIVE_STATUS (1 << 29) | 1860 | * HDMI/DP bits are gen4+ |
| 1861 | * | ||
| 1862 | * WARNING: Bspec for hpd status bits on gen4 seems to be completely confused. | ||
| 1863 | * Please check the detailed lore in the commit message for for experimental | ||
| 1864 | * evidence. | ||
| 1865 | */ | ||
| 1866 | #define PORTD_HOTPLUG_LIVE_STATUS (1 << 29) | ||
| 1861 | #define PORTC_HOTPLUG_LIVE_STATUS (1 << 28) | 1867 | #define PORTC_HOTPLUG_LIVE_STATUS (1 << 28) |
| 1862 | #define PORTD_HOTPLUG_LIVE_STATUS (1 << 27) | 1868 | #define PORTB_HOTPLUG_LIVE_STATUS (1 << 27) |
| 1863 | #define PORTD_HOTPLUG_INT_STATUS (3 << 21) | 1869 | #define PORTD_HOTPLUG_INT_STATUS (3 << 21) |
| 1864 | #define PORTC_HOTPLUG_INT_STATUS (3 << 19) | 1870 | #define PORTC_HOTPLUG_INT_STATUS (3 << 19) |
| 1865 | #define PORTB_HOTPLUG_INT_STATUS (3 << 17) | 1871 | #define PORTB_HOTPLUG_INT_STATUS (3 << 17) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5fb305840db8..e38b45786653 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -8269,9 +8269,11 @@ check_crtc_state(struct drm_device *dev) | |||
| 8269 | 8269 | ||
| 8270 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | 8270 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
| 8271 | base.head) { | 8271 | base.head) { |
| 8272 | enum pipe pipe; | ||
| 8272 | if (encoder->base.crtc != &crtc->base) | 8273 | if (encoder->base.crtc != &crtc->base) |
| 8273 | continue; | 8274 | continue; |
| 8274 | if (encoder->get_config) | 8275 | if (encoder->get_config && |
| 8276 | encoder->get_hw_state(encoder, &pipe)) | ||
| 8275 | encoder->get_config(encoder, &pipe_config); | 8277 | encoder->get_config(encoder, &pipe_config); |
| 8276 | } | 8278 | } |
| 8277 | 8279 | ||
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 67e2c1f1c9a8..5950888ae1d0 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
| @@ -497,8 +497,11 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max) | |||
| 497 | goto out; | 497 | goto out; |
| 498 | } | 498 | } |
| 499 | 499 | ||
| 500 | /* scale to hardware */ | 500 | /* scale to hardware, but be careful to not overflow */ |
| 501 | level = level * freq / max; | 501 | if (freq < max) |
| 502 | level = level * freq / max; | ||
| 503 | else | ||
| 504 | level = freq / max * level; | ||
| 502 | 505 | ||
| 503 | dev_priv->backlight.level = level; | 506 | dev_priv->backlight.level = level; |
| 504 | if (dev_priv->backlight.device) | 507 | if (dev_priv->backlight.device) |
| @@ -515,6 +518,17 @@ void intel_panel_disable_backlight(struct drm_device *dev) | |||
| 515 | struct drm_i915_private *dev_priv = dev->dev_private; | 518 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 516 | unsigned long flags; | 519 | unsigned long flags; |
| 517 | 520 | ||
| 521 | /* | ||
| 522 | * Do not disable backlight on the vgaswitcheroo path. When switching | ||
| 523 | * away from i915, the other client may depend on i915 to handle the | ||
| 524 | * backlight. This will leave the backlight on unnecessarily when | ||
| 525 | * another client is not activated. | ||
| 526 | */ | ||
| 527 | if (dev->switch_power_state == DRM_SWITCH_POWER_CHANGING) { | ||
| 528 | DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n"); | ||
| 529 | return; | ||
| 530 | } | ||
| 531 | |||
| 518 | spin_lock_irqsave(&dev_priv->backlight.lock, flags); | 532 | spin_lock_irqsave(&dev_priv->backlight.lock, flags); |
| 519 | 533 | ||
| 520 | dev_priv->backlight.enabled = false; | 534 | dev_priv->backlight.enabled = false; |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index f895d1508df8..b0e4a0bd1313 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
| @@ -5063,8 +5063,26 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable) | |||
| 5063 | } | 5063 | } |
| 5064 | } else { | 5064 | } else { |
| 5065 | if (enable_requested) { | 5065 | if (enable_requested) { |
| 5066 | unsigned long irqflags; | ||
| 5067 | enum pipe p; | ||
| 5068 | |||
| 5066 | I915_WRITE(HSW_PWR_WELL_DRIVER, 0); | 5069 | I915_WRITE(HSW_PWR_WELL_DRIVER, 0); |
| 5070 | POSTING_READ(HSW_PWR_WELL_DRIVER); | ||
| 5067 | DRM_DEBUG_KMS("Requesting to disable the power well\n"); | 5071 | DRM_DEBUG_KMS("Requesting to disable the power well\n"); |
| 5072 | |||
| 5073 | /* | ||
| 5074 | * After this, the registers on the pipes that are part | ||
| 5075 | * of the power well will become zero, so we have to | ||
| 5076 | * adjust our counters according to that. | ||
| 5077 | * | ||
| 5078 | * FIXME: Should we do this in general in | ||
| 5079 | * drm_vblank_post_modeset? | ||
| 5080 | */ | ||
| 5081 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | ||
| 5082 | for_each_pipe(p) | ||
| 5083 | if (p != PIPE_A) | ||
| 5084 | dev->last_vblank[p] = 0; | ||
| 5085 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
| 5068 | } | 5086 | } |
| 5069 | } | 5087 | } |
| 5070 | } | 5088 | } |
diff --git a/drivers/gpu/drm/mgag200/mgag200_ttm.c b/drivers/gpu/drm/mgag200/mgag200_ttm.c index 13878d5de063..d70e4a92773b 100644 --- a/drivers/gpu/drm/mgag200/mgag200_ttm.c +++ b/drivers/gpu/drm/mgag200/mgag200_ttm.c | |||
| @@ -323,6 +323,7 @@ int mgag200_bo_create(struct drm_device *dev, int size, int align, | |||
| 323 | 323 | ||
| 324 | mgabo->gem.driver_private = NULL; | 324 | mgabo->gem.driver_private = NULL; |
| 325 | mgabo->bo.bdev = &mdev->ttm.bdev; | 325 | mgabo->bo.bdev = &mdev->ttm.bdev; |
| 326 | mgabo->bo.bdev->dev_mapping = dev->dev_mapping; | ||
| 326 | 327 | ||
| 327 | mgag200_ttm_placement(mgabo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); | 328 | mgag200_ttm_placement(mgabo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); |
| 328 | 329 | ||
diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c index 0bfd55e08820..9953e1fbc46d 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.c +++ b/drivers/gpu/drm/radeon/btc_dpm.c | |||
| @@ -2548,9 +2548,6 @@ int btc_dpm_init(struct radeon_device *rdev) | |||
| 2548 | { | 2548 | { |
| 2549 | struct rv7xx_power_info *pi; | 2549 | struct rv7xx_power_info *pi; |
| 2550 | struct evergreen_power_info *eg_pi; | 2550 | struct evergreen_power_info *eg_pi; |
| 2551 | int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); | ||
| 2552 | u16 data_offset, size; | ||
| 2553 | u8 frev, crev; | ||
| 2554 | struct atom_clock_dividers dividers; | 2551 | struct atom_clock_dividers dividers; |
| 2555 | int ret; | 2552 | int ret; |
| 2556 | 2553 | ||
| @@ -2633,16 +2630,7 @@ int btc_dpm_init(struct radeon_device *rdev) | |||
| 2633 | eg_pi->vddci_control = | 2630 | eg_pi->vddci_control = |
| 2634 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0); | 2631 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0); |
| 2635 | 2632 | ||
| 2636 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, | 2633 | rv770_get_engine_memory_ss(rdev); |
| 2637 | &frev, &crev, &data_offset)) { | ||
| 2638 | pi->sclk_ss = true; | ||
| 2639 | pi->mclk_ss = true; | ||
| 2640 | pi->dynamic_ss = true; | ||
| 2641 | } else { | ||
| 2642 | pi->sclk_ss = false; | ||
| 2643 | pi->mclk_ss = false; | ||
| 2644 | pi->dynamic_ss = true; | ||
| 2645 | } | ||
| 2646 | 2634 | ||
| 2647 | pi->asi = RV770_ASI_DFLT; | 2635 | pi->asi = RV770_ASI_DFLT; |
| 2648 | pi->pasi = CYPRESS_HASI_DFLT; | 2636 | pi->pasi = CYPRESS_HASI_DFLT; |
| @@ -2659,8 +2647,7 @@ int btc_dpm_init(struct radeon_device *rdev) | |||
| 2659 | 2647 | ||
| 2660 | pi->dynamic_pcie_gen2 = true; | 2648 | pi->dynamic_pcie_gen2 = true; |
| 2661 | 2649 | ||
| 2662 | if (pi->gfx_clock_gating && | 2650 | if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE) |
| 2663 | (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)) | ||
| 2664 | pi->thermal_protection = true; | 2651 | pi->thermal_protection = true; |
| 2665 | else | 2652 | else |
| 2666 | pi->thermal_protection = false; | 2653 | pi->thermal_protection = false; |
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 6dacec4e2090..8928bd109c16 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
| @@ -2587,9 +2587,11 @@ u32 cik_compute_ring_get_rptr(struct radeon_device *rdev, | |||
| 2587 | if (rdev->wb.enabled) { | 2587 | if (rdev->wb.enabled) { |
| 2588 | rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]); | 2588 | rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]); |
| 2589 | } else { | 2589 | } else { |
| 2590 | mutex_lock(&rdev->srbm_mutex); | ||
| 2590 | cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0); | 2591 | cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0); |
| 2591 | rptr = RREG32(CP_HQD_PQ_RPTR); | 2592 | rptr = RREG32(CP_HQD_PQ_RPTR); |
| 2592 | cik_srbm_select(rdev, 0, 0, 0, 0); | 2593 | cik_srbm_select(rdev, 0, 0, 0, 0); |
| 2594 | mutex_unlock(&rdev->srbm_mutex); | ||
| 2593 | } | 2595 | } |
| 2594 | rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift; | 2596 | rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift; |
| 2595 | 2597 | ||
| @@ -2604,9 +2606,11 @@ u32 cik_compute_ring_get_wptr(struct radeon_device *rdev, | |||
| 2604 | if (rdev->wb.enabled) { | 2606 | if (rdev->wb.enabled) { |
| 2605 | wptr = le32_to_cpu(rdev->wb.wb[ring->wptr_offs/4]); | 2607 | wptr = le32_to_cpu(rdev->wb.wb[ring->wptr_offs/4]); |
| 2606 | } else { | 2608 | } else { |
| 2609 | mutex_lock(&rdev->srbm_mutex); | ||
| 2607 | cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0); | 2610 | cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0); |
| 2608 | wptr = RREG32(CP_HQD_PQ_WPTR); | 2611 | wptr = RREG32(CP_HQD_PQ_WPTR); |
| 2609 | cik_srbm_select(rdev, 0, 0, 0, 0); | 2612 | cik_srbm_select(rdev, 0, 0, 0, 0); |
| 2613 | mutex_unlock(&rdev->srbm_mutex); | ||
| 2610 | } | 2614 | } |
| 2611 | wptr = (wptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift; | 2615 | wptr = (wptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift; |
| 2612 | 2616 | ||
| @@ -2897,6 +2901,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev) | |||
| 2897 | WREG32(CP_CPF_DEBUG, tmp); | 2901 | WREG32(CP_CPF_DEBUG, tmp); |
| 2898 | 2902 | ||
| 2899 | /* init the pipes */ | 2903 | /* init the pipes */ |
| 2904 | mutex_lock(&rdev->srbm_mutex); | ||
| 2900 | for (i = 0; i < (rdev->mec.num_pipe * rdev->mec.num_mec); i++) { | 2905 | for (i = 0; i < (rdev->mec.num_pipe * rdev->mec.num_mec); i++) { |
| 2901 | int me = (i < 4) ? 1 : 2; | 2906 | int me = (i < 4) ? 1 : 2; |
| 2902 | int pipe = (i < 4) ? i : (i - 4); | 2907 | int pipe = (i < 4) ? i : (i - 4); |
| @@ -2919,6 +2924,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev) | |||
| 2919 | WREG32(CP_HPD_EOP_CONTROL, tmp); | 2924 | WREG32(CP_HPD_EOP_CONTROL, tmp); |
| 2920 | } | 2925 | } |
| 2921 | cik_srbm_select(rdev, 0, 0, 0, 0); | 2926 | cik_srbm_select(rdev, 0, 0, 0, 0); |
| 2927 | mutex_unlock(&rdev->srbm_mutex); | ||
| 2922 | 2928 | ||
| 2923 | /* init the queues. Just two for now. */ | 2929 | /* init the queues. Just two for now. */ |
| 2924 | for (i = 0; i < 2; i++) { | 2930 | for (i = 0; i < 2; i++) { |
| @@ -2972,6 +2978,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev) | |||
| 2972 | mqd->static_thread_mgmt23[0] = 0xffffffff; | 2978 | mqd->static_thread_mgmt23[0] = 0xffffffff; |
| 2973 | mqd->static_thread_mgmt23[1] = 0xffffffff; | 2979 | mqd->static_thread_mgmt23[1] = 0xffffffff; |
| 2974 | 2980 | ||
| 2981 | mutex_lock(&rdev->srbm_mutex); | ||
| 2975 | cik_srbm_select(rdev, rdev->ring[idx].me, | 2982 | cik_srbm_select(rdev, rdev->ring[idx].me, |
| 2976 | rdev->ring[idx].pipe, | 2983 | rdev->ring[idx].pipe, |
| 2977 | rdev->ring[idx].queue, 0); | 2984 | rdev->ring[idx].queue, 0); |
| @@ -3099,6 +3106,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev) | |||
| 3099 | WREG32(CP_HQD_ACTIVE, mqd->queue_state.cp_hqd_active); | 3106 | WREG32(CP_HQD_ACTIVE, mqd->queue_state.cp_hqd_active); |
| 3100 | 3107 | ||
| 3101 | cik_srbm_select(rdev, 0, 0, 0, 0); | 3108 | cik_srbm_select(rdev, 0, 0, 0, 0); |
| 3109 | mutex_unlock(&rdev->srbm_mutex); | ||
| 3102 | 3110 | ||
| 3103 | radeon_bo_kunmap(rdev->ring[idx].mqd_obj); | 3111 | radeon_bo_kunmap(rdev->ring[idx].mqd_obj); |
| 3104 | radeon_bo_unreserve(rdev->ring[idx].mqd_obj); | 3112 | radeon_bo_unreserve(rdev->ring[idx].mqd_obj); |
| @@ -4320,6 +4328,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev) | |||
| 4320 | 4328 | ||
| 4321 | /* XXX SH_MEM regs */ | 4329 | /* XXX SH_MEM regs */ |
| 4322 | /* where to put LDS, scratch, GPUVM in FSA64 space */ | 4330 | /* where to put LDS, scratch, GPUVM in FSA64 space */ |
| 4331 | mutex_lock(&rdev->srbm_mutex); | ||
| 4323 | for (i = 0; i < 16; i++) { | 4332 | for (i = 0; i < 16; i++) { |
| 4324 | cik_srbm_select(rdev, 0, 0, 0, i); | 4333 | cik_srbm_select(rdev, 0, 0, 0, i); |
| 4325 | /* CP and shaders */ | 4334 | /* CP and shaders */ |
| @@ -4335,6 +4344,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev) | |||
| 4335 | /* XXX SDMA RLC - todo */ | 4344 | /* XXX SDMA RLC - todo */ |
| 4336 | } | 4345 | } |
| 4337 | cik_srbm_select(rdev, 0, 0, 0, 0); | 4346 | cik_srbm_select(rdev, 0, 0, 0, 0); |
| 4347 | mutex_unlock(&rdev->srbm_mutex); | ||
| 4338 | 4348 | ||
| 4339 | cik_pcie_gart_tlb_flush(rdev); | 4349 | cik_pcie_gart_tlb_flush(rdev); |
| 4340 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", | 4350 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", |
| @@ -5954,6 +5964,8 @@ static int cik_startup(struct radeon_device *rdev) | |||
| 5954 | struct radeon_ring *ring; | 5964 | struct radeon_ring *ring; |
| 5955 | int r; | 5965 | int r; |
| 5956 | 5966 | ||
| 5967 | cik_mc_program(rdev); | ||
| 5968 | |||
| 5957 | if (rdev->flags & RADEON_IS_IGP) { | 5969 | if (rdev->flags & RADEON_IS_IGP) { |
| 5958 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || | 5970 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || |
| 5959 | !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw) { | 5971 | !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw) { |
| @@ -5985,7 +5997,6 @@ static int cik_startup(struct radeon_device *rdev) | |||
| 5985 | if (r) | 5997 | if (r) |
| 5986 | return r; | 5998 | return r; |
| 5987 | 5999 | ||
| 5988 | cik_mc_program(rdev); | ||
| 5989 | r = cik_pcie_gart_enable(rdev); | 6000 | r = cik_pcie_gart_enable(rdev); |
| 5990 | if (r) | 6001 | if (r) |
| 5991 | return r; | 6002 | return r; |
| @@ -6194,7 +6205,7 @@ int cik_suspend(struct radeon_device *rdev) | |||
| 6194 | radeon_vm_manager_fini(rdev); | 6205 | radeon_vm_manager_fini(rdev); |
| 6195 | cik_cp_enable(rdev, false); | 6206 | cik_cp_enable(rdev, false); |
| 6196 | cik_sdma_enable(rdev, false); | 6207 | cik_sdma_enable(rdev, false); |
| 6197 | r600_uvd_rbc_stop(rdev); | 6208 | r600_uvd_stop(rdev); |
| 6198 | radeon_uvd_suspend(rdev); | 6209 | radeon_uvd_suspend(rdev); |
| 6199 | cik_irq_suspend(rdev); | 6210 | cik_irq_suspend(rdev); |
| 6200 | radeon_wb_disable(rdev); | 6211 | radeon_wb_disable(rdev); |
| @@ -6358,6 +6369,7 @@ void cik_fini(struct radeon_device *rdev) | |||
| 6358 | radeon_vm_manager_fini(rdev); | 6369 | radeon_vm_manager_fini(rdev); |
| 6359 | radeon_ib_pool_fini(rdev); | 6370 | radeon_ib_pool_fini(rdev); |
| 6360 | radeon_irq_kms_fini(rdev); | 6371 | radeon_irq_kms_fini(rdev); |
| 6372 | r600_uvd_stop(rdev); | ||
| 6361 | radeon_uvd_fini(rdev); | 6373 | radeon_uvd_fini(rdev); |
| 6362 | cik_pcie_gart_fini(rdev); | 6374 | cik_pcie_gart_fini(rdev); |
| 6363 | r600_vram_scratch_fini(rdev); | 6375 | r600_vram_scratch_fini(rdev); |
| @@ -6978,7 +6990,7 @@ int cik_uvd_resume(struct radeon_device *rdev) | |||
| 6978 | 6990 | ||
| 6979 | /* programm the VCPU memory controller bits 0-27 */ | 6991 | /* programm the VCPU memory controller bits 0-27 */ |
| 6980 | addr = rdev->uvd.gpu_addr >> 3; | 6992 | addr = rdev->uvd.gpu_addr >> 3; |
| 6981 | size = RADEON_GPU_PAGE_ALIGN(rdev->uvd.fw_size + 4) >> 3; | 6993 | size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3; |
| 6982 | WREG32(UVD_VCPU_CACHE_OFFSET0, addr); | 6994 | WREG32(UVD_VCPU_CACHE_OFFSET0, addr); |
| 6983 | WREG32(UVD_VCPU_CACHE_SIZE0, size); | 6995 | WREG32(UVD_VCPU_CACHE_SIZE0, size); |
| 6984 | 6996 | ||
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c index 9bcdd174780f..7e5d0b570a30 100644 --- a/drivers/gpu/drm/radeon/cypress_dpm.c +++ b/drivers/gpu/drm/radeon/cypress_dpm.c | |||
| @@ -2038,9 +2038,6 @@ int cypress_dpm_init(struct radeon_device *rdev) | |||
| 2038 | { | 2038 | { |
| 2039 | struct rv7xx_power_info *pi; | 2039 | struct rv7xx_power_info *pi; |
| 2040 | struct evergreen_power_info *eg_pi; | 2040 | struct evergreen_power_info *eg_pi; |
| 2041 | int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); | ||
| 2042 | uint16_t data_offset, size; | ||
| 2043 | uint8_t frev, crev; | ||
| 2044 | struct atom_clock_dividers dividers; | 2041 | struct atom_clock_dividers dividers; |
| 2045 | int ret; | 2042 | int ret; |
| 2046 | 2043 | ||
| @@ -2092,16 +2089,7 @@ int cypress_dpm_init(struct radeon_device *rdev) | |||
| 2092 | eg_pi->vddci_control = | 2089 | eg_pi->vddci_control = |
| 2093 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0); | 2090 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0); |
| 2094 | 2091 | ||
| 2095 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, | 2092 | rv770_get_engine_memory_ss(rdev); |
| 2096 | &frev, &crev, &data_offset)) { | ||
| 2097 | pi->sclk_ss = true; | ||
| 2098 | pi->mclk_ss = true; | ||
| 2099 | pi->dynamic_ss = true; | ||
| 2100 | } else { | ||
| 2101 | pi->sclk_ss = false; | ||
| 2102 | pi->mclk_ss = false; | ||
| 2103 | pi->dynamic_ss = true; | ||
| 2104 | } | ||
| 2105 | 2093 | ||
| 2106 | pi->asi = RV770_ASI_DFLT; | 2094 | pi->asi = RV770_ASI_DFLT; |
| 2107 | pi->pasi = CYPRESS_HASI_DFLT; | 2095 | pi->pasi = CYPRESS_HASI_DFLT; |
| @@ -2122,8 +2110,7 @@ int cypress_dpm_init(struct radeon_device *rdev) | |||
| 2122 | 2110 | ||
| 2123 | pi->dynamic_pcie_gen2 = true; | 2111 | pi->dynamic_pcie_gen2 = true; |
| 2124 | 2112 | ||
| 2125 | if (pi->gfx_clock_gating && | 2113 | if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE) |
| 2126 | (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)) | ||
| 2127 | pi->thermal_protection = true; | 2114 | pi->thermal_protection = true; |
| 2128 | else | 2115 | else |
| 2129 | pi->thermal_protection = false; | 2116 | pi->thermal_protection = false; |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 038dcac7670c..d5b49e33315e 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
| @@ -5106,6 +5106,8 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
| 5106 | /* enable aspm */ | 5106 | /* enable aspm */ |
| 5107 | evergreen_program_aspm(rdev); | 5107 | evergreen_program_aspm(rdev); |
| 5108 | 5108 | ||
| 5109 | evergreen_mc_program(rdev); | ||
| 5110 | |||
| 5109 | if (ASIC_IS_DCE5(rdev)) { | 5111 | if (ASIC_IS_DCE5(rdev)) { |
| 5110 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { | 5112 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { |
| 5111 | r = ni_init_microcode(rdev); | 5113 | r = ni_init_microcode(rdev); |
| @@ -5133,7 +5135,6 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
| 5133 | if (r) | 5135 | if (r) |
| 5134 | return r; | 5136 | return r; |
| 5135 | 5137 | ||
| 5136 | evergreen_mc_program(rdev); | ||
| 5137 | if (rdev->flags & RADEON_IS_AGP) { | 5138 | if (rdev->flags & RADEON_IS_AGP) { |
| 5138 | evergreen_agp_enable(rdev); | 5139 | evergreen_agp_enable(rdev); |
| 5139 | } else { | 5140 | } else { |
| @@ -5291,10 +5292,10 @@ int evergreen_resume(struct radeon_device *rdev) | |||
| 5291 | int evergreen_suspend(struct radeon_device *rdev) | 5292 | int evergreen_suspend(struct radeon_device *rdev) |
| 5292 | { | 5293 | { |
| 5293 | r600_audio_fini(rdev); | 5294 | r600_audio_fini(rdev); |
| 5295 | r600_uvd_stop(rdev); | ||
| 5294 | radeon_uvd_suspend(rdev); | 5296 | radeon_uvd_suspend(rdev); |
| 5295 | r700_cp_stop(rdev); | 5297 | r700_cp_stop(rdev); |
| 5296 | r600_dma_stop(rdev); | 5298 | r600_dma_stop(rdev); |
| 5297 | r600_uvd_rbc_stop(rdev); | ||
| 5298 | evergreen_irq_suspend(rdev); | 5299 | evergreen_irq_suspend(rdev); |
| 5299 | radeon_wb_disable(rdev); | 5300 | radeon_wb_disable(rdev); |
| 5300 | evergreen_pcie_gart_disable(rdev); | 5301 | evergreen_pcie_gart_disable(rdev); |
| @@ -5429,6 +5430,7 @@ void evergreen_fini(struct radeon_device *rdev) | |||
| 5429 | radeon_ib_pool_fini(rdev); | 5430 | radeon_ib_pool_fini(rdev); |
| 5430 | radeon_irq_kms_fini(rdev); | 5431 | radeon_irq_kms_fini(rdev); |
| 5431 | evergreen_pcie_gart_fini(rdev); | 5432 | evergreen_pcie_gart_fini(rdev); |
| 5433 | r600_uvd_stop(rdev); | ||
| 5432 | radeon_uvd_fini(rdev); | 5434 | radeon_uvd_fini(rdev); |
| 5433 | r600_vram_scratch_fini(rdev); | 5435 | r600_vram_scratch_fini(rdev); |
| 5434 | radeon_gem_fini(rdev); | 5436 | radeon_gem_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index bb9ea3641312..b0e280058b9b 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c | |||
| @@ -148,18 +148,40 @@ static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock) | |||
| 148 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 148 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 149 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | 149 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
| 150 | u32 base_rate = 24000; | 150 | u32 base_rate = 24000; |
| 151 | u32 max_ratio = clock / base_rate; | ||
| 152 | u32 dto_phase; | ||
| 153 | u32 dto_modulo = clock; | ||
| 154 | u32 wallclock_ratio; | ||
| 155 | u32 dto_cntl; | ||
| 151 | 156 | ||
| 152 | if (!dig || !dig->afmt) | 157 | if (!dig || !dig->afmt) |
| 153 | return; | 158 | return; |
| 154 | 159 | ||
| 160 | if (max_ratio >= 8) { | ||
| 161 | dto_phase = 192 * 1000; | ||
| 162 | wallclock_ratio = 3; | ||
| 163 | } else if (max_ratio >= 4) { | ||
| 164 | dto_phase = 96 * 1000; | ||
| 165 | wallclock_ratio = 2; | ||
| 166 | } else if (max_ratio >= 2) { | ||
| 167 | dto_phase = 48 * 1000; | ||
| 168 | wallclock_ratio = 1; | ||
| 169 | } else { | ||
| 170 | dto_phase = 24 * 1000; | ||
| 171 | wallclock_ratio = 0; | ||
| 172 | } | ||
| 173 | dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; | ||
| 174 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); | ||
| 175 | WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl); | ||
| 176 | |||
| 155 | /* XXX two dtos; generally use dto0 for hdmi */ | 177 | /* XXX two dtos; generally use dto0 for hdmi */ |
| 156 | /* Express [24MHz / target pixel clock] as an exact rational | 178 | /* Express [24MHz / target pixel clock] as an exact rational |
| 157 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE | 179 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE |
| 158 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator | 180 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator |
| 159 | */ | 181 | */ |
| 160 | WREG32(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id)); | 182 | WREG32(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id)); |
| 161 | WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100); | 183 | WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase); |
| 162 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100); | 184 | WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo); |
| 163 | } | 185 | } |
| 164 | 186 | ||
| 165 | 187 | ||
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index a7baf67aef6c..0d582ac1dc31 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
| @@ -497,6 +497,9 @@ | |||
| 497 | #define DCCG_AUDIO_DTO0_MODULE 0x05b4 | 497 | #define DCCG_AUDIO_DTO0_MODULE 0x05b4 |
| 498 | #define DCCG_AUDIO_DTO0_LOAD 0x05b8 | 498 | #define DCCG_AUDIO_DTO0_LOAD 0x05b8 |
| 499 | #define DCCG_AUDIO_DTO0_CNTL 0x05bc | 499 | #define DCCG_AUDIO_DTO0_CNTL 0x05bc |
| 500 | # define DCCG_AUDIO_DTO_WALLCLOCK_RATIO(x) (((x) & 7) << 0) | ||
| 501 | # define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK 7 | ||
| 502 | # define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_SHIFT 0 | ||
| 500 | 503 | ||
| 501 | #define DCCG_AUDIO_DTO1_PHASE 0x05c0 | 504 | #define DCCG_AUDIO_DTO1_PHASE 0x05c0 |
| 502 | #define DCCG_AUDIO_DTO1_MODULE 0x05c4 | 505 | #define DCCG_AUDIO_DTO1_MODULE 0x05c4 |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 56bd4f3be4fe..ccb4f8b54852 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
| @@ -794,9 +794,13 @@ int ni_init_microcode(struct radeon_device *rdev) | |||
| 794 | if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAYMAN)) { | 794 | if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAYMAN)) { |
| 795 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); | 795 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); |
| 796 | err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); | 796 | err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); |
| 797 | if (err) | 797 | if (err) { |
| 798 | goto out; | 798 | printk(KERN_ERR |
| 799 | if (rdev->smc_fw->size != smc_req_size) { | 799 | "smc: error loading firmware \"%s\"\n", |
| 800 | fw_name); | ||
| 801 | release_firmware(rdev->smc_fw); | ||
| 802 | rdev->smc_fw = NULL; | ||
| 803 | } else if (rdev->smc_fw->size != smc_req_size) { | ||
| 800 | printk(KERN_ERR | 804 | printk(KERN_ERR |
| 801 | "ni_mc: Bogus length %zu in firmware \"%s\"\n", | 805 | "ni_mc: Bogus length %zu in firmware \"%s\"\n", |
| 802 | rdev->mc_fw->size, fw_name); | 806 | rdev->mc_fw->size, fw_name); |
| @@ -2079,6 +2083,8 @@ static int cayman_startup(struct radeon_device *rdev) | |||
| 2079 | /* enable aspm */ | 2083 | /* enable aspm */ |
| 2080 | evergreen_program_aspm(rdev); | 2084 | evergreen_program_aspm(rdev); |
| 2081 | 2085 | ||
| 2086 | evergreen_mc_program(rdev); | ||
| 2087 | |||
| 2082 | if (rdev->flags & RADEON_IS_IGP) { | 2088 | if (rdev->flags & RADEON_IS_IGP) { |
| 2083 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | 2089 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { |
| 2084 | r = ni_init_microcode(rdev); | 2090 | r = ni_init_microcode(rdev); |
| @@ -2107,7 +2113,6 @@ static int cayman_startup(struct radeon_device *rdev) | |||
| 2107 | if (r) | 2113 | if (r) |
| 2108 | return r; | 2114 | return r; |
| 2109 | 2115 | ||
| 2110 | evergreen_mc_program(rdev); | ||
| 2111 | r = cayman_pcie_gart_enable(rdev); | 2116 | r = cayman_pcie_gart_enable(rdev); |
| 2112 | if (r) | 2117 | if (r) |
| 2113 | return r; | 2118 | return r; |
| @@ -2286,7 +2291,7 @@ int cayman_suspend(struct radeon_device *rdev) | |||
| 2286 | radeon_vm_manager_fini(rdev); | 2291 | radeon_vm_manager_fini(rdev); |
| 2287 | cayman_cp_enable(rdev, false); | 2292 | cayman_cp_enable(rdev, false); |
| 2288 | cayman_dma_stop(rdev); | 2293 | cayman_dma_stop(rdev); |
| 2289 | r600_uvd_rbc_stop(rdev); | 2294 | r600_uvd_stop(rdev); |
| 2290 | radeon_uvd_suspend(rdev); | 2295 | radeon_uvd_suspend(rdev); |
| 2291 | evergreen_irq_suspend(rdev); | 2296 | evergreen_irq_suspend(rdev); |
| 2292 | radeon_wb_disable(rdev); | 2297 | radeon_wb_disable(rdev); |
| @@ -2418,6 +2423,7 @@ void cayman_fini(struct radeon_device *rdev) | |||
| 2418 | radeon_vm_manager_fini(rdev); | 2423 | radeon_vm_manager_fini(rdev); |
| 2419 | radeon_ib_pool_fini(rdev); | 2424 | radeon_ib_pool_fini(rdev); |
| 2420 | radeon_irq_kms_fini(rdev); | 2425 | radeon_irq_kms_fini(rdev); |
| 2426 | r600_uvd_stop(rdev); | ||
| 2421 | radeon_uvd_fini(rdev); | 2427 | radeon_uvd_fini(rdev); |
| 2422 | cayman_pcie_gart_fini(rdev); | 2428 | cayman_pcie_gart_fini(rdev); |
| 2423 | r600_vram_scratch_fini(rdev); | 2429 | r600_vram_scratch_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index 4f9b9bc20daa..f0f5f748938a 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c | |||
| @@ -4067,9 +4067,6 @@ int ni_dpm_init(struct radeon_device *rdev) | |||
| 4067 | struct rv7xx_power_info *pi; | 4067 | struct rv7xx_power_info *pi; |
| 4068 | struct evergreen_power_info *eg_pi; | 4068 | struct evergreen_power_info *eg_pi; |
| 4069 | struct ni_power_info *ni_pi; | 4069 | struct ni_power_info *ni_pi; |
| 4070 | int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); | ||
| 4071 | u16 data_offset, size; | ||
| 4072 | u8 frev, crev; | ||
| 4073 | struct atom_clock_dividers dividers; | 4070 | struct atom_clock_dividers dividers; |
| 4074 | int ret; | 4071 | int ret; |
| 4075 | 4072 | ||
| @@ -4162,16 +4159,7 @@ int ni_dpm_init(struct radeon_device *rdev) | |||
| 4162 | eg_pi->vddci_control = | 4159 | eg_pi->vddci_control = |
| 4163 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0); | 4160 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0); |
| 4164 | 4161 | ||
| 4165 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, | 4162 | rv770_get_engine_memory_ss(rdev); |
| 4166 | &frev, &crev, &data_offset)) { | ||
| 4167 | pi->sclk_ss = true; | ||
| 4168 | pi->mclk_ss = true; | ||
| 4169 | pi->dynamic_ss = true; | ||
| 4170 | } else { | ||
| 4171 | pi->sclk_ss = false; | ||
| 4172 | pi->mclk_ss = false; | ||
| 4173 | pi->dynamic_ss = true; | ||
| 4174 | } | ||
| 4175 | 4163 | ||
| 4176 | pi->asi = RV770_ASI_DFLT; | 4164 | pi->asi = RV770_ASI_DFLT; |
| 4177 | pi->pasi = CYPRESS_HASI_DFLT; | 4165 | pi->pasi = CYPRESS_HASI_DFLT; |
| @@ -4188,8 +4176,7 @@ int ni_dpm_init(struct radeon_device *rdev) | |||
| 4188 | 4176 | ||
| 4189 | pi->dynamic_pcie_gen2 = true; | 4177 | pi->dynamic_pcie_gen2 = true; |
| 4190 | 4178 | ||
| 4191 | if (pi->gfx_clock_gating && | 4179 | if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE) |
| 4192 | (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)) | ||
| 4193 | pi->thermal_protection = true; | 4180 | pi->thermal_protection = true; |
| 4194 | else | 4181 | else |
| 4195 | pi->thermal_protection = false; | 4182 | pi->thermal_protection = false; |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 10f712e37003..e66e72077350 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -2299,9 +2299,13 @@ int r600_init_microcode(struct radeon_device *rdev) | |||
| 2299 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_HEMLOCK)) { | 2299 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_HEMLOCK)) { |
| 2300 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", smc_chip_name); | 2300 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", smc_chip_name); |
| 2301 | err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); | 2301 | err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); |
| 2302 | if (err) | 2302 | if (err) { |
| 2303 | goto out; | 2303 | printk(KERN_ERR |
| 2304 | if (rdev->smc_fw->size != smc_req_size) { | 2304 | "smc: error loading firmware \"%s\"\n", |
| 2305 | fw_name); | ||
| 2306 | release_firmware(rdev->smc_fw); | ||
| 2307 | rdev->smc_fw = NULL; | ||
| 2308 | } else if (rdev->smc_fw->size != smc_req_size) { | ||
| 2305 | printk(KERN_ERR | 2309 | printk(KERN_ERR |
| 2306 | "smc: Bogus length %zu in firmware \"%s\"\n", | 2310 | "smc: Bogus length %zu in firmware \"%s\"\n", |
| 2307 | rdev->smc_fw->size, fw_name); | 2311 | rdev->smc_fw->size, fw_name); |
| @@ -2697,12 +2701,29 @@ int r600_uvd_rbc_start(struct radeon_device *rdev) | |||
| 2697 | return 0; | 2701 | return 0; |
| 2698 | } | 2702 | } |
| 2699 | 2703 | ||
| 2700 | void r600_uvd_rbc_stop(struct radeon_device *rdev) | 2704 | void r600_uvd_stop(struct radeon_device *rdev) |
| 2701 | { | 2705 | { |
| 2702 | struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; | 2706 | struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; |
| 2703 | 2707 | ||
| 2704 | /* force RBC into idle state */ | 2708 | /* force RBC into idle state */ |
| 2705 | WREG32(UVD_RBC_RB_CNTL, 0x11010101); | 2709 | WREG32(UVD_RBC_RB_CNTL, 0x11010101); |
| 2710 | |||
| 2711 | /* Stall UMC and register bus before resetting VCPU */ | ||
| 2712 | WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8)); | ||
| 2713 | WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3)); | ||
| 2714 | mdelay(1); | ||
| 2715 | |||
| 2716 | /* put VCPU into reset */ | ||
| 2717 | WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET); | ||
| 2718 | mdelay(5); | ||
| 2719 | |||
| 2720 | /* disable VCPU clock */ | ||
| 2721 | WREG32(UVD_VCPU_CNTL, 0x0); | ||
| 2722 | |||
| 2723 | /* Unstall UMC and register bus */ | ||
| 2724 | WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8)); | ||
| 2725 | WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3)); | ||
| 2726 | |||
| 2706 | ring->ready = false; | 2727 | ring->ready = false; |
| 2707 | } | 2728 | } |
| 2708 | 2729 | ||
| @@ -2722,6 +2743,11 @@ int r600_uvd_init(struct radeon_device *rdev) | |||
| 2722 | /* disable interupt */ | 2743 | /* disable interupt */ |
| 2723 | WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1)); | 2744 | WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1)); |
| 2724 | 2745 | ||
| 2746 | /* Stall UMC and register bus before resetting VCPU */ | ||
| 2747 | WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8)); | ||
| 2748 | WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3)); | ||
| 2749 | mdelay(1); | ||
| 2750 | |||
| 2725 | /* put LMI, VCPU, RBC etc... into reset */ | 2751 | /* put LMI, VCPU, RBC etc... into reset */ |
| 2726 | WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET | | 2752 | WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET | |
| 2727 | LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET | | 2753 | LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET | |
| @@ -2751,10 +2777,6 @@ int r600_uvd_init(struct radeon_device *rdev) | |||
| 2751 | WREG32(UVD_MPC_SET_ALU, 0); | 2777 | WREG32(UVD_MPC_SET_ALU, 0); |
| 2752 | WREG32(UVD_MPC_SET_MUX, 0x88); | 2778 | WREG32(UVD_MPC_SET_MUX, 0x88); |
| 2753 | 2779 | ||
| 2754 | /* Stall UMC */ | ||
| 2755 | WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8)); | ||
| 2756 | WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3)); | ||
| 2757 | |||
| 2758 | /* take all subblocks out of reset, except VCPU */ | 2780 | /* take all subblocks out of reset, except VCPU */ |
| 2759 | WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET); | 2781 | WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET); |
| 2760 | mdelay(5); | 2782 | mdelay(5); |
| @@ -3312,6 +3334,8 @@ static int r600_startup(struct radeon_device *rdev) | |||
| 3312 | /* enable pcie gen2 link */ | 3334 | /* enable pcie gen2 link */ |
| 3313 | r600_pcie_gen2_enable(rdev); | 3335 | r600_pcie_gen2_enable(rdev); |
| 3314 | 3336 | ||
| 3337 | r600_mc_program(rdev); | ||
| 3338 | |||
| 3315 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | 3339 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { |
| 3316 | r = r600_init_microcode(rdev); | 3340 | r = r600_init_microcode(rdev); |
| 3317 | if (r) { | 3341 | if (r) { |
| @@ -3324,7 +3348,6 @@ static int r600_startup(struct radeon_device *rdev) | |||
| 3324 | if (r) | 3348 | if (r) |
| 3325 | return r; | 3349 | return r; |
| 3326 | 3350 | ||
| 3327 | r600_mc_program(rdev); | ||
| 3328 | if (rdev->flags & RADEON_IS_AGP) { | 3351 | if (rdev->flags & RADEON_IS_AGP) { |
| 3329 | r600_agp_enable(rdev); | 3352 | r600_agp_enable(rdev); |
| 3330 | } else { | 3353 | } else { |
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index f48240bb8c56..f264df5470f7 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c | |||
| @@ -226,10 +226,29 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) | |||
| 226 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 226 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 227 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 227 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 228 | u32 base_rate = 24000; | 228 | u32 base_rate = 24000; |
| 229 | u32 max_ratio = clock / base_rate; | ||
| 230 | u32 dto_phase; | ||
| 231 | u32 dto_modulo = clock; | ||
| 232 | u32 wallclock_ratio; | ||
| 233 | u32 dto_cntl; | ||
| 229 | 234 | ||
| 230 | if (!dig || !dig->afmt) | 235 | if (!dig || !dig->afmt) |
| 231 | return; | 236 | return; |
| 232 | 237 | ||
| 238 | if (max_ratio >= 8) { | ||
| 239 | dto_phase = 192 * 1000; | ||
| 240 | wallclock_ratio = 3; | ||
| 241 | } else if (max_ratio >= 4) { | ||
| 242 | dto_phase = 96 * 1000; | ||
| 243 | wallclock_ratio = 2; | ||
| 244 | } else if (max_ratio >= 2) { | ||
| 245 | dto_phase = 48 * 1000; | ||
| 246 | wallclock_ratio = 1; | ||
| 247 | } else { | ||
| 248 | dto_phase = 24 * 1000; | ||
| 249 | wallclock_ratio = 0; | ||
| 250 | } | ||
| 251 | |||
| 233 | /* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT. | 252 | /* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT. |
| 234 | * doesn't matter which one you use. Just use the first one. | 253 | * doesn't matter which one you use. Just use the first one. |
| 235 | */ | 254 | */ |
| @@ -242,9 +261,21 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) | |||
| 242 | /* according to the reg specs, this should DCE3.2 only, but in | 261 | /* according to the reg specs, this should DCE3.2 only, but in |
| 243 | * practice it seems to cover DCE3.0 as well. | 262 | * practice it seems to cover DCE3.0 as well. |
| 244 | */ | 263 | */ |
| 245 | WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100); | 264 | if (dig->dig_encoder == 0) { |
| 246 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100); | 265 | dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; |
| 247 | WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ | 266 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); |
| 267 | WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl); | ||
| 268 | WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase); | ||
| 269 | WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo); | ||
| 270 | WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ | ||
| 271 | } else { | ||
| 272 | dto_cntl = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; | ||
| 273 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); | ||
| 274 | WREG32(DCCG_AUDIO_DTO1_CNTL, dto_cntl); | ||
| 275 | WREG32(DCCG_AUDIO_DTO1_PHASE, dto_phase); | ||
| 276 | WREG32(DCCG_AUDIO_DTO1_MODULE, dto_modulo); | ||
| 277 | WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ | ||
| 278 | } | ||
| 248 | } else { | 279 | } else { |
| 249 | /* according to the reg specs, this should be DCE2.0 and DCE3.0 */ | 280 | /* according to the reg specs, this should be DCE2.0 and DCE3.0 */ |
| 250 | WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) | | 281 | WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) | |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 8e3fe815edab..7c780839a7f4 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
| @@ -933,6 +933,9 @@ | |||
| 933 | #define DCCG_AUDIO_DTO0_LOAD 0x051c | 933 | #define DCCG_AUDIO_DTO0_LOAD 0x051c |
| 934 | # define DTO_LOAD (1 << 31) | 934 | # define DTO_LOAD (1 << 31) |
| 935 | #define DCCG_AUDIO_DTO0_CNTL 0x0520 | 935 | #define DCCG_AUDIO_DTO0_CNTL 0x0520 |
| 936 | # define DCCG_AUDIO_DTO_WALLCLOCK_RATIO(x) (((x) & 7) << 0) | ||
| 937 | # define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK 7 | ||
| 938 | # define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_SHIFT 0 | ||
| 936 | 939 | ||
| 937 | #define DCCG_AUDIO_DTO1_PHASE 0x0524 | 940 | #define DCCG_AUDIO_DTO1_PHASE 0x0524 |
| 938 | #define DCCG_AUDIO_DTO1_MODULE 0x0528 | 941 | #define DCCG_AUDIO_DTO1_MODULE 0x0528 |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 2f08219c39b6..274b8e1b889f 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -1468,7 +1468,6 @@ struct radeon_uvd { | |||
| 1468 | void *cpu_addr; | 1468 | void *cpu_addr; |
| 1469 | uint64_t gpu_addr; | 1469 | uint64_t gpu_addr; |
| 1470 | void *saved_bo; | 1470 | void *saved_bo; |
| 1471 | unsigned fw_size; | ||
| 1472 | atomic_t handles[RADEON_MAX_UVD_HANDLES]; | 1471 | atomic_t handles[RADEON_MAX_UVD_HANDLES]; |
| 1473 | struct drm_file *filp[RADEON_MAX_UVD_HANDLES]; | 1472 | struct drm_file *filp[RADEON_MAX_UVD_HANDLES]; |
| 1474 | struct delayed_work idle_work; | 1473 | struct delayed_work idle_work; |
| @@ -2066,6 +2065,7 @@ struct radeon_device { | |||
| 2066 | const struct firmware *mec_fw; /* CIK MEC firmware */ | 2065 | const struct firmware *mec_fw; /* CIK MEC firmware */ |
| 2067 | const struct firmware *sdma_fw; /* CIK SDMA firmware */ | 2066 | const struct firmware *sdma_fw; /* CIK SDMA firmware */ |
| 2068 | const struct firmware *smc_fw; /* SMC firmware */ | 2067 | const struct firmware *smc_fw; /* SMC firmware */ |
| 2068 | const struct firmware *uvd_fw; /* UVD firmware */ | ||
| 2069 | struct r600_blit r600_blit; | 2069 | struct r600_blit r600_blit; |
| 2070 | struct r600_vram_scratch vram_scratch; | 2070 | struct r600_vram_scratch vram_scratch; |
| 2071 | int msi_enabled; /* msi enabled */ | 2071 | int msi_enabled; /* msi enabled */ |
| @@ -2095,6 +2095,8 @@ struct radeon_device { | |||
| 2095 | /* ACPI interface */ | 2095 | /* ACPI interface */ |
| 2096 | struct radeon_atif atif; | 2096 | struct radeon_atif atif; |
| 2097 | struct radeon_atcs atcs; | 2097 | struct radeon_atcs atcs; |
| 2098 | /* srbm instance registers */ | ||
| 2099 | struct mutex srbm_mutex; | ||
| 2098 | }; | 2100 | }; |
| 2099 | 2101 | ||
| 2100 | int radeon_device_init(struct radeon_device *rdev, | 2102 | int radeon_device_init(struct radeon_device *rdev, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 902479fa737f..3d61d5aac18f 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
| @@ -441,7 +441,7 @@ void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rde | |||
| 441 | /* uvd */ | 441 | /* uvd */ |
| 442 | int r600_uvd_init(struct radeon_device *rdev); | 442 | int r600_uvd_init(struct radeon_device *rdev); |
| 443 | int r600_uvd_rbc_start(struct radeon_device *rdev); | 443 | int r600_uvd_rbc_start(struct radeon_device *rdev); |
| 444 | void r600_uvd_rbc_stop(struct radeon_device *rdev); | 444 | void r600_uvd_stop(struct radeon_device *rdev); |
| 445 | int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); | 445 | int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); |
| 446 | void r600_uvd_fence_emit(struct radeon_device *rdev, | 446 | void r600_uvd_fence_emit(struct radeon_device *rdev, |
| 447 | struct radeon_fence *fence); | 447 | struct radeon_fence *fence); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 82335e38ec4f..63398ae1dbf5 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -1163,6 +1163,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
| 1163 | mutex_init(&rdev->gem.mutex); | 1163 | mutex_init(&rdev->gem.mutex); |
| 1164 | mutex_init(&rdev->pm.mutex); | 1164 | mutex_init(&rdev->pm.mutex); |
| 1165 | mutex_init(&rdev->gpu_clock_mutex); | 1165 | mutex_init(&rdev->gpu_clock_mutex); |
| 1166 | mutex_init(&rdev->srbm_mutex); | ||
| 1166 | init_rwsem(&rdev->pm.mclk_lock); | 1167 | init_rwsem(&rdev->pm.mclk_lock); |
| 1167 | init_rwsem(&rdev->exclusive_lock); | 1168 | init_rwsem(&rdev->exclusive_lock); |
| 1168 | init_waitqueue_head(&rdev->irq.vblank_queue); | 1169 | init_waitqueue_head(&rdev->irq.vblank_queue); |
| @@ -1519,6 +1520,7 @@ int radeon_gpu_reset(struct radeon_device *rdev) | |||
| 1519 | radeon_save_bios_scratch_regs(rdev); | 1520 | radeon_save_bios_scratch_regs(rdev); |
| 1520 | /* block TTM */ | 1521 | /* block TTM */ |
| 1521 | resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); | 1522 | resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); |
| 1523 | radeon_pm_suspend(rdev); | ||
| 1522 | radeon_suspend(rdev); | 1524 | radeon_suspend(rdev); |
| 1523 | 1525 | ||
| 1524 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | 1526 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
| @@ -1564,6 +1566,7 @@ retry: | |||
| 1564 | } | 1566 | } |
| 1565 | } | 1567 | } |
| 1566 | 1568 | ||
| 1569 | radeon_pm_resume(rdev); | ||
| 1567 | drm_helper_resume_force_mode(rdev->ddev); | 1570 | drm_helper_resume_force_mode(rdev->ddev); |
| 1568 | 1571 | ||
| 1569 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); | 1572 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 7ddb0efe2408..ddb8f8e04eb5 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
| @@ -782,7 +782,7 @@ int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring) | |||
| 782 | 782 | ||
| 783 | } else { | 783 | } else { |
| 784 | /* put fence directly behind firmware */ | 784 | /* put fence directly behind firmware */ |
| 785 | index = ALIGN(rdev->uvd.fw_size, 8); | 785 | index = ALIGN(rdev->uvd_fw->size, 8); |
| 786 | rdev->fence_drv[ring].cpu_addr = rdev->uvd.cpu_addr + index; | 786 | rdev->fence_drv[ring].cpu_addr = rdev->uvd.cpu_addr + index; |
| 787 | rdev->fence_drv[ring].gpu_addr = rdev->uvd.gpu_addr + index; | 787 | rdev->fence_drv[ring].gpu_addr = rdev->uvd.gpu_addr + index; |
| 788 | } | 788 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 6a51d943ccf4..b990b1a2bd50 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
| @@ -207,7 +207,6 @@ void radeon_gart_table_vram_free(struct radeon_device *rdev) | |||
| 207 | if (rdev->gart.robj == NULL) { | 207 | if (rdev->gart.robj == NULL) { |
| 208 | return; | 208 | return; |
| 209 | } | 209 | } |
| 210 | radeon_gart_table_vram_unpin(rdev); | ||
| 211 | radeon_bo_unref(&rdev->gart.robj); | 210 | radeon_bo_unref(&rdev->gart.robj); |
| 212 | } | 211 | } |
| 213 | 212 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index f374c467aaca..c557850cd345 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
| @@ -1176,7 +1176,14 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
| 1176 | case CHIP_VERDE: | 1176 | case CHIP_VERDE: |
| 1177 | case CHIP_OLAND: | 1177 | case CHIP_OLAND: |
| 1178 | case CHIP_HAINAN: | 1178 | case CHIP_HAINAN: |
| 1179 | if (radeon_dpm == 1) | 1179 | /* DPM requires the RLC, RV770+ dGPU requires SMC */ |
| 1180 | if (!rdev->rlc_fw) | ||
| 1181 | rdev->pm.pm_method = PM_METHOD_PROFILE; | ||
| 1182 | else if ((rdev->family >= CHIP_RV770) && | ||
| 1183 | (!(rdev->flags & RADEON_IS_IGP)) && | ||
| 1184 | (!rdev->smc_fw)) | ||
| 1185 | rdev->pm.pm_method = PM_METHOD_PROFILE; | ||
| 1186 | else if (radeon_dpm == 1) | ||
| 1180 | rdev->pm.pm_method = PM_METHOD_DPM; | 1187 | rdev->pm.pm_method = PM_METHOD_DPM; |
| 1181 | else | 1188 | else |
| 1182 | rdev->pm.pm_method = PM_METHOD_PROFILE; | 1189 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 414fd145d20e..f1c15754e73c 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c | |||
| @@ -56,7 +56,6 @@ static void radeon_uvd_idle_work_handler(struct work_struct *work); | |||
| 56 | 56 | ||
| 57 | int radeon_uvd_init(struct radeon_device *rdev) | 57 | int radeon_uvd_init(struct radeon_device *rdev) |
| 58 | { | 58 | { |
| 59 | const struct firmware *fw; | ||
| 60 | unsigned long bo_size; | 59 | unsigned long bo_size; |
| 61 | const char *fw_name; | 60 | const char *fw_name; |
| 62 | int i, r; | 61 | int i, r; |
| @@ -105,14 +104,14 @@ int radeon_uvd_init(struct radeon_device *rdev) | |||
| 105 | return -EINVAL; | 104 | return -EINVAL; |
| 106 | } | 105 | } |
| 107 | 106 | ||
| 108 | r = request_firmware(&fw, fw_name, rdev->dev); | 107 | r = request_firmware(&rdev->uvd_fw, fw_name, rdev->dev); |
| 109 | if (r) { | 108 | if (r) { |
| 110 | dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n", | 109 | dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n", |
| 111 | fw_name); | 110 | fw_name); |
| 112 | return r; | 111 | return r; |
| 113 | } | 112 | } |
| 114 | 113 | ||
| 115 | bo_size = RADEON_GPU_PAGE_ALIGN(fw->size + 8) + | 114 | bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) + |
| 116 | RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE; | 115 | RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE; |
| 117 | r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true, | 116 | r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true, |
| 118 | RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->uvd.vcpu_bo); | 117 | RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->uvd.vcpu_bo); |
| @@ -145,12 +144,6 @@ int radeon_uvd_init(struct radeon_device *rdev) | |||
| 145 | 144 | ||
| 146 | radeon_bo_unreserve(rdev->uvd.vcpu_bo); | 145 | radeon_bo_unreserve(rdev->uvd.vcpu_bo); |
| 147 | 146 | ||
| 148 | rdev->uvd.fw_size = fw->size; | ||
| 149 | memset(rdev->uvd.cpu_addr, 0, bo_size); | ||
| 150 | memcpy(rdev->uvd.cpu_addr, fw->data, fw->size); | ||
| 151 | |||
| 152 | release_firmware(fw); | ||
| 153 | |||
| 154 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { | 147 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { |
| 155 | atomic_set(&rdev->uvd.handles[i], 0); | 148 | atomic_set(&rdev->uvd.handles[i], 0); |
| 156 | rdev->uvd.filp[i] = NULL; | 149 | rdev->uvd.filp[i] = NULL; |
| @@ -174,33 +167,60 @@ void radeon_uvd_fini(struct radeon_device *rdev) | |||
| 174 | } | 167 | } |
| 175 | 168 | ||
| 176 | radeon_bo_unref(&rdev->uvd.vcpu_bo); | 169 | radeon_bo_unref(&rdev->uvd.vcpu_bo); |
| 170 | |||
| 171 | release_firmware(rdev->uvd_fw); | ||
| 177 | } | 172 | } |
| 178 | 173 | ||
| 179 | int radeon_uvd_suspend(struct radeon_device *rdev) | 174 | int radeon_uvd_suspend(struct radeon_device *rdev) |
| 180 | { | 175 | { |
| 181 | unsigned size; | 176 | unsigned size; |
| 177 | void *ptr; | ||
| 178 | int i; | ||
| 182 | 179 | ||
| 183 | if (rdev->uvd.vcpu_bo == NULL) | 180 | if (rdev->uvd.vcpu_bo == NULL) |
| 184 | return 0; | 181 | return 0; |
| 185 | 182 | ||
| 183 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) | ||
| 184 | if (atomic_read(&rdev->uvd.handles[i])) | ||
| 185 | break; | ||
| 186 | |||
| 187 | if (i == RADEON_MAX_UVD_HANDLES) | ||
| 188 | return 0; | ||
| 189 | |||
| 186 | size = radeon_bo_size(rdev->uvd.vcpu_bo); | 190 | size = radeon_bo_size(rdev->uvd.vcpu_bo); |
| 191 | size -= rdev->uvd_fw->size; | ||
| 192 | |||
| 193 | ptr = rdev->uvd.cpu_addr; | ||
| 194 | ptr += rdev->uvd_fw->size; | ||
| 195 | |||
| 187 | rdev->uvd.saved_bo = kmalloc(size, GFP_KERNEL); | 196 | rdev->uvd.saved_bo = kmalloc(size, GFP_KERNEL); |
| 188 | memcpy(rdev->uvd.saved_bo, rdev->uvd.cpu_addr, size); | 197 | memcpy(rdev->uvd.saved_bo, ptr, size); |
| 189 | 198 | ||
| 190 | return 0; | 199 | return 0; |
| 191 | } | 200 | } |
| 192 | 201 | ||
| 193 | int radeon_uvd_resume(struct radeon_device *rdev) | 202 | int radeon_uvd_resume(struct radeon_device *rdev) |
| 194 | { | 203 | { |
| 204 | unsigned size; | ||
| 205 | void *ptr; | ||
| 206 | |||
| 195 | if (rdev->uvd.vcpu_bo == NULL) | 207 | if (rdev->uvd.vcpu_bo == NULL) |
| 196 | return -EINVAL; | 208 | return -EINVAL; |
| 197 | 209 | ||
| 210 | memcpy(rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size); | ||
| 211 | |||
| 212 | size = radeon_bo_size(rdev->uvd.vcpu_bo); | ||
| 213 | size -= rdev->uvd_fw->size; | ||
| 214 | |||
| 215 | ptr = rdev->uvd.cpu_addr; | ||
| 216 | ptr += rdev->uvd_fw->size; | ||
| 217 | |||
| 198 | if (rdev->uvd.saved_bo != NULL) { | 218 | if (rdev->uvd.saved_bo != NULL) { |
| 199 | unsigned size = radeon_bo_size(rdev->uvd.vcpu_bo); | 219 | memcpy(ptr, rdev->uvd.saved_bo, size); |
| 200 | memcpy(rdev->uvd.cpu_addr, rdev->uvd.saved_bo, size); | ||
| 201 | kfree(rdev->uvd.saved_bo); | 220 | kfree(rdev->uvd.saved_bo); |
| 202 | rdev->uvd.saved_bo = NULL; | 221 | rdev->uvd.saved_bo = NULL; |
| 203 | } | 222 | } else |
| 223 | memset(ptr, 0, size); | ||
| 204 | 224 | ||
| 205 | return 0; | 225 | return 0; |
| 206 | } | 226 | } |
| @@ -215,8 +235,8 @@ void radeon_uvd_free_handles(struct radeon_device *rdev, struct drm_file *filp) | |||
| 215 | { | 235 | { |
| 216 | int i, r; | 236 | int i, r; |
| 217 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { | 237 | for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { |
| 218 | if (rdev->uvd.filp[i] == filp) { | 238 | uint32_t handle = atomic_read(&rdev->uvd.handles[i]); |
| 219 | uint32_t handle = atomic_read(&rdev->uvd.handles[i]); | 239 | if (handle != 0 && rdev->uvd.filp[i] == filp) { |
| 220 | struct radeon_fence *fence; | 240 | struct radeon_fence *fence; |
| 221 | 241 | ||
| 222 | r = radeon_uvd_get_destroy_msg(rdev, | 242 | r = radeon_uvd_get_destroy_msg(rdev, |
| @@ -337,8 +357,10 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, | |||
| 337 | } | 357 | } |
| 338 | 358 | ||
| 339 | r = radeon_bo_kmap(bo, &ptr); | 359 | r = radeon_bo_kmap(bo, &ptr); |
| 340 | if (r) | 360 | if (r) { |
| 361 | DRM_ERROR("Failed mapping the UVD message (%d)!\n", r); | ||
| 341 | return r; | 362 | return r; |
| 363 | } | ||
| 342 | 364 | ||
| 343 | msg = ptr + offset; | 365 | msg = ptr + offset; |
| 344 | 366 | ||
| @@ -364,8 +386,14 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, | |||
| 364 | radeon_bo_kunmap(bo); | 386 | radeon_bo_kunmap(bo); |
| 365 | return 0; | 387 | return 0; |
| 366 | } else { | 388 | } else { |
| 367 | /* it's a create msg, no special handling needed */ | ||
| 368 | radeon_bo_kunmap(bo); | 389 | radeon_bo_kunmap(bo); |
| 390 | |||
| 391 | if (msg_type != 0) { | ||
| 392 | DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type); | ||
| 393 | return -EINVAL; | ||
| 394 | } | ||
| 395 | |||
| 396 | /* it's a create msg, no special handling needed */ | ||
| 369 | } | 397 | } |
| 370 | 398 | ||
| 371 | /* create or decode, validate the handle */ | 399 | /* create or decode, validate the handle */ |
| @@ -388,7 +416,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo, | |||
| 388 | 416 | ||
| 389 | static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, | 417 | static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, |
| 390 | int data0, int data1, | 418 | int data0, int data1, |
| 391 | unsigned buf_sizes[]) | 419 | unsigned buf_sizes[], bool *has_msg_cmd) |
| 392 | { | 420 | { |
| 393 | struct radeon_cs_chunk *relocs_chunk; | 421 | struct radeon_cs_chunk *relocs_chunk; |
| 394 | struct radeon_cs_reloc *reloc; | 422 | struct radeon_cs_reloc *reloc; |
| @@ -417,7 +445,7 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, | |||
| 417 | 445 | ||
| 418 | if (cmd < 0x4) { | 446 | if (cmd < 0x4) { |
| 419 | if ((end - start) < buf_sizes[cmd]) { | 447 | if ((end - start) < buf_sizes[cmd]) { |
| 420 | DRM_ERROR("buffer to small (%d / %d)!\n", | 448 | DRM_ERROR("buffer (%d) to small (%d / %d)!\n", cmd, |
| 421 | (unsigned)(end - start), buf_sizes[cmd]); | 449 | (unsigned)(end - start), buf_sizes[cmd]); |
| 422 | return -EINVAL; | 450 | return -EINVAL; |
| 423 | } | 451 | } |
| @@ -442,9 +470,17 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, | |||
| 442 | } | 470 | } |
| 443 | 471 | ||
| 444 | if (cmd == 0) { | 472 | if (cmd == 0) { |
| 473 | if (*has_msg_cmd) { | ||
| 474 | DRM_ERROR("More than one message in a UVD-IB!\n"); | ||
| 475 | return -EINVAL; | ||
| 476 | } | ||
| 477 | *has_msg_cmd = true; | ||
| 445 | r = radeon_uvd_cs_msg(p, reloc->robj, offset, buf_sizes); | 478 | r = radeon_uvd_cs_msg(p, reloc->robj, offset, buf_sizes); |
| 446 | if (r) | 479 | if (r) |
| 447 | return r; | 480 | return r; |
| 481 | } else if (!*has_msg_cmd) { | ||
| 482 | DRM_ERROR("Message needed before other commands are send!\n"); | ||
| 483 | return -EINVAL; | ||
| 448 | } | 484 | } |
| 449 | 485 | ||
| 450 | return 0; | 486 | return 0; |
| @@ -453,7 +489,8 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, | |||
| 453 | static int radeon_uvd_cs_reg(struct radeon_cs_parser *p, | 489 | static int radeon_uvd_cs_reg(struct radeon_cs_parser *p, |
| 454 | struct radeon_cs_packet *pkt, | 490 | struct radeon_cs_packet *pkt, |
| 455 | int *data0, int *data1, | 491 | int *data0, int *data1, |
| 456 | unsigned buf_sizes[]) | 492 | unsigned buf_sizes[], |
| 493 | bool *has_msg_cmd) | ||
| 457 | { | 494 | { |
| 458 | int i, r; | 495 | int i, r; |
| 459 | 496 | ||
| @@ -467,7 +504,8 @@ static int radeon_uvd_cs_reg(struct radeon_cs_parser *p, | |||
| 467 | *data1 = p->idx; | 504 | *data1 = p->idx; |
| 468 | break; | 505 | break; |
| 469 | case UVD_GPCOM_VCPU_CMD: | 506 | case UVD_GPCOM_VCPU_CMD: |
| 470 | r = radeon_uvd_cs_reloc(p, *data0, *data1, buf_sizes); | 507 | r = radeon_uvd_cs_reloc(p, *data0, *data1, |
| 508 | buf_sizes, has_msg_cmd); | ||
| 471 | if (r) | 509 | if (r) |
| 472 | return r; | 510 | return r; |
| 473 | break; | 511 | break; |
| @@ -488,6 +526,9 @@ int radeon_uvd_cs_parse(struct radeon_cs_parser *p) | |||
| 488 | struct radeon_cs_packet pkt; | 526 | struct radeon_cs_packet pkt; |
| 489 | int r, data0 = 0, data1 = 0; | 527 | int r, data0 = 0, data1 = 0; |
| 490 | 528 | ||
| 529 | /* does the IB has a msg command */ | ||
| 530 | bool has_msg_cmd = false; | ||
| 531 | |||
| 491 | /* minimum buffer sizes */ | 532 | /* minimum buffer sizes */ |
| 492 | unsigned buf_sizes[] = { | 533 | unsigned buf_sizes[] = { |
| 493 | [0x00000000] = 2048, | 534 | [0x00000000] = 2048, |
| @@ -514,8 +555,8 @@ int radeon_uvd_cs_parse(struct radeon_cs_parser *p) | |||
| 514 | return r; | 555 | return r; |
| 515 | switch (pkt.type) { | 556 | switch (pkt.type) { |
| 516 | case RADEON_PACKET_TYPE0: | 557 | case RADEON_PACKET_TYPE0: |
| 517 | r = radeon_uvd_cs_reg(p, &pkt, &data0, | 558 | r = radeon_uvd_cs_reg(p, &pkt, &data0, &data1, |
| 518 | &data1, buf_sizes); | 559 | buf_sizes, &has_msg_cmd); |
| 519 | if (r) | 560 | if (r) |
| 520 | return r; | 561 | return r; |
| 521 | break; | 562 | break; |
| @@ -527,6 +568,12 @@ int radeon_uvd_cs_parse(struct radeon_cs_parser *p) | |||
| 527 | return -EINVAL; | 568 | return -EINVAL; |
| 528 | } | 569 | } |
| 529 | } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); | 570 | } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); |
| 571 | |||
| 572 | if (!has_msg_cmd) { | ||
| 573 | DRM_ERROR("UVD-IBs need a msg command!\n"); | ||
| 574 | return -EINVAL; | ||
| 575 | } | ||
| 576 | |||
| 530 | return 0; | 577 | return 0; |
| 531 | } | 578 | } |
| 532 | 579 | ||
diff --git a/drivers/gpu/drm/radeon/rv6xx_dpm.c b/drivers/gpu/drm/radeon/rv6xx_dpm.c index 363018c60412..bdd888b4db2b 100644 --- a/drivers/gpu/drm/radeon/rv6xx_dpm.c +++ b/drivers/gpu/drm/radeon/rv6xx_dpm.c | |||
| @@ -1944,9 +1944,7 @@ static int rv6xx_parse_power_table(struct radeon_device *rdev) | |||
| 1944 | 1944 | ||
| 1945 | int rv6xx_dpm_init(struct radeon_device *rdev) | 1945 | int rv6xx_dpm_init(struct radeon_device *rdev) |
| 1946 | { | 1946 | { |
| 1947 | int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); | 1947 | struct radeon_atom_ss ss; |
| 1948 | uint16_t data_offset, size; | ||
| 1949 | uint8_t frev, crev; | ||
| 1950 | struct atom_clock_dividers dividers; | 1948 | struct atom_clock_dividers dividers; |
| 1951 | struct rv6xx_power_info *pi; | 1949 | struct rv6xx_power_info *pi; |
| 1952 | int ret; | 1950 | int ret; |
| @@ -1989,16 +1987,18 @@ int rv6xx_dpm_init(struct radeon_device *rdev) | |||
| 1989 | 1987 | ||
| 1990 | pi->gfx_clock_gating = true; | 1988 | pi->gfx_clock_gating = true; |
| 1991 | 1989 | ||
| 1992 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, | 1990 | pi->sclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss, |
| 1993 | &frev, &crev, &data_offset)) { | 1991 | ASIC_INTERNAL_ENGINE_SS, 0); |
| 1994 | pi->sclk_ss = true; | 1992 | pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss, |
| 1995 | pi->mclk_ss = true; | 1993 | ASIC_INTERNAL_MEMORY_SS, 0); |
| 1994 | |||
| 1995 | /* Disable sclk ss, causes hangs on a lot of systems */ | ||
| 1996 | pi->sclk_ss = false; | ||
| 1997 | |||
| 1998 | if (pi->sclk_ss || pi->mclk_ss) | ||
| 1996 | pi->dynamic_ss = true; | 1999 | pi->dynamic_ss = true; |
| 1997 | } else { | 2000 | else |
| 1998 | pi->sclk_ss = false; | ||
| 1999 | pi->mclk_ss = false; | ||
| 2000 | pi->dynamic_ss = false; | 2001 | pi->dynamic_ss = false; |
| 2001 | } | ||
| 2002 | 2002 | ||
| 2003 | pi->dynamic_pcie_gen2 = true; | 2003 | pi->dynamic_pcie_gen2 = true; |
| 2004 | 2004 | ||
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 30ea14e8854c..bcc68ec204ad 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
| @@ -813,7 +813,7 @@ int rv770_uvd_resume(struct radeon_device *rdev) | |||
| 813 | 813 | ||
| 814 | /* programm the VCPU memory controller bits 0-27 */ | 814 | /* programm the VCPU memory controller bits 0-27 */ |
| 815 | addr = rdev->uvd.gpu_addr >> 3; | 815 | addr = rdev->uvd.gpu_addr >> 3; |
| 816 | size = RADEON_GPU_PAGE_ALIGN(rdev->uvd.fw_size + 4) >> 3; | 816 | size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3; |
| 817 | WREG32(UVD_VCPU_CACHE_OFFSET0, addr); | 817 | WREG32(UVD_VCPU_CACHE_OFFSET0, addr); |
| 818 | WREG32(UVD_VCPU_CACHE_SIZE0, size); | 818 | WREG32(UVD_VCPU_CACHE_SIZE0, size); |
| 819 | 819 | ||
| @@ -1829,6 +1829,8 @@ static int rv770_startup(struct radeon_device *rdev) | |||
| 1829 | /* enable pcie gen2 link */ | 1829 | /* enable pcie gen2 link */ |
| 1830 | rv770_pcie_gen2_enable(rdev); | 1830 | rv770_pcie_gen2_enable(rdev); |
| 1831 | 1831 | ||
| 1832 | rv770_mc_program(rdev); | ||
| 1833 | |||
| 1832 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | 1834 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { |
| 1833 | r = r600_init_microcode(rdev); | 1835 | r = r600_init_microcode(rdev); |
| 1834 | if (r) { | 1836 | if (r) { |
| @@ -1841,7 +1843,6 @@ static int rv770_startup(struct radeon_device *rdev) | |||
| 1841 | if (r) | 1843 | if (r) |
| 1842 | return r; | 1844 | return r; |
| 1843 | 1845 | ||
| 1844 | rv770_mc_program(rdev); | ||
| 1845 | if (rdev->flags & RADEON_IS_AGP) { | 1846 | if (rdev->flags & RADEON_IS_AGP) { |
| 1846 | rv770_agp_enable(rdev); | 1847 | rv770_agp_enable(rdev); |
| 1847 | } else { | 1848 | } else { |
| @@ -1983,6 +1984,7 @@ int rv770_resume(struct radeon_device *rdev) | |||
| 1983 | int rv770_suspend(struct radeon_device *rdev) | 1984 | int rv770_suspend(struct radeon_device *rdev) |
| 1984 | { | 1985 | { |
| 1985 | r600_audio_fini(rdev); | 1986 | r600_audio_fini(rdev); |
| 1987 | r600_uvd_stop(rdev); | ||
| 1986 | radeon_uvd_suspend(rdev); | 1988 | radeon_uvd_suspend(rdev); |
| 1987 | r700_cp_stop(rdev); | 1989 | r700_cp_stop(rdev); |
| 1988 | r600_dma_stop(rdev); | 1990 | r600_dma_stop(rdev); |
| @@ -2098,6 +2100,7 @@ void rv770_fini(struct radeon_device *rdev) | |||
| 2098 | radeon_ib_pool_fini(rdev); | 2100 | radeon_ib_pool_fini(rdev); |
| 2099 | radeon_irq_kms_fini(rdev); | 2101 | radeon_irq_kms_fini(rdev); |
| 2100 | rv770_pcie_gart_fini(rdev); | 2102 | rv770_pcie_gart_fini(rdev); |
| 2103 | r600_uvd_stop(rdev); | ||
| 2101 | radeon_uvd_fini(rdev); | 2104 | radeon_uvd_fini(rdev); |
| 2102 | r600_vram_scratch_fini(rdev); | 2105 | r600_vram_scratch_fini(rdev); |
| 2103 | radeon_gem_fini(rdev); | 2106 | radeon_gem_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index 2d347925f77d..094c67a29d0d 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c | |||
| @@ -2319,12 +2319,25 @@ int rv7xx_parse_power_table(struct radeon_device *rdev) | |||
| 2319 | return 0; | 2319 | return 0; |
| 2320 | } | 2320 | } |
| 2321 | 2321 | ||
| 2322 | void rv770_get_engine_memory_ss(struct radeon_device *rdev) | ||
| 2323 | { | ||
| 2324 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
| 2325 | struct radeon_atom_ss ss; | ||
| 2326 | |||
| 2327 | pi->sclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss, | ||
| 2328 | ASIC_INTERNAL_ENGINE_SS, 0); | ||
| 2329 | pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss, | ||
| 2330 | ASIC_INTERNAL_MEMORY_SS, 0); | ||
| 2331 | |||
| 2332 | if (pi->sclk_ss || pi->mclk_ss) | ||
| 2333 | pi->dynamic_ss = true; | ||
| 2334 | else | ||
| 2335 | pi->dynamic_ss = false; | ||
| 2336 | } | ||
| 2337 | |||
| 2322 | int rv770_dpm_init(struct radeon_device *rdev) | 2338 | int rv770_dpm_init(struct radeon_device *rdev) |
| 2323 | { | 2339 | { |
| 2324 | struct rv7xx_power_info *pi; | 2340 | struct rv7xx_power_info *pi; |
| 2325 | int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); | ||
| 2326 | uint16_t data_offset, size; | ||
| 2327 | uint8_t frev, crev; | ||
| 2328 | struct atom_clock_dividers dividers; | 2341 | struct atom_clock_dividers dividers; |
| 2329 | int ret; | 2342 | int ret; |
| 2330 | 2343 | ||
| @@ -2369,16 +2382,7 @@ int rv770_dpm_init(struct radeon_device *rdev) | |||
| 2369 | pi->mvdd_control = | 2382 | pi->mvdd_control = |
| 2370 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0); | 2383 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0); |
| 2371 | 2384 | ||
| 2372 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, | 2385 | rv770_get_engine_memory_ss(rdev); |
| 2373 | &frev, &crev, &data_offset)) { | ||
| 2374 | pi->sclk_ss = true; | ||
| 2375 | pi->mclk_ss = true; | ||
| 2376 | pi->dynamic_ss = true; | ||
| 2377 | } else { | ||
| 2378 | pi->sclk_ss = false; | ||
| 2379 | pi->mclk_ss = false; | ||
| 2380 | pi->dynamic_ss = false; | ||
| 2381 | } | ||
| 2382 | 2386 | ||
| 2383 | pi->asi = RV770_ASI_DFLT; | 2387 | pi->asi = RV770_ASI_DFLT; |
| 2384 | pi->pasi = RV770_HASI_DFLT; | 2388 | pi->pasi = RV770_HASI_DFLT; |
| @@ -2393,8 +2397,7 @@ int rv770_dpm_init(struct radeon_device *rdev) | |||
| 2393 | 2397 | ||
| 2394 | pi->dynamic_pcie_gen2 = true; | 2398 | pi->dynamic_pcie_gen2 = true; |
| 2395 | 2399 | ||
| 2396 | if (pi->gfx_clock_gating && | 2400 | if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE) |
| 2397 | (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)) | ||
| 2398 | pi->thermal_protection = true; | 2401 | pi->thermal_protection = true; |
| 2399 | else | 2402 | else |
| 2400 | pi->thermal_protection = false; | 2403 | pi->thermal_protection = false; |
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.h b/drivers/gpu/drm/radeon/rv770_dpm.h index 96b1b2a62a8a..9244effc6b59 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.h +++ b/drivers/gpu/drm/radeon/rv770_dpm.h | |||
| @@ -275,6 +275,7 @@ void rv770_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev, | |||
| 275 | void rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev, | 275 | void rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev, |
| 276 | struct radeon_ps *new_ps, | 276 | struct radeon_ps *new_ps, |
| 277 | struct radeon_ps *old_ps); | 277 | struct radeon_ps *old_ps); |
| 278 | void rv770_get_engine_memory_ss(struct radeon_device *rdev); | ||
| 278 | 279 | ||
| 279 | /* smc */ | 280 | /* smc */ |
| 280 | int rv770_read_smc_soft_register(struct radeon_device *rdev, | 281 | int rv770_read_smc_soft_register(struct radeon_device *rdev, |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 6ca904673a4f..daa8d2df8ec5 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
| @@ -1663,9 +1663,13 @@ static int si_init_microcode(struct radeon_device *rdev) | |||
| 1663 | 1663 | ||
| 1664 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); | 1664 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); |
| 1665 | err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); | 1665 | err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); |
| 1666 | if (err) | 1666 | if (err) { |
| 1667 | goto out; | 1667 | printk(KERN_ERR |
| 1668 | if (rdev->smc_fw->size != smc_req_size) { | 1668 | "smc: error loading firmware \"%s\"\n", |
| 1669 | fw_name); | ||
| 1670 | release_firmware(rdev->smc_fw); | ||
| 1671 | rdev->smc_fw = NULL; | ||
| 1672 | } else if (rdev->smc_fw->size != smc_req_size) { | ||
| 1669 | printk(KERN_ERR | 1673 | printk(KERN_ERR |
| 1670 | "si_smc: Bogus length %zu in firmware \"%s\"\n", | 1674 | "si_smc: Bogus length %zu in firmware \"%s\"\n", |
| 1671 | rdev->smc_fw->size, fw_name); | 1675 | rdev->smc_fw->size, fw_name); |
| @@ -6418,6 +6422,8 @@ static int si_startup(struct radeon_device *rdev) | |||
| 6418 | /* enable aspm */ | 6422 | /* enable aspm */ |
| 6419 | si_program_aspm(rdev); | 6423 | si_program_aspm(rdev); |
| 6420 | 6424 | ||
| 6425 | si_mc_program(rdev); | ||
| 6426 | |||
| 6421 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || | 6427 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || |
| 6422 | !rdev->rlc_fw || !rdev->mc_fw) { | 6428 | !rdev->rlc_fw || !rdev->mc_fw) { |
| 6423 | r = si_init_microcode(rdev); | 6429 | r = si_init_microcode(rdev); |
| @@ -6437,7 +6443,6 @@ static int si_startup(struct radeon_device *rdev) | |||
| 6437 | if (r) | 6443 | if (r) |
| 6438 | return r; | 6444 | return r; |
| 6439 | 6445 | ||
| 6440 | si_mc_program(rdev); | ||
| 6441 | r = si_pcie_gart_enable(rdev); | 6446 | r = si_pcie_gart_enable(rdev); |
| 6442 | if (r) | 6447 | if (r) |
| 6443 | return r; | 6448 | return r; |
| @@ -6621,7 +6626,7 @@ int si_suspend(struct radeon_device *rdev) | |||
| 6621 | si_cp_enable(rdev, false); | 6626 | si_cp_enable(rdev, false); |
| 6622 | cayman_dma_stop(rdev); | 6627 | cayman_dma_stop(rdev); |
| 6623 | if (rdev->has_uvd) { | 6628 | if (rdev->has_uvd) { |
| 6624 | r600_uvd_rbc_stop(rdev); | 6629 | r600_uvd_stop(rdev); |
| 6625 | radeon_uvd_suspend(rdev); | 6630 | radeon_uvd_suspend(rdev); |
| 6626 | } | 6631 | } |
| 6627 | si_irq_suspend(rdev); | 6632 | si_irq_suspend(rdev); |
| @@ -6763,8 +6768,10 @@ void si_fini(struct radeon_device *rdev) | |||
| 6763 | radeon_vm_manager_fini(rdev); | 6768 | radeon_vm_manager_fini(rdev); |
| 6764 | radeon_ib_pool_fini(rdev); | 6769 | radeon_ib_pool_fini(rdev); |
| 6765 | radeon_irq_kms_fini(rdev); | 6770 | radeon_irq_kms_fini(rdev); |
| 6766 | if (rdev->has_uvd) | 6771 | if (rdev->has_uvd) { |
| 6772 | r600_uvd_stop(rdev); | ||
| 6767 | radeon_uvd_fini(rdev); | 6773 | radeon_uvd_fini(rdev); |
| 6774 | } | ||
| 6768 | si_pcie_gart_fini(rdev); | 6775 | si_pcie_gart_fini(rdev); |
| 6769 | r600_vram_scratch_fini(rdev); | 6776 | r600_vram_scratch_fini(rdev); |
| 6770 | radeon_gem_fini(rdev); | 6777 | radeon_gem_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 41825575b403..88699e3cd868 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
| @@ -2903,7 +2903,8 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, | |||
| 2903 | { | 2903 | { |
| 2904 | struct ni_ps *ps = ni_get_ps(rps); | 2904 | struct ni_ps *ps = ni_get_ps(rps); |
| 2905 | struct radeon_clock_and_voltage_limits *max_limits; | 2905 | struct radeon_clock_and_voltage_limits *max_limits; |
| 2906 | bool disable_mclk_switching; | 2906 | bool disable_mclk_switching = false; |
| 2907 | bool disable_sclk_switching = false; | ||
| 2907 | u32 mclk, sclk; | 2908 | u32 mclk, sclk; |
| 2908 | u16 vddc, vddci; | 2909 | u16 vddc, vddci; |
| 2909 | int i; | 2910 | int i; |
| @@ -2911,8 +2912,11 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, | |||
| 2911 | if ((rdev->pm.dpm.new_active_crtc_count > 1) || | 2912 | if ((rdev->pm.dpm.new_active_crtc_count > 1) || |
| 2912 | ni_dpm_vblank_too_short(rdev)) | 2913 | ni_dpm_vblank_too_short(rdev)) |
| 2913 | disable_mclk_switching = true; | 2914 | disable_mclk_switching = true; |
| 2914 | else | 2915 | |
| 2915 | disable_mclk_switching = false; | 2916 | if (rps->vclk || rps->dclk) { |
| 2917 | disable_mclk_switching = true; | ||
| 2918 | disable_sclk_switching = true; | ||
| 2919 | } | ||
| 2916 | 2920 | ||
| 2917 | if (rdev->pm.dpm.ac_power) | 2921 | if (rdev->pm.dpm.ac_power) |
| 2918 | max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; | 2922 | max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; |
| @@ -2940,27 +2944,43 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, | |||
| 2940 | 2944 | ||
| 2941 | if (disable_mclk_switching) { | 2945 | if (disable_mclk_switching) { |
| 2942 | mclk = ps->performance_levels[ps->performance_level_count - 1].mclk; | 2946 | mclk = ps->performance_levels[ps->performance_level_count - 1].mclk; |
| 2943 | sclk = ps->performance_levels[0].sclk; | ||
| 2944 | vddc = ps->performance_levels[0].vddc; | ||
| 2945 | vddci = ps->performance_levels[ps->performance_level_count - 1].vddci; | 2947 | vddci = ps->performance_levels[ps->performance_level_count - 1].vddci; |
| 2946 | } else { | 2948 | } else { |
| 2947 | sclk = ps->performance_levels[0].sclk; | ||
| 2948 | mclk = ps->performance_levels[0].mclk; | 2949 | mclk = ps->performance_levels[0].mclk; |
| 2949 | vddc = ps->performance_levels[0].vddc; | ||
| 2950 | vddci = ps->performance_levels[0].vddci; | 2950 | vddci = ps->performance_levels[0].vddci; |
| 2951 | } | 2951 | } |
| 2952 | 2952 | ||
| 2953 | if (disable_sclk_switching) { | ||
| 2954 | sclk = ps->performance_levels[ps->performance_level_count - 1].sclk; | ||
| 2955 | vddc = ps->performance_levels[ps->performance_level_count - 1].vddc; | ||
| 2956 | } else { | ||
| 2957 | sclk = ps->performance_levels[0].sclk; | ||
| 2958 | vddc = ps->performance_levels[0].vddc; | ||
| 2959 | } | ||
| 2960 | |||
| 2953 | /* adjusted low state */ | 2961 | /* adjusted low state */ |
| 2954 | ps->performance_levels[0].sclk = sclk; | 2962 | ps->performance_levels[0].sclk = sclk; |
| 2955 | ps->performance_levels[0].mclk = mclk; | 2963 | ps->performance_levels[0].mclk = mclk; |
| 2956 | ps->performance_levels[0].vddc = vddc; | 2964 | ps->performance_levels[0].vddc = vddc; |
| 2957 | ps->performance_levels[0].vddci = vddci; | 2965 | ps->performance_levels[0].vddci = vddci; |
| 2958 | 2966 | ||
| 2959 | for (i = 1; i < ps->performance_level_count; i++) { | 2967 | if (disable_sclk_switching) { |
| 2960 | if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk) | 2968 | sclk = ps->performance_levels[0].sclk; |
| 2961 | ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk; | 2969 | for (i = 1; i < ps->performance_level_count; i++) { |
| 2962 | if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc) | 2970 | if (sclk < ps->performance_levels[i].sclk) |
| 2963 | ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc; | 2971 | sclk = ps->performance_levels[i].sclk; |
| 2972 | } | ||
| 2973 | for (i = 0; i < ps->performance_level_count; i++) { | ||
| 2974 | ps->performance_levels[i].sclk = sclk; | ||
| 2975 | ps->performance_levels[i].vddc = vddc; | ||
| 2976 | } | ||
| 2977 | } else { | ||
| 2978 | for (i = 1; i < ps->performance_level_count; i++) { | ||
| 2979 | if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk) | ||
| 2980 | ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk; | ||
| 2981 | if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc) | ||
| 2982 | ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc; | ||
| 2983 | } | ||
| 2964 | } | 2984 | } |
| 2965 | 2985 | ||
| 2966 | if (disable_mclk_switching) { | 2986 | if (disable_mclk_switching) { |
| @@ -6253,9 +6273,6 @@ int si_dpm_init(struct radeon_device *rdev) | |||
| 6253 | struct evergreen_power_info *eg_pi; | 6273 | struct evergreen_power_info *eg_pi; |
| 6254 | struct ni_power_info *ni_pi; | 6274 | struct ni_power_info *ni_pi; |
| 6255 | struct si_power_info *si_pi; | 6275 | struct si_power_info *si_pi; |
| 6256 | int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); | ||
| 6257 | u16 data_offset, size; | ||
| 6258 | u8 frev, crev; | ||
| 6259 | struct atom_clock_dividers dividers; | 6276 | struct atom_clock_dividers dividers; |
| 6260 | int ret; | 6277 | int ret; |
| 6261 | u32 mask; | 6278 | u32 mask; |
| @@ -6346,16 +6363,7 @@ int si_dpm_init(struct radeon_device *rdev) | |||
| 6346 | si_pi->vddc_phase_shed_control = | 6363 | si_pi->vddc_phase_shed_control = |
| 6347 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_PHASE_LUT); | 6364 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_PHASE_LUT); |
| 6348 | 6365 | ||
| 6349 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, | 6366 | rv770_get_engine_memory_ss(rdev); |
| 6350 | &frev, &crev, &data_offset)) { | ||
| 6351 | pi->sclk_ss = true; | ||
| 6352 | pi->mclk_ss = true; | ||
| 6353 | pi->dynamic_ss = true; | ||
| 6354 | } else { | ||
| 6355 | pi->sclk_ss = false; | ||
| 6356 | pi->mclk_ss = false; | ||
| 6357 | pi->dynamic_ss = true; | ||
| 6358 | } | ||
| 6359 | 6367 | ||
| 6360 | pi->asi = RV770_ASI_DFLT; | 6368 | pi->asi = RV770_ASI_DFLT; |
| 6361 | pi->pasi = CYPRESS_HASI_DFLT; | 6369 | pi->pasi = CYPRESS_HASI_DFLT; |
| @@ -6366,8 +6374,7 @@ int si_dpm_init(struct radeon_device *rdev) | |||
| 6366 | eg_pi->sclk_deep_sleep = true; | 6374 | eg_pi->sclk_deep_sleep = true; |
| 6367 | si_pi->sclk_deep_sleep_above_low = false; | 6375 | si_pi->sclk_deep_sleep_above_low = false; |
| 6368 | 6376 | ||
| 6369 | if (pi->gfx_clock_gating && | 6377 | if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE) |
| 6370 | (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)) | ||
| 6371 | pi->thermal_protection = true; | 6378 | pi->thermal_protection = true; |
| 6372 | else | 6379 | else |
| 6373 | pi->thermal_protection = false; | 6380 | pi->thermal_protection = false; |
