Subversion Repositories Kolibri OS

Rev

Rev 5271 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5271 Rev 6104
1
/*
1
/*
2
 * Copyright 2012 Advanced Micro Devices, Inc.
2
 * Copyright 2012 Advanced Micro Devices, Inc.
3
 *
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the "Software"),
5
 * copy of this software and associated documentation files (the "Software"),
6
 * to deal in the Software without restriction, including without limitation
6
 * to deal in the Software without restriction, including without limitation
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 * and/or sell copies of the Software, and to permit persons to whom the
8
 * and/or sell copies of the Software, and to permit persons to whom the
9
 * Software is furnished to do so, subject to the following conditions:
9
 * Software is furnished to do so, subject to the following conditions:
10
 *
10
 *
11
 * The above copyright notice and this permission notice shall be included in
11
 * The above copyright notice and this permission notice shall be included in
12
 * all copies or substantial portions of the Software.
12
 * all copies or substantial portions of the Software.
13
 *
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
17
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
19
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20
 * OTHER DEALINGS IN THE SOFTWARE.
20
 * OTHER DEALINGS IN THE SOFTWARE.
21
 *
21
 *
22
 */
22
 */
23
 
23
 
24
#include "drmP.h"
24
#include "drmP.h"
25
#include "radeon.h"
25
#include "radeon.h"
26
#include "radeon_asic.h"
26
#include "radeon_asic.h"
27
#include "trinityd.h"
27
#include "trinityd.h"
28
#include "r600_dpm.h"
28
#include "r600_dpm.h"
29
#include "trinity_dpm.h"
29
#include "trinity_dpm.h"
30
#include 
30
#include 
31
 
31
 
32
#define TRINITY_MAX_DEEPSLEEP_DIVIDER_ID 5
32
#define TRINITY_MAX_DEEPSLEEP_DIVIDER_ID 5
33
#define TRINITY_MINIMUM_ENGINE_CLOCK 800
33
#define TRINITY_MINIMUM_ENGINE_CLOCK 800
34
#define SCLK_MIN_DIV_INTV_SHIFT     12
34
#define SCLK_MIN_DIV_INTV_SHIFT     12
35
#define TRINITY_DISPCLK_BYPASS_THRESHOLD 10000
35
#define TRINITY_DISPCLK_BYPASS_THRESHOLD 10000
36
 
36
 
37
#ifndef TRINITY_MGCG_SEQUENCE
37
#ifndef TRINITY_MGCG_SEQUENCE
38
#define TRINITY_MGCG_SEQUENCE  100
38
#define TRINITY_MGCG_SEQUENCE  100
39
 
39
 
40
static const u32 trinity_mgcg_shls_default[] =
40
static const u32 trinity_mgcg_shls_default[] =
41
{
41
{
42
	/* Register, Value, Mask */
42
	/* Register, Value, Mask */
43
	0x0000802c, 0xc0000000, 0xffffffff,
43
	0x0000802c, 0xc0000000, 0xffffffff,
44
	0x00003fc4, 0xc0000000, 0xffffffff,
44
	0x00003fc4, 0xc0000000, 0xffffffff,
45
	0x00005448, 0x00000100, 0xffffffff,
45
	0x00005448, 0x00000100, 0xffffffff,
46
	0x000055e4, 0x00000100, 0xffffffff,
46
	0x000055e4, 0x00000100, 0xffffffff,
47
	0x0000160c, 0x00000100, 0xffffffff,
47
	0x0000160c, 0x00000100, 0xffffffff,
48
	0x00008984, 0x06000100, 0xffffffff,
48
	0x00008984, 0x06000100, 0xffffffff,
49
	0x0000c164, 0x00000100, 0xffffffff,
49
	0x0000c164, 0x00000100, 0xffffffff,
50
	0x00008a18, 0x00000100, 0xffffffff,
50
	0x00008a18, 0x00000100, 0xffffffff,
51
	0x0000897c, 0x06000100, 0xffffffff,
51
	0x0000897c, 0x06000100, 0xffffffff,
52
	0x00008b28, 0x00000100, 0xffffffff,
52
	0x00008b28, 0x00000100, 0xffffffff,
53
	0x00009144, 0x00800200, 0xffffffff,
53
	0x00009144, 0x00800200, 0xffffffff,
54
	0x00009a60, 0x00000100, 0xffffffff,
54
	0x00009a60, 0x00000100, 0xffffffff,
55
	0x00009868, 0x00000100, 0xffffffff,
55
	0x00009868, 0x00000100, 0xffffffff,
56
	0x00008d58, 0x00000100, 0xffffffff,
56
	0x00008d58, 0x00000100, 0xffffffff,
57
	0x00009510, 0x00000100, 0xffffffff,
57
	0x00009510, 0x00000100, 0xffffffff,
58
	0x0000949c, 0x00000100, 0xffffffff,
58
	0x0000949c, 0x00000100, 0xffffffff,
59
	0x00009654, 0x00000100, 0xffffffff,
59
	0x00009654, 0x00000100, 0xffffffff,
60
	0x00009030, 0x00000100, 0xffffffff,
60
	0x00009030, 0x00000100, 0xffffffff,
61
	0x00009034, 0x00000100, 0xffffffff,
61
	0x00009034, 0x00000100, 0xffffffff,
62
	0x00009038, 0x00000100, 0xffffffff,
62
	0x00009038, 0x00000100, 0xffffffff,
63
	0x0000903c, 0x00000100, 0xffffffff,
63
	0x0000903c, 0x00000100, 0xffffffff,
64
	0x00009040, 0x00000100, 0xffffffff,
64
	0x00009040, 0x00000100, 0xffffffff,
65
	0x0000a200, 0x00000100, 0xffffffff,
65
	0x0000a200, 0x00000100, 0xffffffff,
66
	0x0000a204, 0x00000100, 0xffffffff,
66
	0x0000a204, 0x00000100, 0xffffffff,
67
	0x0000a208, 0x00000100, 0xffffffff,
67
	0x0000a208, 0x00000100, 0xffffffff,
68
	0x0000a20c, 0x00000100, 0xffffffff,
68
	0x0000a20c, 0x00000100, 0xffffffff,
69
	0x00009744, 0x00000100, 0xffffffff,
69
	0x00009744, 0x00000100, 0xffffffff,
70
	0x00003f80, 0x00000100, 0xffffffff,
70
	0x00003f80, 0x00000100, 0xffffffff,
71
	0x0000a210, 0x00000100, 0xffffffff,
71
	0x0000a210, 0x00000100, 0xffffffff,
72
	0x0000a214, 0x00000100, 0xffffffff,
72
	0x0000a214, 0x00000100, 0xffffffff,
73
	0x000004d8, 0x00000100, 0xffffffff,
73
	0x000004d8, 0x00000100, 0xffffffff,
74
	0x00009664, 0x00000100, 0xffffffff,
74
	0x00009664, 0x00000100, 0xffffffff,
75
	0x00009698, 0x00000100, 0xffffffff,
75
	0x00009698, 0x00000100, 0xffffffff,
76
	0x000004d4, 0x00000200, 0xffffffff,
76
	0x000004d4, 0x00000200, 0xffffffff,
77
	0x000004d0, 0x00000000, 0xffffffff,
77
	0x000004d0, 0x00000000, 0xffffffff,
78
	0x000030cc, 0x00000104, 0xffffffff,
78
	0x000030cc, 0x00000104, 0xffffffff,
79
	0x0000d0c0, 0x00000100, 0xffffffff,
79
	0x0000d0c0, 0x00000100, 0xffffffff,
80
	0x0000d8c0, 0x00000100, 0xffffffff,
80
	0x0000d8c0, 0x00000100, 0xffffffff,
81
	0x0000951c, 0x00010000, 0xffffffff,
81
	0x0000951c, 0x00010000, 0xffffffff,
82
	0x00009160, 0x00030002, 0xffffffff,
82
	0x00009160, 0x00030002, 0xffffffff,
83
	0x00009164, 0x00050004, 0xffffffff,
83
	0x00009164, 0x00050004, 0xffffffff,
84
	0x00009168, 0x00070006, 0xffffffff,
84
	0x00009168, 0x00070006, 0xffffffff,
85
	0x00009178, 0x00070000, 0xffffffff,
85
	0x00009178, 0x00070000, 0xffffffff,
86
	0x0000917c, 0x00030002, 0xffffffff,
86
	0x0000917c, 0x00030002, 0xffffffff,
87
	0x00009180, 0x00050004, 0xffffffff,
87
	0x00009180, 0x00050004, 0xffffffff,
88
	0x0000918c, 0x00010006, 0xffffffff,
88
	0x0000918c, 0x00010006, 0xffffffff,
89
	0x00009190, 0x00090008, 0xffffffff,
89
	0x00009190, 0x00090008, 0xffffffff,
90
	0x00009194, 0x00070000, 0xffffffff,
90
	0x00009194, 0x00070000, 0xffffffff,
91
	0x00009198, 0x00030002, 0xffffffff,
91
	0x00009198, 0x00030002, 0xffffffff,
92
	0x0000919c, 0x00050004, 0xffffffff,
92
	0x0000919c, 0x00050004, 0xffffffff,
93
	0x000091a8, 0x00010006, 0xffffffff,
93
	0x000091a8, 0x00010006, 0xffffffff,
94
	0x000091ac, 0x00090008, 0xffffffff,
94
	0x000091ac, 0x00090008, 0xffffffff,
95
	0x000091b0, 0x00070000, 0xffffffff,
95
	0x000091b0, 0x00070000, 0xffffffff,
96
	0x000091b4, 0x00030002, 0xffffffff,
96
	0x000091b4, 0x00030002, 0xffffffff,
97
	0x000091b8, 0x00050004, 0xffffffff,
97
	0x000091b8, 0x00050004, 0xffffffff,
98
	0x000091c4, 0x00010006, 0xffffffff,
98
	0x000091c4, 0x00010006, 0xffffffff,
99
	0x000091c8, 0x00090008, 0xffffffff,
99
	0x000091c8, 0x00090008, 0xffffffff,
100
	0x000091cc, 0x00070000, 0xffffffff,
100
	0x000091cc, 0x00070000, 0xffffffff,
101
	0x000091d0, 0x00030002, 0xffffffff,
101
	0x000091d0, 0x00030002, 0xffffffff,
102
	0x000091d4, 0x00050004, 0xffffffff,
102
	0x000091d4, 0x00050004, 0xffffffff,
103
	0x000091e0, 0x00010006, 0xffffffff,
103
	0x000091e0, 0x00010006, 0xffffffff,
104
	0x000091e4, 0x00090008, 0xffffffff,
104
	0x000091e4, 0x00090008, 0xffffffff,
105
	0x000091e8, 0x00000000, 0xffffffff,
105
	0x000091e8, 0x00000000, 0xffffffff,
106
	0x000091ec, 0x00070000, 0xffffffff,
106
	0x000091ec, 0x00070000, 0xffffffff,
107
	0x000091f0, 0x00030002, 0xffffffff,
107
	0x000091f0, 0x00030002, 0xffffffff,
108
	0x000091f4, 0x00050004, 0xffffffff,
108
	0x000091f4, 0x00050004, 0xffffffff,
109
	0x00009200, 0x00010006, 0xffffffff,
109
	0x00009200, 0x00010006, 0xffffffff,
110
	0x00009204, 0x00090008, 0xffffffff,
110
	0x00009204, 0x00090008, 0xffffffff,
111
	0x00009208, 0x00070000, 0xffffffff,
111
	0x00009208, 0x00070000, 0xffffffff,
112
	0x0000920c, 0x00030002, 0xffffffff,
112
	0x0000920c, 0x00030002, 0xffffffff,
113
	0x00009210, 0x00050004, 0xffffffff,
113
	0x00009210, 0x00050004, 0xffffffff,
114
	0x0000921c, 0x00010006, 0xffffffff,
114
	0x0000921c, 0x00010006, 0xffffffff,
115
	0x00009220, 0x00090008, 0xffffffff,
115
	0x00009220, 0x00090008, 0xffffffff,
116
	0x00009294, 0x00000000, 0xffffffff
116
	0x00009294, 0x00000000, 0xffffffff
117
};
117
};
118
 
118
 
119
static const u32 trinity_mgcg_shls_enable[] =
119
static const u32 trinity_mgcg_shls_enable[] =
120
{
120
{
121
	/* Register, Value, Mask */
121
	/* Register, Value, Mask */
122
	0x0000802c, 0xc0000000, 0xffffffff,
122
	0x0000802c, 0xc0000000, 0xffffffff,
123
	0x000008f8, 0x00000000, 0xffffffff,
123
	0x000008f8, 0x00000000, 0xffffffff,
124
	0x000008fc, 0x00000000, 0x000133FF,
124
	0x000008fc, 0x00000000, 0x000133FF,
125
	0x000008f8, 0x00000001, 0xffffffff,
125
	0x000008f8, 0x00000001, 0xffffffff,
126
	0x000008fc, 0x00000000, 0xE00B03FC,
126
	0x000008fc, 0x00000000, 0xE00B03FC,
127
	0x00009150, 0x96944200, 0xffffffff
127
	0x00009150, 0x96944200, 0xffffffff
128
};
128
};
129
 
129
 
130
static const u32 trinity_mgcg_shls_disable[] =
130
static const u32 trinity_mgcg_shls_disable[] =
131
{
131
{
132
	/* Register, Value, Mask */
132
	/* Register, Value, Mask */
133
	0x0000802c, 0xc0000000, 0xffffffff,
133
	0x0000802c, 0xc0000000, 0xffffffff,
134
	0x00009150, 0x00600000, 0xffffffff,
134
	0x00009150, 0x00600000, 0xffffffff,
135
	0x000008f8, 0x00000000, 0xffffffff,
135
	0x000008f8, 0x00000000, 0xffffffff,
136
	0x000008fc, 0xffffffff, 0x000133FF,
136
	0x000008fc, 0xffffffff, 0x000133FF,
137
	0x000008f8, 0x00000001, 0xffffffff,
137
	0x000008f8, 0x00000001, 0xffffffff,
138
	0x000008fc, 0xffffffff, 0xE00B03FC
138
	0x000008fc, 0xffffffff, 0xE00B03FC
139
};
139
};
140
#endif
140
#endif
141
 
141
 
142
#ifndef TRINITY_SYSLS_SEQUENCE
142
#ifndef TRINITY_SYSLS_SEQUENCE
143
#define TRINITY_SYSLS_SEQUENCE  100
143
#define TRINITY_SYSLS_SEQUENCE  100
144
 
144
 
145
static const u32 trinity_sysls_default[] =
145
static const u32 trinity_sysls_default[] =
146
{
146
{
147
	/* Register, Value, Mask */
147
	/* Register, Value, Mask */
148
	0x000055e8, 0x00000000, 0xffffffff,
148
	0x000055e8, 0x00000000, 0xffffffff,
149
	0x0000d0bc, 0x00000000, 0xffffffff,
149
	0x0000d0bc, 0x00000000, 0xffffffff,
150
	0x0000d8bc, 0x00000000, 0xffffffff,
150
	0x0000d8bc, 0x00000000, 0xffffffff,
151
	0x000015c0, 0x000c1401, 0xffffffff,
151
	0x000015c0, 0x000c1401, 0xffffffff,
152
	0x0000264c, 0x000c0400, 0xffffffff,
152
	0x0000264c, 0x000c0400, 0xffffffff,
153
	0x00002648, 0x000c0400, 0xffffffff,
153
	0x00002648, 0x000c0400, 0xffffffff,
154
	0x00002650, 0x000c0400, 0xffffffff,
154
	0x00002650, 0x000c0400, 0xffffffff,
155
	0x000020b8, 0x000c0400, 0xffffffff,
155
	0x000020b8, 0x000c0400, 0xffffffff,
156
	0x000020bc, 0x000c0400, 0xffffffff,
156
	0x000020bc, 0x000c0400, 0xffffffff,
157
	0x000020c0, 0x000c0c80, 0xffffffff,
157
	0x000020c0, 0x000c0c80, 0xffffffff,
158
	0x0000f4a0, 0x000000c0, 0xffffffff,
158
	0x0000f4a0, 0x000000c0, 0xffffffff,
159
	0x0000f4a4, 0x00680fff, 0xffffffff,
159
	0x0000f4a4, 0x00680fff, 0xffffffff,
160
	0x00002f50, 0x00000404, 0xffffffff,
160
	0x00002f50, 0x00000404, 0xffffffff,
161
	0x000004c8, 0x00000001, 0xffffffff,
161
	0x000004c8, 0x00000001, 0xffffffff,
162
	0x0000641c, 0x00000000, 0xffffffff,
162
	0x0000641c, 0x00000000, 0xffffffff,
163
	0x00000c7c, 0x00000000, 0xffffffff,
163
	0x00000c7c, 0x00000000, 0xffffffff,
164
	0x00006dfc, 0x00000000, 0xffffffff
164
	0x00006dfc, 0x00000000, 0xffffffff
165
};
165
};
166
 
166
 
167
static const u32 trinity_sysls_disable[] =
167
static const u32 trinity_sysls_disable[] =
168
{
168
{
169
	/* Register, Value, Mask */
169
	/* Register, Value, Mask */
170
	0x0000d0c0, 0x00000000, 0xffffffff,
170
	0x0000d0c0, 0x00000000, 0xffffffff,
171
	0x0000d8c0, 0x00000000, 0xffffffff,
171
	0x0000d8c0, 0x00000000, 0xffffffff,
172
	0x000055e8, 0x00000000, 0xffffffff,
172
	0x000055e8, 0x00000000, 0xffffffff,
173
	0x0000d0bc, 0x00000000, 0xffffffff,
173
	0x0000d0bc, 0x00000000, 0xffffffff,
174
	0x0000d8bc, 0x00000000, 0xffffffff,
174
	0x0000d8bc, 0x00000000, 0xffffffff,
175
	0x000015c0, 0x00041401, 0xffffffff,
175
	0x000015c0, 0x00041401, 0xffffffff,
176
	0x0000264c, 0x00040400, 0xffffffff,
176
	0x0000264c, 0x00040400, 0xffffffff,
177
	0x00002648, 0x00040400, 0xffffffff,
177
	0x00002648, 0x00040400, 0xffffffff,
178
	0x00002650, 0x00040400, 0xffffffff,
178
	0x00002650, 0x00040400, 0xffffffff,
179
	0x000020b8, 0x00040400, 0xffffffff,
179
	0x000020b8, 0x00040400, 0xffffffff,
180
	0x000020bc, 0x00040400, 0xffffffff,
180
	0x000020bc, 0x00040400, 0xffffffff,
181
	0x000020c0, 0x00040c80, 0xffffffff,
181
	0x000020c0, 0x00040c80, 0xffffffff,
182
	0x0000f4a0, 0x000000c0, 0xffffffff,
182
	0x0000f4a0, 0x000000c0, 0xffffffff,
183
	0x0000f4a4, 0x00680000, 0xffffffff,
183
	0x0000f4a4, 0x00680000, 0xffffffff,
184
	0x00002f50, 0x00000404, 0xffffffff,
184
	0x00002f50, 0x00000404, 0xffffffff,
185
	0x000004c8, 0x00000001, 0xffffffff,
185
	0x000004c8, 0x00000001, 0xffffffff,
186
	0x0000641c, 0x00007ffd, 0xffffffff,
186
	0x0000641c, 0x00007ffd, 0xffffffff,
187
	0x00000c7c, 0x0000ff00, 0xffffffff,
187
	0x00000c7c, 0x0000ff00, 0xffffffff,
188
	0x00006dfc, 0x0000007f, 0xffffffff
188
	0x00006dfc, 0x0000007f, 0xffffffff
189
};
189
};
190
 
190
 
191
static const u32 trinity_sysls_enable[] =
191
static const u32 trinity_sysls_enable[] =
192
{
192
{
193
	/* Register, Value, Mask */
193
	/* Register, Value, Mask */
194
	0x000055e8, 0x00000001, 0xffffffff,
194
	0x000055e8, 0x00000001, 0xffffffff,
195
	0x0000d0bc, 0x00000100, 0xffffffff,
195
	0x0000d0bc, 0x00000100, 0xffffffff,
196
	0x0000d8bc, 0x00000100, 0xffffffff,
196
	0x0000d8bc, 0x00000100, 0xffffffff,
197
	0x000015c0, 0x000c1401, 0xffffffff,
197
	0x000015c0, 0x000c1401, 0xffffffff,
198
	0x0000264c, 0x000c0400, 0xffffffff,
198
	0x0000264c, 0x000c0400, 0xffffffff,
199
	0x00002648, 0x000c0400, 0xffffffff,
199
	0x00002648, 0x000c0400, 0xffffffff,
200
	0x00002650, 0x000c0400, 0xffffffff,
200
	0x00002650, 0x000c0400, 0xffffffff,
201
	0x000020b8, 0x000c0400, 0xffffffff,
201
	0x000020b8, 0x000c0400, 0xffffffff,
202
	0x000020bc, 0x000c0400, 0xffffffff,
202
	0x000020bc, 0x000c0400, 0xffffffff,
203
	0x000020c0, 0x000c0c80, 0xffffffff,
203
	0x000020c0, 0x000c0c80, 0xffffffff,
204
	0x0000f4a0, 0x000000c0, 0xffffffff,
204
	0x0000f4a0, 0x000000c0, 0xffffffff,
205
	0x0000f4a4, 0x00680fff, 0xffffffff,
205
	0x0000f4a4, 0x00680fff, 0xffffffff,
206
	0x00002f50, 0x00000903, 0xffffffff,
206
	0x00002f50, 0x00000903, 0xffffffff,
207
	0x000004c8, 0x00000000, 0xffffffff,
207
	0x000004c8, 0x00000000, 0xffffffff,
208
	0x0000641c, 0x00000000, 0xffffffff,
208
	0x0000641c, 0x00000000, 0xffffffff,
209
	0x00000c7c, 0x00000000, 0xffffffff,
209
	0x00000c7c, 0x00000000, 0xffffffff,
210
	0x00006dfc, 0x00000000, 0xffffffff
210
	0x00006dfc, 0x00000000, 0xffffffff
211
};
211
};
212
#endif
212
#endif
213
 
