aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-02-26 23:39:30 -0500
committerDave Airlie <airlied@redhat.com>2014-02-26 23:39:30 -0500
commit4d538b79197901fecc42e746d515d07fd1089b62 (patch)
tree0551acabf260fcd7c0189a4e06bb608e31d1206e
parentc48cdd23ea5006c377b670bc3056fa7b63f92574 (diff)
parent82dc62a31ce3ed7b4eeea9c65a3b69e81e2ea688 (diff)
Merge branch 'drm-next-3.15' of git://people.freedesktop.org/~deathsimple/linux into drm-next
So this is the initial pull request for radeon drm-next 3.15. Highlights: - VCE bringup including DPM support - Few cleanups for the ring handling code * 'drm-next-3.15' of git://people.freedesktop.org/~deathsimple/linux: drm/radeon: cleanup false positive lockup handling drm/radeon: drop radeon_ring_force_activity drm/radeon: drop drivers copy of the rptr drm/radeon/cik: enable/disable vce cg when encoding v2 drm/radeon: add support for vce 2.0 clock gating drm/radeon/dpm: properly enable/disable vce when vce pg is enabled drm/radeon/dpm: enable dynamic vce state switching v2 drm/radeon: add vce dpm support for KV/KB drm/radeon: enable vce dpm on CI drm/radeon: add vce dpm support for CI drm/radeon: fill in set_vce_clocks for CIK asics drm/radeon/dpm: fetch vce states from the vbios drm/radeon/dpm: fill in some initial vce infrastructure drm/radeon/dpm: move platform caps fetching to a separate function drm/radeon: add callback for setting vce clocks drm/radeon: add VCE version parsing and checking drm/radeon: add VCE ring query drm/radeon: initial VCE support v4 drm/radeon: fix CP semaphores on CIK
-rw-r--r--drivers/gpu/drm/radeon/Makefile6
-rw-r--r--drivers/gpu/drm/radeon/btc_dpm.c4
-rw-r--r--drivers/gpu/drm/radeon/ci_dpm.c67
-rw-r--r--drivers/gpu/drm/radeon/cik.c109
-rw-r--r--drivers/gpu/drm/radeon/cik_sdma.c6
-rw-r--r--drivers/gpu/drm/radeon/cikd.h49
-rw-r--r--drivers/gpu/drm/radeon/cypress_dpm.c4
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c6
-rw-r--r--drivers/gpu/drm/radeon/evergreen_dma.c4
-rw-r--r--drivers/gpu/drm/radeon/kv_dpm.c64
-rw-r--r--drivers/gpu/drm/radeon/ni.c8
-rw-r--r--drivers/gpu/drm/radeon/ni_dma.c6
-rw-r--r--drivers/gpu/drm/radeon/ni_dpm.c7
-rw-r--r--drivers/gpu/drm/radeon/r100.c5
-rw-r--r--drivers/gpu/drm/radeon/r600.c6
-rw-r--r--drivers/gpu/drm/radeon/r600_dma.c6
-rw-r--r--drivers/gpu/drm/radeon/r600_dpm.c48
-rw-r--r--drivers/gpu/drm/radeon/r600_dpm.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon.h99
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c19
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h14
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c10
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c25
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c74
-rw-r--r--drivers/gpu/drm/radeon/radeon_test.c39
-rw-r--r--drivers/gpu/drm/radeon/radeon_vce.c694
-rw-r--r--drivers/gpu/drm/radeon/rs780_dpm.c7
-rw-r--r--drivers/gpu/drm/radeon/rv6xx_dpm.c7
-rw-r--r--drivers/gpu/drm/radeon/rv770_dpm.c7
-rw-r--r--drivers/gpu/drm/radeon/si.c10
-rw-r--r--drivers/gpu/drm/radeon/si_dma.c4
-rw-r--r--drivers/gpu/drm/radeon/si_dpm.c7
-rw-r--r--drivers/gpu/drm/radeon/sid.h47
-rw-r--r--drivers/gpu/drm/radeon/sumo_dpm.c7
-rw-r--r--drivers/gpu/drm/radeon/trinity_dpm.c7
-rw-r--r--drivers/gpu/drm/radeon/uvd_v1_0.c2
-rw-r--r--drivers/gpu/drm/radeon/vce_v1_0.c187
-rw-r--r--drivers/gpu/drm/radeon/vce_v2_0.c181
-rw-r--r--include/uapi/drm/radeon_drm.h5
40 files changed, 1691 insertions, 175 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index 306364a1ecda..ed60caa32518 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -99,6 +99,12 @@ radeon-y += \
99 uvd_v3_1.o \ 99 uvd_v3_1.o \
100 uvd_v4_2.o 100 uvd_v4_2.o
101 101
102# add VCE block
103radeon-y += \
104 radeon_vce.o \
105 vce_v1_0.o \
106 vce_v2_0.o \
107
102radeon-$(CONFIG_COMPAT) += radeon_ioc32.o 108radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
103radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o 109radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
104radeon-$(CONFIG_ACPI) += radeon_acpi.o 110radeon-$(CONFIG_ACPI) += radeon_acpi.o
diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c
index ea103ccdf4bd..f81d7ca134db 100644
--- a/drivers/gpu/drm/radeon/btc_dpm.c
+++ b/drivers/gpu/drm/radeon/btc_dpm.c
@@ -2601,6 +2601,10 @@ int btc_dpm_init(struct radeon_device *rdev)
2601 pi->min_vddc_in_table = 0; 2601 pi->min_vddc_in_table = 0;
2602 pi->max_vddc_in_table = 0; 2602 pi->max_vddc_in_table = 0;
2603 2603
2604 ret = r600_get_platform_caps(rdev);
2605 if (ret)
2606 return ret;
2607
2604 ret = rv7xx_parse_power_table(rdev); 2608 ret = rv7xx_parse_power_table(rdev);
2605 if (ret) 2609 if (ret)
2606 return ret; 2610 return ret;
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c
index 8d49104ca6c2..cad89a977527 100644
--- a/drivers/gpu/drm/radeon/ci_dpm.c
+++ b/drivers/gpu/drm/radeon/ci_dpm.c
@@ -172,6 +172,8 @@ extern void si_trim_voltage_table_to_fit_state_table(struct radeon_device *rdev,
172extern void cik_enter_rlc_safe_mode(struct radeon_device *rdev); 172extern void cik_enter_rlc_safe_mode(struct radeon_device *rdev);
173extern void cik_exit_rlc_safe_mode(struct radeon_device *rdev); 173extern void cik_exit_rlc_safe_mode(struct radeon_device *rdev);
174extern int ci_mc_load_microcode(struct radeon_device *rdev); 174extern int ci_mc_load_microcode(struct radeon_device *rdev);
175extern void cik_update_cg(struct radeon_device *rdev,
176 u32 block, bool enable);
175 177
176static int ci_get_std_voltage_value_sidd(struct radeon_device *rdev, 178static int ci_get_std_voltage_value_sidd(struct radeon_device *rdev,
177 struct atom_voltage_table_entry *voltage_table, 179 struct atom_voltage_table_entry *voltage_table,
@@ -746,6 +748,14 @@ static void ci_apply_state_adjust_rules(struct radeon_device *rdev,
746 u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc; 748 u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc;
747 int i; 749 int i;
748 750
751 if (rps->vce_active) {
752 rps->evclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].evclk;
753 rps->ecclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].ecclk;
754 } else {
755 rps->evclk = 0;
756 rps->ecclk = 0;
757 }
758
749 if ((rdev->pm.dpm.new_active_crtc_count > 1) || 759 if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
750 ci_dpm_vblank_too_short(rdev)) 760 ci_dpm_vblank_too_short(rdev))
751 disable_mclk_switching = true; 761 disable_mclk_switching = true;
@@ -804,6 +814,13 @@ static void ci_apply_state_adjust_rules(struct radeon_device *rdev,
804 sclk = ps->performance_levels[0].sclk; 814 sclk = ps->performance_levels[0].sclk;
805 } 815 }
806 816
817 if (rps->vce_active) {
818 if (sclk < rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk)
819 sclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk;
820 if (mclk < rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].mclk)
821 mclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].mclk;
822 }
823
807 ps->performance_levels[0].sclk = sclk; 824 ps->performance_levels[0].sclk = sclk;
808 ps->performance_levels[0].mclk = mclk; 825 ps->performance_levels[0].mclk = mclk;
809 826
@@ -3468,7 +3485,6 @@ static int ci_enable_uvd_dpm(struct radeon_device *rdev, bool enable)
3468 0 : -EINVAL; 3485 0 : -EINVAL;
3469} 3486}
3470 3487
3471#if 0
3472static int ci_enable_vce_dpm(struct radeon_device *rdev, bool enable) 3488static int ci_enable_vce_dpm(struct radeon_device *rdev, bool enable)
3473{ 3489{
3474 struct ci_power_info *pi = ci_get_pi(rdev); 3490 struct ci_power_info *pi = ci_get_pi(rdev);
@@ -3501,6 +3517,7 @@ static int ci_enable_vce_dpm(struct radeon_device *rdev, bool enable)
3501 0 : -EINVAL; 3517 0 : -EINVAL;
3502} 3518}
3503 3519
3520#if 0
3504static int ci_enable_samu_dpm(struct radeon_device *rdev, bool enable) 3521static int ci_enable_samu_dpm(struct radeon_device *rdev, bool enable)
3505{ 3522{
3506 struct ci_power_info *pi = ci_get_pi(rdev); 3523 struct ci_power_info *pi = ci_get_pi(rdev);
@@ -3587,7 +3604,6 @@ static int ci_update_uvd_dpm(struct radeon_device *rdev, bool gate)
3587 return ci_enable_uvd_dpm(rdev, !gate); 3604 return ci_enable_uvd_dpm(rdev, !gate);
3588} 3605}
3589 3606
3590#if 0
3591static u8 ci_get_vce_boot_level(struct radeon_device *rdev) 3607static u8 ci_get_vce_boot_level(struct radeon_device *rdev)
3592{ 3608{
3593 u8 i; 3609 u8 i;
@@ -3608,15 +3624,15 @@ static int ci_update_vce_dpm(struct radeon_device *rdev,
3608 struct radeon_ps *radeon_current_state) 3624 struct radeon_ps *radeon_current_state)
3609{ 3625{
3610 struct ci_power_info *pi = ci_get_pi(rdev); 3626 struct ci_power_info *pi = ci_get_pi(rdev);
3611 bool new_vce_clock_non_zero = (radeon_new_state->evclk != 0);
3612 bool old_vce_clock_non_zero = (radeon_current_state->evclk != 0);
3613 int ret = 0; 3627 int ret = 0;
3614 u32 tmp; 3628 u32 tmp;
3615 3629
3616 if (new_vce_clock_non_zero != old_vce_clock_non_zero) { 3630 if (radeon_current_state->evclk != radeon_new_state->evclk) {
3617 if (new_vce_clock_non_zero) { 3631 if (radeon_new_state->evclk) {
3618 pi->smc_state_table.VceBootLevel = ci_get_vce_boot_level(rdev); 3632 /* turn the clocks on when encoding */
3633 cik_update_cg(rdev, RADEON_CG_BLOCK_VCE, false);
3619 3634
3635 pi->smc_state_table.VceBootLevel = ci_get_vce_boot_level(rdev);
3620 tmp = RREG32_SMC(DPM_TABLE_475); 3636 tmp = RREG32_SMC(DPM_TABLE_475);
3621 tmp &= ~VceBootLevel_MASK; 3637 tmp &= ~VceBootLevel_MASK;
3622 tmp |= VceBootLevel(pi->smc_state_table.VceBootLevel); 3638 tmp |= VceBootLevel(pi->smc_state_table.VceBootLevel);
@@ -3624,12 +3640,16 @@ static int ci_update_vce_dpm(struct radeon_device *rdev,
3624 3640
3625 ret = ci_enable_vce_dpm(rdev, true); 3641 ret = ci_enable_vce_dpm(rdev, true);
3626 } else { 3642 } else {
3643 /* turn the clocks off when not encoding */
3644 cik_update_cg(rdev, RADEON_CG_BLOCK_VCE, true);
3645
3627 ret = ci_enable_vce_dpm(rdev, false); 3646 ret = ci_enable_vce_dpm(rdev, false);
3628 } 3647 }
3629 } 3648 }
3630 return ret; 3649 return ret;
3631} 3650}
3632 3651
3652#if 0
3633static int ci_update_samu_dpm(struct radeon_device *rdev, bool gate) 3653static int ci_update_samu_dpm(struct radeon_device *rdev, bool gate)
3634{ 3654{
3635 return ci_enable_samu_dpm(rdev, gate); 3655 return ci_enable_samu_dpm(rdev, gate);
@@ -4752,13 +4772,13 @@ int ci_dpm_set_power_state(struct radeon_device *rdev)
4752 DRM_ERROR("ci_generate_dpm_level_enable_mask failed\n"); 4772 DRM_ERROR("ci_generate_dpm_level_enable_mask failed\n");
4753 return ret; 4773 return ret;
4754 } 4774 }
4755#if 0 4775
4756 ret = ci_update_vce_dpm(rdev, new_ps, old_ps); 4776 ret = ci_update_vce_dpm(rdev, new_ps, old_ps);
4757 if (ret) { 4777 if (ret) {
4758 DRM_ERROR("ci_update_vce_dpm failed\n"); 4778 DRM_ERROR("ci_update_vce_dpm failed\n");
4759 return ret; 4779 return ret;
4760 } 4780 }
4761#endif 4781
4762 ret = ci_update_sclk_t(rdev); 4782 ret = ci_update_sclk_t(rdev);
4763 if (ret) { 4783 if (ret) {
4764 DRM_ERROR("ci_update_sclk_t failed\n"); 4784 DRM_ERROR("ci_update_sclk_t failed\n");
@@ -4959,9 +4979,6 @@ static int ci_parse_power_table(struct radeon_device *rdev)
4959 if (!rdev->pm.dpm.ps) 4979 if (!rdev->pm.dpm.ps)
4960 return -ENOMEM; 4980 return -ENOMEM;
4961 power_state_offset = (u8 *)state_array->states; 4981 power_state_offset = (u8 *)state_array->states;
4962 rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
4963 rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
4964 rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
4965 for (i = 0; i < state_array->ucNumEntries; i++) { 4982 for (i = 0; i < state_array->ucNumEntries; i++) {
4966 u8 *idx; 4983 u8 *idx;
4967 power_state = (union pplib_power_state *)power_state_offset; 4984 power_state = (union pplib_power_state *)power_state_offset;
@@ -4998,6 +5015,21 @@ static int ci_parse_power_table(struct radeon_device *rdev)
4998 power_state_offset += 2 + power_state->v2.ucNumDPMLevels; 5015 power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
4999 } 5016 }
5000 rdev->pm.dpm.num_ps = state_array->ucNumEntries; 5017 rdev->pm.dpm.num_ps = state_array->ucNumEntries;
5018
5019 /* fill in the vce power states */
5020 for (i = 0; i < RADEON_MAX_VCE_LEVELS; i++) {
5021 u32 sclk, mclk;
5022 clock_array_index = rdev->pm.dpm.vce_states[i].clk_idx;
5023 clock_info = (union pplib_clock_info *)
5024 &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
5025 sclk = le16_to_cpu(clock_info->ci.usEngineClockLow);
5026 sclk |= clock_info->ci.ucEngineClockHigh << 16;
5027 mclk = le16_to_cpu(clock_info->ci.usMemoryClockLow);
5028 mclk |= clock_info->ci.ucMemoryClockHigh << 16;
5029 rdev->pm.dpm.vce_states[i].sclk = sclk;
5030 rdev->pm.dpm.vce_states[i].mclk = mclk;
5031 }
5032
5001 return 0; 5033 return 0;
5002} 5034}
5003 5035
@@ -5077,17 +5109,25 @@ int ci_dpm_init(struct radeon_device *rdev)
5077 ci_dpm_fini(rdev); 5109 ci_dpm_fini(rdev);
5078 return ret; 5110 return ret;
5079 } 5111 }
5080 ret = ci_parse_power_table(rdev); 5112
5113 ret = r600_get_platform_caps(rdev);
5081 if (ret) { 5114 if (ret) {
5082 ci_dpm_fini(rdev); 5115 ci_dpm_fini(rdev);
5083 return ret; 5116 return ret;
5084 } 5117 }
5118
5085 ret = r600_parse_extended_power_table(rdev); 5119 ret = r600_parse_extended_power_table(rdev);
5086 if (ret) { 5120 if (ret) {
5087 ci_dpm_fini(rdev); 5121 ci_dpm_fini(rdev);
5088 return ret; 5122 return ret;
5089 } 5123 }
5090 5124
5125 ret = ci_parse_power_table(rdev);
5126 if (ret) {
5127 ci_dpm_fini(rdev);
5128 return ret;
5129 }
5130
5091 pi->dll_default_on = false; 5131 pi->dll_default_on = false;
5092 pi->sram_end = SMC_RAM_END; 5132 pi->sram_end = SMC_RAM_END;
5093 5133
@@ -5120,6 +5160,7 @@ int ci_dpm_init(struct radeon_device *rdev)
5120 pi->caps_sclk_throttle_low_notification = false; 5160 pi->caps_sclk_throttle_low_notification = false;
5121 5161
5122 pi->caps_uvd_dpm = true; 5162 pi->caps_uvd_dpm = true;
5163 pi->caps_vce_dpm = true;
5123 5164
5124 ci_get_leakage_voltages(rdev); 5165 ci_get_leakage_voltages(rdev);
5125 ci_patch_dependency_tables_with_leakage(rdev); 5166 ci_patch_dependency_tables_with_leakage(rdev);
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index e6419ca7cd37..92e38b54efb9 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -75,6 +75,7 @@ extern void si_init_uvd_internal_cg(struct radeon_device *rdev);
75extern int cik_sdma_resume(struct radeon_device *rdev); 75extern int cik_sdma_resume(struct radeon_device *rdev);
76extern void cik_sdma_enable(struct radeon_device *rdev, bool enable); 76extern void cik_sdma_enable(struct radeon_device *rdev, bool enable);
77extern void cik_sdma_fini(struct radeon_device *rdev); 77extern void cik_sdma_fini(struct radeon_device *rdev);
78extern void vce_v2_0_enable_mgcg(struct radeon_device *rdev, bool enable);
78static void cik_rlc_stop(struct radeon_device *rdev); 79static void cik_rlc_stop(struct radeon_device *rdev);
79static void cik_pcie_gen3_enable(struct radeon_device *rdev); 80static void cik_pcie_gen3_enable(struct radeon_device *rdev);
80static void cik_program_aspm(struct radeon_device *rdev); 81static void cik_program_aspm(struct radeon_device *rdev);
@@ -4030,8 +4031,6 @@ static int cik_cp_gfx_resume(struct radeon_device *rdev)
4030 WREG32(CP_RB0_BASE, rb_addr); 4031 WREG32(CP_RB0_BASE, rb_addr);
4031 WREG32(CP_RB0_BASE_HI, upper_32_bits(rb_addr)); 4032 WREG32(CP_RB0_BASE_HI, upper_32_bits(rb_addr));
4032 4033
4033 ring->rptr = RREG32(CP_RB0_RPTR);
4034
4035 /* start the ring */ 4034 /* start the ring */
4036 cik_cp_gfx_start(rdev); 4035 cik_cp_gfx_start(rdev);
4037 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true; 4036 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true;
@@ -4586,8 +4585,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
4586 rdev->ring[idx].wptr = 0; 4585 rdev->ring[idx].wptr = 0;
4587 mqd->queue_state.cp_hqd_pq_wptr = rdev->ring[idx].wptr; 4586 mqd->queue_state.cp_hqd_pq_wptr = rdev->ring[idx].wptr;
4588 WREG32(CP_HQD_PQ_WPTR, mqd->queue_state.cp_hqd_pq_wptr); 4587 WREG32(CP_HQD_PQ_WPTR, mqd->queue_state.cp_hqd_pq_wptr);
4589 rdev->ring[idx].rptr = RREG32(CP_HQD_PQ_RPTR); 4588 mqd->queue_state.cp_hqd_pq_rptr = RREG32(CP_HQD_PQ_RPTR);
4590 mqd->queue_state.cp_hqd_pq_rptr = rdev->ring[idx].rptr;
4591 4589
4592 /* set the vmid for the queue */ 4590 /* set the vmid for the queue */
4593 mqd->queue_state.cp_hqd_vmid = 0; 4591 mqd->queue_state.cp_hqd_vmid = 0;
@@ -5117,11 +5115,9 @@ bool cik_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
5117 if (!(reset_mask & (RADEON_RESET_GFX | 5115 if (!(reset_mask & (RADEON_RESET_GFX |
5118 RADEON_RESET_COMPUTE | 5116 RADEON_RESET_COMPUTE |
5119 RADEON_RESET_CP))) { 5117 RADEON_RESET_CP))) {
5120 radeon_ring_lockup_update(ring); 5118 radeon_ring_lockup_update(rdev, ring);
5121 return false; 5119 return false;
5122 } 5120 }
5123 /* force CP activities */
5124 radeon_ring_force_activity(rdev, ring);
5125 return radeon_ring_test_lockup(rdev, ring); 5121 return radeon_ring_test_lockup(rdev, ring);
5126} 5122}
5127 5123
@@ -6141,6 +6137,10 @@ void cik_update_cg(struct radeon_device *rdev,
6141 cik_enable_hdp_mgcg(rdev, enable); 6137 cik_enable_hdp_mgcg(rdev, enable);
6142 cik_enable_hdp_ls(rdev, enable); 6138 cik_enable_hdp_ls(rdev, enable);
6143 } 6139 }
6140
6141 if (block & RADEON_CG_BLOCK_VCE) {
6142 vce_v2_0_enable_mgcg(rdev, enable);
6143 }
6144} 6144}
6145 6145
6146static void cik_init_cg(struct radeon_device *rdev) 6146static void cik_init_cg(struct radeon_device *rdev)
@@ -7490,6 +7490,20 @@ restart_ih:
7490 /* reset addr and status */ 7490 /* reset addr and status */
7491 WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); 7491 WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
7492 break; 7492 break;
7493 case 167: /* VCE */
7494 DRM_DEBUG("IH: VCE int: 0x%08x\n", src_data);
7495 switch (src_data) {
7496 case 0:
7497 radeon_fence_process(rdev, TN_RING_TYPE_VCE1_INDEX);
7498 break;
7499 case 1:
7500 radeon_fence_process(rdev, TN_RING_TYPE_VCE2_INDEX);
7501 break;
7502 default:
7503 DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
7504 break;
7505 }
7506 break;
7493 case 176: /* GFX RB CP_INT */ 7507 case 176: /* GFX RB CP_INT */
7494 case 177: /* GFX IB CP_INT */ 7508 case 177: /* GFX IB CP_INT */
7495 radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); 7509 radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
@@ -7789,6 +7803,22 @@ static int cik_startup(struct radeon_device *rdev)
7789 if (r) 7803 if (r)
7790 rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; 7804 rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
7791 7805
7806 r = radeon_vce_resume(rdev);
7807 if (!r) {
7808 r = vce_v2_0_resume(rdev);
7809 if (!r)
7810 r = radeon_fence_driver_start_ring(rdev,
7811 TN_RING_TYPE_VCE1_INDEX);
7812 if (!r)
7813 r = radeon_fence_driver_start_ring(rdev,
7814 TN_RING_TYPE_VCE2_INDEX);
7815 }
7816 if (r) {
7817 dev_err(rdev->dev, "VCE init error (%d).\n", r);
7818 rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0;
7819 rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0;
7820 }
7821
7792 /* Enable IRQ */ 7822 /* Enable IRQ */
7793 if (!rdev->irq.installed) { 7823 if (!rdev->irq.installed) {
7794 r = radeon_irq_kms_init(rdev); 7824 r = radeon_irq_kms_init(rdev);
@@ -7864,6 +7894,23 @@ static int cik_startup(struct radeon_device *rdev)
7864 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); 7894 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
7865 } 7895 }
7866 7896
7897 r = -ENOENT;
7898
7899 ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
7900 if (ring->ring_size)
7901 r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
7902 VCE_CMD_NO_OP);
7903
7904 ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
7905 if (ring->ring_size)
7906 r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
7907 VCE_CMD_NO_OP);
7908
7909 if (!r)
7910 r = vce_v1_0_init(rdev);
7911 else if (r != -ENOENT)
7912 DRM_ERROR("radeon: failed initializing VCE (%d).\n", r);
7913
7867 r = radeon_ib_pool_init(rdev); 7914 r = radeon_ib_pool_init(rdev);
7868 if (r) { 7915 if (r) {
7869 dev_err(rdev->dev, "IB initialization failed (%d).\n", r); 7916 dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
@@ -7934,6 +7981,7 @@ int cik_suspend(struct radeon_device *rdev)
7934 cik_sdma_enable(rdev, false); 7981 cik_sdma_enable(rdev, false);
7935 uvd_v1_0_fini(rdev); 7982 uvd_v1_0_fini(rdev);
7936 radeon_uvd_suspend(rdev); 7983 radeon_uvd_suspend(rdev);
7984 radeon_vce_suspend(rdev);
7937 cik_fini_pg(rdev); 7985 cik_fini_pg(rdev);
7938 cik_fini_cg(rdev); 7986 cik_fini_cg(rdev);
7939 cik_irq_suspend(rdev); 7987 cik_irq_suspend(rdev);
@@ -8066,6 +8114,17 @@ int cik_init(struct radeon_device *rdev)
8066 r600_ring_init(rdev, ring, 4096); 8114 r600_ring_init(rdev, ring, 4096);
8067 } 8115 }
8068 8116
8117 r = radeon_vce_init(rdev);
8118 if (!r) {
8119 ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
8120 ring->ring_obj = NULL;
8121 r600_ring_init(rdev, ring, 4096);
8122
8123 ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
8124 ring->ring_obj = NULL;
8125 r600_ring_init(rdev, ring, 4096);
8126 }
8127
8069 rdev->ih.ring_obj = NULL; 8128 rdev->ih.ring_obj = NULL;
8070 r600_ih_ring_init(rdev, 64 * 1024); 8129 r600_ih_ring_init(rdev, 64 * 1024);
8071 8130
@@ -8127,6 +8186,7 @@ void cik_fini(struct radeon_device *rdev)
8127 radeon_irq_kms_fini(rdev); 8186 radeon_irq_kms_fini(rdev);
8128 uvd_v1_0_fini(rdev); 8187 uvd_v1_0_fini(rdev);
8129 radeon_uvd_fini(rdev); 8188 radeon_uvd_fini(rdev);
8189 radeon_vce_fini(rdev);
8130 cik_pcie_gart_fini(rdev); 8190 cik_pcie_gart_fini(rdev);
8131 r600_vram_scratch_fini(rdev); 8191 r600_vram_scratch_fini(rdev);
8132 radeon_gem_fini(rdev); 8192 radeon_gem_fini(rdev);
@@ -8865,6 +8925,41 @@ int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
8865 return r; 8925 return r;
8866} 8926}
8867 8927
8928int cik_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk)
8929{
8930 int r, i;
8931 struct atom_clock_dividers dividers;
8932 u32 tmp;
8933
8934 r = radeon_atom_get_clock_dividers(rdev, COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK,
8935 ecclk, false, &dividers);
8936 if (r)
8937 return r;
8938
8939 for (i = 0; i < 100; i++) {
8940 if (RREG32_SMC(CG_ECLK_STATUS) & ECLK_STATUS)
8941 break;
8942 mdelay(10);
8943 }
8944 if (i == 100)
8945 return -ETIMEDOUT;
8946
8947 tmp = RREG32_SMC(CG_ECLK_CNTL);
8948 tmp &= ~(ECLK_DIR_CNTL_EN|ECLK_DIVIDER_MASK);
8949 tmp |= dividers.post_divider;
8950 WREG32_SMC(CG_ECLK_CNTL, tmp);
8951
8952 for (i = 0; i < 100; i++) {
8953 if (RREG32_SMC(CG_ECLK_STATUS) & ECLK_STATUS)
8954 break;
8955 mdelay(10);
8956 }
8957 if (i == 100)
8958 return -ETIMEDOUT;
8959
8960 return 0;
8961}
8962
8868static void cik_pcie_gen3_enable(struct radeon_device *rdev) 8963static void cik_pcie_gen3_enable(struct radeon_device *rdev)
8869{ 8964{
8870 struct pci_dev *root = rdev->pdev->bus->self; 8965 struct pci_dev *root = rdev->pdev->bus->self;
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c
index 1ecb3f1070e3..00150ac49cd2 100644
--- a/drivers/gpu/drm/radeon/cik_sdma.c
+++ b/drivers/gpu/drm/radeon/cik_sdma.c
@@ -362,8 +362,6 @@ static int cik_sdma_gfx_resume(struct radeon_device *rdev)
362 ring->wptr = 0; 362 ring->wptr = 0;
363 WREG32(SDMA0_GFX_RB_WPTR + reg_offset, ring->wptr << 2); 363 WREG32(SDMA0_GFX_RB_WPTR + reg_offset, ring->wptr << 2);
364 364
365 ring->rptr = RREG32(SDMA0_GFX_RB_RPTR + reg_offset) >> 2;
366
367 /* enable DMA RB */ 365 /* enable DMA RB */
368 WREG32(SDMA0_GFX_RB_CNTL + reg_offset, rb_cntl | SDMA_RB_ENABLE); 366 WREG32(SDMA0_GFX_RB_CNTL + reg_offset, rb_cntl | SDMA_RB_ENABLE);
369 367
@@ -713,11 +711,9 @@ bool cik_sdma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
713 mask = RADEON_RESET_DMA1; 711 mask = RADEON_RESET_DMA1;
714 712
715 if (!(reset_mask & mask)) { 713 if (!(reset_mask & mask)) {
716 radeon_ring_lockup_update(ring); 714 radeon_ring_lockup_update(rdev, ring);
717 return false; 715 return false;
718 } 716 }
719 /* force ring activities */
720 radeon_ring_force_activity(rdev, ring);
721 return radeon_ring_test_lockup(rdev, ring); 717 return radeon_ring_test_lockup(rdev, ring);
722} 718}
723 719
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h
index 98bae9d7b74d..213873270d5f 100644
--- a/drivers/gpu/drm/radeon/cikd.h
+++ b/drivers/gpu/drm/radeon/cikd.h
@@ -203,6 +203,12 @@
203#define CTF_TEMP_MASK 0x0003fe00 203#define CTF_TEMP_MASK 0x0003fe00
204#define CTF_TEMP_SHIFT 9 204#define CTF_TEMP_SHIFT 9
205 205
206#define CG_ECLK_CNTL 0xC05000AC
207# define ECLK_DIVIDER_MASK 0x7f
208# define ECLK_DIR_CNTL_EN (1 << 8)
209#define CG_ECLK_STATUS 0xC05000B0
210# define ECLK_STATUS (1 << 0)
211
206#define CG_SPLL_FUNC_CNTL 0xC0500140 212#define CG_SPLL_FUNC_CNTL 0xC0500140
207#define SPLL_RESET (1 << 0) 213#define SPLL_RESET (1 << 0)
208#define SPLL_PWRON (1 << 1) 214#define SPLL_PWRON (1 << 1)
@@ -2010,4 +2016,47 @@
2010/* UVD CTX indirect */ 2016/* UVD CTX indirect */
2011#define UVD_CGC_MEM_CTRL 0xC0 2017#define UVD_CGC_MEM_CTRL 0xC0
2012 2018
2019/* VCE */
2020
2021#define VCE_VCPU_CACHE_OFFSET0 0x20024
2022#define VCE_VCPU_CACHE_SIZE0 0x20028
2023#define VCE_VCPU_CACHE_OFFSET1 0x2002c
2024#define VCE_VCPU_CACHE_SIZE1 0x20030
2025#define VCE_VCPU_CACHE_OFFSET2 0x20034
2026#define VCE_VCPU_CACHE_SIZE2 0x20038
2027#define VCE_RB_RPTR2 0x20178
2028#define VCE_RB_WPTR2 0x2017c
2029#define VCE_RB_RPTR 0x2018c
2030#define VCE_RB_WPTR 0x20190
2031#define VCE_CLOCK_GATING_A 0x202f8
2032# define CGC_CLK_GATE_DLY_TIMER_MASK (0xf << 0)
2033# define CGC_CLK_GATE_DLY_TIMER(x) ((x) << 0)
2034# define CGC_CLK_GATER_OFF_DLY_TIMER_MASK (0xff << 4)
2035# define CGC_CLK_GATER_OFF_DLY_TIMER(x) ((x) << 4)
2036# define CGC_UENC_WAIT_AWAKE (1 << 18)
2037#define VCE_CLOCK_GATING_B 0x202fc
2038#define VCE_CGTT_CLK_OVERRIDE 0x207a0
2039#define VCE_UENC_CLOCK_GATING 0x207bc
2040# define CLOCK_ON_DELAY_MASK (0xf << 0)
2041# define CLOCK_ON_DELAY(x) ((x) << 0)
2042# define CLOCK_OFF_DELAY_MASK (0xff << 4)
2043# define CLOCK_OFF_DELAY(x) ((x) << 4)
2044#define VCE_UENC_REG_CLOCK_GATING 0x207c0
2045#define VCE_SYS_INT_EN 0x21300
2046# define VCE_SYS_INT_TRAP_INTERRUPT_EN (1 << 3)
2047#define VCE_LMI_CTRL2 0x21474
2048#define VCE_LMI_CTRL 0x21498
2049#define VCE_LMI_VM_CTRL 0x214a0
2050#define VCE_LMI_SWAP_CNTL 0x214b4
2051#define VCE_LMI_SWAP_CNTL1 0x214b8
2052#define VCE_LMI_CACHE_CTRL 0x214f4
2053
2054#define VCE_CMD_NO_OP 0x00000000
2055#define VCE_CMD_END 0x00000001
2056#define VCE_CMD_IB 0x00000002
2057#define VCE_CMD_FENCE 0x00000003
2058#define VCE_CMD_TRAP 0x00000004
2059#define VCE_CMD_IB_AUTO 0x00000005
2060#define VCE_CMD_SEMAPHORE 0x00000006
2061
2013#endif 2062#endif
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c
index cf783fc0ef21..5a9a5f4d7888 100644
--- a/drivers/gpu/drm/radeon/cypress_dpm.c
+++ b/drivers/gpu/drm/radeon/cypress_dpm.c
@@ -2036,6 +2036,10 @@ int cypress_dpm_init(struct radeon_device *rdev)
2036 pi->min_vddc_in_table = 0; 2036 pi->min_vddc_in_table = 0;
2037 pi->max_vddc_in_table = 0; 2037 pi->max_vddc_in_table = 0;
2038 2038
2039 ret = r600_get_platform_caps(rdev);
2040 if (ret)
2041 return ret;
2042
2039 ret = rv7xx_parse_power_table(rdev); 2043 ret = rv7xx_parse_power_table(rdev);
2040 if (ret) 2044 if (ret)
2041 return ret; 2045 return ret;
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 5623e7542d99..b1f1253e2ced 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -2990,8 +2990,6 @@ static int evergreen_cp_resume(struct radeon_device *rdev)
2990 WREG32(CP_RB_BASE, ring->gpu_addr >> 8); 2990 WREG32(CP_RB_BASE, ring->gpu_addr >> 8);
2991 WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); 2991 WREG32(CP_DEBUG, (1 << 27) | (1 << 28));
2992 2992
2993 ring->rptr = RREG32(CP_RB_RPTR);
2994
2995 evergreen_cp_start(rdev); 2993 evergreen_cp_start(rdev);
2996 ring->ready = true; 2994 ring->ready = true;
2997 r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, ring); 2995 r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, ring);
@@ -3952,11 +3950,9 @@ bool evergreen_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *rin
3952 if (!(reset_mask & (RADEON_RESET_GFX | 3950 if (!(reset_mask & (RADEON_RESET_GFX |
3953 RADEON_RESET_COMPUTE | 3951 RADEON_RESET_COMPUTE |
3954 RADEON_RESET_CP))) { 3952 RADEON_RESET_CP))) {
3955 radeon_ring_lockup_update(ring); 3953 radeon_ring_lockup_update(rdev, ring);
3956 return false; 3954 return false;
3957 } 3955 }
3958 /* force CP activities */
3959 radeon_ring_force_activity(rdev, ring);
3960 return radeon_ring_test_lockup(rdev, ring); 3956 return radeon_ring_test_lockup(rdev, ring);
3961} 3957}
3962 3958
diff --git a/drivers/gpu/drm/radeon/evergreen_dma.c b/drivers/gpu/drm/radeon/evergreen_dma.c
index a37b54436382..287fe966d7de 100644
--- a/drivers/gpu/drm/radeon/evergreen_dma.c
+++ b/drivers/gpu/drm/radeon/evergreen_dma.c
@@ -174,11 +174,9 @@ bool evergreen_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *rin
174 u32 reset_mask = evergreen_gpu_check_soft_reset(rdev); 174 u32 reset_mask = evergreen_gpu_check_soft_reset(rdev);
175 175
176 if (!(reset_mask & RADEON_RESET_DMA)) { 176 if (!(reset_mask & RADEON_RESET_DMA)) {
177 radeon_ring_lockup_update(ring); 177 radeon_ring_lockup_update(rdev, ring);
178 return false; 178 return false;
179 } 179 }
180 /* force ring activities */
181 radeon_ring_force_activity(rdev, ring);
182 return radeon_ring_test_lockup(rdev, ring); 180 return radeon_ring_test_lockup(rdev, ring);
183} 181}
184 182
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c
index 351db361239d..16ec9d56a234 100644
--- a/drivers/gpu/drm/radeon/kv_dpm.c
+++ b/drivers/gpu/drm/radeon/kv_dpm.c
@@ -1338,13 +1338,11 @@ static int kv_enable_uvd_dpm(struct radeon_device *rdev, bool enable)
1338 PPSMC_MSG_UVDDPM_Enable : PPSMC_MSG_UVDDPM_Disable); 1338 PPSMC_MSG_UVDDPM_Enable : PPSMC_MSG_UVDDPM_Disable);
1339} 1339}
1340 1340
1341#if 0
1342static int kv_enable_vce_dpm(struct radeon_device *rdev, bool enable) 1341static int kv_enable_vce_dpm(struct radeon_device *rdev, bool enable)
1343{ 1342{
1344 return kv_notify_message_to_smu(rdev, enable ? 1343 return kv_notify_message_to_smu(rdev, enable ?
1345 PPSMC_MSG_VCEDPM_Enable : PPSMC_MSG_VCEDPM_Disable); 1344 PPSMC_MSG_VCEDPM_Enable : PPSMC_MSG_VCEDPM_Disable);
1346} 1345}
1347#endif
1348 1346
1349static int kv_enable_samu_dpm(struct radeon_device *rdev, bool enable) 1347static int kv_enable_samu_dpm(struct radeon_device *rdev, bool enable)
1350{ 1348{
@@ -1389,7 +1387,6 @@ static int kv_update_uvd_dpm(struct radeon_device *rdev, bool gate)
1389 return kv_enable_uvd_dpm(rdev, !gate); 1387 return kv_enable_uvd_dpm(rdev, !gate);
1390} 1388}
1391 1389
1392#if 0
1393static u8 kv_get_vce_boot_level(struct radeon_device *rdev) 1390static u8 kv_get_vce_boot_level(struct radeon_device *rdev)
1394{ 1391{
1395 u8 i; 1392 u8 i;
@@ -1414,6 +1411,9 @@ static int kv_update_vce_dpm(struct radeon_device *rdev,
1414 int ret; 1411 int ret;
1415 1412
1416 if (radeon_new_state->evclk > 0 && radeon_current_state->evclk == 0) { 1413 if (radeon_new_state->evclk > 0 && radeon_current_state->evclk == 0) {
1414 kv_dpm_powergate_vce(rdev, false);
1415 /* turn the clocks on when encoding */
1416 cik_update_cg(rdev, RADEON_CG_BLOCK_VCE, false);
1417 if (pi->caps_stable_p_state) 1417 if (pi->caps_stable_p_state)
1418 pi->vce_boot_level = table->count - 1; 1418 pi->vce_boot_level = table->count - 1;
1419 else 1419 else
@@ -1436,11 +1436,13 @@ static int kv_update_vce_dpm(struct radeon_device *rdev,
1436 kv_enable_vce_dpm(rdev, true); 1436 kv_enable_vce_dpm(rdev, true);
1437 } else if (radeon_new_state->evclk == 0 && radeon_current_state->evclk > 0) { 1437 } else if (radeon_new_state->evclk == 0 && radeon_current_state->evclk > 0) {
1438 kv_enable_vce_dpm(rdev, false); 1438 kv_enable_vce_dpm(rdev, false);
1439 /* turn the clocks off when not encoding */
1440 cik_update_cg(rdev, RADEON_CG_BLOCK_VCE, true);
1441 kv_dpm_powergate_vce(rdev, true);
1439 } 1442 }
1440 1443
1441 return 0; 1444 return 0;
1442} 1445}
1443#endif
1444 1446
1445static int kv_update_samu_dpm(struct radeon_device *rdev, bool gate) 1447static int kv_update_samu_dpm(struct radeon_device *rdev, bool gate)
1446{ 1448{
@@ -1575,11 +1577,16 @@ static void kv_dpm_powergate_vce(struct radeon_device *rdev, bool gate)
1575 pi->vce_power_gated = gate; 1577 pi->vce_power_gated = gate;
1576 1578
1577 if (gate) { 1579 if (gate) {
1578 if (pi->caps_vce_pg) 1580 if (pi->caps_vce_pg) {
1581 /* XXX do we need a vce_v1_0_stop() ? */
1579 kv_notify_message_to_smu(rdev, PPSMC_MSG_VCEPowerOFF); 1582 kv_notify_message_to_smu(rdev, PPSMC_MSG_VCEPowerOFF);
1583 }
1580 } else { 1584 } else {
1581 if (pi->caps_vce_pg) 1585 if (pi->caps_vce_pg) {
1582 kv_notify_message_to_smu(rdev, PPSMC_MSG_VCEPowerON); 1586 kv_notify_message_to_smu(rdev, PPSMC_MSG_VCEPowerON);
1587 vce_v2_0_resume(rdev);
1588 vce_v1_0_start(rdev);
1589 }
1583 } 1590 }
1584} 1591}
1585 1592
@@ -1768,7 +1775,7 @@ int kv_dpm_set_power_state(struct radeon_device *rdev)
1768{ 1775{
1769 struct kv_power_info *pi = kv_get_pi(rdev); 1776 struct kv_power_info *pi = kv_get_pi(rdev);
1770 struct radeon_ps *new_ps = &pi->requested_rps; 1777 struct radeon_ps *new_ps = &pi->requested_rps;
1771 /*struct radeon_ps *old_ps = &pi->current_rps;*/ 1778 struct radeon_ps *old_ps = &pi->current_rps;
1772 int ret; 1779 int ret;
1773 1780
1774 if (pi->bapm_enable) { 1781 if (pi->bapm_enable) {
@@ -1798,13 +1805,12 @@ int kv_dpm_set_power_state(struct radeon_device *rdev)
1798 kv_set_enabled_levels(rdev); 1805 kv_set_enabled_levels(rdev);
1799 kv_force_lowest_valid(rdev); 1806 kv_force_lowest_valid(rdev);
1800 kv_unforce_levels(rdev); 1807 kv_unforce_levels(rdev);
1801#if 0 1808
1802 ret = kv_update_vce_dpm(rdev, new_ps, old_ps); 1809 ret = kv_update_vce_dpm(rdev, new_ps, old_ps);
1803 if (ret) { 1810 if (ret) {
1804 DRM_ERROR("kv_update_vce_dpm failed\n"); 1811 DRM_ERROR("kv_update_vce_dpm failed\n");
1805 return ret; 1812 return ret;
1806 } 1813 }
1807#endif
1808 kv_update_sclk_t(rdev); 1814 kv_update_sclk_t(rdev);
1809 } 1815 }
1810 } else { 1816 } else {
@@ -1823,13 +1829,11 @@ int kv_dpm_set_power_state(struct radeon_device *rdev)
1823 kv_program_nbps_index_settings(rdev, new_ps); 1829 kv_program_nbps_index_settings(rdev, new_ps);
1824 kv_freeze_sclk_dpm(rdev, false); 1830 kv_freeze_sclk_dpm(rdev, false);
1825 kv_set_enabled_levels(rdev); 1831 kv_set_enabled_levels(rdev);
1826#if 0
1827 ret = kv_update_vce_dpm(rdev, new_ps, old_ps); 1832 ret = kv_update_vce_dpm(rdev, new_ps, old_ps);
1828 if (ret) { 1833 if (ret) {
1829 DRM_ERROR("kv_update_vce_dpm failed\n"); 1834 DRM_ERROR("kv_update_vce_dpm failed\n");
1830 return ret; 1835 return ret;
1831 } 1836 }
1832#endif
1833 kv_update_acp_boot_level(rdev); 1837 kv_update_acp_boot_level(rdev);
1834 kv_update_sclk_t(rdev); 1838 kv_update_sclk_t(rdev);
1835 kv_enable_nb_dpm(rdev); 1839 kv_enable_nb_dpm(rdev);
@@ -2037,6 +2041,14 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev,
2037 struct radeon_clock_and_voltage_limits *max_limits = 2041 struct radeon_clock_and_voltage_limits *max_limits =
2038 &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; 2042 &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
2039 2043
2044 if (new_rps->vce_active) {
2045 new_rps->evclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].evclk;
2046 new_rps->ecclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].ecclk;
2047 } else {
2048 new_rps->evclk = 0;
2049 new_rps->ecclk = 0;
2050 }
2051
2040 mclk = max_limits->mclk; 2052 mclk = max_limits->mclk;
2041 sclk = min_sclk; 2053 sclk = min_sclk;
2042 2054
@@ -2056,6 +2068,11 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev,
2056 sclk = stable_p_state_sclk; 2068 sclk = stable_p_state_sclk;
2057 } 2069 }
2058 2070
2071 if (new_rps->vce_active) {
2072 if (sclk < rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk)
2073 sclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk;
2074 }
2075
2059 ps->need_dfs_bypass = true; 2076 ps->need_dfs_bypass = true;
2060 2077
2061 for (i = 0; i < ps->num_levels; i++) { 2078 for (i = 0; i < ps->num_levels; i++) {
@@ -2092,7 +2109,8 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev,
2092 } 2109 }
2093 } 2110 }
2094 2111
2095 pi->video_start = new_rps->dclk || new_rps->vclk; 2112 pi->video_start = new_rps->dclk || new_rps->vclk ||
2113 new_rps->evclk || new_rps->ecclk;
2096 2114
2097 if ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == 2115 if ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) ==
2098 ATOM_PPLIB_CLASSIFICATION_UI_BATTERY) 2116 ATOM_PPLIB_CLASSIFICATION_UI_BATTERY)
@@ -2538,9 +2556,6 @@ static int kv_parse_power_table(struct radeon_device *rdev)
2538 if (!rdev->pm.dpm.ps) 2556 if (!rdev->pm.dpm.ps)
2539 return -ENOMEM; 2557 return -ENOMEM;
2540 power_state_offset = (u8 *)state_array->states; 2558 power_state_offset = (u8 *)state_array->states;
2541 rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
2542 rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
2543 rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
2544 for (i = 0; i < state_array->ucNumEntries; i++) { 2559 for (i = 0; i < state_array->ucNumEntries; i++) {
2545 u8 *idx; 2560 u8 *idx;
2546 power_state = (union pplib_power_state *)power_state_offset; 2561 power_state = (union pplib_power_state *)power_state_offset;
@@ -2577,6 +2592,19 @@ static int kv_parse_power_table(struct radeon_device *rdev)
2577 power_state_offset += 2 + power_state->v2.ucNumDPMLevels; 2592 power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
2578 } 2593 }
2579 rdev->pm.dpm.num_ps = state_array->ucNumEntries; 2594 rdev->pm.dpm.num_ps = state_array->ucNumEntries;
2595
2596 /* fill in the vce power states */
2597 for (i = 0; i < RADEON_MAX_VCE_LEVELS; i++) {
2598 u32 sclk;
2599 clock_array_index = rdev->pm.dpm.vce_states[i].clk_idx;
2600 clock_info = (union pplib_clock_info *)
2601 &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
2602 sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);
2603 sclk |= clock_info->sumo.ucEngineClockHigh << 16;
2604 rdev->pm.dpm.vce_states[i].sclk = sclk;
2605 rdev->pm.dpm.vce_states[i].mclk = 0;
2606 }
2607
2580 return 0; 2608 return 0;
2581} 2609}
2582 2610
@@ -2590,6 +2618,10 @@ int kv_dpm_init(struct radeon_device *rdev)
2590 return -ENOMEM; 2618 return -ENOMEM;
2591 rdev->pm.dpm.priv = pi; 2619 rdev->pm.dpm.priv = pi;
2592 2620
2621 ret = r600_get_platform_caps(rdev);
2622 if (ret)
2623 return ret;
2624
2593 ret = r600_parse_extended_power_table(rdev); 2625 ret = r600_parse_extended_power_table(rdev);
2594 if (ret) 2626 if (ret)
2595 return ret; 2627 return ret;
@@ -2623,7 +2655,7 @@ int kv_dpm_init(struct radeon_device *rdev)
2623 pi->caps_fps = false; /* true? */ 2655 pi->caps_fps = false; /* true? */
2624 pi->caps_uvd_pg = true; 2656 pi->caps_uvd_pg = true;
2625 pi->caps_uvd_dpm = true; 2657 pi->caps_uvd_dpm = true;
2626 pi->caps_vce_pg = false; 2658 pi->caps_vce_pg = false; /* XXX true */
2627 pi->caps_samu_pg = false; 2659 pi->caps_samu_pg = false;
2628 pi->caps_acp_pg = false; 2660 pi->caps_acp_pg = false;
2629 pi->caps_stable_p_state = false; 2661 pi->caps_stable_p_state = false;
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index ea932ac66fc6..85168ecd216b 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1642,8 +1642,8 @@ static int cayman_cp_resume(struct radeon_device *rdev)
1642 ring = &rdev->ring[ridx[i]]; 1642 ring = &rdev->ring[ridx[i]];
1643 WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA); 1643 WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA);
1644 1644
1645 ring->rptr = ring->wptr = 0; 1645 ring->wptr = 0;
1646 WREG32(cp_rb_rptr[i], ring->rptr); 1646 WREG32(cp_rb_rptr[i], 0);
1647 WREG32(cp_rb_wptr[i], ring->wptr); 1647 WREG32(cp_rb_wptr[i], ring->wptr);
1648 1648
1649 mdelay(1); 1649 mdelay(1);
@@ -1917,11 +1917,9 @@ bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
1917 if (!(reset_mask & (RADEON_RESET_GFX | 1917 if (!(reset_mask & (RADEON_RESET_GFX |
1918 RADEON_RESET_COMPUTE | 1918 RADEON_RESET_COMPUTE |
1919 RADEON_RESET_CP))) { 1919 RADEON_RESET_CP))) {
1920 radeon_ring_lockup_update(ring); 1920 radeon_ring_lockup_update(rdev, ring);
1921 return false; 1921 return false;
1922 } 1922 }
1923 /* force CP activities */
1924 radeon_ring_force_activity(rdev, ring);
1925 return radeon_ring_test_lockup(rdev, ring); 1923 return radeon_ring_test_lockup(rdev, ring);
1926} 1924}
1927 1925
diff --git a/drivers/gpu/drm/radeon/ni_dma.c b/drivers/gpu/drm/radeon/ni_dma.c
index 7cf96b15377f..6378e0276691 100644
--- a/drivers/gpu/drm/radeon/ni_dma.c
+++ b/drivers/gpu/drm/radeon/ni_dma.c
@@ -248,8 +248,6 @@ int cayman_dma_resume(struct radeon_device *rdev)
248 ring->wptr = 0; 248 ring->wptr = 0;
249 WREG32(DMA_RB_WPTR + reg_offset, ring->wptr << 2); 249 WREG32(DMA_RB_WPTR + reg_offset, ring->wptr << 2);
250 250
251 ring->rptr = RREG32(DMA_RB_RPTR + reg_offset) >> 2;
252
253 WREG32(DMA_RB_CNTL + reg_offset, rb_cntl | DMA_RB_ENABLE); 251 WREG32(DMA_RB_CNTL + reg_offset, rb_cntl | DMA_RB_ENABLE);
254 252
255 ring->ready = true; 253 ring->ready = true;
@@ -302,11 +300,9 @@ bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
302 mask = RADEON_RESET_DMA1; 300 mask = RADEON_RESET_DMA1;
303 301
304 if (!(reset_mask & mask)) { 302 if (!(reset_mask & mask)) {
305 radeon_ring_lockup_update(ring); 303 radeon_ring_lockup_update(rdev, ring);
306 return false; 304 return false;
307 } 305 }
308 /* force ring activities */
309 radeon_ring_force_activity(rdev, ring);
310 return radeon_ring_test_lockup(rdev, ring); 306 return radeon_ring_test_lockup(rdev, ring);
311} 307}
312 308
diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c
index ca814276b075..004c931606c4 100644
--- a/drivers/gpu/drm/radeon/ni_dpm.c
+++ b/drivers/gpu/drm/radeon/ni_dpm.c
@@ -4025,9 +4025,6 @@ static int ni_parse_power_table(struct radeon_device *rdev)
4025 power_info->pplib.ucNumStates, GFP_KERNEL); 4025 power_info->pplib.ucNumStates, GFP_KERNEL);
4026 if (!rdev->pm.dpm.ps) 4026 if (!rdev->pm.dpm.ps)
4027 return -ENOMEM; 4027 return -ENOMEM;
4028 rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
4029 rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
4030 rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
4031 4028
4032 for (i = 0; i < power_info->pplib.ucNumStates; i++) { 4029 for (i = 0; i < power_info->pplib.ucNumStates; i++) {
4033 power_state = (union pplib_power_state *) 4030 power_state = (union pplib_power_state *)
@@ -4089,6 +4086,10 @@ int ni_dpm_init(struct radeon_device *rdev)
4089 pi->min_vddc_in_table = 0; 4086 pi->min_vddc_in_table = 0;
4090 pi->max_vddc_in_table = 0; 4087 pi->max_vddc_in_table = 0;
4091 4088
4089 ret = r600_get_platform_caps(rdev);
4090 if (ret)
4091 return ret;
4092
4092 ret = ni_parse_power_table(rdev); 4093 ret = ni_parse_power_table(rdev);
4093 if (ret) 4094 if (ret)
4094 return ret; 4095 return ret;
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index ef024ce3f7cc..1690a2dc0721 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -1193,7 +1193,6 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
1193 1193
1194 WREG32(RADEON_CP_RB_CNTL, tmp); 1194 WREG32(RADEON_CP_RB_CNTL, tmp);
1195 udelay(10); 1195 udelay(10);
1196 ring->rptr = RREG32(RADEON_CP_RB_RPTR);
1197 /* Set cp mode to bus mastering & enable cp*/ 1196 /* Set cp mode to bus mastering & enable cp*/
1198 WREG32(RADEON_CP_CSQ_MODE, 1197 WREG32(RADEON_CP_CSQ_MODE,
1199 REG_SET(RADEON_INDIRECT2_START, indirect2_start) | 1198 REG_SET(RADEON_INDIRECT2_START, indirect2_start) |
@@ -2523,11 +2522,9 @@ bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
2523 2522
2524 rbbm_status = RREG32(R_000E40_RBBM_STATUS); 2523 rbbm_status = RREG32(R_000E40_RBBM_STATUS);
2525 if (!G_000E40_GUI_ACTIVE(rbbm_status)) { 2524 if (!G_000E40_GUI_ACTIVE(rbbm_status)) {
2526 radeon_ring_lockup_update(ring); 2525 radeon_ring_lockup_update(rdev, ring);
2527 return false; 2526 return false;
2528 } 2527 }
2529 /* force CP activities */
2530 radeon_ring_force_activity(rdev, ring);
2531 return radeon_ring_test_lockup(rdev, ring); 2528 return radeon_ring_test_lockup(rdev, ring);
2532} 2529}
2533 2530
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index cdbc4171fe73..0f4ab928a15a 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -1748,11 +1748,9 @@ bool r600_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
1748 if (!(reset_mask & (RADEON_RESET_GFX | 1748 if (!(reset_mask & (RADEON_RESET_GFX |
1749 RADEON_RESET_COMPUTE | 1749 RADEON_RESET_COMPUTE |
1750 RADEON_RESET_CP))) { 1750 RADEON_RESET_CP))) {
1751 radeon_ring_lockup_update(ring); 1751 radeon_ring_lockup_update(rdev, ring);
1752 return false; 1752 return false;
1753 } 1753 }
1754 /* force CP activities */
1755 radeon_ring_force_activity(rdev, ring);
1756 return radeon_ring_test_lockup(rdev, ring); 1754 return radeon_ring_test_lockup(rdev, ring);
1757} 1755}
1758 1756
@@ -2604,8 +2602,6 @@ int r600_cp_resume(struct radeon_device *rdev)
2604 WREG32(CP_RB_BASE, ring->gpu_addr >> 8); 2602 WREG32(CP_RB_BASE, ring->gpu_addr >> 8);
2605 WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); 2603 WREG32(CP_DEBUG, (1 << 27) | (1 << 28));
2606 2604
2607 ring->rptr = RREG32(CP_RB_RPTR);
2608
2609 r600_cp_start(rdev); 2605 r600_cp_start(rdev);
2610 ring->ready = true; 2606 ring->ready = true;
2611 r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, ring); 2607 r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, ring);
diff --git a/drivers/gpu/drm/radeon/r600_dma.c b/drivers/gpu/drm/radeon/r600_dma.c
index b2d4c91e6272..53fcb28f5578 100644
--- a/drivers/gpu/drm/radeon/r600_dma.c
+++ b/drivers/gpu/drm/radeon/r600_dma.c
@@ -176,8 +176,6 @@ int r600_dma_resume(struct radeon_device *rdev)
176 ring->wptr = 0; 176 ring->wptr = 0;
177 WREG32(DMA_RB_WPTR, ring->wptr << 2); 177 WREG32(DMA_RB_WPTR, ring->wptr << 2);
178 178
179 ring->rptr = RREG32(DMA_RB_RPTR) >> 2;
180
181 WREG32(DMA_RB_CNTL, rb_cntl | DMA_RB_ENABLE); 179 WREG32(DMA_RB_CNTL, rb_cntl | DMA_RB_ENABLE);
182 180
183 ring->ready = true; 181 ring->ready = true;
@@ -221,11 +219,9 @@ bool r600_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
221 u32 reset_mask = r600_gpu_check_soft_reset(rdev); 219 u32 reset_mask = r600_gpu_check_soft_reset(rdev);
222 220
223 if (!(reset_mask & RADEON_RESET_DMA)) { 221 if (!(reset_mask & RADEON_RESET_DMA)) {
224 radeon_ring_lockup_update(ring); 222 radeon_ring_lockup_update(rdev, ring);
225 return false; 223 return false;
226 } 224 }
227 /* force ring activities */
228 radeon_ring_force_activity(rdev, ring);
229 return radeon_ring_test_lockup(rdev, ring); 225 return radeon_ring_test_lockup(rdev, ring);
230} 226}
231 227
diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c
index e4cc9b314ce9..cbf7e3269f84 100644
--- a/drivers/gpu/drm/radeon/r600_dpm.c
+++ b/drivers/gpu/drm/radeon/r600_dpm.c
@@ -834,6 +834,26 @@ static int r600_parse_clk_voltage_dep_table(struct radeon_clock_voltage_dependen
834 return 0; 834 return 0;
835} 835}
836 836
837int r600_get_platform_caps(struct radeon_device *rdev)
838{
839 struct radeon_mode_info *mode_info = &rdev->mode_info;
840 union power_info *power_info;
841 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
842 u16 data_offset;
843 u8 frev, crev;
844
845 if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
846 &frev, &crev, &data_offset))
847 return -EINVAL;
848 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
849
850 rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
851 rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
852 rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
853
854 return 0;
855}
856
837/* sizeof(ATOM_PPLIB_EXTENDEDHEADER) */ 857/* sizeof(ATOM_PPLIB_EXTENDEDHEADER) */
838#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2 12 858#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2 12
839#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3 14 859#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3 14
@@ -1043,7 +1063,15 @@ int r600_parse_extended_power_table(struct radeon_device *rdev)
1043 (mode_info->atom_context->bios + data_offset + 1063 (mode_info->atom_context->bios + data_offset +
1044 le16_to_cpu(ext_hdr->usVCETableOffset) + 1 + 1064 le16_to_cpu(ext_hdr->usVCETableOffset) + 1 +
1045 1 + array->ucNumEntries * sizeof(VCEClockInfo)); 1065 1 + array->ucNumEntries * sizeof(VCEClockInfo));
1066 ATOM_PPLIB_VCE_State_Table *states =
1067 (ATOM_PPLIB_VCE_State_Table *)
1068 (mode_info->atom_context->bios + data_offset +
1069 le16_to_cpu(ext_hdr->usVCETableOffset) + 1 +
1070 1 + (array->ucNumEntries * sizeof (VCEClockInfo)) +
1071 1 + (limits->numEntries * sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record)));
1046 ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *entry; 1072 ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *entry;
1073 ATOM_PPLIB_VCE_State_Record *state_entry;
1074 VCEClockInfo *vce_clk;
1047 u32 size = limits->numEntries * 1075 u32 size = limits->numEntries *
1048 sizeof(struct radeon_vce_clock_voltage_dependency_entry); 1076 sizeof(struct radeon_vce_clock_voltage_dependency_entry);
1049 rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries = 1077 rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries =
@@ -1055,8 +1083,9 @@ int r600_parse_extended_power_table(struct radeon_device *rdev)
1055 rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.count = 1083 rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.count =
1056 limits->numEntries; 1084 limits->numEntries;
1057 entry = &limits->entries[0]; 1085 entry = &limits->entries[0];
1086 state_entry = &states->entries[0];
1058 for (i = 0; i < limits->numEntries; i++) { 1087 for (i = 0; i < limits->numEntries; i++) {
1059 VCEClockInfo *vce_clk = (VCEClockInfo *) 1088 vce_clk = (VCEClockInfo *)
1060 ((u8 *)&array->entries[0] + 1089 ((u8 *)&array->entries[0] +
1061 (entry->ucVCEClockInfoIndex * sizeof(VCEClockInfo))); 1090 (entry->ucVCEClockInfoIndex * sizeof(VCEClockInfo)));
1062 rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].evclk = 1091 rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].evclk =
@@ -1068,6 +1097,23 @@ int r600_parse_extended_power_table(struct radeon_device *rdev)
1068 entry = (ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *) 1097 entry = (ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *)
1069 ((u8 *)entry + sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record)); 1098 ((u8 *)entry + sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record));
1070 } 1099 }
1100 for (i = 0; i < states->numEntries; i++) {
1101 if (i >= RADEON_MAX_VCE_LEVELS)
1102 break;
1103 vce_clk = (VCEClockInfo *)
1104 ((u8 *)&array->entries[0] +
1105 (state_entry->ucVCEClockInfoIndex * sizeof(VCEClockInfo)));
1106 rdev->pm.dpm.vce_states[i].evclk =
1107 le16_to_cpu(vce_clk->usEVClkLow) | (vce_clk->ucEVClkHigh << 16);
1108 rdev->pm.dpm.vce_states[i].ecclk =
1109 le16_to_cpu(vce_clk->usECClkLow) | (vce_clk->ucECClkHigh << 16);
1110 rdev->pm.dpm.vce_states[i].clk_idx =
1111 state_entry->ucClockInfoIndex & 0x3f;
1112 rdev->pm.dpm.vce_states[i].pstate =
1113 (state_entry->ucClockInfoIndex & 0xc0) >> 6;
1114 state_entry = (ATOM_PPLIB_VCE_State_Record *)
1115 ((u8 *)state_entry + sizeof(ATOM_PPLIB_VCE_State_Record));
1116 }
1071 } 1117 }
1072 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3) && 1118 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3) &&
1073 ext_hdr->usUVDTableOffset) { 1119 ext_hdr->usUVDTableOffset) {
diff --git a/drivers/gpu/drm/radeon/r600_dpm.h b/drivers/gpu/drm/radeon/r600_dpm.h
index 07eab2b04e81..46b9d2a03018 100644
--- a/drivers/gpu/drm/radeon/r600_dpm.h
+++ b/drivers/gpu/drm/radeon/r600_dpm.h
@@ -215,6 +215,8 @@ void r600_stop_dpm(struct radeon_device *rdev);
215 215
216bool r600_is_internal_thermal_sensor(enum radeon_int_thermal_type sensor); 216bool r600_is_internal_thermal_sensor(enum radeon_int_thermal_type sensor);
217 217
218int r600_get_platform_caps(struct radeon_device *rdev);
219
218int r600_parse_extended_power_table(struct radeon_device *rdev); 220int r600_parse_extended_power_table(struct radeon_device *rdev);
219void r600_free_extended_power_table(struct radeon_device *rdev); 221void r600_free_extended_power_table(struct radeon_device *rdev);
220 222
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 024db37b1832..4581df193932 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -113,19 +113,16 @@ extern int radeon_hard_reset;
113#define RADEONFB_CONN_LIMIT 4 113#define RADEONFB_CONN_LIMIT 4
114#define RADEON_BIOS_NUM_SCRATCH 8 114#define RADEON_BIOS_NUM_SCRATCH 8
115 115
116/* max number of rings */
117#define RADEON_NUM_RINGS 6
118
119/* fence seq are set to this number when signaled */ 116/* fence seq are set to this number when signaled */
120#define RADEON_FENCE_SIGNALED_SEQ 0LL 117#define RADEON_FENCE_SIGNALED_SEQ 0LL
121 118
122/* internal ring indices */ 119/* internal ring indices */
123/* r1xx+ has gfx CP ring */ 120/* r1xx+ has gfx CP ring */
124#define RADEON_RING_TYPE_GFX_INDEX 0 121#define RADEON_RING_TYPE_GFX_INDEX 0
125 122
126/* cayman has 2 compute CP rings */ 123/* cayman has 2 compute CP rings */
127#define CAYMAN_RING_TYPE_CP1_INDEX 1 124#define CAYMAN_RING_TYPE_CP1_INDEX 1
128#define CAYMAN_RING_TYPE_CP2_INDEX 2 125#define CAYMAN_RING_TYPE_CP2_INDEX 2
129 126
130/* R600+ has an async dma ring */ 127/* R600+ has an async dma ring */
131#define R600_RING_TYPE_DMA_INDEX 3 128#define R600_RING_TYPE_DMA_INDEX 3
@@ -133,7 +130,17 @@ extern int radeon_hard_reset;
133#define CAYMAN_RING_TYPE_DMA1_INDEX 4 130#define CAYMAN_RING_TYPE_DMA1_INDEX 4
134 131
135/* R600+ */ 132/* R600+ */
136#define R600_RING_TYPE_UVD_INDEX 5 133#define R600_RING_TYPE_UVD_INDEX 5
134
135/* TN+ */
136#define TN_RING_TYPE_VCE1_INDEX 6
137#define TN_RING_TYPE_VCE2_INDEX 7
138
139/* max number of rings */
140#define RADEON_NUM_RINGS 8
141
142/* number of hw syncs before falling back on blocking */
143#define RADEON_NUM_SYNCS 4
137 144
138/* number of hw syncs before falling back on blocking */ 145/* number of hw syncs before falling back on blocking */
139#define RADEON_NUM_SYNCS 4 146#define RADEON_NUM_SYNCS 4
@@ -789,7 +796,6 @@ struct radeon_ib {
789struct radeon_ring { 796struct radeon_ring {
790 struct radeon_bo *ring_obj; 797 struct radeon_bo *ring_obj;
791 volatile uint32_t *ring; 798 volatile uint32_t *ring;
792 unsigned rptr;
793 unsigned rptr_offs; 799 unsigned rptr_offs;
794 unsigned rptr_save_reg; 800 unsigned rptr_save_reg;
795 u64 next_rptr_gpu_addr; 801 u64 next_rptr_gpu_addr;
@@ -953,8 +959,8 @@ void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *c
953void radeon_ring_undo(struct radeon_ring *ring); 959void radeon_ring_undo(struct radeon_ring *ring);
954void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *cp); 960void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *cp);
955int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); 961int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp);
956void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring); 962void radeon_ring_lockup_update(struct radeon_device *rdev,
957void radeon_ring_lockup_update(struct radeon_ring *ring); 963 struct radeon_ring *ring);
958bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring); 964bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
959unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring, 965unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring,
960 uint32_t **data); 966 uint32_t **data);
@@ -1255,6 +1261,17 @@ enum radeon_dpm_event_src {
1255 RADEON_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL = 4 1261 RADEON_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL = 4
1256}; 1262};
1257 1263
1264#define RADEON_MAX_VCE_LEVELS 6
1265
1266enum radeon_vce_level {
1267 RADEON_VCE_LEVEL_AC_ALL = 0, /* AC, All cases */
1268 RADEON_VCE_LEVEL_DC_EE = 1, /* DC, entropy encoding */
1269 RADEON_VCE_LEVEL_DC_LL_LOW = 2, /* DC, low latency queue, res <= 720 */
1270 RADEON_VCE_LEVEL_DC_LL_HIGH = 3, /* DC, low latency queue, 1080 >= res > 720 */
1271 RADEON_VCE_LEVEL_DC_GP_LOW = 4, /* DC, general purpose queue, res <= 720 */
1272 RADEON_VCE_LEVEL_DC_GP_HIGH = 5, /* DC, general purpose queue, 1080 >= res > 720 */
1273};
1274
1258struct radeon_ps { 1275struct radeon_ps {
1259 u32 caps; /* vbios flags */ 1276 u32 caps; /* vbios flags */
1260 u32 class; /* vbios flags */ 1277 u32 class; /* vbios flags */
@@ -1265,6 +1282,8 @@ struct radeon_ps {
1265 /* VCE clocks */ 1282 /* VCE clocks */
1266 u32 evclk; 1283 u32 evclk;
1267 u32 ecclk; 1284 u32 ecclk;
1285 bool vce_active;
1286 enum radeon_vce_level vce_level;
1268 /* asic priv */ 1287 /* asic priv */
1269 void *ps_priv; 1288 void *ps_priv;
1270}; 1289};
@@ -1439,6 +1458,17 @@ enum radeon_dpm_forced_level {
1439 RADEON_DPM_FORCED_LEVEL_HIGH = 2, 1458 RADEON_DPM_FORCED_LEVEL_HIGH = 2,
1440}; 1459};
1441 1460
1461struct radeon_vce_state {
1462 /* vce clocks */
1463 u32 evclk;
1464 u32 ecclk;
1465 /* gpu clocks */
1466 u32 sclk;
1467 u32 mclk;
1468 u8 clk_idx;
1469 u8 pstate;
1470};
1471
1442struct radeon_dpm { 1472struct radeon_dpm {
1443 struct radeon_ps *ps; 1473 struct radeon_ps *ps;
1444 /* number of valid power states */ 1474 /* number of valid power states */
@@ -1451,6 +1481,9 @@ struct radeon_dpm {
1451 struct radeon_ps *boot_ps; 1481 struct radeon_ps *boot_ps;
1452 /* default uvd power state */ 1482 /* default uvd power state */
1453 struct radeon_ps *uvd_ps; 1483 struct radeon_ps *uvd_ps;
1484 /* vce requirements */
1485 struct radeon_vce_state vce_states[RADEON_MAX_VCE_LEVELS];
1486 enum radeon_vce_level vce_level;
1454 enum radeon_pm_state_type state; 1487 enum radeon_pm_state_type state;
1455 enum radeon_pm_state_type user_state; 1488 enum radeon_pm_state_type user_state;
1456 u32 platform_caps; 1489 u32 platform_caps;
@@ -1476,6 +1509,7 @@ struct radeon_dpm {
1476 /* special states active */ 1509 /* special states active */
1477 bool thermal_active; 1510 bool thermal_active;
1478 bool uvd_active; 1511 bool uvd_active;
1512 bool vce_active;
1479 /* thermal handling */ 1513 /* thermal handling */
1480 struct radeon_dpm_thermal thermal; 1514 struct radeon_dpm_thermal thermal;
1481 /* forced levels */ 1515 /* forced levels */
@@ -1486,6 +1520,7 @@ struct radeon_dpm {
1486}; 1520};
1487 1521
1488void radeon_dpm_enable_uvd(struct radeon_device *rdev, bool enable); 1522void radeon_dpm_enable_uvd(struct radeon_device *rdev, bool enable);
1523void radeon_dpm_enable_vce(struct radeon_device *rdev, bool enable);
1489 1524
1490struct radeon_pm { 1525struct radeon_pm {
1491 struct mutex mutex; 1526 struct mutex mutex;
@@ -1591,6 +1626,46 @@ int radeon_uvd_calc_upll_dividers(struct radeon_device *rdev,
1591int radeon_uvd_send_upll_ctlreq(struct radeon_device *rdev, 1626int radeon_uvd_send_upll_ctlreq(struct radeon_device *rdev,
1592 unsigned cg_upll_func_cntl); 1627 unsigned cg_upll_func_cntl);
1593 1628
1629/*
1630 * VCE
1631 */
1632#define RADEON_MAX_VCE_HANDLES 16
1633#define RADEON_VCE_STACK_SIZE (1024*1024)
1634#define RADEON_VCE_HEAP_SIZE (4*1024*1024)
1635
1636struct radeon_vce {
1637 struct radeon_bo *vcpu_bo;
1638 void *cpu_addr;
1639 uint64_t gpu_addr;
1640 unsigned fw_version;
1641 unsigned fb_version;
1642 atomic_t handles[RADEON_MAX_VCE_HANDLES];
1643 struct drm_file *filp[RADEON_MAX_VCE_HANDLES];
1644 struct delayed_work idle_work;
1645};
1646
1647int radeon_vce_init(struct radeon_device *rdev);
1648void radeon_vce_fini(struct radeon_device *rdev);
1649int radeon_vce_suspend(struct radeon_device *rdev);
1650int radeon_vce_resume(struct radeon_device *rdev);
1651int radeon_vce_get_create_msg(struct radeon_device *rdev, int ring,
1652 uint32_t handle, struct radeon_fence **fence);
1653int radeon_vce_get_destroy_msg(struct radeon_device *rdev, int ring,
1654 uint32_t handle, struct radeon_fence **fence);
1655void radeon_vce_free_handles(struct radeon_device *rdev, struct drm_file *filp);
1656void radeon_vce_note_usage(struct radeon_device *rdev);
1657int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi);
1658int radeon_vce_cs_parse(struct radeon_cs_parser *p);
1659bool radeon_vce_semaphore_emit(struct radeon_device *rdev,
1660 struct radeon_ring *ring,
1661 struct radeon_semaphore *semaphore,
1662 bool emit_wait);
1663void radeon_vce_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
1664void radeon_vce_fence_emit(struct radeon_device *rdev,
1665 struct radeon_fence *fence);
1666int radeon_vce_ring_test(struct radeon_device *rdev, struct radeon_ring *ring);
1667int radeon_vce_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
1668
1594struct r600_audio_pin { 1669struct r600_audio_pin {
1595 int channels; 1670 int channels;
1596 int rate; 1671 int rate;
@@ -1780,6 +1855,7 @@ struct radeon_asic {
1780 void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes); 1855 void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes);
1781 void (*set_clock_gating)(struct radeon_device *rdev, int enable); 1856 void (*set_clock_gating)(struct radeon_device *rdev, int enable);
1782 int (*set_uvd_clocks)(struct radeon_device *rdev, u32 vclk, u32 dclk); 1857 int (*set_uvd_clocks)(struct radeon_device *rdev, u32 vclk, u32 dclk);
1858 int (*set_vce_clocks)(struct radeon_device *rdev, u32 evclk, u32 ecclk);
1783 int (*get_temperature)(struct radeon_device *rdev); 1859 int (*get_temperature)(struct radeon_device *rdev);
1784 } pm; 1860 } pm;
1785 /* dynamic power management */ 1861 /* dynamic power management */
@@ -2186,6 +2262,7 @@ struct radeon_device {
2186 struct radeon_gem gem; 2262 struct radeon_gem gem;
2187 struct radeon_pm pm; 2263 struct radeon_pm pm;
2188 struct radeon_uvd uvd; 2264 struct radeon_uvd uvd;
2265 struct radeon_vce vce;
2189 uint32_t bios_scratch[RADEON_BIOS_NUM_SCRATCH]; 2266 uint32_t bios_scratch[RADEON_BIOS_NUM_SCRATCH];
2190 struct radeon_wb wb; 2267 struct radeon_wb wb;
2191 struct radeon_dummy_page dummy_page; 2268 struct radeon_dummy_page dummy_page;
@@ -2205,6 +2282,7 @@ struct radeon_device {
2205 const struct firmware *sdma_fw; /* CIK SDMA firmware */ 2282 const struct firmware *sdma_fw; /* CIK SDMA firmware */
2206 const struct firmware *smc_fw; /* SMC firmware */ 2283 const struct firmware *smc_fw; /* SMC firmware */
2207 const struct firmware *uvd_fw; /* UVD firmware */ 2284 const struct firmware *uvd_fw; /* UVD firmware */
2285 const struct firmware *vce_fw; /* VCE firmware */
2208 struct r600_vram_scratch vram_scratch; 2286 struct r600_vram_scratch vram_scratch;
2209 int msi_enabled; /* msi enabled */ 2287 int msi_enabled; /* msi enabled */
2210 struct r600_ih ih; /* r6/700 interrupt ring */ 2288 struct r600_ih ih; /* r6/700 interrupt ring */
@@ -2639,6 +2717,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
2639#define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->pm.set_pcie_lanes((rdev), (l)) 2717#define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->pm.set_pcie_lanes((rdev), (l))
2640#define radeon_set_clock_gating(rdev, e) (rdev)->asic->pm.set_clock_gating((rdev), (e)) 2718#define radeon_set_clock_gating(rdev, e) (rdev)->asic->pm.set_clock_gating((rdev), (e))
2641#define radeon_set_uvd_clocks(rdev, v, d) (rdev)->asic->pm.set_uvd_clocks((rdev), (v), (d)) 2719#define radeon_set_uvd_clocks(rdev, v, d) (rdev)->asic->pm.set_uvd_clocks((rdev), (v), (d))
2720#define radeon_set_vce_clocks(rdev, ev, ec) (rdev)->asic->pm.set_vce_clocks((rdev), (ev), (ec))
2642#define radeon_get_temperature(rdev) (rdev)->asic->pm.get_temperature((rdev)) 2721#define radeon_get_temperature(rdev) (rdev)->asic->pm.get_temperature((rdev))
2643#define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->surface.set_reg((rdev), (r), (f), (p), (o), (s))) 2722#define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->surface.set_reg((rdev), (r), (f), (p), (o), (s)))
2644#define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->surface.clear_reg((rdev), (r))) 2723#define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->surface.clear_reg((rdev), (r)))
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index dda02bfc10a4..b8a24a75d4ff 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1987,6 +1987,19 @@ static struct radeon_asic_ring ci_dma_ring = {
1987 .set_wptr = &cik_sdma_set_wptr, 1987 .set_wptr = &cik_sdma_set_wptr,
1988}; 1988};
1989 1989
1990static struct radeon_asic_ring ci_vce_ring = {
1991 .ib_execute = &radeon_vce_ib_execute,
1992 .emit_fence = &radeon_vce_fence_emit,
1993 .emit_semaphore = &radeon_vce_semaphore_emit,
1994 .cs_parse = &radeon_vce_cs_parse,
1995 .ring_test = &radeon_vce_ring_test,
1996 .ib_test = &radeon_vce_ib_test,
1997 .is_lockup = &radeon_ring_test_lockup,
1998 .get_rptr = &vce_v1_0_get_rptr,
1999 .get_wptr = &vce_v1_0_get_wptr,
2000 .set_wptr = &vce_v1_0_set_wptr,
2001};
2002
1990static struct radeon_asic ci_asic = { 2003static struct radeon_asic ci_asic = {
1991 .init = &cik_init, 2004 .init = &cik_init,
1992 .fini = &cik_fini, 2005 .fini = &cik_fini,
@@ -2015,6 +2028,8 @@ static struct radeon_asic ci_asic = {
2015 [R600_RING_TYPE_DMA_INDEX] = &ci_dma_ring, 2028 [R600_RING_TYPE_DMA_INDEX] = &ci_dma_ring,
2016 [CAYMAN_RING_TYPE_DMA1_INDEX] = &ci_dma_ring, 2029 [CAYMAN_RING_TYPE_DMA1_INDEX] = &ci_dma_ring,
2017 [R600_RING_TYPE_UVD_INDEX] = &cayman_uvd_ring, 2030 [R600_RING_TYPE_UVD_INDEX] = &cayman_uvd_ring,
2031 [TN_RING_TYPE_VCE1_INDEX] = &ci_vce_ring,
2032 [TN_RING_TYPE_VCE2_INDEX] = &ci_vce_ring,
2018 }, 2033 },
2019 .irq = { 2034 .irq = {
2020 .set = &cik_irq_set, 2035 .set = &cik_irq_set,
@@ -2061,6 +2076,7 @@ static struct radeon_asic ci_asic = {
2061 .set_pcie_lanes = NULL, 2076 .set_pcie_lanes = NULL,
2062 .set_clock_gating = NULL, 2077 .set_clock_gating = NULL,
2063 .set_uvd_clocks = &cik_set_uvd_clocks, 2078 .set_uvd_clocks = &cik_set_uvd_clocks,
2079 .set_vce_clocks = &cik_set_vce_clocks,
2064 .get_temperature = &ci_get_temp, 2080 .get_temperature = &ci_get_temp,
2065 }, 2081 },
2066 .dpm = { 2082 .dpm = {
@@ -2117,6 +2133,8 @@ static struct radeon_asic kv_asic = {
2117 [R600_RING_TYPE_DMA_INDEX] = &ci_dma_ring, 2133 [R600_RING_TYPE_DMA_INDEX] = &ci_dma_ring,
2118 [CAYMAN_RING_TYPE_DMA1_INDEX] = &ci_dma_ring, 2134 [CAYMAN_RING_TYPE_DMA1_INDEX] = &ci_dma_ring,
2119 [R600_RING_TYPE_UVD_INDEX] = &cayman_uvd_ring, 2135 [R600_RING_TYPE_UVD_INDEX] = &cayman_uvd_ring,
2136 [TN_RING_TYPE_VCE1_INDEX] = &ci_vce_ring,
2137 [TN_RING_TYPE_VCE2_INDEX] = &ci_vce_ring,
2120 }, 2138 },
2121 .irq = { 2139 .irq = {
2122 .set = &cik_irq_set, 2140 .set = &cik_irq_set,
@@ -2163,6 +2181,7 @@ static struct radeon_asic kv_asic = {
2163 .set_pcie_lanes = NULL, 2181 .set_pcie_lanes = NULL,
2164 .set_clock_gating = NULL, 2182 .set_clock_gating = NULL,
2165 .set_uvd_clocks = &cik_set_uvd_clocks, 2183 .set_uvd_clocks = &cik_set_uvd_clocks,
2184 .set_vce_clocks = &cik_set_vce_clocks,
2166 .get_temperature = &kv_get_temp, 2185 .get_temperature = &kv_get_temp,
2167 }, 2186 },
2168 .dpm = { 2187 .dpm = {
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index ae637cfda783..3d55a3a39e82 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -717,6 +717,7 @@ u32 cik_get_xclk(struct radeon_device *rdev);
717uint32_t cik_pciep_rreg(struct radeon_device *rdev, uint32_t reg); 717uint32_t cik_pciep_rreg(struct radeon_device *rdev, uint32_t reg);
718void cik_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); 718void cik_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
719int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); 719int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
720int cik_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk);
720void cik_sdma_fence_ring_emit(struct radeon_device *rdev, 721void cik_sdma_fence_ring_emit(struct radeon_device *rdev,
721 struct radeon_fence *fence); 722 struct radeon_fence *fence);
722bool cik_sdma_semaphore_ring_emit(struct radeon_device *rdev, 723bool cik_sdma_semaphore_ring_emit(struct radeon_device *rdev,
@@ -863,4 +864,17 @@ bool uvd_v3_1_semaphore_emit(struct radeon_device *rdev,
863/* uvd v4.2 */ 864/* uvd v4.2 */
864int uvd_v4_2_resume(struct radeon_device *rdev); 865int uvd_v4_2_resume(struct radeon_device *rdev);
865 866
867/* vce v1.0 */
868uint32_t vce_v1_0_get_rptr(struct radeon_device *rdev,
869 struct radeon_ring *ring);
870uint32_t vce_v1_0_get_wptr(struct radeon_device *rdev,
871 struct radeon_ring *ring);
872void vce_v1_0_set_wptr(struct radeon_device *rdev,
873 struct radeon_ring *ring);
874int vce_v1_0_init(struct radeon_device *rdev);
875int vce_v1_0_start(struct radeon_device *rdev);
876
877/* vce v2.0 */
878int vce_v2_0_resume(struct radeon_device *rdev);
879
866#endif 880#endif
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index dfb5a1db87d4..f28a8d82fa19 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -147,6 +147,10 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority
147 case RADEON_CS_RING_UVD: 147 case RADEON_CS_RING_UVD:
148 p->ring = R600_RING_TYPE_UVD_INDEX; 148 p->ring = R600_RING_TYPE_UVD_INDEX;
149 break; 149 break;
150 case RADEON_CS_RING_VCE:
151 /* TODO: only use the low priority ring for now */
152 p->ring = TN_RING_TYPE_VCE1_INDEX;
153 break;
150 } 154 }
151 return 0; 155 return 0;
152} 156}
@@ -343,6 +347,9 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev,
343 347
344 if (parser->ring == R600_RING_TYPE_UVD_INDEX) 348 if (parser->ring == R600_RING_TYPE_UVD_INDEX)
345 radeon_uvd_note_usage(rdev); 349 radeon_uvd_note_usage(rdev);
350 else if ((parser->ring == TN_RING_TYPE_VCE1_INDEX) ||
351 (parser->ring == TN_RING_TYPE_VCE2_INDEX))
352 radeon_vce_note_usage(rdev);
346 353
347 radeon_cs_sync_rings(parser); 354 radeon_cs_sync_rings(parser);
348 r = radeon_ib_schedule(rdev, &parser->ib, NULL); 355 r = radeon_ib_schedule(rdev, &parser->ib, NULL);
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 114d1672d616..baff98be65b1 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -433,6 +433,9 @@ static int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file
433 case RADEON_CS_RING_UVD: 433 case RADEON_CS_RING_UVD:
434 *value = rdev->ring[R600_RING_TYPE_UVD_INDEX].ready; 434 *value = rdev->ring[R600_RING_TYPE_UVD_INDEX].ready;
435 break; 435 break;
436 case RADEON_CS_RING_VCE:
437 *value = rdev->ring[TN_RING_TYPE_VCE1_INDEX].ready;
438 break;
436 default: 439 default:
437 return -EINVAL; 440 return -EINVAL;
438 } 441 }
@@ -477,6 +480,12 @@ static int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file
477 else 480 else
478 *value = rdev->pm.default_sclk * 10; 481 *value = rdev->pm.default_sclk * 10;
479 break; 482 break;
483 case RADEON_INFO_VCE_FW_VERSION:
484 *value = rdev->vce.fw_version;
485 break;
486 case RADEON_INFO_VCE_FB_VERSION:
487 *value = rdev->vce.fb_version;
488 break;
480 default: 489 default:
481 DRM_DEBUG_KMS("Invalid request %d\n", info->request); 490 DRM_DEBUG_KMS("Invalid request %d\n", info->request);
482 return -EINVAL; 491 return -EINVAL;
@@ -610,6 +619,7 @@ void radeon_driver_preclose_kms(struct drm_device *dev,
610 if (rdev->cmask_filp == file_priv) 619 if (rdev->cmask_filp == file_priv)
611 rdev->cmask_filp = NULL; 620 rdev->cmask_filp = NULL;
612 radeon_uvd_free_handles(rdev, file_priv); 621 radeon_uvd_free_handles(rdev, file_priv);
622 radeon_vce_free_handles(rdev, file_priv);
613} 623}
614 624
615/* 625/*
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 8e8153e471c2..4ad9af9fc517 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -826,6 +826,9 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev)
826 826
827 /* no need to reprogram if nothing changed unless we are on BTC+ */ 827 /* no need to reprogram if nothing changed unless we are on BTC+ */
828 if (rdev->pm.dpm.current_ps == rdev->pm.dpm.requested_ps) { 828 if (rdev->pm.dpm.current_ps == rdev->pm.dpm.requested_ps) {
829 /* vce just modifies an existing state so force a change */
830 if (ps->vce_active != rdev->pm.dpm.vce_active)
831 goto force;
829 if ((rdev->family < CHIP_BARTS) || (rdev->flags & RADEON_IS_IGP)) { 832 if ((rdev->family < CHIP_BARTS) || (rdev->flags & RADEON_IS_IGP)) {
830 /* for pre-BTC and APUs if the num crtcs changed but state is the same, 833 /* for pre-BTC and APUs if the num crtcs changed but state is the same,
831 * all we need to do is update the display configuration. 834 * all we need to do is update the display configuration.
@@ -862,16 +865,21 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev)
862 } 865 }
863 } 866 }
864 867
868force:
865 if (radeon_dpm == 1) { 869 if (radeon_dpm == 1) {
866 printk("switching from power state:\n"); 870 printk("switching from power state:\n");
867 radeon_dpm_print_power_state(rdev, rdev->pm.dpm.current_ps); 871 radeon_dpm_print_power_state(rdev, rdev->pm.dpm.current_ps);
868 printk("switching to power state:\n"); 872 printk("switching to power state:\n");
869 radeon_dpm_print_power_state(rdev, rdev->pm.dpm.requested_ps); 873 radeon_dpm_print_power_state(rdev, rdev->pm.dpm.requested_ps);
870 } 874 }
875
871 mutex_lock(&rdev->ddev->struct_mutex); 876 mutex_lock(&rdev->ddev->struct_mutex);
872 down_write(&rdev->pm.mclk_lock); 877 down_write(&rdev->pm.mclk_lock);
873 mutex_lock(&rdev->ring_lock); 878 mutex_lock(&rdev->ring_lock);
874 879
880 /* update whether vce is active */
881 ps->vce_active = rdev->pm.dpm.vce_active;
882
875 ret = radeon_dpm_pre_set_power_state(rdev); 883 ret = radeon_dpm_pre_set_power_state(rdev);
876 if (ret) 884 if (ret)
877 goto done; 885 goto done;
@@ -960,6 +968,23 @@ void radeon_dpm_enable_uvd(struct radeon_device *rdev, bool enable)
960 } 968 }
961} 969}
962 970
971void radeon_dpm_enable_vce(struct radeon_device *rdev, bool enable)
972{
973 if (enable) {
974 mutex_lock(&rdev->pm.mutex);
975 rdev->pm.dpm.vce_active = true;
976 /* XXX select vce level based on ring/task */
977 rdev->pm.dpm.vce_level = RADEON_VCE_LEVEL_AC_ALL;
978 mutex_unlock(&rdev->pm.mutex);
979 } else {
980 mutex_lock(&rdev->pm.mutex);
981 rdev->pm.dpm.vce_active = false;
982 mutex_unlock(&rdev->pm.mutex);
983 }
984
985 radeon_pm_compute_clocks(rdev);
986}
987
963static void radeon_pm_suspend_old(struct radeon_device *rdev) 988static void radeon_pm_suspend_old(struct radeon_device *rdev)
964{ 989{
965 mutex_lock(&rdev->pm.mutex); 990 mutex_lock(&rdev->pm.mutex);
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index 15e44a7281ab..b14c86d57607 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -342,13 +342,17 @@ bool radeon_ring_supports_scratch_reg(struct radeon_device *rdev,
342 */ 342 */
343void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring) 343void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring)
344{ 344{
345 ring->rptr = radeon_ring_get_rptr(rdev, ring); 345 uint32_t rptr = radeon_ring_get_rptr(rdev, ring);
346
346 /* This works because ring_size is a power of 2 */ 347 /* This works because ring_size is a power of 2 */
347 ring->ring_free_dw = (ring->rptr + (ring->ring_size / 4)); 348 ring->ring_free_dw = rptr + (ring->ring_size / 4);
348 ring->ring_free_dw -= ring->wptr; 349 ring->ring_free_dw -= ring->wptr;
349 ring->ring_free_dw &= ring->ptr_mask; 350 ring->ring_free_dw &= ring->ptr_mask;
350 if (!ring->ring_free_dw) { 351 if (!ring->ring_free_dw) {
352 /* this is an empty ring */
351 ring->ring_free_dw = ring->ring_size / 4; 353 ring->ring_free_dw = ring->ring_size / 4;
354 /* update lockup info to avoid false positive */
355 radeon_ring_lockup_update(rdev, ring);
352 } 356 }
353} 357}
354 358
@@ -372,12 +376,6 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsi
372 /* Align requested size with padding so unlock_commit can 376 /* Align requested size with padding so unlock_commit can
373 * pad safely */ 377 * pad safely */
374 radeon_ring_free_size(rdev, ring); 378 radeon_ring_free_size(rdev, ring);
375 if (ring->ring_free_dw == (ring->ring_size / 4)) {
376 /* This is an empty ring update lockup info to avoid
377 * false positive.
378 */
379 radeon_ring_lockup_update(ring);
380 }
381 ndw = (ndw + ring->align_mask) & ~ring->align_mask; 379 ndw = (ndw + ring->align_mask) & ~ring->align_mask;
382 while (ndw > (ring->ring_free_dw - 1)) { 380 while (ndw > (ring->ring_free_dw - 1)) {
383 radeon_ring_free_size(rdev, ring); 381 radeon_ring_free_size(rdev, ring);
@@ -478,38 +476,16 @@ void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *rin
478} 476}
479 477
480/** 478/**
481 * radeon_ring_force_activity - add some nop packets to the ring
482 *
483 * @rdev: radeon_device pointer
484 * @ring: radeon_ring structure holding ring information
485 *
486 * Add some nop packets to the ring to force activity (all asics).
487 * Used for lockup detection to see if the rptr is advancing.
488 */
489void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring)
490{
491 int r;
492
493 radeon_ring_free_size(rdev, ring);
494 if (ring->rptr == ring->wptr) {
495 r = radeon_ring_alloc(rdev, ring, 1);
496 if (!r) {
497 radeon_ring_write(ring, ring->nop);
498 radeon_ring_commit(rdev, ring);
499 }
500 }
501}
502
503/**
504 * radeon_ring_lockup_update - update lockup variables 479 * radeon_ring_lockup_update - update lockup variables
505 * 480 *
506 * @ring: radeon_ring structure holding ring information 481 * @ring: radeon_ring structure holding ring information
507 * 482 *
508 * Update the last rptr value and timestamp (all asics). 483 * Update the last rptr value and timestamp (all asics).
509 */ 484 */
510void radeon_ring_lockup_update(struct radeon_ring *ring) 485void radeon_ring_lockup_update(struct radeon_device *rdev,
486 struct radeon_ring *ring)
511{ 487{
512 ring->last_rptr = ring->rptr; 488 ring->last_rptr = radeon_ring_get_rptr(rdev, ring);
513 ring->last_activity = jiffies; 489 ring->last_activity = jiffies;
514} 490}
515 491
@@ -518,35 +494,21 @@ void radeon_ring_lockup_update(struct radeon_ring *ring)
518 * @rdev: radeon device structure 494 * @rdev: radeon device structure
519 * @ring: radeon_ring structure holding ring information 495 * @ring: radeon_ring structure holding ring information
520 * 496 *
521 * We don't need to initialize the lockup tracking information as we will either 497 */
522 * have CP rptr to a different value of jiffies wrap around which will force
523 * initialization of the lockup tracking informations.
524 *
525 * A possible false positivie is if we get call after while and last_cp_rptr ==
526 * the current CP rptr, even if it's unlikely it might happen. To avoid this
527 * if the elapsed time since last call is bigger than 2 second than we return
528 * false and update the tracking information. Due to this the caller must call
529 * radeon_ring_test_lockup several time in less than 2sec for lockup to be reported
530 * the fencing code should be cautious about that.
531 *
532 * Caller should write to the ring to force CP to do something so we don't get
533 * false positive when CP is just gived nothing to do.
534 *
535 **/
536bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring) 498bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
537{ 499{
500 uint32_t rptr = radeon_ring_get_rptr(rdev, ring);
538 unsigned long cjiffies, elapsed; 501 unsigned long cjiffies, elapsed;
539 502
540 cjiffies = jiffies; 503 cjiffies = jiffies;
541 if (!time_after(cjiffies, ring->last_activity)) { 504 if (!time_after(cjiffies, ring->last_activity)) {
542 /* likely a wrap around */ 505 /* likely a wrap around */
543 radeon_ring_lockup_update(ring); 506 radeon_ring_lockup_update(rdev, ring);
544 return false; 507 return false;
545 } 508 }
546 ring->rptr = radeon_ring_get_rptr(rdev, ring); 509 if (rptr != ring->last_rptr) {
547 if (ring->rptr != ring->last_rptr) {
548 /* CP is still working no lockup */ 510 /* CP is still working no lockup */
549 radeon_ring_lockup_update(ring); 511 radeon_ring_lockup_update(rdev, ring);
550 return false; 512 return false;
551 } 513 }
552 elapsed = jiffies_to_msecs(cjiffies - ring->last_activity); 514 elapsed = jiffies_to_msecs(cjiffies - ring->last_activity);
@@ -709,7 +671,7 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig
709 if (radeon_debugfs_ring_init(rdev, ring)) { 671 if (radeon_debugfs_ring_init(rdev, ring)) {
710 DRM_ERROR("Failed to register debugfs file for rings !\n"); 672 DRM_ERROR("Failed to register debugfs file for rings !\n");
711 } 673 }
712 radeon_ring_lockup_update(ring); 674 radeon_ring_lockup_update(rdev, ring);
713 return 0; 675 return 0;
714} 676}
715 677
@@ -780,8 +742,6 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data)
780 742
781 seq_printf(m, "driver's copy of the wptr: 0x%08x [%5d]\n", 743 seq_printf(m, "driver's copy of the wptr: 0x%08x [%5d]\n",
782 ring->wptr, ring->wptr); 744 ring->wptr, ring->wptr);
783 seq_printf(m, "driver's copy of the rptr: 0x%08x [%5d]\n",
784 ring->rptr, ring->rptr);
785 seq_printf(m, "last semaphore signal addr : 0x%016llx\n", 745 seq_printf(m, "last semaphore signal addr : 0x%016llx\n",
786 ring->last_semaphore_signal_addr); 746 ring->last_semaphore_signal_addr);
787 seq_printf(m, "last semaphore wait addr : 0x%016llx\n", 747 seq_printf(m, "last semaphore wait addr : 0x%016llx\n",
@@ -814,6 +774,8 @@ static int cayman_cp2_index = CAYMAN_RING_TYPE_CP2_INDEX;
814static int radeon_dma1_index = R600_RING_TYPE_DMA_INDEX; 774static int radeon_dma1_index = R600_RING_TYPE_DMA_INDEX;
815static int radeon_dma2_index = CAYMAN_RING_TYPE_DMA1_INDEX; 775static int radeon_dma2_index = CAYMAN_RING_TYPE_DMA1_INDEX;
816static int r600_uvd_index = R600_RING_TYPE_UVD_INDEX; 776static int r600_uvd_index = R600_RING_TYPE_UVD_INDEX;
777static int si_vce1_index = TN_RING_TYPE_VCE1_INDEX;
778static int si_vce2_index = TN_RING_TYPE_VCE2_INDEX;
817 779
818static struct drm_info_list radeon_debugfs_ring_info_list[] = { 780static struct drm_info_list radeon_debugfs_ring_info_list[] = {
819 {"radeon_ring_gfx", radeon_debugfs_ring_info, 0, &radeon_gfx_index}, 781 {"radeon_ring_gfx", radeon_debugfs_ring_info, 0, &radeon_gfx_index},
@@ -822,6 +784,8 @@ static struct drm_info_list radeon_debugfs_ring_info_list[] = {
822 {"radeon_ring_dma1", radeon_debugfs_ring_info, 0, &radeon_dma1_index}, 784 {"radeon_ring_dma1", radeon_debugfs_ring_info, 0, &radeon_dma1_index},
823 {"radeon_ring_dma2", radeon_debugfs_ring_info, 0, &radeon_dma2_index}, 785 {"radeon_ring_dma2", radeon_debugfs_ring_info, 0, &radeon_dma2_index},
824 {"radeon_ring_uvd", radeon_debugfs_ring_info, 0, &r600_uvd_index}, 786 {"radeon_ring_uvd", radeon_debugfs_ring_info, 0, &r600_uvd_index},
787 {"radeon_ring_vce1", radeon_debugfs_ring_info, 0, &si_vce1_index},
788 {"radeon_ring_vce2", radeon_debugfs_ring_info, 0, &si_vce2_index},
825}; 789};
826 790
827static int radeon_debugfs_sa_info(struct seq_file *m, void *data) 791static int radeon_debugfs_sa_info(struct seq_file *m, void *data)
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c
index 12e8099a0823..3a13e0d1055c 100644
--- a/drivers/gpu/drm/radeon/radeon_test.c
+++ b/drivers/gpu/drm/radeon/radeon_test.c
@@ -257,20 +257,36 @@ static int radeon_test_create_and_emit_fence(struct radeon_device *rdev,
257 struct radeon_ring *ring, 257 struct radeon_ring *ring,
258 struct radeon_fence **fence) 258 struct radeon_fence **fence)
259{ 259{
260 uint32_t handle = ring->idx ^ 0xdeafbeef;
260 int r; 261 int r;
261 262
262 if (ring->idx == R600_RING_TYPE_UVD_INDEX) { 263 if (ring->idx == R600_RING_TYPE_UVD_INDEX) {
263 r = radeon_uvd_get_create_msg(rdev, ring->idx, 1, NULL); 264 r = radeon_uvd_get_create_msg(rdev, ring->idx, handle, NULL);
264 if (r) { 265 if (r) {
265 DRM_ERROR("Failed to get dummy create msg\n"); 266 DRM_ERROR("Failed to get dummy create msg\n");
266 return r; 267 return r;
267 } 268 }
268 269
269 r = radeon_uvd_get_destroy_msg(rdev, ring->idx, 1, fence); 270 r = radeon_uvd_get_destroy_msg(rdev, ring->idx, handle, fence);
270 if (r) { 271 if (r) {
271 DRM_ERROR("Failed to get dummy destroy msg\n"); 272 DRM_ERROR("Failed to get dummy destroy msg\n");
272 return r; 273 return r;
273 } 274 }
275
276 } else if (ring->idx == TN_RING_TYPE_VCE1_INDEX ||
277 ring->idx == TN_RING_TYPE_VCE2_INDEX) {
278 r = radeon_vce_get_create_msg(rdev, ring->idx, handle, NULL);
279 if (r) {
280 DRM_ERROR("Failed to get dummy create msg\n");
281 return r;
282 }
283
284 r = radeon_vce_get_destroy_msg(rdev, ring->idx, handle, fence);
285 if (r) {
286 DRM_ERROR("Failed to get dummy destroy msg\n");
287 return r;
288 }
289
274 } else { 290 } else {
275 r = radeon_ring_lock(rdev, ring, 64); 291 r = radeon_ring_lock(rdev, ring, 64);
276 if (r) { 292 if (r) {
@@ -486,6 +502,16 @@ out_cleanup:
486 printk(KERN_WARNING "Error while testing ring sync (%d).\n", r); 502 printk(KERN_WARNING "Error while testing ring sync (%d).\n", r);
487} 503}
488 504
505static bool radeon_test_sync_possible(struct radeon_ring *ringA,
506 struct radeon_ring *ringB)
507{
508 if (ringA->idx == TN_RING_TYPE_VCE2_INDEX &&
509 ringB->idx == TN_RING_TYPE_VCE1_INDEX)
510 return false;
511
512 return true;
513}
514
489void radeon_test_syncing(struct radeon_device *rdev) 515void radeon_test_syncing(struct radeon_device *rdev)
490{ 516{
491 int i, j, k; 517 int i, j, k;
@@ -500,6 +526,9 @@ void radeon_test_syncing(struct radeon_device *rdev)
500 if (!ringB->ready) 526 if (!ringB->ready)
501 continue; 527 continue;
502 528
529 if (!radeon_test_sync_possible(ringA, ringB))
530 continue;
531
503 DRM_INFO("Testing syncing between rings %d and %d...\n", i, j); 532 DRM_INFO("Testing syncing between rings %d and %d...\n", i, j);
504 radeon_test_ring_sync(rdev, ringA, ringB); 533 radeon_test_ring_sync(rdev, ringA, ringB);
505 534
@@ -511,6 +540,12 @@ void radeon_test_syncing(struct radeon_device *rdev)
511 if (!ringC->ready) 540 if (!ringC->ready)
512 continue; 541 continue;
513 542
543 if (!radeon_test_sync_possible(ringA, ringC))
544 continue;
545
546 if (!radeon_test_sync_possible(ringB, ringC))
547 continue;
548
514 DRM_INFO("Testing syncing between rings %d, %d and %d...\n", i, j, k); 549 DRM_INFO("Testing syncing between rings %d, %d and %d...\n", i, j, k);
515 radeon_test_ring_sync2(rdev, ringA, ringB, ringC); 550 radeon_test_ring_sync2(rdev, ringA, ringB, ringC);
516 551
diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c
new file mode 100644
index 000000000000..d130432e313a
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_vce.c
@@ -0,0 +1,694 @@
1/*
2 * Copyright 2013 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19 * USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * The above copyright notice and this permission notice (including the
22 * next paragraph) shall be included in all copies or substantial portions
23 * of the Software.
24 *
25 * Authors: Christian König <christian.koenig@amd.com>
26 */
27
28#include <linux/firmware.h>
29#include <linux/module.h>
30#include <drm/drmP.h>
31#include <drm/drm.h>
32
33#include "radeon.h"
34#include "radeon_asic.h"
35#include "sid.h"
36
37/* 1 second timeout */
38#define VCE_IDLE_TIMEOUT_MS 1000
39
40/* Firmware Names */
41#define FIRMWARE_BONAIRE "radeon/BONAIRE_vce.bin"
42
43MODULE_FIRMWARE(FIRMWARE_BONAIRE);
44
45static void radeon_vce_idle_work_handler(struct work_struct *work);
46
47/**
48 * radeon_vce_init - allocate memory, load vce firmware
49 *
50 * @rdev: radeon_device pointer
51 *
52 * First step to get VCE online, allocate memory and load the firmware
53 */
54int radeon_vce_init(struct radeon_device *rdev)
55{
56 static const char *fw_version = "[ATI LIB=VCEFW,";
57 static const char *fb_version = "[ATI LIB=VCEFWSTATS,";
58 unsigned long size;
59 const char *fw_name, *c;
60 uint8_t start, mid, end;
61 int i, r;
62
63 INIT_DELAYED_WORK(&rdev->vce.idle_work, radeon_vce_idle_work_handler);
64
65 switch (rdev->family) {
66 case CHIP_BONAIRE:
67 case CHIP_KAVERI:
68 case CHIP_KABINI:
69 fw_name = FIRMWARE_BONAIRE;
70 break;
71
72 default:
73 return -EINVAL;
74 }
75
76 r = request_firmware(&rdev->vce_fw, fw_name, rdev->dev);
77 if (r) {
78 dev_err(rdev->dev, "radeon_vce: Can't load firmware \"%s\"\n",
79 fw_name);
80 return r;
81 }
82
83 /* search for firmware version */
84
85 size = rdev->vce_fw->size - strlen(fw_version) - 9;
86 c = rdev->vce_fw->data;
87 for (;size > 0; --size, ++c)
88 if (strncmp(c, fw_version, strlen(fw_version)) == 0)
89 break;
90
91 if (size == 0)
92 return -EINVAL;
93
94 c += strlen(fw_version);
95 if (sscanf(c, "%2hhd.%2hhd.%2hhd]", &start, &mid, &end) != 3)
96 return -EINVAL;
97
98 /* search for feedback version */
99
100 size = rdev->vce_fw->size - strlen(fb_version) - 3;
101 c = rdev->vce_fw->data;
102 for (;size > 0; --size, ++c)
103 if (strncmp(c, fb_version, strlen(fb_version)) == 0)
104 break;
105
106 if (size == 0)
107 return -EINVAL;
108
109 c += strlen(fb_version);
110 if (sscanf(c, "%2u]", &rdev->vce.fb_version) != 1)
111 return -EINVAL;
112
113 DRM_INFO("Found VCE firmware/feedback version %hhd.%hhd.%hhd / %d!\n",
114 start, mid, end, rdev->vce.fb_version);
115
116 rdev->vce.fw_version = (start << 24) | (mid << 16) | (end << 8);
117
118 /* we can only work with this fw version for now */
119 if (rdev->vce.fw_version != ((40 << 24) | (2 << 16) | (2 << 8)))
120 return -EINVAL;
121
122 /* load firmware into VRAM */
123
124 size = RADEON_GPU_PAGE_ALIGN(rdev->vce_fw->size) +
125 RADEON_VCE_STACK_SIZE + RADEON_VCE_HEAP_SIZE;
126 r = radeon_bo_create(rdev, size, PAGE_SIZE, true,
127 RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->vce.vcpu_bo);
128 if (r) {
129 dev_err(rdev->dev, "(%d) failed to allocate VCE bo\n", r);
130 return r;
131 }
132
133 r = radeon_vce_resume(rdev);
134 if (r)
135 return r;
136
137 memset(rdev->vce.cpu_addr, 0, size);
138 memcpy(rdev->vce.cpu_addr, rdev->vce_fw->data, rdev->vce_fw->size);
139
140 r = radeon_vce_suspend(rdev);
141 if (r)
142 return r;
143
144 for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) {
145 atomic_set(&rdev->vce.handles[i], 0);
146 rdev->vce.filp[i] = NULL;
147 }
148
149 return 0;
150}
151
152/**
153 * radeon_vce_fini - free memory
154 *
155 * @rdev: radeon_device pointer
156 *
157 * Last step on VCE teardown, free firmware memory
158 */
159void radeon_vce_fini(struct radeon_device *rdev)
160{
161 radeon_vce_suspend(rdev);
162 radeon_bo_unref(&rdev->vce.vcpu_bo);
163}
164
165/**
166 * radeon_vce_suspend - unpin VCE fw memory
167 *
168 * @rdev: radeon_device pointer
169 *
170 * TODO: Test VCE suspend/resume
171 */
172int radeon_vce_suspend(struct radeon_device *rdev)
173{
174 int r;
175
176 if (rdev->vce.vcpu_bo == NULL)
177 return 0;
178
179 r = radeon_bo_reserve(rdev->vce.vcpu_bo, false);
180 if (!r) {
181 radeon_bo_kunmap(rdev->vce.vcpu_bo);
182 radeon_bo_unpin(rdev->vce.vcpu_bo);
183 radeon_bo_unreserve(rdev->vce.vcpu_bo);
184 }
185 return r;
186}
187
188/**
189 * radeon_vce_resume - pin VCE fw memory
190 *
191 * @rdev: radeon_device pointer
192 *
193 * TODO: Test VCE suspend/resume
194 */
195int radeon_vce_resume(struct radeon_device *rdev)
196{
197 int r;
198
199 if (rdev->vce.vcpu_bo == NULL)
200 return -EINVAL;
201
202 r = radeon_bo_reserve(rdev->vce.vcpu_bo, false);
203 if (r) {
204 radeon_bo_unref(&rdev->vce.vcpu_bo);
205 dev_err(rdev->dev, "(%d) failed to reserve VCE bo\n", r);
206 return r;
207 }
208
209 r = radeon_bo_pin(rdev->vce.vcpu_bo, RADEON_GEM_DOMAIN_VRAM,
210 &rdev->vce.gpu_addr);
211 if (r) {
212 radeon_bo_unreserve(rdev->vce.vcpu_bo);
213 radeon_bo_unref(&rdev->vce.vcpu_bo);
214 dev_err(rdev->dev, "(%d) VCE bo pin failed\n", r);
215 return r;
216 }
217
218 r = radeon_bo_kmap(rdev->vce.vcpu_bo, &rdev->vce.cpu_addr);
219 if (r) {
220 dev_err(rdev->dev, "(%d) VCE map failed\n", r);
221 return r;
222 }
223
224 radeon_bo_unreserve(rdev->vce.vcpu_bo);
225
226 return 0;
227}
228
229/**
230 * radeon_vce_idle_work_handler - power off VCE
231 *
232 * @work: pointer to work structure
233 *
234 * power of VCE when it's not used any more
235 */
236static void radeon_vce_idle_work_handler(struct work_struct *work)
237{
238 struct radeon_device *rdev =
239 container_of(work, struct radeon_device, vce.idle_work.work);
240
241 if ((radeon_fence_count_emitted(rdev, TN_RING_TYPE_VCE1_INDEX) == 0) &&
242 (radeon_fence_count_emitted(rdev, TN_RING_TYPE_VCE2_INDEX) == 0)) {
243 if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
244 radeon_dpm_enable_vce(rdev, false);
245 } else {
246 radeon_set_vce_clocks(rdev, 0, 0);
247 }
248 } else {
249 schedule_delayed_work(&rdev->vce.idle_work,
250 msecs_to_jiffies(VCE_IDLE_TIMEOUT_MS));
251 }
252}
253
254/**
255 * radeon_vce_note_usage - power up VCE
256 *
257 * @rdev: radeon_device pointer
258 *
259 * Make sure VCE is powerd up when we want to use it
260 */
261void radeon_vce_note_usage(struct radeon_device *rdev)
262{
263 bool streams_changed = false;
264 bool set_clocks = !cancel_delayed_work_sync(&rdev->vce.idle_work);
265 set_clocks &= schedule_delayed_work(&rdev->vce.idle_work,
266 msecs_to_jiffies(VCE_IDLE_TIMEOUT_MS));
267
268 if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
269 /* XXX figure out if the streams changed */
270 streams_changed = false;
271 }
272
273 if (set_clocks || streams_changed) {
274 if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
275 radeon_dpm_enable_vce(rdev, true);
276 } else {
277 radeon_set_vce_clocks(rdev, 53300, 40000);
278 }
279 }
280}
281
282/**
283 * radeon_vce_free_handles - free still open VCE handles
284 *
285 * @rdev: radeon_device pointer
286 * @filp: drm file pointer
287 *
288 * Close all VCE handles still open by this file pointer
289 */
290void radeon_vce_free_handles(struct radeon_device *rdev, struct drm_file *filp)
291{
292 int i, r;
293 for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) {
294 uint32_t handle = atomic_read(&rdev->vce.handles[i]);
295 if (!handle || rdev->vce.filp[i] != filp)
296 continue;
297
298 radeon_vce_note_usage(rdev);
299
300 r = radeon_vce_get_destroy_msg(rdev, TN_RING_TYPE_VCE1_INDEX,
301 handle, NULL);
302 if (r)
303 DRM_ERROR("Error destroying VCE handle (%d)!\n", r);
304
305 rdev->vce.filp[i] = NULL;
306 atomic_set(&rdev->vce.handles[i], 0);
307 }
308}
309
310/**
311 * radeon_vce_get_create_msg - generate a VCE create msg
312 *
313 * @rdev: radeon_device pointer
314 * @ring: ring we should submit the msg to
315 * @handle: VCE session handle to use
316 * @fence: optional fence to return
317 *
318 * Open up a stream for HW test
319 */
320int radeon_vce_get_create_msg(struct radeon_device *rdev, int ring,
321 uint32_t handle, struct radeon_fence **fence)
322{
323 const unsigned ib_size_dw = 1024;
324 struct radeon_ib ib;
325 uint64_t dummy;
326 int i, r;
327
328 r = radeon_ib_get(rdev, ring, &ib, NULL, ib_size_dw * 4);
329 if (r) {
330 DRM_ERROR("radeon: failed to get ib (%d).\n", r);
331 return r;
332 }
333
334 dummy = ib.gpu_addr + 1024;
335
336 /* stitch together an VCE create msg */
337 ib.length_dw = 0;
338 ib.ptr[ib.length_dw++] = 0x0000000c; /* len */
339 ib.ptr[ib.length_dw++] = 0x00000001; /* session cmd */
340 ib.ptr[ib.length_dw++] = handle;
341
342 ib.ptr[ib.length_dw++] = 0x00000030; /* len */
343 ib.ptr[ib.length_dw++] = 0x01000001; /* create cmd */
344 ib.ptr[ib.length_dw++] = 0x00000000;
345 ib.ptr[ib.length_dw++] = 0x00000042;
346 ib.ptr[ib.length_dw++] = 0x0000000a;
347 ib.ptr[ib.length_dw++] = 0x00000001;
348 ib.ptr[ib.length_dw++] = 0x00000080;
349 ib.ptr[ib.length_dw++] = 0x00000060;
350 ib.ptr[ib.length_dw++] = 0x00000100;
351 ib.ptr[ib.length_dw++] = 0x00000100;
352 ib.ptr[ib.length_dw++] = 0x0000000c;
353 ib.ptr[ib.length_dw++] = 0x00000000;
354
355 ib.ptr[ib.length_dw++] = 0x00000014; /* len */
356 ib.ptr[ib.length_dw++] = 0x05000005; /* feedback buffer */
357 ib.ptr[ib.length_dw++] = upper_32_bits(dummy);
358 ib.ptr[ib.length_dw++] = dummy;
359 ib.ptr[ib.length_dw++] = 0x00000001;
360
361 for (i = ib.length_dw; i < ib_size_dw; ++i)
362 ib.ptr[i] = 0x0;
363
364 r = radeon_ib_schedule(rdev, &ib, NULL);
365 if (r) {
366 DRM_ERROR("radeon: failed to schedule ib (%d).\n", r);
367 }
368
369 if (fence)
370 *fence = radeon_fence_ref(ib.fence);
371
372 radeon_ib_free(rdev, &ib);
373
374 return r;
375}
376
377/**
378 * radeon_vce_get_destroy_msg - generate a VCE destroy msg
379 *
380 * @rdev: radeon_device pointer
381 * @ring: ring we should submit the msg to
382 * @handle: VCE session handle to use
383 * @fence: optional fence to return
384 *
385 * Close up a stream for HW test or if userspace failed to do so
386 */
387int radeon_vce_get_destroy_msg(struct radeon_device *rdev, int ring,
388 uint32_t handle, struct radeon_fence **fence)
389{
390 const unsigned ib_size_dw = 1024;
391 struct radeon_ib ib;
392 uint64_t dummy;
393 int i, r;
394
395 r = radeon_ib_get(rdev, ring, &ib, NULL, ib_size_dw * 4);
396 if (r) {
397 DRM_ERROR("radeon: failed to get ib (%d).\n", r);
398 return r;
399 }
400
401 dummy = ib.gpu_addr + 1024;
402
403 /* stitch together an VCE destroy msg */
404 ib.length_dw = 0;
405 ib.ptr[ib.length_dw++] = 0x0000000c; /* len */
406 ib.ptr[ib.length_dw++] = 0x00000001; /* session cmd */
407 ib.ptr[ib.length_dw++] = handle;
408
409 ib.ptr[ib.length_dw++] = 0x00000014; /* len */
410 ib.ptr[ib.length_dw++] = 0x05000005; /* feedback buffer */
411 ib.ptr[ib.length_dw++] = upper_32_bits(dummy);
412 ib.ptr[ib.length_dw++] = dummy;
413 ib.ptr[ib.length_dw++] = 0x00000001;
414
415 ib.ptr[ib.length_dw++] = 0x00000008; /* len */
416 ib.ptr[ib.length_dw++] = 0x02000001; /* destroy cmd */
417
418 for (i = ib.length_dw; i < ib_size_dw; ++i)
419 ib.ptr[i] = 0x0;
420
421 r = radeon_ib_schedule(rdev, &ib, NULL);
422 if (r) {
423 DRM_ERROR("radeon: failed to schedule ib (%d).\n", r);
424 }
425
426 if (fence)
427 *fence = radeon_fence_ref(ib.fence);
428
429 radeon_ib_free(rdev, &ib);
430
431 return r;
432}
433
434/**
435 * radeon_vce_cs_reloc - command submission relocation
436 *
437 * @p: parser context
438 * @lo: address of lower dword
439 * @hi: address of higher dword
440 *
441 * Patch relocation inside command stream with real buffer address
442 */
443int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi)
444{
445 struct radeon_cs_chunk *relocs_chunk;
446 uint64_t offset;
447 unsigned idx;
448
449 relocs_chunk = &p->chunks[p->chunk_relocs_idx];
450 offset = radeon_get_ib_value(p, lo);
451 idx = radeon_get_ib_value(p, hi);
452
453 if (idx >= relocs_chunk->length_dw) {
454 DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
455 idx, relocs_chunk->length_dw);
456 return -EINVAL;
457 }
458
459 offset += p->relocs_ptr[(idx / 4)]->lobj.gpu_offset;
460
461 p->ib.ptr[lo] = offset & 0xFFFFFFFF;
462 p->ib.ptr[hi] = offset >> 32;
463
464 return 0;
465}
466
467/**
468 * radeon_vce_cs_parse - parse and validate the command stream
469 *
470 * @p: parser context
471 *
472 */
473int radeon_vce_cs_parse(struct radeon_cs_parser *p)
474{
475 uint32_t handle = 0;
476 bool destroy = false;
477 int i, r;
478
479 while (p->idx < p->chunks[p->chunk_ib_idx].length_dw) {
480 uint32_t len = radeon_get_ib_value(p, p->idx);
481 uint32_t cmd = radeon_get_ib_value(p, p->idx + 1);
482
483 if ((len < 8) || (len & 3)) {
484 DRM_ERROR("invalid VCE command length (%d)!\n", len);
485 return -EINVAL;
486 }
487
488 switch (cmd) {
489 case 0x00000001: // session
490 handle = radeon_get_ib_value(p, p->idx + 2);
491 break;
492
493 case 0x00000002: // task info
494 case 0x01000001: // create
495 case 0x04000001: // config extension
496 case 0x04000002: // pic control
497 case 0x04000005: // rate control
498 case 0x04000007: // motion estimation
499 case 0x04000008: // rdo
500 break;
501
502 case 0x03000001: // encode
503 r = radeon_vce_cs_reloc(p, p->idx + 10, p->idx + 9);
504 if (r)
505 return r;
506
507 r = radeon_vce_cs_reloc(p, p->idx + 12, p->idx + 11);
508 if (r)
509 return r;
510 break;
511
512 case 0x02000001: // destroy
513 destroy = true;
514 break;
515
516 case 0x05000001: // context buffer
517 case 0x05000004: // video bitstream buffer
518 case 0x05000005: // feedback buffer
519 r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2);
520 if (r)
521 return r;
522 break;
523
524 default:
525 DRM_ERROR("invalid VCE command (0x%x)!\n", cmd);
526 return -EINVAL;
527 }
528
529 p->idx += len / 4;
530 }
531
532 if (destroy) {
533 /* IB contains a destroy msg, free the handle */
534 for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i)
535 atomic_cmpxchg(&p->rdev->vce.handles[i], handle, 0);
536
537 return 0;
538 }
539
540 /* create or encode, validate the handle */
541 for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) {
542 if (atomic_read(&p->rdev->vce.handles[i]) == handle)
543 return 0;
544 }
545
546 /* handle not found try to alloc a new one */
547 for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) {
548 if (!atomic_cmpxchg(&p->rdev->vce.handles[i], 0, handle)) {
549 p->rdev->vce.filp[i] = p->filp;
550 return 0;
551 }
552 }
553
554 DRM_ERROR("No more free VCE handles!\n");
555 return -EINVAL;
556}
557
558/**
559 * radeon_vce_semaphore_emit - emit a semaphore command
560 *
561 * @rdev: radeon_device pointer
562 * @ring: engine to use
563 * @semaphore: address of semaphore
564 * @emit_wait: true=emit wait, false=emit signal
565 *
566 */
567bool radeon_vce_semaphore_emit(struct radeon_device *rdev,
568 struct radeon_ring *ring,
569 struct radeon_semaphore *semaphore,
570 bool emit_wait)
571{
572 uint64_t addr = semaphore->gpu_addr;
573
574 radeon_ring_write(ring, VCE_CMD_SEMAPHORE);
575 radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
576 radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
577 radeon_ring_write(ring, 0x01003000 | (emit_wait ? 1 : 0));
578 if (!emit_wait)
579 radeon_ring_write(ring, VCE_CMD_END);
580
581 return true;
582}
583
584/**
585 * radeon_vce_ib_execute - execute indirect buffer
586 *
587 * @rdev: radeon_device pointer
588 * @ib: the IB to execute
589 *
590 */
591void radeon_vce_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
592{
593 struct radeon_ring *ring = &rdev->ring[ib->ring];
594 radeon_ring_write(ring, VCE_CMD_IB);
595 radeon_ring_write(ring, ib->gpu_addr);
596 radeon_ring_write(ring, upper_32_bits(ib->gpu_addr));
597 radeon_ring_write(ring, ib->length_dw);
598}
599
600/**
601 * radeon_vce_fence_emit - add a fence command to the ring
602 *
603 * @rdev: radeon_device pointer
604 * @fence: the fence
605 *
606 */
607void radeon_vce_fence_emit(struct radeon_device *rdev,
608 struct radeon_fence *fence)
609{
610 struct radeon_ring *ring = &rdev->ring[fence->ring];
611 uint32_t addr = rdev->fence_drv[fence->ring].gpu_addr;
612
613 radeon_ring_write(ring, VCE_CMD_FENCE);
614 radeon_ring_write(ring, addr);
615 radeon_ring_write(ring, upper_32_bits(addr));
616 radeon_ring_write(ring, fence->seq);
617 radeon_ring_write(ring, VCE_CMD_TRAP);
618 radeon_ring_write(ring, VCE_CMD_END);
619}
620
621/**
622 * radeon_vce_ring_test - test if VCE ring is working
623 *
624 * @rdev: radeon_device pointer
625 * @ring: the engine to test on
626 *
627 */
628int radeon_vce_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
629{
630 uint32_t rptr = vce_v1_0_get_rptr(rdev, ring);
631 unsigned i;
632 int r;
633
634 r = radeon_ring_lock(rdev, ring, 16);
635 if (r) {
636 DRM_ERROR("radeon: vce failed to lock ring %d (%d).\n",
637 ring->idx, r);
638 return r;
639 }
640 radeon_ring_write(ring, VCE_CMD_END);
641 radeon_ring_unlock_commit(rdev, ring);
642
643 for (i = 0; i < rdev->usec_timeout; i++) {
644 if (vce_v1_0_get_rptr(rdev, ring) != rptr)
645 break;
646 DRM_UDELAY(1);
647 }
648
649 if (i < rdev->usec_timeout) {
650 DRM_INFO("ring test on %d succeeded in %d usecs\n",
651 ring->idx, i);
652 } else {
653 DRM_ERROR("radeon: ring %d test failed\n",
654 ring->idx);
655 r = -ETIMEDOUT;
656 }
657
658 return r;
659}
660
661/**
662 * radeon_vce_ib_test - test if VCE IBs are working
663 *
664 * @rdev: radeon_device pointer
665 * @ring: the engine to test on
666 *
667 */
668int radeon_vce_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
669{
670 struct radeon_fence *fence = NULL;
671 int r;
672
673 r = radeon_vce_get_create_msg(rdev, ring->idx, 1, NULL);
674 if (r) {
675 DRM_ERROR("radeon: failed to get create msg (%d).\n", r);
676 goto error;
677 }
678
679 r = radeon_vce_get_destroy_msg(rdev, ring->idx, 1, &fence);
680 if (r) {
681 DRM_ERROR("radeon: failed to get destroy ib (%d).\n", r);
682 goto error;
683 }
684
685 r = radeon_fence_wait(fence, false);
686 if (r) {
687 DRM_ERROR("radeon: fence wait failed (%d).\n", r);
688 } else {
689 DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
690 }
691error:
692 radeon_fence_unref(&fence);
693 return r;
694}
diff --git a/drivers/gpu/drm/radeon/rs780_dpm.c b/drivers/gpu/drm/radeon/rs780_dpm.c
index 8512085b0aef..02f7710de470 100644
--- a/drivers/gpu/drm/radeon/rs780_dpm.c
+++ b/drivers/gpu/drm/radeon/rs780_dpm.c
@@ -807,9 +807,6 @@ static int rs780_parse_power_table(struct radeon_device *rdev)
807 power_info->pplib.ucNumStates, GFP_KERNEL); 807 power_info->pplib.ucNumStates, GFP_KERNEL);
808 if (!rdev->pm.dpm.ps) 808 if (!rdev->pm.dpm.ps)
809 return -ENOMEM; 809 return -ENOMEM;
810 rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
811 rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
812 rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
813 810
814 for (i = 0; i < power_info->pplib.ucNumStates; i++) { 811 for (i = 0; i < power_info->pplib.ucNumStates; i++) {
815 power_state = (union pplib_power_state *) 812 power_state = (union pplib_power_state *)
@@ -859,6 +856,10 @@ int rs780_dpm_init(struct radeon_device *rdev)
859 return -ENOMEM; 856 return -ENOMEM;
860 rdev->pm.dpm.priv = pi; 857 rdev->pm.dpm.priv = pi;
861 858
859 ret = r600_get_platform_caps(rdev);
860 if (ret)
861 return ret;
862
862 ret = rs780_parse_power_table(rdev); 863 ret = rs780_parse_power_table(rdev);
863 if (ret) 864 if (ret)
864 return ret; 865 return ret;
diff --git a/drivers/gpu/drm/radeon/rv6xx_dpm.c b/drivers/gpu/drm/radeon/rv6xx_dpm.c
index bebf31c4d841..e7045b085715 100644
--- a/drivers/gpu/drm/radeon/rv6xx_dpm.c
+++ b/drivers/gpu/drm/radeon/rv6xx_dpm.c
@@ -1891,9 +1891,6 @@ static int rv6xx_parse_power_table(struct radeon_device *rdev)
1891 power_info->pplib.ucNumStates, GFP_KERNEL); 1891 power_info->pplib.ucNumStates, GFP_KERNEL);
1892 if (!rdev->pm.dpm.ps) 1892 if (!rdev->pm.dpm.ps)
1893 return -ENOMEM; 1893 return -ENOMEM;
1894 rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
1895 rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
1896 rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
1897 1894
1898 for (i = 0; i < power_info->pplib.ucNumStates; i++) { 1895 for (i = 0; i < power_info->pplib.ucNumStates; i++) {
1899 power_state = (union pplib_power_state *) 1896 power_state = (union pplib_power_state *)
@@ -1943,6 +1940,10 @@ int rv6xx_dpm_init(struct radeon_device *rdev)
1943 return -ENOMEM; 1940 return -ENOMEM;
1944 rdev->pm.dpm.priv = pi; 1941 rdev->pm.dpm.priv = pi;
1945 1942
1943 ret = r600_get_platform_caps(rdev);
1944 if (ret)
1945 return ret;
1946
1946 ret = rv6xx_parse_power_table(rdev); 1947 ret = rv6xx_parse_power_table(rdev);
1947 if (ret) 1948 if (ret)
1948 return ret; 1949 return ret;
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c
index b5f63f5e22a3..da041a43d82e 100644
--- a/drivers/gpu/drm/radeon/rv770_dpm.c
+++ b/drivers/gpu/drm/radeon/rv770_dpm.c
@@ -2281,9 +2281,6 @@ int rv7xx_parse_power_table(struct radeon_device *rdev)
2281 power_info->pplib.ucNumStates, GFP_KERNEL); 2281 power_info->pplib.ucNumStates, GFP_KERNEL);
2282 if (!rdev->pm.dpm.ps) 2282 if (!rdev->pm.dpm.ps)
2283 return -ENOMEM; 2283 return -ENOMEM;
2284 rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
2285 rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
2286 rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
2287 2284
2288 for (i = 0; i < power_info->pplib.ucNumStates; i++) { 2285 for (i = 0; i < power_info->pplib.ucNumStates; i++) {
2289 power_state = (union pplib_power_state *) 2286 power_state = (union pplib_power_state *)
@@ -2361,6 +2358,10 @@ int rv770_dpm_init(struct radeon_device *rdev)
2361 pi->min_vddc_in_table = 0; 2358 pi->min_vddc_in_table = 0;
2362 pi->max_vddc_in_table = 0; 2359 pi->max_vddc_in_table = 0;
2363 2360
2361 ret = r600_get_platform_caps(rdev);
2362 if (ret)
2363 return ret;
2364
2364 ret = rv7xx_parse_power_table(rdev); 2365 ret = rv7xx_parse_power_table(rdev);
2365 if (ret) 2366 if (ret)
2366 return ret; 2367 return ret;
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 83578324e5d1..8008cb8d5324 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -3434,8 +3434,6 @@ static int si_cp_resume(struct radeon_device *rdev)
3434 3434
3435 WREG32(CP_RB0_BASE, ring->gpu_addr >> 8); 3435 WREG32(CP_RB0_BASE, ring->gpu_addr >> 8);
3436 3436
3437 ring->rptr = RREG32(CP_RB0_RPTR);
3438
3439 /* ring1 - compute only */ 3437 /* ring1 - compute only */
3440 /* Set ring buffer size */ 3438 /* Set ring buffer size */
3441 ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; 3439 ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
@@ -3460,8 +3458,6 @@ static int si_cp_resume(struct radeon_device *rdev)
3460 3458
3461 WREG32(CP_RB1_BASE, ring->gpu_addr >> 8); 3459 WREG32(CP_RB1_BASE, ring->gpu_addr >> 8);
3462 3460
3463 ring->rptr = RREG32(CP_RB1_RPTR);
3464
3465 /* ring2 - compute only */ 3461 /* ring2 - compute only */
3466 /* Set ring buffer size */ 3462 /* Set ring buffer size */
3467 ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; 3463 ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
@@ -3486,8 +3482,6 @@ static int si_cp_resume(struct radeon_device *rdev)
3486 3482
3487 WREG32(CP_RB2_BASE, ring->gpu_addr >> 8); 3483 WREG32(CP_RB2_BASE, ring->gpu_addr >> 8);
3488 3484
3489 ring->rptr = RREG32(CP_RB2_RPTR);
3490
3491 /* start the rings */ 3485 /* start the rings */
3492 si_cp_start(rdev); 3486 si_cp_start(rdev);
3493 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true; 3487 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true;
@@ -3872,11 +3866,9 @@ bool si_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
3872 if (!(reset_mask & (RADEON_RESET_GFX | 3866 if (!(reset_mask & (RADEON_RESET_GFX |
3873 RADEON_RESET_COMPUTE | 3867 RADEON_RESET_COMPUTE |
3874 RADEON_RESET_CP))) { 3868 RADEON_RESET_CP))) {
3875 radeon_ring_lockup_update(ring); 3869 radeon_ring_lockup_update(rdev, ring);
3876 return false; 3870 return false;
3877 } 3871 }
3878 /* force CP activities */
3879 radeon_ring_force_activity(rdev, ring);
3880 return radeon_ring_test_lockup(rdev, ring); 3872 return radeon_ring_test_lockup(rdev, ring);
3881} 3873}
3882 3874
diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c
index 59be2cfcbb47..cf0fdad8c278 100644
--- a/drivers/gpu/drm/radeon/si_dma.c
+++ b/drivers/gpu/drm/radeon/si_dma.c
@@ -49,11 +49,9 @@ bool si_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
49 mask = RADEON_RESET_DMA1; 49 mask = RADEON_RESET_DMA1;
50 50
51 if (!(reset_mask & mask)) { 51 if (!(reset_mask & mask)) {
52 radeon_ring_lockup_update(ring); 52 radeon_ring_lockup_update(rdev, ring);
53 return false; 53 return false;
54 } 54 }
55 /* force ring activities */
56 radeon_ring_force_activity(rdev, ring);
57 return radeon_ring_test_lockup(rdev, ring); 55 return radeon_ring_test_lockup(rdev, ring);
58} 56}
59 57
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c
index 0a2f5b4bca43..9a3567bedaae 100644
--- a/drivers/gpu/drm/radeon/si_dpm.c
+++ b/drivers/gpu/drm/radeon/si_dpm.c
@@ -6271,9 +6271,6 @@ static int si_parse_power_table(struct radeon_device *rdev)
6271 if (!rdev->pm.dpm.ps) 6271 if (!rdev->pm.dpm.ps)
6272 return -ENOMEM; 6272 return -ENOMEM;
6273 power_state_offset = (u8 *)state_array->states; 6273 power_state_offset = (u8 *)state_array->states;
6274 rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
6275 rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
6276 rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
6277 for (i = 0; i < state_array->ucNumEntries; i++) { 6274 for (i = 0; i < state_array->ucNumEntries; i++) {
6278 u8 *idx; 6275 u8 *idx;
6279 power_state = (union pplib_power_state *)power_state_offset; 6276 power_state = (union pplib_power_state *)power_state_offset;
@@ -6350,6 +6347,10 @@ int si_dpm_init(struct radeon_device *rdev)
6350 pi->min_vddc_in_table = 0; 6347 pi->min_vddc_in_table = 0;
6351 pi->max_vddc_in_table = 0; 6348 pi->max_vddc_in_table = 0;
6352 6349
6350 ret = r600_get_platform_caps(rdev);
6351 if (ret)
6352 return ret;
6353
6353 ret = si_parse_power_table(rdev); 6354 ret = si_parse_power_table(rdev);
6354 if (ret) 6355 if (ret)
6355 return ret; 6356 return ret;
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h
index 9239a6d29128..683532f84931 100644
--- a/drivers/gpu/drm/radeon/sid.h
+++ b/drivers/gpu/drm/radeon/sid.h
@@ -1798,4 +1798,51 @@
1798#define DMA_PACKET_CONSTANT_FILL 0xd 1798#define DMA_PACKET_CONSTANT_FILL 0xd
1799#define DMA_PACKET_NOP 0xf 1799#define DMA_PACKET_NOP 0xf
1800 1800
1801#define VCE_STATUS 0x20004
1802#define VCE_VCPU_CNTL 0x20014
1803#define VCE_CLK_EN (1 << 0)
1804#define VCE_VCPU_CACHE_OFFSET0 0x20024
1805#define VCE_VCPU_CACHE_SIZE0 0x20028
1806#define VCE_VCPU_CACHE_OFFSET1 0x2002c
1807#define VCE_VCPU_CACHE_SIZE1 0x20030
1808#define VCE_VCPU_CACHE_OFFSET2 0x20034
1809#define VCE_VCPU_CACHE_SIZE2 0x20038
1810#define VCE_SOFT_RESET 0x20120
1811#define VCE_ECPU_SOFT_RESET (1 << 0)
1812#define VCE_FME_SOFT_RESET (1 << 2)
1813#define VCE_RB_BASE_LO2 0x2016c
1814#define VCE_RB_BASE_HI2 0x20170
1815#define VCE_RB_SIZE2 0x20174
1816#define VCE_RB_RPTR2 0x20178
1817#define VCE_RB_WPTR2 0x2017c
1818#define VCE_RB_BASE_LO 0x20180
1819#define VCE_RB_BASE_HI 0x20184
1820#define VCE_RB_SIZE 0x20188
1821#define VCE_RB_RPTR 0x2018c
1822#define VCE_RB_WPTR 0x20190
1823#define VCE_CLOCK_GATING_A 0x202f8
1824#define VCE_CLOCK_GATING_B 0x202fc
1825#define VCE_UENC_CLOCK_GATING 0x205bc
1826#define VCE_UENC_REG_CLOCK_GATING 0x205c0
1827#define VCE_FW_REG_STATUS 0x20e10
1828# define VCE_FW_REG_STATUS_BUSY (1 << 0)
1829# define VCE_FW_REG_STATUS_PASS (1 << 3)
1830# define VCE_FW_REG_STATUS_DONE (1 << 11)
1831#define VCE_LMI_FW_START_KEYSEL 0x20e18
1832#define VCE_LMI_FW_PERIODIC_CTRL 0x20e20
1833#define VCE_LMI_CTRL2 0x20e74
1834#define VCE_LMI_CTRL 0x20e98
1835#define VCE_LMI_VM_CTRL 0x20ea0
1836#define VCE_LMI_SWAP_CNTL 0x20eb4
1837#define VCE_LMI_SWAP_CNTL1 0x20eb8
1838#define VCE_LMI_CACHE_CTRL 0x20ef4
1839
1840#define VCE_CMD_NO_OP 0x00000000
1841#define VCE_CMD_END 0x00000001
1842#define VCE_CMD_IB 0x00000002
1843#define VCE_CMD_FENCE 0x00000003
1844#define VCE_CMD_TRAP 0x00000004
1845#define VCE_CMD_IB_AUTO 0x00000005
1846#define VCE_CMD_SEMAPHORE 0x00000006
1847
1801#endif 1848#endif
diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c
index 8b47b3cd0357..3f0e8d7b8dbe 100644
--- a/drivers/gpu/drm/radeon/sumo_dpm.c
+++ b/drivers/gpu/drm/radeon/sumo_dpm.c
@@ -1484,9 +1484,6 @@ static int sumo_parse_power_table(struct radeon_device *rdev)
1484 if (!rdev->pm.dpm.ps) 1484 if (!rdev->pm.dpm.ps)
1485 return -ENOMEM; 1485 return -ENOMEM;
1486 power_state_offset = (u8 *)state_array->states; 1486 power_state_offset = (u8 *)state_array->states;
1487 rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
1488 rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
1489 rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
1490 for (i = 0; i < state_array->ucNumEntries; i++) { 1487 for (i = 0; i < state_array->ucNumEntries; i++) {
1491 u8 *idx; 1488 u8 *idx;
1492 power_state = (union pplib_power_state *)power_state_offset; 1489 power_state = (union pplib_power_state *)power_state_offset;
@@ -1772,6 +1769,10 @@ int sumo_dpm_init(struct radeon_device *rdev)
1772 1769
1773 sumo_construct_boot_and_acpi_state(rdev); 1770 sumo_construct_boot_and_acpi_state(rdev);
1774 1771
1772 ret = r600_get_platform_caps(rdev);
1773 if (ret)
1774 return ret;
1775
1775 ret = sumo_parse_power_table(rdev); 1776 ret = sumo_parse_power_table(rdev);
1776 if (ret) 1777 if (ret)
1777 return ret; 1778 return ret;
diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c
index 2da0e17eb960..2a2822c03329 100644
--- a/drivers/gpu/drm/radeon/trinity_dpm.c
+++ b/drivers/gpu/drm/radeon/trinity_dpm.c
@@ -1694,9 +1694,6 @@ static int trinity_parse_power_table(struct radeon_device *rdev)
1694 if (!rdev->pm.dpm.ps) 1694 if (!rdev->pm.dpm.ps)
1695 return -ENOMEM; 1695 return -ENOMEM;
1696 power_state_offset = (u8 *)state_array->states; 1696 power_state_offset = (u8 *)state_array->states;
1697 rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
1698 rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
1699 rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
1700 for (i = 0; i < state_array->ucNumEntries; i++) { 1697 for (i = 0; i < state_array->ucNumEntries; i++) {
1701 u8 *idx; 1698 u8 *idx;
1702 power_state = (union pplib_power_state *)power_state_offset; 1699 power_state = (union pplib_power_state *)power_state_offset;
@@ -1895,6 +1892,10 @@ int trinity_dpm_init(struct radeon_device *rdev)
1895 1892
1896 trinity_construct_boot_state(rdev); 1893 trinity_construct_boot_state(rdev);
1897 1894
1895 ret = r600_get_platform_caps(rdev);
1896 if (ret)
1897 return ret;
1898
1898 ret = trinity_parse_power_table(rdev); 1899 ret = trinity_parse_power_table(rdev);
1899 if (ret) 1900 if (ret)
1900 return ret; 1901 return ret;
diff --git a/drivers/gpu/drm/radeon/uvd_v1_0.c b/drivers/gpu/drm/radeon/uvd_v1_0.c
index d4a68af1a279..0a243f0e5d68 100644
--- a/drivers/gpu/drm/radeon/uvd_v1_0.c
+++ b/drivers/gpu/drm/radeon/uvd_v1_0.c
@@ -262,7 +262,7 @@ int uvd_v1_0_start(struct radeon_device *rdev)
262 /* Initialize the ring buffer's read and write pointers */ 262 /* Initialize the ring buffer's read and write pointers */
263 WREG32(UVD_RBC_RB_RPTR, 0x0); 263 WREG32(UVD_RBC_RB_RPTR, 0x0);
264 264
265 ring->wptr = ring->rptr = RREG32(UVD_RBC_RB_RPTR); 265 ring->wptr = RREG32(UVD_RBC_RB_RPTR);
266 WREG32(UVD_RBC_RB_WPTR, ring->wptr); 266 WREG32(UVD_RBC_RB_WPTR, ring->wptr);
267 267
268 /* set the ring address */ 268 /* set the ring address */
diff --git a/drivers/gpu/drm/radeon/vce_v1_0.c b/drivers/gpu/drm/radeon/vce_v1_0.c
new file mode 100644
index 000000000000..b44d9c842f7b
--- /dev/null
+++ b/drivers/gpu/drm/radeon/vce_v1_0.c
@@ -0,0 +1,187 @@
1/*
2 * Copyright 2013 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19 * USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * The above copyright notice and this permission notice (including the
22 * next paragraph) shall be included in all copies or substantial portions
23 * of the Software.
24 *
25 * Authors: Christian König <christian.koenig@amd.com>
26 */
27
28#include <linux/firmware.h>
29#include <drm/drmP.h>
30#include "radeon.h"
31#include "radeon_asic.h"
32#include "sid.h"
33
34/**
35 * vce_v1_0_get_rptr - get read pointer
36 *
37 * @rdev: radeon_device pointer
38 * @ring: radeon_ring pointer
39 *
40 * Returns the current hardware read pointer
41 */
42uint32_t vce_v1_0_get_rptr(struct radeon_device *rdev,
43 struct radeon_ring *ring)
44{
45 if (ring->idx == TN_RING_TYPE_VCE1_INDEX)
46 return RREG32(VCE_RB_RPTR);
47 else
48 return RREG32(VCE_RB_RPTR2);
49}
50
51/**
52 * vce_v1_0_get_wptr - get write pointer
53 *
54 * @rdev: radeon_device pointer
55 * @ring: radeon_ring pointer
56 *
57 * Returns the current hardware write pointer
58 */
59uint32_t vce_v1_0_get_wptr(struct radeon_device *rdev,
60 struct radeon_ring *ring)
61{
62 if (ring->idx == TN_RING_TYPE_VCE1_INDEX)
63 return RREG32(VCE_RB_WPTR);
64 else
65 return RREG32(VCE_RB_WPTR2);
66}
67
68/**
69 * vce_v1_0_set_wptr - set write pointer
70 *
71 * @rdev: radeon_device pointer
72 * @ring: radeon_ring pointer
73 *
74 * Commits the write pointer to the hardware
75 */
76void vce_v1_0_set_wptr(struct radeon_device *rdev,
77 struct radeon_ring *ring)
78{
79 if (ring->idx == TN_RING_TYPE_VCE1_INDEX)
80 WREG32(VCE_RB_WPTR, ring->wptr);
81 else
82 WREG32(VCE_RB_WPTR2, ring->wptr);
83}
84
85/**
86 * vce_v1_0_start - start VCE block
87 *
88 * @rdev: radeon_device pointer
89 *
90 * Setup and start the VCE block
91 */
92int vce_v1_0_start(struct radeon_device *rdev)
93{
94 struct radeon_ring *ring;
95 int i, j, r;
96
97 /* set BUSY flag */
98 WREG32_P(VCE_STATUS, 1, ~1);
99
100 ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
101 WREG32(VCE_RB_RPTR, ring->wptr);
102 WREG32(VCE_RB_WPTR, ring->wptr);
103 WREG32(VCE_RB_BASE_LO, ring->gpu_addr);
104 WREG32(VCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
105 WREG32(VCE_RB_SIZE, ring->ring_size / 4);
106
107 ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
108 WREG32(VCE_RB_RPTR2, ring->wptr);
109 WREG32(VCE_RB_WPTR2, ring->wptr);
110 WREG32(VCE_RB_BASE_LO2, ring->gpu_addr);
111 WREG32(VCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
112 WREG32(VCE_RB_SIZE2, ring->ring_size / 4);
113
114 WREG32_P(VCE_VCPU_CNTL, VCE_CLK_EN, ~VCE_CLK_EN);
115
116 WREG32_P(VCE_SOFT_RESET,
117 VCE_ECPU_SOFT_RESET |
118 VCE_FME_SOFT_RESET, ~(
119 VCE_ECPU_SOFT_RESET |
120 VCE_FME_SOFT_RESET));
121
122 mdelay(100);
123
124 WREG32_P(VCE_SOFT_RESET, 0, ~(
125 VCE_ECPU_SOFT_RESET |
126 VCE_FME_SOFT_RESET));
127
128 for (i = 0; i < 10; ++i) {
129 uint32_t status;
130 for (j = 0; j < 100; ++j) {
131 status = RREG32(VCE_STATUS);
132 if (status & 2)
133 break;
134 mdelay(10);
135 }
136 r = 0;
137 if (status & 2)
138 break;
139
140 DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n");
141 WREG32_P(VCE_SOFT_RESET, VCE_ECPU_SOFT_RESET, ~VCE_ECPU_SOFT_RESET);
142 mdelay(10);
143 WREG32_P(VCE_SOFT_RESET, 0, ~VCE_ECPU_SOFT_RESET);
144 mdelay(10);
145 r = -1;
146 }
147
148 /* clear BUSY flag */
149 WREG32_P(VCE_STATUS, 0, ~1);
150
151 if (r) {
152 DRM_ERROR("VCE not responding, giving up!!!\n");
153 return r;
154 }
155
156 return 0;
157}
158
159int vce_v1_0_init(struct radeon_device *rdev)
160{
161 struct radeon_ring *ring;
162 int r;
163
164 r = vce_v1_0_start(rdev);
165 if (r)
166 return r;
167
168 ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
169 ring->ready = true;
170 r = radeon_ring_test(rdev, TN_RING_TYPE_VCE1_INDEX, ring);
171 if (r) {
172 ring->ready = false;
173 return r;
174 }
175
176 ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
177 ring->ready = true;
178 r = radeon_ring_test(rdev, TN_RING_TYPE_VCE2_INDEX, ring);
179 if (r) {
180 ring->ready = false;
181 return r;
182 }
183
184 DRM_INFO("VCE initialized successfully.\n");
185
186 return 0;
187}
diff --git a/drivers/gpu/drm/radeon/vce_v2_0.c b/drivers/gpu/drm/radeon/vce_v2_0.c
new file mode 100644
index 000000000000..1ac7bb825a1b
--- /dev/null
+++ b/drivers/gpu/drm/radeon/vce_v2_0.c
@@ -0,0 +1,181 @@
1/*
2 * Copyright 2013 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19 * USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * The above copyright notice and this permission notice (including the
22 * next paragraph) shall be included in all copies or substantial portions
23 * of the Software.
24 *
25 * Authors: Christian König <christian.koenig@amd.com>
26 */
27
28#include <linux/firmware.h>
29#include <drm/drmP.h>
30#include "radeon.h"
31#include "radeon_asic.h"
32#include "cikd.h"
33
34static void vce_v2_0_set_sw_cg(struct radeon_device *rdev, bool gated)
35{
36 u32 tmp;
37
38 if (gated) {
39 tmp = RREG32(VCE_CLOCK_GATING_B);
40 tmp |= 0xe70000;
41 WREG32(VCE_CLOCK_GATING_B, tmp);
42
43 tmp = RREG32(VCE_UENC_CLOCK_GATING);
44 tmp |= 0xff000000;
45 WREG32(VCE_UENC_CLOCK_GATING, tmp);
46
47 tmp = RREG32(VCE_UENC_REG_CLOCK_GATING);
48 tmp &= ~0x3fc;
49 WREG32(VCE_UENC_REG_CLOCK_GATING, tmp);
50
51 WREG32(VCE_CGTT_CLK_OVERRIDE, 0);
52 } else {
53 tmp = RREG32(VCE_CLOCK_GATING_B);
54 tmp |= 0xe7;
55 tmp &= ~0xe70000;
56 WREG32(VCE_CLOCK_GATING_B, tmp);
57
58 tmp = RREG32(VCE_UENC_CLOCK_GATING);
59 tmp |= 0x1fe000;
60 tmp &= ~0xff000000;
61 WREG32(VCE_UENC_CLOCK_GATING, tmp);
62
63 tmp = RREG32(VCE_UENC_REG_CLOCK_GATING);
64 tmp |= 0x3fc;
65 WREG32(VCE_UENC_REG_CLOCK_GATING, tmp);
66 }
67}
68
69static void vce_v2_0_set_dyn_cg(struct radeon_device *rdev, bool gated)
70{
71 u32 orig, tmp;
72
73 tmp = RREG32(VCE_CLOCK_GATING_B);
74 tmp &= ~0x00060006;
75 if (gated) {
76 tmp |= 0xe10000;
77 } else {
78 tmp |= 0xe1;
79 tmp &= ~0xe10000;
80 }
81 WREG32(VCE_CLOCK_GATING_B, tmp);
82
83 orig = tmp = RREG32(VCE_UENC_CLOCK_GATING);
84 tmp &= ~0x1fe000;
85 tmp &= ~0xff000000;
86 if (tmp != orig)
87 WREG32(VCE_UENC_CLOCK_GATING, tmp);
88
89 orig = tmp = RREG32(VCE_UENC_REG_CLOCK_GATING);
90 tmp &= ~0x3fc;
91 if (tmp != orig)
92 WREG32(VCE_UENC_REG_CLOCK_GATING, tmp);
93
94 if (gated)
95 WREG32(VCE_CGTT_CLK_OVERRIDE, 0);
96}
97
98static void vce_v2_0_disable_cg(struct radeon_device *rdev)
99{
100 WREG32(VCE_CGTT_CLK_OVERRIDE, 7);
101}
102
103void vce_v2_0_enable_mgcg(struct radeon_device *rdev, bool enable)
104{
105 bool sw_cg = false;
106
107 if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_VCE_MGCG)) {
108 if (sw_cg)
109 vce_v2_0_set_sw_cg(rdev, true);
110 else
111 vce_v2_0_set_dyn_cg(rdev, true);
112 } else {
113 vce_v2_0_disable_cg(rdev);
114
115 if (sw_cg)
116 vce_v2_0_set_sw_cg(rdev, false);
117 else
118 vce_v2_0_set_dyn_cg(rdev, false);
119 }
120}
121
122static void vce_v2_0_init_cg(struct radeon_device *rdev)
123{
124 u32 tmp;
125
126 tmp = RREG32(VCE_CLOCK_GATING_A);
127 tmp &= ~(CGC_CLK_GATE_DLY_TIMER_MASK | CGC_CLK_GATER_OFF_DLY_TIMER_MASK);
128 tmp |= (CGC_CLK_GATE_DLY_TIMER(0) | CGC_CLK_GATER_OFF_DLY_TIMER(4));
129 tmp |= CGC_UENC_WAIT_AWAKE;
130 WREG32(VCE_CLOCK_GATING_A, tmp);
131
132 tmp = RREG32(VCE_UENC_CLOCK_GATING);
133 tmp &= ~(CLOCK_ON_DELAY_MASK | CLOCK_OFF_DELAY_MASK);
134 tmp |= (CLOCK_ON_DELAY(0) | CLOCK_OFF_DELAY(4));
135 WREG32(VCE_UENC_CLOCK_GATING, tmp);
136
137 tmp = RREG32(VCE_CLOCK_GATING_B);
138 tmp |= 0x10;
139 tmp &= ~0x100000;
140 WREG32(VCE_CLOCK_GATING_B, tmp);
141}
142
143int vce_v2_0_resume(struct radeon_device *rdev)
144{
145 uint64_t addr = rdev->vce.gpu_addr;
146 uint32_t size;
147
148 WREG32_P(VCE_CLOCK_GATING_A, 0, ~(1 << 16));
149 WREG32_P(VCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000);
150 WREG32_P(VCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F);
151 WREG32(VCE_CLOCK_GATING_B, 0xf7);
152
153 WREG32(VCE_LMI_CTRL, 0x00398000);
154 WREG32_P(VCE_LMI_CACHE_CTRL, 0x0, ~0x1);
155 WREG32(VCE_LMI_SWAP_CNTL, 0);
156 WREG32(VCE_LMI_SWAP_CNTL1, 0);
157 WREG32(VCE_LMI_VM_CTRL, 0);
158
159 size = RADEON_GPU_PAGE_ALIGN(rdev->vce_fw->size);
160 WREG32(VCE_VCPU_CACHE_OFFSET0, addr & 0x7fffffff);
161 WREG32(VCE_VCPU_CACHE_SIZE0, size);
162
163 addr += size;
164 size = RADEON_VCE_STACK_SIZE;
165 WREG32(VCE_VCPU_CACHE_OFFSET1, addr & 0x7fffffff);
166 WREG32(VCE_VCPU_CACHE_SIZE1, size);
167
168 addr += size;
169 size = RADEON_VCE_HEAP_SIZE;
170 WREG32(VCE_VCPU_CACHE_OFFSET2, addr & 0x7fffffff);
171 WREG32(VCE_VCPU_CACHE_SIZE2, size);
172
173 WREG32_P(VCE_LMI_CTRL2, 0x0, ~0x100);
174
175 WREG32_P(VCE_SYS_INT_EN, VCE_SYS_INT_TRAP_INTERRUPT_EN,
176 ~VCE_SYS_INT_TRAP_INTERRUPT_EN);
177
178 vce_v2_0_init_cg(rdev);
179
180 return 0;
181}
diff --git a/include/uapi/drm/radeon_drm.h b/include/uapi/drm/radeon_drm.h
index d9ea3a73afe2..1cf18b4a39ec 100644
--- a/include/uapi/drm/radeon_drm.h
+++ b/include/uapi/drm/radeon_drm.h
@@ -919,6 +919,7 @@ struct drm_radeon_gem_va {
919#define RADEON_CS_RING_COMPUTE 1 919#define RADEON_CS_RING_COMPUTE 1
920#define RADEON_CS_RING_DMA 2 920#define RADEON_CS_RING_DMA 2
921#define RADEON_CS_RING_UVD 3 921#define RADEON_CS_RING_UVD 3
922#define RADEON_CS_RING_VCE 4
922/* The third dword of RADEON_CHUNK_ID_FLAGS is a sint32 that sets the priority */ 923/* The third dword of RADEON_CHUNK_ID_FLAGS is a sint32 that sets the priority */
923/* 0 = normal, + = higher priority, - = lower priority */ 924/* 0 = normal, + = higher priority, - = lower priority */
924 925
@@ -987,6 +988,10 @@ struct drm_radeon_cs {
987#define RADEON_INFO_SI_BACKEND_ENABLED_MASK 0x19 988#define RADEON_INFO_SI_BACKEND_ENABLED_MASK 0x19
988/* max engine clock - needed for OpenCL */ 989/* max engine clock - needed for OpenCL */
989#define RADEON_INFO_MAX_SCLK 0x1a 990#define RADEON_INFO_MAX_SCLK 0x1a
991/* version of VCE firmware */
992#define RADEON_INFO_VCE_FW_VERSION 0x1b
993/* version of VCE feedback */
994#define RADEON_INFO_VCE_FB_VERSION 0x1c
990 995
991 996
992struct drm_radeon_info { 997struct drm_radeon_info {