blob: a594452e043c9896bc5b4fcd793316b9ebd759af [file] [log] [blame]
Arthur Heymans7b9c1392017-04-09 20:40:39 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2008-2009 coresystems GmbH
5 * 2012 secunet Security Networks AG
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; version 2 of
10 * the License.
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
18#include <console/console.h>
19#include <device/device.h>
20#include <device/pci.h>
21#include <device/pci_ids.h>
22#include <pc80/mc146818rtc.h>
23#include <pc80/isa-dma.h>
24#include <pc80/i8259.h>
25#include <arch/io.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020026#include <device/pci_ops.h>
Arthur Heymans7b9c1392017-04-09 20:40:39 +020027#include <arch/ioapic.h>
28#include <arch/acpi.h>
Arthur Heymans7b9c1392017-04-09 20:40:39 +020029#include <cpu/x86/smm.h>
30#include <arch/acpigen.h>
Arthur Heymansad501492017-04-12 00:15:39 +020031#include <arch/smp/mpspec.h>
Arthur Heymans7b9c1392017-04-09 20:40:39 +020032#include <cbmem.h>
33#include <string.h>
Kyösti Mälkki12b121c2019-08-18 16:33:39 +030034#include "chip.h"
Arthur Heymans349e0852017-04-09 20:48:37 +020035#include "i82801jx.h"
Arthur Heymans7b9c1392017-04-09 20:40:39 +020036#include "nvs.h"
37#include <southbridge/intel/common/pciehp.h>
Arthur Heymansa8a9f342017-12-24 08:11:13 +010038#include <southbridge/intel/common/acpi_pirq_gen.h>
Arthur Heymans7b9c1392017-04-09 20:40:39 +020039#include <drivers/intel/gma/i915.h>
40
41#define NMI_OFF 0
42
Arthur Heymans349e0852017-04-09 20:48:37 +020043typedef struct southbridge_intel_i82801jx_config config_t;
Arthur Heymans7b9c1392017-04-09 20:40:39 +020044
Arthur Heymans349e0852017-04-09 20:48:37 +020045static void i82801jx_enable_apic(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +020046{
47 u32 reg32;
48 volatile u32 *ioapic_index = (volatile u32 *)(IO_APIC_ADDR);
49 volatile u32 *ioapic_data = (volatile u32 *)(IO_APIC_ADDR + 0x10);
50
51 /* Enable IOAPIC. Keep APIC Range Select at zero. */
52 RCBA8(0x31ff) = 0x03;
53 /* We have to read 0x31ff back if bit0 changed. */
54 RCBA8(0x31ff);
55
56 /* Lock maximum redirection entries (MRE), R/WO register. */
57 *ioapic_index = 0x01;
58 reg32 = *ioapic_data;
59 *ioapic_index = 0x01;
60 *ioapic_data = reg32;
61
62 setup_ioapic(VIO_APIC_VADDR, 2); /* ICH7 code uses id 2. */
63}
64
Arthur Heymans349e0852017-04-09 20:48:37 +020065static void i82801jx_enable_serial_irqs(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +020066{
67 /* Set packet length and toggle silent mode bit for one frame. */
68 pci_write_config8(dev, D31F0_SERIRQ_CNTL,
69 (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
70}
71
72/* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
73 * 0x00 - 0000 = Reserved
74 * 0x01 - 0001 = Reserved
75 * 0x02 - 0010 = Reserved
76 * 0x03 - 0011 = IRQ3
77 * 0x04 - 0100 = IRQ4
78 * 0x05 - 0101 = IRQ5
79 * 0x06 - 0110 = IRQ6
80 * 0x07 - 0111 = IRQ7
81 * 0x08 - 1000 = Reserved
82 * 0x09 - 1001 = IRQ9
83 * 0x0A - 1010 = IRQ10
84 * 0x0B - 1011 = IRQ11
85 * 0x0C - 1100 = IRQ12
86 * 0x0D - 1101 = Reserved
87 * 0x0E - 1110 = IRQ14
88 * 0x0F - 1111 = IRQ15
89 * PIRQ[n]_ROUT[7] - PIRQ Routing Control
90 * 0x80 - The PIRQ is not routed.
91 */
92
Elyes HAOUAS1a8c1df2018-05-13 13:36:44 +020093static void i82801jx_pirq_init(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +020094{
Elyes HAOUAS1a8c1df2018-05-13 13:36:44 +020095 struct device *irq_dev;
Arthur Heymans7b9c1392017-04-09 20:40:39 +020096
Arthur Heymans87af36a2017-04-12 10:53:30 +020097 /* Interrupt 11 is not used by legacy devices and so can always be used
98 * for PCI interrupts. Full legacy IRQ routing is complicated and hard
99 * to get right. Fortunately all modern OS use MSI and so it's not that
100 * big of an issue anyway. Still we have to provide a reasonable
101 * default. Using interrupt 11 for it everywhere is a working default.
102 * ACPI-aware OS can move it to any interrupt and others will just leave
103 * them at default.
104 */
105 const u8 pirq_routing = 11;
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200106
Arthur Heymans87af36a2017-04-12 10:53:30 +0200107 pci_write_config8(dev, D31F0_PIRQA_ROUT, pirq_routing);
108 pci_write_config8(dev, D31F0_PIRQB_ROUT, pirq_routing);
109 pci_write_config8(dev, D31F0_PIRQC_ROUT, pirq_routing);
110 pci_write_config8(dev, D31F0_PIRQD_ROUT, pirq_routing);
111
112 pci_write_config8(dev, D31F0_PIRQE_ROUT, pirq_routing);
113 pci_write_config8(dev, D31F0_PIRQF_ROUT, pirq_routing);
114 pci_write_config8(dev, D31F0_PIRQG_ROUT, pirq_routing);
115 pci_write_config8(dev, D31F0_PIRQH_ROUT, pirq_routing);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200116
117 /* Eric Biederman once said we should let the OS do this.
118 * I am not so sure anymore he was right.
119 */
120
121 for (irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) {
Arthur Heymans87af36a2017-04-12 10:53:30 +0200122 u8 int_pin = 0;
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200123
124 if (!irq_dev->enabled || irq_dev->path.type != DEVICE_PATH_PCI)
125 continue;
126
127 int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN);
128
Arthur Heymans87af36a2017-04-12 10:53:30 +0200129 if (int_pin == 0)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200130 continue;
131
Arthur Heymans87af36a2017-04-12 10:53:30 +0200132 pci_write_config8(irq_dev, PCI_INTERRUPT_LINE, pirq_routing);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200133 }
134}
135
Elyes HAOUAS1a8c1df2018-05-13 13:36:44 +0200136static void i82801jx_gpi_routing(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200137{
138 /* Get the chip configuration */
139 config_t *config = dev->chip_info;
140 u32 reg32 = 0;
141
142 /* An array would be much nicer here, or some
143 * other method of doing this.
144 */
145 reg32 |= (config->gpi0_routing & 0x03) << 0;
146 reg32 |= (config->gpi1_routing & 0x03) << 2;
147 reg32 |= (config->gpi2_routing & 0x03) << 4;
148 reg32 |= (config->gpi3_routing & 0x03) << 6;
149 reg32 |= (config->gpi4_routing & 0x03) << 8;
150 reg32 |= (config->gpi5_routing & 0x03) << 10;
151 reg32 |= (config->gpi6_routing & 0x03) << 12;
152 reg32 |= (config->gpi7_routing & 0x03) << 14;
153 reg32 |= (config->gpi8_routing & 0x03) << 16;
154 reg32 |= (config->gpi9_routing & 0x03) << 18;
155 reg32 |= (config->gpi10_routing & 0x03) << 20;
156 reg32 |= (config->gpi11_routing & 0x03) << 22;
157 reg32 |= (config->gpi12_routing & 0x03) << 24;
158 reg32 |= (config->gpi13_routing & 0x03) << 26;
159 reg32 |= (config->gpi14_routing & 0x03) << 28;
160 reg32 |= (config->gpi15_routing & 0x03) << 30;
161
162 pci_write_config32(dev, D31F0_GPIO_ROUT, reg32);
163}
164
Elyes HAOUAS1a8c1df2018-05-13 13:36:44 +0200165static void i82801jx_power_options(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200166{
167 u8 reg8;
168 u16 reg16, pmbase;
169 u32 reg32;
170 const char *state;
171 /* Get the chip configuration */
172 config_t *config = dev->chip_info;
173
Nico Huber9faae2b2018-11-14 00:00:35 +0100174 int pwr_on = CONFIG_MAINBOARD_POWER_FAILURE_STATE;
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200175 int nmi_option;
176
177 /* BIOS must program... */
178 reg32 = pci_read_config32(dev, 0xac);
179 pci_write_config32(dev, 0xac, reg32 | (1 << 30) | (3 << 8));
180
181 /* Which state do we want to goto after g3 (power restored)?
182 * 0 == S0 Full On
183 * 1 == S5 Soft Off
184 *
185 * If the option is not existent (Laptops), use MAINBOARD_POWER_ON.
186 */
187 pwr_on = MAINBOARD_POWER_ON;
188 get_option(&pwr_on, "power_on_after_fail");
189
190 reg8 = pci_read_config8(dev, D31F0_GEN_PMCON_3);
191 reg8 &= 0xfe;
192 switch (pwr_on) {
193 case MAINBOARD_POWER_OFF:
194 reg8 |= 1;
195 state = "off";
196 break;
197 case MAINBOARD_POWER_ON:
198 reg8 &= ~1;
199 state = "on";
200 break;
201 case MAINBOARD_POWER_KEEP:
202 reg8 &= ~1;
203 state = "state keep";
204 break;
205 default:
206 state = "undefined";
207 }
208
209 reg8 |= (3 << 4); /* avoid #S4 assertions */
210 reg8 &= ~(1 << 3); /* minimum asssertion is 1 to 2 RTCCLK */
211
212 pci_write_config8(dev, D31F0_GEN_PMCON_3, reg8);
213 printk(BIOS_INFO, "Set power %s after power failure.\n", state);
214
215 /* Set up NMI on errors. */
216 reg8 = inb(0x61);
217 reg8 &= 0x0f; /* Higher Nibble must be 0 */
218 reg8 &= ~(1 << 3); /* IOCHK# NMI Enable */
219 // reg8 &= ~(1 << 2); /* PCI SERR# Enable */
220 reg8 |= (1 << 2); /* PCI SERR# Disable for now */
221 outb(reg8, 0x61);
222
223 reg8 = inb(0x74); /* Read from 0x74 as 0x70 is write only. */
224 nmi_option = NMI_OFF;
225 get_option(&nmi_option, "nmi");
226 if (nmi_option) {
227 printk(BIOS_INFO, "NMI sources enabled.\n");
228 reg8 &= ~(1 << 7); /* Set NMI. */
229 } else {
230 printk(BIOS_INFO, "NMI sources disabled.\n");
Elyes HAOUAS9c5d4632018-04-26 22:21:21 +0200231 reg8 |= (1 << 7); /* Can't mask NMI from PCI-E and NMI_NOW */
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200232 }
233 outb(reg8, 0x70);
234
235 /* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */
236 reg16 = pci_read_config16(dev, D31F0_GEN_PMCON_1);
237 reg16 &= ~(3 << 0); // SMI# rate 1 minute
238 reg16 |= (1 << 2); // CLKRUN_EN - Mobile/Ultra only
239 reg16 |= (1 << 3); // Speedstep Enable - Mobile/Ultra only
240 reg16 |= (1 << 5); // CPUSLP_EN Desktop only
241
242 if (config->c4onc3_enable)
243 reg16 |= (1 << 7);
244
245 // another laptop wants this?
246 // reg16 &= ~(1 << 10); // BIOS_PCI_EXP_EN - Desktop/Mobile only
247 reg16 |= (1 << 10); // BIOS_PCI_EXP_EN - Desktop/Mobile only
248#if DEBUG_PERIODIC_SMIS
Arthur Heymans349e0852017-04-09 20:48:37 +0200249 /* Set DEBUG_PERIODIC_SMIS in i82801jx.h to debug using
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200250 * periodic SMIs.
251 */
252 reg16 |= (3 << 0); // Periodic SMI every 8s
253#endif
254 if (config->c5_enable)
255 reg16 |= (1 << 11); /* Enable C5, C6 and PMSYNC# */
256 pci_write_config16(dev, D31F0_GEN_PMCON_1, reg16);
257
258 /* Set exit timings for C5/C6. */
259 if (config->c5_enable) {
260 reg8 = pci_read_config8(dev, D31F0_C5_EXIT_TIMING);
261 reg8 &= ~((7 << 3) | (7 << 0));
262 if (config->c6_enable)
263 reg8 |= (5 << 3) | (3 << 0); /* 38-44us PMSYNC# to STPCLK#,
264 95-102us DPRSTP# to STP_CPU# */
265 else
266 reg8 |= (0 << 3) | (1 << 0); /* 16-17us PMSYNC# to STPCLK#,
267 34-40us DPRSTP# to STP_CPU# */
268 pci_write_config8(dev, D31F0_C5_EXIT_TIMING, reg8);
269 }
270
271 // Set the board's GPI routing.
Arthur Heymans349e0852017-04-09 20:48:37 +0200272 i82801jx_gpi_routing(dev);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200273
274 pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
275
276 outl(config->gpe0_en, pmbase + 0x28);
277 outw(config->alt_gp_smi_en, pmbase + 0x38);
278
279 /* Set up power management block and determine sleep mode */
280 reg16 = inw(pmbase + 0x00); /* PM1_STS */
281 outw(reg16, pmbase + 0x00); /* Clear status bits. At least bit11 (power
282 button override) must be cleared or SCI
283 will be constantly fired and OSPM must
284 not know about it (ACPI spec says to
285 ignore the bit). */
286 reg32 = inl(pmbase + 0x04); // PM1_CNT
287 reg32 &= ~(7 << 10); // SLP_TYP
288 outl(reg32, pmbase + 0x04);
289
290 /* Set duty cycle for hardware throttling (defaults to 0x0: 50%). */
291 reg32 = inl(pmbase + 0x10);
292 reg32 &= ~(7 << 5);
293 reg32 |= (config->throttle_duty & 7) << 5;
294 outl(reg32, pmbase + 0x10);
295}
296
Elyes HAOUAS1a8c1df2018-05-13 13:36:44 +0200297static void i82801jx_configure_cstates(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200298{
299 u8 reg8;
300
301 reg8 = pci_read_config8(dev, D31F0_CxSTATE_CNF);
302 reg8 |= (1 << 4) | (1 << 3) | (1 << 2); // Enable Popup & Popdown
303 pci_write_config8(dev, D31F0_CxSTATE_CNF, reg8);
304
305 // Set Deeper Sleep configuration to recommended values
306 reg8 = pci_read_config8(dev, D31F0_C4TIMING_CNT);
307 reg8 &= 0xf0;
308 reg8 |= (2 << 2); // Deeper Sleep to Stop CPU: 34-40us
309 reg8 |= (2 << 0); // Deeper Sleep to Sleep: 15us
310 pci_write_config8(dev, D31F0_C4TIMING_CNT, reg8);
311
312 /* We could enable slow-C4 exit here, if someone needs it? */
313}
314
Arthur Heymans349e0852017-04-09 20:48:37 +0200315static void i82801jx_rtc_init(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200316{
317 u8 reg8;
318 int rtc_failed;
319
320 reg8 = pci_read_config8(dev, D31F0_GEN_PMCON_3);
321 rtc_failed = reg8 & RTC_BATTERY_DEAD;
322 if (rtc_failed) {
323 reg8 &= ~RTC_BATTERY_DEAD;
324 pci_write_config8(dev, D31F0_GEN_PMCON_3, reg8);
325 }
326 printk(BIOS_DEBUG, "rtc_failed = 0x%x\n", rtc_failed);
327
328 cmos_init(rtc_failed);
329}
330
331static void enable_hpet(void)
332{
333 u32 reg32;
334
335 /* Move HPET to default address 0xfed00000 and enable it */
336 reg32 = RCBA32(RCBA_HPTC);
337 reg32 |= (1 << 7); // HPET Address Enable
338 reg32 &= ~(3 << 0);
339 RCBA32(RCBA_HPTC) = reg32;
340}
341
342static void enable_clock_gating(void)
343{
344 u32 reg32;
345
346 /* Enable DMI dynamic clock gating. */
347 RCBA32(RCBA_DMIC) |= 3;
348
349 /* Enable Clock Gating for most devices. */
350 reg32 = RCBA32(RCBA_CG);
351 reg32 |= (1 << 31); /* LPC dynamic clock gating */
352 /* USB UHCI dynamic clock gating: */
353 reg32 |= (1 << 29) | (1 << 28);
354 /* SATA dynamic clock gating [0-3]: */
355 reg32 |= (1 << 27) | (1 << 26) | (1 << 25) | (1 << 24);
356 reg32 |= (1 << 23); /* LAN static clock gating (if LAN disabled) */
357 reg32 |= (1 << 22); /* HD audio dynamic clock gating */
358 reg32 &= ~(1 << 21); /* No HD audio static clock gating */
359 reg32 &= ~(1 << 20); /* No USB EHCI static clock gating */
360 reg32 |= (1 << 19); /* USB EHCI dynamic clock gating */
361 /* More SATA dynamic clock gating [4-5]: */
362 reg32 |= (1 << 18) | (1 << 17);
363 reg32 |= (1 << 16); /* PCI dynamic clock gating */
364 /* PCIe, DMI dynamic clock gating: */
365 reg32 |= (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1);
366 reg32 |= (1 << 0); /* PCIe root port static clock gating */
367 RCBA32(RCBA_CG) = reg32;
368
369 /* Enable SPI dynamic clock gating. */
370 RCBA32(0x38c0) |= 7;
371}
372
Kyösti Mälkki83d6a8a2019-07-12 08:16:53 +0300373static void i82801jx_set_acpi_mode(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200374{
Kyösti Mälkki44da9e72019-10-09 12:32:16 +0300375 if (CONFIG(HAVE_SMI_HANDLER)) {
376 if (!acpi_is_wakeup_s3()) {
377 printk(BIOS_DEBUG, "Disabling ACPI via APMC:\n");
378 outb(APM_CNT_ACPI_DISABLE, APM_CNT); // Disable ACPI mode
379 printk(BIOS_DEBUG, "done.\n");
380 } else {
381 printk(BIOS_DEBUG, "S3 wakeup, enabling ACPI via APMC\n");
382 outb(APM_CNT_ACPI_ENABLE, APM_CNT);
383 }
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200384 }
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200385}
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200386
387static void lpc_init(struct device *dev)
388{
Arthur Heymans349e0852017-04-09 20:48:37 +0200389 printk(BIOS_DEBUG, "i82801jx: lpc_init\n");
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200390
391 /* Set the value for PCI command register. */
392 pci_write_config16(dev, PCI_COMMAND, 0x000f);
393
394 /* IO APIC initialization. */
Arthur Heymans349e0852017-04-09 20:48:37 +0200395 i82801jx_enable_apic(dev);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200396
Arthur Heymans349e0852017-04-09 20:48:37 +0200397 i82801jx_enable_serial_irqs(dev);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200398
399 /* Setup the PIRQ. */
Arthur Heymans349e0852017-04-09 20:48:37 +0200400 i82801jx_pirq_init(dev);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200401
402 /* Setup power options. */
Arthur Heymans349e0852017-04-09 20:48:37 +0200403 i82801jx_power_options(dev);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200404
405 /* Configure Cx state registers */
406 if (LPC_IS_MOBILE(dev))
Arthur Heymans349e0852017-04-09 20:48:37 +0200407 i82801jx_configure_cstates(dev);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200408
409 /* Initialize the real time clock. */
Arthur Heymans349e0852017-04-09 20:48:37 +0200410 i82801jx_rtc_init(dev);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200411
412 /* Initialize ISA DMA. */
413 isa_dma_init();
414
415 /* Initialize the High Precision Event Timers, if present. */
416 enable_hpet();
417
418 /* Initialize Clock Gating */
419 enable_clock_gating();
420
421 setup_i8259();
422
423 /* The OS should do this? */
424 /* Interrupt 9 should be level triggered (SCI) */
425 i8259_configure_irq_trigger(9, 1);
426
Kyösti Mälkki44da9e72019-10-09 12:32:16 +0300427 i82801jx_set_acpi_mode(dev);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200428}
429
Arthur Heymansad501492017-04-12 00:15:39 +0200430unsigned long acpi_fill_madt(unsigned long current)
431{
432 /* Local APICs */
433 current = acpi_create_madt_lapics(current);
434
435 /* IOAPIC */
436 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current,
437 2, IO_APIC_ADDR, 0);
438
439 /* LAPIC_NMI */
440 current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)
441 current, 0,
442 MP_IRQ_POLARITY_HIGH |
443 MP_IRQ_TRIGGER_EDGE, 0x01);
444 current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)
445 current, 1, MP_IRQ_POLARITY_HIGH |
446 MP_IRQ_TRIGGER_EDGE, 0x01);
447
448 /* INT_SRC_OVR */
449 current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
450 current, 0, 0, 2, MP_IRQ_POLARITY_HIGH | MP_IRQ_TRIGGER_EDGE);
451 current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
452 current, 0, 9, 9, MP_IRQ_POLARITY_HIGH | MP_IRQ_TRIGGER_LEVEL);
453
454
455 return current;
456}
457
458void acpi_fill_fadt(acpi_fadt_t *fadt)
459{
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300460 struct device *dev = pcidev_on_root(0x1f, 0);
Arthur Heymansad501492017-04-12 00:15:39 +0200461 config_t *chip = dev->chip_info;
462 u16 pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
463
464 fadt->pm1a_evt_blk = pmbase;
465 fadt->pm1b_evt_blk = 0x0;
466 fadt->pm1a_cnt_blk = pmbase + 0x4;
467 fadt->pm1b_cnt_blk = 0x0;
468 fadt->pm2_cnt_blk = pmbase + 0x50;
469 fadt->pm_tmr_blk = pmbase + 0x8;
470 fadt->gpe0_blk = pmbase + 0x20;
471 fadt->gpe1_blk = 0;
472
473 fadt->pm1_evt_len = 4;
474 fadt->pm1_cnt_len = 2;
475 fadt->pm2_cnt_len = 1;
476 fadt->pm_tmr_len = 4;
477 fadt->gpe0_blk_len = 16;
478 fadt->gpe1_blk_len = 0;
479 fadt->gpe1_base = 0;
480
481 fadt->reset_reg.space_id = 1;
482 fadt->reset_reg.bit_width = 8;
483 fadt->reset_reg.bit_offset = 0;
484 fadt->reset_reg.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
485 fadt->reset_reg.addrl = 0xcf9;
486 fadt->reset_reg.addrh = 0;
487 fadt->reset_value = 6;
488
489 fadt->x_pm1a_evt_blk.space_id = 1;
490 fadt->x_pm1a_evt_blk.bit_width = 32;
491 fadt->x_pm1a_evt_blk.bit_offset = 0;
492 fadt->x_pm1a_evt_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
493 fadt->x_pm1a_evt_blk.addrl = pmbase;
494 fadt->x_pm1a_evt_blk.addrh = 0x0;
495
496 fadt->x_pm1b_evt_blk.space_id = 0;
497 fadt->x_pm1b_evt_blk.bit_width = 0;
498 fadt->x_pm1b_evt_blk.bit_offset = 0;
499 fadt->x_pm1b_evt_blk.access_size = 0;
500 fadt->x_pm1b_evt_blk.addrl = 0x0;
501 fadt->x_pm1b_evt_blk.addrh = 0x0;
502
503 fadt->x_pm1a_cnt_blk.space_id = 1;
504 fadt->x_pm1a_cnt_blk.bit_width = 16;
505 fadt->x_pm1a_cnt_blk.bit_offset = 0;
506 fadt->x_pm1a_cnt_blk.access_size = ACPI_ACCESS_SIZE_WORD_ACCESS;
507 fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4;
508 fadt->x_pm1a_cnt_blk.addrh = 0x0;
509
510 fadt->x_pm1b_cnt_blk.space_id = 0;
511 fadt->x_pm1b_cnt_blk.bit_width = 0;
512 fadt->x_pm1b_cnt_blk.bit_offset = 0;
513 fadt->x_pm1b_cnt_blk.access_size = 0;
514 fadt->x_pm1b_cnt_blk.addrl = 0x0;
515 fadt->x_pm1b_cnt_blk.addrh = 0x0;
516
517 fadt->x_pm2_cnt_blk.space_id = 1;
518 fadt->x_pm2_cnt_blk.bit_width = 8;
519 fadt->x_pm2_cnt_blk.bit_offset = 0;
520 fadt->x_pm2_cnt_blk.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
Arthur Heymans3556ac52018-12-03 00:29:08 +0100521 fadt->x_pm2_cnt_blk.addrl = pmbase + 0x50;
Arthur Heymansad501492017-04-12 00:15:39 +0200522 fadt->x_pm2_cnt_blk.addrh = 0x0;
523
524 fadt->x_pm_tmr_blk.space_id = 1;
525 fadt->x_pm_tmr_blk.bit_width = 32;
526 fadt->x_pm_tmr_blk.bit_offset = 0;
527 fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
528 fadt->x_pm_tmr_blk.addrl = pmbase + 0x8;
529 fadt->x_pm_tmr_blk.addrh = 0x0;
530
531 fadt->x_gpe0_blk.space_id = 1;
532 fadt->x_gpe0_blk.bit_width = 128;
533 fadt->x_gpe0_blk.bit_offset = 0;
534 fadt->x_gpe0_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
535 fadt->x_gpe0_blk.addrl = pmbase + 0x20;
536 fadt->x_gpe0_blk.addrh = 0x0;
537
538 fadt->x_gpe1_blk.space_id = 0;
539 fadt->x_gpe1_blk.bit_width = 0;
540 fadt->x_gpe1_blk.bit_offset = 0;
541 fadt->x_gpe1_blk.access_size = 0;
542 fadt->x_gpe1_blk.addrl = 0x0;
543 fadt->x_gpe1_blk.addrh = 0x0;
544 fadt->day_alrm = 0xd;
545 fadt->mon_alrm = 0x00;
546 fadt->century = 0x32;
547
Elyes HAOUAS0d4de2a2019-02-28 13:04:29 +0100548 fadt->reserved = 0;
Arthur Heymansad501492017-04-12 00:15:39 +0200549 fadt->sci_int = 0x9;
550 fadt->smi_cmd = APM_CNT;
551 fadt->acpi_enable = APM_CNT_ACPI_ENABLE;
552 fadt->acpi_disable = APM_CNT_ACPI_DISABLE;
553 fadt->s4bios_req = 0x0;
554 fadt->pstate_cnt = APM_CNT_PST_CONTROL;
555
556 fadt->cst_cnt = APM_CNT_CST_CONTROL;
557 fadt->p_lvl2_lat = 1;
558 fadt->p_lvl3_lat = chip->c3_latency;
559 fadt->flush_size = 0;
560 fadt->flush_stride = 0;
561 fadt->duty_offset = 1;
562 if (chip->p_cnt_throttling_supported)
563 fadt->duty_width = 3;
564 else
565 fadt->duty_width = 0;
566 fadt->iapc_boot_arch = 0x03;
567 fadt->flags = (ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED
568 | ACPI_FADT_SLEEP_BUTTON | ACPI_FADT_S4_RTC_WAKE
569 | ACPI_FADT_PLATFORM_CLOCK | ACPI_FADT_RESET_REGISTER
570 | ACPI_FADT_C2_MP_SUPPORTED);
571 if (chip->docking_supported)
572 fadt->flags |= ACPI_FADT_DOCKING_SUPPORTED;
573}
574
Elyes HAOUAS1a8c1df2018-05-13 13:36:44 +0200575static void i82801jx_lpc_read_resources(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200576{
Arthur Heymanse5dcaf12017-04-12 00:03:37 +0200577 int i, io_index = 0;
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200578 /*
579 * I/O Resources
580 *
581 * 0x0000 - 0x000f....ISA DMA
582 * 0x0010 - 0x001f....ISA DMA aliases
583 * 0x0020 ~ 0x003d....PIC
584 * 0x002e - 0x002f....Maybe Super I/O
585 * 0x0040 - 0x0043....Timer
586 * 0x004e - 0x004f....Maybe Super I/O
587 * 0x0050 - 0x0053....Timer aliases
588 * 0x0061.............NMI_SC
589 * 0x0070.............NMI_EN (readable in alternative access mode)
590 * 0x0070 - 0x0077....RTC
591 * 0x0080 - 0x008f....ISA DMA
592 * 0x0090 ~ 0x009f....ISA DMA aliases
593 * 0x0092.............Fast A20 and Init
594 * 0x00a0 ~ 0x00bd....PIC
595 * 0x00b2 - 0x00b3....APM
596 * 0x00c0 ~ 0x00de....ISA DMA
597 * 0x00c1 ~ 0x00df....ISA DMA aliases
598 * 0x00f0.............Coprocessor Error
599 * (0x0400-0x041f)....SMBus (SMBUS_IO_BASE, during raminit)
600 * 0x04d0 - 0x04d1....PIC
601 * 0x0500 - 0x057f....PM (DEFAULT_PMBASE)
602 * 0x0580 - 0x05bf....SB GPIO (DEFAULT_GPIOBASE)
603 * 0x05c0 - 0x05ff....SB GPIO cont. (mobile only)
604 * 0x0cf8 - 0x0cff....PCI
605 * 0x0cf9.............Reset Control
606 */
607
608 struct resource *res;
609
610 /* Get the normal PCI resources of this device. */
611 pci_dev_read_resources(dev);
612
613 /* Add an extra subtractive resource for both memory and I/O. */
Arthur Heymanse5dcaf12017-04-12 00:03:37 +0200614 res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200615 res->base = 0;
616 res->size = 0x1000;
617 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
618 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
619
Arthur Heymanse5dcaf12017-04-12 00:03:37 +0200620 res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
621 res->base = 0xff000000;
622 res->size = 0x01000000; /* 16 MB for flash */
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200623 res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
624 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
625
626 res = new_resource(dev, 3); /* IOAPIC */
627 res->base = IO_APIC_ADDR;
628 res->size = 0x00001000;
629 res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
Arthur Heymanse5dcaf12017-04-12 00:03:37 +0200630
631 /* Set IO decode ranges if required.*/
632 for (i = 0; i < 4; i++) {
633 u32 gen_dec;
634 gen_dec = pci_read_config32(dev, 0x84 + 4 * i);
635
636 if ((gen_dec & 0xFFFC) > 0x1000) {
637 res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
638 res->base = gen_dec & 0xFFFC;
639 res->size = (gen_dec >> 16) & 0xFC;
640 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
641 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
642 }
643 }
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200644}
645
Elyes HAOUAS1a8c1df2018-05-13 13:36:44 +0200646static void southbridge_inject_dsdt(struct device *dev)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200647{
648 global_nvs_t *gnvs = cbmem_add (CBMEM_ID_ACPI_GNVS, sizeof(*gnvs));
649
650 if (gnvs) {
651 const struct i915_gpu_controller_info *gfx = intel_gma_get_controller_info();
652 memset(gnvs, 0, sizeof(*gnvs));
653 acpi_create_gnvs(gnvs);
654
Nico Huber744d6bd2019-01-12 14:58:20 +0100655 if (gfx) {
656 gnvs->ndid = gfx->ndid;
657 memcpy(gnvs->did, gfx->did, sizeof(gnvs->did));
658 }
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200659
660 /* And tell SMI about it */
661 smm_setup_structures(gnvs, NULL, NULL);
662
663 /* Add it to SSDT. */
664 acpigen_write_scope("\\");
665 acpigen_write_name_dword("NVSA", (u32) gnvs);
666 acpigen_pop_len();
667 }
668}
669
Arthur Heymansa8a9f342017-12-24 08:11:13 +0100670static const char *lpc_acpi_name(const struct device *dev)
671{
672 return "LPCB";
673}
674
Elyes HAOUAS1a8c1df2018-05-13 13:36:44 +0200675static void southbridge_fill_ssdt(struct device *device)
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200676{
Kyösti Mälkkic70eed12018-05-22 02:18:00 +0300677 struct device *dev = pcidev_on_root(0x1f, 0);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200678 config_t *chip = dev->chip_info;
679
680 intel_acpi_pcie_hotplug_generator(chip->pcie_hotplug_map, 8);
Arthur Heymansa8a9f342017-12-24 08:11:13 +0100681 intel_acpi_gen_def_acpi_pirq(device);
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200682}
683
684static struct pci_operations pci_ops = {
Subrata Banik4a0f0712019-03-20 14:29:47 +0530685 .set_subsystem = pci_dev_set_subsystem,
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200686};
687
688static struct device_operations device_ops = {
Arthur Heymans349e0852017-04-09 20:48:37 +0200689 .read_resources = i82801jx_lpc_read_resources,
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200690 .set_resources = pci_dev_set_resources,
691 .enable_resources = pci_dev_enable_resources,
692 .acpi_inject_dsdt_generator = southbridge_inject_dsdt,
693 .write_acpi_tables = acpi_write_hpet,
694 .acpi_fill_ssdt_generator = southbridge_fill_ssdt,
Arthur Heymansa8a9f342017-12-24 08:11:13 +0100695 .acpi_name = lpc_acpi_name,
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200696 .init = lpc_init,
Nico Huber51b75ae2019-03-14 16:02:05 +0100697 .scan_bus = scan_static_bus,
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200698 .ops_pci = &pci_ops,
699};
700
701static const unsigned short pci_device_ids[] = {
Arthur Heymans349e0852017-04-09 20:48:37 +0200702 0x3a10, /* ICH10R Eng. Sample */
703 0x3a14, /* ICH10DO */
704 0x3a16, /* ICH10R */
705 0x3a18, /* ICH10 */
706 0x3a1a, /* ICH10D */
707 0x3a1e, /* ICH10 Eng. Sample */
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200708 0
709};
710
Arthur Heymans349e0852017-04-09 20:48:37 +0200711static const struct pci_driver ich10_lpc __pci_driver = {
Arthur Heymans7b9c1392017-04-09 20:40:39 +0200712 .ops = &device_ops,
713 .vendor = PCI_VENDOR_ID_INTEL,
714 .devices = pci_device_ids,
715};