diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2014-04-10 22:29:01 -0400 |
---|---|---|
committer | Christian König <christian.koenig@amd.com> | 2014-04-17 07:59:38 -0400 |
commit | 90c4cde9d5a2bb6239cb3e253bb3832ed89dc75c (patch) | |
tree | b4a0f87eee618de1fb021e8019a9cda9f1b64b2a | |
parent | 57700ad1f2f21d5d7ab7ee0e58d11b5954852434 (diff) |
drm/radeon: fix runpm handling on APUs (v4)
Don't try and runtime suspend the APU in PX systems. We
only want to power down the dGPU.
v2: fix harder
v3: fix stupid typo
v4: consolidate runpm enablement to a single flag
bugs:
https://bugs.freedesktop.org/show_bug.cgi?id=75127
https://bugzilla.kernel.org/show_bug.cgi?id=72701
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atpx_handler.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_drv.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_family.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_kms.c | 14 |
6 files changed, 27 insertions, 34 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index f21db7a0b34d..7014bdd688ce 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -2321,6 +2321,7 @@ struct radeon_device { | |||
2321 | bool have_disp_power_ref; | 2321 | bool have_disp_power_ref; |
2322 | }; | 2322 | }; |
2323 | 2323 | ||
2324 | bool radeon_is_px(struct drm_device *dev); | ||
2324 | int radeon_device_init(struct radeon_device *rdev, | 2325 | int radeon_device_init(struct radeon_device *rdev, |
2325 | struct drm_device *ddev, | 2326 | struct drm_device *ddev, |
2326 | struct pci_dev *pdev, | 2327 | struct pci_dev *pdev, |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index fa9a9c02751e..dedea72f48c4 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
@@ -59,7 +59,7 @@ struct atpx_mux { | |||
59 | u16 mux; | 59 | u16 mux; |
60 | } __packed; | 60 | } __packed; |
61 | 61 | ||
62 | bool radeon_is_px(void) { | 62 | bool radeon_has_atpx(void) { |
63 | return radeon_atpx_priv.atpx_detected; | 63 | return radeon_atpx_priv.atpx_detected; |
64 | } | 64 | } |
65 | 65 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 835516d2d257..511fe26198e4 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -102,11 +102,14 @@ static const char radeon_family_name[][16] = { | |||
102 | "LAST", | 102 | "LAST", |
103 | }; | 103 | }; |
104 | 104 | ||
105 | #if defined(CONFIG_VGA_SWITCHEROO) | 105 | bool radeon_is_px(struct drm_device *dev) |
106 | bool radeon_is_px(void); | 106 | { |
107 | #else | 107 | struct radeon_device *rdev = dev->dev_private; |
108 | static inline bool radeon_is_px(void) { return false; } | 108 | |
109 | #endif | 109 | if (rdev->flags & RADEON_IS_PX) |
110 | return true; | ||
111 | return false; | ||
112 | } | ||
110 | 113 | ||
111 | /** | 114 | /** |
112 | * radeon_program_register_sequence - program an array of registers. | 115 | * radeon_program_register_sequence - program an array of registers. |
@@ -1082,7 +1085,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero | |||
1082 | { | 1085 | { |
1083 | struct drm_device *dev = pci_get_drvdata(pdev); | 1086 | struct drm_device *dev = pci_get_drvdata(pdev); |
1084 | 1087 | ||
1085 | if (radeon_is_px() && state == VGA_SWITCHEROO_OFF) | 1088 | if (radeon_is_px(dev) && state == VGA_SWITCHEROO_OFF) |
1086 | return; | 1089 | return; |
1087 | 1090 | ||
1088 | if (state == VGA_SWITCHEROO_ON) { | 1091 | if (state == VGA_SWITCHEROO_ON) { |
@@ -1301,9 +1304,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
1301 | * ignore it */ | 1304 | * ignore it */ |
1302 | vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); | 1305 | vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); |
1303 | 1306 | ||
1304 | if (radeon_runtime_pm == 1) | 1307 | if (rdev->flags & RADEON_IS_PX) |
1305 | runtime = true; | ||
1306 | if ((radeon_runtime_pm == -1) && radeon_is_px()) | ||
1307 | runtime = true; | 1308 | runtime = true; |
1308 | vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, runtime); | 1309 | vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, runtime); |
1309 | if (runtime) | 1310 | if (runtime) |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index d0eba48dd74e..25127ba44ed9 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -115,6 +115,7 @@ extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, | |||
115 | unsigned int flags, | 115 | unsigned int flags, |
116 | int *vpos, int *hpos, ktime_t *stime, | 116 | int *vpos, int *hpos, ktime_t *stime, |
117 | ktime_t *etime); | 117 | ktime_t *etime); |
118 | extern bool radeon_is_px(struct drm_device *dev); | ||
118 | extern const struct drm_ioctl_desc radeon_ioctls_kms[]; | 119 | extern const struct drm_ioctl_desc radeon_ioctls_kms[]; |
119 | extern int radeon_max_kms_ioctl; | 120 | extern int radeon_max_kms_ioctl; |
120 | int radeon_mmap(struct file *filp, struct vm_area_struct *vma); | 121 | int radeon_mmap(struct file *filp, struct vm_area_struct *vma); |
@@ -144,11 +145,9 @@ void radeon_debugfs_cleanup(struct drm_minor *minor); | |||
144 | #if defined(CONFIG_VGA_SWITCHEROO) | 145 | #if defined(CONFIG_VGA_SWITCHEROO) |
145 | void radeon_register_atpx_handler(void); | 146 | void radeon_register_atpx_handler(void); |
146 | void radeon_unregister_atpx_handler(void); | 147 | void radeon_unregister_atpx_handler(void); |
147 | bool radeon_is_px(void); | ||
148 | #else | 148 | #else |
149 | static inline void radeon_register_atpx_handler(void) {} | 149 | static inline void radeon_register_atpx_handler(void) {} |
150 | static inline void radeon_unregister_atpx_handler(void) {} | 150 | static inline void radeon_unregister_atpx_handler(void) {} |
151 | static inline bool radeon_is_px(void) { return false; } | ||
152 | #endif | 151 | #endif |
153 | 152 | ||
154 | int radeon_no_wb; | 153 | int radeon_no_wb; |
@@ -405,12 +404,7 @@ static int radeon_pmops_runtime_suspend(struct device *dev) | |||
405 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | 404 | struct drm_device *drm_dev = pci_get_drvdata(pdev); |
406 | int ret; | 405 | int ret; |
407 | 406 | ||
408 | if (radeon_runtime_pm == 0) { | 407 | if (!radeon_is_px(drm_dev)) { |
409 | pm_runtime_forbid(dev); | ||
410 | return -EBUSY; | ||
411 | } | ||
412 | |||
413 | if (radeon_runtime_pm == -1 && !radeon_is_px()) { | ||
414 | pm_runtime_forbid(dev); | 408 | pm_runtime_forbid(dev); |
415 | return -EBUSY; | 409 | return -EBUSY; |
416 | } | 410 | } |
@@ -434,10 +428,7 @@ static int radeon_pmops_runtime_resume(struct device *dev) | |||
434 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | 428 | struct drm_device *drm_dev = pci_get_drvdata(pdev); |
435 | int ret; | 429 | int ret; |
436 | 430 | ||
437 | if (radeon_runtime_pm == 0) | 431 | if (!radeon_is_px(drm_dev)) |
438 | return -EINVAL; | ||
439 | |||
440 | if (radeon_runtime_pm == -1 && !radeon_is_px()) | ||
441 | return -EINVAL; | 432 | return -EINVAL; |
442 | 433 | ||
443 | drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; | 434 | drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; |
@@ -462,14 +453,7 @@ static int radeon_pmops_runtime_idle(struct device *dev) | |||
462 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | 453 | struct drm_device *drm_dev = pci_get_drvdata(pdev); |
463 | struct drm_crtc *crtc; | 454 | struct drm_crtc *crtc; |
464 | 455 | ||
465 | if (radeon_runtime_pm == 0) { | 456 | if (!radeon_is_px(drm_dev)) { |
466 | pm_runtime_forbid(dev); | ||
467 | return -EBUSY; | ||
468 | } | ||
469 | |||
470 | /* are we PX enabled? */ | ||
471 | if (radeon_runtime_pm == -1 && !radeon_is_px()) { | ||
472 | DRM_DEBUG_DRIVER("failing to power off - not px\n"); | ||
473 | pm_runtime_forbid(dev); | 457 | pm_runtime_forbid(dev); |
474 | return -EBUSY; | 458 | return -EBUSY; |
475 | } | 459 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h index 614ad549297f..9da5da4ffd17 100644 --- a/drivers/gpu/drm/radeon/radeon_family.h +++ b/drivers/gpu/drm/radeon/radeon_family.h | |||
@@ -115,6 +115,7 @@ enum radeon_chip_flags { | |||
115 | RADEON_NEW_MEMMAP = 0x00400000UL, | 115 | RADEON_NEW_MEMMAP = 0x00400000UL, |
116 | RADEON_IS_PCI = 0x00800000UL, | 116 | RADEON_IS_PCI = 0x00800000UL, |
117 | RADEON_IS_IGPGART = 0x01000000UL, | 117 | RADEON_IS_IGPGART = 0x01000000UL, |
118 | RADEON_IS_PX = 0x02000000UL, | ||
118 | }; | 119 | }; |
119 | 120 | ||
120 | #endif | 121 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 3e49342a20e6..9337820e4d37 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -35,9 +35,9 @@ | |||
35 | #include <linux/pm_runtime.h> | 35 | #include <linux/pm_runtime.h> |
36 | 36 | ||
37 | #if defined(CONFIG_VGA_SWITCHEROO) | 37 | #if defined(CONFIG_VGA_SWITCHEROO) |
38 | bool radeon_is_px(void); | 38 | bool radeon_has_atpx(void); |
39 | #else | 39 | #else |
40 | static inline bool radeon_is_px(void) { return false; } | 40 | static inline bool radeon_has_atpx(void) { return false; } |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | /** | 43 | /** |
@@ -107,6 +107,13 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) | |||
107 | flags |= RADEON_IS_PCI; | 107 | flags |= RADEON_IS_PCI; |
108 | } | 108 | } |
109 | 109 | ||
110 | if (radeon_runtime_pm == 1) | ||
111 | flags |= RADEON_IS_PX; | ||
112 | else if ((radeon_runtime_pm == -1) && | ||
113 | radeon_has_atpx() && | ||
114 | ((flags & RADEON_IS_IGP) == 0)) | ||
115 | flags |= RADEON_IS_PX; | ||
116 | |||
110 | /* radeon_device_init should report only fatal error | 117 | /* radeon_device_init should report only fatal error |
111 | * like memory allocation failure or iomapping failure, | 118 | * like memory allocation failure or iomapping failure, |
112 | * or memory manager initialization failure, it must | 119 | * or memory manager initialization failure, it must |
@@ -137,8 +144,7 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) | |||
137 | "Error during ACPI methods call\n"); | 144 | "Error during ACPI methods call\n"); |
138 | } | 145 | } |
139 | 146 | ||
140 | if ((radeon_runtime_pm == 1) || | 147 | if (radeon_is_px(dev)) { |
141 | ((radeon_runtime_pm == -1) && radeon_is_px())) { | ||
142 | pm_runtime_use_autosuspend(dev->dev); | 148 | pm_runtime_use_autosuspend(dev->dev); |
143 | pm_runtime_set_autosuspend_delay(dev->dev, 5000); | 149 | pm_runtime_set_autosuspend_delay(dev->dev, 5000); |
144 | pm_runtime_set_active(dev->dev); | 150 | pm_runtime_set_active(dev->dev); |