blob: 9547bec275f4304798cb1c7b9781f37566816aa4 [file] [log] [blame]
Mariusz Szafranskia4041332017-08-02 17:28:17 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2015 - 2017 Intel Corp.
5 *
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; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <arch/acpi.h>
18#include <bootstate.h>
19#include <cbfs.h>
20#include <cbmem.h>
21#include <console/console.h>
22#include <cpu/cpu.h>
23#include <device/device.h>
24#include <device/pci.h>
25#include <fsp/api.h>
26#include <fsp/util.h>
27#include <intelblocks/fast_spi.h>
28#include <soc/iomap.h>
29#include <soc/intel/common/vbt.h>
30#include <soc/pci_devs.h>
31#include <soc/ramstage.h>
32#include <soc/fiamux.h>
33#include <spi-generic.h>
34#include <hsio.h>
35#include <harcuvar_boardid.h>
36
37static void pci_domain_set_resources(device_t dev)
38{
39 assign_resources(dev->link_list);
40}
41
42static struct device_operations pci_domain_ops = {
43 .read_resources = &pci_domain_read_resources,
44 .set_resources = &pci_domain_set_resources,
45 .scan_bus = &pci_domain_scan_bus,
46 .ops_pci_bus = &pci_bus_default_ops,
47};
48
49static struct device_operations cpu_bus_ops = {
50 .read_resources = DEVICE_NOOP,
51 .set_resources = DEVICE_NOOP,
52 .enable_resources = DEVICE_NOOP,
53 .init = denverton_init_cpus,
54 .scan_bus = NULL,
55#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
56 .acpi_fill_ssdt_generator = generate_cpu_entries,
57#endif
58};
59
60static void soc_enable_dev(device_t dev)
61{
62 /* Set the operations if it is a special bus type */
63 if (dev->path.type == DEVICE_PATH_DOMAIN)
64 dev->ops = &pci_domain_ops;
65 else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER)
66 dev->ops = &cpu_bus_ops;
67}
68
69static void soc_init(void *data) { fsp_silicon_init(false); }
70
71static void soc_final(void *data) {}
72
73static void soc_silicon_init_params(FSPS_UPD *silupd)
74{
75 size_t num;
76 uint16_t supported_hsio_lanes;
77 uint8_t boardid = board_id();
78 BL_HSIO_INFORMATION *hsio_config;
79 BL_FIA_MUX_CONFIG_HOB *fiamux_hob_data = get_fiamux_hob_data();
80
81 /* Configure FIA MUX PCD */
82 supported_hsio_lanes =
83 (uint16_t)fiamux_hob_data->FiaMuxConfig.SkuNumLanesAllowed;
84
85 switch (boardid) {
86 case BoardIdHarcuvar:
87 num = ARRAY_SIZE(harcuvar_hsio_config);
88 hsio_config = (BL_HSIO_INFORMATION *)harcuvar_hsio_config;
89 break;
90 default:
91 num = 0;
92 hsio_config = NULL;
93 break;
94 }
95
96 if (get_fiamux_hsio_info(supported_hsio_lanes, num, &hsio_config))
97 die("HSIO Configuration is invalid, please correct it!");
98
99 /* Check the requested FIA MUX Configuration */
100 if (!(&hsio_config->FiaConfig)) {
101 die("Requested FIA MUX Configuration is invalid,"
102 " please correct it!");
103 }
104
105 /* Initialize PCIE Bifurcation & HSIO configuration */
106 silupd->FspsConfig.PcdBifurcationPcie0 = hsio_config->PcieBifCtr[0];
107 silupd->FspsConfig.PcdBifurcationPcie1 = hsio_config->PcieBifCtr[1];
108
109 silupd->FspsConfig.PcdFiaMuxConfigRequestPtr =
110 (uint32_t)&hsio_config->FiaConfig;
111}
112
113void platform_fsp_silicon_init_params_cb(FSPS_UPD *silupd)
114{
115 const struct microcode *microcode_file;
116 size_t microcode_len;
117
118 microcode_file = cbfs_boot_map_with_leak("cpu_microcode_blob.bin",
119 CBFS_TYPE_MICROCODE, &microcode_len);
120
121 if ((microcode_file != NULL) && (microcode_len != 0)) {
122 /* Update CPU Microcode patch base address/size */
123 silupd->FspsConfig.PcdCpuMicrocodePatchBase =
124 (uint32_t)microcode_file;
125 silupd->FspsConfig.PcdCpuMicrocodePatchSize =
126 (uint32_t)microcode_len;
127 }
128
129 soc_silicon_init_params(silupd);
130 mainboard_silicon_init_params(silupd);
131}
132
133struct chip_operations soc_intel_denverton_ns_ops = {
134 CHIP_NAME("Intel Denverton-NS SOC")
135 .enable_dev = &soc_enable_dev,
136 .init = &soc_init,
137 .final = &soc_final
138};
139
140static void soc_set_subsystem(device_t dev, uint32_t vendor, uint32_t device)
141{
142 if (!vendor || !device) {
143 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
144 pci_read_config32(dev, PCI_VENDOR_ID));
145 } else {
146 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
147 ((device & 0xffff) << 16) |
148 (vendor & 0xffff));
149 }
150}
151
152struct pci_operations soc_pci_ops = {
153 .set_subsystem = soc_set_subsystem,
154};
155
156/*
157 * spi_flash init() needs to run unconditionally on every boot (including
158 * resume) to allow write protect to be disabled for eventlog and nvram
159 * updates. This needs to be done as early as possible in ramstage. Thus, add a
160 * callback for entry into BS_PRE_DEVICE.
161 */
162static void spi_flash_init_cb(void *unused)
163{
164 fast_spi_init();
165}
166
167BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, spi_flash_init_cb, NULL);