diff options
Diffstat (limited to 'zephyr/shim')
30 files changed, 492 insertions, 80 deletions
diff --git a/zephyr/shim/chip/CMakeLists.txt b/zephyr/shim/chip/CMakeLists.txt index 1d58857c11..0236570ddd 100644 --- a/zephyr/shim/chip/CMakeLists.txt +++ b/zephyr/shim/chip/CMakeLists.txt @@ -8,5 +8,7 @@ elseif (DEFINED CONFIG_SOC_FAMILY_RISCV_ITE) add_subdirectory(it8xxx2) elseif (DEFINED CONFIG_SOC_FAMILY_MEC) add_subdirectory(mchp) +elseif (DEFINED CONFIG_SOC_FAMILY_STM32) + add_subdirectory(stm32) endif() diff --git a/zephyr/shim/chip/it8xxx2/gpio.c b/zephyr/shim/chip/it8xxx2/gpio.c index 16eb7a3963..78aa504140 100644 --- a/zephyr/shim/chip/it8xxx2/gpio.c +++ b/zephyr/shim/chip/it8xxx2/gpio.c @@ -4,6 +4,9 @@ */ #include "gpio/gpio.h" +#include "gpio_it8xxx2.h" + +#include <errno.h> #include <zephyr/device.h> #include <zephyr/drivers/gpio.h> @@ -52,3 +55,72 @@ int gpio_config_unused_pins(void) return 0; } + +int gpio_configure_port_pin(int port, int id, int flags) +{ + const struct device *dev; + + /* + * Port number mapping to node + * 0 gpioa + * ... ... + * 50 gpioksi + * 51 gpioksoh + * 52 gpioksol + */ + switch ((enum gpio_port_to_node)port) { + case GPIO_A: + dev = DEVICE_DT_GET(DT_NODELABEL(gpioa)); + break; + case GPIO_B: + dev = DEVICE_DT_GET(DT_NODELABEL(gpiob)); + break; + case GPIO_C: + dev = DEVICE_DT_GET(DT_NODELABEL(gpioc)); + break; + case GPIO_D: + dev = DEVICE_DT_GET(DT_NODELABEL(gpiod)); + break; + case GPIO_E: + dev = DEVICE_DT_GET(DT_NODELABEL(gpioe)); + break; + case GPIO_F: + dev = DEVICE_DT_GET(DT_NODELABEL(gpiof)); + break; + case GPIO_G: + dev = DEVICE_DT_GET(DT_NODELABEL(gpiog)); + break; + case GPIO_H: + dev = DEVICE_DT_GET(DT_NODELABEL(gpioh)); + break; + case GPIO_I: + dev = DEVICE_DT_GET(DT_NODELABEL(gpioi)); + break; + case GPIO_J: + dev = DEVICE_DT_GET(DT_NODELABEL(gpioj)); + break; + case GPIO_K: + dev = DEVICE_DT_GET(DT_NODELABEL(gpiok)); + break; + case GPIO_L: + dev = DEVICE_DT_GET(DT_NODELABEL(gpiol)); + break; + case GPIO_M: + dev = DEVICE_DT_GET(DT_NODELABEL(gpiom)); + break; + case GPIO_KSI: + dev = DEVICE_DT_GET(DT_NODELABEL(gpioksi)); + break; + case GPIO_KSOH: + dev = DEVICE_DT_GET(DT_NODELABEL(gpioksoh)); + break; + case GPIO_KSOL: + dev = DEVICE_DT_GET(DT_NODELABEL(gpioksol)); + break; + default: + printk("Error port number %d\n", port); + return -EINVAL; + } + + return gpio_pin_configure(dev, id, flags); +} diff --git a/zephyr/shim/chip/it8xxx2/include/gpio_it8xxx2.h b/zephyr/shim/chip/it8xxx2/include/gpio_it8xxx2.h new file mode 100644 index 0000000000..7abf9f560a --- /dev/null +++ b/zephyr/shim/chip/it8xxx2/include/gpio_it8xxx2.h @@ -0,0 +1,28 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_EC_GPIO_IT8XXX2_H +#define __CROS_EC_GPIO_IT8XXX2_H + +enum gpio_port_to_node { + GPIO_A, + GPIO_B, + GPIO_C, + GPIO_D, + GPIO_E, + GPIO_F, + GPIO_G, + GPIO_H, + GPIO_I, + GPIO_J, + GPIO_K, + GPIO_L, + GPIO_M, + GPIO_KSI = 50, + GPIO_KSOH = 51, + GPIO_KSOL = 52 +}; + +#endif /* __CROS_EC_GPIO_IT8XXX2_H */ diff --git a/zephyr/shim/chip/it8xxx2/keyboard_raw.c b/zephyr/shim/chip/it8xxx2/keyboard_raw.c index 5fe99b7efa..442b51a59a 100644 --- a/zephyr/shim/chip/it8xxx2/keyboard_raw.c +++ b/zephyr/shim/chip/it8xxx2/keyboard_raw.c @@ -6,6 +6,7 @@ /* Functions needed by keyboard scanner module for Chrome EC */ #include "drivers/cros_kb_raw.h" +#include "gpio_it8xxx2.h" #include "keyboard_raw.h" #include <zephyr/device.h> @@ -15,13 +16,27 @@ #include <soc.h> /** - * Return true if the current value of the given input GPIO port is zero + * Return true if the current value of the given gpioksi/gpioksoh/gpioksol + * port is zero */ int keyboard_raw_is_input_low(int port, int id) { - /* - * TODO: implement for factory testing KSI and KSO pin as GPIO - * function. - */ - return 0; + const struct device *dev; + + switch ((enum gpio_port_to_node)port) { + case GPIO_KSI: + dev = DEVICE_DT_GET(DT_NODELABEL(gpioksi)); + break; + case GPIO_KSOH: + dev = DEVICE_DT_GET(DT_NODELABEL(gpioksoh)); + break; + case GPIO_KSOL: + dev = DEVICE_DT_GET(DT_NODELABEL(gpioksol)); + break; + default: + printk("Error port number %d, return 0\n", port); + return 0; + } + + return (gpio_pin_get_raw(dev, id) == 0); } diff --git a/zephyr/shim/chip/npcx/shi.c b/zephyr/shim/chip/npcx/shi.c index 0cecc2c56e..4e0535b91f 100644 --- a/zephyr/shim/chip/npcx/shi.c +++ b/zephyr/shim/chip/npcx/shi.c @@ -21,7 +21,7 @@ LOG_MODULE_REGISTER(shim_cros_shi, LOG_LEVEL_DBG); -#define SHI_NODE DT_NODELABEL(shi) +#define SHI_NODE DT_NODELABEL(shi0) static void shi_enable(void) { diff --git a/zephyr/shim/chip/stm32/CMakeLists.txt b/zephyr/shim/chip/stm32/CMakeLists.txt new file mode 100644 index 0000000000..52787ce656 --- /dev/null +++ b/zephyr/shim/chip/stm32/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +cros_ec_library_include_directories(include) diff --git a/zephyr/shim/chip/stm32/include/flash_chip.h b/zephyr/shim/chip/stm32/include/flash_chip.h new file mode 100644 index 0000000000..cd896eca9a --- /dev/null +++ b/zephyr/shim/chip/stm32/include/flash_chip.h @@ -0,0 +1,22 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_EC_FLASH_CHIP_H +#define __CROS_EC_FLASH_CHIP_H + +/* Minimum write size */ +#define CONFIG_FLASH_WRITE_SIZE \ + DT_PROP(DT_INST(0, soc_nv_flash), write_block_size) + +/* No page mode, so use minimum write size */ +#define CONFIG_FLASH_WRITE_IDEAL_SIZE CONFIG_FLASH_WRITE_SIZE + +/* RO image offset inside protected storage (RO part) */ +#define CONFIG_RO_STORAGE_OFF 0x0 + +/* RW image offset inside writable storage (RW part) */ +#define CONFIG_RW_STORAGE_OFF 0x0 + +#endif /* __CROS_EC_FLASH_CHIP_H */ diff --git a/zephyr/shim/include/builtin/assert.h b/zephyr/shim/include/builtin/assert.h index 27dce8f2c4..e5e4a34b21 100644 --- a/zephyr/shim/include/builtin/assert.h +++ b/zephyr/shim/include/builtin/assert.h @@ -13,4 +13,9 @@ #define ASSERT __ASSERT_NO_MSG #define assert __ASSERT_NO_MSG +/* TODO(b/269175417): This should be handled in Zephyr __assert.h */ +#ifndef __ASSERT_UNREACHABLE +#define __ASSERT_UNREACHABLE CODE_UNREACHABLE +#endif + #endif /* __CROS_EC_ASSERT_H */ diff --git a/zephyr/shim/include/config_chip.h b/zephyr/shim/include/config_chip.h index 7ecb3b0f13..fd97a9d72a 100644 --- a/zephyr/shim/include/config_chip.h +++ b/zephyr/shim/include/config_chip.h @@ -718,6 +718,11 @@ extern char mock_jump_data[CONFIG_PLATFORM_EC_PRESERVED_END_OF_RAM_SIZE]; #define CONFIG_SMBUS_PEC #endif +#undef CONFIG_I2C_NACK_RETRY_COUNT +#ifdef CONFIG_PLATFORM_EC_I2C_NACK_RETRY_COUNT +#define CONFIG_I2C_NACK_RETRY_COUNT CONFIG_PLATFORM_EC_I2C_NACK_RETRY_COUNT +#endif + #undef CONFIG_KEYBOARD_PROTOCOL_8042 #ifdef CONFIG_PLATFORM_EC_KEYBOARD_PROTOCOL_8042 #define CONFIG_KEYBOARD_PROTOCOL_8042 @@ -1543,9 +1548,19 @@ extern char mock_jump_data[CONFIG_PLATFORM_EC_PRESERVED_END_OF_RAM_SIZE]; #undef CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2 #ifdef CONFIG_PLATFORM_EC_USB_PD_TCPM_DRIVER_IT8XXX2 #define CONFIG_USB_PD_TCPM_DRIVER_IT8XXX2 +#if defined(CONFIG_SOC_IT81202_CX) || defined(CONFIG_SOC_IT81302_CX) +/* CCGCR 04h bit[3,2,1] Rp 3A value is changed to 000b. */ +#define IT8XXX2_USBPD_RP_3A0_VALUE_IS_ZERO +/* + * CCGCR 04h bit[7] is reserved, so we control the power of cc analog module + * by CCCSR 05h bit[7,3]. + */ +#define IT8XXX2_USBPD_CCGCR_BIT7_RESERVED +#else /* Individual setting CC1 and CC2 resistance. */ #define IT83XX_USBPD_CC1_CC2_RESISTANCE_SEPARATE #endif +#endif #undef CONFIG_USB_PD_TCPM_DRIVER_IT83XX #ifdef CONFIG_PLATFORM_EC_USB_PD_TCPM_DRIVER_IT83XX @@ -1722,6 +1737,11 @@ extern char mock_jump_data[CONFIG_PLATFORM_EC_PRESERVED_END_OF_RAM_SIZE]; #define CONFIG_USB_PD_ALT_MODE_UFP #endif +#undef CONFIG_USB_PD_DISCOVERY +#ifdef CONFIG_PLATFORM_EC_USB_PD_DISCOVERY +#define CONFIG_USB_PD_DISCOVERY +#endif + #undef CONFIG_USB_PD_DPS #ifdef CONFIG_PLATFORM_EC_USB_PD_DPS #define CONFIG_USB_PD_DPS @@ -1988,6 +2008,11 @@ extern char mock_jump_data[CONFIG_PLATFORM_EC_PRESERVED_END_OF_RAM_SIZE]; #define CONFIG_CMD_USB_PD_CABLE #endif +#undef CONFIG_USB_PD_DP_MODE +#ifdef CONFIG_PLATFORM_EC_USB_PD_DP_MODE +#define CONFIG_USB_PD_DP_MODE +#endif + #undef CONFIG_USB_PD_TBT_COMPAT_MODE #ifdef CONFIG_PLATFORM_EC_USB_PD_TBT_COMPAT_MODE #define CONFIG_USB_PD_TBT_COMPAT_MODE diff --git a/zephyr/shim/include/ec_tasks.h b/zephyr/shim/include/ec_tasks.h index 793beb25ae..2b65b4f056 100644 --- a/zephyr/shim/include/ec_tasks.h +++ b/zephyr/shim/include/ec_tasks.h @@ -6,9 +6,27 @@ #ifndef __CROS_EC_EC_TASKS_H #define __CROS_EC_EC_TASKS_H +#include "task.h" + +#include <zephyr/kernel.h> + /** Starts all of the shimmed EC tasks. Requires CONFIG_SHIMMED_TASKS=y. */ void start_ec_tasks(void); +/** + * Maps an EC task id to a Zephyr thread id. + * + * @returns Thread id OR NULL if mapping fails + */ +k_tid_t task_id_to_thread_id(task_id_t task_id); + +/** + * Maps a Zephyr thread id to an EC task id. + * + * @returns Task id OR TASK_ID_INVALID if mapping fails + */ +task_id_t thread_id_to_task_id(k_tid_t thread_id); + #ifdef TEST_BUILD /** * Set TASK_ID_TEST_RUNNER to current thread tid. Some functions that are tested diff --git a/zephyr/shim/include/shimmed_task_id.h b/zephyr/shim/include/shimmed_task_id.h index a0295ad764..4cccd51b73 100644 --- a/zephyr/shim/include/shimmed_task_id.h +++ b/zephyr/shim/include/shimmed_task_id.h @@ -213,7 +213,6 @@ enum { #define CROS_EC_TASK(name, ...) TASK_ID_##name, #define TASK_TEST(name, ...) CROS_EC_TASK(name) enum { - TASK_ID_IDLE = -1, /* We don't shim the idle task */ CROS_EC_TASK_LIST #ifdef TEST_BUILD TASK_ID_TEST_RUNNER, @@ -226,11 +225,16 @@ enum { /* * Additional task IDs for features that runs on non shimmed threads, - * task_get_current() needs to be updated to identify these ones. + * thread_id_to_task_id() and task_id_to_thread_id() need to be updated + * to identify these tasks. */ +/* clang-format off */ #define CROS_EC_EXTRA_TASKS(fn) \ - COND_CODE_1(CONFIG_TASK_HOSTCMD_THREAD_MAIN, (fn(HOSTCMD)), ()) \ - fn(SYSWORKQ) + COND_CODE_1(CONFIG_TASK_HOSTCMD_THREAD_MAIN, (fn(HOSTCMD)), \ + (fn(MAIN))) \ + fn(SYSWORKQ) \ + fn(IDLE) +/* clang-format on */ #define EXTRA_TASK_INTERNAL_ID(name) EXTRA_TASK_##name, enum { diff --git a/zephyr/shim/include/shimmed_tasks.h b/zephyr/shim/include/shimmed_tasks.h index 75be968f4a..7a55531180 100644 --- a/zephyr/shim/include/shimmed_tasks.h +++ b/zephyr/shim/include/shimmed_tasks.h @@ -47,4 +47,12 @@ #define HAS_TASK_USB_MUX 1 #endif /* CONFIG_PLATFORM_EC_USB_MUX_TASK */ +#ifndef CONFIG_TASK_HOSTCMD_THREAD_MAIN +#define HAS_TASK_MAIN 1 +#endif /* CONFIG_TASK_HOSTCMD_THREAD_DEDICATED */ + +/* These non-shimmed (extra) tasks are always present */ +#define HAS_TASK_IDLE 1 +#define HAS_TASK_SYSWORKQ 1 + #endif /* __CROS_EC_SHIMMED_TASKS_H */ diff --git a/zephyr/shim/include/usbc/tcpc_anx7447.h b/zephyr/shim/include/usbc/tcpc_anx7447.h index 38fcd536a5..53312cd0ea 100644 --- a/zephyr/shim/include/usbc/tcpc_anx7447.h +++ b/zephyr/shim/include/usbc/tcpc_anx7447.h @@ -18,7 +18,5 @@ }, \ .drv = &anx7447_tcpm_drv, \ .flags = DT_PROP(id, tcpc_flags), \ - .alert_signal = COND_CODE_1(DT_NODE_HAS_PROP(id, int_pin), \ - (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \ - (GPIO_LIMIT)), \ + .irq_gpio = GPIO_DT_SPEC_GET_OR(id, irq_gpios, {}), \ }, diff --git a/zephyr/shim/include/usbc/tcpc_anx7447_emul.h b/zephyr/shim/include/usbc/tcpc_anx7447_emul.h index 900ca6f48e..be39ee36d9 100644 --- a/zephyr/shim/include/usbc/tcpc_anx7447_emul.h +++ b/zephyr/shim/include/usbc/tcpc_anx7447_emul.h @@ -17,7 +17,5 @@ .addr_flags = DT_REG_ADDR(id), \ }, \ .drv = &anx7447_tcpm_drv, \ - .alert_signal = COND_CODE_1(DT_NODE_HAS_PROP(id, alert_gpio), \ - (GPIO_SIGNAL(DT_PHANDLE(id, alert_gpio))), \ - (GPIO_LIMIT)), \ + .irq_gpio = GPIO_DT_SPEC_GET_OR(id, irq_gpios, {}), \ }, diff --git a/zephyr/shim/include/usbc/tcpc_ccgxxf.h b/zephyr/shim/include/usbc/tcpc_ccgxxf.h index 731ffcbc80..d28033e053 100644 --- a/zephyr/shim/include/usbc/tcpc_ccgxxf.h +++ b/zephyr/shim/include/usbc/tcpc_ccgxxf.h @@ -18,7 +18,10 @@ }, \ .drv = &ccgxxf_tcpm_drv, \ .flags = TCPC_FLAGS_TCPCI_REV2_0, \ - .alert_signal = COND_CODE_1(DT_NODE_HAS_PROP(id, int_pin), \ - (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \ - (GPIO_LIMIT)), \ + COND_CODE_1(CONFIG_PLATFORM_EC_TCPC_INTERRUPT, \ + (.irq_gpio = GPIO_DT_SPEC_GET_OR(id, irq_gpios, {})), \ + (.alert_signal = COND_CODE_1( \ + DT_NODE_HAS_PROP(id, int_pin), \ + (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \ + (GPIO_LIMIT)))), \ }, diff --git a/zephyr/shim/include/usbc/tcpc_fusb302.h b/zephyr/shim/include/usbc/tcpc_fusb302.h index 2a7e684564..6989dbd21e 100644 --- a/zephyr/shim/include/usbc/tcpc_fusb302.h +++ b/zephyr/shim/include/usbc/tcpc_fusb302.h @@ -4,6 +4,7 @@ */ #include "driver/tcpm/fusb302.h" +#include "usbc/utils.h" #include <zephyr/devicetree.h> @@ -17,7 +18,13 @@ .addr_flags = DT_REG_ADDR(id), \ }, \ .drv = &fusb302_tcpm_drv, \ - .alert_signal = COND_CODE_1(DT_NODE_HAS_PROP(id, int_pin), \ - (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \ - (GPIO_LIMIT)), \ + COND_CODE_1(CONFIG_PLATFORM_EC_TCPC_INTERRUPT, \ + (.irq_gpio = GPIO_DT_SPEC_GET_OR(id, irq_gpios, {})), \ + (.alert_signal = COND_CODE_1( \ + DT_NODE_HAS_PROP(id, int_pin), \ + (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \ + (GPIO_LIMIT)))), \ }, + +DT_FOREACH_STATUS_OKAY(FUSB302_TCPC_COMPAT, + TCPC_VERIFY_NO_FLAGS_ACTIVE_ALERT_HIGH) diff --git a/zephyr/shim/include/usbc/tcpc_generic_emul.h b/zephyr/shim/include/usbc/tcpc_generic_emul.h index 9d2216cb6e..95905b6818 100644 --- a/zephyr/shim/include/usbc/tcpc_generic_emul.h +++ b/zephyr/shim/include/usbc/tcpc_generic_emul.h @@ -17,7 +17,10 @@ .addr_flags = DT_REG_ADDR(id), \ }, \ .drv = &tcpci_tcpm_drv, \ - .alert_signal = COND_CODE_1(DT_NODE_HAS_PROP(id, alert_gpio), \ - (GPIO_SIGNAL(DT_PHANDLE(id, alert_gpio))), \ - (GPIO_LIMIT)), \ + COND_CODE_1(CONFIG_PLATFORM_EC_TCPC_INTERRUPT, \ + (.irq_gpio = GPIO_DT_SPEC_GET_OR(id, irq_gpios, {})), \ + (.alert_signal = COND_CODE_1( \ + DT_NODE_HAS_PROP(id, int_pin), \ + (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \ + (GPIO_LIMIT)))), \ }, diff --git a/zephyr/shim/include/usbc/tcpc_nct38xx.h b/zephyr/shim/include/usbc/tcpc_nct38xx.h index f34fc75863..797993750c 100644 --- a/zephyr/shim/include/usbc/tcpc_nct38xx.h +++ b/zephyr/shim/include/usbc/tcpc_nct38xx.h @@ -21,9 +21,12 @@ }, \ .drv = &nct38xx_tcpm_drv, \ .flags = DT_PROP(id, tcpc_flags), \ - .alert_signal = COND_CODE_1(DT_NODE_HAS_PROP(id, int_pin), \ - (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \ - (GPIO_LIMIT)), \ + COND_CODE_1(CONFIG_PLATFORM_EC_TCPC_INTERRUPT, \ + (.irq_gpio = GPIO_DT_SPEC_GET_OR(id, irq_gpios, {})), \ + (.alert_signal = COND_CODE_1( \ + DT_NODE_HAS_PROP(id, int_pin), \ + (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \ + (GPIO_LIMIT)))), \ }, /** diff --git a/zephyr/shim/include/usbc/tcpc_ps8xxx.h b/zephyr/shim/include/usbc/tcpc_ps8xxx.h index 1caab08a5d..621d4ab016 100644 --- a/zephyr/shim/include/usbc/tcpc_ps8xxx.h +++ b/zephyr/shim/include/usbc/tcpc_ps8xxx.h @@ -4,6 +4,7 @@ */ #include "driver/tcpm/ps8xxx_public.h" +#include "usbc/utils.h" #include <zephyr/devicetree.h> @@ -18,7 +19,13 @@ }, \ .drv = &ps8xxx_tcpm_drv, \ .flags = DT_PROP(id, tcpc_flags), \ - .alert_signal = COND_CODE_1(DT_NODE_HAS_PROP(id, int_pin), \ - (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \ - (GPIO_LIMIT)), \ + COND_CODE_1(CONFIG_PLATFORM_EC_TCPC_INTERRUPT, \ + (.irq_gpio = GPIO_DT_SPEC_GET_OR(id, irq_gpios, {})), \ + (.alert_signal = COND_CODE_1( \ + DT_NODE_HAS_PROP(id, int_pin), \ + (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \ + (GPIO_LIMIT))) \ + ), \ }, + +DT_FOREACH_STATUS_OKAY(PS8XXX_COMPAT, TCPC_VERIFY_NO_FLAGS_ACTIVE_ALERT_HIGH) diff --git a/zephyr/shim/include/usbc/tcpc_ps8xxx_emul.h b/zephyr/shim/include/usbc/tcpc_ps8xxx_emul.h index fa294802dc..09a31b9598 100644 --- a/zephyr/shim/include/usbc/tcpc_ps8xxx_emul.h +++ b/zephyr/shim/include/usbc/tcpc_ps8xxx_emul.h @@ -17,7 +17,10 @@ .addr_flags = DT_REG_ADDR(id), \ }, \ .drv = &ps8xxx_tcpm_drv, \ - .alert_signal = COND_CODE_1(DT_NODE_HAS_PROP(id, alert_gpio), \ - (GPIO_SIGNAL(DT_PHANDLE(id, alert_gpio))), \ - (GPIO_LIMIT)), \ + COND_CODE_1(CONFIG_PLATFORM_EC_TCPC_INTERRUPT, \ + (.irq_gpio = GPIO_DT_SPEC_GET_OR(id, irq_gpios, {})), \ + (.alert_signal = COND_CODE_1( \ + DT_NODE_HAS_PROP(id, int_pin), \ + (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \ + (GPIO_LIMIT)))), \ }, diff --git a/zephyr/shim/include/usbc/tcpc_rt1718s.h b/zephyr/shim/include/usbc/tcpc_rt1718s.h index 20d75482a3..489e00a144 100644 --- a/zephyr/shim/include/usbc/tcpc_rt1718s.h +++ b/zephyr/shim/include/usbc/tcpc_rt1718s.h @@ -4,6 +4,7 @@ */ #include "tcpm/rt1718s_public.h" +#include "usbc/utils.h" #include <zephyr/devicetree.h> @@ -18,7 +19,8 @@ }, \ .drv = &rt1718s_tcpm_drv, \ .flags = DT_PROP(id, tcpc_flags), \ - .alert_signal = COND_CODE_1(DT_NODE_HAS_PROP(id, int_pin), \ - (GPIO_SIGNAL(DT_PHANDLE(id, int_pin))), \ - (GPIO_LIMIT)), \ + .irq_gpio = GPIO_DT_SPEC_GET_OR(id, irq_gpios, {}), \ }, + +DT_FOREACH_STATUS_OKAY(RT1718S_TCPC_COMPAT, + TCPC_VERIFY_NO_FLAGS_ACTIVE_ALERT_HIGH) diff --git a/zephyr/shim/include/usbc/utils.h b/zephyr/shim/include/usbc/utils.h index 53e9a34856..72a2173463 100644 --- a/zephyr/shim/include/usbc/utils.h +++ b/zephyr/shim/include/usbc/utils.h @@ -36,4 +36,16 @@ */ #define USBC_PORT_FROM_INST(inst) USBC_PORT(DT_DRV_INST(inst)) +/* + * Check that the TCPC interrupt flag defined in the devicetree is the same as + * the hardware. + * + * @param id: node id of the tcpc port + */ +#define TCPC_VERIFY_NO_FLAGS_ACTIVE_ALERT_HIGH(id) \ + BUILD_ASSERT( \ + (DT_PROP(id, tcpc_flags) & TCPC_FLAGS_ALERT_ACTIVE_HIGH) == 0, \ + "TCPC interrupt configuration error for " DT_NODE_FULL_NAME( \ + id)); + #endif /* __CROS_EC_ZEPHYR_SHIM_USBC_UTIL */ diff --git a/zephyr/shim/include/zephyr_hooks_shim.h b/zephyr/shim/include/zephyr_hooks_shim.h index f1c25c6e8f..3e0c43088f 100644 --- a/zephyr/shim/include/zephyr_hooks_shim.h +++ b/zephyr/shim/include/zephyr_hooks_shim.h @@ -55,7 +55,7 @@ struct zephyr_shim_hook_list { * See include/hooks.h for documentation. */ #define DECLARE_HOOK(_hooktype, _routine, _priority) \ - STRUCT_SECTION_ITERABLE_ALTERNATE( \ + static const STRUCT_SECTION_ITERABLE_ALTERNATE( \ zephyr_shim_hook_##_hooktype, zephyr_shim_hook_info, \ _cros_hook_##_hooktype##_##_routine) = { \ .routine = _routine, \ diff --git a/zephyr/shim/include/zephyr_host_command.h b/zephyr/shim/include/zephyr_host_command.h index 9271c6c368..844f9ae395 100644 --- a/zephyr/shim/include/zephyr_host_command.h +++ b/zephyr/shim/include/zephyr_host_command.h @@ -13,6 +13,7 @@ #include <stdbool.h> #include <zephyr/init.h> +#include <zephyr/kernel.h> /* Initializes and runs the host command handler loop. */ void host_command_task(void *u); @@ -20,19 +21,29 @@ void host_command_task(void *u); /* Takes over the main thread and runs the host command loop. */ void host_command_main(void); -/* True if running in the main thread. */ -bool in_host_command_main(void); +/* + * Returns the main thread id. Will be the same as the HOSTCMD thread + * when CONFIG_TASK_HOSTCMD_THREAD_MAIN is enabled. + */ +k_tid_t get_main_thread(void); + +/* + * Returns the HOSTCMD thread id. Will be different than the main thread + * when CONFIG_TASK_HOSTCMD_THREAD_DEDICATED is enabled. + */ +k_tid_t get_hostcmd_thread(void); #ifdef CONFIG_PLATFORM_EC_HOSTCMD /** * See include/host_command.h for documentation. */ -#define DECLARE_HOST_COMMAND(_command, _routine, _version_mask) \ - STRUCT_SECTION_ITERABLE(host_command, _cros_hcmd_##_command) = { \ - .command = _command, \ - .handler = _routine, \ - .version_mask = _version_mask, \ +#define DECLARE_HOST_COMMAND(_command, _routine, _version_mask) \ + static const STRUCT_SECTION_ITERABLE(host_command, \ + _cros_hcmd_##_command) = { \ + .command = _command, \ + .handler = _routine, \ + .version_mask = _version_mask, \ } #else /* !CONFIG_PLATFORM_EC_HOSTCMD */ diff --git a/zephyr/shim/include/zephyr_mkbp_event.h b/zephyr/shim/include/zephyr_mkbp_event.h index b8cb88029d..0221be81d4 100644 --- a/zephyr/shim/include/zephyr_mkbp_event.h +++ b/zephyr/shim/include/zephyr_mkbp_event.h @@ -15,8 +15,9 @@ zephyr_find_mkbp_event_source(uint8_t event_type); /** * See include/mkbp_event.h for documentation. */ -#define DECLARE_EVENT_SOURCE(_type, _func) \ - STRUCT_SECTION_ITERABLE(mkbp_event_source, _cros_evtsrc_##_func) = { \ - .event_type = _type, \ - .get_data = _func, \ +#define DECLARE_EVENT_SOURCE(_type, _func) \ + static const STRUCT_SECTION_ITERABLE(mkbp_event_source, \ + _cros_evtsrc_##_func) = { \ + .event_type = _type, \ + .get_data = _func, \ } diff --git a/zephyr/shim/src/host_command.c b/zephyr/shim/src/host_command.c index 16f5ae66d8..5ca84c944a 100644 --- a/zephyr/shim/src/host_command.c +++ b/zephyr/shim/src/host_command.c @@ -19,18 +19,10 @@ struct host_command *zephyr_find_host_command(int command) return NULL; } -/* Pointer to the main thread, defined in kernel/init.c */ -extern struct k_thread z_main_thread; - void host_command_main(void) { - k_thread_priority_set(&z_main_thread, + k_thread_priority_set(get_main_thread(), EC_TASK_PRIORITY(EC_TASK_HOSTCMD_PRIO)); - k_thread_name_set(&z_main_thread, "HOSTCMD"); + k_thread_name_set(get_main_thread(), "HOSTCMD"); host_command_task(NULL); } - -bool in_host_command_main(void) -{ - return (k_current_get() == &z_main_thread); -} diff --git a/zephyr/shim/src/panic.c b/zephyr/shim/src/panic.c index 1a9d7478e4..2e9068078b 100644 --- a/zephyr/shim/src/panic.c +++ b/zephyr/shim/src/panic.c @@ -3,8 +3,8 @@ * found in the LICENSE file. */ +#include "builtin/assert.h" #include "common.h" -#include "host_command.h" #include "panic.h" #include "system_safe_mode.h" @@ -151,9 +151,6 @@ void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *esf) LOG_PANIC(); - if (IS_ENABLED(CONFIG_HOSTCMD_EVENTS)) - host_set_single_event(EC_HOST_EVENT_PANIC); - /* Start system safe mode if possible */ if (IS_ENABLED(CONFIG_PLATFORM_EC_SYSTEM_SAFE_MODE)) { if (reason != K_ERR_KERNEL_PANIC && @@ -173,9 +170,7 @@ void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *esf) * the watchdog will overwrite this panic. */ panic_reboot(); -#ifndef TEST_BUILD - CODE_UNREACHABLE; -#endif + __ASSERT_UNREACHABLE; } void panic_set_reason(uint32_t reason, uint32_t info, uint8_t exception) diff --git a/zephyr/shim/src/rtc.c b/zephyr/shim/src/rtc.c index 3acf6a3bb6..6e694d48e4 100644 --- a/zephyr/shim/src/rtc.c +++ b/zephyr/shim/src/rtc.c @@ -95,7 +95,13 @@ void system_set_rtc_alarm(uint32_t seconds, uint32_t microseconds) return; } - seconds += system_get_rtc_sec(); + /* + * Adding 1 additional second because system_get_rtc_sec + * returns the number of seconds truncated to the nearest + * integer. This results in missed alarms if the actual + * value is 7.99 seconds and 7 seconds is returned. + */ + seconds += system_get_rtc_sec() + 1; cros_rtc_set_alarm(cros_rtc_dev, seconds, microseconds); } diff --git a/zephyr/shim/src/tasks.c b/zephyr/shim/src/tasks.c index 68ebbbc482..d283671f98 100644 --- a/zephyr/shim/src/tasks.c +++ b/zephyr/shim/src/tasks.c @@ -4,6 +4,7 @@ */ #include "common.h" +#include "ec_tasks.h" #include "host_command.h" #include "task.h" #include "timer.h" @@ -78,25 +79,114 @@ static struct task_ctx_base_data *task_get_base_data(task_id_t cros_task_id) return &shimmed_tasks_data[cros_task_id]; } -task_id_t task_get_current(void) +test_export_static k_tid_t get_idle_thread(void) +{ + extern struct k_thread z_idle_threads[]; + + if (!IS_ENABLED(CONFIG_SMP)) { + return &z_idle_threads[0]; + } + __ASSERT(false, "%s does not support SMP", __func__); + return NULL; +} + +test_export_static k_tid_t get_sysworkq_thread(void) +{ + return &k_sys_work_q.thread; +} + +k_tid_t get_main_thread(void) +{ + /* Pointer to the main thread, defined in kernel/init.c */ + extern struct k_thread z_main_thread; + + return &z_main_thread; +} + +test_mockable k_tid_t get_hostcmd_thread(void) +{ +#if IS_ENABLED(HAS_TASK_HOSTCMD) + if (IS_ENABLED(CONFIG_TASK_HOSTCMD_THREAD_MAIN)) { + return get_main_thread(); + } + return task_to_k_tid[TASK_ID_HOSTCMD]; +#endif /* HAS_TASK_HOSTCMD */ + __ASSERT(false, "HOSTCMD task is not enabled"); + return NULL; +} + +k_tid_t task_id_to_thread_id(task_id_t task_id) +{ + if (task_id < 0) { + __ASSERT(false, "Invalid task id %d", task_id); + return NULL; + } + if (task_id < TASK_ID_COUNT) { + return task_to_k_tid[task_id]; + } + if (task_id < TASK_ID_COUNT + EXTRA_TASK_COUNT) { + switch (task_id) { + case TASK_ID_SYSWORKQ: + return get_sysworkq_thread(); + +#if IS_ENABLED(HAS_TASK_HOSTCMD) + case TASK_ID_HOSTCMD: + return get_hostcmd_thread(); +#endif /* HAS_TASK_HOSTCMD */ + +#if IS_ENABLED(HAS_TASK_MAIN) + case TASK_ID_MAIN: + return get_main_thread(); +#endif /* HAS_TASK_MAIN */ + + case TASK_ID_IDLE: + return get_idle_thread(); + } + } + __ASSERT(false, "Failed to map task %d to thread", task_id); + return NULL; +} + +task_id_t thread_id_to_task_id(k_tid_t thread_id) { - if (in_deferred_context()) { + if (thread_id == NULL) { + __ASSERT(false, "Invalid thread_id"); + return TASK_ID_INVALID; + } + + if (get_sysworkq_thread() == thread_id) { return TASK_ID_SYSWORKQ; } -#ifdef CONFIG_TASK_HOSTCMD_THREAD_MAIN - if (in_host_command_main()) { +#if IS_ENABLED(HAS_TASK_HOSTCMD) + if (get_hostcmd_thread() == thread_id) { return TASK_ID_HOSTCMD; } -#endif +#endif /* HAS_TASK_HOSTCMD */ + +#if IS_ENABLED(HAS_TASK_MAIN) + if (get_main_thread() == thread_id) { + return TASK_ID_MAIN; + } +#endif /* HAS_TASK_MAIN */ + + if (get_idle_thread() == thread_id) { + return TASK_ID_IDLE; + } for (size_t i = 0; i < TASK_ID_COUNT; ++i) { - if (task_to_k_tid[i] == k_current_get()) + if (task_to_k_tid[i] == thread_id) { return i; + } } - __ASSERT(false, "Task index out of bound"); - return 0; + __ASSERT(false, "Failed to map thread to task"); + return TASK_ID_INVALID; +} + +task_id_t task_get_current(void) +{ + return thread_id_to_task_id(k_current_get()); } atomic_t *task_get_event_bitmap(task_id_t cros_task_id) @@ -349,5 +439,5 @@ inline bool in_deferred_context(void) /* * Deferred calls run in the sysworkq. */ - return (k_current_get() == &k_sys_work_q.thread); + return (k_current_get() == get_sysworkq_thread()); } diff --git a/zephyr/shim/src/tcpc.c b/zephyr/shim/src/tcpc.c index c4682fce85..98a3cd880b 100644 --- a/zephyr/shim/src/tcpc.c +++ b/zephyr/shim/src/tcpc.c @@ -3,6 +3,7 @@ * found in the LICENSE file. */ +#include "hooks.h" #include "usb_pd.h" #include "usb_pd_tcpm.h" #include "usbc/tcpc_anx7447.h" @@ -20,8 +21,11 @@ #include "usbc/utils.h" #include <zephyr/devicetree.h> +#include <zephyr/logging/log.h> #include <zephyr/sys/util.h> +LOG_MODULE_REGISTER(tcpc, CONFIG_GPIO_LOG_LEVEL); + #define HAS_TCPC_PROP(usbc_id) \ COND_CODE_1(DT_NODE_HAS_PROP(usbc_id, tcpc), (|| 1), ()) @@ -77,14 +81,86 @@ MAYBE_CONST struct tcpc_config_t tcpc_config[] = { DT_FOREACH_STATUS_OKAY( named_usbc_port, TCPC_CHIP) }; +#ifdef CONFIG_PLATFORM_EC_TCPC_INTERRUPT + +BUILD_ASSERT(ARRAY_SIZE(tcpc_config) == CONFIG_USB_PD_PORT_MAX_COUNT); + +struct gpio_callback int_gpio_cb[CONFIG_USB_PD_PORT_MAX_COUNT]; + +static void tcpc_int_gpio_callback(const struct device *dev, + struct gpio_callback *cb, uint32_t pins) +{ + /* + * Retrieve the array index from the callback pointer, and + * use that to get the port number. + */ + int port = cb - &int_gpio_cb[0]; + + schedule_deferred_pd_interrupt(port); +} + +/* + * Enable all tcpc interrupts from devicetree bindings. + * Check whether the callback is already installed, and if + * not, init and add the callback before enabling the + * interrupt. + */ +void tcpc_enable_interrupt(void) +{ + gpio_flags_t flags; + + for (int i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { + /* + * Check whether the interrupt pin has been configured + * by the devicetree. + */ + if (!tcpc_config[i].irq_gpio.port) + continue; + /* + * Check whether the gpio pin is ready + */ + if (!gpio_is_ready_dt(&tcpc_config[i].irq_gpio)) { + LOG_ERR("tcpc port #%i interrupt not ready.", i); + return; + } + /* + * TODO(b/267537103): Once named-gpios support is dropped, + * evaluate if this code should call gpio_pin_configure_dt() + * + * Check whether callback has been initialised + */ + if (!int_gpio_cb[i].handler) { + /* + * Initialise and add the callback. + */ + gpio_init_callback(&int_gpio_cb[i], + tcpc_int_gpio_callback, + BIT(tcpc_config[i].irq_gpio.pin)); + gpio_add_callback(tcpc_config[i].irq_gpio.port, + &int_gpio_cb[i]); + } + flags = tcpc_config[i].flags & TCPC_FLAGS_ALERT_ACTIVE_HIGH ? + GPIO_INT_EDGE_RISING : + GPIO_INT_EDGE_FALLING; + flags = (flags | GPIO_INT_ENABLE) & ~GPIO_INT_DISABLE; + gpio_pin_interrupt_configure_dt(&tcpc_config[i].irq_gpio, + flags); + } +} +/* + * priority set to POST_I2C + 1 so projects can make local edits to + * tcpc_config as needed at POST_I2C before the interrupts are enabled. + */ +DECLARE_HOOK(HOOK_INIT, tcpc_enable_interrupt, HOOK_PRIO_POST_I2C + 1); + +#else /* CONFIG_PLATFORM_EC_TCPC_INTERRUPT */ + /* TCPC GPIO Interrupt Handlers */ void tcpc_alert_event(enum gpio_signal signal) { for (int i = 0; i < ARRAY_SIZE(tcpc_config); i++) { - /* No alerts for embedded TCPC */ /* No alerts if the alert pin is not set in the devicetree */ - if (tcpc_config[i].bus_type == EC_BUS_TYPE_EMBEDDED || - tcpc_config[i].alert_signal == GPIO_LIMIT) { + if (tcpc_config[i].alert_signal == GPIO_LIMIT) { continue; } @@ -95,4 +171,5 @@ void tcpc_alert_event(enum gpio_signal signal) } } +#endif /* CONFIG_PLATFORM_EC_TCPC_INTERRUPT */ #endif /* DT_HAS_COMPAT_STATUS_OKAY */ |