From 097913735beba1c64f73e601a769f404236ecb4e Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 23 May 2022 15:56:08 +0000 Subject: zephyr: shim: add single charge task support Add an option to run the charger code in a single task. This is enabled by default in Zephyr builds, but explicitly disabled for a couple of platforms that currently have task dependent board code. Should be enough to start testing the configuration, will work on handling the remaining boards (corsola and nissa) later. BRANCH=none BUG=b:226411332 TEST=make buildall TEST=zmake testall TEST=cq dry run TEST=run on Brya, connect/disconnect usb devices Signed-off-by: Fabio Baltieri Change-Id: I75a63f7b0a9545e6c824114de7f81b71924e0789 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3663748 Reviewed-by: Keith Short Reviewed-by: Diana Z Reviewed-by: Aaron Massey --- common/usb_charger.c | 73 ++++++++++++++++++++++++++++++++++- include/charge_manager.h | 3 +- include/usb_charge.h | 26 +++++++++---- zephyr/Kconfig.usb_charger | 6 +++ zephyr/app/ec/Kconfig | 2 +- zephyr/projects/corsola/prj.conf | 2 + zephyr/projects/nissa/prj.conf | 2 + zephyr/shim/include/config_chip.h | 2 + zephyr/shim/include/shimmed_task_id.h | 5 +++ 9 files changed, 109 insertions(+), 12 deletions(-) diff --git a/common/usb_charger.c b/common/usb_charger.c index 5387dba594..d0b6dd3ca1 100644 --- a/common/usb_charger.c +++ b/common/usb_charger.c @@ -26,6 +26,26 @@ #include "usbc_ppc.h" #include "util.h" +#ifdef CONFIG_PLATFORM_EC_USB_CHARGER_SINGLE_TASK + +/* Hold the event bits for all ports, 1 byte per port. */ +static atomic_t usb_charger_port_events; + +/* Convert event bits for port so it can be stored in a 32 bit value. */ +#define PORT_EVENT_PACK(port, event) ((event & 0xff) << (8 * port)) + +/* Extract the event bits for port from a 32 bit value. */ +#define PORT_EVENT_UNPACK(port, event_packed) \ + ((event_packed >> (8 * port)) & 0xff) + +/* Ensure port event bits are valid. */ +BUILD_ASSERT(BIT(0) == TASK_EVENT_CUSTOM_BIT(0)); +BUILD_ASSERT(BIT(1) == TASK_EVENT_CUSTOM_BIT(1)); +BUILD_ASSERT(BIT(2) == TASK_EVENT_CUSTOM_BIT(2)); +BUILD_ASSERT(BIT(3) == TASK_EVENT_CUSTOM_BIT(3)); + +#endif /* CONFIG_PLATFORM_EC_USB_CHARGER_SINGLE_TASK */ + static void update_vbus_supplier(int port, int vbus_level) { struct charge_port_info charge = {0}; @@ -73,7 +93,8 @@ void usb_charger_vbus_change(int port, int vbus_level) /* Update VBUS supplier and signal VBUS change to USB_CHG task */ update_vbus_supplier(port, vbus_level); -#ifdef HAS_TASK_USB_CHG_P0 +#if defined(HAS_TASK_USB_CHG_P0) || \ + defined(CONFIG_PLATFORM_EC_USB_CHARGER_SINGLE_TASK) /* USB Charger task(s) */ usb_charger_task_set_event(port, USB_CHG_EVENT_VBUS); @@ -116,9 +137,14 @@ void usb_charger_reset_charge(int port) } -void usb_charger_task_set_event(int port, uint32_t event) +void usb_charger_task_set_event(int port, uint8_t event) { +#ifdef CONFIG_PLATFORM_EC_USB_CHARGER_SINGLE_TASK + atomic_or(&usb_charger_port_events, PORT_EVENT_PACK(port, event)); + task_set_event(TASK_ID_USB_CHG, BIT(port)); +#else task_set_event(USB_CHG_PORT_TO_TASK_ID(port), event); +#endif } static void usb_charger_init(void) @@ -132,6 +158,47 @@ static void usb_charger_init(void) } DECLARE_HOOK(HOOK_INIT, usb_charger_init, HOOK_PRIO_POST_CHARGE_MANAGER); +#ifdef CONFIG_PLATFORM_EC_USB_CHARGER_SINGLE_TASK + +void usb_charger_task_shared(void *u) +{ + int port; + uint32_t evt; + uint32_t port_evt; + struct bc12_config *bc12_port; + + for (port = 0; port < board_get_usb_pd_port_count(); port++) { + bc12_port = &bc12_ports[port]; + + ASSERT(bc12_port->drv->usb_charger_task_init); + ASSERT(bc12_port->drv->usb_charger_task_event); + + bc12_port->drv->usb_charger_task_init(port); + } + + while (1) { + evt = task_wait_event(-1); + + for (port = 0; port < board_get_usb_pd_port_count(); port++) { + if (!(evt & BIT(port))) { + continue; + } + + port_evt = PORT_EVENT_UNPACK( + port, + atomic_get(&usb_charger_port_events)); + atomic_and(&usb_charger_port_events, + ~PORT_EVENT_PACK(port, port_evt)); + + bc12_port = &bc12_ports[port]; + + bc12_port->drv->usb_charger_task_event(port, port_evt); + } + } +} + +#else /* CONFIG_PLATFORM_EC_USB_CHARGER_SINGLE_TASK */ + void usb_charger_task(void *u) { int port = TASK_ID_TO_USB_CHG_PORT(task_get_current()); @@ -157,3 +224,5 @@ void usb_charger_task(void *u) bc12_port->drv->usb_charger_task_event(port, evt); } } + +#endif /* CONFIG_PLATFORM_EC_USB_CHARGER_SINGLE_TASK */ diff --git a/include/charge_manager.h b/include/charge_manager.h index 2cded28295..b6d3c235bf 100644 --- a/include/charge_manager.h +++ b/include/charge_manager.h @@ -19,7 +19,8 @@ /* Only track BC1.2 charge current if we support BC1.2 charging */ #if defined(HAS_TASK_USB_CHG) || defined(HAS_TASK_USB_CHG_P0) || \ -defined(TEST_BUILD) + defined(CONFIG_PLATFORM_EC_USB_CHARGER_SINGLE_TASK) || \ + defined(TEST_BUILD) #define CHARGE_MANAGER_BC12 #endif diff --git a/include/usb_charge.h b/include/usb_charge.h index ec7a655256..135258c7cf 100644 --- a/include/usb_charge.h +++ b/include/usb_charge.h @@ -55,13 +55,23 @@ extern const int usb_port_enable[USB_PORT_ENABLE_COUNT]; int usb_charge_set_mode(int usb_port_id, enum usb_charge_mode mode, enum usb_suspend_charge inhibit_charge); -#define USB_CHG_EVENT_BC12 TASK_EVENT_CUSTOM_BIT(0) -#define USB_CHG_EVENT_VBUS TASK_EVENT_CUSTOM_BIT(1) -#define USB_CHG_EVENT_INTR TASK_EVENT_CUSTOM_BIT(2) -#define USB_CHG_EVENT_DR_UFP TASK_EVENT_CUSTOM_BIT(3) -#define USB_CHG_EVENT_DR_DFP TASK_EVENT_CUSTOM_BIT(4) -#define USB_CHG_EVENT_CC_OPEN TASK_EVENT_CUSTOM_BIT(5) -#define USB_CHG_EVENT_MUX TASK_EVENT_CUSTOM_BIT(6) +#ifdef CONFIG_PLATFORM_EC_USB_CHARGER_SINGLE_TASK +/* + * In single task mode we pack the event bits for up to 4 ports in a 32 bit + * atomic, make sure we don't define more than 8 event bits per port. + */ +#define USB_CHARGER_EVENT_BIT(x) BUILD_CHECK_INLINE(BIT(x), BIT(x) & 0xff) +#else +#define USB_CHARGER_EVENT_BIT(x) TASK_EVENT_CUSTOM_BIT(x) +#endif + +#define USB_CHG_EVENT_BC12 USB_CHARGER_EVENT_BIT(0) +#define USB_CHG_EVENT_VBUS USB_CHARGER_EVENT_BIT(1) +#define USB_CHG_EVENT_INTR USB_CHARGER_EVENT_BIT(2) +#define USB_CHG_EVENT_DR_UFP USB_CHARGER_EVENT_BIT(3) +#define USB_CHG_EVENT_DR_DFP USB_CHARGER_EVENT_BIT(4) +#define USB_CHG_EVENT_CC_OPEN USB_CHARGER_EVENT_BIT(5) +#define USB_CHG_EVENT_MUX USB_CHARGER_EVENT_BIT(6) /* * Define USB_CHG_PORT_TO_TASK_ID() and TASK_ID_TO_USB_CHG_PORT() macros to @@ -174,7 +184,7 @@ static inline int usb_charger_ramp_max(int port, int supplier, int sup_curr) * @param port port number * @param event event bits (USB_CHG_EVENT_*) */ -void usb_charger_task_set_event(int port, uint32_t event); +void usb_charger_task_set_event(int port, uint8_t event); /** * Reset available BC 1.2 chargers on all ports diff --git a/zephyr/Kconfig.usb_charger b/zephyr/Kconfig.usb_charger index 1510e981d1..dd167dddae 100644 --- a/zephyr/Kconfig.usb_charger +++ b/zephyr/Kconfig.usb_charger @@ -15,6 +15,12 @@ config PLATFORM_EC_USB_CHARGER if PLATFORM_EC_USB_CHARGER +config PLATFORM_EC_USB_CHARGER_SINGLE_TASK + bool "Run all charger code in a single task" + default y + help + Run all USB charger code in a single task rather than a task per port. + config PLATFORM_EC_BC12_DETECT_DATA_ROLE_TRIGGER bool help diff --git a/zephyr/app/ec/Kconfig b/zephyr/app/ec/Kconfig index b8d46f8678..ebdeebfdf2 100644 --- a/zephyr/app/ec/Kconfig +++ b/zephyr/app/ec/Kconfig @@ -24,7 +24,7 @@ orsource "chip/$(ARCH)/*/Kconfig.*" # Override the maximum number of preemptive priority levels. # config NUM_PREEMPT_PRIORITIES - default 25 + default 26 # # In Zephyr, the default system workqueue thread priority level is the lowest diff --git a/zephyr/projects/corsola/prj.conf b/zephyr/projects/corsola/prj.conf index 2b087fa310..b9d07a7227 100644 --- a/zephyr/projects/corsola/prj.conf +++ b/zephyr/projects/corsola/prj.conf @@ -26,6 +26,8 @@ CONFIG_PLATFORM_EC_VBOOT_EFS2=y # USB CONFIG_PLATFORM_EC_USB_PD_TBT_COMPAT_MODE=n CONFIG_PLATFORM_EC_USB_PD_USB4=n +# TODO(b/226411332): fix single task USB_CHG for Corsola +CONFIG_PLATFORM_EC_USB_CHARGER_SINGLE_TASK=n # Power Seq CONFIG_PLATFORM_EC_POWERSEQ_HOST_SLEEP=y diff --git a/zephyr/projects/nissa/prj.conf b/zephyr/projects/nissa/prj.conf index 828fccd8be..621355bf6a 100644 --- a/zephyr/projects/nissa/prj.conf +++ b/zephyr/projects/nissa/prj.conf @@ -122,6 +122,8 @@ CONFIG_PLATFORM_EC_USB_MUX_VIRTUAL=y # ADL integrated muxes are slow: unblock PD CONFIG_PLATFORM_EC_USB_MUX_TASK=y CONFIG_PLATFORM_EC_BC12_DETECT_PI3USB9201=y +# TODO(b/226411332): fix single task USB_CHG for Nissa +CONFIG_PLATFORM_EC_USB_CHARGER_SINGLE_TASK=n # USB-C TCPC and PPC standard options CONFIG_PLATFORM_EC_USB_PD_TCPC_LOW_POWER=y diff --git a/zephyr/shim/include/config_chip.h b/zephyr/shim/include/config_chip.h index a811b68ccc..d3924e644d 100644 --- a/zephyr/shim/include/config_chip.h +++ b/zephyr/shim/include/config_chip.h @@ -1447,6 +1447,7 @@ extern struct jump_data mock_jump_data; #endif /* CONFIG_PLATFORM_EC_USB_POWER_DELIVERY */ #ifdef CONFIG_PLATFORM_EC_USB_CHARGER +#ifndef CONFIG_PLATFORM_EC_USB_CHARGER_SINGLE_TASK #define HAS_TASK_USB_CHG_P0 1 #if CONFIG_USB_PD_PORT_MAX_COUNT > 1 @@ -1461,6 +1462,7 @@ extern struct jump_data mock_jump_data; #define HAS_TASK_USB_CHG_P3 1 #endif /* CONFIG_USB_PD_PORT_MAX_COUNT > 3 */ +#endif /* !PLATFORM_EC_USB_CHARGER_SINGLE_TASK */ #endif /* CONFIG_PLATFORM_EC_USB_CHARGER */ #undef CONFIG_USB_PD_ITE_ACTIVE_PORT_COUNT diff --git a/zephyr/shim/include/shimmed_task_id.h b/zephyr/shim/include/shimmed_task_id.h index 88298a401a..31df4daece 100644 --- a/zephyr/shim/include/shimmed_task_id.h +++ b/zephyr/shim/include/shimmed_task_id.h @@ -28,6 +28,7 @@ enum { EC_TASK_PRIO_LOWEST = 0, EC_SYSWORKQ_PRIO = EC_TASK_PRIO_LOWEST, EC_TASK_CHG_RAMP_PRIO, + EC_TASK_USB_CHG_PRIO, EC_TASK_USB_CHG_P0_PRIO, EC_TASK_USB_CHG_P1_PRIO, EC_TASK_USB_CHG_P2_PRIO, @@ -68,6 +69,10 @@ enum { (CROS_EC_TASK(CHG_RAMP, chg_ramp_task, 0, \ CONFIG_TASK_CHG_RAMP_STACK_SIZE, \ EC_TASK_CHG_RAMP_PRIO)), ()) \ + COND_CODE_1(CONFIG_PLATFORM_EC_USB_CHARGER_SINGLE_TASK, \ + (CROS_EC_TASK(USB_CHG, usb_charger_task_shared, 0, \ + CONFIG_TASK_USB_CHG_STACK_SIZE, \ + EC_TASK_USB_CHG_PRIO)), ()) \ COND_CODE_1(HAS_TASK_USB_CHG_P0, \ (CROS_EC_TASK(USB_CHG_P0, usb_charger_task, 0, \ CONFIG_TASK_USB_CHG_STACK_SIZE, \ -- cgit v1.2.1