summaryrefslogtreecommitdiff
path: root/baseboard
diff options
context:
space:
mode:
authorDenis Brockus <dbrockus@chromium.org>2020-02-21 14:21:05 -0700
committerCommit Bot <commit-bot@chromium.org>2020-02-28 22:47:11 +0000
commit9c194fd057558a1dfadee419e92aca31953a86fc (patch)
tree001ae7c162a4152312a180574ae58e19a3763eb8 /baseboard
parentab35b456ad8c52f336ea793b17155cfc796c4e44 (diff)
downloadchrome-ec-9c194fd057558a1dfadee419e92aca31953a86fc.tar.gz
usb_mux: retimer: mux as chained mux and retimer
This makes retimers appear as generic muxes. By allowing a chain of muxes they can be stacked up to the new configurations that zork requires and will continue to work as they did before on configurations that only have a single mux. The code used to have two different arrays, 1) muxes and 2) retimers. On one of the zork configurations the processor MUX stopped being the primary mux and the retimer took its place. In a different configuration of that same platform it left the primary and secondary alone but the mux_set FLIP operation had to be ignored. Since the same interfaces needed to be available for both it stopped making sense to have two different structures and two different methods of handling them. This consolodates the two into one. The platforms that do not have retimers, this change will not make any difference. For platforms like zork, it will remove the retimers and make them chained muxes. So testing on trembyle makes sense to verify, BUG=b:147593660 BRANCH=none TEST=verify USB still works on trembyle Change-Id: I286cf1e302f9bd3dd7e81098ec08514a2a009fe3 Signed-off-by: Denis Brockus <dbrockus@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2066794 Commit-Queue: Jett Rink <jettrink@chromium.org> Reviewed-by: Edward Hill <ecgh@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'baseboard')
-rw-r--r--baseboard/dragonegg/baseboard.c6
-rw-r--r--baseboard/grunt/baseboard.c18
-rw-r--r--baseboard/grunt/usb_pd_policy.c4
-rw-r--r--baseboard/intelrvp/retimer.c15
-rw-r--r--baseboard/intelrvp/usb_mux.c44
-rw-r--r--baseboard/kalista/baseboard.c17
-rw-r--r--baseboard/kukui/usb_pd_policy.c12
-rw-r--r--baseboard/octopus/baseboard.c9
-rw-r--r--baseboard/octopus/variant_usbc_ec_tcpcs.c15
-rw-r--r--baseboard/octopus/variant_usbc_standalone_tcpcs.c8
-rw-r--r--baseboard/volteer/baseboard.c24
-rw-r--r--baseboard/volteer/baseboard.h3
-rw-r--r--baseboard/zork/baseboard.c175
-rw-r--r--baseboard/zork/baseboard.h2
-rw-r--r--baseboard/zork/usb_pd_policy.c10
15 files changed, 203 insertions, 159 deletions
diff --git a/baseboard/dragonegg/baseboard.c b/baseboard/dragonegg/baseboard.c
index 85c39296f6..aa2ee875b7 100644
--- a/baseboard/dragonegg/baseboard.c
+++ b/baseboard/dragonegg/baseboard.c
@@ -200,19 +200,21 @@ struct ppc_config_t ppc_chips[CONFIG_USB_PD_PORT_MAX_COUNT] = {
};
unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips);
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_ITE_0] = {
+ .usb_port = USB_PD_PORT_ITE_0,
.driver = &virtual_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
},
[USB_PD_PORT_ITE_1] = {
+ .usb_port = USB_PD_PORT_ITE_1,
.driver = &virtual_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
},
[USB_PD_PORT_TUSB422_2] = {
- .port_addr = 0,
+ .usb_port = USB_PD_PORT_TUSB422_2,
.driver = &virtual_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
},
diff --git a/baseboard/grunt/baseboard.c b/baseboard/grunt/baseboard.c
index 5ab7dc8d53..82bf063bf9 100644
--- a/baseboard/grunt/baseboard.c
+++ b/baseboard/grunt/baseboard.c
@@ -135,8 +135,6 @@ void tcpc_alert_event(enum gpio_signal signal)
void board_tcpc_init(void)
{
- int port;
-
/* Only reset TCPC if not sysjump */
if (!system_jumped_to_this_image())
board_reset_pd_mcu();
@@ -157,11 +155,8 @@ void board_tcpc_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) {
- const struct usb_mux *mux = &usb_muxes[port];
-
- mux->hpd_update(port, 0, 0);
- }
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C + 1);
@@ -280,28 +275,31 @@ void board_reset_pd_mcu(void)
static uint32_t sku_id;
-static int ps8751_tune_mux(int port)
+static int ps8751_tune_mux(const struct usb_mux *me)
{
/* Tune USB mux registers for treeya's port 1 Rx measurement */
if ((sku_id >= 0xa0) && (sku_id <= 0xaf))
- mux_write(port, PS8XXX_REG_MUX_USB_C2SS_EQ, 0x40);
+ mux_write(me, PS8XXX_REG_MUX_USB_C2SS_EQ, 0x40);
return EC_SUCCESS;
}
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
#ifdef VARIANT_GRUNT_TCPC_0_ANX3429
[USB_PD_PORT_ANX74XX] = {
+ .usb_port = USB_PD_PORT_ANX74XX,
.driver = &anx74xx_tcpm_usb_mux_driver,
.hpd_update = &anx74xx_tcpc_update_hpd_status,
},
#elif defined(VARIANT_GRUNT_TCPC_0_ANX3447)
[USB_PD_PORT_ANX74XX] = {
+ .usb_port = USB_PD_PORT_ANX74XX,
.driver = &anx7447_usb_mux_driver,
.hpd_update = &anx7447_tcpc_update_hpd_status,
},
#endif
[USB_PD_PORT_PS8751] = {
+ .usb_port = USB_PD_PORT_PS8751,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
.board_init = &ps8751_tune_mux,
diff --git a/baseboard/grunt/usb_pd_policy.c b/baseboard/grunt/usb_pd_policy.c
index 4edee5f232..0d2e41b64a 100644
--- a/baseboard/grunt/usb_pd_policy.c
+++ b/baseboard/grunt/usb_pd_policy.c
@@ -129,8 +129,6 @@ __override int svdm_dp_config(int port, uint32_t *payload)
#define PORT_TO_HPD(port) ((port) ? GPIO_USB_C1_DP_HPD : GPIO_USB_C0_DP_HPD)
__override void svdm_dp_post_config(int port)
{
- const struct usb_mux * const mux = &usb_muxes[port];
-
/* Connect the SBU and USB lines to the connector. */
ppc_set_sbu(port, 1);
usb_mux_set(port, svdm_dp_mux_mode(port), USB_SWITCH_CONNECT,
@@ -144,7 +142,7 @@ __override void svdm_dp_post_config(int port)
/* set the minimum time delay (2ms) for the next HPD IRQ */
svdm_hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL;
- mux->hpd_update(port, 1, 0);
+ usb_mux_hpd_update(port, 1, 0);
}
#endif /* CONFIG_USB_PD_ALT_MODE_DFP */
diff --git a/baseboard/intelrvp/retimer.c b/baseboard/intelrvp/retimer.c
index a444806062..0397057641 100644
--- a/baseboard/intelrvp/retimer.c
+++ b/baseboard/intelrvp/retimer.c
@@ -29,19 +29,4 @@ const struct bb_usb_control bb_controls[] = {
};
BUILD_ASSERT(ARRAY_SIZE(bb_controls) == CONFIG_USB_PD_PORT_MAX_COUNT);
-struct usb_retimer usb_retimers[] = {
- [TYPE_C_PORT_0] = {
- .driver = &bb_usb_retimer,
- .i2c_port = I2C_PORT0_BB_RETIMER,
- .i2c_addr_flags = I2C_PORT0_BB_RETIMER_ADDR,
- },
-#ifdef HAS_TASK_PD_C1
- [TYPE_C_PORT_1] = {
- .driver = &bb_usb_retimer,
- .i2c_port = I2C_PORT1_BB_RETIMER,
- .i2c_addr_flags = I2C_PORT1_BB_RETIMER_ADDR,
- },
-#endif /* HAS_TASK_PD_C1 */
-};
-BUILD_ASSERT(ARRAY_SIZE(usb_retimers) == CONFIG_USB_PD_PORT_MAX_COUNT);
#endif /* CONFIG_USBC_RETIMER_INTEL_BB */
diff --git a/baseboard/intelrvp/usb_mux.c b/baseboard/intelrvp/usb_mux.c
index 2dee2bf759..644ae1735c 100644
--- a/baseboard/intelrvp/usb_mux.c
+++ b/baseboard/intelrvp/usb_mux.c
@@ -7,20 +7,46 @@
#include "common.h"
#include "anx7440.h"
+#include "bb_retimer.h"
#include "timer.h"
#include "usb_mux.h"
+#ifdef CONFIG_USBC_RETIMER_INTEL_BB
+struct usb_mux usbc0_retimer = {
+ .usb_port = TYPE_C_PORT_0,
+ .driver = &bb_usb_retimer,
+ .i2c_port = I2C_PORT0_BB_RETIMER,
+ .i2c_addr_flags = I2C_PORT0_BB_RETIMER_ADDR,
+};
+#ifdef HAS_TASK_PD_C1
+struct usb_mux usbc1_retimer = {
+ .usb_port = TYPE_C_PORT_1,
+ .driver = &bb_usb_retimer,
+ .i2c_port = I2C_PORT1_BB_RETIMER,
+ .i2c_addr_flags = I2C_PORT1_BB_RETIMER_ADDR,
+};
+#endif /* HAS_TASK_PD_C1 */
+#endif
+
/* USB muxes Configuration */
#ifdef CONFIG_USB_MUX_VIRTUAL
-struct usb_mux usb_muxes[] = {
+const struct usb_mux usb_muxes[] = {
[TYPE_C_PORT_0] = {
+ .usb_port = TYPE_C_PORT_0,
.driver = &virtual_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
+#ifdef CONFIG_USBC_RETIMER_INTEL_BB
+ .next_mux = &usbc0_retimer,
+#endif
},
#ifdef HAS_TASK_PD_C1
[TYPE_C_PORT_1] = {
+ .usb_port = TYPE_C_PORT_1,
.driver = &virtual_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
+#ifdef CONFIG_USBC_RETIMER_INTEL_BB
+ .next_mux = &usbc1_retimer,
+#endif
},
#endif /* HAS_TASK_PD_C1 */
};
@@ -28,15 +54,25 @@ BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == CONFIG_USB_PD_PORT_MAX_COUNT);
#endif /* CONFIG_USB_MUX_VIRTUAL */
#ifdef CONFIG_USB_MUX_ANX7440
-struct usb_mux usb_muxes[] = {
+const struct usb_mux usb_muxes[] = {
[TYPE_C_PORT_0] = {
- .port_addr = I2C_ADDR_USB_MUX0_FLAGS,
+ .usb_port = TYPE_C_PORT_0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = I2C_ADDR_USB_MUX0_FLAGS,
.driver = &anx7440_usb_mux_driver,
+#ifdef CONFIG_USBC_RETIMER_INTEL_BB
+ .next_mux = &usbc0_retimer,
+#endif
},
#ifdef HAS_TASK_PD_C1
[TYPE_C_PORT_1] = {
- .port_addr = I2C_ADDR_USB_MUX1_FLAGS,
+ .usb_port = TYPE_C_PORT_1,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = I2C_ADDR_USB_MUX1_FLAGS,
.driver = &anx7440_usb_mux_driver,
+#ifdef CONFIG_USBC_RETIMER_INTEL_BB
+ .next_mux = &usbc1_retimer,
+#endif
},
#endif /* HAS_TASK_PD_C1 */
};
diff --git a/baseboard/kalista/baseboard.c b/baseboard/kalista/baseboard.c
index 859962b07c..6592033c83 100644
--- a/baseboard/kalista/baseboard.c
+++ b/baseboard/kalista/baseboard.c
@@ -150,19 +150,20 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
-static int ps8751_tune_mux(int port)
+static int ps8751_tune_mux(const struct usb_mux *me)
{
/* 0x98 sets lower EQ of DP port (4.5db) */
- mux_write(port, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98);
+ mux_write(me, PS8XXX_REG_MUX_DP_EQ_CONFIGURATION, 0x98);
return EC_SUCCESS;
}
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
{
+ .usb_port = 0,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
.board_init = &ps8751_tune_mux,
- }
+ },
};
const int usb_port_enable[USB_PORT_COUNT] = {
@@ -181,7 +182,7 @@ void board_reset_pd_mcu(void)
void board_tcpc_init(void)
{
- int port, reg;
+ int reg;
/* This needs to be executed only once per boot. It could be run by RO
* if we boot in recovery mode. It could be run by RW if we boot in
@@ -202,10 +203,8 @@ void board_tcpc_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) {
- const struct usb_mux *mux = &usb_muxes[port];
- mux->hpd_update(port, 0, 0);
- }
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C+1);
diff --git a/baseboard/kukui/usb_pd_policy.c b/baseboard/kukui/usb_pd_policy.c
index 0925c1b329..b2d56e23b2 100644
--- a/baseboard/kukui/usb_pd_policy.c
+++ b/baseboard/kukui/usb_pd_policy.c
@@ -179,8 +179,6 @@ __override int svdm_dp_config(int port, uint32_t *payload)
__override void svdm_dp_post_config(int port)
{
- const struct usb_mux * const mux = &usb_muxes[port];
-
dp_flags[port] |= DP_FLAGS_DP_ON;
if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING))
return;
@@ -192,7 +190,8 @@ __override void svdm_dp_post_config(int port)
/* set the minimum time delay (2ms) for the next HPD IRQ */
svdm_hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL;
- mux->hpd_update(port, 1, 0);
+
+ usb_mux_hpd_update(port, 1, 0);
}
__override int svdm_dp_attention(int port, uint32_t *payload)
@@ -200,7 +199,6 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
int cur_lvl = gpio_get_level(GPIO_USB_C0_HPD_OD);
int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]);
int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]);
- const struct usb_mux * const mux = &usb_muxes[port];
dp_status[port] = payload[1];
@@ -211,7 +209,7 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
return 1;
}
- mux->hpd_update(port, lvl, irq);
+ usb_mux_hpd_update(port, lvl, irq);
if (irq & cur_lvl) {
uint64_t now = get_time().val;
@@ -250,13 +248,11 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
__override void svdm_exit_dp_mode(int port)
{
- const struct usb_mux * const mux = &usb_muxes[port];
-
svdm_safe_dp_mode(port);
gpio_set_level(GPIO_USB_C0_HPD_OD, 0);
#ifdef VARIANT_KUKUI_DP_MUX_GPIO
board_set_dp_mux_control(0, 0);
#endif
- mux->hpd_update(port, 0, 0);
+ usb_mux_hpd_update(port, 0, 0);
}
#endif /* CONFIG_USB_PD_ALT_MODE_DFP */
diff --git a/baseboard/octopus/baseboard.c b/baseboard/octopus/baseboard.c
index cd9296cd19..ceb32868a0 100644
--- a/baseboard/octopus/baseboard.c
+++ b/baseboard/octopus/baseboard.c
@@ -216,8 +216,6 @@ enum adc_channel board_get_vbus_adc(int port)
void baseboard_tcpc_init(void)
{
- int port;
-
/* Only reset TCPC if not sysjump */
if (!system_jumped_to_this_image())
board_reset_pd_mcu();
@@ -226,11 +224,8 @@ void baseboard_tcpc_init(void)
* Initialize HPD to low; after sysjump SOC needs to see
* HPD pulse to enable video path
*/
- for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) {
- const struct usb_mux *mux = &usb_muxes[port];
-
- mux->hpd_update(port, 0, 0);
- }
+ for (int port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; ++port)
+ usb_mux_hpd_update(port, 0, 0);
}
/* Called after the cbi_init (via +2) */
DECLARE_HOOK(HOOK_INIT, baseboard_tcpc_init, HOOK_PRIO_INIT_I2C + 2);
diff --git a/baseboard/octopus/variant_usbc_ec_tcpcs.c b/baseboard/octopus/variant_usbc_ec_tcpcs.c
index a247ef6452..cbc5fd79e0 100644
--- a/baseboard/octopus/variant_usbc_ec_tcpcs.c
+++ b/baseboard/octopus/variant_usbc_ec_tcpcs.c
@@ -48,9 +48,10 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
/* USB-C MUX Configuration */
/* TODO(crbug.com/826441): Consolidate this logic with other impls */
-static void board_it83xx_hpd_status(int port, int hpd_lvl, int hpd_irq)
+static void board_it83xx_hpd_status(const struct usb_mux *me,
+ int hpd_lvl, int hpd_irq)
{
- enum gpio_signal gpio = port ?
+ enum gpio_signal gpio = me->usb_port ?
GPIO_USB_C1_HPD_1V8_ODL : GPIO_USB_C0_HPD_1V8_ODL;
/* Invert HPD level since GPIOs are active low. */
@@ -67,15 +68,17 @@ static void board_it83xx_hpd_status(int port, int hpd_lvl, int hpd_irq)
/* This configuration might be override by each boards */
struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_ITE_0] = {
- /* Driver uses I2C_PORT_USB_MUX as I2C port */
- .port_addr = IT5205_I2C_ADDR1_FLAGS,
+ .usb_port = USB_PD_PORT_ITE_0,
+ .i2c_port = I2C_PORT_USB_MUX,
+ .i2c_addr_flags = IT5205_I2C_ADDR1_FLAGS,
.driver = &it5205_usb_mux_driver,
.hpd_update = &board_it83xx_hpd_status,
},
[USB_PD_PORT_ITE_1] = {
+ .usb_port = USB_PD_PORT_ITE_1,
/* Use PS8751 as mux only */
- .port_addr = MUX_PORT_AND_ADDR(
- I2C_PORT_USBC1, PS8751_I2C_ADDR1_FLAGS),
+ .i2c_port = I2C_PORT_USBC1,
+ .i2c_addr_flags = PS8751_I2C_ADDR1_FLAGS,
.flags = USB_MUX_FLAG_NOT_TCPC,
.driver = &ps8xxx_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
diff --git a/baseboard/octopus/variant_usbc_standalone_tcpcs.c b/baseboard/octopus/variant_usbc_standalone_tcpcs.c
index 41025de7fa..18a8a3035a 100644
--- a/baseboard/octopus/variant_usbc_standalone_tcpcs.c
+++ b/baseboard/octopus/variant_usbc_standalone_tcpcs.c
@@ -61,16 +61,17 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
/* USB-C MUX Configuration */
#if defined(VARIANT_OCTOPUS_TCPC_0_PS8751)
-static int ps8751_tune_mux(int port)
+static int ps8751_tune_mux(const struct usb_mux *me)
{
/* Tune USB mux registers for casta's port 0 Rx measurement */
- mux_write(port, PS8XXX_REG_MUX_USB_C2SS_EQ, 0x40);
+ mux_write(me, PS8XXX_REG_MUX_USB_C2SS_EQ, 0x40);
return EC_SUCCESS;
}
#endif
-struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_TCPC_0] = {
+ .usb_port = USB_PD_PORT_TCPC_0,
#if defined(VARIANT_OCTOPUS_TCPC_0_PS8751)
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
@@ -81,6 +82,7 @@ struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
#endif
},
[USB_PD_PORT_TCPC_1] = {
+ .usb_port = USB_PD_PORT_TCPC_1,
.driver = &tcpci_tcpm_usb_mux_driver,
.hpd_update = &ps8xxx_tcpc_update_hpd_status,
}
diff --git a/baseboard/volteer/baseboard.c b/baseboard/volteer/baseboard.c
index 53b3a0d146..24e08b514b 100644
--- a/baseboard/volteer/baseboard.c
+++ b/baseboard/volteer/baseboard.c
@@ -396,14 +396,23 @@ unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips);
/******************************************************************************/
/* USBC mux configuration - Tiger Lake includes internal mux */
+struct usb_mux usbc1_usb_retimer = {
+ .usb_port = USBC_PORT_C1,
+ .driver = &bb_usb_retimer,
+ .i2c_port = I2C_PORT_USB_1_MIX,
+ .i2c_addr_flags = USBC_PORT_C1_BB_RETIMER_I2C_ADDR,
+};
struct usb_mux usb_muxes[] = {
[USBC_PORT_C0] = {
+ .usb_port = USBC_PORT_C0,
.driver = &virtual_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
},
[USBC_PORT_C1] = {
+ .usb_port = USBC_PORT_C1,
.driver = &virtual_usb_mux_driver,
.hpd_update = &virtual_hpd_update,
+ .next_mux = &usbc1_usb_retimer,
},
};
BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == USBC_PORT_COUNT);
@@ -421,18 +430,6 @@ struct bb_usb_control bb_controls[] = {
};
BUILD_ASSERT(ARRAY_SIZE(bb_controls) == USBC_PORT_COUNT);
-struct usb_retimer usb_retimers[] = {
- [USBC_PORT_C0] = {
- /* USB-C port 0 doesn't have a retimer */
- },
- [USBC_PORT_C1] = {
- .driver = &bb_usb_retimer,
- .i2c_port = I2C_PORT_USB_1_MIX,
- .i2c_addr_flags = USBC_PORT_C1_BB_RETIMER_I2C_ADDR,
- },
-};
-BUILD_ASSERT(ARRAY_SIZE(usb_retimers) == USBC_PORT_COUNT);
-
static void baseboard_tcpc_init(void)
{
/* Only reset TCPC if not sysjump */
@@ -660,8 +657,7 @@ static void config_db_usb3(void)
{
tcpc_config[USBC_PORT_C1] = tcpc_config_p1_usb3;
/* USB-C port 1 has an integrated retimer */
- memset(&usb_retimers[USBC_PORT_C1], 0,
- sizeof(usb_retimers[USBC_PORT_C1]));
+ usb_muxes[USBC_PORT_C1].next_mux = NULL;
}
/*
diff --git a/baseboard/volteer/baseboard.h b/baseboard/volteer/baseboard.h
index 0f53a0eb65..a9d1816fea 100644
--- a/baseboard/volteer/baseboard.h
+++ b/baseboard/volteer/baseboard.h
@@ -184,6 +184,8 @@
#define CONFIG_USB_PD_VBUS_DETECT_PPC
#define CONFIG_USB_PD_VBUS_MEASURE_NOT_PRESENT
+#define CONFIG_USB_MUX_RUNTIME_CONFIG
+
#define CONFIG_USBC_PPC
#define CONFIG_CMD_PPC_DUMP
/* Note - SN5S330 support automatically adds
@@ -224,7 +226,6 @@
#define PD_VCONN_SWAP_DELAY 5000 /* us */
/* Retimer */
-#define CONFIG_USBC_MUX_RETIMER
#define CONFIG_USBC_RETIMER_INTEL_BB
#define CONFIG_USBC_RETIMER_INTEL_BB_RUNTIME_CONFIG
#define USBC_PORT_C1_BB_RETIMER_I2C_ADDR 0x40
diff --git a/baseboard/zork/baseboard.c b/baseboard/zork/baseboard.c
index f64a911f94..69a61681ff 100644
--- a/baseboard/zork/baseboard.c
+++ b/baseboard/zork/baseboard.c
@@ -23,7 +23,6 @@
#include "driver/retimer/pi3dpx1207.h"
#include "driver/retimer/ps8802.h"
#include "driver/retimer/ps8818.h"
-#include "driver/tcpm/ps8xxx.h"
#include "driver/tcpm/nct38xx.h"
#include "driver/temp_sensor/sb_tsi.h"
#include "driver/usb_mux/amd_fp5.h"
@@ -440,19 +439,19 @@ void bc12_interrupt(enum gpio_signal signal)
* PS8802 set mux tuning.
* Adds in board specific gain and DP lane count configuration
*/
-static int ps8802_tune_mux(int port, mux_state_t mux_state)
+static int ps8802_mux_set(const struct usb_mux *me, mux_state_t mux_state)
{
int rv = EC_SUCCESS;
/* Make sure the PS8802 is awake */
- rv = ps8802_i2c_wake(port);
+ rv = ps8802_i2c_wake(me);
if (rv)
return rv;
/* USB specific config */
if (mux_state & USB_PD_MUX_USB_ENABLED) {
/* Boost the USB gain */
- rv = ps8802_i2c_field_update16(port,
+ rv = ps8802_i2c_field_update16(me,
PS8802_REG_PAGE2,
PS8802_REG2_USB_SSEQ_LEVEL,
PS8802_USBEQ_LEVEL_UP_MASK,
@@ -464,7 +463,7 @@ static int ps8802_tune_mux(int port, mux_state_t mux_state)
/* DP specific config */
if (mux_state & USB_PD_MUX_DP_ENABLED) {
/* Boost the DP gain */
- rv = ps8802_i2c_field_update8(port,
+ rv = ps8802_i2c_field_update8(me,
PS8802_REG_PAGE2,
PS8802_REG2_DPEQ_LEVEL,
PS8802_DPEQ_LEVEL_UP_MASK,
@@ -486,14 +485,14 @@ static int ps8802_tune_mux(int port, mux_state_t mux_state)
* 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)
+static int 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(port,
+ rv = ps8818_i2c_field_update8(me,
PS8818_REG_PAGE1,
PS8818_REG1_APTX1EQ_10G_LEVEL,
PS8818_EQ_LEVEL_UP_MASK,
@@ -501,7 +500,7 @@ static int ps8818_tune_mux(int port, mux_state_t mux_state)
if (rv)
return rv;
- rv = ps8818_i2c_field_update8(port,
+ rv = ps8818_i2c_field_update8(me,
PS8818_REG_PAGE1,
PS8818_REG1_APTX2EQ_10G_LEVEL,
PS8818_EQ_LEVEL_UP_MASK,
@@ -509,7 +508,7 @@ static int ps8818_tune_mux(int port, mux_state_t mux_state)
if (rv)
return rv;
- rv = ps8818_i2c_field_update8(port,
+ rv = ps8818_i2c_field_update8(me,
PS8818_REG_PAGE1,
PS8818_REG1_APTX1EQ_5G_LEVEL,
PS8818_EQ_LEVEL_UP_MASK,
@@ -517,7 +516,7 @@ static int ps8818_tune_mux(int port, mux_state_t mux_state)
if (rv)
return rv;
- rv = ps8818_i2c_field_update8(port,
+ rv = ps8818_i2c_field_update8(me,
PS8818_REG_PAGE1,
PS8818_REG1_APTX2EQ_5G_LEVEL,
PS8818_EQ_LEVEL_UP_MASK,
@@ -529,7 +528,7 @@ static int ps8818_tune_mux(int port, mux_state_t mux_state)
/* DP specific config */
if (mux_state & USB_PD_MUX_DP_ENABLED) {
/* Boost the DP gain */
- rv = ps8818_i2c_field_update8(port,
+ rv = ps8818_i2c_field_update8(me,
PS8818_REG_PAGE1,
PS8818_REG1_DPEQ_LEVEL,
PS8818_DPEQ_LEVEL_UP_MASK,
@@ -548,47 +547,15 @@ static int ps8818_tune_mux(int port, mux_state_t mux_state)
}
/*
- * 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
- */
-static int zork_c1_retimer_set_mux(int port, mux_state_t mux_state)
-{
- return amd_fp5_usb_retimer.set(port,
- mux_state & ~USB_PD_MUX_POLARITY_INVERTED);
-}
-
-const struct usb_retimer_driver zork_c1_usb_retimer = {
- /* Secondary MUX/Retimer only needs the set mux interface */
- .set = zork_c1_retimer_set_mux,
-};
-
-struct usb_retimer usb_retimers[] = {
- [USBC_PORT_C0] = {
- .driver = &pi3dpx1207_usb_retimer,
- .i2c_port = I2C_PORT_TCPC0,
- .i2c_addr_flags = PI3DPX1207_I2C_ADDR_FLAGS,
- },
- [USBC_PORT_C1] = {
- /*
- * The driver is left off until we detect the
- * hardware present. Once the hardware has been
- * detected, the driver will be set to the
- * detected hardware driver table.
- */
- .i2c_port = I2C_PORT_TCPC1,
- },
-};
-BUILD_ASSERT(ARRAY_SIZE(usb_retimers) == USBC_PORT_COUNT);
-
-/*
* To support both OPT1 DB with PS8818 retimer, and OPT3 DB with PS8802
* retimer, Try both, and remember the first one that succeeds.
- *
- * TODO(b:147593660) Cleanup of retimers as muxes in a more
- * generalized mechanism
*/
+const struct usb_mux usbc1_ps8802;
+const struct usb_mux usbc1_ps8818;
+struct usb_mux usbc1_amd_fp5_usb_mux;
+
enum zork_c1_retimer zork_c1_retimer = C1_RETIMER_UNKNOWN;
-static int zork_c1_detect(int port, int err_if_power_off)
+static int zork_c1_detect(const struct usb_mux *me, int err_if_power_off)
{
int rv;
@@ -604,29 +571,30 @@ static int zork_c1_detect(int port, int err_if_power_off)
* Identifying a PS8818 is faster than the PS8802,
* so do it first.
*/
- usb_retimers[port].i2c_addr_flags = PS8818_I2C_ADDR_FLAGS;
- rv = ps8818_detect(port);
+ rv = ps8818_detect(&usbc1_ps8818);
if (rv == EC_SUCCESS) {
zork_c1_retimer = C1_RETIMER_PS8818;
ccprints("C1 PS8818 detected");
/* 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;
+ memcpy(&usb_muxes[USBC_PORT_C1],
+ &usbc1_amd_fp5_usb_mux,
+ sizeof(struct usb_mux));
+ usb_muxes[USBC_PORT_C1].next_mux = &usbc1_ps8818;
return rv;
}
- usb_retimers[port].i2c_addr_flags = PS8802_I2C_ADDR_FLAGS;
- rv = ps8802_detect(port);
+ rv = ps8802_detect(&usbc1_ps8802);
if (rv == EC_SUCCESS) {
zork_c1_retimer = C1_RETIMER_PS8802;
ccprints("C1 PS8802 detected");
/* Main MUX is PS8802, secondary MUX is modified FP5 */
- usb_muxes[USBC_PORT_C1].driver = &ps8802_usb_mux_driver;
- usb_retimers[USBC_PORT_C1].driver = &zork_c1_usb_retimer;
- usb_retimers[USBC_PORT_C1].tune = &ps8802_tune_mux;
+ memcpy(&usb_muxes[USBC_PORT_C1],
+ &usbc1_ps8802,
+ sizeof(struct usb_mux));
+ usb_muxes[USBC_PORT_C1].next_mux = &usbc1_amd_fp5_usb_mux;
+ usbc1_amd_fp5_usb_mux.flags = USB_MUX_FLAG_SET_WITHOUT_FLIP;
}
return rv;
@@ -637,14 +605,36 @@ static int zork_c1_detect(int port, int err_if_power_off)
* the interface to be this special primary MUX driver in order to
* determine the actual hardware and then we patch the jump tables
* to go to the actual drivers instead.
+ *
+ * "me" will always point to usb_muxes[0]. If detection is made
+ * on the real device, then detect will change the tables so the
+ * content of me is the real driver configuration and will setup
+ * next_mux appropriately. So all we have to do on detection is
+ * perform the actual call for this entry and then let the generic
+ * chain traverse mechanism in usb_mux.c do any following calls.
*/
-static int zork_c1_init_mux(int port)
+static int zork_c1_init_mux(const struct usb_mux *me)
{
+ int rv;
+
/* Try to detect, but don't give an error if no power */
- return zork_c1_detect(port, 0);
+ rv = zork_c1_detect(me, 0);
+ if (rv)
+ return rv;
+
+ /*
+ * If we detected the hardware, then call the real routine.
+ * We only do this one time, after that time we will go direct
+ * and avoid this special driver.
+ */
+ if (zork_c1_retimer != C1_RETIMER_UNKNOWN)
+ if (me->driver && me->driver->init)
+ rv = me->driver->init(me);
+
+ return rv;
}
-static int zork_c1_set_mux(int port, mux_state_t mux_state)
+static int zork_c1_set_mux(const struct usb_mux *me, mux_state_t mux_state)
{
int rv;
@@ -652,7 +642,7 @@ static int zork_c1_set_mux(int port, mux_state_t mux_state)
* Try to detect, give an error if we are setting to a
* MUX value that is not NONE when we have no power.
*/
- rv = zork_c1_detect(port, mux_state != USB_PD_MUX_NONE);
+ rv = zork_c1_detect(me, mux_state != USB_PD_MUX_NONE);
if (rv)
return rv;
@@ -661,18 +651,35 @@ static int zork_c1_set_mux(int port, mux_state_t mux_state)
* We only do this one time, after that time we will go direct
* and avoid this special driver.
*/
- if (zork_c1_retimer != C1_RETIMER_UNKNOWN)
- rv = usb_muxes[port].driver->set(port, mux_state);
+ if (zork_c1_retimer != C1_RETIMER_UNKNOWN) {
+ const struct usb_mux_driver *drv = me->driver;
+
+ if (drv && drv->set) {
+ mux_state_t state = mux_state;
+
+ if (me->flags & USB_MUX_FLAG_SET_WITHOUT_FLIP)
+ state &= ~USB_PD_MUX_POLARITY_INVERTED;
+
+ /* Apply Driver generic settings */
+ rv = drv->set(me, state);
+ if (rv)
+ return rv;
+
+ /* Apply Board specific settings */
+ if (me->board_set)
+ rv = me->board_set(me, state);
+ }
+ }
return rv;
}
-static int zork_c1_get_mux(int port, mux_state_t *mux_state)
+static int zork_c1_get_mux(const struct usb_mux *me, mux_state_t *mux_state)
{
int rv;
/* Try to detect the hardware */
- rv = zork_c1_detect(port, 1);
+ rv = zork_c1_detect(me, 1);
if (rv) {
/*
* Not powered is MUX_NONE, so change the values
@@ -691,7 +698,8 @@ static int zork_c1_get_mux(int port, mux_state_t *mux_state)
* and avoid this special driver.
*/
if (zork_c1_retimer != C1_RETIMER_UNKNOWN)
- rv = usb_muxes[port].driver->get(port, mux_state);
+ if (me->driver && me->driver->get)
+ rv = me->driver->get(me, mux_state);
return rv;
}
@@ -714,9 +722,37 @@ const struct usb_mux_driver zork_c1_usb_mux_driver = {
.get = zork_c1_get_mux,
};
+const struct usb_mux usbc0_pi3dpx1207_usb_retimer = {
+ .usb_port = USBC_PORT_C0,
+ .i2c_port = I2C_PORT_TCPC0,
+ .i2c_addr_flags = PI3DPX1207_I2C_ADDR_FLAGS,
+ .driver = &pi3dpx1207_usb_retimer,
+};
+
+const struct usb_mux usbc1_ps8802 = {
+ .usb_port = USBC_PORT_C1,
+ .i2c_port = I2C_PORT_TCPC1,
+ .i2c_addr_flags = PS8802_I2C_ADDR_FLAGS,
+ .driver = &ps8802_usb_mux_driver,
+ .board_set = &ps8802_mux_set,
+};
+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 = &ps8818_mux_set,
+};
+struct usb_mux usbc1_amd_fp5_usb_mux = {
+ .usb_port = USBC_PORT_C1,
+ .driver = &amd_fp5_usb_mux_driver,
+};
+
struct usb_mux usb_muxes[] = {
[USBC_PORT_C0] = {
+ .usb_port = USBC_PORT_C0,
.driver = &amd_fp5_usb_mux_driver,
+ .next_mux = &usbc0_pi3dpx1207_usb_retimer,
},
[USBC_PORT_C1] = {
/*
@@ -724,11 +760,14 @@ struct usb_mux usb_muxes[] = {
* has been detected, the driver will change to the
* detected hardware driver table.
*/
+ .usb_port = USBC_PORT_C1,
+ .i2c_port = I2C_PORT_TCPC1,
.driver = &zork_c1_usb_mux_driver,
- },
+ }
};
BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == USBC_PORT_COUNT);
+
struct ioexpander_config_t ioex_config[] = {
[USBC_PORT_C0] = {
.i2c_host_port = I2C_PORT_TCPC0,
diff --git a/baseboard/zork/baseboard.h b/baseboard/zork/baseboard.h
index 61719b012c..b51f42b683 100644
--- a/baseboard/zork/baseboard.h
+++ b/baseboard/zork/baseboard.h
@@ -133,6 +133,7 @@
#define CONFIG_CMD_PD_CONTROL
#define CONFIG_USB_CHARGER
+#define CONFIG_USB_MUX_RUNTIME_CONFIG
#define CONFIG_USB_POWER_DELIVERY
#define CONFIG_USB_PD_ALT_MODE
#define CONFIG_USB_PD_ALT_MODE_DFP
@@ -147,7 +148,6 @@
#define CONFIG_USB_PD_TCPC_LOW_POWER
#define CONFIG_USB_PD_TCPM_MUX
#define CONFIG_USB_PD_TCPM_NCT38XX
-#define CONFIG_USB_PD_TCPM_PS8751
#define CONFIG_USB_PD_TCPM_TCPCI
#define CONFIG_USB_PD_TRY_SRC
#define CONFIG_USB_PD_VBUS_DETECT_TCPC
diff --git a/baseboard/zork/usb_pd_policy.c b/baseboard/zork/usb_pd_policy.c
index 66433f9ac0..26cc885479 100644
--- a/baseboard/zork/usb_pd_policy.c
+++ b/baseboard/zork/usb_pd_policy.c
@@ -136,8 +136,6 @@ __override int svdm_dp_config(int port, uint32_t *payload)
__override void svdm_dp_post_config(int port)
{
- const struct usb_mux * const mux = &usb_muxes[port];
-
/* Connect the SBU and USB lines to the connector. */
ppc_set_sbu(port, 1);
usb_mux_set(port, svdm_dp_mux_mode(port), USB_SWITCH_CONNECT,
@@ -152,14 +150,11 @@ __override void svdm_dp_post_config(int port)
/* set the minimum time delay (2ms) for the next HPD IRQ */
svdm_hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL;
- if (mux->hpd_update)
- mux->hpd_update(port, 1, 0);
+ usb_mux_hpd_update(port, 1, 0);
}
__override void svdm_exit_dp_mode(int port)
{
- const struct usb_mux * const mux = &usb_muxes[port];
-
dp_flags[port] = 0;
dp_status[port] = 0;
@@ -167,7 +162,6 @@ __override void svdm_exit_dp_mode(int port)
pd_get_polarity(port));
gpio_set_level(PORT_TO_HPD(port), 0);
- if (mux->hpd_update)
- mux->hpd_update(port, 0, 0);
+ usb_mux_hpd_update(port, 0, 0);
}
#endif /* CONFIG_USB_PD_ALT_MODE_DFP */