coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
conn.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <acpi/acpigen.h>
4 #include <boot/coreboot_tables.h>
5 #include <cbmem.h>
6 #include <console/console.h>
7 #include <intelblocks/acpi.h>
8 
9 #include "chip.h"
10 
11 /* Number of registered connectors */
12 static size_t total_conn_count;
13 
14 static void conn_init(struct device *dev)
15 {
17 }
18 
19 static unsigned int get_usb_port_number(const struct device *usb_port)
20 {
21  return usb_port->path.usb.port_id + 1;
22 }
23 
24 static struct type_c_info *conn_get_cbmem_buffer(void)
25 {
26  struct type_c_info *info;
27  size_t size;
28 
30  if (info)
31  return info;
32 
33  size = sizeof(struct type_c_info) + total_conn_count * sizeof(struct type_c_port_info);
35 
36  if (!info)
37  return NULL;
38 
39  memset(info, 0, size);
40  return info;
41 }
42 
43 static void conn_write_cbmem_entry(struct device *dev)
44 {
46  struct type_c_port_info *port_info;
47  struct type_c_info *info;
48  size_t count;
49 
50  /*
51  * Do not re-run this code on resume as the cbmem data is populated on boot-up
52  * (non-S3 path) and stays intact across S3 suspend/resume.
53  */
54  if (acpi_is_wakeup_s3())
55  return;
56 
58  if (!info || (info->port_count >= total_conn_count)) {
59  printk(BIOS_ERR, "No space for Type-C port info!\n");
60  return;
61  }
62 
63  count = info->port_count;
64  port_info = &info->port_info[count];
67  port_info->sbu_orientation = config->sbu_orientation;
68  port_info->data_orientation = config->hsl_orientation;
69 
70  printk(BIOS_INFO, "added type-c port%zu info to cbmem: usb2:%d usb3:%d sbu:%d data:%d\n",
73 
74  info->port_count++;
75 }
76 
77 static const char *conn_acpi_name(const struct device *dev)
78 {
79  static char name[5];
80  snprintf(name, sizeof(name), "CON%1X", dev->path.generic.id);
81  return name;
82 }
83 
84 static const char *orientation_to_str(enum type_c_orientation ori)
85 {
86  switch (ori) {
88  return "normal";
90  return "reverse";
91  case TYPEC_ORIENTATION_NONE: /* Intentional fallthrough */
92  default:
93  return "";
94  }
95 }
96 
97 static void conn_fill_ssdt(const struct device *dev)
98 {
100  struct acpi_dp *dsd;
101  const char *scope;
102  const char *name;
103 
104  /* Reference the existing scope and write CONx device */
105  scope = acpi_device_scope(dev);
106  name = acpi_device_name(dev);
107  if (!scope || !name)
108  return;
109 
110  acpigen_write_scope(scope);
112 
114 
115  /* _DSD, Device-Specific Data */
116  dsd = acpi_dp_new_table("_DSD");
117  acpi_dp_add_integer(dsd, "usb2-port-number", get_usb_port_number(config->usb2_port));
118  acpi_dp_add_integer(dsd, "usb3-port-number", get_usb_port_number(config->usb3_port));
119 
120  /*
121  * The kernel assumes that these Type-C signals (SBUs and HSLs) follow the CC lines,
122  * unless they are explicitly called out otherwise.
123  */
124  if (config->sbu_orientation != TYPEC_ORIENTATION_NONE)
125  acpi_dp_add_string(dsd, "sbu-orientation",
126  orientation_to_str(config->sbu_orientation));
127 
128  if (config->hsl_orientation != TYPEC_ORIENTATION_NONE)
129  acpi_dp_add_string(dsd, "hsl-orientation",
130  orientation_to_str(config->hsl_orientation));
131 
132  acpi_dp_write(dsd);
133 
134  acpigen_pop_len(); /* CONx Device */
135  acpigen_pop_len(); /* Scope */
136 
137  printk(BIOS_INFO, "%s: %s at %s\n", acpi_device_path(dev), dev->chip_ops->name,
138  dev_path(dev));
139 }
140 
141 static struct device_operations conn_dev_ops = {
143  .set_resources = noop_set_resources,
144  .acpi_name = conn_acpi_name,
145  .acpi_fill_ssdt = conn_fill_ssdt,
146  .init = conn_init,
147  .final = conn_write_cbmem_entry,
148 };
149 
150 static void conn_enable(struct device *dev)
151 {
152  dev->ops = &conn_dev_ops;
153 }
154 
156  CHIP_NAME("Intel PMC MUX CONN Driver")
157  .enable_dev = conn_enable,
158 };
159 
160 bool intel_pmc_mux_conn_get_ports(const struct device *conn, unsigned int *usb2_port,
161  unsigned int *usb3_port)
162 {
163  const struct drivers_intel_pmc_mux_conn_config *mux_config;
164 
165  if (!conn->chip_info || conn->chip_ops != &drivers_intel_pmc_mux_conn_ops)
166  return false;
167 
168  mux_config = conn->chip_info;
169  *usb2_port = get_usb_port_number(mux_config->usb2_port);
170  *usb3_port = get_usb_port_number(mux_config->usb3_port);
171 
172  return true;
173 };
const char * acpi_device_path(const struct device *dev)
Definition: device.c:144
struct acpi_dp * acpi_dp_add_string(struct acpi_dp *dp, const char *name, const char *string)
Definition: device.c:991
struct acpi_dp * acpi_dp_add_integer(struct acpi_dp *dp, const char *name, uint64_t value)
Definition: device.c:977
void acpi_dp_write(struct acpi_dp *table)
Definition: device.c:898
const char * acpi_device_name(const struct device *dev)
Definition: device.c:49
struct acpi_dp * acpi_dp_new_table(const char *name)
Definition: device.c:930
const char * acpi_device_scope(const struct device *dev)
Definition: device.c:158
void acpigen_pop_len(void)
Definition: acpigen.c:37
void acpigen_write_scope(const char *name)
Definition: acpigen.c:326
void acpigen_write_name_integer(const char *name, uint64_t val)
Definition: acpigen.c:170
void acpigen_write_device(const char *name)
Definition: acpigen.c:769
static int acpi_is_wakeup_s3(void)
Definition: acpi.h:9
const char * name
Definition: mmu.c:92
void * memset(void *dstpp, int c, size_t len)
Definition: memset.c:12
void * cbmem_add(u32 id, u64 size)
Definition: imd_cbmem.c:144
void * cbmem_find(u32 id)
Definition: imd_cbmem.c:166
#define CBMEM_ID_TYPE_C_INFO
Definition: cbmem_id.h:81
type_c_orientation
@ TYPEC_ORIENTATION_NORMAL
@ TYPEC_ORIENTATION_REVERSE
@ TYPEC_ORIENTATION_NONE
#define printk(level,...)
Definition: stdlib.h:16
static void conn_enable(struct device *dev)
Definition: conn.c:150
static struct type_c_info * conn_get_cbmem_buffer(void)
Definition: conn.c:24
static void conn_write_cbmem_entry(struct device *dev)
Definition: conn.c:43
bool intel_pmc_mux_conn_get_ports(const struct device *conn, unsigned int *usb2_port, unsigned int *usb3_port)
Definition: conn.c:160
static unsigned int get_usb_port_number(const struct device *usb_port)
Definition: conn.c:19
static void conn_init(struct device *dev)
Definition: conn.c:14
static const char * conn_acpi_name(const struct device *dev)
Definition: conn.c:77
static void conn_fill_ssdt(const struct device *dev)
Definition: conn.c:97
static const char * orientation_to_str(enum type_c_orientation ori)
Definition: conn.c:84
struct chip_operations drivers_intel_pmc_mux_conn_ops
Definition: conn.c:155
static size_t total_conn_count
Definition: conn.c:12
static struct device_operations conn_dev_ops
Definition: conn.c:141
const char * dev_path(const struct device *dev)
Definition: device_util.c:149
static struct smmstore_params_info info
Definition: ramstage.c:12
#define CHIP_NAME(X)
Definition: device.h:32
static void noop_read_resources(struct device *dev)
Standard device operations function pointers shims.
Definition: device.h:73
static void noop_set_resources(struct device *dev)
Definition: device.h:74
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
enum board_config config
Definition: memory.c:448
usb_port
Definition: usb.h:56
#define NULL
Definition: stddef.h:19
const char * name
Definition: device.h:29
void(* read_resources)(struct device *dev)
Definition: device.h:39
struct generic_path generic
Definition: path.h:125
Definition: device.h:107
struct chip_operations * chip_ops
Definition: device.h:144
struct device_path path
Definition: device.h:115
struct device_operations * ops
Definition: device.h:143
DEVTREE_CONST void * chip_info
Definition: device.h:164
DEVTREE_CONST struct device * usb2_port
Definition: chip.h:10
DEVTREE_CONST struct device * usb3_port
Definition: chip.h:12
unsigned int id
Definition: path.h:96
struct type_c_port_info port_info[0]
#define count
int snprintf(char *buf, size_t size, const char *fmt,...)
Note: This file is only for POSIX compatibility, and is meant to be chain-included via string....
Definition: vsprintf.c:35