blob: ddb1374ddf18b1b078150e2feb28cfbcfb01d6d4 [file] [log] [blame]
Andrey Petrov70efecd2016-03-04 21:41:13 -08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2015 Intel Corp.
5 * (Written by Alexandru Gagniuc <alexandrux.gagniuc@intel.com> for Intel Corp.)
6 * (Written by Andrey Petrov <andrey.petrov@intel.com> for Intel Corp.)
7 *
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; either version 2 of the License, or
11 * (at your option) any later version.
Martin Rothebabfad2016-04-10 11:09:16 -060012 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
Andrey Petrov70efecd2016-03-04 21:41:13 -080017 */
18
Hannah Williams0f61da82016-04-18 13:47:08 -070019#include <arch/acpi.h>
Andrey Petrov70efecd2016-03-04 21:41:13 -080020#include <bootstate.h>
Lance Zhao1bd0c0c2016-04-19 18:04:21 -070021#include <cbmem.h>
Andrey Petrov70efecd2016-03-04 21:41:13 -080022#include <console/console.h>
23#include <cpu/cpu.h>
24#include <device/device.h>
25#include <device/pci.h>
26#include <fsp/api.h>
27#include <fsp/util.h>
28#include <memrange.h>
Andrey Petrove07e13d2016-03-18 14:43:00 -070029#include <soc/iomap.h>
Andrey Petrov70efecd2016-03-04 21:41:13 -080030#include <soc/cpu.h>
Andrey Petrov868679f2016-05-12 19:11:48 -070031#include <soc/intel/common/vbt.h>
Lance Zhao1bd0c0c2016-04-19 18:04:21 -070032#include <soc/nvs.h>
Andrey Petrov70efecd2016-03-04 21:41:13 -080033#include <soc/pci_devs.h>
Furquan Shaikh6ac226d2016-06-15 17:13:20 -070034#include <spi-generic.h>
Andrey Petrov3dbea292016-06-14 22:20:28 -070035#include <soc/pm.h>
Andrey Petrov70efecd2016-03-04 21:41:13 -080036
37#include "chip.h"
38
Andrey Petrov868679f2016-05-12 19:11:48 -070039static void *vbt;
40static struct region_device vbt_rdev;
41
Andrey Petrov70efecd2016-03-04 21:41:13 -080042static void pci_domain_set_resources(device_t dev)
43{
44 assign_resources(dev->link_list);
45}
46
47static struct device_operations pci_domain_ops = {
48 .read_resources = pci_domain_read_resources,
49 .set_resources = pci_domain_set_resources,
50 .enable_resources = NULL,
51 .init = NULL,
52 .scan_bus = pci_domain_scan_bus,
53 .ops_pci_bus = pci_bus_default_ops,
54};
55
56static struct device_operations cpu_bus_ops = {
57 .read_resources = DEVICE_NOOP,
58 .set_resources = DEVICE_NOOP,
59 .enable_resources = DEVICE_NOOP,
60 .init = apollolake_init_cpus,
61 .scan_bus = NULL,
Hannah Williams0f61da82016-04-18 13:47:08 -070062 .acpi_fill_ssdt_generator = generate_cpu_entries,
Andrey Petrov70efecd2016-03-04 21:41:13 -080063};
64
65static void enable_dev(device_t dev)
66{
67 /* Set the operations if it is a special bus type */
68 if (dev->path.type == DEVICE_PATH_DOMAIN) {
69 dev->ops = &pci_domain_ops;
70 } else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
71 dev->ops = &cpu_bus_ops;
72 }
73}
74
75static void soc_init(void *data)
76{
77 struct range_entry range;
Lance Zhao1bd0c0c2016-04-19 18:04:21 -070078 struct global_nvs_t *gnvs;
Andrey Petrov70efecd2016-03-04 21:41:13 -080079
Andrey Petrov868679f2016-05-12 19:11:48 -070080 /* Save VBT info and mapping */
81 if (locate_vbt(&vbt_rdev) != CB_ERR)
82 vbt = rdev_mmap_full(&vbt_rdev);
83
Andrey Petrov70efecd2016-03-04 21:41:13 -080084 /* TODO: tigten this resource range */
85 /* TODO: fix for S3 resume, as this would corrupt OS memory */
86 range_entry_init(&range, 0x200000, 4ULL*GiB, 0);
87 fsp_silicon_init(&range);
Lance Zhao1bd0c0c2016-04-19 18:04:21 -070088
89 /* Allocate ACPI NVS in CBMEM */
90 gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof(*gnvs));
Andrey Petrov70efecd2016-03-04 21:41:13 -080091}
92
Andrey Petrov868679f2016-05-12 19:11:48 -070093static void soc_final(void *data)
94{
95 if (vbt)
96 rdev_munmap(&vbt_rdev, vbt);
Andrey Petrov3dbea292016-06-14 22:20:28 -070097
98 /* Disable global reset, just in case */
99 global_reset_enable(0);
100 /* Make sure payload/OS can't trigger global reset */
101 global_reset_lock();
Andrey Petrov868679f2016-05-12 19:11:48 -0700102}
103
Andrey Petrov70efecd2016-03-04 21:41:13 -0800104void platform_fsp_silicon_init_params_cb(struct FSPS_UPD *silupd)
105{
106 struct FSP_S_CONFIG *silconfig = &silupd->FspsConfig;
107 static struct soc_intel_apollolake_config *cfg;
108
109 /* Load VBT before devicetree-specific config. */
Andrey Petrov868679f2016-05-12 19:11:48 -0700110 silconfig->GraphicsConfigPtr = (uintptr_t)vbt;
Andrey Petrov70efecd2016-03-04 21:41:13 -0800111
Alexandru Gagniuc944655d2016-05-18 10:26:53 -0700112 struct device *dev = dev_find_slot(NB_BUS, NB_DEVFN);
Patrick Georgi831d65d2016-04-14 11:53:48 +0200113 if (!dev || !dev->chip_info) {
Andrey Petrov70efecd2016-03-04 21:41:13 -0800114 printk(BIOS_ERR, "BUG! Could not find SOC devicetree config\n");
115 return;
116 }
117
118 cfg = dev->chip_info;
119
120 silconfig->PcieRpClkReqNumber[0] = cfg->pcie_rp0_clkreq_pin;
121 silconfig->PcieRpClkReqNumber[1] = cfg->pcie_rp1_clkreq_pin;
122 silconfig->PcieRpClkReqNumber[2] = cfg->pcie_rp2_clkreq_pin;
123 silconfig->PcieRpClkReqNumber[3] = cfg->pcie_rp3_clkreq_pin;
124 silconfig->PcieRpClkReqNumber[4] = cfg->pcie_rp4_clkreq_pin;
125 silconfig->PcieRpClkReqNumber[5] = cfg->pcie_rp5_clkreq_pin;
Andrey Petrove07e13d2016-03-18 14:43:00 -0700126
Zhao, Lijian1b8ee0b2016-05-17 19:01:34 -0700127 if (cfg->emmc_tx_cmd_cntl != 0)
128 silconfig->EmmcTxCmdCntl = cfg->emmc_tx_cmd_cntl;
129 if (cfg->emmc_tx_data_cntl1 != 0)
130 silconfig->EmmcTxDataCntl1 = cfg->emmc_tx_data_cntl1;
131 if (cfg->emmc_tx_data_cntl2 != 0)
132 silconfig->EmmcTxDataCntl2 = cfg->emmc_tx_data_cntl2;
133 if (cfg->emmc_rx_cmd_data_cntl1 != 0)
134 silconfig->EmmcRxCmdDataCntl1 = cfg->emmc_rx_cmd_data_cntl1;
135 if (cfg->emmc_rx_strobe_cntl != 0)
136 silconfig->EmmcRxStrobeCntl = cfg->emmc_rx_strobe_cntl;
137 if (cfg->emmc_rx_cmd_data_cntl2 != 0)
138 silconfig->EmmcRxCmdDataCntl2 = cfg->emmc_rx_cmd_data_cntl2;
139
Andrey Petrove07e13d2016-03-18 14:43:00 -0700140 /* Our defaults may not match FSP defaults, so set them explicitly */
141 silconfig->AcpiBase = ACPI_PMIO_BASE;
142 /* First 4k in BAR0 is used for IPC, real registers start at 4k offset */
143 silconfig->PmcBase = PMC_BAR0 + 0x1000;
144 silconfig->P2sbBase = P2SB_BAR;
Hannah Williams483004f2016-03-28 14:45:59 -0700145
146 silconfig->IshEnable = cfg->integrated_sensor_hub_enable;
Furquan Shaikhcad9b632016-06-20 16:08:42 -0700147
148 /* Disable setting of EISS bit in FSP. */
149 silconfig->SpiEiss = 0;
Andrey Petrov70efecd2016-03-04 21:41:13 -0800150}
151
152struct chip_operations soc_intel_apollolake_ops = {
153 CHIP_NAME("Intel Apollolake SOC")
154 .enable_dev = &enable_dev,
Andrey Petrov868679f2016-05-12 19:11:48 -0700155 .init = &soc_init,
156 .final = &soc_final
Andrey Petrov70efecd2016-03-04 21:41:13 -0800157};
158
159static void fsp_notify_dummy(void *arg)
160{
161
162 enum fsp_notify_phase ph = (enum fsp_notify_phase) arg;
163
164 if (fsp_notify(ph) != FSP_SUCCESS)
165 printk(BIOS_CRIT, "FspNotify failed!\n");
Hannah Williams5d9cc782016-04-29 14:48:20 -0700166 /* Call END_OF_FIRMWARE Notify after READY_TO_BOOT Notify */
167 if (ph == READY_TO_BOOT)
168 fsp_notify_dummy((void *)END_OF_FIRMWARE);
Andrey Petrov70efecd2016-03-04 21:41:13 -0800169}
170
171BOOT_STATE_INIT_ENTRY(BS_DEV_RESOURCES, BS_ON_EXIT, fsp_notify_dummy,
172 (void *) AFTER_PCI_ENUM);
173BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, fsp_notify_dummy,
174 (void *) READY_TO_BOOT);
175BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, fsp_notify_dummy,
176 (void *) READY_TO_BOOT);
Furquan Shaikh6ac226d2016-06-15 17:13:20 -0700177
178/*
179 * spi_init() needs to run unconditionally on every boot (including resume) to
180 * allow write protect to be disabled for eventlog and nvram updates. This needs
181 * to be done as early as possible in ramstage. Thus, add a callback for entry
182 * into BS_PRE_DEVICE.
183 */
184static void spi_init_cb(void *unused)
185{
186 spi_init();
187}
188
189BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, spi_init_cb, NULL);