1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <device/pci_def.h>
5 #include <cpu/x86/msr.h>
6 #include <cpu/intel/speedstep.h>
10 static int sku_freq_index(const gmch_gfx_t sku
, const int low_power_mode
)
27 static void init_freq_scaling(const gmch_gfx_t sku
, const int low_power_mode
)
31 mchbar_clrsetbits32(0x11cc, 0x1f, 0x17);
40 /* No more to be done for the others. */
44 static const u32 voltage_mask
=
45 (0x1f << 24) | (0x1f << 16) | (0x1f << 8) | 0x1f;
46 mchbar_clrsetbits32(0x1120, voltage_mask
, 0x10111213);
47 mchbar_clrsetbits32(0x1124, voltage_mask
, 0x14151617);
48 mchbar_clrsetbits32(0x1128, voltage_mask
, 0x18191a1b);
49 mchbar_clrsetbits32(0x112c, voltage_mask
, 0x1c1d1e1f);
50 mchbar_clrsetbits32(0x1130, voltage_mask
, 0x00010203);
51 mchbar_clrsetbits32(0x1134, voltage_mask
, 0x04050607);
52 mchbar_clrsetbits32(0x1138, voltage_mask
, 0x08090a0b);
53 mchbar_clrsetbits32(0x113c, voltage_mask
, 0x0c0d0e0f);
55 /* Program frequencies. */
56 static const u32 frequencies_from_sku_vco
[][4][8] = {
57 /* GM45/GE45/GS45_perf */ {
58 /* VCO 2666 */ { 0xcd, 0xbc, 0x9b, 0x8a, 0x79, 0x78, 0x67, 0x56 },
59 /* VCO 3200 */ { 0xcd, 0xac, 0x9b, 0x8a, 0x89, 0x78, 0x67, 0x56 },
60 /* VCO 4000 */ { 0xac, 0x9b, 0x9a, 0x89, 0x89, 0x68, 0x56, 0x45 },
61 /* VCO 5333 */ { 0xab, 0x9a, 0x79, 0x68, 0x57, 0x56, 0x45, 0x34 },
63 /* GS45_low_power */ {
64 /* VCO 2666 */ { 0xcd, 0x8a },
65 /* VCO 3200 */ { 0xcd, 0x89 },
66 /* VCO 4000 */ { 0xac, 0x89 },
67 /* VCO 5333 */ { 0xab, 0x68 },
70 /* VCO 2666 */ { 0xcd, 0xcd, 0xbc, 0x9b, 0x79, 0x78, 0x67, 0x56 },
71 /* VCO 3200 */ { 0xde, 0xcd, 0xac, 0x9b, 0x89, 0x78, 0x67, 0x56 },
72 /* VCO 4000 */ { 0xcd, 0xac, 0x9b, 0x9a, 0x89, 0x68, 0x56, 0x45 },
73 /* VCO 5333 */ { 0xac, 0xab, 0x9a, 0x79, 0x68, 0x56, 0x45, 0x34 },
77 /* VCO 3200 */ { 0xef, 0xde, 0xcd, 0xac, 0x89, 0x78, 0x67, 0x56 },
78 /* VCO 4000 */ { 0xef, 0xde, 0xac, 0x9b, 0x89, 0x68, 0x56, 0x45 },
79 /* VCO 5333 */ { 0xce, 0xbd, 0xab, 0x9a, 0x68, 0x57, 0x45, 0x34 },
81 const int sku_index
= sku_freq_index(sku
, low_power_mode
);
82 const int vco_index
= raminit_read_vco_index();
83 const int reg_limit
= low_power_mode
? 1 : 4;
85 mchbar_write8(0x1110 + 3, 0x1b);
87 mchbar_write8(0x1110 + 3, 0x17);
88 mchbar_write8(0x1110 + 1, 0x17);
89 if (!low_power_mode
) {
90 mchbar_write8(0x1114 + 3, 0x17);
91 mchbar_write8(0x1114 + 1, 0x17);
92 mchbar_write8(0x1118 + 3, 0x17);
93 mchbar_write8(0x1118 + 1, 0x17);
94 mchbar_write8(0x111c + 3, 0x17);
95 mchbar_write8(0x111c + 1, 0x17);
97 for (i
= 0; i
< reg_limit
; ++i
) {
98 const int mchbar
= 0x1110 + (i
* 4);
99 mchbar_write8(mchbar
+ 2, frequencies_from_sku_vco
100 [sku_index
][vco_index
][i
* 2 + 0]);
101 mchbar_write8(mchbar
+ 0, frequencies_from_sku_vco
102 [sku_index
][vco_index
][i
* 2 + 1]);
105 if (low_power_mode
) {
106 mchbar_clrsetbits16(0x1190, 7 << 8 | 7 << 4 | 7, 1 << 8 | 1 << 4 | 1);
108 mchbar_clrsetbits16(0x1190, 7 << 8 | 7 << 4, 7);
109 if (sku
== GMCH_GS45
) /* performance mode */
110 mchbar_clrbits32(0x0ffc, 1 << 31);
113 mchbar_setbits16(0x0fc0, 1 << 11);
114 mchbar_write16(0x11b8, 0x333c);
115 mchbar_write16(0x11c0 + 2, 0x0303);
116 mchbar_write32(0x11c4, 0x0a030a03);
117 mchbar_clrsetbits16(0x1100, 0x1f << 8, 3 << 8);
118 mchbar_write16(0x11b8 + 2, 0x4000);
121 void init_pm(const sysinfo_t
*const sysinfo
, int do_freq_scaling_cfg
)
123 const stepping_t stepping
= sysinfo
->stepping
;
124 const fsb_clock_t fsb
= sysinfo
->selected_timings
.fsb_clock
;
125 const mem_clock_t memclk
= sysinfo
->selected_timings
.mem_clock
;
127 mchbar_write16(0xc14, 0);
128 mchbar_write16(0xc20, 0);
129 mchbar_write32(0xfc0, 0x001f00fd);
130 mchbar_setbits32(0xfc0, 3 << 25);
131 mchbar_setbits32(0xfc0, 1 << 11);
132 mchbar_write8(0xfb0, 3);
133 mchbar_setbits8(0xf10, 1 << 1);
134 if (fsb
== FSB_CLOCK_667MHz
) {
135 mchbar_write16(0xc3a, 0x0ea6);
136 mchbar_clrsetbits8(0xc16, 0x7f, 0x0e);
137 } else if (fsb
== FSB_CLOCK_800MHz
) {
138 mchbar_write16(0xc3a, 0x1194);
139 mchbar_clrsetbits8(0xc16, 0x7f, 0x10);
140 } else if (fsb
== FSB_CLOCK_1067MHz
) {
141 mchbar_write16(0xc3a, 0x1777);
142 mchbar_clrsetbits8(0xc16, 0x7f, 0x15);
144 mchbar_write8(0xfb8, 3);
145 if (fsb
== FSB_CLOCK_667MHz
)
146 mchbar_write16(0xc38, 0x0ea6);
147 else if (fsb
== FSB_CLOCK_800MHz
)
148 mchbar_write16(0xc38, 0x1194);
149 else if (fsb
== FSB_CLOCK_1067MHz
)
150 mchbar_write16(0xc38, 0x1777);
151 mchbar_setbits8(0xf10, 1 << 5);
152 mchbar_setbits16(0xc16, 3 << 12);
153 mchbar_write32(0xf60, 0x01030419);
154 if (fsb
== FSB_CLOCK_667MHz
) {
155 mchbar_write32(0xf00, 0x00000600);
156 mchbar_write32(0xf04, 0x00001d80);
157 } else if (fsb
== FSB_CLOCK_800MHz
) {
158 mchbar_write32(0xf00, 0x00000700);
159 mchbar_write32(0xf04, 0x00002380);
160 } else if (fsb
== FSB_CLOCK_1067MHz
) {
161 mchbar_write32(0xf00, 0x00000900);
162 mchbar_write32(0xf04, 0x00002e80);
164 mchbar_write16(0xf08, 0x730f);
165 if (fsb
== FSB_CLOCK_667MHz
)
166 mchbar_write16(0xf0c, 0x0b96);
167 else if (fsb
== FSB_CLOCK_800MHz
)
168 mchbar_write16(0xf0c, 0x0c99);
169 else if (fsb
== FSB_CLOCK_1067MHz
)
170 mchbar_write16(0xf0c, 0x10a4);
171 mchbar_setbits32(0xf80, 1 << 31);
173 mchbar_write32(0x40, (mchbar_read32(0x40) & ~(0x3f << 24)) |
174 ((sysinfo
->cores
== 4) ? (1 << 24) : 0));
176 mchbar_clrbits32(0x40, 1 << 19);
177 mchbar_setbits32(0x40, 1 << 13);
178 mchbar_setbits32(0x40, 1 << 21);
179 mchbar_setbits32(0x40, 1 << 9);
180 if (stepping
> STEPPING_B1
) {
181 if (fsb
!= FSB_CLOCK_1067MHz
) {
182 mchbar_setbits32(0x70, 1 << 30);
184 mchbar_clrbits32(0x70, 1 << 30);
187 if (stepping
< STEPPING_B1
)
188 mchbar_setbits32(0x70, 1 << 29);
190 mchbar_clrbits32(0x70, 1 << 29);
191 if (stepping
> STEPPING_B1
) {
192 mchbar_setbits32(0x70, 1 << 28);
193 mchbar_setbits32(0x70, 1 << 25);
195 if (stepping
> STEPPING_B0
) {
196 if (fsb
!= FSB_CLOCK_667MHz
)
197 mchbar_clrsetbits32(0x70, 3 << 21, 1 << 21);
199 mchbar_clrbits32(0x70, 3 << 21);
201 if (stepping
> STEPPING_B2
)
202 mchbar_setbits32(0x44, 1 << 30);
203 mchbar_setbits32(0x44, 1 << 31);
204 if (sysinfo
->cores
== 2)
205 mchbar_setbits32(0x44, 1 << 26);
206 mchbar_setbits32(0x44, 1 << 21);
207 mchbar_clrsetbits32(0x44, 3 << 24, 2 << 24);
208 mchbar_setbits32(0x44, 1 << 5);
209 mchbar_setbits32(0x44, 1 << 4);
210 mchbar_clrsetbits32(0x90, 7, 4);
211 mchbar_setbits32(0x94, 1 << 29);
212 mchbar_setbits32(0x94, 1 << 11);
213 if (stepping
< STEPPING_B0
)
214 mchbar_clrsetbits32(0x94, 3 << 19, 2 << 19);
215 if (stepping
> STEPPING_B2
)
216 mchbar_setbits32(0x94, 1 << 21);
217 mchbar_clrbits8(0xb00, 1 << 0);
218 mchbar_setbits8(0xb00, 1 << 7);
219 if (fsb
!= FSB_CLOCK_1067MHz
)
220 mchbar_setbits8(0x75, 1 << 6);
222 mchbar_clrbits8(0x75, ~(1 << 1));
223 mchbar_setbits8(0x77, 3);
224 if (stepping
>= STEPPING_B1
)
225 mchbar_setbits8(0x77, 1 << 2);
226 if (stepping
> STEPPING_B2
)
227 mchbar_setbits8(0x77, 1 << 4);
228 if (mchbar_read16(0x90) & (1 << 8))
229 mchbar_clrbits8(0x90, 7 << 4);
230 if (stepping
>= STEPPING_B0
)
231 mchbar_setbits8(0xd0, 1 << 1);
232 mchbar_setbits8(0xbd8, 3 << 2);
233 if (stepping
>= STEPPING_B3
)
234 mchbar_setbits32(0x70, 1 << 0);
235 mchbar_setbits32(0x70, 1 << 3);
236 if (stepping
>= STEPPING_B0
)
237 mchbar_clrbits32(0x70, 1 << 16);
239 mchbar_setbits32(0x70, 1 << 16);
240 if (stepping
>= STEPPING_B3
)
241 mchbar_setbits8(0xc14, 1 << 1);
242 if (stepping
>= STEPPING_B1
)
243 mchbar_clrsetbits16(0xffc, 0x7ff, 0x7c0);
244 mchbar_clrsetbits16(0x48, 0xff << 2, 0xaa << 2);
245 if (stepping
== STEPPING_CONVERSION_A1
) {
246 mchbar_setbits16(0x40, 1 << 12);
247 mchbar_setbits32(0x94, 3 << 22);
250 const int cpu_supports_super_lfm
=
251 rdmsr(MSR_EXTENDED_CONFIG
).lo
& (1 << 27);
252 if ((stepping
>= STEPPING_B0
) && cpu_supports_super_lfm
) {
253 mchbar_clrbits16(CLKCFG_MCHBAR
, 1 << 7);
254 mchbar_setbits16(CLKCFG_MCHBAR
, 1 << 14);
256 mchbar_clrbits16(CLKCFG_MCHBAR
, 1 << 14);
257 mchbar_setbits16(CLKCFG_MCHBAR
, 1 << 7);
258 mchbar_clrbits32(0x44, 1 << 31); /* Was set above. */
261 if ((sysinfo
->gfx_type
!= GMCH_PM45
) && do_freq_scaling_cfg
&&
262 (sysinfo
->gfx_type
!= GMCH_UNKNOWN
))
263 init_freq_scaling(sysinfo
->gfx_type
,
264 sysinfo
->gs45_low_power_mode
);
266 /* This has to be the last write to CLKCFG. */
267 if ((fsb
== FSB_CLOCK_1067MHz
) && (memclk
== MEM_CLOCK_667MT
))
268 mchbar_clrbits32(CLKCFG_MCHBAR
, 1 << 17);