1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <commonlib/bsd/gcd.h>
4 #include <console/console.h>
5 #include <cpu/intel/model_2065x/model_2065x.h>
6 #include <cpu/x86/msr.h>
8 #include <device/pci_def.h>
9 #include <device/pci_ops.h>
10 #include <northbridge/intel/ironlake/raminit.h>
13 #define NORTHBRIDGE PCI_DEV(0, 0, 0)
15 static inline int div_roundup(int a
, int b
)
17 return DIV_ROUND_UP(a
, b
);
20 static u32
lcm(u32 a
, u32 b
)
22 return (a
* b
) / gcd(a
, b
);
29 u8 divisor_f4_to_fmax
;
30 u8 divisor_f3_to_fmax
;
31 u8 freq4_to_max_remainder
;
32 u8 freq3_to_2_remainder
;
33 u8 freq3_to_2_remaindera
;
34 u8 freq4_to_2_remainder
;
35 int divisor_f3_to_f1
, divisor_f4_to_f2
;
36 int common_time_unit_ps
;
41 compute_frequence_ratios(struct raminfo
*info
, u16 freq1
, u16 freq2
,
42 int num_cycles_2
, int num_cycles_1
, int round_it
,
43 int add_freqs
, struct stru1
*result
)
46 int common_time_unit_ps
;
47 int freq1_reduced
, freq2_reduced
;
52 g
= gcd(freq1
, freq2
);
53 freq1_reduced
= freq1
/ g
;
54 freq2_reduced
= freq2
/ g
;
55 freq_min_reduced
= MIN(freq1_reduced
, freq2_reduced
);
56 freq_max_reduced
= MAX(freq1_reduced
, freq2_reduced
);
58 common_time_unit_ps
= div_roundup(900000, lcm(freq1
, freq2
));
59 freq3
= div_roundup(num_cycles_2
, common_time_unit_ps
) - 1;
60 freq4
= div_roundup(num_cycles_1
, common_time_unit_ps
) - 1;
62 freq3
+= freq2_reduced
;
63 freq4
+= freq1_reduced
;
67 result
->freq3_to_2_remainder
= 0;
68 result
->freq3_to_2_remaindera
= 0;
69 result
->freq4_to_max_remainder
= 0;
70 result
->divisor_f4_to_f2
= 0;
71 result
->divisor_f3_to_f1
= 0;
73 if (freq2_reduced
< freq1_reduced
) {
74 result
->freq3_to_2_remainder
=
75 result
->freq3_to_2_remaindera
=
76 freq3
% freq1_reduced
- freq1_reduced
+ 1;
77 result
->freq4_to_max_remainder
=
78 -(freq4
% freq1_reduced
);
79 result
->divisor_f3_to_f1
= freq3
/ freq1_reduced
;
80 result
->divisor_f4_to_f2
=
82 (freq1_reduced
- freq2_reduced
)) / freq2_reduced
;
83 result
->freq4_to_2_remainder
=
84 -(char)((freq1_reduced
- freq2_reduced
) +
87 freq2_reduced
)) % (u8
)freq2_reduced
);
89 if (freq2_reduced
> freq1_reduced
) {
90 result
->freq4_to_max_remainder
=
91 (freq4
% freq2_reduced
) - freq2_reduced
+ 1;
92 result
->freq4_to_2_remainder
=
93 freq4
% freq_max_reduced
-
96 result
->freq4_to_max_remainder
=
97 -(freq4
% freq2_reduced
);
98 result
->freq4_to_2_remainder
=
99 -(char)(freq4
% freq_max_reduced
);
101 result
->divisor_f4_to_f2
= freq4
/ freq2_reduced
;
102 result
->divisor_f3_to_f1
=
104 (freq2_reduced
- freq1_reduced
)) / freq1_reduced
;
105 result
->freq3_to_2_remainder
= -(freq3
% freq2_reduced
);
106 result
->freq3_to_2_remaindera
=
107 -(char)((freq_max_reduced
- freq_min_reduced
) +
110 freq_min_reduced
)) % freq1_reduced
);
113 result
->divisor_f3_to_fmax
= freq3
/ freq_max_reduced
;
114 result
->divisor_f4_to_fmax
= freq4
/ freq_max_reduced
;
116 if (freq2_reduced
> freq1_reduced
) {
117 if (freq3
% freq_max_reduced
)
118 result
->divisor_f3_to_fmax
++;
120 if (freq2_reduced
< freq1_reduced
) {
121 if (freq4
% freq_max_reduced
)
122 result
->divisor_f4_to_fmax
++;
125 result
->freqs_reversed
= (freq2_reduced
< freq1_reduced
);
126 result
->freq_diff_reduced
= freq_max_reduced
- freq_min_reduced
;
127 result
->freq_min_reduced
= freq_min_reduced
;
128 result
->common_time_unit_ps
= common_time_unit_ps
;
129 result
->freq_max_reduced
= freq_max_reduced
;
132 static void compute_274265(struct raminfo
*info
)
134 int delay_a_ps
, delay_b_ps
, delay_c_ps
, delay_d_ps
;
135 int delay_e_ps
, delay_e_cycles
, delay_f_cycles
;
136 int delay_e_over_cycle_ps
;
140 delay_a_ps
= 4 * halfcycle_ps(info
) + 6 * fsbcycle_ps(info
);
141 info
->training
.reg2ca9_bit0
= 0;
142 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
144 900000 / lcm(2 * info
->fsb_frequency
, frequency_11(info
));
146 (halfcycle_ps(info
) * get_max_timing(info
, channel
) >> 6)
147 - info
->some_delay_3_ps_rounded
+ 200;
149 ((info
->silicon_revision
== 0
150 || info
->silicon_revision
== 1)
151 && (info
->revision
>= 8)))
152 delay_d_ps
+= halfcycle_ps(info
) * 2;
154 halfcycle_ps(info
) * (!info
->revision_flag_1
+
155 info
->some_delay_2_halfcycles_ceil
+
156 2 * info
->some_delay_1_cycle_floor
+
157 info
->clock_speed_index
+
158 2 * info
->cas_latency
- 7 + 11);
159 delay_d_ps
+= info
->revision
>= 8 ? 2758 : 4428;
161 mchbar_clrsetbits32(0x140, 7 << 24, 2 << 24);
162 mchbar_clrsetbits32(0x138, 7 << 24, 2 << 24);
163 if ((mchbar_read8(0x144) & 0x1f) > 0x13)
165 delay_c_ps
= delay_d_ps
+ 1800;
166 if (delay_c_ps
<= delay_a_ps
)
170 cycletime_ps
* div_roundup(delay_c_ps
- delay_a_ps
,
173 delay_e_over_cycle_ps
= delay_e_ps
% (2 * halfcycle_ps(info
));
174 delay_e_cycles
= delay_e_ps
/ (2 * halfcycle_ps(info
));
176 div_roundup(2500 - delay_e_over_cycle_ps
,
177 2 * halfcycle_ps(info
));
178 if (delay_f_cycles
> delay_e_cycles
) {
179 info
->delay46_ps
[channel
] = delay_e_ps
;
182 info
->delay46_ps
[channel
] =
183 delay_e_over_cycle_ps
+
184 2 * halfcycle_ps(info
) * delay_f_cycles
;
185 delay_e_cycles
-= delay_f_cycles
;
188 if (info
->delay46_ps
[channel
] < 2500) {
189 info
->delay46_ps
[channel
] = 2500;
190 info
->training
.reg2ca9_bit0
= 1;
192 delay_b_ps
= halfcycle_ps(info
) + delay_c_ps
;
193 if (delay_b_ps
<= delay_a_ps
)
196 delay_b_ps
-= delay_a_ps
;
197 info
->delay54_ps
[channel
] =
198 cycletime_ps
* div_roundup(delay_b_ps
,
200 2 * halfcycle_ps(info
) * delay_e_cycles
;
201 if (info
->delay54_ps
[channel
] < 2500)
202 info
->delay54_ps
[channel
] = 2500;
203 info
->training
.reg274265
[channel
][0] = delay_e_cycles
;
204 if (delay_d_ps
+ 7 * halfcycle_ps(info
) <=
205 24 * halfcycle_ps(info
))
206 info
->training
.reg274265
[channel
][1] = 0;
208 info
->training
.reg274265
[channel
][1] =
209 div_roundup(delay_d_ps
+ 7 * halfcycle_ps(info
),
210 4 * halfcycle_ps(info
)) - 6;
211 info
->training
.reg274265
[channel
][2] =
212 div_roundup(delay_c_ps
+ 3 * fsbcycle_ps(info
),
213 4 * halfcycle_ps(info
)) + 1;
217 static void program_274265(const struct ram_training
*const training
)
221 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
222 mchbar_write32((channel
<< 10) + 0x274,
223 (training
->reg274265
[channel
][0] << 16) |
224 training
->reg274265
[channel
][1]);
225 mchbar_write16((channel
<< 10) + 0x265,
226 training
->reg274265
[channel
][2] << 8);
228 if (training
->reg2ca9_bit0
)
229 mchbar_setbits8(0x2ca9, 1 << 0);
231 mchbar_clrbits8(0x2ca9, 1 << 0);
233 printk(RAM_SPEW
, "reg2ca9_bit0 = %x\n", training
->reg2ca9_bit0
);
235 for (int i
= 0; i
< 2; i
++)
236 for (int j
= 0; j
< 3; j
++)
237 printk(RAM_SPEW
, "reg274265[%d][%d] = %x\n",
238 i
, j
, training
->reg274265
[i
][j
]);
242 set_2d5x_reg(struct raminfo
*info
, u16 reg
, u16 freq1
, u16 freq2
,
243 int num_cycles_2
, int num_cycles_1
, int num_cycles_3
,
244 int num_cycles_4
, int reverse
)
249 compute_frequence_ratios(info
, freq1
, freq2
, num_cycles_2
, num_cycles_1
,
254 (div_roundup(num_cycles_2
, vv
.common_time_unit_ps
) +
255 div_roundup(num_cycles_3
, vv
.common_time_unit_ps
),
256 div_roundup(num_cycles_1
,
257 vv
.common_time_unit_ps
) +
258 div_roundup(num_cycles_4
, vv
.common_time_unit_ps
))
259 + vv
.freq_min_reduced
- 1, vv
.freq_max_reduced
) - 1;
262 (u8
)((vv
.freq_max_reduced
- vv
.freq_min_reduced
) +
263 vv
.freq_max_reduced
* multiplier
)
265 freqs_reversed
<< 8) | ((u8
)(vv
.freq_min_reduced
*
266 multiplier
) << 16) | ((u8
)(vv
.
272 vv
.freq3_to_2_remaindera
| (vv
.freq4_to_2_remainder
<< 8) | (vv
.
275 | (vv
.divisor_f4_to_f2
<< 20) | (vv
.freq_min_reduced
<< 24);
277 mchbar_write32(reg
+ 0, y
);
278 mchbar_write32(reg
+ 4, x
);
280 mchbar_write32(reg
+ 4, y
);
281 mchbar_write32(reg
+ 0, x
);
286 set_6d_reg(struct raminfo
*info
, u16 reg
, u16 freq1
, u16 freq2
,
287 int num_cycles_1
, int num_cycles_2
, int num_cycles_3
,
290 struct stru1 ratios1
;
291 struct stru1 ratios2
;
293 compute_frequence_ratios(info
, freq1
, freq2
, num_cycles_1
, num_cycles_2
,
295 compute_frequence_ratios(info
, freq1
, freq2
, num_cycles_3
, num_cycles_4
,
297 printk(RAM_SPEW
, "[%x] <= %x\n", reg
,
298 ratios1
.freq4_to_max_remainder
| (ratios2
.
299 freq4_to_max_remainder
301 | (ratios1
.divisor_f4_to_fmax
<< 16) | (ratios2
.
304 mchbar_write32(reg
, ratios1
.freq4_to_max_remainder
|
305 ratios2
.freq4_to_max_remainder
<< 8 |
306 ratios1
.divisor_f4_to_fmax
<< 16 |
307 ratios2
.divisor_f4_to_fmax
<< 20);
311 set_2dx8_reg(struct raminfo
*info
, u16 reg
, u8 mode
, u16 freq1
, u16 freq2
,
312 int num_cycles_2
, int num_cycles_1
, int round_it
, int add_freqs
)
316 compute_frequence_ratios(info
, freq1
, freq2
, num_cycles_2
, num_cycles_1
,
317 round_it
, add_freqs
, &ratios
);
320 mchbar_write32(reg
+ 4,
321 ratios
.freq_diff_reduced
|
322 ratios
.freqs_reversed
<< 8);
324 ratios
.freq3_to_2_remainder
|
325 ratios
.freq4_to_max_remainder
<< 8 |
326 ratios
.divisor_f3_to_fmax
<< 16 |
327 ratios
.divisor_f4_to_fmax
<< 20 |
328 ratios
.freq_min_reduced
<< 24);
333 ratios
.freq3_to_2_remainder
|
334 ratios
.divisor_f3_to_fmax
<< 16);
339 ratios
.freq3_to_2_remainder
|
340 ratios
.freq4_to_max_remainder
<< 8 |
341 ratios
.divisor_f3_to_fmax
<< 16 |
342 ratios
.divisor_f4_to_fmax
<< 20);
347 ratios
.divisor_f3_to_fmax
<< 4 |
348 ratios
.divisor_f4_to_fmax
<< 8 |
349 ratios
.freqs_reversed
<< 12 |
350 ratios
.freq_min_reduced
<< 16 |
351 ratios
.freq_diff_reduced
<< 24);
356 static void set_2dxx_series(struct raminfo
*info
, int s3resume
)
358 set_2dx8_reg(info
, 0x2d00, 0, 0x78, frequency_11(info
) / 2, 1359, 1005,
360 set_2dx8_reg(info
, 0x2d08, 0, 0x78, 0x78, 3273, 5033, 1, 1);
361 set_2dx8_reg(info
, 0x2d10, 0, 0x78, info
->fsb_frequency
, 1475, 1131, 0,
363 set_2dx8_reg(info
, 0x2d18, 0, 2 * info
->fsb_frequency
,
364 frequency_11(info
), 1231, 1524, 0, 1);
365 set_2dx8_reg(info
, 0x2d20, 0, 2 * info
->fsb_frequency
,
366 frequency_11(info
) / 2, 1278, 2008, 0, 1);
367 set_2dx8_reg(info
, 0x2d28, 0, info
->fsb_frequency
, frequency_11(info
),
369 set_2dx8_reg(info
, 0x2d30, 0, info
->fsb_frequency
,
370 frequency_11(info
) / 2, 1403, 1318, 0, 1);
371 set_2dx8_reg(info
, 0x2d38, 0, info
->fsb_frequency
, 0x78, 3460, 5363, 1,
373 set_2dx8_reg(info
, 0x2d40, 0, info
->fsb_frequency
, 0x3c, 2792, 5178, 1,
375 set_2dx8_reg(info
, 0x2d48, 0, 2 * info
->fsb_frequency
, 0x78, 2738, 4610,
377 set_2dx8_reg(info
, 0x2d50, 0, info
->fsb_frequency
, 0x78, 2819, 5932, 1,
379 set_2dx8_reg(info
, 0x6d4, 1, info
->fsb_frequency
,
380 frequency_11(info
) / 2, 4000, 0, 0, 0);
381 set_2dx8_reg(info
, 0x6d8, 2, info
->fsb_frequency
,
382 frequency_11(info
) / 2, 4000, 4000, 0, 0);
385 printk(RAM_SPEW
, "[6dc] <= %x\n",
386 info
->cached_training
->reg_6dc
);
387 mchbar_write32(0x6dc, info
->cached_training
->reg_6dc
);
389 set_6d_reg(info
, 0x6dc, 2 * info
->fsb_frequency
, frequency_11(info
), 0,
390 info
->delay46_ps
[0], 0,
391 info
->delay54_ps
[0]);
392 set_2dx8_reg(info
, 0x6e0, 1, 2 * info
->fsb_frequency
,
393 frequency_11(info
), 2500, 0, 0, 0);
394 set_2dx8_reg(info
, 0x6e4, 1, 2 * info
->fsb_frequency
,
395 frequency_11(info
) / 2, 3500, 0, 0, 0);
397 printk(RAM_SPEW
, "[6e8] <= %x\n",
398 info
->cached_training
->reg_6e8
);
399 mchbar_write32(0x6e8, info
->cached_training
->reg_6e8
);
401 set_6d_reg(info
, 0x6e8, 2 * info
->fsb_frequency
, frequency_11(info
), 0,
402 info
->delay46_ps
[1], 0,
403 info
->delay54_ps
[1]);
404 set_2d5x_reg(info
, 0x2d58, 0x78, 0x78, 864, 1195, 762, 786, 0);
405 set_2d5x_reg(info
, 0x2d60, 0x195, info
->fsb_frequency
, 1352, 725, 455,
407 set_2d5x_reg(info
, 0x2d68, 0x195, 0x3c, 2707, 5632, 3277, 2207, 0);
408 set_2d5x_reg(info
, 0x2d70, 0x195, frequency_11(info
) / 2, 1276, 758,
410 set_2d5x_reg(info
, 0x2d78, 0x195, 0x78, 1021, 799, 510, 513, 0);
411 set_2d5x_reg(info
, 0x2d80, info
->fsb_frequency
, 0xe1, 0, 2862, 2579,
413 set_2d5x_reg(info
, 0x2d88, info
->fsb_frequency
, 0xe1, 0, 2690, 2405,
415 set_2d5x_reg(info
, 0x2da0, 0x78, 0xe1, 0, 2560, 2264, 2251, 0);
416 set_2d5x_reg(info
, 0x2da8, 0x195, frequency_11(info
), 1060, 775, 484,
418 set_2d5x_reg(info
, 0x2db0, 0x195, 0x78, 4183, 6023, 2217, 2048, 0);
419 mchbar_write32(0x2dbc, ((frequency_11(info
) / 2) - 1) | 0xe00000);
420 mchbar_write32(0x2db8, (info
->fsb_frequency
- 1) << 16 | 0x77);
423 static u16
quickpath_configure_pll_ratio(struct raminfo
*info
, const u8 x2ca8
)
425 mchbar_setbits32(0x18b4, 1 << 21 | 1 << 16);
426 mchbar_setbits32(0x1890, 1 << 25);
427 mchbar_setbits32(0x18b4, 1 << 15);
429 /* Get maximum supported PLL ratio */
430 u16 qpi_pll_ratio
= (pci_read_config32(QPI_PHY_0
, QPI_PLL_STATUS
) >> 24 & 0x7f);
432 /* Adjust value if invalid */
433 if (qpi_pll_ratio
== 0 || qpi_pll_ratio
> 40)
436 if (qpi_pll_ratio
== 16)
439 while (qpi_pll_ratio
>= 12) {
440 if (qpi_pll_ratio
<= (info
->clock_speed_index
+ 3) * 8)
446 /* Finally, program the ratio */
447 pci_write_config8(QPI_PHY_0
, QPI_PLL_RATIO
, qpi_pll_ratio
);
449 const u16 csipll0
= mchbar_read16(0x2c10);
450 mchbar_write16(0x2c10, (qpi_pll_ratio
> 26) << 11 | 1 << 10 | qpi_pll_ratio
);
452 if (csipll0
!= mchbar_read16(0x2c10) && x2ca8
== 0)
453 mchbar_setbits8(0x2ca8, 1 << 0);
455 mchbar_setbits16(0x2c12, 1 << 8);
457 return qpi_pll_ratio
;
460 void early_quickpath_init(struct raminfo
*info
, const u8 x2ca8
)
465 /* Initialize DDR MPLL first */
467 mchbar_clrsetbits8(0x164, 0x26, info
->clock_speed_index
== 0 ? 0x24 : 0x26);
469 /* Program DDR MPLL feedback divider ratio */
470 mchbar_write16(0x2c20, (info
->clock_speed_index
+ 3) * 4);
473 const u16 qpi_pll_ratio
= quickpath_configure_pll_ratio(info
, x2ca8
);
475 mchbar_clrsetbits32(0x1804, 0x3, 0x8400080);
476 pci_update_config32(QPI_PHY_0
, QPI_PHY_CONTROL
, 0xfffffffc, 0x400080);
478 const u32 x1c04
= mchbar_read32(0x1c04) & 0xc01080;
479 const u32 x1804
= mchbar_read32(0x1804) & 0xc01080;
481 if (x1c04
!= x1804
&& x2ca8
== 0)
482 mchbar_setbits8(0x2ca8, 1 << 0);
485 if (info
->revision
>= 0x18 && qpi_pll_ratio
<= 12) {
486 /* Get TDP limit in 1/8W units */
487 const msr_t msr
= rdmsr(MSR_TURBO_POWER_CURRENT_LIMIT
);
488 if ((msr
.lo
& 0x7fff) <= 90)
491 mchbar_write32(0x18d8, 0x120000);
492 mchbar_write32(0x18dc, reg32
| 0xa484a);
494 reg32
= qpi_pll_ratio
> 20 ? 8 : 16;
495 pci_write_config32(QPI_PHY_0
, QPI_PHY_EP_SELECT
, 0x0);
496 pci_write_config32(QPI_PHY_0
, QPI_PHY_EP_MCTR
, 0x9404a | reg32
<< 7);
498 mchbar_write32(0x18d8, 0x40000);
499 mchbar_write32(0x18dc, 0xb000000);
500 pci_write_config32(QPI_PHY_0
, QPI_PHY_EP_SELECT
, 0x60000);
501 pci_write_config32(QPI_PHY_0
, QPI_PHY_EP_MCTR
, 0x0);
502 mchbar_write32(0x18d8, 0x180000);
503 mchbar_write32(0x18dc, 0xc0000142);
504 pci_write_config32(QPI_PHY_0
, QPI_PHY_EP_SELECT
, 0x20000);
505 pci_write_config32(QPI_PHY_0
, QPI_PHY_EP_MCTR
, 0x142);
506 mchbar_write32(0x18d8, 0x1e0000);
508 const u32 x18dc
= mchbar_read32(0x18dc);
509 mchbar_write32(0x18dc, qpi_pll_ratio
< 18 ? 2 : 3);
511 if (x18dc
!= mchbar_read32(0x18dc) && x2ca8
== 0)
512 mchbar_setbits8(0x2ca8, 1 << 0);
514 reg8
= qpi_pll_ratio
> 20 ? 10 : 9;
516 mchbar_write32(0x188c, 0x20bc00 | reg8
);
517 pci_write_config32(QPI_PHY_0
, QPI_PHY_PWR_MGMT
, 0x40b0c00 | reg8
);
519 if (qpi_pll_ratio
<= 14)
521 else if (qpi_pll_ratio
<= 22)
526 info
->fsb_frequency
= qpi_pll_ratio
* 15;
527 mchbar_write32(0x1a10, reg8
<< 24 | info
->fsb_frequency
);
529 if (info
->silicon_revision
== 2 || info
->silicon_revision
== 3) {
530 mchbar_setbits32(0x18b8, 0x200);
531 mchbar_setbits32(0x1918, 0x300);
534 if (info
->revision
> 0x17)
535 mchbar_setbits32(0x18b8, 0xc00);
537 reg32
= ((qpi_pll_ratio
> 20) + 1) << 16;
539 mchbar_clrsetbits32(0x182c, ~0xfff0f0ff, reg32
| 0x200);
540 pci_update_config32(QPI_PHY_0
, QPI_PHY_PRIM_TIMEOUT
, 0xfff0f0ff, reg32
| 0x200);
541 mchbar_clrbits32(0x1a1c, 7 << 28);
542 mchbar_setbits32(0x1a70, 1 << 20);
544 mchbar_clrbits32(0x18b4, 1 << 15);
545 mchbar_clrsetbits32(0x1a68, 0x00143fc0, 0x143800);
547 const u32 x1e68
= mchbar_read32(0x1e68) & 0x143fc0;
548 const u32 x1a68
= mchbar_read32(0x1a68) & 0x143fc0;
550 if (x1e68
!= x1a68
&& x2ca8
== 0)
551 mchbar_setbits8(0x2ca8, 1 << 0);
553 pci_update_config32(QPI_LINK_0
, QPI_QPILCL
, 0xffffff3f, 0x140000);
555 reg32
= pci_read_config32(QPI_LINK_0
, QPI_DEF_RMT_VN_CREDITS
);
556 pci_write_config32(QPI_LINK_0
, QPI_DEF_RMT_VN_CREDITS
, (reg32
& 0xfffe4555) | 0x64555);
558 if (reg32
!= pci_read_config32(QPI_LINK_0
, QPI_DEF_RMT_VN_CREDITS
) && x2ca8
== 0)
559 mchbar_setbits8(0x2ca8, 1 << 0);
561 pci_update_config32(QPI_NON_CORE
, MIRROR_PORT_CTL
, ~3, 0x80 * 3);
563 reg32
= mchbar_read32(0x1af0);
564 mchbar_write32(0x1af0, (reg32
& 0xfdffcf) | 0x1f020000);
566 if (reg32
!= mchbar_read32(0x1af0) && x2ca8
== 0)
567 mchbar_setbits8(0x2ca8, 1 << 0);
569 mchbar_clrbits32(0x1890, 1 << 25);
570 mchbar_clrsetbits32(0x18b4, 0xf << 12, 0x6 << 12);
571 mchbar_write32(0x18a4, 0x22222222);
572 mchbar_write32(0x18a8, 0x22222222);
573 mchbar_write32(0x18ac, 0x22222);
576 void late_quickpath_init(struct raminfo
*info
, const int s3resume
)
578 const u16 deven
= pci_read_config16(NORTHBRIDGE
, DEVEN
);
580 if (s3resume
&& info
->cached_training
) {
581 program_274265(info
->cached_training
);
583 compute_274265(info
);
584 program_274265(&info
->training
);
587 set_2dxx_series(info
, s3resume
);
590 mchbar_clrsetbits32(0x2cb0, ~0, 0x40);
596 mchbar_setbits32(0xff8, 3 << 11);
597 mchbar_clrbits32(0x2cb0, ~0);
598 pci_read_config8(PCI_DEV(0, 0x2, 0x0), 0x4c);
599 pci_read_config8(PCI_DEV(0, 0x2, 0x0), 0x4c);
600 pci_read_config8(PCI_DEV(0, 0x2, 0x0), 0x4e);
602 mchbar_read8(0x1150);
603 mchbar_read8(0x1151);
604 mchbar_read8(0x1022);
605 mchbar_read8(0x16d0);
606 mchbar_write32(0x1300, 0x60606060);
607 mchbar_write32(0x1304, 0x60606060);
608 mchbar_write32(0x1308, 0x78797a7b);
609 mchbar_write32(0x130c, 0x7c7d7e7f);
610 mchbar_write32(0x1310, 0x60606060);
611 mchbar_write32(0x1314, 0x60606060);
612 mchbar_write32(0x1318, 0x60606060);
613 mchbar_write32(0x131c, 0x60606060);
614 mchbar_write32(0x1320, 0x50515253);
615 mchbar_write32(0x1324, 0x54555657);
616 mchbar_write32(0x1328, 0x58595a5b);
617 mchbar_write32(0x132c, 0x5c5d5e5f);
618 mchbar_write32(0x1330, 0x40414243);
619 mchbar_write32(0x1334, 0x44454647);
620 mchbar_write32(0x1338, 0x48494a4b);
621 mchbar_write32(0x133c, 0x4c4d4e4f);
622 mchbar_write32(0x1340, 0x30313233);
623 mchbar_write32(0x1344, 0x34353637);
624 mchbar_write32(0x1348, 0x38393a3b);
625 mchbar_write32(0x134c, 0x3c3d3e3f);
626 mchbar_write32(0x1350, 0x20212223);
627 mchbar_write32(0x1354, 0x24252627);
628 mchbar_write32(0x1358, 0x28292a2b);
629 mchbar_write32(0x135c, 0x2c2d2e2f);
630 mchbar_write32(0x1360, 0x10111213);
631 mchbar_write32(0x1364, 0x14151617);
632 mchbar_write32(0x1368, 0x18191a1b);
633 mchbar_write32(0x136c, 0x1c1d1e1f);
634 mchbar_write32(0x1370, 0x10203);
635 mchbar_write32(0x1374, 0x4050607);
636 mchbar_write32(0x1378, 0x8090a0b);
637 mchbar_write32(0x137c, 0xc0d0e0f);
638 mchbar_write8(0x11cc, 0x4e);
639 mchbar_write32(0x1110, 0x73970404);
640 mchbar_write32(0x1114, 0x72960404);
641 mchbar_write32(0x1118, 0x6f950404);
642 mchbar_write32(0x111c, 0x6d940404);
643 mchbar_write32(0x1120, 0x6a930404);
644 mchbar_write32(0x1124, 0x68a41404);
645 mchbar_write32(0x1128, 0x66a21404);
646 mchbar_write32(0x112c, 0x63a01404);
647 mchbar_write32(0x1130, 0x609e1404);
648 mchbar_write32(0x1134, 0x5f9c1404);
649 mchbar_write32(0x1138, 0x5c961404);
650 mchbar_write32(0x113c, 0x58a02404);
651 mchbar_write32(0x1140, 0x54942404);
652 mchbar_write32(0x1190, 0x900080a);
653 mchbar_write16(0x11c0, 0xc40b);
654 mchbar_write16(0x11c2, 0x303);
655 mchbar_write16(0x11c4, 0x301);
656 mchbar_clrsetbits32(0x1190, ~0, 0x8900080a);
657 mchbar_write32(0x11b8, 0x70c3000);
658 mchbar_write8(0x11ec, 0xa);
659 mchbar_write16(0x1100, 0x800);
660 mchbar_clrsetbits32(0x11bc, ~0, 0x1e84800);
661 mchbar_write16(0x11ca, 0xfa);
662 mchbar_write32(0x11e4, 0x4e20);
663 mchbar_write8(0x11bc, 0xf);
664 mchbar_write16(0x11da, 0x19);
665 mchbar_write16(0x11ba, 0x470c);
666 mchbar_write32(0x1680, 0xe6ffe4ff);
667 mchbar_write32(0x1684, 0xdeffdaff);
668 mchbar_write32(0x1688, 0xd4ffd0ff);
669 mchbar_write32(0x168c, 0xccffc6ff);
670 mchbar_write32(0x1690, 0xc0ffbeff);
671 mchbar_write32(0x1694, 0xb8ffb0ff);
672 mchbar_write32(0x1698, 0xa8ff0000);
673 mchbar_write32(0x169c, 0xc00);
674 mchbar_write32(0x1290, 0x5000000);
677 mchbar_write32(0x124c, 0x15040d00);
678 mchbar_write32(0x1250, 0x7f0000);
679 mchbar_write32(0x1254, 0x1e220004);
680 mchbar_write32(0x1258, 0x4000004);
681 mchbar_write32(0x1278, 0x0);
682 mchbar_write32(0x125c, 0x0);
683 mchbar_write32(0x1260, 0x0);
684 mchbar_write32(0x1264, 0x0);
685 mchbar_write32(0x1268, 0x0);
686 mchbar_write32(0x126c, 0x0);
687 mchbar_write32(0x1270, 0x0);
688 mchbar_write32(0x1274, 0x0);
691 mchbar_write16(0x1214, 0x320);
692 mchbar_write32(0x1600, 0x40000000);
693 mchbar_clrsetbits32(0x11f4, ~0, 1 << 28);
694 mchbar_clrsetbits16(0x1230, ~0, 1 << 15);
695 mchbar_write32(0x1400, 0x13040020);
696 mchbar_write32(0x1404, 0xe090120);
697 mchbar_write32(0x1408, 0x5120220);
698 mchbar_write32(0x140c, 0x5120330);
699 mchbar_write32(0x1410, 0xe090220);
700 mchbar_write32(0x1414, 0x1010001);
701 mchbar_write32(0x1418, 0x1110000);
702 mchbar_write32(0x141c, 0x9020020);
703 mchbar_write32(0x1420, 0xd090220);
704 mchbar_write32(0x1424, 0x2090220);
705 mchbar_write32(0x1428, 0x2090330);
706 mchbar_write32(0x142c, 0xd090220);
707 mchbar_write32(0x1430, 0x1010001);
708 mchbar_write32(0x1434, 0x1110000);
709 mchbar_write32(0x1438, 0x11040020);
710 mchbar_write32(0x143c, 0x4030220);
711 mchbar_write32(0x1440, 0x1060220);
712 mchbar_write32(0x1444, 0x1060330);
713 mchbar_write32(0x1448, 0x4030220);
714 mchbar_write32(0x144c, 0x1010001);
715 mchbar_write32(0x1450, 0x1110000);
716 mchbar_write32(0x1454, 0x4010020);
717 mchbar_write32(0x1458, 0xb090220);
718 mchbar_write32(0x145c, 0x1090220);
719 mchbar_write32(0x1460, 0x1090330);
720 mchbar_write32(0x1464, 0xb090220);
721 mchbar_write32(0x1468, 0x1010001);
722 mchbar_write32(0x146c, 0x1110000);
723 mchbar_write32(0x1470, 0xf040020);
724 mchbar_write32(0x1474, 0xa090220);
725 mchbar_write32(0x1478, 0x1120220);
726 mchbar_write32(0x147c, 0x1120330);
727 mchbar_write32(0x1480, 0xa090220);
728 mchbar_write32(0x1484, 0x1010001);
729 mchbar_write32(0x1488, 0x1110000);
730 mchbar_write32(0x148c, 0x7020020);
731 mchbar_write32(0x1490, 0x1010220);
732 mchbar_write32(0x1494, 0x10210);
733 mchbar_write32(0x1498, 0x10320);
734 mchbar_write32(0x149c, 0x1010220);
735 mchbar_write32(0x14a0, 0x1010001);
736 mchbar_write32(0x14a4, 0x1110000);
737 mchbar_write32(0x14a8, 0xd040020);
738 mchbar_write32(0x14ac, 0x8090220);
739 mchbar_write32(0x14b0, 0x1111310);
740 mchbar_write32(0x14b4, 0x1111420);
741 mchbar_write32(0x14b8, 0x8090220);
742 mchbar_write32(0x14bc, 0x1010001);
743 mchbar_write32(0x14c0, 0x1110000);
744 mchbar_write32(0x14c4, 0x3010020);
745 mchbar_write32(0x14c8, 0x7090220);
746 mchbar_write32(0x14cc, 0x1081310);
747 mchbar_write32(0x14d0, 0x1081420);
748 mchbar_write32(0x14d4, 0x7090220);
749 mchbar_write32(0x14d8, 0x1010001);
750 mchbar_write32(0x14dc, 0x1110000);
751 mchbar_write32(0x14e0, 0xb040020);
752 mchbar_write32(0x14e4, 0x2030220);
753 mchbar_write32(0x14e8, 0x1051310);
754 mchbar_write32(0x14ec, 0x1051420);
755 mchbar_write32(0x14f0, 0x2030220);
756 mchbar_write32(0x14f4, 0x1010001);
757 mchbar_write32(0x14f8, 0x1110000);
758 mchbar_write32(0x14fc, 0x5020020);
759 mchbar_write32(0x1500, 0x5090220);
760 mchbar_write32(0x1504, 0x2071310);
761 mchbar_write32(0x1508, 0x2071420);
762 mchbar_write32(0x150c, 0x5090220);
763 mchbar_write32(0x1510, 0x1010001);
764 mchbar_write32(0x1514, 0x1110000);
765 mchbar_write32(0x1518, 0x7040120);
766 mchbar_write32(0x151c, 0x2090220);
767 mchbar_write32(0x1520, 0x70b1210);
768 mchbar_write32(0x1524, 0x70b1310);
769 mchbar_write32(0x1528, 0x2090220);
770 mchbar_write32(0x152c, 0x1010001);
771 mchbar_write32(0x1530, 0x1110000);
772 mchbar_write32(0x1534, 0x1010110);
773 mchbar_write32(0x1538, 0x1081310);
774 mchbar_write32(0x153c, 0x5041200);
775 mchbar_write32(0x1540, 0x5041310);
776 mchbar_write32(0x1544, 0x1081310);
777 mchbar_write32(0x1548, 0x1010001);
778 mchbar_write32(0x154c, 0x1110000);
779 mchbar_write32(0x1550, 0x1040120);
780 mchbar_write32(0x1554, 0x4051210);
781 mchbar_write32(0x1558, 0xd051200);
782 mchbar_write32(0x155c, 0xd051200);
783 mchbar_write32(0x1560, 0x4051210);
784 mchbar_write32(0x1564, 0x1010001);
785 mchbar_write32(0x1568, 0x1110000);
786 mchbar_write16(0x1222, 0x220a);
787 mchbar_write16(0x123c, 0x1fc0);
788 mchbar_write16(0x1220, 0x1388);