1c9d75b3cSYann Gautier /* 23d201787SYann Gautier * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. 3c9d75b3cSYann Gautier * 4c9d75b3cSYann Gautier * SPDX-License-Identifier: BSD-3-Clause 5c9d75b3cSYann Gautier */ 6c9d75b3cSYann Gautier 7c9d75b3cSYann Gautier #include <assert.h> 81e919529SYann Gautier #include <errno.h> 9c9d75b3cSYann Gautier 10c9d75b3cSYann Gautier #include <arch_helpers.h> 11c9d75b3cSYann Gautier #include <common/debug.h> 1253612f72SYann Gautier #include <drivers/delay_timer.h> 1353612f72SYann Gautier #include <drivers/st/stm32_console.h> 147ae58c6bSYann Gautier #include <drivers/st/stm32mp_clkfunc.h> 1553612f72SYann Gautier #include <drivers/st/stm32mp_reset.h> 163d201787SYann Gautier #include <lib/smccc.h> 1784686ba3SYann Gautier #include <lib/xlat_tables/xlat_tables_v2.h> 18c9d75b3cSYann Gautier #include <plat/common/platform.h> 193d201787SYann Gautier #include <services/arm_arch_svc.h> 20c9d75b3cSYann Gautier 2153612f72SYann Gautier #include <platform_def.h> 2253612f72SYann Gautier 238ce89187SNicolas Le Bayon #define HEADER_VERSION_MAJOR_MASK GENMASK(23, 16) 2453612f72SYann Gautier #define RESET_TIMEOUT_US_1MS 1000U 2553612f72SYann Gautier 2653612f72SYann Gautier static console_t console; 278ce89187SNicolas Le Bayon 28c9d75b3cSYann Gautier uintptr_t plat_get_ns_image_entrypoint(void) 29c9d75b3cSYann Gautier { 30c9d75b3cSYann Gautier return BL33_BASE; 31c9d75b3cSYann Gautier } 32c9d75b3cSYann Gautier 33c9d75b3cSYann Gautier unsigned int plat_get_syscnt_freq2(void) 34c9d75b3cSYann Gautier { 35c9d75b3cSYann Gautier return read_cntfrq_el0(); 36c9d75b3cSYann Gautier } 37c9d75b3cSYann Gautier 38c9d75b3cSYann Gautier static uintptr_t boot_ctx_address; 397e87ba25SYann Gautier static uint16_t boot_itf_selected; 40c9d75b3cSYann Gautier 413f9c9784SYann Gautier void stm32mp_save_boot_ctx_address(uintptr_t address) 42c9d75b3cSYann Gautier { 437e87ba25SYann Gautier boot_api_context_t *boot_context = (boot_api_context_t *)address; 447e87ba25SYann Gautier 45c9d75b3cSYann Gautier boot_ctx_address = address; 467e87ba25SYann Gautier boot_itf_selected = boot_context->boot_interface_selected; 47c9d75b3cSYann Gautier } 48c9d75b3cSYann Gautier 493f9c9784SYann Gautier uintptr_t stm32mp_get_boot_ctx_address(void) 50c9d75b3cSYann Gautier { 51c9d75b3cSYann Gautier return boot_ctx_address; 52c9d75b3cSYann Gautier } 53c9d75b3cSYann Gautier 547e87ba25SYann Gautier uint16_t stm32mp_get_boot_itf_selected(void) 557e87ba25SYann Gautier { 567e87ba25SYann Gautier return boot_itf_selected; 577e87ba25SYann Gautier } 587e87ba25SYann Gautier 597ae58c6bSYann Gautier uintptr_t stm32mp_ddrctrl_base(void) 607ae58c6bSYann Gautier { 61ade9ce03SYann Gautier return DDRCTRL_BASE; 627ae58c6bSYann Gautier } 637ae58c6bSYann Gautier 647ae58c6bSYann Gautier uintptr_t stm32mp_ddrphyc_base(void) 657ae58c6bSYann Gautier { 66ade9ce03SYann Gautier return DDRPHYC_BASE; 677ae58c6bSYann Gautier } 687ae58c6bSYann Gautier 697ae58c6bSYann Gautier uintptr_t stm32mp_pwr_base(void) 707ae58c6bSYann Gautier { 71ade9ce03SYann Gautier return PWR_BASE; 727ae58c6bSYann Gautier } 737ae58c6bSYann Gautier 747ae58c6bSYann Gautier uintptr_t stm32mp_rcc_base(void) 757ae58c6bSYann Gautier { 76ade9ce03SYann Gautier return RCC_BASE; 777ae58c6bSYann Gautier } 787ae58c6bSYann Gautier 79e463d3f4SYann Gautier bool stm32mp_lock_available(void) 80e463d3f4SYann Gautier { 81e463d3f4SYann Gautier const uint32_t c_m_bits = SCTLR_M_BIT | SCTLR_C_BIT; 82e463d3f4SYann Gautier 83e463d3f4SYann Gautier /* The spinlocks are used only when MMU and data cache are enabled */ 84e463d3f4SYann Gautier return (read_sctlr() & c_m_bits) == c_m_bits; 85e463d3f4SYann Gautier } 86e463d3f4SYann Gautier 871d204ee4SYann Gautier #if STM32MP_USE_STM32IMAGE 881e919529SYann Gautier int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer) 891e919529SYann Gautier { 901e919529SYann Gautier uint32_t i; 911e919529SYann Gautier uint32_t img_checksum = 0U; 921e919529SYann Gautier 931e919529SYann Gautier /* 941e919529SYann Gautier * Check header/payload validity: 951e919529SYann Gautier * - Header magic 961e919529SYann Gautier * - Header version 971e919529SYann Gautier * - Payload checksum 981e919529SYann Gautier */ 991e919529SYann Gautier if (header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) { 1001e919529SYann Gautier ERROR("Header magic\n"); 1011e919529SYann Gautier return -EINVAL; 1021e919529SYann Gautier } 1031e919529SYann Gautier 1048ce89187SNicolas Le Bayon if ((header->header_version & HEADER_VERSION_MAJOR_MASK) != 1058ce89187SNicolas Le Bayon (BOOT_API_HEADER_VERSION & HEADER_VERSION_MAJOR_MASK)) { 1061e919529SYann Gautier ERROR("Header version\n"); 1071e919529SYann Gautier return -EINVAL; 1081e919529SYann Gautier } 1091e919529SYann Gautier 1101e919529SYann Gautier for (i = 0U; i < header->image_length; i++) { 1111e919529SYann Gautier img_checksum += *(uint8_t *)(buffer + i); 1121e919529SYann Gautier } 1131e919529SYann Gautier 1141e919529SYann Gautier if (header->payload_checksum != img_checksum) { 1151e919529SYann Gautier ERROR("Checksum: 0x%x (awaited: 0x%x)\n", img_checksum, 1161e919529SYann Gautier header->payload_checksum); 1171e919529SYann Gautier return -EINVAL; 1181e919529SYann Gautier } 1191e919529SYann Gautier 1201e919529SYann Gautier return 0; 1211e919529SYann Gautier } 1221d204ee4SYann Gautier #endif /* STM32MP_USE_STM32IMAGE */ 12384686ba3SYann Gautier 12484686ba3SYann Gautier int stm32mp_map_ddr_non_cacheable(void) 12584686ba3SYann Gautier { 12684686ba3SYann Gautier return mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE, 12784686ba3SYann Gautier STM32MP_DDR_MAX_SIZE, 128c1ad41fbSYann Gautier MT_NON_CACHEABLE | MT_RW | MT_SECURE); 12984686ba3SYann Gautier } 13084686ba3SYann Gautier 13184686ba3SYann Gautier int stm32mp_unmap_ddr(void) 13284686ba3SYann Gautier { 13384686ba3SYann Gautier return mmap_remove_dynamic_region(STM32MP_DDR_BASE, 13484686ba3SYann Gautier STM32MP_DDR_MAX_SIZE); 13584686ba3SYann Gautier } 1363d201787SYann Gautier 137*aafff043SYann Gautier #if defined(IMAGE_BL2) 13853612f72SYann Gautier static void reset_uart(uint32_t reset) 13953612f72SYann Gautier { 14053612f72SYann Gautier int ret; 14153612f72SYann Gautier 14253612f72SYann Gautier ret = stm32mp_reset_assert(reset, RESET_TIMEOUT_US_1MS); 14353612f72SYann Gautier if (ret != 0) { 14453612f72SYann Gautier panic(); 14553612f72SYann Gautier } 14653612f72SYann Gautier 14753612f72SYann Gautier udelay(2); 14853612f72SYann Gautier 14953612f72SYann Gautier ret = stm32mp_reset_deassert(reset, RESET_TIMEOUT_US_1MS); 15053612f72SYann Gautier if (ret != 0) { 15153612f72SYann Gautier panic(); 15253612f72SYann Gautier } 15353612f72SYann Gautier 15453612f72SYann Gautier mdelay(1); 15553612f72SYann Gautier } 156*aafff043SYann Gautier #endif 15753612f72SYann Gautier 15853612f72SYann Gautier int stm32mp_uart_console_setup(void) 15953612f72SYann Gautier { 16053612f72SYann Gautier struct dt_node_info dt_uart_info; 16153612f72SYann Gautier unsigned int console_flags; 16253612f72SYann Gautier uint32_t clk_rate; 16353612f72SYann Gautier int result; 16453612f72SYann Gautier 16553612f72SYann Gautier result = dt_get_stdout_uart_info(&dt_uart_info); 16653612f72SYann Gautier 16753612f72SYann Gautier if ((result <= 0) || 16853612f72SYann Gautier (dt_uart_info.status == DT_DISABLED) || 16953612f72SYann Gautier (dt_uart_info.clock < 0) || 17053612f72SYann Gautier (dt_uart_info.reset < 0)) { 17153612f72SYann Gautier return -ENODEV; 17253612f72SYann Gautier } 17353612f72SYann Gautier 174*aafff043SYann Gautier #if defined(IMAGE_BL2) 17553612f72SYann Gautier if (dt_set_stdout_pinctrl() != 0) { 17653612f72SYann Gautier return -ENODEV; 17753612f72SYann Gautier } 178*aafff043SYann Gautier #endif 17953612f72SYann Gautier 18053612f72SYann Gautier stm32mp_clk_enable((unsigned long)dt_uart_info.clock); 18153612f72SYann Gautier 182*aafff043SYann Gautier #if defined(IMAGE_BL2) 18353612f72SYann Gautier reset_uart((uint32_t)dt_uart_info.reset); 184*aafff043SYann Gautier #endif 18553612f72SYann Gautier 18653612f72SYann Gautier clk_rate = stm32mp_clk_get_rate((unsigned long)dt_uart_info.clock); 18753612f72SYann Gautier 18853612f72SYann Gautier if (console_stm32_register(dt_uart_info.base, clk_rate, 18953612f72SYann Gautier STM32MP_UART_BAUDRATE, &console) == 0) { 19053612f72SYann Gautier panic(); 19153612f72SYann Gautier } 19253612f72SYann Gautier 19353612f72SYann Gautier console_flags = CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH | 19453612f72SYann Gautier CONSOLE_FLAG_TRANSLATE_CRLF; 195*aafff043SYann Gautier #if !defined(IMAGE_BL2) && defined(DEBUG) 196*aafff043SYann Gautier console_flags |= CONSOLE_FLAG_RUNTIME; 197*aafff043SYann Gautier #endif 19853612f72SYann Gautier console_set_scope(&console, console_flags); 19953612f72SYann Gautier 20053612f72SYann Gautier return 0; 20153612f72SYann Gautier } 20253612f72SYann Gautier 2033d201787SYann Gautier /***************************************************************************** 2043d201787SYann Gautier * plat_is_smccc_feature_available() - This function checks whether SMCCC 2053d201787SYann Gautier * feature is availabile for platform. 2063d201787SYann Gautier * @fid: SMCCC function id 2073d201787SYann Gautier * 2083d201787SYann Gautier * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and 2093d201787SYann Gautier * SMC_ARCH_CALL_NOT_SUPPORTED otherwise. 2103d201787SYann Gautier *****************************************************************************/ 2113d201787SYann Gautier int32_t plat_is_smccc_feature_available(u_register_t fid) 2123d201787SYann Gautier { 2133d201787SYann Gautier switch (fid) { 2143d201787SYann Gautier case SMCCC_ARCH_SOC_ID: 2153d201787SYann Gautier return SMC_ARCH_CALL_SUCCESS; 2163d201787SYann Gautier default: 2173d201787SYann Gautier return SMC_ARCH_CALL_NOT_SUPPORTED; 2183d201787SYann Gautier } 2193d201787SYann Gautier } 2203d201787SYann Gautier 2213d201787SYann Gautier /* Get SOC version */ 2223d201787SYann Gautier int32_t plat_get_soc_version(void) 2233d201787SYann Gautier { 2243d201787SYann Gautier uint32_t chip_id = stm32mp_get_chip_dev_id(); 2253d201787SYann Gautier uint32_t manfid = SOC_ID_SET_JEP_106(JEDEC_ST_BKID, JEDEC_ST_MFID); 2263d201787SYann Gautier 2273d201787SYann Gautier return (int32_t)(manfid | (chip_id & SOC_ID_IMPL_DEF_MASK)); 2283d201787SYann Gautier } 2293d201787SYann Gautier 2303d201787SYann Gautier /* Get SOC revision */ 2313d201787SYann Gautier int32_t plat_get_soc_revision(void) 2323d201787SYann Gautier { 2333d201787SYann Gautier return (int32_t)(stm32mp_get_chip_version() & SOC_ID_REV_MASK); 2343d201787SYann Gautier } 235