diff options
author | Yilun Lin <yllin@google.com> | 2018-12-17 15:00:48 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-12-29 05:45:29 -0800 |
commit | 860fe2962d40ee901369d1dc67f4aa7a7a42ba4d (patch) | |
tree | f78bd92e4cf48389bce28299ad97dfc9884b0823 | |
parent | c7804fd61b3bacf29cb4f1da9483860435ecac20 (diff) | |
download | chrome-ec-860fe2962d40ee901369d1dc67f4aa7a7a42ba4d.tar.gz |
mt_scp/ipi: Support host command.
mt_scp is the first chip which uses IPI to do host command communication.
This CL implements the host command over IPI.
TEST=Run ec.RW.bin on kukui by "echo start >
/sys/class/remoteproc/remoteproc0/state" and see that there are HC logs
from SCP uart
[0.000385 hostcmd init 0x0000000000002000]
[0.049958 HC 0x0b]
[0.050061 HC 0x400b]
[0.050108 HC 0x400b err 1]
[0.050204 HC 0x08]
[0.050240 HC 0x08 err 3]
[0.050370 HC 0x8d]
[0.050406 HC 0x8d err 1]
[0.050821 HC 0x0d]
BUG=b:117917141, b:120953723
BRANCH=None
Change-Id: I2c2b701d92504a74cc2ee90ab05912e99378acde
Signed-off-by: Yilun Lin <yllin@google.com>
Reviewed-on: https://chromium-review.googlesource.com/1379410
Commit-Ready: Nicolas Boichat <drinkcat@chromium.org>
Tested-by: Yilun Lin <yllin@chromium.org>
Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
-rw-r--r-- | board/kukui_scp/ec.tasklist | 1 | ||||
-rw-r--r-- | chip/mt_scp/ipi.c | 72 | ||||
-rw-r--r-- | common/ec_features.c | 3 | ||||
-rw-r--r-- | include/ec_commands.h | 2 |
4 files changed, 78 insertions, 0 deletions
diff --git a/board/kukui_scp/ec.tasklist b/board/kukui_scp/ec.tasklist index e38dd10eb2..16c8741e62 100644 --- a/board/kukui_scp/ec.tasklist +++ b/board/kukui_scp/ec.tasklist @@ -27,5 +27,6 @@ #define CONFIG_TASK_LIST \ TASK_ALWAYS(HOOKS, hook_task, NULL, LARGER_TASK_STACK_SIZE) \ UART_TASK \ + TASK_ALWAYS(HOSTCMD, host_command_task, NULL, LARGER_TASK_STACK_SIZE) \ TASK_ALWAYS(CONSOLE, console_task, NULL, LARGER_TASK_STACK_SIZE) diff --git a/chip/mt_scp/ipi.c b/chip/mt_scp/ipi.c index 91e46740c9..a8bfce0a11 100644 --- a/chip/mt_scp/ipi.c +++ b/chip/mt_scp/ipi.c @@ -41,6 +41,9 @@ static struct ipc_shared_obj *const scp_send_obj = static struct ipc_shared_obj *const scp_recv_obj = (struct ipc_shared_obj *)(CONFIG_IPC_SHARED_OBJ_ADDR + sizeof(struct ipc_shared_obj)); +#ifdef HAS_TASK_HOSTCMD +static struct host_packet ipi_packet; +#endif /* Check if SCP to AP IPI is in use. */ static inline int is_ipi_busy(void) @@ -141,6 +144,75 @@ void ipi_inform_ap(void) ccprintf("Failed to send initialization IPC messages.\n"); } +#ifdef HAS_TASK_HOSTCMD +static void ipi_send_response_packet(struct host_packet *pkt) +{ + int ret; + + ret = ipi_send(IPI_HOST_COMMAND, pkt->response, pkt->response_size, 0); + if (ret) + CPRINTS("#ERR IPI HOSTCMD %d", ret); +} + +static void ipi_hostcmd_handler(int32_t id, void *buf, uint32_t len) +{ + uint8_t *in_msg = buf; + struct ec_host_request *r = (struct ec_host_request *)in_msg; + int i; + + if (in_msg[0] != EC_HOST_REQUEST_VERSION) { + CPRINTS("ERROR: Protocol V2 is not supported!"); + CPRINTF("in_msg=["); + for (i = 0; i < len; i++) + CPRINTF("%02x ", in_msg[i]); + CPRINTF("]\n"); + return; + } + + /* Protocol version 3 */ + + ipi_packet.send_response = ipi_send_response_packet; + + /* + * Just assign the buffer to request, host_packet_receive + * handles the buffer copy. + */ + ipi_packet.request = (void *)r; + ipi_packet.request_temp = NULL; + ipi_packet.request_max = IPI_MAX_REQUEST_SIZE; + ipi_packet.request_size = host_request_expected_size(r); + + ipi_packet.response = scp_send_obj->buffer; + /* Reserve space for the preamble and trailing byte */ + ipi_packet.response_max = IPI_MAX_RESPONSE_SIZE; + ipi_packet.response_size = 0; + + ipi_packet.driver_result = EC_RES_SUCCESS; + + host_packet_receive(&ipi_packet); +} +DECLARE_IPI(IPI_HOST_COMMAND, ipi_hostcmd_handler, 0); + +/* + * Get protocol information + */ +static int ipi_get_protocol_info(struct host_cmd_handler_args *args) +{ + struct ec_response_get_protocol_info *r = args->response; + + memset(r, 0, sizeof(*r)); + r->protocol_versions |= (1 << 3); + r->max_request_packet_size = IPI_MAX_REQUEST_SIZE; + r->max_response_packet_size = IPI_MAX_RESPONSE_SIZE; + + args->response_size = sizeof(*r); + + return EC_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_CMD_GET_PROTOCOL_INFO, ipi_get_protocol_info, + EC_VER_MASK(0)); +#endif + static void ipi_enable_ipc0_deferred(void) { /* Clear IPC0 IRQs. */ diff --git a/common/ec_features.c b/common/ec_features.c index 4bf9f14c2a..eba3889681 100644 --- a/common/ec_features.c +++ b/common/ec_features.c @@ -134,6 +134,9 @@ uint32_t get_feature_flags1(void) #ifdef CONFIG_AUDIO_CODEC | EC_FEATURE_MASK_1(EC_FEATURE_AUDIO_CODEC) #endif +#ifdef CONFIG_IPI + | EC_FEATURE_MASK_1(EC_FEATURE_SCP) +#endif ; #ifdef CONFIG_EC_FEATURE_BOARD_OVERRIDE result = board_override_feature_flags1(result); diff --git a/include/ec_commands.h b/include/ec_commands.h index 9f066e0988..45198db0dc 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -1338,6 +1338,8 @@ enum ec_feature_code { EC_FEATURE_REFINED_TABLET_MODE_HYSTERESIS = 37, /* EC supports audio codec. */ EC_FEATURE_AUDIO_CODEC = 38, + /* EC Supports SCP. */ + EC_FEATURE_SCP = 39, }; #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32)) |