213
 
214
static const u32 trinity_override_mgpg_sequences[] =
214
static const u32 trinity_override_mgpg_sequences[] =
215
{
215
{
216
	/* Register, Value */
216
	/* Register, Value */
217
	0x00000200, 0xE030032C,
217
	0x00000200, 0xE030032C,
218
	0x00000204, 0x00000FFF,
218
	0x00000204, 0x00000FFF,
219
	0x00000200, 0xE0300058,
219
	0x00000200, 0xE0300058,
220
	0x00000204, 0x00030301,
220
	0x00000204, 0x00030301,
221
	0x00000200, 0xE0300054,
221
	0x00000200, 0xE0300054,
222
	0x00000204, 0x500010FF,
222
	0x00000204, 0x500010FF,
223
	0x00000200, 0xE0300074,
223
	0x00000200, 0xE0300074,
224
	0x00000204, 0x00030301,
224
	0x00000204, 0x00030301,
225
	0x00000200, 0xE0300070,
225
	0x00000200, 0xE0300070,
226
	0x00000204, 0x500010FF,
226
	0x00000204, 0x500010FF,
227
	0x00000200, 0xE0300090,
227
	0x00000200, 0xE0300090,
228
	0x00000204, 0x00030301,
228
	0x00000204, 0x00030301,
229
	0x00000200, 0xE030008C,
229
	0x00000200, 0xE030008C,
230
	0x00000204, 0x500010FF,
230
	0x00000204, 0x500010FF,
231
	0x00000200, 0xE03000AC,
231
	0x00000200, 0xE03000AC,
232
	0x00000204, 0x00030301,
232
	0x00000204, 0x00030301,
233
	0x00000200, 0xE03000A8,
233
	0x00000200, 0xE03000A8,
234
	0x00000204, 0x500010FF,
234
	0x00000204, 0x500010FF,
235
	0x00000200, 0xE03000C8,
235
	0x00000200, 0xE03000C8,
236
	0x00000204, 0x00030301,
236
	0x00000204, 0x00030301,
237
	0x00000200, 0xE03000C4,
237
	0x00000200, 0xE03000C4,
238
	0x00000204, 0x500010FF,
238
	0x00000204, 0x500010FF,
239
	0x00000200, 0xE03000E4,
239
	0x00000200, 0xE03000E4,
240
	0x00000204, 0x00030301,
240
	0x00000204, 0x00030301,
241
	0x00000200, 0xE03000E0,
241
	0x00000200, 0xE03000E0,
242
	0x00000204, 0x500010FF,
242
	0x00000204, 0x500010FF,
243
	0x00000200, 0xE0300100,
243
	0x00000200, 0xE0300100,
244
	0x00000204, 0x00030301,
244
	0x00000204, 0x00030301,
245
	0x00000200, 0xE03000FC,
245
	0x00000200, 0xE03000FC,
246
	0x00000204, 0x500010FF,
246
	0x00000204, 0x500010FF,
247
	0x00000200, 0xE0300058,
247
	0x00000200, 0xE0300058,
248
	0x00000204, 0x00030303,
248
	0x00000204, 0x00030303,
249
	0x00000200, 0xE0300054,
249
	0x00000200, 0xE0300054,
250
	0x00000204, 0x600010FF,
250
	0x00000204, 0x600010FF,
251
	0x00000200, 0xE0300074,
251
	0x00000200, 0xE0300074,
252
	0x00000204, 0x00030303,
252
	0x00000204, 0x00030303,
253
	0x00000200, 0xE0300070,
253
	0x00000200, 0xE0300070,
254
	0x00000204, 0x600010FF,
254
	0x00000204, 0x600010FF,
255
	0x00000200, 0xE0300090,
255
	0x00000200, 0xE0300090,
256
	0x00000204, 0x00030303,
256
	0x00000204, 0x00030303,
257
	0x00000200, 0xE030008C,
257
	0x00000200, 0xE030008C,
258
	0x00000204, 0x600010FF,
258
	0x00000204, 0x600010FF,
259
	0x00000200, 0xE03000AC,
259
	0x00000200, 0xE03000AC,
260
	0x00000204, 0x00030303,
260
	0x00000204, 0x00030303,
261
	0x00000200, 0xE03000A8,
261
	0x00000200, 0xE03000A8,
262
	0x00000204, 0x600010FF,
262
	0x00000204, 0x600010FF,
263
	0x00000200, 0xE03000C8,
263
	0x00000200, 0xE03000C8,
264
	0x00000204, 0x00030303,
264
	0x00000204, 0x00030303,
265
	0x00000200, 0xE03000C4,
265
	0x00000200, 0xE03000C4,
266
	0x00000204, 0x600010FF,
266
	0x00000204, 0x600010FF,
267
	0x00000200, 0xE03000E4,
267
	0x00000200, 0xE03000E4,
268
	0x00000204, 0x00030303,
268
	0x00000204, 0x00030303,
269
	0x00000200, 0xE03000E0,
269
	0x00000200, 0xE03000E0,
270
	0x00000204, 0x600010FF,
270
	0x00000204, 0x600010FF,
271
	0x00000200, 0xE0300100,
271
	0x00000200, 0xE0300100,
272
	0x00000204, 0x00030303,
272
	0x00000204, 0x00030303,
273
	0x00000200, 0xE03000FC,
273
	0x00000200, 0xE03000FC,
274
	0x00000204, 0x600010FF,
274
	0x00000204, 0x600010FF,
275
	0x00000200, 0xE0300058,
275
	0x00000200, 0xE0300058,
276
	0x00000204, 0x00030303,
276
	0x00000204, 0x00030303,
277
	0x00000200, 0xE0300054,
277
	0x00000200, 0xE0300054,
278
	0x00000204, 0x700010FF,
278
	0x00000204, 0x700010FF,
279
	0x00000200, 0xE0300074,
279
	0x00000200, 0xE0300074,
280
	0x00000204, 0x00030303,
280
	0x00000204, 0x00030303,
281
	0x00000200, 0xE0300070,
281
	0x00000200, 0xE0300070,
282
	0x00000204, 0x700010FF,
282
	0x00000204, 0x700010FF,
283
	0x00000200, 0xE0300090,
283
	0x00000200, 0xE0300090,
284
	0x00000204, 0x00030303,
284
	0x00000204, 0x00030303,
285
	0x00000200, 0xE030008C,
285
	0x00000200, 0xE030008C,
286
	0x00000204, 0x700010FF,
286
	0x00000204, 0x700010FF,
287
	0x00000200, 0xE03000AC,
287
	0x00000200, 0xE03000AC,
288
	0x00000204, 0x00030303,
288
	0x00000204, 0x00030303,
289
	0x00000200, 0xE03000A8,
289
	0x00000200, 0xE03000A8,
290
	0x00000204, 0x700010FF,
290
	0x00000204, 0x700010FF,
291
	0x00000200, 0xE03000C8,
291
	0x00000200, 0xE03000C8,
292
	0x00000204, 0x00030303,
292
	0x00000204, 0x00030303,
293
	0x00000200, 0xE03000C4,
293
	0x00000200, 0xE03000C4,
294
	0x00000204, 0x700010FF,
294
	0x00000204, 0x700010FF,
295
	0x00000200, 0xE03000E4,
295
	0x00000200, 0xE03000E4,
296
	0x00000204, 0x00030303,
296
	0x00000204, 0x00030303,
297
	0x00000200, 0xE03000E0,
297
	0x00000200, 0xE03000E0,
298
	0x00000204, 0x700010FF,
298
	0x00000204, 0x700010FF,
299
	0x00000200, 0xE0300100,
299
	0x00000200, 0xE0300100,
300
	0x00000204, 0x00030303,
300
	0x00000204, 0x00030303,
301
	0x00000200, 0xE03000FC,
301
	0x00000200, 0xE03000FC,
302
	0x00000204, 0x700010FF,
302
	0x00000204, 0x700010FF,
303
	0x00000200, 0xE0300058,
303
	0x00000200, 0xE0300058,
304
	0x00000204, 0x00010303,
304
	0x00000204, 0x00010303,
305
	0x00000200, 0xE0300054,
305
	0x00000200, 0xE0300054,
306
	0x00000204, 0x800010FF,
306
	0x00000204, 0x800010FF,
307
	0x00000200, 0xE0300074,
307
	0x00000200, 0xE0300074,
308
	0x00000204, 0x00010303,
308
	0x00000204, 0x00010303,
309
	0x00000200, 0xE0300070,
309
	0x00000200, 0xE0300070,
310
	0x00000204, 0x800010FF,
310
	0x00000204, 0x800010FF,
311
	0x00000200, 0xE0300090,
311
	0x00000200, 0xE0300090,
312
	0x00000204, 0x00010303,
312
	0x00000204, 0x00010303,
313
	0x00000200, 0xE030008C,
313
	0x00000200, 0xE030008C,
314
	0x00000204, 0x800010FF,
314
	0x00000204, 0x800010FF,
315
	0x00000200, 0xE03000AC,
315
	0x00000200, 0xE03000AC,
316
	0x00000204, 0x00010303,
316
	0x00000204, 0x00010303,
317
	0x00000200, 0xE03000A8,
317
	0x00000200, 0xE03000A8,
318
	0x00000204, 0x800010FF,
318
	0x00000204, 0x800010FF,
319
	0x00000200, 0xE03000C4,
319
	0x00000200, 0xE03000C4,
320
	0x00000204, 0x800010FF,
320
	0x00000204, 0x800010FF,
321
	0x00000200, 0xE03000C8,
321
	0x00000200, 0xE03000C8,
322
	0x00000204, 0x00010303,
322
	0x00000204, 0x00010303,
323
	0x00000200, 0xE03000E4,
323
	0x00000200, 0xE03000E4,
324
	0x00000204, 0x00010303,
324
	0x00000204, 0x00010303,
325
	0x00000200, 0xE03000E0,
325
	0x00000200, 0xE03000E0,
326
	0x00000204, 0x800010FF,
326
	0x00000204, 0x800010FF,
327
	0x00000200, 0xE0300100,
327
	0x00000200, 0xE0300100,
328
	0x00000204, 0x00010303,
328
	0x00000204, 0x00010303,
329
	0x00000200, 0xE03000FC,
329
	0x00000200, 0xE03000FC,
330
	0x00000204, 0x800010FF,
330
	0x00000204, 0x800010FF,
331
	0x00000200, 0x0001f198,
331
	0x00000200, 0x0001f198,
332
	0x00000204, 0x0003ffff,
332
	0x00000204, 0x0003ffff,
333
	0x00000200, 0x0001f19C,
333
	0x00000200, 0x0001f19C,
334
	0x00000204, 0x3fffffff,
334
	0x00000204, 0x3fffffff,
335
	0x00000200, 0xE030032C,
335
	0x00000200, 0xE030032C,
336
	0x00000204, 0x00000000,
336
	0x00000204, 0x00000000,
337
};
337
};
-
 
338
 
338
 
339
extern void vce_v1_0_enable_mgcg(struct radeon_device *rdev, bool enable);
339
static void trinity_program_clk_gating_hw_sequence(struct radeon_device *rdev,
340
static void trinity_program_clk_gating_hw_sequence(struct radeon_device *rdev,
340
						   const u32 *seq, u32 count);
341
						   const u32 *seq, u32 count);
341
static void trinity_override_dynamic_mg_powergating(struct radeon_device *rdev);
342
static void trinity_override_dynamic_mg_powergating(struct radeon_device *rdev);
342
static void trinity_apply_state_adjust_rules(struct radeon_device *rdev,
343
static void trinity_apply_state_adjust_rules(struct radeon_device *rdev,
343
					     struct radeon_ps *new_rps,
344
					     struct radeon_ps *new_rps,
344
					     struct radeon_ps *old_rps);
345
					     struct radeon_ps *old_rps);
345
 
346
 
346
static struct trinity_ps *trinity_get_ps(struct radeon_ps *rps)
347
static struct trinity_ps *trinity_get_ps(struct radeon_ps *rps)
347
{
348
{
348
	struct trinity_ps *ps = rps->ps_priv;
349
	struct trinity_ps *ps = rps->ps_priv;
349
 
350
 
350
	return ps;
351
	return ps;
351
}
352
}
352
 
353
 
353
static struct trinity_power_info *trinity_get_pi(struct radeon_device *rdev)
354
static struct trinity_power_info *trinity_get_pi(struct radeon_device *rdev)
354
{
355
{
355
	struct trinity_power_info *pi = rdev->pm.dpm.priv;
356
	struct trinity_power_info *pi = rdev->pm.dpm.priv;
356
 
357
 
357
	return pi;
358
	return pi;
358
}
359
}
359
 
360
 
360
static void trinity_gfx_powergating_initialize(struct radeon_device *rdev)
361
static void trinity_gfx_powergating_initialize(struct radeon_device *rdev)
361
{
362
{
362
	struct trinity_power_info *pi = trinity_get_pi(rdev);
363
	struct trinity_power_info *pi = trinity_get_pi(rdev);
363
	u32 p, u;
364
	u32 p, u;
364
	u32 value;
365
	u32 value;
365
	struct atom_clock_dividers dividers;
366
	struct atom_clock_dividers dividers;
366
	u32 xclk = radeon_get_xclk(rdev);
367
	u32 xclk = radeon_get_xclk(rdev);
367
	u32 sssd = 1;
368
	u32 sssd = 1;
368
	int ret;
369
	int ret;
369
	u32 hw_rev = (RREG32(HW_REV) & ATI_REV_ID_MASK) >> ATI_REV_ID_SHIFT;
370
	u32 hw_rev = (RREG32(HW_REV) & ATI_REV_ID_MASK) >> ATI_REV_ID_SHIFT;
370
 
371
 
371
        ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
372
        ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
372
                                             25000, false, ÷rs);
373
                                             25000, false, ÷rs);
373
	if (ret)
374
	if (ret)
374
		return;
375
		return;
375
 
376
 
376
	value = RREG32_SMC(GFX_POWER_GATING_CNTL);
377
	value = RREG32_SMC(GFX_POWER_GATING_CNTL);
377
	value &= ~(SSSD_MASK | PDS_DIV_MASK);
378
	value &= ~(SSSD_MASK | PDS_DIV_MASK);
378
	if (sssd)
379
	if (sssd)
379
		value |= SSSD(1);
380
		value |= SSSD(1);
380
	value |= PDS_DIV(dividers.post_div);
381
	value |= PDS_DIV(dividers.post_div);
381
	WREG32_SMC(GFX_POWER_GATING_CNTL, value);
382
	WREG32_SMC(GFX_POWER_GATING_CNTL, value);
382
 
383
 
383
	r600_calculate_u_and_p(500, xclk, 16, &p, &u);
384
	r600_calculate_u_and_p(500, xclk, 16, &p, &u);
384
 
385
 
385
	WREG32(CG_PG_CTRL, SP(p) | SU(u));
386
	WREG32(CG_PG_CTRL, SP(p) | SU(u));
386
 
387
 
387
	WREG32_P(CG_GIPOTS, CG_GIPOT(p), ~CG_GIPOT_MASK);
388
	WREG32_P(CG_GIPOTS, CG_GIPOT(p), ~CG_GIPOT_MASK);
388
 
389
 
389
	/* XXX double check hw_rev */
390
	/* XXX double check hw_rev */
390
	if (pi->override_dynamic_mgpg && (hw_rev == 0))
391
	if (pi->override_dynamic_mgpg && (hw_rev == 0))
391
		trinity_override_dynamic_mg_powergating(rdev);
392
		trinity_override_dynamic_mg_powergating(rdev);
392
 
393
 
393
}
394
}
394
 
395
 
395
#define CGCG_CGTT_LOCAL0_MASK       0xFFFF33FF
396
#define CGCG_CGTT_LOCAL0_MASK       0xFFFF33FF
396
#define CGCG_CGTT_LOCAL1_MASK       0xFFFB0FFE
397
#define CGCG_CGTT_LOCAL1_MASK       0xFFFB0FFE
397
#define CGTS_SM_CTRL_REG_DISABLE    0x00600000
398
#define CGTS_SM_CTRL_REG_DISABLE    0x00600000
398
#define CGTS_SM_CTRL_REG_ENABLE     0x96944200
399
#define CGTS_SM_CTRL_REG_ENABLE     0x96944200
399
 
400
 
400
static void trinity_mg_clockgating_enable(struct radeon_device *rdev,
401
static void trinity_mg_clockgating_enable(struct radeon_device *rdev,
401
					  bool enable)
402
					  bool enable)
402
{
403
{
403
	u32 local0;
404
	u32 local0;
404
	u32 local1;
405
	u32 local1;
405
 
406
 
406
	if (enable) {
407
	if (enable) {
407
		local0 = RREG32_CG(CG_CGTT_LOCAL_0);
408
		local0 = RREG32_CG(CG_CGTT_LOCAL_0);
408
		local1 = RREG32_CG(CG_CGTT_LOCAL_1);
409
		local1 = RREG32_CG(CG_CGTT_LOCAL_1);
409
 
410
 
410
		WREG32_CG(CG_CGTT_LOCAL_0,
411
		WREG32_CG(CG_CGTT_LOCAL_0,
411
			  (0x00380000 & CGCG_CGTT_LOCAL0_MASK) | (local0 & ~CGCG_CGTT_LOCAL0_MASK) );
412
			  (0x00380000 & CGCG_CGTT_LOCAL0_MASK) | (local0 & ~CGCG_CGTT_LOCAL0_MASK) );
412
		WREG32_CG(CG_CGTT_LOCAL_1,
413
		WREG32_CG(CG_CGTT_LOCAL_1,
413
			  (0x0E000000 & CGCG_CGTT_LOCAL1_MASK) | (local1 & ~CGCG_CGTT_LOCAL1_MASK) );
414
			  (0x0E000000 & CGCG_CGTT_LOCAL1_MASK) | (local1 & ~CGCG_CGTT_LOCAL1_MASK) );
414
 
415
 
415
		WREG32(CGTS_SM_CTRL_REG, CGTS_SM_CTRL_REG_ENABLE);
416
		WREG32(CGTS_SM_CTRL_REG, CGTS_SM_CTRL_REG_ENABLE);
416
	} else {
417
	} else {
417
		WREG32(CGTS_SM_CTRL_REG, CGTS_SM_CTRL_REG_DISABLE);
418
		WREG32(CGTS_SM_CTRL_REG, CGTS_SM_CTRL_REG_DISABLE);
418
 
419
 
419
		local0 = RREG32_CG(CG_CGTT_LOCAL_0);
420
		local0 = RREG32_CG(CG_CGTT_LOCAL_0);
420
		local1 = RREG32_CG(CG_CGTT_LOCAL_1);
421
		local1 = RREG32_CG(CG_CGTT_LOCAL_1);
421
 
422
 
422
		WREG32_CG(CG_CGTT_LOCAL_0,
423
		WREG32_CG(CG_CGTT_LOCAL_0,
423
			  CGCG_CGTT_LOCAL0_MASK | (local0 & ~CGCG_CGTT_LOCAL0_MASK) );
424
			  CGCG_CGTT_LOCAL0_MASK | (local0 & ~CGCG_CGTT_LOCAL0_MASK) );
424
		WREG32_CG(CG_CGTT_LOCAL_1,
425
		WREG32_CG(CG_CGTT_LOCAL_1,
425
			  CGCG_CGTT_LOCAL1_MASK | (local1 & ~CGCG_CGTT_LOCAL1_MASK) );
426
			  CGCG_CGTT_LOCAL1_MASK | (local1 & ~CGCG_CGTT_LOCAL1_MASK) );
426
	}
427
	}
427
}
428
}
428
 
429
 
429
static void trinity_mg_clockgating_initialize(struct radeon_device *rdev)
430
static void trinity_mg_clockgating_initialize(struct radeon_device *rdev)
430
{
431
{
431
	u32 count;
432
	u32 count;
432
	const u32 *seq = NULL;
433
	const u32 *seq = NULL;
433
 
434
 
434
	seq = &trinity_mgcg_shls_default[0];
435
	seq = &trinity_mgcg_shls_default[0];
435
	count = sizeof(trinity_mgcg_shls_default) / (3 * sizeof(u32));
436
	count = sizeof(trinity_mgcg_shls_default) / (3 * sizeof(u32));
436
 
437
 
437
	trinity_program_clk_gating_hw_sequence(rdev, seq, count);
438
	trinity_program_clk_gating_hw_sequence(rdev, seq, count);
438
}
439
}
439
 
440
 
440
static void trinity_gfx_clockgating_enable(struct radeon_device *rdev,
441
static void trinity_gfx_clockgating_enable(struct radeon_device *rdev,
441
					   bool enable)
442
					   bool enable)
442
{
443
{
443
	if (enable) {
444
	if (enable) {
444
		WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
445
		WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
445
	} else {
446
	} else {
446
		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
447
		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
447
		WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON);
448
		WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON);
448
		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON);
449
		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON);
449
		RREG32(GB_ADDR_CONFIG);
450
		RREG32(GB_ADDR_CONFIG);
450
	}
451
	}
451
}
452
}
452
 
453
 
453
static void trinity_program_clk_gating_hw_sequence(struct radeon_device *rdev,
454
static void trinity_program_clk_gating_hw_sequence(struct radeon_device *rdev,
454
						   const u32 *seq, u32 count)
455
						   const u32 *seq, u32 count)
