diff options
Diffstat (limited to 'baseboard/trogdor')
-rw-r--r-- | baseboard/trogdor/baseboard.c | 79 | ||||
-rw-r--r-- | baseboard/trogdor/baseboard.h | 196 | ||||
-rw-r--r-- | baseboard/trogdor/build.mk | 9 | ||||
-rw-r--r-- | baseboard/trogdor/usb_pd_policy.c | 260 |
4 files changed, 544 insertions, 0 deletions
diff --git a/baseboard/trogdor/baseboard.c b/baseboard/trogdor/baseboard.c new file mode 100644 index 0000000000..4f112d8e5c --- /dev/null +++ b/baseboard/trogdor/baseboard.c @@ -0,0 +1,79 @@ +/* Copyright 2020 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Trogdor baseboard-specific configuration */ + +#include "charger.h" +#include "driver/charger/isl923x.h" +#include "i2c.h" +#include "power.h" + +/* Wake-up pins for hibernate */ +const enum gpio_signal hibernate_wake_pins[] = { + GPIO_LID_OPEN, + GPIO_AC_PRESENT, + GPIO_POWER_BUTTON_L, + GPIO_EC_RST_ODL, +}; +const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); + +/* Power signal list. Must match order of enum power_signal. */ +const struct power_signal_info power_signal_list[] = { + [SC7180_AP_RST_ASSERTED] = { + GPIO_AP_RST_L, + POWER_SIGNAL_ACTIVE_LOW | POWER_SIGNAL_DISABLE_AT_BOOT, + "AP_RST_ASSERTED"}, + [SC7180_PS_HOLD] = { + GPIO_PS_HOLD, + POWER_SIGNAL_ACTIVE_HIGH, + "PS_HOLD"}, + [SC7180_PMIC_FAULT_L] = { + GPIO_PMIC_FAULT_L, + POWER_SIGNAL_ACTIVE_HIGH | POWER_SIGNAL_DISABLE_AT_BOOT, + "PMIC_FAULT_L"}, + [SC7180_POWER_GOOD] = { + GPIO_POWER_GOOD, + POWER_SIGNAL_ACTIVE_HIGH, + "POWER_GOOD"}, + [SC7180_WARM_RESET] = { + GPIO_WARM_RESET_L, + POWER_SIGNAL_ACTIVE_HIGH, + "WARM_RESET_L"}, + [SC7180_AP_SUSPEND] = { + GPIO_AP_SUSPEND, + POWER_SIGNAL_ACTIVE_HIGH, + "AP_SUSPEND"}, + [SC7180_DEPRECATED_AP_RST_REQ] = { + GPIO_DEPRECATED_AP_RST_REQ, + POWER_SIGNAL_ACTIVE_HIGH, + "DEPRECATED_AP_RST_REQ"}, +}; +BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT); + +/* I2C port map */ +const struct i2c_port_t i2c_ports[] = { + {"power", I2C_PORT_POWER, 100, GPIO_EC_I2C_POWER_SCL, + GPIO_EC_I2C_POWER_SDA}, + {"tcpc0", I2C_PORT_TCPC0, 1000, GPIO_EC_I2C_USB_C0_PD_SCL, + GPIO_EC_I2C_USB_C0_PD_SDA}, + {"tcpc1", I2C_PORT_TCPC1, 1000, GPIO_EC_I2C_USB_C1_PD_SCL, + GPIO_EC_I2C_USB_C1_PD_SDA}, + {"eeprom", I2C_PORT_EEPROM, 400, GPIO_EC_I2C_EEPROM_SCL, + GPIO_EC_I2C_EEPROM_SDA}, + {"sensor", I2C_PORT_SENSOR, 400, GPIO_EC_I2C_SENSOR_SCL, + GPIO_EC_I2C_SENSOR_SDA}, +}; + +const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); + +const struct charger_config_t chg_chips[] = { + { + .i2c_port = I2C_PORT_CHARGER, + .i2c_addr_flags = ISL923X_ADDR_FLAGS, + .drv = &isl923x_drv, + }, +}; + +const unsigned int chg_cnt = ARRAY_SIZE(chg_chips); diff --git a/baseboard/trogdor/baseboard.h b/baseboard/trogdor/baseboard.h new file mode 100644 index 0000000000..f1ad825e5c --- /dev/null +++ b/baseboard/trogdor/baseboard.h @@ -0,0 +1,196 @@ +/* Copyright 2020 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Trogdor baseboard configuration */ + +#ifndef __CROS_EC_BASEBOARD_H +#define __CROS_EC_BASEBOARD_H + +/* + * By default, enable all console messages excepted event and HC: + * The sensor stack is generating a lot of activity. + * They can be enabled through the console command 'chan'. + */ +#define CC_DEFAULT (CC_ALL & ~(CC_MASK(CC_EVENTS) | CC_MASK(CC_HOSTCMD))) + +/* NPCX7 config */ +#define NPCX_UART_MODULE2 1 /* GPIO64/65 are used as UART pins. */ +#define NPCX_TACH_SEL2 0 /* No tach. */ +#define NPCX7_PWM1_SEL 0 /* GPIO C2 is not used as PWM1. */ + +/* Internal SPI flash on NPCX7 */ +#define CONFIG_SPI_FLASH_REGS +#define CONFIG_SPI_FLASH_W25Q80 /* Internal SPI flash type. */ +#define CONFIG_HOSTCMD_FLASH_SPI_INFO + +/* EC Modules */ +#define CONFIG_I2C +#define CONFIG_I2C_MASTER +#define CONFIG_LED_COMMON +#define CONFIG_LOW_POWER_IDLE +#define CONFIG_ADC +#define CONFIG_BACKLIGHT_LID +#define CONFIG_FPU +#define CONFIG_PWM +#define CONFIG_PWM_DISPLIGHT +#define CONFIG_PWM_KBLIGHT + +#define CONFIG_VBOOT_HASH + +#undef CONFIG_PECI + +#define CONFIG_HOSTCMD_SPS +#define CONFIG_HOST_COMMAND_STATUS +#define CONFIG_HOSTCMD_SECTION_SORTED +#define CONFIG_MKBP_EVENT +#define CONFIG_KEYBOARD_PROTOCOL_MKBP +#define CONFIG_KEYBOARD_COL2_INVERTED +#define CONFIG_MKBP_USE_GPIO + +#define CONFIG_BOARD_VERSION_GPIO +#define CONFIG_POWER_BUTTON +#define CONFIG_VOLUME_BUTTONS +#define CONFIG_EMULATED_SYSRQ +#define CONFIG_CMD_BUTTON +#define CONFIG_SWITCH +#define CONFIG_LID_SWITCH +#define CONFIG_EXTPOWER_GPIO + +/* Battery */ +#define CONFIG_BATTERY_CUT_OFF +#define CONFIG_BATTERY_PRESENT_GPIO GPIO_BATT_PRES_ODL +#define CONFIG_BATTERY_SMART + +/* Charger */ +#define CONFIG_CHARGER +#define CONFIG_CHARGE_MANAGER +#define CONFIG_CHARGER_ISL9238 +#define CONFIG_CHARGE_RAMP_HW +#define CONFIG_USB_CHARGER +#define CONFIG_CMD_CHARGER_ADC_AMON_BMON +#define CONFIG_CHARGER_PSYS +#define CONFIG_CHARGER_PSYS_READ +#define CONFIG_CHARGER_DISCHARGE_ON_AC + +#define CONFIG_CHARGER_INPUT_CURRENT 512 +#define CONFIG_CHARGER_MIN_BAT_PCT_FOR_POWER_ON 2 +#define CONFIG_CHARGER_MIN_POWER_MW_FOR_POWER_ON 7500 +#define CONFIG_CHARGER_SENSE_RESISTOR 10 +#define CONFIG_CHARGER_SENSE_RESISTOR_AC 20 + +/* + * USB ID + * + * This is allocated specifically for Trogdor + * http://google3/hardware/standards/usb/ + */ +#define CONFIG_USB_PID 0x5043 + +/* USB */ +#define CONFIG_USB_POWER_DELIVERY +#define CONFIG_USB_PD_TCPMV2 +#define CONFIG_USB_DRP_ACC_TRYSRC +#define CONFIG_USB_PD_DECODE_SOP +#define CONFIG_CMD_PD_CONTROL +#define CONFIG_USB_PD_ALT_MODE +#define CONFIG_USB_PD_ALT_MODE_DFP +#define CONFIG_USB_PD_DISCHARGE_PPC +#define CONFIG_USB_PD_DUAL_ROLE +#define CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE +#define CONFIG_USB_PD_TCPC_LOW_POWER +#define CONFIG_USB_PD_LOGGING +#define CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT TYPEC_RP_3A0 +#define CONFIG_USB_PD_PORT_MAX_COUNT 2 +#define CONFIG_USB_PD_TCPM_MUX +#define CONFIG_USB_PD_TCPM_TCPCI +#define CONFIG_USB_PD_TRY_SRC +#define CONFIG_USB_PD_VBUS_DETECT_TCPC +#define CONFIG_USB_PD_5V_EN_CUSTOM +#define CONFIG_USBC_SS_MUX +#define CONFIG_USBC_VCONN +#define CONFIG_USBC_VCONN_SWAP + +/* RTC */ +#define CONFIG_CMD_RTC +#define CONFIG_HOSTCMD_RTC + +/* Sensors */ +/* Enable sensor fifo, must also define the _SIZE and _THRES */ +#define CONFIG_ACCEL_FIFO +/* FIFO size is a power of 2. */ +#define CONFIG_ACCEL_FIFO_SIZE 256 +/* Depends on how fast the AP boots and typical ODRs. */ +#define CONFIG_ACCEL_FIFO_THRES (CONFIG_ACCEL_FIFO_SIZE / 3) +#define CONFIG_CMD_ACCELS +#define CONFIG_CMD_ACCEL_INFO + +/* PD */ +#define PD_POWER_SUPPLY_TURN_ON_DELAY 30000 /* us */ +#define PD_POWER_SUPPLY_TURN_OFF_DELAY 250000 /* us */ +#define PD_VCONN_SWAP_DELAY 5000 /* us */ + +#define PD_OPERATING_POWER_MW 15000 +#define PD_MAX_POWER_MW ((PD_MAX_VOLTAGE_MV * PD_MAX_CURRENT_MA) / 1000) +#define PD_MAX_CURRENT_MA 3000 +#define PD_MAX_VOLTAGE_MV 20000 + +/* Chipset */ +#define CONFIG_CHIPSET_SC7180 +#define CONFIG_CHIPSET_RESET_HOOK +#define CONFIG_POWER_COMMON +#define CONFIG_POWER_PP5000_CONTROL + +/* NPCX Features */ +#define CONFIG_HIBERNATE_PSL + +/* + * Macros for GPIO signals used in common code that don't match the + * schematic names. Signal names in gpio.inc match the schematic and are + * then redefined here to so it's more clear which signal is being used for + * which purpose. + */ +#define GPIO_AC_PRESENT GPIO_ACOK_OD +#define GPIO_POWER_BUTTON_L GPIO_EC_PWR_BTN_ODL +#define GPIO_VOLUME_DOWN_L GPIO_EC_VOLDN_BTN_ODL +#define GPIO_VOLUME_UP_L GPIO_EC_VOLUP_BTN_ODL +#define GPIO_WP_L GPIO_EC_WP_ODL +#define GPIO_LID_OPEN GPIO_LID_OPEN_EC +#define GPIO_SHI_CS_L GPIO_AP_EC_SPI_CS_L +#define GPIO_ENTERING_RW GPIO_EC_ENTERING_RW +#define GPIO_BATT_PRES_ODL GPIO_EC_BATT_PRES_ODL +#define GPIO_EN_PP5000 GPIO_EN_PP5000_A +#define GPIO_ENABLE_BACKLIGHT GPIO_EC_BL_DISABLE_L +#define GPIO_BOARD_VERSION1 GPIO_BRD_ID0 +#define GPIO_BOARD_VERSION2 GPIO_BRD_ID1 +#define GPIO_BOARD_VERSION3 GPIO_BRD_ID2 +#define GPIO_KBD_KSO2 GPIO_EC_KSO_02_INV + +/* I2C Ports */ +#define I2C_PORT_BATTERY I2C_PORT_POWER +#define I2C_PORT_CHARGER I2C_PORT_POWER +#define I2C_PORT_ACCEL I2C_PORT_SENSOR +#define I2C_PORT_POWER NPCX_I2C_PORT0_0 +#define I2C_PORT_TCPC0 NPCX_I2C_PORT1_0 +#define I2C_PORT_TCPC1 NPCX_I2C_PORT2_0 +#define I2C_PORT_EEPROM NPCX_I2C_PORT5_0 +#define I2C_PORT_SENSOR NPCX_I2C_PORT7_0 + +#ifndef __ASSEMBLER__ + +enum power_signal { + SC7180_AP_RST_ASSERTED = 0, + SC7180_PS_HOLD, + SC7180_PMIC_FAULT_L, + SC7180_POWER_GOOD, + SC7180_WARM_RESET, + SC7180_AP_SUSPEND, + SC7180_DEPRECATED_AP_RST_REQ, + /* Number of power signals */ + POWER_SIGNAL_COUNT +}; + +#endif /* !defined(__ASSEMBLER__) */ + +#endif /* __CROS_EC_BASEBOARD_H */ diff --git a/baseboard/trogdor/build.mk b/baseboard/trogdor/build.mk new file mode 100644 index 0000000000..d882755a64 --- /dev/null +++ b/baseboard/trogdor/build.mk @@ -0,0 +1,9 @@ +# -*- makefile -*- +# Copyright 2020 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# Baseboard specific files build +# + +baseboard-y=baseboard.o usb_pd_policy.o diff --git a/baseboard/trogdor/usb_pd_policy.c b/baseboard/trogdor/usb_pd_policy.c new file mode 100644 index 0000000000..40cfd91319 --- /dev/null +++ b/baseboard/trogdor/usb_pd_policy.c @@ -0,0 +1,260 @@ +/* Copyright 2019 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "charge_manager.h" +#include "chipset.h" +#include "console.h" +#include "gpio.h" +#include "system.h" +#include "usb_mux.h" +#include "usbc_ppc.h" +#include "util.h" + +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) + +int pd_check_vconn_swap(int port) +{ + /* In G3, do not allow vconn swap since PP5000 rail is off */ + return gpio_get_level(GPIO_EN_PP5000); +} + +static uint8_t vbus_en[CONFIG_USB_PD_PORT_MAX_COUNT]; +static uint8_t vbus_rp[CONFIG_USB_PD_PORT_MAX_COUNT] = {TYPEC_RP_1A5, + TYPEC_RP_1A5}; + +static void board_vbus_update_source_current(int port) +{ + /* Both port are controlled by PPC SN5S330. */ + ppc_set_vbus_source_current_limit(port, vbus_rp[port]); + ppc_vbus_source_enable(port, vbus_en[port]); +} + +void pd_power_supply_reset(int port) +{ + int prev_en; + + prev_en = vbus_en[port]; + + /* Disable VBUS */ + vbus_en[port] = 0; + board_vbus_update_source_current(port); + + /* Enable discharge if we were previously sourcing 5V */ + if (prev_en) + pd_set_vbus_discharge(port, 1); + +#ifdef CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT + /* Give back the current quota we are no longer using */ + charge_manager_source_port(port, 0); +#endif /* defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) */ + + /* notify host of power info change */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +} + +int pd_set_power_supply_ready(int port) +{ + /* Disable charging */ + board_vbus_sink_enable(port, 0); + + pd_set_vbus_discharge(port, 0); + + /* Provide VBUS */ + vbus_en[port] = 1; + board_vbus_update_source_current(port); + + /* Ensure we advertise the proper available current quota */ + charge_manager_source_port(port, 1); + + /* notify host of power info change */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); + + return EC_SUCCESS; /* we are ready */ +} + +int board_vbus_source_enabled(int port) +{ + return vbus_en[port]; +} + +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +{ + vbus_rp[port] = rp; + board_vbus_update_source_current(port); +} + +int pd_snk_is_vbus_provided(int port) +{ + return !gpio_get_level(port ? GPIO_USB_C1_VBUS_DET_L : + GPIO_USB_C0_VBUS_DET_L); +} + +/* ----------------- Vendor Defined Messages ------------------ */ +#ifdef CONFIG_USB_PD_ALT_MODE_DFP +__override int svdm_dp_config(int port, uint32_t *payload) +{ + int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); + uint8_t pin_mode = get_dp_pin_mode(port); + + if (!pin_mode) + return 0; + + /* + * Defer setting the usb_mux until HPD goes high, svdm_dp_attention(). + * The AP only supports one DP phy. An external DP mux switches between + * the two ports. Should switch those muxes when it is really used, + * i.e. HPD high; otherwise, the real use case is preempted, like: + * (1) plug a dongle without monitor connected to port-0, + * (2) plug a dongle without monitor connected to port-1, + * (3) plug a monitor to the port-1 dongle. + */ + + payload[0] = VDO(USB_SID_DISPLAYPORT, 1, + CMD_DP_CONFIG | VDO_OPOS(opos)); + payload[1] = VDO_DP_CFG(pin_mode, /* pin mode */ + 1, /* DPv1.3 signaling */ + 2); /* UFP connected */ + return 2; +}; + +__override void svdm_dp_post_config(int port) +{ + dp_flags[port] |= DP_FLAGS_DP_ON; +} + +/** + * Is the port fine to be muxed its DisplayPort lines? + * + * Only one port can be muxed to DisplayPort at a time. + * + * @param port Port number of TCPC. + * @return 1 is fine; 0 is bad as other port is already muxed; + */ +static int is_dp_muxable(int port) +{ + int i; + + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) + if (i != port) { + if (usb_mux_get(i) & USB_PD_MUX_DP_ENABLED) + return 0; + } + + return 1; +} + +__override int svdm_dp_attention(int port, uint32_t *payload) +{ + enum gpio_signal hpd = GPIO_DP_HOT_PLUG_DET; + int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); + int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]); + int cur_lvl = gpio_get_level(hpd); + + dp_status[port] = payload[1]; + + /* + * Initial implementation to handle HPD. Only the first-plugged port + * works, i.e. sending HPD signal to AP. The second-plugged port + * will be ignored. + * + * TODO(waihong): Continue the above case, if the first-plugged port + * is then unplugged, switch to the second-plugged port and signal AP? + */ + if (lvl) { + if (is_dp_muxable(port)) { + /* + * Enable and switch the DP port selection mux to the + * correct port. + * + * TODO(waihong): Better to move switching DP mux to + * the usb_mux abstraction. + */ + gpio_set_level(GPIO_DP_MUX_SEL, port == 1); + gpio_set_level(GPIO_DP_MUX_OE_L, 0); + + /* Connect the SBU lines in PPC chip. */ + if (IS_ENABLED(CONFIG_USBC_PPC_SBU)) + ppc_set_sbu(port, 1); + + /* + * Connect the USB SS/DP lines in TCPC chip. + * + * When mf_pref not true, still use the dock muxing + * because of the board USB-C topology (limited to 2 + * lanes DP). + */ + usb_mux_set(port, USB_PD_MUX_DOCK, + USB_SWITCH_CONNECT, pd_get_polarity(port)); + } else { + /* TODO(waihong): Info user? */ + CPRINTS("p%d: The other port is already muxed.", port); + return 0; /* Nack */ + } + } else { + /* Disconnect the DP port selection mux. */ + gpio_set_level(GPIO_DP_MUX_OE_L, 1); + + /* Disconnect the SBU lines in PPC chip. */ + if (IS_ENABLED(CONFIG_USBC_PPC_SBU)) + ppc_set_sbu(port, 0); + + /* Disconnect the DP but keep the USB SS lines in TCPC chip. */ + usb_mux_set(port, USB_PD_MUX_USB_ENABLED, + USB_SWITCH_CONNECT, pd_get_polarity(port)); + } + + if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && + (irq || lvl)) + /* + * Wake up the AP. IRQ or level high indicates a DP sink is now + * present. + */ + pd_notify_dp_alt_mode_entry(); + + /* Configure TCPC for the HPD event, for proper muxing */ + usb_mux_hpd_update(port, lvl, irq); + + /* Signal AP for the HPD event, through GPIO to AP */ + if (irq & cur_lvl) { + uint64_t now = get_time().val; + /* Wait for the minimum spacing between IRQ_HPD if needed */ + if (now < svdm_hpd_deadline[port]) + usleep(svdm_hpd_deadline[port] - now); + + /* Generate IRQ_HPD pulse */ + gpio_set_level(hpd, 0); + usleep(HPD_DSTREAM_DEBOUNCE_IRQ); + gpio_set_level(hpd, 1); + + /* Set the minimum time delay (2ms) for the next HPD IRQ */ + svdm_hpd_deadline[port] = get_time().val + + HPD_USTREAM_DEBOUNCE_LVL; + } else if (irq & !lvl) { + CPRINTF("ERR:HPD:IRQ&LOW\n"); + return 0; /* Nak */ + } else { + gpio_set_level(hpd, lvl); + /* Set the minimum time delay (2ms) for the next HPD IRQ */ + svdm_hpd_deadline[port] = get_time().val + + HPD_USTREAM_DEBOUNCE_LVL; + } + + return 1; /* Ack */ +} + +__override void svdm_exit_dp_mode(int port) +{ + /* Disconnect the DP port selection mux. */ + gpio_set_level(GPIO_DP_MUX_OE_L, 1); + + /* Below svdm_safe_dp_mode() will disconnect SBU and DP/USB SS lines. */ + svdm_safe_dp_mode(port); + + /* Signal AP for the HPD low event */ + usb_mux_hpd_update(port, 0, 0); + gpio_set_level(GPIO_DP_HOT_PLUG_DET, 0); +} +#endif /* CONFIG_USB_PD_ALT_MODE_DFP */ |