]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
mediatek: mt8192: add pmic mt6359p driver
authorHsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>
Wed, 12 Aug 2020 08:31:06 +0000 (16:31 +0800)
committerManish Pandey <manish.pandey2@arm.com>
Mon, 7 Dec 2020 23:28:48 +0000 (23:28 +0000)
add pmic mt6359p driver

Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>
Change-Id: I20f2218f7d2087e8d2bf31258cf92a02e0dab77d

plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c [new file with mode: 0644]
plat/mediatek/mt8192/drivers/pmic/pmic.c [new file with mode: 0644]
plat/mediatek/mt8192/drivers/pmic/pmic.h [new file with mode: 0644]
plat/mediatek/mt8192/drivers/pmic/pmic_wrap_init.h [new file with mode: 0644]
plat/mediatek/mt8192/include/platform_def.h
plat/mediatek/mt8192/platform.mk

diff --git a/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c b/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c
new file mode 100644 (file)
index 0000000..fca6913
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include "platform_def.h"
+#include "pmic_wrap_init.h"
+
+/* pmic wrap module wait_idle and read polling interval (in microseconds) */
+enum pwrap_polling_interval {
+       WAIT_IDLE_POLLING_DELAY_US      = 1,
+       READ_POLLING_DELAY_US           = 2
+};
+
+static uint32_t pwrap_check_idle(void *wacs_register, uint32_t timeout_us)
+{
+       uint32_t reg_rdata = 0U, retry;
+
+       retry = (timeout_us + WAIT_IDLE_POLLING_DELAY_US) /
+               WAIT_IDLE_POLLING_DELAY_US;
+       while (retry != 0) {
+               udelay(WAIT_IDLE_POLLING_DELAY_US);
+               reg_rdata = mmio_read_32((uintptr_t)wacs_register);
+               if (GET_WACS_FSM(reg_rdata) == SWINF_FSM_IDLE) {
+                       break;
+               }
+               retry--;
+       };
+
+       if (retry == 0) {
+               /* timeout */
+               return E_PWR_WAIT_IDLE_TIMEOUT;
+       }
+
+       return 0U;
+}
+
+static uint32_t pwrap_check_vldclr(void *wacs_register, uint32_t timeout_us)
+{
+       uint32_t reg_rdata = 0U, retry;
+
+       retry = (timeout_us + READ_POLLING_DELAY_US) / READ_POLLING_DELAY_US;
+       while (retry != 0) {
+               udelay(READ_POLLING_DELAY_US);
+               reg_rdata = mmio_read_32((uintptr_t)wacs_register);
+               if (GET_WACS_FSM(reg_rdata) == SWINF_FSM_WFVLDCLR) {
+                       break;
+               }
+               retry--;
+       };
+
+       if (retry == 0) {
+               /* timeout */
+               return E_PWR_WAIT_IDLE_TIMEOUT;
+       }
+
+       return 0U;
+}
+
+static int32_t pwrap_wacs2(uint32_t write, uint32_t adr, uint32_t wdata,
+                          uint32_t *rdata, uint32_t init_check)
+{
+       uint32_t reg_rdata, return_value;
+
+       if (init_check != 0) {
+               if ((mmio_read_32((uintptr_t)&mtk_pwrap->init_done) & 0x1) == 0) {
+                       ERROR("initialization isn't finished\n");
+                       return E_PWR_NOT_INIT_DONE;
+               }
+       }
+
+       /* Wait for Software Interface FSM state to be IDLE. */
+       return_value = pwrap_check_idle(&mtk_pwrap->wacs2_sta,
+                                       PWRAP_WAIT_IDLE_US);
+       if (return_value != 0) {
+               return return_value;
+       }
+
+       /* Set the write data */
+       if (write == 1) {
+               /* Set the write data. */
+               mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_wdata, wdata);
+       }
+
+       /* Send the command. */
+       mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_cmd, (write << 29) | adr);
+
+       if (write == 0) {
+               /*
+                * Wait for Software Interface FSM state to be WFVLDCLR,
+                * read the data and clear the valid flag.
+                */
+               return_value = pwrap_check_vldclr(&mtk_pwrap->wacs2_sta,
+                                                 PWRAP_READ_US);
+               if (return_value != 0) {
+                       return return_value;
+               }
+
+               if (rdata == NULL) {
+                       return E_PWR_INVALID_ARG;
+               }
+
+               reg_rdata = mmio_read_32((uintptr_t)&mtk_pwrap->wacs2_rdata);
+               *rdata = reg_rdata;
+               mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_vldclr, 0x1);
+       }
+
+       return return_value;
+}
+
+/* external API for pmic_wrap user */
+int32_t pwrap_read(uint32_t adr, uint32_t *rdata)
+{
+       return pwrap_wacs2(0, adr, 0, rdata, 1);
+}
+
+int32_t pwrap_write(uint32_t adr, uint32_t wdata)
+{
+       return pwrap_wacs2(1, adr, wdata, 0, 1);
+}
diff --git a/plat/mediatek/mt8192/drivers/pmic/pmic.c b/plat/mediatek/mt8192/drivers/pmic/pmic.c
new file mode 100644 (file)
index 0000000..cca4413
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <pmic.h>
+#include <pmic_wrap_init.h>
+
+void pmic_power_off(void)
+{
+       pwrap_write(PMIC_PWRHOLD, 0x0);
+}
diff --git a/plat/mediatek/mt8192/drivers/pmic/pmic.h b/plat/mediatek/mt8192/drivers/pmic/pmic.h
new file mode 100644 (file)
index 0000000..aac22af
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PMIC_H
+#define PMIC_H
+
+#define PMIC_PWRHOLD 0xa08
+
+/* external API */
+void pmic_power_off(void);
+
+#endif /* PMIC_H */
diff --git a/plat/mediatek/mt8192/drivers/pmic/pmic_wrap_init.h b/plat/mediatek/mt8192/drivers/pmic/pmic_wrap_init.h
new file mode 100644 (file)
index 0000000..ae892ed
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PMIC_WRAP_INIT_H
+#define PMIC_WRAP_INIT_H
+
+#include <stdint.h>
+
+#include "platform_def.h"
+
+/* external API */
+int32_t pwrap_read(uint32_t adr, uint32_t *rdata);
+int32_t pwrap_write(uint32_t adr, uint32_t wdata);
+
+static struct mt8192_pmic_wrap_regs *const mtk_pwrap = (void *)PMIC_WRAP_BASE;
+
+/* PMIC_WRAP registers */
+struct mt8192_pmic_wrap_regs {
+       uint32_t init_done;
+       uint32_t reserved[799];
+       uint32_t wacs2_cmd;
+       uint32_t wacs2_wdata;
+       uint32_t reserved1[3];
+       uint32_t wacs2_rdata;
+       uint32_t reserved2[3];
+       uint32_t wacs2_vldclr;
+       uint32_t wacs2_sta;
+};
+
+#define GET_WACS_FSM(x)        ((x >> 1) & 0x7)
+
+/* macro for SWINF_FSM */
+#define SWINF_FSM_IDLE         (0x00)
+#define SWINF_FSM_REQ          (0x02)
+#define SWINF_FSM_WFDLE                (0x04)
+#define SWINF_FSM_WFVLDCLR     (0x06)
+#define SWINF_INIT_DONE                (0x01)
+
+/* timeout setting */
+#define PWRAP_READ_US  1000
+#define PWRAP_WAIT_IDLE_US     1000
+
+/* error information flag */
+enum pwrap_errno {
+       E_PWR_INVALID_ARG             = 1,
+       E_PWR_INVALID_RW              = 2,
+       E_PWR_INVALID_ADDR            = 3,
+       E_PWR_INVALID_WDAT            = 4,
+       E_PWR_INVALID_OP_MANUAL       = 5,
+       E_PWR_NOT_IDLE_STATE          = 6,
+       E_PWR_NOT_INIT_DONE           = 7,
+       E_PWR_NOT_INIT_DONE_READ      = 8,
+       E_PWR_WAIT_IDLE_TIMEOUT       = 9,
+       E_PWR_WAIT_IDLE_TIMEOUT_READ  = 10,
+       E_PWR_INIT_SIDLY_FAIL         = 11,
+       E_PWR_RESET_TIMEOUT           = 12,
+       E_PWR_TIMEOUT                 = 13,
+       E_PWR_INIT_RESET_SPI          = 20,
+       E_PWR_INIT_SIDLY              = 21,
+       E_PWR_INIT_REG_CLOCK          = 22,
+       E_PWR_INIT_ENABLE_PMIC        = 23,
+       E_PWR_INIT_DIO                = 24,
+       E_PWR_INIT_CIPHER             = 25,
+       E_PWR_INIT_WRITE_TEST         = 26,
+       E_PWR_INIT_ENABLE_CRC         = 27,
+       E_PWR_INIT_ENABLE_DEWRAP      = 28,
+       E_PWR_INIT_ENABLE_EVENT       = 29,
+       E_PWR_READ_TEST_FAIL          = 30,
+       E_PWR_WRITE_TEST_FAIL         = 31,
+       E_PWR_SWITCH_DIO              = 32
+};
+
+#endif /* PMIC_WRAP_INIT_H */
index 163ea61888e8c7cfe5790b9a5b37cf6c740b6bfa..a3ab1a0ca0d4dfae2dcad2eb60168eae3735d948 100644 (file)
@@ -28,6 +28,7 @@
 
 #define GPIO_BASE        (IO_PHYS + 0x00005000)
 #define SPM_BASE         (IO_PHYS + 0x00006000)
+#define PMIC_WRAP_BASE   (IO_PHYS + 0x00026000)
 #define IOCFG_RM_BASE    (IO_PHYS + 0x01C20000)
 #define IOCFG_BM_BASE    (IO_PHYS + 0x01D10000)
 #define IOCFG_BL_BASE    (IO_PHYS + 0x01D30000)
index 3c54f70dd3506d1c3dc78322bfa07489720c49c0..01851effc2c6e5d896dedae3786536bc09fcc727 100644 (file)
@@ -12,6 +12,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/                            \
                  -I${MTK_PLAT_SOC}/drivers/                       \
                  -I${MTK_PLAT_SOC}/drivers/gpio/                  \
                  -I${MTK_PLAT_SOC}/drivers/mcdi/                  \
+                 -I${MTK_PLAT_SOC}/drivers/pmic/                  \
                  -I${MTK_PLAT_SOC}/drivers/spmc/                  \
                  -I${MTK_PLAT_SOC}/drivers/timer/
 
@@ -33,11 +34,13 @@ BL31_SOURCES    += common/desc_image_load.c                              \
                    lib/cpus/aarch64/cortex_a55.S                         \
                    lib/cpus/aarch64/cortex_a76.S                         \
                    plat/common/plat_gicv3.c                              \
+                   ${MTK_PLAT}/common/drivers/pmic_wrap/pmic_wrap_init_v2.c \
                    ${MTK_PLAT}/common/mtk_plat_common.c                  \
                    ${MTK_PLAT}/common/params_setup.c                     \
                    ${MTK_PLAT_SOC}/aarch64/platform_common.c             \
                    ${MTK_PLAT_SOC}/aarch64/plat_helpers.S                \
                    ${MTK_PLAT_SOC}/bl31_plat_setup.c                     \
+                   ${MTK_PLAT_SOC}/drivers/pmic/pmic.c                   \
                    ${MTK_PLAT_SOC}/plat_pm.c                             \
                    ${MTK_PLAT_SOC}/plat_topology.c                       \
                    ${MTK_PLAT_SOC}/plat_mt_gic.c                         \