blob: 53cff315696493f1380505452edbd66d425f993e [file] [log] [blame]
Lee Leahy77ff0b12015-05-05 15:07:29 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2013 Google, Inc.
Lee Leahy32471722015-04-20 15:20:28 -07005 * Copyright (C) 2015 Intel Corp.
Frans Hendriks4e0ec592019-06-06 10:07:17 +02006 * Copyright (C) 2018 Eltan B.V.
Lee Leahy77ff0b12015-05-05 15:07:29 -07007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
Marshall Dawsone8c527e2017-01-13 14:23:49 -070013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Lee Leahy77ff0b12015-05-05 15:07:29 -070014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
Lee Leahy77ff0b12015-05-05 15:07:29 -070016 */
17
Frans Hendriks4e0ec592019-06-06 10:07:17 +020018#include <bootblock_common.h>
19#include <build.h>
20#include <console/console.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020021#include <device/pci_ops.h>
Frans Hendriks4e0ec592019-06-06 10:07:17 +020022#include <pc80/mc146818rtc.h>
Frans Hendriks4e0ec592019-06-06 10:07:17 +020023#include <soc/gpio.h>
24#include <soc/iomap.h>
Lee Leahy77ff0b12015-05-05 15:07:29 -070025#include <soc/iosf.h>
Frans Hendriks4e0ec592019-06-06 10:07:17 +020026#include <soc/lpc.h>
Kyösti Mälkki44f1af22019-11-06 08:56:18 +020027#include <soc/msr.h>
Frans Hendriks4e0ec592019-06-06 10:07:17 +020028#include <soc/pm.h>
29#include <soc/spi.h>
Lee Leahy77ff0b12015-05-05 15:07:29 -070030
Frans Hendriks4e0ec592019-06-06 10:07:17 +020031asmlinkage void bootblock_c_entry(uint64_t base_timestamp)
Lee Leahy77ff0b12015-05-05 15:07:29 -070032{
Frans Hendriks4e0ec592019-06-06 10:07:17 +020033 /* Call lib/bootblock.c main */
Kyösti Mälkki101ef0b2019-08-18 06:58:42 +030034 bootblock_main_with_basetime(base_timestamp);
Lee Leahy77ff0b12015-05-05 15:07:29 -070035}
36
Frans Hendriks4e0ec592019-06-06 10:07:17 +020037static void program_base_addresses(void)
Lee Leahy77ff0b12015-05-05 15:07:29 -070038{
Frans Hendriks4e0ec592019-06-06 10:07:17 +020039 uint32_t reg;
40 const uint32_t lpc_dev = PCI_DEV(0, LPC_DEV, LPC_FUNC);
Lee Leahy77ff0b12015-05-05 15:07:29 -070041
Frans Hendriks4e0ec592019-06-06 10:07:17 +020042 /* Memory Mapped IO registers. */
43 reg = PMC_BASE_ADDRESS | 2;
44 pci_write_config32(lpc_dev, PBASE, reg);
45 reg = IO_BASE_ADDRESS | 2;
46 pci_write_config32(lpc_dev, IOBASE, reg);
47 reg = ILB_BASE_ADDRESS | 2;
48 pci_write_config32(lpc_dev, IBASE, reg);
49 reg = SPI_BASE_ADDRESS | 2;
50 pci_write_config32(lpc_dev, SBASE, reg);
51 reg = MPHY_BASE_ADDRESS | 2;
52 pci_write_config32(lpc_dev, MPBASE, reg);
53 reg = PUNIT_BASE_ADDRESS | 2;
54 pci_write_config32(lpc_dev, PUBASE, reg);
55 reg = RCBA_BASE_ADDRESS | 1;
56 pci_write_config32(lpc_dev, RCBA, reg);
Lee Leahy77ff0b12015-05-05 15:07:29 -070057
Frans Hendriks4e0ec592019-06-06 10:07:17 +020058 /* IO Port Registers. */
59 reg = ACPI_BASE_ADDRESS | 2;
60 pci_write_config32(lpc_dev, ABASE, reg);
61 reg = GPIO_BASE_ADDRESS | 2;
62 pci_write_config32(lpc_dev, GBASE, reg);
63}
64
65static void tco_disable(void)
66{
67 uint32_t reg;
68
69 reg = inl(ACPI_BASE_ADDRESS + TCO1_CNT);
70 reg |= TCO_TMR_HALT;
71 outl(reg, ACPI_BASE_ADDRESS + TCO1_CNT);
72}
73
74static void spi_init(void)
75{
76 void *scs = (void *)(SPI_BASE_ADDRESS + SCS);
77 void *bcr = (void *)(SPI_BASE_ADDRESS + BCR);
78 uint32_t reg;
79
80 /* Disable generating SMI when setting WPD bit. */
81 write32(scs, read32(scs) & ~SMIWPEN);
82 /*
83 * Enable caching and prefetching in the SPI controller. Disable
84 * the SMM-only BIOS write and set WPD bit.
85 */
86 reg = (read32(bcr) & ~SRC_MASK) | SRC_CACHE_PREFETCH | BCR_WPD;
87 reg &= ~EISS;
88 write32(bcr, reg);
89}
90
91static void soc_rtc_init(void)
92{
93 int rtc_failed = rtc_failure();
94
95 if (rtc_failed) {
96 printk(BIOS_ERR,
97 "RTC Failure detected. Resetting date to %x/%x/%x%x\n",
98 COREBOOT_BUILD_MONTH_BCD,
99 COREBOOT_BUILD_DAY_BCD,
100 0x20,
101 COREBOOT_BUILD_YEAR_BCD);
102 }
103
104 cmos_init(rtc_failed);
Lee Leahy77ff0b12015-05-05 15:07:29 -0700105}
106
107static void setup_mmconfig(void)
108{
109 uint32_t reg;
110
Lee Leahy32471722015-04-20 15:20:28 -0700111 /*
112 * Set up the MMCONF range. The register lives in the BUNIT. The
Lee Leahy77ff0b12015-05-05 15:07:29 -0700113 * IO variant of the config access needs to be used initially to
114 * properly configure as the IOSF access registers live in PCI
Lee Leahy32471722015-04-20 15:20:28 -0700115 * config space.
116 */
Lee Leahy77ff0b12015-05-05 15:07:29 -0700117 reg = 0;
118 /* Clear the extended register. */
119 pci_io_write_config32(IOSF_PCI_DEV, MCRX_REG, reg);
120 reg = CONFIG_MMCONF_BASE_ADDRESS | 1;
121 pci_io_write_config32(IOSF_PCI_DEV, MDR_REG, reg);
122 reg = IOSF_OPCODE(IOSF_OP_WRITE_BUNIT) | IOSF_PORT(IOSF_PORT_BUNIT) |
123 IOSF_REG(BUNIT_MMCONF_REG) | IOSF_BYTE_EN;
124 pci_io_write_config32(IOSF_PCI_DEV, MCR_REG, reg);
125}
126
Frans Hendriks4e0ec592019-06-06 10:07:17 +0200127
128void bootblock_soc_early_init(void)
Lee Leahy77ff0b12015-05-05 15:07:29 -0700129{
130 /* Allow memory-mapped PCI config access. */
131 setup_mmconfig();
132
Frans Hendriks4e0ec592019-06-06 10:07:17 +0200133 /* Early chipset initialization */
134 program_base_addresses();
135 tco_disable();
136}
137void bootblock_soc_init(void)
138{
139 /* Continue chipset initialization */
140 soc_rtc_init();
141 set_max_freq();
142 spi_init();
143
144 lpc_init();
Lee Leahy77ff0b12015-05-05 15:07:29 -0700145}