summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Michalec <tm@semihalf.com>2022-07-05 16:12:16 +0200
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-09-13 11:19:02 +0000
commita062b533a068069af8fdea3ea394e99703d7561a (patch)
tree91c38ee93ab9ac28a49bb1e381c247d29d82e9d8
parent16165094ab108ff584b4d3b381884427c859edac (diff)
downloadchrome-ec-a062b533a068069af8fdea3ea394e99703d7561a.tar.gz
zephyr: Support alternative usb_mux_chain config in DTS
Add support for alternative usb_mux configuration from the devicetree. Alternate USB mux chain is created by adding "cros-ec,usb-mux-chain" in DTS with alternative-chain property. To enable alternate configuration, USB_MUX_ENABLE_ALTERNATE_NODE macro has to be used at runtime. BUG=b:234482311 TEST=zmake build -a TEST=./twister -T zephyr/test BRANCH=none Signed-off-by: Tomasz Michalec <tm@semihalf.com> Change-Id: I0ae8889b225800d8741f01f8ea70c5f4f5547065 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3700330 Reviewed-by: Keith Short <keithshort@chromium.org> Tested-by: Tomasz Michalec <tmichalec@google.com> Commit-Queue: Tomasz Michalec <tmichalec@google.com>
-rw-r--r--zephyr/dts/bindings/usbc/cros-ec,usb-mux-chain.yaml19
-rw-r--r--zephyr/shim/include/usbc/usb_muxes.h64
-rw-r--r--zephyr/shim/src/usb_muxes.c16
3 files changed, 91 insertions, 8 deletions
diff --git a/zephyr/dts/bindings/usbc/cros-ec,usb-mux-chain.yaml b/zephyr/dts/bindings/usbc/cros-ec,usb-mux-chain.yaml
index b0af5f6ce2..398d7255ac 100644
--- a/zephyr/dts/bindings/usbc/cros-ec,usb-mux-chain.yaml
+++ b/zephyr/dts/bindings/usbc/cros-ec,usb-mux-chain.yaml
@@ -17,8 +17,16 @@ properties:
adding the "cros-ec,usb-mux-chain" as a child of the "named-usbc-port"
node.
-# Example DTS defining USB-C port 0 with usb mux chain. The chain has two muxes:
-# BB retimer and virtual mux.
+ alternative-chain:
+ type: boolean
+ description: |
+ Set if this is alternative USB-C muxes chain. It can be selected in
+ runtime using USB_MUX_ENABLE_ALTERNATIVE macro.
+
+# Example DTS defining USB-C port 0 with main and alternative usb mux chains.
+# The main chain has two muxes: BB retimer and virtual mux.
+# The alternative chain has three muxes: BB retimer, SOC side BB retimer and
+# virtual mux.
#
# usbc_port0: port0@0 {
# compatible = "named-usbc-port";
@@ -29,4 +37,11 @@ properties:
# usb-muxes = <&usb_c0_bb_retimer
# &virtual_mux_c0>;
# };
+# usb-mux-chain-0 {
+# compatible = "cros-ec,usb-mux-chain";
+# alternative-chain;
+# usb-muxes = <&usb_c0_bb_retimer
+# &usb_c0_soc_side_bb_retimer
+# &virtual_mux_c0>;
+# };
# };
diff --git a/zephyr/shim/include/usbc/usb_muxes.h b/zephyr/shim/include/usbc/usb_muxes.h
index 21f720517c..9dce1a3aa5 100644
--- a/zephyr/shim/include/usbc/usb_muxes.h
+++ b/zephyr/shim/include/usbc/usb_muxes.h
@@ -309,6 +309,25 @@
}
/**
+ * @brief Helper macro to set chain structure value for @p idx mux
+ *
+ * @param chain_id Chain DTS node ID
+ * @param idx USB mux index
+ */
+#define USB_MUX_CHAIN_STRUCT_SET(chain_id, idx) \
+ (struct usb_mux_chain) USB_MUX_CHAIN_STRUCT_INIT(chain_id, idx)
+
+/**
+ * @brief Declaration of USB mux chain extern structure for @p idx mux in
+ * @p chain_id chain
+ *
+ * @param chain_id USB mux chain node ID
+ * @param idx Place in chain
+ */
+#define USB_MUX_CHAIN_STRUCT_DECLARE_EXTERN_OP(chain_id, idx) \
+ extern USB_MUX_CHAIN_STRUCT_DECLARE(USBC_PORT(chain_id), idx);
+
+/**
* @brief Declaration of USB mux chain structure for @p idx mux in @p chain_id
* chain
*
@@ -316,7 +335,7 @@
* @param idx Place in chain
*/
#define USB_MUX_CHAIN_STRUCT_DECLARE_OP(chain_id, idx) \
- extern USB_MUX_CHAIN_STRUCT_DECLARE(USBC_PORT(chain_id), idx);
+ USB_MUX_CHAIN_STRUCT_DECLARE(USBC_PORT(chain_id), idx);
/**
* @brief Definition of USB mux chain structure for @p idx mux in @p chain_id
@@ -358,6 +377,17 @@
[USBC_PORT(chain_id)] = USB_MUX_CHAIN_STRUCT_INIT(chain_id, 0),
/**
+ * @brief Call @p op only if chain @p chain_id is not alternative
+ *
+ * @param chain_id Chain DTS node ID
+ * @param op Operation to perform on main USB mux chain
+ * @param ... Arguments to pass to the @p op operation
+ */
+#define USB_MUX_FOR_MAIN_CHAIN(chain_id, op, ...) \
+ COND_CODE_0(DT_PROP(chain_id, alternative_chain), \
+ (op(chain_id, ##__VA_ARGS__)), ())
+
+/**
* @brief Call @p op for each USB mux chain
*
* @param op Operation to perform on USB mux chain
@@ -423,6 +453,36 @@
(USB_MUX_FOREACH_CHAIN_VARGS(USB_MUX_FIND_PORT, mux_id)(-1))
/**
+ * @brief Set usb_mux_chain structure for mux @p idx in chain @p chain_id
+ *
+ * @param chain_id Alternative USB mux chain node ID
+ * @param idx Position of the mux in chain
+ */
+#define USB_MUX_SET_ALTERNATIVE(chain_id, idx) \
+ USB_MUX_CHAIN_STRUCT_NAME(idx, USBC_PORT(chain_id)) = \
+ USB_MUX_CHAIN_STRUCT_SET(chain_id, idx);
+
+/**
+ * @brief Enable alternative USB mux chain
+ *
+ * @param chain_id Alternative USB mux chain node ID
+ */
+#define USB_MUX_ENABLE_ALTERNATIVE_NODE(chain_id) \
+ do { \
+ usb_muxes[USBC_PORT(chain_id)] = \
+ USB_MUX_CHAIN_STRUCT_SET(chain_id, 0); \
+ USB_MUX_FOREACH_NO_ROOT_MUX(chain_id, USB_MUX_SET_ALTERNATIVE) \
+ } while (0)
+
+/**
+ * @brief Enable alternative USB mux chain
+ *
+ * @param nodelabel Label of alternative USB mux chain
+ */
+#define USB_MUX_ENABLE_ALTERNATIVE(nodelabel) \
+ USB_MUX_ENABLE_ALTERNATIVE_NODE(DT_NODELABEL(nodelabel))
+
+/**
* Forward declare all usb_mux structures e.g.
* MAYBE_CONST struct usb_mux USB_MUX_NODE_<node_id>;
*/
@@ -434,6 +494,6 @@ USB_MUX_FOREACH_MUX(USB_MUX_DECLARE)
* USB_MUX_chain_port_<node_id>_mux_<position_id>;
*/
USB_MUX_FOREACH_CHAIN_VARGS(USB_MUX_FOREACH_NO_ROOT_MUX,
- USB_MUX_CHAIN_STRUCT_DECLARE_OP)
+ USB_MUX_CHAIN_STRUCT_DECLARE_EXTERN_OP)
#endif /* ZEPHYR_CHROME_USBC_USB_MUXES_H */
diff --git a/zephyr/shim/src/usb_muxes.c b/zephyr/shim/src/usb_muxes.c
index e85a095db0..d9f14d0c67 100644
--- a/zephyr/shim/src/usb_muxes.c
+++ b/zephyr/shim/src/usb_muxes.c
@@ -43,7 +43,15 @@
USB_MUX_FOREACH_MUX(USB_MUX_CHECK_ALL_PORTS_ARE_SAME)
/**
- * Define usb_mux_chain structures e.g.
+ * Declare all usb_mux_chain structures e.g.
+ * MAYBE_CONST struct usb_mux_chain
+ * USB_MUX_chain_port_<port_id>_mux_<position_id>;
+ */
+USB_MUX_FOREACH_CHAIN_VARGS(USB_MUX_FOREACH_NO_ROOT_MUX,
+ USB_MUX_CHAIN_STRUCT_DECLARE_OP)
+
+/**
+ * Define usb_mux_chain structures for main chain e.g.
*
* MAYBE_CONST struct usb_mux_chain
* USB_MUX_chain_port_<port_id>_mux_<position_id> = {
@@ -51,7 +59,7 @@ USB_MUX_FOREACH_MUX(USB_MUX_CHECK_ALL_PORTS_ARE_SAME)
* .next = &USB_MUX_chain_port_0_mux_1,
* }
*/
-USB_MUX_FOREACH_CHAIN_VARGS(USB_MUX_FOREACH_NO_ROOT_MUX,
+USB_MUX_FOREACH_CHAIN_VARGS(USB_MUX_FOR_MAIN_CHAIN, USB_MUX_FOREACH_NO_ROOT_MUX,
USB_MUX_CHAIN_STRUCT_DEFINE_OP)
/**
@@ -70,8 +78,8 @@ USB_MUX_FOREACH_MUX(USB_MUX_CB_BOARD_SET_DECLARE_IF_EXISTS)
* },
* [1] = { ... },
*/
-MAYBE_CONST struct usb_mux_chain usb_muxes[] = { USB_MUX_FOREACH_CHAIN(
- USB_MUX_DEFINE_ROOT_MUX) };
+MAYBE_CONST struct usb_mux_chain usb_muxes[] = { USB_MUX_FOREACH_CHAIN_VARGS(
+ USB_MUX_FOR_MAIN_CHAIN, USB_MUX_DEFINE_ROOT_MUX) };
BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == CONFIG_USB_PD_PORT_MAX_COUNT);
/**