diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atpx_handler.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_connectors.c | 63 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 52 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 47 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_drv.c | 122 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_ioc32.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_irq_kms.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_kms.c | 26 |
10 files changed, 299 insertions, 36 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 986100a6e5ca..ad54525cfa79 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -98,6 +98,7 @@ extern int radeon_lockup_timeout; | |||
98 | extern int radeon_fastfb; | 98 | extern int radeon_fastfb; |
99 | extern int radeon_dpm; | 99 | extern int radeon_dpm; |
100 | extern int radeon_aspm; | 100 | extern int radeon_aspm; |
101 | extern int radeon_runtime_pm; | ||
101 | 102 | ||
102 | /* | 103 | /* |
103 | * Copy from radeon_drv.h so we don't have to include both and have conflicting | 104 | * Copy from radeon_drv.h so we don't have to include both and have conflicting |
@@ -2212,6 +2213,9 @@ struct radeon_device { | |||
2212 | /* clock, powergating flags */ | 2213 | /* clock, powergating flags */ |
2213 | u32 cg_flags; | 2214 | u32 cg_flags; |
2214 | u32 pg_flags; | 2215 | u32 pg_flags; |
2216 | |||
2217 | struct dev_pm_domain vga_pm_domain; | ||
2218 | bool have_disp_power_ref; | ||
2215 | }; | 2219 | }; |
2216 | 2220 | ||
2217 | int radeon_device_init(struct radeon_device *rdev, | 2221 | int radeon_device_init(struct radeon_device *rdev, |
@@ -2673,8 +2677,8 @@ extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain); | |||
2673 | extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo); | 2677 | extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo); |
2674 | extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base); | 2678 | extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base); |
2675 | extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); | 2679 | extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); |
2676 | extern int radeon_resume_kms(struct drm_device *dev, bool resume); | 2680 | extern int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); |
2677 | extern int radeon_suspend_kms(struct drm_device *dev, bool suspend); | 2681 | extern int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon); |
2678 | extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size); | 2682 | extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size); |
2679 | extern void radeon_program_register_sequence(struct radeon_device *rdev, | 2683 | extern void radeon_program_register_sequence(struct radeon_device *rdev, |
2680 | const u32 *registers, | 2684 | const u32 *registers, |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index d96070bf8388..6153ec18943a 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
@@ -59,6 +59,10 @@ struct atpx_mux { | |||
59 | u16 mux; | 59 | u16 mux; |
60 | } __packed; | 60 | } __packed; |
61 | 61 | ||
62 | bool radeon_is_px(void) { | ||
63 | return radeon_atpx_priv.atpx_detected; | ||
64 | } | ||
65 | |||
62 | /** | 66 | /** |
63 | * radeon_atpx_call - call an ATPX method | 67 | * radeon_atpx_call - call an ATPX method |
64 | * | 68 | * |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 43f7600803c3..5a74b173eb79 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include "radeon.h" | 31 | #include "radeon.h" |
32 | #include "atom.h" | 32 | #include "atom.h" |
33 | 33 | ||
34 | #include <linux/pm_runtime.h> | ||
35 | |||
34 | extern void | 36 | extern void |
35 | radeon_combios_connected_scratch_regs(struct drm_connector *connector, | 37 | radeon_combios_connected_scratch_regs(struct drm_connector *connector, |
36 | struct drm_encoder *encoder, | 38 | struct drm_encoder *encoder, |
@@ -641,6 +643,11 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) | |||
641 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 643 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
642 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | 644 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); |
643 | enum drm_connector_status ret = connector_status_disconnected; | 645 | enum drm_connector_status ret = connector_status_disconnected; |
646 | int r; | ||
647 | |||
648 | r = pm_runtime_get_sync(connector->dev->dev); | ||
649 | if (r < 0) | ||
650 | return connector_status_disconnected; | ||
644 | 651 | ||
645 | if (encoder) { | 652 | if (encoder) { |
646 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 653 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
@@ -666,6 +673,8 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) | |||
666 | /* check acpi lid status ??? */ | 673 | /* check acpi lid status ??? */ |
667 | 674 | ||
668 | radeon_connector_update_scratch_regs(connector, ret); | 675 | radeon_connector_update_scratch_regs(connector, ret); |
676 | pm_runtime_mark_last_busy(connector->dev->dev); | ||
677 | pm_runtime_put_autosuspend(connector->dev->dev); | ||
669 | return ret; | 678 | return ret; |
670 | } | 679 | } |
671 | 680 | ||
@@ -765,6 +774,11 @@ radeon_vga_detect(struct drm_connector *connector, bool force) | |||
765 | struct drm_encoder_helper_funcs *encoder_funcs; | 774 | struct drm_encoder_helper_funcs *encoder_funcs; |
766 | bool dret = false; | 775 | bool dret = false; |
767 | enum drm_connector_status ret = connector_status_disconnected; | 776 | enum drm_connector_status ret = connector_status_disconnected; |
777 | int r; | ||
778 | |||
779 | r = pm_runtime_get_sync(connector->dev->dev); | ||
780 | if (r < 0) | ||
781 | return connector_status_disconnected; | ||
768 | 782 | ||
769 | encoder = radeon_best_single_encoder(connector); | 783 | encoder = radeon_best_single_encoder(connector); |
770 | if (!encoder) | 784 | if (!encoder) |
@@ -805,9 +819,8 @@ radeon_vga_detect(struct drm_connector *connector, bool force) | |||
805 | * detected a monitor via load. | 819 | * detected a monitor via load. |
806 | */ | 820 | */ |
807 | if (radeon_connector->detected_by_load) | 821 | if (radeon_connector->detected_by_load) |
808 | return connector->status; | 822 | ret = connector->status; |
809 | else | 823 | goto out; |
810 | return ret; | ||
811 | } | 824 | } |
812 | 825 | ||
813 | if (radeon_connector->dac_load_detect && encoder) { | 826 | if (radeon_connector->dac_load_detect && encoder) { |
@@ -832,6 +845,11 @@ radeon_vga_detect(struct drm_connector *connector, bool force) | |||
832 | } | 845 | } |
833 | 846 | ||
834 | radeon_connector_update_scratch_regs(connector, ret); | 847 | radeon_connector_update_scratch_regs(connector, ret); |
848 | |||
849 | out: | ||
850 | pm_runtime_mark_last_busy(connector->dev->dev); | ||
851 | pm_runtime_put_autosuspend(connector->dev->dev); | ||
852 | |||
835 | return ret; | 853 | return ret; |
836 | } | 854 | } |
837 | 855 | ||
@@ -888,10 +906,15 @@ radeon_tv_detect(struct drm_connector *connector, bool force) | |||
888 | struct drm_encoder_helper_funcs *encoder_funcs; | 906 | struct drm_encoder_helper_funcs *encoder_funcs; |
889 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 907 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
890 | enum drm_connector_status ret = connector_status_disconnected; | 908 | enum drm_connector_status ret = connector_status_disconnected; |
909 | int r; | ||
891 | 910 | ||
892 | if (!radeon_connector->dac_load_detect) | 911 | if (!radeon_connector->dac_load_detect) |
893 | return ret; | 912 | return ret; |
894 | 913 | ||
914 | r = pm_runtime_get_sync(connector->dev->dev); | ||
915 | if (r < 0) | ||
916 | return connector_status_disconnected; | ||
917 | |||
895 | encoder = radeon_best_single_encoder(connector); | 918 | encoder = radeon_best_single_encoder(connector); |
896 | if (!encoder) | 919 | if (!encoder) |
897 | ret = connector_status_disconnected; | 920 | ret = connector_status_disconnected; |
@@ -902,6 +925,8 @@ radeon_tv_detect(struct drm_connector *connector, bool force) | |||
902 | if (ret == connector_status_connected) | 925 | if (ret == connector_status_connected) |
903 | ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false); | 926 | ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false); |
904 | radeon_connector_update_scratch_regs(connector, ret); | 927 | radeon_connector_update_scratch_regs(connector, ret); |
928 | pm_runtime_mark_last_busy(connector->dev->dev); | ||
929 | pm_runtime_put_autosuspend(connector->dev->dev); | ||
905 | return ret; | 930 | return ret; |
906 | } | 931 | } |
907 | 932 | ||
@@ -969,12 +994,18 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
969 | struct drm_encoder *encoder = NULL; | 994 | struct drm_encoder *encoder = NULL; |
970 | struct drm_encoder_helper_funcs *encoder_funcs; | 995 | struct drm_encoder_helper_funcs *encoder_funcs; |
971 | struct drm_mode_object *obj; | 996 | struct drm_mode_object *obj; |
972 | int i; | 997 | int i, r; |
973 | enum drm_connector_status ret = connector_status_disconnected; | 998 | enum drm_connector_status ret = connector_status_disconnected; |
974 | bool dret = false, broken_edid = false; | 999 | bool dret = false, broken_edid = false; |
975 | 1000 | ||
976 | if (!force && radeon_check_hpd_status_unchanged(connector)) | 1001 | r = pm_runtime_get_sync(connector->dev->dev); |
977 | return connector->status; | 1002 | if (r < 0) |
1003 | return connector_status_disconnected; | ||
1004 | |||
1005 | if (!force && radeon_check_hpd_status_unchanged(connector)) { | ||
1006 | ret = connector->status; | ||
1007 | goto exit; | ||
1008 | } | ||
978 | 1009 | ||
979 | if (radeon_connector->ddc_bus) | 1010 | if (radeon_connector->ddc_bus) |
980 | dret = radeon_ddc_probe(radeon_connector, false); | 1011 | dret = radeon_ddc_probe(radeon_connector, false); |
@@ -1125,6 +1156,11 @@ out: | |||
1125 | 1156 | ||
1126 | /* updated in get modes as well since we need to know if it's analog or digital */ | 1157 | /* updated in get modes as well since we need to know if it's analog or digital */ |
1127 | radeon_connector_update_scratch_regs(connector, ret); | 1158 | radeon_connector_update_scratch_regs(connector, ret); |
1159 | |||
1160 | exit: | ||
1161 | pm_runtime_mark_last_busy(connector->dev->dev); | ||
1162 | pm_runtime_put_autosuspend(connector->dev->dev); | ||
1163 | |||
1128 | return ret; | 1164 | return ret; |
1129 | } | 1165 | } |
1130 | 1166 | ||
@@ -1392,9 +1428,16 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
1392 | enum drm_connector_status ret = connector_status_disconnected; | 1428 | enum drm_connector_status ret = connector_status_disconnected; |
1393 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | 1429 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; |
1394 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | 1430 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); |
1431 | int r; | ||
1395 | 1432 | ||
1396 | if (!force && radeon_check_hpd_status_unchanged(connector)) | 1433 | r = pm_runtime_get_sync(connector->dev->dev); |
1397 | return connector->status; | 1434 | if (r < 0) |
1435 | return connector_status_disconnected; | ||
1436 | |||
1437 | if (!force && radeon_check_hpd_status_unchanged(connector)) { | ||
1438 | ret = connector->status; | ||
1439 | goto out; | ||
1440 | } | ||
1398 | 1441 | ||
1399 | if (radeon_connector->edid) { | 1442 | if (radeon_connector->edid) { |
1400 | kfree(radeon_connector->edid); | 1443 | kfree(radeon_connector->edid); |
@@ -1458,6 +1501,10 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
1458 | } | 1501 | } |
1459 | 1502 | ||
1460 | radeon_connector_update_scratch_regs(connector, ret); | 1503 | radeon_connector_update_scratch_regs(connector, ret); |
1504 | out: | ||
1505 | pm_runtime_mark_last_busy(connector->dev->dev); | ||
1506 | pm_runtime_put_autosuspend(connector->dev->dev); | ||
1507 | |||
1461 | return ret; | 1508 | return ret; |
1462 | } | 1509 | } |
1463 | 1510 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index d08ae5be1598..b512c0098ee9 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -101,6 +101,12 @@ static const char radeon_family_name[][16] = { | |||
101 | "LAST", | 101 | "LAST", |
102 | }; | 102 | }; |
103 | 103 | ||
104 | #if defined(CONFIG_VGA_SWITCHEROO) | ||
105 | bool radeon_is_px(void); | ||
106 | #else | ||
107 | static inline bool radeon_is_px(void) { return false; } | ||
108 | #endif | ||
109 | |||
104 | /** | 110 | /** |
105 | * radeon_program_register_sequence - program an array of registers. | 111 | * radeon_program_register_sequence - program an array of registers. |
106 | * | 112 | * |
@@ -1076,6 +1082,10 @@ static bool radeon_switcheroo_quirk_long_wakeup(struct pci_dev *pdev) | |||
1076 | static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) | 1082 | static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) |
1077 | { | 1083 | { |
1078 | struct drm_device *dev = pci_get_drvdata(pdev); | 1084 | struct drm_device *dev = pci_get_drvdata(pdev); |
1085 | |||
1086 | if (radeon_is_px() && state == VGA_SWITCHEROO_OFF) | ||
1087 | return; | ||
1088 | |||
1079 | if (state == VGA_SWITCHEROO_ON) { | 1089 | if (state == VGA_SWITCHEROO_ON) { |
1080 | unsigned d3_delay = dev->pdev->d3_delay; | 1090 | unsigned d3_delay = dev->pdev->d3_delay; |
1081 | 1091 | ||
@@ -1086,7 +1096,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero | |||
1086 | if (d3_delay < 20 && radeon_switcheroo_quirk_long_wakeup(pdev)) | 1096 | if (d3_delay < 20 && radeon_switcheroo_quirk_long_wakeup(pdev)) |
1087 | dev->pdev->d3_delay = 20; | 1097 | dev->pdev->d3_delay = 20; |
1088 | 1098 | ||
1089 | radeon_resume_kms(dev, 1); | 1099 | radeon_resume_kms(dev, true, true); |
1090 | 1100 | ||
1091 | dev->pdev->d3_delay = d3_delay; | 1101 | dev->pdev->d3_delay = d3_delay; |
1092 | 1102 | ||
@@ -1096,7 +1106,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero | |||
1096 | printk(KERN_INFO "radeon: switched off\n"); | 1106 | printk(KERN_INFO "radeon: switched off\n"); |
1097 | drm_kms_helper_poll_disable(dev); | 1107 | drm_kms_helper_poll_disable(dev); |
1098 | dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; | 1108 | dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; |
1099 | radeon_suspend_kms(dev, 1); | 1109 | radeon_suspend_kms(dev, true, true); |
1100 | dev->switch_power_state = DRM_SWITCH_POWER_OFF; | 1110 | dev->switch_power_state = DRM_SWITCH_POWER_OFF; |
1101 | } | 1111 | } |
1102 | } | 1112 | } |
@@ -1146,6 +1156,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
1146 | { | 1156 | { |
1147 | int r, i; | 1157 | int r, i; |
1148 | int dma_bits; | 1158 | int dma_bits; |
1159 | bool runtime = false; | ||
1149 | 1160 | ||
1150 | rdev->shutdown = false; | 1161 | rdev->shutdown = false; |
1151 | rdev->dev = &pdev->dev; | 1162 | rdev->dev = &pdev->dev; |
@@ -1292,7 +1303,14 @@ int radeon_device_init(struct radeon_device *rdev, | |||
1292 | /* this will fail for cards that aren't VGA class devices, just | 1303 | /* this will fail for cards that aren't VGA class devices, just |
1293 | * ignore it */ | 1304 | * ignore it */ |
1294 | vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); | 1305 | vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); |
1295 | vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, false); | 1306 | |
1307 | if (radeon_runtime_pm == 1) | ||
1308 | runtime = true; | ||
1309 | if ((radeon_runtime_pm == -1) && radeon_is_px()) | ||
1310 | runtime = true; | ||
1311 | vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, runtime); | ||
1312 | if (runtime) | ||
1313 | vga_switcheroo_init_domain_pm_ops(rdev->dev, &rdev->vga_pm_domain); | ||
1296 | 1314 | ||
1297 | r = radeon_init(rdev); | 1315 | r = radeon_init(rdev); |
1298 | if (r) | 1316 | if (r) |
@@ -1382,7 +1400,7 @@ void radeon_device_fini(struct radeon_device *rdev) | |||
1382 | * Returns 0 for success or an error on failure. | 1400 | * Returns 0 for success or an error on failure. |
1383 | * Called at driver suspend. | 1401 | * Called at driver suspend. |
1384 | */ | 1402 | */ |
1385 | int radeon_suspend_kms(struct drm_device *dev, bool suspend) | 1403 | int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon) |
1386 | { | 1404 | { |
1387 | struct radeon_device *rdev; | 1405 | struct radeon_device *rdev; |
1388 | struct drm_crtc *crtc; | 1406 | struct drm_crtc *crtc; |
@@ -1457,9 +1475,12 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend) | |||
1457 | pci_disable_device(dev->pdev); | 1475 | pci_disable_device(dev->pdev); |
1458 | pci_set_power_state(dev->pdev, PCI_D3hot); | 1476 | pci_set_power_state(dev->pdev, PCI_D3hot); |
1459 | } | 1477 | } |
1460 | console_lock(); | 1478 | |
1461 | radeon_fbdev_set_suspend(rdev, 1); | 1479 | if (fbcon) { |
1462 | console_unlock(); | 1480 | console_lock(); |
1481 | radeon_fbdev_set_suspend(rdev, 1); | ||
1482 | console_unlock(); | ||
1483 | } | ||
1463 | return 0; | 1484 | return 0; |
1464 | } | 1485 | } |
1465 | 1486 | ||
@@ -1472,7 +1493,7 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend) | |||
1472 | * Returns 0 for success or an error on failure. | 1493 | * Returns 0 for success or an error on failure. |
1473 | * Called at driver resume. | 1494 | * Called at driver resume. |
1474 | */ | 1495 | */ |
1475 | int radeon_resume_kms(struct drm_device *dev, bool resume) | 1496 | int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon) |
1476 | { | 1497 | { |
1477 | struct drm_connector *connector; | 1498 | struct drm_connector *connector; |
1478 | struct radeon_device *rdev = dev->dev_private; | 1499 | struct radeon_device *rdev = dev->dev_private; |
@@ -1481,12 +1502,15 @@ int radeon_resume_kms(struct drm_device *dev, bool resume) | |||
1481 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) | 1502 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
1482 | return 0; | 1503 | return 0; |
1483 | 1504 | ||
1484 | console_lock(); | 1505 | if (fbcon) { |
1506 | console_lock(); | ||
1507 | } | ||
1485 | if (resume) { | 1508 | if (resume) { |
1486 | pci_set_power_state(dev->pdev, PCI_D0); | 1509 | pci_set_power_state(dev->pdev, PCI_D0); |
1487 | pci_restore_state(dev->pdev); | 1510 | pci_restore_state(dev->pdev); |
1488 | if (pci_enable_device(dev->pdev)) { | 1511 | if (pci_enable_device(dev->pdev)) { |
1489 | console_unlock(); | 1512 | if (fbcon) |
1513 | console_unlock(); | ||
1490 | return -1; | 1514 | return -1; |
1491 | } | 1515 | } |
1492 | } | 1516 | } |
@@ -1501,9 +1525,11 @@ int radeon_resume_kms(struct drm_device *dev, bool resume) | |||
1501 | radeon_pm_resume(rdev); | 1525 | radeon_pm_resume(rdev); |
1502 | radeon_restore_bios_scratch_regs(rdev); | 1526 | radeon_restore_bios_scratch_regs(rdev); |
1503 | 1527 | ||
1504 | radeon_fbdev_set_suspend(rdev, 0); | 1528 | if (fbcon) { |
1505 | console_unlock(); | 1529 | radeon_fbdev_set_suspend(rdev, 0); |
1506 | 1530 | console_unlock(); | |
1531 | } | ||
1532 | |||
1507 | /* init dig PHYs, disp eng pll */ | 1533 | /* init dig PHYs, disp eng pll */ |
1508 | if (rdev->is_atom_bios) { | 1534 | if (rdev->is_atom_bios) { |
1509 | radeon_atom_encoder_init(rdev); | 1535 | radeon_atom_encoder_init(rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 7adbb7417dd5..0e52cc532c26 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "atom.h" | 30 | #include "atom.h" |
31 | #include <asm/div64.h> | 31 | #include <asm/div64.h> |
32 | 32 | ||
33 | #include <linux/pm_runtime.h> | ||
33 | #include <drm/drm_crtc_helper.h> | 34 | #include <drm/drm_crtc_helper.h> |
34 | #include <drm/drm_edid.h> | 35 | #include <drm/drm_edid.h> |
35 | 36 | ||
@@ -494,11 +495,55 @@ unlock_free: | |||
494 | return r; | 495 | return r; |
495 | } | 496 | } |
496 | 497 | ||
498 | static int | ||
499 | radeon_crtc_set_config(struct drm_mode_set *set) | ||
500 | { | ||
501 | struct drm_device *dev; | ||
502 | struct radeon_device *rdev; | ||
503 | struct drm_crtc *crtc; | ||
504 | bool active = false; | ||
505 | int ret; | ||
506 | |||
507 | if (!set || !set->crtc) | ||
508 | return -EINVAL; | ||
509 | |||
510 | dev = set->crtc->dev; | ||
511 | |||
512 | ret = pm_runtime_get_sync(dev->dev); | ||
513 | if (ret < 0) | ||
514 | return ret; | ||
515 | |||
516 | ret = drm_crtc_helper_set_config(set); | ||
517 | |||
518 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) | ||
519 | if (crtc->enabled) | ||
520 | active = true; | ||
521 | |||
522 | pm_runtime_mark_last_busy(dev->dev); | ||
523 | |||
524 | rdev = dev->dev_private; | ||
525 | /* if we have active crtcs and we don't have a power ref, | ||
526 | take the current one */ | ||
527 | if (active && !rdev->have_disp_power_ref) { | ||
528 | rdev->have_disp_power_ref = true; | ||
529 | return ret; | ||
530 | } | ||
531 | /* if we have no active crtcs, then drop the power ref | ||
532 | we got before */ | ||
533 | if (!active && rdev->have_disp_power_ref) { | ||
534 | pm_runtime_put_autosuspend(dev->dev); | ||
535 | rdev->have_disp_power_ref = false; | ||
536 | } | ||
537 | |||
538 | /* drop the power reference we got coming in here */ | ||
539 | pm_runtime_put_autosuspend(dev->dev); | ||
540 | return ret; | ||
541 | } | ||
497 | static const struct drm_crtc_funcs radeon_crtc_funcs = { | 542 | static const struct drm_crtc_funcs radeon_crtc_funcs = { |
498 | .cursor_set = radeon_crtc_cursor_set, | 543 | .cursor_set = radeon_crtc_cursor_set, |
499 | .cursor_move = radeon_crtc_cursor_move, | 544 | .cursor_move = radeon_crtc_cursor_move, |
500 | .gamma_set = radeon_crtc_gamma_set, | 545 | .gamma_set = radeon_crtc_gamma_set, |
501 | .set_config = drm_crtc_helper_set_config, | 546 | .set_config = radeon_crtc_set_config, |
502 | .destroy = radeon_crtc_destroy, | 547 | .destroy = radeon_crtc_destroy, |
503 | .page_flip = radeon_crtc_page_flip, | 548 | .page_flip = radeon_crtc_page_flip, |
504 | }; | 549 | }; |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 59f067e857db..9902ac76f683 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -36,8 +36,9 @@ | |||
36 | #include <drm/drm_pciids.h> | 36 | #include <drm/drm_pciids.h> |
37 | #include <linux/console.h> | 37 | #include <linux/console.h> |
38 | #include <linux/module.h> | 38 | #include <linux/module.h> |
39 | 39 | #include <linux/pm_runtime.h> | |
40 | 40 | #include <linux/vga_switcheroo.h> | |
41 | #include "drm_crtc_helper.h" | ||
41 | /* | 42 | /* |
42 | * KMS wrapper. | 43 | * KMS wrapper. |
43 | * - 2.0.0 - initial interface | 44 | * - 2.0.0 - initial interface |
@@ -87,8 +88,8 @@ void radeon_driver_postclose_kms(struct drm_device *dev, | |||
87 | struct drm_file *file_priv); | 88 | struct drm_file *file_priv); |
88 | void radeon_driver_preclose_kms(struct drm_device *dev, | 89 | void radeon_driver_preclose_kms(struct drm_device *dev, |
89 | struct drm_file *file_priv); | 90 | struct drm_file *file_priv); |
90 | int radeon_suspend_kms(struct drm_device *dev, bool suspend); | 91 | int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon); |
91 | int radeon_resume_kms(struct drm_device *dev, bool resume); | 92 | int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); |
92 | u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc); | 93 | u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc); |
93 | int radeon_enable_vblank_kms(struct drm_device *dev, int crtc); | 94 | int radeon_enable_vblank_kms(struct drm_device *dev, int crtc); |
94 | void radeon_disable_vblank_kms(struct drm_device *dev, int crtc); | 95 | void radeon_disable_vblank_kms(struct drm_device *dev, int crtc); |
@@ -136,9 +137,11 @@ void radeon_debugfs_cleanup(struct drm_minor *minor); | |||
136 | #if defined(CONFIG_VGA_SWITCHEROO) | 137 | #if defined(CONFIG_VGA_SWITCHEROO) |
137 | void radeon_register_atpx_handler(void); | 138 | void radeon_register_atpx_handler(void); |
138 | void radeon_unregister_atpx_handler(void); | 139 | void radeon_unregister_atpx_handler(void); |
140 | bool radeon_is_px(void); | ||
139 | #else | 141 | #else |
140 | static inline void radeon_register_atpx_handler(void) {} | 142 | static inline void radeon_register_atpx_handler(void) {} |
141 | static inline void radeon_unregister_atpx_handler(void) {} | 143 | static inline void radeon_unregister_atpx_handler(void) {} |
144 | static inline bool radeon_is_px(void) { return false; } | ||
142 | #endif | 145 | #endif |
143 | 146 | ||
144 | int radeon_no_wb; | 147 | int radeon_no_wb; |
@@ -161,6 +164,7 @@ int radeon_lockup_timeout = 10000; | |||
161 | int radeon_fastfb = 0; | 164 | int radeon_fastfb = 0; |
162 | int radeon_dpm = -1; | 165 | int radeon_dpm = -1; |
163 | int radeon_aspm = -1; | 166 | int radeon_aspm = -1; |
167 | int radeon_runtime_pm = -1; | ||
164 | 168 | ||
165 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); | 169 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); |
166 | module_param_named(no_wb, radeon_no_wb, int, 0444); | 170 | module_param_named(no_wb, radeon_no_wb, int, 0444); |
@@ -222,6 +226,9 @@ module_param_named(dpm, radeon_dpm, int, 0444); | |||
222 | MODULE_PARM_DESC(aspm, "ASPM support (1 = enable, 0 = disable, -1 = auto)"); | 226 | MODULE_PARM_DESC(aspm, "ASPM support (1 = enable, 0 = disable, -1 = auto)"); |
223 | module_param_named(aspm, radeon_aspm, int, 0444); | 227 | module_param_named(aspm, radeon_aspm, int, 0444); |
224 | 228 | ||
229 | MODULE_PARM_DESC(runpm, "PX runtime pm (1 = force enable, 0 = disable, -1 = PX only default)"); | ||
230 | module_param_named(runpm, radeon_runtime_pm, int, 0444); | ||
231 | |||
225 | static struct pci_device_id pciidlist[] = { | 232 | static struct pci_device_id pciidlist[] = { |
226 | radeon_PCI_IDS | 233 | radeon_PCI_IDS |
227 | }; | 234 | }; |
@@ -258,6 +265,7 @@ static int radeon_resume(struct drm_device *dev) | |||
258 | return 0; | 265 | return 0; |
259 | } | 266 | } |
260 | 267 | ||
268 | |||
261 | static const struct file_operations radeon_driver_old_fops = { | 269 | static const struct file_operations radeon_driver_old_fops = { |
262 | .owner = THIS_MODULE, | 270 | .owner = THIS_MODULE, |
263 | .open = drm_open, | 271 | .open = drm_open, |
@@ -356,28 +364,121 @@ static int radeon_pmops_suspend(struct device *dev) | |||
356 | { | 364 | { |
357 | struct pci_dev *pdev = to_pci_dev(dev); | 365 | struct pci_dev *pdev = to_pci_dev(dev); |
358 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | 366 | struct drm_device *drm_dev = pci_get_drvdata(pdev); |
359 | return radeon_suspend_kms(drm_dev, 1); | 367 | return radeon_suspend_kms(drm_dev, true, true); |
360 | } | 368 | } |
361 | 369 | ||
362 | static int radeon_pmops_resume(struct device *dev) | 370 | static int radeon_pmops_resume(struct device *dev) |
363 | { | 371 | { |
364 | struct pci_dev *pdev = to_pci_dev(dev); | 372 | struct pci_dev *pdev = to_pci_dev(dev); |
365 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | 373 | struct drm_device *drm_dev = pci_get_drvdata(pdev); |
366 | return radeon_resume_kms(drm_dev, 1); | 374 | return radeon_resume_kms(drm_dev, true, true); |
367 | } | 375 | } |
368 | 376 | ||
369 | static int radeon_pmops_freeze(struct device *dev) | 377 | static int radeon_pmops_freeze(struct device *dev) |
370 | { | 378 | { |
371 | struct pci_dev *pdev = to_pci_dev(dev); | 379 | struct pci_dev *pdev = to_pci_dev(dev); |
372 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | 380 | struct drm_device *drm_dev = pci_get_drvdata(pdev); |
373 | return radeon_suspend_kms(drm_dev, 0); | 381 | return radeon_suspend_kms(drm_dev, false, true); |
374 | } | 382 | } |
375 | 383 | ||
376 | static int radeon_pmops_thaw(struct device *dev) | 384 | static int radeon_pmops_thaw(struct device *dev) |
377 | { | 385 | { |
378 | struct pci_dev *pdev = to_pci_dev(dev); | 386 | struct pci_dev *pdev = to_pci_dev(dev); |
379 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | 387 | struct drm_device *drm_dev = pci_get_drvdata(pdev); |
380 | return radeon_resume_kms(drm_dev, 0); | 388 | return radeon_resume_kms(drm_dev, false, true); |
389 | } | ||
390 | |||
391 | static int radeon_pmops_runtime_suspend(struct device *dev) | ||
392 | { | ||
393 | struct pci_dev *pdev = to_pci_dev(dev); | ||
394 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | ||
395 | int ret; | ||
396 | |||
397 | if (radeon_runtime_pm == 0) | ||
398 | return -EINVAL; | ||
399 | |||
400 | drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; | ||
401 | drm_kms_helper_poll_disable(drm_dev); | ||
402 | vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF); | ||
403 | |||
404 | ret = radeon_suspend_kms(drm_dev, false, false); | ||
405 | pci_save_state(pdev); | ||
406 | pci_disable_device(pdev); | ||
407 | pci_set_power_state(pdev, PCI_D3cold); | ||
408 | drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | static int radeon_pmops_runtime_resume(struct device *dev) | ||
414 | { | ||
415 | struct pci_dev *pdev = to_pci_dev(dev); | ||
416 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | ||
417 | int ret; | ||
418 | |||
419 | if (radeon_runtime_pm == 0) | ||
420 | return -EINVAL; | ||
421 | |||
422 | drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; | ||
423 | |||
424 | pci_set_power_state(pdev, PCI_D0); | ||
425 | pci_restore_state(pdev); | ||
426 | ret = pci_enable_device(pdev); | ||
427 | if (ret) | ||
428 | return ret; | ||
429 | pci_set_master(pdev); | ||
430 | |||
431 | ret = radeon_resume_kms(drm_dev, false, false); | ||
432 | drm_kms_helper_poll_enable(drm_dev); | ||
433 | vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON); | ||
434 | drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; | ||
435 | return 0; | ||
436 | } | ||
437 | |||
438 | static int radeon_pmops_runtime_idle(struct device *dev) | ||
439 | { | ||
440 | struct pci_dev *pdev = to_pci_dev(dev); | ||
441 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | ||
442 | struct drm_crtc *crtc; | ||
443 | |||
444 | if (radeon_runtime_pm == 0) | ||
445 | return -EBUSY; | ||
446 | |||
447 | /* are we PX enabled? */ | ||
448 | if (radeon_runtime_pm == -1 && !radeon_is_px()) { | ||
449 | DRM_DEBUG_DRIVER("failing to power off - not px\n"); | ||
450 | return -EBUSY; | ||
451 | } | ||
452 | |||
453 | list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) { | ||
454 | if (crtc->enabled) { | ||
455 | DRM_DEBUG_DRIVER("failing to power off - crtc active\n"); | ||
456 | return -EBUSY; | ||
457 | } | ||
458 | } | ||
459 | |||
460 | pm_runtime_mark_last_busy(dev); | ||
461 | pm_runtime_autosuspend(dev); | ||
462 | /* we don't want the main rpm_idle to call suspend - we want to autosuspend */ | ||
463 | return 1; | ||
464 | } | ||
465 | |||
466 | long radeon_drm_ioctl(struct file *filp, | ||
467 | unsigned int cmd, unsigned long arg) | ||
468 | { | ||
469 | struct drm_file *file_priv = filp->private_data; | ||
470 | struct drm_device *dev; | ||
471 | long ret; | ||
472 | dev = file_priv->minor->dev; | ||
473 | ret = pm_runtime_get_sync(dev->dev); | ||
474 | if (ret < 0) | ||
475 | return ret; | ||
476 | |||
477 | ret = drm_ioctl(filp, cmd, arg); | ||
478 | |||
479 | pm_runtime_mark_last_busy(dev->dev); | ||
480 | pm_runtime_put_autosuspend(dev->dev); | ||
481 | return ret; | ||
381 | } | 482 | } |
382 | 483 | ||
383 | static const struct dev_pm_ops radeon_pm_ops = { | 484 | static const struct dev_pm_ops radeon_pm_ops = { |
@@ -387,13 +488,16 @@ static const struct dev_pm_ops radeon_pm_ops = { | |||
387 | .thaw = radeon_pmops_thaw, | 488 | .thaw = radeon_pmops_thaw, |
388 | .poweroff = radeon_pmops_freeze, | 489 | .poweroff = radeon_pmops_freeze, |
389 | .restore = radeon_pmops_resume, | 490 | .restore = radeon_pmops_resume, |
491 | .runtime_suspend = radeon_pmops_runtime_suspend, | ||
492 | .runtime_resume = radeon_pmops_runtime_resume, | ||
493 | .runtime_idle = radeon_pmops_runtime_idle, | ||
390 | }; | 494 | }; |
391 | 495 | ||
392 | static const struct file_operations radeon_driver_kms_fops = { | 496 | static const struct file_operations radeon_driver_kms_fops = { |
393 | .owner = THIS_MODULE, | 497 | .owner = THIS_MODULE, |
394 | .open = drm_open, | 498 | .open = drm_open, |
395 | .release = drm_release, | 499 | .release = drm_release, |
396 | .unlocked_ioctl = drm_ioctl, | 500 | .unlocked_ioctl = radeon_drm_ioctl, |
397 | .mmap = radeon_mmap, | 501 | .mmap = radeon_mmap, |
398 | .poll = drm_poll, | 502 | .poll = drm_poll, |
399 | .read = drm_read, | 503 | .read = drm_read, |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index b369d42f7de5..543dcfae7e6f 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h | |||
@@ -113,6 +113,9 @@ | |||
113 | #define DRIVER_MINOR 33 | 113 | #define DRIVER_MINOR 33 |
114 | #define DRIVER_PATCHLEVEL 0 | 114 | #define DRIVER_PATCHLEVEL 0 |
115 | 115 | ||
116 | long radeon_drm_ioctl(struct file *filp, | ||
117 | unsigned int cmd, unsigned long arg); | ||
118 | |||
116 | /* The rest of the file is DEPRECATED! */ | 119 | /* The rest of the file is DEPRECATED! */ |
117 | #ifdef CONFIG_DRM_RADEON_UMS | 120 | #ifdef CONFIG_DRM_RADEON_UMS |
118 | 121 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_ioc32.c b/drivers/gpu/drm/radeon/radeon_ioc32.c index c180df8e84db..bdb0f93e73bc 100644 --- a/drivers/gpu/drm/radeon/radeon_ioc32.c +++ b/drivers/gpu/drm/radeon/radeon_ioc32.c | |||
@@ -418,7 +418,7 @@ long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long | |||
418 | if (nr < DRM_COMMAND_BASE) | 418 | if (nr < DRM_COMMAND_BASE) |
419 | return drm_compat_ioctl(filp, cmd, arg); | 419 | return drm_compat_ioctl(filp, cmd, arg); |
420 | 420 | ||
421 | ret = drm_ioctl(filp, cmd, arg); | 421 | ret = radeon_drm_ioctl(filp, cmd, arg); |
422 | 422 | ||
423 | return ret; | 423 | return ret; |
424 | } | 424 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index cc9e8482cf30..ec6240b00469 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -32,6 +32,8 @@ | |||
32 | #include "radeon.h" | 32 | #include "radeon.h" |
33 | #include "atom.h" | 33 | #include "atom.h" |
34 | 34 | ||
35 | #include <linux/pm_runtime.h> | ||
36 | |||
35 | #define RADEON_WAIT_IDLE_TIMEOUT 200 | 37 | #define RADEON_WAIT_IDLE_TIMEOUT 200 |
36 | 38 | ||
37 | /** | 39 | /** |
@@ -47,8 +49,12 @@ irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) | |||
47 | { | 49 | { |
48 | struct drm_device *dev = (struct drm_device *) arg; | 50 | struct drm_device *dev = (struct drm_device *) arg; |
49 | struct radeon_device *rdev = dev->dev_private; | 51 | struct radeon_device *rdev = dev->dev_private; |
52 | irqreturn_t ret; | ||
50 | 53 | ||
51 | return radeon_irq_process(rdev); | 54 | ret = radeon_irq_process(rdev); |
55 | if (ret == IRQ_HANDLED) | ||
56 | pm_runtime_mark_last_busy(dev->dev); | ||
57 | return ret; | ||
52 | } | 58 | } |
53 | 59 | ||
54 | /* | 60 | /* |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index d6b36766e8c9..bb8710531a1b 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | #include <linux/vga_switcheroo.h> | 33 | #include <linux/vga_switcheroo.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | 35 | #include <linux/pm_runtime.h> | |
36 | /** | 36 | /** |
37 | * radeon_driver_unload_kms - Main unload function for KMS. | 37 | * radeon_driver_unload_kms - Main unload function for KMS. |
38 | * | 38 | * |
@@ -50,9 +50,14 @@ int radeon_driver_unload_kms(struct drm_device *dev) | |||
50 | 50 | ||
51 | if (rdev == NULL) | 51 | if (rdev == NULL) |
52 | return 0; | 52 | return 0; |
53 | |||
53 | if (rdev->rmmio == NULL) | 54 | if (rdev->rmmio == NULL) |
54 | goto done_free; | 55 | goto done_free; |
56 | |||
57 | pm_runtime_get_sync(dev->dev); | ||
58 | |||
55 | radeon_acpi_fini(rdev); | 59 | radeon_acpi_fini(rdev); |
60 | |||
56 | radeon_modeset_fini(rdev); | 61 | radeon_modeset_fini(rdev); |
57 | radeon_device_fini(rdev); | 62 | radeon_device_fini(rdev); |
58 | 63 | ||
@@ -125,9 +130,20 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) | |||
125 | "Error during ACPI methods call\n"); | 130 | "Error during ACPI methods call\n"); |
126 | } | 131 | } |
127 | 132 | ||
133 | if (radeon_runtime_pm != 0) { | ||
134 | pm_runtime_use_autosuspend(dev->dev); | ||
135 | pm_runtime_set_autosuspend_delay(dev->dev, 5000); | ||
136 | pm_runtime_set_active(dev->dev); | ||
137 | pm_runtime_allow(dev->dev); | ||
138 | pm_runtime_mark_last_busy(dev->dev); | ||
139 | pm_runtime_put_autosuspend(dev->dev); | ||
140 | } | ||
141 | |||
128 | out: | 142 | out: |
129 | if (r) | 143 | if (r) |
130 | radeon_driver_unload_kms(dev); | 144 | radeon_driver_unload_kms(dev); |
145 | |||
146 | |||
131 | return r; | 147 | return r; |
132 | } | 148 | } |
133 | 149 | ||
@@ -475,9 +491,14 @@ void radeon_driver_lastclose_kms(struct drm_device *dev) | |||
475 | int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | 491 | int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) |
476 | { | 492 | { |
477 | struct radeon_device *rdev = dev->dev_private; | 493 | struct radeon_device *rdev = dev->dev_private; |
494 | int r; | ||
478 | 495 | ||
479 | file_priv->driver_priv = NULL; | 496 | file_priv->driver_priv = NULL; |
480 | 497 | ||
498 | r = pm_runtime_get_sync(dev->dev); | ||
499 | if (r < 0) | ||
500 | return r; | ||
501 | |||
481 | /* new gpu have virtual address space support */ | 502 | /* new gpu have virtual address space support */ |
482 | if (rdev->family >= CHIP_CAYMAN) { | 503 | if (rdev->family >= CHIP_CAYMAN) { |
483 | struct radeon_fpriv *fpriv; | 504 | struct radeon_fpriv *fpriv; |
@@ -506,6 +527,9 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | |||
506 | 527 | ||
507 | file_priv->driver_priv = fpriv; | 528 | file_priv->driver_priv = fpriv; |
508 | } | 529 | } |
530 | |||
531 | pm_runtime_mark_last_busy(dev->dev); | ||
532 | pm_runtime_put_autosuspend(dev->dev); | ||
509 | return 0; | 533 | return 0; |
510 | } | 534 | } |
511 | 535 | ||