Commit 672c9891 authored by Dave Airlie's avatar Dave Airlie

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
parents bc33b0ca 245ae5e9
...@@ -795,10 +795,19 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, ...@@ -795,10 +795,19 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
if (!adev->pm.fw) { if (!adev->pm.fw) {
switch (adev->asic_type) { switch (adev->asic_type) {
case CHIP_TOPAZ: case CHIP_TOPAZ:
strcpy(fw_name, "amdgpu/topaz_smc.bin"); if (((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x81)) ||
((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x83)) ||
((adev->pdev->device == 0x6907) && (adev->pdev->revision == 0x87)))
strcpy(fw_name, "amdgpu/topaz_k_smc.bin");
else
strcpy(fw_name, "amdgpu/topaz_smc.bin");
break; break;
case CHIP_TONGA: case CHIP_TONGA:
strcpy(fw_name, "amdgpu/tonga_smc.bin"); if (((adev->pdev->device == 0x6939) && (adev->pdev->revision == 0xf1)) ||
((adev->pdev->device == 0x6938) && (adev->pdev->revision == 0xf1)))
strcpy(fw_name, "amdgpu/tonga_k_smc.bin");
else
strcpy(fw_name, "amdgpu/tonga_smc.bin");
break; break;
case CHIP_FIJI: case CHIP_FIJI:
strcpy(fw_name, "amdgpu/fiji_smc.bin"); strcpy(fw_name, "amdgpu/fiji_smc.bin");
......
...@@ -769,7 +769,7 @@ static void amdgpu_connector_unregister(struct drm_connector *connector) ...@@ -769,7 +769,7 @@ static void amdgpu_connector_unregister(struct drm_connector *connector)
{ {
struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
if (amdgpu_connector->ddc_bus->has_aux) { if (amdgpu_connector->ddc_bus && amdgpu_connector->ddc_bus->has_aux) {
drm_dp_aux_unregister(&amdgpu_connector->ddc_bus->aux); drm_dp_aux_unregister(&amdgpu_connector->ddc_bus->aux);
amdgpu_connector->ddc_bus->has_aux = false; amdgpu_connector->ddc_bus->has_aux = false;
} }
......
...@@ -735,8 +735,20 @@ static struct pci_driver amdgpu_kms_pci_driver = { ...@@ -735,8 +735,20 @@ static struct pci_driver amdgpu_kms_pci_driver = {
static int __init amdgpu_init(void) static int __init amdgpu_init(void)
{ {
amdgpu_sync_init(); int r;
amdgpu_fence_slab_init();
r = amdgpu_sync_init();
if (r)
goto error_sync;
r = amdgpu_fence_slab_init();
if (r)
goto error_fence;
r = amd_sched_fence_slab_init();
if (r)
goto error_sched;
if (vgacon_text_force()) { if (vgacon_text_force()) {
DRM_ERROR("VGACON disables amdgpu kernel modesetting.\n"); DRM_ERROR("VGACON disables amdgpu kernel modesetting.\n");
return -EINVAL; return -EINVAL;
...@@ -748,6 +760,15 @@ static int __init amdgpu_init(void) ...@@ -748,6 +760,15 @@ static int __init amdgpu_init(void)
amdgpu_register_atpx_handler(); amdgpu_register_atpx_handler();
/* let modprobe override vga console setting */ /* let modprobe override vga console setting */
return drm_pci_init(driver, pdriver); return drm_pci_init(driver, pdriver);
error_sched:
amdgpu_fence_slab_fini();
error_fence:
amdgpu_sync_fini();
error_sync:
return r;
} }
static void __exit amdgpu_exit(void) static void __exit amdgpu_exit(void)
...@@ -756,6 +777,7 @@ static void __exit amdgpu_exit(void) ...@@ -756,6 +777,7 @@ static void __exit amdgpu_exit(void)
drm_pci_exit(driver, pdriver); drm_pci_exit(driver, pdriver);
amdgpu_unregister_atpx_handler(); amdgpu_unregister_atpx_handler();
amdgpu_sync_fini(); amdgpu_sync_fini();
amd_sched_fence_slab_fini();
amdgpu_fence_slab_fini(); amdgpu_fence_slab_fini();
} }
......
...@@ -99,6 +99,8 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags) ...@@ -99,6 +99,8 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags)
if ((amdgpu_runtime_pm != 0) && if ((amdgpu_runtime_pm != 0) &&
amdgpu_has_atpx() && amdgpu_has_atpx() &&
(amdgpu_is_atpx_hybrid() ||
amdgpu_has_atpx_dgpu_power_cntl()) &&
((flags & AMD_IS_APU) == 0)) ((flags & AMD_IS_APU) == 0))
flags |= AMD_IS_PX; flags |= AMD_IS_PX;
......
...@@ -80,7 +80,9 @@ ...@@ -80,7 +80,9 @@
#include "dce_virtual.h" #include "dce_virtual.h"
MODULE_FIRMWARE("amdgpu/topaz_smc.bin"); MODULE_FIRMWARE("amdgpu/topaz_smc.bin");
MODULE_FIRMWARE("amdgpu/topaz_k_smc.bin");
MODULE_FIRMWARE("amdgpu/tonga_smc.bin"); MODULE_FIRMWARE("amdgpu/tonga_smc.bin");
MODULE_FIRMWARE("amdgpu/tonga_k_smc.bin");
MODULE_FIRMWARE("amdgpu/fiji_smc.bin"); MODULE_FIRMWARE("amdgpu/fiji_smc.bin");
MODULE_FIRMWARE("amdgpu/polaris10_smc.bin"); MODULE_FIRMWARE("amdgpu/polaris10_smc.bin");
MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin"); MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin");
......
...@@ -30,7 +30,7 @@ int smu7_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr, ...@@ -30,7 +30,7 @@ int smu7_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr,
struct phm_fan_speed_info *fan_speed_info) struct phm_fan_speed_info *fan_speed_info)
{ {
if (hwmgr->thermal_controller.fanInfo.bNoFan) if (hwmgr->thermal_controller.fanInfo.bNoFan)
return 0; return -ENODEV;
fan_speed_info->supports_percent_read = true; fan_speed_info->supports_percent_read = true;
fan_speed_info->supports_percent_write = true; fan_speed_info->supports_percent_write = true;
...@@ -60,7 +60,7 @@ int smu7_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr, ...@@ -60,7 +60,7 @@ int smu7_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr,
uint64_t tmp64; uint64_t tmp64;
if (hwmgr->thermal_controller.fanInfo.bNoFan) if (hwmgr->thermal_controller.fanInfo.bNoFan)
return 0; return -ENODEV;
duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
CG_FDO_CTRL1, FMAX_DUTY100); 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,7 +89,7 @@ int smu7_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
if (hwmgr->thermal_controller.fanInfo.bNoFan || if (hwmgr->thermal_controller.fanInfo.bNoFan ||
(hwmgr->thermal_controller.fanInfo. (hwmgr->thermal_controller.fanInfo.
ucTachometerPulsesPerRevolution == 0)) ucTachometerPulsesPerRevolution == 0))
return 0; return -ENODEV;
tach_period = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, tach_period = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
CG_TACH_STATUS, TACH_PERIOD); CG_TACH_STATUS, TACH_PERIOD);
......
...@@ -34,9 +34,6 @@ static bool amd_sched_entity_is_ready(struct amd_sched_entity *entity); ...@@ -34,9 +34,6 @@ static bool amd_sched_entity_is_ready(struct amd_sched_entity *entity);
static void amd_sched_wakeup(struct amd_gpu_scheduler *sched); static void amd_sched_wakeup(struct amd_gpu_scheduler *sched);
static void amd_sched_process_job(struct fence *f, struct fence_cb *cb); static void amd_sched_process_job(struct fence *f, struct fence_cb *cb);
struct kmem_cache *sched_fence_slab;
atomic_t sched_fence_slab_ref = ATOMIC_INIT(0);
/* Initialize a given run queue struct */ /* Initialize a given run queue struct */
static void amd_sched_rq_init(struct amd_sched_rq *rq) static void amd_sched_rq_init(struct amd_sched_rq *rq)
{ {
...@@ -618,13 +615,6 @@ int amd_sched_init(struct amd_gpu_scheduler *sched, ...@@ -618,13 +615,6 @@ int amd_sched_init(struct amd_gpu_scheduler *sched,
INIT_LIST_HEAD(&sched->ring_mirror_list); INIT_LIST_HEAD(&sched->ring_mirror_list);
spin_lock_init(&sched->job_list_lock); spin_lock_init(&sched->job_list_lock);
atomic_set(&sched->hw_rq_count, 0); atomic_set(&sched->hw_rq_count, 0);
if (atomic_inc_return(&sched_fence_slab_ref) == 1) {
sched_fence_slab = kmem_cache_create(
"amd_sched_fence", sizeof(struct amd_sched_fence), 0,
SLAB_HWCACHE_ALIGN, NULL);
if (!sched_fence_slab)
return -ENOMEM;
}
/* Each scheduler will run on a seperate kernel thread */ /* Each scheduler will run on a seperate kernel thread */
sched->thread = kthread_run(amd_sched_main, sched, sched->name); sched->thread = kthread_run(amd_sched_main, sched, sched->name);
...@@ -645,7 +635,4 @@ void amd_sched_fini(struct amd_gpu_scheduler *sched) ...@@ -645,7 +635,4 @@ void amd_sched_fini(struct amd_gpu_scheduler *sched)
{ {
if (sched->thread) if (sched->thread)
kthread_stop(sched->thread); kthread_stop(sched->thread);
rcu_barrier();
if (atomic_dec_and_test(&sched_fence_slab_ref))
kmem_cache_destroy(sched_fence_slab);
} }
...@@ -30,9 +30,6 @@ ...@@ -30,9 +30,6 @@
struct amd_gpu_scheduler; struct amd_gpu_scheduler;
struct amd_sched_rq; struct amd_sched_rq;
extern struct kmem_cache *sched_fence_slab;
extern atomic_t sched_fence_slab_ref;
/** /**
* A scheduler entity is a wrapper around a job queue or a group * A scheduler entity is a wrapper around a job queue or a group
* of other entities. Entities take turns emitting jobs from their * 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,6 +142,9 @@ void amd_sched_entity_fini(struct amd_gpu_scheduler *sched,
struct amd_sched_entity *entity); struct amd_sched_entity *entity);
void amd_sched_entity_push_job(struct amd_sched_job *sched_job); void amd_sched_entity_push_job(struct amd_sched_job *sched_job);
int amd_sched_fence_slab_init(void);
void amd_sched_fence_slab_fini(void);
struct amd_sched_fence *amd_sched_fence_create( struct amd_sched_fence *amd_sched_fence_create(
struct amd_sched_entity *s_entity, void *owner); struct amd_sched_entity *s_entity, void *owner);
void amd_sched_fence_scheduled(struct amd_sched_fence *fence); void amd_sched_fence_scheduled(struct amd_sched_fence *fence);
......
...@@ -27,6 +27,25 @@ ...@@ -27,6 +27,25 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include "gpu_scheduler.h" #include "gpu_scheduler.h"
static struct kmem_cache *sched_fence_slab;
int amd_sched_fence_slab_init(void)
{
sched_fence_slab = kmem_cache_create(
"amd_sched_fence", sizeof(struct amd_sched_fence), 0,
SLAB_HWCACHE_ALIGN, NULL);
if (!sched_fence_slab)
return -ENOMEM;
return 0;
}
void amd_sched_fence_slab_fini(void)
{
rcu_barrier();
kmem_cache_destroy(sched_fence_slab);
}
struct amd_sched_fence *amd_sched_fence_create(struct amd_sched_entity *entity, struct amd_sched_fence *amd_sched_fence_create(struct amd_sched_entity *entity,
void *owner) void *owner)
{ {
......
...@@ -931,7 +931,7 @@ static void radeon_connector_unregister(struct drm_connector *connector) ...@@ -931,7 +931,7 @@ static void radeon_connector_unregister(struct drm_connector *connector)
{ {
struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector *radeon_connector = to_radeon_connector(connector);
if (radeon_connector->ddc_bus->has_aux) { if (radeon_connector->ddc_bus && radeon_connector->ddc_bus->has_aux) {
drm_dp_aux_unregister(&radeon_connector->ddc_bus->aux); drm_dp_aux_unregister(&radeon_connector->ddc_bus->aux);
radeon_connector->ddc_bus->has_aux = false; radeon_connector->ddc_bus->has_aux = false;
} }
......
...@@ -104,6 +104,14 @@ static const char radeon_family_name[][16] = { ...@@ -104,6 +104,14 @@ static const char radeon_family_name[][16] = {
"LAST", "LAST",
}; };
#if defined(CONFIG_VGA_SWITCHEROO)
bool radeon_has_atpx_dgpu_power_cntl(void);
bool radeon_is_atpx_hybrid(void);
#else
static inline bool radeon_has_atpx_dgpu_power_cntl(void) { return false; }
static inline bool radeon_is_atpx_hybrid(void) { return false; }
#endif
#define RADEON_PX_QUIRK_DISABLE_PX (1 << 0) #define RADEON_PX_QUIRK_DISABLE_PX (1 << 0)
#define RADEON_PX_QUIRK_LONG_WAKEUP (1 << 1) #define RADEON_PX_QUIRK_LONG_WAKEUP (1 << 1)
...@@ -160,6 +168,11 @@ static void radeon_device_handle_px_quirks(struct radeon_device *rdev) ...@@ -160,6 +168,11 @@ static void radeon_device_handle_px_quirks(struct radeon_device *rdev)
if (rdev->px_quirk_flags & RADEON_PX_QUIRK_DISABLE_PX) if (rdev->px_quirk_flags & RADEON_PX_QUIRK_DISABLE_PX)
rdev->flags &= ~RADEON_IS_PX; rdev->flags &= ~RADEON_IS_PX;
/* disable PX is the system doesn't support dGPU power control or hybrid gfx */
if (!radeon_is_atpx_hybrid() &&
!radeon_has_atpx_dgpu_power_cntl())
rdev->flags &= ~RADEON_IS_PX;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment