summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Brockus <dbrockus@chromium.org>2020-01-29 09:33:08 -0700
committerCommit Bot <commit-bot@chromium.org>2020-01-31 14:48:08 +0000
commitb56a56eaba32f4d7d06750ffb3aed3f6e69b0d42 (patch)
treeb5c790ebdb658e057a9d05b49d6e05d467fd4637
parente600975e068dc2b2706eac2a11eb2d62564c1b4a (diff)
downloadchrome-ec-b56a56eaba32f4d7d06750ffb3aed3f6e69b0d42.tar.gz
ps8818: fix redriver configuration
in driver Added software IN_HPD control Added compile time optional debug in board specific tune function in usb_retimer Added gain control Added DP lane control BUG=b:146394157 BRANCH=none TEST=verify USB-C1 DP and USB connections Change-Id: Ida0cc243413b8fa469d3edb706040535e4a3f0e0 Signed-off-by: Denis Brockus <dbrockus@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2031645 Reviewed-by: Jett Rink <jettrink@chromium.org>
-rw-r--r--baseboard/zork/baseboard.c97
-rw-r--r--driver/retimer/ps8818.c99
-rw-r--r--driver/retimer/ps8818.h4
-rw-r--r--include/usb_mux.h9
4 files changed, 200 insertions, 9 deletions
diff --git a/baseboard/zork/baseboard.c b/baseboard/zork/baseboard.c
index 3dcbd96560..ef55d12138 100644
--- a/baseboard/zork/baseboard.c
+++ b/baseboard/zork/baseboard.c
@@ -467,6 +467,102 @@ void bc12_interrupt(enum gpio_signal signal)
*/
/*
+ * PS8818 set mux tuning.
+ * Adds in board specific gain and DP lane count configuration
+ */
+static int ps8818_tune_mux(int port, mux_state_t mux_state)
+{
+ int rv = EC_SUCCESS;
+
+ /* USB specific config */
+ if (mux_state & USB_PD_MUX_USB_ENABLED) {
+ /* Boost the USB gain */
+ rv = ps8818_i2c_write(port,
+ PS8818_REG_PAGE1,
+ PS8818_REG1_APTX1EQ_10G_LEVEL,
+ PS8818_EQ_LEVEL_UP_21DB);
+ if (rv)
+ return rv;
+
+ rv = ps8818_i2c_write(port,
+ PS8818_REG_PAGE1,
+ PS8818_REG1_APTX2EQ_10G_LEVEL,
+ PS8818_EQ_LEVEL_UP_21DB);
+ if (rv)
+ return rv;
+
+ rv = ps8818_i2c_write(port,
+ PS8818_REG_PAGE1,
+ PS8818_REG1_APTX1EQ_5G_LEVEL,
+ PS8818_EQ_LEVEL_UP_21DB);
+ if (rv)
+ return rv;
+
+ rv = ps8818_i2c_write(port,
+ PS8818_REG_PAGE1,
+ PS8818_REG1_APTX2EQ_5G_LEVEL,
+ PS8818_EQ_LEVEL_UP_21DB);
+ if (rv)
+ return rv;
+
+ rv = ps8818_i2c_write(port,
+ PS8818_REG_PAGE1,
+ PS8818_REG1_CRX1EQ_10G_LEVEL,
+ PS8818_EQ_LEVEL_UP_21DB);
+ if (rv)
+ return rv;
+
+ rv = ps8818_i2c_write(port,
+ PS8818_REG_PAGE1,
+ PS8818_REG1_CRX2EQ_10G_LEVEL,
+ PS8818_EQ_LEVEL_UP_21DB);
+ if (rv)
+ return rv;
+
+ rv = ps8818_i2c_write(port,
+ PS8818_REG_PAGE1,
+ PS8818_REG1_CRX1EQ_5G_LEVEL,
+ PS8818_EQ_LEVEL_UP_21DB);
+ if (rv)
+ return rv;
+
+ rv = ps8818_i2c_write(port,
+ PS8818_REG_PAGE1,
+ PS8818_REG1_CRX2EQ_5G_LEVEL,
+ PS8818_EQ_LEVEL_UP_21DB);
+ if (rv)
+ return rv;
+ }
+
+ /* DP specific config */
+ if (mux_state & USB_PD_MUX_DP_ENABLED) {
+ int val;
+
+ /* Boost the DP gain */
+ rv = ps8818_i2c_write(port,
+ PS8818_REG_PAGE1,
+ PS8818_REG1_DPEQ_LEVEL,
+ PS8818_DPEQ_LEVEL_UP_21DB);
+ if (rv)
+ return rv;
+
+ /* Set DP lane count */
+ val = (mux_state & USB_PD_MUX_USB_ENABLED)
+ ? PS8818_LANE_COUNT_SET_2_LANE
+ : PS8818_LANE_COUNT_SET_4_LANE;
+
+ rv = ps8818_i2c_write(port,
+ PS8818_REG_PAGE2,
+ PS8818_REG2_LANE_COUNT_SET,
+ val);
+ if (rv)
+ return rv;
+ }
+
+ return rv;
+}
+
+/*
* FP5 is a true MUX but being used as a secondary MUX. Don't want to
* send FLIP or this will cause a double flip
*/
@@ -532,6 +628,7 @@ static int zork_c1_detect(int port, int err_if_power_off)
/* Main MUX is FP5, secondary MUX is PS8818 */
usb_muxes[USBC_PORT_C1].driver = &amd_fp5_usb_mux_driver;
usb_retimers[USBC_PORT_C1].driver = &ps8818_usb_retimer;
+ usb_retimers[USBC_PORT_C1].tune = &ps8818_tune_mux;
return rv;
}
diff --git a/driver/retimer/ps8818.c b/driver/retimer/ps8818.c
index d9c89ef7e4..6059f7f0d4 100644
--- a/driver/retimer/ps8818.c
+++ b/driver/retimer/ps8818.c
@@ -14,15 +14,33 @@
#include "ps8818.h"
#include "usb_mux.h"
-static int ps8818_i2c_read(int port, int page, int offset, int *data)
+#define PS8818_DEBUG 0
+
+int ps8818_i2c_read(int port, int page, int offset, int *data)
{
- return i2c_read8(usb_retimers[port].i2c_port,
+ int rv;
+
+ rv = i2c_read8(usb_retimers[port].i2c_port,
+ usb_retimers[port].i2c_addr_flags + page,
+ offset, data);
+
+ if (PS8818_DEBUG)
+ ccprintf("%s(%d:0x%02X, 0x%02X) => 0x%02X\n", __func__,
+ usb_retimers[port].i2c_port,
usb_retimers[port].i2c_addr_flags + page,
- offset, data);
+ offset, *data);
+
+ return rv;
}
-static int ps8818_i2c_write(int port, int page, int offset, int data)
+int ps8818_i2c_write(int port, int page, int offset, int data)
{
+ if (PS8818_DEBUG)
+ ccprintf("%s(%d:0x%02X, 0x%02X, 0x%02X)\n", __func__,
+ usb_retimers[port].i2c_port,
+ usb_retimers[port].i2c_addr_flags + page,
+ offset, data);
+
return i2c_write8(usb_retimers[port].i2c_port,
usb_retimers[port].i2c_addr_flags + page,
offset, data);
@@ -50,8 +68,17 @@ static int ps8818_set_mux(int port, mux_state_t mux_state)
if (chipset_in_state(CHIPSET_STATE_HARD_OFF))
return (mux_state == USB_PD_MUX_NONE) ? EC_SUCCESS
- : EC_ERROR_NOT_POWERED;
+ : EC_ERROR_NOT_POWERED;
+
+ if (PS8818_DEBUG)
+ ccprintf("%s(%d, 0x%02X) %s %s %s\n",
+ __func__, port, mux_state,
+ (mux_state & USB_PD_MUX_USB_ENABLED) ? "USB" : "",
+ (mux_state & USB_PD_MUX_DP_ENABLED) ? "DP" : "",
+ (mux_state & USB_PD_MUX_POLARITY_INVERTED)
+ ? "FLIP" : "");
+ /* Set the mode */
if (mux_state & USB_PD_MUX_USB_ENABLED)
val |= PS8818_MODE_USB_ENABLE;
if (mux_state & USB_PD_MUX_DP_ENABLED)
@@ -64,14 +91,68 @@ static int ps8818_set_mux(int port, mux_state_t mux_state)
if (rv)
return rv;
+ /* Set the flip */
val = 0;
if (mux_state & USB_PD_MUX_POLARITY_INVERTED)
val |= PS8818_FLIP_CONFIG;
- return ps8818_i2c_write(port,
- PS8818_REG_PAGE0,
- PS8818_REG0_FLIP,
- val);
+ rv = ps8818_i2c_write(port,
+ PS8818_REG_PAGE0,
+ PS8818_REG0_FLIP,
+ val);
+ if (rv)
+ return rv;
+
+ /* Set the IN_HPD */
+ val = PS8818_DPHPD_CONFIG_INHPD_DISABLE;
+ if (mux_state & USB_PD_MUX_DP_ENABLED)
+ val |= PS8818_DPHPD_PLUGGED;
+
+ rv = ps8818_i2c_write(port,
+ PS8818_REG_PAGE0,
+ PS8818_REG0_DPHPD_CONFIG,
+ val);
+ if (rv)
+ return rv;
+
+ /* Board specific retimer mux tuning */
+ if (usb_retimers[port].tune) {
+ rv = usb_retimers[port].tune(port, mux_state);
+ if (rv)
+ return rv;
+ }
+
+ if (PS8818_DEBUG) {
+ int tx_status;
+ int rx_status;
+
+ rv = ps8818_i2c_read(port,
+ PS8818_REG_PAGE2,
+ PS8818_REG2_TX_STATUS,
+ &tx_status);
+ if (rv)
+ return rv;
+
+ rv = ps8818_i2c_read(port,
+ PS8818_REG_PAGE2,
+ PS8818_REG2_RX_STATUS,
+ &rx_status);
+ if (rv)
+ return rv;
+
+ ccprintf("%s: tx:channel %snormal %s10Gbps\n",
+ __func__,
+ (tx_status & PS8818_STATUS_NORMAL_OPERATION)
+ ? "" : "NOT-",
+ (tx_status & PS8818_STATUS_10_GBPS) ? "" : "NON-");
+ ccprintf("%s: rx:channel %snormal %s10Gbps\n",
+ __func__,
+ (rx_status & PS8818_STATUS_NORMAL_OPERATION)
+ ? "" : "NOT-",
+ (rx_status & PS8818_STATUS_10_GBPS) ? "" : "NON-");
+ }
+
+ return rv;
}
const struct usb_retimer_driver ps8818_usb_retimer = {
diff --git a/driver/retimer/ps8818.h b/driver/retimer/ps8818.h
index a42605229e..0b5c3dfe83 100644
--- a/driver/retimer/ps8818.h
+++ b/driver/retimer/ps8818.h
@@ -24,6 +24,7 @@
#define PS8818_REG0_DPHPD_CONFIG 0x02
#define PS8818_DPHPD_CONFIG_INHPD_DISABLE BIT(7)
+#define PS8818_DPHPD_PLUGGED BIT(6)
/*
* PAGE 1 Register Definitions
@@ -93,4 +94,7 @@ extern const struct usb_retimer_driver ps8818_usb_retimer;
int ps8818_detect(int port);
+int ps8818_i2c_read(int port, int page, int offset, int *data);
+int ps8818_i2c_write(int port, int page, int offset, int data);
+
#endif /* __CROS_EC_USB_RETIMER_PS8818_H */
diff --git a/include/usb_mux.h b/include/usb_mux.h
index 152b240fa0..35350222f0 100644
--- a/include/usb_mux.h
+++ b/include/usb_mux.h
@@ -174,6 +174,15 @@ struct usb_retimer {
/* Driver interfaces for this retimer */
const struct usb_retimer_driver *driver;
+
+ /*
+ * USB retimer board specific tune on set mux_state.
+ *
+ * @param port usb port of retimer (not port_addr)
+ * @param mux_state State to set retimer mode to.
+ * @return EC_SUCCESS on success, non-zero error code on failure.
+ */
+ int (*tune)(int port, mux_state_t mux_state);
};
/*