blob: 6effa7c0803e4318af68af1ba8d7f06a9891fb21 [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>
Aaron Durbin2fcc0342018-07-25 08:06:21 -060019#include <compiler.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080020#include <console/console.h>
21#include <device/device.h>
Furquan Shaikh617fcf32018-08-08 13:30:44 -070022#include <device/pci_def.h>
23#include <device/pci_ops.h>
Furquan Shaikh367956d52018-07-20 13:50:16 -070024#include <ec/google/chromeec/ec.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080025#include <ec/ec.h>
26#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{
40 struct device *dev = dev_find_slot(0, PCH_DEVFN_CNVI);
41 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;
111 dev->ops->acpi_inject_dsdt_generator = chromeos_dsdt_generator;
112}
113
114struct chip_operations mainboard_ops = {
115 .init = mainboard_init,
116 .enable_dev = mainboard_enable,
117};
Furquan Shaikh367956d52018-07-20 13:50:16 -0700118
119#define SKU_UNKNOWN 0xFFFFFFFF
120#define SKU_MAX 255
121
122static uint32_t get_board_sku(void)
123{
124 static uint32_t sku_id = SKU_UNKNOWN;
125
126 if (sku_id != SKU_UNKNOWN)
127 return sku_id;
128
129 if (google_chromeec_cbi_get_sku_id(&sku_id))
130 sku_id = SKU_UNKNOWN;
131
132 return sku_id;
133}
134
135const char *smbios_mainboard_sku(void)
136{
137 static char sku_str[7]; /* sku{0..255} */
138 uint32_t sku_id = get_board_sku();
139
140 if ((sku_id == SKU_UNKNOWN) || (sku_id > SKU_MAX)) {
141 printk(BIOS_ERR, "%s: Unexpected SKU ID %u\n",
142 __func__, sku_id);
143 return "";
144 }
145
146 snprintf(sku_str, sizeof(sku_str), "sku%u", sku_id);
147
148 return sku_str;
149}
Aaron Durbin2fcc0342018-07-25 08:06:21 -0600150
151void __weak variant_update_devtree(struct device *dev)
152{
153 /* Place holder for common updates. */
154}
155
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700156/*
157 * Check if CNVi PCI device is released from reset. If yes, then the system is
158 * booting with CNVi module. In this case, the PCIe device for WiFi needs to
159 * be disabled. If CNVi device is held in reset, then disable it.
160 */
161static void wifi_device_update(void)
162{
163 struct device *dev;
164 unsigned int devfn;
165
166 if (is_cnvi_held_in_reset())
167 devfn = PCH_DEVFN_CNVI;
168 else
169 devfn = PCH_DEVFN_PCIE1;
170
171 dev = dev_find_slot(0, devfn);
John Zhaoa2c0cf52018-08-20 10:27:39 -0700172 if (dev)
173 dev->enabled = 0;
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700174}
175
Aaron Durbin2fcc0342018-07-25 08:06:21 -0600176void mainboard_devtree_update(struct device *dev)
177{
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700178 /* Apply common devtree updates. */
179 wifi_device_update();
180
Aaron Durbin2fcc0342018-07-25 08:06:21 -0600181 /* Defer to variant for board-specific updates. */
182 variant_update_devtree(dev);
183}