blob: bd6bfc6ee7d64b6b812647f606dec0a035d1129e [file] [log] [blame]
Arthur Heymans3534c1e2018-12-16 17:17:13 +01001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2015 Damien Zammit <damien@zamaudio.com>
5 * Copyright (C) 2017 Arthur Heymans <arthur@aheymans.xyz>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
Elyes HAOUAS8c905a82019-02-07 09:00:47 +010018#include <arch/io.h>
Elyes HAOUASd07048a2019-04-21 20:17:11 +020019#include <cf9_reset.h>
Kyösti Mälkki3855c012019-03-03 08:45:19 +020020#include <device/pnp_ops.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020021#include <device/pci_ops.h>
Arthur Heymans3534c1e2018-12-16 17:17:13 +010022#include <console/console.h>
Arthur Heymans3534c1e2018-12-16 17:17:13 +010023#include <cpu/intel/romstage.h>
Arthur Heymans3534c1e2018-12-16 17:17:13 +010024#include <cpu/intel/speedstep.h>
Elyes HAOUAS8c905a82019-02-07 09:00:47 +010025#include <cpu/x86/bist.h>
Arthur Heymans3534c1e2018-12-16 17:17:13 +010026#include <cpu/x86/msr.h>
Elyes HAOUAS8c905a82019-02-07 09:00:47 +010027#include <northbridge/intel/x4x/iomap.h>
28#include <northbridge/intel/x4x/x4x.h>
29#include <southbridge/intel/common/gpio.h>
Patrick Rudolph425e75a2019-03-24 15:06:17 +010030#include <southbridge/intel/common/pmclib.h>
Elyes HAOUAS8c905a82019-02-07 09:00:47 +010031#include <southbridge/intel/i82801gx/i82801gx.h>
32#include <superio/winbond/common/winbond.h>
33#include <superio/winbond/w83627dhg/w83627dhg.h>
Arthur Heymans3534c1e2018-12-16 17:17:13 +010034
35#define SERIAL_DEV PNP_DEV(0x2e, W83627DHG_SP1)
36#define GPIO_DEV PNP_DEV(0x2e, W83627DHG_GPIO2345_V)
37#define LPC_DEV PCI_DEV(0, 0x1f, 0)
38
39static u8 msr_get_fsb(void)
40{
41 u8 fsbcfg;
42 msr_t msr;
43 const u32 eax = cpuid_eax(1);
44
45 /* Netburst */
46 if (((eax >> 8) & 0xf) == 0xf) {
47 msr = rdmsr(MSR_EBC_FREQUENCY_ID);
48 fsbcfg = (msr.lo >> 16) & 0x7;
49 } else { /* Intel Core 2 */
50 msr = rdmsr(MSR_FSB_FREQ);
51 fsbcfg = msr.lo & 0x7;
52 }
53
54 return fsbcfg;
55}
56
Angel Ponsc69c8dd2018-06-13 14:13:15 +020057/* BSEL MCH straps are not hooked up to the CPU as usual but to the SIO */
Arthur Heymans3534c1e2018-12-16 17:17:13 +010058
59static int setup_sio_gpio(void)
60{
61 int need_reset = 0;
62 u8 reg, old_reg;
63
64 u8 bsel = msr_get_fsb();
65 switch (bsel) {
66 case 0:
67 case 2:
68 case 4:
69 break;
70 default:
71 printk(BIOS_WARNING,
72 "BSEL: Unsupported FSB frequency, using 800MHz\n");
73 bsel = 2; /* 800MHz */
74 break;
75 }
76
77 pnp_enter_ext_func_mode(GPIO_DEV);
78 pnp_set_logical_device(GPIO_DEV);
79
Julius Wernercd49cce2019-03-05 16:53:33 -080080 if (CONFIG(BOARD_ASUS_P5QPL_AM)) {
Angel Ponsc69c8dd2018-06-13 14:13:15 +020081 /*
82 * P5QPL-AM:
83 * BSEL0 -> not hooked up (not supported anyways)
84 * BSEL1 -> GPIO33
85 * BSEL2 -> GPIO40
86 */
87 reg = 0x92;
88 old_reg = pnp_read_config(GPIO_DEV, 0x2c);
89 pnp_write_config(GPIO_DEV, 0x2c, reg);
90 need_reset = (reg != old_reg);
Arthur Heymans3534c1e2018-12-16 17:17:13 +010091
Angel Ponsc69c8dd2018-06-13 14:13:15 +020092 pnp_write_config(GPIO_DEV, 0x30, 0x06);
93 pnp_write_config(GPIO_DEV, 0xf0, 0xf3); /* GPIO3 direction */
94 pnp_write_config(GPIO_DEV, 0xf4, 0x00); /* GPIO4 direction */
Arthur Heymans3534c1e2018-12-16 17:17:13 +010095
Angel Ponsc69c8dd2018-06-13 14:13:15 +020096 const int gpio33 = (bsel & 2) >> 1;
97 const int gpio40 = (bsel & 4) >> 2;
98 reg = (gpio33 << 3);
99 old_reg = pnp_read_config(GPIO_DEV, 0xf1);
100 pnp_write_config(GPIO_DEV, 0xf1, old_reg | reg);
101 need_reset += ((reg & 0x8) != (old_reg & 0x8));
Arthur Heymans3534c1e2018-12-16 17:17:13 +0100102
Angel Ponsc69c8dd2018-06-13 14:13:15 +0200103 reg = gpio40;
104 old_reg = pnp_read_config(GPIO_DEV, 0xf5);
105 pnp_write_config(GPIO_DEV, 0xf5, old_reg | reg);
106 need_reset += ((reg & 0x1) != (old_reg & 0x1));
107 } else {
108 /*
109 * P5G41T-M LX:
110 * BSEL0 -> not hooked up
111 * BSEL1 -> GPIO43 (inverted)
112 * BSEL2 -> GPIO44
113 */
114 reg = 0xf2;
115 old_reg = pnp_read_config(GPIO_DEV, 0x2c);
116 pnp_write_config(GPIO_DEV, 0x2c, reg);
117 need_reset = (reg != old_reg);
118 pnp_write_config(GPIO_DEV, 0x30, 0x05);
119 pnp_write_config(GPIO_DEV, 0xf6, 0x08); /* invert GPIO43 */
120 pnp_write_config(GPIO_DEV, 0xf4, 0x00); /* GPIO4 direction */
Arthur Heymans3534c1e2018-12-16 17:17:13 +0100121
Angel Ponsc69c8dd2018-06-13 14:13:15 +0200122 const int gpio43 = (bsel & 2) >> 1;
123 const int gpio44 = (bsel & 4) >> 2;
124 reg = (gpio43 << 3) | (gpio44 << 4);
125 old_reg = pnp_read_config(GPIO_DEV, 0xf5);
126 pnp_write_config(GPIO_DEV, 0xf5, old_reg | reg);
127 need_reset += ((reg & 0x18) != (old_reg & 0x18));
128 }
Arthur Heymans3534c1e2018-12-16 17:17:13 +0100129 pnp_exit_ext_func_mode(GPIO_DEV);
130
131 return need_reset;
132}
133
134static void mb_lpc_setup(void)
135{
136 u32 reg32;
137 /* Set the value for GPIO base address register and enable GPIO. */
138 pci_write_config32(LPC_DEV, GPIO_BASE, (DEFAULT_GPIOBASE | 1));
139 pci_write_config8(LPC_DEV, GPIO_CNTL, 0x10);
140
141 setup_pch_gpios(&mainboard_gpio_map);
142
143 /* Enable IOAPIC */
144 RCBA8(0x31ff) = 0x03;
145 RCBA8(0x31ff);
146
147 reg32 = RCBA32(GCS);
148 reg32 |= (1 << 5);
149 RCBA32(GCS) = reg32;
Arthur Heymans3534c1e2018-12-16 17:17:13 +0100150 RCBA32(CG) = 0x00000001;
151}
152
153static void ich7_enable_lpc(void)
154{
155 pci_write_config8(LPC_DEV, SERIRQ_CNTL, 0xd0);
156 /* Fixed IO decode ranges */
157 pci_write_config16(LPC_DEV, LPC_IO_DEC, 0x0010);
158 /* LPC enable devices */
159 pci_write_config16(LPC_DEV, LPC_EN, CNF1_LPC_EN | KBC_LPC_EN
160 | FDD_LPC_EN | LPT_LPC_EN
161 | COMB_LPC_EN | COMA_LPC_EN);
162 /* IO decode range: HWM on 0x295 */
163 pci_write_config32(LPC_DEV, 0x84, 0x000295);
164}
165
166void mainboard_romstage_entry(unsigned long bist)
167{
168 // ch0 ch1
169 const u8 spd_addrmap[4] = { 0x50, 0, 0x52, 0 };
170 u8 boot_path = 0;
171 u8 s3_resume;
172
Arthur Heymans3534c1e2018-12-16 17:17:13 +0100173 /* Set southbridge and Super I/O GPIOs. */
174 ich7_enable_lpc();
175 mb_lpc_setup();
176 winbond_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
177
178 console_init();
179
180 report_bist_failure(bist);
181 enable_smbus();
182
183 x4x_early_init();
184
185 s3_resume = southbridge_detect_s3_resume();
186 if (s3_resume)
187 boot_path = BOOT_PATH_RESUME;
188 if (MCHBAR32(PMSTS_MCHBAR) & PMSTS_WARM_RESET)
189 boot_path = BOOT_PATH_WARM_RESET;
190
191 if (!s3_resume && setup_sio_gpio()) {
192 printk(BIOS_DEBUG,
193 "Needs reset to configure CPU BSEL straps\n");
Elyes HAOUASd07048a2019-04-21 20:17:11 +0200194 full_reset();
Arthur Heymans3534c1e2018-12-16 17:17:13 +0100195 }
196
Arthur Heymans3534c1e2018-12-16 17:17:13 +0100197 sdram_initialize(boot_path, spd_addrmap);
Arthur Heymans3534c1e2018-12-16 17:17:13 +0100198
199 x4x_late_init(s3_resume);
200
201 printk(BIOS_DEBUG, "x4x late init complete\n");
202
203}