Rev 5346 | Rev 6321 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5346 | Rev 6104 | ||
---|---|---|---|
Line 22... | Line 22... | ||
22 | */ |
22 | */ |
23 | #include |
23 | #include |
24 | #include "radeon.h" |
24 | #include "radeon.h" |
25 | #include "avivod.h" |
25 | #include "avivod.h" |
26 | #include "atom.h" |
26 | #include "atom.h" |
27 | - | ||
- | 27 | #include "r600_dpm.h" |
|
Line 28... | Line 28... | ||
28 | 28 | ||
29 | #define RADEON_IDLE_LOOP_MS 100 |
29 | #define RADEON_IDLE_LOOP_MS 100 |
30 | #define RADEON_RECLOCK_DELAY_MS 200 |
30 | #define RADEON_RECLOCK_DELAY_MS 200 |
Line 153... | Line 153... | ||
153 | 153 | ||
154 | static void radeon_sync_with_vblank(struct radeon_device *rdev) |
154 | static void radeon_sync_with_vblank(struct radeon_device *rdev) |
155 | { |
155 | { |
156 | if (rdev->pm.active_crtcs) { |
156 | if (rdev->pm.active_crtcs) { |
157 | rdev->pm.vblank_sync = false; |
157 | rdev->pm.vblank_sync = false; |
158 | // wait_event_timeout( |
158 | wait_event_timeout( |
159 | // rdev->irq.vblank_queue, rdev->pm.vblank_sync, |
159 | rdev->irq.vblank_queue, rdev->pm.vblank_sync, |
160 | // msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT)); |
160 | msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT)); |
161 | } |
161 | } |
Line 162... | Line 162... | ||
162 | } |
162 | } |
163 | 163 | ||
Line 248... | Line 248... | ||
248 | /* no need to take locks, etc. if nothing's going to change */ |
248 | /* no need to take locks, etc. if nothing's going to change */ |
249 | if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) && |
249 | if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) && |
250 | (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index)) |
250 | (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index)) |
251 | return; |
251 | return; |
Line 252... | Line -... | ||
252 | - | ||
253 | mutex_lock(&rdev->ddev->struct_mutex); |
252 | |
254 | down_write(&rdev->pm.mclk_lock); |
253 | down_write(&rdev->pm.mclk_lock); |
Line 255... | Line 254... | ||
255 | mutex_lock(&rdev->ring_lock); |
254 | mutex_lock(&rdev->ring_lock); |
256 | 255 | ||
Line 263... | Line 262... | ||
263 | r = radeon_fence_wait_empty(rdev, i); |
262 | r = radeon_fence_wait_empty(rdev, i); |
264 | if (r) { |
263 | if (r) { |
265 | /* needs a GPU reset dont reset here */ |
264 | /* needs a GPU reset dont reset here */ |
266 | mutex_unlock(&rdev->ring_lock); |
265 | mutex_unlock(&rdev->ring_lock); |
267 | up_write(&rdev->pm.mclk_lock); |
266 | up_write(&rdev->pm.mclk_lock); |
268 | mutex_unlock(&rdev->ddev->struct_mutex); |
- | |
269 | return; |
267 | return; |
270 | } |
268 | } |
271 | } |
269 | } |
Line 272... | Line 270... | ||
272 | 270 | ||
Line 273... | Line 271... | ||
273 | radeon_unmap_vram_bos(rdev); |
271 | radeon_unmap_vram_bos(rdev); |
274 | 272 | ||
275 | if (rdev->irq.installed) { |
273 | if (rdev->irq.installed) { |
276 | for (i = 0; i < rdev->num_crtc; i++) { |
274 | for (i = 0; i < rdev->num_crtc; i++) { |
277 | if (rdev->pm.active_crtcs & (1 << i)) { |
275 | if (rdev->pm.active_crtcs & (1 << i)) { |
278 | rdev->pm.req_vblank |= (1 << i); |
276 | rdev->pm.req_vblank |= (1 << i); |
279 | // drm_vblank_get(rdev->ddev, i); |
277 | drm_vblank_get(rdev->ddev, i); |
280 | } |
278 | } |
Line 281... | Line 279... | ||
281 | } |
279 | } |
Line 282... | Line 280... | ||
282 | } |
280 | } |
283 | 281 | ||
284 | radeon_set_power_state(rdev); |
282 | radeon_set_power_state(rdev); |
285 | 283 | ||
286 | if (rdev->irq.installed) { |
284 | if (rdev->irq.installed) { |
287 | for (i = 0; i < rdev->num_crtc; i++) { |
285 | for (i = 0; i < rdev->num_crtc; i++) { |
288 | if (rdev->pm.req_vblank & (1 << i)) { |
286 | if (rdev->pm.req_vblank & (1 << i)) { |
289 | rdev->pm.req_vblank &= ~(1 << i); |
287 | rdev->pm.req_vblank &= ~(1 << i); |
Line 290... | Line 288... | ||
290 | // drm_vblank_put(rdev->ddev, i); |
288 | drm_vblank_put(rdev->ddev, i); |
Line 299... | Line 297... | ||
299 | 297 | ||
Line 300... | Line 298... | ||
300 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; |
298 | rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; |
301 | 299 | ||
302 | mutex_unlock(&rdev->ring_lock); |
- | |
303 | up_write(&rdev->pm.mclk_lock); |
300 | mutex_unlock(&rdev->ring_lock); |
Line 304... | Line 301... | ||
304 | mutex_unlock(&rdev->ddev->struct_mutex); |
301 | up_write(&rdev->pm.mclk_lock); |
305 | } |
302 | } |
306 | 303 | ||
Line 661... | Line 658... | ||
661 | mutex_unlock(&rdev->pm.mutex); |
658 | mutex_unlock(&rdev->pm.mutex); |
Line 662... | Line 659... | ||
662 | 659 | ||
663 | radeon_pm_compute_clocks(rdev); |
660 | radeon_pm_compute_clocks(rdev); |
Line 664... | Line 661... | ||
664 | } |
661 | } |
665 | - | ||
666 | static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device *rdev, |
662 | |
667 | enum radeon_pm_state_type dpm_state) |
- | |
668 | { |
- | |
669 | int i; |
- | |
670 | struct radeon_ps *ps; |
663 | static bool radeon_dpm_single_display(struct radeon_device *rdev) |
671 | u32 ui_class; |
664 | { |
Line 672... | Line 665... | ||
672 | bool single_display = (rdev->pm.dpm.new_active_crtc_count < 2) ? |
665 | bool single_display = (rdev->pm.dpm.new_active_crtc_count < 2) ? |
673 | true : false; |
666 | true : false; |
674 | 667 | ||
675 | /* check if the vblank period is too short to adjust the mclk */ |
668 | /* check if the vblank period is too short to adjust the mclk */ |
676 | if (single_display && rdev->asic->dpm.vblank_too_short) { |
669 | if (single_display && rdev->asic->dpm.vblank_too_short) { |
Line -... | Line 670... | ||
- | 670 | if (radeon_dpm_vblank_too_short(rdev)) |
|
- | 671 | single_display = false; |
|
- | 672 | } |
|
- | 673 | ||
- | 674 | /* 120hz tends to be problematic even if they are under the |
|
- | 675 | * vblank limit. |
|
- | 676 | */ |
|
- | 677 | if (single_display && (r600_dpm_get_vrefresh(rdev) >= 120)) |
|
- | 678 | single_display = false; |
|
- | 679 | ||
- | 680 | return single_display; |
|
- | 681 | } |
|
- | 682 | ||
- | 683 | static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device *rdev, |
|
- | 684 | enum radeon_pm_state_type dpm_state) |
|
- | 685 | { |
|
- | 686 | int i; |
|
677 | if (radeon_dpm_vblank_too_short(rdev)) |
687 | struct radeon_ps *ps; |
678 | single_display = false; |
688 | u32 ui_class; |
679 | } |
689 | bool single_display = radeon_dpm_single_display(rdev); |
680 | 690 | ||
681 | /* certain older asics have a separare 3D performance state, |
691 | /* certain older asics have a separare 3D performance state, |
Line 801... | Line 811... | ||
801 | { |
811 | { |
802 | int i; |
812 | int i; |
803 | struct radeon_ps *ps; |
813 | struct radeon_ps *ps; |
804 | enum radeon_pm_state_type dpm_state; |
814 | enum radeon_pm_state_type dpm_state; |
805 | int ret; |
815 | int ret; |
- | 816 | bool single_display = radeon_dpm_single_display(rdev); |
|
Line 806... | Line 817... | ||
806 | 817 | ||
807 | /* if dpm init failed */ |
818 | /* if dpm init failed */ |
808 | if (!rdev->pm.dpm_enabled) |
819 | if (!rdev->pm.dpm_enabled) |
Line 825... | Line 836... | ||
825 | /* no need to reprogram if nothing changed unless we are on BTC+ */ |
836 | /* no need to reprogram if nothing changed unless we are on BTC+ */ |
826 | if (rdev->pm.dpm.current_ps == rdev->pm.dpm.requested_ps) { |
837 | if (rdev->pm.dpm.current_ps == rdev->pm.dpm.requested_ps) { |
827 | /* vce just modifies an existing state so force a change */ |
838 | /* vce just modifies an existing state so force a change */ |
828 | if (ps->vce_active != rdev->pm.dpm.vce_active) |
839 | if (ps->vce_active != rdev->pm.dpm.vce_active) |
829 | goto force; |
840 | goto force; |
- | 841 | /* user has made a display change (such as timing) */ |
|
- | 842 | if (rdev->pm.dpm.single_display != single_display) |
|
- | 843 | goto force; |
|
830 | if ((rdev->family < CHIP_BARTS) || (rdev->flags & RADEON_IS_IGP)) { |
844 | if ((rdev->family < CHIP_BARTS) || (rdev->flags & RADEON_IS_IGP)) { |
831 | /* for pre-BTC and APUs if the num crtcs changed but state is the same, |
845 | /* for pre-BTC and APUs if the num crtcs changed but state is the same, |
832 | * all we need to do is update the display configuration. |
846 | * all we need to do is update the display configuration. |
833 | */ |
847 | */ |
834 | if (rdev->pm.dpm.new_active_crtcs != rdev->pm.dpm.current_active_crtcs) { |
848 | if (rdev->pm.dpm.new_active_crtcs != rdev->pm.dpm.current_active_crtcs) { |
Line 869... | Line 883... | ||
869 | radeon_dpm_print_power_state(rdev, rdev->pm.dpm.current_ps); |
883 | radeon_dpm_print_power_state(rdev, rdev->pm.dpm.current_ps); |
870 | printk("switching to power state:\n"); |
884 | printk("switching to power state:\n"); |
871 | radeon_dpm_print_power_state(rdev, rdev->pm.dpm.requested_ps); |
885 | radeon_dpm_print_power_state(rdev, rdev->pm.dpm.requested_ps); |
872 | } |
886 | } |
Line 873... | Line -... | ||
873 | - | ||
874 | mutex_lock(&rdev->ddev->struct_mutex); |
887 | |
875 | down_write(&rdev->pm.mclk_lock); |
888 | down_write(&rdev->pm.mclk_lock); |
Line 876... | Line 889... | ||
876 | mutex_lock(&rdev->ring_lock); |
889 | mutex_lock(&rdev->ring_lock); |
877 | 890 | ||
Line 887... | Line 900... | ||
887 | /* update displays */ |
900 | /* update displays */ |
888 | radeon_dpm_display_configuration_changed(rdev); |
901 | radeon_dpm_display_configuration_changed(rdev); |
Line 889... | Line 902... | ||
889 | 902 | ||
890 | rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs; |
903 | rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs; |
- | 904 | rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count; |
|
Line 891... | Line 905... | ||
891 | rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count; |
905 | rdev->pm.dpm.single_display = single_display; |
892 | 906 | ||
893 | /* wait for the rings to drain */ |
907 | /* wait for the rings to drain */ |
894 | for (i = 0; i < RADEON_NUM_RINGS; i++) { |
908 | for (i = 0; i < RADEON_NUM_RINGS; i++) { |
Line 919... | Line 933... | ||
919 | } |
933 | } |
Line 920... | Line 934... | ||
920 | 934 | ||
921 | done: |
935 | done: |
922 | mutex_unlock(&rdev->ring_lock); |
936 | mutex_unlock(&rdev->ring_lock); |
923 | up_write(&rdev->pm.mclk_lock); |
- | |
924 | mutex_unlock(&rdev->ddev->struct_mutex); |
937 | up_write(&rdev->pm.mclk_lock); |
Line 925... | Line 938... | ||
925 | } |
938 | } |
926 | 939 | ||
927 | void radeon_dpm_enable_uvd(struct radeon_device *rdev, bool enable) |
940 | void radeon_dpm_enable_uvd(struct radeon_device *rdev, bool enable) |
Line 1216... | Line 1229... | ||
1216 | } |
1229 | } |
1217 | DRM_ERROR("radeon: dpm initialization failed\n"); |
1230 | DRM_ERROR("radeon: dpm initialization failed\n"); |
1218 | return ret; |
1231 | return ret; |
1219 | } |
1232 | } |
Line -... | Line 1233... | ||
- | 1233 | ||
- | 1234 | struct radeon_dpm_quirk { |
|
- | 1235 | u32 chip_vendor; |
|
- | 1236 | u32 chip_device; |
|
- | 1237 | u32 subsys_vendor; |
|
- | 1238 | u32 subsys_device; |
|
- | 1239 | }; |
|
- | 1240 | ||
- | 1241 | /* cards with dpm stability problems */ |
|
- | 1242 | static struct radeon_dpm_quirk radeon_dpm_quirk_list[] = { |
|
- | 1243 | /* TURKS - https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1386534 */ |
|
- | 1244 | { PCI_VENDOR_ID_ATI, 0x6759, 0x1682, 0x3195 }, |
|
- | 1245 | /* TURKS - https://bugzilla.kernel.org/show_bug.cgi?id=83731 */ |
|
- | 1246 | { PCI_VENDOR_ID_ATI, 0x6840, 0x1179, 0xfb81 }, |
|
- | 1247 | { 0, 0, 0, 0 }, |
|
- | 1248 | }; |
|
1220 | 1249 | ||
1221 | int radeon_pm_init(struct radeon_device *rdev) |
1250 | int radeon_pm_init(struct radeon_device *rdev) |
- | 1251 | { |
|
- | 1252 | struct radeon_dpm_quirk *p = radeon_dpm_quirk_list; |
|
- | 1253 | bool disable_dpm = false; |
|
- | 1254 | ||
- | 1255 | /* Apply dpm quirks */ |
|
- | 1256 | while (p && p->chip_device != 0) { |
|
- | 1257 | if (rdev->pdev->vendor == p->chip_vendor && |
|
- | 1258 | rdev->pdev->device == p->chip_device && |
|
- | 1259 | rdev->pdev->subsystem_vendor == p->subsys_vendor && |
|
- | 1260 | rdev->pdev->subsystem_device == p->subsys_device) { |
|
- | 1261 | disable_dpm = true; |
|
- | 1262 | break; |
|
- | 1263 | } |
|
- | 1264 | ++p; |
|
- | 1265 | } |
|
1222 | { |
1266 | |
1223 | /* enable dpm on rv6xx+ */ |
1267 | /* enable dpm on rv6xx+ */ |
1224 | switch (rdev->family) { |
1268 | switch (rdev->family) { |
1225 | case CHIP_RV610: |
1269 | case CHIP_RV610: |
1226 | case CHIP_RV630: |
1270 | case CHIP_RV630: |
Line 1273... | Line 1317... | ||
1273 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
1317 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
1274 | else if ((rdev->family >= CHIP_RV770) && |
1318 | else if ((rdev->family >= CHIP_RV770) && |
1275 | (!(rdev->flags & RADEON_IS_IGP)) && |
1319 | (!(rdev->flags & RADEON_IS_IGP)) && |
1276 | (!rdev->smc_fw)) |
1320 | (!rdev->smc_fw)) |
1277 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
1321 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
- | 1322 | else if (disable_dpm && (radeon_dpm == -1)) |
|
- | 1323 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
|
1278 | else if (radeon_dpm == 0) |
1324 | else if (radeon_dpm == 0) |
1279 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
1325 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
1280 | else |
1326 | else |
1281 | rdev->pm.pm_method = PM_METHOD_DPM; |
1327 | rdev->pm.pm_method = PM_METHOD_DPM; |
1282 | break; |
1328 | break; |
Line 1475... | Line 1521... | ||
1475 | /* Iterate over all active crtc's. All crtc's must be in vblank, |
1521 | /* Iterate over all active crtc's. All crtc's must be in vblank, |
1476 | * otherwise return in_vbl == false. |
1522 | * otherwise return in_vbl == false. |
1477 | */ |
1523 | */ |
1478 | for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) { |
1524 | for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) { |
1479 | if (rdev->pm.active_crtcs & (1 << crtc)) { |
1525 | if (rdev->pm.active_crtcs & (1 << crtc)) { |
1480 | vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, 0, &vpos, &hpos, NULL, NULL); |
1526 | vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, |
- | 1527 | crtc, |
|
- | 1528 | USE_REAL_VBLANKSTART, |
|
- | 1529 | &vpos, &hpos, NULL, NULL, |
|
- | 1530 | &rdev->mode_info.crtcs[crtc]->base.hwmode); |
|
1481 | if ((vbl_status & DRM_SCANOUTPOS_VALID) && |
1531 | if ((vbl_status & DRM_SCANOUTPOS_VALID) && |
1482 | !(vbl_status & DRM_SCANOUTPOS_IN_VBLANK)) |
1532 | !(vbl_status & DRM_SCANOUTPOS_IN_VBLANK)) |
1483 | in_vbl = false; |
1533 | in_vbl = false; |
1484 | } |
1534 | } |
1485 | } |
1535 | } |