blob: 010ab8688782b2eaba7e4861e7e7137708b1c9dc [file] [log] [blame]
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +01001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2007-2009 coresystems GmbH
5 * Copyright (C) 2011 Sven Schnelle <svens@stackframe.org>
6 * Copyright (C) 2013 Vladimir Serbinenko <phcoder@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; version 2 of
11 * the License.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +010017 */
18
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +010019#include <stdint.h>
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +010020#include <arch/io.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020021#include <device/pci_ops.h>
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +010022#include <device/pci_def.h>
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +010023#include <cpu/x86/lapic.h>
Kyösti Mälkki1b7609c2016-06-25 11:40:00 +030024#include <romstage_handoff.h>
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +010025#include <console/console.h>
Kyösti Mälkkicd7a70f2019-08-17 20:51:08 +030026#include <arch/romstage.h>
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +010027#include <ec/acpi/ec.h>
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +010028#include <timestamp.h>
Kyösti Mälkkibb805e12014-06-16 09:14:49 +030029#include <arch/acpi.h>
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +010030
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +010031#include "dock.h"
Edward O'Callaghan77757c22015-01-04 21:33:39 +110032#include <southbridge/intel/ibexpeak/pch.h>
Arthur Heymans7dee9742017-04-05 12:05:12 +020033#include <southbridge/intel/common/gpio.h>
Edward O'Callaghan77757c22015-01-04 21:33:39 +110034#include <northbridge/intel/nehalem/nehalem.h>
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +010035
Edward O'Callaghan77757c22015-01-04 21:33:39 +110036#include <northbridge/intel/nehalem/raminit.h>
37#include <southbridge/intel/ibexpeak/me.h>
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +010038
39static void pch_enable_lpc(void)
40{
Peter Lemenkov6dc77482018-10-15 09:28:01 +020041 /* EC Decode Range Port60/64, Port62/66 */
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +010042 /* Enable EC, PS/2 Keyboard/Mouse */
43 pci_write_config16(PCH_LPC_DEV, LPC_EN,
44 CNF2_LPC_EN | CNF1_LPC_EN | MC_LPC_EN | KBC_LPC_EN |
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +010045 COMA_LPC_EN | GAMEL_LPC_EN);
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +010046
47 pci_write_config32(PCH_LPC_DEV, LPC_GEN1_DEC, 0x7c1601);
48 pci_write_config32(PCH_LPC_DEV, LPC_GEN2_DEC, 0xc15e1);
49 pci_write_config32(PCH_LPC_DEV, LPC_GEN3_DEC, 0x1c1681);
50 pci_write_config32(PCH_LPC_DEV, LPC_GEN4_DEC, (0x68 & ~3) | 0x00040001);
51
52 pci_write_config16(PCH_LPC_DEV, LPC_IO_DEC, 0x10);
53
54 pci_write_config32(PCH_LPC_DEV, 0xd0, 0x0);
Vladimir Serbinenko79c712c2014-02-05 19:10:03 +010055 pci_write_config32(PCH_LPC_DEV, 0xdc, 0x8);
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +010056
57 pci_write_config8(PCH_LPC_DEV, GEN_PMCON_3,
58 (pci_read_config8(PCH_LPC_DEV, GEN_PMCON_3) & ~2) | 1);
59
60 pci_write_config32(PCH_LPC_DEV, ETR3,
61 pci_read_config32(PCH_LPC_DEV, ETR3) & ~ETR3_CF9GR);
62}
63
Arthur Heymans39f8a1a2019-10-02 17:13:02 +020064const struct southbridge_usb_port mainboard_usb_ports[] = {
65 /* Enabled, Current table lookup index, OC map */
66 { 1, IF1_557, 0 },
67 { 1, IF1_55F, 1 },
68 { 1, IF1_74B, 3 },
69 { 1, IF1_74B, 3 },
70 { 1, IF1_557, 3 },
71 { 1, IF1_14B, 3 },
72 { 1, IF1_74B, 3 },
73 { 1, IF1_74B, 3 },
74 { 1, IF1_74B, 4 },
75 { 1, IF1_74B, 5 },
76 { 1, IF1_55F, 7 },
77 { 1, IF1_55F, 7 },
78 { 1, IF1_557, 7 },
79 { 1, IF1_55F, 7 },
80};
81
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +010082static void rcba_config(void)
83{
Vladimir Serbinenko33b535f2014-10-19 10:13:14 +020084 southbridge_configure_default_intmap();
85
Arthur Heymans126f9e52019-09-16 21:09:36 +020086 /* Must set BIT0 (hides performance counters PCI device).
87 coreboot enables the Rate Matching Hub which makes the UHCI PCI
88 devices disappear, so BIT5-12 and BIT28 can be set to hide those. */
89 RCBA32(FD) = (1 << 28) | (0xff << 5) | 1;
90
91 /* Set reserved bit to 1 */
92 RCBA32(FD2) = 1;
93
Arthur Heymans39f8a1a2019-10-02 17:13:02 +020094 early_usb_init(mainboard_usb_ports);
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +010095}
96
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +010097static inline void write_acpi32(u32 addr, u32 val)
98{
99 outl(val, DEFAULT_PMBASE | addr);
100}
101
102static inline void write_acpi16(u32 addr, u16 val)
103{
104 outw(val, DEFAULT_PMBASE | addr);
105}
106
107static inline u32 read_acpi32(u32 addr)
108{
109 return inl(DEFAULT_PMBASE | addr);
110}
111
Vladimir Serbinenko9817a372014-02-19 22:07:12 +0100112static void set_fsb_frequency(void)
113{
114 u8 block[5];
115 u16 fsbfreq = 62879;
116 smbus_block_read(0x69, 0, 5, block);
117 block[0] = fsbfreq;
118 block[1] = fsbfreq >> 8;
119
120 smbus_block_write(0x69, 0, 5, block);
121}
122
Kyösti Mälkki157b1892019-08-16 14:02:25 +0300123void mainboard_romstage_entry(void)
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +0100124{
125 u32 reg32;
126 int s3resume = 0;
Vladimir Serbinenko902626c2014-02-16 17:22:26 +0100127 const u8 spd_addrmap[4] = { 0x50, 0, 0x51, 0 };
Kyösti Mälkki157b1892019-08-16 14:02:25 +0300128 enable_lapic();
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +0100129
Vladimir Serbinenkobca98552014-01-09 11:13:18 +0100130 nehalem_early_initialization(NEHALEM_MOBILE);
131
132 pch_enable_lpc();
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +0100133
134 /* Enable USB Power. We need to do it early for usbdebug to work. */
135 ec_set_bit(0x3b, 4);
136
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +0100137 /* Enable GPIOs */
138 pci_write_config32(PCH_LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE | 1);
139 pci_write_config8(PCH_LPC_DEV, GPIO_CNTL, 0x10);
140
Arthur Heymans7dee9742017-04-05 12:05:12 +0200141 setup_pch_gpios(&mainboard_gpio_map);
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +0100142
Arthur Heymansf503b602019-09-16 21:00:22 +0200143 pch_setup_cir(NEHALEM_MOBILE);
144
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +0100145
146 /* This should probably go away. Until now it is required
147 * and mainboard specific
148 */
149 rcba_config();
150
151 console_init();
152
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +0100153 /* Read PM1_CNT */
154 reg32 = inl(DEFAULT_PMBASE + 0x04);
155 printk(BIOS_DEBUG, "PM1_CNT: %08x\n", reg32);
156 if (((reg32 >> 10) & 7) == 5) {
157 u8 reg8;
158 reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa2);
159 printk(BIOS_DEBUG, "a2: %02x\n", reg8);
160 if (!(reg8 & 0x20)) {
161 outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04);
162 printk(BIOS_DEBUG, "Bad resume from S3 detected.\n");
163 } else {
Kyösti Mälkkibb805e12014-06-16 09:14:49 +0300164 if (acpi_s3_resume_allowed()) {
165 printk(BIOS_DEBUG, "Resume from S3 detected.\n");
166 s3resume = 1;
167 } else {
168 printk(BIOS_DEBUG,
169 "Resume from S3 detected, but disabled.\n");
170 }
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +0100171 }
172 }
173
174 /* Enable SMBUS. */
175 enable_smbus();
176
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +0100177 outb((inb(DEFAULT_GPIOBASE | 0x3a) & ~0x2) | 0x20,
178 DEFAULT_GPIOBASE | 0x3a);
179 outb(0x50, 0x15ec);
180 outb(inb(0x15ee) & 0x70, 0x15ee);
181
182 write_acpi16(0x2, 0x0);
183 write_acpi32(0x28, 0x0);
184 write_acpi32(0x2c, 0x0);
185 if (!s3resume) {
186 read_acpi32(0x4);
187 read_acpi32(0x20);
188 read_acpi32(0x34);
189 write_acpi16(0x0, 0x900);
190 write_acpi32(0x20, 0xffff7ffe);
191 write_acpi32(0x34, 0x56974);
192 pci_write_config8(PCH_LPC_DEV, GEN_PMCON_3,
193 pci_read_config8(PCH_LPC_DEV, GEN_PMCON_3) | 2);
194 }
195
Vladimir Serbinenko1cd937b2014-01-09 23:41:48 +0100196 early_thermal_init();
197
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +0100198 timestamp_add_now(TS_BEFORE_INITRAM);
199
Vladimir Serbinenko9817a372014-02-19 22:07:12 +0100200 chipset_init(s3resume);
201
202 set_fsb_frequency();
203
Vladimir Serbinenko902626c2014-02-16 17:22:26 +0100204 raminit(s3resume, spd_addrmap);
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +0100205
206 timestamp_add_now(TS_AFTER_INITRAM);
207
208 intel_early_me_status();
209
210 if (s3resume) {
211 /* Clear SLP_TYPE. This will break stage2 but
212 * we care for that when we get there.
213 */
214 reg32 = inl(DEFAULT_PMBASE + 0x04);
215 outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04);
216 }
Kyösti Mälkki97e1b112014-01-06 17:18:58 +0200217
Kyösti Mälkki1b7609c2016-06-25 11:40:00 +0300218 romstage_handoff_init(s3resume);
Vladimir Serbinenko9bf05de2013-11-14 19:11:19 +0100219}