1*1dc7d0e9SClément Léger // SPDX-License-Identifier: BSD-2-Clause 2*1dc7d0e9SClément Léger /* 3*1dc7d0e9SClément Léger * Copyright (c) 2021, Microchip 4*1dc7d0e9SClément Léger */ 5*1dc7d0e9SClément Léger 6*1dc7d0e9SClément Léger #include <drivers/atmel_rstc.h> 7*1dc7d0e9SClément Léger #include <io.h> 8*1dc7d0e9SClément Léger #include <kernel/dt.h> 9*1dc7d0e9SClément Léger #include <tee_api_defines.h> 10*1dc7d0e9SClément Léger #include <tee_api_types.h> 11*1dc7d0e9SClément Léger #include <types_ext.h> 12*1dc7d0e9SClément Léger 13*1dc7d0e9SClément Léger #define AT91_RSTC_CR 0x0 14*1dc7d0e9SClément Léger #define AT91_RSTC_CR_KEY SHIFT_U32(0xA5, 24) 15*1dc7d0e9SClément Léger #define AT91_RSTC_CR_PROCRST BIT32(0) 16*1dc7d0e9SClément Léger #define AT91_RSTC_CR_PERRST BIT32(2) 17*1dc7d0e9SClément Léger 18*1dc7d0e9SClément Léger static vaddr_t rstc_base; 19*1dc7d0e9SClément Léger 20*1dc7d0e9SClément Léger bool atmel_rstc_available(void) 21*1dc7d0e9SClément Léger { 22*1dc7d0e9SClément Léger return rstc_base != 0; 23*1dc7d0e9SClément Léger } 24*1dc7d0e9SClément Léger 25*1dc7d0e9SClément Léger void __noreturn atmel_rstc_reset(void) 26*1dc7d0e9SClément Léger { 27*1dc7d0e9SClément Léger uint32_t val = AT91_RSTC_CR_KEY | AT91_RSTC_CR_PROCRST | 28*1dc7d0e9SClément Léger AT91_RSTC_CR_PERRST; 29*1dc7d0e9SClément Léger 30*1dc7d0e9SClément Léger io_write32(rstc_base + AT91_RSTC_CR, val); 31*1dc7d0e9SClément Léger 32*1dc7d0e9SClément Léger /* 33*1dc7d0e9SClément Léger * After the previous write, the CPU will reset so we will never hit 34*1dc7d0e9SClément Léger * this loop. 35*1dc7d0e9SClément Léger */ 36*1dc7d0e9SClément Léger while (true) 37*1dc7d0e9SClément Léger ; 38*1dc7d0e9SClément Léger } 39*1dc7d0e9SClément Léger 40*1dc7d0e9SClément Léger static TEE_Result atmel_rstc_probe(const void *fdt, int node, 41*1dc7d0e9SClément Léger const void *compat_data __unused) 42*1dc7d0e9SClément Léger 43*1dc7d0e9SClément Léger { 44*1dc7d0e9SClément Léger size_t size = 0; 45*1dc7d0e9SClément Léger 46*1dc7d0e9SClément Léger if (dt_map_dev(fdt, node, &rstc_base, &size) < 0) 47*1dc7d0e9SClément Léger return TEE_ERROR_GENERIC; 48*1dc7d0e9SClément Léger 49*1dc7d0e9SClément Léger return TEE_SUCCESS; 50*1dc7d0e9SClément Léger } 51*1dc7d0e9SClément Léger 52*1dc7d0e9SClément Léger static const struct dt_device_match atmel_rstc_match_table[] = { 53*1dc7d0e9SClément Léger { .compatible = "atmel,sama5d3-rstc" }, 54*1dc7d0e9SClément Léger { } 55*1dc7d0e9SClément Léger }; 56*1dc7d0e9SClément Léger 57*1dc7d0e9SClément Léger const struct dt_driver atmel_rstc_dt_driver __dt_driver = { 58*1dc7d0e9SClément Léger .name = "atmel_rstc", 59*1dc7d0e9SClément Léger .type = DT_DRIVER_NOTYPE, 60*1dc7d0e9SClément Léger .match_table = atmel_rstc_match_table, 61*1dc7d0e9SClément Léger .probe = atmel_rstc_probe, 62*1dc7d0e9SClément Léger }; 63