diff options
author | Caveh Jalali <caveh@chromium.org> | 2019-07-30 17:45:59 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-09-01 12:42:22 +0000 |
commit | 689e8cdc09254072c0dface2954bc6e87f5ceaf7 (patch) | |
tree | 90eaf2adfbc5ff996f63a6cbe51ea657e6e67032 /driver/tcpm/ps8xxx.c | |
parent | 9c880833331e25bf436aa6628e837b9c98a47bc2 (diff) | |
download | chrome-ec-689e8cdc09254072c0dface2954bc6e87f5ceaf7.tar.gz |
ps8xxx: disable DCI mode
DCI mode is auto-enabled by default. we don't actually support DCI
(intel specific SoC debug path), so we can explicitly disable DCI
mode. doing so, saves about 40mW on the 3.3v rail when USB2 devices
or USB-C to USB-A dongles are left plugged in. this is particulary
relevant in sleep mode as this accounts for a significant portion
of the system power consumption.
BUG=b:119875949
BRANCH=none
TEST=verified power consumption drops using sweetberry, USB devices
still functional across suspend/resume.
Change-Id: Id13630425c78965d2ac4f2e97715374ae0640d23
Signed-off-by: Caveh Jalali <caveh@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1732231
Reviewed-by: Edward Hill <ecgh@chromium.org>
Commit-Queue: Caveh Jalali <caveh@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2315962
Tested-by: Devin Lu <Devin.Lu@quantatw.com>
Reviewed-by: Marco Chen <marcochen@chromium.org>
Commit-Queue: Marco Chen <marcochen@chromium.org>
Diffstat (limited to 'driver/tcpm/ps8xxx.c')
-rw-r--r-- | driver/tcpm/ps8xxx.c | 74 |
1 files changed, 73 insertions, 1 deletions
diff --git a/driver/tcpm/ps8xxx.c b/driver/tcpm/ps8xxx.c index bbdf8f1a82..9cb6e46017 100644 --- a/driver/tcpm/ps8xxx.c +++ b/driver/tcpm/ps8xxx.c @@ -168,8 +168,80 @@ static int ps8xxx_get_chip_info(int port, int live, } +/* + * DCI is enabled by default and burns about 40 mW when the port is in + * USB2 mode or when a C-to-A dongle is attached, so force it off. + */ + +static int ps8xxx_addr_dci_disable(int port, int i2c_addr, int i2c_reg) +{ + int status; + int dci; + + status = tcpc_addr_read(port, i2c_addr, i2c_reg, &dci); + if (status != EC_SUCCESS) + return status; + if ((dci & PS8XXX_REG_MUX_USB_DCI_CFG_MODE_MASK) != + PS8XXX_REG_MUX_USB_DCI_CFG_MODE_OFF) { + dci &= ~PS8XXX_REG_MUX_USB_DCI_CFG_MODE_MASK; + dci |= PS8XXX_REG_MUX_USB_DCI_CFG_MODE_OFF; + if (tcpc_addr_write(port, i2c_addr, i2c_reg, dci) != EC_SUCCESS) + return status; + } + return EC_SUCCESS; +} + +#ifdef CONFIG_USB_PD_TCPM_PS8805 +static int ps8xxx_dci_disable(int port) +{ + int status, e; + int p1_addr; + + status = tcpc_write(port, PS8XXX_REG_I2C_DEBUGGING_ENABLE, + PS8XXX_REG_I2C_DEBUGGING_ENABLE_ON); + if (status != EC_SUCCESS) + return status; + + p1_addr = tcpc_config[port].i2c_info.addr - + (PS8751_I2C_ADDR1 - PS8751_I2C_ADDR1_P1); + status = ps8xxx_addr_dci_disable(port, p1_addr, + PS8805_P1_REG_MUX_USB_DCI_CFG); + + e = tcpc_write(port, PS8XXX_REG_I2C_DEBUGGING_ENABLE, + PS8XXX_REG_I2C_DEBUGGING_ENABLE_OFF); + if (e != EC_SUCCESS) { + if (status == EC_SUCCESS) + status = e; + } + + return status; +} +#endif /* CONFIG_USB_PD_TCPM_PS8805 */ + +#ifdef CONFIG_USB_PD_TCPM_PS8751 +static int ps8xxx_dci_disable(int port) +{ + int p3_addr; + + p3_addr = tcpc_config[port].i2c_info.addr; + return ps8xxx_addr_dci_disable(port, p3_addr, + PS8751_REG_MUX_USB_DCI_CFG); +} +#endif /* CONFIG_USB_PD_TCPM_PS8751 */ + +static int ps8xxx_tcpm_init(int port) +{ + int status; + + status = tcpci_tcpm_init(port); + if (status != EC_SUCCESS) + return status; + + return ps8xxx_dci_disable(port); +} + const struct tcpm_drv ps8xxx_tcpm_drv = { - .init = &tcpci_tcpm_init, + .init = &ps8xxx_tcpm_init, .release = &ps8xxx_tcpm_release, .get_cc = &tcpci_tcpm_get_cc, #ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC |