diff options
author | Rob Barnes <robbarnes@google.com> | 2021-01-27 16:33:25 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-02-04 19:57:25 +0000 |
commit | 2386e5d0add90a4301fc4fe3aabba7687444147a (patch) | |
tree | b84205977968ea588ebd630ce0ef2390e2c827d0 | |
parent | 7cc4c6e351b346c650817d13b8fc9ef1d7f0b547 (diff) | |
download | chrome-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.c | 136 | ||||
-rw-r--r-- | baseboard/guybrush/baseboard.h | 1 |
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 |