11dc7d0e9SClément Léger // SPDX-License-Identifier: BSD-2-Clause 21dc7d0e9SClément Léger /* 31dc7d0e9SClément Léger * Copyright (c) 2021, Microchip 41dc7d0e9SClément Léger */ 51dc7d0e9SClément Léger 61dc7d0e9SClément Léger #include <drivers/atmel_rstc.h> 71dc7d0e9SClément Léger #include <io.h> 81dc7d0e9SClément Léger #include <kernel/dt.h> 91dc7d0e9SClément Léger #include <tee_api_defines.h> 101dc7d0e9SClément Léger #include <tee_api_types.h> 111dc7d0e9SClément Léger #include <types_ext.h> 121dc7d0e9SClément Léger 131dc7d0e9SClément Léger #define AT91_RSTC_CR 0x0 141dc7d0e9SClément Léger #define AT91_RSTC_CR_KEY SHIFT_U32(0xA5, 24) 151dc7d0e9SClément Léger #define AT91_RSTC_CR_PROCRST BIT32(0) 161dc7d0e9SClément Léger #define AT91_RSTC_CR_PERRST BIT32(2) 171dc7d0e9SClément Léger 181dc7d0e9SClément Léger static vaddr_t rstc_base; 191dc7d0e9SClément Léger 201dc7d0e9SClément Léger bool atmel_rstc_available(void) 211dc7d0e9SClément Léger { 221dc7d0e9SClément Léger return rstc_base != 0; 231dc7d0e9SClément Léger } 241dc7d0e9SClément Léger 251dc7d0e9SClément Léger void __noreturn atmel_rstc_reset(void) 261dc7d0e9SClément Léger { 271dc7d0e9SClément Léger uint32_t val = AT91_RSTC_CR_KEY | AT91_RSTC_CR_PROCRST | 281dc7d0e9SClément Léger AT91_RSTC_CR_PERRST; 291dc7d0e9SClément Léger 301dc7d0e9SClément Léger io_write32(rstc_base + AT91_RSTC_CR, val); 311dc7d0e9SClément Léger 321dc7d0e9SClément Léger /* 331dc7d0e9SClément Léger * After the previous write, the CPU will reset so we will never hit 341dc7d0e9SClément Léger * this loop. 351dc7d0e9SClément Léger */ 361dc7d0e9SClément Léger while (true) 371dc7d0e9SClément Léger ; 381dc7d0e9SClément Léger } 391dc7d0e9SClément Léger 401dc7d0e9SClément Léger static TEE_Result atmel_rstc_probe(const void *fdt, int node, 411dc7d0e9SClément Léger const void *compat_data __unused) 421dc7d0e9SClément Léger 431dc7d0e9SClément Léger { 441dc7d0e9SClément Léger size_t size = 0; 451dc7d0e9SClément Léger 461dc7d0e9SClément Léger if (dt_map_dev(fdt, node, &rstc_base, &size) < 0) 471dc7d0e9SClément Léger return TEE_ERROR_GENERIC; 481dc7d0e9SClément Léger 491dc7d0e9SClément Léger return TEE_SUCCESS; 501dc7d0e9SClément Léger } 511dc7d0e9SClément Léger 521dc7d0e9SClément Léger static const struct dt_device_match atmel_rstc_match_table[] = { 531dc7d0e9SClément Léger { .compatible = "atmel,sama5d3-rstc" }, 541dc7d0e9SClément Léger { } 551dc7d0e9SClément Léger }; 561dc7d0e9SClément Léger 57*61bdedeaSJerome Forissier DEFINE_DT_DRIVER(atmel_rstc_dt_driver) = { 581dc7d0e9SClément Léger .name = "atmel_rstc", 591dc7d0e9SClément Léger .type = DT_DRIVER_NOTYPE, 601dc7d0e9SClément Léger .match_table = atmel_rstc_match_table, 611dc7d0e9SClément Léger .probe = atmel_rstc_probe, 621dc7d0e9SClément Léger }; 63