summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaveh Jalali <caveh@chromium.org>2019-07-30 17:45:59 -0700
committerCommit Bot <commit-bot@chromium.org>2019-08-15 04:11:54 +0000
commit0acbdb597f4e9817ec06b18210df41ccad1c9d19 (patch)
treef0166f5bc2316dc7f43d996aca31346e0b4e7b32
parentbd42a8691405c9aeab28e5153d19100bf45b90a3 (diff)
downloadchrome-ec-0acbdb597f4e9817ec06b18210df41ccad1c9d19.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> (cherry picked from commit ce1a0c9bdfa0b35455b9619fdb1b5794caa63894) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1726826 Reviewed-by: Caveh Jalali <caveh@google.com>
-rw-r--r--driver/tcpm/ps8xxx.c74
-rw-r--r--driver/tcpm/ps8xxx.h22
-rw-r--r--driver/tcpm/tcpci.c8
-rw-r--r--driver/tcpm/tcpm.h24
4 files changed, 110 insertions, 18 deletions
diff --git a/driver/tcpm/ps8xxx.c b/driver/tcpm/ps8xxx.c
index fe770de5c1..9aa5231386 100644
--- a/driver/tcpm/ps8xxx.c
+++ b/driver/tcpm/ps8xxx.c
@@ -169,8 +169,80 @@ static int ps8xxx_enter_low_power_mode(int port)
}
#endif
+/*
+ * 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_slave_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_slave_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
diff --git a/driver/tcpm/ps8xxx.h b/driver/tcpm/ps8xxx.h
index 6d0faab56f..705469a53c 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 0x16
-#define PS8751_I2C_ADDR2 0x36
-#define PS8751_I2C_ADDR3 0x56
-#define PS8751_I2C_ADDR4 0x96
+#define PS8751_I2C_ADDR1_P1 0x12
+#define PS8751_I2C_ADDR1 0x16
+#define PS8751_I2C_ADDR2 0x36
+#define PS8751_I2C_ADDR3 0x56
+#define PS8751_I2C_ADDR4 0x96
/* 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 f20fbd91e3..fa21e497c9 100644
--- a/driver/tcpm/tcpci.c
+++ b/driver/tcpm/tcpci.c
@@ -34,14 +34,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_host_port,
- tcpc_config[port].i2c_slave_addr, reg, val);
+ i2c_addr, reg, val);
pd_device_accessed(port);
return rv;
@@ -60,14 +60,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_host_port,
- tcpc_config[port].i2c_slave_addr, 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 52314151ae..30c9c20588 100644
--- a/driver/tcpm/tcpm.h
+++ b/driver/tcpm/tcpm.h
@@ -30,10 +30,10 @@ extern struct tcpc_config_t tcpc_config[];
/* 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_host_port,
- tcpc_config[port].i2c_slave_addr, reg, val);
+ i2c_addr, reg, val);
}
static inline int tcpc_write16(int port, int reg, int val)
@@ -42,10 +42,10 @@ static inline int tcpc_write16(int port, int reg, int val)
tcpc_config[port].i2c_slave_addr, 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_host_port,
- tcpc_config[port].i2c_slave_addr, reg, val);
+ i2c_addr, reg, val);
}
static inline int tcpc_read16(int port, int reg, int *val)
@@ -84,9 +84,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);
@@ -97,6 +97,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_slave_addr, reg, val);
+}
+
+static inline int tcpc_read(int port, int reg, int *val)
+{
+ return tcpc_addr_read(port,
+ tcpc_config[port].i2c_slave_addr, reg, val);
+}
+
static inline void tcpc_lock(int port, int lock)
{
i2c_lock(tcpc_config[port].i2c_host_port, lock);