summaryrefslogtreecommitdiff
path: root/src/southbridge/intel/i82801jx/early_init.c
blob: c10c421fe4a4dff3e29583876e9acad697a7e684 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
 * This file is part of the coreboot project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of
 * the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <console/console.h>
#include <device/pci_ops.h>
#include <device/smbus_host.h>
#include <southbridge/intel/common/gpio.h>
#include <southbridge/intel/common/pmbase.h>
#include "i82801jx.h"
#include "chip.h"

void i82801jx_lpc_setup(void)
{
	const pci_devfn_t d31f0 = PCI_DEV(0, 0x1f, 0);
	const struct device *dev = pcidev_on_root(0x1f, 0);
	const struct southbridge_intel_i82801jx_config *config;

	/* Configure serial IRQs.*/
	pci_write_config8(d31f0, D31F0_SERIRQ_CNTL, 0xd0);
	/*
	 * Enable some common LPC IO ranges:
	 * - 0x2e/0x2f, 0x4e/0x4f often SuperIO
	 * - 0x60/0x64, 0x62/0x66 often KBC/EC
	 * - 0x3f0-0x3f5/0x3f7 FDD
	 * - 0x378-0x37f and 0x778-0x77f LPT
	 * - 0x2f8-0x2ff COMB
	 * - 0x3f8-0x3ff COMA
	 * - 0x208-0x20f GAMEH
	 * - 0x200-0x207 GAMEL
	 */
	pci_write_config16(d31f0, D31F0_LPC_IODEC, 0x0010);
	pci_write_config16(d31f0, D31F0_LPC_EN, CNF2_LPC_EN | CNF1_LPC_EN
			   | MC_LPC_EN | KBC_LPC_EN | GAMEH_LPC_EN
			   | GAMEL_LPC_EN | FDD_LPC_EN | LPT_LPC_EN
			   | COMB_LPC_EN | COMA_LPC_EN);


	/* Set up generic decode ranges */
	if (!dev || !dev->chip_info)
		return;
	config = dev->chip_info;

	pci_write_config32(d31f0, D31F0_GEN1_DEC, config->gen1_dec);
	pci_write_config32(d31f0, D31F0_GEN2_DEC, config->gen2_dec);
	pci_write_config32(d31f0, D31F0_GEN3_DEC, config->gen3_dec);
	pci_write_config32(d31f0, D31F0_GEN4_DEC, config->gen4_dec);
}

void i82801jx_setup_bars(void)
{
	const pci_devfn_t d31f0 = PCI_DEV(0, 0x1f, 0);

	/* Set up RCBA. */
	pci_write_config32(d31f0, RCBA, (uintptr_t)DEFAULT_RCBA | 1);

	/* Set up PMBASE. */
	pci_write_config32(d31f0, D31F0_PMBASE, DEFAULT_PMBASE | 1);
	/* Enable PMBASE. */
	pci_write_config8(d31f0, D31F0_ACPI_CNTL, 0x80);

	/* Set up GPIOBASE. */
	pci_write_config32(d31f0, D31F0_GPIO_BASE, DEFAULT_GPIOBASE);
		/* Enable GPIO. */
	pci_write_config8(d31f0, D31F0_GPIO_CNTL,
			  pci_read_config8(d31f0, D31F0_GPIO_CNTL) | 0x10);
}

#define TCO_BASE 0x60

void i82801jx_early_init(void)
{
	const pci_devfn_t d31f0 = PCI_DEV(0, 0x1f, 0);

	if (ENV_ROMSTAGE)
		enable_smbus();

	printk(BIOS_DEBUG, "Setting up static southbridge registers...");
	i82801jx_setup_bars();
	printk(BIOS_DEBUG, " done.\n");

	setup_pch_gpios(&mainboard_gpio_map);

	printk(BIOS_DEBUG, "Disabling Watchdog reboot...");
	RCBA32(GCS) = RCBA32(GCS) | (1 << 5);	/* No reset */
	write_pmbase16(TCO_BASE + 0x8, (1 << 11));	/* halt timer */
	write_pmbase16(TCO_BASE + 0x4, (1 << 3));	/* clear timeout */
	write_pmbase16(TCO_BASE + 0x6, (1 << 1));	/* clear 2nd timeout */
	printk(BIOS_DEBUG, " done.\n");

	/* Enable IOAPIC */
	RCBA8(OIC) = 0x3;
	RCBA8(OIC);

	/* Initialize power management initialization
	   register early as it affects reboot behavior. */
	/* Bit 20 activates global reset of host and ME on cf9 writes of 0x6
	   and 0xe (required if ME is disabled but present), bit 31 locks it.
	   The other bits are 'must write'. */
	u8 reg8 = pci_read_config8(d31f0, 0xac);
	reg8 |= (1 << 31) | (1 << 30) | (1 << 20) | (3 << 8);
	pci_write_config8(d31f0, 0xac, reg8);

	/* TODO: If RTC power failed, reset RTC state machine
		(set, then reset RTC 0x0b bit7) */

	/* TODO: Check power state bits in GEN_PMCON_2 (D31F0 0xa2)
		before they get cleared. */
}