blob: 7b73b9d1bea843c74eb902d0a58295ea2c22f4bb [file] [log] [blame]
Hannah Williams5e83e8b2018-02-09 18:35:17 -08001/*
2 * This file is part of the coreboot project.
3 *
Hannah Williams5e83e8b2018-02-09 18:35:17 -08004 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <arch/acpi.h>
16#include <baseboard/variants.h>
17#include <boardid.h>
Karthikeyan Ramasubramanian02592ec2019-06-06 15:57:47 -060018#include <bootstate.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080019#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>
Karthikeyan Ramasubramanian02592ec2019-06-06 15:57:47 -060025#include <intelblocks/xhci.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080026#include <nhlt.h>
Furquan Shaikh367956d52018-07-20 13:50:16 -070027#include <smbios.h>
Aaron Durbin2fcc0342018-07-25 08:06:21 -060028#include <soc/cpu.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080029#include <soc/gpio.h>
30#include <soc/nhlt.h>
Furquan Shaikh617fcf32018-08-08 13:30:44 -070031#include <soc/pci_devs.h>
32#include <stdint.h>
Furquan Shaikh367956d52018-07-20 13:50:16 -070033#include <string.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080034#include <vendorcode/google/chromeos/chromeos.h>
35#include <variant/ec.h>
36#include <variant/gpio.h>
37
Furquan Shaikh617fcf32018-08-08 13:30:44 -070038static bool is_cnvi_held_in_reset(void)
39{
Kyösti Mälkkie7377552018-06-21 16:20:55 +030040 struct device *dev = pcidev_path_on_root(PCH_DEVFN_CNVI);
Furquan Shaikh617fcf32018-08-08 13:30:44 -070041 uint32_t reg = pci_read_config32(dev, PCI_VENDOR_ID);
42
43 /*
44 * If vendor/device ID for CNVi reads as 0xffffffff, then it is safe to
45 * assume that it is being held in reset.
46 */
47 if (reg == 0xffffffff)
48 return true;
49
50 return false;
51}
52
Furquan Shaikh65428992018-08-09 10:11:26 -070053static void disable_wifi_wake(void)
54{
55 static const struct pad_config wifi_wake_gpio[] = {
56 PAD_NC(GPIO_119, UP_20K),
57 };
58
59 gpio_configure_pads(wifi_wake_gpio, ARRAY_SIZE(wifi_wake_gpio));
60}
61
Hannah Williams5e83e8b2018-02-09 18:35:17 -080062static void mainboard_init(void *chip_info)
63{
64 int boardid;
Furquan Shaikh06a41f12018-07-25 14:30:59 -070065 const struct pad_config *base_pads;
66 const struct pad_config *override_pads;
67 size_t base_num, override_num;
Hannah Williams5e83e8b2018-02-09 18:35:17 -080068
69 boardid = board_id();
70 printk(BIOS_INFO, "Board ID: %d\n", boardid);
71
Furquan Shaikh06a41f12018-07-25 14:30:59 -070072 base_pads = variant_base_gpio_table(&base_num);
73 override_pads = variant_override_gpio_table(&override_num);
74
75 gpio_configure_pads_with_override(base_pads, base_num,
76 override_pads, override_num);
Hannah Williams5e83e8b2018-02-09 18:35:17 -080077
Furquan Shaikh65428992018-08-09 10:11:26 -070078 if (!is_cnvi_held_in_reset())
79 disable_wifi_wake();
80
Hannah Williams5e83e8b2018-02-09 18:35:17 -080081 mainboard_ec_init();
82}
83
84static unsigned long mainboard_write_acpi_tables(
Elyes HAOUASd129d432018-05-04 20:23:33 +020085 struct device *device, unsigned long current, acpi_rsdp_t *rsdp)
Hannah Williams5e83e8b2018-02-09 18:35:17 -080086{
87 uintptr_t start_addr;
88 uintptr_t end_addr;
89 struct nhlt *nhlt;
90
91 start_addr = current;
92
93 nhlt = nhlt_init();
94
95 if (nhlt == NULL)
96 return start_addr;
97
98 variant_nhlt_init(nhlt);
99
100 end_addr = nhlt_soc_serialize(nhlt, start_addr);
101
102 if (end_addr != start_addr)
103 acpi_add_table(rsdp, (void *)start_addr);
104
105 return end_addr;
106}
107
Elyes HAOUASd129d432018-05-04 20:23:33 +0200108static void mainboard_enable(struct device *dev)
Hannah Williams5e83e8b2018-02-09 18:35:17 -0800109{
110 dev->ops->write_acpi_tables = mainboard_write_acpi_tables;
Nico Huber68680dd2020-03-31 17:34:52 +0200111 dev->ops->acpi_inject_dsdt = chromeos_dsdt_generator;
Hannah Williams5e83e8b2018-02-09 18:35:17 -0800112}
113
114struct chip_operations mainboard_ops = {
115 .init = mainboard_init,
116 .enable_dev = mainboard_enable,
117};
Furquan Shaikh367956d52018-07-20 13:50:16 -0700118
Aaron Durbin2fcc0342018-07-25 08:06:21 -0600119void __weak variant_update_devtree(struct device *dev)
120{
121 /* Place holder for common updates. */
122}
123
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700124/*
125 * Check if CNVi PCI device is released from reset. If yes, then the system is
126 * booting with CNVi module. In this case, the PCIe device for WiFi needs to
127 * be disabled. If CNVi device is held in reset, then disable it.
128 */
129static void wifi_device_update(void)
130{
131 struct device *dev;
132 unsigned int devfn;
133
134 if (is_cnvi_held_in_reset())
135 devfn = PCH_DEVFN_CNVI;
136 else
137 devfn = PCH_DEVFN_PCIE1;
138
Kyösti Mälkkie7377552018-06-21 16:20:55 +0300139 dev = pcidev_path_on_root(devfn);
John Zhaoa2c0cf52018-08-20 10:27:39 -0700140 if (dev)
141 dev->enabled = 0;
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700142}
143
Aaron Durbin2fcc0342018-07-25 08:06:21 -0600144void mainboard_devtree_update(struct device *dev)
145{
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700146 /* Apply common devtree updates. */
147 wifi_device_update();
148
Aaron Durbin2fcc0342018-07-25 08:06:21 -0600149 /* Defer to variant for board-specific updates. */
150 variant_update_devtree(dev);
151}
Wisley Chenbd3568a2018-11-06 17:38:57 +0800152
153const char *smbios_mainboard_manufacturer(void)
154{
155 static char oem_name[32];
156 static const char *manuf;
157
158 if (manuf)
159 return manuf;
160
161 if (google_chromeec_cbi_get_oem_name(&oem_name[0],
162 ARRAY_SIZE(oem_name)) < 0) {
163 printk(BIOS_ERR, "Couldn't obtain OEM name from CBI\n");
164 manuf = CONFIG_MAINBOARD_SMBIOS_MANUFACTURER;
165 } else {
166 manuf = &oem_name[0];
167 }
168
169 return manuf;
170}
Karthikeyan Ramasubramanian02592ec2019-06-06 15:57:47 -0600171
172bool __weak variant_ext_usb_status(unsigned int port_type, unsigned int port_id)
173{
174 /* All externally visible USB ports are present */
175 return true;
176}
177
178static void disable_unused_devices(void *unused)
179{
180 usb_xhci_disable_unused(variant_ext_usb_status);
181}
182
183BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, disable_unused_devices, NULL);