mediatek: mt8183: add MTK SSPM driver
authorkenny liang <kenny.liang@mediatek.com>
Wed, 21 Aug 2019 13:17:49 +0000 (21:17 +0800)
committerkenny liang <kenny.liang@mediatek.com>
Mon, 16 Sep 2019 02:34:02 +0000 (10:34 +0800)
Add MTK SSPM driver.

Signed-off-by: kenny liang <kenny.liang@mediatek.com>
Change-Id: I30dd9a95456b8c3c8d18fd22120824eec97634ee

plat/mediatek/mt8183/drivers/sspm/sspm.c [new file with mode: 0644]
plat/mediatek/mt8183/drivers/sspm/sspm.h [new file with mode: 0644]
plat/mediatek/mt8183/platform.mk

diff --git a/plat/mediatek/mt8183/drivers/sspm/sspm.c b/plat/mediatek/mt8183/drivers/sspm/sspm.c
new file mode 100644 (file)
index 0000000..3917638
--- /dev/null
@@ -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 (file)
index 0000000..2c2cc10
--- /dev/null
@@ -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__ */
index 302b4692f3a05bb8baa0705042b20f191bc21a34..5bf504b19157e7d5607a1d6c97c8912cb03bb8b3 100644 (file)
@@ -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