blob: 44dbf62a1c1a699a68ea1d19d78fe59150884aa2 [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>
19#include <arch/acpi.h>
Marshall Dawson8a906df2017-06-13 14:19:02 -060020#include <bootstate.h>
Marshall Dawsone9b862e2017-09-22 15:14:46 -060021#include <cpu/x86/smm.h>
Marc Jones24484842017-05-04 21:17:45 -060022#include <device/device.h>
23#include <device/pci.h>
24#include <device/pci_ids.h>
25#include <device/pci_ops.h>
26#include <cbmem.h>
Marshall Dawson8a906df2017-06-13 14:19:02 -060027#include <amd_pci_util.h>
Marc Jonesdfeb1c42017-08-07 19:08:24 -060028#include <soc/southbridge.h>
Marc Jones24484842017-05-04 21:17:45 -060029#include <soc/smi.h>
Richard Spiegel376dc822017-12-01 08:24:26 -070030#include <soc/amd_pci_int_defs.h>
Marc Jones24484842017-05-04 21:17:45 -060031#include <fchec.h>
Richard Spiegelbec44f22017-11-24 07:41:29 -070032#include <delay.h>
33#include <soc/pci_devs.h>
Marc Jones24484842017-05-04 21:17:45 -060034
Richard Spiegel376dc822017-12-01 08:24:26 -070035/*
36 * Table of APIC register index and associated IRQ name. Using IDX_XXX_NAME
37 * provides a visible association with the index, therefor helping
38 * maintainability of table. If a new index/name is defined in
39 * amd_pci_int_defs.h, just add the pair at the end of this table.
40 * Order is not important.
41 */
42const static struct irq_idx_name irq_association[] = {
43 { PIRQ_A, "INTA#\t" },
44 { PIRQ_B, "INTB#\t" },
45 { PIRQ_C, "INTC#\t" },
46 { PIRQ_D, "INTD#\t" },
47 { PIRQ_E, "INTE#\t" },
48 { PIRQ_F, "INTF#\t" },
49 { PIRQ_G, "INTG#\t" },
50 { PIRQ_H, "INTH#\t" },
51 { PIRQ_MISC, "Misc\t" },
52 { PIRQ_MISC0, "Misc0\t" },
53 { PIRQ_MISC1, "Misc1\t" },
54 { PIRQ_MISC2, "Misc2\t" },
55 { PIRQ_SIRQA, "Ser IRQ INTA" },
56 { PIRQ_SIRQB, "Ser IRQ INTB" },
57 { PIRQ_SIRQC, "Ser IRQ INTC" },
58 { PIRQ_SIRQD, "Ser IRQ INTD" },
59 { PIRQ_SCI, "SCI\t" },
60 { PIRQ_SMBUS, "SMBUS\t" },
61 { PIRQ_ASF, "ASF\t" },
62 { PIRQ_HDA, "HDA\t" },
63 { PIRQ_FC, "FC\t\t" },
64 { PIRQ_PMON, "PerMon\t" },
65 { PIRQ_SD, "SD\t\t" },
66 { PIRQ_SDIO, "SDIO\t" },
67 { PIRQ_IMC0, "IMC INT0\t" },
68 { PIRQ_IMC1, "IMC INT1\t" },
69 { PIRQ_IMC2, "IMC INT2\t" },
70 { PIRQ_IMC3, "IMC INT3\t" },
71 { PIRQ_IMC4, "IMC INT4\t" },
72 { PIRQ_IMC5, "IMC INT5\t" },
73 { PIRQ_EHCI, "EHCI\t" },
74 { PIRQ_XHCI, "XHCI\t" },
75 { PIRQ_SATA, "SATA\t" },
76 { PIRQ_GPIO, "GPIO\t" },
77 { PIRQ_I2C0, "I2C0\t" },
78 { PIRQ_I2C1, "I2C1\t" },
79 { PIRQ_I2C2, "I2C2\t" },
80 { PIRQ_I2C3, "I2C3\t" },
81 { PIRQ_UART0, "UART0\t" },
82 { PIRQ_UART1, "UART1\t" },
83};
84
85const struct irq_idx_name *sb_get_apic_reg_association(size_t *size)
86{
87 *size = ARRAY_SIZE(irq_association);
88 return irq_association;
89}
90
Richard Spiegelbec44f22017-11-24 07:41:29 -070091void configure_stoneyridge_uart(void)
92{
93 u8 byte, byte2;
94
95 if (CONFIG_UART_FOR_CONSOLE < 0 || CONFIG_UART_FOR_CONSOLE > 1)
96 return;
97
98 /* Power on the UART and AMBA devices */
99 byte = read8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG56
100 + CONFIG_UART_FOR_CONSOLE * 2);
101 byte |= AOAC_PWR_ON_DEV;
102 write8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG56
103 + CONFIG_UART_FOR_CONSOLE * 2, byte);
104
105 byte = read8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG62);
106 byte |= AOAC_PWR_ON_DEV;
107 write8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG62, byte);
108
109 /* Set the GPIO mux to UART */
110 write8((void *)FCH_IOMUXx89_UART0_RTS_L_EGPIO137, 0);
111 write8((void *)FCH_IOMUXx8A_UART0_TXD_EGPIO138, 0);
112 write8((void *)FCH_IOMUXx8E_UART1_RTS_L_EGPIO142, 0);
113 write8((void *)FCH_IOMUXx8F_UART1_TXD_EGPIO143, 0);
114
115 /* Wait for the UART and AMBA devices to indicate power and clock OK */
116 do {
117 udelay(100);
118 byte = read8((void *)ACPI_MMIO_BASE + AOAC_BASE + FCH_AOAC_REG57
119 + CONFIG_UART_FOR_CONSOLE * 2);
120 byte &= (A0AC_PWR_RST_STATE | AOAC_RST_CLK_OK_STATE);
121 byte2 = read8((void *)ACPI_MMIO_BASE + AOAC_BASE
122 + FCH_AOAC_REG63);
123 byte2 &= (A0AC_PWR_RST_STATE | AOAC_RST_CLK_OK_STATE);
124 } while (!((byte == (A0AC_PWR_RST_STATE | AOAC_RST_CLK_OK_STATE)) &&
125 (byte2 == (A0AC_PWR_RST_STATE | AOAC_RST_CLK_OK_STATE))));
126
127}
128
129void sb_pci_port80(void)
130{
131 u8 byte;
132
133 byte = pci_read_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DEC_EN_HIGH);
134 byte &= ~DECODE_IO_PORT_ENABLE4_H; /* disable lpc port 80 */
135 pci_write_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DEC_EN_HIGH, byte);
136}
137
138void sb_lpc_port80(void)
139{
140 u8 byte;
141
142 /* Enable LPC controller */
143 outb(PM_LPC_GATING, PM_INDEX);
144 byte = inb(PM_DATA);
145 byte |= PM_LPC_ENABLE;
146 outb(PM_LPC_GATING, PM_INDEX);
147 outb(byte, PM_DATA);
148
149 /* Enable port 80 LPC decode in pci function 3 configuration space. */
150 byte = pci_read_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DEC_EN_HIGH);
151 byte |= DECODE_IO_PORT_ENABLE4_H; /* enable port 80 */
152 pci_write_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DEC_EN_HIGH, byte);
153}
154
155void sb_lpc_decode(void)
156{
157 u32 tmp = 0;
158
159 /* Enable I/O decode to LPC bus */
160 tmp = DECODE_ENABLE_PARALLEL_PORT0 | DECODE_ENABLE_PARALLEL_PORT2
161 | DECODE_ENABLE_PARALLEL_PORT4 | DECODE_ENABLE_SERIAL_PORT0
162 | DECODE_ENABLE_SERIAL_PORT1 | DECODE_ENABLE_SERIAL_PORT2
163 | DECODE_ENABLE_SERIAL_PORT3 | DECODE_ENABLE_SERIAL_PORT4
164 | DECODE_ENABLE_SERIAL_PORT5 | DECODE_ENABLE_SERIAL_PORT6
165 | DECODE_ENABLE_SERIAL_PORT7 | DECODE_ENABLE_AUDIO_PORT0
166 | DECODE_ENABLE_AUDIO_PORT1 | DECODE_ENABLE_AUDIO_PORT2
167 | DECODE_ENABLE_AUDIO_PORT3 | DECODE_ENABLE_MSS_PORT2
168 | DECODE_ENABLE_MSS_PORT3 | DECODE_ENABLE_FDC_PORT0
169 | DECODE_ENABLE_FDC_PORT1 | DECODE_ENABLE_GAME_PORT
170 | DECODE_ENABLE_KBC_PORT | DECODE_ENABLE_ACPIUC_PORT
171 | DECODE_ENABLE_ADLIB_PORT;
172
173 pci_write_config32(SOC_LPC_DEV, LPC_IO_PORT_DECODE_ENABLE, tmp);
174}
175
176void sb_clk_output_48Mhz(void)
177{
178 u32 ctrl;
179
180 /*
181 * Enable the X14M_25M_48M_OSC pin and leaving it at it's default so
182 * 48Mhz will be on ball AP13 (FT3b package)
183 */
184 ctrl = read32((void *)(ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40));
185
186 /* clear the OSCOUT1_ClkOutputEnb to enable the 48 Mhz clock */
187 ctrl &= ~FCH_MISC_REG40_OSCOUT1_EN;
188 write32((void *)(ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40), ctrl);
189}
190
191static uintptr_t sb_spibase(void)
192{
193 u32 base, enables;
194
195 /* Make sure the base address is predictable */
196 base = pci_read_config32(SOC_LPC_DEV, SPIROM_BASE_ADDRESS_REGISTER);
197 enables = base & 0xf;
198 base &= ~0x3f;
199
200 if (!base) {
201 base = SPI_BASE_ADDRESS;
202 pci_write_config32(SOC_LPC_DEV, SPIROM_BASE_ADDRESS_REGISTER,
203 base | enables | SPI_ROM_ENABLE);
204 /* PCI_COMMAND_MEMORY is read-only and enabled. */
205 }
206 return (uintptr_t)base;
207}
208
209void sb_set_spi100(u16 norm, u16 fast, u16 alt, u16 tpm)
210{
211 uintptr_t base = sb_spibase();
212 write16((void *)base + SPI100_SPEED_CONFIG,
213 (norm << SPI_NORM_SPEED_NEW_SH) |
214 (fast << SPI_FAST_SPEED_NEW_SH) |
215 (alt << SPI_ALT_SPEED_NEW_SH) |
216 (tpm << SPI_TPM_SPEED_NEW_SH));
217 write16((void *)base + SPI100_ENABLE, SPI_USE_SPI100);
218}
219
220void sb_disable_4dw_burst(void)
221{
222 uintptr_t base = sb_spibase();
223 write16((void *)base + SPI100_HOST_PREF_CONFIG,
224 read16((void *)base + SPI100_HOST_PREF_CONFIG)
225 & ~SPI_RD4DW_EN_HOST);
226}
227
228void sb_set_readspeed(u16 norm, u16 fast)
229{
230 uintptr_t base = sb_spibase();
231 write16((void *)base + SPI_CNTRL1, (read16((void *)base + SPI_CNTRL1)
232 & ~SPI_CNTRL1_SPEED_MASK)
233 | (norm << SPI_NORM_SPEED_SH)
234 | (fast << SPI_FAST_SPEED_SH));
235}
236
237void sb_read_mode(u32 mode)
238{
239 uintptr_t base = sb_spibase();
240 write32((void *)base + SPI_CNTRL0,
241 (read32((void *)base + SPI_CNTRL0)
242 & ~SPI_READ_MODE_MASK) | mode);
243}
244
245void sb_tpm_decode_spi(void)
246{
247 u32 spibase = pci_read_config32(SOC_LPC_DEV,
248 SPIROM_BASE_ADDRESS_REGISTER);
249 pci_write_config32(SOC_LPC_DEV, SPIROM_BASE_ADDRESS_REGISTER, spibase
250 | ROUTE_TPM_2_SPI);
251}
252
253/*
254 * Enable 4MB (LPC) ROM access at 0xFFC00000 - 0xFFFFFFFF.
255 *
256 * Hardware should enable LPC ROM by pin straps. This function does not
257 * handle the theoretically possible PCI ROM, FWH, or SPI ROM configurations.
258 *
259 * The southbridge power-on default is to map 512K ROM space.
260 *
261 */
262void sb_enable_rom(void)
263{
264 u8 reg8;
265
266 /*
267 * Decode variable LPC ROM address ranges 1 and 2.
268 * Bits 3-4 are not defined in any publicly available datasheet
269 */
270 reg8 = pci_read_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DECODE_ENABLE);
271 reg8 |= (1 << 3) | (1 << 4);
272 pci_write_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DECODE_ENABLE, reg8);
273
274 /*
275 * LPC ROM address range 1:
276 * Enable LPC ROM range mirroring start at 0x000e(0000).
277 */
278 pci_write_config16(SOC_LPC_DEV, ROM_ADDRESS_RANGE1_START, 0x000e);
279
280 /* Enable LPC ROM range mirroring end at 0x000f(ffff). */
281 pci_write_config16(SOC_LPC_DEV, ROM_ADDRESS_RANGE1_END, 0x000f);
282
283 /*
284 * LPC ROM address range 2:
285 *
286 * Enable LPC ROM range start at:
287 * 0xfff8(0000): 512KB
288 * 0xfff0(0000): 1MB
289 * 0xffe0(0000): 2MB
290 * 0xffc0(0000): 4MB
291 */
292 pci_write_config16(SOC_LPC_DEV, ROM_ADDRESS_RANGE2_START, 0x10000
293 - (CONFIG_COREBOOT_ROMSIZE_KB >> 6));
294
295 /* Enable LPC ROM range end at 0xffff(ffff). */
296 pci_write_config16(SOC_LPC_DEV, ROM_ADDRESS_RANGE2_END, 0xffff);
297}
298
299void bootblock_fch_early_init(void)
300{
301 sb_enable_rom();
302 sb_lpc_port80();
303 sb_lpc_decode();
304}
305
306int s3_save_nvram_early(u32 dword, int size, int nvram_pos)
307{
308 int i;
309 printk(BIOS_DEBUG, "Writing %x of size %d to nvram pos: %d\n",
310 dword, size, nvram_pos);
311
312 for (i = 0; i < size; i++) {
313 outb(nvram_pos, BIOSRAM_INDEX);
314 outb((dword >> (8 * i)) & 0xff, BIOSRAM_DATA);
315 nvram_pos++;
316 }
317
318 return nvram_pos;
319}
320
321int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos)
322{
323 u32 data = *old_dword;
324 int i;
325 for (i = 0; i < size; i++) {
326 outb(nvram_pos, BIOSRAM_INDEX);
327 data &= ~(0xff << (i * 8));
328 data |= inb(BIOSRAM_DATA) << (i * 8);
329 nvram_pos++;
330 }
331 *old_dword = data;
332 printk(BIOS_DEBUG, "Loading %x of size %d to nvram pos:%d\n",
333 *old_dword, size, nvram_pos-size);
334 return nvram_pos;
335}
Marc Jones24484842017-05-04 21:17:45 -0600336
337int acpi_get_sleep_type(void)
338{
Marshall Dawsonf9592cc2017-11-09 16:55:31 -0700339 return acpi_sleep_from_pm1(inw(pm_acpi_pm_cnt_blk()));
Marc Jones24484842017-05-04 21:17:45 -0600340}
341
Marc Jonesdfeb1c42017-08-07 19:08:24 -0600342void sb_enable(device_t dev)
Marc Jones24484842017-05-04 21:17:45 -0600343{
Marc Jonesdfeb1c42017-08-07 19:08:24 -0600344 printk(BIOS_DEBUG, "%s\n", __func__);
Marc Jones24484842017-05-04 21:17:45 -0600345}
346
Marc Jonesdfeb1c42017-08-07 19:08:24 -0600347static void sb_init_acpi_ports(void)
Marc Jones24484842017-05-04 21:17:45 -0600348{
Marshall Dawson91b80412017-09-27 16:44:40 -0600349 u32 reg;
350
Marc Jones24484842017-05-04 21:17:45 -0600351 /* We use some of these ports in SMM regardless of whether or not
352 * ACPI tables are generated. Enable these ports indiscriminately.
353 */
354
355 pm_write16(PM_EVT_BLK, ACPI_PM_EVT_BLK);
356 pm_write16(PM1_CNT_BLK, ACPI_PM1_CNT_BLK);
357 pm_write16(PM_TMR_BLK, ACPI_PM_TMR_BLK);
358 pm_write16(PM_GPE0_BLK, ACPI_GPE0_BLK);
359 /* CpuControl is in \_PR.CP00, 6 bytes */
360 pm_write16(PM_CPU_CTRL, ACPI_CPU_CONTROL);
361
362 if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) {
Marshall Dawsona05fdcb2017-09-27 15:01:37 -0600363 /* APMC - SMI Command Port */
Marshall Dawsone9b862e2017-09-22 15:14:46 -0600364 pm_write16(PM_ACPI_SMI_CMD, APM_CNT);
Marshall Dawsona05fdcb2017-09-27 15:01:37 -0600365 configure_smi(SMITYPE_SMI_CMD_PORT, SMI_MODE_SMI);
Marshall Dawson91b80412017-09-27 16:44:40 -0600366
367 /* SMI on SlpTyp requires sending SMI before completion
368 * response of the I/O write. The BKDG also specifies
369 * clearing ForceStpClkRetry for SMI trapping.
370 */
371 reg = pm_read32(PM_PCI_CTRL);
372 reg |= FORCE_SLPSTATE_RETRY;
373 reg &= ~FORCE_STPCLK_RETRY;
374 pm_write32(PM_PCI_CTRL, reg);
375
376 /* Disable SlpTyp feature */
377 reg = pm_read8(PM_RST_CTRL1);
378 reg &= ~SLPTYPE_CONTROL_EN;
379 pm_write8(PM_RST_CTRL1, reg);
380
381 configure_smi(SMITYPE_SLP_TYP, SMI_MODE_SMI);
Marc Jones24484842017-05-04 21:17:45 -0600382 } else {
383 pm_write16(PM_ACPI_SMI_CMD, 0);
384 }
385
Marshall Dawson5e2e74f2017-11-10 09:59:56 -0700386 /* Decode ACPI registers and enable standard features */
387 pm_write8(PM_ACPI_CONF, PM_ACPI_DECODE_STD |
388 PM_ACPI_GLOBAL_EN |
389 PM_ACPI_RTC_EN_EN |
390 PM_ACPI_TIMER_EN_EN);
Marc Jones24484842017-05-04 21:17:45 -0600391}
392
Marc Jonesdfeb1c42017-08-07 19:08:24 -0600393void southbridge_init(void *chip_info)
Marc Jones24484842017-05-04 21:17:45 -0600394{
Marc Jonesdfeb1c42017-08-07 19:08:24 -0600395 sb_init_acpi_ports();
Marc Jones24484842017-05-04 21:17:45 -0600396}
397
Marc Jonesdfeb1c42017-08-07 19:08:24 -0600398void southbridge_final(void *chip_info)
Marc Jones24484842017-05-04 21:17:45 -0600399{
Richard Spiegel38f19402017-09-29 11:39:46 -0700400 if (IS_ENABLED(CONFIG_STONEYRIDGE_IMC_FWM)) {
401 agesawrapper_fchecfancontrolservice();
402 if (!IS_ENABLED(CONFIG_ACPI_ENABLE_THERMAL_ZONE))
403 enable_imc_thermal_zone();
404 }
Marc Jones24484842017-05-04 21:17:45 -0600405}
Marshall Dawson8a906df2017-06-13 14:19:02 -0600406
407/*
408 * Update the PCI devices with a valid IRQ number
409 * that is set in the mainboard PCI_IRQ structures.
410 */
411static void set_pci_irqs(void *unused)
412{
413 /* Write PCI_INTR regs 0xC00/0xC01 */
414 write_pci_int_table();
415
416 /* Write IRQs for all devicetree enabled devices */
417 write_pci_cfg_irqs();
418}
419
420/*
421 * Hook this function into the PCI state machine
422 * on entry into BS_DEV_ENABLE.
423 */
424BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY, set_pci_irqs, NULL);