diff --git a/core/.changelog.d/2587.changed b/core/.changelog.d/2587.changed new file mode 100644 index 0000000000..beda2d0a0f --- /dev/null +++ b/core/.changelog.d/2587.changed @@ -0,0 +1 @@ +CPU Frequency increased to 180 MHz diff --git a/core/embed/boardloader/.changelog.d/2587.changed b/core/embed/boardloader/.changelog.d/2587.changed new file mode 100644 index 0000000000..beda2d0a0f --- /dev/null +++ b/core/embed/boardloader/.changelog.d/2587.changed @@ -0,0 +1 @@ +CPU Frequency increased to 180 MHz diff --git a/core/embed/boardloader/main.c b/core/embed/boardloader/main.c index d11c1a1d97..e17896b1d3 100644 --- a/core/embed/boardloader/main.c +++ b/core/embed/boardloader/main.c @@ -192,15 +192,6 @@ static secbool copy_sdcard(void) { } #endif -// this function resets settings changed in boardloader, which might be -// incompatible with older bootloader versions, where this setting might be -// unknown -void set_bld_compatible_settings(void) { -#ifdef TREZOR_MODEL_T - display_set_big_endian(); -#endif -} - int main(void) { reset_flags_reset(); @@ -243,7 +234,7 @@ int main(void) { ensure(check_image_contents(&hdr, IMAGE_HEADER_SIZE, sectors, 1), "invalid bootloader hash"); - set_bld_compatible_settings(); + ensure_compatible_settings(); jump_to(BOOTLOADER_START + IMAGE_HEADER_SIZE); diff --git a/core/embed/bootloader/.changelog.d/2587.changed b/core/embed/bootloader/.changelog.d/2587.changed new file mode 100644 index 0000000000..beda2d0a0f --- /dev/null +++ b/core/embed/bootloader/.changelog.d/2587.changed @@ -0,0 +1 @@ +CPU Frequency increased to 180 MHz diff --git a/core/embed/bootloader/main.c b/core/embed/bootloader/main.c index d0494e8d17..9fca724d3a 100644 --- a/core/embed/bootloader/main.c +++ b/core/embed/bootloader/main.c @@ -29,6 +29,7 @@ #include "mpu.h" #include "random_delays.h" #include "secbool.h" +#include "stm32.h" #ifdef TREZOR_MODEL_T #include "dma2d.h" #include "touch.h" @@ -255,6 +256,7 @@ int main(void) { #endif #if defined TREZOR_MODEL_T + set_core_clock(CLOCK_180_MHZ); display_set_little_endian(); touch_power_on(); touch_init(); diff --git a/core/embed/firmware/main.c b/core/embed/firmware/main.c index 2977b62068..eab237a582 100644 --- a/core/embed/firmware/main.c +++ b/core/embed/firmware/main.c @@ -59,6 +59,7 @@ #endif #include "rng.h" #include "sdcard.h" +#include "stm32.h" #include "supervise.h" #include "touch.h" #ifdef USE_SECP256K1_ZKP @@ -121,6 +122,7 @@ int main(void) { #endif #if defined TREZOR_MODEL_T + set_core_clock(CLOCK_180_MHZ); touch_init(); display_set_little_endian(); sdcard_init(); diff --git a/core/embed/trezorhal/common.c b/core/embed/trezorhal/common.c index 0bacc5f1a1..64a16c9429 100644 --- a/core/embed/trezorhal/common.c +++ b/core/embed/trezorhal/common.c @@ -25,6 +25,7 @@ #include "display.h" #include "flash.h" #include "rand.h" +#include "stm32.h" #include "supervise.h" #include "stm32f4xx_ll_utils.h" @@ -191,5 +192,6 @@ void collect_hw_entropy(void) { void ensure_compatible_settings(void) { #ifdef TREZOR_MODEL_T display_set_big_endian(); + set_core_clock(CLOCK_168_MHZ); #endif } diff --git a/core/embed/trezorhal/stm32.c b/core/embed/trezorhal/stm32.c index 5a458b9006..1575f8db11 100644 --- a/core/embed/trezorhal/stm32.c +++ b/core/embed/trezorhal/stm32.c @@ -19,21 +19,80 @@ #include STM32_HAL_H +#include "stm32.h" #include "rng.h" const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4}; +typedef struct { + uint32_t freq; + uint32_t pllq; + uint32_t pllp; + uint32_t pllm; + uint32_t plln; +} clock_conf_t; + #ifdef STM32F427xx -#define CORE_CLOCK_MHZ 168U +#ifdef TREZOR_MODEL_T +#define DEFAULT_FREQ 168U +#define DEFAULT_PLLQ 7U +#define DEFAULT_PLLP 0U // P = 2 (two bits, 00 means PLLP = 2) +#define DEFAULT_PLLM 4U +#define DEFAULT_PLLN 168U +#else +#define DEFAULT_FREQ 180U +#define DEFAULT_PLLQ 15U +#define DEFAULT_PLLP 1U // P = 4 (two bits, 01 means PLLP = 4) +#define DEFAULT_PLLM 4U +#define DEFAULT_PLLN 360U +#endif #elif STM32F405xx -#define CORE_CLOCK_MHZ 120U +#define DEFAULT_FREQ 120U +#define DEFAULT_PLLQ 5U +#define DEFAULT_PLLP 0U // P = 2 (two bits, 00 means PLLP = 2) +#define DEFAULT_PLLM 8U +#define DEFAULT_PLLN 240U #else #error Unsupported MCU #endif -uint32_t SystemCoreClock = CORE_CLOCK_MHZ * 1000000U; +uint32_t SystemCoreClock = DEFAULT_FREQ * 1000000U; + +// assuming HSE 8 MHz +clock_conf_t clock_conf[3] = { + { + // P = 4 (two bits, 01 means PLLP = 4) + // clk = ((8MHz / 4) * 360) / 4 = 180 MHz + // usb = ((8MHz / 4) * 360) / 15 = 48 MHz + 180, + 15, + 1, + 4, + 360, + }, + { + // P = 2 (two bits, 00 means PLLP = 2) + // clk = ((8MHz / 4) * 168) / 2 = 168 MHz + // usb = ((8MHz / 4) * 168) / 7 = 48 MHz + 168, + 7, + 0, + 4, + 168, + }, + { + // P = 2 (two bits, 00 means PLLP = 2) + // clk = ((8MHz / 8) * 240) / 2 = 120 MHz + // usb = ((8MHz / 8) * 240) / 5 = 48 MHz + 120, + 5, + 0, + 8, + 240, + }, +}; #pragma GCC optimize( \ "no-stack-protector") // applies to all functions in this file @@ -46,16 +105,19 @@ void SystemInit(void) { // guidance while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLASH_ACR_LATENCY_5WS) ; - // configure main PLL; assumes HSE is 8 MHz; this should evaluate to - // 0x27402a04 -- reference RM0090 section 7.3.2 + // configure main PLL + // reference RM0090 section 6.3.2 RCC->PLLCFGR = (RCC_PLLCFGR_RST_VALUE & ~RCC_PLLCFGR_PLLQ & ~RCC_PLLCFGR_PLLSRC & ~RCC_PLLCFGR_PLLP & ~RCC_PLLCFGR_PLLN & ~RCC_PLLCFGR_PLLM) | - (7U << RCC_PLLCFGR_PLLQ_Pos) // Q = 7 - | RCC_PLLCFGR_PLLSRC_HSE // PLLSRC = HSE - | (0U << RCC_PLLCFGR_PLLP_Pos) // P = 2 (two bits, 00 means PLLP = 2) - | (CORE_CLOCK_MHZ << RCC_PLLCFGR_PLLN_Pos) // N = CORE_CLOCK_MHZ - | (4U << RCC_PLLCFGR_PLLM_Pos); // M = 4 + (DEFAULT_PLLQ << RCC_PLLCFGR_PLLQ_Pos) | + RCC_PLLCFGR_PLLSRC_HSE // PLLSRC = HSE + | (DEFAULT_PLLP << RCC_PLLCFGR_PLLP_Pos) | + (DEFAULT_PLLN << RCC_PLLCFGR_PLLN_Pos) | + (DEFAULT_PLLM << RCC_PLLCFGR_PLLM_Pos); + // this will be overriden by static initialization + SystemCoreClock = DEFAULT_FREQ * 1000000U; + // enable spread spectrum clock for main PLL RCC->SSCGR = RCC_SSCGR_SSCGEN | (44 << RCC_SSCGR_INCSTEP_Pos) | (250 << RCC_SSCGR_MODPER_Pos); @@ -86,6 +148,53 @@ void SystemInit(void) { SCB->CPACR |= ((3U << 22) | (3U << 20)); } +#ifdef TREZOR_MODEL_T +void set_core_clock(clock_settings_t settings) { + /* Enable HSI clock */ + RCC->CR |= RCC_CR_HSION; + + /* Wait till HSI is ready */ + while (!(RCC->CR & RCC_CR_HSIRDY)) + ; + + /* Select HSI clock as main clock */ + RCC->CFGR = (RCC->CFGR & ~(RCC_CFGR_SW)) | RCC_CFGR_SW_HSI; + + /* Disable PLL */ + RCC->CR &= ~RCC_CR_PLLON; + + /* Set PLL settings */ + clock_conf_t conf = clock_conf[settings]; + RCC->PLLCFGR = + (RCC_PLLCFGR_RST_VALUE & ~RCC_PLLCFGR_PLLQ & ~RCC_PLLCFGR_PLLSRC & + ~RCC_PLLCFGR_PLLP & ~RCC_PLLCFGR_PLLN & ~RCC_PLLCFGR_PLLM) | + (conf.pllq << RCC_PLLCFGR_PLLQ_Pos) | + RCC_PLLCFGR_PLLSRC_HSE // PLLSRC = HSE + | (conf.pllp << RCC_PLLCFGR_PLLP_Pos) | + (conf.plln << RCC_PLLCFGR_PLLN_Pos) | (conf.pllm << RCC_PLLCFGR_PLLM_Pos); + SystemCoreClock = conf.freq * 1000000U; + + /* Enable PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till PLL is ready */ + while (!(RCC->CR & RCC_CR_PLLRDY)) + ; + + /* Enable PLL as main clock */ + RCC->CFGR = (RCC->CFGR & ~(RCC_CFGR_SW)) | RCC_CFGR_SW_PLL; + + HAL_InitTick(TICK_INT_PRIORITY); + + // turn off the HSI as it is now unused (it will be turned on again + // automatically if a clock security failure occurs) + RCC->CR &= ~RCC_CR_HSION; + // wait until ths HSI is off + while ((RCC->CR & RCC_CR_HSION) == RCC_CR_HSION) + ; +} +#endif + // from util.s extern void shutdown_privileged(void); diff --git a/core/embed/trezorhal/stm32.h b/core/embed/trezorhal/stm32.h new file mode 100644 index 0000000000..9c63d51c36 --- /dev/null +++ b/core/embed/trezorhal/stm32.h @@ -0,0 +1,33 @@ +/* + * This file is part of the Trezor project, https://trezor.io/ + * + * Copyright (c) SatoshiLabs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef TREZORHAL_STM32_H +#define TREZORHAL_STM32_H + +#include STM32_HAL_H + +typedef enum { + CLOCK_180_MHZ = 0, + CLOCK_168_MHZ = 1, + CLOCK_120_MHZ = 2, +} clock_settings_t; + +void set_core_clock(clock_settings_t settings); + +#endif // TREZORHAL_STM32_H