xref: /aosp_15_r20/external/coreboot/src/northbridge/intel/gm45/pm.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <stdint.h>
4 #include <device/pci_def.h>
5 #include <cpu/x86/msr.h>
6 #include <cpu/intel/speedstep.h>
7 
8 #include "gm45.h"
9 
sku_freq_index(const gmch_gfx_t sku,const int low_power_mode)10 static int sku_freq_index(const gmch_gfx_t sku, const int low_power_mode)
11 {
12 	if (low_power_mode)
13 		return 1;
14 	switch (sku) {
15 	case GMCH_GM45:
16 	case GMCH_GE45:
17 	case GMCH_GS45:
18 		return 0;
19 	case GMCH_GM47:
20 		return 2;
21 	case GMCH_GM49:
22 		return 3;
23 	default:
24 		return 0;
25 	}
26 }
init_freq_scaling(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)
28 {
29 	int i;
30 
31 	mchbar_clrsetbits32(0x11cc, 0x1f, 0x17);
32 	switch (sku) {
33 	case GMCH_GM45:
34 	case GMCH_GE45:
35 	case GMCH_GS45:
36 	case GMCH_GM47:
37 	case GMCH_GM49:
38 		break;
39 	default:
40 		/* No more to be done for the others. */
41 		return;
42 	}
43 
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);
54 
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 },
62 	},
63 	/* GS45_low_power */ {
64 	    /* VCO 2666 */ { 0xcd, 0x8a },
65 	    /* VCO 3200 */ { 0xcd, 0x89 },
66 	    /* VCO 4000 */ { 0xac, 0x89 },
67 	    /* VCO 5333 */ { 0xab, 0x68 },
68 	},
69 	/* GM47 */ {
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 },
74 	},
75 	/* GM49 */ {
76 	    /* VCO 2666 */ { },
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 },
80 	}};
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;
84 	if (sku == GMCH_GM49)
85 		mchbar_write8(0x1110 + 3, 0x1b);
86 	else
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);
96 	}
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]);
103 	}
104 
105 	if (low_power_mode) {
106 		mchbar_clrsetbits16(0x1190, 7 << 8 | 7 << 4 | 7, 1 << 8 | 1 << 4 | 1);
107 	} else {
108 		mchbar_clrsetbits16(0x1190, 7 << 8 | 7 << 4, 7);
109 		if (sku == GMCH_GS45) /* performance mode */
110 			mchbar_clrbits32(0x0ffc, 1 << 31);
111 	}
112 
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);
119 }
120 
init_pm(const sysinfo_t * const sysinfo,int do_freq_scaling_cfg)121 void init_pm(const sysinfo_t *const sysinfo, int do_freq_scaling_cfg)
122 {
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;
126 
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);
143 	}
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);
163 	}
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);
172 
173 	mchbar_write32(0x40, (mchbar_read32(0x40) & ~(0x3f << 24)) |
174 		       ((sysinfo->cores == 4) ? (1 << 24) : 0));
175 
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);
183 		} else {
184 			mchbar_clrbits32(0x70, 1 << 30);
185 		}
186 	}
187 	if (stepping < STEPPING_B1)
188 		mchbar_setbits32(0x70, 1 << 29);
189 	else
190 		mchbar_clrbits32(0x70, 1 << 29);
191 	if (stepping > STEPPING_B1) {
192 		mchbar_setbits32(0x70, 1 << 28);
193 		mchbar_setbits32(0x70, 1 << 25);
194 	}
195 	if (stepping > STEPPING_B0) {
196 		if (fsb != FSB_CLOCK_667MHz)
197 			mchbar_clrsetbits32(0x70, 3 << 21, 1 << 21);
198 		else
199 			mchbar_clrbits32(0x70, 3 << 21);
200 	}
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);
221 	else
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);
238 	else
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);
248 	}
249 
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);
255 	} else {
256 		mchbar_clrbits16(CLKCFG_MCHBAR, 1 << 14);
257 		mchbar_setbits16(CLKCFG_MCHBAR, 1 << 7);
258 		mchbar_clrbits32(0x44, 1 << 31); /* Was set above. */
259 	}
260 
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);
265 
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);
269 }
270