1 /* 2 * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <arch_helpers.h> 8 #include <common/debug.h> 9 #include <drivers/arm/gicv2.h> 10 #include <lib/mmio.h> 11 12 #include "rcar_def.h" 13 14 extern void gicd_set_icenabler(uintptr_t base, unsigned int id); 15 16 #define RST_BASE (0xE6160000U) 17 #define RST_WDTRSTCR (RST_BASE + 0x0054U) 18 #define SWDT_BASE (0xE6030000U) 19 #define SWDT_WTCNT (SWDT_BASE + 0x0000U) 20 #define SWDT_WTCSRA (SWDT_BASE + 0x0004U) 21 #define SWDT_WTCSRB (SWDT_BASE + 0x0008U) 22 #define SWDT_GICD_BASE (0xF1010000U) 23 #define SWDT_GICC_BASE (0xF1020000U) 24 #define SWDT_GICD_CTLR (SWDT_GICD_BASE + 0x0000U) 25 #define SWDT_GICD_IGROUPR (SWDT_GICD_BASE + 0x0080U) 26 #define SWDT_GICD_ISPRIORITYR (SWDT_GICD_BASE + 0x0400U) 27 #define SWDT_GICC_CTLR (SWDT_GICC_BASE + 0x0000U) 28 #define SWDT_GICC_PMR (SWDT_GICC_BASE + 0x0004U) 29 #define SWDT_GICD_ITARGETSR (SWDT_GICD_BASE + 0x0800U) 30 #define IGROUPR_NUM (16U) 31 #define ISPRIORITY_NUM (128U) 32 #define ITARGET_MASK (0x03U) 33 34 #define WDTRSTCR_UPPER_BYTE (0xA55A0000U) 35 #define WTCSRA_UPPER_BYTE (0xA5A5A500U) 36 #define WTCSRB_UPPER_BYTE (0xA5A5A500U) 37 #define WTCNT_UPPER_BYTE (0x5A5A0000U) 38 #define WTCNT_RESET_VALUE (0xF488U) 39 #define WTCSRA_BIT_CKS (0x0007U) 40 #define WTCSRB_BIT_CKS (0x003FU) 41 #define SWDT_RSTMSK (1U << 1U) 42 #define WTCSRA_WOVFE (1U << 3U) 43 #define WTCSRA_WRFLG (1U << 5U) 44 #define SWDT_ENABLE (1U << 7U) 45 46 #define WDTRSTCR_MASK_ALL (0x0000FFFFU) 47 #define WTCSRA_MASK_ALL (0x000000FFU) 48 #define WTCNT_INIT_DATA (WTCNT_UPPER_BYTE + WTCNT_RESET_VALUE) 49 #define WTCSRA_INIT_DATA (WTCSRA_UPPER_BYTE + 0x0FU) 50 #define WTCSRB_INIT_DATA (WTCSRB_UPPER_BYTE + 0x21U) 51 52 #if RCAR_LSI == RCAR_D3 53 #define WTCNT_COUNT_8p13k (0x10000U - 40760U) 54 #else 55 #define WTCNT_COUNT_8p13k (0x10000U - 40687U) 56 #endif 57 #define WTCNT_COUNT_8p13k_H3VER10 (0x10000U - 20343U) 58 #define WTCNT_COUNT_8p22k (0x10000U - 41115U) 59 #define WTCNT_COUNT_7p81k (0x10000U - 39062U) 60 #define WTCSRA_CKS_DIV16 (0x00000002U) 61 62 static void swdt_disable(void) 63 { 64 uint32_t rmsk; 65 66 rmsk = mmio_read_32(RST_WDTRSTCR) & WDTRSTCR_MASK_ALL; 67 rmsk |= SWDT_RSTMSK; 68 mmio_write_32(RST_WDTRSTCR, WDTRSTCR_UPPER_BYTE | rmsk); 69 70 mmio_write_32(SWDT_WTCNT, WTCNT_INIT_DATA); 71 mmio_write_32(SWDT_WTCSRA, WTCSRA_INIT_DATA); 72 mmio_write_32(SWDT_WTCSRB, WTCSRB_INIT_DATA); 73 74 /* Set the interrupt clear enable register */ 75 gicd_set_icenabler(RCAR_GICD_BASE, ARM_IRQ_SEC_WDT); 76 } 77 78 void rcar_swdt_init(void) 79 { 80 uint32_t rmsk, sr; 81 #if (RCAR_LSI != RCAR_E3) && (RCAR_LSI != RCAR_D3) && (RCAR_LSI != RZ_G2E) 82 uint32_t reg, val, product_cut, chk_data; 83 84 reg = mmio_read_32(RCAR_PRR); 85 product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK); 86 87 reg = mmio_read_32(RCAR_MODEMR); 88 chk_data = reg & CHECK_MD13_MD14; 89 #endif 90 /* stop watchdog */ 91 if (mmio_read_32(SWDT_WTCSRA) & SWDT_ENABLE) 92 mmio_write_32(SWDT_WTCSRA, WTCSRA_UPPER_BYTE); 93 94 mmio_write_32(SWDT_WTCSRA, WTCSRA_UPPER_BYTE | 95 WTCSRA_WOVFE | WTCSRA_CKS_DIV16); 96 97 #if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RZ_G2E) 98 mmio_write_32(SWDT_WTCNT, WTCNT_UPPER_BYTE | WTCNT_COUNT_7p81k); 99 #elif (RCAR_LSI == RCAR_D3) 100 mmio_write_32(SWDT_WTCNT, WTCNT_UPPER_BYTE | WTCNT_COUNT_8p13k); 101 #else 102 val = WTCNT_UPPER_BYTE; 103 104 switch (chk_data) { 105 case MD14_MD13_TYPE_0: 106 case MD14_MD13_TYPE_2: 107 val |= WTCNT_COUNT_8p13k; 108 break; 109 case MD14_MD13_TYPE_1: 110 val |= WTCNT_COUNT_8p22k; 111 break; 112 case MD14_MD13_TYPE_3: 113 val |= product_cut == (PRR_PRODUCT_H3 | PRR_PRODUCT_10) ? 114 WTCNT_COUNT_8p13k_H3VER10 : WTCNT_COUNT_8p13k; 115 break; 116 default: 117 ERROR("MODEMR ERROR value = %x\n", chk_data); 118 panic(); 119 break; 120 } 121 122 mmio_write_32(SWDT_WTCNT, val); 123 #endif 124 rmsk = mmio_read_32(RST_WDTRSTCR) & WDTRSTCR_MASK_ALL; 125 rmsk |= SWDT_RSTMSK | WDTRSTCR_UPPER_BYTE; 126 mmio_write_32(RST_WDTRSTCR, rmsk); 127 128 while ((mmio_read_8(SWDT_WTCSRA) & WTCSRA_WRFLG) != 0U) 129 ; 130 131 /* Start the System WatchDog Timer */ 132 sr = mmio_read_32(SWDT_WTCSRA) & WTCSRA_MASK_ALL; 133 mmio_write_32(SWDT_WTCSRA, (WTCSRA_UPPER_BYTE | sr | SWDT_ENABLE)); 134 } 135 136 void rcar_swdt_release(void) 137 { 138 uintptr_t itarget = SWDT_GICD_ITARGETSR + 139 (ARM_IRQ_SEC_WDT & ~ITARGET_MASK); 140 uint32_t i; 141 142 /* Disable FIQ interrupt */ 143 write_daifset(DAIF_FIQ_BIT); 144 /* FIQ interrupts are not taken to EL3 */ 145 write_scr_el3(read_scr_el3() & ~SCR_FIQ_BIT); 146 147 swdt_disable(); 148 gicv2_cpuif_disable(); 149 150 for (i = 0; i < IGROUPR_NUM; i++) 151 mmio_write_32(SWDT_GICD_IGROUPR + i * 4, 0U); 152 153 for (i = 0; i < ISPRIORITY_NUM; i++) 154 mmio_write_32(SWDT_GICD_ISPRIORITYR + i * 4, 0U); 155 156 mmio_write_32(itarget, 0U); 157 mmio_write_32(SWDT_GICD_CTLR, 0U); 158 mmio_write_32(SWDT_GICC_CTLR, 0U); 159 mmio_write_32(SWDT_GICC_PMR, 0U); 160 } 161 162 void rcar_swdt_exec(uint64_t p) 163 { 164 gicv2_end_of_interrupt(ARM_IRQ_SEC_WDT); 165 rcar_swdt_release(); 166 ERROR("\n"); 167 ERROR("System WDT overflow, occurred address is %p\n", (void *)p); 168 panic(); 169 } 170