summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYilun Lin <yllin@google.com>2018-12-17 15:00:48 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-12-29 05:45:29 -0800
commit860fe2962d40ee901369d1dc67f4aa7a7a42ba4d (patch)
treef78bd92e4cf48389bce28299ad97dfc9884b0823
parentc7804fd61b3bacf29cb4f1da9483860435ecac20 (diff)
downloadchrome-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.tasklist1
-rw-r--r--chip/mt_scp/ipi.c72
-rw-r--r--common/ec_features.c3
-rw-r--r--include/ec_commands.h2
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))