summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Barnes <robbarnes@google.com>2021-01-27 16:33:25 -0700
committerCommit Bot <commit-bot@chromium.org>2021-02-04 19:57:25 +0000
commit2386e5d0add90a4301fc4fe3aabba7687444147a (patch)
treeb84205977968ea588ebd630ce0ef2390e2c827d0
parent7cc4c6e351b346c650817d13b8fc9ef1d7f0b547 (diff)
downloadchrome-ec-2386e5d0add90a4301fc4fe3aabba7687444147a.tar.gz
guybrush: Configure FP6 USB Muxes for C0 and C1
Only PS8818 is supported with this change. Support for ANX74xx will be added later. BUG=b:178713079 BRANCH=None TEST=Build Change-Id: I60b58395001f258896612e9c3efa0a03c5d455bc Signed-off-by: Rob Barnes <robbarnes@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2654388 Reviewed-by: Diana Z <dzigterman@chromium.org>
-rw-r--r--baseboard/guybrush/baseboard.c136
-rw-r--r--baseboard/guybrush/baseboard.h1
2 files changed, 134 insertions, 3 deletions
diff --git a/baseboard/guybrush/baseboard.c b/baseboard/guybrush/baseboard.c
index be4eebe144..6f1f074f3b 100644
--- a/baseboard/guybrush/baseboard.c
+++ b/baseboard/guybrush/baseboard.c
@@ -10,16 +10,18 @@
#include "battery_fuel_gauge.h"
#include "charge_manager.h"
#include "charge_ramp.h"
-#include "charge_state.h"
#include "charge_state_v2.h"
+#include "charge_state.h"
#include "charger.h"
#include "chip/npcx/ps2_chip.h"
#include "chip/npcx/pwm_chip.h"
#include "chipset.h"
#include "driver/ppc/aoz1380.h"
#include "driver/ppc/nx20p348x.h"
+#include "driver/retimer/ps8818.h"
#include "driver/tcpm/nct38xx.h"
#include "driver/temp_sensor/sb_tsi.h"
+#include "driver/usb_mux/amd_fp6.h"
#include "gpio.h"
#include "hooks.h"
#include "i2c.h"
@@ -382,12 +384,49 @@ const struct pi3usb9201_config_t pi3usb9201_bc12_chips[] = {
};
BUILD_ASSERT(ARRAY_SIZE(pi3usb9201_bc12_chips) == USBC_PORT_COUNT);
+/*
+ * .init is not necessary here because it has nothing
+ * to do. Primary mux will handle mux state so .get is
+ * not needed as well. usb_mux.c can handle the situation
+ * properly.
+ */
+static int fsusb42umx_set_mux(const struct usb_mux*, mux_state_t);
+const struct usb_mux_driver usbc0_sbu_mux_driver = {
+ .set = fsusb42umx_set_mux,
+};
+
+/*
+ * Since FSUSB42UMX is not a i2c device, .i2c_port and
+ * .i2c_addr_flags are not required here.
+ */
+const struct usb_mux usbc0_sbu_mux = {
+ .usb_port = USBC_PORT_C0,
+ .driver = &usbc0_sbu_mux_driver,
+};
+
+static int board_ps8818_mux_set(const struct usb_mux*, mux_state_t);
+const struct usb_mux usbc1_ps8818 = {
+ .usb_port = USBC_PORT_C1,
+ .i2c_port = I2C_PORT_TCPC1,
+ .i2c_addr_flags = PS8818_I2C_ADDR_FLAGS,
+ .driver = &ps8818_usb_retimer_driver,
+ .board_set = &board_ps8818_mux_set,
+};
+
struct usb_mux usb_muxes[] = {
[USBC_PORT_C0] = {
- /* TODO: FIll in FP6 USB Mux configuration */
+ .usb_port = USBC_PORT_C0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = AMD_FP6_C0_MUX_I2C_ADDR,
+ .driver = &amd_fp6_usb_mux_driver,
+ .next_mux = &usbc0_sbu_mux,
},
[USBC_PORT_C1] = {
- /* TODO: Fill in dynamically */
+ .usb_port = USBC_PORT_C1,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = AMD_FP6_C4_MUX_I2C_ADDR,
+ .driver = &amd_fp6_usb_mux_driver,
+ .next_mux = &usbc1_ps8818,
}
};
BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == USBC_PORT_COUNT);
@@ -451,6 +490,97 @@ const struct pwm_t pwm_channels[] = {
};
BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT);
+/*
+ * USB C0 port SBU mux use standalone FSUSB42UMX
+ * chip and it needs a board specific driver.
+ * Overall, it will use chained mux framework.
+ */
+static int fsusb42umx_set_mux(const struct usb_mux *me, mux_state_t mux_state)
+{
+ if (mux_state & USB_PD_MUX_POLARITY_INVERTED)
+ ioex_set_level(IOEX_USB_C0_SBU_FLIP, 1);
+ else
+ ioex_set_level(IOEX_USB_C0_SBU_FLIP, 0);
+
+ return EC_SUCCESS;
+}
+
+/*
+ * PS8818 set mux board tuning.
+ * Adds in board specific gain and DP lane count configuration
+ * TODO(b/179036200): Adjust PS8818 tuning for guybrush and variants
+ */
+static int board_ps8818_mux_set(const struct usb_mux *me,
+ 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_field_update8(me,
+ PS8818_REG_PAGE1,
+ PS8818_REG1_APTX1EQ_10G_LEVEL,
+ PS8818_EQ_LEVEL_UP_MASK,
+ PS8818_EQ_LEVEL_UP_19DB);
+ if (rv)
+ return rv;
+
+ rv = ps8818_i2c_field_update8(me,
+ PS8818_REG_PAGE1,
+ PS8818_REG1_APTX2EQ_10G_LEVEL,
+ PS8818_EQ_LEVEL_UP_MASK,
+ PS8818_EQ_LEVEL_UP_19DB);
+ if (rv)
+ return rv;
+
+ rv = ps8818_i2c_field_update8(me,
+ PS8818_REG_PAGE1,
+ PS8818_REG1_APTX1EQ_5G_LEVEL,
+ PS8818_EQ_LEVEL_UP_MASK,
+ PS8818_EQ_LEVEL_UP_19DB);
+ if (rv)
+ return rv;
+
+ rv = ps8818_i2c_field_update8(me,
+ PS8818_REG_PAGE1,
+ PS8818_REG1_APTX2EQ_5G_LEVEL,
+ PS8818_EQ_LEVEL_UP_MASK,
+ PS8818_EQ_LEVEL_UP_19DB);
+ if (rv)
+ return rv;
+
+ /* Set the RX input termination */
+ rv = ps8818_i2c_field_update8(me,
+ PS8818_REG_PAGE1,
+ PS8818_REG1_RX_PHY,
+ PS8818_RX_INPUT_TERM_MASK,
+ PS8818_RX_INPUT_TERM_112_OHM);
+ if (rv)
+ return rv;
+ }
+
+ /* DP specific config */
+ if (mux_state & USB_PD_MUX_DP_ENABLED) {
+ /* Boost the DP gain */
+ rv = ps8818_i2c_field_update8(me,
+ PS8818_REG_PAGE1,
+ PS8818_REG1_DPEQ_LEVEL,
+ PS8818_DPEQ_LEVEL_UP_MASK,
+ PS8818_DPEQ_LEVEL_UP_19DB);
+ if (rv)
+ return rv;
+
+ /* Enable HPD on the DB */
+ gpio_set_level(GPIO_USB_C1_HPD, 1);
+ } else {
+ /* Disable HPD on the DB */
+ gpio_set_level(GPIO_USB_C1_HPD, 0);
+ }
+
+ return rv;
+}
+
int board_set_active_charge_port(int port)
{
int is_valid_port = (port >= 0 &&
diff --git a/baseboard/guybrush/baseboard.h b/baseboard/guybrush/baseboard.h
index 463834f310..a2caca06cd 100644
--- a/baseboard/guybrush/baseboard.h
+++ b/baseboard/guybrush/baseboard.h
@@ -164,6 +164,7 @@
#define CONFIG_USBC_PPC_NX20P3483
#define CONFIG_USBC_RETIMER_PS8818
#define CONFIG_USB_MUX_RUNTIME_CONFIG
+#define CONFIG_USB_MUX_AMD_FP6
#define GPIO_USB_C0_DP_HPD GPIO_USB_C0_HPD
#define GPIO_USB_C1_DP_HPD GPIO_USB_C1_HPD