arm-trusted-firmware/drivers/renesas/rcar/watchdog/swdt.c
Antonio Nino Diaz 09d40e0e08 Sanitise includes across codebase
Enforce full include path for includes. Deprecate old paths.

The following folders inside include/lib have been left unchanged:

- include/lib/cpus/${ARCH}
- include/lib/el3_runtime/${ARCH}

The reason for this change is that having a global namespace for
includes isn't a good idea. It defeats one of the advantages of having
folders and it introduces problems that are sometimes subtle (because
you may not know the header you are actually including if there are two
of them).

For example, this patch had to be created because two headers were
called the same way: e0ea0928d5 ("Fix gpio includes of mt8173 platform
to avoid collision."). More recently, this patch has had similar
problems: 46f9b2c3a2 ("drivers: add tzc380 support").

This problem was introduced in commit 4ecca33988 ("Move include and
source files to logical locations"). At that time, there weren't too
many headers so it wasn't a real issue. However, time has shown that
this creates problems.

Platforms that want to preserve the way they include headers may add the
removed paths to PLAT_INCLUDES, but this is discouraged.

Change-Id: I39dc53ed98f9e297a5966e723d1936d6ccf2fc8f
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
2019-01-04 10:43:17 +00:00

159 lines
4.4 KiB
C

/*
* Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/arm/gicv2.h>
#include <lib/mmio.h>
#include "rcar_def.h"
extern void gicd_set_icenabler(uintptr_t base, unsigned int id);
#define RST_BASE (0xE6160000U)
#define RST_WDTRSTCR (RST_BASE + 0x0054U)
#define SWDT_BASE (0xE6030000U)
#define SWDT_WTCNT (SWDT_BASE + 0x0000U)
#define SWDT_WTCSRA (SWDT_BASE + 0x0004U)
#define SWDT_WTCSRB (SWDT_BASE + 0x0008U)
#define SWDT_GICD_BASE (0xF1010000U)
#define SWDT_GICC_BASE (0xF1020000U)
#define SWDT_GICD_CTLR (SWDT_GICD_BASE + 0x0000U)
#define SWDT_GICD_IGROUPR (SWDT_GICD_BASE + 0x0080U)
#define SWDT_GICD_ISPRIORITYR (SWDT_GICD_BASE + 0x0400U)
#define SWDT_GICC_CTLR (SWDT_GICC_BASE + 0x0000U)
#define SWDT_GICC_PMR (SWDT_GICC_BASE + 0x0004U)
#define SWDT_GICD_ITARGETSR (SWDT_GICD_BASE + 0x0800U)
#define IGROUPR_NUM (16U)
#define ISPRIORITY_NUM (128U)
#define ITARGET_MASK (0x03U)
#define WDTRSTCR_UPPER_BYTE (0xA55A0000U)
#define WTCSRA_UPPER_BYTE (0xA5A5A500U)
#define WTCSRB_UPPER_BYTE (0xA5A5A500U)
#define WTCNT_UPPER_BYTE (0x5A5A0000U)
#define WTCNT_RESET_VALUE (0xF488U)
#define WTCSRA_BIT_CKS (0x0007U)
#define WTCSRB_BIT_CKS (0x003FU)
#define SWDT_RSTMSK (1U << 1U)
#define WTCSRA_WOVFE (1U << 3U)
#define WTCSRA_WRFLG (1U << 5U)
#define SWDT_ENABLE (1U << 7U)
#define WDTRSTCR_MASK_ALL (0x0000FFFFU)
#define WTCSRA_MASK_ALL (0x000000FFU)
#define WTCNT_INIT_DATA (WTCNT_UPPER_BYTE + WTCNT_RESET_VALUE)
#define WTCSRA_INIT_DATA (WTCSRA_UPPER_BYTE + 0x0FU)
#define WTCSRB_INIT_DATA (WTCSRB_UPPER_BYTE + 0x21U)
#define WTCNT_COUNT_8p13k (0x10000U - 40687U)
#define WTCNT_COUNT_8p13k_H3VER10 (0x10000U - 20343U)
#define WTCNT_COUNT_8p22k (0x10000U - 41115U)
#define WTCNT_COUNT_7p81k (0x10000U - 39062U)
#define WTCSRA_CKS_DIV16 (0x00000002U)
static void swdt_disable(void)
{
uint32_t rmsk;
rmsk = mmio_read_32(RST_WDTRSTCR) & WDTRSTCR_MASK_ALL;
rmsk |= SWDT_RSTMSK;
mmio_write_32(RST_WDTRSTCR, WDTRSTCR_UPPER_BYTE | rmsk);
mmio_write_32(SWDT_WTCNT, WTCNT_INIT_DATA);
mmio_write_32(SWDT_WTCSRA, WTCSRA_INIT_DATA);
mmio_write_32(SWDT_WTCSRB, WTCSRB_INIT_DATA);
/* Set the interrupt clear enable register */
gicd_set_icenabler(RCAR_GICD_BASE, ARM_IRQ_SEC_WDT);
}
void rcar_swdt_init(void)
{
uint32_t rmsk, sr;
#if (RCAR_LSI != RCAR_E3)
uint32_t reg, val, product_cut, chk_data;
reg = mmio_read_32(RCAR_PRR);
product_cut = reg & (RCAR_PRODUCT_MASK | RCAR_CUT_MASK);
reg = mmio_read_32(RCAR_MODEMR);
chk_data = reg & CHECK_MD13_MD14;
#endif
/* stop watchdog */
if (mmio_read_32(SWDT_WTCSRA) & SWDT_ENABLE)
mmio_write_32(SWDT_WTCSRA, WTCSRA_UPPER_BYTE);
mmio_write_32(SWDT_WTCSRA, WTCSRA_UPPER_BYTE |
WTCSRA_WOVFE | WTCSRA_CKS_DIV16);
#if (RCAR_LSI == RCAR_E3)
mmio_write_32(SWDT_WTCNT, WTCNT_UPPER_BYTE | WTCNT_COUNT_7p81k);
#else
val = WTCNT_UPPER_BYTE;
switch (chk_data) {
case MD14_MD13_TYPE_0:
case MD14_MD13_TYPE_2:
val |= WTCNT_COUNT_8p13k;
break;
case MD14_MD13_TYPE_1:
val |= WTCNT_COUNT_8p22k;
break;
case MD14_MD13_TYPE_3:
val |= product_cut == (RCAR_PRODUCT_H3 | RCAR_CUT_VER10) ?
WTCNT_COUNT_8p13k_H3VER10 : WTCNT_COUNT_8p13k;
break;
default:
ERROR("MODEMR ERROR value = %x\n", chk_data);
panic();
break;
}
mmio_write_32(SWDT_WTCNT, val);
#endif
rmsk = mmio_read_32(RST_WDTRSTCR) & WDTRSTCR_MASK_ALL;
rmsk |= SWDT_RSTMSK | WDTRSTCR_UPPER_BYTE;
mmio_write_32(RST_WDTRSTCR, rmsk);
while ((mmio_read_8(SWDT_WTCSRA) & WTCSRA_WRFLG) != 0U)
;
/* Start the System WatchDog Timer */
sr = mmio_read_32(SWDT_WTCSRA) & WTCSRA_MASK_ALL;
mmio_write_32(SWDT_WTCSRA, (WTCSRA_UPPER_BYTE | sr | SWDT_ENABLE));
}
void rcar_swdt_release(void)
{
uintptr_t itarget = SWDT_GICD_ITARGETSR +
(ARM_IRQ_SEC_WDT & ~ITARGET_MASK);
uint32_t i;
write_daifset(DAIF_FIQ_BIT);
swdt_disable();
gicv2_cpuif_disable();
for (i = 0; i < IGROUPR_NUM; i++)
mmio_write_32(SWDT_GICD_IGROUPR + i * 4, 0U);
for (i = 0; i < ISPRIORITY_NUM; i++)
mmio_write_32(SWDT_GICD_ISPRIORITYR + i * 4, 0U);
mmio_write_32(itarget, 0U);
mmio_write_32(SWDT_GICD_CTLR, 0U);
mmio_write_32(SWDT_GICC_CTLR, 0U);
mmio_write_32(SWDT_GICC_PMR, 0U);
}
void rcar_swdt_exec(uint64_t p)
{
gicv2_end_of_interrupt(ARM_IRQ_SEC_WDT);
rcar_swdt_release();
ERROR("\n");
ERROR("System WDT overflow, occured address is %p\n", (void *)p);
panic();
}