blob: e6dbd0330bfa84c7dd27f8378a1570dec4a7ecd5 [file] [log] [blame]
Angel Pons08b52802020-04-05 13:22:20 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Hannah Williams5e83e8b2018-02-09 18:35:17 -08002
Furquan Shaikh76cedd22020-05-02 10:24:23 -07003#include <acpi/acpi.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -08004#include <baseboard/variants.h>
5#include <boardid.h>
Karthikeyan Ramasubramanian02592ec2019-06-06 15:57:47 -06006#include <bootstate.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -08007#include <console/console.h>
8#include <device/device.h>
Furquan Shaikh617fcf32018-08-08 13:30:44 -07009#include <device/pci_def.h>
10#include <device/pci_ops.h>
Furquan Shaikh367956d52018-07-20 13:50:16 -070011#include <ec/google/chromeec/ec.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080012#include <ec/ec.h>
Karthikeyan Ramasubramanian02592ec2019-06-06 15:57:47 -060013#include <intelblocks/xhci.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080014#include <nhlt.h>
Furquan Shaikh367956d52018-07-20 13:50:16 -070015#include <smbios.h>
Aaron Durbin2fcc0342018-07-25 08:06:21 -060016#include <soc/cpu.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080017#include <soc/gpio.h>
18#include <soc/nhlt.h>
Furquan Shaikh617fcf32018-08-08 13:30:44 -070019#include <soc/pci_devs.h>
20#include <stdint.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080021#include <vendorcode/google/chromeos/chromeos.h>
22#include <variant/ec.h>
23#include <variant/gpio.h>
24
Furquan Shaikh617fcf32018-08-08 13:30:44 -070025static bool is_cnvi_held_in_reset(void)
26{
Kyösti Mälkkie7377552018-06-21 16:20:55 +030027 struct device *dev = pcidev_path_on_root(PCH_DEVFN_CNVI);
Furquan Shaikh617fcf32018-08-08 13:30:44 -070028 uint32_t reg = pci_read_config32(dev, PCI_VENDOR_ID);
29
30 /*
31 * If vendor/device ID for CNVi reads as 0xffffffff, then it is safe to
32 * assume that it is being held in reset.
33 */
34 if (reg == 0xffffffff)
35 return true;
36
37 return false;
38}
39
Furquan Shaikh65428992018-08-09 10:11:26 -070040static void disable_wifi_wake(void)
41{
42 static const struct pad_config wifi_wake_gpio[] = {
43 PAD_NC(GPIO_119, UP_20K),
44 };
45
46 gpio_configure_pads(wifi_wake_gpio, ARRAY_SIZE(wifi_wake_gpio));
47}
48
Hannah Williams5e83e8b2018-02-09 18:35:17 -080049static void mainboard_init(void *chip_info)
50{
51 int boardid;
Furquan Shaikh06a41f12018-07-25 14:30:59 -070052 const struct pad_config *base_pads;
53 const struct pad_config *override_pads;
54 size_t base_num, override_num;
Hannah Williams5e83e8b2018-02-09 18:35:17 -080055
56 boardid = board_id();
57 printk(BIOS_INFO, "Board ID: %d\n", boardid);
58
Furquan Shaikh06a41f12018-07-25 14:30:59 -070059 base_pads = variant_base_gpio_table(&base_num);
60 override_pads = variant_override_gpio_table(&override_num);
61
62 gpio_configure_pads_with_override(base_pads, base_num,
63 override_pads, override_num);
Hannah Williams5e83e8b2018-02-09 18:35:17 -080064
Furquan Shaikh65428992018-08-09 10:11:26 -070065 if (!is_cnvi_held_in_reset())
66 disable_wifi_wake();
67
Hannah Williams5e83e8b2018-02-09 18:35:17 -080068 mainboard_ec_init();
69}
70
71static unsigned long mainboard_write_acpi_tables(
Furquan Shaikh0f007d82020-04-24 06:41:18 -070072 const struct device *device, unsigned long current, acpi_rsdp_t *rsdp)
Hannah Williams5e83e8b2018-02-09 18:35:17 -080073{
74 uintptr_t start_addr;
75 uintptr_t end_addr;
76 struct nhlt *nhlt;
77
78 start_addr = current;
79
80 nhlt = nhlt_init();
81
82 if (nhlt == NULL)
83 return start_addr;
84
85 variant_nhlt_init(nhlt);
86
87 end_addr = nhlt_soc_serialize(nhlt, start_addr);
88
89 if (end_addr != start_addr)
90 acpi_add_table(rsdp, (void *)start_addr);
91
92 return end_addr;
93}
94
Elyes HAOUASd129d432018-05-04 20:23:33 +020095static void mainboard_enable(struct device *dev)
Hannah Williams5e83e8b2018-02-09 18:35:17 -080096{
97 dev->ops->write_acpi_tables = mainboard_write_acpi_tables;
Nico Huber68680dd2020-03-31 17:34:52 +020098 dev->ops->acpi_inject_dsdt = chromeos_dsdt_generator;
Hannah Williams5e83e8b2018-02-09 18:35:17 -080099}
100
101struct chip_operations mainboard_ops = {
102 .init = mainboard_init,
103 .enable_dev = mainboard_enable,
104};
Furquan Shaikh367956d52018-07-20 13:50:16 -0700105
Aaron Durbin2fcc0342018-07-25 08:06:21 -0600106void __weak variant_update_devtree(struct device *dev)
107{
108 /* Place holder for common updates. */
109}
110
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700111/*
112 * Check if CNVi PCI device is released from reset. If yes, then the system is
113 * booting with CNVi module. In this case, the PCIe device for WiFi needs to
114 * be disabled. If CNVi device is held in reset, then disable it.
115 */
116static void wifi_device_update(void)
117{
118 struct device *dev;
119 unsigned int devfn;
120
121 if (is_cnvi_held_in_reset())
122 devfn = PCH_DEVFN_CNVI;
123 else
124 devfn = PCH_DEVFN_PCIE1;
125
Kyösti Mälkkie7377552018-06-21 16:20:55 +0300126 dev = pcidev_path_on_root(devfn);
John Zhaoa2c0cf52018-08-20 10:27:39 -0700127 if (dev)
128 dev->enabled = 0;
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700129}
130
Aaron Durbin2fcc0342018-07-25 08:06:21 -0600131void mainboard_devtree_update(struct device *dev)
132{
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700133 /* Apply common devtree updates. */
134 wifi_device_update();
135
Aaron Durbin2fcc0342018-07-25 08:06:21 -0600136 /* Defer to variant for board-specific updates. */
137 variant_update_devtree(dev);
138}
Wisley Chenbd3568a2018-11-06 17:38:57 +0800139
Karthikeyan Ramasubramanian02592ec2019-06-06 15:57:47 -0600140bool __weak variant_ext_usb_status(unsigned int port_type, unsigned int port_id)
141{
142 /* All externally visible USB ports are present */
143 return true;
144}
145
146static void disable_unused_devices(void *unused)
147{
148 usb_xhci_disable_unused(variant_ext_usb_status);
149}
150
151BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, disable_unused_devices, NULL);