1 /* SPDX-License-Identifier: GPL-2.0-only */
5 #include <arch/ioapic.h>
6 #include <console/console.h>
7 #include <cpu/x86/smm.h>
8 #include <device/device.h>
9 #include <device/pci.h>
10 #include <device/pci_ids.h>
11 #include <device/pci_ops.h>
13 #include <pc80/i8259.h>
14 #include <pc80/isa-dma.h>
15 #include <pc80/mc146818rtc.h>
23 typedef struct southbridge_intel_i82801dx_config config_t
;
26 * Set miscellaneous static southbridge features.
28 * @param dev PCI device with I/O APIC control registers
30 static void i82801dx_enable_ioapic(struct device
*dev
)
34 reg32
= pci_read_config32(dev
, GEN_CNTL
);
35 reg32
|= (1 << 13); /* Coprocessor error enable (COPR_ERR_EN) */
36 reg32
|= (3 << 7); /* IOAPIC enable (APIC_EN) */
37 reg32
|= (1 << 2); /* DMA collection buffer enable (DCB_EN) */
38 reg32
|= (1 << 1); /* Delayed transaction enable (DTE) */
39 pci_write_config32(dev
, GEN_CNTL
, reg32
);
40 printk(BIOS_DEBUG
, "IOAPIC Southbridge enabled %x\n", reg32
);
42 register_new_ioapic_gsi0(IO_APIC_ADDR
);
44 ioapic_set_boot_config(IO_APIC_ADDR
, true);
47 static void i82801dx_enable_serial_irqs(struct device
*dev
)
49 /* Set packet length and toggle silent mode bit. */
50 pci_write_config8(dev
, SERIRQ_CNTL
,
51 (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
52 pci_write_config8(dev
, SERIRQ_CNTL
,
53 (1 << 7) | (0 << 6) | ((21 - 17) << 2) | (0 << 0));
56 static void i82801dx_pirq_init(struct device
*dev
)
58 /* Get the chip configuration */
59 config_t
*config
= dev
->chip_info
;
61 pci_write_config8(dev
, PIRQA_ROUT
, config
->pirqa_routing
);
62 pci_write_config8(dev
, PIRQB_ROUT
, config
->pirqb_routing
);
63 pci_write_config8(dev
, PIRQC_ROUT
, config
->pirqc_routing
);
64 pci_write_config8(dev
, PIRQD_ROUT
, config
->pirqd_routing
);
65 pci_write_config8(dev
, PIRQE_ROUT
, config
->pirqe_routing
);
66 pci_write_config8(dev
, PIRQF_ROUT
, config
->pirqf_routing
);
67 pci_write_config8(dev
, PIRQG_ROUT
, config
->pirqg_routing
);
68 pci_write_config8(dev
, PIRQH_ROUT
, config
->pirqh_routing
);
71 static void i82801dx_power_options(struct device
*dev
)
78 /* Which state do we want to goto after g3 (power restored)?
82 * If the option is not existent (Laptops), use MAINBOARD_POWER_ON.
84 const unsigned int pwr_on
= get_uint_option("power_on_after_fail", MAINBOARD_POWER_ON
);
86 reg8
= pci_read_config8(dev
, GEN_PMCON_3
);
89 case MAINBOARD_POWER_OFF
:
93 case MAINBOARD_POWER_ON
:
97 case MAINBOARD_POWER_KEEP
:
105 reg8
&= ~(1 << 3); /* minimum assertion is 1 to 2 RTCCLK */
107 pci_write_config8(dev
, GEN_PMCON_3
, reg8
);
108 printk(BIOS_INFO
, "Set power %s after power failure.\n", state
);
110 /* Set up NMI on errors. */
112 reg8
&= 0x0f; /* Higher Nibble must be 0 */
113 reg8
&= ~(1 << 3); /* IOCHK# NMI Enable */
114 // reg8 &= ~(1 << 2); /* PCI SERR# Enable */
115 reg8
|= (1 << 2); /* PCI SERR# Disable for now */
119 const unsigned int nmi_option
= get_uint_option("nmi", NMI_OFF
);
121 printk(BIOS_INFO
, "NMI sources enabled.\n");
122 reg8
&= ~(1 << 7); /* Set NMI. */
124 printk(BIOS_INFO
, "NMI sources disabled.\n");
125 reg8
|= (1 << 7); /* Disable NMI. */
129 /* Set SMI# rate down and enable CPU_SLP# */
130 reg16
= pci_read_config16(dev
, GEN_PMCON_1
);
131 reg16
&= ~(3 << 0); // SMI# rate 1 minute
132 reg16
|= (1 << 5); // CPUSLP_EN Desktop only
133 pci_write_config16(dev
, GEN_PMCON_1
, reg16
);
135 pmbase
= pci_read_config16(dev
, 0x40) & 0xfffe;
137 /* Set up power management block and determine sleep mode */
138 reg32
= inl(pmbase
+ 0x04); // PM1_CNT
140 reg32
&= ~(7 << 10); // SLP_TYP
141 reg32
|= (1 << 0); // SCI_EN
142 outl(reg32
, pmbase
+ 0x04);
146 static void i82801dx_rtc_init(struct device
*dev
)
152 reg8
= pci_read_config8(dev
, GEN_PMCON_3
);
153 rtc_failed
= reg8
& RTC_BATTERY_DEAD
;
155 reg8
&= ~(1 << 1); /* Preserve the power fail state. */
156 pci_write_config8(dev
, GEN_PMCON_3
, reg8
);
158 reg32
= pci_read_config32(dev
, GEN_STS
);
159 rtc_failed
|= reg32
& (1 << 2);
160 cmos_init(rtc_failed
);
162 /* Enable access to the upper 128 byte bank of CMOS RAM. */
163 pci_write_config8(dev
, RTC_CONF
, 0x04);
166 static void i82801dx_set_acpi_mode(struct device
*dev
)
168 if (!acpi_is_wakeup_s3()) {
169 apm_control(APM_CNT_ACPI_DISABLE
);
171 apm_control(APM_CNT_ACPI_ENABLE
);
175 static void i82801dx_lpc_route_dma(struct device
*dev
, u8 mask
)
180 reg16
= pci_read_config16(dev
, PCI_DMA_CFG
);
182 for (i
= 0; i
< 8; i
++) {
185 reg16
|= ((mask
& (1 << i
)) ? 3 : 1) << (i
* 2);
187 pci_write_config16(dev
, PCI_DMA_CFG
, reg16
);
190 /* ICH4 does not mention HPET in the docs, but
191 * all ICH3 and ICH4 do have HPETs built in.
193 static void enable_hpet(struct device
*dev
)
195 u32 reg32
, hpet
, val
;
197 /* Set HPET base address and enable it */
198 printk(BIOS_DEBUG
, "Enabling HPET at 0x%x\n", HPET_BASE_ADDRESS
);
199 reg32
= pci_read_config32(dev
, GEN_CNTL
);
201 * Bit 17 is HPET enable bit.
202 * Bit 16:15 control the HPET base address.
204 reg32
&= ~(3 << 15); /* Clear it */
206 hpet
= HPET_BASE_ADDRESS
>> 12;
209 reg32
|= (hpet
<< 15);
210 reg32
|= (1 << 17); /* Enable HPET. */
211 pci_write_config32(dev
, GEN_CNTL
, reg32
);
213 /* Check to see whether it took */
214 reg32
= pci_read_config32(dev
, GEN_CNTL
);
218 if ((val
& 0x4) && (hpet
== (val
& 0x3))) {
219 printk(BIOS_INFO
, "HPET enabled at 0x%x\n", HPET_BASE_ADDRESS
);
221 printk(BIOS_WARNING
, "HPET was not enabled correctly\n");
222 reg32
&= ~(1 << 17); /* Clear Enable */
223 pci_write_config32(dev
, GEN_CNTL
, reg32
);
227 static void lpc_init(struct device
*dev
)
229 /* IO APIC initialization. */
230 i82801dx_enable_ioapic(dev
);
232 i82801dx_enable_serial_irqs(dev
);
234 /* Setup the PIRQ. */
235 i82801dx_pirq_init(dev
);
237 /* Setup power options. */
238 i82801dx_power_options(dev
);
240 /* Initialize the real time clock. */
241 i82801dx_rtc_init(dev
);
244 i82801dx_lpc_route_dma(dev
, 0xff);
246 /* Initialize ISA DMA. */
249 /* Initialize the High Precision Event Timers */
254 i82801dx_set_acpi_mode(dev
);
257 static void i82801dx_lpc_read_resources(struct device
*dev
)
259 struct resource
*res
;
261 /* Get the normal PCI resources of this device. */
262 pci_dev_read_resources(dev
);
264 /* Add an extra subtractive resource for both memory and I/O. */
265 res
= new_resource(dev
, IOINDEX_SUBTRACTIVE(0, 0));
268 res
->flags
= IORESOURCE_IO
| IORESOURCE_SUBTRACTIVE
|
269 IORESOURCE_ASSIGNED
| IORESOURCE_FIXED
;
271 res
= new_resource(dev
, IOINDEX_SUBTRACTIVE(1, 0));
272 res
->base
= 0xff800000;
273 res
->size
= 0x00800000; /* 8 MB for flash */
274 res
->flags
= IORESOURCE_MEM
| IORESOURCE_SUBTRACTIVE
|
275 IORESOURCE_ASSIGNED
| IORESOURCE_FIXED
;
277 res
= new_resource(dev
, 3); /* IOAPIC */
278 res
->base
= IO_APIC_ADDR
;
279 res
->size
= 0x00001000;
280 res
->flags
= IORESOURCE_MEM
| IORESOURCE_ASSIGNED
| IORESOURCE_FIXED
;
283 static struct device_operations lpc_ops
= {
284 .read_resources
= i82801dx_lpc_read_resources
,
285 .set_resources
= pci_dev_set_resources
,
286 .enable_resources
= pci_dev_enable_resources
,
288 .scan_bus
= scan_static_bus
,
289 .enable
= i82801dx_enable
,
293 static const struct pci_driver lpc_driver_db __pci_driver
= {
295 .vendor
= PCI_VID_INTEL
,
296 .device
= PCI_DID_INTEL_82801DB_LPC
,
300 static const struct pci_driver lpc_driver_dbm __pci_driver
= {
302 .vendor
= PCI_VID_INTEL
,
303 .device
= PCI_DID_INTEL_82801DBM_LPC
,