Ticket #9343: power.cpp

File power.cpp, 2.4 KB (added by kallisti5, 11 years ago)

rev1

Line 
1/*
2 * Copyright 2012-2013, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Alexander von Gluck IV, kallisti5@unixzen.com
7 */
8
9
10#include "accelerant_protos.h"
11#include "accelerant.h"
12
13#include <string.h>
14
15
16status_t
17intel_pm_downclock(bool enable)
18{
19 if (!gInfo->shared_info->device_type.InGroup(GEN6_TYPE_SNB)
20 && !gInfo->shared_info->device_type.InGroup(GEN6_TYPE_IVB)) {
21 TRACE("%s: Downclocking not supported on this chipset.\n", __func__);
22 return B_ERROR;
23 }
24
25 // TODO: Check for deep RC6
26 // IvyBridge, SandyBridge, and Haswell can do depth 1 atm
27 // Some chipsets can go deeper... but this is safe for now
28 // Haswell should *NOT* do over depth 1;
29 int depth = 1;
30
31 /* Magical sequence of register writes to enable
32 * downclocking from the fine folks at Xorg
33 */
34 write32(GEN6_RC_STATE, 0);
35 // TODO: We may need grab rps states here
36 write32(GEN6_RC_CONTROL, 0);
37
38 write32(GEN6_RC1_WAKE_RATE_LIMIT, 1000 << 16);
39 write32(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16 | 30);
40 write32(GEN6_RC6pp_WAKE_RATE_LIMIT, 30);
41 write32(GEN6_RC_EVALUATION_INTERVAL, 125000);
42 write32(GEN6_RC_IDLE_HYSTERSIS, 25);
43
44 // TODO: Idle each ring
45
46 write32(GEN6_RC_SLEEP, 0);
47 write32(GEN6_RC1e_THRESHOLD, 1000);
48 write32(GEN6_RC6_THRESHOLD, 50000);
49 write32(GEN6_RC6p_THRESHOLD, 100000);
50 write32(GEN6_RC6pp_THRESHOLD, 64000);
51
52 uint32 rc6Mask = GEN6_RC_CTL_RC6_ENABLE;
53
54 if (depth > 1)
55 rc6Mask |= GEN6_RC_CTL_RC6p_ENABLE;
56 if (depth > 2)
57 rc6Mask |= GEN6_RC_CTL_RC6pp_ENABLE;
58
59 write32(GEN6_RC_CONTROL, rc6Mask |
60 write32(GEN6_RPNSWREQ,
61 write32(GEN6_RC_VIDEO_FREQ,
62
63 write32(GEN6_RP_DOWN_TIMEOUT, 1000000);
64 write32(GEN6_RP_INTERRUPT_LIMITS,
65 maxDelay << 24 | minDelay << 16);
66
67 write32(GEN6_RP_UP_THRESHOLD, 59400);
68 write32(GEN6_RP_DOWN_THRESHOLD, 245000);
69 write32(GEN6_RP_UP_EI, 66000);
70 write32(GEN6_RP_DOWN_EI, 350000);
71
72 write32(GEN6_RP_IDLE_HYSTERSIS, 10);
73 write32(GEN6_RP_CONTROL, GEN6_RP_MEDIA_TURBO
74 | GEN6_RP_MEDIA_HW_NORMAL_MODE | GEN6_RP_MEDIA_IS_GFX
75 | GEN6_RP_ENABLE | GEN6_RP_UP_BUSY_AVG
76 | GEN6_RP_DOWN_IDLE_CONT);
77 // TODO: | (HASWELL ? GEN7_RP_DOWN_IDLE_AVG : GEN6_RP_DOWN_IDLE_CONT));
78
79 // TODO: wait for (read32(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY)
80
81 write32(GEN6_PCODE_DATA, 0);
82 write32(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY
83 | GEN6_PCODE_WRITE_MIN_FREQ_TABLE);
84
85 // TODO: wait for (read32(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY)
86
87 // TODO: check for overclock support and set.
88
89}