summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaveh Jalali <caveh@chromium.org>2019-07-30 17:45:59 -0700
committerCommit Bot <commit-bot@chromium.org>2020-09-11 01:46:05 +0000
commit676b2b217dce1e9b15675ea69f3f07757451228e (patch)
treec36eeac5415a1fe749662e1a62667bf6e456b614
parentf000fcd31f63ed34b1000a1be512a886d7d265aa (diff)
downloadchrome-ec-676b2b217dce1e9b15675ea69f3f07757451228e.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/+/2392235 Tested-by: Devin Lu <Devin.Lu@quantatw.com> Commit-Queue: Edward Hill <ecgh@chromium.org>
-rw-r--r--driver/tcpm/ps8xxx.c74
-rw-r--r--driver/tcpm/ps8xxx.h22
-rw-r--r--driver/tcpm/tcpci.c10
-rw-r--r--driver/tcpm/tcpm.h26
4 files changed, 110 insertions, 22 deletions
diff --git a/driver/tcpm/ps8xxx.c b/driver/tcpm/ps8xxx.c
index 7c8f53f745..c2e647e693 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_flags -
+ (PS8751_I2C_ADDR1_FLAGS - PS8751_I2C_ADDR1_P1_FLAGS);
+ 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_flags;
+ 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
diff --git a/driver/tcpm/ps8xxx.h b/driver/tcpm/ps8xxx.h
index 4047fb5c14..fc474f6a2b 100644
--- a/driver/tcpm/ps8xxx.h
+++ b/driver/tcpm/ps8xxx.h
@@ -9,10 +9,11 @@
#define __CROS_EC_USB_PD_TCPM_PS8XXX_H
/* I2C interface */
-#define PS8751_I2C_ADDR1_FLAGS 0x0B
-#define PS8751_I2C_ADDR2_FLAGS 0x1B
-#define PS8751_I2C_ADDR3_FLAGS 0x2B
-#define PS8751_I2C_ADDR4_FLAGS 0x4B
+#define PS8751_I2C_ADDR1_P1_FLAGS 0x09
+#define PS8751_I2C_ADDR1_FLAGS 0x0B
+#define PS8751_I2C_ADDR2_FLAGS 0x1B
+#define PS8751_I2C_ADDR3_FLAGS 0x2B
+#define PS8751_I2C_ADDR4_FLAGS 0x4B
/* Minimum Delay for reset assertion */
#define PS8XXX_RESET_DELAY_MS 1
@@ -29,12 +30,17 @@
#define PS8XXX_VENDOR_ID 0x1DA0
#define PS8XXX_REG_I2C_DEBUGGING_ENABLE 0xA0
+#define PS8XXX_REG_I2C_DEBUGGING_ENABLE_ON 0x30
+#define PS8XXX_REG_I2C_DEBUGGING_ENABLE_OFF 0x31 /* default */
#define PS8XXX_REG_BIST_CONT_MODE_BYTE0 0xBC
#define PS8XXX_REG_BIST_CONT_MODE_BYTE1 0xBD
#define PS8XXX_REG_BIST_CONT_MODE_BYTE2 0xBE
-#define PS8XXX_REG_BIST_CONT_MODE_CTR 0XBF
+#define PS8XXX_REG_BIST_CONT_MODE_CTR 0xBF
#define PS8XXX_REG_DET_CTRL0 0x08
+#define PS8XXX_REG_MUX_USB_DCI_CFG_MODE_MASK 0xC0
+#define PS8XXX_REG_MUX_USB_DCI_CFG_MODE_OFF 0x80
+
#if defined(CONFIG_USB_PD_TCPM_PS8751)
/* Vendor defined registers */
#define PS8XXX_PRODUCT_ID 0x8751
@@ -48,13 +54,15 @@
#define PS8XXX_REG_MUX_DP_EQ_CONFIGURATION 0xD3
#define PS8XXX_REG_MUX_USB_C2SS_EQ 0xE7
#define PS8XXX_REG_MUX_USB_C2SS_HS_THRESHOLD 0xE8
+#define PS8751_REG_MUX_USB_DCI_CFG 0xED
#elif defined(CONFIG_USB_PD_TCPM_PS8805)
/* Vendor defined registers */
#define PS8XXX_PRODUCT_ID 0x8805
-#define FW_VER_REG 0x82
-#define MUX_IN_HPD_ASSERTION_REG 0xD0
+#define PS8805_P1_REG_MUX_USB_DCI_CFG 0x4B
+#define FW_VER_REG 0x82
+#define MUX_IN_HPD_ASSERTION_REG 0xD0
#define IN_HPD (1 << 0)
#define HPD_IRQ (1 << 1)
diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c
index 215ffd8a9c..135e13d7d5 100644
--- a/driver/tcpm/tcpci.c
+++ b/driver/tcpm/tcpci.c
@@ -30,15 +30,14 @@ static int selected_rp[CONFIG_USB_PD_PORT_COUNT];
#ifdef CONFIG_USB_PD_TCPC_LOW_POWER
-int tcpc_write(int port, int reg, int val)
+int tcpc_addr_write(int port, int i2c_addr, int reg, int val)
{
int rv;
pd_wait_exit_low_power(port);
rv = i2c_write8(tcpc_config[port].i2c_info.port,
- tcpc_config[port].i2c_info.addr_flags,
- reg, val);
+ i2c_addr, reg, val);
pd_device_accessed(port);
return rv;
@@ -58,15 +57,14 @@ int tcpc_write16(int port, int reg, int val)
return rv;
}
-int tcpc_read(int port, int reg, int *val)
+int tcpc_addr_read(int port, int i2c_addr, int reg, int *val)
{
int rv;
pd_wait_exit_low_power(port);
rv = i2c_read8(tcpc_config[port].i2c_info.port,
- tcpc_config[port].i2c_info.addr_flags,
- reg, val);
+ i2c_addr, reg, val);
pd_device_accessed(port);
return rv;
diff --git a/driver/tcpm/tcpm.h b/driver/tcpm/tcpm.h
index ca7d3cf7bd..2b645f3510 100644
--- a/driver/tcpm/tcpm.h
+++ b/driver/tcpm/tcpm.h
@@ -25,11 +25,10 @@
/* I2C wrapper functions - get I2C port / slave addr from config struct. */
#ifndef CONFIG_USB_PD_TCPC_LOW_POWER
-static inline int tcpc_write(int port, int reg, int val)
+static inline int tcpc_addr_write(int port, int i2c_addr, int reg, int val)
{
return i2c_write8(tcpc_config[port].i2c_info.port,
- tcpc_config[port].i2c_info.addr_flags,
- reg, val);
+ i2c_addr, reg, val);
}
static inline int tcpc_write16(int port, int reg, int val)
@@ -39,11 +38,10 @@ static inline int tcpc_write16(int port, int reg, int val)
reg, val);
}
-static inline int tcpc_read(int port, int reg, int *val)
+static inline int tcpc_addr_read(int port, int i2c_addr, int reg, int *val)
{
return i2c_read8(tcpc_config[port].i2c_info.port,
- tcpc_config[port].i2c_info.addr_flags,
- reg, val);
+ i2c_addr, reg, val);
}
static inline int tcpc_read16(int port, int reg, int *val)
@@ -85,9 +83,9 @@ static inline int tcpc_write_block(int port, int reg,
}
#else /* !CONFIG_USB_PD_TCPC_LOW_POWER */
-int tcpc_write(int port, int reg, int val);
+int tcpc_addr_write(int port, int i2c_addr, int reg, int val);
int tcpc_write16(int port, int reg, int val);
-int tcpc_read(int port, int reg, int *val);
+int tcpc_addr_read(int port, int i2c_addr, int reg, int *val);
int tcpc_read16(int port, int reg, int *val);
int tcpc_read_block(int port, int reg, uint8_t *in, int size);
int tcpc_write_block(int port, int reg, const uint8_t *out, int size);
@@ -98,6 +96,18 @@ int tcpc_xfer_unlocked(int port, const uint8_t *out, int out_size,
#endif /* CONFIG_USB_PD_TCPC_LOW_POWER */
+static inline int tcpc_write(int port, int reg, int val)
+{
+ return tcpc_addr_write(port,
+ tcpc_config[port].i2c_info.addr_flags, reg, val);
+}
+
+static inline int tcpc_read(int port, int reg, int *val)
+{
+ return tcpc_addr_read(port,
+ tcpc_config[port].i2c_info.addr_flags, reg, val);
+}
+
static inline void tcpc_lock(int port, int lock)
{
i2c_lock(tcpc_config[port].i2c_info.port, lock);