From 40e4771bb320311aa031d678f3d92b03f78b2a63 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Tue, 14 Jul 2020 17:33:34 +0800 Subject: chip/mt8192_scp: support hostcmd over IPI BRANCH=none BUG=b:146213943 BUG=b:160382789 TEST=make BOARD=asurada_scp Signed-off-by: Tzung-Bi Shih Change-Id: Ifc2cfc127213c6951eab1aea733a6e90e3594827 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2299601 Reviewed-by: Eric Yilun Lin --- chip/mt8192_scp/build.mk | 1 + chip/mt8192_scp/hostcmd.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++ chip/mt8192_scp/hostcmd.h | 12 +++++ chip/mt8192_scp/ipi.c | 6 +++ 4 files changed, 147 insertions(+) create mode 100644 chip/mt8192_scp/hostcmd.c create mode 100644 chip/mt8192_scp/hostcmd.h diff --git a/chip/mt8192_scp/build.mk b/chip/mt8192_scp/build.mk index 277b2d8f6d..86ba6a499c 100644 --- a/chip/mt8192_scp/build.mk +++ b/chip/mt8192_scp/build.mk @@ -23,3 +23,4 @@ endif chip-$(CONFIG_COMMON_TIMER)+=hrtimer.o chip-$(CONFIG_IPI)+=ipi.o ipi_table.o chip-$(CONFIG_WATCHDOG)+=watchdog.o +chip-$(HAS_TASK_HOSTCMD)+=hostcmd.o diff --git a/chip/mt8192_scp/hostcmd.c b/chip/mt8192_scp/hostcmd.c new file mode 100644 index 0000000000..42a463ee56 --- /dev/null +++ b/chip/mt8192_scp/hostcmd.c @@ -0,0 +1,128 @@ +/* Copyright 2020 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "console.h" +#include "host_command.h" +#include "ipi_chip.h" +#include "util.h" + +#define CPRINTF(format, args...) cprintf(CC_IPI, format, ##args) +#define CPRINTS(format, args...) cprints(CC_IPI, format, ##args) + +#define HOSTCMD_MAX_REQUEST_SIZE CONFIG_IPC_SHARED_OBJ_BUF_SIZE +/* Reserve 1 extra byte for HOSTCMD_TYPE and 3 bytes for padding. */ +#define HOSTCMD_MAX_RESPONSE_SIZE (CONFIG_IPC_SHARED_OBJ_BUF_SIZE - 4) +#define HOSTCMD_TYPE_HOSTCMD 1 +#define HOSTCMD_TYPE_HOSTEVENT 2 + +/* + * hostcmd and hostevent share the same IPI ID, and use first byte type to + * indicate its type. + */ +static struct hostcmd_data { + const uint8_t type; + /* To be compatible with CONFIG_HOSTCMD_ALIGNED */ + uint8_t response[HOSTCMD_MAX_RESPONSE_SIZE] __aligned(4); +} hc_cmd_obj = { .type = HOSTCMD_TYPE_HOSTCMD }; +BUILD_ASSERT(sizeof(struct hostcmd_data) == CONFIG_IPC_SHARED_OBJ_BUF_SIZE); + +/* Size of the rpmsg device name, should sync across kernel and EC. */ +#define RPMSG_NAME_SIZE 32 + +/* + * The layout of name service message. + * This should sync across kernel and EC. + */ +struct rpmsg_ns_msg { + /* Name of the corresponding rpmsg_driver. */ + char name[RPMSG_NAME_SIZE]; + /* IPC ID */ + uint32_t addr; +}; + +static void hostcmd_send_response_packet(struct host_packet *pkt) +{ + int ret; + + ret = ipi_send(SCP_IPI_HOST_COMMAND, &hc_cmd_obj, + pkt->response_size + + offsetof(struct hostcmd_data, response), + 1); + if (ret) + CPRINTS("failed to %s(), ret=%d", __func__, ret); +} + +static void hostcmd_handler(int32_t id, void *buf, uint32_t len) +{ + static struct host_packet packet; + 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 */ + + packet.send_response = hostcmd_send_response_packet; + + /* + * Just assign the buffer to request, host_packet_receive + * handles the buffer copy. + */ + packet.request = (void *)r; + packet.request_temp = NULL; + packet.request_max = HOSTCMD_MAX_REQUEST_SIZE; + packet.request_size = host_request_expected_size(r); + + packet.response = hc_cmd_obj.response; + /* Reserve space for the preamble and trailing byte */ + packet.response_max = HOSTCMD_MAX_RESPONSE_SIZE; + packet.response_size = 0; + + packet.driver_result = EC_RES_SUCCESS; + + host_packet_receive(&packet); +} +DECLARE_IPI(SCP_IPI_HOST_COMMAND, hostcmd_handler, 0); + +/* + * Get protocol information + */ +static enum ec_status hostcmd_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 |= BIT(3); + r->max_request_packet_size = HOSTCMD_MAX_REQUEST_SIZE; + r->max_response_packet_size = HOSTCMD_MAX_RESPONSE_SIZE; + + args->response_size = sizeof(*r); + + return EC_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_CMD_GET_PROTOCOL_INFO, hostcmd_get_protocol_info, + EC_VER_MASK(0)); + +void hostcmd_init(void) +{ + int ret; + struct rpmsg_ns_msg ns_msg; + + if (IS_ENABLED(CONFIG_RPMSG_NAME_SERVICE)) { + ns_msg.addr = SCP_IPI_HOST_COMMAND; + strncpy(ns_msg.name, "cros-ec-rpmsg", RPMSG_NAME_SIZE); + ret = ipi_send(SCP_IPI_NS_SERVICE, &ns_msg, sizeof(ns_msg), 1); + if (ret) + CPRINTS("Failed to announce host command channel"); + } +} diff --git a/chip/mt8192_scp/hostcmd.h b/chip/mt8192_scp/hostcmd.h new file mode 100644 index 0000000000..b93f1e725d --- /dev/null +++ b/chip/mt8192_scp/hostcmd.h @@ -0,0 +1,12 @@ +/* Copyright 2020 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_EC_HOSTCMD_H +#define __CROS_EC_HOSTCMD_H + +/* Initialize hostcmd. */ +void hostcmd_init(void); + +#endif /* __CROS_EC_HOSTCMD_H */ diff --git a/chip/mt8192_scp/ipi.c b/chip/mt8192_scp/ipi.c index cc78c7878c..1f50b092f7 100644 --- a/chip/mt8192_scp/ipi.c +++ b/chip/mt8192_scp/ipi.c @@ -7,6 +7,7 @@ #include "common.h" #include "console.h" #include "hooks.h" +#include "hostcmd.h" #include "ipi_chip.h" #include "registers.h" #include "system.h" @@ -52,6 +53,9 @@ static int ipi_is_busy(void) static void ipi_wake_ap(int32_t id) { + if (id >= IPI_COUNT) + return; + if (*ipi_wakeup_table[id]) SCP_SCP2SPM_IPC_SET = IPC_SCP2HOST; } @@ -135,6 +139,8 @@ static void ipi_enable_deferred(void) return; } + hostcmd_init(); + task_enable_irq(SCP_IRQ_GIPC_IN0); } DECLARE_DEFERRED(ipi_enable_deferred); -- cgit v1.2.1