mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
Merge branch 'drm-fixes-4.3' of git://people.freedesktop.org/~agd5f/linux into drm-fixes
radeon and amdgpu fixes for 4.3. Highlights: - Move pm sysfs setup later in the driver init process to avoid problems with laptop scripts attempting to change pm settings before the driver has finished setting up the pm hardware. - Fix console restore if a drm app (e.g. X) is forcibly killed - Flag iceland support as experimental for now - Misc bug fixes * 'drm-fixes-4.3' of git://people.freedesktop.org/~agd5f/linux: drm/amdgpu: fix memory leak in amdgpu_vm_update_page_directory drm/amdgpu: fix 32-bit compiler warning drm/amdgpu: flag iceland as experimental drm/amdgpu: check before checking pci bridge registers drm/amdgpu: fix num_crtc on CZ drm/amdgpu: restore the fbdev mode in lastclose drm/radeon: restore the fbdev mode in lastclose drm/radeon: add quirk for ASUS R7 370 drm/amdgpu: add pm sysfs files late drm/radeon: add pm sysfs files late
This commit is contained in:
commit
e87d68dd61
18 changed files with 118 additions and 59 deletions
|
@ -177,7 +177,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
|
|||
|
||||
/* get chunks */
|
||||
INIT_LIST_HEAD(&p->validated);
|
||||
chunk_array_user = (uint64_t __user *)(cs->in.chunks);
|
||||
chunk_array_user = (uint64_t __user *)(unsigned long)(cs->in.chunks);
|
||||
if (copy_from_user(chunk_array, chunk_array_user,
|
||||
sizeof(uint64_t)*cs->in.num_chunks)) {
|
||||
ret = -EFAULT;
|
||||
|
@ -197,7 +197,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
|
|||
struct drm_amdgpu_cs_chunk user_chunk;
|
||||
uint32_t __user *cdata;
|
||||
|
||||
chunk_ptr = (void __user *)chunk_array[i];
|
||||
chunk_ptr = (void __user *)(unsigned long)chunk_array[i];
|
||||
if (copy_from_user(&user_chunk, chunk_ptr,
|
||||
sizeof(struct drm_amdgpu_cs_chunk))) {
|
||||
ret = -EFAULT;
|
||||
|
@ -208,7 +208,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
|
|||
p->chunks[i].length_dw = user_chunk.length_dw;
|
||||
|
||||
size = p->chunks[i].length_dw;
|
||||
cdata = (void __user *)user_chunk.chunk_data;
|
||||
cdata = (void __user *)(unsigned long)user_chunk.chunk_data;
|
||||
p->chunks[i].user_ptr = cdata;
|
||||
|
||||
p->chunks[i].kdata = drm_malloc_ab(size, sizeof(uint32_t));
|
||||
|
|
|
@ -242,11 +242,11 @@ static struct pci_device_id pciidlist[] = {
|
|||
{0x1002, 0x985F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMD_IS_MOBILITY|AMD_IS_APU},
|
||||
#endif
|
||||
/* topaz */
|
||||
{0x1002, 0x6900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
|
||||
{0x1002, 0x6901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
|
||||
{0x1002, 0x6902, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
|
||||
{0x1002, 0x6903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
|
||||
{0x1002, 0x6907, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ},
|
||||
{0x1002, 0x6900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
|
||||
{0x1002, 0x6901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
|
||||
{0x1002, 0x6902, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
|
||||
{0x1002, 0x6903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
|
||||
{0x1002, 0x6907, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},
|
||||
/* tonga */
|
||||
{0x1002, 0x6920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
|
||||
{0x1002, 0x6921, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},
|
||||
|
|
|
@ -402,3 +402,19 @@ bool amdgpu_fbdev_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj)
|
|||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void amdgpu_fbdev_restore_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_fbdev *afbdev = adev->mode_info.rfbdev;
|
||||
struct drm_fb_helper *fb_helper;
|
||||
int ret;
|
||||
|
||||
if (!afbdev)
|
||||
return;
|
||||
|
||||
fb_helper = &afbdev->helper;
|
||||
|
||||
ret = drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper);
|
||||
if (ret)
|
||||
DRM_DEBUG("failed to restore crtc mode\n");
|
||||
}
|
||||
|
|
|
@ -485,7 +485,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
|
|||
* Outdated mess for old drm with Xorg being in charge (void function now).
|
||||
*/
|
||||
/**
|
||||
* amdgpu_driver_firstopen_kms - drm callback for last close
|
||||
* amdgpu_driver_lastclose_kms - drm callback for last close
|
||||
*
|
||||
* @dev: drm dev pointer
|
||||
*
|
||||
|
@ -493,6 +493,9 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
|
|||
*/
|
||||
void amdgpu_driver_lastclose_kms(struct drm_device *dev)
|
||||
{
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
|
||||
amdgpu_fbdev_restore_mode(adev);
|
||||
vga_switcheroo_process_delayed_switch();
|
||||
}
|
||||
|
||||
|
|
|
@ -567,6 +567,7 @@ void amdgpu_fbdev_fini(struct amdgpu_device *adev);
|
|||
void amdgpu_fbdev_set_suspend(struct amdgpu_device *adev, int state);
|
||||
int amdgpu_fbdev_total_size(struct amdgpu_device *adev);
|
||||
bool amdgpu_fbdev_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj);
|
||||
void amdgpu_fbdev_restore_mode(struct amdgpu_device *adev);
|
||||
|
||||
void amdgpu_fb_output_poll_changed(struct amdgpu_device *adev);
|
||||
|
||||
|
|
|
@ -455,8 +455,10 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
|
|||
return -ENOMEM;
|
||||
|
||||
r = amdgpu_ib_get(ring, NULL, ndw * 4, ib);
|
||||
if (r)
|
||||
if (r) {
|
||||
kfree(ib);
|
||||
return r;
|
||||
}
|
||||
ib->length_dw = 0;
|
||||
|
||||
/* walk over the address space and update the page directory */
|
||||
|
|
|
@ -6185,6 +6185,11 @@ static int ci_dpm_late_init(void *handle)
|
|||
if (!amdgpu_dpm)
|
||||
return 0;
|
||||
|
||||
/* init the sysfs and debugfs files late */
|
||||
ret = amdgpu_pm_sysfs_init(adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ci_set_temperature_range(adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -6232,9 +6237,6 @@ static int ci_dpm_sw_init(void *handle)
|
|||
adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;
|
||||
if (amdgpu_dpm == 1)
|
||||
amdgpu_pm_print_power_states(adev);
|
||||
ret = amdgpu_pm_sysfs_init(adev);
|
||||
if (ret)
|
||||
goto dpm_failed;
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
DRM_INFO("amdgpu: dpm initialized\n");
|
||||
|
||||
|
|
|
@ -1567,6 +1567,9 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
|
|||
int ret, i;
|
||||
u16 tmp16;
|
||||
|
||||
if (pci_is_root_bus(adev->pdev->bus))
|
||||
return;
|
||||
|
||||
if (amdgpu_pcie_gen2 == 0)
|
||||
return;
|
||||
|
||||
|
|
|
@ -596,6 +596,12 @@ static int cz_dpm_late_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (amdgpu_dpm) {
|
||||
int ret;
|
||||
/* init the sysfs and debugfs files late */
|
||||
ret = amdgpu_pm_sysfs_init(adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* powerdown unused blocks for now */
|
||||
cz_dpm_powergate_uvd(adev, true);
|
||||
cz_dpm_powergate_vce(adev, true);
|
||||
|
@ -632,10 +638,6 @@ static int cz_dpm_sw_init(void *handle)
|
|||
if (amdgpu_dpm == 1)
|
||||
amdgpu_pm_print_power_states(adev);
|
||||
|
||||
ret = amdgpu_pm_sysfs_init(adev);
|
||||
if (ret)
|
||||
goto dpm_init_failed;
|
||||
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
DRM_INFO("amdgpu: dpm initialized\n");
|
||||
|
||||
|
|
|
@ -2888,7 +2888,7 @@ static int dce_v11_0_early_init(void *handle)
|
|||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_CARRIZO:
|
||||
adev->mode_info.num_crtc = 4;
|
||||
adev->mode_info.num_crtc = 3;
|
||||
adev->mode_info.num_hpd = 6;
|
||||
adev->mode_info.num_dig = 9;
|
||||
break;
|
||||
|
|
|
@ -2995,6 +2995,12 @@ static int kv_dpm_late_init(void *handle)
|
|||
{
|
||||
/* powerdown unused blocks for now */
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int ret;
|
||||
|
||||
/* init the sysfs and debugfs files late */
|
||||
ret = amdgpu_pm_sysfs_init(adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
kv_dpm_powergate_acp(adev, true);
|
||||
kv_dpm_powergate_samu(adev, true);
|
||||
|
@ -3038,9 +3044,6 @@ static int kv_dpm_sw_init(void *handle)
|
|||
adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;
|
||||
if (amdgpu_dpm == 1)
|
||||
amdgpu_pm_print_power_states(adev);
|
||||
ret = amdgpu_pm_sysfs_init(adev);
|
||||
if (ret)
|
||||
goto dpm_failed;
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
DRM_INFO("amdgpu: dpm initialized\n");
|
||||
|
||||
|
|
|
@ -1005,6 +1005,9 @@ static void vi_pcie_gen3_enable(struct amdgpu_device *adev)
|
|||
u32 mask;
|
||||
int ret;
|
||||
|
||||
if (pci_is_root_bus(adev->pdev->bus))
|
||||
return;
|
||||
|
||||
if (amdgpu_pcie_gen2 == 0)
|
||||
return;
|
||||
|
||||
|
|
|
@ -1633,18 +1633,8 @@ int radeon_modeset_init(struct radeon_device *rdev)
|
|||
radeon_fbdev_init(rdev);
|
||||
drm_kms_helper_poll_init(rdev->ddev);
|
||||
|
||||
if (rdev->pm.dpm_enabled) {
|
||||
/* do dpm late init */
|
||||
ret = radeon_pm_late_init(rdev);
|
||||
if (ret) {
|
||||
rdev->pm.dpm_enabled = false;
|
||||
DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n");
|
||||
}
|
||||
/* set the dpm state for PX since there won't be
|
||||
* a modeset to call this.
|
||||
*/
|
||||
radeon_pm_compute_clocks(rdev);
|
||||
}
|
||||
/* do pm late init */
|
||||
ret = radeon_pm_late_init(rdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -397,3 +397,19 @@ void radeon_fb_remove_connector(struct radeon_device *rdev, struct drm_connector
|
|||
{
|
||||
drm_fb_helper_remove_one_connector(&rdev->mode_info.rfbdev->helper, connector);
|
||||
}
|
||||
|
||||
void radeon_fbdev_restore_mode(struct radeon_device *rdev)
|
||||
{
|
||||
struct radeon_fbdev *rfbdev = rdev->mode_info.rfbdev;
|
||||
struct drm_fb_helper *fb_helper;
|
||||
int ret;
|
||||
|
||||
if (!rfbdev)
|
||||
return;
|
||||
|
||||
fb_helper = &rfbdev->helper;
|
||||
|
||||
ret = drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper);
|
||||
if (ret)
|
||||
DRM_DEBUG("failed to restore crtc mode\n");
|
||||
}
|
||||
|
|
|
@ -598,7 +598,7 @@ static int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file
|
|||
* Outdated mess for old drm with Xorg being in charge (void function now).
|
||||
*/
|
||||
/**
|
||||
* radeon_driver_firstopen_kms - drm callback for last close
|
||||
* radeon_driver_lastclose_kms - drm callback for last close
|
||||
*
|
||||
* @dev: drm dev pointer
|
||||
*
|
||||
|
@ -606,6 +606,9 @@ static int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file
|
|||
*/
|
||||
void radeon_driver_lastclose_kms(struct drm_device *dev)
|
||||
{
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
|
||||
radeon_fbdev_restore_mode(rdev);
|
||||
vga_switcheroo_process_delayed_switch();
|
||||
}
|
||||
|
||||
|
|
|
@ -980,6 +980,7 @@ int radeon_fbdev_init(struct radeon_device *rdev);
|
|||
void radeon_fbdev_fini(struct radeon_device *rdev);
|
||||
void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state);
|
||||
bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj);
|
||||
void radeon_fbdev_restore_mode(struct radeon_device *rdev);
|
||||
|
||||
void radeon_fb_output_poll_changed(struct radeon_device *rdev);
|
||||
|
||||
|
|
|
@ -1326,14 +1326,6 @@ static int radeon_pm_init_old(struct radeon_device *rdev)
|
|||
INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler);
|
||||
|
||||
if (rdev->pm.num_power_states > 1) {
|
||||
/* where's the best place to put these? */
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_profile);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for power profile\n");
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_method);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for power method\n");
|
||||
|
||||
if (radeon_debugfs_pm_init(rdev)) {
|
||||
DRM_ERROR("Failed to register debugfs file for PM!\n");
|
||||
}
|
||||
|
@ -1391,20 +1383,6 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev)
|
|||
goto dpm_failed;
|
||||
rdev->pm.dpm_enabled = true;
|
||||
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for dpm state\n");
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for dpm state\n");
|
||||
/* XXX: these are noops for dpm but are here for backwards compat */
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_profile);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for power profile\n");
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_method);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for power method\n");
|
||||
|
||||
if (radeon_debugfs_pm_init(rdev)) {
|
||||
DRM_ERROR("Failed to register debugfs file for dpm!\n");
|
||||
}
|
||||
|
@ -1545,9 +1523,44 @@ int radeon_pm_late_init(struct radeon_device *rdev)
|
|||
int ret = 0;
|
||||
|
||||
if (rdev->pm.pm_method == PM_METHOD_DPM) {
|
||||
mutex_lock(&rdev->pm.mutex);
|
||||
ret = radeon_dpm_late_enable(rdev);
|
||||
mutex_unlock(&rdev->pm.mutex);
|
||||
if (rdev->pm.dpm_enabled) {
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for dpm state\n");
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for dpm state\n");
|
||||
/* XXX: these are noops for dpm but are here for backwards compat */
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_profile);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for power profile\n");
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_method);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for power method\n");
|
||||
|
||||
mutex_lock(&rdev->pm.mutex);
|
||||
ret = radeon_dpm_late_enable(rdev);
|
||||
mutex_unlock(&rdev->pm.mutex);
|
||||
if (ret) {
|
||||
rdev->pm.dpm_enabled = false;
|
||||
DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n");
|
||||
} else {
|
||||
/* set the dpm state for PX since there won't be
|
||||
* a modeset to call this.
|
||||
*/
|
||||
radeon_pm_compute_clocks(rdev);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (rdev->pm.num_power_states > 1) {
|
||||
/* where's the best place to put these? */
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_profile);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for power profile\n");
|
||||
ret = device_create_file(rdev->dev, &dev_attr_power_method);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to create device file for power method\n");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -2928,6 +2928,7 @@ static struct si_dpm_quirk si_dpm_quirk_list[] = {
|
|||
{ PCI_VENDOR_ID_ATI, 0x6811, 0x174b, 0xe271, 0, 120000 },
|
||||
{ PCI_VENDOR_ID_ATI, 0x6810, 0x174b, 0xe271, 85000, 90000 },
|
||||
{ PCI_VENDOR_ID_ATI, 0x6811, 0x1762, 0x2015, 0, 120000 },
|
||||
{ PCI_VENDOR_ID_ATI, 0x6811, 0x1043, 0x2015, 0, 120000 },
|
||||
{ 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue