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> 99e3c57c8SEtienne Carriere #include <kernel/dt_driver.h> 10c2c7da1dSClément Léger #include <matrix.h> 116370f75dSTony Han #include <platform_config.h> 121dc7d0e9SClément Léger #include <tee_api_defines.h> 131dc7d0e9SClément Léger #include <tee_api_types.h> 141dc7d0e9SClément Léger #include <types_ext.h> 151dc7d0e9SClément Léger 161dc7d0e9SClément Léger #define AT91_RSTC_CR 0x0 171dc7d0e9SClément Léger #define AT91_RSTC_CR_KEY SHIFT_U32(0xA5, 24) 181dc7d0e9SClément Léger #define AT91_RSTC_CR_PROCRST BIT32(0) 191dc7d0e9SClément Léger #define AT91_RSTC_CR_PERRST BIT32(2) 201dc7d0e9SClément Léger 21*d557d174STony Han #define AT91_RSTC_GRSTR 0xE4 22*d557d174STony Han #define AT91_RSTC_GRSTR_USB(x) SHIFT_U32(1, 4 + (x)) 23*d557d174STony Han 241dc7d0e9SClément Léger static vaddr_t rstc_base; 251dc7d0e9SClément Léger 261dc7d0e9SClément Léger bool atmel_rstc_available(void) 271dc7d0e9SClément Léger { 281dc7d0e9SClément Léger return rstc_base != 0; 291dc7d0e9SClément Léger } 301dc7d0e9SClément Léger 311dc7d0e9SClément Léger void __noreturn atmel_rstc_reset(void) 321dc7d0e9SClément Léger { 331dc7d0e9SClément Léger uint32_t val = AT91_RSTC_CR_KEY | AT91_RSTC_CR_PROCRST | 341dc7d0e9SClément Léger AT91_RSTC_CR_PERRST; 351dc7d0e9SClément Léger 361dc7d0e9SClément Léger io_write32(rstc_base + AT91_RSTC_CR, val); 371dc7d0e9SClément Léger 381dc7d0e9SClément Léger /* 391dc7d0e9SClément Léger * After the previous write, the CPU will reset so we will never hit 401dc7d0e9SClément Léger * this loop. 411dc7d0e9SClément Léger */ 421dc7d0e9SClément Léger while (true) 431dc7d0e9SClément Léger ; 441dc7d0e9SClément Léger } 451dc7d0e9SClément Léger 46*d557d174STony Han void sam_rstc_usb_por(unsigned char id, bool enable) 47*d557d174STony Han { 48*d557d174STony Han if (!atmel_rstc_available()) 49*d557d174STony Han panic(); 50*d557d174STony Han 51*d557d174STony Han if (enable) 52*d557d174STony Han io_setbits32(rstc_base + AT91_RSTC_GRSTR, 53*d557d174STony Han AT91_RSTC_GRSTR_USB(id)); 54*d557d174STony Han else 55*d557d174STony Han io_clrbits32(rstc_base + AT91_RSTC_GRSTR, 56*d557d174STony Han AT91_RSTC_GRSTR_USB(id)); 57*d557d174STony Han } 58*d557d174STony Han 59379dc2aeSTony Han /* Non-null reference for compat data */ 60379dc2aeSTony Han static const uint8_t rstc_always_secure; 61379dc2aeSTony Han 621dc7d0e9SClément Léger static TEE_Result atmel_rstc_probe(const void *fdt, int node, 63379dc2aeSTony Han const void *compat_data) 641dc7d0e9SClément Léger 651dc7d0e9SClément Léger { 661dc7d0e9SClément Léger size_t size = 0; 671dc7d0e9SClément Léger 68f354a5d8SGatien Chevallier if (fdt_get_status(fdt, node) != DT_STATUS_OK_SEC) 69c2c7da1dSClément Léger return TEE_ERROR_BAD_PARAMETERS; 70c2c7da1dSClément Léger 71379dc2aeSTony Han if (compat_data != &rstc_always_secure) 72c2c7da1dSClément Léger matrix_configure_periph_secure(AT91C_ID_SYS); 73c2c7da1dSClément Léger 74a5d5bbc8SVesa Jääskeläinen if (dt_map_dev(fdt, node, &rstc_base, &size, DT_MAP_AUTO) < 0) 751dc7d0e9SClément Léger return TEE_ERROR_GENERIC; 761dc7d0e9SClément Léger 771dc7d0e9SClément Léger return TEE_SUCCESS; 781dc7d0e9SClément Léger } 791dc7d0e9SClément Léger 801dc7d0e9SClément Léger static const struct dt_device_match atmel_rstc_match_table[] = { 811dc7d0e9SClément Léger { .compatible = "atmel,sama5d3-rstc" }, 82379dc2aeSTony Han { 83379dc2aeSTony Han .compatible = "microchip,sama7g5-rstc", 84379dc2aeSTony Han .compat_data = &rstc_always_secure, 85379dc2aeSTony Han }, 861dc7d0e9SClément Léger { } 871dc7d0e9SClément Léger }; 881dc7d0e9SClément Léger 8961bdedeaSJerome Forissier DEFINE_DT_DRIVER(atmel_rstc_dt_driver) = { 901dc7d0e9SClément Léger .name = "atmel_rstc", 911dc7d0e9SClément Léger .type = DT_DRIVER_NOTYPE, 921dc7d0e9SClément Léger .match_table = atmel_rstc_match_table, 931dc7d0e9SClément Léger .probe = atmel_rstc_probe, 941dc7d0e9SClément Léger }; 95