blob: e0040f3fb2a776e2e029cb218ec919c3800eae11 [file] [log] [blame]
Angel Pons08b52802020-04-05 13:22:20 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Hannah Williams5e83e8b2018-02-09 18:35:17 -08003
4#include <arch/acpi.h>
5#include <baseboard/variants.h>
6#include <boardid.h>
Karthikeyan Ramasubramanian02592ec2019-06-06 15:57:47 -06007#include <bootstate.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -08008#include <console/console.h>
9#include <device/device.h>
Furquan Shaikh617fcf32018-08-08 13:30:44 -070010#include <device/pci_def.h>
11#include <device/pci_ops.h>
Furquan Shaikh367956d52018-07-20 13:50:16 -070012#include <ec/google/chromeec/ec.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080013#include <ec/ec.h>
Karthikeyan Ramasubramanian02592ec2019-06-06 15:57:47 -060014#include <intelblocks/xhci.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080015#include <nhlt.h>
Furquan Shaikh367956d52018-07-20 13:50:16 -070016#include <smbios.h>
Aaron Durbin2fcc0342018-07-25 08:06:21 -060017#include <soc/cpu.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080018#include <soc/gpio.h>
19#include <soc/nhlt.h>
Furquan Shaikh617fcf32018-08-08 13:30:44 -070020#include <soc/pci_devs.h>
21#include <stdint.h>
Furquan Shaikh367956d52018-07-20 13:50:16 -070022#include <string.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080023#include <vendorcode/google/chromeos/chromeos.h>
24#include <variant/ec.h>
25#include <variant/gpio.h>
26
Furquan Shaikh617fcf32018-08-08 13:30:44 -070027static bool is_cnvi_held_in_reset(void)
28{
Kyösti Mälkkie7377552018-06-21 16:20:55 +030029 struct device *dev = pcidev_path_on_root(PCH_DEVFN_CNVI);
Furquan Shaikh617fcf32018-08-08 13:30:44 -070030 uint32_t reg = pci_read_config32(dev, PCI_VENDOR_ID);
31
32 /*
33 * If vendor/device ID for CNVi reads as 0xffffffff, then it is safe to
34 * assume that it is being held in reset.
35 */
36 if (reg == 0xffffffff)
37 return true;
38
39 return false;
40}
41
Furquan Shaikh65428992018-08-09 10:11:26 -070042static void disable_wifi_wake(void)
43{
44 static const struct pad_config wifi_wake_gpio[] = {
45 PAD_NC(GPIO_119, UP_20K),
46 };
47
48 gpio_configure_pads(wifi_wake_gpio, ARRAY_SIZE(wifi_wake_gpio));
49}
50
Hannah Williams5e83e8b2018-02-09 18:35:17 -080051static void mainboard_init(void *chip_info)
52{
53 int boardid;
Furquan Shaikh06a41f12018-07-25 14:30:59 -070054 const struct pad_config *base_pads;
55 const struct pad_config *override_pads;
56 size_t base_num, override_num;
Hannah Williams5e83e8b2018-02-09 18:35:17 -080057
58 boardid = board_id();
59 printk(BIOS_INFO, "Board ID: %d\n", boardid);
60
Furquan Shaikh06a41f12018-07-25 14:30:59 -070061 base_pads = variant_base_gpio_table(&base_num);
62 override_pads = variant_override_gpio_table(&override_num);
63
64 gpio_configure_pads_with_override(base_pads, base_num,
65 override_pads, override_num);
Hannah Williams5e83e8b2018-02-09 18:35:17 -080066
Furquan Shaikh65428992018-08-09 10:11:26 -070067 if (!is_cnvi_held_in_reset())
68 disable_wifi_wake();
69
Hannah Williams5e83e8b2018-02-09 18:35:17 -080070 mainboard_ec_init();
71}
72
73static unsigned long mainboard_write_acpi_tables(
Elyes HAOUASd129d432018-05-04 20:23:33 +020074 struct device *device, unsigned long current, acpi_rsdp_t *rsdp)
Hannah Williams5e83e8b2018-02-09 18:35:17 -080075{
76 uintptr_t start_addr;
77 uintptr_t end_addr;
78 struct nhlt *nhlt;
79
80 start_addr = current;
81
82 nhlt = nhlt_init();
83
84 if (nhlt == NULL)
85 return start_addr;
86
87 variant_nhlt_init(nhlt);
88
89 end_addr = nhlt_soc_serialize(nhlt, start_addr);
90
91 if (end_addr != start_addr)
92 acpi_add_table(rsdp, (void *)start_addr);
93
94 return end_addr;
95}
96
Elyes HAOUASd129d432018-05-04 20:23:33 +020097static void mainboard_enable(struct device *dev)
Hannah Williams5e83e8b2018-02-09 18:35:17 -080098{
99 dev->ops->write_acpi_tables = mainboard_write_acpi_tables;
Nico Huber68680dd2020-03-31 17:34:52 +0200100 dev->ops->acpi_inject_dsdt = chromeos_dsdt_generator;
Hannah Williams5e83e8b2018-02-09 18:35:17 -0800101}
102
103struct chip_operations mainboard_ops = {
104 .init = mainboard_init,
105 .enable_dev = mainboard_enable,
106};
Furquan Shaikh367956d52018-07-20 13:50:16 -0700107
Aaron Durbin2fcc0342018-07-25 08:06:21 -0600108void __weak variant_update_devtree(struct device *dev)
109{
110 /* Place holder for common updates. */
111}
112
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700113/*
114 * Check if CNVi PCI device is released from reset. If yes, then the system is
115 * booting with CNVi module. In this case, the PCIe device for WiFi needs to
116 * be disabled. If CNVi device is held in reset, then disable it.
117 */
118static void wifi_device_update(void)
119{
120 struct device *dev;
121 unsigned int devfn;
122
123 if (is_cnvi_held_in_reset())
124 devfn = PCH_DEVFN_CNVI;
125 else
126 devfn = PCH_DEVFN_PCIE1;
127
Kyösti Mälkkie7377552018-06-21 16:20:55 +0300128 dev = pcidev_path_on_root(devfn);
John Zhaoa2c0cf52018-08-20 10:27:39 -0700129 if (dev)
130 dev->enabled = 0;
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700131}
132
Aaron Durbin2fcc0342018-07-25 08:06:21 -0600133void mainboard_devtree_update(struct device *dev)
134{
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700135 /* Apply common devtree updates. */
136 wifi_device_update();
137
Aaron Durbin2fcc0342018-07-25 08:06:21 -0600138 /* Defer to variant for board-specific updates. */
139 variant_update_devtree(dev);
140}
Wisley Chenbd3568a2018-11-06 17:38:57 +0800141
142const char *smbios_mainboard_manufacturer(void)
143{
144 static char oem_name[32];
145 static const char *manuf;
146
147 if (manuf)
148 return manuf;
149
150 if (google_chromeec_cbi_get_oem_name(&oem_name[0],
151 ARRAY_SIZE(oem_name)) < 0) {
152 printk(BIOS_ERR, "Couldn't obtain OEM name from CBI\n");
153 manuf = CONFIG_MAINBOARD_SMBIOS_MANUFACTURER;
154 } else {
155 manuf = &oem_name[0];
156 }
157
158 return manuf;
159}
Karthikeyan Ramasubramanian02592ec2019-06-06 15:57:47 -0600160
161bool __weak variant_ext_usb_status(unsigned int port_type, unsigned int port_id)
162{
163 /* All externally visible USB ports are present */
164 return true;
165}
166
167static void disable_unused_devices(void *unused)
168{
169 usb_xhci_disable_unused(variant_ext_usb_status);
170}
171
172BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, disable_unused_devices, NULL);