coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
mainboard.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <acpi/acpi.h>
4 #include <baseboard/cbi_ssfc.h>
5 #include <baseboard/variants.h>
6 #include <boardid.h>
7 #include <bootstate.h>
8 #include <console/console.h>
9 #include <device/device.h>
10 #include <device/pci_def.h>
11 #include <device/pci_ops.h>
13 #include <ec/google/chromeec/ec.h>
14 #include <ec/ec.h>
15 #include <intelblocks/xhci.h>
16 #include <nhlt.h>
17 #include <smbios.h>
18 #include <soc/cpu.h>
19 #include <soc/gpio.h>
20 #include <soc/nhlt.h>
21 #include <soc/pci_devs.h>
22 #include <stdint.h>
23 #include <variant/ec.h>
24 #include <variant/gpio.h>
25 
29 
30 static bool is_cnvi_held_in_reset(void)
31 {
34 
35  /*
36  * If vendor/device ID for CNVi reads as 0xffffffff, then it is safe to
37  * assume that it is being held in reset.
38  */
39  if (reg == 0xffffffff)
40  return true;
41 
42  return false;
43 }
44 
45 static void disable_wifi_wake(void)
46 {
47  static const struct pad_config wifi_wake_gpio[] = {
48  PAD_NC(GPIO_119, UP_20K),
49  };
50 
51  gpio_configure_pads(wifi_wake_gpio, ARRAY_SIZE(wifi_wake_gpio));
52 }
53 
54 /*
55  * GPIO_137 for two audio codecs right now has the different configuration so
56  * if SSFC indicates that codec is different than default one then GPIO_137
57  * needs to be overridden for the corresponding second source.
58  */
59 static void gpio_modification_by_ssfc(struct pad_config *table, size_t num)
60 {
61  /* For RT5682, GPIO 137 should be set as EDGE_BOTH. */
62  const struct pad_config rt5682_gpio_137 = PAD_CFG_GPI_APIC_IOS(GPIO_137,
63  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
72  * provide override_table right now so it will be returned earlier since
73  * table above is NULL.
74  */
75  if ((codec != SSFC_AUDIO_CODEC_RT5682) &&
76  (codec != SSFC_AUDIO_CODEC_RT5682_VS))
77  return;
78 
79  while (num--) {
80  if (table->pad == GPIO_137) {
81  *table = rt5682_gpio_137;
83  "Configure GPIO 137 based on SSFC.\n");
84  return;
85  }
86 
87  table++;
88  }
89 }
90 
91 static void mainboard_init(void *chip_info)
92 {
93  int boardid;
94  const struct pad_config *base_pads;
95  const struct pad_config *override_pads;
96  size_t base_num, override_num;
97 
98  boardid = board_id();
99  printk(BIOS_INFO, "Board ID: %d\n", boardid);
100 
101  base_pads = variant_base_gpio_table(&base_num);
102  override_pads = variant_override_gpio_table(&override_num);
103  gpio_modification_by_ssfc((struct pad_config *)override_pads,
104  override_num);
105 
106  gpio_configure_pads_with_override(base_pads, base_num,
107  override_pads, override_num);
108 
109  if (!is_cnvi_held_in_reset())
111 
113 }
114 
115 static unsigned long mainboard_write_acpi_tables(
116  const struct device *device, unsigned long current, acpi_rsdp_t *rsdp)
117 {
118  uintptr_t start_addr;
119  uintptr_t end_addr;
120  struct nhlt *nhlt;
121 
122  start_addr = current;
123 
124  nhlt = nhlt_init();
125 
126  if (nhlt == NULL)
127  return start_addr;
128 
130 
131  end_addr = nhlt_soc_serialize(nhlt, start_addr);
132 
133  if (end_addr != start_addr)
134  acpi_add_table(rsdp, (void *)start_addr);
135 
136  return end_addr;
137 }
138 
139 static void mainboard_enable(struct device *dev)
140 {
141  dev->ops->write_acpi_tables = mainboard_write_acpi_tables;
142 }
143 
145  .init = mainboard_init,
146  .enable_dev = mainboard_enable,
147 };
148 
150 {
151  /* Place holder for common updates. */
152 }
153 
154 /*
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  */
159 static 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 
169  dev = pcidev_path_on_root(devfn);
170  if (dev)
171  dev->enabled = 0;
172 }
173 
174 /*
175  * Base on SSFC value in the CBI from EC to enable one of audio codec sources in
176  * the device tree.
177  */
178 static void audio_codec_device_update(void)
179 {
180  struct device *audio_dev = NULL;
181  struct bus *audio_i2c_bus =
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  struct drivers_i2c_generic_config *cfg =
197  audio_dev->chip_info;
198 
199  if ((cfg != NULL && !strcmp(cfg->hid, "10EC5682")) &&
200  (codec == SSFC_AUDIO_CODEC_RT5682)) {
201  printk(BIOS_INFO, "enable RT5682 VD.\n");
202  continue;
203  }
204 
205  if ((cfg != NULL && !strcmp(cfg->hid, "10EC5682")) &&
206  (codec == SSFC_AUDIO_CODEC_RT5682_VS)) {
207  cfg->hid = "RTL5682";
208  printk(BIOS_INFO, "enable RT5682 VS.\n");
209  continue;
210  }
211 
212  if ((cfg != NULL && !strcmp(cfg->hid, "RTL5682")) &&
213  (codec == SSFC_AUDIO_CODEC_RT5682_VS)) {
214  printk(BIOS_INFO, "enable RT5682 VS.\n");
215  continue;
216  }
217  }
218 
219  if ((audio_dev->chip_ops == &drivers_i2c_cs42l42_ops) &&
220  (codec == SSFC_AUDIO_CODEC_CS42L42)) {
221  printk(BIOS_INFO, "enable CS42L42.\n");
222  continue;
223  }
224 
225  printk(BIOS_INFO, "%s has been disabled\n", audio_dev->chip_ops->name);
226  audio_dev->enabled = 0;
227  }
228 }
229 
231 {
232  /* Apply common devtree updates. */
235 
236  /* Defer to variant for board-specific updates. */
238 }
239 
240 bool __weak variant_ext_usb_status(unsigned int port_type, unsigned int port_id)
241 {
242  /* All externally visible USB ports are present */
243  return true;
244 }
245 
246 static void disable_unused_devices(void *unused)
247 {
249 }
250 
struct chip_operations mainboard_ops
Definition: mainboard.c:19
void acpi_add_table(acpi_rsdp_t *rsdp, void *table)
Add an ACPI table to the RSDT (and XSDT) structure, recalculate length and checksum.
Definition: acpi.c:49
@ BS_DEV_INIT
Definition: bootstate.h:83
@ BS_ON_EXIT
Definition: bootstate.h:96
#define ARRAY_SIZE(a)
Definition: helpers.h:12
enum ssfc_audio_codec ssfc_get_audio_codec(void)
Definition: cbi_ssfc.c:61
ssfc_audio_codec
Definition: cbi_ssfc.h:28
@ SSFC_AUDIO_CODEC_RT5682_VS
Definition: cbi_ssfc.h:33
@ SSFC_AUDIO_CODEC_CS42L42
Definition: cbi_ssfc.h:32
@ SSFC_AUDIO_CODEC_DA7219
Definition: cbi_ssfc.h:30
@ SSFC_AUDIO_CODEC_RT5682
Definition: cbi_ssfc.h:31
#define printk(level,...)
Definition: stdlib.h:16
BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_EXIT, sch5545_ec_hwm_init, NULL)
DEVTREE_CONST struct device * pcidev_path_on_root(pci_devfn_t devfn)
Definition: device_const.c:255
DEVTREE_CONST struct device * dev_bus_each_child(const struct bus *parent, DEVTREE_CONST struct device *prev_child)
Given a device and previous match iterate through all the children.
Definition: device_const.c:353
void mainboard_ec_init(void)
Definition: ec.c:8
uint32_t board_id(void)
board_id() - Get the board version
Definition: ec_boardid.c:6
void variant_nhlt_init(struct nhlt *nhlt)
Definition: nhlt.c:7
struct chip_operations drivers_i2c_da7219_ops
Definition: da7219.c:112
struct chip_operations drivers_i2c_generic_ops
Definition: generic.c:217
static unsigned long mainboard_write_acpi_tables(const struct device *device, unsigned long current, acpi_rsdp_t *rsdp)
Definition: mainboard.c:115
static bool is_cnvi_held_in_reset(void)
Definition: mainboard.c:30
static void gpio_modification_by_ssfc(struct pad_config *table, size_t num)
Definition: mainboard.c:59
static void mainboard_init(void *chip_info)
Definition: mainboard.c:91
struct chip_operations drivers_i2c_cs42l42_ops
Definition: cs42l42.c:120
static void disable_unused_devices(void *unused)
Definition: mainboard.c:246
bool __weak variant_ext_usb_status(unsigned int port_type, unsigned int port_id)
variant_ext_usb_status() - Get status of externally visible USB ports @port_type: Type of USB port i....
Definition: mainboard.c:240
static void audio_codec_device_update(void)
Definition: mainboard.c:178
void __weak variant_update_devtree(struct device *dev)
Definition: mainboard.c:149
static void mainboard_enable(struct device *dev)
Definition: mainboard.c:139
static void disable_wifi_wake(void)
Definition: mainboard.c:45
static void wifi_device_update(void)
Definition: mainboard.c:159
void mainboard_devtree_update(struct device *dev)
Definition: mainboard.c:230
__weak const struct soc_amd_gpio * variant_override_gpio_table(size_t *size)
Definition: mainboard.c:224
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
uintptr_t nhlt_soc_serialize(struct nhlt *nhlt, uintptr_t acpi_addr)
Definition: nhlt.c:7
struct nhlt * nhlt_init(void)
Definition: nhlt.c:23
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
const struct pad_config *__weak variant_base_gpio_table(size_t *num)
Definition: gpio.c:444
#define PCI_VENDOR_ID
Definition: pci_def.h:8
const struct smm_save_state_ops *legacy_ops __weak
Definition: save_state.c:8
void gpio_configure_pads(const struct soc_amd_gpio *gpio_list_ptr, size_t size)
program a particular set of GPIO
Definition: gpio.c:307
void gpio_configure_pads_with_override(const struct soc_amd_gpio *base_cfg, size_t base_num_pads, const struct soc_amd_gpio *override_cfg, size_t override_num_pads)
Definition: gpio.c:262
#define PAD_NC(pin)
Definition: gpio_defs.h:263
#define GPIO_137
Definition: gpio.h:92
#define GPIO_119
Definition: gpio.h:86
#define PCH_DEVFN_I2C5
Definition: pci_devs.h:163
#define PCH_DEVFN_PCIE1
Definition: pci_devs.h:176
#define PCH_DEVFN_CNVI
Definition: pci_devs.h:48
#define PAD_CFG_GPI_APIC_IOS(pad, pull, rst, trig, inv, iosstate, iosterm)
Definition: gpio_defs.h:391
void usb_xhci_disable_unused(bool(*ext_usb_xhci_en_cb)(unsigned int port_type, unsigned int port_id))
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
int strcmp(const char *s1, const char *s2)
Definition: string.c:103
Definition: acpi.h:82
Definition: device.h:76
const char * name
Definition: device.h:29
void(* init)(void *chip_info)
Definition: device.h:25
Definition: device.h:107
struct chip_operations * chip_ops
Definition: device.h:144
struct device_operations * ops
Definition: device.h:143
DEVTREE_CONST struct bus * link_list
Definition: device.h:139
DEVTREE_CONST void * chip_info
Definition: device.h:164
unsigned int enabled
Definition: device.h:122
const char * hid
Definition: chip.h:12
Definition: nhlt.h:287
gpio_t pad
Definition: gpio.h:76