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 <baseboard/variants.h>
4 #include <bootmode.h>
5 #include <chip.h>
6 #include <console/console.h>
7 #include <delay.h>
8 #include <device/device.h>
9 #include <device/pci_ids.h>
10 #include <device/pci_ops.h>
11 #include <ec/google/chromeec/ec.h>
12 #include <gpio.h>
14 #include <soc/pci_devs.h>
15 #include <timer.h>
16 
17 #define GPIO_HDMI_HPD GPP_E13
18 #define GPIO_DP_HPD GPP_E14
19 
20 /* TODO: This can be moved to common directory */
21 static void wait_for_hpd(gpio_t gpio, long timeout)
22 {
23  struct stopwatch sw;
24 
25  printk(BIOS_INFO, "Waiting for HPD\n");
26  stopwatch_init_msecs_expire(&sw, timeout);
27  while (!gpio_get(gpio)) {
28  if (stopwatch_expired(&sw)) {
30  "HPD not ready after %ldms. Abort.\n", timeout);
31  return;
32  }
33  mdelay(200);
34  }
35  printk(BIOS_INFO, "HPD ready after %lu ms\n",
37 }
38 
39 /*
40  * For type-C chargers, set PL2 to 97% of max power to account for
41  * cable loss and FET Rdson loss in the path from the source.
42  */
43 #define SET_PSYSPL2(w) (97 * (w) / 100)
44 #define PUFF_U22_PL2 (35)
45 #define PUFF_U62_U42_PL2 (51)
46 #define PUFF_CELERON_PENTIUM_PSYSPL2 (65)
47 #define PUFF_CORE_CPU_PSYSPL2 (90)
48 #define PUFF_MAX_TIME_WINDOW 6
49 #define PUFF_MIN_DUTYCYCLE 4
50 
51 /*
52  * mainboard_set_power_limits
53  *
54  * Set Pl2 and SysPl2 values based on detected charger.
55  * Values are defined below but we use U22 value for all SKUs for now.
56  * definitions:
57  * x = no value entered. Use default value in parenthesis.
58  * will set 0 to anything that shouldn't be set.
59  * n = max value of power adapter.
60  * +-------------+-----+---------+-----------+-------+
61  * | sku_id | PL2 | PsysPL2 | PsysPL3 | PL4 |
62  * +-------------+-----+---------+-----------+-------+
63  * | i7 U42 | 51 | 90 | x(.85PL4) | x(82) |
64  * | i3 U22 | 35 | 65 | x(.85PL4) | x(51) |
65  * +-------------+-----+---------+-----------+-------+
66  * For USB C charger:
67  * +-------------+-----------------+---------+---------+-------+
68  * | Max Power(W)| PL2 | PsysPL2 | PsysPL3 | PL4 |
69  * +-------------+-----+-----------+---------+---------+-------+
70  * | n | min(0.97n, PL2) | 0.97n | 0.97n | 0.97n |
71  * +-------------+-----+-----------+---------+---------+-------+
72  */
73 
74 /*
75  * Psys_pmax considerations
76  *
77  * Given the hardware design in puff, the serial shunt resistor is 0.01ohm.
78  * The full scale of hardware PSYS signal 0.8v maps to system current 9.6A
79  * instead of real system power. The equation is shown below:
80  * PSYS = 0.8v = (0.01ohm x Iinput) x 50 (INA213, gain 50V/V) x 15k/(15k + 75k)
81  * Hence, Iinput (Amps) = 9.6A
82  * Since there is no voltage information from PSYS, different voltage input
83  * would map to different Psys_pmax settings:
84  * For Type-C 15V, the Psys_pmax sholud be 15v x 9.6A = 144W
85  * For Type-C 20V, the Psys_pmax should be 20v x 9.6A = 192W
86  * For a barral jack, the Psys_pmax should be 19v x 9.6A = 182.4W
87  */
88 #define PSYS_IMAX 9600
89 #define BJ_VOLTS_MV 19000
90 
92 {
93  enum usb_chg_type type;
94  u32 watts;
95  u16 volts_mv, current_ma;
96  u32 psyspl2 = PUFF_CELERON_PENTIUM_PSYSPL2; // default BJ value
97  u32 pl2 = PUFF_U22_PL2; // default PL2 for U22
98  int rv = google_chromeec_get_usb_pd_power_info(&type, &current_ma, &volts_mv);
99 
101  u16 mch_id = dev ? pci_read_config16(dev, PCI_DEVICE_ID) : 0xffff;
103  u16 igd_id = dev ? pci_read_config16(dev, PCI_DEVICE_ID) : 0xffff;
104 
105  /* use SoC default value for PsysPL3 and PL4 unless we're on USB-PD*/
106  conf->tdp_psyspl3 = 0;
107  conf->tdp_pl4 = 0;
108 
109  if (rv == 0 && type == USB_CHG_TYPE_PD) {
110  /* Detected USB-PD. Base on max value of adapter */
111  watts = ((u32)current_ma * volts_mv) / 1000000;
112  /* set psyspl2 to 90% of adapter rating */
113  psyspl2 = SET_PSYSPL2(watts);
114 
115  /* Limit PL2 if the adapter is with lower capability */
116  if (mch_id == PCI_DID_INTEL_CML_ULT ||
117  mch_id == PCI_DID_INTEL_CML_ULT_6_2)
118  pl2 = (psyspl2 > PUFF_U62_U42_PL2) ? PUFF_U62_U42_PL2 : psyspl2;
119  else
120  pl2 = (psyspl2 > PUFF_U22_PL2) ? PUFF_U22_PL2 : psyspl2;
121 
122  conf->tdp_psyspl3 = psyspl2;
123  /* set max possible time window */
125  /* set minimum duty cycle */
127  /* No data about an arbitrary Type-C adapter, set pl4 conservatively. */
128  conf->tdp_pl4 = psyspl2;
129  } else {
130  /*
131  * Input type is barrel jack, from the SKU matrix:
132  * 1. i3/i5/i7 SKUs use 90W BJ
133  * 2. Celeron and Pentium use 65W BJ (default)
134  */
135  volts_mv = BJ_VOLTS_MV;
136  /* Use IGD ID to check if CPU is Core SKUs */
137  if (igd_id != PCI_DID_INTEL_CML_GT1_ULT_1 &&
138  igd_id != PCI_DID_INTEL_CML_GT2_ULT_5) {
139  psyspl2 = PUFF_CORE_CPU_PSYSPL2;
140  if (mch_id == PCI_DID_INTEL_CML_ULT ||
141  mch_id == PCI_DID_INTEL_CML_ULT_6_2)
142  pl2 = PUFF_U62_U42_PL2;
143  }
144  }
145  /* voltage unit is milliVolts and current is in milliAmps */
146  conf->psys_pmax = (u16)(((u32)PSYS_IMAX * volts_mv) / 1000000);
147 
148  conf->tdp_pl2_override = pl2;
149  conf->tdp_psyspl2 = psyspl2;
150 }
151 
153 {
154  static const long display_timeout_ms = 3000;
155  struct soc_power_limits_config *soc_config;
156  config_t *conf = config_of_soc();
157 
158  /* This is reconfigured back to whatever FSP-S expects by gpio_configure_pads. */
163  && !gpio_get(GPIO_DP_HPD)) {
164  /* This has to be done before FSP-S runs. */
165  if (google_chromeec_wait_for_displayport(display_timeout_ms))
166  wait_for_hpd(GPIO_DP_HPD, display_timeout_ms);
167  }
168  /* Psys_pmax needs to be setup before FSP-S */
169  soc_config = &conf->power_limits_config;
170  mainboard_set_power_limits(soc_config);
171 }
int display_init_required(void)
Definition: bootmode.c:22
#define printk(level,...)
Definition: stdlib.h:16
void mdelay(unsigned int msecs)
Definition: delay.c:2
DEVTREE_CONST struct device * pcidev_path_on_root(pci_devfn_t devfn)
Definition: device_const.c:255
int google_chromeec_wait_for_displayport(long timeout_ms)
Wait for DisplayPort to be ready.
Definition: ec.c:1668
int google_chromeec_get_usb_pd_power_info(enum usb_chg_type *type, uint16_t *current_max, uint16_t *voltage_max)
Definition: ec.c:1163
usb_chg_type
Definition: ec_commands.h:5618
@ USB_CHG_TYPE_PD
Definition: ec_commands.h:5620
#define PUFF_CELERON_PENTIUM_PSYSPL2
Definition: mainboard.c:46
#define PUFF_U62_U42_PL2
Definition: mainboard.c:45
#define PUFF_U22_PL2
Definition: mainboard.c:44
#define GPIO_DP_HPD
Definition: mainboard.c:18
void variant_ramstage_init(void)
Definition: mainboard.c:152
#define GPIO_HDMI_HPD
Definition: mainboard.c:17
#define BJ_VOLTS_MV
Definition: mainboard.c:89
#define PUFF_CORE_CPU_PSYSPL2
Definition: mainboard.c:47
#define PSYS_IMAX
Definition: mainboard.c:88
static void mainboard_set_power_limits(struct soc_power_limits_config *conf)
Definition: mainboard.c:91
#define PUFF_MAX_TIME_WINDOW
Definition: mainboard.c:48
#define PUFF_MIN_DUTYCYCLE
Definition: mainboard.c:49
#define SET_PSYSPL2(w)
Definition: mainboard.c:43
static void wait_for_hpd(gpio_t gpio, long timeout)
Definition: mainboard.c:21
#define config_of_soc()
Definition: device.h:394
static __always_inline u16 pci_read_config16(const struct device *dev, u16 reg)
Definition: pci_ops.h:52
int gpio_get(gpio_t gpio)
Definition: gpio.c:166
void gpio_input(gpio_t gpio)
Definition: gpio.c:189
static int stopwatch_expired(struct stopwatch *sw)
Definition: timer.h:152
static long stopwatch_duration_msecs(struct stopwatch *sw)
Definition: timer.h:182
static void stopwatch_init_msecs_expire(struct stopwatch *sw, long ms)
Definition: timer.h:133
unsigned int type
Definition: edid.c:57
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_WARNING
BIOS_WARNING - Bad configuration.
Definition: loglevel.h:86
#define PCI_DEVICE_ID
Definition: pci_def.h:9
#define PCI_DID_INTEL_CML_GT1_ULT_1
Definition: pci_ids.h:3884
#define PCI_DID_INTEL_CML_ULT_6_2
Definition: pci_ids.h:4007
#define PCI_DID_INTEL_CML_ULT
Definition: pci_ids.h:4005
#define PCI_DID_INTEL_CML_GT2_ULT_5
Definition: pci_ids.h:3890
#define SA_DEVFN_ROOT
Definition: pci_devs.h:23
#define SA_DEVFN_IGD
Definition: pci_devs.h:32
uint32_t u32
Definition: stdint.h:51
uint16_t u16
Definition: stdint.h:48
Definition: device.h:107
Definition: pinmux.c:36
uint32_t tdp_psyspl3_dutycycle
Definition: power_limit.h:32