blob: 91cf1e4b7014f32b3d8b4e4d06bdaed9104a8d5f [file] [log] [blame]
Hannah Williams5e83e8b2018-02-09 18:35:17 -08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2018 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; 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 <arch/acpi.h>
17#include <baseboard/variants.h>
18#include <boardid.h>
19#include <console/console.h>
20#include <device/device.h>
Furquan Shaikh617fcf32018-08-08 13:30:44 -070021#include <device/pci_def.h>
22#include <device/pci_ops.h>
Furquan Shaikh367956d52018-07-20 13:50:16 -070023#include <ec/google/chromeec/ec.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080024#include <ec/ec.h>
25#include <nhlt.h>
Furquan Shaikh367956d52018-07-20 13:50:16 -070026#include <smbios.h>
Aaron Durbin2fcc0342018-07-25 08:06:21 -060027#include <soc/cpu.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080028#include <soc/gpio.h>
29#include <soc/nhlt.h>
Furquan Shaikh617fcf32018-08-08 13:30:44 -070030#include <soc/pci_devs.h>
31#include <stdint.h>
Furquan Shaikh367956d52018-07-20 13:50:16 -070032#include <string.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080033#include <vendorcode/google/chromeos/chromeos.h>
34#include <variant/ec.h>
35#include <variant/gpio.h>
36
Furquan Shaikh617fcf32018-08-08 13:30:44 -070037static bool is_cnvi_held_in_reset(void)
38{
Kyösti Mälkkie7377552018-06-21 16:20:55 +030039 struct device *dev = pcidev_path_on_root(PCH_DEVFN_CNVI);
Furquan Shaikh617fcf32018-08-08 13:30:44 -070040 uint32_t reg = pci_read_config32(dev, PCI_VENDOR_ID);
41
42 /*
43 * If vendor/device ID for CNVi reads as 0xffffffff, then it is safe to
44 * assume that it is being held in reset.
45 */
46 if (reg == 0xffffffff)
47 return true;
48
49 return false;
50}
51
Furquan Shaikh65428992018-08-09 10:11:26 -070052static void disable_wifi_wake(void)
53{
54 static const struct pad_config wifi_wake_gpio[] = {
55 PAD_NC(GPIO_119, UP_20K),
56 };
57
58 gpio_configure_pads(wifi_wake_gpio, ARRAY_SIZE(wifi_wake_gpio));
59}
60
Hannah Williams5e83e8b2018-02-09 18:35:17 -080061static void mainboard_init(void *chip_info)
62{
63 int boardid;
Furquan Shaikh06a41f12018-07-25 14:30:59 -070064 const struct pad_config *base_pads;
65 const struct pad_config *override_pads;
66 size_t base_num, override_num;
Hannah Williams5e83e8b2018-02-09 18:35:17 -080067
68 boardid = board_id();
69 printk(BIOS_INFO, "Board ID: %d\n", boardid);
70
Furquan Shaikh06a41f12018-07-25 14:30:59 -070071 base_pads = variant_base_gpio_table(&base_num);
72 override_pads = variant_override_gpio_table(&override_num);
73
74 gpio_configure_pads_with_override(base_pads, base_num,
75 override_pads, override_num);
Hannah Williams5e83e8b2018-02-09 18:35:17 -080076
Furquan Shaikh65428992018-08-09 10:11:26 -070077 if (!is_cnvi_held_in_reset())
78 disable_wifi_wake();
79
Hannah Williams5e83e8b2018-02-09 18:35:17 -080080 mainboard_ec_init();
81}
82
83static unsigned long mainboard_write_acpi_tables(
Elyes HAOUASd129d432018-05-04 20:23:33 +020084 struct device *device, unsigned long current, acpi_rsdp_t *rsdp)
Hannah Williams5e83e8b2018-02-09 18:35:17 -080085{
86 uintptr_t start_addr;
87 uintptr_t end_addr;
88 struct nhlt *nhlt;
89
90 start_addr = current;
91
92 nhlt = nhlt_init();
93
94 if (nhlt == NULL)
95 return start_addr;
96
97 variant_nhlt_init(nhlt);
98
99 end_addr = nhlt_soc_serialize(nhlt, start_addr);
100
101 if (end_addr != start_addr)
102 acpi_add_table(rsdp, (void *)start_addr);
103
104 return end_addr;
105}
106
Elyes HAOUASd129d432018-05-04 20:23:33 +0200107static void mainboard_enable(struct device *dev)
Hannah Williams5e83e8b2018-02-09 18:35:17 -0800108{
109 dev->ops->write_acpi_tables = mainboard_write_acpi_tables;
110 dev->ops->acpi_inject_dsdt_generator = chromeos_dsdt_generator;
111}
112
113struct chip_operations mainboard_ops = {
114 .init = mainboard_init,
115 .enable_dev = mainboard_enable,
116};
Furquan Shaikh367956d52018-07-20 13:50:16 -0700117
118#define SKU_UNKNOWN 0xFFFFFFFF
119#define SKU_MAX 255
120
Kevin Chiu5e450532019-06-14 00:23:14 +0800121uint32_t get_board_sku(void)
Furquan Shaikh367956d52018-07-20 13:50:16 -0700122{
123 static uint32_t sku_id = SKU_UNKNOWN;
124
125 if (sku_id != SKU_UNKNOWN)
126 return sku_id;
127
128 if (google_chromeec_cbi_get_sku_id(&sku_id))
129 sku_id = SKU_UNKNOWN;
130
131 return sku_id;
132}
133
Nico Huberebd8a4f2017-11-01 09:49:16 +0100134const char *smbios_system_sku(void)
Furquan Shaikh367956d52018-07-20 13:50:16 -0700135{
136 static char sku_str[7]; /* sku{0..255} */
137 uint32_t sku_id = get_board_sku();
138
139 if ((sku_id == SKU_UNKNOWN) || (sku_id > SKU_MAX)) {
140 printk(BIOS_ERR, "%s: Unexpected SKU ID %u\n",
141 __func__, sku_id);
142 return "";
143 }
144
145 snprintf(sku_str, sizeof(sku_str), "sku%u", sku_id);
146
147 return sku_str;
148}
Aaron Durbin2fcc0342018-07-25 08:06:21 -0600149
150void __weak variant_update_devtree(struct device *dev)
151{
152 /* Place holder for common updates. */
153}
154
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700155/*
156 * Check if CNVi PCI device is released from reset. If yes, then the system is
157 * booting with CNVi module. In this case, the PCIe device for WiFi needs to
158 * be disabled. If CNVi device is held in reset, then disable it.
159 */
160static void wifi_device_update(void)
161{
162 struct device *dev;
163 unsigned int devfn;
164
165 if (is_cnvi_held_in_reset())
166 devfn = PCH_DEVFN_CNVI;
167 else
168 devfn = PCH_DEVFN_PCIE1;
169
Kyösti Mälkkie7377552018-06-21 16:20:55 +0300170 dev = pcidev_path_on_root(devfn);
John Zhaoa2c0cf52018-08-20 10:27:39 -0700171 if (dev)
172 dev->enabled = 0;
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700173}
174
Aaron Durbin2fcc0342018-07-25 08:06:21 -0600175void mainboard_devtree_update(struct device *dev)
176{
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700177 /* Apply common devtree updates. */
178 wifi_device_update();
179
Aaron Durbin2fcc0342018-07-25 08:06:21 -0600180 /* Defer to variant for board-specific updates. */
181 variant_update_devtree(dev);
182}
Wisley Chenbd3568a2018-11-06 17:38:57 +0800183
184const char *smbios_mainboard_manufacturer(void)
185{
186 static char oem_name[32];
187 static const char *manuf;
188
189 if (manuf)
190 return manuf;
191
192 if (google_chromeec_cbi_get_oem_name(&oem_name[0],
193 ARRAY_SIZE(oem_name)) < 0) {
194 printk(BIOS_ERR, "Couldn't obtain OEM name from CBI\n");
195 manuf = CONFIG_MAINBOARD_SMBIOS_MANUFACTURER;
196 } else {
197 manuf = &oem_name[0];
198 }
199
200 return manuf;
201}