summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Herrmann <eherrmann@chromium.org>2021-02-04 10:44:26 -0800
committerCommit Bot <commit-bot@chromium.org>2021-02-18 17:48:00 +0000
commitb7e0151f3c1b23e1d6142907b7bd4a61e5755ab9 (patch)
treea9a10d3c6f6ce5faf4452c74cbe832fe173e585a
parent1aeb4e7e6bfc1393511ea243af6dd428f1fe26b1 (diff)
downloadchrome-ec-b7e0151f3c1b23e1d6142907b7bd4a61e5755ab9.tar.gz
RT1715: Enable power saving modes
The RT1715 implements its own low-power mode (LPM) to save power. Switch from using the default I2CIdle LPM to using the RT1715-specific one. Disable the 24MHz oscillator in LPM, and enable the interrupt to wake from LPM. For interrupts, clear the WAKEUP interrupt before checking the TCPCI interrupts. Enable auto-idle to save power with a device connected. Disable when the TCPC is sourcing Vconn. BUG=b:179256608 TEST=On Voxel: while no device attached, make sure both SNK and SRC devices wake up the TCPC from LPM TEST=On Voxel: with no devices connected, measure fake G3 power consuption and make sure it has decreased TEST=On Voxel: with a pass-through hub configured as a sink, check that connecting a charger will prompt Voxel to begin charging TEST=make buildall BRANCH=None Change-Id: Ifb2fa5a7940e5862e217c04c5c1082aae6b43989 Signed-off-by: Eric Herrmann <eherrmann@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2676934 Reviewed-by: Abe Levkoy <alevkoy@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2704622 Tested-by: Abe Levkoy <alevkoy@chromium.org> Commit-Queue: Abe Levkoy <alevkoy@chromium.org>
-rw-r--r--driver/tcpm/rt1715.c75
-rw-r--r--driver/tcpm/rt1715.h72
2 files changed, 114 insertions, 33 deletions
diff --git a/driver/tcpm/rt1715.c b/driver/tcpm/rt1715.c
index 98084d4c83..5f8c9cde04 100644
--- a/driver/tcpm/rt1715.c
+++ b/driver/tcpm/rt1715.c
@@ -62,6 +62,11 @@ static int rt1715_tcpci_tcpm_init(int port)
if (rv)
return rv;
+ /* Unmask interrupt for LPM wakeup */
+ rv = tcpc_write(port, RT1715_REG_RT_MASK, RT1715_REG_RT_MASK_M_WAKEUP);
+ if (rv)
+ return rv;
+
/*
* Set tTCPCFilter (CC debounce time) to 400 us
* (min 250 us, max 500 us).
@@ -138,6 +143,59 @@ static int rt1715_get_cc(int port, enum tcpc_cc_voltage_status *cc1,
return rt1715_init_cc_params(port, rt1715_polarity[port] ? *cc2 : *cc1);
}
+/*
+ * See b/179256608#comment26 for explanation.
+ * Disable 24MHz oscillator and enable LPM. Upon exit from LPM, the LPEN will be
+ * reset to 0.
+ *
+ * The exit condition for LPM is CC status change, and the wakeup interrupt will
+ * be set.
+ */
+#ifdef CONFIG_USB_PD_TCPC_LOW_POWER
+static int rt1715_enter_low_power_mode(int port)
+{
+ int regval;
+ int rv;
+
+ rv = tcpc_read(port, RT1715_REG_PWR, &regval);
+ if (rv)
+ return rv;
+
+ regval |= RT1715_REG_PWR_BMCIO_LPEN;
+ regval &= ~RT1715_REG_PWR_BMCIO_OSCEN;
+ rv = tcpc_write(port, RT1715_REG_PWR, regval);
+ if (rv)
+ return rv;
+
+ return tcpci_enter_low_power_mode(port);
+}
+#endif
+
+static int rt1715_set_vconn(int port, int enable)
+{
+ int rv;
+ int regval;
+
+ /*
+ * Auto-idle cannot be used while sourcing Vconn.
+ * See b/179256608#comment26 for explanation.
+ */
+ rv = tcpc_read(port, RT1715_REG_VENDOR_5, &regval);
+ if (rv)
+ return rv;
+
+ if (enable)
+ regval &= ~RT1715_REG_VENDOR_5_AUTOIDLE_EN;
+ else
+ regval |= RT1715_REG_VENDOR_5_AUTOIDLE_EN;
+
+ rv = tcpc_write(port, RT1715_REG_VENDOR_5, regval);
+ if (rv)
+ return rv;
+
+ return tcpci_tcpm_set_vconn(port, enable);
+}
+
static int rt1715_set_polarity(int port, enum tcpc_cc_polarity polarity)
{
int rv;
@@ -156,6 +214,17 @@ static int rt1715_set_polarity(int port, enum tcpc_cc_polarity polarity)
return tcpci_tcpm_set_polarity(port, polarity);
}
+static void rt1715_alert(int port)
+{
+ /*
+ * Make sure the wakeup interrupt is cleared. This bit is set on wakeup
+ * from LPM. See b/179256608#comment16 for explanation.
+ */
+ tcpc_write(port, RT1715_REG_RT_INT, RT1715_REG_RT_INT_WAKEUP);
+
+ tcpci_tcpc_alert(port);
+}
+
const struct tcpm_drv rt1715_tcpm_drv = {
.init = &rt1715_tcpci_tcpm_init,
.release = &tcpci_tcpm_release,
@@ -169,12 +238,12 @@ const struct tcpm_drv rt1715_tcpm_drv = {
#ifdef CONFIG_USB_PD_DECODE_SOP
.sop_prime_enable = &tcpci_tcpm_sop_prime_enable,
#endif
- .set_vconn = &tcpci_tcpm_set_vconn,
+ .set_vconn = &rt1715_set_vconn,
.set_msg_header = &tcpci_tcpm_set_msg_header,
.set_rx_enable = &tcpci_tcpm_set_rx_enable,
.get_message_raw = &tcpci_tcpm_get_message_raw,
.transmit = &tcpci_tcpm_transmit,
- .tcpc_alert = &tcpci_tcpc_alert,
+ .tcpc_alert = &rt1715_alert,
#ifdef CONFIG_USB_PD_DISCHARGE_TCPC
.tcpc_discharge_vbus = &tcpci_tcpc_discharge_vbus,
#endif
@@ -189,7 +258,7 @@ const struct tcpm_drv rt1715_tcpm_drv = {
#endif
.get_chip_info = &tcpci_get_chip_info,
#ifdef CONFIG_USB_PD_TCPC_LOW_POWER
- .enter_low_power_mode = &tcpci_enter_low_power_mode,
+ .enter_low_power_mode = &rt1715_enter_low_power_mode,
#endif
.set_bist_test_mode = &tcpci_set_bist_test_mode,
};
diff --git a/driver/tcpm/rt1715.h b/driver/tcpm/rt1715.h
index 334ab8f522..dcf2aa28d4 100644
--- a/driver/tcpm/rt1715.h
+++ b/driver/tcpm/rt1715.h
@@ -7,66 +7,78 @@
#define __CROS_EC_USB_PD_TCPM_RT1715_H
/* I2C interface */
-#define RT1715_I2C_ADDR_FLAGS 0x4E
+#define RT1715_I2C_ADDR_FLAGS 0x4E
-#define RT1715_VENDOR_ID 0x29CF
+#define RT1715_VENDOR_ID 0x29CF
-#define RT1715_REG_VENDOR_7 0xA0
-#define RT1715_REG_VENDOR_7_SOFT_RESET BIT(0)
+#define RT1715_REG_VENDOR_7 0xA0
+#define RT1715_REG_VENDOR_7_SOFT_RESET BIT(0)
-#define RT1715_REG_PHY_CTRL1 0x80
+#define RT1715_REG_PHY_CTRL1 0x80
/* Wait for tReceive before retrying transmit in response to a bad GoodCRC */
-#define RT1715_REG_PHY_CTRL1_ENRETRY BIT(7)
+#define RT1715_REG_PHY_CTRL1_ENRETRY BIT(7)
/*
* Bit 6:4 <TRANSCNT>: Consider CC to be idle if there are 7 or fewer BMC
* transients observed in <46.67us>
*/
-#define RT1715_REG_PHY_CTRL1_TRANSCNT_7 0x70
+#define RT1715_REG_PHY_CTRL1_TRANSCNT_7 0x70
/*
* Bit 1:0 <TRXFilter>: RX filter to make sure the stable received PD message.
* default value is 01b
* The debounce time is (register value + 2) * 41.67ns
*/
-#define RT1715_REG_PHY_CTRL1_TRXFILTER_125NS 0x01
-#define RT1715_REG_PHY_CTRL2 0x81
+#define RT1715_REG_PHY_CTRL1_TRXFILTER_125NS 0x01
+#define RT1715_REG_PHY_CTRL2 0x81
/*
* Decrease the time that the PHY will wait for a second transition to detect
* a BMC-encoded 1 bit from 2.67 us to 2.25 us.
* Timeout = register value * .04167 us.
*/
-#define RT1715_REG_PHY_CTRL2_CDRTHRESH_2_25US 54
+#define RT1715_REG_PHY_CTRL2_CDRTHRESH_2_25US 54
#define RT1715_REG_PHY_CTRL2_CDRTHRESH_2_5US 60
#define RT1715_REG_PHY_CTRL2_CDRTHRESH_2_58US 62
-#define RT1715_REG_BMCIO_RXDZSEL 0x93
-#define RT1715_REG_BMCIO_RXDZSEL_OCCTRL_600MA BIT(7)
-#define RT1715_REG_BMCIO_RXDZSEL_SEL BIT(0)
+#define RT1715_REG_PWR 0x90
+#define RT1715_REG_PWR_BMCIO_LPEN BIT(3)
+#define RT1715_REG_PWR_VBUS_DETEN BIT(1)
+#define RT1715_REG_PWR_BMCIO_OSCEN BIT(0)
-#define RT1715_REG_VENDOR_5 0x9B
-#define RT1715_REG_VENDOR_5_SHUTDOWN_OFF BIT(5)
-#define RT1715_REG_VENDOR_5_ENEXTMSG BIT(4)
+#define RT1715_REG_BMCIO_RXDZSEL 0x93
+#define RT1715_REG_BMCIO_RXDZSEL_OCCTRL_600MA BIT(7)
+#define RT1715_REG_BMCIO_RXDZSEL_SEL BIT(0)
-#define RT1715_REG_I2CRST_CTRL 0x9E
+#define RT1715_REG_RT_INT 0x98
+#define RT1715_REG_RT_INT_WAKEUP BIT(0)
+
+#define RT1715_REG_RT_MASK 0x99
+#define RT1715_REG_RT_MASK_M_WAKEUP BIT(0)
+
+#define RT1715_REG_VENDOR_5 0x9B
+#define RT1715_REG_VENDOR_5_SHUTDOWN_OFF BIT(5)
+#define RT1715_REG_VENDOR_5_ENEXTMSG BIT(4)
+#define RT1715_REG_VENDOR_5_AUTOIDLE_EN BIT(3)
+
+#define RT1715_REG_I2CRST_CTRL 0x9E
/* I2C reset : (val + 1) * 12.5ms */
-#define RT1715_REG_I2CRST_CTRL_TOUT_200MS 0x0F
-#define RT1715_REG_I2CRST_CTRL_TOUT_150MS 0x0B
-#define RT1715_REG_I2CRST_CTRL_TOUT_100MS 0x07
-#define RT1715_REG_I2CRST_CTRL_EN BIT(7)
+#define RT1715_REG_I2CRST_CTRL_TOUT_200MS 0x0F
+#define RT1715_REG_I2CRST_CTRL_TOUT_150MS 0x0B
+#define RT1715_REG_I2CRST_CTRL_TOUT_100MS 0x07
+#define RT1715_REG_I2CRST_CTRL_EN BIT(7)
-#define RT1715_REG_TTCPC_FILTER 0xA1
-#define RT1715_REG_TTCPC_FILTER_400US 0x0F
+#define RT1715_REG_TTCPC_FILTER 0xA1
+#define RT1715_REG_TTCPC_FILTER_400US 0x0F
-#define RT1715_REG_DRP_TOGGLE_CYCLE 0xA2
+#define RT1715_REG_DRP_TOGGLE_CYCLE 0xA2
/* DRP Duty : (51.2 + 6.4 * val) ms */
-#define RT1715_REG_DRP_TOGGLE_CYCLE_76MS 0x04
+#define RT1715_REG_DRP_TOGGLE_CYCLE_76MS 0x04
-#define RT1715_REG_DRP_DUTY_CTRL 0xA3
-#define RT1715_REG_DRP_DUTY_CTRL_40PERCENT 400
+#define RT1715_REG_DRP_DUTY_CTRL 0xA3
+#define RT1715_REG_DRP_DUTY_CTRL_40PERCENT 400
-#define RT1715_REG_BMCIO_RXDZEN 0xAF
-#define RT1715_REG_BMCIO_RXDZEN_ENABLE 0x01
-#define RT1715_REG_BMCIO_RXDZEN_DISABLE 0x00
+#define RT1715_REG_BMCIO_RXDZEN 0xAF
+#define RT1715_REG_BMCIO_RXDZEN_ENABLE 0x01
+#define RT1715_REG_BMCIO_RXDZEN_DISABLE 0x00
extern const struct tcpm_drv rt1715_tcpm_drv;