diff options
| author | Dave Airlie <airlied@redhat.com> | 2016-11-06 18:40:40 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2016-11-06 18:40:40 -0500 |
| commit | 672c98915891285b04b97ea6112c7db507903595 (patch) | |
| tree | 27e58a0c33041f19fc6f97e50be21f5e4dad17ef /drivers/gpu/drm/amd | |
| parent | bc33b0ca11e3df467777a4fa7639ba488c9d4911 (diff) | |
| parent | 245ae5e915853ced749eb47a343749cf0a9c4109 (diff) | |
Merge branch 'drm-fixes-4.9' of git://people.freedesktop.org/~agd5f/linux into drm-fixes
A few more fixes for 4.9.
* 'drm-fixes-4.9' of git://people.freedesktop.org/~agd5f/linux:
drm/amdgpu: add some error handling to amdgpu_init v2
drm/amd: fix scheduler fence teardown order v2
drm/amd/powerplay: don't succeed in getters if fan is missing
drm/amdgpu: make sure ddc_bus is valid in connector unregister
drm/radeon: Fix kernel panic on shutdown
drm/amdgpu: disable runtime pm in certain cases
drm/radeon: disable runtime pm in certain cases
drm/amdgpu: add support for new smc firmware on iceland
drm/amdgpu: add support for new smc firmware on tonga
Diffstat (limited to 'drivers/gpu/drm/amd')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 13 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 26 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vi.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 13 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/scheduler/sched_fence.c | 19 |
9 files changed, 65 insertions, 24 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index 7a8bfa34682f..662976292535 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | |||
| @@ -795,10 +795,19 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, | |||
| 795 | if (!adev->pm.fw) { | 795 | if (!adev->pm.fw) { |
| 796 | switch (adev->asic_type) { | 796 | switch (adev->asic_type) { |
| 797 | case CHIP_TOPAZ: | 797 | case CHIP_TOPAZ: |
| 798 | strcpy(fw_name, "amdgpu/topaz_smc.bin"); | 798 | if (((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x81)) || |
| 799 | ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x83)) || | ||
| 800 | ((adev->pdev->device == 0x6907) && (adev->pdev->revision == 0x87))) | ||
| 801 | strcpy(fw_name, "amdgpu/topaz_k_smc.bin"); | ||
| 802 | else | ||
| 803 | strcpy(fw_name, "amdgpu/topaz_smc.bin"); | ||
| 799 | break; | 804 | break; |
| 800 | case CHIP_TONGA: | 805 | case CHIP_TONGA: |
| 801 | strcpy(fw_name, "amdgpu/tonga_smc.bin"); | 806 | if (((adev->pdev->device == 0x6939) && (adev->pdev->revision == 0xf1)) || |
| 807 | ((adev->pdev->device == 0x6938) && (adev->pdev->revision == 0xf1))) | ||
| 808 | strcpy(fw_name, "amdgpu/tonga_k_smc.bin"); | ||
| 809 | else | ||
| 810 | strcpy(fw_name, "amdgpu/tonga_smc.bin"); | ||
| 802 | break; | 811 | break; |
| 803 | case CHIP_FIJI: | 812 | case CHIP_FIJI: |
| 804 | strcpy(fw_name, "amdgpu/fiji_smc.bin"); | 813 | strcpy(fw_name, "amdgpu/fiji_smc.bin"); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index e3281d4e3e41..086aa5c9c634 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | |||
| @@ -769,7 +769,7 @@ static void amdgpu_connector_unregister(struct drm_connector *connector) | |||
| 769 | { | 769 | { |
| 770 | struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); | 770 | struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); |
| 771 | 771 | ||
| 772 | if (amdgpu_connector->ddc_bus->has_aux) { | 772 | if (amdgpu_connector->ddc_bus && amdgpu_connector->ddc_bus->has_aux) { |
| 773 | drm_dp_aux_unregister(&amdgpu_connector->ddc_bus->aux); | 773 | drm_dp_aux_unregister(&amdgpu_connector->ddc_bus->aux); |
| 774 | amdgpu_connector->ddc_bus->has_aux = false; | 774 | amdgpu_connector->ddc_bus->has_aux = false; |
| 775 | } | 775 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 71ed27eb3dde..02ff0747197c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | |||
| @@ -735,8 +735,20 @@ static struct pci_driver amdgpu_kms_pci_driver = { | |||
| 735 | 735 | ||
| 736 | static int __init amdgpu_init(void) | 736 | static int __init amdgpu_init(void) |
| 737 | { | 737 | { |
| 738 | amdgpu_sync_init(); | 738 | int r; |
| 739 | amdgpu_fence_slab_init(); | 739 | |
| 740 | r = amdgpu_sync_init(); | ||
| 741 | if (r) | ||
| 742 | goto error_sync; | ||
| 743 | |||
| 744 | r = amdgpu_fence_slab_init(); | ||
| 745 | if (r) | ||
| 746 | goto error_fence; | ||
| 747 | |||
| 748 | r = amd_sched_fence_slab_init(); | ||
| 749 | if (r) | ||
| 750 | goto error_sched; | ||
| 751 | |||
| 740 | if (vgacon_text_force()) { | 752 | if (vgacon_text_force()) { |
| 741 | DRM_ERROR("VGACON disables amdgpu kernel modesetting.\n"); | 753 | DRM_ERROR("VGACON disables amdgpu kernel modesetting.\n"); |
| 742 | return -EINVAL; | 754 | return -EINVAL; |
| @@ -748,6 +760,15 @@ static int __init amdgpu_init(void) | |||
| 748 | amdgpu_register_atpx_handler(); | 760 | amdgpu_register_atpx_handler(); |
| 749 | /* let modprobe override vga console setting */ | 761 | /* let modprobe override vga console setting */ |
| 750 | return drm_pci_init(driver, pdriver); | 762 | return drm_pci_init(driver, pdriver); |
| 763 | |||
| 764 | error_sched: | ||
| 765 | amdgpu_fence_slab_fini(); | ||
| 766 | |||
| 767 | error_fence: | ||
| 768 | amdgpu_sync_fini(); | ||
| 769 | |||
| 770 | error_sync: | ||
| 771 | return r; | ||
| 751 | } | 772 | } |
| 752 | 773 | ||
| 753 | static void __exit amdgpu_exit(void) | 774 | static void __exit amdgpu_exit(void) |
| @@ -756,6 +777,7 @@ static void __exit amdgpu_exit(void) | |||
| 756 | drm_pci_exit(driver, pdriver); | 777 | drm_pci_exit(driver, pdriver); |
| 757 | amdgpu_unregister_atpx_handler(); | 778 | amdgpu_unregister_atpx_handler(); |
| 758 | amdgpu_sync_fini(); | 779 | amdgpu_sync_fini(); |
| 780 | amd_sched_fence_slab_fini(); | ||
| 759 | amdgpu_fence_slab_fini(); | 781 | amdgpu_fence_slab_fini(); |
| 760 | } | 782 | } |
| 761 | 783 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 203d98b00555..3938fca1ea8e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | |||
| @@ -99,6 +99,8 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags) | |||
| 99 | 99 | ||
| 100 | if ((amdgpu_runtime_pm != 0) && | 100 | if ((amdgpu_runtime_pm != 0) && |
| 101 | amdgpu_has_atpx() && | 101 | amdgpu_has_atpx() && |
| 102 | (amdgpu_is_atpx_hybrid() || | ||
| 103 | amdgpu_has_atpx_dgpu_power_cntl()) && | ||
| 102 | ((flags & AMD_IS_APU) == 0)) | 104 | ((flags & AMD_IS_APU) == 0)) |
| 103 | flags |= AMD_IS_PX; | 105 | flags |= AMD_IS_PX; |
| 104 | 106 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 7c13090df7c0..f62f1a74f890 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c | |||
| @@ -80,7 +80,9 @@ | |||
| 80 | #include "dce_virtual.h" | 80 | #include "dce_virtual.h" |
| 81 | 81 | ||
| 82 | MODULE_FIRMWARE("amdgpu/topaz_smc.bin"); | 82 | MODULE_FIRMWARE("amdgpu/topaz_smc.bin"); |
| 83 | MODULE_FIRMWARE("amdgpu/topaz_k_smc.bin"); | ||
| 83 | MODULE_FIRMWARE("amdgpu/tonga_smc.bin"); | 84 | MODULE_FIRMWARE("amdgpu/tonga_smc.bin"); |
| 85 | MODULE_FIRMWARE("amdgpu/tonga_k_smc.bin"); | ||
| 84 | MODULE_FIRMWARE("amdgpu/fiji_smc.bin"); | 86 | MODULE_FIRMWARE("amdgpu/fiji_smc.bin"); |
| 85 | MODULE_FIRMWARE("amdgpu/polaris10_smc.bin"); | 87 | MODULE_FIRMWARE("amdgpu/polaris10_smc.bin"); |
| 86 | MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin"); | 88 | MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin"); |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.c index fb6c6f6106d5..29d0319b22e6 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_thermal.c | |||
| @@ -30,7 +30,7 @@ int smu7_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr, | |||
| 30 | struct phm_fan_speed_info *fan_speed_info) | 30 | struct phm_fan_speed_info *fan_speed_info) |
| 31 | { | 31 | { |
| 32 | if (hwmgr->thermal_controller.fanInfo.bNoFan) | 32 | if (hwmgr->thermal_controller.fanInfo.bNoFan) |
| 33 | return 0; | 33 | return -ENODEV; |
| 34 | 34 | ||
| 35 | fan_speed_info->supports_percent_read = true; | 35 | fan_speed_info->supports_percent_read = true; |
| 36 | fan_speed_info->supports_percent_write = true; | 36 | fan_speed_info->supports_percent_write = true; |
| @@ -60,7 +60,7 @@ int smu7_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr, | |||
| 60 | uint64_t tmp64; | 60 | uint64_t tmp64; |
| 61 | 61 | ||
| 62 | if (hwmgr->thermal_controller.fanInfo.bNoFan) | 62 | if (hwmgr->thermal_controller.fanInfo.bNoFan) |
| 63 | return 0; | 63 | return -ENODEV; |
| 64 | 64 | ||
| 65 | duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, | 65 | duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, |
| 66 | CG_FDO_CTRL1, FMAX_DUTY100); | 66 | CG_FDO_CTRL1, FMAX_DUTY100); |
| @@ -89,7 +89,7 @@ int smu7_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed) | |||
| 89 | if (hwmgr->thermal_controller.fanInfo.bNoFan || | 89 | if (hwmgr->thermal_controller.fanInfo.bNoFan || |
| 90 | (hwmgr->thermal_controller.fanInfo. | 90 | (hwmgr->thermal_controller.fanInfo. |
| 91 | ucTachometerPulsesPerRevolution == 0)) | 91 | ucTachometerPulsesPerRevolution == 0)) |
| 92 | return 0; | 92 | return -ENODEV; |
| 93 | 93 | ||
| 94 | tach_period = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, | 94 | tach_period = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, |
| 95 | CG_TACH_STATUS, TACH_PERIOD); | 95 | CG_TACH_STATUS, TACH_PERIOD); |
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index 910b8d5b21c5..ffe1f85ce300 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | |||
| @@ -34,9 +34,6 @@ static bool amd_sched_entity_is_ready(struct amd_sched_entity *entity); | |||
| 34 | static void amd_sched_wakeup(struct amd_gpu_scheduler *sched); | 34 | static void amd_sched_wakeup(struct amd_gpu_scheduler *sched); |
| 35 | static void amd_sched_process_job(struct fence *f, struct fence_cb *cb); | 35 | static void amd_sched_process_job(struct fence *f, struct fence_cb *cb); |
| 36 | 36 | ||
| 37 | struct kmem_cache *sched_fence_slab; | ||
| 38 | atomic_t sched_fence_slab_ref = ATOMIC_INIT(0); | ||
| 39 | |||
| 40 | /* Initialize a given run queue struct */ | 37 | /* Initialize a given run queue struct */ |
| 41 | static void amd_sched_rq_init(struct amd_sched_rq *rq) | 38 | static void amd_sched_rq_init(struct amd_sched_rq *rq) |
| 42 | { | 39 | { |
| @@ -618,13 +615,6 @@ int amd_sched_init(struct amd_gpu_scheduler *sched, | |||
| 618 | INIT_LIST_HEAD(&sched->ring_mirror_list); | 615 | INIT_LIST_HEAD(&sched->ring_mirror_list); |
| 619 | spin_lock_init(&sched->job_list_lock); | 616 | spin_lock_init(&sched->job_list_lock); |
| 620 | atomic_set(&sched->hw_rq_count, 0); | 617 | atomic_set(&sched->hw_rq_count, 0); |
| 621 | if (atomic_inc_return(&sched_fence_slab_ref) == 1) { | ||
| 622 | sched_fence_slab = kmem_cache_create( | ||
| 623 | "amd_sched_fence", sizeof(struct amd_sched_fence), 0, | ||
| 624 | SLAB_HWCACHE_ALIGN, NULL); | ||
| 625 | if (!sched_fence_slab) | ||
| 626 | return -ENOMEM; | ||
| 627 | } | ||
| 628 | 618 | ||
| 629 | /* Each scheduler will run on a seperate kernel thread */ | 619 | /* Each scheduler will run on a seperate kernel thread */ |
| 630 | sched->thread = kthread_run(amd_sched_main, sched, sched->name); | 620 | sched->thread = kthread_run(amd_sched_main, sched, sched->name); |
| @@ -645,7 +635,4 @@ void amd_sched_fini(struct amd_gpu_scheduler *sched) | |||
| 645 | { | 635 | { |
| 646 | if (sched->thread) | 636 | if (sched->thread) |
| 647 | kthread_stop(sched->thread); | 637 | kthread_stop(sched->thread); |
| 648 | rcu_barrier(); | ||
| 649 | if (atomic_dec_and_test(&sched_fence_slab_ref)) | ||
| 650 | kmem_cache_destroy(sched_fence_slab); | ||
| 651 | } | 638 | } |
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h index 7cbbbfb502ef..51068e6c3d9a 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | |||
| @@ -30,9 +30,6 @@ | |||
| 30 | struct amd_gpu_scheduler; | 30 | struct amd_gpu_scheduler; |
| 31 | struct amd_sched_rq; | 31 | struct amd_sched_rq; |
| 32 | 32 | ||
| 33 | extern struct kmem_cache *sched_fence_slab; | ||
| 34 | extern atomic_t sched_fence_slab_ref; | ||
| 35 | |||
| 36 | /** | 33 | /** |
| 37 | * A scheduler entity is a wrapper around a job queue or a group | 34 | * A scheduler entity is a wrapper around a job queue or a group |
| 38 | * of other entities. Entities take turns emitting jobs from their | 35 | * of other entities. Entities take turns emitting jobs from their |
| @@ -145,6 +142,9 @@ void amd_sched_entity_fini(struct amd_gpu_scheduler *sched, | |||
| 145 | struct amd_sched_entity *entity); | 142 | struct amd_sched_entity *entity); |
| 146 | void amd_sched_entity_push_job(struct amd_sched_job *sched_job); | 143 | void amd_sched_entity_push_job(struct amd_sched_job *sched_job); |
| 147 | 144 | ||
| 145 | int amd_sched_fence_slab_init(void); | ||
| 146 | void amd_sched_fence_slab_fini(void); | ||
| 147 | |||
| 148 | struct amd_sched_fence *amd_sched_fence_create( | 148 | struct amd_sched_fence *amd_sched_fence_create( |
| 149 | struct amd_sched_entity *s_entity, void *owner); | 149 | struct amd_sched_entity *s_entity, void *owner); |
| 150 | void amd_sched_fence_scheduled(struct amd_sched_fence *fence); | 150 | void amd_sched_fence_scheduled(struct amd_sched_fence *fence); |
diff --git a/drivers/gpu/drm/amd/scheduler/sched_fence.c b/drivers/gpu/drm/amd/scheduler/sched_fence.c index 3653b5a40494..88fc2d662579 100644 --- a/drivers/gpu/drm/amd/scheduler/sched_fence.c +++ b/drivers/gpu/drm/amd/scheduler/sched_fence.c | |||
| @@ -27,6 +27,25 @@ | |||
| 27 | #include <drm/drmP.h> | 27 | #include <drm/drmP.h> |
| 28 | #include "gpu_scheduler.h" | 28 | #include "gpu_scheduler.h" |
| 29 | 29 | ||
| 30 | static struct kmem_cache *sched_fence_slab; | ||
| 31 | |||
| 32 | int amd_sched_fence_slab_init(void) | ||
| 33 | { | ||
| 34 | sched_fence_slab = kmem_cache_create( | ||
| 35 | "amd_sched_fence", sizeof(struct amd_sched_fence), 0, | ||
| 36 | SLAB_HWCACHE_ALIGN, NULL); | ||
| 37 | if (!sched_fence_slab) | ||
| 38 | return -ENOMEM; | ||
| 39 | |||
| 40 | return 0; | ||
| 41 | } | ||
| 42 | |||
| 43 | void amd_sched_fence_slab_fini(void) | ||
| 44 | { | ||
| 45 | rcu_barrier(); | ||
| 46 | kmem_cache_destroy(sched_fence_slab); | ||
| 47 | } | ||
| 48 | |||
| 30 | struct amd_sched_fence *amd_sched_fence_create(struct amd_sched_entity *entity, | 49 | struct amd_sched_fence *amd_sched_fence_create(struct amd_sched_entity *entity, |
| 31 | void *owner) | 50 | void *owner) |
| 32 | { | 51 | { |
