aboutsummaryrefslogtreecommitdiffstats
path: root/plat/mediatek/common
diff options
context:
space:
mode:
Diffstat (limited to 'plat/mediatek/common')
-rw-r--r--plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c125
-rw-r--r--plat/mediatek/common/drivers/uart/8250_console.S7
-rw-r--r--plat/mediatek/common/drivers/uart/uart.c112
-rw-r--r--plat/mediatek/common/mtk_plat_common.c32
-rw-r--r--plat/mediatek/common/mtk_plat_common.h3
5 files changed, 275 insertions, 4 deletions
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
index 000000000..fca69130a
--- /dev/null
+++ b/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init_v2.c
@@ -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/common/drivers/uart/8250_console.S b/plat/mediatek/common/drivers/uart/8250_console.S
index 94a6c02ab..7a946f9a3 100644
--- a/plat/mediatek/common/drivers/uart/8250_console.S
+++ b/plat/mediatek/common/drivers/uart/8250_console.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -149,16 +149,15 @@ getc_error:
endfunc console_core_getc
/* ---------------------------------------------
- * int console_core_flush(uintptr_t base_addr)
+ * void console_core_flush(uintptr_t base_addr)
* Function to force a write of all buffered
* data that hasn't been output.
* In : x0 - console base address
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list : x0, x1
* ---------------------------------------------
*/
func console_core_flush
/* Placeholder */
- mov w0, #0
ret
endfunc console_core_flush
diff --git a/plat/mediatek/common/drivers/uart/uart.c b/plat/mediatek/common/drivers/uart/uart.c
new file mode 100644
index 000000000..b940eb339
--- /dev/null
+++ b/plat/mediatek/common/drivers/uart/uart.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+#include <uart.h>
+
+static struct mt_uart uart_save_addr[DRV_SUPPORT_UART_PORTS];
+
+static const uint32_t uart_base_addr[DRV_SUPPORT_UART_PORTS] = {
+ UART0_BASE,
+ UART1_BASE
+};
+
+void mt_uart_restore(void)
+{
+ int uart_idx = UART_PORT0;
+ struct mt_uart *uart;
+ unsigned long base;
+
+ /* Must NOT print any debug log before UART restore */
+ for (uart_idx = UART_PORT0; uart_idx < HW_SUPPORT_UART_PORTS;
+ uart_idx++) {
+
+ uart = &uart_save_addr[uart_idx];
+ base = uart->base;
+
+ mmio_write_32(UART_LCR(base), UART_LCR_MODE_B);
+ mmio_write_32(UART_EFR(base), uart->registers.efr);
+ mmio_write_32(UART_LCR(base), uart->registers.lcr);
+ mmio_write_32(UART_FCR(base), uart->registers.fcr);
+
+ /* baudrate */
+ mmio_write_32(UART_HIGHSPEED(base), uart->registers.highspeed);
+ mmio_write_32(UART_FRACDIV_L(base), uart->registers.fracdiv_l);
+ mmio_write_32(UART_FRACDIV_M(base), uart->registers.fracdiv_m);
+ mmio_write_32(UART_LCR(base),
+ uart->registers.lcr | UART_LCR_DLAB);
+ mmio_write_32(UART_DLL(base), uart->registers.dll);
+ mmio_write_32(UART_DLH(base), uart->registers.dlh);
+ mmio_write_32(UART_LCR(base), uart->registers.lcr);
+ mmio_write_32(UART_SAMPLE_COUNT(base),
+ uart->registers.sample_count);
+ mmio_write_32(UART_SAMPLE_POINT(base),
+ uart->registers.sample_point);
+ mmio_write_32(UART_GUARD(base), uart->registers.guard);
+
+ /* flow control */
+ mmio_write_32(UART_ESCAPE_EN(base), uart->registers.escape_en);
+ mmio_write_32(UART_MCR(base), uart->registers.mcr);
+ mmio_write_32(UART_IER(base), uart->registers.ier);
+ mmio_write_32(UART_SCR(base), uart->registers.scr);
+ }
+}
+
+void mt_uart_save(void)
+{
+ int uart_idx = UART_PORT0;
+ struct mt_uart *uart;
+ unsigned long base;
+
+ for (uart_idx = UART_PORT0; uart_idx < HW_SUPPORT_UART_PORTS;
+ uart_idx++) {
+
+ uart_save_addr[uart_idx].base = uart_base_addr[uart_idx];
+ base = uart_base_addr[uart_idx];
+ uart = &uart_save_addr[uart_idx];
+ uart->registers.lcr = mmio_read_32(UART_LCR(base));
+
+ mmio_write_32(UART_LCR(base), UART_LCR_MODE_B);
+ uart->registers.efr = mmio_read_32(UART_EFR(base));
+ mmio_write_32(UART_LCR(base), uart->registers.lcr);
+ uart->registers.fcr = mmio_read_32(UART_FCR_RD(base));
+
+ /* baudrate */
+ uart->registers.highspeed = mmio_read_32(UART_HIGHSPEED(base));
+ uart->registers.fracdiv_l = mmio_read_32(UART_FRACDIV_L(base));
+ uart->registers.fracdiv_m = mmio_read_32(UART_FRACDIV_M(base));
+ mmio_write_32(UART_LCR(base),
+ uart->registers.lcr | UART_LCR_DLAB);
+ uart->registers.dll = mmio_read_32(UART_DLL(base));
+ uart->registers.dlh = mmio_read_32(UART_DLH(base));
+ mmio_write_32(UART_LCR(base), uart->registers.lcr);
+ uart->registers.sample_count = mmio_read_32(
+ UART_SAMPLE_COUNT(base));
+ uart->registers.sample_point = mmio_read_32(
+ UART_SAMPLE_POINT(base));
+ uart->registers.guard = mmio_read_32(UART_GUARD(base));
+
+ /* flow control */
+ uart->registers.escape_en = mmio_read_32(UART_ESCAPE_EN(base));
+ uart->registers.mcr = mmio_read_32(UART_MCR(base));
+ uart->registers.ier = mmio_read_32(UART_IER(base));
+ uart->registers.scr = mmio_read_32(UART_SCR(base));
+ }
+}
+
+void mt_console_uart_cg(int on)
+{
+ if (on == 1) {
+ mmio_write_32(UART_CLOCK_GATE_CLR, UART0_CLOCK_GATE_BIT);
+ } else {
+ mmio_write_32(UART_CLOCK_GATE_SET, UART0_CLOCK_GATE_BIT);
+ }
+}
+
+uint32_t mt_console_uart_cg_status(void)
+{
+ return mmio_read_32(UART_CLOCK_GATE_STA) & UART0_CLOCK_GATE_BIT;
+}
diff --git a/plat/mediatek/common/mtk_plat_common.c b/plat/mediatek/common/mtk_plat_common.c
index a07a2981a..f57e4357d 100644
--- a/plat/mediatek/common/mtk_plat_common.c
+++ b/plat/mediatek/common/mtk_plat_common.c
@@ -10,8 +10,10 @@
#include <drivers/arm/cci.h>
#include <drivers/console.h>
#include <lib/mmio.h>
+#include <lib/smccc.h>
#include <lib/xlat_tables/xlat_tables.h>
#include <plat/common/platform.h>
+#include <services/arm_arch_svc.h>
#include <mtk_plat_common.h>
#include <mtk_sip_svc.h>
@@ -116,3 +118,33 @@ uint32_t plat_get_spsr_for_bl33_entry(void)
spsr = SPSR_MODE32(mode, 0, ee, daif);
return spsr;
}
+
+/*****************************************************************************
+ * plat_is_smccc_feature_available() - This function checks whether SMCCC
+ * feature is availabile for platform.
+ * @fid: SMCCC function id
+ *
+ * Return SMC_OK if SMCCC feature is available and SMC_ARCH_CALL_NOT_SUPPORTED
+ * otherwise.
+ *****************************************************************************/
+int32_t plat_is_smccc_feature_available(u_register_t fid)
+{
+ switch (fid) {
+ case SMCCC_ARCH_SOC_ID:
+ return SMC_ARCH_CALL_SUCCESS;
+ default:
+ return SMC_ARCH_CALL_NOT_SUPPORTED;
+ }
+}
+
+int32_t plat_get_soc_version(void)
+{
+ uint32_t manfid = (JEDEC_MTK_BKID << 24U) | (JEDEC_MTK_MFID << 16U);
+
+ return (int32_t)(manfid | (SOC_CHIP_ID & 0xFFFFU));
+}
+
+int32_t plat_get_soc_revision(void)
+{
+ return 0;
+}
diff --git a/plat/mediatek/common/mtk_plat_common.h b/plat/mediatek/common/mtk_plat_common.h
index 55f4c516e..919c17358 100644
--- a/plat/mediatek/common/mtk_plat_common.h
+++ b/plat/mediatek/common/mtk_plat_common.h
@@ -18,6 +18,9 @@
#define LINUX_KERNEL_32 0
#define SMC32_PARAM_MASK (0xFFFFFFFF)
+#define JEDEC_MTK_BKID U(4)
+#define JEDEC_MTK_MFID U(0x26)
+
struct atf_arg_t {
unsigned int atf_magic;
unsigned int tee_support;