summaryrefslogtreecommitdiff
path: root/plat/mediatek
diff options
context:
space:
mode:
authorkenny liang <kenny.liang@mediatek.com>2019-08-21 21:17:49 +0800
committerkenny liang <kenny.liang@mediatek.com>2019-09-16 10:34:02 +0800
commit9fc34bbd8d804b5a89472b714a55ccfe7931f2ae (patch)
tree69014f868eb13858cd095478149cd36561f28581 /plat/mediatek
parent3c25ba440750d4b58599aca907a479627ef62551 (diff)
mediatek: mt8183: add MTK SSPM driver
Add MTK SSPM driver. Signed-off-by: kenny liang <kenny.liang@mediatek.com> Change-Id: I30dd9a95456b8c3c8d18fd22120824eec97634ee
Diffstat (limited to 'plat/mediatek')
-rw-r--r--plat/mediatek/mt8183/drivers/sspm/sspm.c159
-rw-r--r--plat/mediatek/mt8183/drivers/sspm/sspm.h32
-rw-r--r--plat/mediatek/mt8183/platform.mk4
3 files changed, 194 insertions, 1 deletions
diff --git a/plat/mediatek/mt8183/drivers/sspm/sspm.c b/plat/mediatek/mt8183/drivers/sspm/sspm.c
new file mode 100644
index 00000000..39176381
--- /dev/null
+++ b/plat/mediatek/mt8183/drivers/sspm/sspm.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <errno.h>
+#include <lib/mmio.h>
+#include <sspm.h>
+
+static void memcpy_to_sspm(uint32_t dst, uint32_t *src, uint32_t len)
+{
+ while (len--) {
+ mmio_write_32(dst, *src);
+ dst += sizeof(uint32_t);
+ src++;
+ }
+}
+
+static void memcpy_from_sspm(uint32_t *dst, uint32_t src, uint32_t len)
+{
+ while (len--) {
+ *dst = mmio_read_32(src);
+ dst++;
+ src += sizeof(uint32_t);
+ }
+}
+
+int sspm_mbox_read(uint32_t slot, uint32_t *data, uint32_t len)
+{
+ if (slot >= 32) {
+ ERROR("%s:slot = %d\n", __func__, slot);
+ return -EINVAL;
+ }
+
+ if (data)
+ memcpy_from_sspm(data,
+ MBOX3_BASE + slot * 4,
+ len);
+
+ return 0;
+}
+
+int sspm_mbox_write(uint32_t slot, uint32_t *data, uint32_t len)
+{
+ if (slot >= 32) {
+ ERROR("%s:slot = %d\n", __func__, slot);
+ return -EINVAL;
+ }
+
+ if (data)
+ memcpy_to_sspm(MBOX3_BASE + slot * 4,
+ data,
+ len);
+
+ return 0;
+}
+
+static int sspm_ipi_check_ack(uint32_t id)
+{
+ int ret = 0;
+
+ if (id == IPI_ID_PLATFORM) {
+ if ((mmio_read_32(MBOX0_BASE + MBOX_IN_IRQ_OFS) & 0x1) == 0x1)
+ ret = -EINPROGRESS;
+ } else if (id == IPI_ID_SUSPEND) {
+ if ((mmio_read_32(MBOX1_BASE + MBOX_IN_IRQ_OFS) & 0x2) == 0x2)
+ ret = -EINPROGRESS;
+ } else {
+ ERROR("%s: id = %d\n", __func__, id);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+int sspm_ipi_send_non_blocking(uint32_t id, uint32_t *data)
+{
+ int ret = 0;
+
+ ret = sspm_ipi_check_ack(id);
+ if (ret)
+ return ret;
+
+ if (id == IPI_ID_PLATFORM) {
+ memcpy_to_sspm(MBOX0_BASE + PINR_OFFSET_PLATFORM * 4,
+ data,
+ PINR_SIZE_PLATFORM);
+ dsb();
+ mmio_write_32(MBOX0_BASE + MBOX_OUT_IRQ_OFS, 0x1);
+ } else if (id == IPI_ID_SUSPEND) {
+ memcpy_to_sspm(MBOX1_BASE + PINR_OFFSET_SUSPEND * 4,
+ data,
+ PINR_SIZE_SUSPEND);
+ dsb();
+ mmio_write_32(MBOX1_BASE + MBOX_OUT_IRQ_OFS,
+ 0x2);
+ }
+
+ return 0;
+}
+
+int sspm_ipi_recv_non_blocking(uint32_t id, uint32_t *data, uint32_t len)
+{
+ int ret = 0;
+
+ ret = sspm_ipi_check_ack(id);
+ if (ret == -EINPROGRESS) {
+ if (id == IPI_ID_PLATFORM) {
+ memcpy_from_sspm(data,
+ MBOX0_BASE + PINR_OFFSET_PLATFORM * 4,
+ len);
+ dsb();
+ /* clear interrupt bit*/
+ mmio_write_32(MBOX0_BASE + MBOX_IN_IRQ_OFS,
+ 0x1);
+ ret = 0;
+ } else if (id == IPI_ID_SUSPEND) {
+ memcpy_from_sspm(data,
+ MBOX1_BASE + PINR_OFFSET_SUSPEND * 4,
+ len);
+ dsb();
+ /* clear interrupt bit*/
+ mmio_write_32(MBOX1_BASE + MBOX_IN_IRQ_OFS,
+ 0x2);
+ ret = 0;
+ }
+ } else if (ret == 0) {
+ ret = -EBUSY;
+ }
+
+ return ret;
+}
+
+int sspm_alive_show(void)
+{
+ uint32_t ipi_data, count;
+ int ret = 0;
+
+ count = 5;
+ ipi_data = 0xdead;
+
+ if (sspm_ipi_send_non_blocking(IPI_ID_PLATFORM, &ipi_data) != 0) {
+ ERROR("sspm init send fail! ret=%d\n", ret);
+ return -1;
+ }
+
+ while (sspm_ipi_recv_non_blocking(IPI_ID_PLATFORM,
+ &ipi_data,
+ sizeof(ipi_data))
+ && count) {
+ mdelay(100);
+ count--;
+ }
+
+ return (ipi_data == 1) ? 0 : -1;
+}
diff --git a/plat/mediatek/mt8183/drivers/sspm/sspm.h b/plat/mediatek/mt8183/drivers/sspm/sspm.h
new file mode 100644
index 00000000..2c2cc10e
--- /dev/null
+++ b/plat/mediatek/mt8183/drivers/sspm/sspm.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef __SSPM_H__
+#define __SSPM_H__
+/* These should sync with sspm.bin */
+#define IPI_ID_PLATFORM 0
+#define IPI_ID_SUSPEND 6
+#define PINR_OFFSET_PLATFORM 0
+#define PINR_SIZE_PLATFORM 3
+#define PINR_OFFSET_SUSPEND 2
+#define PINR_SIZE_SUSPEND 8
+
+#define MBOX0_BASE 0x10450000
+#define MBOX1_BASE 0x10460000
+#define MBOX3_BASE 0x10480000
+#define MBOX_OUT_IRQ_OFS 0x1000
+#define MBOX_IN_IRQ_OFS 0x1004
+
+#define SHAREMBOX_OFFSET_MCDI 0
+#define SHAREMBOX_SIZE_MCDI 20
+#define SHAREMBOX_OFFSET_SUSPEND 26
+#define SHAREMBOX_SIZE_SUSPEND 6
+
+int sspm_mbox_read(uint32_t slot, uint32_t *data, uint32_t len);
+int sspm_mbox_write(uint32_t slot, uint32_t *data, uint32_t len);
+int sspm_ipi_send_non_blocking(uint32_t id, uint32_t *data);
+int sspm_ipi_recv_non_blocking(uint32_t slot, uint32_t *data, uint32_t len);
+int sspm_alive_show(void);
+#endif /* __SSPM_H__ */
diff --git a/plat/mediatek/mt8183/platform.mk b/plat/mediatek/mt8183/platform.mk
index 302b4692..5bf504b1 100644
--- a/plat/mediatek/mt8183/platform.mk
+++ b/plat/mediatek/mt8183/platform.mk
@@ -13,6 +13,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
-I${MTK_PLAT_SOC}/drivers/gpio/ \
-I${MTK_PLAT_SOC}/drivers/pmic/ \
-I${MTK_PLAT_SOC}/drivers/spm/ \
+ -I${MTK_PLAT_SOC}/drivers/sspm/ \
-I${MTK_PLAT_SOC}/drivers/rtc/ \
-I${MTK_PLAT_SOC}/drivers/uart/ \
-I${MTK_PLAT_SOC}/include/
@@ -59,7 +60,8 @@ BL31_SOURCES += common/desc_image_load.c \
${MTK_PLAT_SOC}/plat_dcm.c \
${MTK_PLAT_SOC}/bl31_plat_setup.c \
${MTK_PLAT_SOC}/plat_debug.c \
- ${MTK_PLAT_SOC}/scu.c
+ ${MTK_PLAT_SOC}/scu.c \
+ ${MTK_PLAT_SOC}/drivers/sspm/sspm.c
# Enable workarounds for selected Cortex-A53 erratas.
ERRATA_A53_826319 := 0