blob: 5d7b73d1a68130bfd1466f6ec374b5104e2fc49f [file] [log] [blame]
Marc Jones24484842017-05-04 21:17:45 -06001/*
2 * This file is part of the coreboot project.
3 *
Richard Spiegel376dc822017-12-01 08:24:26 -07004 * Copyright (C) 2010-2017 Advanced Micro Devices, Inc.
Marc Jones24484842017-05-04 21:17:45 -06005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <console/console.h>
17
18#include <arch/io.h>
Marshall Dawson8a906df2017-06-13 14:19:02 -060019#include <bootstate.h>
Marshall Dawsone9b862e2017-09-22 15:14:46 -060020#include <cpu/x86/smm.h>
Marc Jones24484842017-05-04 21:17:45 -060021#include <device/device.h>
22#include <device/pci.h>
23#include <device/pci_ids.h>
24#include <device/pci_ops.h>
25#include <cbmem.h>
Richard Spiegel2bbc3dc2017-12-06 16:14:58 -070026#include <amdblocks/amd_pci_util.h>
Marc Jonesdfeb1c42017-08-07 19:08:24 -060027#include <soc/southbridge.h>
Marc Jones24484842017-05-04 21:17:45 -060028#include <soc/smi.h>
Richard Spiegel376dc822017-12-01 08:24:26 -070029#include <soc/amd_pci_int_defs.h>
Marc Jones24484842017-05-04 21:17:45 -060030#include <fchec.h>
Richard Spiegelbec44f22017-11-24 07:41:29 -070031#include <delay.h>
32#include <soc/pci_devs.h>
Marshall Dawson2942db62017-12-14 10:00:27 -070033#include <agesa_headers.h>
34
35static int is_sata_config(void)
36{
37 return !((CONFIG_STONEYRIDGE_SATA_MODE == SataNativeIde)
38 || (CONFIG_STONEYRIDGE_SATA_MODE == SataLegacyIde));
39}
40
Richard Spiegel7ea8e022018-01-16 14:40:10 -070041static inline int sb_sata_enable(void)
42{
43 /* True if IDE or AHCI. */
44 return (CONFIG_STONEYRIDGE_SATA_MODE == SataNativeIde) ||
45 (CONFIG_STONEYRIDGE_SATA_MODE == SataAhci);
46}
47
48static inline int sb_ide_enable(void)
49{
50 /* True if IDE or LEGACY IDE. */
51 return (CONFIG_STONEYRIDGE_SATA_MODE == SataNativeIde) ||
52 (CONFIG_STONEYRIDGE_SATA_MODE == SataLegacyIde);
53}
54
Marshall Dawson2942db62017-12-14 10:00:27 -070055void SetFchResetParams(FCH_RESET_INTERFACE *params)
56{
57 params->Xhci0Enable = IS_ENABLED(CONFIG_STONEYRIDGE_XHCI_ENABLE);
Richard Spiegela318d282018-01-16 13:25:40 -070058 params->SataEnable = sb_sata_enable();
59 params->IdeEnable = sb_ide_enable();
Marshall Dawson2942db62017-12-14 10:00:27 -070060}
61
62void SetFchEnvParams(FCH_INTERFACE *params)
63{
64 params->AzaliaController = AzEnable;
65 params->SataClass = CONFIG_STONEYRIDGE_SATA_MODE;
66 params->SataEnable = is_sata_config();
67 params->IdeEnable = !params->SataEnable;
68 params->SataIdeMode = (CONFIG_STONEYRIDGE_SATA_MODE == SataLegacyIde);
69}
70
71void SetFchMidParams(FCH_INTERFACE *params)
72{
73 SetFchEnvParams(params);
74}
Marc Jones24484842017-05-04 21:17:45 -060075
Richard Spiegel376dc822017-12-01 08:24:26 -070076/*
77 * Table of APIC register index and associated IRQ name. Using IDX_XXX_NAME
Jonathan Neuschäfer5268b762018-02-12 12:24:25 +010078 * provides a visible association with the index, therefore helping
Richard Spiegel376dc822017-12-01 08:24:26 -070079 * maintainability of table. If a new index/name is defined in
80 * amd_pci_int_defs.h, just add the pair at the end of this table.
81 * Order is not important.
82 */
83const static struct irq_idx_name irq_association[] = {
Richard Spiegele89d4442017-12-08 07:52:42 -070084 { PIRQ_A, "INTA#" },
85 { PIRQ_B, "INTB#" },
86 { PIRQ_C, "INTC#" },
87 { PIRQ_D, "INTD#" },
88 { PIRQ_E, "INTE#" },
89 { PIRQ_F, "INTF#" },
90 { PIRQ_G, "INTG#" },
91 { PIRQ_H, "INTH#" },
92 { PIRQ_MISC, "Misc" },
93 { PIRQ_MISC0, "Misc0" },
94 { PIRQ_MISC1, "Misc1" },
95 { PIRQ_MISC2, "Misc2" },
Richard Spiegel376dc822017-12-01 08:24:26 -070096 { PIRQ_SIRQA, "Ser IRQ INTA" },
97 { PIRQ_SIRQB, "Ser IRQ INTB" },
98 { PIRQ_SIRQC, "Ser IRQ INTC" },
99 { PIRQ_SIRQD, "Ser IRQ INTD" },
Richard Spiegele89d4442017-12-08 07:52:42 -0700100 { PIRQ_SCI, "SCI" },
101 { PIRQ_SMBUS, "SMBUS" },
102 { PIRQ_ASF, "ASF" },
103 { PIRQ_HDA, "HDA" },
104 { PIRQ_FC, "FC" },
105 { PIRQ_PMON, "PerMon" },
106 { PIRQ_SD, "SD" },
107 { PIRQ_SDIO, "SDIOt" },
108 { PIRQ_IMC0, "IMC INT0" },
109 { PIRQ_IMC1, "IMC INT1" },
110 { PIRQ_IMC2, "IMC INT2" },
111 { PIRQ_IMC3, "IMC INT3" },
112 { PIRQ_IMC4, "IMC INT4" },
113 { PIRQ_IMC5, "IMC INT5" },
114 { PIRQ_EHCI, "EHCI" },
115 { PIRQ_XHCI, "XHCI" },
116 { PIRQ_SATA, "SATA" },
117 { PIRQ_GPIO, "GPIO" },
118 { PIRQ_I2C0, "I2C0" },
119 { PIRQ_I2C1, "I2C1" },
120 { PIRQ_I2C2, "I2C2" },
121 { PIRQ_I2C3, "I2C3" },
122 { PIRQ_UART0, "UART0" },
123 { PIRQ_UART1, "UART1" },
Richard Spiegel376dc822017-12-01 08:24:26 -0700124};
125
Richard Spiegelebf3aa82017-11-24 07:47:42 -0700126/*
127 * Structure to simplify code obtaining the total of used wide IO
128 * registers and the size assigned to each.
129 */
130static struct wide_io_ioport_and_bits {
131 uint32_t enable;
132 uint16_t port;
133 uint8_t alt;
134} wio_io_en[TOTAL_WIDEIO_PORTS] = {
135 {
136 LPC_WIDEIO0_ENABLE,
137 LPC_WIDEIO_GENERIC_PORT,
138 LPC_ALT_WIDEIO0_ENABLE
139 },
140 {
141 LPC_WIDEIO1_ENABLE,
142 LPC_WIDEIO1_GENERIC_PORT,
143 LPC_ALT_WIDEIO1_ENABLE
144 },
145 {
146 LPC_WIDEIO2_ENABLE,
147 LPC_WIDEIO2_GENERIC_PORT,
148 LPC_ALT_WIDEIO2_ENABLE
149 }
150};
151
Richard Spiegel376dc822017-12-01 08:24:26 -0700152const struct irq_idx_name *sb_get_apic_reg_association(size_t *size)
153{
154 *size = ARRAY_SIZE(irq_association);
155 return irq_association;
156}
157
Justin TerAvest3fe3f042018-02-14 19:10:15 -0700158void sb_program_gpios(const struct soc_amd_stoneyridge_gpio *gpio_ptr,
159 size_t size)
Richard Spiegele539c852017-12-25 18:25:58 -0700160{
161 void *tmp_ptr;
Richard Spiegele539c852017-12-25 18:25:58 -0700162 uint8_t control, mux, index;
163
164 printk(BIOS_SPEW, "GPIO programming stage %s\n", STR_GPIO_STAGE);
Richard Spiegele539c852017-12-25 18:25:58 -0700165 for (index = 0; index < size; index++) {
166 mux = gpio_ptr[index].function;
167 control = gpio_ptr[index].control;
168 tmp_ptr = (void *)(gpio_ptr[index].gpio + AMD_GPIO_MUX);
169 write8(tmp_ptr, mux & AMD_GPIO_MUX_MASK);
170
171 /*
172 * Get the address of AMD_GPIO_CONTROL (dword) relative
173 * to the desired pin and program bits 16-23.
174 */
175 tmp_ptr = (void *)(gpio_ptr[index].gpio * sizeof(uint32_t) +
176 AMD_GPIO_CONTROL + 2);
177 write8(tmp_ptr, control);
178 }
179 printk(BIOS_SPEW, "End GPIO programming\n");
180}
181
Richard Spiegelebf3aa82017-11-24 07:47:42 -0700182/**
183 * @brief Find the size of a particular wide IO
184 *
185 * @param index = index of desired wide IO
186 *
187 * @return size of desired wide IO
188 */
189uint16_t sb_wideio_size(int index)
190{
191 uint32_t enable_register;
192 uint16_t size = 0;
193 uint8_t alternate_register;
194
195 if (index >= TOTAL_WIDEIO_PORTS)
196 return size;
197 enable_register = pci_read_config32(SOC_LPC_DEV,
198 LPC_IO_OR_MEM_DECODE_ENABLE);
199 alternate_register = pci_read_config8(SOC_LPC_DEV,
200 LPC_ALT_WIDEIO_RANGE_ENABLE);
201 if (enable_register & wio_io_en[index].enable)
202 size = (alternate_register & wio_io_en[index].alt) ?
203 16 : 512;
204 return size;
205}
206
207/**
208 * @brief Identify if any LPC wide IO is covering the IO range
209 *
210 * @param start = start of IO range
211 * @param size = size of IO range
212 *
213 * @return Index of wide IO covering the range or error
214 */
215int sb_find_wideio_range(uint16_t start, uint16_t size)
216{
217 uint32_t enable_register;
218 int i, index = WIDEIO_RANGE_ERROR;
219 uint16_t end, current_size, start_wideio, end_wideio;
220
221 end = start + size;
222 enable_register = pci_read_config32(SOC_LPC_DEV,
223 LPC_IO_OR_MEM_DECODE_ENABLE);
224 for (i = 0; i < TOTAL_WIDEIO_PORTS; i++) {
225 current_size = sb_wideio_size(i);
226 if (current_size == 0)
227 continue;
228 start_wideio = pci_read_config16(SOC_LPC_DEV,
229 wio_io_en[i].port);
230 end_wideio = start_wideio + current_size;
231 if ((start >= start_wideio) && (end <= end_wideio)) {
232 index = i;
233 break;
234 }
235 }
236 return index;
237}
238
239/**
240 * @brief Program a LPC wide IO to support an IO range
241 *
242 * @param start = start of range to be routed through wide IO
243 * @param size = size of range to be routed through wide IO
244 *
245 * @return Index of wide IO register used or error
246 */
247int sb_set_wideio_range(uint16_t start, uint16_t size)
248{
249 int i, index = WIDEIO_RANGE_ERROR;
250 uint32_t enable_register;
251 uint8_t alternate_register;
252
253 enable_register = pci_read_config32(SOC_LPC_DEV,
254 LPC_IO_OR_MEM_DECODE_ENABLE);
255 alternate_register = pci_read_config8(SOC_LPC_DEV,
256 LPC_ALT_WIDEIO_RANGE_ENABLE);
257 for (i = 0; i < TOTAL_WIDEIO_PORTS; i++) {
258 if (enable_register & wio_io_en[i].enable)
259 continue;
260 index = i;
261 pci_write_config16(SOC_LPC_DEV, wio_io_en[i].port, start);
262 enable_register |= wio_io_en[i].enable;
263 pci_write_config32(SOC_LPC_DEV, LPC_IO_OR_MEM_DECODE_ENABLE,
264 enable_register);
265 if (size <= 16)
266 alternate_register |= wio_io_en[i].alt;
267 else
268 alternate_register &= ~wio_io_en[i].alt;
269 pci_write_config8(SOC_LPC_DEV,
270 LPC_ALT_WIDEIO_RANGE_ENABLE,
271 alternate_register);
272 break;
273 }
274 return index;
275}
276
Richard Spiegelbec44f22017-11-24 07:41:29 -0700277void configure_stoneyridge_uart(void)
278{
279 u8 byte, byte2;
280
281 if (CONFIG_UART_FOR_CONSOLE < 0 || CONFIG_UART_FOR_CONSOLE > 1)
282 return;
283
284 /* Power on the UART and AMBA devices */
285 byte = read8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG56
286 + CONFIG_UART_FOR_CONSOLE * 2);
287 byte |= AOAC_PWR_ON_DEV;
288 write8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG56
289 + CONFIG_UART_FOR_CONSOLE * 2, byte);
290
291 byte = read8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG62);
292 byte |= AOAC_PWR_ON_DEV;
293 write8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG62, byte);
294
295 /* Set the GPIO mux to UART */
296 write8((void *)FCH_IOMUXx89_UART0_RTS_L_EGPIO137, 0);
297 write8((void *)FCH_IOMUXx8A_UART0_TXD_EGPIO138, 0);
298 write8((void *)FCH_IOMUXx8E_UART1_RTS_L_EGPIO142, 0);
299 write8((void *)FCH_IOMUXx8F_UART1_TXD_EGPIO143, 0);
300
301 /* Wait for the UART and AMBA devices to indicate power and clock OK */
302 do {
303 udelay(100);
304 byte = read8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG57
305 + CONFIG_UART_FOR_CONSOLE * 2);
306 byte &= (A0AC_PWR_RST_STATE | AOAC_RST_CLK_OK_STATE);
307 byte2 = read8((void *)ACPI_MMIO_BASE + AOAC_BASE
308 + FCH_AOAC_REG63);
309 byte2 &= (A0AC_PWR_RST_STATE | AOAC_RST_CLK_OK_STATE);
310 } while (!((byte == (A0AC_PWR_RST_STATE | AOAC_RST_CLK_OK_STATE)) &&
311 (byte2 == (A0AC_PWR_RST_STATE | AOAC_RST_CLK_OK_STATE))));
312
313}
314
315void sb_pci_port80(void)
316{
317 u8 byte;
318
319 byte = pci_read_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DEC_EN_HIGH);
320 byte &= ~DECODE_IO_PORT_ENABLE4_H; /* disable lpc port 80 */
321 pci_write_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DEC_EN_HIGH, byte);
322}
323
324void sb_lpc_port80(void)
325{
326 u8 byte;
327
328 /* Enable LPC controller */
329 outb(PM_LPC_GATING, PM_INDEX);
330 byte = inb(PM_DATA);
331 byte |= PM_LPC_ENABLE;
332 outb(PM_LPC_GATING, PM_INDEX);
333 outb(byte, PM_DATA);
334
335 /* Enable port 80 LPC decode in pci function 3 configuration space. */
336 byte = pci_read_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DEC_EN_HIGH);
337 byte |= DECODE_IO_PORT_ENABLE4_H; /* enable port 80 */
338 pci_write_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DEC_EN_HIGH, byte);
339}
340
341void sb_lpc_decode(void)
342{
343 u32 tmp = 0;
344
345 /* Enable I/O decode to LPC bus */
346 tmp = DECODE_ENABLE_PARALLEL_PORT0 | DECODE_ENABLE_PARALLEL_PORT2
347 | DECODE_ENABLE_PARALLEL_PORT4 | DECODE_ENABLE_SERIAL_PORT0
348 | DECODE_ENABLE_SERIAL_PORT1 | DECODE_ENABLE_SERIAL_PORT2
349 | DECODE_ENABLE_SERIAL_PORT3 | DECODE_ENABLE_SERIAL_PORT4
350 | DECODE_ENABLE_SERIAL_PORT5 | DECODE_ENABLE_SERIAL_PORT6
351 | DECODE_ENABLE_SERIAL_PORT7 | DECODE_ENABLE_AUDIO_PORT0
352 | DECODE_ENABLE_AUDIO_PORT1 | DECODE_ENABLE_AUDIO_PORT2
353 | DECODE_ENABLE_AUDIO_PORT3 | DECODE_ENABLE_MSS_PORT2
354 | DECODE_ENABLE_MSS_PORT3 | DECODE_ENABLE_FDC_PORT0
355 | DECODE_ENABLE_FDC_PORT1 | DECODE_ENABLE_GAME_PORT
356 | DECODE_ENABLE_KBC_PORT | DECODE_ENABLE_ACPIUC_PORT
357 | DECODE_ENABLE_ADLIB_PORT;
358
359 pci_write_config32(SOC_LPC_DEV, LPC_IO_PORT_DECODE_ENABLE, tmp);
360}
361
362void sb_clk_output_48Mhz(void)
363{
364 u32 ctrl;
365
366 /*
367 * Enable the X14M_25M_48M_OSC pin and leaving it at it's default so
368 * 48Mhz will be on ball AP13 (FT3b package)
369 */
370 ctrl = read32((void *)(ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40));
371
372 /* clear the OSCOUT1_ClkOutputEnb to enable the 48 Mhz clock */
373 ctrl &= ~FCH_MISC_REG40_OSCOUT1_EN;
374 write32((void *)(ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40), ctrl);
375}
376
377static uintptr_t sb_spibase(void)
378{
379 u32 base, enables;
380
381 /* Make sure the base address is predictable */
382 base = pci_read_config32(SOC_LPC_DEV, SPIROM_BASE_ADDRESS_REGISTER);
383 enables = base & 0xf;
384 base &= ~0x3f;
385
386 if (!base) {
387 base = SPI_BASE_ADDRESS;
388 pci_write_config32(SOC_LPC_DEV, SPIROM_BASE_ADDRESS_REGISTER,
389 base | enables | SPI_ROM_ENABLE);
390 /* PCI_COMMAND_MEMORY is read-only and enabled. */
391 }
392 return (uintptr_t)base;
393}
394
395void sb_set_spi100(u16 norm, u16 fast, u16 alt, u16 tpm)
396{
397 uintptr_t base = sb_spibase();
398 write16((void *)base + SPI100_SPEED_CONFIG,
399 (norm << SPI_NORM_SPEED_NEW_SH) |
400 (fast << SPI_FAST_SPEED_NEW_SH) |
401 (alt << SPI_ALT_SPEED_NEW_SH) |
402 (tpm << SPI_TPM_SPEED_NEW_SH));
403 write16((void *)base + SPI100_ENABLE, SPI_USE_SPI100);
404}
405
406void sb_disable_4dw_burst(void)
407{
408 uintptr_t base = sb_spibase();
409 write16((void *)base + SPI100_HOST_PREF_CONFIG,
410 read16((void *)base + SPI100_HOST_PREF_CONFIG)
411 & ~SPI_RD4DW_EN_HOST);
412}
413
414void sb_set_readspeed(u16 norm, u16 fast)
415{
416 uintptr_t base = sb_spibase();
417 write16((void *)base + SPI_CNTRL1, (read16((void *)base + SPI_CNTRL1)
418 & ~SPI_CNTRL1_SPEED_MASK)
419 | (norm << SPI_NORM_SPEED_SH)
420 | (fast << SPI_FAST_SPEED_SH));
421}
422
423void sb_read_mode(u32 mode)
424{
425 uintptr_t base = sb_spibase();
426 write32((void *)base + SPI_CNTRL0,
427 (read32((void *)base + SPI_CNTRL0)
428 & ~SPI_READ_MODE_MASK) | mode);
429}
430
431void sb_tpm_decode_spi(void)
432{
433 u32 spibase = pci_read_config32(SOC_LPC_DEV,
434 SPIROM_BASE_ADDRESS_REGISTER);
435 pci_write_config32(SOC_LPC_DEV, SPIROM_BASE_ADDRESS_REGISTER, spibase
436 | ROUTE_TPM_2_SPI);
437}
438
439/*
440 * Enable 4MB (LPC) ROM access at 0xFFC00000 - 0xFFFFFFFF.
441 *
442 * Hardware should enable LPC ROM by pin straps. This function does not
443 * handle the theoretically possible PCI ROM, FWH, or SPI ROM configurations.
444 *
445 * The southbridge power-on default is to map 512K ROM space.
446 *
447 */
448void sb_enable_rom(void)
449{
450 u8 reg8;
451
452 /*
453 * Decode variable LPC ROM address ranges 1 and 2.
454 * Bits 3-4 are not defined in any publicly available datasheet
455 */
456 reg8 = pci_read_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DECODE_ENABLE);
457 reg8 |= (1 << 3) | (1 << 4);
458 pci_write_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DECODE_ENABLE, reg8);
459
460 /*
461 * LPC ROM address range 1:
462 * Enable LPC ROM range mirroring start at 0x000e(0000).
463 */
464 pci_write_config16(SOC_LPC_DEV, ROM_ADDRESS_RANGE1_START, 0x000e);
465
466 /* Enable LPC ROM range mirroring end at 0x000f(ffff). */
467 pci_write_config16(SOC_LPC_DEV, ROM_ADDRESS_RANGE1_END, 0x000f);
468
469 /*
470 * LPC ROM address range 2:
471 *
472 * Enable LPC ROM range start at:
473 * 0xfff8(0000): 512KB
474 * 0xfff0(0000): 1MB
475 * 0xffe0(0000): 2MB
476 * 0xffc0(0000): 4MB
477 */
478 pci_write_config16(SOC_LPC_DEV, ROM_ADDRESS_RANGE2_START, 0x10000
479 - (CONFIG_COREBOOT_ROMSIZE_KB >> 6));
480
481 /* Enable LPC ROM range end at 0xffff(ffff). */
482 pci_write_config16(SOC_LPC_DEV, ROM_ADDRESS_RANGE2_END, 0xffff);
483}
484
485void bootblock_fch_early_init(void)
486{
487 sb_enable_rom();
488 sb_lpc_port80();
489 sb_lpc_decode();
490}
491
Marc Jonesdfeb1c42017-08-07 19:08:24 -0600492void sb_enable(device_t dev)
Marc Jones24484842017-05-04 21:17:45 -0600493{
Marc Jonesdfeb1c42017-08-07 19:08:24 -0600494 printk(BIOS_DEBUG, "%s\n", __func__);
Marc Jones24484842017-05-04 21:17:45 -0600495}
496
Marc Jonesdfeb1c42017-08-07 19:08:24 -0600497static void sb_init_acpi_ports(void)
Marc Jones24484842017-05-04 21:17:45 -0600498{
Marshall Dawson91b80412017-09-27 16:44:40 -0600499 u32 reg;
500
Marc Jones24484842017-05-04 21:17:45 -0600501 /* We use some of these ports in SMM regardless of whether or not
502 * ACPI tables are generated. Enable these ports indiscriminately.
503 */
504
505 pm_write16(PM_EVT_BLK, ACPI_PM_EVT_BLK);
506 pm_write16(PM1_CNT_BLK, ACPI_PM1_CNT_BLK);
507 pm_write16(PM_TMR_BLK, ACPI_PM_TMR_BLK);
508 pm_write16(PM_GPE0_BLK, ACPI_GPE0_BLK);
509 /* CpuControl is in \_PR.CP00, 6 bytes */
510 pm_write16(PM_CPU_CTRL, ACPI_CPU_CONTROL);
511
512 if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) {
Marshall Dawsona05fdcb2017-09-27 15:01:37 -0600513 /* APMC - SMI Command Port */
Marshall Dawsone9b862e2017-09-22 15:14:46 -0600514 pm_write16(PM_ACPI_SMI_CMD, APM_CNT);
Marshall Dawsona05fdcb2017-09-27 15:01:37 -0600515 configure_smi(SMITYPE_SMI_CMD_PORT, SMI_MODE_SMI);
Marshall Dawson91b80412017-09-27 16:44:40 -0600516
517 /* SMI on SlpTyp requires sending SMI before completion
518 * response of the I/O write. The BKDG also specifies
519 * clearing ForceStpClkRetry for SMI trapping.
520 */
521 reg = pm_read32(PM_PCI_CTRL);
522 reg |= FORCE_SLPSTATE_RETRY;
523 reg &= ~FORCE_STPCLK_RETRY;
524 pm_write32(PM_PCI_CTRL, reg);
525
526 /* Disable SlpTyp feature */
527 reg = pm_read8(PM_RST_CTRL1);
528 reg &= ~SLPTYPE_CONTROL_EN;
529 pm_write8(PM_RST_CTRL1, reg);
530
531 configure_smi(SMITYPE_SLP_TYP, SMI_MODE_SMI);
Marc Jones24484842017-05-04 21:17:45 -0600532 } else {
533 pm_write16(PM_ACPI_SMI_CMD, 0);
534 }
535
Marshall Dawson5e2e74f2017-11-10 09:59:56 -0700536 /* Decode ACPI registers and enable standard features */
537 pm_write8(PM_ACPI_CONF, PM_ACPI_DECODE_STD |
538 PM_ACPI_GLOBAL_EN |
539 PM_ACPI_RTC_EN_EN |
540 PM_ACPI_TIMER_EN_EN);
Marc Jones24484842017-05-04 21:17:45 -0600541}
542
Marc Jonesdfeb1c42017-08-07 19:08:24 -0600543void southbridge_init(void *chip_info)
Marc Jones24484842017-05-04 21:17:45 -0600544{
Marc Jonesdfeb1c42017-08-07 19:08:24 -0600545 sb_init_acpi_ports();
Marc Jones24484842017-05-04 21:17:45 -0600546}
547
Marc Jonesdfeb1c42017-08-07 19:08:24 -0600548void southbridge_final(void *chip_info)
Marc Jones24484842017-05-04 21:17:45 -0600549{
Richard Spiegel38f19402017-09-29 11:39:46 -0700550 if (IS_ENABLED(CONFIG_STONEYRIDGE_IMC_FWM)) {
551 agesawrapper_fchecfancontrolservice();
552 if (!IS_ENABLED(CONFIG_ACPI_ENABLE_THERMAL_ZONE))
553 enable_imc_thermal_zone();
554 }
Marc Jones24484842017-05-04 21:17:45 -0600555}
Marshall Dawson8a906df2017-06-13 14:19:02 -0600556
557/*
558 * Update the PCI devices with a valid IRQ number
559 * that is set in the mainboard PCI_IRQ structures.
560 */
561static void set_pci_irqs(void *unused)
562{
563 /* Write PCI_INTR regs 0xC00/0xC01 */
564 write_pci_int_table();
565
566 /* Write IRQs for all devicetree enabled devices */
567 write_pci_cfg_irqs();
568}
569
570/*
571 * Hook this function into the PCI state machine
572 * on entry into BS_DEV_ENABLE.
573 */
574BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY, set_pci_irqs, NULL);