Commit 1e81e9a4 authored by Sandrine Bailleux's avatar Sandrine Bailleux Committed by TrustedFirmware Code Review
Browse files

Merge "mt8173: Add support for new watchdog SMC" into integration

parents 8f74c884 e9cf1bcc
/*
* Copyright (c) 2020, Google LLC. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#include <lib/mmio.h>
#include <mt8173_def.h>
#include <plat_sip_calls.h>
#include <lib/psci/psci.h>
#include <smccc_helpers.h>
#include <wdt.h>
#define WDT_BASE (RGU_BASE + 0)
#define WDT_MODE (WDT_BASE + 0x00)
#define WDT_LENGTH (WDT_BASE + 0x04)
#define WDT_RESTART (WDT_BASE + 0x08)
#define WDT_SWRST (WDT_BASE + 0x14)
#define WDT_MODE_DUAL_MODE 0x40
#define WDT_MODE_IRQ 0x8
#define WDT_MODE_KEY 0x22000000
#define WDT_MODE_EXTEN 0x4
#define WDT_MODE_EN 0x1
#define WDT_LENGTH_KEY 0x8
#define WDT_RESTART_KEY 0x1971
#define WDT_SWRST_KEY 0x1209
#define WDT_MIN_TIMEOUT 1
#define WDT_MAX_TIMEOUT 31
enum smcwd_call {
SMCWD_INFO = 0,
SMCWD_SET_TIMEOUT = 1,
SMCWD_ENABLE = 2,
SMCWD_PET = 3,
};
static int wdt_enabled_before_suspend;
/*
* We expect the WDT registers to be correctly initialized by BL2 firmware
* (which may be board specific), so we do not reinitialize them here.
*/
void wdt_trigger_reset(void)
{
mmio_write_32(WDT_SWRST, WDT_SWRST_KEY);
}
void wdt_pet(void)
{
mmio_write_32(WDT_RESTART, WDT_RESTART_KEY);
}
int wdt_set_timeout(uint32_t timeout)
{
/* One tick here equals 512 32KHz ticks. 512 / 32000 * 125 / 2 = 1 */
uint32_t ticks = timeout * 125 / 2;
if (timeout < WDT_MIN_TIMEOUT || timeout > WDT_MAX_TIMEOUT)
return PSCI_E_INVALID_PARAMS;
mmio_write_32(WDT_LENGTH, ticks << 5 | WDT_LENGTH_KEY);
return PSCI_E_SUCCESS;
}
void wdt_set_enable(int enable)
{
if (enable)
wdt_pet();
mmio_clrsetbits_32(WDT_MODE, WDT_MODE_EN,
WDT_MODE_KEY | (enable ? WDT_MODE_EN : 0));
}
void wdt_suspend(void)
{
wdt_enabled_before_suspend = mmio_read_32(WDT_MODE) & WDT_MODE_EN;
if (wdt_enabled_before_suspend)
wdt_set_enable(0);
}
void wdt_resume(void)
{
if (wdt_enabled_before_suspend)
wdt_set_enable(1);
}
uint64_t wdt_smc_handler(uint32_t x1,
uint32_t x2,
void *handle)
{
int ret;
switch (x1) {
case SMCWD_INFO:
SMC_RET3(handle, PSCI_E_SUCCESS,
WDT_MIN_TIMEOUT, WDT_MAX_TIMEOUT);
case SMCWD_SET_TIMEOUT:
ret = wdt_set_timeout(x2);
SMC_RET1(handle, ret);
case SMCWD_ENABLE:
wdt_set_enable(x2 > 0);
SMC_RET1(handle, PSCI_E_SUCCESS);
case SMCWD_PET:
wdt_pet();
SMC_RET1(handle, PSCI_E_SUCCESS);
default:
ERROR("Unimplemented SMCWD call (%d)\n", x1);
SMC_RET1(handle, PSCI_E_NOT_SUPPORTED);
}
}
/*
* Copyright (c) 2020, Google LLC. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef WDT_H
#define WDT_H
#include "stdint.h"
void wdt_pet(void);
void wdt_resume(void);
void wdt_set_enable(int enable);
int wdt_set_timeout(uint32_t timeout);
uint64_t wdt_smc_handler(uint32_t x1, uint32_t x2, void *handle);
void wdt_suspend(void);
void wdt_trigger_reset(void);
#endif /* WDT_H */
...@@ -80,18 +80,6 @@ ...@@ -80,18 +80,6 @@
#define PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX 4 #define PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX 4
#define PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX 3 #define PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX 3
/*******************************************************************************
* WDT related constants
******************************************************************************/
#define MTK_WDT_BASE (RGU_BASE + 0)
#define MTK_WDT_SWRST (MTK_WDT_BASE + 0x0014)
#define MTK_WDT_MODE_DUAL_MODE 0x0040
#define MTK_WDT_MODE_IRQ 0x0008
#define MTK_WDT_MODE_KEY 0x22000000
#define MTK_WDT_MODE_EXTEN 0x0004
#define MTK_WDT_SWRST_KEY 0x1209
/* FIQ platform related define */ /* FIQ platform related define */
#define MT_IRQ_SEC_SGI_0 8 #define MT_IRQ_SEC_SGI_0 8
#define MT_IRQ_SEC_SGI_1 9 #define MT_IRQ_SEC_SGI_1 9
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
/******************************************************************************* /*******************************************************************************
* Plat SiP function constants * Plat SiP function constants
******************************************************************************/ ******************************************************************************/
#define MTK_PLAT_SIP_NUM_CALLS 6 #define MTK_PLAT_SIP_NUM_CALLS 7
#define MTK_SIP_PWR_ON_MTCMOS 0x82000402 #define MTK_SIP_PWR_ON_MTCMOS 0x82000402
#define MTK_SIP_PWR_OFF_MTCMOS 0x82000403 #define MTK_SIP_PWR_OFF_MTCMOS 0x82000403
...@@ -18,5 +18,6 @@ ...@@ -18,5 +18,6 @@
#define MTK_SIP_SET_HDCP_KEY_NUM 0x82000405 #define MTK_SIP_SET_HDCP_KEY_NUM 0x82000405
#define MTK_SIP_CLR_HDCP_KEY 0x82000406 #define MTK_SIP_CLR_HDCP_KEY 0x82000406
#define MTK_SIP_SET_HDCP_KEY_EX 0x82000407 #define MTK_SIP_SET_HDCP_KEY_EX 0x82000407
#define MTK_SIP_SMC_WATCHDOG 0x82003D06
#endif /* PLAT_SIP_CALLS_H */ #endif /* PLAT_SIP_CALLS_H */
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <spm_hotplug.h> #include <spm_hotplug.h>
#include <spm_mcdi.h> #include <spm_mcdi.h>
#include <spm_suspend.h> #include <spm_suspend.h>
#include <wdt.h>
#define MTK_PWR_LVL0 0 #define MTK_PWR_LVL0 0
#define MTK_PWR_LVL1 1 #define MTK_PWR_LVL1 1
...@@ -350,6 +351,7 @@ static void plat_power_domain_suspend(const psci_power_state_t *state) ...@@ -350,6 +351,7 @@ static void plat_power_domain_suspend(const psci_power_state_t *state)
} }
if (MTK_SYSTEM_PWR_STATE(state) == MTK_LOCAL_STATE_OFF) { if (MTK_SYSTEM_PWR_STATE(state) == MTK_LOCAL_STATE_OFF) {
wdt_suspend();
disable_scu(mpidr); disable_scu(mpidr);
generic_timer_backup(); generic_timer_backup();
spm_system_suspend(); spm_system_suspend();
...@@ -409,6 +411,7 @@ static void plat_power_domain_suspend_finish(const psci_power_state_t *state) ...@@ -409,6 +411,7 @@ static void plat_power_domain_suspend_finish(const psci_power_state_t *state)
plat_arm_gic_init(); plat_arm_gic_init();
spm_system_suspend_finish(); spm_system_suspend_finish();
enable_scu(mpidr); enable_scu(mpidr);
wdt_resume();
} }
/* Perform the common cluster specific operations */ /* Perform the common cluster specific operations */
...@@ -455,11 +458,7 @@ static void __dead2 plat_system_reset(void) ...@@ -455,11 +458,7 @@ static void __dead2 plat_system_reset(void)
/* Write the System Configuration Control Register */ /* Write the System Configuration Control Register */
INFO("MTK System Reset\n"); INFO("MTK System Reset\n");
mmio_clrsetbits_32(MTK_WDT_BASE, wdt_trigger_reset();
(MTK_WDT_MODE_DUAL_MODE | MTK_WDT_MODE_IRQ),
MTK_WDT_MODE_KEY);
mmio_setbits_32(MTK_WDT_BASE, (MTK_WDT_MODE_KEY | MTK_WDT_MODE_EXTEN));
mmio_setbits_32(MTK_WDT_SWRST, MTK_WDT_SWRST_KEY);
wfi(); wfi();
ERROR("MTK System Reset: operation not handled.\n"); ERROR("MTK System Reset: operation not handled.\n");
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <mtcmos.h> #include <mtcmos.h>
#include <mtk_sip_svc.h> #include <mtk_sip_svc.h>
#include <plat_sip_calls.h> #include <plat_sip_calls.h>
#include <wdt.h>
/* Authorized secure register list */ /* Authorized secure register list */
enum { enum {
...@@ -102,6 +103,9 @@ uint64_t mediatek_plat_sip_handler(uint32_t smc_fid, ...@@ -102,6 +103,9 @@ uint64_t mediatek_plat_sip_handler(uint32_t smc_fid,
ret = crypt_clear_hdcp_key(); ret = crypt_clear_hdcp_key();
SMC_RET1(handle, ret); SMC_RET1(handle, ret);
case MTK_SIP_SMC_WATCHDOG:
return wdt_smc_handler(x1, x2, handle);
default: default:
ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
break; break;
......
...@@ -15,6 +15,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ ...@@ -15,6 +15,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
-I${MTK_PLAT_SOC}/drivers/rtc/ \ -I${MTK_PLAT_SOC}/drivers/rtc/ \
-I${MTK_PLAT_SOC}/drivers/spm/ \ -I${MTK_PLAT_SOC}/drivers/spm/ \
-I${MTK_PLAT_SOC}/drivers/timer/ \ -I${MTK_PLAT_SOC}/drivers/timer/ \
-I${MTK_PLAT_SOC}/drivers/wdt/ \
-I${MTK_PLAT_SOC}/include/ -I${MTK_PLAT_SOC}/include/
PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \
...@@ -50,6 +51,7 @@ BL31_SOURCES += common/desc_image_load.c \ ...@@ -50,6 +51,7 @@ BL31_SOURCES += common/desc_image_load.c \
${MTK_PLAT_SOC}/drivers/spm/spm_mcdi.c \ ${MTK_PLAT_SOC}/drivers/spm/spm_mcdi.c \
${MTK_PLAT_SOC}/drivers/spm/spm_suspend.c \ ${MTK_PLAT_SOC}/drivers/spm/spm_suspend.c \
${MTK_PLAT_SOC}/drivers/timer/mt_cpuxgpt.c \ ${MTK_PLAT_SOC}/drivers/timer/mt_cpuxgpt.c \
${MTK_PLAT_SOC}/drivers/wdt/wdt.c \
${MTK_PLAT_SOC}/plat_pm.c \ ${MTK_PLAT_SOC}/plat_pm.c \
${MTK_PLAT_SOC}/plat_sip_calls.c \ ${MTK_PLAT_SOC}/plat_sip_calls.c \
${MTK_PLAT_SOC}/plat_topology.c \ ${MTK_PLAT_SOC}/plat_topology.c \
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment