summaryrefslogtreecommitdiff
path: root/chip
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 /chip
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>
Diffstat (limited to 'chip')
-rw-r--r--chip/mt_scp/ipi.c72
1 files changed, 72 insertions, 0 deletions
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. */