blob: 1e6acc77455c928507d18c0ff4ce1776a8593085 [file] [log] [blame]
Werner Zehfa6f8612016-04-20 10:08:17 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2007-2009 coresystems GmbH
5 * Copyright (C) 2011 Google Inc.
Werner Zehf7da8922018-02-14 08:08:24 +01006 * Copyright (C) 2016-2018 Siemens AG
Werner Zehfa6f8612016-04-20 10:08:17 +02007 *
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,
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 <types.h>
19#include <string.h>
20#include <device/device.h>
Werner Zehfa6f8612016-04-20 10:08:17 +020021#include <device/pci_def.h>
22#include <device/pci_ops.h>
Werner Zeh96b89ae2017-06-28 12:56:31 +020023#include <device/pci_ids.h>
Werner Zehf7da8922018-02-14 08:08:24 +010024#include <device/path.h>
Werner Zehfa6f8612016-04-20 10:08:17 +020025#include <console/console.h>
Martin Roth43927ba2017-06-24 21:54:33 -060026#if IS_ENABLED(CONFIG_VGA_ROM_RUN)
Werner Zehfa6f8612016-04-20 10:08:17 +020027#include <x86emu/x86emu.h>
28#endif
Werner Zehfa6f8612016-04-20 10:08:17 +020029#include <arch/acpi.h>
30#include <arch/io.h>
31#include <arch/interrupt.h>
32#include <boot/coreboot_tables.h>
Werner Zehb2213ed2016-06-30 08:21:17 +020033#include <hwilib.h>
34#include <i210.h>
Werner Zehe1d6aa62016-07-06 11:59:10 +020035#include <soc/pci_devs.h>
Werner Zeha845f422016-07-07 07:10:50 +020036#include <soc/irq.h>
Werner Zeh9d18e332016-09-08 07:52:03 +020037#include <soc/lpc.h>
Werner Zehc0d1e312017-10-10 12:35:10 +020038#include <bootstate.h>
39#include <timer.h>
40#include <timestamp.h>
Werner Zehf7da8922018-02-14 08:08:24 +010041#include <pca9538.h>
Werner Zehfa6f8612016-04-20 10:08:17 +020042
Werner Zehb2213ed2016-06-30 08:21:17 +020043#define MAX_PATH_DEPTH 12
44#define MAX_NUM_MAPPINGS 10
Werner Zehe1d6aa62016-07-06 11:59:10 +020045
46/*
47 * SPI Opcode Menu setup for SPIBAR lock down
48 * should support most common flash chips.
49 */
50#define SPI_OPMENU_0 0x01 /* WRSR: Write Status Register */
51#define SPI_OPTYPE_0 0x01 /* Write, no address */
52
53#define SPI_OPMENU_1 0x02 /* BYPR: Byte Program */
54#define SPI_OPTYPE_1 0x03 /* Write, address required */
55
56#define SPI_OPMENU_2 0x03 /* READ: Read Data */
57#define SPI_OPTYPE_2 0x02 /* Read, address required */
58
59#define SPI_OPMENU_3 0x05 /* RDSR: Read Status Register */
60#define SPI_OPTYPE_3 0x00 /* Read, no address */
61
62#define SPI_OPMENU_4 0x20 /* SE20: Sector Erase 0x20 */
63#define SPI_OPTYPE_4 0x03 /* Write, address required */
64
65#define SPI_OPMENU_5 0x9f /* RDID: Read ID */
66#define SPI_OPTYPE_5 0x00 /* Read, no address */
67
68#define SPI_OPMENU_6 0xd8 /* BED8: Block Erase 0xd8 */
69#define SPI_OPTYPE_6 0x03 /* Write, address required */
70
71#define SPI_OPMENU_7 0x0b /* FAST: Fast Read */
72#define SPI_OPTYPE_7 0x02 /* Read, address required */
73
74#define SPI_OPMENU_UPPER ((SPI_OPMENU_7 << 24) | (SPI_OPMENU_6 << 16) | \
75 (SPI_OPMENU_5 << 8) | SPI_OPMENU_4)
76#define SPI_OPMENU_LOWER ((SPI_OPMENU_3 << 24) | (SPI_OPMENU_2 << 16) | \
77 (SPI_OPMENU_1 << 8) | SPI_OPMENU_0)
78
79#define SPI_OPTYPE ((SPI_OPTYPE_7 << 14) | (SPI_OPTYPE_6 << 12) | \
80 (SPI_OPTYPE_5 << 10) | (SPI_OPTYPE_4 << 8) | \
81 (SPI_OPTYPE_3 << 6) | (SPI_OPTYPE_2 << 4) | \
82 (SPI_OPTYPE_1 << 2) | (SPI_OPTYPE_0))
83
84#define SPI_OPPREFIX ((0x50 << 8) | 0x06) /* EWSR and WREN */
85
86#define SPIBAR_OFFSET 0x3800
87#define SPI_REG_PREOP 0x94
88#define SPI_REG_OPTYPE 0x96
89#define SPI_REG_OPMENU_L 0x98
90#define SPI_REG_OPMENU_H 0x9c
91
Werner Zehf7da8922018-02-14 08:08:24 +010092/* Define the slave address for the I/O expander. */
93#define PCA9538_SLAVE_ADR 0x71
Werner Zehfa6f8612016-04-20 10:08:17 +020094/*
95 * mainboard_enable is executed as first thing after enumerate_buses().
96 * This is the earliest point to add customization.
97 */
Elyes HAOUAS47503cd2018-05-04 21:58:51 +020098static void mainboard_enable(struct device *dev)
Werner Zehfa6f8612016-04-20 10:08:17 +020099{
100
101}
Werner Zehe1d6aa62016-07-06 11:59:10 +0200102
Werner Zeha845f422016-07-07 07:10:50 +0200103static void mainboard_init(void *chip_info)
104{
105 uint8_t actl = 0;
Elyes HAOUAS47503cd2018-05-04 21:58:51 +0200106 struct device *dev = dev_find_slot(0, PCI_DEVFN(LPC_DEV, LPC_FUNC));
Werner Zeha845f422016-07-07 07:10:50 +0200107
108 /* Route SCI to IRQ 10 to free IRQ 9 slot. */
109 actl = pci_read_config8(dev, ACPI_CNTL_OFFSET);
110 actl &= ~SCIS_MASK;
111 actl |= SCIS_IRQ10;
112 pci_write_config8(dev, ACPI_CNTL_OFFSET, actl);
Werner Zeh9d18e332016-09-08 07:52:03 +0200113
114 /* Enable additional I/O decoding ranges on LPC for COM 3 and COM 4 */
115 pci_write_config32(dev, LPC_GEN1_DEC, 0x1C02E9);
116 pci_write_config32(dev, LPC_GEN2_DEC, 0x1C03E9);
Werner Zeha845f422016-07-07 07:10:50 +0200117}
118
Werner Zehe1d6aa62016-07-06 11:59:10 +0200119static void mainboard_final(void *chip_info)
120{
121 void *spi_base = NULL;
122 uint32_t rcba = 0;
Elyes HAOUAS47503cd2018-05-04 21:58:51 +0200123 struct device *dev = dev_find_slot(0, PCI_DEVFN(LPC_DEV, LPC_FUNC));
Werner Zehe1d6aa62016-07-06 11:59:10 +0200124
125 /* Get address of SPI controller. */
126 rcba = (pci_read_config32(dev, 0xf0) & 0xffffc000);
127 if (!rcba)
128 return;
129 spi_base = (void *)(rcba + SPIBAR_OFFSET);
130 /* Setup OPCODE menu */
131 write16((spi_base + SPI_REG_PREOP), SPI_OPPREFIX);
132 write16((spi_base + SPI_REG_OPTYPE), SPI_OPTYPE);
133 write32((spi_base + SPI_REG_OPMENU_L), SPI_OPMENU_LOWER);
134 write32((spi_base + SPI_REG_OPMENU_H), SPI_OPMENU_UPPER);
Werner Zeh96b89ae2017-06-28 12:56:31 +0200135
136 /* Set Master Enable for on-board PCI devices. */
137 dev = dev_find_device(PCI_VENDOR_ID_SIEMENS, 0x403e, 0);
138 if (dev) {
139 uint16_t cmd = pci_read_config16(dev, PCI_COMMAND);
140 cmd |= PCI_COMMAND_MASTER;
141 pci_write_config16(dev, PCI_COMMAND, cmd);
142 }
143 dev = dev_find_device(PCI_VENDOR_ID_SIEMENS, 0x403f, 0);
144 if (dev) {
145 uint16_t cmd = pci_read_config16(dev, PCI_COMMAND);
146 cmd |= PCI_COMMAND_MASTER;
147 pci_write_config16(dev, PCI_COMMAND, cmd);
148 }
Werner Zehf7da8922018-02-14 08:08:24 +0100149 /* Show the mainboard version well-visible on console. */
150 printk(BIOS_NOTICE, "***************************\n"
151 "* Mainboard version: 0x%02x *\n"
152 "***************************\n",
153 pca9538_read_input());
Werner Zehe1d6aa62016-07-06 11:59:10 +0200154}
155
Werner Zehb2213ed2016-06-30 08:21:17 +0200156/** \brief This function can decide if a given MAC address is valid or not.
157 * Currently, addresses filled with 0xff or 0x00 are not valid.
158 * @param mac Buffer to the MAC address to check
159 * @return 0 if address is not valid, otherwise 1
160 */
161static uint8_t is_mac_adr_valid(uint8_t mac[6])
162{
163 uint8_t buf[6];
164
165 memset(buf, 0, sizeof(buf));
166 if (!memcmp(buf, mac, sizeof(buf)))
167 return 0;
168 memset(buf, 0xff, sizeof(buf));
169 if (!memcmp(buf, mac, sizeof(buf)))
170 return 0;
171 return 1;
172}
173 /** \brief This function will search for a MAC address which can be assigned
174 * to a MACPHY.
175 * @param dev pointer to PCI device
176 * @param mac buffer where to store the MAC address
177 * @return cb_err CB_ERR or CB_SUCCESS
178 */
179enum cb_err mainboard_get_mac_address(struct device *dev, uint8_t mac[6])
180{
181 struct bus *parent = dev->bus;
182 uint8_t buf[16], mapping[16], i = 0, chain_len = 0;
183
184 memset(buf, 0, sizeof(buf));
185 memset(mapping, 0, sizeof(mapping));
186
187 /* The first entry in the tree is the device itself. */
188 buf[0] = dev->path.pci.devfn;
189 chain_len = 1;
190 for (i = 1; i < MAX_PATH_DEPTH && parent->dev->bus->subordinate; i++) {
191 buf[i] = parent->dev->path.pci.devfn;
192 chain_len++;
193 parent = parent->dev->bus;
194 }
195 if (i == MAX_PATH_DEPTH) {
196 /* The path is deeper than MAX_PATH_DEPTH devices, error. */
197 printk(BIOS_ERR, "Too many bridges for %s\n", dev_path(dev));
198 return CB_ERR;
199 }
200 /* Now construct the mapping based on the device chain starting from */
201 /* root bridge device to the device itself. */
202 mapping[0] = 1;
203 mapping[1] = chain_len;
204 for (i = 0; i < chain_len; i++)
205 mapping[i + 4] = buf[chain_len - i - 1];
206
207 /* Open main hwinfo block */
208 if (hwilib_find_blocks("hwinfo.hex") != CB_SUCCESS)
209 return CB_ERR;
210 /* Now try to find a valid MAC address in hwinfo for this mapping.*/
211 for (i = 0; i < MAX_NUM_MAPPINGS; i++) {
212 if ((hwilib_get_field(XMac1Mapping + i, buf, 16) == 16) &&
213 !(memcmp(buf, mapping, chain_len + 4))) {
214 /* There is a matching mapping available, get MAC address. */
215 if ((hwilib_get_field(XMac1 + i, mac, 6) == 6) &&
216 (is_mac_adr_valid(mac))) {
217 return CB_SUCCESS;
218 } else {
219 return CB_ERR;
220 }
221 } else
222 continue;
223 }
224 /* No MAC address found for */
225 return CB_ERR;
226}
Werner Zehfa6f8612016-04-20 10:08:17 +0200227
Werner Zehc0d1e312017-10-10 12:35:10 +0200228static void wait_for_legacy_dev(void *unused)
229{
230 uint32_t legacy_delay, us_since_boot;
231 struct stopwatch sw;
232
233 /* Open main hwinfo block. */
234 if (hwilib_find_blocks("hwinfo.hex") != CB_SUCCESS)
235 return;
236
237 /* Get legacy delay parameter from hwinfo. */
238 if (hwilib_get_field(LegacyDelay, (uint8_t *) &legacy_delay,
239 sizeof(legacy_delay)) != sizeof(legacy_delay))
240 return;
241
242 us_since_boot = get_us_since_boot();
243 /* No need to wait if the time since boot is already long enough.*/
244 if (us_since_boot > legacy_delay)
245 return;
246 stopwatch_init_msecs_expire(&sw, (legacy_delay - us_since_boot) / 1000);
247 printk(BIOS_NOTICE, "Wait remaining %d of %d us for legacy devices...",
248 legacy_delay - us_since_boot, legacy_delay);
249 stopwatch_wait_until_expired(&sw);
250 printk(BIOS_NOTICE, "done!\n");
251}
252
Werner Zehf7da8922018-02-14 08:08:24 +0100253/*
254 * To access the I/O expander PCA9538 we need to know its device structure.
255 * This function will provide it as mainboard code has the knowledge of the
256 * right I2C slave address for the I/O expander.
257 */
258struct device *pca9538_get_dev(void)
259{
260 struct device *dev = NULL;
Werner Zeh5ea714a2018-02-19 09:49:52 +0100261
262 while ((dev = dev_find_path(dev, DEVICE_PATH_I2C))) {
Werner Zehf7da8922018-02-14 08:08:24 +0100263 if (dev->path.i2c.device == PCA9538_SLAVE_ADR)
264 break;
Werner Zeh5ea714a2018-02-19 09:49:52 +0100265 }
Werner Zehf7da8922018-02-14 08:08:24 +0100266 return dev;
267}
268
269
Werner Zehc0d1e312017-10-10 12:35:10 +0200270BOOT_STATE_INIT_ENTRY(BS_DEV_ENUMERATE, BS_ON_ENTRY, wait_for_legacy_dev, NULL);
271
Werner Zehfa6f8612016-04-20 10:08:17 +0200272struct chip_operations mainboard_ops = {
273 .enable_dev = mainboard_enable,
Werner Zeha845f422016-07-07 07:10:50 +0200274 .init = mainboard_init,
Werner Zehe1d6aa62016-07-06 11:59:10 +0200275 .final = mainboard_final
Werner Zehfa6f8612016-04-20 10:08:17 +0200276};