diff --git a/plat/mediatek/mt8195/drivers/pmic/pmic.c b/plat/mediatek/mt8195/drivers/pmic/pmic.c new file mode 100644 index 0000000000000000000000000000000000000000..cca44139730f6810ac262e9ebba7635e0e383f7c --- /dev/null +++ b/plat/mediatek/mt8195/drivers/pmic/pmic.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +void pmic_power_off(void) +{ + pwrap_write(PMIC_PWRHOLD, 0x0); +} diff --git a/plat/mediatek/mt8195/drivers/pmic/pmic.h b/plat/mediatek/mt8195/drivers/pmic/pmic.h new file mode 100644 index 0000000000000000000000000000000000000000..aac22afa39547ca8172fd79480f88221a3884799 --- /dev/null +++ b/plat/mediatek/mt8195/drivers/pmic/pmic.h @@ -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/mt8195/drivers/pmic/pmic_wrap_init.h b/plat/mediatek/mt8195/drivers/pmic/pmic_wrap_init.h new file mode 100644 index 0000000000000000000000000000000000000000..39e78f5f31551f2a845bf27aca7c7f24df361574 --- /dev/null +++ b/plat/mediatek/mt8195/drivers/pmic/pmic_wrap_init.h @@ -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 + +#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 mt8195_pmic_wrap_regs *const mtk_pwrap = (void *)PMIC_WRAP_BASE; + +/* PMIC_WRAP registers */ +struct mt8195_pmic_wrap_regs { + uint32_t init_done; + uint32_t reserved[543]; + 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 */ diff --git a/plat/mediatek/mt8195/include/platform_def.h b/plat/mediatek/mt8195/include/platform_def.h index a97d222bb6d3ab2976c11daa91a016a525768e78..f6eb742f34e82efbfe1cac6bbed34b6fe3e42191 100644 --- a/plat/mediatek/mt8195/include/platform_def.h +++ b/plat/mediatek/mt8195/include/platform_def.h @@ -44,6 +44,11 @@ #define UART_BAUDRATE 115200 +/******************************************************************************* + * PMIC related constants + ******************************************************************************/ +#define PMIC_WRAP_BASE (IO_PHYS + 0x00024000) + /******************************************************************************* * System counter frequency related constants ******************************************************************************/ diff --git a/plat/mediatek/mt8195/plat_pm.c b/plat/mediatek/mt8195/plat_pm.c index 0bff30eb948e3222112ef25e8afbbb5d3a7f8c5e..7cc25655b81cbc56f6616fec2f6119651acc6b9f 100644 --- a/plat/mediatek/mt8195/plat_pm.c +++ b/plat/mediatek/mt8195/plat_pm.c @@ -19,6 +19,7 @@ #include #include #include +#include /* * Cluster state request: @@ -350,8 +351,20 @@ static void __dead2 plat_mtk_system_reset(void) panic(); } +static void __dead2 plat_mtk_system_off(void) +{ + INFO("MTK System Off\n"); + + pmic_power_off(); + + wfi(); + ERROR("MTK System Off: operation not handled.\n"); + panic(); +} + static const plat_psci_ops_t plat_psci_ops = { .system_reset = plat_mtk_system_reset, + .system_off = plat_mtk_system_off, .cpu_standby = plat_cpu_standby, .pwr_domain_on = plat_power_domain_on, .pwr_domain_on_finish = plat_power_domain_on_finish, diff --git a/plat/mediatek/mt8195/platform.mk b/plat/mediatek/mt8195/platform.mk index 1a49b6718dc86241203f37079b0d2c0fdf9f42ed..e37e4404d55133a7711452a90c36b633d7769a3b 100644 --- a/plat/mediatek/mt8195/platform.mk +++ b/plat/mediatek/mt8195/platform.mk @@ -13,6 +13,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT}/common/drivers/timer/ \ -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}/include/ @@ -37,6 +38,7 @@ BL31_SOURCES += common/desc_image_load.c \ plat/common/plat_gicv3.c \ ${MTK_PLAT}/common/drivers/gic600/mt_gic_v3.c \ ${MTK_PLAT}/common/drivers/gpio/mtgpio_common.c \ + ${MTK_PLAT}/common/drivers/pmic_wrap/pmic_wrap_init_v2.c \ ${MTK_PLAT}/common/drivers/timer/mt_timer.c \ ${MTK_PLAT}/common/mtk_cirq.c \ ${MTK_PLAT}/common/mtk_plat_common.c \ @@ -50,6 +52,7 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/drivers/mcdi/mt_cpu_pm_cpc.c \ ${MTK_PLAT_SOC}/drivers/mcdi/mt_mcdi.c \ ${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c \ + ${MTK_PLAT_SOC}/drivers/pmic/pmic.c \ ${MTK_PLAT_SOC}/drivers/spmc/mtspmc.c \ ${MTK_PLAT_SOC}/plat_pm.c \ ${MTK_PLAT_SOC}/plat_sip_calls.c \