blob: 9ffd63373868461c4fc2d2ab3e3de4b0e67dea99 [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>
Marco Chen07c80b22020-12-21 22:10:21 +08004#include <baseboard/cbi_ssfc.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -08005#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>
Marco Chen07c80b22020-12-21 22:10:21 +080012#include <drivers/i2c/generic/chip.h>
Furquan Shaikh367956d52018-07-20 13:50:16 -070013#include <ec/google/chromeec/ec.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080014#include <ec/ec.h>
Karthikeyan Ramasubramanian02592ec2019-06-06 15:57:47 -060015#include <intelblocks/xhci.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080016#include <nhlt.h>
Furquan Shaikh367956d52018-07-20 13:50:16 -070017#include <smbios.h>
Aaron Durbin2fcc0342018-07-25 08:06:21 -060018#include <soc/cpu.h>
Hannah Williams5e83e8b2018-02-09 18:35:17 -080019#include <soc/gpio.h>
20#include <soc/nhlt.h>
Furquan Shaikh617fcf32018-08-08 13:30:44 -070021#include <soc/pci_devs.h>
22#include <stdint.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
Marco Chen07c80b22020-12-21 22:10:21 +080027extern struct chip_operations drivers_i2c_generic_ops;
Eric Lai598f2ba2021-04-15 11:43:02 +080028extern struct chip_operations drivers_i2c_cs42l42_ops;
Marco Chen07c80b22020-12-21 22:10:21 +080029extern struct chip_operations drivers_i2c_da7219_ops;
30
Furquan Shaikh617fcf32018-08-08 13:30:44 -070031static bool is_cnvi_held_in_reset(void)
32{
Kyösti Mälkkie7377552018-06-21 16:20:55 +030033 struct device *dev = pcidev_path_on_root(PCH_DEVFN_CNVI);
Furquan Shaikh617fcf32018-08-08 13:30:44 -070034 uint32_t reg = pci_read_config32(dev, PCI_VENDOR_ID);
35
36 /*
37 * If vendor/device ID for CNVi reads as 0xffffffff, then it is safe to
38 * assume that it is being held in reset.
39 */
40 if (reg == 0xffffffff)
41 return true;
42
43 return false;
44}
45
Furquan Shaikh65428992018-08-09 10:11:26 -070046static void disable_wifi_wake(void)
47{
48 static const struct pad_config wifi_wake_gpio[] = {
49 PAD_NC(GPIO_119, UP_20K),
50 };
51
52 gpio_configure_pads(wifi_wake_gpio, ARRAY_SIZE(wifi_wake_gpio));
53}
54
Marco Chen07c80b22020-12-21 22:10:21 +080055/*
56 * GPIO_137 for two audio codecs right now has the different configuration so
57 * if SSFC indicates that codec is different than default one then GPIO_137
58 * needs to be overridden for the corresponding second source.
59 */
60static void gpio_modification_by_ssfc(struct pad_config *table, size_t num)
61{
62 /* For RT5682, GPIO 137 should be set as EDGE_BOTH. */
63 const struct pad_config rt5682_gpio_137 = PAD_CFG_GPI_APIC_IOS(GPIO_137,
64 NONE, DEEP, EDGE_BOTH, INVERT, HIZCRx1, DISPUPD);
65
66 if (table == NULL || num == 0)
67 return;
68
69 /*
70 * Currently we only have the case of RT5682 as the second source. And
71 * in case of Ampton which used RT5682 as the default source, it didn't
Martin Roth50863da2021-10-01 14:37:30 -060072 * provide override_table right now so it will be returned earlier since
Marco Chen07c80b22020-12-21 22:10:21 +080073 * table above is NULL.
74 */
75 if (ssfc_get_audio_codec() != SSFC_AUDIO_CODEC_RT5682)
76 return;
77
78 while (num--) {
79 if (table->pad == GPIO_137) {
80 *table = rt5682_gpio_137;
81 printk(BIOS_INFO,
82 "Configure GPIO 137 based on SSFC.\n");
83 return;
84 }
85
86 table++;
87 }
88}
89
Hannah Williams5e83e8b2018-02-09 18:35:17 -080090static void mainboard_init(void *chip_info)
91{
92 int boardid;
Furquan Shaikh06a41f12018-07-25 14:30:59 -070093 const struct pad_config *base_pads;
94 const struct pad_config *override_pads;
95 size_t base_num, override_num;
Hannah Williams5e83e8b2018-02-09 18:35:17 -080096
97 boardid = board_id();
98 printk(BIOS_INFO, "Board ID: %d\n", boardid);
99
Furquan Shaikh06a41f12018-07-25 14:30:59 -0700100 base_pads = variant_base_gpio_table(&base_num);
101 override_pads = variant_override_gpio_table(&override_num);
Marco Chen07c80b22020-12-21 22:10:21 +0800102 gpio_modification_by_ssfc((struct pad_config *)override_pads,
103 override_num);
Furquan Shaikh06a41f12018-07-25 14:30:59 -0700104
105 gpio_configure_pads_with_override(base_pads, base_num,
106 override_pads, override_num);
Hannah Williams5e83e8b2018-02-09 18:35:17 -0800107
Furquan Shaikh65428992018-08-09 10:11:26 -0700108 if (!is_cnvi_held_in_reset())
109 disable_wifi_wake();
110
Hannah Williams5e83e8b2018-02-09 18:35:17 -0800111 mainboard_ec_init();
112}
113
114static unsigned long mainboard_write_acpi_tables(
Furquan Shaikh0f007d82020-04-24 06:41:18 -0700115 const struct device *device, unsigned long current, acpi_rsdp_t *rsdp)
Hannah Williams5e83e8b2018-02-09 18:35:17 -0800116{
117 uintptr_t start_addr;
118 uintptr_t end_addr;
119 struct nhlt *nhlt;
120
121 start_addr = current;
122
123 nhlt = nhlt_init();
124
125 if (nhlt == NULL)
126 return start_addr;
127
128 variant_nhlt_init(nhlt);
129
130 end_addr = nhlt_soc_serialize(nhlt, start_addr);
131
132 if (end_addr != start_addr)
133 acpi_add_table(rsdp, (void *)start_addr);
134
135 return end_addr;
136}
137
Elyes HAOUASd129d432018-05-04 20:23:33 +0200138static void mainboard_enable(struct device *dev)
Hannah Williams5e83e8b2018-02-09 18:35:17 -0800139{
140 dev->ops->write_acpi_tables = mainboard_write_acpi_tables;
Nico Huber68680dd2020-03-31 17:34:52 +0200141 dev->ops->acpi_inject_dsdt = chromeos_dsdt_generator;
Hannah Williams5e83e8b2018-02-09 18:35:17 -0800142}
143
144struct chip_operations mainboard_ops = {
145 .init = mainboard_init,
146 .enable_dev = mainboard_enable,
147};
Furquan Shaikh367956d52018-07-20 13:50:16 -0700148
Aaron Durbin2fcc0342018-07-25 08:06:21 -0600149void __weak variant_update_devtree(struct device *dev)
150{
151 /* Place holder for common updates. */
152}
153
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700154/*
155 * Check if CNVi PCI device is released from reset. If yes, then the system is
156 * booting with CNVi module. In this case, the PCIe device for WiFi needs to
157 * be disabled. If CNVi device is held in reset, then disable it.
158 */
159static void wifi_device_update(void)
160{
161 struct device *dev;
162 unsigned int devfn;
163
164 if (is_cnvi_held_in_reset())
165 devfn = PCH_DEVFN_CNVI;
166 else
167 devfn = PCH_DEVFN_PCIE1;
168
Kyösti Mälkkie7377552018-06-21 16:20:55 +0300169 dev = pcidev_path_on_root(devfn);
John Zhaoa2c0cf52018-08-20 10:27:39 -0700170 if (dev)
171 dev->enabled = 0;
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700172}
173
Marco Chen07c80b22020-12-21 22:10:21 +0800174/*
175 * Base on SSFC value in the CBI from EC to enable one of audio codec sources in
176 * the device tree.
177 */
178static void audio_codec_device_update(void)
179{
180 struct device *audio_dev = NULL;
181 struct bus *audio_i2c_bus =
182 pcidev_path_on_root(PCH_DEVFN_I2C5)->link_list;
183 enum ssfc_audio_codec codec = ssfc_get_audio_codec();
184
185 while ((audio_dev = dev_bus_each_child(audio_i2c_bus, audio_dev))) {
186 if (audio_dev->chip_info == NULL)
187 continue;
188
189 if ((audio_dev->chip_ops == &drivers_i2c_da7219_ops) &&
190 (codec == SSFC_AUDIO_CODEC_DA7219)) {
191 printk(BIOS_INFO, "enable DA7219.\n");
192 continue;
193 }
194
195 if ((audio_dev->chip_ops == &drivers_i2c_generic_ops) &&
196 (codec == SSFC_AUDIO_CODEC_RT5682)) {
197 struct drivers_i2c_generic_config *cfg =
198 audio_dev->chip_info;
199
200 if (cfg != NULL && !strcmp(cfg->hid, "10EC5682")) {
201 printk(BIOS_INFO, "enable RT5682.\n");
202 continue;
203 }
204 }
Eric Lai598f2ba2021-04-15 11:43:02 +0800205
206 if ((audio_dev->chip_ops == &drivers_i2c_cs42l42_ops) &&
207 (codec == SSFC_AUDIO_CODEC_CS42L42)) {
208 printk(BIOS_INFO, "enable CS42L42.\n");
209 continue;
210 }
211
Eric Lai5c633dc2021-04-14 11:43:17 +0800212 printk(BIOS_INFO, "%s has been disabled\n", audio_dev->chip_ops->name);
Marco Chen07c80b22020-12-21 22:10:21 +0800213 audio_dev->enabled = 0;
214 }
215}
216
Aaron Durbin2fcc0342018-07-25 08:06:21 -0600217void mainboard_devtree_update(struct device *dev)
218{
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700219 /* Apply common devtree updates. */
220 wifi_device_update();
Marco Chen07c80b22020-12-21 22:10:21 +0800221 audio_codec_device_update();
Furquan Shaikh617fcf32018-08-08 13:30:44 -0700222
Aaron Durbin2fcc0342018-07-25 08:06:21 -0600223 /* Defer to variant for board-specific updates. */
224 variant_update_devtree(dev);
225}
Wisley Chenbd3568a2018-11-06 17:38:57 +0800226
Karthikeyan Ramasubramanian02592ec2019-06-06 15:57:47 -0600227bool __weak variant_ext_usb_status(unsigned int port_type, unsigned int port_id)
228{
229 /* All externally visible USB ports are present */
230 return true;
231}
232
233static void disable_unused_devices(void *unused)
234{
235 usb_xhci_disable_unused(variant_ext_usb_status);
236}
237
238BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, disable_unused_devices, NULL);