455
{
456
{
456
	u32 i, length = count * 3;
457
	u32 i, length = count * 3;
457
 
458
 
458
	for (i = 0; i < length; i += 3)
459
	for (i = 0; i < length; i += 3)
459
		WREG32_P(seq[i], seq[i+1], ~seq[i+2]);
460
		WREG32_P(seq[i], seq[i+1], ~seq[i+2]);
460
}
461
}
461
 
462
 
462
static void trinity_program_override_mgpg_sequences(struct radeon_device *rdev,
463
static void trinity_program_override_mgpg_sequences(struct radeon_device *rdev,
463
						    const u32 *seq, u32 count)
464
						    const u32 *seq, u32 count)
464
{
465
{
465
	u32  i, length = count * 2;
466
	u32  i, length = count * 2;
466
 
467
 
467
	for (i = 0; i < length; i += 2)
468
	for (i = 0; i < length; i += 2)
468
		WREG32(seq[i], seq[i+1]);
469
		WREG32(seq[i], seq[i+1]);
469
 
470
 
470
}
471
}
471
 
472
 
472
static void trinity_override_dynamic_mg_powergating(struct radeon_device *rdev)
473
static void trinity_override_dynamic_mg_powergating(struct radeon_device *rdev)
473
{
474
{
474
	u32 count;
475
	u32 count;
475
	const u32 *seq = NULL;
476
	const u32 *seq = NULL;
476
 
477
 
477
	seq = &trinity_override_mgpg_sequences[0];
478
	seq = &trinity_override_mgpg_sequences[0];
478
	count = sizeof(trinity_override_mgpg_sequences) / (2 * sizeof(u32));
479
	count = sizeof(trinity_override_mgpg_sequences) / (2 * sizeof(u32));
479
 
480
 
480
	trinity_program_override_mgpg_sequences(rdev, seq, count);
481
	trinity_program_override_mgpg_sequences(rdev, seq, count);
481
}
482
}
482
 
483
 
483
static void trinity_ls_clockgating_enable(struct radeon_device *rdev,
484
static void trinity_ls_clockgating_enable(struct radeon_device *rdev,
484
					  bool enable)
485
					  bool enable)
485
{
486
{
486
	u32 count;
487
	u32 count;
487
	const u32 *seq = NULL;
488
	const u32 *seq = NULL;
488
 
489
 
489
	if (enable) {
490
	if (enable) {
490
		seq = &trinity_sysls_enable[0];
491
		seq = &trinity_sysls_enable[0];
491
		count = sizeof(trinity_sysls_enable) / (3 * sizeof(u32));
492
		count = sizeof(trinity_sysls_enable) / (3 * sizeof(u32));
492
	} else {
493
	} else {
493
		seq = &trinity_sysls_disable[0];
494
		seq = &trinity_sysls_disable[0];
494
		count = sizeof(trinity_sysls_disable) / (3 * sizeof(u32));
495
		count = sizeof(trinity_sysls_disable) / (3 * sizeof(u32));
495
	}
496
	}
496
 
497
 
497
	trinity_program_clk_gating_hw_sequence(rdev, seq, count);
498
	trinity_program_clk_gating_hw_sequence(rdev, seq, count);
498
}
499
}
499
 
500
 
500
static void trinity_gfx_powergating_enable(struct radeon_device *rdev,
501
static void trinity_gfx_powergating_enable(struct radeon_device *rdev,
501
					   bool enable)
502
					   bool enable)
502
{
503
{
503
	if (enable) {
504
	if (enable) {
504
		if (RREG32_SMC(CC_SMU_TST_EFUSE1_MISC) & RB_BACKEND_DISABLE_MASK)
505
		if (RREG32_SMC(CC_SMU_TST_EFUSE1_MISC) & RB_BACKEND_DISABLE_MASK)
505
			WREG32_SMC(SMU_SCRATCH_A, (RREG32_SMC(SMU_SCRATCH_A) | 0x01));
506
			WREG32_SMC(SMU_SCRATCH_A, (RREG32_SMC(SMU_SCRATCH_A) | 0x01));
506
 
507
 
507
		WREG32_P(SCLK_PWRMGT_CNTL, DYN_PWR_DOWN_EN, ~DYN_PWR_DOWN_EN);
508
		WREG32_P(SCLK_PWRMGT_CNTL, DYN_PWR_DOWN_EN, ~DYN_PWR_DOWN_EN);
508
	} else {
509
	} else {
509
		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_PWR_DOWN_EN);
510
		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_PWR_DOWN_EN);
510
		RREG32(GB_ADDR_CONFIG);
511
		RREG32(GB_ADDR_CONFIG);
511
	}
512
	}
512
}
513
}
513
 
514
 
514
static void trinity_gfx_dynamic_mgpg_enable(struct radeon_device *rdev,
515
static void trinity_gfx_dynamic_mgpg_enable(struct radeon_device *rdev,
515
					    bool enable)
516
					    bool enable)
516
{
517
{
517
	u32 value;
518
	u32 value;
518
 
519
 
519
	if (enable) {
520
	if (enable) {
520
		value = RREG32_SMC(PM_I_CNTL_1);
521
		value = RREG32_SMC(PM_I_CNTL_1);
521
		value &= ~DS_PG_CNTL_MASK;
522
		value &= ~DS_PG_CNTL_MASK;
522
		value |= DS_PG_CNTL(1);
523
		value |= DS_PG_CNTL(1);
523
		WREG32_SMC(PM_I_CNTL_1, value);
524
		WREG32_SMC(PM_I_CNTL_1, value);
524
 
525
 
525
		value = RREG32_SMC(SMU_S_PG_CNTL);
526
		value = RREG32_SMC(SMU_S_PG_CNTL);
526
		value &= ~DS_PG_EN_MASK;
527
		value &= ~DS_PG_EN_MASK;
527
		value |= DS_PG_EN(1);
528
		value |= DS_PG_EN(1);
528
		WREG32_SMC(SMU_S_PG_CNTL, value);
529
		WREG32_SMC(SMU_S_PG_CNTL, value);
529
	} else {
530
	} else {
530
		value = RREG32_SMC(SMU_S_PG_CNTL);
531
		value = RREG32_SMC(SMU_S_PG_CNTL);
531
		value &= ~DS_PG_EN_MASK;
532
		value &= ~DS_PG_EN_MASK;
532
		WREG32_SMC(SMU_S_PG_CNTL, value);
533
		WREG32_SMC(SMU_S_PG_CNTL, value);
533
 
534
 
534
		value = RREG32_SMC(PM_I_CNTL_1);
535
		value = RREG32_SMC(PM_I_CNTL_1);
535
		value &= ~DS_PG_CNTL_MASK;
536
		value &= ~DS_PG_CNTL_MASK;
536
		WREG32_SMC(PM_I_CNTL_1, value);
537
		WREG32_SMC(PM_I_CNTL_1, value);
537
	}
538
	}
538
 
539
 
539
	trinity_gfx_dynamic_mgpg_config(rdev);
540
	trinity_gfx_dynamic_mgpg_config(rdev);
540
 
541
 
541
}
542
}
542
 
543
 
543
static void trinity_enable_clock_power_gating(struct radeon_device *rdev)
544
static void trinity_enable_clock_power_gating(struct radeon_device *rdev)
544
{
545
{
545
	struct trinity_power_info *pi = trinity_get_pi(rdev);
546
	struct trinity_power_info *pi = trinity_get_pi(rdev);
546
 
547
 
547
	if (pi->enable_gfx_clock_gating)
548
	if (pi->enable_gfx_clock_gating)
548
		sumo_gfx_clockgating_initialize(rdev);
549
		sumo_gfx_clockgating_initialize(rdev);
549
	if (pi->enable_mg_clock_gating)
550
	if (pi->enable_mg_clock_gating)
550
		trinity_mg_clockgating_initialize(rdev);
551
		trinity_mg_clockgating_initialize(rdev);
551
	if (pi->enable_gfx_power_gating)
552
	if (pi->enable_gfx_power_gating)
552
		trinity_gfx_powergating_initialize(rdev);
553
		trinity_gfx_powergating_initialize(rdev);
553
	if (pi->enable_mg_clock_gating) {
554
	if (pi->enable_mg_clock_gating) {
554
		trinity_ls_clockgating_enable(rdev, true);
555
		trinity_ls_clockgating_enable(rdev, true);
555
		trinity_mg_clockgating_enable(rdev, true);
556
		trinity_mg_clockgating_enable(rdev, true);
556
	}
557
	}
557
	if (pi->enable_gfx_clock_gating)
558
	if (pi->enable_gfx_clock_gating)
558
		trinity_gfx_clockgating_enable(rdev, true);
559
		trinity_gfx_clockgating_enable(rdev, true);
559
	if (pi->enable_gfx_dynamic_mgpg)
560
	if (pi->enable_gfx_dynamic_mgpg)
560
		trinity_gfx_dynamic_mgpg_enable(rdev, true);
561
		trinity_gfx_dynamic_mgpg_enable(rdev, true);
561
	if (pi->enable_gfx_power_gating)
562
	if (pi->enable_gfx_power_gating)
562
		trinity_gfx_powergating_enable(rdev, true);
563
		trinity_gfx_powergating_enable(rdev, true);
563
}
564
}
564
 
565
 
565
static void trinity_disable_clock_power_gating(struct radeon_device *rdev)
566
static void trinity_disable_clock_power_gating(struct radeon_device *rdev)
566
{
567
{
567
	struct trinity_power_info *pi = trinity_get_pi(rdev);
568
	struct trinity_power_info *pi = trinity_get_pi(rdev);
568
 
569
 
569
	if (pi->enable_gfx_power_gating)
570
	if (pi->enable_gfx_power_gating)
570
		trinity_gfx_powergating_enable(rdev, false);
571
		trinity_gfx_powergating_enable(rdev, false);
571
	if (pi->enable_gfx_dynamic_mgpg)
572
	if (pi->enable_gfx_dynamic_mgpg)
572
		trinity_gfx_dynamic_mgpg_enable(rdev, false);
573
		trinity_gfx_dynamic_mgpg_enable(rdev, false);
573
	if (pi->enable_gfx_clock_gating)
574
	if (pi->enable_gfx_clock_gating)
574
		trinity_gfx_clockgating_enable(rdev, false);
575
		trinity_gfx_clockgating_enable(rdev, false);
575
	if (pi->enable_mg_clock_gating) {
576
	if (pi->enable_mg_clock_gating) {
576
		trinity_mg_clockgating_enable(rdev, false);
577
		trinity_mg_clockgating_enable(rdev, false);
577
		trinity_ls_clockgating_enable(rdev, false);
578
		trinity_ls_clockgating_enable(rdev, false);
578
	}
579
	}
579
}
580
}
580
 
581
 
581
static void trinity_set_divider_value(struct radeon_device *rdev,
582
static void trinity_set_divider_value(struct radeon_device *rdev,
582
				      u32 index, u32 sclk)
583
				      u32 index, u32 sclk)
583
{
584
{
584
	struct atom_clock_dividers  dividers;
585
	struct atom_clock_dividers  dividers;
585
	int ret;
586
	int ret;
586
	u32 value;
587
	u32 value;
587
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
588
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
588
 
589
 
589
        ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
590
        ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
590
                                             sclk, false, ÷rs);
591
                                             sclk, false, ÷rs);
591
	if (ret)
592
	if (ret)
592
		return;
593
		return;
593
 
594
 
594
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
595
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
595
	value &= ~CLK_DIVIDER_MASK;
596
	value &= ~CLK_DIVIDER_MASK;
596
	value |= CLK_DIVIDER(dividers.post_div);
597
	value |= CLK_DIVIDER(dividers.post_div);
597
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
598
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
598
 
599
 
599
        ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
600
        ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
600
                                             sclk/2, false, ÷rs);
601
                                             sclk/2, false, ÷rs);
601
	if (ret)
602
	if (ret)
602
		return;
603
		return;
603
 
604
 
604
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_PG_CNTL + ix);
605
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_PG_CNTL + ix);
605
	value &= ~PD_SCLK_DIVIDER_MASK;
606
	value &= ~PD_SCLK_DIVIDER_MASK;
606
	value |= PD_SCLK_DIVIDER(dividers.post_div);
607
	value |= PD_SCLK_DIVIDER(dividers.post_div);
607
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_PG_CNTL + ix, value);
608
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_PG_CNTL + ix, value);
608
}
609
}
609
 
610
 
610
static void trinity_set_ds_dividers(struct radeon_device *rdev,
611
static void trinity_set_ds_dividers(struct radeon_device *rdev,
611
				    u32 index, u32 divider)
612
				    u32 index, u32 divider)
612
{
613
{
613
	u32 value;
614
	u32 value;
614
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
615
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
615
 
616
 
616
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
617
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
617
	value &= ~DS_DIV_MASK;
618
	value &= ~DS_DIV_MASK;
618
	value |= DS_DIV(divider);
619
	value |= DS_DIV(divider);
619
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
620
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
620
}
621
}
621
 
622
 
622
static void trinity_set_ss_dividers(struct radeon_device *rdev,
623
static void trinity_set_ss_dividers(struct radeon_device *rdev,
623
				    u32 index, u32 divider)
624
				    u32 index, u32 divider)
624
{
625
{
625
	u32 value;
626
	u32 value;
626
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
627
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
627
 
628
 
628
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
629
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
629
	value &= ~DS_SH_DIV_MASK;
630
	value &= ~DS_SH_DIV_MASK;
630
	value |= DS_SH_DIV(divider);
631
	value |= DS_SH_DIV(divider);
631
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
632
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
632
}
633
}
633
 
634
 
634
static void trinity_set_vid(struct radeon_device *rdev, u32 index, u32 vid)
635
static void trinity_set_vid(struct radeon_device *rdev, u32 index, u32 vid)
635
{
636
{
636
	struct trinity_power_info *pi = trinity_get_pi(rdev);
637
	struct trinity_power_info *pi = trinity_get_pi(rdev);
637
	u32 vid_7bit = sumo_convert_vid2_to_vid7(rdev, &pi->sys_info.vid_mapping_table, vid);
638
	u32 vid_7bit = sumo_convert_vid2_to_vid7(rdev, &pi->sys_info.vid_mapping_table, vid);
638
	u32 value;
639
	u32 value;
639
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
640
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
640
 
641
 
641
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
642
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
642
	value &= ~VID_MASK;
643
	value &= ~VID_MASK;
643
	value |= VID(vid_7bit);
644
	value |= VID(vid_7bit);
644
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
645
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
645
 
646
 
646
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
647
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
647
	value &= ~LVRT_MASK;
648
	value &= ~LVRT_MASK;
648
	value |= LVRT(0);
649
	value |= LVRT(0);
649
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
650
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
650
}
651
}
651
 
652
 
652
static void trinity_set_allos_gnb_slow(struct radeon_device *rdev,
653
static void trinity_set_allos_gnb_slow(struct radeon_device *rdev,
653
				       u32 index, u32 gnb_slow)
654
				       u32 index, u32 gnb_slow)
654
{
655
{
655
	u32 value;
656
	u32 value;
656
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
657
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
657
 
658
 
658
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix);
659
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix);
659
	value &= ~GNB_SLOW_MASK;
660
	value &= ~GNB_SLOW_MASK;
660
	value |= GNB_SLOW(gnb_slow);
661
	value |= GNB_SLOW(gnb_slow);
661
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix, value);
662
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix, value);
662
}
663
}
663
 
664
 
664
static void trinity_set_force_nbp_state(struct radeon_device *rdev,
665
static void trinity_set_force_nbp_state(struct radeon_device *rdev,
665
					u32 index, u32 force_nbp_state)
666
					u32 index, u32 force_nbp_state)
666
{
667
{
667
	u32 value;
668
	u32 value;
668
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
669
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
669
 
670
 
670
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix);
671
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix);
671
	value &= ~FORCE_NBPS1_MASK;
672
	value &= ~FORCE_NBPS1_MASK;
672
	value |= FORCE_NBPS1(force_nbp_state);
673
	value |= FORCE_NBPS1(force_nbp_state);
673
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix, value);
674
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix, value);
674
}
675
}
675
 
676
 
676
static void trinity_set_display_wm(struct radeon_device *rdev,
677
static void trinity_set_display_wm(struct radeon_device *rdev,
677
				   u32 index, u32 wm)
678
				   u32 index, u32 wm)
678
{
679
{
679
	u32 value;
680
	u32 value;
680
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
681
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
681
 
682
 
682
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
683
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
683
	value &= ~DISPLAY_WM_MASK;
684
	value &= ~DISPLAY_WM_MASK;
684
	value |= DISPLAY_WM(wm);
685
	value |= DISPLAY_WM(wm);
685
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
686
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
686
}
687
}
687
 
688
 
688
static void trinity_set_vce_wm(struct radeon_device *rdev,
689
static void trinity_set_vce_wm(struct radeon_device *rdev,
689
			       u32 index, u32 wm)
690
			       u32 index, u32 wm)
690
{
691
{
691
	u32 value;
692
	u32 value;
692
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
693
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
693
 
694
 
694
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
695
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
695
	value &= ~VCE_WM_MASK;
696
	value &= ~VCE_WM_MASK;
696
	value |= VCE_WM(wm);
697
	value |= VCE_WM(wm);
697
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
698
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
698
}
699
}
699
 
700
 
700
static void trinity_set_at(struct radeon_device *rdev,
701
static void trinity_set_at(struct radeon_device *rdev,
701
			   u32 index, u32 at)
702
			   u32 index, u32 at)
702
{
703
{
703
	u32 value;
704
	u32 value;
704
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
705
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
705
 
706
 
706
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_AT + ix);
707
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_AT + ix);
707
	value &= ~AT_MASK;
708
	value &= ~AT_MASK;
708
	value |= AT(at);
709
	value |= AT(at);
709
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_AT + ix, value);
710
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_AT + ix, value);
710
}
711
}
711
 
712
 
712
static void trinity_program_power_level(struct radeon_device *rdev,
713
static void trinity_program_power_level(struct radeon_device *rdev,
713
					struct trinity_pl *pl, u32 index)
714
					struct trinity_pl *pl, u32 index)
714
{
715
{
715
	struct trinity_power_info *pi = trinity_get_pi(rdev);
716
	struct trinity_power_info *pi = trinity_get_pi(rdev);
716
 
717
 
717
	if (index >= SUMO_MAX_HARDWARE_POWERLEVELS)
718
	if (index >= SUMO_MAX_HARDWARE_POWERLEVELS)
718
		return;
719
		return;
719
 
720
 
720
	trinity_set_divider_value(rdev, index, pl->sclk);
721
	trinity_set_divider_value(rdev, index, pl->sclk);
721
	trinity_set_vid(rdev, index, pl->vddc_index);
722
	trinity_set_vid(rdev, index, pl->vddc_index);
722
	trinity_set_ss_dividers(rdev, index, pl->ss_divider_index);
723
	trinity_set_ss_dividers(rdev, index, pl->ss_divider_index);
723
	trinity_set_ds_dividers(rdev, index, pl->ds_divider_index);
724
	trinity_set_ds_dividers(rdev, index, pl->ds_divider_index);
724
	trinity_set_allos_gnb_slow(rdev, index, pl->allow_gnb_slow);
725
	trinity_set_allos_gnb_slow(rdev, index, pl->allow_gnb_slow);
725
	trinity_set_force_nbp_state(rdev, index, pl->force_nbp_state);
726
	trinity_set_force_nbp_state(rdev, index, pl->force_nbp_state);
726
	trinity_set_display_wm(rdev, index, pl->display_wm);
727
	trinity_set_display_wm(rdev, index, pl->display_wm);
727
	trinity_set_vce_wm(rdev, index, pl->vce_wm);
728
	trinity_set_vce_wm(rdev, index, pl->vce_wm);
728
	trinity_set_at(rdev, index, pi->at[index]);
729
	trinity_set_at(rdev, index, pi->at[index]);
729
}
730
}
730
 
731
 
731
static void trinity_power_level_enable_disable(struct radeon_device *rdev,
732
static void trinity_power_level_enable_disable(struct radeon_device *rdev,
732
					       u32 index, bool enable)
733
					       u32 index, bool enable)
733
{
734
{
734
	u32 value;
735
	u32 value;
735
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
736
	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
736
 
737
 
737
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
738
	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
738
	value &= ~STATE_VALID_MASK;
739
	value &= ~STATE_VALID_MASK;
739
	if (enable)
740
	if (enable)
740
		value |= STATE_VALID(1);
741
		value |= STATE_VALID(1);
741
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
742
	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
742
}
743
}
743
 
744
 
744
static bool trinity_dpm_enabled(struct radeon_device *rdev)
745
static bool trinity_dpm_enabled(struct radeon_device *rdev)
745
{
746
{
746
	if (RREG32_SMC(SMU_SCLK_DPM_CNTL) & SCLK_DPM_EN(1))
747
	if (RREG32_SMC(SMU_SCLK_DPM_CNTL) & SCLK_DPM_EN(1))
747
		return true;
748
		return true;
748
	else
749
	else
749
		return false;
750
		return false;
750
}
751
}
751
 
752
 
752
static void trinity_start_dpm(struct radeon_device *rdev)
753
static void trinity_start_dpm(struct radeon_device *rdev)
753
{
754
{
754
	u32 value = RREG32_SMC(SMU_SCLK_DPM_CNTL);
755
	u32 value = RREG32_SMC(SMU_SCLK_DPM_CNTL);
755
 
756
 
756
	value &= ~(SCLK_DPM_EN_MASK | SCLK_DPM_BOOT_STATE_MASK | VOLTAGE_CHG_EN_MASK);
757
	value &= ~(SCLK_DPM_EN_MASK | SCLK_DPM_BOOT_STATE_MASK | VOLTAGE_CHG_EN_MASK);
757
	value |= SCLK_DPM_EN(1) | SCLK_DPM_BOOT_STATE(0) | VOLTAGE_CHG_EN(1);
758
	value |= SCLK_DPM_EN(1) | SCLK_DPM_BOOT_STATE(0) | VOLTAGE_CHG_EN(1);
758
	WREG32_SMC(SMU_SCLK_DPM_CNTL, value);
759
	WREG32_SMC(SMU_SCLK_DPM_CNTL, value);
759
 
760
 
760
	WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN);
761
	WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN);
761
	WREG32_P(CG_CG_VOLTAGE_CNTL, 0, ~EN);
762
	WREG32_P(CG_CG_VOLTAGE_CNTL, 0, ~EN);
762
 
763
 
763
	trinity_dpm_config(rdev, true);
764
	trinity_dpm_config(rdev, true);
764
}
765
}
765
 
766
 
766
static void trinity_wait_for_dpm_enabled(struct radeon_device *rdev)
767
static void trinity_wait_for_dpm_enabled(struct radeon_device *rdev)
767
{
768
{
768
	int i;
769
	int i;
769
 
770
 
770
	for (i = 0; i < rdev->usec_timeout; i++) {
771
	for (i = 0; i < rdev->usec_timeout; i++) {
771
		if (RREG32(SCLK_PWRMGT_CNTL) & DYNAMIC_PM_EN)
772
		if (RREG32(SCLK_PWRMGT_CNTL) & DYNAMIC_PM_EN)
772
			break;
773
			break;
773
		udelay(1);
774
		udelay(1);
774
	}
775
	}
775
	for (i = 0; i < rdev->usec_timeout; i++) {
776
	for (i = 0; i < rdev->usec_timeout; i++) {
776
		if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & TARGET_STATE_MASK) == 0)
777
		if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & TARGET_STATE_MASK) == 0)
777
			break;
778
			break;
778
		udelay(1);
779
		udelay(1);
779
	}
780
	}
780
	for (i = 0; i < rdev->usec_timeout; i++) {
781
	for (i = 0; i < rdev->usec_timeout; i++) {
781
		if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) == 0)
782
		if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) == 0)
782
			break;
783
			break;
783
		udelay(1);
784
		udelay(1);
784
	}
785
	}
785
}
786
}
786
 
787
 
787
static void trinity_stop_dpm(struct radeon_device *rdev)
788
static void trinity_stop_dpm(struct radeon_device *rdev)
788
{
789
{
789
	u32 sclk_dpm_cntl;
790
	u32 sclk_dpm_cntl;
790
 
791
 
791
	WREG32_P(CG_CG_VOLTAGE_CNTL, EN, ~EN);
792
	WREG32_P(CG_CG_VOLTAGE_CNTL, EN, ~EN);
792
 
793
 
793
	sclk_dpm_cntl = RREG32_SMC(SMU_SCLK_DPM_CNTL);
794
	sclk_dpm_cntl = RREG32_SMC(SMU_SCLK_DPM_CNTL);
794
	sclk_dpm_cntl &= ~(SCLK_DPM_EN_MASK | VOLTAGE_CHG_EN_MASK);
795
	sclk_dpm_cntl &= ~(SCLK_DPM_EN_MASK | VOLTAGE_CHG_EN_MASK);
795
	WREG32_SMC(SMU_SCLK_DPM_CNTL, sclk_dpm_cntl);
796
	WREG32_SMC(SMU_SCLK_DPM_CNTL, sclk_dpm_cntl);
796
 
797
 
797
	trinity_dpm_config(rdev, false);
798
	trinity_dpm_config(rdev, false);
798
}
799
}
799
 
800
 
800
static void trinity_start_am(struct radeon_device *rdev)
801
static void trinity_start_am(struct radeon_device *rdev)
801
{
802
{
802
	WREG32_P(SCLK_PWRMGT_CNTL, 0, ~(RESET_SCLK_CNT | RESET_BUSY_CNT));
803
	WREG32_P(SCLK_PWRMGT_CNTL, 0, ~(RESET_SCLK_CNT | RESET_BUSY_CNT));
803
}
804
}
804
 
805
 
805
static void trinity_reset_am(struct radeon_device *rdev)
806
static void trinity_reset_am(struct radeon_device *rdev)
806
{
807
{
807
	WREG32_P(SCLK_PWRMGT_CNTL, RESET_SCLK_CNT | RESET_BUSY_CNT,
808
	WREG32_P(SCLK_PWRMGT_CNTL, RESET_SCLK_CNT | RESET_BUSY_CNT,
808
		 ~(RESET_SCLK_CNT | RESET_BUSY_CNT));
809
		 ~(RESET_SCLK_CNT | RESET_BUSY_CNT));
809
}
810
}
810
 
811
 
811
static void trinity_wait_for_level_0(struct radeon_device *rdev)
812
static void trinity_wait_for_level_0(struct radeon_device *rdev)
812
{
813
{
813
	int i;
814
	int i;
814
 
815
 
815
	for (i = 0; i < rdev->usec_timeout; i++) {
816
	for (i = 0; i < rdev->usec_timeout; i++) {
816
		if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) == 0)
817
		if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) == 0)
817
			break;
818
			break;
818
		udelay(1);
819
		udelay(1);
819
	}
820
	}
820
}
821
}
821
 
822
 
822
static void trinity_enable_power_level_0(struct radeon_device *rdev)
823
static void trinity_enable_power_level_0(struct radeon_device *rdev)
823
{
824
{
824
	trinity_power_level_enable_disable(rdev, 0, true);
825
	trinity_power_level_enable_disable(rdev, 0, true);
825
}
826
}
826
 
827
 
827
static void trinity_force_level_0(struct radeon_device *rdev)
828
static void trinity_force_level_0(struct radeon_device *rdev)
828
{
829
{
829
	trinity_dpm_force_state(rdev, 0);
830
	trinity_dpm_force_state(rdev, 0);
830
}
831
}
831
 
832
 
832
static void trinity_unforce_levels(struct radeon_device *rdev)
833
static void trinity_unforce_levels(struct radeon_device *rdev)
833
{
834
{
834
	trinity_dpm_no_forced_level(rdev);
835
	trinity_dpm_no_forced_level(rdev);
835
}
836
}
836
 
837
 
837
static void trinity_program_power_levels_0_to_n(struct radeon_device *rdev,
838
static void trinity_program_power_levels_0_to_n(struct radeon_device *rdev,
838
						struct radeon_ps *new_rps,
839
						struct radeon_ps *new_rps,
839
						struct radeon_ps *old_rps)
840
						struct radeon_ps *old_rps)
840
{
841
{
841
	struct trinity_ps *new_ps = trinity_get_ps(new_rps);
842
	struct trinity_ps *new_ps = trinity_get_ps(new_rps);
842
	struct trinity_ps *old_ps = trinity_get_ps(old_rps);
843
	struct trinity_ps *old_ps = trinity_get_ps(old_rps);
843
	u32 i;
844
	u32 i;
844
	u32 n_current_state_levels = (old_ps == NULL) ? 1 : old_ps->num_levels;
845
	u32 n_current_state_levels = (old_ps == NULL) ? 1 : old_ps->num_levels;
845
 
846
 
846
	for (i = 0; i < new_ps->num_levels; i++) {
847
	for (i = 0; i < new_ps->num_levels; i++) {
847
		trinity_program_power_level(rdev, &new_ps->levels[i], i);
848
		trinity_program_power_level(rdev, &new_ps->levels[i], i);
848
		trinity_power_level_enable_disable(rdev, i, true);
849
		trinity_power_level_enable_disable(rdev, i, true);
849
	}
850
	}
850
 
851
 
851
	for (i = new_ps->num_levels; i < n_current_state_levels; i++)
852
	for (i = new_ps->num_levels; i < n_current_state_levels; i++)
852
		trinity_power_level_enable_disable(rdev, i, false);
853
		trinity_power_level_enable_disable(rdev, i, false);
853
}
854
}
854
 
855
 
855
static void trinity_program_bootup_state(struct radeon_device *rdev)
856
static void trinity_program_bootup_state(struct radeon_device *rdev)
856
{
857
{
857
	struct trinity_power_info *pi = trinity_get_pi(rdev);
858
	struct trinity_power_info *pi = trinity_get_pi(rdev);
858
	u32 i;
859
	u32 i;
859
 
860
 
860
	trinity_program_power_level(rdev, &pi->boot_pl, 0);
861
	trinity_program_power_level(rdev, &pi->boot_pl, 0);
861
	trinity_power_level_enable_disable(rdev, 0, true);
862
	trinity_power_level_enable_disable(rdev, 0, true);
862
 
863
 
863
	for (i = 1; i < 8; i++)
864
	for (i = 1; i < 8; i++)
864
		trinity_power_level_enable_disable(rdev, i, false);
865
		trinity_power_level_enable_disable(rdev, i, false);
865
}
866
}
866
 
867
 
867
static void trinity_setup_uvd_clock_table(struct radeon_device *rdev,
868
static void trinity_setup_uvd_clock_table(struct radeon_device *rdev,
868
					  struct radeon_ps *rps)
869
					  struct radeon_ps *rps)
869
{
870
{
870
	struct trinity_ps *ps = trinity_get_ps(rps);
871
	struct trinity_ps *ps = trinity_get_ps(rps);
871
	u32 uvdstates = (ps->vclk_low_divider |
872
	u32 uvdstates = (ps->vclk_low_divider |
872
			 ps->vclk_high_divider << 8 |
873
			 ps->vclk_high_divider << 8 |
873
			 ps->dclk_low_divider << 16 |
874
			 ps->dclk_low_divider << 16 |
874
			 ps->dclk_high_divider << 24);
875
			 ps->dclk_high_divider << 24);
875
 
876
 
876
	WREG32_SMC(SMU_UVD_DPM_STATES, uvdstates);
877
	WREG32_SMC(SMU_UVD_DPM_STATES, uvdstates);
877
}
878
}
878
 
879
 
879
static void trinity_setup_uvd_dpm_interval(struct radeon_device *rdev,
880
static void trinity_setup_uvd_dpm_interval(struct radeon_device *rdev,
880
					   u32 interval)
881
					   u32 interval)
881
{
882
{
882
	u32 p, u;
883
	u32 p, u;
883
	u32 tp = RREG32_SMC(PM_TP);
884
	u32 tp = RREG32_SMC(PM_TP);
884
	u32 val;
885
	u32 val;
885
	u32 xclk = radeon_get_xclk(rdev);
886
	u32 xclk = radeon_get_xclk(rdev);
886
 
887
 
887
	r600_calculate_u_and_p(interval, xclk, 16, &p, &u);
888
	r600_calculate_u_and_p(interval, xclk, 16, &p, &u);
888
 
889
 
889
	val = (p + tp - 1) / tp;
890
	val = (p + tp - 1) / tp;
890
 
891
 
891
	WREG32_SMC(SMU_UVD_DPM_CNTL, val);
892
	WREG32_SMC(SMU_UVD_DPM_CNTL, val);
892
}
893
}
893
 
894
 
894
static bool trinity_uvd_clocks_zero(struct radeon_ps *rps)
895
static bool trinity_uvd_clocks_zero(struct radeon_ps *rps)
895
{
896
{
896
	if ((rps->vclk == 0) && (rps->dclk == 0))
897
	if ((rps->vclk == 0) && (rps->dclk == 0))
897
		return true;
898
		return true;
898
	else
899
	else
899
		return false;
900
		return false;
900
}
901
}
901
 
902
 
902
static bool trinity_uvd_clocks_equal(struct radeon_ps *rps1,
903
static bool trinity_uvd_clocks_equal(struct radeon_ps *rps1,
903
				     struct radeon_ps *rps2)
904
				     struct radeon_ps *rps2)
904
{
905
{
905
	struct trinity_ps *ps1 = trinity_get_ps(rps1);
906
	struct trinity_ps *ps1 = trinity_get_ps(rps1);
906
	struct trinity_ps *ps2 = trinity_get_ps(rps2);
907
	struct trinity_ps *ps2 = trinity_get_ps(rps2);
907
 
908
 
908
	if ((rps1->vclk == rps2->vclk) &&
909
	if ((rps1->vclk == rps2->vclk) &&
909
	    (rps1->dclk == rps2->dclk) &&
910
	    (rps1->dclk == rps2->dclk) &&
910
	    (ps1->vclk_low_divider == ps2->vclk_low_divider) &&
911
	    (ps1->vclk_low_divider == ps2->vclk_low_divider) &&
911
	    (ps1->vclk_high_divider == ps2->vclk_high_divider) &&
912
	    (ps1->vclk_high_divider == ps2->vclk_high_divider) &&
912
	    (ps1->dclk_low_divider == ps2->dclk_low_divider) &&
913
	    (ps1->dclk_low_divider == ps2->dclk_low_divider) &&
913
	    (ps1->dclk_high_divider == ps2->dclk_high_divider))
914
	    (ps1->dclk_high_divider == ps2->dclk_high_divider))
914
		return true;
915
		return true;
915
	else
916
	else
916
		return false;
917
		return false;
917
}
918
}
918
 
919
 
919
static void trinity_setup_uvd_clocks(struct radeon_device *rdev,
920
static void trinity_setup_uvd_clocks(struct radeon_device *rdev,
920
				     struct radeon_ps *new_rps,
921
				     struct radeon_ps *new_rps,
921
				     struct radeon_ps *old_rps)
922
				     struct radeon_ps *old_rps)
922
{
923
{
923
	struct trinity_power_info *pi = trinity_get_pi(rdev);
924
	struct trinity_power_info *pi = trinity_get_pi(rdev);
924
 
925
 
925
	if (pi->enable_gfx_power_gating) {
926
	if (pi->enable_gfx_power_gating) {
926
		trinity_gfx_powergating_enable(rdev, false);
927
		trinity_gfx_powergating_enable(rdev, false);
927
	}
928
	}
928
 
929
 
929
	if (pi->uvd_dpm) {
930
	if (pi->uvd_dpm) {
930
		if (trinity_uvd_clocks_zero(new_rps) &&
931
		if (trinity_uvd_clocks_zero(new_rps) &&
931
		    !trinity_uvd_clocks_zero(old_rps)) {
932
		    !trinity_uvd_clocks_zero(old_rps)) {
932
			trinity_setup_uvd_dpm_interval(rdev, 0);
933
			trinity_setup_uvd_dpm_interval(rdev, 0);
933
		} else if (!trinity_uvd_clocks_zero(new_rps)) {
934
		} else if (!trinity_uvd_clocks_zero(new_rps)) {
934
			trinity_setup_uvd_clock_table(rdev, new_rps);
935
			trinity_setup_uvd_clock_table(rdev, new_rps);
935
 
936
 
936
			if (trinity_uvd_clocks_zero(old_rps)) {
937
			if (trinity_uvd_clocks_zero(old_rps)) {
937
				u32 tmp = RREG32(CG_MISC_REG);
938
				u32 tmp = RREG32(CG_MISC_REG);
938
				tmp &= 0xfffffffd;
939
				tmp &= 0xfffffffd;
939
				WREG32(CG_MISC_REG, tmp);
940
				WREG32(CG_MISC_REG, tmp);
940
 
941
 
941
				radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
942
				radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
942
 
943
 
943
				trinity_setup_uvd_dpm_interval(rdev, 3000);
944
				trinity_setup_uvd_dpm_interval(rdev, 3000);
944
			}
945
			}
945
		}
946
		}
946
		trinity_uvd_dpm_config(rdev);
947
		trinity_uvd_dpm_config(rdev);
947
	} else {
948
	} else {
948
		if (trinity_uvd_clocks_zero(new_rps) ||
949
		if (trinity_uvd_clocks_zero(new_rps) ||
949
		    trinity_uvd_clocks_equal(new_rps, old_rps))
950
		    trinity_uvd_clocks_equal(new_rps, old_rps))
950
			return;
951
			return;
951
 
952
 
952
		radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
953
		radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
953
	}
954
	}
954
 
955
 
955
	if (pi->enable_gfx_power_gating) {
956
	if (pi->enable_gfx_power_gating) {
956
		trinity_gfx_powergating_enable(rdev, true);
957
		trinity_gfx_powergating_enable(rdev, true);
957
	}
958
	}
958
}
959
}
959
 
960
 
960
static void trinity_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
961
static void trinity_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
961
						       struct radeon_ps *new_rps,
962
						       struct radeon_ps *new_rps,
962
						       struct radeon_ps *old_rps)
963
						       struct radeon_ps *old_rps)
963
{
964
{
964
	struct trinity_ps *new_ps = trinity_get_ps(new_rps);
965
	struct trinity_ps *new_ps = trinity_get_ps(new_rps);
965
	struct trinity_ps *current_ps = trinity_get_ps(new_rps);
966
	struct trinity_ps *current_ps = trinity_get_ps(new_rps);
966
 
967
 
967
	if (new_ps->levels[new_ps->num_levels - 1].sclk >=
968
	if (new_ps->levels[new_ps->num_levels - 1].sclk >=
968
	    current_ps->levels[current_ps->num_levels - 1].sclk)
969
	    current_ps->levels[current_ps->num_levels - 1].sclk)
969
		return;
970
		return;
970
 
971
 
971
	trinity_setup_uvd_clocks(rdev, new_rps, old_rps);
972
	trinity_setup_uvd_clocks(rdev, new_rps, old_rps);
972
}
973
}
973
 
974
 
974
static void trinity_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
975
static void trinity_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
975
						      struct radeon_ps *new_rps,
976
						      struct radeon_ps *new_rps,
976
						      struct radeon_ps *old_rps)
977
						      struct radeon_ps *old_rps)
977
{
978
{
978
	struct trinity_ps *new_ps = trinity_get_ps(new_rps);
979
	struct trinity_ps *new_ps = trinity_get_ps(new_rps);
979
	struct trinity_ps *current_ps = trinity_get_ps(old_rps);
980
	struct trinity_ps *current_ps = trinity_get_ps(old_rps);
980
 
981
 
981
	if (new_ps->levels[new_ps->num_levels - 1].sclk <
982
	if (new_ps->levels[new_ps->num_levels - 1].sclk <
982
	    current_ps->levels[current_ps->num_levels - 1].sclk)
983
	    current_ps->levels[current_ps->num_levels - 1].sclk)
983
		return;
984
		return;
984
 
985
 
985
	trinity_setup_uvd_clocks(rdev, new_rps, old_rps);
986
	trinity_setup_uvd_clocks(rdev, new_rps, old_rps);
986
}
987
}
-
 
988
 
-
 
989
static void trinity_set_vce_clock(struct radeon_device *rdev,
-
 
990
				  struct radeon_ps *new_rps,
-
 
991
				  struct radeon_ps *old_rps)
-
 
992
{
-
 
993
	if ((old_rps->evclk != new_rps->evclk) ||
-
 
994
	    (old_rps->ecclk != new_rps->ecclk)) {
-
 
995
		/* turn the clocks on when encoding, off otherwise */
-
 
996
		if (new_rps->evclk || new_rps->ecclk)
-
 
997
			vce_v1_0_enable_mgcg(rdev, false);
-
 
998
		else
-
 
999
			vce_v1_0_enable_mgcg(rdev, true);
-
 
1000
		radeon_set_vce_clocks(rdev, new_rps->evclk, new_rps->ecclk);
-
 
1001
	}
-
 
1002
}
987
 
1003
 
988
static void trinity_program_ttt(struct radeon_device *rdev)
1004
static void trinity_program_ttt(struct radeon_device *rdev)
989
{
1005
{
990
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1006
	struct trinity_power_info *pi = trinity_get_pi(rdev);
991
	u32 value = RREG32_SMC(SMU_SCLK_DPM_TTT);
1007
	u32 value = RREG32_SMC(SMU_SCLK_DPM_TTT);
992
 
1008
 
993
	value &= ~(HT_MASK | LT_MASK);
1009
	value &= ~(HT_MASK | LT_MASK);
994
	value |= HT((pi->thermal_auto_throttling + 49) * 8);
1010
	value |= HT((pi->thermal_auto_throttling + 49) * 8);
995
	value |= LT((pi->thermal_auto_throttling + 49 - pi->sys_info.htc_hyst_lmt) * 8);
1011
	value |= LT((pi->thermal_auto_throttling + 49 - pi->sys_info.htc_hyst_lmt) * 8);
996
	WREG32_SMC(SMU_SCLK_DPM_TTT, value);
1012
	WREG32_SMC(SMU_SCLK_DPM_TTT, value);
997
}
1013
}
998
 
1014
 
999
static void trinity_enable_att(struct radeon_device *rdev)
1015
static void trinity_enable_att(struct radeon_device *rdev)
1000
{
1016
{
1001
	u32 value = RREG32_SMC(SMU_SCLK_DPM_TT_CNTL);
1017
	u32 value = RREG32_SMC(SMU_SCLK_DPM_TT_CNTL);
1002
 
1018
 
1003
	value &= ~SCLK_TT_EN_MASK;
1019
	value &= ~SCLK_TT_EN_MASK;
1004
	value |= SCLK_TT_EN(1);
1020
	value |= SCLK_TT_EN(1);
1005
	WREG32_SMC(SMU_SCLK_DPM_TT_CNTL, value);
1021
	WREG32_SMC(SMU_SCLK_DPM_TT_CNTL, value);
1006
}
1022
}
1007
 
1023
 
1008
static void trinity_program_sclk_dpm(struct radeon_device *rdev)
1024
static void trinity_program_sclk_dpm(struct radeon_device *rdev)
1009
{
1025
{
1010
	u32 p, u;
1026
	u32 p, u;
1011
	u32 tp = RREG32_SMC(PM_TP);
1027
	u32 tp = RREG32_SMC(PM_TP);
1012
	u32 ni;
1028
	u32 ni;
1013
	u32 xclk = radeon_get_xclk(rdev);
1029
	u32 xclk = radeon_get_xclk(rdev);
1014
	u32 value;
1030
	u32 value;
1015
 
1031
 
1016
	r600_calculate_u_and_p(400, xclk, 16, &p, &u);
1032
	r600_calculate_u_and_p(400, xclk, 16, &p, &u);
1017
 
1033
 
1018
	ni = (p + tp - 1) / tp;
1034
	ni = (p + tp - 1) / tp;
1019
 
1035
 
1020
	value = RREG32_SMC(PM_I_CNTL_1);
1036
	value = RREG32_SMC(PM_I_CNTL_1);
1021
	value &= ~SCLK_DPM_MASK;
1037
	value &= ~SCLK_DPM_MASK;
1022
	value |= SCLK_DPM(ni);
1038
	value |= SCLK_DPM(ni);
1023
	WREG32_SMC(PM_I_CNTL_1, value);
1039
	WREG32_SMC(PM_I_CNTL_1, value);
1024
}
1040
}
1025
 
1041
 
1026
static int trinity_set_thermal_temperature_range(struct radeon_device *rdev,
1042
static int trinity_set_thermal_temperature_range(struct radeon_device *rdev,
1027
						 int min_temp, int max_temp)
1043
						 int min_temp, int max_temp)
1028
{
1044
{
1029
	int low_temp = 0 * 1000;
1045
	int low_temp = 0 * 1000;
1030
	int high_temp = 255 * 1000;
1046
	int high_temp = 255 * 1000;
1031
 
1047
 
1032
        if (low_temp < min_temp)
1048
        if (low_temp < min_temp)
1033
		low_temp = min_temp;
1049
		low_temp = min_temp;
1034
        if (high_temp > max_temp)
1050
        if (high_temp > max_temp)
1035
		high_temp = max_temp;
1051
		high_temp = max_temp;
1036
        if (high_temp < low_temp) {
1052
        if (high_temp < low_temp) {
1037
		DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);
1053
		DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);
1038
                return -EINVAL;
1054
                return -EINVAL;
1039
        }
1055
        }
1040
 
1056
 
1041
	WREG32_P(CG_THERMAL_INT_CTRL, DIG_THERM_INTH(49 + (high_temp / 1000)), ~DIG_THERM_INTH_MASK);
1057
	WREG32_P(CG_THERMAL_INT_CTRL, DIG_THERM_INTH(49 + (high_temp / 1000)), ~DIG_THERM_INTH_MASK);
1042
	WREG32_P(CG_THERMAL_INT_CTRL, DIG_THERM_INTL(49 + (low_temp / 1000)), ~DIG_THERM_INTL_MASK);
1058
	WREG32_P(CG_THERMAL_INT_CTRL, DIG_THERM_INTL(49 + (low_temp / 1000)), ~DIG_THERM_INTL_MASK);
1043
 
1059
 
1044
	rdev->pm.dpm.thermal.min_temp = low_temp;
1060
	rdev->pm.dpm.thermal.min_temp = low_temp;
1045
	rdev->pm.dpm.thermal.max_temp = high_temp;
1061
	rdev->pm.dpm.thermal.max_temp = high_temp;
1046
 
1062
 
1047
	return 0;
1063
	return 0;
1048
}
1064
}
1049
 
1065
 
1050
static void trinity_update_current_ps(struct radeon_device *rdev,
1066
static void trinity_update_current_ps(struct radeon_device *rdev,
1051
				      struct radeon_ps *rps)
1067
				      struct radeon_ps *rps)
1052
{
1068
{
1053
	struct trinity_ps *new_ps = trinity_get_ps(rps);
1069
	struct trinity_ps *new_ps = trinity_get_ps(rps);
1054
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1070
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1055
 
1071
 
1056
	pi->current_rps = *rps;
1072
	pi->current_rps = *rps;
1057
	pi->current_ps = *new_ps;
1073
	pi->current_ps = *new_ps;
1058
	pi->current_rps.ps_priv = &pi->current_ps;
1074
	pi->current_rps.ps_priv = &pi->current_ps;
1059
}
1075
}
1060
 
1076
 
1061
static void trinity_update_requested_ps(struct radeon_device *rdev,
1077
static void trinity_update_requested_ps(struct radeon_device *rdev,
1062
					struct radeon_ps *rps)
1078
					struct radeon_ps *rps)
1063
{
1079
{
1064
	struct trinity_ps *new_ps = trinity_get_ps(rps);
1080
	struct trinity_ps *new_ps = trinity_get_ps(rps);
1065
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1081
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1066
 
1082
 
1067
	pi->requested_rps = *rps;
1083
	pi->requested_rps = *rps;
1068
	pi->requested_ps = *new_ps;
1084
	pi->requested_ps = *new_ps;
1069
	pi->requested_rps.ps_priv = &pi->requested_ps;
1085
	pi->requested_rps.ps_priv = &pi->requested_ps;
1070
}
1086
}
1071
 
1087
 
1072
void trinity_dpm_enable_bapm(struct radeon_device *rdev, bool enable)
1088
void trinity_dpm_enable_bapm(struct radeon_device *rdev, bool enable)
1073
{
1089
{
1074
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1090
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1075
 
1091
 
1076
	if (pi->enable_bapm) {
1092
	if (pi->enable_bapm) {
1077
		trinity_acquire_mutex(rdev);
1093
		trinity_acquire_mutex(rdev);
1078
		trinity_dpm_bapm_enable(rdev, enable);
1094
		trinity_dpm_bapm_enable(rdev, enable);
1079
		trinity_release_mutex(rdev);
1095
		trinity_release_mutex(rdev);
1080
	}
1096
	}
1081
}
1097
}
1082
 
1098
 
1083
int trinity_dpm_enable(struct radeon_device *rdev)
1099
int trinity_dpm_enable(struct radeon_device *rdev)
1084
{
1100
{
1085
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1101
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1086
 
1102
 
1087
	trinity_acquire_mutex(rdev);
1103
	trinity_acquire_mutex(rdev);
1088
 
1104
 
1089
	if (trinity_dpm_enabled(rdev)) {
1105
	if (trinity_dpm_enabled(rdev)) {
1090
		trinity_release_mutex(rdev);
1106
		trinity_release_mutex(rdev);
1091
		return -EINVAL;
1107
		return -EINVAL;
1092
	}
1108
	}
1093
 
1109
 
1094
	trinity_program_bootup_state(rdev);
1110
	trinity_program_bootup_state(rdev);
1095
	sumo_program_vc(rdev, 0x00C00033);
1111
	sumo_program_vc(rdev, 0x00C00033);
1096
	trinity_start_am(rdev);
1112
	trinity_start_am(rdev);
1097
	if (pi->enable_auto_thermal_throttling) {
1113
	if (pi->enable_auto_thermal_throttling) {
1098
		trinity_program_ttt(rdev);
1114
		trinity_program_ttt(rdev);
1099
		trinity_enable_att(rdev);
1115
		trinity_enable_att(rdev);
1100
	}
1116
	}
1101
	trinity_program_sclk_dpm(rdev);
1117
	trinity_program_sclk_dpm(rdev);
1102
	trinity_start_dpm(rdev);
1118
	trinity_start_dpm(rdev);
1103
	trinity_wait_for_dpm_enabled(rdev);
1119
	trinity_wait_for_dpm_enabled(rdev);
1104
	trinity_dpm_bapm_enable(rdev, false);
1120
	trinity_dpm_bapm_enable(rdev, false);
1105
	trinity_release_mutex(rdev);
1121
	trinity_release_mutex(rdev);
1106
 
1122
 
1107
	trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
1123
	trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
1108
 
1124
 
1109
	return 0;
1125
	return 0;
1110
}
1126
}
1111
 
1127
 
1112
int trinity_dpm_late_enable(struct radeon_device *rdev)
1128
int trinity_dpm_late_enable(struct radeon_device *rdev)
1113
{
1129
{
1114
	int ret;
1130
	int ret;
1115
 
1131
 
1116
	trinity_acquire_mutex(rdev);
1132
	trinity_acquire_mutex(rdev);
1117
	trinity_enable_clock_power_gating(rdev);
1133
	trinity_enable_clock_power_gating(rdev);
1118
 
1134
 
1119
	if (rdev->irq.installed &&
1135
	if (rdev->irq.installed &&
1120
	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
1136
	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
1121
		ret = trinity_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
1137
		ret = trinity_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
1122
		if (ret) {
1138
		if (ret) {
1123
			trinity_release_mutex(rdev);
1139
			trinity_release_mutex(rdev);
1124
			return ret;
1140
			return ret;
1125
		}
1141
		}
1126
		rdev->irq.dpm_thermal = true;
1142
		rdev->irq.dpm_thermal = true;
1127
		radeon_irq_set(rdev);
1143
		radeon_irq_set(rdev);
1128
	}
1144
	}
1129
	trinity_release_mutex(rdev);
1145
	trinity_release_mutex(rdev);
1130
 
1146
 
1131
	return 0;
1147
	return 0;
1132
}
1148
}
1133
 
1149
 
1134
void trinity_dpm_disable(struct radeon_device *rdev)
1150
void trinity_dpm_disable(struct radeon_device *rdev)
1135
{
1151
{
1136
	trinity_acquire_mutex(rdev);
1152
	trinity_acquire_mutex(rdev);
1137
	if (!trinity_dpm_enabled(rdev)) {
1153
	if (!trinity_dpm_enabled(rdev)) {
1138
		trinity_release_mutex(rdev);
1154
		trinity_release_mutex(rdev);
1139
		return;
1155
		return;
1140
	}
1156
	}
1141
	trinity_dpm_bapm_enable(rdev, false);
1157
	trinity_dpm_bapm_enable(rdev, false);
1142
	trinity_disable_clock_power_gating(rdev);
1158
	trinity_disable_clock_power_gating(rdev);
1143
	sumo_clear_vc(rdev);
1159
	sumo_clear_vc(rdev);
1144
	trinity_wait_for_level_0(rdev);
1160
	trinity_wait_for_level_0(rdev);
1145
	trinity_stop_dpm(rdev);
1161
	trinity_stop_dpm(rdev);
1146
	trinity_reset_am(rdev);
1162
	trinity_reset_am(rdev);
1147
	trinity_release_mutex(rdev);
1163
	trinity_release_mutex(rdev);
1148
 
1164
 
1149
	if (rdev->irq.installed &&
1165
	if (rdev->irq.installed &&
1150
	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
1166
	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
1151
		rdev->irq.dpm_thermal = false;
1167
		rdev->irq.dpm_thermal = false;
1152
		radeon_irq_set(rdev);
1168
		radeon_irq_set(rdev);
1153
	}
1169
	}
1154
 
1170
 
1155
	trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
1171
	trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
1156
}
1172
}
1157
 
1173
 
1158
static void trinity_get_min_sclk_divider(struct radeon_device *rdev)
1174
static void trinity_get_min_sclk_divider(struct radeon_device *rdev)
1159
{
1175
{
1160
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1176
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1161
 
1177
 
1162
	pi->min_sclk_did =
1178
	pi->min_sclk_did =
1163
		(RREG32_SMC(CC_SMU_MISC_FUSES) & MinSClkDid_MASK) >> MinSClkDid_SHIFT;
1179
		(RREG32_SMC(CC_SMU_MISC_FUSES) & MinSClkDid_MASK) >> MinSClkDid_SHIFT;
1164
}
1180
}
1165
 
1181
 
1166
static void trinity_setup_nbp_sim(struct radeon_device *rdev,
1182
static void trinity_setup_nbp_sim(struct radeon_device *rdev,
1167
				  struct radeon_ps *rps)
1183
				  struct radeon_ps *rps)
1168
{
1184
{
1169
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1185
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1170
	struct trinity_ps *new_ps = trinity_get_ps(rps);
1186
	struct trinity_ps *new_ps = trinity_get_ps(rps);
1171
	u32 nbpsconfig;
1187
	u32 nbpsconfig;
1172
 
1188
 
1173
	if (pi->sys_info.nb_dpm_enable) {
1189
	if (pi->sys_info.nb_dpm_enable) {
1174
		nbpsconfig = RREG32_SMC(NB_PSTATE_CONFIG);
1190
		nbpsconfig = RREG32_SMC(NB_PSTATE_CONFIG);
1175
		nbpsconfig &= ~(Dpm0PgNbPsLo_MASK | Dpm0PgNbPsHi_MASK | DpmXNbPsLo_MASK | DpmXNbPsHi_MASK);
1191
		nbpsconfig &= ~(Dpm0PgNbPsLo_MASK | Dpm0PgNbPsHi_MASK | DpmXNbPsLo_MASK | DpmXNbPsHi_MASK);
1176
		nbpsconfig |= (Dpm0PgNbPsLo(new_ps->Dpm0PgNbPsLo) |
1192
		nbpsconfig |= (Dpm0PgNbPsLo(new_ps->Dpm0PgNbPsLo) |
1177
			       Dpm0PgNbPsHi(new_ps->Dpm0PgNbPsHi) |
1193
			       Dpm0PgNbPsHi(new_ps->Dpm0PgNbPsHi) |
1178
			       DpmXNbPsLo(new_ps->DpmXNbPsLo) |
1194
			       DpmXNbPsLo(new_ps->DpmXNbPsLo) |
1179
			       DpmXNbPsHi(new_ps->DpmXNbPsHi));
1195
			       DpmXNbPsHi(new_ps->DpmXNbPsHi));
1180
		WREG32_SMC(NB_PSTATE_CONFIG, nbpsconfig);
1196
		WREG32_SMC(NB_PSTATE_CONFIG, nbpsconfig);
1181
	}
1197
	}
1182
}
1198
}
1183
 
1199
 
1184
int trinity_dpm_force_performance_level(struct radeon_device *rdev,
1200
int trinity_dpm_force_performance_level(struct radeon_device *rdev,
1185
					enum radeon_dpm_forced_level level)
1201
					enum radeon_dpm_forced_level level)
1186
{
1202
{
1187
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1203
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1188
	struct radeon_ps *rps = &pi->current_rps;
1204
	struct radeon_ps *rps = &pi->current_rps;
1189
	struct trinity_ps *ps = trinity_get_ps(rps);
1205
	struct trinity_ps *ps = trinity_get_ps(rps);
1190
	int i, ret;
1206
	int i, ret;
1191
 
1207
 
1192
	if (ps->num_levels <= 1)
1208
	if (ps->num_levels <= 1)
1193
		return 0;
1209
		return 0;
1194
 
1210
 
1195
	if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
1211
	if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
1196
		/* not supported by the hw */
1212
		/* not supported by the hw */
1197
		return -EINVAL;
1213
		return -EINVAL;
1198
	} else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
1214
	} else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
1199
		ret = trinity_dpm_n_levels_disabled(rdev, ps->num_levels - 1);
1215
		ret = trinity_dpm_n_levels_disabled(rdev, ps->num_levels - 1);
1200
		if (ret)
1216
		if (ret)
1201
			return ret;
1217
			return ret;
1202
	} else {
1218
	} else {
1203
		for (i = 0; i < ps->num_levels; i++) {
1219
		for (i = 0; i < ps->num_levels; i++) {
1204
			ret = trinity_dpm_n_levels_disabled(rdev, 0);
1220
			ret = trinity_dpm_n_levels_disabled(rdev, 0);
1205
			if (ret)
1221
			if (ret)
1206
				return ret;
1222
				return ret;
1207
		}
1223
		}
1208
	}
1224
	}
1209
 
1225
 
1210
	rdev->pm.dpm.forced_level = level;
1226
	rdev->pm.dpm.forced_level = level;
1211
 
1227
 
1212
	return 0;
1228
	return 0;
1213
}
1229
}
1214
 
1230
 
1215
int trinity_dpm_pre_set_power_state(struct radeon_device *rdev)
1231
int trinity_dpm_pre_set_power_state(struct radeon_device *rdev)
1216
{
1232
{
1217
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1233
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1218
	struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
1234
	struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
1219
	struct radeon_ps *new_ps = &requested_ps;
1235
	struct radeon_ps *new_ps = &requested_ps;
1220
 
1236
 
1221
	trinity_update_requested_ps(rdev, new_ps);
1237
	trinity_update_requested_ps(rdev, new_ps);
1222
 
1238
 
1223
	trinity_apply_state_adjust_rules(rdev,
1239
	trinity_apply_state_adjust_rules(rdev,
1224
					 &pi->requested_rps,
1240
					 &pi->requested_rps,
1225
					 &pi->current_rps);
1241
					 &pi->current_rps);
1226
 
1242
 
1227
	return 0;
1243
	return 0;
1228
}
1244
}
1229
 
1245
 
1230
int trinity_dpm_set_power_state(struct radeon_device *rdev)
1246
int trinity_dpm_set_power_state(struct radeon_device *rdev)
1231
{
1247
{
1232
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1248
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1233
	struct radeon_ps *new_ps = &pi->requested_rps;
1249
	struct radeon_ps *new_ps = &pi->requested_rps;
1234
	struct radeon_ps *old_ps = &pi->current_rps;
1250
	struct radeon_ps *old_ps = &pi->current_rps;
1235
 
1251
 
1236
	trinity_acquire_mutex(rdev);
1252
	trinity_acquire_mutex(rdev);
1237
	if (pi->enable_dpm) {
1253
	if (pi->enable_dpm) {
1238
		if (pi->enable_bapm)
1254
		if (pi->enable_bapm)
1239
			trinity_dpm_bapm_enable(rdev, rdev->pm.dpm.ac_power);
1255
			trinity_dpm_bapm_enable(rdev, rdev->pm.dpm.ac_power);
1240
		trinity_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
1256
		trinity_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
1241
		trinity_enable_power_level_0(rdev);
1257
		trinity_enable_power_level_0(rdev);
1242
		trinity_force_level_0(rdev);
1258
		trinity_force_level_0(rdev);
1243
		trinity_wait_for_level_0(rdev);
1259
		trinity_wait_for_level_0(rdev);
1244
		trinity_setup_nbp_sim(rdev, new_ps);
1260
		trinity_setup_nbp_sim(rdev, new_ps);
1245
		trinity_program_power_levels_0_to_n(rdev, new_ps, old_ps);
1261
		trinity_program_power_levels_0_to_n(rdev, new_ps, old_ps);
1246
		trinity_force_level_0(rdev);
1262
		trinity_force_level_0(rdev);
1247
		trinity_unforce_levels(rdev);
1263
		trinity_unforce_levels(rdev);
1248
		trinity_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
1264
		trinity_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
-
 
1265
		trinity_set_vce_clock(rdev, new_ps, old_ps);
1249
	}
1266
	}
1250
	trinity_release_mutex(rdev);
1267
	trinity_release_mutex(rdev);
1251
 
1268
 
1252
	return 0;
1269
	return 0;
1253
}
1270
}
1254
 
1271
 
1255
void trinity_dpm_post_set_power_state(struct radeon_device *rdev)
1272
void trinity_dpm_post_set_power_state(struct radeon_device *rdev)
1256
{
1273
{
1257
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1274
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1258
	struct radeon_ps *new_ps = &pi->requested_rps;
1275
	struct radeon_ps *new_ps = &pi->requested_rps;
1259
 
1276
 
1260
	trinity_update_current_ps(rdev, new_ps);
1277
	trinity_update_current_ps(rdev, new_ps);
1261
}
1278
}
1262
 
1279
 
1263
void trinity_dpm_setup_asic(struct radeon_device *rdev)
1280
void trinity_dpm_setup_asic(struct radeon_device *rdev)
1264
{
1281
{
1265
	trinity_acquire_mutex(rdev);
1282
	trinity_acquire_mutex(rdev);
1266
	sumo_program_sstp(rdev);
1283
	sumo_program_sstp(rdev);
1267
	sumo_take_smu_control(rdev, true);
1284
	sumo_take_smu_control(rdev, true);
1268
	trinity_get_min_sclk_divider(rdev);
1285
	trinity_get_min_sclk_divider(rdev);
1269
	trinity_release_mutex(rdev);
1286
	trinity_release_mutex(rdev);
1270
}
1287
}
-
 
1288
 
1271
 
1289
#if 0
1272
void trinity_dpm_reset_asic(struct radeon_device *rdev)
1290
void trinity_dpm_reset_asic(struct radeon_device *rdev)
1273
{
1291
{
1274
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1292
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1275
 
1293
 
1276
	trinity_acquire_mutex(rdev);
1294
	trinity_acquire_mutex(rdev);
1277
	if (pi->enable_dpm) {
1295
	if (pi->enable_dpm) {
1278
		trinity_enable_power_level_0(rdev);
1296
		trinity_enable_power_level_0(rdev);
1279
		trinity_force_level_0(rdev);
1297
		trinity_force_level_0(rdev);
1280
		trinity_wait_for_level_0(rdev);
1298
		trinity_wait_for_level_0(rdev);
1281
		trinity_program_bootup_state(rdev);
1299
		trinity_program_bootup_state(rdev);
1282
		trinity_force_level_0(rdev);
1300
		trinity_force_level_0(rdev);
1283
		trinity_unforce_levels(rdev);
1301
		trinity_unforce_levels(rdev);
1284
	}
1302
	}
1285
	trinity_release_mutex(rdev);
1303
	trinity_release_mutex(rdev);
1286
}
1304
}
-
 
1305
#endif
1287
 
1306
 
1288
static u16 trinity_convert_voltage_index_to_value(struct radeon_device *rdev,
1307
static u16 trinity_convert_voltage_index_to_value(struct radeon_device *rdev,
1289
						  u32 vid_2bit)
1308
						  u32 vid_2bit)
1290
{
1309
{
1291
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1310
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1292
	u32 vid_7bit = sumo_convert_vid2_to_vid7(rdev, &pi->sys_info.vid_mapping_table, vid_2bit);
1311
	u32 vid_7bit = sumo_convert_vid2_to_vid7(rdev, &pi->sys_info.vid_mapping_table, vid_2bit);
1293
	u32 svi_mode = (RREG32_SMC(PM_CONFIG) & SVI_Mode) ? 1 : 0;
1312
	u32 svi_mode = (RREG32_SMC(PM_CONFIG) & SVI_Mode) ? 1 : 0;
1294
	u32 step = (svi_mode == 0) ? 1250 : 625;
1313
	u32 step = (svi_mode == 0) ? 1250 : 625;
1295
	u32 delta = vid_7bit * step + 50;
1314
	u32 delta = vid_7bit * step + 50;
1296
 
1315
 
1297
	if (delta > 155000)
1316
	if (delta > 155000)
1298
		return 0;
1317
		return 0;
1299
 
1318
 
1300
	return (155000 - delta) / 100;
1319
	return (155000 - delta) / 100;
1301
}
1320
}
1302
 
1321
 
1303
static void trinity_patch_boot_state(struct radeon_device *rdev,
1322
static void trinity_patch_boot_state(struct radeon_device *rdev,
1304
				     struct trinity_ps *ps)
1323
				     struct trinity_ps *ps)
1305
{
1324
{
1306
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1325
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1307
 
1326
 
1308
	ps->num_levels = 1;
1327
	ps->num_levels = 1;
1309
	ps->nbps_flags = 0;
1328
	ps->nbps_flags = 0;
1310
	ps->bapm_flags = 0;
1329
	ps->bapm_flags = 0;
1311
	ps->levels[0] = pi->boot_pl;
1330
	ps->levels[0] = pi->boot_pl;
1312
}
1331
}
1313
 
1332
 
1314
static u8 trinity_calculate_vce_wm(struct radeon_device *rdev, u32 sclk)
1333
static u8 trinity_calculate_vce_wm(struct radeon_device *rdev, u32 sclk)
1315
{
1334
{
1316
	if (sclk < 20000)
1335
	if (sclk < 20000)
1317
		return 1;
1336
		return 1;
1318
	return 0;
1337
	return 0;
1319
}
1338
}
1320
 
1339
 
1321
static void trinity_construct_boot_state(struct radeon_device *rdev)
1340
static void trinity_construct_boot_state(struct radeon_device *rdev)
1322
{
1341
{
1323
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1342
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1324
 
1343
 
1325
	pi->boot_pl.sclk = pi->sys_info.bootup_sclk;
1344
	pi->boot_pl.sclk = pi->sys_info.bootup_sclk;
1326
	pi->boot_pl.vddc_index = pi->sys_info.bootup_nb_voltage_index;
1345
	pi->boot_pl.vddc_index = pi->sys_info.bootup_nb_voltage_index;
1327
	pi->boot_pl.ds_divider_index = 0;
1346
	pi->boot_pl.ds_divider_index = 0;
1328
	pi->boot_pl.ss_divider_index = 0;
1347
	pi->boot_pl.ss_divider_index = 0;
1329
	pi->boot_pl.allow_gnb_slow = 1;
1348
	pi->boot_pl.allow_gnb_slow = 1;
1330
	pi->boot_pl.force_nbp_state = 0;
1349
	pi->boot_pl.force_nbp_state = 0;
1331
	pi->boot_pl.display_wm = 0;
1350
	pi->boot_pl.display_wm = 0;
1332
	pi->boot_pl.vce_wm = 0;
1351
	pi->boot_pl.vce_wm = 0;
1333
	pi->current_ps.num_levels = 1;
1352
	pi->current_ps.num_levels = 1;
1334
	pi->current_ps.levels[0] = pi->boot_pl;
1353
	pi->current_ps.levels[0] = pi->boot_pl;
1335
}
1354
}
1336
 
1355
 
1337
static u8 trinity_get_sleep_divider_id_from_clock(struct radeon_device *rdev,
1356
static u8 trinity_get_sleep_divider_id_from_clock(struct radeon_device *rdev,
1338
						  u32 sclk, u32 min_sclk_in_sr)
1357
						  u32 sclk, u32 min_sclk_in_sr)
1339
{
1358
{
1340
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1359
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1341
	u32 i;
1360
	u32 i;
1342
	u32 temp;
1361
	u32 temp;
1343
	u32 min = (min_sclk_in_sr > TRINITY_MINIMUM_ENGINE_CLOCK) ?
1362
	u32 min = (min_sclk_in_sr > TRINITY_MINIMUM_ENGINE_CLOCK) ?
1344
		min_sclk_in_sr : TRINITY_MINIMUM_ENGINE_CLOCK;
1363
		min_sclk_in_sr : TRINITY_MINIMUM_ENGINE_CLOCK;
1345
 
1364
 
1346
	if (sclk < min)
1365
	if (sclk < min)
1347
		return 0;
1366
		return 0;
1348
 
1367
 
1349
	if (!pi->enable_sclk_ds)
1368
	if (!pi->enable_sclk_ds)
1350
		return 0;
1369
		return 0;
1351
 
1370
 
1352
	for (i = TRINITY_MAX_DEEPSLEEP_DIVIDER_ID;  ; i--) {
1371
	for (i = TRINITY_MAX_DEEPSLEEP_DIVIDER_ID;  ; i--) {
1353
		temp = sclk / sumo_get_sleep_divider_from_id(i);
1372
		temp = sclk / sumo_get_sleep_divider_from_id(i);
1354
		if (temp >= min || i == 0)
1373
		if (temp >= min || i == 0)
1355
			break;
1374
			break;
1356
	}
1375
	}
1357
 
1376
 
1358
	return (u8)i;
1377
	return (u8)i;
1359
}
1378
}
1360
 
1379
 
1361
static u32 trinity_get_valid_engine_clock(struct radeon_device *rdev,
1380
static u32 trinity_get_valid_engine_clock(struct radeon_device *rdev,
1362
					  u32 lower_limit)
1381
					  u32 lower_limit)
1363
{
1382
{
1364
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1383
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1365
	u32 i;
1384
	u32 i;
1366
 
1385
 
1367
	for (i = 0; i < pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries; i++) {
1386
	for (i = 0; i < pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries; i++) {
1368
		if (pi->sys_info.sclk_voltage_mapping_table.entries[i].sclk_frequency >= lower_limit)
1387
		if (pi->sys_info.sclk_voltage_mapping_table.entries[i].sclk_frequency >= lower_limit)
1369
			return pi->sys_info.sclk_voltage_mapping_table.entries[i].sclk_frequency;
1388
			return pi->sys_info.sclk_voltage_mapping_table.entries[i].sclk_frequency;
1370
	}
1389
	}
1371
 
1390
 
1372
	if (i == pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries)
1391
	if (i == pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries)
1373
		DRM_ERROR("engine clock out of range!");
1392
		DRM_ERROR("engine clock out of range!");
1374
 
1393
 
1375
	return 0;
1394
	return 0;
1376
}
1395
}
1377
 
1396
 
1378
static void trinity_patch_thermal_state(struct radeon_device *rdev,
1397
static void trinity_patch_thermal_state(struct radeon_device *rdev,
1379
					struct trinity_ps *ps,
1398
					struct trinity_ps *ps,
1380
					struct trinity_ps *current_ps)
1399
					struct trinity_ps *current_ps)
1381
{
1400
{
1382
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1401
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1383
	u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */
1402
	u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */
1384
	u32 current_vddc;
1403
	u32 current_vddc;
1385
	u32 current_sclk;
1404
	u32 current_sclk;
1386
	u32 current_index = 0;
1405
	u32 current_index = 0;
1387
 
1406
 
1388
	if (current_ps) {
1407
	if (current_ps) {
1389
		current_vddc = current_ps->levels[current_index].vddc_index;
1408
		current_vddc = current_ps->levels[current_index].vddc_index;
1390
		current_sclk = current_ps->levels[current_index].sclk;
1409
		current_sclk = current_ps->levels[current_index].sclk;
1391
	} else {
1410
	} else {
1392
		current_vddc = pi->boot_pl.vddc_index;
1411
		current_vddc = pi->boot_pl.vddc_index;
1393
		current_sclk = pi->boot_pl.sclk;
1412
		current_sclk = pi->boot_pl.sclk;
1394
	}
1413
	}
1395
 
1414
 
1396
	ps->levels[0].vddc_index = current_vddc;
1415
	ps->levels[0].vddc_index = current_vddc;
1397
 
1416
 
1398
	if (ps->levels[0].sclk > current_sclk)
1417
	if (ps->levels[0].sclk > current_sclk)
1399
		ps->levels[0].sclk = current_sclk;
1418
		ps->levels[0].sclk = current_sclk;
1400
 
1419
 
1401
	ps->levels[0].ds_divider_index =
1420
	ps->levels[0].ds_divider_index =
1402
		trinity_get_sleep_divider_id_from_clock(rdev, ps->levels[0].sclk, sclk_in_sr);
1421
		trinity_get_sleep_divider_id_from_clock(rdev, ps->levels[0].sclk, sclk_in_sr);
1403
	ps->levels[0].ss_divider_index = ps->levels[0].ds_divider_index;
1422
	ps->levels[0].ss_divider_index = ps->levels[0].ds_divider_index;
1404
	ps->levels[0].allow_gnb_slow = 1;
1423
	ps->levels[0].allow_gnb_slow = 1;
1405
	ps->levels[0].force_nbp_state = 0;
1424
	ps->levels[0].force_nbp_state = 0;
1406
	ps->levels[0].display_wm = 0;
1425
	ps->levels[0].display_wm = 0;
1407
	ps->levels[0].vce_wm =
1426
	ps->levels[0].vce_wm =
1408
		trinity_calculate_vce_wm(rdev, ps->levels[0].sclk);
1427
		trinity_calculate_vce_wm(rdev, ps->levels[0].sclk);
1409
}
1428
}
1410
 
1429
 
1411
static u8 trinity_calculate_display_wm(struct radeon_device *rdev,
1430
static u8 trinity_calculate_display_wm(struct radeon_device *rdev,
1412
				       struct trinity_ps *ps, u32 index)
1431
				       struct trinity_ps *ps, u32 index)
1413
{
1432
{
1414
	if (ps == NULL || ps->num_levels <= 1)
1433
	if (ps == NULL || ps->num_levels <= 1)
1415
		return 0;
1434
		return 0;
1416
	else if (ps->num_levels == 2) {
1435
	else if (ps->num_levels == 2) {
1417
		if (index == 0)
1436
		if (index == 0)
1418
			return 0;
1437
			return 0;
1419
		else
1438
		else
1420
			return 1;
1439
			return 1;
1421
	} else {
1440
	} else {
1422
		if (index == 0)
1441
		if (index == 0)
1423
			return 0;
1442
			return 0;
1424
		else if (ps->levels[index].sclk < 30000)
1443
		else if (ps->levels[index].sclk < 30000)
1425
			return 0;
1444
			return 0;
1426
		else
1445
		else
1427
			return 1;
1446
			return 1;
1428
	}
1447
	}
1429
}
1448
}
1430
 
1449
 
1431
static u32 trinity_get_uvd_clock_index(struct radeon_device *rdev,
1450
static u32 trinity_get_uvd_clock_index(struct radeon_device *rdev,
1432
				       struct radeon_ps *rps)
1451
				       struct radeon_ps *rps)
1433
{
1452
{
1434
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1453
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1435
	u32 i = 0;
1454
	u32 i = 0;
1436
 
1455
 
1437
	for (i = 0; i < 4; i++) {
1456
	for (i = 0; i < 4; i++) {
1438
		if ((rps->vclk == pi->sys_info.uvd_clock_table_entries[i].vclk) &&
1457
		if ((rps->vclk == pi->sys_info.uvd_clock_table_entries[i].vclk) &&
1439
		    (rps->dclk == pi->sys_info.uvd_clock_table_entries[i].dclk))
1458
		    (rps->dclk == pi->sys_info.uvd_clock_table_entries[i].dclk))
1440
		    break;
1459
		    break;
1441
	}
1460
	}
1442
 
1461
 
1443
	if (i >= 4) {
1462
	if (i >= 4) {
1444
		DRM_ERROR("UVD clock index not found!\n");
1463
		DRM_ERROR("UVD clock index not found!\n");
1445
		i = 3;
1464
		i = 3;
1446
	}
1465
	}
1447
	return i;
1466
	return i;
1448
}
1467
}
1449
 
1468
 
1450
static void trinity_adjust_uvd_state(struct radeon_device *rdev,
1469
static void trinity_adjust_uvd_state(struct radeon_device *rdev,
1451
				     struct radeon_ps *rps)
1470
				     struct radeon_ps *rps)
1452
{
1471
{
1453
	struct trinity_ps *ps = trinity_get_ps(rps);
1472
	struct trinity_ps *ps = trinity_get_ps(rps);
1454
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1473
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1455
	u32 high_index = 0;
1474
	u32 high_index = 0;
1456
	u32 low_index = 0;
1475
	u32 low_index = 0;
1457
 
1476
 
1458
	if (pi->uvd_dpm && r600_is_uvd_state(rps->class, rps->class2)) {
1477
	if (pi->uvd_dpm && r600_is_uvd_state(rps->class, rps->class2)) {
1459
		high_index = trinity_get_uvd_clock_index(rdev, rps);
1478
		high_index = trinity_get_uvd_clock_index(rdev, rps);
1460
 
1479
 
1461
		switch(high_index) {
1480
		switch(high_index) {
1462
		case 3:
1481
		case 3:
1463
		case 2:
1482
		case 2:
1464
			low_index = 1;
1483
			low_index = 1;
1465
			break;
1484
			break;
1466
		case 1:
1485
		case 1:
1467
		case 0:
1486
		case 0:
1468
		default:
1487
		default:
1469
			low_index = 0;
1488
			low_index = 0;
1470
			break;
1489
			break;
1471
		}
1490
		}
1472
 
1491
 
1473
		ps->vclk_low_divider =
1492
		ps->vclk_low_divider =
1474
			pi->sys_info.uvd_clock_table_entries[high_index].vclk_did;
1493
			pi->sys_info.uvd_clock_table_entries[high_index].vclk_did;
1475
		ps->dclk_low_divider =
1494
		ps->dclk_low_divider =
1476
			pi->sys_info.uvd_clock_table_entries[high_index].dclk_did;
1495
			pi->sys_info.uvd_clock_table_entries[high_index].dclk_did;
1477
		ps->vclk_high_divider =
1496
		ps->vclk_high_divider =
1478
			pi->sys_info.uvd_clock_table_entries[low_index].vclk_did;
1497
			pi->sys_info.uvd_clock_table_entries[low_index].vclk_did;
1479
		ps->dclk_high_divider =
1498
		ps->dclk_high_divider =
1480
			pi->sys_info.uvd_clock_table_entries[low_index].dclk_did;
1499
			pi->sys_info.uvd_clock_table_entries[low_index].dclk_did;
1481
	}
1500
	}
1482
}
1501
}
-
 
1502
 
-
 
1503
static int trinity_get_vce_clock_voltage(struct radeon_device *rdev,
-
 
1504
					 u32 evclk, u32 ecclk, u16 *voltage)
-
 
1505
{
-
 
1506
	u32 i;
-
 
1507
	int ret = -EINVAL;
-
 
1508
	struct radeon_vce_clock_voltage_dependency_table *table =
-
 
1509
		&rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table;
-
 
1510
 
-
 
1511
	if (((evclk == 0) && (ecclk == 0)) ||
-
 
1512
	    (table && (table->count == 0))) {
-
 
1513
		*voltage = 0;
-
 
1514
		return 0;
-
 
1515
	}
-
 
1516
 
-
 
1517
	for (i = 0; i < table->count; i++) {
-
 
1518
		if ((evclk <= table->entries[i].evclk) &&
-
 
1519
		    (ecclk <= table->entries[i].ecclk)) {
-
 
1520
			*voltage = table->entries[i].v;
-
 
1521
			ret = 0;
-
 
1522
			break;
-
 
1523
		}
-
 
1524
	}
-
 
1525
 
-
 
1526
	/* if no match return the highest voltage */
-
 
1527
	if (ret)
-
 
1528
		*voltage = table->entries[table->count - 1].v;
-
 
1529
 
1483
 
1530
	return ret;
1484
 
1531
}
1485
 
1532
 
1486
static void trinity_apply_state_adjust_rules(struct radeon_device *rdev,
1533
static void trinity_apply_state_adjust_rules(struct radeon_device *rdev,
1487
					     struct radeon_ps *new_rps,
1534
					     struct radeon_ps *new_rps,
1488
					     struct radeon_ps *old_rps)
1535
					     struct radeon_ps *old_rps)
1489
{
1536
{
1490
	struct trinity_ps *ps = trinity_get_ps(new_rps);
1537
	struct trinity_ps *ps = trinity_get_ps(new_rps);
1491
	struct trinity_ps *current_ps = trinity_get_ps(old_rps);
1538
	struct trinity_ps *current_ps = trinity_get_ps(old_rps);
1492
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1539
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1493
	u32 min_voltage = 0; /* ??? */
1540
	u32 min_voltage = 0; /* ??? */
1494
	u32 min_sclk = pi->sys_info.min_sclk; /* XXX check against disp reqs */
1541
	u32 min_sclk = pi->sys_info.min_sclk; /* XXX check against disp reqs */
1495
	u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */
1542
	u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */
1496
	u32 i;
1543
	u32 i;
-
 
1544
	u16 min_vce_voltage;
1497
	bool force_high;
1545
	bool force_high;
1498
	u32 num_active_displays = rdev->pm.dpm.new_active_crtc_count;
1546
	u32 num_active_displays = rdev->pm.dpm.new_active_crtc_count;
1499
 
1547
 
1500
	if (new_rps->class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
1548
	if (new_rps->class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
1501
		return trinity_patch_thermal_state(rdev, ps, current_ps);
1549
		return trinity_patch_thermal_state(rdev, ps, current_ps);
1502
 
1550
 
1503
	trinity_adjust_uvd_state(rdev, new_rps);
1551
	trinity_adjust_uvd_state(rdev, new_rps);
-
 
1552
 
-
 
1553
	if (new_rps->vce_active) {
-
 
1554
		new_rps->evclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].evclk;
-
 
1555
		new_rps->ecclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].ecclk;
-
 
1556
	} else {
-
 
1557
		new_rps->evclk = 0;
-
 
1558
		new_rps->ecclk = 0;
-
 
1559
	}
1504
 
1560
 
1505
	for (i = 0; i < ps->num_levels; i++) {
1561
	for (i = 0; i < ps->num_levels; i++) {
1506
		if (ps->levels[i].vddc_index < min_voltage)
1562
		if (ps->levels[i].vddc_index < min_voltage)
1507
			ps->levels[i].vddc_index = min_voltage;
1563
			ps->levels[i].vddc_index = min_voltage;
1508
 
1564
 
1509
		if (ps->levels[i].sclk < min_sclk)
1565
		if (ps->levels[i].sclk < min_sclk)
1510
			ps->levels[i].sclk =
1566
			ps->levels[i].sclk =
1511
				trinity_get_valid_engine_clock(rdev, min_sclk);
1567
				trinity_get_valid_engine_clock(rdev, min_sclk);
-
 
1568
 
-
 
1569
		/* patch in vce limits */
-
 
1570
		if (new_rps->vce_active) {
-
 
1571
			/* sclk */
-
 
1572
			if (ps->levels[i].sclk < rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk)
-
 
1573
				ps->levels[i].sclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk;
-
 
1574
			/* vddc */
-
 
1575
			trinity_get_vce_clock_voltage(rdev, new_rps->evclk, new_rps->ecclk, &min_vce_voltage);
-
 
1576
			if (ps->levels[i].vddc_index < min_vce_voltage)
-
 
1577
				ps->levels[i].vddc_index = min_vce_voltage;
-
 
1578
		}
1512
 
1579
 
1513
		ps->levels[i].ds_divider_index =
1580
		ps->levels[i].ds_divider_index =
1514
			sumo_get_sleep_divider_id_from_clock(rdev, ps->levels[i].sclk, sclk_in_sr);
1581
			sumo_get_sleep_divider_id_from_clock(rdev, ps->levels[i].sclk, sclk_in_sr);
1515
 
1582
 
1516
		ps->levels[i].ss_divider_index = ps->levels[i].ds_divider_index;
1583
		ps->levels[i].ss_divider_index = ps->levels[i].ds_divider_index;
1517
 
1584
 
1518
		ps->levels[i].allow_gnb_slow = 1;
1585
		ps->levels[i].allow_gnb_slow = 1;
1519
		ps->levels[i].force_nbp_state = 0;
1586
		ps->levels[i].force_nbp_state = 0;
1520
		ps->levels[i].display_wm =
1587
		ps->levels[i].display_wm =
1521
			trinity_calculate_display_wm(rdev, ps, i);
1588
			trinity_calculate_display_wm(rdev, ps, i);
1522
		ps->levels[i].vce_wm =
1589
		ps->levels[i].vce_wm =
1523
			trinity_calculate_vce_wm(rdev, ps->levels[0].sclk);
1590
			trinity_calculate_vce_wm(rdev, ps->levels[0].sclk);
1524
	}
1591
	}
1525
 
1592
 
1526
	if ((new_rps->class & (ATOM_PPLIB_CLASSIFICATION_HDSTATE | ATOM_PPLIB_CLASSIFICATION_SDSTATE)) ||
1593
	if ((new_rps->class & (ATOM_PPLIB_CLASSIFICATION_HDSTATE | ATOM_PPLIB_CLASSIFICATION_SDSTATE)) ||
1527
	    ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == ATOM_PPLIB_CLASSIFICATION_UI_BATTERY))
1594
	    ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == ATOM_PPLIB_CLASSIFICATION_UI_BATTERY))
1528
		ps->bapm_flags |= TRINITY_POWERSTATE_FLAGS_BAPM_DISABLE;
1595
		ps->bapm_flags |= TRINITY_POWERSTATE_FLAGS_BAPM_DISABLE;
1529
 
1596
 
1530
	if (pi->sys_info.nb_dpm_enable) {
1597
	if (pi->sys_info.nb_dpm_enable) {
1531
		ps->Dpm0PgNbPsLo = 0x1;
1598
		ps->Dpm0PgNbPsLo = 0x1;
1532
		ps->Dpm0PgNbPsHi = 0x0;
1599
		ps->Dpm0PgNbPsHi = 0x0;
1533
		ps->DpmXNbPsLo = 0x2;
1600
		ps->DpmXNbPsLo = 0x2;
1534
		ps->DpmXNbPsHi = 0x1;
1601
		ps->DpmXNbPsHi = 0x1;
1535
 
1602
 
1536
		if ((new_rps->class & (ATOM_PPLIB_CLASSIFICATION_HDSTATE | ATOM_PPLIB_CLASSIFICATION_SDSTATE)) ||
1603
		if ((new_rps->class & (ATOM_PPLIB_CLASSIFICATION_HDSTATE | ATOM_PPLIB_CLASSIFICATION_SDSTATE)) ||
1537
		    ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == ATOM_PPLIB_CLASSIFICATION_UI_BATTERY)) {
1604
		    ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == ATOM_PPLIB_CLASSIFICATION_UI_BATTERY)) {
1538
			force_high = ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_HDSTATE) ||
1605
			force_high = ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_HDSTATE) ||
1539
				      ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_SDSTATE) &&
1606
				      ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_SDSTATE) &&
1540
				       (pi->sys_info.uma_channel_number == 1)));
1607
				       (pi->sys_info.uma_channel_number == 1)));
1541
			force_high = (num_active_displays >= 3) || force_high;
1608
			force_high = (num_active_displays >= 3) || force_high;
1542
			ps->Dpm0PgNbPsLo = force_high ? 0x2 : 0x3;
1609
			ps->Dpm0PgNbPsLo = force_high ? 0x2 : 0x3;
1543
			ps->Dpm0PgNbPsHi = 0x1;
1610
			ps->Dpm0PgNbPsHi = 0x1;
1544
			ps->DpmXNbPsLo = force_high ? 0x2 : 0x3;
1611
			ps->DpmXNbPsLo = force_high ? 0x2 : 0x3;
1545
			ps->DpmXNbPsHi = 0x2;
1612
			ps->DpmXNbPsHi = 0x2;
1546
			ps->levels[ps->num_levels - 1].allow_gnb_slow = 0;
1613
			ps->levels[ps->num_levels - 1].allow_gnb_slow = 0;
1547
		}
1614
		}
1548
	}
1615
	}
1549
}
1616
}
1550
 
1617
 
1551
static void trinity_cleanup_asic(struct radeon_device *rdev)
1618
static void trinity_cleanup_asic(struct radeon_device *rdev)
1552
{
1619
{
1553
	sumo_take_smu_control(rdev, false);
1620
	sumo_take_smu_control(rdev, false);
1554
}
1621
}
1555
 
1622
 
1556
#if 0
1623
#if 0
1557
static void trinity_pre_display_configuration_change(struct radeon_device *rdev)
1624
static void trinity_pre_display_configuration_change(struct radeon_device *rdev)
1558
{
1625
{
1559
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1626
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1560
 
1627
 
1561
	if (pi->voltage_drop_in_dce)
1628
	if (pi->voltage_drop_in_dce)
1562
		trinity_dce_enable_voltage_adjustment(rdev, false);
1629
		trinity_dce_enable_voltage_adjustment(rdev, false);
1563
}
1630
}
1564
#endif
1631
#endif
1565
 
1632
 
1566
static void trinity_add_dccac_value(struct radeon_device *rdev)
1633
static void trinity_add_dccac_value(struct radeon_device *rdev)
1567
{
1634
{
1568
	u32 gpu_cac_avrg_cntl_window_size;
1635
	u32 gpu_cac_avrg_cntl_window_size;
1569
	u32 num_active_displays = rdev->pm.dpm.new_active_crtc_count;
1636
	u32 num_active_displays = rdev->pm.dpm.new_active_crtc_count;
1570
	u64 disp_clk = rdev->clock.default_dispclk / 100;
1637
	u64 disp_clk = rdev->clock.default_dispclk / 100;
1571
	u32 dc_cac_value;
1638
	u32 dc_cac_value;
1572
 
1639
 
1573
	gpu_cac_avrg_cntl_window_size =
1640
	gpu_cac_avrg_cntl_window_size =
1574
		(RREG32_SMC(GPU_CAC_AVRG_CNTL) & WINDOW_SIZE_MASK) >> WINDOW_SIZE_SHIFT;
1641
		(RREG32_SMC(GPU_CAC_AVRG_CNTL) & WINDOW_SIZE_MASK) >> WINDOW_SIZE_SHIFT;
1575
 
1642
 
1576
	dc_cac_value = (u32)((14213 * disp_clk * disp_clk * (u64)num_active_displays) >>
1643
	dc_cac_value = (u32)((14213 * disp_clk * disp_clk * (u64)num_active_displays) >>
1577
			     (32 - gpu_cac_avrg_cntl_window_size));
1644
			     (32 - gpu_cac_avrg_cntl_window_size));
1578
 
1645
 
1579
	WREG32_SMC(DC_CAC_VALUE, dc_cac_value);
1646
	WREG32_SMC(DC_CAC_VALUE, dc_cac_value);
1580
}
1647
}
1581
 
1648
 
1582
void trinity_dpm_display_configuration_changed(struct radeon_device *rdev)
1649
void trinity_dpm_display_configuration_changed(struct radeon_device *rdev)
1583
{
1650
{
1584
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1651
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1585
 
1652
 
1586
	if (pi->voltage_drop_in_dce)
1653
	if (pi->voltage_drop_in_dce)
1587
		trinity_dce_enable_voltage_adjustment(rdev, true);
1654
		trinity_dce_enable_voltage_adjustment(rdev, true);
1588
	trinity_add_dccac_value(rdev);
1655
	trinity_add_dccac_value(rdev);
1589
}
1656
}
1590
 
1657
 
1591
union power_info {
1658
union power_info {
1592
	struct _ATOM_POWERPLAY_INFO info;
1659
	struct _ATOM_POWERPLAY_INFO info;
1593
	struct _ATOM_POWERPLAY_INFO_V2 info_2;
1660
	struct _ATOM_POWERPLAY_INFO_V2 info_2;
1594
	struct _ATOM_POWERPLAY_INFO_V3 info_3;
1661
	struct _ATOM_POWERPLAY_INFO_V3 info_3;
1595
	struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
1662
	struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
1596
	struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
1663
	struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
1597
	struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
1664
	struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
1598
};
1665
};
1599
 
1666
 
1600
union pplib_clock_info {
1667
union pplib_clock_info {
1601
	struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
1668
	struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
1602
	struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
1669
	struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
1603
	struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
1670
	struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
1604
	struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
1671
	struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
1605
};
1672
};
1606
 
1673
 
1607
union pplib_power_state {
1674
union pplib_power_state {
1608
	struct _ATOM_PPLIB_STATE v1;
1675
	struct _ATOM_PPLIB_STATE v1;
1609
	struct _ATOM_PPLIB_STATE_V2 v2;
1676
	struct _ATOM_PPLIB_STATE_V2 v2;
1610
};
1677
};
1611
 
1678
 
1612
static void trinity_parse_pplib_non_clock_info(struct radeon_device *rdev,
1679
static void trinity_parse_pplib_non_clock_info(struct radeon_device *rdev,
1613
					       struct radeon_ps *rps,
1680
					       struct radeon_ps *rps,
1614
					       struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
1681
					       struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
1615
					       u8 table_rev)
1682
					       u8 table_rev)
1616
{
1683
{
1617
	struct trinity_ps *ps = trinity_get_ps(rps);
1684
	struct trinity_ps *ps = trinity_get_ps(rps);
1618
 
1685
 
1619
	rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
1686
	rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
1620
	rps->class = le16_to_cpu(non_clock_info->usClassification);
1687
	rps->class = le16_to_cpu(non_clock_info->usClassification);
1621
	rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
1688
	rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
1622
 
1689
 
1623
	if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
1690
	if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
1624
		rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
1691
		rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
1625
		rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
1692
		rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
1626
	} else {
1693
	} else {
1627
		rps->vclk = 0;
1694
		rps->vclk = 0;
1628
		rps->dclk = 0;
1695
		rps->dclk = 0;
1629
	}
1696
	}
1630
 
1697
 
1631
	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
1698
	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
1632
		rdev->pm.dpm.boot_ps = rps;
1699
		rdev->pm.dpm.boot_ps = rps;
1633
		trinity_patch_boot_state(rdev, ps);
1700
		trinity_patch_boot_state(rdev, ps);
1634
	}
1701
	}
1635
	if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
1702
	if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
1636
		rdev->pm.dpm.uvd_ps = rps;
1703
		rdev->pm.dpm.uvd_ps = rps;
1637
}
1704
}
1638
 
1705
 
1639
static void trinity_parse_pplib_clock_info(struct radeon_device *rdev,
1706
static void trinity_parse_pplib_clock_info(struct radeon_device *rdev,
1640
					   struct radeon_ps *rps, int index,
1707
					   struct radeon_ps *rps, int index,
1641
					   union pplib_clock_info *clock_info)
1708
					   union pplib_clock_info *clock_info)
1642
{
1709
{
1643
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1710
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1644
	struct trinity_ps *ps = trinity_get_ps(rps);
1711
	struct trinity_ps *ps = trinity_get_ps(rps);
1645
	struct trinity_pl *pl = &ps->levels[index];
1712
	struct trinity_pl *pl = &ps->levels[index];
1646
	u32 sclk;
1713
	u32 sclk;
1647
 
1714
 
1648
	sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);
1715
	sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);
1649
	sclk |= clock_info->sumo.ucEngineClockHigh << 16;
1716
	sclk |= clock_info->sumo.ucEngineClockHigh << 16;
1650
	pl->sclk = sclk;
1717
	pl->sclk = sclk;
1651
	pl->vddc_index = clock_info->sumo.vddcIndex;
1718
	pl->vddc_index = clock_info->sumo.vddcIndex;
1652
 
1719
 
1653
	ps->num_levels = index + 1;
1720
	ps->num_levels = index + 1;
1654
 
1721
 
1655
	if (pi->enable_sclk_ds) {
1722
	if (pi->enable_sclk_ds) {
1656
		pl->ds_divider_index = 5;
1723
		pl->ds_divider_index = 5;
1657
		pl->ss_divider_index = 5;
1724
		pl->ss_divider_index = 5;
1658
	}
1725
	}
1659
}
1726
}
1660
 
1727
 
1661
static int trinity_parse_power_table(struct radeon_device *rdev)
1728
static int trinity_parse_power_table(struct radeon_device *rdev)
1662
{
1729
{
1663
	struct radeon_mode_info *mode_info = &rdev->mode_info;
1730
	struct radeon_mode_info *mode_info = &rdev->mode_info;
1664
	struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
1731
	struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
1665
	union pplib_power_state *power_state;
1732
	union pplib_power_state *power_state;
1666
	int i, j, k, non_clock_array_index, clock_array_index;
1733
	int i, j, k, non_clock_array_index, clock_array_index;
1667
	union pplib_clock_info *clock_info;
1734
	union pplib_clock_info *clock_info;
1668
	struct _StateArray *state_array;
1735
	struct _StateArray *state_array;
1669
	struct _ClockInfoArray *clock_info_array;
1736
	struct _ClockInfoArray *clock_info_array;
1670
	struct _NonClockInfoArray *non_clock_info_array;
1737
	struct _NonClockInfoArray *non_clock_info_array;
1671
	union power_info *power_info;
1738
	union power_info *power_info;
1672
	int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
1739
	int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
1673
        u16 data_offset;
1740
        u16 data_offset;
1674
	u8 frev, crev;
1741
	u8 frev, crev;
1675
	u8 *power_state_offset;
1742
	u8 *power_state_offset;
1676
	struct sumo_ps *ps;
1743
	struct sumo_ps *ps;
1677
 
1744
 
1678
	if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
1745
	if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
1679
				   &frev, &crev, &data_offset))
1746
				   &frev, &crev, &data_offset))
1680
		return -EINVAL;
1747
		return -EINVAL;
1681
	power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
1748
	power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
1682
 
1749
 
1683
	state_array = (struct _StateArray *)
1750
	state_array = (struct _StateArray *)
1684
		(mode_info->atom_context->bios + data_offset +
1751
		(mode_info->atom_context->bios + data_offset +
1685
		 le16_to_cpu(power_info->pplib.usStateArrayOffset));
1752
		 le16_to_cpu(power_info->pplib.usStateArrayOffset));
1686
	clock_info_array = (struct _ClockInfoArray *)
1753
	clock_info_array = (struct _ClockInfoArray *)
1687
		(mode_info->atom_context->bios + data_offset +
1754
		(mode_info->atom_context->bios + data_offset +
1688
		 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
1755
		 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
1689
	non_clock_info_array = (struct _NonClockInfoArray *)
1756
	non_clock_info_array = (struct _NonClockInfoArray *)
1690
		(mode_info->atom_context->bios + data_offset +
1757
		(mode_info->atom_context->bios + data_offset +
1691
		 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
1758
		 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
1692
 
1759
 
1693
	rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) *
1760
	rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) *
1694
				  state_array->ucNumEntries, GFP_KERNEL);
1761
				  state_array->ucNumEntries, GFP_KERNEL);
1695
	if (!rdev->pm.dpm.ps)
1762
	if (!rdev->pm.dpm.ps)
1696
		return -ENOMEM;
1763
		return -ENOMEM;
1697
	power_state_offset = (u8 *)state_array->states;
1764
	power_state_offset = (u8 *)state_array->states;
1698
	for (i = 0; i < state_array->ucNumEntries; i++) {
1765
	for (i = 0; i < state_array->ucNumEntries; i++) {
1699
		u8 *idx;
1766
		u8 *idx;
1700
		power_state = (union pplib_power_state *)power_state_offset;
1767
		power_state = (union pplib_power_state *)power_state_offset;
1701
		non_clock_array_index = power_state->v2.nonClockInfoIndex;
1768
		non_clock_array_index = power_state->v2.nonClockInfoIndex;
1702
		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
1769
		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
1703
			&non_clock_info_array->nonClockInfo[non_clock_array_index];
1770
			&non_clock_info_array->nonClockInfo[non_clock_array_index];
1704
		if (!rdev->pm.power_state[i].clock_info)
1771
		if (!rdev->pm.power_state[i].clock_info)
1705
			return -EINVAL;
1772
			return -EINVAL;
1706
		ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL);
1773
		ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL);
1707
		if (ps == NULL) {
1774
		if (ps == NULL) {
1708
			kfree(rdev->pm.dpm.ps);
1775
			kfree(rdev->pm.dpm.ps);
1709
			return -ENOMEM;
1776
			return -ENOMEM;
1710
		}
1777
		}
1711
		rdev->pm.dpm.ps[i].ps_priv = ps;
1778
		rdev->pm.dpm.ps[i].ps_priv = ps;
1712
		k = 0;
1779
		k = 0;
1713
		idx = (u8 *)&power_state->v2.clockInfoIndex[0];
1780
		idx = (u8 *)&power_state->v2.clockInfoIndex[0];
1714
		for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
1781
		for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
1715
			clock_array_index = idx[j];
1782
			clock_array_index = idx[j];
1716
			if (clock_array_index >= clock_info_array->ucNumEntries)
1783
			if (clock_array_index >= clock_info_array->ucNumEntries)
1717
				continue;
1784
				continue;
1718
			if (k >= SUMO_MAX_HARDWARE_POWERLEVELS)
1785
			if (k >= SUMO_MAX_HARDWARE_POWERLEVELS)
1719
				break;
1786
				break;
1720
			clock_info = (union pplib_clock_info *)
1787
			clock_info = (union pplib_clock_info *)
1721
				((u8 *)&clock_info_array->clockInfo[0] +
1788
				((u8 *)&clock_info_array->clockInfo[0] +
1722
				 (clock_array_index * clock_info_array->ucEntrySize));
1789
				 (clock_array_index * clock_info_array->ucEntrySize));
1723
			trinity_parse_pplib_clock_info(rdev,
1790
			trinity_parse_pplib_clock_info(rdev,
1724
						       &rdev->pm.dpm.ps[i], k,
1791
						       &rdev->pm.dpm.ps[i], k,
1725
						       clock_info);
1792
						       clock_info);
1726
			k++;
1793
			k++;
1727
		}
1794
		}
1728
		trinity_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
1795
		trinity_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
1729
						   non_clock_info,
1796
						   non_clock_info,
1730
						   non_clock_info_array->ucEntrySize);
1797
						   non_clock_info_array->ucEntrySize);
1731
		power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
1798
		power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
1732
	}
1799
	}
1733
	rdev->pm.dpm.num_ps = state_array->ucNumEntries;
1800
	rdev->pm.dpm.num_ps = state_array->ucNumEntries;
-
 
1801
 
-
 
1802
	/* fill in the vce power states */
-
 
1803
	for (i = 0; i < RADEON_MAX_VCE_LEVELS; i++) {
-
 
1804
		u32 sclk;
-
 
1805
		clock_array_index = rdev->pm.dpm.vce_states[i].clk_idx;
-
 
1806
		clock_info = (union pplib_clock_info *)
-
 
1807
			&clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
-
 
1808
		sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);
-
 
1809
		sclk |= clock_info->sumo.ucEngineClockHigh << 16;
-
 
1810
		rdev->pm.dpm.vce_states[i].sclk = sclk;
-
 
1811
		rdev->pm.dpm.vce_states[i].mclk = 0;
-
 
1812
	}
-
 
1813
 
1734
	return 0;
1814
	return 0;
1735
}
1815
}
1736
 
1816
 
1737
union igp_info {
1817
union igp_info {
1738
	struct _ATOM_INTEGRATED_SYSTEM_INFO info;
1818
	struct _ATOM_INTEGRATED_SYSTEM_INFO info;
1739
	struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
1819
	struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
1740
	struct _ATOM_INTEGRATED_SYSTEM_INFO_V5 info_5;
1820
	struct _ATOM_INTEGRATED_SYSTEM_INFO_V5 info_5;
1741
	struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
1821
	struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
1742
	struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;
1822
	struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;
1743
};
1823
};
1744
 
1824
 
1745
static u32 trinity_convert_did_to_freq(struct radeon_device *rdev, u8 did)
1825
static u32 trinity_convert_did_to_freq(struct radeon_device *rdev, u8 did)
1746
{
1826
{
1747
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1827
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1748
	u32 divider;
1828
	u32 divider;
1749
 
1829
 
1750
	if (did >= 8 && did <= 0x3f)
1830
	if (did >= 8 && did <= 0x3f)
1751
		divider = did * 25;
1831
		divider = did * 25;
1752
	else if (did > 0x3f && did <= 0x5f)
1832
	else if (did > 0x3f && did <= 0x5f)
1753
		divider = (did - 64) * 50 + 1600;
1833
		divider = (did - 64) * 50 + 1600;
1754
	else if (did > 0x5f && did <= 0x7e)
1834
	else if (did > 0x5f && did <= 0x7e)
1755
		divider = (did - 96) * 100 + 3200;
1835
		divider = (did - 96) * 100 + 3200;
1756
	else if (did == 0x7f)
1836
	else if (did == 0x7f)
1757
		divider = 128 * 100;
1837
		divider = 128 * 100;
1758
	else
1838
	else
1759
		return 10000;
1839
		return 10000;
1760
 
1840
 
1761
	return ((pi->sys_info.dentist_vco_freq * 100) + (divider - 1)) / divider;
1841
	return ((pi->sys_info.dentist_vco_freq * 100) + (divider - 1)) / divider;
1762
}
1842
}
1763
 
1843
 
1764
static int trinity_parse_sys_info_table(struct radeon_device *rdev)
1844
static int trinity_parse_sys_info_table(struct radeon_device *rdev)
1765
{
1845
{
1766
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1846
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1767
	struct radeon_mode_info *mode_info = &rdev->mode_info;
1847
	struct radeon_mode_info *mode_info = &rdev->mode_info;
1768
	int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
1848
	int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
1769
	union igp_info *igp_info;
1849
	union igp_info *igp_info;
1770
	u8 frev, crev;
1850
	u8 frev, crev;
1771
	u16 data_offset;
1851
	u16 data_offset;
1772
	int i;
1852
	int i;
1773
 
1853
 
1774
	if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1854
	if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1775
				   &frev, &crev, &data_offset)) {
1855
				   &frev, &crev, &data_offset)) {
1776
		igp_info = (union igp_info *)(mode_info->atom_context->bios +
1856
		igp_info = (union igp_info *)(mode_info->atom_context->bios +
1777
					      data_offset);
1857
					      data_offset);
1778
 
1858
 
1779
		if (crev != 7) {
1859
		if (crev != 7) {
1780
			DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
1860
			DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
1781
			return -EINVAL;
1861
			return -EINVAL;
1782
		}
1862
		}
1783
		pi->sys_info.bootup_sclk = le32_to_cpu(igp_info->info_7.ulBootUpEngineClock);
1863
		pi->sys_info.bootup_sclk = le32_to_cpu(igp_info->info_7.ulBootUpEngineClock);
1784
		pi->sys_info.min_sclk = le32_to_cpu(igp_info->info_7.ulMinEngineClock);
1864
		pi->sys_info.min_sclk = le32_to_cpu(igp_info->info_7.ulMinEngineClock);
1785
		pi->sys_info.bootup_uma_clk = le32_to_cpu(igp_info->info_7.ulBootUpUMAClock);
1865
		pi->sys_info.bootup_uma_clk = le32_to_cpu(igp_info->info_7.ulBootUpUMAClock);
1786
		pi->sys_info.dentist_vco_freq = le32_to_cpu(igp_info->info_7.ulDentistVCOFreq);
1866
		pi->sys_info.dentist_vco_freq = le32_to_cpu(igp_info->info_7.ulDentistVCOFreq);
1787
		pi->sys_info.bootup_nb_voltage_index =
1867
		pi->sys_info.bootup_nb_voltage_index =
1788
			le16_to_cpu(igp_info->info_7.usBootUpNBVoltage);
1868
			le16_to_cpu(igp_info->info_7.usBootUpNBVoltage);
1789
		if (igp_info->info_7.ucHtcTmpLmt == 0)
1869
		if (igp_info->info_7.ucHtcTmpLmt == 0)
1790
			pi->sys_info.htc_tmp_lmt = 203;
1870
			pi->sys_info.htc_tmp_lmt = 203;
1791
		else
1871
		else
1792
			pi->sys_info.htc_tmp_lmt = igp_info->info_7.ucHtcTmpLmt;
1872
			pi->sys_info.htc_tmp_lmt = igp_info->info_7.ucHtcTmpLmt;
1793
		if (igp_info->info_7.ucHtcHystLmt == 0)
1873
		if (igp_info->info_7.ucHtcHystLmt == 0)
1794
			pi->sys_info.htc_hyst_lmt = 5;
1874
			pi->sys_info.htc_hyst_lmt = 5;
1795
		else
1875
		else
1796
			pi->sys_info.htc_hyst_lmt = igp_info->info_7.ucHtcHystLmt;
1876
			pi->sys_info.htc_hyst_lmt = igp_info->info_7.ucHtcHystLmt;
1797
		if (pi->sys_info.htc_tmp_lmt <= pi->sys_info.htc_hyst_lmt) {
1877
		if (pi->sys_info.htc_tmp_lmt <= pi->sys_info.htc_hyst_lmt) {
1798
			DRM_ERROR("The htcTmpLmt should be larger than htcHystLmt.\n");
1878
			DRM_ERROR("The htcTmpLmt should be larger than htcHystLmt.\n");
1799
		}
1879
		}
1800
 
1880
 
1801
		if (pi->enable_nbps_policy)
1881
		if (pi->enable_nbps_policy)
1802
			pi->sys_info.nb_dpm_enable = igp_info->info_7.ucNBDPMEnable;
1882
			pi->sys_info.nb_dpm_enable = igp_info->info_7.ucNBDPMEnable;
1803
		else
1883
		else
1804
			pi->sys_info.nb_dpm_enable = 0;
1884
			pi->sys_info.nb_dpm_enable = 0;
1805
 
1885
 
1806
		for (i = 0; i < TRINITY_NUM_NBPSTATES; i++) {
1886
		for (i = 0; i < TRINITY_NUM_NBPSTATES; i++) {
1807
			pi->sys_info.nbp_mclk[i] = le32_to_cpu(igp_info->info_7.ulNbpStateMemclkFreq[i]);
1887
			pi->sys_info.nbp_mclk[i] = le32_to_cpu(igp_info->info_7.ulNbpStateMemclkFreq[i]);
1808
			pi->sys_info.nbp_nclk[i] = le32_to_cpu(igp_info->info_7.ulNbpStateNClkFreq[i]);
1888
			pi->sys_info.nbp_nclk[i] = le32_to_cpu(igp_info->info_7.ulNbpStateNClkFreq[i]);
1809
		}
1889
		}
1810
 
1890
 
1811
		pi->sys_info.nbp_voltage_index[0] = le16_to_cpu(igp_info->info_7.usNBP0Voltage);
1891
		pi->sys_info.nbp_voltage_index[0] = le16_to_cpu(igp_info->info_7.usNBP0Voltage);
1812
		pi->sys_info.nbp_voltage_index[1] = le16_to_cpu(igp_info->info_7.usNBP1Voltage);
1892
		pi->sys_info.nbp_voltage_index[1] = le16_to_cpu(igp_info->info_7.usNBP1Voltage);
1813
		pi->sys_info.nbp_voltage_index[2] = le16_to_cpu(igp_info->info_7.usNBP2Voltage);
1893
		pi->sys_info.nbp_voltage_index[2] = le16_to_cpu(igp_info->info_7.usNBP2Voltage);
1814
		pi->sys_info.nbp_voltage_index[3] = le16_to_cpu(igp_info->info_7.usNBP3Voltage);
1894
		pi->sys_info.nbp_voltage_index[3] = le16_to_cpu(igp_info->info_7.usNBP3Voltage);
1815
 
1895
 
1816
		if (!pi->sys_info.nb_dpm_enable) {
1896
		if (!pi->sys_info.nb_dpm_enable) {
1817
			for (i = 1; i < TRINITY_NUM_NBPSTATES; i++) {
1897
			for (i = 1; i < TRINITY_NUM_NBPSTATES; i++) {
1818
				pi->sys_info.nbp_mclk[i] = pi->sys_info.nbp_mclk[0];
1898
				pi->sys_info.nbp_mclk[i] = pi->sys_info.nbp_mclk[0];
1819
				pi->sys_info.nbp_nclk[i] = pi->sys_info.nbp_nclk[0];
1899
				pi->sys_info.nbp_nclk[i] = pi->sys_info.nbp_nclk[0];
1820
				pi->sys_info.nbp_voltage_index[i] = pi->sys_info.nbp_voltage_index[0];
1900
				pi->sys_info.nbp_voltage_index[i] = pi->sys_info.nbp_voltage_index[0];
1821
			}
1901
			}
1822
		}
1902
		}
1823
 
1903
 
1824
		pi->sys_info.uma_channel_number = igp_info->info_7.ucUMAChannelNumber;
1904
		pi->sys_info.uma_channel_number = igp_info->info_7.ucUMAChannelNumber;
1825
 
1905
 
1826
		sumo_construct_sclk_voltage_mapping_table(rdev,
1906
		sumo_construct_sclk_voltage_mapping_table(rdev,
1827
							  &pi->sys_info.sclk_voltage_mapping_table,
1907
							  &pi->sys_info.sclk_voltage_mapping_table,
1828
							  igp_info->info_7.sAvail_SCLK);
1908
							  igp_info->info_7.sAvail_SCLK);
1829
		sumo_construct_vid_mapping_table(rdev, &pi->sys_info.vid_mapping_table,
1909
		sumo_construct_vid_mapping_table(rdev, &pi->sys_info.vid_mapping_table,
1830
						 igp_info->info_7.sAvail_SCLK);
1910
						 igp_info->info_7.sAvail_SCLK);
1831
 
1911
 
1832
		pi->sys_info.uvd_clock_table_entries[0].vclk_did =
1912
		pi->sys_info.uvd_clock_table_entries[0].vclk_did =
1833
			igp_info->info_7.ucDPMState0VclkFid;
1913
			igp_info->info_7.ucDPMState0VclkFid;
1834
		pi->sys_info.uvd_clock_table_entries[1].vclk_did =
1914
		pi->sys_info.uvd_clock_table_entries[1].vclk_did =
1835
			igp_info->info_7.ucDPMState1VclkFid;
1915
			igp_info->info_7.ucDPMState1VclkFid;
1836
		pi->sys_info.uvd_clock_table_entries[2].vclk_did =
1916
		pi->sys_info.uvd_clock_table_entries[2].vclk_did =
1837
			igp_info->info_7.ucDPMState2VclkFid;
1917
			igp_info->info_7.ucDPMState2VclkFid;
1838
		pi->sys_info.uvd_clock_table_entries[3].vclk_did =
1918
		pi->sys_info.uvd_clock_table_entries[3].vclk_did =
1839
			igp_info->info_7.ucDPMState3VclkFid;
1919
			igp_info->info_7.ucDPMState3VclkFid;
1840
 
1920
 
1841
		pi->sys_info.uvd_clock_table_entries[0].dclk_did =
1921
		pi->sys_info.uvd_clock_table_entries[0].dclk_did =
1842
			igp_info->info_7.ucDPMState0DclkFid;
1922
			igp_info->info_7.ucDPMState0DclkFid;
1843
		pi->sys_info.uvd_clock_table_entries[1].dclk_did =
1923
		pi->sys_info.uvd_clock_table_entries[1].dclk_did =
1844
			igp_info->info_7.ucDPMState1DclkFid;
1924
			igp_info->info_7.ucDPMState1DclkFid;
1845
		pi->sys_info.uvd_clock_table_entries[2].dclk_did =
1925
		pi->sys_info.uvd_clock_table_entries[2].dclk_did =
1846
			igp_info->info_7.ucDPMState2DclkFid;
1926
			igp_info->info_7.ucDPMState2DclkFid;
1847
		pi->sys_info.uvd_clock_table_entries[3].dclk_did =
1927
		pi->sys_info.uvd_clock_table_entries[3].dclk_did =
1848
			igp_info->info_7.ucDPMState3DclkFid;
1928
			igp_info->info_7.ucDPMState3DclkFid;
1849
 
1929
 
1850
		for (i = 0; i < 4; i++) {
1930
		for (i = 0; i < 4; i++) {
1851
			pi->sys_info.uvd_clock_table_entries[i].vclk =
1931
			pi->sys_info.uvd_clock_table_entries[i].vclk =
1852
				trinity_convert_did_to_freq(rdev,
1932
				trinity_convert_did_to_freq(rdev,
1853
							    pi->sys_info.uvd_clock_table_entries[i].vclk_did);
1933
							    pi->sys_info.uvd_clock_table_entries[i].vclk_did);
1854
			pi->sys_info.uvd_clock_table_entries[i].dclk =
1934
			pi->sys_info.uvd_clock_table_entries[i].dclk =
1855
				trinity_convert_did_to_freq(rdev,
1935
				trinity_convert_did_to_freq(rdev,
1856
							    pi->sys_info.uvd_clock_table_entries[i].dclk_did);
1936
							    pi->sys_info.uvd_clock_table_entries[i].dclk_did);
1857
		}
1937
		}
1858
 
1938
 
1859
 
1939
 
1860
 
1940
 
1861
	}
1941
	}
1862
	return 0;
1942
	return 0;
1863
}
1943
}
1864
 
1944
 
1865
int trinity_dpm_init(struct radeon_device *rdev)
1945
int trinity_dpm_init(struct radeon_device *rdev)
1866
{
1946
{
1867
	struct trinity_power_info *pi;
1947
	struct trinity_power_info *pi;
1868
	int ret, i;
1948
	int ret, i;
1869
 
1949
 
1870
	pi = kzalloc(sizeof(struct trinity_power_info), GFP_KERNEL);
1950
	pi = kzalloc(sizeof(struct trinity_power_info), GFP_KERNEL);
1871
	if (pi == NULL)
1951
	if (pi == NULL)
1872
		return -ENOMEM;
1952
		return -ENOMEM;
1873
	rdev->pm.dpm.priv = pi;
1953
	rdev->pm.dpm.priv = pi;
1874
 
1954
 
1875
	for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++)
1955
	for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++)
1876
		pi->at[i] = TRINITY_AT_DFLT;
1956
		pi->at[i] = TRINITY_AT_DFLT;
1877
 
1957
 
1878
	if (radeon_bapm == -1) {
1958
	if (radeon_bapm == -1) {
1879
	/* There are stability issues reported on with
1959
		/* There are stability issues reported on with
1880
	 * bapm enabled when switching between AC and battery
1960
		 * bapm enabled when switching between AC and battery
1881
	 * power.  At the same time, some MSI boards hang
1961
		 * power.  At the same time, some MSI boards hang
1882
	 * if it's not enabled and dpm is enabled.  Just enable
1962
		 * if it's not enabled and dpm is enabled.  Just enable
1883
	 * it for MSI boards right now.
1963
		 * it for MSI boards right now.
1884
	 */
1964
		 */
1885
	if (rdev->pdev->subsystem_vendor == 0x1462)
1965
		if (rdev->pdev->subsystem_vendor == 0x1462)
1886
		pi->enable_bapm = true;
1966
			pi->enable_bapm = true;
1887
	else
1967
		else
1888
		pi->enable_bapm = false;
1968
			pi->enable_bapm = false;
1889
	} else if (radeon_bapm == 0) {
1969
	} else if (radeon_bapm == 0) {
1890
		pi->enable_bapm = false;
1970
		pi->enable_bapm = false;
1891
	} else {
1971
	} else {
1892
		pi->enable_bapm = true;
1972
		pi->enable_bapm = true;
1893
	}
1973
	}
1894
	pi->enable_nbps_policy = true;
1974
	pi->enable_nbps_policy = true;
1895
	pi->enable_sclk_ds = true;
1975
	pi->enable_sclk_ds = true;
1896
	pi->enable_gfx_power_gating = true;
1976
	pi->enable_gfx_power_gating = true;
1897
	pi->enable_gfx_clock_gating = true;
1977
	pi->enable_gfx_clock_gating = true;
1898
	pi->enable_mg_clock_gating = false;
1978
	pi->enable_mg_clock_gating = false;
1899
	pi->enable_gfx_dynamic_mgpg = false;
1979
	pi->enable_gfx_dynamic_mgpg = false;
1900
	pi->override_dynamic_mgpg = false;
1980
	pi->override_dynamic_mgpg = false;
1901
	pi->enable_auto_thermal_throttling = true;
1981
	pi->enable_auto_thermal_throttling = true;
1902
	pi->voltage_drop_in_dce = false; /* need to restructure dpm/modeset interaction */
1982
	pi->voltage_drop_in_dce = false; /* need to restructure dpm/modeset interaction */
1903
	pi->uvd_dpm = true; /* ??? */
1983
	pi->uvd_dpm = true; /* ??? */
1904
 
1984
 
1905
	ret = trinity_parse_sys_info_table(rdev);
1985
	ret = trinity_parse_sys_info_table(rdev);
1906
	if (ret)
1986
	if (ret)
1907
		return ret;
1987
		return ret;
1908
 
1988
 
1909
	trinity_construct_boot_state(rdev);
1989
	trinity_construct_boot_state(rdev);
1910
 
1990
 
1911
	ret = r600_get_platform_caps(rdev);
1991
	ret = r600_get_platform_caps(rdev);
1912
	if (ret)
1992
	if (ret)
1913
		return ret;
1993
		return ret;
-
 
1994
 
-
 
1995
	ret = r600_parse_extended_power_table(rdev);
-
 
1996
	if (ret)
-
 
1997
		return ret;
1914
 
1998
 
1915
	ret = trinity_parse_power_table(rdev);
1999
	ret = trinity_parse_power_table(rdev);
1916
	if (ret)
2000
	if (ret)
1917
		return ret;
2001
		return ret;
1918
 
2002
 
1919
	pi->thermal_auto_throttling = pi->sys_info.htc_tmp_lmt;
2003
	pi->thermal_auto_throttling = pi->sys_info.htc_tmp_lmt;
1920
	pi->enable_dpm = true;
2004
	pi->enable_dpm = true;
1921
 
2005
 
1922
	return 0;
2006
	return 0;
1923
}
2007
}
1924
 
2008
 
1925
void trinity_dpm_print_power_state(struct radeon_device *rdev,
2009
void trinity_dpm_print_power_state(struct radeon_device *rdev,
1926
				   struct radeon_ps *rps)
2010
				   struct radeon_ps *rps)
1927
{
2011
{
1928
	int i;
2012
	int i;
1929
	struct trinity_ps *ps = trinity_get_ps(rps);
2013
	struct trinity_ps *ps = trinity_get_ps(rps);
1930
 
2014
 
1931
	r600_dpm_print_class_info(rps->class, rps->class2);
2015
	r600_dpm_print_class_info(rps->class, rps->class2);
1932
	r600_dpm_print_cap_info(rps->caps);
2016
	r600_dpm_print_cap_info(rps->caps);
1933
	printk("\tuvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
2017
	printk("\tuvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
1934
	for (i = 0; i < ps->num_levels; i++) {
2018
	for (i = 0; i < ps->num_levels; i++) {
1935
		struct trinity_pl *pl = &ps->levels[i];
2019
		struct trinity_pl *pl = &ps->levels[i];
1936
		printk("\t\tpower level %d    sclk: %u vddc: %u\n",
2020
		printk("\t\tpower level %d    sclk: %u vddc: %u\n",
1937
		       i, pl->sclk,
2021
		       i, pl->sclk,
1938
		       trinity_convert_voltage_index_to_value(rdev, pl->vddc_index));
2022
		       trinity_convert_voltage_index_to_value(rdev, pl->vddc_index));
1939
	}
2023
	}
1940
	r600_dpm_print_ps_status(rdev, rps);
2024
	r600_dpm_print_ps_status(rdev, rps);
1941
}
2025
}
1942
 
2026
 
1943
void trinity_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
2027
void trinity_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
1944
							 struct seq_file *m)
2028
							 struct seq_file *m)
1945
{
2029
{
1946
	struct trinity_power_info *pi = trinity_get_pi(rdev);
2030
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1947
	struct radeon_ps *rps = &pi->current_rps;
2031
	struct radeon_ps *rps = &pi->current_rps;
1948
	struct trinity_ps *ps = trinity_get_ps(rps);
2032
	struct trinity_ps *ps = trinity_get_ps(rps);
1949
	struct trinity_pl *pl;
2033
	struct trinity_pl *pl;
1950
	u32 current_index =
2034
	u32 current_index =
1951
		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) >>
2035
		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) >>
1952
		CURRENT_STATE_SHIFT;
2036
		CURRENT_STATE_SHIFT;
1953
 
2037
 
1954
	if (current_index >= ps->num_levels) {
2038
	if (current_index >= ps->num_levels) {
1955
		seq_printf(m, "invalid dpm profile %d\n", current_index);
2039
		seq_printf(m, "invalid dpm profile %d\n", current_index);
1956
	} else {
2040
	} else {
1957
		pl = &ps->levels[current_index];
2041
		pl = &ps->levels[current_index];
1958
		seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
2042
		seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
1959
		seq_printf(m, "power level %d    sclk: %u vddc: %u\n",
2043
		seq_printf(m, "power level %d    sclk: %u vddc: %u\n",
1960
			   current_index, pl->sclk,
2044
			   current_index, pl->sclk,
1961
			   trinity_convert_voltage_index_to_value(rdev, pl->vddc_index));
2045
			   trinity_convert_voltage_index_to_value(rdev, pl->vddc_index));
1962
	}
2046
	}
1963
}
2047
}
-
 
2048
 
-
 
2049
u32 trinity_dpm_get_current_sclk(struct radeon_device *rdev)
-
 
2050
{
-
 
2051
	struct trinity_power_info *pi = trinity_get_pi(rdev);
-
 
2052
	struct radeon_ps *rps = &pi->current_rps;
-
 
2053
	struct trinity_ps *ps = trinity_get_ps(rps);
-
 
2054
	struct trinity_pl *pl;
-
 
2055
	u32 current_index =
-
 
2056
		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) >>
-
 
2057
		CURRENT_STATE_SHIFT;
-
 
2058
 
-
 
2059
	if (current_index >= ps->num_levels) {
-
 
2060
		return 0;
-
 
2061
	} else {
-
 
2062
		pl = &ps->levels[current_index];
-
 
2063
		return pl->sclk;
-
 
2064
	}
-
 
2065
}
-
 
2066
 
-
 
2067
u32 trinity_dpm_get_current_mclk(struct radeon_device *rdev)
-
 
2068
{
-
 
2069
	struct trinity_power_info *pi = trinity_get_pi(rdev);
-
 
2070
 
-
 
2071
	return pi->sys_info.bootup_uma_clk;
-
 
2072
}
1964
 
2073
 
1965
void trinity_dpm_fini(struct radeon_device *rdev)
2074
void trinity_dpm_fini(struct radeon_device *rdev)
1966
{
2075
{
1967
	int i;
2076
	int i;
1968
 
2077
 
1969
	trinity_cleanup_asic(rdev); /* ??? */
2078
	trinity_cleanup_asic(rdev); /* ??? */
1970
 
2079
 
1971
	for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
2080
	for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
1972
		kfree(rdev->pm.dpm.ps[i].ps_priv);
2081
		kfree(rdev->pm.dpm.ps[i].ps_priv);
1973
	}
2082
	}
1974
	kfree(rdev->pm.dpm.ps);
2083
	kfree(rdev->pm.dpm.ps);
1975
	kfree(rdev->pm.dpm.priv);
2084
	kfree(rdev->pm.dpm.priv);
-
 
2085
	r600_free_extended_power_table(rdev);
1976
}
2086
}
1977
 
2087
 
1978
u32 trinity_dpm_get_sclk(struct radeon_device *rdev, bool low)
2088
u32 trinity_dpm_get_sclk(struct radeon_device *rdev, bool low)
1979
{
2089
{
1980
	struct trinity_power_info *pi = trinity_get_pi(rdev);
2090
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1981
	struct trinity_ps *requested_state = trinity_get_ps(&pi->requested_rps);
2091
	struct trinity_ps *requested_state = trinity_get_ps(&pi->requested_rps);
1982
 
2092
 
1983
	if (low)
2093
	if (low)
1984
		return requested_state->levels[0].sclk;
2094
		return requested_state->levels[0].sclk;
1985
	else
2095
	else
1986
		return requested_state->levels[requested_state->num_levels - 1].sclk;
2096
		return requested_state->levels[requested_state->num_levels - 1].sclk;
1987
}
2097
}
1988
 
2098
 
1989
u32 trinity_dpm_get_mclk(struct radeon_device *rdev, bool low)
2099
u32 trinity_dpm_get_mclk(struct radeon_device *rdev, bool low)
1990
{
2100
{
1991
	struct trinity_power_info *pi = trinity_get_pi(rdev);
2101
	struct trinity_power_info *pi = trinity_get_pi(rdev);
1992
 
2102
 
1993
	return pi->sys_info.bootup_uma_clk;
2103
	return pi->sys_info.bootup_uma_clk;
1994
}
2104
}
1995
>
2105
>