diff options
author | Dave Airlie <airlied@redhat.com> | 2015-07-23 21:51:18 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-07-23 21:51:18 -0400 |
commit | 762043aa77ad6de79236f3a9e6281f84e4fe9788 (patch) | |
tree | 32644eb4feaf507900f56afebafa50edf95dca7d | |
parent | f135b978c2dab3d439eacb8353d3c0aac6af072a (diff) | |
parent | acc6a1a69b79fad70c4794a925dbfffa9fd6b21b (diff) |
Merge branch 'drm-fixes-4.2' of git://people.freedesktop.org/~agd5f/linux into drm-fixes
Some amdgpu fixes.
* 'drm-fixes-4.2' of git://people.freedesktop.org/~agd5f/linux:
drm/amdgpu/cz/dpm: properly report UVD and VCE clock levels
drm/amdgpu/cz: implement voltage validation properly
drm/amdgpu: add VCE harvesting instance query
drm/amdgpu: implement VCE 3.0 harvesting support (v4)
drm/amdgpu/dce10: Re-set VBLANK interrupt state when enabling a CRTC
drm/amdgpu/dce11: Re-set VBLANK interrupt state when enabling a CRTC
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/cz_dpm.c | 70 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 48 | ||||
-rw-r--r-- | include/uapi/drm/amdgpu_drm.h | 2 |
7 files changed, 117 insertions, 16 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 01657830b470..e9fde72cf038 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -1614,6 +1614,9 @@ struct amdgpu_uvd { | |||
1614 | #define AMDGPU_MAX_VCE_HANDLES 16 | 1614 | #define AMDGPU_MAX_VCE_HANDLES 16 |
1615 | #define AMDGPU_VCE_FIRMWARE_OFFSET 256 | 1615 | #define AMDGPU_VCE_FIRMWARE_OFFSET 256 |
1616 | 1616 | ||
1617 | #define AMDGPU_VCE_HARVEST_VCE0 (1 << 0) | ||
1618 | #define AMDGPU_VCE_HARVEST_VCE1 (1 << 1) | ||
1619 | |||
1617 | struct amdgpu_vce { | 1620 | struct amdgpu_vce { |
1618 | struct amdgpu_bo *vcpu_bo; | 1621 | struct amdgpu_bo *vcpu_bo; |
1619 | uint64_t gpu_addr; | 1622 | uint64_t gpu_addr; |
@@ -1626,6 +1629,7 @@ struct amdgpu_vce { | |||
1626 | const struct firmware *fw; /* VCE firmware */ | 1629 | const struct firmware *fw; /* VCE firmware */ |
1627 | struct amdgpu_ring ring[AMDGPU_MAX_VCE_RINGS]; | 1630 | struct amdgpu_ring ring[AMDGPU_MAX_VCE_RINGS]; |
1628 | struct amdgpu_irq_src irq; | 1631 | struct amdgpu_irq_src irq; |
1632 | unsigned harvest_config; | ||
1629 | }; | 1633 | }; |
1630 | 1634 | ||
1631 | /* | 1635 | /* |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 5533434c7a8f..31ad444c6386 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | |||
@@ -459,6 +459,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
459 | memcpy(&dev_info.cu_bitmap[0], &cu_info.bitmap[0], sizeof(cu_info.bitmap)); | 459 | memcpy(&dev_info.cu_bitmap[0], &cu_info.bitmap[0], sizeof(cu_info.bitmap)); |
460 | dev_info.vram_type = adev->mc.vram_type; | 460 | dev_info.vram_type = adev->mc.vram_type; |
461 | dev_info.vram_bit_width = adev->mc.vram_width; | 461 | dev_info.vram_bit_width = adev->mc.vram_width; |
462 | dev_info.vce_harvest_config = adev->vce.harvest_config; | ||
462 | 463 | ||
463 | return copy_to_user(out, &dev_info, | 464 | return copy_to_user(out, &dev_info, |
464 | min((size_t)size, sizeof(dev_info))) ? -EFAULT : 0; | 465 | min((size_t)size, sizeof(dev_info))) ? -EFAULT : 0; |
diff --git a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c index 1a2d419cbf16..ace870afc7d4 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c | |||
@@ -494,29 +494,67 @@ static void cz_dpm_fini(struct amdgpu_device *adev) | |||
494 | amdgpu_free_extended_power_table(adev); | 494 | amdgpu_free_extended_power_table(adev); |
495 | } | 495 | } |
496 | 496 | ||
497 | #define ixSMUSVI_NB_CURRENTVID 0xD8230044 | ||
498 | #define CURRENT_NB_VID_MASK 0xff000000 | ||
499 | #define CURRENT_NB_VID__SHIFT 24 | ||
500 | #define ixSMUSVI_GFX_CURRENTVID 0xD8230048 | ||
501 | #define CURRENT_GFX_VID_MASK 0xff000000 | ||
502 | #define CURRENT_GFX_VID__SHIFT 24 | ||
503 | |||
497 | static void | 504 | static void |
498 | cz_dpm_debugfs_print_current_performance_level(struct amdgpu_device *adev, | 505 | cz_dpm_debugfs_print_current_performance_level(struct amdgpu_device *adev, |
499 | struct seq_file *m) | 506 | struct seq_file *m) |
500 | { | 507 | { |
508 | struct cz_power_info *pi = cz_get_pi(adev); | ||
501 | struct amdgpu_clock_voltage_dependency_table *table = | 509 | struct amdgpu_clock_voltage_dependency_table *table = |
502 | &adev->pm.dpm.dyn_state.vddc_dependency_on_sclk; | 510 | &adev->pm.dpm.dyn_state.vddc_dependency_on_sclk; |
503 | u32 current_index = | 511 | struct amdgpu_uvd_clock_voltage_dependency_table *uvd_table = |
504 | (RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX) & | 512 | &adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table; |
505 | TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX_MASK) >> | 513 | struct amdgpu_vce_clock_voltage_dependency_table *vce_table = |
506 | TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX__SHIFT; | 514 | &adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table; |
507 | u32 sclk, tmp; | 515 | u32 sclk_index = REG_GET_FIELD(RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX), |
508 | u16 vddc; | 516 | TARGET_AND_CURRENT_PROFILE_INDEX, CURR_SCLK_INDEX); |
509 | 517 | u32 uvd_index = REG_GET_FIELD(RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX_2), | |
510 | if (current_index >= NUM_SCLK_LEVELS) { | 518 | TARGET_AND_CURRENT_PROFILE_INDEX_2, CURR_UVD_INDEX); |
511 | seq_printf(m, "invalid dpm profile %d\n", current_index); | 519 | u32 vce_index = REG_GET_FIELD(RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX_2), |
520 | TARGET_AND_CURRENT_PROFILE_INDEX_2, CURR_VCE_INDEX); | ||
521 | u32 sclk, vclk, dclk, ecclk, tmp; | ||
522 | u16 vddnb, vddgfx; | ||
523 | |||
524 | if (sclk_index >= NUM_SCLK_LEVELS) { | ||
525 | seq_printf(m, "invalid sclk dpm profile %d\n", sclk_index); | ||
512 | } else { | 526 | } else { |
513 | sclk = table->entries[current_index].clk; | 527 | sclk = table->entries[sclk_index].clk; |
514 | tmp = (RREG32_SMC(ixSMU_VOLTAGE_STATUS) & | 528 | seq_printf(m, "%u sclk: %u\n", sclk_index, sclk); |
515 | SMU_VOLTAGE_STATUS__SMU_VOLTAGE_CURRENT_LEVEL_MASK) >> | 529 | } |
516 | SMU_VOLTAGE_STATUS__SMU_VOLTAGE_CURRENT_LEVEL__SHIFT; | 530 | |
517 | vddc = cz_convert_8bit_index_to_voltage(adev, (u16)tmp); | 531 | tmp = (RREG32_SMC(ixSMUSVI_NB_CURRENTVID) & |
518 | seq_printf(m, "power level %d sclk: %u vddc: %u\n", | 532 | CURRENT_NB_VID_MASK) >> CURRENT_NB_VID__SHIFT; |
519 | current_index, sclk, vddc); | 533 | vddnb = cz_convert_8bit_index_to_voltage(adev, (u16)tmp); |
534 | tmp = (RREG32_SMC(ixSMUSVI_GFX_CURRENTVID) & | ||
535 | CURRENT_GFX_VID_MASK) >> CURRENT_GFX_VID__SHIFT; | ||
536 | vddgfx = cz_convert_8bit_index_to_voltage(adev, (u16)tmp); | ||
537 | seq_printf(m, "vddnb: %u vddgfx: %u\n", vddnb, vddgfx); | ||
538 | |||
539 | seq_printf(m, "uvd %sabled\n", pi->uvd_power_gated ? "dis" : "en"); | ||
540 | if (!pi->uvd_power_gated) { | ||
541 | if (uvd_index >= CZ_MAX_HARDWARE_POWERLEVELS) { | ||
542 | seq_printf(m, "invalid uvd dpm level %d\n", uvd_index); | ||
543 | } else { | ||
544 | vclk = uvd_table->entries[uvd_index].vclk; | ||
545 | dclk = uvd_table->entries[uvd_index].dclk; | ||
546 | seq_printf(m, "%u uvd vclk: %u dclk: %u\n", uvd_index, vclk, dclk); | ||
547 | } | ||
548 | } | ||
549 | |||
550 | seq_printf(m, "vce %sabled\n", pi->vce_power_gated ? "dis" : "en"); | ||
551 | if (!pi->vce_power_gated) { | ||
552 | if (vce_index >= CZ_MAX_HARDWARE_POWERLEVELS) { | ||
553 | seq_printf(m, "invalid vce dpm level %d\n", vce_index); | ||
554 | } else { | ||
555 | ecclk = vce_table->entries[vce_index].ecclk; | ||
556 | seq_printf(m, "%u vce ecclk: %u\n", vce_index, ecclk); | ||
557 | } | ||
520 | } | 558 | } |
521 | } | 559 | } |
522 | 560 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index 6e77964f1b64..e70a26f587a0 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | |||
@@ -2632,6 +2632,7 @@ static void dce_v10_0_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2632 | struct drm_device *dev = crtc->dev; | 2632 | struct drm_device *dev = crtc->dev; |
2633 | struct amdgpu_device *adev = dev->dev_private; | 2633 | struct amdgpu_device *adev = dev->dev_private; |
2634 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); | 2634 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); |
2635 | unsigned type; | ||
2635 | 2636 | ||
2636 | switch (mode) { | 2637 | switch (mode) { |
2637 | case DRM_MODE_DPMS_ON: | 2638 | case DRM_MODE_DPMS_ON: |
@@ -2640,6 +2641,9 @@ static void dce_v10_0_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2640 | dce_v10_0_vga_enable(crtc, true); | 2641 | dce_v10_0_vga_enable(crtc, true); |
2641 | amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE); | 2642 | amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE); |
2642 | dce_v10_0_vga_enable(crtc, false); | 2643 | dce_v10_0_vga_enable(crtc, false); |
2644 | /* Make sure VBLANK interrupt is still enabled */ | ||
2645 | type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id); | ||
2646 | amdgpu_irq_update(adev, &adev->crtc_irq, type); | ||
2643 | drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id); | 2647 | drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id); |
2644 | dce_v10_0_crtc_load_lut(crtc); | 2648 | dce_v10_0_crtc_load_lut(crtc); |
2645 | break; | 2649 | break; |
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index 7f7abb0e0be5..dcb402ee048a 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | |||
@@ -2631,6 +2631,7 @@ static void dce_v11_0_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2631 | struct drm_device *dev = crtc->dev; | 2631 | struct drm_device *dev = crtc->dev; |
2632 | struct amdgpu_device *adev = dev->dev_private; | 2632 | struct amdgpu_device *adev = dev->dev_private; |
2633 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); | 2633 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); |
2634 | unsigned type; | ||
2634 | 2635 | ||
2635 | switch (mode) { | 2636 | switch (mode) { |
2636 | case DRM_MODE_DPMS_ON: | 2637 | case DRM_MODE_DPMS_ON: |
@@ -2639,6 +2640,9 @@ static void dce_v11_0_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2639 | dce_v11_0_vga_enable(crtc, true); | 2640 | dce_v11_0_vga_enable(crtc, true); |
2640 | amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE); | 2641 | amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE); |
2641 | dce_v11_0_vga_enable(crtc, false); | 2642 | dce_v11_0_vga_enable(crtc, false); |
2643 | /* Make sure VBLANK interrupt is still enabled */ | ||
2644 | type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id); | ||
2645 | amdgpu_irq_update(adev, &adev->crtc_irq, type); | ||
2642 | drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id); | 2646 | drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id); |
2643 | dce_v11_0_crtc_load_lut(crtc); | 2647 | dce_v11_0_crtc_load_lut(crtc); |
2644 | break; | 2648 | break; |
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index d62c4002e39c..d1064ca3670e 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | |||
@@ -35,6 +35,8 @@ | |||
35 | #include "oss/oss_2_0_d.h" | 35 | #include "oss/oss_2_0_d.h" |
36 | #include "oss/oss_2_0_sh_mask.h" | 36 | #include "oss/oss_2_0_sh_mask.h" |
37 | #include "gca/gfx_8_0_d.h" | 37 | #include "gca/gfx_8_0_d.h" |
38 | #include "smu/smu_7_1_2_d.h" | ||
39 | #include "smu/smu_7_1_2_sh_mask.h" | ||
38 | 40 | ||
39 | #define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04 | 41 | #define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04 |
40 | #define GRBM_GFX_INDEX__VCE_INSTANCE_MASK 0x10 | 42 | #define GRBM_GFX_INDEX__VCE_INSTANCE_MASK 0x10 |
@@ -112,6 +114,10 @@ static int vce_v3_0_start(struct amdgpu_device *adev) | |||
112 | 114 | ||
113 | mutex_lock(&adev->grbm_idx_mutex); | 115 | mutex_lock(&adev->grbm_idx_mutex); |
114 | for (idx = 0; idx < 2; ++idx) { | 116 | for (idx = 0; idx < 2; ++idx) { |
117 | |||
118 | if (adev->vce.harvest_config & (1 << idx)) | ||
119 | continue; | ||
120 | |||
115 | if(idx == 0) | 121 | if(idx == 0) |
116 | WREG32_P(mmGRBM_GFX_INDEX, 0, | 122 | WREG32_P(mmGRBM_GFX_INDEX, 0, |
117 | ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); | 123 | ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); |
@@ -190,10 +196,52 @@ static int vce_v3_0_start(struct amdgpu_device *adev) | |||
190 | return 0; | 196 | return 0; |
191 | } | 197 | } |
192 | 198 | ||
199 | #define ixVCE_HARVEST_FUSE_MACRO__ADDRESS 0xC0014074 | ||
200 | #define VCE_HARVEST_FUSE_MACRO__SHIFT 27 | ||
201 | #define VCE_HARVEST_FUSE_MACRO__MASK 0x18000000 | ||
202 | |||
203 | static unsigned vce_v3_0_get_harvest_config(struct amdgpu_device *adev) | ||
204 | { | ||
205 | u32 tmp; | ||
206 | unsigned ret; | ||
207 | |||
208 | if (adev->flags & AMDGPU_IS_APU) | ||
209 | tmp = (RREG32_SMC(ixVCE_HARVEST_FUSE_MACRO__ADDRESS) & | ||
210 | VCE_HARVEST_FUSE_MACRO__MASK) >> | ||
211 | VCE_HARVEST_FUSE_MACRO__SHIFT; | ||
212 | else | ||
213 | tmp = (RREG32_SMC(ixCC_HARVEST_FUSES) & | ||
214 | CC_HARVEST_FUSES__VCE_DISABLE_MASK) >> | ||
215 | CC_HARVEST_FUSES__VCE_DISABLE__SHIFT; | ||
216 | |||
217 | switch (tmp) { | ||
218 | case 1: | ||
219 | ret = AMDGPU_VCE_HARVEST_VCE0; | ||
220 | break; | ||
221 | case 2: | ||
222 | ret = AMDGPU_VCE_HARVEST_VCE1; | ||
223 | break; | ||
224 | case 3: | ||
225 | ret = AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1; | ||
226 | break; | ||
227 | default: | ||
228 | ret = 0; | ||
229 | } | ||
230 | |||
231 | return ret; | ||
232 | } | ||
233 | |||
193 | static int vce_v3_0_early_init(void *handle) | 234 | static int vce_v3_0_early_init(void *handle) |
194 | { | 235 | { |
195 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 236 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
196 | 237 | ||
238 | adev->vce.harvest_config = vce_v3_0_get_harvest_config(adev); | ||
239 | |||
240 | if ((adev->vce.harvest_config & | ||
241 | (AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1)) == | ||
242 | (AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1)) | ||
243 | return -ENOENT; | ||
244 | |||
197 | vce_v3_0_set_ring_funcs(adev); | 245 | vce_v3_0_set_ring_funcs(adev); |
198 | vce_v3_0_set_irq_funcs(adev); | 246 | vce_v3_0_set_irq_funcs(adev); |
199 | 247 | ||
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index b6fce900a833..d708a53b8fb1 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h | |||
@@ -614,6 +614,8 @@ struct drm_amdgpu_info_device { | |||
614 | uint32_t vram_type; | 614 | uint32_t vram_type; |
615 | /** video memory bit width*/ | 615 | /** video memory bit width*/ |
616 | uint32_t vram_bit_width; | 616 | uint32_t vram_bit_width; |
617 | /* vce harvesting instance */ | ||
618 | uint32_t vce_harvest_config; | ||
617 | }; | 619 | }; |
618 | 620 | ||
619 | struct drm_amdgpu_info_hw_ip { | 621 | struct drm_amdgpu_info_hw_ip { |