blob: 380dca4c3074b3368da18b742945face5626a621 [file] [log] [blame]
Angel Pons182dbde2020-04-02 23:49:05 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Arthur Heymans7b9c1392017-04-09 20:40:39 +02003
4#include <console/console.h>
5#include <device/device.h>
6#include <device/pci.h>
7#include <device/pci_ids.h>
Kyösti Mälkkicbf95712020-01-05 08:05:45 +02008#include <option.h>
Arthur Heymans7b9c1392017-04-09 20:40:39 +02009#include <pc80/mc146818rtc.h>
10#include <pc80/isa-dma.h>
11#include <pc80/i8259.h>
12#include <arch/io.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020013#include <device/pci_ops.h>
Arthur Heymans7b9c1392017-04-09 20:40:39 +020014#include <arch/ioapic.h>
15#include <arch/acpi.h>
Arthur Heymans7b9c1392017-04-09 20:40:39 +020016#include <cpu/x86/smm.h>
17#include <arch/acpigen.h>
Arthur Heymansad501492017-04-12 00:15:39 +020018#include <arch/smp/mpspec.h>
Arthur Heymans7b9c1392017-04-09 20:40:39 +020019#include <cbmem.h>
20#include <string.h>
Kyösti Mälkki12b121c2019-08-18 16:33:39 +030021#include "chip.h"
Arthur Heymans349e0852017-04-09 20:48:37 +020022#include "i82801jx.h"
Arthur Heymans7b9c1392017-04-09 20:40:39 +020023#include "nvs.h"
24#include <southbridge/intel/common/pciehp.h>
Arthur Heymansa8a9f342017-12-24 08:11:13 +010025#include <southbridge/intel/common/acpi_pirq_gen.h>
Arthur Heymans7b9c1392017-04-09 20:40:39 +020026
27#define NMI_OFF 0
28
Arthur Heymans349e0852017-04-09 20:48:37 +020029typedef struct southbridge_intel_i82801jx_config config_t;
Arthur Heymans7b9c1392017-04-09 20:40:39 +020030
Arthur Heymans349e0852017-04-09 20:48:37 +020031static void i82801jx_enable_apic(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +020032{
33 u32 reg32;
34 volatile u32 *ioapic_index = (volatile u32 *)(IO_APIC_ADDR);
35 volatile u32 *ioapic_data = (volatile u32 *)(IO_APIC_ADDR + 0x10);
36
37 /* Enable IOAPIC. Keep APIC Range Select at zero. */
38 RCBA8(0x31ff) = 0x03;
39 /* We have to read 0x31ff back if bit0 changed. */
40 RCBA8(0x31ff);
41
42 /* Lock maximum redirection entries (MRE), R/WO register. */
43 *ioapic_index = 0x01;
44 reg32 = *ioapic_data;
45 *ioapic_index = 0x01;
46 *ioapic_data = reg32;
47
48 setup_ioapic(VIO_APIC_VADDR, 2); /* ICH7 code uses id 2. */
49}
50
Arthur Heymans349e0852017-04-09 20:48:37 +020051static void i82801jx_enable_serial_irqs(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +020052{
53 /* Set packet length and toggle silent mode bit for one frame. */
54 pci_write_config8(dev, D31F0_SERIRQ_CNTL,
55 (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
56}
57
58/* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
59 * 0x00 - 0000 = Reserved
60 * 0x01 - 0001 = Reserved
61 * 0x02 - 0010 = Reserved
62 * 0x03 - 0011 = IRQ3
63 * 0x04 - 0100 = IRQ4
64 * 0x05 - 0101 = IRQ5
65 * 0x06 - 0110 = IRQ6
66 * 0x07 - 0111 = IRQ7
67 * 0x08 - 1000 = Reserved
68 * 0x09 - 1001 = IRQ9
69 * 0x0A - 1010 = IRQ10
70 * 0x0B - 1011 = IRQ11
71 * 0x0C - 1100 = IRQ12
72 * 0x0D - 1101 = Reserved
73 * 0x0E - 1110 = IRQ14
74 * 0x0F - 1111 = IRQ15
75 * PIRQ[n]_ROUT[7] - PIRQ Routing Control
76 * 0x80 - The PIRQ is not routed.
77 */
78
Elyes HAOUAS1a8c1df2018-05-13 13:36:44 +020079static void i82801jx_pirq_init(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +020080{
Elyes HAOUAS1a8c1df2018-05-13 13:36:44 +020081 struct device *irq_dev;
Arthur Heymans7b9c1392017-04-09 20:40:39 +020082
Arthur Heymans87af36a2017-04-12 10:53:30 +020083 /* Interrupt 11 is not used by legacy devices and so can always be used
84 * for PCI interrupts. Full legacy IRQ routing is complicated and hard
85 * to get right. Fortunately all modern OS use MSI and so it's not that
86 * big of an issue anyway. Still we have to provide a reasonable
87 * default. Using interrupt 11 for it everywhere is a working default.
88 * ACPI-aware OS can move it to any interrupt and others will just leave
89 * them at default.
90 */
91 const u8 pirq_routing = 11;
Arthur Heymans7b9c1392017-04-09 20:40:39 +020092
Arthur Heymans87af36a2017-04-12 10:53:30 +020093 pci_write_config8(dev, D31F0_PIRQA_ROUT, pirq_routing);
94 pci_write_config8(dev, D31F0_PIRQB_ROUT, pirq_routing);
95 pci_write_config8(dev, D31F0_PIRQC_ROUT, pirq_routing);
96 pci_write_config8(dev, D31F0_PIRQD_ROUT, pirq_routing);
97
98 pci_write_config8(dev, D31F0_PIRQE_ROUT, pirq_routing);
99 pci_write_config8(dev, D31F0_PIRQF_ROUT, pirq_routing);
100 pci_write_config8(dev, D31F0_PIRQG_ROUT, pirq_routing);
101 pci_write_config8(dev, D31F0_PIRQH_ROUT, pirq_routing);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200102
103 /* Eric Biederman once said we should let the OS do this.
104 * I am not so sure anymore he was right.
105 */
106
107 for (irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) {
Arthur Heymans87af36a2017-04-12 10:53:30 +0200108 u8 int_pin = 0;
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200109
110 if (!irq_dev->enabled || irq_dev->path.type != DEVICE_PATH_PCI)
111 continue;
112
113 int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN);
114
Arthur Heymans87af36a2017-04-12 10:53:30 +0200115 if (int_pin == 0)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200116 continue;
117
Arthur Heymans87af36a2017-04-12 10:53:30 +0200118 pci_write_config8(irq_dev, PCI_INTERRUPT_LINE, pirq_routing);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200119 }
120}
121
Elyes HAOUAS1a8c1df2018-05-13 13:36:44 +0200122static void i82801jx_gpi_routing(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200123{
124 /* Get the chip configuration */
125 config_t *config = dev->chip_info;
126 u32 reg32 = 0;
127
128 /* An array would be much nicer here, or some
129 * other method of doing this.
130 */
131 reg32 |= (config->gpi0_routing & 0x03) << 0;
132 reg32 |= (config->gpi1_routing & 0x03) << 2;
133 reg32 |= (config->gpi2_routing & 0x03) << 4;
134 reg32 |= (config->gpi3_routing & 0x03) << 6;
135 reg32 |= (config->gpi4_routing & 0x03) << 8;
136 reg32 |= (config->gpi5_routing & 0x03) << 10;
137 reg32 |= (config->gpi6_routing & 0x03) << 12;
138 reg32 |= (config->gpi7_routing & 0x03) << 14;
139 reg32 |= (config->gpi8_routing & 0x03) << 16;
140 reg32 |= (config->gpi9_routing & 0x03) << 18;
141 reg32 |= (config->gpi10_routing & 0x03) << 20;
142 reg32 |= (config->gpi11_routing & 0x03) << 22;
143 reg32 |= (config->gpi12_routing & 0x03) << 24;
144 reg32 |= (config->gpi13_routing & 0x03) << 26;
145 reg32 |= (config->gpi14_routing & 0x03) << 28;
146 reg32 |= (config->gpi15_routing & 0x03) << 30;
147
148 pci_write_config32(dev, D31F0_GPIO_ROUT, reg32);
149}
150
Elyes HAOUAS1a8c1df2018-05-13 13:36:44 +0200151static void i82801jx_power_options(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200152{
153 u8 reg8;
154 u16 reg16, pmbase;
155 u32 reg32;
156 const char *state;
157 /* Get the chip configuration */
158 config_t *config = dev->chip_info;
159
Nico Huber9faae2b2018-11-14 00:00:35 +0100160 int pwr_on = CONFIG_MAINBOARD_POWER_FAILURE_STATE;
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200161 int nmi_option;
162
163 /* BIOS must program... */
164 reg32 = pci_read_config32(dev, 0xac);
165 pci_write_config32(dev, 0xac, reg32 | (1 << 30) | (3 << 8));
166
167 /* Which state do we want to goto after g3 (power restored)?
168 * 0 == S0 Full On
169 * 1 == S5 Soft Off
170 *
171 * If the option is not existent (Laptops), use MAINBOARD_POWER_ON.
172 */
173 pwr_on = MAINBOARD_POWER_ON;
174 get_option(&pwr_on, "power_on_after_fail");
175
176 reg8 = pci_read_config8(dev, D31F0_GEN_PMCON_3);
177 reg8 &= 0xfe;
178 switch (pwr_on) {
179 case MAINBOARD_POWER_OFF:
180 reg8 |= 1;
181 state = "off";
182 break;
183 case MAINBOARD_POWER_ON:
184 reg8 &= ~1;
185 state = "on";
186 break;
187 case MAINBOARD_POWER_KEEP:
188 reg8 &= ~1;
189 state = "state keep";
190 break;
191 default:
192 state = "undefined";
193 }
194
195 reg8 |= (3 << 4); /* avoid #S4 assertions */
196 reg8 &= ~(1 << 3); /* minimum asssertion is 1 to 2 RTCCLK */
197
198 pci_write_config8(dev, D31F0_GEN_PMCON_3, reg8);
199 printk(BIOS_INFO, "Set power %s after power failure.\n", state);
200
201 /* Set up NMI on errors. */
202 reg8 = inb(0x61);
203 reg8 &= 0x0f; /* Higher Nibble must be 0 */
204 reg8 &= ~(1 << 3); /* IOCHK# NMI Enable */
205 // reg8 &= ~(1 << 2); /* PCI SERR# Enable */
206 reg8 |= (1 << 2); /* PCI SERR# Disable for now */
207 outb(reg8, 0x61);
208
209 reg8 = inb(0x74); /* Read from 0x74 as 0x70 is write only. */
210 nmi_option = NMI_OFF;
211 get_option(&nmi_option, "nmi");
212 if (nmi_option) {
213 printk(BIOS_INFO, "NMI sources enabled.\n");
214 reg8 &= ~(1 << 7); /* Set NMI. */
215 } else {
216 printk(BIOS_INFO, "NMI sources disabled.\n");
Elyes HAOUAS9c5d4632018-04-26 22:21:21 +0200217 reg8 |= (1 << 7); /* Can't mask NMI from PCI-E and NMI_NOW */
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200218 }
219 outb(reg8, 0x70);
220
221 /* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */
222 reg16 = pci_read_config16(dev, D31F0_GEN_PMCON_1);
223 reg16 &= ~(3 << 0); // SMI# rate 1 minute
224 reg16 |= (1 << 2); // CLKRUN_EN - Mobile/Ultra only
225 reg16 |= (1 << 3); // Speedstep Enable - Mobile/Ultra only
226 reg16 |= (1 << 5); // CPUSLP_EN Desktop only
227
228 if (config->c4onc3_enable)
229 reg16 |= (1 << 7);
230
231 // another laptop wants this?
232 // reg16 &= ~(1 << 10); // BIOS_PCI_EXP_EN - Desktop/Mobile only
233 reg16 |= (1 << 10); // BIOS_PCI_EXP_EN - Desktop/Mobile only
234#if DEBUG_PERIODIC_SMIS
Arthur Heymans349e0852017-04-09 20:48:37 +0200235 /* Set DEBUG_PERIODIC_SMIS in i82801jx.h to debug using
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200236 * periodic SMIs.
237 */
238 reg16 |= (3 << 0); // Periodic SMI every 8s
239#endif
240 if (config->c5_enable)
241 reg16 |= (1 << 11); /* Enable C5, C6 and PMSYNC# */
242 pci_write_config16(dev, D31F0_GEN_PMCON_1, reg16);
243
244 /* Set exit timings for C5/C6. */
245 if (config->c5_enable) {
246 reg8 = pci_read_config8(dev, D31F0_C5_EXIT_TIMING);
247 reg8 &= ~((7 << 3) | (7 << 0));
248 if (config->c6_enable)
249 reg8 |= (5 << 3) | (3 << 0); /* 38-44us PMSYNC# to STPCLK#,
250 95-102us DPRSTP# to STP_CPU# */
251 else
252 reg8 |= (0 << 3) | (1 << 0); /* 16-17us PMSYNC# to STPCLK#,
253 34-40us DPRSTP# to STP_CPU# */
254 pci_write_config8(dev, D31F0_C5_EXIT_TIMING, reg8);
255 }
256
257 // Set the board's GPI routing.
Arthur Heymans349e0852017-04-09 20:48:37 +0200258 i82801jx_gpi_routing(dev);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200259
260 pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
261
262 outl(config->gpe0_en, pmbase + 0x28);
263 outw(config->alt_gp_smi_en, pmbase + 0x38);
264
265 /* Set up power management block and determine sleep mode */
266 reg16 = inw(pmbase + 0x00); /* PM1_STS */
267 outw(reg16, pmbase + 0x00); /* Clear status bits. At least bit11 (power
268 button override) must be cleared or SCI
269 will be constantly fired and OSPM must
270 not know about it (ACPI spec says to
271 ignore the bit). */
272 reg32 = inl(pmbase + 0x04); // PM1_CNT
273 reg32 &= ~(7 << 10); // SLP_TYP
274 outl(reg32, pmbase + 0x04);
275
276 /* Set duty cycle for hardware throttling (defaults to 0x0: 50%). */
277 reg32 = inl(pmbase + 0x10);
278 reg32 &= ~(7 << 5);
279 reg32 |= (config->throttle_duty & 7) << 5;
280 outl(reg32, pmbase + 0x10);
281}
282
Elyes HAOUAS1a8c1df2018-05-13 13:36:44 +0200283static void i82801jx_configure_cstates(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200284{
285 u8 reg8;
286
287 reg8 = pci_read_config8(dev, D31F0_CxSTATE_CNF);
288 reg8 |= (1 << 4) | (1 << 3) | (1 << 2); // Enable Popup & Popdown
289 pci_write_config8(dev, D31F0_CxSTATE_CNF, reg8);
290
291 // Set Deeper Sleep configuration to recommended values
292 reg8 = pci_read_config8(dev, D31F0_C4TIMING_CNT);
293 reg8 &= 0xf0;
294 reg8 |= (2 << 2); // Deeper Sleep to Stop CPU: 34-40us
295 reg8 |= (2 << 0); // Deeper Sleep to Sleep: 15us
296 pci_write_config8(dev, D31F0_C4TIMING_CNT, reg8);
297
298 /* We could enable slow-C4 exit here, if someone needs it? */
299}
300
Arthur Heymans349e0852017-04-09 20:48:37 +0200301static void i82801jx_rtc_init(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200302{
303 u8 reg8;
304 int rtc_failed;
305
306 reg8 = pci_read_config8(dev, D31F0_GEN_PMCON_3);
307 rtc_failed = reg8 & RTC_BATTERY_DEAD;
308 if (rtc_failed) {
309 reg8 &= ~RTC_BATTERY_DEAD;
310 pci_write_config8(dev, D31F0_GEN_PMCON_3, reg8);
311 }
312 printk(BIOS_DEBUG, "rtc_failed = 0x%x\n", rtc_failed);
313
314 cmos_init(rtc_failed);
315}
316
317static void enable_hpet(void)
318{
319 u32 reg32;
320
321 /* Move HPET to default address 0xfed00000 and enable it */
322 reg32 = RCBA32(RCBA_HPTC);
323 reg32 |= (1 << 7); // HPET Address Enable
324 reg32 &= ~(3 << 0);
325 RCBA32(RCBA_HPTC) = reg32;
326}
327
328static void enable_clock_gating(void)
329{
330 u32 reg32;
331
332 /* Enable DMI dynamic clock gating. */
333 RCBA32(RCBA_DMIC) |= 3;
334
335 /* Enable Clock Gating for most devices. */
336 reg32 = RCBA32(RCBA_CG);
337 reg32 |= (1 << 31); /* LPC dynamic clock gating */
338 /* USB UHCI dynamic clock gating: */
339 reg32 |= (1 << 29) | (1 << 28);
340 /* SATA dynamic clock gating [0-3]: */
341 reg32 |= (1 << 27) | (1 << 26) | (1 << 25) | (1 << 24);
342 reg32 |= (1 << 23); /* LAN static clock gating (if LAN disabled) */
343 reg32 |= (1 << 22); /* HD audio dynamic clock gating */
344 reg32 &= ~(1 << 21); /* No HD audio static clock gating */
345 reg32 &= ~(1 << 20); /* No USB EHCI static clock gating */
346 reg32 |= (1 << 19); /* USB EHCI dynamic clock gating */
347 /* More SATA dynamic clock gating [4-5]: */
348 reg32 |= (1 << 18) | (1 << 17);
349 reg32 |= (1 << 16); /* PCI dynamic clock gating */
350 /* PCIe, DMI dynamic clock gating: */
351 reg32 |= (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1);
352 reg32 |= (1 << 0); /* PCIe root port static clock gating */
353 RCBA32(RCBA_CG) = reg32;
354
355 /* Enable SPI dynamic clock gating. */
356 RCBA32(0x38c0) |= 7;
357}
358
Kyösti Mälkki83d6a8a2019-07-12 08:16:53 +0300359static void i82801jx_set_acpi_mode(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200360{
Kyösti Mälkki44da9e72019-10-09 12:32:16 +0300361 if (CONFIG(HAVE_SMI_HANDLER)) {
362 if (!acpi_is_wakeup_s3()) {
363 printk(BIOS_DEBUG, "Disabling ACPI via APMC:\n");
364 outb(APM_CNT_ACPI_DISABLE, APM_CNT); // Disable ACPI mode
365 printk(BIOS_DEBUG, "done.\n");
366 } else {
367 printk(BIOS_DEBUG, "S3 wakeup, enabling ACPI via APMC\n");
368 outb(APM_CNT_ACPI_ENABLE, APM_CNT);
369 }
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200370 }
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200371}
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200372
373static void lpc_init(struct device *dev)
374{
Arthur Heymans349e0852017-04-09 20:48:37 +0200375 printk(BIOS_DEBUG, "i82801jx: lpc_init\n");
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200376
377 /* Set the value for PCI command register. */
378 pci_write_config16(dev, PCI_COMMAND, 0x000f);
379
380 /* IO APIC initialization. */
Arthur Heymans349e0852017-04-09 20:48:37 +0200381 i82801jx_enable_apic(dev);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200382
Arthur Heymans349e0852017-04-09 20:48:37 +0200383 i82801jx_enable_serial_irqs(dev);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200384
385 /* Setup the PIRQ. */
Arthur Heymans349e0852017-04-09 20:48:37 +0200386 i82801jx_pirq_init(dev);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200387
388 /* Setup power options. */
Arthur Heymans349e0852017-04-09 20:48:37 +0200389 i82801jx_power_options(dev);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200390
391 /* Configure Cx state registers */
392 if (LPC_IS_MOBILE(dev))
Arthur Heymans349e0852017-04-09 20:48:37 +0200393 i82801jx_configure_cstates(dev);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200394
395 /* Initialize the real time clock. */
Arthur Heymans349e0852017-04-09 20:48:37 +0200396 i82801jx_rtc_init(dev);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200397
398 /* Initialize ISA DMA. */
399 isa_dma_init();
400
401 /* Initialize the High Precision Event Timers, if present. */
402 enable_hpet();
403
404 /* Initialize Clock Gating */
405 enable_clock_gating();
406
407 setup_i8259();
408
409 /* The OS should do this? */
410 /* Interrupt 9 should be level triggered (SCI) */
411 i8259_configure_irq_trigger(9, 1);
412
Kyösti Mälkki44da9e72019-10-09 12:32:16 +0300413 i82801jx_set_acpi_mode(dev);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200414}
415
Arthur Heymansad501492017-04-12 00:15:39 +0200416unsigned long acpi_fill_madt(unsigned long current)
417{
418 /* Local APICs */
419 current = acpi_create_madt_lapics(current);
420
421 /* IOAPIC */
422 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current,
423 2, IO_APIC_ADDR, 0);
424
425 /* LAPIC_NMI */
426 current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)
427 current, 0,
428 MP_IRQ_POLARITY_HIGH |
429 MP_IRQ_TRIGGER_EDGE, 0x01);
430 current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)
431 current, 1, MP_IRQ_POLARITY_HIGH |
432 MP_IRQ_TRIGGER_EDGE, 0x01);
433
434 /* INT_SRC_OVR */
435 current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
436 current, 0, 0, 2, MP_IRQ_POLARITY_HIGH | MP_IRQ_TRIGGER_EDGE);
437 current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
438 current, 0, 9, 9, MP_IRQ_POLARITY_HIGH | MP_IRQ_TRIGGER_LEVEL);
439
440
441 return current;
442}
443
444void acpi_fill_fadt(acpi_fadt_t *fadt)
445{
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300446 struct device *dev = pcidev_on_root(0x1f, 0);
Arthur Heymansad501492017-04-12 00:15:39 +0200447 config_t *chip = dev->chip_info;
448 u16 pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
449
450 fadt->pm1a_evt_blk = pmbase;
451 fadt->pm1b_evt_blk = 0x0;
452 fadt->pm1a_cnt_blk = pmbase + 0x4;
453 fadt->pm1b_cnt_blk = 0x0;
454 fadt->pm2_cnt_blk = pmbase + 0x50;
455 fadt->pm_tmr_blk = pmbase + 0x8;
456 fadt->gpe0_blk = pmbase + 0x20;
457 fadt->gpe1_blk = 0;
458
459 fadt->pm1_evt_len = 4;
460 fadt->pm1_cnt_len = 2;
461 fadt->pm2_cnt_len = 1;
462 fadt->pm_tmr_len = 4;
463 fadt->gpe0_blk_len = 16;
464 fadt->gpe1_blk_len = 0;
465 fadt->gpe1_base = 0;
466
467 fadt->reset_reg.space_id = 1;
468 fadt->reset_reg.bit_width = 8;
469 fadt->reset_reg.bit_offset = 0;
470 fadt->reset_reg.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
471 fadt->reset_reg.addrl = 0xcf9;
472 fadt->reset_reg.addrh = 0;
473 fadt->reset_value = 6;
474
475 fadt->x_pm1a_evt_blk.space_id = 1;
476 fadt->x_pm1a_evt_blk.bit_width = 32;
477 fadt->x_pm1a_evt_blk.bit_offset = 0;
478 fadt->x_pm1a_evt_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
479 fadt->x_pm1a_evt_blk.addrl = pmbase;
480 fadt->x_pm1a_evt_blk.addrh = 0x0;
481
482 fadt->x_pm1b_evt_blk.space_id = 0;
483 fadt->x_pm1b_evt_blk.bit_width = 0;
484 fadt->x_pm1b_evt_blk.bit_offset = 0;
485 fadt->x_pm1b_evt_blk.access_size = 0;
486 fadt->x_pm1b_evt_blk.addrl = 0x0;
487 fadt->x_pm1b_evt_blk.addrh = 0x0;
488
489 fadt->x_pm1a_cnt_blk.space_id = 1;
490 fadt->x_pm1a_cnt_blk.bit_width = 16;
491 fadt->x_pm1a_cnt_blk.bit_offset = 0;
492 fadt->x_pm1a_cnt_blk.access_size = ACPI_ACCESS_SIZE_WORD_ACCESS;
493 fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4;
494 fadt->x_pm1a_cnt_blk.addrh = 0x0;
495
496 fadt->x_pm1b_cnt_blk.space_id = 0;
497 fadt->x_pm1b_cnt_blk.bit_width = 0;
498 fadt->x_pm1b_cnt_blk.bit_offset = 0;
499 fadt->x_pm1b_cnt_blk.access_size = 0;
500 fadt->x_pm1b_cnt_blk.addrl = 0x0;
501 fadt->x_pm1b_cnt_blk.addrh = 0x0;
502
503 fadt->x_pm2_cnt_blk.space_id = 1;
504 fadt->x_pm2_cnt_blk.bit_width = 8;
505 fadt->x_pm2_cnt_blk.bit_offset = 0;
506 fadt->x_pm2_cnt_blk.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
Arthur Heymans3556ac52018-12-03 00:29:08 +0100507 fadt->x_pm2_cnt_blk.addrl = pmbase + 0x50;
Arthur Heymansad501492017-04-12 00:15:39 +0200508 fadt->x_pm2_cnt_blk.addrh = 0x0;
509
510 fadt->x_pm_tmr_blk.space_id = 1;
511 fadt->x_pm_tmr_blk.bit_width = 32;
512 fadt->x_pm_tmr_blk.bit_offset = 0;
513 fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
514 fadt->x_pm_tmr_blk.addrl = pmbase + 0x8;
515 fadt->x_pm_tmr_blk.addrh = 0x0;
516
517 fadt->x_gpe0_blk.space_id = 1;
518 fadt->x_gpe0_blk.bit_width = 128;
519 fadt->x_gpe0_blk.bit_offset = 0;
520 fadt->x_gpe0_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
521 fadt->x_gpe0_blk.addrl = pmbase + 0x20;
522 fadt->x_gpe0_blk.addrh = 0x0;
523
524 fadt->x_gpe1_blk.space_id = 0;
525 fadt->x_gpe1_blk.bit_width = 0;
526 fadt->x_gpe1_blk.bit_offset = 0;
527 fadt->x_gpe1_blk.access_size = 0;
528 fadt->x_gpe1_blk.addrl = 0x0;
529 fadt->x_gpe1_blk.addrh = 0x0;
530 fadt->day_alrm = 0xd;
531 fadt->mon_alrm = 0x00;
532 fadt->century = 0x32;
533
Elyes HAOUAS0d4de2a2019-02-28 13:04:29 +0100534 fadt->reserved = 0;
Arthur Heymansad501492017-04-12 00:15:39 +0200535 fadt->sci_int = 0x9;
536 fadt->smi_cmd = APM_CNT;
537 fadt->acpi_enable = APM_CNT_ACPI_ENABLE;
538 fadt->acpi_disable = APM_CNT_ACPI_DISABLE;
539 fadt->s4bios_req = 0x0;
540 fadt->pstate_cnt = APM_CNT_PST_CONTROL;
541
542 fadt->cst_cnt = APM_CNT_CST_CONTROL;
543 fadt->p_lvl2_lat = 1;
544 fadt->p_lvl3_lat = chip->c3_latency;
545 fadt->flush_size = 0;
546 fadt->flush_stride = 0;
547 fadt->duty_offset = 1;
548 if (chip->p_cnt_throttling_supported)
549 fadt->duty_width = 3;
550 else
551 fadt->duty_width = 0;
552 fadt->iapc_boot_arch = 0x03;
553 fadt->flags = (ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED
554 | ACPI_FADT_SLEEP_BUTTON | ACPI_FADT_S4_RTC_WAKE
555 | ACPI_FADT_PLATFORM_CLOCK | ACPI_FADT_RESET_REGISTER
556 | ACPI_FADT_C2_MP_SUPPORTED);
557 if (chip->docking_supported)
558 fadt->flags |= ACPI_FADT_DOCKING_SUPPORTED;
559}
560
Elyes HAOUAS1a8c1df2018-05-13 13:36:44 +0200561static void i82801jx_lpc_read_resources(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200562{
Arthur Heymanse5dcaf12017-04-12 00:03:37 +0200563 int i, io_index = 0;
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200564 /*
565 * I/O Resources
566 *
567 * 0x0000 - 0x000f....ISA DMA
568 * 0x0010 - 0x001f....ISA DMA aliases
569 * 0x0020 ~ 0x003d....PIC
570 * 0x002e - 0x002f....Maybe Super I/O
571 * 0x0040 - 0x0043....Timer
572 * 0x004e - 0x004f....Maybe Super I/O
573 * 0x0050 - 0x0053....Timer aliases
574 * 0x0061.............NMI_SC
575 * 0x0070.............NMI_EN (readable in alternative access mode)
576 * 0x0070 - 0x0077....RTC
577 * 0x0080 - 0x008f....ISA DMA
578 * 0x0090 ~ 0x009f....ISA DMA aliases
579 * 0x0092.............Fast A20 and Init
580 * 0x00a0 ~ 0x00bd....PIC
581 * 0x00b2 - 0x00b3....APM
582 * 0x00c0 ~ 0x00de....ISA DMA
583 * 0x00c1 ~ 0x00df....ISA DMA aliases
584 * 0x00f0.............Coprocessor Error
585 * (0x0400-0x041f)....SMBus (SMBUS_IO_BASE, during raminit)
586 * 0x04d0 - 0x04d1....PIC
587 * 0x0500 - 0x057f....PM (DEFAULT_PMBASE)
588 * 0x0580 - 0x05bf....SB GPIO (DEFAULT_GPIOBASE)
589 * 0x05c0 - 0x05ff....SB GPIO cont. (mobile only)
590 * 0x0cf8 - 0x0cff....PCI
591 * 0x0cf9.............Reset Control
592 */
593
594 struct resource *res;
595
596 /* Get the normal PCI resources of this device. */
597 pci_dev_read_resources(dev);
598
599 /* Add an extra subtractive resource for both memory and I/O. */
Arthur Heymanse5dcaf12017-04-12 00:03:37 +0200600 res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200601 res->base = 0;
602 res->size = 0x1000;
603 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
604 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
605
Arthur Heymanse5dcaf12017-04-12 00:03:37 +0200606 res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
607 res->base = 0xff000000;
608 res->size = 0x01000000; /* 16 MB for flash */
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200609 res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
610 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
611
612 res = new_resource(dev, 3); /* IOAPIC */
613 res->base = IO_APIC_ADDR;
614 res->size = 0x00001000;
615 res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
Arthur Heymanse5dcaf12017-04-12 00:03:37 +0200616
617 /* Set IO decode ranges if required.*/
618 for (i = 0; i < 4; i++) {
619 u32 gen_dec;
620 gen_dec = pci_read_config32(dev, 0x84 + 4 * i);
621
622 if ((gen_dec & 0xFFFC) > 0x1000) {
623 res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
624 res->base = gen_dec & 0xFFFC;
625 res->size = (gen_dec >> 16) & 0xFC;
626 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
627 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
628 }
629 }
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200630}
631
Elyes HAOUAS1a8c1df2018-05-13 13:36:44 +0200632static void southbridge_inject_dsdt(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200633{
634 global_nvs_t *gnvs = cbmem_add (CBMEM_ID_ACPI_GNVS, sizeof(*gnvs));
635
636 if (gnvs) {
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200637 memset(gnvs, 0, sizeof(*gnvs));
638 acpi_create_gnvs(gnvs);
639
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200640 /* And tell SMI about it */
641 smm_setup_structures(gnvs, NULL, NULL);
642
643 /* Add it to SSDT. */
644 acpigen_write_scope("\\");
645 acpigen_write_name_dword("NVSA", (u32) gnvs);
646 acpigen_pop_len();
647 }
648}
649
Arthur Heymansa8a9f342017-12-24 08:11:13 +0100650static const char *lpc_acpi_name(const struct device *dev)
651{
652 return "LPCB";
653}
654
Furquan Shaikh7536a392020-04-24 21:59:21 -0700655static void southbridge_fill_ssdt(const struct device *device)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200656{
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300657 struct device *dev = pcidev_on_root(0x1f, 0);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200658 config_t *chip = dev->chip_info;
659
660 intel_acpi_pcie_hotplug_generator(chip->pcie_hotplug_map, 8);
Arthur Heymansa8a9f342017-12-24 08:11:13 +0100661 intel_acpi_gen_def_acpi_pirq(device);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200662}
663
664static struct pci_operations pci_ops = {
Subrata Banik4a0f0712019-03-20 14:29:47 +0530665 .set_subsystem = pci_dev_set_subsystem,
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200666};
667
668static struct device_operations device_ops = {
Arthur Heymans349e0852017-04-09 20:48:37 +0200669 .read_resources = i82801jx_lpc_read_resources,
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200670 .set_resources = pci_dev_set_resources,
671 .enable_resources = pci_dev_enable_resources,
Nico Huber68680dd2020-03-31 17:34:52 +0200672 .acpi_inject_dsdt = southbridge_inject_dsdt,
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200673 .write_acpi_tables = acpi_write_hpet,
Nico Huber68680dd2020-03-31 17:34:52 +0200674 .acpi_fill_ssdt = southbridge_fill_ssdt,
Arthur Heymansa8a9f342017-12-24 08:11:13 +0100675 .acpi_name = lpc_acpi_name,
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200676 .init = lpc_init,
Nico Huber51b75ae2019-03-14 16:02:05 +0100677 .scan_bus = scan_static_bus,
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200678 .ops_pci = &pci_ops,
679};
680
681static const unsigned short pci_device_ids[] = {
Arthur Heymans349e0852017-04-09 20:48:37 +0200682 0x3a10, /* ICH10R Eng. Sample */
683 0x3a14, /* ICH10DO */
684 0x3a16, /* ICH10R */
685 0x3a18, /* ICH10 */
686 0x3a1a, /* ICH10D */
687 0x3a1e, /* ICH10 Eng. Sample */
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200688 0
689};
690
Arthur Heymans349e0852017-04-09 20:48:37 +0200691static const struct pci_driver ich10_lpc __pci_driver = {
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200692 .ops = &device_ops,
693 .vendor = PCI_VENDOR_ID_INTEL,
694 .devices = pci_device_ids,
695};